Wednesday, February 1, 2017

Setting up Linux Router with PPPoE for CenturyLink DSL

There were two big gotchas, for me at least:
  1. Ethernet packets must be in VLAN 201.
  2. (a) Getting the right MTU and (b) clamping MSS to MTU.
Basically you just install and run ppoeconf, and it does everything for you:
  1. configures /etc/ppp/peers/dsl-provider
  2. modifies /etc/network/interfaces
  3. starts up pppd
But then there are the gotchas.

Gotcha #1:

If the ethernet packets aren't tagged with VLAN 201, then your router can send out a PADI packet, but will never get back a PADO response from the DSL access concentrator.

My fix for the VLAN was easy.  The DSL modem I got already had a setting to make it tag ethernet packets with VLAN 201, but I didn't know that was required when I started, so I had to find this out the hard way.  If your modem can't do this for you, I know there is a way to set up a virtual interface named eth0.201 for example, but I've personally never done it.

Gotcha #2a:

pppoeconf pretty much takes care of this for you, setting the MTU to 1492 by default, which really should work, but after some ping testing and whatnot, I determined that for me I needed to set it to 1484.

So this is what my /etc/ppp/peers/dsl-provider looks like (with all comments removed):

noipdefault
defaultroute

hide-password
lcp-echo-interval 20
lcp-echo-failure 3
connect /bin/true
noauth
persist
mtu 1484

noaccomp
default-asyncmap
plugin rp-pppoe.so eth1
user "myppoeuser@qwest.net"


Gotcha #2b:

pppoeconf actually handles this for you as well, by creating a file in /etc/ppp/ip-up.d named 0clampmss with this firewall rule:

iptables -t mangle -o "$PPP_IFACE" --insert FORWARD 1 -p tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1400:65495 -j TCPMSS --clamp-mss-to-pmtu

Without this, some websites might work and others might not.  Some might load partway, etc.  That's what was happening to me, and I finally realized the problem was this rule had gone missing.  It was because I have my own firewall script that I had run, which flushes all the chains and adds just the rules I want.  So I needed to add a rule for this to my firewall script.