如何设置“虚拟私有网路(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 O'Connor 所更正。 核心 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,他的电子邮件地址是 linux-howto@sunsite.unc.edu 。 2.2 免责声明 一如往常:本文对你所造成的任何危害,作者一概不负责任。正确的条文,请参 阅 GNU GPL 0.1.1 的相关部分。 2.3 郑重声明 我们所面临的是安全性的问题:如果你没有形成一个好的安全策略,以及做好相 关的配套 措施,你将无法获得真正的安全。 2.4 功劳 感谢所有提供工具程式给本文使用的人仕。 感谢 Zot O'Connor 不仅指正“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)” (majordomo@greatcircle.com) 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 还新,因为 ping'o'death 的错误。在撰写本文时,最後一个稳定的核心是版本 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 miquels@cistron.nl # 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 个位元,让执 行该档案的人,成为档案的 拥有者。