Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
ruanhaishen
Acme.Sh
Commits
e22bcf7c
Commit
e22bcf7c
authored
Jun 17, 2016
by
neil
Committed by
GitHub
Jun 17, 2016
Browse files
support tls (#215)
* support tls-sni-01 '--tls' and '--tlsport' * fix tls doc
parent
869578ce
Changes
2
Show whitespace changes
Inline
Side-by-side
README.md
View file @
e22bcf7c
...
@@ -170,6 +170,20 @@ acme.sh --issue --standalone -d aa.com -d www.aa.com -d cp.aa.com
...
@@ -170,6 +170,20 @@ acme.sh --issue --standalone -d aa.com -d www.aa.com -d cp.aa.com
More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert
More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert
# Use Standalone tls server to issue cert
**(requires you be root/sudoer, or you have permission to listen tcp 443 port)**
acme.sh supports
`tls-sni-01`
validation.
The tcp
`443`
port
**MUST**
be free to listen, otherwise you will be prompted to free the
`443`
port and try again.
```
bash
acme.sh
--issue
--tls
-d
aa.com
-d
www.aa.com
-d
cp.aa.com
```
More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert
# Use Apache mode
# Use Apache mode
**(requires you be root/sudoer, since it is required to interact with apache server)**
**(requires you be root/sudoer, since it is required to interact with apache server)**
...
...
acme.sh
View file @
e22bcf7c
#!/usr/bin/env sh
#!/usr/bin/env sh
VER
=
2.2.
6
VER
=
2.2.
7
PROJECT_NAME
=
"acme.sh"
PROJECT_NAME
=
"acme.sh"
...
@@ -17,6 +17,10 @@ STAGE_CA="https://acme-staging.api.letsencrypt.org"
...
@@ -17,6 +17,10 @@ STAGE_CA="https://acme-staging.api.letsencrypt.org"
VTYPE_HTTP
=
"http-01"
VTYPE_HTTP
=
"http-01"
VTYPE_DNS
=
"dns-01"
VTYPE_DNS
=
"dns-01"
VTYPE_TLS
=
"tls-sni-01"
VTYPE_TLS2
=
"tls-sni-02"
W_TLS
=
"tls"
BEGIN_CSR
=
"-----BEGIN CERTIFICATE REQUEST-----"
BEGIN_CSR
=
"-----BEGIN CERTIFICATE REQUEST-----"
END_CSR
=
"-----END CERTIFICATE REQUEST-----"
END_CSR
=
"-----END CERTIFICATE REQUEST-----"
...
@@ -251,7 +255,7 @@ _dbase64() {
...
@@ -251,7 +255,7 @@ _dbase64() {
fi
fi
}
}
#Usage: hashalg
#Usage: hashalg
[outputhex]
#Output Base64-encoded digest
#Output Base64-encoded digest
_digest
()
{
_digest
()
{
alg
=
"
$1
"
alg
=
"
$1
"
...
@@ -260,8 +264,14 @@ _digest() {
...
@@ -260,8 +264,14 @@ _digest() {
return
1
return
1
fi
fi
outputhex
=
"
$2
"
if
[
"
$alg
"
=
"sha256"
]
;
then
if
[
"
$alg
"
=
"sha256"
]
;
then
if
[
"
$outputhex
"
]
;
then
echo
$(
openssl dgst
-sha256
-hex
|
cut
-d
=
-f
2
)
else
openssl dgst
-sha256
-binary
| _base64
openssl dgst
-sha256
-binary
| _base64
fi
else
else
_err
"
$alg
is not supported yet"
_err
"
$alg
is not supported yet"
return
1
return
1
...
@@ -288,6 +298,86 @@ _sign() {
...
@@ -288,6 +298,86 @@ _sign() {
}
}
# _createkey 2048|ec-256 file
_createkey
()
{
length
=
"
$1
"
f
=
"
$2
"
isec
=
""
if
_startswith
"
$length
"
"ec-"
;
then
isec
=
"1"
length
=
$(
printf
$length
|
cut
-d
'-'
-f
2-100
)
eccname
=
"
$length
"
fi
if
[
-z
"
$length
"
]
;
then
if
[
"
$isec
"
]
;
then
length
=
256
else
length
=
2048
fi
fi
_info
"Use length
$length
"
if
[
"
$isec
"
]
;
then
if
[
"
$length
"
=
"256"
]
;
then
eccname
=
"prime256v1"
fi
if
[
"
$length
"
=
"384"
]
;
then
eccname
=
"secp384r1"
fi
if
[
"
$length
"
=
"521"
]
;
then
eccname
=
"secp521r1"
fi
_info
"Using ec name:
$eccname
"
fi
#generate account key
if
[
"
$isec
"
]
;
then
openssl ecparam
-name
$eccname
-genkey
2>/dev/null
>
"
$f
"
else
openssl genrsa
$length
2>/dev/null
>
"
$f
"
fi
}
#_createcsr cn san_list keyfile csrfile conf
_createcsr
()
{
_debug _createcsr
domain
=
"
$1
"
domainlist
=
"
$2
"
key
=
"
$3
"
csr
=
"
$4
"
csrconf
=
"
$5
"
_debug2 domain
"
$domain
"
_debug2 domainlist
"
$domainlist
"
if
[
-z
"
$domainlist
"
]
||
[
"
$domainlist
"
=
"no"
]
;
then
#single domain
_info
"Single domain"
"
$domain
"
printf
"[ req_distinguished_name ]
\n
[ req ]
\n
distinguished_name = req_distinguished_name
\n
"
>
"
$csrconf
"
openssl req
-new
-sha256
-key
"
$key
"
-subj
"/CN=
$domain
"
-config
"
$csrconf
"
-out
"
$csr
"
else
if
_contains
"
$domainlist
"
","
;
then
alt
=
"DNS:
$(
echo
$domainlist
|
sed
"s/,/,DNS:/g"
)
"
else
alt
=
"DNS:
$domainlist
"
fi
#multi
_info
"Multi domain"
"
$alt
"
printf
"[ req_distinguished_name ]
\n
[ req ]
\n
distinguished_name = req_distinguished_name
\n
req_extensions = v3_req
\n
[ v3_req ]
\n
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
\n
subjectAltName=
$alt
"
>
"
$csrconf
"
openssl req
-new
-sha256
-key
"
$key
"
-subj
"/CN=
$domain
"
-config
"
$csrconf
"
-out
"
$csr
"
fi
}
#_signcsr key csr conf cert
_signcsr
()
{
key
=
"
$1
"
csr
=
"
$2
"
conf
=
"
$3
"
cert
=
"
$4
"
openssl x509
-req
-days
365
-in
"
$csr
"
-signkey
"
$key
"
-extensions
v3_req
-extfile
"
$conf
"
-out
"
$cert
"
}
_ss
()
{
_ss
()
{
_port
=
"
$1
"
_port
=
"
$1
"
...
@@ -364,7 +454,7 @@ createAccountKey() {
...
@@ -364,7 +454,7 @@ createAccountKey() {
return
return
else
else
#generate account key
#generate account key
openssl genrsa
$length
2>/dev/null
>
"
$ACCOUNT_KEY_PATH
"
_createkey
$length
"
$ACCOUNT_KEY_PATH
"
fi
fi
}
}
...
@@ -378,45 +468,12 @@ createDomainKey() {
...
@@ -378,45 +468,12 @@ createDomainKey() {
fi
fi
domain
=
$1
domain
=
$1
length
=
$2
isec
=
""
if
_startswith
"
$length
"
"ec-"
;
then
isec
=
"1"
length
=
$(
printf
$length
|
cut
-d
'-'
-f
2-100
)
eccname
=
"
$length
"
fi
if
[
-z
"
$length
"
]
;
then
if
[
"
$isec
"
]
;
then
length
=
256
else
length
=
2048
fi
fi
_info
"Use length
$length
"
if
[
"
$isec
"
]
;
then
if
[
"
$length
"
=
"256"
]
;
then
eccname
=
"prime256v1"
fi
if
[
"
$length
"
=
"384"
]
;
then
eccname
=
"secp384r1"
fi
if
[
"
$length
"
=
"521"
]
;
then
eccname
=
"secp521r1"
fi
_info
"Using ec name:
$eccname
"
fi
_initpath
$domain
_initpath
$domain
length
=
$2
if
[
!
-f
"
$CERT_KEY_PATH
"
]
||
(
[
"
$FORCE
"
]
&&
!
[
"
$IS_RENEW
"
]
)
;
then
if
[
!
-f
"
$CERT_KEY_PATH
"
]
||
(
[
"
$FORCE
"
]
&&
!
[
"
$IS_RENEW
"
]
)
;
then
#generate account key
_createkey
"
$length
"
"
$CERT_KEY_PATH
"
if
[
"
$isec
"
]
;
then
openssl ecparam
-name
$eccname
-genkey
2>/dev/null
>
"
$CERT_KEY_PATH
"
else
openssl genrsa
$length
2>/dev/null
>
"
$CERT_KEY_PATH
"
fi
else
else
if
[
"
$IS_RENEW
"
]
;
then
if
[
"
$IS_RENEW
"
]
;
then
_info
"Domain key exists, skip"
_info
"Domain key exists, skip"
...
@@ -447,18 +504,7 @@ createCSR() {
...
@@ -447,18 +504,7 @@ createCSR() {
return
return
fi
fi
if
[
-z
"
$domainlist
"
]
||
[
"
$domainlist
"
=
"no"
]
;
then
_createcsr
"
$domain
"
"
$domainlist
"
"
$CERT_KEY_PATH
"
"
$CSR_PATH
"
"
$DOMAIN_SSL_CONF
"
#single domain
_info
"Single domain"
"
$domain
"
printf
"[ req_distinguished_name ]
\n
[ req ]
\n
distinguished_name = req_distinguished_name
\n
"
>
"
$DOMAIN_SSL_CONF
"
openssl req
-new
-sha256
-key
"
$CERT_KEY_PATH
"
-subj
"/CN=
$domain
"
-config
"
$DOMAIN_SSL_CONF
"
-out
"
$CSR_PATH
"
else
alt
=
"DNS:
$(
echo
$domainlist
|
sed
"s/,/,DNS:/g"
)
"
#multi
_info
"Multi domain"
"
$alt
"
printf
"[ req_distinguished_name ]
\n
[ req ]
\n
distinguished_name = req_distinguished_name
\n
[SAN]
\n
subjectAltName=
$alt
"
>
"
$DOMAIN_SSL_CONF
"
openssl req
-new
-sha256
-key
"
$CERT_KEY_PATH
"
-subj
"/CN=
$domain
"
-reqexts
SAN
-config
"
$DOMAIN_SSL_CONF
"
-out
"
$CSR_PATH
"
fi
}
}
...
@@ -821,9 +867,52 @@ _stopserver(){
...
@@ -821,9 +867,52 @@ _stopserver(){
fi
fi
_get
"http://localhost:
$Le_HTTPPort
"
>
/dev/null 2>&1
_get
"http://localhost:
$Le_HTTPPort
"
>
/dev/null 2>&1
_get
"http://localhost:
$Le_TLSPort
"
>
/dev/null 2>&1
}
}
# _starttlsserver san_a san_b port content
_starttlsserver
()
{
_info
"Starting tls server."
san_a
=
"
$1
"
san_b
=
"
$2
"
port
=
"
$3
"
content
=
"
$4
"
_debug san_a
"
$san_a
"
_debug san_b
"
$san_b
"
_debug port
"
$port
"
#create key TLS_KEY
if
!
_createkey
"2048"
"
$TLS_KEY
"
;
then
_err
"Create tls validation key error."
return
1
fi
#create csr
alt
=
"
$san_a
"
if
[
"
$san_b
"
]
;
then
alt
=
"
$alt
,
$san_b
"
fi
if
!
_createcsr
"tls.acme.sh"
"
$alt
"
"
$TLS_KEY
"
"
$TLS_CSR
"
"
$TLS_CONF
"
;
then
_err
"Create tls validation csr error."
return
1
fi
#self signed
if
!
_signcsr
"
$TLS_KEY
"
"
$TLS_CSR
"
"
$TLS_CONF
"
"
$TLS_CERT
"
;
then
_err
"Create tls validation cert error."
return
1
fi
#start openssl
(
printf
"HTTP/1.1 200 OK
\r\n\r\n
$content
"
| openssl s_server
-cert
"
$TLS_CERT
"
-key
"
$TLS_KEY
"
-accept
$port
>
/dev/null 2>&1
)
&
serverproc
=
"
$!
"
sleep
2
_debug serverproc
$serverproc
}
_initpath
()
{
_initpath
()
{
if
[
-z
"
$LE_WORKING_DIR
"
]
;
then
if
[
-z
"
$LE_WORKING_DIR
"
]
;
then
...
@@ -935,6 +1024,20 @@ _initpath() {
...
@@ -935,6 +1024,20 @@ _initpath() {
if
[
-z
"
$CERT_PFX_PATH
"
]
;
then
if
[
-z
"
$CERT_PFX_PATH
"
]
;
then
CERT_PFX_PATH
=
"
$domainhome
/
$domain
.pfx"
CERT_PFX_PATH
=
"
$domainhome
/
$domain
.pfx"
fi
fi
if
[
-z
"
$TLS_CONF
"
]
;
then
TLS_CONF
=
"
$domainhome
/tls.valdation.conf"
fi
if
[
-z
"
$TLS_CERT
"
]
;
then
TLS_CERT
=
"
$domainhome
/tls.valdation.cert"
fi
if
[
-z
"
$TLS_KEY
"
]
;
then
TLS_KEY
=
"
$domainhome
/tls.valdation.key"
fi
if
[
-z
"
$TLS_CSR
"
]
;
then
TLS_CSR
=
"
$domainhome
/tls.valdation.csr"
fi
}
}
...
@@ -1073,6 +1176,12 @@ _clearup() {
...
@@ -1073,6 +1176,12 @@ _clearup() {
_stopserver
$serverproc
_stopserver
$serverproc
serverproc
=
""
serverproc
=
""
_restoreApache
_restoreApache
if
[
-z
"
$DEBUG
"
]
;
then
rm
-f
"
$TLS_CONF
"
rm
-f
"
$TLS_CERT
"
rm
-f
"
$TLS_KEY
"
rm
-f
"
$TLS_CSR
"
fi
}
}
# webroot removelevel tokenfile
# webroot removelevel tokenfile
...
@@ -1171,6 +1280,24 @@ issue() {
...
@@ -1171,6 +1280,24 @@ issue() {
fi
fi
fi
fi
if
_hasfield
"
$Le_Webroot
"
"
$W_TLS
"
;
then
_info
"Standalone tls mode."
if
[
-z
"
$Le_TLSPort
"
]
;
then
Le_TLSPort
=
443
else
_savedomainconf
"Le_TLSPort"
"
$Le_TLSPort
"
fi
netprc
=
"
$(
_ss
"
$Le_TLSPort
"
|
grep
"
$Le_TLSPort
"
)
"
if
[
"
$netprc
"
]
;
then
_err
"
$netprc
"
_err
"tcp port
$Le_TLSPort
is already used by
$(
echo
"
$netprc
"
|
cut
-d
:
-f
4
)
"
_err
"Please stop it first"
return
1
fi
fi
if
_hasfield
"
$Le_Webroot
"
"apache"
;
then
if
_hasfield
"
$Le_Webroot
"
"apache"
;
then
if
!
_setApache
;
then
if
!
_setApache
;
then
_err
"set up apache error. Report error to me."
_err
"set up apache error. Report error to me."
...
@@ -1263,6 +1390,11 @@ issue() {
...
@@ -1263,6 +1390,11 @@ issue() {
if
_startswith
"
$_currentRoot
"
"dns"
;
then
if
_startswith
"
$_currentRoot
"
"dns"
;
then
vtype
=
"
$VTYPE_DNS
"
vtype
=
"
$VTYPE_DNS
"
fi
fi
if
[
"
$_currentRoot
"
=
"
$W_TLS
"
]
;
then
vtype
=
"
$VTYPE_TLS
"
fi
_info
"Getting token for domain"
$d
_info
"Getting token for domain"
$d
if
!
_send_signed_request
"
$API
/acme/new-authz"
"{
\"
resource
\"
:
\"
new-authz
\"
,
\"
identifier
\"
: {
\"
type
\"
:
\"
dns
\"
,
\"
value
\"
:
\"
$d
\"
}}"
;
then
if
!
_send_signed_request
"
$API
/acme/new-authz"
"{
\"
resource
\"
:
\"
new-authz
\"
,
\"
identifier
\"
: {
\"
type
\"
:
\"
dns
\"
,
\"
value
\"
:
\"
$d
\"
}}"
;
then
...
@@ -1406,7 +1538,7 @@ issue() {
...
@@ -1406,7 +1538,7 @@ issue() {
_debug
"keyauthorization"
"
$keyauthorization
"
_debug
"keyauthorization"
"
$keyauthorization
"
_debug
"uri"
"
$uri
"
_debug
"uri"
"
$uri
"
removelevel
=
""
removelevel
=
""
token
=
""
token
=
"
$(
printf
"%s"
"
$keyauthorization
"
|
cut
-d
'.'
-f
1
)
"
_debug
"_currentRoot"
"
$_currentRoot
"
_debug
"_currentRoot"
"
$_currentRoot
"
...
@@ -1439,7 +1571,6 @@ issue() {
...
@@ -1439,7 +1571,6 @@ issue() {
_debug wellknown_path
"
$wellknown_path
"
_debug wellknown_path
"
$wellknown_path
"
token
=
"
$(
printf
"%s"
"
$keyauthorization
"
|
cut
-d
'.'
-f
1
)
"
_debug
"writing token:
$token
to
$wellknown_path
/
$token
"
_debug
"writing token:
$token
to
$wellknown_path
/
$token
"
mkdir
-p
"
$wellknown_path
"
mkdir
-p
"
$wellknown_path
"
...
@@ -1451,6 +1582,37 @@ issue() {
...
@@ -1451,6 +1582,37 @@ issue() {
fi
fi
fi
fi
elif
[
"
$vtype
"
=
"
$VTYPE_TLS
"
]
;
then
#create A
#_hash_A="$(printf "%s" $token | _digest "sha256" "hex" )"
#_debug2 _hash_A "$_hash_A"
#_x="$(echo $_hash_A | cut -c 1-32)"
#_debug2 _x "$_x"
#_y="$(echo $_hash_A | cut -c 33-64)"
#_debug2 _y "$_y"
#_SAN_A="$_x.$_y.token.acme.invalid"
#_debug2 _SAN_A "$_SAN_A"
#create B
_hash_B
=
"
$(
printf
"%s"
$keyauthorization
| _digest
"sha256"
"hex"
)
"
_debug2 _hash_B
"
$_hash_B
"
_x
=
"
$(
echo
$_hash_B
|
cut
-c
1-32
)
"
_debug2 _x
"
$_x
"
_y
=
"
$(
echo
$_hash_B
|
cut
-c
33-64
)
"
_debug2 _y
"
$_y
"
#_SAN_B="$_x.$_y.ka.acme.invalid"
_SAN_B
=
"
$_x
.
$_y
.acme.invalid"
_debug2 _SAN_B
"
$_SAN_B
"
if
!
_starttlsserver
"
$_SAN_B
"
"
$_SAN_A
"
"
$Le_TLSPort
"
"
$keyauthorization
"
;
then
_err
"Start tls server error."
_clearupwebbroot
"
$_currentRoot
"
"
$removelevel
"
"
$token
"
_clearup
return
1
fi
fi
fi
if
!
_send_signed_request
$uri
"{
\"
resource
\"
:
\"
challenge
\"
,
\"
keyAuthorization
\"
:
\"
$keyauthorization
\"
}"
;
then
if
!
_send_signed_request
$uri
"{
\"
resource
\"
:
\"
challenge
\"
,
\"
keyAuthorization
\"
:
\"
$keyauthorization
\"
}"
;
then
...
@@ -2203,6 +2365,7 @@ Parameters:
...
@@ -2203,6 +2365,7 @@ Parameters:
--webroot, -w /path/to/webroot Specifies the web root folder for web root mode.
--webroot, -w /path/to/webroot Specifies the web root folder for web root mode.
--standalone Use standalone mode.
--standalone Use standalone mode.
--tls Use standalone tls mode.
--apache Use apache mode.
--apache Use apache mode.
--dns [dns_cf|dns_dp|dns_cx|/path/to/api/file] Use dns mode or dns api.
--dns [dns_cf|dns_dp|dns_cx|/path/to/api/file] Use dns mode or dns api.
--dnssleep [60] The time in seconds to wait for all the txt records to take effect in dns api mode. Default 60 seconds.
--dnssleep [60] The time in seconds to wait for all the txt records to take effect in dns api mode. Default 60 seconds.
...
@@ -2227,6 +2390,7 @@ Parameters:
...
@@ -2227,6 +2390,7 @@ Parameters:
--accountkey Specifies the account key path, Only valid for the '--install' command.
--accountkey Specifies the account key path, Only valid for the '--install' command.
--days Specifies the days to renew the cert when using '--issue' command. The max value is 80 days.
--days Specifies the days to renew the cert when using '--issue' command. The max value is 80 days.
--httpport Specifies the standalone listening port. Only valid if the server is behind a reverse proxy or load balancer.
--httpport Specifies the standalone listening port. Only valid if the server is behind a reverse proxy or load balancer.
--tlsport Specifies the standalone tls listening port. Only valid if the server is behind a reverse proxy or load balancer.
--listraw Only used for '--list' command, list the certs in raw format.
--listraw Only used for '--list' command, list the certs in raw format.
"
"
}
}
...
@@ -2277,6 +2441,7 @@ _process() {
...
@@ -2277,6 +2441,7 @@ _process() {
_accountkey
=
""
_accountkey
=
""
_certhome
=
""
_certhome
=
""
_httpport
=
""
_httpport
=
""
_tlsport
=
""
_dnssleep
=
""
_dnssleep
=
""
_listraw
=
""
_listraw
=
""
while
[
${#}
-gt
0
]
;
do
while
[
${#}
-gt
0
]
;
do
...
@@ -2399,6 +2564,14 @@ _process() {
...
@@ -2399,6 +2564,14 @@ _process() {
_webroot
=
"
$_webroot
,
$wvalue
"
_webroot
=
"
$_webroot
,
$wvalue
"
fi
fi
;;
;;
--tls
)
wvalue
=
"
$W_TLS
"
if
[
-z
"
$_webroot
"
]
;
then
_webroot
=
"
$wvalue
"
else
_webroot
=
"
$_webroot
,
$wvalue
"
fi
;;
--dns
)
--dns
)
wvalue
=
"dns"
wvalue
=
"dns"
if
!
_startswith
"
$2
"
"-"
;
then
if
!
_startswith
"
$2
"
"-"
;
then
...
@@ -2490,6 +2663,12 @@ _process() {
...
@@ -2490,6 +2663,12 @@ _process() {
Le_HTTPPort
=
"
$_httpport
"
Le_HTTPPort
=
"
$_httpport
"
shift
shift
;;
;;
--tlsport
)
_tlsport
=
"
$2
"
Le_TLSPort
=
"
$_tlsport
"
shift
;;
--listraw
)
--listraw
)
_listraw
=
"raw"
_listraw
=
"raw"
;;
;;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment