Stunnel patch instructions to send X-forwarded-for ip address

3,204 views
Skip to first unread message

leop...@gmail.com

unread,
Jun 13, 2013, 11:04:20 PM6/13/13
to ratch...@googlegroups.com
Before you begin:

This modification on the botton is for persons that are using Stunnel WHITHOUT Haproxy

If you are using Stunnel + Haproxy, then you can use the proxy options:
STunnel 4.45 version comes with a proxy protocol that works with HAProxy 1.15 and later versions.

Inside stunnel.conf ==> protocol = proxy

Inside ha-proxy configuration ==> frontend frontend_name_that_you_choose *:81 accept-proxy


Now, let´s talk about stunnel+ratchet solution without ha-proxy:

On my server I use ratchet+stunnel only (apache for pages). 
As the proxy option was not available for me as is available for ha-proxy, I had to search for a way to send the ip address from the client to use at ratchet server. 

BEFORE YOU BEGIN SAVE YOUR STUNNEL CONFIGURATION FILE AND CERTIFICATES!!!!
wget https://www.stunnel.org/downloads/stunnel-4.56.tar.gz

tar -zxvf stunnel-4.56.tar.gz

cd stunnel-4.56

wget https://gist.github.com/rraptorr/5599557/raw/0f1335bb9bdb37886d1634d27104a51e90d38c1c/stunnel-4.56-xforwarded-for.diff

patch -P1 < stunnel-4.56-xforwarded-for.diff

./configure (watch for openssl errors/warnings. On mine I had to yum install openssl-devel)

make

make install



If you reach this point your are almost good to go!

Just add this conf inside stunnel.conf: xforwardedfor = yes


How to access header from ratchet:

$myvar= $conn->WebSocket->request->getHeader('X-Forwarded-For', true);



Personal notes:

I don´t like using X-forwarded-for on my systems. 
This is a very common header and for security reasons, as we are patching the code from source, why not change the header name?

Also, let´s assume that the client is acessing stunnel from a proxy system:

Client ==> Proxy ==> Stunnel ==> Ratchet
                    | Ip from proxy will be received by stunnel 
                      and maybe the real client ip address will be at X-forwarded-for header
In this case above, if we use the x-forwarded-for header patch. We will overwrite the real client ip address and will receive the proxy address only. 


So, for both reasons, let´s change the header for a crazy and private one!


Inside stunnel source directory, enter src folder and edit client.c

on the code
, find this line:

/* X-Forwarded-For: xxxx \r\n\0 */
                       
char xforw[17 + IPLEN + 3];

Now you can change for something personal and private, like mine:

 /* X-Forwarded-For: xxxx \r\n\0 */
                       
char xforw[24 + IPLEN + 3];

                       
/* We have all the HTTP headers now. We don't need to
                        * reserve any space anymore. <ssl_ptr> points to the
                        * first byte of unread data, and <last> points to the
                        * exact location where we want to insert our headers,
                        * which is right before the empty line.
                        */

                        c
->buffsize = BUFFSIZE;

                       
/* We will insert our X-Forwarded-For: header here.
                         * We need to write the IP address, but if we use
                         * sprintf, it will pad with the terminating 0.
                         * So we will pass via a temporary buffer allocated
                         * on the stack.
                         */

                        memcpy
(xforw, "IP_Stunnel_Patch_Pucci: ", 24);
                       
if (getnameinfo(&c->peer_addr.sa,
                            c
->peer_addr_len,
                            xforw
+ 24, IPLEN, NULL, 0,
                            NI_NUMERICHOST
) == 0) {
                            strcat
(xforw + 24, "\r\n");
                            buffer_insert
(c->ssl_buff, &last, &c->ssl_ptr,
                                c
->buffsize, xforw);
                       
}
                       
/* last still points to the \r\n and ssl_ptr to the
                         * end of the buffer, so we may add as many headers
                         * as wee need to.
                         */



So now I can access either the ip addres from the internet and also when a proxy redirects for me:

$ipfrominternet= $conn->WebSocket->request->getHeader('IP_Stunnel_Patch_Pucci', true);
$internalipsendbyproxy = $conn->WebSocket->request->getHeader('X-Forwarded-For', true);




Some dudes commented that this workaround will send the ip address only during the first http message. 
If some kind of http keepalive is used. The ip address will not be available in the subsequent packages.

From the ratchet point of view, seems that ratchet knows about this and saves the header during the connection duration. 
I tested a little and could get the ip address inside OnConnection() and OnMessage()


Any questions or doubts, feel free to write here

Thanks,

Pucci

Leonardo Pucci

unread,
May 2, 2014, 10:08:05 AM5/2/14
to ratch...@googlegroups.com
(I did not found how I could update my previous post)
Just an update, 

To access Guzzle htttp header you need WSServer (that have the http header) on  your configuration. 


On ratchet 0.2:

/*use Ratchet\Server\IoServer;
use Ratchet\WebSocket\WsServer;
use MyApp\Chat;
    require dirname(__DIR__) . '/vendor/autoload.php';

    $server = IoServer::factory(
        new WsServer(
            new Chat()
        )
      , 8080
    );

    $server->run();


On Ratchet 0.3:

use Ratchet\WebSocket\WsServer;
use Ratchet\Http\HttpServer;
use Ratchet\Server\IoServer;
use MyApp\Chat;

    require dirname(__DIR__) . '/vendor/autoload.php';

$ws = new WsServer(new Chat());
    $ws->disableVersion(0); // old, bad, protocol version

    // Make sure you're running this as root
    $server = IoServer::factory(new HttpServer($ws),8080);
    $server->run();

Leonardo Pucci

unread,
Jul 8, 2014, 10:46:10 AM7/8/14
to ratch...@googlegroups.com
This patch has been updated. 

You can find the latest version of stunnel (5.02) with the mod here:

Remember that this is my personal patch:
$ipfrominternet= $conn->WebSocket->request->getHeader('IP_Stunnel_Patch_Pucci', true);

If you want the original xforwarded-for patch, you can found it here:
https://github.com/level7systems/stunnel/archive/master.zip

Reply all
Reply to author
Forward
0 new messages