Skip to content

Instantly share code, notes, and snippets.

@raitonoberu
Created November 14, 2024 10:41
Show Gist options
  • Select an option

  • Save raitonoberu/3ee68a70687698ba454e5fec35e3f508 to your computer and use it in GitHub Desktop.

Select an option

Save raitonoberu/3ee68a70687698ba454e5fec35e3f508 to your computer and use it in GitHub Desktop.
iptables-based firewall with systemd service
#!/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
@raitonoberu
Copy link
Author

Задание: написать скрипт, который строит таблицу правил файрвола (на выбор iptables или ipfw). на вход подается файлик, с перечнем ресурсов (адреса или урлы), все переичесленные ресурсы должны блокироваться файрволом. остальное разрешено. Результат работы должен сохраняться при перезагрузке как файрвола, так и системы.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment