chore: lots of changes

This commit is contained in:
2025-05-24 07:09:22 +02:00
parent 77ee769d5e
commit 899227b0a4
178 changed files with 5145 additions and 53 deletions

View File

@@ -0,0 +1,6 @@
wireguard_interface: wg0
wireguard_port: 51820
wireguard_address: 10.8.0.1/24
wireguard_server_ip: 94.16.110.151 # oder deine Domain
wireguard_network: "10.8.0.0/24"

View File

@@ -0,0 +1,133 @@
# --------------------------------------------------------
# WireGuard installieren
# --------------------------------------------------------
- name: Stelle sicher, dass WireGuard installiert ist
apt:
name: wireguard
state: present
update_cache: yes
become: true
when: ansible_connection != "local"
# --------------------------------------------------------
# Server-Schlüssel erzeugen und speichern
# --------------------------------------------------------
- name: Prüfe ob privater Server-Schlüssel existiert
stat:
path: /etc/wireguard/privatekey
register: privkey_file
become: true
when: ansible_connection != "local"
- name: Erstelle Schlüsselpaar für Server (wenn nicht vorhanden)
command: wg genkey
register: server_private_key
when: ansible_connection != "local" and (not privkey_file.stat.exists | default(true))
- name: Speichere privaten Schlüssel
copy:
content: "{{ server_private_key.stdout }}"
dest: /etc/wireguard/privatekey
mode: "0600"
when: server_private_key.stdout is defined and server_private_key.stdout is defined
- name: Lies privaten Schlüssel ein
slurp:
src: /etc/wireguard/privatekey
become: true
when: ansible_connection != "local"
- name: Erzeuge öffentlichen Server-Schlüssel
command: "echo '{{ wg_privkey }}' | wg pubkey"
register: wg_pubkey
when: ansible_connection != "local"
- name: Privaten Server-Schlüssel anzeigen
debug:
msg: "{{ server_private_key }}"
when: ansible_connection != "local"
# --------------------------------------------------------
# Client-Key-Erzeugung lokal (einmalig pro Client)
# --------------------------------------------------------
- name: Generiere privaten Schlüssel für Clients (auf dem Server)
command: wg genkey
args:
creates: "/etc/wireguard/client-{{ item.name }}.key"
loop: "{{ wireguard_clients }}"
loop_control:
label: "{{ item.name }}"
register: client_private_keys
when: ansible_connection != "local"
- name: Erzeuge öffentlichen Schlüssel für Clients
command: "echo '{{ client_privkey_result.stdout }}' | wg pubkey"
register: client_pubkey_result
when:
- ansible_connection != "local"
- client_privkey_result is defined
- client_privkey_result.stdout is defined
- name: wireguard_clients mit public_key anreichern
set_fact:
wireguard_clients: "{{ wireguard_clients_with_pubkey | default([]) + [ item.0 | combine({'public_key': item.1.stdout|trim }) ] }}"
loop: "{{ wireguard_clients | zip(client_public_keys.results) | list }}"
when: client_public_keys is defined
- name: Aktuelles wireguard_clients-Set überschreiben
set_fact:
wireguard_clients: "{{ wireguard_clients_with_pubkey }}"
when: wireguard_clients_with_pubkey is defined
# --------------------------------------------------------
# Konfigurationsdatei erzeugen
# --------------------------------------------------------
#- debug:
# var: wireguard_clients
- name: Render wg0.conf
template:
src: wg0.conf.j2
dest: /etc/wireguard/wg0.conf
when: wg_privkey is defined and wg_privkey != ""
# --------------------------------------------------------
# IP Forwarding & WireGuard aktivieren
# --------------------------------------------------------
- name: Aktiviere IP-Forwarding
sysctl:
name: net.ipv4.ip_forward
value: 1
state: present
sysctl_set: yes
reload: yes
become: true
when: ansible_connection != "local"
- name: Starte und aktiviere WireGuard
systemd:
name: wg-quick@wg0
enabled: true
state: started
daemon_reload: yes
become: true
when: ansible_connection != "local"
- name: Verteilt für jeden Client die Client-Config
template:
src: client.conf.j2
dest: "/etc/wireguard/clients/{{ item.name }}.conf"
owner: root
group: root
mode: 0600
loop: "{{ wireguard_clients }}"
#delegate_to: localhost
run_once: true
become: true
when: ansible_connection != "local"

View File

@@ -0,0 +1,54 @@
---
# roles/wireguard/tasks/failsafe.yml
# Sicherstellt, dass SSH über VPN funktioniert und ein Fallback vorhanden ist
- name: Stelle sicher, dass wireguard_network gesetzt ist
assert:
that:
- wireguard_network is defined
fail_msg: "wireguard_network muss gesetzt sein (z.B. 10.8.0.0/24)"
- name: Automatisch externe IP als fallback_ip setzen (nur wenn nicht gesetzt)
shell: curl -s ifconfig.me
register: detected_fallback_ip
when: fallback_ip is not defined
changed_when: false
- name: Setze fallback_ip dynamisch als Ansible-Fact (wenn nicht gesetzt)
set_fact:
fallback_ip: "{{ detected_fallback_ip.stdout }}"
when: fallback_ip is not defined
- name: (Optional) Erlaube temporär Fallback-SSH von aktueller IP
ufw:
rule: allow
port: 22
proto: tcp
from_ip: "{{ fallback_ip }}"
- name: Erlaube SSH-Zugriff über VPN
ufw:
rule: allow
port: 22
proto: tcp
from_ip: "{{ wireguard_network }}"
- name: (Warnung) Prüfe ob VPN-Interface aktiv ist
shell: ip a show dev wg0
register: vpn_interface_check
failed_when: false
- name: Hinweis, wenn VPN-Interface nicht aktiv ist
debug:
msg: "⚠️ VPN-Interface wg0 scheint nicht aktiv zu sein. SSH über VPN wird nicht funktionieren."
when: vpn_interface_check.rc != 0
- name: (Optional) SSH von überall blockieren nur wenn VPN aktiv
when:
- ssh_lockdown | default(false)
- vpn_interface_check.rc == 0
ufw:
rule: deny
port: 22
proto: tcp
from_ip: 0.0.0.0/0

View File

@@ -0,0 +1,83 @@
# Beispiel: Passe jeden Task in dieser Datei so an:
- name: Aktiviere Firewall-Regeln für WireGuard
ufw:
rule: allow
port: "{{ wireguard_port }}"
proto: udp
become: true
when: ansible_connection != "local"
- name: Prüfe, ob UFW installiert ist
command: which ufw
register: ufw_installed
ignore_errors: true
changed_when: false
- name: Installiere UFW (falls nicht vorhanden)
apt:
name: ufw
state: present
update_cache: yes
when: ufw_installed.rc != 0
# Setze Standardrichtlinien (erst Konfiguration, dann am Ende aktivieren)
- name: Setze Policy für eingehenden Traffic auf "deny"
ufw:
direction: incoming
policy: deny
- name: Setze Policy für ausgehenden Traffic auf "allow"
ufw:
direction: outgoing
policy: allow
# WireGuard-Port freigeben (UDP)
- name: WireGuard-Port erlauben
ufw:
rule: allow
port: "{{ wireguard_port | default(51820) }}"
proto: udp
# SSH von bestimmter IP erlauben
- name: SSH von deiner IP erlauben (empfohlen)
ufw:
rule: allow
port: 22
proto: tcp
from_ip: "{{ fallback_ip }}"
when: fallback_ip is defined and fallback_ip | length > 0
# Temporär für Tests: SSH für alle erlauben (nur bei Bedarf!)
- name: SSH von überall erlauben (fail-safe, NUR während Setup/Test)
ufw:
rule: allow
port: 22
proto: tcp
when: (not (fallback_ip is defined and fallback_ip | length > 0)) or (enable_ssh_from_anywhere | default(false))
# Masquerading für WireGuard
- name: NAT für WireGuard aktivieren
iptables:
table: nat
chain: POSTROUTING
out_interface: "{{ wireguard_exit_interface | default('eth0') }}"
source: "{{ wireguard_network }}"
jump: MASQUERADE
- name: WireGuard Kernel-Modul laden
modprobe:
name: wireguard
state: present
# UFW ganz am Schluss aktivieren
- name: UFW aktivieren
ufw:
state: enabled
- name: Aktive UFW-Regeln anzeigen (zum Debuggen)
command: ufw status verbose
register: ufw_status
changed_when: false
- name: Zeige UFW-Regeln im Ansible-Output
debug:
var: ufw_status.stdout

View File

@@ -0,0 +1,60 @@
- name: Key-Verzeichnis für Client anlegen
file:
path: "{{ role_path }}/client-keys/{{ client.name }}"
state: directory
mode: "0700"
become: true
- name: Existenz des privaten Schlüssels prüfen
stat:
path: "{{ role_path }}/client-keys/{{ client.name }}/private.key"
register: client_private_key_stat
- name: Privaten Schlüssel generieren (nur falls nicht vorhanden)
command: wg genkey
register: genpriv
args:
chdir: "{{ role_path }}/client-keys/{{ client.name }}"
when: not client_private_key_stat.stat.exists
- name: Privaten Schlüssel speichern (nur falls nicht vorhanden)
copy:
content: "{{ genpriv.stdout }}"
dest: "{{ role_path }}/client-keys/{{ client.name }}/private.key"
mode: "0600"
when: not client_private_key_stat.stat.exists
- name: Public Key aus privaten Schlüssel generieren (bei Neuerstellung)
command: wg pubkey
args:
stdin: "{{ genpriv.stdout }}"
chdir: "{{ role_path }}/client-keys/{{ client.name }}"
register: genpub
when: not client_private_key_stat.stat.exists
- name: Bestehenden privaten Schlüssel laden (falls vorhanden)
slurp:
src: "{{ role_path }}/client-keys/{{ client.name }}/private.key"
register: loaded_private
when: client_private_key_stat.stat.exists
- name: Public Key aus gespeichertem Private Key erzeugen (falls vorhanden)
command: wg pubkey
args:
stdin: "{{ loaded_private.content | b64decode }}"
chdir: "{{ role_path }}/client-keys/{{ client.name }}"
register: genpub_existing
when: client_private_key_stat.stat.exists
- name: Public Key für Client in Datei schreiben
copy:
content: >
{{ (genpub.stdout if not client_private_key_stat.stat.exists else genpub_existing.stdout) }}
dest: "{{ role_path }}/client-keys/{{ client.name }}/public.key"
mode: "0644"
- name: Variablen für Client setzen (private/public key, Adresse)
set_fact:
"wg_{{ client.name }}_private_key": "{{ (genpriv.stdout if not client_private_key_stat.stat.exists else loaded_private.content | b64decode) }}"
"wg_{{ client.name }}_public_key": "{{ (genpub.stdout if not client_private_key_stat.stat.exists else genpub_existing.stdout) }}"
"wg_{{ client.name }}_address": "{{ client.address }}"

View File

@@ -0,0 +1,39 @@
- name: Schleife über alle WireGuard-Clients
include_tasks: generate_client_single.yml
loop: "{{ wireguard_clients }}"
loop_control:
loop_var: client
- name: Generiere privaten Schlüssel für jeden Client
shell: "wg genkey"
register: wg_client_private_keys
loop: "{{ wireguard_clients }}"
loop_control:
label: "{{ item.name }}"
# kein delegate_to mehr!
run_once: true # ggf. auch entfernen, siehe Anmerkung unten
- name: Setze globale Client-Key-Facts für alle Clients
set_fact:
wg_all_clients_private_keys: >-
{{
wg_all_clients_private_keys | default({}) | combine({
item.1.name: item.0.stdout
})
}}
loop: "{{ wg_client_private_keys.results | zip(wireguard_clients) | list }}"
delegate_to: localhost
run_once: true
- name: Generiere Private Keys für Clients
command: "wg genkey"
register: client_keys_raw
loop: "{{ wireguard_clients }}"
loop_control:
loop_var: client
changed_when: false
- name: Mappe Keys nach Namen
set_fact:
wg_all_clients_private_keys: "{{ dict(wireguard_clients | map(attribute='name') | list | zip(client_keys_raw.results | map(attribute='stdout') | list)) }}"

View File

@@ -0,0 +1,7 @@
- name: Stelle sicher, dass WireGuard installiert ist
apt:
name: wireguard
state: present
update_cache: yes
become: true
when: ansible_connection != "local"

View File

@@ -0,0 +1,22 @@
#- include_tasks: install.yml
#- include_tasks: configure.yml
#- include_tasks: generate_clients.yml
#- include_tasks: firewall.yml
- name: Installiere WireGuard
import_tasks: install.yml
when: ansible_connection != "local"
- name: Konfiguriere WireGuard
import_tasks: configure.yml
- name: Generiert .conf Dateien
import_tasks: generate_clients.yml
- name: Setze Firewall-Regeln
import_tasks: firewall.yml
when: ansible_connection != "local"
- name: Wende VPN-Failsafe-Regeln an
import_tasks: failsafe.yml

View File

@@ -0,0 +1,10 @@
[Interface]
PrivateKey = {{ wg_all_clients_private_keys[item.name] }}
Address = {{ item.address }}/32
DNS = 1.1.1.1
[Peer]
PublicKey = {{ item.public_key }}
Endpoint = {{ wireguard_server_ip }}:{{ wireguard_port }}
AllowedIPs = {{ wireguard_network }}, {{ wireguard_server_ip }}/32
PersistentKeepalive = 25

View File

@@ -0,0 +1,12 @@
[Interface]
Address = {{ wireguard_address }}
PrivateKey = {{ wg_privkey | b64decode | trim }}
ListenPort = {{ wireguard_port }}
PostUp = iptables -A FORWARD -i {{ wireguard_interface }} -j ACCEPT; iptables -A FORWARD -o {{ wireguard_interface }} -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i {{ wireguard_interface }} -j ACCEPT; iptables -D FORWARD -o {{ wireguard_interface }} -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
{% for client in wireguard_clients %}
[Peer]
PublicKey = {{ client.public_key }}
AllowedIPs = {{ client.address }}/32
{% endfor %}