Using one Linode as a firewall/router for all others.
I've done this before at my place with multiple servers, my linux router handles all traffic for all servers; but it is a little messy. It's done entirely using routing with IPTables and the way it is subnet 2 (the servers) can access Subnet 1 (Home LAN and Internet) but Home LAN needs to go in over the net to access server, or I setup a route on each PC.
Now I could probably duplicate this, but I don't want to. Although I've never bridged before, I've been told it's a good method. Right now I'm trying to determine what I should do. And maybe how to do it after that, though hopefully I can handle it.
My idea at this point is to take the IP off my secondary Linode, and assign it to the one acting as the gateway, that way I can use IPTables to simply forward traffic to the second server's public IP - Is possible? (It's not like my setup at home, though it may sound like
Suggestions on a better method are much welcome, also if anyone has done something similar before and is wanting to share exactly how they did it, that'd be great.
For reference the primary Linode is running Ubuntu 7.10 and the secondary running Debian 4.0.
Thanks In Advance.
20 Replies
It's a pretty impressive package, and would basically mean that your "firewall" linode would have all the capability of an enterprise class hardware firewall. Not sure how you'd go about installing it on a linode, but I'm sure its possible and would be a nice project for you to enjoy
"m0n0wall is a project aimed at creating a complete, embedded firewall software package that, when used together with an embedded PC, provides all the important features of commercial firewall boxes (including ease of use) at a fraction of the price (free software).
m0n0wall is based on a bare-bones version of FreeBSD, along with a web server, PHP and a few other utilities. The entire system configuration is stored in one single XML text file to keep things transparent."
I do want to try it out though…I just need to get a spare box ready for it!
Thanks for the suggestion.
@geekman:
Hi, I currently have two Linodes, I want to use one as my router/firewall for both Linodes (and more if I get more) so I don't need to maintain multiple firewalls. Both Linodes are currently at Dallas so I've enabled private IP's in the hope that I can get one to act as a gateway for the other without any increase in traffic use.
That would be interesting to find out because of the whole issue of bringing up IPs that are assigned to a different Linode (using the IP Failover feature). I'm pretty sure traffic is accounted for per Linode, not per person, but I'm not sure if the traffic would be accounted for the Linode the IP address is actually assigned to (your secondary Linode) or the Linode that actually has the IP address up (your gateway Linode).
@geekman:
My idea at this point is to take the IP off my secondary Linode, and assign it to the one acting as the gateway, that way I can use IPTables to simply forward traffic to the second server's public IP - Is possible?
That should work fine except you'd have to forward traffic to the second server's private IP since you can't bring up it's real IP two times (on it and the gateway, like you described). I assume you're talking about some NAT sort of setup?
As for bridging, I haven't used it in any real-word situations (only virtualized), so I couldn't tell you about that option.
Have fun!
We're also working out a mechanism whereby traffic is pooled between all your Linode accounts which would make either case moot.
-Chris
@JDM:
@geekman:Hi, I currently have two Linodes, I want to use one as my router/firewall for both Linodes (and more if I get more) so I don't need to maintain multiple firewalls. Both Linodes are currently at Dallas so I've enabled private IP's in the hope that I can get one to act as a gateway for the other without any increase in traffic use.
That would be interesting to find out because of the whole issue of bringing up IPs that are assigned to a different Linode (using the IP Failover feature). I'm pretty sure traffic is accounted for per Linode, not per person, but I'm not sure if the traffic would be accounted for the Linode the IP address is actually assigned to (your secondary Linode) or the Linode that actually has the IP address up (your gateway Linode).
@geekman:My idea at this point is to take the IP off my secondary Linode, and assign it to the one acting as the gateway, that way I can use IPTables to simply forward traffic to the second server's public IP - Is possible?
That should work fine except you'd have to forward traffic to the second server's private IP since you can't bring up it's real IP two times (on it and the gateway, like you described). I assume you're talking about some NAT sort of setup?
As for bridging, I haven't used it in any real-word situations (only virtualized), so I couldn't tell you about that option.
Have fun!
When I said "PTables to simply forward traffic to the second server's public IP" I actually meant the second servers private IP.
And yeah I suppose that is NAT…kind of, though it would be different in that the gateway simply forwards traffic based on the Public IP given in the request. Only thing I'm not too sure of is how to maintain a proper connection to the internet from the secondary server, without having a public IP assigned to it. Simple as telling it to set the secondary server's gateway as the Private IP of my proposed gateway? Is it even possible to configure Linode one to have both Public IP's while having no public IP on Linode 2? I can probably just use Lish untill I get it routing correctly, right?
Thanks in Advance.
#/sbin/modprobe ip_conntrack_ftp
#/sbin/modprobe ip_nat_ftp
Currently have those modules commented out as they like to error and don't seem to be enabled in that way. Instead it says the following:
FATAL: Could not load /lib/modules/2.6.23.17-linode43/modules.dep: No such file or directory
FATAL: Could not load /lib/modules/2.6.23.17-linode43/modules.dep: No such file or directory
Although I don't need these modules, I'd like to use NAT with FTP so i'd like them. I am hoping for one of two things here, are these modules already enabled for use in IPTables, or is there another way of enabling them?
Thanks.
@geekman:
And yeah I suppose that is NAT…kind of, though it would be different in that the gateway simply forwards traffic based on the Public IP given in the request. Only thing I'm not too sure of is how to maintain a proper connection to the internet from the secondary server, without having a public IP assigned to it. Simple as telling it to set the secondary server's gateway as the Private IP of my proposed gateway? Is it even possible to configure Linode one to have both Public IP's while having no public IP on Linode 2? I can probably just use Lish untill I get it routing correctly, right?
Thanks in Advance.
It's still NAT because you're translating traffic to a private IP from a public one.. though you're right that it is different from regular home NAT, I believe in this case it would be called SNAT instead of normal DNAT or masquerading. Correct, you would do it by having the gateway set up to route and have it's private IP set as the default gateway on the second Linode (like you would set a home router's private IP as the default gateway to use it to connect to the internet).
As for your last question, it's entirely possible to just have a private IP active on a Linode. You could even bring up no and just use Lish all the time (I don't think you would want to though).
Here's how the interface is setup:
# Used by ifup(8) and ifdown(8). See the interfaces(5) manpage or
# /usr/share/doc/ifupdown/examples for more information.
# The loopback interface
auto lo
iface lo inet loopback
# The first network card - this entry was created during the Debian installation
# (network, broadcast and gateway are optional)
auto eth0
iface eth0 inet dhcp
auto eth1
iface eth1 inet static
address 192.168.130.1xx
netmask 255.255.128.0
# Secondary Linode IP (morpheus)
auto eth0:0
iface eth0:0 inet static
address 67.18.208.xx
netmask 255.255.255.0
gateway 67.18.208.1
And here's the routing table:
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
67.18.208.0 * 255.255.255.0 U 0 0 0 eth0
192.168.128.0 * 255.255.128.0 U 0 0 0 eth1
link-local * 255.255.0.0 U 1000 0 0 eth0
default gateway23.linod 0.0.0.0 UG 100 0 0 eth0
root@theconstruct:/etc/router # cat /etc/network/interfaces
Probably missing something stupid, though I feel like I covered t
Thanks.
@geekman:
# Used by ifup(8) and ifdown(8). See the interfaces(5) manpage or # /usr/share/doc/ifupdown/examples for more information. # The loopback interface auto lo iface lo inet loopback # The first network card - this entry was created during the Debian installation # (network, broadcast and gateway are optional) auto eth0 iface eth0 inet dhcp auto eth1 iface eth1 inet static address 192.168.130.1xx netmask 255.255.128.0 # Secondary Linode IP (morpheus) auto eth0:0 iface eth0:0 inet static address 67.18.208.xx netmask 255.255.255.0 gateway 67.18.208.1
I only have one Linode and one IP so I can't tell you for sure, but it looks like you might be setting the multiple IPs up wrong (eth0 and eth0:1 instead of eth0:0 and eth0:1). Check the wiki entry
Also, have you rebooted since using the IP Failover tool to allow your gateway Linode to bring up the second's IP? This might be necessary. Linode has some fancy firewalling that makes sure you don't bring up IPs that don't belong to you, (and unless something has changed recently) it only updates with new authorizations when you boot.
route add default gw 192.168.130.1xx
Which is the LAN IP of the router (which it can ping), the second Linode can't currently access the internet. Thus, I cannot use TCPDump to see if any traffic is getting through right now.
Here's the output of TCPDump:
07:55:26.560459 IP dsl-203-33-160-120.NSW.netspace.net.au.3994 > morpheus.www: S 1943587100:1943587100(0) win 65535 <mss 1412,nop,wscale="" 0,nop,nop,sackok="">07:55:29.461899 IP dsl-203-33-160-120.NSW.netspace.net.au.3994 > morpheus.www: S 1943587100:1943587100(0) win 65535 <mss 1412,nop,wscale="" 0,nop,nop,sackok="">07:55:35.397855 IP dsl-203-33-160-120.NSW.netspace.net.au.3994 > morpheus.www: S 1943587100:1943587100(0) win 65535</mss></mss>
I'll dig up the output from my server at home which has a somewhat similar setup later.
Thanks.
device eth1 entered promiscuous mode
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 96 bytes
08:15:47.978046 arp who-has none.local tell 192.168.130.1xx
08:16:13.077115 arp reply none.local is-at fe:fe:c0:a8:82:96 (oui Unknown)
08:15:47.978794 IP none.local.32774 > 192.168.130.1xx.domain: 65356+ PTR? 150.130.168.192.in-addr.arpa. (46)
08:15:52.977028 arp who-has 192.168.130.1xx tell none.local
08:15:52.977159 IP none.local.32775 > 192.168.130.1xx.domain: 65356+ PTR? 150.130.168.192.in-addr.arpa. (46)
08:15:52.977301 arp reply 192.168.130.1xx is-at fe:fe:c0:a8:82:9b (oui Unknown)
08:15:58.077313 IP none.local.mdns > 224.0.0.251.mdns: 0 PTR? 150.130.168.192.in-addr.arpa. (46)
08:15:58.077420 IP none.local.mdns > 224.0.0.251.mdns: 0*- [0q] 1/0/0 (Cache flush) PTR[|domain]
08:15:58.077738 IP none.local.32776 > 192.168.130.1xx.domain: 6999+ PTR? 1xx.130.168.192.in-addr.arpa. (46)
08:16:03.076581 IP none.local.32778 > 192.168.130.1xx.domain: 6999+ PTR? 1xx.130.168.192.in-addr.arpa. (46)
08:16:08.176752 IP none.local.mdns > 224.0.0.251.mdns: 0 PTR? 1xx.130.168.192.in-addr.arpa. (46)
08:16:09.177623 IP none.local.mdns > 224.0.0.251.mdns: 0 PTR? 1xx.130.168.192.in-addr.arpa. (46)
08:16:11.178307 IP none.local.mdns > 224.0.0.251.mdns: 0 PTR? 1xx.130.168.192.in-addr.arpa. (46)
08:16:13.077426 IP none.local.32779 > 192.168.130.1xx.domain: 60638+ PTR? 251.0.0.224.in-addr.arpa. (42)
08:16:18.076188 arp who-has 192.168.130.1xx tell none.local
08:16:18.076362 IP none.local.32780 > 192.168.130.1xx.domain: 60638+ PTR? 251.0.0.224.in-addr.arpa. (42)
08:16:18.076470 arp reply 192.168.130.1xx is-at fe:fe:c0:a8:82:9b (oui Unknown)
08:16:23.176470 IP none.local.mdns > 224.0.0.251.mdns: 0 PTR? 251.0.0.224.in-addr.arpa. (42)
08:16:24.177330 IP none.local.mdns > 224.0.0.251.mdns: 0 PTR? 251.0.0.224.in-addr.arpa. (42)
08:16:26.178025 IP none.local.mdns > 224.0.0.251.mdns: 0 PTR? 251.0.0.224.in-addr.arpa. (42)
Looks kind of like it's doing a reverse lookup on the LAN IP maybe? I've not seen this before. And I would assume DNS lookups would be OK since I set the primary DNS as the router - though it could all be buggered if my routing is off I guess.
Thanks.
@geekman:
Thanks. I realised I rebooted the router but not the other one. I also changed the interface of the new IP to eth0:1 just in case. Now i can see the port 80 requests coming in when I try and get to the new IP, though I can't see the router forwarding that request onto the actual server.
Have you actually set up IPTables to forward the traffic yet? I can't find anything mentioning that you did.
@geekman:
On top of this, although I used:
route add default gw 192.168.130.1xx
You shouldn't have to do that… just setting your gateway Linode's private IP as the gateway in /etc/network/interfaces should do the trick.
@geekman:
Looks kind of like it's doing a reverse lookup on the LAN IP maybe? I've not seen this before. And I would assume DNS lookups would be OK since I set the primary DNS as the router - though it could all be buggered if my routing is off I guess.
Is there actually a DNS server running on the gateway Linode? (there's not unless you've configured one)
I meant to post my IPTables rules before I left but forgot. Here they are:
Routing rules:
# Morpheus
# HTTP
iptables -t nat -A PREROUTING -d $morpheus -p TCP --dport 80 -j DNAT --to-destination $morpheus_lan:80
# SSH
iptables -t nat -A PREROUTING -d $morpheus -p TCP --dport 22 -j DNAT --to-destination $morpheus_lan:22
I was going to use interface instead of destination, but it didn't like eth0:1.
Firewall rules for secondary Linode:
# Logging
# Incoming Services
# HTTP
iptables -A FORWARD -j ACCEPT -d $morpheus -p TCP --dport 80 -m state --state NEW
# SSH
iptables -A FORWARD -j ACCEPT -d $morpheus -p TCP --dport 22 -m state --state NEW
# Temporary Rules
# Outgoing Services
# Allow all outgoing traffic from the server. Needs to be tightened.
iptables -A FORWARD -j ACCEPT -s $morpheus_lan
And just because it's easier for me this way…here's all the rules via iptables -L
Chain INPUT (policy DROP)
target prot opt source destination
ACCEPT 0 -- anywhere anywhere state RELATED,ESTABLISHED
ACCEPT icmp -- anywhere anywhere
LOG 0 -- anywhere anywhere LOG level debug prefix `BANDWIDTH_IN:'
ACCEPT tcp -- anywhere theconstruct tcp dpt:ssh state NEW
ACCEPT tcp -- anywhere theconstruct tcp dpt:www state NEW
ACCEPT tcp -- anywhere theconstruct tcp dpt:ftp state NEW
ACCEPT tcp -- anywhere theconstruct tcp dpt:smtp state NEW
ACCEPT tcp -- anywhere theconstruct tcp dpt:https state NEW
ACCEPT tcp -- anywhere theconstruct tcp dpt:pop3 state NEW
ACCEPT tcp -- anywhere theconstruct tcp dpt:imap2 state NEW
ACCEPT tcp -- anywhere theconstruct tcp dpt:imaps state NEW
ACCEPT tcp -- anywhere theconstruct tcp dpt:pop3s state NEW
ACCEPT tcp -- anywhere theconstruct tcp dpt:svn state NEW
ACCEPT tcp -- anywhere theconstruct tcp dpt:6666 state NEW
ACCEPT tcp -- anywhere theconstruct tcp dpt:4001 state NEW
ACCEPT tcp -- anywhere theconstruct tcp dpt:4000 state NEW
ACCEPT tcp -- anywhere theconstruct tcp dpt:7777 state NEW
ACCEPT tcp -- anywhere theconstruct tcp dpt:8806 state NEW
Chain FORWARD (policy DROP)
target prot opt source destination
ACCEPT 0 -- anywhere anywhere state RELATED,ESTABLISHED
ACCEPT icmp -- anywhere anywhere
ACCEPT udp -- anywhere anywhere udp dpts:33434:33523 state NEW
ACCEPT 0 -- dsl-203-33-160-120.NSW.netspace.net.au anywhere state NEW
LOG 0 -- anywhere anywhere LOG level debug prefix `BANDWIDTH_OUT:'
LOG 0 -- anywhere anywhere LOG level debug prefix `BANDWIDTH_IN:'
ACCEPT tcp -- anywhere morpheus tcp dpt:www state NEW
ACCEPT tcp -- anywhere morpheus tcp dpt:ssh state NEW
ACCEPT 0 -- 192.168.130.1xx (LAN IP of 2nd Linode) anywhere
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
LOG 0 -- anywhere anywhere LOG level debug prefix `BANDWIDTH_OUT:'
Thanks!
Some more info.
Router
------
eth0:
listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes
22:28:35.615679 IP dsl-203-33-160-120.NSW.netspace.net.au.4336 > morpheus.www: S 2302786697:2302786697(0) win 65535 <mss 1412,nop,wscale="" 0,nop,nop,sackok="">22:28:38.597072 IP dsl-203-33-160-120.NSW.netspace.net.au.4336 > morpheus.www: S 2302786697:2302786697(0) win 65535 <mss 1412,nop,wscale="" 0,nop,nop,sackok="">22:28:44.619361 IP dsl-203-33-160-120.NSW.netspace.net.au.4336 > morpheus.www: S 2302786697:2302786697(0) win 65535 <mss 1412,nop,wscale="" 0,nop,nop,sackok="">eth0:1:
listening on eth0:1, link-type EN10MB (Ethernet), capture size 96 bytes
22:29:19.851338 IP dsl-203-33-160-120.NSW.netspace.net.au.4337 > morpheus.www: S 1453502692:1453502692(0) win 65535 <mss 1412,nop,wscale="" 0,nop,nop,sackok="">22:29:22.859050 IP dsl-203-33-160-120.NSW.netspace.net.au.4337 > morpheus.www: S 1453502692:1453502692(0) win 65535 <mss 1412,nop,wscale="" 0,nop,nop,sackok="">22:29:28.993963 IP dsl-203-33-160-120.NSW.netspace.net.au.4337 > morpheus.www: S 1453502692:1453502692(0) win 65535 <mss 1412,nop,wscale="" 0,nop,nop,sackok="">(I realised I hadn't checked out eth1 before, so this probably has always had this output)
eth1:
listening on eth1, link-type EN10MB (Ethernet), capture size 96 bytes
22:30:06.411563 IP dsl-203-33-160-120.NSW.netspace.net.au.4346 > 192.168.130.1xx.www: S 1773345872:1773345872(0) win 65535 <mss 1412,nop,wscale="" 0,nop,nop,sackok="">22:30:09.213987 IP dsl-203-33-160-120.NSW.netspace.net.au.4346 > 192.168.130.1xx.www: S 1773345872:1773345872(0) win 65535 <mss 1412,nop,wscale="" 0,nop,nop,sackok="">22:30:15.150333 IP dsl-203-33-160-120.NSW.netspace.net.au.4346 > 192.168.130.1xx.www: S 1773345872:1773345872(0) win 65535 <mss 1412,nop,wscale="" 0,nop,nop,sackok="">The LAN IP is that of the secondary Linode.
Secondary Linode
----------------
eth1:
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 96 bytes</mss></mss></mss></mss></mss></mss></mss></mss></mss>
It seems as though the arp stuff coming up before was the second Linode wanting to do
a reverse lookup on the routers LAN IP. Probably cause before I had the router set as it's DNS. So that makes me think that the traffic is
getting through.
Since it looks to me that eth1 on the router is infact being forwarded the traffic, annd
wants to pass it onto the secondary Linode, is this maybe not the routers fault?
Shrug. I can say that the secondary Linode does not have IPTables being used on it.
I can also verify that apache works fine locally on the second Linode.
Thanks.
Have you set the necessary sysctl in sysctl.conf (net.ipv4.conf.default.forwarding)? That's necessary for your Linode to actually forward any traffic.
Beyond this, I'm pretty much out of ideas.
echo 1 > /proc/sys/net/ipv4/ip_forward
Also picked this up from my router at home (which I could remember exactly what half these rules did). So I'll play around with that see what happens.
iptables --table nat --append POSTROUTING --out-interface 'eth0' --jump MASQUERADE
iptables --append FORWARD --protocol tcp --tcp-flags SYN,RST SYN --jump TCPMSS --clamp-mss-to-pmtu
When you say I'll need to use it somewhere, would you happen to know if that's Router to WAN traffic or LAN to LAN traffic? RTFM on IPTables again soon anyways.
Thanks for all the help!
# For INPUT/OUTPUT chains.
iptables --insert OUTPUT 1 --source 0.0.0.0/0.0.0.0 --destination $morpheus_lan --jump ACCEPT --out-interface 'eth1'
iptables --insert INPUT 1 --source $morpheus_lan --destination 0.0.0.0/0.0.0.0 --jump ACCEPT --in-interface 'eth1'
# For FORWARD chains.
iptables --insert FORWARD 1 --source 0.0.0.0/0.0.0.0 --destination $morpheus_lan --jump ACCEPT --out-interface 'eth1'
iptables --insert FORWARD 1 --source $morpheus_lan --destination 0.0.0.0/0.0.0.0 --jump ACCEPT
iptables --table nat --append POSTROUTING --out-interface 'eth1' --jump MASQUERADE
iptables --append FORWARD --protocol tcp --tcp-flags SYN,RST SYN --jump TCPMSS --clamp-mss-to-pmtu
The only rule I don't really get is the last one, but I took a guess thinking that maybe I needed that rule before the Secondary Linode could send ack packets, maybe not. But it works.
Despite being able to access the services on the second Linode, it still can't access the internet. I'm thinking probably those rules need some tweaking though.