我正在尝试使用httptunnel
这样的隧道连接:
在服务器上:
sudo hts -F localhost:10000 81
nc -l -p 10000
在客户端:
sudo htc -F 7777 server_ip_address:81
telnet 127.0.0.1 7777
但 telnet 失败:
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
Connection closed by foreign host.
系统日志说:
Nov 6 01:41:37 r1y4n-PC htc[1695]: htc (httptunnel) 3.3 started with arguments:
Nov 6 01:41:37 r1y4n-PC htc[1695]: me = htc
Nov 6 01:41:37 r1y4n-PC htc[1695]: device = (null)
Nov 6 01:41:37 r1y4n-PC htc[1695]: host_name = server_ip_address
Nov 6 01:41:37 r1y4n-PC htc[1695]: host_port = 81
Nov 6 01:41:37 r1y4n-PC htc[1695]: proxy_name = (null)
Nov 6 01:41:37 r1y4n-PC htc[1695]: proxy_port = 8080
Nov 6 01:41:37 r1y4n-PC htc[1695]: proxy_buffer_size = 0
Nov 6 01:41:37 r1y4n-PC htc[1695]: proxy_buffer_timeout = -1
Nov 6 01:41:37 r1y4n-PC htc[1695]: content_length = 102400
Nov 6 01:41:37 r1y4n-PC htc[1695]: forward_port = 7777
Nov 6 01:41:37 r1y4n-PC htc[1695]: max_connection_age = 300
Nov 6 01:41:37 r1y4n-PC htc[1695]: use_std = 0
Nov 6 01:41:37 r1y4n-PC htc[1695]: strict_content_length = 0
Nov 6 01:41:37 r1y4n-PC htc[1695]: keep_alive = 5
Nov 6 01:41:37 r1y4n-PC htc[1695]: proxy_authorization = (null)
Nov 6 01:41:37 r1y4n-PC htc[1695]: user_agent = (null)
Nov 6 01:41:37 r1y4n-PC htc[1695]: debug_level = 0
Nov 6 01:41:49 r1y4n-PC htc[1695]: http_write_request: write error: Invalid argument
Nov 6 01:41:49 r1y4n-PC htc[1695]: couldn't open tunnel: Invalid argument
Nov 6 01:41:49 r1y4n-PC htc[1695]: exit with status = 1
是什么原因造成的http_write_request: write error: Invalid argument
?
我该如何正确地建立隧道连接?
服务器和客户端都Ubuntu 14.04
谢谢
答案1
我怎样才能正确地建立隧道连接?
修复 httptunnel。见下文。
请注意,您正在使用带有错误参数的 nc,但它似乎仍然有效。来自man nc
:
-l 用于指定 nc 应该监听传入连接而不是启动与远程主机的连接。 将此选项与 -p、-s 或 -z 选项结合使用是错误的。
什么原因导致 http_write_request:写入错误:参数无效?
Invalid argument
是字符串化POSIX 错误代码版本艾因瓦尔。
错误代码从写libc 函数/内核系统调用,由 httptunnel 客户端的 http_write_request 函数间接调用。EINVAL 表示:
fd 附加到不适合写入的对象;或者文件是使用 O_DIRECT 标志打开的,并且 buf 中指定的地址、count 中指定的值或当前文件偏移量未适当对齐。
在调用 write() 之前,使用以下配置套接字的各种选项:设置sockoptlibc 函数/内核系统调用。其中一个选项是 SO_SNDLOWAT。您可以阅读它应该做什么这里。 注意:
SO_SNDLOWAT 在 Linux 上不可更改(setsockopt(2) 失败并出现错误 ENOPROTOOPT)
因此,至少截至 2015 年,在 Linux 上进行这样的呼吁是毫无意义的。
运行 htc 后斯特拉斯,我注意到代码和 strace 报告的系统调用参数之间存在不一致。tunnel_out_setsockopts
函数中的代码试图设置 SO_SNDLOWAT 选项,但 strace 报告setsockopt(5, SOL_TCP, TCP_REPAIR, [1], 4) = 0
。仔细看看插座手册页中列出了 SO_SNDLOWAT 作为一个选项,并注意以下几点:
可以使用 setsockopt(2) 设置下面列出的套接字选项,并使用 getsockopt(2) 读取,并将所有套接字的套接字级别设置为 SOL_SOCKET。
tunnel_out_setsockopts
不使用 SOL_SOCKET 作为 SO_SNDLOWAT 选项;get_proto_number
而是使用另一个函数 () 的结果。这是一个错误。这可能是由于与内核或 libc API 的先前版本不一致,但我认为可能性不大。
不幸的是,通过用 SOL_SOCKET 替换套接字级别参数来修复此错误并不能产生可用的隧道。之前失败的写入调用现在成功了,但程序在大约一秒钟后因读取调用出现 ETIMEDOUT 而失败。
还有另一个函数tunnel_in_setsockopts
尝试使用get_proto_numer
SOL_SOCKET 的输出来设置 SO_RCVLOWAT。这是另一个错误。
修复这两个问题可使隧道正常工作。
服务器
nc -l 10000
sudo hts -F 本地主机:10000 81
客户
htc -F 7777 本地主机:81
telnet 本地主机 7777
这个错误已经在 Ubuntu 14.04 中被报告过这里。我建议您将其标记为对您有影响。我已上传补丁来修复该问题,但仍需 Ubuntu 接受。