透明代理 - 如何将套接字传递给本地服务器而不进行修改?

Luc*_*ber 6 c sockets linux proxy

我有一个程序侦听端口443,然后根据检测到的协议重定向到SSH或HTTPS本地服务器.

该程序通过连接到本地服务器并通过其自己的进程来回代理所有数据来完成此操作.

但是,这会导致本地服务器上的原始主机记录为localhost.

有没有办法将套接字直接传递给本地服务器进程(而不仅仅是建立一个新的TCP连接),以便保留sockaddr_in(或sockaddr_in6)的参数?

这个平台就是Linux.

Zan*_*ynx 7

这是从stunnel获取的代码片段(如果你想查看所有代码,则从local_bind函数中的client.c获取).

#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(addr.in.sin_port)>=1024) { /* security check */
    if(!bind(c->fd, &addr.sa, 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

之前,使用以下代码将c-> bind_addr设置为连接对等体的地址:

    else if(c->opt->option.transparent)
    memcpy(&c->bind_addr, &c->peer_addr, sizeof(SOCKADDR_LIST));
Run Code Online (Sandbox Code Playgroud)

stunnel文档包含了对最新Linux内核的建议:

远程模式(2.2.x和> = 2.6.28)要求以root身份执行stunnel.setuid选项也会破坏此功能.

Linux> = 2.6.28需要以下iptables和routing设置(可能在/etc/rc.local或等效文件中):

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 0.0.0.0/0 dev lo table 100
Run Code Online (Sandbox Code Playgroud)


caf*_*caf 6

如果您可以控制本地服务器进程,则可以执行此操作.在代理进程和服务器进程之间创建持久的UNIX域套接字连接,然后sendmsg()在该UNIX域套接字上使用以传递SCM_RIGHTS包含TCP套接字的文件描述符的消息.然后,代理进程可以关闭其对TCP套接字的句柄.

当服务器进程从SCM_RIGHTS消息中的代理传递文件描述符时,它只需将其添加到其正常的客户端套接字集中,就好像它来自accept().