您可以使用 Cloudflare Access 向自托管的 GitLab 实例添加 Zero Trust 规则。结合 Cloudflare Tunnel,用户可以通过 HTTP 和 SSH 进行连接,并使用您团队的身份提供商进行身份验证。
本演练涵盖了如何:
- 部署 GitLab 实例
- 锁定对该实例的所有入站连接,并使用 Cloudflare Tunnel 设置到 Cloudflare 的出站连接
- 使用 Cloudflare Access 构建策略以控制谁可以访问 GitLab
- 通过 Cloudflare 使用 HTTP 和 SSH 进行连接
完成所需时间:
1 小时
本节将引导您在 DigitalOcean 中部署 GitLab。如果您已经部署了 GitLab,可以跳过本节。
创建一个拥有 16 GB 内存和 6 个 CPU 的 Droplet。根据 GitLab 的资源推荐 ↗,这应该能够支持 500 个用户。
GitLab 将(暂时)提供一个暴露在互联网上的外部 IP。您需要使用此外部 IP 连接到部署的服务器进行初始配置。您可以通过在您的 DigitalOcean 账户中添加 SSH 密钥 ↗来保护到该 IP 的连接。
此示例使用 macOS 计算机来配置 Droplet。从 DigitalOcean 复制分配给该机器的 IP 地址。
打开终端并运行以下命令,将 IP 地址替换为 DigitalOcean 分配的 IP。
ssh root@134.209.124.123接下来安装 GitLab。此示例使用 Ubuntu 软件包 ↗并按照 GitLab 文档中的步骤操作,但有少数例外情况在下方指出。
运行以下命令以开始。
sudo apt-get update
sudo apt-get install -y curl openssh-server ca-certificates
curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ee/script.deb.sh | sudo bash上述命令将 GitLab 软件下载到此机器上。现在您必须安装它。这是本教程与 GitLab 文档中的操作发生分歧的第一个地方。GitLab 提供的教程中的下一步是设置外部主机名。相比之下,您只需安装该软件即可。
sudo apt-get install gitlab-ee大约一分钟左右,GitLab 将安装完成。
然而,应用程序尚未运行。您可以使用 ss 来检查有哪些端口在监听,以进行确认。
sudo ss -lntup结果应该只有当前在机器上运行的服务:
sudo ss -lntupNetid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
udp UNCONN 0 0 *:9094 *:*
tcp LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=29,fd=3))
tcp LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=29,fd=4))要启动 GitLab,请运行该软件的 reconfigure 命令。
sudo gitlab-ctl reconfigureGitLab 将启动其组件服务。完成后,确认 GitLab 正在运行并在端口 22 和 80 上监听。
sudo ss -lntupNetid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
udp UNCONN 0 0 *:9094 *:*
tcp LISTEN 0 4096 127.0.0.1:9236 0.0.0.0:*
tcp LISTEN 0 4096 127.0.0.1:8150 0.0.0.0:*
tcp LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=29,fd=3))
tcp LISTEN 0 4096 127.0.0.1:8151 0.0.0.0:*
tcp LISTEN 0 4096 127.0.0.1:3000 0.0.0.0:*
tcp LISTEN 0 4096 127.0.0.1:8153 0.0.0.0:*
tcp LISTEN 0 4096 127.0.0.1:8154 0.0.0.0:*
tcp LISTEN 0 4096 127.0.0.1:8155 0.0.0.0:*
tcp LISTEN 0 511 0.0.0.0:8060 0.0.0.0:* users:(("nginx",pid=324,fd=8))
tcp LISTEN 0 4096 127.0.0.1:9121 0.0.0.0:*
tcp LISTEN 0 4096 127.0.0.1:9090 0.0.0.0:*
tcp LISTEN 0 4096 127.0.0.1:9187 0.0.0.0:*
tcp LISTEN 0 4096 127.0.0.1:9093 0.0.0.0:*
tcp LISTEN 0 4096 127.0.0.1:9229 0.0.0.0:*
tcp LISTEN 0 1024 127.0.0.1:8080 0.0.0.0:*
tcp LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=324,fd=7))
tcp LISTEN 0 4096 127.0.0.1:9168 0.0.0.0:*
tcp LISTEN 0 4096 127.0.0.1:8082 0.0.0.0:*
tcp LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=29,fd=4))
tcp LISTEN 0 4096 *:9094 *:*用户通过 SSH(此处为端口 22)和用于 Web 应用的 HTTP(端口 80)连接到 GitLab。在下一步中,您将使用户能够通过 Cloudflare Access 尝试这两种连接。我将让它保持运行并前往 Cloudflare 仪表板。
您可以使用 Cloudflare Access 构建 Zero Trust 规则,以确定谁可以连接到 GitLab 的 Web 应用程序 (HTTP) 以及谁可以通过 SSH 连接。
当用户向受 Access 保护的网站发起请求时,该请求首先到达 Cloudflare 的网络。Access 可以检查该用户是否被允许访问该应用程序。与 Cloudflare Tunnel 集成后,Zero Trust 架构如下所示:
为了确定谁可以访问应用程序,Cloudflare Access 依赖与 Okta、Microsoft Entra ID 或 Google 等身份提供商的集成,以分发在入口处检查的身份卡。虽然 VPN 允许用户在私有网络上自由活动(除非有人建立主动规则来阻止他们),但 Access 会对每个请求实施该身份检查(且精度为配置的任意粒度)。
对于 GitLab,首先构建两条策略。用户将通过几种方法连接到 GitLab:在 Web 应用中以及通过 SSH。为每一项创建策略以保护子域。首先是 Web 应用。
在构建规则之前,您需要按照这些说明在您的账户中设置 Cloudflare Access。
启用后,转到 Zero Trust 中的 Applications(应用程序) 页面。选择 Create new application(创建新应用程序)。
选择 Self-hosted and private(自托管和私有)。
系统将提示您添加代表该资源的子域。这必须是您 Cloudflare 账户中某个域的子域。您需要为 Web 应用程序和 SSH 流程使用不同的子域。
此示例使用 gitlab.widgetcorp.tech 用于 Web 应用程序,使用 gitlab-ssh.widgetcorp.tech 用于 SSH 连接。
您可以决定允许哪些身份提供商进行身份验证。默认情况下,允许所有配置的提供商。添加规则以确定谁可以访问该网站。
选择 Create(创建) 以发布应用程序。为第二个应用程序 gitlab-ssh.widgetcorp.tech 重复这些步骤。
Cloudflare Tunnel 在此机器与 Cloudflare 网络之间创建了一个安全的、仅出站的连接。通过仅出站模式,您可以阻止对该机器的任何直接访问,并锁定任何外部暴露的入站入口点。因此,无需打开防火墙端口。
Cloudflare Tunnel 是通过 Cloudflare 的轻量级守护程序 cloudflared 实现的。按照 Downloads 页面上列出的说明在 DigitalOcean 机器上下载并安装 cloudflared。
安装完成后,使用以下命令对 cloudflared 实例进行身份验证。
cloudflared login该命令将打印一个您必须访问的 URL,以便使用您的 Cloudflare 账户登录。
选择您已添加到账户中的网站。
在您选择账户中的一个网站后,Cloudflare 将下载一个证书文件以对该 cloudflared 实例进行身份验证。您现在可以使用 cloudflared 来控制您 Cloudflare 账户中的 Cloudflare Tunnel 连接。
您现在可以使用 Cloudflare Tunnel 将 GitLab 连接到 Cloudflare。
- 运行以下命令创建新的 Tunnel。
cloudflared tunnel create gitlabcloudflared 将为此 Tunnel 生成一个唯一 ID(例如 6ff42ae2-765d-4adf-8112-31c55c1551ef)。您可以将此 Tunnel 同时用于 SSH 和 HTTP 流量。
- 您需要配置 Cloudflare Tunnel 将流量代理到这两个目的地。以下配置将把发送到为 Web 应用创建...的 DNS 记录的流量,以及发送到代表 SSH 流量的 DNS 记录的流量转发到正确的端口。
您可以使用您选择的文本编辑器来编辑配置文件。本示例依赖于 Vi。
vim ~/.cloudflared/config.yml- 配置 Tunnel 以服务流量。
tunnel: 6ff42ae2-765d-4adf-8112-31c55c1551ef
credentials-file: /root/.cloudflared/6ff42ae2-765d-4adf-8112-31c55c1551ef.json
ingress:
- hostname: gitlab.widgetcorp.tech
service: http://localhost:80
- hostname: gitlab-ssh.widgetcorp.tech
service: ssh://localhost:22
# Catch-all rule, which just responds with 404 if traffic doesn't match any of
# the earlier rules
- service: http_status:404
- 您可以使用以下命令测试配置文件是否设置正确:
cloudflared tunnel ingress validatecloudflared 应该会指示 Tunnel 正常。您现在可以开始运行 Tunnel。
cloudflared tunnel run
您现在可以在 Cloudflare 仪表板中为 GitLab 创建 DNS 记录。请记住,您仍然需要两条记录 —— 一条用于 Web 应用程序,另一条用于 SSH 流量。
-
登录到 Cloudflare 仪表板 ↗ 并转到您域的 DNS Records(DNS 记录) 页面。
Go to Records ↗ -
选择 Add record(添加记录)。选择
CNAME作为记录类型。 -
在 Name(名称) 字段中输入
gitlab。 -
在 Target(目标) 字段中输入创建的 Tunnel 的 ID,后跟
cfargotunnel.com。在此示例中,该值为:
6ff42ae2-765d-4adf-8112-31c55c1551ef.cfargotunnel.com- 选择 Save(保存)。
- 再次重复该过程,创建第二条具有相同 Target(目标) 的
CNAME记录,但对于 Name(名称) 输入gitlab-ssh。这两条记录应该会显示出来,并指向相同的 Tunnel。上述配置文件中定义的 ingress 规则将流量引导到适当的端口。
您现在可以测试 Web 应用程序的端到端配置。访问为 Web 应用程序创建的子域。Cloudflare Access 会提示您进行身份验证。使用您的提供商登录。
验证身份后,您应该会看到 GitLab Web 应用程序。
注册您自己的账户并创建一个空(Blank)项目,以便在下一步中测试 SSH。
GitLab 会创建一个新的项目和存储库。
要通过 SSH 推送和拉取代码,您还需要在客户端计算机上安装 cloudflared。此示例使用 macOS 笔记本电脑。在 macOS 上,您可以使用以下命令安装 cloudflared。
brew install cloudflared虽然您需要安装 cloudflared,但您不需要以任何独特的方式包装您的 SSH 命令。相反,您需要对您的 SSH 配置文件进行一次性修改。
vim /Users/samrhea/.ssh/config输入以下值;将 gitlab-ssh.widgetcorp.tech 替换为您创建的主机名。
Host gitlab-ssh.widgetcorp.tech
ProxyCommand /usr/local/bin/cloudflared access ssh --hostname %h您现在可以通过尝试克隆之前创建的项目来测试 SSH 流程。
git clone git@gitlab-ssh.widgetcorp.tech:samrhea/democloudflared 会提示您登录我的身份提供商,一旦成功,将向您的设备分发一个令牌以允许您进行身份验证。
您现在可以为您的 DigitalOcean 防火墙配置一条规则来阻止任何入站流量,以防止直接访问。
Cloudflare Tunnel 将继续运行仅出站连接,我可以避免这台机器陷入加密货币挖掘操作或更糟的情况。
您还可以查看允许和阻止的事件的日志。打开 Zero Trust 的 Logs 部分中的 Access 页面。
如果您使用的是 Git Large File Storage (LFS),请注意 cloudflared 不自动支持 Git LFS。要访问受 Cloudflare Access 保护的存储库,您需要通过运行以下命令手动进行身份验证:
cloudflared access login <your-git-access-url>将 <your-git-access-url> 替换为受 Cloudflare Access 保护的 URL。