我在 Hetzner 上安装了 Debian 12 系统,运行 Cowmail 和 Nginx。Cowmail 在 mail.mydomain.com 子域(mydomain.com 为占位符)的端口 8069 和 44369 上运行。
我想要做的是:
- 访问 mydomain.com 时提供静态 html(由 nginx 提供)。
- 访问邮件子域时分别将端口 443、80 重定向至 44369、8069。
目前,当我尝试访问 mydomain.com 时,它仍然会重定向端口。
/etc/nginx.conf(删除注释,与默认文件的唯一区别是在末尾包含)
user www-data;
worker_processes auto;
pid /run/nginx.pid;
error_log /var/log/nginx/error.log;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
}
http {
sendfile on;
tcp_nopush on;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dr>
ssl_prefer_server_ciphers on;
access_log /var/log/nginx/access.log;
gzip on;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
include /etc/nginx/tcpconf.d/*;
/etc/nginx/tcpconf.d/lb
stream {
upstream web_server {
server mail.mydomain.com:44369;
}
server {
listen 443;
proxy_pass web_server;
}
}
/etc/nginx/sites-avalible/default(删除注释,/etc/nginx/sites-enabled/ 中的 simlink)
server {
listen 80 default_server;
listen [::]:80 default_server;
root /home/www-none/public;
index index.html ;
server_name _;
location / {
try_files $uri $uri/ =404;
}
}
server {
server_name www.mydomain.com;
return 301 $scheme://mydomain.com$request_uri;
}
server {
root /home/www-mydomain-com/public;
server_name mydomain.com;
ssl_certificate /etc/letsencrypt/live/mydomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mydomain.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location / {
try_files $uri $uri/ =404;
}
}
补充笔记:
- 服务器将托管多个域,因此当直接通过 IP 请求时,它将从 /home/www-none/public 返回页面。
- Let's Encrypt 使用 certbot 生成的 SSL 证书。
- mail.mydomain.com 和 mydomain.com 的证书不同。
- mydomain.com 网站存储在 /home/www-mydomain-com/public,Nginx 确实可以访问它,因为用户 www-data 已添加到 www-mydomain.com 和 www-none 组。
- 我使用这种 TCP 流方法,因为当使用“经典”反向代理时,nginx 会将 ssl 证书替换为为 mydomain.com 创建的证书,这与 mail.mydomain.com 不同。而且 cowmail 有自己的证书。Nginx 应该在这里充当桥梁的作用。
编辑:根据 djdomi 在此处的建议,我进行了更改。删除include /etc/nginx/tcpconf.d/*;
并附加以下代码后/etc/sites-avalible/default
。mydomain.com 可以访问,但 mail.mydomain.com 的 SSL 证书不正确。Nginx 不应在此处终止 SSL。
server {
server_name mail.mydomain.com;
location / {
rewrite /(.*) /$1 break;
proxy_pass https://localhost:44369;
proxy_redirect off;
proxy_set_header Host $host;
}
}
编辑:用以下内容替换 /etc/nginx/tcpconf.d/lb:
stream {
map $ssl_preread_server_name $internalport {
mail.mydomain.com 44369;
default glance-no-upstream-instance;
}
server {
listen 443;
ssl_preread on;
proxy_connect_timeout 20s;
proxy_timeout 30s;
proxy_pass 127.0.0.1:$internalport;
}
}
现在,当我尝试访问 mydomain.com 时,我在 Firefox 中收到“PR_END_OF_FILE_ERROR”。而当我访问 mail.mydomain.com 时,我实际上进入了我的电子邮件。
答案1
虚拟主机是 HTTP 1.1 协议的一个概念。TCP 协议不知道主机名,因为它是通过Host:
HTTP 中的标头进行通信的,或者服务器名称指示(SNI)在 HTTPS (TLS) 中。因此,无法按主机名配置 TCP 代理。它们在不同的层上工作。
但是因为你正在代理(不是重定向;这是 HTTP 协议的完全不同的概念)端口443
(HTTPS)和80
(HTTP)它强烈暗示它将是一个HTTP 反向代理您需要的。是的,即使后端连接也是 TLS 加密的,也可以让 Nginx 处理 TLS 终止。使用 SNI,您可以在同一个 Nginx 实例上拥有多个不同的证书服务器。