mirror of
https://github.com/trailofbits/algo.git
synced 2025-06-07 15:43:54 +02:00
Roles enabled
This commit is contained in:
parent
6cdc749969
commit
fff70293f1
18 changed files with 664 additions and 646 deletions
104
common.yml
104
common.yml
|
@ -1,104 +0,0 @@
|
||||||
# vim:ft=ansible:
|
|
||||||
---
|
|
||||||
|
|
||||||
- name: Common tools
|
|
||||||
hosts: vpn-host
|
|
||||||
gather_facts: false
|
|
||||||
become: true
|
|
||||||
vars_files:
|
|
||||||
- config.cfg
|
|
||||||
|
|
||||||
pre_tasks:
|
|
||||||
- name: Install prerequisites
|
|
||||||
raw: sudo apt-get update -qq && sudo apt-get install -qq -y python2.7
|
|
||||||
- name: Configure defaults
|
|
||||||
raw: sudo update-alternatives --install /usr/bin/python python /usr/bin/python2.7 1
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Wait for port 22 to become available
|
|
||||||
local_action: "wait_for port=22 host={{ inventory_hostname }}"
|
|
||||||
become: false
|
|
||||||
|
|
||||||
- name: Gather Facts
|
|
||||||
setup:
|
|
||||||
|
|
||||||
- name: Install software updates
|
|
||||||
apt: update_cache=yes upgrade=dist
|
|
||||||
|
|
||||||
- name: Check if reboot is required
|
|
||||||
shell: >
|
|
||||||
if [[ $(readlink -f /vmlinuz) != /boot/vmlinuz-$(uname -r) ]]; then echo "required"; else echo "no"; fi
|
|
||||||
args:
|
|
||||||
executable: /bin/bash
|
|
||||||
register: reboot_required
|
|
||||||
|
|
||||||
- name: Reboot
|
|
||||||
shell: sleep 2 && shutdown -r now "Ansible updates triggered"
|
|
||||||
async: 1
|
|
||||||
poll: 0
|
|
||||||
when: reboot_required is defined and reboot_required.stdout == 'required'
|
|
||||||
ignore_errors: true
|
|
||||||
|
|
||||||
- name: Wait for shutdown
|
|
||||||
local_action: wait_for host={{ inventory_hostname }} port=22 state=stopped timeout=120
|
|
||||||
when: reboot_required is defined and reboot_required.stdout == 'required'
|
|
||||||
become: false
|
|
||||||
|
|
||||||
- name: Wait until SSH becomes ready...
|
|
||||||
local_action: wait_for host={{ inventory_hostname }} port=22 state=started timeout=120
|
|
||||||
when: reboot_required is defined and reboot_required.stdout == 'required'
|
|
||||||
become: false
|
|
||||||
|
|
||||||
# SSH fixes
|
|
||||||
|
|
||||||
- name: SSH config
|
|
||||||
lineinfile: dest="{{ item.file }}" regexp="{{ item.regexp }}" line="{{ item.line }}" state=present
|
|
||||||
with_items:
|
|
||||||
- { regexp: '^PasswordAuthentication.*', line: 'PasswordAuthentication no', file: '/etc/ssh/sshd_config' }
|
|
||||||
- { regexp: '^PermitRootLogin.*', line: 'PermitRootLogin without-password', file: '/etc/ssh/sshd_config' }
|
|
||||||
- { regexp: '^UseDNS.*', line: 'UseDNS no', file: '/etc/ssh/sshd_config' }
|
|
||||||
- { regexp: '^Ciphers', line: 'Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com', file: '/etc/ssh/sshd_config' }
|
|
||||||
- { regexp: '^MACs', line: 'MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com', file: '/etc/ssh/sshd_config' }
|
|
||||||
- { regexp: '^KexAlgorithms', line: 'KexAlgorithms curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384', file: '/etc/ssh/sshd_config' }
|
|
||||||
notify:
|
|
||||||
- restart ssh
|
|
||||||
|
|
||||||
- name: Disable MOTD on login and SSHD
|
|
||||||
replace: dest="{{ item.file }}" regexp="{{ item.regexp }}" replace="{{ item.line }}"
|
|
||||||
with_items:
|
|
||||||
- { regexp: '^session.*optional.*pam_motd.so.*', line: '# MOTD DISABLED', file: '/etc/pam.d/login' }
|
|
||||||
- { regexp: '^session.*optional.*pam_motd.so.*', line: '# MOTD DISABLED', file: '/etc/pam.d/sshd' }
|
|
||||||
|
|
||||||
- name: Install tools
|
|
||||||
apt: name="{{ item }}" state=latest
|
|
||||||
with_items:
|
|
||||||
- git
|
|
||||||
- screen
|
|
||||||
- apparmor-utils
|
|
||||||
- uuid-runtime
|
|
||||||
- coreutils
|
|
||||||
- auditd
|
|
||||||
- rsyslog
|
|
||||||
- sendmail
|
|
||||||
- unattended-upgrades
|
|
||||||
- iptables-persistent
|
|
||||||
|
|
||||||
- name: Configure unattended-upgrades
|
|
||||||
template: src=50unattended-upgrades.j2 dest=/etc/apt/apt.conf.d/50unattended-upgrades owner=root group=root mode=644
|
|
||||||
|
|
||||||
- name: Periodic upgrades configured
|
|
||||||
template: src=10periodic.j2 dest=/etc/apt/apt.conf.d/10periodic owner=root group=root mode=644
|
|
||||||
|
|
||||||
handlers:
|
|
||||||
- name: restart auditd
|
|
||||||
service: name=auditd state=restarted
|
|
||||||
|
|
||||||
- name: restart rsyslog
|
|
||||||
service: name=rsyslog state=restarted
|
|
||||||
|
|
||||||
- name: restart ssh
|
|
||||||
service: name=ssh state=restarted
|
|
||||||
|
|
||||||
- name: flush routing cache
|
|
||||||
shell: echo 1 > /proc/sys/net/ipv4/route/flush
|
|
||||||
|
|
|
@ -1,8 +1,4 @@
|
||||||
---
|
---
|
||||||
|
|
||||||
- include: "{{ provider }}.yml"
|
- include: "{{ provider }}.yml"
|
||||||
- include: common.yml
|
|
||||||
- include: security.yml
|
|
||||||
- include: features.yml
|
|
||||||
- include: vpn.yml
|
|
||||||
|
|
||||||
|
|
108
digitalocean.yml
108
digitalocean.yml
|
@ -47,66 +47,23 @@
|
||||||
default: "algo.local"
|
default: "algo.local"
|
||||||
private: no
|
private: no
|
||||||
|
|
||||||
tasks:
|
- name: "dns_enabled"
|
||||||
- name: "Getting your SSH key ID on Digital Ocean..."
|
prompt: "Do you want to use a local DNS resolver to block ads while surfing? (Y or N):\n"
|
||||||
digital_ocean:
|
default: "Y"
|
||||||
state: present
|
private: no
|
||||||
command: ssh
|
|
||||||
name: "{{ do_ssh_name }}"
|
|
||||||
api_token: "{{ do_access_token }}"
|
|
||||||
register: do_ssh_key
|
|
||||||
|
|
||||||
- name: "Creating a droplet..."
|
- name: "auditd_enabled"
|
||||||
digital_ocean:
|
prompt: "Do you want to use auditd ? (Y or N):\n"
|
||||||
state: present
|
default: "Y"
|
||||||
command: droplet
|
private: no
|
||||||
name: "{{ do_server_name }}"
|
|
||||||
region_id: "{{ regions[do_region] }}"
|
|
||||||
size_id: "512mb"
|
|
||||||
image_id: "ubuntu-16-04-x64"
|
|
||||||
ssh_key_ids: "{{ do_ssh_key.ssh_key.id }}"
|
|
||||||
unique_name: yes
|
|
||||||
api_token: "{{ do_access_token }}"
|
|
||||||
register: do
|
|
||||||
|
|
||||||
- name: Add the droplet to an inventory group
|
roles:
|
||||||
add_host:
|
- digitalocean
|
||||||
name: "{{ do.droplet.ip_address }}"
|
|
||||||
groups: vpn-host
|
|
||||||
ansible_ssh_user: root
|
|
||||||
ansible_python_interpreter: "/usr/bin/python2.7"
|
|
||||||
|
|
||||||
- name: Wait for SSH to become available
|
|
||||||
local_action: "wait_for port=22 host={{ do.droplet.ip_address }} timeout=320"
|
|
||||||
|
|
||||||
- name: Enable IPv6 on the droplet
|
|
||||||
uri:
|
|
||||||
url: "https://api.digitalocean.com/v2/droplets/{{ do.droplet.id }}/actions"
|
|
||||||
method: POST
|
|
||||||
body:
|
|
||||||
type: enable_ipv6
|
|
||||||
body_format: json
|
|
||||||
status_code: 201
|
|
||||||
HEADER_Authorization: "Bearer {{ do_access_token }}"
|
|
||||||
HEADER_Content-Type: "application/json"
|
|
||||||
|
|
||||||
- name: Get Droplet networks
|
|
||||||
uri:
|
|
||||||
url: "https://api.digitalocean.com/v2/droplets/{{ do.droplet.id }}"
|
|
||||||
method: GET
|
|
||||||
status_code: 200
|
|
||||||
HEADER_Authorization: "Bearer {{ do_access_token }}"
|
|
||||||
HEADER_Content-Type: "application/json"
|
|
||||||
register: droplet_info
|
|
||||||
|
|
||||||
- name: IPv6 template created
|
|
||||||
template: src=20-ipv6.cfg.j2 dest=configs/20-ipv6.tmp
|
|
||||||
with_items: "{{ droplet_info.json.droplet.networks.v6 }}"
|
|
||||||
|
|
||||||
- name: Post-provisioning tasks
|
- name: Post-provisioning tasks
|
||||||
hosts: vpn-host
|
hosts: vpn-host
|
||||||
gather_facts: false
|
gather_facts: false
|
||||||
user: root
|
become: true
|
||||||
vars_files:
|
vars_files:
|
||||||
- config.cfg
|
- config.cfg
|
||||||
|
|
||||||
|
@ -116,18 +73,53 @@
|
||||||
- name: Configure defaults
|
- name: Configure defaults
|
||||||
raw: sudo update-alternatives --install /usr/bin/python python /usr/bin/python2.7 1
|
raw: sudo update-alternatives --install /usr/bin/python python /usr/bin/python2.7 1
|
||||||
|
|
||||||
tasks:
|
- name: Enable IPv6 on the droplet
|
||||||
|
uri:
|
||||||
|
url: "https://api.digitalocean.com/v2/droplets/{{ do_droplet_id }}/actions"
|
||||||
|
method: POST
|
||||||
|
body:
|
||||||
|
type: enable_ipv6
|
||||||
|
body_format: json
|
||||||
|
status_code: 201
|
||||||
|
HEADER_Authorization: "Bearer {{ do_access_token }}"
|
||||||
|
HEADER_Content-Type: "application/json"
|
||||||
|
|
||||||
|
- name: Get Droplet networks
|
||||||
|
uri:
|
||||||
|
url: "https://api.digitalocean.com/v2/droplets/{{ do_droplet_id }}"
|
||||||
|
method: GET
|
||||||
|
status_code: 200
|
||||||
|
HEADER_Authorization: "Bearer {{ do_access_token }}"
|
||||||
|
HEADER_Content-Type: "application/json"
|
||||||
|
register: droplet_info
|
||||||
|
|
||||||
- name: IPv6 configured
|
- name: IPv6 configured
|
||||||
copy: src=configs/20-ipv6.tmp dest=/etc/network/interfaces.d/20-ipv6.cfg owner=root group=root mode=0644
|
template: src=20-ipv6.cfg.j2 dest=/etc/network/interfaces.d/20-ipv6.cfg owner=root group=root mode=0644
|
||||||
|
with_items: "{{ droplet_info.json.droplet.networks.v6 }}"
|
||||||
|
notify:
|
||||||
|
- reload eth0
|
||||||
|
|
||||||
- name: IPv6 included into the network config
|
- name: IPv6 included into the network config
|
||||||
lineinfile: dest=/etc/network/interfaces line='source /etc/network/interfaces.d/20-ipv6.cfg' state=present
|
lineinfile: dest=/etc/network/interfaces line='source /etc/network/interfaces.d/20-ipv6.cfg' state=present
|
||||||
|
notify:
|
||||||
|
- reload eth0
|
||||||
|
|
||||||
- name: IPV6 is running
|
- meta: flush_handlers
|
||||||
shell: sh -c 'ifdown eth0; ip addr flush dev eth0; ifup eth0'
|
|
||||||
|
|
||||||
- name: Wait for SSH to become available
|
- name: Wait for SSH to become available
|
||||||
local_action: "wait_for port=22 host={{ inventory_hostname }} timeout=320"
|
local_action: "wait_for port=22 host={{ inventory_hostname }} timeout=320"
|
||||||
become: false
|
become: false
|
||||||
|
|
||||||
|
roles:
|
||||||
|
- common
|
||||||
|
- security
|
||||||
|
- features
|
||||||
|
- vpn
|
||||||
|
|
||||||
|
handlers:
|
||||||
|
- name: reload eth0
|
||||||
|
shell: sh -c 'ifdown eth0; ip addr flush dev eth0; ifup eth0'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
39
ec2.yml
39
ec2.yml
|
@ -36,6 +36,16 @@
|
||||||
default: "1"
|
default: "1"
|
||||||
private: no
|
private: no
|
||||||
|
|
||||||
|
- name: "dns_enabled"
|
||||||
|
prompt: "Do you want to use a local DNS resolver to block ads while surfing? (Y or N):\n"
|
||||||
|
default: "Y"
|
||||||
|
private: no
|
||||||
|
|
||||||
|
- name: "auditd_enabled"
|
||||||
|
prompt: "Do you want to use auditd ? (Y or N):\n"
|
||||||
|
default: "Y"
|
||||||
|
private: no
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
|
|
||||||
- name: Grab the default interface subnet.
|
- name: Grab the default interface subnet.
|
||||||
|
@ -107,14 +117,35 @@
|
||||||
register: ec2
|
register: ec2
|
||||||
|
|
||||||
- name: Add new instance to host group
|
- name: Add new instance to host group
|
||||||
add_host: hostname={{ item.public_ip }} groupname=vpn-host remote_user=ubuntu ansible_python_interpreter="/usr/bin/python2.7"
|
add_host:
|
||||||
|
hostname: "{{ item.public_ip }}"
|
||||||
|
groupname: vpn-host
|
||||||
|
remote_user: ubuntu
|
||||||
|
ansible_python_interpreter: "/usr/bin/python2.7"
|
||||||
|
dns_enabled: "{{ dns_enabled }}"
|
||||||
|
auditd_enabled: " {{ auditd_enabled }}"
|
||||||
with_items: "{{ ec2.instances }}"
|
with_items: "{{ ec2.instances }}"
|
||||||
|
|
||||||
- name: Wait for SSH to come up
|
- name: Wait for SSH to come up
|
||||||
wait_for: host={{ item.public_dns_name }} port=22 delay=60 timeout=320 state=started
|
wait_for: host={{ item.public_dns_name }} port=22 delay=60 timeout=320 state=started
|
||||||
with_items: "{{ ec2.instances }}"
|
with_items: "{{ ec2.instances }}"
|
||||||
|
|
||||||
- name: accept new ssh fingerprints
|
- name: Post-provisioning tasks
|
||||||
shell: ssh-keyscan -H {{ item.public_ip }} >> ~/.ssh/known_hosts
|
hosts: vpn-host
|
||||||
with_items: "{{ ec2.instances }}"
|
gather_facts: false
|
||||||
|
become: true
|
||||||
|
vars_files:
|
||||||
|
- config.cfg
|
||||||
|
|
||||||
|
pre_tasks:
|
||||||
|
- name: Install prerequisites
|
||||||
|
raw: sudo apt-get update -qq && sudo apt-get install -qq -y python2.7
|
||||||
|
- name: Configure defaults
|
||||||
|
raw: sudo update-alternatives --install /usr/bin/python python /usr/bin/python2.7 1
|
||||||
|
|
||||||
|
roles:
|
||||||
|
- common
|
||||||
|
- security
|
||||||
|
- features
|
||||||
|
- vpn
|
||||||
|
|
||||||
|
|
160
features.yml
160
features.yml
|
@ -1,160 +0,0 @@
|
||||||
---
|
|
||||||
|
|
||||||
- name: Other features
|
|
||||||
hosts: vpn-host
|
|
||||||
become: true
|
|
||||||
vars_files:
|
|
||||||
- config.cfg
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Loopback for services configured
|
|
||||||
template: src=10-loopback-services.cfg.j2 dest=/etc/network/interfaces.d/10-loopback-services.cfg
|
|
||||||
|
|
||||||
- name: Loopback included into the network config
|
|
||||||
lineinfile: dest=/etc/network/interfaces line='source /etc/network/interfaces.d/10-loopback-services.cfg' state=present
|
|
||||||
|
|
||||||
- name: Loopback is running
|
|
||||||
shell: ifdown lo:100 && ifup lo:100
|
|
||||||
|
|
||||||
# Privoxy
|
|
||||||
|
|
||||||
- name: Install privoxy
|
|
||||||
apt: name=privoxy state=latest
|
|
||||||
|
|
||||||
- name: Privoxy configured
|
|
||||||
template: src=privoxy_config.j2 dest=/etc/privoxy/config
|
|
||||||
notify:
|
|
||||||
- restart privoxy
|
|
||||||
|
|
||||||
- name: Privoxy profile for apparmor configured
|
|
||||||
template: src=usr.sbin.privoxy.j2 dest=/etc/apparmor.d/usr.sbin.privoxy owner=root group=root mode=600
|
|
||||||
notify:
|
|
||||||
- restart privoxy
|
|
||||||
|
|
||||||
- name: Enforce the privoxy AppArmor policy
|
|
||||||
shell: aa-enforce usr.sbin.privoxy
|
|
||||||
|
|
||||||
- name: Privoxy enabled and started
|
|
||||||
service: name=privoxy state=started enabled=yes
|
|
||||||
|
|
||||||
# PageSpeed
|
|
||||||
|
|
||||||
- name: Apache installed
|
|
||||||
apt: name=apache2 state=latest
|
|
||||||
|
|
||||||
- name: PageSpeed installed for x86_64
|
|
||||||
apt: deb=https://dl-ssl.google.com/dl/linux/direct/mod-pagespeed-stable_current_amd64.deb
|
|
||||||
when: ansible_architecture == "x86_64"
|
|
||||||
|
|
||||||
- name: PageSpeed installed for i386
|
|
||||||
apt: deb=https://dl-ssl.google.com/dl/linux/direct/mod-pagespeed-stable_current_i386.deb
|
|
||||||
when: ansible_architecture != "x86_64"
|
|
||||||
|
|
||||||
- name: PageSpeed configured
|
|
||||||
template: src=pagespeed.conf.j2 dest=/etc/apache2/mods-available/pagespeed.conf
|
|
||||||
notify:
|
|
||||||
- restart apache2
|
|
||||||
|
|
||||||
- name: Modules enabled
|
|
||||||
apache2_module: state=present name="{{ item }}"
|
|
||||||
with_items:
|
|
||||||
- proxy_http
|
|
||||||
- pagespeed
|
|
||||||
- cache
|
|
||||||
- proxy_connect
|
|
||||||
- proxy_html
|
|
||||||
- rewrite
|
|
||||||
notify:
|
|
||||||
- restart apache2
|
|
||||||
|
|
||||||
- name: VirtualHost configured for the PageSpeed module
|
|
||||||
template: src=000-default.conf.j2 dest=/etc/apache2/sites-enabled/000-default.conf
|
|
||||||
notify:
|
|
||||||
- restart apache2
|
|
||||||
|
|
||||||
- name: Apache ports configured
|
|
||||||
template: src=ports.conf.j2 dest=/etc/apache2/ports.conf
|
|
||||||
notify:
|
|
||||||
- restart apache2
|
|
||||||
|
|
||||||
# DNS
|
|
||||||
|
|
||||||
- name: Install dnsmasq
|
|
||||||
apt: name=dnsmasq state=latest
|
|
||||||
|
|
||||||
- name: Dnsmasq profile for apparmor configured
|
|
||||||
template: src=usr.sbin.dnsmasq.j2 dest=/etc/apparmor.d/usr.sbin.dnsmasq owner=root group=root mode=600
|
|
||||||
notify:
|
|
||||||
- restart dnsmasq
|
|
||||||
|
|
||||||
- name: Enforce the dnsmasq AppArmor policy
|
|
||||||
shell: aa-enforce usr.sbin.dnsmasq
|
|
||||||
|
|
||||||
- name: Dnsmasq configured
|
|
||||||
template: src=dnsmasq.conf.j2 dest=/etc/dnsmasq.conf
|
|
||||||
notify:
|
|
||||||
- restart dnsmasq
|
|
||||||
|
|
||||||
- name: Adblock script created
|
|
||||||
copy: src=templates/adblock.sh dest=/opt/adblock.sh owner=root group=root mode=755
|
|
||||||
when: service_dns is defined and service_dns == "True"
|
|
||||||
|
|
||||||
- name: Adblock script added to cron
|
|
||||||
cron: name="Adblock hosts update" minute="10" hour="2" job="/opt/adblock.sh"
|
|
||||||
when: service_dns is defined and service_dns == "True"
|
|
||||||
|
|
||||||
- name: Update adblock hosts
|
|
||||||
shell: >
|
|
||||||
/opt/adblock.sh
|
|
||||||
when: service_dns is defined and service_dns == "True"
|
|
||||||
|
|
||||||
- name: Forward all DNS requests to the local resolver
|
|
||||||
iptables:
|
|
||||||
table: nat
|
|
||||||
chain: PREROUTING
|
|
||||||
protocol: udp
|
|
||||||
destination_port: 53
|
|
||||||
source: "{{ vpn_network }}"
|
|
||||||
jump: DNAT
|
|
||||||
to_destination: 172.16.0.1:53
|
|
||||||
notify:
|
|
||||||
- save iptables
|
|
||||||
when: service_dns is defined and service_dns == "True"
|
|
||||||
|
|
||||||
- name: Forward all DNS requests to the local resolver
|
|
||||||
iptables:
|
|
||||||
table: nat
|
|
||||||
chain: PREROUTING
|
|
||||||
protocol: udp
|
|
||||||
destination_port: 53
|
|
||||||
source: "{{ vpn_network_ipv6 }}"
|
|
||||||
jump: DNAT
|
|
||||||
to_destination: fcaa::1:53
|
|
||||||
ip_version: ipv6
|
|
||||||
notify:
|
|
||||||
- save iptables
|
|
||||||
when: service_dns is defined and service_dns == "True"
|
|
||||||
|
|
||||||
- name: Dnsmasq enabled and started
|
|
||||||
service: name=dnsmasq state=started enabled=yes
|
|
||||||
when: service_dns is defined and service_dns == "True"
|
|
||||||
|
|
||||||
- name: Dnsmasq disabled and stopped
|
|
||||||
service: name=dnsmasq state=stopped enabled=no
|
|
||||||
when: service_dns is defined and service_dns == "False"
|
|
||||||
|
|
||||||
handlers:
|
|
||||||
- name: restart privoxy
|
|
||||||
service: name=privoxy state=restarted
|
|
||||||
|
|
||||||
- name: restart dnsmasq
|
|
||||||
service: name=dnsmasq state=restarted
|
|
||||||
|
|
||||||
- name: restart apparmor
|
|
||||||
service: name=apparmor state=restarted
|
|
||||||
|
|
||||||
- name: restart apache2
|
|
||||||
service: name=apache2 state=restarted
|
|
||||||
|
|
||||||
- name: save iptables
|
|
||||||
command: service netfilter-persistent save
|
|
|
@ -1,2 +1,4 @@
|
||||||
[user-management]
|
[user-management]
|
||||||
|
146.185.162.155
|
||||||
|
37.139.21.209
|
||||||
37.139.0.99
|
37.139.0.99
|
||||||
|
|
9
roles/common/handlers/main.yml
Normal file
9
roles/common/handlers/main.yml
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
- name: restart rsyslog
|
||||||
|
service: name=rsyslog state=restarted
|
||||||
|
|
||||||
|
- name: restart ssh
|
||||||
|
service: name=ssh state=restarted
|
||||||
|
|
||||||
|
- name: flush routing cache
|
||||||
|
shell: echo 1 > /proc/sys/net/ipv4/route/flush
|
||||||
|
|
70
roles/common/tasks/main.yml
Normal file
70
roles/common/tasks/main.yml
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
- name: Gather Facts
|
||||||
|
setup:
|
||||||
|
|
||||||
|
- name: Install software updates
|
||||||
|
apt: update_cache=yes upgrade=dist
|
||||||
|
|
||||||
|
- name: Check if reboot is required
|
||||||
|
shell: >
|
||||||
|
if [[ $(readlink -f /vmlinuz) != /boot/vmlinuz-$(uname -r) ]]; then echo "required"; else echo "no"; fi
|
||||||
|
args:
|
||||||
|
executable: /bin/bash
|
||||||
|
register: reboot_required
|
||||||
|
|
||||||
|
- name: Reboot
|
||||||
|
shell: sleep 2 && shutdown -r now "Ansible updates triggered"
|
||||||
|
async: 1
|
||||||
|
poll: 0
|
||||||
|
when: reboot_required is defined and reboot_required.stdout == 'required'
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: Wait for shutdown
|
||||||
|
local_action: wait_for host={{ inventory_hostname }} port=22 state=stopped timeout=120
|
||||||
|
when: reboot_required is defined and reboot_required.stdout == 'required'
|
||||||
|
become: false
|
||||||
|
|
||||||
|
- name: Wait until SSH becomes ready...
|
||||||
|
local_action: wait_for host={{ inventory_hostname }} port=22 state=started timeout=120
|
||||||
|
when: reboot_required is defined and reboot_required.stdout == 'required'
|
||||||
|
become: false
|
||||||
|
|
||||||
|
# SSH fixes
|
||||||
|
|
||||||
|
- name: SSH config
|
||||||
|
lineinfile: dest="{{ item.file }}" regexp="{{ item.regexp }}" line="{{ item.line }}" state=present
|
||||||
|
with_items:
|
||||||
|
- { regexp: '^PasswordAuthentication.*', line: 'PasswordAuthentication no', file: '/etc/ssh/sshd_config' }
|
||||||
|
- { regexp: '^PermitRootLogin.*', line: 'PermitRootLogin without-password', file: '/etc/ssh/sshd_config' }
|
||||||
|
- { regexp: '^UseDNS.*', line: 'UseDNS no', file: '/etc/ssh/sshd_config' }
|
||||||
|
- { regexp: '^Ciphers', line: 'Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com', file: '/etc/ssh/sshd_config' }
|
||||||
|
- { regexp: '^MACs', line: 'MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com', file: '/etc/ssh/sshd_config' }
|
||||||
|
- { regexp: '^KexAlgorithms', line: 'KexAlgorithms curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384', file: '/etc/ssh/sshd_config' }
|
||||||
|
notify:
|
||||||
|
- restart ssh
|
||||||
|
|
||||||
|
- name: Disable MOTD on login and SSHD
|
||||||
|
replace: dest="{{ item.file }}" regexp="{{ item.regexp }}" replace="{{ item.line }}"
|
||||||
|
with_items:
|
||||||
|
- { regexp: '^session.*optional.*pam_motd.so.*', line: '# MOTD DISABLED', file: '/etc/pam.d/login' }
|
||||||
|
- { regexp: '^session.*optional.*pam_motd.so.*', line: '# MOTD DISABLED', file: '/etc/pam.d/sshd' }
|
||||||
|
|
||||||
|
- name: Install tools
|
||||||
|
apt: name="{{ item }}" state=latest
|
||||||
|
with_items:
|
||||||
|
- git
|
||||||
|
- screen
|
||||||
|
- apparmor-utils
|
||||||
|
- uuid-runtime
|
||||||
|
- coreutils
|
||||||
|
- rsyslog
|
||||||
|
- sendmail
|
||||||
|
- unattended-upgrades
|
||||||
|
- iptables-persistent
|
||||||
|
|
||||||
|
- name: Configure unattended-upgrades
|
||||||
|
template: src=50unattended-upgrades.j2 dest=/etc/apt/apt.conf.d/50unattended-upgrades owner=root group=root mode=644
|
||||||
|
|
||||||
|
- name: Periodic upgrades configured
|
||||||
|
template: src=10periodic.j2 dest=/etc/apt/apt.conf.d/10periodic owner=root group=root mode=644
|
0
roles/digitalocean/handlers/main.yml
Normal file
0
roles/digitalocean/handlers/main.yml
Normal file
39
roles/digitalocean/tasks/main.yml
Normal file
39
roles/digitalocean/tasks/main.yml
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
- name: Set the DigitalOcean Access Token fact
|
||||||
|
set_fact:
|
||||||
|
do_token: "{{ do_access_token | default( lookup('env', 'DIGITALOCEAN_API_KEY') ) }}"
|
||||||
|
|
||||||
|
- name: "Getting your SSH key ID on Digital Ocean..."
|
||||||
|
digital_ocean:
|
||||||
|
state: present
|
||||||
|
command: ssh
|
||||||
|
name: "{{ do_ssh_name }}"
|
||||||
|
api_token: "{{ do_access_token }}"
|
||||||
|
register: do_ssh_key
|
||||||
|
|
||||||
|
- name: "Creating a droplet..."
|
||||||
|
digital_ocean:
|
||||||
|
state: present
|
||||||
|
command: droplet
|
||||||
|
name: "{{ do_server_name }}"
|
||||||
|
region_id: "{{ regions[do_region] }}"
|
||||||
|
size_id: "512mb"
|
||||||
|
image_id: "ubuntu-16-04-x64"
|
||||||
|
ssh_key_ids: "{{ do_ssh_key.ssh_key.id }}"
|
||||||
|
unique_name: yes
|
||||||
|
api_token: "{{ do_access_token }}"
|
||||||
|
register: do
|
||||||
|
|
||||||
|
- name: Add the droplet to an inventory group
|
||||||
|
add_host:
|
||||||
|
name: "{{ do.droplet.ip_address }}"
|
||||||
|
groups: vpn-host
|
||||||
|
ansible_ssh_user: root
|
||||||
|
ansible_python_interpreter: "/usr/bin/python2.7"
|
||||||
|
do_access_token: "{{ do_access_token }}"
|
||||||
|
do_droplet_id: "{{ do.droplet.id }}"
|
||||||
|
dns_enabled: "{{ dns_enabled }}"
|
||||||
|
auditd_enabled: " {{ auditd_enabled }}"
|
||||||
|
|
||||||
|
- name: Wait for SSH to become available
|
||||||
|
local_action: "wait_for port=22 host={{ do.droplet.ip_address }} timeout=320"
|
||||||
|
|
17
roles/features/handlers/main.yml
Normal file
17
roles/features/handlers/main.yml
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
- name: restart privoxy
|
||||||
|
service: name=privoxy state=restarted
|
||||||
|
|
||||||
|
- name: restart dnsmasq
|
||||||
|
service: name=dnsmasq state=restarted
|
||||||
|
|
||||||
|
- name: restart apparmor
|
||||||
|
service: name=apparmor state=restarted
|
||||||
|
|
||||||
|
- name: restart apache2
|
||||||
|
service: name=apache2 state=restarted
|
||||||
|
|
||||||
|
- name: save iptables
|
||||||
|
command: service netfilter-persistent save
|
||||||
|
|
||||||
|
- name: restart loopback
|
||||||
|
shell: ifdown lo:100 && ifup lo:100
|
141
roles/features/tasks/main.yml
Normal file
141
roles/features/tasks/main.yml
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
- name: Gather Facts
|
||||||
|
setup:
|
||||||
|
|
||||||
|
- name: Loopback for services configured
|
||||||
|
template: src=10-loopback-services.cfg.j2 dest=/etc/network/interfaces.d/10-loopback-services.cfg
|
||||||
|
notify:
|
||||||
|
- restart loopback
|
||||||
|
|
||||||
|
- name: Loopback included into the network config
|
||||||
|
lineinfile: dest=/etc/network/interfaces line='source /etc/network/interfaces.d/10-loopback-services.cfg' state=present
|
||||||
|
notify:
|
||||||
|
- restart loopback
|
||||||
|
|
||||||
|
- meta: flush_handlers
|
||||||
|
|
||||||
|
# Privoxy
|
||||||
|
|
||||||
|
- name: Privoxy installed
|
||||||
|
apt: name=privoxy state=latest
|
||||||
|
|
||||||
|
- name: Privoxy configured
|
||||||
|
template: src=privoxy_config.j2 dest=/etc/privoxy/config
|
||||||
|
notify:
|
||||||
|
- restart privoxy
|
||||||
|
|
||||||
|
- name: Privoxy profile for apparmor configured
|
||||||
|
template: src=usr.sbin.privoxy.j2 dest=/etc/apparmor.d/usr.sbin.privoxy owner=root group=root mode=600
|
||||||
|
notify:
|
||||||
|
- restart privoxy
|
||||||
|
|
||||||
|
- name: Enforce the privoxy AppArmor policy
|
||||||
|
shell: aa-enforce usr.sbin.privoxy
|
||||||
|
|
||||||
|
- name: Privoxy enabled and started
|
||||||
|
service: name=privoxy state=started enabled=yes
|
||||||
|
|
||||||
|
# PageSpeed
|
||||||
|
|
||||||
|
- name: Apache installed
|
||||||
|
apt: name=apache2 state=latest
|
||||||
|
|
||||||
|
- name: PageSpeed installed for x86_64
|
||||||
|
apt: deb=https://dl-ssl.google.com/dl/linux/direct/mod-pagespeed-stable_current_amd64.deb
|
||||||
|
when: ansible_architecture == "x86_64"
|
||||||
|
|
||||||
|
- name: PageSpeed installed for i386
|
||||||
|
apt: deb=https://dl-ssl.google.com/dl/linux/direct/mod-pagespeed-stable_current_i386.deb
|
||||||
|
when: ansible_architecture != "x86_64"
|
||||||
|
|
||||||
|
- name: PageSpeed configured
|
||||||
|
template: src=pagespeed.conf.j2 dest=/etc/apache2/mods-available/pagespeed.conf
|
||||||
|
notify:
|
||||||
|
- restart apache2
|
||||||
|
|
||||||
|
- name: Modules enabled
|
||||||
|
apache2_module: state=present name="{{ item }}"
|
||||||
|
with_items:
|
||||||
|
- proxy_http
|
||||||
|
- pagespeed
|
||||||
|
- cache
|
||||||
|
- proxy_connect
|
||||||
|
- proxy_html
|
||||||
|
- rewrite
|
||||||
|
notify:
|
||||||
|
- restart apache2
|
||||||
|
|
||||||
|
- name: VirtualHost configured for the PageSpeed module
|
||||||
|
template: src=000-default.conf.j2 dest=/etc/apache2/sites-enabled/000-default.conf
|
||||||
|
notify:
|
||||||
|
- restart apache2
|
||||||
|
|
||||||
|
- name: Apache ports configured
|
||||||
|
template: src=ports.conf.j2 dest=/etc/apache2/ports.conf
|
||||||
|
notify:
|
||||||
|
- restart apache2
|
||||||
|
|
||||||
|
# DNS
|
||||||
|
|
||||||
|
- name: Dnsmasq installed
|
||||||
|
apt: name=dnsmasq state=latest
|
||||||
|
|
||||||
|
- name: Dnsmasq profile for apparmor configured
|
||||||
|
template: src=usr.sbin.dnsmasq.j2 dest=/etc/apparmor.d/usr.sbin.dnsmasq owner=root group=root mode=600
|
||||||
|
notify:
|
||||||
|
- restart dnsmasq
|
||||||
|
|
||||||
|
- name: Enforce the dnsmasq AppArmor policy
|
||||||
|
shell: aa-enforce usr.sbin.dnsmasq
|
||||||
|
|
||||||
|
- name: Dnsmasq configured
|
||||||
|
template: src=dnsmasq.conf.j2 dest=/etc/dnsmasq.conf
|
||||||
|
notify:
|
||||||
|
- restart dnsmasq
|
||||||
|
|
||||||
|
- name: Adblock script created
|
||||||
|
copy: src=templates/adblock.sh dest=/opt/adblock.sh owner=root group=root mode=755
|
||||||
|
when: dns_enabled is defined and dns_enabled == "Y"
|
||||||
|
|
||||||
|
- name: Adblock script added to cron
|
||||||
|
cron: name="Adblock hosts update" minute="10" hour="2" job="/opt/adblock.sh"
|
||||||
|
when: dns_enabled is defined and dns_enabled == "Y"
|
||||||
|
|
||||||
|
- name: Update adblock hosts
|
||||||
|
shell: >
|
||||||
|
/opt/adblock.sh
|
||||||
|
when: dns_enabled is defined and dns_enabled == "Y"
|
||||||
|
|
||||||
|
- name: Forward all DNS requests to the local resolver
|
||||||
|
iptables:
|
||||||
|
table: nat
|
||||||
|
chain: PREROUTING
|
||||||
|
protocol: udp
|
||||||
|
destination_port: 53
|
||||||
|
source: "{{ vpn_network }}"
|
||||||
|
jump: DNAT
|
||||||
|
to_destination: 172.16.0.1:53
|
||||||
|
notify:
|
||||||
|
- save iptables
|
||||||
|
when: dns_enabled is defined and dns_enabled == "Y"
|
||||||
|
|
||||||
|
- name: Forward all DNS requests to the local resolver
|
||||||
|
iptables:
|
||||||
|
table: nat
|
||||||
|
chain: PREROUTING
|
||||||
|
protocol: udp
|
||||||
|
destination_port: 53
|
||||||
|
source: "{{ vpn_network_ipv6 }}"
|
||||||
|
jump: DNAT
|
||||||
|
to_destination: fcaa::1:53
|
||||||
|
ip_version: ipv6
|
||||||
|
notify:
|
||||||
|
- save iptables
|
||||||
|
when: dns_enabled is defined and dns_enabled == "Y"
|
||||||
|
|
||||||
|
- name: Dnsmasq enabled and started
|
||||||
|
service: name=dnsmasq state=started enabled=yes
|
||||||
|
when: dns_enabled is defined and dns_enabled == "Y"
|
||||||
|
|
||||||
|
- name: Dnsmasq disabled and stopped
|
||||||
|
service: name=dnsmasq state=stopped enabled=no
|
||||||
|
when: dns_enabled is defined and dns_enabled != "Y"
|
8
roles/security/handlers/main.yml
Normal file
8
roles/security/handlers/main.yml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
- name: restart auditd
|
||||||
|
service: name=auditd state=restarted
|
||||||
|
|
||||||
|
- name: restart rsyslog
|
||||||
|
service: name=rsyslog state=restarted
|
||||||
|
|
||||||
|
- name: flush routing cache
|
||||||
|
shell: echo 1 > /proc/sys/net/ipv4/route/flush
|
124
roles/security/tasks/main.yml
Normal file
124
roles/security/tasks/main.yml
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
|
||||||
|
|
||||||
|
# Using a two-pass approach for checking directories in order to support symlinks.
|
||||||
|
- name: Find directories for minimizing access
|
||||||
|
stat:
|
||||||
|
path: "{{ item }}"
|
||||||
|
register: minimize_access_directories
|
||||||
|
with_items:
|
||||||
|
- '/usr/local/sbin'
|
||||||
|
- '/usr/local/bin'
|
||||||
|
- '/usr/sbin'
|
||||||
|
- '/usr/bin'
|
||||||
|
- '/sbin'
|
||||||
|
- '/bin'
|
||||||
|
|
||||||
|
- name: Minimize access
|
||||||
|
file: path='{{ item.stat.path }}' mode='go-w' recurse=yes
|
||||||
|
when: item.stat.isdir
|
||||||
|
with_items: "{{ minimize_access_directories.results }}"
|
||||||
|
no_log: True
|
||||||
|
|
||||||
|
- name: Change shadow ownership to root and mode to 0600
|
||||||
|
file: dest='/etc/shadow' owner=root group=root mode=0600
|
||||||
|
|
||||||
|
- name: change su-binary to only be accessible to user and group root
|
||||||
|
file: dest='/bin/su' owner=root group=root mode=0750
|
||||||
|
|
||||||
|
- name: Collect Use of privileged commands
|
||||||
|
shell: >
|
||||||
|
/usr/bin/find {/usr/local/sbin,/usr/local/bin,/sbin,/bin,/usr/sbin,/usr/bin} -xdev \( -perm -4000 -o -perm -2000 \) -type f | awk '{print "-a always,exit -F path=" $1 " -F perm=x -F auid>=500 -F auid!=4294967295 -k privileged" }'
|
||||||
|
args:
|
||||||
|
executable: /bin/bash
|
||||||
|
register: privileged_programs
|
||||||
|
|
||||||
|
# auditd
|
||||||
|
|
||||||
|
- name: Auditd installed
|
||||||
|
apt: name=auditd state=latest
|
||||||
|
when: auditd_enabled is defined and auditd_enabled == 'Y'
|
||||||
|
|
||||||
|
- name: Auditd rules configured
|
||||||
|
template: src=audit.rules.j2 dest=/etc/audit/audit.rules
|
||||||
|
notify:
|
||||||
|
- restart auditd
|
||||||
|
when: auditd_enabled is defined and auditd_enabled == 'Y'
|
||||||
|
|
||||||
|
- name: Auditd configured
|
||||||
|
template: src=auditd.conf.j2 dest=/etc/audit/auditd.conf
|
||||||
|
notify:
|
||||||
|
- restart auditd
|
||||||
|
when: auditd_enabled is defined and auditd_enabled == 'Y'
|
||||||
|
|
||||||
|
- name: Enable services
|
||||||
|
service: name=auditd enabled=yes
|
||||||
|
when: auditd_enabled is defined and auditd_enabled == 'Y'
|
||||||
|
|
||||||
|
# Rsyslog
|
||||||
|
|
||||||
|
- name: Rsyslog configured
|
||||||
|
template: src=rsyslog.conf.j2 dest=/etc/rsyslog.conf
|
||||||
|
notify:
|
||||||
|
- restart rsyslog
|
||||||
|
|
||||||
|
- name: Rsyslog CIS configured
|
||||||
|
template: src=CIS.conf.j2 dest=/etc/rsyslog.d/CIS.conf owner=root group=root mode=0644
|
||||||
|
notify:
|
||||||
|
- restart rsyslog
|
||||||
|
|
||||||
|
- name: Enable services
|
||||||
|
service: name=rsyslog enabled=yes
|
||||||
|
|
||||||
|
# Core dumps
|
||||||
|
|
||||||
|
- name: Restrict core dumps (with PAM)
|
||||||
|
lineinfile: dest=/etc/security/limits.conf line="* hard core 0" state=present
|
||||||
|
|
||||||
|
- name: Restrict core dumps (with sysctl)
|
||||||
|
sysctl: name=fs.suid_dumpable value=0 ignoreerrors=yes sysctl_set=yes reload=yes state=present
|
||||||
|
|
||||||
|
# Kernel fixes
|
||||||
|
|
||||||
|
- name: Disable Source Routed Packet Acceptance
|
||||||
|
sysctl: name="{{item}}" value=0 ignoreerrors=yes sysctl_set=yes reload=yes state=present
|
||||||
|
with_items:
|
||||||
|
- net.ipv4.conf.all.accept_source_route
|
||||||
|
- net.ipv4.conf.default.accept_source_route
|
||||||
|
notify:
|
||||||
|
- flush routing cache
|
||||||
|
|
||||||
|
- name: Disable ICMP Redirect Acceptance
|
||||||
|
sysctl: name="{{item}}" value=0 ignoreerrors=yes sysctl_set=yes reload=yes state=present
|
||||||
|
with_items:
|
||||||
|
- net.ipv4.conf.all.accept_redirects
|
||||||
|
- net.ipv4.conf.default.accept_redirects
|
||||||
|
|
||||||
|
- name: Disable Secure ICMP Redirect Acceptance
|
||||||
|
sysctl: name="{{item}}" value=0 ignoreerrors=yes sysctl_set=yes reload=yes state=present
|
||||||
|
with_items:
|
||||||
|
- net.ipv4.conf.all.secure_redirects
|
||||||
|
- net.ipv4.conf.default.secure_redirects
|
||||||
|
notify:
|
||||||
|
- flush routing cache
|
||||||
|
|
||||||
|
- name: Enable Bad Error Message Protection
|
||||||
|
sysctl: name=net.ipv4.icmp_ignore_bogus_error_responses value=1 ignoreerrors=yes sysctl_set=yes reload=yes state=present
|
||||||
|
notify:
|
||||||
|
- flush routing cache
|
||||||
|
|
||||||
|
- name: Enable RFC-recommended Source Route Validation
|
||||||
|
sysctl: name="{{item}}" value=1 ignoreerrors=yes sysctl_set=yes reload=yes state=present
|
||||||
|
with_items:
|
||||||
|
- net.ipv4.conf.all.rp_filter
|
||||||
|
- net.ipv4.conf.default.rp_filter
|
||||||
|
notify:
|
||||||
|
- flush routing cache
|
||||||
|
|
||||||
|
- name: Enable packet forwarding for IPv4
|
||||||
|
sysctl: name=net.ipv4.ip_forward value=1
|
||||||
|
|
||||||
|
- name: Enable packet forwarding for IPv6
|
||||||
|
sysctl: name=net.ipv6.conf.all.forwarding value=1
|
||||||
|
|
||||||
|
- name: Do not send ICMP redirects (we are not a router)
|
||||||
|
sysctl: name=net.ipv4.conf.all.send_redirects value=0
|
20
roles/vpn/handlers/main.yml
Normal file
20
roles/vpn/handlers/main.yml
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
- name: restart strongswan
|
||||||
|
service: name=strongswan state=restarted
|
||||||
|
|
||||||
|
- name: restart apparmor
|
||||||
|
service: name=apparmor state=restarted
|
||||||
|
|
||||||
|
- name: save iptables
|
||||||
|
command: service netfilter-persistent save
|
||||||
|
|
||||||
|
- name: congrats
|
||||||
|
debug:
|
||||||
|
msg:
|
||||||
|
- "#----------------------------------------------------------------------#"
|
||||||
|
- "# Congratulations! #"
|
||||||
|
- "# Your Algo server is running. #"
|
||||||
|
- "# Config files and certificates are in the ./configs/ directory. #"
|
||||||
|
- "# Go to https://www.dnsleaktest.com/ after connecting #"
|
||||||
|
- "# and ensure that all your traffic passes through the VPN. #"
|
||||||
|
- "# Local DNS resolver and Proxy IP address: 172.16.0.1 #"
|
||||||
|
- "#----------------------------------------------------------------------#"
|
144
roles/vpn/tasks/main.yml
Normal file
144
roles/vpn/tasks/main.yml
Normal file
|
@ -0,0 +1,144 @@
|
||||||
|
- name: Install StrongSwan
|
||||||
|
apt: name=strongswan state=latest update_cache=yes
|
||||||
|
|
||||||
|
- name: Enforcing ipsec with apparmor
|
||||||
|
shell: aa-enforce "{{ item }}"
|
||||||
|
with_items:
|
||||||
|
- /usr/lib/ipsec/charon
|
||||||
|
- /usr/lib/ipsec/lookip
|
||||||
|
- /usr/lib/ipsec/stroke
|
||||||
|
notify:
|
||||||
|
- restart apparmor
|
||||||
|
|
||||||
|
- name: Enable services
|
||||||
|
service: name={{ item }} enabled=yes
|
||||||
|
with_items:
|
||||||
|
- apparmor
|
||||||
|
- strongswan
|
||||||
|
- netfilter-persistent
|
||||||
|
|
||||||
|
- name: Configure iptables so IPSec traffic can traverse the tunnel
|
||||||
|
iptables: table=nat chain=POSTROUTING source="{{ vpn_network }}" jump=MASQUERADE
|
||||||
|
notify:
|
||||||
|
- save iptables
|
||||||
|
|
||||||
|
- name: Configure ip6tables so IPSec traffic can traverse the tunnel
|
||||||
|
iptables: ip_version=ipv6 table=nat chain=POSTROUTING source="{{ vpn_network_ipv6 }}" jump=MASQUERADE
|
||||||
|
notify:
|
||||||
|
- save iptables
|
||||||
|
|
||||||
|
- name: Setup the ipsec.conf file from our template
|
||||||
|
template: src=ipsec.conf.j2 dest=/etc/ipsec.conf owner=root group=root mode=644
|
||||||
|
notify:
|
||||||
|
- restart strongswan
|
||||||
|
|
||||||
|
- name: Setup the ipsec.secrets file
|
||||||
|
template: src=ipsec.secrets.j2 dest=/etc/ipsec.secrets owner=root group=root mode=600
|
||||||
|
notify:
|
||||||
|
- restart strongswan
|
||||||
|
|
||||||
|
- name: Fetch easy-rsa-ipsec from git
|
||||||
|
git: repo=git://github.com/ValdikSS/easy-rsa-ipsec.git dest="{{ easyrsa_dir }}"
|
||||||
|
|
||||||
|
- name: Setup the vars file from our template
|
||||||
|
template: src=easy-rsa.vars.j2 dest={{ easyrsa_dir }}/easyrsa3/vars
|
||||||
|
|
||||||
|
- name: Ensure the pki directory is not exist
|
||||||
|
file: dest={{ easyrsa_dir }}/easyrsa3/pki state=absent
|
||||||
|
when: easyrsa_reinit_existent == True
|
||||||
|
|
||||||
|
- name: Build the pki enviroments
|
||||||
|
shell: >
|
||||||
|
./easyrsa init-pki &&
|
||||||
|
touch '{{ easyrsa_dir }}/easyrsa3/pki/pki_initialized'
|
||||||
|
args:
|
||||||
|
chdir: '{{ easyrsa_dir }}/easyrsa3/'
|
||||||
|
creates: '{{ easyrsa_dir }}/easyrsa3/pki/pki_initialized'
|
||||||
|
|
||||||
|
- name: Build the CA pair
|
||||||
|
shell: >
|
||||||
|
./easyrsa build-ca nopass &&
|
||||||
|
touch {{ easyrsa_dir }}/easyrsa3/pki/ca_initialized
|
||||||
|
args:
|
||||||
|
chdir: '{{ easyrsa_dir }}/easyrsa3/'
|
||||||
|
creates: '{{ easyrsa_dir }}/easyrsa3/pki/ca_initialized'
|
||||||
|
notify:
|
||||||
|
- restart strongswan
|
||||||
|
|
||||||
|
- name: Build the server pair
|
||||||
|
shell: >
|
||||||
|
./easyrsa --subject-alt-name='DNS:{{ server_name }},IP:{{ ansible_ssh_host }}' build-server-full {{ ansible_ssh_host }} nopass&&
|
||||||
|
touch '{{ easyrsa_dir }}/easyrsa3/pki/server_initialized'
|
||||||
|
args:
|
||||||
|
chdir: '{{ easyrsa_dir }}/easyrsa3/'
|
||||||
|
creates: '{{ easyrsa_dir }}/easyrsa3/pki/server_initialized'
|
||||||
|
notify:
|
||||||
|
- restart strongswan
|
||||||
|
|
||||||
|
- name: Build the client's pair
|
||||||
|
shell: >
|
||||||
|
./easyrsa build-client-full {{ item }} nopass &&
|
||||||
|
touch '{{ easyrsa_dir }}/easyrsa3/pki/{{ item }}_initialized'
|
||||||
|
args:
|
||||||
|
chdir: '{{ easyrsa_dir }}/easyrsa3/'
|
||||||
|
creates: '{{ easyrsa_dir }}/easyrsa3/pki/{{ item }}_initialized'
|
||||||
|
with_items: "{{ users }}"
|
||||||
|
|
||||||
|
- name: Build the client's p12
|
||||||
|
shell: >
|
||||||
|
openssl pkcs12 -in {{ easyrsa_dir }}/easyrsa3//pki/issued/{{ item }}.crt -inkey {{ easyrsa_dir }}/easyrsa3//pki/private/{{ item }}.key -export -name {{ item }} -out /{{ easyrsa_dir }}/easyrsa3//pki/private/{{ item }}.p12 -certfile {{ easyrsa_dir }}/easyrsa3//pki/ca.crt -passout pass:{{ easyrsa_p12_export_password }} &&
|
||||||
|
touch '{{ easyrsa_dir }}/easyrsa3/pki/{{ item }}_p12_initialized'
|
||||||
|
args:
|
||||||
|
chdir: '{{ easyrsa_dir }}/easyrsa3/'
|
||||||
|
creates: '{{ easyrsa_dir }}/easyrsa3/pki/{{ item }}_p12_initialized'
|
||||||
|
with_items: "{{ users }}"
|
||||||
|
|
||||||
|
- name: Copy the CA cert to the strongswan directory
|
||||||
|
copy: remote_src=True src='{{ easyrsa_dir }}/easyrsa3/pki/ca.crt' dest=/etc/ipsec.d/cacerts/ca.crt owner=root group=root mode=0600
|
||||||
|
notify:
|
||||||
|
- restart strongswan
|
||||||
|
|
||||||
|
- name: Copy the server cert to the strongswan directory
|
||||||
|
copy: remote_src=True src='{{ easyrsa_dir }}/easyrsa3/pki/issued/{{ ansible_ssh_host }}.crt' dest=/etc/ipsec.d/certs/{{ ansible_ssh_host }}.crt owner=root group=root mode=0600
|
||||||
|
notify:
|
||||||
|
- restart strongswan
|
||||||
|
|
||||||
|
- name: Copy the server key to the strongswan directory
|
||||||
|
copy: remote_src=True src='{{ easyrsa_dir }}/easyrsa3/pki/private/{{ ansible_ssh_host }}.key' dest=/etc/ipsec.d/private/{{ ansible_ssh_host }}.key owner=root group=root mode=0600
|
||||||
|
notify:
|
||||||
|
- restart strongswan
|
||||||
|
|
||||||
|
- name: Register p12 PayloadContent
|
||||||
|
shell: >
|
||||||
|
cat /{{ easyrsa_dir }}/easyrsa3//pki/private/{{ item }}.p12 | base64
|
||||||
|
register: PayloadContent
|
||||||
|
with_items: "{{ users }}"
|
||||||
|
|
||||||
|
- name: Register CA PayloadContent
|
||||||
|
shell: >
|
||||||
|
cat /{{ easyrsa_dir }}/easyrsa3/pki/ca.crt | base64
|
||||||
|
register: PayloadContentCA
|
||||||
|
|
||||||
|
- name: Build the mobileconfigs
|
||||||
|
template: src=mobileconfig.j2 dest=/{{ easyrsa_dir }}/easyrsa3//pki/private/{{ item.0 }}.mobileconfig mode=0600
|
||||||
|
with_together:
|
||||||
|
- "{{ users }}"
|
||||||
|
- "{{ PayloadContent.results }}"
|
||||||
|
no_log: True
|
||||||
|
|
||||||
|
- name: Fetch users P12
|
||||||
|
fetch: src=/{{ easyrsa_dir }}/easyrsa3//pki/private/{{ item }}.p12 dest=configs/{{ server_name }}_{{ item }}.p12 flat=yes
|
||||||
|
with_items: "{{ users }}"
|
||||||
|
|
||||||
|
- name: Fetch users mobileconfig
|
||||||
|
fetch: src=/{{ easyrsa_dir }}/easyrsa3//pki/private/{{ item }}.mobileconfig dest=configs/{{ server_name }}_{{ item }}.mobileconfig flat=yes
|
||||||
|
with_items: "{{ users }}"
|
||||||
|
|
||||||
|
- name: Fetch server CA certificate
|
||||||
|
fetch: src=/{{ easyrsa_dir }}/easyrsa3/pki/ca.crt dest=configs/{{ server_name }}_ca.crt flat=yes
|
||||||
|
|
||||||
|
- name: Add server to the inventory file
|
||||||
|
local_action: lineinfile dest=inventory_users line="{{ inventory_hostname }}" insertafter='\[user-management\]\n' state=present
|
||||||
|
become: false
|
||||||
|
notify:
|
||||||
|
- congrats
|
136
security.yml
136
security.yml
|
@ -1,136 +0,0 @@
|
||||||
---
|
|
||||||
|
|
||||||
- name: Security enhancements
|
|
||||||
hosts: vpn-host
|
|
||||||
become: true
|
|
||||||
vars_files:
|
|
||||||
- config.cfg
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
# Using a two-pass approach for checking directories in order to support symlinks.
|
|
||||||
- name: Find directories for minimizing access
|
|
||||||
stat:
|
|
||||||
path: "{{ item }}"
|
|
||||||
register: minimize_access_directories
|
|
||||||
with_items:
|
|
||||||
- '/usr/local/sbin'
|
|
||||||
- '/usr/local/bin'
|
|
||||||
- '/usr/sbin'
|
|
||||||
- '/usr/bin'
|
|
||||||
- '/sbin'
|
|
||||||
- '/bin'
|
|
||||||
|
|
||||||
- name: Minimize access
|
|
||||||
file: path='{{ item.stat.path }}' mode='go-w' recurse=yes
|
|
||||||
when: item.stat.isdir
|
|
||||||
with_items: "{{ minimize_access_directories.results }}"
|
|
||||||
no_log: True
|
|
||||||
|
|
||||||
- name: Change shadow ownership to root and mode to 0600
|
|
||||||
file: dest='/etc/shadow' owner=root group=root mode=0600
|
|
||||||
|
|
||||||
- name: change su-binary to only be accessible to user and group root
|
|
||||||
file: dest='/bin/su' owner=root group=root mode=0750
|
|
||||||
|
|
||||||
# auditd
|
|
||||||
|
|
||||||
- name: Collect Use of privileged commands
|
|
||||||
shell: >
|
|
||||||
/usr/bin/find {/usr/local/sbin,/usr/local/bin,/sbin,/bin,/usr/sbin,/usr/bin} -xdev \( -perm -4000 -o -perm -2000 \) -type f | awk '{print "-a always,exit -F path=" $1 " -F perm=x -F auid>=500 -F auid!=4294967295 -k privileged" }'
|
|
||||||
args:
|
|
||||||
executable: /bin/bash
|
|
||||||
register: privileged_programs
|
|
||||||
|
|
||||||
- name: Auditd rules configured
|
|
||||||
template: src=audit.rules.j2 dest=/etc/audit/audit.rules
|
|
||||||
notify:
|
|
||||||
- restart auditd
|
|
||||||
|
|
||||||
- name: Auditd configured
|
|
||||||
template: src=auditd.conf.j2 dest=/etc/audit/auditd.conf
|
|
||||||
notify:
|
|
||||||
- restart auditd
|
|
||||||
|
|
||||||
# Rsyslog
|
|
||||||
|
|
||||||
- name: Rsyslog configured
|
|
||||||
template: src=rsyslog.conf.j2 dest=/etc/rsyslog.conf
|
|
||||||
notify:
|
|
||||||
- restart rsyslog
|
|
||||||
|
|
||||||
- name: Rsyslog CIS configured
|
|
||||||
template: src=CIS.conf.j2 dest=/etc/rsyslog.d/CIS.conf owner=root group=root mode=0644
|
|
||||||
notify:
|
|
||||||
- restart rsyslog
|
|
||||||
|
|
||||||
- name: Enable services
|
|
||||||
service: name={{ item }} enabled=yes
|
|
||||||
with_items:
|
|
||||||
- auditd
|
|
||||||
- rsyslog
|
|
||||||
|
|
||||||
# Core dumps
|
|
||||||
|
|
||||||
- name: Restrict core dumps (with PAM)
|
|
||||||
lineinfile: dest=/etc/security/limits.conf line="* hard core 0" state=present
|
|
||||||
|
|
||||||
- name: Restrict core dumps (with sysctl)
|
|
||||||
sysctl: name=fs.suid_dumpable value=0 ignoreerrors=yes sysctl_set=yes reload=yes state=present
|
|
||||||
|
|
||||||
# Kernel fixes
|
|
||||||
|
|
||||||
- name: Disable Source Routed Packet Acceptance
|
|
||||||
sysctl: name="{{item}}" value=0 ignoreerrors=yes sysctl_set=yes reload=yes state=present
|
|
||||||
with_items:
|
|
||||||
- net.ipv4.conf.all.accept_source_route
|
|
||||||
- net.ipv4.conf.default.accept_source_route
|
|
||||||
notify:
|
|
||||||
- flush routing cache
|
|
||||||
|
|
||||||
- name: Disable ICMP Redirect Acceptance
|
|
||||||
sysctl: name="{{item}}" value=0 ignoreerrors=yes sysctl_set=yes reload=yes state=present
|
|
||||||
with_items:
|
|
||||||
- net.ipv4.conf.all.accept_redirects
|
|
||||||
- net.ipv4.conf.default.accept_redirects
|
|
||||||
|
|
||||||
- name: Disable Secure ICMP Redirect Acceptance
|
|
||||||
sysctl: name="{{item}}" value=0 ignoreerrors=yes sysctl_set=yes reload=yes state=present
|
|
||||||
with_items:
|
|
||||||
- net.ipv4.conf.all.secure_redirects
|
|
||||||
- net.ipv4.conf.default.secure_redirects
|
|
||||||
notify:
|
|
||||||
- flush routing cache
|
|
||||||
|
|
||||||
- name: Enable Bad Error Message Protection
|
|
||||||
sysctl: name=net.ipv4.icmp_ignore_bogus_error_responses value=1 ignoreerrors=yes sysctl_set=yes reload=yes state=present
|
|
||||||
notify:
|
|
||||||
- flush routing cache
|
|
||||||
|
|
||||||
- name: Enable RFC-recommended Source Route Validation
|
|
||||||
sysctl: name="{{item}}" value=1 ignoreerrors=yes sysctl_set=yes reload=yes state=present
|
|
||||||
with_items:
|
|
||||||
- net.ipv4.conf.all.rp_filter
|
|
||||||
- net.ipv4.conf.default.rp_filter
|
|
||||||
notify:
|
|
||||||
- flush routing cache
|
|
||||||
|
|
||||||
- name: Enable packet forwarding for IPv4
|
|
||||||
sysctl: name=net.ipv4.ip_forward value=1
|
|
||||||
|
|
||||||
- name: Enable packet forwarding for IPv6
|
|
||||||
sysctl: name=net.ipv6.conf.all.forwarding value=1
|
|
||||||
|
|
||||||
- name: Do not send ICMP redirects (we are not a router)
|
|
||||||
sysctl: name=net.ipv4.conf.all.send_redirects value=0
|
|
||||||
|
|
||||||
handlers:
|
|
||||||
- name: restart auditd
|
|
||||||
service: name=auditd state=restarted
|
|
||||||
|
|
||||||
- name: restart rsyslog
|
|
||||||
service: name=rsyslog state=restarted
|
|
||||||
|
|
||||||
- name: flush routing cache
|
|
||||||
shell: echo 1 > /proc/sys/net/ipv4/route/flush
|
|
||||||
|
|
||||||
|
|
175
vpn.yml
175
vpn.yml
|
@ -1,175 +0,0 @@
|
||||||
---
|
|
||||||
|
|
||||||
- name: VPN Configuration
|
|
||||||
hosts: vpn-host
|
|
||||||
gather_facts: false
|
|
||||||
become: true
|
|
||||||
vars_files:
|
|
||||||
- config.cfg
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Install StrongSwan
|
|
||||||
apt: name=strongswan state=latest update_cache=yes
|
|
||||||
|
|
||||||
- name: Enforcing ipsec with apparmor
|
|
||||||
shell: aa-enforce "{{ item }}"
|
|
||||||
with_items:
|
|
||||||
- /usr/lib/ipsec/charon
|
|
||||||
- /usr/lib/ipsec/lookip
|
|
||||||
- /usr/lib/ipsec/stroke
|
|
||||||
notify:
|
|
||||||
- restart apparmor
|
|
||||||
|
|
||||||
- name: Enable services
|
|
||||||
service: name={{ item }} enabled=yes
|
|
||||||
with_items:
|
|
||||||
- apparmor
|
|
||||||
- strongswan
|
|
||||||
- netfilter-persistent
|
|
||||||
|
|
||||||
- name: Configure iptables so IPSec traffic can traverse the tunnel
|
|
||||||
iptables: table=nat chain=POSTROUTING source="{{ vpn_network }}" jump=MASQUERADE
|
|
||||||
notify:
|
|
||||||
- save iptables
|
|
||||||
|
|
||||||
- name: Configure ip6tables so IPSec traffic can traverse the tunnel
|
|
||||||
iptables: ip_version=ipv6 table=nat chain=POSTROUTING source="{{ vpn_network_ipv6 }}" jump=MASQUERADE
|
|
||||||
notify:
|
|
||||||
- save iptables
|
|
||||||
|
|
||||||
- name: Setup the ipsec.conf file from our template
|
|
||||||
template: src=ipsec.conf.j2 dest=/etc/ipsec.conf owner=root group=root mode=644
|
|
||||||
notify:
|
|
||||||
- restart strongswan
|
|
||||||
|
|
||||||
- name: Setup the ipsec.secrets file
|
|
||||||
template: src=ipsec.secrets.j2 dest=/etc/ipsec.secrets owner=root group=root mode=600
|
|
||||||
notify:
|
|
||||||
- restart strongswan
|
|
||||||
|
|
||||||
- name: Fetch easy-rsa-ipsec from git
|
|
||||||
git: repo=git://github.com/ValdikSS/easy-rsa-ipsec.git dest="{{ easyrsa_dir }}"
|
|
||||||
|
|
||||||
- name: Setup the vars file from our template
|
|
||||||
template: src=easy-rsa.vars.j2 dest={{ easyrsa_dir }}/easyrsa3/vars
|
|
||||||
|
|
||||||
- name: Ensure the pki directory is not exist
|
|
||||||
file: dest={{ easyrsa_dir }}/easyrsa3/pki state=absent
|
|
||||||
when: easyrsa_reinit_existent == True
|
|
||||||
|
|
||||||
- name: Build the pki enviroments
|
|
||||||
shell: >
|
|
||||||
./easyrsa init-pki &&
|
|
||||||
touch '{{ easyrsa_dir }}/easyrsa3/pki/pki_initialized'
|
|
||||||
args:
|
|
||||||
chdir: '{{ easyrsa_dir }}/easyrsa3/'
|
|
||||||
creates: '{{ easyrsa_dir }}/easyrsa3/pki/pki_initialized'
|
|
||||||
|
|
||||||
- name: Build the CA pair
|
|
||||||
shell: >
|
|
||||||
./easyrsa build-ca nopass &&
|
|
||||||
touch {{ easyrsa_dir }}/easyrsa3/pki/ca_initialized
|
|
||||||
args:
|
|
||||||
chdir: '{{ easyrsa_dir }}/easyrsa3/'
|
|
||||||
creates: '{{ easyrsa_dir }}/easyrsa3/pki/ca_initialized'
|
|
||||||
notify:
|
|
||||||
- restart strongswan
|
|
||||||
|
|
||||||
- name: Build the server pair
|
|
||||||
shell: >
|
|
||||||
./easyrsa --subject-alt-name='DNS:{{ server_name }},IP:{{ ansible_ssh_host }}' build-server-full {{ ansible_ssh_host }} nopass&&
|
|
||||||
touch '{{ easyrsa_dir }}/easyrsa3/pki/server_initialized'
|
|
||||||
args:
|
|
||||||
chdir: '{{ easyrsa_dir }}/easyrsa3/'
|
|
||||||
creates: '{{ easyrsa_dir }}/easyrsa3/pki/server_initialized'
|
|
||||||
notify:
|
|
||||||
- restart strongswan
|
|
||||||
|
|
||||||
- name: Build the client's pair
|
|
||||||
shell: >
|
|
||||||
./easyrsa build-client-full {{ item }} nopass &&
|
|
||||||
touch '{{ easyrsa_dir }}/easyrsa3/pki/{{ item }}_initialized'
|
|
||||||
args:
|
|
||||||
chdir: '{{ easyrsa_dir }}/easyrsa3/'
|
|
||||||
creates: '{{ easyrsa_dir }}/easyrsa3/pki/{{ item }}_initialized'
|
|
||||||
with_items: "{{ users }}"
|
|
||||||
|
|
||||||
- name: Build the client's p12
|
|
||||||
shell: >
|
|
||||||
openssl pkcs12 -in {{ easyrsa_dir }}/easyrsa3//pki/issued/{{ item }}.crt -inkey {{ easyrsa_dir }}/easyrsa3//pki/private/{{ item }}.key -export -name {{ item }} -out /{{ easyrsa_dir }}/easyrsa3//pki/private/{{ item }}.p12 -certfile {{ easyrsa_dir }}/easyrsa3//pki/ca.crt -passout pass:{{ easyrsa_p12_export_password }} &&
|
|
||||||
touch '{{ easyrsa_dir }}/easyrsa3/pki/{{ item }}_p12_initialized'
|
|
||||||
args:
|
|
||||||
chdir: '{{ easyrsa_dir }}/easyrsa3/'
|
|
||||||
creates: '{{ easyrsa_dir }}/easyrsa3/pki/{{ item }}_p12_initialized'
|
|
||||||
with_items: "{{ users }}"
|
|
||||||
|
|
||||||
- name: Copy the CA cert to the strongswan directory
|
|
||||||
copy: remote_src=True src='{{ easyrsa_dir }}/easyrsa3/pki/ca.crt' dest=/etc/ipsec.d/cacerts/ca.crt owner=root group=root mode=0600
|
|
||||||
notify:
|
|
||||||
- restart strongswan
|
|
||||||
|
|
||||||
- name: Copy the server cert to the strongswan directory
|
|
||||||
copy: remote_src=True src='{{ easyrsa_dir }}/easyrsa3/pki/issued/{{ ansible_ssh_host }}.crt' dest=/etc/ipsec.d/certs/{{ ansible_ssh_host }}.crt owner=root group=root mode=0600
|
|
||||||
notify:
|
|
||||||
- restart strongswan
|
|
||||||
|
|
||||||
- name: Copy the server key to the strongswan directory
|
|
||||||
copy: remote_src=True src='{{ easyrsa_dir }}/easyrsa3/pki/private/{{ ansible_ssh_host }}.key' dest=/etc/ipsec.d/private/{{ ansible_ssh_host }}.key owner=root group=root mode=0600
|
|
||||||
notify:
|
|
||||||
- restart strongswan
|
|
||||||
|
|
||||||
- name: Register p12 PayloadContent
|
|
||||||
shell: >
|
|
||||||
cat /{{ easyrsa_dir }}/easyrsa3//pki/private/{{ item }}.p12 | base64
|
|
||||||
register: PayloadContent
|
|
||||||
with_items: "{{ users }}"
|
|
||||||
|
|
||||||
- name: Register CA PayloadContent
|
|
||||||
shell: >
|
|
||||||
cat /{{ easyrsa_dir }}/easyrsa3/pki/ca.crt | base64
|
|
||||||
register: PayloadContentCA
|
|
||||||
|
|
||||||
- name: Build the mobileconfigs
|
|
||||||
template: src=mobileconfig.j2 dest=/{{ easyrsa_dir }}/easyrsa3//pki/private/{{ item.0 }}.mobileconfig mode=0600
|
|
||||||
with_together:
|
|
||||||
- "{{ users }}"
|
|
||||||
- "{{ PayloadContent.results }}"
|
|
||||||
no_log: True
|
|
||||||
|
|
||||||
- name: Fetch users P12
|
|
||||||
fetch: src=/{{ easyrsa_dir }}/easyrsa3//pki/private/{{ item }}.p12 dest=configs/{{ server_name }}_{{ item }}.p12 flat=yes
|
|
||||||
with_items: "{{ users }}"
|
|
||||||
|
|
||||||
- name: Fetch users mobileconfig
|
|
||||||
fetch: src=/{{ easyrsa_dir }}/easyrsa3//pki/private/{{ item }}.mobileconfig dest=configs/{{ server_name }}_{{ item }}.mobileconfig flat=yes
|
|
||||||
with_items: "{{ users }}"
|
|
||||||
|
|
||||||
- name: Fetch server CA certificate
|
|
||||||
fetch: src=/{{ easyrsa_dir }}/easyrsa3/pki/ca.crt dest=configs/{{ server_name }}_ca.crt flat=yes
|
|
||||||
|
|
||||||
- name: Add server to the inventory file
|
|
||||||
local_action: lineinfile dest=inventory_users line="{{ inventory_hostname }}" insertafter='\[user-management\]\n' state=present
|
|
||||||
become: false
|
|
||||||
notify:
|
|
||||||
- congrats
|
|
||||||
|
|
||||||
handlers:
|
|
||||||
- name: restart strongswan
|
|
||||||
service: name=strongswan state=restarted
|
|
||||||
|
|
||||||
- name: restart apparmor
|
|
||||||
service: name=apparmor state=restarted
|
|
||||||
|
|
||||||
- name: save iptables
|
|
||||||
command: service netfilter-persistent save
|
|
||||||
|
|
||||||
- name: congrats
|
|
||||||
debug:
|
|
||||||
msg:
|
|
||||||
- "#----------------------------------------------------------------------#"
|
|
||||||
- "# Congratulations! #"
|
|
||||||
- "# Your Algo server is running. #"
|
|
||||||
- "# Config files and certificates are in the ./configs/ directory. #"
|
|
||||||
- "# Go to https://www.dnsleaktest.com/ after connecting #"
|
|
||||||
- "# and ensure that all your traffic passes through the VPN. #"
|
|
||||||
- "#----------------------------------------------------------------------#"
|
|
Loading…
Add table
Reference in a new issue