diff --git a/README.md b/README.md index c044d3d..af9df90 100644 --- a/README.md +++ b/README.md @@ -96,7 +96,7 @@ You can now set up clients to connect to your VPN. Proceed to [Configure the VPN "# Local DNS resolver 172.16.0.1 #" "# The p12 and SSH keys password for new users is XXXXXXXX #" "# The CA key password is XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX #" - "# Shell access: ssh -F configs//ssh_config algo #" + "# Shell access: ssh -F configs//ssh_config #" ``` ## Configure the VPN Clients @@ -159,12 +159,20 @@ Use the example command below to start an SSH tunnel by replacing `` and ` Your Algo server is configured for key-only SSH access for administrative purposes. Open the Terminal app, `cd` into the `algo-master` directory where you originally downloaded Algo, and then use the command listed on the success message: - `ssh -F configs//ssh_config algo` +`ssh -F configs//ssh_config ` where `` is the IP address of your Algo server. If you find yourself regularly logging into the server then it will be useful to load your Algo ssh key automatically. Add the following snippet to the bottom of `~/.bash_profile` to add it to your shell environment permanently. `ssh-add ~/.ssh/algo > /dev/null 2>&1` +Alternatively, you can choose to include the generated configuration for any Algo servers created into your SSH config. Edit the file `~/.ssh/config` to include this directive at the top: + +``` +Include /configs/*/ssh_config +``` + +where `` is the directory where you cloned Algo. + ## Adding or Removing Users _If you chose to save the CA key during the deploy process,_ then Algo's own scripts can easily add and remove users from the VPN server. diff --git a/config.cfg b/config.cfg index 7d3027e..6446398 100644 --- a/config.cfg +++ b/config.cfg @@ -146,7 +146,7 @@ congrats: ca_key_pass: | "# The CA key password is {{ CA_password|default(omit) }} #" ssh_access: | - "# Shell access: ssh -F configs/{{ ansible_ssh_host|default(omit) }}/ssh_config algo #" + "# Shell access: ssh -F configs/{{ ansible_ssh_host|default(omit) }}/ssh_config {{ algo_server_name }} #" SSH_keys: comment: algo@ssh diff --git a/input.yml b/input.yml index cc1794b..3ee6257 100644 --- a/input.yml +++ b/input.yml @@ -52,42 +52,43 @@ when: - server_name is undefined - algo_provider != "local" - - block: - - 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 - - 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 + - name: Cellular On Demand prompt + pause: + prompt: | + Do you want macOS/iOS clients to enable "Connect On Demand" when connected to cellular networks? + [y/N] + register: _ondemand_cellular + when: ondemand_cellular is undefined - - 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) - register: _ondemand_wifi_exclude - when: - - ondemand_wifi_exclude is undefined - - (ondemand_wifi|default(false)|bool) or - (booleans_map[_ondemand_wifi.user_input|default(omit)]|default(false)) + - name: Wi-Fi On Demand prompt + pause: + prompt: | + Do you want macOS/iOS clients to enable "Connect On Demand" when connected to Wi-Fi? + [y/N] + register: _ondemand_wifi + when: ondemand_wifi is undefined - - name: Retain the PKI prompt - pause: - prompt: | - Do you want to retain the keys (PKI)? (required to add users in the future, but less secure) - [y/N] - register: _store_pki - when: store_pki is undefined - when: ipsec_enabled + - name: Trusted Wi-Fi networks prompt + pause: + prompt: | + List the names of any trusted Wi-Fi networks where macOS/iOS clients should not use "Connect On Demand" + (e.g., your home network. Comma-separated value, e.g., HomeNet,OfficeWifi,AlgoWiFi) + register: _ondemand_wifi_exclude + when: + - ondemand_wifi_exclude is undefined + - (ondemand_wifi|default(false)|bool) or + (booleans_map[_ondemand_wifi.user_input|default(omit)]|default(false)) + + - name: Retain the PKI prompt + pause: + prompt: | + Do you want to retain the keys (PKI)? (required to add users in the future, but less secure) + [y/N] + register: _store_pki + when: + - store_pki is undefined + - ipsec_enabled - name: DNS adblocking prompt pause: diff --git a/roles/common/tasks/aip/digitalocean.yml b/roles/common/tasks/aip/digitalocean.yml index cd5032f..bc01630 100644 --- a/roles/common/tasks/aip/digitalocean.yml +++ b/roles/common/tasks/aip/digitalocean.yml @@ -11,3 +11,13 @@ - name: Set SNAT IP as a fact set_fact: snat_aipv4: "{{ anchor_ipv4.content }}" + +- name: IPv6 egress alias configured + template: + src: 99-algo-ipv6-egress.yaml.j2 + dest: /etc/netplan/99-algo-ipv6-egress.yaml + when: + - ipv6_support + - ipv6_subnet_size|int > 1 + notify: + - netplan apply diff --git a/roles/common/tasks/aip/main.yml b/roles/common/tasks/aip/main.yml index 6055fd3..e644d9d 100644 --- a/roles/common/tasks/aip/main.yml +++ b/roles/common/tasks/aip/main.yml @@ -1,4 +1,9 @@ --- +- name: Verify the provider + assert: + that: algo_provider in aip_supported_providers + msg: Algo does not support Alternative Ingress IP for {{ algo_provider }} + - name: Include alternative ingress ip configuration include_tasks: file: "{{ algo_provider if algo_provider in aip_supported_providers else 'placeholder' }}.yml" diff --git a/roles/common/tasks/ubuntu.yml b/roles/common/tasks/ubuntu.yml index 6355bbf..04e9cd8 100644 --- a/roles/common/tasks/ubuntu.yml +++ b/roles/common/tasks/ubuntu.yml @@ -78,16 +78,6 @@ - name: Gather additional facts import_tasks: facts.yml -- name: IPv6 egress alias configured - template: - src: 99-algo-ipv6-egress.yaml.j2 - dest: /etc/netplan/99-algo-ipv6-egress.yaml - when: - - ipv6_support - - ipv6_subnet_size|int > 1 - notify: - - netplan apply - - name: Set OS specific facts set_fact: tools: diff --git a/roles/wireguard/tasks/main.yml b/roles/wireguard/tasks/main.yml index 4e38762..7e1fbc1 100644 --- a/roles/wireguard/tasks/main.yml +++ b/roles/wireguard/tasks/main.yml @@ -8,7 +8,8 @@ - "{{ wireguard_pki_path }}/preshared" - "{{ wireguard_pki_path }}/private" - "{{ wireguard_pki_path }}/public" - - "{{ wireguard_config_path }}" + - "{{ wireguard_config_path }}/apple/ios" + - "{{ wireguard_config_path }}/apple/macos" delegate_to: localhost become: false @@ -51,6 +52,13 @@ vars: index: "{{ item.0 }}" + - include_tasks: mobileconfig.yml + loop: + - ios + - macos + loop_control: + loop_var: system + - name: Generate QR codes shell: > umask 077; diff --git a/roles/wireguard/tasks/mobileconfig.yml b/roles/wireguard/tasks/mobileconfig.yml new file mode 100644 index 0000000..0e192b4 --- /dev/null +++ b/roles/wireguard/tasks/mobileconfig.yml @@ -0,0 +1,10 @@ +--- +- name: WireGuard apple mobileconfig generated + template: + src: mobileconfig.j2 + dest: "{{ wireguard_config_path }}/apple/{{ system }}/{{ item.1 }}.mobileconfig" + mode: "0600" + with_indexed_items: "{{ wireguard_users }}" + when: item.1 in users + vars: + index: "{{ item.0 }}" diff --git a/roles/wireguard/templates/mobileconfig.j2 b/roles/wireguard/templates/mobileconfig.j2 new file mode 100644 index 0000000..6c3f33e --- /dev/null +++ b/roles/wireguard/templates/mobileconfig.j2 @@ -0,0 +1,25 @@ +#jinja2:lstrip_blocks: True + + + + + PayloadContent + + {% include 'vpn-dict.j2' %} + + PayloadDisplayName + AlgoVPN {{ algo_server_name }} WireGuard + PayloadIdentifier + donut.local.{{ 500000 | random | to_uuid | upper }} + PayloadOrganization + AlgoVPN + PayloadRemovalDisallowed + + PayloadType + Configuration + PayloadUUID + {{ 400000 | random | to_uuid | upper }} + PayloadVersion + 1 + + diff --git a/roles/wireguard/templates/vpn-dict.j2 b/roles/wireguard/templates/vpn-dict.j2 new file mode 100644 index 0000000..6444df9 --- /dev/null +++ b/roles/wireguard/templates/vpn-dict.j2 @@ -0,0 +1,94 @@ + + IPv4 + + OverridePrimary + 1 + + PayloadDescription + Configures VPN settings + PayloadDisplayName + {{ algo_server_name }} + PayloadIdentifier + com.apple.vpn.managed.{{ algo_server_name + system | to_uuid | upper }} + PayloadType + com.apple.vpn.managed + PayloadUUID + {{ algo_server_name + system | to_uuid | upper }} + PayloadVersion + 1 + Proxies + + HTTPEnable + 0 + HTTPSEnable + 0 + + UserDefinedName + AlgoVPN {{ algo_server_name }} + VPN + + OnDemandEnabled + {{ 1 if algo_ondemand_wifi or algo_ondemand_cellular else 0 }} + OnDemandRules + + {% if algo_ondemand_wifi or algo_ondemand_cellular %} + {% if algo_ondemand_wifi_exclude|b64decode != '_null' %} + {% set WIFI_EXCLUDE_LIST = (algo_ondemand_wifi_exclude|b64decode|string).split(',') %} + + Action + Disconnect + InterfaceTypeMatch + WiFi + SSIDMatch + + {% for network_name in WIFI_EXCLUDE_LIST %} + {{ network_name|e }} + {% endfor %} + + + {% endif %} + + Action + {% if algo_ondemand_wifi %} + Connect + {% else %} + Disconnect + {% endif %} + InterfaceTypeMatch + WiFi + URLStringProbe + http://captive.apple.com/hotspot-detect.html + + + Action + {% if algo_ondemand_cellular %} + Connect + {% else %} + Disconnect + {% endif %} + InterfaceTypeMatch + Cellular + URLStringProbe + http://captive.apple.com/hotspot-detect.html + + {% endif %} + + Action + {{ 'Disconnect' if algo_ondemand_wifi or algo_ondemand_cellular else 'Connect' }} + + + AuthenticationMethod + Password + RemoteAddress + {{ IP_subject_alt_name }}:{{ wireguard_port }} + + VPNSubType + com.wireguard.{{ system }} + VPNType + VPN + VendorConfig + + WgQuickConfig + {{- lookup('template', 'client.conf.j2') | indent(8) }} + + diff --git a/server.yml b/server.yml index fb472f0..54551eb 100644 --- a/server.yml +++ b/server.yml @@ -28,11 +28,11 @@ dest: "configs/{{ IP_subject_alt_name }}/ssh_config" mode: "0600" content: | - Host {{ IP_subject_alt_name }} algo + Host {{ IP_subject_alt_name }} {{ algo_server_name }} HostName {{ IP_subject_alt_name }} User {{ ansible_ssh_user }} Port {{ ansible_ssh_port }} - IdentityFile {{ SSH_keys.private }} + IdentityFile {{ SSH_keys.private | realpath }} KeepAlive yes ServerAliveInterval 30 when: inventory_hostname != 'localhost' diff --git a/tests/wireguard-client.sh b/tests/wireguard-client.sh index 46b4603..cc7d652 100755 --- a/tests/wireguard-client.sh +++ b/tests/wireguard-client.sh @@ -2,6 +2,8 @@ set -euxo pipefail +xmllint --noout ./configs/10.0.8.100/wireguard/apple/*/*.mobileconfig + crudini --set configs/10.0.8.100/wireguard/user1.conf Interface Table off wg-quick up configs/10.0.8.100/wireguard/user1.conf