This commit is contained in:
Jack Ivanov 2018-05-10 14:44:28 +00:00 committed by GitHub
commit 157131640e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 90 additions and 136 deletions

84
algo
View file

@ -22,53 +22,51 @@ additional_roles () {
read -p "
Do you want macOS/iOS clients to enable \"VPN On Demand\" when connected to cellular networks?
[y/N]: " -r OnDemandEnabled_Cellular
OnDemandEnabled_Cellular=${OnDemandEnabled_Cellular:-n}
if [[ "$OnDemandEnabled_Cellular" =~ ^(y|Y)$ ]]; then EXTRA_VARS+=" OnDemandEnabled_Cellular=Y"; fi
OnDemandEnabled_Cellular=${OnDemandEnabled_Cellular:-false}
if [[ "$OnDemandEnabled_Cellular" =~ ^(y|Y)$ ]]; then EXTRA_VARS+=", OnDemandEnabled_Cellular: true"; fi
read -p "
Do you want macOS/iOS clients to enable \"VPN On Demand\" when connected to Wi-Fi?
[y/N]: " -r OnDemandEnabled_WIFI
OnDemandEnabled_WIFI=${OnDemandEnabled_WIFI:-n}
if [[ "$OnDemandEnabled_WIFI" =~ ^(y|Y)$ ]]; then EXTRA_VARS+=" OnDemandEnabled_WIFI=Y"; fi
OnDemandEnabled_WIFI=${OnDemandEnabled_WIFI:-false}
if [[ "$OnDemandEnabled_WIFI" =~ ^(y|Y)$ ]]; then EXTRA_VARS+=", OnDemandEnabled_WIFI: true"; fi
if [[ "$OnDemandEnabled_WIFI" =~ ^(y|Y)$ ]]; then
read -p "
List the names of trusted Wi-Fi networks (if any) that macOS/iOS clients exclude from using the VPN (e.g., your home network. Comma-separated value, e.g., HomeNet,OfficeWifi,AlgoWiFi)
: " -r OnDemandEnabled_WIFI_EXCLUDE
OnDemandEnabled_WIFI_EXCLUDE=${OnDemandEnabled_WIFI_EXCLUDE:-_null}
EXTRA_VARS+=" OnDemandEnabled_WIFI_EXCLUDE=\"$OnDemandEnabled_WIFI_EXCLUDE\""
EXTRA_VARS+=", OnDemandEnabled_WIFI_EXCLUDE: \"$OnDemandEnabled_WIFI_EXCLUDE\""
fi
read -p "
Do you want to install a DNS resolver on this VPN server, to block ads while surfing?
[y/N]: " -r dns_enabled
dns_enabled=${dns_enabled:-n}
if [[ "$dns_enabled" =~ ^(y|Y)$ ]]; then ROLES+=" dns"; EXTRA_VARS+=" local_dns=true"; fi
if [[ "$dns_enabled" =~ ^(y|Y)$ ]]; then ROLES+=" dns"; EXTRA_VARS+=", local_dns: true"; fi
read -p "
Do you want each user to have their own account for SSH tunneling?
[y/N]: " -r ssh_tunneling_enabled
ssh_tunneling_enabled=${ssh_tunneling_enabled:-n}
if [[ "$ssh_tunneling_enabled" =~ ^(y|Y)$ ]]; then ROLES+=" ssh_tunneling"; fi
[y/N]: " -r ssh_tunneling
ssh_tunneling=${ssh_tunneling:-false}
if [[ "$ssh_tunneling" =~ ^(y|Y)$ ]]; then ROLES+=" ssh_tunneling"; EXTRA_VARS+=", ssh_tunneling: true"; fi
read -p "
Do you want the VPN to support Windows 10 or Linux Desktop clients? (enables compatible ciphers and key exchange, less secure)
[y/N]: " -r Win10_Enabled
Win10_Enabled=${Win10_Enabled:-n}
if [[ "$Win10_Enabled" =~ ^(y|Y)$ ]]; then EXTRA_VARS+=" Win10_Enabled=Y"; fi
Win10_Enabled=${Win10_Enabled:-false}
if [[ "$Win10_Enabled" =~ ^(y|Y)$ ]]; then EXTRA_VARS+=", Win10_Enabled: true"; fi
read -p "
Do you want to retain the CA key? (required to add users in the future, but less secure)
[y/N]: " -r Store_CAKEY
Store_CAKEY=${Store_CAKEY:-N}
if [[ "$Store_CAKEY" =~ ^(n|N)$ ]]; then EXTRA_VARS+=" Store_CAKEY=N"; fi
Store_CAKEY=${Store_CAKEY:-false}
if [[ "$Store_CAKEY" =~ ^(y|Y)$ ]]; then EXTRA_VARS+=", Store_CAKEY: true"; fi
}
deploy () {
ansible-playbook deploy.yml -t "${ROLES// /,}" -e "${EXTRA_VARS}" --skip-tags "${SKIP_TAGS// /,}"
ansible-playbook deploy.yml -t "${ROLES// /,}" -e "{${EXTRA_VARS}}" --skip-tags "${SKIP_TAGS// /,}"
}
azure () {
@ -181,7 +179,7 @@ Enter the number of your desired region:
esac
ROLES="azure vpn cloud"
EXTRA_VARS="azure_secret=$azure_secret azure_tenant=$azure_tenant azure_client_id=$azure_client_id azure_subscription_id=$azure_subscription_id azure_server_name=$azure_server_name ssh_public_key=$ssh_public_key region=$region"
EXTRA_VARS="azure_secret: $azure_secret, azure_tenant: $azure_tenant, azure_client_id: $azure_client_id, azure_subscription_id: $azure_subscription_id, azure_server_name: $azure_server_name ssh_public_key: $ssh_public_key, region: $region"
}
digitalocean () {
@ -232,7 +230,7 @@ Enter the number of your desired region:
esac
ROLES="digitalocean vpn cloud"
EXTRA_VARS="do_access_token=$do_access_token do_server_name=$do_server_name do_region=$do_region"
EXTRA_VARS="do_access_token: $do_access_token, do_server_name: $do_server_name, do_region: $do_region"
}
ec2 () {
@ -298,7 +296,7 @@ Enter the number of your desired region:
esac
ROLES="ec2 vpn cloud"
EXTRA_VARS="aws_access_key=$aws_access_key aws_secret_key=$aws_secret_key aws_server_name=$aws_server_name region=$region"
EXTRA_VARS="aws_access_key: $aws_access_key, aws_secret_key: $aws_secret_key, aws_server_name: $aws_server_name, region: $region"
}
lightsail () {
@ -356,7 +354,7 @@ algo_region=${algo_region:-1}
esac
ROLES="lightsail vpn cloud"
EXTRA_VARS="aws_access_key=$aws_access_key aws_secret_key=$aws_secret_key algo_server_name=$algo_server_name region=$region"
EXTRA_VARS="aws_access_key: $aws_access_key, aws_secret_key: $aws_secret_key, algo_server_name: $algo_server_name, region: $region"
}
scaleway () {
@ -392,7 +390,7 @@ algo_region=${algo_region:-1}
esac
ROLES="scaleway vpn cloud"
EXTRA_VARS="scaleway_auth_token=$scaleway_auth_token scaleway_organization=\"$scaleway_organization\" algo_server_name=$algo_server_name algo_region=$region"
EXTRA_VARS="scaleway_auth_token: $scaleway_auth_token, scaleway_organization: \"$scaleway_organization\", algo_server_name: $algo_server_name, algo_region: $region"
}
openstack () {
@ -407,7 +405,7 @@ Name the vpn server:
algo_server_name=${algo_server_name:-algo.local}
ROLES="openstack vpn cloud"
EXTRA_VARS="algo_server_name=$algo_server_name"
EXTRA_VARS="algo_server_name: $algo_server_name"
source $os_rc
}
@ -506,7 +504,7 @@ Please choose the number of your zone. Press enter for default (#14) zone.
esac
ROLES="gce vpn cloud"
EXTRA_VARS="credentials_file=$credentials_file gce_server_name=$server_name ssh_public_key=$ssh_public_key zone=$zone max_mss=1316"
EXTRA_VARS="credentials_file: $credentials_file, gce_server_name: $server_name, ssh_public_key: $ssh_public_key, zone: $zone, max_mss: 1316"
}
non_cloud () {
@ -539,16 +537,8 @@ if [ "x${IP_subject}" = "x" ]; then
fi
ROLES="local vpn"
EXTRA_VARS="server_ip=$server_ip server_user=$server_user IP_subject_alt_name=$IP_subject"
EXTRA_VARS="server_ip: $server_ip, server_user: $server_user, IP_subject_alt_name: $IP_subject"
SKIP_TAGS+=" cloud update-alternatives"
read -p "
Was this server deployed by Algo previously?
[y/N]: " -r Deployed_By_Algo
Deployed_By_Algo=${Deployed_By_Algo:-n}
if [[ "$Deployed_By_Algo" =~ ^(y|Y)$ ]]; then EXTRA_VARS+=" Deployed_By_Algo=Y"; fi
}
algo_provisioning () {
@ -585,44 +575,16 @@ Enter the number of your desired provider
}
user_management () {
read -p "
Enter the IP address of your server: (or use localhost for local installation)
: " -r server_ip
read -p "
What user should we use to login on the server? (note: passwordless login required, or ignore if you're deploying to localhost)
[root]: " -r server_user
server_user=${server_user:-root}
read -p "
Do you want each user to have their own account for SSH tunneling?
[y/N]: " -r ssh_tunneling_enabled
ssh_tunneling_enabled=${ssh_tunneling_enabled:-n}
if [ "x${server_ip}" = "xlocalhost" ]; then
myip=""
else
myip=${server_ip}
fi
read -p "
Enter the public IP address of your server: (IMPORTANT! This IP is used to verify the certificate)
[$myip]: " -r IP_subject
IP_subject=${IP_subject:-$myip}
if [ "x${IP_subject}" = "x" ]; then
echo "no server IP given. exiting."
exit 1
fi
read -p "
Enter the password for the private CA key:
$ADDITIONAL_PROMPT
: " -rs easyrsa_CA_password
ansible-playbook users.yml -e "server_ip=$server_ip server_user=$server_user ssh_tunneling_enabled=$ssh_tunneling_enabled IP_subject_alt_name=$IP_subject easyrsa_CA_password=$easyrsa_CA_password" -t update-users --skip-tags common
ansible-playbook users.yml -e "server_ip=$server_ip easyrsa_CA_password=$easyrsa_CA_password" -t update-users --skip-tags common
}
case "$1" in

View file

@ -9,12 +9,6 @@
- name: Local pre-tasks
include_tasks: playbooks/local.yml
tags: [ 'always' ]
- name: Local pre-tasks
include_tasks: playbooks/local_ssh.yml
become: false
when: Deployed_By_Algo is defined and Deployed_By_Algo == "Y"
tags: [ 'local' ]
rescue:
- debug: var=fail_hint
tags: always
@ -69,30 +63,45 @@
post_tasks:
- block:
- name: Delete the CA key
local_action:
module: file
path: "configs/{{ IP_subject_alt_name }}/pki/private/cakey.pem"
state: absent
become: false
when: not Store_CAKEY
- name: Dump the configuration
local_action:
module: copy
dest: "configs/{{ IP_subject_alt_name }}/config.yml"
content: |
server_ip: {{ ansible_ssh_host }}
server_user: {{ ansible_ssh_user }}
ansible_ssh_private_key_file: {{ ansible_ssh_private_key_file|default(SSH_keys.private) }}
ssh_tunneling: {{ ssh_tunneling }}
IP_subject_alt_name: {{ IP_subject_alt_name }}
OnDemandEnabled_Cellular: {{ OnDemandEnabled_Cellular }}
OnDemandEnabled_WIFI: {{ OnDemandEnabled_WIFI }}
OnDemandEnabled_WIFI_EXCLUDE: '{{ OnDemandEnabled_WIFI_EXCLUDE }}'
Win10_Enabled: {{ Win10_Enabled }}
become: false
- debug:
msg:
- "{{ congrats.common.split('\n') }}"
- " {{ congrats.p12_pass }}"
- " {% if Store_CAKEY is defined and Store_CAKEY == 'N' %}{% else %}{{ congrats.ca_key_pass }}{% endif %}"
- " {% if Store_CAKEY %}{{ congrats.ca_key_pass }}{% endif %}"
- " {% if cloud_deployment is defined %}{{ congrats.ssh_access }}{% endif %}"
tags: always
rescue:
- debug: var=fail_hint
tags: always
- fail:
tags: always
- name: Save the CA key password
local_action: >
shell echo "{{ easyrsa_CA_password }}" > /tmp/ca_password
become: no
tags: tests
- name: Delete the CA key
local_action:
module: file
path: "configs/{{ IP_subject_alt_name }}/pki/private/cakey.pem"
state: absent
become: no
tags: always
when: Store_CAKEY is defined and Store_CAKEY == "N"
rescue:
- debug: var=fail_hint
tags: always
- fail:
tags: always

View file

@ -35,9 +35,9 @@ Server roles:
Note: The `vpn` role generates Apple profiles with On-Demand Wifi and Cellular if you pass the following variables:
- OnDemandEnabled_WIFI=Y
- OnDemandEnabled_WIFI_EXCLUDE=HomeNet
- OnDemandEnabled_Cellular=Y
- OnDemandEnabled_WIFI: true
- OnDemandEnabled_WIFI_EXCLUDE: HomeNet,OfficeWifi
- OnDemandEnabled_Cellular: true
### Local Installation

View file

@ -1,12 +0,0 @@
---
- name: Ensure the local ssh directory is exist
file:
path: ~/.ssh/
state: directory
- name: Copy the algo ssh key to the local ssh directory
copy:
src: "{{ SSH_keys.private }}"
dest: ~/.ssh/algo.pem
mode: '0600'

View file

@ -12,5 +12,3 @@
- name: A short pause, in order to be sure the instance is ready
pause:
seconds: 20
- include_tasks: local_ssh.yml

View file

@ -4,4 +4,4 @@ dependencies:
- { role: common, tags: common }
- role: dns_encryption
tags: dns_encryption
when: dns_encryption == true
when: dns_encryption

View file

@ -88,7 +88,7 @@ no-resolv
# You can control how dnsmasq talks to a server: this forces
# queries to 10.1.2.3 to be routed via eth1
# server=10.1.2.3@eth1
{% if dns_encryption|default(false)|bool == true %}
{% if dns_encryption %}
server={{ local_service_ip }}#5353
{% else %}
{% for host in dns_servers.ipv4 %}

View file

@ -1,7 +1,9 @@
---
listen_port: "{% if local_dns|d(false)|bool == true %}5353{% else %}53{% endif %}"
local_dns: false
listen_port: "{% if local_dns %}5353{% else %}53{% endif %}"
# the version used if the latest unavailable (in case of Github API rate limited)
dnscrypt_proxy_version: 2.0.10
apparmor_enabled: true
dns_encryption: true
dns_encryption_provider: "*"
ipv6_support: false

View file

@ -88,7 +88,7 @@
shell: >
getent group algo | cut -f4 -d: | sed "s/,/\n/g"
register: valid_users
when: ssh_tunneling_enabled is defined and ssh_tunneling_enabled == "y"
when: ssh_tunneling
- name: SSH | Delete non-existing users
user:
@ -96,7 +96,7 @@
state: absent
remove: yes
force: yes
when: item not in users and ssh_tunneling_enabled is defined and ssh_tunneling_enabled == "y"
when: item not in users and ssh_tunneling
with_items: "{{ valid_users.stdout_lines | default('null') }}"
rescue:
- debug: var=fail_hint

View file

@ -1,5 +1,12 @@
---
OnDemandEnabled_Cellular: false
OnDemandEnabled_WIFI: false
OnDemandEnabled_WIFI_EXCLUDE: '_null'
Win10_Enabled: false
Store_CAKEY: false
local_dns: false
ipv6_support: false
dns_encryption: true
domain: false
subjectAltName_IP: "IP:{{ IP_subject_alt_name }}"
openssl_bin: openssl

View file

@ -4,4 +4,4 @@ dependencies:
- { role: common, tags: common }
- role: dns_encryption
tags: dns_encryption
when: dns_encryption == true
when: dns_encryption

View file

@ -56,23 +56,12 @@
with_items:
- "{{ users }}"
- name: Create the windows check file
file:
state: touch
path: configs/{{ IP_subject_alt_name }}/.supports_windows
when: Win10_Enabled is defined and Win10_Enabled == "Y"
- name: Check if the windows check file exists
stat:
path: configs/{{ IP_subject_alt_name }}/.supports_windows
register: supports_windows
- name: Build the windows client powershell script
template:
src: client_windows.ps1.j2
dest: configs/{{ IP_subject_alt_name }}/windows_{{ item.0 }}.ps1
mode: 0600
when: Win10_Enabled is defined and Win10_Enabled == "Y" or supports_windows.stat.exists == true
when: Win10_Enabled
with_together:
- "{{ users }}"
- "{{ PayloadContent.results }}"

View file

@ -6,7 +6,7 @@ conn ikev2-{{ IP_subject_alt_name }}
compress=no
dpddelay=35s
{% if Win10_Enabled is defined and Win10_Enabled == "Y" %}
{% if Win10_Enabled %}
ike={{ ciphers.compat.ike }}
esp={{ ciphers.compat.esp }}
{% else %}

View file

@ -10,7 +10,7 @@ conn %default
compress=yes
dpddelay=35s
{% if Win10_Enabled is defined and Win10_Enabled == "Y" %}
{% if Win10_Enabled %}
ike={{ ciphers.compat.ike }}
esp={{ ciphers.compat.esp }}
{% else %}
@ -28,7 +28,7 @@ conn %default
right=%any
rightauth=pubkey
rightsourceip={{ vpn_network }},{{ vpn_network_ipv6 }}
{% if local_dns|d(false)|bool == true or dns_encryption|d(false)|bool == true %}
{% if local_dns or dns_encryption %}
rightdns={{ local_service_ip }}
{% else %}
rightdns={% 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 %}

View file

@ -7,12 +7,12 @@
<dict>
<key>IKEv2</key>
<dict>
{% if (OnDemandEnabled_WIFI is defined and OnDemandEnabled_WIFI == 'Y') or (OnDemandEnabled_Cellular is defined and OnDemandEnabled_Cellular == 'Y') %}
{% if OnDemandEnabled_WIFI or OnDemandEnabled_Cellular %}
<key>OnDemandEnabled</key>
<integer>1</integer>
<key>OnDemandRules</key>
<array>
{% if OnDemandEnabled_WIFI_EXCLUDE is defined and OnDemandEnabled_WIFI_EXCLUDE != '_null' %}
{% if OnDemandEnabled_WIFI_EXCLUDE != '_null' %}
{% set WIFI_EXCLUDE_LIST = OnDemandEnabled_WIFI_EXCLUDE.split(',') %}
<dict>
<key>Action</key>
@ -30,7 +30,7 @@
{% endif %}
<dict>
<key>Action</key>
{% if OnDemandEnabled_WIFI is defined and OnDemandEnabled_WIFI == 'Y' %}
{% if OnDemandEnabled_WIFI %}
<string>Connect</string>
{% else %}
<string>Disconnect</string>
@ -42,7 +42,7 @@
</dict>
<dict>
<key>Action</key>
{% if OnDemandEnabled_Cellular is defined and OnDemandEnabled_Cellular == 'Y' %}
{% if OnDemandEnabled_Cellular %}
<string>Connect</string>
{% else %}
<string>Disconnect</string>

View file

@ -2,7 +2,7 @@
set -ex
DEPLOY_ARGS="server_ip=$LXC_IP server_user=ubuntu IP_subject_alt_name=$LXC_IP local_dns=true dns_over_https=true apparmor_enabled=false"
DEPLOY_ARGS="{server_ip: $LXC_IP, server_user: ubuntu, IP_subject_alt_name: $LXC_IP, local_dns: true, dns_over_https: true, apparmor_enabled: false, ssh_tunneling: true}"
if [ "${LXC_NAME}" == "docker" ]
then

View file

@ -3,9 +3,8 @@
set -ex
CAPW=`cat /tmp/ca_password`
USER_ARGS="server_ip=$LXC_IP server_user=ubuntu ssh_tunneling_enabled=y IP_subject=$LXC_IP easyrsa_CA_password=$CAPW"
sed -i 's/- jack$/- jack_test/' config.cfg
USER_ARGS="server_ip=$LXC_IP easyrsa_CA_password=$CAPW users=['user1', 'user2']"
USERS=""
if [ "${LXC_NAME}" == "docker" ]
then
@ -24,7 +23,7 @@ if openssl crl -inform pem -noout -text -in crl/jack.crt | grep CRL
exit 1
fi
if openssl x509 -inform pem -noout -text -in certs/jack_test.crt | grep CN=jack_test
if openssl x509 -inform pem -noout -text -in certs/user1.crt | grep CN=user1
then
echo "The new user exists"
else

View file

@ -5,6 +5,7 @@
tags: always
vars_files:
- config.cfg
- "configs/{{ server_ip }}/config.yml"
tasks:
- block:
@ -12,12 +13,10 @@
add_host:
hostname: "{{ server_ip }}"
groupname: vpn-host
ansible_ssh_user: "{{ server_user }}"
ansible_ssh_user: "{{ server_user|default(root) }}"
ansible_python_interpreter: "/usr/bin/python2.7"
ssh_tunneling_enabled: "{{ ssh_tunneling_enabled }}"
easyrsa_CA_password: "{{ easyrsa_CA_password }}"
IP_subject: "{{ IP_subject_alt_name }}"
ansible_ssh_private_key_file: "{{ SSH_keys.private }}"
ansible_ssh_private_key_file: "{{ ansible_ssh_private_key_file }}"
- name: Wait until SSH becomes ready...
local_action:
@ -41,6 +40,7 @@
become: true
vars_files:
- config.cfg
- "configs/{{ server_ip }}/config.yml"
pre_tasks:
- block:
@ -54,7 +54,7 @@
tags: always
roles:
- { role: ssh_tunneling, tags: always, when: ssh_tunneling_enabled is defined and ssh_tunneling_enabled == "y" }
- { role: ssh_tunneling, tags: always, when: ssh_tunneling }
- { role: vpn }
post_tasks: