本人使用routeos ovn客户端,并打算使用openwrt 的ovn 连接,结果遇到了加密算法不兼容的问题,而且报错也比较隐晦,很难从里面发现信息。
先看一眼报错信息
Server
duplicate packet, dropping
TCP connection established from xxx
duplicate packet, dropping
TCP connection established from xxx
duplicate packet, dropping
TCP connection established from xxx
... 无限重试、循环
Client
可以看到报错信息:
Connection reset, restarting [0]
TCP/UDP: Closing socket
SIGUSR1[soft,connection-reset] received, process restarting
Restart pause, 5 second(s)
注意报错信息出现的时机,实在TLS校验完成后报错,且不含关键信息
配置详情
RourterOS Ov9n Server
OperWRT Ov9n Client
注意对比Server 和Client的关键信息,看看哪部分不一致,或者哪一部分缺失了
再补充一个关键信息,无论用户名和密码设置如何,都会报相同的错误
排错过程
我们大体上定位了错误发生的位置,在TLS校验成功后,且在用户认证之前
通过浏览源码我们发现,这一步其实在进行socks握手 (socks handshake),且报错也是在这个阶段发生的,原因就是socks握手失败了
/openv9n/src/openv9n/socks.c
void
establish_socks_proxy_passthru(struct socks_proxy_info *p,
socket_descriptor_t sd, /* already open to proxy */
const char *host, /* openvpn server remote */
const char *servname, /* openvpn server port */
volatile int *signal_received)
{
char buf[270];
size_t len;
if (!socks_handshake(p, sd, signal_received))
{
goto error;
}
/* format Socks CONNECT message */
buf[0] = '\x05'; /* VER = 5 */
buf[1] = '\x01'; /* CMD = 1 (CONNECT) */
buf[2] = '\x00'; /* RSV */
buf[3] = '\x03'; /* ATYP = 3 (DOMAINNAME) */
len = strlen(host);
len = (5 + len + 2 > sizeof(buf)) ? (sizeof(buf) - 5 - 2) : len;
buf[4] = (char) len;
memcpy(buf + 5, host, len);
int port = port_from_servname(servname);
if (port ==0)
{
msg(D_LINK_ERRORS, "establish_socks_proxy_passthrough: Cannot convert %s to port number", servname);
goto error;
}
buf[5 + len] = (char) (port >> 8);
buf[5 + len + 1] = (char) (port & 0xff);
{
const ssize_t size = send(sd, buf, 5 + len + 2, MSG_NOSIGNAL);
if ((int)size != 5 + (int)len + 2)
{
msg(D_LINK_ERRORS | M_ERRNO, "establish_socks_proxy_passthru: TCP port write failed on send()");
goto error;
}
}
/* receive reply from Socks proxy and discard */
if (!recv_socks_reply(sd, NULL, signal_received))
{
goto error;
}
return;
error:
if (!*signal_received)
{
*signal_received = SIGUSR1; /* SOFT-SIGUSR1 -- socks error */
}
return;
}
可以明显看到报错的位置。
下面通过追踪握手信息发现了异常的地方:
原来这部分握手信息早就打印出来了,通过对比RouterOS的设置返现,没有设置cipher的信息。而由于openwrt使用的Ov9n client版本是2.5.x版本,它客户端默认的cipher就是 AES-256-GCM:AES-128-GCM
,但是这两种算法我们的RouterOS均不支持
所以在握手期间就发生了错误,因为cipher算法不被支持。
所以我们手动在配置文件中添加cipher项目(从2.5文档中来看cipher项目还可以在配置中使用)
改进后的配置:
可以看见新的配置中auth和cipher均对应RouterOS中的配置,再尝试连接
可以看见连接成功建立,但是也会有提示,BF-CBC作为一种加密算法已经过时了,它面临着Sweet32生日攻击,需要注意保护通信的内容,毕竟这是连接到互联网上的vpn环境。所以建议及时更换新的Ov9n Server,以支持更高级别的加密算法。
Ov9n 在国内风评不是很好,但是作为一种企业连接的VPN工具,它的性能和安全性都是非常好的,且有着广泛的兼容环境,非常适合小企业使用,而大中企业可以选择更加高效和安全的硬件级别SSL VPN方案。
排错过程就到这里了,感谢大家观看。
补充信息
现在发现了一个问题,
- 当你的用户名和密码不对时,也会出现该问题。
- 如果在Routeros的用户secret中未指定
Remote_Address
,也会出现问题。