Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
Acme.Sh
Commits
975a7359
Commit
975a7359
authored
Jul 09, 2017
by
neil
Committed by
GitHub
Jul 09, 2017
Browse files
Merge pull request #937 from Neilpang/dev
Dev
parents
dd9df068
ac7361a5
Changes
7
Hide whitespace changes
Inline
Side-by-side
.travis.yml
View file @
975a7359
...
@@ -40,7 +40,7 @@ script:
...
@@ -40,7 +40,7 @@ script:
-
if [ "$TRAVIS_OS_NAME" = "linux" ]; then ~/shfmt -l -w -i 2 . ; fi
-
if [ "$TRAVIS_OS_NAME" = "linux" ]; then ~/shfmt -l -w -i 2 . ; fi
-
if [ "$TRAVIS_OS_NAME" = "linux" ]; then git diff --exit-code && echo "shfmt OK" ; fi
-
if [ "$TRAVIS_OS_NAME" = "linux" ]; then git diff --exit-code && echo "shfmt OK" ; fi
-
if [ "$TRAVIS_OS_NAME" = "linux" ]; then shellcheck -V ; fi
-
if [ "$TRAVIS_OS_NAME" = "linux" ]; then shellcheck -V ; fi
-
if [ "$TRAVIS_OS_NAME" = "linux" ]; then shellcheck **/*.sh && echo "shellcheck OK" ; fi
-
if [ "$TRAVIS_OS_NAME" = "linux" ]; then shellcheck
-e SC2181
**/*.sh && echo "shellcheck OK" ; fi
-
cd ..
-
cd ..
-
git clone https://github.com/Neilpang/acmetest.git && cp -r acme.sh acmetest/ && cd acmetest
-
git clone https://github.com/Neilpang/acmetest.git && cp -r acme.sh acmetest/ && cd acmetest
-
if [ "$TRAVIS_OS_NAME" = "linux" -a "$NGROK_TOKEN" ]; then sudo TEST_LOCAL="$TEST_LOCAL" NGROK_TOKEN="$NGROK_TOKEN" ./letest.sh ; fi
-
if [ "$TRAVIS_OS_NAME" = "linux" -a "$NGROK_TOKEN" ]; then sudo TEST_LOCAL="$TEST_LOCAL" NGROK_TOKEN="$NGROK_TOKEN" ./letest.sh ; fi
...
...
Dockerfile
View file @
975a7359
...
@@ -44,6 +44,7 @@ RUN for verb in help \
...
@@ -44,6 +44,7 @@ RUN for verb in help \
create-domain-key \
create-domain-key \
createCSR \
createCSR \
deactivate \
deactivate \
deactivate-account \
; do \
; do \
printf -- "%b" "#!/usr/bin/env sh\n/root/.acme.sh/acme.sh --${verb} --config-home /acme.sh \"\$@\"" >/usr/local/bin/--${verb} && chmod +x /usr/local/bin/--${verb} \
printf -- "%b" "#!/usr/bin/env sh\n/root/.acme.sh/acme.sh --${verb} --config-home /acme.sh \"\$@\"" >/usr/local/bin/--${verb} && chmod +x /usr/local/bin/--${verb} \
; done
; done
...
...
README.md
View file @
975a7359
...
@@ -336,6 +336,7 @@ You don't have to do anything manually!
...
@@ -336,6 +336,7 @@ You don't have to do anything manually!
1.
NS1.com API
1.
NS1.com API
1.
DuckDNS.org API
1.
DuckDNS.org API
1.
Name.com API
1.
Name.com API
1.
Dyn Managed DNS API
And:
And:
...
...
dnsapi/README.md
View file @
975a7359
...
@@ -540,6 +540,39 @@ acme.sh --issue --dns dns_namecom -d example.com -d www.example.com
...
@@ -540,6 +540,39 @@ acme.sh --issue --dns dns_namecom -d example.com -d www.example.com
For issues, please report to https://github.com/raidenii/acme.sh/issues.
For issues, please report to https://github.com/raidenii/acme.sh/issues.
## 29. Use Dyn Managed DNS API to automatically issue cert
First, login to your Dyn Managed DNS account: https://portal.dynect.net/login/
It is recommended to add a new user specific for API access.
The minimum "Zones & Records Permissions" required are:
```
RecordAdd
RecordUpdate
RecordDelete
RecordGet
ZoneGet
ZoneAddNode
ZoneRemoveNode
ZonePublish
```
Pass the API user credentials to the environment:
```
export DYN_Customer="customer"
export DYN_Username="apiuser"
export DYN_Password="secret"
```
Ok, let's issue a cert now:
```
acme.sh --issue --dns dns_dyn -d example.com -d www.example.com
```
The
`DYN_Customer`
,
`DYN_Username`
and
`DYN_Password`
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.
...
...
dnsapi/dns_aws.sh
View file @
975a7359
...
@@ -208,7 +208,7 @@ aws_rest() {
...
@@ -208,7 +208,7 @@ aws_rest() {
kServiceH
=
"
$(
printf
"
$Service
%s"
| _hmac
"
$Hash
"
"
$kRegionH
"
hex
)
"
kServiceH
=
"
$(
printf
"
$Service
%s"
| _hmac
"
$Hash
"
"
$kRegionH
"
hex
)
"
_debug2 kServiceH
"
$kServiceH
"
_debug2 kServiceH
"
$kServiceH
"
kSigningH
=
"
$(
printf
"aws4_request
%s
"
| _hmac
"
$Hash
"
"
$kServiceH
"
hex
)
"
kSigningH
=
"
$(
printf
"%s"
"aws4_request"
| _hmac
"
$Hash
"
"
$kServiceH
"
hex
)
"
_debug2 kSigningH
"
$kSigningH
"
_debug2 kSigningH
"
$kSigningH
"
signature
=
"
$(
printf
"
$StringToSign
%s"
| _hmac
"
$Hash
"
"
$kSigningH
"
hex
)
"
signature
=
"
$(
printf
"
$StringToSign
%s"
| _hmac
"
$Hash
"
"
$kSigningH
"
hex
)
"
...
...
dnsapi/dns_dyn.sh
0 → 100644
View file @
975a7359
#!/usr/bin/env sh
#
# Dyn.com Domain API
#
# Author: Gerd Naschenweng
# https://github.com/magicdude4eva
#
# Dyn Managed DNS API
# https://help.dyn.com/dns-api-knowledge-base/
#
# It is recommended to add a "Dyn Managed DNS" user specific for API access.
# The "Zones & Records Permissions" required by this script are:
# --
# RecordAdd
# RecordUpdate
# RecordDelete
# RecordGet
# ZoneGet
# ZoneAddNode
# ZoneRemoveNode
# ZonePublish
# --
#
# Pass credentials before "acme.sh --issue --dns dns_dyn ..."
# --
# export DYN_Customer="customer"
# export DYN_Username="apiuser"
# export DYN_Password="secret"
# --
DYN_API
=
"https://api.dynect.net/REST"
#REST_API
######## Public functions #####################
#Usage: add _acme-challenge.www.domain.com "Challenge-code"
dns_dyn_add
()
{
fulldomain
=
"
$1
"
txtvalue
=
"
$2
"
DYN_Customer
=
"
${
DYN_Customer
:-
$(
_readaccountconf_mutable DYN_Customer
)
}
"
DYN_Username
=
"
${
DYN_Username
:-
$(
_readaccountconf_mutable DYN_Username
)
}
"
DYN_Password
=
"
${
DYN_Password
:-
$(
_readaccountconf_mutable DYN_Password
)
}
"
if
[
-z
"
$DYN_Customer
"
]
||
[
-z
"
$DYN_Username
"
]
||
[
-z
"
$DYN_Password
"
]
;
then
DYN_Customer
=
""
DYN_Username
=
""
DYN_Password
=
""
_err
"You must export variables: DYN_Customer, DYN_Username and DYN_Password"
return
1
fi
#save the config variables to the account conf file.
_saveaccountconf_mutable DYN_Customer
"
$DYN_Customer
"
_saveaccountconf_mutable DYN_Username
"
$DYN_Username
"
_saveaccountconf_mutable DYN_Password
"
$DYN_Password
"
if
!
_dyn_get_authtoken
;
then
return
1
fi
if
[
-z
"
$_dyn_authtoken
"
]
;
then
_dyn_end_session
return
1
fi
if
!
_dyn_get_zone
;
then
_dyn_end_session
return
1
fi
if
!
_dyn_add_record
;
then
_dyn_end_session
return
1
fi
if
!
_dyn_publish_zone
;
then
_dyn_end_session
return
1
fi
_dyn_end_session
return
0
}
#Usage: fulldomain txtvalue
#Remove the txt record after validation.
dns_dyn_rm
()
{
fulldomain
=
"
$1
"
txtvalue
=
"
$2
"
DYN_Customer
=
"
${
DYN_Customer
:-
$(
_readaccountconf_mutable DYN_Customer
)
}
"
DYN_Username
=
"
${
DYN_Username
:-
$(
_readaccountconf_mutable DYN_Username
)
}
"
DYN_Password
=
"
${
DYN_Password
:-
$(
_readaccountconf_mutable DYN_Password
)
}
"
if
[
-z
"
$DYN_Customer
"
]
||
[
-z
"
$DYN_Username
"
]
||
[
-z
"
$DYN_Password
"
]
;
then
DYN_Customer
=
""
DYN_Username
=
""
DYN_Password
=
""
_err
"You must export variables: DYN_Customer, DYN_Username and DYN_Password"
return
1
fi
if
!
_dyn_get_authtoken
;
then
return
1
fi
if
[
-z
"
$_dyn_authtoken
"
]
;
then
_dyn_end_session
return
1
fi
if
!
_dyn_get_zone
;
then
_dyn_end_session
return
1
fi
if
!
_dyn_get_record_id
;
then
_dyn_end_session
return
1
fi
if
[
-z
"
$_dyn_record_id
"
]
;
then
_dyn_end_session
return
1
fi
if
!
_dyn_rm_record
;
then
_dyn_end_session
return
1
fi
if
!
_dyn_publish_zone
;
then
_dyn_end_session
return
1
fi
_dyn_end_session
return
0
}
#################### Private functions below ##################################
#get Auth-Token
_dyn_get_authtoken
()
{
_info
"Start Dyn API Session"
data
=
"{
\"
customer_name
\"
:
\"
$DYN_Customer
\"
,
\"
user_name
\"
:
\"
$DYN_Username
\"
,
\"
password
\"
:
\"
$DYN_Password
\"
}"
dyn_url
=
"
$DYN_API
/Session/"
method
=
"POST"
_debug data
"
$data
"
_debug dyn_url
"
$dyn_url
"
export
_H1
=
"Content-Type: application/json"
response
=
"
$(
_post
"
$data
"
"
$dyn_url
"
""
"
$method
"
)
"
sessionstatus
=
"
$(
printf
"%s
\n
"
"
$response
"
| _egrep_o
'"status" *: *"[^"]*'
| _head_n 1 |
sed
's#^"status" *: *"##'
)
"
_debug response
"
$response
"
_debug sessionstatus
"
$sessionstatus
"
if
[
"
$sessionstatus
"
=
"success"
]
;
then
_dyn_authtoken
=
"
$(
printf
"%s
\n
"
"
$response
"
| _egrep_o
'"token" *: *"[^"]*'
| _head_n 1 |
sed
's#^"token" *: *"##'
)
"
_info
"Token received"
_debug _dyn_authtoken
"
$_dyn_authtoken
"
return
0
fi
_dyn_authtoken
=
""
_err
"get token failed"
return
1
}
#fulldomain=_acme-challenge.www.domain.com
#returns
# _dyn_zone=domain.com
_dyn_get_zone
()
{
i
=
2
while
true
;
do
domain
=
"
$(
printf
"%s"
"
$fulldomain
"
|
cut
-d
.
-f
"
$i
-100"
)
"
if
[
-z
"
$domain
"
]
;
then
break
fi
dyn_url
=
"
$DYN_API
/Zone/
$domain
/"
export
_H1
=
"Auth-Token:
$_dyn_authtoken
"
export
_H2
=
"Content-Type: application/json"
response
=
"
$(
_get
"
$dyn_url
"
""
""
)
"
sessionstatus
=
"
$(
printf
"%s
\n
"
"
$response
"
| _egrep_o
'"status" *: *"[^"]*'
| _head_n 1 |
sed
's#^"status" *: *"##'
)
"
_debug dyn_url
"
$dyn_url
"
_debug response
"
$response
"
_debug sessionstatus
"
$sessionstatus
"
if
[
"
$sessionstatus
"
=
"success"
]
;
then
_dyn_zone
=
"
$domain
"
return
0
fi
i
=
$(
_math
"
$i
"
+ 1
)
done
_dyn_zone
=
""
_err
"get zone failed"
return
1
}
#add TXT record
_dyn_add_record
()
{
_info
"Adding TXT record"
data
=
"{
\"
rdata
\"
:{
\"
txtdata
\"
:
\"
$txtvalue
\"
},
\"
ttl
\"
:
\"
300
\"
}"
dyn_url
=
"
$DYN_API
/TXTRecord/
$_dyn_zone
/
$fulldomain
/"
method
=
"POST"
export
_H1
=
"Auth-Token:
$_dyn_authtoken
"
export
_H2
=
"Content-Type: application/json"
response
=
"
$(
_post
"
$data
"
"
$dyn_url
"
""
"
$method
"
)
"
sessionstatus
=
"
$(
printf
"%s
\n
"
"
$response
"
| _egrep_o
'"status" *: *"[^"]*'
| _head_n 1 |
sed
's#^"status" *: *"##'
)
"
_debug response
"
$response
"
_debug sessionstatus
"
$sessionstatus
"
if
[
"
$sessionstatus
"
=
"success"
]
;
then
_info
"TXT Record successfully added"
return
0
fi
_err
"add TXT record failed"
return
1
}
#publish the zone
_dyn_publish_zone
()
{
_info
"Publishing zone"
data
=
"{
\"
publish
\"
:
\"
true
\"
}"
dyn_url
=
"
$DYN_API
/Zone/
$_dyn_zone
/"
method
=
"PUT"
export
_H1
=
"Auth-Token:
$_dyn_authtoken
"
export
_H2
=
"Content-Type: application/json"
response
=
"
$(
_post
"
$data
"
"
$dyn_url
"
""
"
$method
"
)
"
sessionstatus
=
"
$(
printf
"%s
\n
"
"
$response
"
| _egrep_o
'"status" *: *"[^"]*'
| _head_n 1 |
sed
's#^"status" *: *"##'
)
"
_debug response
"
$response
"
_debug sessionstatus
"
$sessionstatus
"
if
[
"
$sessionstatus
"
=
"success"
]
;
then
_info
"Zone published"
return
0
fi
_err
"publish zone failed"
return
1
}
#get record_id of TXT record so we can delete the record
_dyn_get_record_id
()
{
_info
"Getting record_id of TXT record"
dyn_url
=
"
$DYN_API
/TXTRecord/
$_dyn_zone
/
$fulldomain
/"
export
_H1
=
"Auth-Token:
$_dyn_authtoken
"
export
_H2
=
"Content-Type: application/json"
response
=
"
$(
_get
"
$dyn_url
"
""
""
)
"
sessionstatus
=
"
$(
printf
"%s
\n
"
"
$response
"
| _egrep_o
'"status" *: *"[^"]*'
| _head_n 1 |
sed
's#^"status" *: *"##'
)
"
_debug response
"
$response
"
_debug sessionstatus
"
$sessionstatus
"
if
[
"
$sessionstatus
"
=
"success"
]
;
then
_dyn_record_id
=
"
$(
printf
"%s
\n
"
"
$response
"
| _egrep_o
"
\"
data
\"
*: *
\[\"
/REST/TXTRecord/
$_dyn_zone
/
$fulldomain
/[^
\"
]*"
| _head_n 1 |
sed
"s#^
\"
data
\"
*: *
\[\"
/REST/TXTRecord/
$_dyn_zone
/
$fulldomain
/##"
)
"
_debug _dyn_record_id
"
$_dyn_record_id
"
return
0
fi
_dyn_record_id
=
""
_err
"getting record_id failed"
return
1
}
#delete TXT record
_dyn_rm_record
()
{
_info
"Deleting TXT record"
dyn_url
=
"
$DYN_API
/TXTRecord/
$_dyn_zone
/
$fulldomain
/
$_dyn_record_id
/"
method
=
"DELETE"
_debug dyn_url
"
$dyn_url
"
export
_H1
=
"Auth-Token:
$_dyn_authtoken
"
export
_H2
=
"Content-Type: application/json"
response
=
"
$(
_post
""
"
$dyn_url
"
""
"
$method
"
)
"
sessionstatus
=
"
$(
printf
"%s
\n
"
"
$response
"
| _egrep_o
'"status" *: *"[^"]*'
| _head_n 1 |
sed
's#^"status" *: *"##'
)
"
_debug response
"
$response
"
_debug sessionstatus
"
$sessionstatus
"
if
[
"
$sessionstatus
"
=
"success"
]
;
then
_info
"TXT record successfully deleted"
return
0
fi
_err
"delete TXT record failed"
return
1
}
#logout
_dyn_end_session
()
{
_info
"End Dyn API Session"
dyn_url
=
"
$DYN_API
/Session/"
method
=
"DELETE"
_debug dyn_url
"
$dyn_url
"
export
_H1
=
"Auth-Token:
$_dyn_authtoken
"
export
_H2
=
"Content-Type: application/json"
response
=
"
$(
_post
""
"
$dyn_url
"
""
"
$method
"
)
"
_debug response
"
$response
"
_dyn_authtoken
=
""
return
0
}
dnsapi/dns_infoblox.sh
View file @
975a7359
...
@@ -41,10 +41,10 @@ dns_infoblox_add() {
...
@@ -41,10 +41,10 @@ dns_infoblox_add() {
export
_H2
=
"Authorization: Basic
$Infoblox_CredsEncoded
"
export
_H2
=
"Authorization: Basic
$Infoblox_CredsEncoded
"
## Add the challenge record to the Infoblox grid member
## Add the challenge record to the Infoblox grid member
result
=
$(
_post
""
"
$baseurlnObject
"
""
"POST"
)
result
=
"
$(
_post
""
"
$baseurlnObject
"
""
"POST"
)
"
## Let's see if we get something intelligible back from the unit
## Let's see if we get something intelligible back from the unit
if
echo
"
$result
"
| egrep
"record:txt/.*:.*/
$Infoblox_View
"
;
then
if
[
"
$(
echo
"
$result
"
|
_
egrep
_o
"record:txt/.*:.*/
$Infoblox_View
"
)
"
]
;
then
_info
"Successfully created the txt record"
_info
"Successfully created the txt record"
return
0
return
0
else
else
...
@@ -66,7 +66,7 @@ dns_infoblox_rm() {
...
@@ -66,7 +66,7 @@ dns_infoblox_rm() {
_debug txtvalue
"
$txtvalue
"
_debug txtvalue
"
$txtvalue
"
## Base64 encode the credentials
## Base64 encode the credentials
Infoblox_CredsEncoded
=
$(
printf
"%b"
"
$Infoblox_Creds
"
| _base64
)
Infoblox_CredsEncoded
=
"
$(
printf
"%b"
"
$Infoblox_Creds
"
| _base64
)
"
## Construct the HTTP Authorization header
## Construct the HTTP Authorization header
export
_H1
=
"Accept-Language:en-US"
export
_H1
=
"Accept-Language:en-US"
...
@@ -74,17 +74,17 @@ dns_infoblox_rm() {
...
@@ -74,17 +74,17 @@ dns_infoblox_rm() {
## Does the record exist? Let's check.
## Does the record exist? Let's check.
baseurlnObject
=
"https://
$Infoblox_Server
/wapi/v2.2.2/record:txt?name=
$fulldomain
&text=
$txtvalue
&view=
$Infoblox_View
&_return_type=xml-pretty"
baseurlnObject
=
"https://
$Infoblox_Server
/wapi/v2.2.2/record:txt?name=
$fulldomain
&text=
$txtvalue
&view=
$Infoblox_View
&_return_type=xml-pretty"
result
=
$(
_get
"
$baseurlnObject
"
)
result
=
"
$(
_get
"
$baseurlnObject
"
)
"
## Let's see if we get something intelligible back from the grid
## Let's see if we get something intelligible back from the grid
if
echo
"
$result
"
| egrep
"record:txt/.*:.*/
$Infoblox_View
"
;
then
if
[
"
$(
echo
"
$result
"
|
_
egrep
_o
"record:txt/.*:.*/
$Infoblox_View
"
)
"
]
;
then
## Extract the object reference
## Extract the object reference
objRef
=
$(
printf
"%b"
"
$result
"
| _egrep_o
"record:txt/.*:.*/
$Infoblox_View
"
)
objRef
=
"
$(
printf
"%b"
"
$result
"
| _egrep_o
"record:txt/.*:.*/
$Infoblox_View
"
)
"
objRmUrl
=
"https://
$Infoblox_Server
/wapi/v2.2.2/
$objRef
"
objRmUrl
=
"https://
$Infoblox_Server
/wapi/v2.2.2/
$objRef
"
## Delete them! All the stale records!
## Delete them! All the stale records!
rmResult
=
$(
_post
""
"
$objRmUrl
"
""
"DELETE"
)
rmResult
=
"
$(
_post
""
"
$objRmUrl
"
""
"DELETE"
)
"
## Let's see if that worked
## Let's see if that worked
if
echo
"
$rmResult
"
| egrep
"record:txt/.*:.*/
$Infoblox_View
"
;
then
if
[
"
$(
echo
"
$rmResult
"
|
_
egrep
_o
"record:txt/.*:.*/
$Infoblox_View
"
)
"
]
;
then
_info
"Successfully deleted
$objRef
"
_info
"Successfully deleted
$objRef
"
return
0
return
0
else
else
...
...
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