TCP打孔问题

9 投票
1 回答
3344 浏览
提问于 2025-04-18 03:57

我尝试用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数据包在两个方向上都在传输:

Wireshark捕获

但是什么都没有打印出“连接成功!”我到底哪里出错了呢?

1 个回答

6

答案其实很简单:如果数据包不是发往同一个IP地址,就不会被认为是RELATED的!

bind的部分改成

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

(这里的''是绑定到回环地址)就能完全解决这个问题。

撰写回答