群晖反向代理服务器支持泛解析域名通配

最近折腾群晖有一个小技巧,记录下,后续找起来也方便

起因

最近我为群晖上的容器服务搭建了一套统一访问网关,为每个服务自动分配一个域名,例如nginx服务会自动分配域名nginx.example.com,也就是一个服务一个子域名

由于群晖本身的web服务占用系统80端口,只能使用群晖的web服务器再进行一次代理来转发了

初试

其实群晖出来webstation以外还有一个方便的地方可以配置反向代理,很多人容器忽略

路径在,控制面板,应用程序门户,反向代理服务器

看到这个界面,点击新增,立马就能领悟这个功能干了什么,其实就是往nginx中加了一个server

问题

群晖的web服务器本身就是一个nginx,通过大量脚本来生成需要的配置文件启动即可,一开始我天真的认为按照nginx那样添加一个server *.example.com即可实现子域名的代理访问,实际上当我输入*号的的时候无法提交这个表单,因为群晖在前端上限制了不允许输入泛解析域名

思考

思考了几个方法

  1. 手动写nginx配置加进去,但是这样不确定后续群晖管理配置的时候是否回头冲突
  2. 修改前端校验,允许提交*号的域名,这个看起来有点麻烦
  3. 手动修改群晖的数据库,强行加入一条记录,但是这样不确定后续在生成的时候是否回错误

这几个方法都不太满意,可靠性和可行性都欠佳

解决

这个时候在google中看到一片老外的帖子,遇到的问题和我几乎一致,大体上的思路是,在群晖生成nginx配置文件的时候动下手脚将特定标记转换成通配符,这里使用wildcard作为标记,在界面设置的时候统一填写wildcard.example.com添加反向代理,在生成nginx配置文件的时候统一替换成*.example.com,整体思路很清晰,改动也小,后续几乎不可能出问题。

实际操作需要ssh登录机器修改文件/usr/syno/etc/rc.sysv/nginx-conf-generator.sh

1
2
3
4
5
6
7
8
9
--- /usr/syno/etc/rc.sysv/nginx-conf-generator.sh.orig	2021-08-27 11:13:23.448844850 +0200
+++ /usr/syno/etc/rc.sysv/nginx-conf-generator.sh 2021-08-27 11:03:18.603670899 +0200
@@ -27,6 +27,7 @@
GenerateConf "$SZF_NGINX_MUSTACHE" "$tmp" "$SZF_TMP_NGINX_CONF" || true

if [ -s "$SZF_RP_DATASTORE" ]; then
+ sed -i 's/\("fqdn" \+: \+\)"wildcard\.\([^"]*\)"/\1"*.\2"/g' "$SZF_RP_DATASTORE"
GenerateConf "$SZD_MUSTACHE/Portal.mustache" "$SZF_RP_DATASTORE" "$SZD_TMP_APP_D/server.ReverseProxy.conf" || true
fi

修改后,按照约定添加相关配置,测试,完美解决

DSM7更新

在升级到DSM7.1之后,之前的方法失效了,替换解决办法手动添加nginx配置文件,ssh登录添加文件/etc/nginx/sites-enabled/traefik.conf,内容如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
server {
listen 443 ssl;
listen [::]:443 ssl;

server_name *.ds.jove.im ;
include /usr/syno/etc/www/certificate/system_default/cert.conf;
include /usr/syno/etc/security-profile/tls-profile/config/dsm.conf;
proxy_ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
location / {
proxy_connect_timeout 60;
proxy_read_timeout 60;
proxy_send_timeout 60;
proxy_intercept_errors off;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://127.0.0.1:52080;
}
}
server {
listen 80;
listen [::]:80;
server_name *.ds.jove.im ;
return 301 https://$host$request_uri;
}