SSH tunneling is faster than OpenVPN, could it be?
Logically, VPN should be faster than SSH for tunneling, because:
- It's running on UDP and not TCP (so no TCP over TCP)
- It has compression
However, today I tested Redis replication over both methods.
I ran the test over an Ireland AWS VM, connecting to a US-East AWS VM.
Since my test case is Redis replication, this is exactly what I tested - I ran a blank Redis server, and after it finished loading, I executed slaveof
the other server, and measured the time between Connecting to MASTER
and MASTER <-> SLAVE sync: Finished with success
. In between, I used
while 1; do redis-cli -p 7777 info | grep master_sync_left_bytes;sleep 1; done
To get a crude estimation of the speed.
SSH won by a long shot: ~11MB/s compared to OpenVPN's ~2MB/s.
Does that mean that all of what I reaserched was wrong, or have I grossly misconfigured my setup?
Update
I've made several test with the same dataset, and got these results:
- OpenVPN
- TCP:
compression: 15m
no compression: 21m - UDP:
compression: 5m
no compression: 6m
- TCP:
- SSH
defaults: 1m50s
no compression: 1m30s
compression: 2m30s
Update2
Here are the iperf results, with bidirectional tests (except SSH, where no return path is available)
| method | result (Mb/s)|
|------------------+--------------|
| ssh | 91.1 / N.A |
| vpn blowfish udp | 43 / 11 |
| vpn blowfish tcp | 13 / 12 |
| vpn AES udp | 36 / 4 |
| vpn AES tcp | 12 / 5 |
Technical specs
I'm running CentOS 6.3 (server), CentOS 6.5 (client).
OpenVPN version is 2.3.2 (same as in Ubuntu 14.10, so no moldy version there)
My SSH tunnelling looks like:
ssh -f XXXX@XXXX -i XXXX -L 12345:127.0.0.1:12345 -N
My configuration file looks like:
server
port 1194
proto udp
dev tun0
topology subnet
log /var/log/openvpn.log
ca XXXX
cert XXXX
key XXXX
dh XXXX
crl-verify XXXX
cipher AES-256-CBC
server XXXX 255.255.255.0
ifconfig-pool-persist /etc/openvpn/ipp.txt
keepalive 10 120
comp-lzo
status /var/log/openvpn-status.log
verb 3
tun-mtu 1500
fragment 1300
persist-key
persist-tun
client
client
remote XXXX 1194
proto udp
dev tun
log /var/log/openvpn.log
comp-lzo
cipher AES-256-CBC
ns-cert-type server
# the full paths to your server keys and certs
ca XXXX
cert XXXX
key XXXX
tun-mtu 1500 # Device MTU
fragment 1300 # Internal fragmentation
persist-key
persist-tun
nobind
Thanks to kasperd's comment, I learnt that SSH doesn't suffer from TCP-over-TCP since it only moves packet data.
I wrote a blog post about it, but the most interesting thing is the netstat
output, proving that SSH indeed doesn't preserve Layer 3,4 data:
after tunneling, before connecting
backslasher@client$ netstat -nap | grep -P '(ssh|redis)'
...
tcp 0 0 127.0.0.1:20000 0.0.0.0:* LISTEN 20879/ssh
tcp 0 0 10.105.16.225:53142 <SERVER IP>:22 ESTABLISHED 20879/ssh
...
backslasher@server$ netstat -nap | grep -P '(ssh|redis)'
...
tcp 0 0 0.0.0.0:6379 0.0.0.0:* LISTEN 54328/redis-server
tcp 0 0 <SERVER IP>:22 <CLIENT IP>:53142 ESTABLISHED 53692/sshd
...
after tunneling and connecting
backslasher@client$ netstat -nap | grep -P '(ssh|redis)'
...
tcp 0 0 127.0.0.1:20000 0.0.0.0:* LISTEN 20879/ssh
tcp 0 0 127.0.0.1:20000 127.0.0.1:53142 ESTABLISHED 20879/ssh
tcp 0 0 127.0.0.1:53142 127.0.0.1:20000 ESTABLISHED 21692/redis-cli
...
backslasher@server$ netstat -nap | grep -P '(ssh|redis)'
...
tcp 0 0 0.0.0.0:6379 0.0.0.0:* LISTEN 54328/redis-server
tcp 0 0 127.0.0.1:6379 127.0.0.1:42680 ESTABLISHED 54328/redis-server
tcp 0 0 127.0.0.1:42680 127.0.0.1:6379 ESTABLISHED 54333/sshd
tcp 0 0 <SERVER IP>:22 <CLIENT IP>:53142 ESTABLISHED 52889/sshd
...
So I'm going to use SSH tunneling, since it seems that my OpenVPN isn't misconfigured or anything, just not the right tool for the job.
It depends what you are trying to achieve and what your priorities are. VPN connects you to a network and SSH to a machine. VPN is a bit more secure with the encapsulation, which SSH does not do.
Also, VPN allows all the traffic to easily go through it, versus SSH where you will have to force the applications.
Are you going to use AD at all? Because VPN will let you do that with much more ease.
I prefer SSH for speedy necessities and VPN for critical applications where I should spare the extra time.
Depending on the situation, I have used SSH in a VPN in case the VPN was compromised. This way someone probing would have to get through the SSH tunneling.