#!/bin/bash ###TODO### #available functions - can be used as a function list or a direct execute by passing action - done #would write domains into file/list on issuance so it can be used for renewal - done using cron #revoked certificate names would be removed from existing list of issued certificates - done #cron jobs would be created for renew function - done #add auto update for lego tool - (also to cron) - done, not using cron making manual from menu #add install for webserver type either apache/nginx - pending #auto create default config file for created domains (man i really wish i can do this. lol) #Export to be based on user preference #Enviromental Variables for certificate paths, this is to make sure certificates are always issued in same path #if cert in used by multiple applications. can be placed in central path #Can be run without root - root only needed to install dependencies from apt/yum #should be folder that doesn't need root permission #Use case - namecheap (environment variable depends on dns provider) #check out https://go-acme.github.io/lego/dns/index.html for dns provider variables install_as_sudo() { if [ -z "$SUDO_PASS" ] && [ "$EUID" -ne 0 ]; then echo 'Sudo access needed to install dependencies' read -sp 'Enter Sudo Password:' SUDO_PASS printf '\n\n' fi get_os_type } set_env_variables() { #envs for lego export CERT_PATH=/etc/acme export CONTACT_MAIL=xxxxxxxxxxxxxxxxxxxxxxxx export DNS_PROVIDER=namecheap export NAMECHEAP_PROPAGATION_TIMEOUT=60 export NAMECHEAP_POLLING_INTERVAL=2 export NAMECHEAP_API_USER=xxxxxxxxxxxxxxxxxxxxxxxx export NAMECHEAP_API_KEY=xxxxxxxxxxxxxxxxxxxxxxxx #envs for path export LEGO_PATH=$CERT_PATH export GOPATH=$HOME/.go export GO_HOME=/usr/local/go export PATH=$PATH:$GO_HOME/bin:$GOPATH/bin } check_dependencies() { echo "Checking dependencies..." install_tar install_curl install_jq install_git install_go install_lego echo "Check compelete" if [ "$dependency_install" == "yes" ]; then echo "restart shell session" exit 0 fi } install_tar() { if ! command -v tar 2>&1 >/dev/null; then install_as_sudo echo 'tar module not installed' echo "now installing tar..." ###download and install curl eval "echo $SUDO_PASS | sudo -S $install_cmd install tar -y" echo "tar succcesfully installed" eval "tar --version" dependency_install=yes fi } install_curl() { if ! command -v curl 2>&1 >/dev/null; then install_as_sudo echo 'curl module not installed' echo "now installing curl..." ###download and install curl eval "echo $SUDO_PASS | sudo -S $install_cmd install curl -y" echo "curl succcesfully installed" eval "curl -V" dependency_install=yes fi } install_jq() { if ! command -v jq 2>&1 >/dev/null; then install_as_sudo echo 'jq module not installed' echo "now installing jq..." ###download and install curl eval "echo $SUDO_PASS | sudo -S $install_cmd install jq -y" echo "jq succcesfully installed" eval "jq -V" dependency_install=yes fi } install_git() { if ! command -v git 2>&1 >/dev/null; then install_as_sudo echo 'git module not installed' echo "now installing git..." ###download and install curl eval "echo $SUDO_PASS | sudo -S $install_cmd install git -y" echo "git succcesfully installed" eval "git -v" dependency_install=yes fi } install_go() { if ! command -v go 2>&1 >/dev/null; then install_as_sudo echo 'go module not installed' echo "now installing go..." ###download and install go get_system_information eval "echo $SUDO_PASS | sudo -S rm -rf $GO_HOME" command=$(curl -o /tmp/$file_name $url) eval "$command" command=$(echo $SUDO_PASS | sudo -S tar -xf /tmp/$file_name -C /usr/local) eval "$command" echo "go succcesfully installed" eval "go version" command=$(rm /tmp/$file_name) eval "$command" dependency_install=yes fi } install_lego() { if ! command -v lego 2>&1 >/dev/null; then echo 'lego could not be found' echo 'now installing lego...' export GO111MODULE=on if [ ! -d $CERT_PATH ]; then sudo mkdir -p $CERT_PATH sudo chown $USER:$USER -R $CERT_PATH fi eval "go install github.com/go-acme/lego/v4/cmd/lego@latest" #add crontab for auto renewal of certificates (occurence is at monday,thursdays - can be changed) eval "(crontab -l 2>/dev/null || true; echo '0 0 * * 1,4 $0 autorenew') | sort -u |crontab - " printf "\n" echo "lego succcesfully installed" eval "lego -version" dependency_install=yes fi } install_web_server() { install_as_sudo echo "Install WebServer" PS3="Select Option to enter option or and key to exit: " options=("nginx" "apache" "haproxy") select option in "${options[@]}"; do case $option in "nginx") eval "echo $SUDO_PASS | sudo -S $install_cmd install nginx* -y" printf "\n\n\n" echo "run below command as admin on rhel type OS to allow network connections" echo "setsebool httpd_can_network_connect 1" exit 0 ;; "apache") eval "echo $SUDO_PASS | sudo -S $install_cmd install apach2e* -y" printf "\n\n\n" echo "run below command as admin on rhel type OS to allow network connections" echo "setsebool httpd_can_network_connect 1" exit 0 ;; "haproxy") eval "echo $SUDO_PASS | sudo -S $install_cmd install haproxy* -y" printf "\n\n\n" echo "run below command as admin on rhel type OS to allow network connections" echo "setsebool httpd_can_network_connect 1" exit 0 ;; esac done } update_lego() { export GO111MODULE=on eval "go install github.com/go-acme/lego/v4/cmd/lego@latest" } get_system_information() { ##go1.24.3.linux-amd64.tar.gz ##https://dl.google.com/go/go1.24.3.linux-amd64.tar.gz ###As at writing script - go version is 1.24.3 (could find api to get current version) version="1.24.5" #Get System Information (Adapted to Debian - This would need changes for other OS's) sys=$(uname -s) system=$(echo $sys | tr '[:upper:]' '[:lower:]') #Form URL Based on system information file_name="go$version.$system-amd64.tar.gz" url="https://dl.google.com/go/$file_name" } get_os_type() { #get OSTYPE - modify to know defualt package name to use for installation os_type=$(awk -F'=' '/ID_LIKE/ {print $2}' /etc/os-release | awk -F'"' '{print $2}') if [[ $os_type == *"debian"* ]]; then install_cmd="apt" elif [[ $os_type == *"ubuntu"* ]]; then install_cmd="apt" elif [[ $os_type == *"almalinux"* ]]; then install_cmd="yum" elif [[ $os_type == *"redhat"* ]]; then install_cmd="yum" elif [[ $os_type == *"centos"* ]]; then install_cmd="yum" fi } run() { read -p 'enter domain name(s) seperate with ,: ' -a domains for domain in "${domains[@]}"; do command+="-d $domain " done eval " $command run" exit 0 } revoke() { read -p 'enter domain name(s) seperate with ,: ' -a domains for domain in "${domains[@]}"; do command+="-d $domain " done eval " $command revoke" exit 0 } renew() { read -p 'enter domain name(s) seperate with ,: ' -a domains for domain in "${domains[@]}"; do command+="-d $domain " done eval " $command renew" exit 0 } list() { eval " $command list" exit 0 } autorenew() { ###to be used to store output from crontab renewals LOG_FILE="$CERT_PATH/log" if [ ! -d $LOG_FILE ]; then mkdir -p $LOG_FILE fi for files in $(find $LEGO_PATH/certificates/*.json -type f); do IFS=$'\n' for file in $files; do temp_domain=$(cat $file | jq .domain | sed -e 's/^"//' -e 's/"$//') renew_command="$command -d $temp_domain renew" eval $renew_command done done exit 0 } functionlist() { echo "Usage: {run, renew, revoke, list, update lego}" PS3="Select Option to enter option or and key to exit: " options=("run" "revoke" "renew" "list" "update lego" "install web server") select option in "${options[@]}"; do case $option in "run") run ;; "revoke") revoke ;; "renew") renew ;; "list") list ;; "update lego") update_lego exit 0 ;; "install web server") install_web_server exit 0 ;; *) exit 0 ;; esac done } functionvar() { case $1 in "run") run ;; "revoke") revoke ;; "renew") renew ;; "list") list ;; "autorenew") autorenew ;; esac } set_env_variables check_dependencies cd $CERT_PATH echo "Acme Script for $DNS_PROVIDER" ## If no parameters are given, print which are avaiable. echo "Usage: only dns challenge function available" command="lego --email $CONTACT_MAIL --dns $DNS_PROVIDER " IFS="," if [ -z "$1" ]; then functionlist exit 0 else functionvar $1 exit 0 fi