Guardian
This document describes how to build Guardian, a switch, router, and firewall. Guardian runs on commodity router hardware and provides a number of features, including:
- a wireless access point,
- a switch comprised of a number of Gigabit Ethernet ports,
- a firewall and NAT translator, and
- a print service.
Guardian is made up of the following hardware components:
- a Microtik RouterBoard 493G,
- a Microtik RouterBoard R52n-M miniPCI wireless adapter,
- a Microtik 5V USB power injector,
- a RouterBoard 493G case with interior USB extension cable,
- two whip antennas,
- a Belkin USB-to-RS-232 adapter,
- an RS-232 cable,
- a null-modem adapter,
- a GFP121U-0520 GME switching AC/DC power adapter, and
- a USB printer.
I purchased my hardware from Baltic Networks.
Selecting the software for a Guardian image
This section describes how to gather and select the OpenWrt source code which makes up Guardian.
- Obtain the OpenWrt source tree using
git clone https://git.openwrt.org/openwrt/openwrt.git
. - Enter the OpenWrt source tree and modify the package configuration provided by
feeds.conf
to usesrc-git packages ssh://git@github.com/MikePetullo/packages.git
. Run./scripts/feeds update
. - Activate the necessary packages using:
./scripts/feeds install ca-certificates \
ddns-scripts \
freifunk-watchdog \
libustream-openssl \
openvpn \
p910nd \
rsync \
wget \
zoneinfo-core \
zoneinfo-northamerica
- Run
make menuconfig
and select:
- Target System: Atheros ATH79 (DTS)
- Subtarget: Mikrotik devices
- Target Profile: MikroTik RouterBoard 493G
- Target Images: ramdisk then tar.gz (Note that you need to build twice for the RB493G: (1) for a TFTP image and (2) for an installable rootfs image.)
- Base system:
- ca-certificates
- Kernel Modules:
- Netfilter Extensions: kmod-ipt-tee
- Other modules: kmod-softdog
- USB Support:
- kmod-usb-ohci
- kmod-usb-printer
- kmod-usb2
- Wireless Drivers: kmod-ath9k
- LuCI: Freifunk: freifunk-watchdog
- Network:
- File Transfer:
- rsync
- wget
- Firewall: iptables-mod-tee
- IP Addresses and Names:
- ddns-scripts
- ddns-scripts_no-ip.com
- Printing: p910nd
- VPN:
- openvpn-openssl
- File Transfer:
- Utilities:
- zoneinfo: zoneinfo-northamerica
- Create the directory files and populate it as described in the following sections.
Configuring the network interfaces
Aside from the standard loopback device, Guardian provides for four networks:
- a private LAN for workstations and internal servers (192.168.1.128/25),
- a public LAN for Internet-facing servers (192.168.1.0/25),
- a WAN (DHCP-assigned), and
- a network for use with OpenVPN (192.168.2.0/24).
Guardian splits its switch ports between the private and public LANs. Guardian also provides WiFi connectivity to its private and public LANs.
/etc/config/network
:
config interface loopback
option ifname lo
option proto static
option ipaddr 127.0.0.1
option netmask 255.0.0.0
config switch
option name switch0
option enable 1
option reset 1
option enable_vlan 1
config switch
option name switch1
option enable 1
option reset 1
option enable_vlan 1
# Private:
config switch_vlan
option device switch0
option vlan 0
option vid 100
# 0: CPU, 1--4: phy. ports, 5 unused.
# t indicates packets sent will be VLAN tagged; rec'd must match tag.
option ports "0t 1 2 3 4"
config interface privlan
option ifname 'eth0.100 tap0' # Bridge in OpenVPN tap device.
option type bridge
option proto static
option ipaddr 192.168.1.129
option netmask 255.255.255.128
# Public:
config switch_vlan
option device switch1
option vlan 1
option vid 200
# 0: CPU, 1--4: phy. ports, 5 below.
# t indicates packets sent will be VLAN tagged; rec'd must match tag.
option ports "0t 1 2 3 4"
config interface publan
option ifname eth1.200
option type bridge
option proto static
option ipaddr 192.168.1.1
option netmask 255.255.255.128
# WAN:
config switch_vlan
option device switch1
option vlan 2
option vid 300
# t indicates packets sent will be VLAN tagged; rec'd must match tag.
option ports "0t 5"
config interface wan
option ifname eth1.300
option proto dhcp
# Use OpenDNS (not ISP DNS) for content filter.
option dns "208.67.222.123 208.67.220.123"
option peerdns 0
# OpenVPN:
config interface vpn
option ifname tun0
option proto none
/etc/config/wireless
(replacePCIPATH
,ExampleCom
,ExampleComGuest
,KEY1
, andKEY2
):
config wifi-device radio0
option type mac80211
option country US
option channel 11
option hwmode 11ng
option htmode HT20
option path PCIPATH
list ht_capab SHORT-GI-40
list ht_capab TX-STBC
list ht_capab RX-STBC1
list ht_capab DSSS_CCK-40
config wifi-iface
option device radio0
option network privlan
option mode ap
option ssid ExampleCom
option encryption psk2
option key KEY1
config wifi-iface
option device radio0
option network publan
option mode ap
option ssid ExampleComGuest
option encryption psk2
option key KEY2
Configuring the firewall
Guardian’s firewall drops most incoming traffic destined for its private and OpenVPN LANs. Guardian also blocks outgoing DNS queries from its LANs which are destined to servers other than Guardian. Aside from this, Guardian allows:
- connections from the private LAN to Guardian,
- connections from the OpenVPN LAN to Guardian,
- DHCP and DNS requests from the public LAN to Guardian,
- and OpenVPN connections from anywhere to Guardian.
Guardian allows LDAPS and Kerberos traffic to flow from the public LAN to the private LAN because it assumes that the network’s authentication services exist on the private LAN.
Guardian redirects connections for the following services from the WAN to 192.168.1.5 on the public LAN:
- SSH,
- HTTP,
- HTTPS,
- SMTP,
- XMPP client-to-server connections, and
- XMPP server-to-server connections.
Guardian also provides a copy of all packets to 192.168.1.8 for analysis.
- /etc/config/firewall:
config include
option path /etc/firewall.user
config defaults
option drop_invalid 1
option input DROP
option output DROP
option forward DROP
# WAN: NAT, drop incoming; accept outgoing; drop forward.
config zone
option name wan
option network wan
option input DROP
option output ACCEPT
option forward DROP
option masq 1
# Private LAN: drop incoming; accept outgoing; reject forward.
config zone
option name privlan
option network privlan
option input DROP
option output ACCEPT
option forward REJECT
# Public (guest) LAN: drop incoming; accept outgoing; reject forward.
config zone
option name publan
option network publan
option input DROP
option output ACCEPT
option forward REJECT
# OpenVPN LAN: drop incoming; accept outgoing; reject forward.
config zone
option name vpn
option network vpn
option input DROP
option output ACCEPT
option forward REJECT
# Forward from private LAN to WAN.
config forwarding
option src privlan
option dest wan
# Forward from public LAN to WAN.
config forwarding
option src publan
option dest wan
# Forward from OpenVPN LAN to WAN.
config forwarding
option src vpn
option dest wan
# Forward from private LAN to public LAN.
config forwarding
option src privlan
option dest publan
# Forward from OpenVPN LAN to public LAN.
config forwarding
option src vpn
option dest publan
# Forward from OpenVPN LAN to private LAN.
config forwarding
option src vpn
option dest privlan
# Forward from private LAN to OpenVPN LAN.
config forwarding
option src privlan
option dest vpn
# Forbid DNS requests to outside servers unless from router.
config rule
option target REJECT
option src *
option dest wan
option dest_port 53
option proto tcpudp
# Allow DNS requests from public LAN.
config rule
option target ACCEPT
option src publan
option dest_port 53
option proto tcpudp
# Allow ALL connections from private LAN to router.
config rule
option target ACCEPT
option src privlan
option proto all
# Allow ALL connections from OpenVPN LAN to router.
config rule
option target ACCEPT
option src vpn
option proto all
# Allow OpenVPN connections from anywhere to router.
config rule
option target ACCEPT
option src *
option dest_port 1194
option proto udp
# Allow DHCP requests from public LAN to router.
config rule
option target ACCEPT
option src publan
option src_port 67-68
option dest_port 67-68
option proto udp
# Allow LDAPS requests from public LAN to private LAN.
config rule
option target ACCEPT
option src publan
option dest privlan
option dest_port 636
option proto tcp
# Allow Kerberos requests from public LAN to private LAN.
config rule
option target ACCEPT
option src publan
option dest privlan
option dest_port 88
option proto tcp
# Redirect HTTP to herald.
config redirect
option target DNAT
option src wan
option proto tcp
option src_dport 80
option dest_ip 192.168.1.5
option dest publan
# Redirect HTTPS to herald.
config redirect
option target DNAT
option src wan
option proto tcp
option src_dport 443
option dest_ip 192.168.1.5
option dest publan
# Redirect SMTP to herald.
config redirect
option target DNAT
option src wan
option proto tcp
option src_dport 25
option dest_ip 192.168.1.5
option dest publan
# Redirect Jabber client-to-server connections to herald.
config redirect
option target DNAT
option src wan
option proto tcp
option src_dport 5222
option dest_ip 192.168.1.5
option dest publan
# Redirect Jabber server-to-server connections to herald.
config redirect
option target DNAT
option src wan
option proto tcp
option src_dport 5269
option dest_ip 192.168.1.5
option dest publan
- /etc/firewall.user:
iptables -t mangle -A INPUT ! -s 192.168.1.8/32 -j TEE --gateway 192.168.1.8
iptables -t mangle -A OUTPUT ! -d 192.168.1.8/32 -j TEE --gateway 192.168.1.8
iptables -t mangle -A FORWARD ! -d 192.168.1.8/32 ! -s 192.168.1.8/32 -j TEE --gateway 192.168.1.8
Configure OpenVPN
Guardian accepts OpenVPN connections, allowing access to its private LAN from remote workstations.
/etc/config/openvpn
(replace example.com
):
package openvpn
config openvpn privlan
option enable 1
option port 1194
option proto udp
option dev tun0
option txqueuelen 1000
option tun-mtu 1500
option mssfix 1300
option ca /etc/openvpn/ca.cert
option cert /etc/openvpn/example.com.cert
option key /etc/openvpn/example.com.key
option dh /etc/openvpn/dh2048.pem
option ifconfig-pool-persist /tmp/ipp.txt
option keepalive '10 120'
option persist-key 1
option persist-tun 1
option status /var/log/openvpn-status.log
option verb 3
option server '192.168.2.0 255.255.255.0'
option client-to-client 1
option tls-version-min 1.2
option tls ECDHE-RSA-AES256-GCM-SHA384
list push 'redirect-gateway def1'
list push 'dhcp-option DNS 192.168.1.129'
list push 'route 192.168.1.0 255.255.255.128'
list push 'route 192.168.1.128 255.255.255.128'
## Configure basic system settings
1. `/etc/config/p910nd`:
config p910nd option device /dev/usb/lp0 option port 0 option bidirectional 1 option enabled 1
2. `/etc/config/system`:
config system option hostname guardian.example.com option timezone EST5EDT,M3.2.0,M11.1.0
config timeserver ntp list server 0.openwrt.pool.ntp.org list server 1.openwrt.pool.ntp.org list server 2.openwrt.pool.ntp.org list server 3.openwrt.pool.ntp.org option enabled 1 option enable_server 0
3 `/etc/config/ddns` (replace `examplecom`, `example.com`, `USERNAME`, and `PASSWORD`):
config service ’examplecom' option enabled ‘1’ option interface ‘wan’ option service_name ’no-ip.com' option lookup_host ‘www.example.com’ option domain ’example.com' option username ‘USERNAME’ option password ‘PASSWORD’ option use_https ‘1’ option cacert ‘/etc/ssl/certs’ option use_syslog ‘3’ 4. /etc/config/freifunk-watchdog
:
config process
option process dropbear
option initscript /etc/init.d/dropbear
config process
option process crond
option initscript '/etc/init.d/cron'
config process
option process dnsmasq
option initscript /etc/init.d/dnsmasq
config process
option process p910nd
option initscript /etc/init.d/p910nd
/etc/config/dropbear
:
config dropbear
option PasswordAuth 'off'
option RootPasswordAuth 'off'
option Port '22'
/etc/config/dhcp
:
config dhcp privlan
option interface privlan
option start 138 # Room for static at bottom.
option limit 254 # Room for OpenVPN at top.
option leasetime 24h
# GW, DNS:
list dhcp_option "3,192.168.1.129"
list dhcp_option "6,192.168.1.129"
config dhcp publan
option interface publan
option start 10
option limit 126
option leasetime 24h
# GW, DNS:
list dhcp_option "3,192.168.1.1"
list dhcp_option "6,192.168.1.1"
config dnsmasq
option leasefile '/tmp/dhcp.leases'
option resolvfile '/tmp/resolv.conf.auto'
option localise_queries 1
config odhcpd 'odhcpd'
option maindhcp '0'
option leasefile '/tmp/hosts/odhcpd'
option leasetrigger '/usr/sbin/odhcpd-update'
config host
option name 'host.example.com'
option ip '192.168.1.2'
option mac 'aa:bb:cc:dd:ee:ff'
/etc/hosts
(replaceexamplecom
):
127.0.0.1 localhost
192.168.1.1 guardian.example.com
192.168.1.5 www.example.com example.com
Build software and perform installation
- Run
make V=99
. - Install the image you just built onto your router. The instructions here require a computer running Linux, in addition to the Guardian device.
- On the Linux computer:
- Install
dhcp-server
,tftp-server
,minicom
,mtd-utils
, andmtd-utils-ubi
. Configure minicom to emulate an 115,200-bps 8N1 terminal without hardware flow control and without software flow control. - Temporarily disable the host’s firewall (or allow incoming TFTP requests).
- Run the tftp service with
in.tftpd -v -s -p -L /var/lib/tftpboot/
. - Place
openwrt-ath79-mikrotik-mikrotik_routerboard-493g-initramfs-kernel.bin
in/var/lib/tftpboot
. - Set the computer’s IP address to 192.168.1.3 using
ip addr add 192.168.1.3/24 dev enp0s25
. (You might have to do this repeatedly, because the Linux computer’s interface might drop its IP address when the router reboots.) - Configure DHCP as shown below (replace
XX:XX:XX:XX:XX:XX
with your router’s MAC address (likely eth1), which you can discover using the router’s firmware utility), and start the DHCP server withsystemctl start dhcpd
.
- Install
allow booting;
allow bootp;
subnet 192.168.1.0 netmask 255.255.255.0 {
option routers 192.168.1.3;
option subnet-mask 255.255.255.0;
option broadcast-address 192.168.1.255;
}
group {
host routerboard {
hardware ethernet XX:XX:XX:XX:XX:XX;
next-server 192.168.1.3;
fixed-address 192.168.1.2;
filename "openwrt-ath79-mikrotik-mikrotik_routerboard-493g-initramfs-kernel.bin";
}
}
- On the router:
- At boot menu, use
e
to erase the existing OS firmware. - Instruct the boot firmware to boot from the network (select
o
,e
, andx
). In order to boot the router over the network, it might be necessary to reset the Linux computer’s IP address (because the IP address might have been lost after the link momentarily went down). After the router boots, it might be necessary to wait while the router configures its network interfaces and generates its SSH keys; you might also need to deactivate the firewall’s router to permit SSH connections over its WAN interface. - After booting, run
passwd
to set the root password. - The router’s IP address should now be 192.168.1.2. Use
scp
to copyopenwrt-ath79-mikrotik-mikrotik_routerboard-493g-squashfs-sysupgrade.bin
to the router. - Run
sysupgrade -n openwrt-ath79-mikrotik-mikrotik_routerboard-493g-squashfs-sysupgrade.bin
. - Reboot the router, ensuring it boots from its internal flash.
- At boot menu, use
- Finalize the router install:
- Run
passwd
to set the root password. - Create the OpenVPN key material using:
clean-all
build-ca
build-dh
build-key-server example.com
build-key client
- Copy
ca.cert
,dh2048.pem
,example.com.cert
, andexample.com.key
to/etc/openvpn
. - Copy
ca.cert
,dh2048.pem
,client.cert
, andclient.key
to the client’s/etc/openvpn
.
- Configure OpenVPN on each client host.
- Place the client’s certificate, the client’s private key, and the CA certificate in
/etc/openvpn
. - Option 1: Configuration using NetworkManager
- Create a new VPN connection using NetworkManager.
- Under
Advanced
→TLS Authentication
: - Set
Subject Match
to/CN=example.com
. - Select
Verify peer (server) certificate usage signature
and set toServer
.
- Option 2: Direct configuration of OpenVPN
- Copy
/usr/share/doc/openvpn/contrib/pull-resolv-conf/client.up
andclient.down
to/etc/openvpn
. - Set the scripts’ permissions with
chmod +x client.up client.down
. /etc/openvpn/example.conf
(replaceclient.cert
,client.key
, andserver.example.com
):
- Copy
dev tun
proto udp
verb 3
ca /etc/openvpn/ca.cert
cert /etc/openvpn/client.cert
key /etc/openvpn/client.key
dh /etc/openvpn/dh2048.pem
persist-tun
persist-key
client
remote-cert-tls server
remote server.example.com 1194
script-security 2
up /etc/openvpn/client.up
down /etc/openvpn/client.down
4. `ln -s /lib/systemd/system/openvpn@.service /etc/systemd/system/openvpn@example.service`
5. `systemctl start openvpn@example.service`