3

I found a question from another post that is close answering what I'm seeking. In short, I want to be able to setup a rule via ipset that times out automatically, but I want to whitelist specific IPs and ranges, and block everything else (on all ports).


Original code: Ban 1.1.1.2 for 400 seconds.

ipset create temp_hosts hash:ip timeout 0
iptables -I INPUT 1 -m set -j DROP  --match-set temp_hosts src
iptables -I FORWARD 1 -m set -j DROP  --match-set temp_hosts src
ipset add temp_hosts 1.1.1.2 timeout 400

I would like to change this to whitelist just 192.168.2.123 and 192.168.1.0/255.255.255.0 for 3600 seconds (one hour), and ban everyone else. How would I modify this script to accomplish this?

Additionally, how could I modify this to allow separate port ranges for 192.168.2.123 versus 192.168.1.0/255.255.255.0?

Work So Far

I've tried this, which works temporarily:

sudo ipset create temp_hosts hash:ip timeout 3600
sudo iptables -I INPUT 1   -m set -j ACCEPT --match-set temp_hosts src
sudo iptables -I FORWARD 1 -m set -j ACCEPT --match-set temp_hosts src
sudo iptables -A INPUT     -m set ! --match-set temp_hosts src -j DROP

However, when it completes, everyone is banned indefinitely until I reset the box.

Thank you.


Edit

Is this the proposed/suggested change?

1|  sudo ipset create temp_hosts hash:ip timeout 3600
2|  sudo iptables -I INPUT 2   -m set -j ACCEPT --match-set temp_hosts src
3|  sudo iptables -I FORWARD 1 -m set -j ACCEPT --match-set temp_hosts src
4|  sudo iptables -A INPUT     -m set ! --match-set temp_hosts src -j DROP
5|  sudo iptables -I INPUT 1   -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
5
  • get rid of the ||true doesn't belong with iptables or ipset
    – cybernard
    Commented Mar 8, 2019 at 0:31
  • Everyone is banned because after 3600 second temp_host is empty and all traffic matches the 4th rule and therefore is dropped. You need to add iptables -I INPUT 1 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT and your other rule you can change to input 2
    – cybernard
    Commented Mar 8, 2019 at 2:59
  • This is good to know. May I please request a snippet/example (i.e. based on my buggy one) that would accomplish this?
    – Cloud
    Commented Mar 8, 2019 at 3:08
  • Do you want users with established connection to be killed at the 3600 second mark, or if they try and establish a new connection after 3600 then don't allow it?
    – cybernard
    Commented Mar 8, 2019 at 3:13
  • Let's assume no rules to start with. When my script is executed, anyone in the whitelist stays connected, while anyone not in the whitelist is dropped, and cannot connect until 3600 seconds have elapsed. During the 3600 second window, whitelisted IPs are completely unaffected. When the 3600 second duration has elapsed, everything reverts to how it was before the script was executed (i.e. whitelisted IPs remain connected, and whitelisted/non-whitelisted IPs can connect again).
    – Cloud
    Commented Mar 8, 2019 at 3:15

1 Answer 1

4
ipset add temp_hosts 192.168.2.123 timeout 3600
ipset add temp_hosts 192.168.1.0/24 timeout 3600

This accomplishes your first goal, but you need to have a save and load in place if you want this to persist across reboots.

If you had systemd installed

create afile named "/usr/lib/systemd/system/ipset.service"

[Unit]
Description=IP sets for iptables
After=ufw.service
Before=network.target
Before=iptables.service
Before=webmin-iptables.service
AssertPathExists=/src/all.txt

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStartPre=-/bin/echo 'Loading ipset sets'
ExecStart=/sbin/ipset restore -f /src/all.txt
ExecStop=/sbin/ipset save -f /src/all.txt
ExecStartPost=-/bin/echo 'Saving ipsets to disk'
#ExecReload=/usr/libexec/ipset/ipset.start-stop reload
# Save current ipset entries on stop/restart.
#   Value: yes|no,  default: no
# Saves all ipsets to /etc/sysconfig/ipset if ipset gets stopped
Environment=IPSET_SAVE_ON_STOP=yes IPSET_SAVE_ON_RESTART=no
ReadWriteDirectories=/src
NoNewPrivileges=yes

[Install]
WantedBy=basic.target

Notice how the it saves to /src/all.txt either create the folder and file in advanced or change it to a file/folder of your choosing.

chkconfig ipset on 

Should enable said process

Next periodically do a ipset save temp_hosts

You should see the timeout gradually go down each time.

ipset create foo hash:ip,port timeout 3600
ipset add foo 192.168.1.0/24,80-82

You also have to have iptables load each time linux is started up. Different distro store iptables.save in different locations.

Note the default limit for an ipset is 65535, but can easily be changed by adding maxelem 800000 to the end of the create line. I have approx 750,000 ip in a single set.

Update

sudo ipset create whitelist hash:ip,port timeout 3600
sudo iptables -I INPUT 1   -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT 
sudo iptables -I INPUT 2   -m set -j ACCEPT --match-set whitelist src
sudo iptables -I FORWARD 1 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT 
sudo iptables -I FORWARD 2 -m set -j ACCEPT --match-set whitelist src
sudo iptables -A INPUT     -m set ! --match-set whitelist src -j DROP

sudo ipset add whitelist permanent_ip_1,80-82 timeout 0
sudo ipset add whitelist permanent_ip_2,80-82 timeout 0
sudo ipset add whitelist temp_ip1,80-82 timeout 3600

The conntrack rules allow traffic that is already connected to keep going, but no new connection can be established. If you were logged in as an admin, and doing updates and the updates took longer than 3600 seconds they would be immediately cut off after 3600 seconds. You can do that if you want.

The other problem that exists is with out RELATED,ESTABLISHED if you try to download something from an IP not in the whitelist it will fail. Try to go to google.com, nope its not on the whitelist. The connection go to google.com, but when google.com sends a packet pack it will be dropped without my conntrack rule.

8
  • Could I also please request a minimal example without persistence/save files? I'm still not certain on how to properly block all other IPs, and avoid the issue I have where, when the timeout elapses, everyone is locked out of the system.
    – Cloud
    Commented Mar 8, 2019 at 0:50
  • @DevNull The save files only exist so you don't lose this when you reboot. If that doesn't matter to you, then ignore them.
    – cybernard
    Commented Mar 8, 2019 at 2:55
  • That much I realize, but I don't see which piece of the example bans/blocks incoming IP connectivity outside of the whitelisted range (I edited the question to note this). Additionally, with the example I provided, it works, but after the timeout elapses, all incoming connections are blocked until I power cycle the machine. I was hoping I could block all incoming IPs outside of the whitelist. My intent is basically to allow a handful of IPs to have temporary, exclusive access to a machine (i.e. via SSH, TELNET, HTTP, etc.) and then guaranantee the change expires/times-out.
    – Cloud
    Commented Mar 8, 2019 at 3:00
  • sudo iptables -A INPUT -m set ! --match-set temp_hosts src -j DROP This kills all your traffic when the whitelist is empty. You need to added entries with a timeout 0 for IP's that have permanent access.
    – cybernard
    Commented Mar 8, 2019 at 3:07
  • I edited the question to address this (hopefully). Does the edited example match your suggestion?
    – Cloud
    Commented Mar 8, 2019 at 3:12

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .