Difference between revisions of "Classic perimetral firewall example"

From nftables wiki
Jump to navigation Jump to search
(Add page. People ask me about this.)
 
(fix example)
 
Line 17: Line 17:
include "./defines.nft"
include "./defines.nft"


chain global {
        ct state established,related accept
        ct state invalid drop
        ip protocol icmp accept
        ip6 nexthdr icmpv6 accept
        udp dport 53 accept
}


table inet filter {
table inet filter {
        chain global {
                ct state established,related accept
                ct state invalid drop
                ip protocol icmp accept
                ip6 nexthdr icmpv6 accept
                udp dport 53 accept
        }
         include "./inet-filter-sets.nft"
         include "./inet-filter-sets.nft"
         include "./inet-filter-forward.nft"
         include "./inet-filter-forward.nft"

Latest revision as of 12:10, 1 June 2018

This example assumes a classic perimetral firewall, which is connected to 3 networks: internet, DMZ, and workstation LAN.

You could either put your ruleset all in the same file or split it in different text files for better maintenance.

In this example we will use several files:

  • ruleset.nft (core nftables file, the one you load with nft -f)
  • defines.nft (definitions used in the other files)
  • inet-filter-sets.nft (sets and maps definitions)
  • inet filter-forward.nft (the forward chains and rules)
  • inet-filter-local.nft (the local chains and rules)

File ruleset.nft:

flush ruleset

include "./defines.nft"


table inet filter {
        chain global {
                ct state established,related accept
                ct state invalid drop
                ip protocol icmp accept
                ip6 nexthdr icmpv6 accept
                udp dport 53 accept
        }

        include "./inet-filter-sets.nft"
        include "./inet-filter-forward.nft"
        include "./inet-filter-local.nft"
}

File defines.nft:

# interfaces
define nic_inet = bond0
define nic_dmz = bond1
define nic_lan = bond2

# network ranks
define net_ipv4_dmz = 10.0.1.0/24
define net_ipv6_dmz = fe00:1::/64
define net_ipv4_lan = 10.0.2.0/24
define net_ipv6_lan = fe00:2::/64

# some machines
define server1_ipv4 = 10.0.1.2
define server1_ipv6 = fe00:1::2
define workstation1_ipv4 = 10.0.2.2
define workstation1_ipv6 = fe00:2::2

File inet-filter-sets.nft:

set myset_ipv4 {
         type ipv4_addr;
         elements = { $server1_ipv4 , $workstation1_ipv4 }
}

set myset_ipv6 {
         type ipv6_addr;
         elements = { $server1_ipv6 , $workstation1_ipv6 }
}

File inet-filter-forward.nft:

chain dmz_in {
        # your rules for traffic to your dmz servers
        ip saddr @myset_ipv4
        ip6 saddr @myset_ipv6
}

chain dmz_out {
        # your rules for traffic from the dmz to internet
}

chain lan_in {
        # your rules for traffic to your LAN nodes
}

chain lan_out {
        # your rules for traffic from the LAN to the internet
}

chain forward {
        type filter hook forward priority 0; policy drop;
        jump global
        oifname vmap { $nic_dmz : jump dmz_in , $nic_lan : jump lan_in }
        oifname $nic_inet iifname vmap { $nic_dmz : jump dmz_out , $nic_lan : jump lan_out }
}


File inet-filter-local.nft:

chain input {
        type filter hook input priority 0 ; policy drop;
        jump global
        # your rules for traffic to the firewall here
}

chain output {
        type filter hook output priority 0 ; policy drop;
        jump global
        # your rules for traffic originated from the firewall itself here
}

As all of these are plan text files, you can even think of maintaining them with some kind of control version (example here: https://github.com/aborrero/nftables-managed-with-git)