[Pound Mailing List] Pound 2.7 and TProxy
Scott McKeown <scott-Oteo70RhwZ77w/[email protected]>
| Newsgroups | gmane.comp.web.pound.general |
|---|---|
| Message-ID | <[email protected]> |
Hello Everyone,
I've finally got to admit defeat on getting this patch to work and I was
wondering if anyone out there could please give me a hand getting this to
work.
I've attached the patch file for anyone to play with but what I'm trying to
do is get Unix TProxy to work with pound 2.7 again, the original version of
this patch has been working since pound v2.4.
Anyhow, the patch compiles into the latest version but if you add "TProxy
1" into the configuration you get a 'unknown directive' error
*Config File:*
# cat /etc/pound/pound.cfg
# Pound configuration file generated by loadbalancer.org appliance
User "nobody"
Group "nobody"
LogLevel 0
Client 30
Timeout 60
Threads 250
TProxy 1
ListenHTTPS
# Label: pound1
Address 192.168.63.59
Port 443
Cert "/etc/loadbalancer.org/certs/server.pem"
xHTTP 3
ReWriteLocation 1
Ciphers
"ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS"
SSLHonorCipherOrder 1
SSLAllowClientRenegotiation 0
Disable SSLv2
Disable SSLv3
Service
BackEnd
Address 192.168.64.254
Port 80
TProxy 1
End
End
End
*Start Up:*
# /usr/local/sbin/pound
starting...
detect_tproxy(): tproxy is is detected
tproxy: available
/etc/pound/pound.cfg line 8: unknown directive - aborted
--
With Kind Regards.
Scott McKeown
Loadbalancer.org
http://www.loadbalancer.org
Tel (UK) - +44 (0) 3303801064 (24x7)
Tel (US) - +1 888.867.9504 (Toll Free)(24x7)
pound_2.7_tproxy.patch
(application/octet-stream, 10.4 KB)
--- /config.c
+++ /config.c
@@ -81,6 +81,9 @@
static regex_t ClientCert, AddHeader, DisableProto, SSLAllowClientRenegotiation, SSLHonorCipherOrder, Ciphers;
static regex_t CAlist, VerifyList, CRLlist, NoHTTPS11, Grace, Include, ConnTO, IgnoreCase, HTTPS;
static regex_t Disabled, Threads, CNName, Anonymise, ECDHCurve;
+#ifdef TPROXY_ENABLE
+static regex_t TProxy;
+#endif
static regmatch_t matches[5];
@@ -250,6 +250,9 @@
res->url = NULL;
res->next = NULL;
has_addr = has_port = 0;
+#ifdef TPROXY_ENABLE
+ res->tp_enabled = 0;
+#endif
pthread_mutex_init(&res->mut, NULL);
while(conf_fgets(lin, MAXBUF)) {
if(strlen(lin) > 0 && lin[strlen(lin) - 1] == '\n')
@@ -415,6 +415,10 @@
if((res->addr.ai_family == AF_INET || res->addr.ai_family == AF_INET6) && !has_port)
conf_err("BackEnd missing Port - aborted");
return res;
+#ifdef TPROXY_ENABLE
+ } else if(!regexec(&TProxy, lin, 4, matches, 0)) {
+ if (enable_tproxy && have_tproxy) res->tp_enabled = atoi(lin + matches[1].rm_so);
+#endif
} else {
conf_err("unknown directive");
}
@@ -1282,6 +1282,13 @@
#endif
}
return res;
+#ifdef TPROXY_ENABLE
+ } else if(!regexec(&TProxy, lin, 4, matches, 0)) {
+ if (have_tproxy)
+ enable_tproxy = atoi(lin + matches[1].rm_so);
+ else
+ enable_tproxy = 0;
+#endif
} else {
conf_err("unknown directive");
}
@@ -1492,6 +1492,9 @@
|| regcomp(&VerifyList, "^[ \t]*VerifyList[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&CRLlist, "^[ \t]*CRLlist[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&NoHTTPS11, "^[ \t]*NoHTTPS11[ \t]+([0-2])[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
+#ifdef TPROXY_ENABLE
+ || regcomp(&TProxy, "^[ \t]*TProxy[ \t]+([01])[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
+#endif
|| regcomp(&Include, "^[ \t]*Include[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&ConnTO, "^[ \t]*ConnTO[ \t]+([1-9][0-9]*)[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&IgnoreCase, "^[ \t]*IgnoreCase[ \t]+([01])[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
@@ -1662,6 +1662,9 @@
regfree(&VerifyList);
regfree(&CRLlist);
regfree(&NoHTTPS11);
+#ifdef TPROXY_ENABLE
+ regfree(&TProxy);
+#endif
regfree(&Include);
regfree(&ConnTO);
regfree(&IgnoreCase);
--- /http.c
+++ /http.c
@@ -855,7 +855,12 @@
clean_all();
return;
}
- if(connect_nb(sock, &backend->addr, backend->conn_to) < 0) {
+
+#ifdef TPROXY_ENABLE
+ if(connect_nb(sock, &backend->addr, backend->to, backend->tp_enabled ? &from_host : NULL) < 0) {
+#else
+ if(connect_nb(sock, &backend->addr, backend->to) < 0) {
+#endif
str_be(buf, MAXBUF - 1, backend);
logmsg(LOG_WARNING, "(%lx) backend %s connect: %s", pthread_self(), buf, strerror(errno));
shutdown(sock, 2);
diff -urN Makefile.in Makefile.in
--- Makefile.in
+++ Makefile.in
@@ -25,18 +25,9 @@
CC=@PTHREAD_CC@
-C_TPROXY=
-
-TPROXY=0
-
-ifeq (${TPROXY}, 1)
- $(if $(findstring "@target_os@", "linux-gnu"),,$(error TPROXY can be used just with Linux))
- C_TPROXY=-DTPROXY_ENABLE
-endif
-
CFLAGS=-DF_CONF=\"@sysconfdir@/pound.cfg\" -DVERSION=\"@PACKAGE_VERSION@\" -DC_SSL=\"@C_SSL@\" -DC_T_RSA=\"@C_T_RSA@\" \
-DC_DH_LEN=\"@C_DH_LEN@\" -DC_MAXBUF=\"@C_MAXBUF@\" -DC_OWNER=\"@C_OWNER@\" -DC_GROUP=\"@C_GROUP@\" \
- -DC_SUPER=\"@C_SUPER@\" -DC_CERT1L=\"@C_CERT1L@\" @CFLAGS@ @PTHREAD_CFLAGS@ @CPPFLAGS@ ${C_TPROXY}
+ -DC_SUPER=\"@C_SUPER@\" -DC_CERT1L=\"@C_CERT1L@\" @CFLAGS@ @PTHREAD_CFLAGS@ @CPPFLAGS@
LIBS=@LIBS@ @PTHREAD_LIBS@
prefix=@prefix@
diff -urN pound.h pound.h
--- pound.h
+++ pound.h
@@ -241,6 +241,14 @@
#define const
#endif
+#ifdef TPROXY_ENABLE
+#include <sys/prctl.h>
+#include <linux/capability.h>
+#ifndef IP_TRANSPARENT
+#define IP_TRANSPARENT 19
+#endif
+#endif
+
#ifdef HAVE_LONG_LONG_INT
#define LONG long long
#define L0 0LL
@@ -275,6 +275,11 @@
grace, /* grace period before shutdown */
control_sock; /* control socket */
+#ifdef TPROXY_ENABLE
+extern int have_tproxy, /* is tproxy available */
+ enable_tproxy; /* is tproxy enabled */
+#endif
+
extern regex_t HEADER, /* Allowed header */
CHUNK_HEAD, /* chunk header line */
RESP_SKIP, /* responses for which we skip response */
@@ -320,6 +320,9 @@
int to; /* read/write time-out */
int conn_to; /* connection time-out */
struct addrinfo ha_addr; /* HA address/port */
+#ifdef TPROXY_ENABLE
+ int tp_enabled; /* TProxy is enabled */
+#endif
char *url; /* for redirectors */
int redir_req; /* the redirect should include the request path */
SSL_CTX *ctx; /* CTX for SSL connections */
@@ -579,7 +579,12 @@
* Non-blocking version of connect(2). Does the same as connect(2) but
* ensures it will time-out after a much shorter time period CONN_TO.
*/
+#ifdef TPROXY_ENABLE
+extern int detect_tproxy(void);
+extern int connect_nb(const int, const struct addrinfo *, const int, const struct addrinfo *);
+#else
extern int connect_nb(const int, const struct addrinfo *, const int);
+#endif
/*
* Parse arguments/config file
diff -urN svc.c svc.c
--- svc.c
+++ svc.c
@@ -372,6 +372,40 @@
return res - kp_res;
}
+#ifdef TPROXY_ENABLE
+/*
+ * detect_tproxy
+ * check for TPROXY
+ *
+ * Thanks to Loadbalancer.org, Inc. especially to Malcolm Turnbull for sponsorship
+ * Thanks to Sianet Business Hosting especially to Rodrigo L. L. Jorge for sponsorship
+ *
+ */
+int
+detect_tproxy(void)
+{
+ int sock, tp_val;
+
+ tp_val = 1;
+
+ sock = socket(AF_INET, SOCK_STREAM, 0);
+ if (sock < 0) {
+ logmsg(LOG_WARNING, "detect_tproxy(): socket SOCK_STREAM failed: %s", strerror(errno));
+ return 1;
+ }
+ if (setsockopt(sock, SOL_IP, IP_TRANSPARENT, &tp_val, sizeof(tp_val)) < 0) {
+ logmsg(LOG_INFO, "detect_tproxy(): tproxy is not available");
+ close(sock);
+ return 1;
+ }
+
+ close(sock);
+ logmsg(LOG_INFO, "detect_tproxy(): tproxy is is detected");
+
+ return 0;
+}
+#endif
+
/*
* Parse a header
* return a code and possibly content in the arg
@@ -922,12 +922,26 @@
* Non-blocking connect(). Does the same as connect(2) but ensures
* it will time-out after a much shorter time period SERVER_TO
*/
+#ifdef TPROXY_ENABLE
int
-connect_nb(const int sockfd, const struct addrinfo *serv_addr, const int to)
-{
+connect_nb(const int sockfd, const struct addrinfo *serv_addr, const int to, const struct addrinfo *tp_addr) {
+#else
+int
+connect_nb(const int sockfd, const struct addrinfo *serv_addr, const int to) {
+#endif
int flags, res, error;
socklen_t len;
struct pollfd p;
+#ifdef TPROXY_ENABLE
+ int tp_val = 1;
+ struct sockaddr_in in;
+#endif
+
+ if (! serv_addr->ai_addr)
+ {
+ logmsg(LOG_ERR, "cconnect_nb: wrong serv_addr->ai_addr");
+ return -1;
+ }
if((flags = fcntl(sockfd, F_GETFL, 0)) < 0) {
logmsg(LOG_WARNING, "(%lx) connect_nb: fcntl GETFL failed: %s", pthread_self(), strerror(errno));
@@ -937,6 +937,24 @@
logmsg(LOG_WARNING, "(%lx) connect_nb: fcntl SETFL failed: %s", pthread_self(), strerror(errno));
return -1;
}
+
+#ifdef TPROXY_ENABLE
+ if (tp_addr) {
+ memcpy(&in, tp_addr->ai_addr, sizeof(in));
+ in.sin_port = 0;
+ if (setsockopt(sockfd, SOL_IP, IP_TRANSPARENT, &tp_val, sizeof(tp_val)) < 0) {
+ logmsg(LOG_ERR, "(%lx) connect_nb: cannot set TProxy IP_TRANSPARENT socket option. Error: %d, %s.", pthread_self(),
+ error, strerror(error));
+ return -1;
+ }
+
+ if (bind(sockfd, (struct sockaddr *) &in, sizeof(in)) < 0) {
+ logmsg(LOG_ERR, "(%lx) connect_nb: cannot bind to TProxy IP. Error: %d, %s.", pthread_self(),
+ error, strerror(error));
+ return -1;
+ }
+ }
+#endif
error = 0;
if((res = connect(sockfd, serv_addr->ai_addr, serv_addr->ai_addrlen)) < 0)
@@ -1036,7 +1036,12 @@
default:
continue;
}
- if(connect_nb(sock, &be->ha_addr, be->conn_to) != 0) {
+#ifdef TPROXY_ENABLE
+ if(connect_nb(sock, &be->ha_addr, be->conn_to, NULL) != 0)
+#else
+ if(connect_nb(sock, &be->ha_addr, be->conn_to) != 0)
+#endif
+ {
kill_be(svc, be, BE_KILL);
str_be(buf, MAXBUF - 1, be);
logmsg(LOG_NOTICE, "BackEnd %s is dead (HA)", buf);
@@ -1072,7 +1072,12 @@
default:
continue;
}
- if(connect_nb(sock, &be->ha_addr, be->conn_to) != 0) {
+#ifdef TPROXY_ENABLE
+ if(connect_nb(sock, &be->ha_addr, be->conn_to, NULL) != 0)
+#else
+ if(connect_nb(sock, &be->ha_addr, be->conn_to) != 0)
+#endif
+ {
kill_be(svc, be, BE_KILL);
str_be(buf, MAXBUF - 1, be);
logmsg(LOG_NOTICE, "BackEnd %s is dead (HA)", buf);
@@ -1127,7 +1127,12 @@
}
addr = &be->ha_addr;
}
- if(connect_nb(sock, addr, be->conn_to) == 0) {
+#ifdef TPROXY_ENABLE
+ if(connect_nb(sock, addr, be->conn_to, NULL) == 0)
+#else
+ if(connect_nb(sock, addr, be->conn_to) == 0)
+#endif
+ {
be->resurrect = 1;
modified = 1;
}
@@ -1196,7 +1196,12 @@
}
addr = &be->ha_addr;
}
- if(connect_nb(sock, addr, be->conn_to) == 0) {
+#ifdef TPROXY_ENABLE
+ if(connect_nb(sock, addr, be->conn_to, NULL) != 0)
+#else
+ if(connect_nb(sock, &be->ha_addr, be->conn_to) != 0)
+#endif
+ {
be->resurrect = 1;
modified = 1;
}