From 416e87fa8ac5af50083e6d4b4ef9a46b58972ead Mon Sep 17 00:00:00 2001 From: Acrux Development Date: Sun, 25 Oct 2026 13:49:30 -0300 Subject: [PATCH] Enable SSH and no-login access to public repos --- gitea-host/install.sh | 31 ++++++++++++++++++++++++++++-- gitea-podman/setup-gitea-podman.sh | 21 ++++++++++++++++++-- 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/gitea-host/install.sh b/gitea-host/install.sh index af668b4..2e2e6a4 100755 --- a/gitea-host/install.sh +++ b/gitea-host/install.sh @@ -289,10 +289,27 @@ create_git_user() { fi # Use what the system really has (matters when the user already existed). - local entry + local entry configured_default + configured_default="$GITEA_HOME" # the script's own default/--env-var choice, before we overwrite it below entry="$(getent passwd "$GITEA_USER")" GITEA_HOME="$(cut -d: -f6 <<<"$entry")" GITEA_GROUP="$(id -gn "$GITEA_USER")" + + # A pre-existing 'git' account (made by some other package, a bare distro + # default, or an earlier partial install) commonly has NO real home + # directory: 'useradd --system' without --create-home still records a path + # in /etc/passwd but never creates it on disk. Left alone, every path this + # script builds from GITEA_HOME (repos, authorized_keys) lands wherever + # that missing path's nearest existing ancestor is -- for a bare, never- + # created path that resolves to the filesystem root. Fix it in place. + if [[ -z "$GITEA_HOME" || "$GITEA_HOME" == "/" || ! -d "$GITEA_HOME" ]]; then + warn "User '${GITEA_USER}' has no real home directory (passwd says '${GITEA_HOME:-}'); creating ${configured_default} and pointing the account at it." + mkdir -p -- "$configured_default" + chown "${GITEA_USER}:${GITEA_GROUP}" "$configured_default" + usermod --home "$configured_default" "$GITEA_USER" + GITEA_HOME="$configured_default" + fi + case "$(cut -d: -f7 <<<"$entry")" in */nologin|*/false|*/git-shell) warn "User '${GITEA_USER}' has a non-interactive login shell, so SSH pushes will fail. Fix: usermod -s /bin/bash ${GITEA_USER}" @@ -420,6 +437,10 @@ START_SSH_SERVER = false SSH_DOMAIN = ${GITEA_DOMAIN} SSH_PORT = ${GITEA_SSH_PORT} SSH_CREATE_AUTHORIZED_KEYS_FILE = true +; Show the SSH clone URL on a public repo's page to visitors who aren't +; signed in (an anonymous key still can't push or read a private repo -- +; this only affects whether the URL itself is displayed). +SSH_EXPOSE_ANONYMOUS = true LFS_START_SERVER = true LFS_JWT_SECRET = ${lfs_jwt_secret} @@ -444,7 +465,10 @@ JWT_SECRET = ${oauth2_jwt_secret} [service] DISABLE_REGISTRATION = ${GITEA_DISABLE_REGISTRATION} -REQUIRE_SIGNIN_VIEW = true +; false (GitHub-style): public repos can be browsed and cloned over HTTP(S) +; without signing in. Private repos still require auth either way -- this +; only affects whether the sign-in wall covers public content too. +REQUIRE_SIGNIN_VIEW = false DEFAULT_KEEP_EMAIL_PRIVATE = true DEFAULT_ALLOW_CREATE_ORGANIZATION = true @@ -452,6 +476,9 @@ DEFAULT_ALLOW_CREATE_ORGANIZATION = true MODE = console LEVEL = info ROOT_PATH = ${GITEA_WORK_DIR}/log +; Logs each SSH (git serv) connection -- who connected and which key/repo -- +; the SSH-side counterpart of the HTTP access log. +ENABLE_SSH_LOG = true EOF } diff --git a/gitea-podman/setup-gitea-podman.sh b/gitea-podman/setup-gitea-podman.sh index 8be7f3e..c14e292 100644 --- a/gitea-podman/setup-gitea-podman.sh +++ b/gitea-podman/setup-gitea-podman.sh @@ -373,6 +373,10 @@ SSH_DOMAIN = ${GITEA_DOMAIN} ; at a non-privileged port, mapped to the outside via the Quadlet unit's PublishPort. SSH_PORT = ${GITEA_SSH_PORT} SSH_LISTEN_PORT = ${SSH_LISTEN_PORT} +; Show the SSH clone URL on a public repo's page to visitors who aren't +; signed in (an anonymous key still can't push or read a private repo -- +; this only affects whether the URL itself is displayed). +SSH_EXPOSE_ANONYMOUS = true LFS_START_SERVER = true LFS_JWT_SECRET = ${lfs_jwt_secret} @@ -397,7 +401,10 @@ JWT_SECRET = ${oauth2_jwt_secret} [service] DISABLE_REGISTRATION = ${GITEA_DISABLE_REGISTRATION} -REQUIRE_SIGNIN_VIEW = true +; false (GitHub-style): public repos can be browsed and cloned over HTTP(S) +; without signing in. Private repos still require auth either way -- this +; only affects whether the sign-in wall covers public content too. +REQUIRE_SIGNIN_VIEW = false DEFAULT_KEEP_EMAIL_PRIVATE = true DEFAULT_ALLOW_CREATE_ORGANIZATION = true @@ -406,6 +413,9 @@ DEFAULT_ALLOW_CREATE_ORGANIZATION = true ; which keeps log rotation the host's job (journald) instead of ours. MODE = console LEVEL = info +; Logs each SSH connection to the built-in SSH server -- who connected and +; which key/repo -- the SSH-side counterpart of the HTTP access log. +ENABLE_SSH_LOG = true EOF } @@ -490,7 +500,14 @@ EOF start_service() { log "Starting ${UNIT_NAME}..." - systemctl enable "$UNIT_NAME" + # NOT 'systemctl enable': Quadlet units are transient/generated (they live + # under /run/systemd/generator/, regenerated from the .container file on + # every daemon-reload and boot), and systemd refuses to enable those -- + # "Failed to enable unit: Unit .../gitea.service is transient or generated". + # The generator itself already applies this file's [Install] section (the + # WantedBy=multi-user.target above) every time it regenerates the unit, + # which is what makes it come back up on the next boot -- no enable step + # needed, and none is possible. systemctl restart "$UNIT_NAME" }