NAT/IP Masquerading and UFW
After getting OSPF working with UFW, it turned out I had a need to configure NAT/IP Masquerading as well.
After some troubleshooting and screwing around, here are the usable cliff notes.
1. sudo apt install ufw
2. sudo ufw disable
3. Add the following line to /etc/sysctl.conf:
net.ipv4.ip_forward = 1
4. Save the file and type the command:
sysctl -p
5. Add the following lines to the end of the /etc/ufw/before.rules file:
COMMIT
# Setting up NAT
*nat
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -s <lan subnet> -o eth0 -j MASQUERADE
# don't delete the 'COMMIT' line or these rules won't be processed
COMMIT
Note 1. The first COMMIT finishes the *filter table, which starts further up. You then start a NAT/IP Masquerading table with the *nat line, which needs to be committed afterwards as well. Hence the second 'COMMIT'.
Note 2. Don't add anything to the after.rules file and don't add anything to the user.rules file either (unless of course, you know what you are doing).
6. sudo ufw default deny forward
7. sudo ufw allow in on eth1
8. sudo ufw route allow in on eth0 out on eth1
9. sudo ufw route allow in on eth1 out on eth0
10. sudo ufw allow in on eth0 from EXTERNAL-WAN-IP to WAN-IP port 22 proto tcp
11. sudo ufw allow in on eth1 from INTERNAL-LAN-IP to LAN-IP port 22 proto tcp
12. sudo ufw enable
Note! If you've been screwing around with this all day and the above doesn't work, try rebooting first.
1. Install UFW
2. Disable the firewall for good measure, especially if you're doing something silly like testing in production :-/
3. Update the /etc/sysctl.conf file to enable IP Forwarding in the Kernel. Yes, there's a UFW file for this too. You can uncomment the same line in /etc/ufw/sysctl.conf if you wish. Doing both won't break anything, it's just redundant. If you only make the change in this file: /etc/ufw/sysctl.conf it will only be effective while UFW is running. Could be problematic if you trying to troubleshoot a routing issue with the firewall off.
4. Safe the changes and validate the change. You should see the line you just added printed to the screen. If you dediced to use the /etc/ufw/sysctl.conf file instead, you won't see anything printed to the screen.
5. Set up the NAT/IP Masquerading Table in UFW. It's not there by default.
6. Just in case you already tried enabling forwarding in UFW, let's make sure it's disabled. That feature doesn't do what you think it does.
7. Allow traffic inbound from your LAN interface.
8. Allow traffic to traverse your firewall from the WAN interface to the LAN interface.
9. Allow traffic to traverse your firewall from the LAN interface to the WAN interface.
10. You'll probably want to allow SSH access to your firewall from outside your network. This command locks down external access to a single IP outside your network. If you need a little more freedom then that, try:
sudo ufw allow in on eth0 from any to any port 22 proto tcp
EXTERNAL-WAN-IP The IP Address you will be accessing the firewall from, outside your network.
WAN-IP The IP Address assigned to eth0.
11. You'll probably want to allow SSH access to your firewall from inside your network. This command locks down internal access to a single IP inside your network. If you need a little more freedom then that, try:
sudo ufw allow in on eth1 from any to any port 22 proto tcp
INTERNAL-LAN-IP The IP Address you will be accessing the firewall from, inside your network.
LAN-IP The IP Address assigned to eth1
12. Enable the firewall.
Note 1. Unfortunately, you can't setup the NAT/IP Masquerading table with native UFW commands. From an automation point of view, I'm focusing on simplicity without too much file modification. This is just a necassary complexity.
Note 2. You do not need to allow traffic in on eth0. i.e. do not issue the following command:
sudo ufw allow in on eth0
This would effectively open your firewall to everyone and everything on the internet. It's required on the LAN interface for traffic passing through and out to the internet, but it is not required for traffic returning by request. Inbound traffic should be allowed by specific rules only, such as the rule in Step 10.