PKI to tmpfs (#1496)

* PKI to tmpfs

* Fixes
- diskutil to full path
- unmount and eject fixes

* Umount fix

* run diskutil info only on Darwin kernels

* fix shell tasks
This commit is contained in:
Jack Ivanov 2019-07-10 18:31:25 +02:00 committed by Dan Guido
parent f986811d64
commit 090a60d48d
19 changed files with 128 additions and 34 deletions

View file

@ -11,6 +11,10 @@ users:
### Advanced users only below this line ###
# Store the PKI in a ram disk. Enabled only if store_pki (retain the PKI) is set to false
# Supports on MacOS and Linux only (including Windows Subsystem for Linux)
pki_in_tmpfs: true
# If True re-init all existing certificates. Boolean
keys_clean_all: False

View file

@ -87,7 +87,7 @@ ansible-playbook main.yml -e "provider=digitalocean
dns_adblocking=false
ssh_tunneling=false
windows=false
store_cakey=true
store_pki=true
region=nyc3
do_token=token"
```

View file

@ -18,7 +18,7 @@ ansible-playbook main.yml -e "provider=digitalocean
dns_adblocking=true
ssh_tunneling=true
windows=false
store_cakey=true
store_pki=true
region=ams3
do_token=token"
```

View file

@ -19,7 +19,7 @@ The command will prepare the environment and install AlgoVPN with the default pa
`ONDEMAND_WIFI` - "Connect On Demand" when connected to Wi-Fi. Default: false.
`ONDEMAND_WIFI_EXCLUDE` - List the names of any trusted Wi-Fi networks where macOS/iOS IPsec clients should not use "Connect On Demand". Comma-separated list.
`WINDOWS` - To support Windows 10 or Linux Desktop clients. Default: false.
`STORE_CAKEY` - To retain the CA key. (required to add users in the future, but less secure). Default: false.
`STORE_PKI` - To retain the PKI. (required to add users in the future, but less secure). Default: false.
`DNS_ADBLOCKING` - To install an ad blocking DNS resolver. Default: false.
`SSH_TUNNELING` - Enable SSH tunneling for each user. Default: false.
`ENDPOINT` - The public IP address or domain name of your server: (IMPORTANT! This is used to verify the certificate). It will be gathered automatically for DigitalOcean, AWS, GCE, Azure or Vultr if the `METHOD` is cloud. Otherwise you need to define this variable according to your public IP address.

View file

@ -10,7 +10,7 @@
dns_adblocking: false
ssh_tunneling: false
windows: false
store_cakey: false
store_pki: false
providers_map:
- { name: DigitalOcean, alias: digitalocean }
- { name: Amazon Lightsail, alias: lightsail }
@ -87,13 +87,13 @@
register: _windows
when: windows is undefined
- name: Retain the CA key prompt
- name: Retain the PKI prompt
pause:
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 keys (PKI)? (required to add users in the future, but less secure)
[y/N]
register: _store_cakey
when: store_cakey is undefined
register: _store_pki
when: store_pki is undefined
when: ipsec_enabled
- name: DNS adblocking prompt
@ -145,9 +145,9 @@
{% if windows is defined %}{{ windows | bool }}
{%- elif _windows.user_input is defined %}{{ booleans_map[_windows.user_input] | default(defaults['windows']) }}
{%- else %}false{% endif %}
algo_store_cakey: >-
{% if ipsec_enabled %}{%- if store_cakey is defined %}{{ store_cakey | bool }}
{%- elif _store_cakey.user_input is defined %}{{ booleans_map[_store_cakey.user_input] | default(defaults['store_cakey']) }}
algo_store_pki: >-
{% if ipsec_enabled %}{%- if store_pki is defined %}{{ store_pki | bool }}
{%- elif _store_pki.user_input is defined %}{{ booleans_map[_store_pki.user_input] | default(defaults['store_pki']) }}
{%- else %}false{% endif %}{% endif %}
rescue:
- include_tasks: playbooks/rescue.yml

View file

@ -7,7 +7,7 @@ ONDEMAND_CELLULAR="${2:-${ONDEMAND_CELLULAR:-false}}"
ONDEMAND_WIFI="${3:-${ONDEMAND_WIFI:-false}}"
ONDEMAND_WIFI_EXCLUDE="${4:-${ONDEMAND_WIFI_EXCLUDE:-_null}}"
WINDOWS="${5:-${WINDOWS:-false}}"
STORE_CAKEY="${6:-${STORE_CAKEY:-false}}"
STORE_PKI="${6:-${STORE_PKI:-false}}"
DNS_ADBLOCKING="${7:-${DNS_ADBLOCKING:-false}}"
SSH_TUNNELING="${8:-${SSH_TUNNELING:-false}}"
ENDPOINT="${9:-${ENDPOINT:-localhost}}"
@ -92,7 +92,7 @@ deployAlgo() {
-e "ondemand_wifi=${ONDEMAND_WIFI}" \
-e "ondemand_wifi_exclude=${ONDEMAND_WIFI_EXCLUDE}" \
-e "windows=${WINDOWS}" \
-e "store_cakey=${STORE_CAKEY}" \
-e "store_pki=${STORE_PKI}" \
-e "dns_adblocking=${DNS_ADBLOCKING}" \
-e "ssh_tunneling=${SSH_TUNNELING}" \
-e "endpoint=$ENDPOINT" \

View file

@ -18,7 +18,7 @@
algo_dns_adblocking: "{{ algo_dns_adblocking }}"
algo_ssh_tunneling: "{{ algo_ssh_tunneling }}"
algo_windows: "{{ algo_windows }}"
algo_store_cakey: "{{ algo_store_cakey }}"
algo_store_pki: "{{ algo_store_pki }}"
IP_subject_alt_name: "{{ IP_subject_alt_name }}"
- name: Additional variables for the server
@ -37,6 +37,14 @@
state: present
when: cloud_instance_ip != "localhost"
- name: Mount tmpfs
import_tasks: tmpfs/main.yml
when:
- pki_in_tmpfs
- not algo_store_pki
- ansible_system == "Darwin" or
ansible_system == "Linux"
- debug:
var: IP_subject_alt_name

View file

@ -0,0 +1,5 @@
---
- name: Linux | set OS specific facts
set_fact:
tmpfs_volume_name: "AlgoVPN-{{ IP_subject_alt_name }}"
tmpfs_volume_path: /dev/shm

12
playbooks/tmpfs/macos.yml Normal file
View file

@ -0,0 +1,12 @@
---
- name: MacOS | set OS specific facts
set_fact:
tmpfs_volume_name: "AlgoVPN-{{ IP_subject_alt_name }}"
tmpfs_volume_path: /Volumes
- name: MacOS | mount a ram disk
shell: >
/usr/sbin/diskutil info "/{{ tmpfs_volume_path }}/{{ tmpfs_volume_name }}/" ||
/usr/sbin/diskutil erasevolume HFS+ "{{ tmpfs_volume_name }}" $(hdiutil attach -nomount ram://64000)
args:
creates: "/{{ tmpfs_volume_path }}/{{ tmpfs_volume_name }}"

19
playbooks/tmpfs/main.yml Normal file
View file

@ -0,0 +1,19 @@
---
- name: Include tasks for MacOS
import_tasks: macos.yml
when: ansible_system == "Darwin"
- name: Include tasks for Linux
import_tasks: linux.yml
when: ansible_system == "Linux"
- name: Set config paths as facts
set_fact:
wireguard_pki_path: "/{{ tmpfs_volume_path }}/{{ tmpfs_volume_name }}/WireGuard/"
ipsec_pki_path: "/{{ tmpfs_volume_path }}/{{ tmpfs_volume_name }}/IPsec/"
- name: Update config paths
add_host:
name: "{{ 'localhost' if cloud_instance_ip == 'localhost' else cloud_instance_ip }}"
wireguard_pki_path: "{{ wireguard_pki_path }}"
ipsec_pki_path: "{{ ipsec_pki_path }}"

View file

@ -0,0 +1,26 @@
---
- name: Linux | Delete the PKI directory
file:
path: "/{{ facts.tmpfs_volume_path }}/{{ facts.tmpfs_volume_name }}/"
state: absent
when: facts.ansible_system == "Linux"
- block:
- name: MacOS | check fs the ramdisk exists
command: /usr/sbin/diskutil info "{{ facts.tmpfs_volume_name }}"
ignore_errors: true
changed_when: false
register: diskutil_info
- name: MacOS | unmount and eject the ram disk
shell: >
/usr/sbin/diskutil umount force "/{{ facts.tmpfs_volume_path }}/{{ facts.tmpfs_volume_name }}/" &&
/usr/sbin/diskutil eject "{{ facts.tmpfs_volume_name }}"
changed_when: false
when: diskutil_info.rc == 0
register: result
until: result.rc == 0
retries: 5
delay: 3
when:
- facts.ansible_system == "Darwin"

View file

@ -8,7 +8,6 @@ algo_ondemand_cellular: false
algo_ondemand_wifi: false
algo_ondemand_wifi_exclude: '_null'
algo_windows: false
algo_store_cakey: false
algo_dns_adblocking: false
ipv6_support: false
dns_encryption: true

View file

@ -29,3 +29,13 @@
enabled: true
- meta: flush_handlers
- name: Delete the PKI directory
file:
path: "{{ ipsec_pki_path }}"
state: absent
become: false
delegate_to: localhost
when:
- not algo_store_pki
- not pki_in_tmpfs

View file

@ -231,13 +231,3 @@
- gencrl.changed
notify:
- rereadcrls
- name: Delete the CA key
file:
path: "{{ ipsec_pki_path }}/private/cakey.pem"
state: absent
become: false
delegate_to: localhost
when:
- ipsec_enabled
- not algo_store_cakey

View file

@ -1,13 +1,14 @@
---
- name: Ensure the required directories exist
file:
dest: "{{ wireguard_pki_path }}/{{ item }}"
dest: "{{ item }}"
state: directory
recurse: true
with_items:
- private
- public
- preshared
- "{{ wireguard_pki_path }}/preshared"
- "{{ wireguard_pki_path }}/private"
- "{{ wireguard_pki_path }}/public"
- "{{ wireguard_config_path }}"
delegate_to: localhost
become: false
@ -82,4 +83,14 @@
state: started
enabled: true
- name: Delete the PKI directory
file:
path: "{{ wireguard_pki_path }}"
state: absent
become: false
delegate_to: localhost
when:
- not algo_store_pki
- not pki_in_tmpfs
- meta: flush_handlers

View file

@ -51,7 +51,7 @@
algo_dns_adblocking: {{ algo_dns_adblocking }}
algo_ssh_tunneling: {{ algo_ssh_tunneling }}
algo_windows: {{ algo_windows }}
algo_store_cakey: {{ algo_store_cakey }}
algo_store_pki: {{ algo_store_pki }}
IP_subject_alt_name: {{ IP_subject_alt_name }}
ipsec_enabled: {{ ipsec_enabled }}
wireguard_enabled: {{ wireguard_enabled }}
@ -70,11 +70,21 @@
force: true
when: inventory_hostname == 'localhost'
- name: Import tmpfs tasks
import_tasks: playbooks/tmpfs/umount.yml
become: false
delegate_to: localhost
vars:
facts: "{{ hostvars['localhost'] }}"
when:
- pki_in_tmpfs
- not algo_store_pki
- debug:
msg:
- "{{ congrats.common.split('\n') }}"
- " {{ congrats.p12_pass if algo_ssh_tunneling or ipsec_enabled else '' }}"
- " {{ congrats.ca_key_pass if algo_store_cakey and ipsec_enabled else '' }}"
- " {{ congrats.ca_key_pass if algo_store_pki and ipsec_enabled else '' }}"
- " {{ congrats.ssh_access if algo_provider != 'local' else ''}}"
tags: always
rescue:

View file

@ -5,7 +5,7 @@ export ONDEMAND_CELLULAR=true
export ONDEMAND_WIFI=true
export ONDEMAND_WIFI_EXCLUDE=test1,test2
export WINDOWS=true
export STORE_CAKEY=true
export STORE_PKI=true
export DNS_ADBLOCKING=true
export SSH_TUNNELING=true
export ENDPOINT=10.0.8.100

View file

@ -2,7 +2,7 @@
set -ex
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 dns_adblocking=true ssh_tunneling=true windows=true store_cakey=true install_headers=false tests=true local_service_ip=172.16.0.1"
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 dns_adblocking=true ssh_tunneling=true windows=true store_pki=true install_headers=false tests=true local_service_ip=172.16.0.1"
if [ "${DEPLOY}" == "docker" ]
then

View file

@ -113,7 +113,7 @@
msg:
- "{{ congrats.common.split('\n') }}"
- " {{ congrats.p12_pass if algo_ssh_tunneling or ipsec_enabled else '' }}"
- " {{ congrats.ca_key_pass if algo_store_cakey and ipsec_enabled else '' }}"
- " {{ congrats.ca_key_pass if algo_store_pki and ipsec_enabled else '' }}"
- " {{ congrats.ssh_access if algo_provider != 'local' else ''}}"
tags: always
rescue: