Firewall con IPTABLES

Realizado por Jesus Lara y  Nerissa Aguilera

http://phenobarbital.gnu.org.ve/doku.php/weyu:firewall

firewall.sh
#!/bin/bash
####===============================================####
## Firewall v0.5
##
## Autor: Jesus Lara <jesuslara@gmail.com>
## Licencia: Licencia GNU/GPL.
##
## configuracion de un gateway-firewall basico
##
####===============================================####

#############################################################
## Configuracion de usuario

# Datos de las interfaces
EXTERNAL_INTERFACE="ppp0"
PPP="yes"

LAN_INTERFACE="eth0"
LOOPBACK_INTERFACE="lo"

# habilitar proxy
PROXY=1
PROXY_SERVER="192.168.1.1"
PROXY_PORT=3128

# habilitar transparent forward y NAT
NAT=1

## Puerto SSH
SSH_PORT=22

## otros puertos TCP (incluye razor,pyzor,amavis)
PUERTOS_TCP="109,110,995,993,2703,3128,5280,7777,5557,4369,8080,8000"
NEGADOS="1031,1038"

## Servidores DNS
DNS="8.8.8.8 208.67.222.222 200.35.65.5 200.35.65.4"

#############################################################
## Root needed

if [ "$UID" != "0" ]; then

 $CAT << _MSG

  ---------------------------------------
  | Advertencia:                        |
  | Solo el usuario root puede ejecutar |
  | Iptables y aplicar este firewall!   |
  |                                     |
  |             ALTO!                   |
  ---------------------------------------

_MSG

 exit 0

fi

#############################################################

COMMAND=$1
DIRECTORY="$(pwd)"

## ubicacion de comandos #######################
IPTABLES="$(which iptables)"
CAT="$(which cat)"
GREP="$(which grep)"
AWK="$(which awk)"
CAT="$(which cat)"
SED="$(which sed)"
IP="$(which ip)"
ROUTE="$(which route)"
IFCONFIG="$(which ifconfig)"
NETSTAT="$(which netstat)"
##########################

# == main execution ==

usage() {
    echo "Usage: $(readlink -f $0) {apply|clean|test}"
    exit 0
}

help() {
    cat <<EOF

Ejecuta un firewall basico en un sistema Debian GNU/Linux

EOF
}

# Main program

# si no pasamos ningun parametro
if [ $# = 0 ]; then
    usage
fi

net() {
#################################################
## prueba de que existen las interfaces
cat /proc/net/dev | grep $LAN_INTERFACE > /dev/null
LAN_CHECK=$?
if [ $LAN_CHECK -ne 0 ]; then
	echo "Firewall ERROR: no existe la interfaz $LAN_INTERFACE"
	exit 1
fi

# todo: test grep -q $EXTERNAL_INTERFACE /proc/net/dev
cat /proc/net/dev | grep $EXTERNAL_INTERFACE > /dev/null
NET_CHECK=$?
if [ $NET_CHECK -ne 0 ]; then
        echo "Firewall ERROR: no existe la interfaz $EXTERNAL_INTERFACE"
        exit 1
fi

#############################################################

#############################################################
## Descubrimiento de IPs

LAN_IPADDR="$($IP addr show $LAN_INTERFACE | awk "/^.*inet.*$LAN_INTERFACE\$/{print \$2}" | sed -n '1 s,/.*,,p')"
LAN_BCAST_ADDRESS=`$IFCONFIG $LAN_INTERFACE | grep -i "Bcast:" | cut -f3 -d: | cut -f1 -d " "`
LOCALNETMASK=`$IFCONFIG $LAN_INTERFACE | grep -i "Mask:" | cut -f4 -d: | cut -f1 -d " "`
LOCALNET=`$NETSTAT -rn | grep $LAN_INTERFACE | grep -i 'U[ \t]' | grep $LOCALNETMASK | awk '{print $1}' | cut -f1 -d " " | head -1`

if [ "$PPP"="yes" ]; then
IPADDR="$($IP addr show $EXTERNAL_INTERFACE | awk "/^.*inet.*$EXTERNAL_INTERFACE\$/{print \$2}" | cut -f1 -d " " | head -1)"
GATEWAY=`$NETSTAT -rn | grep $EXTERNAL_INTERFACE | grep -i 'UH[ \t]' | awk '{print $1}' | head -1`
NETMASK=`$IFCONFIG $EXTERNAL_INTERFACE | grep -i "Mask:" | cut -f4 -d: | cut -f1 -d " " | head -1`
NET="0.0.0.0"
else
IPADDR="$($IP addr show $EXTERNAL_INTERFACE | awk "/^.*inet.*$EXTERNAL_INTERFACE\$/{print \$2}" | sed -n '1 s,/.*,,p')"
GATEWAY=`$NETSTAT -rn | grep $EXTERNAL_INTERFACE | grep -i 'UG[ \t]' | awk '{print $2}' | head -1`
NETMASK=`$IFCONFIG $EXTERNAL_INTERFACE | grep -i "Mask:" | cut -f4 -d: | cut -f1 -d " " | head -1`
NET=`$NETSTAT -rn | grep $EXTERNAL_INTERFACE | grep -i 'U[ \t]' | grep $NETMASK | awk '{print $1}' | cut -f1 -d " " | head -1`
fi

BCAST_ADDRESS=`$IFCONFIG $EXTERNAL_INTERFACE | grep -i "Bcast:" | cut -f3 -d: | cut -f1 -d " "`

LOCALHOST_IP="127.0.0.1/32"
}

test() {
net
## Muestro un pequeño esquema de como esta
## nuestra configuracion actual de la red

$CAT << _MSG
 ************************** [ Info Firewall ] **************************
 *
 * Interfaz Publica : .............. $EXTERNAL_INTERFACE
 * Interfaz Privada : .............. $LAN_INTERFACE
 *
 * Red Publica : ................... $NET
 * IP Publica : .................... $IPADDR
 * Subnet Publica : ................ $NETMASK
 * Gateway : ....................... $GATEWAY
 *
 * Red Privada : ................... $LOCALNET
 * IP Privada : .................... $LAN_IPADDR
 * Subnet Privada : ................ $LOCALNETMASK
 *
 *
 ****************************************************************************
_MSG

}

# limpieza de reglas
clean() {
echo " ** [ Limpieza de Firewall ] ** "
# Limpiamos las cadenas INPUT y FORWARD
$IPTABLES -F INPUT
$IPTABLES -F FORWARD
$IPTABLES -F
$IPTABLES -F -t nat
$IPTABLES -X
$IPTABLES -P INPUT ACCEPT
$IPTABLES -P OUTPUT ACCEPT
$IPTABLES -P FORWARD ACCEPT
$IPTABLES -A INPUT -i $LOOPBACK_INTERFACE -j ACCEPT
$IPTABLES -A OUTPUT -o $LOOPBACK_INTERFACE -j ACCEPT
$IPTABLES -t nat -F
$IPTABLES -t nat -X
$IPTABLES -t mangle -F
$IPTABLES -t mangle -X

# apagamos el forwarding
echo "0" > /proc/sys/net/ipv4/ip_forward
}

########### Reglas IPTABLES #################
basicas() {
echo " [ Reglas Basicas ]"
$IPTABLES -A INPUT -p ALL -i lo -j ACCEPT
#Accept myself $PUB_IP in SSH
$IPTABLES -A INPUT -d $IPADDR -p tcp --dport $SSH_PORT -j ACCEPT
#established
##SE ACEPTAN entradas previamente establecidas
$IPTABLES -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
$IPTABLES -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
$IPTABLES -A OUTPUT -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT
$IPTABLES -A FORWARD -i $ -o $LAN_INTERFACE -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A INPUT -p ALL -d $IPADDR -m state --state ESTABLISHED,RELATED -j ACCEPT
# dejar esta línea o de lo contrario no se puede acceder remotamente
$IPTABLES -A INPUT -i $LAN_INTERFACE -j ACCEPT
$IPTABLES -A INPUT -p ALL -s $LAN_IPADDR -d $IPADDR -j ACCEPT
$IPTABLES -A INPUT -p ALL -d $LAN_IPADDR -j ACCEPT
}

servicios() {
echo " [ Servicios ]"
#DNS
# Allow inbound DNS requests from the local network.
#Se permite la entrada de requisiciones de la red privada al puerto tcp y udp
$IPTABLES -A INPUT -i $LAN_INTERFACE -p udp --dport 53 -j ACCEPT
$IPTABLES -A INPUT -i $LAN_INTERFACE -p tcp --dport 53 -j ACCEPT
#$IPTABLES -A INPUT -i $LAN_INTERFACE -p udp --dport 53 -m limit --limit 100/s -j ACCEPT

# salida de solicitudes DNS hacia la red externa
$IPTABLES -A INPUT -d $IPADDR -p tcp --dport 53 -j ACCEPT
$IPTABLES -A INPUT -d $IPADDR -p udp --dport 53 -j ACCEPT

#acepto SSH desde la red interna
$IPTABLES -A INPUT -s $LOCALNET -i $LAN_INTERFACE -p tcp -m tcp --dport $SSH_PORT -j ACCEPT

# y acepto SSH desde la red externa
$IPTABLES -A INPUT -d $IPADDR -p tcp --dport $SSH_PORT -j ACCEPT

# ssh login-rate, rechaza por 300 segundos despues de 4 intentos erroneos
$IPTABLES -A INPUT -p tcp --dport $SSH_PORT -i $EXTERNAL_INTERFACE -m state --state NEW -m recent --set
$IPTABLES -A INPUT -p tcp --dport $SSH_PORT -i $EXTERNAL_INTERFACE -m state --state NEW -m recent --update --seconds 300 --hitcount 10 -j REJECT

# FTP: (Notice how you can specify a range of ports 20-21)
$IPTABLES -A INPUT -d $IPADDR -p tcp --dport 20:21 -j ACCEPT

#cups
$IPTABLES -A INPUT -s $LAN_IPADDR -p tcp -m tcp --dport 631 -j ACCEPT
$IPTABLES -A INPUT -s $LAN_IPADDR -p udp --dport 631 -j ACCEPT
$IPTABLES -A INPUT -s $LAN_IPADDR -p tcp -m tcp --dport 515 -j ACCEPT

# jabber
$IPTABLES -A FORWARD -p tcp -m tcp --dport 5222 -j ACCEPT
$IPTABLES -A FORWARD -p tcp -m tcp --dport 5223 -j ACCEPT
$IPTABLES -A FORWARD -p tcp -m tcp --dport 5280 -j ACCEPT
$IPTABLES -A FORWARD -p tcp -m tcp --dport 9090 -j ACCEPT
}

apache() {
# HTTP/Apache
$IPTABLES -A INPUT -d $IPADDR -p tcp --dport 80 -j ACCEPT
$IPTABLES -A INPUT -d $IPADDR -p tcp --dport 443 -j ACCEPT
$IPTABLES -A INPUT -d $IPADDR -p tcp --dport 8080 -j ACCEPT
}

ports() {
########## Puertos ***ACEPTADOS*** para la RED EXTERNA (los demas son denegados por defecto)

echo " [ Puertos Aceptados ]"
$IPTABLES -A INPUT -i $EXTERNAL_INTERFACE -p tcp --dport 113 -j ACCEPT # ident (ataques detectados)
$IPTABLES -A INPUT -i $EXTERNAL_INTERFACE -p tcp --dport 22 -j ACCEPT # acceso SSH
$IPTABLES -A INPUT -i $EXTERNAL_INTERFACE -p tcp --dport 2200 -j ACCEPT # acceso SSH
$IPTABLES -A INPUT -i $EXTERNAL_INTERFACE -p tcp --dport 5222 -j ACCEPT # acceso mensajeria interna
$IPTABLES -A INPUT -i $EXTERNAL_INTERFACE -p tcp --dport 5280 -j ACCEPT # acceso mensajeria interna
$IPTABLES -A INPUT -i $EXTERNAL_INTERFACE -p tcp --dport 80 -j ACCEPT # acceso HTTP
$IPTABLES -A INPUT -i $EXTERNAL_INTERFACE -p tcp --dport 443 -j ACCEPT # acceso HTTPS
# resto de puertos
$IPTABLES -A INPUT -i $EXTERNAL_INTERFACE -m multiport -p tcp --dport $PUERTOS_TCP -j ACCEPT

########## Puertos ***DENEGADOS***  para la RED INTERNA (los demas son aceptados por defecto)
echo " [ Puertos Negados ]"
$IPTABLES -A INPUT -i $LAN_INTERFACE -m multiport -p tcp --dport $NEGADOS -j DROP #
}

icmp() {
# ICMP/Ping:
$IPTABLES -A INPUT -i $EXTERNAL_INTERFACE -p icmp -j ACCEPT
echo " [ Regulacion de ICMP ]"
# regulaciones de ICMP
$IPTABLES -A INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT
$IPTABLES -A INPUT -p icmp --icmp-type source-quench -j ACCEPT
$IPTABLES -A INPUT -p icmp --icmp-type time-exceeded -j ACCEPT
$IPTABLES -A INPUT -p icmp --icmp-type parameter-problem -j ACCEPT
$IPTABLES -A INPUT -p icmp --icmp-type echo-reply -j ACCEPT
}

protecciones() {
##### - Protecciones ----------------------------------------------------------------

echo " [ Protecciones ]"
# Syn-flood
$IPTABLES -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
$IPTABLES -A INPUT -p tcp --syn -j DROP

# drop fragment packets drop
$IPTABLES -A INPUT -f -j DROP
# drop xmas packets
$IPTABLES  -A INPUT -p tcp --tcp-flags ALL ALL -j DROP

#drop malformed & null packets
$IPTABLES -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
}

forward() {
### Forward de la red interna a la externa
$IPTABLES -A FORWARD -i $LAN_INTERFACE -o $EXTERNAL_INTERFACE -s $LOCALNET/$LOCALNETMASK -j ACCEPT
# habilito NAT
if [ "$NAT"="1" ]; then
	echo " [ reglas para NAT ]"
	#trafico de la red interna hacia afuera
	$IPTABLES -A FORWARD -i $LAN_INTERFACE --src $LOCALNET -o $EXTERNAL_INTERFACE --dst 0/0 -j ACCEPT
	## Habilito finalmente el SOURCE NAT
	$IPTABLES -t nat -A POSTROUTING -o $EXTERNAL_INTERFACE -j MASQUERADE
fi
}

proxy() {
# redireccion a un proxy
if [ "$PROXY"="1" ]; then
    echo " [ Reglas para el Proxy ]"
    $IPTABLES -t nat -A PREROUTING -i $LAN_INTERFACE -p tcp --dport 80 -j DNAT --to $PROXY_SERVER:$PROXY_PORT
    $IPTABLES -t nat -A PREROUTING -i $EXTERNAL_INTERFACE -p tcp --dport 80 -j REDIRECT --to-port $PROXY_PORT
fi
}

# aplicar reglas
apply() {
clean
echo "  ** [ Aplicando Firewall ] ** "
test
######################################
# Carga de modulos
/sbin/modprobe ip_tables
/sbin/modprobe ip_conntrack
/sbin/modprobe iptable_filter
/sbin/modprobe iptable_nat
/sbin/modprobe ipt_LOG
/sbin/modprobe ipt_limit
/sbin/modprobe ipt_state
/sbin/modprobe ipt_REJECT
/sbin/modprobe ip_conntrack_ftp
/sbin/modprobe ip_conntrack_irc
/sbin/modprobe ip_nat_ftp
/sbin/modprobe ip_nat_irc

# declaramos el forwarding
echo "1" > /proc/sys/net/ipv4/ip_forward
echo "1" > /proc/sys/net/ipv4/conf/all/accept_source_route

# editamos DNS
echo "# resolv.conf created by firewall" > /etc/resolv.conf
for myDNS in $DNS
do
 echo "nameserver $myDNS" >> /etc/resolv.conf
done

# aplicar reglas basicas
basicas
servicios
apache
ports
icmp
protecciones
forward
proxy

#########
# - GLOBAL REJECTS LAST:
# ----------------------------------------------------------------------
# Reject everything else to that IP:
$IPTABLES -A INPUT -d $IPADDR -j REJECT
$IPTABLES -A INPUT -i $LAN_INTERFACE -j ACCEPT
$IPTABLES -A FORWARD -j DROP

echo " ** [ Firewall Cargado ] ** "
exit 0;
}

### main execution program

case "$COMMAND" in
    -h|-help|--help) help;;
    apply)   apply;;
    clean)  clean;;
    test)    test;;
    *)        usage;;
esac

exit 0;

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: