mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-02-02 19:42:41 +00:00
[MEDIUM] support fully transparent proxy on Linux (USE_LINUX_TPROXY)
Using some Linux kernel patches, it is possible to redirect non-local traffic to local sockets when IP forwarding is enabled. In order to enable this option, we introduce the "transparent" option keyword on the "bind" command line. It will make the socket reachable by remote sources even if the destination address does not belong to the machine.
This commit is contained in:
parent
fe10a0619d
commit
b1e52e8c44
6
Makefile
6
Makefile
@ -19,6 +19,7 @@
|
||||
# USE_STATIC_PCRE : enable static libpcre. Recommended.
|
||||
# USE_TCPSPLICE : enable tcp_splice() on Linux (needs kernel patch).
|
||||
# USE_TPROXY : enable transparent proxy. Automatic.
|
||||
# USE_LINUX_TPROXY : enable full transparent proxy (need kernel patch).
|
||||
#
|
||||
# Options can be forced by specifying "USE_xxx=1" or can be disabled by using
|
||||
# "USE_xxx=" (empty string).
|
||||
@ -291,6 +292,11 @@ OPTIONS_CFLAGS += -DTPROXY
|
||||
BUILD_OPTIONS += $(call ignore_implicit,USE_TPROXY)
|
||||
endif
|
||||
|
||||
ifneq ($(USE_LINUX_TPROXY),)
|
||||
OPTIONS_CFLAGS += -DCONFIG_HAP_LINUX_TPROXY
|
||||
BUILD_OPTIONS += $(call ignore_implicit,USE_LINUX_TPROXY)
|
||||
endif
|
||||
|
||||
ifneq ($(USE_POLL),)
|
||||
OPTIONS_CFLAGS += -DENABLE_POLL
|
||||
OPTIONS_OBJS += src/ev_poll.o
|
||||
|
@ -2,9 +2,9 @@
|
||||
HAProxy
|
||||
Configuration Manual
|
||||
----------------------
|
||||
version 1.3.14.2
|
||||
version 1.3.15
|
||||
willy tarreau
|
||||
2008/01/05
|
||||
2008/01/13
|
||||
|
||||
|
||||
This document covers the configuration language as implemented in the version
|
||||
@ -758,19 +758,30 @@ balance <algorithm> [ <arguments> ]
|
||||
|
||||
|
||||
bind [<address>]:<port> [, ...]
|
||||
bind [<address>]:<port> [, ...] transparent
|
||||
Define one or several listening addresses and/or ports in a frontend.
|
||||
May be used in sections : defaults | frontend | listen | backend
|
||||
no | yes | yes | no
|
||||
Arguments :
|
||||
<address> is optional and can be a host name, an IPv4 address, an IPv6
|
||||
address, or '*'. It designates the address the frontend will
|
||||
listen on. If unset, all IPv4 addresses of the system will be
|
||||
listened on. The same will apply for '*' or the system's special
|
||||
address "0.0.0.0".
|
||||
<address> is optional and can be a host name, an IPv4 address, an IPv6
|
||||
address, or '*'. It designates the address the frontend will
|
||||
listen on. If unset, all IPv4 addresses of the system will be
|
||||
listened on. The same will apply for '*' or the system's
|
||||
special address "0.0.0.0".
|
||||
|
||||
<port> is the TCP port number the proxy will listen on. The port is
|
||||
mandatory. Note that in the case of an IPv6 address, the port is
|
||||
always the number after the last colon (':').
|
||||
<port> is the TCP port number the proxy will listen on. The port is
|
||||
mandatory. Note that in the case of an IPv6 address, the port
|
||||
is always the number after the last colon (':').
|
||||
|
||||
transparent is an optional keyword which is supported only on certain
|
||||
Linux kernels. It indicates that the addresses will be bound
|
||||
even if they do not belong to the local machine. Any packet
|
||||
targetting any of these addresses will be caught just as if
|
||||
the address was locally configured. This normally requires
|
||||
that IP forwarding is enabled. Caution! do not use this with
|
||||
the default address '*', as it would redirect any traffic for
|
||||
the specified port. This keyword is available only when
|
||||
HAProxy is built with USE_LINUX_TPROXY=1.
|
||||
|
||||
It is possible to specify a list of address:port combinations delimited by
|
||||
commas. The frontend will then listen on all of these addresses. There is no
|
||||
|
@ -2,7 +2,7 @@
|
||||
include/common/compat.h
|
||||
Operating system compatibility interface.
|
||||
|
||||
Copyright (C) 2000-2006 Willy Tarreau - w@1wt.eu
|
||||
Copyright (C) 2000-2008 Willy Tarreau - w@1wt.eu
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
@ -66,6 +66,13 @@
|
||||
#include <linux/netfilter_ipv4.h>
|
||||
#endif
|
||||
|
||||
/* On Linux, IP_TRANSPARENT generally requires a kernel patch */
|
||||
#if defined(CONFIG_HAP_LINUX_TPROXY)
|
||||
#if !defined(IP_TRANSPARENT)
|
||||
#define IP_TRANSPARENT 19
|
||||
#endif /* !IP_TRANSPARENT */
|
||||
#endif /* CONFIG_HAP_LINUX_TPROXY */
|
||||
|
||||
/* We'll try to enable SO_REUSEPORT on Linux 2.4 and 2.6 if not defined.
|
||||
* There are two families of values depending on the architecture. Those
|
||||
* are at least valid on Linux 2.4 and 2.6, reason why we'll rely on the
|
||||
|
@ -2,7 +2,7 @@
|
||||
include/types/protocols.h
|
||||
This file defines the structures used by generic network protocols.
|
||||
|
||||
Copyright (C) 2000-2007 Willy Tarreau - w@1wt.eu
|
||||
Copyright (C) 2000-2008 Willy Tarreau - w@1wt.eu
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
@ -65,6 +65,7 @@
|
||||
/* listener socket options */
|
||||
#define LI_O_NONE 0x0000
|
||||
#define LI_O_NOLINGER 0x0001 /* disable linger on this socket */
|
||||
#define LI_O_FOREIGN 0x0002 /* permit listening on foreing addresses */
|
||||
|
||||
/* The listener will be directly referenced by the fdtab[] which holds its
|
||||
* socket. The listener provides the protocol-specific accept() function to
|
||||
|
@ -728,6 +728,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int inv)
|
||||
|
||||
/* Now let's parse the proxy-specific keywords */
|
||||
if (!strcmp(args[0], "bind")) { /* new listen addresses */
|
||||
struct listener *last_listen;
|
||||
if (curproxy == &defproxy) {
|
||||
Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
|
||||
return -1;
|
||||
@ -740,9 +741,30 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int inv)
|
||||
file, linenum, args[0]);
|
||||
return -1;
|
||||
}
|
||||
curproxy->listen = str2listener(args[1], curproxy->listen);
|
||||
|
||||
last_listen = curproxy->listen;
|
||||
curproxy->listen = str2listener(args[1], last_listen);
|
||||
if (!curproxy->listen)
|
||||
return -1;
|
||||
if (*args[2]) {
|
||||
#ifdef CONFIG_HAP_LINUX_TPROXY
|
||||
if (!strcmp(args[2], "transparent")) { /* transparently bind to these addresses */
|
||||
struct listener *l;
|
||||
|
||||
for (l = curproxy->listen; l != last_listen; l = l->next)
|
||||
l->options |= LI_O_FOREIGN;
|
||||
}
|
||||
else {
|
||||
Alert("parsing [%s:%d] : '%s' only supports the 'transparent' option.\n",
|
||||
file, linenum, args[0]);
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
Alert("parsing [%s:%d] : '%s' supports no option after the address list.\n",
|
||||
file, linenum, args[0]);
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
global.maxsock++;
|
||||
return 0;
|
||||
}
|
||||
|
@ -153,6 +153,13 @@ int tcp_bind_listener(struct listener *listener, char *errmsg, int errlen)
|
||||
* it might return an error that we will silently ignore.
|
||||
*/
|
||||
setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, (char *) &one, sizeof(one));
|
||||
#endif
|
||||
#ifdef CONFIG_HAP_LINUX_TPROXY
|
||||
if ((listener->options & LI_O_FOREIGN)
|
||||
&& (setsockopt(fd, SOL_IP, IP_TRANSPARENT, (char *) &one, sizeof(one)) == -1)) {
|
||||
msg = "cannot make listening socket transparent";
|
||||
err |= ERR_ALERT;
|
||||
}
|
||||
#endif
|
||||
if (bind(fd, (struct sockaddr *)&listener->addr, listener->proto->sock_addrlen) == -1) {
|
||||
err |= ERR_RETRYABLE | ERR_ALERT;
|
||||
|
Loading…
Reference in New Issue
Block a user