Accessing SIMATIC IOT2050 Remotely Over 4G Setup and NAT

David Krause11 min read
Industrial NetworkingSiemensTutorial / How-to
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

Overview of the Problem

The SIMATIC IOT2050 is a fanless, arm64-based industrial edge device used for data acquisition, OPC UA aggregation, MQTT bridging, and protocol translation between field devices (S7, Modbus TCP/RTU, OPC UA) and higher-level SCADA / cloud systems. When a 4G USB modem or mPCIe cellular module is installed with a SIM card, the IOT2050 typically obtains an IPv4 address through pppd on interface ppp0. Although ping www.google.com succeeds outbound and ip a shows a valid peer/remote address on the PPP link, the device cannot be reached inbound from a host PC using that IP. This is the expected behavior on virtually all consumer and M2M cellular plans because the address assigned is a Carrier-Grade NAT (CGNAT) address, not a publicly routable one.

This article documents the root cause, the diagnostics required to prove it, and the five field-proven remote-access methods: requesting a public IP, MQTT relay, reverse SSH tunnel, WireGuard/OpenVPN, and the Siemens Industrial Edge relay. Verification procedures, port maps, and a troubleshooting matrix are included for engineers deploying IOT2050 units in out-of-town cabinets, remote pumping stations, and similar unstaffed sites.

SIMATIC IOT2050 Network Architecture

The IOT2050 ships with two Gigabit Ethernet ports (eth0, eth1) managed by NetworkManager and an mPCIe slot that accepts most Quectel / Sierra Wireless LTE cat-4 / cat-6 modems. The stock Example Industrial OS image uses systemd-networkd on newer firmware and NetworkManager on older images, with a serial console on ttyS0 at 115200 8N1. The setup procedure documented in the SIMATIC IOT2050 setting up guide uses nmtui for the wired interfaces and a separate pppd peer file (typically /etc/ppp/peers/provider or /etc/ppp/peers/4g) for the cellular link.

Component Default Verification Command
Ethernet eth0 DHCP client, link-local fallback ip -br addr show eth0
Ethernet eth1 Static 192.168.200.1/24 (factory image) ip route show 192.168.200.0/24
Cellular ppp0 Obtains address from APN ip -br addr show ppp0
Default route Metric 100 on ppp0, 1024 on eth0 ip route show default
DNS Provided by PPP IPCP cat /etc/resolv.conf
SSH server Enabled (dropbear or openssh) systemctl status sshd

The factory default management address 192.168.200.1 works only because it is reachable on the same Layer-2 segment as the engineering PC. Once the IOT2050 leaves the local LAN and connects solely over LTE, that address is no longer routable from the public Internet.

Why Direct 4G Access Fails: CGNAT and Carrier NAT

When the IOT2050 negotiates a PPP session it receives an IP from the cellular provider. The IP that ip a reports on ppp0 is one of three things:

  1. Public, static IPv4 — routable from anywhere; port forwarding can be configured on the carrier's PGW.
  2. Public, dynamic IPv4 — routable, but the address changes; DDNS or a relay is required.
  3. CGNAT (RFC 6333 / DS-Lite carrier-side NAT) — the address belongs to a private pool such as 100.64.0.0/10 and is shared by hundreds of subscribers. Inbound TCP/UDP from the Internet is impossible regardless of firewall rules on the IOT2050.

To determine which case applies, run the following on the IOT2050:

ip -4 addr show ppp0 | grep inet
ip -4 route show default
curl -s https://api.ipify.org ; echo
curl -s https://ifconfig.co/json

Compare the address reported by ip a on ppp0 with the address returned by api.ipify.org. If they match, the carrier is providing a public IP. If they differ, the PPP address is CGNAT and direct inbound access will not work without operator cooperation.

Critical: Operators in the EU (Deutsche Telekom, Vodafone, Telefonica) and most US MVNOs (T-Mobile, Verizon) hand out CGNAT by default for M2M and consumer SIMs. Only enterprise APNs (e.g. iot.sfr.fr, web.vodafone.de.corp) or static-IP add-ons (often +€5–+€20/month per SIM) deliver a public address.

Verifying the Local PPP/4G Connection

Before attempting any remote-access strategy, confirm the cellular link is healthy:

# Signal quality (Quectel modems expose AT commands via /dev/ttyUSBx)
echo -e "AT+CSQ\r" | socat - /dev/ttyUSB2,crnl
# Response: +CSQ: 14,99  -- RSSI = (14-113)/2 dBm ~ -49 dBm (good)

# Registration state
echo -e "AT+CREG?\r" | socat - /dev/ttyUSB2,crnl
# +CREG: 0,1  -- registered, home network

# Active PDP context / IP assignment
echo -e "AT+CGPADDR\r" | socat - /dev/ttyUSB2,crnl

# Latency / packet loss
ping -c 5 -I ppp0 8.8.8.8

# DNS resolution
dig +short google.com @$PRIMARY_DNS

If ping -I ppp0 fails but ping (default route) succeeds, the PPP default route metric is wrong. Re-check /etc/ppp/peers/4g for the defaultroute and replacedefaultroute directives. The SIMATIC IOT2050 Industrial Edge Device (arm64) manual lists the supported LTE modules and the correct dial strings for each APN.

Method 1: Requesting a Public IP from the Carrier

The most straightforward path is to ask the mobile operator for a public, static IPv4 or for a fixed public IP behind NAT with port-forwarding enabled. Each operator handles this differently:

Operator Service Name Typical Lead Time
Vodafone Business (DE) Fixed IP Plus / M2M Static 5–10 business days
Deutsche Telekom Industrie SIM static Contract change required
Telefonica / O2 IoT Connectivity Pro 10–15 business days
SFR (FR) IP Fixe M2M 3–7 business days
Verizon (US) Static IP for Business 2–5 business days
T-Mobile (US) Not offered on M2M plans N/A — use VPN/MQTT

Once a public address is provisioned, inbound SSH on port 22 is reachable directly. Recommended hardening before opening SSH to the Internet:

# /etc/ssh/sshd_config on the IOT2050
Port 2222                       # non-standard port
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
AllowUsers iotadmin
MaxAuthTries 3
ClientAliveInterval 30
ClientAliveCountMax 3
systemctl restart sshd
firewall-cmd --permanent --add-port=2222/tcp
firewall-cmd --reload

Method 2: MQTT Broker as a Relay

When a public IP is unavailable, an MQTT broker hosted on the public Internet (Mosquitto on AWS EC2, HiveMQ Cloud, EMQX Cloud, or Siemens MindSphere) acts as a bidirectional relay. The IOT2050 maintains the outbound TCP connection (which works through any NAT) and publishes diagnostic data, accepts commands, and pushes tag values to topics subscribed by the engineering PC.

# /etc/mosquitto/mosquitto.conf (on the IOT2050 acting as publisher)
persistence true
persistence_location /var/lib/mosquitto/
log_dest file /var/log/mosquitto/mosquitto.log
connection_messages true

# Outbound to cloud broker
listener 1883 127.0.0.1
allow_anonymous false
password_file /etc/mosquitto/pwfile

# Bridge to public broker (initiated outbound, no inbound rule needed)
connection iot2050-cloud
address broker.example.com:8883
bridge_insecure false
notifications false
try_private false
start_type automatic
remote_username iot2050
remote_password <secret>
remote_clientid iot2050-sn-12345
topic # both 0 site/iot2050/ out

On the engineering PC, install mosquitto-clients and subscribe to the topic tree:

mosquitto_sub -h broker.example.com -p 8883 \
  --cafile ca.crt -u engineer -P <secret> \
  -t 'site/iot2050/#' -v

# To send a command back, e.g. trigger a digital output:
mosquitto_pub -h broker.example.com -p 8883 \
  --cafile ca.crt -u engineer -P <secret> \
  -t 'site/iot2050/cmd/digital/0' -m '1'

MQTT-SN over UDP and the Sparkplug B payload definition (Eclipse Tahu) are recommended for noisy cellular links because they compress keepalive overhead. The IOT2050 reference image includes node-red, mosquitto-clients, and the node-red-contrib-s7 palette, making it possible to convert PLC tag updates to MQTT publishes with a few clicks in the Node-RED editor.

Method 3: Reverse SSH Tunnel

A reverse SSH tunnel uses a publicly reachable Linux VPS as a jump host. The IOT2050 opens an outbound SSH connection to the VPS and requests that port 2222 on the VPS be forwarded back to port 22 on the IOT2050. The engineer then connects to vps.example.com:2222 and lands on the IOT2050's SSH daemon. This works because only outbound connections are required — the carrier NAT keeps the state open for the return traffic.

# On the IOT2050, generate a keypair as root
ssh-keygen -t ed25519 -N '' -f /root/.ssh/id_ed25519
ssh-copy-id -i /root/.ssh/id_ed25519.pub [email protected]

# Create the persistent tunnel service
cat >/etc/systemd/system/reverse-tunnel.service <<'EOF'
[Unit]
Description=Reverse SSH tunnel to VPS
After=network-online.target
Wants=network-online.target

[Service]
User=root
ExecStart=/usr/bin/ssh -N -T \
  -o ServerAliveInterval=30 \
  -o ServerAliveCountMax=3 \
  -o ExitOnForwardFailure=yes \
  -o StrictHostKeyChecking=accept-new \
  -i /root/.ssh/id_ed25519 \
  -R 2222:127.0.0.1:22 \
  [email protected]
Restart=always
RestartSec=15

[Install]
WantedBy=multi-user.target
EOF

systemctl enable --now reverse-tunnel.service

From the engineering PC:

ssh -p 2222 [email protected]

The connection transparently arrives on the IOT2050. For long-running engineering sessions add -o TCPKeepAlive=yes and consider autossh with the -M 20000 monitor port to survive cellular drops:

autossh -M 20000 -N -T \
  -o "ServerAliveInterval=10" -o "ServerAliveCountMax=3" \
  -R 2222:127.0.0.1:22 \
  -i /root/.ssh/id_ed25519 [email protected]

Method 4: VPN with WireGuard or OpenVPN

A full-mesh VPN is the cleanest solution when multiple IOT2050 units need to be reached and port forwarding on a VPS is undesired. WireGuard (kernel module in mainline Linux 5.6+, available on IOT2050 images) requires a single UDP port and survives roaming between LTE cells. OpenVPN is the fallback when UDP is blocked.

# /etc/wireguard/wg0.conf on the IOT2050
[Interface]
PrivateKey = <IOT2050_private_key>
Address = 10.10.10.21/24
DNS = 1.1.1.1

[Peer]
PublicKey = <HQ_router_public_key>
PresharedKey = <pre_shared_key>
Endpoint = hq.example.com:51820
AllowedIPs = 10.10.10.0/24, 192.168.200.0/24
PersistentKeepalive = 25
chmod 600 /etc/wireguard/wg0.conf
systemctl enable --now wg-quick@wg0
wg show   # verify handshake and transfer counters

Once the tunnel is up, the engineering PC connected to the HQ WireGuard peer can reach the IOT2050 at 10.10.10.21 as if it were on the LAN. Web-based administration (Node-RED on port 1880, the IOT2050 web configurator on port 443) becomes available without further firewall work.

Method 5: Siemens Industrial Edge Platform Relay

For plants already standardized on the Siemens Industrial Edge (IE) ecosystem, the IOT2050 can be enrolled as a managed device. The IE Hub maintains the outbound mTLS connection to the IE Databus and provides a secure reverse proxy that exposes services to authorized operators via the IE App. This is documented in the SIMATIC IOT2050 Industrial Edge Device (arm64) manual. The advantages are zero firewall configuration on the customer side, central certificate management, and audit logging; the disadvantages are a mandatory IE Hub appliance at the edge and subscription costs.

Firewall and Security Hardening

Regardless of which method is selected, the IOT2050 must be hardened before any inbound exposure. Recommended baseline:

Service Port Action Notes
SSH 22 Move to 2222, key-only auth Disable password auth
Node-RED 1880 Bind to 127.0.0.1, expose via tunnel Set uiHost=127.0.0.1 in settings.js
Mosquitto 1883 Bind to 127.0.0.1, TLS 8883 for cloud Disable anonymous
HTTP admin 80/443 Disable if not used Block with iptables
ICMP 0 Limit to 1 pps Mitigate ping flood
# /etc/nftables.conf - minimal inbound policy on ppp0
table inet filter {
  chain input {
    type filter hook input priority 0; policy drop;
    ct state established,related accept
    iifname "lo" accept
    iifname "ppp0" tcp dport 2222 accept
    iifname "ppp0" udp dport 51820 accept   # WireGuard only if used
    iifname "ppp0" limit rate 1/second icmp type echo-request accept
  }
  chain forward { policy drop; }
  chain output { policy accept; }
}
systemctl enable --now nftables

Verification Checklist

  1. ip a on IOT2050 shows the expected ppp0 address and metric.
  2. curl https://api.ipify.org matches a public address (or the documented CGNAT range 100.64.0.0/10).
  3. From the engineering PC, ssh -p <chosen_port> iotadmin@<reachable_host> lands on the IOT2050 shell.
  4. systemctl status reverse-tunnel (or wg show) shows an active session.
  5. node-red and mosquitto are bound to 127.0.0.1 only.
  6. nmap -Pn -p 22,1880,8883 <iaddress> from a third host shows only the expected ports.
  7. journalctl -u sshd -u reverse-tunnel --since "-1h" shows no failed authentications.

Troubleshooting Matrix

Symptom Likely Cause Diagnostic Fix
ping 8.8.8.8 works, ping google.com fails DNS not negotiated over PPP cat /etc/resolv.conf Add usepeerdns to /etc/ppp/peers/4g
PPP link drops every 60–90 s LCP echo failure, weak signal pppd log + AT+CSQ Mount external antenna, lower MTU to 1400
Reverse tunnel connects then disconnects Carrier TCP idle timeout ServerAliveInterval in sshd_config Set keepalive to 30 s, use autossh
WireGuard handshake never completes UDP blocked by carrier nc -uv hq.example.com 51820 Switch endpoint to TCP 443 (wg-tcp-tunnel) or use OpenVPN
MQTT publishes appear but no commands received ACL on broker rejects the client mosquitto -v with log_type all Add topic readwrite site/iot2050/cmd/# ACL
Public IP confirmed but SSH still refused Carrier-side firewall / APN Test with nc -vz <ip> 22 from external host Request "inbound allowed" from operator

Why can I ping Google from the IOT2050 but cannot SSH into it from my PC?

Outbound traffic from the IOT2050 traverses the carrier NAT successfully, but inbound traffic is blocked because the assigned PPP address is either CGNAT (RFC 6333) or a carrier-firewalled public IP. Ask the operator for a public IP with inbound allowed, or use a relay such as a reverse SSH tunnel, MQTT broker, or WireGuard VPN.

How do I confirm whether my 4G SIM is behind CGNAT?

Compare the inet address on ppp0 with the address returned by curl https://api.ipify.org. If they differ, the PPP address is CGNAT. Additionally, addresses in 100.64.0.0/10, 10.0.0.0/8, 172.16.0.0/12, or 192.168.0.0/16 on ppp0 are non-routable.

Can I open a port on the IOT2050 firewall to allow inbound SSH over 4G?

Opening the local nftables or iptables rules does not help, because the carrier NAT discards unsolicited inbound packets before they reach the device. Local firewall changes only matter once the operator confirms the SIM has a public IP with port forwarding enabled.

Which remote-access method is best for a fleet of ten IOT2050 units?

WireGuard to a central hub is the most scalable because each device maintains only one outbound UDP 51820 session and engineering tools can reach any unit by tunnel address. For brownfield deployments where the cellular contract cannot be changed, MQTT with Sparkplug B over TLS 8883 is the next best option because it also carries the process data, eliminating a second connection.

Does the SIMATIC IOT2050 support MQTT out of the box?

Yes. The reference Industrial OS image ships with Node-RED and Mosquitto. Pre-built apps in the Industrial Edge catalog include an MQTT publisher and a Siemens S7 connector, so PLC tag values can be pushed to any broker without additional programming.

Back to blog