<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Soul Of Free Loop &#187; TUN</title>
	<atom:link href="https://zohead.com/archives/tag/tun/feed" rel="self" type="application/rss+xml" />
	<link>https://zohead.com</link>
	<description>Uranus Zhou&#039;s Blog</description>
	<lastBuildDate>Sat, 19 Jul 2025 15:42:46 +0000</lastBuildDate>
	<language>zh-CN</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.8</generator>
	<item>
		<title>OpenWRT实现OpenVPN按ipset自动分流</title>
		<link>https://zohead.com/archives/openwrt-openvpn-ipset/</link>
		<comments>https://zohead.com/archives/openwrt-openvpn-ipset/#comments</comments>
		<pubDate>Sun, 16 Jul 2017 04:35:35 +0000</pubDate>
		<dc:creator><![CDATA[Uranus Zhou]]></dc:creator>
				<category><![CDATA[网络]]></category>
		<category><![CDATA[dnsmasq]]></category>
		<category><![CDATA[gfwlist]]></category>
		<category><![CDATA[ipset]]></category>
		<category><![CDATA[iptables]]></category>
		<category><![CDATA[newifi mini]]></category>
		<category><![CDATA[OpenVPN]]></category>
		<category><![CDATA[OpenWRT]]></category>
		<category><![CDATA[PandoraBox]]></category>
		<category><![CDATA[TUN]]></category>
		<category><![CDATA[Windscribe]]></category>

		<guid isPermaLink="false">https://zohead.com/?p=1476</guid>
		<description><![CDATA[接着上面一篇介绍 Windscribe 免费 VPN 的文章，住处的网络通过 OpenVPN 连接 Windscribe 之后虽然速度不快，但好歹广电宽带下没有之前用的几个 VPS 经常超时的问题了。因此想着最好能部署到现在用的 newifi mini 路由器上（毕竟已经刷了 PandoraBox 固件），目标就是能在路由器上用 OpenVPN 连接 Windscribe 并自动分流翻墙访问某些特殊的网站。 OpenWRT 安装使用 OpenVPN 首先在路由器上安装 OpenVPN 客户端： 把上篇文章中生成的 Windscribe OpenVPN 配置文件上传到 /etc/openvpn  [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>接着上面一篇介绍 <a href="https://zohead.com/archives/windscribe-openvpn/">Windscribe 免费 VPN</a> 的文章，住处的网络通过 OpenVPN 连接 Windscribe 之后虽然速度不快，但好歹广电宽带下没有之前用的几个 VPS 经常超时的问题了。因此想着最好能部署到现在用的 newifi mini 路由器上（毕竟已经刷了 PandoraBox 固件），目标就是能在路由器上用 OpenVPN 连接 Windscribe 并自动分流翻墙访问某些特殊的网站。</p>
<h2 id="openwrt-安装使用-openvpn">OpenWRT 安装使用 OpenVPN</h2>
<p>首先在路由器上安装 OpenVPN 客户端：</p>
<pre class="brush: bash; title: ; notranslate">
[root@PandoraBox:/root]# opkg update
[root@PandoraBox:/root]# opkg install openvpn-openssl
</pre>
<p>把上篇文章中生成的 Windscribe OpenVPN 配置文件上传到 <code>/etc/openvpn</code> 目录，假设配置文件路径为 <code>/etc/openvpn/windscribe.ovpn</code>。</p>
<p>这里需要注意 OpenWRT 的 OpenVPN 客户端并不能像 Windows 等客户端那样提示用户输入 Windscribe VPN 连接用户名和密码，只能通过用户密码文件指定。我们需要手工生成用户密码文件 <code>/etc/openvpn/windscribe.txt</code>，文件格式为第一行用户名，第二行密码。</p>
<p>接着修改 OpenVPN 配置文件，增加一行指定用户密码文件：</p>
<pre class="brush: plain; title: ; notranslate">
auth-user-pass windscribe.txt
</pre>
<blockquote>
<p><strong>提示</strong></p>
<p>如果你使用的 OpenVPN 客户端版本比较老（比如我的 PandoraBox 系统里安装的是 2.3.6-2 版本），可能不支持 Windscribe OpenVPN 配置文件里的 <code>block-outside-dns</code> 选项，如果 OpenVPN 运行报错的话可以注释掉这个选项。</p>
</blockquote>
<p>然后修改 <code>/etc/config/openvpn</code> 配置文件增加一个新的 OpenVPN instance，新的配置名称不要与现有的重复即可：</p>
<pre class="brush: plain; title: ; notranslate">
config openvpn 'windscribe'
	option config '/etc/openvpn/windscribe.ovpn'
	option enabled '1'
</pre>
<p>剩下就是激活并启动 OpenVPN 客户端服务了：</p>
<pre class="brush: bash; title: ; notranslate">
[root@PandoraBox:/root]# /etc/init.d/openvpn enable
[root@PandoraBox:/root]# /etc/init.d/openvpn start
</pre>
<p>稍等一会，如果一切正常的话，用 <code>logread</code> 命令应该能看到 OpenVPN 的连接日志：</p>
<pre class="brush: bash; title: ; notranslate">
[root@PandoraBox:/root]# logread -f
Fri Jul  7 00:02:13 2017 daemon.notice openvpn(windscribe)[5618]: TUN/TAP device tun0 opened
Fri Jul  7 00:02:13 2017 daemon.notice openvpn(windscribe)[5618]: do_ifconfig, tt-&gt;ipv6=0, tt-&gt;did_ifconfig_ipv6_setup=0
Fri Jul  7 00:02:13 2017 daemon.notice openvpn(windscribe)[5618]: /sbin/ifconfig tun0 10.110.34.41 netmask 255.255.254.0 mtu 1500 broadcast 10.110.35.255
Fri Jul  7 00:02:13 2017 daemon.notice openvpn(windscribe)[5618]: Initialization Sequence Completed
</pre>
<p>连接上服务器之后可以看看 OpenVPN tun 设备路由信息：</p>
<pre class="brush: bash; title: ; notranslate">
[root@PandoraBox:/root]# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         10.110.34.1     128.0.0.0       UG    0      0        0 tun0
0.0.0.0         10.58.71.1      0.0.0.0         UG    0      0        0 eth0.2
10.58.71.0      0.0.0.0         255.255.255.0   U     0      0        0 eth0.2
10.110.34.0     0.0.0.0         255.255.254.0   U     0      0        0 tun0
103.10.197.3    10.58.71.1      255.255.255.255 UGH   0      0        0 eth0.2
128.0.0.0       10.110.34.1     128.0.0.0       UG    0      0        0 tun0
192.168.1.0     0.0.0.0         255.255.255.0   U     0      0        0 br-lan
</pre>
<h2 id="dnsmasq-配置修改">dnsmasq 配置修改</h2>
<p>与之前使用的 Shadowsocks 通过 ipset 自动分流类似，我们首先需要在 OpenWRT 上安装 <code>dnsmasq-full</code> 和 <code>ipset</code> 包。</p>
<p>基本原理也很简单，OpenWRT 上的 dnsmasq 服务器将 gfwlist 中的域名通过 OpenVPN 解析防止域名污染并将解析结果添加到 ipset，然后设置 ipset 中的所有 IP 地址都走 OpenVPN 翻墙，其它地址仍然走默认的宽带线路。</p>
<p>dnsmasq 使用 gfwlist 和 gfwlist 自动更新的方法可以参考我之前写的 <a href="https://zohead.com/archives/newifi-mini-openwrt/">newifi mini路由器OpenWRT初步体验</a> 文章。</p>
<p>我的服务器上基于 gfwlist 自动生成的 dnsmasq 配置文件地址没有变：</p>
<p><a href="https://zohead.com/downloads/dnsmasq.tar.gz">https://zohead.com/downloads/dnsmasq.tar.gz</a></p>
<p>只是自动更新 gfwlist 的 crontab 配置文件要修改一下了，因为上面的 dnsmasq 配置文件是为 Shadowsocks 本地转发解析域名准备的，这里换成 Google 提供的 <code>8.8.8.8</code> DNS 解析服务器：</p>
<pre class="brush: bash; title: ; notranslate">
[root@PandoraBox:/root]#cat /etc/crontabs/root
10 5 * * * curl -k -o /tmp/dnsmasq.tar.gz https://zohead.com/downloads/dnsmasq.tar.gz &amp;&amp; tar -C /tmp -xzf /tmp/dnsmasq.tar.gz &amp;&amp; sed -i 's/127\.0\.0\.1#5353$/8.8.8.8/g' /tmp/dnsmasq_list.conf &amp;&amp; cat /tmp/dnsmasq_list.conf &gt; /etc/dnsmasq.d/dnsmasq_list.conf &amp;&amp; rm -f /tmp/dnsmasq.tar.gz /tmp/dnsmasq_list.conf
</pre>
<h2 id="配置-ipset-自动分流">配置 ipset 自动分流</h2>
<p>首先修改 <code>/etc/iproute2/rt_tables</code> 配置文件，为 OpenVPN 专门增加一个名字为 <code>gfwtable</code> 的路由表（数字不和现有的表重复即可）：</p>
<pre class="brush: plain; title: ; notranslate">
99	gfwtable
</pre>
<p>需要注意的是我们可以从上面的 OpenVPN tun 设备路由信息中看到 OpenVPN 客户端连接上服务器之后自动添加了默认路由，而为了使默认流量都走宽带线路，需要修改 OpenVPN 配置文件禁用默认路由：</p>
<pre class="brush: plain; title: ; notranslate">
route-nopull
</pre>
<p>编辑 <code>/etc/firewall.user</code> 文件增加自定义的防火墙规则：</p>
<pre class="brush: bash; title: ; notranslate">
[root@PandoraBox:/root]# cat /etc/firewall.user
ipset -N gfwlist iphash
iptables -t mangle -N fwmark
iptables -t mangle -C OUTPUT -j fwmark || iptables -t mangle -A OUTPUT -j fwmark
iptables -t mangle -C PREROUTING -j fwmark || iptables -t mangle -A PREROUTING -j fwmark
</pre>
<p>分别简单解释一下：</p>
<ul>
<li>第一行增加新的 iphash 类型的名为 <code>gfwlist</code> 的 ipset；</li>
<li>第二行在 iptables 的 <code>mangle</code> 表中新增 <code>fwmark</code> 链；</li>
<li>第三和第四行分别在 iptables 的 <code>mangle</code> 表的 <code>OUTPUT</code> 和 <code>PREROUTING</code> 链中增加 <code>fwmark</code> target，为了避免重复，增加之前都用了 iptables 命令判断原有规则是否已经存在；</li>
<li>后面三条规则有些 OpenWRT 系统里已经自带了，这里为了保险还是加上了。</li>
</ul>
<p>接着还要再修改 Windscribe OpenVPN 配置文件，增加 VPN 的启动和停止脚本设置，因为我们要在脚本中 添加 / 删除 路由和 iptables 规则：</p>
<pre class="brush: plain; title: ; notranslate">
script-security 2
up /etc/openvpn/openvpn-up.sh
down /etc/openvpn/openvpn-down.sh
</pre>
<p>当然别忘了给 OpenVPN 启动和停止脚本增加执行权限：</p>
<pre class="brush: bash; title: ; notranslate">
[root@PandoraBox:/root]#chmod +x /etc/openvpn/openvpn-up.sh /etc/openvpn/openvpn-down.sh
</pre>
<p>OpenVPN 调用启动和停止脚本的参数格式会区分 tun 和 tap 设备，对于 tun 设备脚本调用参数是这样的：</p>
<pre class="brush: bash; title: ; notranslate">
cmd tun_dev tun_mtu link_mtu ifconfig_local_ip ifconfig_remote_ip [ init | restart ]
</pre>
<p>tap 设备则是：</p>
<pre class="brush: bash; title: ; notranslate">
cmd tap_dev tap_mtu link_mtu ifconfig_local_ip ifconfig_netmask [ init | restart ]
</pre>
<p>这里我们只需要关心第一个 tun /tap 设备名参数，我的 OpenVPN 启动脚本如下：</p>
<pre class="brush: bash; title: ; notranslate">
[root@PandoraBox:/root]#cat /etc/openvpn/openvpn-up.sh
#!/bin/sh
ip route add 8.8.8.8 dev $1
iptables -t mangle -A fwmark -m set --match-set gfwlist dst -j MARK --set-mark 0xffff
ip rule add fwmark 0xffff table gfwtable
ip route add default dev $1 table gfwtable
iptables -I FORWARD -o $1 -j ACCEPT
iptables -t nat -I POSTROUTING -o $1 -j MASQUERADE
</pre>
<p>同样简单说明一下：</p>
<ul>
<li>首先将 <code>8.8.8.8</code> DNS 解析服务器设置为从 OpenVPN 走防止域名污染；</li>
<li>使用 iptables <code>mangle</code> 表中的 <code>fwmark</code> 链为所有目标为 gfwlist ipset 中 IP 地址的数据包打标记，这里标记号用的是 0xffff；</li>
<li>所有标记号为 0xffff 的数据包都使用上面新增的 <code>gfwtable</code> 路由表；</li>
<li><code>gfwtable</code> 路由表固定使用 OpenVPN 线路；</li>
<li>最后两条 iptables 规则也非常重要，允许路由器下的其它设备访问被封锁域名时走 OpenVPN 线路。</li>
</ul>
<p>类似的 OpenVPN 停止脚本就比较简单了：</p>
<pre class="brush: bash; title: ; notranslate">
[root@PandoraBox:/root]#cat /etc/openvpn/openvpn-down.sh
#!/bin/sh
ip rule del table gfwtable
iptables -t mangle -D fwmark -m set --match-set gfwlist dst -j MARK --set-mark 0xffff
iptables -D FORWARD -o $1 -j ACCEPT
iptables -t nat -D POSTROUTING -o $1 -j MASQUERADE
</pre>
<p>都是清理启动脚本中增加的规则，ip route 项会在 tun 设备停止时自动删除，不需要手工进行清理了。</p>
<h2 id="总结">总结</h2>
<p>经过这番对 OpenWRT 的配置折腾，现在住处的手机和电脑就都能通过 Windscribe OpenVPN 自动翻墙了。</p>
<p>最后贴上我的 newifi mini 路由器上的 Windscribe 完整 OpenVPN 配置文件给大家参考，由于文件比较长我放到 Pastebin 上了，最后祝大家炎炎夏日也能玩的开心：</p>
<p><a href="http://pastebin.com/raw.php?i=TWbaMXdg" target="_blank">http://pastebin.com/raw.php?i=TWbaMXdg</a></p>
]]></content:encoded>
			<wfw:commentRss>https://zohead.com/archives/openwrt-openvpn-ipset/feed/</wfw:commentRss>
		<slash:comments>36</slash:comments>
		</item>
		<item>
		<title>在Linux容器中使用ZeroTier P2P VPN</title>
		<link>https://zohead.com/archives/zerotier-container/</link>
		<comments>https://zohead.com/archives/zerotier-container/#comments</comments>
		<pubDate>Wed, 31 Aug 2016 16:57:17 +0000</pubDate>
		<dc:creator><![CDATA[Uranus Zhou]]></dc:creator>
				<category><![CDATA[Docker]]></category>
		<category><![CDATA[网络技术]]></category>
		<category><![CDATA[Codeanywhere]]></category>
		<category><![CDATA[P2P]]></category>
		<category><![CDATA[SSH]]></category>
		<category><![CDATA[TAP]]></category>
		<category><![CDATA[TUN]]></category>
		<category><![CDATA[VPN]]></category>
		<category><![CDATA[ZeroTier]]></category>
		<category><![CDATA[容器]]></category>

		<guid isPermaLink="false">https://zohead.com/?p=1266</guid>
		<description><![CDATA[关于 ZeroTier P2P VPN P2P VPN 和我们平常使用的 PPTP、OpenVPN 等 VPN 的不同之处在于其只负责将两个或多个主机通过点对点的方式进行连接，不需要中心服务器支持，多个主机之间通过 STUN 打洞或者 TURN 中继等方式进行连接，比较适合不同网络间的多个主机进行直接连接，不像 PPTP 这种在国内用的最多的就是拿来爬墙的。 目前使用的比较多的包括 n2n、tinc 和本文要介绍的 ZeroTier 等几种免费开源的 P2P VPN 软件。 n2n 由于已经没人继续开发支持了所以不予考虑，我在对比了 tinc 和 ZeroTier 之后发现 ZeroTier  [&#8230;]]]></description>
				<content:encoded><![CDATA[<h2 id="关于-zerotier-p2p-vpn">关于 ZeroTier P2P VPN</h2>
<p>P2P VPN 和我们平常使用的 PPTP、OpenVPN 等 VPN 的不同之处在于其只负责将两个或多个主机通过点对点的方式进行连接，不需要中心服务器支持，多个主机之间通过 <a href="https://en.wikipedia.org/wiki/STUN">STUN</a> 打洞或者 <a href="https://en.wikipedia.org/wiki/Traversal_Using_Relays_around_NAT">TURN</a> 中继等方式进行连接，比较适合不同网络间的多个主机进行直接连接，不像 PPTP 这种在国内用的最多的就是拿来爬墙的。</p>
<p>目前使用的比较多的包括 n2n、tinc 和本文要介绍的 ZeroTier 等几种免费开源的 P2P VPN 软件。</p>
<p>n2n 由于已经没人继续开发支持了所以不予考虑，我在对比了 tinc 和 ZeroTier 之后发现 ZeroTier 虽然看起来性能比 tinc 略差一点，但其客户端配置步骤非常简单，不需要像 tinc 那样要在多个主机分别手工生成配置文件，而且 ZeroTier 自己也自带了几个不同国家区域的中继服务器方便普通用户使用，另外一点就是本文要介绍的 ZeroTier 支持在 Linux 容器中使用，因此平时我主要使用 ZeroTier，tinc 用作辅助。</p>
<p>ZeroTier 的虚拟网络可以包含多个处于相同或不同物理网络里的主机，每个虚拟网络都有一个唯一的网络 ID，多个运行 ZeroTier 服务的主机加入同一个 ZeroTier 网络 ID 就可以构成一个虚拟网络。虚拟网络都是由 ZeroTier Controller 控制器来管理的，默认可以使用 ZeroTier 提供的控制器来管理，用户也可以自行搭建控制器来实现完全自己管理 ZeroTier 网络。</p>
<p>另外 ZeroTier 有一个特殊的 <code>8056c2e21c000001</code> 网络 ID 表示全球公共 ZeroTier 网络，如果只是想测试连接网络的话也可以加入这个公共网络；但实际使用中为了安全性考虑建议最好在 ZeroTier 网站上注册一个账户并新建你自己的 P2P VPN 网络用于管理。</p>
<p>有关 ZeroTier P2P VPN 的详细介绍可以参考其官网：</p>
<p><a href="https://www.zerotier.com/">https://www.zerotier.com/</a></p>
<h2 id="容器中使用-zerotier-的问题">容器中使用 ZeroTier 的问题</h2>
<p>简单了解 ZeroTier P2P VPN 主机端的工作机制之后我就发现一个问题，其依赖的 TUN/TAP 驱动（n2n 和 tinc VPN 也同样依赖）在很多 Linux 容器系统中是无法使用的。</p>
<p>我使用的 OpenVZ VPS 容器还好还可以在控制面板里开启 TUN/TAP 支持，而对于现在非常流行的 Docker 容器（例如之前我用到的 IBM Bluemix 容器）就比较麻烦了，Docker 容器在运行时必须包含 <code>SYS_NET_ADMIN</code> 特权才能正常执行 TUN/TAP 虚拟网卡设备的创建操作（Docker 容器中同样也不能使用 OpenVPN、OpenConnect 等依赖 TUN/TAP 驱动的程序），但目前的容器服务厂商基本上不会以特权方式运行容器。</p>
<p>ZeroTier 为此提出的解决方案就是 Network Containers 模式，通过实现一个轻量级的应用层 TCP/IP API 来 hook 现有应用程序的 Socket API，这样可以使现有的程序也能使用 ZeroTier 技术连接其它主机。</p>
<blockquote>
<p>最近 ZeroTier 已经将 Network Containers 模式更名为 ZeroTier SDK 并使用了单独的版本库，开发者也可以选择将 ZeroTier SDK 直接编译进自己的应用程序以方便直接使用。有关容器模式的详细介绍可以参考官方介绍文章：<a href="https://www.zerotier.com/product-netcon.shtml">ZeroTier Network Containers</a>。</p>
</blockquote>
<h2 id="关于-codeanywhere-容器">关于 Codeanywhere 容器</h2>
<p>这里我使用 <a href="https://codeanywhere.com/">Codeanywhere</a> 虚拟机来测试 ZeroTier Network Containers，Codeanywhere 作为一个云端 IDE 平台还是比较好用的，其提供的免费版本的容器支持：</p>
<ul>
<li>2GB 磁盘空间；</li>
<li>256MB RAM (+ 512 MB 交换空间)；</li>
<li>sudo 支持；</li>
<li>支持 SSH 登录（免费版本的容器每次启动时 SSH 端口不固定）；</li>
<li>支持访问所有 HTTP 和 Websocket 端口（默认 1024 - 9999）。</li>
</ul>
<p>问题是 Codeanywhere 免费版本的虚拟机不支持固定 IP 地址，也不支持域名绑定或者固定子域名，每次虚拟机启动之后分配到的都是一个超长的子域名，例如你看到的子域名可能就是下面的形式：</p>
<pre><code>preview.7reszf59tfv18aor9x7odheaio340a4ih8tcn8fvndzvkj4i.box.codeanywhere.com
</code></pre>
<p>这样实际开发测试起来还是有点不太方便。</p>
<p>当然 Codeanywhere 也是不提供 TUN/TAP 支持的，这样如果 ZeroTier 的容器模式可以在 Codeanywhere 虚拟机内正常使用，我就可以直接在自己的电脑上直接使用虚拟的 P2P VPN 节点 IP 地址来访问 Codeanywhere 虚拟机了，可以省掉那一长串恶心的子域名了。</p>
<h2 id="使用-zerotier-network-containers">使用 ZeroTier Network Containers</h2>
<h3 id="编译安装-zerotier-network-containers">编译安装 ZeroTier Network Containers</h3>
<p>首先创建一个新的 Codeanywhere 虚拟机，建议使用 <code>C/C++ Development Stack</code> 类型方便后续编译安装 ZeroTier 程序，另外操作系统最好选择 Centos 6.5 64 位，如果使用 Ubuntu 系统可能存在连接不上 P2P VPN 网络的问题。</p>
<p>在 Codeanywhere 虚拟机中使用 git 命令检出 ZeroTier 官方版本库，检出之后运行 <code>make netcon</code> 命令就可以编译出 ZeroTier Network Containers 模式需要的文件了：</p>
<pre class="brush: bash; title: ; notranslate">
[cabox@box-codeanywhere ZeroTierOne]$ ls                                           
AUTHORS.md   examples                 netcon        ui
LICENSE.txt  ext                      node          version.h
Makefile     include                  objects.mk    windows
README.md    java                     one.cpp       world
artwork      libzerotierintercept.so  osdep         zerotier-cli
attic        make-freebsd.mk          selftest.cpp  zerotier-idtool
cluster-geo  make-linux.mk            service       zerotier-netcon-service
controller   make-mac.mk              tcp-proxy
</pre>
<p>其中最重要的就是 <code>zerotier-netcon-service</code> 服务和 <code>libzerotierintercept.so</code> 以及 netcon 目录中的 <code>liblwip.so</code> 应用层 Socket API 库文件了，接着可以先将 ZeroTier Network Container 模式程序和有关库文件安装到 <code>/var/lib/zerotier-one</code> 目录中：</p>
<pre class="brush: bash; title: ; notranslate">
[cabox@box-codeanywhere ZeroTierOne]$ mkdir -m /var/lib/zerotier-one
[cabox@box-codeanywhere ZeroTierOne]$ cp -ra zerotier-* /var/lib/zerotier-one
[cabox@box-codeanywhere ZeroTierOne]$ cp libzerotierintercept.so netcon/liblwip.so /var/lib/zerotier-one
</pre>
<h3 id="将容器主机加入-zerotier-虚拟网络">将容器主机加入 ZeroTier 虚拟网络</h3>
<p>下面就可以在 Codeanywhere 虚拟机中进行测试了，首先启动 Network Container 模式下的 ZeroTier 主服务程序：</p>
<pre class="brush: bash; title: ; notranslate">
[cabox@box-codeanywhere workspace]$ /var/lib/zerotier-one/zerotier-netcon-service -d
</pre>
<p>服务启动成功之后稍等片刻，运行 <code>zerotier-cli</code> 命令加入现有的 ZeroTier 虚拟网络，下面命令行中的 <code>565799d8f61077e9</code> 就是我在 ZeroTier 网站上新创建的虚拟网络 ID：</p>
<pre class="brush: bash; title: ; notranslate">
[cabox@box-codeanywhere workspace]$ /var/lib/zerotier-one/zerotier-cli join 565799d8f61077e9
</pre>
<blockquote>
<p><strong>提示</strong></p>
<p>如果你加入的是 <code>8056c2e21c000001</code> 这个全球公共 ZeroTier 虚拟网络那就可以省掉下面这一段落的配置步骤了。</p>
</blockquote>
<p>join 操作完成之后需要在 ZeroTier 网站后台虚拟网络管理界面中先允许新的主机加入此网络，接着可以为此主机配置虚拟网络上的 IP 地址、子网掩码之类的，具体配置操作步骤还算比较简单基本都可以在 <a href="https://my.zerotier.com/network">ZeroTier Central</a> 网站后台中完成。</p>
<p>配置完成之后就可以在容器中继续运行 <code>zerotier-cli</code> 命令查询该主机上 ZeroTier 虚拟网络状态：</p>
<pre class="brush: bash; title: ; notranslate">
[cabox@box-codeanywhere workspace]$ /var/lib/zerotier-one/zerotier-cli listnetworks
200 listnetworks &lt;nwid&gt; &lt;name&gt; &lt;mac&gt; &lt;status&gt; &lt;type&gt; &lt;dev&gt; &lt;ZT assigned ips&gt;
200 listnetworks 565799d8f61077e9 zohead-network fa:d9:cf:a8:b2:40 OK PRIVATE /var/lib/zerotier-one/nc_565799d8f61077e9 10.10.8.4/24
</pre>
<p>可以看到该容器中已经正确连接到我建立的私有 ZeroTier 虚拟网络了，而且分配到了一个 <code>10.10.8.4</code> 的 IP 地址，子网掩码为 255.255.255.0（对应 24）。</p>
<h3 id="通过虚拟网络访问容器主机">通过虚拟网络访问容器主机</h3>
<p>此时需要特别注意的是容器中运行的程序还不能直接使用 ZeroTier 虚拟网络与其它主机进行连接，必须通过预加载 Network Container 库文件的方式运行程序才可以在容器系统中正确访问 ZeroTier 虚拟网络，这里我们以 SSH 服务器为例，首先可以新运行一个 <code>sshd</code> 服务程序：</p>
<pre class="brush: bash; title: ; notranslate">
[cabox@box-codeanywhere workspace]$ sudo ZT_NC_NETWORK=/var/lib/zerotier-one/nc_565799d8f61077e9 LD_PRELOAD=/var/lib/zerotier-one/libzerotierintercept.so /usr/sbin/sshd -p 27001
</pre>
<p>这样可以新运行一个 <code>sshd</code> 服务程序，并绑定新的端口（例如上面例子中的 27001 端口）防止和系统默认的 22 端口冲突，<code>ZT_NC_NETWORK</code> 变量指定需要使用的 ZeroTier 虚拟网络路径（默认为：<code>/var/lib/zerotier-one/nc_网络ID</code>），<code>LD_PRELOAD</code> 是必须指定的，否则新运行的 <code>sshd</code> 程序将无法访问 ZeroTier 虚拟网络。</p>
<p>新的 <code>sshd</code> 服务启动成功之后，我们就可以在测试的 Windows、Linux 等主机上运行 ZeroTier 客户端，加入同样的虚拟网络并配置虚拟网络 IP 地址（例如我的 Windows 机器 ZeroTier 网络 IP 地址是 <code>10.10.8.3</code>）及子网掩码。</p>
<p>最后我们可以在 Windows 主机上 ping 测试 Codeanywhere 容器的虚拟网络 IP 地址了，如果通讯正常的话就可以通过 ssh 客户端工具直接连接登录 Codeanywhere 容器系统了，这样就顺利绕过了 Codeanywhere 的随机子域名限制。</p>
<h2 id="后记">后记</h2>
<p>如果需要在 Codeanywhere 容器系统启动时自动连接 ZeroTier 虚拟网络并开启独立的 <code>sshd</code> 服务程序，那可以将类似下面的两句命令加到 <code>/etc/rc.local</code> 文件末尾：</p>
<pre class="brush: bash; title: ; notranslate">
/var/lib/zerotier-one/zerotier-netcon-service -d
echo &quot;ZT_NC_NETWORK=/var/lib/zerotier-one/nc_565799d8f61077e9 LD_PRELOAD=/var/lib/zerotier-one/libzerotierintercept.so /usr/sbin/sshd -p 27001&quot; | at now + 2 minutes
</pre>
<p>第二句命令表示在 ZeroTier Network Container 服务程序启动两分钟之后再启动单独的 <code>sshd</code> 服务程序，以使 ZeroTier 服务程序在等待的时间内能正确连接虚拟网络。</p>
<p>本文主要介绍 ZeroTier 程序里不太常见的 Network Container 容器模式，这对于越来越多的 Docker 容器系统而言能绕过 TUN/TAP 限制还是有点用处的，如果读者发现了有关 ZeroTier P2P VPN 的更多好玩法，欢迎提出交流哦，祝大家玩的开心～～～。</p>
]]></content:encoded>
			<wfw:commentRss>https://zohead.com/archives/zerotier-container/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
	</channel>
</rss>
