Page MenuHomeVyOS Platform

In state related mode, does the OUT rules-set of an interface are the same that the IN rules-set of the others interfaces ? (and vice versa)
Closed, ResolvedPublic

Asked by Smiley on Feb 28 2018, 3:24 PM.



I just set some firewalling rules on a VyOS instance, and have a remaining question...
So, it is possible to set one IN, one OUT and one LOCAL group-rules for each interface.
But in fact, in state related mode, OUT rules of an interface are supposed to be the same that the IN rules of the others, isn't it ?
For example, if we want to allow a http network connection from a client connected to interface eth0, to a server connected to interface eth1, are the two following rules the same ?

in the OUT rules set for eth1: source=client; destination=server; protocol=http; action=accept
in the IN rules set for eth0: source=client; destination=server; protocol=http ; action=accept

So theses are two similar rules.
Is that true ? Is it necessary to configure both ? Or only one of them is enough ? If the two are set-up, will this take two times more CPU usage ?
More generally, are the IN rules processed firstly, before the OUT rules are processed ?

Thanks for your help,


Updated 1,334 Days Ago

When you make use of the global firewall state policy it will evaluate configured ESTABLISHED, RELATED, and INVALID state matches before traversing a policy that has been applied to an interface and direction (either via interface-level or zone-policy configuration).

In terms of performance considerations, since it (correctly) performs state matching early on, it is efficient in bypassing rule traversal for established and related connections.

It is important to understand, that using this global level of state matching, while easy to use, does limit the amount of control you have (e.g. it is a tradeoff of control vs. simple configuration).

One such example is that if you wish to block a connection that is already established, there is no place to configure a rule to drop that traffic. Instead you will need to remove that connection from the conntrack table (e.g. perform a lookup using show conntrack ipv4 to determine the connection ID followed by delete conntrack table ipv4 conn-id <ID> to remove it).

Alternatively, if you are performing state matching on a per-policy basis you have the ability to insert drop rules before the state check. A practice I recommend is to maintain a NET-BLACKLIST network-group that you can use to quickly drop problem traffic and apply as a pair of drop rules (one for matching source, one for matching destination) before your state check rules.

There is no practical performance difference between defining state match rules globally or individually per-policy provided that you perform the match within the first few rules.

If you were to move your state match rules to the end of a long ruleset, on the other hand, then you would see a performance penalty since each rule would need to be evaluated before reaching the state check. This is why you should always have your rules to permit ESTABLISHED and RELATED traffic at the start of your policy as opposed to the end of it.

It's very hard to see a performance difference between 1 and 10 rules being evaluated on Linux. You would see a difference between 1 and 100 or 1000 rules, though (depending on PPS and resources available). So it really depends on what scale you're working with. I say there is no practical difference because you would typically be talking fractions of a millisecond in terms of the difference between 10 and 1000.

Also note that in terms of connection tracking, for a connection to be considered established, there must be bi-directional communication observed. Likewise, for traffic to be related, it must first have an entry in the expect table.

As an aside entries in the expect table are only created by conntrack helper modules observing established connections for specific protocols that make additional connections using different 5-tuple (protocol, source address, destination address, source port, and destination port or type if applicable) information than the original connection. The most common example of this is Active-mode FTP, where the server will respond with an additional source port to the one used to initiate the connection.

Here is an example:

Provided you have two network interfaces on a firewall, and you have a default drop policy in place on traffic in both directions, on each interface (e.g. 4 firewall rulesets to traverse), the global permit for related and established traffic will not apply until bi-directional communication has been observed. Even if you allow the traffic coming into the interface of the first network, it must still be explicitly permitted in the policy for outgoing traffic of the second network before the destination host will be able to receive and respond to move the connection into an established state. Until that response happens, the connection remains NEW (or rather a sub-state of UNREPLIED but that detail only matters to netfilter developers).

Also note that conntrack is always described in terms of the traffic initiator. What permitting established state traffic does is allow the return traffic without the need to create a specific rule to do so. So, generally, no if you are allowing established and related traffic, once you have the rules to permit the initial connection, you do not need rules to match the return traffic. This is the essence to a stateful firewall. It allows you to control the flow of communication by introducing the concept of direction to traffic (as hinted by the initiator and responder). For example, you might allow connections to your web server on TCP port 80 for HTTP, and allowing established traffic would permit the return traffic for each connection specifically, while maintaining the ability to prevent your web server from making outbound connections on its own, even if using a source port of 80. This is the difference between a stateful firewall and an access control list. Using a simple router ACL, all you would need to do is define your source port to be 80 and you could make any outgoing connection you want. Using a stateful firewall, that attempt would fail unless it were in response to a specific connection that was initiated remotely (and in the case of TCP, still open in terms of the TCP state machine).

That's a long way of getting to your question (sorry). I hope I made it less confusing.

So while you don't need to make a rule specifically for return traffic in your example, if you're traversing two different firewall rulesets, one applied to inbound traffic on interface A and the other applied to outbound traffic on interface B, then yes, you will need rules that match new connections on each of those for the traffic to flow (but not for the other two rulesets for traffic in to interface B and out of interface A, since allowing established and related traffic covers that).

Updated 1,329 Days Ago

Thank you for these detailed explanations !

Thus I have a remaining question: if I don't need IN ruleset, and implement only OUT ruleset (with for example eth1: source=client; destination=server; protocol=http; action=accept), do I have the same security level that implementing both IN and OUT rulesets ?
Or, if I don't need OUT ruleset but ONLY implement IN ruleset (which will be eth0: source=client; destination=server; protocol=http ; action=accept for this example), will this work and be enough secured too ?

Thank you very much !

New Answer


This question has been marked as closed, but you can still leave a new answer.