前言
多年前就有使用n2n的经验。
记得公司购买的戴尔R720服务器托管到电信机房,该机房启用了代理人防火墙,只有特定IP才能连接进来。
这样是提升了安全性,但对我们来讲,管理维护非常不便。
应对方案,就是安装n2n,电信机房的服务器可以连接到外部中心节点,通过和指定主机组网,方便运维。
当然,n2n是一个非常有用的软件,还可以实现vpn代理,内外穿透等功能,值得一玩。
supernode的安装启动
1 |
|
很不幸,启动后报错,很明显,连不上supernode
1 | 07/Jan/2024 01:20:59 [edge_utils.c:1610] WARNING: supernode not responding, now trying [****] |
为了排查原因,在supernode节点,执行抓包,之后重新启动edge边缘节点,从始至终,没有看到过来访问的数据包。
1 | tcpdump port [supernode-port] |
这就很诡异了,纠结了半天,之后试着改变边缘节点的启动命令
1 |
|
终于找到了原因,这套软件默认使用udp通信,中心节点的防火墙,只开放了对应端口的tcp协议,没有放开udp。
坑啊。。。
到这儿,仍然不能让我满意。
如果使用上面的命令组网,暴露在公网上,安全性太差了。
继续查看软件的说明文档,找到很多有价值的信息,对于提高安全和运行效率很有帮助。
Communities
Communities概念,用来指定虚拟网络,如果有多个网络,指定的名称必须不同。
community名称,由19个字节长度的字符和1个零字符结尾,结尾零字符不能是特殊符号(如 * + ? [ ] 等)。
为了充分利用字符空间,可以使用16进制的表达方式(如启动时使用”edge … -c $(echo -en ‘\x3a\x3b\x4a\x6a\xfa’) …”)。
如果写入配置文件,可以按照格式占位填充(如-c :;Jjþ)。
除了-c启动参数和配置文件,community(团体字)也可以赋值给N2N_COMMUNITY环境变量,以避免在命令行泄露。
写入配置文件,如community.list, 一行配置一个,官方给出示例(可以使用#添加注释)。
使用配置文件时,需增加启动参数 “-c community.list”1
2
3
4
5# community.list (a text file)
-----------------------------------------------------
myCommunity
yourCommunitycommunity名称定义,支持正则表达式。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'.' Dot, matches any character
'*' Asterisk, match zero or more of previous element (greedy)
'+' Plus, match one or more of previous element (greedy)
'?' Question, match zero or one (non-greedy)
'[abc]' Character class, match if one of {'a', 'b', 'c'}
'[^abc]' Inverted class, match if NOT one of {'a', 'b', 'c'} (feature is currently broken)
'[a-zA-Z]' Character ranges, the character set of the ranges { a-z | A-Z }
'\s' Whitespace, \t \f \r \n \v and spaces
'\S' Non-whitespace
'\w' Alphanumeric, [a-zA-Z0-9_]
'\W' Non-alphanumeric
'\d' Digits, [0-9]
'\D' Non-digits下面的配置内容 ,就使用了正则表达。
1
2
3# community.list (a text file)
-----------------------------------------------------
myCommunity\d\d
正常情况下,community的名称由明文传送,仍然可以被嗅探窃取,此时最好打开Header Encryption, 即标头加密。
加密只对写入配置文件的固定名称的community有效(使用正则表达的community除外)。
打开Header Encryption的方式也很简单,在启动命令里,增加”-H”参数。
加密原理
n2n目前支持4种加密方式,均可以在启动命令中指定。
- Twofish in CTS mode (-A2)
- AES in CBC mode (-A3)
- ChaCha20 (CTR) (-A4)
- SPECK in CTR mode (-A5)
Cipher | Mode | Block Size | Key Size | IV length | Speed | Built-In | Origin |
---|---|---|---|---|---|---|---|
Twofish | CTS | 128 bits | 256 bit | 128 bit | -..O | Y | Bruce Schneier |
AES | CTS | 128 bits | 128, 192, 256 bit | 128 bit | O..+ | Y | Joan Daemen, Vincent Rijmen, NSA-approved |
ChaCha20 | CTR | Stream | 256 bit | 128 bit | +..++ | Y | Daniel J. Bernstein |
SPECK | CTR | Stream | 256 bit | 128 bit | ++ | Y | NSA |
启动命令中,-k参数,用以提供秘钥,当然也可以使用N2N_KEY设置在环境变量中。
1 | sudo N2N_KEY=mysecretpass edge -c mynetwork -a 192.168.100.1 -f -l supernode.ntop.org:7777 |
如果提供了秘钥,但没有指定加密方式(-A),则默认使用AES.
使用-A1,将放弃加密,明文传送,和省略-k的效果相同。
认证机制
为防止MAC地址欺骗,截止到目前,n2n提供的最新开发(dev)版本中,提供两种类型的认证方案供用户选择。
基于身份的认证方案
边缘节点启动后,首先向中心节点提交注册。
边缘节点随机生成一个唯一ID值,伴随REGISTER_SUPER类型的消息,一起向中心节点传送。
中心节点抽取ID值,和本地缓存的集合做比对,如果发现已经注册过,则返回REGISTER_SUPER_NAK类型的消息,客户端收到后马上报错。
已经注册成功的客户端,出现故障退出的情况,对应的ID值仍然会持续保存,失效时间大概为90s.
边缘节点的MAC地址和ID,并不是一个东西,MAC地址在组网成功的节点之间可以相互看到,但ID只有客户端和中心节点才能识别。
以上可以看出,基于ID值的认证只是一种最基础的方案,对于防范网络攻击和信息安全,作用很小~
基于用户名和密码的认证方案
这是一种高级认证方案,能极大保障通信安全,官方称为”Curve25519”.
用户名和密码充当私钥,使用工具包中提供的”tools/n2n-keygen”命令生成公钥,并将公钥传递给中心节点完成配对。
supernode(中心节点)准备
假设当前配置的用户名为logan,密码为007, 在supernode节点,使用工具生成公钥如下:
1 | [user@machine n2n]$ tools/n2n-keygen logan 007 |
要将命令执行的输出信息,拷贝到community.list配置文件。
1 | # |
上面的配置文件表明,虚拟网络netleo,下面有两个使用秘钥登录的节点,分别是logan和sister.
这样做的好处是,如果logan或者sister用户转移到mynetwork网络,只需要执行简单的剪切、粘贴操作,将这两行配置移位即可实现。
中心节点并不限制边缘节点使用相同的用户名,强烈建议区分使用不同的用户名(使用动态IP地址分配时,分配的IP也是基于用户名)。
当一个边缘节点用户使用新密码,或者被隔离删除,则可以操作community.list配置中对应的行,替换新生成的密码或删除。
操作更改后,需要重新启动超级节点或向管理端口发出”reload_communities”命令,以使超级节点重载配置。
联邦模式下,存在多个中心节点,当修改了一个中心节点的配置,需要同步到其他节点并执行重载动作。
为了在中心节点之间派生、共享私钥,基于用户名和密码的认证方案,需要使用-F参数,给中心节点指定一个联邦别名(也可以N2N_FEDERATION在环境变量中定义)。
Edge边缘节点准备
边缘节点使用-I指定用户名,-J指定密码。
1 | [user@host n2n]$ sudo ./edge -l <supernode:port> -c netleo -I logan -J 007 <your additional parameters> |
此时已自动开启了标头加密功能,只有流密码在安全性方面能够可靠地与此身份验证方案配合使用。
所以,需要添加额外的启动参数,-A4 (ChaCha20), -A5(SPECK), -k 添加秘钥。
边缘节点需要知道超级节点的公钥。
超级节点的公钥,也是由命令行工具生成,边缘节点使用-P参数,引用该公钥。
1 | # 生成超级节点公钥的命令 |
到这里,可以确定边缘节点的启动命令为:
1 | [user@host n2n]$ sudo ./edge -l <supernode:port> -c netleo -I logan -J 007 -A5 -k mySecretKey -P opIyaWhWjKLJSNOHNpKnGmelhHWRqkmY5pAx7lbDHp4 |
以上,可以通过N2N_PASSWORD设置环境变量,防止密码泄露,同时,可以将所有配置参数存放到配置文件,方便管理。
使用配置文件
创建配置文件/etc/n2n/edge.conf, 内容形式如下(可以任意添加)
1 | # automated edge configuration |
使用配置文件启动边缘节点
1 |
|
在传入配置文件后,也可以增加其他配置参数
1 | sudo edge /etc/n2n/edge.conf -z1 -I myComputer |
配置文件也支持=标记,但两边不能有空格。
1 | -c=netleo |