diff --git a/playbooks/vpn-ipsec.yml b/playbooks/vpn-ipsec.yml new file mode 100644 index 0000000..aa9b29a --- /dev/null +++ b/playbooks/vpn-ipsec.yml @@ -0,0 +1,6 @@ +- name: Configure IPsec StrongSwan + hosts: all + tasks: + - name: Configure services to install in the server + import_role: + name: ipsec \ No newline at end of file diff --git a/roles/ipsec/defaults/main.yml b/roles/ipsec/defaults/main.yml new file mode 100644 index 0000000..c8b1cd0 --- /dev/null +++ b/roles/ipsec/defaults/main.yml @@ -0,0 +1,29 @@ +strongswan_requeriments: + - strongswan + - libstrongswan-standard-plugins + - strongswan-pki + - tcpdump + - iperf + - conntrack + - iptables-persistent +certificates: + - { content: '{{ cert_ipsec }}', dest: '/etc/ipsec.d/certs/cert.pem', mode: 'u=rw,g=r,o=r' } + - { content: '{{ ca }}', dest: '/etc/ipsec.d/cacerts/ca.pem', mode: 'u=rw,g=r,o=r' } +config_ipsec_files: + - { src: 'ipsec.conf', dest: '/etc/ipsec.conf', mode: 'u=rw,g=r,o=r' } + - { src: 'vn-attr.conf', dest: '/etc/strongswan.d/charon/vn-attr.conf', mode: 'u=rw,g=r,o=r' } + - { src: 'vn-eap-radius.conf', dest: '/etc/strongswan.d/charon/vn-eap-radius.conf', mode: 'u=r,g=,o=' } + - { src: 'ipsec.secrets', dest: '/etc/ipsec.secrets', mode: 'u=r,g=,o=' } +mangle_block: | + *mangle + :PREROUTING ACCEPT [0:0] + :INPUT ACCEPT [0:0] + :FORWARD ACCEPT [0:0] + :OUTPUT ACCEPT [0:0] + :POSTROUTING ACCEPT [0:0] + -A PREROUTING -p tcp -m policy --dir in --pol ipsec -m tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1361:1536 -j TCPMSS --set-mss 1360 + -A POSTROUTING -p tcp -m policy --dir out --pol ipsec -m tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1361:1536 -j TCPMSS --set-mss 1360 + COMMIT +config_and_logrotate: + - { src: vn.conf, dest: '/etc/strongswan.d/vn.conf' } + - { src: charon, dest: '/etc/logrotate.d/charon' } diff --git a/roles/ipsec/files/charon b/roles/ipsec/files/charon new file mode 100644 index 0000000..9a05de0 --- /dev/null +++ b/roles/ipsec/files/charon @@ -0,0 +1,11 @@ +/var/log/strongswan/charon.log +{ + copytruncate + create 644 root root + rotate 10 + weekly + missingok + notifempty + compress + delaycompress +} diff --git a/roles/ipsec/files/vn.conf b/roles/ipsec/files/vn.conf new file mode 100644 index 0000000..0b26373 --- /dev/null +++ b/roles/ipsec/files/vn.conf @@ -0,0 +1,19 @@ +charon { + cisco_unity = yes + + filelog { + log { + path = /var/log/strongswan/charon.log + append = yes + default = 1 + flush_line = yes + ike_name = yes + time_format = %Y-%m-%d %H:%M:%S + } + } + syslog { + identifier = charon + daemon { + } + } +} diff --git a/roles/ipsec/handlers/main.yml b/roles/ipsec/handlers/main.yml new file mode 100644 index 0000000..79978af --- /dev/null +++ b/roles/ipsec/handlers/main.yml @@ -0,0 +1,4 @@ +- name: restart-ipsec + systemd: + name: strongswan-starter.service + state: restarted diff --git a/roles/ipsec/tasks/ipsec.yml b/roles/ipsec/tasks/ipsec.yml new file mode 100644 index 0000000..37f63ce --- /dev/null +++ b/roles/ipsec/tasks/ipsec.yml @@ -0,0 +1,85 @@ +- name: Update apt cache + apt: + update_cache: yes +- name: Install VPN package requirements + apt: + name: "{{ strongswan_requeriments }}" + state: present + install_recommends: no +- name: Create directory /var/log/strongswan + file: + path: /var/log/strongswan + state: directory + owner: root + group: root + mode: '0755' +- name: Insert certificates + no_log: true + copy: + content: "{{ item.content }}" + dest: "{{ item.dest }}" + owner: root + group: root + mode: "{{ item.mode }}" + loop: "{{ certificates }}" +- name: Add private key + copy: + content: "{{ lookup(passbolt, 'ipsec_private_key', folder_parent_id=passbolt_folder).description }}" + dest: /etc/ipsec.d/private/key.pem + owner: root + group: root + mode: u=r,g=r,o= +- name: Configure ipsec and charon + template: + src: "{{ item.src }}" + dest: "{{ item.dest }}" + owner: root + group: root + mode: "{{ item.mode }}" + loop: "{{ config_ipsec_files }}" + notify: restart-ipsec +- name: Copy Configure file and logrotate Charon + copy: + src: "{{ item.src }}" + dest: "{{ item.dest }}" + owner: root + group: root + mode: u=rw,g=r,o=r + loop: "{{ config_and_logrotate }}" + notify: restart-ipsec +- name: IP forward as a router + sysctl: + name: net.ipv4.ip_forward + value: "1" + state: present + sysctl_set: yes + reload: yes +- name: Add iptables rules in rules.v4 file + blockinfile: + path: /etc/iptables/rules.v4 + marker: "# {mark} ANSIBLE-MANAGED MANGLE CHAIN" + block: "{{ mangle_block }}" + register: iptables +- name: Reload iptables rules + command: netfilter-persistent reload + when: iptables.changed +- name: Get default IPv4 interface + command: ip -o -4 route show default + register: default_route +- name: Extract interface default name + set_fact: + active_interface: "{{ default_route.stdout.split()[-1] }}" +- name: Routing table for VPN + lineinfile: + path: /etc/iproute2/rt_tables + line: "10 vpn" + state: present + regexp: "vpn" +- name: Static routing rules to send VPN traffic directly to the firewall + lineinfile: + path: /etc/network/interfaces + insertafter: "dhcp" + line: "{{ item }}" + state: present + loop: "{{ static_routes }}" + \ No newline at end of file diff --git a/roles/ipsec/tasks/main.yml b/roles/ipsec/tasks/main.yml new file mode 100644 index 0000000..d3dd860 --- /dev/null +++ b/roles/ipsec/tasks/main.yml @@ -0,0 +1,3 @@ +- import_tasks: ipsec.yml + tags: ipsec + diff --git a/roles/ipsec/templates/ipsec.conf b/roles/ipsec/templates/ipsec.conf new file mode 100644 index 0000000..76d3627 --- /dev/null +++ b/roles/ipsec/templates/ipsec.conf @@ -0,0 +1,32 @@ + +config setup + charondebug="ike 1, knl 1, cfg 0" + uniqueids=no + +conn %default + auto=add + compress=no + type=tunnel + keyexchange=ikev2 + fragmentation=yes + forceencaps=yes + eap_identity=%identity + + dpdaction=clear + dpddelay=300s + rekey=no + + left=%any + leftid=@{{ leftid }} + leftcert=cert.pem + leftsendcert=always + leftsubnet={{ leftsubnet }} + + right=%any + rightid=%any + rightauth=eap-radius + rightdns={{ rightdns }} + rightsendcert=never + +{{ ipsec_groups }} + diff --git a/roles/ipsec/templates/ipsec.secrets b/roles/ipsec/templates/ipsec.secrets new file mode 100644 index 0000000..9956a00 --- /dev/null +++ b/roles/ipsec/templates/ipsec.secrets @@ -0,0 +1,2 @@ +{{ leftid }} : RSA "key.pem" +admin %any% : EAP "{{ lookup(passbolt, 'eap', folder_parent_id=passbolt_folder).password }}" diff --git a/roles/ipsec/templates/vn-attr.conf b/roles/ipsec/templates/vn-attr.conf new file mode 100644 index 0000000..94b2b2f --- /dev/null +++ b/roles/ipsec/templates/vn-attr.conf @@ -0,0 +1,8 @@ +attr { + load = yes + dns = {{ rightdns }} + split-include = {{ leftsubnet }} + split-exclude = 0.0.0.0/0 + 28674 = {{ leftid }} + 25 = {{ leftid }} +} diff --git a/roles/ipsec/templates/vn-eap-radius.conf b/roles/ipsec/templates/vn-eap-radius.conf new file mode 100644 index 0000000..de69c64 --- /dev/null +++ b/roles/ipsec/templates/vn-eap-radius.conf @@ -0,0 +1,21 @@ +eap-radius { + load = yes + accounting = yes + class_group = yes + servers { + primary { + #address = radius1.verdnatura.es + address = {{ address_radiusA }} + auth_port = {{ auth_port }} + acct_port = {{ acct_port }} + secret = {{ lookup(passbolt, 'eap-radius', folder_parent_id=passbolt_folder).password }} + } + secondary { + #address = radius2.verdnatura.es + address = {{ address_radiusB }} + auth_port = {{ auth_port }} + acct_port = {{ acct_port }} + secret = {{ lookup(passbolt, 'eap-radius', folder_parent_id=passbolt_folder).password }} + } + } +} \ No newline at end of file