Marvo2011
2 years ago
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
46 changed files with 1849 additions and 559 deletions
-
196.github/workflows/DNS.yml
-
71.github/workflows/DragonFlyBSD.yml
-
21.github/workflows/FreeBSD.yml
-
6.github/workflows/Linux.yml
-
5.github/workflows/MacOS.yml
-
72.github/workflows/NetBSD.yml
-
76.github/workflows/OpenBSD.yml
-
16.github/workflows/PebbleStrict.yml
-
21.github/workflows/Solaris.yml
-
14.github/workflows/Ubuntu.yml
-
5.github/workflows/Windows.yml
-
4.github/workflows/dockerhub.yml
-
19.github/workflows/issue.yml
-
30.github/workflows/pr_dns.yml
-
30.github/workflows/pr_notify.yml
-
5.github/workflows/shellcheck.yml
-
42README.md
-
49acme.sh
-
16deploy/mailcow.sh
-
132deploy/proxmoxve.sh
-
4deploy/qiniu.sh
-
36dnsapi/dns_aws.sh
-
11dnsapi/dns_cf.sh
-
2dnsapi/dns_cyon.sh
-
234dnsapi/dns_dnsservices.sh
-
4dnsapi/dns_edgedns.sh
-
4dnsapi/dns_gcloud.sh
-
50dnsapi/dns_gd.sh
-
24dnsapi/dns_huaweicloud.sh
-
30dnsapi/dns_ionos.sh
-
12dnsapi/dns_ispconfig.sh
-
303dnsapi/dns_kas.sh
-
147dnsapi/dns_la.sh
-
1dnsapi/dns_miab.sh
-
16dnsapi/dns_mydnsjp.sh
-
4dnsapi/dns_namecheap.sh
-
6dnsapi/dns_nederhost.sh
-
2dnsapi/dns_oci.sh
-
4dnsapi/dns_opnsense.sh
-
8dnsapi/dns_ovh.sh
-
4dnsapi/dns_regru.sh
-
4dnsapi/dns_selectel.sh
-
21dnsapi/dns_ultra.sh
-
22dnsapi/dns_vultr.sh
-
48dnsapi/dns_world4you.sh
-
45notify/slack_app.sh
@ -0,0 +1,71 @@ |
|||||
|
name: DragonFlyBSD |
||||
|
on: |
||||
|
push: |
||||
|
branches: |
||||
|
- '*' |
||||
|
paths: |
||||
|
- '*.sh' |
||||
|
- '.github/workflows/DragonFlyBSD.yml' |
||||
|
|
||||
|
pull_request: |
||||
|
branches: |
||||
|
- dev |
||||
|
paths: |
||||
|
- '*.sh' |
||||
|
- '.github/workflows/DragonFlyBSD.yml' |
||||
|
|
||||
|
concurrency: |
||||
|
group: ${{ github.workflow }}-${{ github.ref }} |
||||
|
cancel-in-progress: true |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
jobs: |
||||
|
DragonFlyBSD: |
||||
|
strategy: |
||||
|
matrix: |
||||
|
include: |
||||
|
- TEST_ACME_Server: "LetsEncrypt.org_test" |
||||
|
CA_ECDSA: "" |
||||
|
CA: "" |
||||
|
CA_EMAIL: "" |
||||
|
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 |
||||
|
#- TEST_ACME_Server: "ZeroSSL.com" |
||||
|
# CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" |
||||
|
# CA: "ZeroSSL RSA Domain Secure Site CA" |
||||
|
# CA_EMAIL: "githubtest@acme.sh" |
||||
|
# TEST_PREFERRED_CHAIN: "" |
||||
|
runs-on: macos-12 |
||||
|
env: |
||||
|
TEST_LOCAL: 1 |
||||
|
TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }} |
||||
|
CA_ECDSA: ${{ matrix.CA_ECDSA }} |
||||
|
CA: ${{ matrix.CA }} |
||||
|
CA_EMAIL: ${{ matrix.CA_EMAIL }} |
||||
|
TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }} |
||||
|
steps: |
||||
|
- uses: actions/checkout@v2 |
||||
|
- uses: vmactions/cf-tunnel@v0.0.3 |
||||
|
id: tunnel |
||||
|
with: |
||||
|
protocol: http |
||||
|
port: 8080 |
||||
|
- name: Set envs |
||||
|
run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV |
||||
|
- name: Clone acmetest |
||||
|
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ |
||||
|
- uses: vmactions/dragonflybsd-vm@v0 |
||||
|
with: |
||||
|
envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN' |
||||
|
copyback: "false" |
||||
|
nat: | |
||||
|
"8080": "80" |
||||
|
prepare: | |
||||
|
pkg install -y curl socat |
||||
|
usesh: true |
||||
|
run: | |
||||
|
cd ../acmetest \ |
||||
|
&& ./letest.sh |
||||
|
|
||||
|
|
@ -0,0 +1,72 @@ |
|||||
|
name: NetBSD |
||||
|
on: |
||||
|
push: |
||||
|
branches: |
||||
|
- '*' |
||||
|
paths: |
||||
|
- '*.sh' |
||||
|
- '.github/workflows/NetBSD.yml' |
||||
|
|
||||
|
pull_request: |
||||
|
branches: |
||||
|
- dev |
||||
|
paths: |
||||
|
- '*.sh' |
||||
|
- '.github/workflows/NetBSD.yml' |
||||
|
|
||||
|
concurrency: |
||||
|
group: ${{ github.workflow }}-${{ github.ref }} |
||||
|
cancel-in-progress: true |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
jobs: |
||||
|
NetBSD: |
||||
|
strategy: |
||||
|
matrix: |
||||
|
include: |
||||
|
- TEST_ACME_Server: "LetsEncrypt.org_test" |
||||
|
CA_ECDSA: "" |
||||
|
CA: "" |
||||
|
CA_EMAIL: "" |
||||
|
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 |
||||
|
#- TEST_ACME_Server: "ZeroSSL.com" |
||||
|
# CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" |
||||
|
# CA: "ZeroSSL RSA Domain Secure Site CA" |
||||
|
# CA_EMAIL: "githubtest@acme.sh" |
||||
|
# TEST_PREFERRED_CHAIN: "" |
||||
|
runs-on: macos-12 |
||||
|
env: |
||||
|
TEST_LOCAL: 1 |
||||
|
TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }} |
||||
|
CA_ECDSA: ${{ matrix.CA_ECDSA }} |
||||
|
CA: ${{ matrix.CA }} |
||||
|
CA_EMAIL: ${{ matrix.CA_EMAIL }} |
||||
|
TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }} |
||||
|
steps: |
||||
|
- uses: actions/checkout@v2 |
||||
|
- uses: vmactions/cf-tunnel@v0.0.3 |
||||
|
id: tunnel |
||||
|
with: |
||||
|
protocol: http |
||||
|
port: 8080 |
||||
|
- name: Set envs |
||||
|
run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV |
||||
|
- name: Clone acmetest |
||||
|
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ |
||||
|
- uses: vmactions/netbsd-vm@v0 |
||||
|
with: |
||||
|
envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN' |
||||
|
nat: | |
||||
|
"8080": "80" |
||||
|
prepare: | |
||||
|
export PKG_PATH="http://cdn.NetBSD.org/pub/pkgsrc/packages/NetBSD/$(uname -p)/$(uname -r|cut -f '1 2' -d.)/All/" |
||||
|
pkg_add curl socat |
||||
|
usesh: true |
||||
|
copyback: false |
||||
|
run: | |
||||
|
cd ../acmetest \ |
||||
|
&& ./letest.sh |
||||
|
|
||||
|
|
@ -0,0 +1,76 @@ |
|||||
|
name: OpenBSD |
||||
|
on: |
||||
|
push: |
||||
|
branches: |
||||
|
- '*' |
||||
|
paths: |
||||
|
- '*.sh' |
||||
|
- '.github/workflows/OpenBSD.yml' |
||||
|
|
||||
|
pull_request: |
||||
|
branches: |
||||
|
- dev |
||||
|
paths: |
||||
|
- '*.sh' |
||||
|
- '.github/workflows/OpenBSD.yml' |
||||
|
|
||||
|
concurrency: |
||||
|
group: ${{ github.workflow }}-${{ github.ref }} |
||||
|
cancel-in-progress: true |
||||
|
|
||||
|
|
||||
|
|
||||
|
jobs: |
||||
|
OpenBSD: |
||||
|
strategy: |
||||
|
matrix: |
||||
|
include: |
||||
|
- TEST_ACME_Server: "LetsEncrypt.org_test" |
||||
|
CA_ECDSA: "" |
||||
|
CA: "" |
||||
|
CA_EMAIL: "" |
||||
|
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 |
||||
|
- TEST_ACME_Server: "LetsEncrypt.org_test" |
||||
|
CA_ECDSA: "" |
||||
|
CA: "" |
||||
|
CA_EMAIL: "" |
||||
|
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 |
||||
|
ACME_USE_WGET: 1 |
||||
|
#- TEST_ACME_Server: "ZeroSSL.com" |
||||
|
# CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" |
||||
|
# CA: "ZeroSSL RSA Domain Secure Site CA" |
||||
|
# CA_EMAIL: "githubtest@acme.sh" |
||||
|
# TEST_PREFERRED_CHAIN: "" |
||||
|
runs-on: macos-12 |
||||
|
env: |
||||
|
TEST_LOCAL: 1 |
||||
|
TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }} |
||||
|
CA_ECDSA: ${{ matrix.CA_ECDSA }} |
||||
|
CA: ${{ matrix.CA }} |
||||
|
CA_EMAIL: ${{ matrix.CA_EMAIL }} |
||||
|
TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }} |
||||
|
ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }} |
||||
|
steps: |
||||
|
- uses: actions/checkout@v2 |
||||
|
- uses: vmactions/cf-tunnel@v0.0.3 |
||||
|
id: tunnel |
||||
|
with: |
||||
|
protocol: http |
||||
|
port: 8080 |
||||
|
- name: Set envs |
||||
|
run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV |
||||
|
- name: Clone acmetest |
||||
|
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ |
||||
|
- uses: vmactions/openbsd-vm@v0 |
||||
|
with: |
||||
|
envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN ACME_USE_WGET' |
||||
|
nat: | |
||||
|
"8080": "80" |
||||
|
prepare: pkg_add socat curl wget |
||||
|
usesh: true |
||||
|
copyback: false |
||||
|
run: | |
||||
|
cd ../acmetest \ |
||||
|
&& ./letest.sh |
||||
|
|
||||
|
|
@ -0,0 +1,19 @@ |
|||||
|
name: "Update issues" |
||||
|
on: |
||||
|
issues: |
||||
|
types: [opened] |
||||
|
|
||||
|
jobs: |
||||
|
comment: |
||||
|
runs-on: ubuntu-latest |
||||
|
steps: |
||||
|
- uses: actions/github-script@v6 |
||||
|
with: |
||||
|
script: | |
||||
|
github.rest.issues.createComment({ |
||||
|
issue_number: context.issue.number, |
||||
|
owner: context.repo.owner, |
||||
|
repo: context.repo.repo, |
||||
|
body: "Please upgrade to the latest code and try again first. Maybe it's already fixed. ```acme.sh --upgrade``` If it's still not working, please provide the log with `--debug 2`, otherwise, nobody can help you." |
||||
|
|
||||
|
}) |
@ -0,0 +1,30 @@ |
|||||
|
name: Check dns api |
||||
|
|
||||
|
on: |
||||
|
pull_request_target: |
||||
|
types: |
||||
|
- opened |
||||
|
branches: |
||||
|
- 'dev' |
||||
|
paths: |
||||
|
- 'dnsapi/*.sh' |
||||
|
|
||||
|
|
||||
|
jobs: |
||||
|
welcome: |
||||
|
runs-on: ubuntu-latest |
||||
|
steps: |
||||
|
- uses: actions/github-script@v6 |
||||
|
with: |
||||
|
script: | |
||||
|
await github.rest.issues.createComment({ |
||||
|
issue_number: context.issue.number, |
||||
|
owner: context.repo.owner, |
||||
|
repo: context.repo.repo, |
||||
|
body: `**Welcome** |
||||
|
Please make sure you're read our [DNS API Dev Guide](../wiki/DNS-API-Dev-Guide) and [DNS-API-Test](../wiki/DNS-API-Test). |
||||
|
Then reply on this message, otherwise, your code will not be reviewed or merged. |
||||
|
We look forward to reviewing your Pull request shortly ✨ |
||||
|
` |
||||
|
}) |
||||
|
|
@ -0,0 +1,30 @@ |
|||||
|
name: Check dns api |
||||
|
|
||||
|
on: |
||||
|
pull_request_target: |
||||
|
types: |
||||
|
- opened |
||||
|
branches: |
||||
|
- 'dev' |
||||
|
paths: |
||||
|
- 'notify/*.sh' |
||||
|
|
||||
|
|
||||
|
jobs: |
||||
|
welcome: |
||||
|
runs-on: ubuntu-latest |
||||
|
steps: |
||||
|
- uses: actions/github-script@v6 |
||||
|
with: |
||||
|
script: | |
||||
|
await github.rest.issues.createComment({ |
||||
|
issue_number: context.issue.number, |
||||
|
owner: context.repo.owner, |
||||
|
repo: context.repo.repo, |
||||
|
body: `**Welcome** |
||||
|
Please make sure you're read our [Code-of-conduct](../wiki/Code-of-conduct) and add the usage here: [notify](../wiki/notify). |
||||
|
Then reply on this message, otherwise, your code will not be reviewed or merged. |
||||
|
We look forward to reviewing your Pull request shortly ✨ |
||||
|
` |
||||
|
}) |
||||
|
|
@ -0,0 +1,132 @@ |
|||||
|
#!/usr/bin/env sh |
||||
|
|
||||
|
# Deploy certificates to a proxmox virtual environment node using the API. |
||||
|
# |
||||
|
# Environment variables that can be set are: |
||||
|
# `DEPLOY_PROXMOXVE_SERVER`: The hostname of the proxmox ve node. Defaults to |
||||
|
# _cdomain. |
||||
|
# `DEPLOY_PROXMOXVE_SERVER_PORT`: The port number the management interface is on. |
||||
|
# Defaults to 8006. |
||||
|
# `DEPLOY_PROXMOXVE_NODE_NAME`: The name of the node we'll be connecting to. |
||||
|
# Defaults to the host portion of the server |
||||
|
# domain name. |
||||
|
# `DEPLOY_PROXMOXVE_USER`: The user we'll connect as. Defaults to root. |
||||
|
# `DEPLOY_PROXMOXVE_USER_REALM`: The authentication realm the user authenticates |
||||
|
# with. Defaults to pam. |
||||
|
# `DEPLOY_PROXMOXVE_API_TOKEN_NAME`: The name of the API token created for the |
||||
|
# user account. Defaults to acme. |
||||
|
# `DEPLOY_PROXMOXVE_API_TOKEN_KEY`: The API token. Required. |
||||
|
|
||||
|
proxmoxve_deploy() { |
||||
|
_cdomain="$1" |
||||
|
_ckey="$2" |
||||
|
_ccert="$3" |
||||
|
_cca="$4" |
||||
|
_cfullchain="$5" |
||||
|
|
||||
|
_debug _cdomain "$_cdomain" |
||||
|
_debug2 _ckey "$_ckey" |
||||
|
_debug _ccert "$_ccert" |
||||
|
_debug _cca "$_cca" |
||||
|
_debug _cfullchain "$_cfullchain" |
||||
|
|
||||
|
# "Sane" defaults. |
||||
|
_getdeployconf DEPLOY_PROXMOXVE_SERVER |
||||
|
if [ -z "$DEPLOY_PROXMOXVE_SERVER" ]; then |
||||
|
_target_hostname="$_cdomain" |
||||
|
else |
||||
|
_target_hostname="$DEPLOY_PROXMOXVE_SERVER" |
||||
|
_savedeployconf DEPLOY_PROXMOXVE_SERVER "$DEPLOY_PROXMOXVE_SERVER" |
||||
|
fi |
||||
|
_debug2 DEPLOY_PROXMOXVE_SERVER "$_target_hostname" |
||||
|
|
||||
|
_getdeployconf DEPLOY_PROXMOXVE_SERVER_PORT |
||||
|
if [ -z "$DEPLOY_PROXMOXVE_SERVER_PORT" ]; then |
||||
|
_target_port="8006" |
||||
|
else |
||||
|
_target_port="$DEPLOY_PROXMOXVE_SERVER_PORT" |
||||
|
_savedeployconf DEPLOY_PROXMOXVE_SERVER_PORT "$DEPLOY_PROXMOXVE_SERVER_PORT" |
||||
|
fi |
||||
|
_debug2 DEPLOY_PROXMOXVE_SERVER_PORT "$_target_port" |
||||
|
|
||||
|
_getdeployconf DEPLOY_PROXMOXVE_NODE_NAME |
||||
|
if [ -z "$DEPLOY_PROXMOXVE_NODE_NAME" ]; then |
||||
|
_node_name=$(echo "$_target_hostname" | cut -d. -f1) |
||||
|
else |
||||
|
_node_name="$DEPLOY_PROXMOXVE_NODE_NAME" |
||||
|
_savedeployconf DEPLOY_PROXMOXVE_NODE_NAME "$DEPLOY_PROXMOXVE_NODE_NAME" |
||||
|
fi |
||||
|
_debug2 DEPLOY_PROXMOXVE_NODE_NAME "$_node_name" |
||||
|
|
||||
|
# Complete URL. |
||||
|
_target_url="https://${_target_hostname}:${_target_port}/api2/json/nodes/${_node_name}/certificates/custom" |
||||
|
_debug TARGET_URL "$_target_url" |
||||
|
|
||||
|
# More "sane" defaults. |
||||
|
_getdeployconf DEPLOY_PROXMOXVE_USER |
||||
|
if [ -z "$DEPLOY_PROXMOXVE_USER" ]; then |
||||
|
_proxmoxve_user="root" |
||||
|
else |
||||
|
_proxmoxve_user="$DEPLOY_PROXMOXVE_USER" |
||||
|
_savedeployconf DEPLOY_PROXMOXVE_USER "$DEPLOY_PROXMOXVE_USER" |
||||
|
fi |
||||
|
_debug2 DEPLOY_PROXMOXVE_USER "$_proxmoxve_user" |
||||
|
|
||||
|
_getdeployconf DEPLOY_PROXMOXVE_USER_REALM |
||||
|
if [ -z "$DEPLOY_PROXMOXVE_USER_REALM" ]; then |
||||
|
_proxmoxve_user_realm="pam" |
||||
|
else |
||||
|
_proxmoxve_user_realm="$DEPLOY_PROXMOXVE_USER_REALM" |
||||
|
_savedeployconf DEPLOY_PROXMOXVE_USER_REALM "$DEPLOY_PROXMOXVE_USER_REALM" |
||||
|
fi |
||||
|
_debug2 DEPLOY_PROXMOXVE_USER_REALM "$_proxmoxve_user_realm" |
||||
|
|
||||
|
_getdeployconf DEPLOY_PROXMOXVE_API_TOKEN_NAME |
||||
|
if [ -z "$DEPLOY_PROXMOXVE_API_TOKEN_NAME" ]; then |
||||
|
_proxmoxve_api_token_name="acme" |
||||
|
else |
||||
|
_proxmoxve_api_token_name="$DEPLOY_PROXMOXVE_API_TOKEN_NAME" |
||||
|
_savedeployconf DEPLOY_PROXMOXVE_API_TOKEN_NAME "$DEPLOY_PROXMOXVE_API_TOKEN_NAME" |
||||
|
fi |
||||
|
_debug2 DEPLOY_PROXMOXVE_API_TOKEN_NAME "$_proxmoxve_api_token_name" |
||||
|
|
||||
|
# This is required. |
||||
|
_getdeployconf DEPLOY_PROXMOXVE_API_TOKEN_KEY |
||||
|
if [ -z "$DEPLOY_PROXMOXVE_API_TOKEN_KEY" ]; then |
||||
|
_err "API key not provided." |
||||
|
return 1 |
||||
|
else |
||||
|
_proxmoxve_api_token_key="$DEPLOY_PROXMOXVE_API_TOKEN_KEY" |
||||
|
_savedeployconf DEPLOY_PROXMOXVE_API_TOKEN_KEY "$DEPLOY_PROXMOXVE_API_TOKEN_KEY" |
||||
|
fi |
||||
|
_debug2 DEPLOY_PROXMOXVE_API_TOKEN_KEY _proxmoxve_api_token_key |
||||
|
|
||||
|
# PVE API Token header value. Used in "Authorization: PVEAPIToken". |
||||
|
_proxmoxve_header_api_token="${_proxmoxve_user}@${_proxmoxve_user_realm}!${_proxmoxve_api_token_name}=${_proxmoxve_api_token_key}" |
||||
|
_debug2 "Auth Header" _proxmoxve_header_api_token |
||||
|
|
||||
|
# Ugly. I hate putting heredocs inside functions because heredocs don't |
||||
|
# account for whitespace correctly but it _does_ work and is several times |
||||
|
# cleaner than anything else I had here. |
||||
|
# |
||||
|
# This dumps the json payload to a variable that should be passable to the |
||||
|
# _psot function. |
||||
|
_json_payload=$( |
||||
|
cat <<HEREDOC |
||||
|
{ |
||||
|
"certificates": "$(tr '\n' ':' <"$_cfullchain" | sed 's/:/\\n/g')", |
||||
|
"key": "$(tr '\n' ':' <"$_ckey" | sed 's/:/\\n/g')", |
||||
|
"node":"$_node_name", |
||||
|
"restart":"1", |
||||
|
"force":"1" |
||||
|
} |
||||
|
HEREDOC |
||||
|
) |
||||
|
_debug2 Payload "$_json_payload" |
||||
|
|
||||
|
# Push certificates to server. |
||||
|
export _HTTPS_INSECURE=1 |
||||
|
export _H1="Authorization: PVEAPIToken=${_proxmoxve_header_api_token}" |
||||
|
_post "$_json_payload" "$_target_url" "" POST "application/json" |
||||
|
|
||||
|
} |
@ -0,0 +1,234 @@ |
|||||
|
#!/usr/bin/env sh |
||||
|
|
||||
|
#This file name is "dns_dnsservices.sh" |
||||
|
#Script for Danish DNS registra and DNS hosting provider https://dns.services |
||||
|
|
||||
|
#Author: Bjarke Bruun <bbruun@gmail.com> |
||||
|
#Report Bugs here: https://github.com/acmesh-official/acme.sh/issues/4152 |
||||
|
|
||||
|
# Global variable to connect to the DNS.Services API |
||||
|
DNSServices_API=https://dns.services/api |
||||
|
|
||||
|
######## Public functions ##################### |
||||
|
|
||||
|
#Usage: dns_dnsservices_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" |
||||
|
dns_dnsservices_add() { |
||||
|
fulldomain=$1 |
||||
|
txtvalue=$2 |
||||
|
|
||||
|
_info "Using dns.services to create ACME DNS challenge" |
||||
|
_debug2 add_fulldomain "$fulldomain" |
||||
|
_debug2 add_txtvalue "$txtvalue" |
||||
|
|
||||
|
# Read username/password from environment or .acme.sh/accounts.conf |
||||
|
DnsServices_Username="${DnsServices_Username:-$(_readaccountconf_mutable DnsServices_Username)}" |
||||
|
DnsServices_Password="${DnsServices_Password:-$(_readaccountconf_mutable DnsServices_Password)}" |
||||
|
if [ -z "$DnsServices_Username" ] || [ -z "$DnsServices_Password" ]; then |
||||
|
DnsServices_Username="" |
||||
|
DnsServices_Password="" |
||||
|
_err "You didn't specify dns.services api username and password yet." |
||||
|
_err "Set environment variables DnsServices_Username and DnsServices_Password" |
||||
|
return 1 |
||||
|
fi |
||||
|
|
||||
|
# Setup GET/POST/DELETE headers |
||||
|
_setup_headers |
||||
|
|
||||
|
#save the credentials to the account conf file. |
||||
|
_saveaccountconf_mutable DnsServices_Username "$DnsServices_Username" |
||||
|
_saveaccountconf_mutable DnsServices_Password "$DnsServices_Password" |
||||
|
|
||||
|
if ! _contains "$DnsServices_Username" "@"; then |
||||
|
_err "It seems that the username variable DnsServices_Username has not been set/left blank" |
||||
|
_err "or is not a valid email. Please correct and try again." |
||||
|
return 1 |
||||
|
fi |
||||
|
|
||||
|
if ! _get_root "${fulldomain}"; then |
||||
|
_err "Invalid domain ${fulldomain}" |
||||
|
return 1 |
||||
|
fi |
||||
|
|
||||
|
if ! createRecord "$fulldomain" "${txtvalue}"; then |
||||
|
_err "Error creating TXT record in domain $fulldomain in $rootZoneName" |
||||
|
return 1 |
||||
|
fi |
||||
|
|
||||
|
_debug2 challenge-created "Created $fulldomain" |
||||
|
return 0 |
||||
|
} |
||||
|
|
||||
|
#Usage: fulldomain txtvalue |
||||
|
#Description: Remove the txt record after validation. |
||||
|
dns_dnsservices_rm() { |
||||
|
fulldomain=$1 |
||||
|
txtvalue=$2 |
||||
|
|
||||
|
_info "Using dns.services to remove DNS record $fulldomain TXT $txtvalue" |
||||
|
_debug rm_fulldomain "$fulldomain" |
||||
|
_debug rm_txtvalue "$txtvalue" |
||||
|
|
||||
|
# Read username/password from environment or .acme.sh/accounts.conf |
||||
|
DnsServices_Username="${DnsServices_Username:-$(_readaccountconf_mutable DnsServices_Username)}" |
||||
|
DnsServices_Password="${DnsServices_Password:-$(_readaccountconf_mutable DnsServices_Password)}" |
||||
|
if [ -z "$DnsServices_Username" ] || [ -z "$DnsServices_Password" ]; then |
||||
|
DnsServices_Username="" |
||||
|
DnsServices_Password="" |
||||
|
_err "You didn't specify dns.services api username and password yet." |
||||
|
_err "Set environment variables DnsServices_Username and DnsServices_Password" |
||||
|
return 1 |
||||
|
fi |
||||
|
|
||||
|
# Setup GET/POST/DELETE headers |
||||
|
_setup_headers |
||||
|
|
||||
|
if ! _get_root "${fulldomain}"; then |
||||
|
_err "Invalid domain ${fulldomain}" |
||||
|
return 1 |
||||
|
fi |
||||
|
|
||||
|
_debug2 rm_rootDomainInfo "found root domain $rootZoneName for $fulldomain" |
||||
|
|
||||
|
if ! deleteRecord "${fulldomain}" "${txtvalue}"; then |
||||
|
_err "Error removing record: $fulldomain TXT ${txtvalue}" |
||||
|
return 1 |
||||
|
fi |
||||
|
|
||||
|
return 0 |
||||
|
} |
||||
|
|
||||
|
#################### Private functions below ################################## |
||||
|
|
||||
|
_setup_headers() { |
||||
|
# Set up API Headers for _get() and _post() |
||||
|
# The <function>_add or <function>_rm must have been called before to work |
||||
|
|
||||
|
if [ -z "$DnsServices_Username" ] || [ -z "$DnsServices_Password" ]; then |
||||
|
_err "Could not setup BASIC authentication headers, they are missing" |
||||
|
return 1 |
||||
|
fi |
||||
|
|
||||
|
DnsServiceCredentials="$(printf "%s" "$DnsServices_Username:$DnsServices_Password" | _base64)" |
||||
|
export _H1="Authorization: Basic $DnsServiceCredentials" |
||||
|
export _H2="Content-Type: application/json" |
||||
|
|
||||
|
# Just return if headers are set |
||||
|
return 0 |
||||
|
} |
||||
|
|
||||
|
_get_root() { |
||||
|
domain=$1 |
||||
|
_debug2 _get_root "Get the root domain of ${domain} for DNS API" |
||||
|
|
||||
|
# Setup _get() and _post() headers |
||||
|
#_setup_headers |
||||
|
|
||||
|
result=$(_H1="$_H1" _H2="$_H2" _get "$DNSServices_API/dns") |
||||
|
_debug2 _get_root "Got the following root domain(s) $result" |
||||
|
_debug2 _get_root "- JSON: $result" |
||||
|
|
||||
|
if [ "$(echo "$result" | grep -c '"name"')" -gt "1" ]; then |
||||
|
checkMultiZones="true" |
||||
|
_debug2 _get_root "- multiple zones found" |
||||
|
else |
||||
|
checkMultiZones="false" |
||||
|
|
||||
|
fi |
||||
|
|
||||
|
# Find/isolate the root zone to work with in createRecord() and deleteRecord() |
||||
|
rootZone="" |
||||
|
if [ "$checkMultiZones" = "true" ]; then |
||||
|
rootZone=$(for zone in $(echo "$result" | tr -d '\n' ' '); do |
||||
|
if [ "$(echo "$domain" | grep "$zone")" != "" ]; then |
||||
|
_debug2 _get_root "- trying to figure out if $zone is in $domain" |
||||
|
echo "$zone" |
||||
|
break |
||||
|
fi |
||||
|
done) |
||||
|
else |
||||
|
rootZone=$(echo "$result" | _egrep_o '"name":"[^"]*' | cut -d'"' -f4) |
||||
|
_debug2 _get_root "- only found 1 domain in API: $rootZone" |
||||
|
fi |
||||
|
|
||||
|
if [ -z "$rootZone" ]; then |
||||
|
_err "Could not find root domain for $domain - is it correctly typed?" |
||||
|
return 1 |
||||
|
fi |
||||
|
|
||||
|
# Setup variables used by other functions to communicate with DNS.Services API |
||||
|
#zoneInfo=$(echo "$result" | sed "s,\"zones,\n&,g" | grep zones | cut -d'[' -f2 | cut -d']' -f1 | tr '}' '\n' | grep "\"$rootZone\"") |
||||
|
zoneInfo=$(echo "$result" | sed -E 's,.*(zones)(.*),\1\2,g' | sed -E 's,^(.*"name":")([^"]*)"(.*)$,\2,g' | grep "\"$rootZone\"") |
||||
|
rootZoneName="$rootZone" |
||||
|
subDomainName="$(echo "$domain" | sed "s,\.$rootZone,,g")" |
||||
|
subDomainNameClean="$(echo "$domain" | sed "s,_acme-challenge.,,g")" |
||||
|
rootZoneDomainID=$(echo "$result" | sed -E 's,.*(zones)(.*),\1\2,g' | sed -E 's,^(.*"domain_id":")([^"]*)"(.*)$,\2,g') |
||||
|
rootZoneServiceID=$(echo "$result" | sed -E 's,.*(zones)(.*),\1\2,g' | sed -E 's,^(.*"service_id":")([^"]*)"(.*)$,\2,g') |
||||
|
|
||||
|
_debug2 _zoneInfo "Zone info from API : $zoneInfo" |
||||
|
_debug2 _get_root "Root zone name : $rootZoneName" |
||||
|
_debug2 _get_root "Root zone domain ID : $rootZoneDomainID" |
||||
|
_debug2 _get_root "Root zone service ID: $rootZoneServiceID" |
||||
|
_debug2 _get_root "Sub domain : $subDomainName" |
||||
|
|
||||
|
_debug _get_root "Found valid root domain $rootZone for $subDomainNameClean" |
||||
|
return 0 |
||||
|
} |
||||
|
|
||||
|
createRecord() { |
||||
|
fulldomain=$1 |
||||
|
txtvalue="$2" |
||||
|
|
||||
|
# Get root domain information - needed for DNS.Services API communication |
||||
|
if [ -z "$rootZoneName" ] || [ -z "$rootZoneDomainID" ] || [ -z "$rootZoneServiceID" ]; then |
||||
|
_get_root "$fulldomain" |
||||
|
fi |
||||
|
|
||||
|
_debug2 createRecord "CNAME TXT value is: $txtvalue" |
||||
|
|
||||
|
# Prepare data to send to API |
||||
|
data="{\"name\":\"${fulldomain}\",\"type\":\"TXT\",\"content\":\"${txtvalue}\", \"ttl\":\"10\"}" |
||||
|
|
||||
|
_debug2 createRecord "data to API: $data" |
||||
|
result=$(_post "$data" "$DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID/records" "" "POST") |
||||
|
_debug2 createRecord "result from API: $result" |
||||
|
|
||||
|
if [ "$(echo "$result" | _egrep_o "\"success\":true")" = "" ]; then |
||||
|
_err "Failed to create TXT record $fulldomain with content $txtvalue in zone $rootZoneName" |
||||
|
_err "$result" |
||||
|
return 1 |
||||
|
fi |
||||
|
|
||||
|
_info "Record \"$fulldomain TXT $txtvalue\" has been created" |
||||
|
return 0 |
||||
|
} |
||||
|
|
||||
|
deleteRecord() { |
||||
|
fulldomain=$1 |
||||
|
txtvalue=$2 |
||||
|
|
||||
|
_log deleteRecord "Deleting $fulldomain TXT $txtvalue record" |
||||
|
|
||||
|
if [ -z "$rootZoneName" ] || [ -z "$rootZoneDomainID" ] || [ -z "$rootZoneServiceID" ]; then |
||||
|
_get_root "$fulldomain" |
||||
|
fi |
||||
|
|
||||
|
result="$(_H1="$_H1" _H2="$_H2" _get "$DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID")" |
||||
|
recordInfo="$(echo "$result" | sed -e 's/:{/:{\n/g' -e 's/},/\n},\n/g' | grep "${txtvalue}")" |
||||
|
recordID="$(echo "$recordInfo" | sed -e 's/:{/:{\n/g' -e 's/},/\n},\n/g' | grep "${txtvalue}" | sed -E 's,.*(zones)(.*),\1\2,g' | sed -E 's,^(.*"id":")([^"]*)"(.*)$,\2,g')" |
||||
|
|
||||
|
if [ -z "$recordID" ]; then |
||||
|
_info "Record $fulldomain TXT $txtvalue not found or already deleted" |
||||
|
return 0 |
||||
|
else |
||||
|
_debug2 deleteRecord "Found recordID=$recordID" |
||||
|
fi |
||||
|
|
||||
|
_debug2 deleteRecord "DELETE request $DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID/records/$recordID" |
||||
|
_log "curl DELETE request $DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID/records/$recordID" |
||||
|
result="$(_H1="$_H1" _H2="$_H2" _post "" "$DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID/records/$recordID" "" "DELETE")" |
||||
|
_debug2 deleteRecord "API Delete result \"$result\"" |
||||
|
_log "curl API Delete result \"$result\"" |
||||
|
|
||||
|
# Return OK regardless |
||||
|
return 0 |
||||
|
} |
@ -0,0 +1,147 @@ |
|||||
|
#!/usr/bin/env sh |
||||
|
|
||||
|
#LA_Id="test123" |
||||
|
#LA_Key="d1j2fdo4dee3948" |
||||
|
|
||||
|
LA_Api="https://api.dns.la/api" |
||||
|
|
||||
|
######## Public functions ##################### |
||||
|
|
||||
|
#Usage: dns_la_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" |
||||
|
dns_la_add() { |
||||
|
fulldomain=$1 |
||||
|
txtvalue=$2 |
||||
|
|
||||
|
LA_Id="${LA_Id:-$(_readaccountconf_mutable LA_Id)}" |
||||
|
LA_Key="${LA_Key:-$(_readaccountconf_mutable LA_Key)}" |
||||
|
|
||||
|
if [ -z "$LA_Id" ] || [ -z "$LA_Key" ]; then |
||||
|
LA_Id="" |
||||
|
LA_Key="" |
||||
|
_err "You didn't specify a dnsla api id and key yet." |
||||
|
return 1 |
||||
|
fi |
||||
|
|
||||
|
#save the api key and email to the account conf file. |
||||
|
_saveaccountconf_mutable LA_Id "$LA_Id" |
||||
|
_saveaccountconf_mutable LA_Key "$LA_Key" |
||||
|
|
||||
|
_debug "First detect the root zone" |
||||
|
if ! _get_root "$fulldomain"; then |
||||
|
_err "invalid domain" |
||||
|
return 1 |
||||
|
fi |
||||
|
_debug _domain_id "$_domain_id" |
||||
|
_debug _sub_domain "$_sub_domain" |
||||
|
_debug _domain "$_domain" |
||||
|
|
||||
|
_info "Adding record" |
||||
|
if _la_rest "record.ashx?cmd=create&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domainid=$_domain_id&host=$_sub_domain&recordtype=TXT&recorddata=$txtvalue&recordline="; then |
||||
|
if _contains "$response" '"resultid":'; then |
||||
|
_info "Added, OK" |
||||
|
return 0 |
||||
|
elif _contains "$response" '"code":532'; then |
||||
|
_info "Already exists, OK" |
||||
|
return 0 |
||||
|
else |
||||
|
_err "Add txt record error." |
||||
|
return 1 |
||||
|
fi |
||||
|
fi |
||||
|
_err "Add txt record error." |
||||
|
return 1 |
||||
|
|
||||
|
} |
||||
|
|
||||
|
#fulldomain txtvalue |
||||
|
dns_la_rm() { |
||||
|
fulldomain=$1 |
||||
|
txtvalue=$2 |
||||
|
|
||||
|
LA_Id="${LA_Id:-$(_readaccountconf_mutable LA_Id)}" |
||||
|
LA_Key="${LA_Key:-$(_readaccountconf_mutable LA_Key)}" |
||||
|
|
||||
|
_debug "First detect the root zone" |
||||
|
if ! _get_root "$fulldomain"; then |
||||
|
_err "invalid domain" |
||||
|
return 1 |
||||
|
fi |
||||
|
_debug _domain_id "$_domain_id" |
||||
|
_debug _sub_domain "$_sub_domain" |
||||
|
_debug _domain "$_domain" |
||||
|
|
||||
|
_debug "Getting txt records" |
||||
|
if ! _la_rest "record.ashx?cmd=listn&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domainid=$_domain_id&domain=$_domain&host=$_sub_domain&recordtype=TXT&recorddata=$txtvalue"; then |
||||
|
_err "Error" |
||||
|
return 1 |
||||
|
fi |
||||
|
|
||||
|
if ! _contains "$response" '"recordid":'; then |
||||
|
_info "Don't need to remove." |
||||
|
return 0 |
||||
|
fi |
||||
|
|
||||
|
record_id=$(printf "%s" "$response" | grep '"recordid":' | cut -d : -f 2 | cut -d , -f 1 | tr -d '\r' | tr -d '\n') |
||||
|
_debug "record_id" "$record_id" |
||||
|
if [ -z "$record_id" ]; then |
||||
|
_err "Can not get record id to remove." |
||||
|
return 1 |
||||
|
fi |
||||
|
if ! _la_rest "record.ashx?cmd=remove&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domainid=$_domain_id&domain=$_domain&recordid=$record_id"; then |
||||
|
_err "Delete record error." |
||||
|
return 1 |
||||
|
fi |
||||
|
_contains "$response" '"code":300' |
||||
|
|
||||
|
} |
||||
|
|
||||
|
#################### Private functions below ################################## |
||||
|
#_acme-challenge.www.domain.com |
||||
|
#returns |
||||
|
# _sub_domain=_acme-challenge.www |
||||
|
# _domain=domain.com |
||||
|
# _domain_id=sdjkglgdfewsdfg |
||||
|
_get_root() { |
||||
|
domain=$1 |
||||
|
i=1 |
||||
|
p=1 |
||||
|
|
||||
|
while true; do |
||||
|
h=$(printf "%s" "$domain" | cut -d . -f $i-100) |
||||
|
if [ -z "$h" ]; then |
||||
|
#not valid |
||||
|
return 1 |
||||
|
fi |
||||
|
|
||||
|
if ! _la_rest "domain.ashx?cmd=get&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domain=$h"; then |
||||
|
return 1 |
||||
|
fi |
||||
|
|
||||
|
if _contains "$response" '"domainid":'; then |
||||
|
_domain_id=$(printf "%s" "$response" | grep '"domainid":' | cut -d : -f 2 | cut -d , -f 1 | tr -d '\r' | tr -d '\n') |
||||
|
if [ "$_domain_id" ]; then |
||||
|
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) |
||||
|
_domain="$h" |
||||
|
return 0 |
||||
|
fi |
||||
|
return 1 |
||||
|
fi |
||||
|
p="$i" |
||||
|
i=$(_math "$i" + 1) |
||||
|
done |
||||
|
return 1 |
||||
|
} |
||||
|
|
||||
|
#Usage: URI |
||||
|
_la_rest() { |
||||
|
url="$LA_Api/$1" |
||||
|
_debug "$url" |
||||
|
|
||||
|
if ! response="$(_get "$url" | tr -d ' ' | tr "}" ",")"; then |
||||
|
_err "Error: $url" |
||||
|
return 1 |
||||
|
fi |
||||
|
|
||||
|
_debug2 response "$response" |
||||
|
return 0 |
||||
|
} |
@ -0,0 +1,45 @@ |
|||||
|
#!/usr/bin/env sh |
||||
|
|
||||
|
#Support Slack APP notifications |
||||
|
|
||||
|
#SLACK_APP_CHANNEL="" |
||||
|
#SLACK_APP_TOKEN="" |
||||
|
|
||||
|
slack_app_send() { |
||||
|
_subject="$1" |
||||
|
_content="$2" |
||||
|
_statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped |
||||
|
_debug "_statusCode" "$_statusCode" |
||||
|
|
||||
|
SLACK_APP_CHANNEL="${SLACK_APP_CHANNEL:-$(_readaccountconf_mutable SLACK_APP_CHANNEL)}" |
||||
|
if [ -n "$SLACK_APP_CHANNEL" ]; then |
||||
|
_saveaccountconf_mutable SLACK_APP_CHANNEL "$SLACK_APP_CHANNEL" |
||||
|
fi |
||||
|
|
||||
|
SLACK_APP_TOKEN="${SLACK_APP_TOKEN:-$(_readaccountconf_mutable SLACK_APP_TOKEN)}" |
||||
|
if [ -n "$SLACK_APP_TOKEN" ]; then |
||||
|
_saveaccountconf_mutable SLACK_APP_TOKEN "$SLACK_APP_TOKEN" |
||||
|
fi |
||||
|
|
||||
|
_content="$(printf "*%s*\n%s" "$_subject" "$_content" | _json_encode)" |
||||
|
_data="{\"text\": \"$_content\", " |
||||
|
if [ -n "$SLACK_APP_CHANNEL" ]; then |
||||
|
_data="$_data\"channel\": \"$SLACK_APP_CHANNEL\", " |
||||
|
fi |
||||
|
_data="$_data\"mrkdwn\": \"true\"}" |
||||
|
|
||||
|
export _H1="Authorization: Bearer $SLACK_APP_TOKEN" |
||||
|
|
||||
|
SLACK_APP_API_URL="https://slack.com/api/chat.postMessage" |
||||
|
if _post "$_data" "$SLACK_APP_API_URL" "" "POST" "application/json; charset=utf-8"; then |
||||
|
# shellcheck disable=SC2154 |
||||
|
SLACK_APP_RESULT_OK=$(echo "$response" | _egrep_o 'ok" *: *true') |
||||
|
if [ "$?" = "0" ] && [ "$SLACK_APP_RESULT_OK" ]; then |
||||
|
_info "slack send success." |
||||
|
return 0 |
||||
|
fi |
||||
|
fi |
||||
|
_err "slack send error." |
||||
|
_err "$response" |
||||
|
return 1 |
||||
|
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue