From 2373af008bbbc87279543a98aac003e0c3dc49b1 Mon Sep 17 00:00:00 2001
From: Roland Grunberg
Date: Sun, 9 Nov 2025 10:27:54 -0500
Subject: [PATCH 1/3] Clean up calculation for the Dev Spaces host name.
- Set SSHD LogLevel from DEBUG3 to DEBUG1 for reduction in log file size
- Add basic documentation to CSS file
Signed-off-by: Roland Grunberg
---
build/dockerfiles/dev.sshd.Dockerfile | 2 +-
build/scripts/code-sshd-page/page-style.css | 12 +++++++++---
build/scripts/code-sshd-page/page-utils.js | 1 -
build/scripts/code-sshd-page/server.js | 10 +++-------
4 files changed, 13 insertions(+), 12 deletions(-)
diff --git a/build/dockerfiles/dev.sshd.Dockerfile b/build/dockerfiles/dev.sshd.Dockerfile
index 63dbedc0618..7b6c543f108 100644
--- a/build/dockerfiles/dev.sshd.Dockerfile
+++ b/build/dockerfiles/dev.sshd.Dockerfile
@@ -34,7 +34,7 @@ RUN sed -i \
-e 's|#Port 22|Port 2022|' \
-e 's|#StrictModes yes|StrictModes=no|' \
-e 's|#PidFile /var/run/sshd.pid|PidFile /tmp/sshd.pid|' \
--e 's|#LogLevel INFO|LogLevel DEBUG3|' \
+-e 's|#LogLevel INFO|LogLevel DEBUG1|' \
/opt/ssh/sshd_config
# Provide new path containing host keys
diff --git a/build/scripts/code-sshd-page/page-style.css b/build/scripts/code-sshd-page/page-style.css
index 17e12653084..cc078b56cba 100644
--- a/build/scripts/code-sshd-page/page-style.css
+++ b/build/scripts/code-sshd-page/page-style.css
@@ -7,6 +7,7 @@
SPDX-License-Identifier: EPL-2.0
*/
+/* Code block */
pre {
background-color: #f6f8fa; /* Light gray background */
overflow-x: auto; /* Enable horizontal scrolling for long lines */
@@ -17,6 +18,7 @@ pre {
padding: 10px;
}
+/* Inline code */
code {
background-color: #e3e6e8; /* Slightly darker gray for inline code */
padding: 2px 4px;
@@ -25,14 +27,16 @@ code {
font-size: 0.9em; /* Slightly smaller than surrounding text */
}
+/* Container for code block & clipboard icon */
.parent {
- background-color: #f6f8fa; /* Light gray background */
+ background-color: #f6f8fa;
display: table;
width: 100%;
}
+/* Container for clipboard icon of code block */
.clipboard {
- background-color: #f6f8fa; /* Light gray background */
+ background-color: #f6f8fa;
display: table-cell;
width: 2%;
}
@@ -46,7 +50,7 @@ code {
}
.clipboard-img-code {
- background-color: #e3e6e8; /* Slightly darker gray for inline code */
+ background-color: #e3e6e8;
width: 10px;
height: 10px;
border: 1px solid black;
@@ -55,6 +59,8 @@ code {
vertical-align: bottom;
}
+
+/* Colour change for clipboard icon hover */
.clipboard-img-pre:hover {
background:#e3e6e8;
}
diff --git a/build/scripts/code-sshd-page/page-utils.js b/build/scripts/code-sshd-page/page-utils.js
index 6ad7231a263..6d32fff8f8e 100644
--- a/build/scripts/code-sshd-page/page-utils.js
+++ b/build/scripts/code-sshd-page/page-utils.js
@@ -13,7 +13,6 @@ function copyToClipboard(id) {
}
function initializePlatformContent() {
-
if (navigator.userAgent.indexOf('Windows') !== -1) {
var pathEntries = document.getElementsByClassName('path');
for (var i = 0; i < pathEntries.length; i++) {
diff --git a/build/scripts/code-sshd-page/server.js b/build/scripts/code-sshd-page/server.js
index ece7823e785..ce4c06a483c 100644
--- a/build/scripts/code-sshd-page/server.js
+++ b/build/scripts/code-sshd-page/server.js
@@ -145,13 +145,9 @@ function getHostURL () {
return undefined;
}
let i = 0;
- while (i < consoleURL.length || i < devspacesURL.length) {
- if (consoleURL.substring(consoleURL.length - 1 - i) != devspacesURL.substring(devspacesURL.length - 1 - i)) {
- if (i != 0) {
- break;
- }
- }
+ while (i < consoleURL.length && i < devspacesURL.length
+ && consoleURL.substring(consoleURL.length - 1 - i) === devspacesURL.substring(devspacesURL.length - 1 - i)) {
i++;
- }
+ }
return consoleURL.substring(consoleURL.length - i);
}
From fb6f87eece1a1889437169a81f075d830694d127 Mon Sep 17 00:00:00 2001
From: Roland Grunberg
Date: Fri, 7 Nov 2025 10:55:10 -0500
Subject: [PATCH 2/3] Set up SSHD service entirely within sshd.start.
- Use a volume, /sshd/ that can be used to share SSHD resources
(/usr/sbin/sshd, /usr/bin/ssh-keygen, /etc/ssh/sshd_config,
sshd.start, tools, dynamic libs) across containers
- Use nss_wrapper to ensure default (random) user has a login shell
(instead of /sbin/nologin) and a writeable home folder
- Set home folder to /var/tmp/user if container has set it to / in
passwd and for HOME
- Use LD_PRELOAD to include required libraries in minimal containers
- Place common tools on PATH using .profile
- Prepend exec to (final) SSHD daemon startup in script
Signed-off-by: Roland Grunberg
---
build/dockerfiles/dev.sshd.Dockerfile | 39 ++-----------
build/scripts/code-sshd-page/server.js | 13 ++++-
build/scripts/sshd.start | 79 ++++++++++++++++++++++++--
3 files changed, 89 insertions(+), 42 deletions(-)
diff --git a/build/dockerfiles/dev.sshd.Dockerfile b/build/dockerfiles/dev.sshd.Dockerfile
index 7b6c543f108..57bffc2cde5 100644
--- a/build/dockerfiles/dev.sshd.Dockerfile
+++ b/build/dockerfiles/dev.sshd.Dockerfile
@@ -6,43 +6,15 @@
# SPDX-License-Identifier: EPL-2.0
#
-FROM quay.io/devfile/universal-developer-image:latest
+FROM quay.io/devfile/base-developer-image:latest
USER 0
-RUN dnf -y install libsecret openssh-server && \
+RUN dnf -y install libsecret openssh-server nss_wrapper-libs nodejs && \
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|#StrictModes yes|StrictModes=no|' \
--e 's|#PidFile /var/run/sshd.pid|PidFile /tmp/sshd.pid|' \
--e 's|#LogLevel INFO|LogLevel DEBUG1|' \
- /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
+# sshd_config is root:root 600
+RUN chmod 644 /etc/ssh/sshd_config
# Add script to start and stop the service
COPY --chown=0:0 /build/scripts/sshd.start /
@@ -53,9 +25,6 @@ COPY /build/scripts/code-sshd-page/* /opt/www/
# Lock down /etc/passwd until fixed in UDI
RUN chmod 644 /etc/passwd
-# Bypass nologin shell for random generated user
-RUN cp /bin/bash /sbin/nologin
-
EXPOSE 2022 3400
USER 10001
diff --git a/build/scripts/code-sshd-page/server.js b/build/scripts/code-sshd-page/server.js
index ce4c06a483c..683bb07efe8 100644
--- a/build/scripts/code-sshd-page/server.js
+++ b/build/scripts/code-sshd-page/server.js
@@ -14,6 +14,13 @@ const os = require('os');
const hostname = '127.0.0.1';
const port = 3400;
+let username = "UNKNOWN";
+try {
+ username = fs.readFileSync(`/sshd/username`, 'utf8');
+} catch (error) {
+ // continue
+}
+
const server = http.createServer((req, res) => {
if (req.url === '/') {
res.statusCode = 200;
@@ -30,7 +37,7 @@ const server = http.createServer((req, res) => {
let genKey = "PRIVATE KEY NOT FOUND";
try {
- genKey = fs.readFileSync(`${process.env["HOME"]}/.ssh/ssh_client_ed25519_key`, 'utf8');
+ genKey = fs.readFileSync(`/sshd/ssh_client_ed25519_key`, 'utf8');
} catch (err) {
// continue
}
@@ -55,7 +62,7 @@ const server = http.createServer((req, res) => {
. This establishes a connection to the workspace.
- In your local VS Code instance, with either "Remote - SSH" (for VS Code), or "Open Remote - SSH" (for Code-OSS), connect to localhost on port 2022 with user ${os.userInfo().username} ${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 :`}
+ In your local VS Code instance, with either "Remote - SSH" (for VS Code), or "Open Remote - SSH" (for Code-OSS), connect to localhost on port 2022 with user ${username} ${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}
@@ -77,7 +84,7 @@ const server = http.createServer((req, res) => {
Host localhost
HostName 127.0.0.1
- User ${os.userInfo().username}
+ User ${username}
Port 2022
IdentityFile $HOME/.ssh/ssh_client_ed25519_key
UserKnownHostsFile /dev/null
diff --git a/build/scripts/sshd.start b/build/scripts/sshd.start
index 86872e0ce44..fcf51633118 100755
--- a/build/scripts/sshd.start
+++ b/build/scripts/sshd.start
@@ -8,13 +8,84 @@
# SPDX-License-Identifier: EPL-2.0
#
+# https://github.com/sclorg/s2i-nodejs-container/blob/master/22/root/opt/app-root/etc/generate_container_user
+USER_ID=$(id -u)
+
+export LD_PRELOAD=/sshd/libeconf.so.0:/sshd/libpam.so.0:/sshd/libcrypt.so.2
+
+# Configure passwd/group files for SSHD
+# Random user must have a login shell and appropriate home folder
+if [ x"$USER_ID" != x"0" -a x"$USER_ID" != x"1001" ]; then
+ mkdir -p /var/tmp/etc
+ NSS_WRAPPER_PASSWD=/var/tmp/etc/passwd
+ NSS_WRAPPER_GROUP=/etc/group
+ # Some images (eg. UDI) may contain duplicate users with different IDs
+ USER_NAME=$(grep $USER_ID /etc/passwd | cut -d: -f1)
+
+ cat /etc/passwd | sed \
+ -e "/$USER_ID/ s|/sbin/nologin|/bin/bash|" \
+ -e "/$USER_ID/ s|:/:|:/var/tmp/user:|" \
+ -e "/$USER_NAME:/{/:$USER_ID:/!d;}" \
+ > $NSS_WRAPPER_PASSWD
+
+ export NSS_WRAPPER_PASSWD
+ export NSS_WRAPPER_GROUP
+ export LD_PRELOAD=$LD_PRELOAD:/sshd/libnss_wrapper.so
+fi
+
+if [ $HOME = "/" ]; then
+ export HOME=/var/tmp/user
+ mkdir -p /var/tmp/user
+fi
+
+# Common tools needed to set up service
+mkdir -p $HOME/bin
+cp /sshd/tar /sshd/gzip $HOME/bin/
+echo 'export PATH=$PATH:$HOME/bin' >> $HOME/.profile
+
+# Configure SSHD as non-root user
+
+mkdir /var/tmp/ssh
+chmod 755 /var/tmp/ssh
+
+# Generate SSH Host keys
+/sshd/ssh-keygen -q -N "" -t dsa -f /var/tmp/ssh/ssh_host_dsa_key && \
+/sshd/ssh-keygen -q -N "" -t rsa -b 4096 -f /var/tmp/ssh/ssh_host_rsa_key && \
+/sshd/ssh-keygen -q -N "" -t ecdsa -f /var/tmp/ssh/ssh_host_ecdsa_key && \
+/sshd/ssh-keygen -q -N "" -t ed25519 -f /var/tmp/ssh/ssh_host_ed25519_key
+
+# Ensure appropriate permissions
+chmod 600 /var/tmp/ssh/ssh_host_* /sshd/sshd_config
+
+# Use non-privileged port, disable strict checks
+sed -i \
+-e 's|#Port 22|Port 2022|' \
+-e 's|#StrictModes yes|StrictModes=no|' \
+-e 's|#PidFile /var/run/sshd.pid|PidFile /tmp/sshd.pid|' \
+-e 's|#LogLevel INFO|LogLevel DEBUG1|' \
+ /sshd/sshd_config
+
+# Provide new path containing host keys
+sed -i \
+-e 's|#HostKey /etc/ssh/ssh_host_rsa_key|HostKey /var/tmp/ssh/ssh_host_rsa_key|' \
+-e 's|#HostKey /etc/ssh/ssh_host_ecdsa_key|HostKey /var/tmp/ssh/ssh_host_ecdsa_key|' \
+-e 's|#HostKey /etc/ssh/ssh_host_ed25519_key|HostKey /var/tmp/ssh/ssh_host_ed25519_key|' \
+ /sshd/sshd_config
+
+# Use keys that have been configured, and generate them otherwise
mkdir -p $HOME/.ssh
if [ -f /etc/ssh/dwo_ssh_key.pub ]; then
cp /etc/ssh/dwo_ssh_key.pub $HOME/.ssh/authorized_keys
else
- ssh-keygen -q -N "" -t ed25519 -f $HOME/.ssh/ssh_client_ed25519_key
- cp $HOME/.ssh/ssh_client_ed25519_key.pub $HOME/.ssh/authorized_keys
+ /sshd/ssh-keygen -q -N '' -t ed25519 -f /sshd/ssh_client_ed25519_key
+ cp /sshd/ssh_client_ed25519_key.pub $HOME/.ssh/authorized_keys
fi
-# start
-/usr/sbin/sshd -D -f /opt/ssh/sshd_config -E /tmp/sshd.log
+cp /sshd/sshd_config /var/tmp/ssh/
+
+# Notify that configuration has been successful and share username
+echo -n "$(whoami)" > /sshd/username
+
+# start SSHD
+exec /sshd/sshd -D -f /var/tmp/ssh/sshd_config -E /tmp/sshd.log
+
From 8bcfb1b275975a6dbf1f1fb2a4cecbcb3371d9c5 Mon Sep 17 00:00:00 2001
From: Roland Grunberg
Date: Thu, 8 Jan 2026 12:16:14 -0500
Subject: [PATCH 3/3] Use ubi9-nodejs-20-minimal image as base for
che-code-sshd.
Signed-off-by: Roland Grunberg
---
build/dockerfiles/dev.sshd.Dockerfile | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/build/dockerfiles/dev.sshd.Dockerfile b/build/dockerfiles/dev.sshd.Dockerfile
index 57bffc2cde5..812ecf918e9 100644
--- a/build/dockerfiles/dev.sshd.Dockerfile
+++ b/build/dockerfiles/dev.sshd.Dockerfile
@@ -6,12 +6,12 @@
# SPDX-License-Identifier: EPL-2.0
#
-FROM quay.io/devfile/base-developer-image:latest
+FROM registry.access.redhat.com/ubi9/nodejs-20-minimal:9.6
USER 0
-RUN dnf -y install libsecret openssh-server nss_wrapper-libs nodejs && \
- dnf -y clean all --enablerepo='*'
+RUN microdnf -y install libsecret openssh-server nss_wrapper-libs && \
+ microdnf -y clean all --enablerepo='*'
# sshd_config is root:root 600
RUN chmod 644 /etc/ssh/sshd_config