Jump to content
×
×
  • Create New...

Firewall / Packet Filter


Thyrios
 Share

Recommended Posts

Niveau requis Intermédiaire

 

 

Bonjour,

 

Version FreeBSD : 9.2 Release (à voir si ça passe avec plus ancien) Suite à la remarque de Galet de me suis dit que ça pourrait pas être un mal si je réalisais un cours rapide sur Packet Filter, alias PF. J'ai vu quelques fichiers de conf traînant sur ce forum. Ces fichiers ne sont pas du tout optimisés... Attention, je n'ai pas dit fonctionnel (quoique...), mais optimisé. Ce qu'il faut savoir avant de se lancer dans la rédaction pur du fichier de conf : sa structure. Bah ouai ça peut paraitre idiot mais ça compte.

 

C'est beau quand c'est bien organisé non ? Autre petit truc à connaitre : La commande pfctl

 

Révélation
  • pfctl -e  ==> Mets PF en marche e=enable
  • pfctl -d  ==> Stop PF: d=disable
  • pfctl -f /etc/pf.conf ==> Test & Charge le fichier de règle que contient le fichier /etc/pf.conf
  • pfctl -nf /etc/pf.conf ==> Test le fichier de règle que contient le fichier /etc/pf.conf SANS LE CHARGER. Pratique si vous avez fait du caca...
  • pfctl -sr ==> Permet de voir les règles de filtrage en cours de fonctionnement
  • pfctl -sn ==> Permet de voir les règles de nat en cours de fonctionnement
  • pfctl -vvsr ==> Permet d'avoir les règles de filtrage en cours avec en plus des statistics pour chaque règles.

 

Les Macros & Listes

 

Révélation

 

En gros, c'est ni plus ni moins que des variables que vous aller pouvoir réutiliser dans vos différentes règles. On peut y mettre: Les ports, les interfaces, voir des adresses IP. Syntaxe :

 

  • ext_if="em0"
  • port_ssh = "30322"
  • port_metin2 = "{ 13000, 13001, 13002, 13003, 13004 }" équivalent à: port_metin2 = "{ 13000:13004 }"
  • ips_autorisé = "{ 22.44.66.88 - 22.44.66.99 }" Cela regroupe toute la plage d'ips entre .88 et .99.

 

On peut aussi rajouter une exclusion à l'aide du caractère : ! Exemple :

 

  • ips_autorisé = "{ 22.44.66.88 - 22.44.66.99, !22.44.66.88.77 }"

 

Bon normalement si vous avez suivi la logique vous avez compris. Si je ne me trompe pas vous pouvez aussi l'utiliser avec les ports.

 

 

Les Tables

 

Révélation

 

Alors les tables c'est juste un truc trop de la balle qui déboite tout ! La différence avec les macros ? Ils essayent pas de vous refourguer une... Blague à part, vous pouvez intégrer des ips dynamiquement dans les tables. En gros, un petit malin vous casse les pieds ==> bim dans la table, PAF bloqué ! Idéal aussi dans le cas où vous utilisez fail2ban (Je vous en parlerais p-e un jour). Syntaxe :

 

Définir une table :

 

  • table persist file "/etc/spammers"
  • table const { 10.0.0.0/8, 172.16/12, 192.168/16 }

 

Par défaut une table vide est supprimée. L'option persist permet d'outrepasser ce paramètre. l'option file permet de renseigner un fichier avec des ips. Une ligne = une adresse ip. Les adresses IP peuvent-être noté en notation CIDR. L'option const permet de faire en sorte que la table est inaltérable dynamiquement.

 

Pour ajouter une adresse ip à une table dynamiquement :

 

  • pfctl -t bruteforce -T add 192.168.2.1

 

Pour supprimer une adresse ip d'une table dynamiquement :

 

  • pfctl -t bruteforce -T delete 192.168.2.1

 

Toutes modifications faites dynamiquement ne sont pas répercutées dans le fichier de conf. Ni même dans les fichiers d'adresses IP. Vous devez les ajouter manuellement.

Autre petite particularité des tables : Grâce à des options, PF est capable de renseigner une table tout seul si jamais il décide que l'adresse ip est indésirable.

 

Exemple :

#definition des tables
table  persist

block quick from 

pass in log quick on $ext_if proto { tcp, udp } from any to ($ext_if) port $port_ext flags S/SA keep state (max-src-conn 20, max-src-conn-rate 5/3, overload  flush global)
Vous remarquez à la fin de la règle pass : keep state (max-src-conn 20, max-src-conn-rate 5/3, overload flush global) En gros si une adresse IP source dépasse les 20 connexions simultanées OU qu'elle initie 5 connexions en moins de 3 secondes, elle est envoyée dans la table bruteforce. Et grâce à l'option flush global, tous les états en cours sont coupés net.

 

 

Les Options

 

Révélation

 

Il y a moulte options que l'ont peut utiliser avec PF. Pour en avoir une idée regardez dans le man de PF. Celles qui me paraissent les plus intéressantes sont :

Set block-policy
Set skip
La première permet de définir la chose à faire en cas de blocage de paquets, deux choix :
 
  • -drop : détruit le paquet sans rien dire.
  • -return : détruit le paquet, et renvoie un petit message en disant qu'il est pas autorisé à venir ici.

 

Par défaut, c'est sur drop. L'option return est à choisir dans certains cas. Pas intéressant pour nous. Toutefois je préfère quand même renseigner l'option, au moins on est sûr de ce que fait PF. La seconde permet de renseigner les interfaces sur lesquelles PF ne filtrera pas. Exemple l'interface de bouclage :

set skip on lo0

 

 

 
La Normalisation du Trafic

 

Révélation

 

Cette normalisation permet de détruire tous les paquets qui sont "défectueux". En gros deux paquets se chevauchent : poubelle. Très pratique, toutefois, il peut poser problème lors de l'utilisation de certaines applications comme le partage de dossier via le protocole NFS. Rien à craindre chez nous, on peut l'utiliser.

Scrub in all
La fonction antispoof permet d'éviter l'utilisation d'une adresse ip sur une interface où elle n'est pas censée se trouver. En gros vous recevez un paquet d'une adresse ip de bouclage sur l'interface externe.
Antispoof for $ext_if

 

 

 
La QoS
 
Révélation

Pas d'utilité ici comme dit plus haut. En plus de ça faudrait recompiler le noyau. ALTQ n'étant pas présent dans le noyau GENERIC de FreeBSD...

 

Les Règles de NAT

 

Révélation

Pas besoin non plus ici. Votre FreeBSD ne fait pas office de routeur. Dans le cas où il vous sert aussi de serveur VPN, ça p-e intéressant, mais sujet non traité ici.

 

Les Règles de Pare-Feu

 

Révélation

 

Comment bien faire sa règle. Voici la syntaxe d'une règle :

block/pass in/out log quick on  inet/inet6 proto  from  port  os  to  port  flags  state
  • block/pass : Bon je vous fais pas de dessin. Soit vous bloquez, soit ça passe.
  • in/out : Permet de définir le sens où s'applique la règle, en entrée ou en sortie.
  • log : S'il est renseigné, log tous ce qui correspond à la règle dans l'interface pflog0
  • quick : Faut savoir que PF lit les règles dans un sens bien particulier. En gros la dernière règle trouvée correspondant au paquet est appliquée.

 

Cette option permet de contrer cette lecture. Dès que le paquet correspond à une règle quick, la règle s'applique.

 

  • on : Permet de définir l'interface où s'applique la règle.
  • inet/inet6 : Définit si applicable à de l'ipv4 ou ipv6.
  • proto : Le protocole à appliquer: tcp, udp, icmp. Pour l'icmp on pourra aller un peu plus loin en définissant le type d'icmp.
  • from : D'où viens le paquet.
  • port : De quel port provient le paquet. Honnêtement on l'utilise dans des cas rarissimes. En effet la plupart du temps, les ports sources sont définit dynamiquement.
  • os : Truc assez sympa que j'ai jamais utilisé. Il permet de dire quel OS est autorisé à passer. À voir dans le man de pf.conf pour plus d'info.
  • to : L'adresse de destination du paquet.
  • port : Le port de destination du paquet.
  • flags : Permet de définir le type de paquet tcp autorisé, SYN, SYN/ACK, ACK, etc. Il y en a pas mal.

 

Par défaut c'est l'option : flag S/SA

En gros SYN et SYN/ACK. L'initialisation d'une connexion TCP, plus d'info dans le man de pf.conf.

 

  • state : Ce paramètre permet de définir comment PF gère sa table d'état. Par défaut, même si non renseigné, PF mets l'option keep state, même pour de l'udp.

 

Étrange non ? Hé oui, PF est capable de savoir que deux paquets udp font parti d'une même connexion. Avec le keep state, on peut renseigner les options qu'on a vu dans les tables plus haut. On peut aussi renseigner l'option "synproxy state". Cette option permet de faire en sorte que c'est PF qui initie la connexion TCP (les trois poignées de main). Tant que PF n'a pas reçu les SYN, SYN/ACK, ACK, il ne passe pas les paquets à l'application. Ceci permet par exemple que les requêtes SYN soit arrêté à PF, et donc permet d'éviter qu'apache se retrouve submergé en cas d'attaque DOS. PF étant plus résistant que apache.

Voilà un petit récap de tout ça : Ceci est un exemple !

##MACROS & liste
# on définit la carte réseau
ext_if="em0"

# on définit l'ip du serveur
ext_adr="X.X.X.X"

# on definit les ports utilisés
metin2_port = "{ XXXXX, XXXXX, XXXXXX }"
ssh_port = "XX"
mysql_port = "3306"

# on définit les ports que le serveur va contacter (http, https, ftp, smtp, dns
srv_port_out = "{80, 443, 21, 25, 53}"

#on définit le type d'icmp
icmp_types = "echoreq"

##Tables
table  persist file "/home/ssh_bruteforce"
table  persist file "/home/abusive_ips"

##Options
# Ne pas filtrer sur l'interface de bouclage
set skip on lo0
set block-policy drop

#Normalisation des paquets entrants
scrub in all fragment reassemble

#Antispoof
antispoof for $ext_if

##REGLES
#blocage par défaut
block all

#on stop directement ici si l'ip est banni (quick)
block quick on $ext_if from 
block quick on $ext_if from 

# On autorise les connexions ssh, web, et mysql
pass in inet proto tcp from any to $ext_adr port $ssh_port flags S/SA keep state (max-src-conn 15, max-src-conn-rate 5/3, overload  flush global)
pass in inet proto tcp from any to $ext_adr port www flags S/SA synproxy state
pass in inet proto tcp from any to $ext_adr port $mysql_port flags S/SA keep state (max-src-conn 15, max-src-conn-rate 5/3, overload  flush global)

#metin2 autorisé
pass in inet proto tcp from any to $ext_adr port $metin2_port flags S/SA keep state (max-src-conn 20, max-src-conn-rate 10/5, overload  flush)

#traffic sortant
pass out inet proto {tcp, udp} from $ext_adr to any port $srv_port_out

#definition de l'icmp
pass log inet proto icmp all icmp-type $icmp_types keep state
Il existe deux écoles pour la rédaction de règles: Ceux qui autorisent tout et bloquent ensuite; Ceux qui bloquent tout et autorisent ensuite. Personnellement je bloque, et ensuite j'autorise. Chacun sa popote. Notez ce que j'ai fais pour l'icmp. J'ai défini le type sur echo-request, c'est ce qui caractérise le ping. En gros le seul icmp autorisé c'est le ping. Dans les autres tutoriels on vous dit de renseigner le fichier rc.conf et de reboot la machine pour activer pf. J'aime pas cette pratique... Pourquoi redémarrer quand c'est pas nécessaire... Pour charger pf dynamiquement :
kldload pf
Ensuite activez-le :
pfctl -e
Testez votre fichier de conf :
pfctl -nf /etc/pf.conf
S'il ne vous dit rien, chargez le fichier :
pfctl -f /etc/pf.conf
Enfin, si tout se passe bien, renseignez le fichier /etc/rc.conf :
pf_enable="YES"
pf_rules="/etc/pf.conf"
pflog_enable="YES"
Comme ça au redémarrage, pf se charge correctement. Je n'ai pas tout abordé dans ce poste. Je n'ai pas parlé des ancres, ou encore des labels. Je ferais p-e une mise à jour du poste si l'envie m'en prend. J'ai tiré tout ça du man de PF, du Handbook, ainsi que d'un bouquin : ICI.

 

 
Cordialement,
Hey hey
  • J'adore 4
Link to comment
Share on other sites

  • Replies 15
  • Created
  • Last Reply

Top Posters In This Topic

  • Funkiest

Pas de quoi! ;)

 

Galet, ipfw est aussi un pare feu. Mélanger deux pare feu, c'est des coups à ce mélanger les pinceaux et à faire plus de merde qu'autres choses...

 

En réalité, mon pare-feu possède des règles trouvées un peu partout & f2b est relié a mon ipfw, notamment pour bannir etc... C'est le bordel un peu ^^

 

Mais, tu as raison, en tout cas encore une fois, très bon tutortage !

Link to comment
Share on other sites

Encore merci!

 

A la limite je pourrais mettre à jour le tutoriel avec l'intégration de fail2ban dans pf, quand il sera accepté. Il y a plein de tuto sur le net. C'est pas très compliqué.

Ça te permettra de modifier ta conf et de tout centraliser sur PF.

Link to comment
Share on other sites

  • 2 weeks later...
  • 3 years later...
  • 1 month later...
 Share



Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.