Gitea behind reverse proxy using HTTPS

On my server I have dockerised traefik as reverse proxy (which also does TLS termination), and dockerised gitea. I can access gitea’s frontend successfully.

I want to use HTTPS (not SSH) for git actions.

But when I try to push from my local machine to the remote server I get:

$ git push -u origin master
Username for 'https://gitea.example.com': username
Password for 'https://gitea.example.com':
remote: Unauthorized
fatal: Authentication failed for 'https://gitea.example.com/username/test.git'

That’s weird because I use the same username/password to login to the frontend, without problems.

Does someone have a working example configuration for this? (docker + traefik/nginx/etc. + gitea + HTTPS)

Do you have 2FA enabled on your account? I think you need to create a personal access token and use that as a password for git clone.

Thanks.

Nope I don’t use 2FA. It’s a fresh install with nothing extra.

I just want HTTPS access instead of SSH. But it rejects all my git cli commands even though my user/pass is correct (I can use them to log in to the frontend).

Having the same issue. At first I was blaming the authentication provider I had setup with my Gitea instance, but after some more debugging it seems to also fail on local accounts.

Both for HTTP and HTTPS access through Traefik I get 401s, but when I access the Gitea isntance directly via its exposed port the clone works just fine.

Did anyone find a solution for this? I have the very same issue.

This is how I use Docker + nginx, no issues with HTTPS git:

  gitea:
    image: gitea/gitea:1.21.0
    restart: always
    environment:
      GITEA__database__DB_TYPE: postgres
      GITEA__database__HOST: database:5432
      GITEA__database__NAME: gitea
      GITEA__database__USER: gitea
      GITEA__database__PASSWD: ${DB_GITEA_PASSWORD}
    volumes:
      - /opt/gitea:/data
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "127.0.0.1:3000:3000"
      - "127.0.0.1:3022:22"
    depends_on:
      - database
    env_file:
      - .env.gitea

nginx config:

# https://docs.gitea.com/administration/reverse-proxies#nginx
server {
	include /etc/nginx/snippets/ssl.conf;

	listen 443 quic; # HTTP3
	listen 443 ssl;
	#listen [::]:443 quic; # HTTP3
	#listen [::]:443 ssl;
	server_name gitea.example.com;

	access_log /var/log/nginx/gitea.example.com.access.log main;

	# See: https://github.com/go-gitea/gitea/issues/13606
	# Prevent local authentication (it skips 2FA from IdP so not secure)
	location /user/login {
		return 301 /user/oauth2/SSO;
	}

	location / {
		client_max_body_size 512M;
		proxy_set_header X-Real-IP $remote_addr;
		proxy_set_header X-Forwarded-Proto $scheme;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_set_header Host $host;
		proxy_pass http://127.0.0.1:3000;
	}
}

Gitea config (secrets are in .env.gitea file provided by Docker):

APP_NAME = Gitea
RUN_MODE = prod
RUN_USER = git
WORK_PATH = /data/gitea

[actions]
ENABLED = true

[repository]
ROOT = /data/git/repositories

[repository.local]
LOCAL_COPY_PATH = /data/gitea/tmp/local-repo

[repository.upload]
TEMP_PATH = /data/gitea/uploads

[server]
APP_DATA_PATH = /data/gitea
DOMAIN = gitea.example.com
SSH_DOMAIN = gitea.example.com
HTTP_PORT = 3000
ROOT_URL = https://gitea.example.com/
DISABLE_SSH = false
SSH_PORT = 22
SSH_LISTEN_PORT = 22
LFS_START_SERVER = true
OFFLINE_MODE = true

[database]
SSL_MODE = disable

[indexer]
ISSUE_INDEXER_PATH = /data/gitea/indexers/issues.bleve

[session]
PROVIDER = db

[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
ROOT_PATH = /data/gitea/log

[security]
INSTALL_LOCK = true
REVERSE_PROXY_LIMIT = 1
REVERSE_PROXY_TRUSTED_PROXIES = *
PASSWORD_HASH_ALGO = argon2

[service]
DISABLE_REGISTRATION = true
REQUIRE_SIGNIN_VIEW = false
REGISTER_EMAIL_CONFIRM = false
ENABLE_NOTIFY_MAIL = false
ENABLE_BASIC_AUTHENTICATION = false
ALLOW_ONLY_EXTERNAL_REGISTRATION = false
ENABLE_CAPTCHA = false
DEFAULT_KEEP_EMAIL_PRIVATE = true
DEFAULT_ALLOW_CREATE_ORGANIZATION = false
DEFAULT_ENABLE_TIMETRACKING = true
NO_REPLY_ADDRESS = gitea.example.com

[lfs]
PATH = /data/git/lfs

[mailer]
ENABLED = false

[openid]
ENABLE_OPENID_SIGNIN = false
ENABLE_OPENID_SIGNUP = false

[oauth2_client]
ENABLE_AUTO_REGISTRATION = true
UPDATE_AVATAR = true
ACCOUNT_LINKING = auto
REGISTER_EMAIL_CONFIRM = false

[cron.update_checker]
ENABLED = false

[repository.pull-request]
DEFAULT_MERGE_STYLE = merge

[repository.signing]
DEFAULT_TRUST_MODEL = committer

[other]
SHOW_FOOTER_VERSION = false

Note that my configuration explicitly disables password auth for the API and HTTP git (and includes a workaround to prevent local login on web interface), so my users need to setup personal access tokens and login via SSO IdP.

1 Like