Skip to content

openssh s6 service enters tight infinite restart loop causing 600%+ CPU when /data/ssh keys have wrong ownership #36755

@YamadaHideki

Description

@YamadaHideki

Description

Bug Description
When SSH host keys in the /data/ssh volume are owned by root instead of
the gitea user, the container's openssh s6 service enters a tight infinite
restart loop causing sustained 600–700% CPU usage with ~950 log lines/minute.
Environment

  • Gitea version: 1.25.4 (gitea/gitea:1.25.4)
  • Deployment: Docker with bind-mount volume
  • Config: GITEA__server__START_SSH_SERVER=true
  • Host OS: Linux
    Steps to Reproduce
  1. Deploy gitea container with START_SSH_SERVER=true and a bind-mounted /data volume
  2. Cause SSH host keys to be owned by root:root on the host
    (e.g. keys were generated by a previous privileged operation, or manual intervention)
  3. Start the container
    Actual Behavior
    The openssh service's setup script (/etc/s6/openssh/setup) runs:
    chown root:root /data/ssh/* # fails: Operation not permitted
    chmod 0700 /data/ssh # fails: Operation not permitted
    chmod 0600 /data/ssh/* # fails: Operation not permitted
    Because chown/chmod fail silently (non-zero exit is ignored by source),
    sshd then starts but cannot load the host keys and exits immediately:
    Unable to load host key: /data/ssh/ssh_host_ed25519_key
    Unable to load host key: /data/ssh/ssh_host_rsa_key
    Unable to load host key: /data/ssh/ssh_host_ecdsa_key
    sshd: no hostkeys available -- exiting.
    The finish script exits with 0, so s6 restarts the service with no delay,
    creating an infinite tight loop.
    Resource impact measured:
  • Container CPU: 675% sustained (on 8-core host)
  • Log output: ~950 lines/minute
  • System load average: 8.3 (normally < 1)
    Expected Behavior
    When chown/chmod on SSH keys fail, the container should either:
  1. Exit with a clear error and not restart (or use exponential backoff), or
  2. Log a fatal error and gracefully disable the SSH service
    Root Cause
    In /etc/s6/openssh/setup, failures of chown/chmod are not checked.
    In /etc/s6/openssh/run, source ./setup discards the setup exit status.
    In /etc/s6/openssh/finish, exit 0 unconditionally allows immediate restart.

/etc/s6/openssh/run (current)

[[ -f ./setup ]] && source ./setup # setup failures ignored
exec su-exec root /usr/sbin/sshd -D -e 2>&1

/etc/s6/openssh/finish (current)

exit 0 # always restart
Suggested Fix
Option A — fail the setup script explicitly:

/etc/s6/openssh/setup

chown root:root /data/ssh/* || { echo "FATAL: cannot chown /data/ssh/"; exit 1; }
chmod 0700 /data/ssh || { echo "FATAL: cannot chmod /data/ssh"; exit 1; }
chmod 0600 /data/ssh/
|| { echo "FATAL: cannot chmod /data/ssh/*"; exit 1; }
And in /etc/s6/openssh/run, propagate setup failure:
[[ -f ./setup ]] && { source ./setup || exit 1; }
Option B — in the finish script, use s6's mechanism to prevent restart on
immediate exit (exit code 125 tells s6 not to restart):

/etc/s6/openssh/finish

$1 = exit code of the run script, $2 = signal

if [ "$1" -ne 0 ]; then
echo "openssh exited with code $1 — not restarting"
exit 125
fi
exit 0
Additional Context
The data volume files that triggered this issue:
/data/ssh/ssh_host_ecdsa_key root:root 600
/data/ssh/ssh_host_ed25519_key root:root 600
/data/ssh/ssh_host_rsa_key root:root 600
Container runs with USER_UID=3001 / USER_GID=3001, making chown root:root
impossible for the non-privileged process inside the container.
Workaround (host-side fix):
chown 3001:3001 /path/to/gitea/data/ssh/ssh_host_*
docker restart gitea

Gitea Version

1.25.4

Can you reproduce the bug on the Gitea demo site?

No

Log Gist

No response

Screenshots

No response

Git Version

No response

Operating System

debian 12

How are you running Gitea?

Installation Source

  • Used the official Docker image: gitea/gitea:1.25.4
  • Image pulled from Docker Hub (not self-built from source)
    How Gitea is Running
  • Running inside a Docker container via Docker Compose
  • Managed through Portainer
  • Relevant compose config:
    image: gitea/gitea:1.25.4
    environment:
    USER_UID: "3001"
    USER_GID: "3001"
    GITEA__server__START_SSH_SERVER: "true"
    volumes:
    • /mnt/debian/gitea:/data
      ports:
    • "2222:22"
    • "3000:3000"
  • Host OS: Linux (Debian-based)
  • Docker version: 20.10+

Database

None

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions