【发布时间】:2017-07-10 21:04:00
【问题描述】:
我的机器设置了一个正在运行的 VPN 客户端,并希望通过 VPN 隧道或通过指定套接字上的绑定地址直接通过本地接口连接到 Internet 中的主机。考虑以下代码示例:
import socket, subprocess, re
def get_ipv4_address():
ifc_resp = subprocess.Popen(["ifconfig"], stdout=subprocess.PIPE).communicate()
patt = re.compile(r'inet\s*\w*\S*:\s*(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})')
return patt.findall(ifc_resp[0])
def check_sock(addr):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((addr, 0))
s.connect(("www.google.com", 80))
s.close()
def main():
addrs = sorted(a for a in get_ipv4_address() if not a.startswith("127.0."))
print "Checking addresses " + ", ".join(addrs)
for addr in addrs:
print "Connecting via " + addr
check_sock(addr)
main()
当我运行它时,可以通过 VPN IP 地址毫无问题地建立连接。虽然程序在连接时挂起连接到本地网络:
>>> python binddemo.py
Checking addresses 10.200.195.233, 192.168.2.33
Connecting via 10.200.195.233
Connecting via 192.168.2.33
^CTraceback (most recent call last):
File "binddemo.py", line 22, in <module>
main()
File "binddemo.py", line 20, in main
check_sock(addr)
File "binddemo.py", line 12, in check_sock
s.connect(("www.google.com", 80))
File "/usr/lib/python2.7/socket.py", line 228, in meth
return getattr(self._sock,name)(*args)
KeyboardInterrupt
我不明白为什么会这样,因为本地 NIC 仍应正确设置路由以连接到互联网:
>>> ip route
default via 10.200.195.1 dev tun0 proto static metric 50
default via 192.168.2.1 dev wlan0 proto static metric 600
10.200.195.0/24 dev tun0 proto kernel scope link src 10.200.195.233 metric 50
62.113.253.4 via 192.168.2.1 dev wlan0 proto static metric 600
169.254.0.0/16 dev wlan0 scope link metric 1000
192.168.2.0/24 dev wlan0 proto kernel scope link src 192.168.2.33 metric 600
指定到普通 IP 地址(而不是 google 主机)的连接同样失败,所以我想这不是 DNS 查找造成的问题。任何想法如何解决或至少进一步调查?
【问题讨论】:
-
用任何网络/子网范围划分专用网络接口。
标签: python linux sockets networking openvpn