From 94f60919e7c5b93876e8d102f59f8446a3696537 Mon Sep 17 00:00:00 2001 From: Orion Kindel Date: Thu, 18 May 2023 21:46:07 -0500 Subject: [PATCH] init --- .gitignore | 1 + src/000-entry.sh | 46 ++++++++++++++++++++++++++++++ src/010-apt.sh | 33 ++++++++++++++++++++++ src/020-users.sh | 38 +++++++++++++++++++++++++ src/021-user-gitea.sh | 42 +++++++++++++++++++++++++++ src/022-user-others.sh | 6 ++++ src/030-net.sh | 9 ++++++ src/031-routing.sh | 16 +++++++++++ src/040-gitea.sh | 28 ++++++++++++++++++ src/999-post.sh | 5 ++++ src/gitea-app.ini | 55 ++++++++++++++++++++++++++++++++++++ src/gitea-docker-compose.yml | 19 +++++++++++++ src/nginx.conf | 13 +++++++++ src/sshd_config | 20 +++++++++++++ 14 files changed, 331 insertions(+) create mode 100644 .gitignore create mode 100755 src/000-entry.sh create mode 100755 src/010-apt.sh create mode 100644 src/020-users.sh create mode 100644 src/021-user-gitea.sh create mode 100755 src/022-user-others.sh create mode 100755 src/030-net.sh create mode 100755 src/031-routing.sh create mode 100755 src/040-gitea.sh create mode 100644 src/999-post.sh create mode 100644 src/gitea-app.ini create mode 100644 src/gitea-docker-compose.yml create mode 100644 src/nginx.conf create mode 100644 src/sshd_config diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bdcc60e --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +ext diff --git a/src/000-entry.sh b/src/000-entry.sh new file mode 100755 index 0000000..faa57b0 --- /dev/null +++ b/src/000-entry.sh @@ -0,0 +1,46 @@ +#! /usr/bin/bash + +set -xo pipefail + +domain_root="${DOMAIN_ROOT:-orionkindel.com}" +subdomain_gitea="${SUBDOMAIN_GITEA:-git}" + +uid_git="${UID_GIT:-1000}" + +# NOTE: hard-coded in ./gitea-docker-compose.yml, ./nginx.conf +port_gitea_public="${PORT_GITEA:-8880}" +port_gitea_internal="${PORT_GITEA:-8881}" + +# Creates a login session for `user` (positional argument 1) in their home directory, +# and executes a bash command string (positional argument 2) as `user`. +# +# Differs from `su` in that the new session is entirely isolated from the current +# environment and allows using user-space session utils like systemctl. +# +# Currently uses `ssh $1@localhost` using `/root/.ssh/local_ed25519`, meaning user +# must have `/root/.ssh/local_ed25519.pub` in their `authorized_keys`. +# +# ```sh +# > doas orion "pwd" +# /home/orion/ +# > export FOO=bar +# > doas orion "echo $FOO" +# bar +# > doas orion "echo \$FOO" +# > doas orion "systemctl --user status docker" +# ... +# ``` +function doas { + ssh -F /dev/null -o IdentitiesOnly=yes -i /root/.ssh/local_ed25519 $1@localhost "set -xo pipefail; $2" +} + +rm /root/.ssh/local_ed25519 || true; +rm /root/.ssh/local_ed25519.pub || true; +ssh-keygen -t ed25519 -C "local" -f /root/.ssh/local_ed25519 -P '' + +source ./010-apt.sh +source ./020-users.sh +source ./030-net.sh +source ./031-routing.sh +source ./040-gitea.sh +source ./999-post.sh diff --git a/src/010-apt.sh b/src/010-apt.sh new file mode 100755 index 0000000..5ab0a47 --- /dev/null +++ b/src/010-apt.sh @@ -0,0 +1,33 @@ +#! /usr/bin/bash + +apt-get update -y +apt-get upgrade -y +apt-get install -fy \ + nginx \ + man \ + neovim \ + ca-certificates \ + gnupg \ + curl \ + wget \ + dbus-user-session \ + uidmap \ + ufw \ + certbot \ + python3-certbot-nginx \ + git \ + systemd-container \ + fuse-overlayfs \ + slirp4netns + +install -m 0755 -d /etc/apt/keyrings +rm /etc/apt/keyrings/docker.gpg || true; +curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg +chmod a+r /etc/apt/keyrings/docker.gpg +echo \ + "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \ + "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \ + tee /etc/apt/sources.list.d/docker.list > /dev/null + +apt-get update -y +apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin diff --git a/src/020-users.sh b/src/020-users.sh new file mode 100644 index 0000000..120afb3 --- /dev/null +++ b/src/020-users.sh @@ -0,0 +1,38 @@ +#! /usr/bin/bash + +function user_del_if_exist { + if id "$1" &>/dev/null; then + set +x + grp=`id -g $1` + # https://i.imgflip.com/3ggbcq.jpg + until userdel $1; do pkill -eU $1 || true; done; + set -x + groupdel $grp || true + rm -rf /home/$1 || true + fi +} + +function user_init { + loginctl enable-linger $1 + + rm -r /home/$1/.ssh || true + mkdir /home/$1/.ssh + chown $1:$1 /home/$1/.ssh + + cp /root/.ssh/local_ed25519.pub /home/$1/.ssh/authorized_keys + chown $1:$1 /home/$1/.ssh/authorized_keys + chmod 755 /home/$1/.ssh/authorized_keys + + doas $1 " + echo $2 >> ~/.ssh/authorized_keys; + echo \"export DOCKER_HOST=unix:///run/user/`id -u $1`/docker.sock\" > ~/.bashrc; + echo \"export PATH=/usr/bin:/usr/sbin:$PATH\" >> ~/.bashrc; + source ~/.bashrc; + dockerd-rootless-setuptool.sh install; + systemctl --user enable docker; + systemctl --user start docker; + " +} + +source ./021-user-gitea.sh +source ./022-user-others.sh diff --git a/src/021-user-gitea.sh b/src/021-user-gitea.sh new file mode 100644 index 0000000..c346538 --- /dev/null +++ b/src/021-user-gitea.sh @@ -0,0 +1,42 @@ +#! /usr/bin/bash + +## backup gitea data to /tmp +mkdir -p /tmp/git +if id git &>/dev/null; then + mkdir -p /tmp/git + mv /home/git/data /tmp/git/data + mv /home/git/config /tmp/git/config +else + mkdir /tmp/git + mkdir /tmp/git/data + mkdir /tmp/git/data/git + mkdir /tmp/git/config +fi + +## delete and recreate `git` user +user_del_if_exist git + +echo $uid_git +groupadd --gid $uid_git git +useradd \ + --gid $uid_git \ + --uid $uid_git \ + --create-home \ + --shell /bin/bash \ + git + +read -p 'enter public ssh key allowing sessions as `git`:' git_ssh_pub +user_init git $git_ssh_pub + +## restore homedir +mv /tmp/git/data /home/git/ +mv /tmp/git/config /home/git/ + +cp ./gitea-docker-compose.yml /home/git/docker-compose.yml +cp ./gitea-app.ini /home/git/config/app.ini + +chown -R git:git /home/git + +## docker user perms +chown -R 1000:1000 /home/git/data +chown -R 1000:1000 /home/git/config diff --git a/src/022-user-others.sh b/src/022-user-others.sh new file mode 100755 index 0000000..02200f7 --- /dev/null +++ b/src/022-user-others.sh @@ -0,0 +1,6 @@ +#! /usr/bin/bash + +user_del_if_exist orion +useradd --create-home --shell /bin/bash orion +read -p 'enter public ssh key allowing sessions as `orion`:' orion_ssh_pub +user_init orion $orion_ssh_pub diff --git a/src/030-net.sh b/src/030-net.sh new file mode 100755 index 0000000..89ab99a --- /dev/null +++ b/src/030-net.sh @@ -0,0 +1,9 @@ +#! /usr/bin/bash + +ufw default deny incoming +ufw default allow outgoing +ufw status verbose +ufw allow ssh +ufw allow 'Nginx Full' +ufw allow 8880/tcp +ufw --force enable diff --git a/src/031-routing.sh b/src/031-routing.sh new file mode 100755 index 0000000..4ac6ddf --- /dev/null +++ b/src/031-routing.sh @@ -0,0 +1,16 @@ +#! /usr/bin/bash + +mkdir -p /etc/nginx/sites-available +mkdir -p /etc/nginx/sites-enabled + +rm -r /etc/nginx/sites-available/$domain_root 2>/dev/null || true +rm -r /etc/nginx/sites-enabled/$domain_root 2>/dev/null || true + +touch /etc/nginx/sites-available/$domain_root +ln -s /etc/nginx/sites-available/$domain_root /etc/nginx/sites-enabled/$domain_root + +cp ./nginx.conf /etc/nginx/sites-available/$domain_root +chmod 777 /etc/nginx/sites-available/$domain_root + +systemctl enable nginx +systemctl start nginx diff --git a/src/040-gitea.sh b/src/040-gitea.sh new file mode 100755 index 0000000..a66a233 --- /dev/null +++ b/src/040-gitea.sh @@ -0,0 +1,28 @@ +#! /usr/bin/bash + +doas git " +docker container ls -q | xargs -I{} docker container stop {}; +docker container ls -aq | xargs -I{} docker container rm -f {}; + +docker compose pull; +docker compose up -d; +" + +## SSH Passthrough +## https://docs.gitea.io/en-us/installation/install-with-docker-rootless/#ssh-container-passthrough +## +## Note: 999-post.sh restarts adds a rule to sshd_config and restarts sshd, which +## is required for SSH passthrough to start working. +rm /usr/local/bin/gitea-shell || true; + +cat << "EOF" >> /usr/local/bin/gitea-shell +#!/bin/sh +/usr/bin/docker context use rootless +/usr/bin/docker exec -i \ + --env SSH_ORIGINAL_COMMAND="$SSH_ORIGINAL_COMMAND" \ + gitea \ + sh "$@" +EOF + +chmod +x /usr/local/bin/gitea-shell +usermod -s /usr/local/bin/gitea-shell git diff --git a/src/999-post.sh b/src/999-post.sh new file mode 100644 index 0000000..79df93d --- /dev/null +++ b/src/999-post.sh @@ -0,0 +1,5 @@ +#! /usr/bin/bash + +# https://docs.gitea.io/en-us/installation/install-with-docker-rootless/#ssh-container-passthrough +cp ./sshd_config /etc/ssh/sshd_config +systemctl restart sshd diff --git a/src/gitea-app.ini b/src/gitea-app.ini new file mode 100644 index 0000000..3790f36 --- /dev/null +++ b/src/gitea-app.ini @@ -0,0 +1,55 @@ +; https://github.com/go-gitea/gitea/blob/main/custom/conf/app.example.ini + +APP_NAME = git@orionkindel.com +RUN_MODE = prod + +[server] +DOMAIN = localhost +SSH_DOMAIN = localhost +HTTP_PORT = 3000 +ROOT_URL = git.orionkindel.com +DISABLE_SSH = false +SSH_PORT = 22 +SSH_LISTEN_PORT = 22 +LFS_START_SERVER = false + +[database] +PATH = /data/gitea/gitea.db +DB_TYPE = sqlite3 +HOST = localhost:3306 +NAME = gitea +USER = root +PASSWD = +LOG_SQL = false + +[indexer] +ISSUE_INDEXER_PATH = /data/gitea/indexers/issues.bleve + +[session] +PROVIDER_CONFIG = /data/gitea/sessions + +[picture] +AVATAR_UPLOAD_PATH = /data/gitea/avatars +REPOSITORY_AVATAR_UPLOAD_PATH = /data/gitea/repo-avatars + +[attachment] +PATH = /data/gitea/attachments + +[log] +MODE = console +LEVEL = info +ROUTER = console +ROOT_PATH = /data/gitea/log + +[security] +INSTALL_LOCK = false +SECRET_KEY = +REVERSE_PROXY_LIMIT = 1 +REVERSE_PROXY_TRUSTED_PROXIES = * + +[service] +DISABLE_REGISTRATION = false +REQUIRE_SIGNIN_VIEW = false + +[lfs] +PATH = /data/git/lfs diff --git a/src/gitea-docker-compose.yml b/src/gitea-docker-compose.yml new file mode 100644 index 0000000..0e12714 --- /dev/null +++ b/src/gitea-docker-compose.yml @@ -0,0 +1,19 @@ +version: "3" + +name: gitea_compose + +services: + server: + image: gitea/gitea:dev-rootless + container_name: gitea + user: "1000" + restart: always + volumes: + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + - /home/git/data/:/var/lib/gitea/data + - /home/git/git/:/var/lib/gitea/git + - /home/git/config/:/etc/gitea + ports: + - "8881:3000" + - "127.0.0.1:2222:22" diff --git a/src/nginx.conf b/src/nginx.conf new file mode 100644 index 0000000..29ccf15 --- /dev/null +++ b/src/nginx.conf @@ -0,0 +1,13 @@ +server { + listen 80; + server_name git.orionkindel.com; + + location / { + client_max_body_size 512M; + proxy_pass http://localhost:8881; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } +} diff --git a/src/sshd_config b/src/sshd_config new file mode 100644 index 0000000..84dd537 --- /dev/null +++ b/src/sshd_config @@ -0,0 +1,20 @@ +# $OpenBSD: sshd_config,v 1.103 2018/04/09 20:41:22 tj Exp $ + +Include /etc/ssh/sshd_config.d/*.conf + +ChallengeResponseAuthentication no + +UsePAM yes + +X11Forwarding yes +PrintMotd no + +AcceptEnv LANG LC_* + +Subsystem sftp /usr/lib/openssh/sftp-server + +PasswordAuthentication no + +Match User git + AuthorizedKeysCommandUser git + AuthorizedKeysCommand /usr/bin/docker exec -i gitea /usr/local/bin/gitea keys -e git -u %u -t %t -k %k