{
"title": "利用 Cloudflare Argo Tunnel 绕过备案检测",
"tags": [
"post",
"cloudflare",
"gitlab",
"nginx"
],
"sources": [
"xlog"
],
"external_urls": [
"https://blog.thynanami.com/bypass-icp-check-with-cloudflare-argo"
],
"date_published": "2023-04-09T08:02:56.496Z",
"content": "## 真实需求\n\n绕过备案检测使自托管 Gitlab URL 不带端口号\n\n## 问题\n\n访问通过 Nginx 反代后的带端口的 URL 会被重定向到不带端口的 URL\n\n### 原因\n\nNginx 按照 gitlab.rb 的配置将用户重定向到了 external_url, 也就是 gitlab.rb 中的设定, 此设定改成带端口的 URL 也会导致问题(过多的重定向导致现代浏览器报错).\n\n## 解决方案\n\n使用 Argo Tunnel 接管内置 Nginx, 直接与 Gitlab Workhorse 连接\n\n### 原理\n\n通过分析 Gitlab-CE 源代码可以找到内置 Nginx 的工作方式\n\nhttps://gitlab.com/gitlab-org/gitlab-foss/-/blob/master/lib/support/nginx/gitlab-ssl\n\n```nginx\n# 前面忽略\nupstream gitlab-workhorse {\n # GitLab socket file,\n # for Omnibus this would be: unix:/var/opt/gitlab/gitlab-workhorse/sockets/socket\n server unix:/home/git/gitlab/tmp/sockets/gitlab-workhorse.socket fail_timeout=0;\n}\n\n# 中间忽略\nserver {\n #中间忽略\n location / {\n client_max_body_size 0;\n gzip off;\n\n ## https://github.com/gitlabhq/gitlabhq/issues/694\n ## Some requests take more than 30 seconds.\n proxy_read_timeout 300;\n proxy_connect_timeout 300;\n proxy_redirect off;\n\n proxy_http_version 1.1;\n\n proxy_set_header Host $http_host;\n proxy_set_header X-Real-IP $remote_addr;\n proxy_set_header X-Forwarded-Ssl on;\n proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n proxy_set_header X-Forwarded-Proto $scheme;\n proxy_set_header Upgrade $http_upgrade;\n proxy_set_header Connection $connection_upgrade_gitlab_ssl;\n\n proxy_pass http://gitlab-workhorse;\n }\n}\n#后面忽略\n```\n\n可以发现几乎就是直接把流量交给 Gitlab Workhorse 处理, Nginx 只负责重定向, 提供静态资源, 之间通过 Socket 连接.\n\nArgo Tunnel 可以将本地的服务映射到公网, 也可作为网关转发流量.\n\n因此使用 Argo Tunnel 代替 Nginx 可行.\n\n### 步骤\n\nStep1. 注册 Cloudflare 账号, 将域名转移到 Cloudflare, 然后打开 Zero Trust -> Access -> Tunnels\n\nStep2. 在 Gitlab 主机上安装 cloudflared 并按照 Cloudflare 的指示配置连接.\n\nStep3. 修改 gitlab.rb\n\n```ruby\nexternal_url 'https://git.targetdomain.com'\n# 修改成最终呈现的 URL\ngitlab_rails['trusted_proxies'] = ['0.0.0.0/0']\n# 允许目标 IP 与 Gitlab Workhorse 建立连接\n# Warning: 因为 Argo Tunnel 的远程主机 IP 并不固定, 我也没测出来所有的 IP 段(太多了), 因此这里允许所有主机建立连接.\n# 出于安全原因你需要配置本地防火墙禁止外部连接(关闭对应端口, 即 Gitlab Workhorse 监听的端口), Argo Tunnel 不会因此无法建立连接(在本地建立的自然不影响)\ngitlab_workhorse['listen_network'] = \"tcp\"\ngitlab_workhorse['listen_addr'] = \"0.0.0.0:10080\"\n# 让 Workhorse 在 10080 监听\n# 接应上文, 你需要阻止一切外部主机连接 10080 端口\n# 你也可以使用 Unix Socket\n# gitlab_workhorse['listen_network'] = \"unix\"\n# gitlab_workhorse['listen_addr'] = \"...省略/socket\"\n# 使用 Socket 不需要配置防火墙\nnginx['enable'] = false\n# 禁用 Gitlab 自带的 Nginx\n```\n\nStep4. 配置 Tunnel\n\n在 Tunnel 管理界面 -> Public Hostname 新建一个主机名\n\n![Hostname](https://s2.loli.net/2023/01/28/bUPzfOeNDQF4nBR.png)\n\nSubdomain 与 Domain 按需填写, 需要与 gitlab.rb 中保持一致\n\n在示例配置中 URL 是 https://git.targetdomain.com, 因此需要设置 Subdomain 为 git, 设置Domain(需要接入 Cloudflare)为 targetdomain.com, Path 留空\n\nService Type 选择 TCP, URL 填写 localhost:10080, 同理需要与 gitlab.rb 中保持一致, 在示例配置中它是 10080 端口.\n\nNotice: 如果你使用的是 Unix Socket, Service Type 需要选择 UNIX, URL 需要填写**绝对路径**.\n\nStep5. 现在访问你的 Gitlab, 它应该已经可以正常使用了, 并且所有的 URL 与重定向都是正确的.",
"attributes": [
{
"value": "bypass-icp-check-with-cloudflare-argo",
"trait_type": "xlog_slug"
}
]
}