openvpn

OpenVPN installer for Debian, Ubuntu, Fedora, CentOS and Arch Linux.

遇到的问题

主机有多个IP的情况下,使用UDP会存在地址绑定不一致的情况,即:

openvpn_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:

Updated: