yarrick / iodine

Official git repo for iodine dns tunnel
https://code.kryo.se/iodine
ISC License
6.26k stars 508 forks source link

Bind to interface instead of IP address? #51

Closed Tabiskabis closed 3 years ago

Tabiskabis commented 3 years ago

I'm running iodine daemon on OpenWRT (Linux 4.14) Having a dynamic WAN IP, I'd find it great if iodined could listen on any IP, but only on a specific interface (WAN).

The current way of binding to 0.0.0.0 on any interface messes with my other DNS services.

Obviously I should (and will continue to try to) get a script hooked on an IP change on the WAN interface, that would then restart iodioned with the new address in the -l parameter (but apparently I'm too stupid for that).

lukastribus commented 3 years ago

That's not possible with the socket API.

You can listen to 0.0.0.0 and restrict the incoming traffic to a specific interface with SO_BINDTODEVICE (at least on linux), but then you still can't run your internal resolver on port 53 of the LAN IP (because 192.168.1.1:53 and 0.0.0.0:53 still conflicts).

You should bind to a different fixed IP on a loopback or something, or just run iodine on a different port, and direct the ingress traffic to that particular host:port tuple.

Nable80 commented 3 years ago

FYI: redirection can be achieved by using iptables REDIRECT or DNAT, e.g. (assuming eth0 = WAN interface and iodine listens on 5353)

iptables -t nat -A PREROUTING -p udp --dport 53 -i eth0 -j REDIRECT --to-port 5353
iptables -t nat -A PREROUTING -p tcp --dport 53 -i eth0 -j REDIRECT --to-port 5353

Socket options SO_REUSEADDR / SO_REUSEPORT are interesting too but this way may require modification of your internal resolver to use them too.

JuniorJPDJ commented 3 years ago

The NAT is good way for making this work on OpenWRT. Make it listen on 127.0.0.2:5353 and add nat rule for anything coming from WAN zone to router's IP on 53 port to get redirected (translated) to 127.0.0.2:5353.

yarrick commented 3 years ago

I recently (f2b619faada905) added support for listening only on the external IP, without having to specify it (it is fetched via DNS query). If you run iodined on the machine with the WAN ip, it should be enough to use this flag and just restart it whenever your address changes.