🔌 Diagnostic réseau OT/IT · au shell Linux

Chapitre 05
Ports & services

Objectifs du chapitre

1. Commencer chez soi : les sockets locaux

Avant de scruter le réseau, regarde ce que ton poste — ton laptop WSL ou l'edge de l'armoire — écoute et connecte. C'est gratuit, immédiat, et sans aucun risque : rien ne part sur le fil. L'outil moderne est ss (le successeur de netstat), fourni par iproute2.

# -t TCP   -u UDP   -l en écoute (listening)   -p PID/programme   -n numérique (pas de résolution DNS)
sudo ss -tulpn
# ss -tulpn
Netid State   Local Address:Port   Peer Address:Port  Process
tcp   LISTEN  0.0.0.0:22          0.0.0.0:*          users:(("sshd",pid=641,fd=3))
tcp   LISTEN  127.0.0.1:631        0.0.0.0:*          users:(("cupsd",pid=712,fd=7))
tcp   LISTEN  0.0.0.0:4840        0.0.0.0:*          users:(("opcua-server",pid=980,fd=9))
udp   LISTEN  0.0.0.0:161         0.0.0.0:*          users:(("snmpd",pid=655,fd=6))

Lecture : chaque ligne LISTEN est un service qui attend des clients. L'adresse locale dit sur quelle interface il écoute : 0.0.0.0 = toutes les interfaces (donc joignable depuis le réseau machine), 127.0.0.1 = boucle locale uniquement (invisible de l'extérieur). Ici notre edge expose un serveur OPC-UA (4840), un agent SNMP (161) et SSH (22) au réseau ; le service d'impression (631) reste confiné en local.

Utilise ss -tulpn pour savoir ce que ton edge expose au réseau OT avant de te demander ce que font les autres. Un edge de diagnostic qui écoute sur 0.0.0.0 des services inutiles, c'est une surface d'attaque ajoutée à ta cellule. La colonne Process (grâce à -p, qui exige sudo) te dit quel binaire fermer.

Pour voir non pas les écoutes mais les connexions établies — les échanges TCP en cours — on filtre par état :

$ ss -tan state established
Recv-Q Send-Q   Local Address:Port      Peer Address:Port
0      0        192.168.0.71:52344      192.168.0.1:102
0      0        192.168.0.71:22         192.168.0.240:51002

Cette sortie est déjà un mini-diagnostic : notre poste .71 a une session TCP ouverte vers 192.168.0.1:102 — c'est-à-dire une communication S7 vers le CPU (port 102, on y vient) — et il reçoit une session SSH depuis le Scalance .240. On lit le rôle des machines rien qu'à leurs échanges. (-a = tous, -n = numérique ; le filtre state established ne garde que les sessions actives.)

2. Les ports OT à connaître

La couche 4 (transport) identifie un service par un numéro de port. En bureautique on connaît 80, 443, 22. En OT s'ajoute une famille de ports très parlants : les reconnaître, c'est lire le rôle d'un équipement sans rien deviner. Voici ceux qui reviennent sur une cellule Siemens.

PortProtoServiceÀ quoi ça sert / qui l'ouvre
102TCPS7comm / ISO-on-TCP (RFC 1006)Communication S7 avec un CPU (TIA, HMI, IHM, driver S7). Le port le plus caractéristique d'un automate Siemens.
4840TCPOPC-UA (opc.tcp)Serveur OPC-UA : supervision, échanges IT/OT normalisés. Un CPU S7-1500 peut l'exposer, comme un serveur dédié.
80 / 443TCPHTTP / HTTPSServeur web embarqué du CPU (diagnostic web) ou d'un switch managé (configuration).
161 / 162UDPSNMP / SNMP-trapSupervision d'équipement : switches Scalance, CPU. 161 = requêtes, 162 = traps émis par l'équipement.
34962-34964UDPProfinet acyclique (DCP / RPC)Contexte RPC et services acycliques Profinet (identification, paramétrage). Signature d'un nœud Profinet.
502TCPModbus/TCPPasserelles, capteurs, variateurs tiers. Pas systématique sur une cellule Siemens pure, mais fréquent en environnement mixte.
22 / 23TCPSSH / TelnetAdministration en ligne de commande d'un switch managé ou d'un edge. Telnet (23) = ancien, en clair, à bannir si possible.

Le port 102 est le cœur de la communication S7 : c'est par lui que TIA Portal charge un programme, qu'une IHM lit des variables, qu'un driver S7 dialogue avec le CPU. Le voir ouvert, c'est voir un automate Siemens qui parle S7comm. Le port 4840, lui, révèle que le CPU expose un serveur OPC-UA — une fonction qu'on active explicitement dans la configuration du S7-1500, pour ouvrir la donnée au monde IT.

3. Découverte d'hôtes : qui est vivant ?

Avant de scanner des ports, on établit la liste des machines présentes sur le segment. Le balayage le plus léger est le ping sweep de nmap avec l'option -sn (no port scan) : il ne touche à aucun port applicatif, il se contente de déterminer quels hôtes répondent.

# -sn : découverte d'hôtes seule, aucun scan de port
nmap -sn 192.168.0.0/24
$ nmap -sn 192.168.0.0/24
Starting Nmap 7.94 ( https://nmap.org )
Nmap scan report for 192.168.0.1
Host is up (0.00042s latency).
MAC Address: 28:63:36:1A:2B:3C (Siemens)
Nmap scan report for 192.168.0.20
Host is up (0.00051s latency).
MAC Address: 28:63:36:4D:5E:6F (Siemens)
Nmap scan report for 192.168.0.21
Host is up (0.00049s latency).
MAC Address: 28:63:36:7A:8B:9C (Siemens)
Nmap scan report for 192.168.0.240
Host is up (0.00038s latency).
MAC Address: 20:87:56:11:22:33 (Siemens)
Nmap scan report for 192.168.0.71
Host is up.
Nmap done: 256 IP addresses (5 hosts up) scanned in 2.14 seconds

En quelques secondes, on tient l'inventaire vivant : le CPU .1, deux ET 200SP (.20 et .21), un Scalance .240 et notre poste .71. Bonus précieux : sur le segment local, nmap lit la MAC (via ARP) et en déduit le constructeur — ici « Siemens » sur presque tout, ce qui confirme qu'on est bien dans une cellule Siemens. C'est déjà de l'information de rôle avant même de toucher un port.

Le ping sweep -sn est le geste de reconnaissance le moins agressif : sur le réseau local il s'appuie surtout sur des requêtes ARP, que tout équipement gère nativement. C'est pourquoi c'est toujours par là qu'on commence, y compris en production.

4. Scan de ports ciblé

Une fois les hôtes connus, on demande à chacun quels services il expose. Plutôt que de balayer les 65 535 ports (long et bruyant), on cible d'abord la liste OT du §2 avec -p :

# Scan des ports OT sur tout le sous-réseau (sudo → scan SYN, plus propre)
sudo nmap -p 102,4840,80,443,161,502 192.168.0.0/24

Sortie sur le CPU 192.168.0.1 :

$ sudo nmap -p 102,4840,80,443,161,502 192.168.0.1
Nmap scan report for cpu1500 (192.168.0.1)
Host is up (0.00040s latency).

PORT     STATE  SERVICE
80/tcp   open   http
102/tcp  open   iso-tsap
443/tcp  open   https
4840/tcp open   opcua
161/tcp  closed snmp
502/tcp  closed mbap
MAC Address: 28:63:36:1A:2B:3C (Siemens)

Le profil parle de lui-même : 102 + 80 + 443 + 4840 = un CPU S7-1500 qui parle S7comm (102), expose son serveur web de diagnostic (80/443) et un serveur OPC-UA (4840). Le port SNMP est fermé sur ce CPU, Modbus aussi : cohérent pour un automate Siemens pur. (iso-tsap est le nom que nmap donne au port 102 ; opcua au 4840.)

Sortie sur un Scalance 192.168.0.240 :

$ sudo nmap -p 22,80,161,443 192.168.0.240
Nmap scan report for 192.168.0.240
Host is up (0.00036s latency).

PORT    STATE  SERVICE
22/tcp  open   ssh
80/tcp  open   http
161/tcp open   snmp
443/tcp open   https
MAC Address: 20:87:56:11:22:33 (Siemens)

Ici pas de 102 ni de 4840, mais 22 + 80 + 443 + 161 : administration en ligne (SSH), configuration web, et supervision SNMP. C'est la carte d'identité d'un switch managé, pas d'un automate.

Pour lever un doute sur un hôte précis, on peut faire un scan complet des 65 535 ports — utile quand un service tourne sur un port non standard :

# -p- : scan de tous les ports TCP (long ; à réserver à un hôte, pas à un /24)
nmap -p- 192.168.0.1

Enfin, -sV tente d'identifier la version du service en dialoguant avec lui (bannière, sondes) :

# Détection de version — informatif mais plus intrusif, à manier avec prudence en prod
sudo nmap -sV -p 102,4840,443 192.168.0.1

Un scan actif — surtout -sV et les scripts NSE — envoie du trafic inattendu vers l'automate. Un vieux device Profinet, un coupleur bas de gamme ou une pile TCP fragile peuvent décrocher (perte de connexion Profinet, redémarrage, arrêt de la communication). Sur un banc de test : aucun problème, scanne largement. En production : commence par -sn, cible des ports connus, évite -sV et les scripts, ralentis (§6), et ne scanne jamais une ligne en marche sans accord.

5. Déduire le rôle d'un profil de ports

La force de la méthode : le profil de ports ouverts d'un hôte trahit sa fonction, sans avoir à interroger la documentation. On associe un profil à un rôle :

Ports ouverts (typiques)Rôle déduit
102 + 80/443 + 4840CPU S7-1500 — S7comm, web de diagnostic, serveur OPC-UA
102 + 34962-34964 (UDP), pas de 4840IO-device (ET 200SP) — parle Profinet, éventuellement un peu de S7/DCP, pas de serveur OPC-UA
161 + 443 + 22 (+ 80)Switch managé (Scalance) — SNMP, config web, admin SSH
4840 seul (+ 22)Serveur OPC-UA dédié / edge — expose la donnée, pas de S7comm ni de SNMP d'équipement

En croisant la découverte d'hôtes (§3) et les scans ciblés (§4), on construit un inventaire hôte→rôle de la cellule :

# Inventaire de la cellule 192.168.0.0/24 (construit au scan)
192.168.0.1     cpu1500     CPU S7-1500     (102, 80, 443, 4840)
192.168.0.20    et200sp-a   IO-device       (102, Profinet)
192.168.0.21    et200sp-b   IO-device       (102, Profinet)
192.168.0.240   scalance-1  Switch managé   (22, 80, 443, 161)
192.168.0.241   scalance-2  Switch managé   (22, 80, 443, 161)
192.168.0.71    poste-diag  Poste diagnostic (rien exposé, ou 22)

Retiens le raccourci : le port 102 dit « automate », le port 161 dit « équipement managé », le port 4840 dit « donnée exposée en OPC-UA ». Un hôte qui cumule 102 et 4840 est presque toujours un CPU moderne. Le profil de ports te donne le rôle avant même d'ouvrir un navigateur ou TIA Portal.

6. Timing et prudence : les templates -T

nmap règle son agressivité — cadence d'envoi, parallélisme, délais — via six templates de timing, de -T0 (paranoïaque, très lent) à -T5 (insane, très rapide). Par défaut, nmap est en -T3.

TemplateCadenceQuand l'utiliser
-T0 / -T1Très lent, un paquet à la foisRéseau très fragile, ou pour rester discret. Peut durer des heures.
-T2Lent, ménagéProd sensible : ralentir sans être extrême.
-T3Normal (défaut)Point de départ raisonnable.
-T4Rapide, agressifBanc de test sur réseau fiable : gain de temps net.
-T5Très rapide (risque de rater des ports)Rarement conseillé ; peut saturer des devices fragiles.
# Sur banc de test : on peut pousser la cadence
sudo nmap -T4 -p 102,4840,80,443,161 192.168.0.0/24

# En prod, sur un device suspecté fragile : on ralentit franchement
sudo nmap -T2 -p 102 192.168.0.20

La règle de conduite du chapitre 1 s'applique ici pleinement : en production, on commence par -sn, on cible des ports connus, on évite -sV et les scripts NSE intrusifs sur des devices fragiles, et on ralentit avec -T2 voire moins. Un scan -T5 lancé à l'aveugle sur un vieux nœud Profinet peut suffire à le faire décrocher — et à provoquer un défaut sur la ligne. Sur banc : liberté totale.

Le scan de ports n'est qu'une vue couche 4 : il dit quels services écoutent, pas s'ils sont sains ni ce qu'ils échangent réellement. Pour voir le trafic Profinet temps réel sur le fil, c'est la capture (chapitres suivants) qu'il faut — pas nmap. Les deux se complètent : nmap pour l'inventaire des services, la capture pour la réalité des échanges.

Récapitulatif

Exercices

Exercice 1 — Balayer la cellule

Depuis ton poste, fais un balayage non-intrusif du sous-réseau 192.168.0.0/24 et dresse la liste des hôtes vivants. Quelle option utilises-tu pour ne pas scanner de ports, et quelle information bonus obtiens-tu sur le réseau local ?

Voir la solution
$ nmap -sn 192.168.0.0/24
Nmap scan report for 192.168.0.1
Host is up ... MAC Address: 28:63:36:1A:2B:3C (Siemens)
Nmap scan report for 192.168.0.20   ... (Siemens)
Nmap scan report for 192.168.0.21   ... (Siemens)
Nmap scan report for 192.168.0.240  ... (Siemens)
Nmap scan report for 192.168.0.71
Nmap done: 256 IP addresses (5 hosts up) scanned in 2.14 seconds

L'option -sn (no port scan) fait un simple ping sweep : aucun port applicatif n'est touché, c'est le geste le plus léger. Sur le segment local, nmap résout en prime la MAC par ARP et affiche le constructeur (« Siemens »), ce qui identifie déjà la nature des équipements. On tient cinq hôtes vivants : CPU, deux ET 200SP, un Scalance et le poste.

Exercice 2 — Scanner le CPU et interpréter

Scanne le CPU 192.168.0.1 sur les ports OT (102, 4840, 80, 443, 161, 502). Quels services trouves-tu ouverts, et qu'en déduis-tu sur le rôle et les fonctions activées de cet équipement ?

Voir la solution
$ sudo nmap -p 102,4840,80,443,161,502 192.168.0.1
PORT     STATE  SERVICE
80/tcp   open   http
102/tcp  open   iso-tsap
443/tcp  open   https
4840/tcp open   opcua
161/tcp  closed snmp
502/tcp  closed mbap

Quatre ports ouverts : 102 (S7comm — le CPU parle bien S7), 80/443 (son serveur web de diagnostic est actif), 4840 (le serveur OPC-UA du CPU est activé dans la configuration TIA). SNMP et Modbus fermés. Conclusion : c'est un CPU S7-1500 qui expose à la fois S7comm, le web et OPC-UA — donc un automate ouvert au monde IT via OPC-UA. Le profil 102 + 80 + 4840 est la signature typique d'un CPU moderne.

Exercice 3 — Attribuer le rôle à partir du profil

On te donne trois hôtes découverts sur la cellule, avec leurs ports ouverts. Attribue à chacun un rôle parmi : CPU S7-1500, switch managé, IO-device, serveur OPC-UA dédié — et justifie.

Voir la solution

Hôte A = CPU S7-1500. Le trio 102 + 80/443 + 4840 ne laisse pas de doute : S7comm (102) pour la communication automate, web de diagnostic (80/443), et serveur OPC-UA (4840). C'est un contrôleur moderne qui expose sa donnée.

Hôte B = switch managé (Scalance). 161 (SNMP) trahit un équipement d'infrastructure supervisable ; 22 (SSH) l'administration en ligne ; 80/443 l'interface de configuration. Aucun 102 : ce n'est pas un automate. Profil classique d'un switch managé.

Hôte C = IO-device (ET 200SP). Il parle S7/Profinet (102 et les ports acycliques 34962-34964) mais n'expose ni serveur OPC-UA (pas de 4840) ni SNMP (pas de 161). C'est un périphérique décentralisé piloté par le CPU, pas un contrôleur ni un équipement managé.

Méthode générale : on cherche d'abord 102 (automate ? oui/non), puis on distingue CPU (a du 4840) d'un IO-device (n'en a pas) ; l'absence de 102 avec du 161 pointe vers un équipement managé.