2016년 2월 27일 토요일

Internet connection sharing through a computer with two NIC's

Recently a new server room was built at the office and now all the network and server gear has been moved there. I used to use wireless connections on my notebooks out of convenience, but now that the wireless router is inside the server room instead of in the middle of an open floor plan office, the wireless signal is too weak.
My notebooks are connected to the internal network, however. Most of the test servers have dual NIC's so on a server with Fedora 23 installed, I first enabled port forwarding manually:
# check if port forwarding is enabled (it isn't)
[fedgro@fx8350no2 sysctl.d]$ sudo sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 0
# enable it
[fedgro@fx8350no2 sysctl.d]$ sudo sysctl net.ipv4.ip_forward=1
net.ipv4.ip_forward = 1
# verify that port forwarding has been enabled:
[fedgro@fx8350no2 sysctl.d]$ sudo sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1

The change above will only apply until the next reboot, so to make the changes permanent, I want to edit sysctl.conf

In recent versions of Fedora using systemd, this conf file is no longer monolithic and is generated at boot by systemd from files in /usr/lib/sysctl.d/ (distribution default kernel settings) and in /etc/sysctl.d/ (custom kernel settings)
Here is the content of each directory:

[fedgro@fx8350no2 sysctl.d]$ cd /usr/lib/sysctl.d/
[fedgro@fx8350no2 sysctl.d]$ ls
00-system.conf              50-coredump.conf  60-libvirtd.conf
10-default-yama-scope.conf  50-default.conf
[fedgro@fx8350no2 sysctl.d]$ cd /etc/sysctl.d/
[fedgro@fx8350no2 sysctl.d]$ ls
50-libreswan.conf  99-sysctl.conf
Under /etc/sysctl.d I created a custom file 98-ipv4-forward.conf containing the single line

net.ipv4.ip_forward=1
Now that ipv4 port forwarding has been enabled, it is time to set up IP masquerading in the firewall. Fedora 23 uses firewalld instead of iptables, so to make the appropriate settings you can use the GUI firewall-config or the cli tool firewall-cmd.

You can see that firewalld is running:

[fedgro@fx8350no2 sysctl.d]$ systemctl status firewalld
firewalld.service - firewalld - dynamic firewall daemon
   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled)
   Active: active (running) since Mon 2016-02-22 10:13:28 KST; 23h ago
 Main PID: 2132 (firewalld)
   CGroup: /system.slice/firewalld.service
           └─2132 /usr/bin/python3 -Es /usr/sbin/firewalld --nofork --nopid

Feb 22 10:13:28 fx8350no2 systemd[1]: Starting firewalld - dynamic firewal.....
Feb 22 10:13:28 fx8350no2 systemd[1]: Started firewalld - dynamic firewall...n.
Hint: Some lines were ellipsized, use -l to show in full.

Now I use firewall-cmd below to set up masquerading:
# Check the default firewall zone
# (FedoraServer is the default for F23)
[fedgro@fx8350no2 sysctl.d]$ sudo firewall-cmd --get-default

FedoraServer

Check the firewall zone for the NIC connected to a router providing access to the Internet:

[fedgro@fx8350no2 sysctl.d]$ sudo firewall-cmd --get-zone-of-interface=enp5s0
FedoraServer
 

Add IP masquerading to the default zone:

[fedgro@fx8350no2 sysctl.d]$ sudo firewall-cmd --zone=FedoraServer --add-masquerade
success

[fedgro@fx8350no2 sysctl.d]$ sudo firewall-cmd --permanent --zone=FedoraServer --add-masquerade
success

Verify changes have been made to FedoraServer zone:
[fedgro@fx8350no2 sysctl.d]$ firewall-cmd --zone=FedoraServer --list-all
FedoraServer (default, active)
  interfaces: enp5s0
  sources:
  services: cockpit dhcpv6-client http https ipp ipp-client samba-client sane ssh
  ports: 80/tcp 631/tcp
  protocols:
  masquerade: yes
  forward-ports:
  icmp-blocks:
  rich rules:

Now from my notebook connected to the internal network, I simply add the following route (to the server with dual NIC's):

sudo ip r add default via 192.168.95.145 dev enp1s0

where 192.168.95.145 is the IP of the NIC connected to the internal network on the dual-NIC server, and where enp1s0 is the ethernet port on my notebook.

And now the notebook connected to the internal network can talk to the outside world. Let's test on Google's DNS server 8.8.8.8:

[archjun@pinkS310 ~]$ ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=51 time=36.7 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=51 time=35.3 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=51 time=36.1 ms
64 bytes from 8.8.8.8: icmp_seq=4 ttl=51 time=36.6 ms
64 bytes from 8.8.8.8: icmp_seq=5 ttl=51 time=35.9 ms
^C
--- 8.8.8.8 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4006ms
rtt min/avg/max/mdev = 35.342/36.157/36.718/0.496 ms
[archjun@pinkS310 ~]$ traceroute 8.8.8.8
traceroute to 8.8.8.8 (8.8.8.8), 30 hops max, 60 byte packets
 1  gateway (192.168.95.145)  0.299 ms  0.278 ms  0.279 ms
 2  192.168.30.1 (192.168.30.1)  0.657 ms  0.695 ms  0.743 ms
 3  REDACTED (REDACTED)  11.346 ms  11.357 ms  11.349 ms
 4  REDACTED (REDACTED)  9.661 ms  13.730 ms  13.750 ms
 5  REDACTED (REDACTED)  9.541 ms  9.571 ms  9.566 ms
 6  112.189.28.97 (112.189.28.97)  8.167 ms  6.349 ms 112.189.29.97 (112.189.29.97)  15.201 ms
 7  112.174.103.225 (112.174.103.225)  10.270 ms 112.174.103.213 (112.174.103.213)  8.211 ms 112.174.119.205 (112.174.119.205)  6.721 ms
 8  112.174.48.162 (112.174.48.162)  6.676 ms  6.688 ms 112.174.8.42 (112.174.8.42)  6.898 ms
 9  112.174.83.218 (112.174.83.218)  6.854 ms 112.174.83.34 (112.174.83.34)  6.857 ms 112.174.84.122 (112.174.84.122)  6.957 ms
10  72.14.194.106 (72.14.194.106)  36.267 ms  36.246 ms  36.211 ms
11  216.239.54.13 (216.239.54.13)  36.528 ms 216.239.50.241 (216.239.50.241)  36.149 ms 216.239.54.13 (216.239.54.13)  41.606 ms
12  209.85.254.17 (209.85.254.17)  34.989 ms 209.85.246.89 (209.85.246.89)  37.053 ms 209.85.255.241 (209.85.255.241)  36.305 ms
13  google-public-dns-a.google.com (8.8.8.8)  36.593 ms  36.592 ms  42.129 ms

You can see that the first hop in the traceroute is to 192.168.95.145, the server on the internal network which has 2 NIC's. 1 NIC is connected to the internal network while one NIC is connected to the external network. It forwards the packets from the internal 192.168.95.0/24 network to the external network on subnet 192.168.30.0/24 which has access to the Internet through a router.

(the second link provides some useful commands for firewall-cmd)