Ubuntu server as both a private NAT router and a public router
I am attempting to do something I've never tried before. I have a Dell PowerEdge 540 that I've installed Ubuntu on. I got a Comcast Business line installed, and have the following physical network configuration:
Ubuntu Server 20.04.3 LTS
enp10s0f0: (10gb SFP+ Add-on card)
IPv4: 5*.2*.204.214
Subnet: 255.255.255.252
Gateway: 5*.2*.204.213
enp10s0f1: (10gb SFP+ Add-on card)
IPv4: 5*.2*.205.1
Subnet: 255.255.255.0
eno1: (1gb copper ethernet)
IPv4: 10.0.0.0
Subnet: 255.0.0.0
This is the output of ip addr:
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eno1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:1e:c9:b5:b2:3c brd ff:ff:ff:ff:ff:ff
inet 10.0.0.1/8 brd 10.255.255.255 scope global eno1
valid_lft forever preferred_lft forever
inet6 ****::***:c9ff:feb5:b23c/64 scope link
valid_lft forever preferred_lft forever
3: eno2: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 00:1e:c9:b5:b2:3e brd ff:ff:ff:ff:ff:ff
4: enp12s0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 00:10:18:0d:a3:7e brd ff:ff:ff:ff:ff:ff
5: enp10s0f0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether f4:e9:d4:92:9d:d0 brd ff:ff:ff:ff:ff:ff
inet 5*.2*.204.214/30 brd 5*.2*.204.215 scope global enp10s0f0
valid_lft forever preferred_lft forever
inet6 fe80::f6e9:d4ff:fe92:9dd0/64 scope link
valid_lft forever preferred_lft forever
6: enp10s0f1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether f4:e9:d4:92:9d:d2 brd ff:ff:ff:ff:ff:ff
inet 5*.2*.205.1/24 brd 5*.2*.205.255 scope global enp10s0f1
valid_lft forever preferred_lft forever
inet6 ****::****:d4ff:fe92:9dd2/64 scope link
valid_lft forever preferred_lft forever
I have the following ip routes configured:
default via 5*.2*.204.213 dev enp10s0f0 proto static
10.0.0.0/8 dev eno1 proto kernel scope link src 10.0.0.1
5*.2*.204.212/30 dev enp10s0f0 proto kernel scope link src 5*.2*.204.214
5*.2*.205.0/24 dev enp10s0f1 proto kernel scope link src 5*.2*.205.1
And the following saved in my /etc/rc.local file:
#!/bin/sh -e
iptables --flush
iptables --table nat --flush
iptables --delete-chain
iptables --table nat --delete-chain
iptables -F
iptables -X
###################### Enable Nat ############################
sudo echo "1" > /proc/sys/net/ipv4/ip_forward
#################### Enable Nat for internal ###########################
iptables -t nat -A POSTROUTING -o enp10s0f0 -j MASQUERADE
#iptables -t nat -A POSTROUTING -o enp12s0f1 -j MASQUERADE
################### Enable Log ########################
#iptables -A OUTPUT -j LOG
#iptables -A INPUT -j LOG
#iptables -A FORWARD -j LOG
############# Allow by default #####################
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
############################ Allow Incoming connection ############################
iptables -A INPUT -m conntrack --ctstate "ESTABLISHED,RELATED" -j ACCEPT
################################## Allow outgoing connection ######################
iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED -j ACCEPT
######################## allow internal to external
iptables -A FORWARD -i eno1 -m state "ESTABLISHED,RELATED" -j ACCEPT
#iptables -A FORWARD -i eno1 -o enp12s0f1 -m state "ESTABLISHED,RELATED" -j ACCEPT
###iptables -A FORWARD -i eno1 -o enp10s0f1 -j ACCEPT
iptables -A FORWARD -i eno1 -o enp10s0f1 -j ACCEPT
#iptables -A FORWARD -i eno1 -o enp12s0f0 -j ACCEPT
#iptables -A FORWARD -i enp10s0f1 -o enp10s0f0 -j ACCEPT
#iptables -A FORWARD -i enp10s0f0 -o enp12s0f1 -j ACCEPT
exit 0
A network diagram:
As you will probably notice, I've spent a lot of time reading online what the best way to approach this is, and much of this is commented out. The way I figure, I only need NAT on the eno1 interface. But, since it's linux, do I need iptables to do non-NAT routing? I tried disabling it, and the public network wouldn't work at all.
Even when I get one thing to work, it ends up breaking something else. It's been years since I took a Cisco class, and I'm not used to feeling so ignorant. I'm really hoping someone can help me figure out the best way to implement this, or possibly spot any screw-ups I've made that's causing the error.
Solution 1:
I presume your ISP set up routes to the network 5*.2*.205.0/24
towards you via 5*.2*.204.214
.
Let's assume the following state: the Netfilter is in the default state (iptables-save
shows no rules and all policies are ACCEPT
). Your public network 5*.2*.205.0/24
works, hosts have the default gateway 5*.2*.205.1
. The private network 10.0.0.0/8
(with gateway 10.0.0.1
) does not work because NAT is not set up. Also I'd expect hosts in the 10.0.0.0/8
and 5*.2*.205.0/24
to be able to see and communicate with each other.
You have to do almost nothing to achieve this. Just set up all IPs with netmasks and enable IP forwarding in the kernel (e.g. net.ipv4.ip_forward=1
). Your routing table should be like the one you already have.
For 10.0.0.0/8
to work towards Internet you only have to add the following rule:
iptables -t nat -A POSTROUTING -o enp10s0f0 -s 10.0.0.0/8 -j MASQUERADE
It will do the NAT for the "grey" addresses going out into the wild. You may replace -j MASQUERADE
with any of -j SNAT --to-source 5*.2*.205.1
(the address which is assigned to enp10s0f1
) or 5*.2*.204.214
.
If you want to consider the network 5*.2*.205.0/24
as being like the Internet you may add another NAT rule and translate connections going into it from 10.0.0.0/8
too. This another rule will be the same as the first one, except the outgoing interface filter -o enp10s0f1
. But it may be useful to leave it without NAT, especially if you control than network and want hosts in it to see direct 10.0.0.0/8
addresses rather than cloak them under the gateway's address.