Hello OpenWRT'ers. I have a request for a toggle option in Luci to allow firewall rules to influence traffic in already established sessions. In the current state of OpenWRT if you remove a rule that is allowing traffic it will prevent any new traffic from passing. However it will still allow all existing sessions to flow and that traffic to pass. Some may not consider this a big deal but for absolute network control you want to stop these sessions right away. Especially if you are using something like timed rules to block traffic at certain times of the day.
I have done as much research as I can on other implementations for this and have compiled it all below. There doesn't seem to be a standardize name for this so sorry about all the different terms. I just want to include as many examples as I can.
Example #1 IPFW
IPFW refers to this as keep states. This is basically a flag you can toggle on and off to influence this behavior.
net.inet.ip.fw.dyn_keep_states: 0
Keep dynamic states on rule/set deletion. States are relinked to default rule (65535). This can be handly for ruleset reload. Turned off by default.
Example #2 Fortinet
On Fortinet once a session is established traffic no longer has to hit the policy lookup process. All packets that have established sessions just flow from source to destination. When a rule is deleted on Fortinet it marks all packets afterwards with the "dirty flag". Packets with the dirty flag are subject to hit the firewall policy lookup again even though they have sessions already established. This effectively makes it so any new rule changes influence already established traffic.
Example #3 Juniper
I was not able to find the best documentation on Juniper but I did find a bug report that describes what happens when a firewall policy is deleted. Essentially when you remove a policy on an SRX is tears down all of the sessions related to it. Since sessions are removed along with the firewall rule this prevents established traffic from flowing when you make firewall changes.
Example #4 Check Point
Check point has the option to toggle this behavior on and off. You can have it keep all sessions on policy changes or you can set this to not and have it remove sessions on policy changes.
The conntrack subsystem does not have any mechanism to reevaluate established connections against firewall rules. Once a connection is tracked, it remains unaffected by rule changes unless explicitly removed or until it times out. Are you asking for an option to flush the entire conntrack table, disrupting all connections, after a rule change?
Thank you for profound insight into firewall marketplace.
Unlike FreeBSD IPFW , linux (iptables or nftables) conntrack does not keep track of a rule that made a state.
Yes, you can see numbers in listing, but those nibble whenever any netdev is added/removed.
What remains is to flush all states and rely on fw picking them uo.
Ok so if it is not possible to have session tracking on a per firewall basis would it be possible to add an automatic conntrack session clear option in OpenWRT?
Maybe the gui could have several options:
*Option 1 - no change firewall acts the way it does not. This should probably be the default.
*Option 2 - A toggle on a per firewall rule basis that lets the user enable session clearing when changes happen to that rule or that rule is removed.
*Option 3 - A global setting that can be toggled for all firewall rule changes. With this toggle enabled anytime the user makes any change to the firewall conntrack sessions are cleared.
When I have messed with this it seems that sessions rebuild fast enough that there is no noticeable impact to client devices. Probably depends on the application, number of sessions, and the performance of the router hardware. I think this can all be done natively as you can clear sessions with "echo f > /proc/net/nf_conntrack".
Yes, your commamd is correct, check the fw3 file and integrate conntrack flush via init script or /sbin/fw4, both are text files you can edit on live router with handy backup kept in /rom.
Ok so I added the following and now when I make rule changes it does automatically clear sessions. This needs to be under the reload section to work but I also put it under restart. Not too sure if I need it there or not. So far this doesn't seem to be causing any issues but I probably will need to test it more to know for sure.
I was not able to find the init.d FW3 file anywhere to check how it worked then.
root@JSTN-R1:~# cat /etc/init.d/firewall
#!/bin/sh /etc/rc.common
START=19
USE_PROCD=1
QUIET=""
service_triggers() {
procd_add_reload_trigger firewall
procd_add_reload_data_trigger firewall
}
restart() {
fw4 restart
echo f > /proc/net/nf_conntrack <--- ADDED THIS
}
start_service() {
fw4 ${QUIET} start
}
stop_service() {
fw4 flush
}
reload_service() {
fw4 reload
echo f > /proc/net/nf_conntrack <--- ADDED THIS
}
boot() {
# Be silent on boot, firewall might be started by hotplug already,
# so don't complain in syslog.
QUIET=-q
start
}
RELOAD - remove and re-add, and apply considering Δ
RESTART - generally, this should do what the OP proposed (clear connection states) and load the firewall in its entirety, all ipsets, etc.
This is a proposal to significantly change functionality, e.g., (unlike the OP) I personally have and use systems that assume the netfiltet-like functionality of the firewall as it relates to connection states.
I once made a cheat sheet of what actually happens with the ruleset when you invoke different stop/start/restart/reload commands. I must have deleted it, but there were some unexpected results.
For example, /etc/init.d/firewall stop deletes all the nftables tables (fw4 plus others if you have them). /sbin/fw4 stop deletes only the fw4 table. The former actually calls fw4 flush.