Skip to content

Commit 1220392

Browse files
committed
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) 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 - Prepend exec to (final) SSHD daemon startup in script Signed-off-by: Roland Grunberg <[email protected]>
1 parent 2373af0 commit 1220392

File tree

3 files changed

+79
-42
lines changed

3 files changed

+79
-42
lines changed

build/dockerfiles/dev.sshd.Dockerfile

Lines changed: 4 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -6,43 +6,15 @@
66
# SPDX-License-Identifier: EPL-2.0
77
#
88

9-
FROM quay.io/devfile/universal-developer-image:latest
9+
FROM quay.io/devfile/base-developer-image:latest
1010

1111
USER 0
1212

13-
RUN dnf -y install libsecret openssh-server && \
13+
RUN dnf -y install libsecret openssh-server nss_wrapper-libs nodejs && \
1414
dnf -y clean all --enablerepo='*'
1515

16-
# Step 1. Generate SSH Host keys
17-
RUN mkdir /opt/ssh
18-
RUN chmod 755 /opt/ssh
19-
RUN chown -R root:root /opt/ssh/
20-
21-
RUN ssh-keygen -q -N "" -t dsa -f /opt/ssh/ssh_host_dsa_key && \
22-
ssh-keygen -q -N "" -t rsa -b 4096 -f /opt/ssh/ssh_host_rsa_key && \
23-
ssh-keygen -q -N "" -t ecdsa -f /opt/ssh/ssh_host_ecdsa_key && \
24-
ssh-keygen -q -N "" -t ed25519 -f /opt/ssh/ssh_host_ed25519_key
25-
26-
# Step 2. Configure SSH as non-root user
27-
RUN cp /etc/ssh/sshd_config /opt/ssh/
28-
29-
# Step 3. Fix permissions
30-
RUN chmod 644 /opt/ssh/ssh_host_* /opt/ssh/sshd_config
31-
32-
# Use non-privileged port, set user authorized keys, disable strict checks
33-
RUN sed -i \
34-
-e 's|#Port 22|Port 2022|' \
35-
-e 's|#StrictModes yes|StrictModes=no|' \
36-
-e 's|#PidFile /var/run/sshd.pid|PidFile /tmp/sshd.pid|' \
37-
-e 's|#LogLevel INFO|LogLevel DEBUG1|' \
38-
/opt/ssh/sshd_config
39-
40-
# Provide new path containing host keys
41-
RUN sed -i \
42-
-e 's|#HostKey /etc/ssh/ssh_host_rsa_key|HostKey /opt/ssh/ssh_host_rsa_key|' \
43-
-e 's|#HostKey /etc/ssh/ssh_host_ecdsa_key|HostKey /opt/ssh/ssh_host_ecdsa_key|' \
44-
-e 's|#HostKey /etc/ssh/ssh_host_ed25519_key|HostKey /opt/ssh/ssh_host_ed25519_key|' \
45-
/opt/ssh/sshd_config
16+
# sshd_config is root:root 600
17+
RUN chmod 644 /etc/ssh/sshd_config
4618

4719
# Add script to start and stop the service
4820
COPY --chown=0:0 /build/scripts/sshd.start /
@@ -53,9 +25,6 @@ COPY /build/scripts/code-sshd-page/* /opt/www/
5325
# Lock down /etc/passwd until fixed in UDI
5426
RUN chmod 644 /etc/passwd
5527

56-
# Bypass nologin shell for random generated user
57-
RUN cp /bin/bash /sbin/nologin
58-
5928
EXPOSE 2022 3400
6029

6130
USER 10001

build/scripts/code-sshd-page/server.js

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,13 @@ const os = require('os');
1414
const hostname = '127.0.0.1';
1515
const port = 3400;
1616

17+
let username = "UNKNOWN";
18+
try {
19+
username = fs.readFileSync(`/sshd/username`, 'utf8');
20+
} catch (error) {
21+
// continue
22+
}
23+
1724
const server = http.createServer((req, res) => {
1825
if (req.url === '/') {
1926
res.statusCode = 200;
@@ -30,7 +37,7 @@ const server = http.createServer((req, res) => {
3037

3138
let genKey = "PRIVATE KEY NOT FOUND";
3239
try {
33-
genKey = fs.readFileSync(`${process.env["HOME"]}/.ssh/ssh_client_ed25519_key`, 'utf8');
40+
genKey = fs.readFileSync(`/sshd/ssh_client_ed25519_key`, 'utf8');
3441
} catch (err) {
3542
// continue
3643
}
@@ -55,7 +62,7 @@ const server = http.createServer((req, res) => {
5562
<path fill="currentColor" d="M18 20H8c-1.1 0-2-.9-2-2V8c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2v10c0 1.1-.9 2-2 2zM8 7c-.6 0-1 .4-1 1v10c0 .6.4 1 1 1h10c.6 0 1-.4 1-1V8c0-.6-.4-1-1-1H8z"></path>
5663
</svg></a>. This establishes a connection to the workspace.</p></li>
5764
<li>
58-
In your local VS Code instance, with either <a href="https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-ssh">"Remote - SSH"</a> (for VS Code), or <a href="https://open-vsx.org/extension/jeanp413/open-remote-ssh">"Open Remote - SSH"</a> (for Code-OSS), connect to <code>localhost</code> on port <code>2022</code> with user <code>${os.userInfo().username}</code> ${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 :`}
65+
In your local VS Code instance, with either <a href="https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-ssh">"Remote - SSH"</a> (for VS Code), or <a href="https://open-vsx.org/extension/jeanp413/open-remote-ssh">"Open Remote - SSH"</a> (for Code-OSS), connect to <code>localhost</code> on port <code>2022</code> with user <code>${username}</code> ${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 :`}
5966
<div class="parent">
6067
<div>
6168
<pre id="key">${keyMessage}</pre>
@@ -77,7 +84,7 @@ const server = http.createServer((req, res) => {
7784
<div>
7885
<pre id="config" class="path">Host localhost
7986
HostName 127.0.0.1
80-
User ${os.userInfo().username}
87+
User ${username}
8188
Port 2022
8289
IdentityFile $HOME/.ssh/ssh_client_ed25519_key
8390
UserKnownHostsFile /dev/null</pre>

build/scripts/sshd.start

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,74 @@
88
# SPDX-License-Identifier: EPL-2.0
99
#
1010

11+
# https://github.com/sclorg/s2i-nodejs-container/blob/master/22/root/opt/app-root/etc/generate_container_user
12+
USER_ID=$(id -u)
13+
14+
# Configure passwd/group files for SSHD
15+
# Random user must have a login shell and appropriate home folder
16+
if [ x"$USER_ID" != x"0" -a x"$USER_ID" != x"1001" ]; then
17+
mkdir -p /var/tmp/etc
18+
NSS_WRAPPER_PASSWD=/var/tmp/etc/passwd
19+
NSS_WRAPPER_GROUP=/etc/group
20+
21+
cat /etc/passwd | sed \
22+
-e "/$USER_ID/ s|/sbin/nologin|/bin/bash|" \
23+
-e "/$USER_ID/ s|:/:|:/var/tmp/user:|" \
24+
> $NSS_WRAPPER_PASSWD
25+
26+
export NSS_WRAPPER_PASSWD
27+
export NSS_WRAPPER_GROUP
28+
export LD_PRELOAD=/sshd/libnss_wrapper.so
29+
fi
30+
31+
if [ $HOME = "/" ]; then
32+
export HOME=/var/tmp/user
33+
mkdir -p /var/tmp/user
34+
fi
35+
36+
# Configure SSHD as non-root user
37+
38+
mkdir /var/tmp/ssh
39+
chmod 755 /var/tmp/ssh
40+
41+
# Generate SSH Host keys
42+
/sshd/ssh-keygen -q -N "" -t dsa -f /var/tmp/ssh/ssh_host_dsa_key && \
43+
/sshd/ssh-keygen -q -N "" -t rsa -b 4096 -f /var/tmp/ssh/ssh_host_rsa_key && \
44+
/sshd/ssh-keygen -q -N "" -t ecdsa -f /var/tmp/ssh/ssh_host_ecdsa_key && \
45+
/sshd/ssh-keygen -q -N "" -t ed25519 -f /var/tmp/ssh/ssh_host_ed25519_key
46+
47+
# Ensure appropriate permissions
48+
chmod 600 /var/tmp/ssh/ssh_host_* /sshd/sshd_config
49+
50+
# Use non-privileged port, disable strict checks
51+
sed -i \
52+
-e 's|#Port 22|Port 2022|' \
53+
-e 's|#StrictModes yes|StrictModes=no|' \
54+
-e 's|#PidFile /var/run/sshd.pid|PidFile /tmp/sshd.pid|' \
55+
-e 's|#LogLevel INFO|LogLevel DEBUG1|' \
56+
/sshd/sshd_config
57+
58+
# Provide new path containing host keys
59+
sed -i \
60+
-e 's|#HostKey /etc/ssh/ssh_host_rsa_key|HostKey /var/tmp/ssh/ssh_host_rsa_key|' \
61+
-e 's|#HostKey /etc/ssh/ssh_host_ecdsa_key|HostKey /var/tmp/ssh/ssh_host_ecdsa_key|' \
62+
-e 's|#HostKey /etc/ssh/ssh_host_ed25519_key|HostKey /var/tmp/ssh/ssh_host_ed25519_key|' \
63+
/sshd/sshd_config
64+
65+
# Use keys that have been configured, and generate them otherwise
1166
mkdir -p $HOME/.ssh
1267
if [ -f /etc/ssh/dwo_ssh_key.pub ]; then
1368
cp /etc/ssh/dwo_ssh_key.pub $HOME/.ssh/authorized_keys
1469
else
15-
ssh-keygen -q -N "" -t ed25519 -f $HOME/.ssh/ssh_client_ed25519_key
16-
cp $HOME/.ssh/ssh_client_ed25519_key.pub $HOME/.ssh/authorized_keys
70+
/sshd/ssh-keygen -q -N '' -t ed25519 -f /sshd/ssh_client_ed25519_key
71+
cp /sshd/ssh_client_ed25519_key.pub $HOME/.ssh/authorized_keys
1772
fi
1873

19-
# start
20-
/usr/sbin/sshd -D -f /opt/ssh/sshd_config -E /tmp/sshd.log
74+
cp /sshd/sshd_config /var/tmp/ssh/
75+
76+
# Notify that configuration has been successful and share username
77+
echo -n "$(whoami)" > /sshd/username
78+
79+
# start SSHD
80+
exec /sshd/sshd -D -f /var/tmp/ssh/sshd_config -E /tmp/sshd.log
81+

0 commit comments

Comments
 (0)