Skip to content
Snippets Groups Projects
Commit c3de136b authored by ricardo.dossanto1's avatar ricardo.dossanto1
Browse files

fuck le double nat

parents
No related branches found
No related tags found
No related merge requests found
File added
\documentclass[12pt]{article}
\usepackage{import}
\import{./}{preambule.tex}
\graphicspath{ {./images/} }
\title{\huge{\TITLE}}
\author{\NAME}
\date{\DATE}
\begin{document}
\maketitle
\begin{center}\thanks{Ce rapport est écrit sans IA générative}\end{center}
\clearpage
\tableofcontents
\clearpage
\section{Introduction}
Les namespaces sont un moyen de virtualiser au niveau logiciel plusieurs instances séparées de pile TCP/IP sur un PC typique comparé à des machines virtuelles.\\\\
Ce document parle des namespaces réseau Linux, et ce document parlera d'instancier, à l'aide des namespaces réseau, des routeurs virtuels.\\\\
Chaque script sera dans ce \href{URL}{git}
\section{Topologie}
La topologie est telle que dans la figure 1:
\FloatBarrier
\begin{figure*}[h!]
\centering
\includegraphics[scale=0.6]{topo}
\caption{Topologie du labo}
\end{figure*}
\FloatBarrier
La topologie de la figure 1 ne contient qu'un seul hôte dans un LAN (local area network) dédié, avec un routeur (Un pc linux débian) et un accès à internet sur l'une des interfaces du routeur (ici eth0).\\\\
L'accès SSH est fait via l'interface mgmt0 de chaque hôte, cependant au delà de cet accès, aucun trafic ne sera routé via cette interface.
\section{Préparation d'un hôte}
\label{section_prepHost}
Tout d'abords, il faut préparer l'hôte (ici H1) a utilisé R1 sans namespace.\\\\
Pour ce faire, nous allons commencé par activé l'\textit{IP\_forward} dans R1 via la commande:
\begin{lstlisting}[language=bash]
echo 1 > /proc/sys/net/ipv4/ip_forward
\end{lstlisting}
Sans cette commande, il est impossible de router des paquets à travers l'hôte, cette commande autorise le kernel a routé les paquets qu'il reçoit.\\\\
Ensuite, il faut configurer les IPs des interfaces de R1 et H1. Pour ce faire, la configuration est la suivante:
\begin{itemize}
\item L'interface \textit{eth0}, celle du côté \textit{internet provider}, sera configuré via DHCP. L'un des moyens disponible est le suivant:
\begin{lstlisting}[language=bash]
dhclient -v eth0
\end{lstlisting}
La commande ci-dessus invoque un processus qui fait les requêtes DHCP pour l'interface passée en paramètre (DHCP offer, DHCP request, ect.).\\\\
Une route par défaut sera installé via l'interface \textit{eth0} qui recevra l'adresse via DHCP.
\item Pour ce labo, il suffira d'ajouter statiquement l'adresse IP des interfaces (\textit{eth1} pour R1, \textit{eth0} pour H1). L'adresse réseau du LAN dans lequel se trouve H1 est choisi arbitrairement à 10.0.0.0/24 (donc une adresse réseau privée).
\item La route par défaut de H1 est l'adresse de l'interface \textit{eth1} de R1:
\begin{lstlisting}[language=bash]
ip route add default via 10.0.0.1
\end{lstlisting}
Cette commande ajoute de manière éphémère (la route disparaît au redémarrage) une route par défaut passant par l'adresse arbitraire de R1 qui est 10.0.0.1/24.
\end{itemize}
Finalement, nous allons ajouté une règle \textit{nftables} qui dit que chaque paquet routé sur \textit{eth0} dans R1 vera son adresse source modifiée à celle de \textit{eth0}. En d'autres termes, un Network Address Translation (NAT).\\\\
Pour ce faire, voici la règle à appliquer:
\begin{lstlisting}[language=bash]
#!/usr/sbin/nft -f
flush ruleset
table ip nat {
chain masq {
type nat hook postrouting priority 100;
oifname "eth0" counter masquerade
}
}
\end{lstlisting}
Ci-dessus, chaque ligne s'explique comme suit:
\begin{itemize}
\item \textit{\#!/usr/sbin/nft -f}: Ce script, quand lancer, utilise la commande nft -f (au même titre qu'un script bash utiliserait \#!/bin/bash, c'est équivalent)
\item \textit{flush ruleset}: Supprimer chaque règles établie auparavant
\item \textit{table ip nat}: Ajout d'une table de la famille IP, dont le nom est "nat"
\item \textit{chain masq}: Ajout d'une chaîne nommée "masq"
\item \textit{type nat hook postroting priority 100;}: Attaché un hook nat après le routage de chaque paquet avec une priorité de 100.\\\\
En d'autres termes, appliqué les principes du nat à chaque paquet après routage de ce dernier. La priorité permet de donné un ordonnancement si cette chaîne a plusieurs règles.
\item \textit{oifname "eth0" counter masquerade}: Compter le nombre de fois que l'interface \textit{eth0} exécute un "masquerade", donc un remplaçement de l'adresse source par celle de l'interface (donc \textit{eth0}).
\end{itemize}\newpage
Avec tout cela, il est possible de pinger internet depuis H1:
\FloatBarrier
\begin{figure*}[h!]
\centering
\includegraphics[scale=0.6]{traceroute_1}
\caption{Screenshot de traceroute depuis H1}
\end{figure*}
\FloatBarrier
\section{Policy Routing et les horreurs du double nat}
Désormais, l'hôte R1 aura un namespace qui servira de routeur, nommé R2, connecté par des paires d'interface virtual ethernet (veth).\\\\
Voici la topologie au niveau de R1:
\FloatBarrier
\begin{figure*}[h!]
\centering
\includegraphics[scale=0.5]{topo_policy}
\caption{Screenshot de la représentation de R1 avec namespace, sourcé de l'énoncé du labo}
\end{figure*}
\FloatBarrier
Cette fois-ci, voici la configuration de R1:
\begin{itemize}
\item La route par défaut est veth1 dans R1.
\item La route par défaut de R2 est veth0.
\item L'adresse de \textit{eth1} est inchangée (10.0.0.1/24).
\item L'adresse de \textit{veth1} est 192.168.1.1/24.
\item L'adresse de \textit{veth0} est 192.168.0.1/24.
\item L'adresse de \textit{eth0} est reçue via dhcp, et la route par défaut via \textit{eth0} doit être supprimée si elle existe.
\item Une table de routage customisé qui envoie tous les paquets provenant de \textit{veth0} vers \textit{eth0} en tant que route par défaut.\\\\
Ceci est fait grâce aux commandes suivantes:
\begin{lstlisting}[language=bash]
echo 100 custom >> /etc/iproute2/rt_tables
ip rule add iif veth0 table custom
ip route add default via 172.21.1.1 table custom
\end{lstlisting}
Ces trois lignes de codes font les actions suivantes dans l'ordre:
\begin{itemize}
\item Ajout de la table custom avec une priorité de 100
\item Ajout d'une règle qui dit que tout paquet venant de \textit{veth0} doit se référer à la table custom de routage
\item Ajout d'une route par défaut via 172.21.1.1 (La passerelle internet) dans la table custom
\end{itemize}
\end{itemize}
Pour ce qui est de R2, voici la configuration:
\begin{itemize}
\item \textit{veth0\_r2} a l'adresse 192.168.0.2/24
\item \textit{veth1\_r2} a l'adresse 192.168.1.2/24
\item Une route par défaut allant vers \textit{veth0} de R1
\item Une route vers 10.0.0.0/24 passant par \textit{veth1} de R1 est faite afin que les paquets puissent revenir vers H1
\end{itemize}
En plus de toutes ces configurations, nous devons pêché et faire non pas un NAT, mais \textbf{deux NATs}.\\
Pour ce faire, nous pouvons reprendre le script nftables du premier point pour R1. Pour R2, il suffit de remplacer \textit{eth0} par le \textit{veth} de sortie du namespace (ex: veth0\_r2).\\\\
Ceci est dû au fait que l'action de naté ne se déroule qu'au sein de la pile dans lequel le nat doit se passer.\\
Ce qui signifie que la sortie du namespace et la sortie de R1 forment leur propre pile, auquel les paquets de H1 n'appartiennent pas à cette pile TCP/IP. De ce fait, il faut nater l'adresse en sortant de R2 afin que les paquets soient naté à la sortie de R1.\\\\
Le fait de router par R2 affecte le \textit{Time to Live}(TTL), qui sera plus bas qu'un ping ne passant que par R1.
\FloatBarrier
\begin{figure*}[h!]
\centering
\includegraphics[scale=0.7]{ping_policy}
\caption{Screenshot des pings après configuration d'un double nat, après beaucoup de douleur à comprendre qu'il fallait faire un double nat}
\end{figure*}
\FloatBarrier
\section{Routeur virtuel bridgé}
Afin d'éviter des règles de routages afin de renvoyer les paquets dans R2 depuis R1, nous pouvons utiliser des bridges linux.\\\\
Les bridges linux sont des switchs virtuels, chaque interface passe en mode promiscuous.\\
Le mode promiscuous change les comportements de l'interface, qui accepte chaque trame qui lui est envoyé, à l'inverse du comportement par défaut qui n'acceptait que les trames qui lui étaient directement dédiées.\\\\
La topologie est la suivante:
\FloatBarrier
\begin{figure*}[h!]
\centering
\includegraphics[scale=0.6]{topo_3}
\caption{Screenshot de la topologie de R1 sourcé de l'énoncé}
\end{figure*}
\FloatBarrier
Dans cette topologie, R1 ne sert que de switch virtuel au routeur R2.\\\\
La configuration de R1 devient la suivante:
\begin{itemize}
\item Création des bridges et des paires veth.
\item Création du namespace, et déplacement de la paire des veth dans le namespace R2.
\item Changer les interfaces en promiscuous de tel manière:
\begin{lstlisting}[language=bash]
ip link set eth1 master br1
ip lin set veth1 master br1
ip link set eth0 master br0
ip link set veth0 master br0
\end{lstlisting}
Finalement, pour configurer R2, nous reprenons la configuration de la \hyperref[section_prepHost]{première section du document}, mais à la place de R1, nous le faisons dans R2.
\end{itemize}
\section{Instancier plusieurs routeurs virtuels}
Pour cette partie, il faut choisir entre policy routing et bridgé pour la configuration de deux routeurs virtuels.\\
Le choix est vite fait: ce sera les bridges. Plus jamais de NAT.\\\\
La topologie est la suivante:
\FloatBarrier
\begin{figure*}[h!]
\centering
\includegraphics[scale=0.6]{topo_4}
\caption{Screenshot de la topologie de R1 sourcé de l'énoncée}
\end{figure*}
\FloatBarrier
La configuration se fait en trois étapes:
\begin{itemize}
\item Configuration de R1: Ajout des bridges, ajout des paires veth.\\\\
Les paires appartenant à R1 sont master au bridges \textit{br0} et \textit{br1}. Pour finir, les interfaces sont up
\item Configuration de R2: Déplacement des veths appartenant à R2, ajout des addresses en 10.0.0.0/24 côté H1 et 192.168.2.0/24 côté R3.\\\\
Une route par défaut est rajoutée vers R3 (l'interface doit être déjà configurée et up).\\\\
Up des interfaces
\item Configuration de R3: Déplacement des veths, ajout d'une route vers 10.0.0.0/24 vers 192.168.2.2/24 (veth côté R2) et appel à dhclient pour recevoir une adresse en DHCP côté internet.\\\\
Ajout des règles de NAT à la veth de sortie de R3.\\\\
Up des interfaces.
\end{itemize}
Cette configuration fait que chaque routeur est sa propre pile TCP/IP unique et ne demande pas de faire l'affront capital du double NAT.\newpage
Cela nous permet de traverser les deux routeurs virtuels et de ping \textit{1.1.1.1}:
\FloatBarrier
\begin{figure*}[h!]
\centering
\hspace*{-2cm}
\includegraphics[scale=0.3]{big_dump}
\caption{Screenshot de tcpdump avec veth2 haut-gauche, veth0\_r3 haut-droite et veth2\_r3 bas-droite, montrant le chemin du paquet et sa réponse chacun avec l'id 651}
\end{figure*}
\FloatBarrier
\end{document}
#!/bin/bash
echo "Forward to 1"
ssh r1 "echo 1 > /proc/sys/net/ipv4/ip_forward"
echo "creation"
ssh r1 "ip link add br0 type bridge"
ssh r1 "ip link add br1 type bridge"
ssh r1 "ip link add veth1 type veth peer name veth1_r2"
ssh r1 "ip link add veth0 type veth peer name veth0_r3"
ssh r1 "ip link add veth2 type veth peer name veth2_r3"
ssh r1 "ip netns add r2"
ssh r1 "ip netns add r3"
echo "r1 config"
ssh r1 "ip link set eth1 master br1"
ssh r1 "ip link set eth1 up"
ssh r1 "ip link set veth1 master br1"
ssh r1 "ip link set veth1 up"
ssh r1 "ip link set eth0 master br0"
ssh r1 "ip link set eth0 up"
ssh r1 "ip link set veth0 master br0"
ssh r1 "ip link set veth0 up"
ssh r1 "ip link set up br0"
ssh r1 "ip link set up br1"
echo "r2 config"
ssh r1 "ip link set veth1_r2 netns r2"
ssh r1 "ip link set veth2 netns r2"
ssh r1 "ip netns exec r2 ip addr add 10.0.0.1/24 dev veth1_r2"
ssh r1 "ip netns exec r2 ip link set up veth1_r2"
ssh r1 "ip netns exec r2 ip addr add 192.168.2.2/24 dev veth2"
ssh r1 "ip netns exec r2 ip link set up veth2"
echo "r3 config"
ssh r1 "ip link set veth2_r3 netns r3"
ssh r1 "ip link set veth0_r3 netns r3"
ssh r1 "ip netns exec r3 ip addr add 192.168.2.3/24 dev veth2_r3"
ssh r1 "ip netns exec r3 ip link set up veth2_r3"
ssh r1 "ip netns exec r2 ip route add default via 192.168.2.3"
ssh r1 "ip netns exec r3 ip route add 10.0.0.0/24 via 192.168.2.2"
ssh r1 "ip netns exec r3 dhclient -v veth0_r3"
ssh r1 "ip netns exec r3 nft -f nftrule_4.txt"
echo "h1 config"
ssh h1 "ip addr add 10.0.0.3/24 dev eth0"
ssh h1 "ip link set up eth0"
ssh h1 "ip route add default via 10.0.0.1"
#!/bin/bash
echo "Forward to 1"
ssh r1 "echo 1 > /proc/sys/net/ipv4/ip_forward"
echo "create veth pair"
ssh r1 "ip link add veth0 type veth peer name veth0_ns2 && ip link add veth1 type veth peer name veth1_ns2"
echo "Add namespace"
ssh r1 "ip netns add ns2"
echo "Move veth to ns2"
ssh r1 "ip link set veth1_ns2 netns ns2 && ip link set veth0_ns2 netns ns2"
echo "IP config r1"
ssh r1 "ip addr add 10.0.0.1/24 dev eth1"
ssh r1 "ip link set up eth1"
ssh r1 "ip addr add 192.168.1.1/24 dev veth1"
ssh r1 "ip link set up veth1"
ssh r1 "ip netns exec ns2 ip addr add 192.168.1.2/24 dev veth1_ns2"
ssh r1 "ip netns exec ns2 ip link set up veth1_ns2"
ssh r1 "ip r del default"
ssh r1 "ip r add default via 192.168.1.2"
ssh r1 "dhclient -v eth0"
ssh r1 "ip netns exec ns2 ip addr add 192.168.0.2/24 dev veth0_ns2"
ssh r1 "ip netns exec ns2 ip link set up veth0_ns2"
ssh r1 "ip addr add 192.168.0.1/24 dev veth0"
ssh r1 "ip link set up veth0"
ssh r1 "ip netns exec ns2 ip r add default via 192.168.0.1"
ssh r1 "ip netns exec ns2 ip r add 10.0.0.0/24 via 192.168.1.1"
ssh r1 "echo 100 custom >> /etc/iproute2/rt_tables"
ssh r1 "ip rule add iif veth0 table custom"
ssh r1 "ip r add default via 172.21.1.1 table custom"
ssh r1 "nft -f nftrule_2.txt"
ssh r1 "ip netns exec ns2 nft -f nftrule_natr2_policy.txt"
echo "Configure h1"
ssh h1 "ip addr add 10.0.0.3/24 dev eth0"
ssh h1 "ip link set up eth0"
ssh h1 "ip r add default via 10.0.0.1"
\usepackage[utf8]{inputenc}
\usepackage{hyperref}
\usepackage{graphicx}
\usepackage[a4paper, margin={2.5cm}]{geometry}
\usepackage{xcolor}
\usepackage{fancyhdr}
\usepackage{amsmath,amsfonts}
\usepackage{listings}
\usepackage{hyperref}
\usepackage{float}
\usepackage{attachfile}
\usepackage{placeins}
\usepackage[
backend=biber,
style=numeric,
sorting=none
]{biblatex}
\addbibresource{reference.bib}
\def\DATE{\today}
\def\NAME{Ricardo Dos Santos}
\def\TITLE{Rapport Namespace}
\pagestyle{fancy}
\fancyhead{}
\fancyhead[LO,LE]{\textbf{\TITLE}}
\fancyhead[RO,RE]{\textbf{\NAME}}
\fancyfoot{}
\fancyfoot[LE,RO]{\thepage}
\fancyfoot[LO]{\DATE}
\renewcommand\thesection{\Roman{section}}
\renewcommand{\thesubsection}{\Roman{subsection}}
\renewcommand{\thesubsubsection}{\Roman{subsubsection}}
% Define custom colors based on the example
\definecolor{backgroundcolor}{rgb}{0.16,0.16,0.16} % Dark background, close to black
\definecolor{promptcolor}{rgb}{0.06,0.53,0.53} % Teal color for the prompt
\definecolor{commandcolor}{rgb}{0.78,0.78,0.78} % Light grey for the command text
% Define custom colors based on the image provided
\definecolor{backgroundcolor}{rgb}{0.12,0.12,0.12} % Dark background
\definecolor{commandcolor}{rgb}{0.12,0.56,0.16} % Greenish-blue color for commands
\definecolor{usercolor}{rgb}{0.5,0.5,0.5} % Grey for user text
\definecolor{inputtextcolor}{rgb}{0.85,0.85,0.85} % Light grey for input text
\definecolor{mGreen}{rgb}{0,0.6,0}
\definecolor{mGray}{rgb}{0.5,0.5,0.5}
\definecolor{mPurple}{rgb}{0.58,0,0.82}
\definecolor{backgroundColour}{rgb}{0.95,0.95,0.92}
\lstdefinestyle{CStyle}{
backgroundcolor=\color{backgroundColour},
commentstyle=\color{mGreen},
keywordstyle=\color{magenta},
numberstyle=\tiny\color{mGray},
stringstyle=\color{mPurple},
basicstyle=\footnotesize,
breakatwhitespace=false,
breaklines=true,
captionpos=b,
keepspaces=true,
numbers=left,
numbersep=5pt,
showspaces=false,
showstringspaces=false,
showtabs=false,
tabsize=2,
language=C
}
% lstlisting configuration for bash
\lstset{
language=bash,
basicstyle=\ttfamily\small\color{inputtextcolor},
breaklines=true,
breakatwhitespace=true,
showstringspaces=false,
commentstyle=\color{usercolor}\ttfamily,
keywordstyle=\color{commandcolor}\bfseries,
stringstyle=\color{inputtextcolor}\ttfamily,
frame=tlbr, % Top, left, bottom, right frames
framesep=5pt, % Frame separation
framerule=0pt, % Frame rule size
rulecolor=\color{backgroundcolor}, % Frame color
tabsize=2,
captionpos=b,
numbers=none, % No line numbers
backgroundcolor=\color{backgroundcolor},
escapeinside={(*@}{@*)}, % Escape to LaTeX between (*@ and @*)
}
\lstdefinestyle{AntoieStyle}{
backgroundcolor=\color{backcolour},
commentstyle=\color{codegreen},
keywordstyle=\color{magenta},
numberstyle=\tiny\color{codegray},
stringstyle=\color{codepurple},
basicstyle=\ttfamily\footnotesize,
breakatwhitespace=false,
breaklines=true,
captionpos=b,
keepspaces=true,
numbers=left,
numbersep=5pt,
showspaces=false,
showstringspaces=false,
showtabs=false,
tabsize=2
}
#!/bin/bash
echo "Forward to 1"
ssh r1 "echo 1 > /proc/sys/net/ipv4/ip_forward"
echo "Add bridges"
ssh r1 "ip link add br0 type bridge"
ssh r1 "ip link add br1 type bridge"
echo "Add veth pairs"
ssh r1 "ip link add veth0 type veth peer name veth0_ns2 && ip link add veth1 type veth peer name veth1_ns2"
echo "Add namespace"
ssh r1 "ip netns add ns2"
echo "Move veth to ns2"
ssh r1 "ip link set veth1_ns2 netns ns2 && ip link set veth0_ns2 netns ns2"
echo "Master bridges"
ssh r1 "ip link set eth0 master br0 && ip link set veth0 master br0"
ssh r1 "ip link set eth1 master br1 && ip link set veth1 master br1"
echo "First links up"
ssh r1 "ip link set eth0 up"
ssh r1 "ip link set eth1 up"
ssh r1 "ip link set br0 up"
ssh r1 "ip link set br1 up"
ssh r1 "ip link set veth0 up"
ssh r1 "ip link set veth1 up"
echo "ns2 config"
ssh r1 "ip netns exec ns2 ip addr add 10.0.0.1/24 dev veth1_ns2"
ssh r1 "ip netns exec ns2 dhclient veth0_ns2"
ssh r1 "ip netns exec ns2 nft -f nftrule.txt"
ssh r1 "ip netns exec ns2 ip link set up veth1_ns2"
echo "h1 config"
ssh h1 "ip addr add 10.0.0.3/24 dev eth0"
ssh h1 "ip link set eth0 up"
ssh h1 "ip r add default via 10.0.0.1"
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment