使用 Frp 内网穿透搭建 GitLab 服务

短文 ? 次阅读
延迟发表
本文早先已经创作完成,因若干原因延迟发表,可能已无时效。上方标注者为创作日期,实际发表于 2021 年 04 月 04 日。

近期有多个项目正在进行,涉及到很多份程序代码,大多数由师兄提供。

学习过程中:

  • 一方面,需要对代码做不同程度的修改,以完成新的任务;
  • 另一方面,也需要在代码中写上注释、创建 README 等,作为研读程序过程中的记录;
  • 若能够将程序的改动记录下来,也将会是一件很有帮助的事情;
  • 现在有两台工作用的电脑,加上自己的笔记本,总共有三台电脑,需要更方便地在它们之间传递最新版本的代码。

显然,用 Git 结合云托管平台来维护这些代码是一种自然的需求。然而,教研室的这些代码并不适合放在公有云上;考虑到这一方面的问题,以及未来教研室可能的需求,我决定尝试自己搭建一个 GitLab 平台,用来存放这些代码。

现在我手头没有公网 IP 的电脑,用来建个人网站的云服务器的带宽、硬盘也受限。因此,决定先在自己宿舍的旧笔记本上搭一个 GitLab,然后通过 Sakura Frp 内网穿透映射到公网上。

配置情况

旧笔记本(服务器)的配置:

  • 型号:ThinkPad E555(20DHA01QCD);;
  • CPU 为 AMD A10-7300;
  • 显卡为 AMD Radeon R7;
  • 4G(实际为 3.2G)内存;
  • 系统为 Cent OS 7.8;
  • 近 500G 的机械硬盘;
  • 接入宿舍的 50M 宽带。

配置很差,但基本能达到运行 GitLab 服务的要求。

此外,笔记本上已经运行了一个 Seafile 服务,80、443、8080 等端口已经被占用了。

解决方案

个人安装,当然选社区版本(gitlab-ce)。首先,按 GitLab 官方的要求检查依赖项是否安装:

sudo yum install -y curl policycoreutils-python openssh-server postfix

一般来说,Cent OS 上这些服务都是安装了的。

然后,通过 GitLab 的 yum 软件源安装 gitlab-ce;为加快速度,采用清华的镜像,具体配置请直接参考这里。这一过程可能会耗费一点时间。

安装完成之后,立即去改配置,需要调整下面几项。配置文件一般是:

/etc/gitlab/gitlab.rb

配置文件较长,下面仅展示需要修改的内容,你可以在编辑器中查找对应的部分在哪里。

配置 URL 及 SSL 证书

NATFrp 的国内隧道现在不允许做 HTTP 映射,只能用 HTTPS。假设采用的域名为 gitlab.example.com,则需在配置文件的头部中做如下设置:

external_url 'https://gitlab.example.com'

根据默认设置,若在 URL 中采用 HTTPS 协议头,则 GitLab 将自动通过 acme 工具来获取并更新 Let’s Encrypted 的免费 SSL 证书。在大多数场景下,这是最方便的一种策略,但在当前情景(内网穿透)中:

  • 经过多次尝试,发现很难通过宿舍网接通 Let’s Encrypted 的验证站点,经常获取不到 IP;
  • 即使能够联通,也会因为笔记本处于内网之中而无法完成验证。

因此,只好手动配置证书。首先到配置文件 gitlab.rb 中(路径已述)找以下内容,取消注释,关闭 Let’s Encrypted:

################################################################################
# Let's Encrypt integration
################################################################################
letsencrypt['enable'] = false
...

然后,自己通过 Let’s Encrypted 或其他平台(如 freessl.cn)手动为当前站点生成 SSL 证书。将:

  • 获取到的证书文件命名为 <domain>.crt,如 gitlab.example.com.crt
  • 获取到的私钥文件命名为 <domain>.key,如 gitlab.example.com.key
  • 将这两个文件拷贝到服务器的 /etc/gitlab/ssl 目录下即可。

以上是根据默认配置设置的,在配置文件中的对应内容为:

# nginx['ssl_certificate'] = "/etc/gitlab/ssl/#{node['fqdn']}.crt"
# nginx['ssl_certificate_key'] = "/etc/gitlab/ssl/#{node['fqdn']}.key"

这里的 #{node['fqdn']} 就对应着网站的域名。当然,你可以根据你的需要修改上面的默认配置,然后再按对应的配置来放置文件。

修改冲突端口

在需求中已言及,常用的几个 WEB 端口在安装 GitLab 之前都已经被占用了。新版本(13.x)中 GitLab 的应用服务器(Puma / Unicorn 及 GitLab Workhorse)已经默认采用 Unix Domain Socket 通信(之前通过 TCP 方式通信,占用 8080 端口),这一方面无需再做调整;但 GitLab 内置的 Nginx 仍然会占用 80 端口(无论是否启用 HTTPS)。为此需要解决这一方面的冲突,例如将其改为 81 端口:

nginx['listen_port'] = 81

在之后采用内网穿透时,也就需要将这里的 81 端口映射出去。(完整的端口分配列表可参考:GitLab 默认端口列表。)

内网穿透情景下配置 SSH 通道

在内网穿透的情景下,还有一个问题需要注意:需要采用正确的方式将 GitLab 所用的 SSH 端口映射出来。默认情况下 SSH 会使用 22 端口,但是:

在使用像 Sakura Frp 及花生壳这样的内网穿透服务时,分配的外网端口通常都是随机分配的五位数,不可能是 22 端口。

当然,内网端口仍然可以设置为 22,但这时就需要自己手工修改 GitLab 上生成的 SSH 访问地址了。GitLab 的网页端事实上可以为每个仓库自动生成的 SSH 访问地址附加自定义的端口号,前提是需要修改 Gitlab 所采用的 SSH 通道端口;思索一番便会发现,最简单易行的方法就是:把 SSH 服务对应的内网与外网端口都改为一个 22 以外的统一值(最好以外网端口为准,因为可用的外网端口通常是在限定的范围内随机分配的,并且需要与其他使用同一内网穿透的用户分享,很难调整)。

假设内网穿透服务自动分配(或由你人工选取)的 SSH 通道端口为 23333,首先在 GitLab 的配置文件中修改 GitLab Shell 的 SSH 服务端口号:

gitlab_rails['gitlab_shell_ssh_port'] = 23333

然后,去修改服务器的 OpenSSH 服务配置文件(/etc/ssh/sshd_config),在其中添加 23333 端口为 SSH 服务端口

# This is the sshd server system-wide configuration file.  See
# sshd_config(5) for more information.
# ...
Port 22
Port 23333  # add this

注意到上面的写法中保留了 22 端口,这意味着你仍然可以在内网通过 22 端口(具体来说就是直接 ssh xxx@IP)连接服务器。

Sakura Frp 配置内网穿透通道

这一步,直接按 Sakura Frp 官网上的指南来做即可。不再赘述,只需记得内网穿透设置中的内部端口为 23333 即可。启动为系统服务,保证每次服务器重启后都能正常工作。

启动

完成以上配置之后,需要让 GitLab 重载以上配置,并重新启动(以下命令都需要管理员权限):

gitlab-ctl reconfigure
gitlab-ctl restart

可能会花费一点时间。由于我的旧笔记本性能较差,在启动大概 3 分钟后才能正常工作;在此之前,网站会显示 502 错误。

试试在外网用你设置的域名(如 gitlab.example.com)访问一下(第一次登录的时候会要求设定 root 账户的密码):

GitLab index page preview

完成,收工!

补充

若服务器条件尚可,宜用 Docker 安装 GitLab,如此可规避上面曾碰到过的不少问题。不过,对 GitLab 来说,需要认真配置其持久化储存的方式,并做好备份。

写本篇时,尚不知有 Gogs、Gitea 等轻量级的 Git 托管平台;如今若再要配置,宁则此诸小型服务,更方便。