2015-06-10

How to share WiFi over LAN on Linux

Sometimes we need to share our wireless connection to LAN or vice-versa, the simplest way to do that is using NAT (and dnsmasq - a DHCP server and DNS proxy). First thing you need to do is check your server/sharer's network interfaces, for example:

$ ifconfig -a
enp1s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.0.0.1  netmask 255.0.0.0  broadcast 10.255.255.255
        inet6 fe80::d63d:7e3f:fe3f:497a  prefixlen 64  scopeid 0x20<link>
        ether d4:3d:7e:9f:49:7a  txqueuelen 1000  (Ethernet)
        RX packets 2149  bytes 214913 (209.8 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 256  bytes 20714 (20.2 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 0  (Local Loopback)
        RX packets 9344  bytes 840957 (821.2 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 9344  bytes 840957 (821.2 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

wlp2s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.100  netmask 255.255.255.0  broadcast 192.168.1.255
        inet6 fe30::e33e:27ff:fe3d:9533  prefixlen 64  scopeid 0x20<link>
        ether e8:de:27:7d:95:3f  txqueuelen 1000  (Ethernet)
        RX packets 877461  bytes 1171868706 (1.0 GiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 790957  bytes 82979794 (79.1 MiB)

        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

That command will show you all network interface that available on your PC. The most important thing is to understand which interface that used to connect to the internet, and which one that connect locally. In this example, the wlp2s0 is the one that used to connect to the internet, and enp1s0 is the one that used to connect locally (10.0.0.1). The next part is enable your NAT using these commands:

sudo iptables -t nat -A POSTROUTING -o wlp2s0 -j MASQUERADE
sudo iptables -A FORWARD -i enp1s0 -j ACCEPT
sudo iptables -n -L
sudo su - -c 'echo 1 > /proc/sys/net/ipv4/ip_forward'

The last part is configure your dnsmasq, just give some address on your /etc/dnsmasq.conf, for example:

port=53
dhcp-range=10.0.0.2,10.0.0.10,24h

And then restart your dnsmasq using this command:

sudo systemctl enable dnsmasq
sudo systemctl restart dnsmasq

On the client (the other computer that need to connect to the internet through previous computer), just enable the DHCP client, for example, on archlinux, use this command:

sudo systemctl enable dhcpcd@enp2s0
sudo systemctl start dhcpcd@enp2s0

where the enp2s0 is your network interface that will be used. If it's not already set, configure your DNS and default gateway using this command:

sudo route add default gw 10.0.0.1 dev enp2s0
echo nameserver 10.0.0.1 > /etc/resolv.conf

where the 10.0.0.1 is the gateway server's IP. That's all you'll need to share your wifi connection on Linux.

When there are trouble, please make sure:
  1. is the server connected to the internet? (traceroute or ping 8.8.8.8 or internet gateway), check the cable, access point or your router
  2. is the server could resolve correctly? (dig google.com), check /etc/resolv.conf if it's configured correctly
  3. is the client get correct IP? (ifconfig), check the dhcpcd and dnsmasq's DHCP configuration
  4. is the client could connect to the server? (ping 10.0.0.1), check your cable. is the interface enabled
  5. is the client could connect to the internet? (traceroute or ping 8.8.8.8), check the iptables (NAT command)
  6. is the client could resolve correctly? (dig google.com), check the dnsmasq configuration
That's all for now.