added first roles and playbook
This commit is contained in:
@@ -44,7 +44,7 @@
|
||||
|
||||
[servers]
|
||||
192.168.0.28
|
||||
192.168.0.99
|
||||
##192.168.0.99
|
||||
|
||||
[all:vars]
|
||||
ansible_python_interpreter=/usr/bin/python3
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>{{ item['title'] }}</title>
|
||||
<style type="text/css">
|
||||
h1 {
|
||||
font-family: Verdana, sans-serif;
|
||||
font-size: 14pt;
|
||||
}
|
||||
p, ul, li, td {
|
||||
font-family: Verdana, sans-serif;
|
||||
font-size: 9pt;
|
||||
line-height: 175%;
|
||||
}
|
||||
a {
|
||||
color: rgb(31, 83, 81);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<table cellspacing="0" cellpadding="0" border="0" width="100%" height="100%">
|
||||
<tr height="100%">
|
||||
<td height="100%" width="100%" align="center">
|
||||
<table cellspacing="0" cellpadding="0" border="0" width="830">
|
||||
<tr>
|
||||
<td><img src="data:image/gif;base64,R0lGODlhGQAZAPQeAOvr6/Dw8Nzc3PX19eTk5Pb29vLy8vf39/Hx8eXl5fT09PPz8+3t7ezs7Pj4+Pr6+v39/d/f3+np6fn5+e/v7+fn5+Dg4N3d3fv7++Li4ubm5ujo6Pz8/P///wAAAAAAACH5BAUAAB4ALAAAAAAZABkAAAWgoAdBHPZMznEUxeC+8Dua06oshoEgQe//PYjJUVAYAhRGA8BsOp2cB3ERYAAkFU2CwO16u5hJgdrYJDKWyEXAbrvbj4Mi0OjY7/h8XmxgbPSAgA5zAAmBh3cHCxQSGYiIB30VFo+HBQYNGhGVgQUIhRecgAOfBAKiegMBAKaoeaqsp653sK2zdrWyt7m3uKu2u7+6s7y9xcGxvR3HxMLKIQA7" /></td>
|
||||
<td style="background-image:url('data:image/gif;base64,R0lGODdhKQAPAPIAAOTk5PX19dzc3PDw8Ovr6////wAAAAAAACwAAAAAKQAPAAADOBi63P6wjUmrvThbwrv/YCh+QGmeaKquqOC+cCzPdFzceK7vfO//wKBwSCwaj8ikcslsOp/QaC4BADs=');background-repeat:repeat-x;" colspan="2"> </td>
|
||||
<td><img src="data:image/gif;base64,R0lGODdhGQAZAPUAAOvr6+Tk5Nzc3PDw8PX19cvLy9PT0/b29uXl5e3t7ezs7PLy8uLi4vf399/f3/T09Ofn5+/v7/j4+Onp6dXV1fPz8+bm5vHx8fr6+uDg4NnZ2d3d3ejo6Pn5+c/Pz83NzdTU1NbW1tLS0tvb2/v7+8zMzN7e3v39/fz8/P///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAGQAZAAAGo0CCcEgsHg6NhqSDIaFOg6h0Or1cFovKA8kkAb7gsBigSEQGi60EE2i733CEBTIBJAaVg0TA7/v/Gw4ZDAgcCngHKYqLjI2NDBCHD46UlCYMHAkLlZyLGg4IAAOdnRQjDBMRpJwiGhkQCauVHiEOFgqylB8UG6G5jiUgAgEAv40FBsPFxovIyszNycTQis7T1NbL0NnUKdzY0trM39vh3eTj4UEAOw==" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="background-image:url('data:image/gif;base64,R0lGODdhIgAhAPIAAPDw8PX19dzc3OTk5Ovr6////wAAAAAAACwAAAAAIgAhAAADUBhAI/UwykmLYq7qbVfj4HR9YdlhZjlmKbe24Atv8lzVtuixuYT3kB/wRBoGd8aIELjsNXNPW3Q2hVVb11TWtFUhk49uSBz7gskucxJNUxsTADs=');background-repeat:repeat-y;"> </td>
|
||||
<td height="50" colspan="2"> </td>
|
||||
<td style="background-image:url('data:image/gif;base64,R0lGODdhIgAhAPIAANzc3OTk5MvLy9PT0+vr6////wAAAAAAACwAAAAAIgAhAAADUVi63P5FDBAIvFhJarNvW/WN2iSSX9ihmcp67ovFMkTXzo0z+l5yvpxpFfydikZisedj7pw4aE0qo76sLCxKS+KOvKkhcgGGiceR87jcUiNVCQA7');background-position:right;background-repeat:repeat-y;"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="background-image:url('data:image/gif;base64,R0lGODdhIgAhAPIAAPDw8PX19dzc3OTk5Ovr6////wAAAAAAACwAAAAAIgAhAAADUBhAI/UwykmLYq7qbVfj4HR9YdlhZjlmKbe24Atv8lzVtuixuYT3kB/wRBoGd8aIELjsNXNPW3Q2hVVb11TWtFUhk49uSBz7gskucxJNUxsTADs=');background-repeat:repeat-y;"> </td>
|
||||
<td valign="top" width="80"><img style="margin-top:-15px;margin-right:25px;margin-left:8px;" src="data:image/gif;base64,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" /></td>
|
||||
<td width="750" style="padding-right:50px;">
|
||||
{{ item['message'] }}
|
||||
</td>
|
||||
<td style="background-image:url('data:image/gif;base64,R0lGODdhIgAhAPIAANzc3OTk5MvLy9PT0+vr6////wAAAAAAACwAAAAAIgAhAAADUVi63P5FDBAIvFhJarNvW/WN2iSSX9ihmcp67ovFMkTXzo0z+l5yvpxpFfydikZisedj7pw4aE0qo76sLCxKS+KOvKkhcgGGiceR87jcUiNVCQA7');background-position:right;background-repeat:repeat-y;"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="background-image:url('data:image/gif;base64,R0lGODdhIgAhAPIAAPDw8PX19dzc3OTk5Ovr6////wAAAAAAACwAAAAAIgAhAAADUBhAI/UwykmLYq7qbVfj4HR9YdlhZjlmKbe24Atv8lzVtuixuYT3kB/wRBoGd8aIELjsNXNPW3Q2hVVb11TWtFUhk49uSBz7gskucxJNUxsTADs=');background-repeat:repeat-y;"> </td>
|
||||
<td height="40" colspan="2"> </td>
|
||||
<td style="background-image:url('data:image/gif;base64,R0lGODdhIgAhAPIAANzc3OTk5MvLy9PT0+vr6////wAAAAAAACwAAAAAIgAhAAADUVi63P5FDBAIvFhJarNvW/WN2iSSX9ihmcp67ovFMkTXzo0z+l5yvpxpFfydikZisedj7pw4aE0qo76sLCxKS+KOvKkhcgGGiceR87jcUiNVCQA7');background-position:right;background-repeat:repeat-y;"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="data:image/gif;base64,R0lGODdhGQAZAPUAAOvr6+Tk5Nzc3PDw8PX19cvLy9PT0/b29uXl5e3t7ezs7PLy8uLi4vf399/f3/T09Ofn5+/v7/j4+Onp6dXV1fPz8+bm5vHx8fr6+uDg4NnZ2d3d3ejo6Pn5+c/Pz83NzdTU1NbW1tLS0tvb2/v7+8zMzN7e3v39/fz8/P///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAGQAZAAAGokDCABAQpI7IpFIpJBqX0GWzGK0ip09rFKutcrvQL5g5pI7JzjParD6K2291/DwfEy7p9vGAR2z0ewsKFg6AKQ0LCRAZhg0VERMMhhIPQwiGHQeJHAwmGhQiHh8lBaWmp6UYDZUKEAwOIxohFCAGtre4tiSZFQMKHAgMGQ4bAsbHyMcoGBIHvQkAExAWCAHW19jXJyTMBw8LAxEJCgDl5ufnQQA7" /></td>
|
||||
<td style="background-image:url('data:image/gif;base64,R0lGODdhKQAPAPIAAMvLy9PT0+Tk5Nzc3Ovr6////wAAAAAAACwAAAAAKQAPAAADOFi63P4wykmrvTjrzbv/YCiOJAOcaKqubKsGcCzPdG3PQ67vfO//PIFwSCwaj8giYclsOp/QqDMBADs=');background-position:bottom;background-repeat:repeat-x;" colspan="2"> </td>
|
||||
<td><img src="data:image/gif;base64,R0lGODdhGQAZAPUAAOvr6+Tk5Nzc3MvLy9PT0+Li4vDw8NXV1dnZ2eXl5e3t7ezs7N/f3+fn59vb293d3dLS0s/Pz+/v7/Ly8unp6dbW1szMzM3Nzebm5uDg4NTU1Ojo6PT09Pb29t7e3vPz8/j4+Pr6+v///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAGQAZAAAGn0CRcEgsFgcEQQBgbDaRSqZzKoQuqVSrFPtMXrndKDj8HRO15qN3mxah29U1PC6ev+H3tkVTh18ODwlsaREVDBgLcyIQCBkNCooHDgUUEooIDIIGA5ydnp4WFxEQBwgeBRsKEwSsra6uGgcVCA4MBQ0LBhwCvL2+vw8MGQUJG7kfHQHKy8zNCRgNFAAKBsggANjZ2tsACwoSBhMcHSAhQQA7" /></td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,6 @@
|
||||
error_pages:
|
||||
- { type: "502", title: "Error 502: Bad Gateway", message: "<h1>Error 502: Bad Gateway</h1><p>Most of the time, a 502 error occurs because the server is too busy or because there's maintenance being performed on it.</p><p><b>Please check back in a few minutes.</b></p>" }
|
||||
- { type: "503", title: "Error 503: Service unavailable", message: "<h1>Error 503: Service unavailable</h1><p>Most of the time, a 503 error occurs because there's maintenance being performed.</p><p><b>Please check back in a few minutes.</b></p>" }
|
||||
- { type: "401", title: "Error 401: Unauthorized", message: "<h1>Error 401: Unauthorized</h1><p>You are not allowed to access this page.</p><p><b>Please log in to access this page.</b></p>" }
|
||||
- { type: "403", title: "Error 403: Forbidden", message: "<h1>Error 403: Forbidden</h1><p>You don't have permission to access this page or directory on this server</p>" }
|
||||
- { type: "404", title: "Error 404: File not found", message: "<h1>Error 404: File not found</h1><p>The requested URL was not found on this server. Maybe it was a valid URL once, but the file/directory has been removed.</p><p><b>Please double-check the URL and try again.</b></p>" }
|
||||
@@ -0,0 +1,11 @@
|
||||
add_header Content-Security-Policy "default-src 'none'; font-src 'self'; script-src 'self' 'sha256-2XPtiIriLCRC9BnusBjoTHsfh5zn7F+h7Cr17XwSN50='; img-src * data:; object-src 'none'; style-src 'self' 'sha256-PEo9RAB0C7Pw0EzsgS+HuVOHFPZRr93dZNJ9mYzz95A=' 'sha256-lrhGtO62QsLjBNsk1WGpvRZbHmXYMG/CmjhMFhLDJpg=' 'sha256-4SHcbKIX1Fx5rhlottWqqHggM5MSJz+xg9uwwq8UK74=' 'sha256-bQfd5MwpJ1ZxnVh373acxlqXQ8VwM88QhEHNuQ0ppNg=' 'sha256-yIJ6JcbosmUis6IDdnDV7NU2qPkU/1KUJHRwj44Q32o='; frame-src 'self'; connect-src 'self'; form-action 'self'; base-uri 'self';frame-ancestors 'self'; report-uri https://searx.report-uri.com/r/d/csp/enforce;";
|
||||
add_header X-Content-Security-Policy "default-src 'none'; font-src 'self'; script-src 'self' 'sha256-2XPtiIriLCRC9BnusBjoTHsfh5zn7F+h7Cr17XwSN50='; img-src * data:; object-src 'none'; style-src 'self' 'sha256-PEo9RAB0C7Pw0EzsgS+HuVOHFPZRr93dZNJ9mYzz95A=' 'sha256-lrhGtO62QsLjBNsk1WGpvRZbHmXYMG/CmjhMFhLDJpg=' 'sha256-4SHcbKIX1Fx5rhlottWqqHggM5MSJz+xg9uwwq8UK74=' 'sha256-bQfd5MwpJ1ZxnVh373acxlqXQ8VwM88QhEHNuQ0ppNg=' 'sha256-yIJ6JcbosmUis6IDdnDV7NU2qPkU/1KUJHRwj44Q32o='; frame-src 'self'; connect-src 'self'; form-action 'self'; base-uri 'self';frame-ancestors 'self'; report-uri https://https://searx.report-uri.com/r/d/csp/enforce;";
|
||||
add_header X-WebKit-CSP "default-src 'none'; font-src 'self'; script-src 'self' 'sha256-2XPtiIriLCRC9BnusBjoTHsfh5zn7F+h7Cr17XwSN50='; img-src * data:; object-src 'none'; style-src 'self' 'sha256-PEo9RAB0C7Pw0EzsgS+HuVOHFPZRr93dZNJ9mYzz95A=' 'sha256-lrhGtO62QsLjBNsk1WGpvRZbHmXYMG/CmjhMFhLDJpg=' 'sha256-4SHcbKIX1Fx5rhlottWqqHggM5MSJz+xg9uwwq8UK74=' 'sha256-bQfd5MwpJ1ZxnVh373acxlqXQ8VwM88QhEHNuQ0ppNg=' 'sha256-yIJ6JcbosmUis6IDdnDV7NU2qPkU/1KUJHRwj44Q32o='; frame-src 'self'; connect-src 'self'; base-uri 'self'; form-action 'self';frame-ancestors 'self'; report-uri https://searx.report-uri.com/r/d/csp/enforce;";
|
||||
|
||||
add_header Expect-CT "max-age=0; report-uri=https://searx.report-uri.com/r/d/ct/reportOnly;";
|
||||
add_header Expect-Staple "max-age=0; report-uri=https://searx.report-uri.com/r/d/staple/reportOnly";
|
||||
}
|
||||
|
||||
location /stats {
|
||||
rewrite / https://stats.searx.xyz;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
[nginx_hosts]
|
||||
62.75.247.110
|
||||
@@ -0,0 +1,81 @@
|
||||
- hosts: scn.21x9.org
|
||||
|
||||
tasks:
|
||||
|
||||
- include_vars: vhosts.yml
|
||||
- include_vars: error_pages.yml
|
||||
|
||||
- name: "Install nginx"
|
||||
apt: name=nginx state=present
|
||||
notify:
|
||||
- "Restart nginx"
|
||||
|
||||
- name: "Generate global config"
|
||||
template:
|
||||
src: ./nginx.j2
|
||||
dest: /etc/nginx/nginx.conf
|
||||
owner: root
|
||||
group: root
|
||||
mode: 0644
|
||||
notify:
|
||||
- "Restart nginx"
|
||||
|
||||
- name: "Generate default config"
|
||||
template:
|
||||
src: ./default.j2
|
||||
dest: /etc/nginx/sites-available/default.conf
|
||||
owner: root
|
||||
group: root
|
||||
mode: 0644
|
||||
notify:
|
||||
- "Restart nginx"
|
||||
|
||||
- name: "Generate vhosts config"
|
||||
template:
|
||||
src: ./vhosts.j2
|
||||
dest: /etc/nginx/sites-available/{{ item['name'] }}.conf
|
||||
owner: root
|
||||
group: root
|
||||
mode: 0644
|
||||
notify:
|
||||
- "Restart nginx"
|
||||
with_items:
|
||||
- "{{ nginx_vhosts }}"
|
||||
|
||||
- name: "Create symlinks"
|
||||
file:
|
||||
src: /etc/nginx/sites-available/{{ item['name'] }}.conf
|
||||
dest: /etc/nginx/sites-enabled/{{ item['name'] }}.conf
|
||||
state: link
|
||||
with_items:
|
||||
- {name: 'default'}
|
||||
- "{{ nginx_vhosts }}"
|
||||
register: managed_files
|
||||
|
||||
- set_fact:
|
||||
nginx_confs: "{{ managed_files.results|selectattr('dest', 'string')|map(attribute='dest')|list + managed_files.results|selectattr('path', 'string')|map(attribute='path')|select|list }}"
|
||||
|
||||
- shell: ls -d -1 /etc/nginx/sites-enabled/*
|
||||
register: contents
|
||||
|
||||
- name: "Remove unmanaged symlinks"
|
||||
file: path={{ item }} state=absent
|
||||
with_items: "{{ contents.stdout_lines }}"
|
||||
when: nginx_confs and item not in nginx_confs
|
||||
notify:
|
||||
- "Restart nginx"
|
||||
|
||||
- name: "Generate error pages"
|
||||
template:
|
||||
src: ./error_page.j2
|
||||
dest: /var/www/html/{{ item['type'] }}.html
|
||||
owner: root
|
||||
group: root
|
||||
mode: 0644
|
||||
with_items:
|
||||
- "{{ error_pages }}"
|
||||
|
||||
handlers:
|
||||
|
||||
- name: "Restart nginx"
|
||||
shell: /usr/sbin/nginx -t && /etc/init.d/nginx reload
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
|
||||
- name: install nginx
|
||||
apt: name=nginx state=latest
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
|
||||
- name: apt update the server
|
||||
apt: update_cache=yes
|
||||
@@ -0,0 +1,188 @@
|
||||
###############################################################################
|
||||
### {{ item['name'] }}
|
||||
###############################################################################
|
||||
|
||||
server {
|
||||
{% if 'ip' in item %}
|
||||
listen {{ item['ip']}}:80;
|
||||
{% else %}
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
{% endif %}
|
||||
{% if item['alias'] != "none" %}
|
||||
server_name {{ item['name'] }}
|
||||
{{ item['alias'] }};
|
||||
{% else %}
|
||||
server_name {{ item['name'] }};
|
||||
{% endif %}
|
||||
|
||||
{% if 'root' in item %}
|
||||
root {{ item['root'] }};
|
||||
{% else %}
|
||||
root /var/www/html;
|
||||
{% endif %}
|
||||
|
||||
# For letsencrypt.sh
|
||||
location /.well-known/acme-challenge/ {
|
||||
root /var/www/html/;
|
||||
try_files $uri $uri/ =404;
|
||||
}
|
||||
|
||||
# Redirect all HTTP requests to HTTPS with a 301 Moved Permanently response.
|
||||
return 301 https://{{ item['name'] }}$request_uri;
|
||||
|
||||
access_log off;
|
||||
error_log syslog,tag=nginx,severity=error,facility=local7;
|
||||
}
|
||||
|
||||
server {
|
||||
{% if 'ip' in item %}
|
||||
listen {{ item['ip']}}:443 ssl{% if 'spdy' in item %} http2{% endif %};
|
||||
{% else %}
|
||||
listen 443 ssl{% if 'spdy' in item %} http2{% endif %};
|
||||
listen [::]:443 ssl{% if 'spdy' in item %} http2{% endif %};
|
||||
{% endif %}
|
||||
|
||||
{% if item['alias'] != "none" %}
|
||||
server_name {{ item['name'] }}
|
||||
{{ item['alias'] }};
|
||||
{% else %}
|
||||
server_name {{ item['name'] }};
|
||||
{% endif %}
|
||||
|
||||
gzip off;
|
||||
|
||||
{% if 'ssl' in item %}
|
||||
ssl_certificate /etc/letsencrypt.sh/certs/{{ item['ssl'] }}/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt.sh/certs/{{ item['ssl'] }}/privkey.pem;
|
||||
#ssl_trusted_certificate /etc/letsencrypt.sh/certs/{{ item['ssl'] }}/fullchain.pem;
|
||||
{% else %}
|
||||
ssl_certificate /etc/letsencrypt.sh/certs/{{ item['name'] }}/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt.sh/certs/{{ item['name'] }}/privkey.pem;
|
||||
#ssl_trusted_certificate /etc/letsencrypt.sh/certs/{{ item['name'] }}/fullchain.pem;
|
||||
{% endif %}
|
||||
ssl_stapling on;
|
||||
ssl_stapling_verify on;
|
||||
ssl_dhparam /etc/nginx/dhparam.pem;
|
||||
|
||||
ssl_session_cache shared:SSL:50m;
|
||||
ssl_session_timeout 10m;
|
||||
ssl_session_tickets off;
|
||||
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_prefer_server_ciphers on;
|
||||
ssl_ciphers 'AES256+EECDH:AES256+EDH:!aNULL';
|
||||
ssl_ecdh_curve secp384r1;
|
||||
|
||||
resolver 8.8.8.8 8.8.4.4 valid=300s;
|
||||
resolver_timeout 5s;
|
||||
|
||||
server_tokens off;
|
||||
|
||||
access_log /var/log/nginx/{{ item['name'] }}.log extended;
|
||||
error_log /var/log/nginx/{{ item['name'] }}.log;
|
||||
|
||||
{% if 'root' in item %}
|
||||
root {{ item['root'] }};
|
||||
{% else %}
|
||||
root /var/www/html;
|
||||
{% endif %}
|
||||
|
||||
# For letsencrypt.sh
|
||||
location /.well-known/acme-challenge/ {
|
||||
root /var/www/html/;
|
||||
try_files $uri $uri/ =404;
|
||||
}
|
||||
|
||||
location ~ /\.ht {
|
||||
deny all;
|
||||
}
|
||||
|
||||
{% for error in error_pages %}
|
||||
{% if error['type'] == '401' %}
|
||||
error_page {{ error['type'] }} /{{ error['type'] }}.html;
|
||||
{% else %}
|
||||
error_page {{ error['type'] }} /{{ error['type'] }}.html;
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% for error in error_pages %}
|
||||
location /{{ error['type'] }}.html {
|
||||
root /var/www/html;
|
||||
internal;
|
||||
break;
|
||||
}
|
||||
{% endfor %}
|
||||
|
||||
location / {
|
||||
{% if 'maintenance' in item %}
|
||||
set $maintenance true;
|
||||
{% else %}
|
||||
set $maintenance false;
|
||||
{% endif %}
|
||||
|
||||
if (-f $document_root/maintenance.html) {
|
||||
set $maintenance true;
|
||||
}
|
||||
if ($maintenance = true) {
|
||||
rewrite / /503.html;
|
||||
}
|
||||
|
||||
{% if 'port' in item %}
|
||||
proxy_pass http://localhost:{{ item['port'] }}/;
|
||||
|
||||
proxy_redirect off;
|
||||
proxy_intercept_errors on;
|
||||
proxy_read_timeout 86400;
|
||||
proxy_ignore_client_abort on;
|
||||
proxy_connect_timeout 120s;
|
||||
|
||||
proxy_buffer_size 128k;
|
||||
proxy_buffers 4 256k;
|
||||
proxy_busy_buffers_size 256k;
|
||||
|
||||
proxy_headers_hash_max_size 512;
|
||||
proxy_buffering on;
|
||||
proxy_cache_bypass $http_pragma $http_authorization $cookie_nocache;
|
||||
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Scheme $scheme;
|
||||
|
||||
proxy_hide_header Strict-Transport-Security;
|
||||
proxy_hide_header Public-Key-Pins;
|
||||
proxy_hide_header Content-Security-Policy;
|
||||
proxy_hide_header X-Content-Security-Policy;
|
||||
proxy_hide_header X-WebKit-CSP;
|
||||
proxy_hide_header X-Content-Type-Options;
|
||||
proxy_hide_header X-XSS-Protection;
|
||||
proxy_hide_header X-Frame-Options;
|
||||
proxy_hide_header Alternate-Protocol;
|
||||
proxy_hide_header X-Powered-By;
|
||||
|
||||
add_header Front-End-Https on;
|
||||
{% endif %}
|
||||
|
||||
{% if 'hsts' in item %}
|
||||
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
|
||||
{% endif %}
|
||||
{% if 'hpkp' in item %}
|
||||
add_header Public-Key-Pins "pin-sha256=\"YLh1dUR9y6Kja30RrAn7JKnbQG/uEtLMkBgFF2Fuihg=\"; pin-sha256=\"sRHdihwgkaib1P1gxX8HFszlD+7/gTfNvuAybgLPNis=\"; pin-sha256=\"dd9ClLS4xSTx8j2dH5/hjS6dPXTkzpzDcKeEX+3J74E=\"; pin-sha256=\"NO6gHdYxKGz47EYVvoXpJhxY3RXfoM1O56gPrOGmrg8=\"; max-age=7776000; includeSubDomains;";
|
||||
{% endif %}
|
||||
{% if 'security' in item %}
|
||||
add_header X-Frame-Options "sameorigin";
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
add_header X-Content-Type-Options "nosniff";
|
||||
{% endif %}
|
||||
{% if 'noref' in item %}
|
||||
add_header Referrer-Policy "no-referrer, strict-origin-when-cross-origin";
|
||||
{% endif %}
|
||||
|
||||
{% if 'extra' in item %}
|
||||
{% include item['extra'] %}
|
||||
{% else %}
|
||||
}
|
||||
{% endif %}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
nginx_vhosts:
|
||||
- { name: "21x9.org", alias: "www.21x9.org", port: "8000", extra: 'wordpress.j2', hsts: "on", hpkp: "on", security: "on", noref: "on", spdy: "on" }
|
||||
- { name: "legacy.21x9.org", alias: "www.legacy.21x9.org", port: "8002", extra: 'legacy.j2', hsts: "off", hpkp: "off", security: "off", noref: "off", ip: "1.2.3.4" }
|
||||
- { name: "searx.xyz", alias: "www.searx.xyz ipv4.searx.xyz ipv6.searx.xyz", port: "8888", extra: 'searx.j2', hsts: "on", hpkp: "on", security: "on", noref: "on", spdy: "on" }
|
||||
- { name: "stats.searx.xyz", alias: "none", hsts: "on", hpkp: "on", security: "on", noref: "on", spdy: "on", root: "/var/www/html/stats/" }
|
||||
- { name: "pukiyama-kakuzo.com", alias: "www.pukiyama-kakuzo.com", hsts: "on", hpkp: "on", security: "on", noref: "on", spdy: "on", root: "/var/www/html/pukiyama-kakuzo/" }
|
||||
@@ -0,0 +1,69 @@
|
||||
# pihole raspberry pi ansible role
|
||||
|
||||
Role installs and configures Pihole https://pi-hole.net/ with unattentded setup
|
||||
|
||||
Documents relating to pi-hole are at https://docs.pi-hole.net/
|
||||
|
||||
## Requirements
|
||||
User with sudo access to the machine.
|
||||
|
||||
other [prerequisites](https://docs.pi-hole.net/main/prerequisites/)
|
||||
|
||||
### Required Variables
|
||||
#### pihole_setupvars_webpassword
|
||||
You will need to generate a admin password for the `pihole_setupvars_webpassword` variable, password is hashed with sha256 twice. You can genearte a password with the following shell command.
|
||||
|
||||
With the password in a file (recommended).
|
||||
```shell
|
||||
echo -n $(cat ~/piholepass.word) | sha256sum | awk '{printf "%s", $1}' | sha256sum
|
||||
```
|
||||
|
||||
With the password in shell command (not recommended)
|
||||
```shell
|
||||
echo -n notsosecretpassword | sha256sum | awk '{printf "%s", $1}' | sha256sum
|
||||
```
|
||||
|
||||
recommended to store this variable in ansible vault.
|
||||
|
||||
#### pihole_setupvars_ipv4_address
|
||||
IPv4 adress of the pihole
|
||||
|
||||
#### pihole_setupvars_pihole_dns_1/2
|
||||
DNS servers you want the pihole to use
|
||||
|
||||
##### DNS
|
||||
Alternative DNS Providers
|
||||
```yaml
|
||||
Google: https://developers.google.com/speed/public-dns
|
||||
- 8.8.8.8
|
||||
- 8.8.4.4
|
||||
|
||||
OpenDNS: https://use.opendns.com/
|
||||
- 208.67.222.222
|
||||
- 208.67.220.220
|
||||
|
||||
Cloudflare: https://1.1.1.1/dns/
|
||||
- 1.1.1.1
|
||||
- 1.0.0.1
|
||||
```
|
||||
|
||||
## Role Variables
|
||||
[defaults/main.yml](defaults/main.yml) for default values
|
||||
|
||||
## Example Playbook
|
||||
```yaml
|
||||
---
|
||||
- name: pihole
|
||||
hosts: pi
|
||||
strategy: free
|
||||
become_method: sudo
|
||||
become: yes
|
||||
gather_facts: yes
|
||||
vars:
|
||||
pihole_setupvars_ipv4_address: 192.168.1.100
|
||||
pihole_setupvars_webpassword: 35030714f1136486a612d7014b739a6c7ef3be589bb14b14a3d01f521dd7ef18
|
||||
pihole_setupvars_pihole_dns_1: 1.1.1.1
|
||||
pihole_setupvars_pihole_dns_2: 1.0.0.1
|
||||
roles:
|
||||
- zfuller.pihole
|
||||
```
|
||||
@@ -0,0 +1,37 @@
|
||||
---
|
||||
# task variables
|
||||
pihole_repo: https://github.com/pi-hole/pi-hole.git
|
||||
pihole_repo_depth: 1
|
||||
pihole_user: pihole
|
||||
pihole_group: pihole
|
||||
pihole_directory: "/home/{{ pihole_user }}/pihole"
|
||||
pihole_branch: "master"
|
||||
pihole_etc_dir: /etc/pihole/
|
||||
pihole_bin_path: /usr/local/bin/pihole
|
||||
pihole_update: true
|
||||
pihole_reinstall: false
|
||||
|
||||
## setupVars.conf
|
||||
pihole_setupvars_pihole_interface: "eth0"
|
||||
pihole_setupvars_ipv4_address:
|
||||
pihole_setupvars_ipv6_address:
|
||||
pihole_setupvars_query_logging: "true"
|
||||
pihole_setupvars_install_web_server: "true"
|
||||
pihole_setupvars_install_web_interface: "true"
|
||||
pihole_setupvars_lighttpd_enabled: "true"
|
||||
pihole_setupvars_webpassword:
|
||||
pihole_setupvars_blocking_enabled: "true"
|
||||
pihole_setupvars_pihole_dns_1: 8.8.8.8
|
||||
pihole_setupvars_pihole_dns_2:
|
||||
pihole_setupvars_dns_fqdn_required: "true"
|
||||
pihole_setupvars_dns_bogus_priv: "true"
|
||||
pihole_setupvars_dnssec: "true"
|
||||
pihole_setupvars_conditional_forwarding: "false"
|
||||
pihole_setupvars_conditional_forwarding_ip:
|
||||
pihole_setupvars_conditional_forwarding_domain:
|
||||
pihole_setupvars_conditional_forwarding_reverse:
|
||||
pihole_setupvars_dnsmasq_listening: "single"
|
||||
pihole_setupvars_admin_email:
|
||||
pihole_setupvars_weblayout: "boxed"
|
||||
pihole_setupvars_webtheme: "default-dark"
|
||||
pihole_setupvars_rev_server: "false"
|
||||
@@ -0,0 +1 @@
|
||||
{install_date: 'Fri Nov 27 08:26:14 2020', version: master}
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
galaxy_info:
|
||||
author: zfuller
|
||||
description: Simple role to install and configure pihole
|
||||
issue_tracker_url: https://github.com/zfuller/pihole/issues
|
||||
license: GPLv2
|
||||
min_ansible_version: 2.4
|
||||
platforms:
|
||||
- name: Fedora
|
||||
versions:
|
||||
- 31
|
||||
- 32
|
||||
- name: CentOS
|
||||
versions:
|
||||
- 7
|
||||
- 8
|
||||
- name: Debian
|
||||
versions:
|
||||
- buster
|
||||
- stretch
|
||||
- name: Ubuntu
|
||||
versions:
|
||||
- xenial
|
||||
- bionic
|
||||
- focal
|
||||
galaxy_tags:
|
||||
- pihole
|
||||
- raspberrypi
|
||||
@@ -0,0 +1,99 @@
|
||||
---
|
||||
- name: ensure git
|
||||
package:
|
||||
name: git
|
||||
state: present
|
||||
|
||||
- name: check for existing installation of pihole
|
||||
stat:
|
||||
path: "{{ pihole_bin_path }}"
|
||||
register: pihole_bin
|
||||
|
||||
- name: install pihole
|
||||
block:
|
||||
- name: ensure pihole group exists for pi user
|
||||
group:
|
||||
name: "{{ pihole_group }}"
|
||||
state: present
|
||||
|
||||
- name: create pihole user
|
||||
user:
|
||||
name: "{{ pihole_user }}"
|
||||
comment: pihole
|
||||
groups: "{{ pihole_group }}"
|
||||
|
||||
- name: Ensure pihole destination exists
|
||||
stat:
|
||||
path: "{{ pihole_directory }}"
|
||||
register: pihole_dir
|
||||
|
||||
- name: making pihole git directory
|
||||
file:
|
||||
path: "{{ pihole_directory }}"
|
||||
state: directory
|
||||
mode: 0755
|
||||
owner: "{{ pihole_user }}"
|
||||
group: "{{ pihole_group }}"
|
||||
when:
|
||||
- pihole_dir.stat.isdir is not defined
|
||||
|
||||
- name: cloning pihole
|
||||
git:
|
||||
repo: "{{ pihole_repo }}"
|
||||
dest: "{{ pihole_directory }}"
|
||||
depth: "{{ pihole_repo_depth }}"
|
||||
version: "{{ pihole_branch }}"
|
||||
become_user: "{{ pihole_user }}"
|
||||
become: true
|
||||
|
||||
- name: check if pihole etc dir exists
|
||||
stat:
|
||||
path: "{{ pihole_etc_dir }}"
|
||||
register: pi_etc_dir
|
||||
|
||||
- name: making pihole etc directory
|
||||
file:
|
||||
path: "{{ pihole_etc_dir }}"
|
||||
state: directory
|
||||
mode: 0755
|
||||
when:
|
||||
- not pi_etc_dir.stat.exists
|
||||
|
||||
- name: pushing config file setupVars
|
||||
template:
|
||||
src: templates/setupVars.conf.j2
|
||||
dest: "{{ pihole_etc_dir }}/setupVars.conf"
|
||||
mode: 0644
|
||||
|
||||
- name: installing pihole # noqa 305
|
||||
shell:
|
||||
chdir: "{{ pihole_directory }}/automated install/"
|
||||
cmd: "bash basic-install.sh --unattended"
|
||||
|
||||
when:
|
||||
- not pihole_bin.stat.exists or pihole_reinstall
|
||||
|
||||
- name: "check and apply updates to pihole"
|
||||
command: "{{ pihole_bin_path }} updatePihole"
|
||||
register: updatePihole
|
||||
when:
|
||||
- pihole_bin.stat.exists
|
||||
- pihole_update|bool
|
||||
- not pihole_reinstall
|
||||
|
||||
- name: Output from update
|
||||
debug:
|
||||
var: updatePihole.stdout_lines
|
||||
when: updatePihole.changed == true
|
||||
|
||||
- name: Finished! ipv4
|
||||
debug:
|
||||
msg: "visit http://{{ pihole_setupvars_ipv4_address }}/admin/ to start managing your pi-hole"
|
||||
when:
|
||||
- pihole_setupvars_ipv4_address and pihole_setupvars_ipv4_address|length > 0
|
||||
|
||||
- name: Finished! ipv6
|
||||
debug:
|
||||
msg: "visit http://{{ pihole_setupvars_ipv6_address }}/admin/ to start managing your pi-hole"
|
||||
when:
|
||||
- pihole_setupvars_ipv6_address and pihole_setupvars_ipv6_address|length > 0
|
||||
@@ -0,0 +1,23 @@
|
||||
WEBPASSWORD={{ pihole_setupvars_webpassword }}
|
||||
DNS_FQDN_REQUIRED={{ pihole_setupvars_dns_fqdn_required }}
|
||||
DNS_BOGUS_PRIV={{ pihole_setupvars_dns_bogus_priv }}
|
||||
DNSSEC={{ pihole_setupvars_dnssec }}
|
||||
CONDITIONAL_FORWARDING={{ pihole_setupvars_conditional_forwarding }}
|
||||
DNSMASQ_LISTENING={{ pihole_setupvars_dnsmasq_listening }}
|
||||
CONDITIONAL_FORWARDING_IP={{ pihole_setupvars_conditional_forwarding_ip }}
|
||||
CONDITIONAL_FORWARDING_DOMAIN={{ pihole_setupvars_conditional_forwarding_domain }}
|
||||
CONDITIONAL_FORWARDING_REVERSE={{ pihole_setupvars_conditional_forwarding_reverse }}
|
||||
PIHOLE_INTERFACE={{ pihole_setupvars_pihole_interface }}
|
||||
IPV4_ADDRESS={{ pihole_setupvars_ipv4_address }}
|
||||
IPV6_ADDRESS={{ pihole_setupvars_ipv6_address }}
|
||||
PIHOLE_DNS_1={{ pihole_setupvars_pihole_dns_1 }}
|
||||
PIHOLE_DNS_2={{ pihole_setupvars_pihole_dns_2 }}
|
||||
QUERY_LOGGING={{ pihole_setupvars_query_logging }}
|
||||
INSTALL_WEB_SERVER={{ pihole_setupvars_install_web_server }}
|
||||
INSTALL_WEB_INTERFACE={{ pihole_setupvars_install_web_interface }}
|
||||
LIGHTTPD_ENABLED={{ pihole_setupvars_lighttpd_enabled }}
|
||||
BLOCKING_ENABLED={{ pihole_setupvars_blocking_enabled }}
|
||||
ADMIN_EMAIL={{ pihole_setupvars_admin_email }}
|
||||
WEBUIBOXEDLAYOUT={{ pihole_setupvars_weblayout }}
|
||||
WEBTHEME={{ pihole_setupvars_webtheme }}
|
||||
REV_SERVER={{ pihole_setupvars_rev_server }}
|
||||
Reference in New Issue
Block a user