【问题标题】:SSH not working using Gitea on docker with traefikSSH无法在带有traefik的docker上使用Gitea
【发布时间】:2021-05-26 07:44:19
【问题描述】:

我已经在 docker (docker-compose) 上安装了 gitea,并使用 traefik (v2.3) 作为反向代理。我正在尝试设置 ssh,但无论是 SSH 进入还是(主要)执行 git clone 和推送都失败了。

我明白了

<user>@<domain>: Permission denied (publickey).

我尝试在 docker-compose 文件中为 traefik 容器指定端口

ports:
  - "22:22"

在 docker-compose for gitea 我有以下标签:

  # SSH
  - "traefik.http.routers.gitea_ssh.rule=HOST(`gitea.localhost`)"
  - "traefik.http.routers.gitea_ssh.entrypoints=ssh"
  - "traefik.http.routers.gitea_ssh.service=gitea_ssh"
  # Services
  - "traefik.http.services.gitea_ssh.loadbalancer.server.port=22"

我对 http 和 https 有类似的设置,http 被重定向到 https。

入口点在 traefik.yml 中定义为":22"

但这不起作用。我认为信号流会是这样的:

ssh request -> server port 1234 -> docker port 22 -> traefik redirects -> gitea container port 22 

我已将公钥上传到

我通过此设置获得的 ssh 连接请求响应是:

<login on computer>:/ <user>$ ssh -v <address to gitea>
OpenSSH_8.1p1, LibreSSL 2.7.3
debug1: Reading configuration data /<Path to config>/config
debug1: /<Path to config>/config line 12: Applying options for <address to gitea>
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 47: Applying options for *
debug1: Connecting to <address to gitea> port 1234.
debug1: Connection established.
debug1: identity file /<Path to private key>/private-key type 0
debug1: identity file /<Path to private key>/private-key-cert type -1
debug1: Local version string SSH-2.0-OpenSSH_8.1
debug1: kex_exchange_identification: banner line 0: HTTP/1.1 400 Bad Request
debug1: kex_exchange_identification: banner line 1: Content-Type: text/plain; charset=utf-8
debug1: kex_exchange_identification: banner line 2: Connection: close
debug1: kex_exchange_identification: banner line 3: 
kex_exchange_identification: Connection closed by remote host

当我尝试访问 git clone 时:

<login on computer>:/ <user>$ git clone git@<address to gitea>:<path to repo>.git
Cloning into 'some-repo'...
kex_exchange_identification: Connection closed by remote host
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

【问题讨论】:

    标签: docker ssh docker-compose traefik gitea


    【解决方案1】:

    我没有通过 traefik 代理 ssh 的第一手经验,但我之前看过这篇文章:

    https://www.georglutz.de/blog/2020/06/20/homeassistant-with-traefik-and-ssh/

    推荐它是有意义的,因为它是相同的设置。

    我会指出你错误地使用了 http 路由器,你需要一个 tcp 路由器。

    我使用 Gitea,我建议只在不同的端口上公开 SSH; Traefik 只会给你开销。

    【讨论】:

      【解决方案2】:

      gitea ssh 在端口 222 上可用的示例,因为端口 22 用于主机 ssh。

      1. 为 traefik 创建一个名为 ssh 的入口点,用于端口 222
      2. 将端口配置添加到 traefik 容器 222:222/tcp(不需要 udp、sctp)
      3. 对于 gitea,您不需要公开端口
      4. 配置gitea,添加环境变量:
      # details: https://docs.gitea.io/en-us/config-cheat-sheet/#admin-admin
      # start gitea only ssh server, default use system which didn't work for me in any way
      GITEA__server__START_SSH_SERVER: "true"
      # this port is used in git clone, if not 22 this will add ssh:// to clone url which... i needed to remove everytime
      GITEA__server__SSH_PORT: 22
      # gitea ssh listen port
      GITEA__server__SSH_LISTEN_PORT: 222
      
      1. 为带有标签的 gitea 配置 traefik:
      # host resolving doesn't work for ssh, so you can only use "*"
      - "traefik.tcp.routers.gitea-ssh.rule=HostSNI(`*`)"
      - "traefik.tcp.routers.gitea-ssh.entrypoints=ssh"
      - "traefik.tcp.routers.gitea-ssh.service=gitea-ssh-svc"
      - "traefik.tcp.services.gitea-ssh-svc.loadbalancer.server.port=222"
      
      1. 将您的 ssh 密钥添加到您的帐户,检查其类型是否有效,最小位数也是如此。 https://docs.gitea.io/en-us/config-cheat-sheet/#ssh-minimum-key-sizes-sshminimum_key_sizes
      2. 创建一个名为 Example 的简单存储库
      3. 客户端更新 ~/.ssh/config:
      Host MyGiteaInstance
        HostName git.example.de
        IdentityFile ~/.ssh/gitea
        User username
        Port 222
      
      1. clone git@git.example.de:user/Example.git,对我来说,如果 url 中有端口信息或者有 ssh:// 之类的协议前缀,它就会失败

      调试提示:

      1. 检查 traefik 日志是否有找不到入口点等错误
      2. 使用详细的 ssh 进行克隆:GIT_SSH_COMMAND="ssh -v" git clone git@git.example.de:user/Example.git
      • 如果主机无法访问 -> 您这边的 ssh 端口错误或入口点未在 traefik 中设置
      • 主机真实性请求 = traefik 很好,客户端端口配置可能很好(多个 ssh 服务器)
      • 权限被拒绝 -> gitea 中的 ssh 服务器已启动,端口设置正确,检查 gitea 日志或 ssh 密钥未添加到用户

      如果我错过了上面的内容,请完成不是最小的示例:

      networks:
        proxy:
          external: false
          internal: true
        web:
          external: false
        gitea:
          external: false
          internal: true
      
      volumes:
        gitea:
        gitea_db:
      
      services:
        traefik:
          image: traefik:v2.5
          command: --api.insecure=true --providers.docker
          ports:
            # entrypoint http
            - "80:80"
            # entrypoint https
            - "443:443"
            # entrypoint ssh
            - "222:222/tcp"
            # todo maybe behind vpn?
            # - "8080:8080"
          # todo create docker.sock proxy
          volumes:
            - /var/run/docker.sock:/var/run/docker.sock:ro
            - ./traefik:/etc/traefik:ro
            - ./acme.json:/certs/acme.json
            - /etc/timezone:/etc/timezone:ro
            - /etc/localtime:/etc/localtime:ro
          networks: 
            - proxy
            - web
        
        watchtower:
          image: containrrr/watchtower:latest
          environment:
            WATCHTOWER_CLEANUP: "true"
            WATCHTOWER_REVIVE_STOPPED: "true"
          volumes:
            - /var/run/docker.sock:/var/run/docker.sock
            - /etc/timezone:/etc/timezone:ro
            - /etc/localtime:/etc/localtime:ro
          # disable for container?
          # LABEL com.centurylinklabs.watchtower.enable="false"
        
      
        gitea_db:
          image: postgres:14
          restart: unless-stopped
          environment:
            POSTGRES_USER: gitea
            POSTGRES_PASSWORD: ${GITEA_DB_PASSWD}
            POSTGRES_DB: gitea
          networks:
            - gitea
          volumes:
            - gitea_db:/var/lib/postgresql/data
            - /etc/timezone:/etc/timezone:ro
            - /etc/localtime:/etc/localtime:ro
      
        gitea:
          image: gitea/gitea:1.15
          depends_on:
            - gitea_db
          # https://docs.gitea.io/en-us/config-cheat-sheet/
          environment:
            USER_UID: 1000
            USER_GID: 1000
            # configuration:
            # some values are created from the documentation but untested, therefore uncommented
            # https://docs.gitea.io/en-us/config-cheat-sheet/#repository---local-repositorylocal
            ## default
            GITEA__default__RUN_MODE: prod
            GITEA__default__APP_NAME: "Gitea: Git with a cup of tea"
            ## database
            GITEA__database__DB_TYPE: postgres
            GITEA__database__HOST: gitea_db:5432
            GITEA__database__NAME: gitea
            GITEA__database__USER: gitea
            GITEA__database__PASSWD: ${GITEA_DB_PASSWD}
            ## server
            GITEA__server__DOMAIN: ${GITEA_DOMAIN}
            # ensuring unneccessary port isnt added
            GITEA__server__ROOT_URL: "https://%(DOMAIN)s"
            GITEA__server__HTTP_PORT: 80
            # if true SSH_LISTEN_PORT needs to be != 22
            GITEA__server__START_SSH_SERVER: "true"
            # SSH port in clone URL (needs to be 22 to remove ssh:// from clone url)
            GITEA__server__SSH_PORT: 22
            # disable forced ssh:// prefix of clone url
            GITEA__repository__USE_COMPAT_SSH_URI: "false"
            # SSH port for built-in SSH server (e.g. docker run ... -p SSH_PORT:LISTEN_PORT)
            GITEA__server__SSH_LISTEN_PORT: 222
            
            # mailer
            GITEA__mailer__ENABLED: "true"
            GITEA__mailer__HOST: "${GITEA_MAIL_HOST}"
            GITEA__mailer__FROM: "${GITEA_MAIL}"
            GITEA__mailer__USER: "${GITEA_MAIL}"
            # require email confirmation to register, enable email notifications
            # no effect: GITEA__server__REGISTER_EMAIL_CONFIRM: "true"
            # allows mails as notifications on updates
            # no effect: GITEA__server__ENABLE_NOTIFY_MAIL: "true"
            #
            # open-id sign
            GITEA__openid__ENABLE_OPENID_SIGNIN: "true"
            # disable self-registration
            GITEA__service__DISABLE_REGISTRATION: "true"
            # require sign in to view pages
            GITEA__service__REQUIRE_SIGNIN_VIEW: "true"
            # password hash argon2
            GITEA__security__PASSWORD_HASH_ALGO: "argon2"
            #
            # change default branch from master to x
            GITEA__repository__DEFAULT_BRANCH: "main"
            #
            # set manually during install, keys don't work for unknown reason:
            # Email Settings:
            # SMTP Password:
            # GITEA__mailer__PASSWD: "${GITEA_MAIL_PASSWORD}"
            # [x] Require Email Confirmation to Register
            # [x] Enable Email Notifications (to watch repos / issues aso.)
            #
            # set manually, no config option found:
            # Server and Third-Party Service Settings:
            # [x] Enable Local Mode (disable all third party content)
            #
            # Admin Account:
            # admin: ${GITEA_ADMIN_NAME}
            # pw: "${GITEA_MAIL_PASSWORD}"
            # mail: ${GITEA_MAIL}
            #
            # check configuration here:
            # https://${GITEA_DOMAIN}/admin/config
            # 
            # remember correct port isn't part of ssh clone url, but works with ~/.ssh/config
      
          restart: unless-stopped
          networks:
            - gitea
            - proxy
          volumes:
            - gitea:/data
            - /etc/timezone:/etc/timezone:ro
            - /etc/localtime:/etc/localtime:ro
          labels:
            - "traefik.enable=true"
            - "traefik.http.services.gitea.loadbalancer.server.port=80"
            - "traefik.http.routers.gitea_insecure.rule=Host(`${GITEA_DOMAIN}`)"
            - "traefik.http.routers.gitea_insecure.entrypoints=http"
            - "traefik.http.routers.gitea_insecure.middlewares=https-redirect@file"
            - "traefik.http.routers.gitea.rule=Host(`${GITEA_DOMAIN}`)"
            - "traefik.http.routers.gitea.entrypoints=https"
            - "traefik.http.routers.gitea.tls.certresolver=tlsChallenge"
      # https://community.traefik.io/t/routing-ssh-traffic-with-traefik-v2/717 
            # ssh cant be set on specific domain
            - "traefik.tcp.routers.gitea-ssh.rule=HostSNI(`*`)"
            - "traefik.tcp.routers.gitea-ssh.entrypoints=ssh"
            - "traefik.tcp.routers.gitea-ssh.service=gitea-ssh-svc"
            - "traefik.tcp.services.gitea-ssh-svc.loadbalancer.server.port=222"
      
      

      .env 文件:

      GITEA_DOMAIN=git.example.de
      GITEA_DB_PASSWD=securePassword
      GITEA_ADMIN_NAME=admin name
      GITEA_MAIL_PASSWORD=securePassword
      GITEA_MAIL_HOST=smtp.mymail.de:465
      GITEA_MAIL=yourEmail
      

      ./traefik/dynamic.yml

      http:
        middlewares:
          https-redirect:
            redirectScheme:
              scheme: https
      

      ./traefik/traefik.yml

      global:
        sendAnonymousUsage: false
      
      log:
        level: INFO
      
      entryPoints:
        http:
          address: :80
        https:
          address: :443
        ssh:
          address: :222
      
      defaultEntryPoints:
        - https
      
      api:
        insecure: true
        dashboard: true
      
      providers:
        docker:
          endpoint: unix:///var/run/docker.sock
          watch: true
          exposedByDefault: false
          network: shared_proxy
        file:
          filename: /etc/traefik/dynamic.yml
          watch: true
      
      certificatesResolvers:
        tlsChallenge:
          acme:
            email: MyEmailAdress
            storage: /certs/acme.json
            tlsChallenge: {}
            # https://doc.traefik.io/traefik/https/acme/#caserver
            # caServer: https://acme-staging-v02.api.letsencrypt.org/directory # For test certificates
      

      【讨论】:

        猜你喜欢
        • 2019-06-24
        • 2018-08-24
        • 1970-01-01
        • 1970-01-01
        • 2018-05-24
        • 2019-08-07
        • 1970-01-01
        • 2018-06-18
        • 1970-01-01
        相关资源
        最近更新 更多