网络通信 频道

实战:不需公网IP架设OpenVPN网络

    【IT168 报道】OpenVPN是一款开源的基于SSL的VPN, 它获得了广泛的支持, 并且已经从IANA获得了知名端口,那我们应该如何架设OpenVPN网络呢?

    OpenVPN实际上是在应用层做的传输, 传输协议可以选择UDP/TCP, 其中UDP更为常用, 原因有专门文章论述。

为何需要OpenVPN网络?

    如果我想在家里访问单位的网络资源, VPN是个不错的选择, 但一般来说, 架设VPN需要有VPN服务器, 也就是说至少需要有一个真实IP, 这个并不是谁个人都有的. 但别忘了OpenVPN支持UDP传输, 在BT大行其道的今天, UDP很多时候就是NAT穿透的代名词, 那么, OpenVPN能不能也使用这种模式呢? 如果能, 那将会解决不少问题, 设想:

    1, 我是一个学生, 我在写论文, 但我目前不在学校, 因而不能下载学校论文数据库的资料, 老让同学下也不是办法, 而且不方便, 这样我可以考虑在学校任意电脑上开一个OpenVPN软件, 然后让它穿越NAT对外提供服务, 这样我就可以在校外网络上和学校里一样使用.

    2, 我是一个上班族, 我想在家里做一些要在单位网络里才能完成的事情, 但单位没有VPN或者有VPN但我没帐号, 我可以在单位的工作机上放个OpenVPN然后回家接入再用, 呵呵.

    听起来不错, 但如何实现呢? 这里我先说明一些技术前提: 你应该知道平常怎么配置OpenVPN, 即有真实IP时候怎么配置, 如果不了解, 上GOOGLE搜索吧, 文章很多.

    处于防火墙或者NAT设备后面的主机想要对外提供服务, 比如和其他同样处于不通网络NAT设备之后的主机通信, 可以使用UDP打洞技术, 这个细节网上也有很多文章讲, 可以参考http://www.ppcn.net/n1306c2.aspx
 

解决UDP穿越防火墙问题

    在能使用UDP成功打洞之前, 要先解决以下几个问题:

    1, 确认通信双方所处NAT的类型, NAT可以大致的分成两类: 锥形NAT和对称NAT(关于NAT的详细分类可以参考RFC3489第5节, 那里分了4类, 前三类归为锥形NAT, 第4类为对称NAT). 做UDP穿透的一般原则是, 锥形NAT之间可以做UDP穿透, 而对称NAT不能, 事实上, 当一端为锥形一段为对称也是有可能的, 但这不能保证, 主要看对称NAT有没有规律可循.

    如何确定自身的NAT类型呢? 可以利用STUN的客户端查看, 软件可以从这里获取:

    Linux版: http://sourceforge.net/projects/stun/

    Java版(适用各种操作系统): http://jstun.javawi.de/

    这些软件很好使用, 比如Linux版的stun, 编译好后运行 ./client stun01.sipphone.com 即可. Java版则直接双击jar文件执行, 它会将结果记录在同目录的log文件里. 你只需要确认通信双方都不是对称NAT即可. 如果双方均为对称NAT那本文所描述的方法没有希望了. 如果查类型失败, 这可能的原因有两种:

    a, 无法访问该STUN服务器, 你可以试试后面STUN列表中的其他服务器, 如果你是教育网用户且不能访问国外流量, 那么暂时没有办法用, 因为还没有找到国内的开放STUN服务器.

    b, 你所在网络的防火墙把UDP禁了, 这种情况我见过, 很变态, 没有任何办法.

    确认了两端NAT类型都不是对称NAT则继续往下看, 否则希望不大, 但也还有机会.

    2, 通信建立前需要通信双方告知对方自己经NAT设备转换后的IP/PORT, IP/PORT也可以通过STUN服务器得到, 公网上有不少这种免费STUN服务, 只是国内的很少见.

    前两个问题归结一下, 其实就是如何找到免费的STUN服务器, 下面的列表是我试过能用的, 但都在国外, 这对教育网用户不是个好消息, 国内的还在寻找中, 也希望有人能提供线索

    stun01.sipphone.com
    stun.ekiga.net
    stun.fwdnet.net
    stun.ideasip.com
    stun.iptel.org
    stun.rixtelecom.se
    stun.schlund.de
    stunserver.org
    stun.softjoys.com
    stun.voiparound.com
    stun.voipbuster.com
    stun.voipstunt.com
    stun.voxgratia.org
    stun.xten.com

    3, 现在已经能知道自己经NAT映射后的真实地址了, 但如何才能告诉对方呢, 目前广泛使用的BT应用中实际上都有一个中介服务器, 但我们不会有, 否则的话我直接就拿它做VPN服务器了

    解决这个问题有点麻烦, 在我的这个例子里是用的GMail做交互, 客户端注册一个GMail帐号, 服务端注册一个GMail帐号, 这样就有了一个速度很慢的管道, 但至少能完成通信了, 流程也就可以通了.

    到了这里, 能查自己的IP/PORT, 有通信两端交互的管道, 剩下的问题就是定一个简单的协议把这些真正的跑起来.
 

    如何建立UDP通道?

    1, 客户端发起, 通过Mail告诉服务器客户端经NAT映射后的IP/PORT.  
    2, 服务端查询自己经NAT映射后的IP/PORT并将其通过邮件返回给客户端, 同时向客户端的UDP端口做打洞操作.    
    3, 客户端收到服务端的Mail后向服务端UDP端口发送数据, 这时服务端UDP端口应该能收到数据, 返回一条UDP信息给客户端, 标志通道建立成功.

  4, 服务端启动OpenVPN, 客户端打开OpenVPN客户端, 通过刚才建立的通道即可建立VPN连接.这个过程我用Python做了一个模型实现, 不能说是软件, 只是一些脚本, 但能稳定工作, 这里介绍一下使用过程:

    1, 配置OpenVPN, 这个过程和有真实IP完全相同, 我这里列举一个非常简单的例子, 这里默认服务器运行在Linux平台, 客户端则在Windows上, OpenVPN采用2.0.9版本, 客户端我用的是OpenVPN GUI for Windows V1.0.3, 默认安装路径.

    可以在局域网找两台机器(或者虚拟机)做测试, 你需要将客户端配置中的remote改为OpenVPN服务所在主机IP/PORT.


图1 OpenVPN服务端简明配置


图2 OpenVPN客户端简明配置


    配置好之后, 用客户端连接服务, 应该可以连通, 然后从客户端机器ping 10.4.0.1如果响应, 则配置完成, 可进行下一步, 否则, 请查找原因, 参考OpenVPN的相关文档以及网络上关于OpenVPN配置的文章.

    2, 申请两个GMail帐号做通信使用, 比如openvpn.nat.server@gmail.com, openvpn.nat.client@gmail.com, 注意申请完后进入GMail邮箱设置, 开启IMAP支持, 否则后面无法继续.

    3, 获取UDP穿透NAT的代码, 从http://code.google.com/p/natvpn/downloads/list获取最新包即可, 也可以从svn获取最新的代码. 获取后解压包, 我的例子是服务器运行在Linux操作系统, 客户端运行在Windows上, 其实和系统关系不大, 图方便而已, OpenVPN和Python都是跨平台的, 需要的只是修改路径. Python版本是2.5.

    解压, 先配置服务器, 把源码目录下的几个*.py和OpenVPN配置文件都拷贝到你习惯的位置, 比如/usr/local/etc下, 然后修改server.py文件中的路径, 与你的系统保持一致:


    图3 server.py中需要更改的变量
 

    然后是客户端, 将*.py和OpenVPN客户端配置文件拷贝到OpenVPN安装路径下的config目录. 注意client.ovpn文件要可写, 因为脚本会在后面重写该文件中的remote地址等部分.

 

图4 client.py中需要更改的变量

    4, 启动服务端, 注意要用root启动:

    # ./server.py
   
    5, 回家:) 然后启动客户端. Windows首先要安装Python, 我用ActiveState Python 2.5, 很方便安装, 软件可以从http://www.activestate.com/Products/activepython/下载. 然后双击执行client.py, 运行一直到它提示可以连接, 这个过程在当前的配置状态下需要三到五分钟左右, 这主要是因为GMail设置的查新邮件时间有3分钟, 最后应该出现如下图提示:


图5 客户端执行UDP打洞成功后的提示界面
   
    看到这个画面, 说明UDP通道已经打通, 这是你需要尽快(1分种以内)启动OpenVPN客户端, 这样即可完成连接.


图6 启动OpenVPN客户端连接

    我从家里连接单位, 单位是对称NAT, 家里是锥形NAT, 本来这种网络连通的希望不大, 但我对单位的NAT方式稍有了解, 他的NAT映射具有时间局部性, 所以在server.py/client.py中做了一些优化: 针对一个PORT范围打洞, 而不是针对某个具体PORT, 这样, 连接可以成功建立, 从无失手:)

    不得不说, OpenVPN的通信质量还是很不错的, 我使用的这段时间从没有出现过连接中断, 值得一试!
    欢迎交流, 谢谢!Email: dugang@188.com
 

12
相关文章