Internet Sharing Over Linux/Raspberry Pi My friend got a desktop. However, she didn't have a wireless adapter for her pi; and the computer was to be situated too far from the router to make ethernet a viable option in the interrim. I'd previously convinced her to buy a Raspberry Pi 3, which conveniently has a WiFi chip and an Ethernet port. I set out to bridge the adapters, and provide internet access to that poor, malnourished desktop. Here's how I made it work. Being the lazy programmer that I am (I think we're all pretty lazy when it comes to programming; we're making the computer do work for us already...), I initially Googled how to bridge the two adapters. My Google-Fu led me to the following link: https://wiki.debian.org/BridgeNetworkConnections Most notably, the procedure for bridging two ethernet devices is significantly different to bridging a WiFi device and an ethernet adapter. She too, being a programmer, said "that's too many instructions", and countered with this link: http://www.glennklockwood.com/sysadmin-howtos/rpi-wifi-island.html I immediately saw static IPs and suggested that this was *not* a good way to do things; you never know when you might need to change IP addresses (new router, LAN Party, etc.). So she attempted my link, swapping out aptitude for apt-get, because I know how to use apt-get and could instruct her; nonetheless, the labour bore no fruits of success. By this time I was sufficiently intrigued (actually I was pretty intrigued from the get-go; I had no landline access several years ago, and if only I could have bridged a 3G/4G USB dongle through a Pi, I could have kept using my already-configured router). First up, I decided reverse everything we'd tried previously - a clean slate is always good. Secondly - I figured the Pi needed to act as a DHCP server, due to this comment from my original link: > Just like you can bridge two wired ethernet interfaces, you can bridge between an ethernet interface and a wireless interface. However, most Access Points (APs) will reject frames that have a source address that didn't authenticate with the AP. If it doesn't translate the requests, but transparently forwards them through, then the router will most likely reject it. Using a DHCP server on the Pi would give the desktop an IP address - using Network Address Translation (NAT), I could share the internet connection. More Googling led to some official Raspberry Pi teaching material: https://www.raspberrypi.org/learning/networking-lessons/lesson-3/plan/ Using this, I installed `dnsmasq`, the DHCP server software: ``` sudo apt-get install dnsmasq ``` And put the following content in `/etc/dnsmasq.conf` (using `sudo nano /etc/dnsmasq.conf` to edit): ``` interface=eth0 dhcp-range=10.0.1.2,10.0.1.254,255.255.255.0,12h ``` This tells `dnsmasq` to allocate IP addresses between `10.0.1.2` and `10.0.1.254` inclusive; a total of 253 possible addresses, and devices on the network. I could have used `192.168.x.x`, but the WiFi network was using that already, and the `10.x.x.x` range can be used for the same purpose. This doesn't include the Pi itself; that comes next. The `255.255.255.0` is the subnet mask, which you can read up about; the `12h` means that once a device is given an IP address, that IP is "leased" for 12 hours - no other device can have that IP until the lease expires, it's reserved until then. You'll notice that `10.0.1.1` was left out, as was `10.0.1.255`. The IP `10.0.1.1` is for the Pi - it's the router. `10.0.1.255` is a broadcast address, which means ordinary devices aren't to be used with it. To set the Pi ethernet adapter to `10.0.1.1`, we needed to setup a static IP. On Debian (Raspbian is a fork of Debian), you simply edit the `/etc/network/interfaces` file as follows: ``` # iface eth0 inet manual iface eth0 inet dhcp auto eth0 iface eth0 inet static address 10.0.1.1 netmask 255.255.255.0 ``` The top line was already present; you comment it out by adding the `#` character (a hash) in front of it. You'll notice the subnet mask (`netmask`) matches the previous step. However, I remembered reading that static IPs were changed on Raspbian (or possibly Debian), so I went looking and found the blog post that I'd stumbled upon several months prior: https://nebulousthinking.wordpress.com/2016/02/25/setting-a-static-ip-for-raspbian-jessie-in-2016/ As such, it's necessary to edit `/etc/dhcpcd.conf` and put this at the bottom: ``` interface eth0 static ip_address=10.0.1.1/24 ``` Do note that this must go at the bottom, and the line `nohook lookup-hostname` must be uncommented - if the above lines go at the top, all other lines will only apply to `eth0`, meaning that defaults will be applied to the other adapters (e.g. `wlan0`). On my Pi 2B, I noticed the defaults would break DNS (i.e. I could `ping 8.8.8.8` but not `ping google.com`). The `10.0.1.1` is again the IP address of the Pi; the `/24` at the end is another way of writing the subnet mask. See my other post for details. At this point, I restarted both the networking and dnsmasq services on the Pi, in order to read the new configurations. ``` sudo service networking restart sudo service dnsmasq restart ``` After being disconnected from the Pi (I was working over ssh), the network reconnected and I confirmed that my friend had an IP on her desktop. However, still no internet access. I found I had another tab open from my previous Googling: https://serverfault.com/questions/152363/bridging-wlan0-to-eth0 The top answer there instructs you to turn on IP forwarding by writing a "1" to the file listed below (the command will write a "1"): ``` echo 1 > /proc/sys/net/ipv4/ip_forward ``` However, there is another way to turn on IP forwarding, which is explained in the second link in this post. In the file `/etc/sysctl.conf`, the line `#net.ipv4.ip_forward=1` needs to be uncommented (remove the hash). This command will also remove it for you: ``` sudo sed -i 's/#net\.ipv4\.ip_forward=1/net\.ipv4\.ip_forward=1/' /etc/sysctl.conf ``` Then reload your System-Control: ``` sudo sysctl -system ``` Back to the ServerFault question, it lists this IPtables rule for forwarding the network traffic: ``` iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE ``` I looked into this command to see what it was doing. The `-t nat` says to use the "nat" table (remember, Network Address Translation, from before), then `-A POSTROUTING` appends it to the "POSTROUTING" rule-chain. The `-o wlan0` sets it to output over the `wlan0` adapter (the WiFi, which we want to output to), and lastly the `-j MASQUERADE` tells IPtables to jump to the "MASQUERADE" instructions when it matches this rule. Note that IPtables won't store this rule when you reboot. I installed `iptables-persistent` (using `sudo apt-get install iptables-persistent`) and as part of the install process, it asks if you want to save the current rules. Press yes, and the current rules will be loaded upon each restart. More ways to save your IPtables rule(s): https://askubuntu.com/questions/270693/how-can-set-these-iptables-rules-to-run-at-startup You may need to restart `dnsmasq` and `networking` services yet again; or simply reboot the Pi. To test the internet connection on the desktop, I had my friend first use `ipconfig` (in Windows command prompt) to verify the desktop had a valid IP address (10.0.1.146 was the one it acquired). Next, I had her ping `10.0.1.1` (the Pi, for initial connectivity), then `8.8.8.8` (Google, which should always be accessible if the internet is up), and lastly `google.com`, which tests DNS resolution (the process of converting a domain name to an IP address). I did try some other things along the way, but this was the final configuration that worked!