Article published by: Leah Rowe
Date of publication: 29 November 2022
Most people assume that a router is a piece of hardware, but that’s not true. The router is actually software, and the hardware is just what that software runs on. Almost anything can be a router, just like anything can be on a cob in that one episode of Rick and Morty. The laptop in the photo is my router, configured in exactly the way this guide describes.
Have you ever wanted to host a server at home or in your office, but you can’t because the ISP won’t give you static IPs? Are you behind a CGNAT? This guide is for you. It will teach you how to route static IPv4 and (native) IPv6 addresses to your network, with hosts directly pingable on the internet and all ports open. With this guide, you won’t need to host your software project on github anymore, because you can instead install gitea/cgit with a mailing list on your raspberry pi and host it in your basement or living room!
I recently moved libreboot.org hosting to a much faster network than what it had before, but the new ISP doesn’t assign static IPv4 or IPv6 subnets on the line, and it has all kinds of restrictions, though speed, uptime and latency are all excellent. I decided therefore to set up a tunnel connection using Andrews & Arnold Ltd (A&A) L2TP tunnel service. This is basically similar to most VPN services, but you get a lot more freedom and flexibility e.g. IPv4 subnets (for example, you could host your own DNS on this).
It could also just be used for normal day to day internet tasks. A&A provide you with an unfiltered service, unshaped and unthrottled in any way.
Adapt this guide according to your distro. Basically all we want to do is do PPP via L2TP and enable packet forwarding in Linux, so that packets can pass between two interfaces. We then set routes. We will have these interfaces:
L2TP is a protocol used for to tunnel traffic on the internet. It’s quite commonly used by ISPs to connect customers up to their backend, where they then provide a PPP login.
So long as you have an ethernet port available to use for internet, your tunnel router can work nicely. If you need to, you could set up a WiFi connection or 4G tether on another machine, sharing that over an RJ45 ethernet port for your L2TP router to connect to; for example, raspberry pi USB tethered to 4G LTE service via dongle, assigned IPs presumably on NAT+DHCP, via ethernet.
Traffic will be forced, via static route, to A&A’s L2TP tunnel server. In this way, all traffic will go through L2TP and nothing else. It is completely isolated from your main network. With this setup, you can host your servers anywhere, and move them very easily.
You need a computer with 2 ethernet interfaces on it (RJ45). You then need to run either Linux or BSD on that. For the purpose of this tutorial, I will tell you how to configure Debian Linux, but the information here can be adapted for any other system. I really only recommend hosting this on BSD or Linux.
In my case, I had these physical interfaces:
enp14s0is configured via NAT address to normal ISP router, and static route to A&A’s L2TP server. Client-side L2TP shall connect through this
eno0is for routing IPs from the L2TP, to a switch. this is basically my LAN port
Yours may differ, so adapt accordingly.
When you first install Debian on the router, you might aswell just use the net installer. Install only the base system (
Standard system utilities selected in
tasksel). You might also enable SSH, if you wish.
Before you actually configure the routing, your Debian machine must have internet so that you can download packages. Alternatively, you might have apt configured to fetch them from installation media. It’s up to you, really.
You must install these packages:
apt-get install ppp pppoe xl2tpd iproute2 tcpdump net-tools resolvconf
You should install these packages BEFORE doing anything else. Just connect via DHCP or something and install these. You could also grab them from Debian installation media.
If you need a decent text editor, might I suggest Vim. As scandalous as it may seem, Debian doesn’t install it by default!
MAKE SURE you have the packages installed, as listed above, before continuing. At this point, we dive straight in and configure everything.
For our purposes, the WAN side on the router will connect to the internet via NAT, through the main ISPs network, but we will not use DHCP. Instead, a static (NAT) IP address will be specified, but with no gateway; in so doing, no default route will be set, but we will set a static route.
The static route will only route traffic to
220.127.116.11 which is A&A’s L2TP server, via what would otherwise be a gateway IP, in my case
10.42.0.1, but in your case that might be
192.168.1.1. You must adapt accordingly.
By setting the static route this way, we can only connect to A&A L2TP when the tunnel connection is down. When it’s up, we still have no default route but then we add a default route, going through the PPP tunnel via L2TP. In this way, all traffic (except traffic to
18.104.22.168 directly) will go through the L2TP tunnel, NOT your main upstream ISP (e.g. Virgin, Sky, TalkTalk). By doing this, we ensure that all traffic correctly goes through A&A only.
The reason we use A&A’s IP address directly, is because we don’t have DNS when the L2TP tunnel is down.
Please read the comments in the example below. They are important. You must adapt the config below for your purposes:
source /etc/network/interfaces.d/* # The loopback network interface auto lo iface lo inet loopback # NOTE: 10.42.0.116 is the normal gateway router, LAN side, # not anything l2tp-related. # the 10 addresses below would likely be `192.168.x.x/24` in your case # adapt accordingly # NOTE: the IPs on eno0 are /28 subnet ones, assigned by a&a for my l2tp service # you must adapt these for your own line. please note also a&a typically # offers a /29 for l2tp but they gave me a /28; for a /29, you should # use netmask 255.255.255.248, but in my case i specified 255.255.255.240 auto enp14s0 allow-hotplug enp14s0 iface enp14s0 inet static address 10.42.0.116 netmask 255.255.255.0 network 10.42.0.0 # gateway 10.42.0.1 # we will set a custom route instead. see below broadcast 10.42.0.255 up /sbin/ip route add 22.214.171.124/32 via 10.42.0.1 dev enp14s0 # LAN auto eno0 iface eno0 inet static address 126.96.36.199 netmask 255.255.255.240 dns-nameservers 188.8.131.52 184.108.40.206 iface eno0 inet6 static address 2001:8b0:b95:1bb5::1 netmask 64 dns-nameservers 2001:8b0::2020 2001:8b0::2021 # NOTE: because above, we are forcing everything to go over L2TP, we will # not have DNS until the L2TP is up. this is why the IP address of A&A's # L2TP router is used directly! # NOTE: no hardline so PPP not configured here. This is handled via xl2tpd
NOTE: IP address
220.127.116.11 is what
l2tp.aa.net.uk resolves to, and it shall be used directly for our purposes, due to absent name resolution during initialisation of this network, when setting up L2TP. The static route that we set, on
enp14s0, ensures that we do have internet on the WAN side (to the main ISP, not A&A), assuming that the (physical) main network itself works.
You must permit packet forwarding, so that traffic can flow between the two network interfaces. Edit this file:
Uncomment this line:
And this line (NOTE: disables stateless address autoconfiguration)
The lines should then look like this:
The last command simply applies it now, but this would also apply during every booting of your system.
It may seem counter-intuitive, that we’re configuring PPP as though we’re on a hardline, but this is important for the next step. A&A provides L2TP without authentication, but then you authenticate via PPP routed through L2TP. It is through PPP that your (public) IP addresses are assigned, when you use A&A. Such is also true of their hardline servers (e.g. VDSL/FTTP).
Debian kernels should already have the correct modules, but otherwise you must ensure that the
CONFIG_L2TP options are enabled in your kernel configuration.
It should be noted that A&A L2TP service is (as of this day) currently without IPSEC or other encryption such as wireguard. This is less than ideal, but you will likely be doing a lot of encrypted things online anyway (lots of websites are https-aware nowadays).
As a result of plain L2TP being used, you can get away with hosting this on very weak hardware, and still get full speed. One day, I might write guides for how to use L2TP with, say, IPSEC enabled (using something other than A&A for the upstream L2TP service).
You will not be able to use DNS until the L2TP is up, so we will use A&A’s IP address for
l2tp.aa.net.uk directly, which is
Place the following contents:
[lac aaisp] lns = 18.104.22.168 require authentication = no pppoptfile = /etc/ppp/options.aaisp
Create this file, and place the following contents:
password entries are your A&A login details for L2TP.
+ipv6 ipv6cp-use-ipaddr name xyz@a.X password Your_xyz@A.X_password noauth ifname ppp-aaisp-l2tp
PPP and L2TP are managed by
pppd, which executes if up/down scripts when interfaces go up or down. We shall manipulate this accordingly:
This file sets a default route on IPv6, but it can be (ab)used in general to handle L2TP/PPP going up/down. This file is for when the link goes up. A default route must be set!
The file should contain this logic:
#!/bin/bash /bin/logger $1 is up if [ $1 = "ppp-aaisp-l2tp" ]; then /bin/logger "AAISP over L2TP circuit is online; adding routes" /sbin/ip route add default dev ppp-aaisp-l2tp scope link /sbin/ip -6 route add default dev ppp-aaisp-l2tp scope link fi
Don’t forget to make it executable:
chmod 755 /etc/ppp/ipv6-up.d/0000-defaultroute
The routes must be deleted, when the line goes down:
#!/bin/bash /bin/logger $1 is down if [ $1 = "ppp-aaisp-l2tp" ]; then /bin/logger "AAISP over L2TP circuit is offline; removing routes" /sbin/ip route del default dev ppp-aaisp-l2tp scope link /sbin/ip -6 route del default dev ppp-aaisp-l2tp scope link fi
Don’t forget to make this executable aswell:
chmod 755 /etc/ppp/ipv6-down.d/0000-defaultroute
You may notice that we have, thus far, not specified any way in which the L2TP tunnel connection is actually started. This will now be explained.
Create the xl2tpd control file:
mkdir -p /var/run/xl2tpd touch /var/run/xl2tpd/l2tp-control
Start the xl2tpd service:
systemctl start xl2tpd
Enable it at every boot:
systemctl enable xl2tpd
We now have the L2TP daemon starting automatically at boot time, but it will not automatically bring up your connection. The daemon monitors writes to a control file, which we just created at
Tell the daemon to connect to aaisp:
echo “c aaisp” > /var/run/xl2tpd/l2tp-control
To stop the L2TP connection, do this:
echo “d aaisp” > /var/run/xl2tpd/l2tp-control
ip a, you will see the tunnel connection listed as
ppp-aaisp-l2tp, but only when the PPP (over L2TP) connection is active. As you saw earlier, we went through the ifup/down scripts in Debian, that add/remove routes.
You need to decide whether you want L2TP automatically starting in your router. In some situations, it may not actually be desirable for it to autostart, like if you just want to quickly test a new network but aren’t ready for it to go in production yet.
You can find useful logs in
Due to the way xl2tpd works (control files), I concluded that the best way to handle this is with crontab. As root, do:
In there, insert:
* * * * * echo "c aaisp" > /var/run/xl2tpd/l2tp-control
You might also add something like this, for resolving domain names:
* * * * * echo "nameserver 22.214.171.124" > /etc/resolv.conf
This L2TP routing setup is a bit hacky, and this guide could use some refinement. The rule for
resolvconf, as above, simply keeps DNS working. The nameserver IP used, in the above example, is provided by A&A for customers.
Running the command when L2TP is up does nothing, and xl2tpd will simply exit on that run, while the tunnel remains open. When the tunnel is down, running that command will bring it back up.
If your connection frequently has drop-outs of a few seconds, xl2tpd re-running every minute will give you a lot more unnecessary down time.
It may be advisable to run every 5 seconds instead. The
crontab file does not provide for this, allowing only per minute instructions in our case.
You might simply run a script at boot time, that does it in a five-second loop. For example:
#!/bin/sh while true do echo "c aaisp" > /var/run/xl2tpd/l2tp-control sleep 5 done
A more intelligent way might be to put, in the ifdown script as above, an instruction to run the above loop, but make the loop exit when the tunnel is up. That same modified script would also run at boot time. In this way, you might save an extra second or two, but I wouldn’t bother.
You can simply hook up an ethernet switch, to the 2nd interface on your router, the one that has allocated IPv4/6 subnet addresses on it as per
/etc/network/interfaces. Your host will then connect to that switch.
On that ethernet switch, you will then set your host(s) to use an IP address from the /28 or /29 IPv4 subnet. You may even have a bigger subnet than that, if you asked A&A nicely. You can also use IPv6, but without SLAAC; simply set as many static IPv6 addresses that you want, on the host.
With this routing setup, dual stack IPv4 and IPv6 is possible, for any host connected to it.
The internet should Just Work on the router itself. No DHCP or NAT is running, in this configuration; perhaps a guide could be written for that, but for this exact setup as described on the page, you can simply specify the following as static IP address:
255.255.255.240on my /28 subnet. If you have a /29, it should be
126.96.36.199/28, so the broadcast address would be
188.8.131.52; 128 is 10000000 in binary, and 32-28 is 4, so we mask the 4 least significant bits which becomes 10001111, which is 143. You need to do the maths, for your specific IP and subnet size.
Again, there is no DHCP on this network; additionally, we are not running a DNS resolver (you could run one, if you wish). You must specify one manually. Many resolvers exist. A&A provide them, for customers:
You should configure SSH to accept keys only and (optional) only listen on a local IP address (e.g. 10 network). This is beyond the scope of the article, but it’s quite trivial to set up.
The following commands may be useful later, to debug issues:
ip route ip -6 route ping 184.108.40.206 ping6 2001:4860:4860::8888 tcpdump -ni eno0
Your main ISP (that you use to then run L2TP through) most likely doesn’t support higher than 1500 MTU, if that. Your L2TP connection will add bytes in a frame, so the encapsulated PPP connection will have a lower MTU. There is no way to avoid this, unless you have a hypothetical ISP that can give you, say, 1540 MTU or something like that.
Anyway, the result is that your packets will be fragmented. In your A&A control panel login (see: https://control.aa.net.uk/), you can set MTU manually but I just recommend leaving it on auto.
If you see an MTU of, say, 1460, on your PPP connection (when SSH’d into the router and running
ip a or something), don’t worry, it’s normal. Just let your router handle it, it’s what Linux was born to do.
Sometimes called reverse DNS.
In an IP address, the PTR record resolves back to an arbitrary domain name which can be set. Typically, your ISP will assign one and that’s all you get, but A&A lets you change it in the control panel: https://control.aa.net.uk/
You must get your domain name added to your login, even if it’s not actually registered with A&A. Simply email their tech team and ask them to do it. You could also just ask them to set the PTR records.
For example, A/AAAA records in your DNS for
foo.bar.com might point to one of your IPs, and then you’d make that IP point back to
foo.bar.com. You can do this for an IPv4 and an IPv6 address that A&A assigns to you.
This can be very useful when running mail servers, precisely because you can make the same entry for both IPv4 and IPv6. For example, my mail server has the PTR record, on IPv4 and IPv6, of
libreland.libreboot.org and I specify this in my mail server plus DNS server configurations; the IP is also set in my SPF record, with A/AAAA records for that IP pointing to
libreland.libreboot.org, so that everything matches up. This, plus other things like setting proper DKIM record, is essential when running a mail server, because a lot of services (like GMail) will block you on suspicion of spam if these are misconfigured.
My next guide may in fact be how to set up a mail server! Also DNS and web, etc.
I will not configure a firewall on this network. I always get an IPv4 subnet from a&a either on hardlines or L2TP, and I run an open network. The router is always hardened to only allow local SSH connections, or SSH turned off, for security.
No NAT/DHCP either. If local hosts want to firewall themselves, they can, and they can provide that stuff. I really don’t see the point in using DHCP for public IPv4 subnets.
If I want NAT/DHCP inside such a network, I usually plug in an OpenWRT router and set a static IP on the WAN port for that. I also use OpenWRT routers to in this way, when I want to set up a WiFi connection behind A&A.
Essentially, I like my main network to be “invisible”. Just plug in and set an IP (from the public subnet) and you’re good to go. This assumes you have good physical security and/or you trust the people that have access to it.
In short, this is a real internet connection. Anything you plug into this network will be directly on the internet. You should consider your security model, when doing this. It is especially important to consider physical security; who do you trust, if you’re running this at your company (or even your own home)?
You should not connect anything insecure directly to this main network. For iexample, your playstation or proprietary shitware Windows PC are not to be trusted. A secure linux/BSD machine, assuming you’re competent, is absolutely fine. This setup is intended for sysadmins who really want to host lots of servers on their home network.
You might configure
codel which is nice for QoS but that’s beyond the scope of this article.
/var/lock directories should also be tmpfs. This isn’t strictly necessary, but for a high-performance machine it might be desirable, especially for something like this.
If you’re running this on really slow hardware, you might consider that, but you must also take memory usage into account when relying on tmpfs.
Markdown file for this page: https://vimuser.org/l2tp.md
This HTML page was generated by the untitled static site generator.