Skip to content

Commit

Permalink
feat: prepare SSHD to work in the Helm chart #27
Browse files Browse the repository at this point in the history
- Correct naming of variables
- Allow SSHD logging level configuration with `$SSHD_LOG_LEVEL`
- Fix tests
- Fix README
- Disable `PAM` on SSHD to allow unprivileged users

Signed-off-by: Damien Duportal <[email protected]>
  • Loading branch information
dduportal committed Nov 23, 2024
1 parent f5b1b3f commit df46b7c
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 15 deletions.
4 changes: 3 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ EXPOSE $RSYNCD_PORT $SSHD_PORT
USER $user

# Change it to 'sshd' to use rsync over SSH instead of rsyncd
ENV RSYNC_DAEMON="rsyncd"
ENV RSYNCD_DAEMON="rsyncd"

ENV SSHD_LOG_LEVEL="INFO"

ENTRYPOINT ["/bin/tini","--"]

Expand Down
11 changes: 7 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,20 +48,20 @@ rsync -av --port=873 localhost::jenkins/ .tmp/jenkins/

This mode should be preferred when using authenticated access (usually to write data).

To enable SSH instead of RsyncD, the environment variable `$RSYNC_DAEMON` must be set to the value `sshd`.
To enable SSH instead of RsyncD, the environment variable `$RSYNCD_DAEMON` must be set to the value `sshd`.

SSH is restricted to only `rsync *` commands for the `rsyncd` user:
you cannot login and execute commands, no port/X11 forwarding and no SCP/sftp are allowed
(see the `ssh-rsync-wrapper.sh` script specified in the authorized keys).

SSH Authentication is restricted to only 1 public key associated to the default user `rsyncd`.
This key is provided through the `$SSH_PUBLIC_KEY` environment variable.
This key is provided through the `$SSHD_PUBLIC_KEY` environment variable.

Simple example:

```shell
# Start in background
docker run --detach --read-only -p 22:22 -e RSYNC_DAEMON=sshd -e SSH_PUBLIC_KEY="$(cat ~/.ssh/id_rsyncd.pub)" rsyncd
docker run --detach --read-only -p 22:22 -e RSYNCD_DAEMON=sshd -e SSHD_PUBLIC_KEY="$(cat ~/.ssh/id_rsyncd.pub)" rsyncd
# Check default dir (empty) with the rsync protocol and unauthenticated request
rsync -av --rsh="ssh -i $HOME/.ssh/id_rsyncd" rsyncd@localhost:data/ .tmp/
```
Expand All @@ -70,11 +70,14 @@ It exposes the default SSH port `22`, which can be changed using the `$SSHD_PORT

```shell
# Start in background and publishes the port 4022
docker run --detach --read-only -p 4022:4022 -e SSHD_PORT=4022 -e RSYNC_DAEMON=sshd -e SSH_PUBLIC_KEY="$(cat ~/.ssh/id_rsyncd.pub)" rsyncd
docker run --detach --read-only -p 4022:4022 -e SSHD_PORT=4022 -e RSYNCD_DAEMON=sshd -e SSHD_PUBLIC_KEY="$(cat ~/.ssh/id_rsyncd.pub)" rsyncd
# Check default dir (empty) with the rsync protocol and unauthenticated request
rsync -av --rsh="ssh -p 4022 -i $HOME/.ssh/id_rsyncd" rsyncd@localhost:data/ .tmp/
```

SSH Daemon log level can be set through the `$SSHD_LOG_LEVEL` environment variable.
Default value is `INFO`, refer to <https://manpages.debian.org/testing/openssh-server/sshd_config.5.en.html#LogLevel> for possible values.

Safety Note: There are no concepts of "Rsync" module with SSH: any specified directory accessible by the `rsyncd` user can be read (...or written).
As such, it's recommended to always use a read-only rootfs and eventually restrict network access as additional security measures to the key based authentication.

Expand Down
4 changes: 3 additions & 1 deletion cst.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ metadataTest:
- "873"
user: rsyncd
envVars:
- key: RSYNC_DAEMON
- key: RSYNCD_DAEMON
value: rsyncd
- key: SSHD_PORT
value: "22"
Expand All @@ -18,6 +18,8 @@ metadataTest:
value: /home/rsyncd/etc
- key: USER_RUN_DIR
value: /home/rsyncd/run
- key: SSHD_LOG_LEVEL
value: INFO
volumes: ["/home/rsyncd", "/tmp"]
workdir: /home/rsyncd/data

Expand Down
12 changes: 6 additions & 6 deletions entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

set -eux -o pipefail

case "${RSYNC_DAEMON:-rsyncd}" in
case "${RSYNCD_DAEMON:-rsyncd}" in
'rsyncd')
# Generate configuration from env vars
envsubst '$RSYNCD_PORT $USER_ETC_DIR $USER_RUN_DIR'< "${USER_ETC_DIR}"/rsyncd.conf.orig > "${USER_ETC_DIR}"/rsyncd.conf
Expand All @@ -11,7 +11,7 @@ case "${RSYNC_DAEMON:-rsyncd}" in
exec /usr/bin/rsync --no-detach --daemon --config "${USER_ETC_DIR}"/rsyncd.conf;;
'sshd')
# Generate configuration from env vars
envsubst '$SSHD_PORT $USER_ETC_DIR $USER_RUN_DIR'< "${USER_ETC_DIR}"/sshd_config.orig > "${USER_ETC_DIR}"/sshd_config
envsubst '$SSHD_PORT $SSHD_LOG_LEVEL $USER_ETC_DIR $USER_RUN_DIR'< "${USER_ETC_DIR}"/sshd_config.orig > "${USER_ETC_DIR}"/sshd_config

# Generate hostkeys
ssh-keygen -q -N "" -t dsa -f "${USER_ETC_DIR}"/ssh_host_dsa_key
Expand All @@ -20,17 +20,17 @@ case "${RSYNC_DAEMON:-rsyncd}" in
ssh-keygen -q -N "" -t ed25519 -f "${USER_ETC_DIR}"/ssh_host_ed25519_key

# Load public key if provided
if [[ "${SSH_PUBLIC_KEY:-'defaultNoKey'}" == ssh-* ]]; then
if [[ "${SSHD_PUBLIC_KEY:-'defaultNoKey'}" == ssh-* ]]; then
mkdir -p "${HOME}/.ssh"
chmod 0700 "${HOME}/.ssh"
SSH_RSYNC_KEY="command=\"/ssh-rsync-wrapper.sh\",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ${SSH_PUBLIC_KEY}"
echo "${SSH_RSYNC_KEY}" > "${HOME}/.ssh/authorized_keys"
ssh_rsync_key="command=\"/ssh-rsync-wrapper.sh\",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ${SSHD_PUBLIC_KEY}"
echo "${ssh_rsync_key}" > "${HOME}/.ssh/authorized_keys"
chmod 0600 "${HOME}/.ssh/authorized_keys"
fi

# Start SSHD daemon
exec /usr/sbin/sshd -D -f "${USER_ETC_DIR}"/sshd_config -e;;
*)
echo "ERROR: 'RSYNC_DAEMON' can only take one of the following values: 'rsyncd' (default), 'sshd";
echo "ERROR: 'RSYNCD_DAEMON' can only take one of the following values: 'rsyncd' (default), 'sshd";
exit 1;;
esac
5 changes: 2 additions & 3 deletions sshd_config
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ Port ${SSHD_PORT}
HostKey "${USER_ETC_DIR}"/ssh_host_rsa_key
HostKey "${USER_ETC_DIR}"/ssh_host_ecdsa_key
HostKey "${USER_ETC_DIR}"/ssh_host_ed25519_key
## Enable DEBUG log. You can ignore this but this may help you debug any issue while enabling SSHD for the first time
# LogLevel DEBUG3
LogLevel ${SSHD_LOG_LEVEL}
## Provide a path to store PID file which is accessible by normal user for write purpose
PidFile "${USER_RUN_DIR}"/sshd.pid

Expand All @@ -15,7 +14,7 @@ KbdInteractiveAuthentication no
PasswordAuthentication no
PermitRootLogin no
SyslogFacility AUTH
UsePAM yes
UsePAM no
X11Forwarding no
PrintMotd no
Subsystem sftp /usr/lib/openssh/sftp-server

0 comments on commit df46b7c

Please sign in to comment.