Ansible upgrade 6.1 (#14500)

* linting

* update ansible

* linters
pull/14472/head
Jack Ivanov 2 years ago committed by GitHub
parent a43de09437
commit 347f864abb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,6 +1,10 @@
skip_list: skip_list:
- yaml
- '204' - '204'
verbosity: 1 verbosity: 1
warn_list: warn_list:
- no-changed-when - no-changed-when
- no-handler
- fqcn-builtins
- var-spacing

@ -18,7 +18,7 @@ jobs:
python -m pip install --upgrade pip python -m pip install --upgrade pip
pip install -r requirements.txt pip install -r requirements.txt
sudo snap install shellcheck sudo snap install shellcheck
pip install ansible-lint pip install ansible-lint==6.3.0
- name: Checks and linters - name: Checks and linters
run: | run: |

@ -8,14 +8,14 @@
tasks: tasks:
- block: - block:
- name: Local pre-tasks - name: Local pre-tasks
import_tasks: playbooks/cloud-pre.yml import_tasks: playbooks/cloud-pre.yml
- name: Include a provisioning role - name: Include a provisioning role
include_role: include_role:
name: "{{ 'local' if algo_provider == 'local' else 'cloud-' + algo_provider }}" name: "{{ 'local' if algo_provider == 'local' else 'cloud-' + algo_provider }}"
- name: Local post-tasks - name: Local post-tasks
import_tasks: playbooks/cloud-post.yml import_tasks: playbooks/cloud-post.yml
rescue: rescue:
- include_tasks: playbooks/rescue.yml - include_tasks: playbooks/rescue.yml

@ -13,7 +13,7 @@
ansible_ssh_user: "{{ 'root' if client_ip == 'localhost' else ssh_user }}" ansible_ssh_user: "{{ 'root' if client_ip == 'localhost' else ssh_user }}"
vpn_user: "{{ vpn_user }}" vpn_user: "{{ vpn_user }}"
IP_subject_alt_name: "{{ server_ip }}" IP_subject_alt_name: "{{ server_ip }}"
ansible_python_interpreter: "/usr/bin/python3" ansible_python_interpreter: /usr/bin/python3
- name: Configure the client and install required software - name: Configure the client and install required software
hosts: client-host hosts: client-host

@ -18,127 +18,126 @@
- { name: Google Compute Engine, alias: gce } - { name: Google Compute Engine, alias: gce }
- { name: Hetzner Cloud, alias: hetzner } - { name: Hetzner Cloud, alias: hetzner }
- { name: Vultr, alias: vultr } - { name: Vultr, alias: vultr }
- { name: Scaleway, alias: scaleway} - { name: Scaleway, alias: scaleway }
- { name: OpenStack (DreamCompute optimised), alias: openstack } - { name: OpenStack (DreamCompute optimised), alias: openstack }
- { name: CloudStack (Exoscale optimised), alias: cloudstack } - { name: CloudStack (Exoscale optimised), alias: cloudstack }
- { name: Linode, alias: linode } - { name: Linode, alias: linode }
- { name: "Install to existing Ubuntu 18.04 or 20.04 server (for more advanced users)", alias: local } - { name: Install to existing Ubuntu 18.04 or 20.04 server (for more advanced users), alias: local }
vars_files: vars_files:
- config.cfg - config.cfg
tasks: tasks:
- block: - block:
- name: Cloud prompt - name: Cloud prompt
pause: pause:
prompt: | prompt: |
What provider would you like to use? What provider would you like to use?
{% for p in providers_map %} {% for p in providers_map %}
{{ loop.index }}. {{ p['name'] }} {{ loop.index }}. {{ p['name'] }}
{% endfor %} {% endfor %}
Enter the number of your desired provider Enter the number of your desired provider
register: _algo_provider register: _algo_provider
when: provider is undefined when: provider is undefined
- name: Set facts based on the input - name: Set facts based on the input
set_fact: set_fact:
algo_provider: "{{ provider | default(providers_map[_algo_provider.user_input|default(omit)|int - 1]['alias']) }}" algo_provider: "{{ provider | default(providers_map[_algo_provider.user_input|default(omit)|int - 1]['alias']) }}"
- name: VPN server name prompt - name: VPN server name prompt
pause: pause:
prompt: | prompt: |
Name the vpn server Name the vpn server
[algo] [algo]
register: _algo_server_name register: _algo_server_name
when: when:
- server_name is undefined - server_name is undefined
- algo_provider != "local" - algo_provider != "local"
- name: Cellular On Demand prompt - name: Cellular On Demand prompt
pause: pause:
prompt: | prompt: |
Do you want macOS/iOS clients to enable "Connect On Demand" when connected to cellular networks? Do you want macOS/iOS clients to enable "Connect On Demand" when connected to cellular networks?
[y/N] [y/N]
register: _ondemand_cellular register: _ondemand_cellular
when: ondemand_cellular is undefined when: ondemand_cellular is undefined
- name: Wi-Fi On Demand prompt - name: Wi-Fi On Demand prompt
pause: pause:
prompt: | prompt: |
Do you want macOS/iOS clients to enable "Connect On Demand" when connected to Wi-Fi? Do you want macOS/iOS clients to enable "Connect On Demand" when connected to Wi-Fi?
[y/N] [y/N]
register: _ondemand_wifi register: _ondemand_wifi
when: ondemand_wifi is undefined when: ondemand_wifi is undefined
- name: Trusted Wi-Fi networks prompt - name: Trusted Wi-Fi networks prompt
pause: pause:
prompt: | prompt: |
List the names of any trusted Wi-Fi networks where macOS/iOS clients should not use "Connect On Demand" List the names of any trusted Wi-Fi networks where macOS/iOS clients should not use "Connect On Demand"
(e.g., your home network. Comma-separated value, e.g., HomeNet,OfficeWifi,AlgoWiFi) (e.g., your home network. Comma-separated value, e.g., HomeNet,OfficeWifi,AlgoWiFi)
register: _ondemand_wifi_exclude register: _ondemand_wifi_exclude
when: when:
- ondemand_wifi_exclude is undefined - ondemand_wifi_exclude is undefined
- (ondemand_wifi|default(false)|bool) or - (ondemand_wifi|default(false)|bool) or (booleans_map[_ondemand_wifi.user_input|default(omit)]|default(false))
(booleans_map[_ondemand_wifi.user_input|default(omit)]|default(false))
- name: Retain the PKI prompt - name: Retain the PKI prompt
pause: pause:
prompt: | prompt: |
Do you want to retain the keys (PKI)? (required to add users in the future, but less secure) Do you want to retain the keys (PKI)? (required to add users in the future, but less secure)
[y/N] [y/N]
register: _store_pki register: _store_pki
when: when:
- store_pki is undefined - store_pki is undefined
- ipsec_enabled - ipsec_enabled
- name: DNS adblocking prompt - name: DNS adblocking prompt
pause: pause:
prompt: | prompt: |
Do you want to enable DNS ad blocking on this VPN server? Do you want to enable DNS ad blocking on this VPN server?
[y/N] [y/N]
register: _dns_adblocking register: _dns_adblocking
when: dns_adblocking is undefined when: dns_adblocking is undefined
- name: SSH tunneling prompt - name: SSH tunneling prompt
pause: pause:
prompt: | prompt: |
Do you want each user to have their own account for SSH tunneling? Do you want each user to have their own account for SSH tunneling?
[y/N] [y/N]
register: _ssh_tunneling register: _ssh_tunneling
when: ssh_tunneling is undefined when: ssh_tunneling is undefined
- name: Set facts based on the input - name: Set facts based on the input
set_fact: set_fact:
algo_server_name: >- algo_server_name: >-
{% if server_name is defined %}{% set _server = server_name %} {% if server_name is defined %}{% set _server = server_name %}
{%- elif _algo_server_name.user_input is defined and _algo_server_name.user_input|length > 0 -%} {%- elif _algo_server_name.user_input is defined and _algo_server_name.user_input|length > 0 -%}
{%- set _server = _algo_server_name.user_input -%} {%- set _server = _algo_server_name.user_input -%}
{%- else %}{% set _server = defaults['server_name'] %}{% endif -%} {%- else %}{% set _server = defaults['server_name'] %}{% endif -%}
{{ _server | regex_replace('(?!\.)(\W|_)', '-') }} {{ _server | regex_replace('(?!\.)(\W|_)', '-') }}
algo_ondemand_cellular: >- algo_ondemand_cellular: >-
{% if ondemand_cellular is defined %}{{ ondemand_cellular | bool }} {% if ondemand_cellular is defined %}{{ ondemand_cellular | bool }}
{%- elif _ondemand_cellular.user_input is defined %}{{ booleans_map[_ondemand_cellular.user_input] | default(defaults['ondemand_cellular']) }} {%- elif _ondemand_cellular.user_input is defined %}{{ booleans_map[_ondemand_cellular.user_input] | default(defaults['ondemand_cellular']) }}
{%- else %}false{% endif %} {%- else %}false{% endif %}
algo_ondemand_wifi: >- algo_ondemand_wifi: >-
{% if ondemand_wifi is defined %}{{ ondemand_wifi | bool }} {% if ondemand_wifi is defined %}{{ ondemand_wifi | bool }}
{%- elif _ondemand_wifi.user_input is defined %}{{ booleans_map[_ondemand_wifi.user_input] | default(defaults['ondemand_wifi']) }} {%- elif _ondemand_wifi.user_input is defined %}{{ booleans_map[_ondemand_wifi.user_input] | default(defaults['ondemand_wifi']) }}
{%- else %}false{% endif %} {%- else %}false{% endif %}
algo_ondemand_wifi_exclude: >- algo_ondemand_wifi_exclude: >-
{% if ondemand_wifi_exclude is defined %}{{ ondemand_wifi_exclude | b64encode }} {% if ondemand_wifi_exclude is defined %}{{ ondemand_wifi_exclude | b64encode }}
{%- elif _ondemand_wifi_exclude.user_input is defined and _ondemand_wifi_exclude.user_input|length > 0 -%} {%- elif _ondemand_wifi_exclude.user_input is defined and _ondemand_wifi_exclude.user_input|length > 0 -%}
{{ _ondemand_wifi_exclude.user_input | b64encode }} {{ _ondemand_wifi_exclude.user_input | b64encode }}
{%- else %}{{ '_null' | b64encode }}{% endif %} {%- else %}{{ '_null' | b64encode }}{% endif %}
algo_dns_adblocking: >- algo_dns_adblocking: >-
{% if dns_adblocking is defined %}{{ dns_adblocking | bool }} {% if dns_adblocking is defined %}{{ dns_adblocking | bool }}
{%- elif _dns_adblocking.user_input is defined %}{{ booleans_map[_dns_adblocking.user_input] | default(defaults['dns_adblocking']) }} {%- elif _dns_adblocking.user_input is defined %}{{ booleans_map[_dns_adblocking.user_input] | default(defaults['dns_adblocking']) }}
{%- else %}false{% endif %} {%- else %}false{% endif %}
algo_ssh_tunneling: >- algo_ssh_tunneling: >-
{% if ssh_tunneling is defined %}{{ ssh_tunneling | bool }} {% if ssh_tunneling is defined %}{{ ssh_tunneling | bool }}
{%- elif _ssh_tunneling.user_input is defined %}{{ booleans_map[_ssh_tunneling.user_input] | default(defaults['ssh_tunneling']) }} {%- elif _ssh_tunneling.user_input is defined %}{{ booleans_map[_ssh_tunneling.user_input] | default(defaults['ssh_tunneling']) }}
{%- else %}false{% endif %} {%- else %}false{% endif %}
algo_store_pki: >- algo_store_pki: >-
{% if ipsec_enabled %}{%- if store_pki is defined %}{{ store_pki | bool }} {% if ipsec_enabled %}{%- if store_pki is defined %}{{ store_pki | bool }}
{%- elif _store_pki.user_input is defined %}{{ booleans_map[_store_pki.user_input] | default(defaults['store_pki']) }} {%- elif _store_pki.user_input is defined %}{{ booleans_map[_store_pki.user_input] | default(defaults['store_pki']) }}
{%- else %}false{% endif %}{% endif %} {%- else %}false{% endif %}{% endif %}
rescue: rescue:
- include_tasks: playbooks/rescue.yml - include_tasks: playbooks/rescue.yml

@ -23,12 +23,15 @@
- name: Set required ansible version as a fact - name: Set required ansible version as a fact
set_fact: set_fact:
required_ansible_version: required_ansible_version: "{{ item | regex_replace('^ansible[\\s+]?(?P<op>[=,>,<]+)[\\s+]?(?P<ver>\\d.\\d+(.\\d+)?)$', '{\"op\": \"\\g<op>\",\"ver\"\
"{{ item | regex_replace('^ansible-core[\\s+]?(?P<op>[=,>,<]+)[\\s+]?(?P<ver>\\d.\\d+(.\\d+)?)$', : \"\\g<ver>\" }') }}"
'{\"op\": \"\\g<op>\",\"ver\": \"\\g<ver>\" }') }}" when: '"ansible" in item'
when: '"ansible-core" in item'
with_items: "{{ lookup('file', 'requirements.txt').splitlines() }}" with_items: "{{ lookup('file', 'requirements.txt').splitlines() }}"
- name: Just get the list from default pip
community.general.pip_package_info:
register: pip_package_info
- name: Verify Python meets Algo VPN requirements - name: Verify Python meets Algo VPN requirements
assert: assert:
that: (ansible_python.version.major|string + '.' + ansible_python.version.minor|string) is version('3.8', '>=') that: (ansible_python.version.major|string + '.' + ansible_python.version.minor|string) is version('3.8', '>=')
@ -40,10 +43,10 @@
- name: Verify Ansible meets Algo VPN requirements - name: Verify Ansible meets Algo VPN requirements
assert: assert:
that: that:
- ansible_version.full is version(required_ansible_version.ver, required_ansible_version.op) - pip_package_info.packages.pip.ansible.0.version is version(required_ansible_version.ver, required_ansible_version.op)
- not ipaddr.failed - not ipaddr.failed
msg: > msg: >
Ansible version is {{ ansible_version.full }}. Ansible version is {{ pip_package_info.packages.pip.ansible.0.version }}.
You must update the requirements to use this version of Algo. You must update the requirements to use this version of Algo.
Try to run python3 -m pip install -U -r requirements.txt Try to run python3 -m pip install -U -r requirements.txt

@ -10,7 +10,7 @@
ansible_connection: "{% if cloud_instance_ip == 'localhost' %}local{% else %}ssh{% endif %}" ansible_connection: "{% if cloud_instance_ip == 'localhost' %}local{% else %}ssh{% endif %}"
ansible_ssh_user: "{{ ansible_ssh_user|default('root') }}" ansible_ssh_user: "{{ ansible_ssh_user|default('root') }}"
ansible_ssh_port: "{{ ansible_ssh_port|default(22) }}" ansible_ssh_port: "{{ ansible_ssh_port|default(22) }}"
ansible_python_interpreter: "/usr/bin/python3" ansible_python_interpreter: /usr/bin/python3
algo_provider: "{{ algo_provider }}" algo_provider: "{{ algo_provider }}"
algo_server_name: "{{ algo_server_name }}" algo_server_name: "{{ algo_server_name }}"
algo_ondemand_cellular: "{{ algo_ondemand_cellular }}" algo_ondemand_cellular: "{{ algo_ondemand_cellular }}"
@ -33,7 +33,7 @@
wait_for: wait_for:
port: "{{ ansible_ssh_port|default(22) }}" port: "{{ ansible_ssh_port|default(22) }}"
host: "{{ cloud_instance_ip }}" host: "{{ cloud_instance_ip }}"
search_regex: "OpenSSH" search_regex: OpenSSH
delay: 10 delay: 10
timeout: 320 timeout: 320
state: present state: present
@ -44,8 +44,7 @@
when: when:
- pki_in_tmpfs - pki_in_tmpfs
- not algo_store_pki - not algo_store_pki
- ansible_system == "Darwin" or - ansible_system == "Darwin" or ansible_system == "Linux"
ansible_system == "Linux"
- debug: - debug:
var: IP_subject_alt_name var: IP_subject_alt_name

@ -1,53 +1,53 @@
--- ---
- block: - block:
- name: Display the invocation environment - name: Display the invocation environment
shell: > shell: >
./algo-showenv.sh \ ./algo-showenv.sh \
'algo_provider "{{ algo_provider }}"' \ 'algo_provider "{{ algo_provider }}"' \
{% if ipsec_enabled %} {% if ipsec_enabled %}
'algo_ondemand_cellular "{{ algo_ondemand_cellular }}"' \ 'algo_ondemand_cellular "{{ algo_ondemand_cellular }}"' \
'algo_ondemand_wifi "{{ algo_ondemand_wifi }}"' \ 'algo_ondemand_wifi "{{ algo_ondemand_wifi }}"' \
'algo_ondemand_wifi_exclude "{{ algo_ondemand_wifi_exclude }}"' \ 'algo_ondemand_wifi_exclude "{{ algo_ondemand_wifi_exclude }}"' \
{% endif %} {% endif %}
'algo_dns_adblocking "{{ algo_dns_adblocking }}"' \ 'algo_dns_adblocking "{{ algo_dns_adblocking }}"' \
'algo_ssh_tunneling "{{ algo_ssh_tunneling }}"' \ 'algo_ssh_tunneling "{{ algo_ssh_tunneling }}"' \
'wireguard_enabled "{{ wireguard_enabled }}"' \ 'wireguard_enabled "{{ wireguard_enabled }}"' \
'dns_encryption "{{ dns_encryption }}"' \ 'dns_encryption "{{ dns_encryption }}"' \
> /dev/tty || true > /dev/tty || true
tags: debug tags: debug
- name: Install the requirements - name: Install the requirements
pip: pip:
state: present state: present
name: name:
- pyOpenSSL>=0.15 - pyOpenSSL>=0.15
- segno - segno
tags: tags:
- always - always
- skip_ansible_lint - skip_ansible_lint
delegate_to: localhost delegate_to: localhost
become: false become: false
- block: - block:
- name: Generate the SSH private key - name: Generate the SSH private key
openssl_privatekey: openssl_privatekey:
path: "{{ SSH_keys.private }}" path: "{{ SSH_keys.private }}"
size: 2048 size: 2048
mode: "0600" mode: "0600"
type: RSA type: RSA
- name: Generate the SSH public key - name: Generate the SSH public key
openssl_publickey: openssl_publickey:
path: "{{ SSH_keys.public }}" path: "{{ SSH_keys.public }}"
privatekey_path: "{{ SSH_keys.private }}" privatekey_path: "{{ SSH_keys.private }}"
format: OpenSSH format: OpenSSH
- name: Copy the private SSH key to /tmp - name: Copy the private SSH key to /tmp
copy: copy:
src: "{{ SSH_keys.private }}" src: "{{ SSH_keys.private }}"
dest: "{{ SSH_keys.private_tmp }}" dest: "{{ SSH_keys.private_tmp }}"
force: true force: true
mode: '0600' mode: "0600"
delegate_to: localhost delegate_to: localhost
become: false become: false
when: algo_provider != "local" when: algo_provider != "local"

@ -1,5 +1,5 @@
--- ---
- name: Linux | set OS specific facts - name: Linux | set OS specific facts
set_fact: set_fact:
tmpfs_volume_name: "AlgoVPN-{{ IP_subject_alt_name }}" tmpfs_volume_name: AlgoVPN-{{ IP_subject_alt_name }}
tmpfs_volume_path: /dev/shm tmpfs_volume_path: /dev/shm

@ -1,7 +1,7 @@
--- ---
- name: MacOS | set OS specific facts - name: MacOS | set OS specific facts
set_fact: set_fact:
tmpfs_volume_name: "AlgoVPN-{{ IP_subject_alt_name }}" tmpfs_volume_name: AlgoVPN-{{ IP_subject_alt_name }}
tmpfs_volume_path: /Volumes tmpfs_volume_path: /Volumes
- name: MacOS | mount a ram disk - name: MacOS | mount a ram disk
@ -9,4 +9,4 @@
/usr/sbin/diskutil info "/{{ tmpfs_volume_path }}/{{ tmpfs_volume_name }}/" || /usr/sbin/diskutil info "/{{ tmpfs_volume_path }}/{{ tmpfs_volume_name }}/" ||
/usr/sbin/diskutil erasevolume HFS+ "{{ tmpfs_volume_name }}" $(hdiutil attach -nomount ram://64000) /usr/sbin/diskutil erasevolume HFS+ "{{ tmpfs_volume_name }}" $(hdiutil attach -nomount ram://64000)
args: args:
creates: "/{{ tmpfs_volume_path }}/{{ tmpfs_volume_name }}" creates: /{{ tmpfs_volume_path }}/{{ tmpfs_volume_name }}

@ -9,7 +9,7 @@
- name: Set config paths as facts - name: Set config paths as facts
set_fact: set_fact:
ipsec_pki_path: "/{{ tmpfs_volume_path }}/{{ tmpfs_volume_name }}/IPsec/" ipsec_pki_path: /{{ tmpfs_volume_path }}/{{ tmpfs_volume_name }}/IPsec/
- name: Update config paths - name: Update config paths
add_host: add_host:

@ -1,26 +1,26 @@
--- ---
- name: Linux | Delete the PKI directory - name: Linux | Delete the PKI directory
file: file:
path: "/{{ facts.tmpfs_volume_path }}/{{ facts.tmpfs_volume_name }}/" path: /{{ facts.tmpfs_volume_path }}/{{ facts.tmpfs_volume_name }}/
state: absent state: absent
when: facts.ansible_system == "Linux" when: facts.ansible_system == "Linux"
- block: - block:
- name: MacOS | check fs the ramdisk exists - name: MacOS | check fs the ramdisk exists
command: /usr/sbin/diskutil info "{{ facts.tmpfs_volume_name }}" command: /usr/sbin/diskutil info "{{ facts.tmpfs_volume_name }}"
ignore_errors: true ignore_errors: true
changed_when: false changed_when: false
register: diskutil_info register: diskutil_info
- name: MacOS | unmount and eject the ram disk - name: MacOS | unmount and eject the ram disk
shell: > shell: >
/usr/sbin/diskutil umount force "/{{ facts.tmpfs_volume_path }}/{{ facts.tmpfs_volume_name }}/" && /usr/sbin/diskutil umount force "/{{ facts.tmpfs_volume_path }}/{{ facts.tmpfs_volume_name }}/" &&
/usr/sbin/diskutil eject "{{ facts.tmpfs_volume_name }}" /usr/sbin/diskutil eject "{{ facts.tmpfs_volume_name }}"
changed_when: false changed_when: false
when: diskutil_info.rc == 0 when: diskutil_info.rc == 0
register: result register: result
until: result.rc == 0 until: result.rc == 0
retries: 5 retries: 5
delay: 3 delay: 3
when: when:
- facts.ansible_system == "Darwin" - facts.ansible_system == "Darwin"

@ -1,4 +1,3 @@
ansible-core==2.12.3 ansible==6.1.0
ansible==5.0.1
jinja2~=3.0.3 jinja2~=3.0.3
netaddr netaddr

@ -1,6 +1,6 @@
---
- name: Gather Facts - name: Gather Facts
setup: setup:
- name: Include system based facts and tasks - name: Include system based facts and tasks
import_tasks: systems/main.yml import_tasks: systems/main.yml
@ -22,9 +22,9 @@
- name: Setup the ipsec config - name: Setup the ipsec config
template: template:
src: "roles/strongswan/templates/client_ipsec.conf.j2" src: roles/strongswan/templates/client_ipsec.conf.j2
dest: "{{ configs_prefix }}/ipsec.{{ IP_subject_alt_name }}.conf" dest: "{{ configs_prefix }}/ipsec.{{ IP_subject_alt_name }}.conf"
mode: '0644' mode: "0644"
with_items: with_items:
- "{{ vpn_user }}" - "{{ vpn_user }}"
notify: notify:
@ -32,9 +32,9 @@
- name: Setup the ipsec secrets - name: Setup the ipsec secrets
template: template:
src: "roles/strongswan/templates/client_ipsec.secrets.j2" src: roles/strongswan/templates/client_ipsec.secrets.j2
dest: "{{ configs_prefix }}/ipsec.{{ IP_subject_alt_name }}.secrets" dest: "{{ configs_prefix }}/ipsec.{{ IP_subject_alt_name }}.secrets"
mode: '0600' mode: "0600"
with_items: with_items:
- "{{ vpn_user }}" - "{{ vpn_user }}"
notify: notify:
@ -44,12 +44,12 @@
lineinfile: lineinfile:
dest: "{{ item.dest }}" dest: "{{ item.dest }}"
line: "{{ item.line }}" line: "{{ item.line }}"
create: yes create: true
with_items: with_items:
- dest: "{{ configs_prefix }}/ipsec.conf" - dest: "{{ configs_prefix }}/ipsec.conf"
line: "include ipsec.{{ IP_subject_alt_name }}.conf" line: include ipsec.{{ IP_subject_alt_name }}.conf
- dest: "{{ configs_prefix }}/ipsec.secrets" - dest: "{{ configs_prefix }}/ipsec.secrets"
line: "include ipsec.{{ IP_subject_alt_name }}.secrets" line: include ipsec.{{ IP_subject_alt_name }}.secrets
notify: notify:
- restart strongswan - restart strongswan
@ -66,11 +66,11 @@
src: "{{ item.src }}" src: "{{ item.src }}"
dest: "{{ item.dest }}" dest: "{{ item.dest }}"
with_items: with_items:
- src: "configs/{{ IP_subject_alt_name }}/ipsec/.pki/certs/{{ vpn_user }}.crt" - src: configs/{{ IP_subject_alt_name }}/ipsec/.pki/certs/{{ vpn_user }}.crt
dest: "{{ configs_prefix }}/ipsec.d/certs/{{ vpn_user }}.crt" dest: "{{ configs_prefix }}/ipsec.d/certs/{{ vpn_user }}.crt"
- src: "configs/{{ IP_subject_alt_name }}/ipsec/.pki/cacert.pem" - src: configs/{{ IP_subject_alt_name }}/ipsec/.pki/cacert.pem
dest: "{{ configs_prefix }}/ipsec.d/cacerts/{{ IP_subject_alt_name }}.pem" dest: "{{ configs_prefix }}/ipsec.d/cacerts/{{ IP_subject_alt_name }}.pem"
- src: "configs/{{ IP_subject_alt_name }}/ipsec/.pki/private/{{ vpn_user }}.key" - src: configs/{{ IP_subject_alt_name }}/ipsec/.pki/private/{{ vpn_user }}.key
dest: "{{ configs_prefix }}/ipsec.d/private/{{ vpn_user }}.key" dest: "{{ configs_prefix }}/ipsec.d/private/{{ vpn_user }}.key"
notify: notify:
- restart strongswan - restart strongswan

@ -1,5 +1,4 @@
--- ---
- include_tasks: Debian.yml - include_tasks: Debian.yml
when: ansible_distribution == 'Debian' when: ansible_distribution == 'Debian'

@ -208,4 +208,3 @@ azure_regions:
- displayName: West US (Stage) - displayName: West US (Stage)
name: westusstage name: westusstage
regionalDisplayName: (US) West US (Stage) regionalDisplayName: (US) West US (Stage)

@ -6,21 +6,21 @@
subscription_id: "{{ azure_subscription_id | default(lookup('env','AZURE_SUBSCRIPTION_ID'), true) }}" subscription_id: "{{ azure_subscription_id | default(lookup('env','AZURE_SUBSCRIPTION_ID'), true) }}"
- block: - block:
- name: Set the default region - name: Set the default region
set_fact: set_fact:
default_region: >- default_region: >-
{% for r in azure_regions %}
{%- if r['name'] == "eastus" %}{{ loop.index }}{% endif %}
{%- endfor %}
- pause:
prompt: |
What region should the server be located in?
{% for r in azure_regions %} {% for r in azure_regions %}
{{ loop.index }}. {{ r['regionalDisplayName'] }} {%- if r['name'] == "eastus" %}{{ loop.index }}{% endif %}
{% endfor %} {%- endfor %}
- pause:
prompt: |
What region should the server be located in?
{% for r in azure_regions %}
{{ loop.index }}. {{ r['regionalDisplayName'] }}
{% endfor %}
Enter the number of your desired region Enter the number of your desired region
[{{ default_region }}] [{{ default_region }}]
register: _algo_region register: _algo_region
when: region is undefined when: region is undefined

@ -1,6 +1,6 @@
--- ---
- name: Install requirements - name: Install requirements
pip: pip:
requirements: https://raw.githubusercontent.com/ansible-collections/azure/v1.9.0/requirements-azure.txt requirements: https://raw.githubusercontent.com/ansible-collections/azure/v1.13.0/requirements-azure.txt
state: latest state: latest
virtualenv_python: python3 virtualenv_python: python3

@ -26,7 +26,7 @@
end_port: "{{ item.end_port }}" end_port: "{{ item.end_port }}"
cidr: "{{ item.range }}" cidr: "{{ item.range }}"
with_items: with_items:
- { proto: tcp, start_port: '{{ ssh_port }}', end_port: '{{ ssh_port }}', range: 0.0.0.0/0 } - { proto: tcp, start_port: "{{ ssh_port }}", end_port: "{{ ssh_port }}", range: 0.0.0.0/0 }
- { proto: udp, start_port: 4500, end_port: 4500, range: 0.0.0.0/0 } - { proto: udp, start_port: 4500, end_port: 4500, range: 0.0.0.0/0 }
- { proto: udp, start_port: 500, end_port: 500, range: 0.0.0.0/0 } - { proto: udp, start_port: 500, end_port: 500, range: 0.0.0.0/0 }
- { proto: udp, start_port: "{{ wireguard_port }}", end_port: "{{ wireguard_port }}", range: 0.0.0.0/0 } - { proto: udp, start_port: "{{ wireguard_port }}", end_port: "{{ wireguard_port }}", range: 0.0.0.0/0 }

@ -1,65 +1,65 @@
--- ---
- block: - block:
- pause: - pause:
prompt: | prompt: |
Enter the API key (https://trailofbits.github.io/algo/cloud-cloudstack.html): Enter the API key (https://trailofbits.github.io/algo/cloud-cloudstack.html):
echo: false echo: false
register: _cs_key register: _cs_key
when: when:
- cs_key is undefined - cs_key is undefined
- lookup('env','CLOUDSTACK_KEY')|length <= 0 - lookup('env','CLOUDSTACK_KEY')|length <= 0
- pause: - pause:
prompt: | prompt: |
Enter the API ssecret (https://trailofbits.github.io/algo/cloud-cloudstack.html): Enter the API ssecret (https://trailofbits.github.io/algo/cloud-cloudstack.html):
echo: false echo: false
register: _cs_secret register: _cs_secret
when: when:
- cs_secret is undefined - cs_secret is undefined
- lookup('env','CLOUDSTACK_SECRET')|length <= 0 - lookup('env','CLOUDSTACK_SECRET')|length <= 0
- pause: - pause:
prompt: | prompt: |
Enter the API endpoint (https://trailofbits.github.io/algo/cloud-cloudstack.html) Enter the API endpoint (https://trailofbits.github.io/algo/cloud-cloudstack.html)
[https://api.exoscale.com/compute] [https://api.exoscale.com/compute]
register: _cs_url register: _cs_url
when: when:
- cs_url is undefined - cs_url is undefined
- lookup('env', 'CLOUDSTACK_ENDPOINT') | length <= 0 - lookup('env', 'CLOUDSTACK_ENDPOINT') | length <= 0
- set_fact: - set_fact:
algo_cs_key: "{{ cs_key | default(_cs_key.user_input|default(None)) | default(lookup('env', 'CLOUDSTACK_KEY'), true) }}" algo_cs_key: "{{ cs_key | default(_cs_key.user_input|default(None)) | default(lookup('env', 'CLOUDSTACK_KEY'), true) }}"
algo_cs_token: "{{ cs_secret | default(_cs_secret.user_input|default(None)) | default(lookup('env', 'CLOUDSTACK_SECRET'), true) }}" algo_cs_token: "{{ cs_secret | default(_cs_secret.user_input|default(None)) | default(lookup('env', 'CLOUDSTACK_SECRET'), true) }}"
algo_cs_url: "{{ cs_url | default(_cs_url.user_input|default(None)) | default(lookup('env', 'CLOUDSTACK_ENDPOINT'), true) | default('https://api.exoscale.com/compute', true) }}" algo_cs_url: "{{ cs_url | default(_cs_url.user_input|default(None)) | default(lookup('env', 'CLOUDSTACK_ENDPOINT'), true) | default('https://api.exoscale.com/compute',\
\ true) }}"
- name: Get zones on cloud - name: Get zones on cloud
cs_zone_info: cs_zone_info:
register: _cs_zones register: _cs_zones
environment: environment:
CLOUDSTACK_KEY: "{{ algo_cs_key }}" CLOUDSTACK_KEY: "{{ algo_cs_key }}"
CLOUDSTACK_SECRET: "{{ algo_cs_token }}" CLOUDSTACK_SECRET: "{{ algo_cs_token }}"
CLOUDSTACK_ENDPOINT: "{{ algo_cs_url }}" CLOUDSTACK_ENDPOINT: "{{ algo_cs_url }}"
- name: Extract zones from output - name: Extract zones from output
set_fact: set_fact:
cs_zones: "{{ _cs_zones['zones'] | sort(attribute='name') }}" cs_zones: "{{ _cs_zones['zones'] | sort(attribute='name') }}"
- name: Set the default zone - name: Set the default zone
set_fact: set_fact:
default_zone: >- default_zone: >-
{% for z in cs_zones %}
{%- if z['name'] == "ch-gva-2" %}{{ loop.index }}{% endif %}
{%- endfor %}
- pause:
prompt: |
What zone should the server be located in?
{% for z in cs_zones %} {% for z in cs_zones %}
{{ loop.index }}. {{ z['name'] }} {%- if z['name'] == "ch-gva-2" %}{{ loop.index }}{% endif %}
{% endfor %} {%- endfor %}
Enter the number of your desired zone - pause:
[{{ default_zone }}] prompt: |
register: _algo_region What zone should the server be located in?
when: region is undefined {% for z in cs_zones %}
{{ loop.index }}. {{ z['name'] }}
{% endfor %}
Enter the number of your desired zone
[{{ default_zone }}]
register: _algo_region
when: region is undefined

@ -2,14 +2,14 @@
- name: Include prompts - name: Include prompts
import_tasks: prompts.yml import_tasks: prompts.yml
- name: "Upload the SSH key" - name: Upload the SSH key
digital_ocean_sshkey: digital_ocean_sshkey:
oauth_token: "{{ algo_do_token }}" oauth_token: "{{ algo_do_token }}"
name: "{{ SSH_keys.comment }}" name: "{{ SSH_keys.comment }}"
ssh_pub_key: "{{ lookup('file', '{{ SSH_keys.public }}') }}" ssh_pub_key: "{{ lookup('file', '{{ SSH_keys.public }}') }}"
register: do_ssh_key register: do_ssh_key
- name: "Creating a droplet..." - name: Creating a droplet...
digital_ocean_droplet: digital_ocean_droplet:
state: present state: present
name: "{{ algo_server_name }}" name: "{{ algo_server_name }}"
@ -31,16 +31,16 @@
droplet: "{{ digital_ocean_droplet.data.droplet | default(digital_ocean_droplet.data) }}" droplet: "{{ digital_ocean_droplet.data.droplet | default(digital_ocean_droplet.data) }}"
- block: - block:
- name: "Create a Floating IP" - name: Create a Floating IP
digital_ocean_floating_ip: digital_ocean_floating_ip:
state: present state: present
oauth_token: "{{ algo_do_token }}" oauth_token: "{{ algo_do_token }}"
droplet_id: "{{ droplet.id }}" droplet_id: "{{ droplet.id }}"
register: digital_ocean_floating_ip register: digital_ocean_floating_ip
- name: Set the static ip as a fact - name: Set the static ip as a fact
set_fact: set_fact:
cloud_alternative_ingress_ip: "{{ digital_ocean_floating_ip.data.floating_ip.ip }}" cloud_alternative_ingress_ip: "{{ digital_ocean_floating_ip.data.floating_ip.ip }}"
when: alternative_ingress_ip when: alternative_ingress_ip
- set_fact: - set_fact:

@ -18,8 +18,8 @@
method: GET method: GET
status_code: 200 status_code: 200
headers: headers:
Content-Type: "application/json" Content-Type: application/json
Authorization: "Bearer {{ algo_do_token }}" Authorization: Bearer {{ algo_do_token }}
register: _do_regions register: _do_regions
- name: Set facts about the regions - name: Set facts about the regions

@ -4,7 +4,7 @@
aws_access_key: "{{ access_key }}" aws_access_key: "{{ access_key }}"
aws_secret_key: "{{ secret_key }}" aws_secret_key: "{{ secret_key }}"
stack_name: "{{ stack_name }}" stack_name: "{{ stack_name }}"
state: "present" state: present
region: "{{ algo_region }}" region: "{{ algo_region }}"
template: roles/cloud-ec2/files/stack.yaml template: roles/cloud-ec2/files/stack.yaml
template_parameters: template_parameters:

@ -13,7 +13,7 @@
region: "{{ algo_region }}" region: "{{ algo_region }}"
filters: filters:
architecture: "{{ cloud_providers.ec2.image.arch }}" architecture: "{{ cloud_providers.ec2.image.arch }}"
name: "ubuntu/images/hvm-ssd/{{ cloud_providers.ec2.image.name }}-*64-server-*" name: ubuntu/images/hvm-ssd/{{ cloud_providers.ec2.image.name }}-*64-server-*
register: ami_search register: ami_search
- name: Set the ami id as a fact - name: Set the ami id as a fact

@ -6,8 +6,8 @@
echo: false echo: false
register: _aws_access_key register: _aws_access_key
when: when:
- aws_access_key is undefined - aws_access_key is undefined
- lookup('env','AWS_ACCESS_KEY_ID')|length <= 0 - lookup('env','AWS_ACCESS_KEY_ID')|length <= 0
- pause: - pause:
prompt: | prompt: |
@ -23,35 +23,35 @@
secret_key: "{{ aws_secret_key | default(_aws_secret_key.user_input|default(None)) | default(lookup('env','AWS_SECRET_ACCESS_KEY'), true) }}" secret_key: "{{ aws_secret_key | default(_aws_secret_key.user_input|default(None)) | default(lookup('env','AWS_SECRET_ACCESS_KEY'), true) }}"
- block: - block:
- name: Get regions - name: Get regions
aws_region_info: aws_region_info:
aws_access_key: "{{ access_key }}" aws_access_key: "{{ access_key }}"
aws_secret_key: "{{ secret_key }}" aws_secret_key: "{{ secret_key }}"
region: us-east-1 region: us-east-1
register: _aws_regions register: _aws_regions
- name: Set facts about the regions - name: Set facts about the regions
set_fact: set_fact:
aws_regions: "{{ _aws_regions.regions | sort(attribute='region_name') }}" aws_regions: "{{ _aws_regions.regions | sort(attribute='region_name') }}"
- name: Set the default region - name: Set the default region
set_fact: set_fact:
default_region: >- default_region: >-
{% for r in aws_regions %}
{%- if r['region_name'] == "us-east-1" %}{{ loop.index }}{% endif %}
{%- endfor %}
- pause:
prompt: |
What region should the server be located in?
(https://docs.aws.amazon.com/general/latest/gr/rande.html#ec2_region)
{% for r in aws_regions %} {% for r in aws_regions %}
{{ loop.index }}. {{ r['region_name'] }} {%- if r['region_name'] == "us-east-1" %}{{ loop.index }}{% endif %}
{% endfor %} {%- endfor %}
- pause:
prompt: |
What region should the server be located in?
(https://docs.aws.amazon.com/general/latest/gr/rande.html#ec2_region)
{% for r in aws_regions %}
{{ loop.index }}. {{ r['region_name'] }}
{% endfor %}
Enter the number of your desired region Enter the number of your desired region
[{{ default_region }}] [{{ default_region }}]
register: _algo_region register: _algo_region
when: region is undefined when: region is undefined
- name: Set algo_region and stack_name facts - name: Set algo_region and stack_name facts
@ -63,26 +63,26 @@
stack_name: "{{ algo_server_name | replace('.', '-') }}" stack_name: "{{ algo_server_name | replace('.', '-') }}"
- block: - block:
- name: Get existing available Elastic IPs - name: Get existing available Elastic IPs
ec2_eip_info: ec2_eip_info:
aws_access_key: "{{ access_key }}" aws_access_key: "{{ access_key }}"
aws_secret_key: "{{ secret_key }}" aws_secret_key: "{{ secret_key }}"
region: "{{ algo_region }}" region: "{{ algo_region }}"
register: raw_eip_addresses register: raw_eip_addresses
- set_fact: - set_fact:
available_eip_addresses: "{{ raw_eip_addresses.addresses | selectattr('association_id', 'undefined') | list }}" available_eip_addresses: "{{ raw_eip_addresses.addresses | selectattr('association_id', 'undefined') | list }}"
- pause: - pause:
prompt: >- prompt: >-
What Elastic IP would you like to use? What Elastic IP would you like to use?
{% for eip in available_eip_addresses %} {% for eip in available_eip_addresses %}
{{ loop.index }}. {{ eip['public_ip'] }} {{ loop.index }}. {{ eip['public_ip'] }}
{% endfor %} {% endfor %}
Enter the number of your desired Elastic IP Enter the number of your desired Elastic IP
register: _use_existing_eip register: _use_existing_eip
- set_fact: - set_fact:
existing_eip: "{{ available_eip_addresses[_use_existing_eip.user_input | int -1 ]['allocation_id'] }}" existing_eip: "{{ available_eip_addresses[_use_existing_eip.user_input | int -1 ]['allocation_id'] }}"
when: cloud_providers.ec2.use_existing_eip when: cloud_providers.ec2.use_existing_eip

@ -27,27 +27,27 @@
allowed: allowed:
- ip_protocol: udp - ip_protocol: udp
ports: ports:
- '500' - "500"
- '4500' - "4500"
- '{{ wireguard_port|string }}' - "{{ wireguard_port|string }}"
- ip_protocol: tcp - ip_protocol: tcp
ports: ports:
- '{{ ssh_port }}' - "{{ ssh_port }}"
- ip_protocol: icmp - ip_protocol: icmp
- block: - block:
- name: External IP allocated - name: External IP allocated
gcp_compute_address: gcp_compute_address:
auth_kind: serviceaccount auth_kind: serviceaccount
service_account_file: "{{ credentials_file_path }}" service_account_file: "{{ credentials_file_path }}"
project: "{{ project_id }}" project: "{{ project_id }}"
name: "{{ algo_server_name }}" name: "{{ algo_server_name }}"
region: "{{ algo_region }}" region: "{{ algo_region }}"
register: gcp_compute_address register: gcp_compute_address
- name: Set External IP as a fact - name: Set External IP as a fact
set_fact: set_fact:
external_ip: "{{ gcp_compute_address.address }}" external_ip: "{{ gcp_compute_address.address }}"
when: cloud_providers.gce.external_static_ip when: cloud_providers.gce.external_static_ip
- name: Instance created - name: Instance created
@ -62,9 +62,9 @@
- auto_delete: true - auto_delete: true
boot: true boot: true
initialize_params: initialize_params:
source_image: "projects/ubuntu-os-cloud/global/images/family/{{ cloud_providers.gce.image }}" source_image: projects/ubuntu-os-cloud/global/images/family/{{ cloud_providers.gce.image }}
metadata: metadata:
ssh-keys: "algo:{{ ssh_public_key_lookup }}" ssh-keys: algo:{{ ssh_public_key_lookup }}
user-data: "{{ lookup('template', 'files/cloud-init/base.yml') }}" user-data: "{{ lookup('template', 'files/cloud-init/base.yml') }}"
network_interfaces: network_interfaces:
- network: "{{ gcp_compute_network }}" - network: "{{ gcp_compute_network }}"
@ -74,7 +74,7 @@
type: ONE_TO_ONE_NAT type: ONE_TO_ONE_NAT
tags: tags:
items: items:
- "environment-algo" - environment-algo
register: gcp_compute_instance register: gcp_compute_instance
- set_fact: - set_fact:

@ -9,7 +9,8 @@
- lookup('env','GCE_CREDENTIALS_FILE_PATH')|length <= 0 - lookup('env','GCE_CREDENTIALS_FILE_PATH')|length <= 0
- set_fact: - set_fact:
credentials_file_path: "{{ gce_credentials_file | default(_gce_credentials_file.user_input|default(None)) | default(lookup('env','GCE_CREDENTIALS_FILE_PATH'), true) }}" credentials_file_path: "{{ gce_credentials_file | default(_gce_credentials_file.user_input|default(None)) | default(lookup('env','GCE_CREDENTIALS_FILE_PATH'),\
\ true) }}"
ssh_public_key_lookup: "{{ lookup('file', '{{ SSH_keys.public }}') }}" ssh_public_key_lookup: "{{ lookup('file', '{{ SSH_keys.public }}') }}"
- set_fact: - set_fact:
@ -20,40 +21,40 @@
project_id: "{{ credentials_file_lookup.project_id | default(lookup('env','GCE_PROJECT')) }}" project_id: "{{ credentials_file_lookup.project_id | default(lookup('env','GCE_PROJECT')) }}"
- block: - block:
- name: Get regions - name: Get regions
gcp_compute_location_info: gcp_compute_location_info:
auth_kind: serviceaccount auth_kind: serviceaccount
service_account_file: "{{ credentials_file_path }}" service_account_file: "{{ credentials_file_path }}"
project: "{{ project_id }}" project: "{{ project_id }}"
scope: regions scope: regions
filters: status=UP filters: status=UP
register: gcp_compute_regions_info register: gcp_compute_regions_info
- name: Set facts about the regions - name: Set facts about the regions
set_fact: set_fact:
gce_regions: >- gce_regions: >-
[{%- for region in gcp_compute_regions_info.resources | sort(attribute='name') -%} [{%- for region in gcp_compute_regions_info.resources | sort(attribute='name') -%}
'{{ region.name }}'{% if not loop.last %},{% endif %} '{{ region.name }}'{% if not loop.last %},{% endif %}
{%- endfor -%}] {%- endfor -%}]
- name: Set facts about the default region - name: Set facts about the default region
set_fact: set_fact:
default_region: >- default_region: >-
{% for region in gce_regions %} {% for region in gce_regions %}
{%- if region == "us-east1" %}{{ loop.index }}{% endif %} {%- if region == "us-east1" %}{{ loop.index }}{% endif %}
{%- endfor %} {%- endfor %}
- pause: - pause:
prompt: | prompt: |
What region should the server be located in? What region should the server be located in?
(https://cloud.google.com/compute/docs/regions-zones/#locations) (https://cloud.google.com/compute/docs/regions-zones/#locations)
{% for r in gce_regions %} {% for r in gce_regions %}
{{ loop.index }}. {{ r }} {{ loop.index }}. {{ r }}
{% endfor %} {% endfor %}
Enter the number of your desired region Enter the number of your desired region
[{{ default_region }}] [{{ default_region }}]
register: _gce_region register: _gce_region
when: region is undefined when: region is undefined
- name: Set region as a fact - name: Set region as a fact
@ -70,8 +71,8 @@
project: "{{ project_id }}" project: "{{ project_id }}"
scope: zones scope: zones
filters: filters:
- "name={{ algo_region }}-*" - name={{ algo_region }}-*
- "status=UP" - status=UP
register: gcp_compute_zone_info register: gcp_compute_zone_info
- name: Set random available zone as a fact - name: Set random available zone as a fact

@ -7,7 +7,7 @@
- name: Create an ssh key - name: Create an ssh key
hcloud_ssh_key: hcloud_ssh_key:
name: "algo-{{ 999999 | random(seed=lookup('file', SSH_keys.public)) }}" name: algo-{{ 999999 | random(seed=lookup('file', SSH_keys.public)) }}
public_key: "{{ lookup('file', SSH_keys.public) }}" public_key: "{{ lookup('file', SSH_keys.public) }}"
state: present state: present
api_token: "{{ algo_hcloud_token }}" api_token: "{{ algo_hcloud_token }}"

@ -4,7 +4,7 @@
aws_access_key: "{{ access_key }}" aws_access_key: "{{ access_key }}"
aws_secret_key: "{{ secret_key }}" aws_secret_key: "{{ secret_key }}"
stack_name: "{{ stack_name }}" stack_name: "{{ stack_name }}"
state: "present" state: present
region: "{{ algo_region }}" region: "{{ algo_region }}"
template: roles/cloud-lightsail/files/stack.yaml template: roles/cloud-lightsail/files/stack.yaml
template_parameters: template_parameters:

@ -6,8 +6,8 @@
echo: false echo: false
register: _aws_access_key register: _aws_access_key
when: when:
- aws_access_key is undefined - aws_access_key is undefined
- lookup('env','AWS_ACCESS_KEY_ID')|length <= 0 - lookup('env','AWS_ACCESS_KEY_ID')|length <= 0
- pause: - pause:
prompt: | prompt: |
@ -23,35 +23,35 @@
secret_key: "{{ aws_secret_key | default(_aws_secret_key.user_input|default(None)) | default(lookup('env','AWS_SECRET_ACCESS_KEY'), true) }}" secret_key: "{{ aws_secret_key | default(_aws_secret_key.user_input|default(None)) | default(lookup('env','AWS_SECRET_ACCESS_KEY'), true) }}"
- block: - block:
- name: Get regions - name: Get regions
lightsail_region_facts: lightsail_region_facts:
aws_access_key: "{{ access_key }}" aws_access_key: "{{ access_key }}"
aws_secret_key: "{{ secret_key }}" aws_secret_key: "{{ secret_key }}"
region: us-east-1 region: us-east-1
register: _lightsail_regions register: _lightsail_regions
- name: Set facts about the regions - name: Set facts about the regions
set_fact: set_fact:
lightsail_regions: "{{ _lightsail_regions.data.regions | sort(attribute='name') }}" lightsail_regions: "{{ _lightsail_regions.data.regions | sort(attribute='name') }}"
- name: Set the default region - name: Set the default region
set_fact: set_fact:
default_region: >- default_region: >-
{% for r in lightsail_regions %}
{%- if r['name'] == "us-east-1" %}{{ loop.index }}{% endif %}
{%- endfor %}
- pause:
prompt: |
What region should the server be located in?
(https://aws.amazon.com/about-aws/global-infrastructure/regional-product-services/)
{% for r in lightsail_regions %} {% for r in lightsail_regions %}
{{ (loop.index|string + '.').ljust(3) }} {{ r['name'].ljust(20) }} {{ r['displayName'] }} {%- if r['name'] == "us-east-1" %}{{ loop.index }}{% endif %}
{% endfor %} {%- endfor %}
Enter the number of your desired region - pause:
[{{ default_region }}] prompt: |
register: _algo_region What region should the server be located in?
(https://aws.amazon.com/about-aws/global-infrastructure/regional-product-services/)
{% for r in lightsail_regions %}
{{ (loop.index|string + '.').ljust(3) }} {{ r['name'].ljust(20) }} {{ r['displayName'] }}
{% endfor %}
Enter the number of your desired region
[{{ default_region }}]
register: _algo_region
when: region is undefined when: region is undefined
- set_fact: - set_fact:

@ -26,7 +26,7 @@
- name: Update the stackscript - name: Update the stackscript
uri: uri:
url: "https://api.linode.com/v4/linode/stackscripts/{{ _linode_stackscript.stackscript.id }}" url: https://api.linode.com/v4/linode/stackscripts/{{ _linode_stackscript.stackscript.id }}
method: PUT method: PUT
body_format: json body_format: json
body: body:
@ -34,10 +34,10 @@
{{ stackscript }} {{ stackscript }}
headers: headers:
Content-Type: application/json Content-Type: application/json
Authorization: "Bearer {{ algo_linode_token }}" Authorization: Bearer {{ algo_linode_token }}
when: (_linode_stackscript.stackscript.script | hash('md5')) != (stackscript | hash('md5')) when: (_linode_stackscript.stackscript.script | hash('md5')) != (stackscript | hash('md5'))
- name: "Creating an instance..." - name: Creating an instance...
linode_v4: linode_v4:
access_token: "{{ algo_linode_token }}" access_token: "{{ algo_linode_token }}"
label: "{{ algo_server_name }}" label: "{{ algo_server_name }}"

@ -22,7 +22,7 @@
port_range_max: "{{ item.port_max }}" port_range_max: "{{ item.port_max }}"
remote_ip_prefix: "{{ item.range }}" remote_ip_prefix: "{{ item.range }}"
with_items: with_items:
- { proto: tcp, port_min: '{{ ssh_port }}', port_max: '{{ ssh_port }}', range: 0.0.0.0/0 } - { proto: tcp, port_min: "{{ ssh_port }}", port_max: "{{ ssh_port }}", range: 0.0.0.0/0 }
- { proto: icmp, port_min: -1, port_max: -1, range: 0.0.0.0/0 } - { proto: icmp, port_min: -1, port_max: -1, range: 0.0.0.0/0 }
- { proto: udp, port_min: 4500, port_max: 4500, range: 0.0.0.0/0 } - { proto: udp, port_min: 4500, port_max: 4500, range: 0.0.0.0/0 }
- { proto: udp, port_min: 500, port_max: 500, range: 0.0.0.0/0 } - { proto: udp, port_min: 500, port_max: 500, range: 0.0.0.0/0 }

@ -1,73 +1,74 @@
---
- name: Include prompts - name: Include prompts
import_tasks: prompts.yml import_tasks: prompts.yml
- block: - block:
- name: Gather Scaleway organizations facts - name: Gather Scaleway organizations facts
scaleway_organization_info: scaleway_organization_info:
register: scaleway_org register: scaleway_org
- name: Get images - name: Get images
scaleway_image_info: scaleway_image_info:
region: "{{ algo_region }}" region: "{{ algo_region }}"
register: scaleway_image register: scaleway_image
- name: Set cloud specific facts - name: Set cloud specific facts
set_fact: set_fact:
organization_id: "{{ scaleway_org.scaleway_organization_info[0]['id'] }}" organization_id: "{{ scaleway_org.scaleway_organization_info[0]['id'] }}"
images: >- images: >-
[{% for i in scaleway_image.scaleway_image_info -%} [{% for i in scaleway_image.scaleway_image_info -%}
{% if i.name == cloud_providers.scaleway.image and {% if i.name == cloud_providers.scaleway.image and
i.arch == cloud_providers.scaleway.arch -%} i.arch == cloud_providers.scaleway.arch -%}
'{{ i.id }}'{% if not loop.last %},{% endif %} '{{ i.id }}'{% if not loop.last %},{% endif %}
{%- endif -%} {%- endif -%}
{%- endfor -%}] {%- endfor -%}]
- name: Create a server - name: Create a server
scaleway_compute: scaleway_compute:
name: "{{ algo_server_name }}" name: "{{ algo_server_name }}"
enable_ipv6: true enable_ipv6: true
public_ip: dynamic public_ip: dynamic
boot_type: local boot_type: local
state: present state: present
image: "{{ images[0] }}" image: "{{ images[0] }}"
organization: "{{ organization_id }}" organization: "{{ organization_id }}"
region: "{{ algo_region }}" region: "{{ algo_region }}"
commercial_type: "{{ cloud_providers.scaleway.size }}" commercial_type: "{{ cloud_providers.scaleway.size }}"
wait: true wait: true
tags: tags:
- Environment:Algo - Environment:Algo
- AUTHORIZED_KEY={{ lookup('file', SSH_keys.public)|regex_replace(' ', '_') }} - AUTHORIZED_KEY={{ lookup('file', SSH_keys.public)|regex_replace(' ', '_') }}
register: scaleway_compute register: scaleway_compute
- name: Patch the cloud-init - name: Patch the cloud-init
uri: uri:
url: "https://cp-{{ algo_region }}.scaleway.com/servers/{{ scaleway_compute.msg.id }}/user_data/cloud-init" url: https://cp-{{ algo_region }}.scaleway.com/servers/{{ scaleway_compute.msg.id }}/user_data/cloud-init
method: PATCH method: PATCH
body: "{{ lookup('template', 'files/cloud-init/base.yml') }}" body: "{{ lookup('template', 'files/cloud-init/base.yml') }}"
status_code: 204 status_code: 204
headers: headers:
Content-Type: "text/plain" Content-Type: text/plain
X-Auth-Token: "{{ algo_scaleway_token }}" X-Auth-Token: "{{ algo_scaleway_token }}"
- name: Start the server - name: Start the server
scaleway_compute: scaleway_compute:
name: "{{ algo_server_name }}" name: "{{ algo_server_name }}"
enable_ipv6: true enable_ipv6: true
public_ip: dynamic public_ip: dynamic
boot_type: local boot_type: local
state: running state: running
image: "{{ images[0] }}" image: "{{ images[0] }}"
organization: "{{ organization_id }}" organization: "{{ organization_id }}"
region: "{{ algo_region }}" region: "{{ algo_region }}"
commercial_type: "{{ cloud_providers.scaleway.size }}" commercial_type: "{{ cloud_providers.scaleway.size }}"
wait: true wait: true
tags: tags:
- Environment:Algo - Environment:Algo
- AUTHORIZED_KEY={{ lookup('file', SSH_keys.public)|regex_replace(' ', '_') }} - AUTHORIZED_KEY={{ lookup('file', SSH_keys.public)|regex_replace(' ', '_') }}
register: algo_instance register: algo_instance
until: algo_instance.msg.public_ip until: algo_instance.msg.public_ip
retries: 3 retries: 3
delay: 3 delay: 3
environment: environment:
SCW_TOKEN: "{{ algo_scaleway_token }}" SCW_TOKEN: "{{ algo_scaleway_token }}"

@ -3,54 +3,54 @@
import_tasks: prompts.yml import_tasks: prompts.yml
- block: - block:
- name: Creating a firewall group - name: Creating a firewall group
vultr_firewall_group: vultr_firewall_group:
name: "{{ algo_server_name }}" name: "{{ algo_server_name }}"
- name: Creating firewall rules - name: Creating firewall rules
vultr_firewall_rule: vultr_firewall_rule:
group: "{{ algo_server_name }}" group: "{{ algo_server_name }}"
protocol: "{{ item.protocol }}" protocol: "{{ item.protocol }}"
port: "{{ item.port }}" port: "{{ item.port }}"
ip_version: "{{ item.ip }}" ip_version: "{{ item.ip }}"
cidr: "{{ item.cidr }}" cidr: "{{ item.cidr }}"
with_items: with_items:
- { protocol: tcp, port: "{{ ssh_port }}", ip: v4, cidr: "0.0.0.0/0" } - { protocol: tcp, port: "{{ ssh_port }}", ip: v4, cidr: 0.0.0.0/0 }
- { protocol: tcp, port: "{{ ssh_port }}", ip: v6, cidr: "::/0" } - { protocol: tcp, port: "{{ ssh_port }}", ip: v6, cidr: "::/0" }
- { protocol: udp, port: 500, ip: v4, cidr: "0.0.0.0/0" } - { protocol: udp, port: 500, ip: v4, cidr: 0.0.0.0/0 }
- { protocol: udp, port: 500, ip: v6, cidr: "::/0" } - { protocol: udp, port: 500, ip: v6, cidr: "::/0" }
- { protocol: udp, port: 4500, ip: v4, cidr: "0.0.0.0/0" } - { protocol: udp, port: 4500, ip: v4, cidr: 0.0.0.0/0 }
- { protocol: udp, port: 4500, ip: v6, cidr: "::/0" } - { protocol: udp, port: 4500, ip: v6, cidr: "::/0" }
- { protocol: udp, port: "{{ wireguard_port }}", ip: v4, cidr: "0.0.0.0/0" } - { protocol: udp, port: "{{ wireguard_port }}", ip: v4, cidr: 0.0.0.0/0 }
- { protocol: udp, port: "{{ wireguard_port }}", ip: v6, cidr: "::/0" } - { protocol: udp, port: "{{ wireguard_port }}", ip: v6, cidr: "::/0" }
- name: Upload the startup script - name: Upload the startup script
vultr_startup_script: vultr_startup_script:
name: algo-startup name: algo-startup
script: | script: |
{{ lookup('template', 'files/cloud-init/base.yml') }} {{ lookup('template', 'files/cloud-init/base.yml') }}
- name: Creating a server - name: Creating a server
vultr_server: vultr_server:
name: "{{ algo_server_name }}" name: "{{ algo_server_name }}"
startup_script: algo-startup startup_script: algo-startup
hostname: "{{ algo_server_name }}" hostname: "{{ algo_server_name }}"
os: "{{ cloud_providers.vultr.os }}" os: "{{ cloud_providers.vultr.os }}"
plan: "{{ cloud_providers.vultr.size }}" plan: "{{ cloud_providers.vultr.size }}"
region: "{{ algo_vultr_region }}" region: "{{ algo_vultr_region }}"
firewall_group: "{{ algo_server_name }}" firewall_group: "{{ algo_server_name }}"
state: started state: started
tag: Environment:Algo tag: Environment:Algo
ipv6_enabled: true ipv6_enabled: true
auto_backup_enabled: false auto_backup_enabled: false
notify_activate: false notify_activate: false
register: vultr_server register: vultr_server
- set_fact: - set_fact:
cloud_instance_ip: "{{ vultr_server.vultr_server.v4_main_ip }}" cloud_instance_ip: "{{ vultr_server.vultr_server.v4_main_ip }}"
ansible_ssh_user: algo ansible_ssh_user: algo
ansible_ssh_port: "{{ ssh_port }}" ansible_ssh_port: "{{ ssh_port }}"
cloudinit: true cloudinit: true
environment: environment:
VULTR_API_CONFIG: "{{ algo_vultr_config }}" VULTR_API_CONFIG: "{{ algo_vultr_config }}"

@ -1,3 +1,4 @@
---
- name: restart rsyslog - name: restart rsyslog
service: name=rsyslog state=restarted service: name=rsyslog state=restarted

@ -13,13 +13,12 @@
- name: Gather facts - name: Gather facts
setup: setup:
- name: Gather additional facts - name: Gather additional facts
import_tasks: facts.yml import_tasks: facts.yml
- name: Set OS specific facts - name: Set OS specific facts
set_fact: set_fact:
config_prefix: "/usr/local/" config_prefix: /usr/local/
strongswan_shell: /usr/sbin/nologin strongswan_shell: /usr/sbin/nologin
strongswan_home: /var/empty strongswan_home: /var/empty
root_group: wheel root_group: wheel
@ -50,7 +49,7 @@
- name: Loopback included into the rc config - name: Loopback included into the rc config
blockinfile: blockinfile:
dest: /etc/rc.conf dest: /etc/rc.conf
create: yes create: true
block: | block: |
cloned_interfaces="lo100" cloned_interfaces="lo100"
ifconfig_lo100="inet {{ local_service_ip }} netmask 255.255.255.255" ifconfig_lo100="inet {{ local_service_ip }} netmask 255.255.255.255"

@ -1,5 +1,4 @@
--- ---
- name: Iptables configured - name: Iptables configured
template: template:
src: "{{ item.src }}" src: "{{ item.src }}"

@ -1,7 +1,6 @@
--- ---
- name: Gather facts - name: Gather facts
setup: setup:
- name: Cloud only tasks - name: Cloud only tasks
block: block:
- name: Install software updates - name: Install software updates
@ -42,8 +41,8 @@
- name: Disable MOTD on login and SSHD - name: Disable MOTD on login and SSHD
replace: dest="{{ item.file }}" regexp="{{ item.regexp }}" replace="{{ item.line }}" replace: dest="{{ item.file }}" regexp="{{ item.regexp }}" replace="{{ item.line }}"
with_items: with_items:
- { regexp: '^session.*optional.*pam_motd.so.*', line: '# MOTD DISABLED', file: '/etc/pam.d/login' } - { regexp: ^session.*optional.*pam_motd.so.*, line: "# MOTD DISABLED", file: /etc/pam.d/login }
- { regexp: '^session.*optional.*pam_motd.so.*', line: '# MOTD DISABLED', file: '/etc/pam.d/sshd' } - { regexp: ^session.*optional.*pam_motd.so.*, line: "# MOTD DISABLED", file: /etc/pam.d/sshd }
- name: Ensure fallback resolvers are set - name: Ensure fallback resolvers are set
ini_file: ini_file:
@ -75,7 +74,7 @@
- name: Check apparmor support - name: Check apparmor support
command: apparmor_status command: apparmor_status
ignore_errors: yes ignore_errors: true
changed_when: false changed_when: false
register: apparmor_status register: apparmor_status
@ -117,7 +116,7 @@
apt: apt:
name: name:
- linux-headers-generic - linux-headers-generic
- "linux-headers-{{ ansible_kernel }}" - linux-headers-{{ ansible_kernel }}
state: present state: present
when: install_headers | bool when: install_headers | bool

@ -6,4 +6,4 @@
- name: Enable mac_portacl - name: Enable mac_portacl
lineinfile: lineinfile:
path: /etc/rc.conf path: /etc/rc.conf
line: 'dnscrypt_proxy_mac_portacl_enable="YES"' line: dnscrypt_proxy_mac_portacl_enable="YES"

@ -1,22 +1,22 @@
--- ---
- block: - block:
- name: Add the repository - name: Add the repository
apt_repository: apt_repository:
state: present state: present
codename: "{{ ansible_distribution_release }}" codename: "{{ ansible_distribution_release }}"
repo: ppa:shevchuk/dnscrypt-proxy repo: ppa:shevchuk/dnscrypt-proxy
register: result register: result
until: result is succeeded until: result is succeeded
retries: 10 retries: 10
delay: 3 delay: 3
- name: Configure unattended-upgrades - name: Configure unattended-upgrades
copy: copy:
src: 50-dnscrypt-proxy-unattended-upgrades src: 50-dnscrypt-proxy-unattended-upgrades
dest: /etc/apt/apt.conf.d/50-dnscrypt-proxy-unattended-upgrades dest: /etc/apt/apt.conf.d/50-dnscrypt-proxy-unattended-upgrades
owner: root owner: root
group: root group: root
mode: 0644 mode: 0644
when: ansible_facts['distribution_version'] is version('20.04', '<') when: ansible_facts['distribution_version'] is version('20.04', '<')
- name: Install dnscrypt-proxy - name: Install dnscrypt-proxy
@ -26,18 +26,18 @@
update_cache: true update_cache: true
- block: - block:
- name: Ubuntu | Configure AppArmor policy for dnscrypt-proxy - name: Ubuntu | Configure AppArmor policy for dnscrypt-proxy
copy: copy:
src: apparmor.profile.dnscrypt-proxy src: apparmor.profile.dnscrypt-proxy
dest: /etc/apparmor.d/usr.bin.dnscrypt-proxy dest: /etc/apparmor.d/usr.bin.dnscrypt-proxy
owner: root owner: root
group: root group: root
mode: 0600 mode: 0600
notify: restart dnscrypt-proxy notify: restart dnscrypt-proxy
- name: Ubuntu | Enforce the dnscrypt-proxy AppArmor policy - name: Ubuntu | Enforce the dnscrypt-proxy AppArmor policy
command: aa-enforce usr.bin.dnscrypt-proxy command: aa-enforce usr.bin.dnscrypt-proxy
changed_when: false changed_when: false
tags: apparmor tags: apparmor
when: apparmor_enabled|default(false)|bool when: apparmor_enabled|default(false)|bool
@ -60,4 +60,4 @@
[Service] [Service]
AmbientCapabilities=CAP_NET_BIND_SERVICE AmbientCapabilities=CAP_NET_BIND_SERVICE
notify: notify:
- restart dnscrypt-proxy - restart dnscrypt-proxy

@ -20,25 +20,25 @@
- name: Set the facts - name: Set the facts
set_fact: set_fact:
cloud_instance_ip: >- cloud_instance_ip: >-
{% if server is defined %}{{ server }} {% if server is defined %}{{ server }}
{%- elif _algo_server.user_input %}{{ _algo_server.user_input }} {%- elif _algo_server.user_input %}{{ _algo_server.user_input }}
{%- else %}localhost{% endif %} {%- else %}localhost{% endif %}
- block: - block:
- pause: - pause:
prompt: | prompt: |
What user should we use to login on the server? (note: passwordless login required, or ignore if you're deploying to localhost) What user should we use to login on the server? (note: passwordless login required, or ignore if you're deploying to localhost)
[root] [root]
register: _algo_ssh_user register: _algo_ssh_user
when: ssh_user is undefined when: ssh_user is undefined
- name: Set the facts - name: Set the facts
set_fact: set_fact:
ansible_ssh_user: >- ansible_ssh_user: >-
{% if ssh_user is defined %}{{ ssh_user }} {% if ssh_user is defined %}{{ ssh_user }}
{%- elif _algo_ssh_user.user_input %}{{ _algo_ssh_user.user_input }} {%- elif _algo_ssh_user.user_input %}{{ _algo_ssh_user.user_input }}
{%- else %}root{% endif %} {%- else %}root{% endif %}
when: cloud_instance_ip != "localhost" when: cloud_instance_ip != "localhost"
- pause: - pause:

@ -1,2 +1,2 @@
--- ---
ssh_tunnels_config_path: "configs/{{ IP_subject_alt_name }}/ssh-tunnel/" ssh_tunnels_config_path: configs/{{ IP_subject_alt_name }}/ssh-tunnel/

@ -1,2 +1,3 @@
---
- name: restart ssh - name: restart ssh
service: name="{{ ssh_service_name|default('ssh') }}" state=restarted service: name="{{ ssh_service_name|default('ssh') }}" state=restarted

@ -2,7 +2,7 @@
- name: Ensure that the sshd_config file has desired options - name: Ensure that the sshd_config file has desired options
blockinfile: blockinfile:
dest: /etc/ssh/sshd_config dest: /etc/ssh/sshd_config
marker: '# {mark} ANSIBLE MANAGED BLOCK ssh_tunneling_role' marker: "# {mark} ANSIBLE MANAGED BLOCK ssh_tunneling_role"
block: | block: |
Match Group algo Match Group algo
AllowTcpForwarding local AllowTcpForwarding local
@ -28,90 +28,90 @@
group: "{{ root_group|default('root') }}" group: "{{ root_group|default('root') }}"
- block: - block:
- name: Ensure that the SSH users exist - name: Ensure that the SSH users exist
user: user:
name: "{{ item }}" name: "{{ item }}"
group: algo group: algo
home: '/var/jail/{{ item }}' home: /var/jail/{{ item }}
createhome: yes createhome: true
generate_ssh_key: false generate_ssh_key: false
shell: /bin/false shell: /bin/false
state: present state: present
append: yes append: true
with_items: "{{ users }}" with_items: "{{ users }}"
- block: - block:
- name: Clean up the ssh-tunnel directory - name: Clean up the ssh-tunnel directory
file: file:
dest: "{{ ssh_tunnels_config_path }}" dest: "{{ ssh_tunnels_config_path }}"
state: absent state: absent
when: keys_clean_all|bool when: keys_clean_all|bool
- name: Ensure the config directories exist - name: Ensure the config directories exist
file: file:
dest: "{{ ssh_tunnels_config_path }}" dest: "{{ ssh_tunnels_config_path }}"
state: directory state: directory
recurse: yes recurse: true
mode: '0700' mode: "0700"
- name: Check if the private keys exist - name: Check if the private keys exist
stat: stat:
path: "{{ ssh_tunnels_config_path }}/{{ item }}.pem" path: "{{ ssh_tunnels_config_path }}/{{ item }}.pem"
register: privatekey register: privatekey
with_items: "{{ users }}" with_items: "{{ users }}"
- name: Build ssh private keys - name: Build ssh private keys
openssl_privatekey: openssl_privatekey:
path: "{{ ssh_tunnels_config_path }}/{{ item.item }}.pem" path: "{{ ssh_tunnels_config_path }}/{{ item.item }}.pem"
passphrase: "{{ p12_export_password }}" passphrase: "{{ p12_export_password }}"
cipher: auto cipher: auto
force: false force: false
no_log: "{{ no_log|bool }}" no_log: "{{ no_log|bool }}"
when: not item.stat.exists when: not item.stat.exists
with_items: "{{ privatekey.results }}" with_items: "{{ privatekey.results }}"
register: openssl_privatekey register: openssl_privatekey
- name: Build ssh public keys - name: Build ssh public keys
openssl_publickey: openssl_publickey:
path: "{{ ssh_tunnels_config_path }}/{{ item.item.item }}.pub" path: "{{ ssh_tunnels_config_path }}/{{ item.item.item }}.pub"
privatekey_path: "{{ ssh_tunnels_config_path }}/{{ item.item.item }}.pem" privatekey_path: "{{ ssh_tunnels_config_path }}/{{ item.item.item }}.pem"
privatekey_passphrase: "{{ p12_export_password }}" privatekey_passphrase: "{{ p12_export_password }}"
format: OpenSSH format: OpenSSH
force: true force: true
no_log: "{{ no_log|bool }}" no_log: "{{ no_log|bool }}"
when: item.changed when: item.changed
with_items: "{{ openssl_privatekey.results }}" with_items: "{{ openssl_privatekey.results }}"
- name: Build the client ssh config - name: Build the client ssh config
template: template:
src: ssh_config.j2 src: ssh_config.j2
dest: "{{ ssh_tunnels_config_path }}/{{ item }}.ssh_config" dest: "{{ ssh_tunnels_config_path }}/{{ item }}.ssh_config"
mode: 0700 mode: 0700
with_items: "{{ users }}" with_items: "{{ users }}"
delegate_to: localhost delegate_to: localhost
become: false become: false
- name: The authorized keys file created - name: The authorized keys file created
authorized_key: authorized_key:
user: "{{ item }}" user: "{{ item }}"
key: "{{ lookup('file', ssh_tunnels_config_path + '/' + item + '.pub') }}" key: "{{ lookup('file', ssh_tunnels_config_path + '/' + item + '.pub') }}"
state: present state: present
manage_dir: true manage_dir: true
exclusive: true exclusive: true
with_items: "{{ users }}" with_items: "{{ users }}"
- name: Get active users - name: Get active users
getent: getent:
database: group database: group
key: algo key: algo
split: ':' split: ":"
- name: Delete non-existing users - name: Delete non-existing users
user: user:
name: "{{ item }}" name: "{{ item }}"
state: absent state: absent
remove: yes remove: true
force: yes force: true
when: item not in users when: item not in users
with_items: "{{ getent_group['algo'][2].split(',') }}" with_items: "{{ getent_group['algo'][2].split(',') }}"
tags: update-users tags: update-users

@ -1,5 +1,5 @@
--- ---
ipsec_config_path: "configs/{{ IP_subject_alt_name }}/ipsec/" ipsec_config_path: configs/{{ IP_subject_alt_name }}/ipsec/
ipsec_pki_path: "{{ ipsec_config_path }}/.pki/" ipsec_pki_path: "{{ ipsec_config_path }}/.pki/"
strongswan_shell: /usr/sbin/nologin strongswan_shell: /usr/sbin/nologin
strongswan_home: /var/lib/strongswan strongswan_home: /var/lib/strongswan
@ -7,7 +7,7 @@ strongswan_service: "{{ 'strongswan-starter' if ansible_facts['distribution_vers
BetweenClients_DROP: true BetweenClients_DROP: true
algo_ondemand_cellular: false algo_ondemand_cellular: false
algo_ondemand_wifi: false algo_ondemand_wifi: false
algo_ondemand_wifi_exclude: '_null' algo_ondemand_wifi_exclude: _null
algo_dns_adblocking: false algo_dns_adblocking: false
ipv6_support: false ipv6_support: false
dns_encryption: true dns_encryption: true
@ -16,7 +16,7 @@ subjectAltName_type: "{{ 'DNS' if IP_subject_alt_name|regex_search('[a-z]') else
subjectAltName: >- subjectAltName: >-
{{ subjectAltName_type }}:{{ IP_subject_alt_name }} {{ subjectAltName_type }}:{{ IP_subject_alt_name }}
{%- if ipv6_support -%},IP:{{ ansible_default_ipv6['address'] }}{%- endif -%} {%- if ipv6_support -%},IP:{{ ansible_default_ipv6['address'] }}{%- endif -%}
subjectAltName_USER: "email:{{ item }}@{{ openssl_constraint_random_id }}" subjectAltName_USER: email:{{ item }}@{{ openssl_constraint_random_id }}
nameConstraints: >- nameConstraints: >-
critical,permitted;{{ subjectAltName_type }}:{{ IP_subject_alt_name }}{{- '/255.255.255.255' if subjectAltName_type == 'IP' else '' -}} critical,permitted;{{ subjectAltName_type }}:{{ IP_subject_alt_name }}{{- '/255.255.255.255' if subjectAltName_type == 'IP' else '' -}}
{%- if subjectAltName_type == 'IP' -%} {%- if subjectAltName_type == 'IP' -%}

@ -1,3 +1,4 @@
---
- name: restart strongswan - name: restart strongswan
service: name={{ strongswan_service }} state=restarted service: name={{ strongswan_service }} state=restarted

@ -4,7 +4,7 @@
set -o pipefail set -o pipefail
cat private/{{ item }}.p12 | cat private/{{ item }}.p12 |
base64 base64
register: PayloadContent register: PayloadContent
changed_when: false changed_when: false
args: args:
executable: bash executable: bash

@ -1,5 +1,4 @@
--- ---
- name: Copy the keys to the strongswan directory - name: Copy the keys to the strongswan directory
copy: copy:
src: "{{ ipsec_pki_path }}/{{ item.src }}" src: "{{ ipsec_pki_path }}/{{ item.src }}"
@ -8,18 +7,18 @@
group: "{{ item.group }}" group: "{{ item.group }}"
mode: "{{ item.mode }}" mode: "{{ item.mode }}"
with_items: with_items:
- src: "cacert.pem" - src: cacert.pem
dest: "cacerts/ca.crt" dest: cacerts/ca.crt
owner: strongswan owner: strongswan
group: "{{ root_group|default('root') }}" group: "{{ root_group|default('root') }}"
mode: "0600" mode: "0600"
- src: "certs/{{ IP_subject_alt_name }}.crt" - src: certs/{{ IP_subject_alt_name }}.crt
dest: "certs/{{ IP_subject_alt_name }}.crt" dest: certs/{{ IP_subject_alt_name }}.crt
owner: strongswan owner: strongswan
group: "{{ root_group|default('root') }}" group: "{{ root_group|default('root') }}"
mode: "0600" mode: "0600"
- src: "private/{{ IP_subject_alt_name }}.key" - src: private/{{ IP_subject_alt_name }}.key
dest: "private/{{ IP_subject_alt_name }}.key" dest: private/{{ IP_subject_alt_name }}.key
owner: strongswan owner: strongswan
group: "{{ root_group|default('root') }}" group: "{{ root_group|default('root') }}"
mode: "0600" mode: "0600"

@ -1,5 +1,4 @@
--- ---
- name: Setup the config files from our templates - name: Setup the config files from our templates
template: template:
src: "{{ item.src }}" src: "{{ item.src }}"
@ -9,22 +8,22 @@
mode: "{{ item.mode }}" mode: "{{ item.mode }}"
with_items: with_items:
- src: strongswan.conf.j2 - src: strongswan.conf.j2
dest: "strongswan.conf" dest: strongswan.conf
owner: root owner: root
group: "{{ root_group|default('root') }}" group: "{{ root_group|default('root') }}"
mode: "0644" mode: "0644"
- src: ipsec.conf.j2 - src: ipsec.conf.j2
dest: "ipsec.conf" dest: ipsec.conf
owner: root owner: root
group: "{{ root_group|default('root') }}" group: "{{ root_group|default('root') }}"
mode: "0644" mode: "0644"
- src: ipsec.secrets.j2 - src: ipsec.secrets.j2
dest: "ipsec.secrets" dest: ipsec.secrets
owner: strongswan owner: strongswan
group: "{{ root_group|default('root') }}" group: "{{ root_group|default('root') }}"
mode: "0600" mode: "0600"
- src: charon.conf.j2 - src: charon.conf.j2
dest: "strongswan.d/charon.conf" dest: strongswan.d/charon.conf
owner: root owner: root
group: "{{ root_group|default('root') }}" group: "{{ root_group|default('root') }}"
mode: "0644" mode: "0644"
@ -44,8 +43,8 @@
- name: Disable unneeded plugins - name: Disable unneeded plugins
lineinfile: lineinfile:
dest: "{{ config_prefix|default('/') }}etc/strongswan.d/charon/{{ item }}.conf" dest: "{{ config_prefix|default('/') }}etc/strongswan.d/charon/{{ item }}.conf"
regexp: '.*load.*' regexp: .*load.*
line: 'load = no' line: load = no
state: present state: present
notify: notify:
- restart strongswan - restart strongswan

@ -19,7 +19,7 @@
- import_tasks: distribute_keys.yml - import_tasks: distribute_keys.yml
- import_tasks: client_configs.yml - import_tasks: client_configs.yml
delegate_to: localhost delegate_to: localhost
become: no become: false
tags: update-users tags: update-users
- name: strongSwan started - name: strongSwan started

@ -1,239 +1,239 @@
--- ---
- block: - block:
- debug: var=subjectAltName - debug: var=subjectAltName
- name: Ensure the pki directory does not exist - name: Ensure the pki directory does not exist
file: file:
dest: "{{ ipsec_pki_path }}" dest: "{{ ipsec_pki_path }}"
state: absent state: absent
when: keys_clean_all|bool when: keys_clean_all|bool
- name: Ensure the pki directories exist - name: Ensure the pki directories exist
file: file:
dest: "{{ ipsec_pki_path }}/{{ item }}" dest: "{{ ipsec_pki_path }}/{{ item }}"
state: directory state: directory
recurse: yes recurse: true
mode: '0700' mode: "0700"
with_items: with_items:
- ecparams - ecparams
- certs - certs
- crl - crl
- newcerts - newcerts
- private - private
- public - public
- reqs - reqs
- name: Ensure the config directories exist - name: Ensure the config directories exist
file: file:
dest: "{{ ipsec_config_path }}/{{ item }}" dest: "{{ ipsec_config_path }}/{{ item }}"
state: directory state: directory
recurse: yes recurse: true
mode: '0700' mode: "0700"
with_items: with_items:
- apple - apple
- manual - manual
- name: Ensure the files exist - name: Ensure the files exist
file: file:
dest: "{{ ipsec_pki_path }}/{{ item }}" dest: "{{ ipsec_pki_path }}/{{ item }}"
state: touch state: touch
with_items: with_items:
- ".rnd" - .rnd
- "private/.rnd" - private/.rnd
- "index.txt" - index.txt
- "index.txt.attr" - index.txt.attr
- "serial" - serial
- name: Generate the openssl server configs - name: Generate the openssl server configs
template: template:
src: openssl.cnf.j2 src: openssl.cnf.j2
dest: "{{ ipsec_pki_path }}/openssl.cnf" dest: "{{ ipsec_pki_path }}/openssl.cnf"
- name: Build the CA pair - name: Build the CA pair
shell: > shell: >
umask 077; umask 077;
{{ openssl_bin }} ecparam -name secp384r1 -out ecparams/secp384r1.pem && {{ openssl_bin }} ecparam -name secp384r1 -out ecparams/secp384r1.pem &&
{{ openssl_bin }} req -utf8 -new {{ openssl_bin }} req -utf8 -new
-newkey ec:ecparams/secp384r1.pem -newkey ec:ecparams/secp384r1.pem
-config <(cat openssl.cnf <(printf "[basic_exts]\nsubjectAltName={{ subjectAltName }}")) -config <(cat openssl.cnf <(printf "[basic_exts]\nsubjectAltName={{ subjectAltName }}"))
-keyout private/cakey.pem -keyout private/cakey.pem
-out cacert.pem -x509 -days 3650 -out cacert.pem -x509 -days 3650
-batch -batch
-passout pass:"{{ CA_password }}" && -passout pass:"{{ CA_password }}" &&
touch {{ IP_subject_alt_name }}_ca_generated touch {{ IP_subject_alt_name }}_ca_generated
args: args:
chdir: "{{ ipsec_pki_path }}" chdir: "{{ ipsec_pki_path }}"
creates: "{{ IP_subject_alt_name }}_ca_generated" creates: "{{ IP_subject_alt_name }}_ca_generated"
executable: bash executable: bash
- name: Copy the CA certificate - name: Copy the CA certificate
copy: copy:
src: "{{ ipsec_pki_path }}/cacert.pem" src: "{{ ipsec_pki_path }}/cacert.pem"
dest: "{{ ipsec_config_path }}/manual/cacert.pem" dest: "{{ ipsec_config_path }}/manual/cacert.pem"
- name: Generate the serial number - name: Generate the serial number
shell: echo 01 > serial && touch serial_generated shell: echo 01 > serial && touch serial_generated
args: args:
chdir: "{{ ipsec_pki_path }}" chdir: "{{ ipsec_pki_path }}"
creates: serial_generated creates: serial_generated
- name: Build the server pair - name: Build the server pair
shell: > shell: >
umask 077; umask 077;
{{ openssl_bin }} req -utf8 -new {{ openssl_bin }} req -utf8 -new
-newkey ec:ecparams/secp384r1.pem -newkey ec:ecparams/secp384r1.pem
-config <(cat openssl.cnf <(printf "[basic_exts]\nsubjectAltName={{ subjectAltName }}")) -config <(cat openssl.cnf <(printf "[basic_exts]\nsubjectAltName={{ subjectAltName }}"))
-keyout private/{{ IP_subject_alt_name }}.key -keyout private/{{ IP_subject_alt_name }}.key
-out reqs/{{ IP_subject_alt_name }}.req -nodes -out reqs/{{ IP_subject_alt_name }}.req -nodes
-passin pass:"{{ CA_password }}" -passin pass:"{{ CA_password }}"
-subj "/CN={{ IP_subject_alt_name }}" -batch && -subj "/CN={{ IP_subject_alt_name }}" -batch &&
{{ openssl_bin }} ca -utf8 {{ openssl_bin }} ca -utf8
-in reqs/{{ IP_subject_alt_name }}.req -in reqs/{{ IP_subject_alt_name }}.req
-out certs/{{ IP_subject_alt_name }}.crt -out certs/{{ IP_subject_alt_name }}.crt
-config <(cat openssl.cnf <(printf "[basic_exts]\nsubjectAltName={{ subjectAltName }}")) -config <(cat openssl.cnf <(printf "[basic_exts]\nsubjectAltName={{ subjectAltName }}"))
-days 3650 -batch -days 3650 -batch
-passin pass:"{{ CA_password }}" -passin pass:"{{ CA_password }}"
-subj "/CN={{ IP_subject_alt_name }}" && -subj "/CN={{ IP_subject_alt_name }}" &&
touch certs/{{ IP_subject_alt_name }}_crt_generated touch certs/{{ IP_subject_alt_name }}_crt_generated
args: args:
chdir: "{{ ipsec_pki_path }}" chdir: "{{ ipsec_pki_path }}"
creates: certs/{{ IP_subject_alt_name }}_crt_generated creates: certs/{{ IP_subject_alt_name }}_crt_generated
executable: bash executable: bash
- name: Build the client's pair - name: Build the client's pair
shell: > shell: >
umask 077; umask 077;
{{ openssl_bin }} req -utf8 -new {{ openssl_bin }} req -utf8 -new
-newkey ec:ecparams/secp384r1.pem -newkey ec:ecparams/secp384r1.pem
-config <(cat openssl.cnf <(printf "[basic_exts]\nsubjectAltName={{ subjectAltName_USER }}")) -config <(cat openssl.cnf <(printf "[basic_exts]\nsubjectAltName={{ subjectAltName_USER }}"))
-keyout private/{{ item }}.key -keyout private/{{ item }}.key
-out reqs/{{ item }}.req -nodes -out reqs/{{ item }}.req -nodes
-passin pass:"{{ CA_password }}" -passin pass:"{{ CA_password }}"
-subj "/CN={{ item }}" -batch && -subj "/CN={{ item }}" -batch &&
{{ openssl_bin }} ca -utf8 {{ openssl_bin }} ca -utf8
-in reqs/{{ item }}.req -in reqs/{{ item }}.req
-out certs/{{ item }}.crt -out certs/{{ item }}.crt
-config <(cat openssl.cnf <(printf "[basic_exts]\nsubjectAltName={{ subjectAltName_USER }}")) -config <(cat openssl.cnf <(printf "[basic_exts]\nsubjectAltName={{ subjectAltName_USER }}"))
-days 3650 -batch -days 3650 -batch
-passin pass:"{{ CA_password }}" -passin pass:"{{ CA_password }}"
-subj "/CN={{ item }}" && -subj "/CN={{ item }}" &&
touch certs/{{ item }}_crt_generated touch certs/{{ item }}_crt_generated
args: args:
chdir: "{{ ipsec_pki_path }}" chdir: "{{ ipsec_pki_path }}"
creates: certs/{{ item }}_crt_generated creates: certs/{{ item }}_crt_generated
executable: bash executable: bash
with_items: "{{ users }}" with_items: "{{ users }}"
- name: Build the tests pair - name: Build the tests pair
shell: > shell: >
umask 077; umask 077;
{{ openssl_bin }} req -utf8 -new {{ openssl_bin }} req -utf8 -new
-newkey ec:ecparams/secp384r1.pem -newkey ec:ecparams/secp384r1.pem
-config <(cat openssl.cnf <(printf "[basic_exts]\nsubjectAltName=DNS:google-algo-test-pair.com")) -config <(cat openssl.cnf <(printf "[basic_exts]\nsubjectAltName=DNS:google-algo-test-pair.com"))
-keyout private/google-algo-test-pair.com.key -keyout private/google-algo-test-pair.com.key
-out reqs/google-algo-test-pair.com.req -nodes -out reqs/google-algo-test-pair.com.req -nodes
-passin pass:"{{ CA_password }}" -passin pass:"{{ CA_password }}"
-subj "/CN=google-algo-test-pair.com" -batch && -subj "/CN=google-algo-test-pair.com" -batch &&
{{ openssl_bin }} ca -utf8 {{ openssl_bin }} ca -utf8
-in reqs/google-algo-test-pair.com.req -in reqs/google-algo-test-pair.com.req
-out certs/google-algo-test-pair.com.crt -out certs/google-algo-test-pair.com.crt
-config <(cat openssl.cnf <(printf "[basic_exts]\nsubjectAltName=DNS:google-algo-test-pair.com")) -config <(cat openssl.cnf <(printf "[basic_exts]\nsubjectAltName=DNS:google-algo-test-pair.com"))
-days 3650 -batch -days 3650 -batch
-passin pass:"{{ CA_password }}" -passin pass:"{{ CA_password }}"
-subj "/CN=google-algo-test-pair.com" && -subj "/CN=google-algo-test-pair.com" &&
touch certs/google-algo-test-pair.com_crt_generated touch certs/google-algo-test-pair.com_crt_generated
args: args:
chdir: "{{ ipsec_pki_path }}" chdir: "{{ ipsec_pki_path }}"
creates: certs/google-algo-test-pair.com_crt_generated creates: certs/google-algo-test-pair.com_crt_generated
executable: bash executable: bash
when: tests|default(false)|bool when: tests|default(false)|bool
- name: Build openssh public keys - name: Build openssh public keys
openssl_publickey: openssl_publickey:
path: "{{ ipsec_pki_path }}/public/{{ item }}.pub" path: "{{ ipsec_pki_path }}/public/{{ item }}.pub"
privatekey_path: "{{ ipsec_pki_path }}/private/{{ item }}.key" privatekey_path: "{{ ipsec_pki_path }}/private/{{ item }}.key"
format: OpenSSH format: OpenSSH
with_items: "{{ users }}" with_items: "{{ users }}"
- name: Build the client's p12 - name: Build the client's p12
shell: > shell: >
umask 077; umask 077;
{{ openssl_bin }} pkcs12 {{ openssl_bin }} pkcs12
-in certs/{{ item }}.crt -in certs/{{ item }}.crt
-inkey private/{{ item }}.key -inkey private/{{ item }}.key
-export -export
-name {{ item }} -name {{ item }}
-out private/{{ item }}.p12 -out private/{{ item }}.p12
-passout pass:"{{ p12_export_password }}" -passout pass:"{{ p12_export_password }}"
args: args:
chdir: "{{ ipsec_pki_path }}" chdir: "{{ ipsec_pki_path }}"
executable: bash executable: bash
with_items: "{{ users }}" with_items: "{{ users }}"
register: p12 register: p12
- name: Build the client's p12 with the CA cert included - name: Build the client's p12 with the CA cert included
shell: > shell: >
umask 077; umask 077;
{{ openssl_bin }} pkcs12 {{ openssl_bin }} pkcs12
-in certs/{{ item }}.crt -in certs/{{ item }}.crt
-inkey private/{{ item }}.key -inkey private/{{ item }}.key
-export -export
-name {{ item }} -name {{ item }}
-out private/{{ item }}_ca.p12 -out private/{{ item }}_ca.p12
-certfile cacert.pem -certfile cacert.pem
-passout pass:"{{ p12_export_password }}" -passout pass:"{{ p12_export_password }}"
args: args:
chdir: "{{ ipsec_pki_path }}" chdir: "{{ ipsec_pki_path }}"
executable: bash executable: bash
with_items: "{{ users }}" with_items: "{{ users }}"
register: p12 register: p12
- name: Copy the p12 certificates - name: Copy the p12 certificates
copy: copy:
src: "{{ ipsec_pki_path }}/private/{{ item }}.p12" src: "{{ ipsec_pki_path }}/private/{{ item }}.p12"
dest: "{{ ipsec_config_path }}/manual/{{ item }}.p12" dest: "{{ ipsec_config_path }}/manual/{{ item }}.p12"
with_items: with_items:
- "{{ users }}" - "{{ users }}"
- name: Get active users - name: Get active users
shell: > shell: >
grep ^V index.txt | grep ^V index.txt |
grep -v "{{ IP_subject_alt_name }}" | grep -v "{{ IP_subject_alt_name }}" |
awk '{print $5}' | awk '{print $5}' |
sed 's/\/CN=//g' sed 's/\/CN=//g'
args: args:
chdir: "{{ ipsec_pki_path }}" chdir: "{{ ipsec_pki_path }}"
register: valid_certs register: valid_certs
- name: Revoke non-existing users - name: Revoke non-existing users
shell: > shell: >
{{ openssl_bin }} ca -gencrl {{ openssl_bin }} ca -gencrl
-config <(cat openssl.cnf <(printf "[basic_exts]\nsubjectAltName={{ subjectAltName_USER }}")) -config <(cat openssl.cnf <(printf "[basic_exts]\nsubjectAltName={{ subjectAltName_USER }}"))
-passin pass:"{{ CA_password }}" -passin pass:"{{ CA_password }}"
-revoke certs/{{ item }}.crt -revoke certs/{{ item }}.crt
-out crl/{{ item }}.crt -out crl/{{ item }}.crt
register: gencrl register: gencrl
args: args:
chdir: "{{ ipsec_pki_path }}" chdir: "{{ ipsec_pki_path }}"
creates: crl/{{ item }}.crt creates: crl/{{ item }}.crt
executable: bash executable: bash
when: item.split('@')[0] not in users when: item.split('@')[0] not in users
with_items: "{{ valid_certs.stdout_lines }}" with_items: "{{ valid_certs.stdout_lines }}"
- name: Generate new CRL file - name: Generate new CRL file
shell: > shell: >
{{ openssl_bin }} ca -gencrl {{ openssl_bin }} ca -gencrl
-config <(cat openssl.cnf <(printf "[basic_exts]\nsubjectAltName=DNS:{{ IP_subject_alt_name }}")) -config <(cat openssl.cnf <(printf "[basic_exts]\nsubjectAltName=DNS:{{ IP_subject_alt_name }}"))
-passin pass:"{{ CA_password }}" -passin pass:"{{ CA_password }}"
-out crl/algo.root.pem -out crl/algo.root.pem
when: when:
- gencrl is defined - gencrl is defined
- gencrl.changed - gencrl.changed
args: args:
chdir: "{{ ipsec_pki_path }}" chdir: "{{ ipsec_pki_path }}"
executable: bash executable: bash
delegate_to: localhost delegate_to: localhost
become: no become: false
vars: vars:
ansible_python_interpreter: "{{ ansible_playbook_python }}" ansible_python_interpreter: "{{ ansible_playbook_python }}"

@ -2,32 +2,31 @@
- name: Set OS specific facts - name: Set OS specific facts
set_fact: set_fact:
strongswan_additional_plugins: [] strongswan_additional_plugins: []
- name: Ubuntu | Install strongSwan - name: Ubuntu | Install strongSwan
apt: apt:
name: strongswan name: strongswan
state: present state: present
update_cache: yes update_cache: true
install_recommends: yes install_recommends: true
- block: - block:
# https://bugs.launchpad.net/ubuntu/+source/strongswan/+bug/1826238 # https://bugs.launchpad.net/ubuntu/+source/strongswan/+bug/1826238
- name: Ubuntu | Charon profile for apparmor configured - name: Ubuntu | Charon profile for apparmor configured
copy: copy:
dest: /etc/apparmor.d/local/usr.lib.ipsec.charon dest: /etc/apparmor.d/local/usr.lib.ipsec.charon
content: ' capability setpcap,' content: " capability setpcap,"
owner: root owner: root
group: root group: root
mode: 0644 mode: 0644
notify: restart strongswan notify: restart strongswan
- name: Ubuntu | Enforcing ipsec with apparmor - name: Ubuntu | Enforcing ipsec with apparmor
command: aa-enforce "{{ item }}" command: aa-enforce "{{ item }}"
changed_when: false changed_when: false
with_items: with_items:
- /usr/lib/ipsec/charon - /usr/lib/ipsec/charon
- /usr/lib/ipsec/lookip - /usr/lib/ipsec/lookip
- /usr/lib/ipsec/stroke - /usr/lib/ipsec/stroke
tags: apparmor tags: apparmor
when: apparmor_enabled|default(false)|bool when: apparmor_enabled|default(false)|bool

@ -1,6 +1,6 @@
--- ---
wireguard_PersistentKeepalive: 0 wireguard_PersistentKeepalive: 0
wireguard_config_path: "configs/{{ IP_subject_alt_name }}/wireguard/" wireguard_config_path: configs/{{ IP_subject_alt_name }}/wireguard/
wireguard_pki_path: "{{ wireguard_config_path }}/.pki/" wireguard_pki_path: "{{ wireguard_config_path }}/.pki/"
wireguard_interface: wg0 wireguard_interface: wg0
wireguard_port_avoid: 53 wireguard_port_avoid: 53
@ -10,7 +10,8 @@ wireguard_dns_servers: >-
{% if algo_dns_adblocking|default(false)|bool or dns_encryption|default(false)|bool %} {% if algo_dns_adblocking|default(false)|bool or dns_encryption|default(false)|bool %}
{{ local_service_ip }}{{ ', ' + local_service_ipv6 if ipv6_support else '' }} {{ local_service_ip }}{{ ', ' + local_service_ipv6 if ipv6_support else '' }}
{% else %} {% else %}
{% for host in dns_servers.ipv4 %}{{ host }}{% if not loop.last %},{% endif %}{% endfor %}{% if ipv6_support %},{% for host in dns_servers.ipv6 %}{{ host }}{% if not loop.last %},{% endif %}{% endfor %}{% endif %} {% for host in dns_servers.ipv4 %}{{ host }}{% if not loop.last %},{% endif %}{% endfor %}{% if ipv6_support %},{% for host in dns_servers.ipv6 %}{{ host }}{% if
not loop.last %},{% endif %}{% endfor %}{% endif %}
{% endif %} {% endif %}
wireguard_client_ip: >- wireguard_client_ip: >-
{{ wireguard_network_ipv4 | ipmath(index|int+2) }} {{ wireguard_network_ipv4 | ipmath(index|int+2) }}

@ -18,24 +18,24 @@
- "{{ IP_subject_alt_name }}" - "{{ IP_subject_alt_name }}"
- block: - block:
- name: Save private keys - name: Save private keys
copy: copy:
dest: "{{ wireguard_pki_path }}/private/{{ item['item'] }}" dest: "{{ wireguard_pki_path }}/private/{{ item['item'] }}"
content: "{{ item['stdout'] }}" content: "{{ item['stdout'] }}"
mode: "0600" mode: "0600"
no_log: "{{ no_log|bool }}" no_log: "{{ no_log|bool }}"
when: item.changed when: item.changed
with_items: "{{ wg_genkey['results'] }}" with_items: "{{ wg_genkey['results'] }}"
delegate_to: localhost delegate_to: localhost
become: false become: false
- name: Touch the lock file - name: Touch the lock file
file: file:
dest: "{{ config_prefix|default('/') }}etc/wireguard/private_{{ item }}.lock" dest: "{{ config_prefix|default('/') }}etc/wireguard/private_{{ item }}.lock"
state: touch state: touch
with_items: with_items:
- "{{ users }}" - "{{ users }}"
- "{{ IP_subject_alt_name }}" - "{{ IP_subject_alt_name }}"
when: wg_genkey.changed when: wg_genkey.changed
- name: Delete the preshared lock files - name: Delete the preshared lock files
@ -57,24 +57,24 @@
- "{{ IP_subject_alt_name }}" - "{{ IP_subject_alt_name }}"
- block: - block:
- name: Save preshared keys - name: Save preshared keys
copy: copy:
dest: "{{ wireguard_pki_path }}/preshared/{{ item['item'] }}" dest: "{{ wireguard_pki_path }}/preshared/{{ item['item'] }}"
content: "{{ item['stdout'] }}" content: "{{ item['stdout'] }}"
mode: "0600" mode: "0600"
no_log: "{{ no_log|bool }}" no_log: "{{ no_log|bool }}"
when: item.changed when: item.changed
with_items: "{{ wg_genpsk['results'] }}" with_items: "{{ wg_genpsk['results'] }}"
delegate_to: localhost delegate_to: localhost
become: false become: false
- name: Touch the preshared lock file - name: Touch the preshared lock file
file: file:
dest: "{{ config_prefix|default('/') }}etc/wireguard/preshared_{{ item }}.lock" dest: "{{ config_prefix|default('/') }}etc/wireguard/preshared_{{ item }}.lock"
state: touch state: touch
with_items: with_items:
- "{{ users }}" - "{{ users }}"
- "{{ IP_subject_alt_name }}" - "{{ IP_subject_alt_name }}"
when: wg_genpsk.changed when: wg_genpsk.changed
- name: Generate public keys - name: Generate public keys

@ -28,61 +28,61 @@
tags: update-users tags: update-users
- block: - block:
- block: - block:
- name: WireGuard user list updated - name: WireGuard user list updated
lineinfile: lineinfile:
dest: "{{ wireguard_pki_path }}/index.txt" dest: "{{ wireguard_pki_path }}/index.txt"
create: true create: true
mode: "0600" mode: "0600"
insertafter: EOF insertafter: EOF
line: "{{ item }}" line: "{{ item }}"
register: lineinfile register: lineinfile
with_items: "{{ users }}" with_items: "{{ users }}"
- set_fact: - set_fact:
wireguard_users: "{{ (lookup('file', wireguard_pki_path + 'index.txt')).split('\n') }}" wireguard_users: "{{ (lookup('file', wireguard_pki_path + 'index.txt')).split('\n') }}"
- name: WireGuard users config generated - name: WireGuard users config generated
template: template:
src: client.conf.j2 src: client.conf.j2
dest: "{{ wireguard_config_path }}/{{ item.1 }}.conf" dest: "{{ wireguard_config_path }}/{{ item.1 }}.conf"
mode: "0600" mode: "0600"
with_indexed_items: "{{ wireguard_users }}" with_indexed_items: "{{ wireguard_users }}"
when: item.1 in users when: item.1 in users
vars: vars:
index: "{{ item.0 }}" index: "{{ item.0 }}"
- include_tasks: mobileconfig.yml - include_tasks: mobileconfig.yml
loop: loop:
- ios - ios
- macos - macos
loop_control: loop_control:
loop_var: system loop_var: system
- name: Generate QR codes - name: Generate QR codes
shell: > shell: >
umask 077; umask 077;
which segno && which segno &&
segno --scale=5 --output={{ item.1 }}.png \ segno --scale=5 --output={{ item.1 }}.png \
"{{ lookup('template', 'client.conf.j2') }}" || true "{{ lookup('template', 'client.conf.j2') }}" || true
changed_when: false changed_when: false
with_indexed_items: "{{ wireguard_users }}" with_indexed_items: "{{ wireguard_users }}"
when: item.1 in users when: item.1 in users
vars: vars:
index: "{{ item.0 }}" index: "{{ item.0 }}"
ansible_python_interpreter: "{{ ansible_playbook_python }}" ansible_python_interpreter: "{{ ansible_playbook_python }}"
args: args:
chdir: "{{ wireguard_config_path }}" chdir: "{{ wireguard_config_path }}"
executable: bash executable: bash
become: false become: false
delegate_to: localhost delegate_to: localhost
- name: WireGuard configured - name: WireGuard configured
template: template:
src: server.conf.j2 src: server.conf.j2
dest: "{{ config_prefix|default('/') }}etc/wireguard/{{ wireguard_interface }}.conf" dest: "{{ config_prefix|default('/') }}etc/wireguard/{{ wireguard_interface }}.conf"
mode: "0600" mode: "0600"
notify: restart wireguard notify: restart wireguard
tags: update-users tags: update-users
- name: WireGuard enabled and started - name: WireGuard enabled and started

@ -4,7 +4,7 @@
src: mobileconfig.j2 src: mobileconfig.j2
dest: "{{ wireguard_config_path }}/apple/{{ system }}/{{ item.1 }}.mobileconfig" dest: "{{ wireguard_config_path }}/apple/{{ system }}/{{ item.1 }}.mobileconfig"
mode: "0600" mode: "0600"
with_indexed_items: "{{ wireguard_users }}" with_indexed_items: "{{ wireguard_users }}"
when: item.1 in users when: item.1 in users
vars: vars:
index: "{{ item.0 }}" index: "{{ item.0 }}"

@ -7,5 +7,5 @@
- name: Set OS specific facts - name: Set OS specific facts
set_fact: set_fact:
service_name: "wg-quick@{{ wireguard_interface }}" service_name: wg-quick@{{ wireguard_interface }}
tags: always tags: always

@ -7,117 +7,116 @@
- config.cfg - config.cfg
tasks: tasks:
- block: - block:
- name: Wait until the cloud-init completed - name: Wait until the cloud-init completed
wait_for: wait_for:
path: /var/lib/cloud/data/result.json path: /var/lib/cloud/data/result.json
delay: 10 delay: 10
timeout: 600 timeout: 600
state: present state: present
become: false become: false
when: cloudinit when: cloudinit
- block: - block:
- name: Ensure the config directory exists - name: Ensure the config directory exists
file: file:
dest: "configs/{{ IP_subject_alt_name }}" dest: configs/{{ IP_subject_alt_name }}
state: directory state: directory
mode: "0700" mode: "0700"
- name: Dump the ssh config - name: Dump the ssh config
copy: copy:
dest: "configs/{{ IP_subject_alt_name }}/ssh_config" dest: configs/{{ IP_subject_alt_name }}/ssh_config
mode: "0600" mode: "0600"
content: | content: |
Host {{ IP_subject_alt_name }} {{ algo_server_name }} Host {{ IP_subject_alt_name }} {{ algo_server_name }}
HostName {{ IP_subject_alt_name }} HostName {{ IP_subject_alt_name }}
User {{ ansible_ssh_user }} User {{ ansible_ssh_user }}
Port {{ ansible_ssh_port }} Port {{ ansible_ssh_port }}
IdentityFile {{ SSH_keys.private | realpath }} IdentityFile {{ SSH_keys.private | realpath }}
KeepAlive yes KeepAlive yes
ServerAliveInterval 30 ServerAliveInterval 30
when: inventory_hostname != 'localhost' when: inventory_hostname != 'localhost'
become: false become: false
delegate_to: localhost delegate_to: localhost
- import_role: - import_role:
name: common name: common
tags: common tags: common
- import_role: - import_role:
name: dns name: dns
when: when:
- algo_dns_adblocking or - algo_dns_adblocking or dns_encryption
dns_encryption tags: dns
tags: dns
- import_role: - import_role:
name: wireguard name: wireguard
when: wireguard_enabled when: wireguard_enabled
tags: wireguard tags: wireguard
- import_role: - import_role:
name: strongswan name: strongswan
when: ipsec_enabled when: ipsec_enabled
tags: ipsec tags: ipsec
- import_role: - import_role:
name: ssh_tunneling name: ssh_tunneling
when: algo_ssh_tunneling when: algo_ssh_tunneling
tags: ssh_tunneling tags: ssh_tunneling
- block: - block:
- name: Dump the configuration - name: Dump the configuration
copy: copy:
dest: "configs/{{ IP_subject_alt_name }}/.config.yml" dest: configs/{{ IP_subject_alt_name }}/.config.yml
content: | content: |
server: {{ 'localhost' if inventory_hostname == 'localhost' else inventory_hostname }} server: {{ 'localhost' if inventory_hostname == 'localhost' else inventory_hostname }}
server_user: {{ ansible_ssh_user }} server_user: {{ ansible_ssh_user }}
ansible_ssh_port: "{{ ansible_ssh_port|default(22) }}" ansible_ssh_port: "{{ ansible_ssh_port|default(22) }}"
{% if algo_provider != "local" %} {% if algo_provider != "local" %}
ansible_ssh_private_key_file: {{ SSH_keys.private }} ansible_ssh_private_key_file: {{ SSH_keys.private }}
{% endif %} {% endif %}
algo_provider: {{ algo_provider }} algo_provider: {{ algo_provider }}
algo_server_name: {{ algo_server_name }} algo_server_name: {{ algo_server_name }}
algo_ondemand_cellular: {{ algo_ondemand_cellular }} algo_ondemand_cellular: {{ algo_ondemand_cellular }}
algo_ondemand_wifi: {{ algo_ondemand_wifi }} algo_ondemand_wifi: {{ algo_ondemand_wifi }}
algo_ondemand_wifi_exclude: {{ algo_ondemand_wifi_exclude }} algo_ondemand_wifi_exclude: {{ algo_ondemand_wifi_exclude }}
algo_dns_adblocking: {{ algo_dns_adblocking }} algo_dns_adblocking: {{ algo_dns_adblocking }}
algo_ssh_tunneling: {{ algo_ssh_tunneling }} algo_ssh_tunneling: {{ algo_ssh_tunneling }}
algo_store_pki: {{ algo_store_pki }} algo_store_pki: {{ algo_store_pki }}
IP_subject_alt_name: {{ IP_subject_alt_name }} IP_subject_alt_name: {{ IP_subject_alt_name }}
ipsec_enabled: {{ ipsec_enabled }} ipsec_enabled: {{ ipsec_enabled }}
wireguard_enabled: {{ wireguard_enabled }} wireguard_enabled: {{ wireguard_enabled }}
{% if tests|default(false)|bool %} {% if tests|default(false)|bool %}
ca_password: '{{ CA_password }}' ca_password: '{{ CA_password }}'
p12_password: '{{ p12_export_password }}' p12_password: '{{ p12_export_password }}'
{% endif %} {% endif %}
become: false become: false
delegate_to: localhost delegate_to: localhost
- name: Create a symlink if deploying to localhost - name: Create a symlink if deploying to localhost
file: file:
src: "{{ IP_subject_alt_name }}" src: "{{ IP_subject_alt_name }}"
dest: configs/localhost dest: configs/localhost
state: link state: link
force: true force: true
when: inventory_hostname == 'localhost' when: inventory_hostname == 'localhost'
- name: Import tmpfs tasks - name: Import tmpfs tasks
import_tasks: playbooks/tmpfs/umount.yml import_tasks: playbooks/tmpfs/umount.yml
become: false become: false
delegate_to: localhost delegate_to: localhost
vars: vars:
facts: "{{ hostvars['localhost'] }}" facts: "{{ hostvars['localhost'] }}"
when: when:
- pki_in_tmpfs - pki_in_tmpfs
- not algo_store_pki - not algo_store_pki
- debug: - debug:
msg: msg:
- "{{ congrats.common.split('\n') }}" - "{{ congrats.common.split('\n') }}"
- " {{ congrats.p12_pass if algo_ssh_tunneling or ipsec_enabled else '' }}" - " {{ congrats.p12_pass if algo_ssh_tunneling or ipsec_enabled else '' }}"
- " {{ congrats.ca_key_pass if algo_store_pki and ipsec_enabled else '' }}" - " {{ congrats.ca_key_pass if algo_store_pki and ipsec_enabled else '' }}"
- " {{ congrats.ssh_access if algo_provider != 'local' else ''}}" - " {{ congrats.ssh_access if algo_provider != 'local' else ''}}"
tags: always tags: always
rescue: rescue:
- include_tasks: playbooks/rescue.yml - include_tasks: playbooks/rescue.yml

@ -1,6 +1,6 @@
--- ---
- hosts: localhost - hosts: localhost
gather_facts: False gather_facts: false
tags: always tags: always
vars_files: vars_files:
- config.cfg - config.cfg
@ -13,7 +13,7 @@
depth: 2 depth: 2
recurse: true recurse: true
hidden: true hidden: true
patterns: ".config.yml" patterns: .config.yml
register: _configs_list register: _configs_list
- name: Verify servers - name: Verify servers
@ -50,23 +50,23 @@
- name: Import host specific variables - name: Import host specific variables
include_vars: include_vars:
file: "configs/{{ algo_server }}/.config.yml" file: configs/{{ algo_server }}/.config.yml
- when: ipsec_enabled - when: ipsec_enabled
block: block:
- name: CA password prompt - name: CA password prompt
pause: pause:
prompt: Enter the password for the private CA key prompt: Enter the password for the private CA key
echo: false echo: false
register: _ca_password register: _ca_password
when: ca_password is undefined when: ca_password is undefined
- name: Set facts based on the input - name: Set facts based on the input
set_fact: set_fact:
CA_password: >- CA_password: >-
{% if ca_password is defined %}{{ ca_password }} {% if ca_password is defined %}{{ ca_password }}
{%- elif _ca_password.user_input %}{{ _ca_password.user_input }} {%- elif _ca_password.user_input %}{{ _ca_password.user_input }}
{%- else %}omit{% endif %} {%- else %}omit{% endif %}
- name: Local pre-tasks - name: Local pre-tasks
import_tasks: playbooks/cloud-pre.yml import_tasks: playbooks/cloud-pre.yml
@ -78,7 +78,7 @@
groups: vpn-host groups: vpn-host
ansible_ssh_user: "{{ server_user|default('root') }}" ansible_ssh_user: "{{ server_user|default('root') }}"
ansible_connection: "{% if algo_server == 'localhost' %}local{% else %}ssh{% endif %}" ansible_connection: "{% if algo_server == 'localhost' %}local{% else %}ssh{% endif %}"
ansible_python_interpreter: "/usr/bin/python3" ansible_python_interpreter: /usr/bin/python3
CA_password: "{{ CA_password|default(omit) }}" CA_password: "{{ CA_password|default(omit) }}"
rescue: rescue:
- include_tasks: playbooks/rescue.yml - include_tasks: playbooks/rescue.yml
@ -89,32 +89,32 @@
become: true become: true
vars_files: vars_files:
- config.cfg - config.cfg
- "configs/{{ inventory_hostname }}/.config.yml" - configs/{{ inventory_hostname }}/.config.yml
tasks: tasks:
- block: - block:
- import_role: - import_role:
name: common name: common
- import_role: - import_role:
name: wireguard name: wireguard
when: wireguard_enabled when: wireguard_enabled
- import_role: - import_role:
name: strongswan name: strongswan
when: ipsec_enabled when: ipsec_enabled
tags: ipsec tags: ipsec
- import_role: - import_role:
name: ssh_tunneling name: ssh_tunneling
when: algo_ssh_tunneling when: algo_ssh_tunneling
- debug: - debug:
msg: msg:
- "{{ congrats.common.split('\n') }}" - "{{ congrats.common.split('\n') }}"
- " {{ congrats.p12_pass if algo_ssh_tunneling or ipsec_enabled else '' }}" - " {{ congrats.p12_pass if algo_ssh_tunneling or ipsec_enabled else '' }}"
- " {{ congrats.ca_key_pass if algo_store_pki and ipsec_enabled else '' }}" - " {{ congrats.ca_key_pass if algo_store_pki and ipsec_enabled else '' }}"
- " {{ congrats.ssh_access if algo_provider != 'local' else ''}}" - " {{ congrats.ssh_access if algo_provider != 'local' else ''}}"
tags: always tags: always
rescue: rescue:
- include_tasks: playbooks/rescue.yml - include_tasks: playbooks/rescue.yml

Loading…
Cancel
Save