Đăng vào

Cấu hình NGINX SSL Passthrough cho nhiều domain dùng SNI routing

Giới thiệu

Ở các bài viết trước về thiết lập Kubernetes cluster trên Microsoft Hyper-V server mình có đề cập đến việc sử dụng NGINX làm Reverse Proxy.

Nhiệm vụ chủ yếu là điều hướng các request đến các backend tương ứng, trong trường hợp của mình:

  • IP a.b.c.D: làm VM mail zimbra có địa chỉ mailserver.com
  • IP a.b.c.F: là IP của Metallb của K8s cluster. Trên K8s cluster này mình deploy rất nhiều các service, website chẳng hạn như abc.com, xyz.org, api.vn, ...

Server của mình chỉ có 1 Public IP duy nhất, bài toán đặt ra là cần cấu hình NGINX để hệ thống có thể hoạt động dùng chung IP đó.

Tiến hành

Thông thường, 1 mail server sẽ sử dụng các port 25, 143, 587, 465, ... và port 80/443 dành để truy cập vào webmail. Như vậy mình chỉ cần cấu hình để các HTTP/HTTPS request đến tên miền mailserver.com sẽ điều hướng dến Zimbra Mail server còn các tên miền khác sẽ điều hướng đến K8s cluster. Với các TCP request đến các port 25, 143, ... sẽ điều hướng tới Mail server.

SSL Passthrough hay SSL Termination

Bởi vì mình cần điều hướng các HTTPs nên phải làm việc với vấn đề SSL certificate cho các tên miền. Khi sử dụng NGINX có 2 cách để quản lý các chứng chỉ SSL:

  • SSL Termination: các SSL được quản lý bởi proxy
  • SSL Passthrough: các SSL được quản lý bởi backend server

Lưu ý: Vui lòng Google 2 khái niệm trên để có cách hiểu chính xác và đầy đủ nhất.

Trong trường hợp của mình

  • Zimbra mail server sẽ được cài đặt SSL và quản lý trực tiếp.
  • K8s cluster mình sử dụng Ingress NGINX + Cert-manager.io để tạo và quản lý các chứng chỉ Let's Encrypt SSL trên cluster.

Như vậy trong trường hợp của mình cần cấu hình SSL Passthrough

NGINX cho Windows với module with-stream_ssl_preread_module

Với phiên bản NGINX cho Window được download từ website chính chủ thì sẽ không có module with-stream_ssl_preread_module vì vậy bạn phải tự Build lại Nginx từ source code hoặc Download bản build của mình có module with-stream_ssl_preread_module

.\nginx.exe -V

...
TLS SNI support enabled
...
--with-stream_ssl_module
--with-stream_ssl_preread_module

Redirect HTTP sang HTTPs

Mình sẽ redirect các HTTP request thành HTTPS hết, trong block http:

[...]

http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;

    keepalive_timeout  65;

    server {
		listen 80 default_server;
		server_name _;
		return 301 https://$host$request_uri;
	}
}

Cấu hình stream block:

stream {
	[...]

    map_hash_bucket_size 128;
    map $ssl_preread_server_name $https_server {
        mailserver.com zimbra_443;
        default metallb_443;
    }

    ## HTTPs traffic
    server {
        listen 443;
        proxy_pass $https_server;
        ssl_preread on;
    }

    # Mail server TCP ports
    server {
        listen 25;
        proxy_pass zimbra_25;
    }
    server {
        listen 110;
        proxy_pass zimbra_110;
    }
    [...] # Tương tự cho các port 465, 587


    ## Kuberntes
    upstream metallb_443 {
        server a.b.c.F:443;
    }

    # Zimbra
    upstream zimbra_443 {
	    server a.b.c.D:443;
    }
    upstream zimbra_25 {
	    server a.b.c.D:25;
    }
    upstream zimbra_110 {
        server a.b.c.D:110;
    }
    [...] # Tương tự cho các port 465, 587
}

Hy vọng bài viết sẽ giúp ích được cho người khác.

Liên hệ