NetworkEnjin – Part 0: PPPoE

This part is skippable for those of you who don’t have to interface with a PPPoE modem for their internet, but essential those who do. All the information I found on this topic was quite old, but with a small amount of trial and error I got it working in my own home.

Please note:

  1. This part isn’t tested as well as the others. There is a lot below that depends on how your upstream provider wants you to connect to their network.
  2. If you have to do PPPoE with a VLAN then that will need to be setup first. The PPP daemon doesn’t handle VLANs so you’ll need to create a VLAN sub-interface to use as your ethernet interface below (e.g. eth0.2 for VLAN 2 via eth0).
  3. The version of Ubuntu you are running might not include the PPPoE kernel modules anymore. Here is me finding out the hard way that this happened with the Raspberry Pi build in 22.04 so you now need to install the linux-modules-extra-raspi too (backup web archive link).

While the device still has access to the internet install PPPoE support

apt install pppoe

As per my note 3 above, if you are doing this on a Raspberry Pi you’ll also need to run

apt install linux-modules-extra-raspi

Save your credentials into /etc/ppp/chap-secrets as required

"{:Username:}" * "{:Password:}"

Create your provider /etc/ppp/peers/{:ConnectionID:}

linkname {:ConnectionID:}
user {:Username:}
plugin rp-pppoe.so
noipdefault
defaultroute
hide-password
usepeerdns 
lcp-echo-interval 20
lcp-echo-failure 3
noauth
persist
maxfail 0
mtu 1492
mru 1492
noaccomp
default-asyncmap
+ipv6

Please note:

  1. This is just my template I have used, you may need/want to adjust some values. For a complete list of options I found this to be a useful reference https://ppp.samba.org/pppd.html
  2. The plugin name may change. I’m actually running Alpine Linux for my home router now and my line in that config is: plugin pppoe.so eth1.2
  3. If later you get an error like “Failed to create PPPoE socket: Address family not supported by protocol” or “Couldn’t set tty to PPP discipline: Invalid argument” please see note 3 in my first lot of notes.

Next create a new service by running:

systemctl edit --force --full [email protected]

And fill it with the following details

[Unit]
Description=pppd for %I
After=network.target
StartLimitIntervalSec=0

[Service]
Type=forking
Restart=always
RestartSec=5
ExecStart=/usr/sbin/pppd call %i {:EthernetDevice:}
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true

[Install]
WantedBy=multi-user.target

If you need to run a script to prepare your ethernet device before calling pppd add something like the following under the [service] section

ExecStartPre=/etc/ppp/preparedevice.sh {:EthernetDevice:}

As I was using a USB to Ethernet device as my second NIC so I required the following script to help in specific scenarios

#!/bin/bash
echo "Preparing $1"

/sbin/ip link set mtu 1500 dev $1
/sbin/ip link set up dev $1

Once you’re all good to go enable and start the service

systemctl enable pppd@{:ConnectionID:}
systemctl start pppd@{:ConnectionID:}

To use the connection as your default gateway add this route:

ip route add 0.0.0.0/0 dev {:PPPDevice:}