/ Zope / Apsis / Pound Mailing List / Archive / 2007 / 2007-12 / Pound use real IP instead of virtual IP to call with backends server

[ << ] [ >> ]

[ Problems with "The service is not available. ... ] [ req / sec / aT <pakistan(at)gmail.com> ]

Pound use real IP instead of virtual IP to call with backends server
plutonium239(at)free.fr
2007-12-12 14:34:10 [ FULL ]
Hi,

I have configure pound to work with hearbeat to allow failover between two
servers.
This is my configuration file of pound :

User            "www-data"
Group           "www-data"
LogLevel        3
Alive           2
Control         "/etc/pound/pound.sock"

ListenHTTPS
        Address 192.168.a.xx    # virtual address of my cluster
        Port 443
        Cert "/somewhere/server.pem"
        Ciphers
"ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL"
        HeadRemove "X-SSL-.*"
        HeadRemove "X-Client-Verify.*"
        AddHeader "X-Client-Verify: SUCCESS"
        Service
                BackEnd
                        Address first backend
                        Port    f
                End

                BackEnd
                        Address second backend
                        Port    b
                End

                Session
                        Type    Cookie
                        ID      "session_id"
                        TTL     3600
                End
        End
End




I also configure the firewall to allow access from my Virtual address to
backend.
The problem is : Pound use the real address IP to call with backend (on eth0)
instead of the virtual address IP (192.168.a.xx on eth0:0) that's why the
traffic can't pass through the firewall because there is no rules for.
My target is to configure firewall only with the VIrtual IP address and not
with
many rules ( for both of the real IP of my cluster).

Why pound use Virtual address on the frontend and not on the backend ?

This my architecture :
             heartbeat monitoring
server 1  with pound <---------------------->  server 2 with pound  
(example of
Virtual address 192.168.0.99)
  |                                         here is frontend
  |
firewall (with rules to allow Virtual address 192.168.0.99)
  |
  |                                         here is backend, no traffic because
  |                                         pound doesn't use VIP
Backend server

Re: [Pound Mailing List] Pound use real IP instead of virtual IP to call with backends server
Jacques Caron <jc(at)oxado.com>
2007-12-12 14:59:09 [ FULL ]
At 14:34 12/12/2007, plutonium239(at)free.fr wrote:[...]

It is not pound doing that, but your OS. Any time you open a TCP 
connection (or UDP, for that matter), it picks up the IP address that 
is "most appropriate", i.e. that of the interface it sends the 
traffic through. Try it: do a "telnet backend_ip 80" and see what the 
source IP is...

Pound could not possibly always use the front-end address, as in many 
cases it will be on a box with two interfaces, one "external" where 
it listens for connections, and one "internal" it uses to talk to the 
back-ends. And even if it is the same interface, not everyone wants 
to use the front-end address (some people listen on many addresses, 
but want pound to always use the same IP to connect to the back-ends).

One might consider adding an option to chose the address to bind to 
when opening a new connection, though. Probably a dozen lines of code 
or so... There might be ways to do it at the OS level also, but no 
easy ones come to mind...

Jacques.

Re: [Pound Mailing List] Pound use real IP instead of virtual IP to call with backends server
plutonium239(at)free.fr
2007-12-12 15:32:36 [ FULL ]
Unfortunately I have no choice. In fact, I must use the virtual IP address to
avoid duplication of rules in my firewall and of course securities flaw.
I try to telnet BackendIPServer port_xx but of course, telnet use the address
on
eth0 (the real) and not the address on eth0:0 (the virtual)
But, there is an option with telnet to use specific address :
telnet -b VirtualIP BackendIP BackendPort who works fine.
So, I imagine it's possible to configure OS to do that but how ????


I works on Ubuntu 7.10 server Edition and pound 2.xxx, I don't exactly remember
the version.

Re: [Pound Mailing List] Pound use real IP instead of virtual IP to call with backends server
justin.kinney(at)academy.com
2007-12-12 16:19:41 [ FULL ]
I'm not sure if this is the best solution, but it works for me in brief 
testing (on Ubuntu 7.10).

Here is my test configuration:

eth0 - 10.1.151.108
eth0:0 - 10.1.151.109

I'm using wireshark to capture network traffic.

Before adding any iptables rules, a ping to 10.1.100.132 shows traffic 
coming from 10.1.151.108.

After adding the following rule, pinging 10.1.100.132 reveals traffic 
coming from 10.1.151.109.

# iptables -A OUTPUT --destination 10.1.100.132 -o 10.1.151.109

Using iptables, you should be able to achieve what you're looking for.


Hope this helps,
Justin


Justin Kinney
Academy Sports & Outdoors
Systems Engineer - Linux & Windows
Email: justin.kinney(at)academy.com



From:
plutonium239(at)free.fr
To:
pound(at)apsis.ch
Date:
12/12/2007 08:53 AM
Subject:
Re: [Pound Mailing List] Pound use real IP instead of virtual IP to call 
with backends server


Unfortunately I have no choice. In fact, I must use the virtual IP address 
to
avoid duplication of rules in my firewall and of course securities flaw.
I try to telnet BackendIPServer port_xx but of course, telnet use the 
address on
eth0 (the real) and not the address on eth0:0 (the virtual)
But, there is an option with telnet to use specific address :
telnet -b VirtualIP BackendIP BackendPort who works fine.
So, I imagine it's possible to configure OS to do that but how ????


I works on Ubuntu 7.10 server Edition and pound 2.xxx, I don't exactly 
remember
the version.

--
To unsubscribe send an email with subject unsubscribe to pound(at)apsis.ch.
Please contact roseg(at)apsis.ch for questions.
Attachments:  
text.html text/html 2809 Bytes

Re: [Pound Mailing List] Pound use real IP instead of virtual IP to call with backends server
plutonium239(at)free.fr
2007-12-12 17:22:43 [ FULL ]
It seems to be a good idea; if i understood, the rule you use change the
destination and finally use virtual ip address.
Thanks, i will see that but i want other feedbacks about this problem because
Jacque say it must possibly be a modification to do in OS, so i prefer to have
many field of research to choose the better and safe idea even if i thank you
because, for the moment, you are the one to propose a solution...

Wait for other solution, but i find stupid that pound don't use end-to-end the
virtual IP to do the connection ?!

Re: [Pound Mailing List] Pound use real IP instead of virtual IP to call with backends server
Jacques Caron <jc(at)oxado.com>
2007-12-13 00:39:59 [ FULL ]
Hi again,

At 17:22 12/12/2007, plutonium239(at)free.fr wrote:[...]

I said there could be an OS-specific solution (and indeed I was 
thinking of iptables or something equivalent, but since I don't use 
Linux boxes I'm not familiar with the ways to do that), or one could 
patch pound to do so.

Actually, here's the patch (against 2.3.2, very little testing done):

diff -u Pound-2.3.2.orig/config.c Pound-2.3.2/config.c
--- Pound-2.3.2.orig/config.c   Fri May 18 10:34:53 2007
+++ Pound-2.3.2/config.c        Thu Dec 13 00:23:54 2007
(at)(at) -79,7 +79,7 (at)(at)
  static regex_t  Service, ServiceName, URL, HeadRequire, HeadDeny, 
BackEnd, Emergency, Priority, HAport, HAportAddr;
  static regex_t  Redirect, TimeOut, Session, Type, TTL, ID, DynScale;
  static regex_t  ClientCert, AddHeader, Ciphers, CAlist, VerifyList, 
CRLlist, NoHTTPS11;
-static regex_t  Grace;
+static regex_t  Grace, BindAddress;

  static regmatch_t   matches[5];

(at)(at) -189,6 +189,15 (at)(at)
              }
              memcpy(&res->HA.sin_addr.s_addr, host->h_addr_list[0], 
sizeof(res->HA.sin_addr.s_addr));
              res->HA.sin_port = (in_port_t)htons(atoi(lin + 
matches[2].rm_so));
+        } else if(!regexec(&BindAddress, lin, 4, matches, 0)) {
+            lin[matches[1].rm_eo] = '\0';
+            if((host = gethostbyname(lin + matches[1].rm_so)) == 
NULL || host->h_addr_list[0] == NULL) {
+               logmsg(LOG_ERR, "line %d: could not resolve BackEnd 
BindAddress: %s - aborted", n_lin, lin + matches[1].rm_so);
+               exit(1);
+            } else {
+                res->bindaddr.sin_family = AF_INET;
+                memcpy(&res->bindaddr.sin_addr.s_addr, 
host->h_addr_list[0], sizeof(res->bindaddr.sin_addr.s_addr));
+            }
          } else if(!regexec(&End, lin, 4, matches, 0)) {
              if(!has_addr) {
                  logmsg(LOG_ERR, "line %d: BackEnd missing Address - 
aborted", n_lin);
(at)(at) -1096,6 +1105,7 (at)(at)
      || 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)
+    || regcomp(&BindAddress, "^[ \t]*BindAddress[ \t]+([^ \t]+)[ 
\t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
      ) {
          logmsg(LOG_ERR, "bad config Regex - aborted");
          exit(1);
(at)(at) -1241,6 +1251,7 (at)(at)
      regfree(&VerifyList);
      regfree(&CRLlist);
      regfree(&NoHTTPS11);
+    regfree(&BindAddress);

      /* set the facility only here to ensure the syslog gets opened 
if necessary */
      log_facility = def_facility;
diff -u Pound-2.3.2.orig/http.c Pound-2.3.2/http.c
--- Pound-2.3.2.orig/http.c     Fri May 18 10:34:53 2007
+++ Pound-2.3.2/http.c  Thu Dec 13 00:23:32 2007
(at)(at) -743,6 +743,16 (at)(at)
                      clean_all();
                      pthread_exit(NULL);
                  }
+               if(bind(sock, (struct sockaddr *)&backend->bindaddr, 
(socklen_t)sizeof(backend->bindaddr)) < 0) {
+                    addr2str(caddr, MAXBUF - 1,
&backend->addr.in.sin_addr);
+                   logmsg(LOG_WARNING, "backend %s:%hd bind: %s",
+                        caddr, ntohs(backend->addr.in.sin_port), 
strerror(errno));
+                   close(sock);
+                    err_reply(cl, h503, lstn->err503);
+                    free_headers(headers);
+                    clean_all();
+                    pthread_exit(NULL);
+               }
                  if(connect_nb(sock, (struct sockaddr 
*)&backend->addr.in, (socklen_t)sizeof(backend->addr.in),
backend->to) < 0) {
                      addr2str(caddr, MAXBUF - 1,
&backend->addr.in.sin_addr);
                      logmsg(LOG_WARNING, "backend %s:%hd connect: %s",
diff -u Pound-2.3.2.orig/pound.h Pound-2.3.2/pound.h
--- Pound-2.3.2.orig/pound.h    Fri May 18 10:34:53 2007
+++ Pound-2.3.2/pound.h Thu Dec 13 00:22:53 2007
(at)(at) -285,6 +285,7 (at)(at)
          struct sockaddr_in  in;     /* IPv4 address */
          struct sockaddr_un  un;     /* UNIX "address" */
      }                   addr;
+    struct sockaddr_in bindaddr;   /* address to bind to */
      int                 priority;   /* priority */
      int                 to;
      struct sockaddr_in  HA;         /* HA address & port */
diff -u Pound-2.3.2.orig/svc.c Pound-2.3.2/svc.c
--- Pound-2.3.2.orig/svc.c      Fri May 18 10:34:53 2007
+++ Pound-2.3.2/svc.c   Thu Dec 13 00:24:39 2007
(at)(at) -868,6 +868,10 (at)(at)
          /* try connecting */
          if((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0)
              continue;
+       if(bind(sock, (struct sockaddr *)&be->bindaddr, 
(socklen_t)sizeof(be->bindaddr)) < 0) {
+           close(sock);
+           continue;
+       }
          if(connect_nb(sock, (struct sockaddr *)&be->HA, 
(socklen_t)sizeof(be->HA), be->to) != 0) {
              kill_be(svc, be);
              addr2str(buf, MAXBUF - 1, &be->HA.sin_addr);
(at)(at) -890,6 +894,10 (at)(at)
          /* try connecting */
          if((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0)
              continue;
+       if(bind(sock, (struct sockaddr *)&be->bindaddr, 
(socklen_t)sizeof(be->bindaddr)) < 0) {
+           close(sock);
+           continue;
+       }
          if(connect_nb(sock, (struct sockaddr *)&be->HA, 
(socklen_t)sizeof(be->HA), be->to) != 0) {
              kill_be(svc, be);
              addr2str(buf, MAXBUF - 1, &be->HA.sin_addr);
(at)(at) -909,6 +917,10 (at)(at)
                  continue;
              if((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0)
                  continue;
+           if(be->domain == PF_INET && bind(sock, (struct sockaddr 
*)&be->bindaddr, (socklen_t)sizeof(be->bindaddr)) < 0) {
+               close(sock);
+               continue;
+           }
              if(memcmp(&(be->HA), &z_addr, sizeof(z_addr)) == 0)
                  if(be->domain == PF_INET)
                      addr = (struct sockaddr *)&be->addr.in;
(at)(at) -945,6 +957,10 (at)(at)
                  continue;
              if((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0)
                  continue;
+           if(be->domain == PF_INET && bind(sock, (struct sockaddr 
*)&be->bindaddr, (socklen_t)sizeof(be->bindaddr)) < 0) {
+               close(sock);
+               continue;
+           }
              if(memcmp(&(be->HA), &z_addr, sizeof(z_addr)) == 0)
                  if(be->domain == PF_INET)
                      addr = (struct sockaddr *)&be->addr.in;
diff -u Pound-2.3.2.orig/pound.8 Pound-2.3.2/pound.8
--- Pound-2.3.2.orig/pound.8    Fri May 18 10:34:53 2007
+++ Pound-2.3.2/pound.8 Thu Dec 13 00:38:08 2007
(at)(at) -651,6 +651,9 (at)(at)
  .B Pound
  uses the same address as the back-end server, but you may use a 
separate address
  if you wish. This directive applies only to non Unix-domain servers.
+.TP
+\fBBindAddress\fR address
+An address to be used as the source address for connections to this backend.
  .SH "Emergency"
  The emergency server will be used once all existing back-ends are "dead".
  All configuration directives enclosed between
[...]

As I said, there's certainly nothing stupid there, and there are many 
reasons for pound not to do so by default.

Jacques.

Re: [Pound Mailing List] Pound use real IP instead of virtual IP to call with backends server
plutonium239(at)free.fr
2007-12-13 09:14:17 [ FULL ]
I'm running on 2.2.7-2 version of pound.

I'm not very familiar with source code, so i can't understand the differences
between both version :( In fact, I learn C but not at this level .

So,Is this new version do what I want ?
Moreover, the new version of pound doesn't include daemon like the package
version of Ubuntu 7.10. That's why I choose the simplest version : apt-get
install pound :) , I can't stop and start daemon simply by /etc/init.d/stop or
start without write a script to do that !

As I say, my objective is very simple, limited number of rules in my firewall
and  of course not use real IP in my firewall but virtual IP ...

Re: [Pound Mailing List] Pound use real IP instead of virtual IP to call with backends server
justin.kinney(at)academy.com
2007-12-13 16:01:28 [ FULL ]
plutonium239(at)free.fr wrote on 12/13/2007 02:14:17 AM:
[...]
apt-get[...]
/etc/init.d/stop or[...]

Attached is an init script I wrote (for SuSE Linux) to start up multiple 
instances of pound.  It does this by looking in /usr/local/etc/pound.d/ 
for any file ending in ".conf", and starts a process for that 
configuration file. 

Arguments are as follows:

start - start an instance for each file in /usr/local/etc/pound.d
stop - kill all running instances of pound
status - runs a poundctl -c /tmp/instance.ctl for each instance found in 
/tmp/*.ctl
configtest - does a config check on all config files in 
/usr/local/etc/pound.d

To use, place it in /etc/init.d/ and chmod 755 /etc/init.d/pound

As to the remainder of your question - I think you'll find that the only 
way to do what you're asking for (without modifying source code) is by 
using iptables. 

Hope this helps,
Justin
Attachments:  
text.html text/html 1494 Bytes
pound application/octet-stream 2028 Bytes

Re: [Pound Mailing List] Pound use real IP instead of virtual IP to call with backends server
justin.kinney(at)academy.com
2007-12-13 16:07:32 [ FULL ]
> Attached is an init script I wrote (for SuSE Linux) to start up multiple


Looks like it got stripped...Here it is in text:

**************************************************

#!/bin/sh
#
# Pound Load Balancer
#
### BEGIN INIT INFO
# Provides:       pound
# Required-Start: $remote_fs $syslog $named
# Required-Stop:  $remote_fs $syslog
# Default-Start:  2 3 5
# Default-Stop:   0 1 6
# Description:    Start Pound Load Balance/Reverse Proxy
### END INIT INFO

POUND_CFG_DIR="/usr/local/etc/pound.d"
POUND_CTL_DIR="/tmp"
POUND_BIN="/usr/local/sbin/pound"
POUNDCTL_BIN="/usr/local/sbin/poundctl"

# First reset status of this service
 /etc/rc.status
rc_reset

case "$1" in
    start)
        echo "Starting Pound"
        rm -f $POUND_CTL_DIR/*.ctl
        for i in $POUND_CFG_DIR/*.conf; do
                echo $i
                $POUND_BIN -v -f $i
                rc_status -v
        done
        ;;
    stop)
        echo "Stopping POUND"
        pkill -f $POUND_BIN
        rc_status -v
        ;;
    restart)
        $0 stop
        $0 start
        rc_status
        ;;
    conf*)
        echo "Performing configuration check for files in $POUND_CFG_DIR"
        for i in $POUND_CFG_DIR/*.conf; do
                echo $i
                $POUND_BIN -c -f $i
                rc_status -v
        done
        ;;
    status)
        echo "Pound Status:"
        for i in $POUND_CTL_DIR/*.ctl; do
                echo "$i:"
                $POUNDCTL_BIN -c $i
                rc_status -v
        done
        ;;
    *)
        echo "Usage: $0 <command>"
        echo
        echo "Where <command> is one of:"
        echo "  start              - start a Pound instance for each .conf 
file in $POUND_CFG_DIR"
        echo "  stop               - stop all Pound instances"
        echo "  restart            - stop all Pound instances and start 
them again"
        echo "  status             - check the status of all Pound 
instances"
        echo "  configtest         - do a configuration syntax test on all 
configuration files in $POUND_CFG_DIR"
        exit 1
        ;;
Attachments:  
text.html text/html 6264 Bytes

MailBoxer