Allow looking up external address and listen to it

This commit is contained in:
Erik Ekman 2021-06-04 18:55:07 +02:00
parent a6d82b1a44
commit f2b619faad
2 changed files with 21 additions and 4 deletions

View file

@ -268,10 +268,12 @@ This will be sent to the client on login, and the client will use the same mtu
for its tun device. Default 1130. Note that the DNS traffic will be for its tun device. Default 1130. Note that the DNS traffic will be
automatically fragmented when needed. automatically fragmented when needed.
.TP .TP
.B -l listen_ip4 .B -l external|listen_ip4
Make the server listen only on 'listen_ip4' for incoming IPv4 requests. Make the server listen only on 'listen_ip4' for incoming IPv4 requests.
By default, incoming requests are accepted from all interfaces (0.0.0.0). By default, incoming requests are accepted from all interfaces (0.0.0.0).
A domain name can be used as argument - use one with only one A record. A domain name can be used as argument - use one with only one A record.
If listen_ip4 is 'external', iodined will use the opendns.com DNS service to
retrieve the external IP of the host and use that as listen address.
.TP .TP
.B -L listen_ip6 .B -L listen_ip6
Make the server listen only on 'listen_ip6' for incoming IPv6 requests. Make the server listen only on 'listen_ip6' for incoming IPv6 requests.

View file

@ -2315,11 +2315,12 @@ static void help(FILE *stream)
" -z context to apply SELinux context after initialization\n" " -z context to apply SELinux context after initialization\n"
" -l IPv4 address to listen on for incoming dns traffic " " -l IPv4 address to listen on for incoming dns traffic "
"(default 0.0.0.0)\n" "(default 0.0.0.0)\n"
" (Use 'external' to listen only on external IP, looked up via a service)\n"
" -L IPv6 address to listen on for incoming dns traffic " " -L IPv6 address to listen on for incoming dns traffic "
"(default ::)\n" "(default ::)\n"
" -p port to listen on for incoming dns traffic (default 53)\n" " -p port to listen on for incoming dns traffic (default 53)\n"
" -n ip to respond with to NS queries\n" " -n ip to respond with to NS queries\n"
" (Use 'auto' to look up external IP via a service)\n" " (Use 'auto' to use the external IP, looked up via a service)\n"
" -b port to forward normal DNS queries to (on localhost)\n" " -b port to forward normal DNS queries to (on localhost)\n"
" -P password used for authentication (max 32 chars will be used)\n" " -P password used for authentication (max 32 chars will be used)\n"
" -F pidfile to write pid to a file\n" " -F pidfile to write pid to a file\n"
@ -2578,18 +2579,32 @@ main(int argc, char **argv)
foreground = 1; foreground = 1;
} }
if (addrfamily == AF_UNSPEC || addrfamily == AF_INET) { if (addrfamily == AF_UNSPEC || addrfamily == AF_INET) {
if (listen_ip4 && strcmp("external", listen_ip4) == 0) {
struct in_addr extip;
int res = get_external_ip(&extip);
if (res) {
fprintf(stderr, "Failed to get external IP via DNS query.\n");
exit(3);
}
listen_ip4 = inet_ntoa(extip);
fprintf(stderr, "Will listen on external IP %s\n", listen_ip4);
}
dns4addr_len = get_addr(listen_ip4, port, AF_INET, AI_PASSIVE, &dns4addr); dns4addr_len = get_addr(listen_ip4, port, AF_INET, AI_PASSIVE, &dns4addr);
if (dns4addr_len < 0) { if (dns4addr_len < 0) {
warnx("Bad IPv4 address to listen on."); warnx("Bad IPv4 address to listen on: '%s'", listen_ip4);
usage(); usage();
} }
// Use dns4addr from here on.
listen_ip4 = NULL;
} }
if (addrfamily == AF_UNSPEC || addrfamily == AF_INET6) { if (addrfamily == AF_UNSPEC || addrfamily == AF_INET6) {
dns6addr_len = get_addr(listen_ip6, port, AF_INET6, AI_PASSIVE, &dns6addr); dns6addr_len = get_addr(listen_ip6, port, AF_INET6, AI_PASSIVE, &dns6addr);
if (dns6addr_len < 0) { if (dns6addr_len < 0) {
warnx("Bad IPv6 address to listen on."); warnx("Bad IPv6 address to listen on: '%s'", listen_ip6);
usage(); usage();
} }
// Use dns6addr from here on.
listen_ip6 = NULL;
} }
if (bind_enable) { if (bind_enable) {