Using Ubuntu Server as a Router (PPPoE Dial-Up)

Author Avatar
Axell Jan 24, 2025
  • Read this article on other devices

Introduction

Typically, routers run specialized operating systems: for hardware routers like those from TP-Link, the firmware is custom-built and closely integrated with the hardware. For software routers, OpenWRT is a popular choice. However, these dedicated router operating systems often have limited functionality and are difficult to extend. The hardware of traditional routers can also impose limitations, making it challenging to meet specific needs. Recently, the performance of small devices like NUCs and Raspberry Pis has improved to the point where they can serve as routers. Combined with mainstream Linux distributions, they allow for more flexibility and elegance in implementing router functionalities, with the added advantage of customizability. This guide demonstrates how to use Ubuntu Server as a router to achieve PPPoE dial-up, DHCP (IPv4/v6), and other functionalities, creating a reliable home router.

Installing Ubuntu Server

First, install Ubuntu Server. Download the latest Ubuntu Server ISO from the official website, create a bootable USB, and install it on your NUC or Raspberry Pi. In this guide, I used the LTS 24.04 version. The installation process is straightforward and will not be covered here.

Preparing the Network Interfaces

Assume the server has two network interfaces: enp1s0 and enp2s0. enp1s0 connects to the ISP’s modem, while enp2s0 connects to the home network.

Configuring the Network Interfaces

Ubuntu Server uses netplan by default to configure the network. Edit (or create) the /etc/netplan/01-netcfg.yaml file to configure the interfaces. Here’s a reference configuration, where the interfaces are matched by their MAC addresses to ensure stable naming:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
network:
version: 2
renderer: NetworkManager
ethernets:
# ISP modem
# This interface handles only PPPoE data transmission and does not require any IP configuration. DHCP is disabled.
enp1s0:
match:
macaddress: "e8:ff:1e:--:--:--"
optional: true
dhcp4: false
dhcp6: false
set-name: "enp1s0"
# Home network
# This interface serves as the main router (gateway) for the home network and needs an IP address. DHCP is disabled.
enp2s0:
match:
macaddress: "e8:ff:1e:--:--:--"
addresses: ["192.168.0.1/24"]
dhcp4-overrides:
use-routes: false
dhcp4: false
dhcp6: false
set-name: "enp2s0"

Configuring PPPoE

To optimize performance, it’s better not to use the ISP modem for PPPoE dialing, as modems typically lack performance and manageability. First, set the modem to bridge mode and delegate PPPoE dialing to the Ubuntu Server. Refer to online resources for instructions on enabling bridge mode. Install pppoeconf, a simple PPPoE configuration tool:

1
sudo apt install pppoeconf

Run the tool to configure PPPoE:

1
sudo pppoeconf

Follow the prompts to enter your ISP username and password.

Enabling IPv6 for PPPoE

By default, pppoeconf configures PPPoE for IPv4 only. To enable IPv6, manually edit the configuration file. Edit /etc/ppp/peers/dsl-provider and add the following:

1
+ipv6

Dialing

Start the PPPoE connection:

1
sudo pon dsl-provider

Stop all PPPoE connections:

1
sudo poff -a

Configuring DHCP

The PPPoE connection will acquire an IPv4 address. For IPv6 support, configure DHCP. Install dhcpcd:

1
sudo apt install dhcpcd5

Edit /etc/dhcpcd.conf to include the following:

1
2
3
4
5
6
7
8
9
# Enable DHCP only on the ppp0 interface; other interfaces are managed by NetworkManager
allowinterfaces ppp0

# IPv6 configuration for the ppp0 interface
# The ISP typically provides an IPv6 prefix delegation (IA_PD)
# dhcpcd will automatically allocate IPv6 addresses and assign prefixes to the home network
interface ppp0
ipv6
ia_pd 1

Start and enable the dhcpcd service:

1
2
sudo systemctl enable dhcpcd
sudo systemctl start dhcpcd

Configuring the Firewall

To enable internet access for devices on the home network, configure NAT to forward packets from the home network to the PPPoE interface. Edit /etc/sysctl.conf and uncomment the following lines:

1
2
net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1

Apply the changes:

1
sudo sysctl -p

For firewall rules, we use nftables. If you’re more familiar with iptables, you can use that instead. Below is an example configuration:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# /etc/nftables.conf
flush ruleset

table inet filter {
chain input {
type filter hook input priority -10; policy drop;

# loopback
iif "lo" accept

# icmp
ip6 daddr fe80::/64 udp dport dhcpv6-client accept
meta l4proto { icmp, ipv6-icmp } accept

# related
ct state vmap { invalid : drop, established : accept, related : accept }
ct state new limit rate over 1/second burst 10 packets drop
}

chain forward {
type filter hook forward priority -10; policy drop;

# icmp
meta l4proto { icmp, icmpv6} accept

# NAT forward
iifname "enp2s0" oifname "ppp0" accept
ct state established,related accept
}

chain output {
type filter hook output priority -10; policy accept;
}
}

table inet nat {
chain postrouting {
type nat hook postrouting priority srcnat; policy accept;

# NAT masquerade
iifname enp2s0 oifname ppp0 masquerade
}
}

Apply the firewall rules:

1
nft -f /etc/nftables.conf

Configuring DNS

Since DHCP is disabled on the interfaces, you must manually configure DNS to resolve domain names. Ubuntu Server uses systemd-resolved by default. Disable it and set DNS manually:

1
2
3
sudo systemctl disable systemd-resolved
sudo systemctl stop systemd-resolved
sudo rm /etc/resolv.conf

Create a new /etc/resolv.conf file with the following content:

1
2
nameserver 119.29.29.29
nameserver 223.5.5.5

Final Steps

At this point, the router is configured. For simplicity, I opted to let a downstream WiFi router handle DHCP for the LAN. The configuration is as follows:

  1. Modem -> Server (WAN: public IP, LAN: 192.168.0.1)
  2. Server -> WiFi Router (WAN: 192.168.0.2, LAN: 192.168.1.1, DHCP)
  3. WiFi Router -> Devices

Improving Stability

Network disruptions or ISP issues can cause disconnections. Use a watchdog script with crontab to monitor the PPPoE service: Crontab entry:

1
*/1 * * * * bash /usr/local/bin/pppoe_watchdog.sh >> /var/log/pppoe_watchdog.log 2>&1

Watchdog script (/usr/local/bin/pppoe_watchdog.sh):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/bin/bash
if ! ip link show ppp0 &>/dev/null; then
echo "[`date`] ppp0 interface missing, restarting connection"
poff -a
sleep 5
pon dsl-provider
sleep 20
elif ! ip -4 addr show dev ppp0 | grep -q "inet "; then
echo "[`date`] ppp0 has no IPv4, restarting connection"
poff -a
sleep 5
pon dsl-provider
sleep 20
fi

if ! ip -6 addr show dev ppp0 | grep -v "fe80:" | grep -q "inet6 "; then
echo "[`date`] ppp0 has no IPv6, restarting dhcpcd"
systemctl restart dhcpcd
fi

echo "[`date`] exit"

Conclusion

You now have a functional home router configured with PPPoE dial-up, DHCP (IPv4/v6), and basic firewall rules. You can further extend this setup with:

  • VPN for remote access
  • DNS services for LAN name resolution or ad blocking
  • Advanced firewall rules for granular access control
  • Traffic interception, analysis, or transparent proxying
  • … and more!

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.

Link to this article: https://blog.axell.top/archives/using-ubuntu-server-as-a-router-pppoe-dial-up/