mirror of
https://github.com/trailofbits/algo.git
synced 2025-06-06 15:13:56 +02:00
Refactoring, Linting and additional tests (#1397)
* Refactoring, Linting and additional tests * Vultr: Undefined variable and deprecation notes fix * Travis-CI enable linters * Azure: Update python requirements * Update main.yml * Update install.sh * Add missing roles to ansible-lint * Linting for skipped roles * add .ansible-lint config
This commit is contained in:
parent
feb0091448
commit
25513cf925
61 changed files with 405 additions and 245 deletions
3
.ansible-lint
Normal file
3
.ansible-lint
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
skip_list:
|
||||||
|
- '204'
|
||||||
|
verbosity: 1
|
82
.travis.yml
82
.travis.yml
|
@ -8,15 +8,14 @@ services:
|
||||||
|
|
||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
sources:
|
sources: &default_sources
|
||||||
- sourceline: 'ppa:ubuntu-lxc/stable'
|
- sourceline: 'ppa:ubuntu-lxc/stable'
|
||||||
- sourceline: 'ppa:wireguard/wireguard'
|
- sourceline: 'ppa:wireguard/wireguard'
|
||||||
packages:
|
packages: &default_packages
|
||||||
- python-pip
|
- python-pip
|
||||||
- lxd
|
- lxd
|
||||||
- expect-dev
|
- expect-dev
|
||||||
- debootstrap
|
- debootstrap
|
||||||
- shellcheck
|
|
||||||
- tree
|
- tree
|
||||||
- bridge-utils
|
- bridge-utils
|
||||||
- dnsutils
|
- dnsutils
|
||||||
|
@ -25,7 +24,12 @@ addons:
|
||||||
- libffi-dev
|
- libffi-dev
|
||||||
- python-dev
|
- python-dev
|
||||||
- linux-headers-$(uname -r)
|
- linux-headers-$(uname -r)
|
||||||
- wireguard-dkms
|
- wireguard
|
||||||
|
- libxml2-utils
|
||||||
|
- crudini
|
||||||
|
- fping
|
||||||
|
- strongswan
|
||||||
|
- libstrongswan-standard-plugins
|
||||||
|
|
||||||
cache:
|
cache:
|
||||||
directories:
|
directories:
|
||||||
|
@ -37,39 +41,54 @@ before_cache:
|
||||||
- sudo tar cf $HOME/lxc/cache.tar /var/lib/lxd/images/
|
- sudo tar cf $HOME/lxc/cache.tar /var/lib/lxd/images/
|
||||||
- sudo chown $USER. $HOME/lxc/cache.tar
|
- sudo chown $USER. $HOME/lxc/cache.tar
|
||||||
|
|
||||||
|
custom_scripts:
|
||||||
|
provisioning: &provisioning
|
||||||
|
- ssh-keygen -f ~/.ssh/id_rsa -t rsa -N ''
|
||||||
|
- sudo ./tests/pre-deploy.sh
|
||||||
|
- 'sed -i "s/^reduce_mtu:\s0$/reduce_mtu: 20/" config.cfg'
|
||||||
|
tests: &tests
|
||||||
|
- sudo ./tests/wireguard-client.sh
|
||||||
|
- sudo env "PATH=$PATH" ./tests/ipsec-client.sh
|
||||||
|
- sudo ./tests/ssh-tunnel.sh
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
fast_finish: true
|
fast_finish: true
|
||||||
include:
|
include:
|
||||||
- stage: Test
|
- stage: Tests
|
||||||
name: local deployment from docker
|
name: code checks and linters
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
packages:
|
||||||
|
- shellcheck
|
||||||
script:
|
script:
|
||||||
- docker build -t travis/algo .
|
|
||||||
- sudo tar xf $HOME/lxc/cache.tar -C / || echo "Didn't extract cache."
|
|
||||||
- sudo cp -f tests/lxd-bridge /etc/default/lxd-bridge
|
|
||||||
- ssh-keygen -f ~/.ssh/id_rsa -t rsa -N ''
|
|
||||||
- echo -e "#cloud-config\nssh_authorized_keys:\n - $(cat ~/.ssh/id_rsa.pub)" | sudo lxc profile set default user.user-data -
|
|
||||||
- sudo service lxd restart
|
|
||||||
- sudo lxc launch ubuntu:18.04 algo
|
|
||||||
- until host algo.lxd 10.0.8.1 -t A; do sleep 3; done
|
|
||||||
- export LXC_IP="$(dig algo.lxd @10.0.8.1 +short)"
|
|
||||||
- pip install -r requirements.txt
|
|
||||||
- pip install ansible-lint
|
- pip install ansible-lint
|
||||||
- gem install awesome_bot
|
- shellcheck algo install.sh
|
||||||
- ansible-playbook --version
|
|
||||||
- tree . -L 2
|
|
||||||
- ansible-playbook main.yml --syntax-check
|
- ansible-playbook main.yml --syntax-check
|
||||||
|
- ansible-lint -v roles/*/*/*.yml playbooks/*.yml *.yml
|
||||||
|
|
||||||
|
- stage: Deploy
|
||||||
|
name: local deployment from docker
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
sources: *default_sources
|
||||||
|
packages: *default_packages
|
||||||
|
env: DEPLOY=docker
|
||||||
|
before_install: *provisioning
|
||||||
|
before_script:
|
||||||
|
- docker build -t travis/algo .
|
||||||
- ./tests/local-deploy.sh
|
- ./tests/local-deploy.sh
|
||||||
- ./tests/update-users.sh
|
- ./tests/update-users.sh
|
||||||
|
script: *tests
|
||||||
|
|
||||||
- stage: Test
|
- stage: Deploy
|
||||||
name: cloud-init deployment
|
name: cloud-init deployment
|
||||||
script:
|
addons:
|
||||||
- sudo tar xf $HOME/lxc/cache.tar -C / || echo "Didn't extract cache."
|
apt:
|
||||||
- sudo cp -f tests/lxd-bridge /etc/default/lxd-bridge
|
sources: *default_sources
|
||||||
- sudo service lxd restart
|
packages: *default_packages
|
||||||
- bash tests/cloud-init.sh | sudo lxc profile set default user.user-data -
|
env: DEPLOY=cloud-init
|
||||||
- sudo lxc profile show default
|
before_install: *provisioning
|
||||||
- sudo lxc launch ubuntu:18.04 algo
|
before_script:
|
||||||
- until sudo lxc exec algo -- test -f /var/log/cloud-init-output.log; do echo 'Log file not found, Sleep for 3 seconds'; sleep 3; done
|
- until sudo lxc exec algo -- test -f /var/log/cloud-init-output.log; do echo 'Log file not found, Sleep for 3 seconds'; sleep 3; done
|
||||||
- ( sudo lxc exec algo -- tail -f /var/log/cloud-init-output.log & )
|
- ( sudo lxc exec algo -- tail -f /var/log/cloud-init-output.log & )
|
||||||
- |
|
- |
|
||||||
|
@ -78,11 +97,10 @@ matrix:
|
||||||
sleep 30;
|
sleep 30;
|
||||||
done
|
done
|
||||||
- sudo lxc exec algo -- test -f /opt/algo/configs/localhost/.config.yml
|
- sudo lxc exec algo -- test -f /opt/algo/configs/localhost/.config.yml
|
||||||
|
- sudo lxc exec algo -- tar zcf /root/algo-configs.tar -C /opt/algo/configs/ .
|
||||||
# script:
|
- sudo lxc file pull algo/root/algo-configs.tar ./
|
||||||
# - awesome_bot --allow-dupe --skip-save-results *.md docs/*.md --white-list paypal.com,do.co,microsoft.com,https://github.com/trailofbits/algo/archive/master.zip,https://github.com/trailofbits/algo/issues/new
|
- sudo tar -C ./configs -zxf algo-configs.tar
|
||||||
# - shellcheck algo
|
script: *tests
|
||||||
# - ansible-lint main.yml users.yml deploy_client.yml
|
|
||||||
|
|
||||||
notifications:
|
notifications:
|
||||||
email: false
|
email: false
|
||||||
|
|
9
algo
9
algo
|
@ -7,7 +7,8 @@ then
|
||||||
ACTIVATE_SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/env/bin/activate"
|
ACTIVATE_SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/env/bin/activate"
|
||||||
if [ -f "$ACTIVATE_SCRIPT" ]
|
if [ -f "$ACTIVATE_SCRIPT" ]
|
||||||
then
|
then
|
||||||
source $ACTIVATE_SCRIPT
|
# shellcheck source=/dev/null
|
||||||
|
source "$ACTIVATE_SCRIPT"
|
||||||
else
|
else
|
||||||
echo "$ACTIVATE_SCRIPT not found. Did you follow documentation to install dependencies?"
|
echo "$ACTIVATE_SCRIPT not found. Did you follow documentation to install dependencies?"
|
||||||
exit 1
|
exit 1
|
||||||
|
@ -15,8 +16,8 @@ then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
case "$1" in
|
case "$1" in
|
||||||
update-users) PLAYBOOK=users.yml; ARGS="${@:2} -t update-users";;
|
update-users) PLAYBOOK=users.yml; ARGS=( "${@:2}" -t update-users ) ;;
|
||||||
*) PLAYBOOK=main.yml; ARGS=${@} ;;
|
*) PLAYBOOK=main.yml; ARGS=( "${@}" ) ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
ansible-playbook ${PLAYBOOK} ${ARGS}
|
ansible-playbook ${PLAYBOOK} "${ARGS[@]}"
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
|
---
|
||||||
- name: Configure the client
|
- name: Configure the client
|
||||||
hosts: localhost
|
hosts: localhost
|
||||||
|
become: false
|
||||||
vars_files:
|
vars_files:
|
||||||
- config.cfg
|
- config.cfg
|
||||||
|
|
||||||
|
@ -8,9 +10,10 @@
|
||||||
add_host:
|
add_host:
|
||||||
name: "{{ client_ip }}"
|
name: "{{ client_ip }}"
|
||||||
groups: client-host
|
groups: client-host
|
||||||
ansible_ssh_user: "{{ ssh_user }}"
|
ansible_ssh_user: "{{ 'root' if client_ip == 'localhost' else ssh_user }}"
|
||||||
vpn_user: "{{ vpn_user }}"
|
vpn_user: "{{ vpn_user }}"
|
||||||
server_ip: "{{ server_ip }}"
|
IP_subject_alt_name: "{{ server_ip }}"
|
||||||
|
ansible_python_interpreter: "/usr/bin/python3"
|
||||||
|
|
||||||
- name: Configure the client and install required software
|
- name: Configure the client and install required software
|
||||||
hosts: client-host
|
hosts: client-host
|
||||||
|
@ -18,33 +21,6 @@
|
||||||
become: true
|
become: true
|
||||||
vars_files:
|
vars_files:
|
||||||
- config.cfg
|
- config.cfg
|
||||||
- roles/vpn/defaults/main.yml
|
- roles/strongswan/defaults/main.yml
|
||||||
|
|
||||||
pre_tasks:
|
|
||||||
- name: Get the OS
|
|
||||||
raw: uname -a
|
|
||||||
register: distribution
|
|
||||||
|
|
||||||
- name: Modify the server name fact
|
|
||||||
set_fact:
|
|
||||||
IP_subject_alt_name: "{{ server_ip }}"
|
|
||||||
|
|
||||||
- name: Ubuntu Xenial | Install prerequisites
|
|
||||||
raw: >
|
|
||||||
test -x /usr/bin/python2.7 ||
|
|
||||||
sudo apt-get update -qq && sudo apt-get install -qq -y python2.7 &&
|
|
||||||
sudo update-alternatives --install /usr/bin/python python /usr/bin/python2.7 1
|
|
||||||
changed_when: false
|
|
||||||
when: "'ubuntu' in distribution.stdout|lower"
|
|
||||||
|
|
||||||
- name: Fedora 25 | Install prerequisites
|
|
||||||
raw: >
|
|
||||||
test -x /usr/bin/python2.7 ||
|
|
||||||
sudo dnf install python2 -y &&
|
|
||||||
sudo update-alternatives --install /usr/bin/python python /usr/bin/python2.7 1 &&
|
|
||||||
rpm -ql python2-dnf || dnf install python2-dnf -y
|
|
||||||
changed_when: false
|
|
||||||
when: "'fedora' in distribution.stdout|lower"
|
|
||||||
|
|
||||||
roles:
|
roles:
|
||||||
- { role: client, tags: ['client'] }
|
- role: client
|
||||||
|
|
45
input.yml
45
input.yml
|
@ -26,7 +26,8 @@
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
- block:
|
- block:
|
||||||
- pause:
|
- name: Region prompt
|
||||||
|
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 %}
|
||||||
|
@ -41,7 +42,8 @@
|
||||||
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']) }}"
|
||||||
|
|
||||||
- pause:
|
- name: VPN server name prompt
|
||||||
|
pause:
|
||||||
prompt: |
|
prompt: |
|
||||||
Name the vpn server
|
Name the vpn server
|
||||||
[algo]
|
[algo]
|
||||||
|
@ -50,21 +52,24 @@
|
||||||
- server_name is undefined
|
- server_name is undefined
|
||||||
- algo_provider != "local"
|
- algo_provider != "local"
|
||||||
- block:
|
- block:
|
||||||
- pause:
|
- name: Cellular On Demand prompt
|
||||||
|
pause:
|
||||||
prompt: |
|
prompt: |
|
||||||
Do you want macOS/iOS IPsec clients to enable "Connect On Demand" when connected to cellular networks?
|
Do you want macOS/iOS IPsec 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
|
||||||
|
|
||||||
- pause:
|
- name: Wi-Fi On Demand prompt
|
||||||
|
pause:
|
||||||
prompt: |
|
prompt: |
|
||||||
Do you want macOS/iOS IPsec clients to enable "Connect On Demand" when connected to Wi-Fi?
|
Do you want macOS/iOS IPsec 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
|
||||||
|
|
||||||
- pause:
|
- name: Trusted Wi-Fi networks prompt
|
||||||
|
pause:
|
||||||
prompt: |
|
prompt: |
|
||||||
List the names of any trusted Wi-Fi networks where macOS/iOS IPsec clients should not use "Connect On Demand"
|
List the names of any trusted Wi-Fi networks where macOS/iOS IPsec 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)
|
||||||
|
@ -74,14 +79,16 @@
|
||||||
- (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))
|
||||||
|
|
||||||
- pause:
|
- name: Compatible ciphers prompt
|
||||||
|
pause:
|
||||||
prompt: |
|
prompt: |
|
||||||
Do you want the VPN to support Windows 10 or Linux Desktop clients? (enables compatible ciphers and key exchange, less secure)
|
Do you want the VPN to support Windows 10 or Linux Desktop clients? (enables compatible ciphers and key exchange, less secure)
|
||||||
[y/N]
|
[y/N]
|
||||||
register: _windows
|
register: _windows
|
||||||
when: windows is undefined
|
when: windows is undefined
|
||||||
|
|
||||||
- pause:
|
- name: Retain the CA key prompt
|
||||||
|
pause:
|
||||||
prompt: |
|
prompt: |
|
||||||
Do you want to retain the CA key? (required to add users in the future, but less secure)
|
Do you want to retain the CA key? (required to add users in the future, but less secure)
|
||||||
[y/N]
|
[y/N]
|
||||||
|
@ -89,14 +96,16 @@
|
||||||
when: store_cakey is undefined
|
when: store_cakey is undefined
|
||||||
when: ipsec_enabled
|
when: ipsec_enabled
|
||||||
|
|
||||||
- pause:
|
- name: DNS adblocking prompt
|
||||||
|
pause:
|
||||||
prompt: |
|
prompt: |
|
||||||
Do you want to install an ad blocking DNS resolver on this VPN server?
|
Do you want to install an ad blocking DNS resolver on this VPN server?
|
||||||
[y/N]
|
[y/N]
|
||||||
register: _local_dns
|
register: _local_dns
|
||||||
when: local_dns is undefined
|
when: local_dns is undefined
|
||||||
|
|
||||||
- pause:
|
- name: SSH tunneling prompt
|
||||||
|
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]
|
||||||
|
@ -107,36 +116,38 @@
|
||||||
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 != "" %}{% set _server = _algo_server_name.user_input %}
|
{%- elif _algo_server_name.user_input is defined and _algo_server_name.user_input|length > 0 -%}
|
||||||
|
{%- 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 and _ondemand_cellular.user_input != "" %}{{ booleans_map[_ondemand_cellular.user_input] | default(defaults['ondemand_cellular']) }}
|
{%- elif _ondemand_cellular.user_input %}{{ 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 and _ondemand_wifi.user_input != "" %}{{ booleans_map[_ondemand_wifi.user_input] | default(defaults['ondemand_wifi']) }}
|
{%- elif _ondemand_wifi.user_input %}{{ 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 != "" %}{{ _ondemand_wifi_exclude.user_input | b64encode }}
|
{%- elif _ondemand_wifi_exclude.user_input is defined and _ondemand_wifi_exclude.user_input|length > 0 -%}
|
||||||
|
{{ _ondemand_wifi_exclude.user_input | b64encode }}
|
||||||
{%- else %}{{ '_null' | b64encode }}{% endif %}
|
{%- else %}{{ '_null' | b64encode }}{% endif %}
|
||||||
algo_local_dns: >-
|
algo_local_dns: >-
|
||||||
{% if local_dns is defined %}{{ local_dns | bool }}
|
{% if local_dns is defined %}{{ local_dns | bool }}
|
||||||
{%- elif _local_dns.user_input is defined and _local_dns.user_input != "" %}{{ booleans_map[_local_dns.user_input] | default(defaults['local_dns']) }}
|
{%- elif _local_dns.user_input %}{{ booleans_map[_local_dns.user_input] | default(defaults['local_dns']) }}
|
||||||
{%- 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 and _ssh_tunneling.user_input != "" %}{{ booleans_map[_ssh_tunneling.user_input] | default(defaults['ssh_tunneling']) }}
|
{%- elif _ssh_tunneling.user_input %}{{ booleans_map[_ssh_tunneling.user_input] | default(defaults['ssh_tunneling']) }}
|
||||||
{%- else %}false{% endif %}
|
{%- else %}false{% endif %}
|
||||||
algo_windows: >-
|
algo_windows: >-
|
||||||
{% if windows is defined %}{{ windows | bool }}
|
{% if windows is defined %}{{ windows | bool }}
|
||||||
{%- elif _windows.user_input is defined and _windows.user_input != "" %}{{ booleans_map[_windows.user_input] | default(defaults['windows']) }}
|
{%- elif _windows.user_input %}{{ booleans_map[_windows.user_input] | default(defaults['windows']) }}
|
||||||
{%- else %}false{% endif %}
|
{%- else %}false{% endif %}
|
||||||
algo_store_cakey: >-
|
algo_store_cakey: >-
|
||||||
{% if store_cakey is defined %}{{ store_cakey | bool }}
|
{% if store_cakey is defined %}{{ store_cakey | bool }}
|
||||||
{%- elif _store_cakey.user_input is defined and _store_cakey.user_input != "" %}{{ booleans_map[_store_cakey.user_input] | default(defaults['store_cakey']) }}
|
{%- elif _store_cakey.user_input %}{{ booleans_map[_store_cakey.user_input] | default(defaults['store_cakey']) }}
|
||||||
{%- else %}false{% endif %}
|
{%- else %}false{% endif %}
|
||||||
rescue:
|
rescue:
|
||||||
- include_tasks: playbooks/rescue.yml
|
- include_tasks: playbooks/rescue.yml
|
||||||
|
|
37
install.sh
37
install.sh
|
@ -36,12 +36,11 @@ installRequirements() {
|
||||||
}
|
}
|
||||||
|
|
||||||
getAlgo() {
|
getAlgo() {
|
||||||
[ ! -d "algo" ] && git clone https://github.com/${REPO_SLUG} algo
|
[ ! -d "algo" ] && git clone "https://github.com/${REPO_SLUG}" -b "${REPO_BRANCH}" algo
|
||||||
cd algo
|
cd algo
|
||||||
|
|
||||||
git checkout ${REPO_BRANCH}
|
python -m virtualenv --python="$(command -v python2)" .venv
|
||||||
|
# shellcheck source=/dev/null
|
||||||
python -m virtualenv --python=`which python2` .venv
|
|
||||||
. .venv/bin/activate
|
. .venv/bin/activate
|
||||||
python -m pip install -U pip virtualenv
|
python -m pip install -U pip virtualenv
|
||||||
python -m pip install -r requirements.txt
|
python -m pip install -r requirements.txt
|
||||||
|
@ -50,27 +49,23 @@ getAlgo() {
|
||||||
publicIpFromInterface() {
|
publicIpFromInterface() {
|
||||||
echo "Couldn't find a valid ipv4 address, using the first IP found on the interfaces as the endpoint."
|
echo "Couldn't find a valid ipv4 address, using the first IP found on the interfaces as the endpoint."
|
||||||
DEFAULT_INTERFACE="$(ip -4 route list match default | grep -Eo "dev .*" | awk '{print $2}')"
|
DEFAULT_INTERFACE="$(ip -4 route list match default | grep -Eo "dev .*" | awk '{print $2}')"
|
||||||
ENDPOINT=$(ip -4 addr sh dev $DEFAULT_INTERFACE | grep -w inet | head -n1 | awk '{print $2}' | grep -oE '\b([0-9]{1,3}\.){3}[0-9]{1,3}\b')
|
ENDPOINT=$(ip -4 addr sh dev "$DEFAULT_INTERFACE" | grep -w inet | head -n1 | awk '{print $2}' | grep -oE '\b([0-9]{1,3}\.){3}[0-9]{1,3}\b')
|
||||||
export ENDPOINT=$ENDPOINT
|
export ENDPOINT=$ENDPOINT
|
||||||
echo "Using ${ENDPOINT} as the endpoint"
|
echo "Using ${ENDPOINT} as the endpoint"
|
||||||
}
|
}
|
||||||
|
|
||||||
publicIpFromMetadata() {
|
publicIpFromMetadata() {
|
||||||
if curl -s http://169.254.169.254/metadata/v1/vendor-data | grep DigitalOcean >/dev/null; then
|
if curl -s http://169.254.169.254/metadata/v1/vendor-data | grep DigitalOcean >/dev/null; then
|
||||||
PROVIDER="digitalocean"
|
|
||||||
ENDPOINT="$(curl -s http://169.254.169.254/metadata/v1/interfaces/public/0/ipv4/address)"
|
ENDPOINT="$(curl -s http://169.254.169.254/metadata/v1/interfaces/public/0/ipv4/address)"
|
||||||
elif test "$(curl -s http://169.254.169.254/latest/meta-data/services/domain)" = "amazonaws.com"; then
|
elif test "$(curl -s http://169.254.169.254/latest/meta-data/services/domain)" = "amazonaws.com"; then
|
||||||
PROVIDER="amazon"
|
|
||||||
ENDPOINT="$(curl -s http://169.254.169.254/latest/meta-data/public-ipv4)"
|
ENDPOINT="$(curl -s http://169.254.169.254/latest/meta-data/public-ipv4)"
|
||||||
elif host -t A -W 10 metadata.google.internal 127.0.0.53 >/dev/null; then
|
elif host -t A -W 10 metadata.google.internal 127.0.0.53 >/dev/null; then
|
||||||
PROVIDER="gce"
|
|
||||||
ENDPOINT="$(curl -H "Metadata-Flavor: Google" "http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/access-configs/0/external-ip")"
|
ENDPOINT="$(curl -H "Metadata-Flavor: Google" "http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/access-configs/0/external-ip")"
|
||||||
elif test "$(curl -s -H Metadata:true 'http://169.254.169.254/metadata/instance/compute/publisher/?api-version=2017-04-02&format=text')" = "Canonical"; then
|
elif test "$(curl -s -H Metadata:true 'http://169.254.169.254/metadata/instance/compute/publisher/?api-version=2017-04-02&format=text')" = "Canonical"; then
|
||||||
PROVIDER="azure"
|
|
||||||
ENDPOINT="$(curl -H Metadata:true 'http://169.254.169.254/metadata/instance/network/interface/0/ipv4/ipAddress/0/publicIpAddress?api-version=2017-04-02&format=text')"
|
ENDPOINT="$(curl -H Metadata:true 'http://169.254.169.254/metadata/instance/network/interface/0/ipv4/ipAddress/0/publicIpAddress?api-version=2017-04-02&format=text')"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if echo ${ENDPOINT} | grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b"; then
|
if echo "${ENDPOINT}" | grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b"; then
|
||||||
export ENDPOINT=$ENDPOINT
|
export ENDPOINT=$ENDPOINT
|
||||||
echo "Using ${ENDPOINT} as the endpoint"
|
echo "Using ${ENDPOINT} as the endpoint"
|
||||||
else
|
else
|
||||||
|
@ -82,23 +77,25 @@ deployAlgo() {
|
||||||
getAlgo
|
getAlgo
|
||||||
|
|
||||||
cd /opt/algo
|
cd /opt/algo
|
||||||
|
# shellcheck source=/dev/null
|
||||||
. .venv/bin/activate
|
. .venv/bin/activate
|
||||||
|
|
||||||
export HOME=/root
|
export HOME=/root
|
||||||
export ANSIBLE_LOCAL_TEMP=/root/.ansible/tmp
|
export ANSIBLE_LOCAL_TEMP=/root/.ansible/tmp
|
||||||
export ANSIBLE_REMOTE_TEMP=/root/.ansible/tmp
|
export ANSIBLE_REMOTE_TEMP=/root/.ansible/tmp
|
||||||
|
|
||||||
|
# shellcheck disable=SC2086
|
||||||
ansible-playbook main.yml \
|
ansible-playbook main.yml \
|
||||||
-e provider=local \
|
-e provider=local \
|
||||||
-e ondemand_cellular=${ONDEMAND_CELLULAR} \
|
-e "ondemand_cellular=${ONDEMAND_CELLULAR}" \
|
||||||
-e ondemand_wifi=${ONDEMAND_WIFI} \
|
-e "ondemand_wifi=${ONDEMAND_WIFI}" \
|
||||||
-e ondemand_wifi_exclude=${ONDEMAND_WIFI_EXCLUDE} \
|
-e "ondemand_wifi_exclude=${ONDEMAND_WIFI_EXCLUDE}" \
|
||||||
-e windows=${WINDOWS} \
|
-e "windows=${WINDOWS}" \
|
||||||
-e store_cakey=${STORE_CAKEY} \
|
-e "store_cakey=${STORE_CAKEY}" \
|
||||||
-e local_dns=${LOCAL_DNS} \
|
-e "local_dns=${LOCAL_DNS}" \
|
||||||
-e ssh_tunneling=${SSH_TUNNELING} \
|
-e "ssh_tunneling=${SSH_TUNNELING}" \
|
||||||
-e endpoint=$ENDPOINT \
|
-e "endpoint=$ENDPOINT" \
|
||||||
-e users=$(echo "$USERS" | jq -Rc 'split(",")') \
|
-e "users=$(echo "$USERS" | jq -Rc 'split(",")')" \
|
||||||
-e server=localhost \
|
-e server=localhost \
|
||||||
-e ssh_user=root \
|
-e ssh_user=root \
|
||||||
-e "${EXTRA_VARS}" \
|
-e "${EXTRA_VARS}" \
|
||||||
|
@ -106,7 +103,7 @@ deployAlgo() {
|
||||||
tee /var/log/algo.log
|
tee /var/log/algo.log
|
||||||
}
|
}
|
||||||
|
|
||||||
if test $METHOD = "cloud"; then
|
if test "$METHOD" = "cloud"; then
|
||||||
publicIpFromMetadata
|
publicIpFromMetadata
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
11
main.yml
11
main.yml
|
@ -1,4 +1,15 @@
|
||||||
---
|
---
|
||||||
|
- hosts: localhost
|
||||||
|
become: false
|
||||||
|
tasks:
|
||||||
|
- name: Verify Ansible meets Drupal VM's version requirements.
|
||||||
|
assert:
|
||||||
|
that: "ansible_version.full is version('2.7.10', '==')"
|
||||||
|
msg: >
|
||||||
|
Ansible version is {{ ansible_version.full }}.
|
||||||
|
You must update the requirements to use this version of Algo.
|
||||||
|
Try to run python -m pip install -U -r requirements.txt
|
||||||
|
|
||||||
- name: Include prompts playbook
|
- name: Include prompts playbook
|
||||||
import_playbook: input.yml
|
import_playbook: input.yml
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
---
|
---
|
||||||
|
- block:
|
||||||
- name: Display the invocation environment
|
- name: Display the invocation environment
|
||||||
local_action:
|
shell: >
|
||||||
module: shell
|
|
||||||
./algo-showenv.sh \
|
./algo-showenv.sh \
|
||||||
'algo_provider "{{ algo_provider }}"' \
|
'algo_provider "{{ algo_provider }}"' \
|
||||||
'algo_ondemand_cellular "{{ algo_ondemand_cellular }}"' \
|
'algo_ondemand_cellular "{{ algo_ondemand_cellular }}"' \
|
||||||
|
@ -16,14 +16,17 @@
|
||||||
tags: debug
|
tags: debug
|
||||||
|
|
||||||
- name: Install the requirements
|
- name: Install the requirements
|
||||||
local_action:
|
pip:
|
||||||
module: pip
|
|
||||||
state: latest
|
state: latest
|
||||||
name:
|
name:
|
||||||
- pyOpenSSL
|
- pyOpenSSL
|
||||||
- jinja2==2.8
|
- jinja2==2.8
|
||||||
- segno
|
- segno
|
||||||
tags: always
|
tags:
|
||||||
|
- always
|
||||||
|
- skip_ansible_lint
|
||||||
|
delegate_to: localhost
|
||||||
|
become: false
|
||||||
|
|
||||||
- name: Generate the SSH private key
|
- name: Generate the SSH private key
|
||||||
openssl_privatekey:
|
openssl_privatekey:
|
||||||
|
|
|
@ -2,4 +2,5 @@
|
||||||
- debug:
|
- debug:
|
||||||
var: fail_hint
|
var: fail_hint
|
||||||
|
|
||||||
- fail:
|
- name: Fail the installation
|
||||||
|
fail:
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
ansible==2.5.2
|
ansible==2.7.10
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
---
|
---
|
||||||
|
|
||||||
- name: restart strongswan
|
- name: restart strongswan
|
||||||
service: name=strongswan state=restarted
|
service: name=strongswan state=restarted
|
||||||
|
|
|
@ -8,13 +8,21 @@
|
||||||
package: name="{{ item }}" state=present
|
package: name="{{ item }}" state=present
|
||||||
with_items:
|
with_items:
|
||||||
- "{{ prerequisites }}"
|
- "{{ prerequisites }}"
|
||||||
|
register: result
|
||||||
|
until: result is succeeded
|
||||||
|
retries: 10
|
||||||
|
delay: 3
|
||||||
|
|
||||||
- name: Install strongSwan
|
- name: Install strongSwan
|
||||||
package: name=strongswan state=present
|
package: name=strongswan state=present
|
||||||
|
register: result
|
||||||
|
until: result is succeeded
|
||||||
|
retries: 10
|
||||||
|
delay: 3
|
||||||
|
|
||||||
- name: Setup the ipsec config
|
- name: Setup the ipsec config
|
||||||
template:
|
template:
|
||||||
src: "roles/vpn/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:
|
||||||
|
@ -24,7 +32,7 @@
|
||||||
|
|
||||||
- name: Setup the ipsec secrets
|
- name: Setup the ipsec secrets
|
||||||
template:
|
template:
|
||||||
src: "roles/vpn/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:
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
|
- name: Set OS specific facts
|
||||||
- set_fact:
|
set_fact:
|
||||||
prerequisites:
|
prerequisites:
|
||||||
- epel-release
|
- epel-release
|
||||||
configs_prefix: /etc/strongswan
|
configs_prefix: /etc/strongswan
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
---
|
---
|
||||||
|
- name: Set OS specific facts
|
||||||
- set_fact:
|
set_fact:
|
||||||
prerequisites: []
|
prerequisites:
|
||||||
|
- libstrongswan-standard-plugins
|
||||||
configs_prefix: /etc
|
configs_prefix: /etc
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
|
- name: Set OS specific facts
|
||||||
- set_fact:
|
set_fact:
|
||||||
prerequisites:
|
prerequisites:
|
||||||
- libselinux-python
|
- libselinux-python
|
||||||
configs_prefix: /etc/strongswan
|
configs_prefix: /etc/strongswan
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
---
|
---
|
||||||
|
- name: Set OS specific facts
|
||||||
- set_fact:
|
set_fact:
|
||||||
prerequisites: []
|
prerequisites:
|
||||||
|
- libstrongswan-standard-plugins
|
||||||
configs_prefix: /etc
|
configs_prefix: /etc
|
||||||
|
|
|
@ -9,14 +9,14 @@
|
||||||
- set_fact:
|
- set_fact:
|
||||||
algo_region: >-
|
algo_region: >-
|
||||||
{% if region is defined %}{{ region }}
|
{% if region is defined %}{{ region }}
|
||||||
{%- elif _algo_region.user_input is defined and _algo_region.user_input != "" %}{{ azure_regions[_algo_region.user_input | int -1 ]['name'] }}
|
{%- elif _algo_region.user_input %}{{ azure_regions[_algo_region.user_input | int -1 ]['name'] }}
|
||||||
{%- else %}{{ azure_regions[default_region | int - 1]['name'] }}{% endif %}
|
{%- else %}{{ azure_regions[default_region | int - 1]['name'] }}{% endif %}
|
||||||
|
|
||||||
- name: Create AlgoVPN Server
|
- name: Create AlgoVPN Server
|
||||||
azure_rm_deployment:
|
azure_rm_deployment:
|
||||||
state: present
|
state: present
|
||||||
deployment_name: "{{ algo_server_name }}"
|
deployment_name: "{{ algo_server_name }}"
|
||||||
template: "{{ lookup('file', 'deployment.json') }}"
|
template: "{{ lookup('file', role_path + '/files/deployment.json') }}"
|
||||||
secret: "{{ secret }}"
|
secret: "{{ secret }}"
|
||||||
tenant: "{{ tenant }}"
|
tenant: "{{ tenant }}"
|
||||||
client_id: "{{ client_id }}"
|
client_id: "{{ client_id }}"
|
||||||
|
|
|
@ -10,23 +10,32 @@
|
||||||
name:
|
name:
|
||||||
- packaging
|
- packaging
|
||||||
- requests[security]
|
- requests[security]
|
||||||
- azure-mgmt-compute>=2.0.0,<3
|
- azure-cli-core==2.0.35
|
||||||
- azure-mgmt-network>=1.3.0,<2
|
- azure-cli-nspkg==3.0.2
|
||||||
- azure-mgmt-storage>=1.5.0,<2
|
- azure-common==1.1.11
|
||||||
- azure-mgmt-resource>=1.1.0,<2
|
- azure-mgmt-batch==4.1.0
|
||||||
- azure-storage>=0.35.1,<0.36
|
- azure-mgmt-compute==2.1.0
|
||||||
- azure-cli-core>=2.0.12,<3
|
- azure-mgmt-containerinstance==0.4.0
|
||||||
|
- azure-mgmt-containerregistry==2.0.0
|
||||||
|
- azure-mgmt-containerservice==3.0.1
|
||||||
|
- azure-mgmt-dns==1.2.0
|
||||||
|
- azure-mgmt-keyvault==0.40.0
|
||||||
|
- azure-mgmt-marketplaceordering==0.1.0
|
||||||
|
- azure-mgmt-monitor==0.5.2
|
||||||
|
- azure-mgmt-network==1.7.1
|
||||||
|
- azure-mgmt-nspkg==2.0.0
|
||||||
|
- azure-mgmt-rdbms==1.2.0
|
||||||
|
- azure-mgmt-resource==1.2.2
|
||||||
|
- azure-mgmt-sql==0.7.1
|
||||||
|
- azure-mgmt-storage==1.5.0
|
||||||
|
- azure-mgmt-trafficmanager==0.50.0
|
||||||
|
- azure-mgmt-web==0.32.0
|
||||||
|
- azure-nspkg==2.0.0
|
||||||
|
- azure-storage==0.35.1
|
||||||
- msrest==0.4.29
|
- msrest==0.4.29
|
||||||
- msrestazure==0.4.31
|
- msrestazure==0.4.31
|
||||||
- azure-mgmt-dns>=1.0.1,<2
|
- azure-keyvault==1.0.0a1
|
||||||
- azure-mgmt-keyvault>=0.40.0,<0.41
|
- azure-graphrbac==0.40.0
|
||||||
- azure-mgmt-batch>=4.1.0,<5
|
|
||||||
- azure-mgmt-sql>=0.7.1,<0.8
|
|
||||||
- azure-mgmt-web>=0.32.0,<0.33
|
|
||||||
- azure-mgmt-containerservice>=2.0.0,<3.0.0
|
|
||||||
- azure-mgmt-containerregistry>=1.0.1
|
|
||||||
- azure-mgmt-rdbms==1.2.0
|
|
||||||
- azure-mgmt-containerinstance==0.4.0
|
|
||||||
state: latest
|
state: latest
|
||||||
virtualenv: "{{ azure_venv }}"
|
virtualenv: "{{ azure_venv }}"
|
||||||
virtualenv_python: python2.7
|
virtualenv_python: python2.7
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
set_fact:
|
set_fact:
|
||||||
algo_do_region: >-
|
algo_do_region: >-
|
||||||
{% if region is defined %}{{ region }}
|
{% if region is defined %}{{ region }}
|
||||||
{%- elif _algo_region.user_input is defined and _algo_region.user_input != "" %}{{ do_regions[_algo_region.user_input | int -1 ]['slug'] }}
|
{%- elif _algo_region.user_input %}{{ do_regions[_algo_region.user_input | int -1 ]['slug'] }}
|
||||||
{%- else %}{{ do_regions[default_region | int - 1]['slug'] }}{% endif %}
|
{%- else %}{{ do_regions[default_region | int - 1]['slug'] }}{% endif %}
|
||||||
public_key: "{{ lookup('file', '{{ SSH_keys.public }}') }}"
|
public_key: "{{ lookup('file', '{{ SSH_keys.public }}') }}"
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@
|
||||||
api_token: "{{ algo_do_token }}"
|
api_token: "{{ algo_do_token }}"
|
||||||
name: "{{ SSH_keys.comment }}"
|
name: "{{ SSH_keys.comment }}"
|
||||||
register: ssh_keys
|
register: ssh_keys
|
||||||
until: ssh_keys.changed != true
|
until: not ssh_keys.changed
|
||||||
retries: 10
|
retries: 10
|
||||||
delay: 1
|
delay: 1
|
||||||
|
|
||||||
|
@ -83,7 +83,7 @@
|
||||||
api_token: "{{ algo_do_token }}"
|
api_token: "{{ algo_do_token }}"
|
||||||
name: "{{ SSH_keys.comment }}"
|
name: "{{ SSH_keys.comment }}"
|
||||||
register: ssh_keys
|
register: ssh_keys
|
||||||
until: ssh_keys.changed != true
|
until: not ssh_keys.changed
|
||||||
retries: 10
|
retries: 10
|
||||||
delay: 1
|
delay: 1
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
stack_name: "{{ stack_name }}"
|
stack_name: "{{ stack_name }}"
|
||||||
state: "present"
|
state: "present"
|
||||||
region: "{{ algo_region }}"
|
region: "{{ algo_region }}"
|
||||||
template: roles/cloud-ec2/files/stack.yml
|
template: roles/cloud-ec2/files/stack.yaml
|
||||||
template_parameters:
|
template_parameters:
|
||||||
InstanceTypeParameter: "{{ cloud_providers.ec2.size }}"
|
InstanceTypeParameter: "{{ cloud_providers.ec2.size }}"
|
||||||
PublicSSHKeyParameter: "{{ lookup('file', SSH_keys.public) }}"
|
PublicSSHKeyParameter: "{{ lookup('file', SSH_keys.public) }}"
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
- set_fact:
|
- set_fact:
|
||||||
algo_region: >-
|
algo_region: >-
|
||||||
{% if region is defined %}{{ region }}
|
{% if region is defined %}{{ region }}
|
||||||
{%- elif _algo_region.user_input is defined and _algo_region.user_input != "" %}{{ aws_regions[_algo_region.user_input | int -1 ]['region_name'] }}
|
{%- elif _algo_region.user_input %}{{ aws_regions[_algo_region.user_input | int -1 ]['region_name'] }}
|
||||||
{%- else %}{{ aws_regions[default_region | int - 1]['region_name'] }}{% endif %}
|
{%- else %}{{ aws_regions[default_region | int - 1]['region_name'] }}{% endif %}
|
||||||
stack_name: "{{ algo_server_name | replace('.', '-') }}"
|
stack_name: "{{ algo_server_name | replace('.', '-') }}"
|
||||||
|
|
||||||
|
|
|
@ -63,5 +63,5 @@
|
||||||
- set_fact:
|
- set_fact:
|
||||||
algo_region: >-
|
algo_region: >-
|
||||||
{% if region is defined %}{{ region }}
|
{% if region is defined %}{{ region }}
|
||||||
{%- elif _gce_region.user_input is defined and _gce_region.user_input != "" %}{{ gce_regions[_gce_region.user_input | int -1 ] }}
|
{%- elif _gce_region.user_input %}{{ gce_regions[_gce_region.user_input | int -1 ] }}
|
||||||
{%- else %}{{ gce_regions[default_region | int - 1] }}{% endif %}
|
{%- else %}{{ gce_regions[default_region | int - 1] }}{% endif %}
|
||||||
|
|
|
@ -57,5 +57,5 @@
|
||||||
- set_fact:
|
- set_fact:
|
||||||
algo_region: >-
|
algo_region: >-
|
||||||
{% if region is defined %}{{ region }}
|
{% if region is defined %}{{ region }}
|
||||||
{%- elif _algo_region.user_input is defined and _algo_region.user_input != "" %}{{ lightsail_regions[_algo_region.user_input | int -1 ]['name'] }}
|
{%- elif _algo_region.user_input %}{{ lightsail_regions[_algo_region.user_input | int -1 ]['name'] }}
|
||||||
{%- else %}{{ lightsail_regions[default_region | int - 1]['name'] }}{% endif %}
|
{%- else %}{{ lightsail_regions[default_region | int - 1]['name'] }}{% endif %}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
---
|
---
|
||||||
- fail:
|
- fail:
|
||||||
msg: "OpenStack credentials are not set. Download it from the OpenStack dashboard->Compute->API Access and source it in the shell (eg: source /tmp/dhc-openrc.sh)"
|
msg: "OpenStack credentials are not set. Download it from the OpenStack dashboard->Compute->API Access and source it in the shell (eg: source /tmp/dhc-openrc.sh)"
|
||||||
when: lookup('env', 'OS_AUTH_URL') == ""
|
when: lookup('env', 'OS_AUTH_URL')|length <= 0
|
||||||
|
|
||||||
- name: Build python virtual environment
|
- name: Build python virtual environment
|
||||||
import_tasks: venv.yml
|
import_tasks: venv.yml
|
||||||
|
|
|
@ -30,5 +30,5 @@
|
||||||
algo_scaleway_org: "{{ scaleway_org | default(_scaleway_org.user_input|default(omit)) }}"
|
algo_scaleway_org: "{{ scaleway_org | default(_scaleway_org.user_input|default(omit)) }}"
|
||||||
algo_region: >-
|
algo_region: >-
|
||||||
{% if region is defined %}{{ region }}
|
{% if region is defined %}{{ region }}
|
||||||
{%- elif _algo_region.user_input is defined and _algo_region.user_input != "" %}{{ scaleway_regions[_algo_region.user_input | int -1 ]['alias'] }}
|
{%- elif _algo_region.user_input %}{{ scaleway_regions[_algo_region.user_input | int -1 ]['alias'] }}
|
||||||
{%- else %}{{ scaleway_regions.0.alias }}{% endif %}
|
{%- else %}{{ scaleway_regions.0.alias }}{% endif %}
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
---
|
---
|
||||||
- block:
|
|
||||||
- name: Include prompts
|
- name: Include prompts
|
||||||
import_tasks: prompts.yml
|
import_tasks: prompts.yml
|
||||||
|
|
||||||
|
- block:
|
||||||
- name: Upload the SSH key
|
- name: Upload the SSH key
|
||||||
vr_ssh_key:
|
vultr_ssh_key:
|
||||||
name: "{{ SSH_keys.comment }}"
|
name: "{{ SSH_keys.comment }}"
|
||||||
ssh_key: "{{ lookup('file', '{{ SSH_keys.public }}') }}"
|
ssh_key: "{{ lookup('file', '{{ SSH_keys.public }}') }}"
|
||||||
register: ssh_key
|
register: ssh_key
|
||||||
|
|
||||||
- name: Creating a server
|
- name: Creating a server
|
||||||
vr_server:
|
vultr_server:
|
||||||
name: "{{ algo_server_name }}"
|
name: "{{ algo_server_name }}"
|
||||||
hostname: "{{ algo_server_name }}"
|
hostname: "{{ algo_server_name }}"
|
||||||
os: "{{ cloud_providers.vultr.os }}"
|
os: "{{ cloud_providers.vultr.os }}"
|
||||||
|
|
|
@ -54,5 +54,5 @@
|
||||||
set_fact:
|
set_fact:
|
||||||
algo_vultr_region: >-
|
algo_vultr_region: >-
|
||||||
{% if region is defined %}{{ region }}
|
{% if region is defined %}{{ region }}
|
||||||
{%- elif _algo_region.user_input is defined and _algo_region.user_input != "" %}{{ vultr_regions[_algo_region.user_input | int -1 ]['name'] }}
|
{%- elif _algo_region.user_input %}{{ vultr_regions[_algo_region.user_input | int -1 ]['name'] }}
|
||||||
{%- else %}{{ vultr_regions[default_region | int - 1]['name'] }}{% endif %}
|
{%- else %}{{ vultr_regions[default_region | int - 1]['name'] }}{% endif %}
|
||||||
|
|
|
@ -20,8 +20,5 @@
|
||||||
ifconfig lo100 inet {{ local_service_ip }} netmask 255.255.255.255 &&
|
ifconfig lo100 inet {{ local_service_ip }} netmask 255.255.255.255 &&
|
||||||
ifconfig lo100 inet6 FCAA::1/64; echo $?
|
ifconfig lo100 inet6 FCAA::1/64; echo $?
|
||||||
|
|
||||||
- name: save iptables
|
|
||||||
shell: service netfilter-persistent save
|
|
||||||
|
|
||||||
- name: restart iptables
|
- name: restart iptables
|
||||||
service: name=netfilter-persistent state=restarted
|
service: name=netfilter-persistent state=restarted
|
||||||
|
|
|
@ -1,26 +1,26 @@
|
||||||
---
|
---
|
||||||
- block:
|
- block:
|
||||||
- name: Generate password for the CA key
|
- name: Generate password for the CA key
|
||||||
local_action:
|
command: openssl rand -hex 16
|
||||||
module: shell
|
|
||||||
openssl rand -hex 16
|
|
||||||
register: CA_password
|
register: CA_password
|
||||||
|
|
||||||
- name: Generate p12 export password
|
- name: Generate p12 export password
|
||||||
local_action:
|
shell: >
|
||||||
module: shell
|
openssl rand 8 |
|
||||||
openssl rand 8 | python -c 'import sys,string; chars=string.ascii_letters + string.digits + "_@"; print("".join([chars[ord(c) % 64] for c in list(sys.stdin.read())]))'
|
python -c 'import sys,string; chars=string.ascii_letters + string.digits + "_@"; print("".join([chars[ord(c) % 64] for c in list(sys.stdin.read())]))'
|
||||||
register: p12_password_generated
|
register: p12_password_generated
|
||||||
when: p12_password is not defined
|
when: p12_password is not defined
|
||||||
tags: update-users
|
tags: update-users
|
||||||
become: false
|
become: false
|
||||||
|
delegate_to: localhost
|
||||||
|
|
||||||
- name: Define facts
|
- name: Define facts
|
||||||
set_fact:
|
set_fact:
|
||||||
p12_export_password: "{{ p12_password|default(p12_password_generated.stdout) }}"
|
p12_export_password: "{{ p12_password|default(p12_password_generated.stdout) }}"
|
||||||
tags: update-users
|
tags: update-users
|
||||||
|
|
||||||
- set_fact:
|
- name: Set facts
|
||||||
|
set_fact:
|
||||||
CA_password: "{{ CA_password.stdout }}"
|
CA_password: "{{ CA_password.stdout }}"
|
||||||
IP_subject_alt_name: "{{ IP_subject_alt_name }}"
|
IP_subject_alt_name: "{{ IP_subject_alt_name }}"
|
||||||
|
|
||||||
|
@ -31,5 +31,5 @@
|
||||||
|
|
||||||
- name: Check size of MTU
|
- name: Check size of MTU
|
||||||
set_fact:
|
set_fact:
|
||||||
reduce_mtu: "{% if reduce_mtu|int == 0 and ansible_default_ipv4['mtu']|int < 1500 %}{{ 1500 - ansible_default_ipv4['mtu']|int }}{% else %}{{ reduce_mtu|int }}{% endif %}"
|
reduce_mtu: "{{ 1500 - ansible_default_ipv4['mtu']|int if reduce_mtu|int == 0 and ansible_default_ipv4['mtu']|int < 1500 else reduce_mtu|int }}"
|
||||||
tags: always
|
tags: always
|
||||||
|
|
|
@ -17,7 +17,8 @@
|
||||||
- name: Gather additional facts
|
- name: Gather additional facts
|
||||||
import_tasks: facts.yml
|
import_tasks: facts.yml
|
||||||
|
|
||||||
- set_fact:
|
- name: Set OS specific facts
|
||||||
|
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
|
||||||
|
@ -73,5 +74,6 @@
|
||||||
shell: >
|
shell: >
|
||||||
kldstat -n ipfw.ko || kldload ipfw ; sysctl net.inet.ip.fw.enable=0 &&
|
kldstat -n ipfw.ko || kldload ipfw ; sysctl net.inet.ip.fw.enable=0 &&
|
||||||
bash /etc/rc.firewall && sysctl net.inet.ip.fw.enable=1
|
bash /etc/rc.firewall && sysctl net.inet.ip.fw.enable=1
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
- meta: flush_handlers
|
- meta: flush_handlers
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
- name: Check the system
|
- name: Check the system
|
||||||
raw: uname -a
|
raw: uname -a
|
||||||
register: OS
|
register: OS
|
||||||
|
changed_when: false
|
||||||
tags:
|
tags:
|
||||||
- update-users
|
- update-users
|
||||||
|
|
||||||
|
@ -17,7 +18,7 @@
|
||||||
|
|
||||||
- name: Sysctl tuning
|
- name: Sysctl tuning
|
||||||
sysctl: name="{{ item.item }}" value="{{ item.value }}"
|
sysctl: name="{{ item.item }}" value="{{ item.value }}"
|
||||||
when: item.item != ""
|
when: item.item
|
||||||
with_items:
|
with_items:
|
||||||
- "{{ sysctl|default([]) }}"
|
- "{{ sysctl|default([]) }}"
|
||||||
tags:
|
tags:
|
||||||
|
|
|
@ -25,8 +25,7 @@
|
||||||
ignore_errors: true
|
ignore_errors: true
|
||||||
|
|
||||||
- name: Wait until SSH becomes ready...
|
- name: Wait until SSH becomes ready...
|
||||||
local_action:
|
wait_for:
|
||||||
module: wait_for
|
|
||||||
port: 22
|
port: 22
|
||||||
host: "{{ inventory_hostname }}"
|
host: "{{ inventory_hostname }}"
|
||||||
search_regex: OpenSSH
|
search_regex: OpenSSH
|
||||||
|
@ -34,6 +33,7 @@
|
||||||
timeout: 320
|
timeout: 320
|
||||||
when: reboot_required is defined and reboot_required.stdout == 'required'
|
when: reboot_required is defined and reboot_required.stdout == 'required'
|
||||||
become: false
|
become: false
|
||||||
|
delegate_to: localhost
|
||||||
when: algo_provider != "local"
|
when: algo_provider != "local"
|
||||||
|
|
||||||
- name: Include unatteded upgrades configuration
|
- name: Include unatteded upgrades configuration
|
||||||
|
@ -65,18 +65,21 @@
|
||||||
- meta: flush_handlers
|
- meta: flush_handlers
|
||||||
|
|
||||||
- name: Check apparmor support
|
- name: Check apparmor support
|
||||||
shell: apparmor_status
|
command: apparmor_status
|
||||||
ignore_errors: yes
|
ignore_errors: yes
|
||||||
|
changed_when: false
|
||||||
register: apparmor_status
|
register: apparmor_status
|
||||||
|
|
||||||
- set_fact:
|
- name: Set fact if apparmor enabled
|
||||||
|
set_fact:
|
||||||
apparmor_enabled: true
|
apparmor_enabled: true
|
||||||
when: '"profiles are in enforce mode" in apparmor_status.stdout'
|
when: '"profiles are in enforce mode" in apparmor_status.stdout'
|
||||||
|
|
||||||
- name: Gather additional facts
|
- name: Gather additional facts
|
||||||
import_tasks: facts.yml
|
import_tasks: facts.yml
|
||||||
|
|
||||||
- set_fact:
|
- name: Set OS specific facts
|
||||||
|
set_fact:
|
||||||
tools:
|
tools:
|
||||||
- git
|
- git
|
||||||
- screen
|
- screen
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
- name: Install unattended-upgrades
|
- name: Install unattended-upgrades
|
||||||
apt:
|
apt:
|
||||||
name: unattended-upgrades
|
name: unattended-upgrades
|
||||||
state: latest
|
state: present
|
||||||
|
|
||||||
- name: Configure unattended-upgrades
|
- name: Configure unattended-upgrades
|
||||||
template:
|
template:
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
|
|
||||||
- name: Update adblock hosts
|
- name: Update adblock hosts
|
||||||
command: /usr/local/sbin/adblock.sh
|
command: /usr/local/sbin/adblock.sh
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
- meta: flush_handlers
|
- meta: flush_handlers
|
||||||
|
|
||||||
|
|
|
@ -7,13 +7,13 @@
|
||||||
owner: root
|
owner: root
|
||||||
group: root
|
group: root
|
||||||
mode: 0600
|
mode: 0600
|
||||||
when: apparmor_enabled|default(false)|bool == true
|
when: apparmor_enabled|default(false)|bool
|
||||||
notify:
|
notify:
|
||||||
- restart dnsmasq
|
- restart dnsmasq
|
||||||
|
|
||||||
- name: Ubuntu | Enforce the dnsmasq AppArmor policy
|
- name: Ubuntu | Enforce the dnsmasq AppArmor policy
|
||||||
shell: aa-enforce usr.sbin.dnsmasq
|
command: aa-enforce usr.sbin.dnsmasq
|
||||||
when: apparmor_enabled|default(false)|bool == true
|
when: apparmor_enabled|default(false)|bool
|
||||||
tags: ['apparmor']
|
tags: ['apparmor']
|
||||||
|
|
||||||
- name: Ubuntu | Ensure that the dnsmasq service directory exist
|
- name: Ubuntu | Ensure that the dnsmasq service directory exist
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
- name: Install dnscrypt-proxy
|
- name: Install dnscrypt-proxy
|
||||||
apt:
|
apt:
|
||||||
name: dnscrypt-proxy
|
name: dnscrypt-proxy
|
||||||
state: latest
|
state: present
|
||||||
update_cache: true
|
update_cache: true
|
||||||
|
|
||||||
- name: Configure unattended-upgrades
|
- name: Configure unattended-upgrades
|
||||||
|
@ -37,7 +37,7 @@
|
||||||
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 == true
|
when: apparmor_enabled|default(false)|bool
|
||||||
|
|
||||||
- name: Ubuntu | Ensure that the dnscrypt-proxy service directory exist
|
- name: Ubuntu | Ensure that the dnscrypt-proxy service directory exist
|
||||||
file:
|
file:
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
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 is defined and _algo_server.user_input != "" %}{{ _algo_server.user_input }}
|
{%- elif _algo_server.user_input %}{{ _algo_server.user_input }}
|
||||||
{%- else %}localhost{% endif %}
|
{%- else %}localhost{% endif %}
|
||||||
|
|
||||||
- pause:
|
- pause:
|
||||||
|
@ -26,7 +26,7 @@
|
||||||
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 is defined and _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 %}
|
||||||
|
|
||||||
- pause:
|
- pause:
|
||||||
|
@ -40,5 +40,5 @@
|
||||||
set_fact:
|
set_fact:
|
||||||
IP_subject_alt_name: >-
|
IP_subject_alt_name: >-
|
||||||
{% if endpoint is defined %}{{ endpoint }}
|
{% if endpoint is defined %}{{ endpoint }}
|
||||||
{%- elif _endpoint.user_input is defined and _endpoint.user_input != "" %}{{ _endpoint.user_input }}
|
{%- elif _endpoint.user_input %}{{ _endpoint.user_input }}
|
||||||
{%- else %}{{ cloud_instance_ip }}{% endif %}
|
{%- else %}{{ cloud_instance_ip }}{% endif %}
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
file:
|
file:
|
||||||
dest: "{{ ssh_tunnels_config_path }}"
|
dest: "{{ ssh_tunnels_config_path }}"
|
||||||
state: absent
|
state: absent
|
||||||
when: keys_clean_all|bool == True
|
when: keys_clean_all|bool
|
||||||
|
|
||||||
- name: Ensure the config directories exist
|
- name: Ensure the config directories exist
|
||||||
file:
|
file:
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
service: name=strongswan state=restarted
|
service: name=strongswan state=restarted
|
||||||
|
|
||||||
- name: daemon-reload
|
- name: daemon-reload
|
||||||
shell: systemctl daemon-reload
|
systemd: daemon_reload=true
|
||||||
|
|
||||||
- name: restart apparmor
|
- name: restart apparmor
|
||||||
service: name=apparmor state=restarted
|
service: name=apparmor state=restarted
|
||||||
|
|
|
@ -1,8 +1,13 @@
|
||||||
---
|
---
|
||||||
- name: Register p12 PayloadContent
|
- name: Register p12 PayloadContent
|
||||||
shell: cat private/{{ item }}.p12 | base64
|
shell: |
|
||||||
|
set -o pipefail
|
||||||
|
cat private/{{ item }}.p12 |
|
||||||
|
base64
|
||||||
register: PayloadContent
|
register: PayloadContent
|
||||||
|
changed_when: false
|
||||||
args:
|
args:
|
||||||
|
executable: bash
|
||||||
chdir: "{{ ipsec_pki_path }}"
|
chdir: "{{ ipsec_pki_path }}"
|
||||||
with_items: "{{ users }}"
|
with_items: "{{ users }}"
|
||||||
|
|
||||||
|
|
|
@ -32,8 +32,13 @@
|
||||||
- restart strongswan
|
- restart strongswan
|
||||||
|
|
||||||
- name: Get loaded plugins
|
- name: Get loaded plugins
|
||||||
shell: >
|
shell: |
|
||||||
find {{ config_prefix|default('/') }}etc/strongswan.d/charon/ -type f -name '*.conf' -exec basename {} \; | cut -f1 -d.
|
set -o pipefail
|
||||||
|
find {{ config_prefix|default('/') }}etc/strongswan.d/charon/ -type f -name '*.conf' -exec basename {} \; |
|
||||||
|
cut -f1 -d.
|
||||||
|
changed_when: false
|
||||||
|
args:
|
||||||
|
executable: bash
|
||||||
register: strongswan_plugins
|
register: strongswan_plugins
|
||||||
|
|
||||||
- name: Disable unneeded plugins
|
- name: Disable unneeded plugins
|
||||||
|
|
|
@ -2,14 +2,19 @@
|
||||||
- block:
|
- block:
|
||||||
- name: Set subjectAltName as a fact
|
- name: Set subjectAltName as a fact
|
||||||
set_fact:
|
set_fact:
|
||||||
subjectAltName: "{{ subjectAltName_IP }}{% if ipv6_support %},IP:{{ ansible_default_ipv6['address'] }}{% endif %}{% if domain and subjectAltName_DNS %},DNS:{{ subjectAltName_DNS }}{% endif %}"
|
subjectAltName: >-
|
||||||
|
{{ subjectAltName_IP }}
|
||||||
|
{%- if ipv6_support -%},IP:{{ ansible_default_ipv6['address'] }}{%- endif -%}
|
||||||
|
{%- if domain and subjectAltName_DNS -%},DNS:{{ subjectAltName_DNS }}{%- endif -%}
|
||||||
tags: always
|
tags: always
|
||||||
|
|
||||||
|
- 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 == True
|
when: keys_clean_all|bool
|
||||||
|
|
||||||
- name: Ensure the pki directories exist
|
- name: Ensure the pki directories exist
|
||||||
file:
|
file:
|
||||||
|
@ -228,11 +233,11 @@
|
||||||
- rereadcrls
|
- rereadcrls
|
||||||
|
|
||||||
- name: Delete the CA key
|
- name: Delete the CA key
|
||||||
local_action:
|
file:
|
||||||
module: file
|
|
||||||
path: "{{ ipsec_pki_path }}/private/cakey.pem"
|
path: "{{ ipsec_pki_path }}/private/cakey.pem"
|
||||||
state: absent
|
state: absent
|
||||||
become: false
|
become: false
|
||||||
|
delegate_to: localhost
|
||||||
when:
|
when:
|
||||||
- ipsec_enabled
|
- ipsec_enabled
|
||||||
- not algo_store_cakey
|
- not algo_store_cakey
|
||||||
|
|
|
@ -1,18 +1,19 @@
|
||||||
---
|
---
|
||||||
|
- 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: latest
|
state: present
|
||||||
update_cache: yes
|
update_cache: yes
|
||||||
install_recommends: yes
|
install_recommends: yes
|
||||||
|
|
||||||
- name: Ubuntu | Enforcing ipsec with apparmor
|
- name: Ubuntu | Enforcing ipsec with apparmor
|
||||||
shell: aa-enforce "{{ item }}"
|
command: aa-enforce "{{ item }}"
|
||||||
when: apparmor_enabled|default(false)|bool == true
|
when: apparmor_enabled|default(false)|bool
|
||||||
|
changed_when: false
|
||||||
with_items:
|
with_items:
|
||||||
- /usr/lib/ipsec/charon
|
- /usr/lib/ipsec/charon
|
||||||
- /usr/lib/ipsec/lookip
|
- /usr/lib/ipsec/lookip
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
conn ikev2-{{ IP_subject_alt_name }}
|
conn algovpn-{{ IP_subject_alt_name }}
|
||||||
fragmentation=yes
|
fragmentation=yes
|
||||||
rekey=no
|
rekey=no
|
||||||
dpdaction=clear
|
dpdaction=clear
|
||||||
|
@ -16,7 +16,7 @@ conn ikev2-{{ IP_subject_alt_name }}
|
||||||
|
|
||||||
right={{ IP_subject_alt_name }}
|
right={{ IP_subject_alt_name }}
|
||||||
rightid={{ IP_subject_alt_name }}
|
rightid={{ IP_subject_alt_name }}
|
||||||
rightsubnet=0.0.0.0/0
|
rightsubnet={{ rightsubnet | default('0.0.0.0/0') }}
|
||||||
rightauth=pubkey
|
rightauth=pubkey
|
||||||
|
|
||||||
leftsourceip=%config
|
leftsourceip=%config
|
||||||
|
|
|
@ -5,7 +5,7 @@ wireguard_pki_path: "{{ wireguard_config_path }}/.pki/"
|
||||||
wireguard_interface: wg0
|
wireguard_interface: wg0
|
||||||
keys_clean_all: false
|
keys_clean_all: false
|
||||||
wireguard_dns_servers: >-
|
wireguard_dns_servers: >-
|
||||||
{% if local_dns|default(false)|bool or dns_encryption|default(false)|bool == true %}
|
{% if local_dns|default(false)|bool or dns_encryption|default(false)|bool %}
|
||||||
{{ local_service_ip }}
|
{{ local_service_ip }}
|
||||||
{% 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 %}
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
name: wireguard
|
name: wireguard
|
||||||
state: present
|
state: present
|
||||||
|
|
||||||
- set_fact:
|
- name: Set OS specific facts
|
||||||
|
set_fact:
|
||||||
service_name: wireguard
|
service_name: wireguard
|
||||||
tags: always
|
tags: always
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
file:
|
file:
|
||||||
dest: "{{ config_prefix|default('/') }}etc/wireguard/private_{{ item }}.lock"
|
dest: "{{ config_prefix|default('/') }}etc/wireguard/private_{{ item }}.lock"
|
||||||
state: absent
|
state: absent
|
||||||
when: keys_clean_all|bool == True
|
when: keys_clean_all|bool
|
||||||
with_items:
|
with_items:
|
||||||
- "{{ users }}"
|
- "{{ users }}"
|
||||||
- "{{ IP_subject_alt_name }}"
|
- "{{ IP_subject_alt_name }}"
|
||||||
|
@ -39,7 +39,10 @@
|
||||||
when: wg_genkey.changed
|
when: wg_genkey.changed
|
||||||
|
|
||||||
- name: Generate public keys
|
- name: Generate public keys
|
||||||
shell: echo "{{ lookup('file', wireguard_pki_path + '/private/' + item) }}" | wg pubkey
|
shell: |
|
||||||
|
set -o pipefail
|
||||||
|
echo "{{ lookup('file', wireguard_pki_path + '/private/' + item) }}" |
|
||||||
|
wg pubkey
|
||||||
register: wg_pubkey
|
register: wg_pubkey
|
||||||
changed_when: false
|
changed_when: false
|
||||||
args:
|
args:
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
group: root
|
group: root
|
||||||
mode: 0644
|
mode: 0644
|
||||||
|
|
||||||
- set_fact:
|
- name: Set OS specific facts
|
||||||
|
set_fact:
|
||||||
service_name: "wg-quick@{{ wireguard_interface }}"
|
service_name: "wg-quick@{{ wireguard_interface }}"
|
||||||
tags: always
|
tags: always
|
||||||
|
|
|
@ -38,8 +38,7 @@
|
||||||
|
|
||||||
- block:
|
- block:
|
||||||
- name: Dump the configuration
|
- name: Dump the configuration
|
||||||
local_action:
|
copy:
|
||||||
module: copy
|
|
||||||
dest: "configs/{{ IP_subject_alt_name }}/.config.yml"
|
dest: "configs/{{ IP_subject_alt_name }}/.config.yml"
|
||||||
content: |
|
content: |
|
||||||
server: {{ 'localhost' if inventory_hostname == 'localhost' else inventory_hostname }}
|
server: {{ 'localhost' if inventory_hostname == 'localhost' else inventory_hostname }}
|
||||||
|
@ -59,8 +58,12 @@
|
||||||
IP_subject_alt_name: {{ IP_subject_alt_name }}
|
IP_subject_alt_name: {{ IP_subject_alt_name }}
|
||||||
ipsec_enabled: {{ ipsec_enabled }}
|
ipsec_enabled: {{ ipsec_enabled }}
|
||||||
wireguard_enabled: {{ wireguard_enabled }}
|
wireguard_enabled: {{ wireguard_enabled }}
|
||||||
{% if tests|default(false)|bool %}ca_password: {{ CA_password }}{% endif %}
|
{% if tests|default(false)|bool %}
|
||||||
|
ca_password: {{ CA_password }}
|
||||||
|
p12_password: {{ p12_export_password }}
|
||||||
|
{% endif %}
|
||||||
become: false
|
become: false
|
||||||
|
delegate_to: localhost
|
||||||
|
|
||||||
- name: Create a symlink if deploying to localhost
|
- name: Create a symlink if deploying to localhost
|
||||||
file:
|
file:
|
||||||
|
|
1
tests/algo.conf
Normal file
1
tests/algo.conf
Normal file
|
@ -0,0 +1 @@
|
||||||
|
dhcp-host=algo,10.0.8.100
|
|
@ -7,8 +7,9 @@ export ONDEMAND_WIFI_EXCLUDE=test1,test2
|
||||||
export WINDOWS=true
|
export WINDOWS=true
|
||||||
export STORE_CAKEY=true
|
export STORE_CAKEY=true
|
||||||
export LOCAL_DNS=true
|
export LOCAL_DNS=true
|
||||||
export ENDPOINT=algo.lxc
|
export SSH_TUNNELING=true
|
||||||
export USERS=user1,user2
|
export ENDPOINT=10.0.8.100
|
||||||
|
export USERS=desktop,user1,user2
|
||||||
export EXTRA_VARS='install_headers=false tests=true apparmor_enabled=false'
|
export EXTRA_VARS='install_headers=false tests=true apparmor_enabled=false'
|
||||||
export ANSIBLE_EXTRA_ARGS='--skip-tags apparmor'
|
export ANSIBLE_EXTRA_ARGS='--skip-tags apparmor'
|
||||||
export REPO_SLUG=${TRAVIS_PULL_REQUEST_SLUG:-${TRAVIS_REPO_SLUG:-trailofbits/algo}}
|
export REPO_SLUG=${TRAVIS_PULL_REQUEST_SLUG:-${TRAVIS_REPO_SLUG:-trailofbits/algo}}
|
||||||
|
|
23
tests/ipsec-client.sh
Executable file
23
tests/ipsec-client.sh
Executable file
|
@ -0,0 +1,23 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euxo pipefail
|
||||||
|
|
||||||
|
xmllint --noout ./configs/10.0.8.100/ipsec/apple/user1.mobileconfig
|
||||||
|
|
||||||
|
ansible-playbook deploy_client.yml \
|
||||||
|
-e client_ip=localhost \
|
||||||
|
-e vpn_user=desktop \
|
||||||
|
-e server_ip=10.0.8.100 \
|
||||||
|
-e rightsubnet='172.16.0.1/32'
|
||||||
|
|
||||||
|
ipsec up algovpn-10.0.8.100
|
||||||
|
|
||||||
|
ipsec statusall
|
||||||
|
|
||||||
|
ipsec statusall | grep -w ^algovpn-10.0.8.100 | grep -w ESTABLISHED
|
||||||
|
|
||||||
|
fping -t 900 -c3 -r3 -Dse 10.0.8.100 172.16.0.1
|
||||||
|
|
||||||
|
host google.com 172.16.0.1
|
||||||
|
|
||||||
|
echo "IPsec tests passed"
|
|
@ -2,11 +2,11 @@
|
||||||
|
|
||||||
set -ex
|
set -ex
|
||||||
|
|
||||||
DEPLOY_ARGS="provider=local server=$LXC_IP ssh_user=ubuntu endpoint=$LXC_IP apparmor_enabled=false ondemand_cellular=true ondemand_wifi=true ondemand_wifi_exclude=test local_dns=true ssh_tunneling=true windows=true store_cakey=true install_headers=false tests=true"
|
DEPLOY_ARGS="provider=local server=10.0.8.100 ssh_user=ubuntu endpoint=10.0.8.100 apparmor_enabled=false ondemand_cellular=true ondemand_wifi=true ondemand_wifi_exclude=test local_dns=true ssh_tunneling=true windows=true store_cakey=true install_headers=false tests=true"
|
||||||
|
|
||||||
if [ "${LXC_NAME}" == "docker" ]
|
if [ "${DEPLOY}" == "docker" ]
|
||||||
then
|
then
|
||||||
docker run -it -v $(pwd)/config.cfg:/algo/config.cfg -v ~/.ssh:/root/.ssh -v $(pwd)/configs:/algo/configs -e "DEPLOY_ARGS=${DEPLOY_ARGS}" travis/algo /bin/sh -c "chown -R 0:0 /root/.ssh && source env/bin/activate && ansible-playbook main.yml -e \"${DEPLOY_ARGS}\" --skip-tags apparmor"
|
docker run -it -v $(pwd)/config.cfg:/algo/config.cfg -v ~/.ssh:/root/.ssh -v $(pwd)/configs:/algo/configs -e "DEPLOY_ARGS=${DEPLOY_ARGS}" travis/algo /bin/sh -c "chown -R root: /root/.ssh && chmod -R 600 /root/.ssh && source env/bin/activate && ansible-playbook main.yml -e \"${DEPLOY_ARGS}\" --skip-tags apparmor"
|
||||||
else
|
else
|
||||||
ansible-playbook main.yml -e "${DEPLOY_ARGS}" --skip-tags apparmor
|
ansible-playbook main.yml -e "${DEPLOY_ARGS}" --skip-tags apparmor
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
USE_LXD_BRIDGE="true"
|
USE_LXD_BRIDGE="true"
|
||||||
LXD_BRIDGE="lxdbr0"
|
LXD_BRIDGE="lxdbr0"
|
||||||
UPDATE_PROFILE="true"
|
UPDATE_PROFILE="true"
|
||||||
LXD_CONFILE=""
|
LXD_CONFILE="/etc/default/algo.conf"
|
||||||
LXD_DOMAIN="lxd"
|
LXD_DOMAIN="lxd"
|
||||||
LXD_IPV4_ADDR="10.0.8.1"
|
LXD_IPV4_ADDR="10.0.8.1"
|
||||||
LXD_IPV4_NETMASK="255.255.255.0"
|
LXD_IPV4_NETMASK="255.255.255.0"
|
||||||
|
@ -13,4 +13,4 @@ LXD_IPV6_ADDR=""
|
||||||
LXD_IPV6_MASK=""
|
LXD_IPV6_MASK=""
|
||||||
LXD_IPV6_NETWORK=""
|
LXD_IPV6_NETWORK=""
|
||||||
LXD_IPV6_NAT="false"
|
LXD_IPV6_NAT="false"
|
||||||
LXD_IPV6_PROXY="true"
|
LXD_IPV6_PROXY="false"
|
||||||
|
|
30
tests/pre-deploy.sh
Executable file
30
tests/pre-deploy.sh
Executable file
|
@ -0,0 +1,30 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euxo pipefail
|
||||||
|
|
||||||
|
sysctl net.ipv6.conf.all.disable_ipv6=0
|
||||||
|
|
||||||
|
tar xf $HOME/lxc/cache.tar -C / || echo "Didn't extract cache."
|
||||||
|
cp -f tests/lxd-bridge /etc/default/lxd-bridge
|
||||||
|
cp -f tests/algo.conf /etc/default/algo.conf
|
||||||
|
|
||||||
|
if [[ "$DEPLOY" == "cloud-init" ]]; then
|
||||||
|
bash tests/cloud-init.sh | lxc profile set default user.user-data -
|
||||||
|
else
|
||||||
|
echo -e "#cloud-config\nssh_authorized_keys:\n - $(cat ~/.ssh/id_rsa.pub)" | lxc profile set default user.user-data -
|
||||||
|
fi
|
||||||
|
|
||||||
|
systemctl restart lxd-bridge.service lxd-containers.service lxd.service
|
||||||
|
|
||||||
|
lxc profile set default raw.lxc lxc.aa_profile=unconfined
|
||||||
|
lxc profile set default security.privileged true
|
||||||
|
lxc profile show default
|
||||||
|
lxc launch ubuntu:18.04 algo
|
||||||
|
|
||||||
|
ip addr
|
||||||
|
|
||||||
|
until dig A +short algo.lxd @10.0.8.1 | grep -vE '^$' > /dev/null; do
|
||||||
|
sleep 3
|
||||||
|
done
|
||||||
|
|
||||||
|
lxc list
|
15
tests/ssh-tunnel.sh
Executable file
15
tests/ssh-tunnel.sh
Executable file
|
@ -0,0 +1,15 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euxo pipefail
|
||||||
|
|
||||||
|
PASS=$(grep ^p12_password: configs/10.0.8.100/.config.yml | awk '{print $2}')
|
||||||
|
|
||||||
|
ssh-keygen -p -P ${PASS} -N '' -f configs/10.0.8.100/ssh-tunnel/desktop.pem
|
||||||
|
|
||||||
|
ssh -o StrictHostKeyChecking=no -D 127.0.0.1:1080 -f -q -C -N desktop@10.0.8.100 -i configs/10.0.8.100/ssh-tunnel/desktop.pem
|
||||||
|
|
||||||
|
git config --global http.proxy 'socks5://127.0.0.1:1080'
|
||||||
|
|
||||||
|
git clone -vv https://github.com/trailofbits/algo /tmp/ssh-tunnel-check
|
||||||
|
|
||||||
|
echo "SSH tunneling tests passed"
|
|
@ -2,11 +2,11 @@
|
||||||
|
|
||||||
set -ex
|
set -ex
|
||||||
|
|
||||||
USER_ARGS="{ 'server': '$LXC_IP', 'users': ['user1', 'user2'] }"
|
USER_ARGS="{ 'server': '10.0.8.100', 'users': ['desktop', 'user1', 'user2'] }"
|
||||||
|
|
||||||
if [ "${LXC_NAME}" == "docker" ]
|
if [ "${DEPLOY}" == "docker" ]
|
||||||
then
|
then
|
||||||
docker run -it -v $(pwd)/config.cfg:/algo/config.cfg -v ~/.ssh:/root/.ssh -v $(pwd)/configs:/algo/configs -e "USER_ARGS=${USER_ARGS}" travis/algo /bin/sh -c "chown -R 0:0 /root/.ssh && source env/bin/activate && ansible-playbook users.yml -e \"${USER_ARGS}\" -t update-users"
|
docker run -it -v $(pwd)/config.cfg:/algo/config.cfg -v ~/.ssh:/root/.ssh -v $(pwd)/configs:/algo/configs -e "USER_ARGS=${USER_ARGS}" travis/algo /bin/sh -c "chown -R root: /root/.ssh && chmod -R 600 /root/.ssh && source env/bin/activate && ansible-playbook users.yml -e \"${USER_ARGS}\" -t update-users"
|
||||||
else
|
else
|
||||||
ansible-playbook users.yml -e "${USER_ARGS}" -t update-users
|
ansible-playbook users.yml -e "${USER_ARGS}" -t update-users
|
||||||
fi
|
fi
|
||||||
|
@ -15,7 +15,7 @@ fi
|
||||||
# IPsec
|
# IPsec
|
||||||
#
|
#
|
||||||
|
|
||||||
if sudo openssl crl -inform pem -noout -text -in configs/$LXC_IP/ipsec/.pki/crl/phone.crt | grep CRL
|
if sudo openssl crl -inform pem -noout -text -in configs/10.0.8.100/ipsec/.pki/crl/phone.crt | grep CRL
|
||||||
then
|
then
|
||||||
echo "The CRL check passed"
|
echo "The CRL check passed"
|
||||||
else
|
else
|
||||||
|
@ -23,7 +23,7 @@ if sudo openssl crl -inform pem -noout -text -in configs/$LXC_IP/ipsec/.pki/crl/
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if sudo openssl x509 -inform pem -noout -text -in configs/$LXC_IP/ipsec/.pki/certs/user1.crt | grep CN=user1
|
if sudo openssl x509 -inform pem -noout -text -in configs/10.0.8.100/ipsec/.pki/certs/user1.crt | grep CN=user1
|
||||||
then
|
then
|
||||||
echo "The new user exists"
|
echo "The new user exists"
|
||||||
else
|
else
|
||||||
|
@ -35,7 +35,7 @@ fi
|
||||||
# WireGuard
|
# WireGuard
|
||||||
#
|
#
|
||||||
|
|
||||||
if sudo test -f configs/$LXC_IP/wireguard/user1.conf
|
if sudo test -f configs/10.0.8.100/wireguard/user1.conf
|
||||||
then
|
then
|
||||||
echo "WireGuard: The new user exists"
|
echo "WireGuard: The new user exists"
|
||||||
else
|
else
|
||||||
|
@ -47,7 +47,7 @@ fi
|
||||||
# SSH tunneling
|
# SSH tunneling
|
||||||
#
|
#
|
||||||
|
|
||||||
if sudo test -f configs/$LXC_IP/ssh-tunnel/user1.ssh_config
|
if sudo test -f configs/10.0.8.100/ssh-tunnel/user1.ssh_config
|
||||||
then
|
then
|
||||||
echo "SSH Tunneling: The new user exists"
|
echo "SSH Tunneling: The new user exists"
|
||||||
else
|
else
|
||||||
|
|
21
tests/wireguard-client.sh
Executable file
21
tests/wireguard-client.sh
Executable file
|
@ -0,0 +1,21 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euxo pipefail
|
||||||
|
|
||||||
|
crudini --set configs/10.0.8.100/wireguard/user1.conf Interface Table off
|
||||||
|
|
||||||
|
wg-quick up configs/10.0.8.100/wireguard/user1.conf
|
||||||
|
|
||||||
|
wg
|
||||||
|
|
||||||
|
ifconfig user1
|
||||||
|
|
||||||
|
ip route add 172.16.0.1/32 dev user1
|
||||||
|
|
||||||
|
fping -t 900 -c3 -r3 -Dse 10.0.8.100 172.16.0.1
|
||||||
|
|
||||||
|
wg | grep "latest handshake"
|
||||||
|
|
||||||
|
host google.com 172.16.0.1
|
||||||
|
|
||||||
|
echo "WireGuard tests passed"
|
10
users.yml
10
users.yml
|
@ -7,7 +7,8 @@
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
- block:
|
- block:
|
||||||
- pause:
|
- name: Server address prompt
|
||||||
|
pause:
|
||||||
prompt: "Enter the IP address of your server: (or use localhost for local installation)"
|
prompt: "Enter the IP address of your server: (or use localhost for local installation)"
|
||||||
register: _server
|
register: _server
|
||||||
when: server is undefined
|
when: server is undefined
|
||||||
|
@ -16,14 +17,15 @@
|
||||||
set_fact:
|
set_fact:
|
||||||
algo_server: >-
|
algo_server: >-
|
||||||
{% if server is defined %}{{ server }}
|
{% if server is defined %}{{ server }}
|
||||||
{%- elif _server.user_input is defined and _server.user_input != "" %}{{ _server.user_input }}
|
{%- elif _server.user_input %}{{ _server.user_input }}
|
||||||
{%- else %}omit{% endif %}
|
{%- else %}omit{% endif %}
|
||||||
|
|
||||||
- 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"
|
||||||
|
|
||||||
- pause:
|
- name: CA password prompt
|
||||||
|
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
|
||||||
|
@ -35,7 +37,7 @@
|
||||||
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 is defined and _ca_password.user_input != "" %}{{ _ca_password.user_input }}
|
{%- elif _ca_password.user_input %}{{ _ca_password.user_input }}
|
||||||
{%- else %}omit{% endif %}
|
{%- else %}omit{% endif %}
|
||||||
|
|
||||||
- name: Add the server to the vpn-host group
|
- name: Add the server to the vpn-host group
|
||||||
|
|
Loading…
Add table
Reference in a new issue