Docker GitLab:从GUI复制和粘贴链接,Web资源,证书和实际端口中解耦GitLab“外部URL”和“ssh端口”

时间:2016-05-08 10:27:05

标签: apache https docker gitlab

请注意,此问题涉及个人使用专用服务器,而非专业服务器。

我想在同一台机器上运行两个GitLab Docker Containers,它们有两个不同的卷,其中两个在主机的端口443上“可用”。 http内容的端口80不可用。主机的HTTP不是3xx重定向,它将是使用HSTS的网页。主机上的SSH端口将类似于1 07 03和1 08 03。

网址将为 https://gitlab.example.com https://sources.example.com 。证书由主机上的Let's Encrypt维护。

内容将由Apache使用mod_proxy和虚拟主机提供。 Apache不在Docker中运行。启用的其他虚拟主机与GitLab无关。为了简化证书,我试图不将证书放在gitlab中。相反,Apache配置包含证书。

现在问题来了。

  • 如果我将https://gitlab.example.com指定为external_url:

    • https将启用。 gitlab甚至会拒绝启动,因为缺少证书。正如我所说我正在使用mod_proxy,我不需要证书,因为Apache已经完成了所有的工作。我希望GitLab能够在Apache本地提供不安全的内容,这样就可以让Apache通过不受信任的网络实现安全。
  • 如果我将http://gitlab.example.com指定为external_url并让Apache转发到http://127.0.0.1:10701,即Docker Container上的端口80:

    • 几乎所有gitlab网络资源都将通过http://gitlab.example.com提供,导致浏览器指示网站实际上不安全,这是可以理解的。
    • 克隆gitlab存储库的复制和粘贴链接将为http://gitlab.example.com/group/something.git,导致克隆链接失败,因为它不是https。
  • SSH从主机的端口10703转发。在Docker Container中,它在端口22上运行。当前的SSH克隆复制和粘贴链接仍为git@gitlab.example.com:group/something.git。我希望它是ssh://git@gitlab.example.com:10703/group/something.git(请参阅answer about cloning on other ports

我的X问题是:

  • 在主机的标准https端口上安全地提供GitLab Web界面(443)。

  • 保留Web界面内容的复制和粘贴链接的可用性,同时不影响安全性。

  • 约束:不得替换Apache。

我目前的Y理想解决方案是:

  • 我想强烈地将GitLab的配置 intent 分离。目前,当我将外部URL配置为https时,它会识别要提供安全内容的意图,这需要证书。事实上,我只想改变外部URL。同样处理SSH,从容器的角度来看,从实际网络端口单独显示外部显示端口(用于复制和粘贴链接)。也许有一个配置允许这个。

我目前的Y快速而肮脏的解决方案是:

  • 使用https:// ...作为外部网址,并将占位符证书文件添加到/etc/gitlab/ssl/。 GitLab将完全忽略这些证书,但只要它们存在于文件系统中,GitLab就能够启动,主机将能够提供安全内容。 如果有更好的选择,我想避免这样做。

  • 要解决SSH问题,也许我可以添加gitlab_rails['gitlab_shell_ssh_port'] = 10703(请参阅answer about changing SSH port,然后使用docker run --publish 10703:10703 ...代替当前的工作方式docker run --publish 10703:22 ...)。 编辑:事实证明,gitlab_rails['gitlab_shell_ssh_port']仅更改显示的端口。由于它是管理端口22而不是gitlab的sshd,docker run --publish 10703:10703 ...将导致主机上的端口10703被转发到容器上的端口10703,该容器已关闭。 docker run --publish 10703:22 ... + gitlab_rails['gitlab_shell_ssh_port'] = 10703是应该如何做的。

我该如何解决这个问题?我们赞赏优雅,快捷和肮脏的方式。

1 个答案:

答案 0 :(得分:2)

4个月后,我将以一种不回答原始问题的方式回答我的问题,但提供我迄今为止如何设法执行我想要的,对于任何可能绊倒这个问题的读者。< / p>

我刚才这样做了,所以这个答案的内容可能不正确,也可能是不好的做法,但我不知道。

请记住此问题与个人使用专用服务器有关,而非专业

容器配置

无保证此配置足以拥有一个可保存数据的可移动容器。使用此风险需要您自担风险。

这是我的泊坞窗运行命令:

docker create \
    --name example-gitlab \
    --restart=unless-stopped \
    --hostname gitlab.example.com \
    --publish 2222:22 \
    --env GITLAB_OMNIBUS_CONFIG="external_url 'https://gitlab.example.com/'; gitlab_rails['gitlab_signup_enabled'] = false; gitlab_rails['gitlab_shell_ssh_port'] = 2222; nginx['real_ip_trusted_addresses'] = [ '172.17.0.0/16' ]; nginx['real_ip_header'] = 'X-Forwarded-For'" \
    --volume /data/docker-data/example-gitlab/config:/etc/gitlab \
    --volume /data/docker-data/example-gitlab/logs:/var/log/gitlab \
    --volume /data/docker-data/example-gitlab/data:/var/opt/gitlab \
    gitlab/gitlab-ce:latest

我不确定--hostname gitlab.example.com \是否有用。

SSH端口曝光和UI显示

GitLab并不关心其逻辑中的SSH端口。在向用户显示存储库的SSH URL时,环境变量中提供的SSH端口仅用于显示目的。

  • 我已将容器的真实端口22暴露在端口2222上:--publish 2222:22
  • 我已向GitLab传递了要显示的端口号:gitlab_rails['gitlab_shell_ssh_port'] = 2222

HTTPS

对于https,我必须将https://放在环境变量中。它一定不是http。如果是http,则不会安全地提供页面,因为几乎所有资源和链接都将通过http,而某些第三方资源也将是http。

将https添加到环境变量时,GitLab将检查有效的TLS证书。

我无法找到解决方法,所以我放弃了,现在我正在给GitLab提供真正的证书。

由于它是个人服务器,我使用外部脚本将Let的加密证书复制到我通过上面的docker run命令公开的卷中。

cp /data/docker-data/http-realm/certs/live/gitlab.example.com/cert.pem /data/docker-data/example-gitlab/config/ssl/gitlab.example.com.crt
cp /data/docker-data/http-realm/certs/live/gitlab.example.com/privkey.pem /data/docker-data/example-gitlab/config/ssl/gitlab.example.com.key

不漂亮,但确实有效。

反向代理

从原来的问题发生了重大变化,因为现在我在Docker中使用 Apache 。这导致Apache获得对Docker内部DNS解析的访问权。

这是我使用Apache的虚拟主机配置。我可以使用nginx,但我正在使用我有信心合作的东西。

<IfModule mod_ssl.c>
        <VirtualHost *:443>
                ServerAdmin webmaster@localhost
                ServerName gitlab.example.com

        ## REQUIRED so that external resources such as gravatar are fetched
        ## using https by the underlying nginx wizard stuff
        #RequestHeader set X-Forwarded-Proto "https"
        Header add X-Forwarded-Proto "https"

        ## http://stackoverflow.com/questions/6764852/proxying-with-ssl
        SSLProxyEngine On

        RewriteEngine On
        ProxyRequests     Off
        ProxyPreserveHost On


        ProxyAddHeaders On
        ## docker alias
        ProxyPass / https://example-gitlab:443/
        <Location />
          ProxyPassReverse /
          Require all granted
        </Location>

        SSLEngine on

        SSLCertificateFile      /etc/letsencrypt/live/gitlab.example.com/cert.pem
        SSLCertificateKeyFile /etc/letsencrypt/live/gitlab.example.com/privkey.pem
        SSLCertificateChainFile /etc/letsencrypt/live/gitlab.example.com/chain.pem

        SSLProtocol all -SSLv2 -SSLv3
        SSLHonorCipherOrder on
        SSLCipherSuite "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4"



        # Custom log file locations
        ErrorLog /var/log/apache2/example-gitlab_error.log
        CustomLog /var/log/apache2/example-gitlab_access.log combined

        </VirtualHost>
</IfModule>

在行ProxyPass https://example-gitlab:443/中:主机名example-gitlab可通过Docker自己的DNS解析,因为它是容器的名称。我正在使用Docker 1.12,以防这个版本特定于此版本。

因此,我不需要将GitLab容器的端口443或端口80发布到主机,我的反向代理处理这个。

网络图层和X-Forwarded-For

需要设置gitlab以信任与您的网络层对应的X-Forwarded-For标头。

否则,在管理面板中,所有用户的IP似乎都来自docker网络层。

如果您使用的是此类型的网络层:

docker network create --driver=bridge \
  --subnet=192.168.127.0/24 --gateway=192.168.127.1 \
  --ip-range=192.168.127.128/25 strawberry

我相信你需要更改docker run配置并替换它:

nginx['real_ip_trusted_addresses'] = [ '172.17.0.0/16' ]

有了这个:

nginx['real_ip_trusted_addresses'] = [ '192.168.127.128/25' ]

(除了在docker run配置中添加--net=strawberry

此外,如果您使用的是nginx,您可能需要切换它:

nginx['real_ip_header'] = 'X-Forwarded-For'

有了这个:

nginx['real_ip_header'] = 'X-Real-IP'