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

本文涉及的产品
云原生数据库 PolarDB MySQL 版,Serverless 5000PCU 100GB
简介: 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 版本进行备份,版本不同备份命令可能不同。

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 <container name> gitlab-backup create

GitLab 12.1 及更早版本:

docker exec -t <container name> 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 实例的版本必须相同。
  • 复 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

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

备份数据恢复

此过程假定:

  • 您已安装与创建备份 完全相同的 GitLab Omnibus 版本和类型 (CE/EE) 。
  • sudo gitlab-ctl reconfigure至少跑过一次。
  • GitLab 正在运行。如果没有,请使用sudo 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 11 的支持。确保在更新到 GitLab 14.0 之前将 您的数据库更新到版本 12。
  • GitLab 14.0 中删除了对 Unicorn 的支持,转而支持 Puma。Puma 具有多线程架构,与 Unicorn 等多进程应用程序服务器相比,它使用的内存更少。使用 Puma 减少了 40% 的内存消耗。

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的版本吧,或者提桶跑路也行。


相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
相关文章
|
7月前
|
Kubernetes NoSQL 关系型数据库
通过helm部署gitlab服务
通过helm部署gitlab服务
|
7月前
|
缓存 程序员 开发工具
服务搭建篇(八) 使用GitLab部署一个属于自己的代码托管平台
服务启动完成后,就可以访问gitlab服务了。默认的服务端口就是80端口。默认的用户名和密码是 root/123456(通常建议登录后立即修改默认密码)
197 0
|
2月前
|
NoSQL 关系型数据库 MySQL
Docker安装详细步骤及相关环境安装配置(mysql、jdk、redis、自己的私有仓库Gitlab 、C和C++环境以及Nginx服务代理)
Docker安装详细步骤及相关环境安装配置(mysql、jdk、redis、自己的私有仓库Gitlab 、C和C++环境以及Nginx服务代理)
233 0
|
7月前
|
Kubernetes NoSQL 关系型数据库
通过编写k8s的资源清单yaml文件部署gitlab服务
通过编写k8s的资源清单yaml文件部署gitlab服务
|
5月前
|
缓存 JavaScript 前端开发
GitLab 官网使用 pages 服务,发布 vue 前端项目
GitLab 官网使用 pages 服务,发布 vue 前端项目
|
7月前
|
存储 Linux 网络安全
Gitlab的基本使用与备份恢复升级
Gitlab的基本使用与备份恢复升级
|
7月前
|
人工智能 IDE Java
IntelliJ IDEA 2023.2正式发布,引入AI助手和GitLab集成,升级你的开发体验!( IDEA 2023.2彻底弃用Struts2,不支持Win7)
IntelliJ IDEA 2023.2正式发布,引入AI助手和GitLab集成,升级你的开发体验!( IDEA 2023.2彻底弃用Struts2,不支持Win7)
176 0
|
7月前
|
存储 Kubernetes Linux
GitLab 最新安装&备份&升级教程(全)
本文介绍了gitlab从安装、升级、备份、恢复一系列操作方法,便于日常更新维护。
249 0
GitLab 最新安装&备份&升级教程(全)
|
7月前
|
Java jenkins 持续交付
服务搭建篇(十) 使用GitLab+Jenkins搭建CI\CD执行环境 (下) 配置整合
上一篇文章搭建了GitLab+Jenkins的基础环境 , 现在基于搭建好的环境快速的实现CI/CD , 接下来需要在Jenkins中配置一个构建任务。
94 0
|
7月前
|
运维 Devops Java
服务搭建篇(九) 使用GitLab+Jenkins搭建CI\CD执行环境 (上) 基础环境搭建
所以 , 在现代化的大型软件项目中 , 对于开发的要求还是比较高的 , 虽然不会要求像运维老哥那样linux命令熟练到起飞 , 精通各种参数调优 , 安全策略 , 但是基础的运行环境运维的操作也是需要了解的 , 这样才能指导运维老哥进行业务环境部署 , 也就是开发运维一体化。虽然现在有很多工具能够帮助开发人员减少一些复杂的操作,但是开发人员还是需要更多的接触运维的工作
139 0