最近公司架构调整,将原来在阿里云的开发环境和测试环境迁移到了,公司内网环境,但是,最近在周末的时候,老是有对应的临时需求在周末发布,结果自己在家,没办法访问公司的内网测试环境,很是恼火,根本没办法测试,但无法在在家中解决,自己也不想去公司,需要在内网测试并且上进行分析和定位对应的 bug。第一个想到的就是远程登陆,但公司没有公网 IP,怎么办?
经过一波调查明确如解决下需求:
1.一个是可以无视外网 ip 的变化 然后进行网络通信,使自己可以在家访问公司测试环境
经过最终在的调研,最终采用 open*** 实现使用外网访问公司的内网测试环境
open*是一个基于 OpenSSL 库的应用层实现。其主要技术核心是虚拟网卡和 SSL 协议实现。可以实现多种复杂的业务场景需求,包括单个客户端和服务器,多客户端和服务器 (客户端不通讯),多客户端和服务器 (客户端互通),这里的客户端和服务端都可以扩展到局域网的层面上,其使用工业标准的 SSL/TLS 协议实现第 2 层和第 3 层的安全数据链路*。其优点如下:
1、基于 SSL 协议,安全,并使用单一 TCP 或 UDP 端口即可实现;
2、使用双向验证,服务器只需保存自己的证书和密钥;
3、服务器只接受那些由主 CA 证书签名的客户端,并有撤回机制,而不需要重建整个 PKI;
4、可以实现基于 Common Name 的权限控制。
,英文全称是 Virtual Private Network,字面解释可理解为:虚拟私有网络;可以运行为 Point-to-Point 模式,也可以运行为 Server 模式,在 Server 模式下,服务器可作为网关设备使用,用以给处于外部的不安全网络环境中的 Client 提供安全访问内网服务的通道
以 Server 模式运行的其走包流程如下图所示:
硬件
CentOS Linux release 7.7.1908 (Core) 服务器一台
客户端笔记本一台
工具包
https://github.com/Open***/easy-rsa.git
安装依赖包
yum install lz4-devel lzo-devel pam-devel openssl-devel systemd-devel sqlite-devel
从 github 上下载 ope源代码包并解压*
wget https://github.com/Open***/open***/archive/v2.4.7.tar.gz
tar zvxf v2.4.7.tar.gz
编译 open并安装*
cd open***-2.4.7
autoreconf -i -v -f
./configure --prefix=/usr/local/open*** --enable-lzo --enable-lz4 --enable-crypto --enable-server --enable-plugins --enable-port-share --enable-iproute2 --enable-pf --enable-plugin-auth-pam --enable-pam-dlopen --enable-systemd
make && make install
配置系统服务
修改/usr/local/open*/lib/systemd/system/open*-server@.service
[Service]
...
ExecStart=/usr/local/open***/sbin/open*** --config server.conf
将 open-server@.service 设置成系统服务*
cp /usr/local/open***/lib/systemd/system/open***-server@.service /usr/lib/systemd/system/open***.service
systemctl enable open***
下载 easy-rsa3 并解压
wget https://github.com/Open***/easy-rsa/archive/v3.0.7.tar.gz
tar -xvf v3.0.7.tar.gz
根据 easy-rsa-3.0.7/vars.example 文件生成全局配置文件 vars
set_var EASYRSA_REQ_COUNTRY "CN"
set_var EASYRSA_REQ_PROVINCE "HUBEI"\
set_var EASYRSA_REQ_CITY "WUHAN"\
set_var EASYRSA_REQ_ORG "ZJ"\
set_var EASYRSA_REQ_EMAIL "zj@test.com"\
set_var EASYRSA_REQ_OU "ZJ"\
set_var EASYRSA_KEY_SIZE 2048\
set_var EASYRSA_ALGO rsa\
生成服务端证书
初始化,生成一系列文件与目录
./easyrsa init-pki
生成根证书,记住 ca 密码
./easyrsa build-ca
生成服务端证书
./easyrsa build-server-full server nopass ,nopass参数生成一个无密码的证书
生成 Diffie-Hellman
./easyrsa gen-dh
生成客户端证书
./easyrsa build-client-full client1 nopass
备注:注:可生成 client1, client2, client3 或对应姓名的客户端证书
为了提高安全性,生成 ta.key
open*** --genkey --secret ta.key
整理证书
cp pki/ca.crt /etc/open***/server/
cp pki/private/server.key /etc/open***/server/
cp pki/issued/server.crt /etc/open***/server/
cp pki/dh.pem /etc/open***/server/
cp ta.key /etc/open***/server/
下载 pam_sqlite3 并安装
git clone https://gitee.com/lang13002/pam_sqlite3.git
cd pam_sqlite3
make && make install
添加 pam 认证文件
# vim /etc/pam.d/open***
auth required pam_sqlite3.so db=/etc/open***/open***.db table=t_user user=username passwd=password expire=expire crypt=1
account required pam_sqlite3.so db=/etc/open***/open***.db table=t_user user=username passwd=password expire=expire crypt=1
创建 sqlite3 数据库文件
sqlite3 /etc/open***/open***.db
sqlite> create table t_user (
username text not null,
password text not null,
active int,
expire text
);
sqlite> .quit
创建服务端配置文件 (参照 sample/sample-config-files/server.conf 文件)
vim /etc/open***/server/server.conf
port 1194
proto tcp-server
;proto udp
dev tun
topology subnet
ca /etc/open***/server/ca.crt
cert /etc/open***/server/server.crt
key /etc/open***/server/server.key
dh /etc/open***/server/dh.pem
cipher AES-256-CBC
auth SHA512
tls-version-min 1.2
tls-cipher TLS-DHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-128-GCM-SHA256:TLS-DHE-RSA-WITH-AES-256-CBC-SHA:TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA:TLS-DHE-RSA-WITH-AES-128-CBC-SHA:TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA
tls-auth /etc/open***/server/ta.key 0
#tls-crypt /etc/open***/server/ta.key
user nobody
group nobody
server 10.8.0.0 255.255.255.0
;ifconfig-pool-persist ipp.txt
;push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 114.114.114.114"
push "route 192.168.133.0 255.255.255.0"
push "route-gateway 10.200.227.114"
;client-to-client
verify-client-cert none
username-as-common-name
plugin /usr/local/open***/lib/open***/plugins/open***-plugin-auth-pam.so open***
keepalive 10 120
comp-lzo
compress "lz4"
persist-key
persist-tun
status /var/log/open***-status.log
log /var/log/open***.log
verb 3
开启路由转发功能与防火墙
# 路由转发
# vim /etc/sysctl.conf
net.ipv4.ip_forward = 1
# 临时启用
# echo 1 > /proc/sys/net/ipv4/ip_forward
# 防火墙
# firewall-cmd --zone=public --add-service=open***
启动 open服务*
systemctl start open***
下载客户端程序
https://gitee.com/lang13002/open***-portable/repository/archive/v1.0?ref=v1.0&sha=1a7401cb8767a8f15726f04613d84458abccd272&format=zip&captcha_type=yunpian&token=335b826daacc4b17a81d2ce8e8f36c8a&authenticate=ced5c39711c343f0bfdb41531204a3ea
安装驱动
运行 open*-portable/tap-windows.exe
设置客户端证书
将上面生成的 ca.crt, client1.crt, client1.key 放到 open*-portable 的 data/config 下,并修改客户端配置
client
dev tun
proto tcp-client
remote ***server.com 1194
allow-recursive-routing
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
auth-user-pass
auth-nocache
ca ca.crt
cert client1.crt
key client1.key
remote-cert-tls server
auth-user-pass
auth-nocache
cipher AES-256-CBC
auth SHA512
tls-version-min 1.2
tls-cipher TLS-DHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-128-GCM-SHA256:TLS-DHE-RSA-WITH-AES-256-CBC-SHA:TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA:TLS-DHE-RSA-WITH-AES-128-CBC-SHA:TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA
tls-auth ta.key 1
comp-lzo
compress lz4
verb 3
mute 20
备注
注:当有多个客户端时,有多个文件(ca.crt, client1.crt, client1.key, client.o***)需要分发给客户,势必会很麻烦;可以将证书嵌入到客户端配置文件中;
;ca ca.crt // 将这行注释掉
;cert client.crt // 将这行注释掉
;key client.key // 将这行注释掉
;tls-auth ta.key 1 // 将这行注释掉
<ca>
-----BEGIN CERTIFICATE-----
MIIDGDCCAgCgAwIBAgIJAI9Ld4PlKEiOMA0GCSqGSIb3DQEBCwUAMA0xCzAJBgNV
....
OCeTQvQ4WhyIvVgURV3ITcAKYFKUQ1sPbpjuZg==
-----END CERTIFICATE---
</ca>
<cert>
-----BEGIN CERTIFICATE-----
MIIDODCCAiCgAwIBAgIRAIZoEQ5PvHDs9xpTLMP3RqMwDQYJKoZIhvcNAQELBQAw
......
nCpzC3l8sVezxk2r
-----END CERTIFICATE-----
</cert>
<key>
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDw1iq3HBe1otCU
......
ullaNc6mu3N/wTPZoQhDOKAO
-----END PRIVATE KEY-----
</key>
<tls-crypt>
#
# 2048 bit Open*** static key
#
-----BEGIN Open*** Static key V1-----
376ff00121bc6cd39fe1382c44be1433
......
-----END Open*** Static key V1-----
</tls-crypt>
连接代理
安装依赖
pip install peewee tornado
下载 ope-web*
git clone https://gitee.com/lang13002/open***_web.git
创建相应的数据库表
# sqlite3 /etc/open***/ope**n.db
sqlite> .read open***_web/model/open***.sql
添加日志脚本
服务端配置添加运行脚本
script-security 2
client-connect /etc/open***/server/connect.py
client-disconnect /etc/open***/server/disconnect.py
connect.py
!/usr/bin/python
import os
import time
import sqlite3
username = os.environ['common_name']
trusted_ip = os.environ['trusted_ip']
trusted_port = os.environ['trusted_port']
local = os.environ['ifconfig_local']
remote = os.environ['ifconfig_pool_remote_ip']
timeunix= os.environ['time_unix']
logintime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))
conn = sqlite3.connect("/etc/open***/open***.db")
cursor = conn.cursor()
query = "insert into t_logs(username, timeunix, trusted_ip, trusted_port, local, remote, logintime) values('%s','%s', '%s', '%s', '%s', '%s', '%s')" % (username, timeunix, trusted_ip, trusted_port, local, remote, logintime)
cursor.execute(query)
conn.commit()
conn.close()
disconnect.py
/usr/bin/python
import os
import time
import sqlite3
username = os.environ['common_name']
trusted_ip = os.environ['trusted_ip']
received = os.environ['bytes_received']
sent = os.environ['bytes_sent']
logouttime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))
conn = sqlite3.connect("/etc/open***/open***.db")
cursor = conn.cursor()
query = "update t_logs set logouttime='%s', received='%s', sent= '%s' where username = '%s' and trusted_ip = '%s'" % (logouttime, received, sent, username, trusted_ip)
cursor.execute(query)
conn.commit()
conn.close()
启动服务
python myapp.py