Created
November 14, 2024 10:41
-
-
Save raitonoberu/3ee68a70687698ba454e5fec35e3f508 to your computer and use it in GitHub Desktop.
iptables-based firewall with systemd service
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| set -euo pipefail | |
| CHAIN_NAME=FIREWALL | |
| SERVICE_NAME=firewall.service | |
| SERVICE_PATH=/etc/systemd/system/$SERVICE_NAME | |
| EXECUTABLE_PATH=/usr/local/sbin/firewall | |
| INPUT_FILE=/etc/firewall_hosts | |
| function delete_chain() | |
| { | |
| iptables --delete OUTPUT -j $CHAIN_NAME || true | |
| iptables --flush $CHAIN_NAME || true | |
| iptables --delete-chain $CHAIN_NAME || true | |
| } | |
| function create_chain() | |
| { | |
| iptables --new $CHAIN_NAME | |
| iptables --append OUTPUT -j $CHAIN_NAME | |
| iptables --policy OUTPUT ACCEPT | |
| } | |
| function get_ips() | |
| { | |
| ip_or_host=$1 | |
| if [[ $ip_or_host =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then | |
| echo $ip_or_host | |
| return 0 | |
| fi | |
| getent ahostsv4 $ip_or_host | grep STREAM | cut -d ' ' -f 1 | |
| } | |
| function block_ip() | |
| { | |
| ip=$1 | |
| iptables --append $CHAIN_NAME --destination $ip --jump DROP | |
| } | |
| function check_root() | |
| { | |
| if [ "$EUID" -ne 0 ]; then | |
| echo "root please" | |
| return 1 | |
| fi | |
| } | |
| function apply() | |
| { | |
| if [ ! -f $INPUT_FILE ]; then | |
| echo "input file doesn't exist" | |
| return 1 | |
| fi | |
| create_chain | |
| while read -r ip_or_host | |
| do | |
| echo "# Blocking $ip_or_host" | |
| ips=`get_ips $ip_or_host` | |
| while read -r ip | |
| do | |
| echo "- $ip" | |
| block_ip $ip | |
| done <<< $ips | |
| done < $INPUT_FILE | |
| } | |
| function install() | |
| { | |
| if [ -f $SERVICE_PATH ]; then | |
| return 0 | |
| fi | |
| cp "$0" $EXECUTABLE_PATH | |
| chmod +x $EXECUTABLE_PATH | |
| cat > $SERVICE_PATH << EOF | |
| [Unit] | |
| Description=Firewall | |
| After=network.target | |
| [Service] | |
| Type=oneshot | |
| ExecStart=$EXECUTABLE_PATH start | |
| ExecStop=$EXECUTABLE_PATH stop | |
| ExecReload=$EXECUTABLE_PATH restart | |
| RemainAfterExit=yes | |
| [Install] | |
| WantedBy=multi-user.target | |
| EOF | |
| systemctl enable --now $SERVICE_NAME | |
| } | |
| function uninstall() | |
| { | |
| systemctl disable --now $SERVICE_NAME | |
| rm $SERVICE_PATH || true | |
| rm $EXECUTABLE_PATH || true | |
| } | |
| case "${1-}" in | |
| install) | |
| check_root | |
| install | |
| ;; | |
| uninstall) | |
| check_root | |
| uninstall | |
| ;; | |
| start) | |
| check_root | |
| apply | |
| ;; | |
| stop) | |
| check_root | |
| delete_chain | |
| ;; | |
| restart) | |
| check_root | |
| delete_chain | |
| apply | |
| ;; | |
| *) | |
| echo "Usage: {install|uninstall|start|stop|restart}" | |
| exit 1 | |
| esac |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Задание: написать скрипт, который строит таблицу правил файрвола (на выбор iptables или ipfw). на вход подается файлик, с перечнем ресурсов (адреса или урлы), все переичесленные ресурсы должны блокироваться файрволом. остальное разрешено. Результат работы должен сохраняться при перезагрузке как файрвола, так и системы.