摘要:如果希望开发支持多租户(Multiple Tenant)的通配子域名的软件,需要在本地搭建相应的环境,本文介绍如何搭建这样的环境。
概述
通过本文,我们将搭建多租户通配子域名开发环境,该环境的功能如下:
- 可以正确的解析任意子域名访问
- 可以正确的解析子域名所对应的服务
- 可以正确的显示 SSL 证书
本文所用的技术
- dnsmasq 本地 DNS 解析服务
- nginx 反向代理
- ng serve 的选项
假设我们需要设定的域名为 mengxin.science
, 其统配子域名为 *.mengxin.science
。
dnsmasq 配置 DNS
我们都知道,在本地调试的时候,如果希望指定域名,一般都会使用 /etc/hosts
来指定域名对应的解析 IP(一般为本地)。但是这个 hosts
文件并不支持子域名通配。也就是说我们无法使用该文件达到解析所有的 *.mengxin.scienc
到本地 IP。
这时候我们需要一个本地的 DNS 服务来达到这个目标,也就是 dnsmasq
。作为一个 DNS server, dnsmasq
有很多功能,我们这里只介绍必要的配置。
安装
安装大家完全可以官方获得手册,本人使用 Fedora,所以直接用 dnf
安装,可以参考该文章。
step 1
安装
sudo dnf install dnsmasq
step 2
配置用户和用户组来操作 dnsmasq
sudo groupadd -r dnsmasq
sudo useradd -r -g dnsmasq dnsmasq
dnsmasq
配置
我们需要的配置很简单,实际上只需要一条记录配置统配域名的 DNS A 记录(A record)就行了。
dnsmasq 的配置和 nginx 类似,有一个默认的主配置文件 /etc/dnsmasq.conf
,同时还可以创建自定义子配置文件,因为在主配置文件中包含了相应文件夹下的所有配置:
1 | # Include all files in /etc/dnsmasq.d except RPM backup files |
所有我们只需要在 /etc/dnsmasq.d
目录下创建一个我们自己的配置文件即可,例如 dev.conf
。该文件我们配置如下:
1 | address=/mengxin.science/192.168.XXX.XXX |
其中后面的 IP 地址为你需要指定的地址,也可以是本地地址。
配置结束后我们可以使用一下命令来测试配置文件:
1 | sudo dnsmasq --test |
让 dnsmasq 生效
在配置中发现总是不能生效,因为还没有告诉你的操作系统如何使用这个本地的 DNS,所以我们需要配置我们解析网址的 DNS 服务器,其配置文件为 resolve.conf
。向该文件中增加条目:nameserver 127.0.0.1
,结果如下:
1 | # Generated by NetworkManager |
该列表为所有可用的 DNS 解析服务器。
修改了这个文件可以需要重启一下 networkManager
sudo service network-manager restart
管理 dnsmasq 服务
我们可以使用 service
来管理,也可以用 systemctl
。
启动服务
sudo systemctl start dnsmasq
重启服务
sudo systemctl restart dnsmasq
停止服务
sudo systemctl stop dnsmasq
Nginx 配置反向代理
至此我们已经成功的解析的统配的 *.mengxin.science
到指定的 IP 地址。下面我们就要来将统配的子域名反向代理到争取的服务端口。
假设我们开发环境分为前端后后端:
- 前端端口为
3000
, 访问路径为 localhost:3000 - 后端端口为
8081
, 访问路径为 localhost:8081/rest
则我们需要将
*.mengxin.science
-> localhost:3000*.mengxin.science/rest
-> localhost:8081/rest
SSL 证书
既然我们需要统配子域名,那么我们就需要一个统配的证书 (同时兼容统配和子域名为空的情形),这个证书的特点是其 issuer to 为一个统配的域名,比如 *.google.co.uk。
nginx 配置
和 dnsmasq
一样,我们只需要配置增加一个配置文件在 /etc/nginx/conf.d
目录下即可,比如 dev.conf
1 | server { |
其中有两点需要注意
server_name
如果前面不加 * 表示统配两种情形:任意的子域名和子域名为空- 如果你的开发程序不能接受在请求头部信息的任意的 Host,那么可以将头部设为可接受的内容,比如顶级域名。
前端 Angular 服务启动配置
前面我们说到关于头部的 Host 信息的问题,在前端开发 Angular (2+),我们使用 ng serve 命令的时候,是可以忽略 Host 检查的,其参数为--disable-host-check
,所以在开发的时候加上这个选项,任意子域名的反向代理,即使不配置头部也可以正确的导向前端的服务。
总结
至此我们完成了目标:
- 可以正确的解析任意子域名访问
- 可以正确的解析子域名所对应的服务
- 可以正确的显示 SSL 证书
至于子域名到达服务后,那么就需要程序本身来进行处理,比如 servlet
在 filter
中可以提取 子域名。js
也可以将路径中的子域名提取出来。