Difference between revisions of "Simple ruleset for a home router"

From nftables wiki
Jump to navigation Jump to search
(add another example with WLAN)
(Pages using deprecated source tags)
 
(3 intermediate revisions by the same user not shown)
Line 1: Line 1:
The following example rulesets have been tested with Linux kernel 4.19 and nftables 1.0.0.
Before you configure your ruleset policy, do not forget to:
Before you configure your ruleset policy, do not forget to:


<source lang="bash">
<syntaxhighlight lang="bash">
echo 1 > /proc/sys/net/ipv4/ip_forward
echo 1 > /proc/sys/net/ipv4/ip_forward
</source>
</syntaxhighlight>


to enable IPv4 forwarding in your router or enable it through /etc/sysctl.conf for persistency
to enable IPv4 forwarding in your router or enable it through /etc/sysctl.conf for persistency
Line 11: Line 13:
This example shows the configuration of an IPv4-only home router using a ppp interface to go out to the Internet.
This example shows the configuration of an IPv4-only home router using a ppp interface to go out to the Internet.


<source lang="bash">
<syntaxhighlight lang="bash">
flush ruleset
flush ruleset


Line 71: Line 73:
     }
     }
}
}
</source>
</syntaxhighlight>


= Router with LAN and WLAN segments using VLAN interface to the Internet =
= Router with LAN and WLAN segments using VLAN interface to the Internet =


<source lang="bash">
A similar example with a Wireless LAN network segment and using a VLAN device to go out to the Internet
 
<syntaxhighlight lang="bash">
flush ruleset
flush ruleset


Line 81: Line 85:
define DEV_WLAN = wlan0
define DEV_WLAN = wlan0
define DEV_WORLD = eth0.20
define DEV_WORLD = eth0.20
# LAN is 192.168.2.0/24 and WLAN is 192.168.3.0/24, hence 192.168.2.0/23 contains both network segments
define NET_PRIVATE = 192.168.2.0/23
define NET_PRIVATE = 192.168.2.0/23


Line 95: Line 100:
     }
     }


     chain inbound_private {
     chain inbound_private_lan {
         # accepting ping (icmp-echo-request) for diagnostic purposes.
         # accepting ping (icmp-echo-request) for diagnostic purposes.
         icmp type echo-request limit rate 5/second accept
         icmp type echo-request limit rate 5/second accept


         # allow DHCP, DNS and SSH from the private network
         # allow DHCP, DNS and SSH from the wired private network
         ip protocol . th dport vmap { tcp . 22 : accept, udp . 53 : accept, tcp . 53 : accept, udp . 67 : accept}
         ip protocol . th dport vmap { tcp . 22 : accept, udp . 53 : accept, tcp . 53 : accept, udp . 67 : accept}
    }
    chain inbound_private_wlan {
        # accepting ping (icmp-echo-request) for diagnostic purposes.
        icmp type echo-request limit rate 5/second accept
        # allow DHCP and DNS from the private wireless network
        ip protocol . th dport vmap { udp . 53 : accept, tcp . 53 : accept, udp . 67 : accept}
     }
     }


Line 110: Line 123:


         # allow loopback traffic, anything else jump to chain for further evaluation
         # allow loopback traffic, anything else jump to chain for further evaluation
         iifname vmap { lo : accept, $DEV_WORLD : jump inbound_world, $DEV_LAN : jump inbound_private, $DEV_WLAN : jump inbound_private }
         iifname vmap { lo : accept, $DEV_WORLD : jump inbound_world, $DEV_LAN : jump inbound_private_lan, $DEV_WLAN : jump inbound_private_wlan }


         # the rest is dropped by the above policy
         # the rest is dropped by the above policy
Line 131: Line 144:


         # masquerade private IP addresses
         # masquerade private IP addresses
         ip saddr $NET_PRIVATE counter oifname $DEV_WORLD counter masquerade
         ip saddr $NET_PRIVATE meta oifname $DEV_WORLD counter masquerade
     }
     }
}
}
</source>
</syntaxhighlight>

Latest revision as of 00:53, 9 December 2021

The following example rulesets have been tested with Linux kernel 4.19 and nftables 1.0.0.

Before you configure your ruleset policy, do not forget to:

echo 1 > /proc/sys/net/ipv4/ip_forward

to enable IPv4 forwarding in your router or enable it through /etc/sysctl.conf for persistency

Simple router using ppp interface

This example shows the configuration of an IPv4-only home router using a ppp interface to go out to the Internet.

flush ruleset

define DEV_PRIVATE = eth1
define DEV_WORLD = ppp0
define NET_PRIVATE = 192.168.0.0/16

table ip global {

    chain inbound_world {
        # accepting ping (icmp-echo-request) for diagnostic purposes.
        # However, it also lets probes discover this host is alive.
        # This sample accepts them within a certain rate limit:
        #
        # icmp type echo-request limit rate 5/second accept

        # allow SSH connections from some well-known internet host
        ip saddr 81.209.165.42 tcp dport ssh accept
    }

    chain inbound_private {
        # accepting ping (icmp-echo-request) for diagnostic purposes.
        icmp type echo-request limit rate 5/second accept

        # allow DHCP, DNS and SSH from the private network
        ip protocol . th dport vmap { tcp . 22 : accept, udp . 53 : accept, tcp . 53 : accept, udp . 67 : accept}
    }

    chain inbound {
        type filter hook input priority 0; policy drop;

        # Allow traffic from established and related packets, drop invalid
        ct state vmap { established : accept, related : accept, invalid : drop }

        # allow loopback traffic, anything else jump to chain for further evaluation
        iifname vmap { lo : accept, $DEV_WORLD : jump inbound_world, $DEV_PRIVATE : jump inbound_private }

        # the rest is dropped by the above policy
    }

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

        # Allow traffic from established and related packets, drop invalid
        ct state vmap { established : accept, related : accept, invalid : drop }

        # connections from the internal net to the internet or to other
        # internal nets are allowed
        iifname $DEV_PRIVATE accept

        # the rest is dropped by the above policy
    }

    chain postrouting {
        type nat hook postrouting priority 100; policy accept;

        # masquerade private IP addresses
        ip saddr $NET_PRIVATE oifname $DEV_WORLD masquerade
    }
}

Router with LAN and WLAN segments using VLAN interface to the Internet

A similar example with a Wireless LAN network segment and using a VLAN device to go out to the Internet

flush ruleset

define DEV_LAN = eth1
define DEV_WLAN = wlan0
define DEV_WORLD = eth0.20
# LAN is 192.168.2.0/24 and WLAN is 192.168.3.0/24, hence 192.168.2.0/23 contains both network segments
define NET_PRIVATE = 192.168.2.0/23

table ip global {
    chain inbound_world {
        # accepting ping (icmp-echo-request) for diagnostic purposes.
        # However, it also lets probes discover this host is alive.
        # This sample accepts them within a certain rate limit:
        #
        # icmp type echo-request limit rate 5/second accept

        # allow SSH connections from some well-known internet host
        ip saddr 81.209.165.42 tcp dport 22 accept
    }

    chain inbound_private_lan {
        # accepting ping (icmp-echo-request) for diagnostic purposes.
        icmp type echo-request limit rate 5/second accept

        # allow DHCP, DNS and SSH from the wired private network
        ip protocol . th dport vmap { tcp . 22 : accept, udp . 53 : accept, tcp . 53 : accept, udp . 67 : accept}
    }

    chain inbound_private_wlan {
        # accepting ping (icmp-echo-request) for diagnostic purposes.
        icmp type echo-request limit rate 5/second accept

        # allow DHCP and DNS from the private wireless network
        ip protocol . th dport vmap { udp . 53 : accept, tcp . 53 : accept, udp . 67 : accept}
    }

    chain inbound {
        type filter hook input priority 0; policy drop;

        # Allow traffic from established and related packets, drop invalid
        ct state vmap { established : accept, related : accept, invalid : drop }

        # allow loopback traffic, anything else jump to chain for further evaluation
        iifname vmap { lo : accept, $DEV_WORLD : jump inbound_world, $DEV_LAN : jump inbound_private_lan, $DEV_WLAN : jump inbound_private_wlan }

        # the rest is dropped by the above policy
    }

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

        # Allow traffic from established and related packets, drop invalid
        ct state vmap { established : accept, related : accept, invalid : drop }

        # connections from the internal net to the internet: wlan to lan and lan to wlan not allowed
        meta iifname . meta oifname { $DEV_LAN . $DEV_WORLD, $DEV_WLAN . $DEV_WORLD, $DEV_WORLD . $DEV_LAN, $DEV_WORLD . $DEV_WLAN } accept

        # the rest is dropped by the above policy
    }

    chain postrouting {
        type nat hook postrouting priority 100; policy accept;

        # masquerade private IP addresses
        ip saddr $NET_PRIVATE meta oifname $DEV_WORLD counter masquerade
    }
}