152 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			YAML
		
	
	
	
			
		
		
	
	
			152 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			YAML
		
	
	
	
| ---
 | |
| - name: SSL Certificate Management and Monitoring
 | |
|   hosts: all
 | |
|   gather_facts: yes
 | |
|   
 | |
|   vars:
 | |
|     # 常见证书路径
 | |
|     cert_paths:
 | |
|       - /etc/ssl/certs
 | |
|       - /etc/letsencrypt/live
 | |
|       - /etc/nginx/ssl
 | |
|       - /etc/apache2/ssl
 | |
|       - /usr/local/share/ca-certificates
 | |
|     
 | |
|     # 需要检查的服务端口
 | |
|     ssl_services:
 | |
|       - { name: "HTTPS", port: 443 }
 | |
|       - { name: "SMTPS", port: 465 }
 | |
|       - { name: "IMAPS", port: 993 }
 | |
|       - { name: "LDAPS", port: 636 }
 | |
|   
 | |
|   tasks:
 | |
|     # 检查证书目录
 | |
|     - name: Check certificate directories
 | |
|       stat:
 | |
|         path: "{{ item }}"
 | |
|       register: cert_dirs
 | |
|       loop: "{{ cert_paths }}"
 | |
|       
 | |
|     - name: List existing certificate directories
 | |
|       debug:
 | |
|         msg: "📁 Certificate directory {{ item.item }}: {{ 'EXISTS' if item.stat.exists else 'NOT FOUND' }}"
 | |
|       loop: "{{ cert_dirs.results }}"
 | |
|       
 | |
|     # 查找证书文件
 | |
|     - name: Find certificate files
 | |
|       find:
 | |
|         paths: "{{ cert_paths }}"
 | |
|         patterns: "*.crt,*.pem,*.cert"
 | |
|         recurse: yes
 | |
|       register: cert_files
 | |
|       
 | |
|     - name: Display found certificates
 | |
|       debug:
 | |
|         msg: "🔐 Found {{ cert_files.files | length }} certificate files"
 | |
|         
 | |
|     # 检查证书过期时间
 | |
|     - name: Check certificate expiration
 | |
|       shell: |
 | |
|         if [ -f "{{ item.path }}" ]; then
 | |
|           openssl x509 -in "{{ item.path }}" -noout -enddate 2>/dev/null | cut -d= -f2
 | |
|         fi        
 | |
|       register: cert_expiry
 | |
|       loop: "{{ cert_files.files[:10] }}"  # 限制检查前10个证书
 | |
|       failed_when: false
 | |
|       
 | |
|     - name: Display certificate expiration dates
 | |
|       debug:
 | |
|         msg: "📅 {{ item.item.path | basename }}: expires {{ item.stdout if item.stdout else 'INVALID/UNREADABLE' }}"
 | |
|       loop: "{{ cert_expiry.results }}"
 | |
|       when: item.stdout != ""
 | |
|       
 | |
|     # 检查即将过期的证书 (30天内)
 | |
|     - name: Check certificates expiring soon
 | |
|       shell: |
 | |
|         if [ -f "{{ item.path }}" ]; then
 | |
|           exp_date=$(openssl x509 -in "{{ item.path }}" -noout -enddate 2>/dev/null | cut -d= -f2)
 | |
|           if [ ! -z "$exp_date" ]; then
 | |
|             exp_epoch=$(date -d "$exp_date" +%s 2>/dev/null)
 | |
|             now_epoch=$(date +%s)
 | |
|             days_left=$(( (exp_epoch - now_epoch) / 86400 ))
 | |
|             if [ $days_left -lt 30 ]; then
 | |
|               echo "WARNING: $days_left days left"
 | |
|             else
 | |
|               echo "OK: $days_left days left"
 | |
|             fi
 | |
|           fi
 | |
|         fi        
 | |
|       register: cert_warnings
 | |
|       loop: "{{ cert_files.files[:10] }}"
 | |
|       failed_when: false
 | |
|       
 | |
|     - name: Display certificate warnings
 | |
|       debug:
 | |
|         msg: "⚠️  {{ item.item.path | basename }}: {{ item.stdout }}"
 | |
|       loop: "{{ cert_warnings.results }}"
 | |
|       when: item.stdout != "" and "WARNING" in item.stdout
 | |
|       
 | |
|     # 检查 Let's Encrypt 证书
 | |
|     - name: Check Let's Encrypt certificates
 | |
|       shell: certbot certificates 2>/dev/null || echo "Certbot not installed"
 | |
|       register: letsencrypt_certs
 | |
|       failed_when: false
 | |
|       
 | |
|     - name: Display Let's Encrypt status
 | |
|       debug:
 | |
|         msg: "🔒 Let's Encrypt: {{ letsencrypt_certs.stdout_lines }}"
 | |
|       when: "'not installed' not in letsencrypt_certs.stdout"
 | |
|       
 | |
|     # 检查 SSL 服务端口
 | |
|     - name: Check SSL service ports
 | |
|       wait_for:
 | |
|         port: "{{ item.port }}"
 | |
|         timeout: 3
 | |
|       register: ssl_ports
 | |
|       loop: "{{ ssl_services }}"
 | |
|       failed_when: false
 | |
|       
 | |
|     - name: Display SSL service status
 | |
|       debug:
 | |
|         msg: "🔌 {{ item.item.name }} (port {{ item.item.port }}): {{ 'LISTENING' if not item.failed else 'NOT AVAILABLE' }}"
 | |
|       loop: "{{ ssl_ports.results }}"
 | |
|       
 | |
|     # 测试 HTTPS 连接
 | |
|     - name: Test HTTPS connection to localhost
 | |
|       uri:
 | |
|         url: "https://{{ ansible_default_ipv4.address }}"
 | |
|         method: GET
 | |
|         validate_certs: no
 | |
|         timeout: 5
 | |
|       register: https_test
 | |
|       failed_when: false
 | |
|       when: ssl_ports.results[0] is defined and not ssl_ports.results[0].failed
 | |
|       
 | |
|     - name: Display HTTPS test result
 | |
|       debug:
 | |
|         msg: "🌐 HTTPS Test: {{ 'SUCCESS' if https_test.status is defined else 'FAILED' }}"
 | |
|       when: https_test is defined
 | |
|       
 | |
|     # 检查证书链
 | |
|     - name: Check certificate chain for HTTPS
 | |
|       shell: |
 | |
|         echo | openssl s_client -connect {{ ansible_default_ipv4.address }}:443 -servername {{ ansible_hostname }} 2>/dev/null | openssl x509 -noout -subject -issuer        
 | |
|       register: cert_chain
 | |
|       failed_when: false
 | |
|       when: ssl_ports.results[0] is defined and not ssl_ports.results[0].failed
 | |
|       
 | |
|     - name: Display certificate chain info
 | |
|       debug:
 | |
|         msg: "🔗 Certificate Chain: {{ cert_chain.stdout_lines }}"
 | |
|       when: cert_chain is defined and cert_chain.rc == 0
 | |
|       
 | |
|     # 生成证书健康报告
 | |
|     - name: Generate certificate health summary
 | |
|       debug:
 | |
|         msg: |
 | |
|           🔐 Certificate Health Summary for {{ inventory_hostname }}:
 | |
|           📁 Certificate directories found: {{ (cert_dirs.results | selectattr('stat.exists') | list | length) }}
 | |
|           📄 Certificate files found: {{ cert_files.files | length }}
 | |
|           ⚠️  Certificates expiring soon: {{ (cert_warnings.results | selectattr('stdout', 'search', 'WARNING') | list | length) }}
 | |
|           🔒 Let's Encrypt: {{ 'Configured' if 'not installed' not in letsencrypt_certs.stdout else 'Not installed' }}
 | |
|           🌐 SSL Services: {{ (ssl_ports.results | rejectattr('failed') | list | length) }}/{{ ssl_services | length }} available           |