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 |