好文章


讓我打開另一道門。


本身對網路不熟,也不懂。大約能看懂4~5成。


謝謝"01"大的分享
平安、健康最重要
今天要開始說如何設定HAProxy來偵測TCP類的port scan。當前的網際網路是以IP為基礎的,在IP上的傳輸協定最常聽到的是TCP與UDP;UDP上也有許多網路服務,如DNS,就是將網域名稱(如mobile01.com)轉換為數字的IP位址。由於UDP無法確保來源IP的正確性,所以不在我的偵測機制內。

首先你需要1台偵測主機,能夠執行Linux,有網路。我大約有24台偵測主機,除了2台實體主機在我家,其他都是從世界各地租來(或免費申請)的VPS;這些主機的記憶體、儲存空間大小各有不同,以下列出我的偵測主機各類硬體資源的最小值,只要大於最小值,應該就可以用來偵測。

1、記憶體:最小的是128MB;
2、儲存空間:最小的是2GB,就是放在我家裡的那兩台,因為主機原本沒有硬碟,我把系統安裝在2GB的USB隨身碟上;
3、網路速度:不必多快,我最慢的一台是位於香港的VPS,網速10Mbps;
4、IP位址:你的偵測主機必須要有獨立的IPv4位址才行。

假設你有台電腦(或VM也成),有128MB記憶體,2GB的硬碟,10Mbps的網路頻寬,有獨立的IPv4位址,偵測主機的硬體環境就解決了。

我說一下在台灣要如何建構網路環境好了,這可能是大家會面臨的問題。去年9月前,我在台灣是沒有偵測主機的,因為台灣的公有雲或VPS太貴了(相對來說);那時我在家是用4G上網,沒有固網,所以也不會有獨立的IPv4位址。

去年10月發現第四台的網路實在太便宜了,我裝了cable;後來就想到何不用這網路偵測殭屍電腦?我向cable業者申請了一個固定IP,直接指到我裝好的偵測主機,結果沒問題,可以用。

通常固網(不管是cable或光世代之類)都是給8個浮動IP,或1個固定IP搭配7個浮動IP,我心想那浮動IP能偵測嗎?我又弄了1台主機;由於我的cable數據機是路由器,也取得一個IPv4的浮動IP,我就將第2台主機設為cable數據機的DMZ主機(有些路由器的類似設定是exposed server),結果也行。

我現在的問題是,那可以把業者給的8個浮動IP都用來偵測嗎?我現在想到的解決方案是:

1、我不可能搞8台電腦來做(電也是要錢的好嗎?),勢必要導入虛擬化環境。我買了台J1900主機,4GB記憶體,64GB的儲存空間,應該能切出8台偵測用的VM。
2、8台VM的網路介面要有各自獨立的MAC位址。然後如果是光世代之類的網路,就每個VM各自用pppoe撥接取得IP位址;如果是cable之類的,就各自用DHCP取得IP。可能有1台VM要用路由器取得的IP來偵測。

以上方案不知行不行?由於以前沒自己切過VM,所以目前在摸索Proxmox的階段。如果有人先試出來,麻煩告訴我是否行得通。

待續。
美軍連茂伊島野火都不救,還指望他來臺海千里送人頭嗎?
解決偵測主機的硬體與網路連接問題後,接著就是安裝HAProxy進行偵測的部分。我的偵測主機都是安裝Debian Linux(7之後的版本)的環境,下面就以我想像中的Mobile01網站主機,說明如何如何設定偵測機制。

據我觀察,Mobile01網站主機至少有兩個對外的網路服務:

1、HTTP(TCP port 80):沒做什麼特別的處理,就是將連線重導(redirect)到HTTPS。
2、HTTPS(TCP port 443):就是我們看到的Mobile01網站。

此外應該還有只對內部工作人員開放的SSH服務;在此我假設SSH被移到TCP port 2020(因為今年是公元2020年)。所以該主機在對外IP(假設是W.X.Y.Z)上會開放3個網路服務,佔用80、443、2020等3個埠號。

請以root身分安裝HAProxy:

apt-get install haproxy

安裝完畢後,HAProxy已經啟動,但我們還須修改其設定檔(我習慣用vi):

vi /etc/haproxy/haproxy.cfg

在設定檔結尾處加入以下設定:

frontend fr_tcp
mode tcp
bind W.X.Y.Z:1-79
bind W.X.Y.Z:81-442
bind W.X.Y.Z:444-2019
bind W.X.Y.Z:2021-10000
log-format %ci:%cp\ =>\ %fi:%fp\ [%t]
default_backend bk_tcp

backend bk_tcp
mode tcp
server www-2 127.0.0.1:2020
上面有4行bind設定,跳過了主機原本使用的3個埠號,涵蓋其他埠號1到10000之間的9997個埠號。log-format指定了須留存的幾種資料,意義如下:

%ci:來源 IP
%cp:來源 IP 的 TCP 網路埠號
%fi:接受連線的偵測主機 IP
%fp:偵測主機接受連線的 TCP 網路埠號
%t:連線日期與時間

bk_tcp定義了HAProxy要將外界連線轉接到內部的後端伺服器資訊。在偵測初期,有無後端伺服器似乎不重要,因為是否被掃描到是由機率決定;但有後端伺服器的話,駭客會覺得此處有網路服務,存在入侵的機會,而找更多殭屍電腦來試探,偵測的效果會更好。

至此HAProxy的設定已修改完成,接下來要讓新設定生效;執行以下指令重新啟動rsyslog與HAProxy:

service rsyslog restart
service haproxy restart

此時執行ss -ln | grep tcp | grep W.X.Y.Z | wc這個指令(統計對外IP W.X.Y.Z上,等待連線的TCP埠號總數)應該會得到非常接近或剛好就是10000的結果,代表HAProxy已經依照設定,在埠號1到10000間的TCP port等待連線。

說明一下ss -ln | grep tcp | grep W.X.Y.Z | wc這個指令:
1、ss指令檢視系統內的網路連線狀況(以前我都是用"netstat","ss"對我是新指令);"ss -ln"列出系統內等待連線(處於"LISTEN"狀態,所以用"l"功能選項)的網路埠號(numeric,所以用"n"功能選項)。
2、grep會將標準輸入(stdin)讀取的資料進行過濾;"grep tcp"代表帶有字串"tcp"的輸入資料會被再次輸出,其他資料則被丟棄,而"grep W.X.Y.Z"代表帶有字串"W.X.Y.Z"(對外IP)的輸入資料會被再次輸出,其他資料則被丟棄。所以經過兩個grep的處理,剩下的資料就是同時有"tcp"與"W.X.Y.Z"的資料。
3、wc(word count)會讀取標準輸入(stdin)的資料,當資料讀光時,輸出總共有多少行資料、多少空格分開的字(word)、及多少字元。

重新啟動後,過一段時間應該就會有外界連線進來;連線記錄在/var/log/haproxy.log內,留存類似以下記錄:

2019-06-16T03:48:46.282268+00:00 testvm haproxy[9544]: A.B.C.D:56670 => E.F.G.H:10006 [16/Jun/2019:03:48:46.281]

這筆記錄顯示在2019年6月16日3點48分左右,位於 IP 位址 A.B.C.D 的連網裝置,經由其 TCP port 56670,主動連線到位於 IP 位址 E.F.G.H 的偵測主機的 TCP port 10006。此處記錄到的來源 IP,A.B.C.D ,就是殭屍電腦的 IP,而它掃描的 TCP網路埠號就是10006。

下次說明如何設定後端伺服器。
美軍連茂伊島野火都不救,還指望他來臺海千里送人頭嗎?
今天要說明上次的/etc/haproxy/haproxy.cfg中的後端伺服器。我先把相關的設定列在下面:
frontend fr_tcp
...
bind W.X.Y.Z:2021-10000
...
default_backend bk_tcp

backend bk_tcp
...
server www-2 127.0.0.1:2020
其實有4行bind設定,不過這裡只列出1行來協助說明。我定義的frontend設定fr_tcp會在TCP port 1到10000間(須排除少數原已使用的埠號)等待連線;一旦有連線進來,預設的後端伺服器(default_backend)是bk_tcp。而bk_tcp則指示HAProxy應該將外界連線導向給位在IP 127.0.0.1的TCP port 2020。

IP 127.0.0.1是一個特殊的IP,代表系統自身,它有個名稱叫loopback address;所有送到這個IP的資料都會被自己收到。這個IP與實體線路無關;就算系統沒有可用的對外連線(沒接網路線、也沒有無線網路),loopback還是可以運作,它的目的是要測試整個網路軟體層(network software stack)是沒問題的。

上次的偵測機制中,我並未設定要在IP 127.0.0.1的TCP port 2020執行的網路服務;這個情況下HAProxy還是可以偵測到一些隨機掃描的殭屍電腦。就好比停一輛車在停車場中,竊車集團的人員會隨機來拉車門;沒設定HAProxy的後端伺服器,就像一輛門拉不開的車,我還是知道隨機拉車門的人是有問題的。

車門拉不開,一切就此結束;如果車門能拉開呢?後續會有什麼差異?竊車集團最終要把車開走,所以是不是要找有技術的人來發動?看是要把電線短接,還是要電子啟動,這都要找更多人來處理;這樣是不是可以找出更多竊車集團的成員?

用同樣的道理來思考,如果我們在IP 127.0.0.1的TCP port 2020提供一個活的連線,對掃描的殭屍電腦來說,這個服務是活的,給它一個“搞不好可以從這裡入侵進去”的感覺,就可以吸引駭客在此投注更多資源;這有兩個好處:

1、偵測到更多殭屍電腦;
2、此處消耗駭客的資源,就可減少駭客對其他系統的攻擊或入侵行為。

我用過兩種方式設定後端伺服器,一種是無法登入的SSH服務,另一種則只是單純消耗殭屍電腦時間的網路服務;明天說說這兩種不同的設定方式。
美軍連茂伊島野火都不救,還指望他來臺海千里送人頭嗎?
我設定的第一種後端伺服器是無法登入系統的SSH服務;其實這就是我先前在#5提到的fake SSH。設定步驟如下:

1、SSH的原始設定檔是/etc/ssh/sshd_config,以root權限先複製一份方便修改:
cp /etc/ssh/sshd_config /etc/ssh/sshd_config_fake

2、編輯/etc/ssh/sshd_config_fake,將有關設定改成以下所示:
Port 2020
ListenAddress 127.0.0.1
LoginGraceTime 10
DenyUsers *
在前面haproxy的設定檔中,後端伺服器的socket是在IP 127.0.0.1的TCP port 2020,所以此處sshd的Port與ListenAddress就依此設定。“DenyUsers *”指示SSH伺服器不接受任何登入帳號;“LoginGraceTime 10”則是設為在成功連線後,若未在10秒鐘內成功登入系統,SSH伺服器就會自動斷線。
3、啟動這個無法登入系統的SSH服務:
/usr/sbin/sshd -f /etc/ssh/sshd_config_fake

我自己透過tail -f /var/log/haproxy.log指令(即時顯示haproxy的記錄資料)觀察,在增加後端伺服器一段時日後,等偵測到的活動比較頻繁後,如果停掉後端伺服器,haproxy輸出記錄就會變少;如果再次啟動後端伺服器,haproxy輸出記錄又會逐漸增多。

下次再說明第二種後端伺服器。

順帶說明一下,127.0.0.1這個IP是系統內的IP位址,外部主機是不能連到其他主機的127.0.0.1。比方說你家有兩台主機,IP分別是192.168.1.10與192.168.1.11,第二台主機(192.168.1.11)是無法連到第一台主機(192.168.1.10)的127.0.0.1。這個特性被用來進行一些資安上的設定,比方說我知道某個網路服務有軟體弱點,不能對外開放,但我的某些應用卻又須使用這個服務,就可將這個有弱點的服務設定在IP 127.0.0.1上提供服務,這樣就只有同一台主機執行的其他軟體能連線,又不至於被駭客藉此入侵系統。
美軍連茂伊島野火都不救,還指望他來臺海千里送人頭嗎?
mobile01_267539 wrote:
我設定的第一種後端伺...(恕刪)

好文章!我沒想到原來127.0.0.1可以這麼用🤔
好文章~‍‍‍‍‍
寶貝:)開心最重要!
上次說明了我設定的第一種後端伺服器,無法登入系統的SSH服務;在說明第二種後端伺服器前,先解釋我為什麼需要第二種後端伺服器:

1、每當有外界連線,SSH就會產生(fork)一個新的process;每個process都需要自己的記憶體空間,直到連線結束才會釋出。如果大量連線湧入,SSH有可能耗盡所有記憶體,導致系統不穩定或效能問題。
2、第一種後端伺服器其實是我當初用的fake SSH,會留存連線相關資訊,以便後續通報。現在所有外界連線都經由HAProxy首先接收,所以並不需要fake SSH的連線記錄;這些記錄反而會佔用大量儲存空間,必須定期刪除,否則可能耗盡儲存空間,衍生其他問題。

第一個問題其實可經由HAProxy的設定解決;HAProxy設定後端伺服器時,可同時指定最高連線數,例如:
    server www-2 127.0.0.1:9504 maxconn 8

結尾的“maxconn 8”,就是設定HAProxy同一時間最多轉接8個外界連線至後端伺服器。如果這時外界還有連線進來,HAProxy會先接受連線,但不進行轉接,等於先在HAProxy那裡等著;等後端伺服器結束先前轉接的連線時,HAProxy才會將等待中的外界連線轉接到後端伺服器。

第二個問題其實只要改rsyslog的設定檔就能解決,也不是太難。

第二種後端伺服器是我用Tcl(Tool Command Language)寫的。首先必須先安裝Tcl:
apt-get install tcl

後端伺服器的script如下(假設存放在junkd.tcl):
proc connDrop {sock} {
after 100
close $sock
after cancel [list close $sock]
}

proc connAccept {sock addr port} {
fconfigure $sock -buffering line
after 10000 [list close $sock]
fileevent $sock readable [list connDrop $sock]
}

socket -server connAccept -myaddr 127.0.0.1 9504
vwait forever
要清楚解釋script如何運作其實有點難,我只能簡單說一下:

1、請看倒數第2行。在IP 127.0.0.1,TCP port 9504處("-myaddr 127.0.0.1 9504")啟動後端伺服器("socket -server");當外界連線進來時,呼叫程序connAccept(參數:connAccept)。
2、請看proc connAccept的定義。呼叫connAccept時,Tcl會提供3個參數:連線對應的socket、來源IP(addr)、來源TCP埠號(port)。由於此服務位於IP 127.0.0.1,只有內部程序才能連接,所以來源IP(應該也是127.0.0.1)與來源TCP埠號都沒有留存的必要。當connAccept被呼叫,10秒鐘後會自動結束("after 10000 [list close $sock]";10000的單位是毫秒,也就是千分之一秒)。如果socket有可讀取的資料("fileevent $sock readable"),則呼叫程序connDrop。
3、proc connDrop的主要工作是:等待0.1秒("after 100")後結束連線("close $sock"),所以每秒最多處理10次連線;我用延遲回應的方式控制junkd.tcl每秒的處理次數(同時連線數8乘以每個連線每秒可處理10次=80),避免HAProxy記錄太多資料,耗盡儲存空間。

script其他太細微的部分我就不解釋了。啟動junkd.tcl的指令為:
nohup nice tclsh junkd.tcl > /dev/null 2>&1 &

主要執行的指令是"tclsh junkd.tcl";前("nohup")後("> /dev/null 2>&1 &")是將此程序移到背景執行,"nice"則是降低此程序的執行優先權,避免在資源不足時與其他程序搶CPU。

Tcl處理網路連線並不產生新process,也不留存任何連線資訊,所以不會有fake SSH的那兩個問題。

後端伺服器就說明到此;下次談談別的。
美軍連茂伊島野火都不救,還指望他來臺海千里送人頭嗎?
殭屍電腦偵測機制上路後,接下來就該統計每天的殭屍電腦IP資料;不過我先補充說明兩件事。

第一件事。依照前面我介紹的方法安裝HAProxy,其實系統會每天自動輪替產生(rotate)新的記錄檔(在/var/log/路徑下的haproxy.log);預設會保留52個記錄檔,最新的記錄檔名是haproxy.log,前一天則為haproxy.log.1,再往前則遞增結尾的數字並以gzip壓縮,例如haproxy.log.2.gz。

不過Debian系統預設的每日例行作業輪替時間是6點25分,這樣記錄檔會有兩天的記錄混在一起(前一天6:25以後的資料與第二天6:25之前的資料),資料處理會比較麻煩;這可以透過修改crontab的每日例行作業輪替時間來解決。以root身份編輯/etc/crontab,找到以下這一行:
25 6     * * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
把開頭的兩個數字改成0:
0 0     * * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
儲存檔案;之後haproxy的記錄檔就會是每天一個檔案。

第二件事。我在#13所列的一筆偵測記錄
2019-06-16T03:48:46.282268+00:00 testvm haproxy[9544]: A.B.C.D:56670 => E.F.G.H:10006 [16/Jun/2019:03:48:46.281]
記錄開頭的日期時間並非系統預設的如下格式(只有月、日、時間,無年份):
Mar  4 16:26:34 debian systemd[1]: Reloading.
英文月份並不好處理。要改成#13的那種記錄時間,可以root身份編輯/etc/rsyslog.conf,將下列設定:
$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat
前頭加上“#”,如下:
# $ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat
並下指令重新啟動rsyslog:
service rsyslog restart
即可。

以下說明統計殭屍電腦IP的指令。先列出記錄樣本:
2019-06-16T03:48:46.282268+00:00 testvm haproxy[9544]: A.B.C.D:56670 => E.F.G.H:10006 [16/Jun/2019:03:48:46.281]
殭屍電腦的IP,A.B.C.D是以空白隔開的第4個欄位,後面緊接著一個“:"與來源TCP埠號。我現在要產生一個檔案,每行資料包含一個殭屍電腦IP(在第2個欄位)與其嘗試的連線次數(在第1個欄位);欄位間以空白隔開,並以連線次數遞減的方式來進行資料排序。所需指令如下:
grep ' => ' /var/log/haproxy.log | grep '^2019-06-16' | awk '{ print $4; }' | sed -e 's/:.*$//' | sort | uniq -c | sort -nr > /tmp/tmp1.txt
各指令使用UNIX的pipe功能進行串連;“|”左邊指令的標準輸出資料會成為“|”右邊指令的標準輸入資料。以下逐個指令進行說明:
1、第1個grep指令:輸出/var/log/haproxy.log內,帶有‘ => '字串(一共4個字元,前後有空格)的資料記錄;
2、第2個grep指令:讀取標準輸入資料,輸出以字串'2019-06-16'開頭("^"代表一行資料的開頭)的資料記錄。如果記錄有’2019-06-16'的字串,但不是在開頭出現,則不會被輸出;
3、awk指令:讀取標準輸入資料,輸出以空白隔開的第4個欄位(即記錄樣本的"A.B.C.D:56670");
4、sed指令:讀取標準輸入資料,刪除冒號及其後字元(即記錄樣本的":56670")後輸出(即記錄樣本的"A.B.C.D",殭屍電腦IP);
5、第1個sort指令:讀取標準輸入資料(殭屍電腦IP),排序後(相同的IP會在一起)輸出;
6、uniq指令:讀取標準輸入資料(殭屍電腦IP),統計相同資料的出現次數(殭屍電腦IP連線次數),輸出出現次數與原始資料(殭屍電腦IP);
7、第2個sort指令:讀取標準輸入資料,依照第1個欄位(殭屍電腦IP連線次數)的數值(選項"n")以遞減排序(選項"r")後輸出到/tmp/tmp1.txt。

統計偵測到多少個殭屍電腦IP的指令:
wc -l /tmp/tmp1.txt
只列出殭屍電腦IP清單的指令:
awk '{ print $2; }' /tmp/tmp1.txt

今天就寫到這裡。
美軍連茂伊島野火都不救,還指望他來臺海千里送人頭嗎?
基本上利用HAProxy偵測殭屍電腦的要點都已經介紹得差不多,其他細節並不容易說明,除非有實際的例子。所以我有個想法。

如果有人想照我的法子來偵測殭屍電腦,可是擔心建置時遇到不知如何解決的問題,我可以從旁協助。不過你要先準備好一台乾淨的Debian Linux主機,並具有一個對外IP;如果你的Linux主機是放在家裡,經由IP分享器連上Internet,這或許也可以,不過具體如何做,要看分享器是否提供DMZ或exposed server的設定功能,不見得一定成。

我建議的處理方式是這樣。你用SSH登入Linux主機,然後利用類似線上語音會議(非視訊會議)的方式分享你的SSH畫面;在看得到你下指令與輸出畫面的狀況下,經由語音交談,我們合作在你的主機建置偵測機制,並共同解決中間遇到的問題。整個過程如果順利,希望不會超過30分鐘。

目前我想到的線上語音會議服務是roundee.io;老實說我也剛開始了解這個服務。基本上它不須安裝軟體,只要用Chrome瀏覽器開啟會議室的URL即可,且可多人(至多6人)與會;它也提供online chat的功能,在修改設定時應該用得上。

如果有興趣找我從旁協助,就發私訊過來,並說明:

1、你對Linux的熟悉度(可分為:會登入系統、會編輯檔案、會啟動/停止系統服務等幾個階段;從沒用過Linux的人請先自行裝一台Linux再説);
2、Linux主機的Debian版本與系統資源(記憶體大小、硬碟大小)等;
3、Linux主機的連網方式。

這部分就先這樣,其他問題遇到再說。

未來我會繼續說明如何進行殭屍電腦通報。
美軍連茂伊島野火都不救,還指望他來臺海千里送人頭嗎?
關閉廣告
文章分享
評分
評分
複製連結

今日熱門文章 網友點擊推薦!