ip firewall place-after

I have a long series of firewall rules.

I would like to be able to add a new firewall rule, from the Terminal, to after a particular rule (with a specific comment) that I don’t inherently know which position it will be in. My goal is creating a command line where it will work regardless of the specific rule configuration or order on the router. (really, I want the rule to be added after my established/related rule)

I know I can use
/ip firewall filter move x y
but to do that I need to know the values of x and y, which are the numbers from the print command.

I can use the “place-before” option, but that (unsurprisingly) places the new rule before the other rule, where I would like after.

I can use
[/ip firewall filter find comment=“this comment”]
to determine the internal Id, but the internal Id doesn’t work with the /ip firewall move command

What would be the command(s) to add a firewall rule after a rule with a particular comment?

Answering my own question, this script will work:

:global VarAllRules [/ip firewall filter find]
:global VarEstablish [/ip firewall filter find where comment="Accept established related"]
:global VarNext 0
:global VarSet 1

:foreach k in=$VarAllRules do={
 :if ($VarNext = 1) do={ 
   /ip firewall filter add chain=forward action=drop protocol=udp dst-port=53  place-before=$k \
   connection-state=new content="dropbox" comment="Block Dropbox DNS udp"
   :set $VarNext
   :set $VarSet
 }
 :if ($k = $VarEstablish) do={ :global VarNext 1 }
}

:if ($VarSet = 1) do={
   /ip firewall filter add chain=forward action=drop protocol=udp dst-port=53 \
   connection-state=new content="dropbox" comment="Block Dropbox DNS udp"
}

That code will (mostly) get the list of the internal Ids of all rules in order of the firewall list, find the rule AFTER the rule you want your rule before, and then add the rule before the rule that’s after the rule you want the rule after, which means you now have your rule after the rule you wanted it after, and before the rule after it :slight_smile: If the rule you want the rule after has nothing after it, add the new rule to the end. It probably doesn’t need globals, but that’s not the point of this exercise :slight_smile:

There’s a “place-before”. There’s ~20 lines of code that is “place-after”

There has to be a simpler way but that at least will work. Anyone have a simpler way?

This post is quite old but i want to give an answer for shortening this process. For example, you want to place a rule in the input chain “after” the common “established,related” states rule, this can be achieved with the following code:


/ip firewall filter add chain=input protocol=tcp dst-port=22 action=accept place-before=([get ([find chain=input && connection-state ~ "established"]->0)]->".nextid")

It is using the .nextid property of a rule to get the next itemid in the list of rules. Implied there is such a rule, otherwise you have to do these with if checks beforehand. So to be secure you something like this:

{
    :local rule ([/ip firewall filter find chain=input && connection-state ~ "established"]->0)
    :if ($rule) do={
       /ip firewall filter add chain=input protocol=tcp dst-port=22 action=accept place-before=([get $rule]->".nextid")
    } else={
       :error "Rule not found!"
    }
}

Just replace your checks in the find sentences to fit your needs.

Regards @colinardo