使用 Docker 和 Traefik 搭建 GitLab(後篇)

本文使用「署名 4.0 國際 (CC BY 4.0)」許可協議,歡迎轉載、或從新修改使用,但須要註明來源。 署名 4.0 國際 (CC BY 4.0)html

本文做者: 蘇洋git

建立時間: 2019年04月10日 統計字數: 7143字 閱讀時間: 15分鐘閱讀 本文連接: soulteary.com/2019/04/10/…github


使用 Docker 和 Traefik 搭建 GitLab(後篇)

前篇文章提到了要介紹一些 GitLab 安全配置上的問題,本篇文章就來簡單聊聊如何加固你部署在公網上的 GitLab 代碼倉庫。docker

問題背景

通常來講,咱們建議在內網環境下使用 GitLab 這類包含大量敏感信息,相對大型複雜的軟件,由於網絡的隔離,自然能夠減小許多「可攻擊面」。數據庫

若是須要外部使用,則推薦使用 「專用隧道」 等方式提供定向的流量訪問途徑。編程

前文提到過,此次遇到的訴求偏偏是:安全

  • 不能使用專有的流量隧道
  • 不能搭建在內網,要提供公網訪問方式

不要緊,見招拆招便可。bash

分析攻擊基本面

在暫時不考慮內鬼做祟的狀況下,對應用進行環境加固。能夠先對能夠受到攻擊的場景進行簡單的分類:網絡

  • 系統層(宿主機環境)
  • 網絡層(具有流量交互的場景)
  • 應用層(軟件運行環境、相關配置)
  • 用戶層(軟件使用平常場景)

考慮篇幅、文章針對性兩個緣由,本文重點介紹「應用層」安全加固。app

系統加固

網上關於系統加固的資料有很多,我以前的文章中也有零碎的提過,感興趣能夠自行翻看。爲了方便你進行搜索,這裏簡單提一下常規手段:

  • 針對敏感端口進行日誌審計。
  • 修改系統敏感端口,好比 SSH 端口,並考慮按需開啓。
  • 限制登陸用戶和用戶登陸方式(好比堡壘機、或者祕鑰認證),並建立普通用戶取代 root 進行平常操做。
  • 購買雲安全服務,並對接監控告警。

網絡加固

網絡加固的內容比較雜,咱們從下面五個點展開。

加密流量傳輸

網絡加固這裏有一個簡單原則,除了本機流量外,但凡可使用 SSL 加密的流量,一概使用 SSL 加密模式進行傳輸,包括:

  • 跨主機之間的系統調用
  • 應用和數據庫以前的調用

雖然不進行 SSL 化配置,部署和編碼成本會有所提升,若是機器資源緊張,還可能影響一些性能,而且還可能帶來額外的費用問題:

  • 企業使用的SSL證書按年付費,價格十分昂貴。
  • 不過若是你以爲購買證書費用太太高昂,也可使用自簽名證書來解決問題。

實際上,部署 SSL 所帶來的各類成本放到長期來看,都是能夠忽略不計的一次性投入,可是安全風險問題是基礎和底線,不值得爲此冒險

避免公開的 DNS 解析

提到網絡服務,其中有一點常常被忽略:DNS 解析

若是你的應用只針對少數人提供服務,不妨考慮不在公網 DNS 上進行解析,僅經過綁定 Hosts 提供服務。

配合 Traefik 的服務發現功能,若是對方不知道你的服務域名,即便經過 IP 掃描到你的站點,請求後獲得的結果也只有 404 Not Found

添加網絡請求驗證

上一條措施,不進行公網域名暴露,已經能夠解決一大部分掃描器的嗅探。可是面對有針對性的攻擊,這招就不靈光了。

此時,建議在咱們的 Web 系統前添加一層基礎的用戶驗證:Baisc Auth

使用 Traefik 添加這層驗證很容易,只須要下面兩行簡單的聲明:

- "traefik.gitlab.frontend.auth.basic=${BASIC_AUTH}"
- "traefik.gitlab.frontend.auth.basic.removeHeader=true"
複製代碼

這兩行配置的做用是:

  • 第一行告訴程序,咱們要使用 Basic 認證,認證的用戶名密碼是什麼。
  • 第二行配置則告訴程序,這個認證僅僅在 Traefik 流量進入的時候使用,不要繼續傳遞給應用程序,避免帶來其餘麻煩(好比 Confluence 這類應用會將 HTTP 請求頭中的 authorization 用做系統登陸憑據)。

固然,這裏一樣須要建立一個 .env 環境配置文件,好比:

BASIC_AUTH=soulteary:$apr1$rgGAffTk$vDZ1tL03og0nZ8XlCfdv80
複製代碼

若是你好奇這段代碼是如何生成的,能夠在使用 Docker 搭建 Confluence 這篇文章中找到答案。

下面給出一個相對完整的配置參考:

labels:
      - "traefik.enable=true"
      # GitLab Web 服務
      - "traefik.gitlab.frontend.auth.basic.removeHeader=true"
      - "traefik.gitlab.frontend.auth.basic=${BASIC_AUTH}"
      - "traefik.gitlab.port=80"
      - "traefik.gitlab.frontend.rule=Host:gitlab.${BASEHOST}"
      - "traefik.gitlab.frontend.entryPoints=http,https"
      - "traefik.gitlab.frontend.headers.SSLProxyHeaders=X-Forwarded-For:https"
      - "traefik.gitlab.frontend.headers.STSSeconds=315360000"
      - "traefik.gitlab.frontend.headers.browserXSSFilter=true"
      - "traefik.gitlab.frontend.headers.contentTypeNosniff=true"
      - "traefik.gitlab.frontend.headers.customrequestheaders=X-Forwarded-Ssl:on"
      - "traefik.gitlab.frontend.passHostHeader=true"
      - "traefik.gitlab.frontend.passTLSCert=false"
複製代碼

使用浮動 IP

若是對方不光使用侵入的方式進行攻擊,還想讓你暫時沒法正常使用系統,好比對你進行使人髮指的 DDoS 攻擊。

做爲被攻擊方,可使用 浮動IP 的方式,在遭遇攻擊的時刻,下降切換 IP 的成本,快速金蟬脫殼,這裏配合支持動態加速的 CDN 服務效果更好。

應用層

應用層作的事情也比較雜,咱們來慢慢提及。

用戶側流量加密

建議系統不提供任何 HTTP 流量,防止用戶側流量被劫持利用。

全部出公網流量一概走 HTTPS,若是你也使用前文提到的 Traefik ,那麼這個事情默認就是作好了的(參考剛剛的配置)。

對接 Prometheus 性能監控

若是你對可用性有很高的要求,能夠參考官方文檔,對接 Prometheus 性能監控,若是你對Prometheus沒有概念,能夠先瀏覽一下官方的在線示例,這部分展開聊能夠寫好幾篇,先略過。

處理 CI Runner

CI 雖然做爲呼之即來、揮之即去的「附加部分」,可是實際上也能夠由於「頻繁調用」而拒絕服務,或者由於不恰當的 CI 配置,而泄露敏感信息,或者做爲攻擊跳板,傷害到線上業務代碼。

對於 GitLab CI Runner 運行監控,推薦使用 timoschwarzer/gitlab-monitor ,不過若是你在系統中配置好了推送消息,項目數量比較少的時候,一個手機Push過來,或許更方便迅捷。

對於 CI Runner ,要肯定儘量少的提供 SHELL 模式的 Runner,多提供容器模式的 Runner,減小 Runner 攻擊到宿主機的可能。

另外 Runner 可被觸發的分支和倉庫要作額外的限制,儘量避免過分頻繁的 Runner 執行,讓宿主機器「過勞死」。

最後,Runner 中使用的環境變量和配置信息,須要使用加密環境變量的方式進行獲取,而非明文寫死在配置文件代碼中。GitLab 這部分作的很好,有興趣的小夥伴能夠了解一下。

監控 GitLab SSH 端口

由於咱們對用戶提供了 SSH 的方式去 ClonePush 代碼,因此做爲開放訪問的 SSH 端口就面臨被攻擊的可能。

下面是一臺長期運行在公網的代碼倉庫的端口日誌(cat logs/sshd/current),我節選了比較有表明性的一部分日誌,並隱去了具體時間:

Invalid user admin from 179.53.182.234
Invalid user user from 183.89.94.13
Invalid user admin from 36.236.233.142
Invalid user admin from 143.255.154.219
Invalid user admin from 85.57.5.107
Invalid user ubnt from 85.57.5.107
Invalid user admin from 85.57.5.107
Invalid user admin from 156.223.73.14
Invalid user support from 200.145.6.88
Invalid user admin from 152.231.118.191
Invalid user user from 171.228.172.27
Invalid user admin from 27.66.79.45
Invalid user Admin from 117.0.57.69
Invalid user admin from 14.207.231.218
Invalid user gitlab from 121.71.20.66
Invalid user admin from 183.157.173.121
Invalid user guest from 37.214.104.206
Invalid user admin from 197.32.190.120
Invalid user Administrator from 125.34.196.43
Invalid user Administrator from 125.34.196.43
Invalid user \243\254git from 112.87.206.54
Invalid user \243\254git from 112.87.206.54
Invalid user admin from 116.118.104.96
Invalid user admin from 14.186.202.33
Invalid user admin from 113.172.217.15
....
複製代碼

能夠看到有大量掃描器在默默的替你關注者你的系統安全,絕不誇張的說,一旦你漏出破綻,你的機器、你的應用就不歸你使用了,這類掃描器的擁有者便能光明正大的隨意用你的機器、玩你的系統、欺負你的用戶…

如何避免這類惡意的掃描器呢?其實寫一段簡單的日誌檢測腳本就能解決很大一部分問題。

好比下面這段腳本,在參考 這篇文章 後,我結合實際狀況,更新了它,讓腳本可以處理 GitLab 的日誌格式。

#!/bin/bash 
# 容許錯誤嘗試的最大次數
LIMIT=3
# 要進行分析的日誌文件
SCAN_LOG="/data/gitlab/logs/sshd/current"
# 封禁IP記錄
LOGFILE="/data/gitlab/logs/bad_gay_22_port.log"
# 要匹配的日誌格式: 2019-04-10_12
TIME=$(date '+%Y-%m-%d_%H')

# 掃描當前 GitLab 日誌,找出全部的錯誤登陸行爲,並進行計數,篩選出超過容許次數的 IP
BLOCK_IP=$(grep "$TIME" "$SCAN_LOG"|grep "Invalid user"|awk '{print $(NF-3)}'|sort|uniq -c|awk '$1>"$LIMIT"{print $1":"$2}')
for i in $BLOCK_IP
do
    IP=$(echo $i|awk -F: '{print $2}')
	# 驗證該IP是否已經被封禁
    iptables-save|grep INPUT|grep DROP|grep $IP>/dev/null
	# 若是未被封禁,則進行封禁操做
    if [ $? -gt 0 ];then
        iptables -A INPUT -s $IP -p tcp --dport 22 -j DROP
        NOW=$(date '+%Y-%m-%d %H:%M')
        echo -e "$NOW : $IP">>${LOGFILE}
    fi
done
複製代碼

將上面的內容保存爲 gitlab_ssh.sh ,而後賦予腳本可執行權限。

chmod 755 gitlab_ssh.sh && chmod +x gitlab_ssh.sh
複製代碼

接着將腳本放到 GitLab 應用目錄中(或者任意你方便管理的地方),舉個例子: /data/gitlab/gitlab_ssh.sh

最後將腳本添加到 crontab 中,以10分鐘爲粒度執行 (結合本身狀況進行調整)。

echo "*/10 * * * * root /data/gitlab/gitlab_ssh.sh" >>/etc/crontab
複製代碼

不出意外,日後若是還有這類掃描器,他們最多隻能撲騰個10分鐘左右。

至於這個腳本的戰績,能夠經過查看 /data/gitlab/logs/bad_gay_22_port.log 日誌文件來進行了解:

2019-04-10 19:33 : 113.172.217.15
2019-04-10 19:33 : 14.186.202.33
複製代碼

監控界面登陸

前面已經在網絡層添加了訪問受權,可是若是受權密碼泄露,被針對性攻擊,好比在界面/應用接口層面進行弱口令掃描,那麼又該如何處理呢。

配合 fail2ban 能夠減小這類事情的影響,下面給出一段參考腳本

[Init]
maxlines = 6

[Definition]

# The relevant log file is in /var/log/gitlab/gitlab-rails/production.log
# Note that a single failure can appear in the logs up to 3 times with just one login attempt. Adjust your maxfails accordingly.

## Example fail - clone repo via https
#Started GET "/" for 10.0.0.91 at 2016-10-25 00:01:24 +0200
#Processing by RootController#index as HTML
#Completed 401 Unauthorized in 69ms (ActiveRecord: 23.7ms)

## Example fail - login via GUI
#Started GET "//chmielu/test.git/info/refs?service=git-upload-pack" for 10.0.0.91 at 2016-10-25 00:01:09 +0200
#Processing by Projects::GitHttpController#info_refs as */*
# Parameters: {"service"=>"git-upload-pack", "namespace_id"=>"chmielu", "project_id"=>"test.git"}
#Filter chain halted as :authenticate_user rendered or redirected
#Completed 401 Unauthorized in 50ms (Views: 0.8ms | ActiveRecord: 8.1ms)


failregex = ^Started .* for <HOST> at .*<SKIPLINES>Completed 401 Unauthorized

ignoreregex =
複製代碼

用戶層

用戶層面其實問題很少,若是你能肯定你能夠堅持使用如下措施的話:

  • 關注官方版本更新和 changelog,及時更新應用版本,減小 XSSCVE 漏洞問題。
  • 進行最小權限授予,減小錯誤受權帶來的風險。
    • 在系統設置中設置全部項目都是 private 的,避免某雲平臺的事故重演。
    • 避免添加過多的全局 Admin 角色,針對項目羣組和項目進行管理員設置。
  • 僅容許使用 SSH 方式進行代碼 ClonePush,推薦使用祕鑰認證的方式進行系統交互。
  • 儘量減小與外部系統的交互,好比導入外部倉庫,僅支持你以爲必要的來源;好比服務調用,僅調用你以爲安全可靠的。
  • 關閉默認註冊方式,使用邀請制度,或者使用 SSO/LDAP 方式進行註冊。
  • 根據實際狀況進行用戶頻率限制(系統功能)。
  • 要求你的用戶使用隨機生成的強密碼,並按期更換。

最後

使用容器在公網環境搭建 GitLab 就先介紹到這裏,性能監控部分,等把 WordPress 的坑填完,再細聊吧。


我如今有一個小小的折騰羣,裏面彙集了一些喜歡折騰的小夥伴。

在不發廣告的狀況下,咱們在裏面會一塊兒聊聊軟件、HomeLab、編程上的一些問題,也會在羣裏不按期的分享一些技術沙龍的資料。

喜歡折騰的小夥伴歡迎掃碼添加好友。(請註明來源和目的,不然不會經過審覈)

關於折騰羣入羣的那些事

相關文章
相關標籤/搜索