OpenVPN on Windows notes
------------------------

This is a BETA release.  Please report any bugs
to openvpn-users AT lists DOT sourceforge DOT net
(you don't need to subscribe in order to post).

As of 1.5-beta3, OpenVPN runs on Win 2000
and XP.  OpenVPN also runs on Linux, Mac OS X,
Solaris, FreeBSD, NetBSD, and OpenBSD, making it
one of the most portable VPN packages today.

What's new in 1.5-beta3
-----------------------

Ease of installation has been dramatically improved
with the development a real windows
installer/uninstaller using the Nullsoft Install System.

The OpenVPN Windows distribution is now packaged as a
self-installing EXE which will automatically
install/upgrade OpenVPN, OpenSSL components,
and the TAP-Win32 driver.

You can now create multiple TAP-Win32 adapter instances,
to allow several VPN tunnels to run concurrently
(See OpenVPN Start Menu shortcuts).

How to Install
--------------

Download and Unzip the most recent OpenVPN-Win32 beta
which can be found in:

http://prdownloads.sourceforge.net/openvpn/

Choose the most recent self-installing distribution
with an .exe extension.

You can also download a source-only distribution by
selecting a .zip or .tar.gz file.

If you are upgrading from 1.5-beta2 or earlier,
you might want to uninstall the TAP
device using the device manager (Control Panel ->
System -> Hardware), reboot, then reinstall
from the self-installing exe to be sure that
all remnants of the previous driver installation
are removed from your system.  Going forward,
the new installer is designed to make upgrading
OpenVPN and the TAP-Win32 driver as automatic
as possible.

Configure the TAP-Win32 adapter
-----------------------------

On XP Go to Start -> Control Panel -> Network Connections.

On Win2K, go to Start -> Settings -> Control Panel ->
Network (and Dial-up) Connections.

You should see a "TAP-Win32 Adapter" with a name like
"Local Area Connection 3".  Right click and rename
this to something shorter and without embedded spaces
such as "my-tap".

Now right click again and select properties.

Select Internet Protocol (TCP/IP) from the list
and click on Properties.

Set the IP address and subnet mask of your
new TAP device.  For the example below we
will use an IP of 10.3.0.1 and a subnet mask
of 255.255.255.0.  Other fields can be left
as they are.

Note also that the command line tool
netsh can do many of these same functions.

Check that OpenVPN sees the adapter
-----------------------------------

Type:
  openvpn --show-adapters

You should see a list that looks like this:

Available TAP-Win32 devices:
[1] 'my-tap'

You can list all network interfaces with the
Windows "ipconfig" command, and all TAP-Win32
interfaces should be included among them.

Windows and TAP device naming
-----------------------------

One change in usage between running on Windows vs.
the Posix world is the lack of an "ifconfig" command on
Windows.  Basically what happens when you install the
TAP-Win32 driver is that you get a new network adapter
that shows up in your network control panel.  You right
click on the TAP adapter and set the TCP/IP properties,
i.e. IP address and netmask.  Then you rename the TAP
adapter icon to something like "my-tap" and reference
it using the --dev-node option in OpenVPN.

To a certain extent, the devcon, netsh, and ipconfig
command-line utilities on Windows replicate the
functionality of the ifconfig command.

Example running a VPN between Windows and Linux
-----------------------------------------------

First generate a static key:

  openvpn --genkey --secret key

Copy this key to your linux system via a secure medium.

Now generate config files for the windows
and linux sides:

on the windows create a file openvpn-config :

  remote [my-linux-box]
  dev tap
  dev-node my-tap
  secret key
  verb 3
  mute 20

on linux create a file openvpn-config :

  remote [my-windows-box]
  dev tap
  up ./tap.up
  secret key
  verb 3

on linux also create a file tap.up and do a chmod +x on it:

#!/bin/bash
ifconfig $1 10.3.0.2 netmask 255.255.255.0 mtu $2

Note: if the linux side is running 1.4.x or earlier, add these
lines to the linux configuration:

  tun-mtu 1500
  tun-mtu-extra 64

They are now the default on 1.5 when --dev tap is used.

Make sure that both boxes can talk to each other
over UDP port 5000.  Also make sure that the linux
side has a firewall rule like this to let IP traffic
come in from the TAP adapter:

iptables -A INPUT -i tap+ -j ACCEPT

Now the moment of truth... Type:

 openvpn --config openvpn-config

On both windows and linux boxes.

If everything worked correctly you will now have a
point-to-point VPN connecting the two boxes.

On Windows, you can ping the Linux box through
the VPN with:

  ping 10.3.0.2

On Linux, you can ping the Windows box through
the VPN with:

  ping 10.3.0.1

Notes -- Driver Stability
-------------------------

The stability of the TAP-Win32 driver is obviously of
great concern since any crash by a driver will also
crash the entire system, producing the infamous blue screen
of death (BSOD).

Between 1.5-beta1 and 1.5-beta2, significant stability
improvements have been made in the driver, and it now passes
the Windows Driver Verifier when running in its most
rigourous verification mode.  The 1.5-beta1 driver had
problems crashing on sleep/resume and I believe these
bugs have been fixed in 1.5-beta2 and higher.

Notes -- Ethernet bridging
--------------------------

Ethernet bridging is a powerful networking capability
that allows remote systems (such as "Road Warriors")
to connect over a VPN to an ethernet LAN in such a way
that their system appears to be directly connected to
the LAN, i.e. they have an IP address taken right from
the LAN's subnet and they are able to interact with other
hosts on the LAN including sending and receiving broadcasts
and being able to conveniently browse and access the
Windows network neighborhood.

I have tested ethernet bridging with Windows clients connecting
to a Linux server.  On the linux side, basically follow the
instructions in the Ethernet bridging Mini-Howto on the
OpenVPN web site.

On the Windows side, change the IP address and subnet mask
of the TAP-Win32 adapter to a combination which would be valid
if the Windows client were directly connected to the remote
ethernet LAN which is being bridged.  Basically, just choose
a free IP address on the remote ethernet subnet and use it, also
copying exactly the subnet mask.

On the Linux side you must first set up ethernet bridging.  Here
is a configuration which I use:

#!/bin/bash

modprobe tun
modprobe bridge

openvpn --mktun --dev tap0
openvpn --mktun --dev tap1

brctl addbr br0
brctl addif br0 eth1
brctl addif br0 tap0
brctl addif br0 tap1

ifconfig tap0 0.0.0.0 promisc up
ifconfig tap1 0.0.0.0 promisc up
ifconfig eth1 0.0.0.0 promisc up

ifconfig br0 10.5.0.1 netmask 255.255.255.0 broadcast 10.5.0.255

# end of script

This script will set up ethernet bridging between eth1,
tap0, and tap1.  Change the br0 ifconfig to match the ifconfig
that would be used for eth1 under normal, non-bridged
configuration.  Use as many tapX virtual adapters as you will
have remote clients connecting.

In the firewall, add these entries to allow TAP devices
and ethernet bridges to operate:

iptables -A INPUT -i tap+ -j ACCEPT
iptables -A INPUT -i br0 -j ACCEPT
iptables -A FORWARD -i br0 -j ACCEPT

Now make an OpenVPN configuration on the server side to receive
incoming connections such as:

###################################
# OpenVPN bridge config, Linux side

local [public IP address or hostname]

# IP settings
port 8888
dev tap0

# crypto config
secret key.txt

# restart control
persist-key
persist-tun
ping-timer-rem
ping-restart 60
ping 10

# compression
comp-lzo

# UID
user nobody
group nobody

# verbosity
verb 3

# end of config
###################################

For additional clients, copy the configuration
above, but use a different port number, tapX
unit number, and secret key.

Now on the windows client side:

############################################
# OpenVPN bridge config, windows client side

remote [public IP address or hostname of server]
port 8888
dev tap
dev-node my-tap
secret key.txt
ping 10
comp-lzo
verb 3

# end of config
###################################

The windows client should have a TAP-Win32 adapter
named "my-tap" (you can name it by going to the
Network Control Panel), which should be set to an IP
address on the Linux server's subnet, for example
10.5.0.5 (if it is available) and an identical
subnet mask of 255.255.255.0.  It may also be
possible to have windows get an address automatically
from a DHCP server running on the Linux box, but
I have not tested this yet.

Now run OpenVPN on both sides with the appropriate
configuration file, using the --config option.

On the Linux side, you probably want to run as a daemon,
so include --daemon and --cd [dir], where dir is
the directory that contains the key file.

If everything worked correctly, the Linux server or
any host on its subnet should be able to ping
10.5.0.5 and see the remote VPN connected client.

The Windows client should be able to ping any address
on the 10.5.0.x subnet, including addresses of other
remote, OpenVPN-bridged clients.

If Windows machines or Samba servers exist on the LAN
bridged by the Linux server (including Samba running on the
Linux server itself), the Windows client
should see them in its network neighborhood, and vice versa.

Furthermore, ethernet bridging allows for the transport
of all protocols which are compatible with Ethernet,
including IPv6 and IPX.

Ethernet bridging is a great way to work when on the
road, and I personally use it for securely connecting
to home or office from WiFi Internet cafes.

Notes -- Firewall on the Windows client
---------------------------------------

In general, it's a good idea to always protect
a VPN client or server with a firewall.

The important points for setting up firewalling
on a Windows system running OpenVPN are:

(1) Leave open the UDP or TCP port that OpenVPN
    is using to communicate with the remote OpenVPN
    server.
(2) Try to set up the firewall not to filter packets
    coming in on the TAP-Win32 adapter.  Once an IP
    packet appears to be "coming in" on the TAP-Win32
    adapter, it has already been decrypted and
    authenticated by OpenVPN.

Notes -- Media Status
---------------------

1.5-beta2 of the driver has the Media Status patch.
This patch shows the TAP-Win32 adapter as being
"unplugged" whenever OpenVPN is not running.

Notes -- Error message from OpenVPN
-----------------------------------

OpenVPN can be on the chatty side when it comes
to error messages, and sleep-resume activity often
produces a flurry of non-fatal messages.  Most of
these messages can be safely ignored and are provided
for informational and debugging purposes only.

To suppress repeating messages, the --mute option
can be used.  For example --mute 10 will print
no more than 10 consecutive messages in the same
error class.  To suppress all error messages
except those that are fatal, use --verb 0.

Notes -- ARP/MAC Issues with the TAP-Win32 driver
-------------------------------------------------

Most TAP drivers allocate a random MAC to their virtual NIC.
If OpenVPN running on Windows disconnects and reconnects to
a remote peer, it is possible that that peer will reinitialize
its TAP device and generate a new random MAC, causing Windows to
temporarily lose access to the IP addresses exported by that
remote peer.  This is because Windows doesn't know that a given
IP address on the virtual TAP network now is associated with a
new MAC, so it tries to send packets to the old MAC, causing
them to be dropped.

Luckily, there is an easy solution to this problem.
Create a batch file with one or more of the following commands:

  arp -d [ip-address]

Where ip-address is a remote IP address at the other end of the
virtual TAP network whose access was lost due to an OpenVPN
restart.  The arp -d command will cause Windows
to "forget" the MAC address which it previously associated with
the given IP address.  Next time that IP address is used,
Windows will actively query the remote peer
(with an "arp who-has" message) to get the new MAC address.

You can also use 

  arp -d *

to purge all MAC addresses from the cache.

You can use the --up option in OpenVPN to automatically run a
given batch file immediately after TAP device initialization --
such a batch file can contain arp commands as described above.

Notes -- Limitations
--------------------

The following features which are normally available in the
Posix version of OpenVPN are either missing or implemented
differently in the Windows version as of 1.5-beta3.

(1) --daemon doesn't work yet, so each OpenVPN instance must
    run in a command prompt window.  At some point in the
    future I plan to implement a real windows installer
    and implement OpenVPN as a system-tray applet.

(2) Only TAP virtual devices are supported on Windows, not
    TUN devices.

(3) --shaper doesn't work yet due to the lack of a
    gettimeofday library function.  This is not difficult
    to fix and could be implemented by borrowing some code
    from the cygwin library.

(4) Windows doesn't support Posix signals directly, however
    keyboard shortcuts have been set up for the current
    windows beta to simulate signals using the following
    mapping: F1:USR1 F2:USR2 F3:HUP F4:TERM -- this is an
    interim measure that will need to suffice until the
    system-tray applet is implemented.

(5) The TAP-Win32 adapter MTU cannot be explicitly set
    by OpenVPN.  Right now the MTU is hardcoded to
    1500 to allow for seamless ethernet bridging.  In
    1.5 and above, --tun-mtu is set to 1500 and
    --tun-mtu-extra to 64 by default.

Notes -- Differences between TAP-Win32 driver and CIPE driver
-------------------------------------------------------------

The TAP-Win32 driver distributed with OpenVPN 1.5-beta2 and
later is derived from Cipe-Win32 2.0-pre15 with some
significant changes:

(1) Stability is much improved, especially with sleep/resume,
    using Michael Clarke's patch which upgrades the driver
    to NDIS5, properly implements sleep/resume OIDs, and fixes
    a race condition between AdapterTransmit and IRP_MJ_READ.

(2) Added Christof Meerwald's "Media Status" patch which shows
    a given TAP-Win32 adapter as being "unplugged" when it is
    not currently open by an OpenVPN instance.

(3) Modified the MAC generation code to follow the Linux
    algorithm for generating MACs, using 0:FF:XX:XX:XX:XX
    where XX:XX:XX:XX is random.

(4) Added code to lock the TAP device so that only one
    OpenVPN instance can have it open at a time.

(5) Ran the driver through the windows driver verifier
    with all testing modes enabled, including low-resource
    simulation mode.  Based on the resulting bug checks,
    I was able to fix a number
    of problems including using MmGetSystemAddressForMdlSafe
    instead of MmGetSystemAddressForMdl, fixing several places
    in the code where the return status of
    NdisAllocateMemory is not checked, and making the flags
    match between NdisAllocateMemory and NdisFreeMemory calls.

(6) Renamed the driver so that it shows up as a "TAP-Win32" adapter
    in the network control panel, and does not conflict with the
    CIPE driver.

(7) To a certain extent, backwards compatibility with NT 4 has
    been sacrificed in the interest of better portability and
    stability on Win2K/XP.

Notes -- Building from source
-----------------------------

This section is for developers only.

You will need the following:

(1) MinGW/MSYS environment
    http://mingw.sourceforge.net/

(2) OpenSSL library
    http://www.openssl.org/

(3) LZO library
    http://www.oberhumer.com/opensource/lzo/

(4) Windows DDK (available only from Microsoft)
    http://www.microsoft.com/whdc/ddk/winddk.mspx

(5) Nullsoft Install System (optional)
    http://www.nullsoft.com/free/nsis/

It should be noted that Visual C++ is NOT required.
The open-source MinGW compiler is used to build the
userspace component of OpenVPN, and the DDK is used
to build the driver component.

First build the usermode component of OpenVPN
from the top-level directory of the OpenVPN
source distribution:

Edit makefile.32 with the location of
your OpenSSL and LZO distributions.  Note that
it is only necessary to build these distributions,
not to install them.

Note that the makefile accepts a 'dynamic'
or 'static' target, depending on the way
you want to link with the OpenSSL library.

By default the makefile will attempt to
dynamically link with OpenSSL.

Type:
  make -f makefile.w32

This will build the user mode component of OpenVPN.

Now build the TAP-Win32 kernel driver:

Go to Start -> All Programs -> Development Kits -> Windows DDK
  -> Build Environments -> Win Free Build Environment

Use the Checked Build Environment if you want a debugging version.

A command prompt window will open.  Go to the tap-win32 directory
of the OpenVPN distribution.

Type:
  build -cef

This will build the kernel driver in the i386 directory.

At this point you will have built:

.\openvpn.exe -- openvpn daemon
.\tap-win32\i386\tapdrvr.sys -- TAP-Win32 kernel driver

Copy openvpn.exe to a directory in your path.
If you build dynamically with OpenSSL, copy the OpenSSL
DLLs to a directory in your path.

If you want to build a self-installing EXE, consult
the NSIS install script (openvpn.nsi) in the
install-win32 directory.  You will need to edit
openvpn.nsi to reflect the setup of your
development environment.

See instructions below for installing the kernel driver.

Notes -- Manual Install/Update/Uninstall of the TAP-Win32 kernel driver
-----------------------------------------------------------------------

This is best done using devcon.exe, a DDK sample which is distributed
with the self-installing form of OpenVPN on Windows.  Cd to the
directory which contains OemWin2k.inf and tapdrvr.sys.

To install:
  devcon install OemWin2k.inf TAP

To update:
  devcon update OemWin2k.inf TAP

To uninstall:
  devcon remove TAP

By installing multiple times, you will create
additional TAP-Win32 adapter instances, which can
be used for multiple concurrent VPN tunnels.

It is also possible to install using Control Panel ->
Add New Hardware, and it is possible to uninstall
using Control Panel -> System -> Hardware -> Device
Manager.

Notes -- OpenVPN Performance Benchmarks
---------------------------------------

All tests with OpenVPN 1.5-beta2 on systems
locally connected to a 100Mbps LAN using
UDP tunnel transport, TAP devices
with an MTU of 1500, and no compression.

[---------------------]
[     TEST #1         ]
[---------------------]

Linux 2.4.21 P2 266Mhz <-> Linux 2.4.21 P4 2.4Ghz

OpenVPN Blowfish tunnel
-----------------------

FTP get on 266Mhz

 33128460 bytes received in 23.1 secs (1.4e+03 Kbytes/sec)
 33128460 bytes received in 25.7 secs (1.3e+03 Kbytes/sec)

FTP send on 266MHz

 33128460 bytes sent in 16.9 secs (1.9e+03 Kbytes/sec)
 33128460 bytes sent in 15.8 secs (2e+03 Kbytes/sec)

OpenVPN plaintext tunnel
------------------------

FTP get on 266Mhz

 33128460 bytes received in 9.75 secs (3.3e+03 Kbytes/sec)
 33128460 bytes received in 9.65 secs (3.4e+03 Kbytes/sec)

FTP send on 266MHz

 33128460 bytes sent in 8.21 secs (3.9e+03 Kbytes/sec)
 33128460 bytes sent in 9.65 secs (3.4e+03 Kbytes/sec)

Direct FTP without OpenVPN
--------------------------

FTP get on 266Mhz

 33128460 bytes received in 4.73 secs (6.8e+03 Kbytes/sec)
 33128460 bytes received in 4.75 secs (6.8e+03 Kbytes/sec)

FTP send on 266MHz

 33128460 bytes sent in 4 secs (8.1e+03 Kbytes/sec)
 33128460 bytes sent in 3.93 secs (8.2e+03 Kbytes/sec)

[---------------------]
[     TEST #2         ]
[---------------------]

Linux 2.4.21 P2 266Mhz <-> Win XP SP1 P4 2.2 Ghz

OpenVPN Blowfish tunnel
-----------------------

FTP get on Win XP

 33128460 bytes received in 19.14Seconds 1731.03Kbytes/sec.
 33128460 bytes received in 19.11Seconds 1733.84Kbytes/sec.

FTP send on Win XP

 33128460 bytes sent in 23.46Seconds 1411.94Kbytes/sec.
 33128460 bytes sent in 23.44Seconds 1413.09Kbytes/sec.

OpenVPN plaintext tunnel
------------------------

FTP get on Win XP

 33128460 bytes received in 11.31Seconds 2930.17Kbytes/sec.
 33128460 bytes received in 11.89Seconds 2786.95Kbytes/sec.

FTP send on Win XP

 33128460 bytes sent in 11.72Seconds 2827.38Kbytes/sec.
 33128460 bytes sent in 10.71Seconds 3094.67Kbytes/sec.

Direct FTP without OpenVPN
--------------------------

FTP get on Win XP

 33128460 bytes received in 5.55Seconds 5971.24Kbytes/sec
 33128460 bytes received in 5.39Seconds 6148.56Kbytes/sec

FTP send on Win XP

 33128460 bytes sent in 4.90Seconds 6765.05Kbytes/sec
 33128460 bytes sent in 4.91Seconds 6751.27Kbytes/sec
