当前位置:Linux教程 - Linux - 如何建立虚拟私有网路(VPN)

如何建立虚拟私有网路(VPN)

作者: Arpad Magosanyi
译者: 蒋大伟

v0.2, 7 August 1997 翻译完成日期: 20 Feb 1999
_________________________________________________________________

如何建立虚拟私有网路(Virtual Private Network)。
_________________________________________________________________

1. 更正

2. 推荐广告

* 2.1 版权声明
* 2.2 免责声明
* 2.3 郑重声明
* 2.4 功劳
* 2.5 本文的现况
* 2.6 相关文件

3. 介绍

* 3.1 命名惯例

4. 开始建置

* 4.1 规划
* 4.2 搜集工具
* 4.3 编译与安装
* 4.4 其它子系统的设定
* 4.5 设定 VPN 的使用者帐户
* 4.6 为 master 帐户,产生一个 ssh key
* 4.7 为 slave 帐户,设置自动的 ssh 登入环境。
* 4.8 加强 ssh 在 bastion 主机上的安全性。
* 4.9 允许 ppp 的执行,和这两个帐户的路由。
* 4.10 撰写命令稿程式

5. 让我们检视执行的结果:

6. 著手执行。

* 6.1 登入
* 6.2 启动 ppp
* 6.3 一次完成两个动作
* 6.4 Pty 的重导功能
* 6.5 这个装置上面,会有些什麽东西?
* 6.6 设定路由

7. 调整

* 7.1 设定的调整
* 7.2 频宽与安全谁重要

8. 分析易受攻击的弱点
_________________________________________________________________

1. 更正

no controlling tty problem -> -o BatchMode yes 是由 Zot OConnor
所更正。

核心 2.0.30 的警告讯息,是由 mag 所更正。

2. 推荐广告

这份文件是 Linux VPN howto,它收集了如何在 Linux (以及一般的 UNIX) 上建立 一个虚拟保护式网路的相关资讯。

2.1 版权声明

这份文件是 Linux HOWTO 计划的一部分。它的版权声明如下:除非特别说明,Linux HOWTO 文件的版权归属他们各自的作者所有。Linux HOWTO 文件的全部或部分,可以 使用任何物理或电子形式的媒体来复制与散布,只要这个版权声明被保留在每份拷贝 中。商业行为的再散布是被允许而且受欢迎的;但是,任何的散布行为作者都希望能 被告知。所有翻译、衍生的工作、或合并任何 Linux HOWTO 文件的聚集工作,都必须 受到这个版权声明的保护。也就是说,你不可以从 HOWTO 衍生出一份文件,然後对这 份衍生文件的散布强加上其他限制条件。
除非在一些特定的状况下,才会允诺这些限制 条件;请联络 Linux HOWTO 的协调人,他的地址如下。简而言之,我们希望能够尽可 能透过各种管道,来推动这个资讯的散布工作。然而,我们也希望保留 HOWTO 文件的 版权,以及如果有任何对 HOWTOs 的再散布计划也希望能够被通知到。如果有任何疑问 ,请联络Linux HOWTO 协调人 Tim Bynum,他的电子邮件地址是[email protected]

2.2 免责声明

一如往常:本文对你所造成的任何危害,作者一概不负责任。正确的条文,请参阅 GNU GPL 0.1.1 的相关部分。

2.3 郑重声明

我们所面临的是安全性的问题:如果你没有形成一个好的安全策略,以及做好相关的配套 措施,你将无法获得真正的安全。

2.4 功劳

感谢所有提供工具程式给本文使用的人仕。

感谢 Zot OConnor 不仅指正“no controlling tty”的问题,而且还提供了解决方法。

2.5 本文的现况

在阅读本文前,你应该已具备完整的 IP 管理知识,至少要对“防火墙(firewall)”、ppp 、和 ssh ,等知识,有一些了解。如果你要设定一个
VPN 环境,无论如何一定得知道这些 东西。我只是将我的经验写下来 ,以免日後忘记相关的内容。所以,我相信一定会有安全 的漏洞存在。为了清楚起见,我试著以主机设置为路由器方式,而不是以防火墙的方式,来 说明整个内容,希望大家轻轻松松就能够了解本文。

2.6 相关文件

* 档案 /usr/doc/HOWTO/Firewall-HOWTO 上的 Linux Firewall-HOWTO 文件
* 档案 /usr/doc/HOWTO/PPP-HOWTO.gz 上的 Linux PPP-HOWTO 文件
* 目录 /usr/doc/ssh/* 中的 ssh 文件
* Linux “网路管理指引(Network Admins Guide)”
* 国家标准及技术委员会 (National Institute Standards and Technology,简写为 NIST) 在电脑安全方面的出版品,请参考网址
http://csrc.ncsl.nist.gov/nistpubs/
* “防火墙通信论坛(Firewall list)” ([email protected])

3. 介绍

由於网路安全问题日益受到重视,所以,防火墙的技术越来越广泛地被应用在,网际网路 和“公司内部网路(intranet)”上,防火墙能力的优劣,对 VPN 的安全性有著举足轻重的 影响。这只是我个人的体会。欢迎大家提出自己的看法。

3.1 命名惯例

我将会使用到“主防火墙(master firewall)”和“次防火墙(slave firewall)”这两个专 有名称,然而,VPN 的建置与主仆式架构之间没有任何关联性。我只是把它们看成,两端在 建立连线时,它是个主动的参与者或被动的参与者。发起建立连线的主机,会被当作主防火 墙;然而,被动的参与者,就会被当作次防火墙。

4. 开始建置

4.1 规划

在你开始设定系统前,你应该要先了解一下网路连接的细节。现在,我假定你有两个防火墙 ,各保护一个公司内部网路。所以,现在每个防火墙应该会有两个网路界面(至少)。拿一 张纸,写下它们的 IP 位址和网路遮罩。每个 VPN 的防火墙,将会使用到数个 IP 位址区 段。这些 IP 位址区段,应该设定在你公司现有的子网路的□围以外。我建议使用“私有” IP 位址区段的□围。如下所示:

* 10.0.0.0 - 10.255.255.255
* 172.16.0.0 - 172.31.255.255
* 192.168.0.0 - 192.168.255.255

为了说明,此处我举了一个设定的案例:有两台 bastion [译注] 主机,分别被称为 fellini 和 polanski。它们各有一个界面连接网际网路 (-out),一个界面连接公司内部网路 (-in) ,以及,一个界面连接 VPN (-vpn)。所有的 IP 位址和网路遮罩,如下:

* fellini-out: 193.6.34.12 255.255.255.0
* fellini-in: 193.6.35.12 255.255.255.0
* fellini-vpn: 192.168.0.1 点对点
* polanski-out: 193.6.36.12 255.255.255.0
* polanski-in: 193.6.37.12 255.255.255.0
* polanski-vpn: 192.168.0.2 点对点

译注: bastion 是指暴露在公司网路外部的防火墙闸道。

所以我们有个计划。

4.2 搜集工具

你将会需要
* Linux 防火墙
* 核心
* 非常少的设定
* ipfwadm 程式
* fwtk 程式
* VPN 所使用的工具
* ssh 程式
* pppd 程式
* sudo 程式
* pty-redir 程式

目前使用的版本:
* 核心: 2.0.29 。请使用稳定的核心,而且,必须比 2.0.20 还新,因为pingodeath 的错误。在撰写本文时,最後一个稳定的核心是版本 2.0.30,但是它有一些错误。如果 ,你想要使用最新版核心所提供,既快又酷的网路程式码,你自己可以尝试看看,版本 2.0.30 对我而言,已经很好用了。
* 基本的作业系统:我比较喜欢 Debian 所发行的版本。你绝对使用不到任何大型的 软体套件,当然,也包含 sendmail 在内。你也绝对不能像其它的UNIX 主机一样,允许 telnet、ftp、和 r 命令,等功能的使用。
* ipfwadm 程式: 我使用的是 2.3.0。
* fwtk 程式: 我使用的是 1.3。
* ssh 程式: >= 1.2.20。较旧的版本,下层的协定会有问题。
* pppd 程式: 我测试的是 2.2.0f,但是我无法确定它是否安全,这就是为什麽我会 将它的 setuid 位元拿掉,并透过 sudo 来执行它的原因。
* sudo 程式: 我所知道的最新版本是 1.5.2。
* pty-redir 程式: 这是我写。请至
ftp://ftp.vein.hu/ssa/contrib/mag/pty-redir-0.1.tar.gz 取得。现在的
版本是 0.1 。如果使用上有任何问题,请来信告知。

4.3 编译与安装

你现在的工作不是编译就是安装所搜集到的工具。 并参阅其(以及
firewall-howto) 详细的说明文件。现在,我们已经安装好这些工具了。

4.4 其它子系统的设定

设定防火墙以及其它的项目。你必须在两台防火墙主机之间,允许 ssh 资料的流通。这 是指,主防火墙会有网路连线到次防火墙的埠 22。在次防火墙上启动sshd,来验证是否 允许你“登入(login)”。这个步骤尚未测试过,请告诉我你的测试结果。

4.5 设定 VPN 的使用者帐户

以你日常使用的工具(例如,vi、mkdir、chown、chmod)在次防火墙上建立一个使用者帐 户,你也可以在主防火墙上建立一个使用者帐户,但是,我认为在开机阶段设定连线就可以 了,所以,使用原始的 root 帐户就已足够。有任何人可以为我们说明一下,在主防火墙上 使用 root 帐户,会有什麽危险性?

4.6 为 master 帐户,产生一个 ssh key

你可以使用 ssh-keygen 程式。如果,你要自动设置 VPN,你可以设定一个没有密码的 “私人钥匙(private key)”。

4.7 为 slave 帐户,设置自动的 ssh 登入环境。

在次防火墙中,复制你刚才产生的“公共钥匙(public key)”到,使用者帐户slave 中 的 .ssh/authorized_keys 档案里,并且,设定档案的使用权限,如下:

drwx------ 2 slave slave 1024 Apr 7 23:49 ./
drwx------ 4 slave slave 1024 Apr 24 14:05 ../
-rwx------ 1 slave slave 328 Apr 7 03:04 authorized_keys
-rw------- 1 slave slave 660 Apr 14 15:23 known_hosts
-rw------- 1 slave slave 512 Apr 21 10:03 random_seed

其中,第一行是 ~slave/.ssh,第二行是 ~slave。

4.8 加强 ssh 在 bastion 主机上的安全性。

请按照我在 sshd_conf 上的设定:

PermitRootLogin no
IgnoreRhosts yes
StrictModes yes
QuietMode no
FascistLogging yes
KeepAlive yes
RhostsAuthentication no
RhostsRSAAuthentication no
RSAAuthentication yes
PasswordAuthentication no
PermitEmptyPasswords no

密码认证(PasswordAuthentication)被关闭了,所以,你只有使用授权过的 key,才能够 完成登入的动作。(当然,你也已经关闭了,telnet 与 r 命令)。

4.9 允许 ppp 的执行,和这两个帐户的路由。

当你的 master 帐户是 root 时(以我的例子而言),你不必做任何事情。至於slave 帐户,则会在你的 /etc/sudoers 的档案中出现一行:

Cmnd_Alias VPN=/usr/sbin/pppd,/usr/local/vpn/route
slave ALL=NOPASSWD: VPN

正如你所看到的,我在次防火墙主机上,使用了一些命令稿(scripts),来设定ppp 和路由表。

4.10 撰写命令稿程式

在主防火墙主机上,我使用了一个成熟的启始命令稿:
#! /bin/sh
# 程式架构 这个档案是个建立在 /etc/init.d/ 目录下的命令稿实例。
# 你应该在 /etc/init.d 目录下使用这个命令稿。
#
# 作者 Miquel van Smoorenburg .
# Debian GNU/Linux 修订版作者
# Ian Murdock .
#
# 版本: @(#)skeleton 1.6 11-Nov-1996 [email protected]
#

PATH=/usr/local/sbin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/bin/X11/:
PPPAPP=/home/slave/ppp
ROUTEAPP=/home/slave/route
PPPD=/usr/sbin/pppd
NAME=VPN
REDIR=/usr/local/bin/pty-redir
SSH=/usr/bin/ssh
MYPPPIP=192.168.0.1
TARGETIP=192.168.0.2
TARGETNET=193.6.37.0
MYNET=193.6.35.0
SLAVEWALL=polanski-out
SLAVEACC=slave

test -f $PPPD || exit 0

set -e

case ""$1"" in
start)
echo setting up vpn
$REDIR $SSH -o Batchmode yes -t -l $SLAVEACC $SLAVEWALL sudo $PPPAPP
>/tmp/device
TTYNAME=``cat /tmp/device``
echo tty is $TTYNAME
sleep 10s
if [ ! -z $TTYNAME ]
then
$PPPD $TTYNAME ${MYPPPIP}:${TARGETIP}
else
echo FAILED!
logger ""vpn setup failed""
fi
sleep 5s
route add -net $TARGETNET gw $TARGETIP
$SSH -o Batchmode yes -l $SLAVEACC $SLAVEWALL sudo $ROUTEAPP
;;
stop)
ps -ax | grep ""ssh -t -l $SLAVEACC "" | grep -v grep | awk {print $1}
| xargs kill
;;
*)
# echo ""Usage: /etc/init.d/$NAME {start|stop|reload}""
echo ""Usage: /etc/init.d/$NAME {start|stop}""
exit 1
;;
esac

exit 0

slave 帐户可以使用命令稿来设定路由 (/usr/local/vpn/route):
#!/bin/bash
/sbin/route add -net 193.6.35.0 gw 192.168.0.1

而其 .ppprc 的内容,如下:
passive

5. 让我们检视执行的结果:

master 会登入到 slave 帐户里、启动 pppd、以及,将所有的资料重导至本机的pty( 虚拟终端机)。整个执行流程如下:

* 配置一个新的 pty
* 透过 ssh 登入 slave 帐户
* 在 slave 帐户中执行 pppd
* master 在本机的 pty 执行 pppd
* 并且在用户端设定路由表。

此处我们考虑到了时序的问题(不是太严格的要求),这就是为什麽我们会使用到 sleep 10s 这个叙述的原因。

6. 著手执行。

6.1 登入

现在,你应该已经测试过 ssh 是否能够正常地工作。如果,slave 拒绝你登入,请阅读 记录档。也许是档案使用权限或 sshd ,在设定上的问题。

6.2 启动 ppp

登入到 slave 帐户,并执行:
sudo /usr/sbin/pppd passive

此时,如果工作正常你应该会看到一些乱码。假设,没有出现乱码,不是 sudo就是 pppd 有问题。请参考,记录档、/etc/ppp/options 和 .ppprc ,等档案,以便找出是那个命令出了问题。问题排除後,将 passive 这个字写到.ppprc 里,然 後再试一次。以压下 enter、~、和 ^Z等按键的方式,清除萤幕上的乱码,继续 工作。现在,你应该会看到 master 的“输入提示符号(prompt)”,然後执行 kill %1 。如果你想知道更多有关“逸出字元(escape
character)”的说明,请参阅“调整(tuning)” 那一节。

6.3 一次完成两个动作

当然,你也可以这麽做

ssh -l slave polanski sudo /usr/sbin/pppd

如果工作正常,它就会当著你的面,传送一些看似乱码的资料。

6.4 Pty 的重导功能

这次,我们试著重导上面的动作:
/usr/local/bin/pty-redir /usr/bin/ssh -l slave polanski sudo /usr/sbin/pppd

好长的句子,不是吗?你应该使用 ssh 执行档的完全路径名称,为了安全的理由,pty-redir 程式只允许你使用这种方式。现在,你会透过这个程式取得一个装置名称。假设,你取得的 是 /dev/ttyp0 。你可以使用 ps 命令来检视目前的状况。请找寻 p0 这个装 置的相关叙述。

6.5 这个装置上面,会有些什麽东西?

试著执行
/usr/sbin/pppd /dev/ttyp0 local 192.168.0.1:192.168.0.2

来建立连线。然後,检视 ifconfig 命令的输出结果,看是否已经建立了这个装置,然後 ,使用 ping 来检查你的虚拟网路。

6.6 设定路由

除了设定主防火墙主机的路由,次防火墙主机也要设定。现在,你应该能够从公司的一个 内部网路上的主机,ping 到其它内部网路上的主机。接著,设定额外的防火墙规则。现 在,你已经拥有了 VPN 的环境,你可以设定公司两个内部网路之间的连接规则。

7. 调整

7.1 设定的调整

正如我所说的,这份文件只是我个人设定 VPN 的备忘录而已。设定中有部分的内容,我还 未测试过。等到我测试过後,会给它们正确的定位,或有任何人告诉我“它是如何工作的” 。有个最重要的事情大家必须铭记在心,ppp 网路连线尚未使用 8-bit。我自己也觉得 ssh 或 pty 的设定,一定还有要加强的地方。在ssh 的设定中,使用了“颚化符号(tilde)” (~) 字元做为逸出字元。它可以停止或减缓两端之间的通讯,当任何的“新行符号- 颚化符号(newline-tilde)”逸出顺序的出现,会使得 ssh 跳到输入提示符号的模式。ssh 的文件上说: < 在大部分的系统上,若设定不使用逸出字元,则就算是你使用了 tty ,也会造成通讯对话的透通化。> 这个功能相对於 ssh 的选项标记是 -e ,你也可以在设定档中设定它。

7.2 频宽与安全谁重要

不论建置任何的虚拟网路,都会浪费掉实际资源。VPN 会吃掉频宽和计算的资源。你的目标 应该是如何取得双赢的局面。你可以使用 -C 开关或CompressionLevel 选项,来调整 它。你也以尝试使用另一种加密法,但是,我并不建议这麽做。也请注意,如果你使用越高 的压缩等级,你传送资料的来回时间就越长。欢迎提供任何相关的测试报告。

8. 分析易受攻击的弱点

我试著在此处说明一下,这个特别的设定和 VPNs 一般有那些易受攻击的弱点。热诚地欢迎 各位发表任何意见。
* sudo 程式:我承认,我过度地使用了 sudo。我深信目前它仍然比使用
setuid bits 还安全。Linux 上仍然没有好的存取控制机制,是个不争的事实。只有等到相容 POSIX.6 标准的核心正式发行了<
http://www.xarius.demon.co.uk/software/posix6/>。更糟糕的是,我居
然透过 sudo 来呼叫执行 shell 的命令稿程式。实在糟糕透了。你有任何
建议麽?
* pppd 程式:它也会使用 suid root (译注) 的执行方式。你可以透过使用者的 .ppprc 来设定它。留心,它可能会有“缓冲区超限运转(buffer
overrun)”的状况发生。底限是 :尽可能地保护你的 slave 帐户的安全性。
* ssh 程式:当心,ssh 在 1.2.20 以前的版本有安全的漏洞。更糟糕的是,我们的 设定是,当我们对 master 帐户的安全性做出了让步,相对地,也弃守了 slave 帐户的安 全底限,而且,我们使用了两个透过 sudo 启动的程式,也大开了攻击之门。那是因为,为 了能够自动设定 VPN,我们选择让master 使用没有密码的“私人钥匙(secret key)”。
* firewall 程式: bastion 主机上的防火墙,若规则设定的不恰当,就等於是大开公 司内部网路的方便之门。我建议大家使用 IP“伪
装(Masquerading)”的技术(此时,就算是 路由设定不正确,所造成的影响也是微不足道的),以及,在 VPN 的界面上做严格的控制 。

译注: suid root 是指任何执行该程式的人,在执行的当时会取得 root 的权限。其中,suid( 设定使用者识别代码)是指设定档案属性的第 11 个位元,让执行该档案的人,成为档案的 拥有者。