ONLamp.com    
 Published on ONLamp.com (http://www.onlamp.com/)
 See this if you're having trouble printing code examples


FreeBSD Basics

BSD Firewalls: IPFW

04/25/2001

Also in FreeBSD Basics:

Fun with Xorg

Sharing Internet Connections

Building a Desktop Firewall

Using DesktopBSD

Using PC-BSD

Su sistema FreeBSD viene con dos mecanismos interconstruidos para inspeccionar paquetes IP:ipfw ye ipfilter. Ambos tienen su peculiar sintaxis para crear conjuntos de reglas para determinar qué paquetes permitir y cuáles descartar, así que quisiera demostrar el uso de ambos. Debido a que usted puede ejecutar uno u otro, empezaré con ipfw; una vez que hayamos tenido una buena mirada en éste, nos dedicaremos a ipfilter.

Antes de que pueda usar ipfw, tendrá que agregar algunas opciones a su archivo de configuración del kernel y recompilar éste. Si usted está un poco oxidado para compilar kernels, querrá echar una mirada a esa sección del manual.

Hay varias opciones que pueden usarse por ipfw, así que empecemos echando una mirada a LINT. Haré una búsqueda usando "/" para encontrar rápidamente la sección correcta:

cd /usr/src/sys/i386/conf
more LINT
/IPFIREWALL

# IPFIREWALL enables support for IP firewall construction,
# in conjunction with the 'ipfw' program.  IPFIREWALL_VERBOSE
# sends logged packets to the system logger.
# IPFIREWALL_VERBOSE_LIMIT limits the number of times a
# matching entry can be logged.
#
# WARNING:  IPFIREWALL defaults to a policy of "deny ip
# from any to any" and if you do not add other rules during
# startup to allow access, YOU WILL LOCK YOURSELF OUT.  It
# is suggested that you set firewall_type=open in /etc/rc.conf
# when first enabling this feature, then refining the firewall
# rules in /etc/rc.firewall after you've tested that the new
# kernel feature works properly.
#
# IPFIREWALL_DEFAULT_TO_ACCEPT causes the default rule (at boot)
# to allow everything.  Use with care, if a cracker can crash
# your firewall machine, they can get to your protected machines.
# However, if you are using it as an as-needed filter for
# specific problems as they arise, then this may be for you.
# Changing the default to 'allow' means that you won't get stuck
# if the kernel and /sbin/ipfw binary get out of sync.

Como mínimo, necesita incluir la opción IPFIREWALL para habilitar a ipfw; esto le dice a su kernel que examine cada paquete IP y lo compare con el conjunto de reglas. Es siempre una buena idea incluir soporte al ingreso (logging support), que se hace aņadiendo la opción IPFIREWALL_VERBOSE. También debería limitar la cantidad de paquetes que el kernel registrará por la misma razón que vimos la semana pasada en limitando la cantidad de paquetes ICMP que fueran registrados. Usted limita el registro de paquetes IP con la opción IPFIREWALL_VERBOSE_LIMIT.

También en lo básico de FreeBSD:

Firewalls BSD: Conjuntos de reglas para sintonización fina

Firewalls BSD: conjuntos de reglas IPFW

Explorando su red

Examinando paquetes ICMP

Paquetes IP revelados

Note que la condición por omisión de ipfw es botar todos los paquetes IP excepto aquellos que especificamente haya permitido en su conjunto de reglas. Yo prefiero esta condición pues da control más fino sobre qué paquetes están siendo aceptados; odiaría pensar que mi kernel estaba aceptando paquetes de los cuales no estaba consciente. Definitivamente notaría si los paquetes que quiero no estuvieran siendo aceptados y puedo cambiar mi conjunto de reglas para permitirlos; nunca sabría la diferencia si los paquetes de los cuales no había tenido cuidado estuvieran durmiendo por mi firewall debido a que no hice un conjunto de reglas para denegarlos explícitamente. En consecuencia, no pasaría sobre la condición por omisión incluyendo la opción IPFIREWALL_DEFAULT_TO_ACCEPT.

# IPDIVERT enables the divert IP sockets, used
# by ''ipfw divert''

Esta opción es utilizada en conjunción con natd. Debido a que sólo estoy construyendo un firewall para proteger una sola máquina, no necesitaré esta opción

# IPSTEALTH enables code to support stealth forwarding
# (i.e., forwarding packets without touching the ttl).
# This can be useful to hide firewalls from traceroute
# and similar tools.

Esto suena como una opción interesante, así que la incluiré en mi firewall y veré como funciona cuando pruebe mi firewall.

# Statically Link in accept filters
options            ACCEPT_FILTER_DATA
options            ACCEPT_FILTER_HTTP

No estoy ejecutando un servidor web en esta computadora, así que no compilaré en estas dos opciones.

# The following options add sysctl variables for controlling
# how certain TCP packets are handled.
#
# TCP_DROP_SYNFIN adds support for ignoring TCP packets with
# SYN+FIN. This prevents nmap et al. from identifying the
# TCP/IP stack, but breaks support for RFC1644 extensions
# and is not recommended for web servers.
#
# TCP_RESTRICT_RST adds support for blocking the emission
# of TCP RST packets. This is useful on systems which are
# exposed to SYN floods (e.g. IRC servers) or any system
# which one does not want to be easily portscannable.

De nuevo, voy a incluir esas opciones para ver los resultados cuando pruebe mi firewall.

# ICMP_BANDLIM enables icmp error response bandwidth
# limiting.   You typically want this option as it will
# help protect the machine from D.O.S. packet attacks.
#
options     ICMP_BANDLIM

Esta opción viene habilitada con el kernel por omisión; vimos su comportamiento la semana pasada cuando usamos la utilería nmap.

# DUMMYNET enables the "dummynet" bandwidth limiter.
# You need IPFIREWALL as well. See the dummynet(4)
# manpage for more info. BRIDGE enables bridging between
# ethernet cards -- see bridge(4).

No incluiré esas dos opciones debido a que no necesito hacer ningún análisis de tráfico en esta sola computadora.

Antes de reconstruir mi kernel, añadiré las siguientes líneas a mi archivo de configuración:

#To enable IPFW with default deny all packets
options   IPFIREWALL
options   IPFIREWALL_VERBOSE
options   IPFIREWALL_VERBOSE_LIMIT=10

#To hide firewall from traceroute
options   IPSTEALTH

#To hide from nmap, remove if create web server
options   TCP_DROP_SYNFIN

#To hide from portscans
options   TCP_RESTRICT_RST

Mientras se recompila mi kernel, echaré una mirada a las opciones que debería añadir en /etc/rc.conf. De nuevo, usaré "/" para buscar la sección correcta en manpage:

man rc.conf
/firewall

firewall_enable
   (bool) Set to NO if you do not want have firewall rules
   loaded at startup, or YES if you do.  If set to YES, and
   the kernel was not built with IPFIREWALL, the ipfw kernel
   module will be loaded.  See also ipfilter_enable.

firewall_script
   (str) If you want to run a firewall script other than
   /etc/rc.firewall, set this variable to the full path to
   that script.

firewall_type
   (str) Names the firewall type from the selection in
   /etc/rc.firewall, or the file which contains the local
   firewall ruleset.  Valid selections from /etc/rc.firewall,
   are ''open'' - unrestricted IP access; ''closed'' - all IP
   services disabled, except via lo0; ''client'' - basic pro-
   tection for a workstation; ''simple'' - basic protection
   for a LAN.  If a filename is specified, the full path must
   be given.

Debido a que quiero que las reglas de mi firewall se carguen en el arranque, voy a poner firewall_enable en YES. Estaré creando mi propio conjunto de reglas, así que especificaré la ruta del archivo que crearé usando firewall_type.

firewall_quiet
   (bool) Set to YES to disable the display of ipfw rules on
   the console during boot.

Es buena opción poner en YES a medida que le muestra cada regla que está cargando; si tiene un tipo en su conjunto de reglas, todas las reglas que siguen a tipo NO serán cargadas. Si está mirando la pantalla durante el arranque, verá un mensaje de sintaxis ipfw a continuación de la última regla que fue cargada exitosamente; querrá mirar un tipo en la siguiente línea de tal regla, entonces rearranque para asegurar que todas sus reglas se cargaron exitosamente.

firewall_logging
   (bool) Set to YES to enable ipfw event logging.  This is
   equivalent to the IPFIREWALL_VERBOSE kernel option.

tcp_extensions
   (bool) Set to NO by default.  Setting this to YES enables
   certain TCP options as described by RFC 1323.  If you have
   problems with connections randomly hanging or other weird
   behavior of such nature, you might try setting this back to
   NO and seeing if that helps.  Some hardware/software out
   there is known to be broken with respect to these options.

log_in_vain   (bool) Set to NO by default.  Setting to YES
   will enable logging of connection attempts to ports that have
   no listening socket on them.

tcp_keepalive
   (bool) Set to YES by default.  Setting to NO will disable
   probing idle TCP connections to verify that the peer is
   still up and reachable.

tcp_drop_synfin
   (bool) Set to NO by default.  Setting to YES will cause the
   kernel to ignore TCP frames that have both the SYN and FIN
   flags set.  This prevents OS fingerprinting, but may break
   some legitimate applications.  This option is only avail-
   able if the kernel was built with the TCP_DROP_SYNFIN op-
   tion.

Debido a que añadí la opción TCP_DROP_SYNFIN en mi kernel, pondré este valor correspondiente en YES. Incluiré una nota para eliminar esta línea si yo habilito un servidor web en esta computadora.

tcp_restrict_rst
   (bool) Set to NO by default.  Setting to YES will cause the
   kernel to refrain from emitting TCP RST frames in response
   to invalid TCP packets (e.g., frames destined for closed
   ports).  This option is only available if the kernel was
   built with the TCP_RESTRICT_RST option.

icmp_drop_redirect
   (bool) Set to NO by default.  Setting to YES will cause the
   kernel to ignore ICMP REDIRECT packets.

icmp_log_redirect
   (bool) Set to NO by default.  Setting to YES will cause the
   kernel to log ICMP REDIRECT packets.  Note that the log
   messages are not rate-limited, so this option should only
   be used for troubleshooting your own network.

Terminaré agregando las siguientes líneas a mi archivo /etc/rc.conf:

#required for ipfw support
firewall_enable="YES"
firewall_script="/etc/rc.firewall"
firewall_type="/etc/ipfw.rules"
firewall_quiet="NO" #change to YES once happy with rules
firewall_logging_enable="YES"

#extra firewalling options
log_in_vain="YES"
tcp_drop_synfin="YES"   #change to NO if create webserver
tcp_restrict_rst="YES"
icmp_drop_redirect="YES"

Unas notas antes de rearrancar con mi nuevo kernel. El archivo LINT realmente tiene significado cuando dice "TU MISMO TE QUEDARAS ENCERRADO AFUERA". Hasta que arranque creando un conjunto de reglas que permita los paquetes IP que deseo, ningún paquete IP podrá salir o entrar en mi computadora. Si deseo verificar mi correo electrónico o bajar cualquier de Internet cantidad de bits de la información sobre conjuntos de reglas, ahora es el momento de hacerlo, antes de rearrancar.

Crear un buen conjunto de reglas es un poco del arte fino; si va a crear un firewall por vez primera, espere hasta que tenga un período de tiempo en el cual no es esencial tener la conexión de red y tenga el tiempo de probar cosas y rearrancar y probar algo más y rearrancar, etc. Encontrará que la lógica usada por ipfw no necesariamente será la misma que use usted.

También, un firewall no es algo que usted sólo instala y se olvida del asunto. Planee invertir algún tiempo probándolo y rascándose la cabeza cuando no parezca hacer las cosas de la manera que ested esperaba que las haría. Una vez que que haya rearrancado con su nuevo kernel habilitado como firewall, querrá planear y completar las siguientes tres tareas:

  1. Metódicamente agregue reglas a su conjunto de reglas y prueba cada una de ellas para asegurar que se está permitiendo sólo los paquetes que usted desea permitir.
  2. Decida qué desea registrar (log) y mire el resultante archivo de registro. Probablemente termine modificando sus reglas a medida que descubra que inadvertidamente permitió o denegó algunos paquetes que no deseaba hacer.
  3. Una vez que esté satisfecho de que su firewall está soltando y aceptando los paquetes que desea, pruébelo para asegurarse de que se está comportando com esperaría.

Está bien, rearrancaré mi computadora para cargar el nuevo kernel. Y voy a ver cuidadosamente mis pantallas de arranque; debería ver el siguiente mensaje justo después que se ha cargado mi NIC:

Flushed all rules.
00100 allow ip from any to any via lo0
00200 deny ip from any to any to 127.0.0.0/8
Firewall rules loaded, starting divert daemons:.
Additional routing options: tcp extensions=NO ignore ICMP redirect=YES TCP keepalive=YES restrict TCP reset=YES drop SYN+FIN packets=YES.


Additional TCP options: log_in_vain=YES.

Se preguntará porqué recibí esas primeras tres líneas si no he creado aún el archivo que contiene mi conjunto de reglas. Cuando edité /etc/rc.conf,agregué la línea:

firewall_script="/etc/rc.firewall"

El archivo /etc/rc.firewall fue leído a tiempo de arranque y contiene las siguientes líneas:

############
# Flush out the list before we begin.
#
${fwcmd} -f flush

############
# Only in rare cases do you want to change these rules
#
${fwcmd} add 100 pass all from any to any via lo0
${fwcmd} add 200 deny all from any to 127.0.0.0/8

Como muestra claramente las reglas 100 y 200 deberán usarse, yo arranco con la regla 300 cuando cree mi conjunto de reglas. Antes de hacerlo, deseo verificar un par de veces que ipfw está denegando todos los paquetes por omisión. Puede hacer esto usando el comando ipfw show.

ipfw show
ipfw: socket: Operation not permitted

Parece como si sólo al superusuario le está permitido ver las reglas del firewall, así que trataré de nuevo como el supersusuario:

su
Password:
ipfw show
00100   0     0 allow ip from any to any via lo0
00200   0     0 deny ip from any to 127.0.0.0/8
65535 115 14092 deny ip from any to any

Después, para estar realmente seguro, trataré de usar mi conexión a red:

ping www.freebsd.org
ping: cannot resolve www.freebsd.org: Host name lookup failure

traceroute www.freebsd.org
traceroute: unknown host www.freebsd.org

lynx www.freebsd.org
Alert!: Unable to access document.

Bueno, la resolución de nombres definitivamente no está trabajando; vamos a tratar de hacer ping por la dirección IP:

ping 24.141.116.1
PING 24.141.116.1 (24.141.116.1): 56 data bytes
ping: sendto: Permission denied
ping: sendto: Permission denied
^C
--- 24.141.116.1 ping statistics ---
2 packets transmitted, 0 packets received, 100% packet loss

Como ejecuté el último ping como superusuario, parece como ipfw que en verdad está descartando todos los paquetes IP. Ahora que verdaderamente me he quedado encerrado afuera de mi conexión de red, es tiempo de crear un conjunto de reglas que me permita enviar y recibir los paquetes IP que deseo.

Hay dos formas de crear las reglas que son leídas por ipfw:

Debido a que soy la única persona que usa la computadora de casa, agregaré mis reglas directamente al archivo y rearrancaré. Lo que precisamente, he hecho en /etc/rc.conf

firewall_type="/etc/ipfw.rules"

Así, estaré creando un archivo llamado /etc/ipfw.rules.

Tomará todo un artículo crear y probar el conjunto de reglas, así que esperemos una semana para hacer esto. Mientras tanto, querrá echar una mirada a lo siguiente para que tenga un acercamiento a la sintaxis de las reglas de ipfw y qué tipo de reglas debería incluir en su conjunto de reglas:

man ipfw

http://www.robertgraham.com/pubs/firewall-seen.html

http://www.defcon1.org//html/Networking_Articles/Firewall-Ipfw/firewall-ipfw

http://www.interhack.net/pubs/fwfaq/

http://www.freebsddiary.org/firewall.html

http://www.bsdtoday.com/2000/December/Features359.html

http://www.freebsd-howto.com/HOWTO/Ipfw-HOWTO

http://www.daemonnews.org/200103/firewall.html

Como puede ver, hay muchos recursos disponibles y no tendrá que reinventar la rueda cuando cree su conjunto de reglas. Notará también que esos conjuntos de reglas tienden a ser específicas a las necesidades de un usuario; encontrará que terminará adoptando buenas ideas de varios recursos. Hasta la siguiente semana, feliz lectura.

Dru Lavigne is a network and systems administrator, IT instructor, author and international speaker. She has over a decade of experience administering and teaching Netware, Microsoft, Cisco, Checkpoint, SCO, Solaris, Linux, and BSD systems. A prolific author, she pens the popular FreeBSD Basics column for O'Reilly and is author of BSD Hacks and The Best of FreeBSD Basics.


Read more FreeBSD Basics columns.

Return to the BSD DevCenter.

Copyright © 2009 O'Reilly Media, Inc.