Browse Source

single-user openssh ssh server restricted to sftp

Fabian Peter Hammerle 3 years ago
commit
64da870f82
6 changed files with 184 additions and 0 deletions
  1. 12 0
      .github/dependabot.yml
  2. 37 0
      Dockerfile
  3. 34 0
      Makefile
  4. 40 0
      docker-compose.yml
  5. 23 0
      entrypoint.sh
  6. 38 0
      sshd_config

+ 12 - 0
.github/dependabot.yml

@@ -0,0 +1,12 @@
+# sync with https://github.com/fphammerle/docker-onion-service/blob/master/.github/dependabot.yml
+
+version: 2
+
+updates:
+- package-ecosystem: docker
+  directory: /
+  schedule:
+    interval: weekly
+    day: friday
+
+# https://docs.github.com/en/free-pro-team@latest/github/administering-a-repository/configuration-options-for-dependency-updates

+ 37 - 0
Dockerfile

@@ -0,0 +1,37 @@
+FROM docker.io/alpine:3.13.2
+
+ARG OPENSSH_SERVER_PACKAGE_VERSION=8.4_p1-r3
+ENV SSHD_HOST_KEYS_DIR=/etc/ssh/host_keys
+ENV CLIENT_USER=nonroot
+ENV CLIENT_HOME=/home/$CLIENT_USER
+ARG CHROOT_PATH=/data
+RUN apk add --no-cache \
+        openssh-server="$OPENSSH_SERVER_PACKAGE_VERSION" \
+        openssh-sftp-server="$OPENSSH_SERVER_PACKAGE_VERSION" \
+    && mkdir "$SSHD_HOST_KEYS_DIR" \
+    && adduser -S -h "$CLIENT_HOME" "$CLIENT_USER" \
+    && sed -i "s/^$CLIENT_USER:!:/$CLIENT_USER:*:/" /etc/shadow \
+    && mkdir "$CLIENT_HOME/.ssh" \
+    && chmod -c a+rX "$CLIENT_HOME/.ssh" \
+    && mkdir "$CHROOT_PATH" \
+    && chmod -c a+rX "$CHROOT_PATH"
+VOLUME $SSHD_HOST_KEYS_DIR
+VOLUME $CHROOT_PATH
+
+COPY sshd_config /etc/ssh/sshd_config
+EXPOSE 2200/tcp
+
+ENV SSH_CLIENT_PUBLIC_KEYS=
+COPY entrypoint.sh /
+ENTRYPOINT ["/entrypoint.sh"]
+
+# uid=0 required for ChrootDirectory option
+# https://unix.stackexchange.com/a/224329/155174
+USER 0
+CMD ["/usr/sbin/sshd", "-D", "-e"]
+
+# https://github.com/opencontainers/image-spec/blob/v1.0.1/annotations.md
+ARG REVISION=
+LABEL org.opencontainers.image.title="single-user openssh server restricted to sftp access" \
+    org.opencontainers.image.source="https://github.com/fphammerle/docker-sftpd" \
+    org.opencontainers.image.revision="$REVISION"

+ 34 - 0
Makefile

@@ -0,0 +1,34 @@
+# sync with https://github.com/fphammerle/docker-onion-service/blob/master/Makefile
+
+IMAGE_NAME = docker.io/fphammerle/sftpd
+PROJECT_VERSION = $(shell git describe --match=v* --abbrev=0 --dirty | sed -e 's/^v//')
+OPENSSH_SERVER_PACKAGE_VERSION := $(shell grep -Po 'OPENSSH_SERVER_PACKAGE_VERSION=\K.+' Dockerfile | tr -d _-)
+ARCH = $(shell arch)
+# architecture[arm_variant]
+# https://github.com/opencontainers/image-spec/blob/v1.0.1/image-index.md#image-index-property-descriptions
+IMAGE_TAG_ARCH_aarch64 = arm64
+IMAGE_TAG_ARCH_armv6l = armv6
+IMAGE_TAG_ARCH_armv7l = armv7
+IMAGE_TAG_ARCH_x86_64 = amd64
+IMAGE_TAG_ARCH = ${IMAGE_TAG_ARCH_${ARCH}}
+IMAGE_TAG = ${PROJECT_VERSION}-openssh${OPENSSH_SERVER_PACKAGE_VERSION}-${IMAGE_TAG_ARCH}
+BUILD_PARAMS = --tag="${IMAGE_NAME}:${IMAGE_TAG}" \
+	--build-arg=REVISION="$(shell git rev-parse HEAD)"
+
+.PHONY: worktree-clean docker-build podman-build docker-push
+
+worktree-clean:
+	git diff --exit-code
+	git diff --staged --exit-code
+
+docker-build: worktree-clean
+	sudo docker build ${BUILD_PARAMS} .
+
+podman-build: worktree-clean
+	# --format=oci (default) not fully supported by hub.docker.com
+	# https://github.com/docker/hub-feedback/issues/1871#issuecomment-748924149
+	podman build --format=docker ${BUILD_PARAMS} .
+
+docker-push: docker-build
+	sudo docker push "${IMAGE_NAME}:${IMAGE_TAG}"
+	@echo git tag --sign --message '$(shell sudo docker image inspect --format '{{join .RepoDigests "\n"}}' "${IMAGE_NAME}:${IMAGE_TAG}")' docker/${IMAGE_TAG} $(shell git rev-parse HEAD)

+ 40 - 0
docker-compose.yml

@@ -0,0 +1,40 @@
+version: '2.3'
+
+volumes:
+  ssh_host_keys:
+  data:
+
+services:
+  sshd:
+    build: .
+    image: docker.io/fphammerle/sftpd
+    container_name: sftpd
+    environment:
+      SSH_CLIENT_PUBLIC_KEYS: |
+        ssh-rsa ...
+        ssh-rsa ...
+    read_only: true
+    volumes:
+    - type: volume
+      source: ssh_host_keys
+      target: /etc/ssh/host_keys
+      read_only: false
+    - type: volume
+      source: data
+      target: /data
+      read_only: false
+    - type: tmpfs
+      target: /home/nonroot/.ssh # authorized_keys
+      tmpfs:
+        # nosuid,nodev,noexec added by default
+        size: 16k
+    ports:
+    - '127.0.0.1:2200:2200'
+    cap_drop: [ALL]
+    cap_add: [SETUID, SETGID, SYS_CHROOT]
+    security_opt: [no-new-privileges]
+    # docker-compose >=2.2,<3
+    cpus: 0.8
+    mem_limit: 64M
+
+# https://docs.docker.com/compose/compose-file/compose-file-v2/

+ 23 - 0
entrypoint.sh

@@ -0,0 +1,23 @@
+#!/bin/sh
+
+set -eu
+
+# sync with https://github.com/fphammerle/docker-gitolite/blob/master/entrypoint.sh
+if [ ! -f "$SSHD_HOST_KEYS_DIR/rsa" ]; then
+    ssh-keygen -t rsa -b 4096 -N '' -f "$SSHD_HOST_KEYS_DIR/rsa"
+fi
+if [ ! -f "$SSHD_HOST_KEYS_DIR/ed25519" ]; then
+    ssh-keygen -t ed25519 -N '' -f "$SSHD_HOST_KEYS_DIR/ed25519"
+fi
+unset SSHD_HOST_KEYS_DIR
+
+authorized_keys_path="$CLIENT_HOME/.ssh/authorized_keys"
+printenv SSH_CLIENT_PUBLIC_KEYS > "$authorized_keys_path"
+chmod a+r "$authorized_keys_path"
+unset SSH_CLIENT_PUBLIC_KEYS
+unset CLIENT_USER
+unset CLIENT_HOME
+
+set -x
+
+exec "$@"

+ 38 - 0
sshd_config

@@ -0,0 +1,38 @@
+# sync with https://github.com/fphammerle/docker-gitolite/blob/master/sshd_config
+
+LogLevel INFO
+#LogLevel DEBUG
+
+PidFile none
+
+Port 2200
+Protocol 2
+
+HostKey /etc/ssh/host_keys/rsa
+HostKey /etc/ssh/host_keys/ed25519
+
+# https://www.ssh-audit.com/hardening_guides.html#ubuntu_20_04_lts
+KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha256
+Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
+MACs hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,umac-128-etm@openssh.com
+HostKeyAlgorithms ssh-ed25519,ssh-ed25519-cert-v01@openssh.com,rsa-sha2-256,rsa-sha2-512,rsa-sha2-256-cert-v01@openssh.com,rsa-sha2-512-cert-v01@openssh.com
+
+#UsePAM no
+PermitRootLogin no
+PubkeyAuthentication yes
+PasswordAuthentication no
+ChallengeResponseAuthentication no
+StrictModes no
+
+AllowAgentForwarding no
+AllowTcpForwarding no
+GatewayPorts no
+PermitTunnel no
+X11Forwarding no
+PermitUserEnvironment no
+PrintMotd no
+PermitTTY no
+
+ChrootDirectory /data
+Subsystem sftp /usr/lib/openssh/sftp-server
+ForceCommand internal-sftp