How to enable HTTPS for my marketplace
I'm building a marketplace platform that enables many merchants to sell to their customers. At the moment I serve stores on my own domain like so https://storeA.mydomain.com
or https://storeB.mydomain.com
(I'm able to use the subdomain to distinguish which store is to be served). However, I'd like to enable my merchants to use their own domains on my platform whilst being able to secure the site over HTTPS, how can I achieve this automatically? In the past, I've tried CNAME to CNAME but this doesn't allow HTTPS.
EDIT: If you know of any intermediary services (that offer some sort of domain masking) that the merchants would be able to use that would be great!
Solution 1:
It should be possible to automate this with Let's Encrypt using Certbot, but I'm afraid there's no existing ready for use solution for this. Therefore, it requires some scripting, and you may need to hire someone, as you asked this question.
I would suggest something like this (examples are for the Apache 2.4 web server):
-
Create a catch-all configuration that points
http://*/.well-known/acme-challenge/
to the same directory with any domain and with the default virtual host for the rest. This is possible with a globalAlias
that could be placed in/etc/apache2/conf-enabled/acme-challenge.conf
:<IfModule alias_module> Alias /.well-known/acme-challenge/ /var/www/letsencrypt/.well-known/acme-challenge/ </IfModule>
-
Let your customers input their custom domains for validation and save the information somewhere, with a reference to the correct customer. A database would be ideal for that, wouldn't it. Possibly limit this to one custom hostname (& www) per customer.
-
Instruct your customers to point their domains to the correct IP address. In the case of a subdomain, a
CNAME
record will work, but at the domain apex you will need to provide instructions for anA
record.Here, the examples simply assume every domain has both
example.com
andwww.example.com
, but you can modify this according to your requirements. -
Do not launch HTTP-01 challenge immediately, but create a script launched with a cronjob or a Systemd timer. The script should first check whether the domains waiting for validation points to your server or not, and launch the ACME challenge only for domains that meets the condition. Otherwise, someone could abuse the feature and make your server perform unnecessary Let’s Encrypt validations.
#!/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
-
Once the validation is completed, the script may also add the configuration to the web server. You might use a macro, e.g.
/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>
In this case, adding a new customer domain would be simple:
Use CustomWebShopDomain customerid example.com
Your script might add this line to the configuration and then reload the Apache web server:
printf "%s\n" "Use CustomWebShopDomain $2 $1" \ >> /etc/apache2/conf-enabled/custdomain-use.conf systemctl reload apache2
Be sure to clean out expired domains
Certbot adds all the domains for automatic renewals. If those renewals start to fail, you don't want to keep those domains in the configuration forever. It's best to automate the removal, i.e.
- Remove the Certbot configuration
/etc/letsencrypt/renewal/example.com
- Remove the
Use CustomWebShopDomain customerid example.com
line.