chore: complete update
This commit is contained in:
31
ansible/nginx-cdn-germany/.gitignore
vendored
Normal file
31
ansible/nginx-cdn-germany/.gitignore
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
# Cache
|
||||
*.cache
|
||||
.cache/
|
||||
|
||||
# Ansible
|
||||
*.retry
|
||||
.ansible/
|
||||
|
||||
# System
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Logs
|
||||
*.log
|
||||
|
||||
# Backups
|
||||
*.backup
|
||||
*.bak
|
||||
|
||||
# SSL Keys (niemals committen!)
|
||||
*.key
|
||||
*.pem
|
||||
*.crt
|
||||
|
||||
# Secrets
|
||||
vault.yml
|
||||
secrets.yml
|
||||
|
||||
# Temporäre Dateien
|
||||
*.tmp
|
||||
*.temp
|
||||
64
ansible/nginx-cdn-germany/Makefile
Normal file
64
ansible/nginx-cdn-germany/Makefile
Normal file
@@ -0,0 +1,64 @@
|
||||
# Einfache CDN-Verwaltung mit Make
|
||||
|
||||
.PHONY: deploy check health purge-cache warm-cache status reload
|
||||
|
||||
# Standard deployment
|
||||
deploy:
|
||||
@echo "🚀 Deploying Simple CDN..."
|
||||
chmod +x scripts/deploy.sh
|
||||
./scripts/deploy.sh
|
||||
|
||||
# Deployment mit Check-Modus (Dry-Run)
|
||||
check:
|
||||
@echo "🔍 Checking deployment (dry-run)..."
|
||||
ansible-playbook -i inventories/production/hosts.yml playbooks/deploy-simple-cdn.yml --check --diff
|
||||
|
||||
# Health check aller Nodes
|
||||
health:
|
||||
@echo "🏥 Checking CDN health..."
|
||||
ansible cdn_nodes -i inventories/production/hosts.yml -m uri -a "url=https://{{ inventory_hostname }}/health method=GET"
|
||||
|
||||
# Cache leeren
|
||||
purge-cache:
|
||||
@echo "🧹 Purging cache on all nodes..."
|
||||
ansible cdn_nodes -i inventories/production/hosts.yml -m shell -a "find /var/cache/nginx/ -type f -delete"
|
||||
@echo "✅ Cache purged on all nodes"
|
||||
|
||||
# Cache warming
|
||||
warm-cache:
|
||||
@echo "🔥 Warming cache..."
|
||||
chmod +x scripts/warm-cache.sh
|
||||
./scripts/warm-cache.sh
|
||||
|
||||
# Status-Report
|
||||
status:
|
||||
@echo "📊 CDN Status Report..."
|
||||
ansible cdn_nodes -i inventories/production/hosts.yml -m shell -a "echo '=== {{ inventory_hostname }} ===' && /usr/local/bin/cdn-monitor && echo ''"
|
||||
|
||||
# Nginx neuladen
|
||||
reload:
|
||||
@echo "⚙️ Reloading nginx configuration..."
|
||||
ansible cdn_nodes -i inventories/production/hosts.yml -m systemd -a "name=nginx state=reloaded"
|
||||
|
||||
# SSL-Zertifikate erneuern
|
||||
renew-ssl:
|
||||
@echo "🔐 Renewing SSL certificates..."
|
||||
ansible cdn_nodes -i inventories/production/hosts.yml -m shell -a "certbot renew --quiet"
|
||||
|
||||
# Interaktive Verwaltung
|
||||
manage:
|
||||
@echo "🔧 Starting interactive management..."
|
||||
ansible-playbook -i inventories/production/hosts.yml playbooks/manage-cdn.yml
|
||||
|
||||
# Hilfe
|
||||
help:
|
||||
@echo "📖 Available commands:"
|
||||
@echo " make deploy - Deploy CDN"
|
||||
@echo " make check - Test deployment (dry-run)"
|
||||
@echo " make health - Check all nodes health"
|
||||
@echo " make purge-cache - Clear all cache"
|
||||
@echo " make warm-cache - Warm cache with popular URLs"
|
||||
@echo " make status - Show detailed status"
|
||||
@echo " make reload - Reload nginx config"
|
||||
@echo " make renew-ssl - Renew SSL certificates"
|
||||
@echo " make manage - Interactive management"
|
||||
48
ansible/nginx-cdn-germany/README.md
Normal file
48
ansible/nginx-cdn-germany/README.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# Simple Nginx CDN für Deutschland
|
||||
|
||||
Dieses Ansible-Projekt erstellt ein einfaches, aber effektives CDN nur mit Nginx für deutsche Server.
|
||||
|
||||
## Schnellstart
|
||||
|
||||
1. **Konfiguration anpassen:**
|
||||
```bash
|
||||
# Server-IPs eintragen
|
||||
vim inventories/production/hosts.yml
|
||||
|
||||
# Domains anpassen
|
||||
vim inventories/production/group_vars/all/main.yml
|
||||
```
|
||||
|
||||
2. **Deployment:**
|
||||
```bash
|
||||
# Testen
|
||||
ansible-playbook -i inventories/production/hosts.yml playbooks/deploy-simple-cdn.yml --check
|
||||
|
||||
# Deployen
|
||||
ansible-playbook -i inventories/production/hosts.yml playbooks/deploy-simple-cdn.yml
|
||||
```
|
||||
|
||||
3. **Verwalten:**
|
||||
```bash
|
||||
# Cache leeren
|
||||
make purge-cache
|
||||
|
||||
# Status prüfen
|
||||
make health
|
||||
```
|
||||
|
||||
## Struktur
|
||||
|
||||
- `inventories/` - Server-Konfiguration
|
||||
- `roles/` - Ansible-Rollen
|
||||
- `playbooks/` - Deployment-Skripte
|
||||
- `scripts/` - Hilfsskripte
|
||||
|
||||
## Features
|
||||
|
||||
✅ Nginx-basiertes CDN
|
||||
✅ SSL mit Let's Encrypt
|
||||
✅ DSGVO-konforme Logs
|
||||
✅ Einfaches Monitoring
|
||||
✅ Cache-Management
|
||||
✅ Rate Limiting
|
||||
115
ansible/nginx-cdn-germany/SETUP.md
Normal file
115
ansible/nginx-cdn-germany/SETUP.md
Normal file
@@ -0,0 +1,115 @@
|
||||
# SETUP.md - Einrichtungsanleitung
|
||||
|
||||
## 1. Vorbereitung
|
||||
|
||||
### Server vorbereiten
|
||||
```bash
|
||||
# Für jeden CDN-Server (als root):
|
||||
apt update && apt upgrade -y
|
||||
apt install -y python3 python3-pip
|
||||
```
|
||||
|
||||
### SSH-Keys einrichten
|
||||
```bash
|
||||
# Auf deinem lokalen Rechner:
|
||||
ssh-keygen -t rsa -b 4096 -C "cdn-deployment"
|
||||
ssh-copy-id root@cdn-fra1.example.de
|
||||
ssh-copy-id root@cdn-ham1.example.de
|
||||
ssh-copy-id root@cdn-muc1.example.de
|
||||
```
|
||||
|
||||
## 2. Konfiguration anpassen
|
||||
|
||||
### Domains und IPs ändern
|
||||
```bash
|
||||
# 1. Server-IPs eintragen
|
||||
vim inventories/production/hosts.yml
|
||||
|
||||
# 2. Domain-Namen anpassen
|
||||
vim inventories/production/group_vars/all/main.yml
|
||||
```
|
||||
|
||||
**Wichtig:** Ändere diese Werte:
|
||||
- `cdn_domain: "cdn.example.de"` → deine CDN-Domain
|
||||
- `ssl_email: "admin@example.de"` → deine E-Mail
|
||||
- `origin_domain: "www.example.de"` → deine Website
|
||||
- Alle IP-Adressen in `hosts.yml`
|
||||
|
||||
## 3. DNS konfigurieren
|
||||
|
||||
Bevor du deployest, stelle sicher dass deine CDN-Domain zu den Servern zeigt:
|
||||
|
||||
```bash
|
||||
# A-Records für deine CDN-Domain:
|
||||
cdn.example.de. IN A 10.0.1.10 # Frankfurt
|
||||
cdn.example.de. IN A 10.0.2.10 # Hamburg
|
||||
cdn.example.de. IN A 10.0.3.10 # München
|
||||
```
|
||||
|
||||
## 4. Deployment
|
||||
|
||||
```bash
|
||||
# Testen
|
||||
make check
|
||||
|
||||
# Deployen
|
||||
make deploy
|
||||
|
||||
# Health-Check
|
||||
make health
|
||||
```
|
||||
|
||||
## 5. Testen
|
||||
|
||||
```bash
|
||||
# CDN testen
|
||||
curl -I https://cdn.example.de/health
|
||||
|
||||
# Cache-Header prüfen
|
||||
curl -I https://cdn.example.de/some-static-file.css
|
||||
|
||||
# Performance testen
|
||||
time curl -o /dev/null -s https://cdn.example.de/
|
||||
```
|
||||
|
||||
## 6. Wartung
|
||||
|
||||
```bash
|
||||
# Cache leeren
|
||||
make purge-cache
|
||||
|
||||
# Status prüfen
|
||||
make status
|
||||
|
||||
# SSL erneuern
|
||||
make renew-ssl
|
||||
|
||||
# Interaktive Verwaltung
|
||||
make manage
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Ansible-Verbindung testen
|
||||
```bash
|
||||
ansible all -m ping
|
||||
```
|
||||
|
||||
### Nginx-Konfiguration prüfen
|
||||
```bash
|
||||
ansible cdn_nodes -m shell -a "nginx -t"
|
||||
```
|
||||
|
||||
### Logs anschauen
|
||||
```bash
|
||||
ansible cdn_nodes -m shell -a "tail -f /var/log/nginx/error.log"
|
||||
```
|
||||
|
||||
### SSL-Probleme
|
||||
```bash
|
||||
# SSL-Status prüfen
|
||||
ansible cdn_nodes -m shell -a "certbot certificates"
|
||||
|
||||
# Manuell erneuern
|
||||
ansible cdn_nodes -m shell -a "certbot renew --force-renewal"
|
||||
```
|
||||
15
ansible/nginx-cdn-germany/ansible.cfg
Normal file
15
ansible/nginx-cdn-germany/ansible.cfg
Normal file
@@ -0,0 +1,15 @@
|
||||
[defaults]
|
||||
inventory = inventories/production/hosts.yml
|
||||
host_key_checking = False
|
||||
timeout = 30
|
||||
forks = 5
|
||||
|
||||
[privilege_escalation]
|
||||
become = True
|
||||
become_method = sudo
|
||||
become_user = root
|
||||
become_ask_pass = False
|
||||
|
||||
[ssh_connection]
|
||||
ssh_args = -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no
|
||||
control_path = /tmp/ansible-ssh-%%h-%%p-%%r
|
||||
19
ansible/nginx-cdn-germany/init.sh
Normal file
19
ansible/nginx-cdn-germany/init.sh
Normal file
@@ -0,0 +1,19 @@
|
||||
#!/bin/bash
|
||||
# Scripts ausführbar machen
|
||||
chmod +x scripts/deploy.sh
|
||||
chmod +x scripts/warm-cache.sh
|
||||
|
||||
echo "✅ CDN-Projekt wurde erfolgreich erstellt!"
|
||||
echo ""
|
||||
echo "Nächste Schritte:"
|
||||
echo "1. Konfiguration anpassen:"
|
||||
echo " - vim inventories/production/hosts.yml"
|
||||
echo " - vim inventories/production/group_vars/all/main.yml"
|
||||
echo ""
|
||||
echo "2. SETUP.md lesen für detaillierte Anleitung"
|
||||
echo ""
|
||||
echo "3. Deployment testen:"
|
||||
echo " make check"
|
||||
echo ""
|
||||
echo "4. CDN deployen:"
|
||||
echo " make deploy"
|
||||
@@ -0,0 +1,26 @@
|
||||
---
|
||||
# Globale Variablen für das CDN
|
||||
|
||||
# Domain-Konfiguration (ÄNDERE DIESE!)
|
||||
cdn_domain: "cdn.example.de" # Deine CDN-Domain
|
||||
ssl_email: "admin@example.de" # E-Mail für SSL-Zertifikate
|
||||
origin_domain: "www.example.de" # Deine Haupt-Website
|
||||
|
||||
# Cache-Einstellungen
|
||||
cache_settings:
|
||||
static_files_ttl: "1y" # CSS, JS, Fonts
|
||||
images_ttl: "30d" # Bilder
|
||||
html_ttl: "5m" # HTML-Seiten
|
||||
api_ttl: "0" # APIs (kein Caching)
|
||||
|
||||
# DSGVO-Einstellungen
|
||||
gdpr_settings:
|
||||
log_retention_days: 30
|
||||
anonymize_ips: true
|
||||
cookie_consent_required: true
|
||||
|
||||
# Rate Limiting
|
||||
rate_limits:
|
||||
api: "10r/s"
|
||||
static: "100r/s"
|
||||
images: "50r/s"
|
||||
@@ -0,0 +1,22 @@
|
||||
---
|
||||
# CDN-Node spezifische Konfiguration
|
||||
|
||||
# Nginx Performance
|
||||
nginx_worker_processes: "auto"
|
||||
nginx_worker_connections: 2048
|
||||
nginx_keepalive_timeout: 65
|
||||
|
||||
# Performance-Tuning
|
||||
tcp_optimizations:
|
||||
tcp_nodelay: "on"
|
||||
tcp_nopush: "on"
|
||||
sendfile: "on"
|
||||
|
||||
# Proxy-Einstellungen
|
||||
proxy_settings:
|
||||
connect_timeout: "5s"
|
||||
send_timeout: "10s"
|
||||
read_timeout: "10s"
|
||||
buffering: "on"
|
||||
buffer_size: "64k"
|
||||
buffers: "8 64k"
|
||||
@@ -0,0 +1,47 @@
|
||||
---
|
||||
# Inventar mit gruppierten SSH-Schlüsseln
|
||||
|
||||
all:
|
||||
children:
|
||||
origin_servers:
|
||||
hosts:
|
||||
origin1.example.de:
|
||||
ansible_host: 192.168.1.10
|
||||
origin2.example.de:
|
||||
ansible_host: 192.168.1.11
|
||||
vars:
|
||||
ansible_ssh_private_key_file: ~/.ssh/origin_servers_key
|
||||
|
||||
cdn_nodes:
|
||||
children:
|
||||
primary_nodes:
|
||||
hosts:
|
||||
cdn-fra1.example.de:
|
||||
ansible_host: 10.0.1.10
|
||||
city: "Frankfurt"
|
||||
region: "Hessen"
|
||||
tier: "primary"
|
||||
cache_size: "50g"
|
||||
vars:
|
||||
ansible_ssh_private_key_file: ~/.ssh/cdn_primary_key
|
||||
|
||||
secondary_nodes:
|
||||
hosts:
|
||||
cdn-ham1.example.de:
|
||||
ansible_host: 10.0.2.10
|
||||
city: "Hamburg"
|
||||
region: "Hamburg"
|
||||
tier: "secondary"
|
||||
cache_size: "20g"
|
||||
cdn-muc1.example.de:
|
||||
ansible_host: 10.0.3.10
|
||||
city: "München"
|
||||
region: "Bayern"
|
||||
tier: "secondary"
|
||||
cache_size: "20g"
|
||||
vars:
|
||||
ansible_ssh_private_key_file: ~/.ssh/cdn_secondary_key
|
||||
|
||||
vars:
|
||||
ansible_user: root
|
||||
ansible_ssh_common_args: '-o StrictHostKeyChecking=no'
|
||||
@@ -0,0 +1,48 @@
|
||||
---
|
||||
# Inventar mit individuellen SSH-Schlüsseln
|
||||
|
||||
all:
|
||||
children:
|
||||
origin_servers:
|
||||
hosts:
|
||||
origin1.example.de:
|
||||
ansible_host: 192.168.1.10
|
||||
datacenter: "Frankfurt"
|
||||
ansible_ssh_private_key_file: ~/.ssh/origin1_key
|
||||
origin2.example.de:
|
||||
ansible_host: 192.168.1.11
|
||||
datacenter: "Frankfurt"
|
||||
ansible_ssh_private_key_file: ~/.ssh/origin2_key
|
||||
|
||||
cdn_nodes:
|
||||
hosts:
|
||||
# Frankfurt - Primary
|
||||
cdn-fra1.example.de:
|
||||
ansible_host: 10.0.1.10
|
||||
city: "Frankfurt"
|
||||
region: "Hessen"
|
||||
tier: "primary"
|
||||
cache_size: "50g"
|
||||
ansible_ssh_private_key_file: ~/.ssh/cdn_fra1_key
|
||||
|
||||
# Hamburg - Secondary
|
||||
cdn-ham1.example.de:
|
||||
ansible_host: 10.0.2.10
|
||||
city: "Hamburg"
|
||||
region: "Hamburg"
|
||||
tier: "secondary"
|
||||
cache_size: "20g"
|
||||
ansible_ssh_private_key_file: ~/.ssh/cdn_ham1_key
|
||||
|
||||
# München - Secondary
|
||||
cdn-muc1.example.de:
|
||||
ansible_host: 10.0.3.10
|
||||
city: "München"
|
||||
region: "Bayern"
|
||||
tier: "secondary"
|
||||
cache_size: "20g"
|
||||
ansible_ssh_private_key_file: ~/.ssh/cdn_muc1_key
|
||||
|
||||
vars:
|
||||
ansible_user: root
|
||||
ansible_ssh_common_args: '-o StrictHostKeyChecking=no'
|
||||
45
ansible/nginx-cdn-germany/inventories/production/hosts.yml
Normal file
45
ansible/nginx-cdn-germany/inventories/production/hosts.yml
Normal file
@@ -0,0 +1,45 @@
|
||||
---
|
||||
# Inventar für deutsches CDN
|
||||
|
||||
all:
|
||||
children:
|
||||
origin_servers:
|
||||
hosts:
|
||||
origin1.example.de:
|
||||
ansible_host: 192.168.1.10 # Ändere diese IP
|
||||
datacenter: "Frankfurt"
|
||||
origin2.example.de:
|
||||
ansible_host: 192.168.1.11 # Ändere diese IP
|
||||
datacenter: "Frankfurt"
|
||||
|
||||
cdn_nodes:
|
||||
hosts:
|
||||
# Frankfurt - Primary
|
||||
cdn-fra1.example.de:
|
||||
ansible_host: 10.0.1.10 # Ändere diese IP
|
||||
city: "Frankfurt"
|
||||
region: "Hessen"
|
||||
tier: "primary"
|
||||
cache_size: "50g"
|
||||
|
||||
# Hamburg - Secondary
|
||||
cdn-ham1.example.de:
|
||||
ansible_host: 10.0.2.10 # Ändere diese IP
|
||||
city: "Hamburg"
|
||||
region: "Hamburg"
|
||||
tier: "secondary"
|
||||
cache_size: "20g"
|
||||
|
||||
# München - Secondary
|
||||
cdn-muc1.example.de:
|
||||
ansible_host: 10.0.3.10 # Ändere diese IP
|
||||
city: "München"
|
||||
region: "Bayern"
|
||||
tier: "secondary"
|
||||
cache_size: "20g"
|
||||
|
||||
vars:
|
||||
# SSH-Konfiguration
|
||||
ansible_user: root
|
||||
ansible_ssh_private_key_file: ~/.ssh/id_rsa
|
||||
ansible_ssh_common_args: '-o StrictHostKeyChecking=no'
|
||||
43
ansible/nginx-cdn-germany/playbooks/deploy-simple-cdn.yml
Normal file
43
ansible/nginx-cdn-germany/playbooks/deploy-simple-cdn.yml
Normal file
@@ -0,0 +1,43 @@
|
||||
---
|
||||
# Simple CDN Deployment
|
||||
|
||||
- name: Deploy Simple CDN for Germany
|
||||
hosts: cdn_nodes
|
||||
become: yes
|
||||
serial: 1 # Ein Node nach dem anderen
|
||||
|
||||
pre_tasks:
|
||||
- name: Update system packages
|
||||
apt:
|
||||
update_cache: yes
|
||||
upgrade: dist
|
||||
|
||||
- name: Install required packages
|
||||
apt:
|
||||
name:
|
||||
- nginx
|
||||
- certbot
|
||||
- python3-certbot-nginx
|
||||
- curl
|
||||
- htop
|
||||
- bc
|
||||
state: present
|
||||
|
||||
roles:
|
||||
- nginx-cdn-config
|
||||
- ssl-certificates
|
||||
- simple-monitoring
|
||||
|
||||
post_tasks:
|
||||
- name: Verify CDN health
|
||||
uri:
|
||||
url: "https://{{ inventory_hostname }}/health"
|
||||
method: GET
|
||||
status_code: 200
|
||||
validate_certs: yes
|
||||
retries: 5
|
||||
delay: 10
|
||||
|
||||
- name: Display deployment success
|
||||
debug:
|
||||
msg: "✅ CDN Node {{ inventory_hostname }} ({{ city }}) successfully deployed!"
|
||||
68
ansible/nginx-cdn-germany/playbooks/manage-cdn.yml
Normal file
68
ansible/nginx-cdn-germany/playbooks/manage-cdn.yml
Normal file
@@ -0,0 +1,68 @@
|
||||
---
|
||||
# CDN Management Tasks
|
||||
- name: CDN Management and Maintenance
|
||||
hosts: cdn_nodes
|
||||
become: yes
|
||||
vars_prompt:
|
||||
- name: action
|
||||
prompt: "What action? (purge-cache/reload-config/check-health/view-stats/warm-cache)"
|
||||
private: no
|
||||
|
||||
tasks:
|
||||
- name: Purge all cache
|
||||
shell: find /var/cache/nginx/ -type f -delete
|
||||
when: action == "purge-cache"
|
||||
|
||||
- name: Display cache purge result
|
||||
debug:
|
||||
msg: "✅ Cache purged on {{ inventory_hostname }}"
|
||||
when: action == "purge-cache"
|
||||
|
||||
- name: Reload nginx configuration
|
||||
systemd:
|
||||
name: nginx
|
||||
state: reloaded
|
||||
when: action == "reload-config"
|
||||
|
||||
- name: Check CDN health
|
||||
uri:
|
||||
url: "https://{{ inventory_hostname }}/health"
|
||||
method: GET
|
||||
status_code: 200
|
||||
register: health_result
|
||||
when: action == "check-health"
|
||||
|
||||
- name: Display health result
|
||||
debug:
|
||||
msg: "{{ health_result.content }}"
|
||||
when: action == "check-health"
|
||||
|
||||
- name: Show cache and system statistics
|
||||
shell: |
|
||||
echo "=== Cache Size ==="
|
||||
du -sh /var/cache/nginx/
|
||||
echo "=== Cache Files ==="
|
||||
find /var/cache/nginx/ -type f | wc -l
|
||||
echo "=== System Load ==="
|
||||
uptime
|
||||
echo "=== Memory Usage ==="
|
||||
free -h
|
||||
echo "=== Disk Usage ==="
|
||||
df -h /
|
||||
register: stats_result
|
||||
when: action == "view-stats"
|
||||
|
||||
- name: Display statistics
|
||||
debug:
|
||||
msg: "{{ stats_result.stdout_lines }}"
|
||||
when: action == "view-stats"
|
||||
|
||||
- name: Warm cache with popular URLs
|
||||
uri:
|
||||
url: "https://{{ inventory_hostname }}{{ item }}"
|
||||
method: GET
|
||||
loop:
|
||||
- "/"
|
||||
- "/health"
|
||||
ignore_errors: yes
|
||||
when: action == "warm-cache"
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
- name: reload nginx
|
||||
systemd:
|
||||
name: nginx
|
||||
state: reloaded
|
||||
|
||||
- name: restart nginx
|
||||
systemd:
|
||||
name: nginx
|
||||
state: restarted
|
||||
@@ -0,0 +1,64 @@
|
||||
---
|
||||
# Nginx CDN Konfiguration
|
||||
|
||||
- name: Remove default nginx config
|
||||
file:
|
||||
path: /etc/nginx/sites-enabled/default
|
||||
state: absent
|
||||
notify: reload nginx
|
||||
|
||||
- name: Create nginx directories
|
||||
file:
|
||||
path: "{{ item }}"
|
||||
state: directory
|
||||
owner: www-data
|
||||
group: www-data
|
||||
mode: '0755'
|
||||
loop:
|
||||
- /var/cache/nginx/static
|
||||
- /var/cache/nginx/images
|
||||
- /var/cache/nginx/html
|
||||
- /var/log/nginx/cdn
|
||||
- /etc/nginx/includes
|
||||
|
||||
- name: Configure nginx main config
|
||||
template:
|
||||
src: nginx.conf.j2
|
||||
dest: /etc/nginx/nginx.conf
|
||||
backup: yes
|
||||
notify: reload nginx
|
||||
|
||||
- name: Create nginx includes
|
||||
template:
|
||||
src: "{{ item }}.j2"
|
||||
dest: "/etc/nginx/includes/{{ item }}"
|
||||
loop:
|
||||
- security-headers.conf
|
||||
- rate-limiting.conf
|
||||
- gzip-settings.conf
|
||||
notify: reload nginx
|
||||
|
||||
- name: Configure CDN site
|
||||
template:
|
||||
src: cdn-site.conf.j2
|
||||
dest: /etc/nginx/sites-available/cdn
|
||||
backup: yes
|
||||
notify: reload nginx
|
||||
|
||||
- name: Enable CDN site
|
||||
file:
|
||||
src: /etc/nginx/sites-available/cdn
|
||||
dest: /etc/nginx/sites-enabled/cdn
|
||||
state: link
|
||||
notify: reload nginx
|
||||
|
||||
- name: Test nginx configuration
|
||||
command: nginx -t
|
||||
register: nginx_test
|
||||
failed_when: nginx_test.rc != 0
|
||||
|
||||
- name: Start and enable nginx
|
||||
systemd:
|
||||
name: nginx
|
||||
state: started
|
||||
enabled: yes
|
||||
@@ -0,0 +1,195 @@
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name {{ cdn_domain }};
|
||||
|
||||
# Redirect HTTP to HTTPS
|
||||
return 301 https://$server_name$request_uri;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
listen [::]:443 ssl http2;
|
||||
server_name {{ cdn_domain }};
|
||||
|
||||
# SSL Configuration (wird von Certbot automatisch gefüllt)
|
||||
ssl_certificate /etc/letsencrypt/live/{{ cdn_domain }}/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/{{ cdn_domain }}/privkey.pem;
|
||||
include /etc/letsencrypt/options-ssl-nginx.conf;
|
||||
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
|
||||
|
||||
# CDN Headers
|
||||
add_header X-CDN-Node "{{ city }}, Deutschland";
|
||||
add_header X-Cache-Status $upstream_cache_status always;
|
||||
add_header X-Served-By "nginx-{{ inventory_hostname }}";
|
||||
|
||||
# Security Headers
|
||||
include /etc/nginx/includes/security-headers.conf;
|
||||
|
||||
# Logging
|
||||
access_log /var/log/nginx/cdn/{{ cdn_domain }}.access.log cdn_format;
|
||||
error_log /var/log/nginx/cdn/{{ cdn_domain }}.error.log warn;
|
||||
|
||||
# Rate Limiting
|
||||
include /etc/nginx/includes/rate-limiting.conf;
|
||||
|
||||
# Gzip Compression
|
||||
include /etc/nginx/includes/gzip-settings.conf;
|
||||
|
||||
# Nginx Status für Monitoring
|
||||
location /nginx_status {
|
||||
stub_status on;
|
||||
access_log off;
|
||||
allow 127.0.0.1;
|
||||
allow 10.0.0.0/8;
|
||||
deny all;
|
||||
}
|
||||
|
||||
##
|
||||
# Static Files (CSS, JS, Fonts) - Lange Cache-Zeit
|
||||
##
|
||||
location ~* \.(css|js|woff|woff2|ttf|eot|ico)$ {
|
||||
proxy_pass https://origin_servers;
|
||||
proxy_ssl_verify off;
|
||||
|
||||
# Cache Settings
|
||||
proxy_cache static_cache;
|
||||
proxy_cache_valid 200 302 {{ cache_settings.static_files_ttl }};
|
||||
proxy_cache_valid 404 1m;
|
||||
proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504;
|
||||
proxy_cache_lock on;
|
||||
proxy_cache_revalidate on;
|
||||
|
||||
# Headers
|
||||
expires {{ cache_settings.static_files_ttl }};
|
||||
add_header Cache-Control "public, immutable";
|
||||
add_header Vary "Accept-Encoding";
|
||||
|
||||
# Rate Limiting
|
||||
limit_req zone=static_files burst=50 nodelay;
|
||||
|
||||
# Proxy Headers
|
||||
proxy_set_header Host {{ origin_domain }};
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
##
|
||||
# Images - Mittlere Cache-Zeit
|
||||
##
|
||||
location ~* \.(jpg|jpeg|png|gif|webp|svg|avif|bmp|tiff)$ {
|
||||
proxy_pass https://origin_servers;
|
||||
proxy_ssl_verify off;
|
||||
|
||||
# Cache Settings
|
||||
proxy_cache images_cache;
|
||||
proxy_cache_valid 200 302 {{ cache_settings.images_ttl }};
|
||||
proxy_cache_valid 404 5m;
|
||||
proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504;
|
||||
|
||||
# Headers
|
||||
expires {{ cache_settings.images_ttl }};
|
||||
add_header Cache-Control "public";
|
||||
add_header Vary "Accept";
|
||||
|
||||
# Rate Limiting
|
||||
limit_req zone=images burst=30 nodelay;
|
||||
|
||||
# Proxy Headers
|
||||
proxy_set_header Host {{ origin_domain }};
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
##
|
||||
# API Endpoints - Kein Caching
|
||||
##
|
||||
location /api/ {
|
||||
proxy_pass https://origin_servers;
|
||||
proxy_ssl_verify off;
|
||||
|
||||
# Kein Caching
|
||||
proxy_no_cache 1;
|
||||
proxy_cache_bypass 1;
|
||||
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
||||
add_header Pragma "no-cache";
|
||||
add_header Expires "0";
|
||||
|
||||
# Rate Limiting
|
||||
limit_req zone=api burst=10 nodelay;
|
||||
|
||||
# CORS Headers
|
||||
add_header Access-Control-Allow-Origin "https://{{ origin_domain }}";
|
||||
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS";
|
||||
add_header Access-Control-Allow-Headers "Authorization, Content-Type, X-Requested-With";
|
||||
add_header Access-Control-Allow-Credentials true;
|
||||
|
||||
# Proxy Headers
|
||||
proxy_set_header Host {{ origin_domain }};
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
# Timeouts
|
||||
proxy_connect_timeout {{ proxy_settings.connect_timeout }};
|
||||
proxy_send_timeout {{ proxy_settings.send_timeout }};
|
||||
proxy_read_timeout {{ proxy_settings.read_timeout }};
|
||||
}
|
||||
|
||||
##
|
||||
# Cache Purge (nur interne IPs)
|
||||
##
|
||||
location ~ /purge(/.*) {
|
||||
allow 127.0.0.1;
|
||||
allow 10.0.0.0/8;
|
||||
allow 192.168.0.0/16;
|
||||
deny all;
|
||||
|
||||
proxy_cache_purge static_cache $scheme$proxy_host$1;
|
||||
}
|
||||
|
||||
##
|
||||
# Health Check
|
||||
##
|
||||
location /health {
|
||||
access_log off;
|
||||
return 200 "OK - CDN Node {{ city }}\nRegion: {{ region }}\nTier: {{ tier }}\nTimestamp: $time_iso8601\n";
|
||||
add_header Content-Type text/plain;
|
||||
}
|
||||
|
||||
##
|
||||
# Default Location - HTML Caching
|
||||
##
|
||||
location / {
|
||||
proxy_pass https://origin_servers;
|
||||
proxy_ssl_verify off;
|
||||
|
||||
# Cache Settings für HTML
|
||||
proxy_cache html_cache;
|
||||
proxy_cache_valid 200 {{ cache_settings.html_ttl }};
|
||||
proxy_cache_valid 404 1m;
|
||||
proxy_cache_bypass $arg_nocache $cookie_sessionid $http_authorization;
|
||||
|
||||
# Headers
|
||||
add_header Cache-Control "public, max-age=300";
|
||||
|
||||
# Proxy Headers
|
||||
proxy_set_header Host {{ origin_domain }};
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-CDN-Node "{{ city }}";
|
||||
|
||||
# Timeouts
|
||||
proxy_connect_timeout {{ proxy_settings.connect_timeout }};
|
||||
proxy_send_timeout {{ proxy_settings.send_timeout }};
|
||||
proxy_read_timeout {{ proxy_settings.read_timeout }};
|
||||
|
||||
# Buffering
|
||||
proxy_buffering {{ proxy_settings.buffering }};
|
||||
proxy_buffer_size {{ proxy_settings.buffer_size }};
|
||||
proxy_buffers {{ proxy_settings.buffers }};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
# Gzip Compression Settings
|
||||
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_min_length 1024;
|
||||
gzip_comp_level 6;
|
||||
gzip_proxied any;
|
||||
gzip_disable "msie6";
|
||||
|
||||
gzip_types
|
||||
text/plain
|
||||
text/css
|
||||
text/xml
|
||||
text/javascript
|
||||
application/javascript
|
||||
application/xml+rss
|
||||
application/atom+xml
|
||||
image/svg+xml
|
||||
application/json
|
||||
application/ld+json;
|
||||
@@ -0,0 +1,75 @@
|
||||
user www-data;
|
||||
worker_processes {{ nginx_worker_processes }};
|
||||
pid /run/nginx.pid;
|
||||
include /etc/nginx/modules-enabled/*.conf;
|
||||
|
||||
events {
|
||||
worker_connections {{ nginx_worker_connections }};
|
||||
use epoll;
|
||||
multi_accept on;
|
||||
}
|
||||
|
||||
http {
|
||||
##
|
||||
# Basic Settings
|
||||
##
|
||||
sendfile {{ tcp_optimizations.sendfile }};
|
||||
tcp_nopush {{ tcp_optimizations.tcp_nopush }};
|
||||
tcp_nodelay {{ tcp_optimizations.tcp_nodelay }};
|
||||
keepalive_timeout {{ nginx_keepalive_timeout }};
|
||||
types_hash_max_size 2048;
|
||||
server_tokens off;
|
||||
|
||||
server_names_hash_bucket_size 64;
|
||||
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
##
|
||||
# DSGVO-konforme Logging
|
||||
##
|
||||
map $remote_addr $anonymized_ip {
|
||||
~(?P<ip>\d+\.\d+\.\d+)\.\d+ $ip.0;
|
||||
~(?P<ipv6>[^:]+:[^:]+:[^:]+:[^:]+):.* $ipv6::;
|
||||
default 0.0.0.0;
|
||||
}
|
||||
|
||||
log_format cdn_format '$anonymized_ip - $remote_user [$time_local] '
|
||||
'"$request" $status $body_bytes_sent '
|
||||
'"$http_referer" "$http_user_agent" '
|
||||
'rt=$request_time '
|
||||
'cache="$upstream_cache_status" '
|
||||
'cdn_node="{{ inventory_hostname }}"';
|
||||
|
||||
access_log /var/log/nginx/access.log cdn_format;
|
||||
error_log /var/log/nginx/error.log warn;
|
||||
|
||||
##
|
||||
# Cache Paths
|
||||
##
|
||||
proxy_cache_path /var/cache/nginx/static levels=1:2 keys_zone=static_cache:100m
|
||||
max_size={{ cache_size }} inactive=7d use_temp_path=off;
|
||||
proxy_cache_path /var/cache/nginx/images levels=1:2 keys_zone=images_cache:100m
|
||||
max_size={{ cache_size }} inactive=30d use_temp_path=off;
|
||||
proxy_cache_path /var/cache/nginx/html levels=1:2 keys_zone=html_cache:50m
|
||||
max_size=5g inactive=1h use_temp_path=off;
|
||||
|
||||
##
|
||||
# Upstream zu Origin-Servern
|
||||
##
|
||||
upstream origin_servers {
|
||||
{% for host in groups['origin_servers'] %}
|
||||
server {{ hostvars[host]['ansible_default_ipv4']['address'] }}:443
|
||||
weight=1 max_fails=3 fail_timeout=30s;
|
||||
{% endfor %}
|
||||
keepalive 32;
|
||||
keepalive_requests 1000;
|
||||
keepalive_timeout 60s;
|
||||
}
|
||||
|
||||
##
|
||||
# Include configurations
|
||||
##
|
||||
include /etc/nginx/includes/*.conf;
|
||||
include /etc/nginx/sites-enabled/*;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
# Rate Limiting Zones
|
||||
|
||||
limit_req_zone $binary_remote_addr zone=api:10m rate={{ rate_limits.api }};
|
||||
limit_req_zone $binary_remote_addr zone=static_files:10m rate={{ rate_limits.static }};
|
||||
limit_req_zone $binary_remote_addr zone=images:10m rate={{ rate_limits.images }};
|
||||
|
||||
# Connection Limiting
|
||||
limit_conn_zone $binary_remote_addr zone=perip:10m;
|
||||
limit_conn perip 10;
|
||||
@@ -0,0 +1,10 @@
|
||||
# Security Headers für CDN
|
||||
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header X-XSS-Protection "1; mode=block" always;
|
||||
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
||||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
||||
|
||||
# DSGVO Header
|
||||
add_header X-Data-Processing "Art. 6 Abs. 1 lit. f DSGVO" always;
|
||||
@@ -0,0 +1,29 @@
|
||||
---
|
||||
# Einfaches Monitoring ohne Prometheus
|
||||
|
||||
- name: Create simple monitoring script
|
||||
template:
|
||||
src: simple-monitor.sh.j2
|
||||
dest: /usr/local/bin/cdn-monitor
|
||||
mode: '0755'
|
||||
|
||||
- name: Setup monitoring cron job
|
||||
cron:
|
||||
name: "CDN Health Monitor"
|
||||
minute: "*/5"
|
||||
job: "/usr/local/bin/cdn-monitor"
|
||||
user: root
|
||||
|
||||
- name: Create log rotation for monitoring logs
|
||||
copy:
|
||||
content: |
|
||||
/var/log/nginx/cdn-monitor.log {
|
||||
weekly
|
||||
missingok
|
||||
rotate 4
|
||||
compress
|
||||
delaycompress
|
||||
notifempty
|
||||
}
|
||||
dest: /etc/logrotate.d/cdn-monitor
|
||||
mode: '0644'
|
||||
@@ -0,0 +1,71 @@
|
||||
#!/bin/bash
|
||||
# Einfaches CDN Monitoring für {{ inventory_hostname }}
|
||||
|
||||
LOG_FILE="/var/log/nginx/cdn-monitor.log"
|
||||
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
|
||||
CDN_DOMAIN="{{ cdn_domain }}"
|
||||
|
||||
# Health Check
|
||||
health_check() {
|
||||
local response=$(curl -s -o /dev/null -w "%{http_code}" "https://$CDN_DOMAIN/health")
|
||||
|
||||
if [ "$response" = "200" ]; then
|
||||
echo "[$TIMESTAMP] ✅ Health check OK" >> $LOG_FILE
|
||||
return 0
|
||||
else
|
||||
echo "[$TIMESTAMP] ❌ Health check FAILED (HTTP $response)" >> $LOG_FILE
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Nginx-Statistiken
|
||||
nginx_stats() {
|
||||
local stats=$(curl -s http://127.0.0.1/nginx_status 2>/dev/null)
|
||||
if [ $? -eq 0 ]; then
|
||||
local active_conn=$(echo "$stats" | grep "Active connections" | awk '{print $3}')
|
||||
local total_requests=$(echo "$stats" | grep "server accepts" | awk '{print $3}')
|
||||
echo "[$TIMESTAMP] 📊 Active: $active_conn, Total: $total_requests" >> $LOG_FILE
|
||||
fi
|
||||
}
|
||||
|
||||
# Cache-Größe prüfen
|
||||
cache_check() {
|
||||
local cache_size=$(du -sh /var/cache/nginx/ 2>/dev/null | cut -f1)
|
||||
local cache_files=$(find /var/cache/nginx/ -type f 2>/dev/null | wc -l)
|
||||
echo "[$TIMESTAMP] 💾 Cache: $cache_size ($cache_files files)" >> $LOG_FILE
|
||||
}
|
||||
|
||||
# System-Ressourcen
|
||||
system_check() {
|
||||
local load=$(uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' ')
|
||||
local memory=$(free | grep Mem | awk '{printf "%.1f", $3/$2 * 100.0}')
|
||||
local disk=$(df / | tail -1 | awk '{print $5}' | sed 's/%//')
|
||||
|
||||
echo "[$TIMESTAMP] 🖥️ Load: $load, Memory: ${memory}%, Disk: ${disk}%" >> $LOG_FILE
|
||||
|
||||
# Warnungen bei hoher Auslastung
|
||||
if (( $(echo "$load > 5.0" | bc -l 2>/dev/null || echo 0) )); then
|
||||
echo "[$TIMESTAMP] ⚠️ HIGH LOAD WARNING: $load" >> $LOG_FILE
|
||||
fi
|
||||
|
||||
if (( $(echo "$memory > 90.0" | bc -l 2>/dev/null || echo 0) )); then
|
||||
echo "[$TIMESTAMP] ⚠️ HIGH MEMORY WARNING: ${memory}%" >> $LOG_FILE
|
||||
fi
|
||||
|
||||
if [ "$disk" -gt 85 ]; then
|
||||
echo "[$TIMESTAMP] ⚠️ HIGH DISK USAGE WARNING: ${disk}%" >> $LOG_FILE
|
||||
fi
|
||||
}
|
||||
|
||||
# Hauptausführung
|
||||
main() {
|
||||
health_check
|
||||
nginx_stats
|
||||
cache_check
|
||||
system_check
|
||||
|
||||
# Log-Datei begrenzen (nur letzte 1000 Zeilen behalten)
|
||||
tail -n 1000 $LOG_FILE > ${LOG_FILE}.tmp && mv ${LOG_FILE}.tmp $LOG_FILE
|
||||
}
|
||||
|
||||
main
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
# SSL-Zertifikate mit Let's Encrypt
|
||||
|
||||
- name: Check if certificate exists
|
||||
stat:
|
||||
path: "/etc/letsencrypt/live/{{ cdn_domain }}/fullchain.pem"
|
||||
register: cert_exists
|
||||
|
||||
- name: Generate SSL certificate with certbot
|
||||
command: >
|
||||
certbot certonly --nginx
|
||||
-d {{ cdn_domain }}
|
||||
--non-interactive
|
||||
--agree-tos
|
||||
--email {{ ssl_email }}
|
||||
when: not cert_exists.stat.exists
|
||||
|
||||
- name: Setup SSL certificate renewal
|
||||
cron:
|
||||
name: "Renew SSL certificates"
|
||||
minute: "0"
|
||||
hour: "3"
|
||||
job: "certbot renew --quiet --deploy-hook 'systemctl reload nginx'"
|
||||
user: root
|
||||
|
||||
- name: Test SSL certificate renewal (dry-run)
|
||||
command: certbot renew --dry-run
|
||||
register: renewal_test
|
||||
failed_when: renewal_test.rc != 0
|
||||
changed_when: false
|
||||
44
ansible/nginx-cdn-germany/scripts/deploy.sh
Normal file
44
ansible/nginx-cdn-germany/scripts/deploy.sh
Normal file
@@ -0,0 +1,44 @@
|
||||
#!/bin/bash
|
||||
# Simple CDN Deployment Script
|
||||
|
||||
set -e
|
||||
|
||||
INVENTORY_FILE="inventories/production/hosts.yml"
|
||||
PLAYBOOK="playbooks/deploy-simple-cdn.yml"
|
||||
|
||||
echo "🚀 Starting Simple CDN Deployment for Germany..."
|
||||
|
||||
# Pre-deployment checks
|
||||
echo "🔍 Running pre-deployment checks..."
|
||||
if ! ansible all -i $INVENTORY_FILE -m ping; then
|
||||
echo "❌ Some hosts are not reachable. Please check your inventory."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "📋 Testing ansible configuration..."
|
||||
if ! ansible-playbook $PLAYBOOK -i $INVENTORY_FILE --check --diff; then
|
||||
echo "❌ Configuration test failed. Please fix errors first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
read -p "Continue with deployment? (y/N): " -n 1 -r
|
||||
echo
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo "Deployment cancelled."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Deployment
|
||||
echo "🔧 Deploying CDN nodes..."
|
||||
ansible-playbook $PLAYBOOK -i $INVENTORY_FILE
|
||||
|
||||
# Post-deployment verification
|
||||
echo "✅ Verifying deployment..."
|
||||
ansible cdn_nodes -i $INVENTORY_FILE -m uri -a "url=https://{{ inventory_hostname }}/health method=GET status_code=200"
|
||||
|
||||
echo "🎉 CDN Deployment completed successfully!"
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo "1. Update your DNS to point to the CDN nodes"
|
||||
echo "2. Test your CDN: curl -I https://your-cdn-domain.de/health"
|
||||
echo "3. Monitor with: ansible-playbook -i $INVENTORY_FILE playbooks/manage-cdn.yml"
|
||||
125
ansible/nginx-cdn-germany/scripts/ssh-keys.sh
Normal file
125
ansible/nginx-cdn-germany/scripts/ssh-keys.sh
Normal file
@@ -0,0 +1,125 @@
|
||||
#!/bin/bash
|
||||
# SSH-Schlüssel Management für CDN
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
show_help() {
|
||||
echo "CDN SSH Key Management"
|
||||
echo ""
|
||||
echo "Usage: $0 [OPTION]"
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " single - Ein Schlüssel für alle Nodes (Standard)"
|
||||
echo " individual - Separater Schlüssel pro Node"
|
||||
echo " grouped - Gruppierte Schlüssel (Primary/Secondary)"
|
||||
echo " generate - SSH-Schlüssel generieren"
|
||||
echo " deploy - Öffentliche Schlüssel zu Servern kopieren"
|
||||
echo " help - Diese Hilfe anzeigen"
|
||||
}
|
||||
|
||||
generate_single_key() {
|
||||
echo "🔑 Generiere einen SSH-Schlüssel für alle CDN-Nodes..."
|
||||
|
||||
if [ ! -f ~/.ssh/cdn_key ]; then
|
||||
ssh-keygen -t ed25519 -C "cdn-deployment" -f ~/.ssh/cdn_key -N ""
|
||||
echo "✅ Schlüssel generiert: ~/.ssh/cdn_key"
|
||||
else
|
||||
echo "ℹ️ Schlüssel existiert bereits: ~/.ssh/cdn_key"
|
||||
fi
|
||||
|
||||
# Inventar anpassen
|
||||
sed -i 's|ansible_ssh_private_key_file: .*|ansible_ssh_private_key_file: ~/.ssh/cdn_key|' \
|
||||
"$SCRIPT_DIR/../inventories/production/hosts.yml"
|
||||
|
||||
echo "✅ Inventar aktualisiert"
|
||||
}
|
||||
|
||||
generate_individual_keys() {
|
||||
echo "🔑 Generiere individuelle SSH-Schlüssel..."
|
||||
|
||||
NODES=("cdn_fra1" "cdn_ham1" "cdn_muc1" "origin1" "origin2")
|
||||
|
||||
for node in "${NODES[@]}"; do
|
||||
if [ ! -f ~/.ssh/${node}_key ]; then
|
||||
ssh-keygen -t ed25519 -C "cdn-${node}" -f ~/.ssh/${node}_key -N ""
|
||||
echo "✅ Schlüssel generiert: ~/.ssh/${node}_key"
|
||||
else
|
||||
echo "ℹ️ Schlüssel existiert bereits: ~/.ssh/${node}_key"
|
||||
fi
|
||||
done
|
||||
|
||||
echo "✅ Alle individuellen Schlüssel generiert"
|
||||
echo "💡 Verwende: cp inventories/production/hosts-individual-keys.yml.example inventories/production/hosts.yml"
|
||||
}
|
||||
|
||||
generate_grouped_keys() {
|
||||
echo "🔑 Generiere gruppierte SSH-Schlüssel..."
|
||||
|
||||
GROUPS=("origin_servers" "cdn_primary" "cdn_secondary")
|
||||
|
||||
for group in "${GROUPS[@]}"; do
|
||||
if [ ! -f ~/.ssh/${group}_key ]; then
|
||||
ssh-keygen -t ed25519 -C "cdn-${group}" -f ~/.ssh/${group}_key -N ""
|
||||
echo "✅ Schlüssel generiert: ~/.ssh/${group}_key"
|
||||
else
|
||||
echo "ℹ️ Schlüssel existiert bereits: ~/.ssh/${group}_key"
|
||||
fi
|
||||
done
|
||||
|
||||
echo "✅ Alle gruppierten Schlüssel generiert"
|
||||
echo "💡 Verwende: cp inventories/production/hosts-grouped-keys.yml.example inventories/production/hosts.yml"
|
||||
}
|
||||
|
||||
deploy_keys() {
|
||||
echo "🚀 Deploye öffentliche Schlüssel zu den Servern..."
|
||||
|
||||
# Lese IPs aus dem Inventar
|
||||
IPS=$(grep "ansible_host:" "$SCRIPT_DIR/../inventories/production/hosts.yml" | awk '{print $2}' | sort | uniq)
|
||||
|
||||
for ip in $IPS; do
|
||||
echo "Deploying to $ip..."
|
||||
|
||||
# Versuche verschiedene Schlüssel
|
||||
for key in ~/.ssh/*_key ~/.ssh/cdn_key ~/.ssh/id_rsa; do
|
||||
if [ -f "$key" ]; then
|
||||
echo " Versuche Schlüssel: $key"
|
||||
if ssh-copy-id -i "${key}.pub" "root@$ip" 2>/dev/null; then
|
||||
echo " ✅ Erfolgreich: $key -> $ip"
|
||||
break
|
||||
fi
|
||||
fi
|
||||
done
|
||||
done
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
"single")
|
||||
generate_single_key
|
||||
;;
|
||||
"individual")
|
||||
generate_individual_keys
|
||||
;;
|
||||
"grouped")
|
||||
generate_grouped_keys
|
||||
;;
|
||||
"generate")
|
||||
echo "Welche Art von Schlüsseln?"
|
||||
echo "1) Ein Schlüssel für alle (empfohlen für Start)"
|
||||
echo "2) Individuelle Schlüssel pro Node (sicherste)"
|
||||
echo "3) Gruppierte Schlüssel (Kompromiss)"
|
||||
read -p "Wähle (1-3): " choice
|
||||
|
||||
case $choice in
|
||||
1) generate_single_key ;;
|
||||
2) generate_individual_keys ;;
|
||||
3) generate_grouped_keys ;;
|
||||
*) echo "Ungültige Auswahl" ;;
|
||||
esac
|
||||
;;
|
||||
"deploy")
|
||||
deploy_keys
|
||||
;;
|
||||
"help"|*)
|
||||
show_help
|
||||
;;
|
||||
esac
|
||||
37
ansible/nginx-cdn-germany/scripts/warm-cache.sh
Normal file
37
ansible/nginx-cdn-germany/scripts/warm-cache.sh
Normal file
@@ -0,0 +1,37 @@
|
||||
#!/bin/bash
|
||||
# Cache Warming Script
|
||||
|
||||
INVENTORY_FILE="inventories/production/hosts.yml"
|
||||
|
||||
# URLs zum Cache-Warming
|
||||
URLS=(
|
||||
"/"
|
||||
"/health"
|
||||
# Füge hier deine wichtigsten URLs hinzu:
|
||||
# "/css/main.css"
|
||||
# "/js/app.js"
|
||||
# "/images/logo.png"
|
||||
)
|
||||
|
||||
echo "🔥 Starting cache warming for all CDN nodes..."
|
||||
|
||||
# Hole alle CDN Node Hostnamen
|
||||
CDN_NODES=$(ansible-inventory -i $INVENTORY_FILE --list | jq -r '.cdn_nodes.hosts[]' 2>/dev/null || ansible cdn_nodes -i $INVENTORY_FILE --list-hosts | grep -v hosts)
|
||||
|
||||
for node in $CDN_NODES; do
|
||||
echo "Warming cache for: $node"
|
||||
|
||||
for url in "${URLS[@]}"; do
|
||||
echo " Warming: $url"
|
||||
response=$(curl -s -o /dev/null -w "%{http_code}" "https://${node}${url}" || echo "000")
|
||||
if [ "$response" = "200" ]; then
|
||||
echo " ✅ OK"
|
||||
else
|
||||
echo " ❌ Failed (HTTP $response)"
|
||||
fi
|
||||
sleep 0.5
|
||||
done
|
||||
echo ""
|
||||
done
|
||||
|
||||
echo "🎉 Cache warming completed!"
|
||||
Reference in New Issue
Block a user