mirror of
https://github.com/trailofbits/algo.git
synced 2025-06-06 15:13:56 +02:00
Refactoring (#1334)
<!--- Provide a general summary of your changes in the Title above --> ## Description Renames the vpn role to strongswan, and split up the variables to support 2 separate VPNs. Closes #1330 and closes #1162 Configures Ansible to use python3 on the server side. Closes #1024 Removes unneeded playbooks, reorganises a lot of variables Reorganises the `config` folder. Closes #1330 <details><summary>Here is how the config directory looks like now</summary> <p> ``` configs/X.X.X.X/ |-- ipsec | |-- apple | | |-- desktop.mobileconfig | | |-- laptop.mobileconfig | | `-- phone.mobileconfig | |-- manual | | |-- cacert.pem | | |-- desktop.p12 | | |-- desktop.ssh.pem | | |-- ipsec_desktop.conf | | |-- ipsec_desktop.secrets | | |-- ipsec_laptop.conf | | |-- ipsec_laptop.secrets | | |-- ipsec_phone.conf | | |-- ipsec_phone.secrets | | |-- laptop.p12 | | |-- laptop.ssh.pem | | |-- phone.p12 | | `-- phone.ssh.pem | `-- windows | |-- desktop.ps1 | |-- laptop.ps1 | `-- phone.ps1 |-- ssh-tunnel | |-- desktop.pem | |-- desktop.pub | |-- laptop.pem | |-- laptop.pub | |-- phone.pem | |-- phone.pub | `-- ssh_config `-- wireguard |-- desktop.conf |-- desktop.png |-- laptop.conf |-- laptop.png |-- phone.conf `-- phone.png ```  </p> </details> ## Motivation and Context This refactoring is focused to aim to the 1.0 release ## How Has This Been Tested? Deployed to several cloud providers with various options enabled and disabled ## Types of changes <!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: --> - [x] Refactoring ## Checklist: <!--- Go over all the following points, and put an `x` in all the boxes that apply. --> <!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! --> - [x] I have read the **CONTRIBUTING** document. - [x] My code follows the code style of this project. - [x] My change requires a change to the documentation. - [x] I have updated the documentation accordingly. - [x] All new and existing tests passed.
This commit is contained in:
parent
7e7476ec6b
commit
273c7665d3
42 changed files with 360 additions and 365 deletions
|
@ -123,9 +123,9 @@ Install strongSwan, then copy the included ipsec_user.conf, ipsec_user.secrets,
|
||||||
#### Ubuntu Server 18.04 example
|
#### Ubuntu Server 18.04 example
|
||||||
|
|
||||||
1. `sudo apt-get install strongswan libstrongswan-standard-plugins`: install strongSwan
|
1. `sudo apt-get install strongswan libstrongswan-standard-plugins`: install strongSwan
|
||||||
2. `/etc/ipsec.d/certs`: copy `<name>.crt` from `algo-master/configs/<server_ip>/pki/certs/<name>.crt`
|
2. `/etc/ipsec.d/certs`: copy `<name>.crt` from `algo-master/configs/<server_ip>/ipsec/manual/<name>.crt`
|
||||||
3. `/etc/ipsec.d/private`: copy `<name>.key` from `algo-master/configs/<server_ip>/pki/private/<name>.key`
|
3. `/etc/ipsec.d/private`: copy `<name>.key` from `algo-master/configs/<server_ip>/ipsec/manual/<name>.key`
|
||||||
4. `/etc/ipsec.d/cacerts`: copy `cacert.pem` from `algo-master/configs/<server_ip>/pki/cacert.pem`
|
4. `/etc/ipsec.d/cacerts`: copy `cacert.pem` from `algo-master/configs/<server_ip>/ipsec/manual/cacert.pem`
|
||||||
5. `/etc/ipsec.secrets`: add your `user.key` to the list, e.g. `<server_ip> : ECDSA <name>.key`
|
5. `/etc/ipsec.secrets`: add your `user.key` to the list, e.g. `<server_ip> : ECDSA <name>.key`
|
||||||
6. `/etc/ipsec.conf`: add the connection from `ipsec_user.conf` and ensure `leftcert` matches the `<name>.crt` filename
|
6. `/etc/ipsec.conf`: add the connection from `ipsec_user.conf` and ensure `leftcert` matches the `<name>.crt` filename
|
||||||
7. `sudo ipsec restart`: pick up config changes
|
7. `sudo ipsec restart`: pick up config changes
|
||||||
|
@ -160,7 +160,7 @@ If you turned on the optional SSH tunneling role, then local user accounts will
|
||||||
|
|
||||||
Use the example command below to start an SSH tunnel by replacing `user` and `ip` with your own. Once the tunnel is setup, you can configure a browser or other application to use 127.0.0.1:1080 as a SOCKS proxy to route traffic through the Algo server.
|
Use the example command below to start an SSH tunnel by replacing `user` and `ip` with your own. Once the tunnel is setup, you can configure a browser or other application to use 127.0.0.1:1080 as a SOCKS proxy to route traffic through the Algo server.
|
||||||
|
|
||||||
`ssh -D 127.0.0.1:1080 -f -q -C -N user@ip -i configs/ip_user.ssh.pem`
|
`ssh -D 127.0.0.1:1080 -f -q -C -N user@ip -i configs/<server_ip>/ssh-tunnel/<user>.pem`
|
||||||
|
|
||||||
## SSH into Algo Server
|
## SSH into Algo Server
|
||||||
|
|
||||||
|
|
18
config.cfg
18
config.cfg
|
@ -18,8 +18,14 @@ keys_clean_all: False
|
||||||
# Clean up cloud python environments
|
# Clean up cloud python environments
|
||||||
clean_environment: false
|
clean_environment: false
|
||||||
|
|
||||||
vpn_network: 10.19.48.0/24
|
# Deploy StrongSwan to enable IPsec support
|
||||||
vpn_network_ipv6: 'fd9d:bc11:4020::/48'
|
ipsec_enabled: true
|
||||||
|
|
||||||
|
# StrongSwan log level
|
||||||
|
# https://wiki.strongswan.org/projects/strongswan/wiki/LoggerConfiguration
|
||||||
|
strongswan_log_level: 2
|
||||||
|
|
||||||
|
# Deploy WireGuard
|
||||||
wireguard_enabled: true
|
wireguard_enabled: true
|
||||||
wireguard_port: 51820
|
wireguard_port: 51820
|
||||||
# If you're behind NAT or a firewall and you want to receive incoming connections long after network traffic has gone silent.
|
# If you're behind NAT or a firewall and you want to receive incoming connections long after network traffic has gone silent.
|
||||||
|
@ -36,10 +42,6 @@ wireguard_PersistentKeepalive: 0
|
||||||
# See: https://github.com/trailofbits/algo/blob/master/docs/troubleshooting.md#various-websites-appear-to-be-offline-through-the-vpn
|
# See: https://github.com/trailofbits/algo/blob/master/docs/troubleshooting.md#various-websites-appear-to-be-offline-through-the-vpn
|
||||||
reduce_mtu: 0
|
reduce_mtu: 0
|
||||||
|
|
||||||
# StrongSwan log level
|
|
||||||
# https://wiki.strongswan.org/projects/strongswan/wiki/LoggerConfiguration
|
|
||||||
strongswan_log_level: 2
|
|
||||||
|
|
||||||
# Algo will use the following lists to block ads. You can add new block lists
|
# Algo will use the following lists to block ads. You can add new block lists
|
||||||
# after deployment by modifying the line starting "BLOCKLIST_URLS=" at:
|
# after deployment by modifying the line starting "BLOCKLIST_URLS=" at:
|
||||||
# /usr/local/sbin/adblock.sh
|
# /usr/local/sbin/adblock.sh
|
||||||
|
@ -90,10 +92,6 @@ unattended_reboot:
|
||||||
enabled: false
|
enabled: false
|
||||||
time: 06:00
|
time: 06:00
|
||||||
|
|
||||||
pkcs12_PayloadCertificateUUID: "{{ 900000 | random | to_uuid | upper }}"
|
|
||||||
VPN_PayloadIdentifier: "{{ 800000 | random | to_uuid | upper }}"
|
|
||||||
CA_PayloadIdentifier: "{{ 700000 | random | to_uuid | upper }}"
|
|
||||||
|
|
||||||
# Block traffic between connected clients
|
# Block traffic between connected clients
|
||||||
BetweenClients_DROP: true
|
BetweenClients_DROP: true
|
||||||
|
|
||||||
|
|
71
input.yml
71
input.yml
|
@ -48,30 +48,45 @@
|
||||||
when:
|
when:
|
||||||
- server_name is undefined
|
- server_name is undefined
|
||||||
- algo_provider != "local"
|
- algo_provider != "local"
|
||||||
|
- block:
|
||||||
|
- 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:
|
- pause:
|
||||||
prompt: |
|
prompt: |
|
||||||
Do you want macOS/iOS IPsec clients to enable "Connect On Demand" when connected to cellular networks?
|
Do you want macOS/iOS IPsec clients to enable "Connect On Demand" when connected to Wi-Fi?
|
||||||
[y/N]
|
[y/N]
|
||||||
register: _ondemand_cellular
|
register: _ondemand_wifi
|
||||||
when: ondemand_cellular is undefined
|
when: ondemand_wifi is undefined
|
||||||
|
|
||||||
- pause:
|
- pause:
|
||||||
prompt: |
|
prompt: |
|
||||||
Do you want macOS/iOS IPsec clients to enable "Connect On Demand" when connected to Wi-Fi?
|
List the names of any trusted Wi-Fi networks where macOS/iOS IPsec clients should not use "Connect On Demand"
|
||||||
[y/N]
|
(e.g., your home network. Comma-separated value, e.g., HomeNet,OfficeWifi,AlgoWiFi)
|
||||||
register: _ondemand_wifi
|
register: _ondemand_wifi_exclude
|
||||||
when: ondemand_wifi is undefined
|
when:
|
||||||
|
- ondemand_wifi_exclude is undefined
|
||||||
|
- (ondemand_wifi|default(false)|bool) or
|
||||||
|
(booleans_map[_ondemand_wifi.user_input|default(omit)]|default(false))
|
||||||
|
|
||||||
- pause:
|
- pause:
|
||||||
prompt: |
|
prompt: |
|
||||||
List the names of any trusted Wi-Fi networks where macOS/iOS IPsec clients should not use "Connect On Demand"
|
Do you want the VPN to support Windows 10 or Linux Desktop clients? (enables compatible ciphers and key exchange, less secure)
|
||||||
(e.g., your home network. Comma-separated value, e.g., HomeNet,OfficeWifi,AlgoWiFi)
|
[y/N]
|
||||||
register: _ondemand_wifi_exclude
|
register: _windows
|
||||||
when:
|
when: windows is undefined
|
||||||
- ondemand_wifi_exclude is undefined
|
|
||||||
- (ondemand_wifi|default(false)|bool) or
|
- pause:
|
||||||
(booleans_map[_ondemand_wifi.user_input|default(omit)]|default(false))
|
prompt: |
|
||||||
|
Do you want to retain the CA key? (required to add users in the future, but less secure)
|
||||||
|
[y/N]
|
||||||
|
register: _store_cakey
|
||||||
|
when: store_cakey is undefined
|
||||||
|
when: ipsec_enabled
|
||||||
|
|
||||||
- pause:
|
- pause:
|
||||||
prompt: |
|
prompt: |
|
||||||
|
@ -87,20 +102,6 @@
|
||||||
register: _ssh_tunneling
|
register: _ssh_tunneling
|
||||||
when: ssh_tunneling is undefined
|
when: ssh_tunneling is undefined
|
||||||
|
|
||||||
- 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:
|
|
||||||
prompt: |
|
|
||||||
Do you want to retain the CA key? (required to add users in the future, but less secure)
|
|
||||||
[y/N]
|
|
||||||
register: _store_cakey
|
|
||||||
when: store_cakey is undefined
|
|
||||||
|
|
||||||
- name: Set facts based on the input
|
- name: Set facts based on the input
|
||||||
set_fact:
|
set_fact:
|
||||||
algo_server_name: >-
|
algo_server_name: >-
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
groups: vpn-host
|
groups: vpn-host
|
||||||
ansible_connection: "{% if cloud_instance_ip == 'localhost' %}local{% else %}ssh{% endif %}"
|
ansible_connection: "{% if cloud_instance_ip == 'localhost' %}local{% else %}ssh{% endif %}"
|
||||||
ansible_ssh_user: "{{ ansible_ssh_user }}"
|
ansible_ssh_user: "{{ ansible_ssh_user }}"
|
||||||
ansible_python_interpreter: "/usr/bin/python2.7"
|
ansible_python_interpreter: "/usr/bin/python3"
|
||||||
algo_provider: "{{ algo_provider }}"
|
algo_provider: "{{ algo_provider }}"
|
||||||
algo_server_name: "{{ algo_server_name }}"
|
algo_server_name: "{{ algo_server_name }}"
|
||||||
algo_ondemand_cellular: "{{ algo_ondemand_cellular }}"
|
algo_ondemand_cellular: "{{ algo_ondemand_cellular }}"
|
||||||
|
|
|
@ -1,67 +0,0 @@
|
||||||
---
|
|
||||||
|
|
||||||
# This playbook is designed to help when modifying the Windows script template
|
|
||||||
# in roles/vpn/templates/client_windows.ps1.j2
|
|
||||||
# It rebuilds the client_USER.ps1 scripts for each user defined in config.cfg,
|
|
||||||
# without redeploying users or opening an SSH connection to the Algo server at
|
|
||||||
# all.
|
|
||||||
#
|
|
||||||
# This playbook is _not_ part of a normal Algo deployment.
|
|
||||||
# It is only intended to speed up development of the client_USER.ps1 Windows
|
|
||||||
# Algo install scripts.
|
|
||||||
#
|
|
||||||
# REQUIREMENTS
|
|
||||||
# - Algo must have been deployed once
|
|
||||||
# - Windows users must have been enabled at deployment time
|
|
||||||
# - All users defined in config.cfg must not have changed
|
|
||||||
# - Only one Algo deployment exists in the configs/ directory
|
|
||||||
# - There must be exactly one subfolder in the configs/ directory:
|
|
||||||
# the folder named after the IP of the algo server
|
|
||||||
|
|
||||||
- hosts: localhost
|
|
||||||
gather_facts: False
|
|
||||||
tags: always
|
|
||||||
vars_files:
|
|
||||||
- ../config.cfg
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
|
|
||||||
- name: Get config subdir
|
|
||||||
shell: find ../configs/* -maxdepth 0 -type d | sed 's/.*\///'
|
|
||||||
register: config_subdir_result
|
|
||||||
- fail:
|
|
||||||
msg:
|
|
||||||
- "Found wrong number of config subdirs... stdout:"
|
|
||||||
- "{{ config_subdir_result.split('\n') }}"
|
|
||||||
when: config_subdir_result.stdout.split('\n') | length != 1
|
|
||||||
- set_fact:
|
|
||||||
IP_subject_alt_name: "{{ config_subdir_result.stdout }}"
|
|
||||||
- debug:
|
|
||||||
var: IP_subject_alt_name
|
|
||||||
|
|
||||||
- name: Register p12 PayloadContent
|
|
||||||
shell: cat private/{{ item }}.p12 | base64
|
|
||||||
register: PayloadContent
|
|
||||||
args:
|
|
||||||
chdir: "../configs/{{ IP_subject_alt_name }}/pki/"
|
|
||||||
with_items: "{{ users }}"
|
|
||||||
|
|
||||||
- name: Set facts for mobileconfigs
|
|
||||||
set_fact:
|
|
||||||
proxy_enabled: false
|
|
||||||
PayloadContentCA: "{{ lookup('file' , '../configs/{{ IP_subject_alt_name }}/pki/cacert.pem')|b64encode }}"
|
|
||||||
|
|
||||||
- name: Build the windows client powershell script
|
|
||||||
template:
|
|
||||||
src: ../roles/vpn/templates/client_windows.ps1.j2
|
|
||||||
dest: ../configs/{{ IP_subject_alt_name }}/windows_{{ item.0 }}.ps1
|
|
||||||
mode: 0600
|
|
||||||
with_together:
|
|
||||||
- "{{ users }}"
|
|
||||||
- "{{ PayloadContent.results }}"
|
|
||||||
|
|
||||||
- name: List windows client powershell scripts
|
|
||||||
debug:
|
|
||||||
msg: "configs/{{ IP_subject_alt_name }}/windows_{{ item }}.ps1"
|
|
||||||
with_items:
|
|
||||||
- "{{ users }}"
|
|
|
@ -50,11 +50,11 @@
|
||||||
src: "{{ item.src }}"
|
src: "{{ item.src }}"
|
||||||
dest: "{{ item.dest }}"
|
dest: "{{ item.dest }}"
|
||||||
with_items:
|
with_items:
|
||||||
- src: "configs/{{ IP_subject_alt_name }}/pki/certs/{{ vpn_user }}.crt"
|
- src: "configs/{{ IP_subject_alt_name }}/ipsec/.pki/certs/{{ vpn_user }}.crt"
|
||||||
dest: "{{ configs_prefix }}/ipsec.d/certs/{{ vpn_user }}.crt"
|
dest: "{{ configs_prefix }}/ipsec.d/certs/{{ vpn_user }}.crt"
|
||||||
- src: "configs/{{ IP_subject_alt_name }}/pki/cacert.pem"
|
- src: "configs/{{ IP_subject_alt_name }}/ipsec/.pki/cacert.pem"
|
||||||
dest: "{{ configs_prefix }}/ipsec.d/cacerts/{{ IP_subject_alt_name }}.pem"
|
dest: "{{ configs_prefix }}/ipsec.d/cacerts/{{ IP_subject_alt_name }}.pem"
|
||||||
- src: "configs/{{ IP_subject_alt_name }}/pki/private/{{ vpn_user }}.key"
|
- src: "configs/{{ IP_subject_alt_name }}/ipsec/.pki/private/{{ vpn_user }}.key"
|
||||||
dest: "{{ configs_prefix }}/ipsec.d/private/{{ vpn_user }}.key"
|
dest: "{{ configs_prefix }}/ipsec.d/private/{{ vpn_user }}.key"
|
||||||
notify:
|
notify:
|
||||||
- restart strongswan
|
- restart strongswan
|
||||||
|
|
|
@ -19,3 +19,9 @@
|
||||||
ifconfig lo100 create &&
|
ifconfig lo100 create &&
|
||||||
ifconfig lo100 inet {{ local_service_ip }} netmask 255.255.255.255 &&
|
ifconfig lo100 inet {{ local_service_ip }} netmask 255.255.255.255 &&
|
||||||
ifconfig lo100 inet6 FCAA::1/64; echo $?
|
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,4 +1,16 @@
|
||||||
---
|
---
|
||||||
|
- name: FreeBSD | Install prerequisites
|
||||||
|
package:
|
||||||
|
name:
|
||||||
|
- python3
|
||||||
|
- sudo
|
||||||
|
vars:
|
||||||
|
ansible_python_interpreter: /usr/local/bin/python2.7
|
||||||
|
|
||||||
|
- name: Set python3 as the interpreter to use
|
||||||
|
set_fact:
|
||||||
|
ansible_python_interpreter: /usr/local/bin/python3
|
||||||
|
|
||||||
- name: Gather facts
|
- name: Gather facts
|
||||||
setup:
|
setup:
|
||||||
|
|
||||||
|
@ -15,7 +27,6 @@
|
||||||
strongswan_additional_plugins:
|
strongswan_additional_plugins:
|
||||||
- kernel-pfroute
|
- kernel-pfroute
|
||||||
- kernel-pfkey
|
- kernel-pfkey
|
||||||
ansible_python_interpreter: /usr/local/bin/python2.7
|
|
||||||
tools:
|
tools:
|
||||||
- git
|
- git
|
||||||
- subversion
|
- subversion
|
||||||
|
|
|
@ -1,24 +1,4 @@
|
||||||
---
|
---
|
||||||
- block:
|
|
||||||
- name: Ubuntu | Install prerequisites
|
|
||||||
apt:
|
|
||||||
name: "{{ item }}"
|
|
||||||
update_cache: true
|
|
||||||
with_items:
|
|
||||||
- python2.7
|
|
||||||
- sudo
|
|
||||||
|
|
||||||
- name: Ubuntu | Configure defaults
|
|
||||||
alternatives:
|
|
||||||
name: python
|
|
||||||
link: /usr/bin/python
|
|
||||||
path: /usr/bin/python2.7
|
|
||||||
priority: 1
|
|
||||||
tags:
|
|
||||||
- update-alternatives
|
|
||||||
vars:
|
|
||||||
ansible_python_interpreter: /usr/bin/python3
|
|
||||||
|
|
||||||
- name: Gather facts
|
- name: Gather facts
|
||||||
setup:
|
setup:
|
||||||
|
|
||||||
|
@ -115,15 +95,20 @@
|
||||||
value: 1
|
value: 1
|
||||||
|
|
||||||
- name: Install tools
|
- name: Install tools
|
||||||
package: name="{{ item }}" state=present
|
apt:
|
||||||
|
name: "{{ item }}"
|
||||||
|
state: present
|
||||||
|
update_cache: true
|
||||||
with_items:
|
with_items:
|
||||||
- "{{ tools|default([]) }}"
|
- "{{ tools|default([]) }}"
|
||||||
|
|
||||||
- name: Install headers
|
- name: Install headers
|
||||||
apt:
|
apt:
|
||||||
name: "{{ item }}"
|
name:
|
||||||
|
- linux-headers-generic
|
||||||
|
- "linux-headers-{{ ansible_kernel }}"
|
||||||
state: present
|
state: present
|
||||||
when: install_headers
|
when: install_headers
|
||||||
with_items:
|
|
||||||
- linux-headers-generic
|
- include_tasks: iptables.yml
|
||||||
- "linux-headers-{{ ansible_kernel }}"
|
tags: iptables
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
{% set subnets = ([strongswan_network] if ipsec_enabled else []) + ([wireguard_network_ipv4] if wireguard_enabled else []) %}
|
||||||
|
{% set ports = (['500', '4500'] if ipsec_enabled else []) + ([wireguard_port] if wireguard_enabled else []) %}
|
||||||
|
|
||||||
#### The mangle table
|
#### The mangle table
|
||||||
# This table allows us to modify packet headers
|
# This table allows us to modify packet headers
|
||||||
# Packets enter this table first
|
# Packets enter this table first
|
||||||
|
@ -10,8 +13,8 @@
|
||||||
:OUTPUT ACCEPT [0:0]
|
:OUTPUT ACCEPT [0:0]
|
||||||
:POSTROUTING ACCEPT [0:0]
|
:POSTROUTING ACCEPT [0:0]
|
||||||
|
|
||||||
{% if reduce_mtu|int > 0 %}
|
{% if reduce_mtu|int > 0 and ipsec_enabled %}
|
||||||
-A FORWARD -s {{ vpn_network }} -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss {{ 1360 - reduce_mtu|int }}
|
-A FORWARD -s {{ strongswan_network }} -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss {{ 1360 - reduce_mtu|int }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
COMMIT
|
COMMIT
|
||||||
|
@ -27,7 +30,7 @@ COMMIT
|
||||||
:POSTROUTING ACCEPT [0:0]
|
:POSTROUTING ACCEPT [0:0]
|
||||||
|
|
||||||
# Allow traffic from the VPN network to the outside world, and replies
|
# Allow traffic from the VPN network to the outside world, and replies
|
||||||
-A POSTROUTING -s {{ vpn_network }}{% if wireguard_enabled %},{{ wireguard_vpn_network }}{% endif %} -m policy --pol none --dir out -j MASQUERADE
|
-A POSTROUTING -s {{ subnets|join(',') }} -m policy --pol none --dir out -j MASQUERADE
|
||||||
|
|
||||||
|
|
||||||
COMMIT
|
COMMIT
|
||||||
|
@ -54,12 +57,15 @@ COMMIT
|
||||||
-A INPUT -p ah -j ACCEPT
|
-A INPUT -p ah -j ACCEPT
|
||||||
# rate limit ICMP traffic per source
|
# rate limit ICMP traffic per source
|
||||||
-A INPUT -p icmp --icmp-type echo-request -m hashlimit --hashlimit-upto 5/s --hashlimit-mode srcip --hashlimit-srcmask 32 --hashlimit-name icmp-echo-drop -j ACCEPT
|
-A INPUT -p icmp --icmp-type echo-request -m hashlimit --hashlimit-upto 5/s --hashlimit-mode srcip --hashlimit-srcmask 32 --hashlimit-name icmp-echo-drop -j ACCEPT
|
||||||
# Accept IPSEC traffic to ports 500 (IPSEC) and 4500 (MOBIKE aka IKE + NAT traversal)
|
# Accept IPSEC/WireGuard traffic to ports {{ subnets|join(',') }}
|
||||||
-A INPUT -p udp -m multiport --dports 500,4500{% if wireguard_enabled %},{{ wireguard_port}}{% endif %} -j ACCEPT
|
-A INPUT -p udp -m multiport --dports {{ ports|join(',') }} -j ACCEPT
|
||||||
# Allow new traffic to port 22 (SSH)
|
# Allow new traffic to port 22 (SSH)
|
||||||
-A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT
|
-A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT
|
||||||
# Allow any traffic from the VPN
|
|
||||||
|
{% if ipsec_enabled %}
|
||||||
|
# Allow any traffic from the IPsec VPN
|
||||||
-A INPUT -p ipencap -m policy --dir in --pol ipsec --proto esp -j ACCEPT
|
-A INPUT -p ipencap -m policy --dir in --pol ipsec --proto esp -j ACCEPT
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
# TODO:
|
# TODO:
|
||||||
# The IP of the resolver should be bound to a DUMMY interface.
|
# The IP of the resolver should be bound to a DUMMY interface.
|
||||||
|
@ -70,10 +76,7 @@ COMMIT
|
||||||
-A INPUT -d {{ local_service_ip }} -p udp --dport 53 -j ACCEPT
|
-A INPUT -d {{ local_service_ip }} -p udp --dport 53 -j ACCEPT
|
||||||
|
|
||||||
# Drop traffic between VPN clients
|
# Drop traffic between VPN clients
|
||||||
{% if BetweenClients_DROP %}
|
-A FORWARD -s {{ subnets|join(',') }} -d {{ subnets|join(',') }} -j {{ "DROP" if BetweenClients_DROP else "ACCEPT" }}
|
||||||
{% set BetweenClientsPolicy = "DROP" %}
|
|
||||||
{% endif %}
|
|
||||||
-A FORWARD -s {{ vpn_network }}{% if wireguard_enabled %},{{ wireguard_vpn_network }}{% endif %} -d {{ vpn_network }}{% if wireguard_enabled %},{{ wireguard_vpn_network }}{% endif %} -j {{ BetweenClientsPolicy | default("ACCEPT") }}
|
|
||||||
|
|
||||||
# Forward any packet that's part of an established connection
|
# Forward any packet that's part of an established connection
|
||||||
-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
|
-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
|
||||||
|
@ -83,12 +86,14 @@ COMMIT
|
||||||
-A FORWARD -p udp -m multiport --ports 137,138 -j DROP
|
-A FORWARD -p udp -m multiport --ports 137,138 -j DROP
|
||||||
-A FORWARD -p tcp -m multiport --ports 137,139 -j DROP
|
-A FORWARD -p tcp -m multiport --ports 137,139 -j DROP
|
||||||
|
|
||||||
|
{% if ipsec_enabled %}
|
||||||
# Forward any IPSEC traffic from the VPN network
|
# Forward any IPSEC traffic from the VPN network
|
||||||
-A FORWARD -m conntrack --ctstate NEW -s {{ vpn_network }} -m policy --pol ipsec --dir in -j ACCEPT
|
-A FORWARD -m conntrack --ctstate NEW -s {{ strongswan_network }} -m policy --pol ipsec --dir in -j ACCEPT
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
# Forward any traffic from the WireGuard VPN network
|
|
||||||
{% if wireguard_enabled %}
|
{% if wireguard_enabled %}
|
||||||
-A FORWARD -m conntrack --ctstate NEW -s {{ wireguard_vpn_network }} -m policy --pol none --dir in -j ACCEPT
|
# Forward any traffic from the WireGuard VPN network
|
||||||
|
-A FORWARD -m conntrack --ctstate NEW -s {{ wireguard_network_ipv4 }} -m policy --pol none --dir in -j ACCEPT
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
COMMIT
|
COMMIT
|
|
@ -1,3 +1,6 @@
|
||||||
|
{% set subnets = ([strongswan_network_ipv6] if ipsec_enabled else []) + ([wireguard_network_ipv6] if wireguard_enabled else []) %}
|
||||||
|
{% set ports = (['500', '4500'] if ipsec_enabled else []) + ([wireguard_port] if wireguard_enabled else []) %}
|
||||||
|
|
||||||
#### The mangle table
|
#### The mangle table
|
||||||
# This table allows us to modify packet headers
|
# This table allows us to modify packet headers
|
||||||
# Packets enter this table first
|
# Packets enter this table first
|
||||||
|
@ -10,8 +13,8 @@
|
||||||
:OUTPUT ACCEPT [0:0]
|
:OUTPUT ACCEPT [0:0]
|
||||||
:POSTROUTING ACCEPT [0:0]
|
:POSTROUTING ACCEPT [0:0]
|
||||||
|
|
||||||
{% if reduce_mtu|int > 0 %}
|
{% if reduce_mtu|int > 0 and ipsec_enabled %}
|
||||||
-A FORWARD -s {{ vpn_network_ipv6 }} -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss {{ 1340 - reduce_mtu|int }}
|
-A FORWARD -s {{ strongswan_network_ipv6 }} -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss {{ 1340 - reduce_mtu|int }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
COMMIT
|
COMMIT
|
||||||
|
@ -26,7 +29,7 @@ COMMIT
|
||||||
:POSTROUTING ACCEPT [0:0]
|
:POSTROUTING ACCEPT [0:0]
|
||||||
|
|
||||||
# Allow traffic from the VPN network to the outside world, and replies
|
# Allow traffic from the VPN network to the outside world, and replies
|
||||||
-A POSTROUTING -s {{ vpn_network_ipv6 }}{% if wireguard_enabled %},{{ wireguard_vpn_network_ipv6 }}{% endif %} -m policy --pol none --dir out -j MASQUERADE
|
-A POSTROUTING -s {{ subnets|join(',') }} -m policy --pol none --dir out -j MASQUERADE
|
||||||
|
|
||||||
COMMIT
|
COMMIT
|
||||||
|
|
||||||
|
@ -60,8 +63,8 @@ COMMIT
|
||||||
-A INPUT -m ah -j ACCEPT
|
-A INPUT -m ah -j ACCEPT
|
||||||
# rate limit ICMP traffic per source
|
# rate limit ICMP traffic per source
|
||||||
-A INPUT -p icmpv6 --icmpv6-type echo-request -m hashlimit --hashlimit-upto 5/s --hashlimit-mode srcip --hashlimit-srcmask 32 --hashlimit-name icmp-echo-drop -j ACCEPT
|
-A INPUT -p icmpv6 --icmpv6-type echo-request -m hashlimit --hashlimit-upto 5/s --hashlimit-mode srcip --hashlimit-srcmask 32 --hashlimit-name icmp-echo-drop -j ACCEPT
|
||||||
# Accept IPSEC traffic to ports 500 (IPSEC) and 4500 (MOBIKE aka IKE + NAT traversal)
|
# Accept IPSEC/WireGuard traffic to ports {{ subnets|join(',') }}
|
||||||
-A INPUT -p udp -m multiport --dports 500,4500{% if wireguard_enabled %},{{ wireguard_port}}{% endif %} -j ACCEPT
|
-A INPUT -p udp -m multiport --dports {{ ports|join(',') }} -j ACCEPT
|
||||||
# Allow new traffic to port 22 (SSH)
|
# Allow new traffic to port 22 (SSH)
|
||||||
-A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT
|
-A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT
|
||||||
|
|
||||||
|
@ -83,19 +86,18 @@ COMMIT
|
||||||
-A INPUT -d fcaa::1 -p udp --dport 53 -j ACCEPT
|
-A INPUT -d fcaa::1 -p udp --dport 53 -j ACCEPT
|
||||||
|
|
||||||
# Drop traffic between VPN clients
|
# Drop traffic between VPN clients
|
||||||
{% if BetweenClients_DROP %}
|
-A FORWARD -s {{ subnets|join(',') }} -d {{ subnets|join(',') }} -j {{ "DROP" if BetweenClients_DROP else "ACCEPT" }}
|
||||||
{% set BetweenClientsPolicy = "DROP" %}
|
|
||||||
{% endif %}
|
|
||||||
-A FORWARD -s {{ vpn_network_ipv6 }}{% if wireguard_enabled %},{{ wireguard_vpn_network_ipv6 }}{% endif %} -d {{ vpn_network_ipv6 }}{% if wireguard_enabled %},{{ wireguard_vpn_network_ipv6 }}{% endif %} -j {{ BetweenClientsPolicy | default("ACCEPT") }}
|
|
||||||
|
|
||||||
-A FORWARD -j ICMPV6-CHECK
|
-A FORWARD -j ICMPV6-CHECK
|
||||||
-A FORWARD -p tcp --dport 445 -j DROP
|
-A FORWARD -p tcp --dport 445 -j DROP
|
||||||
-A FORWARD -p udp -m multiport --ports 137,138 -j DROP
|
-A FORWARD -p udp -m multiport --ports 137,138 -j DROP
|
||||||
-A FORWARD -p tcp -m multiport --ports 137,139 -j DROP
|
-A FORWARD -p tcp -m multiport --ports 137,139 -j DROP
|
||||||
-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
|
-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
|
||||||
-A FORWARD -m conntrack --ctstate NEW -s {{ vpn_network_ipv6 }} -m policy --pol ipsec --dir in -j ACCEPT
|
{% if ipsec_enabled %}
|
||||||
|
-A FORWARD -m conntrack --ctstate NEW -s {{ strongswan_network_ipv6 }} -m policy --pol ipsec --dir in -j ACCEPT
|
||||||
|
{% endif %}
|
||||||
{% if wireguard_enabled %}
|
{% if wireguard_enabled %}
|
||||||
-A FORWARD -m conntrack --ctstate NEW -s {{ wireguard_vpn_network_ipv6 }} -m policy --pol none --dir in -j ACCEPT
|
-A FORWARD -m conntrack --ctstate NEW -s {{ wireguard_network_ipv6 }} -m policy --pol none --dir in -j ACCEPT
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
# Use the ICMPV6-CHECK chain, described above
|
# Use the ICMPV6-CHECK chain, described above
|
2
roles/ssh_tunneling/defaults/main.yml
Normal file
2
roles/ssh_tunneling/defaults/main.yml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
---
|
||||||
|
ssh_tunnels_config_path: "configs/{{ IP_subject_alt_name }}/ssh-tunnel/"
|
|
@ -25,65 +25,93 @@
|
||||||
owner: root
|
owner: root
|
||||||
group: "{{ root_group|default('root') }}"
|
group: "{{ root_group|default('root') }}"
|
||||||
|
|
||||||
- name: Ensure that the SSH users exist
|
- block:
|
||||||
user:
|
- name: Ensure that the SSH users exist
|
||||||
name: "{{ item }}"
|
user:
|
||||||
groups: algo
|
name: "{{ item }}"
|
||||||
home: '/var/jail/{{ item }}'
|
groups: algo
|
||||||
createhome: yes
|
home: '/var/jail/{{ item }}'
|
||||||
generate_ssh_key: false
|
createhome: yes
|
||||||
shell: /bin/false
|
generate_ssh_key: false
|
||||||
state: present
|
shell: /bin/false
|
||||||
append: yes
|
state: present
|
||||||
with_items: "{{ users }}"
|
append: yes
|
||||||
tags: update-users
|
with_items: "{{ users }}"
|
||||||
|
|
||||||
- name: The authorized keys file created
|
- block:
|
||||||
authorized_key:
|
- name: Clean up the ssh-tunnel directory
|
||||||
user: "{{ item }}"
|
file:
|
||||||
key: "{{ lookup('file', 'configs/' + IP_subject_alt_name + '/pki/public/' + item + '.pub') }}"
|
dest: "{{ ssh_tunnels_config_path }}"
|
||||||
state: present
|
state: absent
|
||||||
manage_dir: true
|
when: keys_clean_all|bool == True
|
||||||
exclusive: true
|
|
||||||
with_items: "{{ users }}"
|
|
||||||
tags: update-users
|
|
||||||
|
|
||||||
- name: Generate SSH fingerprints
|
- name: Ensure the config directories exist
|
||||||
shell: ssh-keyscan {{ IP_subject_alt_name }} 2>/dev/null
|
file:
|
||||||
register: ssh_fingerprints
|
dest: "{{ ssh_tunnels_config_path }}"
|
||||||
|
state: directory
|
||||||
|
recurse: yes
|
||||||
|
mode: '0700'
|
||||||
|
|
||||||
- name: Fetch the known_hosts file
|
- name: Check if the private keys exist
|
||||||
local_action:
|
stat:
|
||||||
module: template
|
path: "{{ ssh_tunnels_config_path }}/{{ item }}.pem"
|
||||||
src: known_hosts.j2
|
register: privatekey
|
||||||
dest: configs/{{ IP_subject_alt_name }}/known_hosts
|
with_items: "{{ users }}"
|
||||||
become: no
|
|
||||||
|
|
||||||
- name: Build the client ssh config
|
- name: Build ssh private keys
|
||||||
local_action:
|
openssl_privatekey:
|
||||||
module: template
|
path: "{{ ssh_tunnels_config_path }}/{{ item.item }}.pem"
|
||||||
src: ssh_config.j2
|
passphrase: "{{ p12_export_password }}"
|
||||||
dest: configs/{{ IP_subject_alt_name }}/{{ item }}.ssh_config
|
cipher: aes256
|
||||||
mode: 0600
|
force: false
|
||||||
become: false
|
no_log: true
|
||||||
tags: update-users
|
when: not item.stat.exists
|
||||||
with_items: "{{ users }}"
|
with_items: "{{ privatekey.results }}"
|
||||||
|
register: openssl_privatekey
|
||||||
|
|
||||||
- name: Get active users
|
- name: Build ssh public keys
|
||||||
getent:
|
openssl_publickey:
|
||||||
database: group
|
path: "{{ ssh_tunnels_config_path }}/{{ item.item.item }}.pub"
|
||||||
key: algo
|
privatekey_path: "{{ ssh_tunnels_config_path }}/{{ item.item.item }}.pem"
|
||||||
split: ':'
|
privatekey_passphrase: "{{ p12_export_password }}"
|
||||||
tags: update-users
|
format: OpenSSH
|
||||||
|
force: true
|
||||||
|
no_log: true
|
||||||
|
when: item.changed
|
||||||
|
with_items: "{{ openssl_privatekey.results }}"
|
||||||
|
|
||||||
- name: Delete non-existing users
|
- name: Build the client ssh config
|
||||||
user:
|
template:
|
||||||
name: "{{ item }}"
|
src: ssh_config.j2
|
||||||
state: absent
|
dest: "{{ ssh_tunnels_config_path }}/{{ item }}.ssh_config"
|
||||||
remove: yes
|
mode: 0700
|
||||||
force: yes
|
with_items: "{{ users }}"
|
||||||
when: item not in users
|
delegate_to: localhost
|
||||||
with_items: "{{ getent_group['algo'][2].split(',') }}"
|
become: false
|
||||||
|
|
||||||
|
- name: The authorized keys file created
|
||||||
|
authorized_key:
|
||||||
|
user: "{{ item }}"
|
||||||
|
key: "{{ lookup('file', ssh_tunnels_config_path + '/' + item + '.pub') }}"
|
||||||
|
state: present
|
||||||
|
manage_dir: true
|
||||||
|
exclusive: true
|
||||||
|
with_items: "{{ users }}"
|
||||||
|
|
||||||
|
- name: Get active users
|
||||||
|
getent:
|
||||||
|
database: group
|
||||||
|
key: algo
|
||||||
|
split: ':'
|
||||||
|
|
||||||
|
- name: Delete non-existing users
|
||||||
|
user:
|
||||||
|
name: "{{ item }}"
|
||||||
|
state: absent
|
||||||
|
remove: yes
|
||||||
|
force: yes
|
||||||
|
when: item not in users
|
||||||
|
with_items: "{{ getent_group['algo'][2].split(',') }}"
|
||||||
tags: update-users
|
tags: update-users
|
||||||
rescue:
|
rescue:
|
||||||
- debug: var=fail_hint
|
- debug: var=fail_hint
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
{% for item in ssh_fingerprints.stdout_lines %}
|
|
||||||
{{ item }}
|
|
||||||
{% endfor %}
|
|
|
@ -1,31 +1,11 @@
|
||||||
---
|
---
|
||||||
|
ipsec_config_path: "configs/{{ IP_subject_alt_name }}/ipsec/"
|
||||||
|
ipsec_pki_path: "{{ ipsec_config_path }}/.pki/"
|
||||||
|
strongswan_network: 10.19.48.0/24
|
||||||
|
strongswan_network_ipv6: 'fd9d:bc11:4020::/48'
|
||||||
strongswan_shell: /usr/sbin/nologin
|
strongswan_shell: /usr/sbin/nologin
|
||||||
strongswan_home: /var/lib/strongswan
|
strongswan_home: /var/lib/strongswan
|
||||||
BetweenClients_DROP: true
|
BetweenClients_DROP: true
|
||||||
wireguard_config_path: "configs/{{ IP_subject_alt_name }}/wireguard/"
|
|
||||||
wireguard_interface: wg0
|
|
||||||
wireguard_network_ipv4:
|
|
||||||
subnet: 10.19.49.0
|
|
||||||
prefix: 24
|
|
||||||
gateway: 10.19.49.1
|
|
||||||
clients_range: 10.19.49
|
|
||||||
clients_start: 2
|
|
||||||
wireguard_network_ipv6:
|
|
||||||
subnet: 'fd9d:bc11:4021::'
|
|
||||||
prefix: 48
|
|
||||||
gateway: 'fd9d:bc11:4021::1'
|
|
||||||
clients_range: 'fd9d:bc11:4021::'
|
|
||||||
clients_start: 2
|
|
||||||
wireguard_vpn_network: "{{ wireguard_network_ipv4['subnet'] }}/{{ wireguard_network_ipv4['prefix'] }}"
|
|
||||||
wireguard_vpn_network_ipv6: "{{ wireguard_network_ipv6['subnet'] }}/{{ wireguard_network_ipv6['prefix'] }}"
|
|
||||||
keys_clean_all: false
|
|
||||||
wireguard_dns_servers: >-
|
|
||||||
{% if local_dns|default(false)|bool or dns_encryption|default(false)|bool == true %}
|
|
||||||
{{ 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 %}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
algo_ondemand_cellular: false
|
algo_ondemand_cellular: false
|
||||||
algo_ondemand_wifi: false
|
algo_ondemand_wifi: false
|
||||||
algo_ondemand_wifi_exclude: '_null'
|
algo_ondemand_wifi_exclude: '_null'
|
||||||
|
@ -65,3 +45,7 @@ ciphers:
|
||||||
compat:
|
compat:
|
||||||
ike: aes256gcm16-prfsha512-ecp384,aes256-sha2_512-prfsha512-ecp384,aes256-sha2_384-prfsha384-ecp384!
|
ike: aes256gcm16-prfsha512-ecp384,aes256-sha2_512-prfsha512-ecp384,aes256-sha2_384-prfsha384-ecp384!
|
||||||
esp: aes256gcm16-ecp384,aes256-sha2_512-prfsha512-ecp384!
|
esp: aes256gcm16-ecp384,aes256-sha2_512-prfsha512-ecp384!
|
||||||
|
|
||||||
|
pkcs12_PayloadCertificateUUID: "{{ 900000 | random | to_uuid | upper }}"
|
||||||
|
VPN_PayloadIdentifier: "{{ 800000 | random | to_uuid | upper }}"
|
||||||
|
CA_PayloadIdentifier: "{{ 700000 | random | to_uuid | upper }}"
|
|
@ -7,11 +7,5 @@
|
||||||
- name: restart apparmor
|
- name: restart apparmor
|
||||||
service: name=apparmor state=restarted
|
service: name=apparmor state=restarted
|
||||||
|
|
||||||
- name: save iptables
|
|
||||||
shell: service netfilter-persistent save
|
|
||||||
|
|
||||||
- name: restart iptables
|
|
||||||
service: name=netfilter-persistent state=restarted
|
|
||||||
|
|
||||||
- name: rereadcrls
|
- name: rereadcrls
|
||||||
shell: ipsec rereadcrls; ipsec purgecrls
|
shell: ipsec rereadcrls; ipsec purgecrls
|
|
@ -1,20 +1,19 @@
|
||||||
---
|
---
|
||||||
|
|
||||||
- name: Register p12 PayloadContent
|
- name: Register p12 PayloadContent
|
||||||
shell: cat private/{{ item }}.p12 | base64
|
shell: cat private/{{ item }}.p12 | base64
|
||||||
register: PayloadContent
|
register: PayloadContent
|
||||||
args:
|
args:
|
||||||
chdir: "configs/{{ IP_subject_alt_name }}/pki/"
|
chdir: "{{ ipsec_pki_path }}"
|
||||||
with_items: "{{ users }}"
|
with_items: "{{ users }}"
|
||||||
|
|
||||||
- name: Set facts for mobileconfigs
|
- name: Set facts for mobileconfigs
|
||||||
set_fact:
|
set_fact:
|
||||||
PayloadContentCA: "{{ lookup('file' , 'configs/{{ IP_subject_alt_name }}/pki/cacert.pem')|b64encode }}"
|
PayloadContentCA: "{{ lookup('file' , '{{ ipsec_pki_path }}/cacert.pem')|b64encode }}"
|
||||||
|
|
||||||
- name: Build the mobileconfigs
|
- name: Build the mobileconfigs
|
||||||
template:
|
template:
|
||||||
src: mobileconfig.j2
|
src: mobileconfig.j2
|
||||||
dest: configs/{{ IP_subject_alt_name }}/{{ item.0 }}.mobileconfig
|
dest: "{{ ipsec_config_path }}/apple/{{ item.0 }}.mobileconfig"
|
||||||
mode: 0600
|
mode: 0600
|
||||||
with_together:
|
with_together:
|
||||||
- "{{ users }}"
|
- "{{ users }}"
|
||||||
|
@ -24,7 +23,7 @@
|
||||||
- name: Build the client ipsec config file
|
- name: Build the client ipsec config file
|
||||||
template:
|
template:
|
||||||
src: client_ipsec.conf.j2
|
src: client_ipsec.conf.j2
|
||||||
dest: configs/{{ IP_subject_alt_name }}/ipsec_{{ item }}.conf
|
dest: "{{ ipsec_config_path }}/manual/{{ item }}.conf"
|
||||||
mode: 0600
|
mode: 0600
|
||||||
with_items:
|
with_items:
|
||||||
- "{{ users }}"
|
- "{{ users }}"
|
||||||
|
@ -32,7 +31,7 @@
|
||||||
- name: Build the client ipsec secret file
|
- name: Build the client ipsec secret file
|
||||||
template:
|
template:
|
||||||
src: client_ipsec.secrets.j2
|
src: client_ipsec.secrets.j2
|
||||||
dest: configs/{{ IP_subject_alt_name }}/ipsec_{{ item }}.secrets
|
dest: "{{ ipsec_config_path }}/manual/{{ item }}.secrets"
|
||||||
mode: 0600
|
mode: 0600
|
||||||
with_items:
|
with_items:
|
||||||
- "{{ users }}"
|
- "{{ users }}"
|
||||||
|
@ -40,7 +39,7 @@
|
||||||
- name: Build the windows client powershell script
|
- name: Build the windows client powershell script
|
||||||
template:
|
template:
|
||||||
src: client_windows.ps1.j2
|
src: client_windows.ps1.j2
|
||||||
dest: configs/{{ IP_subject_alt_name }}/windows_{{ item.0 }}.ps1
|
dest: "{{ ipsec_config_path }}/windows/{{ item.0 }}.ps1"
|
||||||
mode: 0600
|
mode: 0600
|
||||||
when: algo_windows
|
when: algo_windows
|
||||||
with_together:
|
with_together:
|
||||||
|
@ -49,8 +48,6 @@
|
||||||
|
|
||||||
- name: Restrict permissions for the local private directories
|
- name: Restrict permissions for the local private directories
|
||||||
file:
|
file:
|
||||||
path: "{{ item }}"
|
path: "{{ ipsec_config_path }}"
|
||||||
state: directory
|
state: directory
|
||||||
mode: 0700
|
mode: 0700
|
||||||
with_items:
|
|
||||||
- configs/{{ IP_subject_alt_name }}
|
|
27
roles/strongswan/tasks/distribute_keys.yml
Normal file
27
roles/strongswan/tasks/distribute_keys.yml
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
- name: Copy the keys to the strongswan directory
|
||||||
|
copy:
|
||||||
|
src: "{{ ipsec_pki_path }}/{{ item.src }}"
|
||||||
|
dest: "{{ config_prefix|default('/') }}etc/ipsec.d/{{ item.dest }}"
|
||||||
|
owner: "{{ item.owner }}"
|
||||||
|
group: "{{ item.group }}"
|
||||||
|
mode: "{{ item.mode }}"
|
||||||
|
with_items:
|
||||||
|
- src: "cacert.pem"
|
||||||
|
dest: "cacerts/ca.crt"
|
||||||
|
owner: strongswan
|
||||||
|
group: "{{ root_group|default('root') }}"
|
||||||
|
mode: "0600"
|
||||||
|
- src: "certs/{{ IP_subject_alt_name }}.crt"
|
||||||
|
dest: "certs/{{ IP_subject_alt_name }}.crt"
|
||||||
|
owner: strongswan
|
||||||
|
group: "{{ root_group|default('root') }}"
|
||||||
|
mode: "0600"
|
||||||
|
- src: "private/{{ IP_subject_alt_name }}.key"
|
||||||
|
dest: "private/{{ IP_subject_alt_name }}.key"
|
||||||
|
owner: strongswan
|
||||||
|
group: "{{ root_group|default('root') }}"
|
||||||
|
mode: "0600"
|
||||||
|
notify:
|
||||||
|
- restart strongswan
|
|
@ -3,23 +3,23 @@
|
||||||
- name: Setup the config files from our templates
|
- name: Setup the config files from our templates
|
||||||
template:
|
template:
|
||||||
src: "{{ item.src }}"
|
src: "{{ item.src }}"
|
||||||
dest: "{{ item.dest }}"
|
dest: "{{ config_prefix|default('/') }}etc/{{ item.dest }}"
|
||||||
owner: "{{ item.owner }}"
|
owner: "{{ item.owner }}"
|
||||||
group: "{{ item.group }}"
|
group: "{{ item.group }}"
|
||||||
mode: "{{ item.mode }}"
|
mode: "{{ item.mode }}"
|
||||||
with_items:
|
with_items:
|
||||||
- src: strongswan.conf.j2
|
- src: strongswan.conf.j2
|
||||||
dest: "{{ config_prefix|default('/') }}etc/strongswan.conf"
|
dest: "strongswan.conf"
|
||||||
owner: root
|
owner: root
|
||||||
group: "{{ root_group|default('root') }}"
|
group: "{{ root_group|default('root') }}"
|
||||||
mode: "0644"
|
mode: "0644"
|
||||||
- src: ipsec.conf.j2
|
- src: ipsec.conf.j2
|
||||||
dest: "{{ config_prefix|default('/') }}etc/ipsec.conf"
|
dest: "ipsec.conf"
|
||||||
owner: root
|
owner: root
|
||||||
group: "{{ root_group|default('root') }}"
|
group: "{{ root_group|default('root') }}"
|
||||||
mode: "0644"
|
mode: "0644"
|
||||||
- src: ipsec.secrets.j2
|
- src: ipsec.secrets.j2
|
||||||
dest: "{{ config_prefix|default('/') }}etc/ipsec.secrets"
|
dest: "ipsec.secrets"
|
||||||
owner: strongswan
|
owner: strongswan
|
||||||
group: "{{ root_group|default('root') }}"
|
group: "{{ root_group|default('root') }}"
|
||||||
mode: "0600"
|
mode: "0600"
|
|
@ -1,11 +1,5 @@
|
||||||
---
|
---
|
||||||
- block:
|
- block:
|
||||||
- name: Include WireGuard role
|
|
||||||
include_role:
|
|
||||||
name: wireguard
|
|
||||||
tags: wireguard
|
|
||||||
when: wireguard_enabled and ansible_distribution == 'Ubuntu'
|
|
||||||
|
|
||||||
- include_tasks: ubuntu.yml
|
- include_tasks: ubuntu.yml
|
||||||
when: ansible_distribution == 'Debian' or ansible_distribution == 'Ubuntu'
|
when: ansible_distribution == 'Debian' or ansible_distribution == 'Ubuntu'
|
||||||
|
|
|
@ -7,13 +7,13 @@
|
||||||
|
|
||||||
- name: Ensure the pki directory does not exist
|
- name: Ensure the pki directory does not exist
|
||||||
file:
|
file:
|
||||||
dest: configs/{{ IP_subject_alt_name }}/pki
|
dest: "{{ ipsec_pki_path }}"
|
||||||
state: absent
|
state: absent
|
||||||
when: keys_clean_all|bool == True
|
when: keys_clean_all|bool == True
|
||||||
|
|
||||||
- name: Ensure the pki directories exist
|
- name: Ensure the pki directories exist
|
||||||
file:
|
file:
|
||||||
dest: "configs/{{ IP_subject_alt_name }}/pki/{{ item }}"
|
dest: "{{ ipsec_pki_path }}/{{ item }}"
|
||||||
state: directory
|
state: directory
|
||||||
recurse: yes
|
recurse: yes
|
||||||
mode: '0700'
|
mode: '0700'
|
||||||
|
@ -26,9 +26,20 @@
|
||||||
- public
|
- public
|
||||||
- reqs
|
- reqs
|
||||||
|
|
||||||
|
- name: Ensure the config directories exist
|
||||||
|
file:
|
||||||
|
dest: "{{ ipsec_config_path }}/{{ item }}"
|
||||||
|
state: directory
|
||||||
|
recurse: yes
|
||||||
|
mode: '0700'
|
||||||
|
with_items:
|
||||||
|
- apple
|
||||||
|
- windows
|
||||||
|
- manual
|
||||||
|
|
||||||
- name: Ensure the files exist
|
- name: Ensure the files exist
|
||||||
file:
|
file:
|
||||||
dest: "configs/{{ IP_subject_alt_name }}/pki/{{ item }}"
|
dest: "{{ ipsec_pki_path }}/{{ item }}"
|
||||||
state: touch
|
state: touch
|
||||||
with_items:
|
with_items:
|
||||||
- ".rnd"
|
- ".rnd"
|
||||||
|
@ -40,7 +51,7 @@
|
||||||
- name: Generate the openssl server configs
|
- name: Generate the openssl server configs
|
||||||
template:
|
template:
|
||||||
src: openssl.cnf.j2
|
src: openssl.cnf.j2
|
||||||
dest: "configs/{{ IP_subject_alt_name }}/pki/openssl.cnf"
|
dest: "{{ ipsec_pki_path }}/openssl.cnf"
|
||||||
|
|
||||||
- name: Build the CA pair
|
- name: Build the CA pair
|
||||||
shell: >
|
shell: >
|
||||||
|
@ -55,20 +66,19 @@
|
||||||
-passout pass:"{{ CA_password }}" &&
|
-passout pass:"{{ CA_password }}" &&
|
||||||
touch {{ IP_subject_alt_name }}_ca_generated
|
touch {{ IP_subject_alt_name }}_ca_generated
|
||||||
args:
|
args:
|
||||||
chdir: "configs/{{ IP_subject_alt_name }}/pki/"
|
chdir: "{{ ipsec_pki_path }}"
|
||||||
creates: "{{ IP_subject_alt_name }}_ca_generated"
|
creates: "{{ IP_subject_alt_name }}_ca_generated"
|
||||||
executable: bash
|
executable: bash
|
||||||
|
|
||||||
- name: Copy the CA certificate
|
- name: Copy the CA certificate
|
||||||
copy:
|
copy:
|
||||||
src: "configs/{{ IP_subject_alt_name }}/pki/cacert.pem"
|
src: "{{ ipsec_pki_path }}/cacert.pem"
|
||||||
dest: "configs/{{ IP_subject_alt_name }}/cacert.pem"
|
dest: "{{ ipsec_config_path }}/manual/cacert.pem"
|
||||||
mode: 0600
|
|
||||||
|
|
||||||
- name: Generate the serial number
|
- name: Generate the serial number
|
||||||
shell: echo 01 > serial && touch serial_generated
|
shell: echo 01 > serial && touch serial_generated
|
||||||
args:
|
args:
|
||||||
chdir: "configs/{{ IP_subject_alt_name }}/pki/"
|
chdir: "{{ ipsec_pki_path }}"
|
||||||
creates: serial_generated
|
creates: serial_generated
|
||||||
|
|
||||||
- name: Build the server pair
|
- name: Build the server pair
|
||||||
|
@ -90,7 +100,7 @@
|
||||||
-subj "/CN={{ IP_subject_alt_name }}" &&
|
-subj "/CN={{ IP_subject_alt_name }}" &&
|
||||||
touch certs/{{ IP_subject_alt_name }}_crt_generated
|
touch certs/{{ IP_subject_alt_name }}_crt_generated
|
||||||
args:
|
args:
|
||||||
chdir: "configs/{{ IP_subject_alt_name }}/pki/"
|
chdir: "{{ ipsec_pki_path }}"
|
||||||
creates: certs/{{ IP_subject_alt_name }}_crt_generated
|
creates: certs/{{ IP_subject_alt_name }}_crt_generated
|
||||||
executable: bash
|
executable: bash
|
||||||
|
|
||||||
|
@ -113,23 +123,15 @@
|
||||||
-subj "/CN={{ item }}" &&
|
-subj "/CN={{ item }}" &&
|
||||||
touch certs/{{ item }}_crt_generated
|
touch certs/{{ item }}_crt_generated
|
||||||
args:
|
args:
|
||||||
chdir: "configs/{{ IP_subject_alt_name }}/pki/"
|
chdir: "{{ ipsec_pki_path }}"
|
||||||
creates: certs/{{ item }}_crt_generated
|
creates: certs/{{ item }}_crt_generated
|
||||||
executable: bash
|
executable: bash
|
||||||
with_items: "{{ users }}"
|
with_items: "{{ users }}"
|
||||||
|
|
||||||
- name: Create links for the private keys
|
|
||||||
file:
|
|
||||||
src: "pki/private/{{ item }}.key"
|
|
||||||
dest: "configs/{{ IP_subject_alt_name }}/{{ item }}.ssh.pem"
|
|
||||||
state: link
|
|
||||||
force: true
|
|
||||||
with_items: "{{ users }}"
|
|
||||||
|
|
||||||
- name: Build openssh public keys
|
- name: Build openssh public keys
|
||||||
openssl_publickey:
|
openssl_publickey:
|
||||||
path: "configs/{{ IP_subject_alt_name }}/pki/public/{{ item }}.pub"
|
path: "{{ ipsec_pki_path }}/public/{{ item }}.pub"
|
||||||
privatekey_path: "configs/{{ IP_subject_alt_name }}/pki/private/{{ item }}.key"
|
privatekey_path: "{{ ipsec_pki_path }}/private/{{ item }}.key"
|
||||||
format: OpenSSH
|
format: OpenSSH
|
||||||
with_items: "{{ users }}"
|
with_items: "{{ users }}"
|
||||||
|
|
||||||
|
@ -144,16 +146,15 @@
|
||||||
-out private/{{ item }}.p12
|
-out private/{{ item }}.p12
|
||||||
-passout pass:"{{ p12_export_password }}"
|
-passout pass:"{{ p12_export_password }}"
|
||||||
args:
|
args:
|
||||||
chdir: "configs/{{ IP_subject_alt_name }}/pki/"
|
chdir: "{{ ipsec_pki_path }}"
|
||||||
executable: bash
|
executable: bash
|
||||||
with_items: "{{ users }}"
|
with_items: "{{ users }}"
|
||||||
register: p12
|
register: p12
|
||||||
|
|
||||||
- name: Copy the p12 certificates
|
- name: Copy the p12 certificates
|
||||||
copy:
|
copy:
|
||||||
src: "configs/{{ IP_subject_alt_name }}/pki/private/{{ item }}.p12"
|
src: "{{ ipsec_pki_path }}/private/{{ item }}.p12"
|
||||||
dest: "configs/{{ IP_subject_alt_name }}/{{ item }}.p12"
|
dest: "{{ ipsec_config_path }}/manual/{{ item }}.p12"
|
||||||
mode: 0600
|
|
||||||
with_items:
|
with_items:
|
||||||
- "{{ users }}"
|
- "{{ users }}"
|
||||||
|
|
||||||
|
@ -164,7 +165,7 @@
|
||||||
awk '{print $5}' |
|
awk '{print $5}' |
|
||||||
sed 's/\/CN=//g'
|
sed 's/\/CN=//g'
|
||||||
args:
|
args:
|
||||||
chdir: "configs/{{ IP_subject_alt_name }}/pki/"
|
chdir: "{{ ipsec_pki_path}}"
|
||||||
register: valid_certs
|
register: valid_certs
|
||||||
|
|
||||||
- name: Revoke non-existing users
|
- name: Revoke non-existing users
|
||||||
|
@ -176,7 +177,7 @@
|
||||||
-out crl/{{ item }}.crt
|
-out crl/{{ item }}.crt
|
||||||
register: gencrl
|
register: gencrl
|
||||||
args:
|
args:
|
||||||
chdir: configs/{{ IP_subject_alt_name }}/pki/
|
chdir: "{{ ipsec_pki_path }}"
|
||||||
creates: crl/{{ item }}.crt
|
creates: crl/{{ item }}.crt
|
||||||
executable: bash
|
executable: bash
|
||||||
when: item not in users
|
when: item not in users
|
||||||
|
@ -192,7 +193,7 @@
|
||||||
- gencrl is defined
|
- gencrl is defined
|
||||||
- gencrl.changed
|
- gencrl.changed
|
||||||
args:
|
args:
|
||||||
chdir: configs/{{ IP_subject_alt_name }}/pki/
|
chdir: "{{ ipsec_pki_path }}"
|
||||||
executable: bash
|
executable: bash
|
||||||
delegate_to: localhost
|
delegate_to: localhost
|
||||||
become: no
|
become: no
|
||||||
|
@ -201,7 +202,7 @@
|
||||||
|
|
||||||
- name: Copy the CRL to the vpn server
|
- name: Copy the CRL to the vpn server
|
||||||
copy:
|
copy:
|
||||||
src: configs/{{ IP_subject_alt_name }}/pki/crl/algo.root.pem
|
src: "{{ ipsec_pki_path }}/crl/algo.root.pem"
|
||||||
dest: "{{ config_prefix|default('/') }}etc/ipsec.d/crls/algo.root.pem"
|
dest: "{{ config_prefix|default('/') }}etc/ipsec.d/crls/algo.root.pem"
|
||||||
when:
|
when:
|
||||||
- gencrl is defined
|
- gencrl is defined
|
|
@ -43,6 +43,3 @@
|
||||||
notify:
|
notify:
|
||||||
- daemon-reload
|
- daemon-reload
|
||||||
- restart strongswan
|
- restart strongswan
|
||||||
|
|
||||||
- include_tasks: iptables.yml
|
|
||||||
tags: iptables
|
|
|
@ -27,7 +27,7 @@ conn %default
|
||||||
|
|
||||||
right=%any
|
right=%any
|
||||||
rightauth=pubkey
|
rightauth=pubkey
|
||||||
rightsourceip={{ vpn_network }},{{ vpn_network_ipv6 }}
|
rightsourceip={{ strongswan_network }},{{ strongswan_network_ipv6 }}
|
||||||
{% if algo_local_dns or dns_encryption %}
|
{% if algo_local_dns or dns_encryption %}
|
||||||
rightdns={{ local_service_ip }}
|
rightdns={{ local_service_ip }}
|
||||||
{% else %}
|
{% else %}
|
|
@ -1,27 +0,0 @@
|
||||||
---
|
|
||||||
|
|
||||||
- name: Copy the keys to the strongswan directory
|
|
||||||
copy:
|
|
||||||
src: "{{ item.src }}"
|
|
||||||
dest: "{{ item.dest }}"
|
|
||||||
owner: "{{ item.owner }}"
|
|
||||||
group: "{{ item.group }}"
|
|
||||||
mode: "{{ item.mode }}"
|
|
||||||
with_items:
|
|
||||||
- src: "configs/{{ IP_subject_alt_name }}/pki/cacert.pem"
|
|
||||||
dest: "{{ config_prefix|default('/') }}etc/ipsec.d/cacerts/ca.crt"
|
|
||||||
owner: strongswan
|
|
||||||
group: "{{ root_group|default('root') }}"
|
|
||||||
mode: "0600"
|
|
||||||
- src: "configs/{{ IP_subject_alt_name }}/pki/certs/{{ IP_subject_alt_name }}.crt"
|
|
||||||
dest: "{{ config_prefix|default('/') }}etc/ipsec.d/certs/{{ IP_subject_alt_name }}.crt"
|
|
||||||
owner: strongswan
|
|
||||||
group: "{{ root_group|default('root') }}"
|
|
||||||
mode: "0600"
|
|
||||||
- src: "configs/{{ IP_subject_alt_name }}/pki/private/{{ IP_subject_alt_name }}.key"
|
|
||||||
dest: "{{ config_prefix|default('/') }}etc/ipsec.d/private/{{ IP_subject_alt_name }}.key"
|
|
||||||
owner: strongswan
|
|
||||||
group: "{{ root_group|default('root') }}"
|
|
||||||
mode: "0600"
|
|
||||||
notify:
|
|
||||||
- restart strongswan
|
|
|
@ -1,4 +1,28 @@
|
||||||
---
|
---
|
||||||
wireguard_PersistentKeepalive: 0
|
wireguard_PersistentKeepalive: 0
|
||||||
wireguard_client_ip: "{{ wireguard_network_ipv4['clients_range'] }}.{{ wireguard_network_ipv4['clients_start'] + index|int + 1 }}/{{ wireguard_network_ipv4['prefix'] }}{% if ipv6_support %},{{ wireguard_network_ipv6['clients_range'] }}{{ wireguard_network_ipv6['clients_start'] + index|int + 1 }}/{{ wireguard_network_ipv6['prefix'] }}{% endif %}"
|
wireguard_config_path: "configs/{{ IP_subject_alt_name }}/wireguard/"
|
||||||
wireguard_server_ip: "{{ wireguard_network_ipv4['gateway'] }}/{{ wireguard_network_ipv4['prefix'] }}{% if ipv6_support %},{{ wireguard_network_ipv6['gateway'] }}/{{ wireguard_network_ipv6['prefix'] }}{% endif %}"
|
wireguard_pki_path: "{{ wireguard_config_path }}/.pki/"
|
||||||
|
wireguard_interface: wg0
|
||||||
|
_wireguard_network_ipv4:
|
||||||
|
subnet: 10.19.49.0
|
||||||
|
prefix: 24
|
||||||
|
gateway: 10.19.49.1
|
||||||
|
clients_range: 10.19.49
|
||||||
|
clients_start: 2
|
||||||
|
_wireguard_network_ipv6:
|
||||||
|
subnet: 'fd9d:bc11:4021::'
|
||||||
|
prefix: 48
|
||||||
|
gateway: 'fd9d:bc11:4021::1'
|
||||||
|
clients_range: 'fd9d:bc11:4021::'
|
||||||
|
clients_start: 2
|
||||||
|
wireguard_network_ipv4: "{{ _wireguard_network_ipv4['subnet'] }}/{{ _wireguard_network_ipv4['prefix'] }}"
|
||||||
|
wireguard_network_ipv6: "{{ _wireguard_network_ipv6['subnet'] }}/{{ _wireguard_network_ipv6['prefix'] }}"
|
||||||
|
keys_clean_all: false
|
||||||
|
wireguard_dns_servers: >-
|
||||||
|
{% if local_dns|default(false)|bool or dns_encryption|default(false)|bool == true %}
|
||||||
|
{{ 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 %}
|
||||||
|
{% endif %}
|
||||||
|
wireguard_client_ip: "{{ _wireguard_network_ipv4['clients_range'] }}.{{ _wireguard_network_ipv4['clients_start'] + index|int + 1 }}/{{ _wireguard_network_ipv4['prefix'] }}{% if ipv6_support %},{{ _wireguard_network_ipv6['clients_range'] }}{{ _wireguard_network_ipv6['clients_start'] + index|int + 1 }}/{{ _wireguard_network_ipv6['prefix'] }}{% endif %}"
|
||||||
|
wireguard_server_ip: "{{ _wireguard_network_ipv4['gateway'] }}/{{ _wireguard_network_ipv4['prefix'] }}{% if ipv6_support %},{{ _wireguard_network_ipv6['gateway'] }}/{{ _wireguard_network_ipv6['prefix'] }}{% endif %}"
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
- block:
|
- block:
|
||||||
- name: Save private keys
|
- name: Save private keys
|
||||||
copy:
|
copy:
|
||||||
dest: "{{ wireguard_config_path }}/private/{{ item['item'] }}"
|
dest: "{{ wireguard_pki_path }}/private/{{ item['item'] }}"
|
||||||
content: "{{ item['stdout'] }}"
|
content: "{{ item['stdout'] }}"
|
||||||
mode: "0600"
|
mode: "0600"
|
||||||
no_log: true
|
no_log: true
|
||||||
|
@ -39,7 +39,7 @@
|
||||||
when: wg_genkey.changed
|
when: wg_genkey.changed
|
||||||
|
|
||||||
- name: Generate public keys
|
- name: Generate public keys
|
||||||
shell: echo "{{ lookup('file', wireguard_config_path + '/private/' + item) }}" | wg pubkey
|
shell: echo "{{ lookup('file', wireguard_pki_path + '/private/' + item) }}" | wg pubkey
|
||||||
register: wg_pubkey
|
register: wg_pubkey
|
||||||
changed_when: false
|
changed_when: false
|
||||||
args:
|
args:
|
||||||
|
@ -50,7 +50,7 @@
|
||||||
|
|
||||||
- name: Save public keys
|
- name: Save public keys
|
||||||
copy:
|
copy:
|
||||||
dest: "{{ wireguard_config_path }}/public/{{ item['item'] }}"
|
dest: "{{ wireguard_pki_path }}/public/{{ item['item'] }}"
|
||||||
content: "{{ item['stdout'] }}"
|
content: "{{ item['stdout'] }}"
|
||||||
mode: "0600"
|
mode: "0600"
|
||||||
no_log: true
|
no_log: true
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
---
|
---
|
||||||
- name: Ensure the required directories exist
|
- name: Ensure the required directories exist
|
||||||
file:
|
file:
|
||||||
dest: "{{ wireguard_config_path }}/{{ item }}"
|
dest: "{{ wireguard_pki_path }}/{{ item }}"
|
||||||
state: directory
|
state: directory
|
||||||
recurse: true
|
recurse: true
|
||||||
with_items:
|
with_items:
|
||||||
|
@ -28,7 +28,7 @@
|
||||||
- block:
|
- block:
|
||||||
- name: WireGuard user list updated
|
- name: WireGuard user list updated
|
||||||
lineinfile:
|
lineinfile:
|
||||||
dest: "{{ wireguard_config_path }}/index.txt"
|
dest: "{{ wireguard_pki_path }}/index.txt"
|
||||||
create: true
|
create: true
|
||||||
mode: "0600"
|
mode: "0600"
|
||||||
insertafter: EOF
|
insertafter: EOF
|
||||||
|
@ -37,7 +37,7 @@
|
||||||
with_items: "{{ users }}"
|
with_items: "{{ users }}"
|
||||||
|
|
||||||
- set_fact:
|
- set_fact:
|
||||||
wireguard_users: "{{ (lookup('file', wireguard_config_path + 'index.txt')).split('\n') }}"
|
wireguard_users: "{{ (lookup('file', wireguard_pki_path + 'index.txt')).split('\n') }}"
|
||||||
|
|
||||||
- name: WireGuard users config generated
|
- name: WireGuard users config generated
|
||||||
template:
|
template:
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
[Interface]
|
[Interface]
|
||||||
PrivateKey = {{ lookup('file', wireguard_config_path + '/private/' + item.1) }}
|
PrivateKey = {{ lookup('file', wireguard_pki_path + '/private/' + item.1) }}
|
||||||
Address = {{ wireguard_client_ip }}
|
Address = {{ wireguard_client_ip }}
|
||||||
DNS = {{ wireguard_dns_servers }}
|
DNS = {{ wireguard_dns_servers }}
|
||||||
{% if reduce_mtu|int > 0 %}MTU = {{ 1420 - reduce_mtu|int }}
|
{% if reduce_mtu|int > 0 %}MTU = {{ 1420 - reduce_mtu|int }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
[Peer]
|
[Peer]
|
||||||
PublicKey = {{ lookup('file', wireguard_config_path + '/public/' + IP_subject_alt_name) }}
|
PublicKey = {{ lookup('file', wireguard_pki_path + '/public/' + IP_subject_alt_name) }}
|
||||||
AllowedIPs = 0.0.0.0/0, ::/0
|
AllowedIPs = 0.0.0.0/0, ::/0
|
||||||
Endpoint = {{ IP_subject_alt_name }}:{{ wireguard_port }}
|
Endpoint = {{ IP_subject_alt_name }}:{{ wireguard_port }}
|
||||||
{{ 'PersistentKeepalive = ' + wireguard_PersistentKeepalive|string if wireguard_PersistentKeepalive > 0 else '' }}
|
{{ 'PersistentKeepalive = ' + wireguard_PersistentKeepalive|string if wireguard_PersistentKeepalive > 0 else '' }}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
[Interface]
|
[Interface]
|
||||||
Address = {{ wireguard_server_ip }}
|
Address = {{ wireguard_server_ip }}
|
||||||
ListenPort = {{ wireguard_port }}
|
ListenPort = {{ wireguard_port }}
|
||||||
PrivateKey = {{ lookup('file', wireguard_config_path + '/private/' + IP_subject_alt_name) }}
|
PrivateKey = {{ lookup('file', wireguard_pki_path + '/private/' + IP_subject_alt_name) }}
|
||||||
SaveConfig = false
|
SaveConfig = false
|
||||||
|
|
||||||
{% for u in wireguard_users %}
|
{% for u in wireguard_users %}
|
||||||
|
@ -10,8 +10,8 @@ SaveConfig = false
|
||||||
|
|
||||||
[Peer]
|
[Peer]
|
||||||
# {{ u }}
|
# {{ u }}
|
||||||
PublicKey = {{ lookup('file', wireguard_config_path + '/public/' + u) }}
|
PublicKey = {{ lookup('file', wireguard_pki_path + '/public/' + u) }}
|
||||||
AllowedIPs = {{ wireguard_network_ipv4['clients_range'] }}.{{ wireguard_network_ipv4['clients_start'] + index }}/32{% if ipv6_support %},{{ wireguard_network_ipv6['clients_range'] }}{{ wireguard_network_ipv6['clients_start'] + index }}/128{% endif %}
|
AllowedIPs = {{ _wireguard_network_ipv4['clients_range'] }}.{{ _wireguard_network_ipv4['clients_start'] + index }}/32{% if ipv6_support %},{{ _wireguard_network_ipv6['clients_range'] }}{{ _wireguard_network_ipv6['clients_start'] + index }}/128{% endif %}
|
||||||
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
21
server.yml
21
server.yml
|
@ -19,8 +19,9 @@
|
||||||
- role: wireguard
|
- role: wireguard
|
||||||
when: wireguard_enabled
|
when: wireguard_enabled
|
||||||
tags: wireguard
|
tags: wireguard
|
||||||
- role: vpn
|
- role: strongswan
|
||||||
tags: vpn
|
when: ipsec_enabled
|
||||||
|
tags: ipsec
|
||||||
- role: ssh_tunneling
|
- role: ssh_tunneling
|
||||||
when: algo_ssh_tunneling
|
when: algo_ssh_tunneling
|
||||||
tags: ssh_tunneling
|
tags: ssh_tunneling
|
||||||
|
@ -30,15 +31,17 @@
|
||||||
- name: Delete the CA key
|
- name: Delete the CA key
|
||||||
local_action:
|
local_action:
|
||||||
module: file
|
module: file
|
||||||
path: "configs/{{ IP_subject_alt_name }}/pki/private/cakey.pem"
|
path: "{{ ipsec_pki_path }}/private/cakey.pem"
|
||||||
state: absent
|
state: absent
|
||||||
become: false
|
become: false
|
||||||
when: not algo_store_cakey
|
when:
|
||||||
|
- ipsec_enabled
|
||||||
|
- not algo_store_cakey
|
||||||
|
|
||||||
- name: Dump the configuration
|
- name: Dump the configuration
|
||||||
local_action:
|
local_action:
|
||||||
module: copy
|
module: copy
|
||||||
dest: "configs/{{ IP_subject_alt_name }}/config.yml"
|
dest: "configs/{{ IP_subject_alt_name }}/.config.yml"
|
||||||
content: |
|
content: |
|
||||||
server: {{ 'localhost' if inventory_hostname == 'localhost' else inventory_hostname }}
|
server: {{ 'localhost' if inventory_hostname == 'localhost' else inventory_hostname }}
|
||||||
server_user: {{ ansible_ssh_user }}
|
server_user: {{ ansible_ssh_user }}
|
||||||
|
@ -55,6 +58,8 @@
|
||||||
algo_windows: {{ algo_windows }}
|
algo_windows: {{ algo_windows }}
|
||||||
algo_store_cakey: {{ algo_store_cakey }}
|
algo_store_cakey: {{ algo_store_cakey }}
|
||||||
IP_subject_alt_name: {{ IP_subject_alt_name }}
|
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 }}{% endif %}
|
||||||
become: false
|
become: false
|
||||||
|
|
||||||
|
@ -69,9 +74,9 @@
|
||||||
- debug:
|
- debug:
|
||||||
msg:
|
msg:
|
||||||
- "{{ congrats.common.split('\n') }}"
|
- "{{ congrats.common.split('\n') }}"
|
||||||
- " {{ congrats.p12_pass }}"
|
- " {{ congrats.p12_pass if algo_ssh_tunneling or ipsec_enabled else '' }}"
|
||||||
- " {% if algo_store_cakey %}{{ congrats.ca_key_pass }}{% endif %}"
|
- " {{ congrats.ca_key_pass if algo_store_cakey and ipsec_enabled else '' }}"
|
||||||
- " {% if algo_provider != 'local' %}{{ congrats.ssh_access }}{% endif %}"
|
- " {{ congrats.ssh_access if algo_provider != 'local' else ''}}"
|
||||||
tags: always
|
tags: always
|
||||||
rescue:
|
rescue:
|
||||||
- debug: var=fail_hint
|
- debug: var=fail_hint
|
||||||
|
|
|
@ -11,7 +11,11 @@ else
|
||||||
ansible-playbook users.yml -e "${USER_ARGS}" -t update-users
|
ansible-playbook users.yml -e "${USER_ARGS}" -t update-users
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if sudo openssl crl -inform pem -noout -text -in configs/$LXC_IP/pki/crl/phone.crt | grep CRL
|
#
|
||||||
|
# IPsec
|
||||||
|
#
|
||||||
|
|
||||||
|
if sudo openssl crl -inform pem -noout -text -in configs/$LXC_IP/ipsec/.pki/crl/phone.crt | grep CRL
|
||||||
then
|
then
|
||||||
echo "The CRL check passed"
|
echo "The CRL check passed"
|
||||||
else
|
else
|
||||||
|
@ -19,10 +23,34 @@ if sudo openssl crl -inform pem -noout -text -in configs/$LXC_IP/pki/crl/phone.c
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if sudo openssl x509 -inform pem -noout -text -in configs/$LXC_IP/pki/certs/user1.crt | grep CN=user1
|
if sudo openssl x509 -inform pem -noout -text -in configs/$LXC_IP/ipsec/.pki/certs/user1.crt | grep CN=user1
|
||||||
then
|
then
|
||||||
echo "The new user exists"
|
echo "The new user exists"
|
||||||
else
|
else
|
||||||
echo "The new user does not exist"
|
echo "The new user does not exist"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
#
|
||||||
|
# WireGuard
|
||||||
|
#
|
||||||
|
|
||||||
|
if sudo test -f configs/$LXC_IP/wireguard/user1.conf
|
||||||
|
then
|
||||||
|
echo "WireGuard: The new user exists"
|
||||||
|
else
|
||||||
|
echo "WireGuard: The new user does not exist"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
#
|
||||||
|
# SSH tunneling
|
||||||
|
#
|
||||||
|
|
||||||
|
if sudo test -f configs/$LXC_IP/ssh-tunnel/user1.ssh_config
|
||||||
|
then
|
||||||
|
echo "SSH Tunneling: The new user exists"
|
||||||
|
else
|
||||||
|
echo "SSH Tunneling: The new user does not exist"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
15
users.yml
15
users.yml
|
@ -21,13 +21,15 @@
|
||||||
|
|
||||||
- name: Import host specific variables
|
- name: Import host specific variables
|
||||||
include_vars:
|
include_vars:
|
||||||
file: "configs/{{ algo_server }}/config.yml"
|
file: "configs/{{ algo_server }}/.config.yml"
|
||||||
|
|
||||||
- pause:
|
- pause:
|
||||||
prompt: Enter the password for the private CA key
|
prompt: Enter the password for the private CA key
|
||||||
echo: false
|
echo: false
|
||||||
register: _ca_password
|
register: _ca_password
|
||||||
when: ca_password is undefined
|
when:
|
||||||
|
- ca_password is undefined
|
||||||
|
- ipsec_enabled
|
||||||
|
|
||||||
- name: Set facts based on the input
|
- name: Set facts based on the input
|
||||||
set_fact:
|
set_fact:
|
||||||
|
@ -42,7 +44,7 @@
|
||||||
groups: vpn-host
|
groups: vpn-host
|
||||||
ansible_ssh_user: "{{ server_user|default('root') }}"
|
ansible_ssh_user: "{{ server_user|default('root') }}"
|
||||||
ansible_connection: "{% if algo_server == 'localhost' %}local{% else %}ssh{% endif %}"
|
ansible_connection: "{% if algo_server == 'localhost' %}local{% else %}ssh{% endif %}"
|
||||||
ansible_python_interpreter: "/usr/bin/python2.7"
|
ansible_python_interpreter: "/usr/bin/python3"
|
||||||
CA_password: "{{ CA_password }}"
|
CA_password: "{{ CA_password }}"
|
||||||
rescue:
|
rescue:
|
||||||
- debug: var=fail_hint
|
- debug: var=fail_hint
|
||||||
|
@ -56,7 +58,7 @@
|
||||||
become: true
|
become: true
|
||||||
vars_files:
|
vars_files:
|
||||||
- config.cfg
|
- config.cfg
|
||||||
- "configs/{{ inventory_hostname }}/config.yml"
|
- "configs/{{ inventory_hostname }}/.config.yml"
|
||||||
|
|
||||||
pre_tasks:
|
pre_tasks:
|
||||||
- block:
|
- block:
|
||||||
|
@ -74,8 +76,9 @@
|
||||||
- role: wireguard
|
- role: wireguard
|
||||||
tags: [ 'vpn', 'wireguard' ]
|
tags: [ 'vpn', 'wireguard' ]
|
||||||
when: wireguard_enabled
|
when: wireguard_enabled
|
||||||
- role: vpn
|
- role: strongswan
|
||||||
tags: vpn
|
when: ipsec_enabled
|
||||||
|
tags: ipsec
|
||||||
- role: ssh_tunneling
|
- role: ssh_tunneling
|
||||||
when: algo_ssh_tunneling
|
when: algo_ssh_tunneling
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue