誰是那些試圖透過SSH非法存取我的伺服器的人?來自哪個國家?
大家好,我是無能。我公開了Vultr的FreeBSD伺服器,很好奇那些試圖透過SSH進行嘗試的人是誰,所以就查看了一下。順帶一提,FreeBSD會將「security run output」發送到我的網域,告訴我有哪些嘗試。
就是這種感覺。那麼,我們就用geoip來看看這些試圖進行嘗試的人的全球IP位址來自哪個國家吧。順帶一提,geoiplookup指令可以這樣安裝:
sudo pacman -S geoip
指令是這個
$ geoiplookup IP位址
GeoIP Country Edition: RU, Russian Federation
使用bash進行文字格式化
那麼,首先將原始資料「security run output」的字串隨意地複製到我的ThinkPad上,然後進行格式化。
cat vultr | grep -oP "from.*port" | awk '{print $(NF-1)}' | sort | uniq > grepip
在上述情況中,我們從名為vultr的「security run output」描述中,使用grep的-o選項匹配值,並使用-P選項的Perl正規表達式,提取從「from」字串到「port」字串的描述。
會變成像下面這樣的字串。
from IP位址 port
此時不使用awk的原因是,如果以空格作為分隔符,當密碼錯誤或伺服器上不存在目標使用者時,錯誤輸出會有所不同,因此我提取了從「from」到「port」的整個字串以捕捉所有情況。接下來,我使用awk提取最後一個記錄中的IP位址,然後使用sort和uniq刪除重複的IP,並將結果寫入名為grepip的檔案中。然後,我們將使用bash對這些IP執行geoiplookup,並進行簡單的國家統計。
$ cat country.sh
#!/bin/bash
# IP位址的檔案
INPUT="grepip"
# 輸出檔案
OUTPUT="countries.log"
# 初始化
> $OUTPUT
# 對每個IP位址執行geoiplookup,取得國家資訊
while IFS= read -r ip; do
geoiplookup "$ip" | awk -F: '{print $2}' >> $OUTPUT
done < "$INPUT"
# 統計並顯示國家資訊
sort $OUTPUT | uniq -c | sort -tr
這樣就賦予了執行權限。
chmod +x ./country.sh
只需執行即可
$ ./country.sh
1 BE, Belgium
1 BG, Bulgaria
1 BR, Brazil
1 CH, Switzerland
1 HK, Hong Kong
1 HU, Hungary
1 IR, Iran, Islamic Republic of
1 IT, Italy
1 LT, Lithuania
1 MT, Malta
1 MX, Mexico
1 MY, Malaysia
1 NO, Norway
1 PA, Panama
1 PE, Peru
1 SE, Sweden
1 SK, Slovakia
1 TH, Thailand
1 TM, Turkmenistan
1 TZ, Tanzania, United Republic of
1 UZ, Uzbekistan
1 ZA, South Africa
2 RO, Romania
2 UA, Ukraine
3 PL, Poland
6 GB, United Kingdom
7 VN, Vietnam
8 CA, Canada
8 ID, Indonesia
9 RU, Russian Federation
9 SG, Singapore
10 FR, France
10 KR, Korea, Republic of
11 DE, Germany
11 NL, Netherlands
16 CN, China
18 IN, India
43 US, United States
哦,原來如此...
使用Matplotlib清晰地顯示圖表
嗯,雖然在字串上可以理解,但當數量變多時會很難看,所以想用圖表顯示對吧?
此外,如果將其腳本化,也可以作為cron作業來生成。因此,我們將使用方便的Python函式庫Matplotlib來顯示圖表。安裝與程式碼:
pip install matplotlib
cat AreYouFrom.py
#!/usr/bin/python3
import matplotlib.pyplot as plt
import collections
# 讀取檔案,按國家統計存取次數
country_counts = collections.Counter()
with open('countries.txt', 'r') as file:
for line in file:
# 取得國家資訊
country = line.strip().split(",")[1]
country_counts[country] += 1
# 排序資料
countries, counts = zip(*country_counts.most_common())
# 建立圖表
plt.figure(figsize=(10, 6))
plt.bar(countries, counts, color='skyblue')
plt.xlabel('Country')
plt.ylabel('Accesses')
plt.title('Accesses by Country')
plt.xticks(rotation=90)
plt.tight_layout()
# 輸出為png圖片檔案
plt.savefig('accesses.png')
這樣就可以輸出圖表和圖片了。
chmod +x AreYouFrom.py
(這檔名真像國中生英文啊!)

登登!看來來自美國的最多。
按嘗試SSH的埠號進行統計
那麼,我們來按嘗試存取的埠號進行調查。
這樣就只grep出了埠號。
cat vultr | grep -oP "port [123456789].*ssh2$" | grep -oP "[123456789].* "
將其輸出為ports.txt。
然而,由於所有埠號都不同,所以在繪製圖表時,我們將它們分成不同的區塊。
$ cat AreYouPort.py
#!/usr/bin/python3
import matplotlib.pyplot as plt
from collections import Counter
# 從檔案讀取埠號
with open('ports.txt', 'r') as file:
ports = [int(line.strip()) for line in file]
# 計算埠號的頻率分佈
counter = Counter(ports)
blocks = {}
for port, count in counter.items():
block = (port // 10000) * 10000
if block not in blocks:
blocks[block] = 0
blocks[block] += count
# 建立圖表
x = list(blocks.keys())
y = list(blocks.values())
plt.figure(figsize=(12, 6))
plt.bar(x, y, width=6000, color='skyblue', edgecolor='black')
plt.xlabel('Port Number')
plt.ylabel('Frequency')
plt.title('Port Numbers by Frequency')
plt.xticks(x, [f'{i}-{i+9999}' for i in x], rotation=45)
plt.grid(True, axis='y', linestyle='--', alpha=0.7)
plt.tight_layout()
# 儲存為PNG檔案
plt.savefig('port_numbers.png')
結果是....

為什麼會有這麼多嘗試使用不可能的30,000以上埠號呢...。那麼今天就到這裡。下次再見了。