Caius Theory

Now with even more cowbell…

Raspberry Pi 3 as an emergency router

Given a dead router, how do you get back online whilst you wait for the replacement part to arrive? Grab a Raspberry Pi 3 off the shelf, along with a USB to Ethernet adapter and hey presto the internet works again.

This is with a fibre modem (FTTC), using PPPoE to connect out. Plug the modem (WAN) into the RPi's ethernet port, and plug the LAN switch into the USB adapter.

First thing is to get the WAN link working, get it talking PPPoE to the ISP. Usually this will be configured in /etc/ppp/pppoe.conf (depends on your linux distro). (That'll require your username/password for your ISP usually too.)

Get it up & connected, and make sure you can ping the internet from the RPi. Then it's time to get the LAN working. Give it a static IP in the range you want shared out.

# /etc/network/interfaces
iface eth0 inet static
  address 192.168.1.1
  netmask 255.255.255.0
  gateway 192.168.1.1

auto eth1
iface eth1 inet dhcp

Get a dhcp server running on the LAN connection,

# /etc/dhcpcd.conf
interface eth0
static ip_address=192.168.1.1
static routers=192.168.1.1
static domain_name_servers=8.8.8.8,8.8.4.4

And then it's time to handle WAN -> LAN traffic and the reverse. Make sure you have packet forwarding enabled, and then setup the firewall to handle NAT and also keep out undesirable traffic.

sysctl net.ipv4.ip_forward=1

iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -i eth0 -j ACCEPT
iptables -A INPUT -p icmp --icmp-type any -j ACCEPT
iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
iptables -A INPUT -f -j DROP
iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
iptables -A INPUT -j DROP

Hey presto, you have a working emergency router. In testing I found my fibre connection (80/20Mb) was slower than the traffic the RPi could push, so didn't notice any difference vs my normal router. (Although I did disable a bunch of automated stuff, so there was less contention on the WAN link.)

Compile & run swift files directly

Turns out you can run a swift file without having to compile it into a binary somewhere and then run that binary. Makes swift behave a bit more like a scripting language like ruby or python when you need it to.

Using the xcrun binary, we can reach into the current Xcode /bin folder and run binaries within there. So xcrun swift lets you run the swift binary to compile files for instance. If you view the help with -h, there's a useful flag -i listed there:

-i    Immediate mode

Turns out immediate mode means "compile & run" in the same command, which is what we're after.

$ cat hello.swift
println("Hello World")

$ xcrun swift -i hello.swift
Hello World

Bingo. But what if we want to make hello.swift executable and call it directly without having to know it needs the swift binary to call it. Unix lets files define their shebang to say how the file needs to be executed, so lets go for that here too!

$ cat hello2.swift
#!/usr/bin/env xcrun swift -i
println("Hello World 2")

$ chmod +x hello2.swift
$ ./hello2.swift
Hello World 2

No more having to fire up Xcode for quick CLI tools, especially ones using the system frameworks!