[SOLVED] Logging drop records iptables

Linode 12GB

Debian 9

Not very good with this stuff.

I would like to log drop IP's in a log when blocked. For some reason this is not working, most likely because I am doing something wrong.

While blocking does work, logging doesn't.

Using the iptable rules listed below, and loading ipset sets and adding rules to iptables, I can add an ip or block of ip's and they show up in the ipset for them, they do get blocked, but they don't get logged.

I had added logging rules at the end of the iptable rules, but they don't see to log anything.

Not clear what I am missing.

Below are my iptable rules:

*filter

#  Allow all loopback (lo0) traffic and drop all traffic to 127/8 that doesn't use lo0
-A INPUT -i lo -j ACCEPT
-A INPUT ! -i lo -d 127.0.0.0/8 -j REJECT

#  Accept all established inbound connections
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

#  Allow all outbound traffic - you can modify this to only allow certain traffic
-A OUTPUT -j ACCEPT

#  Allow HTTP and HTTPS connections from anywhere (the normal ports for websites and SSL).
-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -p tcp --dport 443 -j ACCEPT

#  Allow SSH connections
#  The -dport number should be the same port number you set in sshd_config
-A INPUT -p tcp -m state --state NEW --dport 2222 -j ACCEPT

#  Allow SFTP Connections
#  on port 2022 under different control from ssh 2222
-A INPUT -p tcp --dport 20:21 -j ACCEPT

#Passive FTP Ports Maybe: (Again, specifying ports 50000 through 50050 in one rule)
-A INPUT -p tcp --dport 50000:50050 -j ACCEPT

#-I INPUT -m set --match-set block src -j DROP
#-I INPUT -s 24.249.176.173 -j ACCEPT

#  Reject all other inbound - default deny unless explicitly allowed policy
-A INPUT -j REJECT
-A FORWARD -j REJECT

-N LOGGING
-A INPUT -j LOGGING
-A OUTPUT -j LOGGING
-A LOGGING -m limit --limit 2/min -j LOG --log-prefix "IPTablesDROP: " --log-level 4
-A LOGGING -j DROP
COMMIT

What they look like after loading ipset rules and adding them to iptables:

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
DROP       all  --  anywhere             anywhere             match-set tempdrop src
DROP       all  --  anywhere             anywhere             match-set geoblock src
DROP       all  --  anywhere             anywhere             match-set ylmf src
ACCEPT     all  --  anywhere             anywhere            
REJECT     all  --  anywhere             loopback/8           reject-with icmp-port-unreachable
ACCEPT     all  --  anywhere             anywhere             state RELATED,ESTABLISHED
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:http
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:https
ACCEPT     tcp  --  anywhere             anywhere             state NEW tcp dpt:2222
ACCEPT     tcp  --  anywhere             anywhere             state NEW tcp dpt:2022
ACCEPT     icmp --  anywhere             anywhere             icmp echo-request
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:smtp
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:2025
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:imap2
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:pop3
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:10110
ACCEPT     tcp  --  anywhere             anywhere             tcp dpts:ftp-data:ftp
ACCEPT     tcp  --  anywhere             anywhere             tcp dpts:50000:50050
REJECT     all  --  anywhere             anywhere             reject-with icmp-port-unreachable
LOGGING    all  --  anywhere             anywhere            

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         
REJECT     all  --  anywhere             anywhere             reject-with icmp-port-unreachable

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     all  --  anywhere             anywhere            
LOGGING    all  --  anywhere             anywhere            

Chain LOGGING (2 references)
target     prot opt source               destination         
LOG        all  --  anywhere             anywhere             limit: avg 2/min burst 5 LOG level warning prefix "IPTablesDROP: "
DROP       all  --  anywhere             anywhere 

I have the rule in rsyslog.conf to direct kern.warning

kern.warning                    /var/log/firewall.log

just before:

kern.*                          -/var/log/kern.log

and yes I did restart rsyslog.

8 Replies

@Dweeber:

#  Reject all other inbound - default deny unless explicitly allowed policy
-A INPUT -j REJECT
-A FORWARD -j REJECT

Before these lines, add:

-A INPUT -j LOG
-A FORWARD -j LOG

Then you can remove the LOG lines that follow the REJECTs.

When a rule matches in iptables and the target is DROP or REJECT, that action is taken and processing stops. (They are known as "terminating" targets.) If you want to have a LOG rule, it must come before you DROP or REJECT a packet.

There is a lot to cover when it comes to iptables. Here is my brief explanation.

There are multiple ways of manipulating the iptables rules. One is the CLI (or a script running the CLI commands) and another is a file that is basically shorthand for the CLI commands. In a RedHat distro (Fedora, CentOS) not using systemd (I don't know about Debian) that file is /etc/sysconfig/iptables. The contents of the file you posted is similar to the /etc/sysconfig/iptables on CentOS.

The iptables command and the files have similar formats, but the file only uses a subset of the commands available.

iptables -N WXYZ # Creates a new chain

iptables -L INPUT –line-numbers # Lists all rules with line numbers in the filter table (by default) and INPUT chain

iptables -I INPUT $rulenum …. # Inserts the specified rule (indicated by ….) at rule number $rulenum, moving subsequent rules down

iptables -A INPUT …. # Appends the specified rule (indicated by ….) at the bottom of the INPUT chain

iptables -R INPUT $rulenum …. # Replaces the rule number $rulenum with the specified rule (indicated by ….)

iptables -D INPUT $rulenum # Deletes the specified rule number, moving subsequent rules up

When you refer to ipset groups, do you mean the chain LOGGING? You have to create the chain before you can jump (-j) to it. In your config file you should be able to create the chain there. For example, here is what mine looks like, with my custom chain called HOME:

*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
:HOME - [0:0]

-A INPUT -p tcp -m tcp --dport 22 -j HOME

-A HOME -s w.x.y.z -j LOG --log-prefix "HOME:: "
-A HOME -s w.x.y.z -j ACCEPT

The top part (:HOME - [0:0]) is equal to using iptables -N HOME. This is where you have a choice. You can either create rules in the chain first OR create rules that jump to the empty chain and then create rules in it.

I've got it working better.

Part of the problem was that my ipset rules were not in the main iptables config file. Upon reboot, the server loaded the saved iptable rules and if the ipset groups had not been loaded yet, it would error.

The ipset iptable rules are -I not -A which then placed them out of order.

Now, I make sure the server loads the ipset groups first and the iptables rules are then loaded using -A entries and I moved the logging rule before them.

Now I am getting logging for the blocks related to IPset and I really don't care much about other blocks for services I don't allow.

Thanks for the info, it has been an education.

Thanks…

Okay. I tried the suggestion by carmp3fan last night and it does log other blocks. But was not logging the match-set blocks which is more of interest to me.

This morning, based on Vance's suggestion, I changed the rules for the match-set to look like:

-I INPUT -m set --match-set ylmf src -j LOG --log-prefix "IPTablesDROP: " --log-level 4
-I INPUT -m set --match-set geoblock src -j LOG --log-prefix "IPTablesDROP: " --log-level 4
-I INPUT -m set --match-set tempdrop src -j LOG --log-prefix "IPTablesDROP: " --log-level 4

-I INPUT -m set --match-set ylmf src -j DROP
-I INPUT -m set --match-set geoblock src -j DROP
-I INPUT -m set --match-set tempdrop src -j DROP

But didn't see any log entries.

When I looked at the output of iptables -L those rules seem to indicate the drops are before the logs??

Not sure how to force the log entries above?

DROP       all  --  anywhere             anywhere             match-set tempdrop src
DROP       all  --  anywhere             anywhere             match-set geoblock src
DROP       all  --  anywhere             anywhere             match-set ylmf src
LOG        all  --  anywhere             anywhere             match-set tempdrop src LOG level warning prefix "IPTablesDROP: "
LOG        all  --  anywhere             anywhere             match-set geoblock src LOG level warning prefix "IPTablesDROP: "
LOG        all  --  anywhere             anywhere             match-set ylmf src LOG level warning prefix "IPTablesDROP: "

@Dweeber:

I tried the suggestion by carmp3fan last night and it does log other blocks. But was not logging the match-set blocks which is more of interest to me.

That's my fault. I don't think I read the entire post clearly.

@Dweeber:

Not sure how to force the log entries above?

DROP       all  --  anywhere             anywhere             match-set tempdrop src
DROP       all  --  anywhere             anywhere             match-set geoblock src
DROP       all  --  anywhere             anywhere             match-set ylmf src
LOG        all  --  anywhere             anywhere             match-set tempdrop src LOG level warning prefix "IPTablesDROP: "
LOG        all  --  anywhere             anywhere             match-set geoblock src LOG level warning prefix "IPTablesDROP: "
LOG        all  --  anywhere             anywhere             match-set ylmf src LOG level warning prefix "IPTablesDROP: "

You just need to move your jump rules up in your source file. Basically, the -A means append, so if you are placing the append line below the reject or drop, then it won't ever match. If you place the -A INPUT -j LOGGING above the drop then it will jump to the LOGGING chain before being rejected or dropped. Unless there is a good reason, I try to keep all INPUT rules in one section, all FORWARD rules in another, all OUTPUT rules in another, etc. That helps eliminate this confusion.

*filter

#  Allow all loopback (lo0) traffic and drop all traffic to 127/8 that doesn't use lo0
-A INPUT -i lo -j ACCEPT
-A INPUT ! -i lo -d 127.0.0.0/8 -j REJECT

#  Accept all established inbound connections
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

#  Allow all outbound traffic - you can modify this to only allow certain traffic
-A OUTPUT -j ACCEPT

#  Allow HTTP and HTTPS connections from anywhere (the normal ports for websites and SSL).
-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -p tcp --dport 443 -j ACCEPT

#  Allow SSH connections
#  The -dport number should be the same port number you set in sshd_config
-A INPUT -p tcp -m state --state NEW --dport 2222 -j ACCEPT

#  Allow SFTP Connections
#  on port 2022 under different control from ssh 2222
-A INPUT -p tcp --dport 20:21 -j ACCEPT

#Passive FTP Ports Maybe: (Again, specifying ports 50000 through 50050 in one rule)
-A INPUT -p tcp --dport 50000:50050 -j ACCEPT

#-I INPUT -m set --match-set block src -j DROP
#-I INPUT -s 24.249.176.173 -j ACCEPT

-A INPUT -j LOGGING
-A OUTPUT -j LOGGING

#  Reject all other inbound - default deny unless explicitly allowed policy
-A INPUT -j REJECT
-A FORWARD -j REJECT

-N LOGGING
-A LOGGING -m limit --limit 2/min -j LOG --log-prefix "IPTablesDROP: " --log-level 4
-A LOGGING -j DROP
COMMIT

@carmp3fan thanks.

This afternoon, I will organize the rules in a more orderly fashion. What I have is now a collection from various sources without really knowing what I'm doing to get the desired effect I am looking for.

Learning experience.

Thanks!

Thanks for the additional information.

Debian (Ubuntu) are similar to CentOS which I know less about. I'm more of a Solaris, AIX, Debian guy but most of my servers are inside firewalls I don't have access to.

There is no system pre-defined file but I created one in /etc/iptables.firewall.rules

and in the network section under /etc/network/if-pre-up.d I have a script called iptables.

On a reboot, this gets run which loads my saved ipset groups and then the firewall settings.

#!/bin/sh
echo LOADING IPSET RULES
/sbin/ipset -! restore < /storage/ipsetdata/last

echo LOADING FIREWALL RULES
/sbin/iptables-restore < /etc/iptables.firewall.rules

@carmp3fan:

When you refer to ipset groups, do you mean the chain LOGGING?

Not sure about chain logging, haven't heard that term before, but the below is working.

# Block IP's in ipset matches
-A INPUT -m set --match-set ylmf src -j LOG
-A INPUT -m set --match-set geoblock src -j LOG
-A INPUT -m set --match-set tempdrop src -j LOG

-A INPUT -m set --match-set ylmf src -j DROP
-A INPUT -m set --match-set geoblock src -j DROP
-A INPUT -m set --match-set tempdrop src -j DROP

Before I was trying to do (note the -I for the drop's but -A for log entries) which were making the location of the entries in a different order than where I was placing them. I didn't notice the -I instead of -A.

# Block IP's in ipset matches
-A INPUT -m set --match-set ylmf src -j LOG
-A INPUT -m set --match-set geoblock src -j LOG
-A INPUT -m set --match-set tempdrop src -j LOG

-I INPUT -m set --match-set ylmf src -j DROP
-I INPUT -m set --match-set geoblock src -j DROP
-I INPUT -m set --match-set tempdrop src -j DROP

Basically, when one of the rules above drops a connection it is now being logged in my firewall.log. I want to know when this happens if someone says they are being blocked.

My ipset groups are updated during the day via various processes and their state is saved once an hour so the contents are preserved across reboots. In the past, I would have a text file and I would load all that into iptables directly taking up to 10 mins or so. ipsets makes it a lot easier.

Reply

Please enter an answer
Tips:

You can mention users to notify them: @username

You can use Markdown to format your question. For more examples see the Markdown Cheatsheet.

> I’m a blockquote.

I’m a blockquote.

[I'm a link] (https://www.google.com)

I'm a link

**I am bold** I am bold

*I am italicized* I am italicized

Community Code of Conduct