11 May 2009

Remote Firewall HOWTO

Zdarza się, że administrator systemu musi zmienić reguły firewalla nie mając fizycznego dostępu do komputera. Sytuacja taka jest dosyć niebezpieczna, ponieważ jedna źle skonstruowana reguła może odciąć dostęp do zdalnego systemu. Poniżej chciałbym przedstawić jeden ze sposobów w miarę bezpiecznego przeprowadzania takiej operacji.

Całość opiera się na skrypcie w języku Bash, powodującym zresetowanie ustawień firewalla jeśli choć jedna zakończy się niepowodzeniem. By nie pisać wiele wstępu, przedstawię kod:
#!/bin/bash

IFS=$'\n'

# output iface
NET_ETH=eth0 

# disable all comands tools we have to use absolute paths
export PATH=""

# Clean up all chains
flush() {
 echo "Setting Accept Policy for all chains ..."
 /sbin/iptables -F
 /sbin/iptables -Z
 /sbin/iptables -X
 /sbin/iptables -P INPUT ACCEPT
 /sbin/iptables -P OUTPUT ACCEPT
 /sbin/iptables -P FORWARD ACCEPT
 
 # czysczenie tablic nat mangle filter
 echo "Flushing all modules ..."
 for table in nat mangle filter ; do
  /sbin/iptables -t $table -F
  /sbin/iptables -t $table -X
 done
 echo "Firewall is now very unoptimized"
}

# iptables command wrapper - if wrong rule - flush
iptables() {
 /sbin/iptables $@
 if [ $? -ne 0 ] ; then
  echo 'Error: >> iptables' $@
  # zeby sie nie odciac z powodu zlej regulki
  flush
  exit 1;
 fi
}

# sysctl wrapper
sysctl() { 
 /sbin/sysctl $@ > /dev/null
}

# modprobe wrapper
modprobe() {
 /sbin/modprobe $@
 if [ $? -ne 0 ] ; then
  echo "Error: loading module "$@
  exit 1;
 fi
}

# do init - add chains, load modules, config sysctls
init() {
 echo "Loading kernel modules ..."
 # start initializations
 echo "Initializing default settings ..."
 # TODO: Add code here
}

# set default policy
policy() {
 echo "Setting firewall default policy ..."
 # TODO: Add default policy
}

# do connect all parts (my fw has few chains here i'm connecting it)
# you can write your rules here
connect() {
 # TODO: Apply firewall rules here
}

##
## MAIN
##
echo -ne "Simple firewall script\n"

if [ $# -lt 1 ] ;then
 echo "usage: $1 [start|stop]"
 exit
fi

case "$1" in
 start ) flush
  policy
  init
  connect ;;
 stop) flush;;
 *)  echo "Wrong arg $1";;
  #flush;;
esac
To chyba na tyle ;). Skrypt działa na pewno sam czasami tego rozwiązania używam, ale trochę bardziej rozbudowanego niemniej jednak cała idea jest taka sama. Czyli każde wywołanie iptables jest opakowane w funkcje i w tej funkcji jest sprawdzany returncode - jeśli jest różny od zero - coś poszło nie tak - następuje reset ustawień.

Jak można rozwinąć skrypt?

  • Dodać regułki iptables
  • Dodać kod pozwalający sprawdzić czy możliwe jest połączenie się po ssh z serwerem
  • Ewentualnie przepisać to na wygodniejszy język (np. Perl)
  • Nie aplikować wszystkich reguł za każdym razem tylko te zmienione

No comments:

Post a Comment