acmesh-official / acme.sh Goto Github PK
View Code? Open in Web Editor NEWA pure Unix shell script implementing ACME client protocol
Home Page: https://acme.sh
License: GNU General Public License v3.0
A pure Unix shell script implementing ACME client protocol
Home Page: https://acme.sh
License: GNU General Public License v3.0
[root@s2 le]# le issue /data/wwwroot/xxxxx.com xxxxx.com www.xxxxx.com
Use default length 2048
Generating RSA private key, 2048 bit long modulus
................................................................................................................................+++
.........................................................................................+++
e is 65537 (0x10001)
Use default length 2048
Generating RSA private key, 2048 bit long modulus
.........................+++
......................................+++
e is 65537 (0x10001)
multi domain DNS:www.xxxxx.com
cat: /etc/ssl/openssl.cnf: No such file or directory
unable to find 'distinguished_name' in config
problems making Certificate Request
140032319231816:error:0E06D06C:configuration file routines:NCONF_get_string:no value:conf_lib.c:335:group=req name=distinguished_name
Registering account
Registered
verify each domain
Verifing domain xxxxx.com
verify error:xxxxx.com
[root@s2 le]# lsb_release -a
LSB Version: :base-4.0-amd64:base-4.0-noarch:core-4.0-amd64:core-4.0-noarch:graphics-4.0-amd64:graphics-4.0-noarch:printing-4.0-amd64:printing-4.0-noarch
Distributor ID: CentOS
Description: CentOS release 6.6 (Final)
Release: 6.6
Codename: Final
Hi,
Would it be possible to add support to remove "_acme-challenge" TXT records after validation via DNSAPI?
Regrads
Frank
First try with this script, I typoed a subdomain. I re-ran le issue blah
and and it failed to regenerate the CSR, using the same typoed subdomain.
In fact, looking at the code it looks like even if you do FORCE=true le issue
it won't regenerate the CSR, making it impossible to add SubjectAltNames to a certificate at a later date, which is something I do regularly with the official client.
I suggest either modifying the current $FORCE logic to force regenerating the entire configuration, or perhaps adding $REGEN_CSR and $REGEN_KEY flags to force regeneration of CSRs and keys. Either way, you have to modify the code in issue()
to not clobber the provided arguments with those from $DOMAIN_CONF — or else require the use of le createCSR
and le createDomainKey
for regeneration, but that seems overly cumbersome.
Please use openssl dgst -sha256
instead of openssl sha
.
openssl sha
breaks support for libressl.
现在 DEBUG 直接写在脚本里了,想这样:
DEBUG=1 le issue abc.com
都不行,还要每次去改脚本
Sadly Github as far as I know has no way (other than giving you a star) of saying thanks!
We as a hosting company implemented Let's Encrypt using the official client, not only it has too many dependencies, but they basically removed some functionality that made it almost impossible to issue certificates for our customers.
Saw your script, gave it a test - works like charm! So I just wanted to say thanks on behalf of our company.
That also means we might actually be able to contribute! One nice feature (That I really like from the official client) is that you can define multiple web-roots - also if you want to create a SAN certificate this would be a great feature in this script, but I'll see if I can come up with a way to do it, and submit a pull request!
From looking at the code in le, to register an email address just do
only once at install ?
[email protected] le.sh install
or everytime when issuing a cert ?
[email protected] le issue
when hitting the rate limits for certificates per domain & week, letsencrypt.org returns a 429
response. le.sh
should handle it and inform the user. currently there's just an empty error message outputted:
...
Verifying:my.domain.org
Success
Verify finished, start to sign.
Sign failed:
the contents of curl.header
is
HTTP/1.1 100 Continue
Expires: Fri, 05 Feb 2016 18:18:17 GMT
Cache-Control: max-age=0, no-cache, no-store
Pragma: no-cache
HTTP/1.1 429 Unknown
Server: nginx
Content-Type: application/problem+json
Content-Length: 142
Replay-Nonce: LzW9_1jn3SFxJ7ypBRKdmVkn3M0ZW5dG1EVQZU_viD0
Expires: Fri, 05 Feb 2016 18:18:17 GMT
Cache-Control: max-age=0, no-cache, no-store
Pragma: no-cache
Date: Fri, 05 Feb 2016 18:18:17 GMT
Connection: close
the json body payload would contain the exact error message but is not shown:
{"type":"urn:acme:error:rateLimited","detail":"Error creating new cert :: Too many certificates already issued for: domain.org","status":429}
[2.2.6-RELEASE][[email protected]]/root/le: bash ./le.sh issue /root/certs/ example.com o.example,e.example.com,s.example.com,j.example.com
Use default length 2048
Generating RSA private key, 2048 bit long modulus
................................+++
....+++
e is 65537 (0x10001)
Use default length 2048
Generating RSA private key, 2048 bit long modulus
.............................................+++
.........................................................................................+++
e is 65537 (0x10001)
Multi domain=DNS:o.example.com,DNS:e.example.com,DNS:s.example.com,DNS:j.example.com
error on line -1 of /dev/fd/63
675592508:error:02001002:system library:fopen:No such file or directory:/usr/pfSensesrc/src.RELENG_2_2/secure/lib/libcrypto/../../../crypto/openssl/crypto/bio/bss_file.c:169:fopen('/dev/fd/63','rb')
675592508:error:2006D080:BIO routines:BIO_new_file:no such file:/usr/pfSensesrc/src.RELENG_2_2/secure/lib/libcrypto/../../../crypto/openssl/crypto/bio/bss_file.c:172:
675592508:error:0E078072:configuration file routines:DEF_LOAD:no such file:/usr/pfSensesrc/src.RELENG_2_2/secure/lib/libcrypto/../../../crypto/openssl/crypto/conf/conf_def.c:197:
Create CSR error.
Thanks for this tool. I'm just testing it and found out there is no support for revoking certificates. I think something like that should be added.
I feel like we're getting to the limits of harcoded arguments (with no
meaning default) vs. optional arguments. Wouldn't it be easier to give "-c certfile", "-C cafile", etc.? Especially when bash has a builtin getopts
.
www-data@my-host:~/.le/my.host.com$ ls -lh
total 20K
-rw-r--r-- 1 www-data www-data 1.7K Jan 27 17:30 ca.cer
-rw-r--r-- 1 www-data www-data 2.1K Jan 27 17:30 my.host.com.cer
-rw-r--r-- 1 www-data www-data 487 Jan 27 17:30 my.host.com.conf
-rw-r--r-- 1 www-data www-data 1.6K Jan 27 17:30 my.host.com.csr
-rw-r--r-- 1 www-data www-data 3.2K Jan 27 17:30 my.host.com.key
^^^^^^ WTFFFFFF
Generated private key can be read by any user on this machine which is not secure.
I found some documentation for how us the tls-sni-01 challenge support to a client:
https://github.com/ietf-wg-acme/acme/blob/master/draft-ietf-acme-acme.md
In general simply changing the VTYPE_HTTP to "tls-sni-01" does all the proper steps but fails to verify with a poorly worded error. My understanding is that if the script where to add the proper subjectAlternativeName to a self signed cert and asking the user to install it before proceeding then it SHOULD world.
Just throwing ideas:
I guess the .well-known/ should be deleted after a success validation, just to respect the original content.
Btw, I love this implementation! is the simplest and easiest from all that I checked.
I just tested le on Windows.
It worked.
Make sure cygwin with openssl, curl and crontab installed.
Possible to add support for the official client's --user-agent=
?
Add the following TXT record:
Domain: _acme-challenge.xxx.com
TXT value: wP-0cCLJ2SKkhUdG2CVlR-GrX1hUKj3cK5EWxXbw2KA
Please be aware that you prepend _acme-challenge. before your domain
so the resulting subdomain will be: _acme-challenge.xxx.com
Please add the TXT records to the domains, and retry again.
Is the a command flag on le
to switch between staging and live API servers ?
maybe support the --test-cert
equivalent flag from letsencrypt official client ?
in installcert? On some filesystems this return errors like
cp: preserving permissions for ‘/etc/pve/local/pve-ssl.pem.bak’: Function not implemented
no harm done and permissions are in fact preserved, but we all don't like error messages, are we?
I would wait with a PR after decision on #84 so there won't be merge conflicts
On Line 333, I had to make some small adjustments to the nc command so it would work with the native netcat on CentOS 5, basically just removing the -p and making sure _NC was set to "nc". It was an easy fix though, and thanks for such a handy utility.
333d332
< _NC="nc"
336c335
< echo -e -n "HTTP/1.1 200 OK\r\n\r\n$content" | $_NC -l $Le_HTTPPort -v
---
> echo -e -n "HTTP/1.1 200 OK\r\n\r\n$content" | $_NC -l -p $Le_HTTPPort -vv
338c337
< echo -e -n "HTTP/1.1 200 OK\r\n\r\n$content" | $_NC -l $Le_HTTPPort > /dev/null
---
> echo -e -n "HTTP/1.1 200 OK\r\n\r\n$content" | $_NC -l -p $Le_HTTPPort > /dev/null
I'm thinking about if there is a way for us to submit the Certificate Transparency.
ew-authz error: {"type":"urn:acme:error:malformed","detail":"Error creating new authz :: DNS name does not have enough labels","status":400}
这个是什么原因导致的呢? 真心解决不了了. 还请帮忙解答, 非常感谢
is this a typo ?
0 0 * * * WORKING_DIR="/root/.le" "/root/.le"/le.sh cron > /dev/null
should be ?
0 0 * * * WORKING_DIR="/root/.le" /root/.le/le.sh cron > /dev/null
I used this command to set everything up:
le issue /srv/acme domain.com www.domain.com 2048 /srv/domain.com/ssl/domain.com.chained.crt /srv/somain.com/ssl/domain.com.key "sudo /usr/sbin/service nginx reload"
/usr/sbin/service is set up for this user to be run with sudo without password.
However in the .le/domain.com/domain.com.conf file the following is set up:
Le_RealCACertPath="sudo"
Le_ReloadCmd="/usr/sbin/service"
The rest looks ok and i fixed these entries manually, so it is not a big deal for me, but maybe something that can be resolved in an update.
Also thank you for the work, this was the only solution i got working automated :D
Hey there!
I've been trying to automatize the process of renewing my certificates with le using the automatic CloudFlare API integration, I've tried with all my domains on my account, all of them are "Free plan" except for one that is "Pro plan", somehow it only works for the "Pro plan" one and the others end up in an Error without number.
Error
Error add txt for domain:_acme-challenge.example.com
The v4 API documentation states that creating and updating DNS records into a zone is available for all plans.
Did anyone experience something similar with Free plans?
I opened a support ticket with CloudFlare explaining the problem and I'll post the answer in here when I get one
.
Cheers!
Yes, openssl is not reliable everywhere.
We should think about using other ssl implementations. Such as : GnuTls
as the default configuration of le.sh
no email adress is used, some users might want to add/change their email later on to receive expiration notifications from let's encrypt. the ACME protocol allows updating the email adress assigned to the account. there's a post on let's encrypt's community which explains how updating an existing account would be done:
However, there's another good reason you might want to change the email address on an account: So that you get expiration emails. This is supported in the ACME protocol and in the Boulder software: POST a signed update to your account object (aka registration object) with a new value for the Contacts field. However, unfortunately this is not yet implemented in the Python client. We have an open issue for it: certbot/certbot#1215
maybe le.sh
could provide an "updateAccount" function that takes the current ACCOUNT_EMAIL
value and POSTs it to LE?
Scott posted this today, seems like it could be relevant to this : https://github.com/ScottHelme/Lets-Encrypt-Smart-Renew
From reading the code, it looks like installcert()
installs the CA and the key but not the cert file itself. Is it expected?
Support ECDSA certificate
ECDSA is in staging. We will support it soon.
You provide the option for apache integration, but you did a small but integral mistake which I was not aware too. The Apache 2.4 handles the permissions different.
Order allow,deny
Allow from all
Needs to been replaced by
Require all granted
Hi, I've posted my problem here:
https://community.letsencrypt.org/t/revoking-a-certificate-stupid-version/12305
Basically, I have the following error:
Verify error:Error parsing key authorization file: Invalid key authorization: malformed token
I'm using an url of type 123.456.789.123.xip.io
Do you know what's a token? Why is it malformed? How can I fix it?
Here is an excerpt of my (without DEBUG flag) output:
root@somewhere:~# le issue /home/path/www 123.456.789.123.xip.io www.123.456.789.123.xip.io 4096
Creating account key
Account key exists, skip
Creating domain key
Use length 4096
Creating csr
Multi domain=DNS:www.123.456.789.123.xip.io
Registering account
Already registered
Verify each domain
Getting token for domain=123.456.789.123.xip.io
Getting token for domain=www.123.456.789.123.xip.io
Verifying:123.456.789.123.xip.io
213.165.71.244.xip.io:Verify error:Error parsing key authorization file: Invalid key authorization: malformed token
Hi just need some clarification of how to populate and set the Le_ReloadCmd
flag from the below code
does that mean to set flag to say /usr/bin/ngxreload
I would need use command for subdomain sub.a.com
le issue /path/to/webroot sub.a.com no 4096 no no no /usr/bin/ngxreload
??
issue() {
if [ -z "$2" ] ; then
_err "Usage: le issue webroot|no|apache|dns a.com [www.a.com,b.com,c.com]|no [key-length]|no"
return 1
fi
Le_Webroot="$1"
Le_Domain="$2"
Le_Alt="$3"
Le_Keylength="$4"
Le_RealCertPath="$5"
Le_RealKeyPath="$6"
Le_RealCACertPath="$7"
Le_ReloadCmd="$8"
_initpath $Le_Domain
if [ -f "$DOMAIN_CONF" ] ; then
Le_NextRenewTime=$(grep "^Le_NextRenewTime=" "$DOMAIN_CONF" | cut -d '=' -f 2)
if [ -z "$FORCE" ] && [ "$Le_NextRenewTime" ] && [ "$(date -u "+%s" )" -lt "$Le_NextRenewTime" ] ; then
_info "Skip, Next renewal time is: $(grep "^Le_NextRenewTimeStr" "$DOMAIN_CONF" | cut -d '=' -f 2)"
return 2
fi
fi
if [ "$Le_Alt" == "no" ] ; then
Le_Alt=""
fi
if [ "$Le_Keylength" == "no" ] ; then
Le_Keylength=""
fi
if [ "$Le_RealCertPath" == "no" ] ; then
Le_RealCertPath=""
fi
if [ "$Le_RealKeyPath" == "no" ] ; then
Le_RealKeyPath=""
fi
if [ "$Le_RealCACertPath" == "no" ] ; then
Le_RealCACertPath=""
fi
if [ "$Le_ReloadCmd" == "no" ] ; then
Le_ReloadCmd=""
fi
The _initpath() function calls sudo despite the "Do NOT require to be root/sudoer." comment on the 4th line of README.md.
This leads to spurious errors from cron jobs being sent to system administrators.
Can anyone do me a favor to lend me a domain at godaddy ?
I don't have a domain there for testing.
In the readme you explain the options:
[key-length]|no [cert-file-path]|no [key-file-path]|no
It seems they are optional. What happens if I write no
?? Are the certs not issued? Where are they saved?
I currently run a letsencrypt-auto
command like:
$ /opt/letsencrypt/letsencrypt-auto certonly \
--webroot --agree-tos --keep-until-expiring --rsa-key-size 4096 \
-w /srv/www/domain.com/public -d domain.com -d www.domain.com \
-w /srv/www/subdomain.domain.com/public -d subdomain.domain.com
It would be great to be able to request a single webroot cert for multiple webroots and groups of domain names.
I noticed that I could not get a certificate with aliases for a new domain as the verification fails with a 404 (it looks like the wrong file is requested, no corresponding file exists in the file system), while without aliases everything went fine.
In order to check if it could be repeated, I tried to force a renewal on another system for an existing certificate which also has an alias (www.rfc1149.net
) in addition to the domain name (rfc1149.net
). The original multi-domain certificate was acquired through le.sh
on January 13:
% FORCE=1 ./le.sh renewAll
renewAll
renew rfc1149.net
Account key exists, skip
Generating RSA private key, 2048 bit long modulus
...........................................................+++
...............................................................................+++
e is 65537 (0x10001)
Multi domain=DNS:www.rfc1149.net
Registering account
Already registered
Verify each domain
Geting token for domain=rfc1149.net
Geting token for domain=www.rfc1149.net
Verifying:rfc1149.net
rfc1149.net:Verify error:Invalid response from http://rfc1149.net/.well-known/acme-challenge/NbFnzhCqKPH64xDvAlAM69p_udAz6sFy5wLMaCnDuTo [195.154.227.159]: 404
When I check, indeed, no file with this name is present, another one is:
% ls -l $SITEROOT/.well-known/acme-challenge/
-rw------- 1 sam users 87 Jan 22 19:15 A-xLbrJyK-Zq8cIHa2iMFYXUzj4QxS9L_AphO7UeErA
Is the multi-domain certificate acquisition broken?
In addition, the umask has been honoured, which is probably not a good idea, I'll open another issue for that.
重启nginx的时候提示这个,是什么引起的? 环境是 oneinstack 安装的
nginx: [emerg] cannot get certificate (SSL: error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag error:0D07803A:asn1 encoding routines:ASN1_ITEM_EX_D2I:nested asn1 error:Type=X509)
configuration file /usr/local/tengine/conf/nginx.conf test failed
server {
listen 443 ssl spdy;
ssl_certificate /root/.le/www.xxxxx.com/www.xxxxx.com.cer;
ssl_certificate_key /root/.le/www.xxxxx.com/www.xxxxx.com.key;
ssl_session_timeout 10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-RC4-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:RC4-SHA:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!DSS:!PKS;
ssl_session_cache builtin:1000 shared:SSL:10m;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
server_name www.xxxxx.com xxxxx.com;
access_log /data/wwwlogs/www.xxxxx.com_nginx.log combined;
index index.html index.htm index.php;
root /data/wwwroot/www.xxxxx.com;
if ($host != www.xxxxx.com) {
rewrite ^/(.*)$ $scheme://www.xxxxx.com/$1 permanent;
}
location / {
try_files $uri @apache;
}
location @apache {
proxy_pass http://127.0.0.1:88;
include proxy.conf;
}
location ~ ..(php|php5|cgi|pl)?$ {
proxy_pass http://127.0.0.1:88;
include proxy.conf;
}
location ~ ..(gif|jpg|jpeg|png|bmp|swf|flv|ico)$ {
expires 30d;
access_log off;
}
location ~ .*.(js|css)?$ {
expires 7d;
access_log off;
}
}
USAGE: ./le issue /var/www/hostname.sld.tld/htdocs hostname.sld.tld
Requires that I enable a Virtualhost listening on port 80 for hostname.sld.tld.
Must I have port 80 open and listening for that host or is there a way to allow everything to work on a server that is only serving over port 443?
If I use apache mode instead can I do this without having to expose port 80 and just listen on 443?
Also, I keep my certs in /etc/httpd/ssl/hostname.sld.tld/ and create symlinks to /root/.le/hostname.sld.tld/ for the certs and key, so can I just issue the following which installs the cronjob to renew by default every 80 days?:
le installcert hostname.sld.tld /root/.le/hostname.sld.tld/hostname.sld.tld.cer /root/.le/hostname.sld.tld/hostname.sld.tld.key /root/.le/hostname.sld.tld/ca.cer "/etc/rc.d/rc.httpd reload"
This would install the cronjob which renews and overwrites the /root/.le/hostname.sld.tld/hostname.sld.tld.cer - right?
If so, I'm thinking to add functionality for 'le issue...' or le issue apache...' to create the symlinks in the respective subdirectory under /etc/httpd/ssl// for the .key, ca.cer, and .cer files.
currently when issuing a ECC key based certificate le.sh uses the same directory as for RSA key based certificates. as such it is not possible to issue both a RSA and a (separate) ECC cert for the same domain. maybe suffixing the key type to the directory for non-RSA certificates would be a futureproof fix for this:
RSA key certificate for example.com: $LE_WORKING_DIR/example.com/example.com.cer
ECC key certificate for example.com: $LE_WORKING_DIR/example.com-ecc/example.com.cer
Hi,
I just tested the script in standalone mode and I encounter an error on line 227 and 229.
man nc (-q arg does not exist)
I removed it and the script works.
the return code of the issue
function call within renew()
is not caught, renew
always returns 0
even when an error during renewal happens (f.e. when signing fails due to hitting certs per domain & week limit).
Write a sample ~/.le/account.conf
file when installed for the first time.
Write all the supported macros in it.
such as:
STAGE
DEBUG
FORCE
ACCOUNT_EMAIL
Le_RenewalDays
ACME_DIR
...
According to letsencrypt/boulder#1357, LE support ECDSA account key now, will you change to ECDSA ?
I wanted to check to see what your thoughts are in regards to the dnsapi plugins. I wrote a AWS Route 53 API plugin but it uses the python awscli
tool and jq
to parse JSON and I wasn't sure if you had strict requirements for using only bash or if 3rd party libraries could be a requirement. This probably needs some additional error checking but it's worked decently for me so far: https://gist.github.com/mbentley/d5da0bf962f050dd07ec
Hi!
As nginx requires that CA certificate should be concatenated with site ceritificate, please consider to change installcert to something like that:
if [ "$Le_RealCertPath" ] ; then
if [ -f "$Le_RealCertPath" ] ; then
cp -p "$Le_RealCertPath" "$Le_RealCertPath".bak
fi
cat "$CERT_PATH" > "$Le_RealCertPath"
if [[ "$Le_ReloadCmd" =~ "nginx" ]] ; then
cat "$CA_CERT_PATH" >> "$Le_RealCertPath"
fi
fi
I just tried to run this on alpine linux, and I get the following error:
egrep: bad regex '{[^{]*"type":"http-01"[^}]*': Invalid contents of {}
If i trying to create single domain certificate with ecc algorithm,
le issue /usr/share/nginx/html domain.tld ec-384
using this command, le sets ec-384 as a alternative name.
So it makes error.
How can I issue it?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.