[SOLVED] Logging drop records iptables
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.
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
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!
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.
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.
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.