Secure Remote Access to PLC Networks: WireGuard vs Traditional VPN, and How to Deploy It

July 13, 2026 · Category: Guide · Tags: Remote Access, PLC, WireGuard, VPN, OT Security

The OT security baseline says no inbound ports. The automation integrator needs to reach the PLC for commissioning, and the IT team suggests IPsec while someone else swears by OpenVPN. How do you give an engineer access to the PLC network without breaking the baseline?

This guide covers a practical architecture for it: an outbound-only WireGuard mesh with a self-hosted Headscale control plane and scoped ACLs. It walks through the threat model, the deployment steps, ACL design, how this compares with IPsec and OpenVPN for OT, and how it lines up with IEC 62443 and NIS2.

Threat Model: What Are We Protecting Against?

Before choosing a tool, name what you are defending. For remote access into OT, four threats matter most:

1. Unauthorized PLC Exposure

If a PLC's TCP/102 (S7), TCP/502 (Modbus TCP) or EtherNet/IP (TCP/44818) port is reachable from the internet, anyone can try to connect. That means port scanners and targeted attacks alike, and the risk goes beyond unauthorized control to reconnaissance, firmware extraction and protocol-level exploitation. Modbus in particular has no authentication at all; see Modbus TCP security risks.

2. Standing Access and Credential Theft

Traditional VPNs often hand out long-lived credentials. If an engineer's laptop is stolen or infected, or their credentials are phished, the attacker has standing access to your OT network. The longer a credential stays valid, the bigger the window.

3. Lateral Movement Beyond PLC Subnets

Remote access should reach only the PLC subnets the engineer needs. If the same tunnel reaches the historian, HMI stations or file shares, you have built a lateral movement path. Least privilege applies at the network level, not just in the application.

4. Lack of Audit Trail

When someone accesses the PLC network, can you answer who, what, when, from where and for how long? "The VPN logs show something" is not an answer. You need queryable records with user identity and target subnets. For the wider checklist, see the OT security checklist for SCADA.

Architecture: Outbound-Only WireGuard Mesh

Voltrus Remote answers these with a different connectivity model from a classic VPN concentrator:

┌─────────────────┐         ┌──────────────────┐         ┌─────────────────┐
│ Engineer Laptop │◄────────┤ Headscale Control│────────►│ OT Gateway      │
│ (TIA Portal)    │  WireGuard  Plane (Self-    │  DERP   │ (Linux Box)     │
│ 10.0.0.5        │  Mesh     Hosted)           │ Relay  │ 192.168.1.10    │
└────────▲────────┘         └──────────────────┘         └───────┬─────────┘
         │                                                        │
         │ Routes: 192.168.1.0/24 advertised by gateway           │
         │                                                        │
         └────────────────────────────────────────────────────────┘
                          │
                          ▼
                  ┌───────────────┐
                  │ Siemens PLC   │
                  │ 192.168.1.20  │
                  │ TCP/102       │
                  └───────────────┘

Key Points:
• Engineer initiates outbound to Headscale (no inbound ports)
• Gateway initiates outbound to Headscale (no inbound ports)
• DERP relay over TCP/443 for restrictive NAT
• Engineer receives scoped routes to advertised subnets only
• PLC appears at local IP in TIA Portal, no RDP layer
			

Three properties matter:

  1. Outbound-only: Both the engineer's laptop and the OT gateway make outbound connections to your Headscale control plane. Nothing is opened inbound on the OT firewall. The control plane can live in your cloud account or on-premise.
  2. Scoped routes: The gateway advertises only the PLC subnet you list (for example 192.168.1.0/24). Engineers get routes only to subnets their ACL permits, so there is no path to unrelated networks.
  3. Self-hosted custody: Headscale runs on infrastructure you control. You own the user registry, access logs and machine identities, and no third party holds your customers' network topology.

Protocol vs Control Plane: Why Not Just IPsec or OpenVPN?

WireGuard, IPsec and OpenVPN are protocols. Headscale is a control plane. "WireGuard vs IPsec" compares two tunnels; the fair comparison is "WireGuard plus Headscale" against "IPsec plus whatever you build for users, ACLs and audit". For OT remote access the control plane matters more than the cipher, because what you actually need is user authentication, per-user subnet ACLs, an audit trail and separate identities for gateways and engineers.

Dimension WireGuard + Headscale IPsec OpenVPN
Key management Per-device keys registered with a self-hosted control plane; the private key stays on the device Pre-shared keys, or an X.509 PKI you run (CA, issuance, revocation) TLS PKI you run, or static keys
User identity and ACLs Headscale users and a policy file with default-deny Separate firewall or routing layer Separate firewall or routing layer
NAT traversal Direct UDP preferred, DERP relay over TCP/443 as fallback NAT-T on UDP/4500, often blocked upstream UDP/1194 or TCP/443, configurable
Roaming Handled by the protocol; a laptop moving from Wi-Fi to cellular keeps its session Depends on vendor MOBIKE support and keepalives Reconnects after address change
Where it runs In-kernel on Linux, so small overhead Kernel stack; speed depends on crypto offload on your firewall Userspace, so more context switching
Code size Around 4,000 lines in the Linux implementation, small enough to audit Large, with a long negotiation and compatibility history Large, plus an OpenSSL dependency
Audit trail Logs on your own control plane Whatever you configure Whatever you configure

Two of these differences decide most OT projects. First, NAT traversal: IPsec NAT-T on UDP/4500 is frequently blocked by upstream firewalls, and getting it enabled means exceptions that undo the "no inbound" baseline. OpenVPN on TCP/443 gets through but adds TLS-over-TCP latency, which you feel in TIA Portal over a long link. WireGuard prefers UDP and falls back to DERP on TCP/443 when UDP is blocked, with no firewall change. Second, key management: running a PKI with revocation for a handful of integrators is a job in itself, and short of that you end up with shared static keys and standing access.

When a Traditional VPN Still Makes Sense

For engineer-to-PLC access, where the problem is "one laptop, one subnet, for a few days", the mesh is the better fit.

Deployment Checklist: Step-by-Step

Step 1: Deploy the Headscale Control Plane

Provision a small VPS or use an existing server reachable from the OT network over outbound HTTPS. On the hosted Voltrus Remote service, Voltrus runs this step for you. To run it yourself, Voltrus Remote ships the control plane as a Docker Compose stack (Headscale, the control API and a dashboard):

cp .env.example .env
docker compose up -d headscale
docker exec voltrus-headscale headscale users create default
docker exec voltrus-headscale headscale apikeys create   # -> HEADSCALE_API_KEY
docker compose up -d

Headscale manages WireGuard key registration, route advertisement and ACL enforcement, and it runs the DERP relay. For production, put it behind a reverse proxy with TLS.

Step 2: Deploy the OT Gateway Device

On the PLC network, deploy a small Linux machine with two network interfaces:

A Raspberry Pi 4, an industrial mini-PC or a hardened appliance all work. The agent drives the official tailscale client against your Headscale, so it does not reimplement WireGuard crypto, and it needs NET_ADMIN to manage the tunnel interface:

# enrol the gateway and advertise the PLC subnet behind it
./voltrus-remote-agent enrol \
  --hostname siteA-gw \
  --routes 192.168.1.0/24

The gateway makes an outbound connection to the control plane and advertises 192.168.1.0/24. Approve the advertised route in Headscale. No firewall change is needed on the OT side.

Step 3: Define ACLs for Engineers

Headscale enforces a policy.hujson file, default-deny: anything not accepted is blocked. Map each engineer group to the subnets it needs:

{
  "groups": {
    "group:site-a":   ["john@"],
    "group:site-b":   ["sarah@"]
  },
  "acls": [
    // Site A engineers reach only the Site A PLC subnet
    { "action": "accept", "src": ["group:site-a"], "dst": ["192.168.1.0/24:*"] },

    // Site B engineers reach only the Site B PLC subnet
    { "action": "accept", "src": ["group:site-b"], "dst": ["10.0.20.0/24:*"] }
  ]
}

Apply the policy (on current Headscale versions, headscale policy set -f policy.hujson) and check it before the first login.

Step 4: Engineer Installs the Client

The engineer connects with the standard client and accepts the advertised routes. Without --accept-routes the subnet route is never installed, which is the most common reason the gateway shows online but the PLC is unreachable:

# engineer's laptop (Windows, macOS or Linux)
tailscale up --login-server=https://headscale.your-domain.com --accept-routes

After login the laptop has routes to the subnets its ACL permits, and the PLC answers at its local IP:

ping 192.168.1.20

Step 5: Verify Native Tool Reachability

Open TIA Portal, GX Works or Studio 5000, add the PLC at its local IP (192.168.1.20) and connect. It should behave like on-site access, with no RDP layer and no screen-share lag.

Verification Checklist:

  • Engineer can ping the PLC subnet from their laptop
  • TIA Portal or GX Works connects to the PLC at its local IP
  • Engineer cannot reach unrelated subnets (ACL enforcement)
  • Headscale shows the engineer as a connected peer
  • Access logs show user identity, timestamp and routes

When It Does Not Work

ACL Design: Least Privilege in Practice

Per-Project Scoping

One group per site or project, each mapped to exactly the subnets it works on, as in the policy above. When a project ends, remove the group member. Nothing else needs to change.

Per-Protocol Segmentation

If PLC protocols sit on separate subnets, you can narrow access to the service port as well as the subnet:

{
  "acls": [
    // Modbus specialists: Modbus TCP only, on the Modbus subnet
    { "action": "accept", "src": ["group:modbus"], "dst": ["192.168.10.0/24:502"] },

    // EtherNet/IP specialists: CIP explicit messaging only
    { "action": "accept", "src": ["group:enip"],   "dst": ["192.168.20.0/24:44818"] }
  ]
}

Time-Boxed Grants

Standing access is the biggest remaining gap in this model today. Time-boxed grants with expiry and default-deny between sessions are on the Voltrus Remote roadmap, not shipped. Until then, treat commissioning access as something you remove by hand when the work is done, and review group membership on a schedule.

DERP Relay: Working Around Restrictive NAT

Some upstream firewalls block UDP entirely. When no direct path exists, traffic falls back to the DERP relay built into Headscale:

Normal WireGuard: Engineer ←UDP→ Headscale ←UDP→ Gateway

UDP Blocked:     Engineer ←TCP/443→ DERP Relay ←TCP/443→ Gateway
                 (masquerades as HTTPS)
			

DERP rides on outbound HTTPS-compatible TCP, so to the upstream firewall it looks like web traffic. No special rules are needed.

Compliance Alignment: IEC 62443 and NIS2

The architecture maps onto several requirements. This is alignment, not certification; whether your deployment meets a standard depends on your whole system and your assessor.

IEC 62443-3-3 (System Security Requirements)

NIS2 (EU Cybersecurity Directive)

Important: This guide covers network-level remote access. For full compliance you also need endpoint security on engineer laptops, procedural controls such as change management, and monitoring. Remote access is one layer of a defense-in-depth strategy.

Operational Considerations

What Happens When the Gateway Loses Internet?

If the OT gateway loses connectivity, for example after an upstream router restart, the tunnel drops and engineers lose access to the PLC subnet until it reconnects. That is by design: access requires an active, authenticated connection, not a standing credential.

How to Handle Emergency Access?

For after-hours breakdowns, give the engineer a separate group with the subnets needed for that incident, and remove it afterwards. Session recording and approval workflows are roadmap items for Voltrus Remote, not features today.

Multi-Tenant Scenarios

If you are an integrator managing several customers, run a separate Headscale instance per customer. Sharing one control plane across customers blurs audit boundaries. Hosted Voltrus Remote works this way: every customer gets an isolated instance of its own.

Deploy Secure PLC Remote Access Today

Voltrus Remote gives your integrators outbound-only access to PLC networks over WireGuard, on a dedicated instance per customer that Voltrus hosts (or you self-host). Zero inbound ports, default-deny policy, route approval and an audit log. Start with a free 14-day hosted pilot.

Get Started with Voltrus Remote →