簡體   English   中英

使用套接字 AF_PACKET / SOCK_RAW 但告訴內核不要發送 RST

[英]Using socket AF_PACKET / SOCK_RAW but tell kernel to not send RST

我的問題在這里已經大致討論過

而 tl;dr 解決方案是:

iptables -A OUTPUT -p tcp --tcp-flags RST RST -j DROP

您可以修改它以僅阻止您正在積極偵聽的端口。
但是正如上面的問題和這里提到的,這些都不是優雅的解決方案。

現在,我真的不在乎事物的優雅。
但我確實在乎學習。 因此,我深入研究了 Linux 源代碼(目前主要對基於 Linux 的機器感興趣)並整理了我認為的socket.bind方法,以便找到與指示“我們”正在積極監視的內核相關的任何內容一個 TCP 端口。

我假設套接字庫通知內核一些特定端口綁定到應用程序的情況,這樣內核就不會自動使用RST數據包響應客戶端連接,提示“連接被拒絕”

但是,我在源代碼中找不到這樣的代碼。
數據包手冊頁也沒有告訴我如何通知內核忽略/接受來自特定端口的數據包。

我有一個非常基本的套接字設置來以混雜模式收聽(這是它自己的故事)

但是,我的問題是,一旦客戶端在任何給定端口上連接 - 內核按預期的方式發送傳入的Ethernet+IP+TCP數據幀 - 但它也會立即發送具有“反向”源和目標的響應端口和RST標志集。 它應該,但不是在我告訴它的特定端口上。 問題是,我如何告訴內核我正在監視特定端口?

一種選擇是(如在其他一些論壇和其他各種 SO 線程中討論的那樣) - 在該端口上創建一個虛擬套接字。

s = socket()
s.bind(('', <port>))

然而,這會導致一系列其他問題(其中一個是這將有一個很快就會被填滿的緩沖區) ,最重要的是,仍然沒有告訴我所有這些魔法是如何發生的。 如果沒有其他方法,上述兩種解決方案是最后的手段,但我覺得我比以往任何時候都更接近,但也比以往任何時候都更難找到解決這個問題的適當方法。

解決方案或提示也可以在C 中,和/或內核模塊,只是為了指示內核所需的信息。 我知道這一切都在內核中發生了,在下面的評論和一個非常感謝的解決方案想法之后,我現在知道沒有用戶空間功能可以解決這個問題。 我可能/輕松地將它移植到 cPython 模塊,或者使用內核模塊/擴展輕松地將它轉換為 Python 代碼。 但是我真的不知道設置這些東西的內核函數在哪里,或者它們叫什么。

我挖得很深,很遠很淺。但似乎沒有其他人需要這樣做。 主要是因為混雜的套接字旨在獲取流量並對其進行分析。 .bind((interface, protocol))也在那里,它面臨着同樣的問題,一種不進入混雜模式而是只接收 TCP 數據包的方法,例如通過執行.bind((interface, 0x0800))

我可能在這里man 7 netdevice了,但也許man 7 netdevice只是給了我一個想法。 我正在嘗試設置SystemTap以檢查調用ioctl()作用以及socket()對象如何請求文件描述符。 可能是關於這一切如何發生的線索。 讓 SystemTap 工作很棘手。

任何人都有任何其他線索如何解決這個問題或以前遇到過這個問題?

附言。 對不起,我問了一個模糊的問題,我不知道這些低級事物的正確術語是什么。 因為他們對我來說很新。

編輯:我可能一直在尋找錯誤的地方bind() ,根據ipv4.af_inet實現,它將嘗試調用套接字bind()函數,但如果沒有,它將嘗試在這里設置很多魔法. 在這里,他們在af_inetaf_inet ,做了很多表垃圾..我仍然沒有找到解決方案,但也許已經邁出了一步......或者最壞的情況是,又一次鵝狩獵。

更進一步, selinux/hooks.c 也包含一些綁定功能。 也許更多的安全相關,但仍然值得我調查。 仍然無法解決這個該死的謎語。

這里的問題是,您正在尋求一種方法來告訴內核實際上“為我做這 100 件事,但忽略這個特定的細節”。 坦率地說,我認為 iptables 的解決方案是最簡單和最干凈的。

但是,另一種選擇是要求內核完成所有其他工作,而是自己承擔更多工作。 具體來說,自己編一個IP地址,然后開始使用。 唯一的缺點是你必須接管內核一直在為你做的另一件重要的事情:響應 ARP(ARP 用於發現擁有給定 IP 地址的站的 MAC [以太網] 地址)。 簡而言之,我建議你:

  1. 在本地子網上選擇一個未使用的 IP 地址。
  2. 組成一個 MAC 地址供您使用。 (並非絕對必要,但可以更輕松地區分“您的”流量。)
  3. 打開原始數據包套接字而不是原始 IP 套接字 ( https://linux.die.net/man/7/packet )。
  4. 編寫並發送 ARP 請求以發現您要發送到的站的 MAC 地址(如果在本地 LAN 上,否則為下一跳 [路由器] IP 地址的 MAC)。
  5. 收到ARP回復,記錄對方的MAC。
  6. 構建您的 SYN 數據包並將其從您自己的 MAC 地址發送到目標站的 MAC。 (使用您選擇的源和目標 IP、端口等)
  7. 偵聽您的 IP 的返回 ARP 並根據需要進行回復。
  8. 接收 SYN+ACK 響應。 由於內核不知道目標 IP 地址(您創建的 IP 地址)屬於您的系統,因此內核不會使用 RST(或其他任何內容)響應 SYN+ACK。
  9. 做你接下來想做的事……

如果您使用的 MAC 地址不是分配給接口的 MAC 地址,則您當然必須進行混雜的捕獲。 這對於原始數據包套接字來說非常典型。 此外,您將為所有流量構建以太網標頭、IP 標頭和 TCP 標頭(嗯,用於 ARP 請求的以太網 + ARP),因此您將學到很多東西。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM