Nginx

完全透明的反向代理

  • May 4, 2022

我正在嘗試設置以下內容:

┌──────────────────┐            ┌────────────────────┐           ┌─────────┐    
│                  │            │                    │           │         │    
│      Router      │            │                    │           │Server 1 │    
│       NAT        │Port forward│                    │           │         │    
│                  │ ────────►  │     Server 0       │           │HTTP >   │    
│                  │            │                    │           │HTTPS    │    
│                  │            │    1.example.com  ───────────► │redirect │    
│                  │            │    2.example.com  ────┐        └─────────┘    
└──────────────────┘            └────────────────────┘  │         192.168.178.8 
                                    192.168.178.4      │                       
                                                       │   ┌─────────┐         
                                                       │   │         │         
                                                       │   │         │         
                                                       │   │Server 2 │         
                                                       └─► │         │         
                                                           │HTTP only│         
                                                           │         │         
                                                           └─────────┘         
                                                           192.168.178.7       

我希望伺服器 0 充當僅轉發流量的完全透明代理。這樣客戶端就不會與伺服器 0 建立 TLS 連接,而是直接與伺服器 1/2 建立連接,並且在伺服器 1/2 上基於 HTTP-01 挑戰的自動證書生成和更新仍然有效。

編輯:如果您擔心反向代理(終止 SSL 隧道)和內容伺服器之間的連接不安全,儘管這確實有效並且是安全的,但您最好配置上游 SSL 或安全隧道,如 SSH 或內容伺服器和反向代理之間的 IPSEC。


我讓它工作:

文件結構:

ngnix/
   config/
       nginx.conf
   http_server_name.js
   docker-compose.yml

nginx.conf

load_module modules/ngx_stream_js_module.so;

events {}

stream {
   js_import main from http_server_name.js;
   js_set $preread_server_name main.get_server_name;

   map $preread_server_name $http {
       1.example.com server1_backend_http;
       2.example.com server2_backend_http;
   }

   map $ssl_preread_server_name $https {
       1.example.com server1_backend_https;
       2.example.com server2_backend_https;
   }

   upstream server1_backend_http {
       server 192.168.178.8:80;
   }
   
   upstream server1_backend_https {
       server 192.168.178.8:443;
   }

   upstream server2_backend_http {
       server 192.168.178.7:80;
   }

   server {
       listen 443;  
       ssl_preread on;
       proxy_pass $https;
   }

   server {
       listen 80;
       js_preread main.read_server_name;
       proxy_pass $http;
   }
}

碼頭工人-compose.yml

version: '3'

services:
 ngnix:
   image: nginx
   container_name: ngnix
   restart: unless-stopped
   volumes:
     - ./config/ngnix.conf:/etc/nginx/nginx.conf:ro
     - ./config/http_server_name.js:/etc/nginx/http_server_name.js:ro
   ports:
     - "192.168.178.4:80:80"
     - "192.168.178.4:443:443"

http_server_name.js

var server_name = '-';

/**
* Read the server name from the HTTP stream.
*
* @param s
*   Stream.
*/
function read_server_name(s) {
 s.on('upload', function (data, flags) {
   if (data.length || flags.last) {
     s.done();
   }

   // If we can find the Host header.
   var n = data.indexOf('\r\nHost: ');
   if (n != -1) {
     // Determine the start of the Host header value and of the next header.
     var start_host = n + 8;
     var next_header = data.indexOf('\r\n', start_host);

     // Extract the Host header value.
     server_name = data.substr(start_host, next_header - start_host);

     // Remove the port if given.
     var port_start = server_name.indexOf(':');
     if (port_start != -1) {
       server_name = server_name.substr(0, port_start);
     }
   }
 });
}

function get_server_name(s) {
 return server_name;
}

export default {read_server_name, get_server_name}

文件:

ngx_http_upstream_module

ngx_http_map_module

ngx_stream_proxy_module

編輯:

閱讀這篇博文了解更多資訊

引用自:https://serverfault.com/questions/1075851