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
086444c7
Commit
086444c7
authored
Feb 20, 2017
by
neil
Committed by
GitHub
Feb 20, 2017
Browse files
Merge pull request #650 from Neilpang/dev
Dev
parents
a2da26cb
1efb2085
Changes
4
Hide whitespace changes
Inline
Side-by-side
README.md
View file @
086444c7
...
@@ -292,6 +292,7 @@ You don't have to do anything manually!
...
@@ -292,6 +292,7 @@ You don't have to do anything manually!
1.
Alwaysdata.com API
1.
Alwaysdata.com API
1.
Linode.com API
1.
Linode.com API
1.
FreeDNS (https://freedns.afraid.org/)
1.
FreeDNS (https://freedns.afraid.org/)
1.
cyon.ch
**More APIs coming soon...**
**More APIs coming soon...**
...
...
acme.sh
View file @
086444c7
...
@@ -1730,7 +1730,7 @@ _setopt() {
...
@@ -1730,7 +1730,7 @@ _setopt() {
_debug3 APP
_debug3 APP
echo
"
$__opt$__sep$__val$__end
"
>>
"
$__conf
"
echo
"
$__opt$__sep$__val$__end
"
>>
"
$__conf
"
fi
fi
_debug
2
"
$(
grep
-n
"^
$__opt$__sep
"
"
$__conf
"
)
"
_debug
3
"
$(
grep
-n
"^
$__opt$__sep
"
"
$__conf
"
)
"
}
}
#_save_conf file key value
#_save_conf file key value
...
...
dnsapi/README.md
View file @
086444c7
...
@@ -305,6 +305,24 @@ Note that you cannot use acme.sh automatic DNS validation for FreeDNS public dom
...
@@ -305,6 +305,24 @@ Note that you cannot use acme.sh automatic DNS validation for FreeDNS public dom
you create under a FreeDNS public domain. You must own the top level domain in order to automaitcally
you create under a FreeDNS public domain. You must own the top level domain in order to automaitcally
validate with acme.sh at FreeDNS.
validate with acme.sh at FreeDNS.
## 16. Use cyon.ch
You only need to set your cyon.ch login credentials.
If you also have 2 Factor Authentication (OTP) enabled, you need to set your secret token too and have
`oathtool`
installed.
```
export CY_Username="your_cyon_username"
export CY_Password="your_cyon_password"
export CY_OTP_Secret="your_otp_secret" # Only required if using 2FA
```
To issue a cert:
```
acme.sh --issue --dns dns_cyon -d example.com -d www.example.com
```
The
`CY_Username`
,
`CY_Password`
and
`CY_OTP_Secret`
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_cyon.sh
0 → 100644
View file @
086444c7
#!/usr/bin/env sh
########
# Custom cyon.ch DNS API for use with [acme.sh](https://github.com/Neilpang/acme.sh)
#
# Usage: acme.sh --issue --dns dns_cyon -d www.domain.com
#
# Dependencies:
# -------------
# - oathtool (When using 2 Factor Authentication)
#
# Issues:
# -------
# Any issues / questions / suggestions can be posted here:
# https://github.com/noplanman/cyon-api/issues
#
# Author: Armando Lüscher <armando@noplanman.ch>
########
dns_cyon_add
()
{
_cyon_load_credentials
\
&&
_cyon_load_parameters
"
$@
"
\
&&
_cyon_print_header
"add"
\
&&
_cyon_login
\
&&
_cyon_change_domain_env
\
&&
_cyon_add_txt
\
&&
_cyon_logout
}
dns_cyon_rm
()
{
_cyon_load_credentials
\
&&
_cyon_load_parameters
"
$@
"
\
&&
_cyon_print_header
"delete"
\
&&
_cyon_login
\
&&
_cyon_change_domain_env
\
&&
_cyon_delete_txt
\
&&
_cyon_logout
}
#########################
### PRIVATE FUNCTIONS ###
#########################
_cyon_load_credentials
()
{
# Convert loaded password to/from base64 as needed.
if
[
"
${
CY_Password_B64
}
"
]
;
then
CY_Password
=
"
$(
printf
"%s"
"
${
CY_Password_B64
}
"
| _dbase64
"multiline"
)
"
elif
[
"
${
CY_Password
}
"
]
;
then
CY_Password_B64
=
"
$(
printf
"%s"
"
${
CY_Password
}
"
| _base64
)
"
fi
if
[
-z
"
${
CY_Username
}
"
]
||
[
-z
"
${
CY_Password
}
"
]
;
then
# Dummy entries to satify script checker.
CY_Username
=
""
CY_Password
=
""
CY_OTP_Secret
=
""
_err
""
_err
"You haven't set your cyon.ch login credentials yet."
_err
"Please set the required cyon environment variables."
_err
""
return
1
fi
# Save the login credentials to the account.conf file.
_debug
"Save credentials to account.conf"
_saveaccountconf CY_Username
"
${
CY_Username
}
"
_saveaccountconf CY_Password_B64
"
$CY_Password_B64
"
if
[
!
-z
"
${
CY_OTP_Secret
}
"
]
;
then
_saveaccountconf CY_OTP_Secret
"
$CY_OTP_Secret
"
else
_clearaccountconf CY_OTP_Secret
fi
}
_cyon_is_idn
()
{
_idn_temp
=
"
$(
printf
"%s"
"
${
1
}
"
|
tr
-d
"0-9a-zA-Z.,-_"
)
"
_idn_temp2
=
"
$(
printf
"%s"
"
${
1
}
"
|
grep
-o
"xn--"
)
"
[
"
$_idn_temp
"
]
||
[
"
$_idn_temp2
"
]
}
_cyon_load_parameters
()
{
# Read the required parameters to add the TXT entry.
# shellcheck disable=SC2018,SC2019
fulldomain
=
"
$(
printf
"%s"
"
${
1
}
"
|
tr
"A-Z"
"a-z"
)
"
fulldomain_idn
=
"
${
fulldomain
}
"
# Special case for IDNs, as cyon needs a domain environment change,
# which uses the "pretty" instead of the punycode version.
if
_cyon_is_idn
"
${
fulldomain
}
"
;
then
if
!
_exists idn
;
then
_err
"Please install idn to process IDN names."
_err
""
return
1
fi
fulldomain
=
"
$(
idn
-u
"
${
fulldomain
}
"
)
"
fulldomain_idn
=
"
$(
idn
-a
"
${
fulldomain
}
"
)
"
fi
_debug fulldomain
"
${
fulldomain
}
"
_debug fulldomain_idn
"
${
fulldomain_idn
}
"
txtvalue
=
"
${
2
}
"
_debug txtvalue
"
${
txtvalue
}
"
# This header is required for curl calls.
_H1
=
"X-Requested-With: XMLHttpRequest"
export
_H1
}
_cyon_print_header
()
{
if
[
"
${
1
}
"
=
"add"
]
;
then
_info
""
_info
"+---------------------------------------------+"
_info
"| Adding DNS TXT entry to your cyon.ch domain |"
_info
"+---------------------------------------------+"
_info
""
_info
" * Full Domain:
${
fulldomain
}
"
_info
" * TXT Value:
${
txtvalue
}
"
_info
""
elif
[
"
${
1
}
"
=
"delete"
]
;
then
_info
""
_info
"+-------------------------------------------------+"
_info
"| Deleting DNS TXT entry from your cyon.ch domain |"
_info
"+-------------------------------------------------+"
_info
""
_info
" * Full Domain:
${
fulldomain
}
"
_info
""
fi
}
_cyon_get_cookie_header
()
{
printf
"Cookie: %s"
"
$(
grep
"cyon="
"
$HTTP_HEADER
"
|
grep
"^Set-Cookie:"
| _tail_n 1 | _egrep_o
'cyon=[^;]*;'
|
tr
-d
';'
)
"
}
_cyon_login
()
{
_info
" - Logging in..."
username_encoded
=
"
$(
printf
"%s"
"
${
CY_Username
}
"
| _url_encode
)
"
password_encoded
=
"
$(
printf
"%s"
"
${
CY_Password
}
"
| _url_encode
)
"
login_url
=
"https://my.cyon.ch/auth/index/dologin-async"
login_data
=
"
$(
printf
"%s"
"username=
${
username_encoded
}
&password=
${
password_encoded
}
&pathname=%2F"
)
"
login_response
=
"
$(
_post
"
$login_data
"
"
$login_url
"
)
"
_debug login_response
"
${
login_response
}
"
# Bail if login fails.
if
[
"
$(
printf
"%s"
"
${
login_response
}
"
| _cyon_get_response_success
)
"
!=
"success"
]
;
then
_err
"
$(
printf
"%s"
"
${
login_response
}
"
| _cyon_get_response_message
)
"
_err
""
return
1
fi
_info
" success"
# NECESSARY!! Load the main page after login, to get the new cookie.
_H2
=
"
$(
_cyon_get_cookie_header
)
"
export
_H2
_get
"https://my.cyon.ch/"
>
/dev/null
# todo: instead of just checking if the env variable is defined, check if we actually need to do a 2FA auth request.
# 2FA authentication with OTP?
if
[
!
-z
"
${
CY_OTP_Secret
}
"
]
;
then
_info
" - Authorising with OTP code..."
if
!
_exists oathtool
;
then
_err
"Please install oathtool to use 2 Factor Authentication."
_err
""
return
1
fi
# Get OTP code with the defined secret.
otp_code
=
"
$(
oathtool
--base32
--totp
"
${
CY_OTP_Secret
}
"
2>/dev/null
)
"
login_otp_url
=
"https://my.cyon.ch/auth/multi-factor/domultifactorauth-async"
login_otp_data
=
"totpcode=
${
otp_code
}
&pathname=%2F&rememberme=0"
login_otp_response
=
"
$(
_post
"
$login_otp_data
"
"
$login_otp_url
"
)
"
_debug login_otp_response
"
${
login_otp_response
}
"
# Bail if OTP authentication fails.
if
[
"
$(
printf
"%s"
"
${
login_otp_response
}
"
| _cyon_get_response_success
)
"
!=
"success"
]
;
then
_err
"
$(
printf
"%s"
"
${
login_otp_response
}
"
| _cyon_get_response_message
)
"
_err
""
return
1
fi
_info
" success"
fi
_info
""
}
_cyon_logout
()
{
_info
" - Logging out..."
_get
"https://my.cyon.ch/auth/index/dologout"
>
/dev/null
_info
" success"
_info
""
}
_cyon_change_domain_env
()
{
_info
" - Changing domain environment..."
# Get the "example.com" part of the full domain name.
domain_env
=
"
$(
printf
"%s"
"
${
fulldomain
}
"
|
sed
-E
-e
's/.*\.(.*\..*)$/\1/'
)
"
_debug
"Changing domain environment to
${
domain_env
}
"
gloo_item_key
=
"
$(
_get
"https://my.cyon.ch/domain/"
|
tr
'\n'
' '
|
sed
-E
-e
"s/.*data-domain=
\"
${
domain_env
}
\"
[^<]*data-itemkey=
\"
([^
\"
]*).*/
\1
/"
)
"
_debug gloo_item_key
"
${
gloo_item_key
}
"
domain_env_url
=
"https://my.cyon.ch/user/environment/setdomain/d/
${
domain_env
}
/gik/
${
gloo_item_key
}
"
domain_env_response
=
"
$(
_get
"
${
domain_env_url
}
"
)
"
_debug domain_env_response
"
${
domain_env_response
}
"
if
!
_cyon_check_if_2fa_missed
"
${
domain_env_response
}
"
;
then return
1
;
fi
domain_env_success
=
"
$(
printf
"%s"
"
${
domain_env_response
}
"
| _egrep_o
'"authenticated":\w*'
|
cut
-d
:
-f
2
)
"
# Bail if domain environment change fails.
if
[
"
${
domain_env_success
}
"
!=
"true"
]
;
then
_err
"
$(
printf
"%s"
"
${
domain_env_response
}
"
| _cyon_get_response_message
)
"
_err
""
return
1
fi
_info
" success"
_info
""
}
_cyon_add_txt
()
{
_info
" - Adding DNS TXT entry..."
add_txt_url
=
"https://my.cyon.ch/domain/dnseditor/add-record-async"
add_txt_data
=
"zone=
${
fulldomain_idn
}
.&ttl=900&type=TXT&value=
${
txtvalue
}
"
add_txt_response
=
"
$(
_post
"
$add_txt_data
"
"
$add_txt_url
"
)
"
_debug add_txt_response
"
${
add_txt_response
}
"
if
!
_cyon_check_if_2fa_missed
"
${
add_txt_response
}
"
;
then return
1
;
fi
add_txt_message
=
"
$(
printf
"%s"
"
${
add_txt_response
}
"
| _cyon_get_response_message
)
"
add_txt_status
=
"
$(
printf
"%s"
"
${
add_txt_response
}
"
| _cyon_get_response_status
)
"
# Bail if adding TXT entry fails.
if
[
"
${
add_txt_status
}
"
!=
"true"
]
;
then
_err
"
${
add_txt_message
}
"
_err
""
return
1
fi
_info
" success (TXT|
${
fulldomain_idn
}
.|
${
txtvalue
}
)"
_info
""
}
_cyon_delete_txt
()
{
_info
" - Deleting DNS TXT entry..."
list_txt_url
=
"https://my.cyon.ch/domain/dnseditor/list-async"
list_txt_response
=
"
$(
_get
"
${
list_txt_url
}
"
|
sed
-e
's/data-hash/\\ndata-hash/g'
)
"
_debug list_txt_response
"
${
list_txt_response
}
"
if
!
_cyon_check_if_2fa_missed
"
${
list_txt_response
}
"
;
then return
1
;
fi
# Find and delete all acme challenge entries for the $fulldomain.
_dns_entries
=
"
$(
printf
"%b
\n
"
"
${
list_txt_response
}
"
|
sed
-n
's/data-hash=\\"\([^"]*\)\\" data-identifier=\\"\([^"]*\)\\".*/\1 \2/p'
)
"
printf
"%s"
"
${
_dns_entries
}
"
|
while
read
-r
_hash _identifier
;
do
dns_type
=
"
$(
printf
"%s"
"
$_identifier
"
|
cut
-d
'|'
-f1
)
"
dns_domain
=
"
$(
printf
"%s"
"
$_identifier
"
|
cut
-d
'|'
-f2
)
"
if
[
"
${
dns_type
}
"
!=
"TXT"
]
||
[
"
${
dns_domain
}
"
!=
"
${
fulldomain_idn
}
."
]
;
then
continue
fi
hash_encoded
=
"
$(
printf
"%s"
"
${
_hash
}
"
| _url_encode
)
"
identifier_encoded
=
"
$(
printf
"%s"
"
${
_identifier
}
"
| _url_encode
)
"
delete_txt_url
=
"https://my.cyon.ch/domain/dnseditor/delete-record-async"
delete_txt_data
=
"
$(
printf
"%s"
"hash=
${
hash_encoded
}
&identifier=
${
identifier_encoded
}
"
)
"
delete_txt_response
=
"
$(
_post
"
$delete_txt_data
"
"
$delete_txt_url
"
)
"
_debug delete_txt_response
"
${
delete_txt_response
}
"
if
!
_cyon_check_if_2fa_missed
"
${
delete_txt_response
}
"
;
then return
1
;
fi
delete_txt_message
=
"
$(
printf
"%s"
"
${
delete_txt_response
}
"
| _cyon_get_response_message
)
"
delete_txt_status
=
"
$(
printf
"%s"
"
${
delete_txt_response
}
"
| _cyon_get_response_status
)
"
# Skip if deleting TXT entry fails.
if
[
"
${
delete_txt_status
}
"
!=
"true"
]
;
then
_err
"
${
delete_txt_message
}
(
${
_identifier
}
)"
else
_info
" success (
${
_identifier
}
)"
fi
done
_info
" done"
_info
""
}
_cyon_get_response_message
()
{
_egrep_o
'"message":"[^"]*"'
|
cut
-d
:
-f
2 |
tr
-d
'"'
}
_cyon_get_response_status
()
{
_egrep_o
'"status":\w*'
|
cut
-d
:
-f
2
}
_cyon_get_response_success
()
{
_egrep_o
'"onSuccess":"[^"]*"'
|
cut
-d
:
-f
2 |
tr
-d
'"'
}
_cyon_check_if_2fa_missed
()
{
# Did we miss the 2FA?
if
test
"
${
1
#*multi_factor_form
}
"
!=
"
${
1
}
"
;
then
_err
" Missed OTP authentication!"
_err
""
return
1
fi
}
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