From 9d9355a379f8a9922645ecd87b66f68acbb6bc89 Mon Sep 17 00:00:00 2001 From: Matthias Lucas Jaros Date: Mon, 20 Oct 2025 10:20:42 +0200 Subject: Moved files to src and renamed variables --- Dockerfile | 18 ++++----- init | 119 ----------------------------------------------------------- run | 23 ------------ src/init | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/run | 25 +++++++++++++ src/ssh.conf | 17 +++++++++ src/sudo-git | 2 + ssh.conf | 17 --------- sudo-git | 2 - 9 files changed, 172 insertions(+), 170 deletions(-) delete mode 100755 init delete mode 100755 run create mode 100755 src/init create mode 100755 src/run create mode 100644 src/ssh.conf create mode 100644 src/sudo-git delete mode 100644 ssh.conf delete mode 100644 sudo-git diff --git a/Dockerfile b/Dockerfile index 10e70d3..e773b1c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,17 +1,17 @@ -FROM alpine +FROM alpine:latest RUN apk add --no-cache openssh-server fish git sudo +# default uid for git user who has access to all repos ENV GIT_UID=1000 # Modified ssh conf with disabled root login and no password authentication -COPY ssh.conf /etc/ssh/sshd_config.d/ -COPY sudo-git /etc/sudoers.d/ +COPY src/ssh.conf /etc/ssh/sshd_config.d/ +COPY src/sudo-git /etc/sudoers.d/ -# required for permission check -COPY run /usr/local/bin/ -RUN chmod +x /usr/local/bin/run +# copy scrips +COPY src/run /usr/local/bin/ +COPY src/init /usr/local/bin/ +RUN chmod 755 /usr/local/bin/run +RUN chmod 755 /usr/local/bin/init -# required for starting -COPY init /usr/local/bin/ -RUN chmod +x /usr/local/bin/init ENTRYPOINT ["/usr/local/bin/init"] diff --git a/init b/init deleted file mode 100755 index 64ffd85..0000000 --- a/init +++ /dev/null @@ -1,119 +0,0 @@ -#!/usr/bin/env fish - -# -# -# function definitions -# -# - -set _REPO_PERMISSIONS /etc/repo-permissions -set _REPO_REGEX "^((?:\/[a-zA-Z-]+)+.git)\$" - -function createUser - set -l userConfig (string split ':' $argv[1]) - set -l user $userConfig[1] - set -l key $userConfig[2] - echo "Setting up user: $user" - if [ "$user" = git ] - echo "Error: User git is reserved" - return 1 - end - - set -l HOME "/home/$user" - # user is not restricted, this is done in ssh config with forceCommand - # we need to be able to run a fish script to check for permissions - adduser --home $HOME -D "$user" - # unlock account to allow ssh logins - passwd -u "$user" - mkdir "$HOME/.ssh" - echo "$key" > "$HOME/.ssh/authorized_keys" - chown -R $user "$HOME" - chmod -R 700 "$HOME" -end - -function setupRepo - set -l repoConfig $argv[1] - set -l parsedConfig (string split ':' $repoConfig) - set -l repo $parsedConfig[1] - - # check repo name - set -l matcher (string match -r -g $_REPO_REGEX $repo) - if test -z $matcher[1] - echo "Invalid repo name $repo" - return 1 - end - - # we assume all repos to be in /srv/repos - set -l repoDir srv repos - set repoDir /(string join -n '/' $repoDir (string split '/' $repo)) - echo "Setting up repo: $repo" - - # write user as allowed into permission file - for user in $parsedConfig[2..] - echo "$repoDir:$user" >> $_REPO_PERMISSIONS - end - - # setup repo dir - if not test -d $repoDir - mkdir -p $repoDir - git init --bare $repoDir -b trunk - end - chown -R git:git "$repoDir" - chmod -R 700 "$repoDir" -end - -# -# -# main -# -# - -argparse 'g/git-uid=?' 'u/user=+' 'r/repo=+' 'h/help' -- $argv -or exit 1; - -if set -q _flag_h - echo "Usage: $(status filename) [ OPTIONS ]..." - echo -e "" - echo -e "OPTIONS" - echo -e "\t -h, --help \t\t Display this page" - echo -e "\t -g, --git-uid \t\t UID of the git user that is used also as ownership for all repos" - echo -e "\t -u, --user \t\t User setting in form of :" - echo -e "\t -r, --repo \t\t Repo setting in form of :. You can add as many users as you want. Currently if a user is allowed he has all permissions read/write" - echo -e "" - return -end - -# read environment variables -set -l users $_flag_u -for user in (set -n | string match -r "^USER_\S+") - set users $users (eval echo \$$user) -end - -set -l repos $_flag_r -for repo in (set -n | string match -r "^REPO_\S+") - set repos $repos (eval echo \$$repo) -end - -if set -q $_flag_g - set GIT_UID $_flag_g -end - -# Setup users -# 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" -for userConfig in $users - createUser "$userConfig" -end - -# Setup repos -echo > $_REPO_PERMISSIONS -for repoConfig in $repos - setupRepo "$repoConfig" -end - -echo "Setting up server" -# generate host keys in case -mkdir -p /var/ssh/etc/ssh/ && ssh-keygen -A -f /var/ssh -# run ssh daemon -/usr/sbin/sshd -D -e diff --git a/run b/run deleted file mode 100755 index ec997ab..0000000 --- a/run +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/env fish - -set REPO_PERMISSIONS /etc/repo-permissions -set GIT_COMMAND_REGEX "^(git-(?:upload-pack|receive-pack|upload-archive)) '((?:\/[a-zA-Z-]+)+.git)'\$" - -# check given git command -set -l matcher (string match -r -g $GIT_COMMAND_REGEX "$argv") -if test (count $matcher) -ne 2 - # there should be two groups otherwise something is wrong - exit 1 -end - -# echo check for permissions -set -l checkUser (whoami) -set -l gitCommand $matcher[1] -set -l repo $matcher[2] -set -l repoDir srv repos -set -l repoDir /(string join -n '/' $repoDir (string split '/' $repo)) -cat $REPO_PERMISSIONS | grep -q -E "^$repoDir:$checkUser\$" -or exit 1; - -# run command -/usr/bin/sudo -u git /usr/bin/git-shell -c "$gitCommand '$repoDir'" diff --git a/src/init b/src/init new file mode 100755 index 0000000..61ab8a1 --- /dev/null +++ b/src/init @@ -0,0 +1,119 @@ +#!/usr/bin/env fish + +# +# +# 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] + set -l key $userConfig[2] + echo "Setting up user: $user" + if [ "$user" = git ] + echo "Error: User git is reserved" + return 1 + end + + set -l HOME "/home/$user" + # user is not restricted, this is done in ssh config with forceCommand + # we need to be able to run a fish script to check for permissions + adduser --home $HOME -D "$user" + # unlock account to allow ssh logins + passwd -u "$user" + mkdir "$HOME/.ssh" + echo "$key" > "$HOME/.ssh/authorized_keys" + chown -R $user "$HOME" + chmod -R 700 "$HOME" +end + +function setupRepo + set -l repoConfig $argv[1] + set -l parsedConfig (string split ':' $repoConfig) + set -l repo $parsedConfig[1] + + # check repo name + set -l matcher (string match -r -g $REPO_VALIDATION_REGEX $repo) + if test -z $matcher[1] + echo "Invalid repo name $repo" + return 1 + end + + # we assume all repos to be in /srv/repos + set -l repoDir srv repos + set repoDir /(string join -n '/' $repoDir (string split '/' $repo)) + echo "Setting up repo: $repo" + + # write user as allowed into permission file + for user in $parsedConfig[2..] + echo "$repoDir:$user" >> $REPO_PERMISSIONS_FILE + end + + # setup repo dir + if not test -d $repoDir + mkdir -p $repoDir + git init --bare $repoDir -b trunk + end + chown -R git:git "$repoDir" + chmod -R 700 "$repoDir" +end + +# +# +# main +# +# + +argparse 'g/git-uid=?' 'u/user=+' 'r/repo=+' 'h/help' -- $argv +or exit 1; + +if set -q _flag_h + echo "Usage: $(status filename) [ OPTIONS ]..." + echo -e "" + echo -e "OPTIONS" + echo -e "\t -h, --help \t\t Display this page" + echo -e "\t -g, --git-uid \t\t UID of the git user that is used also as ownership for all repos" + echo -e "\t -u, --user \t\t User setting in form of :" + echo -e "\t -r, --repo \t\t Repo setting in form of :. You can add as many users as you want. Currently if a user is allowed he has all permissions read/write" + echo -e "" + return +end + +# read environment variables +set -l users $_flag_u +for user in (set -n | string match -r "^USER_\S+") + set users $users (eval echo \$$user) +end + +set -l repos $_flag_r +for repo in (set -n | string match -r "^REPO_\S+") + set repos $repos (eval echo \$$repo) +end + +if set -q $_flag_g + set GIT_UID $_flag_g +end + +# Setup users +# 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" +for userConfig in $users + createUser "$userConfig" +end + +# Setup repos +echo > $REPO_PERMISSIONS_FILE +for repoConfig in $repos + setupRepo "$repoConfig" +end + +echo "Setting up server" +# generate host keys in case +mkdir -p /var/ssh/etc/ssh/ && ssh-keygen -A -f /var/ssh +# run ssh daemon +/usr/sbin/sshd -D -e diff --git a/src/run b/src/run new file mode 100755 index 0000000..a1ae7d5 --- /dev/null +++ b/src/run @@ -0,0 +1,25 @@ +#!/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)'\$" + +# check given git command +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 + exit 1 +end + +# echo check for permissions +set -l checkUser (whoami) +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; + +# 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 new file mode 100644 index 0000000..2940260 --- /dev/null +++ b/src/ssh.conf @@ -0,0 +1,17 @@ +# Security, do not allow any access to the git repos outside of allowed users +PermitRootLogin no +PasswordAuthentication no +PermitTTY no +AllowAgentForwarding no + +# Point keys to shared data dir +HostKey /var/ssh/etc/ssh/ssh_host_rsa_key +HostKey /var/ssh/etc/ssh/ssh_host_ecdsa_key +HostKey /var/ssh/etc/ssh/ssh_host_ed25519_key + +# Logging +SyslogFacility AUTH +LogLevel INFO + +# Force run script that checks for permissions and runs sudo +ForceCommand /usr/local/bin/run "$SSH_ORIGINAL_COMMAND" diff --git a/src/sudo-git b/src/sudo-git new file mode 100644 index 0000000..cd2f413 --- /dev/null +++ b/src/sudo-git @@ -0,0 +1,2 @@ +Defaults:pass !requiretty +ALL ALL=(git) NOPASSWD: /usr/bin/git-shell diff --git a/ssh.conf b/ssh.conf deleted file mode 100644 index 2940260..0000000 --- a/ssh.conf +++ /dev/null @@ -1,17 +0,0 @@ -# Security, do not allow any access to the git repos outside of allowed users -PermitRootLogin no -PasswordAuthentication no -PermitTTY no -AllowAgentForwarding no - -# Point keys to shared data dir -HostKey /var/ssh/etc/ssh/ssh_host_rsa_key -HostKey /var/ssh/etc/ssh/ssh_host_ecdsa_key -HostKey /var/ssh/etc/ssh/ssh_host_ed25519_key - -# Logging -SyslogFacility AUTH -LogLevel INFO - -# Force run script that checks for permissions and runs sudo -ForceCommand /usr/local/bin/run "$SSH_ORIGINAL_COMMAND" diff --git a/sudo-git b/sudo-git deleted file mode 100644 index cd2f413..0000000 --- a/sudo-git +++ /dev/null @@ -1,2 +0,0 @@ -Defaults:pass !requiretty -ALL ALL=(git) NOPASSWD: /usr/bin/git-shell -- cgit v1.3.1