This post will show how to share the Internet between two network adapters on Ubuntu Desktop 18.04 (any architecture) and Raspbian Buster 10 (for Raspberry Pi).
The most common situation is when your device (a laptop or Raspberry Pi) is connected to the Internet via Wifi and you want to share this connection with another device via Ethernet (port RJ45), such as a SmartTV or a Desktop that has no Integrated Wifi.
What is necessary:
- Wifi already set up with the Internet.
- Laptop or Raspberry Pi with Wireless Card
- Linux Operating System (Ubuntu or Raspbian)
- Ethernet Cable
- The device you want to connect (TV, Computer, Printer, etc.)
What will be configured:
- Configure the NIC (network adapter)
- Install DHCP Server (auto-assign IPs) [learn more – CertBros]
- Configure NAT (routing) [learn more – CertBros]
- Install DNS Server (optional) [learn more – Techquickie]
Configuring the NIC
ip a
1: lo: <omitted unnecessary text>
inet 127.0.0.1/8 scope host lo
<omitted unnecessary text>
2: eth0: <omitted unnecessary text>
inet 172.16.1.1/24 brd 172.16.1.255 scope global noprefixroute eth0
<omitted unnecessary text>
3: wlan0: <omitted unnecessary text>
inet 192.168.2.40/24 brd 192.168.2.255 scope global dynamic noprefixroute wlan0
<omitted unnecessary text>
1: lo: It is the loopback interface. Just ignore this virtual interface.
2: eth0: This is the Ethernet adapter that will be connected to the TV, Computer, Printer…
3: wlan0: This is the Wireless adapter that has to be connected to your Wifi and have Internet connection working.
Note: The names of the interfaces may vary, in my case eth0 (LAN) and wlan0 (WAN).
In my example, my eth0 is already manually configured.
On Ubuntu, configure the eth0 using the graphical interface according to the configuration below:
On Raspbian, configure the eth0 using the terminal to edit the file /etc/dhcpcd.conf, and paste the following code inside. Go to Terminal and issue:
sudo nano /etc/dhcpcd.conf
Add this code at the end of the file.
interface eth0 static ip_address=172.16.1.1/24 nogateway
Restart the computer after changing the configuration.
Pay attention to the IPs in the new scenario:
No matter if you are doing the Laptop + TV situation or Raspberry Pi + PC or both, what you have to pay attention to is the color of the IPs. All the Orange IPs are in the same subnet and the Blue and the Green are other subnets.
The TV and the PC have to have an IP to communicate in the subnet, so or you manually configure each of them, or you dynamically configure any device that connectors the new networks.
Installing DHCP Server
sudo apt-get update sudo apt-get install isc-dhcp-server -y sudo nano /etc/default/isc-dhcp-server
Inform the network adapter that the DHCP will work (LAN):
INTERFACESv4="eth0"
Edit the configuration file:
sudo nano /etc/dhcp/dhcpd.conf
Clean the file content and add this code:
default-lease-time 600; max-lease-time 7200; option subnet-mask 255.255.255.0; option broadcast-address 172.16.1.255; option routers 172.16.1.1; option domain-name-servers 8.8.8.8, 8.8.4.4; option domain-name "host.local"; subnet 172.16.1.0 netmask 255.255.255.0 { range 172.16.1.10 172.16.1.100; }
Issue the commands:
sudo systemctl restart isc-dhcp-server sudo systemctl enable isc-dhcp-server sudo systemctl status isc-dhcp-server
The second command may fail in Raspbian, but don’t worry! Keep moving…
Check if the service is ACTIVE in green:
This is the new scenario, the devices can get IP configuration automatically:
All this configuration is customizable, take the change and make modifications and make how it works. In the example above intentionally the IPs of the Laptop and the Raspberry Pi are the same, but they are in physically different networks. Same for the TV and PC, they may get the first available IP from the DHCP Server, which is the same in both. Check if the devices got the IP correctly.
Configuring NAT (for Ubuntu):
sudo ufw enable sudo nano /etc/ufw/sysctl.conf
Uncomment this configuration or add if you do not find it:
net/ipv4/ip_forward=1
Do the same for /etc/sysctl.conf.
Edit the startup script:
sudo nano /etc/rc.local
Copy and paste this content to the file:
#!/bin/bash iptables -P INPUT DROP iptables -P FORWARD DROP iptables -A INPUT -i lo -j ACCEPT iptables -A INPUT -i eth0 -j ACCEPT iptables -A INPUT -i wlan0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT iptables -t nat -A PREROUTING -p tcp -d 192.168.2.40 --dport 80 -j DNAT --to-destination 172.16.1.10:80 iptables -A FORWARD -i eth0 -o wlan0 -j ACCEPT iptables -A FORWARD -i wlan0 -o eth0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT iptables -t nat -A POSTROUTING -j MASQUERADE exit 0
Note: there is one line in the middle of this code that is the template in case you want to do a Static NAT, known as Port Forwarding. The IP 192.168.2.40 shall be replaced by the public IP, and the IP 172.16.1.10 shall be replaced by the private IP, a Webserver in this case (port 80). If you are not using Port Forwarding simply delete this line, or not! See the illustration below:
Change the permission of the file to make it executable:
sudo chmod 755 /etc/rc.local
Configuring NAT (for Raspbian):
sudo nano /etc/rc.local
Add this code at the end of the file, right before the last line: exit 0
iptables -A INPUT -i lo -j ACCEPT iptables -A INPUT -i eth0 -j ACCEPT iptables -A INPUT -i wlan0 -m conntrack \ --ctstate ESTABLISHED,RELATED -j ACCEPT iptables -A FORWARD -i eth0 -o wlan0 -j ACCEPT iptables -A FORWARD -i wlan0 -o eth0 -m conntrack \ --ctstate ESTABLISHED,RELATED -j ACCEPT iptables -t nat -A POSTROUTING -j MASQUERADE systemctl start isc-dhcp-server
Restart Ubuntu/Raspbian to take effect and test if the TV and/or PC have internet!
Installing DNS Server (optional)
Taking a look at the preview configuration, the DHCP Server auto-configure the devices (TV, PC, Printer…) to the Google Public DNS Server (no contraindication). Another alternative would be using the Wireless router DNS Server, in my case 192.168.2.1.
Here is how to create your own Private DNS Server and have full control of it. Black-list or white-list can be applied as Parental Control or Business Policy or any other application you want to perform to your network.
sudo apt install bind9 -y sudo nano /etc/bind/named.conf.options
Replace the whole content of the file with the code below:
options{ directory "/var/cache/bind"; recursion yes; forwarders { 8.8.8.8; 8.8.4.4; }; forward only; };
Note: the DNS Server works forwarding the requests that it does not know, after the first time it keeps the information in ‘cache’ for the next time, increasing the performance of the internet
Remember to restart DNS and DHCP Servers:
sudo systemctl restart bind9 sudo systemctl restart isc-dhcp-server.service
Now, restart all the devices, so they will request a new configuration from the DHCP Server and start using the local DNS Server in your gateway.
It is all set up and running!
To reserve an IP for a specific device append the following lines to the file /etc/dhcp/dhcpd.conf:
host mytv { hardware ethernet A4:BA:DB:14:BD:4F; fixed-address 192.168.110.10; }
BONUS
For port forwarding in the same network or single network interface:
#!/bin/bash iptables -P INPUT DROP iptables -P FORWARD DROP iptables -A INPUT -i lo -j ACCEPT iptables -A INPUT -i eth0 -j ACCEPT iptables -t nat -A PREROUTING -p tcp -d 192.168.1.5 --dport 443 -j DNAT --to-destination 192.168.1.50:443 iptables -A FORWARD -s 192.168.1.0/24 -j ACCEPT iptables -t nat -A POSTROUTING -j MASQUERADE exit 0
Or use nftables to manage the iptable rules:
sudo ufw disable sudo systemctl disable ufw sudo apt install nftables -y sudo systemctl enable nftables sudo sed -i 's/#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/g' /etc/sysctl.conf sudo sysctl -p sudo nft list ruleset sudo nft flush ruleset sudo nft list ruleset sudo nft flush ruleset sudo nft add table nat sudo nft 'add chain nat postrouting { type nat hook postrouting priority 100 ; }' sudo nft 'add chain nat prerouting { type nat hook prerouting priority -100; }' sudo nft 'add rule nat prerouting ip daddr 192.168.1.5 tcp dport { 21 } dnat 192.168.1.50:21' sudo nft 'add rule nat prerouting ip daddr 192.168.1.5 tcp dport { 60000-65000 } dnat 192.168.1.50:60000-65000' sudo nft add rule nat postrouting masquerade sudo nft list ruleset | sudo tee /etc/nftables.conf
To manage the rules use the following commands:
sudo nft -a list table nat sudo nft delete rule nat prerouting handle 7
How to do NAT with nftables:
sudo nano /etc/sysctl.conf
net.ipv4.ip_forward = 1
sudo nano /etc/nftables.conf
table inet nat { chain prerouting { type nat hook prerouting priority -100; policy accept; } chain postrouting { type nat hook postrouting priority 100; policy accept; oifname "eth0" masquerade } } table inet filter { chain forward { type filter hook forward priority 0; policy drop; iifname "eth1" oifname "eth0" accept ct state established,related accept } }
sudo sysctl -p sudo nft -f /etc/nftables.conf