Initial commit
This commit is contained in:
commit
8b3acb54ab
9
ansible.cfg
Normal file
9
ansible.cfg
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
[defaults]
|
||||||
|
inventory = inventory
|
||||||
|
interpreter_python = auto_silent
|
||||||
|
|
||||||
|
[privilege_escalation]
|
||||||
|
become = True
|
||||||
|
become_method = sudo
|
||||||
|
become_user = root
|
||||||
|
become_ask_pass = False
|
6
group_vars/all
Normal file
6
group_vars/all
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
---
|
||||||
|
hessnet_asn: "209616"
|
||||||
|
v4_prefixes:
|
||||||
|
- "44.145.128.0/24"
|
||||||
|
v6_prefixes:
|
||||||
|
- "2001:678:15c::/48"
|
1
host_vars/archvm1.hosts.v6.hessnet.dk.yml
Normal file
1
host_vars/archvm1.hosts.v6.hessnet.dk.yml
Normal file
|
@ -0,0 +1 @@
|
||||||
|
---
|
40
host_vars/vul1.ams.nl.routers.v6.hessnet.dk.yml
Normal file
40
host_vars/vul1.ams.nl.routers.v6.hessnet.dk.yml
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
---
|
||||||
|
router_id: "136.244.111.183"
|
||||||
|
router_v4_ip: "136.244.111.183"
|
||||||
|
router_v6_ip: "2001:19f0:5001:256b:5400:02ff:feb0:cd41"
|
||||||
|
|
||||||
|
bgp_peers:
|
||||||
|
- name: "vultr_v4"
|
||||||
|
template: "peer_vultr_v4"
|
||||||
|
asn: "64515"
|
||||||
|
neighbor_ip: "169.254.169.254"
|
||||||
|
password: !vault |
|
||||||
|
$ANSIBLE_VAULT;1.1;AES256
|
||||||
|
65313532636233353638373732623333376562393335373233396534616531353164386636616538
|
||||||
|
6436323265316639373831346634366332666333663265320a323534626166653432343562386639
|
||||||
|
30626239303536376162643730633536303964616131636139656233316363363338633362376137
|
||||||
|
6434313931353037610a323261313664356261323963623530636536393162626666376265333532
|
||||||
|
3934
|
||||||
|
|
||||||
|
- name: "vultr_v6"
|
||||||
|
template: "peer_vultr_v6"
|
||||||
|
asn: "64515"
|
||||||
|
neighbor_ip: "2001:19f0:ffff::1"
|
||||||
|
password: !vault |
|
||||||
|
$ANSIBLE_VAULT;1.1;AES256
|
||||||
|
65313532636233353638373732623333376562393335373233396534616531353164386636616538
|
||||||
|
6436323265316639373831346634366332666333663265320a323534626166653432343562386639
|
||||||
|
30626239303536376162643730633536303964616131636139656233316363363338633362376137
|
||||||
|
6434313931353037610a323261313664356261323963623530636536393162626666376265333532
|
||||||
|
3934
|
||||||
|
|
||||||
|
- name: "home_router"
|
||||||
|
template: "peer_hessnet"
|
||||||
|
asn: "209616"
|
||||||
|
neighbor_ip: "172.16.12.19"
|
||||||
|
filters:
|
||||||
|
export: "{ peer_export_default_only(); }"
|
||||||
|
import: "myroutes_import_export();"
|
||||||
|
|
||||||
|
announce_from_here: false
|
||||||
|
configure_static_multihop_routes: true
|
10
inventory
Normal file
10
inventory
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
[vms]
|
||||||
|
archvm1.hosts.v6.hessnet.dk
|
||||||
|
archvm2.hosts.v6.hessnet.dk
|
||||||
|
|
||||||
|
[routers]
|
||||||
|
# frb1.cph.dk.routers.v6.hessnet.dk
|
||||||
|
vul1.ams.nl.routers.v6.hessnet.dk
|
||||||
|
|
||||||
|
[as209616_webservers]
|
||||||
|
archvm1.hosts.v6.hessnet.dk
|
5
roles/archvms_base/tasks/full_upgrade.yml
Normal file
5
roles/archvms_base/tasks/full_upgrade.yml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
- name: "Full pacman upgrade"
|
||||||
|
pacman:
|
||||||
|
update_cache: "yes"
|
||||||
|
upgrade: "yes"
|
2
roles/archvms_base/tasks/main.yml
Normal file
2
roles/archvms_base/tasks/main.yml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
---
|
||||||
|
- include_tasks: "full_upgrade.yml"
|
3
roles/bird/meta/main.yml
Normal file
3
roles/bird/meta/main.yml
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
dependencies:
|
||||||
|
- { role: "handlers" }
|
17
roles/bird/tasks/bird.yml
Normal file
17
roles/bird/tasks/bird.yml
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
---
|
||||||
|
- name: "Install bird"
|
||||||
|
pacman:
|
||||||
|
name: "bird"
|
||||||
|
state: "installed"
|
||||||
|
|
||||||
|
- name: "Copy bird configuration templates"
|
||||||
|
template:
|
||||||
|
src: "bird.conf.j2"
|
||||||
|
dest: "/etc/bird.conf"
|
||||||
|
notify: "reconfigure bird"
|
||||||
|
|
||||||
|
- name: "Enable bird service"
|
||||||
|
service:
|
||||||
|
name: "bird"
|
||||||
|
enabled: "yes"
|
||||||
|
state: "started"
|
2
roles/bird/tasks/main.yml
Normal file
2
roles/bird/tasks/main.yml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
---
|
||||||
|
- include_tasks: "bird.yml"
|
267
roles/bird/templates/bird.conf.j2
Normal file
267
roles/bird/templates/bird.conf.j2
Normal file
|
@ -0,0 +1,267 @@
|
||||||
|
### This file is generated using Ansible and will be overwritten.
|
||||||
|
### Do not change this file directly!
|
||||||
|
|
||||||
|
log syslog all;
|
||||||
|
log "/var/log/bird.log" all;
|
||||||
|
debug protocols all;
|
||||||
|
timeformat base iso long;
|
||||||
|
timeformat log iso long;
|
||||||
|
timeformat protocol iso long;
|
||||||
|
timeformat route iso long;
|
||||||
|
|
||||||
|
router id {{ router_id }};
|
||||||
|
|
||||||
|
define my_asn = {{ hessnet_asn }};
|
||||||
|
|
||||||
|
define my_prefixes_ipv6 = [
|
||||||
|
{% for prefix in v6_prefixes %}
|
||||||
|
{{ prefix }}+{{"," if not loop.last }}
|
||||||
|
{% endfor %}
|
||||||
|
];
|
||||||
|
|
||||||
|
define my_prefixes_ipv4 = [
|
||||||
|
{% for prefix in v4_prefixes %}
|
||||||
|
{{ prefix }}+{{"," if not loop.last }}
|
||||||
|
{% endfor %}
|
||||||
|
];
|
||||||
|
|
||||||
|
define my_net_aggregated_ipv6 = [
|
||||||
|
{% for prefix in v6_prefixes %}
|
||||||
|
{{ prefix }}{{"," if not loop.last }}
|
||||||
|
{% endfor %}
|
||||||
|
];
|
||||||
|
|
||||||
|
define my_net_aggregated_ipv4 = [
|
||||||
|
{% for prefix in v4_prefixes %}
|
||||||
|
{{ prefix }}{{"," if not loop.last }}
|
||||||
|
{% endfor %}
|
||||||
|
];
|
||||||
|
|
||||||
|
# functions and filters
|
||||||
|
|
||||||
|
function is_default_route() {
|
||||||
|
case net.type {
|
||||||
|
NET_IP4: if net = 0.0.0.0/0 then return true;
|
||||||
|
NET_IP6: if net = ::/0 then return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function is_own_route() {
|
||||||
|
case net.type {
|
||||||
|
NET_IP4: if net ~ my_prefixes_ipv4 then return true;
|
||||||
|
NET_IP6: if net ~ my_prefixes_ipv6 then return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function is_own_aggregated_net() {
|
||||||
|
case net.type {
|
||||||
|
NET_IP4: if net ~ my_net_aggregated_ipv4 then return true;
|
||||||
|
NET_IP6: if net ~ my_net_aggregated_ipv6 then return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function honor_graceful_shutdown()
|
||||||
|
{
|
||||||
|
# RFC 8326 Graceful BGP Session Shutdown
|
||||||
|
if (65535, 0) ~ bgp_community then {
|
||||||
|
bgp_local_pref = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function peer_export_default_only() {
|
||||||
|
if !is_default_route() then reject;
|
||||||
|
accept;
|
||||||
|
}
|
||||||
|
|
||||||
|
function peer_export_dfz() {
|
||||||
|
if source !~ [ RTS_BGP, RTS_STATIC ] then reject;
|
||||||
|
if is_default_route() then reject;
|
||||||
|
accept;
|
||||||
|
}
|
||||||
|
|
||||||
|
function peer_export_dfz_and_default() {
|
||||||
|
if is_default_route() then {
|
||||||
|
peer_export_default_only();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
peer_export_dfz();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
filter kernel_export {
|
||||||
|
if source !~ [ RTS_BGP, RTS_OSPF, RTS_STATIC ] then reject;
|
||||||
|
if is_default_route() then accept;
|
||||||
|
if is_own_route() then accept;
|
||||||
|
reject;
|
||||||
|
}
|
||||||
|
|
||||||
|
filter ospf_export {
|
||||||
|
if source = RTS_DEVICE then accept;
|
||||||
|
reject;
|
||||||
|
}
|
||||||
|
|
||||||
|
filter transit_import {
|
||||||
|
honor_graceful_shutdown();
|
||||||
|
# bgp_large_community.add(({{hessnet_asn}},1,1));
|
||||||
|
accept;
|
||||||
|
}
|
||||||
|
|
||||||
|
filter transit_export {
|
||||||
|
{% if configure_static_multihop_routes is sameas true %}
|
||||||
|
if proto = "noAnnounce_v6" then reject;
|
||||||
|
if proto = "noAnnounce_v4" then reject;
|
||||||
|
{% endif %}
|
||||||
|
if is_own_aggregated_net() then accept;
|
||||||
|
reject;
|
||||||
|
}
|
||||||
|
|
||||||
|
filter myroutes_import_export {
|
||||||
|
if source !~ [ RTS_BGP, RTS_OSPF, RTS_STATIC ] then reject;
|
||||||
|
if is_own_route() then accept;
|
||||||
|
reject;
|
||||||
|
}
|
||||||
|
|
||||||
|
{% if announce_from_here is sameas true %}
|
||||||
|
protocol static announce_v6 {
|
||||||
|
ipv6;
|
||||||
|
{% for prefix in v6_prefixes %}
|
||||||
|
route {{ prefix }} unreachable;
|
||||||
|
{% endfor %}
|
||||||
|
}
|
||||||
|
|
||||||
|
protocol static announce_v4 {
|
||||||
|
ipv4;
|
||||||
|
{% for prefix in v4_prefixes %}
|
||||||
|
route {{ prefix }} unreachable;
|
||||||
|
{% endfor %}
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if configure_static_multihop_routes is sameas true %}
|
||||||
|
protocol static noAnnounce_v6 {
|
||||||
|
ipv6;
|
||||||
|
{% for peer in bgp_peers %}
|
||||||
|
{% if peer.neighbor_ip | ipv6 %}
|
||||||
|
route {{ peer.neighbor_ip }}/128 via {{ router_v6_ip }};
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
}
|
||||||
|
|
||||||
|
protocol static noAnnounce_v4 {
|
||||||
|
ipv4;
|
||||||
|
{% for peer in bgp_peers %}
|
||||||
|
{% if peer.neighbor_ip | ipv4 %}
|
||||||
|
route {{ peer.neighbor_ip }}/32 via {{ router_v4_ip }};
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
protocol device {
|
||||||
|
scan time 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
protocol direct {
|
||||||
|
ipv6;
|
||||||
|
interface "dummy*";
|
||||||
|
}
|
||||||
|
|
||||||
|
protocol kernel {
|
||||||
|
ipv4 {
|
||||||
|
import filter myroutes_import_export;
|
||||||
|
export none; #filter kernel_export;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protocol kernel kernel6 {
|
||||||
|
scan time 5;
|
||||||
|
ipv6 {
|
||||||
|
import none;
|
||||||
|
export none; #filter kernel_export;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
template bgp transit_v6 {
|
||||||
|
local as my_asn;
|
||||||
|
hold time 600;
|
||||||
|
ipv6 {
|
||||||
|
import filter transit_import;
|
||||||
|
export filter transit_export;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
template bgp transit_v4 {
|
||||||
|
local as my_asn;
|
||||||
|
hold time 600;
|
||||||
|
ipv4 {
|
||||||
|
import filter transit_import;
|
||||||
|
export filter transit_export;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
template bgp peer_vultr_v6 {
|
||||||
|
local as my_asn;
|
||||||
|
source address {{ router_v6_ip }};
|
||||||
|
graceful restart on;
|
||||||
|
multihop 2;
|
||||||
|
ipv6 {
|
||||||
|
import filter transit_import;
|
||||||
|
export filter transit_export;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
template bgp peer_vultr_v4 {
|
||||||
|
local as my_asn;
|
||||||
|
source address {{router_v4_ip}};
|
||||||
|
graceful restart on;
|
||||||
|
multihop 2;
|
||||||
|
ipv4 {
|
||||||
|
import filter transit_import;
|
||||||
|
export filter transit_export;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
template bgp peer_hessnet {
|
||||||
|
local as my_asn;
|
||||||
|
ipv6 {
|
||||||
|
#next hop self;
|
||||||
|
import none;
|
||||||
|
export none;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
{% for peer in bgp_peers %}
|
||||||
|
protocol bgp {{ peer.name }} from {{ peer.template }} {
|
||||||
|
neighbor {{peer.neighbor_ip}} as {{peer.asn}};
|
||||||
|
{% if peer.password is defined %}
|
||||||
|
password "{{ peer.password }}";
|
||||||
|
{% endif %}
|
||||||
|
{% if peer.filters is defined %}
|
||||||
|
ipv6 {
|
||||||
|
export filter {{ peer.filters.export }};
|
||||||
|
import filter {{ peer.filters.import }};
|
||||||
|
};
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
# OSPF
|
||||||
|
protocol ospf v3 {
|
||||||
|
area 0 {
|
||||||
|
interface "dummy0" {
|
||||||
|
stub;
|
||||||
|
};
|
||||||
|
|
||||||
|
interface "wg*" { };
|
||||||
|
interface "tun*" { };
|
||||||
|
};
|
||||||
|
|
||||||
|
ipv6 {
|
||||||
|
import all;
|
||||||
|
export filter ospf_export;
|
||||||
|
};
|
||||||
|
}
|
11
roles/cockpit/tasks/cockpit.yml
Normal file
11
roles/cockpit/tasks/cockpit.yml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
---
|
||||||
|
- name: "Install cockpit"
|
||||||
|
pacman:
|
||||||
|
name: "cockpit"
|
||||||
|
state: "present"
|
||||||
|
|
||||||
|
- name: "Enable cockpit service"
|
||||||
|
service:
|
||||||
|
name: "cockpit"
|
||||||
|
enabled: "true"
|
||||||
|
state: "started"
|
2
roles/cockpit/tasks/main.yml
Normal file
2
roles/cockpit/tasks/main.yml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
---
|
||||||
|
- include_tasks: "cockpit.yml"
|
3
roles/handlers/handlers/bird.yml
Normal file
3
roles/handlers/handlers/bird.yml
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
- name: "reconfigure bird"
|
||||||
|
command: "birdc configure"
|
4
roles/handlers/handlers/main.yml
Normal file
4
roles/handlers/handlers/main.yml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
---
|
||||||
|
- import_tasks: "nginx.yml"
|
||||||
|
- import_tasks: "systemd.yml"
|
||||||
|
- import_tasks: "bird.yml"
|
10
roles/handlers/handlers/nginx.yml
Normal file
10
roles/handlers/handlers/nginx.yml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
---
|
||||||
|
- name: "start nginx"
|
||||||
|
service:
|
||||||
|
name: "nginx"
|
||||||
|
state: "started"
|
||||||
|
|
||||||
|
- name: "reload nginx"
|
||||||
|
service:
|
||||||
|
name: "nginx"
|
||||||
|
state: "reloaded"
|
5
roles/handlers/handlers/systemd.yml
Normal file
5
roles/handlers/handlers/systemd.yml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
- name: "systemd daemon reload"
|
||||||
|
systemd:
|
||||||
|
daemon_reload: "yes"
|
||||||
|
|
6
roles/letsencrypt/files/certbot-renew.service
Normal file
6
roles/letsencrypt/files/certbot-renew.service
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
[Unit]
|
||||||
|
Description=LetsEncrypt renewal
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=/usr/bin/certbot renew --quiet --agree-tos --deploy-hook "systemctl reload nginx.service"
|
10
roles/letsencrypt/files/certbot-renew.timer
Normal file
10
roles/letsencrypt/files/certbot-renew.timer
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
[Unit]
|
||||||
|
Description=Twice daily renewal of LetsEncrypt certificates
|
||||||
|
|
||||||
|
[Timer]
|
||||||
|
OnCalendar=0/12:00:00
|
||||||
|
RandomizedDelaySec=1h
|
||||||
|
Persistent=true
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=timers.target
|
3
roles/letsencrypt/meta/main.yml
Normal file
3
roles/letsencrypt/meta/main.yml
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
dependencies:
|
||||||
|
- { role: handlers }
|
5
roles/letsencrypt/tasks/certbot.yml
Normal file
5
roles/letsencrypt/tasks/certbot.yml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
- name: "Install certbot"
|
||||||
|
pacman:
|
||||||
|
name: "certbot"
|
||||||
|
state: "present"
|
27
roles/letsencrypt/tasks/install_timers.yml
Normal file
27
roles/letsencrypt/tasks/install_timers.yml
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
---
|
||||||
|
- name: "Install certbot systemd service file"
|
||||||
|
copy:
|
||||||
|
owner: "root"
|
||||||
|
group: "root"
|
||||||
|
mode: "755"
|
||||||
|
src: "certbot-renew.service"
|
||||||
|
dest: "/etc/systemd/system/certbot-renew.service"
|
||||||
|
notify: "systemd daemon reload"
|
||||||
|
|
||||||
|
- name: "Install certbot systemd timer"
|
||||||
|
copy:
|
||||||
|
owner: "root"
|
||||||
|
group: "root"
|
||||||
|
mode: "755"
|
||||||
|
src: "certbot-renew.timer"
|
||||||
|
dest: "/etc/systemd/system/certbot-renew.timer"
|
||||||
|
notify: "systemd daemon reload"
|
||||||
|
|
||||||
|
- name: "Force systemd handlers run"
|
||||||
|
meta: "flush_handlers"
|
||||||
|
|
||||||
|
- name: "Enable certbot systemd timer"
|
||||||
|
systemd:
|
||||||
|
name: "certbot-renew.timer"
|
||||||
|
state: "started"
|
||||||
|
enabled: "true"
|
3
roles/letsencrypt/tasks/main.yml
Normal file
3
roles/letsencrypt/tasks/main.yml
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
- include_tasks: "certbot.yml"
|
||||||
|
- include_tasks: "install_timers.yml"
|
3
roles/nginx_server/defaults/main.yml
Normal file
3
roles/nginx_server/defaults/main.yml
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
domain_name: "as209616.net"
|
||||||
|
letsencrypt_email: "jesper@graffen.dk"
|
4
roles/nginx_server/meta/main.yml
Normal file
4
roles/nginx_server/meta/main.yml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
---
|
||||||
|
dependencies:
|
||||||
|
- { role: "handlers" }
|
||||||
|
- { role: "letsencrypt" }
|
2
roles/nginx_server/tasks/main.yml
Normal file
2
roles/nginx_server/tasks/main.yml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
---
|
||||||
|
- include_tasks: "nginx.yml"
|
57
roles/nginx_server/tasks/nginx.yml
Normal file
57
roles/nginx_server/tasks/nginx.yml
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
---
|
||||||
|
- name: "Install nginx"
|
||||||
|
pacman:
|
||||||
|
name: "nginx"
|
||||||
|
state: "present"
|
||||||
|
|
||||||
|
- name: "Enable and start nginx service"
|
||||||
|
service:
|
||||||
|
name: "nginx"
|
||||||
|
enabled: "yes"
|
||||||
|
state: "started"
|
||||||
|
|
||||||
|
- name: "Create nginx config directory"
|
||||||
|
file:
|
||||||
|
path: "/etc/nginx/conf.d"
|
||||||
|
state: "directory"
|
||||||
|
|
||||||
|
- name: "Create nginx vhost directory"
|
||||||
|
file:
|
||||||
|
path: "/etc/nginx/sites"
|
||||||
|
state: "directory"
|
||||||
|
|
||||||
|
- name: "Create certbot directory"
|
||||||
|
file:
|
||||||
|
path: "/usr/share/nginx/letsencrypt"
|
||||||
|
state: "directory"
|
||||||
|
|
||||||
|
- name: "Copy base nginx.conf"
|
||||||
|
template:
|
||||||
|
src: "nginx.conf.j2"
|
||||||
|
dest: "/etc/nginx/nginx.conf"
|
||||||
|
notify: "reload nginx"
|
||||||
|
|
||||||
|
- name: "Install nginx site for letsencrypt requests"
|
||||||
|
template:
|
||||||
|
src: "nginx-http.j2"
|
||||||
|
dest: "/etc/nginx/sites/http"
|
||||||
|
notify: "reload nginx"
|
||||||
|
|
||||||
|
- name: "Force all notified nginx handlers to enable letsencrypt"
|
||||||
|
meta: "flush_handlers"
|
||||||
|
|
||||||
|
- name: "Create letsencrypt certificate"
|
||||||
|
shell: "certbot certonly -n --webroot -w /usr/share/nginx/letsencrypt -m {{ letsencrypt_email }} --agree-tos -d {{ domain_name }}"
|
||||||
|
args:
|
||||||
|
creates: "/etc/letsencrypt/live/{{ domain_name }}"
|
||||||
|
|
||||||
|
- name: "Generate dhparams"
|
||||||
|
shell: "openssl dhparam -out /etc/nginx/dhparams.pem 2048"
|
||||||
|
args:
|
||||||
|
creates: "/etc/nginx/dhparams.pem"
|
||||||
|
|
||||||
|
- name: "Install nginx site config"
|
||||||
|
template:
|
||||||
|
src: templates/nginx-https.j2
|
||||||
|
dest: /etc/nginx/sites/https
|
||||||
|
notify: "reload nginx"
|
14
roles/nginx_server/templates/nginx-http.j2
Normal file
14
roles/nginx_server/templates/nginx-http.j2
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
# HTTP for LetsEncrypt
|
||||||
|
server {
|
||||||
|
listen [::]:80 default_server;
|
||||||
|
server_name {{ domain_name }};
|
||||||
|
|
||||||
|
location /.well-known/acme-challenge {
|
||||||
|
root /usr/share/nginx/letsencrypt;
|
||||||
|
try_files $uri $uri/ =404;
|
||||||
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
rewrite ^ https://{{ domain_name }}$request_uri? permanent;
|
||||||
|
}
|
||||||
|
}
|
37
roles/nginx_server/templates/nginx-https.j2
Normal file
37
roles/nginx_server/templates/nginx-https.j2
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
add_header X-Frame-Options SAMEORIGIN;
|
||||||
|
add_header X-Content-Type-Options nosniff;
|
||||||
|
add_header X-XSS-Protection "1; mode=block";
|
||||||
|
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; img-src 'self'; style-src 'self' 'unsafe-inline'; font-src 'self'; frame-src 'none'; object-src 'none'";
|
||||||
|
add_header Referrer-Policy "same-origin";
|
||||||
|
add_header Strict-Transport-Security "max-age=31536000";
|
||||||
|
|
||||||
|
server_tokens off;
|
||||||
|
|
||||||
|
# HTTPS server
|
||||||
|
#
|
||||||
|
server {
|
||||||
|
listen [::]:443 ssl http2 default;
|
||||||
|
server_name {{ domain_name }};
|
||||||
|
|
||||||
|
ssl_certificate /etc/letsencrypt/live/{{ domain_name }}/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/{{ domain_name }}/privkey.pem;
|
||||||
|
ssl_trusted_certificate /etc/letsencrypt/live/{{ domain_name }}/fullchain.pem;
|
||||||
|
|
||||||
|
ssl_session_cache shared:SSL:50m;
|
||||||
|
ssl_session_timeout 5m;
|
||||||
|
ssl_stapling on;
|
||||||
|
ssl_stapling_verify on;
|
||||||
|
|
||||||
|
ssl_protocols TLSv1.2;
|
||||||
|
ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
|
||||||
|
|
||||||
|
ssl_dhparam /etc/nginx/dhparams.pem;
|
||||||
|
ssl_prefer_server_ciphers on;
|
||||||
|
|
||||||
|
root /usr/share/nginx/{{ domain_name }};
|
||||||
|
index index.html index.htm;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ =404;
|
||||||
|
}
|
||||||
|
}
|
21
roles/nginx_server/templates/nginx.conf.j2
Normal file
21
roles/nginx_server/templates/nginx.conf.j2
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
worker_processes 4;
|
||||||
|
|
||||||
|
events {
|
||||||
|
worker_connections 768;
|
||||||
|
}
|
||||||
|
|
||||||
|
http {
|
||||||
|
sendfile on;
|
||||||
|
tcp_nopush on;
|
||||||
|
tcp_nodelay on;
|
||||||
|
keepalive_timeout 65;
|
||||||
|
types_hash_max_size 2048;
|
||||||
|
include /etc/nginx/mime.types;
|
||||||
|
default_type application/octet-stream;
|
||||||
|
|
||||||
|
gzip on;
|
||||||
|
gzip_disable "msie6";
|
||||||
|
|
||||||
|
include /etc/nginx/conf.d/*.conf;
|
||||||
|
include /etc/nginx/sites/*;
|
||||||
|
}
|
22
roles/playbook.yml
Normal file
22
roles/playbook.yml
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
---
|
||||||
|
- name: "Basic housekeeping"
|
||||||
|
hosts: "all"
|
||||||
|
become: "yes"
|
||||||
|
roles:
|
||||||
|
- "archvms_base"
|
||||||
|
|
||||||
|
- name: "Configure webservers"
|
||||||
|
hosts: "as209616_webservers"
|
||||||
|
become: "yes"
|
||||||
|
roles:
|
||||||
|
- "letsencrypt"
|
||||||
|
- "nginx_server"
|
||||||
|
- "website"
|
||||||
|
- "cockpit"
|
||||||
|
|
||||||
|
|
||||||
|
- name: "Configure Bird 2.0 Routers"
|
||||||
|
hosts: "routers"
|
||||||
|
become: "yes"
|
||||||
|
roles:
|
||||||
|
- { role: "bird", tags: "bird" }
|
18
roles/website/files/index.html
Normal file
18
roles/website/files/index.html
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Welcome to AS209616!</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
width: 35em;
|
||||||
|
margin: 0 auto;
|
||||||
|
font-family: Tahoma, Verdana, Arial, sans-serif;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Welcome to nginx!</h1>
|
||||||
|
<p>If you see this page, the nginx web server is successfully installed and
|
||||||
|
working. </p>
|
||||||
|
</body>
|
||||||
|
</html>
|
BIN
roles/website/files/site.tar.gz
Normal file
BIN
roles/website/files/site.tar.gz
Normal file
Binary file not shown.
2
roles/website/tasks/main.yml
Normal file
2
roles/website/tasks/main.yml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
---
|
||||||
|
- import_tasks: "website.yml"
|
11
roles/website/tasks/website.yml
Normal file
11
roles/website/tasks/website.yml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
- name: "Create vhost folder"
|
||||||
|
file:
|
||||||
|
path: "/usr/share/nginx/{{ domain_name }}"
|
||||||
|
state: "directory"
|
||||||
|
|
||||||
|
- name: "Unarchive website to vhost root"
|
||||||
|
unarchive:
|
||||||
|
src: "files/site.tar.gz"
|
||||||
|
dest: "/usr/share/nginx/{{ domain_name }}"
|
Loading…
Reference in a new issue