[olug] How can I sever IPtables established connections for only certain IPs?
Ben Hollingsworth
obiwan at jedi.com
Tue May 23 13:35:20 CDT 2023
Heh. My current IPtables config is over 700 lines, so I think
converting to a different platform will be a bit more complex than
that. Thanks for the pointers, though. I'll definitely save them for
future reference.
On 5/23/23 13:15, Lou Duchez wrote:
> Perhaps now's the time to take the plunge with nftables. The sample I
> provided is a working sample - I actually ran it on my router to make
> sure it works - and other than tweaking IP addresses to your purposes,
> it should be ready to go. I think you'd just drop a couple lines like
> this in my_filter_forward:
>
> ip saddr 192.168.1.240 drop
> ip daddr 192.168.1.240 drop
>
> ... I am noting that there's not even a "conntrack" line in there
> because it forwards everything by default, so there's no need to even
> check "conntrack". If the default were "drop", that's when the
> "conntrack" line would be necessary.
>
>
> On 5/23/2023 1:57 PM, Ben Hollingsworth wrote:
>> That's a great writeup.
>>
>> I've been very fond of the fwbuilder GUI for running IPtables. I
>> haven't typed a raw command in years. The down side is that it has
>> no facility for doing what you suggested (moving rules above
>> conntrack), so I'll finally have to get my hands dirty again. That
>> shouldn't be too hard, I guess.
>>
>> On 5/23/23 12:39, Lou Duchez wrote:
>>> While I'm in a mood to be expansive, I remember what a hassle it was
>>> for me to learn nftables. Here is the writeup that I would have
>>> loved to have had back in the day, because I think this makes things
>>> simple.
>>>
>>> NFTABLES CONCEPTS
>>>
>>> nftables operates via nested sections contained between curly brackets.
>>>
>>> The highest level section is the "table", and when you define your
>>> table, you need to specify the "family" it is to govern ("ip" for
>>> IPv4, "ipv6" for IPv6, "inet" for both, etc), plus a name. You can
>>> have more than one table for a given family, for your own
>>> organizational purposes.
>>>
>>> To do NAT and masquerading, you have to use "ip" or "ipv6", but not
>>> "inet". So with that in mind, we will do a family of "ip", and our
>>> table will start with:
>>>
>>> table ip myiptable {
>>>
>>> Within a table you can create "chains", which are sets of rules.
>>> Additionally you can hook them to specific events; for example, the
>>> first line in a chain might read:
>>>
>>> type filter hook input priority 0; policy accept;
>>>
>>> And that tells you that this chain is to be traversed during the
>>> "filter" phase of inbound traffic. Also, this chain's priority is
>>> "0" (which means it executes before a comparable chain with priority
>>> of "1"), and any traffic that is not otherwise disposed of in this
>>> chain leaves the chain with a status of "accept".
>>>
>>> Here is a chain that allows only loopback traffic and ports 80 and
>>> 443, and drops everything else:
>>>
>>> chain myinput {
>>>
>>> type filter hook input priority 0; policy drop;
>>>
>>> ct state established,related accept
>>>
>>> iifname "lo" accept
>>>
>>> tcp dport 80 accept
>>>
>>> tcp dport 443 accept
>>>
>>> }
>>>
>>> Chains can call other chains by name; that's why you'd create a
>>> chain that doesn't have any hook instructions, so it can be treated
>>> like a subroutine that you can "jump" to.
>>>
>>> You can also create sets of IPs, so for example you could create a
>>> set of trusted IPs, and then test against it something like: "ip
>>> saddr @trusted_ips accept".
>>>
>>> So, how do we put this together? A very simple router
>>> /etc/sysconfig/nftables.conf would look like:
>>>
>>>
>>> table ip myiptable {
>>>
>>> # traffic with a destination of this server
>>>
>>> chain my_filter_input {
>>>
>>> type filter hook input priority 0; policy drop;
>>>
>>> ct state established,related accept
>>>
>>> iifname "lo" accept
>>>
>>> ip saddr 192.168.1.0/24 tcp dport 22 accept
>>>
>>> tcp dport 80 accept
>>>
>>> tcp dport 443 accept
>>>
>>> }
>>>
>>> # outbound traffic - no restrictions
>>>
>>> chain my_filter_output {
>>>
>>> type filter hook output priority 0; policy accept;
>>>
>>> }
>>>
>>> # forwarded traffic - no restrictions
>>>
>>> chain my_filter_forward {
>>>
>>> type filter hook forward priority 0; policy accept;
>>>
>>> }
>>>
>>> # NAT required to use this server as a router
>>>
>>> chain my_nat_postrouting {
>>>
>>> type nat hook postrouting priority 0; policy accept;
>>>
>>> ip saddr 192.168.1.0/24 masquerade
>>>
>>> }
>>>
>>> # DSCP to give the user at 192.168.1.2 priority over everyone else
>>>
>>> chain my_route_output {
>>>
>>> type route hook output priority filter; policy accept;
>>>
>>> ip saddr 192.168.1.2 ip dscp cs1
>>>
>>> }
>>>
>>> }
>>>
>>> So you could run "nft flush ruleset; nft -f
>>> /etc/sysconfig/nftables.conf" to load those rules.
>>>
>>> Another useful command: "nft list ruleset".
>>>
>>>
>>>
>>> On 5/23/2023 12:01 PM, Lou Duchez wrote:
>>>> ... even more efficiency: what happens if, ten minutes after you
>>>> disable the IPs, you switch to a third ruleset where the IPs are
>>>> disabled AFTER the "established,related" line? So hopefully all
>>>> those established connections will have been broken in those ten
>>>> minutes, and then you can go back to the efficiency of putting
>>>> "established,related" first.
>>>>
>>>> Side note, I switched to nftables a couple years ago, and I've been
>>>> very happy with it. There's a learning curve, but it's not that
>>>> terrible. I don't know that there's any advantage for your
>>>> particular scenario, but it seems to be what they want us to use
>>>> instead of iptables, and so it feels like bowing to the inevitable.
>>>>
>>>> On 5/23/2023 11:18 AM, Lou Duchez wrote:
>>>>> Put in the rules to disable the IPs before the
>>>>> "established,related" line? Normally you want the
>>>>> "established,related" as the first thing for efficiency's sake,
>>>>> but if you have to put a couple rules before that, you have to.
>>>>>
>>>>> On 5/23/2023 10:42 AM, Ben Hollingsworth wrote:
>>>>>> I have a somewhat complex IPtables setup (configured via
>>>>>> fwbuilder) that protects my home network. My firewall box runs
>>>>>> Ubuntu server 20.04. At a certain hour each night, I block a
>>>>>> handful of IPs that belong to my children's devices so that they
>>>>>> can't use them all night. I do this by keeping two separate
>>>>>> IPtables configs and using cron to install the appropriate one at
>>>>>> the appropriate time.
>>>>>>
>>>>>> This works fine for blocking new connections, but I've found that
>>>>>> any connections that happen to be open when the new config is
>>>>>> loaded will continue to stay open. My kids have figured that out
>>>>>> as well.
>>>>>>
>>>>>> The problem comes from this line, which exists in both configs,
>>>>>> and keeps related connections open across my reload:
>>>>>>
>>>>>> $IPTABLES -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED
>>>>>> -j ACCEPT
>>>>>>
>>>>>> Is there any way that I can turn off connection tracking for only
>>>>>> certain IPs? I'd really rather that open connections for
>>>>>> authorized IPs not get interrupted, but I can live with that if I
>>>>>> must.
>>>>>>
--
*Ben "Obi-Wan" Hollingsworth* obiwan at jedi.com www.Jedi.com
<http://www.jedi.com>
The stuff of earth competes for the allegiance I owe only to the
Giver of all good things, so if I stand, let me stand on the
promise that You will pull me through. /-- Rich Mullins/
More information about the OLUG
mailing list