Using PPPoE on Linux

When it comes to internet connectivity in Switzerland, you might stumble across ADSL or VDSL. Most of the time you’ll end up with a router provided by the provider, which is already pre-configured with the connection information. This setup might work for the majority of users, but if you’re a pro-user or enterprise with special needs, you want more.

In our case, we were looking for a much more “dynamic” way to configure the internet access, and of course we wanted to route and filter the traffic on a Linux machine. So we ended up with a dial-up account (not that shitty 56k dial-up connection) and a PPPoE modem.

What is PPPoE?

PPPoE is the abbreviation for Point-to-Point protocol over Ethernet. Basically it’s a network protocol to encapsulate PPP frames inside Ethernet frames. There’s a really nice Wikipedia Article for PPPoE:

The Point-to-Point Protocol over Ethernet (PPPoE) is a network protocol for encapsulating PPP frames inside Ethernet frames. It appeared shortly after the year 2000, in the context of the boom of the DSL as the solution for tunneling packets over the DSL connection to the ISP’s IP network, and from there to the rest of the Internet. A 2005 networking book noted that “Most DSL providers use PPPoE, which provides authentication, encryption, and compression.” Typical use of PPPoE involves leveraging the PPP facilities for authenticating the user with a username and password, predominately via the PAP protocol and less often via CHAP.

Install & configure pppd for a PPPoE connection

To use PPPoE connections on Linux, we need some additional software. On Debian-based systems, we’re looking for pppd and pppoeconf:

As we now have installed the required software, we need to configure it. The configuration of a provider (aka peer) is stored in the /etc/ppp/peers directory, and there’s already a default provider configuration file. Just have a look at it:

As we know exactly what kind of configuration parameters are required, we can create a new configuration file:

With this configuration, we make sure that the PPPoE connection is always up (aka  persist ), and that it is reopened automatically (aka  maxfail & holdoff) in case it unexpectedly disconnects.The  user  has to match the username you’ll get from your provider. Since we get our IP address dynamically (DHCP), we set the parameter  noipdefault . Of course this is our main interface for the internet connection, so we want to have a defaultroute  in place.

Of course you still need a password for your PPPoE connection, so add one more line to the /etc/ppp/chap-secrets  file:

Open the PPPoE connection

Now that you’ve everything configured, you should be able to open the PPPoE connection by calling:

Wait for a few seconds and then you should see a new interface:

To stop the connection, you can execute:

Hint: The command pon  can also be called without the peer argument, but then it looks for the default provider in /etc/ppp/peers/provider . If you want your connection to be the default provider, you can symlink your peer configuration to it:

Make the PPPoE connection coming up automatically

If you want the PPPoE connection come up automatically, you’ve several options. The good old fashioned way is an interfaces entry, at least on Debian-based systems.

This works fine when you’re rebooting your machine. But if you’ve a system with systemd enabled, you might want to start / stop your connection via systemd  / systemctl , instead of the interfaces file:

Now you’re able to manage the connection via systemctl :

Routing & Firewalling

If you want to use your Linux machine as a router and firewall, you’ve to enable IP(v4) forwarding and add some iptables rules.

IP(v4) forwarding enables Linux to forward packages from one interface (network) to another.

With iptables  we need to setup IP masquerading, which is done via NAT table. IP masquerading helps us do “hide” the client on the remote host, by rewriting the source address of the package after routing. The remote system will only see the IP address of our Linux router, and not the IP address of the client behind. While this is required for the PPPoE connection, it can also be a security enhancement in routing of private networks.

The second iptables  rule helps us to solve a PPP “issue”. Ethernet packages have a fixed size and they will define the amount of payload the can carry via MTU (maximum transmission unit). By default, Ethernet packages have a MTU size of 1500 bytes, which is fine. However, PPPoE packages have to define an additional header of 6 bytes, and a PPP ID of 2 bytes. This means in PPPoE packages, we “lose” 8 bytes and so the MTU size is reduced to 1492. This isn’t a problem in the first place, but it will become one when a client (e.g. browser / surfing the internet) connects to a server (e.g. webserver). They negotiate a MTU size of 1500 bytes, and the server starts sending data with 1500 bytes chunks, while the PPPoE package can only hold 1492 bytes. There’s a technique called MSS clamping which will fix this issue. Cisco has a really nice white paper which describes exactly that.

IMPORTANT: While the IP(v4) forwarding is persistent, the iptables rules aren’t. So you might want to do a  iptables save  or simply create a file with the iptables rules in /etc/ppp/ip-up.d/ , which will automatically be loaded as soon as the PPPoE connection is up.

7 Comments

  • vas Reply

    hi,
    here you are authenticating ppoe client with ISP providers authentication server,

    What if I want to authenticate pppoe users locally.??

    So, my set uup would be:
    1. Ubuntu machine with 2 nic cards
    2. one nic has public static IP configuration
    3. Other nic is supposed to have one switch which will contain multiple ppoe client machines and they should only access the internet once they are authenticated

  • jonny Reply

    Thanks a lot .
    I had setup rasberry pi as hotspot using pppoe. But only google or some random sites were opening. I suspected it to be gateway or dns issue. I had been searching for hours to fix it. I had no idea about this mtu thing. Really a life saver for me.
    Again Thanks a ton for your blog.

    • Dominique Barton Reply

      A bit late, but you’re welcome 😉

  • John ffitch Reply

    my firewall as 2 ethernats; one is used for the LAn and the oter has pppoe running over it. I am replacing the hardware and updating fron a broken jessie to stretch but i am unsure how to configure pppoe to run on the second ethernet. You did not seem to cover than

    • Dominique Barton Reply

      That should also work with the config above. In the provider file, simply replace eth0 with the name of the interface, where the PPPoE modem is connected. Also replace the pre-up /sbin/ip link set dev eth0 up command in the /etc/network/interfaces.d/ file.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.