How to test that the VPN works
Technical checklist to validate the WireGuard tunnel with Rela AI end-to-end: from the first handshake to reading the PLC, with copy-paste commands and category-based troubleshooting.
How to test that the VPN works
This guide is written for the customer's IT technician — someone who just pasted the WireGuard config into their router and wants to confirm everything is operational before handing off to the plant team. Each step includes the exact command and the expected output.
What this guide is for
So that paste-and-forget doesn't turn into "at 2 AM Monday nobody reaches the PLC". You'll verify 6 layers in order: handshake → routing → IP connectivity → TCP port → Modbus request → dashboard. If any layer fails, the error message points exactly to the culprit layer.
How the layered diagnosis works
When a WireGuard connection misbehaves, the error is almost always in ONE specific layer — and each layer has its own diagnostic tool. Going bottom-up (handshake first, Modbus last) saves hours of "I checked everything and it still doesn't work".
Benefits
| Systematic diagnosis | When it fails, you know exactly which layer to fix. |
| Fewer support calls | 95% of problems are solved with this checklist. |
| Evidence for your IT | Concrete logs and outputs to attach to a ticket if you escalate. |
Prerequisites
Before starting:
- WireGuard config applied on your router/firewall (see Setup and Configuration).
- Terminal access (SSH / web console) to the router or the machine running WireGuard.
- Known private IP of the PLC (inside your local network).
- Subnet assigned by Rela AI (visible in the dashboard when you created the peer — format
10.200.X.0/24).
Layer 1 — WireGuard handshake
Verify your router and the Rela AI concentrator handshook.
pfSense / OPNsense
Menu: Status → WireGuard. You should see:
- Interface
rela_vpnin green. - On the peer,
Latest Handshakeunder 2 minutes. Transferwith growing bytes (rx and tx).
Mikrotik RouterOS
/interface wireguard peers printExpected:
# INTERFACE=rela-vpn PUBLIC-KEY=clrU9+Aj... LAST-HANDSHAKE=15s RX=2.8KiB TX=3.1KiBIf LAST-HANDSHAKE says never or a very large number (>1 hour), the handshake never occurred. Jump to troubleshooting: Layer 1.
Ubiquiti EdgeOS
show interfaces wireguard wg0Look for peer: <pubkey> followed by latest handshake: X seconds ago.
Linux (wg-quick)
sudo wg show wg0Expected:
interface: wg0
public key: <your-pubkey>
listening port: 51820
peer: clrU9+AjXQ4GdSEV4NhIWs4uspF76tlemYpE8mZR6z0=
endpoint: 34.22.248.0:51820
allowed ips: 10.200.0.0/16
latest handshake: 18 seconds ago
transfer: 3.2 KiB received, 4.8 KiB sent
persistent keepalive: every 25 secondsDocker (linuxserver/wireguard)
docker exec rela-vpn wg showSame format as direct Linux.
Pass criterion: latest handshake < 120 seconds + transfer > 0 bytes in both directions.
Layer 2 — Routing
The route to the Rela AI-assigned subnet must go through the WireGuard interface.
Linux / router with shell
ip route get 10.200.7.2 # replace with an IP inside your assigned subnetExpected:
10.200.7.2 dev wg0 src 10.200.7.2 uid 0Key: dev wg0 (or rela-vpn depending on the name you gave it). If it says dev eth0 or similar, the route is wrong and traffic is not going through the tunnel.
Mikrotik
/ip route print where dst-address=10.200.X.0/24Should show a route GATEWAY=rela-vpn.
pfSense / OPNsense
Diagnostics → Routes and search for 10.200.X.0/24 — must point to the rela_vpn interface.
Pass criterion: the 10.200.X.0/24 prefix (your assigned subnet) has a route via the WireGuard interface.
Layer 3 — IP connectivity (ping)
From your router/gateway, ping an IP within the Rela AI-assigned subnet:
ping -c 4 10.200.7.2Expected: 0% packet loss, RTT typically 30–150 ms (depending on your geographic location relative to europe-west1).
Note: Only IPs "on the Rela AI side" respond to ping if we have a sim there (testbed). In production your subnet is reserved only for your devices, so ping will fail until you've configured a PLC or a test peer. The absence of ping to
10.200.X.2is not necessarily an error in prod.
When it DOES matter: from the plant side, ping <PLC_IP> (internal IP, NOT the VPN IP) must work. If it doesn't, the PLC or your LAN has a problem — not the VPN.
Pass criterion: ping to the PLC from the router (local LAN) works.
Layer 4 — TCP port
Now verify that the Modbus port (502) on the PLC responds:
# From the router / gateway, if it has nc or ncat:
nc -zv <PLC_IP> 502
# Alternative with telnet:
telnet <PLC_IP> 502Expected:
Connection to 192.168.1.50 502 port [tcp/*] succeeded!If you see Connection refused or No route to host, the problem is in the plant — not the VPN. Check:
- Plant-local firewall between router and PLC.
- The Modbus service on the PLC is on.
- The right IP — check the PLC's network settings.
Pass criterion: nc/telnet to the PLC's 502 port says succeeded.
Layer 5 — Actual Modbus read
Test a read_holding_registers against the PLC. Several tools:
From Linux with pymodbus-client (more technical)
pip install pymodbus
python3 <<EOF
import asyncio
from pymodbus.client import AsyncModbusTcpClient
async def main():
c = AsyncModbusTcpClient("192.168.1.50", port=502)
await c.connect()
r = await c.read_holding_registers(address=0, count=1, device_id=1)
print("value:", r.registers if hasattr(r, "registers") else r)
c.close()
asyncio.run(main())
EOFExpected: a number (e.g. [785] if it's temperature ×10).
From Windows with Modbus Poll (GUI)
- Install Modbus Poll (free trial).
- Connect → Modbus TCP/IP → PLC IP, port 502, Unit 1.
- Setup → Read/Write Definition → Holding Register, Address 0, Quantity 1.
- Should show the value in real time.
From the Rela AI Dashboard
If you already created the Modbus source pointing at the PLC:
- Dashboard →
Alarms → Sources → your-source. - Click Test connection.
- A panel opens with:
rtt_ms: round-trip latency (should be under 500 ms).sample_values: table with the register name + decoded value.
Pass criterion: you read a numeric value that changes with the real process (if you watch for 10-30 seconds, it should vary slightly if the process is active).
Layer 6 — Full pipeline in the Dashboard
The final leg: events reach the inbox.
- Dashboard →
Alarms → Inbox. - Within 1-5 minutes of having the source active, you should see events with your register name as
event_type(e.g.reactor.temperature). - The inbox consolidates detections from the same source under the same asset; if you see a row growing with
count × N, it's working.
Pass criterion: events with your event_type appear in the inbox.
Troubleshooting Layer 1: the handshake never arrives
If Last Handshake = never or RX/TX at 0:
1. Outbound firewall
Your router must be able to make an outbound UDP connection to port 51820 toward the public IP of our concentrator. Many corporate firewalls block UDP by default.
Check: from the router, try nc -uvz <concentrator-ip> 51820 (hangs for a few seconds and ends). If the firewall allows, go to the next step; if it blocks, ask IT to open that outbound flow.
2. Correct public key
A single missed character in copy-paste breaks the handshake. Verify the peer's PublicKey on your router matches exactly what the dashboard shows.
3. NAT closing the mapping
If your router is behind double NAT (ISP + corporate), the UDP mapping can close before the next handshake. Make sure PersistentKeepalive = 25 is active. This forces a handshake every 25s and keeps the NAT alive.
4. MTU mismatch
Rare but possible: if your connection has MTU under 1420, WG packets fragment. Router logs may show "packet too big".
Fix: lower the WG interface MTU to 1380:
- pfSense: VPN → WireGuard → Settings → MTU = 1380
- Linux:
ip link set mtu 1380 dev wg0
Troubleshooting Layer 3-4: handshake OK but you don't reach the PLC
1. Forwarding disabled on the router
Your router needs net.ipv4.ip_forward=1 to pass traffic between interfaces.
- Linux:
sudo sysctl -w net.ipv4.ip_forward=1(persist in/etc/sysctl.conf). - pfSense: enabled by default.
- Mikrotik: enabled by default.
2. LAN firewall rules
Your router must allow traffic from the WG interface to your OT LAN.
- pfSense:
Firewall → Rules → WireGuard interface. Add aAllow from any to LAN subnetrule. - OPNsense: same.
- Mikrotik: verify there's no
droprule in/ip firewall filterfor packetsin-interface=rela-vpn.
3. PLC doesn't accept connections outside its LAN
Some PLCs have an internal IP whitelist. The TCP source from our worker is 10.200.X.2 (the VPN-assigned IP for your site). Make sure the PLC doesn't block that IP.
Troubleshooting Layer 5-6: Modbus answers locally but Rela AI doesn't
1. The worker doesn't have Direct VPC Egress enabled
If VPN connectivity was just activated on your account, there may be a few-minute delay until Cloud Run redeploys. Wait 5 minutes and retry.
2. Wrong deployment mode
- If the PLC is behind your VPN, the source must have
deployment_mode = cloud_direct. - If you use rela-ai-edge instead of VPN, it must be
deployment_mode = edge+ assignededge_gateway_id.
3. Wrong Unit ID
Check on the PLC which slave ID responds (1 is default but some PLCs come with 2 or 255).
4. Data type / byte order
If the connection works but the value looks absurd, it's a decoding problem. See the troubleshooting in the Modbus guide.
Quick printable checklist
[ ] wg show shows latest handshake < 2 min
[ ] ip route get <assigned_subnet_IP> → dev wgX
[ ] ping from router to local PLC works
[ ] nc -zv <PLC_IP> 502 → succeeded
[ ] read_holding_registers from router returns real value
[ ] Dashboard: Test connection with rtt_ms < 500 + correct sample_values
[ ] Inbox: events with event_type=<register_name> appear within 2 minIf all 7 checks are ✓, your tunnel is ready for production. Hand off to the plant team to start configuring alarms and rules.
If any check fails, you have the exact corner to check — use the matching troubleshooting section above.
VPN Connectivity — Setup and Configuration
Create a dedicated WireGuard tunnel between your plant and Rela AI, download the config tailored to your equipment, and verify the PLC reaches the platform.
Why a dedicated tunnel?
The 9 technical and compliance reasons why Rela AI doesn't use our customers' corporate VPN — and what you gain from a dedicated WireGuard peer.