diff --git a/playbooks/arch.yml b/playbooks/arch.yml new file mode 100644 index 00000000..b609bdb9 --- /dev/null +++ b/playbooks/arch.yml @@ -0,0 +1,7 @@ +--- + +- name: Arch Linux | Install prerequisites + become: yes + become_method: su + become_user: root + raw: sleep 10 && pacman -Syu --noconfirm && pacman -S python2 sudo --noconfirm diff --git a/playbooks/common.yml b/playbooks/common.yml index 5628c37f..f78bd728 100644 --- a/playbooks/common.yml +++ b/playbooks/common.yml @@ -12,4 +12,9 @@ include_tasks: freebsd.yml when: '"FreeBSD" in OS.stdout' +- name: Arch pre-tasks + include_tasks: arch.yml + when: '"ARCH" in OS.stdout' + + - include_tasks: facts/main.yml diff --git a/roles/common/tasks/arch.yml b/roles/common/tasks/arch.yml new file mode 100644 index 00000000..a7b36469 --- /dev/null +++ b/roles/common/tasks/arch.yml @@ -0,0 +1,27 @@ +--- + +- set_fact: + tools: [] + sysctl: + - item: net.ipv4.ip_forward + value: 1 + - item: net.ipv4.conf.all.forwarding + value: 1 + - item: net.ipv6.conf.all.forwarding + value: 1 + sysctl_file: /etc/sysctl.d/99-sysctl.conf + tags: + - always + +- name: Loopback for services configured + template: src=10-loopback-services.network.j2 dest=/etc/systemd/network/10-loopback-services.network + tags: + - always + +- name: Networking restarted + systemd: + name: systemd-networkd + daemon_reload: yes + state: restarted + tags: + - always diff --git a/roles/common/tasks/main.yml b/roles/common/tasks/main.yml index 5b6aa438..093ba207 100644 --- a/roles/common/tasks/main.yml +++ b/roles/common/tasks/main.yml @@ -6,6 +6,10 @@ - include_tasks: freebsd.yml when: ansible_distribution == 'FreeBSD' + - include_tasks: arch.yml + when: ansible_distribution == 'Archlinux' + + - name: Install tools package: name="{{ item }}" state=present with_items: @@ -14,7 +18,10 @@ - always - name: Sysctl tuning - sysctl: name="{{ item.item }}" value="{{ item.value }}" + sysctl: + name: "{{ item.item }}" + value: "{{ item.value }}" + sysctl_file: "{{ sysctl_file|default('/etc/sysctl.conf') }}" with_items: - "{{ sysctl|default([]) }}" tags: diff --git a/roles/common/templates/10-loopback-services.network.j2 b/roles/common/templates/10-loopback-services.network.j2 new file mode 100644 index 00000000..257396c6 --- /dev/null +++ b/roles/common/templates/10-loopback-services.network.j2 @@ -0,0 +1,7 @@ +[Match] +Name=lo + +[Network] +Label=lo:100 +Address={{ local_service_ip }}/32 +Address=FCAA::1/64 diff --git a/roles/dns_adblocking/tasks/arch.yml b/roles/dns_adblocking/tasks/arch.yml new file mode 100644 index 00000000..cac7e38f --- /dev/null +++ b/roles/dns_adblocking/tasks/arch.yml @@ -0,0 +1,25 @@ +--- + +- name: Arch Linux | Install cronie + pacman: + name: cronie + +- name: Arch Linux | Enable and start cronie + service: + name: cronie + state: started + enabled: yes + +- name: Arch Linux | Enable systemd-networkd-wait-online + service: + name: systemd-networkd-wait-online + enabled: yes + + +- name: Arch Linux | The dnsmasq additional directories created + file: + dest: "{{ item }}" + state: directory + mode: '0755' + with_items: + - "{{ config_prefix|default('/') }}etc/dnsmasq.d" diff --git a/roles/dns_adblocking/tasks/arch_set_nogroup.yml b/roles/dns_adblocking/tasks/arch_set_nogroup.yml new file mode 100644 index 00000000..3ed2d5f2 --- /dev/null +++ b/roles/dns_adblocking/tasks/arch_set_nogroup.yml @@ -0,0 +1,5 @@ +--- + +- name: Arch Linux | Set nogroup + set_fact: + nogroup: nobody \ No newline at end of file diff --git a/roles/dns_adblocking/tasks/main.yml b/roles/dns_adblocking/tasks/main.yml index ded3f798..2e358379 100644 --- a/roles/dns_adblocking/tasks/main.yml +++ b/roles/dns_adblocking/tasks/main.yml @@ -1,18 +1,20 @@ --- - block: - - name: The DNS tag is defined set_fact: local_dns: true + - include_tasks: arch_set_nogroup.yml + when: ansible_distribution == 'Archlinux' + - name: Dnsmasq installed package: name=dnsmasq - name: Ensure that the dnsmasq user exist - user: name=dnsmasq groups=nogroup append=yes state=present + user: "name=dnsmasq groups={{ nogroup|default('nogroup') }} append=yes state=present" - name: The dnsmasq directory created - file: dest=/var/lib/dnsmasq state=directory mode=0755 owner=dnsmasq group=nogroup + file: "dest=/var/lib/dnsmasq state=directory mode=0755 owner=dnsmasq group={{ nogroup|default('nogroup') }}" - include_tasks: ubuntu.yml when: ansible_distribution == 'Debian' or ansible_distribution == 'Ubuntu' @@ -20,6 +22,9 @@ - include_tasks: freebsd.yml when: ansible_distribution == 'FreeBSD' + - include_tasks: arch.yml + when: ansible_distribution == 'Archlinux' + - name: Dnsmasq configured template: src: dnsmasq.conf.j2 diff --git a/roles/dns_adblocking/templates/dnsmasq.conf.j2 b/roles/dns_adblocking/templates/dnsmasq.conf.j2 index 501f7568..1a2a6194 100644 --- a/roles/dns_adblocking/templates/dnsmasq.conf.j2 +++ b/roles/dns_adblocking/templates/dnsmasq.conf.j2 @@ -104,7 +104,7 @@ server={{ host }} # If you want dnsmasq to change uid and gid to something other # than the default, edit the following lines. user=nobody -group=nogroup +group={{ nogroup|default('nogroup') }} # If you want dnsmasq to listen for DHCP and DNS requests only on # specified interfaces (and the loopback) give the name of the diff --git a/roles/dns_encryption/tasks/arch.yml b/roles/dns_encryption/tasks/arch.yml new file mode 100644 index 00000000..a9de0d35 --- /dev/null +++ b/roles/dns_encryption/tasks/arch.yml @@ -0,0 +1,13 @@ +--- + +- name: Arch Linux | Install dnscrypt-proxy + pacman: + name: dnscrypt-proxy + state: latest + +- name: Arch Linux | Patch dnscrypt-proxy.service + template: + src: dnscrypt-proxy.service.j2 + dest: "{{ config_prefix|default('/') }}etc/systemd/system/dnscrypt-proxy.service" + notify: + - daemon reload \ No newline at end of file diff --git a/roles/dns_encryption/tasks/main.yml b/roles/dns_encryption/tasks/main.yml index 49c8d6e8..74e056c0 100644 --- a/roles/dns_encryption/tasks/main.yml +++ b/roles/dns_encryption/tasks/main.yml @@ -7,6 +7,10 @@ include_tasks: freebsd.yml when: ansible_distribution == 'FreeBSD' +- name: Include tasks for Arch Linux + include_tasks: arch.yml + when: ansible_distribution == 'Archlinux' + - name: dnscrypt-proxy configured template: src: dnscrypt-proxy.toml.j2 diff --git a/roles/dns_encryption/templates/dnscrypt-proxy.service.j2 b/roles/dns_encryption/templates/dnscrypt-proxy.service.j2 new file mode 100644 index 00000000..40726539 --- /dev/null +++ b/roles/dns_encryption/templates/dnscrypt-proxy.service.j2 @@ -0,0 +1,48 @@ +[Unit] +Description=DNSCrypt-proxy client +Documentation=https://github.com/jedisct1/dnscrypt-proxy/wiki + +## Start service after the network is online. +## Requires a wait service such as NetworkManager or systemd-networkd. +## Verify using: +## systemctl is-enabled NetworkManager-wait-online.service systemd-networkd-wait-online.service +## Then enable: +## systemctl enable NetworkManager-wait-online.service +## Or alternatively: +## systemctl enable systemd-networkd-wait-online.service +After=network-online.target +Wants=network-online.target + +## DNSCrypt-proxy provides and requires name resolution. +Before=nss-lookup.target +Wants=nss-lookup.target + +[Service] +## Set O_NONBLOCK flag for socket unit. +NonBlocking=true + +## Execute dnscrypt-proxy with configuration file. +ExecStart=/usr/bin/dnscrypt-proxy --config /etc/dnscrypt-proxy/dnscrypt-proxy.toml + +## Make /home, /root and /run/user read only. +ProtectHome=yes + +## Make Linux control groups read only. +ProtectControlGroups=yes + +## Deny explicit module loading. +ProtectKernelModules=yes + +## Run dnscrypt-proxy as unprivileged user with +## temporary assigned UID/GID. See man:systemd.exec +## for more info. Requires systemd 232+. +DynamicUser=yes +CacheDirectory=dnscrypt-proxy +LogsDirectory=dnscrypt-proxy +RuntimeDirectory=dnscrypt-proxy + +[Install] + +## Create symlink for systemd to pull in the unit when starting multi-user.target +## Can be found in /etc/systemd/system/multi-user.target.wants/ +WantedBy=multi-user.target diff --git a/roles/ssh_tunneling/tasks/arch.yml b/roles/ssh_tunneling/tasks/arch.yml new file mode 100644 index 00000000..c5cbcc90 --- /dev/null +++ b/roles/ssh_tunneling/tasks/arch.yml @@ -0,0 +1,5 @@ +--- + +- name: Arch Linux | Set sshd daemon name + set_fact: + ssh_service_name: sshd \ No newline at end of file diff --git a/roles/ssh_tunneling/tasks/main.yml b/roles/ssh_tunneling/tasks/main.yml index 8a1d4965..eea5dd8d 100644 --- a/roles/ssh_tunneling/tasks/main.yml +++ b/roles/ssh_tunneling/tasks/main.yml @@ -1,5 +1,9 @@ --- - block: + - name: Include tasks for Arch Linux + include_tasks: arch.yml + when: ansible_distribution == 'Archlinux' + - name: Ensure that the sshd_config file has desired options blockinfile: dest: /etc/ssh/sshd_config diff --git a/roles/vpn/handlers/main.yml b/roles/vpn/handlers/main.yml index 8ce3163a..2b0e8c12 100644 --- a/roles/vpn/handlers/main.yml +++ b/roles/vpn/handlers/main.yml @@ -13,5 +13,8 @@ - name: restart iptables service: name=netfilter-persistent state=restarted +- name: restart iptables arch + service: name=iptables state=restarted + - name: rereadcrls shell: ipsec rereadcrls; ipsec purgecrls diff --git a/roles/vpn/tasks/arch.yml b/roles/vpn/tasks/arch.yml new file mode 100644 index 00000000..4b2f36c8 --- /dev/null +++ b/roles/vpn/tasks/arch.yml @@ -0,0 +1,21 @@ +--- +- set_fact: + strongswan_additional_plugins: [] + iptables_rules_v4: /etc/iptables/iptables.rules + iptables_rules_v6: /etc/iptables/ip6tables.rules + restart_iptables: restart iptables arch + ipencap: ipv4 + +- name: Archlinux | Install strongSwan + pacman: + name: strongswan + state: latest + +- name: Archlinux | Enable services + service: name={{ item }} enabled=yes + with_items: + - strongswan + - iptables + +- include_tasks: iptables.yml + tags: iptables diff --git a/roles/vpn/tasks/iptables.yml b/roles/vpn/tasks/iptables.yml index e5b10619..bf577632 100644 --- a/roles/vpn/tasks/iptables.yml +++ b/roles/vpn/tasks/iptables.yml @@ -8,9 +8,9 @@ group: root mode: 0640 with_items: - - { src: rules.v4.j2, dest: /etc/iptables/rules.v4 } + - { src: rules.v4.j2, dest: "{{ iptables_rules_v4|default('/etc/iptables/rules.v4') }}" } notify: - - restart iptables + - "{{ restart_iptables|default('restart iptables') }}" - name: Iptables configured template: @@ -21,6 +21,6 @@ mode: 0640 when: ipv6_support with_items: - - { src: rules.v6.j2, dest: /etc/iptables/rules.v6 } + - { src: rules.v6.j2, dest: "{{ iptables_rules_v6|default('/etc/iptables/rules.v6') }}" } notify: - - restart iptables + - "{{ restart_iptables|default('restart iptables') }}" diff --git a/roles/vpn/tasks/main.yml b/roles/vpn/tasks/main.yml index e0d0d1bf..d51be898 100644 --- a/roles/vpn/tasks/main.yml +++ b/roles/vpn/tasks/main.yml @@ -12,6 +12,9 @@ - include_tasks: freebsd.yml when: ansible_distribution == 'FreeBSD' + - include_tasks: arch.yml + when: ansible_distribution == 'Archlinux' + - name: Install strongSwan package: name=strongswan state=present diff --git a/roles/vpn/templates/rules.v4.j2 b/roles/vpn/templates/rules.v4.j2 index c51568aa..3f88c9e5 100644 --- a/roles/vpn/templates/rules.v4.j2 +++ b/roles/vpn/templates/rules.v4.j2 @@ -66,7 +66,7 @@ COMMIT # Allow new traffic to port 22 (SSH) -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT # Allow any traffic from the VPN --A INPUT -p ipencap -m policy --dir in --pol ipsec --proto esp -j ACCEPT +-A INPUT -p {{ ipencap|default('ipencap') }} -m policy --dir in --pol ipsec --proto esp -j ACCEPT # TODO: # The IP of the resolver should be bound to a DUMMY interface.