master
blallo 2021-02-21 00:45:22 +01:00
commit baa7f33e09
Signed by: blallo
GPG Key ID: 0CBE577C9B72DC3F
21 changed files with 571 additions and 0 deletions

25
files/verify_ip.sh 100755
View File

@ -0,0 +1,25 @@
#!/usr/bin/env bash
RETRY=3
CURL_SLEEP_TIME=10 # These are seconds
EXPECTED_IP=172.94.25.17
sleep 10 # Wait these seconds for ppp to come up
while [ $RETRY -ne 0 ]; do
IP_RESULT=$(curl -s ifconfig.co)
if [ $? -ne 0 ]; then
RETRY=$(( $RETRY - 1 ))
echo "curl failed - retrying ${RETRY} times."
sleep $CURL_SLEEP_TIME
else
break
fi
done
if [ "${EXPECTED_IP}" != "${IP_RESULT}" ]; then
echo "Expected ip (${EXPECTED_IP}) different from the one got (${IP_RESULT})"
exit 1
fi
# vim: set ft=sh et sw=0 ts=2 sts=0:

23
handlers/main.yml 100644
View File

@ -0,0 +1,23 @@
---
- name: reload_nginx
systemd:
name: nginx
daemon_reload: true
state: reloaded
- name: restart_ivacy
systemd:
name: ivacy-ppp
state: restarted
- name: reload_and_restart_ivacy
systemd:
name: ivacy-ppp
daemon_reload: true
state: restarted
- name: restart networking
systemd:
name: systemd-networkd
daemon_reload: true
state: restarted

114
tasks/firewall.yml 100644
View File

@ -0,0 +1,114 @@
---
- name: Require firewalld
apt:
name: firewalld
state: latest
- name: Add wireguard firewalld service
template:
src: firewalld/wireguard.xml.j2
dest: "/etc/firewalld/services/{{ gateway.vpn.name }}.xml"
owner: root
group: root
mode: 0644
# - name: Ensure firewalld is enabled
# systemd:
# name: firewalld.service
# enabled: yes
# masked: no
# state: started
- name: Force all notified handlers to run at this point, not waiting for normal sync points
meta: flush_handlers
- name: Add zones
ansible.posix.firewalld:
zone: "{{ item }}"
state: present
permanent: yes
with_items:
- home
- public
- trusted
- name: Add home interface
ansible.posix.firewalld:
zone: home
interface: "{{ gateway.firewall.home_iface }}"
permanent: yes
immediate: yes
state: enabled
- name: Add public interface
ansible.posix.firewalld:
zone: public
interface: "{{ gateway.firewall.public_iface|default(ppp0) }}"
permanent: yes
immediate: yes
state: enabled
- name: Add vm interface
ansible.posix.firewalld:
zone: trusted
interface: "{{ gateway.firewall.vm_iface }}"
permanent: yes
immediate: yes
state: enabled
- name: Enable masquerade on public interface
ansible.posix.firewalld:
zone: public
masquerade: yes
permanent: yes
immediate: yes
state: enabled
- name: Enable masquerade on vm interface
ansible.posix.firewalld:
zone: trusted
masquerade: yes
permanent: yes
immediate: yes
state: enabled
- name: Add services to public interface
ansible.posix.firewalld:
zone: public
service: "{{ item }}"
permanent: yes
immediate: yes
state: enabled
with_items:
- dhcpv6-client
- http
- https
- ssh
- name: Add services to home interface
ansible.posix.firewalld:
zone: home
service: "{{ item }}"
permanent: yes
immediate: yes
state: enabled
with_items:
- dhcpv6-client
- http
- https
- ssh
- "{{ gateway.vpn.name }}"
- mdns
- samba-client
- samba
- name: Forward ports to hosts
ansible.posix.firewalld:
rich_rule: "rule family=ipv4 forward-port protocol={{ item.proto }} port={{ item.from.port }} to-addr=\"{{ item.to.addr }}\" to-port={{ item.to.port|default(item.from.port) }}"
zone: "{{ item.zone }}"
permanent: yes
immediate: yes
state: enabled
when: gateway.firewall.forwarded_ports is defined
with_items: "{{ gateway.firewall.forwarded_ports }}"

58
tasks/ivacy.yml 100644
View File

@ -0,0 +1,58 @@
---
- name: Require ppp installed
apt:
name: ['pptp-linux', 'pptpd']
state: latest
- name: Ensure pptp options
template:
src: ivacy/options.pptp.j2
dest: /etc/ppp/options.pptp
owner: root
group: root
mode: 0644
notify: restart_ivacy
- name: Ensure ivacy configuration
template:
src: ivacy/ivacy_config
dest: "/etc/ppp/peers/{{ gateway.ivacy.config_name|default('ivacy') }}"
owner: root
group: root
mode: 0644
notify: restart_ivacy
- name: Ensure ppp chap secrets
template:
src: ivacy/chap-secrets.j2
dest: /etc/ppp/chap-secrets
owner: root
group: root
mode: 0644
notify: restart_ivacy
- name: Ensure script to verify ip is present
copy:
src: files/verify_ip.sh
dest: /usr/local/bin/verify_ip.sh
owner: root
group: root
mode: 0755
notify: restart_ivacy
- name: Ensure ivacy service unit
template:
src: ivacy/ivacy-ppp.service.j2
dest: /etc/systemd/system/ivacy-ppp.service
owner: root
group: root
mode: 0644
notify: reload_and_restart_ivacy
- name: Ensure ivacy service is enabled and running
systemd:
name: ivacy-ppp.service
enabled: yes
masked: no
state: started
notify: restart_ivacy

View File

@ -0,0 +1,19 @@
---
- name: ensure letsencrypt is up-to-date
apt:
name: certbot
state: latest
- name: create letsencrypt webroot
file:
path: /var/www/letsencrypt
state: directory
owner: root
group: www-data
mode: '0775'
- name: ensure all the domains have a tls certificate
shell: "[ -f /etc/letsencrypt/live/{{ item.domain_name }}/fullchain.pem ] || certbot certonly --agree-tos -m {{ item.cert_email }} --webroot -w /var/www/letsencrypt -d {{ item.domain_name }}"
when: item.cert_email is defined
with_items: "{{ gateway.proxied_services }}"
notify: reload_nginx

11
tasks/main.yml 100644
View File

@ -0,0 +1,11 @@
---
- name: install passlib
apt:
name: python3-passlib
state: present
- include_tasks: wg_link.yml
- include_tasks: firewall.yml
# - include_tasks: ivacy.yml
- include_tasks: nginx.yml
- include_tasks: letsencrypt.yml
- include_tasks: nginx_ssl.yml

72
tasks/nginx.yml 100644
View File

@ -0,0 +1,72 @@
---
- name: ensure nginx is at the latest version
apt:
name: nginx-full
state: latest
- name: ensure default nginx site is disabled
file:
path: /etc/nginx/sites-enabled/default
state: absent
# - name: start nginx
# systemd:
# name: nginx.service
# state: started
# enabled: true
- name: copy custom configuration
template:
src: "{{ item.src }}"
dest: /etc/nginx
owner: root
group: root
mode: '0644'
with_filetree: templates/nginx/custom_configs/
when: item.state == "file"
notify: reload_nginx
- name: add per-domain ssl configuration
template:
src: templates/nginx/ssl.conf.j2
dest: "/etc/nginx/ssl_{{ item.domain_name }}.conf"
owner: root
group: root
mode: '0644'
vars:
domain_name: "{{ item.domain_name }}"
with_items: "{{ gateway.proxied_services }}"
- name: add password file for sites that are password-protected
htpasswd:
path: "{{ item.password_file }}"
name: "{{ item.username }}"
password: "{{ item.password }}"
owner: "{{ item.owner|default('root') }}"
group: "{{ item.group|default('www-data') }}"
mode: 0640
when: item.password_protect|default(false)
loop: "{{ gateway.proxied_services }}"
- name: add nginx configuration (only http)
template:
src: templates/nginx/sites.conf.j2
dest: "/etc/nginx/sites-available/{{ item.domain_name }}.conf"
owner: root
group: root
mode: '0644'
vars:
service: "{{ item }}"
with_items: "{{ gateway.proxied_services }}"
notify: reload_nginx
- name: enable nginx http configuration
file:
src: "/etc/nginx/sites-available/{{ item.domain_name }}.conf"
dest: "/etc/nginx/sites-enabled/{{ item.domain_name }}.conf"
state: link
with_items: "{{ gateway.proxied_services }}"
notify: reload_nginx
- name: Force all notified handlers to run at this point, not waiting for normal sync points
meta: flush_handlers

View File

@ -0,0 +1,22 @@
---
- name: add nginx configuration (https)
template:
src: templates/nginx/sites_ssl.conf.j2
dest: "/etc/nginx/sites-available/{{ item.domain_name }}-ssl.conf"
owner: root
group: root
mode: '0644'
vars:
service: "{{ item }}"
when: item.cert_email is defined
with_items: "{{ gateway.proxied_services }}"
notify: reload_nginx
- name: enable nginx https configuration
file:
src: "/etc/nginx/sites-available/{{ item.domain_name }}-ssl.conf"
dest: "/etc/nginx/sites-enabled/{{ item.domain_name }}-ssl.conf"
state: link
when: item.cert_email is defined
with_items: "{{ gateway.proxied_services }}"
notify: reload_nginx

35
tasks/wg_link.yml 100644
View File

@ -0,0 +1,35 @@
---
- name: Ensure wireguard is present
apt:
name: wireguard-tools
state: present
default_release: buster-backports
register: wireguard
- name: Ensure wireguard netdev configuration is present
template:
src: templates/wireguard/wireguard.netdev.j2
dest: "/etc/systemd/network/{{ gateway.vpn.name }}.netdev"
owner: root
group: root
mode: 0644
notify: restart networking
- name: Ensure wireguard network configuration is present
template:
src: templates/wireguard/wireguard.network.j2
dest: "/etc/systemd/network/{{ gateway.vpn.name }}.network"
owner: root
group: root
mode: 0644
notify: restart networking
- name: Reboot to allow wireguard to start
reboot:
when: wireguard.changed
- name: Ensure systemd-networkd is enabled and running
systemd:
name: systemd-networkd.service
state: started
enabled: yes

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<service>
<short>PPTP</short>
<description>Allow GRE through PPP tunnel.</description>
<port port="1723" protocol="tcp"/>
</service>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<service>
<short>PPTP</short>
<description>Allow GRE through PPP tunnel.</description>
<port port="{{ gateway.vpn.endpoint.port }}" protocol="udp"/>
</service>

View File

@ -0,0 +1,3 @@
# Secrets for authentication using CHAP
# client server secret IP addresses
{{ gateway.ivacy.username }} PPTP {{ gateway.ivacy.password }} *

View File

@ -0,0 +1,14 @@
[Unit]
Description=PPTP Ivacy VPN
After=network-online.target
[Service]
Type=forking
ExecStart=/usr/sbin/pppd call {{ gateway.ivacy.config_name|default('ivacy') }}
ExecStartPost=/usr/local/bin/verify_ip.sh
TimeoutStartSec=120
Restart=on-failure
RestartSec=600
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,6 @@
pty "pptp de-ded-3.dns2use.com --nolaunchpppd"
name "ivacy0d8560848"
remotename PPTP
file /etc/ppp/options.pptp
require-mppe-128
refuse-eap noauth

View File

@ -0,0 +1,8 @@
lock
noauth
refuse-pap
refuse-eap
refuse-chap
refuse-mschap
nobsdcomp
nodeflate

View File

@ -0,0 +1,10 @@
location ^~ /.well-known/acme-challenge/ {
default_type "text/plain";
root /var/www/letsencrypt;
allow all;
}
# esattamente questa riga: proibisce l'accesso alla dir (per non far leggere
# quali challenge aperti ci sono)
location = /.well-known/acme-challenge/ {
return 404;
}

View File

@ -0,0 +1,42 @@
server {
listen {{ service.port | default(80) }};
server_name {{ service.domain_name }};
access_log /var/log/nginx/{{ service.domain_name }}-access.log;
error_log /var/log/nginx/{{ service.domain_name }}-error.log;
include letsencrypt.conf;
{% if service.redirect_to_https %}
location / {
return 301 https://$host$request_uri;
}
{% else %}
location / {
proxy_pass http://{{ service.internal_ip }}:{{ service.internal_port }};
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
{% if service.http_opts is defined %}
{% for opt in service.http_opts %}
{{ opt }}
{% endfor %}
{% endif %}
}
{% endif %}
{% if service.http_custom_locations is defined %}
{% for location in service.http_custom_locations %}
location {{ location.rule }} {
{% for conf_line in location.conf_lines %}
{{ conf_line }};
{% endfor %}
}
{% endfor %}
{% endif %}
{% if service.http_custom_configurations is defined %}
{% for conf in service.http_custom_configurations %}
{{ conf }};
{% endfor %}
{% endif %}
}

View File

@ -0,0 +1,53 @@
server {
listen {{ service.ssl_port | default(443) }};
server_name {{ service.domain_name }};
access_log /var/log/nginx/{{ service.domain_name }}-ssl-access.log;
error_log /var/log/nginx/{{ service.domain_name }}-ssl-error.log;
include ssl_{{ service.domain_name }}.conf;
{% if service.password_protect|default(false) %}
auth_basic "{{ service.domain_name }} is password protected";
auth_basic_user_file {{ service.password_file }};
{% endif %}
location / {
proxy_pass http://{{ service.internal_ip }}:{{ service.internal_port }};
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
{% if service.https_opts is defined %}
{% for opt in service.https_opts %}
{{ opt }}
{% endfor %}
{% endif %}
}
{% if service.websockets is defined %}
location {{ service.websockets.path }} {
proxy_pass http://{{ service.websockets.internal_ip }}:{{ service.websockets.internal_port }};
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
{% endif %}
{% if service.https_custom_locations is defined %}
{% for location in service.https_custom_locations %}
location {{ location.rule }} {
{% for conf_line in location.conf_lines %}
{{ conf_line }};
{% endfor %}
}
{% endfor %}
{% endif %}
{% if service.https_custom_configurations is defined %}
{% for conf in service.https_custom_configurations %}
{{ conf }};
{% endfor %}
{% endif %}
}

View File

@ -0,0 +1,8 @@
ssl on;
ssl_certificate /etc/letsencrypt/live/{{ domain_name }}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/{{ domain_name }}/privkey.pem;
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
ssl_prefer_server_ciphers on;

View File

@ -0,0 +1,16 @@
[NetDev]
Name={{ gateway.vpn.name }}
Kind=wireguard
Description=WireGuard tunnel {{ gateway.vpn.name }}
[WireGuard]
ListenPort={{ gateway.vpn.listen_port|default(51714) }}
PrivateKey={{ gateway.vpn.private_key }}
[WireGuardPeer]
PublicKey={{ gateway.vpn.endpoint.public_key }}
# The following will route all the traffic through the vpn endpoint
AllowedIPs=0.0.0.0/0
Endpoint={{ gateway.vpn.endpoint.url }}:{{ gateway.vpn.endpoint.port }}
# vim: set ft=dosini:

View File

@ -0,0 +1,20 @@
[Match]
Name={{ gateway.vpn.name }}
[Network]
Address={{ gateway.vpn.this_ip }}/32
[Route]
Destination={{ gateway.vpn.endpoint.this_ip }}/32
Scope=link
[Route]
Destination=0.0.0.0/1
Gateway={{ gateway.vpn.endpoint.this_ip }}
[Route]
Destination=128.0.0.0/1
Gateway={{ gateway.vpn.endpoint.this_ip }}
# vim: set ft=dosini: