Double checking that I did everything right before requesting real cert

Hello,

I’ve finally been able to run letsencrypt-auto. I’m using GoDaddy for my domain name registration and for my hosting. I have a Private Virtual Server so I have root access on it. I run Apache 2.2.29 on CentOS 6.

I used the following command to try and generate a test cert:

./letsencrypt-auto certonly --test-cert --standalone --email My_Real_Email@jetbbs.com -d cpanel.jetbbs.com -d whm.jetbbs.com -d webmail.jetbbs.com -d webdisk.jetbbs.com -d cpcalendars.jetbbs.com -d cpcontacts.jetbbs.com -d jetbbs.com -d www.jetbbs.com

It says it succeeded and that my files were in /etc/letsencrypt/live/cpanel.jetbbs.com.

So I modified my httpd.conf file for Apache and start it up. I go to cpanel.JetBBS.com and the https is crossed out. I click on it and it says:
The identity of this website has not been verified.
Server’s certificate is not trusted.

I click on Certificate information. It shows:
Issued to: cpanel.jetbbs.com

Issued by: happy hacker fake CA

Everything looks good so far, right? So than I go to webmail.JetBBS.com. I see the https crossed out again. I do the same, but this time it says it’s issued to cpanel.jetbbs.com, instead of webmail.jetbbs.com. Because these aren’t subdomains but virtual hosts, is this gonna be a problem?

Or when I apply for the real cert, will the cpanel one work for webmail.jetbbs.com and all the other virtualhosts? Thanks!

If I check the certificate for cpanel.jetbbs.com, it correctly notes all the domains you specified in the LE command line:

X509v3 Subject Alternative Name:
    DNS:cpanel.jetbbs.com, DNS:whm.jetbbs.com, DNS:webdisk.jetbbs.com, DNS:cpcontacts.jetbbs.com, DNS:jetbbs.com, DNS:www.jetbbs.com, DNS:webmail.jetbbs.com, DNS:cpcalendars.jetbbs.com

So that’s good.

And the webmail.jetbbs.com certificate is exactly the same… So that’s good too.

When I connect to webmail with my browser, it just says “This server could not prove that it is webmail.jetbbs.com; its security certificate is not trusted by your computer’s operating system.”, which is logical, because of the happy hacker fake CA issuer.

And yes, if you look at the certificate itself (when trying to connect or connected to webmail), the Common Name is cpanel. But you should look at the “Certificate Subject Alternative Names” in the “Details” tab (of Chrome for example, dunno how it shows in Firefox). There you’ll see all your domains. But Common Name will always be cpanel, because that was the first domain you specified with -d.

So, all good, but perhaps you might want to put jetbbs.com in front of all the other -d switches if you’d prefer jetbbs.com as the Common Name.

Omg, so I did it right?! This is freaking awesome! I've been trying to get an SSL cert ever since I got the domain, but because of how expensive they were, I never got one! Symantec wanted 1,999$ a year for a wildcard. GoDaddy wants 300$ a year for a wildcard. I don't need a wildcard, just thought with all those virtual hosts, that would of been the best way to go. I plan on adding subdomains as well.

I will definitely be putting jetbbs.com first.

Just a few quick questions here. When I do the real cert today, lets say a month from now, I create a subdomain. How do I add that? Do I run the letsencrypt command but with only the subdomain for the -d option? Or do I put every single domain that I have in the original line plus the new subdomain?

For renewing, how do I go about doing that? Will it auto-renew? Should I setup a script that auto-renews it some how? Can I create a subdomain in a month but renew them all at the same time, in 3 months from today? Thanks for all the help guys!!! It's much appreciated!!!!

If you're going to be handling a huge number of subdomains, a wildcard is still a great idea. Dealing with tons of names in a cert isn't the funnest thing to do. You can find a plain wildcard for $94/yr at namecheap.com/ssls.com if you are interested.

It depends. Certificates are unique based on the domains they cover. If you only put a subdomain, it will only be valid for that name. If you want to keep everything on a single certificate, you'll need to include every single name and then handle the new certificate you requested.

For the official client, you can use the "--keep" option with the original command and it will renew the matching certificate if it is 30 days or less before expiring. If it's outside that time, it'll just do nothing. You can automate this command daily then and make sure to trigger the services to reload the new certificate.

As far as I can tell: yep.

Both options are valid. You could just generate a single certificate for that subdomain. But it's not really necessary. You could indeed just use the command you'll use "today", but add the new subdomain with an extra -d. Also, in that case you should add --renew-by-default. From the docs:

--renew-by-default    Select renewal by default when domains are a superset
                      of a previously attained cert (often --keep-until-
                      expiring is more appropriate). Implies --expand.
                      (default: False)

This will "prevent" the client from complaining about the currently installed certificate and just go on with getting the new one.

So should I revoke the fake certs that I generated last night? And then, for today, I’ll type this:

/etc/init.d/httpd stop

./letsencrypt-auto certonly --standalone --email my_real_email@JetBBS.com -d jetbbs.com -d www.jetbbs.com -d cpanel.jetbbs.com -d whm.jetbbs.com -d webmail.jetbbs.com -d webdisk.jetbbs.com -d cpcalendars.jetbbs.com -d cpcontacts.jetbbs.com

/etc/init.d/httpd start

Then, create a cronjob in something like /etc/cron.monthly/ssl_certs.cron, that runs monthly(?) that says something like:

# Try to auto-renew the SSL certs
* * 1 * * root /home/spork/src/letsencrypt-auto certonly --standalone --renew-by-default --email my_real_email@JetBBS.com -d jetbbs.com -d www.jetbbs.com -d cpanel.jetbbs.com -d whm.jetbbs.com -d webmail.jetbbs.com -d webdisk.jetbbs.com -d cpcalendars.jetbbs.com -d cpcontacts.jetbbs.com

# Restart Apache to load the new certs, in case they've changed
* * 1 * * root /etc/init.d/httpd restart

That won't be necessary.. In fact, the "happy hacker fake CA" certificates are unsafe by default: the private key is somewhere in GitHub's repository, at least, that's what I have read somewhere. Those certs are useless in every way, except for testing client operation.

Should be fine. Although, you're sure you really need the standalone plugin? Such a hassle, stopping your webserver, restarting it again after the obtaining of the certs.. Doesn't the webroot plugin work?

You could also run a cronjob daily but use the --keep-until-expiring and not --renew-by-default. Forcing a renewal every month would be unnecessary: LE's advice is after 60 days (out of 90), so you'll have a 30 days grace period if for some reason the renewal doesn't go as planned.

Also, there are some nice Bash scripts out there, which you could run in the cronjob and who'll take care of it all.. Dunno where I found them, but surely you could find them in this community.

I think I need the standalone plugin. If not, that'd be even more awesome! The problem is with this setup, there's these virtual hosts. So, I know where the document root directory is, /home/sporkschivago/public_html. And if I put a file there, like test.html, I can go to http://JetBBS.com/test.html and see it. But I can't do something like http://webmail.JetBBS.com/test.html. There's some weird scripts for the cpanel stuff. Even though I know where the document root for it is (it's a different directory), if I put files in there, I cannot access them. It blocks stuff like webmail.JetBBS.com/test.html.

Does that mean I can use the document root and just point it to /home/sporkschivago/public_html and everything will work for the webmail and cpanel stuff? Or would I still need to use the standalone

Well, with the --webroot plugin you can specify the webroot for every separate (sub)domain (if needed, often a www and non-www variant of the same domain use the same webroot folder, so then it’s not needed to specify it twice) as follows:

letsencrypt-auto certonly --email $email --webroot -w /home/sporkschivago/public_html -d jetbbs.com -d www.jetbbs.com -d /path/to/webmail/webroot -d webmail.jetbbs.com -w /path/to/another/domain/public_html -d otherdomain.tld and so on…

If you say this won’t work, because everything you put in the webmail root isn’t accessible from the outside world wide web, than that’s a pity indeed… Perhaps you could check why cPanel blocks access to those files… Otherwise, you’ll be needing the standalone plugin indeed :slightly_smiling:

By the way, I wouldn’t put such a root /etc/init.d/httpd restart on a single cronjob line if I were you. I think it would be better to check the exit status of the letsencrypt-auto command and act accordingly in a Bash script.

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name command to be executed

# Try to renew cert daily
* * 1 * * root /home/spork/src/letsencrypt-auto certonly --standalone --keep-until-expiring  --email my_real_email@JetBBS.com -d jetbbs.com -d www.jetbbs.com -d cpanel.jetbbs.com -d whm.jetbbs.com -d webmail.jetbbs.com -d webdisk.jetbbs.com -d cpcalendars.jetbbs.com -d cpcontacts.jetbbs.com

# Restart Apache to load the new certs, in case they've changed
* * 1 * * root /etc/init.d/httpd restart

For the standalone, this looks better? And this would go into /etc/cron.daily/ssl_cert.cron

I don’t think the files in /etc/cron.daily/ should be the same as a crontab syntax. On my Gentoo install they’re just bash scripts…

Your Apache will restart daily too with this design. Unfortunately, the exit code of the LE client is 0 (all OK) if the client decides it isn’t time yet for a renewal and it keeps the current certificate. In a way that’s correct ofcourse, but unfortunately it has the effect you can’t run something like: letsencrypt-auto --stuff && /etc/init.d/httpd restart.

So… I guess it’s up to you what you think is the most viable option for renewal…

The httpd service supports a “graceful restart” signal which should cause it to re-load the configuration and new certificates (it’s the USR1 signal). You should see if the init script you’re using supports it and use that instead.

Thanks for the advice on the crontab entries. I’m thinking of just writing a bash script and calling that directly. Just gotta see if I call my bash script as root, will the processes I execute in that script execute with root privileges.

I did check into the cpanel stuff. There’s stuff like this in a .htaccess:

# security rules:
# - deny access to files not containing a dot or starting with a dot
#   in all locations except installer directory

So I tried creating a .test directory and tried accessing that via webmail.JetBBS.com/.test and it gives me an error about the token is missing. It won’t load without the security token or something. I think this is how it tells the various users apart. But when I add the security token to the address, the .test shows as not existing. There’s also a bunch of different webmail programs I can choose from, roundcube is one, and then there’s two others, squirrel is another one. So I’d have to do it for all three I think. But that’s just for the webmail stuff. The cpanel has it’s own different document root. I think because of these reasons, standalone might be necessary, unfortunately.

The exit status of Let’s Encrypt kinda sucks. Maybe I can modify the script to return 0 only if it renews.

I just looked at /etc/init.d/httpd and there is a graceful option! I think this is great! From Motoko’s link, my understanding is if there’s users browsing, it won’t restart until that user log-offs and then it’ll restart the child process, so the next user that logs on gets the restarted Apache. The other users that haven’t logged off yet will still be using the old httpd.conf. If I replace the cert though with users still on the site, would this mess things up for them? You know, the cert changing while they’re using the old cert?

The "old" childs will use the old certificate and new child the new one.. Nothing would mess up as far as I can tell.

Thanks guys! So I wrote a simple bash script to call letsencrypt-auto. Here it is. I’ve tried testing it using another shell script, just to make sure I got everything right, and as far as I can tell, it’s good.

#!/bin/bash
letsencrypt="/home/sporkschivago/src/letsencrypt/letsencrypt-auto certonly --standalone --keep-until-expiring  --agree-tos --email my_real_email@JetBBS.com -d jetbbs.com -d www.jetbbs.com -d cpanel.jetbbs.com -d whm.jetbbs.com -d webmail.jetbbs.com -d webdisk.jetbbs.com -d cpcalendars.jetbbs.com -d cpcontacts.jetbbs.com"
#
# Call the letsencrypt-auto program
eval $letsencrypt
#
# And store the exit code in a varible
return_code=$?
#
# Check the exit status of the letsencrypt-auto program
if [ $return_code = "0" ]; then
#       Send an e-mail saying everything went okay...
        mailx -s "SSL Cert Status" My_Real_Email@gmail.com << MSG_BODY_HERE
command line: $letsencrypt

Return Status: successfully ($return_code).
MSG_BODY_HERE

        /etc/init.d/httpd graceful
else
#       Send an e-mail saying something went wrong...
        mailx -s "ERROR: SSL Cert Status" My_Real_Email@gmail.com << MSG_BODY_HERE
command line: $letsencrypt

ERROR: Return Status: ($return_code).

Please check the log file /var/log/letsencrypt/letsencrypt.log for details.
MSG_BODY_HERE

        exit 1
fi
#
exit 0

So now, I just need to put this in cron.daily and it should run daily, right? I have newlines in that file to make it easier to read, but for some reason the site is removing the newlines, so I put #'s where the new lines go.

Hmmm, something is wrong. I put my script in the cron.daily. It runs the letsencrypt-auto and shows it finished successfully, but the certs in /etc/letsencrypt/live still show up as cpanel.jetbbs.com and they’re the old test certs. I check the /var/log/letsencrypt/letsencrypt.log file and this is what it shows:

2016-01-21 01:42:57,189:DEBUG:letsencrypt.cli:Root logging level set at 30
2016-01-21 01:42:57,191:INFO:letsencrypt.cli:Saving debug log to /var/log/letsencrypt/letsencrypt.log
2016-01-21 01:42:57,192:DEBUG:letsencrypt.cli:letsencrypt version: 0.2.0
2016-01-21 01:42:57,192:DEBUG:letsencrypt.cli:Arguments: ['--standalone', '--keep-until-expiring', '--agree-tos', '--email', 'My_Real_Email@JetBBS.com', '-d', 'jetbbs.com', '-d', 'www.jetbbs.com', '-d', 'cpanel.jetbbs.com', '-d', 'whm.jetbbs.com', '-d', 'webmail.jetbbs.com', '-d', 'webdisk.jetbbs.com', '-d', 'cpcalendars.jetbbs.com', '-d', 'cpcontacts.jetbbs.com']
2016-01-21 01:42:57,193:DEBUG:letsencrypt.cli:Discovered plugins: PluginsRegistry(PluginEntryPoint#apache,PluginEntryPoint#webroot,PluginEntryPoint#null,PluginEntryPoint#manual,PluginEntryPoint#standalone)
2016-01-21 01:42:57,202:DEBUG:letsencrypt.cli:Requested authenticator standalone and installer None
2016-01-21 01:42:57,388:DEBUG:letsencrypt.display.ops:Single candidate plugin: * standalone
Description: Automatically use a temporary webserver
Interfaces: IAuthenticator, IPlugin
Entry point: standalone = letsencrypt.plugins.standalone:Authenticator
Initialized: <letsencrypt.plugins.standalone.Authenticator object at 0x7f24851ffc50>
Prep: True
2016-01-21 01:42:57,390:DEBUG:letsencrypt.cli:Selected authenticator <letsencrypt.plugins.standalone.Authenticator object at 0x7f24851ffc50> and installer None
2016-01-21 01:42:57,406:DEBUG:letsencrypt.cli:Picked account: <Account(261d15f95227afb07b6eb2ebbad6bde3)>
2016-01-21 01:42:57,408:DEBUG:root:Sending GET request to https://acme-v01.api.letsencrypt.org/directory. args: (), kwargs: {}
2016-01-21 01:42:57,412:INFO:requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): acme-v01.api.letsencrypt.org
2016-01-21 01:42:58,117:DEBUG:requests.packages.urllib3.connectionpool:"GET /directory HTTP/1.1" 200 263
2016-01-21 01:42:58,119:DEBUG:root:Received <Response [200]>. Headers: {'Content-Length': '263', 'Strict-Transport-Security': 'max-age=604800', 'Server': 'nginx', 'Connection': 'keep-alive', 'Date': 'Thu, 21 Jan 2016 01:42:58 GMT', 'X-Frame-Options': 'DENY', 'Content-Type': 'application/json', 'Replay-Nonce': 'oCNjgb4lL2u3J2q9yKyD5BTtqgR6K3lLfuHsb63yo4A'}. Content: '{"new-authz":"https://acme-v01.api.letsencrypt.org/acme/new-authz","new-cert":"https://acme-v01.api.letsencrypt.org/acme/new-cert","new-reg":"https://acme-v01.api.letsencrypt.org/acme/new-reg","revoke-cert":"https://acme-v01.api.letsencrypt.org/acme/revoke-cert"}'
2016-01-21 01:42:58,119:DEBUG:acme.client:Received response <Response [200]> (headers: {'Content-Length': '263', 'Strict-Transport-Security':'max-age=604800', 'Server': 'nginx', 'Connection': 'keep-alive', 'Date': 'Thu, 21 Jan 2016 01:42:58 GMT', 'X-Frame-Options': 'DENY', 'Content-Type': 'application/json', 'Replay-Nonce': 'oCNjgb4lL2u3J2q9yKyD5BTtqgR6K3lLfuHsb63yo4A'}): '{"new-authz":"https://acme-v01.api.letsencrypt.org/acme/new-authz","new-cert":"https://acme-v01.api.letsencrypt.org/acme/new-cert","new-reg":"https://acme-v01.api.letsencrypt.org/acme/new-reg","revoke-cert":"https://acme-v01.api.letsencrypt.org/acme/revoke-cert"}'
2016-01-21 01:42:58,127:INFO:letsencrypt.reporter:Reporting to user: If you like Let's Encrypt, please consider supporting our work by:

Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
Donating to EFF:                    https://eff.org/donate-le

Does this mean that my cert is revoked for some reason? I don’t see what I did wrong. I just removed the test-cert switch and moved -d jetbbs.com and -d www.jetbbs.com to the front of the -d switches.

I’ve not tried directly, but running with the same domains in any order will usually get you renewing the existing test certificate and using the same server you used for the initial setup. If you don’t have any production certificates yet, I’d backup the /etc/letsencrypt directory, then clean it out and start new against production.

Omg! It works! I actually have a valid SSL certificate!!!! Thank you so much Motoko! I was thinking maybe because my domain was so similar to Jet.com, I'd be considered high risk, even though my domain name existed before theirs did. I can't believe I just had to delete the /etc/letsencrypt directory!!!

I'm a bit worried about renewal though. Because I'm running from a cron script, when it's time for renewal, I set it up to automatically accept the TOS. When I ran the command manually, for the real certs just now, I had to kill httpd. When I renew, do I have to kill httpd before I run letsencrypt-auto or will it just updates the certs and then I restart Apache so it starts using the updated certs?

Thanks!

If you’re using standalone, you’ll need httpd stopped when authenticating. If you use webroot, then you don’t need it off, but you will need to make sure that the well-known directory can be viewed for future authentication.

So even with renewing, I’ll need to stop httpd / Apache and then run letsencrypt if I’m using standalone…and then run letsencrypt to try and update the cert, and then restart httpd?