2011-11-14

Setting up an encrypted iodine tunnel on OpenBSD and Windows

I was never completely convinced that TCP-over-DNS was anything more than a lark. Upon an old recommendation from a former coworker, I finally took a look today at iodine. iodine has average-quality documentation, but the code is portable. What this means is that I can compile it on an OpenBSD box and figure it out on my own.

Notes for getting this set up:

  1. Fetch the tarball and build it on your SSH server. I put it under /usr/local/iodined/bin for no real reason.
  2. Make a new group, "iodine".
  3. Make two new users, "_iodined" and "_iodinelog".
  4. Make a new directory, /usr/local/iodined/env. Create files with correct values for:
    • echo _iodined > /usr/local/iodined/env/USER
    • echo 192.168.0.53 > /usr/local/iodined/env/IP
    • echo 3IGnrin7 > /usr/local/iodined/env/PASSWORD
    • echo 172.16.0.1 > /usr/local/iodined/env/TUNNELIP
    • echo tunnel.domain.dom > /usr/local/iodined/env/DOMAIN

    "USER" is the name of the user account that iodine will run under after dropping privileges. "IP" is the listening IP address upon which the iodine server will run on port 53/udp. "PASSWORD" is a shared password that any clients that use the tunnel must know. "TUNNELIP" is the IP of the server that will be used by any tunnel connections. It must be a different network than your normal network. If you use 10.0.0.0/24 for your internal network, use 192.168.0.1. If you use 192.168.0.0/16, use 10.0.0.1. If you use both, use 172.16.0.1. If you use all of the major RFC-1918 networks, you're on your own. "DOMAIN" is a specific subdomain that you have chosen to use to distinguish your tunnel traffic.

  5. Make a new /usr/local/iodined/run:
    #!/bin/sh
    exec 2>&1
    exec envdir ./env sh -c '
      exec ./bin/iodined -DD -u $USER -t /service/iodined -f -l $IP -P $PASSWORD $TUNNELIP $DOMAIN
    '
  6. Make a new /usr/local/iodined/log/run:
    #!/bin/sh
    exec setuidgid _iodinelog multilog t ./main
  7. ln -sf /usr/local/iodined /service
  8. Install the OpenVPN TAP driver on your Windows client.
  9. Fetch the iodine Win32 binaries to your Windows client.
  10. In an elevated command prompt: iodine.exe -f -P <password> -I 999 <ip> <domain>.

    The values for <password>, <ip>, and <domain> must match the same values used in the ./run file.

  11. Add this to your SSH server's /etc/pf.conf:

    pass in quick on <if0> inet proto tcp from <tunnelip> to any port 22 rdr-to <sship>

    <if0> is the interface of your iodine server, <tunnelip> is the tunnel IP address of the iodine server, and <sship> is the IP that's running sshd.

  12. Run pfctl -f /etc/pf.conf.
  13. Set up your SSH SOCKS proxy: ssh -2vTND <clienttunnelip>:9050 <user>@<tunnelip>

    <clienttunnelip> is the IP address assigned to your client by the iodine server. <user> is your SSH server's user account. <tunnelip> is the tunnel IP address of the iodine server.

  14. Put this line in your Privoxy config.txt:

    forward-socks5 / <clienttunnelip>:9050 .

  15. Restart Privoxy.
  16. Profit!

I haven't gotten this working as an inline DNS proxy that can redirect non-tunnel traffic to a real authoritative DNS service, which is kind of the whole point, but at least I've gotten basic end-to-end validation that an SSH SOCKS proxy over a TCP-over-DNS proxy is functional. Which is nice.

No comments: