[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