Docker: Fix git sshd

This was completely bugged out. This commit fixes git, provides
two separate cgit servers for the different URL bases and also
supplies a smartgit service for $AURWEB_URL/repo.git interaction.

Docker image needs to be rebuilt with this change:

    $ docker build -t aurweb:latest .

Signed-off-by: Kevin Morris <kevr@0cost.org>
This commit is contained in:
Kevin Morris 2021-06-27 05:16:12 -07:00
parent 83f93c8dbb
commit 0a3aa40f20
14 changed files with 202 additions and 41 deletions

View file

@ -1,4 +1,6 @@
FROM archlinux:base-devel
ENV PYTHONPATH=/aurweb
ENV AUR_CONFIG=conf/config
# Setup some default system stuff.
RUN ln -sf /usr/share/zoneinfo/UTC /etc/localtime
@ -16,7 +18,7 @@ RUN pacman -Syu --noconfirm --noprogressbar \
python-pytest-asyncio python-coverage hypercorn python-bcrypt \
python-email-validator openssh python-lxml mariadb mariadb-libs \
python-isort flake8 cgit uwsgi uwsgi-plugin-cgi php php-fpm \
python-asgiref uvicorn
python-asgiref uvicorn python-pip python-wheel
RUN useradd -U -d /aurweb -c 'AUR User' aur
@ -25,6 +27,9 @@ COPY docker /docker
WORKDIR /aurweb
COPY . .
ENV PYTHONPATH=/aurweb
RUN make -C po all install
RUN pip3 install -t /aurweb/app --upgrade -I .
# Set permissions on directories and binaries.
RUN bash -c 'find /aurweb/app -type d -exec chmod 755 {} \;'
RUN chmod 755 /aurweb/app/bin/*

View file

@ -50,33 +50,77 @@ services:
image: aurweb:latest
init: true
environment:
- AUR_CONFIG=conf/config
- AUR_CONFIG=/aurweb/conf/config
entrypoint: /docker/git-entrypoint.sh
command: /docker/scripts/run-sshd.sh
ports:
- "2222:22"
- "2222:2222"
healthcheck:
test: "bash /docker/health/sshd.sh"
interval: 2s
timeout: 30s
depends_on:
mariadb:
condition: service_healthy
links:
- mariadb
volumes:
- mariadb_run:/var/run/mysqld
- mariadb_data:/var/lib/mysql
- git_data:/aurweb/aur.git
- ./cache:/cache
cgit:
smartgit:
image: aurweb:latest
init: true
environment:
- AUR_CONFIG=/aurweb/conf/config
entrypoint: /docker/smartgit-entrypoint.sh
command: /docker/scripts/run-smartgit.sh
healthcheck:
test: "bash /docker/health/smartgit.sh"
interval: 2s
timeout: 30s
depends_on:
mariadb:
condition: service_healthy
links:
- mariadb
volumes:
- mariadb_run:/var/run/mysqld
- mariadb_data:/var/lib/mysql
- git_data:/aurweb/aur.git
- ./cache:/cache
- smartgit_run:/var/run/smartgit
cgit-php:
image: aurweb:latest
init: true
environment:
- AUR_CONFIG=/aurweb/conf/config
entrypoint: /docker/cgit-entrypoint.sh
command: >-
uwsgi --socket 0.0.0.0:3000
--plugins cgi
--cgi /usr/share/webapps/cgit/cgit.cgi
command: /docker/scripts/run-cgit.sh 3000 "https://localhost:8443/cgit"
healthcheck:
test: "bash /docker/health/cgit.sh"
test: "bash /docker/health/cgit.sh 3000"
interval: 2s
timeout: 30s
depends_on:
git:
condition: service_healthy
links:
- git
volumes:
- git_data:/aurweb/aur.git
cgit-fastapi:
image: aurweb:latest
init: true
environment:
- AUR_CONFIG=/aurweb/conf/config
entrypoint: /docker/cgit-entrypoint.sh
command: /docker/scripts/run-cgit.sh 3000 "https://localhost:8444/cgit"
healthcheck:
test: "bash /docker/health/cgit.sh 3000"
interval: 2s
timeout: 30s
depends_on:
@ -170,14 +214,20 @@ services:
interval: 2s
timeout: 30s
depends_on:
cgit:
cgit-php:
condition: service_healthy
cgit-fastapi:
condition: service_healthy
smartgit:
condition: service_healthy
fastapi:
condition: service_healthy
php-fpm:
condition: service_healthy
links:
- cgit
- cgit-php
- cgit-fastapi
- smartgit
- fastapi
- php-fpm
volumes:
@ -187,6 +237,7 @@ services:
- ./web/html:/aurweb/web/html
- ./web/template:/aurweb/web/template
- ./web/lib:/aurweb/web/lib
- smartgit_run:/var/run/smartgit
sharness:
image: aurweb:latest
@ -298,3 +349,4 @@ volumes:
mariadb_run: {} # Share /var/run/mysqld/mysqld.sock
mariadb_data: {} # Share /var/lib/mysql
git_data: {} # Share aurweb/aur.git
smartgit_run: {}

View file

@ -1,13 +1,12 @@
#!/bin/bash
set -eou pipefail
cp -vf conf/cgitrc.proto /etc/cgitrc
mkdir -p /var/cache/cgit
sed -ri 's|clone-prefix=.*|clone-prefix=https://localhost:8443|' /etc/cgitrc
cp -vf conf/cgitrc.proto /etc/cgitrc
sed -ri "s|clone-prefix=.*|clone-prefix=${2}|" /etc/cgitrc
sed -ri 's|header=.*|header=/aurweb/web/template/cgit/header.html|' /etc/cgitrc
sed -ri 's|footer=.*|footer=/aurweb/web/template/cgit/footer.html|' /etc/cgitrc
sed -ri 's|repo\.path=.*|repo.path=/aurweb/aur.git|' /etc/cgitrc
mkdir -p /var/cache/cgit
exec "$@"

View file

@ -7,4 +7,7 @@ bash $dir/test-mysql-entrypoint.sh
sed -ri "s;^(aur_location) = .+;\1 = https://localhost:8444;" conf/config
sed -ri 's/^(name) = .+/\1 = aurweb/' conf/config
sed -ri "s|^(git_clone_uri_anon) = .+|\1 = https://localhost:8444/cgit/aur.git -b %s|" conf/config.defaults
sed -ri "s|^(git_clone_uri_priv) = .+|\1 = ssh://aur@localhost:2222/%s.git|" conf/config.defaults
exec "$@"

View file

@ -2,44 +2,91 @@
set -eou pipefail
SSHD_CONFIG=/etc/ssh/sshd_config
AUTH_SCRIPT=/aurweb/app/git-auth.sh
GIT_REPO=aur.git
GIT_KEY=/cache/git.key
GIT_REPO=/aurweb/aur.git
GIT_BRANCH=master # 'Master' branch.
# Setup SSH Keys.
ssh-keygen -A
if ! grep -q 'PYTHONPATH' /etc/environment; then
echo "PYTHONPATH='/aurweb:/aurweb/app'" >> /etc/environment
else
sed -ri "s|^(PYTHONPATH)=.*$|\1='/aurweb:/aurweb/app'|" /etc/environment
fi
if ! grep -q 'AUR_CONFIG' /etc/environment; then
echo "AUR_CONFIG='/aurweb/conf/config'" >> /etc/environment
else
sed -ri "s|^(AUR_CONFIG)=.*$|\1='/aurweb/conf/config'|" /etc/environment
fi
if ! grep -q '/aurweb/app/bin' /etc/environment; then
echo "PATH='/aurweb/app/bin:\${PATH}'" >> /etc/environment
fi
# Add AUR SSH config.
cat >> $SSHD_CONFIG << EOF
Match User aur
PasswordAuthentication no
AuthorizedKeysCommand /usr/local/bin/aurweb-git-auth "%t" "%k"
AuthorizedKeysCommand $AUTH_SCRIPT "%t" "%k"
AuthorizedKeysCommandUser aur
AcceptEnv AUR_OVERWRITE
SetEnv AUR_CONFIG=/aurweb/config/config
EOF
cat >> $AUTH_SCRIPT << EOF
#!/usr/bin/env bash
export PYTHONPATH="$PYTHONPATH"
export AUR_CONFIG="$AUR_CONFIG"
export PATH="/aurweb/app/bin:\${PATH}"
exec /aurweb/app/bin/aurweb-git-auth "\$@"
EOF
chmod 755 $AUTH_SCRIPT
DB_NAME="aurweb"
DB_HOST="mariadb"
DB_USER="aur"
DB_PASS="aur"
# Setup a config for our mysql db.
cp -vf conf/config.dev $AUR_CONFIG
sed -i "s;YOUR_AUR_ROOT;$(pwd);g" $AUR_CONFIG
sed -ri "s/^(name) = .+/\1 = ${DB_NAME}/" $AUR_CONFIG
sed -ri "s/^(host) = .+/\1 = ${DB_HOST}/" $AUR_CONFIG
sed -ri "s/^(user) = .+/\1 = ${DB_USER}/" $AUR_CONFIG
sed -ri "s/^;?(password) = .+/\1 = ${DB_PASS}/" $AUR_CONFIG
sed -i "s|/usr/local/bin|/aurweb/app/bin|g" $AUR_CONFIG
AUR_CONFIG_DEFAULTS="${AUR_CONFIG}.defaults"
if [[ "$AUR_CONFIG_DEFAULTS" != "/aurweb/conf/config.defaults" ]]; then
cp -vf conf/config.defaults $AUR_CONFIG_DEFAULTS
fi
# Set some defaults needed for pathing and ssh uris.
sed -i "s|/usr/local/bin|/aurweb/app/bin|g" $AUR_CONFIG_DEFAULTS
sed -ri "s|^(repo-path) = .+|\1 = /aurweb/aur.git/|" $AUR_CONFIG_DEFAULTS
ssh_cmdline='ssh ssh://aur@localhost:2222'
sed -ri "s|^(ssh-cmdline) = .+|\1 = $ssh_cmdline|" $AUR_CONFIG_DEFAULTS
# Setup SSH Keys.
ssh-keygen -A
# Taken from INSTALL.
mkdir -pv $GIT_REPO
# Initialize git repository.
if [ ! -f $GIT_REPO/config ]; then
curdir="$(pwd)"
cd $GIT_REPO
git config --global init.defaultBranch $GIT_BRANCH
git init --bare
git config --local transfer.hideRefs '^refs/'
git config --local --add transfer.hideRefs '!refs/'
git config --local --add transfer.hideRefs '!HEAD'
ln -sf /usr/local/bin/aurweb-git-update hooks/update
chown -R aur .
cd ..
ln -sf /aurweb/app/bin/aurweb-git-update hooks/update
cd $curdir
chown -R aur:aur $GIT_REPO
fi
if [ ! -f $GIT_KEY ]; then
# Create a DSA ssh private/pubkey at /cache/git.key{.pub,}.
ssh-keygen -f $GIT_KEY -t dsa -N '' -C 'AUR Git Key'
fi
# Users should modify these permissions on their local machines.
chmod 666 ${GIT_KEY}{.pub,}
exec "$@"

View file

@ -1,2 +1,2 @@
#!/bin/bash
exec printf "" >>/dev/tcp/127.0.0.1/3000
exec printf "" >>/dev/tcp/127.0.0.1/${1}

2
docker/health/smartgit.sh Executable file
View file

@ -0,0 +1,2 @@
#!/bin/bash
exec pgrep uwsgi

View file

@ -1,2 +1,5 @@
#!/bin/bash
exec printf "" >>/dev/tcp/127.0.0.1/22
# Opt to just pgrep sshd instead of connecting here. This health
# script is used on a regular interval and it ends up spamming
# the git service's logs with accesses.
exec pgrep sshd

View file

@ -45,8 +45,16 @@ http {
server fastapi:8000;
}
upstream cgit {
server cgit:3000;
upstream cgit-php {
server cgit-php:3000;
}
upstream cgit-fastapi {
server cgit-fastapi:3000;
}
upstream smartgit {
server unix:/var/run/smartgit/smartgit.sock;
}
server {
@ -59,12 +67,23 @@ http {
root /aurweb/web/html;
index index.php;
location ~ "^/([a-z0-9][a-z0-9.+_-]*?)(\.git)?/(git-(receive|upload)-pack|HEAD|info/refs|objects/(info/(http-)?alternates|packs)|[0-9a-f]{2}/[0-9a-f]{38}|pack/pack-[0-9a-f]{40}\.(pack|idx))$" {
include uwsgi_params;
uwsgi_pass smartgit;
uwsgi_modifier1 9;
uwsgi_param SCRIPT_FILENAME /usr/lib/git-core/git-http-backend;
uwsgi_param PATH_INFO /aur.git/\$3;
uwsgi_param GIT_HTTP_EXPORT_ALL "";
uwsgi_param GIT_NAMESPACE \$1;
uwsgi_param GIT_PROJECT_ROOT /aurweb;
}
location ~ ^/cgit {
include uwsgi_params;
rewrite ^/cgit/([^?/]+/[^?]*)?(?:\?(.*))?$ /cgit.cgi?url=\$1&\$2 last;
uwsgi_modifier1 9;
uwsgi_param CGIT_CONFIG /etc/cgitrc;
uwsgi_pass uwsgi://cgit;
uwsgi_pass uwsgi://cgit-php;
}
location ~ ^/[^/]+\.php($|/) {
@ -95,12 +114,23 @@ http {
try_files \$uri @proxy_to_app;
}
location ~ "^/([a-z0-9][a-z0-9.+_-]*?)(\.git)?/(git-(receive|upload)-pack|HEAD|info/refs|objects/(info/(http-)?alternates|packs)|[0-9a-f]{2}/[0-9a-f]{38}|pack/pack-[0-9a-f]{40}\.(pack|idx))$" {
include uwsgi_params;
uwsgi_pass smartgit;
uwsgi_modifier1 9;
uwsgi_param SCRIPT_FILENAME /usr/lib/git-core/git-http-backend;
uwsgi_param PATH_INFO /aur.git/\$3;
uwsgi_param GIT_HTTP_EXPORT_ALL "";
uwsgi_param GIT_NAMESPACE \$1;
uwsgi_param GIT_PROJECT_ROOT /aurweb;
}
location ~ ^/cgit {
include uwsgi_params;
rewrite ^/cgit/([^?/]+/[^?]*)?(?:\?(.*))?$ /cgit.cgi?url=\$1&\$2 last;
uwsgi_modifier1 9;
uwsgi_param CGIT_CONFIG /etc/cgitrc;
uwsgi_pass uwsgi://cgit;
uwsgi_pass uwsgi://cgit-fastapi;
}
location @proxy_to_app {

View file

@ -7,6 +7,9 @@ bash $dir/test-mysql-entrypoint.sh
sed -ri "s;^(aur_location) = .+;\1 = https://localhost:8443;" conf/config
sed -ri 's/^(name) = .+/\1 = aurweb/' conf/config
sed -ri "s|^(git_clone_uri_anon) = .+|\1 = https://localhost:8443/cgit/aur.git -b %s|" conf/config.defaults
sed -ri "s|^(git_clone_uri_priv) = .+|\1 = ssh://aur@localhost:2222/%s.git|" conf/config.defaults
sed -ri 's/^(listen).*/\1 = 0.0.0.0:9000/' /etc/php/php-fpm.d/www.conf
sed -ri 's/^;?(clear_env).*/\1 = no/' /etc/php/php-fpm.d/www.conf

4
docker/scripts/run-cgit.sh Executable file
View file

@ -0,0 +1,4 @@
#!/bin/bash
exec uwsgi --socket 0.0.0.0:${1} \
--plugins cgi \
--cgi /usr/share/webapps/cgit/cgit.cgi

9
docker/scripts/run-smartgit.sh Executable file
View file

@ -0,0 +1,9 @@
#!/bin/bash
exec uwsgi \
--socket /var/run/smartgit/smartgit.sock \
--uid root \
--gid http \
--chmod-socket=666 \
--plugins cgi \
--cgi /usr/lib/git-core/git-http-backend

View file

@ -1,2 +1,2 @@
#!/bin/bash
exec /usr/sbin/sshd -D
exec /usr/sbin/sshd -e -p 2222 -D

4
docker/smartgit-entrypoint.sh Executable file
View file

@ -0,0 +1,4 @@
#!/bin/bash
set -eou pipefail
exec "$@"