-
Notifications
You must be signed in to change notification settings - Fork 0
nftables
The nftables configuration file ought to be stored in /etc/nftables.conf
Here is a configuration file that you can use as-is, or that you can adapt to your needs :
#!/usr/sbin/nft -f
flush ruleset
include "/etc/nftables.d/*.nft*"
define NIC_NAME = "eth0"
define LOCAL_IPV4_SUBNETS = { 10.0.0.0/8, 172.16.16.0/12, 192.168.0.0/16 }
define LOCAL_IPV6_SUBNETS = { fe80::/10, 2efe:abba:1dc:6a40::/64}
# ----- NetDev -----
table netdev filter {
set IPV4_BANNED_ADD { type ipv4_addr
flags interval
auto-merge
elements = { $IPV4_BANNED_ADDRESSES_LIST }
}
set IPV6_BANNED_ADD { type ipv6_addr
flags interval
auto-merge
elements = { $IPV6_BANNED_ADDRESSES_LIST }
}
chain input {
type filter hook ingress device $NIC_NAME priority -200; policy accept;
ip saddr @IPV4_BANNED_ADD counter log prefix "Banned IPv4 : " drop
ip6 saddr @IPV6_BANNED_ADD counter log prefix "Banned IPv6 : " drop
}
}
# ----- IPv4 -----
table ip filter {
set ALLOWED_IPV4_COUNTRIES_LIST {
type ipv4_addr
flags interval
auto-merge
elements = { $ipv4_FR }
}
chain input {
type filter hook input priority 0; policy drop;
ct state invalid counter drop comment "early drop of invalid packets"
ct state {established, related} counter accept comment "accept all connections related to connections made by us"
iif lo accept comment "accept loopback"
iif != lo ip daddr 127.0.0.1/8 counter drop comment "drop connections to loopback not coming from loopback"
ip protocol icmp counter accept comment "accept all ICMP types"
# Allow access to defined services from Local Subnets
tcp dport {22, 80, 443} ip saddr $LOCAL_IPV4_SUBNETS counter accept comment "accepted SSH packets from LAN : "
# Allow access to defined services from Allowed Countries
tcp dport {80, 443} ip saddr @ALLOWED_IPV4_COUNTRIES_LIST counter accept comment "Allow access to web server from specified countries"
counter comment "count dropped packets"
}
chain forward {
type filter hook forward priority 0; policy drop;
counter comment "count dropped packets"
}
# If you're not counting packets, this chain can be omitted.
chain output {
type filter hook output priority 0; policy accept;
counter comment "count accepted output packets"
}
}
# ----- IPv6 -----
table ip6 filter {
set ALLOWED_IPV6_COUNTRIES_LIST {
type ipv6_addr
flags interval
auto-merge
elements = { $ipv6_FR }
}
chain input {
type filter hook input priority 0; policy drop;
ct state invalid counter drop comment "early drop of invalid packets"
ct state {established, related} counter accept comment "accept all connections related to connections made by us"
iif lo accept comment "accept loopback"
iif != lo ip6 daddr ::1/128 counter drop comment "drop connections to loopback not coming from loopback"
# Allow some icmpv6 to make IPv6 work (see RFC 4890). This configuration is for an "end host firewall", protecting a single device.
# Allow basic IPv6 functionality.
ip6 nexthdr icmpv6 icmpv6 type {destination-unreachable, packet-too-big, time-exceeded, parameter-problem, echo-request, echo-reply} accept;
# Allow auto configuration support.
ip6 nexthdr icmpv6 icmpv6 type {nd-neighbor-solicit, nd-neighbor-advert, nd-router-advert, nd-router-solicit} ip6 hoplimit 255 accept;
# Allow multicast listener discovery on link-local addresses.
ip6 nexthdr icmpv6 icmpv6 type {mld-listener-query, mld-listener-report, mld-listener-reduction} ip6 saddr fe80::/10 accept;
# Allow multicast router discovery messages on link-local addresses (hop limit 1).
ip6 nexthdr icmpv6 icmpv6 type {nd-router-advert, nd-router-solicit} ip6 hoplimit 1 ip6 saddr fe80::/10 accept;
# Allow access to defined services from Local Subnets
tcp dport {22, 80, 443} ip6 saddr $LOCAL_IPV6_SUBNETS counter accept comment "accepted SSH packets from LAN : "
# Allow access to defined services from Allowed Countries
tcp dport {80, 443} ip6 saddr @ALLOWED_IPV6_COUNTRIES_LIST counter accept comment "Allow access to web server from specified countries"
counter comment "count dropped packets"
}
chain forward {
type filter hook forward priority 0; policy drop;
counter comment "count dropped packets"
}
# If you're not counting packets, this chain can be omitted.
chain output {
type filter hook output priority 0; policy accept;
counter comment "count accepted packets"
}
}
As explain in the netfilter wiki page
In the configuration file the following line tells nftables to read and parses all the files in the /etc/nftables.d/ directory
include "/etc/nftables.d/*.nft*"
Obviously, the script purpose is to create all the files needed to be integrated with the configuration of nftables.
- The name format of the generated files are described as below :
- <ISO Country code>.nft4 : File that contains the Public IPv4 assigned IP addresses, (For example the file that contains the list of Monaco IPv4 affected addresses is called MC.nft4)
- <ISO Country code>.nft6 : File that contains the Public IPv6 assigned IP addresses, (For example the file that contains the list of Spain IPv6 affected addresses is called ES.nft6)
- The structure of the file is as below. This functionnality is described in the including files section of the nftables wiki. The files themselves are structured as below
-
For IPv4 subnets
define ipv4_<ISO Country code> = { <IPv4_Subnet01>, <IPv4_Subnet02>, ... }
-
For IPv6 subnets
define ipv6_<ISO Country code> = { <IPv6_Subnet01>, <IPv6_Subnet02>, ... }
As you noticed it, the generated files are defining variables that you can use it your own sets
If you want to prevent access to the server. You will have to block the flow as earlier as you can. Thus I choose to use the netdev table in order to do that. It avoids then to be analyzed by the kernel. Furthermore if you want to allow a whole country and block just a subnet or a specific IP address, you can then do it. From my point of view this is the best way to do, to offer the most flexible approach. But if you have any other idea on that, please share.
In the provided archive it exists 2 files that are used to define variables that can be used by nftables.
- /etc/nftables.d/banned_ipv4.nft4 (List of IPv4 subnets or IPv4 addresses that we want to block)
- /etc/nftables.d/banned_ipv6.nft6 (List of IPv6 subnets or IPv6 addresses that we want to block)
As an example, let's define a set for Australians IPv4 addresses, that we will allow.
-
Definition of the set
set IPV4_AUSTRALIANS_ADDRESSES_LIST { type ipv4_addr flags interval auto-merge elements = { $ipv4_AU } } -
Now let's allow access to our webserver from Australia.
chain input { type filter hook input priority 0; policy drop; ct state invalid counter drop comment "early drop of invalid packets" ct state {established, related} counter accept comment "accept all connections related to connections made by us" # Allow access to the web server from Australia tcp dport {80, 443} ip saddr @IPV4_AUSTRALIANS_ADDRESSES_LIST counter accept counter comment "count dropped packets" } -
And now as you know how to use it into your nftables.conf file, feel free to use those sets to drop, allow, reject flows from any set of subnets that you want.
nft list tables
nft list table netdev filter
nft list table ip filter
nft list table ip6 filter
nft list set netdev filter IPV4_BANNED_ADD
nft list set netdev filter IPV6_BANNED_ADD
nft list set ip6 filter ALLOWED_IPV6_COUNTRIES_LIST
nft list set ip filter ALLOWED_IPV4_COUNTRIES_LIST