Packet Filter

Mon nouveau jouet

date
5 / 5 / 2010
comments
0

Pris un coup de folie et je me suis procuré le dernier joujou à la mode, un petit nokia n97. Les forfaits c'est vraiment du viol^Wvol, donc clairement je ne vous recommande pas ça, moi j'ai eu l'opportunité de ne pas le payer donc bon. Ce sera nettement plus convi quand il y aura un opérateur mobile valable avec du vrai internet.

En attendant tout ça j'ai quand même pu faire des choses sympa, faut dire que Nokia, contrairement à la pomme, laisse pas mal de liberté essentiellement parce qu'on peut installer tout ce qu'on veut sur la machine et ils fournissent tous les outils pour. J'ai le bestiau depuis seulement quelques jours donc j'ai pas encore trop réfléchi sur le coté dev, mais je pense qu'on peut sortir de la prison Internet by orange avec quelques tools réseau bien pensés.

Unes des premières appli que j'ai testé c'est putty mobile. En wifi sur le réseau local je passe par le port 22 tout marche normal. Seulement sur internet c'est pas sur le port 22 qu'il est mon serveur mais plutôt disons 1234, et avec Internet by orange forcément le port 1234 sortant ça pourrait bien être du contenu pédonazi et alors ça passe pas.

Du coup je browse sur un de mes sites, je chope l'IP 80.10.46.66 de la passerelle nazie dans mes logs, comme c'est bien pensé l'IP de la passerelle change souvent et faut plutôt utiliser 80.10.46.0/24 (voir plus si ça se trouve).

Un petit coup de pf.conf sur la box :

nazis = "80.10.46.0/24"
rdr pass proto tcp to port 1234 -> $serv port ssh # Pour les gens normaux
rdr pass proto tcp from $nazis to port ssh -> $serv

Et taaadaam :

putty symbian

Sûrement à bientôt pour de nouvelles aventures Internet By Orange.

Astuce pf du jour

date
23 / 2 / 2010
comments
0

J'ai la chance d'avoir une bibliothèque avec un rayon informatique bien rempli dans mon Université, dernièrement j'y ai emprunté ce bouquin. Là dedans j'y ai vu une syntaxe pour décrire le réseau local que j'avais raté quand j'ai lu la doc :

ext_if = "rl0"
# Au lieu de
localnet = "{ 192.168.0.0/24, 2a01:e35:2e58:9820::/64 }"
# On peut mettre
localnet = $ext_if:network
# Ou encore
localnet = rl0:network

Pf va lui même calculer le réseau local à l'aide de l'IP du netmask et du prefixe.

Attention tout de même si vous avez plusieurs IP (v4 et v6) sur l'interface, ça peut produire des règles redondantes, en cas de doute :

pfctl -sr

EDIT (27/02/10) : En fait quand il y a des alias sur l'IP il va les évaluer mais pour ne spécifier que l'adresses (sans les alias) on peut mettre $ext_if:network:0

pfstat

date
6 / 12 / 2009
comments
0

J'aime pas franchement les graphe les chiffres tout ça (j'entends déjà rire les gens qui me connaissent devant ce mensonge éhonté). Mais j'avoue que j'aime bien les stats donnée par pfstat (le site est souvent down en ce moment). Ce petit soft récolte des statistiques temporelles sur pf et peut les cracher sous forme de graphe.

Petit exemple tout de suite, ce graphe représente le traffic entrant/sortant (in/out) autorisé/bloqué (block in/block out) sur mon routeur pour les dernières 24h.

stats solo

C'est assez interessant, il peut faire une multitude de graphes configurables, je vais pas poser ma conf ici parce que je l'ai honteusement pompée sur calomel. À noter que pfstat est aussi disponible en daemon (pfstatd), ça permet de générer les images des statistiques d'une autre machine. Il suffit de lancer pfstatd sur la machine ou l'on veut faire des statistiques, et lancer pfstat (dans cron par exemple) avec les options -r host:port.

Vous pouvez voir ici ce qui se passe sur mes deux modestes machines qui font exister philpep.org.

EDIT 10 janvier 2010 : pfstat ne semble plus maintenu :/ , en tout cas il a du mal avec les dernières versions de pf. Bref les graphes que vous voyez sont vieux

fail2ban sshd et pf

date
18 / 11 / 2009
comments
0

Mon /var/log/auth.log est blindé de choses du genre :

Nov 18 17:56:27 lenine sshd[49297]: Invalid user marcio from 24.17.93.35
Nov 18 17:56:27 lenine sshd[49297]: error: PAM: authentication error for illegal user marcio from 24.17.93.35
Nov 18 17:56:27 lenine sshd[49297]: Failed keyboard-interactive/pam for invalid user marcio from 24.17.93.35 port 63330 ssh2
Nov 18 17:58:05 lenine sshd[49312]: Address 92.126.194.108 maps to alfa.navsystem.ru, but this does not map back to the address - POSSIBLE BREAK-IN ATTEMPT!
Nov 18 17:58:05 lenine sshd[49312]: Invalid user marcio from 92.126.194.108
Nov 18 17:58:05 lenine sshd[49312]: error: PAM: authentication error for illegal user marcio from 92.126.194.108
Nov 18 17:58:05 lenine sshd[49312]: Failed keyboard-interactive/pam for invalid user marcio from 92.126.194.108 port 38920 ssh2

C'est une attaque classique par dictionnaire mais distribuée. Ma seule défense pour l'instant c'est mon parre feu qui bloquait les bruteforces un peu trop rapides. Alors même si pf en filtre quand même pas mal, les petits malins tournent sur plusieurs IPs pour faire un bruteforce moins visible.

J'ai donc décidé de bloquer le reste avec fail2ban, la conf par défaut n'est pas adapté à ma config, j'ai des besoin précis sur le filtre sshd et il faut que ça marche avec pf.

L'install est toujours aussi simple :

# make -C /usr/ports/security/py-fail2ban install

La conf est dans /usr/local/etc/fail2ban

En premier lieu, créer l'action pour pf :

action.d/pf.conf

[Definition]
actionstart = 
actionstop = 
actioncheck = 
actionban = pfctl -t flood -T add <ip>
actionunban = pfctl -t flood -T del <ip>

Comme vous voyez on va largement utiliser les tables pf, il y a donc quelques modifs à faire dans votre /etc/pf.conf :

# La table
table <flood> persist
# On laisse passer tout sauf les IP de <flood>
pass in inet proto tcp from ! <flood> to $ext_if port ssh

Ensuite on modifie le filtre filter.d/sshd.conf :

[INCLUDES]

before = common.conf

[Definition]

_daemon = sshd

failregex = ^%(__prefix_line)s[iI](?:llegal|nvalid) user .* from <HOST>\s*$
               ^%(__prefix_line)sAddress <HOST> .* POSSIBLE BREAK-IN ATTEMPT\s*$

ignoreregex =

Et on active le filtre dans jail.conf :

[ssh-pf]
enabled  = true
filter   = sshd
action   = pf
          sendmail-whois[name=SSH, dest=root@localhost, sender=noreply@localhost]
logpath  = /var/log/auth.log
maxretry = 1
bantime  = 86400

Ils sont bannis pour 1 jours (de quoi leur faire perdre beaucoup de temps). En prime pour chaque ban vous recevez le whois de l'IP concernée par mail.

Finalement on oublie pas de lancer fail2ban :

# echo fail2ban_enable=\"YES\" >> /etc/rc.conf
# /usr/local/etc/rc.d/fail2ban start

Ce qui pourrait être intéressant c'est de choper automatiquement les adresses mail Abuse du whois pour envoyer un mail au FAI du méchant pour lui dire tout ce qu'on pense de son client. Mais bon, on ne va pas non plus faire de délation à la HADOPI.

Limiter un utilisateur avec pf

date
11 / 9 / 2009
comments
0

OpenBSD Packet Filter permet de filtrer les paquets suivant l'UID de provenance (et peut être même de destination mais ça nous intéresse moins.

Vous avez un amis qui se connecte en ssh chez vous pour poser un irssi dans un GNU screen. C'est super sympa de votre part, seulement si on a pas une confiance totale en cet utilisateur il pourrait (lui ou un virus) se servir de son accès pour utiliser votre IP et balancer du spam, lancer une attaque de banque ou je ne sais quoi encore. Résultat : vous êtes responsable.

L'idée est simple, nous allons filtrer le trafic sortant de cet utilisateur (de login fictif machin) en lui autorisant uniquement le port IRC 6667 :

pass out on $ext_if proto tcp to port 6667 user machin tag TAG_MACHIN
block out quick on $ext_if proto tcp all user machin ! tagged TAG_MACHIN

La première règle autorise le port 6667 sortant pour machin et tagge le paquet avec TAG_MACHIN. La deuxième bloque tout ce qui vient de machin et qui n'est pas taggé avec TAG_MACHIN. Ce qui fait exactement ce que l'on veut.

Le mot clef quick permet a la règle d'être prise en compte immédiatement peu importe les règles suivantes (ce qui protège d'une éventuelle règle qui ferait tout passer ensuite).

Pour continuer dans l'exemple, il peut être utile d'autoriser les query DNS pour cet utilisateur (si vous n'avez pas de serveur DNS en interne), ça se passe en 53/udp :

pass out on $ext_if proto tcp to port 6667 user machin tag TAG_MACHIN
pass out on $ext_if proto udp to port domain user machin tag TAG_MACHIN
block out quick on $ext_if proto tcp all user machin ! tagged TAG_MACHIN

On peut même faire des listes sur les port et/ou utilisateurs :

users = { machin, truc }
pass out on $ext_if proto tcp to port { 6667, http } user $users tag TAG_USERS
pass out on $ext_if proto udp to port domain user $users tag TAG_USERS
block out quick on $ext_if proto tcp all user $users ! tagged TAG_USERS