Sanitized mirror from private repository - 2026-04-19 08:18:25 UTC
This commit is contained in:
304
ansible/automation/playbooks/security_audit.yml
Normal file
304
ansible/automation/playbooks/security_audit.yml
Normal file
@@ -0,0 +1,304 @@
|
||||
---
|
||||
- name: Security Audit and Hardening
|
||||
hosts: all
|
||||
gather_facts: yes
|
||||
vars:
|
||||
audit_timestamp: "{{ ansible_date_time.iso8601 }}"
|
||||
security_report_dir: "/tmp/security_reports"
|
||||
|
||||
tasks:
|
||||
- name: Create security reports directory
|
||||
file:
|
||||
path: "{{ security_report_dir }}"
|
||||
state: directory
|
||||
mode: '0755'
|
||||
delegate_to: localhost
|
||||
run_once: true
|
||||
|
||||
- name: Check system updates
|
||||
shell: |
|
||||
if command -v apt >/dev/null 2>&1; then
|
||||
apt list --upgradable 2>/dev/null | wc -l
|
||||
elif command -v yum >/dev/null 2>&1; then
|
||||
yum check-update --quiet | wc -l
|
||||
else
|
||||
echo "0"
|
||||
fi
|
||||
register: pending_updates
|
||||
changed_when: false
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Check for security updates
|
||||
shell: |
|
||||
if command -v apt >/dev/null 2>&1; then
|
||||
apt list --upgradable 2>/dev/null | grep -i security | wc -l
|
||||
elif command -v yum >/dev/null 2>&1; then
|
||||
yum --security check-update --quiet 2>/dev/null | wc -l
|
||||
else
|
||||
echo "0"
|
||||
fi
|
||||
register: security_updates
|
||||
changed_when: false
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Check SSH configuration
|
||||
shell: |
|
||||
echo "=== SSH SECURITY AUDIT ==="
|
||||
if [ -f /etc/ssh/sshd_config ]; then
|
||||
echo "SSH Configuration:"
|
||||
echo "PermitRootLogin: $(grep -E '^PermitRootLogin' /etc/ssh/sshd_config | awk '{print $2}' || echo 'default')"
|
||||
echo "PasswordAuthentication: $(grep -E '^PasswordAuthentication' /etc/ssh/sshd_config | awk '{print $2}' || echo 'default')"
|
||||
echo "Port: $(grep -E '^Port' /etc/ssh/sshd_config | awk '{print $2}' || echo '22')"
|
||||
echo "Protocol: $(grep -E '^Protocol' /etc/ssh/sshd_config | awk '{print $2}' || echo 'default')"
|
||||
else
|
||||
echo "SSH config not accessible"
|
||||
fi
|
||||
register: ssh_audit
|
||||
changed_when: false
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Check firewall status
|
||||
shell: |
|
||||
echo "=== FIREWALL STATUS ==="
|
||||
if command -v ufw >/dev/null 2>&1; then
|
||||
echo "UFW Status:"
|
||||
ufw status verbose 2>/dev/null || echo "UFW not configured"
|
||||
elif command -v iptables >/dev/null 2>&1; then
|
||||
echo "IPTables Rules:"
|
||||
iptables -L -n | head -20 2>/dev/null || echo "IPTables not accessible"
|
||||
elif command -v firewall-cmd >/dev/null 2>&1; then
|
||||
echo "FirewallD Status:"
|
||||
firewall-cmd --state 2>/dev/null || echo "FirewallD not running"
|
||||
else
|
||||
echo "No firewall tools found"
|
||||
fi
|
||||
register: firewall_audit
|
||||
changed_when: false
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Check user accounts
|
||||
shell: |
|
||||
echo "=== USER ACCOUNT AUDIT ==="
|
||||
echo "Users with shell access:"
|
||||
grep -E '/bin/(bash|sh|zsh)$' /etc/passwd | cut -d: -f1 | sort
|
||||
echo ""
|
||||
echo "Users with sudo access:"
|
||||
if [ -f /etc/sudoers ]; then
|
||||
grep -E '^[^#]*ALL.*ALL' /etc/sudoers 2>/dev/null | cut -d' ' -f1 || echo "No sudo users found"
|
||||
fi
|
||||
echo ""
|
||||
echo "Recent logins:"
|
||||
last -n 10 2>/dev/null | head -10 || echo "Login history not available"
|
||||
register: user_audit
|
||||
changed_when: false
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Check file permissions
|
||||
shell: |
|
||||
echo "=== FILE PERMISSIONS AUDIT ==="
|
||||
echo "World-writable files in /etc:"
|
||||
find /etc -type f -perm -002 2>/dev/null | head -10 || echo "None found"
|
||||
echo ""
|
||||
echo "SUID/SGID files:"
|
||||
find /usr -type f \( -perm -4000 -o -perm -2000 \) 2>/dev/null | head -10 || echo "None found"
|
||||
echo ""
|
||||
echo "SSH key permissions:"
|
||||
if [ -d ~/.ssh ]; then
|
||||
ls -la ~/.ssh/ 2>/dev/null || echo "SSH directory not accessible"
|
||||
else
|
||||
echo "No SSH directory found"
|
||||
fi
|
||||
register: permissions_audit
|
||||
changed_when: false
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Check network security
|
||||
shell: |
|
||||
echo "=== NETWORK SECURITY AUDIT ==="
|
||||
echo "Open ports:"
|
||||
if command -v netstat >/dev/null 2>&1; then
|
||||
netstat -tuln | grep LISTEN | head -10
|
||||
elif command -v ss >/dev/null 2>&1; then
|
||||
ss -tuln | grep LISTEN | head -10
|
||||
else
|
||||
echo "No network tools available"
|
||||
fi
|
||||
echo ""
|
||||
echo "Network interfaces:"
|
||||
ip addr show 2>/dev/null | grep -E '^[0-9]+:' || echo "Network info not available"
|
||||
register: network_audit
|
||||
changed_when: false
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Check system services
|
||||
shell: |
|
||||
echo "=== SERVICE SECURITY AUDIT ==="
|
||||
if command -v systemctl >/dev/null 2>&1; then
|
||||
echo "Running services:"
|
||||
systemctl list-units --type=service --state=running --no-legend | head -15
|
||||
echo ""
|
||||
echo "Failed services:"
|
||||
systemctl --failed --no-legend | head -5
|
||||
else
|
||||
echo "Systemd not available"
|
||||
fi
|
||||
register: service_audit
|
||||
changed_when: false
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Check Docker security (if available)
|
||||
shell: |
|
||||
if command -v docker >/dev/null 2>&1 && docker info >/dev/null 2>&1; then
|
||||
echo "=== DOCKER SECURITY AUDIT ==="
|
||||
echo "Docker daemon info:"
|
||||
docker info --format '{{.SecurityOptions}}' 2>/dev/null || echo "Security options not available"
|
||||
echo ""
|
||||
echo "Privileged containers:"
|
||||
docker ps --format "table {{.Names}}\t{{.Status}}" --filter "label=privileged=true" 2>/dev/null || echo "No privileged containers found"
|
||||
echo ""
|
||||
echo "Containers with host network:"
|
||||
docker ps --format "table {{.Names}}\t{{.Ports}}" | grep -E '0\.0\.0\.0|::' | head -5 || echo "No host network containers found"
|
||||
else
|
||||
echo "Docker not available or not accessible"
|
||||
fi
|
||||
register: docker_audit
|
||||
changed_when: false
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Calculate security score
|
||||
set_fact:
|
||||
security_score:
|
||||
updates_pending: "{{ pending_updates.stdout | int }}"
|
||||
security_updates_pending: "{{ security_updates.stdout | int }}"
|
||||
ssh_root_login: "{{ 'SECURE' if 'no' in ssh_audit.stdout.lower() else 'INSECURE' }}"
|
||||
ssh_password_auth: "{{ 'SECURE' if 'no' in ssh_audit.stdout.lower() else 'INSECURE' }}"
|
||||
firewall_active: "{{ 'ACTIVE' if 'active' in firewall_audit.stdout.lower() or 'status: active' in firewall_audit.stdout.lower() else 'INACTIVE' }}"
|
||||
overall_risk: >-
|
||||
{{
|
||||
'HIGH' if (
|
||||
(security_updates.stdout | int > 5) or
|
||||
('yes' in ssh_audit.stdout.lower() and 'PermitRootLogin' in ssh_audit.stdout) or
|
||||
('inactive' in firewall_audit.stdout.lower())
|
||||
) else 'MEDIUM' if (
|
||||
(pending_updates.stdout | int > 10) or
|
||||
(security_updates.stdout | int > 0)
|
||||
) else 'LOW'
|
||||
}}
|
||||
|
||||
- name: Display security audit report
|
||||
debug:
|
||||
msg: |
|
||||
|
||||
==========================================
|
||||
🔒 SECURITY AUDIT REPORT - {{ inventory_hostname }}
|
||||
==========================================
|
||||
|
||||
📊 SECURITY SCORE: {{ security_score.overall_risk }} RISK
|
||||
|
||||
🔄 UPDATES:
|
||||
- Pending Updates: {{ security_score.updates_pending }}
|
||||
- Security Updates: {{ security_score.security_updates_pending }}
|
||||
|
||||
🔐 SSH SECURITY:
|
||||
- Root Login: {{ security_score.ssh_root_login }}
|
||||
- Password Auth: {{ security_score.ssh_password_auth }}
|
||||
|
||||
🛡️ FIREWALL:
|
||||
- Status: {{ security_score.firewall_active }}
|
||||
|
||||
{{ ssh_audit.stdout }}
|
||||
|
||||
{{ firewall_audit.stdout }}
|
||||
|
||||
{{ user_audit.stdout }}
|
||||
|
||||
{{ permissions_audit.stdout }}
|
||||
|
||||
{{ network_audit.stdout }}
|
||||
|
||||
{{ service_audit.stdout }}
|
||||
|
||||
{{ docker_audit.stdout }}
|
||||
|
||||
==========================================
|
||||
|
||||
- name: Generate JSON security report
|
||||
copy:
|
||||
content: |
|
||||
{
|
||||
"timestamp": "{{ audit_timestamp }}",
|
||||
"hostname": "{{ inventory_hostname }}",
|
||||
"security_score": {
|
||||
"overall_risk": "{{ security_score.overall_risk }}",
|
||||
"updates_pending": {{ security_score.updates_pending }},
|
||||
"security_updates_pending": {{ security_score.security_updates_pending }},
|
||||
"ssh_root_login": "{{ security_score.ssh_root_login }}",
|
||||
"ssh_password_auth": "{{ security_score.ssh_password_auth }}",
|
||||
"firewall_active": "{{ security_score.firewall_active }}"
|
||||
},
|
||||
"audit_details": {
|
||||
"ssh_config": {{ ssh_audit.stdout | to_json }},
|
||||
"firewall_status": {{ firewall_audit.stdout | to_json }},
|
||||
"user_accounts": {{ user_audit.stdout | to_json }},
|
||||
"file_permissions": {{ permissions_audit.stdout | to_json }},
|
||||
"network_security": {{ network_audit.stdout | to_json }},
|
||||
"services": {{ service_audit.stdout | to_json }},
|
||||
"docker_security": {{ docker_audit.stdout | to_json }}
|
||||
},
|
||||
"recommendations": [
|
||||
{% if security_score.security_updates_pending | int > 0 %}
|
||||
"Apply {{ security_score.security_updates_pending }} pending security updates",
|
||||
{% endif %}
|
||||
{% if security_score.ssh_root_login == "INSECURE" %}
|
||||
"Disable SSH root login",
|
||||
{% endif %}
|
||||
{% if security_score.firewall_active == "INACTIVE" %}
|
||||
"Enable and configure firewall",
|
||||
{% endif %}
|
||||
{% if security_score.updates_pending | int > 20 %}
|
||||
"Apply system updates ({{ security_score.updates_pending }} pending)",
|
||||
{% endif %}
|
||||
"Regular security monitoring recommended"
|
||||
]
|
||||
}
|
||||
dest: "{{ security_report_dir }}/{{ inventory_hostname }}_security_{{ ansible_date_time.epoch }}.json"
|
||||
delegate_to: localhost
|
||||
|
||||
- name: Send security alert for high risk
|
||||
shell: |
|
||||
if command -v curl >/dev/null 2>&1; then
|
||||
curl -d "🚨 HIGH RISK: {{ inventory_hostname }} security audit - {{ security_score.overall_risk }} risk level detected" \
|
||||
-H "Title: Security Alert" \
|
||||
-H "Priority: high" \
|
||||
-H "Tags: security,audit" \
|
||||
"{{ ntfy_url | default('https://ntfy.sh/REDACTED_TOPIC') }}" || true
|
||||
fi
|
||||
when: security_score.overall_risk == "HIGH"
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Summary message
|
||||
debug:
|
||||
msg: |
|
||||
|
||||
🔒 Security audit complete for {{ inventory_hostname }}
|
||||
📊 Risk Level: {{ security_score.overall_risk }}
|
||||
📄 Report saved to: {{ security_report_dir }}/{{ inventory_hostname }}_security_{{ ansible_date_time.epoch }}.json
|
||||
|
||||
{% if security_score.overall_risk == "HIGH" %}
|
||||
🚨 HIGH RISK detected - immediate action required!
|
||||
{% elif security_score.overall_risk == "MEDIUM" %}
|
||||
⚠️ MEDIUM RISK - review and address issues
|
||||
{% else %}
|
||||
✅ LOW RISK - system appears secure
|
||||
{% endif %}
|
||||
|
||||
Key Issues:
|
||||
{% if security_score.security_updates_pending | int > 0 %}
|
||||
- {{ security_score.security_updates_pending }} security updates pending
|
||||
{% endif %}
|
||||
{% if security_score.ssh_root_login == "INSECURE" %}
|
||||
- SSH root login enabled
|
||||
{% endif %}
|
||||
{% if security_score.firewall_active == "INACTIVE" %}
|
||||
- Firewall not active
|
||||
{% endif %}
|
||||
Reference in New Issue
Block a user