Suppose I am logged into a server via ssh. While in the session, I change the firewall config to block all traffic.

When I tried this previously with FreeBSD and pf, the current connection was broken. When I try it now, the current connection remains active but ping (and new connections) doesn't work. I am not sure if there is something else which I am missing.

What is the expected behavior - should this break my current session?

  • 5
    if you block all traffic, then yes, it should block your existing connection too. (It should hang, not break, at least not immediately.) But e.g. with iptables on Linux, it's rather common to accept established connections early in the ruleset, and only do detailed checking on new connections.
    – ilkkachu
    Aug 7 at 18:38
  • 1
    pf looks to have something similar, by default, the man page says: "By default pf(4) filters packets statefully; the first time a packet matches a pass rule, a state entry is created; for subsequent packets the filter checks whether the packet matches any state. If it does, the packet is passed without evaluation of any rules."
    – ilkkachu
    Aug 7 at 18:39
  • Ah, the state does the trick. Thanks!
    – dakini
    Aug 7 at 18:40
  • 1
    or clear all or some of the states with pfctl -F states or pfctl -k, I guess. (based on the pfctl man page and the docs). I don't really know about pf so I'm not sure I dare post this as an answer...
    – ilkkachu
    Aug 7 at 18:51

1 Answer 1


"Should changing firewall settings to block all interrupt ongoing ssh session"

The answer is, maybe. It depends on the precise rules, where the block all appears, and whether existing SSH connections are managed under keep state (or modulate state). set optimization is also relevant; a firewall set to aggressively prune state could drop a session at the same time one is fiddling around with firewall rule changes. There are other relevant settings that may influence whether state is maintained, e.g. set state-policy might be set to if-bound, and the SSH packets for some routing reason start showing up on another interface.

In pf the last matching rule takes effect, unless quick is added to a rule. This is opposite of other firewall rules systems, notably iptables on Linux. Thus the exact ordering of rules is important, as is whether quick is used.

If state is enabled, the existing connections should be preserved through rule changes (unless set optimization kills them by timeout).

An example: block all will not apply as the last matching rule wins; also, state is maintained for existing SSH connections:

block all
pass out on $ext_if proto tcp all modulate state
pass in on  $ext_if proto tcp from any to any port ssh modulate state

The is next ruleset is a secure firewall, in that everything is quickly blocked, though existing SSH connections should still be maintained until the session times out:

block quick all
pass out proto tcp all modulate state
pass in proto tcp from any to any port ssh modulate state

Another way to write the above would be to put block all as the final rule (unless there are other quick rules), as by default the last matching rule wins.

(There is also a complication of how new states are matched; you can be less restrictive with flags any so that state is created for any portion of a TCP connection, not just the default of only new connections via the default flags S/SA. And other such complications from e.g. asymmetric routing.)

It is also usually a very good idea to have some sort of rollback or recovery option when making firewall rule changes, so that you do not lock yourself out of the system:

# pfctl -f pf.conf; sleep 30; cp pf.conf.bak pf.conf; pfctl -f pf.conf

The rules change (to set block return quick) did not kill my existing session, so I hit control+c after mashing a few keys to see if they would be echo'd by the terminal.

  • As @ilkkachu quoted from the man page, if the packet matches an existing state, they it is passed through without any further evaluation of any rules. Then why does having a block quick all hang the existing connection? That implies the block rule actually is evaluated and applied for the stateful packets of the current ssh connection... Let's assume there's no aggressive pruning or optimization.
    – dakini
    Aug 7 at 20:03
  • 1
    @dakini show your rules, and what you changed, and what commands you used. I do not see that behavior setting block quick all while also having the modulate state rules for inbound SSH and outbound TCP connections.
    – thrig
    Aug 7 at 20:18
  • So earlier I was playing with just two lines block in quick all and pass in proto tcp to port 22. When I run this the current session hangs, and resumes after the sleep timer. Then I removed the quick in the first line and the session kept working. Now I copy pasted your 3 lines. There is no difference between the bevavior with your 1st and 2nd set of statements. The connection hangs everytime and at timeout there's an error message client_loop: send disconnect: Broken pipe. Now even my 2 sets of statements behave the exact same way. I have not changed my sshd config in the interim.
    – dakini
    Aug 7 at 20:59
  • I try clearing out the states but it is the same behavior. Going to bed now, will check further tomorrow. The commands I am using is just a simple script - pfctl -d then pfctl -e -f /etc/pf.conf then sleep 30 and finally pfctl -d
    – dakini
    Aug 7 at 21:04
  • 1
    Why are you disabling the firewall, instead of just reloading the rules with pfctl -f /etc/pf.conf?
    – thrig
    Aug 7 at 21:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.