内网穿透是平时使用网络较常遇到的需求。比如远程访问学校内网、一些没有公网 IP 的宽带等等,使用内网穿透是最直接甚至几乎唯一的解决方案。本文主要介绍的是 n2n VPN 的基本使用方法。

关于 n2n

n2n 是一个开源但是已经停止维护了的 VPN 应用,其最大的特点是利用了 P2P 的网络结构,工作节点不是传统的客户端和服务端,而是 super node 和 edge node。大概原理就是 edge nodes 之间通过 super node 进行握手,如果可以直接互相连接就直连,不需要再通过 super node 转发流量;而如果因为各种限制无法直连,就经 super node 中转连接,此时就和普通的内网穿透原理相近。总之是一个看起来很美好的方案。因为已经停止维护,所以原文档找不到了……

下载

Releases · hguandl/n2n-bin 或者参照我的这些文章来自行编译。

使用方法

Super node

要建立 super node 我们运行的二进制文件是 supernode,通过 help 我们得知命令格式如下:

1
2
3
4
5
6
7
8
$ supernode --help
supernode usage
-l <lport>	Set UDP main listen port to <lport>
-f        	Run in foreground.
-u <UID>  	User ID (numeric) to use when privileges are dropped.
-g <GID>  	Group ID (numeric) to use when privileges are dropped.
-v        	Increase verbosity. Can be used multiple times.
-h        	This help message.

翻译过来大概就是:

  • -l 后加用来监听的端口
  • -f 代表前台运行
  • -u 后加 UID,当权限不足时所要用的用户
  • -g 后加 GID,当权限不足时所要用的用户组
  • -v 增加日志的冗长度(应该是 debug 时用的)

实际使用时我们用 sudo 运行,只需要 -l 选项就够了,所以典型的命令是:

1
$ sudo supernode -l 2333

Edge node

类比 supernode,我们看一下 edge node 程序 edge 的帮助~~(前方高能)~~:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
$ edge -h
Welcome to n2n v.2.1.0
Copyright 2007-09 - http://www.ntop.org

edge -a [static:|dhcp:]<tun IP address> -c <community> [-k <encrypt key> | -K <key file>] [-s <netmask>] [-u <uid> -g <gid>][-f][-m <MAC address>]
-l <supernode host:port> [-p <local port>] [-M <mtu>] [-r] [-E] [-v] [-t <mgmt port>] [-b] [-h]

-a <mode:address>        | Set interface address. For DHCP use '-r -a dhcp:0.0.0.0'
-c <community>           | n2n community name the edge belongs to.
-k <encrypt key>         | Encryption key (ASCII) - also N2N_KEY=<encrypt key>. Not with -K.
-K <key file>            | Specify a key schedule file to load. Not with -k.
-s <netmask>             | Edge interface netmask in dotted decimal notation (255.255.255.0).
-l <supernode host:port> | Supernode IP:port
-L <local_ip>            | Add local ip to bypass between same nat problem
-i <interval>            | Set the NAT hole-punch interval (default 20seconds)
-b                       | Periodically resolve supernode IP
                         : (when supernodes are running on dynamic IPs)
-p <local port>          | Fixed local UDP port.
-u <UID>                 | User ID (numeric) to use when privileges are dropped.
-g <GID>                 | Group ID (numeric) to use when privileges are dropped.
-f                       | Do not fork and run as a daemon; rather run in foreground.
-m <MAC address>         | Fix MAC address for the TAP interface (otherwise it may be random)
                         : eg. -m 01:02:03:04:05:06
-M <mtu>                 | Specify n2n MTU of edge interface (default 1400).
-r                       | Enable packet forwarding through n2n community.
-E                       | Accept multicast MAC addresses (default=drop).
-v                       | Make more verbose. Repeat as required.
-t                       | Management UDP Port (for multiple edges on a machine).

Environment variables:
  N2N_KEY                | Encryption key (ASCII). Not with -K or -k.

一看有这么长的选项我也晕了……没关系,我们把只把必要的选项提取出来:

  • -a 加想要构成的 VPN 内网的 IP 地址
  • -c 加 community 名,相当于同一 n2n 下的共有的用户名
  • -l 后加 super node 的 IP 及端口

其他都是可选项目,一般都是为了避免与现有的内网冲突以及增强安全性,大家可以自行看里面的说明。我也懒得翻译了 那么一个典型的 edge node 命令就是:

1
$ sudo edge -a 10.233.0.1 -c turntide -l xxx.xx.xx.xx:2333

然后我们查看一下自己的网卡设置,就能应该能看到 n2n 的设备了

1
2
3
4
5
6
7
8
9
$ ifconfig
edge0     Link encap:Ethernet  HWaddr XX:XX:XX:XX:XX:XX  
          inet addr:10.233.0.1  Bcast:10.233.0.255  Mask:255.255.255.0
          inet6 addr: fe80::c878:f8ff:feb1:f5a4/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1400  Metric:1
          RX packets:9 errors:0 dropped:0 overruns:0 frame:0
          TX packets:13 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:500 
          RX bytes:658 (658.0 b)  TX bytes:1042 (1.0 KiB)

要测试的话,找一个别的设备,再建立一个 edge node:

1
$ sudo edge -a 10.233.0.2 -c turntide -l xxx.xx.xx.xx:2333

如果两者之间可以 ping 通说明就成功了:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
$ ping -c4 10.233.0.1
PING 10.233.0.1 (10.233.0.1): 56 data bytes
64 bytes from 10.233.0.1: seq=0 ttl=64 time=362.338 ms
64 bytes from 10.233.0.1: seq=1 ttl=64 time=195.189 ms
64 bytes from 10.233.0.1: seq=2 ttl=64 time=194.986 ms
64 bytes from 10.233.0.1: seq=3 ttl=64 time=195.166 ms

--- 10.233.0.1 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 194.986/236.919/362.338 ms

第一次 ping 的时间大约是后续的两倍,比较符合先进行握手的原理,到此可以说 n2n 的组网已经成功了。

补充事项(非 Linux 用户必看)

n2n 用到了 TUN/TAP 设备,很多 Linux 是自带的,不过也有可能没有。如果正确运行之前的命令,但是在 ifconfig 里看不到虚拟设备的话,十有八九是系统没有对 TUN/TAP 的支持。不同平台的解决方案如下:

Linux

一般都有,可以通过 modinfo tun 查看是否支持。可能有些 VPS 会默认关闭,请在 VPS 对应的控制面板里打开。

Windows

安装 Tap-windows。下载链接

macOS

安装 TunTap。下载链接

Openwrt / LEDE

安装 kmod-tun。

1
# opkg install kmod-tun