diff --git a/build/dockerfiles/dev.sshd.Dockerfile b/build/dockerfiles/dev.sshd.Dockerfile index 63dbedc0618..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 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 +# 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/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..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
    @@ -145,13 +152,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); } diff --git a/build/scripts/sshd.start b/build/scripts/sshd.start index 86872e0ce44..f9c58c7983f 100755 --- a/build/scripts/sshd.start +++ b/build/scripts/sshd.start @@ -8,13 +8,74 @@ # 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) + +# 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 + + cat /etc/passwd | sed \ + -e "/$USER_ID/ s|/sbin/nologin|/bin/bash|" \ + -e "/$USER_ID/ s|:/:|:/var/tmp/user:|" \ + > $NSS_WRAPPER_PASSWD + + export NSS_WRAPPER_PASSWD + export NSS_WRAPPER_GROUP + export LD_PRELOAD=/sshd/libnss_wrapper.so +fi + +if [ $HOME = "/" ]; then + export HOME=/var/tmp/user + mkdir -p /var/tmp/user +fi + +# 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 +