Bind only to specified interface
PATCH 1/1 Bind only to specified interface
Author: Federico Heinz <[email protected]...>
Accept "local if:<ifname>" option.
The current 'local' configuration directive allows for two types of
values: IP addresses and DNS hostnames. This is not enough for users of dynamic DNS services who must restart OpenVPN when their IP address changes, because their new IP address may not have progagated yet through DNS when OpenVPN starts, and so they may end up binding to a bogus address.
This patch introduces a parameter notation that helps solve the
problem: if the option parameter is of the form "if:<ifname>", it will determine the IP address of the interface and use that as the IP address to bind to.
The patch is small, and meant to be mininally intrusive: instead of adding a new option and/or new code paths to handle the new case, it simply replaces the value supplied by the user by a string representing the IP address, as if the user had entered it.
I'm not entirely sure I'm using gc_malloc() correctly, and I'd appreciate feedback on that.
openvpn.8 +6 -0
@@ -197,6 +197,12 @@ .B \-\-local host Local host name or IP address for bind. If specified, OpenVPN will bind to this address only. +If +.B local +is of the form +.B if:ifname, +OpenVPN will bind only to the IP address of the interface called +.B ifname. If unspecified, OpenVPN will bind to all interfaces. .\"********************************************************* .TP
options.c +29 -1
@@ -51,6 +51,9 @@#include "forward.h" #include "configure.h" #include <ctype.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> #include "memdbg.h"
@@ -101,6 +104,7 @@"\n" "Tunnel Options:\n" "--local host : Local host name or ip address. Implies --bind.\n" +" Use \"if:<ifname>\" for IP address of interface <ifname>." "--remote host [port] : Remote host name or ip address.\n" "--remote-random : If multiple --remote options specified, choose one randomly.\n" "--remote-random-hostname : Add a random string to remote DNS name.\n"
@@ -4017,8 +4021,32 @@ }else if (streq (p[0 ],"local" ) && p[1 ]) { +static const char if_prefix[] ="if:" ;VERIFY_PERMISSION (OPT_P_GENERAL |OPT_P_CONNECTION ); - options->ce.local = p[1 ]; + options->ce.local =NULL ; +if (strneq (if_prefix, p[1 ],sizeof (if_prefix)-1 )) + { +int fd; +struct ifreq ifr; + + ifr.ifr_addr.sa_family =AF_INET ; +strncpy (ifr.ifr_name, &(p[1 ][sizeof (if_prefix)-1 ]),IFNAMSIZ -1 ); +if ((fd =socket (AF_INET ,SOCK_DGRAM ,0 ))>=0 ) + { +if (ioctl (fd,SIOCGIFADDR , &ifr) >=0 ) + { +const char *addr =inet_ntoa (((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr); +char *value =gc_malloc (strlen (addr)+1 , true, &options->gc); +strcpy (value, addr); + options->ce.local = value; + } +close (fd); + } + } +if (options->ce.local ==NULL ) + { + options->ce.local = p[1 ]; + } }else if (streq (p[0 ],"remote-random" )) {
options.h +1 -0
@@ -563,6 +563,7 @@ };#define streq (x, y) (!strcmp((x), (y))) +#define strneq (x, y, n) (!strncmp((x), (y), (n)))/* * Option classes.
Hello,
I don't understand why it is needed.
You can always start openvpn and override configuration via command-line.
So add --local "$(/sbin/ip addr show dev wlan0 | grep inet | sed 's#.*inet \(.*\)/.*#\1#')" parameter while starting it.
A more generic approach can be adding $() support into openvpn options handling, so you can execute any command and put its output as a value of substring option.
Alon.
Quoted 37 lines · Federico Heinz
Author: Federico Heinz <[email protected]...>
Accept "local if:<ifname>" option.
The current 'local' configuration directive allows for two types of
values: IP addresses and DNS hostnames. This is not enough for users of dynamic DNS services who must restart OpenVPN when their IP address changes, because their new IP address may not have progagated yet through DNS when OpenVPN starts, and so they may end up binding to a bogus address.This patch introduces a parameter notation that helps solve the
problem: if the option parameter is of the form "if:<ifname>", it will determine the IP address of the interface and use that as the IP address to bind to.The patch is small, and meant to be mininally intrusive: instead of adding a new option and/or new code paths to handle the new case, it simply replaces the value supplied by the user by a string representing the IP address, as if the user had entered it.
I'm not entirely sure I'm using
gc_malloc()correctly, and I'd appreciate feedback on that.Signed-off-by Federico Heinz <[email protected]...>------------------------------------------------------------------------------
What You Don't Know About Data Connectivity CAN Hurt You This paper provides an overview of data connectivity, details its effect on application quality, and explores various alternative solutions. http://p.sf.net/sfu/progress-d2d
_______________________________________________
Openvpn-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/openvpn-devel
Quoted 5 lines · Alon Bar-Lev
I don't understand why it is needed.
You can always start openvpn and override configuration via command-line.
So add --local "$(/sbin/ip addr show dev wlan0 | grep inet | sed 's#.*inet \(.*\)/.*#\1#')" parameter while starting it.
Sure: there's a huge number of workarounds one could use. Only I think this is a useful feature in its own right, and much easier for people to find.
Fumbling with the command line also works fairly well when you are running only one instance of OpenVPN (say, in Debian you could get away with clever code in /etc/defaults/openvpn). When you run more than one (say, for multiple interfaces), however, the doctoring that has to be done in the startup scripts is more arcane.
Workarounds like to one you propose, are much more complicated and cryptic than the solution I propose.
I'd like to point out that OpenVPN is rather an odd case among internet daemons in not providing an easy way to say "bind to interface so-and-so", most other daemons have such a configuration option.
So, while I agree that there are ways of achieving this by fiddling with the command line and startup scripts, I rather strongly feel that this feature is worthwhile.
Fede
Hi,
Quoted 1 line · Federico Heinz
Accept "local if:<ifname>" option.
I can understand why this feature is desirable - there are a couple of problems with the implementation, though.
- From a code modularity point of view, socket stuff should not go to options.c, but to socket.c
- your code is likely to work on Linux and *BSD, but will it work "as is" on Solaris and Windows? I don't expect it to, so additional #ifdef's are needed --> and that's why it should go to one of the more system-dependent (and already #ifdef-filled) source files
In general, I wonder why binding to the interface is really needed - what happens if you don't specify "local" at all? It should pick the proper source address automatically.
gert
Signature · 4 lines
USENET is *not* the non-clickable part of WWW!
//www.muc.de/~gert/
Gert Doering - Munich, Germany [email protected]...
fax: +49-89-35655025 [email protected]...-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
On 09/03/11 01:05, Federico Heinz wrote:
| On 09/03/2011, Alon Bar-Lev wrote: |> I don't understand why it is needed. |> You can always start openvpn and override configuration via |> command-line. |> So add --local "$(/sbin/ip addr show dev wlan0 | grep inet | sed |> 's#.*inet \(.*\)/.*#\1#')" parameter while starting it.
I see this patch as an indication of a feature which really is missing. However, I am sceptical to the approach of this patch, so I'm actually siding with Alon here.
So, feature-wise - I give this an ACK. Implementation-wise it's a NACK, unfortunately.
Even though that shell trick isn't so obvious, I would say it solves exactly the same thing. It's not as pretty, but your patch does not give any extra advantages either.
| I'd like to point out that OpenVPN is rather an odd case among | internet daemons in not providing an easy way to say "bind to | interface so-and-so", most other daemons have such a configuration | option.
Yes, agreed! This is a feature people to ask for. We just need to find the proper implementation for it. There are a couple things which I don't like about this patch, though.
One is that you do resolve the IP address based on the device name. What if the IP address changes on that device? It would be anticipated by most users that it would then listen to the new IP address. When being done via the command line, it is much more obvious OpenVPN needs to be restarted on an IP address change.
Then there are is this issue with IPv6. It's not available in the coming 2.2 or earlier releases (unless you've added support patches for it). But we're soon (4-12 weeks) starting on the 2.3 beta cycle which will include full IPv6 support. And with IPv6 an interface can also multiple IP addresses, even without using aliasing in Linux. In fact, I wonder if it is even possible to assign multiple IPv4 addresses using iproute2 to a device without aliases. It might be something similar in *BSD as well. Your patch does not cover this scenario at all.
The third thing is that you do socket() operations in options.c. The code is messy enough as it is, and I would like to contain everything which does socket operations in socket.c. Unfortunately, socket.c is pretty messy. So we do need to clean that code up.
And to really top it. OpenVPN does not support listening to multiple IP addresses currently. So socket.c needs a major overhaul and this feature must be implemented. When we manage this, we can bind to devices instead of IP addresses, as then OpenVPN would behave as expected by most users.
I doubt such a change will make it for 2.3, due to the work related to it. But if it is ready in time, we can add it to 2.3. If not, there's always the next 2.4 release in the horizon as well.
kind regards,
David Sommerseth
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/
iEYEARECAAYFAk13RWUACgkQDC186MBRfro6EgCfSSa5ZT+v90ZasciYa9RhM/Wa qOsAn0w5CJ/wJqwI3wgrHsrB5m9aag1o
=hvl5
-----END PGP SIGNATURE-----
Quoted 4 lines · Gert Doering
I can understand why this feature is desirable - there are a couple of problems with the implementation, though.
- From a code modularity point of view, socket stuff should not go tooptions.c, but tosocket.c
I understand that with "socket stuff" you probably mean "socket operations". Actually, my first implementation of this feature (attached) was entirely confined to socket.c, amd simply accepted an interface name as a possible value. The reason I didn't like it was because because I couldn't easily identify a spot in socket.c that would confine this behaviour to just the local interface.
Quoted 5 lines
- your code is likely to work on Linux and *BSD, but will it work "as is" on Solaris and Windows? I don't expect it to, so additional #ifdef's are needed --> and that's why it should go to one of the more system-dependent (and already #ifdef-filled) source files
I'll need help from people with access to those systems to place the appropriate #ifdefs...
Quoted 3 lines
In general, I wonder why binding to the interface is really needed
- what happens if you don't specify "local" at all? It should pick the proper source address automatically.
It does, unless you have more than one interface, and you need OpenVPN to bind to only one of them.
Fede
socket.c +19 -0
@@ -32,6 +32,7 @@#include "ps.h" #include "manage.h" #include "misc.h" +#include <net/if.h> #include "memdbg.h"
@@ -129,6 +130,24 @@ status =openvpn_inet_aton (hostname, &ia);/* parse ascii IP address */ +if (status !=OIA_IP )/* Attempt to parse as interface name */ + { +int fd; +struct ifreq ifr; + + ifr.ifr_addr.sa_family =AF_INET ; +strncpy (ifr.ifr_name, hostname,IFNAMSIZ -1 ); +if ((fd =socket (AF_INET ,SOCK_DGRAM ,0 ))>=0 ) + { +if (ioctl (fd,SIOCGIFADDR , &ifr) >=0 ) + { + ia = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr; + status =OIA_IP ; + } +close (fd); + } + } +if (status !=OIA_IP )/* parse as IP address failed? */ {const int fail_wait_interval =5 ;/* seconds */
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Quoted 3 lines · David Sommerseth
Even though that shell trick isn't so obvious, I would say it solves exactly the same thing. It's not as pretty, but your patch does not give any extra advantages either.
It provides the only advantage it was meant to provide: a simpler setup syntax that is easy to read and write.
Quoted 5 lines
One is that you do resolve the IP address based on the device name. What if the IP address changes on that device? It would be anticipated by most users that it would then listen to the new IP address. When being done via the command line, it is much more obvious OpenVPN needs to be restarted on an IP address change.
AFAIK, te need to restart under such a circumstance is there for any and all internet daemons that allow the user to bind to an interface, so there's nothing unexpected here.
Quoted 9 lines
Then there are is this issue with IPv6. It's not available in the coming 2.2 or earlier releases (unless you've added support patches for it). But we're soon (4-12 weeks) starting on the 2.3 beta cycle which will include full IPv6 support. And with IPv6 an interface can also multiple IP addresses, even without using aliasing in Linux. In fact, I wonder if it is even possible to assign multiple IPv4 addresses using iproute2 to a device without aliases. It might be something similar in *BSD as well. Your patch does not cover this scenario at all.
It's not meant to, since OpenVPN does not currently support listening on a multi-membered subset of the system's IP addresses. In the current scenario, then if you have an interface with more than one address, we will be forced to choose one of them arbitrarily... which is exactly what my patch does: it takes whatever IP address ends up in the socket's IP address field.
Summing up: in the most likely case, my code does the expected thing. In unlikely cases, it does as good as it can for the curren OpenVPN implementation. If and when OpenVPN supports listening on a list of IP addresses, the code can easily be upgraded to support it, but it's impossible to do it before.
Quoted 4 lines
[...] So
socket.cneeds a major overhaul and this feature must be implemented. When we manage this, we can bind to devices instead of IP addresses, as then OpenVPN would behave as expected by most users.
I understand that socket.c needs a major overhaul, but my patches show two strategies how this useful behaviour can be implemented *today* without much hassle. I think it would be better to include the functionality now, at the same time providing a template of what needs to be done for the future, than to delay the inclusion of useful functionality to an unspecified time when socket.c finally gets its overhaul.
Fede
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
iD8DBQFNd3AJbPULDL0CxuARAnk+AKDryLC6e2QeJAZTSXWqGqgejkfvzQCfUcy+ 7aajuzkOtZ0h2hgu3m/xtY8=
=qX6x
-----END PGP SIGNATURE-----
Hi,
any reason this list does not send a proper reply-to-list?
Quoted 5 lines · David Sommerseth
One is that you do resolve the IP address based on the device name. What if the IP address changes on that device? It would be anticipated by most users that it would then listen to the new IP address. When being done via the command line, it is much more obvious OpenVPN needs to be restarted on an IP address change.
You do not want to get into supporting changing addresses, really. While libnl would work for linux, but that does not cover bsds or anything else.
Quoted 4 lines
In fact, I wonder if it is even possible to
assign multiple IPv4 addresses using iproute2 to a device without aliases. It might be something similar in *BSD as well. Your patch does not cover this scenario at all.
This is possible, one can have more than one IPv4 address per interface on linux using iproute2 easily.
To do this properly ...
Either use SO_BINDTODEVICE, which is not portable again, or getifaddrs() to gather the addresses for the interface and multi-listen the daemon -
which is not implemented.
Neither getifaddrs nor SO_BINDTODEVICE are 100% portable, so there is no real proper way, nevertheless getifaddrs would be my choice.
So besides from all mentioned points, even the approach to get the address is wrong.
Markus
Quoted 10 lines · Markus Kötter
Quoted 6 lines · David Sommerseth
One is that you do resolve the IP address based on the device name. What if the IP address changes on that device? It would be anticipated by most users that it would then listen to the new IP address. When being done via the command line, it is much more obvious OpenVPN needs to be restarted on an IP address change.
You do not want to get into supporting changing addresses, really. While libnl would work for linux, but that does not cover bsds or anything else.
Agreed!
Quoted 6 lines
To do this properly ...
Either useSO_BINDTODEVICE, which is not portable again, orgetifaddrs()to gather the addresses for the interface and multi-listen the daemon - which is not implemented. Neither getifaddrs norSO_BINDTODEVICEare 100% portable, so there is no real proper way, nevertheless getifaddrs would be my choice.
I agree that getifaddrs() would be a better way of doing this *if* the deamon knew how to multi-listen (or, to put it in another way, *when* the daemon lerns to).
While I am willing to revise the code to use getifaddr() if that will make it more palatable to the project, the current approach does work and seems to me to be more portable.
Fede
I'm sorry, folks, I'd like to ask for some clarification.
My patch was NAK'd on implementation issues. I offered alternatives to them. I got no answer to them.
Should I bother implementing one of the alternatives, or will the patch be disregarded nonetheless? If the patch does stand a chance to be accepted with a better implemantation, should I go with getiffadrs() or the current approach to get the interface's IP address?
Fede
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Quoted 10 lines · Federico Heinz
I'm sorry, folks, I'd like to ask for some clarification.
My patch was NAK'd on implementation issues. I offered alternatives to them. I got no answer to them.
Should I bother implementing one of the alternatives, or will the patch be disregarded nonetheless? If the patch does stand a chance to be accepted with a better implemantation, should I go with
getiffadrs()or the current approach to get the interface's IP address?
Sorry that you haven't received any response quickly. Most of us here are having full time jobs which is not directly related to OpenVPN.
But I have been thinking about this a lot. And I decided to have a peek at what other open source products does. I checked against openssh-5.8, vsftpd-2.3.4, nginx-0.9.5, lighthttpd-1.4.28 and varnish (git HEAD = 7058d471b586151e). I also checked against the documentation for ISC BIND 9.8,
None of these products supports network device name for setting up listen addresses. I chose these products as they are all aimed at being accessed from the "wild Internet", accepting connections from whoever who are not necessarily known to the server. Which makes their use cases closer to OpenVPN.
After some pondering, I begin to wonder if this feature really is as clever as we believe it is. I do stand corrected in regards to dynamically changing the listening IP address, and in hindsight supporting such a feature probably makes things even worse.
But to summarise it somehow, based on my pondering ... a quick pro/cons list:
+ makes config easier for sys-admins
- OpenVPN will only listen to the first identified IP address, which will need to be both IPv4 and IPv6 aware. This will become a support issue pretty quickly.
- 6 different open source products which has a similar usage profile (open access from the Internet) do not have this support.
- Can cause some surprises, if people re-plug a network cable between two network devices. Suddenly OpenVPN is available on a network segment it should not be available on, due to not being restricted to particular a IP address. Of course it should be a firewall stopping it in front, but that might have been disabled as well - for unknown reasons. Surely this is a PEBKAC issue, but they do happen more often than we like to admit.
So, is this really such a good idea? I'm not withdrawing my feature NACK now, but I'm suddenly not so convinced this is clever. Unless someone comes with convincing arguments.
But please share your opinions - every one who got an opinion about this.
kind regards,
David Sommerseth
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/
iEYEARECAAYFAk16dFIACgkQDC186MBRfrpyPQCfVP2m20ZhWfYN1yPeic4FgSqy QPAAnRqym4IK77PSF7WIfzm4jd8ton3l
=QE4V
-----END PGP SIGNATURE-----
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Quoted 3 lines · David Sommerseth
Sorry that you haven't received any response quickly. Most of us here are having full time jobs which is not directly related to OpenVPN.
I'm sorry if I sounded like I felt that answers were slow in coming. Actually, I was amazed with the response time to my initial submission. When the rhythm of the discussion dropped, I thought people were losing interest, that's why I asked.
Quoted 5 lines
None of these products supports network device name for setting up listen addresses. I chose these products as they are all aimed at being accessed from the "wild Internet", accepting connections from whoever who are not necessarily known to the server. Which makes their use cases closer to OpenVPN.
The reason I looked into this in the first place was that, unlike those TCP-based protocols, I couldn't get OpenVPN to work on a firewall with two external IP addresses without running two deamons, each one bound to one interface only. It is then that I stumbled upon the difficulty of setting up the server that must listen on an interface that has a dynamically-assigned address.
Quoted 6 lines
But to summarise it somehow, based on my pondering ... a quick pro/cons list:
+ makes config easier for sys-admins
- OpenVPN will only listen to the first identified IP address, which will need to be both IPv4 and IPv6 aware. This will become a support issue pretty quickly.
Actually, that would require a user to *both* have multiple IP addresses on the same interface, *and* to want to use this feature, which I'd gather is not likely. In any case, a short mention in the documentation that the "if:" notation only works with interfaces that have just one interface would solve it (I can even add code to check for this condition and log a warning). This of course, would only be the case until OpenVPN supports listening on multiple addresses, then we can simply fix it.
Quoted 2 lines
- 6 different open source products which has a similar usage
profile (open access from the Internet) do not have this support.
Those protocols aren't affected by the issue I mentioned, and I'd venture to say that they are not nearly as likely to be used in a dynamic-IP address setup as OpenVPN, which is great for tunnelling into home.
In any case: I didn't tackle this because I was bored, but because I have a real use case, and a working setup, which I think other people may find useful.
Quoted 7 lines
- Can cause some surprises, if people re-plug a network cable
between two network devices. Suddenly OpenVPN is available on a network segment it should not be available on, due to not being restricted to particular a IP address. Of course it should be a firewall stopping it in front, but that might have been disabled as well - for unknown reasons. Surely this is a PEBKAC issue, but they do happen more often than we like to admit.
Sure... but such a problem would:
1) be rather quickly discovered, when people cannot connect to the VPN,
2) be rather unlikely to cause security issues, since even from the wrong network, people would need the credentials to get connected.
Fede
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
iD8DBQFNeun1bPULDL0CxuARAtSsAJ9DFnb8SFs/Gd0Am9/A9IRKpui6LACg1/aw lif+92pajziWM1/x41kRbhA=
=N/8A
-----END PGP SIGNATURE-----
Quoted 6 lines · Federico Heinz
The reason I looked into this in the first place was that, unlike those TCP-based protocols, I couldn't get OpenVPN to work on a firewall with two external IP addresses without running two deamons, each one bound to one interface only. It is then that I stumbled upon the difficulty of setting up the server that must listen on an interface that has a dynamically-assigned address.
If this is the problem you want to solve I have to say I think you're doing it the wrong way.
There are components in your system which *will* know when your address is reconfigured. Please just configure them to reconfigure OpenVPN. This would seem to be a good use for the management interface in OpenVPN.
I like to use udhcpd for systems like this. It is fast and no-nonsense. It runs a script that you have to write.
It makes no sense trying to work around the requirement of knowing your configuration. That is always neccessary, unless you are prepared to listen on 0.0.0.0, which I would guess already works without special OpenVPN options or code.
//Peter
I'm actually kind of curious what reasons there would be that listening to 0.0.0.0 would be undesireable. For other daemons, I can see a rationale because of two reasons, one being that you don't trust the security of the daemon and want to add interface specificity to your firewall rules for belt-and-suspenders security. The other reason I can think of is if you want to have different configurations bound to different interfaces, like maybe running squid as a caching proxy for your internal users but as a load balancing proxy for inbound connections to a web server, or if you want to have a DNS server that returns different information based on what IP is being accessed but don't want to use views.
Neither of these scenarios makes much sense. If you don't trust the security of openvpn enough to let it listen on the internet, you probably shouldn't be using it in the first place. And while I could possibly see having one configuration for Internet users connecting inbound via VPN and maybe internal wireless users using a different configuration because they understandably don't trust WPA... it's a stretch. And I'm pretty sure that if you start one openvpn process listening on a specific IP, then another listening on 0.0.0.0, it'll still work, and the second instance will effectively be listening on every *other* IP from the first. You'd still have issues if you have multiple dynamic IP's, but that's getting to be *really* convoluted and weird.
I'm all for adding flexibility, but this really seems like a solution to a problem for which there's hardly ever *not* a better work-around.
Quoted 37 lines · Peter Stuge
Quoted 6 lines · Federico Heinz
The reason I looked into this in the first place was that, unlike those TCP-based protocols, I couldn't get OpenVPN to work on a firewall with two external IP addresses without running two deamons, each one bound to one interface only. It is then that I stumbled upon the difficulty of setting up the server that must listen on an interface that has a dynamically-assigned address.
If this is the problem you want to solve I have to say I think you're doing it the wrong way.
There are components in your system which *will* know when your address is reconfigured. Please just configure them to reconfigure OpenVPN. This would seem to be a good use for the management interface in OpenVPN.
I like to use udhcpd for systems like this. It is fast and no-nonsense. It runs a script that you have to write.
It makes no sense trying to work around the requirement of knowing your configuration. That is always neccessary, unless you are prepared to listen on 0.0.0.0, which I would guess already works without special OpenVPN options or code.
//Peter
------------------------------------------------------------------------------
Colocation vs. Managed Hosting
A question and answer guide to determining the best fit for your organization - today and in the future.
http://p.sf.net/sfu/internap-sfd2d
_______________________________________________
Openvpn-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/openvpn-devel
Quoted 4 lines · Peter Stuge
There are components in your system which *will* know when your address is reconfigured. Please just configure them to reconfigure OpenVPN. This would seem to be a good use for the management interface in OpenVPN.
I'm not worried abut the IP number *changing*, that's a completely different issue, and I already have stuff in place that will restart OpenVPN when the interface in question changes configuration.
What I'm trying to solve here is a much simpler (and, in my case, frequent) use case: I'm starting several instances of OpenVPN, and I need each of them to listen on specific interfaces, but their dyndns addresses may not be up-to date yet, so I can specify neither an IP nor a domain name in the "local" directive.
Quoted 2 lines
It makes no sense trying to work around the requirement of knowing your configuration.
I know my configuration I just don't know it at configuration time. Someone pointed out earlier that the same effect I'm aiming at can be achieved with a rather involved command-line hack. I'm just trying to make it more comfortable.
Quoted 2 lines
[...] unless you are prepared to listen on 0.0.0.0, which I would guess already works without special OpenVPN options or code.
Only... it doesn't work in all setups. As described in shorewall's multi-ISP guide[1] (search for "OpenVPN" in that page), sometimes you need to bind the daemon to a specific interface.
That guide talks about binding to the interface in order to force traffic through a certain ISP (something I hope you will agree can be useful under a number of circumstances), but I have found that having OpenVPN listen on 0.0.0.0 in such a setup does not work properly:
connections are unstable and drop for no apparent reason, and establishing the tunnel fails intermittently.
Fede
Quoted 3 lines · Joe Patterson
I'm all for adding flexibility, but this really seems like a solution to a problem for which there's hardly ever *not* a better work-around.
As I just mentioned in an answer to Peter, listening on 0.0.0.0 doesn't work reliably on my setup, please refer to that e-mail for the full explanation.
Of course, if you do have a better workaround that will work in this setup, I'll be glad to hear about it!
Fede
Quoted 2 lines · Joe Patterson
I'm actually kind of curious what reasons there would be that listening to 0.0.0.0 would be undesireable.
..
Quoted 2 lines
if you want to have different configurations bound to different interfaces,
Exactly.
Quoted 4 lines
while I could possibly see having one configuration for Internet users connecting inbound via VPN and maybe internal wireless users using a different configuration because they understandably don't trust WPA... it's a stretch.
Not really. I've implemented this on a customer site with a fairly complex network split into different subnets, but with a single router box that also handled multiple VPNs.
Quoted 4 lines
And I'm pretty sure that if you start one openvpn process listening on a specific IP, then another listening on 0.0.0.0, it'll still work, and the second instance will effectively be listening on every *other* IP from the first.
You'll need to do some more socket programming. :) It will not work. Ports are first come first serve. Only one process can bind to a port at a time. Multicast is the exception, but then the sender must also be using the multicast as destination.
Quoted 2 lines
I'm all for adding flexibility, but this really seems like a solution to a problem for which there's hardly ever *not* a better work-around.
I actually think the proposed patch is a workaround, and that driving a configuration change into openvpn from the system components which are in charge of the network reconfiguration in the first place is the only actual solution.
//Peter
Quoted 5 lines · Federico Heinz
What I'm trying to solve here is a much simpler (and, in my case, frequent) use case: I'm starting several instances of OpenVPN, and I need each of them to listen on specific interfaces, but their dyndns addresses may not be up-to date yet, so I can specify neither an IP nor a domain name in the "local" directive.
Why can't you specify the IP address?
//Peter
Quoted 7 lines · Peter Stuge
Quoted 5 lines · Federico Heinz
What I'm trying to solve here is a much simpler (and, in my case, frequent) use case: I'm starting several instances of OpenVPN, and I need each of them to listen on specific interfaces, but their dyndns addresses may not be up-to date yet, so I can specify neither an IP nor a domain name in the "local" directive.
Why can't you specify the IP address?
Because I don't know it at configuration time.
The "local" directive will currently accept either a fixed IP address (which I don't know, because it will be assigned in the future, and may change every time that particular interface is brought up) or a domain name.
Using the domain name together with a dyndns service works sometimes, but fails when the interface has just been brought up, and the dyndns update hasn't yet propagated through the DNS system.
Alon mentioned earlier that this could be dealt with at run-time by modifying the startup scripts to determine the IP address and specify it through the command-line, but it's an unnecessarily complex solution, which in some cases involves messing around with the way your distro usually does things, something I prefer to avoid.
Fede
Quoted 10 lines · Federico Heinz
Quoted 7 lines · Peter Stuge
Quoted 5 lines · Federico Heinz
What I'm trying to solve here is a much simpler (and, in my case, frequent) use case: I'm starting several instances of OpenVPN, and I need each of them to listen on specific interfaces, but their dyndns addresses may not be up-to date yet, so I can specify neither an IP nor a domain name in the "local" directive.
Why can't you specify the IP address?
Because I don't know it at configuration time.
You said that you already have a solution in place for dealing with interface reconfiguration.
Simply use the same mechanism for initial configuration.
Quoted 4 lines
The "local" directive will currently accept either a fixed IP address (which I don't know, because it will be assigned in the future, and may change every time that particular interface is brought up)
Yes. Third time, tap the configuration information from the authoritative source. Until OpenVPN has multilisten there's no point in OpenVPN trying to do this, because it will only do a poor job.
Quoted 1 line
or a domain name.
The domain name is irrelevant. Go closer to the authoritative source, not further away.
Quoted 4 lines
Alon mentioned earlier that this could be dealt with at run-time by modifying the startup scripts to determine the IP address and specify it through the command-line, but it's an unnecessarily complex solution,
I actually think this is an extremely simple solution.
Quoted 2 lines
which in some cases involves messing around with the way your distro usually does things,
Why would it?
//Peter
Quoted 4 lines · Peter Stuge
Quoted 1 line · Federico Heinz
Because I don't know it at configuration time.
You said that you already have a solution in place for dealing with interface reconfiguration.
I said I have a solution in place to restart OpenVPN when the configuration changes. The solution is part of my distro of choice (Debian), and works pretty well for that purspose.
Quoted 1 line
Simply use the same mechanism for initial configuration.
That's an odd way of unsing the word "simply".
Sure, I could change a few system scripts, and include something like Alon suggested (/sbin/ip addr show dev ppp0 | grep inet | sed 's#.*inet \(.*\)/.*#\1#'), to figure out the IP address, change the configuration files and only then restart OpenVPN.
What I fail to see is how that is "simpler" or easier to understand or maintain than writing "local if:ppp0" in the daemon's config file.
Quoted 2 lines
Until OpenVPN has multilisten there's no point in OpenVPN trying to do this, because it will only do a poor job.
This is simply not true. It will do a good job in most cases, and a well-specified, if incomplete, job in the rather unlikely case that someone deliberately attempts to use this feature together with multiple IP addresses on a single interface, and even then it will emit a warning.
You are arguing that because it cannot do the job perfectly in an unlikely edge case, it shouldn't even attempt to solve a different, well-defined use case.
I'm sorry, that doesn't make sense to me.
Quoted 3 lines
Quoted 1 line
or a domain name.
The domain name is irrelevant. Go closer to the authoritative source, not further away.
Agreed. I'm going as close to it as I can: the interface itself, from the viewpoint of the program that is using it.
Quoted 3 lines
Quoted 2 lines
which in some cases involves messing around with the way your distro usually does things,
Why would it?
It means modifying the distro's startup scripts for OpenVPN, to get them to figure out the IP address of the interface for *some* instances of the server but not necessarily for all.
Sure, modifying those scripts isn't taboo, but it's not as usual and clean as it is to modify the subsystem's own configuration files (in Debian, /etc/openvpn/*.conf and /etc/default/openvpn), because they simply assume the program will be able to gather all the info it needs to run from those configuration files.
The change I'm proposing simply aims at meeting that assumption.
Fede
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
On 12/03/11 22:44, Federico Heinz wrote:
| On 12/03/2011, Peter Stuge wrote:
[...snip...]
|> [...] unless you are prepared to listen on 0.0.0.0, which I would |> guess already works without special OpenVPN options or code. | | Only... it doesn't work in all setups. As described in shorewall's | multi-ISP guide[1] (search for "OpenVPN" in that page), sometimes you | need to bind the daemon to a specific interface. | | That guide talks about binding to the interface in order to force | traffic through a certain ISP (something I hope you will agree can be | useful under a number of circumstances), but I have found that having | OpenVPN listen on 0.0.0.0 in such a setup does not work properly: | connections are unstable and drop for no apparent reason, and | establishing the tunnel fails intermittently.
As Davide Brini already mentioned, I really wonder if this issue is due to lack of --multihome in your configuration, combined with listen on 0.0.0.0.
~From the man page:
~ --multihome
~ Configure a multi-homed UDP server. This option can be used ~ when OpenVPN has been configured to listen on all interfaces, ~ and will attempt to bind client sessions to the interface on ~ which packets are being received, so that outgoing packets will ~ be sent out of the same interface. Note that this option is ~ only relevant for UDP servers and currently is only implemented ~ on Linux.
~ Note: clients connecting to a --multihome server should always
~ use the --nobind option.
Can you please test this?
kind regards,
David Sommerseth
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/
iEYEARECAAYFAk18HQUACgkQDC186MBRfrpvQgCgqTw4Iz0xieT6wDjzaiD8jowJ XiQAn3JB+UgBFSaR9dD4eIexVJodfjXM
=LXsh
-----END PGP SIGNATURE-----
Quoted 7 lines · Federico Heinz
Quoted 4 lines
Quoted 1 line
Because I don't know it at configuration time.
You said that you already have a solution in place for dealing with interface reconfiguration.
I said I have a solution in place to restart OpenVPN when the configuration changes.
I understand. So there is no solution for dealing with the reconfiguration.
Quoted 4 lines
Sure, I could change a few system scripts, and include something like Alon suggested (
/sbin/ipaddr show dev ppp0 | grep inet | sed 's#.*inet \(.*\)/.*#\1#'), to figure out the IP address, change the configuration files and only then restart OpenVPN.
Would suggest wrapping openvpn instead of changing system scripts.
Quoted 2 lines
What I fail to see is how that is "simpler" or easier to understand or maintain than writing "local if:ppp0" in the daemon's config file.
It remains clear that openvpn binds to only one IP.
Quoted 9 lines
Quoted 2 lines
Until OpenVPN has multilisten there's no point in OpenVPN trying to do this, because it will only do a poor job.
This is simply not true. It will do a good job in most cases, and a well-specified, if incomplete, job in the rather unlikely case that someone deliberately attempts to use this feature together with multiple IP addresses on a single interface, and even then it will emit a warning.
Quoted 5 lines
You are arguing that because it cannot do the job perfectly in an unlikely edge case, it shouldn't even attempt to solve a different, well-defined use case.
I'm sorry, that doesn't make sense to me.
I like do it right or don't do it at all. Only working in some cases is not good behavior for a feature.
Quoted 5 lines
Quoted 2 lines
The domain name is irrelevant. Go closer to the authoritative source, not further away.
Agreed. I'm going as close to it as I can: the interface itself, from the viewpoint of the program that is using it.
No, the source is the system component which configures the interface, not the interface itself, which is more like a data store in this case.
Quoted 8 lines
Quoted 4 lines
Quoted 2 lines
which in some cases involves messing around with the way your distro usually does things,
Why would it?
It means modifying the distro's startup scripts for OpenVPN, to get them to figure out the IP address of the interface for *some* instances of the server but not necessarily for all.
Changing startup scripts or wrapping openvpn is one way. But I would probably drive everything from the DHCP client instead.
As I wrote, udhcpc is very very easy to deal with.
Quoted 3 lines · David Sommerseth
As Davide Brini already mentioned, I really wonder if this issue is due to lack of --multihome in your configuration, combined with listen on 0.0.0.0.
He wants different openvpn servers on different interfaces using same port.
//Peter
Quoted 4 lines · Peter Stuge
Changing startup scripts or wrapping openvpn is one way. But I would probably drive everything from the DHCP client instead.
As I wrote, udhcpc is very very easy to deal with.
Your /usr/share/udhcpc/default.script to accomplish this would be:
#!/bin/sh
test "$1" = bound || exit 0
sed -i "/^local /s/.*/local $ip/" /etc/openvpn/something/local.conf /etc/init.d/openvpn.something restart
This covers initial config and reconfig. Zero distro changes. How much simpler do you need?
//Peter
Quoted 10 lines · Peter Stuge
Your
/usr/share/udhcpc/default.scriptto accomplish this would be:#!/bin/sh
test "$1" = bound || exit 0
sed -i "/^local /s/.*/local $ip/"/etc/openvpn/something/local.conf/etc/init.d/openvpn.somethingrestartThis covers initial config and reconfig. Zero distro changes. How much simpler do you need?
Actually no, you get to also apply address changes. So more like this:
#!/bin/bash
case "${1}" in
deconfig)
ip a f dev "${interface}"
;;
bound)
ip a a "${ip}/${mask}" dev "${interface}"
ip r a default via "${router}" dev "${interface}"
sed -i "/^local /s/.*/local ${ip}/" /etc/openvpn/something/local.conf /etc/init.d/openvpn.something restart
;;
*)
exit 1
;;
esac
exit 0
(Might work also with plain sh, but this is similar to what I had in production so known working, as opposed to the previous which I just wrote from memory. :)
Suggest you name (or at least symlink) the vpn config to the interface name, then the above can be generic for all interfaces by substituing ${interface} for "something".
//Peter
Hi,
Quoted 4 lines · Peter Stuge
Changing startup scripts or wrapping openvpn is one way. But I would probably drive everything from the DHCP client instead.
As I wrote, udhcpc is very very easy to deal with.
udhcp can notify components if the IP address of a PPP(!) interface changes?
"No DHCP involved on PPP links".
gert
Signature · 4 lines
USENET is *not* the non-clickable part of WWW!
//www.muc.de/~gert/
Gert Doering - Munich, Germany [email protected]...
fax: +49-89-35655025 [email protected]...Quoted 7 lines · Gert Doering
Quoted 2 lines
Changing startup scripts or wrapping openvpn is one way. But I would probably drive everything from the DHCP client instead.
udhcp can notify components if the IP address of a PPP(!) interface changes?
"No DHCP involved on PPP links".
Was this for PPP? Sorry then, I completely overlooked that! I'm fortunate to not have to deal with many PPP links now, but I have, and pppd of course /etc/ppp/ip-up and -down where the same info about (de/re)config is available as in the udhcpc script.
//Peter
Hi,
Quoted 4 lines · Peter Stuge
Was this for PPP? Sorry then, I completely overlooked that! I'm fortunate to not have to deal with many PPP links now, but I have, and pppd of course
/etc/ppp/ip-upand -down where the same info about (de/re)config is available as in the udhcpc script.
Which is actually somewhat underlining the point :-) - if you absolutely need to do this outside of OpenVPN, it can be done, but how to do that depends on interface technology used, specific distribution used (what if your distribution doesn't *have* udhcp?), etc.
Personally, I tend to
- either do it by run-time-parsing of "ip addr show" and feeding to "openvpn --local $ip" in a script-wrapper
- or try to understand why this is needed in the first place :-) - I still don't understand why not binding to anything + --multihome isn't working
As for including the patch, in either form, I'd rather wait for the to-be-implemented-and-cleaned-up "multi-listen" infrastructure that someone will hopefully implement for 2.3...
gert
Signature · 4 lines
USENET is *not* the non-clickable part of WWW!
//www.muc.de/~gert/
Gert Doering - Munich, Germany [email protected]...
fax: +49-89-35655025 [email protected]...Quoted 10 lines · Gert Doering
Quoted 4 lines · Peter Stuge
Was this for PPP? Sorry then, I completely overlooked that! I'm fortunate to not have to deal with many PPP links now, but I have, and pppd of course
/etc/ppp/ip-upand -down where the same info about (de/re)config is available as in the udhcpc script.Which is actually somewhat underlining the point :-) - if you absolutely need to do this outside of OpenVPN, it can be done, but how to do that depends on interface technology used, specific distribution used (what if your distribution doesn't *have* udhcp?), etc.
Sure, but in any case it remains quite trivial.
Quoted 2 lines
- or try to understand why this is needed in the first place :-) - I still don't understand why not binding to anything + --multihome isn't working
Third time: Multiple openvpn daemons on different interfaces and same port.
Quoted 3 lines
As for including the patch, in either form, I'd rather wait for the to-be-implemented-and-cleaned-up "multi-listen" infrastructure that someone will hopefully implement for 2.3...
+1
//Peter
Hi,
Quoted 5 lines · Peter Stuge
Quoted 2 lines
- or try to understand why this is needed in the first place :-) - I still don't understand why not binding to anything + --multihome isn't working
Third time: Multiple openvpn daemons on different interfaces and same port.
That's one possible use case, but not how I understood Federico.
gert
Signature · 4 lines
USENET is *not* the non-clickable part of WWW!
//www.muc.de/~gert/
Gert Doering - Munich, Germany [email protected]...
fax: +49-89-35655025 [email protected]...-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Quoted 3 lines · David Sommerseth
As Davide Brini already mentioned, I really wonder if this issue is due to lack of --multihome in your configuration, combined with listen on 0.0.0.0.
Thank you for restating Davide's answer, which I somehow missed (and thanks to Davide too, of course!). Indeed, this solved that portion of the problem, which is great!
Fede
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
iD8DBQFNfpl1bPULDL0CxuARAtZJAKCU9x1l7/j8DPP05p0FA/QCrLJdIgCfYaaa 1DX+tvBQSuDEQw+Pr4s5958=
=/q5P
-----END PGP SIGNATURE-----
Quoted 3 lines · Gert Doering
Quoted 2 lines
[...] Multiple openvpn daemons on different interfaces and same port.
That's one possible use case, but not how I understood Federico.
That's part of my use case, not all.
Please let me summarize what I've read in this discussion:
* some people are unconvinced there's a real use case for specifying an interface OpenVPN should use as local, and therefore there's no need for action. I have tried to explain that a use case exists, in connection with multiple ISPs and, being confronted with just such a use case, I find it hard to agree with them.
* some other people agree that there is a use case, but propose different ways of approaching the problem through various mechanisms to resolve the interface name to an IP address before passing it on to OpenVPN. The disagreement here seems to be in how such a use case should be handled. Sure, those approaches work, and I tried them myself before diving into the source code. The problem is I don't think that a supported use case should need such involved procedures, and while these may be more or less complicated, none of them is as simple as being able to specify "if:pppo" in the 'local' directive. As a matter of fact, the last suggestion from Peter has more code in it than the code portion of my suggested patches.
I don't know what else I can do to show the first group of people that a use case exists, even if they aren't confronted with it. As to the second group of people, I guess it's a matter of drawing a line:
at one end of the spectrum, we could do away with OpenVPN altogether and implement it in shell code, at the other end we would have a gazillion configuration options so that we could turn OpenVPN into an HTTP server just touching config files.
I think the proposed change would be a useful addition to the project, but I respect your judgement if you disagree.
Fede
Quoted 8 lines · Federico Heinz
* some other people agree that there is a use case, but propose different ways of approaching the problem through various mechanisms to resolve the interface name to an IP address before passing it on to OpenVPN. The disagreement here seems to be in how such a use case should be handled. Sure, those approaches work, and I tried them myself before diving into the source code. The problem is I don't think that a supported use case should need such involved procedures,
This is exactly the point for me. Until OpenVPN can listen on all IP addresses on the given interface, it must not try to use interface terms at all. So IMO the feature depends on multilisten, without which listening on an interface is not yet supported.
What *is* supported is to listen to a specific IP. It's a rudimentary feature for all IP daemons. Better solutions are possible, but for now this is what is there. This is still useful when taking advantage of hooks in the configuration event source.
When multilisten is in place and listen-on-interface is proposed again, I think we must discuss whether OpenVPN should automatically detect reconfiguration of an interface. I tend to think that yes it should do that. But on the other hand that code will be a bit involved since no two systems work the same way. The alternative is to have external helpers which hook into reconfiguration event sources, but that's not so elegant.
Quoted 5 lines
and while these may be
more or less complicated, none of them is as simple as being able to specify "if:pppo" in the 'local' directive. As a matter of fact, the last suggestion from Peter has more code in it than the code portion of my suggested patches.
On the other hand it has the significant benefit of connecting the *actual* configuration event source directly with OpenVPN. When dealing with dynamic configurations it's critical not to create a race condition, so anything that does not connect and sync with actual event source should be out of the question.
Quoted 4 lines
As to the second group of people, I guess it's a matter of drawing a line:
at one end of the spectrum, we could do away with OpenVPN altogether and implement it in shell code,
Sorry, but this makes no sense. Feel free to rewrite the (re)config event handler in C if you prefer. That can certainly have benefits over the shell script. I showed you something that works that I use.
See above for my feature-nak rationale. It can certainly change to ack in the future when OpenVPN has better infrastructure to support the feature.
Quoted 1 line
we could turn OpenVPN into an HTTP server just touching config files.
Yes please! :)
Quoted 2 lines
I think the proposed change would be a useful addition to the project, but I respect your judgement if you disagree.
I disagree at the moment, because of lack of multilisten and reconfiguration tracking.
The only other programs I can think of that deal in terms of interfaces are low level network monitoring tools. tcpdump, ethtool etc, specifically because they operate below IP level. What you propose is simply not thorough enough for me to like it, if OpenVPN is to climb one step down in the layers and also deal in interfaces. I'm not saying I never want it to, but that it needs to be better prepared if it is going to try.
//Peter