iT邦幫忙

0

Day24 BehaviorGuard:使用 nftables 實作 IP 阻斷與 Response 整合測試

  • 分享至 

  • xImage
  •  

在 Day22,我們使用 SIGTERM 成功終止 Kali Linux 中的測試程序。

Day23 則加入 Response Policy,透過程序白名單、PID、Start Time 與 Executable 等資訊,降低錯誤終止程序的風險。

不過,資安事件的回應方式不只有 Process Termination(程序終止)。

當系統發現可疑的網路連線時,也可能需要透過防火牆阻擋特定 IP,降低攻擊者持續通訊或傳輸資料的機會。

因此,Day24 我們開始實作 Network Blocking(網路阻斷)。

今天主要完成三件事情:

  1. 使用 Linux nftables 真正阻斷指定測試 IP 的封包。
  2. 將封鎖與解除功能整合進 BehaviorGuard 的 Response Engine。
  3. 建立受控自動回應測試,並將執行結果保存到 Response Audit Log。

今天使用的是本機 Loopback 位址 127.0.0.2,目的是驗證防火牆阻斷技術,不會直接封鎖真實外部伺服器。


一、什麼是 Network Blocking?

Network Blocking 是指透過防火牆規則,限制特定網路封包的傳送或接收。

例如,某台 Linux 主機上的程序持續連線到可疑的外部 IP。

資安人員可能希望阻止主機繼續與該 IP 通訊。

Linux 可以透過防火牆機制,根據以下條件判斷封包:

  • Source IP:來源 IP。
  • Destination IP:目的 IP。
  • Protocol:TCP、UDP、ICMP 等網路協定。
  • Port:來源或目的連接埠。
  • Action:接受、拒絕或丟棄封包。

這次我們使用的動作是 DROP。

DROP 的意思是直接丟棄符合條件的封包,不讓封包繼續通過該規則。

nftables 是什麼?

nftables 是 Linux 的封包過濾與防火牆管理機制,能夠透過規則控制網路流量。

它主要包含幾個概念:

名詞 說明
Table 用來組織防火牆規則
Chain 放置規則並指定封包處理位置
Rule 實際的封包比對與處置條件
Hook 指定規則介入封包處理流程的位置
Counter 統計符合規則的封包數量與位元組
Drop 丟棄符合條件的封包

今天我們會建立獨立的 nftables Table,避免清除或覆蓋 Kali Linux 原本的防火牆規則。


二、建立第一個 IP 阻斷測試

首先進入專案:

cd ~/behaviorguard

我們建立:

nano test_day24_block_ip.sh

這次使用的測試 IP 是:

127.0.0.2

它屬於 IPv4 Loopback 範圍,封包會在本機網路堆疊中處理,不需要真正送到外部網路。

測試流程:

Ping 127.0.0.2
       ↓
確認原本可以連通
       ↓
建立 nftables DROP Rule
       ↓
再次 Ping
       ↓
確認封包遭到阻擋
       ↓
移除防火牆規則
       ↓
再次 Ping
       ↓
確認連線恢復

nftables 的核心規則

nft add table ip bg_day24

這行會建立名為 bg_day24 的 IPv4 防火牆表格。

接著建立 Chain:

nft add chain ip bg_day24 output \
'{ type filter hook output priority 0; policy accept; }'

其中:

hook output 代表這條 Chain 會處理本機產生、準備送出的封包。

policy accept 代表這條 Chain 的預設策略為允許,只有符合特定 DROP 規則的流量才會被丟棄。

接著加入封鎖規則:

nft add rule ip bg_day24 output \
ip daddr 127.0.0.2 counter drop

這行才是真正的封包阻斷規則。

各個部分的意義:

指令內容 用途
ip daddr 比對目的 IPv4 位址
127.0.0.2 指定測試目標
counter 記錄符合規則的封包數量
drop 丟棄符合規則的封包

這條規則沒有指定 Port 或傳輸層協定,因此會對符合目的 IPv4 條件的流量進行 DROP,而不只是限制 ICMP。

不過,今天實際驗證的流量只有 ICMP Ping,尚未進行 TCP 或 UDP 的阻斷測試。


三、第一次實際測試結果

完成 Shell Script 後執行:

sudo bash test_day24_block_ip.sh

這次實際取得:

========== Day24 Block IP Test ==========

[TEST 1] Before blocking
[PASS] Target reachable.

[INFO] Firewall rule installed.

[TEST 2] After blocking
[PASS] Connection blocked.

代表封鎖前可以成功 Ping 到測試 IP,但加入防火牆規則後,Ping 無法成功。

接著查看 nftables 規則:

table ip bg_day24 {
    chain output {
        type filter hook output priority filter; policy accept;
        ip daddr 127.0.0.2 counter packets 1 bytes 84 drop
    }
}

這次最重要的資訊是:

counter packets 1 bytes 84 drop

它代表有一個封包符合規則,命中的封包大小總計 84 bytes,且該規則的處置動作為 DROP。

因此,我們不只是看到 Ping 失敗,也能從防火牆 Counter 確認封包確實命中阻斷規則。

最後測試解除封鎖:

[INFO] Test firewall rules removed.

[TEST 3] After restoring
[PASS] Connection restored.

[INFO] Day24 test completed.

這代表移除本次防火牆規則後,測試 IP 可以重新連通。


四、將 Network Blocking 整合進 BehaviorGuard

雖然第一個 Shell Script 已經成功阻斷封包,但它仍然是一支獨立測試程式。

因此,接下來我們將功能改寫成 Python,放入 BehaviorGuard 原本的 response/ 目錄。

新增檔案:

behaviorguard/
└── response/
    ├── engine.py
    ├── policy.py
    ├── network_blocker.py
    ├── auto_response.py
    └── audit_logger.py

1. 建立 Network Blocker

新增:

nano response/network_blocker.py

這個模組負責呼叫 nftables 指令。

核心程式如下:

import subprocess
import ipaddress

TABLE = "bg_day24"
TEST_IP = "127.0.0.2"

def run_nft(*args):
    return subprocess.run(
        ["nft", *args],
        capture_output=True,
        text=True,
        check=True,
        timeout=5
    )

這裡利用 Python 的 subprocess.run() 執行 Linux 指令。

其中:

  • check=True:執行失敗時產生例外。
  • capture_output=True:取得指令輸出。
  • timeout=5:限制指令等待時間。

接著建立 IP 驗證功能:

def validate_target(ip, authorized):
    if not authorized:
        raise PermissionError("Authorization required")

    parsed = ipaddress.ip_address(ip)

    if str(parsed) != TEST_IP:
        raise ValueError("Only 127.0.0.2 is allowed")

    return str(parsed)

這次只允許 127.0.0.2 進入測試流程。

如果輸入其他 IP,就拒絕執行。

這是為了避免測試過程中誤封正常使用的 DNS、Gateway 或外部服務。

2. 建立 Block 與 Unblock 功能

Network Blocker 分別提供:

block_ip(ip, authorized=False)

以及:

unblock_ip(ip, authorized=False)

前者負責建立 nftables 阻斷規則,後者負責移除本次建立的測試表格。

另外,也建立:

is_reachable(ip)

利用 Ping 檢查目標是否可以連通。

需要注意,Ping 失敗不一定代表防火牆成功封鎖,因此仍然需要搭配規則與 Counter 進行確認。


五、將 Network Blocker 接入 Response Engine

完成 network_blocker.py 後,我們修改原本的:

response/engine.py

新增:

def handle_network_response(ip, action, authorized=False):

這個函式會根據 Action 呼叫不同的處置功能。

核心邏輯如下:

if action == "BLOCK":
    result = block_ip(ip, authorized=authorized)

elif action == "UNBLOCK":
    result = unblock_ip(ip, authorized=authorized)

else:
    print("[DENIED] Unsupported action")
    return False

這樣 Network Blocking 就不再只是獨立的 Shell Script,而是正式成為 BehaviorGuard Response Engine 可以呼叫的功能。

目前 Response Engine 已經包含:

  1. handle_alert():根據 Severity 產生 Dry Run 建議。
  2. terminate_test_process():受控程序終止。
  3. handle_network_response():受控 IP 封鎖與解除。

這些功能都在同一個 Response 模組架構內,但正式即時監控流程還沒有直接呼叫真正的阻斷功能。


六、Python Network Response 整合測試

接著建立:

nano test_day24_network.py

測試流程包含:

  1. 確認測試 IP 可以連通。
  2. 透過 Response Engine 執行 BLOCK。
  3. 驗證連線無法成功。
  4. 透過 Response Engine 執行 UNBLOCK。
  5. 驗證連線恢復。

執行:

sudo env PYTHONPATH=. python3 test_day24_network.py

實際測試結果:

========== Day24 Integration Test ==========

[TEST 1] Before blocking
[PASS] Target reachable.

[TEST 2] Block IP

========== BehaviorGuard Network Response ==========
Target IP  : 127.0.0.2
Action     : BLOCK
Mode       : CONTROLLED TEST
[BLOCK] 127.0.0.2
Executed   : True
====================================================

[PASS] Connection blocked.

之後再次查看 nftables:

table ip bg_day24 {
    chain output {
        type filter hook output priority filter; policy accept;
        ip daddr 127.0.0.2 counter packets 1 bytes 84 drop
    }
}

接著解除阻斷:

[TEST 3] Unblock IP

========== BehaviorGuard Network Response ==========
Target IP  : 127.0.0.2
Action     : UNBLOCK
Mode       : CONTROLLED TEST
[UNBLOCK] 127.0.0.2
Executed   : True
====================================================

[TEST 4] Verify restoration
[PASS] Connection restored.

[INFO] Day24 integration test completed.

這次確認 Python Response Engine 可以透過 Network Blocker 真正執行 nftables 操作,並完成封鎖與解除。

最後使用:

sudo nft list table ip bg_day24

顯示:

Error: No such file or directory

因為本次測試的防火牆表格已被刪除,所以這個結果符合預期。


七、建立 Auto Response 與 Audit Log

完成 Python Network Blocking 後,我們再加入兩個功能:

  • response/auto_response.py
  • response/audit_logger.py

1. Auto Response Dispatcher

這個模組負責接收測試 Alert,檢查規則和目標是否符合條件,再呼叫 Response Engine。

例如:

PROCESS_RULE = "BG-TEST-PROC-001"
NETWORK_RULE = "BG-TEST-NET-001"
TEST_IP = "127.0.0.2"

這裡刻意使用測試專用的 Rule ID,避免直接將真實 Detection Rule 與阻斷操作連接。

例如:

def auto_block_network(alert):
    rule = alert.get("rule", "UNKNOWN")
    ip = alert.get("dst_ip")

    if rule != NETWORK_RULE or ip != TEST_IP:
        log_response(
            rule,
            "BLOCK",
            ip,
            "DENIED",
            "Unapproved test target"
        )
        return False

如果 Rule ID 或 IP 不符合測試條件,就不允許執行封鎖。

通過檢查後,才呼叫:

handle_network_response(
    ip,
    "BLOCK",
    authorized=True
)

這裡的 authorized=True 仍然只是測試程式內部的授權參數,不是真正的使用者權限驗證。

2. Response Audit Log

之前的 Alert Logger 主要記錄 Detection Alert。

但如果 Response Engine 真正執行過終止或封鎖,就還需要另外保存處置紀錄。

因此我們建立:

logs/responses.jsonl

並使用 log_response() 儲存:

record = {
    "timestamp": datetime.now(
        timezone.utc
    ).isoformat(),
    "rule": rule,
    "action": action,
    "target": str(target),
    "status": status,
    "reason": reason
}

這樣日後就能查詢系統曾經執行哪些處置、目標是誰,以及處置是否成功或遭到拒絕。


八、Auto Response 整合測試

最後建立:

nano test_day24_auto_response.py

這次測試包含三個主要情境。

測試一:受控程序自動終止

測試程式先建立真正的 sleep 60 子程序,再取得它的 PID 與程序身分。

如果符合測試規則,就產生一筆測試 Alert,交給 Auto Response Dispatcher。

實際結果:

[TEST 1] Automatic Process Response
[DETECTION] Test process PID: 2814072

========== BehaviorGuard Termination ==========
[POLICY] ALLOW: Policy and identity verified

PID        : 2814072
Action     : Process Termination
Mode       : CONTROLLED TEST
Executed   : True
Result     : Process exited

[AUDIT] TERMINATE -> SUCCESS
[PASS] Automatic test process termination.

這次透過測試專用的事件判斷,成功呼叫 Day23 的 Response Policy,並真正終止測試程序。

但這筆事件不是由正式 Process Monitor 的惡意行為規則產生,因此還不能視為實際攻擊自動防禦。

測試二:受控網路事件自動封鎖

接著建立測試專用 Network Alert:

network_alert = {
    "rule": "BG-TEST-NET-001",
    "severity": "HIGH",
    "dst_ip": "127.0.0.2"
}

Dispatcher 檢查後,呼叫真正的 Network Response。

實際結果:

[TEST 2] Automatic Network Response
[DETECTION] Controlled network test event

========== BehaviorGuard Network Response ==========
Target IP  : 127.0.0.2
Action     : BLOCK
Mode       : CONTROLLED TEST
[BLOCK] 127.0.0.2
Executed   : True

[AUDIT] BLOCK -> SUCCESS
[PASS] Automatic test IP blocking.

之後測試解除:

[UNBLOCK] 127.0.0.2
Executed   : True

[AUDIT] UNBLOCK -> SUCCESS
[PASS] Network connection restored.

代表受控測試事件已經能夠透過 Response Dispatcher,觸發實際的 nftables 封鎖及解除操作。

測試三:拒絕不允許的 IP

最後測試輸入:

{
    "rule": "BG-TEST-NET-001",
    "severity": "HIGH",
    "dst_ip": "8.8.8.8"
}

實際結果:

[TEST 3] Unauthorized Target

[AUDIT] BLOCK -> DENIED
[PASS] Unapproved IP denied.

代表即使 Rule ID 符合測試規則,只要目標 IP 不在允許範圍內,系統仍然會拒絕封鎖。

這次並沒有真的封鎖 8.8.8.8。


九、確認 Response Audit Log

完成測試後,執行:

sudo tail -n 5 logs/responses.jsonl

這次實際產生四筆處置紀錄:

Action Target Status
TERMINATE PID 2814072 SUCCESS
BLOCK 127.0.0.2 SUCCESS
UNBLOCK 127.0.0.2 SUCCESS
BLOCK 8.8.8.8 DENIED

其中一筆實際 JSONL:

{
  "timestamp": "2026-10-15T03:28:07.541029+00:00",
  "rule": "BG-TEST-NET-001",
  "action": "BLOCK",
  "target": "127.0.0.2",
  "status": "SUCCESS",
  "reason": "Connectivity blocked"
}

實際儲存時,每筆紀錄都是一行 JSON。

另外,我們再次確認:

sudo nft list table ip bg_day24

結果顯示:

Error: No such file or directory

這表示本次測試表格已經清除,沒有留下該表格的封鎖規則。


十、今天實際完成的功能與限制

經過今天的實作,目前 BehaviorGuard 已經有以下受控 Response 功能:

功能 測試結果
使用 nftables 阻斷指定測試 IP 成功
驗證 DROP 規則命中封包 成功
透過 Python Response Engine 執行 BLOCK 成功
解除封鎖並恢復連線 成功
測試事件觸發 Process Termination 成功
測試事件觸發 Network Blocking 成功
拒絕未允許的目標 IP 成功
保存 Response Audit Log 成功

不過,目前還有幾個重要限制。

第一,尚未連接正式的即時 Network Detection。

今天使用的是測試專用事件,還沒有讓正式的 BG-NET 偵測規則自動觸發封鎖。

第二,目前只允許封鎖 127.0.0.2。

這是為了降低誤封正常網路服務的風險,尚未建立完整的外部 IP 白名單、Gateway 與 DNS 保護機制。

第三,尚未實作限時封鎖。

目前透過測試程式主動解除封鎖。如果程式在處置過程中異常終止,仍可能需要人工清理防火牆規則。

第四,尚未測試 TCP、UDP 與特定 Port 的阻斷效果。

今天主要透過 ICMP Ping 與 nftables Counter 驗證阻斷。

第五,Audit Log 仍是基本版本。

目前已能保存處置時間、對象、動作與結果,但尚未具備完整的事件 ID 關聯、防竄改與集中式管理。


十一、今日心得

Day24 讓我更了解 Network Blocking 並不是單純執行一條防火牆指令。

一開始,我們先透過 Shell Script,確認 Linux nftables 能夠真正阻斷 127.0.0.2 的測試封包。

但後來發現,雖然測試成功,功能卻還沒有成為 BehaviorGuard Response Engine 的一部分。

因此,我們進一步將 nftables 操作封裝成 Python 模組,讓 Response Engine 可以直接呼叫 Block IP 和 Unblock IP。

接著又加入 Auto Response Dispatcher 與 Response Audit Log,讓受控測試事件可以自動進入處置流程,並保存每次執行的結果。

這次比較重要的收穫,是了解到真正的 Response 不應該只有「執行阻斷」,還需要確認阻斷有沒有成功,以及如何安全解除。

例如,今天透過 nftables Counter 確認封包命中 DROP 規則,再透過解除封鎖後 Ping 恢復的結果,驗證網路連線已恢復。

另外,測試中也加入了目標 IP 限制,確認不允許的 IP 即使被傳入 Response Dispatcher,也不會直接遭到封鎖。

不過,目前的 BehaviorGuard 還沒有完成正式 Detection Pipeline 與實際自動阻斷的整合,因此不能宣稱已經具備完整的自動化網路防禦能力。

下一篇 Day25,我們預計整合正式的 Detection Pipeline 與 Response Dispatcher,讓 Detection、Correlation、Response Policy 和 Audit Log 能夠在同一條事件處理流程中運作。

未來也會持續加強 Network Response Policy,例如 IP 白名單、限時封鎖、Protocol / Port 過濾,以及更完整的處置紀錄。


圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言