Before continuing you have to understand how packets are processed by netfilter/iptables framework. Firewall rules are data driven language, but actually, the things are very simple. All the packets traverse different parts of the Linux kernel. At certain points those packets are stopped (figuratively speaking) and set of rules is "executed" that can alter, drop or pass packet. If packet is passed (or modified and passed) it goes to the other parts of the kernel where potentially another set of rules is invoked.
The points where packets are "stopped" are chains, PREROUTING, INPUT, FORWARD, POSTROUTING, OUTPUT. In each chain there are different tables, but I'll ignore those for the moment as they are not important for this post.
Set of rules at each point (chain) is added or deleted using iptables command. The iptables command needs an argument that defines in which chain rule is added. That argument is option -A after which name of the chain follows. For example, to add something to INPUT chain, you would write:
iptables -A INPUT ...
To achieve that functionality, just write the rule as follows:if (src(ip) == 192.168.1.1) {do_something_with_packet;}
iptables -A INPUT -s 192.168.1.1 do_something_with_packetThe part do_something_with_packet I'll explain later, but basically this is a part that will do something useful with the packet on which this rule is executed.
Now, what if you want to add additional constraint, e.g. destination address is 192.168.1.2, i.e.
Well, what you'll write is the following:if (src(ip) == 192.168.1.1 and dst(ip) == 192.168.1.2) {do_something_with_packet;}
iptables -A INPUT -s 192.168.1.1 -d 192.168.1.2 do_something_with_packeteasy, isn't it? All the constraint you wish to bind with operator AND are just written one after another. Operator AND is implicit. Ok, now you can ask: But if I want to have OR, what to do then? For example, something like the following:
Believe it or not, it's simple, write it like this:if (src(ip) == 192.168.1.1 or dst(ip) == 192.168.1.2) {do_something_with_packet;
}
iptables -A INPUT -s 192.168.1.1 do_something_with_packetI suppose that you figured it that when you add iptables one after the other, they are bound by OR, while, when you write constraints in a single command they are bound by AND. Alternatively speaking, reading from left to right is AND, and from top to bottom is OR.
iptables -A INPUT -d 192.168.1.2 do_something_with_packet
3 comments:
How would one add an AND or OR operator for THE SAME constant into one rule?
I need to say -d ! 192.168.18.0/24 AND -d ! 192.168.19.0/24 as an example?
OR is easier, if you want:
iptables condA OR condB target
you can write it as:
iptables condA target
iptables condB target
AND is trickier because iptables doesn't support AND operator in specifiers. But, you can do it using custom chain. Say you want:
iptables condA AND condB target
you can write it as:
iptables -N newchain
iptables condA -j newchain
iptables -A newcnain condB target
Note that the iptables statements are only conceptual. :)
Your article is unique on the internet. Therefore it is a must. It is not clear to me how the AND operator works. I would appreciate an update. Example in my case: I want to block two strings located in different places. So I need a rule that if it matches the first one that checks the second one and if both match, then DROP. How can I use these operators to make it work. None of the examples they give on the internet work. Thanks in advance
Post a Comment