mirror of
https://github.com/BagelHole/DevOps-Security-Agent-Skills.git
synced 2026-08-22 12:49:53 +02:00
.
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
---
|
||||
name: cis-benchmarks
|
||||
description: Audit and remediate CIS benchmark violations. Use automated tools to assess compliance and implement hardening recommendations. Use when meeting compliance requirements or implementing security baselines.
|
||||
license: MIT
|
||||
metadata:
|
||||
author: devops-skills
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# CIS Benchmarks
|
||||
|
||||
Implement and audit CIS security benchmarks.
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
Use this skill when:
|
||||
- Assessing security compliance
|
||||
- Implementing security baselines
|
||||
- Meeting regulatory requirements
|
||||
- Hardening systems to standards
|
||||
|
||||
## Assessment Tools
|
||||
|
||||
### OpenSCAP
|
||||
|
||||
```bash
|
||||
# Install
|
||||
apt install openscap-scanner scap-security-guide
|
||||
|
||||
# Run CIS benchmark scan
|
||||
oscap xccdf eval \
|
||||
--profile xccdf_org.ssgproject.content_profile_cis \
|
||||
--results results.xml \
|
||||
--report report.html \
|
||||
/usr/share/xml/scap/ssg/content/ssg-ubuntu2204-ds.xml
|
||||
```
|
||||
|
||||
### Lynis
|
||||
|
||||
```bash
|
||||
# Install
|
||||
apt install lynis
|
||||
|
||||
# Run audit
|
||||
lynis audit system
|
||||
|
||||
# Generate report
|
||||
lynis audit system --report-file /tmp/lynis-report.dat
|
||||
```
|
||||
|
||||
### InSpec
|
||||
|
||||
```ruby
|
||||
# cis-profile/controls/ssh.rb
|
||||
control 'cis-ssh-1' do
|
||||
impact 1.0
|
||||
title 'Ensure SSH root login is disabled'
|
||||
|
||||
describe sshd_config do
|
||||
its('PermitRootLogin') { should eq 'no' }
|
||||
end
|
||||
end
|
||||
|
||||
control 'cis-ssh-2' do
|
||||
impact 0.7
|
||||
title 'Ensure SSH password authentication is disabled'
|
||||
|
||||
describe sshd_config do
|
||||
its('PasswordAuthentication') { should eq 'no' }
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
```bash
|
||||
# Run InSpec
|
||||
inspec exec cis-profile -t ssh://user@target
|
||||
```
|
||||
|
||||
### Kubernetes CIS
|
||||
|
||||
```bash
|
||||
# kube-bench
|
||||
docker run --rm -v /etc:/etc:ro -v /var:/var:ro \
|
||||
aquasec/kube-bench:latest run --targets node
|
||||
|
||||
# Check specific sections
|
||||
kube-bench run --targets master --check 1.1,1.2
|
||||
```
|
||||
|
||||
## Remediation Workflow
|
||||
|
||||
```yaml
|
||||
workflow:
|
||||
1_scan:
|
||||
- Run automated assessment
|
||||
- Generate baseline report
|
||||
|
||||
2_analyze:
|
||||
- Review findings
|
||||
- Identify false positives
|
||||
- Prioritize by risk
|
||||
|
||||
3_remediate:
|
||||
- Apply fixes
|
||||
- Document exceptions
|
||||
- Verify changes
|
||||
|
||||
4_validate:
|
||||
- Re-run assessment
|
||||
- Confirm remediation
|
||||
- Generate compliance report
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Baseline before hardening
|
||||
- Document exceptions
|
||||
- Automate assessments
|
||||
- Track compliance over time
|
||||
- Regular re-assessment
|
||||
- Version control configurations
|
||||
|
||||
## Related Skills
|
||||
|
||||
- [linux-hardening](../linux-hardening/) - Linux security
|
||||
- [vulnerability-scanning](../../scanning/vulnerability-scanning/) - Security scanning
|
||||
@@ -0,0 +1,102 @@
|
||||
---
|
||||
name: container-hardening
|
||||
description: Secure Docker images and container runtime configurations. Implement non-root users, read-only filesystems, and security contexts. Use when building secure container images or hardening container deployments.
|
||||
license: MIT
|
||||
metadata:
|
||||
author: devops-skills
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# Container Hardening
|
||||
|
||||
Secure container images and runtime configurations.
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
Use this skill when:
|
||||
- Building secure container images
|
||||
- Hardening container deployments
|
||||
- Meeting container security requirements
|
||||
- Implementing defense in depth
|
||||
|
||||
## Dockerfile Security
|
||||
|
||||
```dockerfile
|
||||
# Use minimal base image
|
||||
FROM alpine:3.18
|
||||
|
||||
# Don't run as root
|
||||
RUN addgroup -g 1001 -S appgroup && \
|
||||
adduser -u 1001 -S appuser -G appgroup
|
||||
|
||||
# Copy with specific ownership
|
||||
COPY --chown=appuser:appgroup . /app
|
||||
|
||||
# Remove unnecessary packages
|
||||
RUN apk del --purge build-dependencies && \
|
||||
rm -rf /var/cache/apk/*
|
||||
|
||||
# Use non-root user
|
||||
USER appuser
|
||||
|
||||
# Read-only filesystem support
|
||||
WORKDIR /app
|
||||
```
|
||||
|
||||
## Runtime Security
|
||||
|
||||
```bash
|
||||
# Run with security options
|
||||
docker run -d \
|
||||
--read-only \
|
||||
--tmpfs /tmp \
|
||||
--security-opt=no-new-privileges:true \
|
||||
--cap-drop=ALL \
|
||||
--cap-add=NET_BIND_SERVICE \
|
||||
--user 1001:1001 \
|
||||
myapp:latest
|
||||
```
|
||||
|
||||
## Kubernetes Security Context
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
spec:
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1001
|
||||
fsGroup: 1001
|
||||
containers:
|
||||
- name: app
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
readOnlyRootFilesystem: true
|
||||
capabilities:
|
||||
drop: ["ALL"]
|
||||
```
|
||||
|
||||
## Image Scanning
|
||||
|
||||
```bash
|
||||
# Scan with Trivy
|
||||
trivy image --severity HIGH,CRITICAL myapp:latest
|
||||
|
||||
# Use distroless images
|
||||
FROM gcr.io/distroless/static-debian11
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Use minimal base images
|
||||
- Run as non-root user
|
||||
- Enable read-only filesystem
|
||||
- Drop all capabilities
|
||||
- Scan images regularly
|
||||
- Sign and verify images
|
||||
- Use secrets management
|
||||
|
||||
## Related Skills
|
||||
|
||||
- [container-scanning](../../scanning/container-scanning/) - Vulnerability scanning
|
||||
- [kubernetes-hardening](../kubernetes-hardening/) - K8s security
|
||||
@@ -0,0 +1,105 @@
|
||||
# Container Security Best Practices
|
||||
|
||||
## Dockerfile Hardening
|
||||
|
||||
```dockerfile
|
||||
# Use minimal base image
|
||||
FROM gcr.io/distroless/base-debian12
|
||||
|
||||
# Or Alpine
|
||||
FROM alpine:3.19
|
||||
|
||||
# Non-root user
|
||||
RUN addgroup -g 1000 appgroup && \
|
||||
adduser -u 1000 -G appgroup -D appuser
|
||||
USER appuser
|
||||
|
||||
# Read-only filesystem
|
||||
# (Set at runtime with --read-only)
|
||||
|
||||
# No new privileges
|
||||
# (Set at runtime with --security-opt=no-new-privileges)
|
||||
```
|
||||
|
||||
## Security Scanning
|
||||
|
||||
```bash
|
||||
# Trivy scan
|
||||
trivy image --severity HIGH,CRITICAL myimage:latest
|
||||
|
||||
# Grype scan
|
||||
grype myimage:latest --fail-on high
|
||||
|
||||
# Docker Scout
|
||||
docker scout cves myimage:latest
|
||||
```
|
||||
|
||||
## Runtime Security
|
||||
|
||||
```yaml
|
||||
# Kubernetes securityContext
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
runAsGroup: 1000
|
||||
readOnlyRootFilesystem: true
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
```
|
||||
|
||||
## Docker Run Hardening
|
||||
|
||||
```bash
|
||||
docker run \
|
||||
--read-only \
|
||||
--tmpfs /tmp \
|
||||
--security-opt=no-new-privileges:true \
|
||||
--cap-drop=ALL \
|
||||
--user 1000:1000 \
|
||||
--memory=512m \
|
||||
--cpus=0.5 \
|
||||
myimage
|
||||
```
|
||||
|
||||
## Image Signing
|
||||
|
||||
```bash
|
||||
# Cosign
|
||||
cosign sign --key cosign.key myimage:latest
|
||||
cosign verify --key cosign.pub myimage:latest
|
||||
|
||||
# Docker Content Trust
|
||||
export DOCKER_CONTENT_TRUST=1
|
||||
docker push myimage:latest
|
||||
```
|
||||
|
||||
## Network Policies
|
||||
|
||||
```yaml
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: deny-all
|
||||
spec:
|
||||
podSelector: {}
|
||||
policyTypes:
|
||||
- Ingress
|
||||
- Egress
|
||||
```
|
||||
|
||||
## Checklist
|
||||
|
||||
- [ ] Use minimal base images
|
||||
- [ ] Run as non-root
|
||||
- [ ] Drop all capabilities
|
||||
- [ ] Read-only filesystem
|
||||
- [ ] No privilege escalation
|
||||
- [ ] Scan for vulnerabilities
|
||||
- [ ] Sign images
|
||||
- [ ] Implement network policies
|
||||
- [ ] Use secrets management
|
||||
- [ ] Enable audit logging
|
||||
@@ -0,0 +1,129 @@
|
||||
---
|
||||
name: kubernetes-hardening
|
||||
description: Implement Kubernetes security contexts, Pod Security Standards, and network policies. Secure cluster components and workloads. Use when hardening Kubernetes deployments or meeting security compliance.
|
||||
license: MIT
|
||||
metadata:
|
||||
author: devops-skills
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# Kubernetes Hardening
|
||||
|
||||
Secure Kubernetes clusters and workloads.
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
Use this skill when:
|
||||
- Hardening Kubernetes clusters
|
||||
- Implementing Pod Security Standards
|
||||
- Configuring network policies
|
||||
- Meeting security compliance
|
||||
|
||||
## Pod Security Standards
|
||||
|
||||
```yaml
|
||||
# Namespace with restricted policy
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: production
|
||||
labels:
|
||||
pod-security.kubernetes.io/enforce: restricted
|
||||
pod-security.kubernetes.io/audit: restricted
|
||||
pod-security.kubernetes.io/warn: restricted
|
||||
```
|
||||
|
||||
## Security Context
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: secure-pod
|
||||
spec:
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
runAsGroup: 1000
|
||||
fsGroup: 1000
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
containers:
|
||||
- name: app
|
||||
image: myapp:latest
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
readOnlyRootFilesystem: true
|
||||
capabilities:
|
||||
drop: ["ALL"]
|
||||
```
|
||||
|
||||
## Network Policies
|
||||
|
||||
```yaml
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: default-deny-all
|
||||
spec:
|
||||
podSelector: {}
|
||||
policyTypes:
|
||||
- Ingress
|
||||
- Egress
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: allow-web
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels:
|
||||
app: web
|
||||
ingress:
|
||||
- from:
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
app: frontend
|
||||
ports:
|
||||
- port: 8080
|
||||
```
|
||||
|
||||
## RBAC
|
||||
|
||||
```yaml
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: app-reader
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["pods", "services"]
|
||||
verbs: ["get", "list"]
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: app-reader-binding
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: myapp
|
||||
roleRef:
|
||||
kind: Role
|
||||
name: app-reader
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Enable Pod Security Standards
|
||||
- Implement network policies
|
||||
- Use RBAC with least privilege
|
||||
- Enable audit logging
|
||||
- Secure etcd with encryption
|
||||
- Use service mesh for mTLS
|
||||
- Regular security scanning
|
||||
|
||||
## Related Skills
|
||||
|
||||
- [kubernetes-ops](../../../devops/orchestration/kubernetes-ops/) - K8s operations
|
||||
- [container-hardening](../container-hardening/) - Container security
|
||||
@@ -0,0 +1,130 @@
|
||||
---
|
||||
name: linux-hardening
|
||||
description: Apply CIS benchmarks and secure Linux servers. Configure SSH, manage users, implement firewall rules, and enable security features. Use when hardening Linux systems for production or meeting security compliance requirements.
|
||||
license: MIT
|
||||
metadata:
|
||||
author: devops-skills
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# Linux Hardening
|
||||
|
||||
Secure Linux servers following CIS benchmarks and security best practices.
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
Use this skill when:
|
||||
- Hardening production servers
|
||||
- Meeting compliance requirements
|
||||
- Implementing security baselines
|
||||
- Configuring secure SSH access
|
||||
|
||||
## SSH Hardening
|
||||
|
||||
```bash
|
||||
# /etc/ssh/sshd_config
|
||||
PermitRootLogin no
|
||||
PasswordAuthentication no
|
||||
PubkeyAuthentication yes
|
||||
MaxAuthTries 3
|
||||
ClientAliveInterval 300
|
||||
ClientAliveCountMax 2
|
||||
AllowUsers deploy admin
|
||||
Protocol 2
|
||||
```
|
||||
|
||||
## User Security
|
||||
|
||||
```bash
|
||||
# Password policy
|
||||
sudo apt install libpam-pwquality
|
||||
# /etc/security/pwquality.conf
|
||||
minlen = 14
|
||||
dcredit = -1
|
||||
ucredit = -1
|
||||
ocredit = -1
|
||||
lcredit = -1
|
||||
|
||||
# Lock inactive accounts
|
||||
useradd -D -f 30
|
||||
|
||||
# Audit sudo usage
|
||||
echo "Defaults logfile=/var/log/sudo.log" >> /etc/sudoers
|
||||
```
|
||||
|
||||
## Firewall Configuration
|
||||
|
||||
```bash
|
||||
# UFW setup
|
||||
ufw default deny incoming
|
||||
ufw default allow outgoing
|
||||
ufw allow ssh
|
||||
ufw allow 443/tcp
|
||||
ufw enable
|
||||
|
||||
# Or iptables
|
||||
iptables -P INPUT DROP
|
||||
iptables -P FORWARD DROP
|
||||
iptables -A INPUT -i lo -j ACCEPT
|
||||
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
|
||||
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
|
||||
```
|
||||
|
||||
## Kernel Hardening
|
||||
|
||||
```bash
|
||||
# /etc/sysctl.d/99-security.conf
|
||||
net.ipv4.conf.all.send_redirects = 0
|
||||
net.ipv4.conf.all.accept_redirects = 0
|
||||
net.ipv4.conf.all.accept_source_route = 0
|
||||
net.ipv4.icmp_echo_ignore_broadcasts = 1
|
||||
kernel.randomize_va_space = 2
|
||||
fs.suid_dumpable = 0
|
||||
|
||||
# Apply
|
||||
sysctl -p
|
||||
```
|
||||
|
||||
## File Permissions
|
||||
|
||||
```bash
|
||||
# Critical files
|
||||
chmod 600 /etc/shadow
|
||||
chmod 644 /etc/passwd
|
||||
chmod 700 /root
|
||||
chmod 600 /etc/ssh/sshd_config
|
||||
|
||||
# Find world-writable files
|
||||
find / -type f -perm -0002 -ls
|
||||
|
||||
# Find SUID files
|
||||
find / -perm -4000 -type f -ls
|
||||
```
|
||||
|
||||
## Audit Configuration
|
||||
|
||||
```bash
|
||||
# Install auditd
|
||||
apt install auditd
|
||||
|
||||
# /etc/audit/rules.d/audit.rules
|
||||
-w /etc/passwd -p wa -k identity
|
||||
-w /etc/shadow -p wa -k identity
|
||||
-w /etc/sudoers -p wa -k actions
|
||||
-a always,exit -F arch=b64 -S execve -k exec
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Disable unused services
|
||||
- Keep system updated
|
||||
- Use fail2ban for intrusion prevention
|
||||
- Enable SELinux/AppArmor
|
||||
- Regular security audits
|
||||
- Monitor log files
|
||||
- Implement least privilege
|
||||
|
||||
## Related Skills
|
||||
|
||||
- [cis-benchmarks](../cis-benchmarks/) - Compliance scanning
|
||||
- [firewall-config](../../network/firewall-config/) - Firewall rules
|
||||
@@ -0,0 +1,111 @@
|
||||
# SSH Server Hardening Configuration
|
||||
# Place in /etc/ssh/sshd_config.d/hardening.conf
|
||||
# Restart SSH: systemctl restart sshd
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# AUTHENTICATION
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
# Disable root login
|
||||
PermitRootLogin no
|
||||
|
||||
# Disable password authentication
|
||||
PasswordAuthentication no
|
||||
|
||||
# Enable public key authentication
|
||||
PubkeyAuthentication yes
|
||||
|
||||
# Disable empty passwords
|
||||
PermitEmptyPasswords no
|
||||
|
||||
# Disable keyboard-interactive authentication
|
||||
KbdInteractiveAuthentication no
|
||||
|
||||
# Disable challenge-response authentication
|
||||
ChallengeResponseAuthentication no
|
||||
|
||||
# Maximum authentication attempts
|
||||
MaxAuthTries 3
|
||||
|
||||
# Maximum sessions per connection
|
||||
MaxSessions 2
|
||||
|
||||
# Maximum simultaneous unauthenticated connections
|
||||
MaxStartups 10:30:60
|
||||
|
||||
# Login grace time
|
||||
LoginGraceTime 60
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# SESSION
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
# Client alive settings (timeout)
|
||||
ClientAliveInterval 300
|
||||
ClientAliveCountMax 2
|
||||
|
||||
# Disable TCP forwarding
|
||||
AllowTcpForwarding no
|
||||
|
||||
# Disable agent forwarding
|
||||
AllowAgentForwarding no
|
||||
|
||||
# Disable stream local forwarding
|
||||
AllowStreamLocalForwarding no
|
||||
|
||||
# Disable X11 forwarding
|
||||
X11Forwarding no
|
||||
|
||||
# Disable user environment processing
|
||||
PermitUserEnvironment no
|
||||
|
||||
# Disable tunnel device forwarding
|
||||
PermitTunnel no
|
||||
|
||||
# Disable gateway ports
|
||||
GatewayPorts no
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# CRYPTOGRAPHY
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
# Protocol version (SSH-2 only)
|
||||
Protocol 2
|
||||
|
||||
# Strong ciphers only
|
||||
Ciphers aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr
|
||||
|
||||
# Strong MACs only
|
||||
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512,hmac-sha2-256
|
||||
|
||||
# Strong key exchange algorithms
|
||||
KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512
|
||||
|
||||
# Strong host key algorithms
|
||||
HostKeyAlgorithms ssh-ed25519,rsa-sha2-512,rsa-sha2-256
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# LOGGING
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
# Log level
|
||||
LogLevel VERBOSE
|
||||
|
||||
# Enable sftp logging
|
||||
Subsystem sftp /usr/lib/openssh/sftp-server -l INFO
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# ACCESS CONTROL
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
# Use PAM
|
||||
UsePAM yes
|
||||
|
||||
# Show banner
|
||||
Banner /etc/issue.net
|
||||
|
||||
# Restrict to specific users (uncomment and customize)
|
||||
# AllowUsers admin deploy
|
||||
|
||||
# Restrict to specific groups (uncomment and customize)
|
||||
# AllowGroups sshusers admins
|
||||
@@ -0,0 +1,104 @@
|
||||
# Linux Kernel Security Hardening
|
||||
# Place in /etc/sysctl.d/99-security.conf
|
||||
# Apply with: sysctl -p /etc/sysctl.d/99-security.conf
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# NETWORK SECURITY
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
# Disable IP forwarding (unless router)
|
||||
net.ipv4.ip_forward = 0
|
||||
net.ipv6.conf.all.forwarding = 0
|
||||
|
||||
# Disable packet redirect sending
|
||||
net.ipv4.conf.all.send_redirects = 0
|
||||
net.ipv4.conf.default.send_redirects = 0
|
||||
|
||||
# Disable ICMP redirect acceptance
|
||||
net.ipv4.conf.all.accept_redirects = 0
|
||||
net.ipv4.conf.default.accept_redirects = 0
|
||||
net.ipv4.conf.all.secure_redirects = 0
|
||||
net.ipv4.conf.default.secure_redirects = 0
|
||||
net.ipv6.conf.all.accept_redirects = 0
|
||||
net.ipv6.conf.default.accept_redirects = 0
|
||||
|
||||
# Disable source routing
|
||||
net.ipv4.conf.all.accept_source_route = 0
|
||||
net.ipv4.conf.default.accept_source_route = 0
|
||||
net.ipv6.conf.all.accept_source_route = 0
|
||||
net.ipv6.conf.default.accept_source_route = 0
|
||||
|
||||
# Log suspicious packets
|
||||
net.ipv4.conf.all.log_martians = 1
|
||||
net.ipv4.conf.default.log_martians = 1
|
||||
|
||||
# Ignore ICMP broadcast requests
|
||||
net.ipv4.icmp_echo_ignore_broadcasts = 1
|
||||
|
||||
# Ignore bogus ICMP error responses
|
||||
net.ipv4.icmp_ignore_bogus_error_responses = 1
|
||||
|
||||
# Enable reverse path filtering (spoofing protection)
|
||||
net.ipv4.conf.all.rp_filter = 1
|
||||
net.ipv4.conf.default.rp_filter = 1
|
||||
|
||||
# Enable TCP SYN cookies (SYN flood protection)
|
||||
net.ipv4.tcp_syncookies = 1
|
||||
|
||||
# Disable IPv6 router advertisements
|
||||
net.ipv6.conf.all.accept_ra = 0
|
||||
net.ipv6.conf.default.accept_ra = 0
|
||||
|
||||
# Disable IPv6 if not needed
|
||||
# net.ipv6.conf.all.disable_ipv6 = 1
|
||||
# net.ipv6.conf.default.disable_ipv6 = 1
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# KERNEL SECURITY
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
# Enable ASLR
|
||||
kernel.randomize_va_space = 2
|
||||
|
||||
# Restrict access to kernel pointers
|
||||
kernel.kptr_restrict = 2
|
||||
|
||||
# Restrict dmesg access
|
||||
kernel.dmesg_restrict = 1
|
||||
|
||||
# Restrict ptrace scope
|
||||
kernel.yama.ptrace_scope = 1
|
||||
|
||||
# Disable magic SysRq key
|
||||
kernel.sysrq = 0
|
||||
|
||||
# Restrict unprivileged user namespaces
|
||||
# kernel.unprivileged_userns_clone = 0
|
||||
|
||||
# Restrict loading TTY line disciplines
|
||||
dev.tty.ldisc_autoload = 0
|
||||
|
||||
# Restrict userfaultfd to privileged users
|
||||
vm.unprivileged_userfaultfd = 0
|
||||
|
||||
# Restrict BPF
|
||||
kernel.unprivileged_bpf_disabled = 1
|
||||
net.core.bpf_jit_harden = 2
|
||||
|
||||
# Restrict perf events
|
||||
kernel.perf_event_paranoid = 3
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# FILE SYSTEM SECURITY
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
# Restrict core dumps
|
||||
fs.suid_dumpable = 0
|
||||
|
||||
# Restrict hardlinks and symlinks
|
||||
fs.protected_hardlinks = 1
|
||||
fs.protected_symlinks = 1
|
||||
|
||||
# Protect FIFOs and regular files
|
||||
fs.protected_fifos = 2
|
||||
fs.protected_regular = 2
|
||||
@@ -0,0 +1,139 @@
|
||||
# CIS Linux Hardening Checklist
|
||||
|
||||
## 1. Initial Setup
|
||||
|
||||
### 1.1 Filesystem Configuration
|
||||
- [ ] Disable unused filesystems (cramfs, freevxfs, jffs2, hfs, hfsplus, squashfs, udf)
|
||||
- [ ] Ensure `/tmp` is configured with nodev, nosuid, noexec
|
||||
- [ ] Ensure `/var`, `/var/tmp`, `/var/log`, `/var/log/audit` are separate partitions
|
||||
- [ ] Ensure `/home` is separate partition with nodev
|
||||
|
||||
### 1.2 Configure Software Updates
|
||||
- [ ] Ensure package manager repositories are configured
|
||||
- [ ] Ensure GPG keys are configured
|
||||
- [ ] Ensure automatic updates are enabled
|
||||
|
||||
### 1.3 Filesystem Integrity
|
||||
- [ ] Ensure AIDE is installed
|
||||
- [ ] Ensure filesystem integrity is regularly checked
|
||||
|
||||
## 2. Services
|
||||
|
||||
### 2.1 Special Purpose Services
|
||||
- [ ] Ensure time synchronization is configured (chrony/ntp)
|
||||
- [ ] Ensure X Window System is not installed
|
||||
- [ ] Ensure rsync service is not installed or masked
|
||||
- [ ] Ensure Avahi Server is not installed
|
||||
- [ ] Ensure CUPS is not installed
|
||||
- [ ] Ensure DHCP Server is not installed
|
||||
- [ ] Ensure LDAP server is not installed
|
||||
- [ ] Ensure NFS is not installed
|
||||
- [ ] Ensure DNS Server is not installed
|
||||
- [ ] Ensure FTP Server is not installed
|
||||
- [ ] Ensure HTTP Server is not installed
|
||||
- [ ] Ensure IMAP and POP3 server is not installed
|
||||
- [ ] Ensure Samba is not installed
|
||||
- [ ] Ensure SNMP Server is not installed
|
||||
|
||||
### 2.2 Service Clients
|
||||
- [ ] Ensure NIS Client is not installed
|
||||
- [ ] Ensure rsh client is not installed
|
||||
- [ ] Ensure talk client is not installed
|
||||
- [ ] Ensure telnet client is not installed
|
||||
- [ ] Ensure LDAP client is not installed
|
||||
- [ ] Ensure RPC is not installed
|
||||
|
||||
## 3. Network Configuration
|
||||
|
||||
### 3.1 Network Parameters (Host Only)
|
||||
- [ ] Ensure IP forwarding is disabled
|
||||
- [ ] Ensure packet redirect sending is disabled
|
||||
|
||||
### 3.2 Network Parameters (Host and Router)
|
||||
- [ ] Ensure source routed packets are not accepted
|
||||
- [ ] Ensure ICMP redirects are not accepted
|
||||
- [ ] Ensure secure ICMP redirects are not accepted
|
||||
- [ ] Ensure suspicious packets are logged
|
||||
- [ ] Ensure broadcast ICMP requests are ignored
|
||||
- [ ] Ensure bogus ICMP responses are ignored
|
||||
- [ ] Ensure Reverse Path Filtering is enabled
|
||||
- [ ] Ensure TCP SYN Cookies is enabled
|
||||
|
||||
### 3.3 Firewall Configuration
|
||||
- [ ] Ensure firewall is installed (iptables, nftables, or firewalld)
|
||||
- [ ] Ensure default deny firewall policy
|
||||
- [ ] Ensure loopback traffic is configured
|
||||
- [ ] Ensure outbound connections are configured
|
||||
|
||||
## 4. Access, Authentication and Authorization
|
||||
|
||||
### 4.1 Configure Shadow Suite
|
||||
- [ ] Ensure password expiration is 365 days or less
|
||||
- [ ] Ensure minimum days between password changes is 7 or more
|
||||
- [ ] Ensure password expiration warning days is 7 or more
|
||||
- [ ] Ensure inactive password lock is 30 days or less
|
||||
- [ ] Ensure all users last password change date is in the past
|
||||
|
||||
### 4.2 Configure SSH Server
|
||||
- [ ] Ensure SSH Protocol is set to 2
|
||||
- [ ] Ensure SSH LogLevel is appropriate
|
||||
- [ ] Ensure SSH X11 forwarding is disabled
|
||||
- [ ] Ensure SSH MaxAuthTries is set to 4 or less
|
||||
- [ ] Ensure SSH IgnoreRhosts is enabled
|
||||
- [ ] Ensure SSH HostbasedAuthentication is disabled
|
||||
- [ ] Ensure SSH root login is disabled
|
||||
- [ ] Ensure SSH PermitEmptyPasswords is disabled
|
||||
- [ ] Ensure SSH PermitUserEnvironment is disabled
|
||||
- [ ] Ensure SSH Idle Timeout Interval is configured
|
||||
- [ ] Ensure SSH LoginGraceTime is set to one minute or less
|
||||
- [ ] Ensure SSH warning banner is configured
|
||||
- [ ] Ensure SSH PAM is enabled
|
||||
- [ ] Ensure SSH AllowTcpForwarding is disabled
|
||||
|
||||
### 4.3 Configure PAM
|
||||
- [ ] Ensure password creation requirements are configured
|
||||
- [ ] Ensure lockout for failed password attempts is configured
|
||||
- [ ] Ensure password reuse is limited
|
||||
- [ ] Ensure password hashing algorithm is SHA-512
|
||||
|
||||
## 5. Logging and Auditing
|
||||
|
||||
### 5.1 Configure Logging
|
||||
- [ ] Ensure rsyslog is installed
|
||||
- [ ] Ensure rsyslog Service is enabled
|
||||
- [ ] Ensure logging is configured
|
||||
- [ ] Ensure rsyslog default file permissions configured
|
||||
- [ ] Ensure remote rsyslog messages only accepted on designated log hosts
|
||||
|
||||
### 5.2 Configure auditd
|
||||
- [ ] Ensure auditing is enabled
|
||||
- [ ] Ensure audit log storage size is configured
|
||||
- [ ] Ensure audit logs are not automatically deleted
|
||||
- [ ] Ensure changes to system administration scope are collected
|
||||
- [ ] Ensure login and logout events are collected
|
||||
- [ ] Ensure session initiation information is collected
|
||||
- [ ] Ensure file deletion events by users are collected
|
||||
- [ ] Ensure kernel module loading and unloading is collected
|
||||
|
||||
## 6. System Maintenance
|
||||
|
||||
### 6.1 File Permissions
|
||||
- [ ] Ensure permissions on /etc/passwd are configured (644)
|
||||
- [ ] Ensure permissions on /etc/shadow are configured (600)
|
||||
- [ ] Ensure permissions on /etc/group are configured (644)
|
||||
- [ ] Ensure permissions on /etc/gshadow are configured (600)
|
||||
- [ ] Ensure no world writable files exist
|
||||
- [ ] Ensure no unowned files or directories exist
|
||||
- [ ] Ensure no ungrouped files or directories exist
|
||||
|
||||
### 6.2 User and Group Settings
|
||||
- [ ] Ensure accounts in /etc/passwd use shadowed passwords
|
||||
- [ ] Ensure no legacy "+" entries exist in /etc/passwd
|
||||
- [ ] Ensure root is the only UID 0 account
|
||||
- [ ] Ensure root PATH integrity
|
||||
- [ ] Ensure all users' home directories exist
|
||||
- [ ] Ensure users' home directories permissions are 750 or more restrictive
|
||||
- [ ] Ensure users own their home directories
|
||||
- [ ] Ensure no users have .forward files
|
||||
- [ ] Ensure no users have .netrc files
|
||||
- [ ] Ensure no users have .rhosts files
|
||||
@@ -0,0 +1,138 @@
|
||||
#!/bin/bash
|
||||
# Linux Security Audit Script
|
||||
# Usage: ./audit-system.sh [--verbose]
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
VERBOSE="${1:-}"
|
||||
PASS=0
|
||||
WARN=0
|
||||
FAIL=0
|
||||
|
||||
check() {
|
||||
local status="$1"
|
||||
local message="$2"
|
||||
case "$status" in
|
||||
PASS) echo -e "\e[32m[PASS]\e[0m $message"; ((PASS++)) ;;
|
||||
WARN) echo -e "\e[33m[WARN]\e[0m $message"; ((WARN++)) ;;
|
||||
FAIL) echo -e "\e[31m[FAIL]\e[0m $message"; ((FAIL++)) ;;
|
||||
esac
|
||||
}
|
||||
|
||||
echo "========================================="
|
||||
echo "Linux Security Audit"
|
||||
echo "========================================="
|
||||
echo ""
|
||||
|
||||
# 1. System Updates
|
||||
echo "1. System Updates"
|
||||
echo "-----------------"
|
||||
UPDATES=$(apt-get -s upgrade 2>/dev/null | grep -c "^Inst" || echo 0)
|
||||
if [ "$UPDATES" -eq 0 ]; then
|
||||
check "PASS" "System is up to date"
|
||||
else
|
||||
check "FAIL" "$UPDATES packages need updating"
|
||||
fi
|
||||
|
||||
# 2. SSH Configuration
|
||||
echo ""
|
||||
echo "2. SSH Configuration"
|
||||
echo "--------------------"
|
||||
if grep -q "^PermitRootLogin no" /etc/ssh/sshd_config* 2>/dev/null; then
|
||||
check "PASS" "Root login disabled"
|
||||
else
|
||||
check "FAIL" "Root login may be enabled"
|
||||
fi
|
||||
|
||||
if grep -q "^PasswordAuthentication no" /etc/ssh/sshd_config* 2>/dev/null; then
|
||||
check "PASS" "Password authentication disabled"
|
||||
else
|
||||
check "WARN" "Password authentication may be enabled"
|
||||
fi
|
||||
|
||||
# 3. User Accounts
|
||||
echo ""
|
||||
echo "3. User Accounts"
|
||||
echo "----------------"
|
||||
EMPTY_PASS=$(awk -F: '($2 == "") {print $1}' /etc/shadow 2>/dev/null | wc -l)
|
||||
if [ "$EMPTY_PASS" -eq 0 ]; then
|
||||
check "PASS" "No accounts with empty passwords"
|
||||
else
|
||||
check "FAIL" "$EMPTY_PASS accounts with empty passwords"
|
||||
fi
|
||||
|
||||
ROOT_ACCOUNTS=$(awk -F: '($3 == 0) {print $1}' /etc/passwd | wc -l)
|
||||
if [ "$ROOT_ACCOUNTS" -eq 1 ]; then
|
||||
check "PASS" "Only root has UID 0"
|
||||
else
|
||||
check "FAIL" "$ROOT_ACCOUNTS accounts have UID 0"
|
||||
fi
|
||||
|
||||
# 4. File Permissions
|
||||
echo ""
|
||||
echo "4. File Permissions"
|
||||
echo "-------------------"
|
||||
SHADOW_PERMS=$(stat -c %a /etc/shadow 2>/dev/null)
|
||||
if [ "$SHADOW_PERMS" = "600" ] || [ "$SHADOW_PERMS" = "640" ]; then
|
||||
check "PASS" "/etc/shadow permissions: $SHADOW_PERMS"
|
||||
else
|
||||
check "FAIL" "/etc/shadow permissions: $SHADOW_PERMS (should be 600)"
|
||||
fi
|
||||
|
||||
WORLD_WRITABLE=$(find /etc -type f -perm -002 2>/dev/null | wc -l)
|
||||
if [ "$WORLD_WRITABLE" -eq 0 ]; then
|
||||
check "PASS" "No world-writable files in /etc"
|
||||
else
|
||||
check "FAIL" "$WORLD_WRITABLE world-writable files in /etc"
|
||||
fi
|
||||
|
||||
# 5. Network Security
|
||||
echo ""
|
||||
echo "5. Network Security"
|
||||
echo "-------------------"
|
||||
if sysctl -n net.ipv4.tcp_syncookies 2>/dev/null | grep -q "1"; then
|
||||
check "PASS" "TCP SYN cookies enabled"
|
||||
else
|
||||
check "WARN" "TCP SYN cookies not enabled"
|
||||
fi
|
||||
|
||||
if sysctl -n net.ipv4.conf.all.rp_filter 2>/dev/null | grep -q "1"; then
|
||||
check "PASS" "Reverse path filtering enabled"
|
||||
else
|
||||
check "WARN" "Reverse path filtering not enabled"
|
||||
fi
|
||||
|
||||
# 6. Firewall
|
||||
echo ""
|
||||
echo "6. Firewall Status"
|
||||
echo "------------------"
|
||||
if command -v ufw &>/dev/null && ufw status | grep -q "active"; then
|
||||
check "PASS" "UFW firewall is active"
|
||||
elif command -v firewalld &>/dev/null && systemctl is-active firewalld &>/dev/null; then
|
||||
check "PASS" "firewalld is active"
|
||||
elif iptables -L -n 2>/dev/null | grep -q "DROP\|REJECT"; then
|
||||
check "PASS" "iptables has rules configured"
|
||||
else
|
||||
check "FAIL" "No firewall appears to be active"
|
||||
fi
|
||||
|
||||
# 7. Services
|
||||
echo ""
|
||||
echo "7. Running Services"
|
||||
echo "-------------------"
|
||||
LISTENING=$(ss -tlnp 2>/dev/null | grep -c LISTEN || echo 0)
|
||||
check "WARN" "$LISTENING services listening on ports"
|
||||
|
||||
# Summary
|
||||
echo ""
|
||||
echo "========================================="
|
||||
echo "Audit Summary"
|
||||
echo "========================================="
|
||||
echo -e "Passed: \e[32m$PASS\e[0m"
|
||||
echo -e "Warnings: \e[33m$WARN\e[0m"
|
||||
echo -e "Failed: \e[31m$FAIL\e[0m"
|
||||
echo ""
|
||||
|
||||
if [ "$FAIL" -gt 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
@@ -0,0 +1,131 @@
|
||||
#!/bin/bash
|
||||
# Linux System Hardening Script
|
||||
# Usage: ./harden-system.sh [--apply]
|
||||
# Run without --apply to see what changes would be made
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
APPLY="${1:-}"
|
||||
|
||||
if [ "$APPLY" != "--apply" ]; then
|
||||
echo "DRY RUN MODE - No changes will be made"
|
||||
echo "Run with --apply to make changes"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
apply_change() {
|
||||
if [ "$APPLY" == "--apply" ]; then
|
||||
eval "$1"
|
||||
echo " [APPLIED] $2"
|
||||
else
|
||||
echo " [WOULD APPLY] $2"
|
||||
fi
|
||||
}
|
||||
|
||||
echo "========================================="
|
||||
echo "Linux System Hardening"
|
||||
echo "========================================="
|
||||
echo ""
|
||||
|
||||
# 1. Update system
|
||||
echo "1. System Updates"
|
||||
echo "-----------------"
|
||||
apply_change "apt-get update && apt-get upgrade -y" "Update all packages"
|
||||
|
||||
# 2. Disable unused filesystems
|
||||
echo ""
|
||||
echo "2. Disable Unused Filesystems"
|
||||
echo "------------------------------"
|
||||
FILESYSTEMS="cramfs freevxfs jffs2 hfs hfsplus squashfs udf"
|
||||
for fs in $FILESYSTEMS; do
|
||||
apply_change "echo 'install $fs /bin/true' >> /etc/modprobe.d/disable-filesystems.conf" "Disable $fs"
|
||||
done
|
||||
|
||||
# 3. Kernel parameters
|
||||
echo ""
|
||||
echo "3. Kernel Hardening (sysctl)"
|
||||
echo "----------------------------"
|
||||
SYSCTL_CONF="/etc/sysctl.d/99-hardening.conf"
|
||||
cat << 'EOF' > /tmp/sysctl-hardening.conf
|
||||
# Network security
|
||||
net.ipv4.conf.all.send_redirects = 0
|
||||
net.ipv4.conf.default.send_redirects = 0
|
||||
net.ipv4.conf.all.accept_redirects = 0
|
||||
net.ipv4.conf.default.accept_redirects = 0
|
||||
net.ipv4.conf.all.secure_redirects = 0
|
||||
net.ipv4.conf.default.secure_redirects = 0
|
||||
net.ipv4.conf.all.log_martians = 1
|
||||
net.ipv4.conf.default.log_martians = 1
|
||||
net.ipv4.icmp_echo_ignore_broadcasts = 1
|
||||
net.ipv4.icmp_ignore_bogus_error_responses = 1
|
||||
net.ipv4.conf.all.rp_filter = 1
|
||||
net.ipv4.conf.default.rp_filter = 1
|
||||
net.ipv4.tcp_syncookies = 1
|
||||
|
||||
# IPv6 (disable if not needed)
|
||||
net.ipv6.conf.all.disable_ipv6 = 1
|
||||
net.ipv6.conf.default.disable_ipv6 = 1
|
||||
|
||||
# Kernel hardening
|
||||
kernel.randomize_va_space = 2
|
||||
kernel.kptr_restrict = 2
|
||||
kernel.dmesg_restrict = 1
|
||||
kernel.yama.ptrace_scope = 1
|
||||
EOF
|
||||
apply_change "cp /tmp/sysctl-hardening.conf $SYSCTL_CONF && sysctl -p $SYSCTL_CONF" "Apply kernel hardening parameters"
|
||||
|
||||
# 4. SSH hardening
|
||||
echo ""
|
||||
echo "4. SSH Hardening"
|
||||
echo "----------------"
|
||||
SSH_CONF="/etc/ssh/sshd_config.d/hardening.conf"
|
||||
cat << 'EOF' > /tmp/ssh-hardening.conf
|
||||
PermitRootLogin no
|
||||
PasswordAuthentication no
|
||||
PubkeyAuthentication yes
|
||||
MaxAuthTries 3
|
||||
ClientAliveInterval 300
|
||||
ClientAliveCountMax 2
|
||||
X11Forwarding no
|
||||
AllowAgentForwarding no
|
||||
PermitEmptyPasswords no
|
||||
EOF
|
||||
apply_change "cp /tmp/ssh-hardening.conf $SSH_CONF" "Apply SSH hardening"
|
||||
|
||||
# 5. File permissions
|
||||
echo ""
|
||||
echo "5. File Permissions"
|
||||
echo "-------------------"
|
||||
apply_change "chmod 600 /etc/shadow" "Secure /etc/shadow"
|
||||
apply_change "chmod 644 /etc/passwd" "Secure /etc/passwd"
|
||||
apply_change "chmod 600 /etc/gshadow" "Secure /etc/gshadow"
|
||||
apply_change "chmod 644 /etc/group" "Secure /etc/group"
|
||||
|
||||
# 6. Remove unnecessary packages
|
||||
echo ""
|
||||
echo "6. Remove Unnecessary Services"
|
||||
echo "------------------------------"
|
||||
REMOVE_PKGS="telnet rsh-client rsh-redone-client"
|
||||
for pkg in $REMOVE_PKGS; do
|
||||
apply_change "apt-get remove -y $pkg 2>/dev/null || true" "Remove $pkg"
|
||||
done
|
||||
|
||||
# 7. Configure firewall
|
||||
echo ""
|
||||
echo "7. Enable Firewall"
|
||||
echo "------------------"
|
||||
apply_change "ufw default deny incoming && ufw default allow outgoing && ufw allow ssh && ufw --force enable" "Configure UFW firewall"
|
||||
|
||||
# 8. Enable automatic updates
|
||||
echo ""
|
||||
echo "8. Automatic Security Updates"
|
||||
echo "-----------------------------"
|
||||
apply_change "apt-get install -y unattended-upgrades && dpkg-reconfigure -plow unattended-upgrades" "Enable unattended upgrades"
|
||||
|
||||
echo ""
|
||||
echo "========================================="
|
||||
echo "Hardening script complete"
|
||||
if [ "$APPLY" != "--apply" ]; then
|
||||
echo "Run with --apply to make changes"
|
||||
fi
|
||||
echo "========================================="
|
||||
@@ -0,0 +1,98 @@
|
||||
---
|
||||
name: windows-hardening
|
||||
description: Harden Windows servers per security baselines and CIS benchmarks. Configure Group Policy, Windows Defender, and security features. Use when securing Windows Server environments.
|
||||
license: MIT
|
||||
metadata:
|
||||
author: devops-skills
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# Windows Hardening
|
||||
|
||||
Secure Windows servers following Microsoft security baselines and CIS benchmarks.
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
Use this skill when:
|
||||
- Hardening Windows servers
|
||||
- Implementing security baselines
|
||||
- Meeting compliance requirements
|
||||
- Configuring Windows security features
|
||||
|
||||
## Security Baseline
|
||||
|
||||
```powershell
|
||||
# Download Microsoft Security Baseline
|
||||
# Apply via Group Policy or LGPO tool
|
||||
|
||||
# Install Security Compliance Toolkit
|
||||
Install-Module -Name SecurityPolicyDsc
|
||||
```
|
||||
|
||||
## Account Policies
|
||||
|
||||
```powershell
|
||||
# Password policy via Group Policy
|
||||
# Computer Configuration > Policies > Windows Settings > Security Settings
|
||||
|
||||
# PowerShell alternative
|
||||
net accounts /minpwlen:14 /maxpwage:90 /minpwage:1 /uniquepw:24
|
||||
|
||||
# Disable Administrator account
|
||||
Rename-LocalUser -Name "Administrator" -NewName "LocalAdmin"
|
||||
Disable-LocalUser -Name "Guest"
|
||||
```
|
||||
|
||||
## Windows Firewall
|
||||
|
||||
```powershell
|
||||
# Enable firewall
|
||||
Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled True
|
||||
|
||||
# Default deny
|
||||
Set-NetFirewallProfile -DefaultInboundAction Block -DefaultOutboundAction Allow
|
||||
|
||||
# Allow specific rules
|
||||
New-NetFirewallRule -DisplayName "Allow RDP" -Direction Inbound -Protocol TCP -LocalPort 3389 -Action Allow
|
||||
```
|
||||
|
||||
## Audit Configuration
|
||||
|
||||
```powershell
|
||||
# Enable advanced audit policy
|
||||
auditpol /set /subcategory:"Logon" /success:enable /failure:enable
|
||||
auditpol /set /subcategory:"Account Lockout" /success:enable /failure:enable
|
||||
auditpol /set /subcategory:"Security Group Management" /success:enable
|
||||
|
||||
# Enable PowerShell logging
|
||||
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" -Name "EnableScriptBlockLogging" -Value 1
|
||||
```
|
||||
|
||||
## Windows Defender
|
||||
|
||||
```powershell
|
||||
# Enable real-time protection
|
||||
Set-MpPreference -DisableRealtimeMonitoring $false
|
||||
|
||||
# Enable cloud protection
|
||||
Set-MpPreference -MAPSReporting Advanced
|
||||
|
||||
# Configure scans
|
||||
Set-MpPreference -ScanScheduleDay Everyday
|
||||
Set-MpPreference -ScanScheduleTime 02:00:00
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Apply security baselines
|
||||
- Enable Windows Defender ATP
|
||||
- Configure AppLocker
|
||||
- Disable SMBv1
|
||||
- Enable Credential Guard
|
||||
- Regular Windows updates
|
||||
- Implement LAPS for local admin passwords
|
||||
|
||||
## Related Skills
|
||||
|
||||
- [cis-benchmarks](../cis-benchmarks/) - Compliance scanning
|
||||
- [windows-server](../../../infrastructure/servers/windows-server/) - Server administration
|
||||
@@ -0,0 +1,84 @@
|
||||
---
|
||||
name: firewall-config
|
||||
description: Configure iptables, nftables, and cloud firewalls. Implement network segmentation and traffic filtering. Use when securing network perimeters or implementing security zones.
|
||||
license: MIT
|
||||
metadata:
|
||||
author: devops-skills
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# Firewall Configuration
|
||||
|
||||
Configure host-based and cloud firewalls for network security.
|
||||
|
||||
## iptables
|
||||
|
||||
```bash
|
||||
# Default policies
|
||||
iptables -P INPUT DROP
|
||||
iptables -P FORWARD DROP
|
||||
iptables -P OUTPUT ACCEPT
|
||||
|
||||
# Allow established connections
|
||||
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
|
||||
|
||||
# Allow loopback
|
||||
iptables -A INPUT -i lo -j ACCEPT
|
||||
|
||||
# Allow SSH
|
||||
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
|
||||
|
||||
# Allow HTTP/HTTPS
|
||||
iptables -A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT
|
||||
|
||||
# Save rules
|
||||
iptables-save > /etc/iptables/rules.v4
|
||||
```
|
||||
|
||||
## nftables
|
||||
|
||||
```bash
|
||||
#!/usr/sbin/nft -f
|
||||
flush ruleset
|
||||
|
||||
table inet filter {
|
||||
chain input {
|
||||
type filter hook input priority 0; policy drop;
|
||||
ct state established,related accept
|
||||
iif "lo" accept
|
||||
tcp dport { 22, 80, 443 } accept
|
||||
}
|
||||
|
||||
chain forward {
|
||||
type filter hook forward priority 0; policy drop;
|
||||
}
|
||||
|
||||
chain output {
|
||||
type filter hook output priority 0; policy accept;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## AWS Security Groups
|
||||
|
||||
```bash
|
||||
aws ec2 create-security-group --group-name web-sg --description "Web server SG"
|
||||
|
||||
aws ec2 authorize-security-group-ingress \
|
||||
--group-name web-sg \
|
||||
--protocol tcp --port 443 \
|
||||
--cidr 0.0.0.0/0
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Default deny policy
|
||||
- Minimal rule sets
|
||||
- Regular rule audits
|
||||
- Log denied traffic
|
||||
- Document all rules
|
||||
|
||||
## Related Skills
|
||||
|
||||
- [linux-hardening](../../hardening/linux-hardening/) - System security
|
||||
- [aws-vpc](../../../infrastructure/cloud-aws/aws-vpc/) - AWS networking
|
||||
@@ -0,0 +1,103 @@
|
||||
#!/bin/bash
|
||||
# iptables Firewall Rules Template
|
||||
# Customize and apply with: bash iptables-rules.sh
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Flush existing rules
|
||||
iptables -F
|
||||
iptables -X
|
||||
iptables -t nat -F
|
||||
iptables -t nat -X
|
||||
|
||||
# Set default policies
|
||||
iptables -P INPUT DROP
|
||||
iptables -P FORWARD DROP
|
||||
iptables -P OUTPUT ACCEPT
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# LOOPBACK
|
||||
#------------------------------------------------------------------------------
|
||||
iptables -A INPUT -i lo -j ACCEPT
|
||||
iptables -A OUTPUT -o lo -j ACCEPT
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# ESTABLISHED CONNECTIONS
|
||||
#------------------------------------------------------------------------------
|
||||
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
|
||||
iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# INVALID PACKETS
|
||||
#------------------------------------------------------------------------------
|
||||
iptables -A INPUT -m conntrack --ctstate INVALID -j DROP
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# ICMP (Ping)
|
||||
#------------------------------------------------------------------------------
|
||||
# Allow ping (optional - comment out to disable)
|
||||
iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/s -j ACCEPT
|
||||
iptables -A INPUT -p icmp --icmp-type echo-reply -j ACCEPT
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# SSH (Rate Limited)
|
||||
#------------------------------------------------------------------------------
|
||||
iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -m recent --set --name SSH
|
||||
iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -m recent --update --seconds 60 --hitcount 4 --name SSH -j DROP
|
||||
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# WEB SERVICES (Uncomment as needed)
|
||||
#------------------------------------------------------------------------------
|
||||
# HTTP
|
||||
# iptables -A INPUT -p tcp --dport 80 -j ACCEPT
|
||||
|
||||
# HTTPS
|
||||
# iptables -A INPUT -p tcp --dport 443 -j ACCEPT
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# APPLICATION PORTS (Customize)
|
||||
#------------------------------------------------------------------------------
|
||||
# Application (example: 8080)
|
||||
# iptables -A INPUT -p tcp --dport 8080 -j ACCEPT
|
||||
|
||||
# From specific network only
|
||||
# iptables -A INPUT -s 10.0.0.0/8 -p tcp --dport 8080 -j ACCEPT
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# DATABASE (Internal Only)
|
||||
#------------------------------------------------------------------------------
|
||||
# PostgreSQL from internal network
|
||||
# iptables -A INPUT -s 10.0.0.0/8 -p tcp --dport 5432 -j ACCEPT
|
||||
|
||||
# MySQL from internal network
|
||||
# iptables -A INPUT -s 10.0.0.0/8 -p tcp --dport 3306 -j ACCEPT
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# MONITORING
|
||||
#------------------------------------------------------------------------------
|
||||
# Prometheus metrics
|
||||
# iptables -A INPUT -s 10.0.0.0/8 -p tcp --dport 9090 -j ACCEPT
|
||||
|
||||
# Node exporter
|
||||
# iptables -A INPUT -s 10.0.0.0/8 -p tcp --dport 9100 -j ACCEPT
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# LOGGING
|
||||
#------------------------------------------------------------------------------
|
||||
# Log dropped packets (before final DROP)
|
||||
iptables -A INPUT -j LOG --log-prefix "iptables-dropped: " --log-level 4 -m limit --limit 5/min
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# FINAL DROP (Implicit with policy, but explicit for clarity)
|
||||
#------------------------------------------------------------------------------
|
||||
iptables -A INPUT -j DROP
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# SAVE RULES
|
||||
#------------------------------------------------------------------------------
|
||||
echo "Saving rules..."
|
||||
iptables-save > /etc/iptables/rules.v4 2>/dev/null || iptables-save > /tmp/iptables-rules.v4
|
||||
|
||||
echo "Firewall configured successfully!"
|
||||
iptables -L -n -v
|
||||
@@ -0,0 +1,127 @@
|
||||
# iptables Reference Guide
|
||||
|
||||
## Chain Overview
|
||||
|
||||
```
|
||||
PREROUTING
|
||||
│
|
||||
▼
|
||||
┌─────────┐
|
||||
│ ROUTING │
|
||||
└────┬────┘
|
||||
│
|
||||
┌────────────┼────────────┐
|
||||
│ │ │
|
||||
▼ ▼ ▼
|
||||
INPUT FORWARD OUTPUT
|
||||
│ │ │
|
||||
▼ │ ▼
|
||||
Local Process │ Local Process
|
||||
│
|
||||
▼
|
||||
POSTROUTING
|
||||
```
|
||||
|
||||
## Tables
|
||||
|
||||
| Table | Purpose | Chains |
|
||||
|-------|---------|--------|
|
||||
| filter | Default, packet filtering | INPUT, FORWARD, OUTPUT |
|
||||
| nat | Network Address Translation | PREROUTING, OUTPUT, POSTROUTING |
|
||||
| mangle | Packet alteration | All chains |
|
||||
| raw | Connection tracking exemption | PREROUTING, OUTPUT |
|
||||
|
||||
## Basic Commands
|
||||
|
||||
```bash
|
||||
# List rules
|
||||
iptables -L -n -v # All filter rules
|
||||
iptables -L INPUT -n -v # INPUT chain only
|
||||
iptables -t nat -L -n -v # NAT table
|
||||
|
||||
# Add rules
|
||||
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
|
||||
iptables -I INPUT 1 -p tcp --dport 80 -j ACCEPT # Insert at position 1
|
||||
|
||||
# Delete rules
|
||||
iptables -D INPUT -p tcp --dport 22 -j ACCEPT
|
||||
iptables -D INPUT 3 # Delete rule #3
|
||||
|
||||
# Flush rules
|
||||
iptables -F # Flush all filter rules
|
||||
iptables -t nat -F # Flush NAT rules
|
||||
|
||||
# Set policy
|
||||
iptables -P INPUT DROP
|
||||
iptables -P FORWARD DROP
|
||||
iptables -P OUTPUT ACCEPT
|
||||
```
|
||||
|
||||
## Common Rules
|
||||
|
||||
### Allow Established Connections
|
||||
```bash
|
||||
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
|
||||
```
|
||||
|
||||
### Allow Loopback
|
||||
```bash
|
||||
iptables -A INPUT -i lo -j ACCEPT
|
||||
iptables -A OUTPUT -o lo -j ACCEPT
|
||||
```
|
||||
|
||||
### Allow SSH
|
||||
```bash
|
||||
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
|
||||
|
||||
# Rate limit SSH
|
||||
iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -m recent --set
|
||||
iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -m recent --update --seconds 60 --hitcount 4 -j DROP
|
||||
```
|
||||
|
||||
### Allow Web Traffic
|
||||
```bash
|
||||
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
|
||||
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
|
||||
```
|
||||
|
||||
### Allow from Specific IP/Network
|
||||
```bash
|
||||
iptables -A INPUT -s 192.168.1.0/24 -j ACCEPT
|
||||
iptables -A INPUT -s 10.0.0.5 -p tcp --dport 5432 -j ACCEPT
|
||||
```
|
||||
|
||||
### Block IP
|
||||
```bash
|
||||
iptables -A INPUT -s 1.2.3.4 -j DROP
|
||||
```
|
||||
|
||||
### Log Dropped Packets
|
||||
```bash
|
||||
iptables -A INPUT -j LOG --log-prefix "IPTables-Dropped: " --log-level 4
|
||||
iptables -A INPUT -j DROP
|
||||
```
|
||||
|
||||
## NAT Rules
|
||||
|
||||
### SNAT (Source NAT)
|
||||
```bash
|
||||
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
|
||||
```
|
||||
|
||||
### DNAT (Destination NAT / Port Forwarding)
|
||||
```bash
|
||||
iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.1.10:8080
|
||||
```
|
||||
|
||||
## Save/Restore
|
||||
|
||||
```bash
|
||||
# Save rules
|
||||
iptables-save > /etc/iptables/rules.v4
|
||||
ip6tables-save > /etc/iptables/rules.v6
|
||||
|
||||
# Restore rules
|
||||
iptables-restore < /etc/iptables/rules.v4
|
||||
ip6tables-restore < /etc/iptables/rules.v6
|
||||
```
|
||||
@@ -0,0 +1,91 @@
|
||||
#!/bin/bash
|
||||
# Firewall Configuration Audit Script
|
||||
# Usage: ./firewall-audit.sh
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
echo "========================================="
|
||||
echo "Firewall Configuration Audit"
|
||||
echo "========================================="
|
||||
echo ""
|
||||
|
||||
# Detect firewall type
|
||||
if command -v ufw &>/dev/null; then
|
||||
FIREWALL="ufw"
|
||||
elif command -v firewall-cmd &>/dev/null; then
|
||||
FIREWALL="firewalld"
|
||||
elif command -v nft &>/dev/null; then
|
||||
FIREWALL="nftables"
|
||||
else
|
||||
FIREWALL="iptables"
|
||||
fi
|
||||
|
||||
echo "Detected Firewall: $FIREWALL"
|
||||
echo ""
|
||||
|
||||
case "$FIREWALL" in
|
||||
ufw)
|
||||
echo "UFW Status:"
|
||||
echo "----------"
|
||||
ufw status verbose
|
||||
echo ""
|
||||
echo "UFW Rules (numbered):"
|
||||
echo "--------------------"
|
||||
ufw status numbered
|
||||
echo ""
|
||||
echo "UFW Application Profiles:"
|
||||
echo "------------------------"
|
||||
ufw app list
|
||||
;;
|
||||
|
||||
firewalld)
|
||||
echo "Firewalld Status:"
|
||||
echo "----------------"
|
||||
firewall-cmd --state
|
||||
echo ""
|
||||
echo "Active Zones:"
|
||||
echo "-------------"
|
||||
firewall-cmd --get-active-zones
|
||||
echo ""
|
||||
echo "Default Zone: $(firewall-cmd --get-default-zone)"
|
||||
echo ""
|
||||
echo "All Zone Rules:"
|
||||
echo "--------------"
|
||||
for zone in $(firewall-cmd --get-zones); do
|
||||
echo "--- Zone: $zone ---"
|
||||
firewall-cmd --zone=$zone --list-all 2>/dev/null || true
|
||||
echo ""
|
||||
done
|
||||
;;
|
||||
|
||||
nftables)
|
||||
echo "nftables Ruleset:"
|
||||
echo "----------------"
|
||||
nft list ruleset
|
||||
;;
|
||||
|
||||
iptables)
|
||||
echo "iptables Rules (Filter):"
|
||||
echo "-----------------------"
|
||||
iptables -L -n -v --line-numbers
|
||||
echo ""
|
||||
echo "iptables Rules (NAT):"
|
||||
echo "--------------------"
|
||||
iptables -t nat -L -n -v --line-numbers 2>/dev/null || true
|
||||
echo ""
|
||||
echo "ip6tables Rules:"
|
||||
echo "---------------"
|
||||
ip6tables -L -n -v --line-numbers 2>/dev/null || true
|
||||
;;
|
||||
esac
|
||||
|
||||
echo ""
|
||||
echo "========================================="
|
||||
echo "Open Ports (listening):"
|
||||
echo "========================================="
|
||||
ss -tlnp 2>/dev/null || netstat -tlnp
|
||||
|
||||
echo ""
|
||||
echo "========================================="
|
||||
echo "Audit complete"
|
||||
echo "========================================="
|
||||
@@ -0,0 +1,80 @@
|
||||
#!/bin/bash
|
||||
# UFW Firewall Setup Script
|
||||
# Usage: ./setup-ufw.sh [--apply]
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
APPLY="${1:-}"
|
||||
|
||||
if [ "$APPLY" != "--apply" ]; then
|
||||
echo "DRY RUN MODE - showing commands only"
|
||||
echo "Run with --apply to execute"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
run_cmd() {
|
||||
if [ "$APPLY" == "--apply" ]; then
|
||||
eval "$1"
|
||||
else
|
||||
echo "[DRY RUN] $1"
|
||||
fi
|
||||
}
|
||||
|
||||
echo "========================================="
|
||||
echo "UFW Firewall Setup"
|
||||
echo "========================================="
|
||||
echo ""
|
||||
|
||||
# Reset UFW
|
||||
echo "Resetting UFW to defaults..."
|
||||
run_cmd "ufw --force reset"
|
||||
|
||||
# Set default policies
|
||||
echo ""
|
||||
echo "Setting default policies..."
|
||||
run_cmd "ufw default deny incoming"
|
||||
run_cmd "ufw default allow outgoing"
|
||||
|
||||
# Essential services
|
||||
echo ""
|
||||
echo "Allowing essential services..."
|
||||
|
||||
# SSH (rate limited)
|
||||
run_cmd "ufw limit ssh comment 'SSH with rate limiting'"
|
||||
|
||||
# Common services (uncomment as needed)
|
||||
echo ""
|
||||
echo "Common service rules (customize as needed):"
|
||||
|
||||
# Web server
|
||||
# run_cmd "ufw allow 80/tcp comment 'HTTP'"
|
||||
# run_cmd "ufw allow 443/tcp comment 'HTTPS'"
|
||||
|
||||
# Database (restrict to specific IPs)
|
||||
# run_cmd "ufw allow from 10.0.0.0/8 to any port 5432 comment 'PostgreSQL from internal'"
|
||||
# run_cmd "ufw allow from 10.0.0.0/8 to any port 3306 comment 'MySQL from internal'"
|
||||
|
||||
# Application ports
|
||||
# run_cmd "ufw allow 8080/tcp comment 'Application'"
|
||||
|
||||
# Enable logging
|
||||
echo ""
|
||||
echo "Enabling logging..."
|
||||
run_cmd "ufw logging medium"
|
||||
|
||||
# Enable firewall
|
||||
echo ""
|
||||
echo "Enabling UFW..."
|
||||
run_cmd "ufw --force enable"
|
||||
|
||||
# Show status
|
||||
echo ""
|
||||
echo "Final status:"
|
||||
if [ "$APPLY" == "--apply" ]; then
|
||||
ufw status verbose
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "========================================="
|
||||
echo "Setup complete"
|
||||
echo "========================================="
|
||||
@@ -0,0 +1,96 @@
|
||||
---
|
||||
name: ssl-tls-management
|
||||
description: Manage SSL/TLS certificates with Let's Encrypt and internal PKI. Configure secure HTTPS, certificate renewal, and cipher suites. Use when implementing secure communications.
|
||||
license: MIT
|
||||
metadata:
|
||||
author: devops-skills
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# SSL/TLS Management
|
||||
|
||||
Manage certificates and secure communications.
|
||||
|
||||
## Let's Encrypt (Certbot)
|
||||
|
||||
```bash
|
||||
# Install
|
||||
apt install certbot python3-certbot-nginx
|
||||
|
||||
# Get certificate
|
||||
certbot --nginx -d example.com -d www.example.com
|
||||
|
||||
# Auto-renewal
|
||||
certbot renew --dry-run
|
||||
# Cron: 0 0 * * * certbot renew --quiet
|
||||
```
|
||||
|
||||
## cert-manager (Kubernetes)
|
||||
|
||||
```yaml
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: ClusterIssuer
|
||||
metadata:
|
||||
name: letsencrypt-prod
|
||||
spec:
|
||||
acme:
|
||||
server: https://acme-v02.api.letsencrypt.org/directory
|
||||
email: admin@example.com
|
||||
privateKeySecretRef:
|
||||
name: letsencrypt-prod
|
||||
solvers:
|
||||
- http01:
|
||||
ingress:
|
||||
class: nginx
|
||||
---
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: Certificate
|
||||
metadata:
|
||||
name: example-cert
|
||||
spec:
|
||||
secretName: example-tls
|
||||
issuerRef:
|
||||
name: letsencrypt-prod
|
||||
kind: ClusterIssuer
|
||||
dnsNames:
|
||||
- example.com
|
||||
```
|
||||
|
||||
## Strong Configuration
|
||||
|
||||
```nginx
|
||||
# nginx ssl config
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
|
||||
ssl_prefer_server_ciphers off;
|
||||
ssl_session_timeout 1d;
|
||||
ssl_session_cache shared:SSL:10m;
|
||||
ssl_stapling on;
|
||||
ssl_stapling_verify on;
|
||||
|
||||
add_header Strict-Transport-Security "max-age=63072000" always;
|
||||
```
|
||||
|
||||
## Certificate Monitoring
|
||||
|
||||
```bash
|
||||
# Check expiration
|
||||
openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | \
|
||||
openssl x509 -noout -dates
|
||||
|
||||
# Check certificate chain
|
||||
openssl s_client -connect example.com:443 -showcerts
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Automate renewal
|
||||
- Monitor expiration
|
||||
- Use strong ciphers
|
||||
- Enable HSTS
|
||||
- Regular security audits
|
||||
|
||||
## Related Skills
|
||||
|
||||
- [hashicorp-vault](../../secrets/hashicorp-vault/) - PKI management
|
||||
- [waf-setup](../waf-setup/) - Web protection
|
||||
@@ -0,0 +1,75 @@
|
||||
---
|
||||
name: vpn-setup
|
||||
description: Configure WireGuard, OpenVPN, and cloud VPNs. Implement secure remote access and site-to-site connectivity. Use when setting up secure network tunnels.
|
||||
license: MIT
|
||||
metadata:
|
||||
author: devops-skills
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# VPN Setup
|
||||
|
||||
Configure secure VPN tunnels for remote access and site connectivity.
|
||||
|
||||
## WireGuard
|
||||
|
||||
```bash
|
||||
# Generate keys
|
||||
wg genkey | tee privatekey | wg pubkey > publickey
|
||||
|
||||
# Server config (/etc/wireguard/wg0.conf)
|
||||
[Interface]
|
||||
Address = 10.0.0.1/24
|
||||
ListenPort = 51820
|
||||
PrivateKey = <server-private-key>
|
||||
|
||||
[Peer]
|
||||
PublicKey = <client-public-key>
|
||||
AllowedIPs = 10.0.0.2/32
|
||||
|
||||
# Enable
|
||||
wg-quick up wg0
|
||||
systemctl enable wg-quick@wg0
|
||||
```
|
||||
|
||||
## OpenVPN
|
||||
|
||||
```bash
|
||||
# Install
|
||||
apt install openvpn easy-rsa
|
||||
|
||||
# Generate certificates
|
||||
cd /etc/openvpn/easy-rsa
|
||||
./easyrsa init-pki
|
||||
./easyrsa build-ca
|
||||
./easyrsa gen-req server nopass
|
||||
./easyrsa sign-req server server
|
||||
./easyrsa gen-dh
|
||||
```
|
||||
|
||||
## AWS Site-to-Site VPN
|
||||
|
||||
```bash
|
||||
aws ec2 create-vpn-gateway --type ipsec.1
|
||||
aws ec2 create-customer-gateway \
|
||||
--type ipsec.1 \
|
||||
--bgp-asn 65000 \
|
||||
--public-ip <on-prem-ip>
|
||||
aws ec2 create-vpn-connection \
|
||||
--type ipsec.1 \
|
||||
--customer-gateway-id cgw-xxx \
|
||||
--vpn-gateway-id vgw-xxx
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Use WireGuard for modern deployments
|
||||
- Implement MFA for VPN access
|
||||
- Regular key rotation
|
||||
- Monitor VPN connections
|
||||
- Segment VPN access by role
|
||||
|
||||
## Related Skills
|
||||
|
||||
- [zero-trust](../zero-trust/) - Modern access patterns
|
||||
- [ssl-tls-management](../ssl-tls-management/) - Certificate management
|
||||
@@ -0,0 +1,79 @@
|
||||
---
|
||||
name: waf-setup
|
||||
description: Deploy and tune Web Application Firewalls. Configure rules for OWASP Top 10 protection. Use when protecting web applications from common attacks.
|
||||
license: MIT
|
||||
metadata:
|
||||
author: devops-skills
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# WAF Setup
|
||||
|
||||
Protect web applications with Web Application Firewalls.
|
||||
|
||||
## AWS WAF
|
||||
|
||||
```bash
|
||||
# Create Web ACL
|
||||
aws wafv2 create-web-acl \
|
||||
--name my-waf \
|
||||
--scope REGIONAL \
|
||||
--default-action Allow={} \
|
||||
--rules file://rules.json
|
||||
|
||||
# Associate with ALB
|
||||
aws wafv2 associate-web-acl \
|
||||
--web-acl-arn arn:aws:wafv2:... \
|
||||
--resource-arn arn:aws:elasticloadbalancing:...
|
||||
```
|
||||
|
||||
## ModSecurity (nginx)
|
||||
|
||||
```nginx
|
||||
# nginx.conf
|
||||
load_module modules/ngx_http_modsecurity_module.so;
|
||||
|
||||
server {
|
||||
modsecurity on;
|
||||
modsecurity_rules_file /etc/nginx/modsec/main.conf;
|
||||
}
|
||||
```
|
||||
|
||||
```bash
|
||||
# Install OWASP CRS
|
||||
git clone https://github.com/coreruleset/coreruleset /etc/nginx/modsec/crs
|
||||
```
|
||||
|
||||
## Cloudflare WAF
|
||||
|
||||
```bash
|
||||
# Enable managed rules via API
|
||||
curl -X PUT "https://api.cloudflare.com/client/v4/zones/{zone}/firewall/waf/packages/{package}/rules/{rule}" \
|
||||
-H "Authorization: Bearer $TOKEN" \
|
||||
-d '{"mode":"block"}'
|
||||
```
|
||||
|
||||
## Common Rules
|
||||
|
||||
```yaml
|
||||
protections:
|
||||
- SQL Injection (SQLi)
|
||||
- Cross-Site Scripting (XSS)
|
||||
- Remote File Inclusion (RFI)
|
||||
- Local File Inclusion (LFI)
|
||||
- Command Injection
|
||||
- Cross-Site Request Forgery (CSRF)
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Start in detection mode
|
||||
- Tune for false positives
|
||||
- Monitor blocked requests
|
||||
- Regular rule updates
|
||||
- Custom rules for app-specific attacks
|
||||
|
||||
## Related Skills
|
||||
|
||||
- [dast-scanning](../../scanning/dast-scanning/) - Web security testing
|
||||
- [ssl-tls-management](../ssl-tls-management/) - HTTPS configuration
|
||||
@@ -0,0 +1,120 @@
|
||||
# WAF Rules Reference
|
||||
|
||||
## AWS WAF
|
||||
|
||||
### Managed Rules
|
||||
```hcl
|
||||
resource "aws_wafv2_web_acl" "main" {
|
||||
name = "myapp-waf"
|
||||
scope = "REGIONAL"
|
||||
|
||||
default_action {
|
||||
allow {}
|
||||
}
|
||||
|
||||
# AWS Managed Rules - Core
|
||||
rule {
|
||||
name = "AWSManagedRulesCommonRuleSet"
|
||||
priority = 1
|
||||
override_action { none {} }
|
||||
|
||||
statement {
|
||||
managed_rule_group_statement {
|
||||
vendor_name = "AWS"
|
||||
name = "AWSManagedRulesCommonRuleSet"
|
||||
}
|
||||
}
|
||||
visibility_config {
|
||||
cloudwatch_metrics_enabled = true
|
||||
metric_name = "CommonRuleSet"
|
||||
sampled_requests_enabled = true
|
||||
}
|
||||
}
|
||||
|
||||
# SQL Injection
|
||||
rule {
|
||||
name = "AWSManagedRulesSQLiRuleSet"
|
||||
priority = 2
|
||||
override_action { none {} }
|
||||
|
||||
statement {
|
||||
managed_rule_group_statement {
|
||||
vendor_name = "AWS"
|
||||
name = "AWSManagedRulesSQLiRuleSet"
|
||||
}
|
||||
}
|
||||
visibility_config {
|
||||
cloudwatch_metrics_enabled = true
|
||||
metric_name = "SQLiRuleSet"
|
||||
sampled_requests_enabled = true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Custom Rules
|
||||
```hcl
|
||||
# Rate limiting
|
||||
rule {
|
||||
name = "RateLimit"
|
||||
priority = 0
|
||||
action { block {} }
|
||||
|
||||
statement {
|
||||
rate_based_statement {
|
||||
limit = 2000
|
||||
aggregate_key_type = "IP"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Geo blocking
|
||||
rule {
|
||||
name = "GeoBlock"
|
||||
priority = 3
|
||||
action { block {} }
|
||||
|
||||
statement {
|
||||
geo_match_statement {
|
||||
country_codes = ["CN", "RU"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Cloudflare WAF
|
||||
|
||||
```hcl
|
||||
resource "cloudflare_ruleset" "waf" {
|
||||
zone_id = var.zone_id
|
||||
name = "WAF Rules"
|
||||
kind = "zone"
|
||||
phase = "http_request_firewall_managed"
|
||||
|
||||
rules {
|
||||
action = "execute"
|
||||
action_parameters {
|
||||
id = "efb7b8c949ac4650a09736fc376e9aee" # OWASP Core Ruleset
|
||||
}
|
||||
expression = "true"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Common Attack Patterns
|
||||
|
||||
| Pattern | Description | Rule |
|
||||
|---------|-------------|------|
|
||||
| SQLi | SQL Injection | Block `' OR 1=1`, UNION |
|
||||
| XSS | Cross-Site Scripting | Block `<script>`, event handlers |
|
||||
| LFI | Local File Inclusion | Block `../`, `/etc/passwd` |
|
||||
| RCE | Remote Code Execution | Block shell commands |
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. Start in monitoring mode
|
||||
2. Tune rules for false positives
|
||||
3. Use rate limiting
|
||||
4. Block known bad IPs
|
||||
5. Log all blocked requests
|
||||
6. Regular rule review
|
||||
@@ -0,0 +1,86 @@
|
||||
---
|
||||
name: zero-trust
|
||||
description: Implement zero-trust network architecture. Configure identity-based access, micro-segmentation, and continuous verification. Use when implementing modern security architectures.
|
||||
license: MIT
|
||||
metadata:
|
||||
author: devops-skills
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# Zero Trust Architecture
|
||||
|
||||
Implement "never trust, always verify" security model.
|
||||
|
||||
## Core Principles
|
||||
|
||||
```yaml
|
||||
zero_trust_principles:
|
||||
- Verify explicitly (authenticate all access)
|
||||
- Least privilege access
|
||||
- Assume breach (micro-segmentation)
|
||||
- Continuous validation
|
||||
- End-to-end encryption
|
||||
```
|
||||
|
||||
## Identity-Based Access
|
||||
|
||||
```yaml
|
||||
# Service mesh mTLS
|
||||
apiVersion: security.istio.io/v1beta1
|
||||
kind: PeerAuthentication
|
||||
metadata:
|
||||
name: default
|
||||
spec:
|
||||
mtls:
|
||||
mode: STRICT
|
||||
---
|
||||
apiVersion: security.istio.io/v1beta1
|
||||
kind: AuthorizationPolicy
|
||||
metadata:
|
||||
name: frontend-to-backend
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: backend
|
||||
rules:
|
||||
- from:
|
||||
- source:
|
||||
principals: ["cluster.local/ns/default/sa/frontend"]
|
||||
```
|
||||
|
||||
## Network Segmentation
|
||||
|
||||
```yaml
|
||||
# Kubernetes Network Policy
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: deny-all
|
||||
spec:
|
||||
podSelector: {}
|
||||
policyTypes:
|
||||
- Ingress
|
||||
- Egress
|
||||
```
|
||||
|
||||
## Implementation Steps
|
||||
|
||||
1. Identify sensitive resources
|
||||
2. Map access patterns
|
||||
3. Implement strong authentication
|
||||
4. Apply micro-segmentation
|
||||
5. Enable logging and monitoring
|
||||
6. Continuous verification
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Identity-aware proxies
|
||||
- Device trust verification
|
||||
- Context-based access
|
||||
- Encrypted communications
|
||||
- Continuous monitoring
|
||||
|
||||
## Related Skills
|
||||
|
||||
- [service-mesh](../../../infrastructure/networking/service-mesh/) - mTLS implementation
|
||||
- [kubernetes-hardening](../../hardening/kubernetes-hardening/) - K8s security
|
||||
@@ -0,0 +1,96 @@
|
||||
---
|
||||
name: incident-response
|
||||
description: Handle security incidents with IR playbooks and procedures. Implement detection, containment, eradication, and recovery processes. Use when responding to security events or building incident response capabilities.
|
||||
license: MIT
|
||||
metadata:
|
||||
author: devops-skills
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# Incident Response
|
||||
|
||||
Handle security incidents effectively with structured response procedures.
|
||||
|
||||
## Incident Response Phases
|
||||
|
||||
```yaml
|
||||
phases:
|
||||
1_preparation:
|
||||
- IR team and contacts
|
||||
- Tools and access ready
|
||||
- Playbooks documented
|
||||
|
||||
2_detection:
|
||||
- Alert triage
|
||||
- Initial assessment
|
||||
- Severity classification
|
||||
|
||||
3_containment:
|
||||
- Short-term containment
|
||||
- Evidence preservation
|
||||
- System isolation
|
||||
|
||||
4_eradication:
|
||||
- Root cause analysis
|
||||
- Remove threat
|
||||
- Patch vulnerabilities
|
||||
|
||||
5_recovery:
|
||||
- System restoration
|
||||
- Monitoring enhanced
|
||||
- Business continuity
|
||||
|
||||
6_lessons_learned:
|
||||
- Post-incident review
|
||||
- Documentation update
|
||||
- Process improvement
|
||||
```
|
||||
|
||||
## Severity Classification
|
||||
|
||||
| Level | Impact | Response Time |
|
||||
|-------|--------|---------------|
|
||||
| Critical | Data breach, full outage | Immediate |
|
||||
| High | Service degraded, potential breach | < 1 hour |
|
||||
| Medium | Limited impact, contained | < 4 hours |
|
||||
| Low | Minimal impact | Next business day |
|
||||
|
||||
## Initial Response Checklist
|
||||
|
||||
```markdown
|
||||
- [ ] Confirm incident is real (not false positive)
|
||||
- [ ] Classify severity level
|
||||
- [ ] Notify IR team
|
||||
- [ ] Begin documentation
|
||||
- [ ] Preserve evidence
|
||||
- [ ] Implement containment
|
||||
- [ ] Communicate to stakeholders
|
||||
```
|
||||
|
||||
## Evidence Collection
|
||||
|
||||
```bash
|
||||
# System state
|
||||
ps aux > /evidence/processes.txt
|
||||
netstat -tuln > /evidence/connections.txt
|
||||
last -a > /evidence/logins.txt
|
||||
|
||||
# Memory dump
|
||||
dd if=/dev/mem of=/evidence/memory.dump
|
||||
|
||||
# Log preservation
|
||||
tar czf /evidence/logs.tar.gz /var/log/
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Pre-defined playbooks
|
||||
- Regular IR drills
|
||||
- Clear communication channels
|
||||
- Legal team involvement
|
||||
- Post-incident reviews
|
||||
|
||||
## Related Skills
|
||||
|
||||
- [audit-logging](../../../compliance/auditing/audit-logging/) - Log analysis
|
||||
- [alerting-oncall](../../../devops/observability/alerting-oncall/) - Alert management
|
||||
@@ -0,0 +1,155 @@
|
||||
# Incident Report: [INCIDENT-ID]
|
||||
|
||||
## Executive Summary
|
||||
|
||||
| Field | Value |
|
||||
|-------|-------|
|
||||
| **Incident ID** | INC-YYYY-MMDD-XXX |
|
||||
| **Status** | Open / Contained / Resolved |
|
||||
| **Severity** | SEV1 / SEV2 / SEV3 / SEV4 |
|
||||
| **Incident Commander** | [Name] |
|
||||
| **Detection Time** | YYYY-MM-DD HH:MM UTC |
|
||||
| **Resolution Time** | YYYY-MM-DD HH:MM UTC |
|
||||
| **Duration** | X hours Y minutes |
|
||||
|
||||
**Summary:** [1-2 sentence description of the incident]
|
||||
|
||||
---
|
||||
|
||||
## Timeline
|
||||
|
||||
| Time (UTC) | Event |
|
||||
|------------|-------|
|
||||
| YYYY-MM-DD HH:MM | [Event description] |
|
||||
| YYYY-MM-DD HH:MM | [Event description] |
|
||||
| YYYY-MM-DD HH:MM | [Event description] |
|
||||
|
||||
---
|
||||
|
||||
## Impact Assessment
|
||||
|
||||
### Systems Affected
|
||||
- [ ] System 1 - [Impact description]
|
||||
- [ ] System 2 - [Impact description]
|
||||
|
||||
### Data Affected
|
||||
- [ ] Type of data
|
||||
- [ ] Volume
|
||||
- [ ] Sensitivity classification
|
||||
|
||||
### Users Affected
|
||||
- Number of users: [X]
|
||||
- User groups: [Groups]
|
||||
|
||||
### Business Impact
|
||||
- [ ] Service downtime: [Duration]
|
||||
- [ ] Financial impact: [Estimate]
|
||||
- [ ] Reputation impact: [Assessment]
|
||||
|
||||
---
|
||||
|
||||
## Root Cause Analysis
|
||||
|
||||
### Attack Vector
|
||||
[Description of how the incident occurred]
|
||||
|
||||
### Contributing Factors
|
||||
1. [Factor 1]
|
||||
2. [Factor 2]
|
||||
3. [Factor 3]
|
||||
|
||||
### Root Cause
|
||||
[Description of the underlying cause]
|
||||
|
||||
---
|
||||
|
||||
## Indicators of Compromise (IOCs)
|
||||
|
||||
### IP Addresses
|
||||
```
|
||||
X.X.X.X - [Description]
|
||||
```
|
||||
|
||||
### Domains
|
||||
```
|
||||
malicious.domain.com - [Description]
|
||||
```
|
||||
|
||||
### File Hashes
|
||||
```
|
||||
SHA256: [hash] - [Filename]
|
||||
```
|
||||
|
||||
### Other IOCs
|
||||
[Any other relevant indicators]
|
||||
|
||||
---
|
||||
|
||||
## Response Actions
|
||||
|
||||
### Containment
|
||||
- [x] Action 1
|
||||
- [x] Action 2
|
||||
- [ ] Action 3 (in progress)
|
||||
|
||||
### Eradication
|
||||
- [ ] Action 1
|
||||
- [ ] Action 2
|
||||
|
||||
### Recovery
|
||||
- [ ] Action 1
|
||||
- [ ] Action 2
|
||||
|
||||
---
|
||||
|
||||
## Lessons Learned
|
||||
|
||||
### What Went Well
|
||||
1. [Item 1]
|
||||
2. [Item 2]
|
||||
|
||||
### What Could Be Improved
|
||||
1. [Item 1]
|
||||
2. [Item 2]
|
||||
|
||||
---
|
||||
|
||||
## Action Items
|
||||
|
||||
| ID | Action | Owner | Due Date | Status |
|
||||
|----|--------|-------|----------|--------|
|
||||
| 1 | [Action description] | [Name] | YYYY-MM-DD | Open |
|
||||
| 2 | [Action description] | [Name] | YYYY-MM-DD | Open |
|
||||
|
||||
---
|
||||
|
||||
## Notifications
|
||||
|
||||
### Internal
|
||||
- [ ] Security Team
|
||||
- [ ] Engineering Team
|
||||
- [ ] Executive Team
|
||||
- [ ] Legal/Compliance
|
||||
|
||||
### External
|
||||
- [ ] Affected customers
|
||||
- [ ] Regulatory bodies
|
||||
- [ ] Law enforcement
|
||||
|
||||
---
|
||||
|
||||
## Appendix
|
||||
|
||||
### Evidence Files
|
||||
- [Link to evidence archive]
|
||||
- [Link to log exports]
|
||||
|
||||
### Related Documents
|
||||
- [Link to runbook used]
|
||||
- [Link to previous incidents]
|
||||
|
||||
---
|
||||
|
||||
**Report Author:** [Name]
|
||||
**Report Date:** YYYY-MM-DD
|
||||
**Last Updated:** YYYY-MM-DD
|
||||
@@ -0,0 +1,147 @@
|
||||
# Incident Response Playbook
|
||||
|
||||
## Incident Severity Levels
|
||||
|
||||
| Level | Name | Description | Response Time | Example |
|
||||
|-------|------|-------------|---------------|---------|
|
||||
| SEV1 | Critical | Active breach, data exfiltration | Immediate | Ransomware, active attacker |
|
||||
| SEV2 | High | Confirmed compromise, contained | 1 hour | Malware, credential theft |
|
||||
| SEV3 | Medium | Suspicious activity, potential threat | 4 hours | Phishing success, anomaly |
|
||||
| SEV4 | Low | Minor security event | 24 hours | Policy violation |
|
||||
|
||||
## Response Phases
|
||||
|
||||
### 1. Detection & Triage (0-15 minutes)
|
||||
|
||||
```
|
||||
□ Confirm the incident is real (not false positive)
|
||||
□ Assess initial scope and severity
|
||||
□ Assign Incident Commander
|
||||
□ Open incident channel (#incident-YYYY-MM-DD)
|
||||
□ Start incident timeline documentation
|
||||
```
|
||||
|
||||
**Key Questions:**
|
||||
- What systems are affected?
|
||||
- Is the threat active?
|
||||
- What data may be compromised?
|
||||
- Is it contained or spreading?
|
||||
|
||||
### 2. Containment (15-60 minutes)
|
||||
|
||||
**Short-term Containment:**
|
||||
```
|
||||
□ Isolate affected systems (network/firewall)
|
||||
□ Block malicious IPs/domains
|
||||
□ Disable compromised accounts
|
||||
□ Preserve evidence before changes
|
||||
```
|
||||
|
||||
**Commands:**
|
||||
```bash
|
||||
# Network isolation
|
||||
iptables -I INPUT -s <malicious-ip> -j DROP
|
||||
iptables -I OUTPUT -d <malicious-ip> -j DROP
|
||||
|
||||
# Account disable
|
||||
usermod -L <username>
|
||||
passwd -l <username>
|
||||
|
||||
# Service isolation
|
||||
systemctl stop <compromised-service>
|
||||
```
|
||||
|
||||
### 3. Investigation (1-4 hours)
|
||||
|
||||
```
|
||||
□ Collect evidence (logs, memory, disk)
|
||||
□ Identify attack vector
|
||||
□ Determine scope of compromise
|
||||
□ Document findings in timeline
|
||||
```
|
||||
|
||||
**Log Sources:**
|
||||
- Authentication: /var/log/auth.log, CloudTrail
|
||||
- Application: Application logs, APM
|
||||
- Network: Firewall logs, VPC Flow Logs
|
||||
- System: syslog, journald
|
||||
|
||||
### 4. Eradication (1-24 hours)
|
||||
|
||||
```
|
||||
□ Remove malware/backdoors
|
||||
□ Patch vulnerabilities
|
||||
□ Reset compromised credentials
|
||||
□ Update security controls
|
||||
□ Verify complete removal
|
||||
```
|
||||
|
||||
### 5. Recovery (1-48 hours)
|
||||
|
||||
```
|
||||
□ Restore systems from clean backups
|
||||
□ Validate system integrity
|
||||
□ Monitor for re-infection
|
||||
□ Gradually restore services
|
||||
□ Communicate status updates
|
||||
```
|
||||
|
||||
### 6. Post-Incident (1-2 weeks)
|
||||
|
||||
```
|
||||
□ Conduct blameless post-mortem
|
||||
□ Document lessons learned
|
||||
□ Create action items
|
||||
□ Update runbooks and detection
|
||||
□ Report to stakeholders
|
||||
□ File regulatory notifications (if required)
|
||||
```
|
||||
|
||||
## Communication Templates
|
||||
|
||||
### Internal Notification
|
||||
```
|
||||
SECURITY INCIDENT - [SEV LEVEL]
|
||||
|
||||
Status: Active/Contained/Resolved
|
||||
Incident Commander: [Name]
|
||||
Channel: #incident-YYYY-MM-DD
|
||||
|
||||
Summary: [Brief description]
|
||||
|
||||
Impact:
|
||||
- Systems: [List]
|
||||
- Data: [Type if applicable]
|
||||
- Users: [Count/scope]
|
||||
|
||||
Current Actions:
|
||||
- [Action 1]
|
||||
- [Action 2]
|
||||
|
||||
Next Update: [Time]
|
||||
```
|
||||
|
||||
### External Notification (if required)
|
||||
```
|
||||
Subject: Security Incident Notification
|
||||
|
||||
We are writing to inform you of a security incident
|
||||
that occurred on [DATE].
|
||||
|
||||
What Happened: [Description]
|
||||
Data Involved: [Types]
|
||||
Actions Taken: [Response measures]
|
||||
What You Can Do: [Recommendations]
|
||||
Contact: [Security team contact]
|
||||
```
|
||||
|
||||
## Escalation Contacts
|
||||
|
||||
| Role | Primary | Secondary |
|
||||
|------|---------|-----------|
|
||||
| Incident Commander | [Name] | [Name] |
|
||||
| Security Lead | [Name] | [Name] |
|
||||
| Engineering Lead | [Name] | [Name] |
|
||||
| Legal/Compliance | [Name] | [Name] |
|
||||
| Communications | [Name] | [Name] |
|
||||
| Executive Sponsor | [Name] | [Name] |
|
||||
@@ -0,0 +1,149 @@
|
||||
# Indicator of Compromise (IOC) Hunting Guide
|
||||
|
||||
## Common IOC Types
|
||||
|
||||
| Type | Description | Example |
|
||||
|------|-------------|---------|
|
||||
| IP Address | Malicious source/destination | 192.168.1.100 |
|
||||
| Domain | C2 or phishing domain | malware.evil.com |
|
||||
| File Hash | Malware signature | SHA256:abc123... |
|
||||
| File Path | Suspicious file location | /tmp/.hidden |
|
||||
| Process | Malicious process name | cryptominer |
|
||||
| User | Compromised account | admin |
|
||||
|
||||
## Log Hunting Queries
|
||||
|
||||
### SSH Brute Force Detection
|
||||
```bash
|
||||
# Failed SSH attempts
|
||||
grep "Failed password" /var/log/auth.log | \
|
||||
awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head
|
||||
|
||||
# Successful logins after failures
|
||||
grep -E "Accepted|Failed" /var/log/auth.log | \
|
||||
grep -B5 "Accepted" | grep "Failed"
|
||||
```
|
||||
|
||||
### Suspicious Process Activity
|
||||
```bash
|
||||
# Processes running from /tmp
|
||||
ps aux | grep -E "^.*/tmp/|^.*/dev/shm/"
|
||||
|
||||
# Hidden processes
|
||||
ps aux | awk '$11 ~ /^\./'
|
||||
|
||||
# Processes with deleted binaries
|
||||
ls -la /proc/*/exe 2>/dev/null | grep deleted
|
||||
|
||||
# Unusual parent-child relationships
|
||||
ps -eo pid,ppid,cmd | grep -E "bash.*-c|sh.*-c"
|
||||
```
|
||||
|
||||
### Network IOCs
|
||||
```bash
|
||||
# Connections to known bad ports
|
||||
ss -anp | grep -E ":4444|:5555|:6666|:31337"
|
||||
|
||||
# Outbound connections from unusual processes
|
||||
ss -anp | grep -v -E "chrome|firefox|curl|wget" | grep ESTAB
|
||||
|
||||
# DNS queries to suspicious domains
|
||||
grep -E "query.*\.(tk|ml|ga|cf|gq)$" /var/log/syslog
|
||||
|
||||
# Large outbound transfers
|
||||
ss -anp | awk '$3 > 1000000'
|
||||
```
|
||||
|
||||
### File System IOCs
|
||||
```bash
|
||||
# Recently modified files in sensitive locations
|
||||
find /etc /usr/bin /usr/sbin -mtime -1 -ls 2>/dev/null
|
||||
|
||||
# Files with suspicious permissions
|
||||
find / -perm -4000 -o -perm -2000 -ls 2>/dev/null
|
||||
|
||||
# Hidden files
|
||||
find / -name ".*" -type f -ls 2>/dev/null | head -50
|
||||
|
||||
# World-writable files
|
||||
find / -perm -002 -type f -ls 2>/dev/null
|
||||
```
|
||||
|
||||
### User Activity IOCs
|
||||
```bash
|
||||
# Recent sudo usage
|
||||
grep sudo /var/log/auth.log | tail -50
|
||||
|
||||
# Users logged in from multiple IPs
|
||||
last | awk '{print $1, $3}' | sort | uniq -c | sort -rn
|
||||
|
||||
# SSH keys added recently
|
||||
find /home -name "authorized_keys" -mtime -7 -ls
|
||||
|
||||
# Unusual cron jobs
|
||||
for user in $(cut -d: -f1 /etc/passwd); do
|
||||
crontab -l -u $user 2>/dev/null | grep -v "^#"
|
||||
done
|
||||
```
|
||||
|
||||
## AWS CloudTrail Hunting
|
||||
|
||||
```bash
|
||||
# Console logins from unusual locations
|
||||
aws cloudtrail lookup-events \
|
||||
--lookup-attributes AttributeKey=EventName,AttributeValue=ConsoleLogin \
|
||||
--query 'Events[*].[CloudTrailEvent]' --output text | jq '.'
|
||||
|
||||
# Root account usage
|
||||
aws cloudtrail lookup-events \
|
||||
--lookup-attributes AttributeKey=Username,AttributeValue=root
|
||||
|
||||
# Security group changes
|
||||
aws cloudtrail lookup-events \
|
||||
--lookup-attributes AttributeKey=EventName,AttributeValue=AuthorizeSecurityGroupIngress
|
||||
```
|
||||
|
||||
## YARA Rule Example
|
||||
|
||||
```yara
|
||||
rule Suspicious_Shell_Script {
|
||||
meta:
|
||||
description = "Detects suspicious shell scripts"
|
||||
severity = "medium"
|
||||
strings:
|
||||
$s1 = "curl" ascii
|
||||
$s2 = "wget" ascii
|
||||
$s3 = "/dev/tcp/" ascii
|
||||
$s4 = "base64 -d" ascii
|
||||
$s5 = "chmod +x" ascii
|
||||
condition:
|
||||
3 of them
|
||||
}
|
||||
```
|
||||
|
||||
## Response Actions
|
||||
|
||||
### Block IOC
|
||||
```bash
|
||||
# Block IP
|
||||
iptables -I INPUT -s <IP> -j DROP
|
||||
iptables -I OUTPUT -d <IP> -j DROP
|
||||
|
||||
# Block domain (via hosts)
|
||||
echo "127.0.0.1 malicious.domain.com" >> /etc/hosts
|
||||
|
||||
# Kill process
|
||||
kill -9 <PID>
|
||||
```
|
||||
|
||||
### Preserve Evidence
|
||||
```bash
|
||||
# Capture process memory
|
||||
gcore <PID>
|
||||
|
||||
# Copy suspicious file
|
||||
cp --preserve=all /path/to/file /evidence/
|
||||
|
||||
# Capture network traffic
|
||||
tcpdump -i any -w /evidence/capture.pcap &
|
||||
```
|
||||
@@ -0,0 +1,109 @@
|
||||
#!/bin/bash
|
||||
# Security Incident Evidence Collection Script
|
||||
# Usage: ./collect-evidence.sh [incident-id]
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
INCIDENT_ID="${1:-incident-$(date +%Y%m%d-%H%M%S)}"
|
||||
EVIDENCE_DIR="/tmp/evidence-$INCIDENT_ID"
|
||||
HOSTNAME=$(hostname)
|
||||
|
||||
mkdir -p "$EVIDENCE_DIR"
|
||||
|
||||
echo "========================================="
|
||||
echo "Security Incident Evidence Collection"
|
||||
echo "Incident ID: $INCIDENT_ID"
|
||||
echo "Host: $HOSTNAME"
|
||||
echo "Time: $(date -u '+%Y-%m-%d %H:%M:%S UTC')"
|
||||
echo "Output: $EVIDENCE_DIR"
|
||||
echo "========================================="
|
||||
echo ""
|
||||
|
||||
# Create metadata file
|
||||
cat > "$EVIDENCE_DIR/metadata.txt" << EOF
|
||||
Incident ID: $INCIDENT_ID
|
||||
Collection Time: $(date -u '+%Y-%m-%d %H:%M:%S UTC')
|
||||
Hostname: $HOSTNAME
|
||||
Kernel: $(uname -a)
|
||||
Collector: $(whoami)
|
||||
EOF
|
||||
|
||||
# System information
|
||||
echo "Collecting system information..."
|
||||
mkdir -p "$EVIDENCE_DIR/system"
|
||||
uname -a > "$EVIDENCE_DIR/system/uname.txt"
|
||||
cat /etc/os-release > "$EVIDENCE_DIR/system/os-release.txt" 2>/dev/null || true
|
||||
uptime > "$EVIDENCE_DIR/system/uptime.txt"
|
||||
date -u > "$EVIDENCE_DIR/system/date.txt"
|
||||
|
||||
# Running processes
|
||||
echo "Collecting process information..."
|
||||
mkdir -p "$EVIDENCE_DIR/processes"
|
||||
ps auxf > "$EVIDENCE_DIR/processes/ps-auxf.txt"
|
||||
ps -eo pid,ppid,user,cmd --sort=-pid > "$EVIDENCE_DIR/processes/ps-sorted.txt"
|
||||
pstree -p > "$EVIDENCE_DIR/processes/pstree.txt" 2>/dev/null || true
|
||||
|
||||
# Network connections
|
||||
echo "Collecting network information..."
|
||||
mkdir -p "$EVIDENCE_DIR/network"
|
||||
ss -tlnp > "$EVIDENCE_DIR/network/listening-tcp.txt"
|
||||
ss -ulnp > "$EVIDENCE_DIR/network/listening-udp.txt"
|
||||
ss -anp > "$EVIDENCE_DIR/network/all-connections.txt"
|
||||
ip addr > "$EVIDENCE_DIR/network/ip-addr.txt"
|
||||
ip route > "$EVIDENCE_DIR/network/ip-route.txt"
|
||||
iptables -L -n -v > "$EVIDENCE_DIR/network/iptables.txt" 2>/dev/null || true
|
||||
cat /etc/hosts > "$EVIDENCE_DIR/network/hosts.txt"
|
||||
|
||||
# User information
|
||||
echo "Collecting user information..."
|
||||
mkdir -p "$EVIDENCE_DIR/users"
|
||||
cat /etc/passwd > "$EVIDENCE_DIR/users/passwd.txt"
|
||||
cat /etc/group > "$EVIDENCE_DIR/users/group.txt"
|
||||
who > "$EVIDENCE_DIR/users/who.txt"
|
||||
w > "$EVIDENCE_DIR/users/w.txt"
|
||||
last -100 > "$EVIDENCE_DIR/users/last.txt"
|
||||
lastlog > "$EVIDENCE_DIR/users/lastlog.txt" 2>/dev/null || true
|
||||
|
||||
# Authentication logs
|
||||
echo "Collecting authentication logs..."
|
||||
mkdir -p "$EVIDENCE_DIR/logs"
|
||||
tail -1000 /var/log/auth.log > "$EVIDENCE_DIR/logs/auth.log" 2>/dev/null || true
|
||||
tail -1000 /var/log/secure > "$EVIDENCE_DIR/logs/secure.log" 2>/dev/null || true
|
||||
tail -1000 /var/log/syslog > "$EVIDENCE_DIR/logs/syslog.txt" 2>/dev/null || true
|
||||
journalctl -u sshd --since "1 day ago" > "$EVIDENCE_DIR/logs/sshd.log" 2>/dev/null || true
|
||||
|
||||
# Scheduled tasks
|
||||
echo "Collecting scheduled tasks..."
|
||||
mkdir -p "$EVIDENCE_DIR/scheduled"
|
||||
crontab -l > "$EVIDENCE_DIR/scheduled/crontab-current.txt" 2>/dev/null || true
|
||||
ls -la /etc/cron.* > "$EVIDENCE_DIR/scheduled/cron-dirs.txt" 2>/dev/null || true
|
||||
cat /etc/crontab > "$EVIDENCE_DIR/scheduled/etc-crontab.txt" 2>/dev/null || true
|
||||
systemctl list-timers > "$EVIDENCE_DIR/scheduled/systemd-timers.txt" 2>/dev/null || true
|
||||
|
||||
# File system
|
||||
echo "Collecting filesystem information..."
|
||||
mkdir -p "$EVIDENCE_DIR/filesystem"
|
||||
df -h > "$EVIDENCE_DIR/filesystem/df.txt"
|
||||
mount > "$EVIDENCE_DIR/filesystem/mounts.txt"
|
||||
find /tmp /var/tmp -type f -mtime -1 -ls > "$EVIDENCE_DIR/filesystem/recent-tmp.txt" 2>/dev/null || true
|
||||
|
||||
# Package hashes
|
||||
echo "Collecting hash information..."
|
||||
if command -v sha256sum &>/dev/null; then
|
||||
find /usr/bin /usr/sbin -type f -executable 2>/dev/null | head -100 | xargs sha256sum > "$EVIDENCE_DIR/filesystem/binary-hashes.txt" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Create archive
|
||||
echo ""
|
||||
echo "Creating evidence archive..."
|
||||
ARCHIVE="/tmp/$INCIDENT_ID-evidence.tar.gz"
|
||||
tar -czf "$ARCHIVE" -C /tmp "evidence-$INCIDENT_ID"
|
||||
|
||||
echo ""
|
||||
echo "========================================="
|
||||
echo "Evidence collection complete"
|
||||
echo "Archive: $ARCHIVE"
|
||||
echo "Size: $(du -h "$ARCHIVE" | cut -f1)"
|
||||
echo ""
|
||||
echo "SHA256: $(sha256sum "$ARCHIVE" | cut -d' ' -f1)"
|
||||
echo "========================================="
|
||||
@@ -0,0 +1,111 @@
|
||||
---
|
||||
name: penetration-testing
|
||||
description: Perform basic penetration testing and security assessments. Use reconnaissance, vulnerability discovery, and exploitation techniques. Use when validating security controls or assessing system security.
|
||||
license: MIT
|
||||
metadata:
|
||||
author: devops-skills
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# Penetration Testing
|
||||
|
||||
Validate security controls through authorized testing.
|
||||
|
||||
## Phases
|
||||
|
||||
```yaml
|
||||
pentest_phases:
|
||||
1_reconnaissance:
|
||||
- Passive information gathering
|
||||
- DNS enumeration
|
||||
- Network mapping
|
||||
|
||||
2_scanning:
|
||||
- Port scanning
|
||||
- Service identification
|
||||
- Vulnerability scanning
|
||||
|
||||
3_exploitation:
|
||||
- Attempt exploitation
|
||||
- Verify vulnerabilities
|
||||
- Document findings
|
||||
|
||||
4_post_exploitation:
|
||||
- Privilege escalation
|
||||
- Lateral movement
|
||||
- Data access
|
||||
|
||||
5_reporting:
|
||||
- Document findings
|
||||
- Risk assessment
|
||||
- Remediation recommendations
|
||||
```
|
||||
|
||||
## Reconnaissance
|
||||
|
||||
```bash
|
||||
# DNS enumeration
|
||||
dig example.com ANY
|
||||
host -l example.com
|
||||
|
||||
# Subdomain discovery
|
||||
subfinder -d example.com
|
||||
|
||||
# WHOIS
|
||||
whois example.com
|
||||
```
|
||||
|
||||
## Scanning
|
||||
|
||||
```bash
|
||||
# Port scan
|
||||
nmap -sV -sC -p- target.com
|
||||
|
||||
# Web scanning
|
||||
nikto -h https://target.com
|
||||
dirb https://target.com
|
||||
|
||||
# Vulnerability scan
|
||||
nmap --script vuln target.com
|
||||
```
|
||||
|
||||
## Web Testing
|
||||
|
||||
```bash
|
||||
# SQL injection test
|
||||
sqlmap -u "http://target.com/page?id=1"
|
||||
|
||||
# XSS testing
|
||||
# Use Burp Suite or manual testing
|
||||
|
||||
# Directory traversal
|
||||
curl "http://target.com/file?path=../../../etc/passwd"
|
||||
```
|
||||
|
||||
## Rules of Engagement
|
||||
|
||||
```yaml
|
||||
scope:
|
||||
in_scope:
|
||||
- target.com
|
||||
- api.target.com
|
||||
out_of_scope:
|
||||
- production-db.target.com
|
||||
- third-party services
|
||||
|
||||
testing_window: "Weekdays 2-6 AM UTC"
|
||||
emergency_contact: "security@target.com"
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Always get written authorization
|
||||
- Define clear scope
|
||||
- Document everything
|
||||
- Report critical findings immediately
|
||||
- Safe exploitation techniques only
|
||||
|
||||
## Related Skills
|
||||
|
||||
- [dast-scanning](../../scanning/dast-scanning/) - Automated testing
|
||||
- [vulnerability-scanning](../../scanning/vulnerability-scanning/) - Vulnerability discovery
|
||||
@@ -0,0 +1,116 @@
|
||||
---
|
||||
name: security-automation
|
||||
description: Automate security workflows and remediation. Build security pipelines, automate compliance checks, and implement SOAR capabilities. Use when scaling security operations or implementing DevSecOps.
|
||||
license: MIT
|
||||
metadata:
|
||||
author: devops-skills
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# Security Automation
|
||||
|
||||
Automate security operations for scale and efficiency.
|
||||
|
||||
## Security Pipeline
|
||||
|
||||
```yaml
|
||||
# .github/workflows/security.yml
|
||||
name: Security Pipeline
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
security:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Secret Scanning
|
||||
uses: trufflesecurity/trufflehog@main
|
||||
|
||||
- name: SAST
|
||||
uses: returntocorp/semgrep-action@v1
|
||||
|
||||
- name: Dependency Scan
|
||||
run: npm audit --audit-level=high
|
||||
|
||||
- name: Container Scan
|
||||
uses: aquasecurity/trivy-action@master
|
||||
with:
|
||||
scan-type: 'fs'
|
||||
|
||||
- name: Compliance Check
|
||||
run: |
|
||||
checkov -d . --framework terraform
|
||||
```
|
||||
|
||||
## Automated Remediation
|
||||
|
||||
```python
|
||||
# Auto-remediation script
|
||||
def remediate_public_s3(bucket_name):
|
||||
"""Remove public access from S3 bucket."""
|
||||
s3 = boto3.client('s3')
|
||||
s3.put_public_access_block(
|
||||
Bucket=bucket_name,
|
||||
PublicAccessBlockConfiguration={
|
||||
'BlockPublicAcls': True,
|
||||
'IgnorePublicAcls': True,
|
||||
'BlockPublicPolicy': True,
|
||||
'RestrictPublicBuckets': True
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## SOAR Integration
|
||||
|
||||
```yaml
|
||||
playbook:
|
||||
name: Suspicious Login Response
|
||||
trigger: alert.type == "suspicious_login"
|
||||
actions:
|
||||
- enrich_ip:
|
||||
source: threat_intel
|
||||
- if_condition: ip.is_malicious
|
||||
then:
|
||||
- block_ip:
|
||||
firewall: cloudflare
|
||||
- disable_user:
|
||||
duration: 1h
|
||||
- notify:
|
||||
channel: security
|
||||
- create_ticket:
|
||||
priority: high
|
||||
```
|
||||
|
||||
## Compliance as Code
|
||||
|
||||
```python
|
||||
# Checkov custom check
|
||||
from checkov.terraform.checks.resource.base_resource_check import BaseResourceCheck
|
||||
|
||||
class S3Encryption(BaseResourceCheck):
|
||||
def __init__(self):
|
||||
name = "Ensure S3 bucket has encryption enabled"
|
||||
id = "CUSTOM_S3_1"
|
||||
supported_resources = ['aws_s3_bucket']
|
||||
super().__init__(name=name, id=id, ...)
|
||||
|
||||
def scan_resource_conf(self, conf):
|
||||
if 'server_side_encryption_configuration' in conf:
|
||||
return CheckResult.PASSED
|
||||
return CheckResult.FAILED
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Start with high-impact automations
|
||||
- Test in staging first
|
||||
- Include manual review gates
|
||||
- Monitor automation effectiveness
|
||||
- Regular rule updates
|
||||
|
||||
## Related Skills
|
||||
|
||||
- [github-actions](../../../devops/ci-cd/github-actions/) - CI/CD automation
|
||||
- [policy-as-code](../../../compliance/governance/policy-as-code/) - Policy enforcement
|
||||
@@ -0,0 +1,96 @@
|
||||
---
|
||||
name: threat-modeling
|
||||
description: Conduct threat modeling using STRIDE methodology. Identify threats, assess risks, and design security controls. Use when designing secure systems or assessing application security.
|
||||
license: MIT
|
||||
metadata:
|
||||
author: devops-skills
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# Threat Modeling
|
||||
|
||||
Identify and mitigate security threats during system design.
|
||||
|
||||
## STRIDE Methodology
|
||||
|
||||
| Threat | Description | Mitigation |
|
||||
|--------|-------------|------------|
|
||||
| **S**poofing | Pretending to be someone else | Authentication |
|
||||
| **T**ampering | Modifying data | Integrity controls |
|
||||
| **R**epudiation | Denying actions | Audit logging |
|
||||
| **I**nformation Disclosure | Data exposure | Encryption |
|
||||
| **D**enial of Service | Making service unavailable | Rate limiting |
|
||||
| **E**levation of Privilege | Gaining higher access | Authorization |
|
||||
|
||||
## Process
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
1_scope:
|
||||
- Define system boundaries
|
||||
- Identify assets
|
||||
- Document data flows
|
||||
|
||||
2_diagram:
|
||||
- Create data flow diagrams
|
||||
- Identify trust boundaries
|
||||
- Mark entry points
|
||||
|
||||
3_identify:
|
||||
- Apply STRIDE to each component
|
||||
- List potential threats
|
||||
- Document attack vectors
|
||||
|
||||
4_assess:
|
||||
- Rate likelihood and impact
|
||||
- Prioritize by risk score
|
||||
|
||||
5_mitigate:
|
||||
- Design countermeasures
|
||||
- Accept/transfer risks
|
||||
- Document decisions
|
||||
```
|
||||
|
||||
## Data Flow Diagram
|
||||
|
||||
```
|
||||
[External User] --> |HTTPS| --> [Load Balancer]
|
||||
|
|
||||
v
|
||||
[Web Server]
|
||||
|
|
||||
[Trust Boundary]
|
||||
|
|
||||
v
|
||||
[App Server] --> [Database]
|
||||
```
|
||||
|
||||
## Threat Cards
|
||||
|
||||
```yaml
|
||||
threat:
|
||||
id: T001
|
||||
name: SQL Injection
|
||||
category: Tampering
|
||||
component: Database queries
|
||||
likelihood: High
|
||||
impact: Critical
|
||||
mitigations:
|
||||
- Parameterized queries
|
||||
- Input validation
|
||||
- WAF rules
|
||||
status: Mitigated
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Integrate into SDLC
|
||||
- Review on architecture changes
|
||||
- Include development team
|
||||
- Document all decisions
|
||||
- Regular reassessment
|
||||
|
||||
## Related Skills
|
||||
|
||||
- [sast-scanning](../../scanning/sast-scanning/) - Code analysis
|
||||
- [penetration-testing](../penetration-testing/) - Validation
|
||||
@@ -0,0 +1,100 @@
|
||||
# Threat Modeling Template
|
||||
|
||||
## 1. System Overview
|
||||
|
||||
### Description
|
||||
[Brief description of the system being modeled]
|
||||
|
||||
### Architecture Diagram
|
||||
```
|
||||
[ASCII diagram or link to diagram]
|
||||
|
||||
+--------+ +--------+ +--------+
|
||||
| Client | --> | API | --> | DB |
|
||||
+--------+ +--------+ +--------+
|
||||
```
|
||||
|
||||
### Components
|
||||
| Component | Description | Technology |
|
||||
|-----------|-------------|------------|
|
||||
| Frontend | Web UI | React |
|
||||
| API | REST API | Node.js |
|
||||
| Database | Data storage | PostgreSQL |
|
||||
|
||||
### Data Flows
|
||||
| # | From | To | Data | Protocol |
|
||||
|---|------|----|----- |----------|
|
||||
| 1 | Client | API | User requests | HTTPS |
|
||||
| 2 | API | DB | Queries | TCP/TLS |
|
||||
|
||||
## 2. Trust Boundaries
|
||||
|
||||
```
|
||||
INTERNET
|
||||
|
|
||||
================|================ Trust Boundary 1
|
||||
|
|
||||
[ WAF/LB ]
|
||||
|
|
||||
================|================ Trust Boundary 2
|
||||
|
|
||||
[ API Server ]
|
||||
|
|
||||
================|================ Trust Boundary 3
|
||||
|
|
||||
[ Database ]
|
||||
```
|
||||
|
||||
## 3. Threat Identification (STRIDE)
|
||||
|
||||
### Spoofing
|
||||
| ID | Threat | Component | Mitigation |
|
||||
|----|--------|-----------|------------|
|
||||
| S1 | Session hijacking | API | Use secure cookies, short TTL |
|
||||
| S2 | API impersonation | Client | Certificate pinning |
|
||||
|
||||
### Tampering
|
||||
| ID | Threat | Component | Mitigation |
|
||||
|----|--------|-----------|------------|
|
||||
| T1 | Request modification | API | Input validation, signing |
|
||||
| T2 | Data modification | DB | Access controls, audit logs |
|
||||
|
||||
### Repudiation
|
||||
| ID | Threat | Component | Mitigation |
|
||||
|----|--------|-----------|------------|
|
||||
| R1 | Action denial | API | Comprehensive logging |
|
||||
|
||||
### Information Disclosure
|
||||
| ID | Threat | Component | Mitigation |
|
||||
|----|--------|-----------|------------|
|
||||
| I1 | Data leak | API | Encryption, access controls |
|
||||
| I2 | Error messages | All | Generic error responses |
|
||||
|
||||
### Denial of Service
|
||||
| ID | Threat | Component | Mitigation |
|
||||
|----|--------|-----------|------------|
|
||||
| D1 | Resource exhaustion | API | Rate limiting, auto-scaling |
|
||||
|
||||
### Elevation of Privilege
|
||||
| ID | Threat | Component | Mitigation |
|
||||
|----|--------|-----------|------------|
|
||||
| E1 | IDOR | API | Authorization checks |
|
||||
| E2 | SQL injection | DB | Parameterized queries |
|
||||
|
||||
## 4. Risk Assessment
|
||||
|
||||
| Threat ID | Likelihood | Impact | Risk | Priority |
|
||||
|-----------|------------|--------|------|----------|
|
||||
| S1 | Medium | High | High | P1 |
|
||||
| E2 | Low | Critical | High | P1 |
|
||||
|
||||
## 5. Mitigations
|
||||
|
||||
| Threat ID | Mitigation | Status | Owner |
|
||||
|-----------|------------|--------|-------|
|
||||
| S1 | Implement secure session management | In Progress | Auth Team |
|
||||
| E2 | Use ORM with parameterized queries | Done | Backend Team |
|
||||
|
||||
## 6. Residual Risks
|
||||
|
||||
[List any accepted risks with justification]
|
||||
@@ -0,0 +1,391 @@
|
||||
---
|
||||
name: container-scanning
|
||||
description: Scan container images for vulnerabilities using Trivy, Grype, and cloud-native tools. Identify security issues in base images, packages, and configurations. Use when implementing container security, building secure images, or meeting compliance requirements.
|
||||
license: MIT
|
||||
metadata:
|
||||
author: devops-skills
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# Container Scanning
|
||||
|
||||
Scan container images for vulnerabilities and security misconfigurations.
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
Use this skill when:
|
||||
- Building container images
|
||||
- Implementing container security gates
|
||||
- Scanning registry images
|
||||
- Meeting compliance requirements
|
||||
- Hardening container deployments
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Container runtime (Docker, Podman)
|
||||
- Container images to scan
|
||||
- Scanning tool installation
|
||||
|
||||
## Tool Comparison
|
||||
|
||||
| Tool | License | Speed | Features |
|
||||
|------|---------|-------|----------|
|
||||
| Trivy | OSS | Fast | Comprehensive, IaC |
|
||||
| Grype | OSS | Fast | Accurate, SBOM |
|
||||
| Clair | OSS | Medium | Registry integration |
|
||||
| Snyk Container | Commercial | Fast | Fix suggestions |
|
||||
| Docker Scout | Commercial | Fast | GitHub integration |
|
||||
|
||||
## Trivy
|
||||
|
||||
### Installation
|
||||
|
||||
```bash
|
||||
# Linux
|
||||
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin
|
||||
|
||||
# macOS
|
||||
brew install trivy
|
||||
|
||||
# Docker
|
||||
docker pull aquasec/trivy
|
||||
```
|
||||
|
||||
### Image Scanning
|
||||
|
||||
```bash
|
||||
# Scan local image
|
||||
trivy image myapp:latest
|
||||
|
||||
# Scan remote image
|
||||
trivy image nginx:1.25
|
||||
|
||||
# JSON output
|
||||
trivy image --format json -o results.json myapp:latest
|
||||
|
||||
# Filter by severity
|
||||
trivy image --severity HIGH,CRITICAL myapp:latest
|
||||
|
||||
# Ignore unfixed vulnerabilities
|
||||
trivy image --ignore-unfixed myapp:latest
|
||||
|
||||
# Exit code on vulnerability
|
||||
trivy image --exit-code 1 --severity CRITICAL myapp:latest
|
||||
```
|
||||
|
||||
### Filesystem Scanning
|
||||
|
||||
```bash
|
||||
# Scan project directory
|
||||
trivy fs /path/to/project
|
||||
|
||||
# Scan Dockerfile
|
||||
trivy config Dockerfile
|
||||
|
||||
# Scan Kubernetes manifests
|
||||
trivy config k8s/
|
||||
```
|
||||
|
||||
### Configuration
|
||||
|
||||
```yaml
|
||||
# trivy.yaml
|
||||
timeout: 10m
|
||||
severity:
|
||||
- HIGH
|
||||
- CRITICAL
|
||||
ignore-unfixed: true
|
||||
exit-code: 1
|
||||
|
||||
vulnerability:
|
||||
type:
|
||||
- os
|
||||
- library
|
||||
|
||||
scan:
|
||||
file-patterns:
|
||||
- "Dockerfile"
|
||||
- "*.yaml"
|
||||
```
|
||||
|
||||
### CI Integration
|
||||
|
||||
```yaml
|
||||
# GitHub Actions
|
||||
name: Container Security
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
scan:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build image
|
||||
run: docker build -t myapp:${{ github.sha }} .
|
||||
|
||||
- name: Run Trivy
|
||||
uses: aquasecurity/trivy-action@master
|
||||
with:
|
||||
image-ref: 'myapp:${{ github.sha }}'
|
||||
format: 'sarif'
|
||||
output: 'trivy-results.sarif'
|
||||
severity: 'CRITICAL,HIGH'
|
||||
exit-code: '1'
|
||||
|
||||
- name: Upload results
|
||||
uses: github/codeql-action/upload-sarif@v3
|
||||
with:
|
||||
sarif_file: 'trivy-results.sarif'
|
||||
```
|
||||
|
||||
## Grype
|
||||
|
||||
### Installation
|
||||
|
||||
```bash
|
||||
# Linux/macOS
|
||||
curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh -s -- -b /usr/local/bin
|
||||
|
||||
# Homebrew
|
||||
brew install grype
|
||||
```
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
# Scan image
|
||||
grype myapp:latest
|
||||
|
||||
# Scan from SBOM
|
||||
grype sbom:./sbom.json
|
||||
|
||||
# JSON output
|
||||
grype myapp:latest -o json > results.json
|
||||
|
||||
# Filter severity
|
||||
grype myapp:latest --fail-on high
|
||||
|
||||
# Scan directory
|
||||
grype dir:/path/to/project
|
||||
```
|
||||
|
||||
### Configuration
|
||||
|
||||
```yaml
|
||||
# .grype.yaml
|
||||
check-for-app-update: false
|
||||
fail-on-severity: high
|
||||
output: "json"
|
||||
scope: "Squashed"
|
||||
|
||||
ignore:
|
||||
- vulnerability: CVE-2023-12345
|
||||
reason: "False positive"
|
||||
expires: "2024-12-31"
|
||||
```
|
||||
|
||||
## Docker Scout
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
# Enable Docker Scout
|
||||
docker scout quickview myapp:latest
|
||||
|
||||
# Full CVE report
|
||||
docker scout cves myapp:latest
|
||||
|
||||
# Compare images
|
||||
docker scout compare myapp:v1 myapp:v2
|
||||
|
||||
# Recommendations
|
||||
docker scout recommendations myapp:latest
|
||||
```
|
||||
|
||||
### CI Integration
|
||||
|
||||
```yaml
|
||||
- name: Docker Scout
|
||||
uses: docker/scout-action@v1
|
||||
with:
|
||||
command: cves
|
||||
image: ${{ env.IMAGE_NAME }}
|
||||
sarif-file: scout-results.sarif
|
||||
summary: true
|
||||
```
|
||||
|
||||
## Registry Integration
|
||||
|
||||
### Amazon ECR
|
||||
|
||||
```bash
|
||||
# Enable scan on push
|
||||
aws ecr put-image-scanning-configuration \
|
||||
--repository-name myapp \
|
||||
--image-scanning-configuration scanOnPush=true
|
||||
|
||||
# Get scan findings
|
||||
aws ecr describe-image-scan-findings \
|
||||
--repository-name myapp \
|
||||
--image-id imageTag=latest
|
||||
|
||||
# Start manual scan
|
||||
aws ecr start-image-scan \
|
||||
--repository-name myapp \
|
||||
--image-id imageTag=latest
|
||||
```
|
||||
|
||||
### Azure ACR
|
||||
|
||||
```bash
|
||||
# Enable Defender for Containers
|
||||
az security pricing create \
|
||||
--name Containers \
|
||||
--tier Standard
|
||||
|
||||
# View scan results in Azure Portal or:
|
||||
az acr repository show \
|
||||
--name myregistry \
|
||||
--image myapp:latest
|
||||
```
|
||||
|
||||
### Google Artifact Registry
|
||||
|
||||
```bash
|
||||
# Enable vulnerability scanning
|
||||
gcloud artifacts repositories update myrepo \
|
||||
--location=us-central1 \
|
||||
--enable-vulnerability-scanning
|
||||
|
||||
# View vulnerabilities
|
||||
gcloud artifacts docker images describe \
|
||||
us-central1-docker.pkg.dev/project/myrepo/myapp:latest \
|
||||
--show-package-vulnerability
|
||||
```
|
||||
|
||||
## Admission Controllers
|
||||
|
||||
### OPA Gatekeeper
|
||||
|
||||
```yaml
|
||||
apiVersion: templates.gatekeeper.sh/v1beta1
|
||||
kind: ConstraintTemplate
|
||||
metadata:
|
||||
name: k8sallowedrepos
|
||||
spec:
|
||||
crd:
|
||||
spec:
|
||||
names:
|
||||
kind: K8sAllowedRepos
|
||||
validation:
|
||||
openAPIV3Schema:
|
||||
properties:
|
||||
repos:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
targets:
|
||||
- target: admission.k8s.gatekeeper.sh
|
||||
rego: |
|
||||
package k8sallowedrepos
|
||||
|
||||
violation[{"msg": msg}] {
|
||||
container := input.review.object.spec.containers[_]
|
||||
satisfied := [good | repo = input.parameters.repos[_]; good = startswith(container.image, repo)]
|
||||
not any(satisfied)
|
||||
msg := sprintf("container <%v> has an invalid image repo <%v>", [container.name, container.image])
|
||||
}
|
||||
```
|
||||
|
||||
### Kyverno
|
||||
|
||||
```yaml
|
||||
apiVersion: kyverno.io/v1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: require-image-scan
|
||||
spec:
|
||||
validationFailureAction: enforce
|
||||
rules:
|
||||
- name: check-vulnerabilities
|
||||
match:
|
||||
resources:
|
||||
kinds:
|
||||
- Pod
|
||||
verifyImages:
|
||||
- image: "*"
|
||||
attestations:
|
||||
- predicateType: cosign.sigstore.dev/attestation/vuln/v1
|
||||
conditions:
|
||||
- all:
|
||||
- key: "{{ scanner.result.summary.criticalCount }}"
|
||||
operator: Equals
|
||||
value: "0"
|
||||
```
|
||||
|
||||
## Scanning Policies
|
||||
|
||||
### Policy Definition
|
||||
|
||||
```yaml
|
||||
# scan-policy.yaml
|
||||
policies:
|
||||
- name: critical-vulnerabilities
|
||||
description: Block images with critical CVEs
|
||||
severity: CRITICAL
|
||||
action: block
|
||||
|
||||
- name: high-vulnerabilities
|
||||
description: Warn on high severity CVEs
|
||||
severity: HIGH
|
||||
action: warn
|
||||
max_count: 5
|
||||
|
||||
- name: age-policy
|
||||
description: Block images older than 30 days
|
||||
max_age_days: 30
|
||||
action: block
|
||||
|
||||
- name: base-image
|
||||
description: Only allow approved base images
|
||||
allowed_bases:
|
||||
- alpine:3.18
|
||||
- ubuntu:22.04
|
||||
- python:3.11-slim
|
||||
```
|
||||
|
||||
## Common Issues
|
||||
|
||||
### Issue: False Positives
|
||||
**Problem**: Scanner reports non-exploitable vulnerabilities
|
||||
**Solution**: Use ignore files, validate with context
|
||||
|
||||
### Issue: Slow Scans
|
||||
**Problem**: Scanning takes too long
|
||||
**Solution**: Use caching, scan incrementally, optimize image layers
|
||||
|
||||
### Issue: Unfixed Vulnerabilities
|
||||
**Problem**: No patch available for CVE
|
||||
**Solution**: Update base image, implement compensating controls
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Scan in CI/CD pipeline
|
||||
- Use minimal base images (Alpine, distroless)
|
||||
- Update base images regularly
|
||||
- Implement admission control
|
||||
- Track vulnerabilities over time
|
||||
- Set severity thresholds
|
||||
- Document accepted risks
|
||||
- Use multi-stage builds
|
||||
|
||||
## Related Skills
|
||||
|
||||
- [docker-management](../../../devops/containers/docker-management/) - Container basics
|
||||
- [container-hardening](../../hardening/container-hardening/) - Security hardening
|
||||
- [kubernetes-hardening](../../hardening/kubernetes-hardening/) - K8s security
|
||||
@@ -0,0 +1,399 @@
|
||||
---
|
||||
name: dast-scanning
|
||||
description: Perform dynamic application security testing with OWASP ZAP, Burp Suite, and Nikto. Test running applications for security vulnerabilities through automated and manual testing. Use when testing web applications, APIs, or performing penetration testing.
|
||||
license: MIT
|
||||
metadata:
|
||||
author: devops-skills
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# DAST Scanning
|
||||
|
||||
Test running applications for security vulnerabilities through dynamic analysis.
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
Use this skill when:
|
||||
- Testing deployed applications
|
||||
- Performing automated security scans
|
||||
- Finding runtime vulnerabilities
|
||||
- Testing authentication flows
|
||||
- Validating API security
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Running application instance
|
||||
- Network access to target
|
||||
- Testing authorization
|
||||
- Understanding of web security
|
||||
|
||||
## Tool Overview
|
||||
|
||||
| Tool | Type | Best For |
|
||||
|------|------|----------|
|
||||
| OWASP ZAP | OSS | Automated scanning, CI |
|
||||
| Burp Suite | Commercial | Manual testing, advanced |
|
||||
| Nikto | OSS | Web server scanning |
|
||||
| Nuclei | OSS | Template-based scanning |
|
||||
| Arachni | OSS | Comprehensive scanning |
|
||||
|
||||
## OWASP ZAP
|
||||
|
||||
### Docker Setup
|
||||
|
||||
```bash
|
||||
# Run ZAP in daemon mode
|
||||
docker run -d --name zap \
|
||||
-p 8080:8080 \
|
||||
-v $(pwd)/reports:/zap/reports \
|
||||
ghcr.io/zaproxy/zaproxy:stable \
|
||||
zap.sh -daemon -host 0.0.0.0 -port 8080 \
|
||||
-config api.addrs.addr.name=.* \
|
||||
-config api.addrs.addr.regex=true
|
||||
```
|
||||
|
||||
### Baseline Scan
|
||||
|
||||
```bash
|
||||
# Quick baseline scan
|
||||
docker run --rm -v $(pwd):/zap/wrk \
|
||||
ghcr.io/zaproxy/zaproxy:stable \
|
||||
zap-baseline.py -t https://target.example.com \
|
||||
-r baseline-report.html
|
||||
|
||||
# With authentication
|
||||
docker run --rm -v $(pwd):/zap/wrk \
|
||||
ghcr.io/zaproxy/zaproxy:stable \
|
||||
zap-baseline.py -t https://target.example.com \
|
||||
-r report.html \
|
||||
--auth-login-url https://target.example.com/login \
|
||||
--auth-username user \
|
||||
--auth-password pass
|
||||
```
|
||||
|
||||
### Full Scan
|
||||
|
||||
```bash
|
||||
# Comprehensive scan
|
||||
docker run --rm -v $(pwd):/zap/wrk \
|
||||
ghcr.io/zaproxy/zaproxy:stable \
|
||||
zap-full-scan.py -t https://target.example.com \
|
||||
-r full-report.html \
|
||||
-J full-report.json
|
||||
```
|
||||
|
||||
### API Scan
|
||||
|
||||
```bash
|
||||
# OpenAPI specification scan
|
||||
docker run --rm -v $(pwd):/zap/wrk \
|
||||
ghcr.io/zaproxy/zaproxy:stable \
|
||||
zap-api-scan.py -t https://target.example.com/openapi.json \
|
||||
-f openapi \
|
||||
-r api-report.html
|
||||
```
|
||||
|
||||
### ZAP Automation Framework
|
||||
|
||||
```yaml
|
||||
# zap-automation.yaml
|
||||
env:
|
||||
contexts:
|
||||
- name: "Default Context"
|
||||
urls:
|
||||
- "https://target.example.com"
|
||||
includePaths:
|
||||
- "https://target.example.com/.*"
|
||||
excludePaths:
|
||||
- "https://target.example.com/logout.*"
|
||||
authentication:
|
||||
method: "form"
|
||||
parameters:
|
||||
loginUrl: "https://target.example.com/login"
|
||||
loginRequestData: "username={%username%}&password={%password%}"
|
||||
verification:
|
||||
method: "response"
|
||||
loggedInRegex: "\\QWelcome\\E"
|
||||
users:
|
||||
- name: "testuser"
|
||||
credentials:
|
||||
username: "test@example.com"
|
||||
password: "password123"
|
||||
|
||||
jobs:
|
||||
- type: spider
|
||||
parameters:
|
||||
context: "Default Context"
|
||||
user: "testuser"
|
||||
maxDuration: 10
|
||||
|
||||
- type: spiderAjax
|
||||
parameters:
|
||||
context: "Default Context"
|
||||
user: "testuser"
|
||||
maxDuration: 10
|
||||
|
||||
- type: passiveScan-wait
|
||||
parameters:
|
||||
maxDuration: 5
|
||||
|
||||
- type: activeScan
|
||||
parameters:
|
||||
context: "Default Context"
|
||||
user: "testuser"
|
||||
policy: "Default Policy"
|
||||
|
||||
- type: report
|
||||
parameters:
|
||||
template: "traditional-html"
|
||||
reportDir: "/zap/reports"
|
||||
reportFile: "zap-report"
|
||||
```
|
||||
|
||||
```bash
|
||||
# Run automation
|
||||
docker run --rm -v $(pwd):/zap/wrk \
|
||||
ghcr.io/zaproxy/zaproxy:stable \
|
||||
zap.sh -cmd -autorun /zap/wrk/zap-automation.yaml
|
||||
```
|
||||
|
||||
## CI/CD Integration
|
||||
|
||||
### GitHub Actions
|
||||
|
||||
```yaml
|
||||
name: DAST Scan
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '0 2 * * *'
|
||||
|
||||
jobs:
|
||||
dast:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Start Application
|
||||
run: |
|
||||
docker-compose up -d
|
||||
sleep 30 # Wait for app to be ready
|
||||
|
||||
- name: OWASP ZAP Scan
|
||||
uses: zaproxy/action-full-scan@v0.8.0
|
||||
with:
|
||||
target: 'http://localhost:8080'
|
||||
rules_file_name: '.zap/rules.tsv'
|
||||
cmd_options: '-a'
|
||||
|
||||
- name: Upload Report
|
||||
uses: actions/upload-artifact@v4
|
||||
if: always()
|
||||
with:
|
||||
name: zap-report
|
||||
path: report_html.html
|
||||
```
|
||||
|
||||
### GitLab CI
|
||||
|
||||
```yaml
|
||||
dast:
|
||||
stage: security
|
||||
image: ghcr.io/zaproxy/zaproxy:stable
|
||||
variables:
|
||||
TARGET_URL: $DAST_TARGET_URL
|
||||
script:
|
||||
- mkdir -p /zap/wrk/reports
|
||||
- zap-baseline.py -t $TARGET_URL -r /zap/wrk/reports/zap-report.html -I
|
||||
artifacts:
|
||||
paths:
|
||||
- reports/
|
||||
expire_in: 1 week
|
||||
rules:
|
||||
- if: $CI_COMMIT_BRANCH == "main"
|
||||
```
|
||||
|
||||
## Burp Suite Automation
|
||||
|
||||
### REST API Usage
|
||||
|
||||
```python
|
||||
import requests
|
||||
|
||||
class BurpScanner:
|
||||
def __init__(self, api_url, api_key):
|
||||
self.api_url = api_url
|
||||
self.headers = {'Authorization': api_key}
|
||||
|
||||
def create_scan(self, target_url):
|
||||
"""Create and start a new scan."""
|
||||
payload = {
|
||||
'scan_configurations': [
|
||||
{'name': 'Crawl and Audit - Balanced'}
|
||||
],
|
||||
'scope': {
|
||||
'include': [{'rule': target_url}]
|
||||
},
|
||||
'urls': [target_url]
|
||||
}
|
||||
response = requests.post(
|
||||
f'{self.api_url}/v0.1/scan',
|
||||
json=payload,
|
||||
headers=self.headers
|
||||
)
|
||||
return response.headers.get('Location')
|
||||
|
||||
def get_scan_status(self, scan_id):
|
||||
"""Get scan status."""
|
||||
response = requests.get(
|
||||
f'{self.api_url}/v0.1/scan/{scan_id}',
|
||||
headers=self.headers
|
||||
)
|
||||
return response.json()
|
||||
|
||||
def get_issues(self, scan_id):
|
||||
"""Get scan issues."""
|
||||
response = requests.get(
|
||||
f'{self.api_url}/v0.1/scan/{scan_id}/issues',
|
||||
headers=self.headers
|
||||
)
|
||||
return response.json()
|
||||
|
||||
# Usage
|
||||
scanner = BurpScanner('http://burp:1337', 'api-key')
|
||||
scan_id = scanner.create_scan('https://target.example.com')
|
||||
|
||||
while True:
|
||||
status = scanner.get_scan_status(scan_id)
|
||||
if status['scan_status'] == 'succeeded':
|
||||
break
|
||||
time.sleep(30)
|
||||
|
||||
issues = scanner.get_issues(scan_id)
|
||||
```
|
||||
|
||||
## Nikto
|
||||
|
||||
### Basic Scanning
|
||||
|
||||
```bash
|
||||
# Install
|
||||
apt-get install nikto
|
||||
|
||||
# Basic scan
|
||||
nikto -h https://target.example.com
|
||||
|
||||
# With specific options
|
||||
nikto -h https://target.example.com \
|
||||
-ssl \
|
||||
-Tuning 123bde \
|
||||
-output nikto-report.html \
|
||||
-Format html
|
||||
|
||||
# Scan specific ports
|
||||
nikto -h target.example.com -p 80,443,8080
|
||||
```
|
||||
|
||||
## Common DAST Findings
|
||||
|
||||
### OWASP Top 10
|
||||
|
||||
```yaml
|
||||
owasp_findings:
|
||||
A01_Broken_Access_Control:
|
||||
- IDOR vulnerabilities
|
||||
- Missing function-level access control
|
||||
- Privilege escalation
|
||||
|
||||
A02_Cryptographic_Failures:
|
||||
- Sensitive data in URLs
|
||||
- Missing HTTPS
|
||||
- Weak ciphers
|
||||
|
||||
A03_Injection:
|
||||
- SQL injection
|
||||
- Command injection
|
||||
- XSS
|
||||
|
||||
A05_Security_Misconfiguration:
|
||||
- Default credentials
|
||||
- Verbose error messages
|
||||
- Missing security headers
|
||||
|
||||
A07_Auth_Failures:
|
||||
- Weak passwords accepted
|
||||
- Session fixation
|
||||
- Missing MFA
|
||||
```
|
||||
|
||||
## Security Headers Check
|
||||
|
||||
```bash
|
||||
# Check security headers
|
||||
curl -I https://target.example.com | grep -i "x-\|content-security\|strict"
|
||||
|
||||
# Expected headers:
|
||||
# X-Content-Type-Options: nosniff
|
||||
# X-Frame-Options: DENY
|
||||
# X-XSS-Protection: 1; mode=block
|
||||
# Content-Security-Policy: default-src 'self'
|
||||
# Strict-Transport-Security: max-age=31536000
|
||||
```
|
||||
|
||||
## Custom Test Cases
|
||||
|
||||
```yaml
|
||||
# Test authentication
|
||||
tests:
|
||||
- name: "Authentication Bypass"
|
||||
steps:
|
||||
- Access protected resource without auth
|
||||
- Verify 401/403 response
|
||||
- Access with valid auth
|
||||
- Verify 200 response
|
||||
|
||||
- name: "Session Management"
|
||||
steps:
|
||||
- Login and capture session token
|
||||
- Logout
|
||||
- Attempt to use old session
|
||||
- Verify session invalidated
|
||||
|
||||
- name: "Input Validation"
|
||||
steps:
|
||||
- Submit XSS payload in all inputs
|
||||
- Submit SQL injection in all inputs
|
||||
- Verify proper sanitization
|
||||
```
|
||||
|
||||
## Common Issues
|
||||
|
||||
### Issue: False Positives
|
||||
**Problem**: Scanner reports non-vulnerabilities
|
||||
**Solution**: Configure scan policy, review findings manually
|
||||
|
||||
### Issue: Missing Authentication
|
||||
**Problem**: Cannot scan authenticated areas
|
||||
**Solution**: Configure authentication context, use session tokens
|
||||
|
||||
### Issue: Incomplete Coverage
|
||||
**Problem**: Scanner misses endpoints
|
||||
**Solution**: Import API specs, improve spidering, use authenticated scanning
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Test in staging environment first
|
||||
- Configure proper authentication
|
||||
- Import API specifications for complete coverage
|
||||
- Review findings before reporting
|
||||
- Combine with manual testing
|
||||
- Run regular scans (weekly minimum)
|
||||
- Track findings over time
|
||||
- Coordinate with development team
|
||||
|
||||
## Related Skills
|
||||
|
||||
- [sast-scanning](../sast-scanning/) - Static analysis
|
||||
- [penetration-testing](../../operations/penetration-testing/) - Manual testing
|
||||
- [waf-setup](../../network/waf-setup/) - WAF configuration
|
||||
@@ -0,0 +1,105 @@
|
||||
# DAST Tools Reference
|
||||
|
||||
## Tool Comparison
|
||||
|
||||
| Tool | Type | License | Best For |
|
||||
|------|------|---------|----------|
|
||||
| **OWASP ZAP** | Proxy/Scanner | Apache 2.0 | General DAST |
|
||||
| **Nuclei** | Template-based | MIT | Vulnerability checks |
|
||||
| **Nikto** | Web scanner | GPL | Quick scans |
|
||||
| **Burp Suite** | Proxy/Scanner | Commercial | Manual testing |
|
||||
|
||||
## OWASP ZAP
|
||||
|
||||
### CLI Scanning
|
||||
```bash
|
||||
# Quick scan
|
||||
docker run -t owasp/zap2docker-stable zap-baseline.py -t https://target.com
|
||||
|
||||
# Full scan
|
||||
docker run -t owasp/zap2docker-stable zap-full-scan.py -t https://target.com
|
||||
|
||||
# API scan
|
||||
docker run -t owasp/zap2docker-stable zap-api-scan.py \
|
||||
-t https://target.com/openapi.json -f openapi
|
||||
```
|
||||
|
||||
### Automation Framework
|
||||
```yaml
|
||||
# zap-config.yaml
|
||||
env:
|
||||
contexts:
|
||||
- name: "Default Context"
|
||||
urls: ["https://target.com"]
|
||||
authentication:
|
||||
method: "form"
|
||||
parameters:
|
||||
loginUrl: "https://target.com/login"
|
||||
loginRequestData: "user={%username%}&pass={%password%}"
|
||||
jobs:
|
||||
- type: spider
|
||||
parameters:
|
||||
maxDuration: 5
|
||||
- type: activeScan
|
||||
parameters:
|
||||
maxScanDurationInMins: 60
|
||||
- type: report
|
||||
parameters:
|
||||
template: "traditional-html"
|
||||
reportFile: "zap-report.html"
|
||||
```
|
||||
|
||||
## Nuclei
|
||||
|
||||
```bash
|
||||
# Install
|
||||
go install github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest
|
||||
|
||||
# Scan with all templates
|
||||
nuclei -u https://target.com
|
||||
|
||||
# Specific templates
|
||||
nuclei -u https://target.com -t cves/
|
||||
nuclei -u https://target.com -t exposures/
|
||||
|
||||
# Critical and high only
|
||||
nuclei -u https://target.com -severity critical,high
|
||||
|
||||
# Output
|
||||
nuclei -u https://target.com -json -o results.json
|
||||
```
|
||||
|
||||
### Custom Template
|
||||
```yaml
|
||||
id: custom-check
|
||||
info:
|
||||
name: Custom Security Check
|
||||
severity: high
|
||||
requests:
|
||||
- method: GET
|
||||
path:
|
||||
- "{{BaseURL}}/admin"
|
||||
matchers:
|
||||
- type: status
|
||||
status:
|
||||
- 200
|
||||
```
|
||||
|
||||
## CI Integration
|
||||
|
||||
```yaml
|
||||
# GitHub Actions
|
||||
- name: OWASP ZAP Scan
|
||||
uses: zaproxy/action-baseline@v0.9.0
|
||||
with:
|
||||
target: 'https://target.com'
|
||||
rules_file_name: '.zap/rules.tsv'
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. Run in staging, not production
|
||||
2. Use authentication for full coverage
|
||||
3. Exclude logout/destructive endpoints
|
||||
4. Set reasonable timeouts
|
||||
5. Review and triage findings
|
||||
@@ -0,0 +1,432 @@
|
||||
---
|
||||
name: dependency-scanning
|
||||
description: Scan package dependencies for known vulnerabilities using Snyk, Dependabot, and OWASP Dependency-Check. Identify and remediate vulnerable libraries in your software supply chain. Use when managing third-party dependencies or implementing software composition analysis.
|
||||
license: MIT
|
||||
metadata:
|
||||
author: devops-skills
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# Dependency Scanning
|
||||
|
||||
Identify vulnerabilities in third-party dependencies and libraries.
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
Use this skill when:
|
||||
- Managing third-party dependencies
|
||||
- Implementing software composition analysis
|
||||
- Meeting compliance requirements
|
||||
- Securing the software supply chain
|
||||
- Automating vulnerability detection
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Package manifest files (package.json, requirements.txt, etc.)
|
||||
- CI/CD pipeline access
|
||||
- Dependency scanning tool
|
||||
|
||||
## Tool Comparison
|
||||
|
||||
| Tool | Type | Languages | Best For |
|
||||
|------|------|-----------|----------|
|
||||
| Snyk | Commercial/Free | Many | Comprehensive SCA |
|
||||
| Dependabot | Free (GitHub) | Many | Automated PRs |
|
||||
| OWASP Dep-Check | OSS | Many | Free scanning |
|
||||
| npm audit | Built-in | Node.js | Quick checks |
|
||||
| pip-audit | OSS | Python | Python projects |
|
||||
| Trivy | OSS | Many | Container deps |
|
||||
|
||||
## Snyk
|
||||
|
||||
### CLI Usage
|
||||
|
||||
```bash
|
||||
# Install
|
||||
npm install -g snyk
|
||||
|
||||
# Authenticate
|
||||
snyk auth
|
||||
|
||||
# Test project
|
||||
snyk test
|
||||
|
||||
# Monitor project (track over time)
|
||||
snyk monitor
|
||||
|
||||
# Test specific manifest
|
||||
snyk test --file=package.json
|
||||
snyk test --file=requirements.txt
|
||||
|
||||
# Output formats
|
||||
snyk test --json > snyk-results.json
|
||||
snyk test --sarif > snyk-results.sarif
|
||||
|
||||
# Fix vulnerabilities
|
||||
snyk fix
|
||||
|
||||
# Ignore vulnerability
|
||||
snyk ignore --id=SNYK-JS-LODASH-567746 --expiry=2024-12-31 --reason="No exploit path"
|
||||
```
|
||||
|
||||
### CI Integration
|
||||
|
||||
```yaml
|
||||
# .github/workflows/snyk.yml
|
||||
name: Snyk Security
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
snyk:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Run Snyk to check for vulnerabilities
|
||||
uses: snyk/actions/node@master
|
||||
env:
|
||||
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
|
||||
with:
|
||||
args: --severity-threshold=high
|
||||
|
||||
- name: Upload results to GitHub
|
||||
uses: github/codeql-action/upload-sarif@v3
|
||||
with:
|
||||
sarif_file: snyk.sarif
|
||||
```
|
||||
|
||||
### Policy File
|
||||
|
||||
```yaml
|
||||
# .snyk
|
||||
version: v1.25.0
|
||||
ignore:
|
||||
SNYK-JS-LODASH-567746:
|
||||
- '*':
|
||||
reason: No user input reaches this function
|
||||
expires: 2024-12-31
|
||||
created: 2024-01-15
|
||||
|
||||
'snyk:lic:npm:gpl-3.0':
|
||||
- '*':
|
||||
reason: Internal use only
|
||||
|
||||
patch: {}
|
||||
```
|
||||
|
||||
## GitHub Dependabot
|
||||
|
||||
### Configuration
|
||||
|
||||
```yaml
|
||||
# .github/dependabot.yml
|
||||
version: 2
|
||||
updates:
|
||||
# JavaScript/Node.js
|
||||
- package-ecosystem: "npm"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
day: "monday"
|
||||
open-pull-requests-limit: 10
|
||||
reviewers:
|
||||
- "security-team"
|
||||
labels:
|
||||
- "dependencies"
|
||||
- "security"
|
||||
ignore:
|
||||
- dependency-name: "aws-sdk"
|
||||
update-types: ["version-update:semver-major"]
|
||||
groups:
|
||||
development-dependencies:
|
||||
dependency-type: "development"
|
||||
update-types:
|
||||
- "minor"
|
||||
- "patch"
|
||||
|
||||
# Python
|
||||
- package-ecosystem: "pip"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
|
||||
# Docker
|
||||
- package-ecosystem: "docker"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
|
||||
# GitHub Actions
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
```
|
||||
|
||||
### Security Alerts
|
||||
|
||||
```yaml
|
||||
# Automated security updates
|
||||
# Enable in repository Settings > Security > Dependabot
|
||||
|
||||
# Dependabot will automatically:
|
||||
# - Create PRs for vulnerable dependencies
|
||||
# - Update to patched versions
|
||||
# - Provide CVE details in PR description
|
||||
```
|
||||
|
||||
## OWASP Dependency-Check
|
||||
|
||||
### Installation
|
||||
|
||||
```bash
|
||||
# Download
|
||||
wget https://github.com/jeremylong/DependencyCheck/releases/download/v9.0.0/dependency-check-9.0.0-release.zip
|
||||
unzip dependency-check-9.0.0-release.zip
|
||||
|
||||
# Or via Homebrew
|
||||
brew install dependency-check
|
||||
```
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
# Scan project
|
||||
dependency-check --project "MyProject" \
|
||||
--scan /path/to/project \
|
||||
--out /path/to/reports \
|
||||
--format HTML \
|
||||
--format JSON
|
||||
|
||||
# With specific analyzers
|
||||
dependency-check --project "MyProject" \
|
||||
--scan . \
|
||||
--enableExperimental \
|
||||
--disableRetireJS
|
||||
|
||||
# CI configuration
|
||||
dependency-check --project "MyProject" \
|
||||
--scan . \
|
||||
--format JSON \
|
||||
--failOnCVSS 7 \
|
||||
--suppression suppression.xml
|
||||
```
|
||||
|
||||
### Suppression File
|
||||
|
||||
```xml
|
||||
<!-- suppression.xml -->
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<suppressions xmlns="https://jeremylong.github.io/DependencyCheck/dependency-suppression.1.3.xsd">
|
||||
<suppress>
|
||||
<notes>False positive - not using vulnerable function</notes>
|
||||
<packageUrl regex="true">^pkg:npm/lodash@.*$</packageUrl>
|
||||
<cve>CVE-2021-23337</cve>
|
||||
</suppress>
|
||||
|
||||
<suppress until="2024-12-31">
|
||||
<notes>Risk accepted - mitigated by WAF</notes>
|
||||
<cpe>cpe:/a:apache:struts:2.5.0</cpe>
|
||||
<vulnerabilityName>CVE-2023-12345</vulnerabilityName>
|
||||
</suppress>
|
||||
</suppressions>
|
||||
```
|
||||
|
||||
### Maven Integration
|
||||
|
||||
```xml
|
||||
<!-- pom.xml -->
|
||||
<plugin>
|
||||
<groupId>org.owasp</groupId>
|
||||
<artifactId>dependency-check-maven</artifactId>
|
||||
<version>9.0.0</version>
|
||||
<configuration>
|
||||
<failBuildOnCVSS>7</failBuildOnCVSS>
|
||||
<suppressionFiles>
|
||||
<suppressionFile>suppression.xml</suppressionFile>
|
||||
</suppressionFiles>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>check</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
```
|
||||
|
||||
## Language-Specific Tools
|
||||
|
||||
### Node.js (npm audit)
|
||||
|
||||
```bash
|
||||
# Run audit
|
||||
npm audit
|
||||
|
||||
# JSON output
|
||||
npm audit --json
|
||||
|
||||
# Fix automatically
|
||||
npm audit fix
|
||||
|
||||
# Fix with breaking changes
|
||||
npm audit fix --force
|
||||
|
||||
# Production only
|
||||
npm audit --production
|
||||
```
|
||||
|
||||
### Python (pip-audit)
|
||||
|
||||
```bash
|
||||
# Install
|
||||
pip install pip-audit
|
||||
|
||||
# Scan installed packages
|
||||
pip-audit
|
||||
|
||||
# Scan requirements file
|
||||
pip-audit -r requirements.txt
|
||||
|
||||
# Output formats
|
||||
pip-audit --format json
|
||||
pip-audit --format cyclonedx-json
|
||||
|
||||
# Fix vulnerabilities
|
||||
pip-audit --fix
|
||||
```
|
||||
|
||||
### Go (govulncheck)
|
||||
|
||||
```bash
|
||||
# Install
|
||||
go install golang.org/x/vuln/cmd/govulncheck@latest
|
||||
|
||||
# Scan project
|
||||
govulncheck ./...
|
||||
|
||||
# JSON output
|
||||
govulncheck -json ./...
|
||||
```
|
||||
|
||||
### Ruby (bundler-audit)
|
||||
|
||||
```bash
|
||||
# Install
|
||||
gem install bundler-audit
|
||||
|
||||
# Update database
|
||||
bundle-audit update
|
||||
|
||||
# Run audit
|
||||
bundle-audit check
|
||||
|
||||
# Output format
|
||||
bundle-audit check --format json
|
||||
```
|
||||
|
||||
## SBOM Generation
|
||||
|
||||
### CycloneDX
|
||||
|
||||
```bash
|
||||
# Node.js
|
||||
npx @cyclonedx/cyclonedx-npm --output-file sbom.json
|
||||
|
||||
# Python
|
||||
pip install cyclonedx-bom
|
||||
cyclonedx-py -o sbom.json
|
||||
|
||||
# Go
|
||||
go install github.com/CycloneDX/cyclonedx-gomod/cmd/cyclonedx-gomod@latest
|
||||
cyclonedx-gomod mod -json > sbom.json
|
||||
```
|
||||
|
||||
### Syft
|
||||
|
||||
```bash
|
||||
# Install
|
||||
curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s
|
||||
|
||||
# Generate SBOM
|
||||
syft dir:/path/to/project -o cyclonedx-json > sbom.json
|
||||
syft dir:/path/to/project -o spdx-json > sbom-spdx.json
|
||||
|
||||
# From container
|
||||
syft myimage:latest -o cyclonedx-json > sbom.json
|
||||
```
|
||||
|
||||
## CI/CD Pipeline
|
||||
|
||||
```yaml
|
||||
# Comprehensive dependency scanning
|
||||
name: Dependency Security
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
schedule:
|
||||
- cron: '0 8 * * *'
|
||||
|
||||
jobs:
|
||||
scan:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: npm audit
|
||||
run: npm audit --audit-level=high
|
||||
|
||||
- name: Snyk scan
|
||||
uses: snyk/actions/node@master
|
||||
env:
|
||||
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
|
||||
with:
|
||||
args: --severity-threshold=high
|
||||
|
||||
- name: Generate SBOM
|
||||
run: npx @cyclonedx/cyclonedx-npm --output-file sbom.json
|
||||
|
||||
- name: Upload SBOM
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: sbom
|
||||
path: sbom.json
|
||||
```
|
||||
|
||||
## Common Issues
|
||||
|
||||
### Issue: Too Many Alerts
|
||||
**Problem**: Overwhelmed by vulnerability count
|
||||
**Solution**: Prioritize by exploitability, filter by severity
|
||||
|
||||
### Issue: No Fix Available
|
||||
**Problem**: Vulnerable dependency has no patch
|
||||
**Solution**: Consider alternatives, implement compensating controls
|
||||
|
||||
### Issue: Breaking Updates
|
||||
**Problem**: Security fix breaks functionality
|
||||
**Solution**: Review changelogs, test thoroughly, use lockfiles
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Scan on every build
|
||||
- Use lockfiles for reproducibility
|
||||
- Set severity thresholds
|
||||
- Generate and track SBOMs
|
||||
- Document exceptions properly
|
||||
- Update dependencies regularly
|
||||
- Monitor for new vulnerabilities
|
||||
- Automate PR creation for updates
|
||||
|
||||
## Related Skills
|
||||
|
||||
- [sast-scanning](../sast-scanning/) - Code vulnerabilities
|
||||
- [container-scanning](../container-scanning/) - Container dependencies
|
||||
- [github-actions](../../../devops/ci-cd/github-actions/) - CI integration
|
||||
@@ -0,0 +1,419 @@
|
||||
---
|
||||
name: sast-scanning
|
||||
description: Perform static application security testing with tools like Semgrep, CodeQL, and SonarQube. Identify security vulnerabilities in source code before deployment. Use when implementing secure SDLC, code review automation, or security gates in CI/CD pipelines.
|
||||
license: MIT
|
||||
metadata:
|
||||
author: devops-skills
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# SAST Scanning
|
||||
|
||||
Identify security vulnerabilities in source code through static analysis.
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
Use this skill when:
|
||||
- Implementing secure SDLC practices
|
||||
- Adding security gates to CI/CD
|
||||
- Automating code security reviews
|
||||
- Finding vulnerabilities before deployment
|
||||
- Meeting compliance requirements
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Source code access
|
||||
- CI/CD pipeline
|
||||
- SAST tool installation
|
||||
|
||||
## Tool Comparison
|
||||
|
||||
| Tool | License | Languages | Best For |
|
||||
|------|---------|-----------|----------|
|
||||
| Semgrep | OSS/Commercial | 30+ | Custom rules, speed |
|
||||
| CodeQL | Free (GitHub) | 10+ | Deep analysis |
|
||||
| SonarQube | OSS/Commercial | 25+ | Quality + Security |
|
||||
| Bandit | OSS | Python | Python projects |
|
||||
| Brakeman | OSS | Ruby | Rails apps |
|
||||
|
||||
## Semgrep
|
||||
|
||||
### Installation
|
||||
|
||||
```bash
|
||||
# Install via pip
|
||||
pip install semgrep
|
||||
|
||||
# Or via Homebrew
|
||||
brew install semgrep
|
||||
```
|
||||
|
||||
### Basic Usage
|
||||
|
||||
```bash
|
||||
# Run with default rules
|
||||
semgrep --config auto .
|
||||
|
||||
# Run specific rulesets
|
||||
semgrep --config p/security-audit .
|
||||
semgrep --config p/owasp-top-ten .
|
||||
semgrep --config p/ci .
|
||||
|
||||
# Scan specific languages
|
||||
semgrep --config p/python .
|
||||
semgrep --config p/javascript .
|
||||
|
||||
# Output formats
|
||||
semgrep --config auto --json -o results.json .
|
||||
semgrep --config auto --sarif -o results.sarif .
|
||||
```
|
||||
|
||||
### Custom Rules
|
||||
|
||||
```yaml
|
||||
# .semgrep/custom-rules.yaml
|
||||
rules:
|
||||
- id: hardcoded-password
|
||||
patterns:
|
||||
- pattern-either:
|
||||
- pattern: password = "..."
|
||||
- pattern: PASSWORD = "..."
|
||||
- pattern: passwd = "..."
|
||||
message: Hardcoded password detected
|
||||
severity: ERROR
|
||||
languages: [python, javascript, java]
|
||||
metadata:
|
||||
cwe: "CWE-798"
|
||||
owasp: "A3:2017"
|
||||
|
||||
- id: sql-injection
|
||||
patterns:
|
||||
- pattern: |
|
||||
$QUERY = "..." + $USER_INPUT + "..."
|
||||
$DB.execute($QUERY)
|
||||
message: Potential SQL injection
|
||||
severity: ERROR
|
||||
languages: [python]
|
||||
metadata:
|
||||
cwe: "CWE-89"
|
||||
|
||||
- id: insecure-random
|
||||
pattern: random.random()
|
||||
message: Use secrets module for security-sensitive randomness
|
||||
severity: WARNING
|
||||
languages: [python]
|
||||
fix: secrets.token_hex()
|
||||
```
|
||||
|
||||
### CI Configuration
|
||||
|
||||
```yaml
|
||||
# .github/workflows/semgrep.yml
|
||||
name: Semgrep
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
semgrep:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: returntocorp/semgrep
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Run Semgrep
|
||||
run: semgrep ci
|
||||
env:
|
||||
SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}
|
||||
```
|
||||
|
||||
## CodeQL
|
||||
|
||||
### Setup
|
||||
|
||||
```yaml
|
||||
# .github/workflows/codeql.yml
|
||||
name: CodeQL Analysis
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
branches: [main]
|
||||
schedule:
|
||||
- cron: '0 0 * * 0'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
security-events: write
|
||||
actions: read
|
||||
contents: read
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
language: ['javascript', 'python']
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v3
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
queries: +security-and-quality
|
||||
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v3
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v3
|
||||
with:
|
||||
category: "/language:${{ matrix.language }}"
|
||||
```
|
||||
|
||||
### Custom Queries
|
||||
|
||||
```ql
|
||||
// queries/sql-injection.ql
|
||||
/**
|
||||
* @name SQL Injection
|
||||
* @description User input in SQL query
|
||||
* @kind path-problem
|
||||
* @problem.severity error
|
||||
* @security-severity 9.0
|
||||
* @precision high
|
||||
* @id py/sql-injection
|
||||
* @tags security
|
||||
*/
|
||||
|
||||
import python
|
||||
import semmle.python.dataflow.new.DataFlow
|
||||
import semmle.python.dataflow.new.TaintTracking
|
||||
import semmle.python.security.dataflow.SqlInjectionQuery
|
||||
|
||||
from SqlInjectionConfiguration config, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where config.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink, "SQL injection from $@.", source.getNode(), "user input"
|
||||
```
|
||||
|
||||
## SonarQube
|
||||
|
||||
### Docker Setup
|
||||
|
||||
```yaml
|
||||
# docker-compose.yml
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
sonarqube:
|
||||
image: sonarqube:lts-community
|
||||
ports:
|
||||
- "9000:9000"
|
||||
environment:
|
||||
- SONAR_JDBC_URL=jdbc:postgresql://db:5432/sonar
|
||||
- SONAR_JDBC_USERNAME=sonar
|
||||
- SONAR_JDBC_PASSWORD=sonar
|
||||
volumes:
|
||||
- sonarqube_data:/opt/sonarqube/data
|
||||
- sonarqube_logs:/opt/sonarqube/logs
|
||||
depends_on:
|
||||
- db
|
||||
|
||||
db:
|
||||
image: postgres:15
|
||||
environment:
|
||||
- POSTGRES_USER=sonar
|
||||
- POSTGRES_PASSWORD=sonar
|
||||
- POSTGRES_DB=sonar
|
||||
volumes:
|
||||
- postgresql_data:/var/lib/postgresql/data
|
||||
|
||||
volumes:
|
||||
sonarqube_data:
|
||||
sonarqube_logs:
|
||||
postgresql_data:
|
||||
```
|
||||
|
||||
### Scanner Configuration
|
||||
|
||||
```properties
|
||||
# sonar-project.properties
|
||||
sonar.projectKey=myproject
|
||||
sonar.projectName=My Project
|
||||
sonar.projectVersion=1.0
|
||||
|
||||
sonar.sources=src
|
||||
sonar.tests=tests
|
||||
sonar.exclusions=**/node_modules/**,**/vendor/**
|
||||
|
||||
sonar.language=py
|
||||
sonar.python.coverage.reportPaths=coverage.xml
|
||||
|
||||
sonar.qualitygate.wait=true
|
||||
```
|
||||
|
||||
### CI Integration
|
||||
|
||||
```yaml
|
||||
# GitHub Actions
|
||||
- name: SonarQube Scan
|
||||
uses: sonarsource/sonarqube-scan-action@master
|
||||
env:
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
|
||||
|
||||
- name: Quality Gate
|
||||
uses: sonarsource/sonarqube-quality-gate-action@master
|
||||
timeout-minutes: 5
|
||||
env:
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
```
|
||||
|
||||
## Language-Specific Tools
|
||||
|
||||
### Python (Bandit)
|
||||
|
||||
```bash
|
||||
# Install
|
||||
pip install bandit
|
||||
|
||||
# Run scan
|
||||
bandit -r src/ -f json -o bandit-report.json
|
||||
|
||||
# With configuration
|
||||
bandit -r src/ -c bandit.yaml
|
||||
```
|
||||
|
||||
```yaml
|
||||
# bandit.yaml
|
||||
skips: ['B101', 'B601']
|
||||
exclude_dirs: ['tests', 'venv']
|
||||
|
||||
assert_used:
|
||||
skips: ['*_test.py', '*_tests.py']
|
||||
```
|
||||
|
||||
### JavaScript (ESLint Security)
|
||||
|
||||
```bash
|
||||
# Install
|
||||
npm install eslint eslint-plugin-security --save-dev
|
||||
```
|
||||
|
||||
```javascript
|
||||
// .eslintrc.js
|
||||
module.exports = {
|
||||
plugins: ['security'],
|
||||
extends: ['plugin:security/recommended'],
|
||||
rules: {
|
||||
'security/detect-object-injection': 'error',
|
||||
'security/detect-non-literal-regexp': 'warn',
|
||||
'security/detect-unsafe-regex': 'error',
|
||||
'security/detect-buffer-noassert': 'error',
|
||||
'security/detect-eval-with-expression': 'error',
|
||||
'security/detect-no-csrf-before-method-override': 'error',
|
||||
'security/detect-possible-timing-attacks': 'warn'
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### Ruby (Brakeman)
|
||||
|
||||
```bash
|
||||
# Install
|
||||
gem install brakeman
|
||||
|
||||
# Run scan
|
||||
brakeman -o brakeman-report.json -f json
|
||||
|
||||
# CI configuration
|
||||
brakeman --no-exit-on-warn --no-exit-on-error -o report.html
|
||||
```
|
||||
|
||||
## Quality Gates
|
||||
|
||||
### SonarQube Quality Gate
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "Security Gate",
|
||||
"conditions": [
|
||||
{
|
||||
"metric": "new_security_rating",
|
||||
"op": "GT",
|
||||
"error": "1"
|
||||
},
|
||||
{
|
||||
"metric": "new_vulnerabilities",
|
||||
"op": "GT",
|
||||
"error": "0"
|
||||
},
|
||||
{
|
||||
"metric": "new_security_hotspots_reviewed",
|
||||
"op": "LT",
|
||||
"error": "100"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Custom Gate Script
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# security-gate.sh
|
||||
|
||||
CRITICAL=$(cat results.json | jq '[.results[] | select(.severity == "critical")] | length')
|
||||
HIGH=$(cat results.json | jq '[.results[] | select(.severity == "high")] | length')
|
||||
|
||||
echo "Critical: $CRITICAL, High: $HIGH"
|
||||
|
||||
if [ "$CRITICAL" -gt 0 ]; then
|
||||
echo "FAILED: Critical vulnerabilities found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$HIGH" -gt 5 ]; then
|
||||
echo "FAILED: Too many high severity vulnerabilities"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "PASSED: Security gate"
|
||||
exit 0
|
||||
```
|
||||
|
||||
## Common Issues
|
||||
|
||||
### Issue: Too Many False Positives
|
||||
**Problem**: Alerts on safe code patterns
|
||||
**Solution**: Tune rules, add suppressions, use baseline
|
||||
|
||||
### Issue: Slow Scans
|
||||
**Problem**: SAST taking too long in CI
|
||||
**Solution**: Incremental scanning, parallel execution, exclude test files
|
||||
|
||||
### Issue: Missing Coverage
|
||||
**Problem**: Vulnerabilities not detected
|
||||
**Solution**: Add custom rules, combine multiple tools
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Run on every PR/commit
|
||||
- Establish baseline for existing code
|
||||
- Prioritize by severity and exploitability
|
||||
- Maintain custom rules for your codebase
|
||||
- Integrate with IDE for early feedback
|
||||
- Track trends over time
|
||||
- Document false positive suppressions
|
||||
- Combine with DAST for comprehensive coverage
|
||||
|
||||
## Related Skills
|
||||
|
||||
- [dast-scanning](../dast-scanning/) - Dynamic testing
|
||||
- [dependency-scanning](../dependency-scanning/) - Dependency vulnerabilities
|
||||
- [github-actions](../../../devops/ci-cd/github-actions/) - CI integration
|
||||
@@ -0,0 +1,106 @@
|
||||
# SAST Tools Reference
|
||||
|
||||
## Tool Comparison
|
||||
|
||||
| Tool | Languages | License | CI Integration |
|
||||
|------|-----------|---------|----------------|
|
||||
| **Semgrep** | 30+ | LGPL/Commercial | Excellent |
|
||||
| **SonarQube** | 30+ | LGPL/Commercial | Excellent |
|
||||
| **CodeQL** | 10+ | MIT | GitHub native |
|
||||
| **Bandit** | Python | Apache 2.0 | Good |
|
||||
| **ESLint Security** | JavaScript | MIT | Good |
|
||||
| **Brakeman** | Ruby | MIT | Good |
|
||||
|
||||
## Semgrep
|
||||
|
||||
```bash
|
||||
# Install
|
||||
pip install semgrep
|
||||
|
||||
# Scan with default rules
|
||||
semgrep --config auto .
|
||||
|
||||
# Scan with specific ruleset
|
||||
semgrep --config p/owasp-top-ten .
|
||||
semgrep --config p/security-audit .
|
||||
|
||||
# Output JSON
|
||||
semgrep --config auto --json -o results.json .
|
||||
```
|
||||
|
||||
### Custom Rules
|
||||
```yaml
|
||||
rules:
|
||||
- id: sql-injection
|
||||
patterns:
|
||||
- pattern: |
|
||||
$QUERY = "..." + $INPUT + "..."
|
||||
- metavariable-regex:
|
||||
metavariable: $QUERY
|
||||
regex: (?i)(select|insert|update|delete)
|
||||
message: "Potential SQL injection"
|
||||
severity: ERROR
|
||||
languages: [python]
|
||||
```
|
||||
|
||||
## SonarQube
|
||||
|
||||
```bash
|
||||
# Scanner CLI
|
||||
sonar-scanner \
|
||||
-Dsonar.projectKey=myproject \
|
||||
-Dsonar.sources=src \
|
||||
-Dsonar.host.url=http://sonarqube:9000 \
|
||||
-Dsonar.token=$SONAR_TOKEN
|
||||
```
|
||||
|
||||
### Quality Gate
|
||||
```yaml
|
||||
# sonar-project.properties
|
||||
sonar.projectKey=myproject
|
||||
sonar.sources=src
|
||||
sonar.tests=tests
|
||||
sonar.coverage.exclusions=**/test/**
|
||||
sonar.qualitygate.wait=true
|
||||
```
|
||||
|
||||
## CodeQL
|
||||
|
||||
```yaml
|
||||
# .github/workflows/codeql.yml
|
||||
- uses: github/codeql-action/init@v2
|
||||
with:
|
||||
languages: javascript, python
|
||||
|
||||
- uses: github/codeql-action/analyze@v2
|
||||
```
|
||||
|
||||
## Bandit (Python)
|
||||
|
||||
```bash
|
||||
# Run scan
|
||||
bandit -r ./src -f json -o bandit-report.json
|
||||
|
||||
# With severity filter
|
||||
bandit -r ./src -ll # Medium and above
|
||||
```
|
||||
|
||||
## ESLint Security
|
||||
|
||||
```json
|
||||
// .eslintrc
|
||||
{
|
||||
"plugins": ["security"],
|
||||
"extends": ["plugin:security/recommended"]
|
||||
}
|
||||
```
|
||||
|
||||
## CI Integration
|
||||
|
||||
```yaml
|
||||
# GitHub Actions
|
||||
- name: Run Semgrep
|
||||
uses: returntocorp/semgrep-action@v1
|
||||
with:
|
||||
config: p/security-audit
|
||||
```
|
||||
@@ -0,0 +1,411 @@
|
||||
---
|
||||
name: vulnerability-scanning
|
||||
description: Scan systems and dependencies for CVEs and security vulnerabilities. Use tools like Nessus, OpenVAS, and Qualys to identify and prioritize vulnerabilities. Use when performing security assessments, compliance scanning, or vulnerability management.
|
||||
license: MIT
|
||||
metadata:
|
||||
author: devops-skills
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# Vulnerability Scanning
|
||||
|
||||
Identify and prioritize security vulnerabilities across infrastructure and applications.
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
Use this skill when:
|
||||
- Performing security assessments
|
||||
- Implementing vulnerability management programs
|
||||
- Meeting compliance requirements
|
||||
- Triaging and prioritizing remediation
|
||||
- Scanning infrastructure for known CVEs
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Access to scanning tools
|
||||
- Network access to targets
|
||||
- Appropriate authorization
|
||||
|
||||
## Vulnerability Scanning Tools
|
||||
|
||||
| Tool | Type | Best For |
|
||||
|------|------|----------|
|
||||
| Nessus | Commercial | Enterprise scanning |
|
||||
| OpenVAS | Open Source | Free alternative |
|
||||
| Qualys | Cloud SaaS | Large scale |
|
||||
| Nexpose/InsightVM | Commercial | Asset management |
|
||||
| Nuclei | Open Source | Template-based |
|
||||
|
||||
## OpenVAS Setup
|
||||
|
||||
### Docker Deployment
|
||||
|
||||
```bash
|
||||
# Run OpenVAS container
|
||||
docker run -d --name openvas \
|
||||
-p 443:443 \
|
||||
-v openvas-data:/data \
|
||||
greenbone/openvas-scanner
|
||||
|
||||
# Access web UI at https://localhost
|
||||
# Default credentials: admin/admin
|
||||
```
|
||||
|
||||
### Scanning Commands
|
||||
|
||||
```bash
|
||||
# Create target
|
||||
omp -u admin -w admin --xml='<create_target>
|
||||
<name>Web Servers</name>
|
||||
<hosts>192.168.1.0/24</hosts>
|
||||
</create_target>'
|
||||
|
||||
# Create task
|
||||
omp -u admin -w admin --xml='<create_task>
|
||||
<name>Weekly Scan</name>
|
||||
<target id="target-uuid"/>
|
||||
<config id="daba56c8-73ec-11df-a475-002264764cea"/>
|
||||
</create_task>'
|
||||
|
||||
# Start task
|
||||
omp -u admin -w admin --xml='<start_task task_id="task-uuid"/>'
|
||||
|
||||
# Get results
|
||||
omp -u admin -w admin --xml='<get_results task_id="task-uuid"/>'
|
||||
```
|
||||
|
||||
## Nessus
|
||||
|
||||
### API Usage
|
||||
|
||||
```python
|
||||
import requests
|
||||
|
||||
class NessusScanner:
|
||||
def __init__(self, url, access_key, secret_key):
|
||||
self.url = url
|
||||
self.headers = {
|
||||
'X-ApiKeys': f'accessKey={access_key}; secretKey={secret_key}',
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
|
||||
def create_scan(self, name, targets, template='basic'):
|
||||
"""Create a new scan."""
|
||||
templates = self.get('/editor/scan/templates')
|
||||
template_uuid = next(
|
||||
t['uuid'] for t in templates['templates']
|
||||
if t['name'] == template
|
||||
)
|
||||
|
||||
payload = {
|
||||
'uuid': template_uuid,
|
||||
'settings': {
|
||||
'name': name,
|
||||
'text_targets': targets,
|
||||
'enabled': True
|
||||
}
|
||||
}
|
||||
return self.post('/scans', payload)
|
||||
|
||||
def launch_scan(self, scan_id):
|
||||
"""Start a scan."""
|
||||
return self.post(f'/scans/{scan_id}/launch')
|
||||
|
||||
def get_results(self, scan_id):
|
||||
"""Get scan results."""
|
||||
return self.get(f'/scans/{scan_id}')
|
||||
|
||||
def export_report(self, scan_id, format='pdf'):
|
||||
"""Export scan report."""
|
||||
payload = {'format': format}
|
||||
response = self.post(f'/scans/{scan_id}/export', payload)
|
||||
file_id = response['file']
|
||||
|
||||
# Wait for export
|
||||
while True:
|
||||
status = self.get(f'/scans/{scan_id}/export/{file_id}/status')
|
||||
if status['status'] == 'ready':
|
||||
break
|
||||
time.sleep(5)
|
||||
|
||||
return self.get(f'/scans/{scan_id}/export/{file_id}/download')
|
||||
|
||||
def get(self, path):
|
||||
response = requests.get(f'{self.url}{path}', headers=self.headers, verify=False)
|
||||
return response.json()
|
||||
|
||||
def post(self, path, data=None):
|
||||
response = requests.post(f'{self.url}{path}', json=data, headers=self.headers, verify=False)
|
||||
return response.json()
|
||||
|
||||
# Usage
|
||||
scanner = NessusScanner('https://nessus:8834', 'access-key', 'secret-key')
|
||||
scan = scanner.create_scan('Weekly Infrastructure Scan', '10.0.0.0/24')
|
||||
scanner.launch_scan(scan['scan']['id'])
|
||||
```
|
||||
|
||||
## Nuclei
|
||||
|
||||
### Installation
|
||||
|
||||
```bash
|
||||
# Install nuclei
|
||||
go install -v github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest
|
||||
|
||||
# Or download binary
|
||||
wget https://github.com/projectdiscovery/nuclei/releases/latest/download/nuclei_linux_amd64.zip
|
||||
unzip nuclei_linux_amd64.zip
|
||||
```
|
||||
|
||||
### Basic Scanning
|
||||
|
||||
```bash
|
||||
# Update templates
|
||||
nuclei -update-templates
|
||||
|
||||
# Scan single target
|
||||
nuclei -u https://example.com
|
||||
|
||||
# Scan multiple targets
|
||||
nuclei -l targets.txt
|
||||
|
||||
# Scan with specific templates
|
||||
nuclei -u https://example.com -t cves/
|
||||
nuclei -u https://example.com -t vulnerabilities/
|
||||
|
||||
# Scan with severity filter
|
||||
nuclei -u https://example.com -s critical,high
|
||||
|
||||
# Output formats
|
||||
nuclei -u https://example.com -o results.txt
|
||||
nuclei -u https://example.com -json -o results.json
|
||||
```
|
||||
|
||||
### Custom Templates
|
||||
|
||||
```yaml
|
||||
# custom-check.yaml
|
||||
id: custom-admin-panel
|
||||
|
||||
info:
|
||||
name: Admin Panel Detection
|
||||
author: security-team
|
||||
severity: info
|
||||
tags: recon,panel
|
||||
|
||||
requests:
|
||||
- method: GET
|
||||
path:
|
||||
- "{{BaseURL}}/admin"
|
||||
- "{{BaseURL}}/administrator"
|
||||
- "{{BaseURL}}/wp-admin"
|
||||
|
||||
matchers-condition: or
|
||||
matchers:
|
||||
- type: word
|
||||
words:
|
||||
- "admin"
|
||||
- "login"
|
||||
condition: and
|
||||
|
||||
- type: status
|
||||
status:
|
||||
- 200
|
||||
- 301
|
||||
- 302
|
||||
```
|
||||
|
||||
## CVSS Scoring
|
||||
|
||||
### Severity Levels
|
||||
|
||||
| Score | Rating | Response Time |
|
||||
|-------|--------|---------------|
|
||||
| 9.0-10.0 | Critical | 24 hours |
|
||||
| 7.0-8.9 | High | 7 days |
|
||||
| 4.0-6.9 | Medium | 30 days |
|
||||
| 0.1-3.9 | Low | 90 days |
|
||||
|
||||
### Prioritization Factors
|
||||
|
||||
```yaml
|
||||
prioritization_criteria:
|
||||
critical_factors:
|
||||
- Internet-facing systems
|
||||
- Systems with sensitive data
|
||||
- Active exploitation in the wild
|
||||
- Authentication bypass
|
||||
|
||||
high_factors:
|
||||
- Remote code execution
|
||||
- Privilege escalation
|
||||
- Data exfiltration risk
|
||||
|
||||
context_adjustments:
|
||||
- Compensating controls in place (-1)
|
||||
- No direct exposure (-1)
|
||||
- Critical business system (+1)
|
||||
- Compliance requirement (+1)
|
||||
```
|
||||
|
||||
## Vulnerability Management Process
|
||||
|
||||
### Workflow
|
||||
|
||||
```yaml
|
||||
vulnerability_workflow:
|
||||
discovery:
|
||||
- Run scheduled scans
|
||||
- Import third-party findings
|
||||
- Correlate with asset inventory
|
||||
|
||||
analysis:
|
||||
- Validate findings
|
||||
- Remove false positives
|
||||
- Assess business impact
|
||||
- Prioritize by risk score
|
||||
|
||||
remediation:
|
||||
- Assign to owners
|
||||
- Track SLA compliance
|
||||
- Verify fixes
|
||||
- Document exceptions
|
||||
|
||||
reporting:
|
||||
- Executive summaries
|
||||
- Technical details
|
||||
- Trend analysis
|
||||
- Compliance metrics
|
||||
```
|
||||
|
||||
### Tracking Template
|
||||
|
||||
```markdown
|
||||
## Vulnerability Ticket
|
||||
|
||||
**ID:** VULN-2024-001
|
||||
**CVE:** CVE-2024-12345
|
||||
**CVSS:** 9.8 (Critical)
|
||||
**Affected System:** web-server-01
|
||||
|
||||
### Description
|
||||
Remote code execution vulnerability in Apache Struts.
|
||||
|
||||
### Impact
|
||||
Attacker can execute arbitrary code on the server.
|
||||
|
||||
### Remediation
|
||||
1. Update Apache Struts to version 2.5.33
|
||||
2. Apply WAF rule as temporary mitigation
|
||||
|
||||
### Timeline
|
||||
- Discovered: 2024-01-15
|
||||
- SLA Due: 2024-01-16
|
||||
- Remediated: 2024-01-15
|
||||
|
||||
### Evidence
|
||||
- Scan report: [link]
|
||||
- Screenshot: [link]
|
||||
```
|
||||
|
||||
## CI/CD Integration
|
||||
|
||||
### GitHub Actions
|
||||
|
||||
```yaml
|
||||
name: Vulnerability Scan
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 2 * * *'
|
||||
push:
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
scan:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Run Nuclei
|
||||
uses: projectdiscovery/nuclei-action@main
|
||||
with:
|
||||
target: https://example.com
|
||||
templates: cves/
|
||||
output: nuclei-results.txt
|
||||
|
||||
- name: Check for critical findings
|
||||
run: |
|
||||
if grep -q "critical" nuclei-results.txt; then
|
||||
echo "Critical vulnerabilities found!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Upload results
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: vulnerability-report
|
||||
path: nuclei-results.txt
|
||||
```
|
||||
|
||||
## Compliance Scanning
|
||||
|
||||
### CIS Benchmark Scan
|
||||
|
||||
```bash
|
||||
# Using OpenSCAP
|
||||
oscap xccdf eval \
|
||||
--profile xccdf_org.ssgproject.content_profile_cis \
|
||||
--results results.xml \
|
||||
--report report.html \
|
||||
/usr/share/xml/scap/ssg/content/ssg-ubuntu2204-ds.xml
|
||||
```
|
||||
|
||||
### PCI DSS Scanning
|
||||
|
||||
```yaml
|
||||
pci_scan_requirements:
|
||||
quarterly:
|
||||
- External vulnerability scan (ASV)
|
||||
- Internal vulnerability scan
|
||||
|
||||
after_changes:
|
||||
- Significant infrastructure changes
|
||||
- New system deployments
|
||||
|
||||
passing_criteria:
|
||||
- No vulnerabilities rated 4.0+ (CVSS)
|
||||
- False positives documented
|
||||
- Scan completed within 90 days
|
||||
```
|
||||
|
||||
## Common Issues
|
||||
|
||||
### Issue: False Positives
|
||||
**Problem**: Scanner reports non-existent vulnerabilities
|
||||
**Solution**: Validate manually, tune scanner, maintain exception list
|
||||
|
||||
### Issue: Incomplete Coverage
|
||||
**Problem**: Not all assets scanned
|
||||
**Solution**: Update asset inventory, verify credentials, check network access
|
||||
|
||||
### Issue: Scan Impact
|
||||
**Problem**: Scans affecting production systems
|
||||
**Solution**: Schedule during maintenance windows, use authenticated scans
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Maintain accurate asset inventory
|
||||
- Schedule regular scan cadence
|
||||
- Validate findings before remediation
|
||||
- Track metrics (MTTR, aging)
|
||||
- Integrate with ticketing systems
|
||||
- Document exceptions properly
|
||||
- Use risk-based prioritization
|
||||
- Automate where possible
|
||||
|
||||
## Related Skills
|
||||
|
||||
- [sast-scanning](../sast-scanning/) - Code analysis
|
||||
- [container-scanning](../container-scanning/) - Container security
|
||||
- [cis-benchmarks](../../hardening/cis-benchmarks/) - Compliance benchmarks
|
||||
@@ -0,0 +1,94 @@
|
||||
# GitHub Actions Vulnerability Scanning Workflow
|
||||
# Add to .github/workflows/security-scan.yaml
|
||||
|
||||
name: Security Scan
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main, develop]
|
||||
pull_request:
|
||||
branches: [main]
|
||||
schedule:
|
||||
# Run daily at midnight
|
||||
- cron: '0 0 * * *'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
jobs:
|
||||
trivy-scan:
|
||||
name: Trivy Vulnerability Scan
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Run Trivy vulnerability scanner (filesystem)
|
||||
uses: aquasecurity/trivy-action@master
|
||||
with:
|
||||
scan-type: 'fs'
|
||||
scan-ref: '.'
|
||||
format: 'sarif'
|
||||
output: 'trivy-fs-results.sarif'
|
||||
severity: 'CRITICAL,HIGH'
|
||||
|
||||
- name: Upload Trivy scan results to GitHub Security tab
|
||||
uses: github/codeql-action/upload-sarif@v3
|
||||
if: always()
|
||||
with:
|
||||
sarif_file: 'trivy-fs-results.sarif'
|
||||
|
||||
container-scan:
|
||||
name: Container Image Scan
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'push'
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Build image
|
||||
run: docker build -t myapp:${{ github.sha }} .
|
||||
|
||||
- name: Run Trivy vulnerability scanner (image)
|
||||
uses: aquasecurity/trivy-action@master
|
||||
with:
|
||||
image-ref: 'myapp:${{ github.sha }}'
|
||||
format: 'sarif'
|
||||
output: 'trivy-image-results.sarif'
|
||||
severity: 'CRITICAL,HIGH'
|
||||
ignore-unfixed: true
|
||||
|
||||
- name: Upload Trivy scan results
|
||||
uses: github/codeql-action/upload-sarif@v3
|
||||
if: always()
|
||||
with:
|
||||
sarif_file: 'trivy-image-results.sarif'
|
||||
|
||||
dependency-review:
|
||||
name: Dependency Review
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'pull_request'
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Dependency Review
|
||||
uses: actions/dependency-review-action@v3
|
||||
with:
|
||||
fail-on-severity: high
|
||||
deny-licenses: GPL-3.0, AGPL-3.0
|
||||
|
||||
secrets-scan:
|
||||
name: Secret Detection
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Gitleaks scan
|
||||
uses: gitleaks/gitleaks-action@v2
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -0,0 +1,70 @@
|
||||
# Trivy Configuration
|
||||
# Place in project root or ~/.trivy.yaml
|
||||
|
||||
# Scan settings
|
||||
scan:
|
||||
# Scanners to use
|
||||
scanners:
|
||||
- vuln
|
||||
- secret
|
||||
- config
|
||||
|
||||
# Severity levels to report
|
||||
severity:
|
||||
- CRITICAL
|
||||
- HIGH
|
||||
- MEDIUM
|
||||
|
||||
# Vulnerability settings
|
||||
vulnerability:
|
||||
# Ignore unfixed vulnerabilities
|
||||
ignore-unfixed: true
|
||||
|
||||
# Vulnerability types
|
||||
type:
|
||||
- os
|
||||
- library
|
||||
|
||||
# Secret scanning settings
|
||||
secret:
|
||||
config: trivy-secret.yaml
|
||||
|
||||
# Misconfiguration settings
|
||||
misconfiguration:
|
||||
# Policy paths (custom OPA policies)
|
||||
policy:
|
||||
- ./policies
|
||||
|
||||
# Cache settings
|
||||
cache:
|
||||
# Cache directory
|
||||
dir: /tmp/trivy-cache
|
||||
|
||||
# Cache TTL in hours
|
||||
ttl: 24h
|
||||
|
||||
# Database settings
|
||||
db:
|
||||
# Repository for vulnerability database
|
||||
repository: ghcr.io/aquasecurity/trivy-db
|
||||
|
||||
# Output settings
|
||||
format: table
|
||||
output: ""
|
||||
|
||||
# Exit code when vulnerabilities found
|
||||
exit-code: 0
|
||||
|
||||
# Ignore specific files
|
||||
skip-files:
|
||||
- "**/*_test.go"
|
||||
- "**/test/**"
|
||||
|
||||
# Ignore specific directories
|
||||
skip-dirs:
|
||||
- node_modules
|
||||
- vendor
|
||||
- .git
|
||||
|
||||
# Custom ignore file
|
||||
ignorefile: .trivyignore.yaml
|
||||
@@ -0,0 +1,135 @@
|
||||
# Vulnerability Remediation Guide
|
||||
|
||||
## Triage Process
|
||||
|
||||
### 1. Assess Impact
|
||||
- Is the vulnerability exploitable in your context?
|
||||
- Is the vulnerable component reachable?
|
||||
- What's the potential business impact?
|
||||
|
||||
### 2. Prioritize
|
||||
```
|
||||
Priority Matrix:
|
||||
Exploitable
|
||||
Yes No
|
||||
Impact High P1-Critical P2-High
|
||||
Medium P2-High P3-Medium
|
||||
Low P3-Medium P4-Low
|
||||
```
|
||||
|
||||
### 3. Remediation Options
|
||||
|
||||
| Option | When to Use |
|
||||
|--------|-------------|
|
||||
| **Upgrade** | Fix available, no breaking changes |
|
||||
| **Patch** | Apply security patch |
|
||||
| **Workaround** | Mitigate until fix available |
|
||||
| **Accept** | Risk accepted with documentation |
|
||||
| **Remove** | Dependency not needed |
|
||||
|
||||
## Common Remediation Steps
|
||||
|
||||
### Container Base Images
|
||||
|
||||
```dockerfile
|
||||
# Before: Vulnerable base
|
||||
FROM ubuntu:20.04
|
||||
|
||||
# After: Updated base
|
||||
FROM ubuntu:22.04
|
||||
|
||||
# Better: Minimal base
|
||||
FROM gcr.io/distroless/base-debian12
|
||||
```
|
||||
|
||||
### JavaScript Dependencies
|
||||
|
||||
```bash
|
||||
# View outdated packages
|
||||
npm outdated
|
||||
|
||||
# Update specific package
|
||||
npm update lodash
|
||||
|
||||
# Update all (careful!)
|
||||
npm update
|
||||
|
||||
# Force resolution
|
||||
npm audit fix --force
|
||||
|
||||
# Check for updates
|
||||
npx npm-check-updates
|
||||
```
|
||||
|
||||
### Python Dependencies
|
||||
|
||||
```bash
|
||||
# Update specific package
|
||||
pip install --upgrade requests
|
||||
|
||||
# Update with constraints
|
||||
pip install 'requests>=2.28.0,<3.0.0'
|
||||
|
||||
# Using pip-tools
|
||||
pip-compile --upgrade requirements.in
|
||||
```
|
||||
|
||||
### Terraform Providers
|
||||
|
||||
```hcl
|
||||
# Pin to secure version
|
||||
terraform {
|
||||
required_providers {
|
||||
aws = {
|
||||
source = "hashicorp/aws"
|
||||
version = "~> 5.0" # Update to latest minor
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## False Positive Handling
|
||||
|
||||
### Trivy Ignore
|
||||
```yaml
|
||||
# .trivyignore
|
||||
CVE-2022-12345 # Reason: Not exploitable in our context
|
||||
CVE-2022-67890 # Reason: Component not exposed
|
||||
```
|
||||
|
||||
### Grype Ignore
|
||||
```yaml
|
||||
# .grype.yaml
|
||||
ignore:
|
||||
- vulnerability: CVE-2022-12345
|
||||
reason: "Not applicable - component not used"
|
||||
```
|
||||
|
||||
## Documentation Template
|
||||
|
||||
```markdown
|
||||
## Vulnerability Assessment: CVE-XXXX-XXXXX
|
||||
|
||||
**Severity:** High (CVSS 7.5)
|
||||
**Component:** package-name v1.2.3
|
||||
**Status:** [Remediated/Accepted/Pending]
|
||||
|
||||
### Description
|
||||
Brief description of the vulnerability.
|
||||
|
||||
### Impact Assessment
|
||||
- Exploitability in our environment: [Yes/No/Partial]
|
||||
- Affected systems: [List systems]
|
||||
- Business impact: [Description]
|
||||
|
||||
### Remediation
|
||||
- Action taken: Upgraded to v1.2.4
|
||||
- Date: YYYY-MM-DD
|
||||
- Verified by: [Name]
|
||||
|
||||
### If Accepted
|
||||
- Reason for acceptance:
|
||||
- Compensating controls:
|
||||
- Review date:
|
||||
- Approved by:
|
||||
```
|
||||
@@ -0,0 +1,93 @@
|
||||
# Vulnerability Scanner Comparison
|
||||
|
||||
## Container Image Scanners
|
||||
|
||||
| Tool | License | Speed | Database | CI Integration |
|
||||
|------|---------|-------|----------|----------------|
|
||||
| **Trivy** | Apache 2.0 | Fast | NVD, Red Hat, etc. | Excellent |
|
||||
| **Grype** | Apache 2.0 | Fast | Anchore DB | Good |
|
||||
| **Clair** | Apache 2.0 | Medium | NVD, Alpine, etc. | Good |
|
||||
| **Snyk** | Commercial | Fast | Snyk DB | Excellent |
|
||||
| **Docker Scout** | Commercial | Fast | Docker DB | Native |
|
||||
|
||||
## Recommended: Trivy
|
||||
|
||||
### Installation
|
||||
```bash
|
||||
# Homebrew
|
||||
brew install trivy
|
||||
|
||||
# APT
|
||||
apt-get install trivy
|
||||
|
||||
# Docker
|
||||
docker run aquasec/trivy image nginx:latest
|
||||
```
|
||||
|
||||
### Basic Usage
|
||||
```bash
|
||||
# Scan image
|
||||
trivy image nginx:latest
|
||||
|
||||
# Scan with severity filter
|
||||
trivy image --severity HIGH,CRITICAL nginx:latest
|
||||
|
||||
# Scan and fail on vulnerabilities
|
||||
trivy image --exit-code 1 --severity CRITICAL nginx:latest
|
||||
|
||||
# JSON output
|
||||
trivy image -f json -o results.json nginx:latest
|
||||
|
||||
# Scan filesystem
|
||||
trivy fs /path/to/project
|
||||
|
||||
# Scan Kubernetes
|
||||
trivy k8s --report summary cluster
|
||||
```
|
||||
|
||||
### GitHub Actions
|
||||
```yaml
|
||||
- name: Run Trivy vulnerability scanner
|
||||
uses: aquasecurity/trivy-action@master
|
||||
with:
|
||||
image-ref: 'myapp:${{ github.sha }}'
|
||||
format: 'sarif'
|
||||
output: 'trivy-results.sarif'
|
||||
severity: 'CRITICAL,HIGH'
|
||||
|
||||
- name: Upload Trivy scan results
|
||||
uses: github/codeql-action/upload-sarif@v2
|
||||
with:
|
||||
sarif_file: 'trivy-results.sarif'
|
||||
```
|
||||
|
||||
## Dependency Scanners
|
||||
|
||||
| Tool | Languages | License |
|
||||
|------|-----------|---------|
|
||||
| **npm audit** | JavaScript | Free |
|
||||
| **pip-audit** | Python | Free |
|
||||
| **bundle audit** | Ruby | Free |
|
||||
| **cargo audit** | Rust | Free |
|
||||
| **Snyk** | Multi | Commercial |
|
||||
| **Dependabot** | Multi | Free (GitHub) |
|
||||
| **OWASP Dependency-Check** | Multi | Apache 2.0 |
|
||||
|
||||
## Infrastructure as Code Scanners
|
||||
|
||||
| Tool | Targets | License |
|
||||
|------|---------|---------|
|
||||
| **tfsec** | Terraform | MIT |
|
||||
| **checkov** | TF, CloudFormation, K8s | Apache 2.0 |
|
||||
| **kics** | Multi IaC | Apache 2.0 |
|
||||
| **kubesec** | Kubernetes | Apache 2.0 |
|
||||
|
||||
## CVSS Score Reference
|
||||
|
||||
| Score | Severity |
|
||||
|-------|----------|
|
||||
| 0.0 | None |
|
||||
| 0.1-3.9 | Low |
|
||||
| 4.0-6.9 | Medium |
|
||||
| 7.0-8.9 | High |
|
||||
| 9.0-10.0 | Critical |
|
||||
@@ -0,0 +1,53 @@
|
||||
#!/bin/bash
|
||||
# Container Image Vulnerability Scanner
|
||||
# Usage: ./scan-images.sh <image> [--severity HIGH,CRITICAL] [--format json|table]
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
IMAGE="${1:-}"
|
||||
SEVERITY="${2:-HIGH,CRITICAL}"
|
||||
FORMAT="${3:-table}"
|
||||
|
||||
if [ -z "$IMAGE" ]; then
|
||||
echo "Usage: $0 <image> [--severity HIGH,CRITICAL] [--format json|table]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "========================================="
|
||||
echo "Scanning Image: $IMAGE"
|
||||
echo "Severity Filter: $SEVERITY"
|
||||
echo "========================================="
|
||||
echo ""
|
||||
|
||||
# Check which scanner is available
|
||||
if command -v trivy &>/dev/null; then
|
||||
echo "Using Trivy scanner..."
|
||||
trivy image \
|
||||
--severity "$SEVERITY" \
|
||||
--format "$FORMAT" \
|
||||
--ignore-unfixed \
|
||||
"$IMAGE"
|
||||
|
||||
elif command -v grype &>/dev/null; then
|
||||
echo "Using Grype scanner..."
|
||||
grype "$IMAGE" \
|
||||
--only-fixed \
|
||||
--fail-on high \
|
||||
-o "$FORMAT"
|
||||
|
||||
elif command -v docker &>/dev/null && docker scout version &>/dev/null 2>&1; then
|
||||
echo "Using Docker Scout..."
|
||||
docker scout cves "$IMAGE" \
|
||||
--only-severity critical,high \
|
||||
--format "$FORMAT"
|
||||
|
||||
else
|
||||
echo "Error: No vulnerability scanner found."
|
||||
echo "Install one of: trivy, grype, or docker scout"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "========================================="
|
||||
echo "Scan complete"
|
||||
echo "========================================="
|
||||
@@ -0,0 +1,81 @@
|
||||
#!/bin/bash
|
||||
# Repository Vulnerability Scanner
|
||||
# Scans for vulnerabilities in dependencies and IaC
|
||||
# Usage: ./scan-repo.sh [directory] [--output report.json]
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCAN_DIR="${1:-.}"
|
||||
OUTPUT="${2:-}"
|
||||
|
||||
echo "========================================="
|
||||
echo "Repository Security Scan"
|
||||
echo "Directory: $SCAN_DIR"
|
||||
echo "========================================="
|
||||
echo ""
|
||||
|
||||
ISSUES_FOUND=0
|
||||
|
||||
# Trivy filesystem scan
|
||||
if command -v trivy &>/dev/null; then
|
||||
echo "=== Trivy Filesystem Scan ==="
|
||||
trivy fs "$SCAN_DIR" \
|
||||
--severity HIGH,CRITICAL \
|
||||
--scanners vuln,secret,config \
|
||||
--ignore-unfixed \
|
||||
|| ISSUES_FOUND=1
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# Check for secrets with gitleaks
|
||||
if command -v gitleaks &>/dev/null; then
|
||||
echo "=== GitLeaks Secret Scan ==="
|
||||
gitleaks detect --source "$SCAN_DIR" --no-git || ISSUES_FOUND=1
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# Check Terraform with tfsec
|
||||
if command -v tfsec &>/dev/null && [ -d "$SCAN_DIR" ]; then
|
||||
if find "$SCAN_DIR" -name "*.tf" -print -quit | grep -q .; then
|
||||
echo "=== TFSec Terraform Scan ==="
|
||||
tfsec "$SCAN_DIR" --minimum-severity HIGH || ISSUES_FOUND=1
|
||||
echo ""
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check Kubernetes manifests with kubesec
|
||||
if command -v kubesec &>/dev/null; then
|
||||
for manifest in $(find "$SCAN_DIR" -name "*.yaml" -o -name "*.yml" 2>/dev/null | head -10); do
|
||||
if grep -q "kind:" "$manifest" 2>/dev/null; then
|
||||
echo "=== Kubesec: $manifest ==="
|
||||
kubesec scan "$manifest" 2>/dev/null || true
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# Python dependencies
|
||||
if [ -f "$SCAN_DIR/requirements.txt" ]; then
|
||||
if command -v pip-audit &>/dev/null; then
|
||||
echo "=== Python Dependency Audit ==="
|
||||
pip-audit -r "$SCAN_DIR/requirements.txt" || ISSUES_FOUND=1
|
||||
echo ""
|
||||
fi
|
||||
fi
|
||||
|
||||
# Node.js dependencies
|
||||
if [ -f "$SCAN_DIR/package.json" ]; then
|
||||
if command -v npm &>/dev/null; then
|
||||
echo "=== NPM Audit ==="
|
||||
(cd "$SCAN_DIR" && npm audit --audit-level=high 2>/dev/null) || ISSUES_FOUND=1
|
||||
echo ""
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "========================================="
|
||||
if [ $ISSUES_FOUND -eq 1 ]; then
|
||||
echo "⚠ Security issues found - review above"
|
||||
exit 1
|
||||
else
|
||||
echo "✓ No critical security issues found"
|
||||
fi
|
||||
echo "========================================="
|
||||
@@ -0,0 +1,85 @@
|
||||
---
|
||||
name: aws-secrets-manager
|
||||
description: Store and rotate secrets in AWS Secrets Manager. Configure automatic rotation, access policies, and application integration. Use when managing secrets in AWS environments or requiring automatic credential rotation.
|
||||
license: MIT
|
||||
metadata:
|
||||
author: devops-skills
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# AWS Secrets Manager
|
||||
|
||||
Securely store, manage, and rotate secrets in AWS.
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
Use this skill when:
|
||||
- Storing database credentials
|
||||
- Managing API keys in AWS
|
||||
- Implementing automatic secret rotation
|
||||
- Integrating secrets with AWS services
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- AWS account
|
||||
- AWS CLI configured
|
||||
- IAM permissions for Secrets Manager
|
||||
|
||||
## Basic Operations
|
||||
|
||||
```bash
|
||||
# Create secret
|
||||
aws secretsmanager create-secret \
|
||||
--name myapp/database \
|
||||
--secret-string '{"username":"admin","password":"secret123"}'
|
||||
|
||||
# Get secret
|
||||
aws secretsmanager get-secret-value --secret-id myapp/database
|
||||
|
||||
# Update secret
|
||||
aws secretsmanager put-secret-value \
|
||||
--secret-id myapp/database \
|
||||
--secret-string '{"username":"admin","password":"newpassword"}'
|
||||
|
||||
# Delete secret
|
||||
aws secretsmanager delete-secret --secret-id myapp/database --recovery-window-in-days 7
|
||||
```
|
||||
|
||||
## Automatic Rotation
|
||||
|
||||
```bash
|
||||
# Enable rotation with Lambda
|
||||
aws secretsmanager rotate-secret \
|
||||
--secret-id myapp/database \
|
||||
--rotation-lambda-arn arn:aws:lambda:region:account:function:rotation-function \
|
||||
--rotation-rules AutomaticallyAfterDays=30
|
||||
```
|
||||
|
||||
## Application Integration
|
||||
|
||||
```python
|
||||
import boto3
|
||||
import json
|
||||
|
||||
def get_secret(secret_name):
|
||||
client = boto3.client('secretsmanager')
|
||||
response = client.get_secret_value(SecretId=secret_name)
|
||||
return json.loads(response['SecretString'])
|
||||
|
||||
# Usage
|
||||
creds = get_secret('myapp/database')
|
||||
db_connect(creds['username'], creds['password'])
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Enable automatic rotation
|
||||
- Use resource-based policies
|
||||
- Enable encryption with KMS
|
||||
- Implement least-privilege access
|
||||
- Use versioning for rollback
|
||||
|
||||
## Related Skills
|
||||
|
||||
- [hashicorp-vault](../hashicorp-vault/) - Multi-cloud secrets
|
||||
- [aws-iam](../../../infrastructure/cloud-aws/aws-iam/) - IAM policies
|
||||
@@ -0,0 +1,115 @@
|
||||
# AWS Secrets Manager Patterns
|
||||
|
||||
## Basic Operations
|
||||
|
||||
```bash
|
||||
# Create secret
|
||||
aws secretsmanager create-secret \
|
||||
--name myapp/database \
|
||||
--secret-string '{"username":"admin","password":"secret123"}'
|
||||
|
||||
# Get secret
|
||||
aws secretsmanager get-secret-value --secret-id myapp/database
|
||||
|
||||
# Update secret
|
||||
aws secretsmanager update-secret \
|
||||
--secret-id myapp/database \
|
||||
--secret-string '{"username":"admin","password":"newsecret"}'
|
||||
|
||||
# Delete secret
|
||||
aws secretsmanager delete-secret --secret-id myapp/database --force-delete-without-recovery
|
||||
```
|
||||
|
||||
## Automatic Rotation
|
||||
|
||||
```python
|
||||
# Lambda rotation function
|
||||
def lambda_handler(event, context):
|
||||
secret_id = event['SecretId']
|
||||
token = event['ClientRequestToken']
|
||||
step = event['Step']
|
||||
|
||||
if step == "createSecret":
|
||||
create_secret(secret_id, token)
|
||||
elif step == "setSecret":
|
||||
set_secret(secret_id, token)
|
||||
elif step == "testSecret":
|
||||
test_secret(secret_id, token)
|
||||
elif step == "finishSecret":
|
||||
finish_secret(secret_id, token)
|
||||
```
|
||||
|
||||
## Terraform
|
||||
|
||||
```hcl
|
||||
resource "aws_secretsmanager_secret" "db" {
|
||||
name = "myapp/database"
|
||||
|
||||
tags = {
|
||||
Environment = "production"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_secretsmanager_secret_version" "db" {
|
||||
secret_id = aws_secretsmanager_secret.db.id
|
||||
secret_string = jsonencode({
|
||||
username = "admin"
|
||||
password = random_password.db.result
|
||||
})
|
||||
}
|
||||
|
||||
# Rotation
|
||||
resource "aws_secretsmanager_secret_rotation" "db" {
|
||||
secret_id = aws_secretsmanager_secret.db.id
|
||||
rotation_lambda_arn = aws_lambda_function.rotation.arn
|
||||
|
||||
rotation_rules {
|
||||
automatically_after_days = 30
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Application Integration
|
||||
|
||||
### Python (boto3)
|
||||
```python
|
||||
import boto3
|
||||
import json
|
||||
|
||||
def get_secret(secret_name):
|
||||
client = boto3.client('secretsmanager')
|
||||
response = client.get_secret_value(SecretId=secret_name)
|
||||
return json.loads(response['SecretString'])
|
||||
|
||||
# Usage
|
||||
creds = get_secret('myapp/database')
|
||||
connection = connect(
|
||||
host=creds['host'],
|
||||
user=creds['username'],
|
||||
password=creds['password']
|
||||
)
|
||||
```
|
||||
|
||||
### ECS Task Definition
|
||||
```json
|
||||
{
|
||||
"containerDefinitions": [{
|
||||
"secrets": [{
|
||||
"name": "DATABASE_PASSWORD",
|
||||
"valueFrom": "arn:aws:secretsmanager:us-east-1:123456789:secret:myapp/database:password::"
|
||||
}]
|
||||
}]
|
||||
}
|
||||
```
|
||||
|
||||
### Lambda
|
||||
```yaml
|
||||
# SAM template
|
||||
Environment:
|
||||
Variables:
|
||||
SECRET_ARN: !Ref DatabaseSecret
|
||||
|
||||
Policies:
|
||||
- AWSSecretsManagerGetSecretValuePolicy:
|
||||
SecretArn: !Ref DatabaseSecret
|
||||
```
|
||||
@@ -0,0 +1,88 @@
|
||||
---
|
||||
name: azure-keyvault
|
||||
description: Manage secrets and certificates in Azure Key Vault. Configure access policies, integrate with Azure services, and implement secure secret management. Use when managing secrets in Azure environments.
|
||||
license: MIT
|
||||
metadata:
|
||||
author: devops-skills
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# Azure Key Vault
|
||||
|
||||
Securely store and manage secrets, keys, and certificates in Azure.
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
Use this skill when:
|
||||
- Managing secrets in Azure
|
||||
- Storing encryption keys
|
||||
- Managing SSL certificates
|
||||
- Integrating with Azure services
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Azure subscription
|
||||
- Azure CLI installed
|
||||
- Appropriate RBAC permissions
|
||||
|
||||
## Basic Operations
|
||||
|
||||
```bash
|
||||
# Create Key Vault
|
||||
az keyvault create --name mykeyvault --resource-group mygroup --location eastus
|
||||
|
||||
# Set secret
|
||||
az keyvault secret set --vault-name mykeyvault --name db-password --value "secret123"
|
||||
|
||||
# Get secret
|
||||
az keyvault secret show --vault-name mykeyvault --name db-password
|
||||
|
||||
# List secrets
|
||||
az keyvault secret list --vault-name mykeyvault
|
||||
```
|
||||
|
||||
## Application Integration
|
||||
|
||||
```python
|
||||
from azure.identity import DefaultAzureCredential
|
||||
from azure.keyvault.secrets import SecretClient
|
||||
|
||||
credential = DefaultAzureCredential()
|
||||
client = SecretClient(vault_url="https://mykeyvault.vault.azure.net/", credential=credential)
|
||||
|
||||
# Get secret
|
||||
secret = client.get_secret("db-password")
|
||||
print(secret.value)
|
||||
```
|
||||
|
||||
## Kubernetes Integration
|
||||
|
||||
```yaml
|
||||
apiVersion: secrets-store.csi.x-k8s.io/v1
|
||||
kind: SecretProviderClass
|
||||
metadata:
|
||||
name: azure-keyvault
|
||||
spec:
|
||||
provider: azure
|
||||
parameters:
|
||||
keyvaultName: "mykeyvault"
|
||||
objects: |
|
||||
array:
|
||||
- |
|
||||
objectName: db-password
|
||||
objectType: secret
|
||||
tenantId: "tenant-id"
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Use managed identities
|
||||
- Enable soft-delete and purge protection
|
||||
- Implement access policies carefully
|
||||
- Use private endpoints
|
||||
- Monitor with Azure Monitor
|
||||
|
||||
## Related Skills
|
||||
|
||||
- [hashicorp-vault](../hashicorp-vault/) - Multi-cloud secrets
|
||||
- [azure-networking](../../../infrastructure/cloud-azure/azure-networking/) - Network security
|
||||
@@ -0,0 +1,81 @@
|
||||
---
|
||||
name: gcp-secret-manager
|
||||
description: Secure secrets in Google Cloud Secret Manager. Configure IAM policies, integrate with GKE, and manage secret versions. Use when managing secrets in GCP environments.
|
||||
license: MIT
|
||||
metadata:
|
||||
author: devops-skills
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# GCP Secret Manager
|
||||
|
||||
Store and manage secrets securely in Google Cloud Platform.
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
Use this skill when:
|
||||
- Managing secrets in GCP
|
||||
- Integrating with GKE workloads
|
||||
- Storing API keys and credentials
|
||||
- Implementing secret rotation
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- GCP project
|
||||
- gcloud CLI configured
|
||||
- Secret Manager API enabled
|
||||
|
||||
## Basic Operations
|
||||
|
||||
```bash
|
||||
# Create secret
|
||||
echo -n "secret123" | gcloud secrets create db-password --data-file=-
|
||||
|
||||
# Access secret
|
||||
gcloud secrets versions access latest --secret=db-password
|
||||
|
||||
# Add new version
|
||||
echo -n "newsecret" | gcloud secrets versions add db-password --data-file=-
|
||||
|
||||
# List secrets
|
||||
gcloud secrets list
|
||||
```
|
||||
|
||||
## Application Integration
|
||||
|
||||
```python
|
||||
from google.cloud import secretmanager
|
||||
|
||||
client = secretmanager.SecretManagerServiceClient()
|
||||
name = f"projects/my-project/secrets/db-password/versions/latest"
|
||||
response = client.access_secret_version(request={"name": name})
|
||||
secret = response.payload.data.decode("UTF-8")
|
||||
```
|
||||
|
||||
## GKE Integration
|
||||
|
||||
```yaml
|
||||
apiVersion: secrets-store.csi.x-k8s.io/v1
|
||||
kind: SecretProviderClass
|
||||
metadata:
|
||||
name: gcp-secrets
|
||||
spec:
|
||||
provider: gcp
|
||||
parameters:
|
||||
secrets: |
|
||||
- resourceName: "projects/my-project/secrets/db-password/versions/latest"
|
||||
path: "db-password"
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Use Workload Identity for GKE
|
||||
- Implement IAM least-privilege
|
||||
- Enable audit logging
|
||||
- Use secret versions for rollback
|
||||
- Integrate with Cloud KMS for encryption
|
||||
|
||||
## Related Skills
|
||||
|
||||
- [hashicorp-vault](../hashicorp-vault/) - Multi-cloud secrets
|
||||
- [gcp-gke](../../../infrastructure/cloud-gcp/gcp-gke/) - GKE integration
|
||||
@@ -0,0 +1,384 @@
|
||||
---
|
||||
name: hashicorp-vault
|
||||
description: Manage secrets and PKI with HashiCorp Vault. Configure secret engines, authentication methods, and policies. Use when implementing centralized secrets management, dynamic credentials, or certificate management.
|
||||
license: MIT
|
||||
metadata:
|
||||
author: devops-skills
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# HashiCorp Vault
|
||||
|
||||
Centrally manage secrets, encryption, and access with HashiCorp Vault.
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
Use this skill when:
|
||||
- Centralizing secrets management
|
||||
- Implementing dynamic credentials
|
||||
- Managing PKI and certificates
|
||||
- Encrypting sensitive data
|
||||
- Meeting compliance requirements
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Vault server (dev or production)
|
||||
- Vault CLI installed
|
||||
- Network access to Vault
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Development Server
|
||||
|
||||
```bash
|
||||
# Start dev server
|
||||
vault server -dev
|
||||
|
||||
# Set environment
|
||||
export VAULT_ADDR='http://127.0.0.1:8200'
|
||||
export VAULT_TOKEN='root'
|
||||
|
||||
# Verify connection
|
||||
vault status
|
||||
```
|
||||
|
||||
### Production Deployment
|
||||
|
||||
```hcl
|
||||
# config.hcl
|
||||
storage "raft" {
|
||||
path = "/opt/vault/data"
|
||||
node_id = "vault-1"
|
||||
}
|
||||
|
||||
listener "tcp" {
|
||||
address = "0.0.0.0:8200"
|
||||
tls_cert_file = "/opt/vault/tls/vault.crt"
|
||||
tls_key_file = "/opt/vault/tls/vault.key"
|
||||
}
|
||||
|
||||
api_addr = "https://vault.example.com:8200"
|
||||
cluster_addr = "https://vault.example.com:8201"
|
||||
|
||||
ui = true
|
||||
```
|
||||
|
||||
```bash
|
||||
# Initialize Vault
|
||||
vault operator init -key-shares=5 -key-threshold=3
|
||||
|
||||
# Unseal (run 3 times with different keys)
|
||||
vault operator unseal <key-1>
|
||||
vault operator unseal <key-2>
|
||||
vault operator unseal <key-3>
|
||||
|
||||
# Login
|
||||
vault login <root-token>
|
||||
```
|
||||
|
||||
## Secret Engines
|
||||
|
||||
### KV Secrets
|
||||
|
||||
```bash
|
||||
# Enable KV v2
|
||||
vault secrets enable -path=secret kv-v2
|
||||
|
||||
# Write secret
|
||||
vault kv put secret/myapp/config \
|
||||
username="admin" \
|
||||
password="s3cr3t"
|
||||
|
||||
# Read secret
|
||||
vault kv get secret/myapp/config
|
||||
vault kv get -field=password secret/myapp/config
|
||||
|
||||
# Update secret
|
||||
vault kv put secret/myapp/config \
|
||||
username="admin" \
|
||||
password="new-password"
|
||||
|
||||
# List secrets
|
||||
vault kv list secret/
|
||||
|
||||
# Delete secret
|
||||
vault kv delete secret/myapp/config
|
||||
|
||||
# Version history
|
||||
vault kv metadata get secret/myapp/config
|
||||
```
|
||||
|
||||
### Database Secrets
|
||||
|
||||
```bash
|
||||
# Enable database engine
|
||||
vault secrets enable database
|
||||
|
||||
# Configure PostgreSQL connection
|
||||
vault write database/config/postgresql \
|
||||
plugin_name=postgresql-database-plugin \
|
||||
connection_url="postgresql://{{username}}:{{password}}@localhost:5432/mydb" \
|
||||
allowed_roles="readonly,readwrite" \
|
||||
username="vault" \
|
||||
password="vault-password"
|
||||
|
||||
# Create role
|
||||
vault write database/roles/readonly \
|
||||
db_name=postgresql \
|
||||
creation_statements="CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; \
|
||||
GRANT SELECT ON ALL TABLES IN SCHEMA public TO \"{{name}}\";" \
|
||||
default_ttl="1h" \
|
||||
max_ttl="24h"
|
||||
|
||||
# Get credentials
|
||||
vault read database/creds/readonly
|
||||
```
|
||||
|
||||
### AWS Secrets
|
||||
|
||||
```bash
|
||||
# Enable AWS engine
|
||||
vault secrets enable aws
|
||||
|
||||
# Configure root credentials
|
||||
vault write aws/config/root \
|
||||
access_key=AKIA... \
|
||||
secret_key=secret... \
|
||||
region=us-east-1
|
||||
|
||||
# Create role
|
||||
vault write aws/roles/deploy \
|
||||
credential_type=iam_user \
|
||||
policy_document=-<<EOF
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": ["s3:*"],
|
||||
"Resource": ["arn:aws:s3:::my-bucket/*"]
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
|
||||
# Get credentials
|
||||
vault read aws/creds/deploy
|
||||
```
|
||||
|
||||
### PKI Secrets
|
||||
|
||||
```bash
|
||||
# Enable PKI engine
|
||||
vault secrets enable pki
|
||||
vault secrets tune -max-lease-ttl=87600h pki
|
||||
|
||||
# Generate root CA
|
||||
vault write -field=certificate pki/root/generate/internal \
|
||||
common_name="example.com" \
|
||||
ttl=87600h > ca_cert.crt
|
||||
|
||||
# Configure URLs
|
||||
vault write pki/config/urls \
|
||||
issuing_certificates="https://vault.example.com:8200/v1/pki/ca" \
|
||||
crl_distribution_points="https://vault.example.com:8200/v1/pki/crl"
|
||||
|
||||
# Create role
|
||||
vault write pki/roles/web-server \
|
||||
allowed_domains="example.com" \
|
||||
allow_subdomains=true \
|
||||
max_ttl="720h"
|
||||
|
||||
# Issue certificate
|
||||
vault write pki/issue/web-server \
|
||||
common_name="web.example.com" \
|
||||
ttl="24h"
|
||||
```
|
||||
|
||||
## Authentication Methods
|
||||
|
||||
### AppRole
|
||||
|
||||
```bash
|
||||
# Enable AppRole
|
||||
vault auth enable approle
|
||||
|
||||
# Create role
|
||||
vault write auth/approle/role/myapp \
|
||||
token_policies="myapp-policy" \
|
||||
token_ttl=1h \
|
||||
token_max_ttl=4h \
|
||||
secret_id_ttl=10m
|
||||
|
||||
# Get role ID
|
||||
vault read auth/approle/role/myapp/role-id
|
||||
|
||||
# Generate secret ID
|
||||
vault write -f auth/approle/role/myapp/secret-id
|
||||
|
||||
# Login
|
||||
vault write auth/approle/login \
|
||||
role_id=<role-id> \
|
||||
secret_id=<secret-id>
|
||||
```
|
||||
|
||||
### Kubernetes
|
||||
|
||||
```bash
|
||||
# Enable Kubernetes auth
|
||||
vault auth enable kubernetes
|
||||
|
||||
# Configure
|
||||
vault write auth/kubernetes/config \
|
||||
kubernetes_host="https://kubernetes.default.svc" \
|
||||
kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
|
||||
|
||||
# Create role
|
||||
vault write auth/kubernetes/role/myapp \
|
||||
bound_service_account_names=myapp \
|
||||
bound_service_account_namespaces=default \
|
||||
policies=myapp-policy \
|
||||
ttl=1h
|
||||
```
|
||||
|
||||
### OIDC
|
||||
|
||||
```bash
|
||||
# Enable OIDC auth
|
||||
vault auth enable oidc
|
||||
|
||||
# Configure
|
||||
vault write auth/oidc/config \
|
||||
oidc_discovery_url="https://accounts.google.com" \
|
||||
oidc_client_id="your-client-id" \
|
||||
oidc_client_secret="your-client-secret" \
|
||||
default_role="default"
|
||||
|
||||
# Create role
|
||||
vault write auth/oidc/role/default \
|
||||
bound_audiences="your-client-id" \
|
||||
allowed_redirect_uris="http://localhost:8250/oidc/callback" \
|
||||
user_claim="sub" \
|
||||
policies="default"
|
||||
```
|
||||
|
||||
## Policies
|
||||
|
||||
### Policy Definition
|
||||
|
||||
```hcl
|
||||
# myapp-policy.hcl
|
||||
# Read secrets
|
||||
path "secret/data/myapp/*" {
|
||||
capabilities = ["read", "list"]
|
||||
}
|
||||
|
||||
# Database credentials
|
||||
path "database/creds/myapp-db" {
|
||||
capabilities = ["read"]
|
||||
}
|
||||
|
||||
# PKI certificates
|
||||
path "pki/issue/web-server" {
|
||||
capabilities = ["create", "update"]
|
||||
}
|
||||
|
||||
# Deny access to other secrets
|
||||
path "secret/data/other/*" {
|
||||
capabilities = ["deny"]
|
||||
}
|
||||
```
|
||||
|
||||
```bash
|
||||
# Create policy
|
||||
vault policy write myapp myapp-policy.hcl
|
||||
|
||||
# List policies
|
||||
vault policy list
|
||||
|
||||
# Read policy
|
||||
vault policy read myapp
|
||||
```
|
||||
|
||||
## Application Integration
|
||||
|
||||
### Python
|
||||
|
||||
```python
|
||||
import hvac
|
||||
|
||||
# Initialize client
|
||||
client = hvac.Client(url='http://localhost:8200')
|
||||
|
||||
# AppRole authentication
|
||||
client.auth.approle.login(
|
||||
role_id='role-id',
|
||||
secret_id='secret-id'
|
||||
)
|
||||
|
||||
# Read secret
|
||||
secret = client.secrets.kv.v2.read_secret_version(
|
||||
path='myapp/config',
|
||||
mount_point='secret'
|
||||
)
|
||||
password = secret['data']['data']['password']
|
||||
|
||||
# Get database credentials
|
||||
db_creds = client.secrets.database.generate_credentials(
|
||||
name='myapp-db'
|
||||
)
|
||||
```
|
||||
|
||||
### Kubernetes Sidecar
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: myapp
|
||||
annotations:
|
||||
vault.hashicorp.com/agent-inject: "true"
|
||||
vault.hashicorp.com/role: "myapp"
|
||||
vault.hashicorp.com/agent-inject-secret-config: "secret/data/myapp/config"
|
||||
vault.hashicorp.com/agent-inject-template-config: |
|
||||
{{- with secret "secret/data/myapp/config" -}}
|
||||
export DB_PASSWORD="{{ .Data.data.password }}"
|
||||
{{- end }}
|
||||
spec:
|
||||
serviceAccountName: myapp
|
||||
containers:
|
||||
- name: myapp
|
||||
image: myapp:latest
|
||||
command: ["/bin/sh", "-c", "source /vault/secrets/config && ./start.sh"]
|
||||
```
|
||||
|
||||
## Common Issues
|
||||
|
||||
### Issue: Sealed Vault
|
||||
**Problem**: Vault is sealed after restart
|
||||
**Solution**: Implement auto-unseal with cloud KMS or HSM
|
||||
|
||||
### Issue: Token Expired
|
||||
**Problem**: Application token has expired
|
||||
**Solution**: Implement token renewal, use shorter-lived tokens
|
||||
|
||||
### Issue: Permission Denied
|
||||
**Problem**: Cannot access secrets
|
||||
**Solution**: Review policies, check token capabilities
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Use short-lived tokens
|
||||
- Implement auto-unseal
|
||||
- Enable audit logging
|
||||
- Use namespaces for isolation
|
||||
- Rotate root tokens regularly
|
||||
- Implement least-privilege policies
|
||||
- Use dynamic secrets where possible
|
||||
- Regular backup and DR testing
|
||||
|
||||
## Related Skills
|
||||
|
||||
- [aws-secrets-manager](../aws-secrets-manager/) - AWS native secrets
|
||||
- [sops-encryption](../sops-encryption/) - File encryption
|
||||
- [kubernetes-hardening](../../hardening/kubernetes-hardening/) - K8s security
|
||||
@@ -0,0 +1,81 @@
|
||||
# Kubernetes Authentication for Vault
|
||||
# Enables pods to authenticate with Vault using service accounts
|
||||
|
||||
---
|
||||
# ServiceAccount for Vault auth
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: vault-auth
|
||||
namespace: vault
|
||||
|
||||
---
|
||||
# ClusterRoleBinding for token review
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: vault-tokenreview-binding
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: system:auth-delegator
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: vault-auth
|
||||
namespace: vault
|
||||
|
||||
---
|
||||
# Secret for SA token (K8s 1.24+)
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: vault-auth-token
|
||||
namespace: vault
|
||||
annotations:
|
||||
kubernetes.io/service-account.name: vault-auth
|
||||
type: kubernetes.io/service-account-token
|
||||
|
||||
---
|
||||
# Example: Application ServiceAccount
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: myapp
|
||||
namespace: myapp
|
||||
|
||||
---
|
||||
# Example: Pod using Vault Agent Injector
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: myapp
|
||||
namespace: myapp
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: myapp
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: myapp
|
||||
annotations:
|
||||
# Vault Agent Injector annotations
|
||||
vault.hashicorp.com/agent-inject: "true"
|
||||
vault.hashicorp.com/role: "myapp"
|
||||
vault.hashicorp.com/agent-inject-secret-config: "secret/data/myapp/config"
|
||||
vault.hashicorp.com/agent-inject-template-config: |
|
||||
{{- with secret "secret/data/myapp/config" -}}
|
||||
DATABASE_URL={{ .Data.data.database_url }}
|
||||
API_KEY={{ .Data.data.api_key }}
|
||||
{{- end }}
|
||||
spec:
|
||||
serviceAccountName: myapp
|
||||
containers:
|
||||
- name: myapp
|
||||
image: myapp:latest
|
||||
# Secrets available at /vault/secrets/config
|
||||
volumeMounts:
|
||||
- name: secrets
|
||||
mountPath: /vault/secrets
|
||||
readOnly: true
|
||||
@@ -0,0 +1,62 @@
|
||||
# Vault Server Configuration
|
||||
# /etc/vault.d/vault.hcl
|
||||
|
||||
# Cluster name
|
||||
cluster_name = "production"
|
||||
|
||||
# Storage backend (Raft for HA)
|
||||
storage "raft" {
|
||||
path = "/opt/vault/data"
|
||||
node_id = "vault-1"
|
||||
|
||||
retry_join {
|
||||
leader_api_addr = "https://vault-2.example.com:8200"
|
||||
}
|
||||
retry_join {
|
||||
leader_api_addr = "https://vault-3.example.com:8200"
|
||||
}
|
||||
}
|
||||
|
||||
# Listener configuration
|
||||
listener "tcp" {
|
||||
address = "0.0.0.0:8200"
|
||||
cluster_address = "0.0.0.0:8201"
|
||||
tls_cert_file = "/opt/vault/tls/vault.crt"
|
||||
tls_key_file = "/opt/vault/tls/vault.key"
|
||||
|
||||
# TLS settings
|
||||
tls_min_version = "tls12"
|
||||
tls_cipher_suites = "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"
|
||||
}
|
||||
|
||||
# API address
|
||||
api_addr = "https://vault.example.com:8200"
|
||||
cluster_addr = "https://vault-1.example.com:8201"
|
||||
|
||||
# UI
|
||||
ui = true
|
||||
|
||||
# Telemetry
|
||||
telemetry {
|
||||
prometheus_retention_time = "30s"
|
||||
disable_hostname = true
|
||||
}
|
||||
|
||||
# Audit logging
|
||||
# Enable via API after init:
|
||||
# vault audit enable file file_path=/var/log/vault/audit.log
|
||||
|
||||
# Seal configuration (Auto-unseal with AWS KMS)
|
||||
# seal "awskms" {
|
||||
# region = "us-east-1"
|
||||
# kms_key_id = "alias/vault-unseal-key"
|
||||
# }
|
||||
|
||||
# Performance settings
|
||||
max_lease_ttl = "768h"
|
||||
default_lease_ttl = "768h"
|
||||
disable_mlock = false
|
||||
disable_cache = false
|
||||
|
||||
# Plugin directory
|
||||
plugin_directory = "/opt/vault/plugins"
|
||||
@@ -0,0 +1,136 @@
|
||||
# Vault Secrets Engines Guide
|
||||
|
||||
## KV Secrets Engine (v2)
|
||||
|
||||
### Enable and Configure
|
||||
```bash
|
||||
# Enable KV v2
|
||||
vault secrets enable -path=secret kv-v2
|
||||
|
||||
# Write secret
|
||||
vault kv put secret/myapp/config \
|
||||
db_host="postgres.example.com" \
|
||||
db_user="myapp" \
|
||||
db_password="secret123"
|
||||
|
||||
# Read secret
|
||||
vault kv get secret/myapp/config
|
||||
vault kv get -field=db_password secret/myapp/config
|
||||
|
||||
# List secrets
|
||||
vault kv list secret/myapp/
|
||||
|
||||
# Delete secret
|
||||
vault kv delete secret/myapp/config
|
||||
|
||||
# Versioning
|
||||
vault kv get -version=1 secret/myapp/config
|
||||
vault kv rollback -version=1 secret/myapp/config
|
||||
```
|
||||
|
||||
## Database Secrets Engine
|
||||
|
||||
### Setup Dynamic Credentials
|
||||
```bash
|
||||
# Enable database engine
|
||||
vault secrets enable database
|
||||
|
||||
# Configure PostgreSQL
|
||||
vault write database/config/myapp-db \
|
||||
plugin_name=postgresql-database-plugin \
|
||||
allowed_roles="myapp-role" \
|
||||
connection_url="postgresql://{{username}}:{{password}}@postgres:5432/myapp?sslmode=disable" \
|
||||
username="vault_admin" \
|
||||
password="admin_password"
|
||||
|
||||
# Create role
|
||||
vault write database/roles/myapp-role \
|
||||
db_name=myapp-db \
|
||||
creation_statements="CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; \
|
||||
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO \"{{name}}\";" \
|
||||
default_ttl="1h" \
|
||||
max_ttl="24h"
|
||||
|
||||
# Generate credentials
|
||||
vault read database/creds/myapp-role
|
||||
```
|
||||
|
||||
## AWS Secrets Engine
|
||||
|
||||
### Setup Dynamic AWS Credentials
|
||||
```bash
|
||||
# Enable AWS engine
|
||||
vault secrets enable aws
|
||||
|
||||
# Configure root credentials
|
||||
vault write aws/config/root \
|
||||
access_key=AKIAXXXXXXXX \
|
||||
secret_key=xxxxxxxx \
|
||||
region=us-east-1
|
||||
|
||||
# Create role
|
||||
vault write aws/roles/deploy-role \
|
||||
credential_type=iam_user \
|
||||
policy_document=-<<EOF
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": ["s3:*"],
|
||||
"Resource": ["arn:aws:s3:::my-bucket/*"]
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
|
||||
# Generate credentials
|
||||
vault read aws/creds/deploy-role
|
||||
```
|
||||
|
||||
## PKI Secrets Engine
|
||||
|
||||
### Certificate Authority
|
||||
```bash
|
||||
# Enable PKI
|
||||
vault secrets enable pki
|
||||
vault secrets tune -max-lease-ttl=87600h pki
|
||||
|
||||
# Generate root CA
|
||||
vault write pki/root/generate/internal \
|
||||
common_name="Example Root CA" \
|
||||
ttl=87600h
|
||||
|
||||
# Create role
|
||||
vault write pki/roles/server-cert \
|
||||
allowed_domains="example.com" \
|
||||
allow_subdomains=true \
|
||||
max_ttl="720h"
|
||||
|
||||
# Issue certificate
|
||||
vault write pki/issue/server-cert \
|
||||
common_name="api.example.com" \
|
||||
ttl="24h"
|
||||
```
|
||||
|
||||
## Transit Secrets Engine
|
||||
|
||||
### Encryption as a Service
|
||||
```bash
|
||||
# Enable transit
|
||||
vault secrets enable transit
|
||||
|
||||
# Create encryption key
|
||||
vault write -f transit/keys/myapp-key
|
||||
|
||||
# Encrypt data
|
||||
vault write transit/encrypt/myapp-key \
|
||||
plaintext=$(echo "secret data" | base64)
|
||||
|
||||
# Decrypt data
|
||||
vault write transit/decrypt/myapp-key \
|
||||
ciphertext="vault:v1:xxxxx"
|
||||
|
||||
# Rotate key
|
||||
vault write -f transit/keys/myapp-key/rotate
|
||||
```
|
||||
@@ -0,0 +1,130 @@
|
||||
# Vault Policy Guide
|
||||
|
||||
## Policy Syntax
|
||||
|
||||
```hcl
|
||||
# Basic policy structure
|
||||
path "secret/data/myapp/*" {
|
||||
capabilities = ["create", "read", "update", "delete", "list"]
|
||||
}
|
||||
```
|
||||
|
||||
## Capabilities
|
||||
|
||||
| Capability | HTTP Verb | Description |
|
||||
|------------|-----------|-------------|
|
||||
| `create` | POST/PUT | Create new data |
|
||||
| `read` | GET | Read data |
|
||||
| `update` | POST/PUT | Update existing data |
|
||||
| `delete` | DELETE | Delete data |
|
||||
| `list` | LIST | List keys |
|
||||
| `sudo` | - | Root-protected paths |
|
||||
| `deny` | - | Explicitly deny access |
|
||||
|
||||
## Common Policies
|
||||
|
||||
### Application Read-Only
|
||||
```hcl
|
||||
# app-readonly.hcl
|
||||
path "secret/data/myapp/*" {
|
||||
capabilities = ["read", "list"]
|
||||
}
|
||||
|
||||
path "secret/metadata/myapp/*" {
|
||||
capabilities = ["read", "list"]
|
||||
}
|
||||
```
|
||||
|
||||
### Developer Policy
|
||||
```hcl
|
||||
# developer.hcl
|
||||
path "secret/data/dev/*" {
|
||||
capabilities = ["create", "read", "update", "delete", "list"]
|
||||
}
|
||||
|
||||
path "secret/data/staging/*" {
|
||||
capabilities = ["read", "list"]
|
||||
}
|
||||
|
||||
# Deny production access
|
||||
path "secret/data/prod/*" {
|
||||
capabilities = ["deny"]
|
||||
}
|
||||
```
|
||||
|
||||
### CI/CD Pipeline
|
||||
```hcl
|
||||
# cicd.hcl
|
||||
# Read deployment secrets
|
||||
path "secret/data/deploy/*" {
|
||||
capabilities = ["read"]
|
||||
}
|
||||
|
||||
# Generate dynamic database credentials
|
||||
path "database/creds/myapp-role" {
|
||||
capabilities = ["read"]
|
||||
}
|
||||
|
||||
# Sign SSH keys
|
||||
path "ssh-client-signer/sign/deploy-role" {
|
||||
capabilities = ["create", "update"]
|
||||
}
|
||||
```
|
||||
|
||||
### Admin Policy
|
||||
```hcl
|
||||
# admin.hcl
|
||||
# Manage secrets engines
|
||||
path "sys/mounts/*" {
|
||||
capabilities = ["create", "read", "update", "delete", "list"]
|
||||
}
|
||||
|
||||
# Manage policies
|
||||
path "sys/policies/acl/*" {
|
||||
capabilities = ["create", "read", "update", "delete", "list"]
|
||||
}
|
||||
|
||||
# Manage auth methods
|
||||
path "sys/auth/*" {
|
||||
capabilities = ["create", "read", "update", "delete", "list", "sudo"]
|
||||
}
|
||||
|
||||
# View audit logs
|
||||
path "sys/audit" {
|
||||
capabilities = ["read", "list"]
|
||||
}
|
||||
```
|
||||
|
||||
## Policy Templates
|
||||
|
||||
### Using Templating
|
||||
```hcl
|
||||
# Per-user secrets path
|
||||
path "secret/data/users/{{identity.entity.name}}/*" {
|
||||
capabilities = ["create", "read", "update", "delete", "list"]
|
||||
}
|
||||
|
||||
# Team-based access
|
||||
path "secret/data/teams/{{identity.groups.names}}/*" {
|
||||
capabilities = ["read", "list"]
|
||||
}
|
||||
```
|
||||
|
||||
## Policy Management
|
||||
|
||||
```bash
|
||||
# Write policy
|
||||
vault policy write myapp-policy myapp-policy.hcl
|
||||
|
||||
# List policies
|
||||
vault policy list
|
||||
|
||||
# Read policy
|
||||
vault policy read myapp-policy
|
||||
|
||||
# Delete policy
|
||||
vault policy delete myapp-policy
|
||||
|
||||
# Test policy (requires root)
|
||||
vault token create -policy=myapp-policy
|
||||
```
|
||||
@@ -0,0 +1,55 @@
|
||||
#!/bin/bash
|
||||
# Vault Backup Script (Raft Storage)
|
||||
# Usage: ./vault-backup.sh [output-dir]
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
OUTPUT_DIR="${1:-./vault-backups}"
|
||||
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
|
||||
BACKUP_FILE="$OUTPUT_DIR/vault-snapshot-$TIMESTAMP.snap"
|
||||
|
||||
mkdir -p "$OUTPUT_DIR"
|
||||
|
||||
echo "========================================="
|
||||
echo "Vault Raft Snapshot Backup"
|
||||
echo "Output: $BACKUP_FILE"
|
||||
echo "========================================="
|
||||
echo ""
|
||||
|
||||
# Check Vault status
|
||||
if ! vault status &>/dev/null; then
|
||||
echo "Error: Cannot connect to Vault or Vault is sealed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Take snapshot
|
||||
echo "Creating snapshot..."
|
||||
vault operator raft snapshot save "$BACKUP_FILE"
|
||||
|
||||
if [ -f "$BACKUP_FILE" ]; then
|
||||
SIZE=$(du -h "$BACKUP_FILE" | cut -f1)
|
||||
echo "Snapshot created successfully!"
|
||||
echo "File: $BACKUP_FILE"
|
||||
echo "Size: $SIZE"
|
||||
else
|
||||
echo "Error: Snapshot creation failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Verify snapshot
|
||||
echo ""
|
||||
echo "Verifying snapshot..."
|
||||
vault operator raft snapshot inspect "$BACKUP_FILE" | head -20
|
||||
|
||||
# Cleanup old backups (keep last 7)
|
||||
echo ""
|
||||
echo "Cleaning up old backups (keeping last 7)..."
|
||||
ls -t "$OUTPUT_DIR"/vault-snapshot-*.snap 2>/dev/null | tail -n +8 | xargs -r rm -v
|
||||
|
||||
echo ""
|
||||
echo "========================================="
|
||||
echo "Backup complete"
|
||||
echo ""
|
||||
echo "To restore:"
|
||||
echo " vault operator raft snapshot restore $BACKUP_FILE"
|
||||
echo "========================================="
|
||||
@@ -0,0 +1,78 @@
|
||||
#!/bin/bash
|
||||
# Vault Initialization and Unseal Script
|
||||
# Usage: ./vault-init.sh [vault-addr]
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
export VAULT_ADDR="${1:-http://127.0.0.1:8200}"
|
||||
|
||||
echo "========================================="
|
||||
echo "Vault Initialization"
|
||||
echo "Address: $VAULT_ADDR"
|
||||
echo "========================================="
|
||||
echo ""
|
||||
|
||||
# Check if Vault is already initialized
|
||||
INIT_STATUS=$(vault status -format=json 2>/dev/null | jq -r '.initialized' || echo "error")
|
||||
|
||||
if [ "$INIT_STATUS" == "true" ]; then
|
||||
echo "Vault is already initialized"
|
||||
SEALED=$(vault status -format=json | jq -r '.sealed')
|
||||
if [ "$SEALED" == "true" ]; then
|
||||
echo "Vault is sealed. Use unseal keys to unseal."
|
||||
else
|
||||
echo "Vault is unsealed and ready."
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ "$INIT_STATUS" == "error" ]; then
|
||||
echo "Error: Cannot connect to Vault at $VAULT_ADDR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Initialize Vault
|
||||
echo "Initializing Vault..."
|
||||
echo ""
|
||||
|
||||
# Initialize with 5 key shares, 3 required to unseal
|
||||
INIT_OUTPUT=$(vault operator init \
|
||||
-key-shares=5 \
|
||||
-key-threshold=3 \
|
||||
-format=json)
|
||||
|
||||
# Save keys securely
|
||||
echo "$INIT_OUTPUT" > vault-init-keys.json
|
||||
chmod 600 vault-init-keys.json
|
||||
|
||||
echo "Vault initialized successfully!"
|
||||
echo ""
|
||||
echo "IMPORTANT: vault-init-keys.json contains your unseal keys and root token"
|
||||
echo "Store these securely and distribute unseal keys to different people"
|
||||
echo ""
|
||||
|
||||
# Extract keys
|
||||
UNSEAL_KEY_1=$(echo "$INIT_OUTPUT" | jq -r '.unseal_keys_b64[0]')
|
||||
UNSEAL_KEY_2=$(echo "$INIT_OUTPUT" | jq -r '.unseal_keys_b64[1]')
|
||||
UNSEAL_KEY_3=$(echo "$INIT_OUTPUT" | jq -r '.unseal_keys_b64[2]')
|
||||
ROOT_TOKEN=$(echo "$INIT_OUTPUT" | jq -r '.root_token')
|
||||
|
||||
# Unseal Vault
|
||||
echo "Unsealing Vault..."
|
||||
vault operator unseal "$UNSEAL_KEY_1" >/dev/null
|
||||
vault operator unseal "$UNSEAL_KEY_2" >/dev/null
|
||||
vault operator unseal "$UNSEAL_KEY_3" >/dev/null
|
||||
|
||||
echo "Vault unsealed successfully!"
|
||||
echo ""
|
||||
echo "Root Token: $ROOT_TOKEN"
|
||||
echo ""
|
||||
echo "Login with: vault login $ROOT_TOKEN"
|
||||
echo ""
|
||||
echo "========================================="
|
||||
echo "Next steps:"
|
||||
echo "1. Store unseal keys securely (different locations)"
|
||||
echo "2. Create AppRole or other auth methods"
|
||||
echo "3. Enable audit logging"
|
||||
echo "4. Configure secrets engines"
|
||||
echo "========================================="
|
||||
@@ -0,0 +1,100 @@
|
||||
---
|
||||
name: sops-encryption
|
||||
description: Encrypt files and configs with Mozilla SOPS. Integrate with AWS KMS, GCP KMS, or PGP for key management. Use when encrypting configuration files, Kubernetes secrets, or implementing GitOps with encrypted secrets.
|
||||
license: MIT
|
||||
metadata:
|
||||
author: devops-skills
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# SOPS Encryption
|
||||
|
||||
Encrypt secrets in configuration files while keeping structure visible.
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
Use this skill when:
|
||||
- Encrypting secrets in Git
|
||||
- Implementing GitOps with secrets
|
||||
- Managing Kubernetes secrets as code
|
||||
- Encrypting configuration files
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- SOPS installed
|
||||
- KMS access (AWS, GCP, Azure) or PGP key
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
# macOS
|
||||
brew install sops
|
||||
|
||||
# Linux
|
||||
wget https://github.com/getsops/sops/releases/download/v3.8.0/sops-v3.8.0.linux.amd64
|
||||
chmod +x sops-v3.8.0.linux.amd64
|
||||
mv sops-v3.8.0.linux.amd64 /usr/local/bin/sops
|
||||
```
|
||||
|
||||
## Basic Usage
|
||||
|
||||
```bash
|
||||
# Encrypt with AWS KMS
|
||||
sops --encrypt --kms arn:aws:kms:region:account:key/key-id secrets.yaml > secrets.enc.yaml
|
||||
|
||||
# Decrypt
|
||||
sops --decrypt secrets.enc.yaml
|
||||
|
||||
# Edit encrypted file
|
||||
sops secrets.enc.yaml
|
||||
|
||||
# Encrypt in place
|
||||
sops --encrypt --in-place secrets.yaml
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
```yaml
|
||||
# .sops.yaml
|
||||
creation_rules:
|
||||
- path_regex: .*\.prod\.yaml$
|
||||
kms: arn:aws:kms:us-east-1:account:key/prod-key
|
||||
- path_regex: .*\.dev\.yaml$
|
||||
kms: arn:aws:kms:us-east-1:account:key/dev-key
|
||||
- path_regex: .*
|
||||
pgp: fingerprint
|
||||
```
|
||||
|
||||
## Kubernetes Integration
|
||||
|
||||
```yaml
|
||||
# encrypted secret
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: myapp-secrets
|
||||
type: Opaque
|
||||
stringData:
|
||||
password: ENC[AES256_GCM,data:encrypted...]
|
||||
sops:
|
||||
kms:
|
||||
- arn: arn:aws:kms:region:account:key/key-id
|
||||
```
|
||||
|
||||
```bash
|
||||
# With ArgoCD
|
||||
# Install ksops plugin for ArgoCD to decrypt secrets
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Store .sops.yaml in repository
|
||||
- Use different keys per environment
|
||||
- Rotate encryption keys regularly
|
||||
- Never commit unencrypted secrets
|
||||
- Use key aliases for readability
|
||||
|
||||
## Related Skills
|
||||
|
||||
- [hashicorp-vault](../hashicorp-vault/) - Centralized secrets
|
||||
- [argocd-gitops](../../../devops/orchestration/argocd-gitops/) - GitOps integration
|
||||
Reference in New Issue
Block a user