OpenVPN over Iodine (TCP-over-DNS tunnel)

This forum is for admins who are looking to build or expand their OpenVPN setup.
Forum rules
Please use the [oconf] BB tag for openvpn Configurations. See viewtopic.php?f=30&t=21589 for an example.
Post Reply
MatejKovacic
OpenVPN User
Posts: 30
Joined: Wed Jun 19, 2013 9:43 am

OpenVPN over Iodine (TCP-over-DNS tunnel)

Post by MatejKovacic » Mon Nov 06, 2017 7:34 pm

Iodine is a nice software which creates TCP tunnel over DNS.

On my server (Debian 9) I have installed it like this:

Code: Select all

sudo apt install iodine
sudo nano /etc/default/iodine
And write:

Code: Select all

# Default settings for iodine. This file is sourced from
# /etc/init.d/iodined
START_IODINED="true"
# -l <IP address> specifies on which address Iodine listens
# I am running Dnsmasq, but dnsmasq is listening on tun0 device only. Outside IP is used by Iodine.
IODINED_ARGS="-l 12.34.56.78 10.0.1.1 -c iodine.myserver.com"
IODINED_PASSWORD="mypassword"
Now we run Iodine service:

Code: Select all

sudo systemctl unmask iodined.service
sudo systemctl enable iodined.service
When Iodine started, we have a new network device called dns0 with IP 10.0.1.1 (as specified in Iodined config).

I am also running OpenVPN. My config is:

Code: Select all

mode server
tls-server
local 10.0.1.1
proto tcp4
port 443
port-share 127.0.0.1 4443
dev tun
ca /etc/openvpn/serverkeys/ca.crt
cert /etc/openvpn/serverkeys/myvpn.crt
key /etc/openvpn/serverkeys/myvpn.key
dh /etc/openvpn/serverkeys/dh4096.pem
crl-verify /etc/openvpn/serverkeys/crl.pem
tls-auth /etc/openvpn/serverkeys/ta.key 0
tls-version-min 1.2
remote-cert-tls client
tls-cipher TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-256-GCM-SHA384
auth SHA256
cipher AES-256-CBC
server 10.10.8.0 255.255.255.0
persist-key
persist-tun
topology subnet
push "topology subnet"
push "redirect-gateway def1"
push "route 10.10.9.0 255.255.255.0"
client-to-client
push "dhcp-option DNS 10.10.8.1"
mtu-disc maybe
user nobody
group nogroup
client-config-dir /etc/openvpn/ccd_tcp
keepalive 10 120
verb 1
status /var/log/openvpn/status_iodine.log
log /var/log/openvpn/openvpn_iodine.log
log-append /var/log/openvpn/openvpn_iodine.log
mute 20
Now this is the server part.

Let's go to the client now.

First, I start Iodine client:

Code: Select all

sudo iodine -f -P mypassword iodine.myserver.com
I get quite long listing:

Code: Select all

Opened dns0
Opened IPv4 UDP socket
Sending DNS queries for iodine.myserver.com to 127.0.0.53
Autodetecting DNS query type (use -T to override).iodine: Got NOTIMP as reply: server does not support our request
...
Connection setup complete, transmitting data.
iodine: Hmm, getting some out-of-sequence DNS replies. Setting interval to 1 (use -I1 next time on this network). If data traffic still has large hiccups, try if -L0 works better.
Of course, I also have dns network device on my client (Ubuntu):

Code: Select all

dns0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST>  mtu 1130
        inet 10.0.1.2  netmask 255.255.255.224  destination 10.0.1.2
        unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 500  (UNSPEC)
        RX packets 107  bytes 55122 (55.1 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 124  bytes 41676 (41.6 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
Now I try to connect to VPN. Client config is the following:

Code: Select all

client
remote 10.0.1.1 443
proto tcp
dev tun
mute-replay-warnings
tls-version-min 1.2
remote-cert-tls server
<ca>
...
</ca>
<cert>
...
</cert>
<key>
...
</key>
<tls-auth>
...
</tls-auth>
key-direction 1
auth SHA256
cipher AES-256-CBC
auth-nocache
script-security 2
up /etc/openvpn/update-resolv-conf
down /etc/openvpn/update-resolv-conf
ping 10
ping-restart 60
verb 4
mute 20
So I run it:

Code: Select all

openvpn --config IodineVPN.conf
...and get this:

Code: Select all

Mon Nov  6 20:02:00 2017 us=477837 Attempting to establish TCP connection with [AF_INET]10.0.1.1:443 [nonblock]
Mon Nov  6 20:02:18 2017 us=480192 TCP connection established with [AF_INET]10.0.1.1:443
Mon Nov  6 20:02:18 2017 us=480235 TCP_CLIENT link local: (not bound)
Mon Nov  6 20:02:18 2017 us=480245 TCP_CLIENT link remote: [AF_INET]10.0.1.1:443
Mon Nov  6 20:02:18 2017 us=512286 TLS: Initial packet from [AF_INET]10.0.1.1:443, sid=d65e4a18 6379d54e
Mon Nov  6 20:02:25 2017 us=72275 Validating certificate key usage
Mon Nov  6 20:02:25 2017 us=72285 ++ Certificate has key usage  00a0, expects 00a0
Mon Nov  6 20:02:25 2017 us=72293 VERIFY KU OK
Mon Nov  6 20:02:25 2017 us=72301 Validating certificate extended key usage
Mon Nov  6 20:02:25 2017 us=72308 ++ Certificate has EKU (str) TLS Web Server Authentication, expects TLS Web Server Authentication
Mon Nov  6 20:02:25 2017 us=72314 VERIFY EKU OK
...
Mon Nov  6 20:02:35 2017 us=297267 Control Channel: TLSv1.2, cipher TLSv1/SSLv3 ECDHE-RSA-AES256-GCM-SHA384, 4096 bit RSA
Mon Nov  6 20:02:35 2017 us=297324 [IodineVPN] Peer Connection Initiated with [AF_INET]10.0.1.1:443
Mon Nov  6 20:02:36 2017 us=449382 SENT CONTROL [IodineVPN]: 'PUSH_REQUEST' (status=1)
Mon Nov  6 20:02:41 2017 us=677947 SENT CONTROL [IodineVPN]: 'PUSH_REQUEST' (status=1)
Mon Nov  6 20:02:47 2017 us=101376 SENT CONTROL [IodineVPN]: 'PUSH_REQUEST' (status=1)
Mon Nov  6 20:02:52 2017 us=506578 SENT CONTROL [IodineVPN]: 'PUSH_REQUEST' (status=1)
Mon Nov  6 20:02:58 2017 us=32778 SENT CONTROL [IodineVPN]: 'PUSH_REQUEST' (status=1)
Mon Nov  6 20:03:03 2017 us=287006 SENT CONTROL [IodineVPN]: 'PUSH_REQUEST' (status=1)
Mon Nov  6 20:03:08 2017 us=648275 SENT CONTROL [IodineVPN]: 'PUSH_REQUEST' (status=1)
Mon Nov  6 20:03:14 2017 us=15972 SENT CONTROL [IodineVPN]: 'PUSH_REQUEST' (status=1)
Mon Nov  6 20:03:19 2017 us=757218 SENT CONTROL [IodineVPN]: 'PUSH_REQUEST' (status=1)
Mon Nov  6 20:03:24 2017 us=6526 SENT CONTROL [IodineVPN]: 'PUSH_REQUEST' (status=1)
Mon Nov  6 20:03:29 2017 us=15836 SENT CONTROL [IodineVPN]: 'PUSH_REQUEST' (status=1)
Mon Nov  6 20:03:34 2017 us=25045 SENT CONTROL [IodineVPN]: 'PUSH_REQUEST' (status=1)
Mon Nov  6 20:03:35 2017 us=183322 [IodineVPN] Inactivity timeout (--ping-restart), restarting
Mon Nov  6 20:03:35 2017 us=183748 TCP/UDP: Closing socket
Mon Nov  6 20:03:35 2017 us=183817 SIGUSR1[soft,ping-restart] received, process restarting
Mon Nov  6 20:03:35 2017 us=183863 Restart pause, 5 second(s)
So OpenVPN can connect, but connection gets stuck somewhere... On the other hand, I tried SSH and it is working (unfortunately with some large delays). Any idea what is wrong? Is it bandwidth problem or something else?

User avatar
TinCanTech
OpenVPN Protagonist
Posts: 3336
Joined: Fri Jun 03, 2016 1:17 pm

Re: OpenVPN over Iodine (TCP-over-DNS tunnel)

Post by TinCanTech » Mon Nov 06, 2017 8:14 pm

What does your openvpn server log say .... ? (--verb 4 .. )

MatejKovacic
OpenVPN User
Posts: 30
Joined: Wed Jun 19, 2013 9:43 am

Re: OpenVPN over Iodine (TCP-over-DNS tunnel)

Post by MatejKovacic » Tue Nov 07, 2017 8:19 pm

OK, here we go again.

I am actually running 3 OpenVPN server instances on a server:
- first is listening on TCP/443 (and has port sharing enabled) - tun0, IP range 10.10.8.1/24
- second is listening on TCP/8080 (and is accepting connections through websockets) - tun1, IP range 10.10.9.1/24
- third is listening on TCP/4433 (and is accepting connetions from Iodine) - tun4, IP range 10.10.10.1/24
- tun2 and tun3 are connections to two other VPN networks

So, I have Iodine connection established, dns0 device with IP address 10.0.1.1 is up and this is my OpenVPN client log:

Code: Select all

Tue Nov  7 21:00:04 2017 us=698363 /sbin/ip link set dev tun0 up mtu 1500
Tue Nov  7 21:00:04 2017 us=704629 /sbin/ip addr add dev tun0 10.10.10.2/24 broadcast 10.10.10.255
Tue Nov  7 21:00:04 2017 us=709531 /etc/openvpn/update-resolv-conf tun0 1500 1554 10.10.10.2 255.255.255.0 init
dhcp-option DNS 10.10.8.1
dhcp-option DNS 8.8.8.8
dhcp-option DNS 8.8.4.4
Tue Nov  7 21:00:18 2017 us=789255 /sbin/ip route add 10.0.1.1/32 via 192.168.190.1
Tue Nov  7 21:00:18 2017 us=791050 /sbin/ip route add 0.0.0.0/1 via 10.10.10.1
Tue Nov  7 21:00:18 2017 us=792856 /sbin/ip route add 128.0.0.0/1 via 10.10.10.1
Tue Nov  7 21:00:18 2017 us=795191 /sbin/ip route add 10.10.8.0/24 via 10.10.10.1
Tue Nov  7 21:00:18 2017 us=797314 Initialization Sequence Completed
On a server I have:

Code: Select all

Tue Nov  7 20:59:59 2017 us=391379 TCP connection established with [AF_INET]10.0.1.2:55354
Tue Nov  7 20:59:59 2017 us=391396 TCPv4_SERVER link local: (not bound)
Tue Nov  7 20:59:59 2017 us=391411 TCPv4_SERVER link remote: [AF_INET]10.0.1.2:55354
Tue Nov  7 21:00:00 2017 us=438887 10.0.1.2:55354 TLS: Initial packet from [AF_INET]10.0.1.2:55354, sid=dd92ba99 1f2a63b6
Tue Nov  7 21:00:02 2017 us=518562 10.0.1.2:55354 VERIFY OK: depth=1, ***
Tue Nov  7 21:00:02 2017 us=519084 10.0.1.2:55354 Validating certificate key usage
Tue Nov  7 21:00:02 2017 us=519101 10.0.1.2:55354 ++ Certificate has key usage  0080, expects 0080
Tue Nov  7 21:00:02 2017 us=519119 10.0.1.2:55354 VERIFY KU OK
Tue Nov  7 21:00:02 2017 us=519134 10.0.1.2:55354 Validating certificate extended key usage
Tue Nov  7 21:00:02 2017 us=519149 10.0.1.2:55354 ++ Certificate has EKU (str) TLS Web Client Authentication, expects TLS Web Client Authentication
Tue Nov  7 21:00:02 2017 us=519161 10.0.1.2:55354 VERIFY EKU OK
Tue Nov  7 21:00:02 2017 us=519174 10.0.1.2:55354 VERIFY OK: ***
Tue Nov  7 21:00:02 2017 us=807917 10.0.1.2:55354 peer info: IV_VER=2.4.0
Tue Nov  7 21:00:02 2017 us=808016 10.0.1.2:55354 peer info: IV_PLAT=linux
Tue Nov  7 21:00:02 2017 us=808039 10.0.1.2:55354 peer info: IV_PROTO=2
Tue Nov  7 21:00:02 2017 us=808053 10.0.1.2:55354 peer info: IV_NCP=2
Tue Nov  7 21:00:02 2017 us=808067 10.0.1.2:55354 peer info: IV_LZ4=1
Tue Nov  7 21:00:02 2017 us=808095 10.0.1.2:55354 peer info: IV_LZ4v2=1
Tue Nov  7 21:00:02 2017 us=808136 10.0.1.2:55354 peer info: IV_LZO=1
Tue Nov  7 21:00:02 2017 us=808155 10.0.1.2:55354 peer info: IV_COMP_STUB=1
Tue Nov  7 21:00:02 2017 us=808170 10.0.1.2:55354 peer info: IV_COMP_STUBv2=1
Tue Nov  7 21:00:02 2017 us=808183 10.0.1.2:55354 peer info: IV_TCPNL=1
Tue Nov  7 21:00:02 2017 us=927438 10.0.1.2:55354 Control Channel: TLSv1.2, cipher TLSv1/SSLv3 ECDHE-RSA-AES256-GCM-SHA384, 4096 bit RSA
Tue Nov  7 21:00:02 2017 us=927514 10.0.1.2:55354 [User1] Peer Connection Initiated with [AF_INET]10.0.1.2:55354
Tue Nov  7 21:00:02 2017 us=927609 User1/10.0.1.2:55354 MULTI_sva: pool returned IPv4=10.10.10.2, IPv6=(Not enabled)
Tue Nov  7 21:00:02 2017 us=943852 User1/10.0.1.2:55354 OPTIONS IMPORT: reading client specific options from: /tmp/openvpn_cc_29aba5d814a9674e89d008f51f804d6c.tmp
Tue Nov  7 21:00:02 2017 us=944079 User1/10.0.1.2:55354 MULTI: Learn: 10.10.10.2 -> User1/10.0.1.2:55354
Tue Nov  7 21:00:02 2017 us=944099 User1/10.0.1.2:55354 MULTI: primary virtual IP for User1/10.0.1.2:55354: 10.10.10.2
Tue Nov  7 21:00:04 2017 us=14052 User1/10.0.1.2:55354 PUSH: Received control message: 'PUSH_REQUEST'
Tue Nov  7 21:00:04 2017 us=14226 User1/10.0.1.2:55354 SENT CONTROL [User1]: 'PUSH_REPLY,topology subnet,redirect-gateway def1,route 10.10.8.0 255.255.255.0,dhcp-option DNS 10.10.8.1,dhcp-option DNS 8.8.8.8,dhcp-option DNS 8.8.4.4,route-gateway 10.10.10.1,topology subnet,ping 10,ping-restart 120,ifconfig 10.10.10.2 255.255.255.0,peer-id 0,cipher AES-256-GCM' (status=1)
Tue Nov  7 21:00:04 2017 us=14258 User1/10.0.1.2:55354 Data Channel MTU parms [ L:1551 D:1450 EF:51 EB:406 ET:0 EL:3 ]
Tue Nov  7 21:00:04 2017 us=14365 User1/10.0.1.2:55354 Data Channel Encrypt: Cipher 'AES-256-GCM' initialized with 256 bit key
Tue Nov  7 21:00:04 2017 us=14382 User1/10.0.1.2:55354 Data Channel Decrypt: Cipher 'AES-256-GCM' initialized with 256 bit key
On a client I have tun0 device with IP 10.10.10.2, but I cannot ping OpenVPN server - 10.10.10.1.

My iptables on a server:

Code: Select all

iptables -A INPUT -p tcp -s 10.0.1.1/24 --dport 4433 -j ACCEPT
...
iptables -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
# Primary VPN:
iptables -A FORWARD -i tun0 -j ACCEPT
# WebSocket VPN:
iptables -A FORWARD -i tun1 -j ACCEPT
# Iodine VPN:
iptables -A FORWARD -i tun4 -j ACCEPT

iptables -t nat -F POSTROUTING
iptables -t nat -I POSTROUTING -o ens3 -j MASQUERADE
No idea what I am doing wrong.

Anyway, if OpenVPN connection is not established, I can ping Iodine server (ping 10.0.1.1) and get website with curl -I 10.0.1.1...

I am guessing OpenVPN connection is OK, something is wrong with routing (iptables)...

Post Reply