关键词:openvpn,ipv4,ipv6,ddns,forward,ufw
前言
安装openvpn并配置网上有很多教程,我就不做过多的介绍了,我主要介绍下我认为比较重要的几个坑和自己做的一些便捷方法。
为什么要搭建OpenVPN服务
主要是隐私安全问题,我曾经工作的一家公司旁边有一家做基站开发相关服务的,需要给公家部门在必要情况下提供技术支持,他们能拦截解析很多走他们基站的数据。
另外在连接公司网络的情况下,自己设备传输的数据也会被某信服等公司的软件破解抓包,毫无隐私可言。
我曾经也用过三方提供的服务,但是安不安全还是存在疑惑的,毕竟哪些数据还得经别人的手走一遍。
1.IPV4或者IPV6无法连接上服务器问题
很多教程没讲这个,问题原因出在server.conf文件local 的配置上,很多教程没教配置或者叫你配置固定公网IP,但这个年头固定公网IP可是稀缺货啊。
配置时local可以配置多个,可以配固定IP或域名(我用我的IPV6的DDNS域名测试也可以的),图方便的可以配置0.0.0.0或::,代表支持监听ipv4和ipv6的所有地址。
下面是我脚本中同时添加对v4和v6的监听支持
!!!注意,前提是记得服务的端口防火墙打开了哈!
sed -i 's/;local a.b.c.d/local 0.0.0.0/g' /etc/openvpn/server.conf
sed -i '$alocal ::' /etc/openvpn/server.conf
2.连接和无法上网IPV4与IPV6流量的转发问题
在网上找了教程,安装好OpenVPN后,经过上面的一个问题的解决,我通过IPV6连上的服务器,但是无法上网,连局域网都连接不上。
原因可能是下面两个,解决下这两个问题。
问题1:系统没打开流量转发功能,打开即可
sysctl -w net.ipv4.ip_forward=1
sysctl -w net.ipv4.conf.all.forwarding=1
sysctl -w net.ipv4.conf.default.forwarding=1
sysctl -w net.ipv6.conf.all.disable_ipv6=0
sysctl -w net.ipv6.conf.default.forwarding=1
sysctl -w net.ipv6.conf.all.forwarding=1
问题2:ufw防火墙没打开流量转发(很多教程都是iptables的,教程太旧了,但是在比较新的ubuntu中修改无效),这里需要修改ufw的ipv4和ipv6的规则,添加转发,修改后要重启或重载ufw(网上找到的资料说要重启,我重装也OK,脚本重载不行可以尝试重启),最后重启openvpn服务即可
下面的脚本要结合完整脚本看,其中的一些变量在脚本开头定义了,这里个一些解释
tsubnet --- openvpn ipv4虚拟网络的网段,我脚本中是192.168.88.0
tsubnet6 --- openvpn ipv6虚拟网络的网段,我脚本中是fc00::0
tnetcard --- 用于数据转发的物理网卡
# /etc/ufw/before.rules修改
osindex=$(grep -n "START OPENVPN RULES" /etc/ufw/before.rules | cut -d: -f1)
oeindex=$(grep -n "END OPENVPN RULES" /etc/ufw/before.rules | cut -d: -f1)
if [[ "$osindex" != "" && "$oeindex" != "" ]];then
sed -i ''$osindex','$oeindex'd' /etc/ufw/before.rules
fi
sed -i '$a# START OPENVPN RULES' /etc/ufw/before.rules
sed -i '$a# NAT table rules' /etc/ufw/before.rules
sed -i '$a*nat' /etc/ufw/before.rules
sed -i '$a:POSTROUTING ACCEPT [0:0]' /etc/ufw/before.rules
sed -i '$a# Allow traffic from OpenVPN client to eth0 (change to the interface you discovered!)' /etc/ufw/before.rules
sed -i '$a-A POSTROUTING -s '$tsubnet'/24 -o '$tnetcard' -j MASQUERADE' /etc/ufw/before.rules
sed -i '$aCOMMIT' /etc/ufw/before.rules
sed -i '$a# END OPENVPN RULES' /etc/ufw/before.rules
# /etc/ufw/before6.rules修改
os6index=$(grep -n "START OPENVPN RULES" /etc/ufw/before6.rules | cut -d: -f1)
oe6index=$(grep -n "END OPENVPN RULES" /etc/ufw/before6.rules | cut -d: -f1)
if [[ "$os6index" != "" && "$oe6index" != "" ]];then
sed -i ''$os6index','$oe6index'd' /etc/ufw/before6.rules
fi
sed -i '$a# START OPENVPN RULES' /etc/ufw/before6.rules
sed -i '$a# NAT table rules' /etc/ufw/before6.rules
sed -i '$a*nat' /etc/ufw/before6.rules
sed -i '$a:POSTROUTING ACCEPT [0:0]' /etc/ufw/before6.rules
sed -i '$a# Allow traffic from OpenVPN client to eth0 (change to the interface you discovered!)' /etc/ufw/before6.rules
sed -i '$a-A POSTROUTING -s '$tsubnet6'/64 -o '$tnetcard' -j MASQUERADE' /etc/ufw/before6.rules
sed -i '$aCOMMIT' /etc/ufw/before6.rules
sed -i '$a# END OPENVPN RULES' /etc/ufw/before6.rules
sed -i 's/DEFAULT_FORWARD_POLICY="DROP"/DEFAULT_FORWARD_POLICY="ACCEPT"/g' /etc/default/ufw
ufw reload
3.我的一些个性化功能
1.配置文件发布到网上
在脚本中生成配置文件后,可以直接讲文件拷贝到自己的web服务器路径,让客户端能通过网络下载或者直接通过地址加载(android可以直接通过url加载配置)
从安全考虑,可以生成密码文件加载到nginx服务器保护配置文件被随意下载(其他服务器自己找方法)
第一步:生成密码文件
echo -n '[你的用户名]:' >> /opt/openvpn/conf.passwd
# 设置密码
openssl passwd -apr1 >> /opt/openvpn/conf.passwd
第二步:nginx加载密码文件
location /passwd {
auth_basic "Restricted Content";
auth_basic_user_file /opt/openvpn/conf.passwd
}
2.网址在终端二维码展示
直接包上面的静态文件下载地址赋值给tgeturl变量,然后通过qrencode 生成二维码展示
echo "$tgeturl" | qrencode -t ansi -l L
一些其他想法
1.通过三方提供的TCP/UDP通道提供IPV4连接上服务器
我的设备只有公网IPV6,通过DDNS接通了外网,考虑到公司网络这些情况更根本不给你的设备分配IPV6地址,会导致无法连接上服务器。
可以考虑使用frp等工具使用三方服务来链接我们的设备,在保证数据被openvpn加密的同时还能通过只有IPV4的环境来实现加密通信,网络速度取决于三方服务提供的速度。
目前已经用了一个1M的小水管frp 的 udp 转发测试OK,不看视频啥的应该还够用,能跑到100KB/s的速度,frp配置参考配置如下:
[you_vpn_forward_name]
type=udp
local_ip=127.0.0.1
local_port=10101
remote_port=40032
custom_domains=you.vpn.foeward.name
完整的脚本
使用脚本需要先适配自己的实际情况修改,不能直接运行
飞机盘下载地址:https://share.feijipan.com/s/BLAKGZoN
#!/bin/bash
# openvpn ipv4子网段设置
tsubnet=192.168.88.0
# openvpn ipv6子网段设置
tsubnet6=fc00::0
# !!! openvpn 流量转发的网卡
tnetcard=enp2s0
# openvpn 外部连接的网口
tport=10101
# openvpn 使用udp/tcp协议
tudportcp=udp
# !!! openvpn 用户配置文件中连接服务器的ip地址或者域名
tservername=192.168.3.2
# openvpn 服务器证书名字
tserver="crt.server"
# openvpn 客户端证书名字
tclient="crt.client"
tpath=$(pwd)
# openvpn 证书工作与生成的路径
tcapath=$tpath/ca
# !!! openvpn dns配置
tdns1=192.168.3.1
tdns2=119.29.29.29
# openvpn 配置文件前缀名
tcconfig=client
# !!! 你网页静态资源的服务器路径
tpubpath=/www/root/public/passwd
# 配置好静态资源后的配置文件的下载地址
tgeturl=https://you_web_server/static/$tcconfig.conf
# 配置是否所有流量都走VPN,0否,1是
all_proxy=1
if [[ "$1" == "-s" ]];then
echo 跳过软件安装和证书生成
fi
if [[ "$1" != "-s" ]];then
# apt update && \
apt install openvpn easy-rsa qrencode -y && openvpn --version
echo 软件安装成功
rm -rf $tcapath
make-cadir $tcapath
cp /usr/share/easy-rsa/vars.example $tcapath/vars
sed -i 's/"US"/"CN"/g' $tcapath/vars
sed -i 's/"California"/"JiangSu"/g' $tcapath/vars
sed -i 's/"San Francisco"/"NanJing"/g' $tcapath/vars
sed -i 's/"Copyleft Certificate Co"/"NJU"/g' $tcapath/vars
sed -i 's/"me@example.net"/"maybe_you@qq.com"/g' $tcapath/vars
sed -i 's/"My Organizational Unit"/"University"/g' $tcapath/vars
echo 'export KEY_NAME="'$tserver'"' >> $tcapath/vars
echo easy-rsa配置文件修改完成
cd $tcapath
./easyrsa init-pki
echo 初始化证书环境
./easyrsa build-ca nopass
echo 生成CA证书
./easyrsa build-server-full $tserver nopass
echo 生成服务器证书
./easyrsa build-client-full $tclient nopass
echo 生成客户端证书
./easyrsa gen-dh
echo 生成密钥
fi
cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf /etc/openvpn/server.conf
echo 拷贝案例server.conf文件到/etc/openvpn/server.conf
#sed -i 's/;local a.b.c.d/local '$tservername'/g' /etc/openvpn/server.conf
sed -i 's/;local a.b.c.d/local 0.0.0.0/g' /etc/openvpn/server.conf
sed -i '$alocal ::' /etc/openvpn/server.conf
echo 设置监听的IP
sed -i 's/port 1194/port '$tport'/g' /etc/openvpn/server.conf
echo 修改服务端口为$tport
sed -i 's/;client-to-client/client-to-client/g' /etc/openvpn/server.conf
echo 开启客户端直连
# sed -i 's/;dev tap/dev tap/g' /etc/openvpn/server.conf
# sed -i 's/dev tun/;dev tun/g' /etc/openvpn/server.conf
# echo 网卡模式切换为权限更高得tap模式
if [[ "$tudportcp" == "tcp" ]];then
sed -i 's/proto udp/;proto udp/g' /etc/openvpn/server.conf
sed -i 's/;proto tcp/proto tcp/g' /etc/openvpn/server.conf
echo 运行模式udp修改为tcp
fi
sed -i 's%ca.crt%'$tcapath'/pki/ca.crt%g' /etc/openvpn/server.conf
sed -i 's%dh2048.pem%'$tcapath'/pki/dh.pem%g' /etc/openvpn/server.conf
sed -i 's%server.crt%'$tcapath'/pki/issued/'$tserver'.crt%g' /etc/openvpn/server.conf
sed -i 's%server.key%'$tcapath'/pki/private/'$tserver'.key%g' /etc/openvpn/server.conf
echo 配置证书文件
sed -i 's/server 10.8.0.0 255.255.255.0/server '$tsubnet' 255.255.255.0/g' /etc/openvpn/server.conf
echo 配置vpn网路的网段
if [[ $all_proxy == 0 ]];then
# !!! 配置你要转发流量的网段
sed -i '$apush "route 192.168.3.0 255.255.255.0"' /etc/openvpn/server.conf
sed -i '$apush "route 192.168.0.0 255.255.255.0"' /etc/openvpn/server.conf
echo 配置走VPN的IP段
else
sed -i 's/;push "redirect-gateway/push "redirect-gateway local/g' /etc/openvpn/server.conf
echo 全部流量都走VPN
fi
sed -i 's/;push "dhcp-option DNS 208.67.220.220"/push "dhcp-option DNS '$tdns2'"/g' /etc/openvpn/server.conf
sed -i 's/;push "dhcp-option DNS 208.67.222.222"/push "dhcp-option DNS '$tdns1'"/g' /etc/openvpn/server.conf
echo VPN使用的dns服务器
sed -i 's/;mute 20/mute 20/g' /etc/openvpn/server.conf
sed -i 's/;duplicate-cn/duplicate-cn/g' /etc/openvpn/server.conf
echo 允许多客户端连接
sed -i 's/tls-auth ta.key 0/;tls-auth ta.key 0/g' /etc/openvpn/server.conf
echo 不开启tls连接
sed -i 's/;comp-lzo/comp-lzo/g' /etc/openvpn/server.conf
echo 打开压缩文件
sed -i 's/;log-append/log-append/g' /etc/openvpn/server.conf
echo log 后面增加
sed -i 's/explicit-exit-notify/;explicit-exit-notify/g' /etc/openvpn/server.conf
echo 关闭在断开连接时向服务器发送退出通知。
# echo "proto tcp6" >> /etc/openvpn/server.conf
echo 'server-ipv6 "'$tsubnet6'/64"' >> /etc/openvpn/server.conf
# echo 增加对IPV6的适配
echo 修改openvpn服务配置完成
sysctl -w net.ipv4.ip_forward=1
sysctl -w net.ipv4.conf.all.forwarding=1
sysctl -w net.ipv4.conf.default.forwarding=1
sysctl -w net.ipv6.conf.all.disable_ipv6=0
sysctl -w net.ipv6.conf.default.forwarding=1
sysctl -w net.ipv6.conf.all.forwarding=1
#iptables -t nat -D POSTROUTING -s $tsubnet/24 -o $tnetcard -j MASQUERADE
#iptables -t nat -D POSTROUTING -s $tsubnet/24 -o $tnetcard -j SNAT --to-source 192.168.3.180-192.168.3.189
#iptables -t nat -A POSTROUTING -s $tsubnet/24 -o $tnetcard -j MASQUERADE
#iptables -t nat -A POSTROUTING -s $tsubnet/24 -o $tnetcard -j SNAT --to-source 192.168.3.180-192.168.3.189
# /etc/ufw/before.rules修改
osindex=$(grep -n "START OPENVPN RULES" /etc/ufw/before.rules | cut -d: -f1)
oeindex=$(grep -n "END OPENVPN RULES" /etc/ufw/before.rules | cut -d: -f1)
if [[ "$osindex" != "" && "$oeindex" != "" ]];then
sed -i ''$osindex','$oeindex'd' /etc/ufw/before.rules
fi
sed -i '$a# START OPENVPN RULES' /etc/ufw/before.rules
sed -i '$a# NAT table rules' /etc/ufw/before.rules
sed -i '$a*nat' /etc/ufw/before.rules
sed -i '$a:POSTROUTING ACCEPT [0:0]' /etc/ufw/before.rules
sed -i '$a# Allow traffic from OpenVPN client to eth0 (change to the interface you discovered!)' /etc/ufw/before.rules
sed -i '$a-A POSTROUTING -s '$tsubnet'/24 -o '$tnetcard' -j MASQUERADE' /etc/ufw/before.rules
sed -i '$aCOMMIT' /etc/ufw/before.rules
sed -i '$a# END OPENVPN RULES' /etc/ufw/before.rules
# /etc/ufw/before6.rules修改
os6index=$(grep -n "START OPENVPN RULES" /etc/ufw/before6.rules | cut -d: -f1)
oe6index=$(grep -n "END OPENVPN RULES" /etc/ufw/before6.rules | cut -d: -f1)
if [[ "$os6index" != "" && "$oe6index" != "" ]];then
sed -i ''$os6index','$oe6index'd' /etc/ufw/before6.rules
fi
sed -i '$a# START OPENVPN RULES' /etc/ufw/before6.rules
sed -i '$a# NAT table rules' /etc/ufw/before6.rules
sed -i '$a*nat' /etc/ufw/before6.rules
sed -i '$a:POSTROUTING ACCEPT [0:0]' /etc/ufw/before6.rules
sed -i '$a# Allow traffic from OpenVPN client to eth0 (change to the interface you discovered!)' /etc/ufw/before6.rules
sed -i '$a-A POSTROUTING -s '$tsubnet6'/64 -o '$tnetcard' -j MASQUERADE' /etc/ufw/before6.rules
sed -i '$aCOMMIT' /etc/ufw/before6.rules
sed -i '$a# END OPENVPN RULES' /etc/ufw/before6.rules
sed -i 's/DEFAULT_FORWARD_POLICY="DROP"/DEFAULT_FORWARD_POLICY="ACCEPT"/g' /etc/default/ufw
ufw reload
echo 配置网络NET,让VPN网段能正常上网
systemctl restart openvpn@server
echo 启动openvpn服务
cp /etc/openvpn/server.conf $tpath/server.conf
# !!! 以下是对客户端配置的设置,如果对服务端有除去变量的修改,请仔细甄别这里是否需要修改
cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf $tpath/$tcconfig.conf
# echo "proto tcp6" >> $tpath/$tcconfig.conf
# echo 增加对IPV6的适配
if [[ "$tudportcp" == "tcp" ]];then
sed -i 's/proto udp/;proto udp/g' $tpath/$tcconfig.conf
sed -i 's/;proto tcp/proto tcp/g' $tpath/$tcconfig.conf
echo 客户端运行模式udp修改为tcp
fi
# sed -i 's/;dev tap/dev tap/g' $tpath/$tcconfig.conf
# sed -i 's/dev tun/;dev tun/g' $tpath/$tcconfig.conf
# echo 服务器网卡模式tap
sed -i 's/remote my-server-1 1194/remote '$tservername' '$tport'/g' $tpath/$tcconfig.conf
echo 客户端连接端口以及连接IP
sed -i 's/#comp-lzo/comp-lzo/g' $tpath/$tcconfig.conf
echo 打开压缩文件
sed -i 's/tls-auth ta.key 1/;tls-auth ta.key 1/g' $tpath/$tcconfig.conf
echo 不开启tls连接
sed -i 's/ca ca.crt//g' $tpath/$tcconfig.conf
echo "<ca>" >> $tpath/$tcconfig.conf
cat $tcapath/pki/ca.crt >> $tpath/$tcconfig.conf
echo "</ca>" >> $tpath/$tcconfig.conf
sed -i 's/cert client.crt//g' $tpath/$tcconfig.conf
echo "<cert>" >> $tpath/$tcconfig.conf
cat $tcapath/pki/issued/$tclient.crt >> $tpath/$tcconfig.conf
echo "</cert>" >> $tpath/$tcconfig.conf
sed -i 's/key client.key//g' $tpath/$tcconfig.conf
echo "<key>" >> $tpath/$tcconfig.conf
cat $tcapath/pki/private/$tclient.key >> $tpath/$tcconfig.conf
echo "</key>" >> $tpath/$tcconfig.conf
echo 嵌入证书文件
chmod 777 $tpath/$tcconfig.conf
cp $tpath/$tcconfig.conf $tpubpath/$tcconfig.conf
echo 订阅以下网址自动配置
echo $tgeturl
echo "$tgeturl" | qrencode -t ansi -l L
评论区