Skip to content

Instantly share code, notes, and snippets.

@ArcherN9
Last active September 22, 2021 06:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ArcherN9/8838222897da5a2893f7162efe0e91ae to your computer and use it in GitHub Desktop.
Save ArcherN9/8838222897da5a2893f7162efe0e91ae to your computer and use it in GitHub Desktop.
An NFTables rule set with ipv6 and ipv4 to support Wireguard NAT
#!/sbin/nft -f
# Flushing means to empty; the flush command here empties the entire
# nftable ruleset. Since this is the primary file that is loaded onto the
# chronology of nf configurations, it is safe to flush the entire rulset first.
flush ruleset
# I tried segregating my configuration into multiple tables for comprehension
# But was unable to. If you have a better understanding of nftables and
# comprehend how this configuration can be broken apart into multiple tables,
# drop me an email!
table inet pinhole_filter {
chain prerouting {
type nat hook prerouting priority 0;
# iifname "wg0" oifname "wlan0"
iifname "wg0" dnat ip to 0.0.0.0
}
# This is the default base chain for input | all incoming traffic
# Entersthis
chain default_input {
# Blanket policy to drop all incoming packets unless specified below
type filter hook input priority 0; policy drop;
# If a connection was requested by Pi itself, let it pass
ct state { established, related } counter accept comment "Accept connections made by the Pi itself"
# Perhaps an overkill but if the protocol is an ICMP request, route it to a non base chain
meta l4proto icmp goto icmp_filter
# meta protocol ip6 icmpv6 type { nd-neighbor-solicit, nd-router-advert, nd-neighbor-advert } goto icmp_filter
ip6 nexthdr icmpv6 goto icmp_filter
# Accept everything originating from loopback
iifname "lo" accept
# We segregate packets based on their origin. If a packet is being received from the wlan0 interface,
# Route it to the wlan0_filter chain for further processing
iifname "wlan0" jump wlan0_filter
# Similarly, if the packet originated from wg0, we process it in this chain
iifname "wg0" jump wg0_filter
}
chain postrouting {
type nat hook postrouting priority 100;
oifname "wlan0" masquerade
log flags all
}
# allow all packets sent by Pi itself to the outside world
chain output {
type filter hook output priority 0; policy accept;
}
# The ICMP chain. This is a non-base chain that gets executed on the protocol
# being matched.
chain icmp_filter {
# Accept ICMP requests on ipv4
meta l4proto icmp iifname { "wlan0", "wg0" } ip saddr { 192.168.1.0/24, 10.6.0.0/29 } counter accept comment "icmpv4 : LAN & Wireguard"
# Accept ICMPv6 requests on ipv6
meta l4proto icmpv6 iifname { "wlan0", "wg0" } ip6 saddr { fe80::/112, fd00:43:43::/64 } counter accept comment "icmpv6: lo & Wireguard"
# accept neighbour discovery otherwise IPv6 connectivity breaks
# Refer: https://www.computernetworkingnotes.com/networking-tutorials/ipv6-neighbor-discovery-protocol-explained.html
icmpv6 type { nd-neighbor-solicit, nd-router-advert, nd-neighbor-advert } accept
}
# All queries received on the wlan0 interface that have not already been
# catered to are received and processed here.
chain wlan0_filter {
# Accept SSH requests from wlan0
tcp dport 22 counter accept comment "Accept: SSH"
# Accept Wireguard connection requests
udp dport 51820 counter accept comment "Accept connection requests: Wireguard"
# Plex has a bad habit of flooding the broadcast address. Block packets originating
# From plex
udp dport { 32414, 32412 } drop
}
# All queries received on the wg0 interface that have not already been
# catered to are received and processed here.
chain wg0_filter {
# Accept SSH requests
tcp dport 22 counter accept comment "Accept: SSH"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment