From 9e0ee4faa46233372b011fe4a0da4f37b5263b89 Mon Sep 17 00:00:00 2001 From: Kevin Chen Date: Wed, 12 Apr 2017 20:05:48 -0400 Subject: [PATCH] Directly run ansible-playbook for less fragility. Also, the user no longer needs to specify their cloud host -- we try different in-VPS metadata URLs until one works. --- README.md | 3 +- cloud-init-algo-vpn.sh | 113 +++++++++++++++++++++++++++++------------ 2 files changed, 81 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index 65b8654..770a617 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,7 @@ Some driver scripts for [Algo][algo-gh]. How to use: 1. In `config.cfg` put your name under `users`. -2. In the `cmd` generation code, specify your cloud provider. -3. Paste the entire script into your provider's cloud-init box when creating +2. Paste the entire script into your provider's cloud-init box when creating your VPS. If you're just experimenting, you can launch a free DigitalOcean instance for 2 diff --git a/cloud-init-algo-vpn.sh b/cloud-init-algo-vpn.sh index 7cee50c..26657f2 100644 --- a/cloud-init-algo-vpn.sh +++ b/cloud-init-algo-vpn.sh @@ -1,22 +1,53 @@ #!/bin/bash +set -e + # Cloud-init script for noninteractive installation of Algo # Please set your cloud provider toward the end of the script. +# Test an IP address for validity: +# Usage: +# valid_ip IP_ADDRESS +# if [[ $? -eq 0 ]]; then echo good; else echo bad; fi +# OR +# if valid_ip IP_ADDRESS; then echo good; else echo bad; fi +# +# Source: http://www.linuxjournal.com/content/validating-ip-address-bash-script +function valid_ip() +{ + local ip=$1 + local stat=1 + + if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then + OIFS=$IFS + IFS='.' + ip=($ip) + IFS=$OIFS + [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \ + && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]] + stat=$? + fi + return $stat +} + # not available during cloud-init export HOME="/root" -apt update && apt upgrade +apt update +apt upgrade -y # install algo dependencies apt install -y python-setuptools build-essential libssl-dev libffi-dev python-dev # install my packages apt install -y htop iftop sl cd /root -git clone https://github.com/trailofbits/algo.git && cd algo +git clone https://github.com/trailofbits/algo.git +cd algo # People keep breaking algo and I know this commit was stable git checkout 2798f84d3fdbaf8289ebbe9ec384a266d8ad4b1d -easy_install pip && pip install -r requirements.txt + +easy_install pip +pip install -r requirements.txt cat < config.cfg --- @@ -111,36 +142,52 @@ SSH_keys: public: configs/algo.pem.pub END -# desired provider (existing ubuntu server) -touch cmd -echo 5 >> cmd -# Enter IP address of your server: (use localhost for local installation) -echo localhost >> cmd -# What user should we use to login on the server? (ignore if you're deploying to localhost) -echo >> cmd -# Enter the public IP address of your server: (IMPORTANT! This IP is used to verify the certificate) -google="curl http://169.254.169.254/computeMetadata/v1/instance/network-interfaces/0/access-configs/0/external-ip -H \"Metadata-Flavor: Google\"" -digitalocean="curl http://169.254.169.254/metadata/v1/interfaces/public/0/ipv4/address" -aws="curl http://instance-data/latest/meta-data/public-ipv4" -echo $(eval "$digitalocean") >> cmd -# Do you want to apply security enhancements? (documented in docs/ROLES.md) -echo y >> cmd -# Do you want to install an HTTP proxy to block ads and decrease traffic usage while surfing? -echo n >> cmd -# Do you want to install a local DNS resolver to block ads while surfing? -echo n >> cmd -# Do you want to use auditd for security monitoring (see config.cfg)? -echo y >> cmd -# Do you want each user to have their own account for SSH tunneling? -echo y >> cmd -# Do you want to enable VPN always when connected to Wi-Fi? -echo n >> cmd -# Do you want to enable VPN always when connected to the cellular network? -echo n >> cmd -# Do you want to enable VPN for Windows 10 clients? (Will use insecure algorithms and ciphers) -echo n >> cmd - -./algo < cmd +google="curl --silent http://169.254.169.254/computeMetadata/v1/instance/network-interfaces/0/access-configs/0/external-ip -H \"Metadata-Flavor: Google\"" +digitalocean="curl --silent http://169.254.169.254/metadata/v1/interfaces/public/0/ipv4/address" +aws="curl --silent http://instance-data/latest/meta-data/public-ipv4" +declare -a cmds=("$digitalocean" "$aws" "$google") +nr_cmds=${#cmds[@]} +for (( i=0; i<${nr_cmds}; i++ )); do + set +e + ip=$(eval "${cmds[$i]}") + if [ $? -eq 0 ] && valid_ip "$ip"; then + echo "$ip" + break + fi + set -e +done + +# Set up VPN and SSH tunneling accounts on the local machine +# Also, apply security enhancements +tags='local vpn ssh_tunneling security' + +# In the algo driver script, these tags are always skipped +skip_tags='_null encrypted' + +# Since we already know the public IP +skip_tags="$skip_tags cloud update-alternatives" + +options='' +# Since we're installing on local machine +options="$options server_ip=localhost server_user=`whoami`" + +# Find our IP address using a cloud data service. Required for certificates. +ip=$(eval "$digitalocean") +options="$options IP_subject_alt_name=$ip" + +# Causes the vpn role to generate a .mobileconfig for installing the client +# certificate on Apple devices. +# Can optionally pass "OnDemandEnabled_WIFI_EXCLUDE=\"A,B,C\"" to disconnect the +# VPN upon connecting to networks named A, B, or C. +options="$options OnDemandEnabled_WIFI=Y" +options="$options OnDemandEnabled_WIFI_EXCLUDE=\"\"" +options="$options OnDemandEnabled_Cellular=Y" + +tags="${tags// /,}" +skip_tags="${skip_tags// /,}" + +echo "Running with args: -t $tags -e $options --skip-tags $skip_tags" +ansible-playbook deploy.yml -t "$tags" -e "$options" --skip-tags "$skip_tags" # Private keys are world readable by default :( chmod 600 configs/*