Skip to content

Instantly share code, notes, and snippets.

@insom
Created October 9, 2023 21:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save insom/a2a6e6d85f308661d8dabc68c9c3a02d to your computer and use it in GitHub Desktop.
Save insom/a2a6e6d85f308661d8dabc68c9c3a02d to your computer and use it in GitHub Desktop.
Running PPPoE in its own network namespace.

Problem

I don't want a single router, I want a pair. But I also don't want two dedicated pieces of equipment, which is wasteful.

I already have two machines I could use, but their network namespace is polluted with all sorts of stuff (unauthenticated Redis etc.). I don't want to put them "on" the Internet.

I tried running VyOS VMs but couldn't get a full 1 gigabit out of them on the hardware that I have.

Solution

Run pppd in its own network namespace. No listening ports on the host will leak. It's like a container, but it only contains the network (which is all I need).

Assumptions

You have a VLAN1 default network of normal-ish internet hosts, and you speak PPPoE over VLAN35 to your telco. (Which Bell Canada customers all do, AFAICS).

You have all the right switch config for this.

You have br0 and br35 devices set up for your default network and for the VLAN. In Debian that means:

apt install bridge-utils vlan -y
cat << EOF > /etc/network/interfaces
auto lo
iface lo inet loopback

auto br0
iface br0 inet static
    address 192.168.2.103
    netmask 255.255.254.0
    gateway 192.168.2.1
    bridge_ports eno1 # my physical NIC

auto eno1.35
iface eno1.35 inet manual

auto br35
iface br35 inet manual
    bridge_ports eno1.35
EOF
# Then reboot, or restart networking the usual way.

Cool. Let's create a network namespace for PPP to live in, with a couple of veth pair devices. (One half stays in the default namespace, and get added to the bridges -- the other half will be moved into the new namespace).

ip netns add ppp
ip link add v1 type veth peer name ppp-v1
ip link add v35 type veth peer name ppp-v35

The outside / default namespace parts:

ip link set up dev ppp-v1
ip link set up dev ppp-v35
brctl addif br0 ppp-v1
brctl addif br35 ppp-v35

And the inside / ppp namespace parts:

ip link set v1 netns ppp
ip link set v35 netns ppp
ip netns exec ppp ip link set up dev v1
ip netns exec ppp ip link set up dev v35
ip netns exec ppp ip addr add 192.168.2.1/23 dev v1

Nice. We should install PPP and set up a reasonable config.

apt install pppoe ppp
cat << EOF > /etc/ppp/peers/dsl-provider
noipdefault
defaultroute
hide-password
lcp-echo-interval 20
lcp-echo-failure 3
connect /bin/true
noauth
persist
mtu 1492
noaccomp
default-asyncmap
plugin rp-pppoe.so
nic-v35 # <= Important
user "YOURUSERNAME"
# nodetach # <= optional, if you want pppd to stay in the foreground
EOF
cat << EOF > /etc/ppp/pap-secrets
"YOURUSERNAME" * "YOURPASSWORD"
EOF

We can verify connectivity inside the container.

ip netns exec ppp bash
pppoe-discovery -I v35
Access-Concentrator: OTWAON1147W_RE0
Got a cookie: 2d 20 ad 7c e3 f3 ac d0 d7 bc 22 2e 2f 7f 57 70
AC-Ethernet-Address: 88:d9:8f:20:e2:e0
--------------------------------------------------

Let's ring and set up IP masquerading.

ip netns exec ppp pppd call dsl-provider
ip netns exec ppp iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
ip netns exec ppp iptables -P FORWARD ACCEPT
# outside, in default, we also need to forward packets
iptables -P FORWARD ACCEPT

And some output from PPP, to show it all working:

pppd call dsl-provider
Plugin rp-pppoe.so loaded.
PPP session is 2699
Connected to 88:d9:8f:20:e2:e0 via interface v35
Using interface ppp0
Connect: ppp0 <--> v35
PAP authentication succeeded
peer from calling number 88:D9:8F:20:E2:E0 authorized
local  IP address <REDACTED>
remote IP address 10.50.44.246
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment