我正在构建一个市场平台,使许多商家能够向其客户销售产品。目前,我在自己的域上为商店提供服务,例如https://storeA.mydomain.com
或https://storeB.mydomain.com
(我可以使用子域来区分要为哪个商店提供服务)。但是,我想让我的商家在我的平台上使用他们自己的域,同时能够通过 HTTPS 保护网站,我该如何自动实现这一点?过去,我曾尝试过 CNAME 到 CNAME,但这不允许 HTTPS。
编辑:如果您知道商家可以使用任何中介服务(提供某种域名屏蔽),那就太好了!
答案1
应该可以使用 Certbot 通过 Let's Encrypt 自动执行此操作,但恐怕目前还没有现成的解决方案。因此,它需要一些脚本,你可能需要雇人,就像你问这个问题一样。
我会建议这样的(示例针对 Apache 2.4 Web 服务器):
创建一个指向所有域的同一目录的万能配置
http://*/.well-known/acme-challenge/
,其余域的默认虚拟主机也指向该目录。这可以通过全局配置来实现Alias
可以放置在/etc/apache2/conf-enabled/acme-challenge.conf
:<IfModule alias_module> Alias /.well-known/acme-challenge/ /var/www/letsencrypt/.well-known/acme-challenge/ </IfModule>
让您的客户输入他们的自定义域名进行验证,并将信息保存在某处,并引用正确的客户。数据库将是理想的选择,不是吗?可以限制每个客户只有一个自定义主机名(& www)。
指导您的客户将他们的域名指向正确的 IP 地址。对于子域名,记录
CNAME
将起作用,但在域名顶点您需要提供记录说明A
。此处的示例只是假设每个域都有和
example.com
,www.example.com
但您可以根据您的要求进行修改。不启动HTTP-01 挑战立即,但创建用计划任务或系统定时器。脚本首先应检查等待验证的域是否指向您的服务器,并仅对符合条件的域发起 ACME 挑战。否则,有人可能会滥用该功能并使您的服务器执行不必要的 Let's Encrypt 验证。
#!/bin/bash MYSERVERIP="192.0.2.123" if [ "$#" -ne 1 ]; then printf "\n%s\n\n" "Usage: $0 example.com" >&2 exit 1 fi host "$1" 2>&1 > /dev/null if [ $? -ne 0 ]; then printf "\n%s\n\n" "The given domain is not a valid FQDN." >&2 exit 1 fi IPAPEX=$(dig "$1" +short | tail -n 1) IPWWW=$(dig "www.$1" +short | tail -n 1) if [ "$IPAPEX" = "$MYSERVERIP" ]; then if [ "$IPWWW" = "$MYSERVERIP" ]; then certbot certonly --quiet --webroot -w /var/www/letsencrypt -d $1 -d www.$1 if [ $? -ne 0 ]; then printf "\n%s\n\n" "Certbot failed with HTTP-01 challenge." >&2 exit 1 fi else printf "\n%s\n\n" "Failed: www.$1 is not pointing to $MYSERVERIP." >&2 exit 1 fi else printf "\n%s\n\n" "Failed: $1 is not pointing to $MYSERVERIP." >&2 exit 1 fi
验证完成后,脚本还可能会将配置添加到 Web 服务器。您可以使用宏例如
/etc/apache2/conf-enabled/custdomain-macro.conf
:<Macro CustomWebShopDomain $customer $domain> <VirtualHost *:80> ServerName $domain ServerAlias www.$domain Redirect permanent / https://$domain/ </VirtualHost> <VirtualHost *:443> ServerName $domain SSLEngine on SSLCertificateFile /etc/letsencrypt/live/$domain/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/$domain/privkey.pem SSLVerifyClient None DocumentRoot /path/to/webshop/$customer </VirtualHost> <VirtualHost *:443> ServerName www.$domain SSLEngine on SSLCertificateFile /etc/letsencrypt/live/$domain/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/$domain/privkey.pem SSLVerifyClient None Redirect permanent / https://$domain/ </VirtualHost> </Macro>
在这种情况下,添加新的客户域很简单:
Use CustomWebShopDomain customerid example.com
您的脚本可能会将此行添加到配置中,然后重新加载 Apache Web 服务器:
printf "%s\n" "Use CustomWebShopDomain $2 $1" \ >> /etc/apache2/conf-enabled/custdomain-use.conf systemctl reload apache2
确保清理过期的域名
Certbot 会添加所有用于自动续订的域名。如果这些续订开始失败,您不会希望永远保留这些域名在配置中。最好自动删除,即
- 删除 Certbot 配置
/etc/letsencrypt/renewal/example.com
- 删除该
Use CustomWebShopDomain customerid example.com
线。