Compare commits
19 Commits
564db32244
...
8c4684a450
Author | SHA1 | Date | |
---|---|---|---|
8c4684a450
|
|||
f9491c6553
|
|||
c0a466db6a
|
|||
3fedc63db3
|
|||
0a85cd22ff
|
|||
a8c4bf141b
|
|||
2232e7c213
|
|||
6a3010816a
|
|||
e8661bbddb
|
|||
571f694ed1
|
|||
1115f7d0a8
|
|||
7f39ea724a
|
|||
475fe06fb7
|
|||
1d1b31c461
|
|||
8d649970ee
|
|||
3ab93fd509
|
|||
680b09ca2c
|
|||
4814d7d6ae
|
|||
7388125008
|
@@ -1,11 +1,15 @@
|
|||||||
[defaults]
|
[defaults]
|
||||||
|
# Explicitely redefined some defaults to make play execution work
|
||||||
|
roles_path = ./roles
|
||||||
|
vars_plugins = ./vars_plugins
|
||||||
|
|
||||||
inventory = ./hosts
|
inventory = ./hosts
|
||||||
timeout = 60
|
timeout = 60
|
||||||
# ask_vault_pass = True
|
|
||||||
|
|
||||||
[privilege_escalation]
|
[privilege_escalation]
|
||||||
become = True
|
become = True
|
||||||
become_ask_pass = True
|
# Use a separate module to read passwords from pass
|
||||||
|
become_ask_pass = False
|
||||||
|
|
||||||
[ssh_connection]
|
[ssh_connection]
|
||||||
pipelining = True
|
pipelining = True
|
||||||
|
@@ -17,6 +17,10 @@ ansible_header: |
|
|||||||
|
|
||||||
+++++++++++++++++++++++++++++++++++++++++++++++++++
|
+++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
|
glob_ldap:
|
||||||
|
servers:
|
||||||
|
- 172.16.42.1
|
||||||
|
base: 'dc=ynerant,dc=fr'
|
||||||
|
|
||||||
|
|
||||||
pass:
|
pass:
|
4
group_vars/all/home.yml
Normal file
4
group_vars/all/home.yml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
glob_home:
|
||||||
|
ip: 172.16.42.1
|
||||||
|
mountpoint: /rpool/home
|
3
group_vars/all/ntp.yml
Normal file
3
group_vars/all/ntp.yml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
glob_ntp_client:
|
||||||
|
servers:
|
||||||
|
- ntp.adm.ynerant.fr
|
8
group_vars/certbot.yml
Normal file
8
group_vars/certbot.yml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
glob_certbot:
|
||||||
|
- dns_rfc2136_server: '172.16.42.103'
|
||||||
|
dns_rfc2136_name: certbot_challenge.
|
||||||
|
dns_rfc2136_secret: "{{ vault.certbot_dns_secret }}"
|
||||||
|
mail: ynerant@crans.org
|
||||||
|
certname: ynerant.fr
|
||||||
|
domains: "*.ynerant.fr"
|
7
group_vars/debian.yml
Normal file
7
group_vars/debian.yml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
glob_apt:
|
||||||
|
mirror: "http://mirror.adm.ynerant.fr/"
|
||||||
|
backports: false
|
||||||
|
extra_repositories: []
|
||||||
|
pin:
|
||||||
|
bullseye: []
|
32
group_vars/nginx.yml
Normal file
32
group_vars/nginx.yml
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
---
|
||||||
|
glob_nginx:
|
||||||
|
contact: ynerant@crans.org
|
||||||
|
who: "Ÿnérant"
|
||||||
|
service_name: service
|
||||||
|
ssl:
|
||||||
|
# Add adm.ynerant.fr if necessary
|
||||||
|
- name: ynerant.fr
|
||||||
|
cert: /etc/letsencrypt/live/ynerant.fr/fullchain.pem
|
||||||
|
cert_key: /etc/letsencrypt/live/ynerant.fr/privkey.pem
|
||||||
|
trusted_cert: /etc/letsencrypt/live/ynerant.fr/chain.pem
|
||||||
|
servers:
|
||||||
|
- ssl: false # Replace by crans.org or adm.crans.org
|
||||||
|
default: true
|
||||||
|
server_name:
|
||||||
|
- "default"
|
||||||
|
- "_"
|
||||||
|
root: "/var/www/html"
|
||||||
|
locations:
|
||||||
|
- filter: "/"
|
||||||
|
params: []
|
||||||
|
additional_params: []
|
||||||
|
upstreams: []
|
||||||
|
|
||||||
|
auth_passwd: []
|
||||||
|
default_server:
|
||||||
|
default_ssl_server:
|
||||||
|
default_ssl_domain: ynerant.fr
|
||||||
|
real_ip_from:
|
||||||
|
- "172.16.0.0/16"
|
||||||
|
- "fd00:0:0:42::/64"
|
||||||
|
deploy_robots_file: false
|
46
group_vars/reverseproxy.yml
Normal file
46
group_vars/reverseproxy.yml
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
loc_certbot:
|
||||||
|
- dns_rfc2136_server: '172.16.42.103'
|
||||||
|
dns_rfc2136_name: certbot_challenge.
|
||||||
|
dns_rfc2136_secret: "{{ vault.certbot_dns_secret }}"
|
||||||
|
mail: ynerant@crans.org
|
||||||
|
certname: ynerant.fr
|
||||||
|
domains: "ynerant.fr, *.ynerant.fr, ens.kitchen, *.ens.kitchen, ananas.paris, *.ananas.paris, saperlistpopette.fr, *.saperlistpopette.fr"
|
||||||
|
|
||||||
|
loc_nginx:
|
||||||
|
servers: []
|
||||||
|
ssl:
|
||||||
|
- name: ynerant.fr
|
||||||
|
cert: /etc/letsencrypt/live/ynerant.fr/fullchain.pem
|
||||||
|
cert_key: /etc/letsencrypt/live/ynerant.fr/privkey.pem
|
||||||
|
trusted_cert: /etc/letsencrypt/live/ynerant.fr/chain.pem
|
||||||
|
|
||||||
|
|
||||||
|
glob_reverseproxy:
|
||||||
|
redirect_dnames: []
|
||||||
|
|
||||||
|
reverseproxy_sites:
|
||||||
|
- {from: mailu.ynerant.fr, to: 172.16.42.104}
|
||||||
|
# - {from: mirror.adm.ynerant.fr, to: "https://ftps.crans.org"}
|
||||||
|
|
||||||
|
- {from: element.ynerant.fr, to: "172.16.42.199:8002"}
|
||||||
|
- {from: hydrogen.ynerant.fr, to: "172.16.42.199:8003"}
|
||||||
|
- {from: git.ynerant.fr, to: "172.16.42.199:8007"}
|
||||||
|
- {from: cloud.ynerant.fr, to: "172.16.42.199:8007"}
|
||||||
|
# - {from: notls.adh.crans.org, to: "172.16.42.199:8011"}
|
||||||
|
- {from: thelounge.ynerant.fr, to: "172.16.42.199:8012"}
|
||||||
|
- {from: bibliogram.ynerant.fr, to: "172.16.42.199:8014"}
|
||||||
|
- {from: reddit.ynerant.fr, to: "172.16.42.199:8015"}
|
||||||
|
- {from: teddit.ynerant.fr, to: "172.16.42.199:8015"}
|
||||||
|
- {from: whoami.ynerant.fr, to: "172.16.42.199:8016"}
|
||||||
|
|
||||||
|
- {from: saperlistpopette.fr, to: "172.16.42.199:8010"}
|
||||||
|
- {from: kfet.saperlistpopette.fr, to: "172.16.42.199:8010"}
|
||||||
|
|
||||||
|
- {from: ens.kitchen, to: "https://perso.crans.org/club-kitchens/"}
|
||||||
|
|
||||||
|
redirect_sites: []
|
||||||
|
# - {from: machin.ynerant.fr, to: truc.ynerant.fr}
|
||||||
|
|
||||||
|
static_sites:
|
||||||
|
- ynerant.fr
|
||||||
|
- thelounge.ynerant.fr
|
10
group_vars/slapd.yml
Normal file
10
group_vars/slapd.yml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
glob_slapd:
|
||||||
|
master_ip: "172.16.42.1"
|
||||||
|
ip: "172.16.42.1"
|
||||||
|
replica: false
|
||||||
|
# master_ip: "{{ query('ldap', 'ip', 'templier', 'adm') | ipv6 | first }}"
|
||||||
|
regex: "^(role:(dhcp|dns|dns-primary|dns-secondary|ftp|gitlab|miroir|ntp|pve|radius|backup)|ecdsa-sha2-nistp256:.*|ssh-(ed25519|dss|rsa):.*)$"
|
||||||
|
replication_credentials: "{{ vault.ldap_replication_credentials }}"
|
||||||
|
private_key: "{{ vault.ldap_private_key }}"
|
||||||
|
certificate: "{{ vault.ldap_certificate }}"
|
8
group_vars/virtu.yml
Normal file
8
group_vars/virtu.yml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
service_apt:
|
||||||
|
extra_repositories:
|
||||||
|
- name: pve-entreprise
|
||||||
|
repositories:
|
||||||
|
- url: "{{ glob_apt.mirror }}proxmox/debian/pve"
|
||||||
|
version: "{{ ansible_distribution_release }}"
|
||||||
|
tags: "pve-no-subscription"
|
44
hosts
44
hosts
@@ -1,16 +1,46 @@
|
|||||||
[server]
|
[archlinux:children]
|
||||||
templier.adh.crans.org
|
perso
|
||||||
dt.adh.crans.org
|
|
||||||
|
[certbot]
|
||||||
|
proxy.adm.ynerant.fr
|
||||||
|
|
||||||
|
[debian:children]
|
||||||
|
server
|
||||||
|
|
||||||
|
[nginx:children]
|
||||||
|
reverseproxy
|
||||||
|
|
||||||
|
[ntp_server]
|
||||||
|
routeur-templier.adm.ynerant.fr
|
||||||
|
|
||||||
[perso]
|
[perso]
|
||||||
ynerant-pc.fil.sand.auro.re
|
ynerant-pc.fil.sand.auro.re
|
||||||
ynerant-thinkpad.wifi.sand.auro.re
|
ynerant-thinkpad.wifi.sand.auro.re
|
||||||
localhost
|
localhost
|
||||||
|
|
||||||
[crans]
|
[reverseproxy]
|
||||||
odlyd.crans.org
|
proxy.adm.ynerant.fr
|
||||||
tealc.crans.org
|
|
||||||
zamok.crans.org
|
[server:children]
|
||||||
|
virtu
|
||||||
|
vm
|
||||||
|
|
||||||
|
[slapd]
|
||||||
|
templier.adm.ynerant.fr
|
||||||
|
|
||||||
|
[virtu]
|
||||||
|
# dt.adh.crans.org
|
||||||
|
templier.adm.ynerant.fr
|
||||||
|
|
||||||
|
[vm]
|
||||||
|
routeur-templier.adm.ynerant.fr
|
||||||
|
proxy.adm.ynerant.fr
|
||||||
|
dns.adm.ynerant.fr
|
||||||
|
mailu.adm.ynerant.fr
|
||||||
|
psql.adm.ynerant.fr
|
||||||
|
synapse.adm.ynerant.fr
|
||||||
|
docker.adm.ynerant.fr
|
||||||
|
# candilib.adm.ynerant.fr
|
||||||
|
|
||||||
[all:vars]
|
[all:vars]
|
||||||
# Force remote to use Python 3
|
# Force remote to use Python 3
|
||||||
|
7
plays/apt.yml
Executable file
7
plays/apt.yml
Executable file
@@ -0,0 +1,7 @@
|
|||||||
|
#!/usr/bin/env ansible-playbook
|
||||||
|
---
|
||||||
|
- hosts: debian
|
||||||
|
vars:
|
||||||
|
apt: "{{ glob_apt | default({}) | combine(service_apt | default({})) | combine(loc_apt | default({})) }}"
|
||||||
|
roles:
|
||||||
|
- apt
|
@@ -1,24 +1,33 @@
|
|||||||
#!/usr/bin/env ansible-playbook
|
#!/usr/bin/env ansible-playbook
|
||||||
---
|
---
|
||||||
|
|
||||||
|
- import_playbook: apt.yml
|
||||||
|
- import_playbook: ntp.yml
|
||||||
|
- import_playbook: ldap-client.yml
|
||||||
|
- import_playbook: home.yml
|
||||||
|
|
||||||
|
- hosts: debian
|
||||||
|
roles:
|
||||||
|
- sudo
|
||||||
|
|
||||||
- hosts: all
|
- hosts: all
|
||||||
roles:
|
roles:
|
||||||
- cli-utils
|
- cli-utils
|
||||||
- vim
|
- vim
|
||||||
- ssh
|
- ssh
|
||||||
|
|
||||||
- hosts: templier.adh.crans.org
|
#- hosts: templier.adh.crans.org
|
||||||
roles:
|
# roles:
|
||||||
- bind
|
# - bind
|
||||||
- docker
|
# - docker
|
||||||
become: yes
|
# become: yes
|
||||||
|
|
||||||
- hosts: perso
|
- hosts: perso
|
||||||
roles:
|
roles:
|
||||||
- sudo
|
# - sudo
|
||||||
- systemd
|
- systemd
|
||||||
- pacman
|
- pacman
|
||||||
- ntp
|
- ntp-client-arch
|
||||||
- texlive
|
- texlive
|
||||||
- xorg
|
- xorg
|
||||||
- i3
|
- i3
|
7
plays/certbot.yml
Executable file
7
plays/certbot.yml
Executable file
@@ -0,0 +1,7 @@
|
|||||||
|
#!/usr/bin/env ansible-playbook
|
||||||
|
---
|
||||||
|
- hosts: certbot
|
||||||
|
vars:
|
||||||
|
certbot: "{{ glob_certbot | default(service_certbot | default(loc_certbot | default([]))) }}"
|
||||||
|
roles:
|
||||||
|
- certbot
|
7
plays/home.yml
Executable file
7
plays/home.yml
Executable file
@@ -0,0 +1,7 @@
|
|||||||
|
#!/usr/bin/env ansible-playbook
|
||||||
|
---
|
||||||
|
- hosts: debian
|
||||||
|
vars:
|
||||||
|
home: '{{ glob_home | combine(loc_home | default({})) }}'
|
||||||
|
roles:
|
||||||
|
- home
|
7
plays/ldap-client.yml
Executable file
7
plays/ldap-client.yml
Executable file
@@ -0,0 +1,7 @@
|
|||||||
|
#!/usr/bin/env ansible-playbook
|
||||||
|
---
|
||||||
|
- hosts: debian
|
||||||
|
vars:
|
||||||
|
ldap: '{{ glob_ldap | combine(loc_ldap | default({})) }}'
|
||||||
|
roles:
|
||||||
|
- ldap-client
|
14
plays/nginx.yml
Executable file
14
plays/nginx.yml
Executable file
@@ -0,0 +1,14 @@
|
|||||||
|
#!/usr/bin/env ansible-playbook
|
||||||
|
---
|
||||||
|
- hosts: nginx,!reverseproxy
|
||||||
|
vars:
|
||||||
|
nginx: "{{ glob_nginx | default({}) | combine(service_nginx | default({})) | combine(loc_nginx | default({})) }}"
|
||||||
|
roles:
|
||||||
|
- nginx
|
||||||
|
|
||||||
|
- hosts: reverseproxy
|
||||||
|
vars:
|
||||||
|
nginx: "{{ glob_nginx | default({}) | combine(service_nginx | default({})) | combine(loc_nginx | default({})) }}"
|
||||||
|
reverseproxy: "{{ glob_reverseproxy | default({}) | combine(service_reverseproxy | default({})) | combine(loc_reverseproxy | default({})) }}"
|
||||||
|
roles:
|
||||||
|
- nginx
|
13
plays/ntp.yml
Executable file
13
plays/ntp.yml
Executable file
@@ -0,0 +1,13 @@
|
|||||||
|
#!/usr/bin/env ansible-playbook
|
||||||
|
---
|
||||||
|
- hosts: ntp_server
|
||||||
|
vars:
|
||||||
|
ntp_server: '{{ glob_ntp_server | combine(loc_ntp_server | default({})) }}'
|
||||||
|
roles:
|
||||||
|
- ntp-server
|
||||||
|
|
||||||
|
- hosts: debian
|
||||||
|
vars:
|
||||||
|
ntp_client: '{{ glob_ntp_client | combine(loc_ntp_client | default({})) }}'
|
||||||
|
roles:
|
||||||
|
- ntp-client
|
7
plays/slapd.yml
Executable file
7
plays/slapd.yml
Executable file
@@ -0,0 +1,7 @@
|
|||||||
|
#!/usr/bin/env ansible-playbook
|
||||||
|
---
|
||||||
|
- hosts: slapd
|
||||||
|
vars:
|
||||||
|
slapd: "{{ glob_slapd | default({}) | combine(service_slapd | default({})) | combine(loc_slapd | default({})) }}"
|
||||||
|
roles:
|
||||||
|
- slapd
|
51
roles/apt/tasks/main.yml
Normal file
51
roles/apt/tasks/main.yml
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
---
|
||||||
|
- name: Clear charybde configuration
|
||||||
|
lineinfile:
|
||||||
|
state: absent
|
||||||
|
path: /etc/hosts
|
||||||
|
regex: "^{{ item }}"
|
||||||
|
loop:
|
||||||
|
- "185.230.79.30"
|
||||||
|
- "2a0c:700:2:0:ea39:35ff:fef0:48c9"
|
||||||
|
|
||||||
|
- name: Add mirror.crans.org in /etc/hosts
|
||||||
|
lineinfile:
|
||||||
|
state: present
|
||||||
|
path: /etc/hosts
|
||||||
|
regex: "^{{ item }}"
|
||||||
|
line: "{{ item }} mirror.adm.ynerant.fr"
|
||||||
|
loop:
|
||||||
|
- "172.16.42.102"
|
||||||
|
- "fd00::42:4000:ff:fe01:242"
|
||||||
|
|
||||||
|
- name: Configure Debian repositories
|
||||||
|
template:
|
||||||
|
src: apt/sources.list.j2
|
||||||
|
dest: /etc/apt/sources.list
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: 0644
|
||||||
|
|
||||||
|
- name: Configure extra repositories
|
||||||
|
template:
|
||||||
|
src: apt/sources.list.d/sources.list.j2
|
||||||
|
dest: "/etc/apt/sources.list.d/{{ item.name }}.list"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: 0644
|
||||||
|
loop: "{{ apt.extra_repositories }}"
|
||||||
|
|
||||||
|
- name: Configure pin from future distributions
|
||||||
|
template:
|
||||||
|
src: "apt/{{ item[0] }}.d/pin{{ item[1] }}.j2"
|
||||||
|
dest: "/etc/apt/{{ item[0] }}.d/{{ item[2].key }}{{ item[1] }}"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: 0644
|
||||||
|
with_nested:
|
||||||
|
- [["sources.list", ".list"], ["preferences", ""]]
|
||||||
|
- "{{ apt.pin|dict2items }}"
|
||||||
|
|
||||||
|
- name: Update APT cache
|
||||||
|
apt:
|
||||||
|
update_cache: true
|
12
roles/apt/templates/apt/preferences.d/pin.j2
Normal file
12
roles/apt/templates/apt/preferences.d/pin.j2
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{{ ansible_header | comment }}
|
||||||
|
|
||||||
|
|
||||||
|
Package: *
|
||||||
|
Pin: release n={{ item[2].key }}
|
||||||
|
Pin-Priority: 1
|
||||||
|
{% for package in item[2].value -%}
|
||||||
|
|
||||||
|
Package: {{ package }}
|
||||||
|
Pin: release n={{ item[2].key }}
|
||||||
|
Pin-Priority: 900
|
||||||
|
{% endfor -%}
|
3
roles/apt/templates/apt/sources.list.d/pin.list.j2
Normal file
3
roles/apt/templates/apt/sources.list.d/pin.list.j2
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{{ ansible_header | comment }}
|
||||||
|
|
||||||
|
deb {{ apt.mirror }}debian {{ item[2].key }} main contrib non-free
|
8
roles/apt/templates/apt/sources.list.d/sources.list.j2
Normal file
8
roles/apt/templates/apt/sources.list.d/sources.list.j2
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{{ ansible_header | comment }}
|
||||||
|
|
||||||
|
{% for repo in item.repositories -%}
|
||||||
|
deb {{ repo.url }} {{ repo.version }} {{ repo.tags }}
|
||||||
|
{% if repo.src is defined and repo.src -%}
|
||||||
|
deb-src {{ repo.url }} {{ repo.version }} {{ repo.tags }}
|
||||||
|
{% endif -%}
|
||||||
|
{% endfor -%}
|
18
roles/apt/templates/apt/sources.list.j2
Normal file
18
roles/apt/templates/apt/sources.list.j2
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{{ ansible_header | comment }}
|
||||||
|
|
||||||
|
{% if ansible_distribution_release != "bullseye" %}
|
||||||
|
{# Debian security does not exist yet for bullseye #}
|
||||||
|
# Mises à jour de sécurité
|
||||||
|
deb {{ apt.mirror }}debian-security {{ ansible_distribution_release }}/updates main contrib non-free
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
# Dépôt classique
|
||||||
|
deb {{ apt.mirror }}debian {{ ansible_distribution_release }} main contrib non-free
|
||||||
|
|
||||||
|
# Dépôt pour mises à jour fréquentes (volatile)
|
||||||
|
deb {{ apt.mirror }}debian {{ ansible_distribution_release }}-updates main contrib non-free
|
||||||
|
|
||||||
|
{% if apt.backports | default(false) %}
|
||||||
|
# Backports
|
||||||
|
deb {{ apt.mirror }}debian {{ ansible_distribution_release }}-backports main contrib non-free
|
||||||
|
{% endif %}
|
52
roles/certbot/tasks/main.yml
Normal file
52
roles/certbot/tasks/main.yml
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
---
|
||||||
|
- name: Install certbot and RFC2136 plugin
|
||||||
|
apt:
|
||||||
|
update_cache: true
|
||||||
|
name:
|
||||||
|
- certbot
|
||||||
|
- python3-certbot-dns-rfc2136
|
||||||
|
state: present
|
||||||
|
register: apt_result
|
||||||
|
retries: 3
|
||||||
|
until: apt_result is succeeded
|
||||||
|
|
||||||
|
- name: Add DNS credentials
|
||||||
|
template:
|
||||||
|
src: letsencrypt/rfc2136.ini.j2
|
||||||
|
dest: "/etc/letsencrypt/rfc2136.{{ item.certname }}.ini"
|
||||||
|
mode: 0600
|
||||||
|
owner: root
|
||||||
|
loop: "{{ certbot }}"
|
||||||
|
|
||||||
|
- name: Add dhparam
|
||||||
|
template:
|
||||||
|
src: "letsencrypt/dhparam.j2"
|
||||||
|
dest: "/etc/letsencrypt/dhparam"
|
||||||
|
mode: 0600
|
||||||
|
|
||||||
|
- name: Create /etc/letsencrypt/conf.d
|
||||||
|
file:
|
||||||
|
path: /etc/letsencrypt/conf.d
|
||||||
|
state: directory
|
||||||
|
|
||||||
|
- name: Add Certbot configuration
|
||||||
|
template:
|
||||||
|
src: "letsencrypt/conf.d/certname.ini.j2"
|
||||||
|
dest: "/etc/letsencrypt/conf.d/{{ item.certname }}.ini"
|
||||||
|
mode: 0644
|
||||||
|
loop: "{{ certbot }}"
|
||||||
|
|
||||||
|
- name: Run certbot
|
||||||
|
command: certbot --non-interactive --config /etc/letsencrypt/conf.d/{{ item.certname }}.ini certonly
|
||||||
|
register: certbot_output
|
||||||
|
changed_when: not "Certificate not yet due for renewal" in certbot_output.stdout
|
||||||
|
loop: "{{ certbot }}"
|
||||||
|
|
||||||
|
- name: Clean old files
|
||||||
|
file:
|
||||||
|
path: "{{ item }}"
|
||||||
|
state: absent
|
||||||
|
loop:
|
||||||
|
- "/etc/letsencrypt/options-ssl-nginx.conf"
|
||||||
|
- "/etc/letsencrypt/ssl-dhparams.pem"
|
||||||
|
- "/etc/letsencrypt/rfc2136.ini"
|
28
roles/certbot/templates/letsencrypt/conf.d/certname.ini.j2
Normal file
28
roles/certbot/templates/letsencrypt/conf.d/certname.ini.j2
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
{{ ansible_header | comment(decoration='# ') }}
|
||||||
|
|
||||||
|
# To generate the certificate, please use the following command
|
||||||
|
# certbot --config /etc/letsencrypt/conf.d/{{ item.certname }}.ini certonly
|
||||||
|
|
||||||
|
# Use a 4096 bit RSA key instead of 2048
|
||||||
|
rsa-key-size = 4096
|
||||||
|
|
||||||
|
# Always use the staging/testing server
|
||||||
|
# server = https://acme-staging.api.letsencrypt.org/directory
|
||||||
|
|
||||||
|
# Uncomment and update to register with the specified e-mail address
|
||||||
|
email = {{ item.mail }}
|
||||||
|
|
||||||
|
# Uncomment to use a text interface instead of ncurses
|
||||||
|
text = True
|
||||||
|
|
||||||
|
# Yes I want to sell my soul and my guinea pig.
|
||||||
|
agree-tos = True
|
||||||
|
|
||||||
|
# Use DNS-01 challenge
|
||||||
|
authenticator = dns-rfc2136
|
||||||
|
dns-rfc2136-credentials = /etc/letsencrypt/rfc2136.{{ item.certname }}.ini
|
||||||
|
dns-rfc2136-propagation-seconds = 30
|
||||||
|
|
||||||
|
# Wildcard the domain
|
||||||
|
cert-name = {{ item.certname }}
|
||||||
|
domains = {{ item.domains }}
|
8
roles/certbot/templates/letsencrypt/dhparam.j2
Normal file
8
roles/certbot/templates/letsencrypt/dhparam.j2
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
-----BEGIN DH PARAMETERS-----
|
||||||
|
MIIBCAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz
|
||||||
|
+8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a
|
||||||
|
87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7
|
||||||
|
YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi
|
||||||
|
7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD
|
||||||
|
ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg==
|
||||||
|
-----END DH PARAMETERS-----
|
7
roles/certbot/templates/letsencrypt/rfc2136.ini.j2
Normal file
7
roles/certbot/templates/letsencrypt/rfc2136.ini.j2
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{{ ansible_header | comment(decoration='# ') }}
|
||||||
|
|
||||||
|
dns_rfc2136_server = {{ item.dns_rfc2136_server }}
|
||||||
|
dns_rfc2136_port = 53
|
||||||
|
dns_rfc2136_name = {{ item.dns_rfc2136_name }}
|
||||||
|
dns_rfc2136_secret = {{ item.dns_rfc2136_secret }}
|
||||||
|
dns_rfc2136_algorithm = HMAC-SHA512
|
@@ -5,10 +5,11 @@
|
|||||||
- bash
|
- bash
|
||||||
- bash-completion
|
- bash-completion
|
||||||
- bat
|
- bat
|
||||||
- bind-tools
|
- curl
|
||||||
|
- "{% if ansible_os_family == 'Debian' %}dnsutils{% else %}bind-tools{% endif %}"
|
||||||
- git
|
- git
|
||||||
- man
|
- man
|
||||||
- mtr
|
- "mtr{% if ansible_os_family == 'Debian' %}-tiny{% endif %}"
|
||||||
- sl
|
- sl
|
||||||
- htop
|
- htop
|
||||||
- patch
|
- patch
|
||||||
|
@@ -21,10 +21,10 @@ alias cd='cd -P'
|
|||||||
alias ip='ip -c'
|
alias ip='ip -c'
|
||||||
|
|
||||||
alias less='less -R'
|
alias less='less -R'
|
||||||
|
{% if ansible_os_family == "Archlinux" -%}
|
||||||
alias toilet='toilet -f mono12 --rainbow'
|
|
||||||
|
|
||||||
alias startx='exec startx'
|
alias startx='exec startx'
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
alias gst='git status -s'
|
alias gst='git status -s'
|
||||||
|
|
||||||
@@ -38,6 +38,9 @@ alias jack="ssh -L 8006:jack.adm.crans.org:8006 jack.adm.crans.org"
|
|||||||
alias daniel="ssh -L 8006:daniel.adm.crans.org:8006 daniel.adm.crans.org"
|
alias daniel="ssh -L 8006:daniel.adm.crans.org:8006 daniel.adm.crans.org"
|
||||||
|
|
||||||
alias vi=vim
|
alias vi=vim
|
||||||
|
{% if ansible_os_family == "Debian" -%}
|
||||||
|
alias bat=batcat
|
||||||
|
{% endif -%}
|
||||||
alias cat=bat
|
alias cat=bat
|
||||||
|
|
||||||
# Add some emoji aliases
|
# Add some emoji aliases
|
||||||
@@ -47,5 +50,7 @@ alias 🚆=sl
|
|||||||
alias 🚂=sl
|
alias 🚂=sl
|
||||||
alias 🚅=sl
|
alias 🚅=sl
|
||||||
alias 💿=cd
|
alias 💿=cd
|
||||||
|
{% if ansible_os_family == "Archlinux" -%}
|
||||||
|
{# Personal computer #}
|
||||||
alias 🐿️="cd /home/ynerant/PycharmProjects/SquirrelBattle && venv/bin/python main.py"
|
alias 🐿️="cd /home/ynerant/PycharmProjects/SquirrelBattle && venv/bin/python main.py"
|
||||||
|
{% endif -%}
|
||||||
|
8
roles/home/README.md
Normal file
8
roles/home/README.md
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# HOME-NOUNOUS
|
||||||
|
|
||||||
|
Ce rôle permet d'exporter les homes vers les différents serveurs.
|
||||||
|
|
||||||
|
## VARS
|
||||||
|
|
||||||
|
home_nounous:
|
||||||
|
ip: l'ip du serveur nfs
|
31
roles/home/tasks/main.yml
Normal file
31
roles/home/tasks/main.yml
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
---
|
||||||
|
- name: Install NFS client
|
||||||
|
apt:
|
||||||
|
update_cache: true
|
||||||
|
name:
|
||||||
|
- nfs-common
|
||||||
|
state: present
|
||||||
|
register: apt_result
|
||||||
|
retries: 3
|
||||||
|
until: apt_result is succeeded
|
||||||
|
|
||||||
|
- name: Create directory home
|
||||||
|
file:
|
||||||
|
path: /home
|
||||||
|
state: directory
|
||||||
|
owner: root
|
||||||
|
group: user
|
||||||
|
mode: 0750
|
||||||
|
|
||||||
|
- name: Deploy nfs systemd mount
|
||||||
|
template:
|
||||||
|
src: systemd/system/home.mount.j2
|
||||||
|
dest: /etc/systemd/system/home.mount
|
||||||
|
mode: 0644
|
||||||
|
|
||||||
|
- name: Load and activate nfs systemd mount
|
||||||
|
systemd:
|
||||||
|
name: home.mount
|
||||||
|
daemon_reload: true
|
||||||
|
enabled: true
|
||||||
|
state: started
|
14
roles/home/templates/systemd/system/home.mount.j2
Normal file
14
roles/home/templates/systemd/system/home.mount.j2
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{{ ansible_header | comment }}
|
||||||
|
[Unit]
|
||||||
|
Description=Mount home
|
||||||
|
Wants=network-online.target
|
||||||
|
After=network-online.target
|
||||||
|
|
||||||
|
[Mount]
|
||||||
|
What={{ home.ip }}:{{ home.mountpoint }}
|
||||||
|
Where=/home
|
||||||
|
Type=nfs
|
||||||
|
Options=rw,nosuid
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
@@ -237,5 +237,5 @@ bar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{% if laptop.touchscreen %}
|
{% if laptop.touchscreen %}
|
||||||
exec xinput --set-prop 13 "libinput Natural Scrolling Enabled" 1
|
exec xinput --set-prop 14 "libinput Natural Scrolling Enabled" 1
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
10
roles/ldap-client/README.md
Normal file
10
roles/ldap-client/README.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# LDAP-CLIENT
|
||||||
|
|
||||||
|
Configure un client ldap pour les utilisateurs
|
||||||
|
|
||||||
|
## VARS
|
||||||
|
|
||||||
|
ldap:
|
||||||
|
- local: si le serveur est installé en local
|
||||||
|
- servers: la liste des servers ldap a contacté
|
||||||
|
- base: le search term du ldap
|
16
roles/ldap-client/handlers/main.yml
Normal file
16
roles/ldap-client/handlers/main.yml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
---
|
||||||
|
- name: Reconfigure libnss-ldapd package
|
||||||
|
command: dpkg-reconfigure libnss-ldapd -f noninteractive
|
||||||
|
|
||||||
|
- name: Restart nslcd service
|
||||||
|
service:
|
||||||
|
name: nslcd
|
||||||
|
state: restarted
|
||||||
|
|
||||||
|
# Empty cache when nslcd is restarted
|
||||||
|
- name: Restart nscd service
|
||||||
|
service:
|
||||||
|
name: nscd
|
||||||
|
state: restarted
|
||||||
|
ignore_errors: true # Sometimes service do not exist
|
||||||
|
listen: Restart nslcd service
|
50
roles/ldap-client/tasks/main.yml
Normal file
50
roles/ldap-client/tasks/main.yml
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
---
|
||||||
|
# Install LDAP client packages
|
||||||
|
- name: Install LDAP client packages
|
||||||
|
apt:
|
||||||
|
update_cache: true
|
||||||
|
name:
|
||||||
|
- libnss-ldapd
|
||||||
|
- libpam-ldapd
|
||||||
|
state: present
|
||||||
|
register: apt_result
|
||||||
|
retries: 3
|
||||||
|
until: apt_result is succeeded
|
||||||
|
|
||||||
|
# Configure /etc/nslcd.conf
|
||||||
|
- name: Configure nslcd
|
||||||
|
template:
|
||||||
|
src: nslcd.conf.j2
|
||||||
|
dest: /etc/nslcd.conf
|
||||||
|
mode: 0600
|
||||||
|
notify: Restart nslcd service
|
||||||
|
|
||||||
|
# Configure /etc/nsswitch.conf
|
||||||
|
- name: Configure NSS to use LDAP
|
||||||
|
lineinfile:
|
||||||
|
dest: /etc/nsswitch.conf
|
||||||
|
regexp: "^{{ item }}"
|
||||||
|
line: "{{ item }} files systemd ldap"
|
||||||
|
loop:
|
||||||
|
- "passwd:"
|
||||||
|
- "group: "
|
||||||
|
notify: Restart nslcd service
|
||||||
|
|
||||||
|
- name: Configure NSS to use LDAP
|
||||||
|
lineinfile:
|
||||||
|
dest: /etc/nsswitch.conf
|
||||||
|
regexp: "^{{ item }}"
|
||||||
|
line: "{{ item }} files ldap"
|
||||||
|
loop:
|
||||||
|
- "shadow: "
|
||||||
|
- "networks:"
|
||||||
|
notify: Restart nslcd service
|
||||||
|
|
||||||
|
- name: Configure NSS to use LDAP
|
||||||
|
lineinfile:
|
||||||
|
dest: /etc/nsswitch.conf
|
||||||
|
regexp: "^{{ item }}"
|
||||||
|
line: "{{ item }} files ldap dns"
|
||||||
|
loop:
|
||||||
|
- "hosts:"
|
||||||
|
notify: Restart nslcd service
|
38
roles/ldap-client/templates/nslcd.conf.j2
Normal file
38
roles/ldap-client/templates/nslcd.conf.j2
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
{{ ansible_header | comment }}
|
||||||
|
# /etc/nslcd.conf
|
||||||
|
# nslcd configuration file. See nslcd.conf(5)
|
||||||
|
# for details.
|
||||||
|
|
||||||
|
# The user and group nslcd should run as.
|
||||||
|
uid nslcd
|
||||||
|
gid nslcd
|
||||||
|
|
||||||
|
# The location at which the LDAP server(s) should be reachable.
|
||||||
|
{% if 'slapd' in group_names %}
|
||||||
|
uri ldapi:///
|
||||||
|
{% else %}
|
||||||
|
{% for server in ldap.servers %}
|
||||||
|
uri ldaps://{{ server }}/
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
# The search base that will be used for all queries.
|
||||||
|
base {{ ldap.base }}
|
||||||
|
|
||||||
|
# The LDAP protocol version to use.
|
||||||
|
#ldap_version 3
|
||||||
|
|
||||||
|
# The DN to bind with for normal lookups.
|
||||||
|
#binddn cn=annonymous,dc=example,dc=net
|
||||||
|
#bindpw secret
|
||||||
|
|
||||||
|
# The DN used for password modifications by root.
|
||||||
|
#rootpwmoddn cn=admin,dc=example,dc=com
|
||||||
|
|
||||||
|
# SSL options
|
||||||
|
#ssl off
|
||||||
|
tls_reqcert allow
|
||||||
|
tls_cacertfile /etc/ssl/certs/ca-certificates.crt
|
||||||
|
|
||||||
|
# The search scope.
|
||||||
|
#scope sub
|
5
roles/nginx/handlers/main.yml
Normal file
5
roles/nginx/handlers/main.yml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
- name: Reload nginx
|
||||||
|
systemd:
|
||||||
|
name: nginx
|
||||||
|
state: reloaded
|
128
roles/nginx/tasks/main.yml
Normal file
128
roles/nginx/tasks/main.yml
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
---
|
||||||
|
- name: Install NGINX
|
||||||
|
apt:
|
||||||
|
update_cache: true
|
||||||
|
name: nginx
|
||||||
|
register: apt_result
|
||||||
|
retries: 3
|
||||||
|
until: apt_result is succeeded
|
||||||
|
|
||||||
|
- name: Copy proxypass snippets
|
||||||
|
template:
|
||||||
|
src: "nginx/snippets/options-proxypass.conf.j2"
|
||||||
|
dest: "/etc/nginx/snippets/options-proxypass.conf"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: 0644
|
||||||
|
|
||||||
|
- name: Copy SSL snippets
|
||||||
|
template:
|
||||||
|
src: "nginx/snippets/options-ssl.conf.j2"
|
||||||
|
dest: "/etc/nginx/snippets/options-ssl.{{ item.name }}.conf"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: 0644
|
||||||
|
loop: "{{ nginx.ssl }}"
|
||||||
|
|
||||||
|
- name: Disable default site
|
||||||
|
file:
|
||||||
|
dest: "/etc/nginx/sites-enabled/default"
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- name: Copy reverse proxy sites
|
||||||
|
when: reverseproxy is defined
|
||||||
|
template:
|
||||||
|
src: "nginx/sites-available/{{ item }}.j2"
|
||||||
|
dest: "/etc/nginx/sites-available/{{ item }}"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: 0644
|
||||||
|
loop:
|
||||||
|
- reverseproxy
|
||||||
|
- reverseproxy_redirect_dname
|
||||||
|
- redirect
|
||||||
|
notify: Reload nginx
|
||||||
|
|
||||||
|
- name: Activate reverse proxy sites
|
||||||
|
when: reverseproxy is defined
|
||||||
|
file:
|
||||||
|
src: "/etc/nginx/sites-available/{{ item }}"
|
||||||
|
dest: "/etc/nginx/sites-enabled/{{ item }}"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
state: link
|
||||||
|
loop:
|
||||||
|
- reverseproxy
|
||||||
|
- reverseproxy_redirect_dname
|
||||||
|
- redirect
|
||||||
|
notify: Reload nginx
|
||||||
|
ignore_errors: "{{ ansible_check_mode }}"
|
||||||
|
|
||||||
|
- name: Copy service nginx configuration
|
||||||
|
when: nginx.servers is defined and nginx.servers|length > 0
|
||||||
|
template:
|
||||||
|
src: "nginx/sites-available/service.j2"
|
||||||
|
dest: "/etc/nginx/sites-available/{{ nginx.service_name }}"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: 0644
|
||||||
|
notify: Reload nginx
|
||||||
|
|
||||||
|
- name: Activate local nginx service site
|
||||||
|
when: nginx.servers is defined and nginx.servers|length > 0
|
||||||
|
file:
|
||||||
|
src: "/etc/nginx/sites-available/{{ nginx.service_name }}"
|
||||||
|
dest: "/etc/nginx/sites-enabled/{{ nginx.service_name }}"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
state: link
|
||||||
|
notify: Reload nginx
|
||||||
|
ignore_errors: "{{ ansible_check_mode }}"
|
||||||
|
|
||||||
|
- name: Copy 50x error page
|
||||||
|
template:
|
||||||
|
src: www/html/50x.html.j2
|
||||||
|
dest: /var/www/html/50x.html
|
||||||
|
owner: www-data
|
||||||
|
group: www-data
|
||||||
|
mode: 0644
|
||||||
|
|
||||||
|
- name: Copy robots.txt file
|
||||||
|
when: nginx.deploy_robots_file
|
||||||
|
template:
|
||||||
|
src: www/html/robots.txt.j2
|
||||||
|
dest: /var/www/html/robots.txt
|
||||||
|
owner: www-data
|
||||||
|
group: www-data
|
||||||
|
mode: 0644
|
||||||
|
|
||||||
|
- name: Install passwords
|
||||||
|
when: nginx.auth_passwd|length > 0
|
||||||
|
template:
|
||||||
|
src: nginx/passwd.j2
|
||||||
|
dest: /etc/nginx/passwd
|
||||||
|
mode: 0644
|
||||||
|
|
||||||
|
- name: Copy 401 error page
|
||||||
|
when: nginx.auth_passwd|length > 0
|
||||||
|
template:
|
||||||
|
src: www/html/401.html.j2
|
||||||
|
dest: /var/www/html/401.html
|
||||||
|
owner: www-data
|
||||||
|
group: www-data
|
||||||
|
mode: 0644
|
||||||
|
|
||||||
|
- name: Indicate role in motd
|
||||||
|
template:
|
||||||
|
src: update-motd.d/05-service.j2
|
||||||
|
dest: /etc/update-motd.d/05-nginx
|
||||||
|
mode: 0755
|
||||||
|
|
||||||
|
- name: Clean old files
|
||||||
|
file:
|
||||||
|
path: "{{ item }}"
|
||||||
|
state: absent
|
||||||
|
loop:
|
||||||
|
- "/etc/nginx/snippets/options-ssl.conf"
|
||||||
|
- "/var/www/custom_401.html"
|
||||||
|
- "/var/www/robots.txt"
|
8
roles/nginx/templates/letsencrypt/dhparam.j2
Normal file
8
roles/nginx/templates/letsencrypt/dhparam.j2
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
-----BEGIN DH PARAMETERS-----
|
||||||
|
MIIBCAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz
|
||||||
|
+8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a
|
||||||
|
87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7
|
||||||
|
YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi
|
||||||
|
7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD
|
||||||
|
ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg==
|
||||||
|
-----END DH PARAMETERS-----
|
4
roles/nginx/templates/nginx/passwd.j2
Normal file
4
roles/nginx/templates/nginx/passwd.j2
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{{ ansible_header | comment }}
|
||||||
|
{% for user, hash in nginx.auth_passwd.items() -%}
|
||||||
|
{{ user }}:{{ hash }}
|
||||||
|
{% endfor -%}
|
87
roles/nginx/templates/nginx/sites-available/redirect.j2
Normal file
87
roles/nginx/templates/nginx/sites-available/redirect.j2
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
{{ ansible_header | comment }}
|
||||||
|
|
||||||
|
{% for site in reverseproxy.redirect_sites %}
|
||||||
|
# Redirect http://{{ site.from }} to http://{{ site.to }}
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
listen [::]:80;
|
||||||
|
|
||||||
|
server_name {{ site.from }};
|
||||||
|
|
||||||
|
{% for realip in nginx.real_ip_from %}
|
||||||
|
set_real_ip_from {{ realip }};
|
||||||
|
{% endfor %}
|
||||||
|
real_ip_header X-Real-Ip;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
return 302 http://{{ site.to }}$request_uri;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Redirect https://{{ site.from }} to https://{{ site.to }}
|
||||||
|
server {
|
||||||
|
listen 443 ssl http2;
|
||||||
|
listen [::]:443 ssl http2;
|
||||||
|
|
||||||
|
server_name {{ site.from }};
|
||||||
|
|
||||||
|
# SSL common conf
|
||||||
|
include "/etc/nginx/snippets/options-ssl.{{ site.ssl|default(nginx.default_ssl_domain) }}.conf";
|
||||||
|
|
||||||
|
{% for realip in nginx.real_ip_from %}
|
||||||
|
set_real_ip_from {{ realip }};
|
||||||
|
{% endfor %}
|
||||||
|
real_ip_header X-Real-Ip;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
return 302 https://{{ site.to }}$request_uri;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{# Also redirect for DNAMEs #}
|
||||||
|
{% for dname in reverseproxy.redirect_dnames %}
|
||||||
|
{% for site in reverseproxy.redirect_sites %}
|
||||||
|
{% set from = site.from | regex_replace('crans.org', dname) %}
|
||||||
|
{% if from != site.from %}
|
||||||
|
# Redirect http://{{ from }} to http://{{ site.to }}
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
listen [::]:80;
|
||||||
|
|
||||||
|
server_name {{ from }};
|
||||||
|
|
||||||
|
{% for realip in nginx.real_ip_from %}
|
||||||
|
set_real_ip_from {{ realip }};
|
||||||
|
{% endfor %}
|
||||||
|
real_ip_header X-Real-Ip;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
return 302 http://{{ site.to }}$request_uri;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Redirect https://{{ from }} to https://{{ site.to }}
|
||||||
|
server {
|
||||||
|
listen 443 ssl http2;
|
||||||
|
listen [::]:443 ssl http2;
|
||||||
|
|
||||||
|
server_name {{ from }};
|
||||||
|
|
||||||
|
# SSL common conf
|
||||||
|
include "/etc/nginx/snippets/options-ssl.{{ site.ssl|default(nginx.default_ssl_domain) }}.conf";
|
||||||
|
|
||||||
|
{% for realip in nginx.real_ip_from %}
|
||||||
|
set_real_ip_from {{ realip }};
|
||||||
|
{% endfor %}
|
||||||
|
real_ip_header X-Real-Ip;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
return 302 https://{{ site.to }}$request_uri;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endfor %}
|
62
roles/nginx/templates/nginx/sites-available/reverseproxy.j2
Normal file
62
roles/nginx/templates/nginx/sites-available/reverseproxy.j2
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
{{ ansible_header | comment }}
|
||||||
|
|
||||||
|
# Automatic Connection header for WebSocket support
|
||||||
|
# See http://nginx.org/en/docs/http/websocket.html
|
||||||
|
map $http_upgrade $connection_upgrade {
|
||||||
|
default upgrade;
|
||||||
|
'' close;
|
||||||
|
}
|
||||||
|
|
||||||
|
{% for site in reverseproxy.reverseproxy_sites %}
|
||||||
|
# Redirect http://{{ site.from }} to https://{{ site.from }}
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
listen [::]:80;
|
||||||
|
|
||||||
|
server_name {{ site.from }};
|
||||||
|
|
||||||
|
{% for realip in nginx.real_ip_from %}
|
||||||
|
set_real_ip_from {{ realip }};
|
||||||
|
{% endfor %}
|
||||||
|
real_ip_header X-Real-Ip;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
return 302 https://$host$request_uri;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Reverse proxify https://{{ site.from }} to {% if not site.to.startswith("http") %}http://{% endif %}{{ site.to }}
|
||||||
|
server {
|
||||||
|
listen 443 ssl http2;
|
||||||
|
listen [::]:443 ssl http2;
|
||||||
|
|
||||||
|
server_name {{ site.from }};
|
||||||
|
|
||||||
|
# SSL common conf
|
||||||
|
include "/etc/nginx/snippets/options-ssl.{{ site.ssl|default(nginx.default_ssl_domain) }}.conf";
|
||||||
|
|
||||||
|
# Log into separate log files
|
||||||
|
access_log /var/log/nginx/{{ site.from }}.log;
|
||||||
|
error_log /var/log/nginx/{{ site.from }}_error.log;
|
||||||
|
|
||||||
|
# Keep the TCP connection open a bit for faster browsing
|
||||||
|
keepalive_timeout 70;
|
||||||
|
|
||||||
|
# Custom error page
|
||||||
|
error_page 500 502 503 504 /50x.html;
|
||||||
|
location = /50x.html {
|
||||||
|
root /var/www/html;
|
||||||
|
}
|
||||||
|
|
||||||
|
{% for realip in nginx.real_ip_from %}
|
||||||
|
set_real_ip_from {{ realip }};
|
||||||
|
{% endfor %}
|
||||||
|
real_ip_header X-Real-Ip;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass {% if not site.to.startswith("http") %}http://{% endif %}{{ site.to }};
|
||||||
|
include "/etc/nginx/snippets/options-proxypass.conf";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{% endfor %}
|
@@ -0,0 +1,47 @@
|
|||||||
|
{{ ansible_header | comment }}
|
||||||
|
|
||||||
|
{% for dname in reverseproxy.redirect_dnames %}
|
||||||
|
{% for site in reverseproxy.reverseproxy_sites %}
|
||||||
|
{% set from = site.from | regex_replace('crans.org', dname) %}
|
||||||
|
{% set to = site.from %}
|
||||||
|
{% if from != site.from %}
|
||||||
|
# Redirect http://{{ from }} to http://{{ to }}
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
listen [::]:80;
|
||||||
|
|
||||||
|
server_name {{ from }};
|
||||||
|
|
||||||
|
{% for realip in nginx.real_ip_from %}
|
||||||
|
set_real_ip_from {{ realip }};
|
||||||
|
{% endfor %}
|
||||||
|
real_ip_header X-Real-Ip;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
return 302 http://{{ to }}$request_uri;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Redirect https://{{ from }} to https://{{ to }}
|
||||||
|
server {
|
||||||
|
listen 443 ssl http2;
|
||||||
|
listen [::]:443 ssl http2;
|
||||||
|
|
||||||
|
server_name {{ from }};
|
||||||
|
|
||||||
|
# SSL common conf
|
||||||
|
include "/etc/nginx/snippets/options-ssl.{{ site.ssl|default(nginx.default_ssl_domain) }}.conf";
|
||||||
|
|
||||||
|
{% for realip in nginx.real_ip_from %}
|
||||||
|
set_real_ip_from {{ realip }};
|
||||||
|
{% endfor %}
|
||||||
|
real_ip_header X-Real-Ip;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
return 302 https://{{ to }}$request_uri;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endfor %}
|
132
roles/nginx/templates/nginx/sites-available/service.j2
Normal file
132
roles/nginx/templates/nginx/sites-available/service.j2
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
{{ ansible_header | comment }}
|
||||||
|
|
||||||
|
# Automatic Connection header for WebSocket support
|
||||||
|
# See http://nginx.org/en/docs/http/websocket.html
|
||||||
|
map $http_upgrade $connection_upgrade {
|
||||||
|
default upgrade;
|
||||||
|
'' close;
|
||||||
|
}
|
||||||
|
|
||||||
|
{% for upstream in nginx.upstreams -%}
|
||||||
|
upstream {{ upstream.name }} {
|
||||||
|
# Path of the server
|
||||||
|
server {{ upstream.server }};
|
||||||
|
}
|
||||||
|
{% endfor -%}
|
||||||
|
|
||||||
|
{% if nginx.default_ssl_server -%}
|
||||||
|
# Redirect all services to the main site
|
||||||
|
server {
|
||||||
|
listen 443 default_server ssl;
|
||||||
|
listen [::]:443 default_server ssl;
|
||||||
|
include "/etc/nginx/snippets/options-ssl.{{ nginx.default_ssl_domain }}.conf";
|
||||||
|
|
||||||
|
server_name _;
|
||||||
|
charset utf-8;
|
||||||
|
|
||||||
|
# Hide Nginx version
|
||||||
|
server_tokens off;
|
||||||
|
|
||||||
|
{% for realip in nginx.real_ip_from %}
|
||||||
|
set_real_ip_from {{ realip }};
|
||||||
|
{% endfor %}
|
||||||
|
real_ip_header X-Real-Ip;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
return 302 https://{{ nginx.default_ssl_server }}$request_uri;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{% endif -%}
|
||||||
|
|
||||||
|
{% if nginx.default_server -%}
|
||||||
|
# Redirect all services to the main site
|
||||||
|
server {
|
||||||
|
listen 80 default_server;
|
||||||
|
listen [::]:80 default_server;
|
||||||
|
|
||||||
|
server_name _;
|
||||||
|
charset utf-8;
|
||||||
|
|
||||||
|
# Hide Nginx version
|
||||||
|
server_tokens off;
|
||||||
|
|
||||||
|
{% for realip in nginx.real_ip_from %}
|
||||||
|
set_real_ip_from {{ realip }};
|
||||||
|
{% endfor %}
|
||||||
|
real_ip_header X-Real-Ip;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
return 302 http://{{ nginx.default_server }}$request_uri;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{% endif -%}
|
||||||
|
|
||||||
|
{% for server in nginx.servers %}
|
||||||
|
{% if server.ssl is defined and server.ssl -%}
|
||||||
|
# Redirect HTTP to HTTPS
|
||||||
|
server {
|
||||||
|
listen 80{% if server.default is defined and server.default %} default_server{% endif %};
|
||||||
|
listen [::]:80{% if server.default is defined and server.default %} default_server{% endif %};
|
||||||
|
|
||||||
|
server_name {{ server.server_name|join(" ") }};
|
||||||
|
charset utf-8;
|
||||||
|
|
||||||
|
# Hide Nginx version
|
||||||
|
server_tokens off;
|
||||||
|
|
||||||
|
{% for realip in nginx.real_ip_from %}
|
||||||
|
set_real_ip_from {{ realip }};
|
||||||
|
{% endfor %}
|
||||||
|
real_ip_header X-Real-Ip;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
return 302 https://$host$request_uri;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{% endif -%}
|
||||||
|
|
||||||
|
server {
|
||||||
|
{% if server.ssl is defined and server.ssl -%}
|
||||||
|
listen 443{% if server.default is defined and server.default %} default_server{% endif %} ssl;
|
||||||
|
listen [::]:443{% if server.default is defined and server.default %} default_server{% endif %} ssl;
|
||||||
|
include "/etc/nginx/snippets/options-ssl.{{ server.ssl }}.conf";
|
||||||
|
{% else -%}
|
||||||
|
listen 80{% if server.default is defined and server.default %} default_server{% endif %};
|
||||||
|
listen [::]:80{% if server.default is defined and server.default %} default_server{% endif %};
|
||||||
|
{% endif -%}
|
||||||
|
|
||||||
|
server_name {{ server.server_name|join(" ") }};
|
||||||
|
charset utf-8;
|
||||||
|
|
||||||
|
# Hide Nginx version
|
||||||
|
server_tokens off;
|
||||||
|
|
||||||
|
{% for realip in nginx.real_ip_from %}
|
||||||
|
set_real_ip_from {{ realip }};
|
||||||
|
{% endfor %}
|
||||||
|
real_ip_header X-Real-Ip;
|
||||||
|
|
||||||
|
{% if server.root is defined %}root {{ server.root }};{% endif %}
|
||||||
|
{% if server.index is defined %}index {{ server.index|join(" ") }};{% endif %}
|
||||||
|
|
||||||
|
{% if server.access_log is defined %}access_log {{ server.access_log }};{% endif %}
|
||||||
|
{% if server.error_log is defined %}error_log {{ server.error_log }};{% endif %}
|
||||||
|
|
||||||
|
{% if server.additional_params is defined %}
|
||||||
|
{% for param in server.additional_params %}
|
||||||
|
{{ param }};
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if server.locations is defined %}
|
||||||
|
{% for location in server.locations %}
|
||||||
|
location {{ location.filter }} {
|
||||||
|
{% for param in location.params %}
|
||||||
|
{{ param }};
|
||||||
|
{% endfor %}
|
||||||
|
}
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
{% endfor %}
|
18
roles/nginx/templates/nginx/snippets/fastcgi.conf.j2
Normal file
18
roles/nginx/templates/nginx/snippets/fastcgi.conf.j2
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{{ ansible_header | comment }}
|
||||||
|
|
||||||
|
# regex to split $uri to $fastcgi_script_name and $fastcgi_path
|
||||||
|
fastcgi_split_path_info (^/[^/]*)(.*)$;
|
||||||
|
|
||||||
|
# check that the PHP script exists before passing it
|
||||||
|
try_files $fastcgi_script_name =404;
|
||||||
|
|
||||||
|
# Bypass the fact that try_files resets $fastcgi_path_info
|
||||||
|
# see: http://trac.nginx.org/nginx/ticket/321
|
||||||
|
set $path_info $fastcgi_path_info;
|
||||||
|
fastcgi_param PATH_INFO $path_info;
|
||||||
|
|
||||||
|
# Let NGINX handle errors
|
||||||
|
fastcgi_intercept_errors on;
|
||||||
|
|
||||||
|
include /etc/nginx/fastcgi.conf;
|
||||||
|
fastcgi_pass unix:/var/run/fcgiwrap.socket;
|
@@ -0,0 +1,19 @@
|
|||||||
|
{{ ansible_header | comment }}
|
||||||
|
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
|
||||||
|
# Pass the real client IP
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
|
||||||
|
# Tell proxified server that we are HTTPS, fix Wordpress
|
||||||
|
proxy_set_header X-Forwarded-Proto https;
|
||||||
|
|
||||||
|
# WebSocket support
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection $connection_upgrade;
|
||||||
|
|
||||||
|
# For Owncloud WebDav
|
||||||
|
client_max_body_size 10G;
|
17
roles/nginx/templates/nginx/snippets/options-ssl.conf.j2
Normal file
17
roles/nginx/templates/nginx/snippets/options-ssl.conf.j2
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
{{ ansible_header | comment }}
|
||||||
|
|
||||||
|
ssl_certificate {{ item.cert }};
|
||||||
|
ssl_certificate_key {{ item.cert_key }};
|
||||||
|
ssl_session_timeout 1d;
|
||||||
|
ssl_session_cache shared:MozSSL:10m;
|
||||||
|
ssl_session_tickets off;
|
||||||
|
ssl_dhparam /etc/letsencrypt/dhparam;
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
|
||||||
|
ssl_prefer_server_ciphers off;
|
||||||
|
|
||||||
|
# Enable OCSP Stapling, point to certificate chain
|
||||||
|
ssl_stapling on;
|
||||||
|
ssl_stapling_verify on;
|
||||||
|
ssl_trusted_certificate {{ item.trusted_cert }};
|
||||||
|
|
3
roles/nginx/templates/update-motd.d/05-service.j2
Executable file
3
roles/nginx/templates/update-motd.d/05-service.j2
Executable file
@@ -0,0 +1,3 @@
|
|||||||
|
#!/usr/bin/tail +14
|
||||||
|
{{ ansible_header | comment }}
|
||||||
|
[0m> [38;5;82mNGINX[0m a été déployé sur cette machine. Voir [38;5;6m/etc/nginx/[0m.
|
18
roles/nginx/templates/www/html/401.html.j2
Normal file
18
roles/nginx/templates/www/html/401.html.j2
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{{ ansible_header | comment('xml') }}
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Accès refusé</title>
|
||||||
|
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Accès refusé</h1>
|
||||||
|
<p>
|
||||||
|
Pour éviter le scan des adresses de diffusions par un robot, cette page demande un identifiant et mot de passe.
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>Identifiant : <em>Stop</em></li>
|
||||||
|
<li>Mot de passe : <em>Spam</em></li>
|
||||||
|
</ul>
|
||||||
|
</body>
|
||||||
|
</html>
|
63
roles/nginx/templates/www/html/50x.html.j2
Normal file
63
roles/nginx/templates/www/html/50x.html.j2
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="fr">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>502</title>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
line-height: 1.2;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
color: #888;
|
||||||
|
display: table;
|
||||||
|
font-family: sans-serif;
|
||||||
|
height: 100%;
|
||||||
|
text-align: center;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
display: table-cell;
|
||||||
|
vertical-align: middle;
|
||||||
|
margin: 2em auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #888;
|
||||||
|
text-decoration: underline dotted;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
color: #555;
|
||||||
|
font-size: 2em;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin: 1em auto;
|
||||||
|
max-width: 480px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 280px) {
|
||||||
|
body, p {
|
||||||
|
width: 95%;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 1.5em;
|
||||||
|
margin: 0 0 0.3em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>502</h1>
|
||||||
|
<p>Whoops, le service prend trop de temps à répondre…</p>
|
||||||
|
<p>Essayez de rafraîchir la page. Si le problème persiste, pensez
|
||||||
|
à contacter <a href="mailto:{{ nginx.contact }}">{{ nginx.who }}</a>.</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
2
roles/nginx/templates/www/html/robots.txt.j2
Normal file
2
roles/nginx/templates/www/html/robots.txt.j2
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
User-agent: *
|
||||||
|
Disallow: /
|
5
roles/ntp-client/handlers/main.yml
Normal file
5
roles/ntp-client/handlers/main.yml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
- name: Restart systemd-timesyncd
|
||||||
|
service:
|
||||||
|
name: systemd-timesyncd
|
||||||
|
state: restarted
|
29
roles/ntp-client/tasks/main.yml
Normal file
29
roles/ntp-client/tasks/main.yml
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
---
|
||||||
|
- name: Clean up ntp
|
||||||
|
apt:
|
||||||
|
state: absent
|
||||||
|
name: ntp
|
||||||
|
purge: true
|
||||||
|
register: apt_result
|
||||||
|
retries: 3
|
||||||
|
until: apt_result is succeeded
|
||||||
|
when: "'ntp_server' not in group_names"
|
||||||
|
|
||||||
|
- name: Install systemd-timesyncd (bullseye)
|
||||||
|
apt:
|
||||||
|
name: systemd-timesyncd
|
||||||
|
update_cache: true
|
||||||
|
install_recommends: false
|
||||||
|
register: apt_result
|
||||||
|
retries: 3
|
||||||
|
until: apt_result is succeeded
|
||||||
|
when:
|
||||||
|
- "'ntp_server' not in group_names"
|
||||||
|
- ansible_distribution_release == "bullseye"
|
||||||
|
|
||||||
|
- name: Configure NTP
|
||||||
|
template:
|
||||||
|
src: systemd/timesyncd.conf.j2
|
||||||
|
dest: /etc/systemd/timesyncd.conf
|
||||||
|
notify: Restart systemd-timesyncd
|
||||||
|
when: "'ntp_server' not in group_names"
|
2
roles/ntp-client/templates/systemd/timesyncd.conf.j2
Normal file
2
roles/ntp-client/templates/systemd/timesyncd.conf.j2
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
[Time]
|
||||||
|
NTP={{ ntp_client.servers | join(' ') }}
|
27
roles/ntp-server/tasks/main.yml
Normal file
27
roles/ntp-server/tasks/main.yml
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
---
|
||||||
|
- name: Install NTP
|
||||||
|
apt:
|
||||||
|
update_cache: true
|
||||||
|
name: ntp
|
||||||
|
register: apt_result
|
||||||
|
retries: 3
|
||||||
|
until: apt_result is succeeded
|
||||||
|
|
||||||
|
- name: Configure NTP daemon
|
||||||
|
lineinfile:
|
||||||
|
path: /etc/default/ntp
|
||||||
|
regexp: '^NTPD_OPTS'
|
||||||
|
line: NTPD_OPTS='-g -x'
|
||||||
|
check_mode: no
|
||||||
|
|
||||||
|
- name: Configure NTP
|
||||||
|
template:
|
||||||
|
src: ntp.conf.j2
|
||||||
|
dest: /etc/ntp.conf
|
||||||
|
mode: 0644
|
||||||
|
|
||||||
|
- name: Start ntp service
|
||||||
|
systemd:
|
||||||
|
name: ntp
|
||||||
|
enabled: true
|
||||||
|
state: started
|
62
roles/ntp-server/templates/ntp.conf.j2
Normal file
62
roles/ntp-server/templates/ntp.conf.j2
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
{{ ansible_header | comment }}
|
||||||
|
# /etc/ntp.conf, configuration for ntpd; see ntp.conf(5) for help
|
||||||
|
|
||||||
|
driftfile /var/lib/ntp/ntp.drift
|
||||||
|
|
||||||
|
# Leap seconds definition provided by tzdata
|
||||||
|
leapfile /usr/share/zoneinfo/leap-seconds.list
|
||||||
|
|
||||||
|
# Enable this if you want statistics to be logged.
|
||||||
|
#statsdir /var/log/ntpstats/
|
||||||
|
|
||||||
|
statistics loopstats peerstats clockstats
|
||||||
|
filegen loopstats file loopstats type day enable
|
||||||
|
filegen peerstats file peerstats type day enable
|
||||||
|
filegen clockstats file clockstats type day enable
|
||||||
|
|
||||||
|
|
||||||
|
# pool.ntp.org maps to about 1000 low-stratum NTP servers. Your server will
|
||||||
|
# pick a different set every time it starts up. Please consider joining the
|
||||||
|
# pool: <http://www.pool.ntp.org/join.html>
|
||||||
|
pool ntp.crans.org iburst
|
||||||
|
pool 0.debian.pool.ntp.org iburst
|
||||||
|
pool 1.debian.pool.ntp.org iburst
|
||||||
|
pool 2.debian.pool.ntp.org iburst
|
||||||
|
pool 3.debian.pool.ntp.org iburst
|
||||||
|
|
||||||
|
|
||||||
|
# Access control configuration; see /usr/share/doc/ntp-doc/html/accopt.html for
|
||||||
|
# details. The web page <http://support.ntp.org/bin/view/Support/AccessRestrictions>
|
||||||
|
# might also be helpful.
|
||||||
|
#
|
||||||
|
# Note that "restrict" applies to both servers and clients, so a configuration
|
||||||
|
# that might be intended to block requests from certain clients could also end
|
||||||
|
# up blocking replies from your own upstream servers.
|
||||||
|
|
||||||
|
# By default, exchange time with everybody, but don't allow configuration.
|
||||||
|
restrict -4 default kod notrap nomodify nopeer noquery limited
|
||||||
|
restrict -6 default kod notrap nomodify nopeer noquery limited
|
||||||
|
|
||||||
|
# Local users may interrogate the ntp server more closely.
|
||||||
|
restrict 127.0.0.1
|
||||||
|
restrict ::1
|
||||||
|
|
||||||
|
# Needed for adding pool entries
|
||||||
|
restrict source notrap nomodify noquery
|
||||||
|
|
||||||
|
# Server on adm can sync
|
||||||
|
restrict 172.16.42.0 mask 255.255.255.0 notrap nomodify
|
||||||
|
|
||||||
|
# Clients from this (example!) subnet have unlimited access, but only if
|
||||||
|
# cryptographically authenticated.
|
||||||
|
#restrict 192.168.123.0 mask 255.255.255.0 notrust
|
||||||
|
|
||||||
|
|
||||||
|
# If you want to provide time to your local subnet, change the next line.
|
||||||
|
# (Again, the address is an example only.)
|
||||||
|
#broadcast 192.168.123.255
|
||||||
|
|
||||||
|
# If you want to listen to time broadcasts on your local subnet, de-comment the
|
||||||
|
# next lines. Please do this only if you trust everybody on the network!
|
||||||
|
#disable auth
|
||||||
|
#broadcastclient
|
13
roles/slapd/README.md
Normal file
13
roles/slapd/README.md
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
# SLAPD
|
||||||
|
|
||||||
|
Deploie un serveur ldap master ou replica
|
||||||
|
|
||||||
|
## VARS
|
||||||
|
|
||||||
|
slapd:
|
||||||
|
- ip : l'ip sur lequel il va installer le serveur ldap
|
||||||
|
- replica : s'il s'agit d'un master ou d'une replica
|
||||||
|
- replica_rid : le numéro de replica du serveur
|
||||||
|
- master_ip : l'ip du master
|
||||||
|
- replication_credentials : les credientials pour authentifier les replicas
|
||||||
|
auprès du master
|
6
roles/slapd/handlers/main.yml
Normal file
6
roles/slapd/handlers/main.yml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
- name: Restart slapd
|
||||||
|
service:
|
||||||
|
name: slapd.service
|
||||||
|
state: restarted
|
35
roles/slapd/tasks/main.yml
Normal file
35
roles/slapd/tasks/main.yml
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
---
|
||||||
|
- name: Install slapd
|
||||||
|
apt:
|
||||||
|
update_cache: true
|
||||||
|
name:
|
||||||
|
- slapd
|
||||||
|
register: apt_result
|
||||||
|
retries: 3
|
||||||
|
until: apt_result is succeeded
|
||||||
|
|
||||||
|
- name: Remove slapd config directory
|
||||||
|
file:
|
||||||
|
path: /etc/ldap/slapd.d/
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- name: Deploy slapd configuration
|
||||||
|
template:
|
||||||
|
src: "ldap/{{ item.dest }}.j2"
|
||||||
|
dest: "/etc/ldap/{{ item.dest }}"
|
||||||
|
mode: "{{ item.mode }}"
|
||||||
|
owner: openldap
|
||||||
|
group: openldap
|
||||||
|
loop:
|
||||||
|
- { dest: slapd.conf, mode: "0600" }
|
||||||
|
#- { dest: ldap.key, mode: "0600" }
|
||||||
|
#- { dest: ldap.pem, mode: "0644" }
|
||||||
|
notify: Restart slapd
|
||||||
|
|
||||||
|
- name: Deploy ldap services
|
||||||
|
lineinfile:
|
||||||
|
path: /etc/default/slapd
|
||||||
|
regexp: '^SLAPD_SERVICES='
|
||||||
|
line: 'SLAPD_SERVICES="ldaps://{{ slapd.ip }}/ ldapi:///"'
|
||||||
|
notify: Restart slapd
|
||||||
|
check_mode: no
|
1
roles/slapd/templates/ldap/ldap.key.j2
Normal file
1
roles/slapd/templates/ldap/ldap.key.j2
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{{ slapd.private_key }}
|
1
roles/slapd/templates/ldap/ldap.pem.j2
Normal file
1
roles/slapd/templates/ldap/ldap.pem.j2
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{{ slapd.certificate }}
|
202
roles/slapd/templates/ldap/slapd.conf.j2
Normal file
202
roles/slapd/templates/ldap/slapd.conf.j2
Normal file
@@ -0,0 +1,202 @@
|
|||||||
|
# This is the main slapd configuration file. See slapd.conf(5) for more
|
||||||
|
# info on the configuration options.
|
||||||
|
|
||||||
|
#######################################################################
|
||||||
|
# Global Directives:
|
||||||
|
|
||||||
|
# Schema and objectClass definitions
|
||||||
|
include /etc/ldap/schema/core.schema
|
||||||
|
include /etc/ldap/schema/cosine.schema
|
||||||
|
include /etc/ldap/schema/nis.schema
|
||||||
|
include /etc/ldap/schema/inetorgperson.schema
|
||||||
|
|
||||||
|
# Where the pid file is put. The init.d script
|
||||||
|
# will not stop the server if you change this.
|
||||||
|
pidfile /var/run/slapd/slapd.pid
|
||||||
|
|
||||||
|
# List of arguments that were passed to the server
|
||||||
|
argsfile /var/run/slapd/slapd.args
|
||||||
|
|
||||||
|
# Read slapd.conf(5) for possible values
|
||||||
|
loglevel none
|
||||||
|
|
||||||
|
# Where the dynamically loaded modules are stored
|
||||||
|
modulepath /usr/lib/ldap
|
||||||
|
moduleload back_mdb
|
||||||
|
{% if not slapd.replica %}
|
||||||
|
moduleload auditlog
|
||||||
|
|
||||||
|
overlay auditlog
|
||||||
|
auditlog /var/log/openldap/auditlog.log
|
||||||
|
|
||||||
|
moduleload constraint
|
||||||
|
overlay constraint
|
||||||
|
constraint_attribute description regex {{ slapd.regex }}
|
||||||
|
restrict=ldap:///ou=hosts,dc=ynerant,dc=fr??one?(objectClass=device)
|
||||||
|
constraint_attribute uid regex ^ynerant
|
||||||
|
restrict=ldap:///ou=passwd,dc=ynerant,dc=fr??one?(objectClass=posixAccount)
|
||||||
|
|
||||||
|
moduleload syncprov
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
# TLS Certificates
|
||||||
|
#TLSCipherSuite HIGH:MEDIUM:-SSLv2:-SSLv3
|
||||||
|
#TLSCertificateFile /etc/ldap/ldap.pem
|
||||||
|
#TLSCertificateKeyFile /etc/ldap/ldap.key
|
||||||
|
|
||||||
|
# The maximum number of entries that is returned for a search operation
|
||||||
|
sizelimit 500
|
||||||
|
|
||||||
|
# The tool-threads parameter sets the actual amount of cpu's that is used
|
||||||
|
# for indexing.
|
||||||
|
tool-threads 1
|
||||||
|
|
||||||
|
#######################################################################
|
||||||
|
# Specific Backend Directives for mdb:
|
||||||
|
# Backend specific directives apply to this backend until another
|
||||||
|
# 'backend' directive occurs
|
||||||
|
backend mdb
|
||||||
|
|
||||||
|
#######################################################################
|
||||||
|
# Specific Backend Directives for 'other':
|
||||||
|
# Backend specific directives apply to this backend until another
|
||||||
|
# 'backend' directive occurs
|
||||||
|
#backend <other>
|
||||||
|
|
||||||
|
#######################################################################
|
||||||
|
# Specific Directives for database #1, of type mdb:
|
||||||
|
# Database specific directives apply to this databasse until another
|
||||||
|
# 'database' directive occurs
|
||||||
|
database mdb
|
||||||
|
|
||||||
|
# The base of your directory in database #1
|
||||||
|
suffix "dc=ynerant,dc=fr"
|
||||||
|
|
||||||
|
# rootdn directive for specifying a superuser on the database. This is needed
|
||||||
|
# for syncrepl.
|
||||||
|
rootdn "cn=admin,dc=ynerant,dc=fr"
|
||||||
|
|
||||||
|
# Where the database file are physically stored for database #1
|
||||||
|
directory "/var/lib/ldap"
|
||||||
|
|
||||||
|
# The dbconfig settings are used to generate a DB_CONFIG file the first
|
||||||
|
# time slapd starts. They do NOT override existing an existing DB_CONFIG
|
||||||
|
# file. You should therefore change these settings in DB_CONFIG directly
|
||||||
|
# or remove DB_CONFIG and restart slapd for changes to take effect.
|
||||||
|
|
||||||
|
# For the Debian package we use 2MB as default but be sure to update this
|
||||||
|
# value if you have plenty of RAM
|
||||||
|
#dbconfig set_cachesize 0 2097152 0
|
||||||
|
|
||||||
|
# Sven Hartge reported that he had to set this value incredibly high
|
||||||
|
# to get slapd running at all. See http://bugs.debian.org/303057 for more
|
||||||
|
# information.
|
||||||
|
|
||||||
|
# Number of objects that can be locked at the same time.
|
||||||
|
#dbconfig set_lk_max_objects 1500
|
||||||
|
# Number of locks (both requested and granted)
|
||||||
|
#dbconfig set_lk_max_locks 1500
|
||||||
|
# Number of lockers
|
||||||
|
#dbconfig set_lk_max_lockers 1500
|
||||||
|
|
||||||
|
# Indexing options for database #1
|
||||||
|
index objectClass eq
|
||||||
|
|
||||||
|
# Save the time that the entry gets modified, for database #1
|
||||||
|
lastmod on
|
||||||
|
|
||||||
|
# Checkpoint the BerkeleyDB database periodically in case of system
|
||||||
|
# failure and to speed slapd shutdown.
|
||||||
|
checkpoint 512 30
|
||||||
|
|
||||||
|
{% if slapd.replica %}
|
||||||
|
syncrepl
|
||||||
|
rid={{ slapd.replica_rid }}
|
||||||
|
provider=ldaps://{{ slapd.master_ip }}:636
|
||||||
|
bindmethod=simple
|
||||||
|
binddn="cn=replicator,dc=ynerant,dc=fr"
|
||||||
|
credentials={{ slapd.replication_credentials }}
|
||||||
|
searchbase="dc=ynerant,dc=fr"
|
||||||
|
scope=sub
|
||||||
|
schemachecking=on
|
||||||
|
type=refreshAndPersist
|
||||||
|
timeout=0
|
||||||
|
network-timeout=0
|
||||||
|
retry="30 20 300 +"
|
||||||
|
tls_reqcert=allow
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if slapd.replica %}
|
||||||
|
# The userPassword by default can be changed
|
||||||
|
# by the entry owning it if they are authenticated.
|
||||||
|
# Others should not be able to see it, except the
|
||||||
|
# admin entry below
|
||||||
|
# These access lines apply to database #1 only
|
||||||
|
access to attrs=userPassword,shadowLastChange
|
||||||
|
by anonymous auth
|
||||||
|
by * none
|
||||||
|
|
||||||
|
# Ensure read access to the base for things like
|
||||||
|
# supportedSASLMechanisms. Without this you may
|
||||||
|
# have problems with SASL not knowing what
|
||||||
|
# mechanisms are available and the like.
|
||||||
|
# Note that this is covered by the 'access to *'
|
||||||
|
# ACL below too but if you change that as people
|
||||||
|
# are wont to do you'll still need this if you
|
||||||
|
# want SASL (and possible other things) to work
|
||||||
|
# happily.
|
||||||
|
access to dn.base="" by * read
|
||||||
|
|
||||||
|
# The admin dn has full write access, everyone else
|
||||||
|
# can read everything.
|
||||||
|
access to *
|
||||||
|
by * read
|
||||||
|
{% else %}
|
||||||
|
overlay syncprov
|
||||||
|
|
||||||
|
# The userPassword by default can be changed
|
||||||
|
# by the entry owning it if they are authenticated.
|
||||||
|
# Others should not be able to see it, except the
|
||||||
|
# admin entry below
|
||||||
|
# These access lines apply to database #1 only
|
||||||
|
access to attrs=userPassword,shadowLastChange
|
||||||
|
by anonymous auth
|
||||||
|
by self write
|
||||||
|
by set="[cn=admin,ou=group,dc=ynerant,dc=fr]/memberUid & user/uid" write
|
||||||
|
by dn="cn=replicator,dc=ynerant,dc=fr" read
|
||||||
|
by * none
|
||||||
|
|
||||||
|
access to attrs=loginShell,mail,telephoneNumber
|
||||||
|
by self write
|
||||||
|
by set="[cn=admin,ou=group,dc=ynerant,dc=fr]/memberUid & user/uid" write
|
||||||
|
by dn="cn=replicator,dc=ynerant,dc=fr" read
|
||||||
|
by * read
|
||||||
|
|
||||||
|
# Ensure read access to the base for things like
|
||||||
|
# supportedSASLMechanisms. Without this you may
|
||||||
|
# have problems with SASL not knowing what
|
||||||
|
# mechanisms are available and the like.
|
||||||
|
# Note that this is covered by the 'access to *'
|
||||||
|
# ACL below too but if you change that as people
|
||||||
|
# are wont to do you'll still need this if you
|
||||||
|
# want SASL (and possible other things) to work
|
||||||
|
# happily.
|
||||||
|
access to dn.base="" by * read
|
||||||
|
|
||||||
|
# The admin dn has full write access, everyone else
|
||||||
|
# can read everything.
|
||||||
|
access to *
|
||||||
|
by set="[cn=admin,ou=group,dc=ynerant,dc=fr]/memberUid & user/uid" write
|
||||||
|
by dn="cn=replicator,dc=ynerant,dc=fr" read
|
||||||
|
by * read
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
#######################################################################
|
||||||
|
# Specific Directives for database #2, of type 'other' (can be mdb too):
|
||||||
|
# Database specific directives apply to this databasse until another
|
||||||
|
# 'database' directive occurs
|
||||||
|
#database <other>
|
||||||
|
|
||||||
|
# The base of your directory for database #2
|
||||||
|
#suffix "dc=debian,dc=org"
|
@@ -1,13 +1,10 @@
|
|||||||
---
|
---
|
||||||
|
- name: Configure sudoers
|
||||||
- name: Deploy sudoers configuration files
|
|
||||||
template:
|
template:
|
||||||
src: '{{ item.src }}.j2'
|
src: "{{ item }}.j2"
|
||||||
dest: '/etc/{{ item.src }}'
|
dest: "/etc/{{ item }}"
|
||||||
owner: root
|
mode: 0440
|
||||||
group: root
|
loop:
|
||||||
mode: '{{ item.mode }}'
|
- sudoers.d/custom_passprompt
|
||||||
with_items:
|
- sudoers.d/group_privilege
|
||||||
- { src: 'sudoers', mode: '0440' }
|
- sudoers
|
||||||
- { src: 'sudoers.lecture', mode: '0644' }
|
|
||||||
|
|
||||||
|
4
roles/sudo/templates/sudoers.d/custom_passprompt.j2
Normal file
4
roles/sudo/templates/sudoers.d/custom_passprompt.j2
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{{ ansible_header | comment }}
|
||||||
|
# Change prompt
|
||||||
|
Defaults passprompt_override
|
||||||
|
Defaults passprompt="[sudo] mot de passe pour %p sur %h: "
|
3
roles/sudo/templates/sudoers.d/group_privilege.j2
Normal file
3
roles/sudo/templates/sudoers.d/group_privilege.j2
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{{ ansible_header | comment }}
|
||||||
|
# Group privilege specification
|
||||||
|
ADMINS ALL=(ALL:ALL) ALL
|
@@ -1,103 +1,27 @@
|
|||||||
{{ ansible_header | comment }}
|
{{ ansible_header | comment }}
|
||||||
|
#
|
||||||
|
# See the man page for details on how to write a sudoers file.
|
||||||
|
#
|
||||||
|
Defaults env_reset
|
||||||
|
Defaults mail_badpass
|
||||||
|
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||||
|
|
||||||
## sudoers file.
|
# Host alias specification
|
||||||
##
|
User_Alias USERS= %user
|
||||||
## This file MUST be edited with the 'visudo' command as root.
|
User_Alias ADMINS= %admin
|
||||||
## Failure to use 'visudo' may result in syntax or file permission errors
|
|
||||||
## that prevent sudo from running.
|
|
||||||
##
|
|
||||||
## See the sudoers man page for the details on how to write a sudoers file.
|
|
||||||
##
|
|
||||||
|
|
||||||
##
|
# User alias specification
|
||||||
## Host alias specification
|
|
||||||
##
|
|
||||||
## Groups of machines. These may include host names (optionally with wildcards),
|
|
||||||
## IP addresses, network numbers or netgroups.
|
|
||||||
# Host_Alias WEBSERVERS = www1, www2, www3
|
|
||||||
|
|
||||||
##
|
# Cmnd alias specification
|
||||||
## User alias specification
|
|
||||||
##
|
|
||||||
## Groups of users. These may consist of user names, uids, Unix groups,
|
|
||||||
## or netgroups.
|
|
||||||
# User_Alias ADMINS = millert, dowdy, mikef
|
|
||||||
|
|
||||||
##
|
# User privilege specification
|
||||||
## Cmnd alias specification
|
root ALL=(ALL:ALL) ALL
|
||||||
##
|
|
||||||
## Groups of commands. Often used to group related commands together.
|
|
||||||
# Cmnd_Alias PROCESSES = /usr/bin/nice, /bin/kill, /usr/bin/renice, \
|
|
||||||
# /usr/bin/pkill, /usr/bin/top
|
|
||||||
# Cmnd_Alias REBOOT = /sbin/halt, /sbin/reboot, /sbin/poweroff
|
|
||||||
|
|
||||||
##
|
{% if 'virtu' in group_names %}
|
||||||
## Defaults specification
|
# Pour vérifier quels vms sont sur quels virtus
|
||||||
##
|
USERS ALL=(root:ALL) NOPASSWD:/usr/sbin/qm list
|
||||||
## You may wish to keep some of the following environment variables
|
|
||||||
## when running commands via sudo.
|
|
||||||
##
|
|
||||||
## Locale settings
|
|
||||||
# Defaults env_keep += "LANG LANGUAGE LINGUAS LC_* _XKB_CHARSET"
|
|
||||||
##
|
|
||||||
## Run X applications through sudo; HOME is used to find the
|
|
||||||
## .Xauthority file. Note that other programs use HOME to find
|
|
||||||
## configuration files and this may lead to privilege escalation!
|
|
||||||
# Defaults env_keep += "HOME"
|
|
||||||
##
|
|
||||||
## X11 resource path settings
|
|
||||||
# Defaults env_keep += "XAPPLRESDIR XFILESEARCHPATH XUSERFILESEARCHPATH"
|
|
||||||
##
|
|
||||||
## Desktop path settings
|
|
||||||
# Defaults env_keep += "QTDIR KDEDIR"
|
|
||||||
##
|
|
||||||
## Allow sudo-run commands to inherit the callers' ConsoleKit session
|
|
||||||
# Defaults env_keep += "XDG_SESSION_COOKIE"
|
|
||||||
##
|
|
||||||
## Uncomment to enable special input methods. Care should be taken as
|
|
||||||
## this may allow users to subvert the command being run via sudo.
|
|
||||||
# Defaults env_keep += "XMODIFIERS GTK_IM_MODULE QT_IM_MODULE QT_IM_SWITCHER"
|
|
||||||
##
|
|
||||||
## Uncomment to use a hard-coded PATH instead of the user's to find commands
|
|
||||||
# Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
|
||||||
##
|
|
||||||
## Uncomment to send mail if the user does not enter the correct password.
|
|
||||||
# Defaults mail_badpass
|
|
||||||
##
|
|
||||||
## Uncomment to enable logging of a command's output, except for
|
|
||||||
## sudoreplay and reboot. Use sudoreplay to play back logged sessions.
|
|
||||||
# Defaults log_output
|
|
||||||
# Defaults!/usr/bin/sudoreplay !log_output
|
|
||||||
# Defaults!/usr/local/bin/sudoreplay !log_output
|
|
||||||
# Defaults!REBOOT !log_output
|
|
||||||
|
|
||||||
##
|
{% endif %}
|
||||||
## Runas alias specification
|
# See sudoers(5) for more information on "#include" directives:
|
||||||
##
|
|
||||||
|
|
||||||
##
|
|
||||||
## User privilege specification
|
|
||||||
##
|
|
||||||
root ALL=(ALL) ALL
|
|
||||||
|
|
||||||
## Uncomment to allow members of group wheel to execute any command
|
|
||||||
%wheel ALL=(ALL) ALL
|
|
||||||
|
|
||||||
## Same thing without a password
|
|
||||||
# %wheel ALL=(ALL) NOPASSWD: ALL
|
|
||||||
|
|
||||||
## Uncomment to allow members of group sudo to execute any command
|
|
||||||
# %sudo ALL=(ALL) ALL
|
|
||||||
|
|
||||||
## Uncomment to allow any user to run sudo if they know the password
|
|
||||||
## of the user they are running the command as (root by default).
|
|
||||||
# Defaults targetpw # Ask for the password of the target user
|
|
||||||
# ALL ALL=(ALL) ALL # WARNING: only use this together with 'Defaults targetpw'
|
|
||||||
|
|
||||||
Defaults lecture=always
|
|
||||||
Defaults lecture_file=/etc/sudoers.lecture
|
|
||||||
# toilet -f future --rainbow 'BE NICE' > sudoers.lecture.j2
|
|
||||||
|
|
||||||
## Read drop-in files from /etc/sudoers.d
|
|
||||||
## (the '#' here does not indicate a comment)
|
|
||||||
#includedir /etc/sudoers.d
|
#includedir /etc/sudoers.d
|
||||||
|
@@ -1,3 +0,0 @@
|
|||||||
[0;1;35;95m┏┓[0m [0;1;31;91m┏[0;1;33;93m━╸[0m [0;1;36;96m┏[0;1;34;94m┓╻[0;1;35;95m╻┏[0;1;31;91m━╸[0;1;33;93m┏━[0;1;32;92m╸[0m
|
|
||||||
[0;1;31;91m┣┻[0;1;33;93m┓┣[0;1;32;92m╸[0m [0;1;34;94m┃[0;1;35;95m┗┫[0;1;31;91m┃┃[0m [0;1;32;92m┣╸[0m
|
|
||||||
[0;1;33;93m┗━[0;1;32;92m┛┗[0;1;36;96m━╸[0m [0;1;35;95m╹[0m [0;1;31;91m╹[0;1;33;93m╹┗[0;1;32;92m━╸[0;1;36;96m┗━[0;1;34;94m╸[0m
|
|
@@ -44,5 +44,3 @@ set whichwrap+=<,>,h,l,[,]
|
|||||||
colorscheme elflord
|
colorscheme elflord
|
||||||
highlight ExtraWhitespace ctermbg=lightgreen guibg=lightgreen
|
highlight ExtraWhitespace ctermbg=lightgreen guibg=lightgreen
|
||||||
match ExtraWhitespace /\s\+$/
|
match ExtraWhitespace /\s\+$/
|
||||||
|
|
||||||
set tw=80
|
|
||||||
|
BIN
vars_plugins/__pycache__/pass.cpython-39.pyc
Normal file
BIN
vars_plugins/__pycache__/pass.cpython-39.pyc
Normal file
Binary file not shown.
BIN
vars_plugins/__pycache__/vault_cranspasswords.cpython-39.pyc
Normal file
BIN
vars_plugins/__pycache__/vault_cranspasswords.cpython-39.pyc
Normal file
Binary file not shown.
6
vars_plugins/pass.ini
Normal file
6
vars_plugins/pass.ini
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
[pass]
|
||||||
|
# password_store_dir=/home/ynerant/.password-store
|
||||||
|
crans_password_store_submodule=.
|
||||||
|
|
||||||
|
[pass_become]
|
||||||
|
all=templier
|
6
vars_plugins/pass.ini.example
Normal file
6
vars_plugins/pass.ini.example
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
[pass]
|
||||||
|
# password_store_dir=/home/me/.password-store
|
||||||
|
# crans_password_store_submodule=crans
|
||||||
|
|
||||||
|
[pass_become]
|
||||||
|
# all=mdp-root
|
102
vars_plugins/pass.py
Normal file
102
vars_plugins/pass.py
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
from functools import lru_cache
|
||||||
|
from getpass import getpass
|
||||||
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from ansible.module_utils.six.moves import configparser
|
||||||
|
from ansible.plugins.vars import BaseVarsPlugin
|
||||||
|
|
||||||
|
|
||||||
|
DOCUMENTATION = """
|
||||||
|
module: pass
|
||||||
|
vars: vault
|
||||||
|
version_added: 2.9
|
||||||
|
short_description: Load vault passwords from pass
|
||||||
|
description:
|
||||||
|
- Works exactly as a vault, loading variables from pass.
|
||||||
|
- Decrypts the YAML file `ansible_vault` from cranspasswords.
|
||||||
|
- Loads the secret variables.
|
||||||
|
- Makes use of data caching in order to avoid calling cranspasswords multiple times.
|
||||||
|
- Uses the local gpg key from the user running ansible on the Control node.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class VarsModule(BaseVarsPlugin):
|
||||||
|
@staticmethod
|
||||||
|
@lru_cache
|
||||||
|
def decrypt_password(name, crans_submodule=False):
|
||||||
|
"""
|
||||||
|
Passwords are decrypted from the local password store, then are cached.
|
||||||
|
By that way, we don't decrypt these passwords everytime.
|
||||||
|
"""
|
||||||
|
# Load config
|
||||||
|
config = configparser.ConfigParser()
|
||||||
|
config.read(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'pass.ini'))
|
||||||
|
|
||||||
|
password_store = Path(config.get('pass', 'password_store_dir',
|
||||||
|
fallback=os.getenv('PASSWORD_STORE_DIR', Path.home() / '.password-store')))
|
||||||
|
|
||||||
|
if crans_submodule:
|
||||||
|
password_store /= config.get('pass', 'crans_password_store_submodule',
|
||||||
|
fallback=os.getenv('CRANS_PASSWORD_STORE_SUBMODULE', 'crans'))
|
||||||
|
full_command = ['gpg', '-d', password_store / f'{name}.gpg']
|
||||||
|
proc = subprocess.run(full_command, capture_output=True, close_fds=True)
|
||||||
|
clear_text = proc.stdout.decode('UTF-8')
|
||||||
|
sys.stderr.write(proc.stderr.decode('UTF-8'))
|
||||||
|
return clear_text
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
@lru_cache
|
||||||
|
def become_password(entity):
|
||||||
|
"""
|
||||||
|
Query the become password that should be used for the given entity.
|
||||||
|
If entity is the whole group that has no default password,
|
||||||
|
the become password will be prompted.
|
||||||
|
The configuration should be given in pass.ini, in the `pass_become`
|
||||||
|
group. You have only to write `group=pass-filename`.
|
||||||
|
"""
|
||||||
|
# Load config
|
||||||
|
config = configparser.ConfigParser()
|
||||||
|
config.read(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'pass.ini'))
|
||||||
|
if config.has_option('pass_become', entity.get_name()):
|
||||||
|
return VarsModule.decrypt_password(
|
||||||
|
config.get('pass_become', entity.get_name())).split('\n')[0]
|
||||||
|
if entity.get_name() == "all":
|
||||||
|
return getpass("BECOME password: ", stream=None)
|
||||||
|
return None
|
||||||
|
|
||||||
|
def get_vars(self, loader, path, entities):
|
||||||
|
"""
|
||||||
|
Get all vars for entities, called by Ansible.
|
||||||
|
|
||||||
|
loader: Ansible's DataLoader.
|
||||||
|
path: Current play's playbook directory.
|
||||||
|
entities: Host or group names pertinent to the variables needed.
|
||||||
|
"""
|
||||||
|
# VarsModule objects are called every time you need host vars, per host,
|
||||||
|
# and per group the host is part of.
|
||||||
|
# It is about 6 times per host per task in current state
|
||||||
|
# of Ansible Crans configuration.
|
||||||
|
|
||||||
|
# It is way to much.
|
||||||
|
# So we cache the data into the DataLoader (see parsing/DataLoader).
|
||||||
|
|
||||||
|
passwords = {}
|
||||||
|
|
||||||
|
for entity in entities:
|
||||||
|
# Load vault passwords
|
||||||
|
if entity.get_name() == 'all':
|
||||||
|
passwords['vault'] = loader.load(
|
||||||
|
VarsModule.decrypt_password('ansible_vault', True))
|
||||||
|
|
||||||
|
# Load become password
|
||||||
|
become_password = VarsModule.become_password(entity)
|
||||||
|
if become_password is not None:
|
||||||
|
passwords['ansible_become_password'] = become_password
|
||||||
|
|
||||||
|
return passwords
|
Reference in New Issue
Block a user