summaryrefslogtreecommitdiff
path: root/ssh
diff options
context:
space:
mode:
Diffstat (limited to 'ssh')
-rw-r--r--ssh/Dockerfile13
-rwxr-xr-xssh/entrypoint.sh20
-rwxr-xr-xssh/git-ns25
3 files changed, 58 insertions, 0 deletions
diff --git a/ssh/Dockerfile b/ssh/Dockerfile
new file mode 100644
index 0000000..13367b6
--- /dev/null
+++ b/ssh/Dockerfile
@@ -0,0 +1,13 @@
+# sshd для git-доступа по ключам. Ключи и authorized_keys приезжают из volume /keys (пишет бот).
+FROM debian:bookworm-slim
+RUN apt-get update && apt-get install -y --no-install-recommends openssh-server git \
+ && rm -rf /var/lib/apt/lists/* \
+ && useradd -m -d /home/git -s /bin/sh git \
+ && mkdir -p /home/git/.ssh /run/sshd
+COPY git-ns /usr/local/bin/git-ns
+COPY entrypoint.sh /entrypoint.sh
+RUN chmod +x /usr/local/bin/git-ns /entrypoint.sh
+EXPOSE 22
+VOLUME /repos
+VOLUME /keys
+ENTRYPOINT ["/entrypoint.sh"]
diff --git a/ssh/entrypoint.sh b/ssh/entrypoint.sh
new file mode 100755
index 0000000..c255adf
--- /dev/null
+++ b/ssh/entrypoint.sh
@@ -0,0 +1,20 @@
+#!/bin/sh
+set -e
+mkdir -p /repos /keys /home/git/.ssh /run/sshd
+touch /keys/authorized_keys
+chown -R git:git /home/git/.ssh 2>/dev/null || true
+chmod 700 /home/git/.ssh
+ssh-keygen -A
+cat > /etc/ssh/sshd_config <<EOF
+Port 22
+PermitRootLogin no
+PasswordAuthentication no
+PubkeyAuthentication yes
+AllowUsers git
+AuthorizedKeysFile /keys/authorized_keys
+X11Forwarding no
+AllowTcpForwarding no
+AllowAgentForwarding no
+EOF
+echo "sshd up · authorized_keys=/keys/authorized_keys (пишет бот)"
+exec /usr/sbin/sshd -D -e
diff --git a/ssh/git-ns b/ssh/git-ns
new file mode 100755
index 0000000..f8b6b0b
--- /dev/null
+++ b/ssh/git-ns
@@ -0,0 +1,25 @@
+#!/bin/sh
+# Форс-команда из authorized_keys: command="git-ns <namespace>".
+# Пускает пользователя только в git-операции над репозиториями ЕГО неймспейса.
+NS="$1"
+REPOS="${REPOS_DIR:-/repos}"
+set -- $SSH_ORIGINAL_COMMAND
+cmd="$1"
+repo=$(printf '%s' "$2" | tr -d "'\"")
+repo="${repo#/}"
+case "$cmd" in
+ git-receive-pack|git-upload-pack|git-upload-archive) ;;
+ *) echo "разрешены только git-команды" >&2; exit 1 ;;
+esac
+# без слеша -> свой неймспейс
+case "$repo" in
+ */*) ;;
+ *) repo="$NS/$repo" ;;
+esac
+# запрет выхода в чужой неймспейс
+case "$repo" in
+ "$NS/"*) ;;
+ *) echo "чужой неймспейс запрещён" >&2; exit 1 ;;
+esac
+repo="${repo%/}"
+exec git-shell -c "$cmd '$REPOS/$repo'"