Porting OpenVpn Client only
Moderators: TinCanTech, TinCanTech, TinCanTech, TinCanTech, TinCanTech, TinCanTech
-
- OpenVPN User
- Posts: 22
- Joined: Mon Nov 07, 2011 3:11 pm
Re: Porting OpenVpn Client only
Hi again...
I did take the polarSSL openVpn package, seems fine.
I have a question, I do not understand the routing thing here. There are mainly two scenarios:
1. Data is received from the outside. the data is passed to the application owns the socket, which in this case will be the OpenVPN client. The client decrypts the packet and send it to the TUN, which in it's turn inject the packet into the OS stack, to be passed to the application the packet is intended to.
2. Application is sending a packet. This packet needs to be routed to the TUN (right?). The openvpn client reads from the tun and hence gets this packet, encrypt it (and other security stuff), and then sends it.
How does the packet sent by the application ends up in the TUN, is there any routing rule here (from the source IP of the packet to the TUN IP)? If this is the case, how does the openvpn then write the packet after encryption avoiding the pakcte to be routed just like the packet sent by the application?
I did take the polarSSL openVpn package, seems fine.
I have a question, I do not understand the routing thing here. There are mainly two scenarios:
1. Data is received from the outside. the data is passed to the application owns the socket, which in this case will be the OpenVPN client. The client decrypts the packet and send it to the TUN, which in it's turn inject the packet into the OS stack, to be passed to the application the packet is intended to.
2. Application is sending a packet. This packet needs to be routed to the TUN (right?). The openvpn client reads from the tun and hence gets this packet, encrypt it (and other security stuff), and then sends it.
How does the packet sent by the application ends up in the TUN, is there any routing rule here (from the source IP of the packet to the TUN IP)? If this is the case, how does the openvpn then write the packet after encryption avoiding the pakcte to be routed just like the packet sent by the application?
- janjust
- Forum Team
- Posts: 2703
- Joined: Fri Aug 20, 2010 2:57 pm
- Location: Amsterdam
- Contact:
Re: Porting OpenVpn Client only
your analysis is mostly correct.
Let's say the TUN adapter has an address of 10.8.0.6 (this is the default address for the first client when using 'server 10.8.0.0 255.255.255.0' in the server config) and that the VPN server can be found at address 192.168.0.1. The IP address of the TUN adapter on the server would be 10.8.0.1 in this case.
When OpenVPN starts a direct route is created to 192.168.0.1 netmask 255.255.255.255 , to ensure that all traffic intended for the VPN server LAN IP is not sent via the tunnel.
A client that wishes to send encrypted traffic to the server itself would need to specify as the DEST address 10.8.0.1. The flow would then be
1) application sends a packet with DEST=10.8.0.1
2) kernel routes this packet to the "best" interface, being the TUN interface with address 10.8.0.6; this sets SOURCE=10.8.0.6
3) OpenVPN receives the packet, does its stuff, encrypts it and then sends it to the VPN server @ 192.168.0.1
4) the kernel picks up this packet coming from OpenVPN with DEST=192.168.0.1 and routes it via the best available route, being the direct route via the LAN interface
5) the VPN server receives the encrypted packet etc etc.
It is a common problem to send the encrypted traffic via the tunnel itself ("biting your own tail") but normally OpenVPN works around that using the direct /32 route to the VPN server itself.
Let's say the TUN adapter has an address of 10.8.0.6 (this is the default address for the first client when using 'server 10.8.0.0 255.255.255.0' in the server config) and that the VPN server can be found at address 192.168.0.1. The IP address of the TUN adapter on the server would be 10.8.0.1 in this case.
When OpenVPN starts a direct route is created to 192.168.0.1 netmask 255.255.255.255 , to ensure that all traffic intended for the VPN server LAN IP is not sent via the tunnel.
A client that wishes to send encrypted traffic to the server itself would need to specify as the DEST address 10.8.0.1. The flow would then be
1) application sends a packet with DEST=10.8.0.1
2) kernel routes this packet to the "best" interface, being the TUN interface with address 10.8.0.6; this sets SOURCE=10.8.0.6
3) OpenVPN receives the packet, does its stuff, encrypts it and then sends it to the VPN server @ 192.168.0.1
4) the kernel picks up this packet coming from OpenVPN with DEST=192.168.0.1 and routes it via the best available route, being the direct route via the LAN interface
5) the VPN server receives the encrypted packet etc etc.
It is a common problem to send the encrypted traffic via the tunnel itself ("biting your own tail") but normally OpenVPN works around that using the direct /32 route to the VPN server itself.
-
- OpenVPN User
- Posts: 22
- Joined: Mon Nov 07, 2011 3:11 pm
Re: Porting OpenVpn Client only
Again, thanks!
From an application standpoint: let's say I have several applications running on my machine. These application are not aware of the VPN existence, and hence any data they send would not be using the 10.8.0.1 DEST. The DEST they use will normally be what they actually want to reach (google.com etc). How do we force this to go to the tunnel?
From an application standpoint: let's say I have several applications running on my machine. These application are not aware of the VPN existence, and hence any data they send would not be using the 10.8.0.1 DEST. The DEST they use will normally be what they actually want to reach (google.com etc). How do we force this to go to the tunnel?
- janjust
- Forum Team
- Posts: 2703
- Joined: Fri Aug 20, 2010 2:57 pm
- Location: Amsterdam
- Contact:
Re: Porting OpenVpn Client only
that's plain old routing: if the kernel has a default route set to send everything via the tunnel then all packets by all applications will be sent to the TUN adapter , *unless* a more specific route is present (this is why we need the direct /32 route to the VPN server LAN )
-
- OpenVPN User
- Posts: 22
- Joined: Mon Nov 07, 2011 3:11 pm
Re: Porting OpenVpn Client only
Again...
Your help is appreciated
If you look into the function alloc_buf_gc(), it returns a struct buffer, which seems to me is allocated on the stack, which is causing an issue, I believe, since the function calling alloc_buf_gc() will work on a buffer which becomes garbage.
Please confirm I am not missing something.
Your help is appreciated
If you look into the function alloc_buf_gc(), it returns a struct buffer, which seems to me is allocated on the stack, which is causing an issue, I believe, since the function calling alloc_buf_gc() will work on a buffer which becomes garbage.
Please confirm I am not missing something.
- janjust
- Forum Team
- Posts: 2703
- Joined: Fri Aug 20, 2010 2:57 pm
- Location: Amsterdam
- Contact:
Re: Porting OpenVpn Client only
please post messages of this kind on the openvpn-devel mailing list
-
- OpenVPN User
- Posts: 22
- Joined: Mon Nov 07, 2011 3:11 pm
Re: Porting OpenVpn Client only
Is there a problem running a server with tap device and clients with tun device?
There should be no problem, right?
There should be no problem, right?
- dazo
- OpenVPN Inc.
- Posts: 155
- Joined: Mon Jan 11, 2010 10:14 am
- Location: dazo :: #openvpn-devel @ libera.chat
Re: Porting OpenVpn Client only
This won't work at all. The TAP device transports ethernet frames, while the TUN device transports only IP packets. So both sides must use either TAP or TUN, mixing it will confuse both sides, as it won't understand how to tackle the packets.btk015 wrote:Is there a problem running a server with tap device and clients with tun device?
There should be no problem, right?
As Ethernet frames uses MAC addresses for routing packets, it can transport a lot of other protocols than pure TCP/IP. The tun device will then have stripped out the MAC addresses and only contain IP address information for packet routing; which is what's needed in the TCP/IP world.
-
- OpenVPN User
- Posts: 22
- Joined: Mon Nov 07, 2011 3:11 pm
Re: Porting OpenVpn Client only
Thanks, makes sense.
How does the client knows the server tun/tap address? as it needs to set the dest address of all data sent by application on the client side to the servers tun/tap address, right?
Is this information being communicated through the negotiation?
How does the client knows the server tun/tap address? as it needs to set the dest address of all data sent by application on the client side to the servers tun/tap address, right?
Is this information being communicated through the negotiation?
-
- OpenVPN User
- Posts: 22
- Joined: Mon Nov 07, 2011 3:11 pm
Re: Porting OpenVpn Client only
Guys, I need help again.
It seems like I am through with the vpn initialization, and seems like the session is created successfully.
Now, I start sending data to some server (I have an application which opens a socket to google.com and sends some data). I do see the packet is received on the server side and decrypted successfully (virtual address is the client's tun ip).
I see the server reads this packet from the link adapter(ethernet), and writes it to the tun adapter.
Looking at the tun adapter (using wireshark), I see a packet is there with:
source ip: client's tun ip
destination ip: the google ip
The problem is that nothing happens from this point.
I am missing something, pretty sure about that, but do not know what...
I know that when the server write this packet to the TUN, it means the packet is injected into the OS ip stack, as if it was received from the outside. But who will take care of actually sending it to the destination address?
It seems like I am through with the vpn initialization, and seems like the session is created successfully.
Now, I start sending data to some server (I have an application which opens a socket to google.com and sends some data). I do see the packet is received on the server side and decrypted successfully (virtual address is the client's tun ip).
I see the server reads this packet from the link adapter(ethernet), and writes it to the tun adapter.
Looking at the tun adapter (using wireshark), I see a packet is there with:
source ip: client's tun ip
destination ip: the google ip
The problem is that nothing happens from this point.
I am missing something, pretty sure about that, but do not know what...
I know that when the server write this packet to the TUN, it means the packet is injected into the OS ip stack, as if it was received from the outside. But who will take care of actually sending it to the destination address?
- janjust
- Forum Team
- Posts: 2703
- Joined: Fri Aug 20, 2010 2:57 pm
- Location: Amsterdam
- Contact:
Re: Porting OpenVpn Client only
that's the task of the OS itself, and for that IP forwarding or routing needs to be enabled. How does routing work on your OS anyway?
-
- OpenVPN User
- Posts: 22
- Joined: Mon Nov 07, 2011 3:11 pm
Re: Porting OpenVpn Client only
I didn't do anything for routing on the server side.
I am using a windows XP machine for testing, then moving to a production server.
Which routing is required? Can you explain a bit about the routing in this case?
I am using a windows XP machine for testing, then moving to a production server.
Which routing is required? Can you explain a bit about the routing in this case?
- janjust
- Forum Team
- Posts: 2703
- Joined: Fri Aug 20, 2010 2:57 pm
- Location: Amsterdam
- Contact:
Re: Porting OpenVpn Client only
when you inject a packet into the OS TCP/IP stack the OS needs to be able to forward it; on Linux this is commonly achieved with
On Windows a registry key needs to be set
Code: Select all
echo 1 > /proc/sys/net/ipv4/ip_forward
Code: Select all
regedit
Key: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters
Value: IPEnableRouter
Type: REG_DWORD
Data: 0x00000001 (1)
-
- OpenVPN User
- Posts: 22
- Joined: Mon Nov 07, 2011 3:11 pm
Re: Porting OpenVpn Client only
Thanks!
I tried that, no change, still packet is written to TUN but nothing happens.
Am I missing something in the server configuration? I did nothing for routing in the configuration, assuming that whenever a packet is wriutten into TUN, and injected into the OS stack, the packet would be then forwarded to the IP destination address (of the packet).
I tried that, no change, still packet is written to TUN but nothing happens.
Am I missing something in the server configuration? I did nothing for routing in the configuration, assuming that whenever a packet is wriutten into TUN, and injected into the OS stack, the packet would be then forwarded to the IP destination address (of the packet).
-
- OpenVPN User
- Posts: 22
- Joined: Mon Nov 07, 2011 3:11 pm
Re: Porting OpenVpn Client only
Update!
I do see a change.
It is there and forwarded to the correct address (see this packet on the ethernet device using wireshark, with a correct dest address).
It is a new problem I would need to solve (this is the TCP connection packet, which is probably corrupted).
I would analize the new issue.
Thanks for your help!
I do see a change.
It is there and forwarded to the correct address (see this packet on the ethernet device using wireshark, with a correct dest address).
It is a new problem I would need to solve (this is the TCP connection packet, which is probably corrupted).
I would analize the new issue.
Thanks for your help!
-
- OpenVPN User
- Posts: 22
- Joined: Mon Nov 07, 2011 3:11 pm
Re: Porting OpenVpn Client only
I do see the packet received on the other end (google, in my example), and I see a response is sent from google (well, actually it is not google, just as example), however the response is not there on the vpn server (checked both the tun and the link).
I see "google" packet with:
src ip: "google" ip
dest ip: 10.8.0.6 (client tun address).
In theory, as far as I understand, this packet should have been written to the tun (10.8.0.6 should match tun adapter), which will be read by the VPN server (tun_read), encrypt and sent to the dest (10.8.0.6).
Anything else I am missing?
Maybe the packet is dropped because of the destination address (10.8.0.6, set by "google" as dest)?
Do I need more configuration, something you might know...
I see "google" packet with:
src ip: "google" ip
dest ip: 10.8.0.6 (client tun address).
In theory, as far as I understand, this packet should have been written to the tun (10.8.0.6 should match tun adapter), which will be read by the VPN server (tun_read), encrypt and sent to the dest (10.8.0.6).
Anything else I am missing?
Maybe the packet is dropped because of the destination address (10.8.0.6, set by "google" as dest)?
Do I need more configuration, something you might know...
- janjust
- Forum Team
- Posts: 2703
- Joined: Fri Aug 20, 2010 2:57 pm
- Location: Amsterdam
- Contact:
Re: Porting OpenVpn Client only
the server on which OpenVPN is running gets a reply from google.com (with a different DEST address, as google won't know your 10.8 address); based on NATting rules the server then sets a new DEST IP = 10.8.0.6 and inserts that into the TCP stack. The TCP stack forwards the packet to the server's tun adapter, which means the packet ends up in the openvpn process; openvpn then forwards the packet to the VPN client , where is should be inserted again into the tun adapter , so that the local OS can process it.
-
- OpenVPN User
- Posts: 22
- Joined: Mon Nov 07, 2011 3:11 pm
Re: Porting OpenVpn Client only
Thanks!
Almost done -:)
I did forwarding all traffic from the client through the server.
when I send data (udp, one way link), I do see the data is received by the other end (google.com for example).
But when I need packets to be received on the client side (like establishing a tcp connection, which will require to get a syn/ack for a syn packet), I see the SYN packet is received (at google.com) and then the syn/ack packet sent by google, but nothing is received at the vpn server. It is the same when I use a windows client.
In addition, I see the redirect icmp message (in google.com), which sets the redirect gateway to the vpn client tunnel ip. What is that used for?
Almost done -:)
I did forwarding all traffic from the client through the server.
when I send data (udp, one way link), I do see the data is received by the other end (google.com for example).
But when I need packets to be received on the client side (like establishing a tcp connection, which will require to get a syn/ack for a syn packet), I see the SYN packet is received (at google.com) and then the syn/ack packet sent by google, but nothing is received at the vpn server. It is the same when I use a windows client.
In addition, I see the redirect icmp message (in google.com), which sets the redirect gateway to the vpn client tunnel ip. What is that used for?
-
- OpenVpn Newbie
- Posts: 9
- Joined: Thu Dec 22, 2011 8:28 pm
Re: Porting OpenVpn Client only
I've read through the thread, and your most recent post sounds like either a routing issue or an issue with your TUN's implementation. It also sounds like you may be confusing some OS responsibilities with OpenVPNs'. I'm very new at this stuff so I'm probably going to be overly verbose.
Before I start:
#1) "I did forwarding all traffic from the client through the server."
#2) "In addition, I see the redirect icmp message (in google.com), which sets the redirect gateway to the vpn client tunnel ip. What is that used for?"
Unless I'm misunderstanding you, the mechanism by which you're accomplishing #2, and the whole reason you needed ipv4 forwarding in the first place is via #1. In the OpenVPN server conf file, you specified "--redirect-gateway" or "--redirect-private", no?
Physical Interface G (your "google" server example)
Virtual Interface S (your WinXP or production server or whatever's normal OpenVPN server TUN interface)
Physical Interface E (your embedded device)
Virtual Interface T (your embedded TUN implementation)
Assuming G and E have a direct IP connection, (private subnet) <---> G <~~~> E
The whole point of OpenVPN is to either make E look like it's on the private subnet that G is connected to, or perhaps the connection between G and E isn't secure over whatever ~~~ is (typically the Internet). I'm not really sure what your use case is since you inquired in a few posts how to get around the encryption. The more detail you share the more specific answers can be to your situation.
My checklist for working through this stuff is in three parts:
1) IP forwarding enabled where needed. In direct connectivity, it is NOT unless G is also a gateway and T will be acquiring connectivity that G is servicing. This is specified in G's OpenVPN conf via "push" gateway directives. In a GNU environment there are three main traffic types, INPUT (I'm the destinatio), OUTPUT (I'm the source), and FORWARD (I'm neither). FORWARD is typically disabled at the kernel level by default.
2) Routes need to be implemented in *both* directions for all systems to talk bidirectionally. This means all systems on your private intranet that need to talk to T (or you can implement some sort of routing masquerade on G so that your private subnet only needs to know about G, which it likely already does); this also helps resolve IP conflict issues with T (for large OpenVPN implementations).
Some people assume that RIP or OSPF auto-propagates all this stuff, but it does NOT with OpenVPN alone. That's why the route, push "route", iroute directives exist for OpenVPN implementations, to provide a platform independent mechanism for specifying routes. (This stuff usually gets pushed all the way down to the kernel through userspace mechanisms, but you've already indicated you have full access to the IP stack on your embedded device.) You can run other software like Quagga to implement RIP in software, but I doubt that's an option for your embedded device. Since you have to do all routing by hand, this is so the kernel knows which interface to use when a packet falls under the FORWARD responsibility. google should FORWARD from S, your embedded system should OUTPUT to G via E and probably everything else via T.
3) Firewalls need to be hole-punched because ICMP (which includes ping) is default off in GNU environments, and depending on how locked down the host system G is, the firewall may be preventing the SYN+ACK from actually leaving the system.
When trying to talk with OpenVPN (over T and S), you should see (typically encrypted) traffic on both G and E which is actually encapsulated traffic over T and S (you should also see the traffic when inspecting T and S as they are supposed to be fully-functional interfaces). If you're seeing the ACK+SYN on G,S, and E but not T, you aren't properly routing from your embedded stack to your implementation of the TUN in order for OpenVPN to pick up the communication. If you aren't seeing it on E or T, your server probably isn't routing the response through the correct interface.
To get to the bottom of this, you could also raise the verbosity level of OpenVPN client/server via the --verb 9 directive to get a tcpdump-style output of all activity. I need more information to help you further.
Before I start:
#1) "I did forwarding all traffic from the client through the server."
#2) "In addition, I see the redirect icmp message (in google.com), which sets the redirect gateway to the vpn client tunnel ip. What is that used for?"
Unless I'm misunderstanding you, the mechanism by which you're accomplishing #2, and the whole reason you needed ipv4 forwarding in the first place is via #1. In the OpenVPN server conf file, you specified "--redirect-gateway" or "--redirect-private", no?
Physical Interface G (your "google" server example)
Virtual Interface S (your WinXP or production server or whatever's normal OpenVPN server TUN interface)
Physical Interface E (your embedded device)
Virtual Interface T (your embedded TUN implementation)
Assuming G and E have a direct IP connection, (private subnet) <---> G <~~~> E
The whole point of OpenVPN is to either make E look like it's on the private subnet that G is connected to, or perhaps the connection between G and E isn't secure over whatever ~~~ is (typically the Internet). I'm not really sure what your use case is since you inquired in a few posts how to get around the encryption. The more detail you share the more specific answers can be to your situation.
My checklist for working through this stuff is in three parts:
1) IP forwarding enabled where needed. In direct connectivity, it is NOT unless G is also a gateway and T will be acquiring connectivity that G is servicing. This is specified in G's OpenVPN conf via "push" gateway directives. In a GNU environment there are three main traffic types, INPUT (I'm the destinatio), OUTPUT (I'm the source), and FORWARD (I'm neither). FORWARD is typically disabled at the kernel level by default.
2) Routes need to be implemented in *both* directions for all systems to talk bidirectionally. This means all systems on your private intranet that need to talk to T (or you can implement some sort of routing masquerade on G so that your private subnet only needs to know about G, which it likely already does); this also helps resolve IP conflict issues with T (for large OpenVPN implementations).
Some people assume that RIP or OSPF auto-propagates all this stuff, but it does NOT with OpenVPN alone. That's why the route, push "route", iroute directives exist for OpenVPN implementations, to provide a platform independent mechanism for specifying routes. (This stuff usually gets pushed all the way down to the kernel through userspace mechanisms, but you've already indicated you have full access to the IP stack on your embedded device.) You can run other software like Quagga to implement RIP in software, but I doubt that's an option for your embedded device. Since you have to do all routing by hand, this is so the kernel knows which interface to use when a packet falls under the FORWARD responsibility. google should FORWARD from S, your embedded system should OUTPUT to G via E and probably everything else via T.
3) Firewalls need to be hole-punched because ICMP (which includes ping) is default off in GNU environments, and depending on how locked down the host system G is, the firewall may be preventing the SYN+ACK from actually leaving the system.
When trying to talk with OpenVPN (over T and S), you should see (typically encrypted) traffic on both G and E which is actually encapsulated traffic over T and S (you should also see the traffic when inspecting T and S as they are supposed to be fully-functional interfaces). If you're seeing the ACK+SYN on G,S, and E but not T, you aren't properly routing from your embedded stack to your implementation of the TUN in order for OpenVPN to pick up the communication. If you aren't seeing it on E or T, your server probably isn't routing the response through the correct interface.
To get to the bottom of this, you could also raise the verbosity level of OpenVPN client/server via the --verb 9 directive to get a tcpdump-style output of all activity. I need more information to help you further.
-
- OpenVPN User
- Posts: 22
- Joined: Mon Nov 07, 2011 3:11 pm
Re: Porting OpenVpn Client only
Thanks mmiller!
Lets put the embedded platform aside, once I understand the logic, I would get back to this platform.
I am now trying to establish a windows openvpn client and server configuration to work.
I see the same behavior there.
My config has:
1. redirect-gateway
2. dev tun
3. cipher AES-128-CBC
All traffic on the client side will be routed to the openvpn server (not only intranet but also internet).
I do see the packet received on the server tun interface and then sent on the server physical interface to it's destination (I send packet from client to an internet destination).
The problem is that this packet(client -> server -> internet) is indeed sent successfully, but when a reply is sent from the internet, I do not get this reply on the openvpn server side.
Lets put the embedded platform aside, once I understand the logic, I would get back to this platform.
I am now trying to establish a windows openvpn client and server configuration to work.
I see the same behavior there.
My config has:
1. redirect-gateway
2. dev tun
3. cipher AES-128-CBC
All traffic on the client side will be routed to the openvpn server (not only intranet but also internet).
I do see the packet received on the server tun interface and then sent on the server physical interface to it's destination (I send packet from client to an internet destination).
The problem is that this packet(client -> server -> internet) is indeed sent successfully, but when a reply is sent from the internet, I do not get this reply on the openvpn server side.