openvpn
OpenVPN installer for Debian, Ubuntu, Fedora, CentOS and Arch Linux.
遇到的问题
主机有多个IP的情况下,使用UDP会存在地址绑定不一致的情况,即:
解决方案有二:
-
选择使用TCP,我的选择
-
-multihome
编译,扩展sock API,具体参见OPENVPN文档–multihome
Configure a multi-homed UDP server. This option needs to be used when a server has more than one IP address (e.g. multiple interfaces, or secondary IP addresses), and is not using –local
Note 2: if you do an IPv6+IPv4 dual-stack bind on a Linux machine with multiple IPv4 address, connections to IPv4 addresses will not work right on kernels before 3.15, due to missing kernel support for the IPv4-mapped case (some distributions have ported this to earlier kernel versions, though).
手动安装配置
OpenVPN installer 的脚本已经一团麻的,处理的方式我不是很满意,所以最终选择自己配置。
主要参考https://wiki.archlinux.org/index.php/OpenVPN
Archwiki建议证书在另一个主机上生成CA(证书颁发机构),这里将会在同一个主机上进行。
# CA
cd /etc/easy-rsa
export EASYRSA=$(pwd)
easyrsa init-pki
easyrsa build-ca
cp /etc/easy-rsa/pki/ca.crt /etc/openvpn/server/
# server
export servername="server"
openssl dhparam -out /etc/openvpn/server/dh2048.pem 2048
openvpn --genkey --secret /etc/openvpn/server/ta.key
cd /etc/easy-rsa
easyrsa gen-req $servername nopass
cp /etc/easy-rsa/pki/private/$servername.key /etc/openvpn/server/
easyrsa sign-req server $servername
cp /etc/easy-rsa/pki/issued/$servername.crt /etc/openvpn/server/
# config server to use tcp,port,dns,gateway,etc
cp /usr/share/openvpn/examples/server.conf /etc/openvpn/server/server.conf
vi /etc/openvpn/server/server.conf
# for P20 client
mkdir -p /etc/easy-rsa/pki/signed
export client_name="P20"
cd /etc/easy-rsa
easyrsa gen-req $client_name nopass
easyrsa sign-req client $client_name
mv /etc/easy-rsa/pki/issued/$client_name.crt /etc/easy-rsa/pki/signed
# generate client ovpn
export client_name="P20"
ovpngen 172.24.68.231 /etc/openvpn/server/ca.crt /etc/easy-rsa/pki/signed/$client_name.crt /etc/easy-rsa/pki/private/$client_name.key /etc/openvpn/server/ta.key 1194 tcp > $client_name.ovpn
# change cipher to match server config
启动
sudo systemctl enable openvpn-server@server
sudo systemctl start openvpn-server@server
配置Iptables
sudo sysctl -w net.ipv4.ip_forward=1
sudo iptables -A INPUT -p tcp -i enp4s0 --dport 1194 -j ACCEPT
sudo iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -j MASQUERADE
sudo iptables -A INPUT -i tun+ -j ACCEPT
sudo iptables -A FORWARD -i tun+ -j ACCEPT
sudo iptables -A FORWARD -o tun+ -j ACCEPT
systemd的service文件是可以友好的overide的,参考systemd-drop in files,因此我们通过 sudo systemctl edit openvpn-server@server
的方式来自动处理
/etc/systemd/system/openvpn-server@server.service.d/override.conf
-------------------------------------------------
[Service]
ExecStartPost=/etc/iptables/add-openvpn-rules.sh
ExecStopPost=/etc/iptables/rm-openvpn-rules.sh
/etc/iptables/add-openvpn-rules.sh
-------------------------------------------------
!/bin/sh
iptables -A INPUT -p tcp -i enp4s0 --dport 1194 -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -j MASQUERADE
iptables -A INPUT -i tun+ -j ACCEPT
iptables -A FORWARD -i tun+ -j ACCEPT
iptables -A FORWARD -o tun+ -j ACCEPT
/etc/iptables/rm-openvpn-rules.sh
-------------------------------------------------
!/bin/sh
iptables -D INPUT -p tcp -i enp4s0 --dport 1194 -j ACCEPT
iptables -t nat -D POSTROUTING -s 10.8.0.0/24 -j MASQUERADE
iptables -D INPUT -i tun+ -j ACCEPT
iptables -D FORWARD -i tun+ -j ACCEPT
iptables -D FORWARD -o tun+ -j ACCEPT
配置nftables
/etc/nftables.conf
-------------------------------------------------
#!/usr/bin/nft -f
# ipv4/ipv6 Simple & Safe Firewall
# you can find examples in /usr/share/nftables/
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
# allow established/related connections
ct state {established, related} accept
# early drop of invalid connections
ct state invalid drop
# allow from loopback
iifname lo accept
# allow icmp
ip protocol icmp accept
ip6 nexthdr icmpv6 accept
# allow ssh
tcp dport ssh accept
# allow transmission
tcp dport 51413 accept
# dhcp
#ip protocol udp udp dport 68 accept
#ip6 nexthdr udp udp dport 546 accept
udp dport 68 accept
udp dport 546 accept
# vpn
jump vpn_input
# everything else
reject with icmpx type port-unreachable
}
chain forward {
type filter hook forward priority 0; policy drop;
jump vpn_forward;
}
chain output {
type filter hook output priority 0;
}
chain nat {
type nat hook postrouting priority 100;
jump vpn_nat
}
chain vpn_input {
tcp dport 1194 accept
}
chain vpn_forward {
meta iifname tun0 accept
meta oifname tun0 accept
}
chain vpn_nat {
ip saddr 10.8.0.0/24 masquerade
}
}
# vim:set ts=2 sw=2 et: