diff --git a/lego_wrapper.sh b/lego_wrapper.sh new file mode 100644 index 0000000..9438f79 --- /dev/null +++ b/lego_wrapper.sh @@ -0,0 +1,260 @@ +#!/bin/bash + +#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 + +#should be folder that doesn't have root permission +export CERT_PATH=/etc/nginx/ssl +export CONTACT_MAIL=xxxxxxxxxxxxxxxxxxxxxxxx + +#Use case - namecheap (environment variable depends on dns provider) +#check out https://go-acme.github.io/lego/dns/index.html for dns provider variables +export DNS_PROVIDER=namecheap +export NAMECHEAP_PROPAGATION_TIMEOUT=60 +export NAMECHEAP_POLLING_INTERVAL=2 +export NAMECHEAP_API_USER=xxxxxxxxxxxxxxxxxxxxxxxx +export NAMECHEAP_API_KEY=xxxxxxxxxxxxxxxxxxxxxxxx + +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 + env_file=~/.profile +} + +check_dependencies() { + + echo "Checking dependencies..." + check_install_curl + check_install_jq + check_install_go + check_install_lego + echo "Check compelete" + if [ "$dependency_install" == "yes" ]; then + echo "restart shell session" + exit 1 + fi + +} + +check_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 "sudo apt install curl -y" + echo "curl succcesfully installed" + eval "curl -V" + dependency_install=yes + fi +} + +check_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 "sudo apt install jq -y" + echo "jq succcesfully installed" + eval "jq -V" + dependency_install=yes + fi +} + +check_install_go() { + if ! command -v go 2>&1 >/dev/null; then + install_as_sudo + echo 'go module not installed' + + echo "now installing go..." + echo "export GOPATH=$""HOME/go" >>$env_file + echo "export GO_HOME=/usr/local/go" >>$env_file + echo "export PATH=$""PATH:$""GO_HOME/bin:$""GOPATH/bin" >>$env_file + eval "source $env_file" + + ###download and install go + get_system_information + eval "sudo rm -rf $GO_HOME" + command=$(curl $url | sudo tar -xz -C /usr/local) + eval "$command" + + echo "go succcesfully installed" + eval "source $env_file" + eval "go version" + dependency_install=yes + fi +} + +check_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 + + echo "export LEGO_PATH=$CERT_PATH/lego" >>$env_file + eval "source $env_file" + 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 +} + +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.3" + + #Get System Information (Adapted to Debian - This would need changes for other OS's) + sys=$(uname -s) + system=$(echo $sys | tr '[:upper:]' '[:lower:]') + archictecture=$(dpkg --print-architecture) + + #Form URL Based on system information + url="https://dl.google.com/go/go$version.$system-$archictecture.tar.gz" + printf "\n" + echo $url + printf "\n" + +} + +run() { + read -p 'enter domain name(s) seperate with ,: ' -a domains + for domain in "${domains[@]}"; do + command+="-d $domain " + done + eval " $command run" + exit 1 +} + +revoke() { + + read -p 'enter domain name(s) seperate with ,: ' -a domains + for domain in "${domains[@]}"; do + command+="-d $domain " + done + eval " $command revoke" + exit 1 +} + +renew() { + + read -p 'enter domain name(s) seperate with ,: ' -a domains + for domain in "${domains[@]}"; do + command+="-d $domain " + done + eval " $command renew" + exit 1 +} + +list() { + eval " $command list" + exit 1 +} + +autorenew() { + + 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 1 + +} + +functionlist() { + echo "Usage: {run, renew, revoke, list}" + PS3="Select Option to enter option or and key to exit: " + options=("run" "revoke" "renew" "list") + select option in "${options[@]}"; do + case $option in + "run") + run + ;; + "revoke") + revoke + ;; + "renew") + renew + ;; + "list") + list + ;; + *) + exit 1 + ;; + esac + done +} + +functionvar() { + + case $1 in + "run") + run + ;; + "revoke") + revoke + ;; + "renew") + renew + ;; + "list") + list + ;; + "autorenew") + autorenew + ;; + esac +} + +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="," +###TODO### +#available functions - can be used as a function list or a direct execute by passing action +#would write domains into file/list on issuance so it can be used for renewal +#revoked certificate names would be removed from existing list of issued certificates +#cron jobs would be created for renew function +if [ -z "$1" ]; then + functionlist + exit 1 +else + functionvar $1 + exit 1 +fi