【问题标题】:Problems with TCP hole punchingTCP打孔的问题
【发布时间】:2014-06-08 14:38:42
【问题描述】:

我尝试使用this article 中概述的原则在 Python 3 中为防火墙编写一个基本的 TCP 打孔器。不过,我无法连接任何东西。代码如下:

#!/usr/bin/python3

import sys
import socket
import _thread as thread

def client():
    c = socket.socket()

    c.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    c.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)

    c.bind((socket.gethostbyname(socket.gethostname()), int(sys.argv[3])))
    while(c.connect_ex((sys.argv[1], int(sys.argv[2])))):
        pass
    print("connected!")
    thread.interrupt_main()

def server():
    c = socket.socket()

    c.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    c.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)

    c.bind((socket.gethostbyname(socket.gethostname()), int(sys.argv[3])))
    c.listen(5)
    c.accept()
    print("connected!")
    thread.interrupt_main()

def main():
    thread.start_new_thread(client, ())
    thread.start_new_thread(server, ())

    while True:
        pass

if __name__ == '__main__':
    main()

我决定在本地机器上尝试打孔器,这样我就可以捕获两个实例发送的所有流量。我先设置了一个环回防火墙:

iptables -A INPUT -i lo -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -i lo -j DROP

然后我启动了两个脚本副本:

left$ ./tcphole.py localhost 20012 20011

和

right$ ./tcphole.py localhost 20011 20012

我可以根据 Wireshark 看到 SYN 数据包是双向传输的:

但从来没有打印过“已连接!”我做错了什么?

【问题讨论】:

  • 等等,您的防火墙规则(特别是规则#2)不会丢弃lo 上的传入SYN 数据包吗?您的示例中没有“已建立”或“相关”连接,对吧?
  • 是的,这正是我想要解决的问题。 (在这种情况下,防火墙是对手。)标识为 RELATED 的 SYN 数据包应该可以通过。
  • 感谢您提出的最完整、最清晰的问题之一。 (+1)
  • 哈哈,谢谢!我总是在问之前尝试彻底解决问题,所以我看起来不像个白痴。有时我最终看起来像个白痴,但你只能做这么多。
  • 我可能遗漏了一些明显的东西,但我并不完全清楚您为什么期望这些 SYN 数据包被识别为 RELATED。

标签: python sockets tcp hole-punching


【解决方案1】:

答案很简单:如果数据包没有到达相同的 IP 地址,则不会将它们视为 RELATED!

将bind 行更改为

c.bind('', int(sys.argv[3])))

('' 绑定到环回地址)完全解决了这个问题。

【讨论】:

    猜你喜欢
    • 2012-02-07
    • 2016-12-05
    • 2011-09-19
    • 2014-03-08
    • 2017-01-25
    • 2019-04-11
    • 2015-02-10
    • 1970-01-01
    • 2014-12-28
    相关资源
    最近更新 更多