我已经拥有我的在线形象"现在踢了一年多。因此,对于这篇(过于冗长的)文章,我认为我会发布有关如何创建自己的Git服务器的注释。
有许多开源项目,例如GitTea或GitLab,可以轻松托管自己的git项目。但是我想要一个更简单的(阅读:旧学校)设置。最后,我使用了Linux组织用于发布Linux内核的许多相同项目。
该服务器(在撰写本文时)使用了在Digital Ocean的硬件(参照链接)上运行的Ubuntu 20.04.1 LTS(Focal Fossa)。我全力支持,建议您选择其他设置。人们和技术堆栈中的多样性永远都是一件好事。
开始为git托管任务准备了一个新创建的服务器。创建一个新的管理员用户,锁定OpenSSH守护程序,并安装fail2ban。
Gitolite安装并配置了服务器,以使我们(和同事)可以更精细地控制谁可以访问服务器上的git push | fetch。
我经常会发现安全性&最佳做法"很像在高速公路上开车。有些人超速驶过你,显然是"距重大数据泄露事件仅片刻之遥,而您正在传递的其他数据则很明显地"如此担心整个数据中心的烧毁,他们不可能做其他任何事情。每个人都认为其他人都丢了大理石。
因此,考虑到这一点,我采取了一些措施来保护新创建的服务器。请随时仅使用"最佳做法"您认为适合您的任务。
无论出于何种原因,无论是出于安全考虑还是为了保护服务器免受愚蠢之苦,创建新服务器时要做的第一件事就是为常规管理任务添加新用户。
系统将提示您回答一些问题,包括创建新的UNIX密码。这将是您需要sudo -i并获得root权限的密码,因此使其成为一个很好的密码,或者使用Pass或BitWarden之类的工具来帮助您记住。
在登录服务器时,我还很大程度上消除了所有基于密码的身份验证,而依赖于NitroKey等开源智能卡进行身份验证。如果有兴趣,这要求我们为肢体用户设置.ssh / authorized_keys:
接下来,设置.ssh目录的文件许可权,以便ssh守护程序可以读取文件:
如果一切正常,则在重新启动ssh守护程序(service sshd restart)之后,您现在可以以管理员用户身份登录:
Git和Gitolite(将在下一部分中安装)将需要我们保持端口22开放,从而允许我们从Internet上的任何位置进行git push。这个开放的港口最终会吸引很多人。僵尸程序的关注,他们无休止地搜寻互联网以寻找易受攻击的服务器,漫不经心地塞满密码,希望一个密码最终可以让它们进入。
通过禁用所有基于密码的身份验证,完全依靠非对称密码或" ssh密钥&#34 ;,我们可以消除所有有关密码弱或被泄露的担忧。只需使用您喜欢的文本编辑器打开/ etc / ssh / sshd_config并确保这些行存在于其中:
当我们在这里时,这些机器人中的绝大多数[1]有兴趣以root用户身份登录。如果您在上一节中创建了一个新的管理员帐户,并确保可以使用公共密钥登录,则还可以使用config中的以下行完全禁用root登录:
一些简单的“ bash-fu”在我的/var/log/auth.log上,显示了自启动此服务器以来大约15,000次登录尝试中的〜93.58%,尝试以root用户身份登录第二名是git用户(包括合法登录),为〜1.82%。
如果您将公用密钥上载到VPS提供商,则其中大多数更改应该已经为您配置。但是如果您必须进行一些更改,请重新启动ssh服务以在以下位置加载新的配置更改:
根据您的VPS提供商的不同,他们还可能在其管理面板中内置了防火墙系统,使您可以简单地通过向服务器添加标签来应用规则。但是,如果出于同样的原因,我喜欢将所有的袜子规则都保留在左抽屉中,那么我喜欢将所有防火墙规则都保留在每个盒子中,从而使一切保持井井有条,并位于同一位置。
现在,我们启用的唯一功能是使用端口22的ssh。要通过ufw允许端口22,只需使用以下命令:
即使我们已在上一节中关闭了基于密码的身份验证,我们仍然会收到大量的机器人在浪费我们的计算周期来尝试登录。而且,如果四舍五入到任意数量级,成功的可能性为零,但是如果有机会,机器人将继续窃取非零数量的CPU。
为了阻止这些僵尸程序中最肆无忌bra的工具,Fail2Ban之类的工具会在有用性和烦恼之间做出巨大折衷,这些工具会创建临时防火墙规则来阻止反复通过ssh进行身份验证的IP地址。
安装后,ssh" jail"将为您预先启用。如果要进行任何更改,则需要制作fail2ban配置文件的副本:
fail2ban在记录配置文件中每个选项的功能方面做得很好。我所做的一些更改是:
启用bantime.increment可以根据以前禁止IP地址的次数来增加禁止时间。
启用bantime.rndtime来" randomize"禁止的时间长度,以防止漫游器确切知道何时可以恢复攻击。
启用bantime.maxtime,这样我就不需要取消IP地址限制(如果您不幸与机器人共享IP)。
降低了bantime,findtime和maxretry,使我可以发布一些小禁令,这些禁令的严重性随着IP地址的持续对抗而增加。
取决于受欢迎程度如果您在互联网上,则应该开始在/var/log/fail2ban.log中看到行为不当的漫游器和ufw中等效的防火墙规则的NOTICE行。
$ cat /var/log/fail2ban.log | grep' NOTICE' | tail -1 ... [125553]:注意[sshd]禁止156.155.159.161 $ ufw statusStatus:activeTo操作来自------- ---- Anywhere REJECT 156.155.159.16122 / tcp ALLOW Anywhere22 / tcp(v6 )任何地方(v6)
安装Gitolite非常简单,无需编译任何二进制文件或监控守护程序。
Gitolite的核心只是Perl脚本的集合,当有人使用我们在上一节中配置的ssh守护程序登录服务器后,它们便会运行。安装后,Gitolite将使我们对谁对每个存储库具有git push | fetch权限具有更细化的控制。如果您只是想了解Gitolite的能力,我鼓励您查阅Gitolite的出色文档。
在安装Gitolite之前,我们需要为每个人创建一个新用户以登录并运行Gitolite的Perl脚本。我通常为此使用用户名git,请随时用您认为更合适的用户名替换git。
这将在名为git的服务器上创建一个新的系统用户。因为这不是"正常"用户,/ etc / shadow中将没有老化信息,这在没有人监视此帐户时很方便。
我们还使用--home选项将$ HOME变量设置为/ var / lib / git。这是我们最终放置Gitolite的配置文件和Git存储库的地方。可以随意将其调整为您喜欢的位置,我已经看到很多人使用/ home / git。
我添加了--disabled-password来禁用对新用户的任何基于密码的访问。在前面的部分中,我们已将所有基于密码的身份验证禁用到服务器中,并且Gitolite要求使用ssh密钥进行身份验证,因此为用户禁用密码是明智之举。
因为Gitolite只是一堆Perl脚本,所以我更喜欢从源代码安装Gitolite。正如我们将看到的,从源代码安装Gitolite还具有使升级和将来添加自定义补丁程序非常容易的好处。
当我们(或同事)使用git用户登录服务器时,我们将自动运行Gitolite的Perl脚本,这意味着这些脚本必须由git用户可执行。因此,为简化文件权限管理,我们将在其余的安装过程中使用git用户。
使用"替代用户"登录到我们的git用户。命令:(假设您是root用户)
然后将Gitolite的源代码克隆到$ HOME目录中:(除非您在上面设置git用户时更改了它,否则它应该是/ var / lib / git)
要在服务器上设置Gitolite,我们需要为Gitolite分配一个管理员,该管理员将完全控制编辑Gitolite的配置存储库。这很可能是你。
仍然以git用户身份,使用您喜欢的文本编辑器在$ HOME目录中创建具有所需用户名的新文件,并将您的公共ssh密钥复制到该文件中。例如,我的文件名为bryanbrattlof.pub,如下所示:
我建议查阅Gitolite令人难以置信的文档,以了解如何正确配置访问权限并为所有项目添加挂钩。
虽然从技术上来说Gitolite不能正常运行,但我发现在我们的git用户的$ PATH中添加gitolite可以极大地改善生活质量,而我很少需要扮演系统管理员的角色。
现在,我们可以使用Gitolite的安装脚本在$ HOME / bin文件夹中添加一个符号链接:
注销并重新登录到git用户(或使用源$ HOME / .profile)以获取更改。如果一切操作正确,您将无需再键入Gitolite的完整路径。
Cgit是一个脚本(用C编写),它使用通用网关接口(CGI)规范为人们提供了我们项目的Web视图。当您无权访问终端或只想查找(或展示)对项目的某些更改时很方便。
它作为Web服务器的后端(类似于PHP)运行(我们将在下一部分中安装Nginx),该服务器将解析我们的存储库并返回一个网页,供我们的Web服务器分发。
为了了解Cgit的外观,一些使用Cgit的比较流行的项目是Linux和FreeBSD内核,以及Wireguard和Cgit本身。
就像使用Gitolite一样,我更喜欢从源代码安装Cgit,以便添加个人补丁并快速更改服务器上正在运行的版本。这也意味着我们需要自己安装依赖项:
克隆项目后,我们还需要构建必需的软件包来安装gcc并提供编译Cgit所需的工具:
由于Cgit使用了Git源代码的一部分(包含在子模块中),因此我们需要使用git子模块从Git项目中下载其余代码。
$ git submodule init#在.git / config中注册git子模块$ git submodule update#克隆/获取并检出正确的git版本
在服务器上拥有Cgit的完整副本之后,我们现在可以创建一些补丁以针对我们的用例对其进行自定义。我们将从在刚刚克隆的cgit项目中创建cgit.conf开始,以告诉make我们要将Cgit二进制文件安装在何处。
因为这是一个版本控制的项目,所以我们可以提交更改以保存我们的工作:
如果一切顺利,那么当您从终端执行Cgit时,应该会打印出一个网页:
$ ./cgitContent-Type:text / html; charset = UTF-8最后修改时间:2021年1月12日星期二22:35:43 GMT到期时间:2021年1月12日星期二22:40:43 GMT<!DOCTYPE html>
我们可以使用位于/ var / www / html / cgit / cgitrc的cgitrc文件进一步自定义Cgit的行为。请随意查看手册页,以获取每个选项的完整描述。
将project-list设置为projects.list的位置Gitolite创建,在Cgit的索引页面上的存储库列表中添加描述和类别
Cgit使用Git中的代码,旨在让用户运行命令(例如:git push)然后退出,从而使我们的计算机可以在每次调用之间回收使用的资源。 Nginx使用更快的协议(FastCGI),该协议多次调用同一程序而不会退出。
但是,由于Cgit旨在在每次运行后退出,因此它将永远不会退回其使用的资源,并且会继续消耗更多资源,从而迅速耗尽计算机的所有可用资源。这就是为什么我们需要fcgiwrap。
安装了Cgit和FastCGI Wrapper之后,我们现在可以将注意力转移到Nginx上,可以使用Advanced Packaging Tool进行安装:
接下来,在/ etc / nginx / sites-enabled目录中创建一个新的配置文件,将git.bryanbrattlof.com替换为您的域。 Cgit工作所需的最低配置文件如下所示:
服务器{server_name git.bryanbrattlof.com;听[::]:80;听80; access_log /var/log/nginx/cgit-access.log; error_log /var/log/nginx/cgit-error.log;根目录/ var / www / html / cgit / cgi; try_files $ uri @cgit; location @cgit {包括fastcgi_params; fastcgi_param SCRIPT_FILENAME /var/www/html/cgit/cgi/cgit.cgi; fastcgi_pass Unix:/run/fcgiwrap.socket; fastcgi_param PATH_INFO $ uri; fastcgi_param QUERY_STRING $ args; fastcgi_param HTTP_HOST $服务器名称; }}
请随意添加更多内容,我添加了一个自定义5xx页面,缓存标题以及Mozilla Observatory的建议。
如果出了点问题,或者曾经更改过配置文件,则可以使用nginx -t检查配置是否有错误,并使用nginx -s reload重新启动Nginx服务器。
现在,我们应该已经可以使用git服务器了。但是,像大多数创造性的事情一样," 90%完成了... 90%可以去了。"确实可以提供无穷无尽的东西,应该添加或配置这些东西,以使您的服务器更加安全和可访问。如果您是喜欢学习的人,那么您可能会像我一样觉得这是有趣而有益的经历。
已安装certbot,以安装和管理来自Let's Encrypt的免费SSL证书。大约5年以来,这在所有公共服务器上都是强制性的
使用Borg特定的rsync.net订阅创建了一个基于Borg的备份脚本,以备份我的项目。当我们谈论的公驴发现0天时很有用
创建了一个Git Daemon服务,让人们可以根据需要使用git://协议克隆我的项目
在保持一切正常运行所需的脚本和服务中放置了一堆Healthcheck Pings。当cron或systemd跌倒时,Fail2Ban,Borg Backup,Certbot都会提醒我
所有这些都应该给出自己的文章,因为它们可以在您的所有设置中使用,而不仅是在此完全开源和免费(如libre)的git服务器中。