commit 2ae72cdfd523984d5739f47521b9042c52de8c96 Author: Jarno Rankinen Date: Sun Feb 7 13:45:36 2021 +0200 initial commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..38243c7 --- /dev/null +++ b/README.md @@ -0,0 +1,48 @@ +# jfw +### iptables control system + +##### What is it? +This is my take on replacing the rc.local -method of configuring `iptables` at +startup. + +##### How to install? +Clone the repo and make `install.bash` and `jfw.rules` executable, then run +`install.bash` as root. + +When you run `install.bash`, the script copies the file `jfw.rules` to +`/etc/jfw/`, makes a symlink to it in `/usr/sbin` and copies the included +`jfw.service` systemd service file to `/etc/systemd/system/`. + +You have the option to enable & start the service right away or do it later +yourself using systemctl. + +`jfw.rules` is basically just a list of iptables commands, with a couple of +predefined parameters. The systemd service runs the script at startup. + +Outbound traffic, inbound MDNS and inbound SSH are allowed by default. + +##### How to uninstall? +If you haven't already, clone the repo, make `uninstall.bash`executable` +and run `uninstall.bash`. + +##### Why use this? +The traditional method of using `/etc/rc.local` to run your init scripts +is deprecated by many distros. This is just another way to configure iptables. + +There are a couple of handy parameters to the `jfw` command: +- `jfw flush` flushes the rules and disables the firewall +- `jfw edit` is an alias to edit `/etc/jfw/jfw.rules` with your defined $EDITOR +- `jfw logs` greps `dmesg` to show the logs +- `jfw list` shows the currently active `iptables` rules for IPv4 and IPv6 +- `jfw test` applies your ruleset and automatically flushes the rules after + 60 seconds. Just remember to use `nohup`, `screen` or `tmux` so the script + will continue running even if your connection breaks. +- `jfw reload` resets the rules to those defined in `/etc/jfw/jfw.rules` + This is useful when modifying the rules remotely so you don't get locked out. + +##### Why not use this? +If you are unsure about the methods I've used, don't use these scripts. +Ask someone if it is safe to use them. +If you have no idea how to use `iptables`, then this might not be the easiest +way to control the Linux firewall. My personal favourite of the more +comprehensive firewall programs is `firewalld`. diff --git a/install.bash b/install.bash new file mode 100755 index 0000000..f8e5daa --- /dev/null +++ b/install.bash @@ -0,0 +1,44 @@ +#!/bin/bash + +# root check +if [[ "$UID" -ne 0 ]]; then + echo "This script needs root permissions." + exit 1 +fi + +# Make /etc/jfw directory with "rules" file +# (which is really the iptables script) +if [[ -f /etc/jfw/jfw.rules ]]; then + echo "Found existing jfw configuration, do you wish to overwrite (y/n)?" + read -n 1 + if [[ "$REPLY" == "y" ]];then + echo "Overwriting '/etc/jfw/jfw.rules'" + cp jfw.rules /etc/jfw/ + chmod -R 700 /etc/jfw + else + echo "Not overwriting '/etc/jfw/jfw.rules' ." + fi +else + mkdir -p /etc/jfw + cp jfw.rules /etc/jfw/ + chmod -R 700 /etc/jfw +fi + +# Create symlink to jfw.rules: +ln -s /etc/jfw/jfw.rules /usr/sbin/jfw + +# Install systemd service file, +# Still needs to be enabled automatically +cp jfw.service /etc/systemd/system +systemctl daemon-reload + +echo "SSH port (22) is opened by default with JFW." +read -p "Enable & start JFW now (yes/no)? " + +if [[ "$REPLY" == "yes" ]]; then + systemctl enable --now jfw +else + echo "You can edit the iptables rules to your liking by editing" + echo "'/etc/jfw/jfw.rules'. Afterwards you can use systemct to start" + echo "and/or enable the firewall." +fi diff --git a/jfw.rules b/jfw.rules new file mode 100755 index 0000000..7eac666 --- /dev/null +++ b/jfw.rules @@ -0,0 +1,134 @@ +#!/bin/bash + +PATH="/usr/sbin:/sbin:/usr/bin:/bin" + +flush() { + iptables -P INPUT ACCEPT + iptables -P OUTPUT ACCEPT + iptables -P FORWARD ACCEPT + iptables -F INPUT + iptables -F OUTPUT + iptables -F FORWARD + iptables -F -t nat + iptables -F -t mangle + + ip6tables -P INPUT ACCEPT + ip6tables -P OUTPUT ACCEPT + ip6tables -P FORWARD ACCEPT + ip6tables -F INPUT + ip6tables -F OUTPUT + ip6tables -F FORWARD + ip6tables -F -t nat + ip6tables -F -t mangle +} + +if [[ "$1" == "flush" ]]; then + flush + echo "Firewall rules flushed." + exit 0 +elif [[ "$1" == "edit" ]]; then + sudoedit /etc/jfw/jfw.rules && systemctl reload jfw.service + echo "Firewall rules updated." + exit 0 +elif [[ "$1" == "logs" ]]; then + dmesg -T | grep JFW + exit 0 +elif [[ "$1" == "list" ]]; then + echo "********** IPv4 **********" + iptables -S -v + echo "********** IPv6 **********" + ip6tables -S -v + exit 0 +fi + +flush + +######### +# IPv4 # +######### + +## Loop device +iptables -A INPUT -i lo -j ACCEPT + +## Ping, router advertisements etc +iptables -A INPUT -p icmp -j ACCEPT +iptables -A INPUT -p ALL -d 224.0.0.1 -j ACCEPT + +## established inbound +iptables -A INPUT -p ALL -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT + +## MDNS +iptables -A INPUT -p udp --dport 5353 -j ACCEPT + +## Wireguard network +## Replace AND +#iptables -A INPUT -p udp --dport -j ACCEPT +#iptables -A INPUT -i -j ACCEPT + +## SSH access +iptables -A INPUT -p tcp --dport 22 -j ACCEPT + +## Logging and dropping other inbound packets +## "log lines" may generate too much log entries +## uncomment the following lines to enable logging +#iptables -A INPUT -p ALL -j LOG --log-prefix "JFW IPv4 DROP::" +#iptables -A INPUT -p ALL -j DROP + + +## Default policies for IPv4 +iptables -P INPUT DROP +iptables -P OUTPUT ACCEPT +iptables -P FORWARD DROP + + + + + + +######## +# IPv6 # +######## + +## Loop device +ip6tables -A INPUT -i lo -j ACCEPT + +## Ping, router advertisements etc +ip6tables -A INPUT -p icmpv6 -j ACCEPT + +## established inbound +ip6tables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT + +## MDNS +ip6tables -A INPUT -p udp --dport 5353 -j ACCEPT + +## Wireguard network +## Replace and and uncomment the following lines +#ip6tables -A INPUT -p udp --dport -j ACCEPT +#ip6tables -A INPUT -i -j ACCEPT + +## Logging and dropping other inbound packets +## "log lines" may generate too much log entries +## uncomment the following lines to enable logging +# ip6tables -A INPUT -p ALL -j LOG --log-prefix "JFW IPv6 DROP::" +# ip6tables -A INPUT -p ALL -j DROP + +## Default policies for IPv6 +ip6tables -P INPUT DROP +ip6tables -P OUTPUT ACCEPT +ip6tables -P FORWARD DROP + + + + +## test-parameter for testing, flushes rules after 60 seconds +## reload for resetting temporary changes to those defined in this file +if [[ "$1" == "test" ]]; then + sleep 60 + flush + echo "Firewall test finished, rules flushed." + exit 0 +elif [[ "$1" == "reload" ]]; then + echo "Firewall rules reloaded." + exit 0 +fi + diff --git a/jfw.service b/jfw.service new file mode 100644 index 0000000..2a51060 --- /dev/null +++ b/jfw.service @@ -0,0 +1,12 @@ +[Unit] +Description=iptables rules +After=network.target + +[Service] +ExecStart=/etc/jfw/jfw.rules +ExecStop=/etc/jfw/jfw.rules flush +ExecReload=/etc/jfw/jfw.rules +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/uninstall.bash b/uninstall.bash new file mode 100755 index 0000000..369567d --- /dev/null +++ b/uninstall.bash @@ -0,0 +1,33 @@ +#!/bin/bash + +if [[ "$UID" -ne 0 ]]; then + echo "This script must be run as root." + exit 1 +fi + +echo "This will uninstall the jfw executable, systemd service and flush" +echo "your iptables & ip6tables rules." +read -n 1 -p "Proceed with uninstallation (y/n)? " + +if [[ $REPLY == "y" ]]; then + unset $REPLY + printf "\n" + jfw flush + systemctl disable --now jfw.service + rm -f /etc/systemd/system/jfw.service + systemctl daemon-reload + rm -f /usr/sbin/jfw + + read -n 1 -p "Remove '/etc/jfw/jfw.rules' (y/n)? " + printf "\n" + [[ "$REPLY" == "y" ]] && rm -rf /etc/jfw + [[ "$REPLY" != "y" ]] && echo "Keeping '/etc/jfw/jfw.rules'" + + echo "JFW succesfully removed!" + exit 0 + +else + echo "Aborting uninstallation." + exit 1 +fi +