I need to renumber the machine poly.polyamory.org onto a new network. I decided rather than trying to arrange time when cos and I are both available, I would switch tactics a bit so that both the new and the old IP addresses are active, and then he can do the DNS change at any time. So, I spent some time playing with Netfilter (iptables) getting it to do what I want.
The machine “neko-base” serves as my personal mail server, web server, dns server for myself and a few friends. It is also the firewall for our internal desktops. So, all connections are allowed from the inside going out, and only certain connections are allowed coming in.
I already had statements like these two to allow outbound access (and replies to an outgoing request when they come back)
iptables -A block -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A block -m state --state NEW -i ! eth0 -j ACCEPT
I added some entries to allow specific services that I know the outside will want to access on my box, for destination port values http, ssh, smtp, domain (tcp and udp), auth (ident), and a couple other port numbers that have mushes.
iptables -A block -p tcp --dport http -j ACCEPT
I then have some private services that are only available from certain IP addresses (-s = source ip)
iptables -A block -p tcp --dport rsync -s 209.157.144.18 -j ACCEPT
If anything makes it this far down in the “block” chain, it should be dropped, but I added a bit to log them to syslog.
iptables -A block -j LOG --log-level notice --log-prefix FIREWALL-DROP:
iptables -A block -j DROP
Finally we apply the “block” rule to the INPUT chain. (“block” in this case is just a name we made up for this rule. Probably “myfilter” would have been a more useful name.)
iptables -A INPUT -j block
Because we are sharing an IP address (and the desktops on the internal network don’t have their own valid external IP addresses) we must set up NAT translation. This is the code I use to invoke NAT.
iptables -t nat -F POSTROUTING
iptables -t nat -A POSTROUTING -s 10.12.1.16/29 -d ! 10.12.1.16/29 -j SNAT --to-source 64.139.47.218
echo "1" >> /proc/sys/net/ipv4/ip_forward
Now the change for today was to add a new IP address to the machine, so that we could process packets intended for poly and redirect them there. I am not sure if I want to keep poly as an internal machine, but it might make sense. I will probably keep it on until I am able to move poly into the other room where it can have an external IP, and I will also give it a firewall of its own at that time. For now this will be temporary. So, we identify packets bound for the new poly external address (which we have added as an alias on our external interface) and redirect them to poly (which just received a new internal IP address). This is repeated for ports http, smtp, ssh, and domain.
iptables -t nat -A PREROUTING -p tcp --dport http -d 64.139.47.220 -j DNAT --to-destination 10.12.1.21
If they are not intended for an approved port, we again log them and drop them.
iptables -t nat -A PREROUTING -d 64.139.47.220 -j LOG --log-level notice --log-prefix FIREWALL-DROP:
iptables -t nat -A PREROUTING -d 64.139.47.220 -j DROP
Finally, we need the packets to come back to us so we can undo the mangling we did on the destination address (for outbound packets this will be reflected in the source address — the replies are from poly’s internal interface IP, not from the expected external reply ip). This is something that iptables normally takes care of automatically, but because poly is currently attached to some other router, we would not normally see the packets on the way out. So the answer to this is to have a source nat as well as a destination nat; this is so that poly will think all the requests are coming from neko-base itself and will send the replies our way even though that is not the default route. (This can probably be removed later once we make neko-base the default route)
iptables -t nat -A POSTROUTING -d 10.12.1.21 -j SNAT --to-source 64.139.47.218
That is all for now. The new solution appears to be working; we will see what happens when the DNS is changed on Tuesday.