Does nftables allow port 22 or other ports by default?

I installed nftables on a new Debian 12 (on AWS EC2). I am connected to the instance (the external EC2 IP) over port 22/tcp. I mention EC2 because maybe they do weird tricks. I then installed nftables with:

    sudo apt install nftables
    sudo systemctl enable nftables
    sudo systemctl start nftables

At this point, I have an empty configuration:

    flush ruleset

    table inet filter {
      chain input {
            type filter hook input priority filter;
      chain forward {
            type filter hook forward priority filter;
      chain output {
            type filter hook output priority filter;

My question is simple: I read, and would expect, that in the absence of any rule allowing any packet, my own session should be blocked, and I should be good to reboot. Why is this quite obviously not the case, and/or what is allowing my session?

I noticed that it is only if I explicitly block the flow that it indeed gets blocked.

Asked By: CeSinge


By default nftables does not create any chains meaning every packet is accepted and allowed.

You have created three base chains input forward and output
The default policy if not specified for these is accept which is the same as not having any chains.

To block any packets by default you need to set default action policy to be drop like this for ex:

# Sees incoming packets that are addressed to and have now been routed to the local system and processes running there
add chain filter input {
    type filter hook input priority filter; policy drop;

# Sees packets that originated from processes in the local machine
add chain filter output {
    type filter hook output priority filter; policy drop;

And then explicitly add rules to those chains to allow specific traffic.

  • For more info on creating chains see here.
  • You should find nftables wiki to be most useful to develop firewall.
Answered By: metablaster

in the absence of any rule allowing any packed, my own session should be blocked

Your ruleset allows everything by default.

In order to actually block all the connections, you need to add policy drop; after each respective type filter ... line. Semicolons are optional if you put each rule on its own line.

Such a compact ruleset is really ill-advised. At the very least you need to allow loopback connections ’cause otherwise many programs will fail to work in mysterious ways:

For input, iif lo accept and for output oif lo accept.

And allowing established connections for all the chains is necessary: ct state established,related accept – this rule is the same for every chain.

Answered By: Artem S. Tashkinov
Categories: Answers Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.