服务被挖矿了?凌晨三点还在升级GitLab

【摘要】gitlab漏洞导致服务器被植入挖矿程序,凌晨三点还在升级。

前情回顾

事情是这样色的,去年春节前夕,A同事说gitlab不太稳定,有时候访问会502,代码不能合并,但是重启或者刷新配置就好了(可能这个时候服务器已经被挖矿了)。大概又过了几天吧,B同事说,安装有gitlab的服务器CPU飙到100%了,进程杀不死,有大流量向外网传输,就如同下面的画面。



纳尼,怎么会这样?这台服务器在内网下,为什么会被挖矿?





服务器鬼使神差的主动连接外网的SSH。


这个时候某服务器异常问题群已经建立起来了,总监已经进群了,顿时警觉了起来,好在经过B同事的不懈的努力,终于定位到了该进程。

git       91607 18.7  0.0  54732 41872 ?        Ssl  21:25   0:16 /boot/nptgdg


但是无法将此进程彻底杀死,还是在狂建链接。脑补一下电影中的画面吧,黑客们在疯狂的敲击着键盘...



当然了此时B同事也在疯狂的敲击着键盘,好似黑客攻击大战,你攻我守。费了九牛二虎之力B同事成功定位到这个进程了,就是利用定时任务启动的。此时A同事嘴角泛起一丝微笑,“这台服务器上唯一的定时任务就是gitlab的每日备份了”。经过B同事深挖发现是名称为kthreaddk的程序,百度发现是挖矿的。



最后上了杀毒软件,做了个全盘扫描,发现了106个病毒,都是在/var/opt/gitlab-workhorse/和/usr目录下。



B运维说“这台服务器上重要文件都备份一下吧”。此时我心里犹如乱麻,这台服务器可是我进公司接触的第一台服务器,称它为“老伙计”吧。"老伙计"长期资源利用率不高且杂乱。其实早在一个月之前我就向总监提议要将这台服务器要进行优化,采取专机专用。像比较重要的GitLab、Confluence、DOClever等采用独立部署,增加服务器权限,增加监控策略,增加备份策略(重要文件备份至其它服务器上),这样看来服务器的优化计划要提前了。


大概在晚上7点的时候我们完成了备份。


这个时候总监在群里拽了一篇文章“攻击者利用漏洞发动DDoS攻击,3万台GitLab服务器仍未修补”并@我说“兄弟们,今天必须要整改落实到位啊”,我知道今晚肯定要加班了。


其实早在2021年11月份的时候,谷歌云安全可靠性工程师 Damian Menscher 在推特上指出,根据CVE-2021-22205漏洞利用报告,有攻击者正在利用 GitLab 托管服务器上的安全漏洞来构建僵尸网络,并发起规模惊人的分布式拒绝服务攻击(DDoS)。其中一些攻击的峰值流量,甚至超过了1Tbps。而这个被利用的漏洞,正是GitLab在2021年4月修补的漏洞。谷歌的工程师 Damian Menscher表示,被黑客攻击的服务器是某巨型僵尸网络的一部分,该僵尸网络由"数千个受感染的GitLab实例"组成,并且正在发动大规模的DDoS攻击。


GitLab已提供了超过六个月的补丁服务,然而遗憾的是,针对面向互联网的GitLab实例分析表明,大量实例仍然是脆弱的。Rapid7于周一发布的帖子显示,有超过60,000台GitLab服务器连接到互联网,尽管GitLab已于2021年4月完成了修补工作,但其中大约有30,000台GitLab服务器仍未修补CVE-2021-22205 ExifTool漏洞。


在蜜罐社区,安全威胁情报周报(21.11.13~21.11.19)看到捕获的gitlab漏洞GitLab rce (CVE-2021-22205) 影响的 GitLab版本:11.9 <= GitLab(CE/EE)< 13.8.8 13.9 <= GitLab(CE/EE)< 13.9.6 13.10 <= GitLab(CE/EE)< 13.10.3


我们的版本为13.7.6,正好命中了。


好了,开始加班之旅吧。



一、版本确认


使用内部文件查看当前版本

#通过以下命令来查看GitLab版本
cat /opt/gitlab/embedded/service/gitlab-rails/VERSION

或者使用/help页面确认

查看GitLab的官方博客确定安全版本

GitLab官方博客(https://about.gitlab.com/releases/categories/releases/).可以在这个页面订阅一下GitLab的双周通讯,便于接受一些重要信息。


二、制定升级计划


GitLab升级必须按照官方给定的版本跨度去升级,否则就会出现意想不到的错误。别问我是怎么知道的,因为我曾经被这个版本跨度折磨过,那滋味不好受,你们千万要听劝。


升级路线(https://docs.gitlab.com/ee/update/#upgrade-paths),如下:


三、备份及恢复


备份 GitLab

创建 GitLab 及其所有数据(数据库、存储库、上传、构建、工件、LFS 对象、注册表、页面)的备份。如果升级出现问题,这对于将 GitLab 回滚到工作状态至关重要。

根据GitLab 版本进行备份,版本不同备份命令可能不同。

GitLab 12.2 或更高版本(我们公司备份命令):

sudo gitlab-backup create

GitLab 12.1 及更早版本:

gitlab-rake gitlab:backup:create

如果您从源代码安装了 GitLab,请使用以下命令:

sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production

如果您在 Docker 容器中运行 GitLab,请根据您安装的 GitLab 版本从主机运行备份。

GitLab 12.2 或更高版本:

docker exec -t  gitlab-backup create

GitLab 12.1 及更早版本:

docker exec -t  gitlab-rake gitlab:backup:create

备份配置文件

/etc/gitlab/gitlab-secrets.json
/etc/gitlab/gitlab.rb
/home/git/gitlab/config/secrets.yml
/home/git/gitlab/config/gitlab.yml

对于Docker 安装,您必须备份存储配置文件的卷。如果您根据文档创建了 GitLab 容器,它应该在 /srv/gitlab/config目录中。

恢复 GitLab版本

要恢复 GitLab 备份:

停止 GitLab 并删除当前包,举例:从 13.12.15 到 13.7.6降级.

在主要版本之间降级时,请考虑升级到要降级的主要版本时发生的特定版本更改。这是说有些版本升级的时候进行了一些大的升级,比如调整了配置文件,是需要做相应修改的。

$ sudo gitlab-ctl stop puma  #如果此时运行的是puma,要停止。14版本后必须是puma,之前是unicorn

## 停止 sidekiq
$ sudo gitlab-ctl stop sidekiq

## 如果在Ubuntu上:移除当前安装包
$ sudo gitlab-ctl uninstall

## 如果在Centos上:删除当前包
$ udo yum remove gitlab-ce
$ gitlab-ctl cleanse #保留数据不执行该命令
$ rm -rf /opt/gitlab #保留数据不执行该命令

注:必要时可以直接gitlab-ctl stop停止gitlab来进行降级。

将 GitLab 降级到所需版本

rpm -Uvh gitlab-ce-13.7.6-ce.0.el7.x86_64.rpm

重新配置 GitLab

 gitlab-ctl reconfigure
 gitlab-ctl start

注:若是降级时没有删除数据目录,那么备份恢复就不用操作了。

备份数据恢复

此过程假定:

首先确保您的备份 tar 文件位于 gitlab.rb配置中描述的备份目录中gitlab_rails['backup_path']。默认值为 /var/opt/gitlab/backups. 它需要归git用户所有。

sudo cp 11493107454_2018_04_25_10.6.4-ce_gitlab_backup.tar /var/opt/gitlab/backups/
sudo chown git.git /var/opt/gitlab/backups/11493107454_2018_04_25_10.6.4-ce_gitlab_backup.tar

停止连接到数据库的进程。让 GitLab 的其余部分继续运行:

sudo gitlab-ctl stop puma
sudo gitlab-ctl stop sidekiq
# Verify
sudo gitlab-ctl status

接下来,恢复备份,指定要恢复的备份的时间戳:

# This command will overwrite the contents of your GitLab database!
sudo gitlab-backup restore BACKUP=11493107454_2018_04_25_10.6.4-ce

GitLab 12.1 及更早版本的用户应改用该命令gitlab-rake gitlab:backup:restore。


四、版本升级


##升级前先停止unicorn或者puma、sidekiq、nginx
gitlab-ctl stop unicorn
gitlab-ctl stop sidekiq
gitlab-ctl stop nginx
#开始升级
rpm -Uvh gitlab-ce-14.6.2-ce.0.el7.x86_64.rpm 
gitlab-ctl reconfigure  #加载配置,执行完此步骤请注意打印的信息,有时候会提示重启redis或postgresql等
#启动
gitlab-ctl start

:每升级一个版本都要验证是否升级成功,升级大版本时要注意官网的版本更新变化。有时会对一些依赖插件做调整,如postgresql的版本等。





为啥凌晨3点还在升级?

通过官网的升级路线,我制定了以下的升级版本路线:

13.7.6-->13.8.8-->13.12.15-->14.0.11-->14.1.8-->14.2.6-->14.6.2

升级之前我备份了nginx相关的配置文件,如下:

gitlab-health.conf
gitlab-http.conf
nginx.conf
nginx-status.conf

备份了全量代码,如下:

sudo gitlab-backup create

备份了配置文件,如下:

gitlab.rb
gitlab-secrets.json

我记忆中其余的文件应该都没有动过,只有gitlab.rb中部分是自定义的,如下:

external_url 'http://192.168.0.181'
unicorn['port'] = 80
gitlab_rails['backup_path'] = "/home/gitlab/backups"
gitlab_rails['backup_keep_time'] = 604800
git_data_dirs({ 
   "default" => { 
     "path" => "/home/gitlab-data"
    }
 })

unicorn['port'] = 80 这行配置为我加班埋下了伏笔,不知是哪个挨千刀的加了这行配置(你们要相信这行绝不是我加的,因为我有证据,后面举证。)

从13.7.6-->13.8.8-->13.12.15都很丝滑,升级成功后访问查看,再进行全量代码备份,再升级。直到13.12.15-->14.0.11的时候,这种大版本的升级我知道肯定有重大的变更,通过官网查看,我们设计到的主要有两项变更:

PostgreSQL 12在升级GitLab 13.8.8时候会自动升级为12,至于Puma需要将配置文件中Unicorn相关的都调整为Puma,如下:

external_url 'http://192.168.0.181'
puma['port'] = 80
gitlab_rails['backup_path'] = "/home/gitlab/backups"
gitlab_rails['backup_keep_time'] = 604800
git_data_dirs({ 
   "default" => { 
     "path" => "/home/gitlab-data"
    }
 })

但是在升级完成的时候访问报502,我以为操作有误,来来回回试了很多遍降级、升级都是502。此时差不多22点了吧(gitlab的备份超级慢,耽误了很多时间),版本停留到了13.12.15,其实此时已经脱离了gitlab漏洞范围了,索性回家洗洗睡吧。

(有没有记流水账的感觉?)



回家躺床上,越想越睡不着,“为什么会这样哩?到底哪里出的问题?”,这股牛劲促使着我,我又起来了,开始查找有关的解决方案,试了几次还是不行,最后我猛然想起来,最开始之前的版本我也有备份的配置文件。因为在这之前我还升级过两次,2020.7.10和2021.2.9都升级过,看吧,我是有证据的,最后的配置文件我是有备份的,虽然我记性很好,但是我还是崇尚“好记性不如烂笔头”。

(王婆卖瓜自卖自夸...)



其中2020.7.10是8.6-->13.0.0,也是跨越了好几个大版本的升级。如下配置:

external_url 'http://192.168.0.181'
gitlab_rails['backup_path'] = "/home/gitlab/backups"
git_data_dir "/home/gitlab-data"

2021.2.9是13.0.0-->13.7.6,如下配置:

external_url 'http://192.168.0.181'
gitlab_rails['backup_path'] = "/home/gitlab/backups"
gitlab_rails['backup_keep_time'] = 604800
git_data_dirs({ 
   "default" => { 
     "path" => "/home/gitlab-data"
    }
 })


看到了吧,现在的配置文件比原先的时候多了unicorn['port'] = 80,在升级14之前我改为了puma['port'] = 80,这到底是谁加的呢?


其实unicorn默认的端口是8080,我想是因为端口冲突有人添加了这一行配置。理论上这行不通啊,因为gitlab的nginx默认端口也是80,如下:

...
server {
  listen *:80;
  server_name 192.168.0.181;
}
...


两者都是80端口,难道不冲突吗?但是之前确实是可以启动并且正常访问...

升级14之前我改为了puma['port'] = 80,这个时候确实和gitlab的nginx端口冲突了,导致502访问不成功。我将80改成了81,顺利升级到14.0.11,最后经过几个版本的跨越升级到了14.6.2。



此时已经凌晨3点半了,潇洒的在群里拽了上图后就睡了。


再来说说服务器挖矿的事吧,其实挖矿危机并没有完全解决,即使升级了也无法彻底解决,只要gitlab的定时任务开启,挖矿进程就会死灰复燃,最彻底的做法就是重新装系统,好在我们后来对服务器进行了虚拟化,采用专机专用。


我想说“安全无小事,运维靠大家。” 等啥里,赶紧去检查自家gitlab的版本吧,或者提桶跑路也行。



· END ·

如果这篇文章对您有帮助或者有所启发的话,请帮忙点赞、转发,您的支持是我坚持更新的最大动力。

最后,欢迎关注架构至美微信公众号,查看历史文章,希望我的文章可以给您带来收获,哪怕只是一点点。

展开阅读全文

页面更新:2024-04-02

标签:攻击者   僵尸   端口   总监   备份   漏洞   进程   同事   版本   服务器   凌晨

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号

Top