ZURÜCK

Systemd iptables

Custom iptables loader mit Systemd init tools.

Datum: 2016-02, Tags: Linux, Systemd, iptables, firewall


Die Installation von Runlevel-Scripten unter Systemd-basierten Linux Distributionen verläuft etwas anders, als die klassische Installation unter Sysvinit mit "chkconfig". Eine Umstellung auf Systemd betrifft auch die Verwaltung der Services und Logfiles, das soll hier aber nicht das Thema sein. Eine Kurzreferenz für Systemd und Journald-Logfiles finden Sie z.B. hier:


Die Referenzen finden sich auf den Seiten von freedesktop.org:


Ich benötige für meine eigenen iptables-Regeln einen eigenen Satz von Runlevel-Scripten, der sich aus drei Dateien zusammensetzt: Die Unit-Konfiguration /usr/lib/systemd/system/firewall.service, das Service-Script /etc/firewall/systemd-iptables und mein Regelwerk /etc/firewall/rules.ipv4.

/usr/lib/systemd/system/firewall.service
[Unit]
Description=iptables firewall
Before=network.service
Before=basic.service

[Service]
ExecStart=/etc/firewall/systemd-iptables start
ExecStop=/etc/firewall/systemd-iptables stop
ExecReload=/etc/firewall/systemd-iptables start
RemainAfterExit=true
Type=oneshot

[Install]
WantedBy=multi-user.target
/etc/firewall/systemd-iptables
#!/bin/sh
#
# /etc/firewall/systemd-iptables
#

CONFIG=/etc/firewall/rules.ipv4
BAREPORTS="22"

# safe path
PATH=/sbin:/bin

IPTABLES=/usr/sbin/iptables
IPTSAVE=/usr/sbin/iptables-save
IPTRESTORE=/usr/sbin/iptables-restore
SED=/usr/bin/sed
EGREP=/usr/bin/egrep
XARGS=/usr/bin/xargs

# make sure we have what we need
for tool in $IPTABLES $IPTSAVE $IPTRESTORE \
            $SED $EGREP $XARGS; do
  test -x $tool
  if [ $? -ne 0 ]; then
    echo missing $tool
    exit 1
  fi
done

# nothing to do if there's no config
test -r $CONFIG || exit 0

case "$1" in

  start)

    echo -n "Running "
        $IPTABLES -t nat -F
        $IPTABLES -t filter -F
        $EGREP -v "^(#|;| *$)" $CONFIG |\
                $SED "s/#.*//" |\
                $IPTRESTORE || $0 fail
    echo "."
  ;;

  stop)

    echo -n "flush rules "
    $IPTABLES -t nat -F
        $IPTABLES -t nat -P PREROUTING ACCEPT
        $IPTABLES -t nat -P POSTROUTING ACCEPT
        $IPTABLES -t nat -P OUTPUT ACCEPT
    $IPTABLES -t filter -F
        $IPTABLES -t filter -P INPUT ACCEPT
        $IPTABLES -t filter -P OUTPUT ACCEPT
        $IPTABLES -t filter -P FORWARD ACCEPT
        $IPTABLES -t mangle -F
        $IPTABLES -t mangle -P PREROUTING ACCEPT
        $IPTABLES -t mangle -P POSTROUTING ACCEPT
        $IPTABLES -t mangle -P INPUT ACCEPT
        $IPTABLES -t mangle -P OUTPUT ACCEPT
        $IPTABLES -t mangle -P FORWARD ACCEPT
    echo "."
    echo -n "deleting user chains "
    $IPTSAVE \
    | $SED -n 's/^:\([^ ]\+\) - .*/\1/p' \
    | $XARGS -n 1 $IPTABLES -X
    echo "."
    exit 0
  ;;

  fail)

    echo -e "\nsetting rules FAILD - applying BARE minimum\n"
    $0 stop
    $IPTABLES -A INPUT -i lo -j ACCEPT
    $IPTABLES -A INPUT -m state --state INVALID -j DROP
    $IPTABLES -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
    $IPTABLES -A INPUT -p tcp -m tcp -m state --state NEW -m multiport --dports $BAREPORTS -j ACCEPT
    $IPTABLES -P INPUT DROP
  ;;

  *)
    echo "Usage: systemctl {start|stop} firewall.service"
    exit 1

esac

# /sbin/modprobe nf_conntrack_ftp
# /sbin/modprobe nf_nat_ftp

exit 0
/etc/firewall/rules.ipv4
# iptables firewall ruleset
# enp3s0: ext
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
#
:DROPLOG - [0:0]
:LIMITLOG - [0:0]
#
##############
# INPUT rules
#
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state INVALID -j DROPLOG
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
#
-A INPUT -p tcp -m tcp -m state --state NEW --dport 113 -j REJECT --reject-with tcp-reset
-A INPUT -m addrtype --dst-type BROADCAST -j DROP
-A INPUT -m state --state UNTRACKED -j LOG --log-level 6 --log-prefix "IPT-UNTRACKED: "
#
# ICMP - allow echo request/reply (ping) and destination-unreachable
-A INPUT -p icmp -m icmp --icmp-type 3 -m limit --limit 10/sec -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 8 -m limit --limit 10/sec -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 11 -m limit --limit 10/min -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 12 -m limit --limit 10/min -j ACCEPT
-A INPUT -p icmp -j LIMITLOG
#
# ssh
-A INPUT -p tcp -m state --state NEW --dport 22 -m limit --limit 3/sec -j ACCEPT
#
# log everything else before it gets dropped
-A INPUT -m limit --limit 3/sec -j LOG --log-level 6 --log-prefix "IPT-IN-DROP: "
-A INPUT -j DROP
#
################
# FORWARD rules
#
# -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
#
###############
# OUTPUT rules
#
-A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A OUTPUT -o lo -j ACCEPT
#
################
# Helper chains
#
-A LIMITLOG -m limit --limit 3/sec -j LOG --log-level 6 --log-prefix "IPT-LIMITLOG: "
-A LIMITLOG -j DROP
#
-A DROPLOG -m limit --limit 3/sec -j LOG --log-level 6 --log-prefix "IPT-DROPLOG: "
-A DROPLOG -j DROP
#
#######
COMMIT
#


Das Verzeichnis /etc/firewall müssen wir selbst erstellen. Das Service-Script systemd-iptables muss ausführbar gemacht werden:


chmod 755 /etc/firewall/systemd-iptables


Anschließend können wir den Dienst dauerhaft aktivieren und starten:


systemctl enable firewall.service
systemctl start firewall.service
systemctl status firewall.service
firewall.service - iptables firewall
   Loaded: loaded (/usr/lib/systemd/system/firewall.service; enabled)
   Active: active (exited) since Di 2016-01-12 20:49:15 CET; 1 months 9 days ago
 Main PID: 8863 (code=exited, status=0/SUCCESS)
   CGroup: /system.slice/firewall.service

Jan 12 20:49:15 soil3 systemd-iptables[8863]: Running .
Feb 21 13:23:01 soil3 systemd[1]: Started iptables firewall.
iptables-save
# Generated by iptables-save v1.4.21 on Sun Feb 21 13:23:16 2016
*mangle
:PREROUTING ACCEPT [5871729:1516232162]
:INPUT ACCEPT [5871729:1516232162]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [3163323:7523867875]
:POSTROUTING ACCEPT [3163323:7523867875]
COMMIT
# Completed on Sun Feb 21 13:23:16 2016
# Generated by iptables-save v1.4.21 on Sun Feb 21 13:23:16 2016
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [15053:1147666]
:DROPLOG - [0:0]
:LIMITLOG - [0:0]
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state INVALID -j DROPLOG
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 113 -m state --state NEW -j REJECT --reject-with tcp-reset
-A INPUT -m addrtype --dst-type BROADCAST -j DROP
-A INPUT -m state --state UNTRACKED -j LOG --log-prefix "IPT-UNTRACKED: " --log-level 6
-A INPUT -p icmp -m icmp --icmp-type 3 -m limit --limit 10/sec -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 8 -m limit --limit 10/sec -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 11 -m limit --limit 10/min -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 12 -m limit --limit 10/min -j ACCEPT
-A INPUT -p icmp -j LIMITLOG
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -m limit --limit 3/sec -j ACCEPT
-A INPUT -m limit --limit 3/sec -j LOG --log-prefix "IPT-IN-DROP: " --log-level 6
-A INPUT -j DROP
-A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A OUTPUT -o lo -j ACCEPT
-A DROPLOG -m limit --limit 3/sec -j LOG --log-prefix "IPT-DROPLOG: " --log-level 6
-A DROPLOG -j DROP
-A LIMITLOG -m limit --limit 3/sec -j LOG --log-prefix "IPT-LIMITLOG: " --log-level 6
-A LIMITLOG -j DROP
COMMIT
# Completed on Sun Feb 21 13:23:16 2016