最後更新: 2024-02-10
目錄
- 最基本簡單的 VPN (P2P with Pre-shared key)
- Bridge (Windows Client Join Linux Side Network)
- dh key
- RSA Key 認證入門
- 設定
- 限速 (limit speed)
- Routing
- Scripting
- Log Settings
- logrotate
- management
- Proxy
- 加密強度(cipher)
- ===
- Server Mode
- Server 的 DHCP 設定
- Basic Server Configure
- ===
- port-share
- Debugging
- 建立及使用 HMAC firewall(–tls-auth)
- Signalling
- CRL (certificate revocation list)
- TLS 證書檢查
- --tls-client / --tls-server Setting
- Man-in-the-Middle attack
- Example: TLS Server & Client
- Unified format .opvpn file
- link-mtu
- Login 方式
- 測試 Connection
- WARNING 的處理
- dco
學習
openvpn --help
最基本簡單的 VPN (P2P with Pre-shared key)
Diagram
(100.1) Side_A (10.1) <-- (10.2) Side_B (100.2) Server Client
建立 Key:
Window:
cd C:\Program Files\OpenVPN\bin
openvpn.exe --genkey --secret key.txt # "tls-auth ta.key 0" 用的 key 是以同樣的 cmd 建立
key.txt 的內容:
# # 2048 bit OpenVPN static key # -----BEGIN OpenVPN Static key V1----- ... -----END OpenVPN Static key V1-----
Side_A 的設定檔: (Server)
很少 setting 已經夠
/etc/openvpn/toB.conf
#mode p2p(Default)
#proto udp (Default)
#port 1194 (Default)
#remote 10.10.10.1 (由於是 Server, 等另一方連過來, 所以係非必要的)
secret key.txt
# 可以是定 tun0, tun1 ...
dev tun
# 由於是用 "dev tun" 及 topology net30 (Default)
# 所以要用 ifcofig 設定兩端 IP
ifconfig 192.168.100.1 192.168.100.2
如果另一端是 Linux, 那就要
dos2unix your_configure.ovpn
Side_B 的設定檔: (Client)
/etc/openvpn/toA.conf
# 放在 /etc/openvpn 內的 *.conf 會被 /etc/init.d/openvpn start 時啟動
# remote host [port] [proto] remote 10.10.10.1 # dev virtual-network-device # dev tunX | tapX | null ( X can be omitted for a dynamic device ) dev tun # LOCAL_IP REMOTE_IP ifconfig 192.168.100.2 192.168.100.1 # 需要用 full path, 否則會認為 key.txt 在當前目錄 secret /etc/openvpn/key.txt ##### 以下為非必要設定 ##### # dev-type device-type # Which device type are we using ? # tun (OSI Layer 3) / tap (OSI Layer 2) # 當 "--dev" 的名稱不是以 tun 或 tap 開頭時才需要此設定 # 用了此設定可以將 virtual-network-device 命名得更好, 比如 R1-To-R2 dev-type tun # 在 "--dev tun" 時此設定才有效 # ("-dev tap" 時是沒有效的, 因為 "tap" 只用 "topology subnet") # 在 server mode 時, 此設定會被 push 到 clients # 設定: net30(Default) / subnet # net30: allocating one /30 subnet per client (p2p) # subnet: changes the interpretation of the arguments of "--ifconfig" to mean "address netmask" # (no longer "local remote") topology net30 # 斷線重啟 keepalive 10 60 # log setting mute 10 verb 4 log /var/log/openvpn/log status /var/log/openvpn/status # keep pid writepid /var/run/openvpn.pid
Startup:
openvpn --config /etc/openvpn/toB.conf
以上 cmd 相當於:
openvpn --remote 10.10.10.2 \
--dev tun --ifconfig 192.168.100.1 192.168.100.2 \
--secret /etc/openvpn/key.txt
More info:
# By default, OpenVPN runs in point-to-point mode ("p2p")
--mode m
Firewall 記得開 port:
UDP / 1194 <-- Openvpn default 是用 UDP Port 的
Log
Tue Apr 17 18:20:51 2018 Initialization Sequence Completed
設定說明
Network:
ifconfig
This option, while primarily a proxy for the ifconfig(8) command
( designed to simplify TUN/TAP tunnel configuration )
ifconfig <local IP> <remote IP> # tun ( point-to-point connection )
ifconfig <local IP> <subnet mask> # tap ( bridging mode )
proto <udp> | <tcp-client> ( start connections) | <tcp-server> (waits connections)
Log:
verb <n> 0 ---> 11 (Hightest)
mute <n> 重覆 n 次才 log 一句
Static Key encryption mode (--secret) 好處
1. hand‐shake-free protocol without any distinguishing signature
OVPN Startup Script
ovpn-tun.sh
#!/bin/bash
CONFIG=/etc/openvpn/server-tun.conf
PID=/var/run/server-tun.pid
openvpn --config $CONFIG --writepid $PID --daemon
Bridge (Windows Client Join Linux Side Network)
Windows_Side(Client)
C:\Program Files\OpenVPN\config\client.ovpn
remote datahunter.org port 1194 # 當是 tcp 時, 就用 proto tcp-client proto udp # tun / tap dev tap ping 10 comp-lzo secret key.txt
comp-lzo
選擇性壓縮設定
* Fast LZO compression
may add up to 1 byte per packet for incompressible data
comp-lzo yes | no | adaptive (default)
- adaptive: selectively turn compression on or off for individual clients
Linux_Server_Side:
/etc/openvpn/server.conf
port 1194 proto udp # 設定 tap device 的名單而不是自動生成 dev tap0 # 與 server 一樣的 key secret key.txt # script-security 用來設定 up / down script 行的權限 script-security 3 system # openvpn nic up/down 時所行的 script up /etc/openvpn/up.sh down /etc/openvpn/down.sh comp-lzo # 收到 "SIGUSR1" or "ping-restart" # 1. Don't close and reopen TUN/TAP device # 2. Don't run up/down scripts # Normally if you drop root privileges in OpenVPN, the daemon cannot be restarted # since it will now be unable to re-read protected key files. persist-tun persist-key # Log setting verb 5 mute 10 log /var/log/openvpn/openvpn.log status /var/log/openvpn/status
keepalive Settings
--ping n
# 當沒有 data 傳輸時, 就會每 n 秒在 TCP/UDP control channel ping remote host 一次 # 這個 ping 只會 ping 過去, 對方並不會 echo 回來 !! # 作用是令 stateful firewall allow package 進去
--ping-restart n
# trigger a SIGUSR1 restart after n seconds pass without reception packet
# causing the hostname used with --remote to be re-resolved (if --resolv-retry is specified)
# In server mode, always be applied to individual client instance objects
Default
In client mode, the --ping-restart parameter is set to 120 seconds by default.
To disable the 120 second default, set --ping-restart 0 on the client.
--keepalive interval timeout
# 此設定相當於同時設定了 "--ping" 及 "--ping-restart"
* 當 Client 及 Server 都有此設定時, Server 的 keepalive 會 override Client
i.e.
--keepalive 10 60
if mode server: ping 10 ping-restart 120 push "ping 10" push "ping-restart 60" else ping 10 ping-restart 60
* 'ping-restart' 在 server side 係雙陪的 !
This ensures that a timeout is detected on client side before the server side drops the connection.
keepalive 10 60
idle timeout (Default: 0 = disables this feature)
OpenVPN to exit if less than bytes of combined in/out traffic
are produced on the tun/tap device in n seconds.
--inactive n [bytes]
inactive sec byte
dh key
建立 dh key
# 產生一個 2048 bit 的質數
openssl dhparam -out dh2048.pem 2048
設定
dh keys/dh2048.pem
Remark
https://datahunter.org/dh
使用 RSA Key 認證入門
Server:
# openvpn 會自動找出未被使用的 tun 來使用 (i.e. tun0)
dev tun
ifconfig 10.3.0.1 255.255.255.0
tls-server
dh keys/dh2048.pem
ca keys/ca.crt
cert keys/VPN-Server.crt
key keys/VPN-Server.key
Client:
remote 10.10.10.103
dev tun
ifconfig 10.3.0.2 255.255.255.0
tls-client
dh keys/dh2048.pem
ca keys/ca.crt
cert keys/VPN-Client.crt
key keys/VPN-Client.key
建立 CA, Crt 及 Keys 的方法:
最簡單建方法: easy-rsa
設定
--dev-node <interface name>
--ping-timer-rem # 當 remote 的 DNS Name 有值時, 那 --ping-exit 及 ping-restart 才生效(用於 listen mode)
--inactive <sec> # 沒有使用 tunnel 幾耐後就 shutdown 它
--resolv-retry <sec> # 幾耐解釋一次 DNS Name (Default 1 天 !!)
# i.e. resolv-retry infinite
--local <IP> # 用那個 ip 做 connect
--remote host [port]
--proto p # Default: UDP
--remote-random # 如果有多個 server (--remote) 時, 那會 random 選其中一個來連
--float # 另一端的 VPN Parter 可以轉 IP / Port (會引發 ipchange) 不會引發 restart tunnel !
--ipchange <cmd> # 當 IP 有變時, 那就 call cmd
--connect-retry <sec> # Default 60s
--connect-retry-max <n>
沒有加 float 時:
... TCP/UDP: Incoming packet rejected from [AF_INET]R2.R2.R2.R2:1230[2], expected peer address: [AF_INET]R1.R1.R1.R1:1194 (allow this incoming source address/port by removing --remote or adding --float)
限速 (limit speed)
shaper <n Bytes> <--- 限制 Outgoing 的 BW 在 TCP/UDP port (i.e. eth0) 上
# If you want to limit the bandwidth in both directions, use this option on both peers.
# (OpenVPN allows n to be between 100 bytes/sec and 100 Mbytes/sec.)
algorithm to implement:
after a datagram write of b bytes is queued on the TCP/UDP port,
wait a minimum of (b / n) seconds before queuing the next write.
Routing(Client Setting)
Setting:
- route <network>
- route-gateway <IP>
- route-delay <sec>
- route-up <cmd>
-
redirect-gateway [flags] # commands to redirect all outgoing IP traffic through the VPN
'local'
'def1' # 0.0.0.0/1 rather than 0.0.0.0/0
'bypass-dhcp'
'bypass-dns'
Example:
ifconfig 10.3.0.1 10.3.0.2 route 192.168.0.0 255.255.255.0 10.3.0.2 route-delay 2
Scripting
openvpn script:
* up / down-pre / down <--- tun / tap 的 up / down
* up-restart <--- reconnect
* route-up
* ipchange
/etc/openvpn/up.sh <---- 權限 root / root 的 770 都可以
#!/bin/sh # create by tim # the tap interface name is passed as first argument _ovsBr="br0" ifconfig "$1" up ovs-vsctl --if-exists del-port "$_ovsBr" "$1" ovs-vsctl --may-exist add-port "$_ovsBr" "$1" sleep 3 # arp proxy echo 1 > /proc/sys/net/ipv4/conf/$_ovsBr/proxy_arp
/etc/openvpn/down.sh
#!/bin/sh
# Last update: 20151229
_ovsBr="br0"
#ifconfig "$1" down
ovs-vsctl --if-exists del-port "$_ovsBr" "$1"
exit 0
當 down.sh 寫錯野, 那 openvpn 就會收到 SIGHUP (killall -s HUP openvpn)會起唔返 !
Fri Aug 15 10:43:39 2014 event_wait : Interrupted system call (code=4)
Fri Aug 15 10:43:39 2014 /etc/openvpn/down.sh tap0 1500 1577 init
interface tap0 does not exist!
tap0: ERROR while getting interface flags: No such device
Fri Aug 15 10:43:39 2014 WARNING: Failed running command (--up/--down):
external program exited with error status: 255
Fri Aug 15 10:43:39 2014 Exiting
For --dev tun execute as:
cmd tun_dev tun_mtu link_mtu ifconfig_local_ip ifconfig_remote_ip [ init | restart ]
For --dev tap execute as:
cmd tap_dev tap_mtu link_mtu ifconfig_local_ip ifconfig_netmask [ init | restart ]
root@ubuntu:/etc/openvpn# brctl show
bridge name bridge id STP enabled interfaces vboxbr0 8000.1203e3a90b89 no tap0
--script-security level [method]
0 - Strictly no calling of external programs.
1 - (Default) Only call built-in executables such as ifconfig, ip, route, or netsh.
2 - Allow calling of built-in executables and user-defined scripts.
3 - Allow passwords to be passed to scripts via environmental variables
execve -- (default) Use execve() function on Unix family OSes
--up cmd
Shell command to run after successful TUN/TAP device open (pre --user UID change) <= 亦即是會用 root 來行
P.S.
當 script 執行失敗, vpn 是會起唔到的 !!
Log Settings
Settings
log <file> # log-append 它與 log 有一樣功能, 並會 overwrite file 及 create file
status <file>
OpenVPN STATISTICS Updated,Tue Nov 5 11:00:21 2013 TUN/TAP read bytes,44598 TUN/TAP write bytes,11175 TCP/UDP read bytes,15732 TCP/UDP write bytes,3144 Auth read bytes,11224 pre-compress bytes,4442 post-compress bytes,3678 pre-decompress bytes,1145 post-decompress bytes,1210 END
Example
# 查看新連接
grep 'SENT CONTROL' openvpn.log
logrotate
/etc/openvpn/server.conf
# log setting status /var/log/openvpn/openvpn-status.log log-append /var/log/openvpn/openvpn.log verb 3 mute 10
/etc/logrotate.d/openvpn
/var/log/openvpn/openvpn.log {
daily
rotate 7
delaycompress
compress
notifempty
missingok
create 640 openvpn openvpn
copytruncate
}
# Test
logrotate -v -f /etc/logrotate.d/openvpn
management
啟用 management 功能
[方式1]
management <IP> <port> pw-file
[方式2]
management socket-name unix [pw-file]
management-client-user [user]
management-client-group [user]
i.e.
# management management /var/lib/openvpn/mgt-nas.sock unix management-client-user root management-client-group root
Socket Permission
ls -l /var/lib/openvpn/mgt-nas
srwxrwxrwx 1 root root 0 Sep 10 16:59 /var/lib/openvpn/mgt-nas
although the socket is still created with the same permissions,
you won't be able connect to it with users other than specified by those directives
test
su admin
$ echo status | socat - unix-connect:/var/lib/openvpn/mgt-nas.sock # no output
log file
... MANAGEMENT: unix domain socket client connection rejected -- UID of socket peer (1001) doesn't match required value (0) as given by --management-client-user
Test
# Help
echo help | socat - unix-connect:/var/lib/openvpn/mgt-nas.sock
# OpenVPN STATISTICS
echo status | socat - unix-connect:/var/lib/openvpn/mgt-nas.sock
# Show the current OpenVPN state
echo state | socat - unix-connect:/var/lib/openvpn/mgt-nas.sock
1631264791,CONNECTED,SUCCESS,10.3.0.1,14.0.230.16,8805,,
(a) the integer unix date/time
(b) the state name
(c) optional descriptive string ()
(d) optional TUN/TAP local IP address
(e) optional address of remote server
State name
- CONNECTING OpenVPN's initial state.
- WAIT (Client only) Waiting for initial response from server.
- CONNECTED Initialization Sequence Completed.
Other Setting
management-log-cache <n> # 在 management 保留幾多行 log
Proxy
http-proxy <server port [auth]>
http-proxy-retry <n>
http-proxy-timeout <sec>
socks-proxy <server port>
socks-proxy-retry <n>
加密強度(cipher)
設定
- cipher alg
- ncp-ciphers cipher_list
- digest
cipher
cipher alg # encryption of data channel packets
i.e.
cipher AES-256-CBC
Remark
* V 2.4: The default is BF-CBC (Blowfish in Cipher Block Chaining mode)
P.S.
Set alg "none" to disable encryption.
ncp-ciphers
ncp-ciphers cipher_list
i.e.
ncp-ciphers AES-256-CBC:AES-192-CBC
Remark
For servers, the first cipher from cipher_list will be pushed to clients that support cipher negotiation.
P.S.
* Cipher negotiation is enabled in client-server mode only
If both peers support and do not disable NCP,
the negotiated cipher will override the cipher specified by --cipher
digest
--auth alg
Authenticate packets with HMAC using message digest algorithm alg (default=SHA1).
(usually adds 16 or 20 bytes per packet)
Set alg=none to disable authentication.
i.e.
auth SHA1
查看支持什麼 ciphers
openvpn --show-ciphers
... AES-256-CBC (256 bit key, 128 bit block) AES-256-CFB (256 bit key, 128 bit block, TLS client/server mode only) AES-256-CFB1 (256 bit key, 128 bit block, TLS client/server mode only) AES-256-CFB8 (256 bit key, 128 bit block, TLS client/server mode only) AES-256-GCM (256 bit key, 128 bit block, TLS client/server mode only) AES-256-OFB (256 bit key, 128 bit block, TLS client/server mode only) ...
openvpn --show-digests # message digest
MD5 128 bit digest size RSA-MD5 128 bit digest size SHA1 160 bit digest size ...
openvpn --show-tls
Available TLS Ciphers, listed in order of preference: ECDHE-RSA-AES256-GCM-SHA384 ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-RSA-AES256-SHA384 ECDHE-ECDSA-AES256-SHA384 ECDHE-RSA-AES256-SHA ECDHE-ECDSA-AES256-SHA ......................... EXP-EDH-RSA-DES-CBC-SHA EXP-EDH-DSS-DES-CBC-SHA EXP-DES-CBC-SHA EXP-RC2-CBC-MD5 EXP-RC4-MD5
openvpn --show-engines
RSAX engine support [rsax] Dynamic engine loading support [dynamic]
openvpn --test-crypto --secret /etc/openvpn/key.txt
Tue Nov 19 09:46:00 2013 Entering OpenVPN crypto self-test mode. Tue Nov 19 09:46:00 2013 TESTING ENCRYPT/DECRYPT of packet length=1 Tue Nov 19 09:46:00 2013 TESTING ENCRYPT/DECRYPT of packet length=2 Tue Nov 19 09:46:00 2013 TESTING ENCRYPT/DECRYPT of packet length=3 ...................................... Tue Nov 19 09:46:00 2013 TESTING ENCRYPT/DECRYPT of packet length=1498 Tue Nov 19 09:46:00 2013 TESTING ENCRYPT/DECRYPT of packet length=1499 Tue Nov 19 09:46:00 2013 TESTING ENCRYPT/DECRYPT of packet length=1500 Tue Nov 19 09:46:00 2013 OpenVPN crypto self-test mode SUCCEEDED.
Client 有關的 Setting
# multiple clients with the same certificate/key ( same common name )
duplicate-cn <--- 一 certificate 可以被多個 client 共用
connect-freq <n> sec <--- 一個 Client 在指定時間內可以 connect 幾多次
( 用 --proto udp 及 --tls-auth 會有較好防 DDOS 效果)
nobind
Do not bind to local address and port.
The IP stack will allocate a dynamic port for returning packets.
Since the value of the dynamic port could not be known in advance by a peer,
this option is only suitable for peers which will be initiating connections by using the –remote option.
Server Mode
mode server | p2p (default)
設置用 Server mode 還是 p2p Mode
Remark
"--client-config-dir" 在 server mode 才可以使用
--server 與 --server-bridge
它們都是 shortcut 來, 背後會執行一堆指令
* server 與 server-bridge 是二選 1 的 !!
- --server
- --server-bridge
--server
server <network> <mask>
* 設置 client 的 ip range, 亦即是說會派 IP 給 Client
* The server itself will take the ".1" address
i.e.
--server 10.8.0.0 255.255.255.0
相當於:
mode server
tls-server
push "topology [topology]"
topology:
if dev tun AND (topology == net30 OR topology == p2p): ifconfig 10.8.0.1 10.8.0.2 if !nopool: ifconfig-pool 10.8.0.4 10.8.0.251 route 10.8.0.0 255.255.255.0 if client-to-client: push "route 10.8.0.0 255.255.255.0" else if topology == net30: push "route 10.8.0.1" if dev tap OR (dev tun AND topology == subnet): ifconfig 10.8.0.1 255.255.255.0 if !nopool: ifconfig-pool 10.8.0.2 10.8.0.254 255.255.255.0 push "route-gateway 10.8.0.1"
P.S.
由於有 tls-server, 所用不能用 keyfile 的 login
--server-bridge
It will enable a DHCP-proxy mode
(clients will receive an IP address for their TAP adapter from the DHCP server running on the OpenVPN server-side LAN)
server-bridge gateway netmask pool-start-IP pool-end-IP
mode server tls-server ifconfig-pool pool-start-IP pool-end-IP netmask push "route-gateway gateway"
OR
server-bridge
mode server tls-server push "route-gateway dhcp"
OR
server-bridge nogw
# nogw: gateway information should not be pushed to the client
mode server tls-server
設定過程
1. Configure server mode for ethernet bridging.
=> You must first use your OS's bridging capability to bridge the TAP interface with the ethernet NIC interface.
2. Then you must manually set the IP/netmask on the bridge interface
3. Finally we must set aside an IP range in this subnet
Exampe: tun server
server-tun.conf
server 10.10.10.0 255.255.255.0 ifconfig-pool-persist ipp.txt port 5555 proto udp dev tun0 auth SHA1 cipher AES-192-CBC persist-key persist-tun comp-lzo #shaper 302400 ping 3 ping-restart 15 tls-auth /etc/openvpn/ta.key 0 dh /etc/openvpn/dh2048.pem ca /etc/openvpn/ca.crt cert /etc/openvpn/VPN-Server.crt key /etc/openvpn/VPN-Server.key mute 10 verb 4 log /var/log/openvpn/server-tun.log status /var/log/openvpn/server-tun.status #push "redirect-gateway def1"
iptables
iptables -A INPUT -i tun+ -j ACCEPT iptables -A FORWARD -i tun+ -j ACCEPT iptables -A OUTPUT -o tun+ -j ACCEPT iptables -t nat -A POSTROUTING -s 10.10.10.0/24 -o br0 -j MASQUERADE
Exampe: Ethernet bridging(server-bridge)
設定
由
server dev tun / tap
改成
server-bridge
dev tap
server-bridge
Let OpenVPN manage its own client IP address pool using the server-bridge directive, or
(server-bridge 192.168.8.4 255.255.255.0 192.168.8.128 192.168.8.254)
configure the DHCP server on the LAN to also grant IP address leases to VPN clients.
Remark
* each network interface which is added to the bridge will lose its individual identity in terms of specific settings.
(such as IP address and netmask)
Only the TCP/IP settings of the bridge interface itself will be relevent.
Firewall Setting
#!/bin/sh iptables -t nat -I PREROUTING -p udp --dport 1194 -j ACCEPT iptables -I INPUT -p udp --dport 1194 -j ACCEPT iptables -I INPUT -i tap21 -j ACCEPT iptables -I FORWARD -i tap21 -j ACCEPT
Server 的 DHCP 設定
設定 Server 如何派 IP 比 Client
用了 --server 及 --server-bridge 就不用另外設定它們(--ifconfig-pool)
--ifconfig-pool start-IP end-IP [netmask]
i.e.
ifconfig-pool 10.8.0.128 10.8.0.254 255.255.255.0
Remark
do not guarantee that the given common name will always receive the given IP address. If
you want guaranteed assignment, use --ifconfig-push
persist dhcp ip
--ifconfig-pool-persist file [seconds]
# Maintain a record of client <-> virtual IP address associations in this file.
# ifconfig-pool data to "file", at "seconds" intervals (default=600)
# seconds = 0, file will be treated as read-only. (它變成了 configuration file (自己設定 Persist IP))
ifconfig-pool-persist ipp.txt
log:
Mon May 4 13:35:05 2015 115.160.172.18:1194 MULTI_sva: pool returned IPv4=192.168.123.201, IPv6=1::1300:0:b67f:0
ipp.txt
# <Common-Name>,<IP-address> tim,192.168.234.2
remark
在 tun mode 時 ipp.txt 是保存 "network id" 的
Basic Server Configure
local your_ip_here port 1194 proto udp dev tap0 up "/etc/openvpn/up.sh vboxbr0 tap0 1500" down "/etc/openvpn/down.sh vboxbr0 tap0" persist-key persist-tun #certificates and encryption ca ca.crt cert vpn-server.crt key vpn-server.key # This file should be kept secret dh dh2048.pem tls-auth ta.key 0 # This file is secret comp-lzo max-clients 10 user nobody group nogroup keepalive 10 120 # log log /var/log/openvpn.log status openvpn-status.log verb 3
port-share
# openvpn listen https lport 443 # x.x.x.x is the internal IP address of the web server port-share x.x.x.x 10443
Debugging
verb 5 in its configuration file (會在 log 內見到 RWrw )
WR: real interface Write / Read
* uppercase is used for TCP/UDP packets and lowercase is used for TUN/TAP packets.
未連到:
Mon Nov 4 18:07:03 2013 us=886521 Local Options hash (VER=V4): '83c3b015' Mon Nov 4 18:07:03 2013 us=886540 Expected Remote Options hash (VER=V4): '83c3b015' Mon Nov 4 18:07:03 2013 us=886918 UDPv4 link local (bound): [undef] Mon Nov 4 18:07:03 2013 us=887010 UDPv4 link remote: [undef] rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
連到時:
Nov 4 18:08:35 2013 us=283711 Peer Connection Initiated with [AF_INET]192.168.88.177:1194
Mon Nov 4 18:08:36 2013 us=152528 Initialization Sequence Completed
wrWrWrWrWrWrWRwrWrWrWrWrWrWrWrWrWrWrWrWrWrWrWRwrWrWRwRwRwrWrWrWrWrWrWrWrWrWrWrWRwrWrWrWrWR
單一個 ping package log:
RwrW
Diagram:
client ---- server --> eth0 | tap0 --> R w <-- eth0 | tap0 <-- W r
建立及使用 HMAC firewall(–tls-auth)
Add an additional layer of HMAC authentication on top of the TLS control channel to protect against DoS attacks.
原理:
signing every TLS control channel packet with an HMAC signature ( Protect "TLS handshake" )
packets bearing an incorrect HMAC signature can be dropped immediately without response
--tls-auth gives a peer nothing more than the power to initiate a TLS handshake.
(It is not used to encrypt or authenticate any tunnel data.)
Step 1
建立 key
# This file is secret
openvpn --genkey --secret ta.key
* The server and each client must have a copy of this key.
Server / Client 設定
# it's either 0 and 1, or no parameter for bidirectional use. Server: 0, Client: 1
# –tls-auth file [direction] tls-auth ta.key 0
Remark
–key-direction
Alternative way of specifying the optional direction parameter for the –tls-auth and –secret options.
Useful when using inline files (將 ta.key 打包到 *.ovpn 內)
* pre-existing secure channel with your peer for get ta.key
失敗時的 Server log
TIME us=619043 SOURCE_IP:PORT TLS Error: cannot locate HMAC in incoming packet from [AF_INET]SOURCE_IP:PORT
Default
使用 "--tls-auth ta.key" 時如果沒有加 "--auth", 預設係 SHA1
有機會出 error. Server log
... TLS Error: cannot locate HMAC in incoming packet from [AF_INET]R.R.R.R:1194
Fix
--tls-auth ta.key --auth SHA256
Signalling
- SIGHUP <-- 相當於 service openvpn reload
1. re-read the configuration file
2. close and reopen the network connection to its peer <-- 會有 1~2 個 ping package loss
- SIGUSR1 <-- 相當於 service openvpn reopen
Offers more fine-grained control over which OpenVPN subsystems are reset
Like SIGHUP, except don’t re-read configuration file
and possibly don’t close and reopen TUN/TAP device, re-read key files, preserve local IP address/port
--ping 及 --ping-restart 是 SIGUSR1 來
* 此不會重建 log file
- SIGUSR2 <-- 相當於 service openvpn status
Current statistics to the log file (log /var/log/openvpn/openvpn.log) if --daemon
status /var/log/openvpn/status
CRL (certificate revocation list)
Server 設定:
# ln -s /usr/share/easy-rsa/2.0/keys/crl.pem /etc/openvpn/crl.pem crl-verify crl.pem
建立 CRL:
cd /usr/share/easy-rsa/2.0
. ./vars
./revoke-full client2 <-- cert-name
那會建立 crl.pem
CRL file will be re-read
* any time a new client connects
* an existing client renegotiates the SSL/TLS connection (by default once per hour)
flush all clients:
SIGHUP
A common reason why certificates need to be revoked is that the user encrypts their private key with a password, then forgets the password. By revoking the original certificate, it is possible to generate a new certificate/key pair with the user's original common name.
查看
source ./vars
./list-crl <-- openssl crl -text -noout -in FILE.crl
Log:
Fri Jan 3 16:59:06 2014 xx.xx.xx.xx:1194 CRL CHECK FAILED: C=CN, ST=HK, L=Hong Kong, O=xxx, OU=IT, CN=xxx, [email protected] is REVOKED
TLS 證書檢查
# Client Side 設定來, 用來防止 Man-in-the-Middle 攻擊
remote-cert-tls server / client
It is a macro which sets the --remote-cert-ku and --remote-cert-eku to appropriate values
The values depending on whether you to check if the remote provided certificate is a server certificate or client certificate.
Require that peer certificate was signed with an explicit key usage and extended key usage based on RFC3280 TLS rules.
This is a useful security option for clients, to ensure that the host they connect to is a designated server.
Or the other way around; for a server to verify that only hosts with a client certificate can connect.
Key Usage
CA certificate: key usage “crl sign”, “key cert sign”
Server certificate: “digital signature”, “key enchipherment”, “tls server”
Client certificate: key usage “tls client”
--tls-client / --tls-server Setting
Enable TLS and assume client/server role during TLS handshake.
The designation of client or server is only for the purpose of negotiating the TLS control channel.
--tls-version-min version ['or-highest']
TLS version negotiation. ("1.0", "1.1", or "1.2")
--tls-timeout n
Packet retransmit timeout on TLS control channel if no acknowledgment from remote within n seconds (default=2).
When OpenVPN sends a control packet to its peer, it will expect to receive an acknowledgement within n seconds or
it will retransmit the packet, subject to a TCP-like exponential backoff algorithm.
This parameter only applies to control channel packets.
Data channel packets (which carry encrypted tunnel data) are
never acknowledged, sequenced, or retransmitted by OpenVPN
because the higher level network protocols running on top of the tunnel
such as TCP expect this role to be left to them.
--tls-client v.s. --client
"--client" 相當於 "--tls-client" + "--pull"
Notes
"--route-nopull" bars the server from adding routes to the client's routing table
Man-in-the-Middle attack
情況
An authorized client tries to connect to another client by impersonating the server
Client configuration:
remote-cert-tls server
More info:
當 Server 的 Certicate 沒有 "nsCertType=server" attributes 時就會中止連線
openssl x509 -in VPN-Server.crt -text | less
... X509v3 Extended Key Usage: TLS Web Server Authentication
By Default Server 是不會接受 Server Cert. 的
... VERIFY ERROR: depth=0, error=unsupported certificate purpose: C=HK, ST=HONG KONG, L=HONG KONG, O=Home, OU=IT, CN=VPN-Client01, name=EasyRSA, [email protected]
Example: TLS Server & Client
TLS Server
server-bridge nogw port 1194 proto udp dev tap0 up /etc/openvpn/up.sh down /etc/openvpn/down.sh comp-lzo yes cipher AES-256-CBC persist-key persist-tun #shaper 302400 ping 10 ping-restart 10 tls-auth /etc/openvpn/ta.key 0 dh /etc/openvpn/dh2048.pem ca /etc/openvpn/ca.crt cert /etc/openvpn/VPN-Server.crt key /etc/openvpn/VPN-Server.key mute 10 verb 4 log /var/log/openvpn/openvpn.log status /var/log/openvpn/status
TLS Client
tls-client remote x.y.z port 1194 proto udp remote-cert-tls server dev tap ping 10 ping-restart 10 comp-lzo yes cipher AES-256-CBC # log log home.log verb 4 mute 10 # file tls-auth ta.txt 1 ca ca.txt cert cert.txt key key.txt
unified format .opvpn file
All certs and keys to be embedded into the .ovpn file
原來 setting
ca ca.crt cert client.crt key client.key tls-auth ta.key 1
Unified format Setting
# ca ca.crt <ca> -----BEGIN CERTIFICATE----- ... -----END CERTIFICATE----- </ca> # cert client.crt <cert> -----BEGIN CERTIFICATE----- ... -----END CERTIFICATE----- </cert> # key client.key <key> -----BEGIN PRIVATE KEY----- ... -----END PRIVATE KEY----- </key> # key-direction 0 / 1 / bidirectional # The optional direction parameter for the --tls-auth and --secret # For the tls-auth direction; server=0, client=1 key-direction 1 <tls-auth> -----BEGIN OpenVPN Static key V1----- ... -----END OpenVPN Static key V1----- </tls-auth>
link-mtu
Error on Client
... WARNING: 'link-mtu' is used inconsistently, local='link-mtu 1541', remote='link-mtu 1542'
原因: Server 與 Client 的 WAN(上網方式) 是不同類型 (e.g. Ethernet, 4G)
[Fix]
- --link-mtu max
- --tun-mtu max
建議 fixing
--fragment max --mssfix max # 此設定只在 "proto udp" 時有效
--fragment N
Enable internal datagram fragmentation so that no UDP datagrams
are sent which are larger than max bytes.
* "--fragment" adds 4 bytes of overhead per datagram.
--mssfix N # The default value is 1450.
Announce to TCP sessions running over the tunnel that they should limit their send packet sizes
such that after OpenVPN has encapsulated them the resulting UDP packet size
that OpenVPN sends to its peer will not exceed maxbytes.
--fragment N --mssfix
If --fragment and --mssfix are used together,
--mssfix will take its default max parameter from the --fragment max option.
e.g.
--fragment 1300 --mssfix
--mtu-test
* --mtu-test only makes sense with "--proto udp"
To empirically measure MTU on connection startup
The --mtu-test process normally takes about 3 minutes to complete.
OpenVPN will send ping packets of various sizes to the remote peer and
measure the largest packets which were successfully received.
Login 方式
client-side authentication method is specified
--cert/--key, --pkcs12, or --auth-user-pass
測試 Connection
Client CLI
openvpn --client --remote R.R.R.R 1194 --proto udp \
--tls-auth ta.key --auth SHA256 \
--dev tun --ca ca.crt --remote-cert-tls server \
--auth-user-pass dummy-login.txt \
--verify-x509-name $RANDOM name \
--connect-retry-max 1 --connect-timeout 10
* 由於行 udp, 所以測試不到 service 是否在行
* 由於使用了 HMAC firewall, 即使 service 在行, 但 package 不對也是沒有回應的
--verify-x509-name
設定方式
- verify-x509-name 'C=KG, ST=NA, L=Bishkek, CN=Server-1'
- verify-x509-name Server-1 name
--connect-timeout
Default: 120
--connect-retry-max
...
Client Log
[1]
... AUTH: Received control message: AUTH_FAILED
[2]
.. OpenSSL: error:0A000086:SSL routines::certificate verify failed .. TLS_ERROR: BIO read tls_read_plaintext error .. TLS Error: TLS object -> incoming plaintext read error .. TLS Error: TLS handshake failed
WARNING 的處理
... WARNING: 'auth' is used inconsistently, local='auth [null-digest]', remote='auth SHA1'
當使用 GCM algorithms 時不用理會
GCM algorithms don't use the additional authentication algorithm,
because GCM ciphers includes authentication tags in the main cipher.
... WARNING: No server certificate verification method has been enabled. See http://openvpn.net/howto.html#mitm for more info.
--remote-cert-tls server|client
多數在 Client 設定. 用於肯定連上的是 Server, 而不是 Client
... WARNING: 'link-mtu' is used inconsistently, local='link-mtu 1583', remote='link-mtu 1575'
dco
dco = Data Channel Offload
By offloading data plane management to the Linux kernel module (ovpn-dco)
2.6.12+ implements support for data-channel offloading
=> The userspace openvpn program acts purely as a control plane application.
Module
Linux: ovpn-dco
Windows: ovpn-dco-win
disable-dco
tcp connection 出 error 時用到
... dco connect error: Access is denied. (errno=5)
Add the option --disable-dco to disable data channel offload support.
When starting openvpn it will automatically detect DCO support and use the kernel module.
Limitations by design
- Layer 3 (dev tun) only;
- AEAD ciphers are currently supported: Chacha20-Poly1305 and AES-GCM-128/192/256;