| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704 |
- #!/bin/dash
- ### BEGIN INIT INFO
- # Provides: firewall.sh
- # Required-Start: $syslog $network
- # Required-Stop: $syslog $network
- # Default-Start: 2 3 4 5
- # Default-Stop: 0 1 6
- # Short-Description: Start firewall daemon at boot time
- # Description: Custom Firewall scrip.
- ### END INIT INFO
- #
- # Light Firewall configuration.
- #
- # Original author : Nicolargo
- #
- # chkconfig: 2345 9 91
- # description: Activates/Deactivates the firewall at boot time
- #
- has_parent_process(){
- local parent_to_search
- local ppid
- parent_to_search="${1:-}"
- if [ -z "${parent_to_search:-}" ]
- then
- echo "ERROR: need parent process pid as first arg" >&2
- return 5
- fi
- local pid
- pid="${2:-}"
- if [ -z "${pid:-}" ]
- then
- pid=$$
- fi
- if [ $parent_to_search = $pid ]
- then
- echo ${parent_to_search}
- return 0
- else if [ $pid > 1 ]
- then
- ppid=$(ps --pid ${pid} -o ppid= | xargs)
- if [ $ppid = $pid ]
- then
- echo "ERROR: pid=$pid is the same as ppid=$ppid" >&2
- echo -1
- else
- has_parent_process ${parent_to_search} ${ppid}
- fi
- else
- echo "NOT FOUND: ${parent_to_search}" >&2
- echo 1
- fi
- fi
- return 1
- }
- find_pid_user_of(){
- local used_file=$1
- local regex="$2"
- lsof ${used_file} | awk 'NR>1 && $1 ~ /'${regex}'/ && !($2 in a){a[$2]++; print $2}'
- }
- find_systemctl_pids(){
- ps -elf | grep 'systemctl' | grep -v grep | awk '{print $13}' | sort -u | while read term
- do
- #echo "$term ---"
- #lsof /dev/$term
- #lsof -F 'cp' /dev/$term
- #echo "$term >>>"
- #lsof /dev/$term | awk 'NR>1 && $1 ~ /.*sh$/ && !($2 in a){a[$2]++; print $2}'
- if [ -z "${shell_pid:-}" ]
- then
- shell_pid=$(find_pid_user_of /dev/$term '.*sh$')
- fi
- if [ -z "${systemctl_pid:-}" ]
- then
- systemctl_pid=$(find_pid_user_of /dev/$term 'systemctl')
- fi
- #echo "shell_pid=$shell_pid" >&2
- #echo "systemctl_pid=$systemctl_pid" >&2
- echo ${shell_pid} ${systemctl_pid}
- #echo "TEST:$term" > /dev/$term
- done
- }
- #echo "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
- #declare -g shell_pid=""
- #declare -g systemctl_pid=""
- #ps -elf | grep 'systemctl' | grep -v grep | awk '{print $13}' | sort -u | while read term ; do echo "$term"; lsof /dev/$term ; echo "TEST:$term" > /dev/$term ; done
- process_and_parent=`find_systemctl_pids`
- if has_parent_process ${process_and_parent}
- then
- shell_process=$(echo ${process_and_parent} | awk '{print $1}')
- parent_term=`readlink /proc/${shell_process}/fd/2`
- fi
- echo "Parent terminal: ${parent_term}"
- #echo "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
- set -eu #o pipefail
- help_message_lfirewall(){
- cat <<-EOF
- Light Firewall configuration script.
- $(basename ${0}) [OPTIONS...] COMMAND
- COMMANDS
- start : starts the firewall
- stop : stops the firewall (removes rules set by this script)
- clear : clears the firewall (removes all IPTABLES rules and let all connections work)
- dropall : drops all network connections (USE with CAUTION)
- test : tests the existing rules for 30 seconds
- saveuser : backup of the user (custom) rules
- OPTIONS
- -v --verbose : verbose mode
- -h --help : display this help message
- -l --logging : enables logging (prefix: iptables-logging)
- BACKING UP USER RULES
- WARNING: PLEASE FOLLOW CAREFULLY THE ACTIONS BELOW
- 1. Before setting any rule: clear the firewall
- 2. Setup your rules
- 3. run:
- $(basename ${0}) saveuser
- AUTHOR
- Author: Laurent Hubert
- Idea by: Nicolargo
- EOF
- }
- options=$(getopt -l "help,verbose,logging" -o "hvl" -- "$@")
- if [ $? != 0 ] ; then
- help_message_lfirewall
- exit 1
- fi
- eval set -- "$options"
- IT_INPUT=INPUT
- IT_INPUT_LOG=LOGINPUT
- IT_OUTPUT=OUTPUT
- IT_OUTPUT_LOG=LOGOUTPUT
- verbose=0
- logging=" "
- while :
- do
- if [ ${verbose} = "1" ] ; then
- echo "$@"
- fi
- case "$1" in
- -h|--help)
- help_message_lfirewall
- exit 0
- ;;
- -v|--verbose)
- verbose=$(( verbose + 1 ))
- if [ ${verbose} -gt 1 ]
- then
- set -x
- fi
- if [ ${verbose} -gt 2 ]
- then
- set -v
- fi
- ;;
- -l|--logging)
- logging="-j LOG --log-prefix 'iptables-logging'"
- IT_INPUT=${IT_INPUT_LOG}
- IT_OUTPUT=${IT_OUTPUT_LOG}
- ;;
- --)
- shift
- break
- ;;
- esac
- shift
- done
- PATH=/bin:/sbin:/usr/bin:/usr/sbin
- #Defautl network interface
- NETWORK_IF=eth0
- # Services that the system will offer to the network
- TCP_SERVICES="22" # SSH only
- UDP_SERVICES=""
- # Services the system will use from the network
- REMOTE_TCP_SERVICES="80 443" # web browsing
- REMOTE_UDP_SERVICES="53" # DNS
- # Network that will be used for remote mgmt
- # (if undefined, no rules will be setup)
- # NETWORK_MGMT=192.168.0.0/24
- # Port used for the SSH service, define this is you have setup a
- # management network but remove it from TCP_SERVICES
- SSH_PORT="22"
- # Default IP_TABLES command path
- IP_TABLES="/sbin/iptables"
- IP_TABLES_RESTORE="/sbin/iptables-restore"
- IP_TABLES_RESTORE_6="/sbin/ip6tables-restore"
- IP_TABLES_SAVE="/sbin/iptables-save"
- IP_TABLES_SAVE_6="/sbin/ip6tables-save"
- if ! [ -x $IP_TABLES ]; then
- echo "$IP_TABLES is not executable or not present" >&2
- exit 1
- fi
- if ! [ -x $IP_TABLES_RESTORE ]; then
- echo "$IP_TABLES_RESTORE is not executable or not present" >&2
- exit 3
- fi
- if ! [ -x $IP_TABLES_RESTORE_6 ]; then
- echo "$IP_TABLES_RESTORE_6 is not executable or not present" >&2
- exit 6
- fi
- CONFIGURATION_DIR=/etc/lfirewall
- CONFIGURATION_FILE=${CONFIGURATION_DIR}/lfirewall.conf
- CONFIGURATION_LOCAL_FILE=${CONFIGURATION_DIR}/lfirewall.conf.local
- USER_RULES_IPTABLES=${CONFIGURATION_DIR}/iptables-user.v4
- USER_RULES_IPTABLES_6=${CONFIGURATION_DIR}/iptables-user.v6
- if [ -f $CONFIGURATION_FILE ] ; then
- set +u
- . $CONFIGURATION_FILE
- set -u
- fi
- if [ -f $CONFIGURATION_LOCAL_FILE ] ; then
- set +u
- . $CONFIGURATION_LOCAL_FILE
- set -u
- fi
- if ! /usr/sbin/ifup --no-act $NETWORK_IF > /dev/null 2>&1
- then
- echo "Network interface '$NETWORK_IF' is not present or configured" >&2
- exit 2
- fi
- IPTABLES_CHECK=__iptables_check_action
- IPTABLES_ADD=__iptable_add_action
- IPTABLES_INSERT=__iptable_insert_action
- IPTABLES_SET_POLICY=__iptable_set_policy_action
- export IP_TABLES
- export NETWORK_IF
- do_exec () {
- case $1 in
- __iptable_add_action)
- shift
- iptables_option=-A
- ;;
- __iptable_insert_action)
- shift
- iptables_option=-I
- ;;
- __iptable_set_policy_action)
- shift
- iptables_option=-P
- ;;
- *)
- echo "Nothing to be done for $1"
- ;;
- esac
- if [ ${verbose} -ge 1 ] ; then
- echo $IP_TABLES $iptables_option $*
- fi
- $IP_TABLES $iptables_option $*
- }
- do_check () {
- the_action=$1
- shift
- case $the_action in
- __iptable_add_action)
- iptables_option=-A
- ;;
- __iptable_insert_action)
- iptables_option=-I
- ;;
- __iptable_set_policy_action)
- return 0
- ;;
- *)
- echo "Nothing to be done for $1"
- ;;
- esac
- default_option=-C
- if [ ${verbose} -ge 1 ] ; then
- echo $do_log "$the_action:" $IP_TABLES -C $*
- echo $IP_TABLES -C $*
- fi
- $do_log "$the_action:" $IP_TABLES -C $*
- $IP_TABLES -C $*
- global_status=$((global_status+$?))
- }
- log_action () {
- echo $*
- }
- do_not_log_action () {
- return 0
- }
- do_log=do_not_log_action
- ##########################
- # Drops INPUT
- ##########################
- fw_exec_basic_input_rules(){
- local do_action
- do_action=$1
- ### Blocks any incoming
- $do_action $IPTABLES_SET_POLICY $IT_INPUT DROP
- ### Keep existing connections
- $do_action $IPTABLES_ADD $IT_INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
- # Remote testing
- ### Allows PING
- $do_action $IPTABLES_ADD $IT_INPUT -p icmp -j ACCEPT
- ### Allows LOOPBACK
- $do_action $IPTABLES_ADD $IT_INPUT -i lo -j ACCEPT
- }
- ##########################
- # Executes the Firewall rules
- ##########################
- fw_execute () {
- local do_action
- do_action=$1
- #**************************************************************************#
- # Input traffic:
- #**************************************************************************#
- fw_exec_basic_input_rules $do_action
- # Services
- if [ -n "$TCP_SERVICES" ] ; then
- for PORT in $TCP_SERVICES; do
- $do_action $IPTABLES_ADD $IT_INPUT -p tcp --dport ${PORT} -j ACCEPT
- done
- fi
- if [ -n "$UDP_SERVICES" ] ; then
- for PORT in $UDP_SERVICES; do
- $do_action $IPTABLES_ADD $IT_INPUT -p udp --dport ${PORT} -j ACCEPT
- done
- fi
- # Remote management
- if [ "${NETWORK_MGMT:=UNBOUND_VARIABLE}" != "UNBOUND_VARIABLE" ] ; then
- $do_action $IPTABLES_ADD $IT_INPUT -p tcp --src ${NETWORK_MGMT} --dport ${SSH_PORT} -j ACCEPT
- else
- $do_action $IPTABLES_ADD $IT_INPUT -p tcp --dport ${SSH_PORT} -j ACCEPT
- fi
- # SSH
- if [ ! -z "${SSH_PORT:-}" ] ; then
- $do_action $IPTABLES_ADD $IT_OUTPUT -t filter -p tcp --dport "$SSH_PORT" -j ACCEPT
- $do_action $IPTABLES_ADD $IT_INPUT -t filter -p tcp --dport "$SSH_PORT" -j ACCEPT
- else
- $do_action $IPTABLES_ADD $IT_OUTPUT -t filter -p tcp --dport "22" -j ACCEPT
- $do_action $IPTABLES_ADD $IT_INPUT -t filter -p tcp --dport "22" -j ACCEPT
- fi
- #**************************************************************************#
- # NGINX
- #**************************************************************************#
- $do_action $IPTABLES_ADD $IT_INPUT -i lo -s localhost -d localhost -j ACCEPT
- $do_action $IPTABLES_ADD $IT_OUTPUT -o lo -s localhost -d localhost -j ACCEPT
- #**************************************************************************#
- # Output:
- #**************************************************************************#
- ### Allows LOOPBACK
- $do_action $IPTABLES_ADD $IT_OUTPUT -j ACCEPT -o lo
- ###
- $do_action $IPTABLES_ADD $IT_OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
- # ICMP is permitted:
- ### Allows ping:
- $do_action $IPTABLES_ADD $IT_OUTPUT -p icmp -j ACCEPT
- # As well as the services we have defined:
- if [ -n "$REMOTE_TCP_SERVICES" ] ; then
- for PORT in $REMOTE_TCP_SERVICES; do
- $do_action $IPTABLES_ADD $IT_OUTPUT -p tcp --dport ${PORT} -j ACCEPT
- done
- fi
- if [ -n "$REMOTE_UDP_SERVICES" ] ; then
- for PORT in $REMOTE_UDP_SERVICES; do
- $do_action $IPTABLES_ADD $IT_OUTPUT -p udp --dport ${PORT} -j ACCEPT
- done
- fi
- if [ "${ACTIVATE_LOGGING:-1}" = 1 ]
- then
- # All other connections are registered in system log's backend
- $do_action $IPTABLES_ADD $IT_INPUT -j LOG
- $do_action $IPTABLES_ADD $IT_OUTPUT -j LOG
- $do_action $IPTABLES_ADD $IT_OUTPUT -j REJECT
- $do_action $IPTABLES_ADD FORWARD -j LOG
- fi
- $do_action $IPTABLES_SET_POLICY $IT_OUTPUT DROP
- #**************************************************************************#
- # DOS attack protection
- #**************************************************************************#
- # See http://rockdio.org/ayudatech/how-to-stop-small-ddos-attacks-some-basic-security-advice/
- #
- $do_action $IPTABLES_INSERT $IT_INPUT -p tcp --dport 80 -i $NETWORK_IF -m state --state NEW -m recent --set
- $do_action $IPTABLES_INSERT $IT_INPUT -p tcp --dport 80 -i $NETWORK_IF -m state --state NEW -m recent --update --seconds 30 --hitcount 20 -j DROP
- $do_action $IPTABLES_INSERT $IT_INPUT -p tcp --dport 443 -i $NETWORK_IF -m state --state NEW -m recent --set
- $do_action $IPTABLES_INSERT $IT_INPUT -p tcp --dport 443 -i $NETWORK_IF -m state --state NEW -m recent --update --seconds 30 --hitcount 20 -j DROP
- }
- fw_network_protection(){
- #**************************************************************************#
- # Other network protections
- # (some will only work with some kernel versions)
- #**************************************************************************#
- if [ "${ALLOW_IP_FORWARDING:-0}" = 0 ]
- then
- echo 0 > /proc/sys/net/ipv4/ip_forward
- else
- echo 1 > /proc/sys/net/ipv4/ip_forward
- fi
- if [ "${NETWORK_PROTECTION:-1}" = 1 ]
- then
- echo 1 > /proc/sys/net/ipv4/tcp_syncookies
- echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
- echo 1 > /proc/sys/net/ipv4/conf/all/log_martians
- echo 1 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses
- echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter
- echo 0 > /proc/sys/net/ipv4/conf/all/send_redirects
- echo 0 > /proc/sys/net/ipv4/conf/all/accept_source_route
- echo "Firewall network protection enhancement set"
- fi
- }
- do_this(){
- if [ ${verbose} -ge 1 ] ; then
- echo $*
- fi
- $*
- }
- translate_iptables_rule(){
- echo $* | sed -e 's/'$IPTABLES_ADD'/-A/g' -e 's/'$IPTABLES_INSERT'/-I/g' -e 's/'$IPTABLES_SET_POLICY'/-P/g'
- }
- ##########################
- # Backups user rules
- ##########################
- fw_backup_user(){
- $IP_TABLES_SAVE > ${USER_RULES_IPTABLES}
- $IP_TABLES_SAVE_6 > ${USER_RULES_IPTABLES_6}
- }
- ##########################
- # Restores user rules
- ##########################
- fw_restore_user(){
- if [ -f $USER_RULES_IPTABLES ] ; then
- $IP_TABLES_RESTORE < ${USER_RULES_IPTABLES}
- fi
- if [ -f $USER_RULES_IPTABLES_6 ] ; then
- $IP_TABLES_RESTORE_6 < ${USER_RULES_IPTABLES_6}
- fi
- }
- ##########################
- # Stop the Firewall rules
- ##########################
- do_delete () {
- the_action=$1
- shift
- if [ ${verbose} -gt 1 ] ; then
- $do_log "Trying to delete:" $(translate_iptables_rule $IP_TABLES $the_action $*)
- fi
- case $the_action in
- __iptable_add_action)
- iptables_option=-D
- ;;
- __iptable_insert_action)
- iptables_option=-D
- ;;
- __iptable_set_policy_action)
- CHAIN_NAME="$1"
- $do_log "DELETING: $IP_TABLES -P $CHAIN_NAME DROP"
- $IP_TABLES -P $CHAIN_NAME ACCEPT
- return 0
- ;;
- *)
- echo "Nothing to be done for $1"
- ;;
- esac
- # Checks the rule then delete it, if it exists
- if $IP_TABLES -C $* > /dev/null 2>&1
- then
- $IP_TABLES $iptables_option $* || echo "DID NOT EXIST: "$IP_TABLES $iptables_option $*
- $do_log "DELETING:" $IP_TABLES $iptables_option $*
- else
- $do_log "NOT EXISTING:" $IP_TABLES $iptables_option $*
- fi
- global_status=$((global_status+$?))
- }
- fw_stop () {
- global_status=0
- # Start will not really start but exec the "do_delete" action
- fw_execute do_delete
- if [ 0 -eq "$global_status" ] ; then
- echo "Firewall rules removed"
- return 0
- else
- echo "Some firewall rules were not removed !!!"
- return $global_status
- fi
- }
- ##########################
- # Drop any incoming
- # but keep existing ones
- ##########################
- fw_dropall(){
- do_this $IP_TABLES -F
- do_this $IP_TABLES -t nat -F
- do_this $IP_TABLES -t mangle -F
- fw_exec_basic_input_rules do_exec
- do_this $IP_TABLES -P FORWARD ACCEPT
- do_this $IP_TABLES -P OUTPUT ACCEPT
- }
- ##########################
- # Clear the Firewall rules
- ##########################
- fw_clear () {
- do_this $IP_TABLES -F
- do_this $IP_TABLES -X
- do_this $IP_TABLES -P INPUT ACCEPT
- do_this $IP_TABLES -P FORWARD ACCEPT
- do_this $IP_TABLES -P OUTPUT ACCEPT
- }
- ##########################
- # Test the Firewall rules
- ##########################
- fw_save () {
- if [ ${verbose} -ge 1 ] ; then
- echo "$IP_TABLES_SAVE > /etc/lfirewall/iptables.backup"
- fi
- $IP_TABLES_SAVE > /etc/lfirewall/iptables.backup
- }
- fw_restore () {
- fw_clear
- BACKUP_FILE=/etc/lfirewall/iptables.backup
- if [ -e $BACKUP_FILE ]; then
- if [ ${verbose} -ge 1 ] ; then
- echo "IP_TABLES_RESTORE > $BACKUP_FILE"
- fi
- $IP_TABLES_RESTORE < $BACKUP_FILE
- fi
- }
- fw_test () {
- fw_save
- sleep 30 && echo "Restoring previous Firewall rules" && fw_restore && echo "Done" &
- fw_stop
- fw_execute do_exec
- wait $(jobs -p)
- }
- if [ ${verbose} -gt 0 ] ; then
- do_log=log_action
- fi
- case "$1" in
- start|restart)
- echo -n "Starting firewall.."
- fw_stop
- fw_restore_user
- fw_execute do_exec
- echo "Firewall rules added"
- fw_network_protection
- echo "done."
- ;;
- saveuser)
- echo "###############################################################"
- echo "# Backing up user rules to /etc/lfirewall/iptables-user.v* #"
- echo "# #"
- echo "# Other iptables rules should not be removed unless you use #"
- echo "# the 'clear' command (which deletes every rule) #"
- echo "# If you used the 'clear' command, you can restore them by #"
- echo "# using the 'start' command to restore them #"
- echo "###############################################################"
- echo -n "Backing up rules"
- fw_backup_user
- echo "done."
- ;;
- stop)
- echo "###############################################################"
- echo "# Removing rules set by this tool #"
- echo "# #"
- echo "# Other iptables rules should not be removed unless you use #"
- echo "# the 'clear' command #"
- echo "# Use 'dropall' to stop any traffic and block everything. #"
- echo "###############################################################"
- fw_stop
- ;;
- clear)
- echo "###############################################################"
- echo "# Clearing any rule and let the firewall pass any packet #"
- echo "# #"
- echo "# You can restore them by using the 'start' command #"
- echo "###############################################################"
- echo -n "Clearing firewall rules.."
- fw_clear
- echo "done."
- ;;
- dropall)
- echo "Droping all connections !!!"
- fw_dropall
- echo "done."
- if [ -n "${parent_term}" ]
- then
- exec 2>${parent_term}
- fi
- echo "###############################################################" >&2
- echo "# IMPORTANT WARNING !!! #" >&2
- echo "# From now any new SSH session or INPUT #" >&2
- echo "# WILL BE REFUSED #" >&2
- echo "# If you NEED to continue working remotely, #" >&2
- echo "# run one of the 'lfirewall clear', 'lfirewall stop' #" >&2
- echo "# 'lfirewall start' commands #" >&2
- echo "# NOW !!! #" >&2
- echo "###############################################################" >&2
- ;;
- test)
- echo "Test Firewall rules..."
- echo "Previous configuration will be restore in 30 seconds"
- fw_test
- ;;
- status)
- global_status=0
- # Start will not really start but exec the "check" action
- fw_execute do_check
- if [ 0 -eq "$global_status" ] ; then
- echo "Firewall rules match configuration"
- exit 0
- else
- echo "Some firewall rules are not set correctly"
- exit $global_status
- fi
- ;;
- *)
- echo "Usage: $0 {start|dropall|stop|restart|clear|test}"
- echo "###############################################################"
- echo "# Be aware that 'dropall' will block #"
- echo "# all incoming/outgoing traffic !!! #"
- echo "###############################################################"
- echo "Use start option to restore all rules."
- echo "Use clear option to remove all traffic."
- echo "Use stop option to allow all traffic."
- exit 1
- ;;
- esac
|