1

Firstly I want to ask why my rules.v4 looks so complicated after using: iptables -F. I thought it will be empty after flushing:

# Generated by iptables-save v1.6.0 on Tue Jan  9 21:25:13 2018
*filter
:INPUT ACCEPT [76:4024]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [1:40]
:ufw-after-forward - [0:0]
:ufw-after-input - [0:0]
:ufw-after-logging-forward - [0:0]
:ufw-after-logging-input - [0:0]
:ufw-after-logging-output - [0:0]
:ufw-after-output - [0:0]
:ufw-before-forward - [0:0]
:ufw-before-input - [0:0]
:ufw-before-logging-forward - [0:0]
:ufw-before-logging-input - [0:0]
:ufw-before-logging-output - [0:0]
:ufw-before-output - [0:0]
:ufw-logging-allow - [0:0]
:ufw-logging-deny - [0:0]
:ufw-not-local - [0:0]
:ufw-reject-forward - [0:0]
:ufw-reject-input - [0:0]
:ufw-reject-output - [0:0]
:ufw-skip-to-policy-forward - [0:0]
:ufw-skip-to-policy-input - [0:0]
:ufw-skip-to-policy-output - [0:0]
:ufw-track-forward - [0:0]
:ufw-track-input - [0:0]
:ufw-track-output - [0:0]
:ufw-user-forward - [0:0]
:ufw-user-input - [0:0]
:ufw-user-limit - [0:0]
:ufw-user-limit-accept - [0:0]
:ufw-user-logging-forward - [0:0]
:ufw-user-logging-input - [0:0]
:ufw-user-logging-output - [0:0]
:ufw-user-output - [0:0]
-A INPUT -i enp3s0 -p udp -m udp --dport 67 -j ACCEPT
-A INPUT -i enp3s0 -p tcp -m tcp --dport 67 -j ACCEPT
-A INPUT -i enp3s0 -p udp -m udp --dport 53 -j ACCEPT
-A INPUT -i enp3s0 -p tcp -m tcp --dport 53 -j ACCEPT
-A INPUT -i enp2s0 -p udp -m udp --dport 67 -j ACCEPT
-A INPUT -i enp2s0 -p tcp -m tcp --dport 67 -j ACCEPT
-A INPUT -i enp2s0 -p udp -m udp --dport 53 -j ACCEPT
-A INPUT -i enp2s0 -p tcp -m tcp --dport 53 -j ACCEPT
-A INPUT -j ufw-before-logging-input
-A INPUT -j ufw-before-input
-A INPUT -j ufw-after-input
-A INPUT -j ufw-after-logging-input
-A INPUT -j ufw-reject-input
-A INPUT -j ufw-track-input
-A FORWARD -d 10.42.0.0/24 -o enp3s0 -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -s 10.42.0.0/24 -i enp3s0 -j ACCEPT
-A FORWARD -i enp3s0 -o enp3s0 -j ACCEPT
-A FORWARD -o enp3s0 -j REJECT --reject-with icmp-port-unreachable
-A FORWARD -i enp3s0 -j REJECT --reject-with icmp-port-unreachable
-A FORWARD -d 10.42.1.0/24 -o enp2s0 -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -s 10.42.1.0/24 -i enp2s0 -j ACCEPT
-A FORWARD -i enp2s0 -o enp2s0 -j ACCEPT
-A FORWARD -o enp2s0 -j REJECT --reject-with icmp-port-unreachable
-A FORWARD -i enp2s0 -j REJECT --reject-with icmp-port-unreachable
-A FORWARD -j ufw-before-logging-forward
-A FORWARD -j ufw-before-forward
-A FORWARD -j ufw-after-forward
-A FORWARD -j ufw-after-logging-forward
-A FORWARD -j ufw-reject-forward
-A FORWARD -j ufw-track-forward
-A OUTPUT -j ufw-before-logging-output
-A OUTPUT -j ufw-before-output
-A OUTPUT -j ufw-after-output
-A OUTPUT -j ufw-after-logging-output
-A OUTPUT -j ufw-reject-output
-A OUTPUT -j ufw-track-output
-A ufw-after-input -p udp -m udp --dport 137 -j ufw-skip-to-policy-input
-A ufw-after-input -p udp -m udp --dport 138 -j ufw-skip-to-policy-input
-A ufw-after-input -p tcp -m tcp --dport 139 -j ufw-skip-to-policy-input
-A ufw-after-input -p tcp -m tcp --dport 445 -j ufw-skip-to-policy-input
-A ufw-after-input -p udp -m udp --dport 67 -j ufw-skip-to-policy-input
-A ufw-after-input -p udp -m udp --dport 68 -j ufw-skip-to-policy-input
-A ufw-after-input -m addrtype --dst-type BROADCAST -j ufw-skip-to-policy-input
-A ufw-after-logging-forward -m limit --limit 3/min --limit-burst 10 -j LOG --log-prefix "[UFW BLOCK] "
-A ufw-after-logging-input -m limit --limit 3/min --limit-burst 10 -j LOG --log-prefix "[UFW BLOCK] "
-A ufw-before-forward -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A ufw-before-forward -p icmp -m icmp --icmp-type 3 -j ACCEPT
-A ufw-before-forward -p icmp -m icmp --icmp-type 4 -j ACCEPT
-A ufw-before-forward -p icmp -m icmp --icmp-type 11 -j ACCEPT
-A ufw-before-forward -p icmp -m icmp --icmp-type 12 -j ACCEPT
-A ufw-before-forward -p icmp -m icmp --icmp-type 8 -j ACCEPT
-A ufw-before-forward -j ufw-user-forward
-A ufw-before-input -i lo -j ACCEPT
-A ufw-before-input -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A ufw-before-input -m conntrack --ctstate INVALID -j ufw-logging-deny
-A ufw-before-input -m conntrack --ctstate INVALID -j DROP
-A ufw-before-input -p icmp -m icmp --icmp-type 3 -j ACCEPT
-A ufw-before-input -p icmp -m icmp --icmp-type 4 -j ACCEPT
-A ufw-before-input -p icmp -m icmp --icmp-type 11 -j ACCEPT
-A ufw-before-input -p icmp -m icmp --icmp-type 12 -j ACCEPT
-A ufw-before-input -p icmp -m icmp --icmp-type 8 -j ACCEPT
-A ufw-before-input -p udp -m udp --sport 67 --dport 68 -j ACCEPT
-A ufw-before-input -j ufw-not-local
-A ufw-before-input -d 224.0.0.251/32 -p udp -m udp --dport 5353 -j ACCEPT
-A ufw-before-input -d 239.255.255.250/32 -p udp -m udp --dport 1900 -j ACCEPT
-A ufw-before-input -j ufw-user-input
-A ufw-before-output -o lo -j ACCEPT
-A ufw-before-output -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A ufw-before-output -j ufw-user-output
-A ufw-logging-allow -m limit --limit 3/min --limit-burst 10 -j LOG --log-prefix "[UFW ALLOW] "
-A ufw-logging-deny -m conntrack --ctstate INVALID -m limit --limit 3/min --limit-burst 10 -j RETURN
-A ufw-logging-deny -m limit --limit 3/min --limit-burst 10 -j LOG --log-prefix "[UFW BLOCK] "
-A ufw-not-local -m addrtype --dst-type LOCAL -j RETURN
-A ufw-not-local -m addrtype --dst-type MULTICAST -j RETURN
-A ufw-not-local -m addrtype --dst-type BROADCAST -j RETURN
-A ufw-not-local -m limit --limit 3/min --limit-burst 10 -j ufw-logging-deny
-A ufw-not-local -j DROP
-A ufw-skip-to-policy-forward -j DROP
-A ufw-skip-to-policy-input -j DROP
-A ufw-skip-to-policy-output -j ACCEPT
-A ufw-track-output -p tcp -m conntrack --ctstate NEW -j ACCEPT
-A ufw-track-output -p udp -m conntrack --ctstate NEW -j ACCEPT
-A ufw-user-limit -m limit --limit 3/min -j LOG --log-prefix "[UFW LIMIT BLOCK] "
-A ufw-user-limit -j REJECT --reject-with icmp-port-unreachable
-A ufw-user-limit-accept -j ACCEPT
COMMIT
# Completed on Tue Jan  9 21:25:13 2018
# Generated by iptables-save v1.6.0 on Tue Jan  9 21:25:13 2018
*nat
:PREROUTING ACCEPT [306:30491]
:INPUT ACCEPT [79:4750]
:OUTPUT ACCEPT [128:10004]
:POSTROUTING ACCEPT [122:8932]
-A POSTROUTING -s 10.42.0.0/24 ! -d 10.42.0.0/24 -j MASQUERADE
-A POSTROUTING -s 10.42.1.0/24 ! -d 10.42.1.0/24 -j MASQUERADE
COMMIT
# Completed on Tue Jan  9 21:25:13 2018

Second question - I need iptables to rate limit new connections on specific port (limit not per ip, but all new attempts if there are too many of them), at the same time don't block any traffic that doesn't come to that specific port. All examples I saw on the internet use DROP for default INPUT policy, but that don't suit me.

Update: I run game server on port 45000 (it uses tcp and upd protocol)and recently I had problems with bot spam. Bots are trying to connect to my server from all over the world using hundreds of proxys. Game server plugins successfully blocked them, but this attack become much stronger lately and now it cause lags. Ideally I wanted to block access to this port based on geolocation and allow only 5-10 countries, but thats complicated. Another option is to rate-limit new connections to that port while keeping already existing. Of course it sertanly will block normal players trying to join during attack, but at least those who already play can do it without extreme lagging. My server isn't large (30 players max) so I assume rate limit to 30 new connections to port 45000 per 30 seconds will be fine.

9
  • Try iptables -I INPUT -p tcp -m state --state NEW -m limit --limit 60/minute -j ACCEPT You would accept RELATED and ESTABLISHED first and REJECT after. If you wish, you can be more specific by specifying the port --dport 45000 , and you may need to fine tune the rate limit a bit to find a balance.
    – Panther
    Jan 10, 2018 at 14:36
  • This rule will work with current iptables.v4 rules? With default INPUT ACCEPT policy?
    – Gerolf
    Jan 10, 2018 at 16:13
  • The rule will work regardless, but if you will need to reject anything after this rule to block additional requests, either by setting the default policy which I advise against, or by adding a reject rule last in the chain.
    – Panther
    Jan 10, 2018 at 16:18
  • Of course I need to reject requests if there are too many of them. So as I understand I need 3 rules: iptables -A INPUT -p tcp --dport 45000 -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -I INPUT -p tcp -m state --state NEW -m limit --limit 60/minute -j ACCEPT And third rule to reject connections above 60/minute. The problem is all examples I saw was about limiting per ip and I need to limit globally (all new connections)
    – Gerolf
    Jan 10, 2018 at 16:52
  • Just iptables -I -j REJECT as a last rule will do as long as you do not need anything else such as ssh or http or ping or ...... dhcp or dns
    – Panther
    Jan 10, 2018 at 19:33

1 Answer 1

1

All the items you posted are because at some point you activated ufw which is a front end to iptables and made all those custom tables.

The -F option removes the rules from some, but not all of the rules from all the tables nor the empty chains you are seeing.

You need some additional options:

From https://serverfault.com/questions/200635/linux-iptables-best-way-to-clear-all-rules-leaving-anything-open the full set of commands to reset iptables is:

iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
iptables -t nat -F
iptables -t mangle -F
iptables -F
iptables -X
  • -P option resets the default policy for the tables.
  • The -t nat -F flushes the nat table.
  • The -t mangle -F flushes mangle, which is hardly ever used.
  • -X deletes empty chains.

See the link for IPv6 and the man iptables for additional details.

The "problem" is the -F option, without specifying a chain, does not flush all chains, in your case you have a few remaining chains created by UFW.

To delete those chains you need to flush them first (-X will not delete them unless they are empty)

So for each chain you first have to remove any reference to the chain , flush the chain, and then delete it

Starting with "ufw-before-logging-forward"

sudo iptables -D FORWARD -j ufw-before-logging-forward
sudo iptables -F ufw-before-logging-forward
sudo iptables -X ufw-before-logging-forward

and on for all the custom chains ufw added.

Of course as you are using ufw, so there is a far easier method:

sudo ufw disable

A few general comments

  1. I suggest you keep the default policy ACCEPT rather than REJECT or DROP. If you set the default policy to REJECT/DROP you can lock yourself your if you run iptables -F

  2. If you manually write iptables rules do not use ufw or other tools to alter your rules.

  3. I highly suggest REJECT rather then DROP. In a nut shell, DROP is more bothersome to legitimate traffic and although it sounds nice, DROP does not slow down or fool any of the modern cracking tools. Because your system reacts to a packet would be crackers know you are up and running at your ip address and DROP hides nothing.

See http://www.chiark.greenend.org.uk/~peterb/network/drop-vs-reject for details.

  1. Use iptables-persistent

The top answer How to save rules of the iptables? reviews basic usage including saving and restoring your rule set . See the man page for additional details.


For help writing rules I need more details, what port and what traffic do you want to limit and how. Limiting ping is different. Limiting a web server is different than limiting ssh connections. Allowing most but limiting a few is using perhaps a black list. Limiting all and allowing a few is a white list, etc.

Examples:

Web traffic - I might use the general syntax for a web server if it were very busy:

iptables -I INPUT -p tcp -m state --state NEW -m limit --limit 30/minute --limit-burst 5 -j ACCEPT

You certainly can add the option --dport 80 to the above command.

This limits to 30 connections a minute which is very slow for Apache. If the web server were not so busy you can liberalize up to thousands of connections / minute.

SSH - These rules are great for blocking brute force attempts

# This rule tracks incoming connections to port 22
iptables -A INPUT -p tcp -m tcp --dport 22 -m tcp -m state --state NEW -m recent --set --name SSH --rsource

# This command rejects any attempt to connect to ssh more than
# 8 times in 10 minutes
# After 10 minutes you can attempt again so not permanent ban
iptables -A INPUT -p tcp -m tcp --dport 22 -m recent --update --seconds 600 --hitcount 8 --rttl --name SSH --rsource -j REJECT --reject-with icmp-host-prohibited

# Finally this will accept the connections 
iptables -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT

If you need more specific help please update your question =)

1
  • Thank you for your detailed answer. I updated my post about what I want.
    – Gerolf
    Jan 10, 2018 at 13:49

You must log in to answer this question.

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