# Access private virtual machine network with OpenVPN

## onkelfusspilz

Hi folks,

I have a server with a single IP address and a virtual machine running on it using libvirt/kvm.

I want to create a virtual network on the server (with a local address like 192.168.100.0/24 for example) and connect the virtual machine to it.

Then I want to dial in from an external machine over the internet with OpenVPN and connect to this virtual network so that I can access the virtual machine. I don't want to expose the IP of the VM to the internet and only use it over a VPN.

Can someone tell me what steps I need to work on for archiving this or point me to a howto for a setup like this?

Thank you very much!

Andreas

----------

## Hu

It looks to me like your description of what you want is a good guide for what you should do.  First, ignore that a VM exists.  Just get OpenVPN working between the host machine and the remote machine.  Once that works, get OpenVPN routing working so that the remote machine can access other resources on the local network.  As a side effect of making this work, you will gain connectivity to the VM.

----------

## onkelfusspilz

Hi Hu,

thank you for your response.

The network which has been created with virtmanager has a bridge with the interface of my virtual machine added to it:

```
# brctl show

bridge name   bridge id      STP enabled   interfaces

virbr1      8000.525400a7f42c   yes      virbr1-nic

                                     vnet0
```

I can use this network in my guest and I have access to the outside world since the bridge is natted to my eth0.

I have OpenVPN running and I can connect from outside. I noticed that I should setup a tap based configuration instead of a tun config which I am used to from other installations.

Currently my openvpn.conf looks like this:

```
dev tap

proto udp

port 1194

dev-node /dev/net/tun

server-bridge 192.168.100.1 255.255.255.0 192.168.100.10 192.168.100.20

push "route 192.168.100.0 255.255.255.0"

mode server

dh /etc/openvpn/ssl/keys/dh1024.pem

ca /etc/openvpn/ssl/keys/ca.crt

cert /etc/openvpn/ssl/keys/server.crt

key /etc/openvpn/ssl/keys/server.key

user nobody

group nogroup

status /var/log/openvpn/vpn-status.log

log /var/log/openvpn/vpn.log

comp-lzo

verb 3
```

I have created the tap dev via

```
openvpn --mktun --dev tap0
```

and added it to the bridge via

```
brctl addif virbr1 tap0
```

so that brctl show tells me

```
# brctl show

bridge name   bridge id      STP enabled   interfaces

virbr1      8000.525400a7f42c   yes      tap0

                                     virbr1-nic

                                     vnet0
```

When I connect from outside, I get the IP 192.168.100.10 assigned which is in the same subnet as my guest. But I can't access / ping the guest.

Any hints on this?

----------

## Hu

That configuration seems a bit strange.  Why are you using a bridge here?

----------

## onkelfusspilz

 *Hu wrote:*   

> That configuration seems a bit strange.  Why are you using a bridge here?

 

Libvirt / virt-manager creates a bridge for nat networking per default. I want to dial in and get access to the network / bridge. So it made sense to me to add the VPN dev to this existing bridge.

What else should I use?

----------

## Hu

Bridging and NAT are two different ways to achieve connectivity.  Mixing them can work if you know what you are doing, but it adds needless complexity otherwise.  I would undo the bridge, configure the host to NAT the guest, and then configure the host to NAT incoming OpenVPN traffic.  At that point, there should be no logical difference between traffic coming in off the physical LAN, traffic coming in off the OpenVPN virtual NIC, and traffic coming in off the Qemu TAP NIC.

----------

## onkelfusspilz

 *Hu wrote:*   

> Bridging and NAT are two different ways to achieve connectivity.  Mixing them can work if you know what you are doing, but it adds needless complexity otherwise.  I would undo the bridge, configure the host to NAT the guest, and then configure the host to NAT incoming OpenVPN traffic.  At that point, there should be no logical difference between traffic coming in off the physical LAN, traffic coming in off the OpenVPN virtual NIC, and traffic coming in off the Qemu TAP NIC.

 

So you say I should assign a tap-device directly to the guest machine, no bridging involved, right? So I can create another tap device like I did for OpenVPN?

Then I enable masquerading and forwarding with iptables between the tap devices of OpenVPN and my guest machine? For me this sounds strange because I'm only used to masquerade the network behind a NIC to another one (for instance the network on a lan port to a ppp device) and not a nic to another nic which should share a logical network. Can you provide a specific example to me, since I'm honestly not clear about this.

Thank you again!

----------

## Hu

Yes, remove the bridge.  There is no need to NAT the connections between OpenVPN and guest if the OpenVPN and guest receive addresses on separate subnets and neither subnet shadows a routable subnet.

----------

## jamapii

I'm not sure if this solution can work. If it works, disregard the following.

When I started with qemu, to get any networking (not considering qemu's user mode networking), I had to have a bridge interface. This does not imply "bridged networking" (as seen from a VM connectivity context), but the bridge interface is just the Linux tool to implement VM connectivity.

Here's how I see it...

There are common standard options for VM connectivity, these are "Host-only networking" (a group of VMs and possibly the host in an isolated network), "NAT" (VMs may access the outside behind the NAT), and "bridged" (the VM gets its own public IP address on the same network as the host).

Every VM software implements its own approaches for these things. qemu can do "user mode networking", tap, and a few other options.

User mode networking is done entirely inside qemu and requires no root access. There is probably a way to connect this to openvpn, but I don't know about it.

tap networking works by connecting each VM instance to a tap interface. When I tried, I could not connect more than 1 VM to any tap interface, as I remember I couldn't even reuse any tap interface later. But there are

scripts in /etc/qemu (at least when I started), that create a br0 (or other bridge) interface on demand and a new tap interface for each VM when it starts. The tap interface is connected to the bridge.

If all the VMs' tap interfaces are connected to a bridge, that is "Host-only networking". You can have multiple bridges for multiple separate networks. You can, as an option, add the host itself, by giving it an IP address on the bridge, in /etc/conf.d/net: config_br0=10.x.y.z/24. This network only exists inside the host.

With the following modification in /etc/conf.d/net, it becomes "NAT networking" (this code may be buggy):

```

postup() {

  [ $IFVAR = br0 ] && iptables -t nat -A POSTROUTING ! -o br0 -j MASQUERADE -s 10.x.y/24

}

```

(add your own postdown with -D instead of -A) This NAT is done entirely with Linux, qemu does nothing here.

With another modification, "Host-only networking" becomes "Bridged networking". Add the host's physical network interface (let's call it eth0 here) to the bridge (read the example for /etc/conf.d/net, but sorry i don't know where it is today). Don't use 10.x.y.z as mentioned above, but change the config_eth0 line to refer to config_br0 instead (and all the other *_eth0 lines). Then be aware that all VMs use the same dhcp server as the * host, or must get IP addresses from the host's network.

To add openvpn to any of these, it must be in "tap" mode, and its tap interface must be added to the bridge. Correction: There is no need to bridge openvpn to the VM network. openvpn can use its own network and the host can route between the 2. Then openvpn can use "tun" mode. The decision whether to use NAT is independent of this.

I don't know how to add openvpn in "tun" mode, maybe there is a way, but not with this setup centered around the bridge.

I can't understand how Hu's suggestion can work. If the VM is NATted to the outside, and the openvpn network is NATted to the outside, sure their networking is equivalent, but they dont connect to each other. The (to me) obvious solution is to add both to some kind of bridge.

There is also vde. I dont use it.

----------

