diff --git a/contrib/rrsync/05-hostkeys.conf b/contrib/rrsync/05-hostkeys.conf new file mode 100644 index 00000000..a60cdfa9 --- /dev/null +++ b/contrib/rrsync/05-hostkeys.conf @@ -0,0 +1,6 @@ +# Host keys are generated at container start (see entrypoint.sh) into a +# dedicated directory rather than baked into the image or the default +# /etc/ssh location. +HostKey /etc/ssh/keys/ssh_host_rsa_key +HostKey /etc/ssh/keys/ssh_host_ecdsa_key +HostKey /etc/ssh/keys/ssh_host_ed25519_key diff --git a/contrib/rrsync/10-rsync.conf b/contrib/rrsync/10-rsync.conf new file mode 100644 index 00000000..9fee1bf8 --- /dev/null +++ b/contrib/rrsync/10-rsync.conf @@ -0,0 +1,6 @@ +# Restrict all SSH sessions to rsync-over-ssh; no interactive shell access. +ForceCommand /usr/bin/rrsync /data +PermitTTY no +X11Forwarding no +AllowTcpForwarding no +AllowAgentForwarding no diff --git a/contrib/rrsync/Dockerfile b/contrib/rrsync/Dockerfile new file mode 100644 index 00000000..b7674e18 --- /dev/null +++ b/contrib/rrsync/Dockerfile @@ -0,0 +1,21 @@ +FROM almalinux:9 + +LABEL maintainer="OSG Software " + +RUN --mount=type=cache,id=dnf-9,target=/var/cache/dnf,sharing=locked \ + dnf install -y openssh-server rsync-rrsync + +RUN mkdir /data + +RUN mkdir -p -m0755 /run/sshd && \ + mkdir -p -m0700 /root/.ssh && \ + mkdir -p -m0700 /etc/ssh/keys + +COPY --chown=root:root --chmod=0644 10-rsync.conf /etc/ssh/sshd_config.d/10-rsync.conf +COPY --chown=root:root --chmod=0644 05-hostkeys.conf /etc/ssh/sshd_config.d/05-hostkeys.conf +COPY --chown=root:root --chmod=0755 entrypoint.sh /entrypoint.sh + +CMD ["/entrypoint.sh"] + +EXPOSE 22/tcp +VOLUME /data diff --git a/contrib/rrsync/README.md b/contrib/rrsync/README.md new file mode 100644 index 00000000..0a0d614b --- /dev/null +++ b/contrib/rrsync/README.md @@ -0,0 +1,25 @@ +rsync-over-ssh sidecar +====================== + +Runs an sshd server intended to be deployed as a sidecar container in a +Kubernetes Pod, allowing external clients to write to a shared volume via +rsync over ssh. + +To permit login, volume-mount an `authorized_keys` file into +`/root/.ssh/authorized_keys`. +Mount the target data volume into `/data`. + +sshd is configured (see `10-rsync.conf`) to reject interactive shell +access: every session is forced through [`rrsync`](https://download.samba.org/pub/rsync/rrsync.1). +which restricts the client to rsync operations rooted at `/data` and +rejects anything else. + +Example usage: + +``` +docker run --detach --name rrsync \ + -v ~/authorized_keys:/root/.ssh/authorized_keys \ + -v ~/mydata:/data \ + -p2222:22 rrsync +rsync -e "ssh -p 2222" myfile.txt root@localhost:/ +``` diff --git a/contrib/rrsync/entrypoint.sh b/contrib/rrsync/entrypoint.sh new file mode 100644 index 00000000..10b1a0e7 --- /dev/null +++ b/contrib/rrsync/entrypoint.sh @@ -0,0 +1,12 @@ +#!/bin/sh +set -e + +KEY_DIR=/etc/ssh/keys + +if [ ! -f "$KEY_DIR/ssh_host_rsa_key" ]; then + for type in rsa ecdsa ed25519; do + ssh-keygen -q -t "$type" -f "$KEY_DIR/ssh_host_${type}_key" -N '' + done +fi + +exec /usr/sbin/sshd -D -e