[SOLVED] iptables does not appear to be blocking IP
Linux - NetworkingThis forum is for any issue related to networks or networking.
Routing, network cards, OSI, etc. Anything is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Can you show the complete iptables rules? If too lengthy, at least show us all the rules in the chain. If a rule is matching earlier in the chain then your custom rule will never take effect.
I'll show you what I have. Unfortunately, I felt the need to pull the plug on port 1913. The attacker had tried to brute force 67,642 times in the past 15 1/2 hours. This necessitated restarting iptables. However, I do keep track of the blocked IP and they get put into the bad_people chain when iptables is restarted. Here's what I've now got:
Code:
> iptables -L -v -n --line-numbers | more
Chain INPUT (policy DROP 41 packets, 1640 bytes)
num pkts bytes target prot opt in out source destination
1 1147 65141 ACCEPT tcp -- eth1 * (not 45. ....) 0.0.0.0/0 tcp dpt:22
2 0 0 ACCEPT tcp -- eth1 * (not 45. ....) 0.0.0.0/0 tcp dpt:22
3 29330 4426K bad_people all -- eth1 * 0.0.0.0/0 0.0.0.0/0
4 26180 4582K ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
5 326 21507 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
6 618 35548 ACCEPT tcp -- eth1 * 0.0.0.0/0 0.0.0.0/0 tcp flags:0x17/0x02
7 3741 936K ACCEPT udp -- eth1 * 0.0.0.0/0 0.0.0.0/0
8 0 0 ACCEPT icmp -- * * 192.168.0.0/24 0.0.0.0/0 icmptype 8 state NEW,RELATED,ESTABLISHED
9 0 0 checkcount tcp -- eth1 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 flags:0x17/0x02
10 0 0 ACCEPT tcp -- eth1 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 flags:0x17/0x02 limit: avg 1/sec burst 3
Chain bad_people (2 references)
num pkts bytes target prot opt in out source destination
1 24 1440 DROP all -- * * 181.230.0.0/16 0.0.0.0/0
2 24 1440 DROP all -- * * 202.29.0.0/16 0.0.0.0/0
3 24 1440 DROP all -- * * 122.55.0.0/16 0.0.0.0/0
4 28 1680 DROP all -- * * 211.75.0.0/16 0.0.0.0/0
:
:
and another 438 DROP entries ...
All of the INPUT chain rules are automatically loaded and should have been the same as before I restarted. The bad_people chain is added to by intrusion detection scripts, which is how 45.136.108.15 got added in the first place (OP).
Interestingly, after I turned off port 1913 and listened to that port with nc, the attacker got no response to his "hello" request and, after disconnecting, hasn't retried since (that is, in the past hour).
I know the actual iptables rule-set from the attack is gone, but unless there were somehow a rule permitting 45.136.108.0/24 can you think of any way it could continually get past iptables?
I know the actual iptables rule-set from the attack is gone, but unless there were somehow a rule permitting 45.136.108.0/24 can you think of any way it could continually get past iptables?
No, the only logical explanation is that a matching rule occurs earlier in the netfilter chain, (likely your rule for allowing incoming connections on port 1913).
No, the only logical explanation is that a matching rule occurs earlier in the netfilter chain, (likely your rule for allowing incoming connections on port 1913).
The bot is back! This time trying another port.
The rule that allowed incoming connections on 1913 is:
I've now blocked that ip again with '/usr/sbin/iptables -I bad_people -s 45.136.108.0/24 -j DROP'. Running tcpdump shows continued attempts even though I've done that. They are getting through to the target host, so the DROP is definitely not working.
tcpdump is going to pick up packets before they are presented to iptables. Unless you are also seeing your system sending a response to those packets, your DROP rule is working.
tcpdump is going to pick up packets before they are presented to iptables. Unless you are also seeing your system sending a response to those packets, your DROP rule is working.
Is not the 2nd line in that tcpdump the response? (192.168.0.2 is the local host, 45.136.108.17 is the bad actor)
In any case, the DROP was not working. I was able to see login attempts as it continued to try two ports (one example):
Code:
[2019/09/22 11:14:17.806429, 2] ../source4/auth/ntlm/auth.c:475(auth_check_password_recv)
auth_check_password_recv: sam authentication for user [(null)\USER5] FAILED with error NT_STATUS_NO_SUCH_USER, authoritative=1
As threatened, I then tried deleting the nat rule:
rules 22 and 23 were from 'iptables -t nat ...' rules in my previous post; in this case to host 192.168.0.60. Notice the large number of packets (just since I restarted iptables not long ago).
When I deleted rule 23, I stopped getting the authentication failure messages (above) and tcpdump stopped showing the return ack packets, and less than 5 minutes later the bot stopped trying altogether.
That's the good news. The bad news is that somehow those nat rules override the DROP rules, which is very, very bad. I need to be able to block these hacks!
Can someone help me refine these rules? Again, for reference:
Indeed, since port 1913 is being forwarded to another machine, those packets never traverse the INPUT chain. That chain is only for packets destined for the local machine.
Indeed, since port 1913 is being forwarded to another machine, those packets never traverse the INPUT chain. That chain is only for packets destined for the local machine.
Ah ha! Makes sense. How do I deal with the problem? Is there not something I can do on the machine doing the forwarding?
ferrari: is your '-m set --match-set' suggestion something to accomplish this? If not (or so) what is that supposed to do?
I've checked your link and my "BLACKLIST" chain is "bad_people". Otherwise, I nothing different stands out.
later ...
OK, I've done some searching on '-m set --match-set' (of which I've found precious little!) and it does appear that this parameter will instruct the FORWARD to check the bad_people chain. I'd like to try that. Where should I put these two rules? The order in which I run the iptables command is:
Then I add the saved list of bad_people blocks, then I add those workstation nat/PREROUTING, FORWARD rules.
Should I put the '-m set --match-set' rules after creating the bad_people chain and before adding IPs to that chain, or after adding to the chain and before adding the workstation routing rules?
ferrari: is your '-m set --match-set' suggestion something to accomplish this? If not (or so) what is that supposed to do?
Yes, it was just to illustrate adding a suitable rule to your FOWARD chain (as well as the INPUT chain).
Quote:
I've checked your link and my "BLACKLIST" chain is "bad_people". Otherwise, I nothing different stands out.
Just shared to help with clarification.
later ...
Quote:
OK, I've done some searching on '-m set --match-set' (of which I've found precious little!) and it does appear that this parameter will instruct the FORWARD to check the bad_people chain.
Yes, that's exactly why I posted that rule. For more info
Code:
man iptables
Quote:
I'd like to try that. Where should I put these two rules? The order in which I run the iptables command is:
In general, they should be put as early in the respective chain as possible, but in practice as long there is no rule which might match they absolute position does not matter. The '-I' option will add to the beginning, unless a specific rule number position is explicitly stipulated....
Quote:
-I, --insert chain [rulenum] rule-specification
Insert one or more rules in the selected chain as the given rule number. So, if the rule number is 1, the rule or rules are inserted at
the head of the chain. This is also the default if no rule number is specified.
I've stuck those two '-m set' rules right after creating the bad_people chain and before any IP DROPs, before any workstation FORWARDs and before any other INPUT rules. My erstwhile attacker has gone away (for now) so I'll have to wait to test.
Or will I? While searching for things I came across 'ipset test' which appears to let me test the rules. Unfortunately, I can no longer find that example, nor any other example for 'ipset test'. Maybe I'm just a very poor googler! Can I use that command to test with my known bad actor's IP? I've looked at the ipset man page which has 'ipset test SETNAME TEST-ENTRY [ TEST-OPTIONS ]'. It doesn't really say what a 'set' is, but I'm guessing from your (farrari) rule examples, "bad_people" is a set? How about "FORWARD"? I tried:
Code:
> ipset test bad_people 45.136.108.17
Which gave, "The set with the given name does not exist." So perhaps I don't understand what a set is. Perhaps this isn't even the tool for this.
(btw - I don't know about your iptables version, but my man page, iptables (1.6.0), iptables-extensions, has nothing about --match-set. iptables-extensions says -m specifies the module name -- in this case "set", but where is the documentation on the "set" module? Doing 'iptables -m set -h' gives only "--match-set name flags [--return-nomatch]")
You will have to create an ipset set before you can add/delete/match addresses with it. It is very well worth learning and easy to use. Iptables 1.6.0 supports it (if built with ipset support).
From man iptables-extensions:
Code:
set
This module matches IP sets which can be defined by ipset(8).
[!] --match-set setname flag[,flag]...
where flags are the comma separated list of src and/or dst specifications and there can be no
more than six of them. Hence the command
iptables -A FORWARD -m set --match-set test src,dst
will match packets, for which (if the set type is ipportmap) the source address and destination
port pair can be found in the specified set. If the set type of the specified set is single
dimension (for example ipmap), then the command will match packets for which the source address
can be found in the specified set.
...
SET
This module adds and/or deletes entries from IP sets which can be defined by ipset(8).
--add-set setname flag[,flag...]
add the address(es)/port(s) of the packet to the set
--del-set setname flag[,flag...]
delete the address(es)/port(s) of the packet from the set
...
See man 8 ipset for the ipset options, including set creation and management.
Sets must be created before iptables can match or make other use of them, of course. So if you did not create a bad_people set you will see the message you posted.
An example of creating a set with support for networks and IPs and counts the number of times an address matches might be like this (you need to read man 8 ipset to understand the different set types and write a command for your own case):
Code:
ipset create myset hash:net hashsize 1024 counters
ipset add myset 111.222.0.0/16
ipset list myset
Name: myset
Type: hash:net
Revision: 4
Header: family inet hashsize 1024 maxelem 65536 counters
Size in memory: 440
References: 0
Members:
111.222.0.0/16 packets 0 bytes 0
ipset test myset 111.222.123.45
111.222.123.45 is in set myset.
You can create a set, add, delete and test without actually making use of it in your iptables rules, so it is easy to learn your way around the sets. When you want to use them in your iptables rules, add the set creation to you rules script before it is referenced in any rule.
Everything you need to know is in the man pages for ipset(8) and iptables-extensions, but you will need to read through them and understand them.
UPDATE: Added following for more complete suggestion of use...
If you use an ipset set to keep banned IPs/networks, you can easily script loading them from a simple text file or using ipset save/restore to initialize the set from a previous state.
Then, assuming your set is named bad_people, you might make this your first rule:
Code:
iptables -t raw -I PREROUTING -m set --match-set bad_people src -j DROP
Anything in that set will never be be seen again...
(I wrote the above rule from memory, fix errors according to man pages)
Last edited by astrogeek; 09-25-2019 at 02:10 PM.
Reason: Updated
Everything you need to know is in the man pages for ipset(8) and iptables-extensions, but you will need to read through them and understand them.
Astrogeek: Thanks for that extensive discourse and examples. Athough, I don't know if I totally agree with your assertion that "everything you need to know is in the man pages." I looked for information on understanding, for example, what the various datatypes meant and found little either in the man pages or on the web, although both referenced man pages were highly useful for syntax, if not in-depth explanation. I did find a pretty useful document at https://www.netdevconf.org/1.1/proce...g-iptables.pdf, which was part of the proceedings of a NetDev conference in Spain, 2016. There were a few other helpful posts as well.
Quote:
If you use an ipset set to keep banned IPs/networks, you can easily script loading them from a simple text file or using ipset save/restore to initialize the set from a previous state.
Yes, I do that with my normal iptables rules, which I periodically clear. However, I did find that ipsets persist even when iptables is terminated, which is good. I suppose unless I do save ipsets they would not persist through reboot.
Quote:
Then, assuming your set is named bad_people, you might make this your first rule:
Code:
iptables -t raw -I PREROUTING -m set --match-set bad_people src -j DROP
Anything in that set will never be be seen again...
Here's what I've done, in my iptables script:
Code:
ipset -exist create blockrdc hash:net hashsize 1024 counters
iptables -I INPUT -m set --match-set blockrdc src -j DROP
iptables -I FORWARD -m set --match-set blockrdc src -j DROP
That follows your earlier examples, but using the setname "blockrdc". Your latest example uses only "-t raw -I PREROUTING" as the iptables rule. Would it be better/correct to use that rule instead of what I've got? Or add that rule to what I have? Recall that the iptables rules escaping my normal DROPs in my bad_people chain were of the form:
When I detect an attempted break-in (via a script) I will then do:
Code:
ipset add blockrdc $range
where "$range" is like: 184.57.60.0/24. I did 'ipset test blockrdc 184.57.111.128' after adding that range and got back, "184.57.111.128 is in set blockrdc." So that worked.
I guess my only remaining question has to do with your PREROUTING example and whether my --match rules are adequate or correct.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.