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

前端之家收集整理的这篇文章主要介绍了透明代理 – 如何将套接字传递给本地服务器而不进行修改?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

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

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

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

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

这个平台就是Linux.

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

  1. #ifdef IP_TRANSPARENT
  2. int on=1;
  3. if(c->opt->option.transparent) {
  4. if(setsockopt(c->fd,SOL_IP,IP_TRANSPARENT,&on,sizeof on))
  5. sockerror("setsockopt IP_TRANSPARENT");
  6. /* ignore the error to retain Linux 2.2 compatibility */
  7. /* the error will be handled by bind(),anyway */
  8. }
  9. #endif /* IP_TRANSPARENT */
  10. memcpy(&addr,&c->bind_addr.addr[0],sizeof addr);
  11. if(ntohs(addr.in.sin_port)>=1024) { /* security check */
  12. if(!bind(c->fd,&addr.sa,addr_len(addr))) {
  13. s_log(LOG_INFO,"local_bind succeeded on the original port");
  14. return; /* success */
  15. }
  16. if(get_last_socket_error()!=EADDRINUSE
  17. #ifndef USE_WIN32
  18. || !c->opt->option.transparent
  19. #endif /* USE_WIN32 */
  20. ) {
  21. sockerror("local_bind (original port)");
  22. longjmp(c->err,1);
  23. }
  24. }

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

  1. else if(c->opt->option.transparent)
  2. memcpy(&c->bind_addr,&c->peer_addr,sizeof(SOCKADDR_LIST));

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

Remote mode (either 2.2.x and >=2.6.28) requires stunnel to be executed as root. setuid option will also break this functionality.

Linux >=2.6.28 requires the following setup for iptables and routing (possibly in /etc/rc.local or equivalent file):

  1. iptables -t mangle -N DIVERT
  2. iptables -t mangle -A PREROUTING -p tcp -m socket -j DIVERT
  3. iptables -t mangle -A DIVERT -j MARK --set-mark 1
  4. iptables -t mangle -A DIVERT -j ACCEPT
  5. ip rule add fwmark 1 lookup 100
  6. ip route add local 0.0.0.0/0 dev lo table 100

猜你在找的Linux相关文章