Simplifying Unifi SSL/TLS Certificate Management for Enhanced Security
In today’s digital landscape, where cybersecurity is paramount, managing SSL/TLS certificates for network devices like the Unifi Dream Router has become critical. These certificates not only encrypt the Unifi user interface but also secure the Wi-Fi guest access page, ensuring a safe browsing experience for users.
Understanding the Importance of SSL/TLS Certificates
SSL/TLS certificates play a vital role in securing network communications by encrypting data exchanged between devices and servers. For Unifi devices, these certificates are instrumental in safeguarding sensitive information accessed through the user interface and ensuring the integrity of the Wi-Fi guest access portal.
Introducing the Unifi Device SSLer Script
The Unifi Device SSLer script, version 0.96c (BETA), offers a robust solution for managing SSL/TLS certificates on Unifi devices. This innovative tool, meticulously crafted by Justin @ FalconTechnix, aka REAvER @ DOWNFALL.us, simplifies the often complex process of certificate management, making it accessible to users of all skill levels.
Streamlining Certificate Management
With the Unifi Device SSLer script, users can effortlessly obtain and renew SSL/TLS certificates for their Unifi devices. The script automates the retrieval process using Certbot, a widely recognized certificate management tool, ensuring seamless integration with Let’s Encrypt, a free, automated, and open certificate authority.
Enhanced Security Features
One of the standout features of the Unifi Device SSLer script is its ability to verify certificate validity, providing users with peace of mind regarding their network’s security. By displaying essential certificate information and conducting thorough verification checks, the script ensures that only valid and trusted certificates are utilized, mitigating potential security risks.
Future Developments and Automation
As the Unifi Device SSLer script evolves, users can expect additional features and enhanced automation capabilities. Future updates will focus on further streamlining the certificate management process, reducing manual intervention, and improving overall usability. Stay tuned for updates and enhancements designed to make SSL/TLS certificate management even more seamless and user-friendly.
Sleepless “Knight”
This morning, fueled by a bout of insomnia, I delved deep into the Unifi SSL/TLS certificate management project, dedicating a solid six hours to making significant progress. Despite the sleepless night, I found myself immersed in the task, fueled by a relentless determination to overcome any challenges that came my way. Harnessing the quiet solitude of the early morning hours, I navigated through intricate lines of code, fine-tuning and optimizing the Unifi Device SSLer script to enhance its functionality and user experience. With each passing hour, I made substantial headway, moving closer to my goal of simplifying SSL/TLS certificate management for Unifi devices. Eventually, this endeavor led to the birth of what I’ve dubbed SSLer—a tool poised to revolutionize the management of SSL/TLS certificates across the Unifi ecosystem.
Conclusion
In an era where cybersecurity is paramount, managing SSL/TLS certificates for Unifi devices is essential for safeguarding sensitive information and maintaining a secure network environment. The Unifi Device SSLer script offers a comprehensive solution for certificate management, simplifying the process and enhancing security effortlessly. With its intuitive interface and robust features, the script empowers users to take control of their network’s security with confidence.
For further information on Unifi SSL/TLS certificate management and best practices, consider exploring resources from reputable sources like Let’s Encrypt and the Unifi community forums.
Remember, a secure network starts with effective certificate management. Stay protected, stay secure with the Unifi Device SSLer script.
Keywords: Unifi SSL/TLS certificate management, Unifi Device SSLer script, SSL/TLS certificate automation, network security, Let’s Encrypt, Wi-Fi guest access security
The Unifi Device SSLer script can be found below.
#!/bin/bash SCRIPT_VERSION='0.96c' clear MOTD="BY Justin @ FalconTechnix AKA REAvER @ DOWNFALL.us" # Colors for formatting output RED='\033[1;31m' GREEN='\033[1;32m' YELLOW='\033[1;33m' BLUE='\033[1;34m' PURPLE='\033[1;35m' CYAN='\033[1;36m' NC='\033[0m' # No Color # Function to generate a random color code random_color() { colors=($RED $GREEN $YELLOW $BLUE $PURPLE $CYAN) index=$((RANDOM % ${#colors[@]})) echo "${colors[$index]}" } # Rainbow colored ASCII art echo -e "${RED}███████╗ █████╗ ██╗ ██████╗ ██████╗ ███╗ ██╗${NC}" echo -e "${ORANGE}██╔════╝██╔══██╗██║ ██╔════╝██╔═══██╗████╗ ██║${NC}" echo -e "${YELLOW}█████╗ ███████║██║ ██║ ██║ ██║██╔██╗ ██║${NC}" echo -e "${GREEN}██╔══╝ ██╔══██║██║ ██║ ██║ ██║██║╚██╗██║${NC}" echo -e "${BLUE}██║ ██║ ██║███████╗╚██████╗╚██████╔╝██║ ╚████║${NC}" echo -e "${PURPLE}╚═╝ ╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═══╝${NC}" echo -e "${CYAN}████████╗███████╗ ██████╗██╗ ██╗███╗ ██╗██╗██╗ ██╗${NC}" echo -e "${RED}╚══██╔══╝██╔════╝██╔════╝██║ ██║████╗ ██║██║╚██╗██╔╝${NC}" echo -e "${ORANGE} ██║ █████╗ ██║ ███████║██╔██╗ ██║██║ ╚███╔╝${NC}" echo -e "${YELLOW} ██║ ██╔══╝ ██║ ██╔══██║██║╚██╗██║██║ ██╔██╗${NC}" echo -e "${GREEN} ██║ ███████╗╚██████╗██║ ██║██║ ╚████║██║██╔╝ ██╗${NC}" echo -e "${BLUE} ╚═╝ ╚══════╝ ╚═════╝╚═╝ ╚═╝╚═╝ ╚═══╝╚═╝╚═╝ ╚═╝${NC}" echo -e "${RED}Unifi Device SSLer${GREEN} Version${ORANGE}${PURPLE} ${SCRIPT_VERSION}${CYAN}(BETA)${NC}" # Iterate over each character in the MOTD, colorize and display it for ((i = 0; i < ${#MOTD}; i++)); do color=$(random_color) echo -ne "${color}${MOTD:$i:1}${NC}" done echo "" echo "" # Get the directory of the script SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" # Unifi Core path UNIFI_CORE_PATH="/data/unifi-core/config/" # Unifi Core cert name UNIFI_CORE_CERT="unifi-core.crt" UNIFI_CORE_KEY="unifi-core.key" # Unifi Core certificate and key paths UNIFI_CORE_CERT_PATH="${UNIFI_CORE_PATH}/${UNIFI_CORE_CERT}" UNIFI_CORE_KEY_PATH="${UNIFI_CORE_PATH}/${UNIFI_CORE_KEY}" # File to store execution information EXECUTION_LOG_FILE="$SCRIPT_DIR/SSLer_execution.log" # First run file to store domain and email FIRST_RUN_FILE="$SCRIPT_DIR/SSLer_first_run.txt" # Function to display valid dates of the certificate in the Unifi Core directory display_core_cert_info() { echo -e "${GREEN}------------------------------------${NC}" echo -e "${YELLOW}Certificate Information (Unifi Core):${NC}" echo -e "${GREEN}------------------------------------${NC}" if [ -f "$UNIFI_CORE_CERT_PATH" ]; then echo -e "${YELLOW}[ Data Read Date ]: ${GREEN} $(date) ${NC}" echo -e "${PURPLE}FQDN entered by user:${CYAN} $domain${NC}" echo -e "${YELLOW}Common Name (CN) in certificate:${NC}" cert_cn=$(openssl x509 -in $UNIFI_CORE_CERT_PATH -noout -subject | awk -F '=' '{print $NF}' | sed 's/ //g') echo -e "${CYAN}$cert_cn${NC}" echo -e "${YELLOW}Fingerprint:${NC}" echo -e "${PURPLE}$(openssl x509 -in $UNIFI_CORE_CERT_PATH -noout -fingerprint | sed 's/SHA1 Fingerprint=//g')${NC}" echo -e "${YELLOW}------------------------------------${NC}" echo -e "${YELLOW}[ Not Before ]:${NC}" not_before=$(openssl x509 -in $UNIFI_CORE_CERT_PATH -noout -startdate | sed 's/notBefore=//g') echo "$not_before" echo -e "${YELLOW}[ Not After ]:${NC}" not_after=$(openssl x509 -in $UNIFI_CORE_CERT_PATH -noout -enddate | sed 's/notAfter=//g') echo "$not_after" echo -e "${YELLOW}[ Issued to ]:${NC}" openssl x509 -in $UNIFI_CORE_CERT_PATH -noout -subject | sed 's/subject=//g' echo -e "${YELLOW}[ Issued by ]:${NC}" openssl x509 -in $UNIFI_CORE_CERT_PATH -noout -issuer | sed 's/issuer=//g' echo -e "${YELLOW}------------------------------------${NC}" # Check if the extracted CN exactly matches the entered domain if [[ "$cert_cn" == "unifi.local" ]]; then printf "\n\n\n" printf "${RED}THIS IS A SNAKE OIL CERTIFICATE. YOU ARE EITHER RUNNING THIS TOOL FOR THE FIRST TIME OR DELIBERATELY USING AN INSECURE CERTIFICATE. REGARDLESS, PLEASE CONFIRM WHETHER EITHER OF THESE SCENARIOS IS TRUE.${NC}\n\n" printf "${CYAN}TYPE 'YES' IN ALL CAPS TO CONTINUE:${NC} " read -r confirmation if [[ "$confirmation" == "YES" ]]; then printf "${GREEN}Continuing as per user confirmation.${NC}\n" else printf "${RED}Verification: Certificate is a snakeoil certificate.${NC}\n" exit 1 fi fi # Compare certificate expiration date with current date current_date=$(date +%s) not_after_date=$(date -d "$not_after" +%s) if [[ "$current_date" -gt "$not_after_date" ]]; then echo -e "${RED}Verification: Certificate has expired.${NC}" else echo -e "${GREEN}Verification: Certificate is valid until $not_after.${NC}" fi else echo -e "${RED}Error: Unifi Core certificate not found at $UNIFI_CORE_CERT_PATH.${NC}" echo -e "${RED}Verification failed: Unifi Core certificate not found.${NC}" exit 1 fi } # Function to display valid dates of the downloaded Let's Encrypt certificate display_letsencrypt_cert_info() { echo -e "${GREEN}------------------------------------${NC}" echo -e "${YELLOW}Certificate Information (Let's Encrypt):${NC}" echo -e "${GREEN}------------------------------------${NC}" if [ -f /etc/letsencrypt/live/$domain/cert.pem ]; then echo -e "${YELLOW}[ Data Read Date ]: ${GREEN} $(date) ${NC}" echo -e "${PURPLE}FQDN entered by user:${CYAN} $domain${NC}" echo -e "${YELLOW}Common Name (CN) in certificate:${NC}" cert_cn=$(openssl x509 -in /etc/letsencrypt/live/$domain/cert.pem -noout -subject | awk -F '=' '{print $NF}' | sed 's/ //g') echo -e "${CYAN}$cert_cn${NC}" echo -e "${YELLOW}Fingerprint:${NC}" echo -e "${PURPLE}$(openssl x509 -in /etc/letsencrypt/live/$domain/cert.pem -noout -fingerprint | sed 's/SHA1 Fingerprint=//g')${NC}" echo -e "${YELLOW}------------------------------------${NC}" echo -e "${YELLOW}[ Not Before ]:${NC}" not_before=$(openssl x509 -in /etc/letsencrypt/live/$domain/cert.pem -noout -startdate | sed 's/notBefore=//g') echo "$not_before" echo -e "${YELLOW}[ Not After ]:${NC}" not_after=$(openssl x509 -in /etc/letsencrypt/live/$domain/cert.pem -noout -enddate | sed 's/notAfter=//g') echo "$not_after" echo -e "${YELLOW}[ Issued to ]:${NC}" openssl x509 -in /etc/letsencrypt/live/$domain/cert.pem -noout -subject | sed 's/subject=//g' echo -e "${YELLOW}[ Issued by ]:${NC}" openssl x509 -in /etc/letsencrypt/live/$domain/cert.pem -noout -issuer | sed 's/issuer=//g' echo -e "${YELLOW}------------------------------------${NC}" # Check if the extracted CN exactly matches the entered domain if [[ "$cert_cn" == "$domain" ]]; then echo -e "${GREEN}Verification: CN matches the entered FQDN.${NC}" else echo -e "${RED}Verification: Issued to does not match the entered FQDN.${NC}" exit 1 fi # Compare certificate expiration date with current date current_date=$(date +%s) not_after_date=$(date -d "$not_after" +%s) if [[ "$current_date" -gt "$not_after_date" ]]; then echo -e "${RED}Verification: Certificate has expired.${NC}" else echo -e "${GREEN}Verification: Certificate is valid until $not_after.${NC}" fi else echo -e "${RED}Verification failed: Let's Encrypt certificate not found.${NC}" exit 1 fi } # Function to prompt user for domain and email dn_and_email() { local correct=false while [[ $correct == false ]]; do read -p "Enter the FQDN desired: " domain read -p "Enter the email address for Let's Encrypt certificate: " user_email read -p "Enter the FQDN again: " domain_confirm read -p "Enter the email address again: " email_confirm if [[ "$domain" != "$domain_confirm" ]] || [[ "$user_email" != "$email_confirm" ]]; then for (( i=0; i<5; i++ )); do echo -e "\033[5m${RED}DOMAIN OR EMAIL VERIFICATION FAILED. ENTRIES DO NOT MATCH. PLEASE TRY AGAIN.${NC}" sleep 0.5 echo -e "\033[0m" sleep 0.5 done else correct=true echo "$domain:$user_email" > "$FIRST_RUN_FILE" fi done } # Check if it's the first run and prompt the user for the domain name and email if so if [[ ! -f "$FIRST_RUN_FILE" ]]; then echo -e "${YELLOW}This appears to be the first run.${NC}" dn_and_email else domain=$(cut -d':' -f1 "$FIRST_RUN_FILE") user_email=$(cut -d':' -f2 "$FIRST_RUN_FILE") fi # Ensure certbot is installed if ! command -v certbot &>/dev/null; then echo "Certbot is not installed. Installing..." sudo apt-get update sudo apt-get install certbot -y fi # Display certificate information and log it display_core_cert_info | tee -a "$EXECUTION_LOG_FILE" # Stop the Unifi service sudo systemctl stop unifi # Obtain the certificate using Certbot sudo certbot certonly --manual --preferred-challenges dns -d $domain --agree-tos --email $user_email # Display downloaded certificate information and log it display_letsencrypt_cert_info | tee -a "$EXECUTION_LOG_FILE" # Ask the user if they want to replace the current certificates with the newly downloaded ones read -p "Do you want to replace the existing certificates with the newly downloaded ones? (yes/no):" replace_certs if [ "$replace_certs" == "yes" ]; then echo -e "${GREEN}User has chosen to replace the existing certificates with the newly downloaded ones.${NC}" # Backup the existing certificate and key files echo -e "${YELLOW}Creating a backup of the existing certificate and key files...${NC}" current_date=$(date +"%Y%m%d%H%M%S") sudo cp "$UNIFI_CORE_CERT_PATH" "$UNIFI_CORE_PATH/unifi-core_${current_date}.crt.old" sudo cp "$UNIFI_CORE_KEY_PATH" "$UNIFI_CORE_PATH/unifi-core_${current_date}.key.old" # Verify that backup files are created if [ -f "$UNIFI_CORE_PATH/unifi-core_${current_date}.crt.old" ] && [ -f "$UNIFI_CORE_PATH/unifi-core_${current_date}.key.old" ]; then echo -e "${GREEN}Backup of existing certificate and key files created successfully.${NC}" echo -e "${YELLOW}Backup files created:${NC}" echo -e "${YELLOW} - ${UNIFI_CORE_PATH}/unifi-core_${current_date}.crt.old${NC}" echo -e "${YELLOW} - ${UNIFI_CORE_PATH}/unifi-core_${current_date}.key.old${NC}" else echo -e "${RED}Error: Failed to create a backup of existing certificate and key files.${NC}" exit 1 fi # Replace the existing certificates with the newly downloaded ones echo -e "${YELLOW}Replacing the existing certificates with the newly downloaded ones...${NC}" sudo cp "/etc/letsencrypt/live/$domain/fullchain.pem" "$UNIFI_CORE_PATH/unifi-core.crt" sudo cp "/etc/letsencrypt/live/$domain/privkey.pem" "$UNIFI_CORE_PATH/unifi-core.key" # Verify that certificates are replaced if [ -f "$UNIFI_CORE_PATH/unifi-core.crt" ] && [ -f "$UNIFI_CORE_PATH/unifi-core.key" ]; then echo -e "${GREEN}Certificates have been successfully replaced.${NC}" else echo -e "${RED}Error: Failed to replace the existing certificates with the newly downloaded ones.${NC}" exit 1 fi fi # Restart the Unifi service to apply the changes echo "Restarting the Unifi service to apply the changes..." sudo systemctl start unifi echo "Unifi service has been restarted." echo -e "${GREEN}------------------------------------${NC}" echo -e "${YELLOW}Operation Completed Successfully:${NC}" echo -e "${GREEN}------------------------------------${NC}" echo -e "${CYAN}Your certificates have been successfully renewed and/or updated.${NC}" echo -e "${CYAN}Thank you for using Unifi Device SSLer!${NC}" # Iterate over each character in the MOTD, colorize and display it for ((i = 0; i < ${#MOTD}; i++)); do color=$(random_color) echo -ne "${color}${MOTD:$i:1}${NC}" done echo "" # Add this line to ensure the loop is properly closed echo ""