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:
- Public, static IPv4 — routable from anywhere; port forwarding can be configured on the carrier's PGW.
- Public, dynamic IPv4 — routable, but the address changes; DDNS or a relay is required.
-
CGNAT (RFC 6333 / DS-Lite carrier-side NAT) — the address belongs to a private pool such as
100.64.0.0/10and 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.
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
-
ip aon IOT2050 shows the expectedppp0address and metric. -
curl https://api.ipify.orgmatches a public address (or the documented CGNAT range100.64.0.0/10). - From the engineering PC,
ssh -p <chosen_port> iotadmin@<reachable_host>lands on the IOT2050 shell. -
systemctl status reverse-tunnel(orwg show) shows an active session. -
node-redandmosquittoare bound to127.0.0.1only. -
nmap -Pn -p 22,1880,8883 <iaddress>from a third host shows only the expected ports. -
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.