My poor man’s DNS-unblocking configuration using just a single, public IP address has one serious limitation: it will not run Netflix or Hulu Plus with non-SNI players like the PS3, Xbox 360, Samsung TVs, Sony BluRay players and possibly quite a few other devices. A commenter (kudos go out to Alex) suggested to use Netfilter’s DNAT port forwarding mechanism to overcome this limitation. Using DNAT you can forward packets based on the source-ip:port to a remote-ip:port.
So, here’s a modified version of the poor man’s DNS-unblocking approach. You will need some sort of Linux server at home to do this. I’m using a Raspberry Pi Linux mini computer which is up 24/7 on my LAN. And of course you will need a remote Linux server with an IP address registered in the U.S. You can get a low-end virtual private server for as low as $5/year. Unfortunately, it’s almost impossible to come up with a step-by-step tutorial because every LAN setup is different, hence you have to have some Linux and networking skills in order to get this baby up and running.
And here’s how this approach works: A DNS forwarder like Dnsmasq on your local Linux server will intercept domain names relevant for DNS unblocking. All other queries will be forwarded to the DNS resolver/forwarder of your choice (usually, this will be your router). The intercepted domain names will be resolved to IP addresses which are routed to your Linux server within your LAN. Depending on the resolved IP addresses and ports, iptables DNAT rules will forward the request to a HAProxy proxy on your remote server. Each domain name can have its own internal IP adress and thus its own listening port on your remote server’s HAProxy. And since every domain name can have it’s own HAProxy TCP proxy on your remote server, there’s no need for SNI!
For example: a DNS query to www.some-geofenced-service.com will not be resolved to its actual IP address 18.104.22.168, it will be resolved to 192.168.178.201 thanks to the internal DNS forwarder. The device asking for www.some-geofenced-service.com’s IP address will try to establish a HTTPS connection to 192.168.178.201:443 which is routed to a Linux server within your LAN. A DNAT rule will transparently forward all packets sent to 192.168.178.201:443 to 123.123.123:27201 which is the remote server running HAProxy. The HAProxy proxy listening on port 22.214.171.124:27201 will then forward all layer 4 traffic to www.some-geofenced-service.com:443.
Just enter your local Linux server’s IP address as the DNS address in every device you want to DNS-unblock. You could also set the DNS server address in your router to your local Linux server’s address but make sure not to create an infinite DNS query loop.
A complete configuration file for HAProxy. Use it on your remote server’s HAProxy.
All required DNS mappings for your specified range of internal IP addresses. Put this file in /etc/dnssmasq.d (Debian/Ubuntu) on your local Linux server.
The DNAT iptables rules. Make sure to load these rules whenever your local Linux server starts.
A few words about the config.json input file for the generator:
IP address of your remote HAProxy server
Starting IP address for the DNAT rules. Make sure to use static IP addresses in sequential order and route them to your local Linux server using virtual interfaces. Make sure the static IP range doesn’t interfere with your router’s DHCP settings or weird things will happen.
Starting port for the HAProxy proxies.
HAProxy proxy name
true/false, set it to true if you want to use a catchall/sni HAProxy for this destination address. I primarily added this feature in order to save IP addresses within the LAN and to reduce the amount of iptables rules and HAProxy configuration entries. Has to be set to false it your device needs can’t handle SNI. When in doubt, set to false.
The generator will provide rules to open the inbound firewall on the remote HAProxy server. Additional rules may be required if you’re firewalling the FORWARD and OUTBOUND chains as well. If something doesn’t work as expected, tcpdump is your friend.
php genconf.php Make sure the following IP addresses are available as virtual interfaces on your Ddnsmasq-server: 192.168.178.51 192.168.178.52 192.168.178.53 192.168.178.54 192.168.178.55 192.168.178.56 192.168.178.57 192.168.178.58 192.168.178.59 192.168.178.60 192.168.178.61 192.168.178.62 192.168.178.63 192.168.178.64 192.168.178.65 192.168.178.66 192.168.178.67 192.168.178.68 192.168.178.69 192.168.178.70 192.168.178.71 192.168.178.72 192.168.178.73 192.168.178.74 192.168.178.75 192.168.178.76 192.168.178.77 192.168.178.78 192.168.178.79 192.168.178.80 192.168.178.81 192.168.178.82 192.168.178.83 192.168.178.84 192.168.178.85 192.168.178.86 If you are using an inbound firewall on 126.96.36.199: /sbin/iptables -A INPUT -p tcp -m state --state NEW 188.8.131.52 --dport 27199 -j ACCEPT /sbin/iptables -A INPUT -p tcp -m state --state NEW -m multiport -d 184.108.40.206 --dports 27200:27270 -j ACCEPT File generated: haproxy.conf File generated: dnsmasq-haproxy.conf File generated: iptables-haproxy.conf
Don’t forget to enable packet forwarding on the local Linux server using
net.ipv4.ip_forward = 1