Community discussions

MikroTik App
 
cmaney
just joined
Topic Author
Posts: 18
Joined: Sat Aug 12, 2017 1:23 am

Modifying /ip/firewall/filter with api/script

Sat Aug 12, 2017 1:42 am

I can successfully use the API to add a firewall filter rule with no problems. The issue is that I'd like to add the rules in the appropriate place.

For example, I'd like to add a filter rule *before* the default rule that has the comment: "defconf: drop all from WAN". The difficulty is that the number of the rule is variable, so I can't say something like "place-before=14" and expect it to behave correctly.

I've tried using something like: /ip firewall filter get number=[find comment="defconf: drop all from WAN"]

That successfully finds the correct rule, but doesn't return anything that I can figure out how to use.

(For reference, it returns: .id=*3;.nextid=*4;action=drop;bytes=541304;chain=input;comment=defconf: drop all from WAN;dynamic=false;in-interface=ether1;invalid=false;packets=7671 )

If I do a "/ip firewall filter print" then that particular rule shows up as number 8.

From my reading elsewhere, it appears as if the "id" that is returned is not really associated with the order of the rules, but is rather auto-generated for the display, so I think it's a red herring for this topic.

The box is running 6.40.1.

Am I trying to overcomplicate this? Any suggestions would be greatly appreciated!
 
cmaney
just joined
Topic Author
Posts: 18
Joined: Sat Aug 12, 2017 1:23 am

Re: Modifying /ip/firewall/filter with api/script

Thu Aug 17, 2017 8:56 pm

Anyone have any ideas? Or is there a better way to do this?
 
User avatar
boen_robot
Forum Guru
Forum Guru
Posts: 2400
Joined: Thu Aug 31, 2006 4:43 pm
Location: europe://Bulgaria/Plovdiv

Re: Modifying /ip/firewall/filter with api/script

Fri Aug 18, 2017 2:55 pm

The "add" command has an argument called "place-before". It takes an ID of an item, before which the new one will be placed.

If you want to move an existing item, you need to use the "move" command. It takes two arguments - "numbers", which is items that will be moved from their current position into the order specified, and "destination", which is the item above which the items in "numbers" will be placed. Without "destination", the targeted items are moved to the bottom.
 
pe1chl
Forum Guru
Forum Guru
Posts: 10218
Joined: Mon Jun 08, 2015 12:09 pm

Re: Modifying /ip/firewall/filter with api/script

Fri Aug 18, 2017 3:03 pm

First: why do you need to insert firewall rules? There are other features in RouterOS that you would normally
use to have firewall rules that adapt to changing conditions: IP address list, interface list.
Maybe you can use those instead? (a single rule that is always in place and a list that is updated)
 
cmaney
just joined
Topic Author
Posts: 18
Joined: Sat Aug 12, 2017 1:23 am

Re: Modifying /ip/firewall/filter with api/script

Fri Aug 18, 2017 9:37 pm

boen_robot: Thanks for your comment. I already mentioned why "place-before" won't work in this instance (although I guess I could always just use "place-before=0", but that's ugly.) I'll look at the "move" command, but if I understand you correctly, it will have the same problem, wouldn't it? (The problem being that I have not been able to programmatically figure out which line number to move before.)

pe1chi: I'm not sure why the 'why' is that relevant, but, in short, I'm working on a web interface that can automate some things like, for example, creating nat and firewall rules automatically for a VPN or a webserver without having to train people in all the steps that would normally be required. (This cuts down on people forgetting a step, etc.) Obviously, "place-before=0" would be fine for a VPN since that's where it needs to go anyway, but for mailservers, webservers, etc., it would not be ideal. tldr; I'm abstracting away some of the work in order to increase productivity and decrease errors.
 
User avatar
boen_robot
Forum Guru
Forum Guru
Posts: 2400
Joined: Thu Aug 31, 2006 4:43 pm
Location: europe://Bulgaria/Plovdiv

Re: Modifying /ip/firewall/filter with api/script

Fri Aug 18, 2017 10:06 pm

Since I know from another topic you're using my API client, I can tell you that you can use the Util methods. They implement numbers under the hood. More specifically, you can use Util::find() with a number to get the item at that index, or give a number to Util::move() to implicitly find() the item at that index, and use it in place of "numbers" or "destination".

f.e.
$util->setMenu('/ip firewall filter');
$util->add(array('place-before' => $util->find(14), 'chain' => 'forward'));//Place this new rule above the 15th item
or for existing items
$util->setMenu('/ip firewall filter');
$util->move(14, 0);//Move the 15th item above the 1st
If you were doing it in another API client, you'd need to call "print" with no query or "find" to get all IDs in their actual order (for menus where the position is significant, replies are guaranteed to come in their actual order), and get the appropriate ID out of that, and place it into the appropriate argument.

If you're doing the same from scripting, you can use :pick over a "print as-value", and then get the ".id" out of that, e.g.
/ip firewall filter
add place-before=([:pick [print as-value] 14]->".id") chain=forward;
or
/ip firewall filter
:local items [print as-value];
move ([:pick $items 14]->".id") ([:pick $items 0]->".id");
 
cmaney
just joined
Topic Author
Posts: 18
Joined: Sat Aug 12, 2017 1:23 am

Re: Modifying /ip/firewall/filter with api/script

Fri Aug 18, 2017 10:55 pm

Yes! That is exactly what I needed! Thank you. I'll go play with it this weekend and report back.

(By the way, other than some initial hiccups figuring out how to get your API client, I have been very pleased with it. Great work!)
 
pe1chl
Forum Guru
Forum Guru
Posts: 10218
Joined: Mon Jun 08, 2015 12:09 pm

Re: Modifying /ip/firewall/filter with api/script

Sat Aug 19, 2017 10:54 am

pe1chi: I'm not sure why the 'why' is that relevant, but, in short, I'm working on a web interface that can automate some things like, for example, creating nat and firewall rules automatically for a VPN or a webserver without having to train people in all the steps that would normally be required. (This cuts down on people forgetting a step, etc.) Obviously, "place-before=0" would be fine for a VPN since that's where it needs to go anyway, but for mailservers, webservers, etc., it would not be ideal. tldr; I'm abstracting away some of the work in order to increase productivity and decrease errors.
Ok that is a valid purpose, although as you already indicate the sequence does not really matter for NAT rules.
Of course, NAT rules must be specific to the port being forwarded.
Note, however, that you do not need a matching firewall filter rule for each dst-nat rule that you create. This can
be handled with a single rule that matches incoming forward traffic with connection-nat-state=dstnat
It is always good to limit the number of filter rules as they have to be matched one-by-one for all traffic until a
match is found (which of course is the reason to put the established/related rule a high as possible in the chain).
 
cmaney
just joined
Topic Author
Posts: 18
Joined: Sat Aug 12, 2017 1:23 am

Re: Modifying /ip/firewall/filter with api/script

Thu Aug 24, 2017 12:28 am

pe1chl:

"Note, however, that you do not need a matching firewall filter rule for each dst-nat rule that you create. This can
be handled with a single rule that matches incoming forward traffic with connection-nat-state=dstnat"

That's actually a really good point, and one that I will keep in mind. Thank you! With that said, that feature seems like it might be a nuisance, at times, too. For example: is there an elegant way to handle the situation of opening up an internal server to only certain static IPs on the Internet without a VPN? That situation comes up from time to time, but I have never had to solve it with a Mikrotik. I could always remove the connection-nat-state=dstnat line, or put in permit lines followed by a 0.0.0.0 deny (before the connection-nat-state line), I guess. (I'm guessing that the latter idea would probably be better, performance-wise.)

Is there a better way? Should I open a different thread?
 
User avatar
boen_robot
Forum Guru
Forum Guru
Posts: 2400
Joined: Thu Aug 31, 2006 4:43 pm
Location: europe://Bulgaria/Plovdiv

Re: Modifying /ip/firewall/filter with api/script

Thu Aug 24, 2017 12:50 am

Is there a better way? Should I open a different thread?
Probably yes (to both questions).

But in short and in general: You can group rules into a custom chain, and jump to certain chains depending on criteria. That way, you limit evaluation only to rules in the custom chain, within which the prior checks are guaranteed to be true. You can think of them as if you're having a PHP function.

e.g. the following pseudo PHP code
function input(array $packet): string {
    if ($packet['connection-nat-state'] === 'dstnat') {
        $result = natted($packet);
        if ($result) {
            return $result;
        }
    }
    return 'drop';
}

function natted(array $packet): string {
    if (in_array($packet['src-address'], AddressList::toArray('allowed')) {
        return 'accept';
    }
    return '';
}
is one way to express what in RouterOS would be
add chain=input connection-nat-state=dstnat action=jump jump-target=natted
add chain=input action=drop
add chain=natted src-address-list=allowed action=accept
add chain=natted action=return
And also, as the example demonstrates, prefer using lists where possible, be they address lists or interface lists.

For the particular example, the above is somewhat of an overkill, in that you can simply use:
add chain=input connection-nat-state=dstnat src-address-list=allowed action=accept
add chain=input action=drop
to achieve the same effect, but in more complicated scenarios, particularly when otherwise the same check(s) need to be done by many rules, it pays to jump to custom chains.
 
Sob
Forum Guru
Forum Guru
Posts: 9121
Joined: Mon Apr 20, 2009 9:11 pm

Re: Modifying /ip/firewall/filter with api/script

Thu Aug 24, 2017 3:31 am

Rather than dstnatting everything and then blocking some (or most) of it just a moment later, do the selection in dstnat rule:
/ip firewall nat
add action=dst-nat chain=dstnat dst-address=<public> dst-port=<port> protocol=<protocol> \
    to-addresses=<internal> src-address-list=<list>
And you can keep allowing all connections with connection-nat-state=dstnat.
 
pe1chl
Forum Guru
Forum Guru
Posts: 10218
Joined: Mon Jun 08, 2015 12:09 pm

Re: Modifying /ip/firewall/filter with api/script

Thu Aug 24, 2017 11:44 am

For example: is there an elegant way to handle the situation of opening up an internal server to only certain static IPs on the Internet without a VPN?
As Sob already replied: do all your checking in the dst-nat rule(s) and allow only what you want to allow, then pass all dstnat traffic in the filter chain.
 
cmaney
just joined
Topic Author
Posts: 18
Joined: Sat Aug 12, 2017 1:23 am

Re: Modifying /ip/firewall/filter with api/script

Fri Sep 01, 2017 6:00 pm

Sorry for the delayed response, but I wanted to thank everyone for the input. It's always nice to learn new/better/varied ways of doing things, and I appreciate the assistance. Everything is working now.

Who is online

Users browsing this forum: No registered users and 28 guests