Comment transférer des ports via une passerelle Linux avec Iptables

introduction

  • NAT *, ou traduction d’adresse réseau, est un terme général qui désigne le fait de modifier des paquets afin de les rediriger vers une adresse alternative. Habituellement, cela est utilisé pour permettre au trafic de transcender les limites du réseau. Un hôte qui implémente NAT a généralement accès à deux réseaux ou plus et est configuré pour acheminer le trafic entre eux.

  • Le transfert de port * est le processus de transfert des demandes d’un port spécifique à un autre hôte, réseau ou port. Comme ce processus modifie la destination du paquet en vol, il est considéré comme un type d’opération NAT.

Dans ce guide, nous montrerons comment utiliser + iptables + pour transférer des ports aux hôtes situés derrière un pare-feu à l’aide de techniques NAT. Cela est utile si vous avez configuré un réseau privé, mais que vous souhaitez tout de même autoriser un certain trafic à l’intérieur via un ordinateur passerelle désigné. Nous allons utiliser deux hôtes Ubuntu 14.04 pour démontrer cela.

Prérequis et objectifs

Pour suivre ce guide, vous aurez besoin de deux hôtes Ubuntu 14.04 dans le même centre de données avec la mise en réseau privée activée. Sur chacune de ces machines, vous devrez configurer un compte utilisateur non root avec les privilèges + sudo +. Vous pouvez apprendre à créer un utilisateur avec les privilèges sudo + en suivant notre configuration initiale du serveur https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-14-04 Ubuntu 14.04 guider].

Le premier hôte servira de pare-feu et de routeur pour le réseau privé. À des fins de démonstration, le deuxième hôte sera configuré avec un serveur Web uniquement accessible via son interface privée. Nous allons configurer le pare-feu pour transférer les demandes reçues sur son interface publique vers le serveur Web, qu’il atteindra sur son interface privée.

Détails de l’hôte

Avant de commencer, nous devons savoir quelles interfaces et adresses sont utilisées par nos deux serveurs.

Trouver les détails de votre réseau

Pour obtenir les détails de vos propres systèmes, commencez par rechercher vos interfaces réseau. Vous pouvez trouver les interfaces sur vos machines et les adresses qui leur sont associées en tapant:

ip -4 addr show scope global
Sample Output2: : <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
   inet /18 brd 45.55.191.255 scope global eth0
      valid_lft forever preferred_lft forever
3: : <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
   inet /16 brd 10.132.255.255 scope global eth1
      valid_lft forever preferred_lft forever

La sortie en surbrillance ci-dessus montre deux interfaces (+ eth0 + et + eth1 +) et les adresses attribuées à chacune (+ 192.51.100.45 + et + 192.168.1.5 + respectivement). Pour savoir laquelle de ces interfaces est votre interface publique, tapez:

ip route show | grep default
Outputdefault via 111.111.111.111

L’interface montrée (+ eth0 + dans cet exemple) sera l’interface connectée à votre passerelle par défaut. C’est presque certainement votre interface publique.

Recherchez ces valeurs sur chacune de vos machines et utilisez-les pour suivre correctement ce guide.

Exemple de données pour ce guide

Pour vous faciliter la tâche, nous utiliserons les assignations d’adresse fictive et d’interface suivantes tout au long de ce didacticiel. Veuillez substituer vos propres valeurs à celles que vous voyez ci-dessous:

Détails du réseau du serveur Web:

  • Adresse IP publique: ++

  • Adresse IP privée: ++

  • Interface publique: ++

  • Interface privée: ++

Détails du réseau de pare-feu:

  • Adresse IP publique: ++

  • Adresse IP privée: ++

  • Interface publique: ++

  • Interface privée: ++

Configuration du serveur Web

Nous allons commencer par notre hôte de serveur Web. Connectez-vous avec votre utilisateur + sudo + pour commencer.

Installer Nginx

Le premier processus que nous allons terminer consiste à installer + Nginx + sur notre hôte de serveur Web et à le verrouiller afin qu’il n’écoute que son interface privée. Cela garantira que notre serveur Web ne sera disponible que si nous configurons correctement la redirection de port.

Commencez par mettre à jour le cache du paquet local et utilisez + apt + pour télécharger et installer le logiciel:

sudo apt-get update
sudo apt-get install nginx

Restreindre Nginx au réseau privé

Une fois Nginx installé, nous ouvrirons le fichier de configuration du bloc de serveur par défaut pour nous assurer qu’il n’écoute que l’interface privée. Ouvrez le fichier maintenant:

sudo nano /etc/nginx/sites-enabled/default

À l’intérieur, trouvez la directive + listen +. Vous devriez le trouver deux fois de suite vers le haut de la configuration:

/ etc / nginx / sites-enabled / default

server {
   listen 80 default_server;
   listen [::]:80 default_server ipv6only=on;

   . . .
}

À la première directive + listen +, ajoutez l’adresse IP privée de votre serveur web et deux points avant le `80 + + pour indiquer à Nginx de n’écouter que sur l’interface privée. Nous ne faisons que montrer le transfert IPv4 dans ce guide. Nous pouvons donc supprimer la deuxième directive d’écoute, configurée pour IPv6.

Dans notre exemple, nous avons modifié les directives d’écoute de la manière suivante:

/ etc / nginx / sites-enabled / default

server {
   listen :80 default_server;

   . . .
}

Enregistrez et fermez le fichier lorsque vous avez terminé. Testez le fichier pour les erreurs de syntaxe en tapant:

sudo nginx -t

Si aucune erreur ne s’affiche, redémarrez Nginx pour activer la nouvelle configuration:

sudo service nginx restart

Vérifier la restriction du réseau

À ce stade, il est utile de vérifier le niveau d’accès que nous avons à notre serveur Web.

À partir de notre serveur * pare-feu *, si nous essayons d’accéder à notre serveur Web à partir de l’interface privée, cela devrait fonctionner:

curl --connect-timeout 5
Output<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
   body {
       width: 35em;
       margin: 0 auto;
       font-family: Tahoma, Verdana, Arial, sans-serif;
   }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
. . .

Si nous essayons d’utiliser l’interface publique, nous verrons que nous ne pouvons pas nous connecter:

curl --connect-timeout 5
curl: (7) Failed to connect to 203.0.113.2 port 80: Connection refused

C’est exactement ce à quoi nous nous attendons.

Configuration du pare-feu pour transférer le port 80

Nous pouvons maintenant travailler sur la mise en œuvre du transfert de port sur notre machine pare-feu.

Activer le transfert dans le noyau

La première chose à faire est d’activer la redirection du trafic au niveau du noyau. Par défaut, la plupart des systèmes ont le transfert désactivé.

Pour activer la redirection de port pour cette session uniquement, tapez:

echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward

Pour activer la redirection de port de manière permanente, vous devez éditer le fichier + / etc / sysctl.conf +. Ouvrez le fichier avec les privilèges + sudo + en tapant:

sudo nano /etc/sysctl.conf

À l’intérieur, trouvez et décommentez la ligne qui ressemble à ceci:

/etc/sysctl.conf

net.ipv4.ip_forward=1

Enregistrez et fermez le fichier lorsque vous avez terminé. Vous appliquez les paramètres de ce fichier en tapant:

sudo sysctl -p
sudo sysctl --system

Configuration du pare-feu de base

Nous utiliserons le pare-feu dans les this guide as le cadre de base pour les règles de ce tutoriel. Parcourez le guide maintenant sur votre ordinateur pare-feu afin de le configurer. A la fin, vous aurez:

  • Installé + iptables-persistent +

  • Enregistré le jeu de règles par défaut dans + / etc / iptables / rules.v4 +

  • Apprenez à ajouter ou à ajuster des règles en modifiant le fichier de règles ou en utilisant la commande + iptables +

Une fois le pare-feu de base configuré, continuez ci-dessous afin que nous puissions l’ajuster pour le transfert de port.

Ajout des règles de transfert

Nous voulons configurer notre pare-feu de sorte que le trafic entrant dans notre interface publique (+ eth0 +) sur le port 80 soit transféré vers notre interface privée (+ eth1 +).

Notre pare-feu de base a une chaîne + FORWARD + définie sur le trafic + DROP + par défaut. Nous devons ajouter des règles nous permettant de transférer les connexions vers notre serveur Web. Pour des raisons de sécurité, nous verrons cela assez étroitement afin que seules les connexions que nous souhaitons transmettre soient autorisées.

Dans la chaîne + FORWARD +, nous accepterons les nouvelles connexions destinées au port 80 qui proviennent de notre interface publique et sont acheminées vers notre interface privée. Les nouvelles connexions sont identifiées par l’extension + conntrack + et seront spécifiquement représentées par un paquet TCP SYN:

sudo iptables -A FORWARD -i  -o  -p tcp --syn --dport 80 -m conntrack --ctstate NEW -j ACCEPT

Cela laissera le premier paquet, destiné à établir une connexion, à travers le pare-feu. Nous devons également autoriser tout trafic ultérieur dans les deux sens résultant de cette connexion. Pour autoriser le trafic + ESTABLISHED + et + + RLEATED + entre nos interfaces publique et privée, tapez:

iptables -A FORWARD -i eth0 -o eth1 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -i eth1 -o eth0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

Nous pouvons vérifier que notre politique sur la chaîne + FORWARD + est définie sur + DROP en tapant:

sudo iptables -P FORWARD DROP

À ce stade, nous avons autorisé certains trafics entre nos interfaces publique et privée à traverser notre pare-feu. Cependant, nous n’avons pas encore configuré les règles qui indiqueront à + ​​iptables + comment traduire et diriger le trafic.

Ajouter les règles NAT aux paquets directs correctement

Ensuite, nous ajouterons les règles qui indiqueront + iptables + comment acheminer notre trafic. Nous devons effectuer deux opérations distinctes pour que + iptables + modifie correctement les paquets afin que les clients puissent communiquer avec le serveur Web.

La première opération, appelée + DNAT, aura lieu dans la chaîne` + PREROUTING` de la table + nat +. + DNAT + est une opération qui modifie l’adresse de destination d’un paquet afin de lui permettre d’être correctement routé lorsqu’il passe d’un réseau à un autre. Les clients du réseau public se connecteront à notre serveur pare-feu et n’auront aucune connaissance de la topologie de notre réseau privé. Nous devons modifier l’adresse de destination de chaque paquet pour que, lorsqu’il est envoyé sur notre réseau privé, celui-ci sache atteindre correctement notre serveur Web.

Dans la mesure où nous configurons uniquement la redirection de port et ne réalisons pas de NAT sur chaque paquet qui atteint notre pare-feu, nous souhaitons faire correspondre le port 80 à notre règle. Nous allons faire correspondre les paquets destinés au port 80 à l’adresse IP privée de notre serveur Web (+ 192.0.2.2 + dans notre exemple):

sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination

Cela s’occupe de la moitié de la photo. Le paquet devrait être correctement acheminé vers notre serveur Web. Cependant, pour le moment, le paquet aura toujours l’adresse d’origine du client comme adresse source. Le serveur tentera d’envoyer la réponse directement à cette adresse, ce qui rendra impossible l’établissement d’une connexion TCP légitime.

Note

Pour configurer un routage approprié, nous devons également modifier l’adresse source du paquet au moment où il laisse le pare-feu en route vers le serveur Web. Nous devons modifier l’adresse source en fonction de l’adresse IP privée de notre serveur pare-feu (+ 192.0.2.15 + dans notre exemple). La réponse sera ensuite renvoyée au pare-feu, qui pourra ensuite la renvoyer au client comme prévu.

Pour activer cette fonctionnalité, nous allons ajouter une règle à la chaîne + POSTROUTING + de la table + nat +, qui est évaluée juste avant l’envoi des paquets sur le réseau. Nous allons faire correspondre les paquets destinés à notre serveur Web par adresse IP et port:

sudo iptables -t nat -A POSTROUTING -o eth1 -p tcp --dport 80 -d  -j SNAT --to-source

Une fois cette règle en place, notre serveur Web devrait être accessible en pointant notre navigateur Web sur l’adresse publique de notre ordinateur coupe-feu:

curl
Output<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
   body {
       width: 35em;
       margin: 0 auto;
       font-family: Tahoma, Verdana, Arial, sans-serif;
   }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
. . .

Notre configuration de la redirection de port est terminée.

Réglage du jeu de règles permanent

Maintenant que nous avons configuré la redirection de port, nous pouvons la sauvegarder dans notre jeu de règles permanent.

Si vous ne vous souciez pas de perdre les commentaires de votre jeu de règles actuel, utilisez simplement le service + iptables-persistent pour sauvegarder vos règles:

sudo service iptables-persistent save

Si vous souhaitez conserver les commentaires dans votre fichier, ouvrez-le et éditez-le manuellement:

sudo nano /etc/iptables/rules.v4

Vous devrez ajuster la configuration dans la table filter + pour les règles de chaîne + FORWARD + qui ont été ajoutées. Vous devrez également ajuster la section qui configure la table + nat + pour pouvoir ajouter vos règles + PREROUTING + et + + POSTROUTING +. Pour notre exemple, cela ressemblerait à quelque chose comme ceci:

/etc/iptables/rules.v4

*filter
# Allow all outgoing, but drop incoming and forwarding packets by default
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]

# Custom per-protocol chains
:UDP - [0:0]
:TCP - [0:0]
:ICMP - [0:0]

# Acceptable UDP traffic

# Acceptable TCP traffic
-A TCP -p tcp --dport 22 -j ACCEPT

# Acceptable ICMP traffic

# Boilerplate acceptance policy
-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
-A INPUT -i lo -j ACCEPT

# Drop invalid packets
-A INPUT -m conntrack --ctstate INVALID -j DROP

# Pass traffic to protocol-specific chains
## Only allow new connections (established and related should already be handled)
## For TCP, additionally only allow new SYN packets since that is the only valid
## method for establishing a new TCP connection
-A INPUT -p udp -m conntrack --ctstate NEW -j UDP
-A INPUT -p tcp --syn -m conntrack --ctstate NEW -j TCP
-A INPUT -p icmp -m conntrack --ctstate NEW -j ICMP

# Reject anything that's fallen through to this point
## Try to be protocol-specific w/ rejection message
-A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable
-A INPUT -p tcp -j REJECT --reject-with tcp-reset
-A INPUT -j REJECT --reject-with icmp-proto-unreachable



# Web server network details:

# * Public IP Address:
# * Private IP Address:
# * Public Interface:
# * Private Interface:
#
# Firewall network details:
#
# * Public IP Address:
# * Private IP Address:
# * Public Interface:
# * Private Interface:
-A FORWARD -i eth0 -o eth1 -p tcp --syn --dport 80 -m conntrack --ctstate NEW -j ACCEPT
-A FORWARD -i eth0 -o eth1 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
-A FORWARD -i eth1 -o eth0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT


# Commit the changes

COMMIT

*raw
:PREROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT

*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]





# Web server network details:

# * Public IP Address:
# * Private IP Address:
# * Public Interface:
# * Private Interface:
#
# Firewall network details:
#
# * Public IP Address:
# * Private IP Address:
# * Public Interface:
# * Private Interface:
-A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination
-A POSTROUTING -d  -o eth1 -p tcp --dport 80 -j SNAT --to-source

COMMIT

*security
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT

*mangle
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
COMMIT

Enregistrez et fermez le fichier une fois que vous avez ajouté ce qui précède et modifié les valeurs pour refléter votre propre environnement réseau.

Testez la syntaxe de votre fichier de règles en tapant:

sudo iptables-restore -t < /etc/iptables/rules.v4

Si aucune erreur n’est détectée, chargez le jeu de règles:

sudo service iptables-persistent reload

Vérifiez que votre serveur Web est toujours accessible via l’adresse IP publique de votre pare-feu:

curl

Cela devrait fonctionner comme avant.

Conclusion

A présent, vous devriez être à l’aise avec le transfert de ports sur un serveur Linux avec + iptables +. Le processus implique l’autorisation du transfert au niveau du noyau, la configuration de l’accès pour permettre le transfert du trafic du port spécifique entre deux interfaces sur le système de pare-feu et la configuration des règles NAT afin que les paquets puissent être correctement acheminés. Cela peut sembler être un processus compliqué, mais il démontre également la flexibilité du cadre de filtrage de paquets + netfilter + et du pare-feu + iptables +. Cela peut être utilisé pour dissimuler la topologie de vos réseaux privés tout en permettant au trafic de services de circuler librement à travers votre ordinateur pare-feu de passerelle.