Thématiques principales

dimanche 13 octobre 2019

Reseau: Iptables: routeur logiciel

Nous revenons une nouvelle fois avec iptable mais plus pour faire du filtrage réseau mais pour du routage de trame.
Pour cela nous allons considérer l’exemple suivant: Imaginons un server sur lequel tourne un service. Ce service on le représentera par un service netcat (nc) [1]. Ce server se trouve dans le reseau privé 192.168.1.0/24. Nous, nous sommes dans un reseau externe en 192.168.0.0/24, nous ne pouvons donc pas y accéder directement. Comment allons nous nous y prendre pour que malgré tout nous puissions y parvenir?


Conf réseau de la passerelle

Tout d’abord on va installer une machine entre les deux réseaux, celle-ci servira de passerelle et de routeur étant dans les deux réseaux à la fois. On va donc lui assigner une adresse dans le 1er reseau, par exemple 192.168.1.10 et une seconde dans le second réseau 192.168.0.10.
Deja pour faire cela, on va assigner à notre interface reseau eth0 l’adresse ip externe (en 0.10) et on va creer une interface reseau virtuelle eth0:0 pour l’autre [7]:


root@routeur$ ip addr add 192.168.1.10/24 broadcast 192.168.1.255 dev eth0 label eth0:0

nous allons alors vérifier notre config

root@routeur$ ip a

2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether b8:27:eb:b7:7f:be brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.10/24 brd 192.168.0.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet 192.168.1.10/24 brd 192.168.1.255 scope global eth0:0

Conf réseau du server

Ok on à la passerelle, on reviendra sur la partie iptable plus tard, on va terminer d’abord la configuration réseau. On va donc affecter une adresse ip dans le reseau 192.168.1.0 à notre server:

root@server$ ip addr add 192.168.1.30/24 broadcast 192.168.1.255 dev eth0 label eth0:0
root@server$ ip a
[...]
inet 192.168.1.30/24 brd 192.168.1.255 scope global eth0:0
       valid_lft forever preferred_lft forever

Dans le serveur nous allons donc lancer un service avec netcat qui enverra une réponse à celui qui l'interroge en précisant un port d'écoute et une ip source:


root@server$ echo "reponse" | nc -s 192.168.1.30 -l -p 9999

Conf réseau du client

Du coté client, cela va etre assez similaire à la configuration du server à ceci pret qu’il se trouve dans le reseau 192.168.0.0/24

root@client$ ip addr add 192.168.0.60/24 broadcast 192.168.0.255 dev eth0 label eth0:0
root@client$ ip a
[...]
inet 192.168.0.60/24 brd 192.168.0.255 scope global eth0:0
       valid_lft forever preferred_lft forever

À ce stade nous pouvons verifier que la communication ne marche pas en envoyant sur la passerelle un message (on precise l’ip source par commodité et pour eviter tout implicite):

 root@client$ echo message | nc -s 192.168.0.60 192.168.0.10 8888

Pas de reponse… ok normal

Configuration Iptables de la passerelle

Maintenant que la conf réseau est en place, il faut que l’on construise les règles iptables adaptées au routage des messages.

Tout d’abord on va envoyer toute les trames à destination de la passerelle et du port 8888 sur le server sur son port d'écoute [2]:

root@rooteur$ sudo iptables -t nat -R OUTPUT 1 --dst 192.168.0.10 -p tcp --dport 8888 -j DNAT --to-destination 192.168.1.30:9999

si l’on essaye de voir su cela suffit à partir du server client:

root@client$ echo message | nc -s 192.168.0.60 192.168.0.10 8888

Pas de réponse…. qu’est ce qui se passe?
Pour mieux comprendre on va artificiellement ajouter encore une nouvelle interface réseau à la passerelle mais coté client et on refait le test depuis la passerelle en utilisant cette interface:

root@routeur$ ip addr add 192.168.0.15/24 broadcast 192.168.0.255 dev eth0 label eth0:1

On essaye:

root@rooteur$ echo message | nc -s 192.168.0.15 192.168.0.10 8888
reponse

La cela fonctionne… pourquoi?

Parce que l’on à mis notre regles DNAT [3] dans la chaîne OUTPUT, ainsi un message sortant même sur avec une ip dans un réseaux sera reecrit et retransmis dans l’autre réseau en suivant la règle.

Pour y voir plus clair on va ajouter une regle pour logger [4] les messages entrant venant du client:

root@rooteur$  sudo iptables -t nat -I PREROUTING 1 -s 192.168.0.60 -j LOG --log-level debug --log-prefix "PREROUTING:"
root@rooteur$  sudo iptables -t nat -I OUTPUT 1 -s 192.168.0.60 -j LOG --log-level debug --log-prefix "OUTPUT:"
root@rooteur$  sudo iptables -t nat -I POSTROUTING 1 -s 192.168.0.60 -j LOG --log-level debug --log-prefix "POSTROUTING:"

On emet un message depuis le client et on voir alors que seul la regle de log PREROUTING à reagit (voir /var/log/syslog):

Oct  7 09:38:24 picenter kernel: [1565014.478722] PREROUTING:IN=eth0 OUT= MAC=b8:27:eb:b7:7f:be:50:46:5d:dd:25:1c:08:00:45:00:00:3c:c9:f5:40:00:40:06:ef:2f SRC=192.168.0.60 DST=192.168.0.10 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=51701 DF PROTO=TCP SPT=53707 DPT=8888 WINDOW=64240 RES=0x00 SYN URGP=0

Par contre si on tente la même chose depuis le routeur (comme dans le cas où cela fonctionne) on modifie au passage la règle ouput pour modifier la source:

root@rooteur$  sudo iptables -t nat -R OUTPUT 1 -s 192.168.0.15 -j LOG --log-level debug --log-prefix "OUTPUT:"

on envoie un message:

Oct  7 09:42:27 picenter kernel: [1565257.332088] OUTPUT:IN= OUT=lo SRC=192.168.0.15 DST=192.168.0.10 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=37897 DF PROTO=TCP SPT=54595 DPT=8888 WINDOW=43690 RES=0x00 SYN URGP=0

Il faut donc mettre la regle dans la chaine prerouting

root@rooteur$ iptables -t nat -A PREROUTING --dst 192.168.0.10 -p tcp --dport 8888 -j DNAT --to-destination 192.168.1.30:9999

Et permettre au message retour de revenir en changeant l’adresse sources afin que le server sache qu’il doit s’adresse à la passerelle pour que celle ci route à nouveau ce dernier [6].

root@rooteur$ iptables -t nat -A POSTROUTING -p tcp -j SNAT --to 192.168.1.10

On tente de nouveau depuis le client et… ca marche ! et les messages ont reussi à faire l’allé retour...

root@client$ echo message | nc -s 192.168.0.60 192.168.0.10 8888
reponse
root@server$ echo "reponse" | nc -s 192.168.1.30 -l -p 9999
message

Ca ne marche pas? Retentez avec :


root@rooteur$ sudo sysctl -w net.ipv4.ip_forward=1

Références:


[1] https://www.commandlinux.com/man-page/man1/nc.1.html
[2] https://www.netfilter.org/documentation/HOWTO/fr/NAT-HOWTO-6.html
[3] https://www.inetdoc.net/guides/iptables-tutorial/dnattarget.html
[4] https://www.malekal.com/tutoriel-iptables/
[5] http://www.admin6.fr/2012/03/regles-de-routage-simple-avec-iptables/
[6] http://www.linux-france.org/prj/edu/archinet/systeme/ch62s03.html
[7] https://memo-linux.com/ip-la-commande-linux-pour-gerer-son-interface-reseau/

vendredi 4 octobre 2019

Lecture: De beaux réves

Cela fait un moment que je n'avais évoqué une lecture intéressante, pas que je me soies arrêter de lire ou que je n'ai pas eut de lecture très intéressante, mais celle ci il faut l'avouer, elle sort du lot.

Alors bien sur, tout ça a  voir avec l'IA mais de façon plus subtil voire philosophique et ça tombe bien, il s'agit de cela.

De beaux rêves de Daniel C.Dennett c'est la question (vous verrez en fait il y en a deux) de la conscience, de ce qu'elle peut être, si celle ci est une illusion ou un effet de bord du fonctionnement de notre cerveau. Dans ce livre vous parlerez de divergence d'opinions sur les les Qualia, vous vous demanderai ce qu'est un Zombie Philosophique et si ça peut exister, et vous parlerez de Marie, Marie Marie mais aussi de Marie Robot!

Enfin a mon sens ce livre est un pivot sur les questions éthique de ce qu'est la conscience, de quoi elle résulte. Pour les amoureux des animaux comme des robots, c'est vraiment une œuvre a lire.

samedi 21 septembre 2019

Reseau : Iptables, firewall


Inutile d’expliquer ce qu’est un firewall? Si ?

Un firewall [firewall] est un système réseau logiciel ou matériel dont le rôle est de gérer l'accès à une machine où à un sous-réseau. Alors bien sur des firewalls, il en existe de toute sorte agissant pour divers rôles.

Le premier de ceux-ci est évidemment l'accès à un sous réseau. Il s’agit d’ici d'un système qui couplé à une passerelle permettant à deux réseaux de communiquer tout en garantissant un maximum de sécurité. Nous ne nous intéresserons pas à ce type de firewall puisque ces derniers sont généralement matériel et sont très complexe dans leur utilisation ainsi que dans leur intégration au sein d’une architecture réseau (généralement en couche).

Le second type de firewall, et qui va ici nous intéresser est le firewall logiciel dont le rôle est de sécuriser les interfaces réseaux d’un système. Par système on parle ici bien sûr tout autant d’une machine physique comme d’un PC mais aussi d’un serveur ou d’une machine virtuelle ou même encore d’un conteneur.

Dans notre exemple, nous allons utiliser Iptables, nous l'avions vu dans un article précédent [iptables]. Je vous invite a vous reporter pour faire le point.

On commence par se créer une chaîne à nous et on ajoute une règle permettant de l’appeler quand un message est reçu (cette règle va donc router tous les messages vers notre chaîne) et on ajoute une dernière règle dans justement notre chaîne personnalisé pour DROP les messages.

iptables -N TEST-CHAIN
iptables -A INPUT -s 0/0 -j TEST-CHAIN
  • -j permet de spécifier la cible du paquet, celle ci pouvant être soit une règle de gestion (DROP, ACCEPT, etc…) ou une autre chaîne, ce que nous faisons ici.
  • -s spécifie toutes adresses de tout type de réseau (IP/masque)
Une fois configurer on inspecte la table filter qui nous donne alors:

$ iptables -L


Chain INPUT (policy ACCEPT)
target prot opt source destination
TEST-CHAIN all -- anywhere anywhere

Chain TEST-CHAIN (1 references)
target prot opt source destination
DROP all -- anywhere anywhere 

On test alors avec un simple ping:


$ ping localhost

PING localhost (127.0.0.1) 56(84) bytes of data.


pas de réponse alors que si on retire la règle, le ping est possible:

$ iptables -D TEST-CHAIN 1

$ ping localhost
PING localhost (127.0.0.1): 56 data bytes
64 bytes from 127.0.0.1: seq=0 ttl=64 time=0.130 ms
64 bytes from 127.0.0.1: seq=1 ttl=64 time=0.121 ms

On notera qu’ici la chaîne d’entrée est politique ACCEPT et que c’est parceque notre chaine perso possède une chaine contenant une règle DROP sur tout que nous ne parvenons plus à ping notre machine.

En terme de sécurité, ce n’est pas terrible, normalement on fait l’inverse, on supprime tous les droits et on rétablit des permissions au cas par cas.

On va donc sécuriser la chaîne INPUT en changeant sa politique et on supprimera notre règle DROP pour la remplacer ensuite par une règle autorisant le ping:


$ iptables -P INPUT DROP


On verifie que le ping est desactivé:

$ ping localhost
PING localhost (127.0.0.1) 56(84) bytes of data


On ajoute une regle dans TEST-CHAIN pour le reactiver et le tester:

$ iptables -A TEST-CHAIN -s 0/0 -p icmp -j ACCEPT
$ ping localhost
PING localhost (127.0.0.1) 56(84) bytes of data.
64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.063 ms
  • -p permet de specifier le protocole, permettant de choisir par exemple, udp, tcp où ici pour le ping, icmp.

C’est un peu tout où rien, si par exemple notre machine possede deux interface reseaux, une filaire et une wifi, on pourrait souhaiter diferencier la politique de gestion et n’autoriser que les ping realisés sur l’interface filaire.

Pour cela on va utiliser le parametre -i:

$ iptables -D TEST-CHAIN 1
$ iptables -A TEST-CHAIN -i eth0 -p icmp -j ACCEPT


On test:


$ ping -I eth0 localhost
PING localhost (127.0.0.1) 56(84) bytes of data.
64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.063 ms

$ ping -I wlan0 localhost
PING localhost (127.0.0.1) 56(84) bytes of data.


Ainsi, on peut de la même maniere selection specifiquement les messages associé à telle où telle IP (et de même par le reseau) en multipliant bien sur les regles associés

À noter que l’on peut egalement filtrer le traffic sortant de la machine afin de s’assurer qu’aucun message ne puisse s’en echappé sans avoir ete gerer (à laide des parametres -d, ip destination, ou -o, interface de sortie). On pourra aussi specifier les ports avec -sport et -dport.

De même il est possible d’effectuer des controles sur la nature des messages. Par exemple avec le parametre --syn, on pourra s’interesser specifiquement au message de synchro TCP permettant l’etablissement d’une nouvelle connexion.

On pourra egalement imposer des limites en terme de nombre de connexion par seconde afin de se premunir d’attaque de type DoS en utilisant le parametre -m:

-m limit --limit 5/s

Ce même paramètre pourra aussi servir pour la détection de l'état de la connexion par exemple:

-m state --state ESTABLISHED

Pour poursuivre et aller plus dans les finesse du matching, cette très bonne documentation vous permettra d'affiner vos regles [howto-firewall].

References

[firewall] https://fr.wikipedia.org/wiki/Pare-feu_(informatique)
[iptables] https://un-est-tout-et-tout-est-un.blogspot.com/2019/09/reseau-iptables-bases.html
[howto-firewall] http://www.linuxhomenetworking.com/wiki/index.php/Quick_HOWTO_:_Ch14_:_Linux_Firewalls_Using_iptables

mercredi 18 septembre 2019

Reseau: IpTables, bases


On s'éloigne un peu des précédents articles aujourd’hui en introduisant une nouvelle thématique: le réseau.

Le réseau? mais pourquoi? Simplement parce que dans la conception logicielle, la prise en compte de la composante environnementale dans laquelle le logiciel évolue est essentiel.

Cela va conditionner l’architecture, les technologies, les langages choisis et les contraintes s’appliquant à son exploitation.

Et le réseau est ce sur quoi va reposer l’essentiel de l’infrastructure système.

Par contre, je ne commencerai pas par les fondamentaux. On y viendra mais la on va tout de suite passer à un outil spécifique de la gestion réseau: Iptables.

IpTables [iptables-basics] [iptables-doc] est un outils de gestion des flux réseaux de la machine linux sur laquelle il est installé.

Par gestion, cela signifie qu’il permet d’autoriser ou d’interdire certains flux, entrant ou sortant sur certains type d’interfaces ou protocoles ou selon la provenance ou la destination. Il permet aussi de router ces même flux de façon à élaborer des politiques de gestions de l’information.

Comme vous vous en doutez donc, l’une des premières utilisation de cet outil est donc d’en faire un firewall en filtrant les flux mais il est aussi possible d’un faire un routeur logiciel permettant de déployer des flux au travers d’une architecture réseau spécifique.

Mais avant d’entrer dans le vif d’une utilisation sans explications sur Iptables.

Fondamentaux

Iptable se base sur 3 concepts structuraux principaux, les tables, les chaînes, et les règles.

Les tables implémentent les chaînes contenant à leur tour les règles (faisant référence à leur tour à potentiellement d’autres chaînes ou une règle simple de gestion).

L'exécution des règles va alors s'opérer selon d’une part la source du paquet et d’autre part selon un ordre prédéfini entre les tables et ce qu’elles implémenté comme chaînes [iptables-chains].

On compte 5 types de chaînes:

  • PREROUTING cette chaîne est exécutée lors de la réception d’un paquet elle sera ensuite poussé dans la chaînes INPUT ou/et FORWARD
  • INPUT Cette chaîne permet le traitement d’un paquet avant que celui ci ne soit servi à un processus local
  • FORWARD cette chaîne est exécutée lorsqu’un paquet n’est que routé par la machine sans qu’il soit utilisé par celle ci
  • OUTPUT cette chaîne est exécutée lorsqu’un processus local émet un paquet
  • POSTROUTING cette chaîne permet le traitement des paquets sortant de la machine.



Les tables vont alors implémenter ces différentes chaînes selon un certain ordre et choix (toutes les chaînes n'étant pas forcément implémenté) amenant alors donner un rôle fonctionnel différents à chacune des tables. ainsi par défaut, les tables constituant iptables sont :

  • filter c’est la table par défaut, elle implémente INPUT, OUTPUT et FORWARD et a pour vocation de gérer les entrées sorties de la machine et donc de servir de firewall en filtrant les paquets entrant, sortant ou ceux re-émis.
  • nat : permet de faire de l'altération de paquets dans le but de faire de la translation d’adresse. elle implémente POSTROUTING, PREROUTING et OUTPUT
  • mangle : table de traitement des paquets afin d’en changer des propriétés comme par exemple la Qos. On ne traitera pas de ce genre d’utilisation, elle implémente toutes les chaînes par défaut.
  • raw table de configuration spécifique des paquets en les modifiants au plus près de leur émission, implémente donc logiquement PREROUTING et OUTPUT
  • security permet de gérer du filtrage basé sur des règles de controle d’acces (MAC) implémenté par module de sécurité linux. On n’en parlera pas.

Généralement lorsqu’il s’agit de réaliser une configuration iptables, on s’appuiera sur la table par défaut, c’est à dire filter.

Pour y accéder, il suffit d’utiliser l'argument -t en précisant la table souhaité. Ne pas le préciser revient à utiliser la table par défaut c’est à dire filter.

iptables -L -n -v --line-numbers

équivalent à

iptables -t filter -L -n -v --line-numbers

Les paramètres -L, -n, -v, servent respectivement à:
  • demander la liste des règles de la table (pour simplifier leur suppression avec -D)
  • écrire les adresses sous la forme numérique et non verbalement
  • verbosité de la réponse

Ainsi on obtient la liste des règles associées à chacune des chaînes de la table.

Avant d’aller plus loin voici quelques autres paramètres pratiques qui vont nous permettre de manipuler [iptables-cmd]:

  • les chaînes:
    • -N newChain: création d’une nouvelle chaîne nommée “newChain”
    • -X chain: supprime la chaîne “chain” (celle ci ne devant pas être une parmis les standards)
    • -L chain: liste les règles de la chaîne “chain”
    • -F chain: vide la chaine “chain” de toutes ses règles
    • -P chain ACCEPT|DROP : change la politique finale de la chaine “chain” pour accepter ou rejeter les paquets si aucune règle ne les a pris en charge.
    • -E : renommer une chaîne
  • les règles
    • -A chain rule-spec: ajout d’une règle à la chaîne “chain” à la suite des règles existantes
    • -I chain num rule-spec: insertion d’une règle à la chaîne “chain” à l’index num
    • -D chain rule-spec|num : suppression dans la chaîne “chain” la règle suivante (identifié par sa spécification ou son numéro)
    • -R : replace une règle par une nouvelle.

Ensuite, pour définir les règles, il faudra user de différents paramètres permettant de discriminer les informations comme le protocole, les interfaces entrantes ou sortantes, les ip sources ou de destinations, où encore les ports (entrant ou sortant également) etc... Tout en gardant en tête que l’on ne pourra pas écrire n’importe quelle règles dans n’importe quelle table.

Voila ceci clos une première partie sur iptables, nous n’avons pas fait d’exemple mais nous y viendrons.

Références

[iptables-cmd] https://www.ionos.fr/digitalguide/serveur/outils/tutoriel-iptables-des-regles-pour-les-paquets-de-donnees/
[iptables-basics] https://fr.wikibooks.org/wiki/Le_syst%C3%A8me_d'exploitation_GNU-Linux/Protection_avec_iptables
[iptables-doc] https://help.ubuntu.com/community/IptablesHowTo
[iptables-chains] https://www.booleanworld.com/depth-guide-iptables-linux-firewall/