diff --git a/.gitignore b/.gitignore index 5c199eb..d4623cf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ # ---> Ansible *.retry - +.venv +ssh diff --git a/ansible.cfg b/ansible.cfg new file mode 100644 index 0000000..001defe --- /dev/null +++ b/ansible.cfg @@ -0,0 +1,12 @@ +[defaults] +verbosity = 2 + +remote_user = ansible + +become_method = sudo + +remote_tmp = /tmp/.ansible/tmp + +[persistent_connection] +connect_timeout = 30 +command_timeout = 30 \ No newline at end of file diff --git a/inventory.yml b/inventory.yml new file mode 100644 index 0000000..53379c6 --- /dev/null +++ b/inventory.yml @@ -0,0 +1,6 @@ +main: + hosts: + wireguard: + ansible_host: 100.222.6.20 + ansible_user: ansible + ansible_ssh_private_key_file: ssh/privkey diff --git a/playbook.yml b/playbook.yml new file mode 100644 index 0000000..805c0be --- /dev/null +++ b/playbook.yml @@ -0,0 +1,7 @@ +--- +- name: "Deploy WireGuard" + tags: configure, wireguard + hosts: wireguard + become: true + roles: + - homelab/wireguard diff --git a/roles/homelab/wireguard/handlers/main.yml b/roles/homelab/wireguard/handlers/main.yml new file mode 100644 index 0000000..17178fc --- /dev/null +++ b/roles/homelab/wireguard/handlers/main.yml @@ -0,0 +1,16 @@ +--- + +- name: "restart wireguard" + ansible.builtin.systemd: + name: "wg-quick@{{ wireguard_interface }}" + state: restarted + +- name: "restart nftables" + ansible.builtin.systemd: + name: "nftables" + state: restarted + +- name: "restart named" + ansible.builtin.systemd: + name: "named" + state: restarted \ No newline at end of file diff --git a/roles/homelab/wireguard/tasks/configure_bind9.yml b/roles/homelab/wireguard/tasks/configure_bind9.yml new file mode 100644 index 0000000..5cbd215 --- /dev/null +++ b/roles/homelab/wireguard/tasks/configure_bind9.yml @@ -0,0 +1,20 @@ +--- + +- name: "Import named.conf.local" + tags: bind9 + ansible.builtin.template: + src: named.conf.local.j2 + dest: /etc/bind/named.conf.local + owner: root + group: bind + mode: '0644' + +- name: "Import data base domain serti.fun" + tags: bind9 + ansible.builtin.template: + src: db.serti.fun.j2 + dest: /etc/bind/db.serti.fun + owner: root + group: bind + mode: '0644' + notify: "restart named" \ No newline at end of file diff --git a/roles/homelab/wireguard/tasks/configure_system.yml b/roles/homelab/wireguard/tasks/configure_system.yml new file mode 100644 index 0000000..084fe36 --- /dev/null +++ b/roles/homelab/wireguard/tasks/configure_system.yml @@ -0,0 +1,17 @@ +--- + +- name: "Enable ipv4 forward" + ansible.posix.sysctl: + name: net.ipv4.ip_forward + value: 1 + state: present + reload: yes + +- name: "Upload nftable" + ansible.builtin.template: + src: nftables.conf.j2 + dest: /etc/nftables.conf + owner: root + group: root + mode: '0644' + notify: "restart nftables" \ No newline at end of file diff --git a/roles/homelab/wireguard/tasks/configure_wireguard_server.yml b/roles/homelab/wireguard/tasks/configure_wireguard_server.yml new file mode 100644 index 0000000..18e8a05 --- /dev/null +++ b/roles/homelab/wireguard/tasks/configure_wireguard_server.yml @@ -0,0 +1,39 @@ +--- + +- name: "Generate private key" + ansible.builtin.command: + cmd: wg genkey + register: wg_server_privkey + args: + creates: "{{ wireguard_config_dir }}/server_private.key" + no_log: true + +- name: "Save private key" + ansible.builtin.copy: + content: "{{ wg_server_privkey.stdout }}" + dest: "{{ wireguard_config_dir }}/server_private.key" + owner: root + group: root + mode: "0600" + when: wg_server_privkey.changed + no_log: true + +- name: "Read private key" + ansible.builtin.slurp: + src: "{{ wireguard_config_dir }}/server_private.key" + register: wg_server_privkey_content + no_log: true + +- name: "Generate public key" + ansible.builtin.shell: + cmd: "cat {{ wireguard_config_dir }}/server_private.key | wg pubkey" + register: wg_server_pubkey + changed_when: false + +- name: "Save public key" + ansible.builtin.copy: + content: "{{ wg_server_pubkey.stdout }}" + dest: "{{ wireguard_config_dir }}/server_public.key" + owner: root + group: root + mode: "0600" \ No newline at end of file diff --git a/roles/homelab/wireguard/tasks/install_package.yml b/roles/homelab/wireguard/tasks/install_package.yml new file mode 100644 index 0000000..c937426 --- /dev/null +++ b/roles/homelab/wireguard/tasks/install_package.yml @@ -0,0 +1,14 @@ +--- +- name: "Install default packages" + ansible.builtin.apt: + name: "{{ default_packages }}" + state: present + become: true + register: deps_installed + +- name: "Install wireguard" + ansible.builtin.apt: + name: "{{ wireguard_packages }}" + state: present + become: true + register: deps_installed \ No newline at end of file diff --git a/roles/homelab/wireguard/tasks/main.yml b/roles/homelab/wireguard/tasks/main.yml new file mode 100644 index 0000000..94e2acf --- /dev/null +++ b/roles/homelab/wireguard/tasks/main.yml @@ -0,0 +1,73 @@ +--- + +- name: "Change repos" + ansible.builtin.template: + src: mirror-yandex.ru.j2 + dest: /etc/apt/sources.list + owner: root + group: root + mode: '0744' + +- name: "Update cache" + ansible.builtin.apt: + update_cache: true + cache_valid_time: 3600 + +- name: "Install packages" + ansible.builtin.include_tasks: install_package.yml + +- name: "Configure system" + ansible.builtin.include_tasks: configure_system.yml + +- name: "Configure wireguard server" + ansible.builtin.include_tasks: configure_wireguard_server.yml + +- name: "Create client dirrectory" + ansible.builtin.file: + path: "{{ wireguard_client_config_dir }}" + state: directory + owner: root + group: root + mode: "0700" + +- name: "Include peer management tasks" + tags: peers + ansible.builtin.include_tasks: peers.yml + +- name: "Deploy wireguard server configuration" + ansible.builtin.template: + src: wg0.conf.j2 + dest: "{{ wireguard_config_dir }}/{{ wireguard_interface }}.conf" + owner: root + group: root + mode: '0600' + notify: "restart wireguard" + #notify: restart wireguard_client_config_dir + +- name: "Confiugre bind9" + tags: bind9 + ansible.builtin.include_tasks: configure_bind9.yml + +- name: "Enable and start nftables" + ansible.builtin.systemd: + name: "nftables" + state: started + enabled: yes + +- name: "Enable and start wireguard" + ansible.builtin.systemd: + name: "wg-quick@{{ wireguard_interface }}" + state: started + enabled: yes + +- name: "Enable and start bind9" + ansible.builtin.systemd: + name: "bind9" + state: started + enabled: yes + +- name: "Enable and start named" + ansible.builtin.systemd: + name: "named" + state: started + enabled: yes diff --git a/roles/homelab/wireguard/tasks/peers.yml b/roles/homelab/wireguard/tasks/peers.yml new file mode 100644 index 0000000..bdd133b --- /dev/null +++ b/roles/homelab/wireguard/tasks/peers.yml @@ -0,0 +1,71 @@ +--- + +- name: "Generate private keys" + ansible.builtin.shell: + cmd: wg genkey + register: "peer_keys" + loop: "{{ wireguard_clients }}" + loop_control: + label: "{{ item.name }}" + args: + creates: "{{ wireguard_config_dir }}/peer_{{ item.name }}_private.key" + no_log: true + +- name: "Save private keys" + ansible.builtin.copy: + content: "{{ item.stdout }}" + dest: "{{ wireguard_config_dir }}/peer_{{ item.item.name }}_private.key" + owner: root + group: root + mode: "0600" + loop: "{{ peer_keys.results }}" + loop_control: + label: "{{ item.item.name }}" + when: item.change | default(false) + no_log: true + +- name: "Read all private keys" + ansible.builtin.slurp: + src: "{{ wireguard_config_dir }}/peer_{{ item.name }}_private.key" + register: peer_privkey_contents + loop: "{{ wireguard_clients }}" + loop_control: + label: "{{ item.name }}" + no_log: true + +- name: "Generate public keys" + ansible.builtin.shell: + cmd: "cat {{ wireguard_config_dir }}/peer_{{ item.name }}_private.key | wg pubkey" + register: peer_pubkey + loop: "{{ wireguard_clients }}" + loop_control: + label: "{{ item.name }}" + changed_when: false + +- name: "Save public keys" + ansible.builtin.copy: + content: "{{ item.stdout }}" + dest: "{{ wireguard_config_dir }}/peer_{{ item.item.name }}_public.key" + mode: '0644' + loop: "{{ peer_pubkey.results }}" + loop_control: + label: "{{ item.item.name }}" + +- name: "Generate client configuration files" + ansible.builtin.template: + src: client.conf.j2 + dest: "{{ wireguard_client_config_dir }}/{{ item.0.name }}.conf" + owner: root + group: root + mode: '0600' + loop: "{{ wireguard_clients | zip(peer_privkey_contents.results, peer_pubkey.results) | list }}" + loop_control: + label: "{{ item.0.name }}" + +- name: "Generate QR codes for moblie clients" + ansible.builtin.shell: + cmd: "qrencode -t ansiutf8 < {{ wireguard_client_config_dir }}/{{ item.name }}.conf > {{ wireguard_client_config_dir }}/{{ item.name }}_qr.txt" + loop: "{{ wireguard_clients }}" + loop_control: + label: "{{ item.name }}" + changed_when: false diff --git a/roles/homelab/wireguard/templates/client.conf.j2 b/roles/homelab/wireguard/templates/client.conf.j2 new file mode 100644 index 0000000..ea10a48 --- /dev/null +++ b/roles/homelab/wireguard/templates/client.conf.j2 @@ -0,0 +1,10 @@ +[Interface] +PrivateKey = {{ item.1.content | b64decode | trim }} +Address = {{ item.0.address }}/32 +DNS = {{ wireguard_dns }} + +[Peer] +PublicKey = {{ wg_server_pubkey.stdout }} +Endpoint = {{ wireguard_remote_address }}:{{ wireguard_port }} +AllowedIPs = {{ item.0.allowed_ips }} +PersistentKeepalive = 25 \ No newline at end of file diff --git a/roles/homelab/wireguard/templates/db.serti.fun.j2 b/roles/homelab/wireguard/templates/db.serti.fun.j2 new file mode 100644 index 0000000..81c3e55 --- /dev/null +++ b/roles/homelab/wireguard/templates/db.serti.fun.j2 @@ -0,0 +1,22 @@ +$TTL 3600 +@ IN SOA wireguard.serti.fun. admin.serti.fun. ( + 1 ; serial + 3600 ; refresh + 1800 ; retry + 604800 ; expire + 3600 ; minimum + ) + +; Name servers +@ IN NS wireguard.serti.fun. + +; A records +wireguard IN A {{ wireguard_address }} + +@ IN A {{ wireguard_remote_address }} +{% set apache2 = wireguard_clients | selectattr('name', 'equalto', 'apache2') | first %} +{% for sub in subdomains %} +{{ sub }} IN A {{ apache2.address }} +{% endfor %} + +* IN A {{ wireguard_remote_address }} \ No newline at end of file diff --git a/roles/homelab/wireguard/templates/mirror-yandex.ru.j2 b/roles/homelab/wireguard/templates/mirror-yandex.ru.j2 new file mode 100644 index 0000000..646b499 --- /dev/null +++ b/roles/homelab/wireguard/templates/mirror-yandex.ru.j2 @@ -0,0 +1,8 @@ +deb http://mirror.yandex.ru/debian/ trixie main non-free-firmware +#deb-src http://mirror.yandex.ru/debian/ trixie main non-free-firmware + +deb http://mirror.yandex.ru/debian-security trixie-security main non-free-firmware +#deb-src http://mirror.yandex.ru/debian-security trixie-security main non-free-firmware + +deb http://mirror.yandex.ru/debian/ trixie-updates main non-free-firmware +#deb-src http://mirror.yandex.ru/debian/ trixie-updates main non-free-firmware \ No newline at end of file diff --git a/roles/homelab/wireguard/templates/named.conf.local.j2 b/roles/homelab/wireguard/templates/named.conf.local.j2 new file mode 100644 index 0000000..aadde04 --- /dev/null +++ b/roles/homelab/wireguard/templates/named.conf.local.j2 @@ -0,0 +1,10 @@ +zone "serti.fun" { + type primary; + file "/etc/bind/db.serti.fun"; + allow-transfer { none; }; + allow-update { none; }; + allow-query { + 127.0.0.1; + {{ wireguard_network }}; + }; +}; \ No newline at end of file diff --git a/roles/homelab/wireguard/templates/nftables.conf.j2 b/roles/homelab/wireguard/templates/nftables.conf.j2 new file mode 100644 index 0000000..de1b3e3 --- /dev/null +++ b/roles/homelab/wireguard/templates/nftables.conf.j2 @@ -0,0 +1,47 @@ +#!/usr/sbin/nft -f + +flush ruleset + +table inet filter { + set home_net { + type ipv4_addr + flags interval + comment "Home subnet" + elements = {100.222.5.0/24} + } + set iot_net { + type ipv4_addr + flags interval + comment "iOT subnet" + elements = {100.222.6.0/24} + } + set vpn_net { + type ipv4_addr + flags interval + comment "iOT subnet" + elements = {100.222.11.0/24} + } + + chain input { + type filter hook input priority filter; policy drop; + + iif lo accept comment "Accept any localhost trafic" + ct state invalid drop comment "Drop invalid connection" + fib daddr . iif type != {local, broadcast, multicast} drop + ct state { established, related } accept + + #meta l4proto { icmp, ipv6-icmp } accept comment "Accept ICMP" + + tcp dport 22 accept comment "Allow ssh connection from home subnet" + ip saddr @vpn_net tcp dport 53 accept comment "Allow ssh connection from home subnet" + + ip saddr @vpn_net udp dport 53 accept comment "Allow ssh connection from home subnet" + udp dport {{ wireguard_port }} accept comment "Wireguard port" + } + chain forward { + type filter hook forward priority filter; + } + chain output { + type filter hook output priority filter; + } +} \ No newline at end of file diff --git a/roles/homelab/wireguard/templates/wg0.conf.j2 b/roles/homelab/wireguard/templates/wg0.conf.j2 new file mode 100644 index 0000000..92fb84f --- /dev/null +++ b/roles/homelab/wireguard/templates/wg0.conf.j2 @@ -0,0 +1,12 @@ +[Interface] +Address = {{ wireguard_address }}/24 +ListenPort = {{ wireguard_port }} +PrivateKey = {{ wg_server_privkey_content.content | b64decode | trim }} + +{% for peer in wireguard_clients %} +{% set peer_pubkey = peer_pubkey.results[loop.index0].stdout %} +#Peer: {{ peer.name }} +[Peer] +PublicKey = {{ peer_pubkey }} +AllowedIPs = {{ peer.address }} +{% endfor %} \ No newline at end of file diff --git a/roles/homelab/wireguard/vars/main.yml b/roles/homelab/wireguard/vars/main.yml new file mode 100644 index 0000000..362e336 --- /dev/null +++ b/roles/homelab/wireguard/vars/main.yml @@ -0,0 +1,52 @@ +--- + +wireguard_port: 51820 +wireguard_interface: wg0 +wireguard_address: 100.222.11.1 +wireguard_network: 100.222.11.0/24 +wireguard_dns: 100.222.11.1 +wireguard_remote_address: 95.165.172.12 +wireguard_config_dir: /etc/wireguard +wireguard_client_config_dir: /opt/wireguard-clients + +wireguard_clients: + - name: apache2 + address: 100.222.11.2 + allowed_ips: 100.222.11.0/24 + - name: laptop + address: 100.222.11.3 + allowed_ips: 100.222.11.0/24 + - name: phone_poco-x5-pro-5g + address: 100.222.11.4 + allowed_ips: 100.222.11.0/24 + +subdomains: + - ai + - pve + - dockge + - kuma + - lidarr + - sonarr + - radarr + - truenas + - qbittorrent + - mirror + - suwayomi + +default_packages: + - qemu-guest-agent + - vim + - git + - curl + - wget + - qrencode + - tcpdump + - iperf3 + - bind9 + - bind9-dnsutils + - bind9-utils + + +wireguard_packages: + - wireguard + - wireguard-tools