Skip to content
Learni
Voir tous les tutoriels
Sécurité OT/ICS

Comment sécuriser les systèmes OT/ICS en 2026

Read in English

Introduction

Les systèmes OT (Operational Technology) et ICS (Industrial Control Systems) comme SCADA, PLC et RTU pilotent les infrastructures critiques : énergie, eau, manufacturing. En 2026, les attaques comme Triton ou Industroyer soulignent l'urgence d'une cybersécurité dédiée, distincte de l'IT classique. Contrairement aux réseaux IT, les OT priorisent la disponibilité (99,999% uptime) sur la confidentialité, avec des protocoles legacy non chiffrés (Modbus, DNP3, Profibus).

Ce tutoriel avancé vous guide pas à pas pour implémenter une défense en profondeur : identification des assets, segmentation Purdue, détection d'anomalies via IDS/IPS, et monitoring temps réel. Chaque étape inclut du code complet, fonctionnel sur Linux (ex: Ubuntu Server en bastion OT). À la fin, vous disposerez d'une stack sécurisée, conforme NIST 800-82 et IEC 62443, prête pour production. Idéal pour ingénieurs cybersécurité industrielle bookmarkant des références actionnables. (128 mots)

Prérequis

  • Linux (Ubuntu 22.04+ LTS) avec droits root
  • Connaissances avancées : réseaux industriels (Purdue Model), protocoles ICS (Modbus TCP, DNP3), Python 3.10+
  • Outils installés : Nmap 7.9+, Wireshark 4.0+, Scapy 2.5+
  • Accès lab virtuel (VMware/ Proxmox) simulant PLC (ex: OpenPLC)
  • Lecture : NIST SP 800-82r3

Installation des outils essentiels

install-ot-tools.sh
#!/bin/bash
apt update && apt upgrade -y
apt install -y nmap wireshark sniffer tcpdump python3 python3-pip snort iptables-persistent netfilter-persistent
pip3 install scapy pyshark
systemctl enable snort
ufw enable
echo 'Installation terminée. Vérifiez avec: nmap --version'

Ce script bash unifie l'installation des outils clés pour OT/ICS : Nmap pour scanning passif/agressif, Wireshark/Scapy pour analyse protocoles, Snort pour IDS, iptables pour segmentation. Exécutez-le sur un bastion dédié (niveau 3 Purdue). Piège : activez 'sniffer' pour Wireshark non-root ; persistance iptables évite redémarrages.

Modèle Purdue et scanning initial

Adoptez le modèle Purdue pour segmenter : niveau 0-2 (OT pur), 3 (DMZ), 4-5 (IT). Commencez par un scan passif pour éviter DoS sur PLC sensibles. Identifiez assets : PLC (ports 502 Modbus), HMI (80/443), RTU (20000 DNP3).

Scan Nmap passif et actif ICS

nmap-ics-scan.sh
#!/bin/bash
NETWORK="192.168.1.0/24"  # Remplacez par votre réseau OT

# Scan passif (TCP SYN stealth)
nmap -sS -T2 --top-ports 100 -O -sV $NETWORK -oN nmap-passif.txt

# Scan UDP pour DNP3/Modbus (agressif, lab only)
nmap -sU --top-ports 50 -p 102,502,20000 --script=modbus-discover $NETWORK -oN nmap-udp.txt

# Scan spécifique ICS
nmap -p 44818,2222,4480 --script enip-info $NETWORK -oN nmap-ics.txt
echo 'Rapports générés. grep "Modbus" nmap-*.txt'

Script Nmap adapté OT : -T2 timing lent évite surcharge PLC ; scripts NSE (modbus-discover, enip-info) détectent vendors (Schneider, Rockwell). Sorties en fichiers pour audit. Piège : scans UDP lents (30min+), testez lab-only ; intégrez à cron pour monitoring périodique.

Segmentation réseau avec iptables

Segmentez niveaux Purdue : bloquez tout IT->OT sauf flux autorisés (ex: OPC UA chiffré). Utilisez VLANs + firewalls stateful. Règle d'or : Data Diodes pour flux unidirectionnels (OT->IT monitoring uniquement).

Configuration iptables pour segmentation OT

iptables-ot-segment.sh
#!/bin/bash
iptables -F
iptables -t nat -F

# Variables
OT_NET="192.168.10.0/24"  # Niv 0-2
DMZ_NET="192.168.20.0/24" # Niv 3
IT_NET="192.168.1.0/24"   # Niv 4-5

# Politique par défaut: DROP
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

# Autoriser loopback et established
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# OT->DMZ: monitoring SNMP/OPC UA (ports 161,4840)
iptables -A FORWARD -s $OT_NET -d $DMZ_NET -p udp --dport 161 -j ACCEPT
iptables -A FORWARD -s $OT_NET -d $DMZ_NET -p tcp --dport 4840 -j ACCEPT

# Bloquer tout IT->OT
iptables -A FORWARD -s $IT_NET -d $OT_NET -j DROP

netfilter-persistent save
echo 'Segmentation appliquée. iptables -L -v -n'

Ce script implémente zero-trust : DROP par défaut, flux whitelistés OT->DMZ uniquement. Conntrack gère réponses. Sauvegarde persistante. Piège : testez avec tcpdump avant prod ; ajustez ports (Modbus 502 bloqué par défaut pour sécurité).

Règles Snort pour détection ICS

snort-ics.rules
alert tcp $OT_NET any -> $OT_NET 502 (msg:"Modbus TCP Scan"; flow:to_server,established; content:"|00 00|"; depth:2; content:"|00 01 00 00|"; distance:2; sid:1000001; rev:1;)

alert udp $OT_NET any -> $OT_NET 20000 (msg:"DNP3 Anomalie"; content:"|05 64|"; sid:1000002; rev:1; classtype:protocol-command-decode;)

alert tcp any any -> $OT_NET 44818 (msg:"EtherNet/IP Unauthorized"; content:"|65 00|"; sid:1000003; rev:1;)

alert icmp $EXTERNAL_NET any -> $OT_NET any (msg:"ICMP Ping Sweep OT"; itype:8; sid:1000004; rev:1; droprule;)

# Activation dans /etc/snort/snort.conf: include $RULE_PATH/ics.rules

Règles Snort custom pour protocoles ICS : détecte scans Modbus/DNP3, accès EtherNet/IP non auth. Classtype et droprule pour IPS. Ajoutez à local.rules. Piège : signatures shallow (pas deep inspection payload sensible) ; testez avec Scapy replay.

Déploiement IDS/IPS et monitoring

Configurez Snort en mode IDS (SPAN port) ou IPS (inline). Intégrez ELK pour SIEM. Pour OT, priorisez anomalies comportementales : trafic volume spike = DoS potentiel.

Script Python monitoring trafic ICS avec Scapy

ics-monitor.py
from scapy.all import *
import sys
import json
from collections import defaultdict

OT_NET = "192.168.10.0/24"
stats = defaultdict(int)

def packet_handler(pkt):
    if IP in pkt and pkt[IP].src.startswith('192.168.10.'):
        proto = pkt[IP].proto
        sport = pkt[TCP].sport if TCP in pkt else pkt[UDP].sport
        stats[f'{proto}:{sport}'] += 1
        if stats[f'{proto}:{sport}'] > 100:  # Anomalie: >100 pkts/sec
            print(f'ALERTE: Flood {proto}:{sport} from {pkt[IP].src}')

print('Monitoring OT démarré. Ctrl+C pour arrêter.')
sniff(filter=f'net {OT_NET}', prn=packet_handler, store=0)

# Exemple sortie JSON: with open('stats.json', 'w') as f: json.dump(stats, f)

Script Scapy temps réel : sniff trafic OT, compteur par proto/port, alerte flood (>100pkts). Stateful sans DB lourde. Lancez : python3 ics-monitor.py. Piège : root requis ; filtre BPF optimise perf (10Gbps+ capable).

Configuration Suricata YAML pour ICS

suricata-ics.yaml
%YAML 1.1
---

vars:
  address-groups:
    OT_NET: "[192.168.10.0/24]"
    EXTERNAL_NET: "any"

rule-files:
  - /etc/suricata/rules/ics.rules

outputs:
  - eve-log:
      enabled: yes
      filetype: regular
      filename: eve.json
      types:
        - alert:
            payload: yes
            packet: yes
        - anomaly:
            enabled: yes

af-packet:
  - interface: eth1  # SPAN OT
    threads: auto
    cluster-id: 99
    cluster-type: cluster_flow
    defrag: yes

Config Suricata (alternative Snort) : groupes nets, EVE JSON pour ELK, af-packet multithread perf OT. Inclut ics.rules (comme Snort). Piège : defrag=yes pour Modbus fragments ; intégrez Kibana dashboard ICS-specific.

Bonnes pratiques

  • Patch management : air-gappé, test lab (ex: PLC snapshots)
  • Zero Trust : MFA sur HMI, certificats mTLS pour OPC UA
  • Backup offline : 3-2-1 rule, tested quarterly
  • Incident Response : playbook IEC 62443, tabletop exercises
  • Conformité : auditez NIST 800-82, intégrez Purple Team OT

Erreurs courantes à éviter

  • Scanner agressif en prod : cause shutdown PLC (utilisez -T1/-sn)
  • Oublier legacy protocols : Modbus clair = MITM facile (forcez VPN IPsec)
  • Pas de logging centralisé : alertes Snort perdues (ELK mandatory)
  • Ignorer supply chain : firmware PLC vérifié (SBOM + signatures)

Pour aller plus loin

Plongez dans nos formations Learni sur la cybersécurité OT/ICS. Ressources : S4x25 conference, MITRE ICS ATT&CK, outils GrassMarlin (asset mapping), Nozomi Guardian (OT SIEM). Lab gratuit : ICS Village GitHub.