What's new

DIY routers and APs

  • SNBForums Code of Conduct

    SNBForums is a community for everyone, no matter what their level of experience.

    Please be tolerant and patient of others, especially newcomers. We are all here to share and learn!

    The rules are simple: Be patient, be nice, be helpful or be gone!

Not even sure if that is possible under OpenWRT as there does not seem to be any build essential package.

Building packages on OpenWRT is quite a bit different perhaps than what you expect with a typical desktop/server distro.

I would encourage you to review the OpenWRT developer docs, they do explain in good detail on how to add/modify packages, along with creating a custom build for your needs.
 
After taking a bit longer than expected, thanks to an illness that literally laid me out for a couple of weeks, I finally finished this little project.

Here is my contribution with my adaptation of JackYaz's SpdMerlin for OpenWRT. I called in SpdOpenWRT.sh.

Thanks to @Jack Yaz for the inspiration. @dave14305

https://github.com/Bandsaw12/SpdOpenWRT
 
Today I switched my Raspberry Pi 4B from OpenWrt to plain Raspberry Pi OS Lite as a router.

Details:
  • Debian Bullseye
  • Linux kernel 5.10.63
  • systemd-networkd
  • dnsmasq 2.85
  • nftables firewall
  • IPv6 enabled (managed by systemd)
  • sqm-scripts for easy CAKE mgmt
  • TP-Link UE300 USB Adapter for WAN (rtl8153)
I have my OpenWrt 21.02.1 SD card standing by in case I find any significant issues, or just lose my nerve. But a couple of months on OpenWrt pretty much prepared me for this switchover, learning the ins and outs of IPv6 in more detail. ShieldsUp says I have no open ports and test-ipv6.com says I'm 10/10.

Also a shoutout to @john9527 because during my Pi rebuild, I recommissioned my old AC68U running John's fork as my main router and it was like being reunited with an old friend. I had forgotten how much more flexible IPv6 was on the fork (e.g. I could specify a prefix hint to get a /60 from Comcast). Lean and mean.
 
Today I switched my Raspberry Pi 4B from OpenWrt to plain Raspberry Pi OS Lite as a router.

Details:
  • Debian Bullseye
  • Linux kernel 5.10.63
  • systemd-networkd
  • dnsmasq 2.85
  • nftables firewall
  • IPv6 enabled (managed by systemd)
  • sqm-scripts for easy CAKE mgmt
  • TP-Link UE300 USB Adapter for WAN (rtl8153)
I have my OpenWrt 21.02.1 SD card standing by in case I find any significant issues, or just lose my nerve. But a couple of months on OpenWrt pretty much prepared me for this switchover, learning the ins and outs of IPv6 in more detail. ShieldsUp says I have no open ports and test-ipv6.com says I'm 10/10.

Also a shoutout to @john9527 because during my Pi rebuild, I recommissioned my old AC68U running John's fork as my main router and it was like being reunited with an old friend. I had forgotten how much more flexible IPv6 was on the fork (e.g. I could specify a prefix hint to get a /60 from Comcast). Lean and mean.

Very nice @dave14305

I have a Ubuntu 21.04 RasPi 4B built ready to go as my new router, but I don't know enough about iptables to know if my firewall is adequate, so I have not put it into service. I have looked into just imitating the Asus AXC86U firewall, but still gun shy as to rather I have missed something.

Does nftables have prebuilt router firewalls or any good references you can suggest for putting together a good nftables router/gateway firewall?
 
Does nftables have prebuilt router firewalls or any good references you can suggest for putting together a good nftables router/gateway firewall?
I took my nftables config from examples posted by Dan Lakeland over at OpenWrt forums.


A lot of the QoS parts are optional, but the basic filter and masq tables from the linked Github repo in the thread gives a good starting point.

Code:
/etc/nftables.conf
## this assumes eth0 is LAN and eth1 is WAN, modify as needed

flush ruleset

define wan = eth1
define lan = eth0

table inet filter {
    chain input {
        type filter hook input priority 0; policy drop;

        # established/related connections
        ct state established,related accept

        # loopback interface
        iifname lo accept

        ## icmpv6 is a critical part of the protocol, we just
        ## accept everything, you can lookin to making this
        ## more restrictive but be careful
        ip6 nexthdr icmpv6 accept

        # we are more restrictive for ipv4 icmp
        ip protocol icmp icmp type { destination-unreachable, router-solicitation, router-advertisement, time-exceeded, parameter-problem } accept

        ip protocol igmp accept

        ip protocol icmp meta iifname $lan accept

        ## ntp protocol accept from LAN
        udp dport ntp iifname $lan accept

        ## DHCP accept
        iifname $lan ip protocol udp udp sport bootpc udp dport bootps log prefix "FIREWALL ACCEPT DHCP: " accept

        ## DHCPv6 accept from LAN
        iifname $lan udp sport dhcpv6-client udp dport dhcpv6-server accept

        ## allow dhcpv6 from router to ISP
        iifname $wan udp sport dhcpv6-server udp dport dhcpv6-client accept

        # SSH (port 22), limited to 10 connections per minute,
        # you might prefer to not allow this from WAN for
        # OpenWrt, in which case you should also add an
        # iifname eth0 filter in the front so we're only
        # allowing from LAN
        
        iifname $lan ct state new tcp dport ssh meter ssh-meter4 {ip saddr limit rate 10/minute burst 15 packets} accept
        #ct state new ip6 nexthdr tcp tcp dport ssh meter ssh-meter6 {ip6 saddr limit rate 10/minute burst 15 packets} accept

        ## allow access to LUCI from LAN
        #iifname $lan tcp dport {http,https} accept

        ## DNS for main LAN, we limit the rates allowed from each LAN host to reduce chance of denial of service
        iifname $lan udp dport domain meter dommeter4 { ip saddr limit rate 240/minute burst 240 packets} accept
        iifname $lan udp dport domain meter dommeter6 { ip6 saddr limit rate 240/minute burst 240 packets} accept

        iifname $lan tcp dport domain meter dommeter4tcp { ip saddr limit rate 240/minute burst 240 packets} accept
        iifname $lan tcp dport domain meter dommeter6tcp { ip6 saddr limit rate 240/minute burst 240 packets} accept

        ## allow remote syslog input? you might want this, or remove this
        # iifname $lan udp dport 514 accept

        #counter log prefix "FIREWALL INPUT DROP: " drop
        counter drop
    }

    chain forward {
        type filter hook forward priority 0; policy drop;

        ct state established,related accept

        iifname lo accept
        iifname $lan oifname $wan accept ## allow LAN to forward to WAN

        #counter log prefix "FIREWALL FAIL FORWARDING: " drop
        counter drop
    }
}

## masquerading for ipv4 output on WAN
table ip masq {
    chain masqout {
        type nat hook postrouting priority 0; policy accept;
        oifname $wan masquerade

    }

    ## this empty table is required to make the kernel do the unmasquerading
    chain masqin {
        type nat hook prerouting priority 0; policy accept;

    }

}
 
@dave14305
I'm curious how your Pi Router setup has been operating?
I'm a long time Pi user (6 whole months), and have been amazed what the Pi 4B is capable of accomplishing.
 
@Jeffrey Young

ufw wrapper
UFW is more complicated than it needs to be when it comes to structuring rules.

Much easier to work with a notepad program and assign iptables entries for use.

/etc/iptables/rules.v4

Code:
# Generated by iptables-save v1.8.7 on Sun Jan 23 20:51:32 2022
*mangle
:PREROUTING ACCEPT [115:112557]
:INPUT ACCEPT [110:111760]
:FORWARD ACCEPT [5:797]
:OUTPUT ACCEPT [103:437638]
:POSTROUTING ACCEPT [107:438251]
COMMIT
# Completed on Sun Jan 23 20:51:32 2022
# Generated by iptables-save v1.8.7 on Sun Jan 23 20:51:32 2022
*security
:INPUT ACCEPT [95:94808]
:FORWARD ACCEPT [5:797]
:OUTPUT ACCEPT [102:437454]
COMMIT
# Completed on Sun Jan 23 20:51:32 2022
# Generated by iptables-save v1.8.7 on Sun Jan 23 20:51:32 2022
*raw
:PREROUTING ACCEPT [115:112557]
:OUTPUT ACCEPT [103:437638]
:FORWARD - [0:0]
COMMIT
# Completed on Sun Jan 23 20:51:32 2022
# Generated by iptables-save v1.8.7 on Sun Jan 23 20:51:32 2022
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
:PERMIT-FWD - [0:0]
:PERMIT-IN - [0:0]
:PERMIT-OUT - [0:0]
-A INPUT -j PERMIT-IN
-A FORWARD -j PERMIT-FWD
-A OUTPUT -j PERMIT-OUT
-A PERMIT-FWD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A PERMIT-FWD -m conntrack --ctstate NEW -j ACCEPT
-A PERMIT-FWD -j DROP
-A PERMIT-IN -i lo -j ACCEPT
-A PERMIT-IN -i br0 -j ACCEPT
-A PERMIT-IN -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A PERMIT-IN -j DROP
-A PERMIT-OUT -o lo -j ACCEPT
-A PERMIT-OUT -o br0 -j ACCEPT
-A PERMIT-OUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A PERMIT-OUT -m conntrack --ctstate NEW -j ACCEPT
-A PERMIT-OUT -j DROP
COMMIT
# Completed on Sun Jan 23 20:51:32 2022
# Generated by iptables-save v1.8.7 on Sun Jan 23 20:51:32 2022
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -o nordlynx -j MASQUERADE
-A POSTROUTING -o bo0 -j MASQUERADE
COMMIT
# Completed on Sun Jan 23 20:51:32 2022

This keeps all traffic out that didn't originate from the LAN as it should be. If you want to poke holes it's easy to add the rules or something like knockd to allow remote access / open ports for apps / monitoring.
 
Thanks. I got a good grasp of iptables, it is the lack of confidence in what I build would stand salt against a determined block
 
@dave14305
I'm curious how your Pi Router setup has been operating?
I'm a long time Pi user (6 whole months), and have been amazed what the Pi 4B is capable of accomplishing.
It operates very well. I’m my own worst enemy when I try to tinker with it on the latest snapshots. My biggest “complaint” is the lack of a stable dnsmasq with nftables set support. That’s key to my preferred QoS solution. Right now, I’m cruising along with the stable 21.02.1 release and no complaints.

It was so stable that I got bored and put my AC86U back as my primary router for a couple days and eventually got frustrated by the old limitations of the aged kernel and Broadcom lock-in. In short, I’m fickle.
 
A vast majority of members here do not understand the intrinsic relationships when building table chains...
Well, then we break it down.

INPUT = from the outside
FORWARD = from LAN to WAN
OUTPUT = egress to internet

Rule # BLOCK everything and permit as needed.
Rule # 2 permit the LO & LAN
Rule # 3 permit only local traffic origination
Rule # 4 block everything else
 
Is there a nftables translation of this? Or a preferred DIY Linux FW explainer (for idiots pref.)..

It's pretty simple and straight forward compared to other methods. Keeping the number of rules and the order in an efficient structure keeps thing running fast.

If you're hosting a server for something you can permit multiple ports in a single line or make a container/list to reference to simplify the rule. If you do the list option you don't have to remove / replace the rule to make changes and just add the additional port / IP to the list and it's immediate.

Since I edit them in notepad++ I have a script of commands that I run to strip the rules and reapply them from the text file. Doing it all from CLI and verifying things can be a bit tedious w/ multiple windows open for verification.

For monitoring from a terminal w/ the watch command you can get real time processing / packet counts
1643744079610.png


So, I make 3 "groups" of permit statements and then put the rules under those. Each rule gets processed from the top down. Permitting local things first to reduce lag from processing such as the loopback / LAN. For statistical reasons I break out things a bit more than you need to. I want to see the traffic patterns but not to the point of each granular packet.

Even though it's implied that if it doesn't match a rule by making the policies "DROP" it's nice to see a count by appending a DROP rule to see the hit count of what doesn't match. Seeing the DROP count can clue you into whether you're being attacked or not. It might also indicate if there's something on the inside trying to open access to a RCE / call home in a non-permitted fashion.

Few people realize though there are tons of bots scanning the internet for various reasons and if you don't lock things down properly you're leaking data to them.

1643744563018.png

I use Netwatch to see what's hitting my WAN and periodically check to see who's the most offensive. By blocking everything that didn't originate from the LAN and VPN all traffic it makes it easy to spot the number of packets of repeat hits like these.

1643744808449.png

The a whois will give you an idea of who is behind the IP
inetnum: 104.250.32.0 - 104.250.63.255
netname: KSYUNGLOBAL-HK
descr: Kingsoft Cloud Corporation Limited
country: HK
org: ORG-KCCL1-AP
admin-c: KCCL1-AP
tech-c: KCCL1-AP
abuse-c: AK1146-AP
status: ALLOCATED PORTABLE
remarks: --------------------------------------------------------
remarks: To report network abuse, please contact mnt-irt
remarks: For troubleshooting, please contact tech-c and admin-c
remarks: Report invalid contact via www.apnic.net/invalidcontact
remarks: --------------------------------------------------------
mnt-by: APNIC-HM
mnt-lower: MAINT-KSYUNGLOBAL-HK
mnt-routes: MAINT-KSYUNGLOBAL-HK
mnt-irt: IRT-KSYUNGLOBAL-HK
last-modified: 2020-06-30T08:55:59Z
source: APNIC

There are websites though that can give you a reputation / report for that IP

For me it's a lot easier to deal with a short text file vs XML / JSON
 
My latest experimental router setup is:

OS: Raspberry Pi OS 64-bit Lite (Debian 11, Linux 5.10.92-v8+)
Firewall: nftables
DNS/DHCP: Pi-Hole serving DNS and DHCPv4 on the router, Quad9 upstream
IPv6 RA: systemd-networkd
QoS: sqm-scripts v1.5.1, using CAKE (piece_of_cake.qos with besteffort only)
Wireless: RT-AC86U running stock 386_45956 in AP mode

Deciding to replace plain dnsmasq with Pi-Hole is the "new" aspect to this experiment. I'm managing all my static DHCP reservations within the Pi-Hole Admin interface.

So far so good. It's been about 90 minutes...;)
 
Makes me wish I had bought a couple extra Pi 4's before the onset of Covid. Both of mine are now doing other work (NAS and NextCloud server). Now, besides being hard to find, they are stupid expensive (at least here in Canada).

Great work @dave14305
 

Support SNBForums w/ Amazon

If you'd like to support SNBForums, just use this link and buy anything on Amazon. Thanks!

Sign Up For SNBForums Daily Digest

Get an update of what's new every day delivered to your mailbox. Sign up here!
Top