[prev in list] [next in list] [prev in thread] [next in thread] 

List:       haproxy
Subject:    Re: [PATCH] bind non local ip on FreeBSD
From:       joris dedieu <joris.dedieu () gmail ! com>
Date:       2010-11-24 19:55:53
Message-ID: AANLkTinZt0+sH3PSipU3Fsj0ct5d_ewj2MZD3QWP0z4D () mail ! gmail ! com
[Download RAW message or body]

2010/11/24 Willy Tarreau <w@1wt.eu>:
> On Tue, Nov 23, 2010 at 05:28:26PM +0300, Alexandre Snarskii wrote:
>> On Mon, Nov 22, 2010 at 02:03:42PM +0100, joris dedieu wrote:
>> > Hi list,
>> > FreeBSD (and maybe other BSD) use IP_BINDANY flag to permite bind() to
>> > bind a non local ip
>>
>> Please note that this flag is available only since FreeBSD 8,
>> so your patch will break haproxy builds on older versions, like
>> FreeBSD 7.* or 6.*.
>
> In my opinion, we should not have a build option for this, we should
> just rely on the definition of the IP_BINDANY macro. And the config
> option must always be parsed, then we should report "unsupported on
> this build" if IP_BINDANY is not defined, so that users don't waste
> hours trying to figure why their keyword is rejected.

I tried to do something this way. I included openbsd's SO_BINDANY and
the old IP_NONLOCALOK (see
http://lists.freebsd.org/pipermail/svn-src-all/2009-June/009805.html
).

>
> I too am for a "non-local" bind option if this is required. I was wondering,
> isn't there a system-global option to allow non-local binding as on Linux ?

No there is not. There were a kernel build option which was removed.
But in any case you need a userland explicit decision.

> I still fail to see why doing so requires special privileges, the user is
> not adding nor removing any IP from the system !

Well I investigate this point. In fact there is no root privilege
needed but the PRIV_NETINET_BINDANY privilege. So as far as has I know
It could be configured with the mandatory access control (mac).

Regards
Joris
>
> Regards,
> Willy
>
>

["haproxy-non-local.patch" (application/octet-stream)]

diff --git a/include/types/protocols.h b/include/types/protocols.h
index 3dcb2e7..67f654b 100644
--- a/include/types/protocols.h
+++ b/include/types/protocols.h
@@ -75,6 +75,7 @@
 #define LI_O_TCP_RULES  0x0010  /* run TCP rules checks on the incoming connection \
*/  #define LI_O_CHK_MONNET 0x0020  /* check the source against a monitor-net rule */
 #define LI_O_ACC_PROXY  0x0040  /* find the proxied address in the first request \
line */ +#define LI_O_NON_LOCAL  0x0080  /* allow to bind a non local ip */ 
 
 /* The listener will be directly referenced by the fdtab[] which holds its
  * socket. The listener provides the protocol-specific accept() function to
diff --git a/src/cfgparse.c b/src/cfgparse.c
index d3223ff..ba7f393 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -1733,6 +1733,15 @@ int cfg_parse_listen(const char *file, int linenum, char \
**args, int kwm)  continue;
 			}
 
+			if (!strcmp(args[cur_arg], "non-local")) { 
+				struct listener *l;
+
+				for (l = curproxy->listen; l != last_listen; l = l->next)
+					l->options |= LI_O_NON_LOCAL;
+				 cur_arg ++;
+				 continue;
+			}
+
 			if (!strcmp(args[cur_arg], "name")) {
 				struct listener *l;
 
@@ -1872,7 +1881,7 @@ int cfg_parse_listen(const char *file, int linenum, char \
**args, int kwm)  continue;
                         }
 
-			Alert("parsing [%s:%d] : '%s' only supports the 'transparent', 'accept-proxy', \
'defer-accept', 'name', 'id', 'mss' and 'interface' options.\n", +			Alert("parsing \
[%s:%d] : '%s' only supports the 'transparent', 'accept-proxy', 'defer-accept', \
'name', 'non-local', 'id', 'mss' and 'interface' options.\n",  file, linenum, \
args[0]);  err_code |= ERR_ALERT | ERR_FATAL;
 			goto out;
diff --git a/src/proto_tcp.c b/src/proto_tcp.c
index 5039db8..48f7384 100644
--- a/src/proto_tcp.c
+++ b/src/proto_tcp.c
@@ -527,6 +527,25 @@ int tcp_bind_listener(struct listener *listener, char *errmsg, \
int errlen)  }
 	}
 #endif
+	if (listener->options & LI_O_NON_LOCAL) {
+#if defined(IP_BINDANY) || defined(IP_NONLOCALOK)
+		if (setsockopt(fd, IPPROTO_IP, 24, (char *) &one, sizeof(one)) == -1) {
+		    	err |= ERR_RETRYABLE | ERR_ALERT;
+				msg = "cannot set IP_BINDANY";
+			goto tcp_close_return;
+		} 
+#elif defined(SO_BINDANY)
+		if (setsockopt(fd, SOL_SOCKET, SO_BINDANY, (char *) &one, sizeof(one)) == -1) {
+		    	err |= ERR_RETRYABLE | ERR_ALERT;
+			msg = "cannot set SO_BINDANY";
+			goto tcp_close_return;
+		}
+#else
+		msg = "non-local option has no effect on this platform";
+		err |= ERR_WARN;
+#endif
+	}
+
 	if (bind(fd, (struct sockaddr *)&listener->addr, listener->proto->sock_addrlen) == \
-1) {  err |= ERR_RETRYABLE | ERR_ALERT;
 		msg = "cannot bind socket";



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic