Last active
November 5, 2024 01:02
-
-
Save catchdave/ff9c7d7a396a3201cfb14f912d3e5cda to your computer and use it in GitHub Desktop.
Find all .PEM certificates on Synology
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # | |
| # Finds all .pem certs on synology under /usr. | |
| # | |
| # Usage: ./find_all_certs.sh [--valid-only | --invalid-only] | |
| # --valid-only - Only show valid certificates found | |
| # --invalid-only - Only show invalid certificates found | |
| if [ "$EUID" -ne 0 ]; then | |
| echo "This script must be run as root or with sudo." | |
| exit 1 | |
| fi | |
| # Color codes | |
| GREEN="\033[1;32m" | |
| RED="\033[0;31m" | |
| YELLOW="\033[0;33m" | |
| BLUE="\033[0;95m" | |
| NC="\033[0m" # No Color | |
| BOLD="\033[1m" | |
| HEAD_COL="\033[1;97m\033[1;100m" | |
| # Initialize variables | |
| NOW_TS=$(date +%s) | |
| BASE_DIR=/usr/ | |
| prev_dir="" | |
| valid_count=0 | |
| count=0 | |
| total_count=0 | |
| total_valid=0 | |
| total_invalid=0 | |
| total_dirs_no_valid=0 | |
| total_dirs=0 | |
| valid_status= | |
| mode=all | |
| parse_args() { | |
| while [[ $# -gt 0 ]]; do | |
| case "$1" in | |
| --valid-only) | |
| mode=valid_only | |
| shift | |
| ;; | |
| --invalid-only) | |
| mode=invalid_only | |
| shift | |
| ;; | |
| *) | |
| echo "Usage: $0 [--valid-only | --invalid-only]" | |
| exit 1 | |
| ;; | |
| esac | |
| done | |
| } | |
| main() { | |
| parse_args "$@" | |
| print_header | |
| while read -r cert; do | |
| cert_dir=$(dirname "$cert") | |
| cert_file=$(basename "$cert") | |
| check_valid_cert "$cert" || continue | |
| # Print the directory heading if it's new | |
| if [[ "$cert_dir" != "$prev_dir" ]]; then | |
| process_dir_change | |
| fi | |
| ((count++)) | |
| ((total_count++)) | |
| parse_cert_info "$cert" # Sets the vars: $from, $to, $subject, $issuer, $validity_color & $valid_status | |
| check_filter "$valid_status" || continue | |
| print_cert_line "$validity_color" "$cert_file" "$from" "$to" "$subject" "$issuer" | |
| done < <(find "$BASE_DIR" -type f -name "*.pem" -not -path "/volume*" 2>/dev/null) | |
| print_dir_warn "$cert_dir" | |
| print_summary | |
| } | |
| # Skip files that are not valid certificates | |
| check_valid_cert() { | |
| local cert=$1 | |
| if [[ ! "$(head -n 1 "$cert")" == "-----BEGIN CERTIFICATE-----" ]]; then | |
| return 0 | |
| fi | |
| return 1 | |
| } | |
| # Execute filtering based on mode | |
| check_filter() { | |
| local valid_status=$1 | |
| if [[ "$mode" == "valid_only" && "$valid_status" == "invalid" ]]; then | |
| return 1 | |
| elif [[ "$mode" == "invalid_only" && "$valid_status" == "valid" ]]; then | |
| return 1 | |
| fi | |
| return 0 | |
| } | |
| print_cert_line() { | |
| local color=$1 | |
| LINE_FORMAT="| %-44s | COLOR%-28s${NC} | COLOR%-28s${NC} | %-20s | %-30s |\n" | |
| cur_format="${LINE_FORMAT//COLOR/${color}}" | |
| printf "$cur_format" "$2" "$3" "$4" "$5" "$6" | |
| } | |
| print_dir_warn() { | |
| if [[ "$count" == "0" ]]; then | |
| return | |
| fi | |
| if [[ "$valid_count" == "0" ]]; then | |
| echo -e "${RED}${BOLD}[WARN] No Valid Certs in: ${NC}${RED}$1/${NC}" | |
| ((total_dirs_no_valid++)) | |
| fi | |
| } | |
| print_header() { | |
| LINE_FORMAT="${HEAD_COL}| %-44s | %-28s | %-28s | %-20s | %-30s |${NC}\n" | |
| printf "$LINE_FORMAT" "Filename" "Valid From" "Valid To" "Domain" "Issuer" | |
| } | |
| process_dir_change() { | |
| print_dir_warn "$prev_dir" | |
| ((total_dirs++)) | |
| valid_count=0 | |
| count=0 | |
| prev_dir="$cert_dir" | |
| printf "| ${BLUE}%-163s${NC} |\n" "$cert_dir" | |
| } | |
| print_summary() { | |
| local LINE_FORMAT="${HEAD_COL}%-28s${NC} | ${BOLD}%-10s${NC}\n" | |
| echo "" | |
| echo -e "${BOLD}=== Summary ===${NC}" | |
| printf "$LINE_FORMAT" "Total Directories" "$total_dirs" | |
| printf "$LINE_FORMAT" "Total Certificates" "$total_count" | |
| printf "$LINE_FORMAT" "Total Dirs w/ no valid cert" "$total_dirs_no_valid" | |
| printf "$LINE_FORMAT" "Total Valid Certs" "$total_valid" | |
| printf "$LINE_FORMAT" "Total InValid Certs" "$total_invalid" | |
| } | |
| parse_cert_info() { | |
| local cert="$1" | |
| # Parse details from cert_info | |
| local cert_info=$(openssl x509 -in "$cert" -noout -subject -issuer -startdate -enddate 2>/dev/null) | |
| subject=$(echo "$cert_info" | sed -n '/^subject=/s/.*[Cc][Nn][ ]*=[ ]*\([^,]*\).*/\1/p') | |
| issuer=$(echo "$cert_info" | sed -n '/^issuer=/s/.*[Oo][ ]*=[ ]*\([^,]*\).*/\1/p') | |
| from=$(echo "$cert_info" | sed -n 's/^notBefore=//p') | |
| to=$(echo "$cert_info" | sed -n 's/^notAfter=//p') | |
| # Convert dates to Unix timestamps for comparison | |
| local from_ts=$(date -d "$from" +%s) | |
| local to_ts=$(date -d "$to" +%s) | |
| # Determine validity of certs | |
| valid_status="invalid" | |
| if (( from_ts > NOW_TS )); then | |
| validity_color=$YELLOW # Not reached | |
| ((total_invalid++)) | |
| elif (( to_ts < NOW_TS )); then | |
| validity_color=$RED # Expired | |
| ((total_invalid++)) | |
| else | |
| validity_color=$GREEN # Current | |
| valid_status="valid" | |
| ((valid_count++)) | |
| ((total_valid++)) | |
| fi | |
| } | |
| ### Run main program ### | |
| main "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment