major overhaul of server/client setup, avoiding loops and allowing for targetting one host

This commit is contained in:
max.mehl
2022-03-02 17:12:10 +01:00
parent 480929b214
commit 5047342f0f
4 changed files with 153 additions and 185 deletions

View File

@@ -5,66 +5,10 @@
--- ---
- hosts: innernet_server - hosts: innernet_server
remote_user: root remote_user: root
tasks:
- name: Install needed packages
apt:
package:
- sqlite3
- name: Query innernet-server for CIDRs
shell: 'sqlite3 /var/lib/innernet-server/{{ network_name }}.db "select name from cidrs;"'
register: global_existing_cidrs
ignore_errors: true
- name: CIDRs already registered on innernet-server
debug:
msg: "{{ item }}"
loop: "{{ global_existing_cidrs.stdout_lines }}"
- name: CIDRs defined in this playbook
debug:
msg: "{{ item.name }}"
loop: "{{ cidrs }}"
- name: These CIDRs have been added
debug:
msg: "{{ item.name }} is new!"
when: item.name not in global_existing_cidrs.stdout_lines
loop: "{{ cidrs }}"
- name: Query innernet-server for peers
shell: 'sqlite3 /var/lib/innernet-server/{{ network_name }}.db "select name from peers;"'
register: global_existing_peers
ignore_errors: true
- name: Peers already registered on innernet-server
debug:
msg: "{{ item }}"
loop: "{{ global_existing_peers.stdout_lines }}"
- name: Peers defined in this playbook
debug:
msg: "{{ item.name }}"
loop: "{{ peers }}"
- name: These peers have been added
debug:
msg: "{{ item.name }} is new!"
when: item.name not in global_existing_peers.stdout_lines
loop: "{{ peers }}"
- hosts: innernet_server
remote_user: root
vars:
existing_peers: "{{ global_existing_peers.stdout_lines }}"
existing_cidrs: "{{ global_existing_cidrs.stdout_lines }}"
roles: roles:
- server - server
- hosts: innernet_client - hosts: innernet_client
remote_user: root remote_user: root
vars:
existing_peers: "{{ global_existing_peers.stdout_lines }}"
existing_cidrs: "{{ global_existing_cidrs.stdout_lines }}"
roles: roles:
- client - client

View File

@@ -36,6 +36,7 @@ cidrs:
# machines, e.g. # machines, e.g.
# - { "cidr": "machines", "name": "cont1-plutex", "admin": "false" } # - { "cidr": "machines", "name": "cont1-plutex", "admin": "false" }
peers: "{{ peers_var|from_yaml }}" peers: "{{ peers_var|from_yaml }}"
machine_cidr: { "name": "machines", "cidr": "10.200.64.0/18", "admin": "false" }
peers_var: | peers_var: |
- { "cidr": "admins", "name": "linus", "admin": "true" } - { "cidr": "admins", "name": "linus", "admin": "true" }
- { "cidr": "admins", "name": "max-mehl", "admin": "true" } - { "cidr": "admins", "name": "max-mehl", "admin": "true" }
@@ -43,7 +44,7 @@ peers_var: |
{% for host in groups['innernet_client'] %} {% for host in groups['innernet_client'] %}
- { - {
"cidr": "machines", "cidr": "machines",
"name": {{ host.replace('.', '-').replace('-fsfeurope-org', '').replace('-fsfe-org', '') }}, "name": {{ host.replace('.', '-').replace('-fsfeurope-org', '').replace('-fsfe-org', '').replace('-fsfe-be', '') }},
"admin": "false" "admin": "false"
} }
{% endfor %} {% endfor %}

View File

@@ -3,11 +3,47 @@
# SPDX-License-Identifier: AGPL-3.0-or-later # SPDX-License-Identifier: AGPL-3.0-or-later
--- ---
- name: Install needed packages for uninstalling innernet - name: Get innernet-server hostname from inventory groups
tags: [never, uninstall] set_fact:
# Assuming that we only have one innernet server, we take the first
# occurence
innernet_server: "{{ groups['innernet_server'][0] }}"
run_once: true
- name: Convert hostname to innernet peer name
tags: [peers]
# we want the mere host name before the domain, so e.g.
# * server1.fsfe.org -> server1
# * cont1.noris.fsfeurope.org -> cont1-noris
set_fact:
innernet_client: "{{ innernet_client | replace(item.0, item.1) }}"
vars:
- innernet_client: "{{ ansible_host }}"
loop:
- ['.', '-']
- ['-fsfeurope-org', '']
- ['-fsfe-org', '']
- ['-fsfe-be', '']
- name: Get existing peers from innernet-server database
tags: [peers]
shell: 'sqlite3 /var/lib/innernet-server/{{ network_name }}.db "select name from peers;"'
register: existing_peers
delegate_to: "{{ innernet_server }}"
- name: Gather which packages are installed on the client
tags: [update]
package_facts:
manager: auto
- name: Make sure needed packages for innernet and wireguard are installed
apt: apt:
package: package:
- python3-pexpect - python3-pexpect
- rsync
- wireguard
- wireguard-tools
- ufw
- name: Remove existing innernet - name: Remove existing innernet
tags: [never, uninstall] tags: [never, uninstall]
@@ -16,56 +52,72 @@
responses: responses:
(?i)delete: "yes" (?i)delete: "yes"
- name: Install needed packages - name: Install innernet package on client
tags: [always, update]
apt:
package:
- ufw
- rsync
- wireguard
- wireguard-tools
- name: Copy package to host
tags: [update] tags: [update]
block:
- name: Copy innernet package to client
synchronize: synchronize:
src: "innernet.deb" src: "innernet.deb"
dest: "/tmp/innernet.deb" dest: "/tmp/innernet.deb"
- name: Install package - name: Install innernet client package
tags: [update]
apt: apt:
deb: "/tmp/innernet.deb" deb: "/tmp/innernet.deb"
update_cache: true update_cache: true
install_recommends: true install_recommends: true
# If 1. innernet not installed or 2. `update` tag executed
when: "'innernet' not in ansible_facts.packages or 'update' in ansible_run_tags"
- name: Copy non-admin invitation to hosts - name: Make client a new innernet peer
tags: [new_peer] tags: [peers]
synchronize: block:
src: "{{ item.name }}.toml" - name: Add client as innernet peer
dest: "/tmp/{{ item.name }}.toml"
when:
# is not existing
- item.name not in hostvars['kaim.fsfeurope.org'].global_existing_peers.stdout_lines
# only if filename contains a part of the hostname
- item.name in ansible_host|replace('.', '-')
loop: "{{ peers }}"
- name: Install non-admin invitation on hosts
tags: [new_peer]
shell: | shell: |
innernet install /tmp/{{ item.name }}.toml \ innernet-server add-peer "{{ network_name }}" \
--name "{{ innernet_client }}" \
--cidr "{{ machine_cidr.name }}" \
--admin "{{ machine_cidr.admin }}" \
--save-config "/root/{{ innernet_client }}.toml" \
--invite-expires "14d" \
--auto-ip \
--yes
delegate_to: "{{ innernet_server }}"
- name: Copy peer invitation file from server to controller
fetch:
src: "/root/{{ innernet_client }}.toml"
dest: "{{ playbook_dir }}/roles/client/files/{{ innernet_client }}.toml"
flat: yes
fail_on_missing: yes
delegate_to: "{{ innernet_server }}"
- name: Copy peer invitation file from controller to client
copy:
src: "{{ innernet_client }}.toml"
dest: "/root/{{ innernet_client }}.toml"
- name: Install peer invitation on client
shell: |
innernet install /root/{{ innernet_client }}.toml \
--default-name \ --default-name \
--delete-invite --delete-invite
- name: Delete peer invitation file from client
file:
state: absent
path: "/root/{{ innernet_client }}.toml"
- name: Delete peer invitation file from server
file:
state: absent
path: "/root/{{ innernet_client }}.toml"
delegate_to: "{{ innernet_server }}"
when: when:
# is not existing - innernet_client not in existing_peers.stdout_lines
- item.name not in hostvars['kaim.fsfeurope.org'].global_existing_peers.stdout_lines
# only if filename contains a part of the hostname
- item.name in ansible_host|replace('.', '-')
loop: "{{ peers }}"
- name: Set listen port - name: Set listen port
tags: [listen_port] tags: [listen_port]
community.general.ini_file: ini_file:
path: "/etc/innernet/{{ network_name }}.conf" path: "/etc/innernet/{{ network_name }}.conf"
section: interface section: interface
option: listen-port option: listen-port
@@ -80,14 +132,9 @@
rule: allow rule: allow
proto: udp proto: udp
- name: Just force systemd to reread configs (2.4 and above)
tags: [systemd, daemon]
ansible.builtin.systemd:
daemon_reload: yes
- name: Restart and enable innernet daemon - name: Restart and enable innernet daemon
tags: [systemd, daemon] systemd:
ansible.builtin.systemd:
name: "innernet@{{ network_name }}" name: "innernet@{{ network_name }}"
state: restarted state: restarted
enabled: true enabled: yes
daemon_reload: yes

View File

@@ -3,11 +3,20 @@
# SPDX-License-Identifier: AGPL-3.0-or-later # SPDX-License-Identifier: AGPL-3.0-or-later
--- ---
- name: Install needed packages - name: Gather which packages are installed on the server
tags: [never, uninstall] tags: [update]
package_facts:
manager: auto
- name: Make sure needed packages for innernet and wireguard are installed
apt: apt:
package: package:
- python3-pexpect - python3-pexpect
- rsync
- sqlite3
- wireguard
- wireguard-tools
- ufw
- name: Remove existing innernet - name: Remove existing innernet
tags: [never, uninstall] tags: [never, uninstall]
@@ -16,34 +25,31 @@
responses: responses:
(?i)delete: "yes" (?i)delete: "yes"
- name: Install needed packages - name: Install innernet package on server
tags: [update]
block:
- name: Copy innernet-server package to server
tags: [update] tags: [update]
apt:
package:
- rsync
- wireguard
- wireguard-tools
- name: Copy package to server
tags: [never, update]
synchronize: synchronize:
src: "innernet-server.deb" src: "innernet-server.deb"
dest: "/tmp/innernet-server.deb" dest: "/tmp/innernet-server.deb"
- name: Install package - name: Install innernet-server package
tags: [never, update] tags: [update]
apt: apt:
deb: "/tmp/innernet-server.deb" deb: "/tmp/innernet-server.deb"
update_cache: true update_cache: true
install_recommends: true install_recommends: true
# If 1. innernet-server not installed or 2. `update` tag executed
when: "'innernet-server' not in ansible_facts.packages or 'update' in ansible_run_tags"
- name: Check if network is initialised - name: Check if innernet network is initialised
tags: [base] tags: [base]
stat: stat:
path: "/etc/innernet-server/{{ network_name }}.conf" path: "/etc/innernet-server/{{ network_name }}.conf"
register: conf_file register: conf_file
- name: Create base network - name: Create base network if not existent yet
tags: [base] tags: [base]
shell: | shell: |
innernet-server new \ innernet-server new \
@@ -53,7 +59,12 @@
--listen-port {{ network_listen_port }} --listen-port {{ network_listen_port }}
when: not conf_file.stat.exists when: not conf_file.stat.exists
- name: Create CIDRs - name: Get existing CIDRs from innernet-server database
tags: [cidr]
shell: 'sqlite3 /var/lib/innernet-server/{{ network_name }}.db "select name from cidrs;"'
register: existing_cidrs
- name: Create new CIDRs
tags: [cidr] tags: [cidr]
shell: | shell: |
innernet-server add-cidr "{{ network_name }}" \ innernet-server add-cidr "{{ network_name }}" \
@@ -63,61 +74,26 @@
--yes --yes
loop: "{{ cidrs }}" loop: "{{ cidrs }}"
when: when:
- item.name not in existing_cidrs - item.name not in existing_cidrs.stdout_lines
- name: Create peers - name: Enable firewall and allow SSH
tags: [peers] tags: [listen_port, firewall]
shell: | ufw:
innernet-server add-peer "{{ network_name }}" \ state: enabled
--name "{{ item.name }}" \ default: deny
--cidr "{{ item.cidr }}" \ to_port: 22
--admin "{{ item.admin }}" \ rule: allow
--save-config "{{ item.name }}.toml" \
--invite-expires "14d" \
--auto-ip \
--yes
loop: "{{ peers }}"
when:
- item.name not in existing_peers
- name: Check for actual peer invitation files - name: Allow UDP traffic on WireGuard port
tags: [peers] tags: [listen_port, firewall]
shell: ls | grep .toml ufw:
register: toml_files to_port: "{{ network_listen_port }}"
ignore_errors: true rule: allow
proto: udp
- name: Custom error message - name: Restart and enable innernet-server daemon
tags: [peers]
fail:
msg: "Could not find any new invitation files. Have you added a new peer?"
when: toml_files.rc == 1
- name: Copy invitation files of peers to controller
tags: [peers]
synchronize:
src: "/root/{{ item.name }}.toml"
dest: "{{ playbook_dir }}/roles/client/files/{{ item.name }}.toml"
mode: pull
when: toml_files.stdout.find(item.name) != -1
loop: "{{ peers }}"
- name: Make sure invitation files are deleted on innernet-server
tags: [peers]
file:
state: absent
path: "/root/{{ item.name }}.toml"
loop: "{{ peers }}"
when:
- item.name not in existing_peers
- name: Just force systemd to reread configs (2.4 and above)
tags: [systemd, daemon]
ansible.builtin.systemd:
daemon_reload: yes
- name: Enable innernet-server daemon
tags: [systemd, daemon]
systemd: systemd:
name: "innernet-server@{{ network_name }}" name: "innernet-server@{{ network_name }}"
state: restarted state: restarted
enabled: true enabled: yes
daemon_reload: yes