Evoacme: big refactoring
* debug messages are sent to stdout * domains discovery from vhosts is extracted to "vhost-domains" * fixes suggested by shellcheck * variables are "local" or "readonly" wherever possible
This commit is contained in:
parent
c5844fa193
commit
beff333a1a
|
@ -11,37 +11,40 @@ set -e
|
||||||
set -u
|
set -u
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
echo "Usage: $0 NAME"
|
cat <<EOT
|
||||||
echo ""
|
Usage: ${PROGNAME} NAME
|
||||||
echo "NAME must be correspond to :"
|
NAME must be correspond to :
|
||||||
echo "- a CSR in ${CSR_DIR}/NAME.csr"
|
- a CSR in ${CSR_DIR}/NAME.csr
|
||||||
echo "- a KEY in ${SSL_KEY_DIR}/NAME.key"
|
- a KEY in ${SSL_KEY_DIR}/NAME.key
|
||||||
echo ""
|
|
||||||
echo "If env variable TEST=1, certbot is run in staging mode"
|
If env variable TEST=1, certbot is run in staging mode
|
||||||
echo "If env variable DRY_RUN=1, certbot is run in dry-run mode"
|
If env variable DRY_RUN=1, certbot is run in dry-run mode
|
||||||
echo "If env variable CRON=1, no message is output"
|
If env variable QUIET=1, no message is output
|
||||||
echo ""
|
If env variable VERBOSE=1, debug messages are output
|
||||||
|
EOT
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log() {
|
||||||
|
[ "${QUIET}" != "1" ] && echo "${PROGNAME}: $1"
|
||||||
|
}
|
||||||
debug() {
|
debug() {
|
||||||
[ "${CRON}" != "1" ] && echo "$1"
|
[ "${VERBOSE}" = "1" ] && [ "${QUIET}" != "1" ] && >&2 echo "${PROGNAME}: $1"
|
||||||
}
|
}
|
||||||
|
|
||||||
error() {
|
error() {
|
||||||
echo "error: $1" >&2
|
>&2 echo "${PROGNAME}: $1"
|
||||||
[ "$1" = "invalid argument(s)" ] && usage
|
[ "$1" = "invalid argument(s)" ] && >&2 usage
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
sed_cert_path_for_apache() {
|
sed_cert_path_for_apache() {
|
||||||
vhost=$1
|
local vhost=$1
|
||||||
vhost_full_path="/etc/apache2/ssl/${vhost}.conf"
|
local vhost_full_path="/etc/apache2/ssl/${vhost}.conf"
|
||||||
cert_path=$2
|
local cert_path=$2
|
||||||
|
|
||||||
[ ! -r "${vhost_full_path}" ] || return 0
|
[ ! -r "${vhost_full_path}" ] || return 0
|
||||||
|
|
||||||
search="^SSLCertificateFile.*$"
|
local search="^SSLCertificateFile.*$"
|
||||||
replace="SSLCertificateFile ${cert_path}"
|
local replace="SSLCertificateFile ${cert_path}"
|
||||||
|
|
||||||
if ! $(grep -qE "${search}" "${vhost_full_path}"); then
|
if ! $(grep -qE "${search}" "${vhost_full_path}"); then
|
||||||
[ -w "${vhost_full_path}" ] || error "File ${vhost_full_path} is not writable"
|
[ -w "${vhost_full_path}" ] || error "File ${vhost_full_path} is not writable"
|
||||||
|
@ -51,16 +54,15 @@ sed_cert_path_for_apache() {
|
||||||
$(command -v apache2ctl) -t
|
$(command -v apache2ctl) -t
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
sed_cert_path_for_nginx() {
|
sed_cert_path_for_nginx() {
|
||||||
vhost=$1
|
local vhost=$1
|
||||||
vhost_full_path="/etc/nginx/ssl/${vhost}.conf"
|
local vhost_full_path="/etc/nginx/ssl/${vhost}.conf"
|
||||||
cert_path=$2
|
local cert_path=$2
|
||||||
|
|
||||||
[ ! -r "${vhost_full_path}" ] || return 0
|
[ ! -r "${vhost_full_path}" ] || return 0
|
||||||
|
|
||||||
search="^ssl_certificate[^_].*$"
|
local search="^ssl_certificate[^_].*$"
|
||||||
replace="ssl_certificate ${cert_path};"
|
local replace="ssl_certificate ${cert_path};"
|
||||||
|
|
||||||
if ! $(grep -qE "${search}" "${vhost_full_path}"); then
|
if ! $(grep -qE "${search}" "${vhost_full_path}"); then
|
||||||
[ -w "${vhost_full_path}" ] || error "File ${vhost_full_path} is not writable"
|
[ -w "${vhost_full_path}" ] || error "File ${vhost_full_path} is not writable"
|
||||||
|
@ -70,36 +72,27 @@ sed_cert_path_for_nginx() {
|
||||||
$(command -v nginx) -t
|
$(command -v nginx) -t
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
x509_verify() {
|
x509_verify() {
|
||||||
file="$1"
|
local file="$1"
|
||||||
[ -r "$file" ] || error "File ${file} not found"
|
[ -r "$file" ] || error "File ${file} not found"
|
||||||
${OPENSSL_BIN} x509 -noout -modulus -in "$file" >/dev/null
|
"${OPENSSL_BIN}" x509 -noout -modulus -in "$file" >/dev/null
|
||||||
}
|
|
||||||
csr_verify() {
|
|
||||||
file="$1"
|
|
||||||
[ -r "$file" ] || error "File ${file} not found"
|
|
||||||
${OPENSSL_BIN} req -noout -modulus -in "$file" >/dev/null
|
|
||||||
}
|
}
|
||||||
x509_enddate() {
|
x509_enddate() {
|
||||||
file="$1"
|
local file="$1"
|
||||||
[ -r "$file" ] || error "File ${file} not found"
|
[ -r "$file" ] || error "File ${file} not found"
|
||||||
${OPENSSL_BIN} x509 -noout -enddate -in "$file"
|
"${OPENSSL_BIN}" x509 -noout -enddate -in "$file"
|
||||||
|
}
|
||||||
|
csr_verify() {
|
||||||
|
local file="$1"
|
||||||
|
[ -r "$file" ] || error "File ${file} not found"
|
||||||
|
"${OPENSSL_BIN}" req -noout -modulus -in "$file" >/dev/null
|
||||||
}
|
}
|
||||||
|
|
||||||
main() {
|
main() {
|
||||||
# Read configuration file, if it exists
|
[ "$1" = "-h" ] || [ "$1" = "--help" ] && usage && exit 0
|
||||||
[ -r /etc/default/evoacme ] && . /etc/default/evoacme
|
# check arguments
|
||||||
|
echo "1: '$1'"
|
||||||
# Default value for main variables
|
[ "$#" -eq 1 ] || error "invalid argument(s)"
|
||||||
SSL_KEY_DIR=${SSL_KEY_DIR:-"/etc/ssl/private"}
|
|
||||||
ACME_DIR=${ACME_DIR:-"/var/lib/letsencrypt"}
|
|
||||||
CSR_DIR=${CSR_DIR:-"/etc/ssl/requests"}
|
|
||||||
CRT_DIR=${CRT_DIR:-"/etc/letsencrypt"}
|
|
||||||
LOG_DIR=${LOG_DIR:-"/var/log/evoacme"}
|
|
||||||
SSL_MINDAY=${SSL_MINDAY:-"30"}
|
|
||||||
SELF_SIGNED_DIR=${SELF_SIGNED_DIR:-"/etc/ssl/self-signed"}
|
|
||||||
SSL_EMAIL=${SSL_EMAIL:-""}
|
|
||||||
|
|
||||||
[ -w "${SSL_KEY_DIR}" ] || error "Directory ${SSL_KEY_DIR} is not writable"
|
[ -w "${SSL_KEY_DIR}" ] || error "Directory ${SSL_KEY_DIR} is not writable"
|
||||||
[ -w "${ACME_DIR}" ] || error "Directory ${ACME_DIR} is not writable"
|
[ -w "${ACME_DIR}" ] || error "Directory ${ACME_DIR} is not writable"
|
||||||
|
@ -108,19 +101,11 @@ main() {
|
||||||
[ -w "${LOG_DIR}" ] || error "Directory ${LOG_DIR} is not writable"
|
[ -w "${LOG_DIR}" ] || error "Directory ${LOG_DIR} is not writable"
|
||||||
[ -w "${SELF_SIGNED_DIR}" ] || error "Directory ${SELF_SIGNED_DIR} is not writable"
|
[ -w "${SELF_SIGNED_DIR}" ] || error "Directory ${SELF_SIGNED_DIR} is not writable"
|
||||||
|
|
||||||
CRON=${CRON:-"0"}
|
readonly VHOST=$(basename "$1" .conf)
|
||||||
TEST=${TEST:-"0"}
|
|
||||||
DRY_RUN=${DRY_RUN:-"0"}
|
|
||||||
|
|
||||||
[ "$1" = "-h" ] || [ "$1" = "--help" ] && usage && exit 0
|
|
||||||
# check arguments
|
|
||||||
[ "$#" -eq 1 ] || error "invalid argument(s)"
|
|
||||||
|
|
||||||
VHOST=$(basename "$1" .conf)
|
|
||||||
|
|
||||||
# check for important programs
|
# check for important programs
|
||||||
OPENSSL_BIN=$(command -v openssl) || error "openssl command not installed"
|
readonly OPENSSL_BIN=$(command -v openssl) || error "openssl command not installed"
|
||||||
CERTBOT_BIN=$(command -v certbot) || error "certbot command not installed"
|
readonly CERTBOT_BIN=$(command -v certbot) || error "certbot command not installed"
|
||||||
|
|
||||||
# double check for directories
|
# double check for directories
|
||||||
[ -d "${ACME_DIR}" ] || error "${ACME_DIR} is not a directory"
|
[ -d "${ACME_DIR}" ] || error "${ACME_DIR} is not a directory"
|
||||||
|
@ -130,7 +115,7 @@ main() {
|
||||||
#### CSR VALIDATION
|
#### CSR VALIDATION
|
||||||
|
|
||||||
# verify .csr file
|
# verify .csr file
|
||||||
CSR_FILE="${CSR_DIR}/${VHOST}.csr"
|
readonly CSR_FILE="${CSR_DIR}/${VHOST}.csr"
|
||||||
debug "Using CSR file: ${CSR_FILE}"
|
debug "Using CSR file: ${CSR_FILE}"
|
||||||
[ -f "${CSR_FILE}" ] || error "${CSR_FILE} absent"
|
[ -f "${CSR_FILE}" ] || error "${CSR_FILE} absent"
|
||||||
[ -r "${CSR_FILE}" ] || error "${CSR_FILE} is not readable"
|
[ -r "${CSR_FILE}" ] || error "${CSR_FILE} is not readable"
|
||||||
|
@ -138,7 +123,7 @@ main() {
|
||||||
csr_verify "${CSR_FILE}" || error "${CSR_FILE} is invalid"
|
csr_verify "${CSR_FILE}" || error "${CSR_FILE} is invalid"
|
||||||
|
|
||||||
# Hook for evoadmin-web in cluster mode : check master status
|
# Hook for evoadmin-web in cluster mode : check master status
|
||||||
evoadmin_state_file="/home/${VHOST}/state"
|
local evoadmin_state_file="/home/${VHOST}/state"
|
||||||
[ -r "${evoadmin_state_file}" ] \
|
[ -r "${evoadmin_state_file}" ] \
|
||||||
&& grep -q "STATE=slave" "${evoadmin_state_file}" \
|
&& grep -q "STATE=slave" "${evoadmin_state_file}" \
|
||||||
&& debug "We are slave of this evoadmin cluster. Quit!" \
|
&& debug "We are slave of this evoadmin cluster. Quit!" \
|
||||||
|
@ -146,10 +131,10 @@ main() {
|
||||||
|
|
||||||
#### INIT OR RENEW?
|
#### INIT OR RENEW?
|
||||||
|
|
||||||
LIVE_DIR="${CRT_DIR}/${VHOST}/live"
|
readonly LIVE_DIR="${CRT_DIR}/${VHOST}/live"
|
||||||
LIVE_CERT="${LIVE_DIR}/cert.crt"
|
readonly LIVE_CERT="${LIVE_DIR}/cert.crt"
|
||||||
LIVE_FULLCHAIN="${LIVE_DIR}/fullchain.pem"
|
readonly LIVE_FULLCHAIN="${LIVE_DIR}/fullchain.pem"
|
||||||
LIVE_CHAIN="${LIVE_DIR}/chain.pem"
|
readonly LIVE_CHAIN="${LIVE_DIR}/chain.pem"
|
||||||
|
|
||||||
# If live symlink already exists, it's not our first time...
|
# If live symlink already exists, it's not our first time...
|
||||||
if [ -h "${LIVE_DIR}" ]; then
|
if [ -h "${LIVE_DIR}" ]; then
|
||||||
|
@ -169,10 +154,10 @@ main() {
|
||||||
|
|
||||||
#### CERTIFICATE CREATION WITH CERTBOT
|
#### CERTIFICATE CREATION WITH CERTBOT
|
||||||
|
|
||||||
ITERATION=$(date "+%Y%m%d%H%M%S")
|
local iteration=$(date "+%Y%m%d%H%M%S")
|
||||||
[ -n "${ITERATION}" ] || error "invalid iteration (${ITERATION})"
|
[ -n "${iteration}" ] || error "invalid iteration (${iteration})"
|
||||||
|
|
||||||
NEW_DIR="${CRT_DIR}/${VHOST}/${ITERATION}"
|
readonly NEW_DIR="${CRT_DIR}/${VHOST}/${iteration}"
|
||||||
|
|
||||||
[ -d "${NEW_DIR}" ] && error "${NEW_DIR} directory already exists, remove it manually."
|
[ -d "${NEW_DIR}" ] && error "${NEW_DIR} directory already exists, remove it manually."
|
||||||
mkdir -p "${NEW_DIR}"
|
mkdir -p "${NEW_DIR}"
|
||||||
|
@ -180,16 +165,16 @@ main() {
|
||||||
chown -R acme: "${CRT_DIR}"
|
chown -R acme: "${CRT_DIR}"
|
||||||
debug "New cert will be created in ${NEW_DIR}"
|
debug "New cert will be created in ${NEW_DIR}"
|
||||||
|
|
||||||
NEW_CERT="${NEW_DIR}/cert.crt"
|
readonly NEW_CERT="${NEW_DIR}/cert.crt"
|
||||||
NEW_FULLCHAIN="${NEW_DIR}/fullchain.pem"
|
readonly NEW_FULLCHAIN="${NEW_DIR}/fullchain.pem"
|
||||||
NEW_CHAIN="${NEW_DIR}/chain.pem"
|
readonly NEW_CHAIN="${NEW_DIR}/chain.pem"
|
||||||
|
|
||||||
CERTBOT_MODE=""
|
local CERTBOT_MODE=""
|
||||||
[ "${TEST}" = "1" ] && CERTBOT_MODE="${CERTBOT_MODE} --test-cert"
|
[ "${TEST}" = "1" ] && CERTBOT_MODE="${CERTBOT_MODE} --test-cert"
|
||||||
[ "${CRON}" = "1" ] && CERTBOT_MODE="${CERTBOT_MODE} --quiet"
|
[ "${QUIET}" = "1" ] && CERTBOT_MODE="${CERTBOT_MODE} --quiet"
|
||||||
[ "${DRY_RUN}" = "1" ] && CERTBOT_MODE="${CERTBOT_MODE} --dry-run"
|
[ "${DRY_RUN}" = "1" ] && CERTBOT_MODE="${CERTBOT_MODE} --dry-run"
|
||||||
|
|
||||||
CERTBOT_REGISTRATION="--agree-tos"
|
local CERTBOT_REGISTRATION="--agree-tos"
|
||||||
if [ -n "${SSL_EMAIL}" ]; then
|
if [ -n "${SSL_EMAIL}" ]; then
|
||||||
debug "Registering at certbot with ${SSL_EMAIL} as email"
|
debug "Registering at certbot with ${SSL_EMAIL} as email"
|
||||||
CERTBOT_REGISTRATION="${CERTBOT_REGISTRATION} -m ${SSL_EMAIL}"
|
CERTBOT_REGISTRATION="${CERTBOT_REGISTRATION} -m ${SSL_EMAIL}"
|
||||||
|
@ -204,7 +189,7 @@ main() {
|
||||||
|
|
||||||
# create a certificate with certbot
|
# create a certificate with certbot
|
||||||
sudo -u acme \
|
sudo -u acme \
|
||||||
${CERTBOT_BIN} \
|
"${CERTBOT_BIN}" \
|
||||||
certonly \
|
certonly \
|
||||||
${CERTBOT_MODE} \
|
${CERTBOT_MODE} \
|
||||||
${CERTBOT_REGISTRATION} \
|
${CERTBOT_REGISTRATION} \
|
||||||
|
@ -220,7 +205,7 @@ main() {
|
||||||
| grep -v "certbot.crypto_util"
|
| grep -v "certbot.crypto_util"
|
||||||
|
|
||||||
if [ "${DRY_RUN}" = "1" ]; then
|
if [ "${DRY_RUN}" = "1" ]; then
|
||||||
echo "In dry-run mode, we stop here. Bye"
|
debug "In dry-run mode, we stop here. Bye"
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -229,6 +214,8 @@ main() {
|
||||||
x509_verify "${NEW_FULLCHAIN}" || error "${NEW_FULLCHAIN} is invalid"
|
x509_verify "${NEW_FULLCHAIN}" || error "${NEW_FULLCHAIN} is invalid"
|
||||||
x509_verify "${NEW_CHAIN}" || error "${NEW_CHAIN} is invalid"
|
x509_verify "${NEW_CHAIN}" || error "${NEW_CHAIN} is invalid"
|
||||||
|
|
||||||
|
log "New certificate available at ${NEW_CERT}"
|
||||||
|
|
||||||
#### CERTIFICATE ACTIVATION
|
#### CERTIFICATE ACTIVATION
|
||||||
|
|
||||||
# link dance
|
# link dance
|
||||||
|
@ -264,4 +251,26 @@ main() {
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
main "$@"
|
readonly PROGNAME=$(basename "$0")
|
||||||
|
readonly PROGDIR=$(readlink -m $(dirname "$0"))
|
||||||
|
readonly ARGS=$@
|
||||||
|
|
||||||
|
readonly VERBOSE=${VERBOSE:-"0"}
|
||||||
|
readonly QUIET=${QUIET:-"0"}
|
||||||
|
readonly TEST=${TEST:-"0"}
|
||||||
|
readonly DRY_RUN=${DRY_RUN:-"0"}
|
||||||
|
|
||||||
|
# Read configuration file, if it exists
|
||||||
|
[ -r /etc/default/evoacme ] && . /etc/default/evoacme
|
||||||
|
|
||||||
|
# Default value for main variables
|
||||||
|
readonly SSL_KEY_DIR=${SSL_KEY_DIR:-"/etc/ssl/private"}
|
||||||
|
readonly ACME_DIR=${ACME_DIR:-"/var/lib/letsencrypt"}
|
||||||
|
readonly CSR_DIR=${CSR_DIR:-"/etc/ssl/requests"}
|
||||||
|
readonly CRT_DIR=${CRT_DIR:-"/etc/letsencrypt"}
|
||||||
|
readonly LOG_DIR=${LOG_DIR:-"/var/log/evoacme"}
|
||||||
|
readonly SSL_MINDAY=${SSL_MINDAY:-"30"}
|
||||||
|
readonly SELF_SIGNED_DIR=${SELF_SIGNED_DIR:-"/etc/ssl/self-signed"}
|
||||||
|
readonly SSL_EMAIL=${SSL_EMAIL:-""}
|
||||||
|
|
||||||
|
main ${ARGS}
|
||||||
|
|
|
@ -7,110 +7,38 @@
|
||||||
# Licence: AGPLv3
|
# Licence: AGPLv3
|
||||||
#
|
#
|
||||||
|
|
||||||
real_ip_for_domain() {
|
set -u
|
||||||
dig +short "$1" | grep -oE "([0-9]+\.){3}[0-9]+"
|
|
||||||
|
usage() {
|
||||||
|
cat <<EOT
|
||||||
|
Usage: ${PROGNAME} VHOST DOMAIN...
|
||||||
|
VHOST must correspond to an Apache or Nginx enabled VHost
|
||||||
|
If VHOST ends with ".conf" it is stripped,
|
||||||
|
then files are seached at those paths:
|
||||||
|
- /etc/apache2/sites-enables/VHOST.conf
|
||||||
|
- /etc/nginx/sites-enabled/VHOST.conf
|
||||||
|
- /etc/nginx/sites-enabled/VHOST
|
||||||
|
DOMAIN... is a list of domains for the CSR (passed as arguments or input)
|
||||||
|
|
||||||
|
If env variable VERBOSE=1, debug messages are sent to stderr
|
||||||
|
EOT
|
||||||
}
|
}
|
||||||
local_ip() {
|
debug() {
|
||||||
ip a | grep brd | cut -d'/' -f1 | grep -oE "([0-9]+\.){3}[0-9]+"
|
if [ "${VERBOSE}" = 1 ]; then
|
||||||
|
>&2 echo "${PROGNAME}: $1"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
error() {
|
||||||
|
>&2 echo "${PROGNAME}: $1"
|
||||||
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
get_domains() {
|
default_key_size() {
|
||||||
echo "$vhostfile" | grep -q nginx
|
grep default_bits "${SSL_CONFIG_FILE}" | cut -d'=' -f2 | xargs
|
||||||
if [ "$?" -eq 0 ]; then
|
|
||||||
domains=$(
|
|
||||||
grep -oE "^( )*[^#]+" "$vhostfile" \
|
|
||||||
| grep -oE "[^\$]server_name.*;$" \
|
|
||||||
| sed 's/server_name//' \
|
|
||||||
| tr -d ';' \
|
|
||||||
| sed 's/\s\{1,\}//' \
|
|
||||||
| sed 's/\s\{1,\}/\n/g' \
|
|
||||||
| sort \
|
|
||||||
| uniq
|
|
||||||
)
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "$vhostfile" | grep -q apache2
|
|
||||||
if [ "$?" -eq 0 ]; then
|
|
||||||
domains=$(
|
|
||||||
grep -oE "^( )*[^#]+" "$vhostfile" \
|
|
||||||
| grep -oE "(ServerName|ServerAlias).*" \
|
|
||||||
| sed 's/ServerName//' \
|
|
||||||
| sed 's/ServerAlias//' \
|
|
||||||
| sed 's/\s\{1,\}//' \
|
|
||||||
| sort \
|
|
||||||
| uniq
|
|
||||||
)
|
|
||||||
fi
|
|
||||||
valid_domains=""
|
|
||||||
nb=0
|
|
||||||
|
|
||||||
echo "Valid(s) domain(s) in ${VHOST} :"
|
|
||||||
for domain in $domains; do
|
|
||||||
real_ip=$(real_ip_for_domain "${domain}")
|
|
||||||
for ip in $(echo "${SRV_IP}" | xargs -n1); do
|
|
||||||
if [ "${ip}" = "${real_ip}" ]; then
|
|
||||||
valid_domains="${valid_domains} ${domain}"
|
|
||||||
nb=$(( nb + 1 ))
|
|
||||||
echo "* ${domain} -> ${real_ip}"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ "${nb}" -eq 0 ]; then
|
|
||||||
nb=$(echo "${domains}" | wc -l)
|
|
||||||
echo "* No valid domain found"
|
|
||||||
echo "All following(s) domain(s) will be used for CSR creation :"
|
|
||||||
for domain in $domains; do
|
|
||||||
echo "* ${domain}"
|
|
||||||
done
|
|
||||||
else
|
|
||||||
domains="${valid_domains}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
domains=$(echo "$domains" | xargs -n1)
|
|
||||||
}
|
|
||||||
|
|
||||||
make_key() {
|
|
||||||
openssl genrsa -out "${SSL_KEY_FILE}" "${SSL_KEY_SIZE}" 2>/dev/null
|
|
||||||
chown root: "${SSL_KEY_FILE}"
|
|
||||||
chmod 600 "${SSL_KEY_FILE}"
|
|
||||||
}
|
|
||||||
|
|
||||||
make_csr() {
|
|
||||||
domains="$1"
|
|
||||||
nb=$(echo "${domains}" | wc -l)
|
|
||||||
config_file="/tmp/make-csr-${VHOST}.conf"
|
|
||||||
|
|
||||||
mkdir -p -m 0755 "${CSR_DIR}" || error "Unable to mkdir ${CSR_DIR}"
|
|
||||||
|
|
||||||
if [ "${nb}" -eq 1 ]; then
|
|
||||||
cat ${SSL_CONFIG_FILE} - > "${config_file}" <<EOF
|
|
||||||
CN=$domains
|
|
||||||
EOF
|
|
||||||
openssl req -new -sha256 -key "${SSL_KEY_FILE}" -config "${config_file}" -out "${CSR_FILE}"
|
|
||||||
elif [ "${nb}" -gt 1 ]; then
|
|
||||||
san=""
|
|
||||||
for domain in $domains; do
|
|
||||||
san="${san},DNS:${domain}"
|
|
||||||
done
|
|
||||||
san=$(echo "${san}" | sed 's/,//')
|
|
||||||
cat ${SSL_CONFIG_FILE} - > "${config_file}" <<EOF
|
|
||||||
[SAN]
|
|
||||||
subjectAltName=${san}
|
|
||||||
EOF
|
|
||||||
openssl req -new -sha256 -key "${SSL_KEY_FILE}" -reqexts SAN -config "${config_file}" > "${CSR_FILE}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -f "${CSR_FILE}" ]; then
|
|
||||||
chmod 644 "${CSR_FILE}"
|
|
||||||
mkdir -p -m 0755 "${SELF_SIGNED_DIR}"
|
|
||||||
openssl x509 -req -sha256 -days 365 -in "${CSR_FILE}" -signkey "${SSL_KEY_FILE}" -out "${SELF_SIGNED_FILE}"
|
|
||||||
[ -f "${SELF_SIGNED_FILE}" ] && chmod 644 "${SELF_SIGNED_FILE}"
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sed_selfsigned_cert_path_for_apache() {
|
sed_selfsigned_cert_path_for_apache() {
|
||||||
apache_ssl_vhost_path="$1"
|
local apache_ssl_vhost_path="$1"
|
||||||
|
|
||||||
mkdir -p $(dirname "${apache_ssl_vhost_path}")
|
mkdir -p $(dirname "${apache_ssl_vhost_path}")
|
||||||
if [ ! -f "${apache_ssl_vhost_path}" ]; then
|
if [ ! -f "${apache_ssl_vhost_path}" ]; then
|
||||||
|
@ -119,13 +47,18 @@ SSLEngine On
|
||||||
SSLCertificateFile ${SELF_SIGNED_FILE}
|
SSLCertificateFile ${SELF_SIGNED_FILE}
|
||||||
SSLCertificateKeyFile ${SSL_KEY_FILE}
|
SSLCertificateKeyFile ${SSL_KEY_FILE}
|
||||||
EOF
|
EOF
|
||||||
|
debug "SSL config added in ${apache_ssl_vhost_path}"
|
||||||
else
|
else
|
||||||
sed -i "s~^SSLCertificateFile.*$~SSLCertificateFile ${SELF_SIGNED_FILE}~" "${apache_ssl_vhost_path}"
|
local search="^SSLCertificateFile.*$"
|
||||||
|
local replace="SSLCertificateFile ${SELF_SIGNED_FILE}"
|
||||||
|
|
||||||
|
sed -i "s~${search}~${replace}~" "${apache_ssl_vhost_path}"
|
||||||
|
debug "SSL config updated in ${apache_ssl_vhost_path}"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
sed_selfsigned_cert_path_for_nginx() {
|
sed_selfsigned_cert_path_for_nginx() {
|
||||||
nginx_ssl_vhost_path="$1"
|
local nginx_ssl_vhost_path="$1"
|
||||||
|
|
||||||
mkdir -p $(dirname "${nginx_ssl_vhost_path}")
|
mkdir -p $(dirname "${nginx_ssl_vhost_path}")
|
||||||
if [ ! -f "${nginx_ssl_vhost_path}" ]; then
|
if [ ! -f "${nginx_ssl_vhost_path}" ]; then
|
||||||
|
@ -133,85 +66,171 @@ sed_selfsigned_cert_path_for_nginx() {
|
||||||
ssl_certificate ${SELF_SIGNED_FILE};
|
ssl_certificate ${SELF_SIGNED_FILE};
|
||||||
ssl_certificate_key ${SSL_KEY_FILE};
|
ssl_certificate_key ${SSL_KEY_FILE};
|
||||||
EOF
|
EOF
|
||||||
|
debug "SSL config added in ${nginx_ssl_vhost_path}"
|
||||||
else
|
else
|
||||||
sed -i "s~^ssl_certificate[^_].*$~ssl_certificate ${SELF_SIGNED_FILE};~" "${nginx_ssl_vhost_path}"
|
local search="^ssl_certificate[^_].*$"
|
||||||
|
local replace="ssl_certificate ${SELF_SIGNED_FILE};"
|
||||||
|
|
||||||
|
sed -i "s~${search}~${replace}~" "${nginx_ssl_vhost_path}"
|
||||||
|
debug "SSL config updated in ${nginx_ssl_vhost_path}"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
first_vhost_file_found() {
|
openssl_selfsigned() {
|
||||||
vhost=$1
|
local csr="$1"
|
||||||
|
local key="$2"
|
||||||
|
local crt="$3"
|
||||||
|
local crt_dir=$(dirname ${crt})
|
||||||
|
|
||||||
ls "/etc/nginx/sites-enabled/${vhost}" \
|
[ -r "${csr}" ] || error "File ${csr} is not readable"
|
||||||
"/etc/nginx/sites-enabled/${vhost}.conf" \
|
[ -r "${key}" ] || error "File ${key} is not readable"
|
||||||
"/etc/apache2/sites-enabled/${vhost}.conf" 2>/dev/null \
|
[ -w "${crt_dir}" ] || error "Directory ${crt_dir} is not writable"
|
||||||
| head -n 1
|
|
||||||
|
"${OPENSSL_BIN}" x509 -req -sha256 -days 365 -in "${csr}" -signkey "${key}" -out "${crt}" 2> /dev/null
|
||||||
|
}
|
||||||
|
openssl_key(){
|
||||||
|
local key="$1"
|
||||||
|
local key_dir=$(dirname "${key}")
|
||||||
|
local size="$2"
|
||||||
|
|
||||||
|
[ -w "${key_dir}" ] || error "Directory ${key_dir} is not writable"
|
||||||
|
|
||||||
|
"${OPENSSL_BIN}" genrsa -out "${key}" "${size}" 2> /dev/null
|
||||||
|
}
|
||||||
|
openssl_csr_san() {
|
||||||
|
local csr="$1"
|
||||||
|
local csr_dir=$(dirname "${csr}")
|
||||||
|
local key="$2"
|
||||||
|
local cfg="$3"
|
||||||
|
|
||||||
|
[ -w "${csr_dir}" ] || error "Directory ${csr_dir} is not writable"
|
||||||
|
|
||||||
|
"${OPENSSL_BIN}" req -new -sha256 -key "${key}" -reqexts SAN -config "${cfg}" -out "${csr}"
|
||||||
|
}
|
||||||
|
openssl_csr_single() {
|
||||||
|
local csr="$1"
|
||||||
|
local csr_dir=$(dirname "${csr}")
|
||||||
|
local key="$2"
|
||||||
|
local cfg="$3"
|
||||||
|
|
||||||
|
[ -w "${csr_dir}" ] || error "Directory ${csr_dir} is not writable"
|
||||||
|
|
||||||
|
"${OPENSSL_BIN}" req -new -sha256 -key "${key}" -config "${cfg}" -out "${csr}"
|
||||||
}
|
}
|
||||||
|
|
||||||
default_key_size() {
|
make_key() {
|
||||||
grep default_bits ${SSL_CONFIG_FILE} \
|
local key="$1"
|
||||||
| cut -d'=' -f2 \
|
local size="$2"
|
||||||
| xargs
|
|
||||||
|
openssl_key "${key}" "${size}"
|
||||||
|
debug "Private key stored at ${key}"
|
||||||
|
|
||||||
|
chown root: "${key}"
|
||||||
|
chmod 600 "${key}"
|
||||||
|
}
|
||||||
|
|
||||||
|
make_csr() {
|
||||||
|
local domains=$@
|
||||||
|
local nb=$#
|
||||||
|
local config_file="/tmp/make-csr-${VHOST}.conf"
|
||||||
|
local san=
|
||||||
|
|
||||||
|
mkdir -p -m 0755 "${CSR_DIR}" || error "Unable to mkdir ${CSR_DIR}"
|
||||||
|
|
||||||
|
if [ "${nb}" -eq 1 ]; then
|
||||||
|
cat "${SSL_CONFIG_FILE}" - > "${config_file}" <<EOF
|
||||||
|
CN=$domains
|
||||||
|
EOF
|
||||||
|
openssl_csr_single "${CSR_FILE}" "${SSL_KEY_FILE}" "${config_file}"
|
||||||
|
elif [ "${nb}" -gt 1 ]; then
|
||||||
|
for domain in $domains; do
|
||||||
|
san="${san},DNS:${domain}"
|
||||||
|
done
|
||||||
|
san=$(echo "${san}" | sed 's/,//')
|
||||||
|
cat ${SSL_CONFIG_FILE} - > "${config_file}" <<EOF
|
||||||
|
[SAN]
|
||||||
|
subjectAltName=${san}
|
||||||
|
EOF
|
||||||
|
openssl_csr_san "${CSR_FILE}" "${SSL_KEY_FILE}" "${config_file}"
|
||||||
|
fi
|
||||||
|
debug "CSR stored at ${CSR_FILE}"
|
||||||
|
|
||||||
|
if [ -r "${CSR_FILE}" ]; then
|
||||||
|
chmod 644 "${CSR_FILE}"
|
||||||
|
mkdir -p -m 0755 "${SELF_SIGNED_DIR}"
|
||||||
|
|
||||||
|
openssl_selfsigned "${CSR_FILE}" "${SSL_KEY_FILE}" "${SELF_SIGNED_FILE}"
|
||||||
|
|
||||||
|
[ -r "${SELF_SIGNED_FILE}" ] && chmod 644 "${SELF_SIGNED_FILE}"
|
||||||
|
debug "Self-signed certificate stored at ${SELF_SIGNED_FILE}"
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
main() {
|
main() {
|
||||||
if [ "$#" -ne 1 ]; then
|
if [ -t 0 ]; then
|
||||||
echo "You need to provide one argument !" >&2
|
# We have STDIN, so we should have at least 2 arguments
|
||||||
|
if [ "$#" -lt 2 ]; then
|
||||||
|
>&2 echo "invalid arguments"
|
||||||
|
>&2 usage
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
# read VHOST from first argument
|
||||||
|
readonly VHOST="$1"
|
||||||
|
# remove the first argument
|
||||||
|
shift
|
||||||
|
# read domains from remaining arguments
|
||||||
|
readonly DOMAINS=$@
|
||||||
|
else
|
||||||
|
# We don't have STDIN, so we should have only 1 argument
|
||||||
|
if [ "$#" != 1 ]; then
|
||||||
|
>&2 echo "invalid arguments"
|
||||||
|
>&2 usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
# read VHOST from first argument
|
||||||
|
readonly VHOST="$1"
|
||||||
|
# read domains from input
|
||||||
|
DOMAINS=
|
||||||
|
while read -r line ; do
|
||||||
|
DOMAINS="${DOMAINS} ${line}"
|
||||||
|
done
|
||||||
|
# trim the string to remove leading/trailing spaces
|
||||||
|
DOMAINS=$(echo "${DOMAINS}" | xargs)
|
||||||
|
fi
|
||||||
|
|
||||||
|
[ -w "${CSR_DIR}" ] || error "Directory ${CSR_DIR} is not writable"
|
||||||
|
[ -w "${SELF_SIGNED_DIR}" ] || error "Directory ${SELF_SIGNED_DIR} is not writable"
|
||||||
|
[ -w "${SSL_KEY_DIR}" ] || error "Directory ${SSL_KEY_DIR} is not writable"
|
||||||
|
[ -r "${SSL_CONFIG_FILE}" ] || error "File ${SSL_CONFIG_FILE} is not readable"
|
||||||
|
|
||||||
|
# check for important programs
|
||||||
|
readonly OPENSSL_BIN=$(command -v openssl) || error "openssl command not installed"
|
||||||
|
|
||||||
|
SELF_SIGNED_FILE="${SELF_SIGNED_DIR}/${VHOST}.pem"
|
||||||
|
SSL_KEY_FILE="${SSL_KEY_DIR}/${VHOST}.key"
|
||||||
|
CSR_FILE="${CSR_DIR}/${VHOST}.csr"
|
||||||
|
|
||||||
|
make_key "${SSL_KEY_FILE}" "${SSL_KEY_SIZE}"
|
||||||
|
make_csr ${DOMAINS}
|
||||||
|
|
||||||
|
command -v apache2ctl >/dev/null && sed_selfsigned_cert_path_for_apache "/etc/apache2/ssl/${VHOST}.conf"
|
||||||
|
command -v nginx >/dev/null && sed_selfsigned_cert_path_for_nginx "/etc/nginx/ssl/${VHOST}.conf"
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly PROGNAME=$(basename "$0")
|
||||||
|
readonly PROGDIR=$(readlink -m $(dirname "$0"))
|
||||||
|
readonly ARGS=$@
|
||||||
|
|
||||||
|
readonly VERBOSE=${VERBOSE:-"0"}
|
||||||
|
|
||||||
# Read configuration file, if it exists
|
# Read configuration file, if it exists
|
||||||
[ -r /etc/default/evoacme ] && . /etc/default/evoacme
|
[ -r /etc/default/evoacme ] && . /etc/default/evoacme
|
||||||
|
|
||||||
# Default value for main variables
|
# Default value for main variables
|
||||||
CSR_DIR=${CSR_DIR:-'/etc/ssl/requests'}
|
CSR_DIR=${CSR_DIR:-'/etc/ssl/requests'}
|
||||||
CRT_DIR=${CRT_DIR:-'/etc/letsencrypt'}
|
|
||||||
SSL_CONFIG_FILE=${SSL_CONFIG_FILE:-"${CRT_DIR}/openssl.cnf"}
|
SSL_CONFIG_FILE=${SSL_CONFIG_FILE:-"${CRT_DIR}/openssl.cnf"}
|
||||||
SELF_SIGNED_DIR=${SELF_SIGNED_DIR:-'/etc/ssl/self-signed'}
|
SELF_SIGNED_DIR=${SELF_SIGNED_DIR:-'/etc/ssl/self-signed'}
|
||||||
SSL_KEY_DIR=${SSL_KEY_DIR:-'/etc/ssl/private'}
|
SSL_KEY_DIR=${SSL_KEY_DIR:-'/etc/ssl/private'}
|
||||||
SSL_KEY_SIZE=${SSL_KEY_SIZE:-$(default_key_size)}
|
SSL_KEY_SIZE=${SSL_KEY_SIZE:-$(default_key_size)}
|
||||||
SRV_IP=${SRV_IP:-""}
|
|
||||||
|
|
||||||
[ -w "${CSR_DIR}" ] || error "Directory ${CSR_DIR} is not writable"
|
main ${ARGS}
|
||||||
[ -w "${CRT_DIR}" ] || error "Directory ${CRT_DIR} is not writable"
|
|
||||||
[ -w "${SELF_SIGNED_DIR}" ] || error "Directory ${SELF_SIGNED_DIR} is not writable"
|
|
||||||
[ -w "${SSL_KEY_DIR}" ] || error "Directory ${SSL_KEY_DIR} is not writable"
|
|
||||||
[ -r "${SSL_CONFIG_FILE}" ] || error "File ${SSL_CONFIG_FILE} is not readable"
|
|
||||||
|
|
||||||
VHOST=$(basename "$1" .conf)
|
|
||||||
SELF_SIGNED_FILE="${SELF_SIGNED_DIR}/${VHOST}.pem"
|
|
||||||
SSL_KEY_FILE="${SSL_KEY_DIR}/${VHOST}.key"
|
|
||||||
LIVE_DIR="${CRT_DIR}/${VHOST}/live"
|
|
||||||
CSR_FILE="${CSR_DIR}/${VHOST}.csr"
|
|
||||||
|
|
||||||
LOCAL_IP=$(local_ip)
|
|
||||||
if [ -n "${SRV_IP}" ]; then
|
|
||||||
SRV_IP="${SRV_IP} ${LOCAL_IP}"
|
|
||||||
else
|
|
||||||
SRV_IP="${LOCAL_IP}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
vhostfile=$(first_vhost_file_found "${VHOST}")
|
|
||||||
|
|
||||||
if [ ! -h "${vhostfile}" ]; then
|
|
||||||
echo "${VHOST} is not a valid virtualhost !" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -f "${SSL_KEY_FILE}" ]; then
|
|
||||||
echo "${VHOST} key already exist, overwrite it? [yN]"
|
|
||||||
read REPLY
|
|
||||||
|
|
||||||
[ "${REPLY}" = "Y" ] || [ "${REPLY}" = "y" ] || exit 0
|
|
||||||
rm -f "/etc/apache2/ssl/${VHOST}.conf /etc/nginx/ssl/${VHOST}.conf"
|
|
||||||
[ -h "${LIVE_DIR}" ] && rm "${LIVE_DIR}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
get_domains
|
|
||||||
make_key
|
|
||||||
make_csr "${domains}"
|
|
||||||
|
|
||||||
command -v apache2ctl >/dev/null && sed_selfsigned_cert_path_for_apache "/etc/apache2/ssl/${VHOST}.conf"
|
|
||||||
command -v nginx >/dev/null && sed_selfsigned_cert_path_for_nginx "/etc/nginx/ssl/${VHOST}.conf"
|
|
||||||
}
|
|
||||||
|
|
||||||
main "$@"
|
|
||||||
|
|
151
evoacme/files/vhost-domains.sh
Executable file
151
evoacme/files/vhost-domains.sh
Executable file
|
@ -0,0 +1,151 @@
|
||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# make-csr is a shell script designed to automatically generate a
|
||||||
|
# certificate signing request (CSR) from an Apache or a Nginx vhost
|
||||||
|
#
|
||||||
|
# Author: Victor Laborie <vlaborie@evolix.fr>
|
||||||
|
# Licence: AGPLv3
|
||||||
|
#
|
||||||
|
|
||||||
|
set -u
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<EOT
|
||||||
|
Usage: ${PROGNAME} VHOST
|
||||||
|
VHOST must correspond to an Apache or Nginx enabled VHost
|
||||||
|
If VHOST ends with ".conf" it is stripped,
|
||||||
|
then files are seached at those paths:
|
||||||
|
- /etc/apache2/sites-enables/VHOST.conf
|
||||||
|
- /etc/nginx/sites-enabled/VHOST.conf
|
||||||
|
- /etc/nginx/sites-enabled/VHOST
|
||||||
|
|
||||||
|
If env variable VERBOSE=1, debug messages are sent to stderr
|
||||||
|
EOT
|
||||||
|
}
|
||||||
|
|
||||||
|
debug() {
|
||||||
|
[ "${VERBOSE}" = 1 ] && >&2 echo "${PROGNAME}: $1"
|
||||||
|
}
|
||||||
|
error() {
|
||||||
|
>&2 echo "${PROGNAME}: $1"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
real_ip_for_domain() {
|
||||||
|
dig +short "$1" | grep -oE "([0-9]+\.){3}[0-9]+"
|
||||||
|
}
|
||||||
|
local_ip() {
|
||||||
|
ip a | grep brd | cut -d'/' -f1 | grep -oE "([0-9]+\.){3}[0-9]+"
|
||||||
|
}
|
||||||
|
|
||||||
|
nginx_domains() {
|
||||||
|
local vhost_file="$1"
|
||||||
|
|
||||||
|
grep -oE "^( )*[^#]+" "${vhost_file}" \
|
||||||
|
| grep -oE "[^\$]server_name.*;$" \
|
||||||
|
| sed 's/server_name//' \
|
||||||
|
| tr -d ';' \
|
||||||
|
| sed 's/\s\{1,\}//' \
|
||||||
|
| sed 's/\s\{1,\}/\n/g' \
|
||||||
|
| sort \
|
||||||
|
| uniq
|
||||||
|
}
|
||||||
|
|
||||||
|
apache_domains() {
|
||||||
|
local vhost_file="$1"
|
||||||
|
|
||||||
|
grep -oE "^( )*[^#]+" "${vhost_file}" \
|
||||||
|
| grep -oE "(ServerName|ServerAlias).*" \
|
||||||
|
| sed 's/ServerName//' \
|
||||||
|
| sed 's/ServerAlias//' \
|
||||||
|
| sed 's/\s\{1,\}//' \
|
||||||
|
| sort \
|
||||||
|
| uniq
|
||||||
|
}
|
||||||
|
|
||||||
|
get_domains() {
|
||||||
|
local vhost_file="$1"
|
||||||
|
local ips="$2"
|
||||||
|
local domains=""
|
||||||
|
local valid_domains=""
|
||||||
|
local nb=0
|
||||||
|
|
||||||
|
if $(echo "${vhost_file}" | grep -q nginx); then
|
||||||
|
debug "Nginx vhost file used"
|
||||||
|
domains=$(nginx_domains "${vhost_file}")
|
||||||
|
fi
|
||||||
|
if $(echo "${vhost_file}" | grep -q apache2); then
|
||||||
|
debug "Apache vhost file used"
|
||||||
|
domains=$(apache_domains "${vhost_file}")
|
||||||
|
fi
|
||||||
|
|
||||||
|
debug "Valid(s) domain(s) in ${vhost_file} :"
|
||||||
|
for domain in ${domains}; do
|
||||||
|
real_ip=$(real_ip_for_domain "${domain}")
|
||||||
|
for ip in $(echo "${ips}" | xargs -n1); do
|
||||||
|
if [ "${ip}" = "${real_ip}" ]; then
|
||||||
|
valid_domains="${valid_domains} ${domain}"
|
||||||
|
nb=$(( nb + 1 ))
|
||||||
|
debug "* ${domain} -> ${real_ip}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "${nb}" -eq 0 ]; then
|
||||||
|
nb=$(echo "${domains}" | wc -l)
|
||||||
|
debug "* No valid domain found"
|
||||||
|
debug "All following(s) domain(s) will be used for CSR creation :"
|
||||||
|
for domain in ${domains}; do
|
||||||
|
debug "* ${domain}"
|
||||||
|
done
|
||||||
|
else
|
||||||
|
domains="${valid_domains}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "${domains}" | xargs -n 1
|
||||||
|
}
|
||||||
|
|
||||||
|
first_vhost_file_found() {
|
||||||
|
local vhost_name="$1"
|
||||||
|
|
||||||
|
ls "/etc/nginx/sites-enabled/${vhost_name}" \
|
||||||
|
"/etc/nginx/sites-enabled/${vhost_name}.conf" \
|
||||||
|
"/etc/apache2/sites-enabled/${vhost_name}.conf" \
|
||||||
|
2>/dev/null \
|
||||||
|
| head -n 1
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
if [ "$#" != 1 ]; then
|
||||||
|
>&2 usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
|
||||||
|
usage
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
local vhost_name=$(basename "$1" .conf)
|
||||||
|
local vhost_file=$(first_vhost_file_found "${vhost_name}")
|
||||||
|
|
||||||
|
if [ ! -h "${vhost_file}" ]; then
|
||||||
|
>&2 echo "No virtualhost has been found for '${vhost_name}'."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
local ips=$(local_ip)
|
||||||
|
if [ -n "${SRV_IP}" ]; then
|
||||||
|
ips="${ips} ${SRV_IP}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
get_domains "${vhost_file}" "${ips}"
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly PROGNAME=$(basename "$0")
|
||||||
|
readonly PROGDIR=$(readlink -m $(dirname "$0"))
|
||||||
|
readonly ARGS=$@
|
||||||
|
|
||||||
|
readonly VERBOSE=${VERBOSE:-"0"}
|
||||||
|
readonly SRV_IP=${SRV_IP:-""}
|
||||||
|
|
||||||
|
main $ARGS
|
Loading…
Reference in a new issue