Merge branch 'unstable' into stable
This commit is contained in:
commit
9038beefd1
|
@ -1,3 +0,0 @@
|
||||||
---
|
|
||||||
admin_users: {}
|
|
||||||
admin_users_group: adm
|
|
|
@ -1,11 +0,0 @@
|
||||||
---
|
|
||||||
|
|
||||||
- include: user.yml
|
|
||||||
|
|
||||||
- include: profile.yml
|
|
||||||
|
|
||||||
- include: ssh.yml
|
|
||||||
|
|
||||||
- include: sudo.yml
|
|
||||||
|
|
||||||
- meta: flush_handlers
|
|
|
@ -1,16 +0,0 @@
|
||||||
---
|
|
||||||
|
|
||||||
- fail:
|
|
||||||
msg: only compatible with Debian >= 8
|
|
||||||
when:
|
|
||||||
- ansible_distribution != "Debian" or ansible_distribution_major_version | version_compare('8', '<')
|
|
||||||
|
|
||||||
- debug:
|
|
||||||
msg: "Warning: empty 'admin_users' variable, tasks will be skipped!"
|
|
||||||
when: admin_users == {}
|
|
||||||
|
|
||||||
- include: admin_user.yml
|
|
||||||
vars:
|
|
||||||
user: "{{ item.value }}"
|
|
||||||
with_dict: "{{ admin_users }}"
|
|
||||||
when: admin_users != {}
|
|
|
@ -1,15 +0,0 @@
|
||||||
---
|
|
||||||
|
|
||||||
- name: is evomaintenance installed?
|
|
||||||
stat:
|
|
||||||
path: "/usr/share/scripts/evomaintenance.sh"
|
|
||||||
register: evomaintenance_script
|
|
||||||
check_mode: no
|
|
||||||
|
|
||||||
- name: "Add evomaintenance trap for '{{ user.name }}'"
|
|
||||||
lineinfile:
|
|
||||||
state: present
|
|
||||||
dest: '/home/{{ user.name }}/.profile'
|
|
||||||
insertafter: EOF
|
|
||||||
line: 'trap "sudo /usr/share/scripts/evomaintenance.sh" 0'
|
|
||||||
when: evomaintenance_script.stat.exists
|
|
|
@ -1,48 +0,0 @@
|
||||||
---
|
|
||||||
|
|
||||||
- name: "Verify Evolinux sudoers file presence (jessie)"
|
|
||||||
template:
|
|
||||||
src: sudoers_jessie.j2
|
|
||||||
dest: /etc/sudoers.d/evolinux
|
|
||||||
force: no
|
|
||||||
validate: '/usr/sbin/visudo -cf %s'
|
|
||||||
register: copy_sudoers_evolinux
|
|
||||||
when: ansible_distribution_release == "jessie"
|
|
||||||
|
|
||||||
- name: "Verify Evolinux sudoers file presence (Debian 9 or later)"
|
|
||||||
template:
|
|
||||||
src: sudoers_stretch.j2
|
|
||||||
dest: /etc/sudoers.d/evolinux
|
|
||||||
force: no
|
|
||||||
validate: '/usr/sbin/visudo -cf %s'
|
|
||||||
register: copy_sudoers_evolinux
|
|
||||||
when: ansible_distribution_major_version | version_compare('9', '>=')
|
|
||||||
|
|
||||||
- name: "Verify Evolinux sudoers file permissions"
|
|
||||||
file:
|
|
||||||
path: /etc/sudoers.d/evolinux
|
|
||||||
mode: "0440"
|
|
||||||
state: file
|
|
||||||
|
|
||||||
- name: "Add user in sudoers file for '{{ user.name }}' (jessie)"
|
|
||||||
replace:
|
|
||||||
dest: /etc/sudoers.d/evolinux
|
|
||||||
regexp: '^(User_Alias\s+ADMINS\s+=((?!{{ user.name }}).)*)$'
|
|
||||||
replace: '\1,{{ user.name }}'
|
|
||||||
validate: '/usr/sbin/visudo -cf %s'
|
|
||||||
when:
|
|
||||||
- ansible_distribution_release == "jessie"
|
|
||||||
- not copy_sudoers_evolinux.changed
|
|
||||||
|
|
||||||
- name: "Create evolinux-sudo group (Debian 9 or later)"
|
|
||||||
group:
|
|
||||||
name: evolinux-sudo
|
|
||||||
system: yes
|
|
||||||
when: ansible_distribution_major_version | version_compare('9', '>=')
|
|
||||||
|
|
||||||
- name: "Add user to evolinux-sudo group (Debian 9 or later)"
|
|
||||||
user:
|
|
||||||
name: '{{ user.name }}'
|
|
||||||
groups: 'evolinux-sudo'
|
|
||||||
append: yes
|
|
||||||
when: ansible_distribution_major_version | version_compare('9', '>=')
|
|
5
amavis/handlers/main.yml
Normal file
5
amavis/handlers/main.yml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
- name: restart amavis
|
||||||
|
service:
|
||||||
|
name: amavis
|
||||||
|
state: restarted
|
19
amavis/tasks/main.yml
Normal file
19
amavis/tasks/main.yml
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
---
|
||||||
|
- name: install Amavis
|
||||||
|
apt:
|
||||||
|
name: "{{ item }}"
|
||||||
|
state: present
|
||||||
|
with_items:
|
||||||
|
- postgrey
|
||||||
|
- amavisd-new
|
||||||
|
tags:
|
||||||
|
- amavis
|
||||||
|
|
||||||
|
- name: configure Amavis
|
||||||
|
template:
|
||||||
|
src: amavis.conf.j2
|
||||||
|
dest: /etc/amavis/conf.d/49-evolinux-defaults.conf
|
||||||
|
mode: "0644"
|
||||||
|
notify: restart amavis
|
||||||
|
tags:
|
||||||
|
- amavis
|
57
amavis/templates/amavis.conf.j2
Normal file
57
amavis/templates/amavis.conf.j2
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
use strict;
|
||||||
|
|
||||||
|
## Liste des domaines considérés comme locaux
|
||||||
|
#@local_domains_acl = qw(.);
|
||||||
|
@local_domains_acl = (".example.net","example.com");
|
||||||
|
|
||||||
|
# On customise la ligne ajoutée dans les entêtes
|
||||||
|
$X_HEADER_LINE = "by Amavis at $mydomain";
|
||||||
|
|
||||||
|
# On precise les FROM pour etre (bugs dans certaines version d'Amavis)
|
||||||
|
$mailfrom_notify_admin = "postmaster\@$mydomain";
|
||||||
|
$mailfrom_notify_recip = "postmaster\@$mydomain";
|
||||||
|
$mailfrom_notify_spamadmin = "postmaster\@$mydomain";
|
||||||
|
|
||||||
|
# Notifications de fichiers bannis / virus
|
||||||
|
$virus_admin = "postmaster\@$mydomain";
|
||||||
|
# Ne pas recevoir des notifications pour les mails UNCHECKED
|
||||||
|
delete $admin_maps_by_ccat{&CC_UNCHECKED};
|
||||||
|
|
||||||
|
# Que faire avec les messages détectés
|
||||||
|
$final_virus_destiny = D_DISCARD;
|
||||||
|
$final_banned_destiny = D_BOUNCE;
|
||||||
|
$final_spam_destiny = D_BOUNCE;
|
||||||
|
$final_bad_header_destiny = D_PASS;
|
||||||
|
|
||||||
|
# Pour recevoir des bounces (mails originals) des fichiers bloqués / virus
|
||||||
|
#$banned_quarantine_to = "banned\@$mydomain";
|
||||||
|
#$virus_quarantine_to = "virus\@$mydomain";
|
||||||
|
|
||||||
|
# Note tueuse
|
||||||
|
$sa_tag2_level_deflt = 6.31;
|
||||||
|
# Pour un comportement "normal" de SA
|
||||||
|
$sa_tag_level_deflt = -1999;
|
||||||
|
$sa_kill_level_deflt = 1999;
|
||||||
|
$sa_dsn_cutoff_level = -99;
|
||||||
|
$sa_spam_subject_tag = '[SPAM]';
|
||||||
|
|
||||||
|
# log
|
||||||
|
$log_level = 2;
|
||||||
|
|
||||||
|
# En fonction besoin/ressources, on a juste le nbre de process
|
||||||
|
$max_servers = 2;
|
||||||
|
|
||||||
|
$enable_ldap = 1;
|
||||||
|
$default_ldap = {
|
||||||
|
hostname => '127.0.0.1', tls => 0,
|
||||||
|
base => '{{ ldap_suffix }}', scope => 'sub',
|
||||||
|
query_filter => '(&(mailacceptinggeneralid=%m)(isActive=TRUE))'
|
||||||
|
};
|
||||||
|
|
||||||
|
# Activer l'antivirus et antivirus
|
||||||
|
@bypass_virus_checks_maps = (
|
||||||
|
\%bypass_virus_checks, \@bypass_virus_checks_acl, \$bypass_virus_checks_re);
|
||||||
|
@bypass_spam_checks_maps = (
|
||||||
|
\%bypass_spam_checks, \@bypass_spam_checks_acl, \$bypass_spam_checks_re);
|
||||||
|
|
||||||
|
1; # ensure a defined return
|
60
amazon-ec2/README
Normal file
60
amazon-ec2/README
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
# amazon-ec2
|
||||||
|
|
||||||
|
Manage Amazon EC2 instances.
|
||||||
|
|
||||||
|
This role is intended to be called before any other role to setup and start EC2
|
||||||
|
instances.
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
You should first ensure that you have `python-boto` package installed on your
|
||||||
|
machine and an Amazon security access key pair created for your account.
|
||||||
|
|
||||||
|
## Tasks
|
||||||
|
|
||||||
|
By default, this role does nothing (no `main.yml` file).
|
||||||
|
|
||||||
|
* `setup.yml`: create a security group and ssh keys
|
||||||
|
* `create-instance.yml`: create new EC2 instances
|
||||||
|
* `post-install.yml`: remove admin user created on Debian instances
|
||||||
|
|
||||||
|
## Variables
|
||||||
|
|
||||||
|
- `aws_access_key` and `aws_secret_key`: your AWS credentials
|
||||||
|
- `aws_region`: where to create instances. Default: ca-central-1
|
||||||
|
- `ec2_public_ip`: assign public elastic IP address. Default: False
|
||||||
|
- `ec2_instance_count`: how many instance to launch. Default: 1
|
||||||
|
- `ec2_security_group: EC2 security group to use. See
|
||||||
|
ec2_evolinux_security_group in `defaults/main.yml` to define your own.
|
||||||
|
Default: ec2_evolinux_security_group
|
||||||
|
- `ec2_base_ami`: EC2 image to use. Default is to use Debian official ones,
|
||||||
|
depending on the region
|
||||||
|
- `ec2_instance_type`: EC2 instance type to use
|
||||||
|
- `ssh_pubkey_file`: SSH public key file to push to AWS. Do not try to put
|
||||||
|
your ED25519 key here, AWS does not support it. Default: ~/.ssh/id_rsa.pub
|
||||||
|
- `ec2_keyname: a name to give to your public key on AWS. Default is to use
|
||||||
|
$USER environment variable.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
In your main evolinux playbook put this play before Evolinux one:
|
||||||
|
|
||||||
|
```
|
||||||
|
---
|
||||||
|
- name: Prepare Amazon EC2 instance
|
||||||
|
hosts: localhost
|
||||||
|
gather_facts: False
|
||||||
|
|
||||||
|
vars:
|
||||||
|
aws_access_key:
|
||||||
|
aws_secret_key:
|
||||||
|
# Any other variable you want to set.
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- include_role:
|
||||||
|
name: amazon-ec2
|
||||||
|
tasks_from: create-instance.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
See amazon-ec2-evolinux.yml for an almost ready-to-use playbook to set up
|
||||||
|
Amazon EC2 instances running Evolinux.
|
62
amazon-ec2/amazon-ec2-evolinux.yml
Normal file
62
amazon-ec2/amazon-ec2-evolinux.yml
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
---
|
||||||
|
- name: Prepare Amazon EC2 instance
|
||||||
|
hosts: localhost
|
||||||
|
gather_facts: False
|
||||||
|
|
||||||
|
vars:
|
||||||
|
aws_access_key:
|
||||||
|
aws_secret_key:
|
||||||
|
aws_region: ca-central-1
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- include_role:
|
||||||
|
name: amazon-ec2
|
||||||
|
tasks_from: setup.yml
|
||||||
|
- include_role:
|
||||||
|
name: amazon-ec2
|
||||||
|
tasks_from: create-instance.yml
|
||||||
|
|
||||||
|
- name: Install Evolinux
|
||||||
|
hosts: launched-instances
|
||||||
|
become: yes
|
||||||
|
|
||||||
|
vars_files:
|
||||||
|
- 'vars/secrets.yml'
|
||||||
|
|
||||||
|
vars:
|
||||||
|
admin_users: "{{ admin_users }}"
|
||||||
|
minifirewall_trusted_ips: "{{ trusted_ips }}"
|
||||||
|
fail2ban_ignore_ips: "{{ trusted_ips }}"
|
||||||
|
evolinux_hostname:
|
||||||
|
evolinux_domain:
|
||||||
|
evolinux_fqdn:
|
||||||
|
evolinux_internal_hostname:
|
||||||
|
minifirewall_public_ports_tcp: [80, 443]
|
||||||
|
minifirewall_public_ports_udp: []
|
||||||
|
minifirewall_semipublic_ports_tcp: [22]
|
||||||
|
nagios_nrpe_allowed_hosts: "{{ trusted_ips }}"
|
||||||
|
|
||||||
|
roles:
|
||||||
|
- etc-git
|
||||||
|
- evolinux-base
|
||||||
|
- admin-users
|
||||||
|
- munin
|
||||||
|
- minifirewall
|
||||||
|
- fail2ban
|
||||||
|
- nagios-nrpe
|
||||||
|
- listupgrade
|
||||||
|
- evomaintenance
|
||||||
|
- evocheck
|
||||||
|
- packweb-apache
|
||||||
|
- mysql
|
||||||
|
|
||||||
|
post_tasks:
|
||||||
|
- include_role:
|
||||||
|
name: etc-git
|
||||||
|
tasks_from: commit.yml
|
||||||
|
vars:
|
||||||
|
commit_message: "Ansible post-run Evolinux playbook"
|
||||||
|
|
||||||
|
- include_role:
|
||||||
|
name: evocheck
|
||||||
|
tasks_from: exec.yml
|
135
amazon-ec2/defaults/main.yml
Normal file
135
amazon-ec2/defaults/main.yml
Normal file
|
@ -0,0 +1,135 @@
|
||||||
|
---
|
||||||
|
aws_region: ca-central-1
|
||||||
|
ec2_public_ip: False
|
||||||
|
ec2_instance_count: 1
|
||||||
|
ec2_security_group: "{{ ec2_evolinux_security_group }}"
|
||||||
|
ec2_base_ami: "{{ ec2_debian_base_ami[aws_region] }}"
|
||||||
|
ec2_instance_type: t2.micro
|
||||||
|
# Note: Do not try to put your ED25519 key here, AWS does not support it...
|
||||||
|
ssh_pubkey_file: ~/.ssh/id_rsa.pub
|
||||||
|
ec2_keyname: "{{ lookup('env', 'USER') }}"
|
||||||
|
|
||||||
|
# From https://wiki.debian.org/Cloud/AmazonEC2Image/Stretch
|
||||||
|
ec2_debian_base_ami:
|
||||||
|
ap-northeast-1: ami-032dd665
|
||||||
|
ap-northeast-2: ami-e174ac8f
|
||||||
|
ap-south-1: ami-6e7a3e01
|
||||||
|
ap-southeast-1: ami-41365b22
|
||||||
|
ap-southeast-2: ami-51f61333
|
||||||
|
ca-central-1: ami-18239d7c
|
||||||
|
eu-central-1: ami-11bb0e7e
|
||||||
|
eu-west-1: ami-d037cda9
|
||||||
|
eu-west-2: ami-ece3f388
|
||||||
|
sa-east-1: ami-a24635ce
|
||||||
|
us-east-1: ami-ac5e55d7
|
||||||
|
us-east-2: ami-9fbb98fa
|
||||||
|
us-west-1: ami-560c3836
|
||||||
|
us-west-2: ami-fa18f282
|
||||||
|
|
||||||
|
ec2_evolinux_security_group:
|
||||||
|
name: evolinux-default
|
||||||
|
description: Evolinux default security group
|
||||||
|
rules:
|
||||||
|
- proto: icmp
|
||||||
|
cidr_ip: 0.0.0.0/0
|
||||||
|
from_port: -1
|
||||||
|
to_port: -1
|
||||||
|
- proto: tcp
|
||||||
|
from_port: 22
|
||||||
|
to_port: 22
|
||||||
|
cidr_ip: 0.0.0.0/0
|
||||||
|
- proto: tcp
|
||||||
|
from_port: 5666
|
||||||
|
to_port: 5666
|
||||||
|
cidr_ip: 0.0.0.0/0
|
||||||
|
- proto: tcp
|
||||||
|
from_port: 53
|
||||||
|
to_port: 53
|
||||||
|
cidr_ip: 0.0.0.0/0
|
||||||
|
- proto: udp
|
||||||
|
from_port: 53
|
||||||
|
to_port: 53
|
||||||
|
cidr_ip: 0.0.0.0/0
|
||||||
|
- proto: tcp
|
||||||
|
from_port: 389
|
||||||
|
to_port: 389
|
||||||
|
cidr_ip: 0.0.0.0/0
|
||||||
|
- proto: tcp
|
||||||
|
from_port: 636
|
||||||
|
to_port: 636
|
||||||
|
cidr_ip: 0.0.0.0/0
|
||||||
|
- proto: tcp
|
||||||
|
from_port: 143
|
||||||
|
to_port: 143
|
||||||
|
cidr_ip: 0.0.0.0/0
|
||||||
|
- proto: tcp
|
||||||
|
from_port: 993
|
||||||
|
to_port: 993
|
||||||
|
cidr_ip: 0.0.0.0/0
|
||||||
|
- proto: tcp
|
||||||
|
from_port: 110
|
||||||
|
to_port: 110
|
||||||
|
cidr_ip: 0.0.0.0/0
|
||||||
|
- proto: tcp
|
||||||
|
from_port: 995
|
||||||
|
to_port: 995
|
||||||
|
cidr_ip: 0.0.0.0/0
|
||||||
|
- proto: tcp
|
||||||
|
from_port: 25
|
||||||
|
to_port: 25
|
||||||
|
cidr_ip: 0.0.0.0/0
|
||||||
|
- proto: tcp
|
||||||
|
from_port: 80
|
||||||
|
to_port: 80
|
||||||
|
cidr_ip: 0.0.0.0/0
|
||||||
|
- proto: tcp
|
||||||
|
from_port: 443
|
||||||
|
to_port: 443
|
||||||
|
cidr_ip: 0.0.0.0/0
|
||||||
|
- proto: tcp
|
||||||
|
from_port: 21
|
||||||
|
to_port: 21
|
||||||
|
cidr_ip: 0.0.0.0/0
|
||||||
|
- proto: tcp
|
||||||
|
from_port: 20
|
||||||
|
to_port: 20
|
||||||
|
cidr_ip: 0.0.0.0/0
|
||||||
|
- proto: tcp
|
||||||
|
from_port: 5001
|
||||||
|
to_port: 5001
|
||||||
|
cidr_ip: 0.0.0.0/0
|
||||||
|
- proto: tcp
|
||||||
|
from_port: 465
|
||||||
|
to_port: 465
|
||||||
|
cidr_ip: 0.0.0.0/0
|
||||||
|
- proto: tcp
|
||||||
|
from_port: 587
|
||||||
|
to_port: 587
|
||||||
|
cidr_ip: 0.0.0.0/0
|
||||||
|
- proto: tcp
|
||||||
|
from_port: 8181
|
||||||
|
to_port: 8181
|
||||||
|
cidr_ip: 0.0.0.0/0
|
||||||
|
- proto: tcp
|
||||||
|
from_port: 8282
|
||||||
|
to_port: 8282
|
||||||
|
cidr_ip: 0.0.0.0/0
|
||||||
|
- proto: tcp
|
||||||
|
from_port: 9091
|
||||||
|
to_port: 9091
|
||||||
|
cidr_ip: 0.0.0.0/0
|
||||||
|
- proto: tcp
|
||||||
|
from_port: 2222
|
||||||
|
to_port: 2222
|
||||||
|
cidr_ip: 0.0.0.0/0
|
||||||
|
- proto: tcp
|
||||||
|
from_port: 2223
|
||||||
|
to_port: 2223
|
||||||
|
cidr_ip: 0.0.0.0/0
|
||||||
|
- proto: udp
|
||||||
|
from_port: 123
|
||||||
|
to_port: 123
|
||||||
|
cidr_ip: 0.0.0.0/0
|
||||||
|
rules_egress:
|
||||||
|
- proto: all
|
||||||
|
cidr_ip: 0.0.0.0/0
|
36
amazon-ec2/tasks/create-instance.yml
Normal file
36
amazon-ec2/tasks/create-instance.yml
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
- name: Launch new instance(s)
|
||||||
|
ec2:
|
||||||
|
state: present
|
||||||
|
aws_access_key: "{{aws_access_key}}"
|
||||||
|
aws_secret_key: "{{aws_secret_key}}"
|
||||||
|
region: "{{aws_region}}"
|
||||||
|
image: "{{ec2_base_ami}}"
|
||||||
|
instance_type: "{{ec2_instance_type}}"
|
||||||
|
count: "{{ec2_instance_count}}"
|
||||||
|
assign_public_ip: "{{ec2_public_ip}}"
|
||||||
|
group: "{{ec2_security_group.name}}"
|
||||||
|
key_name: "{{ec2_keyname}}"
|
||||||
|
wait: yes
|
||||||
|
register: ec2
|
||||||
|
|
||||||
|
- name: Add newly created instance(s) to inventory
|
||||||
|
add_host:
|
||||||
|
hostname: "{{item.public_dns_name}}"
|
||||||
|
groupname: launched-instances
|
||||||
|
ansible_user: admin
|
||||||
|
ansible_ssh_common_args: "-o StrictHostKeyChecking=no"
|
||||||
|
with_items: "{{ec2.instances}}"
|
||||||
|
|
||||||
|
- debug:
|
||||||
|
msg: "Your newly created instance is reachable at: {{item.public_dns_name}}"
|
||||||
|
with_items: "{{ec2.instances}}"
|
||||||
|
|
||||||
|
- name: Wait for SSH to come up on all instances (give up after 2m)
|
||||||
|
wait_for:
|
||||||
|
state: started
|
||||||
|
host: "{{item.public_dns_name}}"
|
||||||
|
port: 22
|
||||||
|
timeout: 120
|
||||||
|
with_items: "{{ec2.instances}}"
|
5
amazon-ec2/tasks/post-install.yml
Normal file
5
amazon-ec2/tasks/post-install.yml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
- name: Remove admin user
|
||||||
|
user:
|
||||||
|
name: admin
|
||||||
|
state: absent
|
20
amazon-ec2/tasks/setup.yml
Normal file
20
amazon-ec2/tasks/setup.yml
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
---
|
||||||
|
- name: Create default security group
|
||||||
|
ec2_group:
|
||||||
|
name: "{{ec2_security_group.name}}"
|
||||||
|
state: present
|
||||||
|
aws_access_key: "{{aws_access_key}}"
|
||||||
|
aws_secret_key: "{{aws_secret_key}}"
|
||||||
|
region: "{{aws_region}}"
|
||||||
|
description: "{{ec2_security_group.description}}"
|
||||||
|
rules: "{{ec2_security_group.rules}}"
|
||||||
|
|
||||||
|
- name: Create key pair
|
||||||
|
ec2_key:
|
||||||
|
name: "{{ec2_keyname}}"
|
||||||
|
state: present
|
||||||
|
aws_access_key: "{{aws_access_key}}"
|
||||||
|
aws_secret_key: "{{aws_secret_key}}"
|
||||||
|
region: "{{aws_region}}"
|
||||||
|
key_material: "{{item}}"
|
||||||
|
with_file: "{{ssh_pubkey_file}}"
|
|
@ -10,8 +10,8 @@ Everything is in the `tasks/main.yml` file for now.
|
||||||
|
|
||||||
Main variables are :
|
Main variables are :
|
||||||
|
|
||||||
* `apache_private_ipaddr_whitelist_present` : list of IP addresses to have in the private whitelist ;
|
* `apache_ipaddr_whitelist_present` : list of IP addresses to have in the private whitelist ;
|
||||||
* `apache_private_ipaddr_whitelist_absent` : list of IP addresses **not** to have in the whitelist;
|
* `apache_ipaddr_whitelist_absent` : list of IP addresses **not** to have in the whitelist;
|
||||||
* `apache_private_htpasswd_present` : list of users to have in the private htpasswd ;
|
* `apache_private_htpasswd_present` : list of users to have in the private htpasswd ;
|
||||||
* `apache_private_htpasswd_absent` : list of users to **not** have in the private htpasswd.
|
* `apache_private_htpasswd_absent` : list of users to **not** have in the private htpasswd.
|
||||||
* `log2mail_alert_email`: email address to send Log2mail messages to (default: `general_alert_email`).
|
* `log2mail_alert_email`: email address to send Log2mail messages to (default: `general_alert_email`).
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
---
|
---
|
||||||
apache_private_ipaddr_whitelist_present: []
|
evolix_trusted_ips: []
|
||||||
apache_private_ipaddr_whitelist_absent: []
|
additional_trusted_ips: []
|
||||||
|
# Let's merge evolix_trusted_ips with additional_trusted_ips
|
||||||
|
apache_ipaddr_whitelist_present: "{{ evolix_trusted_ips | union(additional_trusted_ips) | unique }}"
|
||||||
|
apache_ipaddr_whitelist_absent: []
|
||||||
|
|
||||||
apache_private_htpasswd_present: []
|
apache_private_htpasswd_present: []
|
||||||
apache_private_htpasswd_absent: []
|
apache_private_htpasswd_absent: []
|
||||||
|
|
18
apache/files/save_apache_status.sh
Normal file
18
apache/files/save_apache_status.sh
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
DIR="/var/log/apache-status"
|
||||||
|
URL="http://127.0.0.1/server-status"
|
||||||
|
TS=`date +%Y%m%d%H%M%S`
|
||||||
|
FILE="${DIR}/${TS}.html"
|
||||||
|
|
||||||
|
mkdir -p "${DIR}"
|
||||||
|
|
||||||
|
wget -q -O "${FILE}" "${URL}"
|
||||||
|
|
||||||
|
chmod 640 "${FILE}"
|
||||||
|
|
||||||
|
find "${DIR}" -type f -mtime +1 -delete
|
||||||
|
|
||||||
|
exit 0
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
- name: Init ipaddr_whitelist.conf file
|
- name: Init ipaddr_whitelist.conf file
|
||||||
copy:
|
copy:
|
||||||
src: private_ipaddr_whitelist.conf
|
src: ipaddr_whitelist.conf
|
||||||
dest: /etc/apache2/ipaddr_whitelist.conf
|
dest: /etc/apache2/ipaddr_whitelist.conf
|
||||||
owner: root
|
owner: root
|
||||||
group: root
|
group: root
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
dest: /etc/apache2/ipaddr_whitelist.conf
|
dest: /etc/apache2/ipaddr_whitelist.conf
|
||||||
line: "Require ip {{ item }}"
|
line: "Require ip {{ item }}"
|
||||||
state: present
|
state: present
|
||||||
with_items: "{{ apache_private_ipaddr_whitelist_present }}"
|
with_items: "{{ apache_ipaddr_whitelist_present }}"
|
||||||
notify: reload apache
|
notify: reload apache
|
||||||
tags:
|
tags:
|
||||||
- apache
|
- apache
|
||||||
|
@ -26,7 +26,7 @@
|
||||||
dest: /etc/apache2/ipaddr_whitelist.conf
|
dest: /etc/apache2/ipaddr_whitelist.conf
|
||||||
line: "Require ip {{ item }}"
|
line: "Require ip {{ item }}"
|
||||||
state: absent
|
state: absent
|
||||||
with_items: "{{ apache_private_ipaddr_whitelist_absent }}"
|
with_items: "{{ apache_ipaddr_whitelist_absent }}"
|
||||||
notify: reload apache
|
notify: reload apache
|
||||||
tags:
|
tags:
|
||||||
- apache
|
- apache
|
||||||
|
|
|
@ -38,6 +38,10 @@
|
||||||
- expires
|
- expires
|
||||||
- headers
|
- headers
|
||||||
- cgi
|
- cgi
|
||||||
|
- ssl
|
||||||
|
- include
|
||||||
|
- negotiation
|
||||||
|
- alias
|
||||||
notify: reload apache
|
notify: reload apache
|
||||||
tags:
|
tags:
|
||||||
- apache
|
- apache
|
||||||
|
@ -127,30 +131,17 @@
|
||||||
tags:
|
tags:
|
||||||
- apache
|
- apache
|
||||||
|
|
||||||
- name: Stat /default index
|
- include_role:
|
||||||
stat:
|
name: remount-usr
|
||||||
path: /var/www/index.html
|
|
||||||
register: _default_index
|
|
||||||
check_mode: no
|
|
||||||
tags:
|
tags:
|
||||||
- apache
|
- apache
|
||||||
|
|
||||||
# - block:
|
- name: "Install save_apache_status.sh"
|
||||||
# - name: generate random string for serverstatus suffix
|
copy:
|
||||||
# command: "apg -a 1 -M N -n 1"
|
src: save_apache_status.sh
|
||||||
# changed_when: False
|
dest: /usr/share/scripts/save_apache_status.sh
|
||||||
# register: _random_serverstatus_suffix
|
mode: "0755"
|
||||||
#
|
force: no
|
||||||
# - name: overwrite apache_serverstatus_suffix
|
|
||||||
# set_fact:
|
|
||||||
# apache_serverstatus_suffix: "{{ _random_serverstatus_suffix.stdout }}"
|
|
||||||
# when: apache_serverstatus_suffix == ""
|
|
||||||
#
|
|
||||||
# - name: replace server-status suffix in default site index
|
|
||||||
# replace:
|
|
||||||
# dest: /var/www/index.html
|
|
||||||
# regexp: '__SERVERSTATUS_SUFFIX__'
|
|
||||||
# replace: "{{ apache_serverstatus_suffix }}"
|
|
||||||
|
|
||||||
- include: log2mail.yml
|
- include: log2mail.yml
|
||||||
when: apache_log2mail_include
|
when: apache_log2mail_include
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
---
|
---
|
||||||
|
|
||||||
- name: munin-node and core plugins are installed
|
- name: "Install munin-node and core plugins packages"
|
||||||
apt:
|
apt:
|
||||||
name: "{{ item }}"
|
name: "{{ item }}"
|
||||||
state: installed
|
state: installed
|
||||||
with_items:
|
with_items:
|
||||||
- munin-node
|
- munin-node
|
||||||
- munin-plugins-core
|
- munin-plugins-core
|
||||||
|
tags:
|
||||||
|
- apache
|
||||||
|
- munin
|
||||||
|
|
||||||
- name: enable munin plugins
|
- name: "Enable Munin plugins"
|
||||||
file:
|
file:
|
||||||
src: "/usr/share/munin/plugins/{{ item }}"
|
src: "/usr/share/munin/plugins/{{ item }}"
|
||||||
dest: "/etc/munin/plugins/{{ item }}"
|
dest: "/etc/munin/plugins/{{ item }}"
|
||||||
|
@ -21,3 +24,32 @@
|
||||||
tags:
|
tags:
|
||||||
- apache
|
- apache
|
||||||
- munin
|
- munin
|
||||||
|
|
||||||
|
- name: "Install fcgi packages for Munin graphs"
|
||||||
|
apt:
|
||||||
|
name: "{{ item }}"
|
||||||
|
state: installed
|
||||||
|
with_items:
|
||||||
|
- libapache2-mod-fcgid
|
||||||
|
- libcgi-fast-perl
|
||||||
|
notify: reload apache
|
||||||
|
tags:
|
||||||
|
- apache
|
||||||
|
- munin
|
||||||
|
|
||||||
|
- name: "Enable libapache2-mod-fcgid"
|
||||||
|
command: a2enmod fcgid
|
||||||
|
register: cmd_enable_fcgid
|
||||||
|
changed_when: "'Module fcgid already enabled' not in cmd_enable_fcgid.stdout"
|
||||||
|
notify: restart apache
|
||||||
|
tags:
|
||||||
|
- apache
|
||||||
|
- munin
|
||||||
|
|
||||||
|
- name: "Apache has access to /var/log/munin/"
|
||||||
|
file:
|
||||||
|
path: /var/log/munin/
|
||||||
|
group: www-data
|
||||||
|
tags:
|
||||||
|
- apache
|
||||||
|
- munin
|
||||||
|
|
|
@ -19,11 +19,13 @@
|
||||||
Require all denied
|
Require all denied
|
||||||
Include /etc/apache2/ipaddr_whitelist.conf
|
Include /etc/apache2/ipaddr_whitelist.conf
|
||||||
</Directory>
|
</Directory>
|
||||||
<Directory /usr/lib/munin/cgi/>
|
# munin-cgi-graph, used for zooming on graphs.
|
||||||
Options -Indexes
|
ScriptAlias /munin-cgi/munin-cgi-graph /usr/lib/munin/cgi/munin-cgi-graph
|
||||||
|
<Location /munin-cgi/munin-cgi-graph>
|
||||||
|
Options +ExecCGI
|
||||||
Require all denied
|
Require all denied
|
||||||
Include /etc/apache2/ipaddr_whitelist.conf
|
Include /etc/apache2/ipaddr_whitelist.conf
|
||||||
</Directory>
|
</Location>
|
||||||
|
|
||||||
# For CGI Scripts. We need to set Directory directive as ScriptAlias take precedence.
|
# For CGI Scripts. We need to set Directory directive as ScriptAlias take precedence.
|
||||||
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
|
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
|
||||||
|
|
|
@ -11,6 +11,7 @@ Tasks are extracted in several files, included in `tasks/main.yml` :
|
||||||
|
|
||||||
## Available variables
|
## Available variables
|
||||||
|
|
||||||
|
* `apt_config` : customize apt configuration (default: `True`) ;
|
||||||
* `apt_install_basics` : change basic sources components (default: `True`) ;
|
* `apt_install_basics` : change basic sources components (default: `True`) ;
|
||||||
* `apt_basics_components` : basic sources components (default: `main`) ;
|
* `apt_basics_components` : basic sources components (default: `main`) ;
|
||||||
* `apt_install_backports` : install backports sources (default: `False`) ;
|
* `apt_install_backports` : install backports sources (default: `False`) ;
|
||||||
|
|
|
@ -1,4 +1,10 @@
|
||||||
---
|
---
|
||||||
|
apt_config: True
|
||||||
|
apt_evolinux_config: True
|
||||||
|
apt_hooks: True
|
||||||
|
apt_remove_aptitude: True
|
||||||
|
apt_upgrade: False
|
||||||
|
|
||||||
apt_install_basics: True
|
apt_install_basics: True
|
||||||
apt_basics_components: "main"
|
apt_basics_components: "main"
|
||||||
|
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
---
|
|
||||||
- name: apt update
|
|
||||||
apt:
|
|
||||||
update_cache: yes
|
|
|
@ -13,7 +13,7 @@
|
||||||
dest: /etc/apt/sources.list.d/backports.list
|
dest: /etc/apt/sources.list.d/backports.list
|
||||||
force: yes
|
force: yes
|
||||||
mode: "0640"
|
mode: "0640"
|
||||||
notify: apt update
|
register: apt_backports_list
|
||||||
tags:
|
tags:
|
||||||
- apt
|
- apt
|
||||||
|
|
||||||
|
@ -23,11 +23,13 @@
|
||||||
dest: /etc/apt/preferences.d/0-backports-defaults
|
dest: /etc/apt/preferences.d/0-backports-defaults
|
||||||
force: yes
|
force: yes
|
||||||
mode: "0640"
|
mode: "0640"
|
||||||
notify: apt update
|
register: apt_backports_config
|
||||||
tags:
|
tags:
|
||||||
- apt
|
- apt
|
||||||
|
|
||||||
- name: Intermediate flush of handlers
|
- name: Apt update
|
||||||
meta: flush_handlers
|
apt:
|
||||||
|
update_cache: yes
|
||||||
|
when: apt_backports_list | changed or apt_backports_config | changed
|
||||||
tags:
|
tags:
|
||||||
- apt
|
- apt
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
dest: /etc/apt/sources.list
|
dest: /etc/apt/sources.list
|
||||||
mode: "0644"
|
mode: "0644"
|
||||||
force: yes
|
force: yes
|
||||||
notify: apt update
|
register: apt_basic_list
|
||||||
tags:
|
tags:
|
||||||
- apt
|
- apt
|
||||||
|
|
||||||
|
@ -20,7 +20,9 @@
|
||||||
- /etc/apt/sources.list.d/debian-update.list
|
- /etc/apt/sources.list.d/debian-update.list
|
||||||
when: apt_clean_gandi_sourceslist
|
when: apt_clean_gandi_sourceslist
|
||||||
|
|
||||||
- name: Intermediate flush of handlers
|
- name: Apt update
|
||||||
meta: flush_handlers
|
apt:
|
||||||
|
update_cache: yes
|
||||||
|
when: apt_basic_list | changed
|
||||||
tags:
|
tags:
|
||||||
- apt
|
- apt
|
||||||
|
|
|
@ -1,24 +1,19 @@
|
||||||
---
|
---
|
||||||
|
|
||||||
- include_role:
|
- name: Evolinux config for APT
|
||||||
name: apt
|
|
||||||
vars:
|
|
||||||
apt_install_basics: "{{ evolinux_apt_replace_default_sources }}"
|
|
||||||
apt_install_evolix_public: "{{ evolinux_apt_public_sources }}"
|
|
||||||
|
|
||||||
- name: Setting apt config
|
|
||||||
lineinfile:
|
lineinfile:
|
||||||
dest: /etc/apt/apt.conf.d/z-evolinux.conf
|
dest: /etc/apt/apt.conf.d/z-evolinux.conf
|
||||||
line: "{{ item }}"
|
line: "{{ item.line }}"
|
||||||
|
regexp: "{{ item.regexp }}"
|
||||||
create: yes
|
create: yes
|
||||||
state: present
|
state: present
|
||||||
mode: "0640"
|
mode: "0640"
|
||||||
with_items:
|
with_items:
|
||||||
- "APT::Install-Recommends \"false\";"
|
- { line: "APT::Install-Recommends \"false\";", regexp: 'APT::Install-Recommends' }
|
||||||
- "APT::Install-Suggests \"false\";"
|
- { line: "APT::Install-Suggests \"false\";", regexp: 'APT::Install-Suggests' }
|
||||||
when: evolinux_apt_conf
|
when: apt_evolinux_config
|
||||||
|
|
||||||
- name: DPKg invoke hooks
|
- name: DPkg invoke hooks
|
||||||
lineinfile:
|
lineinfile:
|
||||||
dest: /etc/apt/apt.conf.d/z-evolinux.conf
|
dest: /etc/apt/apt.conf.d/z-evolinux.conf
|
||||||
line: "{{ item }}"
|
line: "{{ item }}"
|
||||||
|
@ -30,13 +25,13 @@
|
||||||
- "DPkg::Pre-Invoke { \"df /usr | grep -q /usr && mount -oremount,rw /usr || true\"; };"
|
- "DPkg::Pre-Invoke { \"df /usr | grep -q /usr && mount -oremount,rw /usr || true\"; };"
|
||||||
- "DPkg::Post-Invoke { \"df /tmp | grep -q /tmp && mount -oremount /tmp || true\"; };"
|
- "DPkg::Post-Invoke { \"df /tmp | grep -q /tmp && mount -oremount /tmp || true\"; };"
|
||||||
- "DPkg::Post-Invoke { \"df /usr | grep -q /usr && mount -oremount /usr || true\"; };"
|
- "DPkg::Post-Invoke { \"df /usr | grep -q /usr && mount -oremount /usr || true\"; };"
|
||||||
when: evolinux_apt_hooks
|
when: apt_hooks
|
||||||
|
|
||||||
- name: Remove Aptitude
|
- name: Remove Aptitude
|
||||||
apt:
|
apt:
|
||||||
name: aptitude
|
name: aptitude
|
||||||
state: absent
|
state: absent
|
||||||
when: evolinux_apt_remove_aptitude
|
when: apt_remove_aptitude
|
||||||
|
|
||||||
- name: Updating APT cache
|
- name: Updating APT cache
|
||||||
apt:
|
apt:
|
||||||
|
@ -46,6 +41,4 @@
|
||||||
- name: Upgrading system
|
- name: Upgrading system
|
||||||
apt:
|
apt:
|
||||||
upgrade: dist
|
upgrade: dist
|
||||||
when: evolinux_apt_upgrade
|
when: apt_upgrade
|
||||||
|
|
||||||
- meta: flush_handlers
|
|
|
@ -19,11 +19,13 @@
|
||||||
dest: /etc/apt/sources.list.d/evolix_public.list
|
dest: /etc/apt/sources.list.d/evolix_public.list
|
||||||
force: yes
|
force: yes
|
||||||
mode: "0640"
|
mode: "0640"
|
||||||
notify: apt update
|
register: apt_evolix_public
|
||||||
tags:
|
tags:
|
||||||
- apt
|
- apt
|
||||||
|
|
||||||
- name: Intermediate flush of handlers
|
- name: Apt update
|
||||||
meta: flush_handlers
|
apt:
|
||||||
|
update_cache: yes
|
||||||
|
when: apt_evolix_public | changed
|
||||||
tags:
|
tags:
|
||||||
- apt
|
- apt
|
||||||
|
|
|
@ -7,6 +7,12 @@
|
||||||
tags:
|
tags:
|
||||||
- apt
|
- apt
|
||||||
|
|
||||||
|
- name: Custom configuration
|
||||||
|
include: config.yml
|
||||||
|
when: apt_config
|
||||||
|
tags:
|
||||||
|
- apt
|
||||||
|
|
||||||
- name: Install basics repositories
|
- name: Install basics repositories
|
||||||
include: basics.yml
|
include: basics.yml
|
||||||
when: apt_install_basics
|
when: apt_install_basics
|
||||||
|
@ -19,9 +25,6 @@
|
||||||
tags:
|
tags:
|
||||||
- apt
|
- apt
|
||||||
|
|
||||||
- debug:
|
|
||||||
var: apt_install_evolix_public
|
|
||||||
|
|
||||||
- name: Install Evolix Public APT repository
|
- name: Install Evolix Public APT repository
|
||||||
include: evolix_public.yml
|
include: evolix_public.yml
|
||||||
when: apt_install_evolix_public
|
when: apt_install_evolix_public
|
||||||
|
|
5
clamav/handlers/main.yml
Normal file
5
clamav/handlers/main.yml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
- name: restart clamav
|
||||||
|
service:
|
||||||
|
name: clamav-daemon
|
||||||
|
state: restarted
|
3
clamav/meta/main.yml
Normal file
3
clamav/meta/main.yml
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
dependencies:
|
||||||
|
- { role: amavis }
|
111
clamav/tasks/main.yml
Normal file
111
clamav/tasks/main.yml
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
---
|
||||||
|
- name: configure clamav-daemon
|
||||||
|
debconf:
|
||||||
|
name: clamav-daemon
|
||||||
|
question: "{{ item.key }}"
|
||||||
|
value: "{{ item.value }}"
|
||||||
|
vtype: "{{ item.type }}"
|
||||||
|
with_items:
|
||||||
|
- { key: 'clamav-daemon/debconf', type: 'boolean', value: 'true' }
|
||||||
|
- { key: 'clamav-daemon/MaxHTMLNormalize', type: 'string', value: '10M' }
|
||||||
|
- { key: 'clamav-daemon/StatsPEDisabled', type: 'boolean', value: 'true' }
|
||||||
|
- { key: 'clamav-daemon/FollowDirectorySymlinks', type: 'boolean', value: 'false' }
|
||||||
|
- { key: 'clamav-daemon/StreamMaxLength', type: 'string', value: '25' }
|
||||||
|
- { key: 'clamav-daemon/ReadTimeout', type: 'string', value: '180' }
|
||||||
|
- { key: 'clamav-daemon/StatsEnabled', type: 'boolean', value: 'false' }
|
||||||
|
- { key: 'clamav-daemon/MaxConnectionQueueLength', type: 'string', value: '15' }
|
||||||
|
- { key: 'clamav-daemon/LogRotate', type: 'boolean', value: 'true' }
|
||||||
|
- { key: 'clamav-daemon/AllowAllMatchScan', type: 'boolean', value: 'true' }
|
||||||
|
- { key: 'clamav-daemon/ScanOnAccess', type: 'boolean', value: 'false' }
|
||||||
|
- { key: 'clamav-daemon/LogFile', type: 'string', value: '/var/log/clamav/clamav.log' }
|
||||||
|
- { key: 'clamav-daemon/ScanMail', type: 'boolean', value: 'true' }
|
||||||
|
- { key: 'clamav-daemon/BytecodeTimeout', type: 'string', value: '60000' }
|
||||||
|
- { key: 'clamav-daemon/LogTime', type: 'boolean', value: 'true' }
|
||||||
|
- { key: 'clamav-daemon/OnAccessMaxFileSize', type: 'string', value: '5M' }
|
||||||
|
- { key: 'clamav-daemon/TcpOrLocal', type: 'select', value: 'UNIX' }
|
||||||
|
- { key: 'clamav-daemon/MaxEmbeddedPE', type: 'string', value: '10M' }
|
||||||
|
- { key: 'clamav-daemon/FixStaleSocket', type: 'boolean', value: 'true' }
|
||||||
|
- { key: 'clamav-daemon/User', type: 'string', value: 'clamav' }
|
||||||
|
- { key: 'clamav-daemon/BytecodeSecurity', type: 'select', value: 'TrustSigned' }
|
||||||
|
- { key: 'clamav-daemon/ScanSWF', type: 'boolean', value: 'true' }
|
||||||
|
- { key: 'clamav-daemon/MaxDirectoryRecursion', type: 'string', value: '0' }
|
||||||
|
- { key: 'clamav-daemon/MaxThreads', type: 'string', value: '12' }
|
||||||
|
- { key: 'clamav-daemon/LocalSocketGroup', type: 'string', value: 'clamav' }
|
||||||
|
- { key: 'clamav-daemon/MaxScriptNormalize', type: 'string', value: '5M' }
|
||||||
|
- { key: 'clamav-daemon/ForceToDisk', type: 'boolean', value: 'false' }
|
||||||
|
- { key: 'clamav-daemon/StatsHostID', type: 'string', value: 'auto' }
|
||||||
|
- { key: 'clamav-daemon/FollowFileSymlinks', type: 'boolean', value: 'false' }
|
||||||
|
- { key: 'clamav-daemon/TCPSocket', type: 'string', value: '3310' }
|
||||||
|
- { key: 'clamav-daemon/TCPAddr', type: 'string', value: 'any' }
|
||||||
|
- { key: 'clamav-daemon/DisableCertCheck', type: 'boolean', value: 'false' }
|
||||||
|
- { key: 'clamav-daemon/SelfCheck', type: 'string', value: '3600' }
|
||||||
|
- { key: 'clamav-daemon/LocalSocket', type: 'string', value: '/var/run/clamav/clamd.ctl' }
|
||||||
|
- { key: 'clamav-daemon/LocalSocketMode', type: 'string', value: '666' }
|
||||||
|
- { key: 'clamav-daemon/StatsTimeout', type: 'string', value: '10' }
|
||||||
|
- { key: 'clamav-daemon/MaxZipTypeRcg', type: 'string', value: '1M' }
|
||||||
|
- { key: 'clamav-daemon/MaxHTMLNoTags', type: 'string', value: '2M' }
|
||||||
|
- { key: 'clamav-daemon/LogSyslog', type: 'boolean', value: 'false' }
|
||||||
|
- { key: 'clamav-daemon/AddGroups', type: 'string', value: '' }
|
||||||
|
- { key: 'clamav-daemon/Bytecode', type: 'boolean', value: 'true' }
|
||||||
|
- { key: 'clamav-daemon/ScanArchive', type: 'boolean', value: 'true' }
|
||||||
|
tags:
|
||||||
|
- clamav
|
||||||
|
|
||||||
|
- name: configure clamav-freshclam
|
||||||
|
debconf:
|
||||||
|
name: clamav-freshclam
|
||||||
|
question: "{{ item.key }}"
|
||||||
|
value: "{{ item.value }}"
|
||||||
|
vtype: "{{ item.type }}"
|
||||||
|
with_items:
|
||||||
|
- { key: 'clamav-freshclam/autoupdate_freshclam', type: 'select', value: 'daemon' }
|
||||||
|
- { key: 'clamav-freshclam/proxy_user', type: 'string', value: '' }
|
||||||
|
- { key: 'clamav-freshclam/NotifyClamd', type: 'boolean', value: 'true' }
|
||||||
|
- { key: 'clamav-freshclam/local_mirror', type: 'select', value: 'db.fr.clamav.net' }
|
||||||
|
- { key: 'clamav-freshclam/http_proxy', type: 'string', value: '' }
|
||||||
|
- { key: 'clamav-freshclam/LogRotate', type: 'boolean', value: 'true' }
|
||||||
|
- { key: 'clamav-freshclam/Bytecode', type: 'boolean', value: 'true' }
|
||||||
|
- { key: 'clamav-freshclam/update_interval', type: 'string', value: '24' }
|
||||||
|
- { key: 'clamav-freshclam/SafeBrowsing', type: 'boolean', value: 'false' }
|
||||||
|
- { key: 'clamav-freshclam/PrivateMirror', type: 'string', value: '' }
|
||||||
|
- { key: 'clamav-freshclam/internet_interface', type: 'string', value: '' }
|
||||||
|
tags:
|
||||||
|
- clamav
|
||||||
|
|
||||||
|
- name: install ClamAV
|
||||||
|
apt:
|
||||||
|
name: "{{ item }}"
|
||||||
|
state: present
|
||||||
|
with_items:
|
||||||
|
- clamav-daemon
|
||||||
|
- clamav
|
||||||
|
- clamdscan
|
||||||
|
- clamav-freshclam
|
||||||
|
- arc
|
||||||
|
- arj
|
||||||
|
- zoo
|
||||||
|
- pax
|
||||||
|
- bzip2
|
||||||
|
- cabextract
|
||||||
|
- rpm
|
||||||
|
- lzop
|
||||||
|
- razor
|
||||||
|
tags:
|
||||||
|
- clamav
|
||||||
|
|
||||||
|
- name: add clamav user to amavis group
|
||||||
|
user:
|
||||||
|
name: clamav
|
||||||
|
groups: amavis
|
||||||
|
append: True
|
||||||
|
tags:
|
||||||
|
- clamav
|
||||||
|
|
||||||
|
- name: allow supplementary groups
|
||||||
|
replace:
|
||||||
|
dest: /etc/clamav/clamd.conf
|
||||||
|
regexp: 'AllowSupplementaryGroups false'
|
||||||
|
replace: 'AllowSupplementaryGroups true'
|
||||||
|
notify: restart clamav
|
||||||
|
tags:
|
||||||
|
- clamav
|
36
dovecot/.kitchen.yml
Normal file
36
dovecot/.kitchen.yml
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
---
|
||||||
|
driver:
|
||||||
|
name: docker
|
||||||
|
privileged: true
|
||||||
|
use_sudo: false
|
||||||
|
|
||||||
|
provisioner:
|
||||||
|
name: ansible_playbook
|
||||||
|
hosts: test-kitchen
|
||||||
|
roles_path: ../
|
||||||
|
ansible_verbose: true
|
||||||
|
require_ansible_source: false
|
||||||
|
require_chef_for_busser: false
|
||||||
|
idempotency_test: true
|
||||||
|
|
||||||
|
platforms:
|
||||||
|
- name: debian
|
||||||
|
driver_config:
|
||||||
|
image: evolix/ansible:2.2.1
|
||||||
|
|
||||||
|
verifier:
|
||||||
|
name: serverspec
|
||||||
|
|
||||||
|
suites:
|
||||||
|
- name: default
|
||||||
|
provisioner:
|
||||||
|
name: ansible_playbook
|
||||||
|
playbook: ./tests/test.yml
|
||||||
|
verifier:
|
||||||
|
patterns:
|
||||||
|
- nginx/tests/spec/memcached_spec.rb
|
||||||
|
bundler_path: '/usr/local/bin'
|
||||||
|
rspec_path: '/usr/local/bin'
|
||||||
|
|
||||||
|
transport:
|
||||||
|
max_ssh_sessions: 6
|
11
dovecot/README.md
Normal file
11
dovecot/README.md
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# Dovecot
|
||||||
|
|
||||||
|
Installation and basic configuration of dovecot
|
||||||
|
|
||||||
|
## Tasks
|
||||||
|
|
||||||
|
Minimal configuration is in `tasks/main.yml`
|
||||||
|
|
||||||
|
## Available variables
|
||||||
|
|
||||||
|
The full list of variables (with default values) can be found in `defaults/main.yml`.
|
2
dovecot/defaults/main.yml
Normal file
2
dovecot/defaults/main.yml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
---
|
||||||
|
dovecot_foo: bar
|
126
dovecot/files/munin_plugin
Executable file
126
dovecot/files/munin_plugin
Executable file
|
@ -0,0 +1,126 @@
|
||||||
|
#! /bin/bash
|
||||||
|
#
|
||||||
|
# Munin Plugin
|
||||||
|
# to count logins to your dovecot mailserver
|
||||||
|
#
|
||||||
|
# Created by Dominik Schulz <lkml@ds.gauner.org>
|
||||||
|
# http://developer.gauner.org/munin/
|
||||||
|
# Contributions by:
|
||||||
|
# - Stephane Enten <tuf@delyth.net>
|
||||||
|
# - Steve Schnepp <steve.schnepp@pwkf.org>
|
||||||
|
#
|
||||||
|
# Parameters understood:
|
||||||
|
#
|
||||||
|
# config (required)
|
||||||
|
# autoconf (optional - used by munin-config)
|
||||||
|
#
|
||||||
|
# Config variables:
|
||||||
|
#
|
||||||
|
# logfile - Where to find the syslog file
|
||||||
|
#
|
||||||
|
# Add the following line to a file in /etc/munin/plugin-conf.d:
|
||||||
|
# env.logfile /var/log/your/logfile.log
|
||||||
|
#
|
||||||
|
# Magic markers (optional - used by munin-config and installation scripts):
|
||||||
|
#
|
||||||
|
#%# family=auto
|
||||||
|
#%# capabilities=autoconf
|
||||||
|
|
||||||
|
######################
|
||||||
|
# Configuration
|
||||||
|
######################
|
||||||
|
EXPR_BIN=/usr/bin/expr
|
||||||
|
LOGFILE=${logfile:-/var/log/mail.log}
|
||||||
|
######################
|
||||||
|
|
||||||
|
if [ "$1" = "autoconf" ]; then
|
||||||
|
echo yes
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$1" = "config" ]; then
|
||||||
|
echo 'graph_title Dovecot Logins'
|
||||||
|
echo 'graph_category Mail'
|
||||||
|
echo 'graph_args --base 1000 -l 0'
|
||||||
|
echo 'graph_vlabel Login Counters'
|
||||||
|
|
||||||
|
for t in Total TLS SSL IMAP POP3
|
||||||
|
do
|
||||||
|
field=$(echo $t | tr '[:upper:]' '[:lower:]')
|
||||||
|
echo "login_$field.label $t Logins"
|
||||||
|
echo "login_$field.type DERIVE"
|
||||||
|
echo "login_$field.min 0"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo 'connected.label Connected Users'
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
######################
|
||||||
|
# Total Logins
|
||||||
|
######################
|
||||||
|
echo -en "login_total.value "
|
||||||
|
VALUE=$(egrep -c '[dovecot]?.*Login' $LOGFILE)
|
||||||
|
if [ ! -z "$VALUE" ]; then
|
||||||
|
echo "$VALUE"
|
||||||
|
else
|
||||||
|
echo "0"
|
||||||
|
fi
|
||||||
|
echo -n
|
||||||
|
######################
|
||||||
|
# Connected Users
|
||||||
|
######################
|
||||||
|
DISCONNECTS=$(egrep -c '[dovecot]?.*Disconnected' $LOGFILE)
|
||||||
|
CONNECTS=$(egrep -c '[dovecot]?.*Login' $LOGFILE)
|
||||||
|
VALUE=$($EXPR_BIN $CONNECTS - $DISCONNECTS)
|
||||||
|
if [ -z "$VALUE" ] || [ "$VALUE" -lt 0 ]; then
|
||||||
|
VALUE=0
|
||||||
|
fi
|
||||||
|
echo -en "connected.value "
|
||||||
|
echo $VALUE
|
||||||
|
echo -n
|
||||||
|
######################
|
||||||
|
# TLS Logins
|
||||||
|
######################
|
||||||
|
echo -en "login_tls.value "
|
||||||
|
VALUE=$(egrep -c '[dovecot]?.*Login.*TLS' $LOGFILE)
|
||||||
|
if [ ! -z "$VALUE" ]; then
|
||||||
|
echo "$VALUE"
|
||||||
|
else
|
||||||
|
echo "0"
|
||||||
|
fi
|
||||||
|
echo -n
|
||||||
|
######################
|
||||||
|
# SSL Logins
|
||||||
|
######################
|
||||||
|
echo -en "login_ssl.value "
|
||||||
|
VALUE=$(egrep -c '[dovecot]?.*Login.*SSL' $LOGFILE)
|
||||||
|
if [ ! -z "$VALUE" ]; then
|
||||||
|
echo "$VALUE"
|
||||||
|
else
|
||||||
|
echo "0"
|
||||||
|
fi
|
||||||
|
echo -n
|
||||||
|
######################
|
||||||
|
# IMAP Logins
|
||||||
|
######################
|
||||||
|
echo -en "login_imap.value "
|
||||||
|
VALUE=$(egrep -c '[dovecot]?.*imap.*Login' $LOGFILE)
|
||||||
|
if [ ! -z "$VALUE" ]; then
|
||||||
|
echo "$VALUE"
|
||||||
|
else
|
||||||
|
echo "0"
|
||||||
|
fi
|
||||||
|
echo -n
|
||||||
|
######################
|
||||||
|
# POP3 Logins
|
||||||
|
######################
|
||||||
|
echo -en "login_pop3.value "
|
||||||
|
VALUE=$(egrep -c '[dovecot]?.*pop3.*Login' $LOGFILE)
|
||||||
|
if [ ! -z "$VALUE" ]; then
|
||||||
|
echo "$VALUE"
|
||||||
|
else
|
||||||
|
echo "0"
|
||||||
|
fi
|
||||||
|
echo -n
|
10
dovecot/handlers/main.yml
Normal file
10
dovecot/handlers/main.yml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
---
|
||||||
|
- name: restart dovecot
|
||||||
|
service:
|
||||||
|
name: dovecot
|
||||||
|
state: restarted
|
||||||
|
|
||||||
|
- name: reload dovecot
|
||||||
|
service:
|
||||||
|
name: dovecot
|
||||||
|
state: reloaded
|
68
dovecot/tasks/main.yml
Normal file
68
dovecot/tasks/main.yml
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
- name: ensure packages are installed
|
||||||
|
apt:
|
||||||
|
name: '{{ item }}'
|
||||||
|
state: present
|
||||||
|
with_items:
|
||||||
|
- dovecot-ldap
|
||||||
|
- dovecot-imapd
|
||||||
|
- dovecot-pop3d
|
||||||
|
- dovecot-sieve
|
||||||
|
- dovecot-managesieved
|
||||||
|
tags:
|
||||||
|
- dovecot
|
||||||
|
|
||||||
|
- name: disable pam auth
|
||||||
|
replace:
|
||||||
|
dest: /etc/dovecot/conf.d/10-auth.conf
|
||||||
|
regexp: "[^#]!include auth-system.conf.ext"
|
||||||
|
replace: "#!include auth-system.conf.ext"
|
||||||
|
tags:
|
||||||
|
- dovecot
|
||||||
|
|
||||||
|
- name: update ldap auth
|
||||||
|
lineinfile:
|
||||||
|
dest: /etc/dovecot/dovecot-ldap.conf.ext
|
||||||
|
line: "{{ item.key }} = {{ item.value }}"
|
||||||
|
regexp: "^#*{{ item.key }}"
|
||||||
|
state: present
|
||||||
|
with_items:
|
||||||
|
- { key: 'hosts', value: '127.0.0.1' }
|
||||||
|
- { key: 'auth_bind', value: 'yes' }
|
||||||
|
- { key: 'ldap_version', value: 3 }
|
||||||
|
- { key: 'base', value: "{{ ldap_suffix }}" }
|
||||||
|
- { key: 'user_attrs', value: 'homeDirectory=home' }
|
||||||
|
- { key: 'user_filter', value: '(&(isActive=TRUE)(uid=%u))' }
|
||||||
|
- { key: 'pass_attrs', value: 'uid=user,userPassword=password' }
|
||||||
|
when: ldap_suffix is defined
|
||||||
|
notify: reload dovecot
|
||||||
|
tags:
|
||||||
|
- dovecot
|
||||||
|
|
||||||
|
- name: create vmail group
|
||||||
|
group:
|
||||||
|
name: vmail
|
||||||
|
gid: 5000
|
||||||
|
tags:
|
||||||
|
- dovecot
|
||||||
|
|
||||||
|
- name: create vmail user
|
||||||
|
user:
|
||||||
|
name: vmail
|
||||||
|
group: vmail
|
||||||
|
uid: 5000
|
||||||
|
shell: /bin/false
|
||||||
|
tags:
|
||||||
|
- dovecot
|
||||||
|
|
||||||
|
- name: deploy evolix config
|
||||||
|
template:
|
||||||
|
src: z-evolinux-defaults.conf.j2
|
||||||
|
dest: /etc/dovecot/conf.d/z-evolinux-defaults.conf
|
||||||
|
mode: "0644"
|
||||||
|
notify: reload dovecot
|
||||||
|
tags:
|
||||||
|
- dovecot
|
||||||
|
|
||||||
|
- include: munin.yml
|
||||||
|
tags:
|
||||||
|
- dovecot
|
20
dovecot/tasks/munin.yml
Normal file
20
dovecot/tasks/munin.yml
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
- name: is Munin present ?
|
||||||
|
stat:
|
||||||
|
path: /etc/munin/plugin-conf.d/munin-node
|
||||||
|
check_mode: no
|
||||||
|
register: munin_node_plugins_config
|
||||||
|
|
||||||
|
- block:
|
||||||
|
- name: Install munin plugin
|
||||||
|
copy:
|
||||||
|
src: munin_plugin
|
||||||
|
dest: /etc/munin/plugins/dovecot
|
||||||
|
mode: "0755"
|
||||||
|
|
||||||
|
# TODO : add in /etc/munin/plugin-conf.d/munin-node
|
||||||
|
# [dovecot]
|
||||||
|
# group adm
|
||||||
|
|
||||||
|
when: munin_node_plugins_config.stat.exists
|
36
dovecot/templates/z-evolinux-defaults.conf.j2
Normal file
36
dovecot/templates/z-evolinux-defaults.conf.j2
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
# {{ ansible_managed }}
|
||||||
|
|
||||||
|
# Autorise les mécanismes PLAIN/LOGIN même sans SSL/TLS
|
||||||
|
disable_plaintext_auth = no
|
||||||
|
auth_mechanisms = plain login
|
||||||
|
|
||||||
|
# Authentification LDAP + intégration avec Postfix pour l'auth SMTP
|
||||||
|
!include auth-ldap.conf.ext
|
||||||
|
service auth {
|
||||||
|
unix_listener auth-userdb {
|
||||||
|
mode = 0600
|
||||||
|
user = vmail
|
||||||
|
group = vmail
|
||||||
|
}
|
||||||
|
unix_listener /var/spool/postfix/private/auth-client {
|
||||||
|
mode = 0666
|
||||||
|
user = postfix
|
||||||
|
group = postfix
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Stockage des emails dans /home/mail avec UID/GID 5000/5000
|
||||||
|
mail_location = maildir:/home/vmail/%d/%n
|
||||||
|
mail_uid = 5000
|
||||||
|
mail_gid = 5000
|
||||||
|
|
||||||
|
# Activation Sieve
|
||||||
|
protocol lda {
|
||||||
|
mail_plugins = sieve
|
||||||
|
}
|
||||||
|
|
||||||
|
# Optimisations
|
||||||
|
service login {
|
||||||
|
process_limit = 256
|
||||||
|
}
|
||||||
|
mail_max_userip_connections = 42
|
|
@ -5,23 +5,3 @@ Install tools to setup DRBD replication accross servers.
|
||||||
## Tasks
|
## Tasks
|
||||||
|
|
||||||
Everything is in the `tasks/main.yml` file.
|
Everything is in the `tasks/main.yml` file.
|
||||||
|
|
||||||
## Available variables
|
|
||||||
|
|
||||||
The variable `admin_users` must be a "dict" of one or more users :
|
|
||||||
|
|
||||||
```
|
|
||||||
admin_users:
|
|
||||||
foo:
|
|
||||||
name: foo
|
|
||||||
uid: 1001
|
|
||||||
fullname: 'Mr Foo'
|
|
||||||
password_hash: 'sdfgsdfgsdfgsdfg'
|
|
||||||
ssh_key: 'ssh-rsa AZERTYXYZ'
|
|
||||||
bar:
|
|
||||||
name: bar
|
|
||||||
uid: 1002
|
|
||||||
fullname: 'Mr Bar'
|
|
||||||
password_hash: 'gsdfgsdfgsdfgsdf'
|
|
||||||
ssh_key: 'ssh-rsa QWERTYUIOP'
|
|
||||||
```
|
|
||||||
|
|
|
@ -8,23 +8,8 @@
|
||||||
tags:
|
tags:
|
||||||
- drbd
|
- drbd
|
||||||
|
|
||||||
- name: Check if /usr is a partition
|
- include_role:
|
||||||
shell: "mount | grep 'on /usr type'"
|
name: remount-usr
|
||||||
args:
|
|
||||||
warn: no
|
|
||||||
changed_when: False
|
|
||||||
failed_when: False
|
|
||||||
register: usr_partition
|
|
||||||
check_mode: no
|
|
||||||
tags:
|
|
||||||
- drbd
|
|
||||||
|
|
||||||
- name: Mount /usr in rw
|
|
||||||
command: mount -o remount,rw /usr
|
|
||||||
args:
|
|
||||||
warn: no
|
|
||||||
changed_when: False
|
|
||||||
when: usr_partition.rc == 0 and nagios_plugins_dir.stat.exists
|
|
||||||
tags:
|
tags:
|
||||||
- drbd
|
- drbd
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ elasticsearch_custom_tmpdir: Null
|
||||||
elasticsearch_default_tmpdir: /var/lib/elasticsearch/tmp
|
elasticsearch_default_tmpdir: /var/lib/elasticsearch/tmp
|
||||||
elasticsearch_jvm_xms: 2g
|
elasticsearch_jvm_xms: 2g
|
||||||
elasticsearch_jvm_xmx: 2g
|
elasticsearch_jvm_xmx: 2g
|
||||||
|
elasticsearch_log_rotate_days: 365
|
||||||
|
|
||||||
elasticsearch_curator: False
|
elasticsearch_curator: False
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ galaxy_info:
|
||||||
- name: Debian
|
- name: Debian
|
||||||
versions:
|
versions:
|
||||||
- jessie
|
- jessie
|
||||||
|
- stretch
|
||||||
|
|
||||||
galaxy_tags: []
|
galaxy_tags: []
|
||||||
# List tags for your role here, one per line. A tag is
|
# List tags for your role here, one per line. A tag is
|
||||||
|
@ -23,4 +24,5 @@ galaxy_info:
|
||||||
# NOTE: A tag is limited to a single word comprised of
|
# NOTE: A tag is limited to a single word comprised of
|
||||||
# alphanumeric characters. Maximum 20 tags per role.
|
# alphanumeric characters. Maximum 20 tags per role.
|
||||||
|
|
||||||
dependencies: []
|
dependencies:
|
||||||
|
- java8
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
- name: Curator sources list is available
|
- name: Curator sources list is available
|
||||||
apt_repository:
|
apt_repository:
|
||||||
repo: "deb http://packages.elastic.co/curator/4/debian stable main"
|
repo: "deb http://packages.elastic.co/curator/4/debian stable main"
|
||||||
|
filename: elastic
|
||||||
update_cache: yes
|
update_cache: yes
|
||||||
state: present
|
state: present
|
||||||
tags:
|
tags:
|
||||||
|
|
|
@ -7,16 +7,16 @@
|
||||||
register: elasticsearch_custom_datadir_test
|
register: elasticsearch_custom_datadir_test
|
||||||
check_mode: no
|
check_mode: no
|
||||||
|
|
||||||
|
|
||||||
- name: "read the real datadir"
|
- name: "read the real datadir"
|
||||||
command: readlink -f /var/lib/elasticsearch
|
command: readlink -f /var/lib/elasticsearch
|
||||||
changed_when: false
|
changed_when: false
|
||||||
register: elasticsearch_current_real_datadir_test
|
register: elasticsearch_current_real_datadir_test
|
||||||
check_mode: no
|
check_mode: no
|
||||||
|
|
||||||
tags:
|
tags:
|
||||||
- elasticsearch
|
- elasticsearch
|
||||||
when: elasticsearch_custom_datadir
|
when:
|
||||||
|
- elasticsearch_custom_datadir != ''
|
||||||
|
- elasticsearch_custom_datadir != None
|
||||||
|
|
||||||
- block:
|
- block:
|
||||||
- name: elasticsearch is stopped
|
- name: elasticsearch is stopped
|
||||||
|
@ -41,4 +41,8 @@
|
||||||
state: started
|
state: started
|
||||||
tags:
|
tags:
|
||||||
- elasticsearch
|
- elasticsearch
|
||||||
when: elasticsearch_custom_datadir and elasticsearch_custom_datadir != elasticsearch_current_real_datadir_test.stdout and not elasticsearch_custom_datadir_test.stat.exists
|
when:
|
||||||
|
- elasticsearch_custom_datadir != ''
|
||||||
|
- elasticsearch_custom_datadir != None
|
||||||
|
- elasticsearch_custom_datadir != elasticsearch_current_real_datadir_test.stdout
|
||||||
|
- not elasticsearch_custom_datadir_test.stat.exists
|
||||||
|
|
9
elasticsearch/tasks/logs.yml
Normal file
9
elasticsearch/tasks/logs.yml
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
- name: "log rotation script"
|
||||||
|
template:
|
||||||
|
src: rotate_elasticsearch_logs.j2
|
||||||
|
dest: /etc/cron.daily/rotate_elasticsearch_logs
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "0750"
|
|
@ -10,6 +10,8 @@
|
||||||
|
|
||||||
- include: tmpdir.yml
|
- include: tmpdir.yml
|
||||||
|
|
||||||
|
- include: logs.yml
|
||||||
|
|
||||||
- include: plugin_head.yml
|
- include: plugin_head.yml
|
||||||
when: elasticsearch_plugin_head
|
when: elasticsearch_plugin_head
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,5 @@
|
||||||
---
|
---
|
||||||
|
|
||||||
- name: install java8
|
|
||||||
include_role:
|
|
||||||
name: java8
|
|
||||||
tags:
|
|
||||||
- elasticsearch
|
|
||||||
- packages
|
|
||||||
|
|
||||||
- name: APT https transport is enabled
|
- name: APT https transport is enabled
|
||||||
apt:
|
apt:
|
||||||
name: apt-transport-https
|
name: apt-transport-https
|
||||||
|
@ -27,7 +20,7 @@
|
||||||
- name: Elastic sources list is available
|
- name: Elastic sources list is available
|
||||||
apt_repository:
|
apt_repository:
|
||||||
repo: "deb https://artifacts.elastic.co/packages/5.x/apt stable main"
|
repo: "deb https://artifacts.elastic.co/packages/5.x/apt stable main"
|
||||||
filename: elastic.list
|
filename: elastic
|
||||||
state: present
|
state: present
|
||||||
update_cache: yes
|
update_cache: yes
|
||||||
tags:
|
tags:
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
- block:
|
- block:
|
||||||
- name: Head repository is checked-out
|
- name: Head repository is checked-out
|
||||||
git:
|
git:
|
||||||
repo: "git://github.com/mobz/elasticsearch-head.git"
|
repo: "https://github.com/mobz/elasticsearch-head.git"
|
||||||
dest: "{{ elasticsearch_plugin_head_clone_dir }}"
|
dest: "{{ elasticsearch_plugin_head_clone_dir }}"
|
||||||
clone: yes
|
clone: yes
|
||||||
tags:
|
tags:
|
||||||
|
@ -53,3 +53,21 @@
|
||||||
- restart elasticsearch
|
- restart elasticsearch
|
||||||
tags:
|
tags:
|
||||||
- elasticsearch
|
- elasticsearch
|
||||||
|
|
||||||
|
- name: Install systemd unit
|
||||||
|
template:
|
||||||
|
src: elasticsearch-head.service.j2
|
||||||
|
dest: /etc/systemd/system/elasticsearch-head.service
|
||||||
|
tags:
|
||||||
|
- elasticsearch
|
||||||
|
- systemd
|
||||||
|
|
||||||
|
- name: Enable systemd unit
|
||||||
|
systemd:
|
||||||
|
name: elasticsearch-head
|
||||||
|
daemon_reload: yes
|
||||||
|
enabled: yes
|
||||||
|
state: started
|
||||||
|
tags:
|
||||||
|
- elasticsearch
|
||||||
|
- systemd
|
||||||
|
|
|
@ -28,4 +28,4 @@
|
||||||
- restart elasticsearch
|
- restart elasticsearch
|
||||||
tags:
|
tags:
|
||||||
- elasticsearch
|
- elasticsearch
|
||||||
when: elasticsearch_custom_tmpdir or fstab_tmp_noexec | success
|
when: (elasticsearch_custom_tmpdir != '' and elasticsearch_custom_tmpdir != None) or fstab_tmp_noexec | success
|
||||||
|
|
14
elasticsearch/templates/elasticsearch-head.service.j2
Normal file
14
elasticsearch/templates/elasticsearch-head.service.j2
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
ExecStart=/usr/bin/npm run start
|
||||||
|
User={{ elasticsearch_plugin_head_owner }}
|
||||||
|
Group={{ elasticsearch_plugin_head_group }}
|
||||||
|
StandardOutput=syslog
|
||||||
|
StandardError=syslog
|
||||||
|
SyslogIdentifier=elasticsearch-head
|
||||||
|
Restart=always
|
||||||
|
WorkingDirectory={{ elasticsearch_plugin_head_clone_dir }}
|
||||||
|
Environment=NODE_ENV=production
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
9
elasticsearch/templates/rotate_elasticsearch_logs.j2
Normal file
9
elasticsearch/templates/rotate_elasticsearch_logs.j2
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# {{ ansible_managed }}
|
||||||
|
|
||||||
|
LOG_DIR=/var/log/elasticsearch
|
||||||
|
USER=elasticsearch
|
||||||
|
MAX_AGE={{ elasticsearch_log_rotate_days | mandatory }}
|
||||||
|
|
||||||
|
find ${LOG_DIR} -type f -user ${USER} -name "*.log.????-??-??" -exec gzip --best {} \;
|
||||||
|
find ${LOG_DIR} -type f -user ${USER} -name "*.log.????-??-??.gz" -mtime +${MAX_AGE} -delete
|
|
@ -5,6 +5,7 @@ evoacme_dhparam_size: 2048
|
||||||
evoacme_acme_dir: /var/lib/letsencrypt
|
evoacme_acme_dir: /var/lib/letsencrypt
|
||||||
evoacme_csr_dir: /etc/ssl/requests
|
evoacme_csr_dir: /etc/ssl/requests
|
||||||
evoacme_crt_dir: /etc/letsencrypt
|
evoacme_crt_dir: /etc/letsencrypt
|
||||||
|
evoacme_hooks_dir: "{{ evoacme_crt_dir }}/hooks"
|
||||||
evoacme_log_dir: /var/log/evoacme
|
evoacme_log_dir: /var/log/evoacme
|
||||||
evoacme_ssl_minday: 30
|
evoacme_ssl_minday: 30
|
||||||
evoacme_ssl_ct: 'FR'
|
evoacme_ssl_ct: 'FR'
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
[ -f /etc/default/evoacme ] && . /etc/default/evoacme
|
[ -f /etc/default/evoacme ] && . /etc/default/evoacme
|
||||||
[ -z "${CRT_DIR}" ] && CRT_DIR='/etc/letsencrypt'
|
CRT_DIR="${CRT_DIR:-'/etc/letsencrypt'}"
|
||||||
|
|
||||||
find "${CRT_DIR}" -maxdepth 1 -mindepth 1 -type d ! -path "*accounts" -exec basename {} \; | while read vhost; do
|
export QUIET=1
|
||||||
evoacme "$vhost"
|
|
||||||
done
|
find "${CRT_DIR}" -maxdepth 1 -mindepth 1 -type d ! -path "*accounts" ! -path "*hooks" -printf "%f\n" | xargs -n1 evoacme
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/bin/sh
|
#!/bin/bash
|
||||||
#
|
#
|
||||||
# evoacme is a shell script to manage Let's Encrypt certificate with
|
# evoacme is a shell script to manage Let's Encrypt certificate with
|
||||||
# certbot tool but with a dedicated user (no-root) and from a csr
|
# certbot tool but with a dedicated user (no-root) and from a csr
|
||||||
|
@ -7,78 +7,287 @@
|
||||||
# Licence: AGPLv3
|
# Licence: AGPLv3
|
||||||
#
|
#
|
||||||
|
|
||||||
|
set -e
|
||||||
|
set -u
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
echo "Usage: $0 NAME"
|
cat <<EOT
|
||||||
echo ""
|
Usage: ${PROGNAME} NAME
|
||||||
echo "NAME must be correspond to :"
|
NAME must be correspond to :
|
||||||
echo "- a CSR in ${CSR_DIR}/NAME.csr"
|
- a CSR in ${CSR_DIR}/NAME.csr
|
||||||
echo "- a KEY in ${SSL_KEY_DIR}/NAME.key"
|
- a KEY in ${SSL_KEY_DIR}/NAME.key
|
||||||
echo ""
|
|
||||||
|
If env variable TEST=1, certbot is run in staging mode
|
||||||
|
If env variable DRY_RUN=1, certbot is run in dry-run mode
|
||||||
|
If env variable QUIET=1, no message is output
|
||||||
|
If env variable VERBOSE=1, debug messages are output
|
||||||
|
EOT
|
||||||
}
|
}
|
||||||
|
|
||||||
mkconf_apache() {
|
log() {
|
||||||
[ -f "/etc/apache2/ssl/${vhost}.conf" ] && sed -i "s~^SSLCertificateFile.*$~SSLCertificateFile $CRT_DIR/${vhost}/live/fullchain.pem~" "/etc/apache2/ssl/${vhost}.conf"
|
if [ "${QUIET}" != "1" ]; then
|
||||||
apache2ctl -t 2>/dev/null && service apache2 reload
|
echo "${PROGNAME}: $1"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
debug() {
|
||||||
|
if [ "${VERBOSE}" = "1" ] && [ "${QUIET}" != "1" ]; then
|
||||||
|
>&2 echo "${PROGNAME}: $1"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
error() {
|
||||||
|
>&2 echo "${PROGNAME}: $1"
|
||||||
|
[ "$1" = "invalid argument(s)" ] && >&2 usage
|
||||||
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
mkconf_nginx() {
|
sed_cert_path_for_apache() {
|
||||||
[ -f "/etc/nginx/ssl/${vhost}.conf" ] && sed -i "s~^ssl_certificate[^_].*$~ssl_certificate $CRT_DIR/${vhost}/live/fullchain.pem;~" "/etc/nginx/ssl/${vhost}.conf"
|
local vhost=$1
|
||||||
nginx -t 2>/dev/null && service nginx reload
|
local vhost_full_path="/etc/apache2/ssl/${vhost}.conf"
|
||||||
}
|
local cert_path=$2
|
||||||
|
|
||||||
mkconf_haproxy() {
|
[ ! -r "${vhost_full_path}" ] && return 0
|
||||||
mkdir -p /etc/ssl/haproxy -m 700
|
|
||||||
cat "$CRT_DIR/${vhost}/live/fullchain.pem" "$SSL_KEY_DIR/${vhost}.key" > "/etc/ssl/haproxy/${vhost}.pem"
|
local search="^SSLCertificateFile.*$"
|
||||||
[ -f "$DH_DIR/${vhost}.pem" ] && cat "$DH_DIR/${vhost}.pem" >> "/etc/ssl/haproxy/${vhost}.pem"
|
local replace="SSLCertificateFile ${cert_path}"
|
||||||
haproxy -c -f /etc/haproxy/haproxy.cfg >/dev/null && service haproxy reload
|
|
||||||
|
if ! $(grep -qE "${search}" "${vhost_full_path}"); then
|
||||||
|
[ -w "${vhost_full_path}" ] || error "File ${vhost_full_path} is not writable"
|
||||||
|
|
||||||
|
sed -i "s~^${search}~${replace}~" "${vhost_full_path}"
|
||||||
|
debug "Config in ${vhost_full_path} has been updated"
|
||||||
|
$(command -v apache2ctl) -t
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
sed_cert_path_for_nginx() {
|
||||||
|
local vhost=$1
|
||||||
|
local vhost_full_path="/etc/nginx/ssl/${vhost}.conf"
|
||||||
|
local cert_path=$2
|
||||||
|
|
||||||
|
[ ! -r "${vhost_full_path}" ] && return 0
|
||||||
|
|
||||||
|
local search="^ssl_certificate[^_].*$"
|
||||||
|
local replace="ssl_certificate ${cert_path};"
|
||||||
|
|
||||||
|
if ! $(grep -qE "${search}" "${vhost_full_path}"); then
|
||||||
|
[ -w "${vhost_full_path}" ] || error "File ${vhost_full_path} is not writable"
|
||||||
|
|
||||||
|
sed -i "s~${search}~${replace}~" "${vhost_full_path}"
|
||||||
|
debug "Config in ${vhost_full_path} has been updated"
|
||||||
|
$(command -v nginx) -t
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
x509_verify() {
|
||||||
|
local file="$1"
|
||||||
|
[ -r "$file" ] || error "File ${file} not found"
|
||||||
|
"${OPENSSL_BIN}" x509 -noout -modulus -in "$file" >/dev/null
|
||||||
|
}
|
||||||
|
x509_enddate() {
|
||||||
|
local file="$1"
|
||||||
|
[ -r "$file" ] || error "File ${file} not found"
|
||||||
|
"${OPENSSL_BIN}" x509 -noout -enddate -in "$file"
|
||||||
|
}
|
||||||
|
csr_verify() {
|
||||||
|
local file="$1"
|
||||||
|
[ -r "$file" ] || error "File ${file} not found"
|
||||||
|
"${OPENSSL_BIN}" req -noout -modulus -in "$file" >/dev/null
|
||||||
}
|
}
|
||||||
|
|
||||||
main() {
|
main() {
|
||||||
[ -f /etc/default/evoacme ] && . /etc/default/evoacme
|
# check arguments
|
||||||
[ -z "${SSL_KEY_DIR}" ] && SSL_KEY_DIR='/etc/ssl/private'
|
[ "$#" -eq 1 ] || error "invalid argument(s)"
|
||||||
[ -z "${CRT_DIR}" ] && CRT_DIR='/etc/letsencrypt'
|
|
||||||
[ -z "${CSR_DIR}" ] && CSR_DIR='/etc/ssl/requests'
|
|
||||||
[ -z "${SELF_SIGNED_DIR}" ] && SELF_SIGNED_DIR='/etc/ssl/self-signed'
|
|
||||||
[ -z "${DH_DIR}" ] && DH_DIR='/etc/ssl/dhparam'
|
|
||||||
[ -z "${LOG_DIR}" ] && LOG_DIR='/var/log/evoacme'
|
|
||||||
|
|
||||||
[ "$#" -ne 1 ] && usage && exit 1
|
[ "$1" = "-h" ] || [ "$1" = "--help" ] && usage && exit 0
|
||||||
|
|
||||||
vhost=$(basename "$1" .conf)
|
mkdir -p "${ACME_DIR}"
|
||||||
|
chown acme: "${ACME_DIR}"
|
||||||
|
[ -w "${ACME_DIR}" ] || error "Directory ${ACME_DIR} is not writable"
|
||||||
|
|
||||||
# Check master status for evoadmin-cluster
|
[ -d "${CSR_DIR}" ] || error "Directory ${CSR_DIR} is not found"
|
||||||
if [ -f "/home/${vhost}/state" ]; then
|
|
||||||
grep -q "STATE=master" "/home/${vhost}/state" || exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
SSL_EMAIL=$(grep emailAddress "${CRT_DIR}/openssl.cnf"|cut -d'=' -f2|xargs)
|
mkdir -p "${CRT_DIR}"
|
||||||
if [ -n "$SSL_EMAIL" ]; then
|
chown acme: "${CRT_DIR}"
|
||||||
emailopt="-m $SSL_EMAIL"
|
[ -w "${CRT_DIR}" ] || error "Directory ${CRT_DIR} is not writable"
|
||||||
else
|
|
||||||
emailopt="--register-unsafely-without-email"
|
|
||||||
fi
|
|
||||||
DATE=$(date "+%Y%m%d")
|
|
||||||
|
|
||||||
if [ -h "$CRT_DIR/${vhost}/live" ]; then
|
mkdir -p "${LOG_DIR}"
|
||||||
crt_end_date=$(openssl x509 -noout -enddate -in "$CRT_DIR/${vhost}/live/cert.crt"|sed -e "s/.*=//")
|
chown acme: "${LOG_DIR}"
|
||||||
date_crt=$(date -ud "$crt_end_date" +"%s")
|
[ -w "${LOG_DIR}" ] || error "Directory ${LOG_DIR} is not writable"
|
||||||
|
|
||||||
|
mkdir -p "${HOOKS_DIR}"
|
||||||
|
chown acme: "${HOOKS_DIR}"
|
||||||
|
[ -d "${HOOKS_DIR}" ] || error "Directory ${HOOKS_DIR} is not found"
|
||||||
|
|
||||||
|
readonly VHOST=$(basename "$1" .conf)
|
||||||
|
|
||||||
|
# check for important programs
|
||||||
|
readonly OPENSSL_BIN=$(command -v openssl) || error "openssl command not installed"
|
||||||
|
readonly CERTBOT_BIN=$(command -v certbot) || error "certbot command not installed"
|
||||||
|
|
||||||
|
# double check for directories
|
||||||
|
[ -d "${ACME_DIR}" ] || error "${ACME_DIR} is not a directory"
|
||||||
|
[ -d "${CSR_DIR}" ] || error "${CSR_DIR} is not a directory"
|
||||||
|
[ -d "${LOG_DIR}" ] || error "${LOG_DIR} is not a directory"
|
||||||
|
|
||||||
|
#### CSR VALIDATION
|
||||||
|
|
||||||
|
# verify .csr file
|
||||||
|
readonly CSR_FILE="${CSR_DIR}/${VHOST}.csr"
|
||||||
|
debug "Using CSR file: ${CSR_FILE}"
|
||||||
|
[ -f "${CSR_FILE}" ] || error "${CSR_FILE} absent"
|
||||||
|
[ -r "${CSR_FILE}" ] || error "${CSR_FILE} is not readable"
|
||||||
|
|
||||||
|
csr_verify "${CSR_FILE}" || error "${CSR_FILE} is invalid"
|
||||||
|
|
||||||
|
# Hook for evoadmin-web in cluster mode : check master status
|
||||||
|
local evoadmin_state_file="/home/${VHOST}/state"
|
||||||
|
[ -r "${evoadmin_state_file}" ] \
|
||||||
|
&& grep -q "STATE=slave" "${evoadmin_state_file}" \
|
||||||
|
&& debug "We are slave of this evoadmin cluster. Quit!" \
|
||||||
|
&& exit 0
|
||||||
|
|
||||||
|
#### INIT OR RENEW?
|
||||||
|
|
||||||
|
readonly LIVE_DIR="${CRT_DIR}/${VHOST}/live"
|
||||||
|
readonly LIVE_CERT="${LIVE_DIR}/cert.crt"
|
||||||
|
readonly LIVE_FULLCHAIN="${LIVE_DIR}/fullchain.pem"
|
||||||
|
readonly LIVE_CHAIN="${LIVE_DIR}/chain.pem"
|
||||||
|
|
||||||
|
# If live symlink already exists, it's not our first time...
|
||||||
|
if [ -h "${LIVE_DIR}" ]; then
|
||||||
|
# we have a live symlink
|
||||||
|
# let's see if there is a cert to renew
|
||||||
|
x509_verify "${LIVE_CERT}" || error "${LIVE_CERT} is invalid"
|
||||||
|
|
||||||
|
# Verify if our certificate will expire
|
||||||
|
crt_end_date=$(x509_enddate "${LIVE_CERT}" | cut -d= -f2)
|
||||||
|
date_renew=$(date -ud "${crt_end_date} - ${SSL_MINDAY} days" +"%s")
|
||||||
date_today=$(date +'%s')
|
date_today=$(date +'%s')
|
||||||
date_diff=$(((date_crt - date_today) / (60*60*24)))
|
if [ "${date_today}" -lt "${date_renew}" ]; then
|
||||||
[ "$date_diff" -ge "$SSL_MINDAY" ] && exit 0
|
debug "Cert ${LIVE_CERT} expires at ${crt_end_date} => more than ${SSL_MINDAY} days: kthxbye."
|
||||||
|
exit 0
|
||||||
fi
|
fi
|
||||||
rm -rf "$CRT_DIR/${vhost}/${DATE}"
|
fi
|
||||||
mkdir -pm 755 "$CRT_DIR/${vhost}/${DATE}"
|
|
||||||
chown -R acme: "$CRT_DIR/${vhost}"
|
#### CERTIFICATE CREATION WITH CERTBOT
|
||||||
sudo -u acme certbot certonly --quiet --webroot --csr "$CSR_DIR/${vhost}.csr" --webroot-path "$ACME_DIR" -n --agree-tos --cert-path="$CRT_DIR/${vhost}/${DATE}/cert.crt" --fullchain-path="$CRT_DIR/${vhost}/${DATE}/fullchain.pem" --chain-path="$CRT_DIR/${vhost}/${DATE}/chain.pem" "$emailopt" --logs-dir "$LOG_DIR" 2>&1 | grep -v "certbot.crypto_util"
|
|
||||||
if [ -f "$CRT_DIR/${vhost}/${DATE}/fullchain.pem" ]; then
|
local iteration=$(date "+%Y%m%d%H%M%S")
|
||||||
rm -f "$CRT_DIR/${vhost}/live"
|
[ -n "${iteration}" ] || error "invalid iteration (${iteration})"
|
||||||
ln -s "$CRT_DIR/${vhost}/${DATE}" "$CRT_DIR/${vhost}/live"
|
|
||||||
which apache2ctl >/dev/null && mkconf_apache
|
readonly NEW_DIR="${CRT_DIR}/${VHOST}/${iteration}"
|
||||||
which nginx >/dev/null && mkconf_nginx
|
|
||||||
which haproxy >/dev/null && mkconf_haproxy
|
[ -d "${NEW_DIR}" ] && error "${NEW_DIR} directory already exists, remove it manually."
|
||||||
|
mkdir -p "${NEW_DIR}"
|
||||||
|
chmod -R 0700 "${CRT_DIR}"
|
||||||
|
chown -R acme: "${CRT_DIR}"
|
||||||
|
debug "New cert will be created in ${NEW_DIR}"
|
||||||
|
|
||||||
|
readonly NEW_CERT="${NEW_DIR}/cert.crt"
|
||||||
|
readonly NEW_FULLCHAIN="${NEW_DIR}/fullchain.pem"
|
||||||
|
readonly NEW_CHAIN="${NEW_DIR}/chain.pem"
|
||||||
|
|
||||||
|
local CERTBOT_MODE=""
|
||||||
|
[ "${TEST}" = "1" ] && CERTBOT_MODE="${CERTBOT_MODE} --test-cert"
|
||||||
|
[ "${QUIET}" = "1" ] && CERTBOT_MODE="${CERTBOT_MODE} --quiet"
|
||||||
|
[ "${DRY_RUN}" = "1" ] && CERTBOT_MODE="${CERTBOT_MODE} --dry-run"
|
||||||
|
|
||||||
|
local CERTBOT_REGISTRATION="--agree-tos"
|
||||||
|
if [ -n "${SSL_EMAIL}" ]; then
|
||||||
|
debug "Registering at certbot with ${SSL_EMAIL} as email"
|
||||||
|
CERTBOT_REGISTRATION="${CERTBOT_REGISTRATION} -m ${SSL_EMAIL}"
|
||||||
else
|
else
|
||||||
rmdir "$CRT_DIR/${vhost}/${DATE}"
|
debug "Registering at certbot without email"
|
||||||
|
CERTBOT_REGISTRATION="${CERTBOT_REGISTRATION} --register-unsafely-without-email"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Permissions checks for acme user
|
||||||
|
sudo -u acme test -r "${CSR_FILE}" || error "File ${CSR_FILE} is not readable by user 'acme'"
|
||||||
|
sudo -u acme test -w "${NEW_DIR}" || error "Directory ${NEW_DIR} is not writable by user 'acme'"
|
||||||
|
|
||||||
|
# create a certificate with certbot
|
||||||
|
sudo -u acme \
|
||||||
|
"${CERTBOT_BIN}" \
|
||||||
|
certonly \
|
||||||
|
${CERTBOT_MODE} \
|
||||||
|
${CERTBOT_REGISTRATION} \
|
||||||
|
--non-interactive \
|
||||||
|
--webroot \
|
||||||
|
--csr "${CSR_FILE}" \
|
||||||
|
--webroot-path "${ACME_DIR}" \
|
||||||
|
--cert-path "${NEW_CERT}" \
|
||||||
|
--fullchain-path "${NEW_FULLCHAIN}" \
|
||||||
|
--chain-path "${NEW_CHAIN}" \
|
||||||
|
--logs-dir "$LOG_DIR" \
|
||||||
|
2>&1 \
|
||||||
|
| grep -v "certbot.crypto_util"
|
||||||
|
|
||||||
|
if [ "${DRY_RUN}" = "1" ]; then
|
||||||
|
debug "In dry-run mode, we stop here. Bye"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# verify if all is right
|
||||||
|
x509_verify "${NEW_CERT}" || error "${NEW_CERT} is invalid"
|
||||||
|
x509_verify "${NEW_FULLCHAIN}" || error "${NEW_FULLCHAIN} is invalid"
|
||||||
|
x509_verify "${NEW_CHAIN}" || error "${NEW_CHAIN} is invalid"
|
||||||
|
|
||||||
|
log "New certificate available at ${NEW_CERT}"
|
||||||
|
|
||||||
|
#### CERTIFICATE ACTIVATION
|
||||||
|
|
||||||
|
# link dance
|
||||||
|
if [ -h "${LIVE_DIR}" ]; then
|
||||||
|
rm "${LIVE_DIR}"
|
||||||
|
debug "Remove ${LIVE_DIR} link"
|
||||||
|
fi
|
||||||
|
ln -s "${NEW_DIR}" "${LIVE_DIR}"
|
||||||
|
debug "Link ${NEW_DIR} to ${LIVE_DIR}"
|
||||||
|
# verify final path
|
||||||
|
x509_verify "${LIVE_CERT}" || error "${LIVE_CERT} is invalid"
|
||||||
|
|
||||||
|
# update Apache
|
||||||
|
sed_cert_path_for_apache "${VHOST}" "${LIVE_FULLCHAIN}"
|
||||||
|
# update Nginx
|
||||||
|
sed_cert_path_for_nginx "${VHOST}" "${LIVE_FULLCHAIN}"
|
||||||
|
|
||||||
|
#### EXECUTE HOOKS
|
||||||
|
#
|
||||||
|
# executable scripts placed in ${HOOKS_DIR}
|
||||||
|
# are executed, unless their name ends with ".disabled"
|
||||||
|
|
||||||
|
export EVOACME_VHOST_NAME="${VHOST}"
|
||||||
|
export EVOACME_CERT="${LIVE_CERT}"
|
||||||
|
export EVOACME_CHAIN="${LIVE_CHAIN}"
|
||||||
|
export EVOACME_FULLCHAIN="${LIVE_FULLCHAIN}"
|
||||||
|
|
||||||
|
# search for files in hooks directory
|
||||||
|
for hook in $(find ${HOOKS_DIR} -type f); do
|
||||||
|
# keep only executables files, not containing a "."
|
||||||
|
if [ -x "${hook}" ] && (basename "${hook}" | grep -vqF "."); then
|
||||||
|
debug "Executing ${hook}"
|
||||||
|
${hook}
|
||||||
|
fi
|
||||||
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
main "$@"
|
readonly PROGNAME=$(basename "$0")
|
||||||
|
readonly PROGDIR=$(realpath -m $(dirname "$0"))
|
||||||
|
readonly ARGS=$@
|
||||||
|
|
||||||
|
readonly VERBOSE=${VERBOSE:-"0"}
|
||||||
|
readonly QUIET=${QUIET:-"0"}
|
||||||
|
readonly TEST=${TEST:-"0"}
|
||||||
|
readonly DRY_RUN=${DRY_RUN:-"0"}
|
||||||
|
|
||||||
|
# Read configuration file, if it exists
|
||||||
|
[ -r /etc/default/evoacme ] && . /etc/default/evoacme
|
||||||
|
|
||||||
|
# Default value for main variables
|
||||||
|
readonly SSL_KEY_DIR=${SSL_KEY_DIR:-"/etc/ssl/private"}
|
||||||
|
readonly ACME_DIR=${ACME_DIR:-"/var/lib/letsencrypt"}
|
||||||
|
readonly CSR_DIR=${CSR_DIR:-"/etc/ssl/requests"}
|
||||||
|
readonly CRT_DIR=${CRT_DIR:-"/etc/letsencrypt"}
|
||||||
|
readonly LOG_DIR=${LOG_DIR:-"/var/log/evoacme"}
|
||||||
|
readonly HOOKS_DIR=${HOOKS_DIR:-"${CRT_DIR}/hooks"}
|
||||||
|
readonly SSL_MINDAY=${SSL_MINDAY:-"30"}
|
||||||
|
readonly SSL_EMAIL=${SSL_EMAIL:-""}
|
||||||
|
|
||||||
|
main ${ARGS}
|
||||||
|
|
28
evoacme/files/hooks/reload_apache
Executable file
28
evoacme/files/hooks/reload_apache
Executable file
|
@ -0,0 +1,28 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
readonly PROGNAME=$(basename "$0")
|
||||||
|
readonly ARGS=$@
|
||||||
|
|
||||||
|
readonly VERBOSE=${VERBOSE:-"0"}
|
||||||
|
readonly QUIET=${QUIET:-"0"}
|
||||||
|
|
||||||
|
error() {
|
||||||
|
>&2 echo "${PROGNAME}: $1"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
debug() {
|
||||||
|
if [ "${VERBOSE}" = "1" ] && [ "${QUIET}" != "1" ]; then
|
||||||
|
>&2 echo "${PROGNAME}: $1"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ -n "$(pidof apache2)" ]; then
|
||||||
|
if $($(command -v apache2ctl) -t 2> /dev/null); then
|
||||||
|
debug "Apache detected... reloading"
|
||||||
|
service apache2 reload
|
||||||
|
else
|
||||||
|
error " Apache config is broken, you must fix it !"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
debug "Apache is not running. Skip."
|
||||||
|
fi
|
32
evoacme/files/hooks/reload_dovecot
Executable file
32
evoacme/files/hooks/reload_dovecot
Executable file
|
@ -0,0 +1,32 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
readonly PROGNAME=$(basename "$0")
|
||||||
|
readonly ARGS=$@
|
||||||
|
|
||||||
|
readonly VERBOSE=${VERBOSE:-"0"}
|
||||||
|
readonly QUIET=${QUIET:-"0"}
|
||||||
|
|
||||||
|
error() {
|
||||||
|
>&2 echo "${PROGNAME}: $1"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
debug() {
|
||||||
|
if [ "${VERBOSE}" = "1" ] && [ "${QUIET}" != "1" ]; then
|
||||||
|
>&2 echo "${PROGNAME}: $1"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ -n "$(pidof dovecot)" ]; then
|
||||||
|
if $($(command -v doveconf) > /dev/null); then
|
||||||
|
if $($(command -v doveconf)|grep -E "^ssl_cert[^_]"|grep -q "letsencrypt"); then
|
||||||
|
debug "Dovecot detected... reloading"
|
||||||
|
service dovecot reload
|
||||||
|
else
|
||||||
|
debug "Dovecot doesn't use Let's Encrypt certificate. Skip."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
error "Dovecot config is broken, you must fix it !"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
debug "Dovecot is not running. Skip."
|
||||||
|
fi
|
28
evoacme/files/hooks/reload_nginx
Executable file
28
evoacme/files/hooks/reload_nginx
Executable file
|
@ -0,0 +1,28 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
readonly PROGNAME=$(basename "$0")
|
||||||
|
readonly ARGS=$@
|
||||||
|
|
||||||
|
readonly VERBOSE=${VERBOSE:-"0"}
|
||||||
|
readonly QUIET=${QUIET:-"0"}
|
||||||
|
|
||||||
|
error() {
|
||||||
|
>&2 echo "${PROGNAME}: $1"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
debug() {
|
||||||
|
if [ "${VERBOSE}" = "1" ] && [ "${QUIET}" != "1" ]; then
|
||||||
|
>&2 echo "${PROGNAME}: $1"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ -n "$(pidof nginx)" ]; then
|
||||||
|
if $($(command -v nginx) -t 2> /dev/null); then
|
||||||
|
debug "Nginx detected... reloading"
|
||||||
|
service nginx reload
|
||||||
|
else
|
||||||
|
error "Nginx config is broken, you must fix it !"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
debug "Nginx is not running. Skip."
|
||||||
|
fi
|
32
evoacme/files/hooks/reload_postfix
Executable file
32
evoacme/files/hooks/reload_postfix
Executable file
|
@ -0,0 +1,32 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
readonly PROGNAME=$(basename "$0")
|
||||||
|
readonly ARGS=$@
|
||||||
|
|
||||||
|
readonly VERBOSE=${VERBOSE:-"0"}
|
||||||
|
readonly QUIET=${QUIET:-"0"}
|
||||||
|
|
||||||
|
error() {
|
||||||
|
>&2 echo "${PROGNAME}: $1"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
debug() {
|
||||||
|
if [ "${VERBOSE}" = "1" ] && [ "${QUIET}" != "1" ]; then
|
||||||
|
>&2 echo "${PROGNAME}: $1"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ -n "$(pidof master)" ]; then
|
||||||
|
if $($(command -v postconf) > /dev/null); then
|
||||||
|
if $($(command -v postconf)|grep -E "^smtpd_tls_cert_file"|grep -q "letsencrypt"); then
|
||||||
|
debug "Postfix detected... reloading"
|
||||||
|
service postfix reload
|
||||||
|
else
|
||||||
|
debug "Postfix doesn't use Let's Encrypt certificate. Skip."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
error "Postfix config is broken, you must fix it !"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
debug "Postfix is not running. Skip."
|
||||||
|
fi
|
|
@ -1,4 +1,4 @@
|
||||||
#!/bin/sh
|
#!/bin/bash
|
||||||
#
|
#
|
||||||
# make-csr is a shell script designed to automatically generate a
|
# make-csr is a shell script designed to automatically generate a
|
||||||
# certificate signing request (CSR) from an Apache or a Nginx vhost
|
# certificate signing request (CSR) from an Apache or a Nginx vhost
|
||||||
|
@ -7,145 +7,242 @@
|
||||||
# Licence: AGPLv3
|
# Licence: AGPLv3
|
||||||
#
|
#
|
||||||
|
|
||||||
get_domains() {
|
set -u
|
||||||
echo "$vhostfile"|grep -q nginx
|
|
||||||
if [ "$?" -eq 0 ]; then
|
|
||||||
domains=$(grep -oE "^( )*[^#]+" "$vhostfile" |grep -oE "[^\$]server_name.*;$"|sed 's/server_name//'|tr -d ';'|sed 's/\s\{1,\}//'|sed 's/\s\{1,\}/\n/g'|sort|uniq)
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "$vhostfile" |grep -q apache2
|
usage() {
|
||||||
if [ "$?" -eq 0 ]; then
|
cat <<EOT
|
||||||
domains=$(grep -oE "^( )*[^#]+" "$vhostfile" |grep -oE "(ServerName|ServerAlias).*"|sed 's/ServerName//'|sed 's/ServerAlias//'|sed 's/\s\{1,\}//'|sort|uniq)
|
Usage: ${PROGNAME} VHOST DOMAIN...
|
||||||
fi
|
VHOST must correspond to an Apache or Nginx enabled VHost
|
||||||
valid_domains=""
|
If VHOST ends with ".conf" it is stripped,
|
||||||
nb=0
|
then files are seached at those paths:
|
||||||
|
- /etc/apache2/sites-enables/VHOST.conf
|
||||||
|
- /etc/nginx/sites-enabled/VHOST.conf
|
||||||
|
- /etc/nginx/sites-enabled/VHOST
|
||||||
|
DOMAIN... is a list of domains for the CSR (passed as arguments or input)
|
||||||
|
|
||||||
echo "Valid(s) domain(s) in $vhost :"
|
If env variable VERBOSE=1, debug messages are sent to stderr
|
||||||
for domain in $domains; do
|
EOT
|
||||||
real_ip=$(dig +short "$domain"|grep -oE "([0-9]+\.){3}[0-9]+")
|
}
|
||||||
for ip in $(echo "$SRV_IP"|xargs -n1); do
|
debug() {
|
||||||
if [ "${ip}" = "${real_ip}" ]; then
|
if [ "${VERBOSE}" = 1 ]; then
|
||||||
valid_domains="$valid_domains $domain"
|
>&2 echo "${PROGNAME}: $1"
|
||||||
nb=$(( nb + 1 ))
|
|
||||||
echo "* $domain -> $real_ip"
|
|
||||||
fi
|
fi
|
||||||
done
|
}
|
||||||
done
|
error() {
|
||||||
|
>&2 echo "${PROGNAME}: $1"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
if [ "$nb" -eq 0 ]; then
|
default_key_size() {
|
||||||
nb=$(echo "$domains"|wc -l)
|
grep default_bits "${SSL_CONFIG_FILE}" | cut -d'=' -f2 | xargs
|
||||||
echo "* No valid domain found"
|
}
|
||||||
echo "All following(s) domain(s) will be used for CSR creation :"
|
|
||||||
for domain in $domains; do
|
sed_selfsigned_cert_path_for_apache() {
|
||||||
echo "* $domain"
|
local apache_ssl_vhost_path="$1"
|
||||||
done
|
|
||||||
|
mkdir -p $(dirname "${apache_ssl_vhost_path}")
|
||||||
|
if [ ! -f "${apache_ssl_vhost_path}" ]; then
|
||||||
|
cat > "${apache_ssl_vhost_path}" <<EOF
|
||||||
|
SSLEngine On
|
||||||
|
SSLCertificateFile ${SELF_SIGNED_FILE}
|
||||||
|
SSLCertificateKeyFile ${SSL_KEY_FILE}
|
||||||
|
EOF
|
||||||
|
debug "SSL config added in ${apache_ssl_vhost_path}"
|
||||||
else
|
else
|
||||||
domains="$valid_domains"
|
local search="^SSLCertificateFile.*$"
|
||||||
|
local replace="SSLCertificateFile ${SELF_SIGNED_FILE}"
|
||||||
|
|
||||||
|
sed -i "s~${search}~${replace}~" "${apache_ssl_vhost_path}"
|
||||||
|
debug "SSL config updated in ${apache_ssl_vhost_path}"
|
||||||
fi
|
fi
|
||||||
domains=$(echo "$domains"|xargs -n1)
|
}
|
||||||
|
|
||||||
|
sed_selfsigned_cert_path_for_nginx() {
|
||||||
|
local nginx_ssl_vhost_path="$1"
|
||||||
|
|
||||||
|
mkdir -p $(dirname "${nginx_ssl_vhost_path}")
|
||||||
|
if [ ! -f "${nginx_ssl_vhost_path}" ]; then
|
||||||
|
cat > "${nginx_ssl_vhost_path}" <<EOF
|
||||||
|
ssl_certificate ${SELF_SIGNED_FILE};
|
||||||
|
ssl_certificate_key ${SSL_KEY_FILE};
|
||||||
|
EOF
|
||||||
|
debug "SSL config added in ${nginx_ssl_vhost_path}"
|
||||||
|
else
|
||||||
|
local search="^ssl_certificate[^_].*$"
|
||||||
|
local replace="ssl_certificate ${SELF_SIGNED_FILE};"
|
||||||
|
|
||||||
|
sed -i "s~${search}~${replace}~" "${nginx_ssl_vhost_path}"
|
||||||
|
debug "SSL config updated in ${nginx_ssl_vhost_path}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
openssl_selfsigned() {
|
||||||
|
local csr="$1"
|
||||||
|
local key="$2"
|
||||||
|
local crt="$3"
|
||||||
|
local crt_dir=$(dirname ${crt})
|
||||||
|
|
||||||
|
[ -r "${csr}" ] || error "File ${csr} is not readable"
|
||||||
|
[ -r "${key}" ] || error "File ${key} is not readable"
|
||||||
|
[ -w "${crt_dir}" ] || error "Directory ${crt_dir} is not writable"
|
||||||
|
|
||||||
|
"${OPENSSL_BIN}" x509 -req -sha256 -days 365 -in "${csr}" -signkey "${key}" -out "${crt}" 2> /dev/null
|
||||||
|
|
||||||
|
[ -r "${crt}" ] || error "Something went wrong, ${crt} has not been generated"
|
||||||
|
}
|
||||||
|
openssl_key(){
|
||||||
|
local key="$1"
|
||||||
|
local key_dir=$(dirname "${key}")
|
||||||
|
local size="$2"
|
||||||
|
|
||||||
|
[ -w "${key_dir}" ] || error "Directory ${key_dir} is not writable"
|
||||||
|
|
||||||
|
"${OPENSSL_BIN}" genrsa -out "${key}" "${size}" 2> /dev/null
|
||||||
|
|
||||||
|
[ -r "${key}" ] || error "Something went wrong, ${key} has not been generated"
|
||||||
|
}
|
||||||
|
openssl_csr() {
|
||||||
|
local csr="$1"
|
||||||
|
local csr_dir=$(dirname "${csr}")
|
||||||
|
local key="$2"
|
||||||
|
local cfg="$3"
|
||||||
|
|
||||||
|
[ -w "${csr_dir}" ] || error "Directory ${csr_dir} is not writable"
|
||||||
|
|
||||||
|
if $(grep -q "DNS:" "${cfg}"); then
|
||||||
|
# CSR with SAN
|
||||||
|
"${OPENSSL_BIN}" req -new -sha256 -key "${key}" -reqexts SAN -config "${cfg}" -out "${csr}"
|
||||||
|
else
|
||||||
|
# Single domain CSR
|
||||||
|
"${OPENSSL_BIN}" req -new -sha256 -key "${key}" -config "${cfg}" -out "${csr}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
[ -r "${csr}" ] || error "Something went wrong, ${csr} has not been generated"
|
||||||
}
|
}
|
||||||
|
|
||||||
make_key() {
|
make_key() {
|
||||||
openssl genrsa -out "$SSL_KEY_DIR/${vhost}.key" "$SSL_KEY_SIZE" 2>/dev/null
|
local key="$1"
|
||||||
chown root: "$SSL_KEY_DIR/${vhost}.key"
|
local size="$2"
|
||||||
chmod 600 "$SSL_KEY_DIR/${vhost}.key"
|
|
||||||
|
openssl_key "${key}" "${size}"
|
||||||
|
debug "Private key stored at ${key}"
|
||||||
|
|
||||||
|
chown root: "${key}"
|
||||||
|
chmod 600 "${key}"
|
||||||
}
|
}
|
||||||
|
|
||||||
make_csr() {
|
make_csr() {
|
||||||
domains="$1"
|
local domains=$@
|
||||||
nb=$(echo "$domains"|wc -l)
|
local nb=$#
|
||||||
config_file="/tmp/make-csr-${vhost}.conf"
|
local config_file="/tmp/make-csr-${VHOST}.conf"
|
||||||
|
local san=""
|
||||||
|
|
||||||
mkdir -p "$CSR_DIR" -m 0755
|
mkdir -p -m 0755 "${CSR_DIR}" || error "Unable to mkdir ${CSR_DIR}"
|
||||||
|
|
||||||
if [ "$nb" -eq 1 ]; then
|
if [ "${nb}" -eq 1 ]; then
|
||||||
cat /etc/letsencrypt/openssl.cnf - > "$config_file" <<EOF
|
cat "${SSL_CONFIG_FILE}" - > "${config_file}" <<EOF
|
||||||
CN=$domains
|
CN=$domains
|
||||||
EOF
|
EOF
|
||||||
openssl req -new -sha256 -key "$SSL_KEY_DIR/${vhost}.key" -config "$config_file" -out "$CSR_DIR/${vhost}.csr"
|
elif [ "${nb}" -gt 1 ]; then
|
||||||
elif [ "$nb" -gt 1 ]; then
|
for domain in ${domains}; do
|
||||||
san=''
|
san="${san},DNS:${domain}"
|
||||||
for domain in $domains
|
|
||||||
do
|
|
||||||
san="$san,DNS:$domain"
|
|
||||||
done
|
done
|
||||||
san=$(echo "$san"|sed 's/,//')
|
san=$(echo "${san}" | sed 's/^,//')
|
||||||
cat /etc/letsencrypt/openssl.cnf - > "$config_file" <<EOF
|
cat "${SSL_CONFIG_FILE}" - > "${config_file}" <<EOF
|
||||||
[SAN]
|
[SAN]
|
||||||
subjectAltName=$san
|
subjectAltName=${san}
|
||||||
EOF
|
EOF
|
||||||
openssl req -new -sha256 -key "$SSL_KEY_DIR/${vhost}.key" -reqexts SAN -config "$config_file" > "$CSR_DIR/${vhost}.csr"
|
|
||||||
fi
|
fi
|
||||||
|
openssl_csr "${CSR_FILE}" "${SSL_KEY_FILE}" "${config_file}"
|
||||||
|
debug "CSR stored at ${CSR_FILE}"
|
||||||
|
|
||||||
if [ -f "$CSR_DIR/${vhost}.csr" ]; then
|
if [ -r "${CSR_FILE}" ]; then
|
||||||
chmod 644 "$CSR_DIR/${vhost}.csr"
|
chmod 644 "${CSR_FILE}"
|
||||||
mkdir -p "$SELF_SIGNED_DIR" -m 0755
|
mkdir -p -m 0755 "${SELF_SIGNED_DIR}"
|
||||||
openssl x509 -req -sha256 -days 365 -in "$CSR_DIR/${vhost}.csr" -signkey "$SSL_KEY_DIR/${vhost}.key" -out "$SELF_SIGNED_DIR/${vhost}.pem"
|
|
||||||
[ -f "$SELF_SIGNED_DIR/${vhost}.pem" ] && chmod 644 "$SELF_SIGNED_DIR/${vhost}.pem"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
mkconf_apache() {
|
openssl_selfsigned "${CSR_FILE}" "${SSL_KEY_FILE}" "${SELF_SIGNED_FILE}"
|
||||||
mkdir -p /etc/apache2/ssl
|
|
||||||
if [ ! -f "/etc/apache2/ssl/${vhost}.conf" ]; then
|
|
||||||
cat > "/etc/apache2/ssl/${vhost}.conf" <<EOF
|
|
||||||
SSLEngine On
|
|
||||||
SSLCertificateFile $SELF_SIGNED_DIR/${vhost}.pem
|
|
||||||
SSLCertificateKeyFile $SSL_KEY_DIR/${vhost}.key
|
|
||||||
EOF
|
|
||||||
else
|
|
||||||
sed -i "s~^SSLCertificateFile.*$~SSLCertificateFile $SELF_SIGNED_DIR/${vhost}.pem~" "/etc/apache2/ssl/${vhost}.conf"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
mkconf_nginx() {
|
[ -r "${SELF_SIGNED_FILE}" ] && chmod 644 "${SELF_SIGNED_FILE}"
|
||||||
mkdir -p /etc/nginx/ssl
|
debug "Self-signed certificate stored at ${SELF_SIGNED_FILE}"
|
||||||
if [ ! -f "/etc/nginx/ssl/${vhost}.conf" ]; then
|
|
||||||
cat > "/etc/nginx/ssl/${vhost}.conf" <<EOF
|
|
||||||
ssl_certificate $SELF_SIGNED_DIR/${vhost}.pem;
|
|
||||||
ssl_certificate_key $SSL_KEY_DIR/${vhost}.key;
|
|
||||||
EOF
|
|
||||||
else
|
|
||||||
sed -i "s~^ssl_certificate[^_].*$~ssl_certificate $SELF_SIGNED_DIR/${vhost}.pem;~" "/etc/nginx/ssl/${vhost}.conf"
|
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
main() {
|
main() {
|
||||||
if [ "$#" -ne 1 ]; then
|
if [ -t 0 ]; then
|
||||||
echo "You need to provide one argument !" >&2
|
# We have STDIN, so we should have at least 2 arguments
|
||||||
|
if [ "$#" -lt 2 ]; then
|
||||||
|
>&2 echo "invalid arguments"
|
||||||
|
>&2 usage
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
vhost=$(basename "$1" .conf)
|
# read VHOST from first argument
|
||||||
local_ip=$(ip a|grep brd|cut -d'/' -f1|grep -oE "([0-9]+\.){3}[0-9]+")
|
VHOST="$1"
|
||||||
|
# remove the first argument
|
||||||
[ -f /etc/default/evoacme ] && . /etc/default/evoacme
|
shift
|
||||||
[ -z "${SSL_KEY_DIR}" ] && SSL_KEY_DIR='/etc/ssl/private'
|
# read domains from remaining arguments
|
||||||
[ -z "${CSR_DIR}" ] && CSR_DIR='/etc/ssl/requests'
|
DOMAINS=$@
|
||||||
[ -z "${CRT_DIR}" ] && CRT_DIR='/etc/letsencrypt'
|
else
|
||||||
[ -z "${SELF_SIGNED_DIR}" ] && SELF_SIGNED_DIR='/etc/ssl/self-signed'
|
# We don't have STDIN, so we should have only 1 argument
|
||||||
SSL_KEY_SIZE=$(grep default_bits /etc/letsencrypt/openssl.cnf|cut -d'=' -f2|xargs)
|
if [ "$#" != 1 ]; then
|
||||||
[ -n "${SRV_IP}" ] && SRV_IP="${SRV_IP} $local_ip" || SRV_IP="$local_ip"
|
>&2 echo "invalid arguments"
|
||||||
|
>&2 usage
|
||||||
vhostfile=$(ls "/etc/nginx/sites-enabled/${vhost}" "/etc/nginx/sites-enabled/${vhost}.conf" "/etc/apache2/sites-enabled/${vhost}" "/etc/apache2/sites-enabled/${vhost}.conf" 2>/dev/null|head -n1)
|
|
||||||
|
|
||||||
if [ ! -h "$vhostfile" ]; then
|
|
||||||
echo "$vhost is not a valid virtualhost !" >&2
|
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
# read VHOST from first argument
|
||||||
if [ -f "$SSL_KEY_DIR/${vhost}.key" ]; then
|
VHOST="$1"
|
||||||
echo "$vhost key already exist, overwrite it ? (y)"
|
# read domains from input
|
||||||
read REPLY
|
DOMAINS=
|
||||||
[ "$REPLY" = "Y" ] || [ "$REPLY" = "y" ] || exit 0
|
while read -r line ; do
|
||||||
rm -f "/etc/apache2/ssl/${vhost}.conf /etc/nginx/ssl/${vhost}.conf"
|
DOMAINS="${DOMAINS} ${line}"
|
||||||
[ -h "${CRT_DIR}/${vhost}/live" ] && rm "${CRT_DIR}/${vhost}/live"
|
done
|
||||||
|
# trim the string to remove leading/trailing spaces
|
||||||
|
DOMAINS=$(echo "${DOMAINS}" | xargs)
|
||||||
fi
|
fi
|
||||||
|
readonly VHOST
|
||||||
|
readonly DOMAINS
|
||||||
|
|
||||||
get_domains
|
mkdir -p "${CSR_DIR}"
|
||||||
make_key
|
chown root: "${CSR_DIR}"
|
||||||
make_csr "$domains"
|
[ -w "${CSR_DIR}" ] || error "Directory ${CSR_DIR} is not writable"
|
||||||
which apache2ctl >/dev/null && mkconf_apache
|
|
||||||
which nginx >/dev/null && mkconf_nginx
|
mkdir -p "${SELF_SIGNED_DIR}"
|
||||||
|
chown root: "${SELF_SIGNED_DIR}"
|
||||||
|
[ -w "${SELF_SIGNED_DIR}" ] || error "Directory ${SELF_SIGNED_DIR} is not writable"
|
||||||
|
|
||||||
|
mkdir -p "${SSL_KEY_DIR}"
|
||||||
|
chown root: "${SSL_KEY_DIR}"
|
||||||
|
[ -w "${SSL_KEY_DIR}" ] || error "Directory ${SSL_KEY_DIR} is not writable"
|
||||||
|
|
||||||
|
[ -r "${SSL_CONFIG_FILE}" ] || error "File ${SSL_CONFIG_FILE} is not readable"
|
||||||
|
|
||||||
|
# check for important programs
|
||||||
|
readonly OPENSSL_BIN=$(command -v openssl) || error "openssl command not installed"
|
||||||
|
|
||||||
|
readonly SELF_SIGNED_FILE="${SELF_SIGNED_DIR}/${VHOST}.pem"
|
||||||
|
readonly SSL_KEY_FILE="${SSL_KEY_DIR}/${VHOST}.key"
|
||||||
|
readonly CSR_FILE="${CSR_DIR}/${VHOST}.csr"
|
||||||
|
|
||||||
|
make_key "${SSL_KEY_FILE}" "${SSL_KEY_SIZE}"
|
||||||
|
make_csr ${DOMAINS}
|
||||||
|
|
||||||
|
command -v apache2ctl >/dev/null && sed_selfsigned_cert_path_for_apache "/etc/apache2/ssl/${VHOST}.conf"
|
||||||
|
command -v nginx >/dev/null && sed_selfsigned_cert_path_for_nginx "/etc/nginx/ssl/${VHOST}.conf"
|
||||||
}
|
}
|
||||||
|
|
||||||
main "$@"
|
readonly PROGNAME=$(basename "$0")
|
||||||
|
readonly PROGDIR=$(realpath -m $(dirname "$0"))
|
||||||
|
readonly ARGS=$@
|
||||||
|
|
||||||
|
readonly VERBOSE=${VERBOSE:-"0"}
|
||||||
|
|
||||||
|
# Read configuration file, if it exists
|
||||||
|
[ -r /etc/default/evoacme ] && . /etc/default/evoacme
|
||||||
|
|
||||||
|
# Default value for main variables
|
||||||
|
readonly CSR_DIR=${CSR_DIR:-'/etc/ssl/requests'}
|
||||||
|
readonly SSL_CONFIG_FILE=${SSL_CONFIG_FILE:-"/etc/letsencrypt/openssl.cnf"}
|
||||||
|
readonly SELF_SIGNED_DIR=${SELF_SIGNED_DIR:-'/etc/ssl/self-signed'}
|
||||||
|
readonly SSL_KEY_DIR=${SSL_KEY_DIR:-'/etc/ssl/private'}
|
||||||
|
readonly SSL_KEY_SIZE=${SSL_KEY_SIZE:-$(default_key_size)}
|
||||||
|
|
||||||
|
main ${ARGS}
|
||||||
|
|
153
evoacme/files/vhost-domains.sh
Executable file
153
evoacme/files/vhost-domains.sh
Executable file
|
@ -0,0 +1,153 @@
|
||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# make-csr is a shell script designed to automatically generate a
|
||||||
|
# certificate signing request (CSR) from an Apache or a Nginx vhost
|
||||||
|
#
|
||||||
|
# Author: Victor Laborie <vlaborie@evolix.fr>
|
||||||
|
# Licence: AGPLv3
|
||||||
|
#
|
||||||
|
|
||||||
|
set -u
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<EOT
|
||||||
|
Usage: ${PROGNAME} VHOST
|
||||||
|
VHOST must correspond to an Apache or Nginx enabled VHost
|
||||||
|
If VHOST ends with ".conf" it is stripped,
|
||||||
|
then files are seached at those paths:
|
||||||
|
- /etc/apache2/sites-enables/VHOST.conf
|
||||||
|
- /etc/nginx/sites-enabled/VHOST.conf
|
||||||
|
- /etc/nginx/sites-enabled/VHOST
|
||||||
|
|
||||||
|
If env variable VERBOSE=1, debug messages are sent to stderr
|
||||||
|
EOT
|
||||||
|
}
|
||||||
|
|
||||||
|
debug() {
|
||||||
|
if [ "${VERBOSE}" = 1 ]; then
|
||||||
|
>&2 echo "${PROGNAME}: $1"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
error() {
|
||||||
|
>&2 echo "${PROGNAME}: $1"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
real_ip_for_domain() {
|
||||||
|
dig +short "$1" | grep -oE "([0-9]+\.){3}[0-9]+"
|
||||||
|
}
|
||||||
|
local_ip() {
|
||||||
|
ip a | grep brd | cut -d'/' -f1 | grep -oE "([0-9]+\.){3}[0-9]+"
|
||||||
|
}
|
||||||
|
|
||||||
|
nginx_domains() {
|
||||||
|
local vhost_file="$1"
|
||||||
|
|
||||||
|
grep -oE "^( )*[^#]+" "${vhost_file}" \
|
||||||
|
| grep -oE "[^\$]server_name.*;$" \
|
||||||
|
| sed 's/server_name//' \
|
||||||
|
| tr -d ';' \
|
||||||
|
| sed 's/\s\{1,\}//' \
|
||||||
|
| sed 's/\s\{1,\}/\n/g' \
|
||||||
|
| sort \
|
||||||
|
| uniq
|
||||||
|
}
|
||||||
|
|
||||||
|
apache_domains() {
|
||||||
|
local vhost_file="$1"
|
||||||
|
|
||||||
|
grep -oE "^( )*[^#]+" "${vhost_file}" \
|
||||||
|
| grep -oE "(ServerName|ServerAlias).*" \
|
||||||
|
| sed 's/ServerName//' \
|
||||||
|
| sed 's/ServerAlias//' \
|
||||||
|
| sed 's/\s\{1,\}//' \
|
||||||
|
| sort \
|
||||||
|
| uniq
|
||||||
|
}
|
||||||
|
|
||||||
|
get_domains() {
|
||||||
|
local vhost_file="$1"
|
||||||
|
local ips="$2"
|
||||||
|
local domains=""
|
||||||
|
local valid_domains=""
|
||||||
|
local nb=0
|
||||||
|
|
||||||
|
if $(echo "${vhost_file}" | grep -q nginx); then
|
||||||
|
debug "Nginx vhost file used"
|
||||||
|
domains=$(nginx_domains "${vhost_file}")
|
||||||
|
fi
|
||||||
|
if $(echo "${vhost_file}" | grep -q apache2); then
|
||||||
|
debug "Apache vhost file used"
|
||||||
|
domains=$(apache_domains "${vhost_file}")
|
||||||
|
fi
|
||||||
|
|
||||||
|
debug "Valid(s) domain(s) in ${vhost_file} :"
|
||||||
|
for domain in ${domains}; do
|
||||||
|
real_ip=$(real_ip_for_domain "${domain}")
|
||||||
|
for ip in $(echo "${ips}" | xargs -n1); do
|
||||||
|
if [ "${ip}" = "${real_ip}" ]; then
|
||||||
|
valid_domains="${valid_domains} ${domain}"
|
||||||
|
nb=$(( nb + 1 ))
|
||||||
|
debug "* ${domain} -> ${real_ip}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "${nb}" -eq 0 ]; then
|
||||||
|
nb=$(echo "${domains}" | wc -l)
|
||||||
|
debug "* No valid domain found"
|
||||||
|
debug "All following(s) domain(s) will be used for CSR creation :"
|
||||||
|
for domain in ${domains}; do
|
||||||
|
debug "* ${domain}"
|
||||||
|
done
|
||||||
|
else
|
||||||
|
domains="${valid_domains}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "${domains}" | xargs -n 1
|
||||||
|
}
|
||||||
|
|
||||||
|
first_vhost_file_found() {
|
||||||
|
local vhost_name="$1"
|
||||||
|
|
||||||
|
ls "/etc/nginx/sites-enabled/${vhost_name}" \
|
||||||
|
"/etc/nginx/sites-enabled/${vhost_name}.conf" \
|
||||||
|
"/etc/apache2/sites-enabled/${vhost_name}.conf" \
|
||||||
|
2>/dev/null \
|
||||||
|
| head -n 1
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
if [ "$#" != 1 ]; then
|
||||||
|
>&2 usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
|
||||||
|
usage
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
local vhost_name=$(basename "$1" .conf)
|
||||||
|
local vhost_file=$(first_vhost_file_found "${vhost_name}")
|
||||||
|
|
||||||
|
if [ ! -h "${vhost_file}" ]; then
|
||||||
|
>&2 echo "No virtualhost has been found for '${vhost_name}'."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
local ips=$(local_ip)
|
||||||
|
if [ -n "${SRV_IP}" ]; then
|
||||||
|
ips="${ips} ${SRV_IP}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
get_domains "${vhost_file}" "${ips}"
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly PROGNAME=$(basename "$0")
|
||||||
|
readonly PROGDIR=$(realpath -m $(dirname "$0"))
|
||||||
|
readonly ARGS=$@
|
||||||
|
|
||||||
|
readonly VERBOSE=${VERBOSE:-"0"}
|
||||||
|
readonly SRV_IP=${SRV_IP:-""}
|
||||||
|
|
||||||
|
main $ARGS
|
|
@ -22,6 +22,14 @@
|
||||||
group: acme
|
group: acme
|
||||||
state: directory
|
state: directory
|
||||||
|
|
||||||
|
- name: "Fix hooks directory permissions"
|
||||||
|
file:
|
||||||
|
path: "{{ evoacme_hooks_dir }}"
|
||||||
|
mode: "0700"
|
||||||
|
owner: acme
|
||||||
|
group: acme
|
||||||
|
state: directory
|
||||||
|
|
||||||
- name: Fix log dir's right
|
- name: Fix log dir's right
|
||||||
file:
|
file:
|
||||||
path: "{{ evoacme_log_dir }}"
|
path: "{{ evoacme_log_dir }}"
|
||||||
|
|
|
@ -20,28 +20,26 @@
|
||||||
name: certbot
|
name: certbot
|
||||||
state: latest
|
state: latest
|
||||||
|
|
||||||
- name: Check if /usr is a partition
|
- include_role:
|
||||||
shell: "mount | grep 'on /usr type'"
|
name: remount-usr
|
||||||
args:
|
|
||||||
warn: no
|
|
||||||
changed_when: False
|
|
||||||
failed_when: False
|
|
||||||
check_mode: no
|
|
||||||
|
|
||||||
register: usr_partition
|
|
||||||
|
|
||||||
- name: Mount /usr in rw
|
|
||||||
command: mount -o remount,rw /usr
|
|
||||||
args:
|
|
||||||
warn: no
|
|
||||||
changed_when: False
|
|
||||||
when: usr_partition.rc == 0
|
|
||||||
|
|
||||||
- name: Remove certbot symlink for apt install
|
- name: Remove certbot symlink for apt install
|
||||||
file:
|
file:
|
||||||
path: /usr/local/bin/certbot
|
path: /usr/local/bin/certbot
|
||||||
state: absent
|
state: absent
|
||||||
|
|
||||||
|
- name: stat /etc/cron.d/certbot
|
||||||
|
stat:
|
||||||
|
path: /etc/cron.d/certbot
|
||||||
|
register: etc_cron_d_certbot
|
||||||
|
|
||||||
|
- name: Rename certbot dpkg cron to .disabled
|
||||||
|
copy:
|
||||||
|
remote_src: True
|
||||||
|
src: /etc/cron.d/certbot
|
||||||
|
dest: /etc/cron.d/certbot.disabled
|
||||||
|
when: etc_cron_d_certbot.stat.exists
|
||||||
|
|
||||||
- name: Remove certbot dpkg cron
|
- name: Remove certbot dpkg cron
|
||||||
file:
|
file:
|
||||||
path: /etc/cron.d/certbot
|
path: /etc/cron.d/certbot
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
- ini_file:
|
- ini_file:
|
||||||
dest: /etc/letsencrypt/openssl.cnf
|
dest: "{{ evoacme_crt_dir }}/openssl.cnf"
|
||||||
section: 'req'
|
section: 'req'
|
||||||
option: "{{ item.name }}"
|
option: "{{ item.name }}"
|
||||||
value: "{{ item.var }}"
|
value: "{{ item.var }}"
|
||||||
|
|
14
evoacme/tasks/evoacme_hook.yml
Normal file
14
evoacme/tasks/evoacme_hook.yml
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
- name: "Search for {{ hook_name }} hook"
|
||||||
|
command: "find {{ evoacme_hooks_dir }} -type f \\( -name '{{ hook_name }}' -o -name '{{ hook_name }}.*' \\)"
|
||||||
|
check_mode: no
|
||||||
|
changed_when: False
|
||||||
|
register: _find_hook
|
||||||
|
|
||||||
|
- name: "Copy {{ hook_name }} hook if missing"
|
||||||
|
copy:
|
||||||
|
src: "hooks/{{ hook_name }}"
|
||||||
|
dest: "{{ evoacme_hooks_dir }}/{{ hook_name }}"
|
||||||
|
mode: "0750"
|
||||||
|
when: _find_hook.stdout == ""
|
|
@ -9,11 +9,30 @@
|
||||||
|
|
||||||
- include: acme.yml
|
- include: acme.yml
|
||||||
|
|
||||||
|
- include: evoacme_hook.yml
|
||||||
|
vars:
|
||||||
|
hook_name: "{{ item }}"
|
||||||
|
with_items:
|
||||||
|
- reload_apache
|
||||||
|
- reload_nginx
|
||||||
|
- reload_dovecot
|
||||||
|
- reload_postfix
|
||||||
|
|
||||||
- include: conf.yml
|
- include: conf.yml
|
||||||
|
|
||||||
- include: scripts.yml
|
- include: scripts.yml
|
||||||
|
|
||||||
- include: webserver.yml
|
- name: Determine Apache presence
|
||||||
|
stat:
|
||||||
|
path: /etc/apache2/apache2.conf
|
||||||
|
check_mode: no
|
||||||
|
register: sta
|
||||||
|
|
||||||
|
- name: Determine Nginx presence
|
||||||
|
stat:
|
||||||
|
path: /etc/nginx/nginx.conf
|
||||||
|
check_mode: no
|
||||||
|
register: stn
|
||||||
|
|
||||||
- include: apache.yml
|
- include: apache.yml
|
||||||
when: sta.stat.isreg is defined and sta.stat.isreg
|
when: sta.stat.isreg is defined and sta.stat.isreg
|
||||||
|
|
|
@ -9,15 +9,23 @@
|
||||||
|
|
||||||
- name: Copy make-csr.sh script
|
- name: Copy make-csr.sh script
|
||||||
copy:
|
copy:
|
||||||
src: files/make-csr.sh
|
src: make-csr.sh
|
||||||
dest: /usr/local/sbin/make-csr
|
dest: /usr/local/sbin/make-csr
|
||||||
owner: root
|
owner: root
|
||||||
group: root
|
group: root
|
||||||
mode: "0755"
|
mode: "0755"
|
||||||
|
|
||||||
|
- name: Copy vhost-domains.sh script
|
||||||
|
copy:
|
||||||
|
src: vhost-domains.sh
|
||||||
|
dest: /usr/local/sbin/vhost-domains
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "0755"
|
||||||
|
|
||||||
- name: Copy evoacme script
|
- name: Copy evoacme script
|
||||||
copy:
|
copy:
|
||||||
src: files/evoacme.sh
|
src: evoacme.sh
|
||||||
dest: /usr/local/sbin/evoacme
|
dest: /usr/local/sbin/evoacme
|
||||||
owner: root
|
owner: root
|
||||||
group: root
|
group: root
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
---
|
|
||||||
- name: Determine Nginx presence
|
|
||||||
stat:
|
|
||||||
path: /etc/nginx/nginx.conf
|
|
||||||
check_mode: no
|
|
||||||
register: stn
|
|
||||||
|
|
||||||
- name: Determine Apache presence
|
|
||||||
stat:
|
|
||||||
path: /etc/apache2/apache2.conf
|
|
||||||
check_mode: no
|
|
||||||
register: sta
|
|
|
@ -1,5 +1,9 @@
|
||||||
location ~ /.well-known/acme-challenge {
|
location ~ /.well-known/acme-challenge {
|
||||||
|
{% if ansible_distribution_major_version > 8 %}
|
||||||
|
alias {{ evoacme_acme_dir }}/;
|
||||||
|
{% else %}
|
||||||
alias {{ evoacme_acme_dir }}/.well-known/acme-challenge;
|
alias {{ evoacme_acme_dir }}/.well-known/acme-challenge;
|
||||||
|
{% endif %}
|
||||||
try_files $uri =404;
|
try_files $uri =404;
|
||||||
allow all;
|
allow all;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
---
|
---
|
||||||
- include: remount_usr_rw.yml
|
- include_role:
|
||||||
|
name: remount-usr
|
||||||
when: evocheck_bin_dir | search ("/usr")
|
when: evocheck_bin_dir | search ("/usr")
|
||||||
|
|
||||||
- name: Scripts dir is present
|
- name: Scripts dir is present
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
---
|
|
||||||
- name: Get mount options for partitions
|
|
||||||
shell: "mount | grep 'on /usr type'"
|
|
||||||
args:
|
|
||||||
warn: no
|
|
||||||
register: mount
|
|
||||||
changed_when: False
|
|
||||||
failed_when: False
|
|
||||||
when: not ansible_check_mode
|
|
||||||
|
|
||||||
- name: Remount /usr if it is a partition and it is not mounted in rw
|
|
||||||
command: "mount -o remount,rw /usr"
|
|
||||||
when: mount.rc == 0 and not mount.stdout_lines.0 | search("rw")
|
|
||||||
args:
|
|
||||||
warn: no
|
|
|
@ -36,6 +36,7 @@ Main variables are:
|
||||||
* `evolinux_additional_packages`: optional additional packages to install (default: `[]`)
|
* `evolinux_additional_packages`: optional additional packages to install (default: `[]`)
|
||||||
* `evolinux_postfix_purge_exim`: purge Exim packages (default: `True`) ;
|
* `evolinux_postfix_purge_exim`: purge Exim packages (default: `True`) ;
|
||||||
* `evolinux_ssh_password_auth_addresses`: list of addresses that can authenticate with a password (default: `[]`)
|
* `evolinux_ssh_password_auth_addresses`: list of addresses that can authenticate with a password (default: `[]`)
|
||||||
* `evolinux_ssh_disable_root`: disable SSH access for root (default: `True`)
|
* `evolinux_ssh_disable_root`: disable SSH access for root (default: `False`)
|
||||||
|
* `evolinux_ssh_allow_current_user`: don't lock yourself out (default: `False`)
|
||||||
|
|
||||||
The full list of variables (with default values) can be found in `defaults/main.yml`.
|
The full list of variables (with default values) can be found in `defaults/main.yml`.
|
||||||
|
|
|
@ -10,6 +10,21 @@ logcheck_alert_email: Null
|
||||||
raid_alert_email: Null
|
raid_alert_email: Null
|
||||||
postfix_alias_email: Null
|
postfix_alias_email: Null
|
||||||
|
|
||||||
|
# apt
|
||||||
|
|
||||||
|
evolinux_apt_include: True
|
||||||
|
|
||||||
|
evolinux_apt_conf: True
|
||||||
|
evolinux_apt_hooks: True
|
||||||
|
evolinux_apt_replace_default_sources: True
|
||||||
|
evolinux_apt_public_sources: True
|
||||||
|
evolinux_apt_upgrade: True
|
||||||
|
evolinux_apt_remove_aptitude: True
|
||||||
|
|
||||||
|
# etc-git
|
||||||
|
|
||||||
|
evolinux_etcgit_include: True
|
||||||
|
|
||||||
# hostname
|
# hostname
|
||||||
|
|
||||||
evolinux_hostname_include: True
|
evolinux_hostname_include: True
|
||||||
|
@ -31,17 +46,6 @@ evolinux_kernel_disable_tcp_timestamps: True
|
||||||
evolinux_kernel_reduce_swapiness: True
|
evolinux_kernel_reduce_swapiness: True
|
||||||
evolinux_kernel_cve20165696: True
|
evolinux_kernel_cve20165696: True
|
||||||
|
|
||||||
# apt
|
|
||||||
|
|
||||||
evolinux_apt_include: True
|
|
||||||
|
|
||||||
evolinux_apt_conf: True
|
|
||||||
evolinux_apt_hooks: True
|
|
||||||
evolinux_apt_replace_default_sources: True
|
|
||||||
evolinux_apt_public_sources: True
|
|
||||||
evolinux_apt_upgrade: True
|
|
||||||
evolinux_apt_remove_aptitude: True
|
|
||||||
|
|
||||||
# fstab
|
# fstab
|
||||||
|
|
||||||
evolinux_fstab_include: True
|
evolinux_fstab_include: True
|
||||||
|
@ -96,6 +100,27 @@ evolinux_system_alert5_init: True
|
||||||
evolinux_system_alert5_enable: True
|
evolinux_system_alert5_enable: True
|
||||||
evolinux_system_eni_auto: True
|
evolinux_system_eni_auto: True
|
||||||
|
|
||||||
|
# evomaintenance
|
||||||
|
|
||||||
|
evolinux_evomaintenance_include: True
|
||||||
|
|
||||||
|
# ssh
|
||||||
|
|
||||||
|
evolinux_ssh_include: True
|
||||||
|
|
||||||
|
evolix_trusted_ips: []
|
||||||
|
additional_trusted_ips: []
|
||||||
|
# Let's merge evolix_trusted_ips with additional_trusted_ips
|
||||||
|
evolinux_ssh_password_auth_addresses: "{{ evolix_trusted_ips | union(additional_trusted_ips) | unique }}"
|
||||||
|
evolinux_ssh_match_address: True
|
||||||
|
evolinux_ssh_disable_acceptenv: True
|
||||||
|
evolinux_ssh_allow_current_user: False
|
||||||
|
|
||||||
|
### disabled because of a memory leak
|
||||||
|
# # evolinux users
|
||||||
|
#
|
||||||
|
# evolinux_users_include: True
|
||||||
|
|
||||||
# root
|
# root
|
||||||
|
|
||||||
evolinux_root_include: True
|
evolinux_root_include: True
|
||||||
|
@ -108,15 +133,7 @@ evolinux_root_gitconfig: True
|
||||||
evolinux_root_bash_history_appendonly: True
|
evolinux_root_bash_history_appendonly: True
|
||||||
evolinux_root_vim_default: True
|
evolinux_root_vim_default: True
|
||||||
evolinux_root_vim_conf: True
|
evolinux_root_vim_conf: True
|
||||||
|
evolinux_root_disable_ssh: False
|
||||||
# ssh
|
|
||||||
|
|
||||||
evolinux_ssh_include: True
|
|
||||||
|
|
||||||
evolinux_ssh_password_auth_addresses: []
|
|
||||||
evolinux_ssh_match_address: True
|
|
||||||
evolinux_ssh_disable_root: True
|
|
||||||
evolinux_ssh_disable_acceptenv: True
|
|
||||||
|
|
||||||
# postfix
|
# postfix
|
||||||
|
|
||||||
|
@ -152,3 +169,31 @@ evolinux_hardware_include: True
|
||||||
|
|
||||||
evolinux_provider_online_include: False
|
evolinux_provider_online_include: False
|
||||||
evolinux_provider_orange_fce_include: False
|
evolinux_provider_orange_fce_include: False
|
||||||
|
|
||||||
|
# log2mail
|
||||||
|
|
||||||
|
evolinux_log2mail_include: True
|
||||||
|
|
||||||
|
# Minifirewall
|
||||||
|
|
||||||
|
evolinux_minifirewall_include: True
|
||||||
|
|
||||||
|
# Munin
|
||||||
|
|
||||||
|
evolinux_munin_include: True
|
||||||
|
|
||||||
|
# Nagios/NRPE
|
||||||
|
|
||||||
|
evolinux_nagios_nrpe_include: True
|
||||||
|
|
||||||
|
# fail2ban
|
||||||
|
|
||||||
|
evolinux_fail2ban_include: True
|
||||||
|
|
||||||
|
# Listupgrade
|
||||||
|
|
||||||
|
evolinux_listupgrade_include: True
|
||||||
|
|
||||||
|
# Generate ldif
|
||||||
|
|
||||||
|
evolinux_generateldif_include: True
|
||||||
|
|
9
evolinux-base/files/alert5.service
Normal file
9
evolinux-base/files/alert5.service
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
[Unit]
|
||||||
|
Description=Evolix alert5 script
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=/usr/share/scripts/alert5.sh
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
31
evolinux-base/files/hwraid.le-vert.net.gpg.key
Normal file
31
evolinux-base/files/hwraid.le-vert.net.gpg.key
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
Version: GnuPG v1.4.12 (GNU/Linux)
|
||||||
|
|
||||||
|
mQENBFHwGLoBCADGXHFostxbz4UzGFYtmox4pvyN1gMhq2KCuQ6f+FESa4HTd9L6
|
||||||
|
XVhXWPCad3cdxBIls+41+AdZTWxWMu7DUdy8nMU1Ikfw6JeHcSx97G5BdxBVMjK4
|
||||||
|
iMGfPdLfDgWf4BQ2h0dnTEWobt31WaqgNiNjNrKktqbymmF94pwYkwL53ydIA4zl
|
||||||
|
8ZQRZooFigkS9WdoKjh30Pv/SWakILSLcSQFHK0dvSkeGd1NxT9dMNPAXXqLom4+
|
||||||
|
7kCc0s04sS+0DwW16b0Hpb46mtsR9kzOnrE/Smj24uOGzNZen0oCc2Y7bfZlyaN+
|
||||||
|
RlTkWEze7lemc4Byup/QWkhT0Er8F8uxexy5ABEBAAG0PEhXUmFpZCAoaHR0cDov
|
||||||
|
L2h3cmFpZC5sZS12ZXJ0Lm5ldCkgPHJvb3RAaHdyYWlkLmxlLXZlcnQubmV0PokB
|
||||||
|
OAQTAQIAIgUCUfAYugIbAwYLCQgHAwIGFQgCCQoLBBYCAwECHgECF4AACgkQYAUh
|
||||||
|
DiOz07Rc4Af+N3dEZZHzLNVTjQ0+fCyeg8/flWOkR8DhP10cyoJhSHFTZRdXVshn
|
||||||
|
kP4VmmUycVeURh76DmrIRe/9Oyca6aGXccRMqvq+HMgBPVwD5qNhcJPIuzqEvmlO
|
||||||
|
6UIeW2ydil/v1pWu740fGntyFRQcsfqjReVPXw9K588F7MDMyL+31vLm6aorLSzR
|
||||||
|
hvLhOmGisTs0wg2Oz9f4muauRy6cpQPw/Zi/P/F4WkQYscbHrSbhszj6OIg/vftR
|
||||||
|
UbZ7QB26/+40B0ag4JzLpmj3scFxf/WdUl5LXazqhsbkurk7huV41BNKXi1+BS3c
|
||||||
|
x6pFzWEHpiuG1j7U/nScGzEQpsMlUW9D+rkBDQRR8Bi6AQgAuhH1H0VLwcROI/5n
|
||||||
|
9yTxSbTIZbyhUan3raAbit3pgo0zLagfUtp3vULVnm5ISqQcYFGLZoE1MUkmjGOL
|
||||||
|
38W0lsIiZTaKOKXxBbLlPhhrvlXnNWAG/S1wnq7K+DV179KCTkUzaLRDbHvv999j
|
||||||
|
9odBRtAkiTnCfHTMCN4AhydEejNxtlzJo4E5FecH4reimLI5euUdTltgCjixrbsa
|
||||||
|
KbQftYpSMdXnLy2+00QZoXu0U/h4WZcMhOSEEiyGP9BY6m5G76n03HIeQ6eALDFu
|
||||||
|
ryAgO+SB9rBrm/VN0kR/TZq0iA3uzLHC7zCw2aImipkr+rIuJOku0wH9MyowBbia
|
||||||
|
bQtnCQARAQABiQEfBBgBAgAJBQJR8Bi6AhsMAAoJEGAFIQ4js9O0d5YH/3fNQgsC
|
||||||
|
LvD0g2wdoksv5bG9CUOi9Bs0JHqI0LhXmPvMsbDojZ+zZle7KWNfK2227mWhmoG1
|
||||||
|
WLujJSmTtxhEO1fXIdYjlDfk2uLJKuFi2wQX9n8dFDUmKY3CUJgeVZof1uQ/5C3D
|
||||||
|
O06CcuOtf2d/+iijuW112aV1q1hoQqw71ojTET0iIV6lD/0i1eEBSSe1Ohb9yTGR
|
||||||
|
VxTVrB78zU9hih4/Oq8wJT/Fv25aO1MDSc26CXAg0JA6IWvKal3BSPNhtz4L4FIg
|
||||||
|
lXleArf9oJqxDO3TsV5zcLyxsIuRuxyP0+AKdSQUqv0dFi4Jf79OmvOmgwydhHjY
|
||||||
|
+f7quLbwiiDmPbU=
|
||||||
|
=Yv6D
|
||||||
|
-----END PGP PUBLIC KEY BLOCK-----
|
|
@ -12,6 +12,7 @@ galaxy_info:
|
||||||
- name: Debian
|
- name: Debian
|
||||||
versions:
|
versions:
|
||||||
- jessie
|
- jessie
|
||||||
|
- stretch
|
||||||
|
|
||||||
dependencies: []
|
dependencies: []
|
||||||
# List your role dependencies here, one per line.
|
# List your role dependencies here, one per line.
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
replace: '\1{{ evolinux_fstab_home_options | mandatory }}\3'
|
replace: '\1{{ evolinux_fstab_home_options | mandatory }}\3'
|
||||||
notify: remount /home
|
notify: remount /home
|
||||||
when:
|
when:
|
||||||
- "' /home ' in fstab_content.stdout"
|
- fstab_content.stdout | regex_search('\s/home\s')
|
||||||
- evolinux_fstab_home
|
- evolinux_fstab_home
|
||||||
|
|
||||||
- name: /tmp partition is customized
|
- name: /tmp partition is customized
|
||||||
|
@ -25,7 +25,7 @@
|
||||||
regexp: '([^#]\s+/tmp\s+\S+\s+)([a-z,]+)(\s+)'
|
regexp: '([^#]\s+/tmp\s+\S+\s+)([a-z,]+)(\s+)'
|
||||||
replace: '\1{{ evolinux_fstab_tmp_options | mandatory }}\3'
|
replace: '\1{{ evolinux_fstab_tmp_options | mandatory }}\3'
|
||||||
when:
|
when:
|
||||||
- "' /tmp ' in fstab_content.stdout"
|
- fstab_content.stdout | regex_search('\s/tmp\s')
|
||||||
- evolinux_fstab_tmp
|
- evolinux_fstab_tmp
|
||||||
|
|
||||||
- name: /usr partition is customized
|
- name: /usr partition is customized
|
||||||
|
@ -34,7 +34,7 @@
|
||||||
regexp: '([^#]\s+/usr\s+\S+\s+)([a-z,]+)(\s+)'
|
regexp: '([^#]\s+/usr\s+\S+\s+)([a-z,]+)(\s+)'
|
||||||
replace: '\1{{ evolinux_fstab_usr_options | mandatory }}\3'
|
replace: '\1{{ evolinux_fstab_usr_options | mandatory }}\3'
|
||||||
when:
|
when:
|
||||||
- "' /usr ' in fstab_content.stdout"
|
- fstab_content.stdout | regex_search('\s/usr\s')
|
||||||
- evolinux_fstab_usr
|
- evolinux_fstab_usr
|
||||||
|
|
||||||
- name: /var partition is customized
|
- name: /var partition is customized
|
||||||
|
@ -44,7 +44,7 @@
|
||||||
replace: '\1{{ evolinux_fstab_var_options | mandatory }}\3'
|
replace: '\1{{ evolinux_fstab_var_options | mandatory }}\3'
|
||||||
notify: remount /var
|
notify: remount /var
|
||||||
when:
|
when:
|
||||||
- "' /var ' in fstab_content.stdout"
|
- fstab_content.stdout | regex_search('\s/var\s')
|
||||||
- evolinux_fstab_var
|
- evolinux_fstab_var
|
||||||
|
|
||||||
- name: /var/tmp is created
|
- name: /var/tmp is created
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
- name: Check if Broadcom NetXtreme II device is present
|
- name: Check if Broadcom NetXtreme II device is present
|
||||||
shell: "lspci | grep -q 'NetXtreme II'"
|
shell: "lspci | grep -q 'NetXtreme II'"
|
||||||
check_mode: no
|
check_mode: no
|
||||||
register: broadcom
|
register: broadcom_netextreme_search
|
||||||
failed_when: False
|
failed_when: False
|
||||||
changed_when: False
|
changed_when: False
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@
|
||||||
tasks_from: basics.yml
|
tasks_from: basics.yml
|
||||||
vars:
|
vars:
|
||||||
apt_basics_components: "main contrib non-free"
|
apt_basics_components: "main contrib non-free"
|
||||||
when: broadcom|success
|
when: broadcom_netextreme_search.rc == 0
|
||||||
|
|
||||||
## RAID
|
## RAID
|
||||||
|
|
||||||
|
@ -53,6 +53,18 @@
|
||||||
when: "'Hewlett-Packard Company Smart Array' in raidmodel.stdout"
|
when: "'Hewlett-Packard Company Smart Array' in raidmodel.stdout"
|
||||||
|
|
||||||
- block:
|
- block:
|
||||||
|
- name: Add HW tool GPG key
|
||||||
|
apt_key:
|
||||||
|
# url: https://hwraid.le-vert.net/debian/hwraid.le-vert.net.gpg.key
|
||||||
|
data: "{{ lookup('file', 'hwraid.le-vert.net.gpg.key') }}"
|
||||||
|
when: ansible_distribution_release == "stretch"
|
||||||
|
|
||||||
|
- name: Add HW tool repository
|
||||||
|
apt_repository:
|
||||||
|
repo: 'deb http://hwraid.le-vert.net/debian stretch main'
|
||||||
|
state: present
|
||||||
|
when: ansible_distribution_release == "stretch"
|
||||||
|
|
||||||
- name: Install packages for DELL/LSI hardware
|
- name: Install packages for DELL/LSI hardware
|
||||||
apt:
|
apt:
|
||||||
name: "{{ item }}"
|
name: "{{ item }}"
|
||||||
|
|
|
@ -5,6 +5,19 @@
|
||||||
when:
|
when:
|
||||||
- ansible_distribution != "Debian" or ansible_distribution_major_version | version_compare('8', '<')
|
- ansible_distribution != "Debian" or ansible_distribution_major_version | version_compare('8', '<')
|
||||||
|
|
||||||
|
- name: Apt configuration
|
||||||
|
include_role:
|
||||||
|
name: apt
|
||||||
|
vars:
|
||||||
|
apt_install_basics: "{{ evolinux_apt_replace_default_sources }}"
|
||||||
|
apt_install_evolix_public: "{{ evolinux_apt_public_sources }}"
|
||||||
|
when: evolinux_apt_include
|
||||||
|
|
||||||
|
- name: /etc versioning with Git
|
||||||
|
include_role:
|
||||||
|
name: etc-git
|
||||||
|
when: evolinux_etcgit_include
|
||||||
|
|
||||||
- name: Hostname
|
- name: Hostname
|
||||||
include: hostname.yml
|
include: hostname.yml
|
||||||
when: evolinux_hostname_include
|
when: evolinux_hostname_include
|
||||||
|
@ -13,10 +26,6 @@
|
||||||
include: kernel.yml
|
include: kernel.yml
|
||||||
when: evolinux_kernel_include
|
when: evolinux_kernel_include
|
||||||
|
|
||||||
- name: Apt configuration and packages install
|
|
||||||
include: apt.yml
|
|
||||||
when: evolinux_apt_include
|
|
||||||
|
|
||||||
- name: Fstab configuration
|
- name: Fstab configuration
|
||||||
include: fstab.yml
|
include: fstab.yml
|
||||||
when: evolinux_fstab_include
|
when: evolinux_fstab_include
|
||||||
|
@ -29,14 +38,25 @@
|
||||||
include: system.yml
|
include: system.yml
|
||||||
when: evolinux_system_include
|
when: evolinux_system_include
|
||||||
|
|
||||||
- name: Root user configuration
|
- name: Evomaintenance
|
||||||
include: root.yml
|
include_role:
|
||||||
when: evolinux_root_include
|
name: evomaintenance
|
||||||
|
when: evolinux_evomaintenance_include
|
||||||
|
|
||||||
- name: SSH configuration
|
- name: SSH configuration
|
||||||
include: ssh.yml
|
include: ssh.yml
|
||||||
when: evolinux_ssh_include
|
when: evolinux_ssh_include
|
||||||
|
|
||||||
|
### disabled because of a memory leak
|
||||||
|
# - name: Create evolinux users
|
||||||
|
# include_role:
|
||||||
|
# name: evolinux-users
|
||||||
|
# when: evolinux_users_include
|
||||||
|
|
||||||
|
- name: Root user configuration
|
||||||
|
include: root.yml
|
||||||
|
when: evolinux_root_include
|
||||||
|
|
||||||
- name: Postfix
|
- name: Postfix
|
||||||
include: postfix.yml
|
include: postfix.yml
|
||||||
when: evolinux_postfix_include
|
when: evolinux_postfix_include
|
||||||
|
@ -63,4 +83,34 @@
|
||||||
|
|
||||||
- name: Override Logmail service
|
- name: Override Logmail service
|
||||||
include: log2mail.yml
|
include: log2mail.yml
|
||||||
when: evolinux_packages_serveur_base
|
when: evolinux_log2mail_include
|
||||||
|
|
||||||
|
- name: Minifirewall
|
||||||
|
include_role:
|
||||||
|
name: minifirewall
|
||||||
|
when: evolinux_minifirewall_include
|
||||||
|
|
||||||
|
- name: Munin
|
||||||
|
include_role:
|
||||||
|
name: munin
|
||||||
|
when: evolinux_munin_include
|
||||||
|
|
||||||
|
- name: Nagios/NRPE
|
||||||
|
include_role:
|
||||||
|
name: nagios-nrpe
|
||||||
|
when: evolinux_nagios_nrpe_include
|
||||||
|
|
||||||
|
- name: fail2ban
|
||||||
|
include_role:
|
||||||
|
name: fail2ban
|
||||||
|
when: evolinux_fail2ban_include
|
||||||
|
|
||||||
|
- name: Listupgrade
|
||||||
|
include_role:
|
||||||
|
name: listupgrade
|
||||||
|
when: evolinux_listupgrade_include
|
||||||
|
|
||||||
|
- name: Generate ldif script
|
||||||
|
include_role:
|
||||||
|
name: generate-ldif
|
||||||
|
when: evolinux_generateldif_include
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
- apg
|
- apg
|
||||||
- conntrack
|
- conntrack
|
||||||
- logrotate
|
- logrotate
|
||||||
|
- bash-completion
|
||||||
- ssl-cert
|
- ssl-cert
|
||||||
- ca-certificates
|
- ca-certificates
|
||||||
when: evolinux_packages_system
|
when: evolinux_packages_system
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
|
|
||||||
- name: packages are installed
|
- name: Postfix packages are installed
|
||||||
apt:
|
apt:
|
||||||
name: "{{ item }}"
|
name: "{{ item }}"
|
||||||
state: present
|
state: present
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
---
|
|
||||||
- name: Get mount options for partitions
|
|
||||||
shell: "mount | grep 'on /usr type'"
|
|
||||||
args:
|
|
||||||
warn: no
|
|
||||||
register: mount
|
|
||||||
changed_when: False
|
|
||||||
failed_when: False
|
|
||||||
when: not ansible_check_mode
|
|
||||||
|
|
||||||
- name: Remount /usr if it is a partition and it is not mounted in rw
|
|
||||||
command: "mount -o remount,rw /usr"
|
|
||||||
when: mount.rc == 0 and not mount.stdout_lines.0 | search("rw")
|
|
||||||
args:
|
|
||||||
warn: no
|
|
|
@ -80,4 +80,23 @@
|
||||||
- "set shiftwidth=4"
|
- "set shiftwidth=4"
|
||||||
when: evolinux_root_vim_conf
|
when: evolinux_root_vim_conf
|
||||||
|
|
||||||
|
- name: disable SSH access for root
|
||||||
|
replace:
|
||||||
|
dest: /etc/ssh/sshd_config
|
||||||
|
regexp: '^PermitRootLogin (yes|without-password|prohibit-password)'
|
||||||
|
replace: "PermitRootLogin no"
|
||||||
|
validate: '/usr/sbin/sshd -T -f %s'
|
||||||
|
notify: reload sshd
|
||||||
|
when: evolinux_root_disable_ssh
|
||||||
|
|
||||||
|
### Disabled : it seems useless and too dangerous for now
|
||||||
|
# - name: remove root from AllowUsers directive
|
||||||
|
# replace:
|
||||||
|
# dest: /etc/ssh/sshd_config
|
||||||
|
# regexp: '^(AllowUsers ((?!root(?:@\S+)?).)*)(\sroot(?:@\S+)?|root(?:@\S+)?\s)(.*)$'
|
||||||
|
# replace: '\1\4'
|
||||||
|
# validate: '/usr/sbin/sshd -T -f %s'
|
||||||
|
# notify: reload sshd
|
||||||
|
# when: evolinux_root_disable_ssh
|
||||||
|
|
||||||
- meta: flush_handlers
|
- meta: flush_handlers
|
||||||
|
|
|
@ -3,61 +3,45 @@
|
||||||
msg: "Warning: empty 'evolinux_ssh_password_auth_addresses' variable, tasks will be skipped!"
|
msg: "Warning: empty 'evolinux_ssh_password_auth_addresses' variable, tasks will be skipped!"
|
||||||
when: evolinux_ssh_password_auth_addresses == []
|
when: evolinux_ssh_password_auth_addresses == []
|
||||||
|
|
||||||
- name: Security directives for Evolinux
|
# From 'man sshd_config' :
|
||||||
|
# « If all of the criteria on the Match line are satisfied, the keywords
|
||||||
|
# on the following lines override those set in the global section of the config
|
||||||
|
# file, until either another Match line or the end of the file.
|
||||||
|
# If a keyword appears in multiple Match blocks that are satisfied,
|
||||||
|
# only the first instance of the keyword is applied. »
|
||||||
|
#
|
||||||
|
# We want to allow any user from a list of IP addresses to login with password,
|
||||||
|
# but users of the "evolix" group can't login with password from other IP addresses
|
||||||
|
|
||||||
|
- name: Security directives for Evolinux (Debian 9 or later)"
|
||||||
blockinfile:
|
blockinfile:
|
||||||
dest: /etc/ssh/sshd_config
|
dest: /etc/ssh/sshd_config
|
||||||
block: |
|
block: |
|
||||||
Match Group evolinux-sudo
|
|
||||||
PasswordAuthentication no
|
|
||||||
Match Address {{ evolinux_ssh_password_auth_addresses | join(',') }}
|
Match Address {{ evolinux_ssh_password_auth_addresses | join(',') }}
|
||||||
PasswordAuthentication yes
|
PasswordAuthentication yes
|
||||||
|
Match Group evolix
|
||||||
|
PasswordAuthentication no
|
||||||
marker: "# {mark} EVOLINUX PASSWORD RESTRICTIONS"
|
marker: "# {mark} EVOLINUX PASSWORD RESTRICTIONS"
|
||||||
insertafter: EOF
|
insertafter: EOF
|
||||||
validate: '/usr/sbin/sshd -T -f %s'
|
validate: '/usr/sbin/sshd -T -f %s'
|
||||||
notify: reload sshd
|
notify: reload sshd
|
||||||
when: not evolinux_ssh_password_auth_addresses == []
|
when:
|
||||||
|
- evolinux_ssh_password_auth_addresses != []
|
||||||
|
- ansible_distribution_major_version | version_compare('9', '>=')
|
||||||
|
|
||||||
# - name: verify Match Address directive
|
- name: Security directives for Evolinux (Jessie)
|
||||||
# command: "grep 'Match Address' /etc/ssh/sshd_config"
|
blockinfile:
|
||||||
# changed_when: False
|
|
||||||
# failed_when: False
|
|
||||||
# check_mode: no
|
|
||||||
# register: grep_matchaddress_ssh
|
|
||||||
#
|
|
||||||
# - name: Add Match Address sshd directive
|
|
||||||
# lineinfile:
|
|
||||||
# dest: /etc/ssh/sshd_config
|
|
||||||
# line: "\nMatch Address {{ evolinux_ssh_password_auth_addresses | join(',') }}\n PasswordAuthentication yes"
|
|
||||||
# insertafter: '# +ForceCommand cvs server'
|
|
||||||
# validate: '/usr/sbin/sshd -T -f %s'
|
|
||||||
# notify: reload sshd
|
|
||||||
# when: evolinux_ssh_match_address and grep_matchaddress_ssh.rc != 0 and evolinux_ssh_password_auth_addresses != []
|
|
||||||
#
|
|
||||||
# - name: Modify Match Address sshd directive
|
|
||||||
# replace:
|
|
||||||
# dest: /etc/ssh/sshd_config
|
|
||||||
# regexp: '^(Match Address ((?!{{ item }}).)*)$'
|
|
||||||
# replace: '\1,{{ item }}'
|
|
||||||
# validate: '/usr/sbin/sshd -T -f %s'
|
|
||||||
# with_items: "{{ evolinux_ssh_password_auth_addresses }}"
|
|
||||||
# notify: reload sshd
|
|
||||||
# when: evolinux_ssh_match_address and grep_matchaddress_ssh.rc == 0
|
|
||||||
#
|
|
||||||
# - name: Add Match Group sudo without password
|
|
||||||
# lineinfile:
|
|
||||||
# dest: /etc/ssh/sshd_config
|
|
||||||
# line: "\nMatch Group sudo\n PasswordAuthentication no"
|
|
||||||
# insertbefore: '^Match Address'
|
|
||||||
# validate: '/usr/sbin/sshd -T -f %s'
|
|
||||||
# notify: reload sshd
|
|
||||||
|
|
||||||
- name: disable SSH access for root
|
|
||||||
replace:
|
|
||||||
dest: /etc/ssh/sshd_config
|
dest: /etc/ssh/sshd_config
|
||||||
regexp: '^PermitRootLogin (yes|without-password)'
|
block: |
|
||||||
replace: "PermitRootLogin no"
|
Match Address {{ evolinux_ssh_password_auth_addresses | join(',') }}
|
||||||
|
PasswordAuthentication yes
|
||||||
|
marker: "# {mark} EVOLINUX PASSWORD RESTRICTIONS BY ADDRESS"
|
||||||
|
insertafter: EOF
|
||||||
|
validate: '/usr/sbin/sshd -T -f %s'
|
||||||
notify: reload sshd
|
notify: reload sshd
|
||||||
when: evolinux_ssh_disable_root
|
when:
|
||||||
|
- evolinux_ssh_password_auth_addresses != []
|
||||||
|
- ansible_distribution_release == "jessie"
|
||||||
|
|
||||||
# We disable AcceptEnv because it can be a security issue, but also because we
|
# We disable AcceptEnv because it can be a security issue, but also because we
|
||||||
# do not want clients to push their environment variables like LANG.
|
# do not want clients to push their environment variables like LANG.
|
||||||
|
@ -77,4 +61,38 @@
|
||||||
notify: reload sshd
|
notify: reload sshd
|
||||||
when: ansible_distribution_major_version | version_compare('9', '>=')
|
when: ansible_distribution_major_version | version_compare('9', '>=')
|
||||||
|
|
||||||
|
- name: "Get current user"
|
||||||
|
command: logname
|
||||||
|
register: logname
|
||||||
|
check_mode: no
|
||||||
|
changed_when: False
|
||||||
|
when: evolinux_ssh_allow_current_user
|
||||||
|
|
||||||
|
# we must double-escape caracters, because python
|
||||||
|
- name: verify AllowUsers directive
|
||||||
|
shell: "grep -E '^AllowUsers' /etc/ssh/sshd_config"
|
||||||
|
changed_when: False
|
||||||
|
failed_when: False
|
||||||
|
register: grep_allowusers_ssh
|
||||||
|
check_mode: no
|
||||||
|
when: evolinux_ssh_allow_current_user
|
||||||
|
|
||||||
|
- name: "Add AllowUsers sshd directive for current user"
|
||||||
|
lineinfile:
|
||||||
|
dest: /etc/ssh/sshd_config
|
||||||
|
line: "\nAllowUsers {{ logname.stdout }}"
|
||||||
|
insertafter: 'Subsystem'
|
||||||
|
validate: '/usr/sbin/sshd -T -f %s'
|
||||||
|
notify: reload sshd
|
||||||
|
when: evolinux_ssh_allow_current_user and grep_allowusers_ssh.rc != 0
|
||||||
|
|
||||||
|
- name: "Modify AllowUsers sshd directive for current user"
|
||||||
|
replace:
|
||||||
|
dest: /etc/ssh/sshd_config
|
||||||
|
regexp: '^(AllowUsers ((?!{{ logname.stdout }}).)*)$'
|
||||||
|
replace: '\1 {{ logname.stdout }}'
|
||||||
|
validate: '/usr/sbin/sshd -T -f %s'
|
||||||
|
notify: reload sshd
|
||||||
|
when: evolinux_ssh_allow_current_user and grep_allowusers_ssh.rc == 0
|
||||||
|
|
||||||
- meta: flush_handlers
|
- meta: flush_handlers
|
||||||
|
|
|
@ -33,7 +33,8 @@
|
||||||
# TODO : find a way to force the console-data configuration
|
# TODO : find a way to force the console-data configuration
|
||||||
# non-interactively (like tzdata ↑)
|
# non-interactively (like tzdata ↑)
|
||||||
|
|
||||||
- include: remount_usr_rw.yml
|
- include_role:
|
||||||
|
name: remount-usr
|
||||||
|
|
||||||
- name: Ensure automagic vim conf is disabled
|
- name: Ensure automagic vim conf is disabled
|
||||||
lineinfile:
|
lineinfile:
|
||||||
|
@ -59,7 +60,7 @@
|
||||||
- name: Set /etc/adduser.conf DIR_MODE to 0700
|
- name: Set /etc/adduser.conf DIR_MODE to 0700
|
||||||
replace:
|
replace:
|
||||||
dest: /etc/adduser.conf
|
dest: /etc/adduser.conf
|
||||||
regexp: "^DIR_MODE=.*$"
|
regexp: "^DIR_MODE=0755$"
|
||||||
replace: "DIR_MODE=0700"
|
replace: "DIR_MODE=0700"
|
||||||
when: evolinux_system_dirmode_adduser
|
when: evolinux_system_dirmode_adduser
|
||||||
|
|
||||||
|
@ -116,29 +117,56 @@
|
||||||
|
|
||||||
## alert5
|
## alert5
|
||||||
|
|
||||||
- name: Install alert5 init script
|
- name: Install alert5 init script (jessie/stretch)
|
||||||
template:
|
template:
|
||||||
src: system/init_alert5.j2
|
src: system/alert5.sysvinit.j2
|
||||||
dest: /etc/init.d/alert5
|
dest: /etc/init.d/alert5
|
||||||
force: no
|
force: no
|
||||||
mode: "0755"
|
mode: "0755"
|
||||||
when: evolinux_system_alert5_init
|
when:
|
||||||
|
- evolinux_system_alert5_init
|
||||||
|
- ansible_distribution_release == "jessie" or ansible_distribution_release == "stretch"
|
||||||
|
|
||||||
|
- name: Enable alert5 init script (jessie/stretch)
|
||||||
#TODO: switch service/systemd modules with Ansible 2.2+
|
|
||||||
|
|
||||||
- name: Enable alert5 init script
|
|
||||||
service:
|
service:
|
||||||
name: alert5
|
name: alert5
|
||||||
enabled: yes
|
enabled: yes
|
||||||
when: evolinux_system_alert5_init and evolinux_system_alert5_enable
|
when:
|
||||||
|
- evolinux_system_alert5_init
|
||||||
|
- evolinux_system_alert5_enable
|
||||||
|
- ansible_distribution_release == "jessie" or ansible_distribution_release == "stretch"
|
||||||
|
|
||||||
# - name: Enable alert5 init script
|
|
||||||
# systemd:
|
|
||||||
# name: alert5
|
- name: Install alert5 init script (buster)
|
||||||
# daemon_reload: yes
|
template:
|
||||||
# enabled: yes
|
src: system/alert5.sh.j2
|
||||||
# when: evolinux_system_alert5_init and evolinux_system_alert5_enable
|
dest: /usr/share/scripts/alert5.sh
|
||||||
|
force: no
|
||||||
|
mode: "0755"
|
||||||
|
when:
|
||||||
|
- evolinux_system_alert5_init
|
||||||
|
- ansible_distribution_major_version | version_compare('10', '>=')
|
||||||
|
|
||||||
|
- name: Install alert5 service (buster)
|
||||||
|
copy:
|
||||||
|
src: alert5.service
|
||||||
|
dest: /etc/systemd/system/alert5.service
|
||||||
|
force: yes
|
||||||
|
mode: "0755"
|
||||||
|
when:
|
||||||
|
- evolinux_system_alert5_init
|
||||||
|
- ansible_distribution_major_version | version_compare('10', '>=')
|
||||||
|
|
||||||
|
- name: Enable alert5 init script (buster)
|
||||||
|
systemd:
|
||||||
|
name: alert5
|
||||||
|
daemon_reload: yes
|
||||||
|
enabled: yes
|
||||||
|
when:
|
||||||
|
- evolinux_system_alert5_init
|
||||||
|
- evolinux_system_alert5_enable
|
||||||
|
- ansible_distribution_major_version | version_compare('10', '>=')
|
||||||
|
|
||||||
## network interfaces
|
## network interfaces
|
||||||
|
|
||||||
|
|
7
evolinux-base/templates/system/alert5.sh.j2
Normal file
7
evolinux-base/templates/system/alert5.sh.j2
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
## sends a mail when booting
|
||||||
|
date | mail -s'boot/reboot' {{ reboot_alert_email or general_alert_email | mandatory }}
|
||||||
|
|
||||||
|
## starts the firewall
|
||||||
|
#/etc/init.d/minifirewall start
|
|
@ -31,7 +31,7 @@ suites:
|
||||||
playbook: ./tests/test.yml
|
playbook: ./tests/test.yml
|
||||||
verifier:
|
verifier:
|
||||||
patterns:
|
patterns:
|
||||||
- admin-users/tests/spec/admin-users_spec.rb
|
- evolinux-users/tests/spec/evolinux-users_spec.rb
|
||||||
bundler_path: '/usr/local/bin'
|
bundler_path: '/usr/local/bin'
|
||||||
rspec_path: '/usr/local/bin'
|
rspec_path: '/usr/local/bin'
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# admin-users
|
# evolinux-users
|
||||||
|
|
||||||
Creates admin users accounts, based on a configuration data structure.
|
Creates evolinux users accounts, based on a configuration data structure.
|
||||||
|
|
||||||
## Tasks
|
## Tasks
|
||||||
|
|
||||||
|
@ -8,20 +8,26 @@ Everything is in the `tasks/main.yml` file.
|
||||||
|
|
||||||
## Available variables
|
## Available variables
|
||||||
|
|
||||||
The variable `admin_users` must be a "dict" of one or more users :
|
The variable `evolinux_users` must be a "dict" of one or more users :
|
||||||
|
|
||||||
```
|
```
|
||||||
admin_users:
|
evolinux_users:
|
||||||
foo:
|
foo:
|
||||||
name: foo
|
name: foo
|
||||||
uid: 1001
|
uid: 1001
|
||||||
fullname: 'Mr Foo'
|
fullname: 'Mr Foo'
|
||||||
|
groups: "baz"
|
||||||
password_hash: 'sdfgsdfgsdfgsdfg'
|
password_hash: 'sdfgsdfgsdfgsdfg'
|
||||||
ssh_key: 'ssh-rsa AZERTYXYZ'
|
ssh_key: 'ssh-rsa AZERTYXYZ'
|
||||||
bar:
|
bar:
|
||||||
name: bar
|
name: bar
|
||||||
uid: 1002
|
uid: 1002
|
||||||
fullname: 'Mr Bar'
|
fullname: 'Mr Bar'
|
||||||
|
groups:
|
||||||
|
- "baz"
|
||||||
|
- "qux"
|
||||||
password_hash: 'gsdfgsdfgsdfgsdf'
|
password_hash: 'gsdfgsdfgsdfgsdf'
|
||||||
ssh_key: 'ssh-rsa QWERTYUIOP'
|
ssh_keys:
|
||||||
|
- 'ssh-rsa QWERTYUIOP'
|
||||||
|
- 'ssh-ed25519 QWERTYUIOP'
|
||||||
```
|
```
|
4
evolinux-users/defaults/main.yml
Normal file
4
evolinux-users/defaults/main.yml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
---
|
||||||
|
evolinux_users: {}
|
||||||
|
evolinux_sudo_group: "evolinux-sudo"
|
||||||
|
evolinux_root_disable_ssh: True
|
|
@ -1,6 +1,6 @@
|
||||||
galaxy_info:
|
galaxy_info:
|
||||||
author: Evolix
|
author: Evolix
|
||||||
description: Creates admin users accounts.
|
description: Creates evolinux users accounts.
|
||||||
|
|
||||||
issue_tracker_url: https://forge.evolix.org/projects/ansible-roles/issues
|
issue_tracker_url: https://forge.evolix.org/projects/ansible-roles/issues
|
||||||
|
|
|
@ -35,19 +35,22 @@
|
||||||
update_password: on_create
|
update_password: on_create
|
||||||
when: loginisbusy.rc != 0 and uidisbusy.rc == 0
|
when: loginisbusy.rc != 0 and uidisbusy.rc == 0
|
||||||
|
|
||||||
- name: "Create {{ admin_users_group }} group (Debian 9 or later)"
|
- name: "Create secondary groups"
|
||||||
group:
|
group:
|
||||||
name: "{{ admin_users_group }}"
|
name: "{{ group }}"
|
||||||
when: ansible_distribution_major_version | version_compare('9', '>=')
|
with_items: "{{ user.groups }}"
|
||||||
|
loop_control:
|
||||||
|
loop_var: group
|
||||||
|
when: user.groups is defined
|
||||||
|
|
||||||
- name: "Add user to {{ admin_users_group }} group (Debian 9 or later)"
|
- name: "Add user '{{ user.name }}' to secondary groups"
|
||||||
user:
|
user:
|
||||||
name: '{{ user.name }}'
|
name: '{{ user.name }}'
|
||||||
groups: '{{ admin_users_group }}'
|
groups: "{{ user.groups }}"
|
||||||
append: yes
|
append: yes
|
||||||
when: ansible_distribution_major_version | version_compare('9', '>=')
|
when: user.groups is defined
|
||||||
|
|
||||||
- name: "Fix perms on homedirectory for '{{ user.name }}'"
|
- name: "Fix perms on home directory for '{{ user.name }}'"
|
||||||
file:
|
file:
|
||||||
name: '/home/{{ user.name }}'
|
name: '/home/{{ user.name }}'
|
||||||
mode: "0700"
|
mode: "0700"
|
20
evolinux-users/tasks/main.yml
Normal file
20
evolinux-users/tasks/main.yml
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
- fail:
|
||||||
|
msg: only compatible with Debian >= 8
|
||||||
|
when:
|
||||||
|
- ansible_distribution != "Debian" or ansible_distribution_major_version | version_compare('8', '<')
|
||||||
|
|
||||||
|
- debug:
|
||||||
|
msg: "Warning: empty 'evolinux_users' variable, tasks will be skipped!"
|
||||||
|
when: evolinux_users == {}
|
||||||
|
|
||||||
|
- name: Create user accounts
|
||||||
|
include: user.yml
|
||||||
|
vars:
|
||||||
|
user: "{{ item.value }}"
|
||||||
|
with_dict: "{{ evolinux_users }}"
|
||||||
|
when: evolinux_users != {}
|
||||||
|
|
||||||
|
- include: root_disable_ssh.yml
|
||||||
|
when: evolinux_root_disable_ssh
|
16
evolinux-users/tasks/profile.yml
Normal file
16
evolinux-users/tasks/profile.yml
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
- name: search profile for presence of evomaintenance
|
||||||
|
command: 'grep -q "trap.*sudo.*evomaintenance.sh"'
|
||||||
|
changed_when: False
|
||||||
|
failed_when: False
|
||||||
|
register: grep_profile_evomaintenance
|
||||||
|
|
||||||
|
# Don't add the trap if it is present or commented
|
||||||
|
- name: "Add evomaintenance trap for '{{ user.name }}'"
|
||||||
|
lineinfile:
|
||||||
|
state: present
|
||||||
|
dest: '/home/{{ user.name }}/.profile'
|
||||||
|
insertafter: EOF
|
||||||
|
line: 'trap "sudo /usr/share/scripts/evomaintenance.sh" 0'
|
||||||
|
when: grep_profile_evomaintenance.rc != 0
|
17
evolinux-users/tasks/root_disable_ssh.yml
Normal file
17
evolinux-users/tasks/root_disable_ssh.yml
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
- name: disable root login
|
||||||
|
replace:
|
||||||
|
dest: /etc/ssh/sshd_config
|
||||||
|
regexp: '^PermitRootLogin (yes|without-password|prohibit-password)'
|
||||||
|
replace: "PermitRootLogin no"
|
||||||
|
notify: reload sshd
|
||||||
|
|
||||||
|
### Disabled : it seems useless and too dangerous for now
|
||||||
|
# - name: remove root from AllowUsers directive
|
||||||
|
# replace:
|
||||||
|
# dest: /etc/ssh/sshd_config
|
||||||
|
# regexp: '^(AllowUsers ((?!root(?:@\S+)?).)*)(\sroot(?:@\S+)?|root(?:@\S+)?\s)(.*)$'
|
||||||
|
# replace: '\1\4'
|
||||||
|
# validate: '/usr/sbin/sshd -T -f %s'
|
||||||
|
# notify: reload sshd
|
|
@ -14,10 +14,21 @@
|
||||||
user: "{{ user.name }}"
|
user: "{{ user.name }}"
|
||||||
key: "{{ user.ssh_key }}"
|
key: "{{ user.ssh_key }}"
|
||||||
state: present
|
state: present
|
||||||
|
when: user.ssh_key is defined
|
||||||
|
|
||||||
|
- name: "Add user's SSH public keys for '{{ user.name }}'"
|
||||||
|
authorized_key:
|
||||||
|
user: "{{ user.name }}"
|
||||||
|
key: "{{ ssk_key }}"
|
||||||
|
state: present
|
||||||
|
with_items: "{{ user.ssh_keys }}"
|
||||||
|
loop_control:
|
||||||
|
loop_var: ssk_key
|
||||||
|
when: user.ssh_keys is defined
|
||||||
|
|
||||||
# we must double-escape caracters, because python
|
# we must double-escape caracters, because python
|
||||||
- name: verify AllowUsers directive
|
- name: verify AllowUsers directive
|
||||||
shell: "egrep '^AllowUsers' /etc/ssh/sshd_config"
|
shell: "grep -E '^AllowUsers' /etc/ssh/sshd_config"
|
||||||
changed_when: False
|
changed_when: False
|
||||||
failed_when: False
|
failed_when: False
|
||||||
register: grep_allowusers_ssh
|
register: grep_allowusers_ssh
|
||||||
|
@ -35,32 +46,37 @@
|
||||||
- name: "Modify AllowUsers sshd directive for '{{ user.name }}'"
|
- name: "Modify AllowUsers sshd directive for '{{ user.name }}'"
|
||||||
replace:
|
replace:
|
||||||
dest: /etc/ssh/sshd_config
|
dest: /etc/ssh/sshd_config
|
||||||
regexp: '^(AllowUsers ((?!{{ user.name }}).)*)$'
|
regexp: '^(AllowUsers ((?!\b{{ user.name }}\b).)*)$'
|
||||||
replace: '\1 {{ user.name }}'
|
replace: '\1 {{ user.name }}'
|
||||||
validate: '/usr/sbin/sshd -T -f %s'
|
validate: '/usr/sbin/sshd -T -f %s'
|
||||||
notify: reload sshd
|
notify: reload sshd
|
||||||
when: grep_allowusers_ssh.rc == 0
|
when: grep_allowusers_ssh.rc == 0
|
||||||
|
|
||||||
- name: verify Match User directive
|
- name: "verify Match User directive"
|
||||||
command: "grep 'Match User' /etc/ssh/sshd_config"
|
command: "grep 'Match User' /etc/ssh/sshd_config"
|
||||||
changed_when: False
|
changed_when: False
|
||||||
failed_when: False
|
failed_when: False
|
||||||
register: grep_matchuser_ssh
|
register: grep_matchuser_ssh
|
||||||
check_mode: no
|
check_mode: no
|
||||||
|
|
||||||
- name: "Add Match User sshd directive for '{{ user.name }}'"
|
- name: "Add Match User sshd directive for '{{ user.name }}' (Jessie)"
|
||||||
lineinfile:
|
lineinfile:
|
||||||
dest: /etc/ssh/sshd_config
|
dest: /etc/ssh/sshd_config
|
||||||
line: "\nMatch User {{ user.name }}\n PasswordAuthentication no"
|
line: "\nMatch User {{ user.name }}\n PasswordAuthentication no"
|
||||||
|
insertafter: "# END EVOLINUX PASSWORD RESTRICTIONS BY ADDRESS"
|
||||||
validate: '/usr/sbin/sshd -T -f %s'
|
validate: '/usr/sbin/sshd -T -f %s'
|
||||||
notify: reload sshd
|
notify: reload sshd
|
||||||
when: grep_matchuser_ssh.rc != 0
|
when:
|
||||||
|
- ansible_distribution_release == "jessie"
|
||||||
|
- grep_matchuser_ssh.rc != 0
|
||||||
|
|
||||||
- name: "Modify Match User's sshd directive for '{{ user.name }}'"
|
- name: "Modify Match User's sshd directive for '{{ user.name }}' (Jessie)"
|
||||||
replace:
|
replace:
|
||||||
dest: /etc/ssh/sshd_config
|
dest: /etc/ssh/sshd_config
|
||||||
regexp: '^(Match User ((?!{{ user.name }}).)*)$'
|
regexp: '^(Match User ((?!{{ user.name }}).)*)$'
|
||||||
replace: '\1,{{ user.name }}'
|
replace: '\1,{{ user.name }}'
|
||||||
validate: '/usr/sbin/sshd -T -f %s'
|
validate: '/usr/sbin/sshd -T -f %s'
|
||||||
notify: reload sshd
|
notify: reload sshd
|
||||||
when: grep_matchuser_ssh.rc == 0
|
when:
|
||||||
|
- ansible_distribution_release == "jessie"
|
||||||
|
- grep_matchuser_ssh.rc == 0
|
18
evolinux-users/tasks/sudo_jessie.yml
Normal file
18
evolinux-users/tasks/sudo_jessie.yml
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
- name: "Verify Evolinux sudoers file presence (jessie)"
|
||||||
|
template:
|
||||||
|
src: sudoers_jessie.j2
|
||||||
|
dest: /etc/sudoers.d/evolinux
|
||||||
|
force: no
|
||||||
|
mode: "0440"
|
||||||
|
validate: '/usr/sbin/visudo -cf %s'
|
||||||
|
register: copy_sudoers_evolinux
|
||||||
|
|
||||||
|
- name: "Add user in sudoers file for '{{ user.name }}' (jessie)"
|
||||||
|
replace:
|
||||||
|
dest: /etc/sudoers.d/evolinux
|
||||||
|
regexp: '^(User_Alias\s+ADMINS\s+=((?!{{ user.name }}).)*)$'
|
||||||
|
replace: '\1,{{ user.name }}'
|
||||||
|
validate: '/usr/sbin/visudo -cf %s'
|
||||||
|
when: not copy_sudoers_evolinux.changed
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue