Handle wildcard prefix of allowed tunnel domain names

This commit is contained in:
Erik Ekman 2021-08-25 01:04:31 +02:00
parent f1e7823a3d
commit 95fde8b3ee
3 changed files with 17 additions and 15 deletions

View file

@ -288,6 +288,11 @@ quence, assuming at most one client will be connected at any time. A small
DNSCACHE_LEN is still advised, preferably 2 or higher, however you can also DNSCACHE_LEN is still advised, preferably 2 or higher, however you can also
undefine it to save a few more kilobytes. undefine it to save a few more kilobytes.
One iodine server can handle multiple domains. Set up different NS records
on the same domain all pointing to the same host, and use `\*.mydomain.com`
as topdomain argument. iodine will accept tunnel traffic for all domains matching that
pattern.
PERFORMANCE PERFORMANCE
----------- -----------

View file

@ -337,7 +337,8 @@ subdomains under 'topdomain'. This is normally a subdomain to a domain you
own. Use a short domain name to get better throughput. This argument must be own. Use a short domain name to get better throughput. This argument must be
the same on both the client and the server. Queries for domains other the same on both the client and the server. Queries for domains other
than 'topdomain' will be forwarded when the \-b option is given, otherwise than 'topdomain' will be forwarded when the \-b option is given, otherwise
they will be dropped. they will be dropped. The topdomain can start with '*' which will allow all
domains ending with the same suffix.
.SH EXAMPLES .SH EXAMPLES
See the README file for both a quick test scenario, and a detailed description See the README file for both a quick test scenario, and a detailed description
of real-world deployment. of real-world deployment.

View file

@ -1523,11 +1523,13 @@ handle_null_request(int tun_fd, int dns_fd, struct dnsfd *dns_fds, struct query
} }
static void static void
handle_ns_request(int dns_fd, struct query *q) handle_ns_request(int dns_fd, struct query *q, int topdomain_offset)
/* Mostly identical to handle_a_request() below */ /* Mostly identical to handle_a_request() below */
{ {
char buf[64*1024]; char buf[64*1024];
int len; int len;
/* Use possibly dynamic top domain in reply */
char *resp_domain = q->name + topdomain_offset;
if (ns_ip != INADDR_ANY) { if (ns_ip != INADDR_ANY) {
/* If ns_ip set, overwrite destination addr with it. /* If ns_ip set, overwrite destination addr with it.
@ -1538,7 +1540,7 @@ handle_ns_request(int dns_fd, struct query *q)
q->dest_len = sizeof(*addr); q->dest_len = sizeof(*addr);
} }
len = dns_encode_ns_response(buf, sizeof(buf), q, topdomain); len = dns_encode_ns_response(buf, sizeof(buf), q, resp_domain);
if (len < 1) { if (len < 1) {
warnx("dns_encode_ns_response doesn't fit"); warnx("dns_encode_ns_response doesn't fit");
return; return;
@ -1683,7 +1685,6 @@ tunnel_dns(int tun_fd, int dns_fd, struct dnsfd *dns_fds, int bind_fd)
struct query q; struct query q;
int read; int read;
int domain_len; int domain_len;
int inside_topdomain = 0;
if ((read = read_dns(dns_fd, dns_fds, tun_fd, &q)) <= 0) if ((read = read_dns(dns_fd, dns_fds, tun_fd, &q)) <= 0)
return 0; return 0;
@ -1693,14 +1694,8 @@ tunnel_dns(int tun_fd, int dns_fd, struct dnsfd *dns_fds, int bind_fd)
format_addr(&q.from, q.fromlen), q.type, q.name); format_addr(&q.from, q.fromlen), q.type, q.name);
} }
domain_len = strlen(q.name) - strlen(topdomain); domain_len = query_datalen(q.name, topdomain);
if (domain_len >= 0 && !strcasecmp(q.name + domain_len, topdomain)) if (domain_len >= 0) {
inside_topdomain = 1;
/* require dot before topdomain */
if (domain_len >= 1 && q.name[domain_len - 1] != '.')
inside_topdomain = 0;
if (inside_topdomain) {
/* This is a query we can handle */ /* This is a query we can handle */
/* Handle A-type query for ns.topdomain, possibly caused /* Handle A-type query for ns.topdomain, possibly caused
@ -1736,7 +1731,7 @@ tunnel_dns(int tun_fd, int dns_fd, struct dnsfd *dns_fds, int bind_fd)
handle_null_request(tun_fd, dns_fd, dns_fds, &q, domain_len); handle_null_request(tun_fd, dns_fd, dns_fds, &q, domain_len);
break; break;
case T_NS: case T_NS:
handle_ns_request(dns_fd, &q); handle_ns_request(dns_fd, &q, domain_len);
break; break;
default: default:
break; break;
@ -2327,7 +2322,8 @@ static void help(FILE *stream)
" -i maximum idle time before shutting down\n\n" " -i maximum idle time before shutting down\n\n"
"tunnel_ip is the IP number of the local tunnel interface.\n" "tunnel_ip is the IP number of the local tunnel interface.\n"
" /netmask sets the size of the tunnel network.\n" " /netmask sets the size of the tunnel network.\n"
"topdomain is the FQDN that is delegated to this server.\n"); "topdomain is the FQDN that is delegated to this server.\n"
" Initial wildcard is allowed (example: *.tun.com)\n");
exit(0); exit(0);
} }
@ -2543,7 +2539,7 @@ main(int argc, char **argv)
} }
topdomain = strdup(argv[1]); topdomain = strdup(argv[1]);
if (check_topdomain(topdomain, 0, &errormsg)) { if (check_topdomain(topdomain, 1, &errormsg)) {
warnx("Invalid topdomain: %s", errormsg); warnx("Invalid topdomain: %s", errormsg);
usage(); usage();
/* NOTREACHED */ /* NOTREACHED */