diff --git a/.github/workflows/image-publish.yml b/.github/workflows/image-publish.yml index dd7da149455..9a58e298869 100644 --- a/.github/workflows/image-publish.yml +++ b/.github/workflows/image-publish.yml @@ -198,4 +198,5 @@ jobs: run: | SHORT_SHA1=$(git rev-parse --short=7 HEAD) docker buildx build --platform linux/amd64 -f build/dockerfiles/dev.Dockerfile --push -t quay.io/che-incubator/che-code-dev:insiders -t quay.io/che-incubator/che-code-dev:next -t quay.io/che-incubator/che-code-dev:insiders-${SHORT_SHA1} . + docker buildx build --platform linux/amd64 -f build/dockerfiles/dev.sshd.Dockerfile --push -t quay.io/che-incubator/che-code-sshd:insiders -t quay.io/che-incubator/che-code-sshd:next -t quay.io/che-incubator/che-code-sshd:insiders-${SHORT_SHA1} . diff --git a/build/dockerfiles/dev.sshd.Dockerfile b/build/dockerfiles/dev.sshd.Dockerfile new file mode 100644 index 00000000000..8573a00c417 --- /dev/null +++ b/build/dockerfiles/dev.sshd.Dockerfile @@ -0,0 +1,62 @@ +# Copyright (c) 2025 Red Hat, Inc. +# This program and the accompanying materials are made +# available under the terms of the Eclipse Public License 2.0 +# which is available at https://www.eclipse.org/legal/epl-2.0/ +# +# SPDX-License-Identifier: EPL-2.0 +# + +FROM quay.io/devfile/universal-developer-image:latest + +USER 0 + +RUN dnf -y install libsecret openssh-server && \ + dnf -y clean all --enablerepo='*' + +# Step 1. Generate SSH Host keys +RUN mkdir /opt/ssh +RUN chmod 755 /opt/ssh +RUN chown -R root:root /opt/ssh/ + +RUN ssh-keygen -q -N "" -t dsa -f /opt/ssh/ssh_host_dsa_key && \ + ssh-keygen -q -N "" -t rsa -b 4096 -f /opt/ssh/ssh_host_rsa_key && \ + ssh-keygen -q -N "" -t ecdsa -f /opt/ssh/ssh_host_ecdsa_key && \ + ssh-keygen -q -N "" -t ed25519 -f /opt/ssh/ssh_host_ed25519_key + +# Step 2. Configure SSH as non-root user +RUN cp /etc/ssh/sshd_config /opt/ssh/ + +# Step 3. Fix permissions +RUN chmod 644 /opt/ssh/ssh_host_* /opt/ssh/sshd_config + +# Use non-privileged port, set user authorized keys, disable strict checks +RUN sed -i \ +-e 's|#Port 22|Port 2022|' \ +-e 's|AuthorizedKeysFile .ssh/authorized_keys|AuthorizedKeysFile /home/user/ssh/authorized_keys|' \ +-e 's|#StrictModes yes|StrictModes=no|' \ +-e 's|#PidFile /var/run/sshd.pid|PidFile /tmp/sshd.pid|' \ +-e 's|#LogLevel INFO|LogLevel DEBUG3|' \ + /opt/ssh/sshd_config + +# Provide new path containing host keys +RUN sed -i \ +-e 's|#HostKey /etc/ssh/ssh_host_rsa_key|HostKey /opt/ssh/ssh_host_rsa_key|' \ +-e 's|#HostKey /etc/ssh/ssh_host_ecdsa_key|HostKey /opt/ssh/ssh_host_ecdsa_key|' \ +-e 's|#HostKey /etc/ssh/ssh_host_ed25519_key|HostKey /opt/ssh/ssh_host_ed25519_key|' \ + /opt/ssh/sshd_config + +# Prepare SSH Keys +RUN ssh-keygen -q -N "" -t ed25519 -f /opt/ssh/ssh_client_ed25519_key +RUN chmod 644 /opt/ssh/ssh_client_* + +# Add script to start and stop the service +COPY --chown=0:0 /build/scripts/sshd.start / + +RUN mkdir /opt/www +COPY /build/scripts/server.js /opt/www/ + +ENV USER_NAME=dev + +EXPOSE 2022 3400 + +USER 10001 diff --git a/build/scripts/server.js b/build/scripts/server.js new file mode 100644 index 00000000000..e77f8934599 --- /dev/null +++ b/build/scripts/server.js @@ -0,0 +1,74 @@ +/* + Copyright (c) 2025 Red Hat, Inc. + This program and the accompanying materials are made + available under the terms of the Eclipse Public License 2.0 + which is available at https://www.eclipse.org/legal/epl-2.0/ + + SPDX-License-Identifier: EPL-2.0 +*/ + +const http = require('http'); +const fs = require('fs'); +const hostname = '127.0.0.1'; +const port = 3400; + +const server = http.createServer((req, res) => { + res.statusCode = 200; + res.setHeader('Content-Type', 'text/html'); + + let hasUserPrefSSHKey = fs.existsSync('/etc/ssh/dwo_ssh_key.pub'); + + let pubKey = "PUBLIC KEY COULD NOT BE DISPLAYED"; + try { + pubKey = fs.readFileSync('/etc/ssh/dwo_ssh_key.pub', 'utf8'); + } catch (err) { + // continue + } + + let genKey = "PRIVATE KEY NOT FOUND"; + try { + genKey = fs.readFileSync('/opt/ssh/ssh_client_ed25519_key', 'utf8'); + } catch (err) { + // continue + } + + let keyMessage = ` +
${hasUserPrefSSHKey ? pubKey : genKey}
+

+

+ This can also be configured locally in $HOME/.ssh/config with the following :`; + + res.end(` + + + + ${process.env["DEVWORKSPACE_NAME"]} + + +

Workspace ${process.env["DEVWORKSPACE_NAME"]} is running

+
+
    +
  1. Make sure your local oc client is logged in to your OpenShift cluster
  2. +
  3. Run oc port-forward ${process.env["HOSTNAME"]} 2022:2022. This establishes a connection to the workspace.

  4. +
  5. +

    In your local VS Code, connect to localhost on port 2022 with user ${process.env["USER_NAME"]} ${hasUserPrefSSHKey ? `. The SSH key, corresponding to the following public key, configured in the "SSH Keys" tab of "User Preferences" has been authorized to connect :` : `and the following identity file :`} ${keyMessage} +

    +Host localhost
    +  HostName 127.0.0.1
    +  User ${process.env["USER_NAME"]}
    +  Port 2022
    +  IdentityFile /path/to/the/ssh_client_ed25519_key
    +        
    +

    +
  6. +
+

If the connection fails with "WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED", it may be necessary to remove the localhost or 127.0.0.1 entries from $HOME/.ssh/known_hosts. This is because the SSHD service container (to which oc port-forward is forwarding) may change.

+
+ + + `); +}); + +server.listen(port, hostname, () => { + console.log(`Server running at http://${hostname}:${port}/`); +}); diff --git a/build/scripts/sshd.start b/build/scripts/sshd.start new file mode 100755 index 00000000000..5f8598e35d8 --- /dev/null +++ b/build/scripts/sshd.start @@ -0,0 +1,20 @@ +#!/bin/bash +# +# Copyright (c) 2025 Red Hat, Inc. +# This program and the accompanying materials are made +# available under the terms of the Eclipse Public License 2.0 +# which is available at https://www.eclipse.org/legal/epl-2.0/ +# +# SPDX-License-Identifier: EPL-2.0 +# + +rm -rf /home/user/ssh +mkdir -p /home/user/ssh +if [ -f /etc/ssh/dwo_ssh_key.pub ]; then + cp /etc/ssh/dwo_ssh_key.pub /home/user/ssh/authorized_keys +else + cp /opt/ssh/ssh_client_ed25519_key.pub /home/user/ssh/authorized_keys +fi + +# start +/usr/sbin/sshd -D -f /opt/ssh/sshd_config -E /tmp/sshd.log