WinCC Unified V18 exposed to the Internet…

This article will show how WinCC Unified can be accessed through a public available server in the internet.

Disclaimer: I only did this for testing and demo purposes!!!

First you need to have a public domain name and a public accessible host. Or a host running somewhere in the cloud and you will get a IP and/or an URL, which will point to your host. In my case I have a public IP address from my internet provider and my public sub domain name points to my server at home.

My registered public domain name is rocworks.at. Additionally I have used a sub-domain name unified.rocworks.at. Because I have multiple services running on my machine at home. With the subdomain the service can be easily be distinguished. At my internet provider I have configured a DDNS services, so that my subdomain unified.rocworks.at points to my IP at home. You can also use other DDNS services (noip.com) , also if you have a dynamic IP address.

If you have it running at home, then you have to setup a port forwarding from your modem to your web server IP at home.

At the WinCC Unified Runtime Host we have to change some settings in files, to set the right public URL for the identity provider (UMC). After doing this, you should reboot the computer.

Config.level (C:\Program Files\Siemens\Automation\WinCCUnified\config)

	[IdentityProvider]
	Url = "https://unified.rocworks.at/umc-sso/"
	
Web.config (C:\Program Files\Siemens\Automation\WinCCUnified\WebRH)

	<appSettings>
	    <add key="appvirtdir" value="/WebRH" />
	    <add key="origins" value="https://unified.rocworks.at" />
	  </appSettings>

Config.json (C:\Program Files\Siemens\Automation\WinCCUnified\SimaticUA)

        "dnsname": "unified.rocworks.at"

Umcd.cfg (C:\Program Files\Siemens\LocalUserManagement\etc)

	Search and replace hostnames

HKEY_LOCAL_MACHINE\SOFTWARE\Siemens\User Management\WebUI\Settings

        ipaddress = "https://unified.rocworks.at/umc-sso/"

Note: instead of "unified.rocworks.at" use your public domain name. 
    

At the web server at home I have NGINX running in a Docker Container together with Let’s Encrypt. With Let’s Encrypt and Certbot we can get valid Certificates for our Webserver. But that’s another story. Here is a docker-compose.yml file for NGINX and Let’s Encrypt:

version: '3'
services:
  nginx:
    image: nginx
    restart: unless-stopped
    ports:
      - 80:80
      - 443:443
    volumes:
      - ./data/www:/var/www
      - ./data/letsencrypt:/etc/letsencrypt
      - ./config:/etc/nginx/conf.d
       
    command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"

  certbot:
    image: certbot/certbot
    restart: unless-stopped
    volumes:
      - ./data/www:/var/www
      - ./data/letsencrypt:/etc/letsencrypt
    entrypoint: "/bin/sh -c 'trap exit TERM; while :; date; do certbot renew --webroot -w /var/www/certbot; sleep 12h & wait $${1}; done;'"

Before you start with a new sub domain you have to initially get a certificate:

docker run --rm -ti -v $PWD/data/www:/var/www -v $PWD/data/letsencrypt:/etc/letsencrypt certbot/certbot certonly --webroot -w /var/www/certbot -d <your-public-domain-name> --email <your-email-address>

NGINX Configuration: default.conf :

server {
        listen 80;
        server_name unified.rocworks.at;
        location /.well-known/acme-challenge/ {
            root /var/www/certbot;
        }
        location / {
            root /var/www/html;
        }
}

NGINX Configuration: unified.conf:

server {
        server_name unified.rocworks.at;

        root /var/www/html;
        index index.html index.htm;

        location / {
            proxy_pass https://<ip-of-wincc-unified-host>/;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_cache_bypass $http_upgrade;
        }

        location /umc-sso {
            proxy_pass https://<ip-of-wincc-unified-host>/umc-sso;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_cache_bypass $http_upgrade;
            proxy_buffer_size 128k;
            proxy_buffers 4 256k;
            proxy_busy_buffers_size 256k;
        }

        #location /graphql { # Optionally you can also publish GraphQL
        #    proxy_pass http://<ip-of-wincc-unified-host>:4000/graphql;
        #    proxy_http_version 1.1;
        #    proxy_set_header Upgrade $http_upgrade;
        #    proxy_set_header Connection 'upgrade';
        #    proxy_set_header Host $host;
        #    proxy_cache_bypass $http_upgrade;
        #}
        

        listen 443 ssl; # managed by Certbot
        ssl_certificate /etc/letsencrypt/live/unified.rocworks.at/fullchain.pem; # managed by Certbot
        ssl_certificate_key /etc/letsencrypt/live/unified.rocworks.at/privkey.pem; # managed by Certbot
        include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}