diff --git a/compose.yaml b/compose.yaml index 88b3ba25787f235326e5689c50d0e1668c48ad39..275787f24a03b71f445856650c6336c04fbfc3f3 100755 --- a/compose.yaml +++ b/compose.yaml @@ -152,7 +152,6 @@ services: image: code.forgejo.org/forgejo/forgejo:13 entrypoint: ["/bin/sh", "/custom/init/entry.sh"] ports: - - 40243:22 - 40244:3000 # port used for forgejo-runner environment: USER_UID: "$USER_ID" @@ -167,6 +166,7 @@ services: FORGEJO_OAUTH2_JWT_SECRET: "${FORGEJO_OAUTH2_JWT_SECRET:?}" FORGEJO_SECURITY_SECRET_KEY: "${FORGEJO_SECURITY_SECRET_KEY:?}" FORGEJO_SECURITY_INTERNAL_TOKEN: "${FORGEJO_SECURITY_INTERNAL_TOKEN:?}" + HOME_INFRA_HOST_DIR: "${HOME_INFRA_HOST_DIR:?}" restart: unless-stopped volumes: - "${APP_ROOT}/keycloak:/shared-keys:ro" @@ -590,7 +590,6 @@ services: image: code.forgejo.org/forgejo/forgejo:13 entrypoint: ["/bin/sh", "/custom/init/entry.sh"] ports: - - 22666:22 - 40666:3000 # port used for forgejo-runner environment: USER_UID: "$USER_ID" @@ -604,6 +603,7 @@ services: FORGEJO_SECURITY_SECRET_KEY: "${EVIL_FORGEJO_SECURITY_SECRET_KEY}" FORGEJO_SECURITY_INTERNAL_TOKEN: "${EVIL_FORGEJO_SECURITY_INTERNAL_TOKEN}" POSTGRES_PASSWORD_EVIL_FORGEJO: "${POSTGRES_PASSWORD_EVIL_FORGEJO:?}" + HOME_INFRA_HOST_DIR: "${HOME_INFRA_HOST_DIR:?}" restart: unless-stopped volumes: - "${APP_ROOT}/evil-infra/forgejo:/data:rw" diff --git a/config/evil-infra/forgejo/init/app.ini b/config/evil-infra/forgejo/init/app.ini index f4cad2fe47696215da94930dec98a470ef0eb3dd..551df234be852b40f0e3d7753a0105a2d707e445 100755 --- a/config/evil-infra/forgejo/init/app.ini +++ b/config/evil-infra/forgejo/init/app.ini @@ -31,13 +31,13 @@ DOMAIN=git.evil.inc SSH_DOMAIN=git.evil.inc HTTP_PORT=3000 ROOT_URL=https://git.evil.inc -DISABLE_SSH=false -SSH_PORT=22 -SSH_LISTEN_PORT=22 LFS_JWT_SECRET=$FORGEJO_SERVER_LFS_JWT_SECRET LFS_START_SERVER=true OFFLINE_MODE=true LANDING_PAGE=/evil +START_SSH_SERVER=false +SSH_CREATE_AUTHORIZED_KEYS_FILE=false +SSH_AUTHORIZED_KEYS_COMMAND_TEMPLATE=$HOME_INFRA_HOST_DIR/config/forgejo/ssh/route.sh {{.Key.ID}} [database] DB_TYPE=postgres diff --git a/config/forgejo/init/app.ini b/config/forgejo/init/app.ini index 00b52391831655b0908027e594659ad7fca3b44b..f39af2e828fc124b70fb01984958f144eb3e3c8e 100755 --- a/config/forgejo/init/app.ini +++ b/config/forgejo/init/app.ini @@ -32,13 +32,13 @@ DOMAIN=git.$HOME_DOMAIN SSH_DOMAIN=git.$HOME_DOMAIN HTTP_PORT=3000 ROOT_URL=https://git.$HOME_DOMAIN/ -DISABLE_SSH=false -SSH_PORT=22 -SSH_LISTEN_PORT=22 LFS_JWT_SECRET=$FORGEJO_SERVER_LFS_JWT_SECRET LFS_START_SERVER=true OFFLINE_MODE=true LANDING_PAGE=/clo +START_SSH_SERVER=false +SSH_CREATE_AUTHORIZED_KEYS_FILE=false +SSH_AUTHORIZED_KEYS_COMMAND_TEMPLATE=$HOME_INFRA_HOST_DIR/config/forgejo/ssh/route.sh {{.Key.ID}} [database] DB_TYPE=postgres diff --git a/config/forgejo/ssh/config b/config/forgejo/ssh/config new file mode 100644 index 0000000000000000000000000000000000000000..5141f1f67fe4a349fd9194fda5ac2ee2f9f1ab7c --- /dev/null +++ b/config/forgejo/ssh/config @@ -0,0 +1,3 @@ +Match User git + AuthorizedKeysCommand /bin/python /mnt/storage1/apps/home-infra/config/forgejo/ssh/keys.py %u %t %k + AuthorizedKeysCommandUser git diff --git a/config/forgejo/ssh/keys.py b/config/forgejo/ssh/keys.py new file mode 100755 index 0000000000000000000000000000000000000000..1844619485964bf7db80b5362c51f7288c8ef11d --- /dev/null +++ b/config/forgejo/ssh/keys.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python3 +import sys +import subprocess +import re + +user, key_type, key = sys.argv[1:4] + + +def get_key_id(container: str): + try: + result = subprocess.run( + [ + "sudo", + "/usr/bin/docker", + "exec", + "-u", + "3000:3000", + container, + "/usr/local/bin/forgejo", + "keys", + "-c", + "/custom/conf/app.ini", + "-e", + "git", + "-u", + user, + "-t", + key_type, + "-k", + key, + ], + capture_output=True, + text=True, + check=False, + ) + match = re.search(r"route\.sh (\d+)", result.stdout) + return match.group(1) if match else None + except: + return None + + +clover_id = get_key_id("forgejo") +evil_id = get_key_id("evil-forgejo") + +if not clover_id and not evil_id: + sys.exit(0) + +args: list[str] = [] +if clover_id: + args.extend(["--clover", clover_id]) +if evil_id: + args.extend(["--evil", evil_id]) + +cmd = "/mnt/storage1/apps/home-infra/config/forgejo/ssh/route.sh " + " ".join(args) +print( + f'command="{cmd}",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty,no-user-rc,restrict {key_type} {key}' +) diff --git a/config/forgejo/ssh/route.sh b/config/forgejo/ssh/route.sh new file mode 100755 index 0000000000000000000000000000000000000000..b830856b120eab173f32ccb8b3339b70735a7034 --- /dev/null +++ b/config/forgejo/ssh/route.sh @@ -0,0 +1,48 @@ +#!/bin/sh +clover_id="" +evil_id="" + +while [ $# -gt 0 ]; do + case "$1" in + --clover) + clover_id="$2" + shift 2 + ;; + --evil) + evil_id="$2" + shift 2 + ;; + *) shift ;; + esac +done + +repo="${SSH_ORIGINAL_COMMAND#* }" +repo="${repo%\'*}" +repo="${repo#\'}" +repo="${repo#/}" + +case "$repo" in +*[!a-zA-Z0-9/_.-]*) + echo "invalid repo name: $repo" >&2 + exit 1 + ;; +*..*) + echo "invalid repo name: $repo" >&2 + exit 1 + ;; +/*) + echo "invalid repo name: $repo" >&2 + exit 1 + ;; +esac + +if [ -d "/mnt/storage1/apps/forgejo/git/repositories/${repo}" ]; then + [ -z "$clover_id" ] && echo "ssh key is not configured for repository on git.paperclover.net" >&2 && exit 1 + exec sudo docker exec -i -u git forgejo /usr/bin/env SSH_ORIGINAL_COMMAND="$SSH_ORIGINAL_COMMAND" /usr/local/bin/forgejo --config=/custom/conf/app.ini serv key-"$clover_id" +elif [ -d "/mnt/storage1/apps/evil-infra/forgejo/git/repositories/${repo}" ]; then + [ -z "$evil_id" ] && echo "ssh key is not configured for repository on git.evil.inc" >&2 && exit 1 + exec sudo docker exec -i -u git evil-forgejo /usr/bin/env SSH_ORIGINAL_COMMAND="$SSH_ORIGINAL_COMMAND" /usr/local/bin/forgejo --config=/custom/conf/app.ini serv key-"$evil_id" +else + echo "repo not found" >&2 + exit 1 +fi diff --git a/docker.sh b/docker.sh new file mode 100644 index 0000000000000000000000000000000000000000..e5be42428c84ac2194c7b7556ceeccf368080718 --- /dev/null +++ b/docker.sh @@ -0,0 +1,2 @@ +#!/bin/sh +ssh clo@192.168.0.1 -- cd /mnt/storage1/apps/home-infra \&\& sudo docker "$@" diff --git a/generate-env.sh b/generate-env.sh index 1f42f0ee8ec0295cf0740ab6270f78856d0cd6d8..11c9a790fd76aa0233c26b7468d08228ef829aba 100644 --- a/generate-env.sh +++ b/generate-env.sh @@ -10,6 +10,7 @@ fi printf "generating...\n" template() { + add "HOME_INFRA_HOST_DIR" "$PWD" add "HOME_DOMAIN" "local.test" add "ADMIN_EMAIL" "" add "USER_ID" "$(id -u)" diff --git a/readme.md b/readme.md index 4ed47285b4b17297dee0fe61e4e7d74597f0bb64..b1569754950579066d66dcdd874b13566a0188ee 100644 --- a/readme.md +++ b/readme.md @@ -3,26 +3,6 @@ this codebase is used for all docker services on my home nas, including personal customization. -## usage - -``` -git clone https://git.paperclover.net/clo/home-infra.git -cd home-infra - -# setup repo -rm config/font/* -git clone https://git.paperclover.net/clo/sitegen.git -cp .env.example .env - -# fill secrets -vi .env -vi secrets/openvpn-credentials.txt - -docker compose up -d -``` - -## license - this repository is for example usage only. you may not re-host it in full, privately or publicly, but you may learn from my usage. please note that some components here are under licenses which do not permit redistribution.