This article explains how to share the internet connection from one machine to other(s).
Requirements
The machine acting as server should have an additional network device. That network device requires a functional data link layer to the machine(s) that are going to receive internet access:
- To be able to share internet to several machines a switch can provide the data link.
- A wireless device can share access to several machines as well, see Software access point first for this case.
- If you are sharing to only one machine, a crossover cable is sufficient. In case one of the two computers’ ethernet cards has MDI-X capability, a crossover cable is not necessary and a regular ethernet cable can be used. Executing
ethtool interface | grep MDI
as root helps to figure it.
Configuration
This section assumes that the network device connected to the client computer(s) is named net0
and the network device connected to the internet as internet0
.
All configuration is done on the server computer, except for the final step of #Assigning IP addresses to the client PC(s).
Static IP address
On the server computer, assign a static IPv4 address to the interface connected to the other machines. The first 3 bytes of this address cannot be exactly the same as those of another interface, unless both interfaces have netmasks strictly greater than /24.
# ip link set up dev net0 # ip addr add 192.168.123.100/24 dev net0 # arbitrary address
To have your static IP assigned at boot, you can use a network manager.
Enable packet forwarding
Check the current packet forwarding settings:
# sysctl -a | grep forward
You will note that options exist for controlling forwarding per default, per interface, as well as separate options for IPv4/IPv6 per interface.
Enter this command to temporarily enable packet forwarding at runtime:
# sysctl net.ipv4.ip_forward=1
Tip: To enable packet forwarding selectively for a specific interface, use sysctl net.ipv4.conf.interface_name.forwarding=1
instead.
IPForward=kernel
semantics introduced in a previous systemd release 220/221 to honor kernel settings does not apply anymore.[1] [2]Edit /etc/sysctl.d/30-ipforward.conf
to make the previous change persistent after a reboot for all interfaces:
/etc/sysctl.d/30-ipforward.conf
net.ipv4.ip_forward=1 net.ipv6.conf.default.forwarding=1 net.ipv6.conf.all.forwarding=1
Afterwards it is advisable to double-check forwarding is enabled as required after a reboot.
Enable NAT
With iptables
Install the iptables package. Use iptables to enable NAT:
# iptables -t nat -A POSTROUTING -o internet0 -j MASQUERADE # iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT # iptables -A FORWARD -i net0 -o internet0 -j ACCEPT
Note: Of course, this also works with a mobile broadband connection (usually called ppp0 on routing PC).
Read the iptables article for more information (especially saving the rule and applying it automatically on boot). There is also an excellent guide on iptables Simple stateful firewall.
With nftables
Install the nftables package. To enable NAT with nftables, you will have to create the prerouting
and postrouting
chains in a new/existing table (you need both chains even if they’re empty):
# nft add table ip nat # nft add chain ip nat prerouting { type nat hook prerouting priority 0 ; } # nft add chain ip nat postrouting { type nat hook postrouting priority 100 ; }
Note: If you want to use IPv6, you have to replace all occurrences of ip
with ip6
.
After that, you have to masquerade the net0
addresses for internet0
:
# nft add rule nat postrouting oifname internet0 masquerade
You may want to add some more firewall restrictions on the forwarding (assuming the filter table already exists, like configured in nftables#Server:
# nft add chain inet filter forward { type filter hook forward priority 0; policy drop; } # nft add rule filter forward ct state related,established accept # nft add rule filter forward iifname net0 oifname internet0 accept
You can find more information on NAT in nftables in the nftables Wiki. If you want to make these changes permanent, follow the instructions on nftables
Assigning IP addresses to the client PC(s)
If you are planning to regularly have several machines using the internet shared by this machine, then is a good idea to install a DHCP server, such as dhcpd or dnsmasq. Then configure a DHCP client (e.g. dhcpcd) on every client PC.
Incoming connections to UDP port 67 has to be allowed for DHCP server. It also necessary to allow incoming connections to UDP/TCP port 53 for DNS requests.
# iptables -I INPUT -p udp --dport 67 -i net0 -j ACCEPT # iptables -I INPUT -p udp --dport 53 -s 192.168.123.0/24 -j ACCEPT # iptables -I INPUT -p tcp --dport 53 -s 192.168.123.0/24 -j ACCEPT
If you are not planing to use this setup regularly, you can manually add an IP to each client instead.
Manually adding an IP
Instead of using DHCP, on each client PC, add an IP address and the default route:
# ip addr add 192.168.123.201/24 dev eth0 # arbitrary address, first three blocks must match the address from above # ip link set up dev eth0 # ip route add default via 192.168.123.100 dev eth0 # same address as in the beginning
Configure a DNS server for each client, see resolv.conf for details.
That is it. The client PC should now have Internet.
Troubleshooting
If you are able to connect the two PCs but cannot send data (for example, if the client PC makes a DHCP request to the server PC, the server PC receives the request and offers an IP to the client, but the client does not accept it, timing out instead), check that you do not have other iptables rules interfering.