commit 9f3f15945e86a5e246d106c31cc51b613a3fc2d5
parent 6032076cd9074451a0ec0c061d9e9e81911932cc
Author: Matthias Jaros <jaros@mailbox.org>
Date: Mon, 20 Oct 2025 12:23:03 +0200
Security hardening
Diffstat:
7 files changed, 49 insertions(+), 19 deletions(-)
diff --git a/Dockerfile b/Dockerfile
@@ -9,9 +9,11 @@ COPY src/ssh.conf /etc/ssh/sshd_config.d/
COPY src/sudo-git /etc/sudoers.d/
# copy scrips
-COPY src/run /usr/local/bin/
+COPY src/env /usr/local/bin/
COPY src/init /usr/local/bin/
-RUN chmod 755 /usr/local/bin/run
+COPY src/run /usr/local/bin/
+RUN chmod 755 /usr/local/bin/env
RUN chmod 755 /usr/local/bin/init
+RUN chmod 755 /usr/local/bin/run
ENTRYPOINT ["/usr/local/bin/init"]
diff --git a/docker-compose.yml b/docker-compose.yml
@@ -10,7 +10,9 @@ services:
environment:
- GIT_UID=1000
- USER_handy=handy:ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPsl91WPAT8aWwZ6y5WAfXU9PoHzxJ3YG9uFgSmlGQr2HwV+gL/XaTBJ4Brj+pa+R7tfYEBMi+7Navx/ZsEmr9E= mj@xps15
+ - USER_yolo=yolo:ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPsl91WPAT8aWwZ6y5WAfXU9PoHzxJ3YG9uFgSmlGQr2HwV+gL/XaTBJ4Brj+pa+R7tfYEBMi+7Navx/ZsEmr9E= mj@xps15
- REPO_pass=/pass.git:handy
volumes:
- ./donotsync/ssh:/var/ssh
- ./donotsync/repos:/srv/repos
+ - ./donotsync/log:/var/log
diff --git a/src/env b/src/env
@@ -0,0 +1,4 @@
+set _REPO_PERMISSIONS_FILE /etc/repo-permissions
+set _REPO_VALIDATION_REGEX "((?:\/[a-zA-Z0-9_-]+)+.git)"
+set _GIT_VALIDATION_REGEX "^(git-(?:upload-pack|receive-pack|upload-archive)) '$_REPO_VALIDATION_REGEX'\$"
+set LOG /var/log/error.txt
diff --git a/src/init b/src/init
@@ -1,14 +1,14 @@
#!/usr/bin/env fish
+# load environment
+source (dirname (status --current-filename))/env
+
#
#
# function definitions
#
#
-set _REPO_PERMISSIONS_FILE /etc/repo-permissions
-set _REPO_VALIDATION_REGEX "^((?:\/[a-zA-Z-]+)+.git)\$"
-
function createUser
set -l userConfig (string split ':' $argv[1])
set -l user $userConfig[1]
@@ -37,9 +37,9 @@ function setupRepo
set -l repo $parsedConfig[1]
# check repo name
- set -l matcher (string match -r -g $_REPO_VALIDATION_REGEX $repo)
+ set -l matcher (string match -r -g "^$_REPO_VALIDATION_REGEX\$" $repo)
if test -z $matcher[1]
- echo "Invalid repo name $repo"
+ echo "Failed to setup repo, invalid path/name: $repo"
return 1
end
@@ -102,6 +102,7 @@ end
# git user has read/write access to all repos, set git-shell
# and no password login allowed -> no ssh login possible
adduser git -u $GIT_UID -D --shell "/usr/bin/git-shell"
+passwd -l git
for userConfig in $users
createUser "$userConfig"
end
@@ -112,6 +113,9 @@ for repoConfig in $repos
setupRepo "$repoConfig"
end
+# create writable log file
+touch $LOG && chmod 777 $LOG
+
echo "Setting up server"
# generate host keys in case
mkdir -p /var/ssh/etc/ssh/ && ssh-keygen -A -f /var/ssh
diff --git a/src/run b/src/run
@@ -1,25 +1,37 @@
#!/usr/bin/env fish
-set _REPO_PERMISSIONS_FILE /etc/repo-permissions
-# unify repo regex somehow
-set _GIT_VALIDATION_REGEX "^(git-(?:upload-pack|receive-pack|upload-archive)) '((?:\/[a-zA-Z-]+)+.git)'\$"
+# load environment
+source (dirname (status --current-filename))/env
# check given git command
-set -l matcher (string match -r -g $_GIT_VALIDATION_REGEX "$argv")
+set -l currentUser (whoami)
+set -l matcher (string match -r -g $_GIT_VALIDATION_REGEX -- "$argv")
if test (count $matcher) -ne 2
# there should be two groups otherwise something is wrong
+ echo "$(date -Is): DENY bad_format user=$currentUser ip=$SSH_CONNECTION argv=$argv" &>$LOG
exit 1
end
-# echo check for permissions
-set -l checkUser (whoami)
+# extract variables from git command
set -l gitCommand $matcher[1]
set -l repo $matcher[2]
+
# adjust repo path to /srv/repos
-set -l repoDir srv repos
-set -l repoDir /(string join -n '/' $repoDir (string split '/' $repo))
-cat $_REPO_PERMISSIONS_FILE | grep -q -E "^$repoDir:$checkUser\$"
-or exit 1;
+set -l repoDir /(string join -n '/' srv repos (string split '/' $repo))
+
+# check repo jail in /srv/repos
+if not string match -r -q -- "/srv/repos/.*" "(realpath $repoDir)"
+ # something is for sure wrong here
+ echo "$(date -Is): DENY jail_escape user=$currentUser ip=$SSH_CONNECTION argv=$argv" &>$LOG
+ exit 2
+end
+
+# check for permissions
+if not cat $_REPO_PERMISSIONS_FILE | grep -q -E "^$repoDir:$currentUser\$"
+ # something is for sure wrong here
+ echo "$(date -Is): DENY no_permissions user=$currentUser ip=$SSH_CONNECTION argv=$argv" &>$LOG
+ exit 1
+end
# execute parsed git command
/usr/bin/sudo -u git /usr/bin/git-shell -c "$gitCommand '$repoDir'"
diff --git a/src/ssh.conf b/src/ssh.conf
@@ -1,6 +1,10 @@
-# Security, do not allow any access to the git repos outside of allowed users
+# Security, we only want public key login for users and NOT for users root,git
PermitRootLogin no
PasswordAuthentication no
+PubkeyAuthentication yes
+AuthenticationMethods publickey
+KbdInteractiveAuthentication no
+ChallengeResponseAuthentication no
PermitTTY no
AllowAgentForwarding no
@@ -15,3 +19,6 @@ LogLevel INFO
# Force run script that checks for permissions and runs sudo
ForceCommand /usr/local/bin/run "$SSH_ORIGINAL_COMMAND"
+
+# git user has access to EVERYTHING. no login should be possible
+DenyUsers git
diff --git a/src/sudo-git b/src/sudo-git
@@ -1,2 +1 @@
-Defaults:pass !requiretty
ALL ALL=(git) NOPASSWD: /usr/bin/git-shell