mysql被瘋狂攻擊
- 描述問題
- 系統登入不上,因為資料庫的原因
- 分析問題
- mysql資料庫被攻擊了
- 思考如何解決問題
- 啟動mysql,并改密碼
- 修改mysql預設端口
- mysql不對外連接配接
- 開啟防火牆
環境
- 資料庫:Mysql
- 伺服器:Mysql資料庫是在Docker中運作
一、描述問題
系統登入不上,首先先看一下f12調試工具,發現登入接口傳回“登入失敗”。
得知,node後端服務并沒有挂,因為接口可正常傳回資訊,那麼登入失敗有兩種情況:
- ❌ node服務本身出現bug,但之前登入一直用得好好的,可排除。
- ✔️ node服務連接配接的mysql資料庫出現異常,導緻登入失敗。
二、分析問題
于是,我們前往伺服器檢視node服務,究竟是什麼情況?
果然,是mysql資料庫出現異常。
用navicat連接配接一下mysql,發現也連接配接不上。
我們趕緊檢視mysql日志。
mysql資料庫被攻擊了,好小子,還用不同ip來攻擊。
我成功不用寫文章了,一大早來解決問題,還好我那不到10位使用者還沒有起床,幹活吧!
三、思考如何解決問題?
3.1 啟動mysql,并改密碼
我想第一步,肯定是先讓mysql資料庫先正常啟動,并且修改密碼。以此讓程式可正常通路。
密碼最好包含:大小寫字母、數字、特殊字元,長度長點。
3.2 修改mysql預設端口
正常mysql端口都是3306,把預設端口給改了,讓别人去猜去,要計算到底是哪個端口,也是需要時間,起碼可以增加一點點安全性。
3.3 mysql不對外連接配接
像我的mysql資料庫,都是外網是可以直接用工具可以連接配接的,但其實這樣子很不安全,一般公司是不會直接對外開放資料庫,一般都是内網才可連接配接。
于是我們不對外開放資料庫的端口。
那問題來了,我想查資料,怎麼查?
♂️ 你可以在伺服器上查資料呀,但我想說,太麻煩了,而且可視化效果很不友好。
那怎麼辦呢?
這個時候,“隧道”就派上用場了。
相信大家看了圖檔,應該不難猜到“隧道”的作用。
上面我們說把資料庫對應的端口不對外開放,但面臨一個問題,我們自己想通過navicat連接配接查資料,就用隧道的方式,用我本地的端口去映射伺服器的端口,這樣子我們自己的電腦就可以連接配接伺服器裡任意端口服務。
如上圖,伺服器3306端口和我本地的3305端口做映射,這樣子,我在navicat用localhost的3305連接配接,實則是通路我伺服器的3306端口。
還不錯吧,今天又✔️GET到一個技能點了吧。
這招下去,有心人想搞你,又多了一層防護安全罩,别人就算在厲害能拿到你的密碼,也無法遠端連接配接你的資料庫了,更别想瘋狂攻擊你的資料庫了,因為他,根本連接配接不了。
魔高一尺,道高一丈。
四、開啟防火牆
曾想起,公司的防火牆也一直都是關閉狀态的。這可是比較危險的事情。但因為公司做了内網才可連接配接伺服器、服務,那防火牆開不開倒是無所謂了。
那我們的,可基本都是外網的,是以建議還是開啟防火牆,畢竟又多了一層安全保護罩。
友情提示:
以下對沒接觸的朋友,可能了解起來稍微費勁一點,因為用到Linux和Docker,是以稍微複雜一丢丢,小澤已經很大白話給大家講解了,先大概看下去,把流程走通,再了解。
建議先收藏,以後用到,想必就很自然的了解了。
看到這裡的朋友,本身就很棒棒啦!
4.1 Linux開啟防火牆
檢視防火牆狀态:
systemctl status firewalld
複制代碼
inactive表示防火牆為關閉狀态。
開啟防火牆:
systemctl start firewalld
複制代碼
啟動後無任何提示,再次檢視防火牆狀态,可以看到變成active,成功啟動。
關閉防火牆:
systemctl stop firewalld
複制代碼
關閉防火牆也無提示,檢視狀态變成inactive表示成功關閉。
4.2 重新開機防火牆
我們的防火牆已經成功開啟。
防火牆開啟之後,需要重新開機防火牆才可生效。
我們對指定端口服務進行開啟防火牆。
添加:
# --permanent永久生效,沒有此參數重新開機後失效
firewall-cmd --zone=public --add-port=80/tcp --permanent
複制代碼
檢視:
firewall-cmd --zone=public --query-port=80/tcp
複制代碼
删除:
firewall-cmd --zone=public --remove-port=80/tcp --permanent
複制代碼
重新載入:
firewall-cmd --reload
複制代碼
同理,我們服務上需要開放的端口,都添加進去哦。
firewall-cmd --zone=public --add-port=3306/tcp --permanent
8088
8087
9052
9000
...
複制代碼
切記:需重新載入才可生效哦~
4.3 docker容器與linux建立連接配接失敗
現在,我們的資料庫已經開啟防火牆了,來連接配接一下測試一下。
Node服務,連接配接不上mysql了。
4.3.1 Docker容器與目标主機之間因為防火牆的阻攔不能建立連接配接
于是百度了一下報錯,說是:Docker容器與目标主機之間因為防火牆的阻攔不能建立連接配接。
我的mysql是運作在docker上的,是以我們要先讓docker容器與linux建立連接配接。
配置 docker 容器内允許通路外部網絡(需重新開機 firewalld、docker 以生效)
firewall-cmd --permanent --zone=trusted --change-interface=docker0
複制代碼
但運作該語句後,docker容器内無法重新開機。
4.3.2 centos 中,啟用了 firewalld 防火牆,docker 内的容器無法通路外網
docker服務'啟動之後'會自動在'防火牆中添加一些規則',但是'防火牆重新開機之後'經常會導緻docker容器重新開機失敗,需要在'重新開機下docker 服務'就好了。
- ❌ 關閉防火牆(就是為了開啟防火牆,才有這麼多故事,現在讓我關了???)
- ✔️ 将firewalld換成iptables
我們docker重新開機用的是firewalld,結果導緻docker重新開機失敗,于是我們換做iptables來。
安裝iptables-services服務:
#此處可以使用 yum install -y iptables-s* 來查詢以“iptables-s”開頭的安裝包
yum install iptables-services
複制代碼
查詢是否安裝成功
yum list installed | grep iptables*
複制代碼
确認這兩個安裝包均已成功安裝。
啟動iptables服務并設定開機自啟。
systemctl start iptables && systemctl enable iptables
複制代碼
檢視狀态
重新啟動伺服器,檢查設定開機自啟是否生效
service iptables status
複制代碼
4.3.3 linux中用iptables開啟指定端口
centos預設開啟的端口隻有22端口,專供于SSH服務,其他端口都需要自行開啟。
- 修改/etc/sysconfig/iptables檔案,增加如下一行:
-A INPUT -m state --state NEW -m tcp -p tcp --dport 10000 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 10000 -j ACCEPT
複制代碼
重新開機 iptables
service iptables restart
複制代碼
重新開機防火牆,這裡有兩種方式重新開機防火牆
service iptables start
複制代碼
或者用menu-system-administration-firewall ,去添加使用者需要的端口。
- netstat -tanp 去顯示端口狀态
/usr/sbin/lsof -i
複制代碼
- telnet ipaddr port
to check if ip and port is available before making connection.
複制代碼
LINUX通過下面的指令可以開啟允許對外通路的網絡端口:
/sbin/iptables -I INPUT -p tcp --dport 8000 -j ACCEPT #開啟8000端口
/etc/rc.d/init.d/iptables save #儲存配置
/etc/rc.d/init.d/iptables restart #重新開機服務
/etc/init.d/iptables status # 檢視端口是否已經開放
複制代碼
Linux中如何開啟8080端口供外界通路。
- 修改檔案/etc/sysconfig/iptables
[root@bogon ~]# cd /etc/sysconfig
[root@bogon sysconfig]# vi iptables
複制代碼
檔案内容如下,倒數第三行是新加的,目的是對外界開放8080端口
這行文字實際是從上一行拷貝修改而來,在VI中拷貝一行用yy,拷貝多行用yyn,粘貼用p。
- 将iptables服務重新開機
如若不想修改iptables表,可以直接輸入下面指令:
# linux iptables開放端口指令
iptables -I INPUT -p tcp --dport 8080 -j ACCEPT
複制代碼
這方法在後面,經常使用!
✔️ 使用之後,重新開機docker,成功!
4.4 通路linux nginx失敗
因為我們使用了iptables開啟指定端口,并沒有開啟linux端口,是以我們要對其他家端口權限。
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT
service iptables save
複制代碼
Linux通路成功了。
接着我們繼續對3000端口進行開放。
iptables -A INPUT -p tcp --dport 3000 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 3000 -j ACCEPT
複制代碼
發現外網并不能通路3000端口,怎麼回事,上面開放22端口都成功了的呀!步驟一模一樣的。
Nginx上的80端口也通路不了,于是想先試一下80端口先開放出來。
iptables -I INPUT -p tcp --dport 80 -j ACCEPT
複制代碼
80端口成功開放了,也可以通路,神奇的是:3000端口也可通路了。
這就是蝴蝶效應?代碼出bug,明天就好了?
我帶着僥幸的心理、一臉懵逼的心态繼續開放我的服務。
同理啊,像還有前端的nginx、oracle資料庫、java服務等等,這些端口也要做下相應的開啟防火牆端口。
于是我們繼續開放9052。
iptables -A INPUT -p tcp --dport 9052 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 9052 -j ACCEPT
複制代碼
發現開放了,但通路不了,這不就是和3000端口現象一樣嗎?
為什麼3000一開始不行,80開放好了之後,就3000可以了?
細心的我們,想必發現了,因為3000用的是-A,而80是-I(忘記了的朋友,可以往上看看)
遇到drop 後面是不生效的。
是以一開始3000可能是在drop後面,然後80-I插入在前面就改變了他們的排列順序,是以3000可以通路。
是以我9052用-A,不能通路,是因為他插入在後面的,我用-I就可以通路,插在前面才可以。
記得添加端口後,要save儲存一下哦~
4.5 nginx在配置iptables注意問題
通常我們的伺服器為了安全,都不會打開太多端口,隻要需要的時候,才開放端口。
iptables可以很好解決我們的問題,一般步驟:
先儲存我們ssh端口的通路權限,不然會讓我們ssh連結不上。
#我們常用的ssh端口是22,大家要根據實際情況處理。
iptables -I INPUT -p TCP --dport 22 -j ACCEPT
複制代碼
Xshell上檢視ssh端口方法:
關閉所有端口的通路
iptables -P INPUT DROP
複制代碼
打開80端口的通路權限
iptables -I INPUT -p TCP --dport 80 -j ACCEPT
複制代碼
如果ngnix和web伺服器是同一台機器,配置規則ip白名單的轉發,不然會導緻ngnix轉發不成功。
# 192.168.3.24就是本機的ip位址
iptables -A INPUT -p tcp -s 192.168.3.24 -j ACCEPT
複制代碼
這是因為ngnix跟web伺服器同一台機器的iptables預設DROP政策導緻。
小插話:我用的是centos7,然後iptables是版本6的,而firewalld是版本7的。
後記
還好,今天起得早,趕上我那不到10個使用者睡醒之前,把線上音樂可正常通路,讓他們能安心聽歌是我最大的滿足。
經過這件mysql被攻擊事件,我學到了程式的安全性一定一定要做好,也讓大家放心聽歌,隻要我還在,這個線上音樂就不會死!!!
共勉:打擊我的,隻會讓我變得更強。