Archives de catégorie : FW

Shorewall

Install

IPV4

apt-get install shorewall

IPV6

apt-get install shorewall6

/etc/shorewall.conf

STARTUP_ENABLED=Yes

/etc/default/shorewall

startup=1

Fichiers de configuration vierges

 cp /usr/share/shorewall/configfiles/{zones,interfaces,policy,rules,params} /etc/shorewall/

Pour l’IPv6 la configuration se fait dans /etc/shorewall6/

Exemple de configuration

ces exemples s’appliquent à un firewall unijambiste. zones

fw      firewall
net     ipv4

interface

#ZONE           INTERFACE               OPTIONS
net             eth0            rpfilter,logmartians,nosmurfs

policy

#SOURCE DEST    POLICY          LOG     LIMIT:          CONNLIMIT:
#                               LEVEL   BURST           MASK
 
net     all     DROP            info    10/sec:40
fw      all     DROP            info
all     all     DROP

params

WEBPORT=80,443
SSHPORT=12345
REPOTS=security.debian.org,ftp.fr.debian.org,ftp.debian.org
ADMINS=123.123.123.123,234.234.234.234
HOME=45.52.12.23

Example rules

#note 1 : if there is no matching rules here, default policies apply => fucking DROP
#note 2 : This is only for new connections, existing connections are automatically accepted.
 
#DROP DNS Amplification attack
INLINE(DROP):info    net   $FW  udp   53   ;  -m u32 --u32 "0>>22&0x3C\@8&0xffff=0x0100 && 0>>22&0x3C\@12&0xffff0000=0x00010000"
 
#SSH
ACCEPT:info     net:$ADMINS,$HOME     fw      tcp     $SSHPORT
#web
ACCEPT          net     fw      tcp     $WEBPORT
#resolution dns for fw
DNS(ACCEPT)     fw      net
#MAJ OS
ACCEPT          fw      net:$REPOTS     tcp     80

Ajout d’une route de secours

echo $interface_in  $your_ip >> /etc/shorewall/routedstopped

Administration

les logs se trouvent par défaut dans /var/log/messages

dmesg

Voir les connexions courantes :

shorewall show connections

Shorewall 4.6.4.3 Connections (32 out of 65536) …

Le nombre de connexion max est définies dans /etc/sysctl.conf avec

net.netfilter.nf_conntrack_max = 65536

Vérification syntaxique des règles

shorewall check

Relance

shorewall restart

Astuce : ne jamais faire de restart sans un check préalable.

Pour aller plus loin : http://shorewall.net/Documentation_Index.html

Paquet Filter

Ceci est spécifique à OpenBSD

Lancement au boot

dans /etc/rc.conf

Vérifiez la présence de

pf=YES 
pf_rules=/etc/pf.conf

Ajout d’un fichier de configuration propre a pf, ceci est pratique en cas de maj de l’os car /etc/rc.conf peut être modifier. On ajoute les logs au passage.

/etc/rc.conf.local

pf=YES 
pf_rules=/etc/pf.conf
pflog_enable="YES"
pflog_logfile="/var/log/pflog"

Contrôle de pf avec pfctl

démarrage de pf

pfctl -e

Arrêt

pfctl -d

Test du fichier de configuration ( n dryrun ) attention l’ordre de ces options est important.

pfctl -vnf /etc/pf.conf

liste des règles actuelles

pfctl -sr 

Liste des règles avec leur numéro

pfctl -vv -sr

Chargement d’un fichier de règle

pfctl -f /etc/pf.conf

Sauvegarde dans un fichier de configuration ( attention format binaire )

pfctl -S /tmp/svgpf_conf

Chargement du fichier de config précédemment sauver par -S

pfctl -L /tmp/svgpf_conf

Configuration

Modification du fichier /etc/pf.conf

if_loc="em0"  # Ajoute une variable contenant la carte réseau
imaps_ports="143, 993"  # variables listé macro à la shorewall

Utilisation de la variable et usage des listes blocage en entrée, si le blockage en sortie est désiré utilisez block drop out …

block in on $if_loc proto tcp from { 192.168.21.0/24, 10.10.0.0/16 } to any port { 123 80 }

avec la commande

pfctl -vnf /etc/pf.conf

on obtient le résultat suivant :

block drop in on em0 inet proto tcp from 192.168.21.0/24 to any port = 123
block drop in on em0 inet proto tcp from 192.168.21.0/24 to any port = 80
block drop in on em0 inet proto tcp from 10.10.0.0/16 to any port = 123
block drop in on em0 inet proto tcp from 10.10.0.0/16 to any port = 80

Les listes c’est bien mais y a mieux a dit le monsieur : les tables !

une table en mémoire est beaucoup plus rapide, et moins coûteuse en temps processeur/mémoire que la recherche dans un jeu de règles correspondant chacune à une valeur d’une liste d’adresses.

toujours dans pf.conf

table <ip_unauthorized> const { 192.168.21.0/24, 10.10.0.0/16 }
table <blacklist> persist file "/etc/blacklist"
block in on $if_loc from { <ip_unauthorized>, <blacklist> } to any

file a un caractère optionnel.
const : table non modifiable
persist : permet l’initialisation de la table même vide et modifiable avec les commandes données ci-après

ATTENTION le fichier /etc/blacklist doit exister

sinon

/etc/pf.conf:12: cannot load "/etc/blacklist": No such file or directory

Ajout d’une ip par exemple 49.213.15.129

pfctl -t blacklist -T add 49.213.15.129/32

Retrait de la table d’une ip

pfctl -t blacklist -T delete 9.21.1.185/32

Voi le contenu des tables

pfctl -t blacklist -T show

Regarder les logs de pf en temps réel

tcpdump -nni pflog0 -e -t

regarder l’historique

tcpdump -nnr /var/log/pflog -e -ttt

Différentes directives

block  #bloque
block in log all  # block & log
pass  in|out   #si rien n'est précisez la règle évalue les deux sens de com. = accept
quick #si le paquet match cette règle le reste des règles n'est pas évaluée. 
rdr pass # = redirection des paquets
nat on # NAT
set skip lo # ne touche à aucun paquet à destination de la loopback

Règles de sécurité standard

Parle d’elle-même

antispoof for $if_loc

Normalisation = réassemble des paquets fragmentés pour analyse, permet de contrer les techniques de fragmentation en tout petit paquet pour passer les filtres des pare-feux.

match in all scrub (no-df)

Première règle à placer après les définitions de variables/liste/tables

block all

en suivant, les accept

exemples …

pass ...
rdr pass ...
nat on ...

Variables :

local_host="ip_em0_par_exemple"
udp_services = "{ dns, ntp }

Utilisées dans une règle

pass in on $if_loc inet proto tcp from any to $local_host port $udp_services

fichier de conf basique et sa traduction par PF

on vire tout sauf le ssh à destination de la machine, on se garde

#vars
if_loc="em0"
localip=192.168.21.145
sshp=22
table <blacklist> persist

antispoof for $if_loc
match in all scrub (no-df)
block in log all

set skip on lo
block drop from {<blacklist>} to  any
pass in on $if_loc proto tcp to $localip port $sshp

puis

pfctl -vnf /etc/pf.conf

traduction :

if_loc = "em0"
localip = "192.168.21.145"
sshp = "22"
table <blacklist> persist
set skip on { lo }
block drop in on ! em0 inet from 192.168.21.0/24 to any
block drop in inet from 192.168.21.145 to any
match in all scrub (no-df)
block drop in log all
block drop from <blacklist> to any
pass in on em0 inet proto tcp from any to 192.168.21.145 port = 22 flags S/SA

OpenBSD & FW

Installation

Fait avec la version 5.7

Et en avant pour l’aventure avec le poisson globe.

  • Appuyer sur la touche I
  • L’installeur demande le keyboard layout. Tapez fr si vous avez un clavier français. Pour la liste de tous les claviers dispo tapez L
  • Choisissez votre nom d’hôte.
  • Carte réseau disponible ⇒ em0
  • Adresse par DHCP, il sera de toute manière possible de revenir là-dessus après.
  • IPV6 pour em0 [none]
  • voulez vous configurez d’autre interfaces réseau [done]
  • Choisissez votre mot de passe root. Attention au pavé numérique !
  • Activer SSH par défault [yes]
  • Activer NTPD par défault [no]
  • Utiliser le X window system [no]
  • Démarrer le X Window System avec XDM [no]
  • Créer un utilisateur [no] Nous sommes ici en lab, en théorie on doit créer un autre utilisateur que root et empêcher root de se connecter via SSH.
  • Timezone [Europe/Paris]
  • Quel disque pour la racine [wd0]
  • Utilisez les UUIDs plutôt que les noms dans /etc/fstab [yes]
  • Utiliser tout le disque [W] par défaut
  • En utilisant l’auto layout [A]par défaut
  • Localisation des ensembles de paquets [http]
  • proxy [none]
  • http server [ftp.fr.openbsd.org] par défaut
  • répertoire sur serveur [par défaut] pub/OpenBSD/5.7/amd64
  • Sélection des paquets ( ensembles sous OB )

Sélectionner les paquets à installer. Les paquets game57.tgz, xbase57.tgz, xetc57.tgz, xshare57.tgz, xfont57.tgz et xserv57.tgz seront supprimés en tapant leurs noms précédés du signe –

-game57.tgz
-xbase57.tgz
-xshare57.tgz
-xfont57.tgz
-xserv57.tgz

Cela décoche les ensembles non désirés, Attention au pavé numérique !

  • Continuez sans vérification [yes]

Après le DL et l’install

  • Ajouter d’autres paquets [done]

tapez reboot pour redémarrer.

Configuration de base

Ajout dans ~/.profile

export PS1="\u@\h:\$PWD>"

donne root@OpenBSD5:/root>

Ajout du paquet vim

pkg_add vim
Ajout d'un paquet : vim
pkg_add vim                                                
quirks-2.54 signed on 2015-03-08T12:33:05Z
quirks-2.54: ok
Ambiguous: choose package for vim
a       0: <None>
        1: vim-7.4.475-gtk2
        2: vim-7.4.475-gtk2-lua
        3: vim-7.4.475-gtk2-perl-python-ruby
        4: vim-7.4.475-gtk2-perl-python3-ruby
        5: vim-7.4.475-no_x11
        6: vim-7.4.475-no_x11-lua
        7: vim-7.4.475-no_x11-perl-python-ruby
        8: vim-7.4.475-no_x11-perl-python3-ruby
        9: vim-7.4.475-no_x11-ruby
Your choice: 5
vim-7.4.475-no_x11:libiconv-1.14p1: ok
vim-7.4.475-no_x11:gettext-0.19.4: ok
vim-7.4.475-no_x11: ok

Désactivation des services lancés au boot

Le daemon ntpd par exemple.

rcctl disable ntpd
rcctl get ntpd flags

ou

rcctl get ntpd

Modification du nom d’hôte

vim /etc/myname

firewalling avec PF

voir : packet_filter

Mettre en place la haute-dispo pour les firewalls

CARP

Toujours sous OPenBSD, la haute disponibilité est effectuée avec CARP.

Clonage de la première VM

modification du nom d’hôte et modification de la ligne

localip=192.168.1.38

dans /etc/pf.conf

A partir de maintenant les commandes décrites ci-après sont effectué sur les deux OPenBSD.

Dans un premier temps il faut autorisé le système à s’en servir :

sysctl -w net.inet.carp.allow=1
sysctl -w net.inet.carp.preempt=1

Création de l’interface :

ifconfig carp1 create

Configuration

ifconfig carp1 vhid 1 pass mot_de_passe carpdev em0 advskew 100 192.168.1.36 netmask 255.255.255.0

Explications :

le carp est un protocole qui permet à un groupe d’hôte d’être redondant sur le niveau 3 de la couche OSI.

vhid 1 = virtual host id 1 id du groupe pass = permet de protégé les paquets du protocole carp avec un mot de passe pour le HMAC SHA1 afin d’éviter le spoof d’une ip du groupe. carpdev = permet à l’interface visée de faire parti du groupe carp advskew = attribut un poids à l’hôte, exemple ici nous prenons 100. Si pour le deuxième FW on prends moins de 100 il sera considéré comme MASTER et un nombre supérieur comme le BACKUP.

Pour pf, il nous faut ceci où carp_dev = em0 dans notre exemple.

pass out on $carp_dev proto carp keep state

Pour le FW 1 ( master )

nous aurons donc

ifconfig carp1 vhid 1 pass mot_de_passe carpdev em0 advskew 50 192.168.1.36 netmask 255.255.255.0

et pour le 2

ifconfig carp1 vhid 1 pass mot_de_passe carpdev em0 advskew 100 192.168.1.36 netmask 255.255.255.0

Résultat :

carp1: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        lladdr 00:00:5e:00:01:01
        priority: 0
        carp: MASTER carpdev em0 vhid 1 advbase 1 advskew 100
        groups: carp
        status: master
        inet 192.168.1.36 netmask 0xffffff00 broadcast 192.168.21.255
carp1: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        lladdr 00:00:5e:00:01:02
        priority: 0
        carp: MASTER carpdev em0 vhid 1 advbase 1 advskew 150
        groups: carp
        status: master
        inet 192.168.1.36 netmask 0xffffff00 broadcast 192.168.21.255

Il y a deux master voir section problème rencontré.

Une fois le problème corrigé on arrive bien à la configuration désirée :

carp1: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        lladdr 00:00:5e:00:01:01
        priority: 0
        carp: MASTER carpdev em0 vhid 1 advbase 1 advskew 50
        groups: carp
        status: master
        inet 192.168.1.36 netmask 0xffffff00 broadcast 192.168.21.255
carp1: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        lladdr 00:00:5e:00:01:01
        priority: 0
        carp: BACKUP carpdev em0 vhid 1 advbase 1 advskew 100
        groups: carp
        status: backup
        inet 192.168.1.36 netmask 0xffffff00 broadcast 192.168.21.255

Afin de tester la configuration, l’interface du master est éteinte avec la commande

ifconfig carp1 down

L’autre interface devient immédiatement master, dans les log nous voyons ce changement par

dmesg
carp1: state transition: BACKUP -> MASTER

pfsync

Création de l’interface pour pfsync, cette techno permet la synchronisation des tables d’état des connexions. Afin de ne pas « couper » la liaison établi lors d’une bascule.

ifconfig pfsync0 create

Configuration de l’interface

FW1 & 2 le trafic sera multicast , Attention note que pour un trafic de 500Mo sec , celui de pfsync est de 150Mo/sec

ifconfig pfsync0 syncdev em0

trafic unicast , on force un peer

ifconfig pfsync0 syncdev em0 [syncpeer 192.168.21.145] [defer|-defer]
ifconfig pfsync0 syncdev em0 [syncpeer 192.168.21.136] [defer|-defer]

Règle PF à ajouter

pass on $sync_if proto pfsync
pass on if_loc proto pfsync

Voir : http://www.openbsd.org/faq/pf/carp.html

Sauvegarde filesystem en vue d’upgrade

Dump à travers le réseau

/sbin/dump -0f- /home | gzip -2 | ssh  root@192.168.1.38 dd of=/root/disk_openbsd57_home.gz

Restauration

scp  disk_openbsd57_home.gz  root@192.168.1.38:/root
cd /rep_to_restore 
cat /root/disk_openbsd57_user.gz | gunzip | restore -rf-  

Problèmes rencontrés

cela ne fonctionne pas, impossible en dehors des deux vm de pinger la 192.168.1.36

dans les logs nous avons :

duplicate IP address 192.168.1.36 sent from ethernet address 00:00:5e:00:01:02
arp: attempt to overwrite permanent entry for 192.168.1.36 by 00:00:5e:00:01:02 on em0

duplicate IP address 192.168.1.36 sent from ethernet address 00:00:5e:00:01:01
arp: attempt to overwrite permanent entry for 192.168.1.36 by 00:00:5e:00:01:01 on em0

ceci était dû à la mauvaise compréhension du vhid qui signifie virtual host ID mais qui représente en réalité l’ID du groupe de redondance. Il doit être identique sur TOUS les membres du même groupe.

VPN IPsec

Howto VPN IPsec sous OpenBSD

Il existe deux méthodes pour mettre en place un VPN IPsec sous OpenBSD. La première est de créer un fichier de configuration /etc/isakmpd/isakmpd.conf. La seconde est d’utiliser /etc/ipsec.conf et sa syntaxe « pf-like » et de laisser ipsecctl s’occuper des politiques de flux et de l’établissement de la SA (Security association).

Méthode isakmpd via isakmpd.conf

Recharger isakmpd

Pour recharger la configuration d’ISAKMPD, il suffit de lui envoyer un SIGHUP. Ceci ne provoque pas coupure VPN pour les phases 1 (IPSEC) mais un rechargement de toutes les phases 2 !

pkill -HUP isakmpd

Note : attention, on a déjà constaté un plantage peu après un rechargement. Il conviendra de surveiller attentivement qu’ISAKMPD tourne bien.

Redémarrer isakmpd

Attention cela interrompt tous les VPN pendant quelques instants.

pkill isakmpd
isakmpd -v

Consulter les logs

tail -f /var/log/messages | grep isakmpd

Voir les routes

route -n show

Si isakmpd est bien lancé, une section Encap: doit apparaître.

Voir les associations VPN

ipsecctl -s a

Envoyer des commandes au daemon

Cela se fait en écrivant dans le fichier fifo /var/run/isakmpd.fifo. La liste des commandes est disponible dans la page de man.

Exemple pour obtenir un rapport de l’état interne du daemon :

echo r >/var/run/isakmpd.fifo
cat /var/run/isakmpd.result

Pour avoir l’état de tous les VPNs :

echo S >/var/run/isakmpd.fifo
grep isakmpd /var/log/daemon

Pour recharger les VPNs (équivalent au pkill -HUP) :

echo R >/var/run/isakmpd.fifo

Pour stopper proprement le démon :

echo Q >/var/run/isakmpd.fifo

Pour stopper un VPN (phase 1 ou 2) :

echo "t main peer-XXXX" >/var/run/isakmpd.fifo
echo "t quick XXXX" >/var/run/isakmpd.fifo

Pour relance un VPN (phase 1 ou 2… ce n’est pas clair. cela semble fonctionner pour la phase 1… à voir pour la phase 2).

echo "c XXXX" >/var/run/isakmpd.fifo

Note générale : attention, il peut un avoir un délai dans l’exécution des commandes

FAQ

Que veulent dire les messages suivants ?

isakmpd[7864]: dpd_handle_notify: bad R_U_THERE seqno 551411465 <= 2374875689

C’est un message relatif au DPD (Dead peer detection) qui est un mécanisme pour détecter des éventuels soucis avec VPN. Voir http://www.juniper.net/techpubs/software/erx/junose61/swconfig-routing-vol1/html/ipsec-config4.html#1329479

isakmpd[7864]: attribute_unacceptable: AUTHENTICATION_METHOD: got PRE_SHARED, expected RSA_SIG
isakmpd[7864]: message_negotiate_sa: no compatible proposal found
isakmpd[7864]: dropped message from 192.0.2.1 port 500 due to notification type NO_PROPOSAL_CHOSEN

Il s’agit d’un routeur VPN distant qui essaye de se connecter, mais n’a pas de configuration correspondante. Cela peut se produire typiquement si son adresse IP change, et qu’elle n’est plus présente dans la configuration d’ISAKMPD.

isakmpd[10418]: isakmpd: phase 1 done (as responder): initiator id 192.0.2.1, responder id 1.2.3.4, src: 1.2.3.4 dst: 192.0.2.1
isakmpd[10418]: dropped message from 192.0.2.1 port 500 due to notification type INVALID_ID_INFORMATION
isakmpd[10418]: message_validate_notify: protocol not supported

Cela signifie a priori que la configuration en face à un réseau « remote » incorrect (soit complètement faux, soit pas sous la forme ADRESSE RÉSEAU / MASQUE)

Voir http://www.thegreenbow.com/support_flow.html?page=12105C&lang=fr

Méthode isakmpd via ipsec.conf

Mise en place d’un VPN « simple » entre 2 machines OpenBSD

On dispose de :

  • 2 passerelles VPN OpenBSD gw1 et gw2 (192.0.2.254 et 198.51.100.254)
  • 2 LAN net1 et net2 correspondants (192.0.2.0/24 et 198.51.100.0/24)

Sur gw1 :

Vérifier que les sysctl suivants sont actifs :

# sysctl net.inet.esp.enable
net.inet.esp.enable=1
# sysctl net.inet.ah.enable
net.inet.ah.enable=1
# sysctl net.inet.ip.forwarding
net.inet.ip.forwarding: 1 -> 1

Activer l’interface enc0 :

ifconfig enc0 up
echo up >/etc/hostname.enc0

Dans /etc/pf.conf, positionner :

set skip on {lo0 enc0}
pass in on $ext_if proto esp from $addr_gw2 to ($ext_if)
pass in on $ext_if proto udp from $addr_gw2 to ($ext_if) port {isakmp, ipsec-nat-t}

Dans /etc/ipsec.conf, positionner :

local_ip="192.0.2.254"
local_network="192.0.2.0/24"
remote_ip="198.51.100.254"
remote_network="198.51.100.0/24"

ike passive esp from $local_network to $remote_network peer $remote_ip
ike passive esp from $local_ip to $remote_network peer $remote_ip
ike passive esp from $local_ip to $remote_ip

Récupérer la clé pré-générée de l’autre passerelle :

scp gw2:/etc/isakmpd/local.pub /etc/isakmpd/pubkeys/ipv4/198.51.100.254

Tester la configuration :

ipsecctl -n -f /etc/ipsec.conf

Démarrer le service :

isakmpd -K
ipsecctl -f /etc/ipsec.conf

Puis effectuer les mêmes actions sur l’autre passerelle.

On doit alors pouvoir pinger chaque réseau à partir de l’autre passerelle ou de l’autre réseau.

Pour relancer un VPN il suffit de récupérer le nom des variables isakmpd générées par ipsectl via la commande suivante puis d’utiliser la même méthode qu’avec isakmpd.

ipsecctl -nvf /etc/ipsec.conf

Debug IPsec

Eteindre isakmpd :

/etc/rc.d/isakmpd stop

Dans une console :

isakmpd -d -DA=90 -K

Dans une autre console :

ipsecctl -f /etc/ipsec.conf