imbrish / letsencrypt

Automatic issuing and renewal of Let's Encrypt SSL certificates on shared hostings.
GNU General Public License v3.0
44 stars 7 forks source link

Issues when running on GoDaddy hosting #6

Closed ghost closed 6 years ago

ghost commented 6 years ago

First, this is an amazing tool that makes letsencrypt be viable when managing multiple domains.

I have a working web environment (separate domain from other ticket) with a certificate already set up with LetsEncrypt. I'm trying to use the script to check it.

Instead, it looks like it's requesting a new cert, and failing

'/opt/alt/php56/usr/bin/php' '/home/ricksdomain/letsencrypt/bin/acme' 'setup' '--email' 'letsencrypt@corwyn.net' '--server' 'letsencrypt' '--storage' '/home/ricksdomain/letsencrypt/storage'
Using existing private key ...
    Registering with acme-v01.api.letsencrypt.org/directory ...
    Registration successful. Contacts: mailto:letsencrypt@corwyn.net
'/opt/alt/php56/usr/bin/php' '/home/ricksdomain/letsencrypt/bin/acme' 'check' '--name' 'dnd.ricksdomain.net' '--ttl' '30' '--names' 'dnd.ricksdomain.net' '--server' 'letsencrypt' '--storage' '/home/ricksdomain/letsencrypt/storage'
Certificate not found.
'/opt/alt/php56/usr/bin/php' '/home/ricksdomain/letsencrypt/bin/acme' 'issue' '--domains' 'dnd.ricksdomain.net' '--path' '/home/ricksdomain/public_html/dnd.ricksdomain.net' '--bits' '4096' '--server' 'letsencrypt' '--storage' '/home/ricksdomain/letsencrypt/storage'
Providing payload at http://dnd.ricksdomain.net/.well-known/acme-challenge/j51Pt8jKWDkGkeB4AA9G6wVkNBaJbDfSEmmacXg7Eds
    dnd.ricksdomain.net is now authorized.

    Requesting certificate ...
    Successfully issued certificate.
    See /home/ricksdomain/letsencrypt/storage/certs/acme-v01.api.letsencrypt.org.directory/dnd.ricksdomain.net
Certificate issued for domains: dnd.ricksdomain.net.
'/opt/alt/php56/usr/bin/php' '/home/ricksdomain/letsencrypt/vendor/neurobin/sslic/sslic.php' 'dnd.ricksdomain.net' '/home/ricksdomain/letsencrypt/storage/certs/acme-v01.api.letsencrypt.org.directory/dnd.ricksdomain.net/cert.pem' '/home/ricksdomain/letsencrypt/storage/certs/acme-v01.api.letsencrypt.org.directory/dnd.ricksdomain.net/key.pem' '/home/ricksdomain/letsencrypt/storage/certs/acme-v01.api.letsencrypt.org.directory/dnd.ricksdomain.net/chain.pem'
domain: dnd.ricksdomain.net
The CURL call did not return valid JSON
Error when installing certificate for dnd.ricksdomain.net
imbrish commented 6 years ago

The certificate was issued successfully, only the installation failed. Maybe this is because of wrong credentials in the config?

You should be able to verify existing certificate by copying it over to /home/ricksdomain/letsencrypt/storage/certs/acme-v01.api.letsencrypt.org.directory/dnd.ricksdomain.net. Files to copy are cert.pem, key.pem and chain.pem. I'm not sure if fullchain.pem is also necessary. Remember to setup correct domains and Let's Encrypt email in the config.

Anyway issuing a new certificate is not a big deal, thus I never worried about this detail.

Btw, you can use code block on GitHub to make command output in your comments more readable. This can be done either by wrapping within ``` (triple backtick) or indenting by four spaces.

ghost commented 6 years ago

Issuing new certificates isn't a big deal, until you're having problems getting this script to work. Then it keeps issuing new certs, and you exceed the rate limiting parameters ...

I double-checked the password. It was in fact wrong (I'd changed it per my earlier attachment error!), but fixing it didn't change the behaviour. I'm trying to get this working under GoDaddy, which is probably part of my angst? I created the keys in ZeroSSL, and then installed them via the Godaddy CPanel HTTPS option.

ricksdomain@p3lcpnl0520 [~/letsencrypt]$ bin/letsencrypt
'/opt/alt/php56/usr/bin/php' '/home/ricksdomain/letsencrypt/bin/acme' 'setup' '--email' 'letsencrypt@ricksdomain.net' '--server' 'letsencrypt' '--storage' '/home/ricksdomain/letsencrypt/storage'
Using existing private key ...
    Registering with acme-v01.api.letsencrypt.org/directory ...
    Registration successful. Contacts: mailto:letsencrypt@ricksdomain.net
'/opt/alt/php56/usr/bin/php' '/home/ricksdomain/letsencrypt/bin/acme' 'check' '--name' 'dnd.ricksdomain.net' '--ttl' '30' '--names' 'dnd.ricksdomain.net' '--server' 'letsencrypt' '--storage' '/home/ricksdomain/letsencrypt/storage'
Certificate is valid until 16.09.2018
Certificate still valid for domains: dnd.ricksdomain.net.
'/opt/alt/php56/usr/bin/php' '/home/ricksdomain/letsencrypt/vendor/neurobin/sslic/sslic.php' 'dnd.ricksdomain.net' '/home/ricksdomain/letsencrypt/storage/certs/acme-v01.api.letsencrypt.org.directory/dnd.ricksdomain.net/cert.pem' '/home/ricksdomain/letsencrypt/storage/certs/acme-v01.api.letsencrypt.org.directory/dnd.ricksdomain.net/key.pem' '/home/ricksdomain/letsencrypt/storage/certs/acme-v01.api.letsencrypt.org.directory/dnd.ricksdomain.net/chain.pem'
domain: dnd.ricksdomain.net
The CURL call did not return valid JSON
Error when installing certificate for dnd.ricksdomain.net
imbrish commented 6 years ago

When developing the script I was using server: letsencrypt:staging to avoid that. Issued certs are not real but quotas are way looser. You may want to check if that helps.

I don't remember how expiration of certs is verified, but I'd guess only Let's Encrypt will work. ZeroSSL could be a viable extension but considering name of the repo and fact that I won't use it personally I don't think I'll ever sit down to tackle it. Nevertheless I'm open to PRs.

Problem with debugging anything CPanel related is that the neurobin/sslic dependency doesn't share any useful info. I suspect that GoDaddy may not expose the CPanel API. What's the other hosting you use, the one that worked?

If you'd like to dig a bit deeper, you can add some debug code in /vendor/neurobin/sslic/sslic.php lines 139-140:

$curl_response = curl_exec( $ch );
var_dump($curl_response, curl_error($ch)); // add this line
curl_close( $ch );

And let me know what happens when you manually call:

'/opt/alt/php56/usr/bin/php' '/home/ricksdomain/letsencrypt/vendor/neurobin/sslic/sslic.php' 'dnd.ricksdomain.net' '/home/ricksdomain/letsencrypt/storage/certs/acme-v01.api.letsencrypt.org.directory/dnd.ricksdomain.net/cert.pem' '/home/ricksdomain/letsencrypt/storage/certs/acme-v01.api.letsencrypt.org.directory/dnd.ricksdomain.net/key.pem' '/home/ricksdomain/letsencrypt/storage/certs/acme-v01.api.letsencrypt.org.directory/dnd.ricksdomain.net/chain.pem'
domain: dnd.ricksdomain.net
ghost commented 6 years ago

ZeroSSL doesn't really do anything but create the certs for me as a front end from LetsEncrypt. I'm not running an automated tool there, I just create them and then load them manually into GoDaddy.

Your script correctly determines the expiration.

All three domains are on Godaddy. AFAIK I don't have anything that's actually worked. All three sites I maintain are structured identically. Two I currently have working with SSL (manually). The other was waiting a week for the quote to expire :-) Thanks for the suggestion for using staging. I can now test with that 3rd domain. It returns the same JSON error.

Interesting. When I look at ~/letsencrypt/storage/certs/acme-v01.api.letsencrypt.org.directory/ I see only one of the 3 domains I'm fiddling with (switching the config.yml file back and forth from the 3 different configs). I would expect there should be a: ~/letsencrypt/storage/certs/acme-v01.api.letsencrypt.org.directory/domain1.com ~/letsencrypt/storage/certs/acme-v01.api.letsencrypt.org.directory/domain2.com ~/letsencrypt/storage/certs/acme-v01.api.letsencrypt.org.directory/domain3.com

folder structure there.

Here's the output with that debug line:

output.txt

imbrish commented 6 years ago

Right, I assumed ZeroSSL is Let's Encrypt competitor. In that case the check should work just fine after copying over the certificate files.

If you added all of the domains to a single certificate, only a single directory will be created. It will be named after a first domain on the list, a "common name" for the certificate. In case when issuing fails the related directory will be removed to avoid subsequent errors due to corrupted files.

The response in attached output is CPanel login page. That would suggest that GoDaddy doesn't allow CPanel API access. Is the CPanel located on the same domain as your webpage or you need to access it via a different URL?

If you feel like pursuing things a bit more it'd be good to contact GoDaddy support and ask about CPanel API. We need to access https://localhost:2083/execute/SSL/install_ssl endpoint.

Alternative would be to use yet another script that can automate installing certificates in CPanel by using web interface. If I remember correctly, back when working on my solution, I've seen a few of these.

ghost commented 6 years ago

For each of my iterations, I've never put more than one domain in the .yml file, so (from what you said) I would still expect there to be a folder for each domain?

The page before I launch cpanel is : https://myh.godaddy.com When I select "Cpanel Admin" it goes to: https://p3plcpnl0520.prod.phx3.secureserver.net:2083/cpsess852993978/frontend/gl_paper_lantern/index.html?login=1&post_login=868233759674 [session numbers munged for security]

If I go to: https://p3plcpnl0520.prod.phx3.secureserver.net:2083/execute/SSL/install_ssl I get an "invalid security token" error, and am prompted to log in: HTTP error 401 Invalid security token

The requested URL does not contain your session’s correct security token.

You may have reached this error by copying and pasting a URL from a different cPanel, WHM, or Webmail session into your browser’s address bar. To resolve this situation, please take one of the following steps:

Go back one page and reload the URL, making sure that the /cpsess.../ section of the URL remains the same. Re-enter your account’s password below. This will assign your session a new security token. This new token will prevent you from using other pages of this application that may be open in other tabs.

If I try to log in on that screen, I get a message that the security token has been updated, and am (quickly) redirected to: https://p3plcpnl0520.prod.phx3.secureserver.net:2083/login If I log in on that screen, it logs in to my cpanel session.

imbrish commented 6 years ago

Let's edit the /vendor/neurobin/sslic/sslic.php file again.

This time change line 67:

-$cpanel_host = 'localhost';
+$cpanel_host = 'p3plcpnl0520.prod.phx3.secureserver.net';
imbrish commented 6 years ago

Regarding directories I'd expect it to work exactly as you describe, a separate folder for every certificate named after a first domain of that certificate.

Try manually calling the issue command for every domain/path pair and let me know what happens with directories on each step.

php bin/acme issue --domains domain-1.net --path /home/ricksdomain/public_html/domain-1.net --bits 4096 --server letsencrypt:staging --storage /home/ricksdomain/letsencrypt/storage
php bin/acme issue --domains domain-2.net --path /home/ricksdomain/public_html/domain-2.net --bits 4096 --server letsencrypt:staging --storage /home/ricksdomain/letsencrypt/storage
...
imbrish commented 6 years ago

Also let me see the certificates part of configuration files you use.

ghost commented 6 years ago
certificates:
    # For each certificate, there are a few options.
    # bits:    Number of bits for the domain private key.
    # domains: Map of document roots to domains. Maps each path to one or multiple
    #          domains. If one domain is given, it's automatically converted to an
    #          array. The first domain will be the common name.
    - bits: 4096
      domains:
        /public_html/dnd.ricksdomain.com:
            - dnd.ricksdomain.com
        /sub/public_html:
#            - sub.example.com
#            - www.sub.example.com
ghost commented 6 years ago

With the change to localhost I still get : The CURL call did not return valid JSON Error when installing certificate for dnd.ricksdomain.com

I still have the debug for output, so here it is: output.txt

ghost commented 6 years ago

Manually calling each command (after correcting for the missing slash in front of home in the path) I get (for both of them):

ricksdomain@p3plcpnl0500 [~/letsencrypt]$ php bin/acme issue --domains domain2.com --path /home/ricksdomain/public_html/www.domain2.com --bits 4096 --server letsencrypt:staging --storage /home/ricksdomain/letsencrypt/storage

Providing payload at http://domain2.com/.well-known/acme-challenge/ZYi0o4Tjx2o7-LkTCIPe1oeNWpgHnmHqzQv-WSQgx8o
domain2.com is now authorized.

Requesting certificate ...
Successfully issued certificate.
See /home/ricksdomain/letsencrypt/storage/certs/acme-staging.api.letsencrypt.org.directory/domain2.com

and I get both folders (one for each domain).

imbrish commented 6 years ago

Regarding directories you're plainly doing something wrong. I just tested it myself and everything works, no matter if I call command for multiple certificates or one-by-one, all directories are created.

This is how to correctly setup multiple certificates for many domains:

# List of separate certificates to issue and install.
certificates:
    # This is definition of a first certificate, common name is example.com, taken from
    # the very first domain name on the domains list, no matter the root (public_html etc).
    # This certificate will be placed in the "example.com" directory. It will be a single
    # certificate for both example.com and sub.example.com with www variants!
    - bits: 4096
      domains:
        /public_html:
            - example.com
            - www.example.com
        /sub/public_html:
            - sub.example.com
            - www.sub.example.com
    # This is definition of a second certificate, common name is another.com.
    - bits: 2048
      domains:
        /another/public_html:
            - another.com
            - www.another.com

In your case commenting out only domain names doesn't seem right, you should also remove empty document root directory.


Regarding installation on GoDaddy - ask support if SSL installation is possible with cPanel API and how to do it. Without this knowledge there's no point in wasting more time fiddling around.

ghost commented 6 years ago

Regarding directories, I said "and I get both folders (one for each domain).". In other words, it created both directories correctly.

Will touch base with Godaddy.

imbrish commented 6 years ago

The thing is bin/letsencrypt should also create separate directories and it does for me.

Let me know when you get some sensible answer from them.

imbrish commented 6 years ago

Actually let's close this for now as the original problem was resolved. Feel free to open a new issue about cPanel API support for GoDaddy when you learn something.

ghost commented 6 years ago

"The thing is bin/letsencrypt should also create separate directories and it does for me."

Yes, that is what I'm saying it did.

imbrish commented 6 years ago

Then what was the problem you had before?

ghost commented 6 years ago

I didn't get multiple folders before. When I ran through the sequence of what you asked for, I did.

ghost commented 6 years ago

BTW, this article explains how to access the API on Godaddy. https://tryingtobeawesome.com/encryptdaddy/

imbrish commented 6 years ago

It was just to check if underlying command works. If you delete folders and then run bin/letsencrypt it should have the same effect.

I'll take a look at the article.

Vincent-Noben commented 6 years ago

@ricks03 I managed to install this on godaddy shared hosting by just following the readme. Your link seems do do a lot of extra steps while following the readme was easy peasy... So glad I found this!

ghost commented 6 years ago

Vincent, can you clarify some of your "this" references?

Also, if you're saying you have the letsencrypt environment working on Godaddy, where we've determined (above) that there's a problem with the letsencrypt script accesses the CPANEL API on, I'm curious how you have the letsencrypt script working.

imbrish commented 6 years ago

I think Vincent means the acme.sh tool mentioned in the article you linked.

Vincent-Noben commented 6 years ago

@imbrish @ricks03 I'm sorry, I had two tabs of issues open of this repo and mistakenly commented on the wrong one... "This" just refered to "installing this repo and adding certificates on godaddy". But that's unrelated to your question about "preexisting setup". Sorry

imbrish commented 6 years ago

@ricks03 as https://github.com/imbrish/letsencrypt/issues/7 is fixed, the installation should now work on GoDaddy. Please let me know if you get to verify it yourself. Refer to https://github.com/imbrish/letsencrypt#updating in case of trouble with updating.

Vincent-Noben commented 6 years ago

@ricks03 @imbrish I just want to clarify. I had let'sencrypt on my godaddy server but I renewed it manually each 3months using some free online tool. When I fould this git repo I downloaded the bin folder, put it on my server with the config.yml file you can find below. Then I ran a manual command (from readme) once and all my manually set certificats got renewed by new one's from this tool. After that I added the cron job in the godaddy cronjob panel and it started sending me renew notices every day so that seems to be working as well. I had no problem with setting up the cpanel link before @imbrish made #7 changes. Your username is the one you can see if you open godaddy cpanel --> left top corner --> base directory --> name after the /home/[yourcpanelname] The cpanel password I had alreaddy saved in my password manager, I'm not sure where you can set/reset it or where I got it from.

So yes, I had a manual let'sencrypt on my Godaddy hosting and I had no issue's overwriting it with certificates generated by this tool. But I think my starting situation is different then yours?

config

imbrish commented 6 years ago

@Vincent-Noben thanks for you comment. The exchange with ricks made me think that the installation as it was just didn't work on GoDaddy. Weird, maybe it was some server setup/configuration difference?

Original issue here was that the script is unaware of previously installed certificates and would just renew them on the first run even if they are still valid. I don't think it's a big deal thus this remain unchanged.

Anyway now that we moved on to uapi I'll appreciate if you could update your setup and let me know if everything still works. You'll need to clear/rename storage/certs directory to force re-installation. Update introduces a small change in the configuration because cPanel password is no longer required and user is optional - please replace:

cpanel:
    user: xxx
    password: xxx

to:

user: xxx

Before updating you may want to run git log -1 and note down the commit hash. In case something doesn't work we will be able to easily move back to the version you're currently on.

ghost commented 6 years ago

commit e1d1a605628ceb0c1a9b6e98c6a61cc4882571b4 (I actually renamed the folder, then performed a fresh install).

First, it doesn't work using staging, which I believe makes sense, because Godaddy reports "The certificate could not be installed on the domain âricksdomain.comâ Certificate verification failed!The system did not find the root certificate that corresponds to the supplied Certificate Authority Bundleâs intermediate certificate. Please supply a full Certificate Authority Bundle with the root certificate included."

and it's not a valid cert from staging.

In the environment, the domain already had an installed cert (expiring 9/19) in Godaddy, working for https. I ran the letsencrypt script, and I now have a cert installed from 9/23, replacing the other cert. It's working correctly for https.

I'm super curious how it now works without a password. Will you update the instructions for the Google API? Or are you doing something different?

Rick PS I noted that the config.yml.example file still has the Password: line

imbrish commented 6 years ago

Yep, looks like everything is fine!

Password is no longer necessary, because now the script relies on UAPI which is a command line tool provided by cPanel. It makes changes on the same account you used to connect with SSH thus neither password nor user are needed. User is necessary only when you log in as root and can make changes for anyone on the system.

What do you mean by "update the instructions for the Google API"? Even if you wanted to say cPanel API, I still don't understand.

Maybe you're looking at a wrong version, see latest one.

ghost commented 6 years ago

Per your request, I had included the commit hash for the version I was using.

I meant GoDaddy API, because I assumed you were using the instructions from the link. You're not, so no worries. Thanks.

Vincent-Noben commented 6 years ago

@imbrish I haven't had time to test your request above, but because you asked for the "git log -1", this is the version that's on my godaddy server at the moment: commit 047a2349e6b53f9f2b9ac7772be4d546f42a96f6

imbrish commented 6 years ago

No feedback on this one so I'm going to assume it's fixed. Feel free to start a new issue if something breaks. Thanks!

Vincent-Noben commented 6 years ago

Hi Imbrish,

It's been a while but I just tried to update this.

The log says (translated): "You have to use an IP-adress on the server. '[IP]' is not linked.

EDIT: The first certificate on my yaml file shows up in Godaddy certificates section. But the script stops after that because of above error. EDIT2: Rolling back to previous commit and doing all the nessecary steps now produces the same error. EDIT3: The updated version works now after I manually removed all files from this tools' folder and hard pulled the latest commit etc... No idea why this did not work when just hard pulled with the files still there. (Yes, I updated composer and set correct permissions ;) )

This can be deleted, will install it on a clients' server now ;)