Merge branch 'dev' into dev

This commit is contained in:
palhaland 2017-03-08 15:06:23 +01:00 committed by GitHub
commit cee0ab87fc
6 changed files with 205 additions and 5 deletions

View File

@ -18,6 +18,18 @@ Twitter: [@neilpangxa](https://twitter.com/neilpangxa)
# [中文说明](https://github.com/Neilpang/acme.sh/wiki/%E8%AF%B4%E6%98%8E) # [中文说明](https://github.com/Neilpang/acme.sh/wiki/%E8%AF%B4%E6%98%8E)
# Who are using **acme.sh**
- [FreeBSD.org](https://blog.crashed.org/letsencrypt-in-freebsd-org/)
- [ruby-china.org](https://ruby-china.org/topics/31983)
- [Proxmox](https://pve.proxmox.com/wiki/HTTPS_Certificate_Configuration_(Version_4.x_and_newer))
- [pfsense](https://github.com/pfsense/FreeBSD-ports/pull/89)
- [webfaction](https://community.webfaction.com/questions/19988/using-letsencrypt)
- [Loadbalancer.org](https://www.loadbalancer.org/blog/loadbalancer-org-with-lets-encrypt-quick-and-dirty)
- [discourse.org](https://meta.discourse.org/t/setting-up-lets-encrypt/40709)
- [Centminmod](http://centminmod.com/letsencrypt-acmetool-https.html)
- [splynx](https://forum.splynx.com/t/free-ssl-cert-for-splynx-lets-encrypt/297)
- [archlinux](https://aur.archlinux.org/packages/acme.sh-git/)
- [more...](https://github.com/Neilpang/acme.sh/wiki/Blogs-and-tutorials)
# Tested OS # Tested OS
@ -295,6 +307,7 @@ You don't have to do anything manually!
1. cyon.ch 1. cyon.ch
1. Domain-Offensive/Resellerinterface/Domainrobot API 1. Domain-Offensive/Resellerinterface/Domainrobot API
1. Gandi LiveDNS API 1. Gandi LiveDNS API
1. Knot DNS API
**More APIs coming soon...** **More APIs coming soon...**

18
acme.sh
View File

@ -299,6 +299,16 @@ _secure_debug3() {
fi fi
} }
_upper_case() {
# shellcheck disable=SC2018,SC2019
tr 'a-z' 'A-Z'
}
_lower_case() {
# shellcheck disable=SC2018,SC2019
tr 'A-Z' 'a-z'
}
_startswith() { _startswith() {
_str="$1" _str="$1"
_sub="$2" _sub="$2"
@ -2462,7 +2472,7 @@ _setNginx() {
fi fi
_debug "Start detect nginx conf for $_d from:$_start_f" _debug "Start detect nginx conf for $_d from:$_start_f"
if ! _checkConf "$_d" "$_start_f"; then if ! _checkConf "$_d" "$_start_f"; then
"Can not find conf file for domain $d" _err "Can not find conf file for domain $d"
return 1 return 1
fi fi
_info "Found conf file: $FOUND_REAL_NGINX_CONF" _info "Found conf file: $FOUND_REAL_NGINX_CONF"
@ -2546,7 +2556,7 @@ _checkConf() {
if [ ! -f "$2" ] && ! echo "$2" | grep '*$' >/dev/null && echo "$2" | grep '*' >/dev/null; then if [ ! -f "$2" ] && ! echo "$2" | grep '*$' >/dev/null && echo "$2" | grep '*' >/dev/null; then
_debug "wildcard" _debug "wildcard"
for _w_f in $2; do for _w_f in $2; do
if _checkConf "$1" "$_w_f"; then if [ -f "$_w_f"] && _checkConf "$1" "$_w_f"; then
return 0 return 0
fi fi
done done
@ -2559,9 +2569,9 @@ _checkConf() {
FOUND_REAL_NGINX_CONF="$2" FOUND_REAL_NGINX_CONF="$2"
return 0 return 0
fi fi
if grep "^ *include *.*;" "$2" >/dev/null; then if cat "$2" | tr "\t" " " | grep "^ *include *.*;" >/dev/null; then
_debug "Try include files" _debug "Try include files"
for included in $(grep "^ *include *.*;" "$2" | sed "s/include //" | tr -d " ;"); do for included in $(cat "$2" | tr "\t" " " | grep "^ *include *.*;" | sed "s/include //" | tr -d " ;"); do
_debug "check included $included" _debug "check included $included"
if _checkConf "$1" "$included"; then if _checkConf "$1" "$included"; then
return 0 return 0

View File

@ -72,7 +72,13 @@ export DEPLOY_EXIM4_RELOAD="/etc/init.d/exim4 restart"
acme.sh --deploy -d ftp.example.com --deploy-hook exim4 acme.sh --deploy -d ftp.example.com --deploy-hook exim4
``` ```
## 6. Deploy the cert to remote routeros ## 6. Deploy the cert to OSX Keychain
```sh
acme.sh --deploy -d ftp.example.com --deploy-hook keychain
```
## 7. Deploy the cert to remote routeros
```sh ```sh
acme.sh --deploy -d ftp.example.com --deploy-hook routeros acme.sh --deploy -d ftp.example.com --deploy-hook routeros

31
deploy/keychain.sh Normal file
View File

@ -0,0 +1,31 @@
#!/usr/bin/env sh
#Here is a sample custom api script.
#This file name is "myapi.sh"
#So, here must be a method myapi_deploy()
#Which will be called by acme.sh to deploy the cert
#returns 0 means success, otherwise error.
######## Public functions #####################
#domain keyfile certfile cafile fullchain
keychain_deploy() {
_cdomain="$1"
_ckey="$2"
_ccert="$3"
_cca="$4"
_cfullchain="$5"
_debug _cdomain "$_cdomain"
_debug _ckey "$_ckey"
_debug _ccert "$_ccert"
_debug _cca "$_cca"
_debug _cfullchain "$_cfullchain"
/usr/bin/security import "$_ckey" -k "/Library/Keychains/System.keychain"
/usr/bin/security import "$_ccert" -k "/Library/Keychains/System.keychain"
/usr/bin/security import "$_cca" -k "/Library/Keychains/System.keychain"
/usr/bin/security import "$_cfullchain" -k "/Library/Keychains/System.keychain"
return 0
}

View File

@ -349,6 +349,51 @@ Ok, let's issue a cert now:
acme.sh --issue --dns dns_gandi_livedns -d example.com -d www.example.com acme.sh --issue --dns dns_gandi_livedns -d example.com -d www.example.com
``` ```
## 19. Use Knot (knsupdate) DNS API to automatically issue cert
First, generate a TSIG key for updating the zone.
```
keymgr tsig generate acme_key algorithm hmac-sha512 > /etc/knot/acme.key
```
Include this key in your knot configuration file.
```
include: /etc/knot/acme.key
```
Next, configure your zone to allow dynamic updates.
Dynamic updates for the zone are allowed via proper ACL rule with the `update` action. For in-depth instructions, please see [Knot DNS's documentation](https://www.knot-dns.cz/documentation/).
```
acl:
- id: acme_acl
address: 192.168.1.0/24
key: acme_key
action: update
zone:
- domain: example.com
file: example.com.zone
acl: acme_acl
```
Finally, make the DNS server and TSIG Key available to `acme.sh`
```
export KNOT_SERVER="dns.example.com"
export KNOT_KEY=`grep \# /etc/knot/acme.key | cut -d' ' -f2`
```
Ok, let's issue a cert now:
```
acme.sh --issue --dns dns_knot -d example.com -d www.example.com
```
The `KNOT_SERVER` and `KNOT_KEY` settings will be saved in `~/.acme.sh/account.conf` and will be reused when needed.
# Use custom API # Use custom API
If your API is not supported yet, you can write your own DNS API. If your API is not supported yet, you can write your own DNS API.

95
dnsapi/dns_knot.sh Normal file
View File

@ -0,0 +1,95 @@
#!/usr/bin/env sh
######## Public functions #####################
#Usage: dns_knot_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_knot_add() {
fulldomain=$1
txtvalue=$2
_checkKey || return 1
[ -n "${KNOT_SERVER}" ] || KNOT_SERVER="localhost"
# save the dns server and key to the account.conf file.
_saveaccountconf KNOT_SERVER "${KNOT_SERVER}"
_saveaccountconf KNOT_KEY "${KNOT_KEY}"
if ! _get_root "$fulldomain"; then
_err "Domain does not exist."
return 1
fi
_info "Adding ${fulldomain}. 60 TXT \"${txtvalue}\""
knsupdate -y "${KNOT_KEY}" <<EOF
server ${KNOT_SERVER}
zone ${_domain}.
update add ${fulldomain}. 60 TXT "${txtvalue}"
send
quit
EOF
if [ $? -ne 0 ]; then
_err "Error updating domain."
return 1
fi
_info "Domain TXT record successfully added."
return 0
}
#Usage: dns_knot_rm _acme-challenge.www.domain.com
dns_knot_rm() {
fulldomain=$1
_checkKey || return 1
[ -n "${KNOT_SERVER}" ] || KNOT_SERVER="localhost"
if ! _get_root "$fulldomain"; then
_err "Domain does not exist."
return 1
fi
_info "Removing ${fulldomain}. TXT"
knsupdate -y "${KNOT_KEY}" <<EOF
server ${KNOT_SERVER}
zone ${_domain}.
update del ${fulldomain}. TXT
send
quit
EOF
if [ $? -ne 0 ]; then
_err "error updating domain"
return 1
fi
_info "Domain TXT record successfully deleted."
return 0
}
#################### Private functions below ##################################
# _acme-challenge.www.domain.com
# returns
# _domain=domain.com
_get_root() {
domain=$1
i="$(echo "$fulldomain" | tr '.' ' ' | wc -w)"
i=$(_math "$i" - 1)
while true; do
h=$(printf "%s" "$domain" | cut -d . -f "$i"-100)
if [ -z "$h" ]; then
return 1
fi
_domain="$h"
return 0
done
_debug "$domain not found"
return 1
}
_checkKey() {
if [ -z "${KNOT_KEY}" ]; then
_err "You must specify a TSIG key to authenticate the request."
return 1
fi
}