使用 GNU Virtual Private Ethernet

提供一个安全的通信信道涉及许多不同的问题,比如如何提供一个能够处理多个信息流的有效通信信道。通过有效地模拟整个网络堆栈并允许您在这个虚拟环境上构建 TCP、UDP 和其他网络技术,GNU Virtual Private Ethernet (GVPE) 提供常规单通道或多通道解决方案的一个替代方案。本文讨论如何使用 GVPE 和您的应用程序来提供通信,以及如何使用 GVPE 和您的网站通过专用和公共网络提供安全的连通性。特别是,您将学习如何将 GVPE 用于一些分布式基础结构项目,比如 Amazon EC2、云或公共/专用 web 性能部署。

Martin C. Brown, 作家, Freelance

Martin BrownMartin Brown 成为专业作家已有八年多的时间了。他是题材广泛的众多书籍和文章的作者。他的专业技术涉及各种开发语言和平台 — Perl、 Python、Java、JavaScript、Basic、Pascal、Modula-2、C、C++、Rebol、Gawk、 Shellscript、Windows、Solaris、Linux、BeOS、Mac OS/X 等等 — 还涉及 Web 编程、系统管理和集成。Martin 是 Microsoft 的主题专家(SME),并且是 ServerWatch.com、LinuxToday.com 和 IBM developerWorks 的定期投稿人,他还是 Computerworld、The Apple Blog 和其他站点的正式博客。您可以通过他的 Web 站点 http://www.mcslp.com 与他联络。



2011 年 4 月 25 日

传统虚拟专用网解决方案

大多数传统 VPN 解决方案通过支持单个连接进行工作。那个连接可能是从您的桌面计算机到您的办公室,这种连接可能会受到限制,只支持有限的传输协议,比如 TCP 和/或基于 UDP 的通信。

支持单个连接、甚至是一个网络和路由连接还不成问题,但当您向系统添加更多主机和/或更多网络时,系统将变得更加复杂。例如,如果一个 VPN 解决方案跨多个主机和多个网络,通过一系列不同的底层协议来提供通信,那么这个解决方案可能既复杂又耗资源。

图 1 展示了这样一个例子。使用常规 VPN 解决方案时,VPN Client 1 和 VPN Client 2 之间的通信只能通过 VPN Host 来路由所有网络流量才可能实现。这可能非常昂贵,特别是当各个主机全部位于同一个网络上,或通过 Internet 这样的公共接口进行通信时。

图 1. 典型 VPN 解决方案
一个典型 VPN 解决方案图示

如果您想要使用的应用程序是基于 TCP 或 UDP 的,那么协议限制不成问题。对于必须访问公司内联网(HTTP)或邮件服务(IMAP、SMTP)的情况,这些限制完全没有影响。但 VPN 解决方案中的路由和协议支持会受到一些限制。


使用 GNU Virtual Private Ethernet

GNU Virtual Private Ethernet 支持在多个主机上配置和构建一个完全虚拟的网络。与典型 VPN 的 “点到点” 方法不同,GVPE 支持在虚拟网络中建立任意数量的主机,而且,您可以随时启用和停用那些主机。

GVPE 还可以通过非传统连接方法进行工作,但本文不会详细介绍这一点。例如,您可以通过本地 IP、HTTP(包括通过代理)、DNS 和 ICMP 来路由支持虚拟网络的网络流量。对于受内部限制,不能通过 HTTP 代理连接到外部世界和公共网络上的设备的计算机,可以使用这种技术来在那些计算机之间构建一个虚拟网络。

通过 GVPE 创建的网络接口也是一个通用网络设备,因此您可以通过这种连接路由非 IP 协议。另外,在虚拟网络上发送的信息将被自动路由到正确的主机并在虚拟网络中配置,如 图 2 所示。

图 2. 使用 GVPE 的 VPN 解决方案
使用 GVPE 的 VPN 解决方案图示

与传统 VPN 相比,包路由和包分发要灵活得多。更重要的是,由于主机间通信能够基于各种不同的传输协议,GVPE 可用于创建一个存在于公共云(比如 Amazon EC2 和 IBM Cloud)、内部云和网格解决方案、桌面机和客户机上的主机上的虚拟网络。图 3 展示了一个示例。

图 3. 创建一个位于公共和专用网络上的虚拟网络
使用 GVPE 创建一个位于公共和专用网络上的虚拟网络的 VPN 解决方案

为方便起见,虚拟网络内的所有主机的配置信息都被共享,使得设置和扩展这个配置非常容易。


GVPE 安全性

GNU Virtual Private Ethernet 的安全性通过 OpenSSL 库,借助公共/私有密匙机制进行处理。虚拟网络中的每个主机都被提供一个惟一的主机密匙,公共版本用于加密通信信道。

同时,由于虚拟专用网基于支持的、以太网级网络环境的,为每个主机都提供一个惟一的 MAC 地址,和一个本地以太网上的情况一样。这意味着您可以通过发送者(和接收者,如果必要的话)的 MAC 地址来验证信息的来源,额外提供了一级安全性。

但是,鉴于简洁性和速度因素,安全网络的身份验证和设置只通过公共/私有密匙处理,而不是通过一个典型的密码或挑战应答机制(challenge response mechanism)。这意味着您可以在启动过程中设置并启用一个 GVPE 安装,从而允许在出现故障或重新启动时重新创建虚拟网络,而不必手动设置连接。


GVPE 安装

GVPE 可在在 Linux® 和许多 UNIX® 发行版上运行,但您可能需要安装其他网络驱动程序,以便创建一个动态网络设备。您可以查阅 gvpe.osdep 手册页,了解关于在各种平台上启用这个服务的更多信息,这样的平台包括 Solaris、Mac OS X 和 Windows®(使用 mingwcygwin)。鉴于这个安装的目的,我们将使用 Linux。

安装 GVPE 之前,您必须确保您的内核已经配置为包含 TUN/TAP 网络内核驱动程序。您需要在您的内核配置中启用这个配置。几个桌面 Linux 安装,包括 Debian/Ubuntu 和 Fedora,可能已经启用了 TUN/TAP 驱动程序。

为了继续安装,您还需要事先安装 OpenSSL 和 OpenSSL 头部/库。另外,安装之前,您应该决定要使用的加密和摘要方法,以及您的 OpenSSL 安装将支持的组件。

GVPE 支持 aes-128、aes-192、aes-256 和 bf (blowfish) 密码,支持 sha512、sha256、sha1、ripemd160、md5 和 md4 摘要算法。

可以通过 openssl 帮助确定受支持的密码和哈希格式列表,如 清单 1 所示。

清单 1. OpenSSL 帮助
$  openssl help
openssl:Error: 'help' is an invalid command.

Standard commands
asn1parse         ca                ciphers           crl
crl2pkcs7         dgst              dh                dhparam
dsa               dsaparam          ec                ecparam
enc               engine            errstr            gendh
gendsa            genrsa            nseq              ocsp
passwd            pkcs12            pkcs7             pkcs8
prime             rand              req               rsa
rsautl            s_client          s_server          s_time
sess_id           smime             speed             spkac
verify            version           x509

Message Digest commands (see the 'dgst' command for more details)
md2               md4               md5               mdc2
rmd160            sha               sha1

Cipher commands (see the 'enc' command for more details)
aes-128-cbc       aes-128-ecb       aes-192-cbc       aes-192-ecb
aes-256-cbc       aes-256-ecb       base64            bf
bf-cbc            bf-cfb            bf-ecb            bf-ofb
camellia-128-cbc  camellia-128-ecb  camellia-192-cbc  camellia-192-ecb
camellia-256-cbc  camellia-256-ecb  cast              cast-cbc
cast5-cbc         cast5-cfb         cast5-ecb         cast5-ofb
des               des-cbc           des-cfb           des-ecb
des-ede           des-ede-cbc       des-ede-cfb       des-ede-ofb
des-ede3          des-ede3-cbc      des-ede3-cfb      des-ede3-ofb
des-ofb           des3              desx              idea
idea-cbc          idea-cfb          idea-ecb          idea-ofb
rc2               rc2-40-cbc        rc2-64-cbc        rc2-cbc
rc2-cfb           rc2-ecb           rc2-ofb           rc4
rc4-40            rc5               rc5-cbc           rc5-cfb
rc5-ecb           rc5-ofb

注意,并非这里的所有摘要和密码都受到支持,但您的 OpenSSL 必须支持您想要使用的密码和摘要。

通过对 configure 脚本使用 --enable-digest 选项来设置要使用的摘要,使用 --enable-cipher 来设置要使用的密码。如果没有进行这个指定,将使用 ripemd160 摘要和 aes-128 密码。

您还需决定 gvpe 和 gvpe 配置文件的安装位置。默认前缀是 /usr/local(这将命令放置到 /usr/local/bin 中并在 /usr/local/etc/gvpe 中查找配置)。

完成上述决定后,执行以下操作编译并安装 GVPE:

  1. 下载 bvpe 包。
  2. 解压 gvpe 包:
    • $ tar zxf gvpe-2.2.tar.gz
  3. 切换到 gvpe-2.2 目录:
    • $ cd gvpe-2.2
  4. 运行 configure 设置您想要使用的选项:
    • $ configure --prefix=/usr/local --enable-digest=sha512 --enable-cipher=aes-256
  5. 编译:
    • $ make
  6. 安装:
    • $ make install

安装复制命令和文档,但配置文件需要针对每个系统分别设置。


设置一个虚拟网络

要设置一个虚拟网络,需要执行以下 6 个步骤。您可以对任意数量的机器执行以下操作,但为了进行演示,您一开始将设置一个仅用于两台机器共享一个虚拟网络的解决方案。

  1. 设置整个网络的配置
  2. 创建公共/私有密匙
  3. 创建一个脚本在每个主机上设置网络
  4. 将 GVPE 配置复制到每台机器
  5. 为每台机器设置主机密匙
  6. 启动 GVPE

下面分别描述每个步骤。

配置脚本

配置文件是整个配置和结构的核心。配置文件将被网络中的所有机器共享,因为它将被每台机器用于理解虚拟网络的布局和组成。

对于网络中的每台主机,只需设置两个值:节点名(标识虚拟网络中的主机)和主机名或通信目标(将被用作与该主机进行通信的公共传输)。最初,我们假定我们能访问一个标准 TCP/IP 网络。

配置文件的第一部分指定将为所有节点所用的全局选项,然后指定各个节点使用的选项。清单 2 展示了一个配置文件示例 gvpe.conf。

清单 2. gvpe.conf 配置文件
# Specify the use of UDP and the default port

enable-udp = yes
udp-port = 407

# Set the name of the virtual device created

ifname = vpn0

# Set the first node

node = private1
hostname = 192.168.1.20

# Set the second node

node = private2
hostname = remote.example.com

这设置第一个节点 private1,并指定一个 IP 地址(本例中位于一个本地网络上)。对于第二个节点,一个主机名被使用,主机的 IP 地址在 GVPE 启动时解析。

全局选项设置使用 UDP、UDP 端口,并配置将要创建的虚拟设备的名称。为方便起见,我们将设备名称设置为 vpn0。这个名称将存在于 /dev 中或 ifconfig 的输出中,需要用于配置虚拟网络设备和路由。

创建公共/私有密匙

需要为每台主机创建公共/私有密匙,它们将用于加密和主机识别。您可以使用控制命令 gvpectrl 自动执行上述任务:$ gvpectrl -c /usr/local/etc/gvpe -g

这将在 configuration 目录中创建两个目录。hostkeys 目录包含每台主机的主机密匙(私有)信息。pubkeys 目录包含每台主机的公共密匙。

公共密匙必须被复制到虚拟网络中的每台主机,因为每台主机都需要它们来进行通信。主机密匙只在每台具体主机上需要,即,private1 主机密匙(将位于 hostkeys/private1 中)只需被复制到虚拟网络中充当 private1 的主机。

网络初始化脚本

在每台主机上创建虚拟网络时,新创建的网络设备需要被配置一个 IP 地址,还需要配置路由方式,以便将数据从一台机器路由到另一台机器。

当 gvpe 在每台机器上启动时,它将运行 if-up(interface up 的缩写)来设置虚拟接口。在此过程中,它将提供一些脚本中可能会使用的标准 shell 环境变量来设置信息(比如识别节点名、接口名和 gvpe 生成的 MAC 地址)。

清单 3 展示了一个样例 if-up 脚本。

清单 3. 一个样例 if-up 脚本
#!/bin/sh
ip link set $IFNAME address $MAC mtu $MTU up
[ $NODENAME = private1 ] && ip addr add 10.0.1.1 dev $IFNAME
[ $NODENAME = private2 ] && ip addr add 10.0.2.1 dev $IFNAME
ip route add 10.0.0.0/16 dev $IFNAME

第一行通过使用指定的 MTU 设置接口的 MAC 地址。这些变量由 gvpe 设置,因此这条命令实际上将被扩展为下面的类似代码:ip link vpn0 address fe:fd:80:00:00:01 mtu 1500 up

第二和第三行设置虚拟用户的 IP 地址。内联测试允许您选择将哪个 IP 地址分配给哪个主机。这就是您设置虚拟网络的 IP 地址的地方。您应该选择一个还没有使用的网络范围(典型的示例是 10.0.0.0 范围或 192.168.0.0 范围)。

在本例中,指定为 private1 的节点将被设置为 IP 地址 10.0.1.1,private2 被设置为 10.0.2.1。

最后一行设置默认路由方式,重定向 10.0.0.0 网络的所有流量通过新创建的虚拟接口。

将配置复制到每台机器

现在脚本、配置和密匙信息已就绪,需要将这些信息复制到每台机器。由于我们的网络中只有一台额外的机器,我们只需复制配置一次,但您可以针对您的网络中的每台机器重复这个过程。

要进行复制,可以使用 rsync,或者通过一个不同的协议,比如 scp、sft、甚至 NFS。记住,您只需从 etc/gvpe 目录复制 gvpe.conf 文件、if-up 脚本和公共密匙目录(pubkey)。

例如,如果使用 rsync,您可以使用以下命令,该命令将除 hostkeys 目录之外的所有内容复制到新机器上,如 清单 4 所示。

清单 4. 使用 rsync 复制
$ rsync -avzessh /usr/local/etc/gvpe remote.example.com:/usr/local/etc/. 
--exclude hostkeys

现在,在节点 private1 上,将私有密匙复制到 /usr/local/etc/gvpe/hostkey。假定您已经在该节点上设置好一切:$ cp /usr/local/etc/gvpe/hostkeys/private1 /usr/local/etc/gvpe/hostkey

在主机 private2 上,从生成的目录复制 private2 主机密匙。在 remote.example.com 主机上使用 scp 命令,如 清单 5 所示。

清单 5. 使用 scp 复制
$ cd /usr/local/etc/gvpe
$ scp 192.168.1.20:/usr/local/etc/gvpe/hostkeys/private2 /usr/local/etc/gvpe/hostkey

配置好后,您现在可以启动 gvpe 服务并将两台机器连接起来。

启动 gvpe

gvpe 流程是简单、静默的。启动后,它通常作为一个守护进程在后台运行。因此,只需运行以下命令即可离开:$ gvpe

但是,您可能想从输出获取一些日志信息。可以使用 -l 参数指定不同的日志级别。对于测试,您还可以使用 -D 参数来阻止 gvpe 进入守护进程模式。您还需要指定节点名,如 清单 6 所示。

清单 6. 指定节点名
$ gvpe -D -l info private1
gvpe daemon 2.22 (Jun 13 2010 11:05:50) starting up.

现在,在将成为网络中的第二个虚拟主机的主机上,运行命令在 private2 上启动虚拟网络。这应该显示,已经使用 UDP 与其他主机建立连接,如 清单 7 所示。

清单 7. 启动一个 private2 虚拟网络
$ gvpe -l info -D private2
gvpe daemon 2.22 (Jun 13 2010 08:30:01) starting up.
private1(udp/192.168.1.20:407): connection established (direct), protocol version 0.1.

private1 上的输出中应该有一个类似的行,如 清单 8 所示。

清单 8. 另一个 private2 成功消息
private2(udp/192.168.1.10:407): connection established (direct), protocol version 0.1.

可以通过使用 ping 并指定 if-up 脚本中设置的 IP 地址来测试网络。

例如,您可以从 private1 ping 到 10.0.2.1(参见 清单 9)。

清单 9. ping 10.0.2.1
$  ping 10.0.2.1
PING 10.0.2.1 (10.0.2.1) 56(84) bytes of data.
64 bytes from 10.0.2.1: icmp_seq=1 ttl=64 time=12.1 ms
64 bytes from 10.0.2.1: icmp_seq=2 ttl=64 time=1.62 ms
^C
--- 10.0.2.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 1.629/6.891/12.154/5.263 ms

要监控整个虚拟网络的状态,使用 gvpectrl 命令和 -s 选项,如 清单 10 所示。

清单 10. 监控虚拟网络的状态
$ gvpectrl -s

Configuration

# of nodes:         2
this node:          <unset>
MTU:                1500
rekeying interval:  0
keepalive interval: 0
interface:          vpn0
primary rsa key:    <default>
rsa key size:       1280

 ID#  MAC               Com Conmode   Node        Host:Port
   1  fe:fd:80:00:00:01  Y  always    private1    192.168.1.20:407
   2  fe:fd:80:00:00:02  Y  always    private2    www.example.com:407

可以使用 kill 命令和 Control-C 终止连接(如果以非守护进程模式启动的话),但最好的方法是使用 gvpectrl 命令,如 清单 11 所示。

清单 11. 优雅地终止连接
$ gvpectrl --kill
preparing shutdown...
private2(udp/192.168.1.10:407): connection lost
exiting.

当然,这只是一个小型内部网络(可能不完全实用)。最有可能的是,虚拟网络将在公共网络上使用,或将多个主机连接成单个虚拟网络。


公共网络上的部署

在公共网络上部署时,基本设置和配置都是相同的,即使是在远程主机上。您设置的密匙将用于身份验证,加密将通过公共/私有密匙自动处理。

一个更重要的注意事项是用于与每个主机通信的通信方法。与其他 VPN 解决方案不同,您可以在不同主机之间混合并匹配的不同底层传输,同时仍然支持并创建相同的基本虚拟网络环境。

要设置一个不同的协议,只需在配置文件中配置每个虚拟节点的协议。清单 12 展示了一个示例,其中,三个新主机(private3、private4 和 private5)已被添加到配置文件。

清单 12. 添加三个新主机
enable-udp = yes
udp-port = 407

# Set the name of the virtual device created

ifname = vpn0

# Set the first node

node = private1
hostname = 192.168.1.20

# Set the second node

node = private2
hostname = remote.example.com

node = private3
hostname = ec2.amazon.com
enable-tcp = yes
tcp-port = 443

node = private4
hostname = 129.168.23.47
enable-rawip = yes

node = private5
hostname = 192.168.100.20
udp-port = 20000

对于 private3,您正在使用 Amazon EC2 与一个主机进行通信。当您与这样一个外部公共网络通信时,您的防火墙上可能有一些限制通信的限制。有一些限制您能使用的通信方式,但对于这个示例的目的,您正在端口 443 上使用一个直接 TCP/IP 通信,这个端口是安全 HTTP 通信通常使用的端口。如果其他端口被您的防火墙封闭,这可能有用。记住,要使虚拟网络正常工作,您必须使这个网络端口可双向访问。

对于 private4,假定您能直接访问主机,但不是通过一个防火墙,因为您正在使用原始 IP 协议。大多数防火墙,包括大多数标准路由器使用的 Network Address Translation (NAT) 环境,通常都不支持这种访问,因此只能在拥有完全访问权时才能使用这种方式。

对于 private5,您使用 UDP 协议,就像 private1 和 private2 上默认使用的一样,但您需要使用一个不同的端口号。在本例中,您已经设置了一个端口号,该端口号位于通常需要特殊特权的范围(低于 1024)之外,这意味着它可以在用于没有根访问权的机器上运行。


配置您的应用程序

如前面的 ping 示例所示,IP 网络的基本组件已经运行,ping 这样的服务通常在一个主机的所有接口上默认启用。

对于其他服务器和应用程序,您需要配置您的应用程序以直接使用虚拟网络接口(我们的示例中为 vpn0),或者,如果它是一个 IP 应用程序,您需要配置并更改一个特殊服务器绑定到的 IP 地址,或者客户端在与远程服务器通信时连接到的 IP 地址。

例如,如果您正在配置一个系统,该系统将支持并监听通过 Apache 连接到您的 web 服务环境的连接,那么您应该将 Apache 配置中的 Listen 指令重置为您的新虚拟设备 IP 地址,例如:Listen 10.0.2.1:80

由于 GVPE 正在创建一个全新的网络,因此您只需使用与配置其他应用程序或服务的方法相同的方法来配置服务器或客户端。

可能对您有用的一个技巧是配置当虚拟网络可用时的特殊场景。您可以通过使用 node-up 和 node-down 脚本来进行配置,与 if-up 脚本一样,这两个脚本应该位于 etc/gvpe 目录中。

只要一个节点启动或关闭,这两个脚本就会被调用。您可以将这个技巧用于各种不同的解决方案,但是一个共同点是要启动一个服务或注册服务器和服务存在性。

例如,用于一个网格或云场景中时,您可能想使用 node-up 命令来调用在云或网络上注册新主机的脚本,以便其他机器知道这台机器现在可用。


结束语

创建虚拟专用网通常是一个复杂的过程,结果并不总是像您想象的那样实用和灵活。使用 GVPE,您获得了创建一个完整的虚拟网络的能力 — 而不只是用于路由并支持一些特定协议的 IP 目标。另外,作为一个可重启和永久的服务,GVPE 还容易设置和配置,同时仍然保持安全性。

在本文中,您看到了 GVPE 和其他 VPN 解决方案之间的差异。您还详细了解了如何使用 gvpe 工具对一个虚拟网络进行基本设置。您还了解了如何配置您的 gvpe 配置以在公共通信网络上工作,以及如何通过新的虚拟网络使用您的自定义应用程序。

参考资料

学习

  • developerWorks 按需演示:观看演示,从为初学者准备的产品安装,到为经验丰富的开发人员准备的高级功能。
  • 参阅 GVPE 主页 进一步了解 GVPE。
  • 阅读 这份 IBM RedBook,深入了解 Virtual Private Networks。
  • 要收听面向软件开发人员的有趣访谈和讨论,请查看 developerWorks 播客
  • developerWorks 技术活动网络广播:随时关注 developerWorks 技术活动和网络广播。
  • Amazon EC2:从这里开始,深入了解 Amazon Elastic Compute Cloud。
  • IBM Cloud:这是深入了解 IBM Cloud 解决方案的一个不错的起点。

获得产品和技术

  • 使用 IBM 试用软件 改进您的下一个开发项目,这些软件可以通过下载或从 DVD 获得。

讨论

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=AIX and UNIX
ArticleID=650501
ArticleTitle=使用 GNU Virtual Private Ethernet
publish-date=04252011