Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

连接有时会在10分钟内掉线 #6

Open
lainme opened this issue Nov 15, 2021 · 17 comments
Open

连接有时会在10分钟内掉线 #6

lainme opened this issue Nov 15, 2021 · 17 comments

Comments

@lainme
Copy link

lainme commented Nov 15, 2021

你好,我最近对hilldust做了一些修改并尝试用来连接公司内网,但发现在我的三台电脑中,只有一个可以持续的保持在线 (CentOS7),另外两台(一台centos7一台centos8)都会在十分钟内掉线。

我最初以为是自己的修改有问题,但使用原本的版本(仅修改了路由设置,和官方客户端的设置一致)也有同样的情况。

我尝试了打印发送和接收的raw data,没得到什么有用的信息,就是突然的服务器就不再返回任何数据了,也没有任何的报错。另外还检查了ip addr, ip route, nmcli conn show tun0的设置,有问题的电脑和没问题的电脑都是一致的,两台centos7上所有其他软件的版本也都一致,不清楚为什么结果这么不同。我还尝试了设置socket的tcp_keepalive,也没有什么用。

咨询了公司的IT,他说公司的VPN也没有什么特殊的连接设置,同帐号多设备登陆是可以的,空闲超过30分钟服务器才会中断。

不知道你有什么建议么?

@lainme
Copy link
Author

lainme commented Nov 15, 2021

很奇怪,我在登入之前有问题的centos7的桌面后,现在这台不掉线了。另一台centos7桌面没有退出,现在远程SSH进入启用hilldust也不掉线。

只有一台远程xrdp进去(没有登陆:0的桌面)的centos8还是会掉。

感觉还是和keepalive之类的东西有关。

@LionNatsu
Copy link
Owner

会不会是新版的网关要求 host_id:str, host_name:str 两个参数填入?

另外建议留意一下这个断线指的是什么引发的,是 tun 被关闭了还是通信连接被 FIN/RST 了?

@lainme
Copy link
Author

lainme commented Nov 15, 2021

我还正在试。我不是很懂网络这方面的,怎么看是tun被关闭了还是被reset了?

@lainme
Copy link
Author

lainme commented Nov 15, 2021

应该不是参数的问题,这个客户端已经很多年不更新了,现在其他两台都没问题,只有centos8的还不行。我明天登陆桌面试试。

@lainme
Copy link
Author

lainme commented Nov 15, 2021

我在centos8的机器上挂了一个chrome后不再掉线了……挂chrome的时候send, recv一直都有数据传输,不挂的话只有我在终端执行ping这类命令的时候才有。

会不会是没有数据的时候send, recv等待时间太久了?

@lainme
Copy link
Author

lainme commented Nov 16, 2021

我在程序里加了一段代码,每隔1分钟用curl请求一次公司的内网网页就不再有掉线问题了。但这个方法不怎么通用,不知道有什么好的办法代替么?ping试过,不能保持连接

@lainme
Copy link
Author

lainme commented Nov 16, 2021

目前是每两分钟向VPN的DNS服务器发送一次DNS请求,效果不错。谢谢~

@lainme lainme closed this as completed Nov 16, 2021
@LionNatsu
Copy link
Owner

如果是这样的话,可能是网络连接设置了一个比较短的超时。

我大概知道问题在哪里了,可能是你的 SSL 端太久没有访问就 timeout 退出了。hilldust.py 的

def inbound_handle():
    while True:
        raw = c.recv()
        platform_linux.write(raw)

def outbound_handle():
    while True:
        raw = platform_linux.read()
        c.send(raw)

这个地方是转发 tun 流量到 SSL 隧道,可能给 c.send 不够勤快。
你可以试试再创建一个线程,循环 sleep 一分钟,就 c.send() 一个人畜无害的 IP 报文进入隧道,类型是 bytes。

我建议用 ICMP Echo,目标地址就随便填一个,TTL 填个位数别让包走出去太远。

@LionNatsu
Copy link
Owner

如果你发现确实能解决问题,建议你开一个 PR 或者重新打开这个 issue,合入一下你的解决方案后再关闭。

@lainme
Copy link
Author

lainme commented Nov 25, 2021

我目前是每两分钟通过subprocess调用nslookup请求一次dns,还是会有掉线的情况,不过一般都能维持一天以上。我可以修改一下提交PR。

@lainme lainme reopened this Nov 25, 2021
@LionNatsu
Copy link
Owner

好的,非常感谢✨

@firemeteorxx
Copy link

我花了点时间对照OpenConnect的代码结构。
里面针对基于ESP的protocol有esp_send_probes() / esp_catch_probes() 回调函数。
看起来这两组回调是用来保活的。而且不同的协议似乎有不同的实现。Lion建议的ICMP包是‘Palo Alto Networks (PAN) GlobalProtect SSL VPN‘的实现方式,而且似乎是一个特殊的包格式。

不知道Hillstone的原版client是采用什么方式来啊保活的...

@firemeteorxx
Copy link

另外,我注意到代码的message-type里包含如下定义:
KEEP_ALIVE = 0x09
这个似乎没有被用到
搜到Junpiter家的keep-alive文档:https://kb.pulsesecure.net/articles/Pulse_Secure_Article/KB26667

@firemeteorxx
Copy link

firemeteorxx commented Dec 15, 2021

从官方windows 客户端里抓了一些信息,其中有keeplive包的内容。
Server的回包看起来都长得一样,但是client的request包的最后4个byte一直变化,没搞明白有什么规律。
edit: 看起来这4个不断改变的字节总是能从前一个发出的packet里找到 (after encap 的版本),虽然位置不太确定。。。

before encap... (44):
00000000: 45 00 00 2c 9c 0f 00 00  20 01 fe c2 00 00 00 00    E..,....  .......
00000010: 00 00 00 00 08 00 5b f0  9c 0f 00 00 00 00 00 00    ......[. ........
00000020: 00 00 00 00 00 00 00 00  00 00 00 00 15 7a 83 27    ........ .....z.'
after encap... (76):
00000000: 08 cf e0 ac 00 00 00 24  37 ab 66 35 15 7a 83 27    .......$ 7.f5.z.'
00000010: 4c 18 1b db d5 28 cf 2d  78 68 c1 d4 e6 a5 44 a0    L....(.- xh....D.
00000020: ac e2 f6 1e 7b e1 b6 df  ed a0 22 b0 7d b8 f6 a7    ....{... ..".}...
00000030: b4 7c a8 fe f4 46 1c 82  2d e4 4f 23 fd 07 14 ae    .|...F.. -.O#....
00000040: 42 c2 85 6b 5f 8e cc 0c  30 e2 88 cd 64 73 68 6c    B..k_... 0...dshl
Encryption time: 0
2021.12.16 00:12:19 LOG_INFO [3996:9896]: Send normal channel keepalive message Thu Dec 16 00:12:19 2021
WaitForMultipleObjectsEx returns 2
TunIoWait: process socket read
Overlapped Received 76 bytes
before decap... (76):
00000000: 7a ad f5 5a 00 00 00 25  c3 34 31 9d 25 cc dc 0c    z..Z...% .41.%...
00000010: 31 4b be b0 53 3f 90 fd  68 fa f6 c8 b0 65 7a 3a    1K..S?.. h....ez:
00000020: 31 bf 55 c0 a9 40 b1 6c  5a 37 6f 7f 2f fe 0f 3f    [email protected] Z7o./..?
00000030: 8f 03 66 90 12 f8 c0 c2  b7 35 81 6e 1d 70 53 9f    ..f..... .5.n.pS.
00000040: b9 b3 79 4b bc 00 14 36  02 16 48 32 61 62 61 03    ..yK...6 ..H2aba.
pad len: 2, next_header: 4
after decap... (44):
00000000: 45 00 00 2c 9c 0f 00 00  20 01 fe c2 00 00 00 00    E..,....  .......
00000010: 00 00 00 00 08 00 5b f0  9c 0f 00 00 00 00 00 00    ......[. ........
00000020: 00 00 00 00 00 00 00 00  00 00 00 00 01 02 02 04    ........ ........
Decryption time: 15
Uncompress start ...
IPCOMP_ERROR_NO_COMPRESS
Uncompress finished ...
2021.12.16 00:12:19 LOG_DEBUG [3996:9892]: RECV keepalive message
2021.12.16 00:12:19 LOG_DEBUG [3996:9892]: RECV MD5 by keepalive message

@firemeteorxx
Copy link

另外,官方客户端的keeplive间隔大致是30秒

@firemeteorxx
Copy link

之前看到的keeplive packet因为长度为44,所以发生变化的部分其实不是有效载荷。找了一个解包网站看了一下格式,发现其实是从0.0.0.0 发往0.0.0.0的ping request,附带16个0的payload。之前lainme说Ping没有效果,不知道是不是因为Ping包里的格式不太符合预期...

@lainme
Copy link
Author

lainme commented Dec 17, 2021

感谢,我最近比较忙,没时间再看这个问题,等我有时间了再试试

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants