First, this allows all traffic in and logs those requests.
Secondly, the final rules could probably be tweaked. I may do another post to examine this set very, very closely.
NOTE: if you’re making changes from a remote location, make sure you tell your firewall to let you in. If you already have rules in place, this will do no harm. If you have no rules in place, this will hopefully make it clear to you and your system that SSH needs to be let through. The -s <start-ip> <end-ip>
is optional.
iptables -A INPUT -s <start-ip> <end-ip> -p tcp --dport 22 -j ACCEPT
View current distro info (if you’re not sure):
root@aptly:~# lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description: Debian GNU/Linux 7.8 (wheezy)
Release: 7.8
Codename: wheezy
Based on the distro info, do we know where iptables configs are being stored? From experience, I would suspect /etc/sysconfig
(RHEL flavors) or /etc/iptables
(Debian flavors) but neither directory exists in my case. Taking a look at iptables -L -n
, there are no rules loaded. So, maybe I’ll just create my own and load them at boot. Also, take a look at netstat -tlnp
to see what is currently listening and be sure not to block anything that you know you need.
# netstat -tlnp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 1642/rpcbind
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 2519/sshd
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 2471/exim4
tcp 0 0 0.0.0.0:58397 0.0.0.0:* LISTEN 1673/rpc.statd
tcp 0 0 0.0.0.0:10050 0.0.0.0:* LISTEN 2357/zabbix_agentd
tcp6 0 0 :::111 :::* LISTEN 1642/rpcbind
tcp6 0 0 :::22 :::* LISTEN 2519/sshd
tcp6 0 0 ::1:25 :::* LISTEN 2471/exim4
tcp6 0 0 :::36063 :::* LISTEN 1673/rpc.statd
tcp6 0 0 :::10050 :::* LISTEN 2357/zabbix_agentd
Now, let’s begin…
Start by making a place for your rules.
mkdir /etc/iptables
vi /etc/iptables/iptables.ipv4
Add the following, or something like it:
# INPUT
iptables -N LOGGING
# Allows all loopback (lo0) traffic and drop all traffic to 127/8 that doesn't use lo0
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT ! -i lo -d 127.0.0.0/8 -j REJECT
# Accepts all established inbound connections
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j LOGGING
# Allows SSH connections
# The --dport number is the same as in /etc/ssh/sshd_config
iptables -A INPUT -p tcp -m state --state NEW --dport 22 -j LOGGING
# Allow ping
# note that blocking other types of icmp packets is considered a bad idea by some
# remove -m icmp --icmp-type 8 from this line to allow all kinds of icmp:
# https://security.stackexchange.com/questions/22711
iptables -A INPUT -p icmp -m icmp --icmp-type 8 -j LOGGING
# log iptables denied calls (access via 'dmesg' command)
iptables -A INPUT -j LOGGING
iptables -A LOGGING -m limit --limit 4/min -j LOG --log-prefix "iptables-accepted: " --log-level 4
iptables -A LOGGING -j ACCEPT
# OUTPUT
# Allows all outbound traffic
iptables -A OUTPUT -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -j ACCEPT
# Reject all other inbound - default deny unless explicitly allowed policy:
iptables -A INPUT -j REJECT
# iptables -A FORWARD -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -j REJECT
Save your changes. Note, the commands in this file are to be *run* on the command line, NOT *loaded* by iptables. So…load this series of iptables commands:
bash /etc/iptables/iptables.ipv4
Assuming you did not lose contact with your host, check the state of your firewall, now.
# iptables -L -n
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:22
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
REJECT all -- 0.0.0.0/0 127.0.0.0/8 reject-with icmp-port-unreachable
LOGGING all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
LOGGING tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22
LOGGING icmp -- 0.0.0.0/0 0.0.0.0/0 icmptype 8
LOGGING all -- 0.0.0.0/0 0.0.0.0/0
REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
Chain FORWARD (policy ACCEPT)
target prot opt source destination
REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state NEW,RELATED,ESTABLISHED
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
Chain LOGGING (5 references)
target prot opt source destination
LOG all -- 0.0.0.0/0 0.0.0.0/0 limit: avg 4/min burst 5 LOG flags 0 level 4 prefix "iptables-accepted: "
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
I will note here first that as it stands now, this may not be the most efficient use of the rules. I doesn’t seem to be the most succinct BUT for now, it’s okay.
Save the current rules to an IPTables config.
iptables-save > /etc/iptables/rules.v4
This is what the rules.v4
file contains:
# Generated by iptables-save v1.4.14 on Thu Mar 12 10:04:00 2020
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:LOGGING - [0:0]
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -d 127.0.0.0/8 ! -i lo -j REJECT --reject-with icmp-port-unreachable
-A INPUT -m state --state RELATED,ESTABLISHED -j LOGGING
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j LOGGING
-A INPUT -p icmp -m icmp --icmp-type 8 -j LOGGING
-A INPUT -j LOGGING
-A INPUT -j REJECT --reject-with icmp-port-unreachable
-A FORWARD -j REJECT --reject-with icmp-port-unreachable
-A OUTPUT -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT
-A OUTPUT -j ACCEPT
-A LOGGING -m limit --limit 4/min -j LOG --log-prefix "iptables-accepted: "
-A LOGGING -j ACCEPT
COMMIT
# Completed on Thu Mar 12 10:04:00 2020
Now…normally, I would follow methods that are more generally acceptable for making sure these rules are loaded each reboot (see iptables-persistent
). However, the system on which I’m setting this up is a system that is being retired. The system is providing legacy services and cannot be updated under any circumstances. This exercise was begun to simply determine what services or servers are accessing this server so I don’t want to do anything too intrusive, like updating packages or even installing packages, for that matter. Therefore, I will load these rules at boot time via cron.
@reboot /sbin/iptables-restore < /etc/iptables/rules.v4
One more test:
# iptables -F
# iptables-restore /etc/iptables/rules.v4
# iptables -L -n
And now reboot to test it all.
I’m seeing some ntp that I didn’t account for:
Mar 12 10:19:25 aptly kernel: [ 6.316149] iptables-accepted: IN=eth0 OUT= MAC=9a:6c:12:75:a3:20:00:1c:73:8d:05:d7:08:00 SRC=88.99.76.254 DST=10.61.75.72 LEN=76 TOS=0x18 PREC=0x00 TTL=50 ID=28740 DF PROTO=UDP SPT=123 DPT=123 LEN=56
What the heck is 88.99.76.254? Seems legit, according to this post, but it did remind me that I ought to update my NTP servers to point to our internal ones.