443端口共用的方案

栏目: 服务器 · 发布时间: 6年前

内容简介:TCP协议中,主机的IP地址加上端口号作为TCP连接的端点,这种端点就叫做套接字(socket)。一般情况下,一个socket同一时刻只能由一个应用监听,对于只有单个公网IP的主机来说,一个对外的端口就是一个socket,例如常用端口约定的服务:在某些特殊需求的情况下,我们可能需要一个端口同时提供多个服务,例如:总的来说,实现端口共用的思路就好比是Nginx的SNI:用某个前端程序(类比:Nginx)监听需要共用的对外端口A(类比:域名),将需要共用的程序(例如:php-fpm、uwsgi)分别监听环路上

简述

TCP协议中,主机的IP地址加上端口号作为TCP连接的端点,这种端点就叫做套接字(socket)。一般情况下,一个socket同一时刻只能由一个应用监听,对于只有单个公网IP的主机来说,一个对外的端口就是一个socket,例如常用端口约定的服务:

  • 22:SSH服务
  • 80:HTTP服务
  • 443:HTTPS服务
    ...

在某些特殊需求的情况下,我们可能需要一个端口同时提供多个服务,例如: ssh/http 共用 80 端口 的讨论。

总的来说,实现端口共用的思路就好比是Nginx的SNI:用某个前端程序(类比:Nginx)监听需要共用的对外端口A(类比:域名),将需要共用的程序(例如:php-fpm、uwsgi)分别监听环路上的不同端口A2、A3(类比:本地套接字),前端程序通过区分特定的包格式(类比:域名)将外部发往端口A的数据分别发给端口A2、A3再根据后端响应发回。

因为Nginx提供的Web服务工作在应用层,所以反向代理时可以直接通过URI来确定使用哪个后端;而一般工作在传输层的端口复用,实际上要解决最主要问题是如何区分复用数据并正确发给处理后端。

实现

I. 预期目标

为了尽可能避免被QoS和受限网络的影响,现希望将某科学上网方式作为复用数据与正常的HTTPS服务共用443端口,在两者都能够提供服务的同时,HTTPS能够 获取前端访客的IP地址

443端口共用的方案

II. 服务结构

除了自己写前端处理程序,现成的方案有用Haproxy来区分不同数据来实现前端,Nginx和科学上网 工具 分别按照原配置改为在本地回环监听,其中Nginx需要稍作修改以获取前端发来的IP地址。

443端口共用的方案

III. Haproxy配置

这里用的Haproxy版本为1.5.18,安装过程不再赘述,主要提提配置的要点。

listen https-in
        bind :443
        tcp-request inspect-delay 5s
        acl is_ssl req_ssl_ver 3:4
        tcp-request content accept if is_ssl
        server server-https :4431 check send-proxy
        use_backend ss-out if !is_ssl

https-in是一个listen,这是好比原来Haproxy里fronted和backend的合并体,上面配置语句的功能如下:

  • bind :443 设置监听所有IP的443端口
  • tcp-request inspect-delay 设置等待数据传输的最大超时时间
  • acl is_ssl req_ssl_ver 3:4 设置一条acl规则,判断是否为ssl连接
  • tcp-request content accept if is_ssl 设置如果上一条件成立则直接使用本listen里的server
  • server server-https :4431 check send-proxy
    设置本listen里名为server-https的后端服务,send-proxy表示向后端发送相关代理信息,后端获取访客的IP地址就是通过这条指令实现的
  • use_backend ss-out if !is_ssl 如果acl规则不成立,则使用名为ss-out的后端

这里最主要的配置就是send-proxy,网上后端获取前端传去的真实IP地址方法是通过Haproxy解析,然后使用option httpclose和option forwardfor之类的指令。这种方法在转发四层TCP数据的时候是无效的!要实现四层TCP数据带源地址转发需要修改前端源码通过重新改包实现。

好在Haproxy支持 代理协议(PROXY protocol) ,这是是Haproxy的作者Willy Tarreau于2010年开发和设计的一个协议,通过为tcp添加一个很小的头信息,来方便的传递客户端信息(协议栈、源IP、目的IP、源端口、目的端口等),在网络情况复杂又需要获取客户IP时非常有用。这里的send-proxy指令就是使用了这套协议来向后端传值。

backend ss-out
        mode tcp
        server D-T-us0 127.0.0.1:1234
        server D-T-us1 127.0.0.1:4321 backup

backend是Haproxy的后端,用来提供服务,上面的配置提供了一个127.0.0.1:1234的服务和一个127.0.0.1:4321备用服务。

IV. Nginx配置

Nginx主要是修改绑定的端口,增加proxy_protocol标记表示使用代理协议,再修改好set_real_ip_from、real_ip_header以及日志格式,其他的没什么实质性内容,不再多说。

log_format  main  '$proxy_protocol_addr - [$remote_addr] - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
server
    {
    listen 4431 ssl http2 proxy_protocol;
    set_real_ip_from xx.xx.xx.xx;
    real_ip_header proxy_protocol;

    include /etc/nginx/sslport.conf;
    server_name  m.holmesian.org;
    ssl on;
    
    include /etc/nginx/sslon.conf;
    root  /data/www/sgk/;
    
    try_files $uri $uri/ /index.php?$args;
    location ~ \.php$
        {
          fastcgi_pass  unix:/var/run/php7-fpm.socket;
          fastcgi_index index.php;
          include fastcgi_params;
        }
    }

V. Dtunnel配置

这个在 通过KCP协议加速科学上网 里讲过,其他类型的服务也是可以的。

效果

在443端口复用的情况下,Dtunnel的话基本能跑满带宽(请忽略下图我的渣带宽)。

443端口共用的方案

Nginx能够获取Haproxy传来的访客IP地址,性能影响微弱。

443端口共用的方案

这个方案在服务器上已经跑了200多天,目前还没发现什么大问题,所以分享出来供有需要的TX参考。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Practical Algorithms for Programmers

Practical Algorithms for Programmers

Andrew Binstock、John Rex / Addison-Wesley Professional / 1995-06-29 / USD 39.99

Most algorithm books today are either academic textbooks or rehashes of the same tired set of algorithms. Practical Algorithms for Programmers is the first book to give complete code implementations o......一起来看看 《Practical Algorithms for Programmers》 这本书的介绍吧!

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具