Outils pour utilisateurs

Outils du site


config:openbsd:pf:start

PF, l'autre firewall

PF est le firewall d'OpenBSD, intégré au noyau du système. Un peu comme NetFilter. Mais là s'arrête la comparaison…

En effet, la syntaxe de PF est bien plus élégante (d'après moi), plus claire et plus puissante que celle d'iptables.

Personnellemnt, je trouve qu'un simple :

block all

est bien plus explicite qu'un

iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP

Non ?

Voici mon fichier de conf, pour un firewall personnel derrière une FAIbox quelconque (configurée en bridge, mais faisant du NAT quand même…), avec autoban des méchants qui font du brute force sur votre serveur SSH.

Ajouter ceci dans la crontab du root :

# purge scan table in PF -- scanning IPs are banned for one week
0       0       *       *       *       /sbin/pfctl -t scan -T expire 604800

Fichier de configuration

OpenBSD 5.2 (post 4.8 en fait...)

pf.conf
# Remember to set net.inet.ip.forwarding=1 and/or net.inet6.ip6.forwarding=1
# in /etc/sysctl.conf if packets are to be forwarded between interfaces.
#
# In most cases the "to any" or "from any" has been removed
#
#
# MaJ 26/09/2012 : syntaxe pour oBSD 5.1 et simplification des regles de sortie
# et ca, c'est le mal ! (tm)
# MaJ 02/11/2012 : suppression de l'option "set-tos" de la directive "scrub" pour
# oBSD 5.2
#


### Macros ###
# Interfaces - will use "egress" for outgoing interface
lan_if = "re0"

# Networks
lan_net = $lan_if:network

# Ports / Types
icmp_types   = "{ echoreq, unreach }"

# Tables
table <martians> const { 10/8, 127/8, 172.16/12, 192.168/16, !egress:0 }
table <bogon> const { 0/8, 192/24, 224/3, 169.254/16, 192.0.2/24, 198.18/15, \
198.51.100/24, 203.0.113/24 }
table <scan> persist

### Options ###
set skip on { lo, enc0 }
set optimization normal
set block-policy drop
set limit { states 200000, frags 100000 }
set state-policy floating
set loginterface egress
set ruleset-optimization basic

### Ruleset ###
# FTP proxy - needs to appear before anything else
anchor "ftp-proxy/*"

# FTP proxy
pass in quick on $lan_if inet proto tcp to any port ftp \
             divert-to 127.0.0.1 port 8021 modulate state

# anchor for relayd(8)
#anchor "relayd/*"

# Normalization: reassemble fragments and resolve or reduce traffic ambiguities
match in all scrub (no-df random-id reassemble tcp max-mss 1440)

# Masquerading: use (interface) for dynamic address
match out on egress inet from !(egress:network) to any nat-to (egress:0)
#nat pass on egress from $lan_net to !88.191.67.90 -> ($ext_if)

# Default rules
block in log
pass out quick proto tcp modulate state
pass out quick proto udp keep state

# No IPv6
block return quick inet6 all

# Block spoofed IPs
block in quick log from urpf-failed label spoof

# Block unauthorized traffic from previous tables definition
block drop in quick log on egress from { <martians>, <bogon> } label martians
block drop in quick log on egress from <scan> label scan
block drop in quick     on egress to 255.255.255.255

# Faster IRC connection (and every ident request)
block return-rst in quick on egress inet proto tcp to port ident

# PPTP VPN
pass in  quick inet proto gre all keep state
pass out quick inet proto gre all keep state

#pass out on $lan_if inet from 88.191.67.90 to $lan_net

pass inet proto icmp all icmp-type $icmp_types keep state

# Firewall services
#pass in on egress inet proto icmp to $ext_if icmp-type $icmp_types keep state
pass in on egress inet proto tcp to egress port ssh \
                   flags S/AUPRFS modulate state \
                   (max-src-conn 50, max-src-conn-rate 10/3, \
                    overload <scan> flush global)

#pass out on $ext_if inet proto udp to 88.191.67.90 port { 500, 4500 } \
                     keep state

# Allow all traffic from LAN
pass in on $lan_if modulate state

# rules for spamd(8)
#table <spamd-white> persist
#table <nospamd> persist file "/etc/mail/nospamd"
#pass in on egress proto tcp from any to any port smtp \
#    rdr-to 127.0.0.1 port spamd
#pass in on egress proto tcp from <nospamd> to any port smtp
#pass in log on egress proto tcp from <spamd-white> to any port smtp
#pass out log on egress proto tcp to any port smtp


# By default, do not permit remote connections to X11
#block in on ! lo0 proto tcp to port 6000:6010

OpenBSD 4.5 (pré 4.8 à priori...)

Ce fichier est plus dense, avec plus de contrôle sur les flux sortants. Probablement moins performant aussi.

pf.conf
# Enable net.inet.ip.forwarding and/or net.inet6.ip6.forwarding in
# /etc/sysctl.conf
#
################################################################################
# BEWARE: In most of the rules, the "to any" or "from any" has been removed in #
# order to simplify ruleset...                                                 #
################################################################################

### Macros ###
# Interfaces
ext_if = "xl0"
lan_if = "xl1"

# Networks
lan_net = $lan_if:network

# Ports / Types
fw_in      = "{ ntp }"
srv_out    = "{ http, https, ftp, ssh, 990 }"
srv_out2   = "{ domain, ntp }"
icmp_types = "{ echoreq, unreach }"
web_ports  = "{ http, https }"

### Tables ###
# See http://www.cymru.com/Documents/bogon-bn-agg.txt
table <martians> const { 10/8, 127/8, 172.16/12, 192.168/16, !$ext_if:0 }
table <iana> const { \
  0/8,   5/8,   14/8,   23/8,   31/8,   36/7,   39/8,   42/8,   49/8, \
100/6, 104/7,  106/8,  176/7,  179/8,  181/8,  185/8,  223/8,  224/3, \
169.254/16, 192.0.2/24, 198.18/15, 198.51.100/24, 203.0.113/24 \
}
# LiveBox/DNS troubles
table <smtp> { smtp.orange.fr }
table <scan> persist

### Options ###
set skip on { lo0, enc0 }
set optimization normal
set block-policy drop
set limit { states 20000, frags 10000 }
set state-policy floating
set loginterface $ext_if
set ruleset-optimization basic

# Normalization: reassemble fragments and resolve or reduce traffic ambiguities
scrub in on $ext_if all no-df random-id fragment reassemble

### Translations ###
# Use ($ext_if) for dynamic address
nat pass on egress from $lan_net -> ($ext_if)

# FTP proxy
nat-anchor "ftp-proxy/*"
rdr-anchor "ftp-proxy/*"

### Redirections ###
# FTP Proxy
rdr pass on { $lan_if, $ext_if } proto tcp to port ftp -> 127.0.0.1 port 8021

### Ruleset ###
# No IPv6
block return quick inet6 all

# Block spoofed IPs
block in quick log from urpf-failed label spoof

# Block ssh brute-forcers
block in quick log from <scan> label scan

# Block unauthorized traffic with previous tables definition
block drop in quick log on $ext_if from { <martians>, <iana> } label martians
block drop in quick     on $ext_if to 255.255.255.255

# Default block rule
block all

# Faster IRC connection (and every ident request)
block return-rst in quick on $ext_if inet proto tcp to port ident

# LAN out
pass inet proto tcp from $lan_net modulate state
pass inet proto udp from $lan_net keep state

# FTP
anchor "ftp-proxy/*"

# Servers out
# SMTP Orange
pass inet proto tcp from $ext_if to <smtp> port smtp modulate state

pass inet proto tcp from $ext_if to port $srv_out modulate state
pass inet proto { tcp, udp } from $ext_if to port $srv_out2 keep state
pass inet proto icmp from { $lan_net, $ext_if } to any \
                icmp-type $icmp_types keep state
pass inet from any to free-unices.org keep state

# Firewall services
pass in on $ext_if inet proto icmp to $ext_if icmp-type $icmp_types \
                keep state             
pass in on $ext_if inet proto tcp to $ext_if port ssh \
                flags S/AUPRFS modulate state \
                (max-src-conn 50, max-src-conn-rate 10/3, \
                overload <scan> flush global)

Logs

Par défaut, PF loggue sur l'interface pflog0 ce qu'il se passe et écrit dans le fichier /var/log/pflog.

Dans les deux cas, il faudra utiliser tcpdump pour analyser le trafic réseau :

tcpdump -n -e -ttt -i pflog0
ou
tcpdump -n -e -ttt -r /var/log/pflog

Histoire de se simplifier la vie, voici un petit script qui lit /var/log/pflog et recrache un fichier texte lisible par un admin humain /var/log/pflog.txt. Il ne vient pas de moi (trouvé sur la toile) et présente l'inconvénient (ou pas ?) de vider /var/log/pflog et d'avoir une latence de 5 minutes (lancé par crontab) :

/etc/pflogrotate
#!/bin/sh
PFLOG=/var/log/pflog
FILE=/var/log/pflog5min.$(date "+%Y%m%d%H%M")
pkill -ALRM -u root -U root -t - -x pflogd
if [ -r $PFLOG ] && [ $(stat -f %z $PFLOG) -gt 24 ]; then
  mv $PFLOG $FILE
  pkill -HUP -u root -U root -t - -x pflogd
  tcpdump -n -e -s 160 -ttt -r $FILE | logger -t pf -p local0.info
  rm $FILE
fi

# EoF

Pour mettre ce script en place, ajoutez cette entrée à la crontab du root :

# logrotate for PF text logfiles
*/5     *       *       *       *       /etc/pflogrotate

et modifiez /etc/newsyslog.conf comme ceci :

#/var/log/pflog                         600  3     250  *     ZB "pkill -HUP -u root -U root -t - -x pflogd"
/var/log/pflog.txt                      600  7     *    24
config/openbsd/pf/start.txt · Dernière modification: 2012/11/02 09:55 par cyriac