我公司办公环境需要用到 OpenVPN,之前允许一个账号在两处登录,现在处于安全考虑只允许一处登录了。
然后,我就不方便了,因为我办公环境有两台电脑(台式机 Windows,笔记本 Ubuntu)都需要接入 VPN。
现在采用的方案
- 台式机(Windows)设置网关为笔记本的内网 IP
- 笔记本(Ubuntu)连上 VPN
- 笔记本上设置 SNAT:
sudo iptables -t filter -A FORWARD -s <台式机IP> -d 10.0.0.0/8 -j ACCEPT sudo iptables -t filter -A FORWARD -s 10.0.0.0/8 -d <台式机IP> -j ACCEPT sudo iptables -t nat -A POSTROUTING -s <台式机IP> -d 10.0.0.0/8 -j SNAT --to <笔记本VPN分配IP>
在 Windows 上设置路由,只把 10 网段转发到笔记本这边:
route print
route add 10.0.0.0 mask 255.0.0.0 <笔记本IP> -p
# -p 表示永远有效
Update at 2021-05-28
在 SHELL 配置文件中注入以下函数,方便快捷:
function ipforward {
TARGET_IP='台式机IP'
TARGET_NET='内网网络, 比如:10.0.0.0/8'
SNAT_Rules=`sudo iptables -t nat -nL --line-numbers | grep SNAT`
if [ -n "$SNAT_Rules" ]
then
echo 'Found SNAT bellow:'
echo $SNAT_Rules
echo '--------------------------------------------------------------------------------'
echo 'Delete all SNAT rules...'
for Rule_Num in `printf $SNAT_Rules | awk '{print $1}'`;
do
echo "Delete SNAT Rule (num: $Rule_Num)"
sudo iptables -t nat -D POSTROUTING $Rule_Num
done;
else
echo 'No SNAT rules found!'
fi
echo '--------------------------------------------------------------------------------'
VPN_IP=`ip addr show tun0 | grep -F "inet " | awk '{print $2}'`
echo "IP forword: $VPN_IP"
sudo iptables -t nat -A POSTROUTING -s $TARGET_IP -d $TARGET_NET -j SNAT --to $VPN_IP
echo '--------------------------------------------------------------------------------'
sudo iptables -t nat -nL --line-numbers | grep SNAT
echo '--------------------------------------------------------------------------------'
echo 'OK!'
}
可能需要的操作
允许转发
我确定和这个有没有关系,反正我的电脑上是 1
cat /proc/sys/net/ipv4/ip_forward
# 允许转发
echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward
关闭防火墙
sudo systemctl disable ufw firewalld
sudo systemctl stop ufw firewalld
取消 iptables 中其他规则
# 如果不知道什么意思就先不要执行
# 还需要加上 -t filter|nat|mangle|raw|security
sudo iptables -vnL # 先看看都是些啥
sudo iptables -F # 清空所有规则
sudo iptables -X # 删除用户自定义链
修复 Windows HOSTS 文件
需要访问的内网域名都需要 dig 一遍,加到 Windows 主机的 HOSTS 文件。
function hosts.config () {
domains=(
home.internel.net
code.internel.net
docs.internel.net
)
for i in $domains; do printf "%-12s\t%s\n" $(dig +short $i) $i; done;
}
# 执行:
hosts.config | sort -k2
常用操作
别名:
vpn='vpn.status; vpn.stop; vpn.start; sleep 1; vpn.status; vpn.check'
vpn.check='/bin/ping -w 10 home.internel.net'
vpn.start='sudo systemctl start openvpn@client && echo started'
vpn.status='systemctl status -l --no-pager openvpn@client'
vpn.stop='sudo systemctl stop openvpn@client && echo stoped'
笔记本上使用的是:
sudo apt install -y openvpn
配置好 VPN 之后,VPN 的 DNS 没有配到 systemd-resolved,我这么搞定的:
sudo apt install -y openvpn-systemd-resolved
sudo tee /etc/openvpn/client.conf <<EOF
script-security 2
setenv PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
up /etc/openvpn/update-systemd-resolved
up-restart
down /etc/openvpn/update-systemd-resolved
down-pre
dhcp-option DOMAIN-ROUTE .
EOF
Update @ 2022-06-29
由于一些特殊原因,需要将指定特定的 IP 走 VPN,操作如下:
Windows 上执行:
route add <特定IP> mask 255.255.255.255 <笔记本IP> -p
Ubuntu 上执行:
sudo iptables -t nat -A POSTROUTING -s <台式机IP> -d <特定IP> -j SNAT --to <笔记本IP>
sudo iptables -t filter -A FORWARD -s <台式机IP> -d <特定IP> -j ACCEPT
sudo iptables -t filter -A FORWARD -s <特定IP> -d <台式机IP> -j ACCEPT
然后就可以了。