Installation als Webserver für Linux
Diese Anleitung beschreibt, wie Sie unter Linux CODESYS 4 als Server betreiben.
Kompatibilität
CODESYS 4 wird momentan unter Linux nur für Debian offiziell unterstützt. Es ist möglich, dass das Paket auch unter anderen Betriebssystemen (beispielsweise Ubuntu, Kubuntu, andere Debian-basierte Betriebssysteme, ...) lauffähig gemacht werden kann. Hierfür kann jedoch nur in begrenzter Kapazität Support angeboten werden.
Vorbemerkung
Grundlagen der Administration von Linux-Systemen
Benutzerverwaltung unter Linux (PAM, LDAP, IPA, ...)
Paketverwaltung unter Debian
Kenntnisse in der Verwaltung von TLS-Zertifikaten und, wenn möglich, der zugehörigen Infrastruktur
evtl. Kenntnisse im Umgang mit Docker, nginx und anderen Servertechnologien
HTTPS/TLS
CODESYS 4 verwendet Browser-APIs, die nur in einem sicheren Kontext verfügbar sind. Wenn der Zugriff über localhost läuft, ist dies immer gegeben.
Sobald Sie aber CODESYS 4 als Server im Netzwerk von anderen Rechnern zugreifbar machen wollen, ist es hierfür zwingend notwendig, dass die Kommunikation über HTTPS erfolgt, da die Applikation sonst nicht korrekt funktioniert.
Da CODESYS 4 jedoch selbst noch keine Kommunikation über HTTPS unterstützt, müssen Sie hierfür einen Proxy vorschalten. Bitte lesen Sie hierzu aufmerksam den Abschnitt Vorschalten eines TLS-Reverse-Proxy durch.
Runtime und Gateway
Die Linux-Pakete von CODESYS 4 beinhalten aktuell kein CODESYS Gateway und keine CODESYS Runtime.
Sie finden die entsprechenden Downloads im CODESYS Store.
Beachten Sie, dass Sie in Ihrem Projekt die Kommunikationseinstellungen (Gateway) so konfigurieren, dass Sie die Steuerung vom Server aus erreichen.
Anwender, die auf dem Server arbeiten, können nur mit CODESYS-Gateways und Steuerungen arbeiten, die vom Server aus erreichbar sind. Bitte achten Sie darauf, dass der Server Zugriff auf die benötigten Gateways hat oder stellen Sie ein lokales Gateway direkt auf dem Server zur Verfügung.
Vorbereitung: Anlegen der Benutzer-Accounts
Der CODESYS 4-Server stützt sich in der Benutzerverwaltung standardmäßig auf die Benutzerverwaltung des Debian-Systems. Am CODESYS 4-Server kann sich standardmäßig jeder "normale" Linux-Benutzer anmelden, der Mitglied in der Gruppe codesys-4 ist. Sie können beim Start des Servers mit der Option --login-groups=erste,zweite,dritte jedoch auch eine oder mehrere andere Gruppen angeben, die sich stattdessen anmelden können sollen.
Legen Sie die Gruppe
codesys-4an.Dies ist nur einmal notwendig und wird bei der Installation des Debian-Pakets automatisch erledigt.
Geben Sie hier Ihre eigene Gruppe an, falls Sie eine andere Gruppe verwenden möchten.
sudo addgroup codesys-4
Legen Sie den neuen Benutzer
User1an, wenn noch nicht existent.(Die Abfrage der Benutzerinformationen wie
FullName,Room Number, etc. kann einfach mit leerer Eingabe übersprungen werden)sudo adduser User1
Fügen Sie den Benutzer
User1zur Gruppecodesys-4hinzu. Weisen Sie den Benutzer einer entsprechend anderen Gruppe zu, wenn Sie eine eigene Gruppe verwenden.(damit erhält er die Berechtigung, sich im Server anzumelden)
sudo adduser User1 codesys-4
Sie können beliebig viele Benutzer anlegen. Alle Benutzer, die sich via Passwort anmelden können und Mitglied der Gruppe codesys-4 sind, können sich in CODESYS 4 einloggen.
Betrieb als Server via systemd:
CODESYS 4 muss als Server unter einem dedizierten System-Benutzer ausgeführt werden.
Vorbereitung
CODESYS 4 muss auf dem Webserver installiert sein. Installieren Sie dazu CODESYS 4 entsprechend der Anleitung im Kapitel Installation als Desktop-Applikation für Linux (bis einschließlich Abschnitt "Installation des Debian-Pakets").
Legen Sie einen dedizierten System-Benutzer für Testzwecke an.
> sudo useradd --system --create-home c4-server
Legen Sie die Datei
Service Unitfürsystemdim Pfad /etc/systemd/system/codesys-4.servicean.[Unit] Description=CODESYS 4 Server [Service] Type=exec WorkingDirectory=/opt/codesys-4/ ExecStart=/opt/codesys-4/c4-server --port 8080 Restart=always # Restart service after 10 seconds if the dotnet service crashes: RestartSec=10 KillSignal=SIGINT SyslogIdentifier=codesys-4-server User=c4-server Environment=ASPNETCORE_ENVIRONMENT=Production Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false [Install] WantedBy=multi-user.target
Starten Sie den Service via
systemd.$> sudo systemctl start codesys-4
Der Dienst ist über http auf
localhost, Port 8080 erreichbar.
Betrieb als Server via Docker
Kein Standard-Docker-Image
CODESYS 4 wird momentan nicht als Docker-Image verteilt. Es gibt daher kein offizielles Docker-Image, das für den Produktivbetrieb von CODESYS 4 vorgesehen ist.
Sie können sich jedoch selbst ein Docker-Image bauen. Die Schritte hierfür sind in diesem Abschnitt nachfolgend beschrieben.
Vorkenntnisse und Support
Um diesen Anwendungsfall korrekt einzurichten, sind grundlegende Kenntnisse im Umgang mit Docker zwingend notwendig. Für die grundlegende Bedienung von Docker kann kein Support gegeben werden.
# Official ASP.NET 8.0 runtime base image FROM mcr.microsoft.com/dotnet/aspnet:8.0 WORKDIR /opt/codesys-4 # The default port is 8080 EXPOSE 8080 # We have to be root to install the package, switch back to app after USER root # Install the Debian package for CODESYS 4. # We set ACCEPT_CODESYS_EULA=true to skip the interactive prompt to accept the EULA during package installation. # Building and executing this Dockerfile therefore means you accept the terms and condition of the CODESYS Engineering EULA! RUN --mount=type=bind,source=output/,target=/tmp/output/ <<EOF ACCEPT_CODESYS_EULA=true dpkg -i /tmp/output/codesys-4*.deb EOF # The server should run with the unprivileged system user "app", see # https://learn.microsoft.com/en-us/dotnet/core/compatibility/containers/8.0/app-user # For security reasons, c4-server will refuse to start as root. USER app:app ENTRYPOINT ["/opt/codesys-4/c4-server"]
Um das Image bauen zu können, müssen Sie zunächst das CODESYS 4-Debian-Paket herunterladen und in dem Ordner, in dem das Dockerfile liegt, im Unterordner output/ ablegen. Dann können Sie das Image ganz normal mittels docker buildx build bauen.
Beim Starten des Images in einem Container ist zu beachten, dass sich am Server nur die Benutzer anmelden können, die im Container existieren und Mitglied der Gruppe codesys-4 sind (vergleiche Kapitel Vorbereitung: Anlegen der Benutzer-Accounts).
Die Benutzer müssen mit geeigneten Mechanismen (beispielsweise PAM) innerhalb des Containers zur Verfügung gestellt werden. Die Home-Verzeichnisse müssen möglichst als persistente Volumes im Container gemountet sein. Abweichende Gruppendefinitionen über die Option --login-groups können entweder in dem Docker-File als Argument in der ENTRYPOINT Definition angegeben oder als Argument beim Start des Containers übergeben werden.
Für Testzwecke können Sie die auf dem Host existierenden Benutzer direkt nach dem Start des Containers in diesen synchronisieren, wie das Skript docker-test-example.sh zeigt:
(Das Script müssen Sie natürlich an Ihre Gegebenheiten anpassen, beispielsweise Ihre Tag-Bezeichner und Ihre eigene Docker-Registry.)
# This script is used to start our CODESYS 4 docker containers in our
# development and test environments (RasPi, WSL, Linux VM).
# It's not regarded as safe for production use!
# The name of our container
CONTAINER=codesys-4
# The repository to fetch the image from
URL="dockerhost.example.com:1234/codesys-images/codesys-4:develop"
# Stop and clean up any running container.
if docker inspect "$CONTAINER" > /dev/null 2>&1; then
echo Trying to clean up
docker stop "$CONTAINER"
docker rm "$CONTAINER"
fi
# stop and rm may fail when the container does not exist,
# but from here on, we want to abort on first error
set -e
echo Downloading "$URL"...
docker pull "$URL"
echo starting image...
# Starting the docker image.
# We mount the /home folder. We listen on port 8080.
# The option "--add-host host.docker.internal:host-gateway" allows us to access
# a CODESYS gateway running on the host machine via the hostname
# "host.docker.internal" from within the container.
docker run --restart=unless-stopped --detach \
--volume /home:/home \
-p127.0.0.1:8080:8080 \
-e CBE_PORT=8080 \
--add-host host.docker.internal:host-gateway \
--name "$CONTAINER" \
"$URL"
# output the version and build info, with some newlines, so it's easier readable.
echo -e \\n CODESYS 4 image build info: $(docker exec codesys-4 cat /opt/codesys-4/dist/version.json) \\n
# Ensure we have a home directory the app user can use, to write the C4 log files.
# The base image already contains /home/app, but it's shadowed by mounting our
# /home into the container, so we need to create the folder if it doesn't exist.
# Strictly speaking, this is only necessary once on a given host (because /home
# has been mounted from the host), but if we run it always, we can be sure that
# this script will also work on fresh machines.
docker exec --user 0 "$CONTAINER" bash -c "mkdir -v -p /home/app ; chown -v app:app /home/app ; chmod -v og-rwx /home/app"
# Synchronize the actual users into the container. We use a very hackish approach
# here, not recommended for production use, it just works for the dev environment.
# WARNING: Synchronizing will only work when:
# 1) The users do not yet exist within the container
# 2) The numeric user and group IDs are not yet occupied within the container.
# Also, it's recommended to configure sudo so it caches the password using
# timestamp-timeout, or even NOPASSWD if you want to take the risk.
# Only the groups codesys-4 and the user personal group will be synchronized.
echo synchronizing group codesys-4
getent group codesys-4| docker exec --user 0 -i "$CONTAINER" /bin/sh -c "cat >>/etc/group"
sudo getent gshadow codesys-4| docker exec --user 0 -i "$CONTAINER" /bin/sh -c "cat >>/etc/gshadow"
# get all users in group codesys-4
C4_USERS=$(getent group codesys-4| awk -F':' '{print $4}' | tr ',' ' ')
for CURRENT in $C4_USERS ; do
echo synchronizing user $CURRENT
getent passwd $CURRENT | docker exec --user 0 -i "$CONTAINER" /bin/sh -c "cat >>/etc/passwd"
sudo getent shadow $CURRENT | docker exec --user 0 -i "$CONTAINER" /bin/sh -c "cat >>/etc/shadow"
# we also need to synchronize the user specific group
getent group $CURRENT | docker exec --user 0 -i "$CONTAINER" /bin/sh -c "cat >>/etc/group"
sudo getent gshadow $CURRENT | docker exec --user 0 -i "$CONTAINER" /bin/sh -c "cat >>/etc/gshadow"
done
echo finished.Vorschalten eines TLS-Reverse-Proxys
CODESYS 4 verwendet Browser-APIs, die nur in einem sicheren Kontext verfügbar sind. Wenn der Zugriff über localhost läuft, ist dies immer gegeben. Sobald CODESYS 4 als Server im Netzwerk von anderen Rechnern zugänglich ist, muss zwingend eine TLS-Verschlüsselung eingerichtet werden, deren Server-Zertifikat von den Browsern als vertrauenswürdig eingestuft wird.
Aktuell implementiert CODESYS 4 noch keine TLS-Verschlüsselung. Wenn Sie CODESYS 4 hinter einem Portal-Proxy betreiben, kann dieser die TLS-Verschlüsselung übernehmen. Ansonsten kann problemlos ein Reverse-Proxy wie beispielsweise nginx vorgeschaltet werden, der die TLS-Verschlüsselung übernimmt. Insbesondere die Direktiven proxy_set_header und proxy_cache_bypass sind hierbei notwendig, damit auch alles (inklusive WebSocket) funktioniert.
SSL-Zertifikate
Sie benötigen für diesen Anwendungsfall zwingend entweder ein gültiges SSL-Zertifikat oder ein selbstsigniertes SSL-Zertifikat, das in Ihrer Organisation als vertrauenswürdig eingestuft ist.
Bitte wenden Sie sich hierfür an Ihren IT-Administrator und versuchen Sie nicht, ohne Vorwissen eigene Zertifikate als vertrauenswürdig einzustufen.
Wenn Sie dennoch wünschen, für Testzwecke Zertifikate zu generieren und Sie wissen was Sie tun, können Sie die Anleitung im Abschnitt TLS-Zertifikate für Testzwecke verwenden. Diese Zertifikate dürfen niemals in Produktion verwendet werden!
Nginx als Reverse Proxy
Das nachfolgende Beispiel zeigt eine Konfiguration von nginx als Reverse Proxy, um die TLS-Verschlüsselung für CODESYS 4 zu übernehmen. Die folgende Datei können Sie unter /etc/nginx/sites-available/codesys-4 anlegen. Die Pfade unter ssl_certificate und ssl_certificate_key müssen Sie dabei auf die tatsächlichen Ablageorte Ihrer Zertifikate anpassen. Danach können Sie die Konfiguration unter /etc/nginx/sites-enabled/ via symlink aktivieren, und nginx neu starten.
# See https://docs.microsoft.com/en-us/troubleshoot/developer/webapps/aspnetcore/practice-troubleshoot-linux/2-2-install-nginx-configure-it-reverse-proxy
# for more information.
server {
listen 443 ssl;
listen [::]:443 ssl;
ssl_certificate /etc/ssl/certs/codesys-4-certificate.crt;
ssl_certificate_key /etc/ssl/private/codesys-4.key;
#server_name _;
server_tokens off; # see https://nginx.org/en/docs/http/ngx_http_core_module.html#server_tokens
location / {
rewrite ^/$ /index.html last;
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
#hsts header
add_header Strict-Transport-Security "max-age=31536000" always;
}
}
# Redirect unencrypted http access to encrypted https access.
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
server_name _;
return 301 https://$host$request_uri;
}TLS-Zertifikate für Testzwecke
Sicherheitshinweis
ACHTUNG: Das Erstellen und Vertrauen eigener Zertifikate kann ein enormes Sicherheitsrisiko darstellen. Führen Sie die nachfolgenden Schritte nur dann aus, wenn Sie dafür die Erlaubnis von Ihrem IT-Administrator haben. Versuchen Sie nicht, eventuell vorhandene Gruppenrichtlinien oder andere Sicherheitsvorkehrungen zu umgehen, um diese Schritte durchzuführen.
Für den Produktivbetrieb sind unbedingt Zertifikate einer offiziellen, von den Browsern anerkannten Zertifizierungsstelle (CA) anzuraten, alternativ in Ihrer Firmeninfrastruktur anerkannte Zertifikate. Im Zweifelsfall stimmen Sie sich mit Ihrer IT-Abteilung ab.
Achten Sie unbedingt darauf, die privaten Schlüsseldateien example.key und insbesondere exampleca.key nur geschützt abzulegen und niemandem sonst zugänglich zu machen. Jeder, der in den Besitz dieser Dateien gelangt, kann damit beliebige Zertifikate fälschen und somit einen Man-in-the-Middle-Angriff gegen Sie oder Ihre Organisation starten.
Zertifikate für Testzwecke können Sie mit dem Kommando openssl wie unten dargestellt erstellen. Zuvor müssen Sie in der Datei example_cert.ext die Hostnamen eintragen, für die das Zertifikat gelten soll. Ebenso sollten Sie die Parameter --subj in den Kommandos an Ihren Anwendungsfall anpassen.
authorityKeyIdentifier=keyid,issuer basicConstraints=CA:FALSE keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment extendedKeyUsage=serverAuth subjectAltName = @alt_names [alt_names] DNS.1=localhost # adjust these to your needs DNS.2=first.host.example.com DNS.3=other.host.example.com
# Generate development/testing certificates for CODESYS 4. # Add the hostnames to example_cert.ext with your favourite text editor. # Creating the CA: openssl genrsa -out exampleca.key 2048 openssl req -new -x509 -days 365 -key exampleca.key -subj "/C=ZZ/ST=Example Kingdom/L=Example City/O=Example Organization/CN=Example Test CA" -out exampleca.crt # Creating the Certificate: openssl genrsa -out example.key 2048 openssl req -new -nodes -out example.csr -key example.key -subj "/C=ZZ/ST=Example Kingdom/L=Example City/O=Example Organization/CN=Example Test Server" openssl x509 -req -days 365 -in example.csr -CA exampleca.crt -CAkey exampleca.key -out codesys-4-development-certificate.crt -extfile example_cert.ext -CAcreateserial
Wichtig
Kompatibilität
Mit einer cygwin-basierten Shell (beispielsweise der GIT bash) könnte das Kommando openssl req fehlschlagen. Das ist ein bekanntes Problem in OpenSSL in Verbindung mit cygwin. Für weitere Informationen siehe https://github.com/openssl/openssl/issues/8795.
Das Problem sollte nicht auftreten, wenn Sie OpenSSL in einer echten Linux-Shell (auch WSL) oder über die Befehlszeile von CMD oder PowerShell aufrufen.
Das Stammzertifikat exampleca.crt muss dann in den jeweiligen Browsern als vertrauenswürdig hinterlegt werden. Das eigentliche Zertifikat codesys-4-development-certificate.crt und der zugehörige private Schlüssel example.key müssen auf dem Server installiert und in der Server-Konfiguration referenziert werden. Beispielsweise kann hierfür nginx verwendet werden (siehe Abschnitt Vorschalten eines TLS-Reverse-Proxys).
Bitte vergessen Sie nicht, nach dem Ende der Testphase die exampleca.crt wieder aus der Liste Ihrer vertrauenswürdigen Zertifikate in Ihren Browsern zu entfernen.