什么是open***?

Open***是一个基于OpenSSL库的应用层***实现

open***可工作于两种模式:

tun 一种是IP遂道路由模式,主要应用于点对点
eth 一种是基于以太网的遂道桥模式, 应用于点对多点,有多个分支机构

open***提供两种安全模式:

Static Key
X509 PKI (Public Key Infrastructure)

1.基础环境安装:

OS: CentOS_6.4   2.6.32-358.el6.x86_64
yum install -y openssl openssl-devel lzo gcc gcc-c++

 安装LZO 用于压缩通讯数据加快传输速度

wget http://www.oberhumer.com/opensource/lzo/download/lzo-2.09.tar.gz
tar zxvf lzo-2.09.tar.gz 
cd lzo-2.09.tar.gz
./configure 
make && make install

TUN/TAP

 Open***要使用到TUN/TAP作为接口建立隧道,但需要内核支持。TUN 接口创建的是三层路由隧道,建立方便;

   TAP 是二层网卡桥接隧道,即创建一个以太网桥接,相对复杂。
   TUN 接口下所有的客户端处于一个完全独立的子网内,与 *** 服务器所在的子网没有关系;
   TAP 接口的好处相较之下则相当明显,客户端可以获得 *** 服务器所处子网的 IP(即,忽略物理上的区别,可以完全将客户端看做是于 *** 服务器处于同一子网的另一台机器)

  检查内核是否支持TUN/TAP设备驱动

 modinfo tun  如果有正常的输出,则支持

  确定内核支持TUN/TAP模块之后,加载模块

 modinfo tun    # 加载
 lsmod tun     # 检查
 ls /dev/net/tun  # 检查文件是否存在判断tun模块是否加载

2.安装open***

  a) RPM安装epel源

rpm -ivh http://mirrors.sohu.com/fedora-epel/6/x86_64/epel-release-6-8.noarch.rpm
sed -i 's/^mirrorlist=https/mirrorlist=http/' /etc/yum.repos.d/epel.repo

  b) 源码安装Open***

  下载 http://open***.net/

tar zxvf open***-2.1.3.tar.gz
cd open***-2.1.3
./configure
make && make install

3.配置Open***

a)初始化PKI
 设置环境变量
  # mkdir -pv /etc/open***
  # cp -r ../../open***-2.1.3/easy-rsa /etc/open***
  修改证书变量 
  # cd /etc/open***/easy-rsa/2.0
  # cat var  # 自定义修改如下内容
    export KEY_COUNTRY="CN"        # 国家
    export KEY_PROVINCE="SH"       # 省
    export KEY_CITY="SH"           # 市
    export KEY_ORG="ZZT"           # 公司
    export KEY_OU="IT"             # 部门
    export KEY_EMAIL="me@zzt.com"  # 邮箱
 初始化环境变量
  # source vars
  # ./clean-all
  # ./build-ca   # 生成根证书ca.crt和根密钥ca.key(一路按回车即可),因为vars文件已经在上面自定义默认的变量值
  # ./build-key-server server # 为服务端生成证书和密钥(一路按回车,直到提示需要输入y/n时,输入y再按回车,一共两次)
  每一个登陆的***客户端需要有一个证书,每个证书在同一时刻只能供一个客户端连接,下面建立
  # ./build-key client  # 为客户端生成证书和密钥(一路按回车,直到提示需要输入y/n时,输入y再按回车,一共两次)
  # ./build-dh   # 创建迪菲·赫尔曼密钥,会生成dh2048.pem文件(生成过程比较慢,在此期间不要去中断它)
  # open*** --genkey --secret keys/ta.key  # 生成ta.key文件(防DDos***、UDP淹没等恶意***)

4.创建服务器端配置文件

  将需要用到的open***证书和密钥复制一份到刚创建好的keys目录中

mkdir -pv /etc/open***/keys
cp /etc/open***/easy-rsa/2.0/keys/{ca.crt,server.{crt,key},dh1024.pem,ta.key} /etc/open***/keys/

  复制一份服务器端配置文件模板server.conf到/etc/open***/

cp ./../open***-2.1.3/sample-config-files/server.conf  /etc/open***/  
cat /etc/open***/server.conf
  ;local a.b.c.d     # 申明本机使用的IP地址,也可以不说明
  port 1194   # 端口
  proto tcp   # 协议,默认使用udp,如果使用HTTP Proxy,必须使用tcp协议            
  dev tun     # 申明使用的设备可选tap和tun,tap是二层设备,支持链路层协议;tun是ip层的点对点协议,限制稍微多一些
  ca keys/ca.crt       # 全路径为/etc/open***/keys/ca.crt,用于验证客户是证书是否合法
  cert keys/server.crt # 全路径为/etc/open***/keys/server.crt,Server使用的证书文件
  key keys/server.key  # 全路径为/etc/open***/keys/server.key,Server使用的证书对应的key,注意文件的权限,防止被盗
  dh keys/dh1024.pem   # 全路径为/etc/open***/keys/dh1024.pem
  server 10.8.0.0 255.255.255.0  # 地址池,配置***使用的网段,Open***会自动提供基于该网段的DHCP服务,保证唯一,不要和实际的局域网冲突即可
  ifconfig-pool-persist ipp.txt  # 用于记录某个Client获得的IP地址,类似于dhcpd.lease文件,防止open***重新启动后“忘记”Client曾经使用过的IP地址
  ;client-config-dir /etc/open***/ccd # 定义每个客户端的个性化配置文件
  # 推送路由信息到客户端,以允许客户端能够连接到服务器背后的其他私有子网
  # (简而言之,就是设置允许客户端访问***服务器自身所在的其他局域网)
  push "route 10.2.8.0 255.255.255.0"     # 可以设置多个服务端所在的其他局域网地址范围
  push "route 192.168.0.0 255.255.255.0"
  ;push "dhcp-option DNS 10.8.0.1"     # 用Open***的DHCP功能为客户端提供指定的DNS、WINS等
  ;route 10.9.0.0 255.255.255.252  # ***启动后,在*** Server上增加的路由,***停止后自动删除
  client-to-client  # 可以让客户端之间相互访问直接通过open***程序转发,不用发送到tun或者tap设备后重新转发,优化Client to Client的访问效率
  duplicate-cn      # 如果客户端都使用相同的证书和密钥连接***,一定要打开这个选项,否则每个证书只允许一个人连接***
  keepalive 10 120  # 每10秒通过***的Control通道ping对方,如果连续120秒无法ping通,认为连接丢失,并重新启动***,重新连接
  tls-auth keys/ta.key 0 # 全路径为/etc/open***/keys/ta.key,注意server端后面的数字肯定使用0,client使用1 
  comp-lzo    # 对数据进行压缩,注意Server和Client一致
  user nobody #定义运行open***的用户
  group nobody
  persist-key  # 通过keepalive检测超时后,重新启动***,不重新读取keys,保留第一次使用的keys
  persist-tun  # 通过keepalive检测超时后,重新启动***,一直保持tun或者tap设备是linkup的,否则网络连接会先linkdown然后linkup
  status /var/log/open***-status.log   # 定期把open***的一些状态信息写到文件中,以便自己写程序计费或者进行其他操作
  log /var/log/***/open***.log         # 记录日志,每次重新启动open***后删除原有的log信息
  log-append /var/log/***/open***.log  # 和log一致,每次重新启动open***后保留原有的log信息,新信息追加到文件最后 
  verb 3    # 相当于debug level,改成verb 5可以多查看一些调试信息
  ;mute 20  # 重复信息的沉默度。相同类别的信息只有前20条会输出到日志文件中

5.配置内核和防火墙,启动服务

开启路由转发功能
  # echo 1 > /proc/sys/net/ipv4/ip_forward
  或者
  # sed -i '/net.ipv4.ip_forward/s/0/1/' /etc/sysctl.conf
  # sysctl -p
配置防火墙,别忘记保存
    # iptables -A INPUT -s 10.8.0.0/24 -j ACCEPT   # 开启虚拟网段
  # iptables -A INPUT -s 10.8.0.0/24 -m state --state NEW -m tcp -p tcp -j ACCEPT # 
  # iptables -A INPUT -m state --state NEW -m udp -p udp --dport 1194 -j ACCEPT # 
  # iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
  # iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -d 10.2.8.0/24 -o eho0 -j SNAT --to-source 10.2.8.10 # 将虚拟网段10.8.0.0/24访问内网10.2.8.0/24都通过内网网卡eth0并且将源地址转换成10.2.8.10转发
  # service iptables save
  # service iptables restart # 重启

# 启动open***并设置为开机启动

 创建open***启动脚本

cp ../../open***-2.1.3/sample-scripts/open***.init /etc/init.d/open***
/etc/init.d/open*** start
service open*** start
或者
/usr/local/sbin/open*** --daemon --config /etc/open***/server.conf # 守护进程模式启动
echo "/usr/local/sbin/open*** --daemon --config /etc/open***/server.conf"  >> /etc/rc.local  # 开机启动

为客户端分配静态IP:(可选)

在/etc/open***/server.conf中增加
 client-config-dir /etc/open***/ccd
然后在 /etc/open***/ccd目录中放针对每个客户端的个性化配置文件。
文件名就用客户端名 生成key的时候输入的 "Common Name" 名字
比如要设置客户端 client 为 10.8.0.8 
只要在 /etc/open***/ccd/client 文件中包含一行:
 ifconfig-push 10.8.0.8 255.255.255.0


Windows客户端安装

  下载安装Open***客户端工具

 创建客户端配置文件,默认../Open***/sample-config/client.o***

  复制一份 client.o*** 到 ../Open***/config/client.o***

  编辑client.o***

cat client.o***
client
dev tun
proto tcp
remote 203.195.xxx.xxx 1194  # Open***服务器的外网IP和端口
resolv-retry infinite
nobind
persist-key
persist-tun
ca ca.crt
cert client1.crt  # client1的证书
key client1.key   # client1的密钥
ns-cert-type server 
tls-auth ta.key 1  # 客户端是1,服务器是0
comp-lzo
verb 3

拷贝client.o***文件到地open***客户端 ../Open***/config/目录下 

从服务器上拷贝证书/秘钥 “ca.crt、client.crt、client.key、ta.key” 到本地open***客户端的config/目录下

然后打开Open***客户端(切记,要用用管理员身份打开Open***客户端,否则客户端将无法执行服务端push推送过来的route路由添加指令)点击连接。

ok,如果一切顺利,就会看到 "Mon Apr 11 16:26:12 2016 MANAGEMENT: >STATE:1460363172,CONNECTED,SUCCESS,10.8.0.6,10.2.8.45",客户端分配到的ip,10.8.0.6

打开CMD,ipconfig /all 可以看到分配的虚拟ip


Linux 客户端安装

1) 下载客户端工具
# yum install -y open*** 
2) 创建客户端配置文件 client.conf
# cat /etc/open***/conf/client.conf  添加如下内容
      client
      dev tun
      proto tcp
      remote 203.195.xxx.xxx 1194  # Open***服务器的外网IP和端口
      resolv-retry infinite
      nobind
      persist-key
      persist-tun
      ca ca.crt
      ns-cert-type server 
      tls-auth ta.key 1  # 客户端是1,服务器是0
      comp-lzo
      verb 3
        auth-user-pass     # 启动User/Pass登录的方式
3) 启动客户端
# open*** --daemon --config /etc/open***/conf/client.conf > /var/log/open***_client.log # 后台守护进程模式启动
   Username: test     # 输入用户名
   Password: 123456   # 输入密码
# ps -ef | grep -v grep | grep open***  # 查看启动进程
4) 客户端启动OK

Linux客户端启动脚本

#!/usr/bin/expect 
# FileName: expect.sh
# Auth: Loren
# Date: 2016-04-26 10:00
# 定义账号密码
set user test
set pass 123456
# 启动命令
spawn /usr/local/sbin/open*** --daemon --config /etc/open***/config/client.conf > /var/log/open***_client.log
set timeout 30
# 检测到指定内容
expect "Username:"
# 输入账号
send "$user\n"
set timeout 30
# 检测输入密码
expect "Password:"
# 输入密码
send "$pass\n"
set timeout 30
# 退出
expect eof

# expect expect.sh # 执行脚本



客户端证书管理

cd /etc/open***/easy-rsa/2.0/
./revoke-full client1  # 注销指定客户端证书名称

  此时 /etc/open***/easy-rsa/2.0/keys/ 目录下面会生成文件“crl.pem revoke-test.pem”,

  其中 crl.pem 文件,是吊销证书的名单,

  index.txt文件中列出所有注册过的用户证书列表,其中标志为R的表示已注销用户

cat /etc/open***/easy-rsa/2.0/keys/index.txt
V	260406062220Z		01	unknown	/C=CN/ST=SH/L=SH/O=DDD/OU=IT/CN=server/emailAddress=me@DDD.com
R	260406062410Z	160412075407Z	02	unknown	/C=CN/ST=SH/L=SH/O=DDD/OU=IT/CN=client/emailAddress=me@DDD.com
R	260410080030Z	160412084055Z	03	unknown	/C=CN/ST=SH/L=SH/O=DDD/OU=IT/CN=client2/emailAddress=me@DDD.com
R	260410084606Z	160412091701Z	04	unknown	/C=CN/ST=SH/L=SH/O=DDD/OU=IT/CN=client3/emailAddress=me@DDD.com
V	260410085953Z		05	unknown	/C=CN/ST=SH/L=SH/O=DDD/OU=IT/CN=client4/emailAddress=me@DDD.com

  拷贝注销文件 crl.pem 到指定目录,若直接指定默认的文件路径,可能会出现报错 “cannot read: crl.pem: Permission denied (errno=13)”

cp ./keys/crl.pem /etc/open***/keys/crl.pem   # 指定原始默认绝对路径

  然后在服务端配置文件 /etc/open***/server.conf 中添加如下

    crl-verify /etc/open***/easy-rsa/2.0/keys/crl.pem

  最后重启Open***即可

service open*** reload

  注意: 每次注销禁用一个用户的证书,就需要重复上面的步骤


配置使用账户/密码验证登录服务器

1) 使用MySQL数据库存储***账号密码

yum install -y mysql-devel pam-devel pam_mysql gcc gcc-c++  # 基础环境安装

  新建数据库 ***,设置active字段值为1时,无权使用***

mysql> create database ***;
mysql> user ***;
mysql> create table ***_users (id INT NOT NULL AUTO_INCREMENT primary key, name char(20) not null, password char(128) default null, mail char(50) default null, active int(10) nmun ('1','0') not null default 1);
mysql> insert into ***_users(name,password,mail) values('test','test','');       明文密码
mysql> insert into ***_users(name,password,mail) values('test',ENCRYPT('test'),'');   使用 ENCRYPT 加密密码(建议使用这种)
创建***用户,对***这个库有所以的操作权限
mysql> grant all privileges on ***.* to ***@'%' identified by '***_001';
mysql> flush privileges

2) 配置 pam_mysql 模块

  创建 /etc/pam.d/open***文件,内容如下

auth sufficient /lib64/security/pam_mysql.so user=*** passwd=***_001 host=10.10.8.94 db=*** table=***_users usercolumn=name passwdcolumn=password where=active=1 sqllog=0 crypt=0
account required /lib64/security/pam_mysql.so user=*** passwd=***_001 host=10.10.8.94 db=*** table=***_users usercolumn=name passwdcolumn=password where=active=1 sqllog=0 crypt=0
# active值0表示禁用,1正常
# crypt值 0 明文密码;1 使用crypt(3)函数,相当于MySQL中的ENCRYPT()函数;2 使用MySQL的PASSWORD()函数。PAM可能与MySQL的函数不同;3 使用MD5;4 使用SHA1
# 如果使用1,则在数据库中添加用户password值的时候需要添加函数 ENCRYPT(),如 insert into ***_users(name,password) values('test',ENCRYPT('123456'));

  生成 open***-auth-pam.so 动态库,注意,如果是使用当前2.1.3版本的Open***生成此动态库,可能会出现错误,建议重新下载2.0.9版本的生成open***-auth-pam.so 动态库

    首先进入到Open***源码plugin解压路径下

tar -zxvf open***-2.0.9.tar.gz -C /data/open***-2.0.9
cd /data/open***-2.1.3/plugin/auth-pam
make    # 生成open***-auth-pam.so
cp open***-auth-pam.so /etc/open***/

  检验pam_mysql配置

启动 saslauthd 服务
/etc/init.d/saslauthd start 或者 saslauthd -a pam
testsaslauthd -u test -p test -s open***  # 测试数据库里设置的账号密码
  0: OK "Success."    #  可以看到验证成功的信息,反之则失败,说明配置有问题,请根据 /var/log/salt/master 日志查找原因

3) 修改主配置文件 server.conf,添加如下代码

port 1194
proto tcp
dev tun
ca /etc/open***/keys/ca.crt
cert /etc/open***/keys/server.crt
key /etc/open***/keys/server.key
dh /etc/open***/keys/dh1024.pem
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist /etc/open***/ipp.txt
push "route 10.2.8.0 255.255.255.0"
push "route 192.168.2.0 255.255.255.0"
push "dhcp-opton DNS 10.8.0.1"
#client-config-dir /etc/open***/ccd
#route 10.8.0.0 255.255.255.0
client-to-client
duplicate-cn
keepalive 10 120
tls-auth /etc/open***/keys/ta.key 0 # This file is secret
comp-lzo
user nobody
group nobody
persist-key
persist-tun
crl-verify /etc/open***/keys/crl.pem
status /var/log/open***-status.log
log         /var/log/open***.log
log-append  /var/log/open***.log
verb 3
mute 20
# 以下是新添加的内容
# User/Key
client-cert-not-required    # 只使用账号密码使用,若注释掉则代表需要证书和用户名密码双重验证登录
plugin /etc/open***/open***-auth-pam.so open***  # 说明使用的插件,open***为插件的参数,使用pam的servicesname
username-as-common-name     # 不请求客户的CA证书,使用User/Pass验证

4) 修改客户端配置文件 client.conf,注释掉原来的客户端的证书和密钥

client
dev tun
proto tcp
# Open***服务器的外网IP和端口
remote 10.2.8.45 1194
resolv-retry infinite
nobind
user nobody
group nobody
persist-key
persist-tun
ca ca.crt
#cert client1.crt   # 注释掉证书
#key client1.key    # 注释掉密钥
remote-cert-tls server
tls-auth ta.key 1
comp-lzo
verb 3  
# 新添加的代码如下
auth-user-pass     # 添加使用账号密码验证

OK,重启服务端

service open*** restart


重新连接客户端(切记,要用用管理员身份打开Open***客户端)



问题记录:

1)客户端启动提示:TLS Error: TLS key negotiation failed to occur within 60 seconds (check your network connectivity)

  解决方法: 修改客户端的client.o***文件
           proto tcp  # 修改为tcp协议


2)AUTH-PAM: BACKGROUND: user 'test' failed to authenticate: Module is unknown

  修改 /etc/pam.d/open*** 的验证方式为 "auth sufficient ... "


3)AUTH-PAM: BACKGROUND: user 'test' failed to authenticate: Permission denied

  原因:可能是2.1.3版本的open***的生成动态库和当前的应用版本不匹配,重新下载个2.0.9版本的源码包,
      然后进入../plugin/auth-pam/,make生成新的open***-auth-pam.so,然后替换替换掉原来的open***-auth-pam.so
      cd ../plugin/auth-pam/ && make