Compare commits
2 Commits
1f063f2501
...
2598532761
| Author | SHA1 | Date | |
|---|---|---|---|
| 2598532761 | |||
| c7eb44ae5f |
43
README.md
43
README.md
@@ -1,16 +1,12 @@
|
|||||||
# WIP
|
# WIP
|
||||||
|
|
||||||
This project contains two files:
|
`acme-cpanel.sh` reads in a list of domains from one or more files. These files may only contain domains and empty lines (see `domains.txt` for example format).
|
||||||
|
|
||||||
`acme-cpanel-webroot.sh` (for webroot challenges)
|
"*www.*" subdomains will be added automatically (do not add them to the domains file list).
|
||||||
|
|
||||||
`acme-cpanel-dns.sh` (for dns challenges, legacy script)
|
|
||||||
|
|
||||||
Both of these scripts read in a list of domains from one or more files. These files may only contain domains and empty lines (see `domains.txt`).
|
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
`acme-cpanel-webroot.sh` may require the following additions to .htaccess so that challenges are not automatically redirected to https:
|
The `--method webroot` may require the following additions to .htaccess so that challenges are not automatically redirected to https:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
RewriteCond %{REQUEST_FILENAME} !-f
|
RewriteCond %{REQUEST_FILENAME} !-f
|
||||||
@@ -23,32 +19,33 @@ Command-line (Linux):
|
|||||||
|
|
||||||
* Move script to user home directory on the server: `scp ./* username@ip:port:~`
|
* Move script to user home directory on the server: `scp ./* username@ip:port:~`
|
||||||
* Login to server: `ssh user@ip -p port`
|
* Login to server: `ssh user@ip -p port`
|
||||||
* Make script executable: `chmod +x $HOME/acme-cpanel-webroot.s`
|
* Make script executable: `chmod +x $HOME/acme-cpanel.sh`
|
||||||
* Run script (ex. `$HOME/acme-cpanel-webroot.sh -s multisites`)
|
* Run script (ex. `$HOME/acme-cpanel.sh -s multisites`)
|
||||||
* Follow prompts to enter credentials, issue certificates, and deploy them
|
* Follow prompts to enter credentials, issue certificates, and deploy them
|
||||||
* Double-check that the acme cron job is enabled: `crontab -l`
|
* Double-check that the acme cron job is enabled: `crontab -l`
|
||||||
|
|
||||||
cPanel:
|
cPanel:
|
||||||
|
|
||||||
* Use File Manager to upload files to the home directory (/home/username/)
|
* Use File Manager to upload files to the home directory (/home/username/)
|
||||||
* You may need to make file executable in Terminal: `chmod +x $HOME/acme-cpanel-webroot.sh`
|
* You may need to make file executable in Terminal: `chmod +x $HOME/acme-cpanel.sh`
|
||||||
* Use Terminal to run the script (ex. `$HOME/acme-cpanel-webroot.sh -s multisites`)
|
* Use Terminal to run the script (ex. `$HOME/acme-cpanel.sh -s multisites`)
|
||||||
* Follow prompts to enter credentials, issue certificates, and deploy them
|
* Follow prompts to enter credentials, issue certificates, and deploy them
|
||||||
* Use Cron Jobs app to double-check that the acme cron job is present
|
* Use Cron Jobs app to double-check that the acme cron job is present
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
### `./acme-cpanel-webroot.sh [OPTIONS] [FILES...]`
|
### `./acme-cpanel.sh [OPTIONS] [FILES...]`
|
||||||
|
|
||||||
#### Options
|
#### Options
|
||||||
|
|
||||||
```text
|
```text
|
||||||
|
--method, -m webroot,dns
|
||||||
|
Choose the authentication method (default: dns)
|
||||||
--email, -e EMAIL
|
--email, -e EMAIL
|
||||||
E-mail not be notified of certificate renewal failures
|
E-mail not be notified of certificate renewal failures
|
||||||
--keep-grouping, -k
|
--group-by-file, -g
|
||||||
Issue multidomain certificates based on grouping by input file
|
Issue multidomain certificates for all domains with the same webroot, grouped by input file
|
||||||
The first domain in each file will be used to determine the shared webroot
|
The first domain in each file will be used to determine the shared webroot
|
||||||
Default: issue certificates by independent domain
|
|
||||||
--sites-dir, -s DIR
|
--sites-dir, -s DIR
|
||||||
Load domain list files from this directory
|
Load domain list files from this directory
|
||||||
--force, -f
|
--force, -f
|
||||||
@@ -59,18 +56,14 @@ cPanel:
|
|||||||
|
|
||||||
#### Examples
|
#### Examples
|
||||||
|
|
||||||
`./acme-cpanel-webroot.sh --force`
|
`./acme-cpanel.sh --force`
|
||||||
|
|
||||||
Load sites from domains.txt, issue and deploy certificates
|
Load sites from domains.txt, issue and deploy certificates using the webroot method
|
||||||
|
|
||||||
`./acme-cpanel-webroot.sh --force -s multisites`
|
`./acme-cpanel.sh --method dns --force -s multisites`
|
||||||
|
|
||||||
Load sites from multisites directory, issue and deploy certificates
|
Load sites from multisites directory, issue and deploy certificates using the dns method
|
||||||
|
|
||||||
`./acme-cpanel-webroot.sh --force -k multisites/flatwhitedesign.pw multisites/greengingerdesign.pw`
|
`./acme-cpanel.sh --force -g multisites/flatwhitedesign.pw multisites/greengingerdesign.pw`
|
||||||
|
|
||||||
Load sites from multisites directory, issue and deploy multidomain certificates based on the grouping in the file.
|
Load sites from multisites directory, issue and deploy multidomain certificates with same webroot based on the grouping in the file using the webroot method
|
||||||
|
|
||||||
### `./acme_cpanel_dns.sh`
|
|
||||||
|
|
||||||
This is a legacy script that takes no arguments. By default it will read all domain lists in a top-level "multisites" directory.
|
|
||||||
|
|||||||
@@ -1,87 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
# This program will install and configure acme, request SSL certificates from Let's Encrypt, and enable them using the cPanel API
|
|
||||||
|
|
||||||
# Comment the following line to skip issuing a test certificate
|
|
||||||
test="true"
|
|
||||||
|
|
||||||
unset err
|
|
||||||
|
|
||||||
get_acme() {
|
|
||||||
curl https://get.acme.sh | sh
|
|
||||||
curl -o "$HOME/.acme.sh/dnsapi/dns_cpaneldns.sh" https://raw.githubusercontent.com/cryobry/dns_cpaneldns/master/dns_cpaneldns.sh
|
|
||||||
"$HOME/.acme.sh/acme.sh" --upgrade --auto-upgrade
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
run_config() {
|
|
||||||
if [[ -f "$HOME/.acme.sh/account.conf" ]]; then
|
|
||||||
if grep -q "CPANELDNS_AUTH_PASSWORD" "$HOME/.acme.sh/account.conf"; then
|
|
||||||
echo "cPanel credentials already present, skipping configuration..."
|
|
||||||
echo "To rerun the configuration, first run 'rm \$HOME/.acme.sh/account.conf'"
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
# Set contact e-mail for ACME failure
|
|
||||||
read -rp 'Enter the e-mail address to contact in case of acme failure: ' EMAIL
|
|
||||||
echo
|
|
||||||
"$HOME/.acme.sh/acme.sh" --update-account --accountemail "$EMAIL"
|
|
||||||
# Read in Namecheap API variables from user for acme
|
|
||||||
read -rp 'Enter your cPanel username: ' CPANELDNS_AUTH_ID
|
|
||||||
echo
|
|
||||||
export CPANELDNS_AUTH_ID
|
|
||||||
read -rp 'Enter your cPanel password: ' CPANELDNS_AUTH_PASSWORD
|
|
||||||
echo
|
|
||||||
export CPANELDNS_AUTH_PASSWORD
|
|
||||||
read -rp 'Enter your cPanel address and port number (example: "https://www.example.com:2083/"): ' CPANELDNS_API
|
|
||||||
echo
|
|
||||||
export CPANELDNS_API
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
touch "$HOME/.acme.sh/account.conf"
|
|
||||||
run_config
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Issue certificates
|
|
||||||
issue_cert() {
|
|
||||||
local multisite_file
|
|
||||||
for multisite_file in ./multisites/*; do
|
|
||||||
echo "Attempting to issue certificates for ${multisite_file##*/} and its multisites..."
|
|
||||||
unset sites issue_cmd deploy_cmd
|
|
||||||
declare -al sites issue_cmd deploy_cmd
|
|
||||||
readarray -t sites < "${multisite_file}"
|
|
||||||
issue_cmd=("$HOME/.acme.sh/acme.sh" "--issue" "--dns" "dns_cpaneldns")
|
|
||||||
deploy_cmd=("$HOME/.acme.sh/acme.sh" "--deploy" "--deploy-hook" "cpanel_uapi")
|
|
||||||
for site in "${sites[@]}"; do
|
|
||||||
[[ "$site" != "" ]] && issue_cmd+=("-d" "$site")
|
|
||||||
done
|
|
||||||
# if test enabled, issue test certificate first
|
|
||||||
if [[ "${test:-x}" == "true" ]]; then
|
|
||||||
"${issue_cmd[@]}" --staging
|
|
||||||
read -rp -n 1 "Was the certificate correctly issued without errors? [y/N]: "
|
|
||||||
echo
|
|
||||||
[[ ! "$REPLY" =~ ^[Yy]$ ]] && err=1 && return 1
|
|
||||||
fi
|
|
||||||
echo "Running:" "${issue_cmd[@]}"
|
|
||||||
if "${issue_cmd[@]}" --force; then
|
|
||||||
echo "Running:" "${deploy_cmd[@]}"
|
|
||||||
! "${deploy_cmd[@]}" && \
|
|
||||||
echo "Could not deploy" && \
|
|
||||||
err=1
|
|
||||||
else
|
|
||||||
echo "Could not issue"
|
|
||||||
err=1
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
main() {
|
|
||||||
get_acme
|
|
||||||
run_config
|
|
||||||
issue_cert
|
|
||||||
}
|
|
||||||
|
|
||||||
main "$@"
|
|
||||||
|
|
||||||
exit "${err:-0}"
|
|
||||||
@@ -1,11 +1,13 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# This script uses acme.sh to issue and deploy SSL certificates from Let's Encrypt for a list of domains using the webroot method
|
# This script uses acme.sh to issue and deploy SSL certificates from Let's Encrypt for a list of domains
|
||||||
# See README for more details
|
# using the webroot or dns methods
|
||||||
|
#
|
||||||
|
# See README.md for more details
|
||||||
#
|
#
|
||||||
# Copyright 2020 Bryan Roessler <bryanroessler@gmail.com>
|
# Copyright 2020 Bryan Roessler <bryanroessler@gmail.com>
|
||||||
#
|
#
|
||||||
# USAGE
|
# USAGE
|
||||||
# ./acme-cpanel-webroot.sh [OPTIONS] [FILES...]
|
# ./acme-cpanel.sh [OPTIONS] [FILES...]
|
||||||
#
|
#
|
||||||
# EXAMPLES
|
# EXAMPLES
|
||||||
# TESTING: ./acme-cpanel-webroot.sh --debug -e me@gmail.com multisites/flatwhitedesign.pw multisites/greengingermultisite.website
|
# TESTING: ./acme-cpanel-webroot.sh --debug -e me@gmail.com multisites/flatwhitedesign.pw multisites/greengingermultisite.website
|
||||||
@@ -20,9 +22,12 @@
|
|||||||
# NOTE: The webroot method does NOT support wildcard domains, Let's Encrypt requires wildcard domains to
|
# NOTE: The webroot method does NOT support wildcard domains, Let's Encrypt requires wildcard domains to
|
||||||
# use DNS challenges, which the CPANEL uapi does not support (use dns_cpaneldns plugin instead)
|
# use DNS challenges, which the CPANEL uapi does not support (use dns_cpaneldns plugin instead)
|
||||||
|
|
||||||
|
source functions.sh
|
||||||
|
|
||||||
unset SITES_DIR USEREMAIL DOMAIN_FILES DOMAIN_GROUPS DEPLOY_CMD_PREFIX ISSUE_CMD_PREFIX DEBUG GROUP
|
unset SITES_DIR USEREMAIL DOMAIN_FILES DOMAIN_GROUPS DEPLOY_CMD_PREFIX ISSUE_CMD_PREFIX DEBUG GROUP
|
||||||
|
|
||||||
DEBUG="true" # quote this line to stop DEBUG mode and issue certificates for real, or use --force in user options
|
DEBUG="true" # quote this line to stop DEBUG mode and issue certificates for real, or use --force in user options
|
||||||
|
METHOD="dns" # set the default method
|
||||||
|
|
||||||
parse_input() {
|
parse_input() {
|
||||||
|
|
||||||
@@ -30,10 +35,14 @@ parse_input() {
|
|||||||
declare -g USEREMAIL
|
declare -g USEREMAIL
|
||||||
declare -ag DOMAIN_FILES
|
declare -ag DOMAIN_FILES
|
||||||
|
|
||||||
if input=$(getopt -o +e:fks:d -l email:,force,keep-grouping,sites-dir:,debug -- "$@"); then
|
if input=$(getopt -o +m:e:fgs:d -l method:,email:,force,group-by-file,sites-dir:,debug -- "$@"); then
|
||||||
eval set -- "$input"
|
eval set -- "$input"
|
||||||
while true; do
|
while true; do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
|
--method|-m)
|
||||||
|
shift
|
||||||
|
METHOD="${1,,}"
|
||||||
|
;;
|
||||||
--email|-e)
|
--email|-e)
|
||||||
shift
|
shift
|
||||||
USEREMAIL="$1"
|
USEREMAIL="$1"
|
||||||
@@ -41,7 +50,7 @@ parse_input() {
|
|||||||
--force|-f)
|
--force|-f)
|
||||||
unset DEBUG
|
unset DEBUG
|
||||||
;;
|
;;
|
||||||
--keep-grouping|-k)
|
--group-by-file|-g)
|
||||||
GROUP="true"
|
GROUP="true"
|
||||||
;;
|
;;
|
||||||
--sites-dir|-s)
|
--sites-dir|-s)
|
||||||
@@ -91,10 +100,27 @@ update_email() { [[ -v USEREMAIL ]] && "$HOME/.acme.sh/acme.sh" --update-account
|
|||||||
|
|
||||||
command_prefixes() {
|
command_prefixes() {
|
||||||
declare -ag ISSUE_CMD_PREFIX DEPLOY_CMD_PREFIX
|
declare -ag ISSUE_CMD_PREFIX DEPLOY_CMD_PREFIX
|
||||||
ISSUE_CMD_PREFIX=("$HOME/.acme.sh/acme.sh" "--issue" "--force")
|
ISSUE_CMD_PREFIX=("$HOME/.acme.sh/acme.sh" "--issue")
|
||||||
[[ -v DEBUG ]] && ISSUE_CMD_PREFIX=("$HOME/.acme.sh/acme.sh" "--issue" "--staging")
|
[[ "$METHOD" == "dns" ]] && ISSUE_CMD_PREFIX=("${ISSUE_CMD_PREFIX[@]}" "--dns" "dns_cpaneldns")
|
||||||
|
[[ -v DEBUG ]] && ISSUE_CMD_PREFIX=("${ISSUE_CMD_PREFIX[@]}" "--staging") || ISSUE_CMD_PREFIX=("${ISSUE_CMD_PREFIX[@]}" "--force")
|
||||||
DEPLOY_CMD_PREFIX=("$HOME/.acme.sh/acme.sh" "--deploy" "--deploy-hook" "cpanel_uapi")
|
DEPLOY_CMD_PREFIX=("$HOME/.acme.sh/acme.sh" "--deploy" "--deploy-hook" "cpanel_uapi")
|
||||||
[[ -v DEBUG ]] && DEPLOY_CMD_PREFIX=("$HOME/.acme.sh/acme.sh" "--deploy" "--deploy-hook" "cpanel_uapi")
|
}
|
||||||
|
|
||||||
|
|
||||||
|
get_webroot() {
|
||||||
|
local webroot
|
||||||
|
if ! webroot=$(uapi DomainInfo single_domain_data domain="$1" | grep documentroot); then
|
||||||
|
echo "UAPI call failed" >&2
|
||||||
|
fi
|
||||||
|
if [[ ! -v webroot || "$webroot" == "" ]]; then
|
||||||
|
if [[ -v DEBUG ]]; then
|
||||||
|
webroot="/tmp" # set missing webroot in DEBUG mode for testing
|
||||||
|
else
|
||||||
|
echo "Could not find $1's webroot" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
echo "$webroot"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -117,23 +143,6 @@ load_domains() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
get_webroot() {
|
|
||||||
local webroot
|
|
||||||
if ! webroot=$(uapi DomainInfo single_domain_data domain="$1" | grep documentroot); then
|
|
||||||
echo "UAPI call failed" >&2
|
|
||||||
fi
|
|
||||||
if [[ ! -v webroot || "$webroot" == "" ]]; then
|
|
||||||
if [[ -v DEBUG ]]; then
|
|
||||||
webroot="/tmp" # set missing webroot in DEBUG mode for testing
|
|
||||||
else
|
|
||||||
echo "Could not find $1's webroot" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
echo "$webroot"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
issue_and_deploy_certs() {
|
issue_and_deploy_certs() {
|
||||||
|
|
||||||
local domain_root domain domain_group
|
local domain_root domain domain_group
|
||||||
@@ -156,7 +165,8 @@ issue_and_deploy_certs() {
|
|||||||
|
|
||||||
# Issue certificate for entire domain group
|
# Issue certificate for entire domain group
|
||||||
echo "Running:" "${issue_cmd[@]}"
|
echo "Running:" "${issue_cmd[@]}"
|
||||||
"${issue_cmd[@]}"
|
if ! "${issue_cmd[@]}"; then
|
||||||
|
echo "Failed to issue certificate"
|
||||||
# Deploy certificates one by one
|
# Deploy certificates one by one
|
||||||
for domain in $domain_group; do
|
for domain in $domain_group; do
|
||||||
deploy_cmd=("${DEPLOY_CMD_PREFIX[@]}" "-w" "$domain_root" "-d" "$domain")
|
deploy_cmd=("${DEPLOY_CMD_PREFIX[@]}" "-w" "$domain_root" "-d" "$domain")
|
||||||
@@ -168,18 +178,19 @@ issue_and_deploy_certs() {
|
|||||||
for domain_group in "${DOMAIN_GROUPS[@]}"; do
|
for domain_group in "${DOMAIN_GROUPS[@]}"; do
|
||||||
# Issue and deploy certificates one by one
|
# Issue and deploy certificates one by one
|
||||||
for domain in $domain_group; do # we want to split on whitespace
|
for domain in $domain_group; do # we want to split on whitespace
|
||||||
domain_root=$(get_webroot "$domain")
|
issue_cmd=("${ISSUE_CMD_PREFIX[@]}" "-d" "$domain" "-d" "www.$domain")
|
||||||
issue_cmd=("${ISSUE_CMD_PREFIX[@]}" "-w" "$domain_root" "-d" "$domain" "-d" "www.$domain")
|
[[ "$METHOD" == "webroot" ]] && domain_root=$(get_webroot "$domain") && issue_cmd=("${issue_cmd[@]}" "-w" "$domain_root")
|
||||||
deploy_cmd=("${DEPLOY_CMD_PREFIX[@]}" "-w" "$domain_root" "-d" "$domain") # I think we only need to deploy to the domain, not subdomains
|
deploy_cmd=("${DEPLOY_CMD_PREFIX[@]}" "-d" "$domain") # I think we only need to deploy to the domain, not subdomains
|
||||||
|
[[ "$METHOD" == "webroot" ]] && deploy_cmd=("${deploy_cmd[@]}" "-w" "$domain_root")
|
||||||
echo "Running:" "${issue_cmd[@]}"
|
echo "Running:" "${issue_cmd[@]}"
|
||||||
if ! "${issue_cmd[@]}"; then
|
if ! "${issue_cmd[@]}"; then
|
||||||
echo "Certificate issue failed for $domain"
|
echo "Failed to issue certificate for $domain"
|
||||||
exit_err=1
|
err=1
|
||||||
fi
|
fi
|
||||||
echo "Running:" "${deploy_cmd[@]}"
|
echo "Running:" "${deploy_cmd[@]}"
|
||||||
if ! "${deploy_cmd[@]}"; then
|
if ! "${deploy_cmd[@]}"; then
|
||||||
echo "Certificate deployment failed for $domain"
|
echo "Failed to deploy certificate for $domain"
|
||||||
exit_err=1
|
err=1
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
done
|
done
|
||||||
@@ -198,4 +209,4 @@ main() {
|
|||||||
|
|
||||||
|
|
||||||
main "$@"
|
main "$@"
|
||||||
exit "${exit_err:-0}"
|
exit "${err:-0}"
|
||||||
Reference in New Issue
Block a user