openvpn config

最後更新: 2024-02-10

目錄

學習

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: 0Client: 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

設定方式

  1. verify-x509-name 'C=KG, ST=NA, L=Bishkek, CN=Server-1'
  2. 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'

MTU 問題

 


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;