Linux IPv6 Router How To
Linux IPv4/IPv6 router using shorewall and dnsmasq only, without radvd.
Background
My old home wi-fi router is dying and instead of buying one, I decided to build one with Linux this time. This will give me more control and visibility into my network and internet traffic.
Hardware
The new box I am using is Qotom-Q355G4:
- Main Port: 1 HD Video Port + 1 COM + 2 USB 2.0 + 2 USB 3.0 + 4 LAN.
- CPU: Intel Core i5-5200U SOC Processor (Broadwell, Dual Core, 3M Cache, 2.2GHz, up to 2.7GHz). Support AES-NI.
- Configuration: 8GB DDR3L RAM, 512GB mSATA SSD, WiFi, NO 2.5" SATA HDD, fanless
- Audio in/out
It is way overkill for a home router even with 100M+ download speed. However it has the extra power to do some docker testing.
Software
Function | Software |
---|---|
OS | Ubuntu Server |
IPv6 DHCP Client | wide-dhcpv6-client |
Firewall | shorewall & shorewall6 |
Wi-Fi Access Point | hostapd |
DNS and DHCP Server | dnsmasq |
Network Layout
NIC Port | Network Zone | IPv4 | IPv6 |
---|---|---|---|
1 | WAN (Internet) | from ISP | from ISP |
2 & Wi-Fi | DMZ | 10.0.0.1/24 | PD from ISP |
3 & 4 | LAN | 192.168.0.1/24 | PD from ISP |
OS Network Setup
The base OS is Ubuntu Server with unnecessary packages removed. You can check my Ubuntu Commands page on that.
To support IPv6 and as a router, following need to be set in /etc/sysctl.conf
|
|
enp1s0
is device name of NIC 1. The last 2 lines are for accepting IPv6 info from upstream ISP.
Netplan Setup
The base interface setup is as follow in /etc/netplan/01-netcfg.yaml
|
|
First we have the “wan” interface enp1s0
:
Option | Usage |
---|---|
dhcp4: true | We need to IPv4 address from upstream |
dhcp-identifier: mac | This is needed to get proper dhcp |
link-local: [ ] | This prevent systemd-network from starting dhcp6, explain below. |
The optional: ture
for other interfaces allow boot process to continue without delay if no cable is plugged in.
Then we have our two bridges dmz
and lan
.
dmz
is enp2s0
(NIC2) by itself. hostapd
will add the wi-fi interfaces to it in later section.
lan
consist of enp3s0
(NIC3) and enp4s0
(NIC4) bridged together for internal network.
Plug in your internet cable to NIC 1 and enable the settings:
|
|
Internet access should be working with IPv4.
Netplan & accept_ra
Though net.ipv6.conf.enp1s0.accept_ra=2
is set in sysctl.conf
, netplan will remove it during network start up because link-local: [ ]
is used. That will prevent the router from receiving IPv6 info from upstream.
To make sure accept_ra is set after network interface is up, create following files:
/etc/systemd/system/accept_ra.service
:
|
|
/root/accept_ra.sh
|
|
Enable it during boot:
|
|
wide-dhcpv6-client
While dmz and lan IPv4s are configured in netplan, IPv6 use global address even for devices within your network. PD(prefix-delegation) is required for lan
, dmz
interfaces so devices behind them will work correctly.
Netplan doesn’t support PD config at the time of writing. Package wide-dhcpv6-client
is used. It is able to assign PD IPv6 addresses to other interfaces after PDs are received, almost (see sla-len
at end of this section) without any address hardcoding in the config file or external helper script.
Install package:
|
|
Config file is located at /etc/wide-dhcpv6/dhcp6c.conf
|
|
Enable wide-dhcpv6-client
during startup:
|
|
After reboot all 3 interfaces(enp1s0, dmz, lan) should have IPv4 and IPv6(scope global) addresses.
|
|
sla-len
: Dojournalctl -t dhcp6c | grep 'IA_PD prefix:'
. If the IA_PD prefix end in /56 instead of /64, change both line tosla-len 8;
. This config is for /64 prefix and actually not suitable for /56, which should use a singleid-assoc pd
block with twoprefix-interface
.
Firewall
A firewall is needed for the following:
- stop incoming traffic
- NAT for IPv4 traffic from lan/dmz to internet
- separation of lan and dmz
Shorewall and shorewall6 are used due to their ease of configuration. To install:
|
|
Following are the basic configuration.
Shorewall
Shorewall handle IPv4 traffic. Following are config files base on /usr/share/doc/shorewall/examples/three-interfaces/
.
/etc/shorewall/zones
|
|
/etc/shorewall/interfaces
|
|
/etc/shorewall/policy
|
|
/etc/shorewall/rules
|
|
/etc/shorewall/snat
This is NAT configuration for both lan and dmz.
|
|
Shorewall6
Shorewall6 handles IPv6 traffic. Following are config files base on /usr/share/doc/shorewall6/examples/three-interfaces
. There is no snat
for IPv6.
/etc/shorewall6/zones
|
|
/etc/shorewall6/interfaces
|
|
/etc/shorewall6/policy
|
|
/etc/shorewall6/rules
|
|
More detail examples of all the config files are in the example directory.
Wi-Fi AP
Install hostapd
to create a wi-fi access point.
|
|
iw
is a command line wifi configuration tool. It can list capabilities of wi-fi adapter.
|
|
Wi-Fi adapter of my box is wlp5s0
. It will be added to bridge lan
.
A 2nd virtual interface wlan0
will be created and join bridge dmz
.
/etc/hostapd/hostapd.conf
|
|
bssid
of the physical wi-fi adapter(wlp5s0
) is its real mac address.
bssid
of the virtual wi-fi adapter(wlan0
) can be any valid mac address format that don’t conflict with other devices in the network. I usually just increase the physical adapter mac by 1.
hostapd
may die during boot up due to interface initialization timing. Add following in hostapd.service [Service]
section:
|
|
Enable and restart service:
|
|
Reference:
DNS & DHCP
dnsmasq
is used to provide both dns and dhcp services for dmz and lan. It is able to create IPv6 dhcp range automatically base on IPv6 address of the interface.
|
|
Put the configuration file in /etc/dnsmasq/
.
|
|
Disable systemd-resolved
as it is Ubuntu default dns server and delete existing /etc/resolv.conf
.
|
|
Create new /etc/resolv.conf
|
|
Conclusion
It took much longer than I thought to put all this together.
I had to switch packages a few times due to various reasons, but mostly to avoid creating custom scripts. The most notable one is dnsmasq replacing both systemd-resolved/powerDNS-recursor and radvd. dnsmasq is able to handle both functions with much cleaner way and more flexibility.
I believe currently, if not using a full router/firewall distro like OpenWRT, pfSense or ClearOS, then dnsmasq with wide-dhcpv6-client is the best combination for DIY Linux router solution. Their ability of auto IPv6 prefix handling, which allow configurations without hardcoding IPv6 prefix, is especially important for location that can’t secure their own IPV6 prefix.
Bonus
mpd on Qotom-Q355G4
mpd
has difficulty identifying the ALSA PCM on Qotom-Q355G4. Use following /etc/asound.conf
to solve it:
|
|