Skip to main content

安装为 Linux Web 服务器

本指南介绍了如何运行CODESYS 4作为Linux服务器上运行。

兼容性

CODESYS 4目前,Linux 系统上的该软件包仅官方支持 Debian 系统。虽然该软件包未来有可能在其他基于 Debian 的发行版(例如 Ubuntu、Kubuntu 等)上运行,但支持程度有限。

开场白

. 生产运营CODESYS 4作为服务器管理员,需要具备以下方面的知识:
  • Linux系统管理基础

  • Linux 用户管理(PAM、LDAP、IPA 等)

  • Debian 上的软件包管理

  • 了解 TLS 证书管理,如果可能,还需了解相关的基础设施。

  • 可能需要了解 Docker、nginx 和其他服务器技术

HTTPS/TLS

CODESYS 4它使用仅在安全环境下可用的浏览器 API。当通过以下方式访问时,情况始终如此:localhost。

你想做的时候就去做CODESYS 4但是,作为网络上其他计算机可以访问的服务器,必须通过 HTTPS 进行通信,否则应用程序将无法正常工作。

因为CODESYS 4本身尚不支持通过 HTTPS 进行通信,您需要设置上游代理才能实现此功能。更多信息,请阅读完整章节。设置上游 TLS 反向代理小心。

运行时和网关

来自 Linux 的软件包CODESYS 4目前不包括CODESYS网关或CODESYS运行时。

您可以在以下位置找到相应的下载:CODESYS Store。

请确保在项目中配置通信设置(网关),以便可以从服务器访问控制器。

在该服务器上工作的用户只能通过以下方式访问它:CODESYS服务器可以访问的网关和控制器。请确保服务器能够访问所需的网关,或者直接在服务器上配置本地网关。

准备工作:创建用户帐户

默认情况下,用户管理CODESYS 4服务器基于 Debian 系统的用户管理。每个普通的 Linux 用户,只要是 Debian 系统的成员,都可以使用该服务器。codesys-4群组可以登录CODESYS 4服务器默认启动。但是,您也可以使用以下选项启动服务器。--login-groups=first,second,third指定一个或多个其他组,这些组应该能够登录。

  1. 创建codesys-4团体。

    这只需要执行一次,并且在安装 Debian 软件包时会自动完成。

    如果您想使用其他组,请在此处指定您自己的组。

    sudo addgroup codesys-4
  2. 创建新用户User1如果它还不存在的话。

    (提示用户提供信息,例如)FullName,Room Number(例如,可以留空跳过。)

    sudo adduser User1
  3. 添加User1到codesys-4分组。如果您使用的是自己的组,请将用户分配到其他组。

    (这将授予该用户登录服务器的权限。)

    sudo adduser User1 codesys-4

您可以创建任意数量的用户。所有用户都可以使用密码登录,并且都是会员。codesys-4群组可以登录CODESYS 4。

通过 systemd 作为服务器运行

CODESYS 4服务器必须在专用系统用户下运行。

准备

CODESYS 4必须安装在 Web 服务器上。为此,请执行以下步骤:安装CODESYS 4根据本章中的指南作为 Linux 桌面应用程序安装(直至“安装 Debian 软件包”部分,包括该部分)

  1. 创建一个专门用于测试的系统用户。

    > sudo useradd --system --create-home c4-server
  2. 在目录中/etc/systemd/system/codesys-4.service配置Service Unit文件systemd

    [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
  3. 通过以下方式启动服务systemd。

    $> sudo systemctl start codesys-4

    该服务将通过 HTTP 提供。localhost在端口 8080 上。

通过 Docker 作为服务器运行

这不是标准的 Docker 镜像

CODESYS 4目前尚未以 Docker 镜像的形式分发。因此,没有官方的 Docker 镜像可供生产环境使用。CODESYS 4。

当然,您也可以构建自己的 Docker 镜像。本节稍后将介绍具体步骤。

先验知识和支持

要正确设置此用例,必须具备 Docker 的基本知识。我们无法提供 Docker 基本使用方面的支持。

例 3. Dockerfile 示例:
# 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"]


要构建镜像,首先需要下载 Debian 软件包。CODESYS 4并将其保存到output/ Dockerfile 所在的子文件夹。然后,您可以像往常一样使用以下命令构建镜像:docker buildx build命令。

在容器中启动镜像时,请注意只有存在于容器中且属于该容器的成员的用户才能访问镜像。codesys-4小组可以登录服务器(参见章节)。准备工作:创建用户帐户)。

用户必须能够访问容器内的合适机制,例如 PAM。主目录应尽可能挂载为容器内的持久卷。通过以下方式更改组定义:--login-groups可以在 Dockerfile 中将此选项指定为 ENTRYPOINT 定义的参数,也可以在容器启动时将其作为参数传递。

为了进行测试,您可以在容器启动后立即将主机上的现有用户同步到容器中,如下所示:docker-test-example.sh脚本:

(当然,您需要根据自身具体情况调整脚本,例如标签标识符和您自己的 Docker 镜像仓库。)

例 4. docker-test-example.sh(仅用于测试目的!)
# 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.


预先部署 TLS 反向代理

CODESYS 4它使用仅在安全环境下可用的浏览器 API。当通过以下方式访问时,情况始终如此:localhost。 立刻CODESYS 4由于网络中的其他计算机可以访问服务器,因此必须设置 TLS 加密,并且该服务器证书必须受到所用浏览器的信任。

CODESYS 4目前尚未实现 TLS 加密。CODESYS 4如果运行在门户代理之后,它可以维持 TLS 加密。否则,反向代理(例如)nginx可以预先轻松部署,从而保持 TLS 加密。特别是,proxy_set_header和proxy_cache_bypass指令是必要的,这样一切才能正常运行(包括 WebSocket)。

SSL证书

对于此使用场景,您绝对需要一个有效的 SSL 证书,或者一个在您的组织内被认定为受信任的自签名 SSL 证书。

请咨询您的 IT 管理员,不要在事先不了解的情况下尝试将您自己的证书归类为受信任的证书。

如果您仍然希望出于测试目的颁发证书,并且您清楚自己在做什么,那么您可以按照该部分的指南进行操作。使用 TLS 证书进行测试这些证书绝不能用于生产环境。

Nginx 作为反向代理

以下示例展示了如何配置 nginx 作为反向代理,以维护 TLS 加密。CODESYS 4您可以将以下文件保存到/etc/nginx/sites-available/codesys-4您还需要调整以下路径。ssl_certificate和ssl_certificate_key指向证书的实际位置。之后,您可以使用symlink启用以下配置/etc/nginx/sites-enabled/然后重启nginx。

例 5. /etc/nginx/sites-available/codesys-4
# 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 证书

安全通知

警告:颁发和信任您自己的证书可能带来严重的安全风险。请仅在获得 IT 管理员许可的情况下执行以下步骤。切勿尝试绕过任何现有的组策略或其他安全措施来执行这些步骤。

为了确保高效使用,强烈建议使用浏览器认可的官方证书颁发机构 (CA) 颁发的证书,或者使用公司内部基础设施认可的证书。如有疑问,请咨询您的 IT 部门。

务必妥善保管私钥文件example.key尤其exampleca.key这些文件必须安全保存,并且其他人无法访问。任何能够访问这些文件的人都可以利用它们伪造任意数量的证书,从而对您或您的组织发起中间人攻击。

你可以使用openssl如下所示,使用命令生成用于测试的证书。在此之前,在example_cert.ext您需要修改文件中的主机名,以确定证书的有效范围。您还应该调整……--subj根据您的具体使用场景,在命令中添加参数。

例 6. 示例证书扩展
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


例 7. 生成证书
# 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


重要

兼容性

使用基于 Cygwin 的 shell——例如 Git bash——openssl req命令可能失败。这是 OpenSSL 与 Cygwin 相关的一个已知问题。更多信息,请参阅以下内容: https://github.com/openssl/openssl/issues/8795。

当您在真正的 Linux shell(也称为 WSL)中运行 OpenSSL 或通过 CMD 或 PowerShell 命令行运行时,不应出现此问题。

根证书exampleca.crt然后需要在相应的浏览器中注册为受信任的证书。实际的证书codesys-4-development-certificate.crt以及相应的私钥example.key必须安装在服务器上,并在服务器配置中引用。例如,可以使用 nginx 来实现此目的(参见相关章节)。预先部署 TLS 反向代理。

记得移除exampleca.crt测试阶段结束后,从浏览器中受信任的证书列表中获取证书。