Troubleshooting Siemens IOT2020 DNS Resolution on Static IP

David Krause11 min read
Industrial NetworkingSiemensTroubleshooting
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

Troubleshooting Siemens IOT2020 DNS Resolution on Static IP

The Siemens SIMATIC IOT2020 (6ES7647-0AA00-0YA2) and IOT2040 (6ES7647-0AA00-1YA2) are Intel Quark x1000-based industrial IoT gateways designed to bridge field-level PLC networks with higher-level MES, cloud, or analytics systems. Both ship with the Siemens "Example Image" based on Debian 8 (jessie) and the proprietary iot2000setup console tool that drives first-boot configuration through a serial terminal. A recurring field issue with these devices is that name resolution (DNS) works correctly under DHCP, but the moment a fixed / static IPv4 address is configured through iot2000setup, hostnames stop resolving and any application that depends on FQDN lookup (NTP, OPC UA, MQTT brokers, cloud SDKs, package updates) silently fails. This reference documents the root cause, the proven fix used by integrators in the field, and the verification steps that confirm DNS is genuinely restored rather than merely masked.

Affected Hardware, Firmware, and Image Revisions

Model Order Number SoC RAM Example Image Branch Symptom Reproducible
SIMATIC IOT2020 6ES7647-0AA00-0YA2 Intel Quark x1000 @ 400 MHz 1 GB DDR3 Debian 8 / kernel 4.4 Yes
SIMATIC IOT2040 6ES7647-0AA00-1YA2 Intel Quark x1000 @ 400 MHz 1 GB DDR3 Debian 8 / kernel 4.4 Yes
SIMATIC IOT2050 6ES7647-0BA00-0YA2 ARM Cortex-A53 quad-core 1 GB / 2 GB DDR4 Debian 10 / kernel 5.10 Different mechanism (see Notes)

The behavior described in this article is specific to the IOT2020/IOT2040 Example Image where iot2000setup writes /etc/network/interfaces directly and where resolvconf may or may not be installed depending on the exact point release. The IOT2050 uses a fundamentally different image and systemd-resolved; the manual /etc/resolv.conf edit pattern still works there but is not the canonical procedure.

Note: Siemens published the original "IOT2000 Setting Up" guide (entry ID 109741654 in the Siemens Industry Online Support). All file paths and tool names in this article refer to that guide and to the firmware shipped with the IOT2020 / IOT2040 Example Image V2.x.

Problem Statement

The fault pattern observed in the field is consistent across deployments:

  1. The IOT2020 is configured through iot2000setup with DHCP. After reboot, ping 8.8.8.8 succeeds and ping google.com also succeeds. DNS resolution works.
  2. The administrator reconfigures the device with a fixed IP address, subnet mask, and gateway through the same tool (or by editing /etc/network/interfaces directly).
  3. After reboot, ping 8.8.8.8 still succeeds (Layer 3 is fine) but ping google.com fails with ping: unknown host google.com. The same behavior applies to every FQDN-based service the gateway runs.
  4. Re-entering DHCP through iot2000setup immediately restores DNS. Re-entering a fixed IP breaks it again.

The output of cat /etc/resolv.conf after the failure typically shows either an empty file, a file containing only the literal word nameserver with no address, or a stale DHCP lease value that points at a server that no longer accepts the static client. The /etc/network/interfaces file may contain correct dns-nameservers directives, but those directives are silently ignored because resolvconf is not installed on the standard image and the ifupdown hooks have nobody to talk to.

Root Cause: Why DNS Stops Working After Static IP Configuration

The Example Image used by Siemens relies on the legacy Debian ifupdown network stack. The chain that should populate /etc/resolv.conf looks like this:

  1. ifup eth0 parses /etc/network/interfaces.
  2. If dns-nameservers 8.8.8.8 8.8.4.4 is present and the resolvconf package is installed, ifupdown passes the values to resolvconf, which atomically regenerates /etc/resolv.conf.
  3. If resolvconf is not installed (default on the stock Example Image), ifupdown simply drops the directives and the file /etc/resolv.conf is never updated.

Under DHCP, the dhclient daemon writes /etc/resolv.conf directly via its resolv.conf hook script (/etc/dhcp/dhclient-exit-hooks.d/resolvconf or its fallback), which is why DNS appears to "work" only in DHCP mode. When the static configuration is written by iot2000setup, dhclient is no longer run, the hook is never executed, and no other component regenerates the resolver file.

A second failure mode compounds the issue: /etc/resolv.conf on the IOT2020 is sometimes a symlink to /var/run/resolvconf/resolv.conf. If resolvconf was never installed, that target file does not exist and the symlink dangles. Any attempt to overwrite the symlink target then writes to a non-existent path, leaving the operator convinced that the change "did not take".

Field-proven caveat: Adding dns-nameservers lines to /etc/network/interfaces alone will not work on the stock IOT2020 image. You must either install resolvconf, replace the symlink manually, or hard-write the resolver file and protect it against being clobbered on next boot.

Solution: Rebuild and Lock /etc/resolv.conf

The integrated procedure that resolves the issue on the IOT2020 / IOT2040 Example Image is the one documented in the original Siemens support thread and replicated by Siemens support engineers. It has three parts, all of which are required for a permanent fix.

Step 1 — Remove the stale /etc/resolv.conf

Connect to the IOT2020 either over the serial console (115200 8N1) or over SSH. Become root:

su -

Inspect the current file and its inode:

ls -l /etc/resolv.conf
stat /etc/resolv.conf

If it is a symlink (which is the most common state on a stock image), unlink it:

unlink /etc/resolv.conf

If it is a regular file that was zeroed out by a failed DHCP attempt, delete it outright:

rm -f /etc/resolv.conf

Step 2 — Write a fresh resolver file

Create a new /etc/resolv.conf with one or more valid upstream resolvers. Use the gateway IP (most reliable when on a routed corporate subnet) and a public fallback such as Google's 8.8.8.8 / 8.8.4.4 or Cloudflare's 1.1.1.1:

cat > /etc/resolv.conf <<'EOF'
# Generated manually for static-IP deployment
nameserver 192.168.1.1
nameserver 8.8.8.8
nameserver 1.1.1.1
search example.local
EOF

The search directive is optional but recommended when the IOT2020 needs to reach PLCs by short hostname (e.g. s7-1500 instead of s7-1500.plant.example.local). Use the DNS suffix your control network actually publishes; do not invent one.

Lock the permissions so the file is not silently overwritten by a misbehaving service:

chmod 644 /etc/resolv.conf
chown root:root /etc/resolv.conf

Step 3 — Make the file immutable

This is the step that prevents recurrence after reboot. The chattr +i flag tells the kernel to reject any write to the file, including writes from dhclient hooks, ifupdown scripts, or stray apt post-install hooks:

chattr +i /etc/resolv.conf

Verify the immutable bit is set:

lsattr /etc/resolv.conf
# expected output line: ----i---------e----- /etc/resolv.conf

If you ever need to edit the file later (for example to switch upstream resolvers), drop the immutable bit first:

chattr -i /etc/resolv.conf
nano /etc/resolv.conf
chattr +i /etc/resolv.conf
Warning: Some package installs (notably resolvconf and certain DHCP client upgrades) will refuse to proceed if /etc/resolv.conf is immutable. Plan to lift the bit, install the package, then re-apply chattr +i.

Verification Procedure

Run the following checks in order. Each one isolates a different layer of the resolver path.

  1. Resolver file present and immutable:
    ls -l /etc/resolv.conf && lsattr /etc/resolv.conf
    Expected: regular file owned by root, ----i---------e----- flag set.
  2. Layer 3 reachability:
    ping -c 3 8.8.8.8
    Expected: at least one reply. If this fails the gateway is the issue, not DNS.
  3. Direct DNS query against each configured resolver:
    dig @8.8.8.8 google.com +short
    Expected: at least one A record. If dig is not installed, apt-get install dnsutils first.
  4. Resolver library path:
    getent hosts google.com
    Expected: prints the IP address. This exercises libc → /etc/nsswitch.conf → /etc/resolv.conf end to end.
  5. Application-level probe:
    curl -v https://www.siemens.com --max-time 10 -o /dev/null
    Expected: TLS handshake completes. If this fails but step 4 succeeds, suspect a transparent proxy, MTU, or TLS interception device on the corporate network.
  6. Persistence after reboot:
    reboot and re-run steps 1 and 4 from a fresh SSH session. If DNS breaks again, the immutable bit was not honored (typically because the filesystem was remounted or the file was recreated by an init script).

Persistent Configuration Through /etc/network/interfaces

For deployments that prefer to keep all network state in one declarative file, install the resolvconf package so that ifupdown can update the resolver file automatically when the interface comes up:

apt-get update
apt-get install resolvconf

Then add the DNS directives to /etc/network/interfaces inside the iface eth0 inet static stanza:

auto eth0
iface eth0 inet static
    address 192.168.1.50
    netmask 255.255.255.0
    gateway 192.168.1.1
    dns-nameservers 192.168.1.1 8.8.8.8 1.1.1.1
    dns-search example.local

Reboot, then verify:

ls -l /etc/resolv.conf
# Expected: /etc/resolv.conf -> /var/run/resolvconf/resolv.conf
cat /etc/resolv.conf

Apply the immutable bit to the underlying target file so that downstream hooks cannot clobber it:

chattr +i /var/run/resolvconf/resolv.conf

Alternative: Disabling Network Manager Overrides

On later Example Image point releases (V2.6 and above), Siemens introduced NetworkManager alongside ifupdown. NetworkManager owns /etc/resolv.conf via its own dispatcher and will overwrite the file you manually wrote if it believes it has authority over the interface. To keep the manual file in place:

systemctl stop NetworkManager
systemctl disable NetworkManager

Then re-apply the immutable bit and reboot. This approach is acceptable on a single-ethernet device that is permanently wired into one control VLAN, which is the typical IOT2020 deployment topology.

Edge Cases: Corporate Proxies, IPv6, and Split DNS

Scenario Symptom Diagnosis Remediation
Corporate transparent proxy on port 3128 DNS works, HTTPS fails with 407 env | grep -i proxy shows nothing; curl -v shows CONNECT 407 Set http_proxy / https_proxy in /etc/environment or per-service
Split-horizon DNS with two internal zones Public DNS works, internal PLC hostnames fail dig plc01.corp.local @192.168.1.1 returns NXDOMAIN from gateway, SERVFAIL from public Add internal zone as nameserver above public fallback in /etc/resolv.conf
IPv6-only upstream A queries return NOERROR with empty answer section dig AAAA google.com works, dig A google.com returns nothing Add options inet6 to /etc/resolv.conf or enable NAT64 / DNS64 upstream
Captive portal redirect DNS works for first 30 s then stops TCP/53 from gateway is accepted, UDP/53 is rate-limited after handshake Use TCP-only resolver (nameserver 8.8.8.8 with options use-vc) or switch to DoT (Cloudflare 1.1.1.1:853 via stubby)
VLAN tag lost on reboot IP is correct but gateway unreachable ip route shows no default route Add vlan-raw-device eth0 and vlan-id 100 to /etc/network/interfaces; reboot
DNS resolver behind firewall that blocks UDP/53 Intermittent timeouts on first query dig +tcp succeeds, plain dig times out Add options timeout:2 attempts:5 use-vc to force TCP

Troubleshooting Matrix

Observed Symptom Most Likely Cause First Diagnostic Command Fix
ping by IP works, by name fails /etc/resolv.conf empty or stale cat /etc/resolv.conf Rebuild as in Step 2 of Solution
Name works for 10 s, then fails Captive portal / firewall UDP/53 rate-limit dig +tcp google.com Add options use-vc
Name works on DHCP, fails on static resolvconf not installed dpkg -l | grep resolvconf Install resolvconf or hard-write /etc/resolv.conf
File reverts after reboot Init script or NetworkManager recreating it journalctl -b | grep resolv Disable NetworkManager; apply chattr +i
Name works, HTTPS handshake fails Transparent proxy / TLS interception openssl s_client -connect siemens.com:443 Configure https_proxy or install corporate CA bundle
All connectivity fails after static config Wrong subnet mask / no default route ip route Correct /etc/network/interfaces
DNS resolution slow (>2 s per query) First nameserver unreachable, fallback used dig google.com shows long response time on first server Reorder or remove dead nameserver entries

Backup and Rollback Procedure

Before touching /etc/resolv.conf, snapshot the current network state so a broken change can be undone from the serial console:

cp /etc/resolv.conf /etc/resolv.conf.bak
cp /etc/network/interfaces /etc/network/interfaces.bak
cp /etc/nsswitch.conf /etc/nsswitch.conf.bak

Rollback is then a single command from the serial console:

chattr -i /etc/resolv.conf
cp /etc/resolv.conf.bak /etc/resolv.conf
chattr +i /etc/resolv.conf
systemctl restart networking

Frequently Asked Questions

Why does DNS work on DHCP but break the moment I switch to a static IP on the IOT2020?

Under DHCP, the dhclient exit hook writes the upstream resolver addresses into /etc/resolv.conf directly. Under a static IP, ifupdown relies on the resolvconf package to translate the dns-nameservers directive into a resolver file, and resolvconf is not installed on the stock Example Image. The result is a stale or empty /etc/resolv.conf.

Do I have to use Google's 8.8.8.8 as a nameserver, or can I keep my corporate one?

Either works. Put the corporate / gateway resolver first (it usually knows the local zone) and a public fallback such as 8.8.8.8 or 1.1.1.1 second. Three entries is the practical maximum; more than that slows down fallback when the primary is down.

Is the chattr +i step really necessary?

Yes, on the IOT2020 it is. Without the immutable bit, the next reboot, package upgrade, or iot2000setup re-run will silently overwrite /etc/resolv.conf and you will be back to "DNS mysteriously stopped working". Lifting the bit is required before any apt-get install that touches the file.

Does this same procedure apply to the SIMATIC IOT2050?

Mechanically yes, but the IOT2050 ships with systemd-resolved active and the canonical fix is to edit /etc/systemd/resolved.conf (DNS= and Domains= directives) then restart the service. The manual /etc/resolv.conf rebuild still works as a quick field fix when the systemd path is unavailable.

My corporate network uses a proxy. Can I still fix DNS without bypassing it?

Yes. Configure the corporate DNS resolvers (typically the gateway IP or a dedicated internal DNS server) in /etc/resolv.conf exactly as described. The proxy only affects HTTP/HTTPS egress on TCP/3128 or TCP/8080, not DNS on UDP/53 or TCP/53. If the proxy also intercepts DNS, use the proxy's DNS relay address instead of 8.8.8.8.

What is the maximum number of nameserver entries I should put in /etc/resolv.conf?

Three is the practical maximum on the IOT2020. The C library queries them in order with a 5-second timeout and 2 retries by default; a fourth or fifth dead resolver measurably delays the first response and has no real-world benefit over three well-chosen ones.

Back to blog