Transparent proxying - how to pass socket to local server without modification?

Transparent proxying - how to pass socket to local server without modification?

I have a program that listens on port 443 and then redirects to either an SSH or HTTPS local server depending on the detected protocol.

The program does this by connecting to the local server and proxying all data back and forth through its own process.

However, this causes the originating host on the local servers to be logged as localhost.

Is there any way to pass the socket directly to the local server process (rather than just making a new TCP connection) so that the parameters of sockaddr_in (or sockaddr_in6) will be retained?

Platform for this is Linux.

Which way to go in Linux 3D programming?


PHP exec - check if enabled or disabled
Here is a code snippet taken from stunnel (from client.c in the local_bind function if you want to look at all the code)..
PHP & bash; Linux; Compile my own function
#ifdef IP_TRANSPARENT int on=1; if(c->opt->option.transparent) {     if(setsockopt(c->fd, SOL_IP, IP_TRANSPARENT, &on, sizeof on))         sockerror("setsockopt IP_TRANSPARENT");     /* ignore the error to retain Linux 2.2 compatibility */     /* the error will be handled by bind(), anyway */ } #endif /* IP_TRANSPARENT */  memcpy(&addr, &c->bind_addr.addr[0], sizeof addr); if(ntohs(>=1024) { /* security check */     if(!bind(c->fd, &, addr_len(addr))) {         s_log(LOG_INFO, "local_bind succeeded on the original port");         return; /* success */     }     if(get_last_socket_error()!=EADDRINUSE #ifndef USE_WIN32             || !c->opt->option.transparent #endif /* USE_WIN32 */             ) {         sockerror("local_bind (original port)");         longjmp(c->err, 1);     } } 
Earlier, c->bind_addr was set to the address of the connecting peer with this code:.
Jumping into argv?
    else if(c->opt->option.transparent)     memcpy(&c->bind_addr, &c->peer_addr, sizeof(SOCKADDR_LIST)); 
The stunnel documentation contains this advice for recent Linux kernels:.
Get calling user ID in PHP setuid script
Remote mode (either 2.2.x and >=2.6.28) requires stunnel to be executed as root.

What is sys/user.h used for?
setuid option will also break this functionality..
Ruby: How do make my program trap and exit properly from a signal?
Linux >=2.6.28 requires the following setup for iptables and routing (possibly in /etc/rc.local or equivalent file):.
Error in requiring Sinatra gem
iptables -t mangle -N DIVERT iptables -t mangle -A PREROUTING -p tcp -m socket -j DIVERT iptables -t mangle -A DIVERT -j MARK --set-mark 1 iptables -t mangle -A DIVERT -j ACCEPT ip rule add fwmark 1 lookup 100 ip route add local dev lo table 100 


If you have control over the local server processes, then you can do this.

Create a persistent UNIX-domain socket connection between the proxy process and the server process, then use sendmsg() on that UNIX-domain socket to pass a SCM_RIGHTS message containing the TCP socket's file descriptor.

The proxy process can then close its handle to the TCP socket.. When the server process gets passed a file descriptor from the proxy in a SCM_RIGHTS message, it just has to add it to its normal set of client sockets, as if it had come from accept()..

56 out of 100 based on 51 user ratings 676 reviews