友情提示:380元/半年,儿童学编程,就上码丁实验室。
搭建VPN服务器
说明
虽然免费、未加密的无线AP遍地都是,但是你不应该连接这些AP来登陆你的网银账户,除非你对他人的窥视毫不在意。那么对此的解决方案是什么呢?一个虚拟专用网,也就是VPN(virtual private network)。
一个VPN可以使你的私有网络拓展至公共场所,因此即使你连接着星巴克的 Wi-Fi,你的网络浏览仍然保持着安全的加密。
准备
- Open VPN:这是一个开源VPN服务软件
- 准备好NOOBS并且安装完Raspbian
- 为树莓派设置内网静态IP地址
- 需要启用SSH
- 路由器的1194端口映射至树莓派的内网IP地址
网络访问路径图
-
如下图所示,假设我们在北京访问百度http网站,ISP是北京联通,百度的服务器在电信,ISP是广东电信。如果没有连接VPN,那么全程数据都是不加密的,用红线表示。
-
如果使用了VPN,那么从用户到VPN这块通信是经过加密的(绿线表示),无法截取通信内容。不过VPN服务器到目的网站这块还是原来的未加密,如下图:
安装必要软件及安全措施
- 启动并修改树莓派的密码
sudo passwd
- 软件包的升级
sudo apt-get update
sudo apt-get upgrade
- 安装open vpn
sudo apt-get install openvpn
生产密钥
只让有密钥的链接我们的VPN
OpenVPN自带了Easy_RSA,一个轻量并容易的使用RSA加密方法的包。发明于1977年,RSA是第一个沿用至今仍旧可用的加密系统。加密的密钥是公开的,解密的密钥是保密的。如果你听说过比特币的工作原理,这些对你来说应该十分熟悉。
通过使用Easy_RSA,你可以使用软件带有的算法来生成一个独一无二的密钥。
- 首先获得树莓派的系统权限,就是将命令提示符中的"pi@raspberrypi"转换成"root@raspberrypi"。
sudo -s
- 这句命令在现有的终端中再次创建了一个拥有root权限的终端实例。我们需要获得root权限的原因是,如果我们没有root权限,树莓派将不会允许我们创建密钥。
接下来,输入:
cp -r /usr/share/doc/openvpn/examples/easy-rsa/2.0 /etc/openvpn/easy-rsa
在这句命令中,"cp"代表"复制","r"代表递归。这说明我们让电脑执行:复制这个目录以及此目录下的所有文件结构及文件。
- 在/2.0和/etc中间的空格表示我们将第一个目录地址的文件(一个实例文件)拷贝至第二个目录地址,就是你让OpenVPN寻找密钥的地址。
cd /etc/openvpn/easy-rsa
-
接下来,我们需要"cd",改变所在目录(change directory),来放置我们生成的Easy_RSA文件。一旦完成这步,我们需要打开文件/etc/openvpn/easy-rsa/vars来编辑。我们可以使用nano: nano /etc/openvpn/easy-rsa/vars,由于我们已经在此目录下了,我们可以使用简写:
nano vars
Nano是Raspbian中内置的文件编辑工具,当然也有其他工具提供给屌丝们,不过我们将在此教程中只使用nano。
- 现在,将你的 EASY_RSA 变量改为:
export EASY_RSA="/etc/openvpn/easy-rsa"
对我的环境来说,这是在第13行。
为什么要修改这个变量呢?其实这是你在回答计算机的问题"你想让文件生成在哪里?"。在这个情况下,我们想要将其生成在我们保存key的同一个目录,在这里是easy-rsa文件树的顶层。
在vars文件中我们还可以做一件事,如果你对黑衣众们阅读你的邮箱这件事十分在意的话,你可以将加密方法从1024-bit改至2048-bit。在vars文件中,它明显的指出,"偏执狂请将此改为2048!"。
但是因为这个方法大大增长了生成密钥的时间,我们不会在这个教程中使用它。保持下面这个样子:
export KEY_SIZE=1024
按下Control+X来保存修改并退出nano。
加密
- 现在该搭建CA证书和Root CA证书了。
在加密学中,一个授权机构(certificate authority (CA))是一个颁布电子证书的存在。电子证书来证明公钥的所有者。
你可能一直在使用它只是你自己不知道而已。举个例子,当我登陆我的网银账户时,我可以在网页地址前看到HTTPS字符。当我点击HTTPS前的锁时,我会看到一个叫做GeoTrust的公司验证了我网银页面的合法性,因此我知道这不是一个钓鱼欺诈网站。(当然最近的Heartbleed漏洞指出HTTPS并不是我们想得那么安全)。
在树莓派这个例子中,我作为我自己的授权机构,自己为OpenVPN签字,而不是通过一个第三方公司。
cd /etc/openvon/easy-rsa
- 现在我们又改变了所在目录,将下面命令一行接一行输入终端:
source ./vars → 这个"source"加载你之前修改的文件(vars)。
./clean-all → 这会删除之前所有的密钥文件,如果有的话。如果在这个文件目录下有你不想删除的密钥文件(比如这是你第二次尝试这篇教程),跳过这条命令。
./build-ca → 最后一条来生成你的授权机构。
再输入第三条命令之后,树莓派会弹出一堆选项,你可以填写这些选项如果你愿意的话--国家名字,州名或省名,位置名,机构名,机构单位和电子邮件地址。如果你不想填写,只要在每个选项出现时按"enter"就行了,树莓派会使用默认值。下面的截屏展现了这些选项的长相:
- 现在你可以为你的服务器命名了。我很“创新”地将其命名为"Server"。你可以取任意的名字,不过别忘记输入:
./build-key-server [Server_Name]
- 再次,树莓派会给出一系列的选项,请随便输入,但注意以下几个选项:
Commom Name 必须是你为服务器取的名字。
A challenge password? 必须啥也不输,回车即可。
Sign the certificate? [y/n] 废话,你必须输入"y"。
你接下来会看到一段消息说你的证书会在接下来的3650天中有效的信息。因此,如果你打算长期使用这个VPN的话,你必须在十年后重新走这个流程。
1 out of 1 certificate requests certified, commit? [y/n] 明显,输入"y"。
- 服务器端就这么设置好了。现在该为各位用户生成密钥了,或者说"客户"。我为家里的计算机,平板,手机各生成了一个密钥,总共有5个。不要以为在所有客户端使用同样的密钥就可以节省时间,这样的话,一次只能有一个设备能访问VPN。
./build-key-pass UserName
我发现采用用户名 Client1, Client2, Client3…十分方便
在这之后,更多信息会弹出!
Enter PEM pass phrase 设置其为你记得住的密码!他会让你输入两次,不会有几率输入错误。
A challenge password? 必须留空!
Sign the certificate? [y/n] 同样签十年。
cd keys
openssl rsa -in Client1.key -des3 -out Client1.3des.key
留意我们使用des3加密生成的字符串文件,des3是一个复杂加密算法会在每一个数据块上运行3次,来防止骇客的暴力破解。OpenSSL 代表开源的加密套接字实现,是一个建立安全连接的标准方法。你需要为你生成的每一个客户端运行这一步。
有人会说这一步完全没有必要,你可以跳过这一步。但是如果你通过Android或者iOS设备连接OpenVPN,那么你必须要做这一步,不然的话目前版本在解析你的密钥时会有一些困难产生。
Enter pass phrase for Client1.key
说实话,我用了和以前一样的密码。再输入一遍,就想说的那样。
现在我们已经创建了服务器证书以及至少一个客户端证书,输入以下命令:
cd /etc/openvpn/easy-rsa/
或者
cd ..
两种方法都会将你的所在目录带会/easy-rsa/。
- 现在该生成Diffie-Hellman key exange了。这是使你的VPN工作的关键代码,一个使两个没有先前信息的双方通过服务器交换密钥的协议。像RSA一样,这是现有的最早发明的加密系统。
./build-dh
这一步会花一些时间,甚至比2048-bit加密还要慢。而且没有任何方法可以预测它运行的时间,因为这个算法使用的是随机数并寻找一些特定的关系。事实上,在我写这篇教程时,1024-bit加密只花了我5分钟。
- 最后,我们要实现OpenVPN内建的服务阻断攻击(Denial of Service — DoS)防护。你可能已经知道服务阻断攻击是骇客找到你的服务器地址后很有效的攻击手段,这种攻击通过生成大量的访问请求来使你的服务器崩溃。
输入以下代码来生成静态的HMAC(hash-based message authentication code)密钥:
openvpn --genkey --secret keys/ta.key
配置
- 我们已经生成了密钥以及来签名的授权机构。剩下的只是如何告诉OpenVPN如何配置这个服务器了。
因为我们在树莓派上使用在没有图形用户界面的Linux操作系统,我们需要生成一个.conf (configuration) 文件来告诉OpenVPN如何配置服务器,而不是通过图形界面的选择。用nano打开.conf文件:
nano /etc/openvpn/server.conf
我们在这个目录下打开.conf文件的理由是,编辑完此文件会直接生成在/etc/openvpn的目录中。但是你刚刚打开的这个文件是空的。将如下的配置复制入编辑器。在配置中我用大写字符注释了你必须要更改的地方,具体可以看注释。按下 Control+X 来保存文件。
local 192.168.2.0 # SWAP THIS NUMBER WITH YOUR RASPBERRY PI IP ADDRESS
dev tun
proto udp #Some people prefer to use tcp. Don't change it if you don't know.
port 1194
ca /etc/openvpn/easy-rsa/keys/ca.crt
cert /etc/openvpn/easy-rsa/keys/Server.crt # SWAP WITH YOUR CRT NAME
key /etc/openvpn/easy-rsa/keys/Server.key # SWAP WITH YOUR KEY NAME
dh /etc/openvpn/easy-rsa/keys/dh1024.pem # If you changed to 2048, change that here!
server 10.8.0.0 255.255.255.0
# server and remote endpoints
ifconfig 10.8.0.1 10.8.0.2
# Add route to Client routing table for the OpenVPN Server
push "route 10.8.0.1 255.255.255.255"
# Add route to Client routing table for the OpenVPN Subnet
push "route 10.8.0.0 255.255.255.0"
# your local subnet
push "route 192.168.2.0 255.255.255.0" # SWAP THE IP NUMBER WITH YOUR RASPBERRY PI IP ADDRESS
# Set primary domain name server address to the SOHO Router
# If your router does not do DNS, you can use Google DNS 8.8.8.8
push "dhcp-option DNS 192.168.2.1" # This should already match your router address and not need to be changed.
# Override the Client default gateway by using 0.0.0.0/1 and
# 128.0.0.0/1 rather than 0.0.0.0/0. This has the benefit of
# overriding but not wiping out the original default gateway.
push "redirect-gateway def1"
client-to-client
duplicate-cn
keepalive 10 120
tls-auth /etc/openvpn/easy-rsa/keys/ta.key 0
cipher AES-128-CBC
comp-lzo
user nobody
group nogroup
persist-key
persist-tun
status /var/log/openvpn-status.log 20
log /var/log/openvpn.log
verb 1
- 让我们快速地编辑一下另一个配置文件。在默认配置下树莓派并不会转发网络流量,我们需要另一个配置文件来使树莓派启用对我们新建网络中的网络流量的转发。
nano /etc/sysctl.conf
在文档开头处有注释:"取消下一行的注释来启用IPv4中的数据包转发。"("Uncomment the next line to enable packet forwarding for IPv4。")。我在下面的截图中高亮了这部分。
删除那一行前面的 # 来取消注释这一行。这告诉树莓派要对IPv4的数据包进行映射。当你取消注释了这一行,树莓派就拥有了作为互联网的中继而不是单单的接受者的权限,可以既接受并发送数据包。
按下 Control+X 来保存修改。通过以下命令启用此配置:
sysctl -p
sysctl命令表示"在运行中改变内核配置参数"。-p 告诉计算机重新加载你刚刚修改的配置文件。
- 到这一步我们以及配置完了一个拥有互联网访问权限的工作中的服务器。但是我们还不能用它,用为树莓派有内置的防火墙来限制传输入的网络连接。
Raspbian的防火墙会在来路不明的互联网源头中保护你的树莓派。我们仍然需要防火墙来保护我们,但是我们要在防火墙中挖一个OpenVPN样子的洞,使OpenVPN的连接可以顺利通过。
此外,Raspbian的防火墙会在重启后默认进行重置。我们需要创建一个简单的脚本使树莓派记住每次重启时对OpenVPN的连接进行允许。
nano /etc/firewall-openvpn-rules.sh
这是一个空文件,输入以下内容:
#!/bin/sh
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j SNAT --to-source 192.168.XX.X
不要忘记将默认IP地址改为你树莓派的IP地址!
解释下这条命令: 10.8.0.0 是客户端连接树莓派VPN后树莓派的默认地址。 "eth0"代表以太网接口。 如果你使树莓派用无线连接互联网的话将其改为"wlan0", 当然我不建议你这么做。 按下 Control+X 保存编辑。
为了安全考虑, 我们要改变/etc/firewall-openvpn-rules.sh的所有者,使此文件默认不可被运行。 首先将权限设定为700 (所有者可以读、写、执行)。 然后,我们会将此脚本的所有者改为root,,在Linux标准系统中,root代表系统管理员。
chmod 700 /etc/firewall-OpenVPN-rules.sh
chown root /etc/firewall-OpenVPN-ruels.sh
- 我们已经创建了一个在防火墙中开出OpenVPN形状的洞,我们现在只需要将这个脚本插入到网络interface初始化的代码中,然后它就会在每次开机时运行了。
nano /etc/network/interfaces
找到带有"iface eth0 inet dchp"的那一行。 我们需要在这行之后的缩进中加上一行。 下面是这两行,一行新加入,一行原来就存在,在完成之后它应该差不多像这样:
iface eth0 inet dhcp
pre-up /etc/firewall-openvpn-rules.sh
按下 Control+X 保存更改 (当你在使用nano的时候都应该这么做)。
最后,再最后, 再最最后:重启树莓派。
sudo reboot
恭喜你!!vpn服务器就这么搭建完成了,当然如果没有客户端连接服务器的话,服务器也没什么用,因此你应该牢记你前面创建生成的用户名及密钥。
建立加密客户端
- 我们已经为需要连接VPN的不同客户端创建了不同的密钥。我们将客户端命名为 Client1、 Client2 和 Client3等。
但是为每个客户端从零单独生成一个配置文件会造成很多不必要的麻烦,这就是为什么我们需要使用SANS institute的Eric Jodoin写的巧妙的脚本。这个脚本会帮助我们生成那些配置文件。
这个脚本会访问我们的默认设置,从而为每一个客户端生成各自的配置文件。我们需要做的第一件事是,创建一个空的文本文档并写入我们的默认配置,以便脚本读取。
nano /etc/openvpn/easy-rsa/keys/Default.txt
在空白文件中写入如下配置:
client
dev tun
proto udp
remote <你的公网ip地址> 1194
resolv-retry infinite
nobind
persist-key
persist-tun
mute-replay-warnings
ns-cert-type server
key-direction 1
cipher AES-128-CBC
comp-lzo
verb 1
mute 20
这个文档应该看起来和下面的截屏差不多,除了你应该填入你自己的公网ip地址之外。你注意到了我已经把我的公网ip删除了,当然这是为了保护我的隐私。相对而言,每个人的本地静态ip则都差不多,他们通常都以 "192.168." 起头。
如果你没有一个静态的公网ip的话,你需要使用动态DNS服务来给你自己一个域名来代替公网ip。我建议你使用免费服务DNS Dynamic,它允许你取一个自己选择的名字。然后在你的树莓派上,你需要运行DDclient来自动更新你的DDNS注册信息。我在这里写过一篇完整的教程。
同样,按 Control+X 来保存文件并推出nano。
- 接下来,我们需要创建一个要用到的脚本。这个可执行脚本通常从shell中启动,可以自动化一些我们需要做的工作。
nano /etc/openvpn/easy-rsa/keys/MakeOPVN.sh
这里是脚本文件,它由Jodoin编写。将内容复制粘贴至编辑器(注意一下复制粘贴中产生的问题)。
你需要将执行权限赋予给这个脚本。首先改变所在目录:
cd /etc/openvpn/easy-rsa/keys/
然后只让root有访问权限。如果你还记得第一部分教程的内容的话,Linux中的权限管理由不同的3位数字代表。700表示"所有者可以读、写、执行"。
chmod 700 MakeOPVN.sh
最后,执行文件:
./MakeOPVN.sh
在脚本运行途中,他会要求你输入现有的客户端名称。例如: "Client1"。注意只输入已经存在的客户端名称。
如果一切正常的话,你应该会看到下面这行字弹出:
Done! Client1.opvn Successfully Created.
为剩下的客户端都重复执行这一步。
- 最后要做的事是将客户端连上树莓派,然后你就可以让客户端下载这些配置文件了。你需要使用一个SCP (Secure Copy Protocol)客户端来实现它。在Windows中,我推荐WinSCP。而我在mac中一直使用Fugu。
注意:如果你没有连接SCP客户端的权限,你需要为自己授权在此文件夹的读/写的权限。回到树莓派中输入:
chmod 777 -R /etc/openvpn
注意在你复制完文件后要取消这一步,以防止其他人从这里下载文件!完成之后将权限改为600, 仅让 用户 pi 能读/写文件:
chmod 600 -R /etc/openvpn
完成后回到客户端.
- 好了,困难的部分都结束了。从这里开始我们需要将之前生成的脚本输入到客户端的图形用户界面。对PC、Android或者iOS手机来说,你可以下载OpenVPN Connect。但是这个软件没有mac版,所以我尝试了Tunnelblick和Viscosity。
Tunnelblick 是免费的,但是Viscosity在免费30天试用之后需要9美刀来购买。不管怎么样,我们来尝试下将mac连入我们的服务器吧。
在我的情况下,mac是我第5个连接VPN的客户端,所以我生成的文件名叫做client5.opvn。
下载可以在你的OS X版本下运行的Tunnelblick。我在使用Mavericks,所以我下载了beta版。虽然这个软件有很多我看起来搞笑的对话框弹出,但是我下载的可不是盗版。
接着它会问你是否有了配置文件,我当然已经有了:Cientt.opvn。
然后它会问你,你的配置文件是.opvn或.tblk。如果你选择了.opvn它会帮你将文件格式转换成Tunnelblick自己的格式。我把Client5.opvn放到Tunnelblick指定的文件夹,然后把文件夹的名字改为了Client5.tblk。
好啦,你已经可以连接了。点击屏幕右上方Tunnelblick的标志然后选择Client5。
它会让你输入密码,这个密码就是上篇中我们生成各个客户端时使用的密码。
如果你密码输入正确,看起来就会如上图。
尝试在咖啡厅, 图书馆或任何有免费WiFi的地方连接VPN。通过使用VPN,即使你连接的是公共网络,你的数据仍然是安全的。
参考:
- https://linux.cn/article-3105-1.html
- https://linux.cn/article-3109-1.html
- http://readwrite.com/2014/04/10/raspberry-pi-vpn-tutorial-server-secure-web-browsing
- http://readwrite.com/2014/04/11/building-a-raspberry-pi-vpn-part-two-creating-an-encrypted-client-side