10
10
2017
42

WireGuard: 简单好用的 VPN

本文来自依云's Blog,转载请注明。

家里和公司电脑连接,因为厌倦了一个个做端口映射,有些还因为安全原因得走 ssh,所以决定弄个 VPN。之前使用过 OpenVPN,然而现在懒得再去配置 OpenVPN 的证书了,所以决定尝试一下新东西。

首先,去 WireGuard 官网上转了一圈,结果还是没弄明白怎么配置。后来尝试了一下 demo,把服务端和客户端的脚本分别看了一下,才弄明白。其实在 WireGuard 里,客户端和服务端基本是平等的,差别只是谁主动连接谁而已。双方都会监听一个 UDP 端口。双方都需要一对密钥。双方都需要把对方的公钥加进来。最后一步,谁主动连接,谁就是客户端。因为家里路由器有公网 IP,我做了端口映射,所以我当然是从公司连家里方便了,用不着麻烦的打洞脚本。

首先 pacman -S wireguard-tools 安装。这也会安装上 WireGuard 的内核模块。然后使用熟悉的 ip 命令添加并配置 WireGuard 的网络接口:

# 生成密钥对
wg genkey | tee privatekey | wg pubkey > publickey

sudo ip link add dev wg0 type wireguard
sudo ip address add dev wg0 192.168.58.1/24
sudo wg set wg0 listen-port 60010 private-key privatekey
sudo ip link set wg0 up

这是我家里的配置。使用的是网段 192.168.58.0/24,因为 56 是 vbox 虚拟机用的,57 分配给 lxc 和我的网络命名空间了。指定了一下监听的端口号。我把之前给 mosh 配置了转发的端口号中最高的那个挪用了。

公司里也是同时的配置,只是不需要指定监听端口号,然后把家里那边设置成 peer,并且连过去(相同的命令我没写):

sudo wg set wg0 private-key privatekey peer 这里是公钥 endpoint 家里的IP:60010 allowed-ips 0.0.0.0/0 persistent-keepalive 180

allowed-ips 指定过来的 IP。这里没怎么限制。persistent-keepalive 是为 NAT 设置的。WireGuard 本来很安静,不需要说话的时候就不说话,但是要往 NAT 后边的主机发送信息,需要经常通信,让 NAT 记得对应的映射关系。

然后家里那边也需要添加一下公司这边的公钥:

sudo wg set wg0 peer YiyFylL+1Dr3j2Cyf0lwXQYz2qaNwm3XyV5YvMFp3Vs= allowed-ips 192.168.58.2/32

IP 限制加上也是没有问题的。这里就不用加上 endpoint 了,它连过来的时候自然就知道了。WireGuard 是支持漫游的,也就是说,双方不管谁的地址变动了,WireGuard 在看到对方从新地址说话的时候,就会记住它的新地址(跟 mosh 一样,不过是双向的)。所以双方要是一直保持在线,并且通信足够频繁的话(比如配置 persistent-keepalive),两边的 IP 都不固定也不影响的。

最后,用得不错,可以把这几条命令写到一个 systemd service 文件里,就可以不用每次敲一串命令了,也可以做到联网后自动启动。


刚刚找了一下,其实之前使用的证书什么的还在,而且还没过期。而且因为弄 nghttpx,用了一下 xca,比 easy-rsa 好用很多呢。不过 WireGuard 的双向漫游很棒啊~

Category: 网络 | Tags: linux 网络 UDP | Read Count: 76400
Matriks 说:
Oct 11, 2017 10:13:29 AM

哇,依云大大弄个VPN都这么复杂,小白如我一个ss就简单粗暴的解决了。
不过感觉这种支持漫游的想法和技术真的很厉害:
“WireGuard 是支持漫游的,也就是说,双方不管谁的地址变动了,WireGuard 在看到对方从新地址说话的时候,就会记住它的新地址(跟 mosh 一样,不过是双向的)。所以双方要是一直保持在线,并且通信足够频繁的话(比如配置 persistent-keepalive),两边的 IP 都不固定也不影响的。”

lyman 说:
Oct 11, 2017 10:33:39 AM

好东西,感谢分享。

Avatar_small
依云 说:
Oct 11, 2017 02:00:35 PM

ss 是代理不是 VPN 啊。其实 ssh 也可以弄 VPN 的,不过 TCP over TCP 不好。

Matriks 说:
Oct 11, 2017 02:25:49 PM

我觉得把本地所有流量都走ss就成了vpn(#・∀・),可能是我想的太简单了吧

Avatar_small
依云 说:
Oct 11, 2017 03:44:34 PM

我不要把所有流量都走过去啊。其实我只是想搞 nfs 而已……哦,X Window 和 fcitx-remote 也可以走这个 VPN,不需要走 ssh 了。

Oooo 说:
Oct 15, 2017 02:31:53 PM

那叫全局代理。

另外需要说明的是: ss 只转发 TCP/UDP 流量。

还有,ss 的全局转发应该需要其他工具支持吧,默认是 "系统默认SOCKS5",也就是说需要 应用程序主动从系统配置获取 SOCKS5 代理信息,并使用之。

Oooo 说:
Oct 15, 2017 02:33:26 PM

真正的简单易用的全局代理在这里:

https://github.com/LuoZijun/rust-netproxy

虽然还在开发当中 ....

Oooo 说:
Oct 15, 2017 02:34:35 PM

@依云 大神,来帮我点个赞: https://github.com/LuoZijun/rust-netproxy

GlacJAY 说:
Oct 18, 2017 09:47:43 AM

漫游的话,记得 OpenVPN 也是支持的?

Uranus Zhou 说:
Oct 30, 2017 02:37:36 PM

我现在用 tinc VPN 的,直接用现成的 tun/tap,基本可以自己控制,可以 UDP 打洞或者自己配置 TCP 中继;
为了省事也给同事装了 ZeroTier,这个默认连中继服务器都带了。

alienzj 说:
Nov 10, 2017 01:27:12 AM

依云,你好!
请教你一个问题,我们公司的VPN没有提供Linux客户端(之前有提供Dell的vpn,后来VPN升级换成了Globalprotect(好像是叫这个名字),就没有Linux版的了),而我在家中主要用archlinux,我该怎么样才能在家里ssh上公司的集群呢?可以用你文中的方法搞吗?
谢谢你!

fish 说:
Feb 23, 2018 09:01:54 PM

hi.
我在openvz vps上运行ip link add dev wg0 type wireguard
得到提示:
root@RegalMusty-VM:/etc/wireguard# ip link add dev wg0 type wireguard
RTNETLINK answers: Operation not supported
root@RegalMusty-VM:/etc/wireguard#

这里的Operation not supported是什么意思?难道不能在openvz vps上安装wireguard?

Avatar_small
依云 说:
Feb 23, 2018 10:10:39 PM

就是说,wireguard 模块没加载。openvz 不能自己加载内核模块,所以是不行的啦(bbr 同理)。你非要跑的话,也可以用 UML。

Avatar_small
依云 说:
Feb 23, 2018 10:14:23 PM

如果你公司的服务器或者办公室的设备有外网IP,并且你可以给装上VPN(公司政策允许),当然是可以的啦。

不行的话,你也可以虚拟机里装一个 Windows 连上 VPN,然后 Linux 这边把公司网段走 Windows 再走 VPN。

Avatar_small
依云 说:
Feb 23, 2018 10:14:52 PM

OpenVPN 才不支持漫游呢。不是客户端漫游,是服务端哦!

Avatar_small
依云 说:
Feb 23, 2018 10:15:21 PM

(其实两边是对等的,除了最开始谁连谁的问题之外。)

fish 说:
Feb 24, 2018 02:22:55 PM

但是我在另一个kvm vps上也遇到同样的问题,怎么回事呢?

fish 说:
Feb 24, 2018 03:08:15 PM

这里https://superuser.com/questions/232807/iproute2-not-functioning-rtnetlink-answers-operation-not-supported说:

SOLVED:

Here is the most thorough list for getting iproute2 to work with your kernel:

CONFIG_NETFILTER_NETLINK=y
CONFIG_NETFILTER_NETLINK_QUEUE=y
CONFIG_NETFILTER_NETLINK_LOG=y
CONFIG_NF_CT_NETLINK=y
CONFIG_SCSI_NETLINK=y
CONFIG_IP_ADVANCED_ROUTER=y
CONFIG_NET_SCH_INGRESS=y
CONFIG_NET_SCHED=y
CONFIG_IP_MULTIPLE_TABLES=y
CONFIG_NETFILTER_XT_TARGET_MARK=y“

这是修改linux里的什么文件?具体的文件路径是什么?

Avatar_small
依云 说:
Feb 24, 2018 04:15:51 PM

这是内核的配置项。可以在 /proc/config.gz 查看,修改需要重新编译内核。

你的内核是很旧吗?还是 wireguard 没装好?sudo modprobe wireguard 手动加载模块试试呢?

fish 说:
Feb 24, 2018 06:25:57 PM

root@vps:~# which wg
/usr/bin/wg
root@vps:~# modprobe wireguard
modprobe: FATAL: Module wireguard not found.
root@vps:~# ip link add dev wg0 type wireguard
RTNETLINK answers: Operation not supported
root@vps:~#
root@vps:~# uname -a
Linux 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt11-1+deb8u6 (2015-11-09) x86_64 GNU/Linux
root@vps:~#

在安装wireguard的过程中,我粗略看到好像提示说gilibc/libc没装成,好像还提示了kernel的版本太低。3.16.0-4还是低了吗?你的内核的版本是多少?

fish 说:
Feb 24, 2018 06:46:32 PM

上面的提示来自第一台kvm vps.我在第二台kvm vps上,又尝试安装
wireguard,里面提示:
“Starting with version 2.26-1, the glibc requires a 3.2 or later Linux
kernel. If you use an older kernel, please upgrade it *before*
installing this glibc version. Failing to do so will end-up with the
following failure:

Preparing to unpack .../libc6_2.26-5_amd64.deb ...
ERROR: This version of the GNU libc requires kernel version
3.2 or later. Please upgrade your kernel before installing
glibc.

The decision to not support older kernels is a GNU libc upstream
decision.

Note: This obviously does not apply to non-Linux kernels.

-- Aurelien Jarno <aurel32@debian.org> Tue, 23 Jan 2018 22:03:12 +0100”

那么如何升级内核到3.2版?

Avatar_small
依云 说:
Feb 24, 2018 10:02:50 PM

我的内核版本目前是 4.15.2 啊。另一个服务器是 4.4.0。

fish 说:
Feb 24, 2018 11:21:27 PM

你用的是哪家的vps?
还是你自己升级内核的呢?

Avatar_small
依云 说:
Feb 25, 2018 12:28:22 AM

阿里云……不是我的,我只是借用一下这机器的剩余资源。

fish 说:
Feb 25, 2018 10:38:05 AM

总结一下:
openvz vps装不了wireguard.
在kvm vps平台上,如果选择debian8系统,则其内核通常为3.16.0-4,内核版本太低。
如果选择ubuntu 16.04系统,则其内核通常为4.4.0-31,内核版本符合要求。

因此我选择了ubuntu 16.04系统,在ubuntu 16.04系统上,成功安装了wireguard:
root@server:/etc/wireguard# wg show
interface: wg0
public key: my-public-key
private key: (hidden)
listening port: my-port
root@server:/etc/wireguard#

不过,我的客户机器是mac.在mac上,没有ip命令。那么在mac上,如何添加虚拟网卡 wg0 并设置 IP 和路由??
(参考https://steemit.com/cn/@curl/ubuntu-vpn-wireguard)

谢谢回复

Avatar_small
依云 说:
Feb 25, 2018 12:08:39 PM

wireguard 现在还只支持 Linux 的吧。

alienzj 说:
Mar 20, 2018 12:58:06 PM

嗯,我用了你推荐的第二种方法,正好有一台闲置的win笔记本,给他装上了VPN,然后把VPN网络共享给笔记本连的WLAN,然后我的arch机通过sudo ip route add的方式让公司集群的网段通过笔记本的ip传给VPN,成功啦!就是有时候不灵,需要在win机那边重新共享网络,这时候win机的IP就变了,就要重新点鼠标关闭WLAN再开启,感觉应该在路由器给win机设置个静态的局域网IP.
谢谢你!:)

Avatar_small
依云 说:
Mar 20, 2018 03:39:36 PM

都连一个局域网的话,应该不需要共享网络,这样(https://www.wikihow.com/Enable-IP-Routing)设置之后,直接路由过去应该就可以了。

ChenBill 说:
Sep 19, 2018 03:16:22 PM

請問一下你連回家裡的時候可以和家裡的電腦互傳檔案嗎?

也就是Samba 
Avatar_small
依云 说:
Sep 19, 2018 10:40:08 PM

我不用 samba 的呀。scp 和 rsync 足够我用了。

ChenBill 说:
Sep 20, 2018 09:59:12 AM

主要想要用最少的成本建置Site to Site VPN 橫跨台灣和內地 所以一直在找尋方法 我認為WireGuard 是最有可能取代網關的SSL VPN的解決方案 但我不知道他能不能Site to Site

Avatar_small
依云 说:
Sep 20, 2018 11:05:37 AM

Site to Site 是什么意思呢?

ChenBill 说:
Oct 07, 2018 12:50:48 AM

其實就是想要在公司裡用網路芳鄰存取家裡的NAS 不知道WireGuard是不是能做到

Avatar_small
依云 说:
Oct 07, 2018 11:34:56 PM

能啊,你用 WireGuard 连回你家里就可以了。注意配置网络路由和防火墙,因为 WireGuard 会创建一个新的局域网。比较方便的方案是 WireGuard 另一端直接放你 NAS 设备上。

FrostRed 说:
Oct 27, 2018 11:49:20 PM

它的特征明显吗?会不久就被封了吗。

Avatar_small
依云 说:
Oct 30, 2018 03:47:45 PM

有特征的。因为使用的是 UDP,你用来访问国际互联网的话,即使不封也很容易被 QOS 的。国内互相访问可以试试。

edward 说:
Nov 06, 2018 12:35:49 PM

TCP over TCP 不好,不过如果一条TCP Flow对应一个TCP Tunnel,问题就不大了,因为死就死一条,不会整个崩溃。

比如ss,lantern的移动版都是这个思路。从tun收到数据,送到一个userspace协议栈,把terminate,发起新的tcp通过socks代理送到overlay网络中,再送到远端。

Avatar_small
依云 说:
Nov 06, 2018 01:17:51 PM

ss 不是 TCP over TCP。它就一代理协议,其上走的是应用层数据而不是 TCP。tun 的实现也只是本地端的处理。

Aaron 说:
Nov 18, 2018 11:49:00 AM

我最近发现一件事 Wireguard在家里时,周一到周六,一直连接失败,日志显示一直握手失败。但是到周日一切正常。 在公司时不会出现这个情况。 我怀疑是家里的网络有QOS限制,请问有办法解决吗?

在问一个问题,国内有一台服务器 A, 国外有一台服务器 B, 家里有一台电脑 C。 C 不能直接连接 B, 但是 A 能连 B。 我该如何让 A 做中转, C访问A时,实际访问的是B 服务器。 这个有点类似路由器的端口映射,只不过我这个映射是外网的服务器,而不是内网的。

Avatar_small
依云 说:
Nov 18, 2018 12:39:24 PM

没什么办法,除了伪装成 TCP 那个方案。

你可以让 C 通过 VPN 连接到 A,然后做路由:
ip r add B/32 via A在VPN上的地址

注意 A 上需要配置好 NAT。

Afan 说:
Nov 19, 2020 10:12:28 PM

你好,博主,我用wireguard能连上远端centos7服务器,可以用samba在本地添加共享目录并可以上传下载文件,但是本地win10却不等上网?博主这个是什么原因?

Avatar_small
依云 说:
Nov 19, 2020 11:35:49 PM

我不用 samba 更不用 win10 呢。我甚至都不知道 win10 上能跑 wireguard 了……


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter

| Theme: Aeros 2.0 by TheBuckmaker.com