Testing my certs shows one with port 80 blocked but not others


#1

I have several certificates that test fine with an autorenew dry run except one which works og and qualsys test fine but the autorenew dry run shows
Attempting to renew cert (gourmetbritain-competition.com) from /etc/letsencrypt/renewal/gourmetbritain-competition.com.conf produced an unexpected error: Problem binding to port 80: Could not bind to IPv4 or IPv6… Skipping.
The following certs could not be renewed:
/etc/letsencrypt/live/gourmetbritain-competition.com/fullchain.pem (failure)


** DRY RUN: simulating ‘certbot renew’ close to cert expiry
** (The test certificates below have not been saved.)

The following certs were successfully renewed:
/etc/letsencrypt/live/cle.bell-computing.com/fullchain.pem (success)
/etc/letsencrypt/live/bell-computing.com/fullchain.pem (success)
/etc/letsencrypt/live/staging.bell-computing.com/fullchain.pem (success)
/etc/letsencrypt/live/pmcarpetsandflooring.com/fullchain.pem (success)

The following certs could not be renewed:
/etc/letsencrypt/live/gourmetbritain-competition.com/fullchain.pem (failure)
** DRY RUN: simulating ‘certbot renew’ close to cert expiry
** (The test certificates above have not been saved.)


1 renew failure(s), 0 parse failure(s)

I have run netstat -plten and got the following fwiw

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State User Inode PID/Program name
tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN 113 17959 1378/mysqld
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 0 2163010 11756/nginx
tcp 0 0 127.0.0.1:81 0.0.0.0:* LISTEN 0 17286 1552/httpd
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 0 16149 1333/sshd
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 0 18617 1884/master
tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 0 2163012 11756/nginx
tcp6 0 0 :::80 :::* LISTEN 0 2163011 11756/nginx
tcp6 0 0 :::22 :::* LISTEN 0 16151 1333/sshd
tcp6 0 0 ::1:25 :::* LISTEN 0 18618 1884/master
tcp6 0 0 :::443 :::* LISTEN 0 2163013 11756/nginx


#2
certbot renew \
--cert-name gourmetbritain-competition.com \
-a nginx --dry-run

The problem is that that certificate was set up with the “standalone” authenticator, which is a substitute for nginx in the issuance process. You don’t want that, because they would fight over port 80, as you have found.


#3

The given command gave me an error. So I deleted the certificate and the related files and tried again and whilst

  ./certbot-auto certonly --webroot -w /srv/users/serverpilot/apps/wordpress/public -d staging.bell-computing.com -d works with no errors the below fails

  ./certbot-auto certonly --webroot -w /srv/users/serverpilot/apps/gourmetbritain/public -d gourmetbritain-competition.com -d

Saving debug log to /var/log/letsencrypt/letsencrypt.log

  Plugins selected: Authenticator webroot, Installer None

  Obtaining a new certificate

  Performing the following challenges:

  http-01 challenge for gourmetbritain-competition.com

  http-01 challenge for Using the webroot path /srv/users/serverpilot/apps/gourmetbritain/public for all unmatched domains. Waiting for verification... Cleaning up challenges Failed authorization procedure. gourmetbritain-competition.com (http-01): urn:ietf:params:acme:error:unauthorized :: The client lacks sufficient authorization :: Invalid response from [178.62.53.135]: 404, (http-01): urn:ietf:params:acme:error:connection :: The server could not connect to the client to verify the domain :: Fetching : Error getting validation data IMPORTANT NOTES:  - The following errors were reported by the server:    Domain: gourmetbritain-competition.com    Type:   unauthorized    Detail: Invalid response from       [178.62.53.135]: 404    To fix these errors, please make sure that your domain name was    entered correctly and the DNS A/AAAA record(s) for that domain    contain(s) the right IP address.  - The following errors were reported by the server:    Domain:    Type:   connection    Detail: Fetching    :    Error getting validation data    To fix these errors, please make sure that your domain name was    entered correctly and the DNS A/AAAA record(s) for that domain    contain(s) the right IP address. Additionally, please check that    your computer has a publicly routable IP address and that no    firewalls are preventing the server from communicating with the    client. If you're using the webroot plugin, you should also verify    that you are serving files from the webroot path you provided.

#4

Ah, you’re using ServerPilot. That would have been helpful to know earlier!

Anyway, at the moment, your web server is not working at all, which accounts for the errors you get in your attempt. Fixing that up and then trying webbroot again should get you a bit further.


#5

www.gourmetbritain-competition.com works though (I had been trying to redirect from another domain using, erroneously I guess, a CNAME alias to gourmetbritain-competition.com). We’ll have to wait for the change to propogate if that was it. Anyway the www is fine but that still generates an error in creating it’s certificate. It is in a separate ServerPilot app, that I specify in the command but should I be using standalone?


#6

Thanks. If I stop nginx and do a dryrun, gourmetbritain goes through fine. I have tried to edit the renewal chron but trying it out on a single line in terminal it doesn’t work. Is this correct?

  0 8 * * 0 root cd /opt/certbot; service nginx-sp stop; ./certbot-auto renew --post-hook ; sudo service cron restart

#7

This looks wrong in four different ways (!)

(1) Starting and stopping the web server, if it’s necessary, should be done using --pre-hook and --post-hook commands. The cron job above always stops nginx-sp every time the cron job runs. (By contrast, the hooks would run only during renewal attempts.)

(2) If you do stop the web server, you also need to restart it.

(3) When you use --post-hook, you need to specify a particular command to use as the hook. Both --pre-hook and --post-hook take mandatory arguments which are command lines for Certbot to run before and after a renewal attempt.

(4) I don’t know of any reason to restart cron itself, or any benefit from doing so.

Also, if you have some domains that are using standalone and others that are using webroot, you have a moderately tricky situation because the webroot renewals require that the normal web server be running, while the standalone renewals require that the normal web server not be running. If this is the case, it can be addressed by changing all of the certificates to use the same authenticator plugin, or by specifying appropriate pre-hooks and post-hooks for the individual domains that use standalone (but not for certbot-auto renew as a whole!).


#8

Thanks for that answer, I think I need to go back to the drawing board. I think I need to review my SSL workflow, I have the issue with gourmetbritain but also other certs. I tried the renew dryrun after stopping nginx and they all worked. I had meant to put the nginx restart in the chron so I thought if i did that it would work. Deleting aand repeating the gourmetbritain cert process got me even more tangled up so I reverted my system.

  Can you tell me where I am going wrong?

  Using serverpilot (ubuntu16.04/apache) I have several apps on my server which are separated by folders like so

  /srv/users/serverpilot/apps/wordpress/public

  /srv/users/serverpilot/apps/gourmetbritain/public

  Serverpilot automatically creates system app.conf files in /etc/nginx-sp/vhosts.d.

  From /opt/certbot I run the following

  ./certbot-auto certonly --webroot -w /srv/users/serverpilot/apps/gourmetbritain/public -d gourmetbritain-competition.com -d This creates the cert in /etc/letsencrypt/live/gourmetbritain-competition.com/ Then create .../vhosts.d/gourmetbritain.ssl.conf (see below) Then ./certbot-auto certonly --webroot -w /srv/users/serverpilot/apps/wordpress/public -d bell-computing.com -d Then create .../vhosts.d/wordpress.ssl.conf (see below) All seems fine. Then I did Then ./certbot-auto certonly --webroot -w /srv/users/serverpilot/apps/wordpress/public -d pmcarpetsandflooring.com -d pmcarpetsandflooring.com installing the cert in  /etc/letsencrypt/live/pmcarpetsandflooring.com/ Adding pmcarpetsandflooring.com (and www) to the servername list in wordpress.ssl.conf This worked. However adding further certs for domains on the wordpress app in the same way doesn't seem to work. staging.bell-competition.com doesn't recognise the certificate and cle.bell-computing.com actually prevents access to the site. Should I be creating conf files for each certificate install command? If thats the case then how come pmcarpetsandflooring works?   Here is my current wordpress.ssl.conf file. I have tried putting the location of the other certificates but this fails completely server {     listen 443 ssl http2;     listen [::]:443 ssl http2;    server_name         178.62.53.135         bell-computing.com                 paulmarshallcarpetsandflooring.com                 staging.bell-computing.com         cle.bell-computing.com                 ;     ssl on;     # letsencrypt certificates     ssl_certificate      /etc/letsencrypt/live/bell-computing.com/fullchain.pem;     ssl_certificate_key  /etc/letsencrypt/live/bell-computing.com/privkey.pem;         #SSL Optimization     ssl_session_timeout 1d;     ssl_session_cache shared:SSL:20m;     ssl_session_tickets off;         # modern configuration     ssl_protocols TLSv1 TLSv1.1 TLSv1.2;         ssl_prefer_server_ciphers on;         ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK';         # OCSP stapling         ssl_stapling on;         ssl_stapling_verify on;         # verify chain of trust of OCSP response         ssl_trusted_certificate /etc/letsencrypt/live/bell-computing.com/chain.pem;         #root directory and logfiles         root /srv/users/serverpilot/apps/wordpress/wordpress_nginx/public;         access_log /srv/users/serverpilot/log/wordpress/wordpress_nginx.access.log main;         error_log /srv/users/serverpilot/log/wordpress/wordpress_nginx.error.log;         #proxyset         proxy_set_header Host $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-SSL on;         proxy_set_header X-Forwarded-Proto $scheme;         #includes         include /etc/nginx-sp/vhosts.d/wordpress.d/*.nonssl_conf;         include /etc/nginx-sp/vhosts.d/wordpress.d/*.conf; }

#9

Your post formatting got pretty messed up; could you edit it or try again?


#10

I think I need to review my SSL workflow, I have the issue with gourmetbritain but also other certs. I tried the renew dryrun after stopping nginx and they all worked. I had meant to put the nginx restart in the chron so I thought if i did that it would work. Deleting aand repeating the gourmetbritain cert process got me even more tangled up so I reverted my system.

Can you tell me where I am going wrong?

Using serverpilot (ubuntu16.04/apache) I have several apps on my server which are separated by folders like so
/srv/users/serverpilot/apps/wordpress/public
/srv/users/serverpilot/apps/gourmetbritain/public

Serverpilot automatically creates system app.conf files in /etc/nginx-sp/vhosts.d.

From /opt/certbot I run the following
./certbot-auto certonly --webroot -w /srv/users/serverpilot/apps/gourmetbritain/public -d gourmetbritain-competition.com -d www.gourmetbritain-competition.com/
This creates the cert in /etc/letsencrypt/live/gourmetbritain-competition.com/

Then create …/vhosts.d/gourmetbritain.ssl.conf (see below)

Then ./certbot-auto certonly --webroot -w /srv/users/serverpilot/apps/wordpress/public -d bell-computing.com -d www.bell-computing.com

Then create …/vhosts.d/wordpress.ssl.conf (see below)

All seems fine. Then I did
Then ./certbot-auto certonly --webroot -w /srv/users/serverpilot/apps/wordpress/public -d pmcarpetsandflooring.com -d pmcarpetsandflooring.com
installing the cert in /etc/letsencrypt/live/pmcarpetsandflooring.com/

Adding pmcarpetsandflooring.com (and www) to the servername list in wordpress.ssl.conf

This worked.

However adding further certs for domains on the wordpress app in the same way doesn’t seem to work. staging.bell-competition.com doesn’t recognise the certificate and cle.bell-computing.com actually prevents access to the site. Should I be creating conf files for each certificate install command? If thats the case then how come pmcarpetsandflooring works?

Here is my current wordpress.ssl.conf file.

server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name
178.62.53.135
bell-computing.com
www.bell-computing.com
paulmarshallcarpetsandflooring.com
www.paulmarshallcarpetsandflooring.com
staging.bell-computing.com
cle.bell-computing.com
www.cle.bell-computing.com
;

ssl on;

# letsencrypt certificates
ssl_certificate      /etc/letsencrypt/live/bell-computing.com/fullchain.pem;
ssl_certificate_key  /etc/letsencrypt/live/bell-computing.com/privkey.pem;

    #SSL Optimization
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:20m;
ssl_session_tickets off;

    # modern configuration
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

    ssl_prefer_server_ciphers on;


    ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK'; 

    # OCSP stapling 
    ssl_stapling on; 
    ssl_stapling_verify on; 

    # verify chain of trust of OCSP response 
    ssl_trusted_certificate /etc/letsencrypt/live/bell-computing.com/chain.pem;

    #root directory and logfiles 
    root /srv/users/serverpilot/apps/wordpress/wordpress_nginx/public; 

    access_log /srv/users/serverpilot/log/wordpress/wordpress_nginx.access.log main; 
    error_log /srv/users/serverpilot/log/wordpress/wordpress_nginx.error.log; 

    #proxyset 
    proxy_set_header Host $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-SSL on; 
    proxy_set_header X-Forwarded-Proto $scheme; 

    #includes 
    include /etc/nginx-sp/vhosts.d/wordpress.d/*.nonssl_conf; 
    include /etc/nginx-sp/vhosts.d/wordpress.d/*.conf; 

}


#11

Each nginx server block allows you to specify only one certificate for that server block. Here, you have all these different names

bell-computing.com
www.bell-computing.com
paulmarshallcarpetsandflooring.com
www.paulmarshallcarpetsandflooring.com
staging.bell-computing.com
cle.bell-computing.com
www.cle.bell-computing.com

in one single nginx server block, which references one single certificate

which doesn’t cover the majority of these names at all.

While I don’t know how this is meant to interact with WordPress, you’ll probably need to either cover all of the names on the same certificate, or else create separate, independent server blocks, conventionally in separate configuration files, for each domain name (and point each one at the corresponding certificate file).


#12

It seems like it works specifically because it’s not in that file. paulmarshallcarpetsandflooring.com is in that file, but pmcarpetsandflooring.com isn’t, and so it’s presumably references in some other nginx configuration with a separate server block, which I assume points to the correct certificate file for that domain name.

One important thing to understand about this is that WordPress doesn’t choose which certificate to present; nginx chooses which certificate to present. It chooses in this on the basis of the server block that’s selected, most often by the server_name directive. Therefore, nginx assumes that the certificate that’s referenced by the ssl_certificate directive must cover every name mentioned in the server_name directive. At least the majority of your certificate mismatch errors are currently caused by violating this assumption.


#13

Well spotted Shoen!

  So there must be as pmcarpetsandflooring.ssl.conf somewhere? Buts its not in /etc/nginx-sp/vhosts.d. Could it be anywhere else? Should all such conf files be there? How does the system find it when I found it in /etc/letsencrypt/renewal? Not sure why I put it there.

  I must create a conf file there for every separate certificate. I was puzzled why the appname conf files had been automatically created and the blog post advice said to create appname.ssl.conf but I guess it must just have expected one domain per app.

  If I want to add to an existing certificate then do I reapply the original install code and add the new domains to the list? (updating the conf file accordingly)

Pat


#14

Maybe try grep -r pmcarpetsandflooring /etc/nginx-sp or something?

Certbot configuration files and nginx configuration files are separate and independent. The Certbot configuration in /etc/letsencrypt/renewal tells Certbot which certificates exist which it should try to renew with certbot renew, while the nginx configuration in /etc/nginx or /etc/nginx-sp tells nginx which server blocks exist which it should use to respond to incoming web requests. When configured with HTTPS by or in conjunction with the use of Certbot, those server blocks will refer to certificate-related files in /etc/letsencrypt/live.

Yes, although I’m not sure which conf file you’re referring to. You’ll need to be sure that nginx knows about the existence of the domains, but domains in Certbot-managed certificates don’t get listed in the Certbot configuration files (only within the certificates themselves).


#15

Hi Seth,

  Yes I found it in /etc/letsencrypt/renewal along with conf files for my problem domains too. But no ssl.conf files.  So would you recommend that I delete my existing certificates and recreate them one by one and create ssl.conf files for each domain rather than the appname.ssl.conf files that are there now?

Pat


#16

Hi Seth

  So trying out my new found knowledge I deleted the spurious domains from wordpress.ssl.conf. Bell-computing.com still works. As does pmcarpetsandflooring.co which is a subdomain of bell-computing.com

  Then deleted the staging.bell-computing.com certificate, restarted nginx and recreated the cert as follows:

  ./certbot-auto certonly --webroot -w /srv/users/serverpilot/apps/wordpress/public -d staging.bell-computing.com -d

  Then created staging.bell-computing.com.ssl.conf in vhosts.d See below. restarted nginx but qualys still claims certificate name mismatch and dry run renew says

     Domain: staging.bell-computing.com

     Type:   connection

     Detail: Fetching

                    4WNpbjR4kSRnlFaZERkjXifzCQ8:    Error getting validation data

  But there is no folder called //staging.bell-computing.com/  let alone .well-known - this is a wordpress multisite and all subdomains are contained in the same public folder ie the same webroot so how do I make it use /srv/users/serverpilot/apps/wordpress/public/.well-known/acme-challenge?

Here is the ssl.conf

  server {

      listen 443 ssl http2;

      listen [::]:443 ssl http2;

     server_name

         staging.bell-computing.com   

               ;     ssl on;     # letsencrypt certificates     ssl_certificate      /etc/letsencrypt/live/staging.bell-computing.com/fullchain.pem;     ssl_certificate_key  /etc/letsencrypt/live/staging.bell-computing.com/privkey.pem;         #SSL Optimization     ssl_session_timeout 1d;     ssl_session_cache shared:SSL:20m;     ssl_session_tickets off;         # modern configuration     ssl_protocols TLSv1 TLSv1.1 TLSv1.2;         ssl_prefer_server_ciphers on;         ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK';         # OCSP stapling         ssl_stapling on;         ssl_stapling_verify on;         # verify chain of trust of OCSP response         ssl_trusted_certificate /etc/letsencrypt/live/staging.bell-computing.com/chain.pem;         #root directory and logfiles         root /srv/users/serverpilot/apps/wordpress/wordpress_nginx/public;         access_log /srv/users/serverpilot/log/wordpress/wordpress_nginx.access.log main;         error_log /srv/users/serverpilot/log/wordpress/wordpress_nginx.error.log;         #proxyset         proxy_set_header Host $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-SSL on;         proxy_set_header X-Forwarded-Proto $scheme;         #includes         include /etc/nginx-sp/vhosts.d/wordpress.d/*.nonssl_conf;         include /etc/nginx-sp/vhosts.d/wordpress.d/*.conf; }

#17

Your e-mail replies are pretty hard to read on the forum because lines with indentation get formatted as preformatted code blocks (with arbitrary long lines). Could you try replying on the forum or else not indenting your replies?

Does /etc/letsencrypt/live/staging.bell-computing.com/fullchain.pem already exist? What names does it cover?

Did you cut out some of the text from the error message? It should have been a complete URL.


#18

Hi Seth

Your e-mail replies are pretty hard to read on the forum because lines with indentation get formatted as preformatted code blocks (with arbitrary long lines). Could you try replying on the forum or else not indenting your replies?

Sorry about that. Is this better?

patbell101:

Then created staging.bell-computing.com.ssl.conf in vhosts.d See below. restarted nginx but qualys still claims certificate name mismatch

Does /etc/letsencrypt/live/staging.bell-computing.com/fullchain.pem already exist? What names does it cover?

I reverted my server to before I was doing this to retain working sites.
But what I had done was to use certbot delete and select staging.bell-computing.com
then I recreated the certificate with
./certbot-auto certonly --webroot -w /srv/users/serverpilot/apps/wordpress/public -d staging.bell-computing.com -d www.staging.bell-computing.com
and added staging.bell-computing.com.ssl.conf to vhosts.d

When I test it with a renew dryrun it fails on a verification error. As far as I can see because it is challenging //staging.bell-computing.com/.well-known/acme-challenge which doesnt exist because staging.bell-competition.com is a subdomain of bell-competition.com.

Domain: staging.bell-computing.com
Type: connection
Detail: Fetching
http://staging.bell-computing.com/.well-known/acme-challenge/yYsecsG-XcUmduP0 4WNpbjR4kSRnlFaZERkjXifzCQ8:
Error getting validation data


#19

I don’t understand this explanation—the location of the challenge file is chosen by the CA and is mandatory. The point of the webroot authentication is that you specify a directory where files could be placed in order to appear in corresponding locations on the public web site. Is /srv/users/serverpilot/apps/wordpress/public not such a directory for http://staging.bell-computing.com/? If it isn’t, you can’t use --webroot with your current configuration.


#20

OK now we’re getting to the core of the problem I think. With a wordpress multisite the domain names requiring certification are all found in the “root” domain of the multisite. In my case the “root” is …wordpress/public/ for all the subdomains (determined by wordpresses database) but the subdomain is for example staging.bell-computing.com. The reason pmcarpetsandflooring works is that it is mapped to a “real” domain. So I can’t use webroot. So what do I do?