mirror of
https://github.com/trailofbits/algo.git
synced 2025-04-11 11:47:08 +02:00
parent
a43de09437
commit
347f864abb
59 changed files with 1140 additions and 1139 deletions
|
@ -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
|
||||||
|
|
2
.github/workflows/main.yml
vendored
2
.github/workflows/main.yml
vendored
|
@ -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: |
|
||||||
|
|
14
cloud.yml
14
cloud.yml
|
@ -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
|
||||||
|
|
207
input.yml
207
input.yml
|
@ -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
|
||||||
|
|
15
main.yml
15
main.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 %}
|
||||||
|
|
||||||
Enter the number of your desired region
|
- pause:
|
||||||
[{{ default_region }}]
|
prompt: |
|
||||||
register: _algo_region
|
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
|
||||||
|
[{{ default_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 %}
|
||||||
|
|
||||||
Enter the number of your desired region
|
- pause:
|
||||||
[{{ default_region }}]
|
prompt: |
|
||||||
register: _algo_region
|
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
|
||||||
|
[{{ default_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
|
||||||
|
when: keys_clean_all|bool
|
||||||
|
|
||||||
|
- name: Ensure the config directories exist
|
||||||
|
file:
|
||||||
|
dest: "{{ ssh_tunnels_config_path }}"
|
||||||
|
state: directory
|
||||||
|
recurse: true
|
||||||
|
mode: "0700"
|
||||||
|
|
||||||
|
- name: Check if the private keys exist
|
||||||
|
stat:
|
||||||
|
path: "{{ ssh_tunnels_config_path }}/{{ item }}.pem"
|
||||||
|
register: privatekey
|
||||||
|
with_items: "{{ users }}"
|
||||||
|
|
||||||
|
- name: Build ssh private keys
|
||||||
|
openssl_privatekey:
|
||||||
|
path: "{{ ssh_tunnels_config_path }}/{{ item.item }}.pem"
|
||||||
|
passphrase: "{{ p12_export_password }}"
|
||||||
|
cipher: auto
|
||||||
|
force: false
|
||||||
|
no_log: "{{ no_log|bool }}"
|
||||||
|
when: not item.stat.exists
|
||||||
|
with_items: "{{ privatekey.results }}"
|
||||||
|
register: openssl_privatekey
|
||||||
|
|
||||||
|
- name: Build ssh public keys
|
||||||
|
openssl_publickey:
|
||||||
|
path: "{{ ssh_tunnels_config_path }}/{{ item.item.item }}.pub"
|
||||||
|
privatekey_path: "{{ ssh_tunnels_config_path }}/{{ item.item.item }}.pem"
|
||||||
|
privatekey_passphrase: "{{ p12_export_password }}"
|
||||||
|
format: OpenSSH
|
||||||
|
force: true
|
||||||
|
no_log: "{{ no_log|bool }}"
|
||||||
|
when: item.changed
|
||||||
|
with_items: "{{ openssl_privatekey.results }}"
|
||||||
|
|
||||||
|
- name: Build the client ssh config
|
||||||
|
template:
|
||||||
|
src: ssh_config.j2
|
||||||
|
dest: "{{ ssh_tunnels_config_path }}/{{ item }}.ssh_config"
|
||||||
|
mode: 0700
|
||||||
|
with_items: "{{ users }}"
|
||||||
|
delegate_to: localhost
|
||||||
|
become: false
|
||||||
|
|
||||||
|
- name: The authorized keys file created
|
||||||
|
authorized_key:
|
||||||
|
user: "{{ item }}"
|
||||||
|
key: "{{ lookup('file', ssh_tunnels_config_path + '/' + item + '.pub') }}"
|
||||||
|
state: present
|
||||||
|
manage_dir: true
|
||||||
|
exclusive: true
|
||||||
|
with_items: "{{ users }}"
|
||||||
|
|
||||||
|
- name: Get active users
|
||||||
|
getent:
|
||||||
|
database: group
|
||||||
|
key: algo
|
||||||
|
split: ":"
|
||||||
|
|
||||||
|
- name: Delete non-existing users
|
||||||
|
user:
|
||||||
|
name: "{{ item }}"
|
||||||
state: absent
|
state: absent
|
||||||
when: keys_clean_all|bool
|
remove: true
|
||||||
|
|
||||||
- name: Ensure the config directories exist
|
|
||||||
file:
|
|
||||||
dest: "{{ ssh_tunnels_config_path }}"
|
|
||||||
state: directory
|
|
||||||
recurse: yes
|
|
||||||
mode: '0700'
|
|
||||||
|
|
||||||
- name: Check if the private keys exist
|
|
||||||
stat:
|
|
||||||
path: "{{ ssh_tunnels_config_path }}/{{ item }}.pem"
|
|
||||||
register: privatekey
|
|
||||||
with_items: "{{ users }}"
|
|
||||||
|
|
||||||
- name: Build ssh private keys
|
|
||||||
openssl_privatekey:
|
|
||||||
path: "{{ ssh_tunnels_config_path }}/{{ item.item }}.pem"
|
|
||||||
passphrase: "{{ p12_export_password }}"
|
|
||||||
cipher: auto
|
|
||||||
force: false
|
|
||||||
no_log: "{{ no_log|bool }}"
|
|
||||||
when: not item.stat.exists
|
|
||||||
with_items: "{{ privatekey.results }}"
|
|
||||||
register: openssl_privatekey
|
|
||||||
|
|
||||||
- name: Build ssh public keys
|
|
||||||
openssl_publickey:
|
|
||||||
path: "{{ ssh_tunnels_config_path }}/{{ item.item.item }}.pub"
|
|
||||||
privatekey_path: "{{ ssh_tunnels_config_path }}/{{ item.item.item }}.pem"
|
|
||||||
privatekey_passphrase: "{{ p12_export_password }}"
|
|
||||||
format: OpenSSH
|
|
||||||
force: true
|
force: true
|
||||||
no_log: "{{ no_log|bool }}"
|
when: item not in users
|
||||||
when: item.changed
|
with_items: "{{ getent_group['algo'][2].split(',') }}"
|
||||||
with_items: "{{ openssl_privatekey.results }}"
|
|
||||||
|
|
||||||
- name: Build the client ssh config
|
|
||||||
template:
|
|
||||||
src: ssh_config.j2
|
|
||||||
dest: "{{ ssh_tunnels_config_path }}/{{ item }}.ssh_config"
|
|
||||||
mode: 0700
|
|
||||||
with_items: "{{ users }}"
|
|
||||||
delegate_to: localhost
|
|
||||||
become: false
|
|
||||||
|
|
||||||
- name: The authorized keys file created
|
|
||||||
authorized_key:
|
|
||||||
user: "{{ item }}"
|
|
||||||
key: "{{ lookup('file', ssh_tunnels_config_path + '/' + item + '.pub') }}"
|
|
||||||
state: present
|
|
||||||
manage_dir: true
|
|
||||||
exclusive: true
|
|
||||||
with_items: "{{ users }}"
|
|
||||||
|
|
||||||
- name: Get active users
|
|
||||||
getent:
|
|
||||||
database: group
|
|
||||||
key: algo
|
|
||||||
split: ':'
|
|
||||||
|
|
||||||
- name: Delete non-existing users
|
|
||||||
user:
|
|
||||||
name: "{{ item }}"
|
|
||||||
state: absent
|
|
||||||
remove: yes
|
|
||||||
force: yes
|
|
||||||
when: item not in users
|
|
||||||
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:
|
||||||
|
src: client.conf.j2
|
||||||
|
dest: "{{ wireguard_config_path }}/{{ item.1 }}.conf"
|
||||||
|
mode: "0600"
|
||||||
|
with_indexed_items: "{{ wireguard_users }}"
|
||||||
|
when: item.1 in users
|
||||||
|
vars:
|
||||||
|
index: "{{ item.0 }}"
|
||||||
|
|
||||||
|
- include_tasks: mobileconfig.yml
|
||||||
|
loop:
|
||||||
|
- ios
|
||||||
|
- macos
|
||||||
|
loop_control:
|
||||||
|
loop_var: system
|
||||||
|
|
||||||
|
- name: Generate QR codes
|
||||||
|
shell: >
|
||||||
|
umask 077;
|
||||||
|
which segno &&
|
||||||
|
segno --scale=5 --output={{ item.1 }}.png \
|
||||||
|
"{{ lookup('template', 'client.conf.j2') }}" || true
|
||||||
|
changed_when: false
|
||||||
|
with_indexed_items: "{{ wireguard_users }}"
|
||||||
|
when: item.1 in users
|
||||||
|
vars:
|
||||||
|
index: "{{ item.0 }}"
|
||||||
|
ansible_python_interpreter: "{{ ansible_playbook_python }}"
|
||||||
|
args:
|
||||||
|
chdir: "{{ wireguard_config_path }}"
|
||||||
|
executable: bash
|
||||||
|
become: false
|
||||||
|
delegate_to: localhost
|
||||||
|
|
||||||
|
- name: WireGuard configured
|
||||||
template:
|
template:
|
||||||
src: client.conf.j2
|
src: server.conf.j2
|
||||||
dest: "{{ wireguard_config_path }}/{{ item.1 }}.conf"
|
dest: "{{ config_prefix|default('/') }}etc/wireguard/{{ wireguard_interface }}.conf"
|
||||||
mode: "0600"
|
mode: "0600"
|
||||||
with_indexed_items: "{{ wireguard_users }}"
|
notify: restart wireguard
|
||||||
when: item.1 in users
|
|
||||||
vars:
|
|
||||||
index: "{{ item.0 }}"
|
|
||||||
|
|
||||||
- include_tasks: mobileconfig.yml
|
|
||||||
loop:
|
|
||||||
- ios
|
|
||||||
- macos
|
|
||||||
loop_control:
|
|
||||||
loop_var: system
|
|
||||||
|
|
||||||
- name: Generate QR codes
|
|
||||||
shell: >
|
|
||||||
umask 077;
|
|
||||||
which segno &&
|
|
||||||
segno --scale=5 --output={{ item.1 }}.png \
|
|
||||||
"{{ lookup('template', 'client.conf.j2') }}" || true
|
|
||||||
changed_when: false
|
|
||||||
with_indexed_items: "{{ wireguard_users }}"
|
|
||||||
when: item.1 in users
|
|
||||||
vars:
|
|
||||||
index: "{{ item.0 }}"
|
|
||||||
ansible_python_interpreter: "{{ ansible_playbook_python }}"
|
|
||||||
args:
|
|
||||||
chdir: "{{ wireguard_config_path }}"
|
|
||||||
executable: bash
|
|
||||||
become: false
|
|
||||||
delegate_to: localhost
|
|
||||||
|
|
||||||
- name: WireGuard configured
|
|
||||||
template:
|
|
||||||
src: server.conf.j2
|
|
||||||
dest: "{{ config_prefix|default('/') }}etc/wireguard/{{ wireguard_interface }}.conf"
|
|
||||||
mode: "0600"
|
|
||||||
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
|
||||||
|
|
207
server.yml
207
server.yml
|
@ -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
|
|
||||||
delegate_to: localhost
|
|
||||||
|
|
||||||
- import_role:
|
|
||||||
name: common
|
|
||||||
tags: common
|
|
||||||
|
|
||||||
- import_role:
|
|
||||||
name: dns
|
|
||||||
when:
|
|
||||||
- algo_dns_adblocking or
|
|
||||||
dns_encryption
|
|
||||||
tags: dns
|
|
||||||
|
|
||||||
- import_role:
|
|
||||||
name: wireguard
|
|
||||||
when: wireguard_enabled
|
|
||||||
tags: wireguard
|
|
||||||
|
|
||||||
- import_role:
|
|
||||||
name: strongswan
|
|
||||||
when: ipsec_enabled
|
|
||||||
tags: ipsec
|
|
||||||
|
|
||||||
- import_role:
|
|
||||||
name: ssh_tunneling
|
|
||||||
when: algo_ssh_tunneling
|
|
||||||
tags: ssh_tunneling
|
|
||||||
|
|
||||||
- block:
|
|
||||||
- name: Dump the configuration
|
|
||||||
copy:
|
|
||||||
dest: "configs/{{ IP_subject_alt_name }}/.config.yml"
|
|
||||||
content: |
|
|
||||||
server: {{ 'localhost' if inventory_hostname == 'localhost' else inventory_hostname }}
|
|
||||||
server_user: {{ ansible_ssh_user }}
|
|
||||||
ansible_ssh_port: "{{ ansible_ssh_port|default(22) }}"
|
|
||||||
{% if algo_provider != "local" %}
|
|
||||||
ansible_ssh_private_key_file: {{ SSH_keys.private }}
|
|
||||||
{% endif %}
|
|
||||||
algo_provider: {{ algo_provider }}
|
|
||||||
algo_server_name: {{ algo_server_name }}
|
|
||||||
algo_ondemand_cellular: {{ algo_ondemand_cellular }}
|
|
||||||
algo_ondemand_wifi: {{ algo_ondemand_wifi }}
|
|
||||||
algo_ondemand_wifi_exclude: {{ algo_ondemand_wifi_exclude }}
|
|
||||||
algo_dns_adblocking: {{ algo_dns_adblocking }}
|
|
||||||
algo_ssh_tunneling: {{ algo_ssh_tunneling }}
|
|
||||||
algo_store_pki: {{ algo_store_pki }}
|
|
||||||
IP_subject_alt_name: {{ IP_subject_alt_name }}
|
|
||||||
ipsec_enabled: {{ ipsec_enabled }}
|
|
||||||
wireguard_enabled: {{ wireguard_enabled }}
|
|
||||||
{% if tests|default(false)|bool %}
|
|
||||||
ca_password: '{{ CA_password }}'
|
|
||||||
p12_password: '{{ p12_export_password }}'
|
|
||||||
{% endif %}
|
|
||||||
become: false
|
become: false
|
||||||
delegate_to: localhost
|
delegate_to: localhost
|
||||||
|
|
||||||
- name: Create a symlink if deploying to localhost
|
- import_role:
|
||||||
file:
|
name: common
|
||||||
src: "{{ IP_subject_alt_name }}"
|
tags: common
|
||||||
dest: configs/localhost
|
|
||||||
state: link
|
|
||||||
force: true
|
|
||||||
when: inventory_hostname == 'localhost'
|
|
||||||
|
|
||||||
- name: Import tmpfs tasks
|
- import_role:
|
||||||
import_tasks: playbooks/tmpfs/umount.yml
|
name: dns
|
||||||
become: false
|
|
||||||
delegate_to: localhost
|
|
||||||
vars:
|
|
||||||
facts: "{{ hostvars['localhost'] }}"
|
|
||||||
when:
|
when:
|
||||||
- pki_in_tmpfs
|
- algo_dns_adblocking or dns_encryption
|
||||||
- not algo_store_pki
|
tags: dns
|
||||||
|
|
||||||
- debug:
|
- import_role:
|
||||||
msg:
|
name: wireguard
|
||||||
- "{{ congrats.common.split('\n') }}"
|
when: wireguard_enabled
|
||||||
- " {{ congrats.p12_pass if algo_ssh_tunneling or ipsec_enabled else '' }}"
|
tags: wireguard
|
||||||
- " {{ congrats.ca_key_pass if algo_store_pki and ipsec_enabled else '' }}"
|
|
||||||
- " {{ congrats.ssh_access if algo_provider != 'local' else ''}}"
|
- import_role:
|
||||||
tags: always
|
name: strongswan
|
||||||
|
when: ipsec_enabled
|
||||||
|
tags: ipsec
|
||||||
|
|
||||||
|
- import_role:
|
||||||
|
name: ssh_tunneling
|
||||||
|
when: algo_ssh_tunneling
|
||||||
|
tags: ssh_tunneling
|
||||||
|
|
||||||
|
- block:
|
||||||
|
- name: Dump the configuration
|
||||||
|
copy:
|
||||||
|
dest: configs/{{ IP_subject_alt_name }}/.config.yml
|
||||||
|
content: |
|
||||||
|
server: {{ 'localhost' if inventory_hostname == 'localhost' else inventory_hostname }}
|
||||||
|
server_user: {{ ansible_ssh_user }}
|
||||||
|
ansible_ssh_port: "{{ ansible_ssh_port|default(22) }}"
|
||||||
|
{% if algo_provider != "local" %}
|
||||||
|
ansible_ssh_private_key_file: {{ SSH_keys.private }}
|
||||||
|
{% endif %}
|
||||||
|
algo_provider: {{ algo_provider }}
|
||||||
|
algo_server_name: {{ algo_server_name }}
|
||||||
|
algo_ondemand_cellular: {{ algo_ondemand_cellular }}
|
||||||
|
algo_ondemand_wifi: {{ algo_ondemand_wifi }}
|
||||||
|
algo_ondemand_wifi_exclude: {{ algo_ondemand_wifi_exclude }}
|
||||||
|
algo_dns_adblocking: {{ algo_dns_adblocking }}
|
||||||
|
algo_ssh_tunneling: {{ algo_ssh_tunneling }}
|
||||||
|
algo_store_pki: {{ algo_store_pki }}
|
||||||
|
IP_subject_alt_name: {{ IP_subject_alt_name }}
|
||||||
|
ipsec_enabled: {{ ipsec_enabled }}
|
||||||
|
wireguard_enabled: {{ wireguard_enabled }}
|
||||||
|
{% if tests|default(false)|bool %}
|
||||||
|
ca_password: '{{ CA_password }}'
|
||||||
|
p12_password: '{{ p12_export_password }}'
|
||||||
|
{% endif %}
|
||||||
|
become: false
|
||||||
|
delegate_to: localhost
|
||||||
|
|
||||||
|
- name: Create a symlink if deploying to localhost
|
||||||
|
file:
|
||||||
|
src: "{{ IP_subject_alt_name }}"
|
||||||
|
dest: configs/localhost
|
||||||
|
state: link
|
||||||
|
force: true
|
||||||
|
when: inventory_hostname == 'localhost'
|
||||||
|
|
||||||
|
- name: Import tmpfs tasks
|
||||||
|
import_tasks: playbooks/tmpfs/umount.yml
|
||||||
|
become: false
|
||||||
|
delegate_to: localhost
|
||||||
|
vars:
|
||||||
|
facts: "{{ hostvars['localhost'] }}"
|
||||||
|
when:
|
||||||
|
- pki_in_tmpfs
|
||||||
|
- not algo_store_pki
|
||||||
|
|
||||||
|
- debug:
|
||||||
|
msg:
|
||||||
|
- "{{ congrats.common.split('\n') }}"
|
||||||
|
- " {{ congrats.p12_pass if algo_ssh_tunneling or ipsec_enabled else '' }}"
|
||||||
|
- " {{ congrats.ca_key_pass if algo_store_pki and ipsec_enabled else '' }}"
|
||||||
|
- " {{ congrats.ssh_access if algo_provider != 'local' else ''}}"
|
||||||
|
tags: always
|
||||||
rescue:
|
rescue:
|
||||||
- include_tasks: playbooks/rescue.yml
|
- include_tasks: playbooks/rescue.yml
|
||||||
|
|
72
users.yml
72
users.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…
Add table
Reference in a new issue