Using dnsmasq/iptables to redirect DNS/HTTP traffic on Tomato

It does indeed redirect all traffic to trailers.apple.com to the router because of the dnsmasq config. There isn't a way there to feed the address based on the source IP or anything like that. However, there are more things that are possible.

Here's an example without ATV modifications to DNS and still runs them on non-priv ports. 

When presented with multiple options (1a, 1b) just do one of them.

1a) Intercept DNS traffic to trailers.apple.com and redirect to the PlexConnect DNS server on a different port with dnsmasq

Add this to your dnsmasq config to redirect DNS queries for trailers.apple.com to a different host and port (keeps it out of the way of my existing DNS servers on port 53):

  server=/trailers.apple.com/172.16.32.2#8053

This delegates DNS resolving for trailers.apple.com to PlexConnect which can decide how to go about serving it up.

WARNING: A loop is possible though if PlexConnect tries to query for trailers.apple.com

1b) Intercept DNS traffic to trailers.apple.com and redirect to the PlexConnect DNS server on a different port with iptables

 
Add this to the firewall config:
 

  iptables -t nat -A PREROUTING -s 172.16.32.12 -d 172.16.32.1 -p udp --dport 53 -j DNAT --to-destination 172.16.32.2:8053

This will grab traffic headed to the router from the ATV and redirect to PlexConnect. This will avoid a loop if the PlexConnect box does a lookup for trailers.apple.com unlike method 1a.

This should be nearly identical to changing the DNS on the ATV except it can be directed to PlexConnect DNS running on any port.

2) Patch DNSServer.py to change the bind on port 53 for DNS to another port

Since we will be using the DNS server in PlexConnect for the ATV, but on a different port, edit DNSServer.py and change 

  DNS.bind(('',53))

to something like this

  DNS.bind(('',8053))

If this ends up useful it may be a good idea to make this a config like ip_server and port_server are.

3a) Redirect traffic headed to port 80 on the Plex Server from the ATV to another port (this is for OS X Lion or higher)

I don't have time to write up the entire thing nicely (so it survives reboots, etc), but basically you can add this to pf (the packet firewall) and it'll grab incoming HTTP traffic and send it to another port. See http://blog.scottlowe.org/2013/05/15/using-pf-on-os-x-mountain-lion/ for instructions on how to make this auto-run on reboot and such.

Edit /etc/pf.conf and add this line near the rdr-anchor line:

  rdr on en0 inet proto tcp from 172.16.32.12 to any port www -> 127.0.0.1 port 8090
 
Enable and reload pf with:
 
  pf -E -f /etc/pf.conf
 
This redirects incoming traffic from the ATV to the local 8090 port. 
 
3b) Redirect traffic on the local Apache server to the Plex Server using a reverse proxy
 
Someone else has instructions for this already using a vhost I believe. Pretty easy.
 
-- 
 
Anyway, there are probably a few more options out there :)
 
A few more things are possible by allowing the DNS server in PlexConnect to advertise a different IP from IP_Self (the router). This would let you put the firewall rule on the router consolidating rules and keeping things tidy.
 
At that point I would really want to get this on the Tomato router and not have anything run on my OS X server keeping PMS on the server (or NAS, desktop, etc) and PlexConnect plus these rules on the router. That way PlexConnect could just use IP_Self, everything would be in one place, etc.
 
Perhaps that's what I'll do soon. My initial run had an error in multiprocessing. Not sure if semaphores work on Tomato (tried mounting /dev/shm as a tempfs and such. Hmm).