mirror of
https://github.com/trailofbits/algo.git
synced 2025-04-11 11:47:08 +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:
|
||||
apt:
|
||||
sources:
|
||||
sources: &default_sources
|
||||
- sourceline: 'ppa:ubuntu-lxc/stable'
|
||||
- sourceline: 'ppa:wireguard/wireguard'
|
||||
packages:
|
||||
packages: &default_packages
|
||||
- python-pip
|
||||
- lxd
|
||||
- expect-dev
|
||||
- debootstrap
|
||||
- shellcheck
|
||||
- tree
|
||||
- bridge-utils
|
||||
- dnsutils
|
||||
|
@ -25,7 +24,12 @@ addons:
|
|||
- libffi-dev
|
||||
- python-dev
|
||||
- linux-headers-$(uname -r)
|
||||
- wireguard-dkms
|
||||
- wireguard
|
||||
- libxml2-utils
|
||||
- crudini
|
||||
- fping
|
||||
- strongswan
|
||||
- libstrongswan-standard-plugins
|
||||
|
||||
cache:
|
||||
directories:
|
||||
|
@ -37,39 +41,54 @@ before_cache:
|
|||
- sudo tar cf $HOME/lxc/cache.tar /var/lib/lxd/images/
|
||||
- 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:
|
||||
fast_finish: true
|
||||
include:
|
||||
- stage: Test
|
||||
name: local deployment from docker
|
||||
- stage: Tests
|
||||
name: code checks and linters
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- shellcheck
|
||||
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
|
||||
- gem install awesome_bot
|
||||
- ansible-playbook --version
|
||||
- tree . -L 2
|
||||
- shellcheck algo install.sh
|
||||
- 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/update-users.sh
|
||||
script: *tests
|
||||
|
||||
- stage: Test
|
||||
- stage: Deploy
|
||||
name: cloud-init deployment
|
||||
script:
|
||||
- sudo tar xf $HOME/lxc/cache.tar -C / || echo "Didn't extract cache."
|
||||
- sudo cp -f tests/lxd-bridge /etc/default/lxd-bridge
|
||||
- sudo service lxd restart
|
||||
- bash tests/cloud-init.sh | sudo lxc profile set default user.user-data -
|
||||
- sudo lxc profile show default
|
||||
- sudo lxc launch ubuntu:18.04 algo
|
||||
addons:
|
||||
apt:
|
||||
sources: *default_sources
|
||||
packages: *default_packages
|
||||
env: DEPLOY=cloud-init
|
||||
before_install: *provisioning
|
||||
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
|
||||
- ( sudo lxc exec algo -- tail -f /var/log/cloud-init-output.log & )
|
||||
- |
|
||||
|
@ -78,11 +97,10 @@ matrix:
|
|||
sleep 30;
|
||||
done
|
||||
- sudo lxc exec algo -- test -f /opt/algo/configs/localhost/.config.yml
|
||||
|
||||
# script:
|
||||
# - 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
|
||||
# - shellcheck algo
|
||||
# - ansible-lint main.yml users.yml deploy_client.yml
|
||||
- sudo lxc exec algo -- tar zcf /root/algo-configs.tar -C /opt/algo/configs/ .
|
||||
- sudo lxc file pull algo/root/algo-configs.tar ./
|
||||
- sudo tar -C ./configs -zxf algo-configs.tar
|
||||
script: *tests
|
||||
|
||||
notifications:
|
||||
email: false
|
||||
|
|
23
algo
23
algo
|
@ -4,19 +4,20 @@ set -e
|
|||
|
||||
if [ -z ${VIRTUAL_ENV+x} ]
|
||||
then
|
||||
ACTIVATE_SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/env/bin/activate"
|
||||
if [ -f "$ACTIVATE_SCRIPT" ]
|
||||
then
|
||||
source $ACTIVATE_SCRIPT
|
||||
else
|
||||
echo "$ACTIVATE_SCRIPT not found. Did you follow documentation to install dependencies?"
|
||||
exit 1
|
||||
fi
|
||||
ACTIVATE_SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/env/bin/activate"
|
||||
if [ -f "$ACTIVATE_SCRIPT" ]
|
||||
then
|
||||
# shellcheck source=/dev/null
|
||||
source "$ACTIVATE_SCRIPT"
|
||||
else
|
||||
echo "$ACTIVATE_SCRIPT not found. Did you follow documentation to install dependencies?"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
case "$1" in
|
||||
update-users) PLAYBOOK=users.yml; ARGS="${@:2} -t update-users";;
|
||||
*) PLAYBOOK=main.yml; ARGS=${@} ;;
|
||||
update-users) PLAYBOOK=users.yml; ARGS=( "${@:2}" -t update-users ) ;;
|
||||
*) PLAYBOOK=main.yml; ARGS=( "${@}" ) ;;
|
||||
esac
|
||||
|
||||
ansible-playbook ${PLAYBOOK} ${ARGS}
|
||||
ansible-playbook ${PLAYBOOK} "${ARGS[@]}"
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
---
|
||||
- name: Configure the client
|
||||
hosts: localhost
|
||||
become: false
|
||||
vars_files:
|
||||
- config.cfg
|
||||
|
||||
|
@ -8,9 +10,10 @@
|
|||
add_host:
|
||||
name: "{{ client_ip }}"
|
||||
groups: client-host
|
||||
ansible_ssh_user: "{{ ssh_user }}"
|
||||
ansible_ssh_user: "{{ 'root' if client_ip == 'localhost' else ssh_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
|
||||
hosts: client-host
|
||||
|
@ -18,33 +21,6 @@
|
|||
become: true
|
||||
vars_files:
|
||||
- config.cfg
|
||||
- roles/vpn/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/strongswan/defaults/main.yml
|
||||
roles:
|
||||
- { role: client, tags: ['client'] }
|
||||
- role: client
|
||||
|
|
49
input.yml
49
input.yml
|
@ -26,11 +26,12 @@
|
|||
|
||||
tasks:
|
||||
- block:
|
||||
- pause:
|
||||
- name: Region prompt
|
||||
pause:
|
||||
prompt: |
|
||||
What provider would you like to use?
|
||||
{% for p in providers_map %}
|
||||
{{ loop.index }}. {{ p['name']}}
|
||||
{{ loop.index }}. {{ p['name'] }}
|
||||
{% endfor %}
|
||||
|
||||
Enter the number of your desired provider
|
||||
|
@ -41,7 +42,8 @@
|
|||
set_fact:
|
||||
algo_provider: "{{ provider | default(providers_map[_algo_provider.user_input|default(omit)|int - 1]['alias']) }}"
|
||||
|
||||
- pause:
|
||||
- name: VPN server name prompt
|
||||
pause:
|
||||
prompt: |
|
||||
Name the vpn server
|
||||
[algo]
|
||||
|
@ -50,21 +52,24 @@
|
|||
- server_name is undefined
|
||||
- algo_provider != "local"
|
||||
- block:
|
||||
- pause:
|
||||
- name: Cellular On Demand prompt
|
||||
pause:
|
||||
prompt: |
|
||||
Do you want macOS/iOS IPsec clients to enable "Connect On Demand" when connected to cellular networks?
|
||||
[y/N]
|
||||
register: _ondemand_cellular
|
||||
when: ondemand_cellular is undefined
|
||||
|
||||
- pause:
|
||||
- name: Wi-Fi On Demand prompt
|
||||
pause:
|
||||
prompt: |
|
||||
Do you want macOS/iOS IPsec clients to enable "Connect On Demand" when connected to Wi-Fi?
|
||||
[y/N]
|
||||
register: _ondemand_wifi
|
||||
when: ondemand_wifi is undefined
|
||||
|
||||
- pause:
|
||||
- name: Trusted Wi-Fi networks prompt
|
||||
pause:
|
||||
prompt: |
|
||||
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)
|
||||
|
@ -74,14 +79,16 @@
|
|||
- (ondemand_wifi|default(false)|bool) or
|
||||
(booleans_map[_ondemand_wifi.user_input|default(omit)]|default(false))
|
||||
|
||||
- pause:
|
||||
- name: Compatible ciphers prompt
|
||||
pause:
|
||||
prompt: |
|
||||
Do you want the VPN to support Windows 10 or Linux Desktop clients? (enables compatible ciphers and key exchange, less secure)
|
||||
[y/N]
|
||||
register: _windows
|
||||
when: windows is undefined
|
||||
|
||||
- pause:
|
||||
- name: Retain the CA key prompt
|
||||
pause:
|
||||
prompt: |
|
||||
Do you want to retain the CA key? (required to add users in the future, but less secure)
|
||||
[y/N]
|
||||
|
@ -89,14 +96,16 @@
|
|||
when: store_cakey is undefined
|
||||
when: ipsec_enabled
|
||||
|
||||
- pause:
|
||||
- name: DNS adblocking prompt
|
||||
pause:
|
||||
prompt: |
|
||||
Do you want to install an ad blocking DNS resolver on this VPN server?
|
||||
[y/N]
|
||||
register: _local_dns
|
||||
when: local_dns is undefined
|
||||
|
||||
- pause:
|
||||
- name: SSH tunneling prompt
|
||||
pause:
|
||||
prompt: |
|
||||
Do you want each user to have their own account for SSH tunneling?
|
||||
[y/N]
|
||||
|
@ -107,36 +116,38 @@
|
|||
set_fact:
|
||||
algo_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 -%}
|
||||
{{ _server | regex_replace('(?!\.)(\W|_)', '-') }}
|
||||
algo_ondemand_cellular: >-
|
||||
{% 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 %}
|
||||
algo_ondemand_wifi: >-
|
||||
{% 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 %}
|
||||
algo_ondemand_wifi_exclude: >-
|
||||
{% 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 %}
|
||||
algo_local_dns: >-
|
||||
{% 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 %}
|
||||
algo_ssh_tunneling: >-
|
||||
{% 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 %}
|
||||
algo_windows: >-
|
||||
{% 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 %}
|
||||
algo_store_cakey: >-
|
||||
{% 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 %}
|
||||
rescue:
|
||||
- include_tasks: playbooks/rescue.yml
|
||||
- include_tasks: playbooks/rescue.yml
|
||||
|
|
39
install.sh
39
install.sh
|
@ -36,12 +36,11 @@ installRequirements() {
|
|||
}
|
||||
|
||||
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
|
||||
|
||||
git checkout ${REPO_BRANCH}
|
||||
|
||||
python -m virtualenv --python=`which python2` .venv
|
||||
|
||||
python -m virtualenv --python="$(command -v python2)" .venv
|
||||
# shellcheck source=/dev/null
|
||||
. .venv/bin/activate
|
||||
python -m pip install -U pip virtualenv
|
||||
python -m pip install -r requirements.txt
|
||||
|
@ -50,27 +49,23 @@ getAlgo() {
|
|||
publicIpFromInterface() {
|
||||
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}')"
|
||||
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
|
||||
echo "Using ${ENDPOINT} as the endpoint"
|
||||
}
|
||||
|
||||
publicIpFromMetadata() {
|
||||
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)"
|
||||
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)"
|
||||
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")"
|
||||
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')"
|
||||
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
|
||||
echo "Using ${ENDPOINT} as the endpoint"
|
||||
else
|
||||
|
@ -82,23 +77,25 @@ deployAlgo() {
|
|||
getAlgo
|
||||
|
||||
cd /opt/algo
|
||||
# shellcheck source=/dev/null
|
||||
. .venv/bin/activate
|
||||
|
||||
export HOME=/root
|
||||
export ANSIBLE_LOCAL_TEMP=/root/.ansible/tmp
|
||||
export ANSIBLE_REMOTE_TEMP=/root/.ansible/tmp
|
||||
|
||||
# shellcheck disable=SC2086
|
||||
ansible-playbook main.yml \
|
||||
-e provider=local \
|
||||
-e ondemand_cellular=${ONDEMAND_CELLULAR} \
|
||||
-e ondemand_wifi=${ONDEMAND_WIFI} \
|
||||
-e ondemand_wifi_exclude=${ONDEMAND_WIFI_EXCLUDE} \
|
||||
-e windows=${WINDOWS} \
|
||||
-e store_cakey=${STORE_CAKEY} \
|
||||
-e local_dns=${LOCAL_DNS} \
|
||||
-e ssh_tunneling=${SSH_TUNNELING} \
|
||||
-e endpoint=$ENDPOINT \
|
||||
-e users=$(echo "$USERS" | jq -Rc 'split(",")') \
|
||||
-e "ondemand_cellular=${ONDEMAND_CELLULAR}" \
|
||||
-e "ondemand_wifi=${ONDEMAND_WIFI}" \
|
||||
-e "ondemand_wifi_exclude=${ONDEMAND_WIFI_EXCLUDE}" \
|
||||
-e "windows=${WINDOWS}" \
|
||||
-e "store_cakey=${STORE_CAKEY}" \
|
||||
-e "local_dns=${LOCAL_DNS}" \
|
||||
-e "ssh_tunneling=${SSH_TUNNELING}" \
|
||||
-e "endpoint=$ENDPOINT" \
|
||||
-e "users=$(echo "$USERS" | jq -Rc 'split(",")')" \
|
||||
-e server=localhost \
|
||||
-e ssh_user=root \
|
||||
-e "${EXTRA_VARS}" \
|
||||
|
@ -106,7 +103,7 @@ deployAlgo() {
|
|||
tee /var/log/algo.log
|
||||
}
|
||||
|
||||
if test $METHOD = "cloud"; then
|
||||
if test "$METHOD" = "cloud"; then
|
||||
publicIpFromMetadata
|
||||
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
|
||||
import_playbook: input.yml
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
- name: Display the invocation environment
|
||||
local_action:
|
||||
module: shell
|
||||
- block:
|
||||
- name: Display the invocation environment
|
||||
shell: >
|
||||
./algo-showenv.sh \
|
||||
'algo_provider "{{ algo_provider }}"' \
|
||||
'algo_ondemand_cellular "{{ algo_ondemand_cellular }}"' \
|
||||
|
@ -13,17 +13,20 @@
|
|||
'wireguard_enabled "{{ wireguard_enabled }}"' \
|
||||
'dns_encryption "{{ dns_encryption }}"' \
|
||||
> /dev/tty
|
||||
tags: debug
|
||||
tags: debug
|
||||
|
||||
- name: Install the requirements
|
||||
local_action:
|
||||
module: pip
|
||||
state: latest
|
||||
name:
|
||||
- pyOpenSSL
|
||||
- jinja2==2.8
|
||||
- segno
|
||||
tags: always
|
||||
- name: Install the requirements
|
||||
pip:
|
||||
state: latest
|
||||
name:
|
||||
- pyOpenSSL
|
||||
- jinja2==2.8
|
||||
- segno
|
||||
tags:
|
||||
- always
|
||||
- skip_ansible_lint
|
||||
delegate_to: localhost
|
||||
become: false
|
||||
|
||||
- name: Generate the SSH private key
|
||||
openssl_privatekey:
|
||||
|
|
|
@ -2,4 +2,5 @@
|
|||
- debug:
|
||||
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
|
||||
service: name=strongswan state=restarted
|
||||
|
|
|
@ -8,13 +8,21 @@
|
|||
package: name="{{ item }}" state=present
|
||||
with_items:
|
||||
- "{{ prerequisites }}"
|
||||
register: result
|
||||
until: result is succeeded
|
||||
retries: 10
|
||||
delay: 3
|
||||
|
||||
- name: Install strongSwan
|
||||
package: name=strongswan state=present
|
||||
register: result
|
||||
until: result is succeeded
|
||||
retries: 10
|
||||
delay: 3
|
||||
|
||||
- name: Setup the ipsec config
|
||||
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"
|
||||
mode: '0644'
|
||||
with_items:
|
||||
|
@ -24,7 +32,7 @@
|
|||
|
||||
- name: Setup the ipsec secrets
|
||||
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"
|
||||
mode: '0600'
|
||||
with_items:
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
|
||||
- set_fact:
|
||||
- name: Set OS specific facts
|
||||
set_fact:
|
||||
prerequisites:
|
||||
- epel-release
|
||||
configs_prefix: /etc/strongswan
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
---
|
||||
|
||||
- set_fact:
|
||||
prerequisites: []
|
||||
- name: Set OS specific facts
|
||||
set_fact:
|
||||
prerequisites:
|
||||
- libstrongswan-standard-plugins
|
||||
configs_prefix: /etc
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
|
||||
- set_fact:
|
||||
- name: Set OS specific facts
|
||||
set_fact:
|
||||
prerequisites:
|
||||
- libselinux-python
|
||||
configs_prefix: /etc/strongswan
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
---
|
||||
|
||||
- set_fact:
|
||||
prerequisites: []
|
||||
- name: Set OS specific facts
|
||||
set_fact:
|
||||
prerequisites:
|
||||
- libstrongswan-standard-plugins
|
||||
configs_prefix: /etc
|
||||
|
|
|
@ -9,14 +9,14 @@
|
|||
- set_fact:
|
||||
algo_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 %}
|
||||
|
||||
- name: Create AlgoVPN Server
|
||||
azure_rm_deployment:
|
||||
state: present
|
||||
deployment_name: "{{ algo_server_name }}"
|
||||
template: "{{ lookup('file', 'deployment.json') }}"
|
||||
template: "{{ lookup('file', role_path + '/files/deployment.json') }}"
|
||||
secret: "{{ secret }}"
|
||||
tenant: "{{ tenant }}"
|
||||
client_id: "{{ client_id }}"
|
||||
|
|
|
@ -10,23 +10,32 @@
|
|||
name:
|
||||
- packaging
|
||||
- requests[security]
|
||||
- azure-mgmt-compute>=2.0.0,<3
|
||||
- azure-mgmt-network>=1.3.0,<2
|
||||
- azure-mgmt-storage>=1.5.0,<2
|
||||
- azure-mgmt-resource>=1.1.0,<2
|
||||
- azure-storage>=0.35.1,<0.36
|
||||
- azure-cli-core>=2.0.12,<3
|
||||
- azure-cli-core==2.0.35
|
||||
- azure-cli-nspkg==3.0.2
|
||||
- azure-common==1.1.11
|
||||
- azure-mgmt-batch==4.1.0
|
||||
- azure-mgmt-compute==2.1.0
|
||||
- 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
|
||||
- msrestazure==0.4.31
|
||||
- azure-mgmt-dns>=1.0.1,<2
|
||||
- azure-mgmt-keyvault>=0.40.0,<0.41
|
||||
- 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
|
||||
- azure-keyvault==1.0.0a1
|
||||
- azure-graphrbac==0.40.0
|
||||
state: latest
|
||||
virtualenv: "{{ azure_venv }}"
|
||||
virtualenv_python: python2.7
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
set_fact:
|
||||
algo_do_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 %}
|
||||
public_key: "{{ lookup('file', '{{ SSH_keys.public }}') }}"
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
|||
api_token: "{{ algo_do_token }}"
|
||||
name: "{{ SSH_keys.comment }}"
|
||||
register: ssh_keys
|
||||
until: ssh_keys.changed != true
|
||||
until: not ssh_keys.changed
|
||||
retries: 10
|
||||
delay: 1
|
||||
|
||||
|
@ -83,7 +83,7 @@
|
|||
api_token: "{{ algo_do_token }}"
|
||||
name: "{{ SSH_keys.comment }}"
|
||||
register: ssh_keys
|
||||
until: ssh_keys.changed != true
|
||||
until: not ssh_keys.changed
|
||||
retries: 10
|
||||
delay: 1
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
stack_name: "{{ stack_name }}"
|
||||
state: "present"
|
||||
region: "{{ algo_region }}"
|
||||
template: roles/cloud-ec2/files/stack.yml
|
||||
template: roles/cloud-ec2/files/stack.yaml
|
||||
template_parameters:
|
||||
InstanceTypeParameter: "{{ cloud_providers.ec2.size }}"
|
||||
PublicSSHKeyParameter: "{{ lookup('file', SSH_keys.public) }}"
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
- set_fact:
|
||||
algo_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 %}
|
||||
stack_name: "{{ algo_server_name | replace('.', '-') }}"
|
||||
|
||||
|
|
|
@ -63,5 +63,5 @@
|
|||
- set_fact:
|
||||
algo_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 %}
|
||||
|
|
|
@ -57,5 +57,5 @@
|
|||
- set_fact:
|
||||
algo_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 %}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
- 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)"
|
||||
when: lookup('env', 'OS_AUTH_URL') == ""
|
||||
when: lookup('env', 'OS_AUTH_URL')|length <= 0
|
||||
|
||||
- name: Build python virtual environment
|
||||
import_tasks: venv.yml
|
||||
|
|
|
@ -84,7 +84,7 @@
|
|||
organization: "{{ organization_id }}"
|
||||
name: "{{ algo_server_name }}"
|
||||
image: "{{ image_id }}"
|
||||
commercial_type: "{{cloud_providers.scaleway.size }}"
|
||||
commercial_type: "{{ cloud_providers.scaleway.size }}"
|
||||
enable_ipv6: true
|
||||
boot_type: local
|
||||
tags:
|
||||
|
|
|
@ -30,5 +30,5 @@
|
|||
algo_scaleway_org: "{{ scaleway_org | default(_scaleway_org.user_input|default(omit)) }}"
|
||||
algo_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 %}
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
---
|
||||
- block:
|
||||
- name: Include prompts
|
||||
import_tasks: prompts.yml
|
||||
- name: Include prompts
|
||||
import_tasks: prompts.yml
|
||||
|
||||
- block:
|
||||
- name: Upload the SSH key
|
||||
vr_ssh_key:
|
||||
vultr_ssh_key:
|
||||
name: "{{ SSH_keys.comment }}"
|
||||
ssh_key: "{{ lookup('file', '{{ SSH_keys.public }}') }}"
|
||||
register: ssh_key
|
||||
|
||||
- name: Creating a server
|
||||
vr_server:
|
||||
vultr_server:
|
||||
name: "{{ algo_server_name }}"
|
||||
hostname: "{{ algo_server_name }}"
|
||||
os: "{{ cloud_providers.vultr.os }}"
|
||||
|
|
|
@ -54,5 +54,5 @@
|
|||
set_fact:
|
||||
algo_vultr_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 %}
|
||||
|
|
|
@ -20,8 +20,5 @@
|
|||
ifconfig lo100 inet {{ local_service_ip }} netmask 255.255.255.255 &&
|
||||
ifconfig lo100 inet6 FCAA::1/64; echo $?
|
||||
|
||||
- name: save iptables
|
||||
shell: service netfilter-persistent save
|
||||
|
||||
- name: restart iptables
|
||||
service: name=netfilter-persistent state=restarted
|
||||
|
|
|
@ -1,26 +1,26 @@
|
|||
---
|
||||
- block:
|
||||
- name: Generate password for the CA key
|
||||
local_action:
|
||||
module: shell
|
||||
openssl rand -hex 16
|
||||
command: openssl rand -hex 16
|
||||
register: CA_password
|
||||
|
||||
- name: Generate p12 export password
|
||||
local_action:
|
||||
module: shell
|
||||
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())]))'
|
||||
shell: >
|
||||
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())]))'
|
||||
register: p12_password_generated
|
||||
when: p12_password is not defined
|
||||
tags: update-users
|
||||
become: false
|
||||
delegate_to: localhost
|
||||
|
||||
- name: Define facts
|
||||
set_fact:
|
||||
p12_export_password: "{{ p12_password|default(p12_password_generated.stdout) }}"
|
||||
tags: update-users
|
||||
|
||||
- set_fact:
|
||||
- name: Set facts
|
||||
set_fact:
|
||||
CA_password: "{{ CA_password.stdout }}"
|
||||
IP_subject_alt_name: "{{ IP_subject_alt_name }}"
|
||||
|
||||
|
@ -31,5 +31,5 @@
|
|||
|
||||
- name: Check size of MTU
|
||||
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
|
||||
|
|
|
@ -17,7 +17,8 @@
|
|||
- name: Gather additional facts
|
||||
import_tasks: facts.yml
|
||||
|
||||
- set_fact:
|
||||
- name: Set OS specific facts
|
||||
set_fact:
|
||||
config_prefix: "/usr/local/"
|
||||
strongswan_shell: /usr/sbin/nologin
|
||||
strongswan_home: /var/empty
|
||||
|
@ -73,5 +74,6 @@
|
|||
shell: >
|
||||
kldstat -n ipfw.ko || kldload ipfw ; sysctl net.inet.ip.fw.enable=0 &&
|
||||
bash /etc/rc.firewall && sysctl net.inet.ip.fw.enable=1
|
||||
changed_when: false
|
||||
|
||||
- meta: flush_handlers
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
- name: Check the system
|
||||
raw: uname -a
|
||||
register: OS
|
||||
changed_when: false
|
||||
tags:
|
||||
- update-users
|
||||
|
||||
|
@ -17,7 +18,7 @@
|
|||
|
||||
- name: Sysctl tuning
|
||||
sysctl: name="{{ item.item }}" value="{{ item.value }}"
|
||||
when: item.item != ""
|
||||
when: item.item
|
||||
with_items:
|
||||
- "{{ sysctl|default([]) }}"
|
||||
tags:
|
||||
|
|
|
@ -25,8 +25,7 @@
|
|||
ignore_errors: true
|
||||
|
||||
- name: Wait until SSH becomes ready...
|
||||
local_action:
|
||||
module: wait_for
|
||||
wait_for:
|
||||
port: 22
|
||||
host: "{{ inventory_hostname }}"
|
||||
search_regex: OpenSSH
|
||||
|
@ -34,6 +33,7 @@
|
|||
timeout: 320
|
||||
when: reboot_required is defined and reboot_required.stdout == 'required'
|
||||
become: false
|
||||
delegate_to: localhost
|
||||
when: algo_provider != "local"
|
||||
|
||||
- name: Include unatteded upgrades configuration
|
||||
|
@ -65,18 +65,21 @@
|
|||
- meta: flush_handlers
|
||||
|
||||
- name: Check apparmor support
|
||||
shell: apparmor_status
|
||||
command: apparmor_status
|
||||
ignore_errors: yes
|
||||
changed_when: false
|
||||
register: apparmor_status
|
||||
|
||||
- set_fact:
|
||||
- name: Set fact if apparmor enabled
|
||||
set_fact:
|
||||
apparmor_enabled: true
|
||||
when: '"profiles are in enforce mode" in apparmor_status.stdout'
|
||||
|
||||
- name: Gather additional facts
|
||||
import_tasks: facts.yml
|
||||
|
||||
- set_fact:
|
||||
- name: Set OS specific facts
|
||||
set_fact:
|
||||
tools:
|
||||
- git
|
||||
- screen
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
- name: Install unattended-upgrades
|
||||
apt:
|
||||
name: unattended-upgrades
|
||||
state: latest
|
||||
state: present
|
||||
|
||||
- name: Configure unattended-upgrades
|
||||
template:
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
|
||||
- name: Update adblock hosts
|
||||
command: /usr/local/sbin/adblock.sh
|
||||
changed_when: false
|
||||
|
||||
- meta: flush_handlers
|
||||
|
||||
|
|
|
@ -7,13 +7,13 @@
|
|||
owner: root
|
||||
group: root
|
||||
mode: 0600
|
||||
when: apparmor_enabled|default(false)|bool == true
|
||||
when: apparmor_enabled|default(false)|bool
|
||||
notify:
|
||||
- restart dnsmasq
|
||||
|
||||
- name: Ubuntu | Enforce the dnsmasq AppArmor policy
|
||||
shell: aa-enforce usr.sbin.dnsmasq
|
||||
when: apparmor_enabled|default(false)|bool == true
|
||||
command: aa-enforce usr.sbin.dnsmasq
|
||||
when: apparmor_enabled|default(false)|bool
|
||||
tags: ['apparmor']
|
||||
|
||||
- name: Ubuntu | Ensure that the dnsmasq service directory exist
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
- name: Install dnscrypt-proxy
|
||||
apt:
|
||||
name: dnscrypt-proxy
|
||||
state: latest
|
||||
state: present
|
||||
update_cache: true
|
||||
|
||||
- name: Configure unattended-upgrades
|
||||
|
@ -37,7 +37,7 @@
|
|||
command: aa-enforce usr.bin.dnscrypt-proxy
|
||||
changed_when: false
|
||||
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
|
||||
file:
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
set_fact:
|
||||
cloud_instance_ip: >-
|
||||
{% 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 %}
|
||||
|
||||
- pause:
|
||||
|
@ -26,7 +26,7 @@
|
|||
set_fact:
|
||||
ansible_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 %}
|
||||
|
||||
- pause:
|
||||
|
@ -40,5 +40,5 @@
|
|||
set_fact:
|
||||
IP_subject_alt_name: >-
|
||||
{% 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 %}
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
file:
|
||||
dest: "{{ ssh_tunnels_config_path }}"
|
||||
state: absent
|
||||
when: keys_clean_all|bool == True
|
||||
when: keys_clean_all|bool
|
||||
|
||||
- name: Ensure the config directories exist
|
||||
file:
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
service: name=strongswan state=restarted
|
||||
|
||||
- name: daemon-reload
|
||||
shell: systemctl daemon-reload
|
||||
systemd: daemon_reload=true
|
||||
|
||||
- name: restart apparmor
|
||||
service: name=apparmor state=restarted
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
---
|
||||
- name: Register p12 PayloadContent
|
||||
shell: cat private/{{ item }}.p12 | base64
|
||||
shell: |
|
||||
set -o pipefail
|
||||
cat private/{{ item }}.p12 |
|
||||
base64
|
||||
register: PayloadContent
|
||||
changed_when: false
|
||||
args:
|
||||
executable: bash
|
||||
chdir: "{{ ipsec_pki_path }}"
|
||||
with_items: "{{ users }}"
|
||||
|
||||
|
|
|
@ -32,8 +32,13 @@
|
|||
- restart strongswan
|
||||
|
||||
- name: Get loaded plugins
|
||||
shell: >
|
||||
find {{ config_prefix|default('/') }}etc/strongswan.d/charon/ -type f -name '*.conf' -exec basename {} \; | cut -f1 -d.
|
||||
shell: |
|
||||
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
|
||||
|
||||
- name: Disable unneeded plugins
|
||||
|
|
|
@ -2,14 +2,19 @@
|
|||
- block:
|
||||
- name: Set subjectAltName as a 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
|
||||
|
||||
- debug: var=subjectAltName
|
||||
|
||||
- name: Ensure the pki directory does not exist
|
||||
file:
|
||||
dest: "{{ ipsec_pki_path }}"
|
||||
state: absent
|
||||
when: keys_clean_all|bool == True
|
||||
when: keys_clean_all|bool
|
||||
|
||||
- name: Ensure the pki directories exist
|
||||
file:
|
||||
|
@ -182,7 +187,7 @@
|
|||
awk '{print $5}' |
|
||||
sed 's/\/CN=//g'
|
||||
args:
|
||||
chdir: "{{ ipsec_pki_path}}"
|
||||
chdir: "{{ ipsec_pki_path }}"
|
||||
register: valid_certs
|
||||
|
||||
- name: Revoke non-existing users
|
||||
|
@ -228,11 +233,11 @@
|
|||
- rereadcrls
|
||||
|
||||
- name: Delete the CA key
|
||||
local_action:
|
||||
module: file
|
||||
file:
|
||||
path: "{{ ipsec_pki_path }}/private/cakey.pem"
|
||||
state: absent
|
||||
become: false
|
||||
delegate_to: localhost
|
||||
when:
|
||||
- ipsec_enabled
|
||||
- not algo_store_cakey
|
||||
|
|
|
@ -1,18 +1,19 @@
|
|||
---
|
||||
|
||||
- set_fact:
|
||||
- name: Set OS specific facts
|
||||
set_fact:
|
||||
strongswan_additional_plugins: []
|
||||
|
||||
- name: Ubuntu | Install strongSwan
|
||||
apt:
|
||||
name: strongswan
|
||||
state: latest
|
||||
state: present
|
||||
update_cache: yes
|
||||
install_recommends: yes
|
||||
|
||||
- name: Ubuntu | Enforcing ipsec with apparmor
|
||||
shell: aa-enforce "{{ item }}"
|
||||
when: apparmor_enabled|default(false)|bool == true
|
||||
command: aa-enforce "{{ item }}"
|
||||
when: apparmor_enabled|default(false)|bool
|
||||
changed_when: false
|
||||
with_items:
|
||||
- /usr/lib/ipsec/charon
|
||||
- /usr/lib/ipsec/lookip
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
conn ikev2-{{ IP_subject_alt_name }}
|
||||
conn algovpn-{{ IP_subject_alt_name }}
|
||||
fragmentation=yes
|
||||
rekey=no
|
||||
dpdaction=clear
|
||||
|
@ -16,7 +16,7 @@ conn ikev2-{{ IP_subject_alt_name }}
|
|||
|
||||
right={{ 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
|
||||
|
||||
leftsourceip=%config
|
||||
|
|
|
@ -5,7 +5,7 @@ wireguard_pki_path: "{{ wireguard_config_path }}/.pki/"
|
|||
wireguard_interface: wg0
|
||||
keys_clean_all: false
|
||||
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 }}
|
||||
{% 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 %}
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
name: wireguard
|
||||
state: present
|
||||
|
||||
- set_fact:
|
||||
- name: Set OS specific facts
|
||||
set_fact:
|
||||
service_name: wireguard
|
||||
tags: always
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
file:
|
||||
dest: "{{ config_prefix|default('/') }}etc/wireguard/private_{{ item }}.lock"
|
||||
state: absent
|
||||
when: keys_clean_all|bool == True
|
||||
when: keys_clean_all|bool
|
||||
with_items:
|
||||
- "{{ users }}"
|
||||
- "{{ IP_subject_alt_name }}"
|
||||
|
@ -39,7 +39,10 @@
|
|||
when: wg_genkey.changed
|
||||
|
||||
- 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
|
||||
changed_when: false
|
||||
args:
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
group: root
|
||||
mode: 0644
|
||||
|
||||
- set_fact:
|
||||
- name: Set OS specific facts
|
||||
set_fact:
|
||||
service_name: "wg-quick@{{ wireguard_interface }}"
|
||||
tags: always
|
||||
|
|
|
@ -38,8 +38,7 @@
|
|||
|
||||
- block:
|
||||
- name: Dump the configuration
|
||||
local_action:
|
||||
module: copy
|
||||
copy:
|
||||
dest: "configs/{{ IP_subject_alt_name }}/.config.yml"
|
||||
content: |
|
||||
server: {{ 'localhost' if inventory_hostname == 'localhost' else inventory_hostname }}
|
||||
|
@ -59,8 +58,12 @@
|
|||
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 }}{% endif %}
|
||||
{% 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:
|
||||
|
|
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 STORE_CAKEY=true
|
||||
export LOCAL_DNS=true
|
||||
export ENDPOINT=algo.lxc
|
||||
export USERS=user1,user2
|
||||
export SSH_TUNNELING=true
|
||||
export ENDPOINT=10.0.8.100
|
||||
export USERS=desktop,user1,user2
|
||||
export EXTRA_VARS='install_headers=false tests=true apparmor_enabled=false'
|
||||
export ANSIBLE_EXTRA_ARGS='--skip-tags apparmor'
|
||||
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
|
||||
|
||||
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
|
||||
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
|
||||
ansible-playbook main.yml -e "${DEPLOY_ARGS}" --skip-tags apparmor
|
||||
fi
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
USE_LXD_BRIDGE="true"
|
||||
LXD_BRIDGE="lxdbr0"
|
||||
UPDATE_PROFILE="true"
|
||||
LXD_CONFILE=""
|
||||
LXD_CONFILE="/etc/default/algo.conf"
|
||||
LXD_DOMAIN="lxd"
|
||||
LXD_IPV4_ADDR="10.0.8.1"
|
||||
LXD_IPV4_NETMASK="255.255.255.0"
|
||||
|
@ -13,4 +13,4 @@ LXD_IPV6_ADDR=""
|
|||
LXD_IPV6_MASK=""
|
||||
LXD_IPV6_NETWORK=""
|
||||
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
|
||||
|
||||
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
|
||||
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
|
||||
ansible-playbook users.yml -e "${USER_ARGS}" -t update-users
|
||||
fi
|
||||
|
@ -15,7 +15,7 @@ fi
|
|||
# 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
|
||||
echo "The CRL check passed"
|
||||
else
|
||||
|
@ -23,7 +23,7 @@ if sudo openssl crl -inform pem -noout -text -in configs/$LXC_IP/ipsec/.pki/crl/
|
|||
exit 1
|
||||
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
|
||||
echo "The new user exists"
|
||||
else
|
||||
|
@ -35,7 +35,7 @@ fi
|
|||
# WireGuard
|
||||
#
|
||||
|
||||
if sudo test -f configs/$LXC_IP/wireguard/user1.conf
|
||||
if sudo test -f configs/10.0.8.100/wireguard/user1.conf
|
||||
then
|
||||
echo "WireGuard: The new user exists"
|
||||
else
|
||||
|
@ -47,7 +47,7 @@ fi
|
|||
# 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
|
||||
echo "SSH Tunneling: The new user exists"
|
||||
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:
|
||||
- block:
|
||||
- pause:
|
||||
- name: Server address prompt
|
||||
pause:
|
||||
prompt: "Enter the IP address of your server: (or use localhost for local installation)"
|
||||
register: _server
|
||||
when: server is undefined
|
||||
|
@ -16,14 +17,15 @@
|
|||
set_fact:
|
||||
algo_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 %}
|
||||
|
||||
- name: Import host specific variables
|
||||
include_vars:
|
||||
file: "configs/{{ algo_server }}/.config.yml"
|
||||
|
||||
- pause:
|
||||
- name: CA password prompt
|
||||
pause:
|
||||
prompt: Enter the password for the private CA key
|
||||
echo: false
|
||||
register: _ca_password
|
||||
|
@ -35,7 +37,7 @@
|
|||
set_fact:
|
||||
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 %}
|
||||
|
||||
- name: Add the server to the vpn-host group
|
||||
|
|
Loading…
Add table
Reference in a new issue