What is the proper way to disable/enable a firewall rule in a general way?

Hi,

I need to turn off this rule off (wait) then back on, automatically.

Now Luci did give me the command it uses.

uci set firewall.cfg0e93c8.enabled='0'
uci del firewall.cfg0e93c8.enabled

But these special number only work on that particular instance of my router, but I wipe it often, and these numbers will change. I need a command that is "general".

The rule is

root@router:~# uci show firewall | grep -i snat
firewall.@nat[0].name='public_snat'
firewall.@nat[0].target='SNAT'
firewall.@nat[0].snat_ip='69.69.69.69'
root@router:~#

I can't rely on "@nat[0]" as a future router might not have that as the "rule 0". It really is the rule named public_snat that I need to turn off then on.

So, what it comes down to, is, is the following the "right way" to identify the rule number ?

root@router:~# uci show firewall | grep "name='public_snat'" | cut -d. -f2
@nat[0]
root@router:~#

Can I expect that formulation to last and be of general use ?

Something like this

id=$(uci show firewall | grep "name='public_snat'" | cut -d. -f2)
uci set firewall.$id.enabled='0'
uci commit firewall
/etc/init.d/firewall reload
sleep 5
uci del firewall.$id.enabled
uci commit firewall
/etc/init.d/firewall reload

I made a oneliner version

id=$(uci show firewall | grep "name='public_snat'" | cut -d. -f2); uci set firewall.$id.enabled='0'; uci commit firewall; /etc/init.d/firewall reload; sleep 5; uci del firewall.$id.enabled; uci commit firewall; /etc/init.d/firewall reload

This works.

Next I will need to, ping to check if internet is up, if internet not up, ping gateway, if no response, run that series of command. Loop and wait 15 seconds to do it again forever.

Also I will need to run this script at boot and it should automatically restart itself if it stops itself on its own.

1 Like
nft insert rule inet fw4 srcnat_wan .... 

Wouldn't that bypass the UCI config entirely ?

You can include a shell script that extracts wan IP and prepends shadow snat rule.

I am just trying to guess result you are after.

You can create a named rule.

uci set firewall.public_snat=nat
uci set firewall.public_snat.name='public_snat'
uci set firewall.public_snat.target='SNAT'
uci set firewall.public_snat.snat_ip='69.69.69.69'
uci set firewall.public_snat.enabled='0'
uci commit firewall
1 Like

Hello,

I had the problem again so I got to test the above commands.

First I tried

rulename='public_snat'; uci set firewall.$rulename.enabled='0'; uci commit firewall; /etc/init.d/firewall reload; sleep 5; uci del firewall.$rulename.enabled; uci commit firewall; /etc/init.d/firewall reload

But this did not work, here is the console output

root@router:~# rulename='public_snat'; uci set firewall.$rulename.enabled='0'; uci commit firewall; /etc/init.d/fir                   ewall reload; sleep 5; uci del firewall.$rulename.enabled; uci commit firewall; /etc/init.d/firewall reload
uci: Invalid argument
Section @redirect[0] (sunshine) is disabled, ignoring section
uci: Entry not found
Section @redirect[0] (sunshine) is disabled, ignoring section
root@router:~#

I tried just the uci set command alone

root@router:~# uci set firewall.$rulename.enabled='0'
uci: Invalid argument
root@router:~# echo uci set firewall.$rulename.enabled='0'
uci set firewall.public_snat.enabled=0
root@router:~# uci set firewall.public_snat.enabled=0
uci: Invalid argument
root@router:~#

I don't understand why didn't uci set firewall.public_snat.enabled=0 work ?

Next I tried my earlier version

id=$(uci show firewall | grep "name='public_snat'" | cut -d. -f2); uci set firewall.$id.enabled='0'; uci commit firewall; /etc/init.d/firewall reload; sleep 5; uci del firewall.$id.enabled; uci commit firewall; /etc/init.d/firewall reload

console output

root@router:~# id=$(uci show firewall | grep "name='public_snat'" | cut -d. -f2); uci set firewall.$id.enabled='0'; uci commit firewall; /etc/init.d/firewall reload; sleep 5; uci del firewall.$id.enabled; uci commit firewall; /etc/init.d/firewall reload
Section @redirect[0] (sunshine) is disabled, ignoring section
Section @nat[0] (public_snat) is disabled, ignoring section
Section @redirect[0] (sunshine) is disabled, ignoring section
root@router:~#

This worked as expected and now internet works again.

Next I will need to make a script which tests internet connectivity at a certain interval and run these commands when internet stops working. And I will need to run that script automatically at boot and automatically restart this script if it stops working.

uci set firewall.public_snat.enabled=0

This syntax, I find much cleaner, am I using it incorrectly ?

You would have to re-create the rule from the command-line using the example commands I gave. Please show the uci show firewall section that includes the full rule you want to manipulate.

Or simply rename the section:

uci show firewall.@nat[0]
uci rename firewall.@nat[0]=public_snat
uci show firewall.public_snat
uci commit firewall
service firewall reload

Here is the section

root@router:~# uci show firewall | grep @nat
firewall.@nat[0]=nat
firewall.@nat[0].name='public_snat'
firewall.@nat[0].proto='all'
firewall.@nat[0].src='wan'
firewall.@nat[0].target='SNAT'
firewall.@nat[0].snat_ip='69.69.69.69'
root@router:~#

Isn't it already named public_snat ?
since there is this firewall.@nat[0].name='public_snat'

I'm a little confused is it

firewall.cfg0e93c8.
firewall.@nat[0].
or 
firewall.public_snat.

The description of the rule is public_snat right now, but the uci name of the rule is @nat[0] (an anonymous section). Once you rename it, it will be public_snat instead of @nat[0].

1 Like

Is it possible to do the rename from luci ?
If the rule gets deleted and re-created in luci, will it go back to being named @nat[0] ?

I don't want my script to break when someone uses luci.

Maybe there is a way to make it that giving a .name automatically renamed the rule ? Or create an alias ?