Tout bloquer sauf squid avec iptables

Bonjour à tous,

J’ai un routeur qui fais également office de proxy transparent sur le port 80.
Actuellement il fonctionne bien, j’ai créer un fichier iptables basique contenant les 2 règles suivantes :

iptables -t nat -A POSTROUTING -o eth2 -j MASQUERADE iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 3128

eth2 c’est le réseau internet
eth0 c’est le réseau lan utilisant le proxy

Je souhaites donc bloquer toute connexion entrante et sortante qui ne passe pas par le port 80, 3128 et 443.

Mais j’ai des problèmes j’ai essayé de tout bloquer dès le départ :

iptables -t filter -P INPUT DROP iptables -t filter -P FORWARD DROP iptables -t filter -P OUTPUT DROP

Et d’autoriser après mais je bloque carrément tout ^^
Quelqu’un peut-il m’aider à créer ce pare-feu minimal car je dois bien bloquer sur sur la table filter et surtout nat.

Merci d’avance

Si tu fais ça tu risques d’avoir des misères. En général il faut aussi autoriser le DNS.
Il va aussi falloir préciser un peu pour chaque port : connexions entrantes, sortantes, traversantes, par quelle interface ?

Non, la table nat ne sert pas à bloquer. C’est le rôle de la table filter seulement. N’importe quel paquet émis, reçu ou retransmis traverse obligatoirement une et une seule chaîne de la table filter.

A ok pour le dns, j’ai déjà fait une erreur sur ce point :unamused:
Je suppose qu’il me faut donc un truc du genre :

iptables -t filter -A OUTPUT -p tcp --dport 53 -j ACCEPT iptables -t filter -A OUTPUT -p udp --dport 53 -j ACCEPT iptables -t filter -A INPUT -p tcp --dport 53 -j ACCEPT iptables -t filter -A INPUT -p udp --dport 53 -j ACCEPT

Là j’en suis donc à cela :

[code]#!/bin/sh
#/etc/init.d/iptables
#Chargement/déchargement d’iptables
#Le rendre exécutable “sudo chmod +x /etc/init.d/iptables”
#Le charger au démarrage “sudo update-rc.d iptables defaults”
#Pour voir le status “sudo iptables -L”

BEGIN INIT INFO

Provides: iptables

Required-Start:

Should-Start:

Required-Stop:

Should-Stop:

Default-Start: 2 3 4 5

Default-Stop: 0 1 6

Short-description: iptables

Description: Firewall

END INIT INFO

je vide les tables actuelles

iptables -t filter -F

idem avec les règles personnelles

iptables -t filter -X

je bloque tout

iptables -t filter -P INPUT DROP
iptables -t filter -P FORWARD DROP
iptables -t filter -P OUTPUT DROP

proxy transparent

iptables -t nat -A POSTROUTING -o eth2 -j MASQUERADE
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 3128

connexion établie

iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

loopback

iptables -t filter -A INPUT -i lo -j ACCEPT
iptables -t filter -A OUTPUT -o lo -j ACCEPT

multicast

iptables -A INPUT -p igmp -j ACCEPT

ping

iptables -t filter -A INPUT -p icmp -j ACCEPT
iptables -t filter -A OUTPUT -p icmp -j ACCEPT

ssh

iptables -t filter -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 22 -j ACCEPT

le dns que j’ai oublié ^^

iptables -t filter -A OUTPUT -p tcp --dport 53 -j ACCEPT
iptables -t filter -A OUTPUT -p udp --dport 53 -j ACCEPT
iptables -t filter -A INPUT -p tcp --dport 53 -j ACCEPT
iptables -t filter -A INPUT -p udp --dport 53 -j ACCEPT
[/code]

Merci

Les règles pour le port 53 en INPUT ne sont utiles que pour autoriser les requêtes vers un serveur DNS qui tourne sur la machine.
Pour le reste, ton jeu de règles ne correspond pas vraiment à ton titre “tout bloquer sauf squid” puisque ça accepte du SSH, de l’ICMP… Ma demande de précisions tient toujours.

Là ssh et ping c’est essentiellement pour les tests avant que cela soit fonctionnelle.
La patte du proxy eth2 (192.168.1.2) est connecté directement à la box du FAI.

La patte eth0 (192.168.2.252) récupère tout ce qui arrive du port 80 et le redirige dans squid. Cette patte est connecté directement à un routeur 2 (192.168.2.254) qui lui dispose d’une autre carte (192.168.3.254).

Les clients sont sur le réseaux 192.168.3.0 (passerelle 192.168.3.254) et comme il n’y a pas de nat sur le routeur 2, je peux voir l’activité des utilisateurs par sarg sur mon proxy.

Le seul moyen d’avoir internet est de passer par le routeur/proxy sous GNU/Linux je veux donc que les clients ne puissent utiliser que les ports 80 (qui passera par le proxy transparent) et 443 (non transparent normal).

J’espère avoir donné les détails voulu.

Bon, on va dégrossir un peu.
A priori il faut autoriser les connexions vers

  • le port 3128/TCP en entrée sur l’interface LAN vers le proxy
  • le port 53/TCP et UDP en sortie sur l’interface WAN pour la résolution DNS du proxy
  • le port 53/TCP et UDP en traversée de l’interface LAN vers WAN pour la résolution DNS des postes clients vers l’extérieur (car proxy transparent) ; sauf s’ils utilisent un serveur/relais DNS qui tourne sur la machine proxy, alors c’est en entrée
  • le port 443/TCP en traversée de l’interface LAN vers WAN pour les connexions HTTPS des postes clients vers l’extérieur
    EDIT :
  • et évidemment, le port 80/TCP en sortie sur l’interface WAN pour les connexions HTTP du proxy
  • optionnellement, le port 443/TCP en sortie sur l’interface WAN pour les connexions HTTPS si le proxy est utilisé de façon explicite par un client

Ce qui donne, en plus des règles de base jusqu’à la section “loopback” incluse :

iptables -t filter -A INPUT -i eth0 -p tcp --dport 3128 -j ACCEPT
iptables -t filter -A OUTPUT -o eth2 -p udp --dport 53 -j ACCEPT
iptables -t filter -A OUTPUT -o eth2 -p tcp --dport 53 -j ACCEPT
iptables -t filter -A OUTPUT -o eth2 -p tcp --dport 80 -j ACCEPT
iptables -t filter -A OUTPUT -o eth2 -p tcp --dport 443 -j ACCEPT
iptables -t filter -A FORWARD -i eth0 -o eth2 -p udp --dport 53 -j ACCEPT
iptables -t filter -A FORWARD -i eth0 -o eth2 -p tcp --dport 53 -j ACCEPT
iptables -t filter -A FORWARD -i eth0 -o eth2 -p tcp --dport 443 -j ACCEPT

Merci beaucoup :smiley:
Je vois bien mes erreurs j’ai pas suffisamment réfléchi sur les conséquences d’un blocage en sortie, je pense que c’est du à l’habitude de bloquer tout ce qui rentre et d’autoriser tout ce qui sort ^^

Je vais donc tester cela :wink:

Edit: Chef, petite faute de frappe dans la chaîne OUTPUT c’est -o :mrgreen:

J’ai appliqué les règles ci-dessus mais internet ne fonctionnait pas avec les clients. Il était impossible avec un pc client de pinguer la box 192.168.1.1
Voici ce que donnais un “iptables -L” :

[code]Chain INPUT (policy DROP)
target prot opt source destination
ACCEPT all – anywhere anywhere state RELATED,ESTABLISHED
ACCEPT all – anywhere anywhere
ACCEPT tcp – anywhere anywhere tcp dpt:3128
ACCEPT igmp – anywhere anywhere
ACCEPT icmp – anywhere anywhere
ACCEPT tcp – anywhere anywhere tcp dpt:ssh

Chain FORWARD (policy DROP)
target prot opt source destination
ACCEPT udp – anywhere anywhere udp dpt:domain
ACCEPT tcp – anywhere anywhere tcp dpt:domain
ACCEPT tcp – anywhere anywhere tcp dpt:https

Chain OUTPUT (policy DROP)
target prot opt source destination
ACCEPT all – anywhere anywhere state RELATED,ESTABLISHED
ACCEPT all – anywhere anywhere
ACCEPT udp – anywhere anywhere udp dpt:domain
ACCEPT tcp – anywhere anywhere tcp dpt:domain
ACCEPT icmp – anywhere anywhere
ACCEPT tcp – anywhere anywhere tcp dpt:ssh
ACCEPT tcp – anywhere anywhere tcp dpt:domain
ACCEPT udp – anywhere anywhere udp dpt:domain[/code]

Je vais donc tacher de voir ce qui bloque, si quelqu’un a une idée, merci.

J’ai pu regarder rapidement, ça fonctionne, voila ce que j’ai fais :

[code]#!/bin/sh
#/etc/init.d/iptables
#Chargement/déchargement d’iptables
#Le rendre exécutable “sudo chmod +x /etc/init.d/iptables”
#Le charger au démarrage “sudo update-rc.d iptables defaults”
#Pour voir le status “sudo iptables -L”

BEGIN INIT INFO

Provides: iptables

Required-Start:

Should-Start:

Required-Stop:

Should-Stop:

Default-Start: 2 3 4 5

Default-Stop: 0 1 6

Short-description: iptables

Description: Firewall

END INIT INFO

je vide les tables actuelles

iptables -t filter -F

idem avec les règles personnelles

iptables -t filter -X

je bloque tout

iptables -t filter -P INPUT DROP
iptables -t filter -P FORWARD ACCEPT #si DROP ne marche plus
iptables -t filter -P OUTPUT DROP

proxy transparent

iptables -t nat -A POSTROUTING -o eth2 -j MASQUERADE
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 3128

connexion établie

iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

loopback

iptables -t filter -A INPUT -i lo -j ACCEPT
iptables -t filter -A OUTPUT -o lo -j ACCEPT

iptables -t filter -A INPUT -i eth0 -p tcp --dport 80 -j ACCEPT #ajout
iptables -t filter -A INPUT -i eth0 -p tcp --dport 3128 -j ACCEPT
iptables -t filter -A OUTPUT -o eth2 -p tcp --dport 80 -j ACCEPT #ajout
iptables -t filter -A OUTPUT -o eth2 -p udp --dport 53 -j ACCEPT
iptables -t filter -A OUTPUT -o eth2 -p tcp --dport 53 -j ACCEPT
iptables -t filter -A FORWARD -i eth0 -o eth2 -p udp --dport 53 -j ACCEPT
iptables -t filter -A FORWARD -i eth0 -o eth2 -p tcp --dport 53 -j ACCEPT
iptables -t filter -A FORWARD -i eth0 -o eth2 -p tcp --dport 443 -j ACCEPT

multicast

iptables -A INPUT -p igmp -j ACCEPT

ping

iptables -t filter -A INPUT -p icmp -j ACCEPT
iptables -t filter -A OUTPUT -p icmp -j ACCEPT

ssh

iptables -t filter -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 22 -j ACCEPT

le dns

iptables -t filter -A OUTPUT -p tcp --dport 53 -j ACCEPT
iptables -t filter -A OUTPUT -p udp --dport 53 -j ACCEPT[/code]

Normal, le ping (ICMP echo) ne fait pas partie des communications autorisées en traversée (DNS et HTTPS). S’il le faut,

Pour le reste, je pense qu’il manque une règle pour la chaîne FORWARD dans le paragraphe “connexion établie”. Les règles que tu as ajoutées pour le port 80 ne sont pas utiles car rien sur le proxy n’écoute sur ce port (la règle REDIRECT change le port avant que la table filter voie les paquets).

PS : Pour lister complètement les règles, je préfère la commande iptables-save.
PS2 : Les dernières règles DNS sont en doublon.

OK d’accord, pour le doublon DNS je m’en suis rendu compte après je l’ai corrigé aussitôt, de tout façon la je vais peaufiner le parfeu :wink:

La commande iptables-save est mieux en effet, elle vient d’être implanté dans mon cerveau :mrgreen:

Encore merci pour le temps que tu m’as accordé à la résolution de mon problème.

@+

Bonjour, voici mes corrections apportées :

[code]#!/bin/sh
#/etc/init.d/iptables
#Par HacKurx - GPLv3
#Iptables avec NAT pour proxy transparrent
#Le rendre executable “sudo chmod +x /etc/init.d/iptables”
#Le charger au demarrage “sudo update-rc.d iptables defaults”
#Pour voir les regles “sudo iptables -L” ou “iptables-save”

BEGIN INIT INFO

Provides: iptables

Required-Start:

Should-Start:

Required-Stop:

Should-Stop:

Default-Start: 2 3 4 5

Default-Stop: 0 1 6

Short-description: iptables

Description: Firewall

END INIT INFO

echo “Iptables [done]”

Reinitialisation de la table FILTER"

iptables -F
iptables -X
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP

Reinitialisation de la table NAT

iptables -t nat -F
iptables -t nat -X
iptables -t nat -P PREROUTING ACCEPT
iptables -t nat -P POSTROUTING ACCEPT
iptables -t nat -P OUTPUT ACCEPT

NAT et proxy transparent

iptables -t nat -A POSTROUTING -o eth2 -j MASQUERADE
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 3128

Ne pas casser les connexions etablies

iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

Autoriser le loopback

iptables -t filter -A INPUT -i lo -j ACCEPT
iptables -t filter -A OUTPUT -o lo -j ACCEPT

Autorise les clients a surfer

iptables -t filter -A INPUT -i eth0 -p tcp --dport 3128 -j ACCEPT
iptables -t filter -A OUTPUT -o eth2 -p tcp --dport 443 -j ACCEPT # https pour le serveur
iptables -t filter -A OUTPUT -o eth2 -p tcp --dport 80 -j ACCEPT # bizarre je sais
iptables -t filter -A OUTPUT -o eth2 -p udp --dport 53 -j ACCEPT
iptables -t filter -A OUTPUT -o eth2 -p tcp --dport 53 -j ACCEPT
iptables -t filter -A FORWARD -i eth0 -o eth2 -p udp --dport 53 -j ACCEPT
iptables -t filter -A FORWARD -i eth0 -o eth2 -p tcp --dport 53 -j ACCEPT
iptables -t filter -A FORWARD -i eth0 -o eth2 -p tcp --dport 443 -j ACCEPT

Limite le nombre de connexions par IP

iptables -A INPUT -p tcp --dport 443 -m state --state NEW -m recent --name BLACKLIST --set
iptables -A INPUT -p tcp --dport 443 -m state --state NEW -m recent --name BLACKLIST --update --seconds 10 --hitcount 10 --rttl -j DROP

Sarg accessible en local sur 8080

iptables -t filter -A INPUT -i eth0 -s 192.168.0.0/16 -p tcp --dport 8080 -j ACCEPT

Autorise SSH

iptables -t filter -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -t filter -A FORWARD -p tcp --dport 22 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 22 -j ACCEPT

Autorise le ping

iptables -t filter -A FORWARD -i eth2 -o eth0 -p icmp --icmp-type echo-request -j ACCEPT

echo “Iptables [up]”
[/code]

Comme on peut le voir j’essaie de limite le nombre de connexions par IP sur le port 443 pour voir si c’est efficace contre le tunneling…

La règle avec le commentaire “# bizarre je sais” n’a rien de bizarre : il faut bien autoriser le proxy a émettre des connexion HTTP pour servir les demandes de ses clients, ce que j’avais un peu éclipsé (j’ai édité mon précédent message pour l’ajouter).

Quant à la limitation du rythme de connexions sur le port 443, je ne suis pas sûr que ça limite les tunnels ; une fois établi, un tunnel ne génère pas de nouvelles connexions. En revanche cela peut affecter la navigation en HTTPS, si le navigateur fait une connexion différente pour charger chaque élément d’une page, donc beaucoup de connexions en très peu de temps.

Ok car ton message “Les règles que tu as ajoutées pour le port 80 ne sont pas utiles car rien sur le proxy n’écoute sur ce port (la règle REDIRECT change le port avant que la table filter voie les paquets)” m’a carrément fait douté :smiley:

Ah zut pour les tunnels :doh: j’ai voulu m’inspiré de ce que je fais chez moi pour mon ssh (en complément de fail2ban). Du coup il faudrait que je trouve une solution pour sois empêcher le tunneling sur le port 80 et 443 (bien que je n’ai pas trouvé grand chose à ce niveau là) ou soit limiter la bande passante d’une connexion afin de rendre inutilisable l’utilisation de logiciel qui tunneling genre teamviewer (y’a bien tcpkill mais bon ^^).

Mon commentaire était valable pour la règle dans INPUT, et j’ai généralisé trop vite à celle dans OUTPUT qui était bien nécessaire.

Ce n’est pas du tout la même problématique. Un tunnel caché dans le port 443 aurait plutôt la forme d’une connexion qui dure longtemps. Ceci dit, un bête téléchargement d’un gros fichier ou avec une machine à faible débit peut aussi présenter les mêmes caractéristiques extérieures.

PS : suite à ton observation j’ai aussi corrigé les -i en -o dans les règles OUTPUT.

Du coup je vais bloquer des sites dans iptables (vu que le https ne passe pas par le proxy) et tester flowgrep:
monkey.org/~jose/software/flowgrep/

Ou bien snort.