diff --git a/README.md b/README.md index f8a280c8..966c4a70 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,61 @@ # Ansible-roles -A repository for Ansible roles used by Evolix. +A repository for Ansible roles used by Evolix on Debian GNU/Linux 9 (stretch) servers. +Few roles are also be compatible with Debian GNU/Linux 8 (jessie) servers. It contains only roles, everything else is available at https://forge.evolix.org/projects/ansible-public +## Branches + The **stable** branch contains roles that we consider ready for production. The **unstable** branch contains not sufficiently tested roles (or evolutions on existing roles) that we don't consider ready for production yet. + +Many feature branches may exist in the repository. They represent "work in progress". They may be used, for testing purposes. + +## Install and usage + +First, check-out the repository : + +``` +$ cd ~/GIT/ +$ git clone https://forge.evolix.org/projects/ansible-roles +``` + +Then, add its path to your ansible load path : + +``` +$ vim ~/.ansible.cfg +[defaults] +roles_path = $HOME/GIT/ansible-roles +``` + +Then, include roles in your playbooks : + +``` +- hosts: all + gather_facts: yes + become: yes + roles: + - etc-git + - evolinux-base +``` + +## Contributing + +Contributions are welcome, especially bug fixes and "ansible good practices". They will be merged in if they are consistent with our conventions and use cases. They might be rejected if they introduce complexity, cover features we don't need or don't fit "style". + +Before starting anything of importance, we suggest contacting us to discuss what you'd like to add or change. + +Our conventions are available in the "ansible-public":https://forge.evolix.org/projects/ansible-public repository, in the CONVENTIONS.md file. + +## Workflow + +The ideal and most typical workflow is to create a branch, based on the "unstable" branch. The branch should have a descriptive name (a ticket/issue number is great). The branch can be treated as a pull-request or merge-request. It should be propery tested and reviewed before merging into "unstable". + +Changes that don't introduce significant changes — or that must go faster that the typical workflow — can be commited directly into "unstable". + +Hotfixes, can be prepared on a new branch, based on "stable" or "unstable" (to be decided by the author). When ready, it can be merged back to "stable" for immediate deployment and to "unstable" for proper backporting. + +Other workflow are not forbidden, but should be discussed in advance. diff --git a/admin-users/defaults/main.yml b/admin-users/defaults/main.yml index e0c1ff04..ad5f42cb 100644 --- a/admin-users/defaults/main.yml +++ b/admin-users/defaults/main.yml @@ -1,2 +1,3 @@ --- admin_users: {} +admin_users_group: adm diff --git a/admin-users/meta/main.yml b/admin-users/meta/main.yml index 7779f782..006768d3 100644 --- a/admin-users/meta/main.yml +++ b/admin-users/meta/main.yml @@ -12,6 +12,7 @@ galaxy_info: - name: Debian versions: - jessie + - stretch dependencies: [] # List your role dependencies here, one per line. diff --git a/admin-users/tasks/adduser_debian.yml b/admin-users/tasks/adduser_debian.yml deleted file mode 100644 index 56c934d5..00000000 --- a/admin-users/tasks/adduser_debian.yml +++ /dev/null @@ -1,140 +0,0 @@ ---- - -- name: "Test if uid exists for '{{ user.name }}'" - command: 'getent passwd {{ user.uid }}' - register: uidisbusy - failed_when: False - changed_when: False - check_mode: no - - -- name: "Add Unix account with classical uid for '{{ user.name }}'" - user: - state: present - uid: '{{ user.uid }}' - name: '{{ user.name }}' - comment: '{{ user.fullname }}' - shell: /bin/bash - password: '{{ user.password_hash }}' - update_password: on_create - when: uidisbusy|failed - -- name: "Add Unix account with random uid for '{{ user.name }}'" - user: - state: present - name: '{{ user.name }}' - comment: '{{ user.fullname }}' - shell: /bin/bash - password: '{{ user.password_hash }}' - update_password: on_create - when: uidisbusy|success - -- name: "Fix perms on homedirectory for '{{ user.name }}'" - file: - name: '/home/{{ user.name }}' - mode: "0700" - state: directory - -- 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 - -- name: "Create .ssh directory for '{{ user.name }}'" - file: - dest: '/home/{{ user.name }}/.ssh/' - state: directory - mode: "0700" - owner: '{{ user.name }}' - group: '{{ user.name }}' - -- name: "Add user's SSH public key for '{{ user.name }}'" - authorized_key: - user: "{{ user.name }}" - key: "{{ user.ssh_key }}" - state: present - -- name: verify AllowUsers directive - command: "grep AllowUsers /etc/ssh/sshd_config" - changed_when: False - failed_when: False - register: grep_allowusers_ssh - check_mode: no - - -- name: "Add AllowUsers sshd directive for '{{ user.name }}'" - lineinfile: - dest: /etc/ssh/sshd_config - line: "\nAllowUsers {{ user.name }}" - insertafter: '^UsePAM' - validate: '/usr/sbin/sshd -T -f %s' - notify: reload sshd - when: grep_allowusers_ssh.rc != 0 - -- name: "Modify AllowUsers sshd directive for '{{ user.name }}'" - replace: - dest: /etc/ssh/sshd_config - regexp: '^(AllowUsers ((?!{{ user.name }}).)*)$' - replace: '\1 {{ user.name }}' - validate: '/usr/sbin/sshd -T -f %s' - notify: reload sshd - when: grep_allowusers_ssh.rc == 0 - -- name: verify Match User directive - command: "grep 'Match User' /etc/ssh/sshd_config" - changed_when: False - failed_when: False - register: grep_matchuser_ssh - check_mode: no - - -- name: "Add Match User sshd directive for '{{ user.name }}'" - lineinfile: - dest: /etc/ssh/sshd_config - line: "\nMatch User {{ user.name }}\n PasswordAuthentication no" - validate: '/usr/sbin/sshd -T -f %s' - notify: reload sshd - when: grep_matchuser_ssh.rc != 0 - -- name: "Modify Match User's sshd directive for '{{ user.name }}'" - replace: - dest: /etc/ssh/sshd_config - regexp: '^(Match User ((?!{{ user.name }}).)*)$' - replace: '\1,{{ user.name }}' - validate: '/usr/sbin/sshd -T -f %s' - notify: reload sshd - when: grep_matchuser_ssh.rc == 0 - -- name: Verify Evolinux sudoers file presence - template: - src: sudoers_debian.j2 - dest: /etc/sudoers.d/evolinux - force: false - validate: '/usr/sbin/visudo -cf %s' - register: copy_sudoers_evolinux - -- 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 }}'" - 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 - -- meta: flush_handlers diff --git a/admin-users/tasks/admin_user.yml b/admin-users/tasks/admin_user.yml new file mode 100644 index 00000000..329ce50e --- /dev/null +++ b/admin-users/tasks/admin_user.yml @@ -0,0 +1,11 @@ +--- + +- include: user.yml + +- include: profile.yml + +- include: ssh.yml + +- include: sudo.yml + +- meta: flush_handlers diff --git a/admin-users/tasks/main.yml b/admin-users/tasks/main.yml index 11800373..6a1d1506 100644 --- a/admin-users/tasks/main.yml +++ b/admin-users/tasks/main.yml @@ -1,15 +1,16 @@ --- - fail: - msg: "Error: empty variable 'admin_users'!" + 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: adduser_debian.yml +- include: admin_user.yml vars: user: "{{ item.value }}" with_dict: "{{ admin_users }}" - when: ansible_distribution == "Debian" - -# - include: adduser_openbsd.yml user={{ item.value }} -# with_dict: "{{ admin_users }}" -# when: ansible_distribution == "OpenBSD" + when: admin_users != {} diff --git a/admin-users/tasks/profile.yml b/admin-users/tasks/profile.yml new file mode 100644 index 00000000..0101d4be --- /dev/null +++ b/admin-users/tasks/profile.yml @@ -0,0 +1,15 @@ +--- + +- 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 diff --git a/admin-users/tasks/ssh.yml b/admin-users/tasks/ssh.yml new file mode 100644 index 00000000..d74a51f2 --- /dev/null +++ b/admin-users/tasks/ssh.yml @@ -0,0 +1,66 @@ +--- + + +- name: "Create .ssh directory for '{{ user.name }}'" + file: + dest: '/home/{{ user.name }}/.ssh/' + state: directory + mode: "0700" + owner: '{{ user.name }}' + group: '{{ user.name }}' + +- name: "Add user's SSH public key for '{{ user.name }}'" + authorized_key: + user: "{{ user.name }}" + key: "{{ user.ssh_key }}" + state: present + +# we must double-escape caracters, because python +- name: verify AllowUsers directive + shell: "egrep '^AllowUsers' /etc/ssh/sshd_config" + changed_when: False + failed_when: False + register: grep_allowusers_ssh + check_mode: no + +- name: "Add AllowUsers sshd directive for '{{ user.name }}'" + lineinfile: + dest: /etc/ssh/sshd_config + line: "\nAllowUsers {{ user.name }}" + insertafter: 'Subsystem' + validate: '/usr/sbin/sshd -T -f %s' + notify: reload sshd + when: grep_allowusers_ssh.rc != 0 + +- name: "Modify AllowUsers sshd directive for '{{ user.name }}'" + replace: + dest: /etc/ssh/sshd_config + regexp: '^(AllowUsers ((?!{{ user.name }}).)*)$' + replace: '\1 {{ user.name }}' + validate: '/usr/sbin/sshd -T -f %s' + notify: reload sshd + when: grep_allowusers_ssh.rc == 0 + +- name: verify Match User directive + command: "grep 'Match User' /etc/ssh/sshd_config" + changed_when: False + failed_when: False + register: grep_matchuser_ssh + check_mode: no + +- name: "Add Match User sshd directive for '{{ user.name }}'" + lineinfile: + dest: /etc/ssh/sshd_config + line: "\nMatch User {{ user.name }}\n PasswordAuthentication no" + validate: '/usr/sbin/sshd -T -f %s' + notify: reload sshd + when: grep_matchuser_ssh.rc != 0 + +- name: "Modify Match User's sshd directive for '{{ user.name }}'" + replace: + dest: /etc/ssh/sshd_config + regexp: '^(Match User ((?!{{ user.name }}).)*)$' + replace: '\1,{{ user.name }}' + validate: '/usr/sbin/sshd -T -f %s' + notify: reload sshd + when: grep_matchuser_ssh.rc == 0 diff --git a/admin-users/tasks/sudo.yml b/admin-users/tasks/sudo.yml new file mode 100644 index 00000000..e05ac614 --- /dev/null +++ b/admin-users/tasks/sudo.yml @@ -0,0 +1,48 @@ +--- + +- 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', '>=') diff --git a/admin-users/tasks/user.yml b/admin-users/tasks/user.yml new file mode 100644 index 00000000..94f1a0c3 --- /dev/null +++ b/admin-users/tasks/user.yml @@ -0,0 +1,54 @@ +--- + +- name: "Test if '{{ user.name }}' exists" + command: 'getent passwd {{ user.name }}' + register: loginisbusy + failed_when: False + changed_when: False + check_mode: no + +- name: "Test if uid exists for '{{ user.name }}'" + command: 'getent passwd {{ user.uid }}' + register: uidisbusy + failed_when: False + changed_when: False + check_mode: no + +- name: "Add Unix account with classical uid for '{{ user.name }}'" + user: + state: present + uid: '{{ user.uid }}' + name: '{{ user.name }}' + comment: '{{ user.fullname }}' + shell: /bin/bash + password: '{{ user.password_hash }}' + update_password: on_create + when: loginisbusy.rc != 0 and uidisbusy.rc != 0 + +- name: "Add Unix account with random uid for '{{ user.name }}'" + user: + state: present + name: '{{ user.name }}' + comment: '{{ user.fullname }}' + shell: /bin/bash + password: '{{ user.password_hash }}' + update_password: on_create + when: loginisbusy.rc != 0 and uidisbusy.rc == 0 + +- name: "Create {{ admin_users_group }} group (Debian 9 or later)" + group: + name: "{{ admin_users_group }}" + when: ansible_distribution_major_version | version_compare('9', '>=') + +- name: "Add user to {{ admin_users_group }} group (Debian 9 or later)" + user: + name: '{{ user.name }}' + groups: '{{ admin_users_group }}' + append: yes + when: ansible_distribution_major_version | version_compare('9', '>=') + +- name: "Fix perms on homedirectory for '{{ user.name }}'" + file: + name: '/home/{{ user.name }}' + mode: "0700" + state: directory diff --git a/admin-users/templates/sudoers_debian.j2 b/admin-users/templates/sudoers_jessie.j2 similarity index 100% rename from admin-users/templates/sudoers_debian.j2 rename to admin-users/templates/sudoers_jessie.j2 diff --git a/admin-users/templates/sudoers_stretch.j2 b/admin-users/templates/sudoers_stretch.j2 new file mode 100644 index 00000000..8de1bbc6 --- /dev/null +++ b/admin-users/templates/sudoers_stretch.j2 @@ -0,0 +1,9 @@ +Defaults umask=0077 + +Cmnd_Alias MAINT = /usr/share/scripts/evomaintenance.sh, /usr/share/scripts/listupgrade.sh, /usr/bin/apt, /bin/mount + +nagios ALL = NOPASSWD: /usr/lib/nagios/plugins/check_procs +nagios ALL = (clamav) NOPASSWD: /usr/bin/clamscan /tmp/safe.txt + +%evolinux-sudo ALL=(ALL:ALL) ALL +%evolinux-sudo ALL = NOPASSWD: MAINT diff --git a/amavis/README.md b/amavis/README.md deleted file mode 100644 index b62ec0ed..00000000 --- a/amavis/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Amavis - -Installation and basic configuration of amavis. - -## 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`. diff --git a/amavis/handlers/main.yml b/amavis/handlers/main.yml deleted file mode 100644 index 62049999..00000000 --- a/amavis/handlers/main.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -- name: restart amavis - service: - name: amavis - state: restarted diff --git a/amavis/meta/main.yml b/amavis/meta/main.yml deleted file mode 100644 index affdf9c9..00000000 --- a/amavis/meta/main.yml +++ /dev/null @@ -1,19 +0,0 @@ -galaxy_info: - author: Evolix - description: Installation and basic configuration of amavis. - - issue_tracker_url: https://forge.evolix.org/projects/ansible-roles/issues - - license: GPLv2 - - min_ansible_version: 2.2 - - platforms: - - name: Debian - versions: - - jessie - -dependencies: [] - # List your role dependencies here, one per line. - # Be sure to remove the '[]' above if you add dependencies - # to this list. diff --git a/amavis/tasks/main.yml b/amavis/tasks/main.yml deleted file mode 100644 index d4dc7803..00000000 --- a/amavis/tasks/main.yml +++ /dev/null @@ -1,4 +0,0 @@ -- name: ensure packages are installed - apt: - name: amavis - state: present diff --git a/ansible-managed/README.md b/ansible-managed/README.md deleted file mode 100644 index 5b0f0e9c..00000000 --- a/ansible-managed/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# ansible-managed - -Set some indications that the server is managed by Ansible and extra care yshould be given not no mess with it manually. - -## Tasks - -Everything is in the `tasks/main.yml` file. - -## Available variables - -* `project_repository` : project URL for the repository. diff --git a/ansible-managed/defaults/main.yml b/ansible-managed/defaults/main.yml deleted file mode 100644 index 7d7ef4da..00000000 --- a/ansible-managed/defaults/main.yml +++ /dev/null @@ -1,2 +0,0 @@ ---- -project_repository: "/!\\ No repository set, contact Evolix" diff --git a/ansible-managed/tasks/main.yml b/ansible-managed/tasks/main.yml deleted file mode 100644 index 7fcbc1fc..00000000 --- a/ansible-managed/tasks/main.yml +++ /dev/null @@ -1,7 +0,0 @@ ---- -- name: Set message of the day - template: - src: motd.j2 - dest: /etc/motd - force: yes - backup: yes diff --git a/ansible-managed/templates/motd.j2 b/ansible-managed/templates/motd.j2 deleted file mode 100644 index 58b468d2..00000000 --- a/ansible-managed/templates/motd.j2 +++ /dev/null @@ -1,4 +0,0 @@ - -SERVER MANAGED BY EVOLIX VIA ANSIBLE ------------------------------------- -{{ project_repository | mandatory }} diff --git a/ansible-managed/tests/test.yml b/ansible-managed/tests/test.yml deleted file mode 100644 index f6e76a31..00000000 --- a/ansible-managed/tests/test.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -- hosts: test-kitchen - roles: - - role: ansible-managed diff --git a/apache/README.md b/apache/README.md index bd45539b..66804981 100644 --- a/apache/README.md +++ b/apache/README.md @@ -14,5 +14,6 @@ Main variables are : * `apache_private_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_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`). The full list of variables (with default values) can be found in `defaults/main.yml`. diff --git a/apache/defaults/main.yml b/apache/defaults/main.yml index 70140cad..276f5a38 100644 --- a/apache/defaults/main.yml +++ b/apache/defaults/main.yml @@ -4,3 +4,15 @@ apache_private_ipaddr_whitelist_absent: [] apache_private_htpasswd_present: [] apache_private_htpasswd_absent: [] + +apache_evolinux_default_enabled: True +apache_evolinux_default_ssl_cert: /etc/ssl/certs/ssl-cert-snakeoil.pem +apache_evolinux_default_ssl_key: /etc/ssl/private/ssl-cert-snakeoil.key + +apache_serverstatus_suffix: "" + +apache_log2mail_include: True +apache_munin_include: True + +general_alert_email: "root@localhost" +log2mail_alert_email: Null diff --git a/apache/files/evolinux-custom.conf b/apache/files/evolinux-custom.conf index def69d90..64d8f97a 100644 --- a/apache/files/evolinux-custom.conf +++ b/apache/files/evolinux-custom.conf @@ -3,3 +3,24 @@ #StartServers 100 #MinSpareServers 40 #MaxSpareServers 60 + +SetEnvIf User-Agent "^BadBot$" GoAway=1 +SetEnvIf User-Agent "Nutch" GoAway=1 +SetEnvIf User-Agent "ApacheBench" GoAway=1 + +# Uncomment for SSL strong security +# +#SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH +#SSLProtocol All -SSLv2 -SSLv3 +#SSLHonorCipherOrder On +#SSLCompression off +#SSLSessionCache shmcb:/var/log/apache2/ssl_gcache_data(512000) +#SSLSessionCacheTimeout 600 +## Stapling not activated by default. Need config. +##SSLUseStapling on +##SSLStaplingCache shmcb:${APACHE_RUN_DIR}/stapling-cache(150000) +# + +# +# Header set Access-Control-Allow-Origin "*" +# diff --git a/apache/files/evolinux-defaults.conf b/apache/files/evolinux-defaults.conf index 511396e5..348717ea 100644 --- a/apache/files/evolinux-defaults.conf +++ b/apache/files/evolinux-defaults.conf @@ -12,4 +12,25 @@ MaxRequestsPerChild 0 AllowOverride None Require all granted + # "Require not env XXX" is not supported :( + Deny from env=GoAway + +SSLProtocol all -SSLv2 -SSLv3 +SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5:!RC4 + + + Require all denied + + + + ExtendedStatus On + + ProxyStatus On + + + + +LimitUIDRange 0 6000 +LimitGIDRange 0 6000 + diff --git a/apache/files/evolinux-ssl.conf b/apache/files/evolinux-ssl.conf deleted file mode 100644 index cde0f7ec..00000000 --- a/apache/files/evolinux-ssl.conf +++ /dev/null @@ -1,11 +0,0 @@ -# Strong security. -SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH -SSLProtocol All -SSLv2 -SSLv3 -SSLHonorCipherOrder On -SSLCompression off -SSLSessionCache shmcb:/var/log/apache2/ssl_gcache_data(512000) -SSLSessionCacheTimeout 600 - -# Stapling not activated by default. Need config. -#SSLUseStapling on -#SSLStaplingCache shmcb:${APACHE_RUN_DIR}/stapling-cache(150000) diff --git a/apache/files/private_ipaddr_whitelist.conf b/apache/files/private_ipaddr_whitelist.conf index 34e7da20..6c42b58c 100644 --- a/apache/files/private_ipaddr_whitelist.conf +++ b/apache/files/private_ipaddr_whitelist.conf @@ -1,2 +1,2 @@ # Whitelisted IP addresses, add `Include ipaddr_whitelist.conf` to use it -#Allow from 192.0.2.42 +#Require ip 192.0.2.42 diff --git a/apache/handlers/main.yml b/apache/handlers/main.yml index af4d94d2..96daa368 100644 --- a/apache/handlers/main.yml +++ b/apache/handlers/main.yml @@ -8,3 +8,8 @@ service: name: apache2 state: reloaded + +- name: restart munin-node + service: + name: munin-node + state: restarted diff --git a/apache/meta/main.yml b/apache/meta/main.yml index 0949e1dd..497d52e9 100644 --- a/apache/meta/main.yml +++ b/apache/meta/main.yml @@ -12,6 +12,7 @@ galaxy_info: - name: Debian versions: - jessie + - stretch dependencies: [] # List your role dependencies here, one per line. diff --git a/apache/tasks/auth.yml b/apache/tasks/auth.yml new file mode 100644 index 00000000..0f550a3c --- /dev/null +++ b/apache/tasks/auth.yml @@ -0,0 +1,73 @@ +--- + +- name: Init ipaddr_whitelist.conf file + copy: + src: private_ipaddr_whitelist.conf + dest: /etc/apache2/ipaddr_whitelist.conf + owner: root + group: root + mode: "0640" + force: no + tags: + - apache + +- name: add IP addresses to private IP whitelist + lineinfile: + dest: /etc/apache2/ipaddr_whitelist.conf + line: "Require ip {{ item }}" + state: present + with_items: "{{ apache_private_ipaddr_whitelist_present }}" + notify: reload apache + tags: + - apache + +- name: remove IP addresses from private IP whitelist + lineinfile: + dest: /etc/apache2/ipaddr_whitelist.conf + line: "Require ip {{ item }}" + state: absent + with_items: "{{ apache_private_ipaddr_whitelist_absent }}" + notify: reload apache + tags: + - apache + +- name: include private IP whitelist for server-status + lineinfile: + dest: /etc/apache2/mods-available/status.conf + line: " include /etc/apache2/ipaddr_whitelist.conf" + insertafter: 'SetHandler server-status' + state: present + tags: + - apache + +- name: Copy private_htpasswd + copy: + src: private_htpasswd + dest: /etc/apache2/private_htpasswd + owner: root + group: root + mode: "0640" + force: no + notify: reload apache + tags: + - apache + +- name: add user:pwd to private htpasswd + lineinfile: + dest: /etc/apache2/private_htpasswd + line: "{{ item }}" + state: present + with_items: "{{ apache_private_htpasswd_present }}" + notify: reload apache + tags: + - apache + +- name: remove user:pwd from private htpasswd + lineinfile: + dest: /etc/apache2/private_htpasswd + line: "{{ item }}" + state: absent + with_items: "{{ apache_private_htpasswd_absent }}" + notify: reload apache + tags: + - apache diff --git a/apache/tasks/log2mail.yml b/apache/tasks/log2mail.yml new file mode 100644 index 00000000..894ff039 --- /dev/null +++ b/apache/tasks/log2mail.yml @@ -0,0 +1,15 @@ +--- + +- name: log2mail is installed + apt: + name: log2mail + state: present + +- name: Add log2mail config for Apache segfaults + template: + src: log2mail-apache.j2 + dest: "/etc/log2mail/config/apache" + owner: log2mail + group: adm + mode: "0644" + force: no diff --git a/apache/tasks/main.yml b/apache/tasks/main.yml index dce83867..50fb548a 100644 --- a/apache/tasks/main.yml +++ b/apache/tasks/main.yml @@ -1,36 +1,33 @@ -- name: packages are installed +--- + +- name: packages are installed (Debian 9 or later) apt: name: '{{ item }}' state: present with_items: - apache2 - - apache2-mpm-prefork + - libapache2-mpm-itk + - libapache2-mod-evasive - apachetop - libwww-perl tags: - apache + - packages + when: ansible_distribution_major_version | version_compare('9', '>=') -- name: manually disable mpm_event - command: a2dismod mpm_event - register: cmd_disable_event - changed_when: "'Module mpm_event already disabled' not in cmd_disable_event.stdout" - -- name: manually enable mpm_prefork - command: a2enmod mpm_prefork - register: cmd_disable_prefork - changed_when: "'Module mpm_prefork already enabled' not in cmd_disable_prefork.stdout" - -# With Ansible 2.2 the module check the config for conflicts -# With 2.3 it can be disabled. -# https://docs.ansible.com/ansible/apache2_module_module.html -# - name: mpm_event modules is disabled -# apache2_module: -# name: '{{ item }}' -# state: absent -# with_items: -# - mpm_event -# tags: -# - apache +- name: packages are installed (jessie) + apt: + name: '{{ item }}' + state: present + with_items: + - apache2-mpm-itk + - libapache2-mod-evasive + - apachetop + - libwww-perl + tags: + - apache + - packages + when: ansible_distribution_release == "jessie" - name: basic modules are enabled apache2_module: @@ -41,7 +38,7 @@ - expires - headers - cgi - - ssl + notify: reload apache tags: - apache @@ -51,8 +48,9 @@ dest: "/etc/apache2/conf-available/z-evolinux-defaults.conf" owner: root group: root - mode: "0644" + mode: "0640" force: yes + notify: reload apache tags: - apache @@ -62,21 +60,17 @@ dest: "/etc/apache2/conf-available/zzz-evolinux-custom.conf" owner: root group: root - mode: "0644" + mode: "0640" force: no + notify: reload apache tags: - apache -- name: Copy Apache SSL (strong security) config file - copy: - src: evolinux-ssl.conf - dest: "/etc/apache2/conf-available/evolinux-ssl.conf" - owner: root - group: root - mode: "0644" - force: no - tags: - - apache +- name: disable status.conf + file: + dest: /etc/apache2/mods-enabled/status.conf + state: absent + notify: reload apache - name: Ensure Apache config files are enabled command: "a2enconf {{ item }}" @@ -85,70 +79,30 @@ with_items: - z-evolinux-defaults.conf - zzz-evolinux-custom.conf - - evolinux-ssl.conf - tags: - - apache - -- name: Init private_ipaddr_whitelist.conf file - copy: - src: private_ipaddr_whitelist.conf - dest: /etc/apache2/private_ipaddr_whitelist.conf - owner: root - group: root - mode: "0640" - force: no - tags: - - apache - -- name: add IP addresses to private IP whitelist - lineinfile: - dest: /etc/apache2/private_ipaddr_whitelist.conf - line: "Allow from {{ item }}" - state: present - with_items: "{{ apache_private_ipaddr_whitelist_present }}" notify: reload apache tags: - apache -- name: remove IP addresses from private IP whitelist - lineinfile: - dest: /etc/apache2/private_ipaddr_whitelist.conf - line: "Allow from {{ item }}" - state: absent - with_items: "{{ apache_private_ipaddr_whitelist_absent }}" - notify: reload apache - tags: - - apache +- include: auth.yml -- name: Copy private_htpasswd - copy: - src: private_htpasswd - dest: /etc/apache2/private_htpasswd - owner: root - group: root +- name: default vhost is installed + template: + src: evolinux-default.conf.j2 + dest: /etc/apache2/sites-available/000-evolinux-default.conf mode: "0640" force: no notify: reload apache tags: - apache -- name: add user:pwd to private htpasswd - lineinfile: - dest: /etc/apache2/private_htpasswd - line: "{{ item }}" - state: present - with_items: "{{ apache_private_htpasswd_present }}" - notify: reload apache - tags: - - apache - -- name: remove user:pwd from private htpasswd - lineinfile: - dest: /etc/apache2/private_htpasswd - line: "{{ item }}" - state: absent - with_items: "{{ apache_private_htpasswd_absent }}" +- name: default vhost is enabled + file: + src: /etc/apache2/sites-available/000-evolinux-default.conf + dest: /etc/apache2/sites-enabled/000-default.conf + state: link + force: yes notify: reload apache + when: apache_evolinux_default_enabled tags: - apache @@ -172,3 +126,34 @@ when: envvar_grep_umask.rc != 0 tags: - apache + +- name: Stat /default index + stat: + path: /var/www/index.html + register: _default_index + check_mode: no + tags: + - apache + +# - block: +# - name: generate random string for serverstatus suffix +# command: "apg -a 1 -M N -n 1" +# changed_when: False +# register: _random_serverstatus_suffix +# +# - 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 + when: apache_log2mail_include + +- include: munin.yml + when: apache_munin_include diff --git a/apache/tasks/munin.yml b/apache/tasks/munin.yml new file mode 100644 index 00000000..85f0b386 --- /dev/null +++ b/apache/tasks/munin.yml @@ -0,0 +1,23 @@ +--- + +- name: munin-node and core plugins are installed + apt: + name: "{{ item }}" + state: installed + with_items: + - munin-node + - munin-plugins-core + +- name: enable munin plugins + file: + src: "/usr/share/munin/plugins/{{ item }}" + dest: "/etc/munin/plugins/{{ item }}" + state: link + with_items: + - apache_accesses + - apache_processes + - apache_volume + notify: restart munin-node + tags: + - apache + - munin diff --git a/apache/templates/evolinux-default.conf.j2 b/apache/templates/evolinux-default.conf.j2 new file mode 100644 index 00000000..b50409a8 --- /dev/null +++ b/apache/templates/evolinux-default.conf.j2 @@ -0,0 +1,121 @@ + + ServerName {{ ansible_fqdn }} + #ServerAlias {{ ansible_fqdn }} + + DocumentRoot /var/www/ + + + Include /etc/apache2/ipaddr_whitelist.conf + + + Options -Indexes + Require all denied + Include /etc/apache2/ipaddr_whitelist.conf + + + # Munin. We need to set Directory directive as Alias take precedence. + Alias /munin /var/cache/munin/www + + Require all denied + Include /etc/apache2/ipaddr_whitelist.conf + + + Options -Indexes + Require all denied + Include /etc/apache2/ipaddr_whitelist.conf + + + # For CGI Scripts. We need to set Directory directive as ScriptAlias take precedence. + ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/ + + Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch + Require all denied + Include /etc/apache2/ipaddr_whitelist.conf + + + CustomLog /var/log/apache2/access.log vhost_combined + ErrorLog /var/log/apache2/error.log + LogLevel warn + + + RewriteEngine on + # Redirect to HTTPS, execpt for munin, because some plugins + # can't handle HTTPS! :( + RewriteCond %{REQUEST_URI} !^/server-status.*$ [NC] [OR] + RewriteCond %{REQUEST_URI} !^/munin_opcache.php$ [NC] + RewriteRule ^/(.*) https://{{ ansible_fqdn }}/$1 [L,R=permanent] + + + + Require local + + + + + SetHandler server-status + include /etc/apache2/ipaddr_whitelist.conf + Require local + + + + + + + + ServerName {{ ansible_fqdn }} + #ServerAlias {{ ansible_fqdn }} + + DocumentRoot /var/www/ + + # We override these 2 Directory directives setted in apache2.conf. + # We want no access except from allowed IP address. + + Include /etc/apache2/ipaddr_whitelist.conf + + + Options -Indexes + Require all denied + Include /etc/apache2/ipaddr_whitelist.conf + + + SSLEngine on + SSLCertificateFile {{ apache_evolinux_default_ssl_cert }} + SSLCertificateKeyFile {{ apache_evolinux_default_ssl_key }} + + # Munin. We need to set Directory directive as Alias take precedence. + Alias /munin /var/cache/munin/www + + Require all denied + Include /etc/apache2/ipaddr_whitelist.conf + + + Options -Indexes + Require all denied + Include /etc/apache2/ipaddr_whitelist.conf + + + # For CGI Scripts. We need to set Directory directive as ScriptAlias take precedence. + ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/ + + Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch + Require all denied + Include /etc/apache2/ipaddr_whitelist.conf + + +# BEGIN phpMyAdmin section +# END phpMyAdmin section + + CustomLog /var/log/apache2/access.log vhost_combined + ErrorLog /var/log/apache2/error.log + LogLevel warn + + + + SetHandler server-status + include /etc/apache2/ipaddr_whitelist.conf + Require local + + + + + diff --git a/packweb-apache/templates/log2mail-apache.j2 b/apache/templates/log2mail-apache.j2 similarity index 100% rename from packweb-apache/templates/log2mail-apache.j2 rename to apache/templates/log2mail-apache.j2 diff --git a/apt-repositories/.kitchen.yml b/apt-repositories/.kitchen.yml deleted file mode 100644 index 65139ac6..00000000 --- a/apt-repositories/.kitchen.yml +++ /dev/null @@ -1,36 +0,0 @@ ---- -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: - - apt-repositories/tests/spec/main_spec.rb - bundler_path: '/usr/local/bin' - rspec_path: '/usr/local/bin' - -transport: - max_ssh_sessions: 6 diff --git a/apt-repositories/README.md b/apt-repositories/README.md deleted file mode 100644 index 7eaff8b5..00000000 --- a/apt-repositories/README.md +++ /dev/null @@ -1,57 +0,0 @@ -# apt-repositories - -A few APT related operations, like easily install backports of change components for repositories. - -## Tasks - -Tasks are extracted in several files, included in `tasks/main.yml` : - -* `backports.yml` : add a sources list for backports ; -* `basics_components.yml` : replace components for the basic sources. - -## Available variables - -* `apt_repositories_install_basics` : change basic sources components (default: `True`) ; -* `apt_repositories_basics_components` : basic sources components (default: `main`) ; -* `apt_repositories_install_backports` : install backports sources (default: `False`) ; -* `apt_repositories_backports_components` : backports sources (default: `main`) ; -* `apt_repositories_install_evolix_public` : install Evolix public repositories (default: `True`). - -## Examples - -To add "non-free" and "contrib" components to basic sources lists : - -``` -{ role: apt-repositories, - apt_repositories_install_basics: True, - apt_repositories_basics_components: "main non-free contrib" -} -``` - -To install backports sources lists : - -``` -{ role: apt-repositories, - apt_repositories_install_backports: True -} -``` - -To install backports sources lists with "non-free" and "contrib" : - -``` -{ role: apt-repositories, - apt_repositories_install_backports: True, - apt_repositories_backports_components: "main non-free contrib" -} -``` - -To install backports sources lists and have "non-free" and "contrib" for each repository : - -``` -{ role: apt-repositories, - apt_repositories_install_basics: True, - apt_repositories_basics_components: "main non-free contrib", - apt_repositories_install_backports: True, - apt_repositories_backports_components: "main non-free contrib" -} -``` diff --git a/apt-repositories/defaults/main.yml b/apt-repositories/defaults/main.yml deleted file mode 100644 index 47c3016f..00000000 --- a/apt-repositories/defaults/main.yml +++ /dev/null @@ -1,7 +0,0 @@ -apt_repositories_install_basics: True -apt_repositories_basics_components: "main" - -apt_repositories_install_backports: False -apt_repositories_backports_components: "main" - -apt_repositories_install_evolix_public: True diff --git a/apt-repositories/tasks/main.yml b/apt-repositories/tasks/main.yml deleted file mode 100644 index a70febd5..00000000 --- a/apt-repositories/tasks/main.yml +++ /dev/null @@ -1,31 +0,0 @@ ---- - -- name: Fail if distribution is not supported - fail: - msg: "Error: '{{ ansible_os_family }} {{ ansible_distribution_release }}' is not a supported distribution." - when: - - ansible_distribution_release != "jessie" - - ansible_distribution_release != "stretch" - tags: - - apt-repositories - -- name: Install basics repositories - include: basics.yml - when: apt_repositories_install_basics - tags: - - apt-repositories - -- name: Install APT Backports repository - include: backports.yml - when: apt_repositories_install_backports - tags: - - apt-repositories - -- debug: - var: apt_repositories_install_evolix_public - -- name: Install Evolix Public APT repository - include: evolix_public.yml - when: apt_repositories_install_evolix_public - tags: - - apt-repositories diff --git a/apt-repositories/templates/jessie_backports.list.j2 b/apt-repositories/templates/jessie_backports.list.j2 deleted file mode 100644 index 863c242c..00000000 --- a/apt-repositories/templates/jessie_backports.list.j2 +++ /dev/null @@ -1,3 +0,0 @@ -# {{ ansible_managed }} - -deb http://mirror.evolix.org/debian jessie-backports {{ apt_repositories_backports_components | mandatory }} diff --git a/apt-repositories/templates/jessie_basics.list.j2 b/apt-repositories/templates/jessie_basics.list.j2 deleted file mode 100644 index 90237365..00000000 --- a/apt-repositories/templates/jessie_basics.list.j2 +++ /dev/null @@ -1,5 +0,0 @@ -# {{ ansible_managed }} - -deb http://mirror.evolix.org/debian/ jessie {{ apt_repositories_basics_components | mandatory }} -deb http://mirror.evolix.org/debian/ jessie-updates {{ apt_repositories_basics_components | mandatory }} -deb http://security.debian.org/ jessie/updates {{ apt_repositories_basics_components | mandatory }} diff --git a/apt-repositories/templates/stretch_backports.list.j2 b/apt-repositories/templates/stretch_backports.list.j2 deleted file mode 100644 index ce887449..00000000 --- a/apt-repositories/templates/stretch_backports.list.j2 +++ /dev/null @@ -1,3 +0,0 @@ -# {{ ansible_managed }} - -deb http://mirror.evolix.org/debian stretch-backports {{ apt_repositories_backports_components | mandatory }} diff --git a/apt-repositories/templates/stretch_basics.list.j2 b/apt-repositories/templates/stretch_basics.list.j2 deleted file mode 100644 index dada4cab..00000000 --- a/apt-repositories/templates/stretch_basics.list.j2 +++ /dev/null @@ -1,4 +0,0 @@ -# {{ ansible_managed }} - -deb http://deb.debian.org/debian stretch {{ apt_repositories_basics_components | mandatory }} -deb http://security.debian.org/debian-security stretch/updates {{ apt_repositories_basics_components | mandatory }} diff --git a/apt-repositories/tests/test.yml b/apt-repositories/tests/test.yml deleted file mode 100644 index a6c49fe6..00000000 --- a/apt-repositories/tests/test.yml +++ /dev/null @@ -1,10 +0,0 @@ ---- -- hosts: test-kitchen - - vars: - apt_repositories_basics_components: "main contrib non-free" - apt_repositories_install_backports: True - apt_repositories_backports_components: "main contrib non-free" - - roles: - - role: apt-repositories diff --git a/nginx-light/.kitchen.yml b/apt/.kitchen.yml similarity index 93% rename from nginx-light/.kitchen.yml rename to apt/.kitchen.yml index f63ccd3a..a950bb61 100644 --- a/nginx-light/.kitchen.yml +++ b/apt/.kitchen.yml @@ -28,7 +28,7 @@ suites: playbook: ./tests/test.yml verifier: patterns: - - nginx/tests/spec/nginx_light_spec.rb + - apt/tests/spec/main_spec.rb bundler_path: '/usr/local/bin' rspec_path: '/usr/local/bin' diff --git a/apt/README.md b/apt/README.md new file mode 100644 index 00000000..ec4da5b6 --- /dev/null +++ b/apt/README.md @@ -0,0 +1,57 @@ +# apt + +A few APT related operations, like easily install backports of change components for repositories. + +## Tasks + +Tasks are extracted in several files, included in `tasks/main.yml` : + +* `backports.yml` : add a sources list for backports ; +* `basics_components.yml` : replace components for the basic sources. + +## Available variables + +* `apt_install_basics` : change basic sources components (default: `True`) ; +* `apt_basics_components` : basic sources components (default: `main`) ; +* `apt_install_backports` : install backports sources (default: `False`) ; +* `apt_backports_components` : backports sources (default: `main`) ; +* `apt_install_evolix_public` : install Evolix public repositories (default: `True`). + +## Examples + +To add "non-free" and "contrib" components to basic sources lists : + +``` +{ role: apt, + apt_install_basics: True, + apt_basics_components: "main non-free contrib" +} +``` + +To install backports sources lists : + +``` +{ role: apt, + apt_install_backports: True +} +``` + +To install backports sources lists with "non-free" and "contrib" : + +``` +{ role: apt, + apt_install_backports: True, + apt_backports_components: "main non-free contrib" +} +``` + +To install backports sources lists and have "non-free" and "contrib" for each repository : + +``` +{ role: apt, + apt_install_basics: True, + apt_basics_components: "main non-free contrib", + apt_install_backports: True, + apt_backports_components: "main non-free contrib" +} +``` diff --git a/apt/defaults/main.yml b/apt/defaults/main.yml new file mode 100644 index 00000000..9e01a74e --- /dev/null +++ b/apt/defaults/main.yml @@ -0,0 +1,8 @@ +--- +apt_install_basics: True +apt_basics_components: "main" + +apt_install_backports: False +apt_backports_components: "main" + +apt_install_evolix_public: True diff --git a/apt-repositories/files/jessie_backports_preferences b/apt/files/jessie_backports_preferences similarity index 100% rename from apt-repositories/files/jessie_backports_preferences rename to apt/files/jessie_backports_preferences diff --git a/apt/files/reg.gpg b/apt/files/reg.gpg new file mode 100644 index 00000000..3fadeb07 --- /dev/null +++ b/apt/files/reg.gpg @@ -0,0 +1,920 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: SKS 1.1.6 +Comment: Hostname: keyserver.ubuntu.com + +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 +BWcdiQ== +=iUyJ +-----END PGP PUBLIC KEY BLOCK----- diff --git a/apt-repositories/files/stretch_backports_preferences b/apt/files/stretch_backports_preferences similarity index 100% rename from apt-repositories/files/stretch_backports_preferences rename to apt/files/stretch_backports_preferences diff --git a/apt-repositories/handlers/main.yml b/apt/handlers/main.yml similarity index 100% rename from apt-repositories/handlers/main.yml rename to apt/handlers/main.yml diff --git a/apt-repositories/meta/main.yml b/apt/meta/main.yml similarity index 100% rename from apt-repositories/meta/main.yml rename to apt/meta/main.yml diff --git a/apt-repositories/tasks/backports.yml b/apt/tasks/backports.yml similarity index 85% rename from apt-repositories/tasks/backports.yml rename to apt/tasks/backports.yml index f079a35b..fd459a34 100644 --- a/apt-repositories/tasks/backports.yml +++ b/apt/tasks/backports.yml @@ -5,31 +5,29 @@ regexp: "backports" state: absent tags: - - apt-repositories + - apt - name: Backports sources list is installed template: src: '{{ ansible_distribution_release }}_backports.list.j2' dest: /etc/apt/sources.list.d/backports.list force: yes - backup: yes mode: "0640" notify: apt update tags: - - apt-repositories + - apt - name: Backports configuration copy: src: '{{ ansible_distribution_release }}_backports_preferences' dest: /etc/apt/preferences.d/0-backports-defaults force: yes - backup: yes mode: "0640" notify: apt update tags: - - apt-repositories + - apt - name: Intermediate flush of handlers meta: flush_handlers tags: - - apt-repositories + - apt diff --git a/apt-repositories/tasks/basics.yml b/apt/tasks/basics.yml similarity index 82% rename from apt-repositories/tasks/basics.yml rename to apt/tasks/basics.yml index a6aa0f5c..5fefbbfc 100644 --- a/apt-repositories/tasks/basics.yml +++ b/apt/tasks/basics.yml @@ -6,12 +6,11 @@ dest: /etc/apt/sources.list mode: "0644" force: yes - backup: yes notify: apt update tags: - - apt-repositories + - apt - name: Intermediate flush of handlers meta: flush_handlers tags: - - apt-repositories + - apt diff --git a/apt-repositories/tasks/evolix_public.yml b/apt/tasks/evolix_public.yml similarity index 77% rename from apt-repositories/tasks/evolix_public.yml rename to apt/tasks/evolix_public.yml index 282255ba..5bfb3287 100644 --- a/apt-repositories/tasks/evolix_public.yml +++ b/apt/tasks/evolix_public.yml @@ -5,26 +5,25 @@ # msg: "Error: Evolix public repository is not compatble with 'Debian Stretch' yet." # when: ansible_distribution_release == "stretch" # tags: -# - apt-repositories +# - apt - name: Add Evolix GPG key apt_key: - keyserver: "hkp://keyserver.ubuntu.com:80" - id: 44975278B8612B5D + #url: http://keyserver.ubuntu.com/pks/lookup?op=get&search=0x44975278B8612B5D + data: "{{ lookup('file', 'reg.gpg') }}" - name: Evolix public list is installed template: src: evolix_public.list.j2 dest: /etc/apt/sources.list.d/evolix_public.list force: yes - backup: yes mode: "0640" notify: apt update tags: - - apt-repositories + - apt - name: Intermediate flush of handlers meta: flush_handlers tags: - - apt-repositories + - apt diff --git a/apt/tasks/main.yml b/apt/tasks/main.yml new file mode 100644 index 00000000..7bb8950e --- /dev/null +++ b/apt/tasks/main.yml @@ -0,0 +1,29 @@ +--- + +- fail: + msg: only compatible with Debian >= 8 + when: + - ansible_distribution != "Debian" or ansible_distribution_major_version | version_compare('8', '<') + tags: + - apt + +- name: Install basics repositories + include: basics.yml + when: apt_install_basics + tags: + - apt + +- name: Install APT Backports repository + include: backports.yml + when: apt_install_backports + tags: + - apt + +- debug: + var: apt_install_evolix_public + +- name: Install Evolix Public APT repository + include: evolix_public.yml + when: apt_install_evolix_public + tags: + - apt diff --git a/apt-repositories/templates/evolix_public.list.j2 b/apt/templates/evolix_public.list.j2 similarity index 100% rename from apt-repositories/templates/evolix_public.list.j2 rename to apt/templates/evolix_public.list.j2 diff --git a/apt/templates/jessie_backports.list.j2 b/apt/templates/jessie_backports.list.j2 new file mode 100644 index 00000000..cba40470 --- /dev/null +++ b/apt/templates/jessie_backports.list.j2 @@ -0,0 +1,3 @@ +# {{ ansible_managed }} + +deb http://mirror.evolix.org/debian jessie-backports {{ apt_backports_components | mandatory }} diff --git a/apt/templates/jessie_basics.list.j2 b/apt/templates/jessie_basics.list.j2 new file mode 100644 index 00000000..684b7bb3 --- /dev/null +++ b/apt/templates/jessie_basics.list.j2 @@ -0,0 +1,5 @@ +# {{ ansible_managed }} + +deb http://mirror.evolix.org/debian/ jessie {{ apt_basics_components | mandatory }} +deb http://mirror.evolix.org/debian/ jessie-updates {{ apt_basics_components | mandatory }} +deb http://security.debian.org/ jessie/updates {{ apt_basics_components | mandatory }} diff --git a/apt/templates/stretch_backports.list.j2 b/apt/templates/stretch_backports.list.j2 new file mode 100644 index 00000000..4f69547d --- /dev/null +++ b/apt/templates/stretch_backports.list.j2 @@ -0,0 +1,3 @@ +# {{ ansible_managed }} + +deb http://mirror.evolix.org/debian stretch-backports {{ apt_backports_components | mandatory }} diff --git a/apt/templates/stretch_basics.list.j2 b/apt/templates/stretch_basics.list.j2 new file mode 100644 index 00000000..2f0bf99e --- /dev/null +++ b/apt/templates/stretch_basics.list.j2 @@ -0,0 +1,5 @@ +# {{ ansible_managed }} + +deb http://mirror.evolix.org/debian stretch {{ apt_basics_components | mandatory }} +deb http://mirror.evolix.org/debian/ stretch-updates {{ apt_basics_components | mandatory }} +deb http://security.debian.org/debian-security stretch/updates {{ apt_basics_components | mandatory }} diff --git a/apt-repositories/tests/spec/main_spec.rb b/apt/tests/spec/main_spec.rb similarity index 100% rename from apt-repositories/tests/spec/main_spec.rb rename to apt/tests/spec/main_spec.rb diff --git a/apt/tests/test.yml b/apt/tests/test.yml new file mode 100644 index 00000000..fce03b45 --- /dev/null +++ b/apt/tests/test.yml @@ -0,0 +1,10 @@ +--- +- hosts: test-kitchen + + vars: + apt_basics_components: "main contrib non-free" + apt_install_backports: True + apt_backports_components: "main contrib non-free" + + roles: + - role: apt diff --git a/bind/README.md b/bind/README.md index a802498e..53f693a8 100644 --- a/bind/README.md +++ b/bind/README.md @@ -9,3 +9,5 @@ Minimal configuration is in `tasks/main.yml` ## Available variables The full list of variables (with default values) can be found in `defaults/main.yml`. + +waening : sync chroot-bind.sh diff --git a/bind/defaults/main.yml b/bind/defaults/main.yml index 52c6ac66..b7bc2090 100644 --- a/bind/defaults/main.yml +++ b/bind/defaults/main.yml @@ -1,6 +1,9 @@ --- +bind_recursive_server: False +bind_authoritative_server: True +bind_chroot_set: True +bind_chroot_path: /var/chroot-bind bind_systemd_service_path: /etc/systemd/system/bind9.service -bind_chroot_root: /var/chroot-bind bind_statistics_file: /var/run/named.stats bind_log_file: /var/log/bind.log -bind_query_file: /var/log/query.log +bind_query_file: /var/log/bind_queries.log diff --git a/bind/files/chroot-bind.sh b/bind/files/chroot-bind.sh new file mode 100644 index 00000000..08c665e8 --- /dev/null +++ b/bind/files/chroot-bind.sh @@ -0,0 +1,76 @@ +#!/bin/sh + +# Gregory Colpart +# chroot (or re-chroot) script for bind9 + +# tested on Debian Wheezy/Jessie/Stretch +# Exec this script after `(apt-get|aptitude|apt) install bind9` +# and after *each* bind9 upgrade + +# When the script is finished, ensure you have +# 'OPTIONS="-u bind -t /var/chroot-bind"' in /etc/default/bind9 +# and /etc/init.d/bind9 (re)start +# +# for Jessie/systemd only: +# cp -a /lib/systemd/system/bind9.service /etc/systemd/system/ +# and modify section [Service] to have : +# EnvironmentFile=-/etc/default/bind9 +# ExecStart=/usr/sbin/named -f $OPTIONS + +# essential dirs +mkdir -p /var/chroot-bind +mkdir -p /var/chroot-bind/bin /var/chroot-bind/dev /var/chroot-bind/etc \ + /var/chroot-bind/lib /var/chroot-bind/usr/lib \ + /var/chroot-bind/usr/sbin /var/chroot-bind/var/cache/bind \ + /var/chroot-bind/var/log /var/chroot-bind/var/run/named/ \ + /var/chroot-bind/run/named/ + +# for conf +if [ ! -h "/etc/bind" ]; then + mv /etc/bind/ /var/chroot-bind/etc/ + ln -s /var/chroot-bind/etc/bind/ /etc/bind +fi + +# for logs +touch /var/chroot-bind/var/log/bind.log +if [ ! -h "/var/log/bind.log" ]; then + ln -s /var/chroot-bind/var/log/bind.log /var/log/bind.log +fi + +# for pid +if [ -f "/var/run/named/named.pid" ]; then + cat /var/run/named/named.pid > /var/chroot-bind/var/run/named/named.pid + rm -f /var/run/named/named.pid +fi + +if [ ! -e "/var/chroot-bind/dev/random" ]; then + mknod /var/chroot-bind/dev/random c 1 8 + chmod 666 /var/chroot-bind/dev/random +fi + +if [ ! -e "/var/chroot-bind/dev/urandom" ]; then + mknod /var/chroot-bind/dev/urandom c 1 9 + chmod 666 /var/chroot-bind/dev/urandom +fi + +# essential dev (hum, null is required ??) +#mknod /var/chroot-bind/dev/null c 1 3 +#chmod 666 /var/chroot-bind/dev/{null,random} + +# essential libs +for i in `ldd $(which named) | grep -v linux-vdso.so.1 | cut -d">" -f2 | cut -d"(" -f1` \ + /usr/lib/x86_64-linux-gnu/openssl-1.0.*/engines/libgost.so ; do + install -D $i /var/chroot-bind/${i##/} +done + +# essential (hum, bash is required ??) +#cp /bin/bash /var/chroot-bind/bin/ +cp /usr/sbin/named /var/chroot-bind/usr/sbin/ + +# minimal passwd & group file (hum, is required ??) +#grep "bind\|root" /etc/passwd > /var/chroot-bind/etc/passwd +#grep "bind\|root" /etc/group > /var/chroot-bind/etc/group + +# just bind +chown -R bind.bind /var/chroot-bind/ + diff --git a/bind/handlers/main.yml b/bind/handlers/main.yml index 4bc9719f..1eee71f6 100644 --- a/bind/handlers/main.yml +++ b/bind/handlers/main.yml @@ -1,4 +1,7 @@ --- +- name: reload systemd + command: systemctl daemon-reload + - name: restart bind service: name: bind9 @@ -9,4 +12,3 @@ name: munin-node state: restarted - diff --git a/bind/tasks/main.yml b/bind/tasks/main.yml index 2c8e0278..1d190135 100644 --- a/bind/tasks/main.yml +++ b/bind/tasks/main.yml @@ -1,25 +1,40 @@ -- name: Ensure bind9 installed +- name: package are installed apt: - name: bind9 + name: '{{ item }}' state: present + with_items: + - bind9 + - dnstop -- name: Set bind configuration +- name: Set bind configuration for recursive server template: - src: named.conf.options.j2 + src: named.conf.options_recursive.j2 dest: /etc/bind/named.conf.options owner: bind group: bind mode: "0644" force: yes - backup: yes notify: restart bind + when: bind_recursive_server -- name: Modify OPTIONS in /etc/default/bind9 - replace: - dest: /etc/default/bind9 - regexp: '^OPTIONS=.*' - replace: 'OPTIONS="-u bind -t {{ bind_chroot_root }}"' +- name: enable zones.rfc1918 for recursive server + lineinfile: + dest: /etc/bind/named.conf.local + line: 'include "/etc/bind/zones.rfc1918";' + regexp: "zones.rfc1918" notify: restart bind + when: bind_recursive_server + +- name: Set bind configuration for authoritative server + template: + src: named.conf.options_authoritative.j2 + dest: /etc/bind/named.conf.options + owner: bind + group: bind + mode: "0644" + force: yes + notify: restart bind + when: bind_authoritative_server - name: Create systemd service template: @@ -29,175 +44,78 @@ group: root mode: "0644" force: yes - backup: yes - notify: restart bind + notify: + - reload systemd + - restart bind + when: ansible_distribution_release == "jessie" -- name: Create directories +- name: touch /var/log/bind.log if non chroot file: - path: "{{ bind_chroot_root }}/{{ item }}" - state: directory + path: /var/log/bind.log owner: bind - group: bind - mode: "0700" - recurse: no - with_items: - - bin - - dev - - etc - - lib - - usr/lib - - usr/sbin - - var/cache/bind - - var/log - - var/run/bind/run - register: create_bind_dir - notify: restart bind - -- name: Stat /etc/bind - stat: - path: "/etc/bind" - check_mode: no - register: etc_bind - -- name: Move /etc/bind in chroot - command: "mv /etc/bind/ {{ bind_chroot_root }}/etc/" - when: etc_bind.stat.exists and not etc_bind.stat.islnk - notify: restart bind - -- name: Create symlink - file: - src: "{{ bind_chroot_root }}/etc/bind" - dest: "/etc/bind" - state: link - notify: restart bind - -- name: is there a log file? - stat: - path: "{{ bind_chroot_root }}/var/log/bind.log" - register: bind_log - -- name: create log file - file: - path: "{{ bind_chroot_root }}/var/log/bind.log" - state: touch - when: not bind_log.stat.exists - -- name: verify log file permissions - file: - path: "{{ bind_chroot_root }}/var/log/bind.log" - owner: bind - group: bind + group: adm mode: "0640" - state: file + state: touch + when: bind_chroot_set == False -- name: Create log symlink +- name: touch /var/log/bind_queries.log if non chroot file: - src: "{{ bind_chroot_root }}/var/log/bind.log" - dest: "/var/log/bind.log" - state: link - notify: restart bind - -- name: Create run directory - file: - path: "/var/run/bind/run" - state: directory - owner: root - group: bind - mode: "0770" - recurse: yes - notify: restart bind - -- name: "Stat var/run/bind/run/named in chroot" - stat: - path: "{{ bind_chroot_root }}/var/run/bind/run/named" - check_mode: no - register: named_run - -- name: "Clean var/run/bind/run/named in chroot" - file: - path: "{{ bind_chroot_root }}/var/run/bind/run/named" - state: absent - when: named_run.stat.exists and named_run.stat.isdir - -- name: Clean /var/run/bind/run/named.pid - file: - path: "/var/run/bind/run/named.pid" - state: absent - when: named_run.stat.exists and named_run.stat.isdir - -- name: Stat /var/run/bind/run/named.pid - stat: - path: "/var/run/bind/run/named.pid" - check_mode: no - register: named_pid - -- name: Cat pid content - command: "cat /var/run/bind/run/named.pid > {{ bind_chroot_root }}/var/run/bind/run/named.pid" - when: named_pid.stat.exists and named_pid.stat.isreg and not named_pid.stat.islnk - -- name: Clean /var/run/bind/run/named.pid - file: - path: "/var/run/bind/run/named.pid" - state: absent - when: named_pid.stat.exists and named_pid.stat.isreg and not named_pid.stat.islnk - -- name: Clean /var/run/bind/run/named.pid - file: - path: "/var/run/bind/run/named.pid" - state: absent - when: named_pid.stat.exists and not named_pid.stat.islnk - -- name: Create pid symlink in chroot - file: - src: "{{ bind_chroot_root }}/var/run/bind/run/named.pid" - dest: "/var/run/bind/run/named.pid" - state: link - when: named_pid.stat.exists and not named_pid.stat.islnk - notify: restart bind - -- name: "Stat dev/random in chroot" - stat: - path: "{{ bind_chroot_root }}/dev/random" - check_mode: no - register: named_random - -- name: clean dev/random in chroot - shell: "mv {{ bind_chroot_root }}/dev/random {{ bind_chroot_root }}/dev/random.$(date +%s)" - when: named_random.stat.exists and not named_random.stat.ischr - -- name: mknod dev/random in chroot - command: "mknod -m 666 {{ bind_chroot_root }}/dev/random c 1 3" - args: - creates: "{{ bind_chroot_root }}/dev/random" - notify: restart bind - -- name: get essential libraries - shell: 'ldd $(which named) | grep -v linux-vdso.so.1 | cut -d">" -f2 | cut -d"(" -f1 | grep -oE "\S+"' - register: bind_ldd - check_mode: no - changed_when: False - -- name: copy essential libs - command: "install -D {{ item }} {{ bind_chroot_root }}{{ item }}" - args: - creates: "{{ bind_chroot_root }}{{ item }}" - with_items: - - "{{ bind_ldd.stdout_lines }}" - - /usr/lib/x86_64-linux-gnu/openssl-1.0.0/engines/libgost.so - register: install_libraries - notify: restart bind - -- name: Copy bind - copy: - src: /usr/sbin/named - dest: "{{ bind_chroot_root }}/usr/sbin/" - remote_src: True - notify: restart bind - -- name: Set the good rights - file: - path: "{{ bind_chroot_root }}" + path: /var/log/bind_queries.log owner: bind - group: bind - recurse: yes + group: adm + mode: "0640" + state: touch + when: bind_authoritative_server and bind_chroot_set == False + +- name: send chroot-bind.sh in /root + copy: + src: chroot-bind.sh + dest: /root/chroot-bind.sh + mode: "0700" + owner: root + force: yes + backup: yes + when: bind_chroot_set + +- name: exec chroot-bind.sh + command: "/root/chroot-bind.sh" + register: chrootbind_run + changed_when: False + check_mode: no + when: bind_chroot_set + +- debug: + var: chrootbind_run.stdout_lines + when: bind_chroot_set and chrootbind_run.stdout != "" + +- name: Modify OPTIONS in /etc/default/bind9 for chroot + replace: + dest: /etc/default/bind9 + regexp: '^OPTIONS=.*' + replace: 'OPTIONS="-u bind -t {{ bind_chroot_path }}"' notify: restart bind + when: bind_chroot_set + +- name: logrotate for non chroot bind + template: + src: logrotate_bind + dest: /etc/logrotate.d/bind + owner: root + group: root + mode: "0644" + force: yes + notify: restart bind + when: bind_chroot_set == False + +- name: logrotate for chroot bind + template: + src: logrotate_bind_chroot.j2 + dest: /etc/logrotate.d/bind + owner: root + group: root + mode: "0644" + force: yes + notify: restart bind + when: bind_chroot_set + + diff --git a/bind/tasks/munin.yml b/bind/tasks/munin.yml index 51ee9b64..a31e6b06 100644 --- a/bind/tasks/munin.yml +++ b/bind/tasks/munin.yml @@ -1,4 +1,4 @@ ---- +--- - name: is Munin present ? stat: @@ -8,32 +8,32 @@ tags: - bind - munin + when: bind_authoritative_server - name: Enable munin plugins file: src: "/usr/share/munin/plugins/{{ item }}" dest: "/etc/munin/plugins/{{ item }}" state: link - with_items: + with_items: - bind9 - bind9_rndc - notify: restart munin - when: munin_node_plugins_config.stat.exists + notify: restart munin-node + when: bind_authoritative_server and munin_node_plugins_config.stat.exists tags: - bind - munin - name: Add munin plugin configuration template: - src: bind9.j2 + src: munin-env_bind9.j2 dest: /etc/munin/plugin-conf.d/bind9 owner: root group: root mode: "0644" force: yes - backup: yes - notify: restart munin - when: munin_node_plugins_config.stat.exists + notify: restart munin-node + when: bind_authoritative_server and munin_node_plugins_config.stat.exists tags: - bind - munin diff --git a/bind/templates/bind9.j2 b/bind/templates/bind9.j2 deleted file mode 100644 index 1eb1eaea..00000000 --- a/bind/templates/bind9.j2 +++ /dev/null @@ -1,6 +0,0 @@ -[bind*] -user root -env.logfile {{ bind_query_file }} -env.querystats /var/chroot-bind{{ bind_statistics_file }} -env.MUNIN_PLUGSTATE /var/lib/munin -timeout 120 diff --git a/bind/templates/bind9.service.j2 b/bind/templates/bind9.service.j2 index e0906300..f43d448b 100644 --- a/bind/templates/bind9.service.j2 +++ b/bind/templates/bind9.service.j2 @@ -1,5 +1,3 @@ -# {{ ansible_managed }} - [Unit] Description=BIND Domain Name Server Documentation=man:named(8) diff --git a/bind/templates/logrotate_bind b/bind/templates/logrotate_bind new file mode 100644 index 00000000..d1471fcb --- /dev/null +++ b/bind/templates/logrotate_bind @@ -0,0 +1,10 @@ +/var/log/bind.log { + weekly + missingok + rotate 8 + create 640 bind bind + sharedscripts + postrotate + rndc reload > /dev/null + endscript +} diff --git a/bind/templates/logrotate_bind_chroot.j2 b/bind/templates/logrotate_bind_chroot.j2 new file mode 100644 index 00000000..5db5d494 --- /dev/null +++ b/bind/templates/logrotate_bind_chroot.j2 @@ -0,0 +1,10 @@ +{{ bind_chroot_path }}/var/log/bind.log { + weekly + missingok + rotate 52 + create 640 bind bind + sharedscripts + postrotate + rndc reload > /dev/null + endscript +} diff --git a/bind/templates/munin-env_bind9.j2 b/bind/templates/munin-env_bind9.j2 new file mode 100644 index 00000000..f1d4b41e --- /dev/null +++ b/bind/templates/munin-env_bind9.j2 @@ -0,0 +1,6 @@ +[bind*] +user root +env.logfile {{ bind_query_file }} +env.querystats {{ bind_chroot_path }}{{ bind_statistics_file }} +env.MUNIN_PLUGSTATE /var/lib/munin +timeout 120 diff --git a/bind/templates/named.conf.options.j2 b/bind/templates/named.conf.options.j2 deleted file mode 100644 index 7ffa4aeb..00000000 --- a/bind/templates/named.conf.options.j2 +++ /dev/null @@ -1,56 +0,0 @@ -options { - directory "/var/cache/bind"; - - // If there is a firewall between you and nameservers you want - // to talk to, you may need to fix the firewall to allow multiple - // ports to talk. See http://www.kb.cert.org/vuls/id/800113 - - // If your ISP provided one or more IP addresses for stable - // nameservers, you probably want to use them as forwarders. - // Uncomment the following block, and insert the addresses replacing - // the all-0's placeholder. - - // forwarders { - // 0.0.0.0; - // }; - - version "Bingo"; - - auth-nxdomain no; # conform to RFC1035 - //listen-on-v6 { ::1; }; - //listen-on { 127.0.0.1; }; - - allow-query { localhost;}; - allow-transfer { localhost; }; - allow-recursion { localhost; }; - - statistics-file "/var/run/named.stats"; -}; - -logging { - //category default { default_syslog; default_debug; }; - category default { default_debug; }; - - channel default_syslog { - syslog daemon; - severity info; - }; - - channel default_debug { - file "/var/log/bind.log"; - severity debug; - }; - channel query { - file "/var/log/query.log" versions 2 size 1m; - print-time yes; - severity info; - }; - category queries { query; }; -}; - -//key "external" { -// algorithm hmac-md5; -// secret "UOQfHEoBzBSC6sD4mwfxLw=="; -//}; -// -//server 85.118.59.1 { keys external; }; diff --git a/bind/templates/named.conf.options_authoritative.j2 b/bind/templates/named.conf.options_authoritative.j2 new file mode 100644 index 00000000..04ab2551 --- /dev/null +++ b/bind/templates/named.conf.options_authoritative.j2 @@ -0,0 +1,35 @@ +acl "foo" { + ::ffff:192.0.2.21; 192.0.2.21; + 2001:db8::21; +}; + +options { + directory "/var/cache/bind"; + version "Bingo"; + auth-nxdomain no; + masterfile-format text; + statistics-file "/var/run/named.stats"; + + listen-on-v6 { any; }; + listen-on { any; }; + + allow-query { localhost; }; + allow-recursion { localhost; }; + allow-transfer { localhost; }; +}; + +logging { + category default { default_file; }; + category queries { query_logging; }; + + channel default_file { + file "/var/log/bind.log"; + severity info; + }; + channel query_logging { + file "/var/log/bind_queries.log" versions 2 size 128M; + print-category yes; + print-severity yes; + print-time yes; + }; +}; diff --git a/bind/templates/named.conf.options_recursive.j2 b/bind/templates/named.conf.options_recursive.j2 new file mode 100644 index 00000000..555230d0 --- /dev/null +++ b/bind/templates/named.conf.options_recursive.j2 @@ -0,0 +1,16 @@ +options { + directory "/var/cache/bind"; + version "Bingo"; + auth-nxdomain no; + listen-on-v6 { ::1; }; + listen-on { 127.0.0.1; }; + allow-recursion { ::1; 127.0.0.1; }; +}; + +logging { + category default { default_file; }; + channel default_file { + file "/var/log/bind.log"; + severity info; + }; +}; diff --git a/clamav/.kitchen.yml b/clamav/.kitchen.yml deleted file mode 100644 index c2afb64d..00000000 --- a/clamav/.kitchen.yml +++ /dev/null @@ -1,27 +0,0 @@ ---- -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 -suites: - - name: default - provisioner: - name: ansible_playbook - playbook: ./tests/test.yml - -transport: - max_ssh_sessions: 6 diff --git a/clamav/handlers/main.yml b/clamav/handlers/main.yml deleted file mode 100644 index 4f445b18..00000000 --- a/clamav/handlers/main.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- -- name: restart clamav-daemon - service: - name: clamav-daemon - state: restarted -- name: restart clamav-freshclam - service: - name: clamav-freshclam - state: restarted diff --git a/clamav/meta/main.yml b/clamav/meta/main.yml deleted file mode 100644 index 732965a4..00000000 --- a/clamav/meta/main.yml +++ /dev/null @@ -1,19 +0,0 @@ -galaxy_info: - author: Evolix - description: Installation and basic configuration of clamav. - - issue_tracker_url: https://forge.evolix.org/projects/ansible-roles/issues - - license: GPLv2 - - min_ansible_version: 2.2 - - platforms: - - name: Debian - versions: - - jessie - -dependencies: [] - # List your role dependencies here, one per line. - # Be sure to remove the '[]' above if you add dependencies - # to this list. diff --git a/clamav/tasks/main.yml b/clamav/tasks/main.yml deleted file mode 100644 index 88b0ba99..00000000 --- a/clamav/tasks/main.yml +++ /dev/null @@ -1,7 +0,0 @@ -- name: ensure packages are installed - apt: - name: '{{ item }}' - state: present - with_items: - - clamav-daemon - - clamav-freshclam diff --git a/clamav/tests/test.yml b/clamav/tests/test.yml deleted file mode 100644 index 91b1f55f..00000000 --- a/clamav/tests/test.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -- hosts: test-kitchen - roles: - - role: clamav diff --git a/courier/README.md b/courier/README.md deleted file mode 100644 index b743ab4c..00000000 --- a/courier/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Courier - -Installation and basic configuration of courier. - -## 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`. diff --git a/courier/defaults/main.yml b/courier/defaults/main.yml deleted file mode 100644 index ed97d539..00000000 --- a/courier/defaults/main.yml +++ /dev/null @@ -1 +0,0 @@ ---- diff --git a/courier/handlers/main.yml b/courier/handlers/main.yml deleted file mode 100644 index 6f71b11f..00000000 --- a/courier/handlers/main.yml +++ /dev/null @@ -1,25 +0,0 @@ ---- -- name: restart courier-authdaemon - service: - name: courier-authdaemon - state: restarted -- name: restart courier-imap - service: - name: courier-imap - state: restarted -- name: restart courier-imap-ssl - service: - name: courier-imap-ssl - state: restarted -- name: restart courier-ldap - service: - name: courier-ldap - state: restarted -- name: restart courier-pop - service: - name: courier-pop - state: restarted -- name: restart courier-pop-ssl - service: - name: courier-pop-ssl - state: restarted diff --git a/courier/meta/main.yml b/courier/meta/main.yml deleted file mode 100644 index b7605b2d..00000000 --- a/courier/meta/main.yml +++ /dev/null @@ -1,19 +0,0 @@ -galaxy_info: - author: Evolix - description: Installation and basic configuration of courier. - - issue_tracker_url: https://forge.evolix.org/projects/ansible-roles/issues - - license: GPLv2 - - min_ansible_version: 2.2 - - platforms: - - name: Debian - versions: - - jessie - -dependencies: [] - # List your role dependencies here, one per line. - # Be sure to remove the '[]' above if you add dependencies - # to this list. diff --git a/courier/tasks/main.yml b/courier/tasks/main.yml deleted file mode 100644 index 59212743..00000000 --- a/courier/tasks/main.yml +++ /dev/null @@ -1,17 +0,0 @@ -- name: ensure packages are installed - apt: - name: '{{ item }}' - state: present - with_items: - - courier-authdaemon - - courier-authlib - - courier-authlib-ldap - - courier-authlib-userdb - - courier-base - - courier-imap - - courier-imap-ssl - - courier-ldap - - courier-pop - - courier-pop-ssl - - courier-ssl - diff --git a/courier/tests/test.yml b/courier/tests/test.yml deleted file mode 100644 index 288625cb..00000000 --- a/courier/tests/test.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -- hosts: test-kitchen - roles: - - role: courier diff --git a/dhcp/defaults/main.yml b/dhcp/defaults/main.yml deleted file mode 100644 index ed97d539..00000000 --- a/dhcp/defaults/main.yml +++ /dev/null @@ -1 +0,0 @@ ---- diff --git a/amavis/.kitchen.yml b/dhcpd/.kitchen.yml similarity index 100% rename from amavis/.kitchen.yml rename to dhcpd/.kitchen.yml diff --git a/dhcp/README.md b/dhcpd/README.md similarity index 100% rename from dhcp/README.md rename to dhcpd/README.md diff --git a/amavis/defaults/main.yml b/dhcpd/defaults/main.yml similarity index 100% rename from amavis/defaults/main.yml rename to dhcpd/defaults/main.yml diff --git a/dhcp/handlers/main.yml b/dhcpd/handlers/main.yml similarity index 100% rename from dhcp/handlers/main.yml rename to dhcpd/handlers/main.yml diff --git a/dhcp/meta/main.yml b/dhcpd/meta/main.yml similarity index 100% rename from dhcp/meta/main.yml rename to dhcpd/meta/main.yml diff --git a/dhcp/tasks/main.yml b/dhcpd/tasks/main.yml similarity index 100% rename from dhcp/tasks/main.yml rename to dhcpd/tasks/main.yml diff --git a/dhcp/tests/test.yml b/dhcpd/tests/test.yml similarity index 100% rename from dhcp/tests/test.yml rename to dhcpd/tests/test.yml diff --git a/docker-host/files/docker-debian.gpg b/docker-host/files/docker-debian.gpg new file mode 100644 index 00000000..ee7872e5 --- /dev/null +++ b/docker-host/files/docker-debian.gpg @@ -0,0 +1,62 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +YT90qFF93M3v01BbxP+EIY2/9tiIPbrd +=0YYh +-----END PGP PUBLIC KEY BLOCK----- diff --git a/haproxy-backports-preferences/files/haproxy_preferences b/docker-host/files/docker_preferences similarity index 68% rename from haproxy-backports-preferences/files/haproxy_preferences rename to docker-host/files/docker_preferences index 18de5cea..1a68427d 100644 --- a/haproxy-backports-preferences/files/haproxy_preferences +++ b/docker-host/files/docker_preferences @@ -1,3 +1,3 @@ -Package: haproxy +Package: python-docker Pin: release a=jessie-backports Pin-Priority: 999 diff --git a/docker-host/tasks/jessie_backports.yml b/docker-host/tasks/jessie_backports.yml new file mode 100644 index 00000000..727ee7c8 --- /dev/null +++ b/docker-host/tasks/jessie_backports.yml @@ -0,0 +1,23 @@ +--- +- include_role: + name: apt + tasks_from: backports.yml + tags: + - packages + +- name: Prefer python-docker package from jessie-backports + copy: + src: docker_preferences + dest: /etc/apt/preferences.d/999-docker + force: yes + mode: "0640" + register: docker_apt_preferences + tags: + - packages + +- name: update apt + apt: + update_cache: yes + when: docker_apt_preferences | changed + tags: + - packages diff --git a/docker-host/tasks/main.yml b/docker-host/tasks/main.yml index 1bcd7810..f468404c 100644 --- a/docker-host/tasks/main.yml +++ b/docker-host/tasks/main.yml @@ -1,44 +1,62 @@ # This role installs the docker daemon --- -- name: Install apt-transport-https +- name: Remove older docker packages apt: - name: apt-transport-https + name: '{{ item }}' + state: absent + with_items: + - docker + - docker-engine + - docker.io + +- name: Install source requirements + apt: + name: '{{ item }}' state: present update_cache: yes + with_items: + - apt-transport-https + - ca-certificates + - gnupg2 -- name: Enable Docker repositories +- name: Add Docker repository apt_repository: - repo: 'deb https://apt.dockerproject.org/repo debian-{{ ansible_distribution_release }} main' + repo: 'deb [arch=amd64] https://download.docker.com/linux/debian {{ ansible_distribution_release }} stable' state: present update_cache: no + filename: docker.list -- name: Enable backports repository for docker-py - apt_repository: - repo: 'deb http://ftp.debian.org/debian {{ ansible_distribution_release }}-backports main' - state: present +- include: jessie_backports.yml + when: ansible_distribution_release == 'jessie' -- name: Install Docker repo keys +- name: Add Docker's official GPG key apt_key: - keyserver: pgp.mit.edu - id: 58118E89F3A912897C070ADBF76221572C52609D + #url: https://download.docker.com/linux/debian/gpg + data: "{{ lookup('file', 'docker-debian.gpg') }}" -- name: Install docker and docker-py +- name: Install docker and python-docker apt: name: "{{ item }}" state: latest update_cache: yes with_items: - - docker-engine + - docker-ce - python-docker -- name: Configure docker service +- name: Copy Docker daemon configuration file template: - src: docker.service.j2 - dest: /lib/systemd/system/docker.service + src: daemon.json.j2 + dest: /etc/docker/daemon.json notify: - reload systemd - restart docker +- name: Remove options from docker systemd service + lineinfile: + dest: /lib/systemd/system/docker.service + regexp: '^ExecStart=' + line: 'ExecStart=/usr/bin/dockerd' + - name: Creating Docker tmp directory file: path: "{{ docker_tmpdir }}" @@ -52,7 +70,7 @@ state: directory mode: "0644" owner: root - when: "{{ docker_tls_enabled }}" + when: docker_tls_enabled - name: Copy shellpki utility to Docker TLS directory template: @@ -62,8 +80,13 @@ with_items: - shellpki.sh - openssl.cnf - when: "{{ docker_tls_enabled }}" + when: docker_tls_enabled + +- name: Check if certs are already created + stat: + path: "{{ docker_tls_path }}/certs" + register: tls_certs_stat - name: Creating a CA, server key command: "{{ docker_tls_path }}/shellpki.sh init" - when: "{{ docker_tls_enabled }}" + when: docker_tls_enabled and not tls_certs_stat.stat.isdir is defined diff --git a/docker-host/templates/daemon.json.j2 b/docker-host/templates/daemon.json.j2 new file mode 100644 index 00000000..ab6cac19 --- /dev/null +++ b/docker-host/templates/daemon.json.j2 @@ -0,0 +1,16 @@ +{ + "debug": false + {% if docker_tls_enabled %} + , + "tls": true, + "tlscert": "{{ docker_tls_path }}/{{ docker_tls_cert }}", + "tlscacert": "{{ docker_tls_path }}/{{ docker_tls_ca }}", + "tlskey": "{{ docker_tls_path }}/{{ docker_tls_key }}" + {% endif %} + , + {% if docker_remote_access_enabled %} + "hosts": ["tcp://{{ docker_daemon_listening_ip }}:{{ docker_daemon_port }}", "fd://"] + {% else %} + "hosts": ["fd://"] + {% endif %} +} diff --git a/docker-host/templates/docker.service.j2 b/docker-host/templates/docker.service.j2 deleted file mode 100644 index 02229fd8..00000000 --- a/docker-host/templates/docker.service.j2 +++ /dev/null @@ -1,27 +0,0 @@ -# {{ ansible_managed }} - -[Unit] -Description=Docker Application Container Engine -Documentation=https://docs.docker.com -After=network.target docker.socket -Requires=docker.socket - -[Service] -ExecStart=/usr/bin/docker daemon -H fd:// \ - {% if docker_tls_enabled %} - --tlsverify \ - --tlscacert={{ docker_tls_path }}/{{ docker_tls_ca }} \ - --tlscert={{ docker_tls_path }}/{{ docker_tls_cert }} \ - --tlskey={{ docker_tls_path }}/{{ docker_tls_key }} \ - {% endif %} - {% if docker_remote_access_enabled %} - -H tcp://{{ docker_daemon_listening_ip }}:{{ docker_daemon_port }} - {% endif %} -MountFlags=slave -LimitNOFILE=1048576 -LimitNPROC=1048576 -LimitCORE=infinity -Environment="TMPDIR={{ docker_tmpdir }}" - -[Install] -WantedBy=multi-user.target diff --git a/drbd-utils/.kitchen.yml b/drbd-utils/.kitchen.yml deleted file mode 100644 index b21cc3db..00000000 --- a/drbd-utils/.kitchen.yml +++ /dev/null @@ -1,28 +0,0 @@ ---- -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 - -suites: - - name: default - provisioner: - name: ansible_playbook - playbook: ./tests/test.yml - -transport: - max_ssh_sessions: 6 diff --git a/ansible-managed/.kitchen.yml b/drbd/.kitchen.yml similarity index 100% rename from ansible-managed/.kitchen.yml rename to drbd/.kitchen.yml diff --git a/drbd-utils/README.md b/drbd/README.md similarity index 100% rename from drbd-utils/README.md rename to drbd/README.md diff --git a/drbd-utils/files/munin/drbd-config b/drbd/files/munin/drbd-config similarity index 100% rename from drbd-utils/files/munin/drbd-config rename to drbd/files/munin/drbd-config diff --git a/drbd-utils/files/munin/drbd-plugin b/drbd/files/munin/drbd-plugin similarity index 100% rename from drbd-utils/files/munin/drbd-plugin rename to drbd/files/munin/drbd-plugin diff --git a/drbd-utils/files/nagios/check_drbd b/drbd/files/nagios/check_drbd similarity index 100% rename from drbd-utils/files/nagios/check_drbd rename to drbd/files/nagios/check_drbd diff --git a/drbd-utils/handlers/main.yml b/drbd/handlers/main.yml similarity index 100% rename from drbd-utils/handlers/main.yml rename to drbd/handlers/main.yml diff --git a/drbd-utils/meta/main.yml b/drbd/meta/main.yml similarity index 100% rename from drbd-utils/meta/main.yml rename to drbd/meta/main.yml diff --git a/drbd-utils/tasks/main.yml b/drbd/tasks/main.yml similarity index 100% rename from drbd-utils/tasks/main.yml rename to drbd/tasks/main.yml diff --git a/drbd-utils/tasks/munin.yml b/drbd/tasks/munin.yml similarity index 100% rename from drbd-utils/tasks/munin.yml rename to drbd/tasks/munin.yml diff --git a/drbd-utils/tasks/nagios.yml b/drbd/tasks/nagios.yml similarity index 100% rename from drbd-utils/tasks/nagios.yml rename to drbd/tasks/nagios.yml diff --git a/drbd-utils/tasks/packages.yml b/drbd/tasks/packages.yml similarity index 100% rename from drbd-utils/tasks/packages.yml rename to drbd/tasks/packages.yml diff --git a/drbd-utils/tests/test.yml b/drbd/tests/test.yml similarity index 100% rename from drbd-utils/tests/test.yml rename to drbd/tests/test.yml diff --git a/elastic-sources-list/.kitchen.yml b/elastic-sources-list/.kitchen.yml deleted file mode 100644 index b21cc3db..00000000 --- a/elastic-sources-list/.kitchen.yml +++ /dev/null @@ -1,28 +0,0 @@ ---- -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 - -suites: - - name: default - provisioner: - name: ansible_playbook - playbook: ./tests/test.yml - -transport: - max_ssh_sessions: 6 diff --git a/elastic-sources-list/README.md b/elastic-sources-list/README.md deleted file mode 100644 index 7ed88d17..00000000 --- a/elastic-sources-list/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# elastic-source-list - -Install Elastic sources list for APT. - -## Tasks - -Everything is in the `tasks/main.yml` file. - -## Available variables diff --git a/elastic-sources-list/meta/main.yml b/elastic-sources-list/meta/main.yml deleted file mode 100644 index 3be58c98..00000000 --- a/elastic-sources-list/meta/main.yml +++ /dev/null @@ -1,28 +0,0 @@ -galaxy_info: - author: Evolix - description: Install Elastic sources list for APT. - - issue_tracker_url: https://forge.evolix.org/projects/ansible-roles/issues - - license: GPLv2 - - min_ansible_version: 2.2 - - platforms: - - name: Debian - versions: - - jessie - - galaxy_tags: [] - # List tags for your role here, one per line. A tag is - # a keyword that describes and categorizes the role. - # Users find roles by searching for tags. Be sure to - # remove the '[]' above if you add tags to this list. - # - # NOTE: A tag is limited to a single word comprised of - # alphanumeric characters. Maximum 20 tags per role. - -dependencies: [] - # List your role dependencies here, one per line. - # Be sure to remove the '[]' above if you add dependencies - # to this list. diff --git a/elastic-sources-list/tasks/main.yml b/elastic-sources-list/tasks/main.yml deleted file mode 100644 index 09c52cc5..00000000 --- a/elastic-sources-list/tasks/main.yml +++ /dev/null @@ -1,30 +0,0 @@ ---- - -- name: APT https transport is enabled - apt: - name: apt-transport-https - state: present - tags: - - elastic - - system - - packages - -- name: Elastic GPG key is installed - apt_key: - url: https://artifacts.elastic.co/GPG-KEY-elasticsearch - state: present - tags: - - elastic - - system - - packages - -- name: Elastic sources list is available - apt_repository: - repo: "deb https://artifacts.elastic.co/packages/5.x/apt stable main" - filename: elastic.list - state: present - update_cache: yes - tags: - - elastic - - system - - packages diff --git a/elastic-sources-list/tests/test.yml b/elastic-sources-list/tests/test.yml deleted file mode 100644 index f8b2eeae..00000000 --- a/elastic-sources-list/tests/test.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -- hosts: test-kitchen - roles: - - role: elastic-sources-list diff --git a/elastic-stack/README.md b/elastic-stack/README.md deleted file mode 100644 index 22f09223..00000000 --- a/elastic-stack/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# elastic-stack - -Install the Elastic Stack. - -It is a "meta-role" for : - -- elasticsearch -- elasticsearch-plugin-head -- logstash -- kibana diff --git a/elastic-stack/meta/main.yml b/elastic-stack/meta/main.yml deleted file mode 100644 index 94d60626..00000000 --- a/elastic-stack/meta/main.yml +++ /dev/null @@ -1,26 +0,0 @@ ---- -galaxy_info: - author: Evolix - description: Single server install of the Elastic Stack (Elasticsearch, Logstash, Kibana) - - issue_tracker_url: https://forge.evolix.org/projects/ansible-roles/issues - - license: GPLv2 - - min_ansible_version: 2.2 - - platforms: - - name: Debian - versions: - - jessie - - galaxy_tags: [] - # List tags for your role here, one per line. A tag is - # a keyword that describes and categorizes the role. - # Users find roles by searching for tags. Be sure to - # remove the '[]' above if you add tags to this list. - # - # NOTE: A tag is limited to a single word comprised of - # alphanumeric characters. Maximum 20 tags per role. - -dependencies: [] diff --git a/elastic-stack/tasks/main.yml b/elastic-stack/tasks/main.yml deleted file mode 100644 index ad01cef0..00000000 --- a/elastic-stack/tasks/main.yml +++ /dev/null @@ -1,13 +0,0 @@ ---- - -- include_role: - name: elasticsearch - -- include_role: - name: elasticsearch-plugin-head - -- include_role: - name: logstash - -- include_role: - name: kibana diff --git a/elasticsearch-curator/README.md b/elasticsearch-curator/README.md deleted file mode 100644 index 39e3da46..00000000 --- a/elasticsearch-curator/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# elasticsearch-curator - -Install Elasticsearch Curtor, for index management. - -## Tasks - -Everything is in the `tasks/main.yml` file. - -## Available variables diff --git a/elasticsearch-curator/meta/main.yml b/elasticsearch-curator/meta/main.yml deleted file mode 100644 index 0b48e8c4..00000000 --- a/elasticsearch-curator/meta/main.yml +++ /dev/null @@ -1,29 +0,0 @@ ---- -galaxy_info: - author: Evolix - description: Install Elasticsearch Curtor, for index management. - - issue_tracker_url: https://forge.evolix.org/projects/ansible-roles/issues - - license: GPLv2 - - min_ansible_version: 2.2 - - platforms: - - name: Debian - versions: - - jessie - - galaxy_tags: [] - # List tags for your role here, one per line. A tag is - # a keyword that describes and categorizes the role. - # Users find roles by searching for tags. Be sure to - # remove the '[]' above if you add tags to this list. - # - # NOTE: A tag is limited to a single word comprised of - # alphanumeric characters. Maximum 20 tags per role. - -dependencies: [] - # List your role dependencies here, one per line. - # Be sure to remove the '[]' above if you add dependencies - # to this list. diff --git a/elasticsearch-plugin-head/README.md b/elasticsearch-plugin-head/README.md deleted file mode 100644 index 442550b5..00000000 --- a/elasticsearch-plugin-head/README.md +++ /dev/null @@ -1,22 +0,0 @@ -# elasticsearch-plugin-head - -Install Head (Elasticsearch plugin). - -## Tasks - -Everything is in the `tasks/main.yml` file. - -## Variables - -* `elasticsearch_plugin_head_basedir`: base directory (default : `/var/www`) ; -* `elasticsearch_plugin_head_clone_name`: directory name for git clone. - -## Misc - -To use this plugin, you have to run the built-in webserver (using Grunt/NodeJS), or point a webserver to the path. More details here : https://github.com/mobz/elasticsearch-head#running-with-built-in-server - -For example, to run the built-in server, with "www-data" user : - -``` -# sudo -u www-data bash -c 'cd /var/www/elasticsearch-head && grunt server' -``` diff --git a/elasticsearch-plugin-head/defaults/main.yml b/elasticsearch-plugin-head/defaults/main.yml deleted file mode 100644 index d12d9b4a..00000000 --- a/elasticsearch-plugin-head/defaults/main.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -elasticsearch_plugin_head_owner: "elasticsearch-head" -elasticsearch_plugin_head_group: "{{ elasticsearch_plugin_head_owner }}" -elasticsearch_plugin_head_home: "/home/{{ elasticsearch_plugin_head_owner }}" -elasticsearch_plugin_head_clone_dir: "{{ elasticsearch_plugin_head_home }}/www" -elasticsearch_plugin_head_tmp_dir: "{{ elasticsearch_plugin_head_home }}/tmp" diff --git a/elasticsearch-plugin-head/handlers/main.yml b/elasticsearch-plugin-head/handlers/main.yml deleted file mode 100644 index 84a96121..00000000 --- a/elasticsearch-plugin-head/handlers/main.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- - -- name: restart elasticsearch - service: - name: elasticsearch - state: restarted diff --git a/elasticsearch-plugin-head/meta/main.yml b/elasticsearch-plugin-head/meta/main.yml deleted file mode 100644 index cd899a1a..00000000 --- a/elasticsearch-plugin-head/meta/main.yml +++ /dev/null @@ -1,27 +0,0 @@ ---- -galaxy_info: - author: Evolix - description: Install the Head plugin for Elasticsearch. - - issue_tracker_url: https://forge.evolix.org/projects/ansible-roles/issues - - license: GPLv2 - - min_ansible_version: 2.2 - - platforms: - - name: Debian - versions: - - jessie - - galaxy_tags: [] - # List tags for your role here, one per line. A tag is - # a keyword that describes and categorizes the role. - # Users find roles by searching for tags. Be sure to - # remove the '[]' above if you add tags to this list. - # - # NOTE: A tag is limited to a single word comprised of - # alphanumeric characters. Maximum 20 tags per role. - -dependencies: - - nodejs diff --git a/elasticsearch/README.md b/elasticsearch/README.md index acdd1552..a6fa0b14 100644 --- a/elasticsearch/README.md +++ b/elasticsearch/README.md @@ -24,3 +24,25 @@ Tasks are extracted in several files, included in `tasks/main.yml` : * `elasticsearch_jvm_xmx`: maximum heap size reserved for the JVM (defaults to 2g). By default, Elasticsearch will listen to the public interfaces (`_site_` cf. https://www.elastic.co/guide/en/elasticsearch/reference/5.0/important-settings.html#network.host), so you will have to secure it, with firewall rules for example. + +## Curator + +Curator can be installed. : + +* `elasticsearch_curator` : enable the package installation (default: `False`) ; + +## Head plugin + +The "head" plugin can be installed : + +* `elasticsearch_plugin_head` : enable the plugin installation (default: `False`) ; +* `elasticsearch_plugin_head_basedir`: base directory (default : `/var/www`) ; +* `elasticsearch_plugin_head_clone_name`: directory name for git clone. + +To use this plugin, you have to run the built-in webserver (using Grunt/NodeJS), or point a webserver to the path. More details here : https://github.com/mobz/elasticsearch-head#running-with-built-in-server + +For example, to run the built-in server, with "www-data" user : + +``` +# sudo -u www-data bash -c 'cd /var/www/elasticsearch-head && grunt server' +``` diff --git a/elasticsearch/defaults/main.yml b/elasticsearch/defaults/main.yml index a3a7180f..77e36070 100644 --- a/elasticsearch/defaults/main.yml +++ b/elasticsearch/defaults/main.yml @@ -8,3 +8,12 @@ elasticsearch_custom_tmpdir: Null elasticsearch_default_tmpdir: /var/lib/elasticsearch/tmp elasticsearch_jvm_xms: 2g elasticsearch_jvm_xmx: 2g + +elasticsearch_curator: False + +elasticsearch_plugin_head: False +elasticsearch_plugin_head_owner: "elasticsearch-head" +elasticsearch_plugin_head_group: "{{ elasticsearch_plugin_head_owner }}" +elasticsearch_plugin_head_home: "/home/{{ elasticsearch_plugin_head_owner }}" +elasticsearch_plugin_head_clone_dir: "{{ elasticsearch_plugin_head_home }}/www" +elasticsearch_plugin_head_tmp_dir: "{{ elasticsearch_plugin_head_home }}/tmp" diff --git a/elasticsearch/files/elasticsearch.key b/elasticsearch/files/elasticsearch.key new file mode 100644 index 00000000..1b50dcca --- /dev/null +++ b/elasticsearch/files/elasticsearch.key @@ -0,0 +1,31 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v2.0.14 (GNU/Linux) + +mQENBFI3HsoBCADXDtbNJnxbPqB1vDNtCsqhe49vFYsZN9IOZsZXgp7aHjh6CJBD +A+bGFOwyhbd7at35jQjWAw1O3cfYsKAmFy+Ar3LHCMkV3oZspJACTIgCrwnkic/9 +CUliQe324qvObU2QRtP4Fl0zWcfb/S8UYzWXWIFuJqMvE9MaRY1bwUBvzoqavLGZ +j3SF1SPO+TB5QrHkrQHBsmX+Jda6d4Ylt8/t6CvMwgQNlrlzIO9WT+YN6zS+sqHd +1YK/aY5qhoLNhp9G/HxhcSVCkLq8SStj1ZZ1S9juBPoXV1ZWNbxFNGwOh/NYGldD +2kmBf3YgCqeLzHahsAEpvAm8TBa7Q9W21C8vABEBAAG0RUVsYXN0aWNzZWFyY2gg +KEVsYXN0aWNzZWFyY2ggU2lnbmluZyBLZXkpIDxkZXZfb3BzQGVsYXN0aWNzZWFy +Y2gub3JnPokBOAQTAQIAIgUCUjceygIbAwYLCQgHAwIGFQgCCQoLBBYCAwECHgEC +F4AACgkQ0n1mbNiOQrRzjAgAlTUQ1mgo3nK6BGXbj4XAJvuZDG0HILiUt+pPnz75 +nsf0NWhqR4yGFlmpuctgCmTD+HzYtV9fp9qW/bwVuJCNtKXk3sdzYABY+Yl0Cez/ +7C2GuGCOlbn0luCNT9BxJnh4mC9h/cKI3y5jvZ7wavwe41teqG14V+EoFSn3NPKm +TxcDTFrV7SmVPxCBcQze00cJhprKxkuZMPPVqpBS+JfDQtzUQD/LSFfhHj9eD+Xe +8d7sw+XvxB2aN4gnTlRzjL1nTRp0h2/IOGkqYfIG9rWmSLNlxhB2t+c0RsjdGM4/ +eRlPWylFbVMc5pmDpItrkWSnzBfkmXL3vO2X3WvwmSFiQbkBDQRSNx7KAQgA5JUl +zcMW5/cuyZR8alSacKqhSbvoSqqbzHKcUQZmlzNMKGTABFG1yRx9r+wa/fvqP6OT +RzRDvVS/cycws8YX7Ddum7x8uI95b9ye1/Xy5noPEm8cD+hplnpU+PBQZJ5XJ2I+ +1l9Nixx47wPGXeClLqcdn0ayd+v+Rwf3/XUJrvccG2YZUiQ4jWZkoxsA07xx7Bj+ +Lt8/FKG7sHRFvePFU0ZS6JFx9GJqjSBbHRRkam+4emW3uWgVfZxuwcUCn1ayNgRt +KiFv9jQrg2TIWEvzYx9tywTCxc+FFMWAlbCzi+m4WD+QUWWfDQ009U/WM0ks0Kww +EwSk/UDuToxGnKU2dQARAQABiQEfBBgBAgAJBQJSNx7KAhsMAAoJENJ9ZmzYjkK0 +c3MIAIE9hAR20mqJWLcsxLtrRs6uNF1VrpB+4n/55QU7oxA1iVBO6IFu4qgsF12J +TavnJ5MLaETlggXY+zDef9syTPXoQctpzcaNVDmedwo1SiL03uMoblOvWpMR/Y0j +6rm7IgrMWUDXDPvoPGjMl2q1iTeyHkMZEyUJ8SKsaHh4jV9wp9KmC8C+9CwMukL7 +vM5w8cgvJoAwsp3Fn59AxWthN3XJYcnMfStkIuWgR7U2r+a210W6vnUxU4oN0PmM +cursYPyeV0NX/KQeUeNMwGTFB6QHS/anRaGQewijkrYYoTNtfllxIu9XYmiBERQ/ +qPDlGRlOgVTd9xUfHFkzB52c70E= +=92oX +-----END PGP PUBLIC KEY BLOCK----- diff --git a/elasticsearch/handlers/main.yml b/elasticsearch/handlers/main.yml index f21919c2..c8a57b70 100644 --- a/elasticsearch/handlers/main.yml +++ b/elasticsearch/handlers/main.yml @@ -1,9 +1,7 @@ --- - name: restart elasticsearch - service: + systemd: + daemon_reload: yes name: elasticsearch state: restarted - -- name: reload elasticsearch unit - command: systemctl daemon-reload diff --git a/elasticsearch/tasks/bootstrap_checks.yml b/elasticsearch/tasks/bootstrap_checks.yml index b7d6547d..a79204b2 100644 --- a/elasticsearch/tasks/bootstrap_checks.yml +++ b/elasticsearch/tasks/bootstrap_checks.yml @@ -38,6 +38,6 @@ option: "LimitMEMLOCK" value: "infinity" notify: - - reload elasticsearch unit + - restart elasticsearch tags: - config diff --git a/elasticsearch-curator/tasks/main.yml b/elasticsearch/tasks/curator.yml similarity index 51% rename from elasticsearch-curator/tasks/main.yml rename to elasticsearch/tasks/curator.yml index 4fef07b9..c1a10658 100644 --- a/elasticsearch-curator/tasks/main.yml +++ b/elasticsearch/tasks/curator.yml @@ -1,30 +1,18 @@ --- -- name: APT https transport is enabled - apt: - name: apt-transport-https - state: present - tags: - - system - - packages - -- name: Elastic GPG key is installed - apt_key: - url: https://packages.elastic.co/GPG-KEY-elasticsearch - state: present - tags: - - system - - packages - - name: Curator sources list is available apt_repository: repo: "deb http://packages.elastic.co/curator/4/debian stable main" + update_cache: yes state: present tags: - - system + - curator - packages - name: Curator package is installed apt: name: elasticsearch-curator state: present + tags: + - curator + - packages diff --git a/elasticsearch/tasks/main.yml b/elasticsearch/tasks/main.yml index 89515c05..00be05ed 100644 --- a/elasticsearch/tasks/main.yml +++ b/elasticsearch/tasks/main.yml @@ -9,3 +9,9 @@ - include: datadir.yml - include: tmpdir.yml + +- include: plugin_head.yml + when: elasticsearch_plugin_head + +- include: curator.yml + when: elasticsearch_curator diff --git a/elasticsearch/tasks/packages.yml b/elasticsearch/tasks/packages.yml index 5a18b1e9..05d5bf46 100644 --- a/elasticsearch/tasks/packages.yml +++ b/elasticsearch/tasks/packages.yml @@ -3,19 +3,48 @@ - name: install java8 include_role: name: java8 + tags: + - elasticsearch + - packages -- name: install Elastic sources list - include_role: - name: elastic-sources-list +- name: APT https transport is enabled + apt: + name: apt-transport-https + state: present + tags: + - elasticsearch + - packages + +- name: Elastic GPG key is installed + apt_key: + # url: https://artifacts.elastic.co/GPG-KEY-elasticsearch + data: "{{ lookup('file', 'elasticsearch.key') }}" + state: present + tags: + - elasticsearch + - packages + +- name: Elastic sources list is available + apt_repository: + repo: "deb https://artifacts.elastic.co/packages/5.x/apt stable main" + filename: elastic.list + state: present + update_cache: yes + tags: + - elasticsearch + - packages - name: Elasticsearch is installed apt: name: elasticsearch state: present tags: - - packages + - elasticsearch + - packages - name: Elasticsearch service is enabled service: name: elasticsearch enabled: yes + tags: + - elasticsearch diff --git a/elasticsearch-plugin-head/tasks/main.yml b/elasticsearch/tasks/plugin_head.yml similarity index 100% rename from elasticsearch-plugin-head/tasks/main.yml rename to elasticsearch/tasks/plugin_head.yml diff --git a/etc-git/README.md b/etc-git/README.md index d0930e59..9028cc1c 100644 --- a/etc-git/README.md +++ b/etc-git/README.md @@ -15,7 +15,7 @@ There is also an independant task that can be executed to commit changes made in pre_tasks: - include_role: name: etc-git - task_from: commit.yml + tasks_from: commit.yml vars: commit_message: "Ansible pre-run my splendid playbook" @@ -25,7 +25,7 @@ There is also an independant task that can be executed to commit changes made in post_tasks: - include_role: name: etc-git - task_from: commit.yml + tasks_from: commit.yml vars: - commit_message: "Ansible pre-run my splendid playbook" + commit_message: "Ansible post-run my splendid playbook" ``` diff --git a/etc-git/tasks/commit.yml b/etc-git/tasks/commit.yml index d7d1fbbf..c11b453c 100644 --- a/etc-git/tasks/commit.yml +++ b/etc-git/tasks/commit.yml @@ -16,8 +16,21 @@ tags: - commit-etc -- name: /etc modifications are committed - shell: "git add -A . && git commit -m \"{{ commit_message | mandatory }}\"" +- name: fetch current Git user.email + git_config: + name: user.email + repo: /etc + scope: local + register: git_config_user_email + ignore_errors: yes + +- name: "set commit author" + set_fact: + commit_author: '{% if ansible_env.SUDO_USER == "" %}root{% else %}{{ ansible_env.SUDO_USER }}{% endif %}' + commit_email: '{% if git_config_user_email.config_value == "" %}root@localhost{% else %}{{ git_config_user_email.config_value }}{% endif %}' + +- name: "/etc modifications are committed" + shell: "git add -A . && git commit -m \"{{ commit_message | mandatory }}\" --author \"{{ commit_author | mandatory }} <{{ commit_email | mandatory }}>\"" args: chdir: /etc register: etc_commit_end_run diff --git a/etc-git/tasks/main.yml b/etc-git/tasks/main.yml index faf4e8c6..58bf52f2 100644 --- a/etc-git/tasks/main.yml +++ b/etc-git/tasks/main.yml @@ -1,16 +1,9 @@ --- -- name: Git is installed +- name: Git is installed (Debian) apt: name: git state: present - when: ansible_os_family == "Debian" - -- name: Git is installed - openbsd_pkg: - name: git - state: present - when: ansible_os_family == "OpenBSD" - name: /etc is versioned with git command: "git init ." @@ -21,11 +14,11 @@ register: git_init - name: Git user.email is configured - ini_file: - dest: /etc/.git/config - section: user - option: email - value: "" + git_config: + name: user.email + repo: /etc + scope: local + value: "root@{{ ansible_fqdn | default('localhost') }}" - name: /etc/.git is secure file: diff --git a/evoacme/defaults/main.yml b/evoacme/defaults/main.yml index 0cdffca9..4194b5aa 100644 --- a/evoacme/defaults/main.yml +++ b/evoacme/defaults/main.yml @@ -6,7 +6,7 @@ evoacme_acme_dir: /var/lib/letsencrypt evoacme_csr_dir: /etc/ssl/requests evoacme_crt_dir: /etc/letsencrypt evoacme_log_dir: /var/log/evoacme -evoacme_ssl_minday: 15 +evoacme_ssl_minday: 30 evoacme_ssl_ct: 'FR' evoacme_ssl_state: 'France' evoacme_ssl_loc: 'Marseille' diff --git a/evoacme/files/certbot.cron b/evoacme/files/certbot.cron index 84a22241..a7c4eef2 100755 --- a/evoacme/files/certbot.cron +++ b/evoacme/files/certbot.cron @@ -1,17 +1,14 @@ #!/bin/sh +# +# Run evoacme script on every configured cert +# +# Author: Victor Laborie +# Licence: AGPLv3 +# [ -f /etc/default/evoacme ] && . /etc/default/evoacme [ -z "${CRT_DIR}" ] && CRT_DIR='/etc/letsencrypt' -[ -z "${SELF_SIGNED_DIR}" ] && SELF_SIGNED_DIR='/etc/ssl/self-signed' -find ${CRT_DIR} -maxdepth 1 -mindepth 1 -type d ! -path "*accounts" -exec basename {} \; | while read vhost; do - evoacme $vhost -done - -# Compatibility with older version of evoacme -find ${CRT_DIR} -maxdepth 1 -mindepth 1 -type f -name "*.crt" -exec basename {} .crt \; | while read vhost; do - [ -f /etc/apache2/ssl/${vhost}.conf ] && sed -i "s~^SSLCertificateFile.*$~SSLCertificateFile $SELF_SIGNED_DIR/${vhost}.pem~" /etc/apache2/ssl/${vhost}.conf - [ -f /etc/nginx/ssl/${vhost}.conf ] && sed -i "s~^ssl_certificate[^_].*$~ssl_certificate $SELF_SIGNED_DIR/${vhost}.pem;~" /etc/nginx/ssl/${vhost}.conf - rm ${CRT_DIR}/${vhost}.crt ${CRT_DIR}/${vhost}-chain.pem ${CRT_DIR}/${vhost}-fullchain.pem - evoacme $vhost +find "${CRT_DIR}" -maxdepth 1 -mindepth 1 -type d ! -path "*accounts" -exec basename {} \; | while read vhost; do + evoacme "$vhost" done diff --git a/evoacme/files/evoacme.sh b/evoacme/files/evoacme.sh index d0940944..ffbf22ac 100755 --- a/evoacme/files/evoacme.sh +++ b/evoacme/files/evoacme.sh @@ -1,62 +1,84 @@ -#!/bin/bash +#!/bin/sh +# +# 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 +# +# Author: Victor Laborie +# Licence: AGPLv3 +# -[ -f /etc/default/evoacme ] && . /etc/default/evoacme -[ -z "${SSL_KEY_DIR}" ] && SSL_KEY_DIR='/etc/ssl/private' -[ -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' +usage() { + echo "Usage: $0 NAME" + echo "" + echo "NAME must be correspond to :" + echo "- a CSR in ${CSR_DIR}/NAME.csr" + echo "- a KEY in ${SSL_KEY_DIR}/NAME.key" + echo "" +} -vhost=$(basename $1 .conf) -DATE=$(date "+%Y%m%d") +mkconf_apache() { + [ -f "/etc/apache2/ssl/${vhost}.conf" ] && sed -i "s~^SSLCertificateFile.*$~SSLCertificateFile $CRT_DIR/${vhost}/live/fullchain.pem~" "/etc/apache2/ssl/${vhost}.conf" + apache2ctl -t 2>/dev/null && service apache2 reload +} -SSL_EMAIL=$(grep emailAddress ${CRT_DIR}/openssl.cnf|cut -d'=' -f2|xargs) -if [ -n "$SSL_EMAIL" ]; then - emailopt="--email $SSL_EMAIL" -else - emailopt="--register-unsafely-without-email" -fi +mkconf_nginx() { + [ -f "/etc/nginx/ssl/${vhost}.conf" ] && sed -i "s~^ssl_certificate[^_].*$~ssl_certificate $CRT_DIR/${vhost}/live/fullchain.pem;~" "/etc/nginx/ssl/${vhost}.conf" + nginx -t 2>/dev/null && service nginx reload +} -# Check master status for evoadmin-cluster -if [ -f /home/${vhost}/state ]; then - grep -q "STATE=master" /home/${vhost}/state - [ $? -ne 0 ] && exit 0 -fi +mkconf_haproxy() { + mkdir -p /etc/ssl/haproxy -m 700 + cat "$CRT_DIR/${vhost}/live/fullchain.pem" "$SSL_KEY_DIR/${vhost}.key" > "/etc/ssl/haproxy/${vhost}.pem" + [ -f "$DH_DIR/${vhost}.pem" ] && cat "$DH_DIR/${vhost}.pem" >> "/etc/ssl/haproxy/${vhost}.pem" + haproxy -c -f /etc/haproxy/haproxy.cfg >/dev/null && service haproxy reload +} -if [ -h $CRT_DIR/${vhost}/live ]; then - crt_end_date=`openssl x509 -noout -enddate -in $CRT_DIR/${vhost}/live/cert.crt|sed -e "s/.*=//"` - date_crt=`date -ud "$crt_end_date" +"%s"` - date_today=`date +'%s'` - date_diff=$(( ( $date_crt - $date_today ) / (60*60*24) )) - [ $date_diff -ge $SSL_MINDAY ] && exit 0 -fi - -mkdir -pm 755 $CRT_DIR/${vhost} $CRT_DIR/${vhost}/${DATE} -chown -R acme: $CRT_DIR/${vhost} -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> >(grep -v certbot.crypto_util) - -if [ $? -eq 0 ]; then - ln -sf $CRT_DIR/${vhost}/${DATE} $CRT_DIR/${vhost}/live - which apache2ctl>/dev/null - if [ $? -eq 0 ]; then - [ -f /etc/apache2/ssl/${vhost}.conf ] && sed -i "s~^SSLCertificateFile.*$~SSLCertificateFile $CRT_DIR/${vhost}/live/fullchain.pem~" /etc/apache2/ssl/${vhost}.conf - apache2ctl -t 2>/dev/null - [ $? -eq 0 ] && service apache2 reload - fi - which nginx>/dev/null - if [ $? -eq 0 ]; then - [ -f /etc/nginx/ssl/${vhost}.conf ] && sed -i "s~^ssl_certificate[^_].*$~ssl_certificate $CRT_DIR/${vhost}/live/fullchain.pem;~" /etc/nginx/ssl/${vhost}.conf - nginx -t 2>/dev/null - [ $? -eq 0 ] && service nginx reload - fi +main() { + [ -f /etc/default/evoacme ] && . /etc/default/evoacme + [ -z "${SSL_KEY_DIR}" ] && SSL_KEY_DIR='/etc/ssl/private' + [ -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' - which haproxy>/dev/null - if [ $? -eq 0 ]; then - mkdir -p /etc/ssl/haproxy -m 700 - cat $CRT_DIR/${vhost}/live/fullchain.pem $SSL_KEY_DIR/${vhost}.key > /etc/ssl/haproxy/${vhost}.pem - [ -f $DH_DIR/${vhost} ] && cat $DH_DIR/${vhost} >> /etc/ssl/haproxy/${vhost}.pem - haproxy -c -f /etc/haproxy/haproxy.cfg 1>/dev/null - [ $? -eq 0 ] && service haproxy reload + [ "$#" -ne 1 ] && usage && exit 1 + + vhost=$(basename "$1" .conf) + + # Check master status for evoadmin-cluster + if [ -f "/home/${vhost}/state" ]; then + grep -q "STATE=master" "/home/${vhost}/state" || exit 0 fi - exit 0 -fi + + SSL_EMAIL=$(grep emailAddress "${CRT_DIR}/openssl.cnf"|cut -d'=' -f2|xargs) + if [ -n "$SSL_EMAIL" ]; then + emailopt="-m $SSL_EMAIL" + else + emailopt="--register-unsafely-without-email" + fi + DATE=$(date "+%Y%m%d") + + if [ -h "$CRT_DIR/${vhost}/live" ]; then + crt_end_date=$(openssl x509 -noout -enddate -in "$CRT_DIR/${vhost}/live/cert.crt"|sed -e "s/.*=//") + date_crt=$(date -ud "$crt_end_date" +"%s") + date_today=$(date +'%s') + date_diff=$(((date_crt - date_today) / (60*60*24))) + [ "$date_diff" -ge "$SSL_MINDAY" ] && exit 0 + fi + rm -rf "$CRT_DIR/${vhost}/${DATE}" + mkdir -pm 755 "$CRT_DIR/${vhost}/${DATE}" + chown -R acme: "$CRT_DIR/${vhost}" + 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 + rm -f "$CRT_DIR/${vhost}/live" + ln -s "$CRT_DIR/${vhost}/${DATE}" "$CRT_DIR/${vhost}/live" + which apache2ctl >/dev/null && mkconf_apache + which nginx >/dev/null && mkconf_nginx + which haproxy >/dev/null && mkconf_haproxy + else + rmdir "$CRT_DIR/${vhost}/${DATE}" + fi +} + +main "$@" diff --git a/evoacme/files/make-csr.sh b/evoacme/files/make-csr.sh index 5b2c9298..844847ab 100755 --- a/evoacme/files/make-csr.sh +++ b/evoacme/files/make-csr.sh @@ -1,114 +1,151 @@ -#!/bin/bash +#!/bin/sh +# +# 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 +# Licence: AGPLv3 +# -[ -f /etc/default/evoacme ] && source /etc/default/evoacme -[ -z "${SSL_KEY_DIR}" ] && SSL_KEY_DIR='/etc/ssl/private' -[ -z "${CSR_DIR}" ] && CSR_DIR='/etc/ssl/requests' -[ -z "${SELF_SIGNED_DIR}" ] && SELF_SIGNED_DIR='/etc/ssl/self-signed' - -shopt -s extglob - -vhost=$(basename $1 .conf) -vhostfiles=$(ls -1 /etc/{nginx,apache2}/sites-enabled/${vhost}?(.conf) 2>/dev/null) - -if [ $(echo "${vhostfiles}"|wc -l) -lt 1 ]; then - echo "$vhost doesn't exist !" - exit 1 -fi - -for vhostfile in "${vhostfiles}"; do - break; -done - -if [ -f $SSL_KEY_DIR/${vhost}.key ]; then - read -p "$vhost key already exist, overwrite it ? (y)" -n 1 -r - echo "" - if [[ ! $REPLY =~ ^[Yy]$ ]]; then - exit 1 +get_domains() { + 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 - rm -f /etc/apache2/ssl/${vhost}.conf - rm -f /etc/nginx/ssl/${vhost}.conf -fi - -SSL_KEY_SIZE=$(grep default_bits /etc/letsencrypt/openssl.cnf|cut -d'=' -f2|xargs) -openssl genrsa -out $SSL_KEY_DIR/${vhost}.key $SSL_KEY_SIZE -chown root: $SSL_KEY_DIR/${vhost}.key -chmod 600 $SSL_KEY_DIR/${vhost}.key - -nb=0 - -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 -if [ $? -eq 0 ]; then - domains=`grep -oE "^( )*[^#]+" $vhostfile |grep -oE "(ServerName|ServerAlias).*"|sed 's/ServerName//'|sed 's/ServerAlias//'|sed 's/\s\{1,\}//'|sort|uniq` -fi - -valid_domains='' -srv_ip=$(ip a|grep brd|cut -d'/' -f1|grep -oE "([0-9]+\.){3}[0-9]+") - -echo "Valid Domain(s) for $vhost :" -for domain in $domains -do - real_ip=$(dig +short $domain|grep -oE "([0-9]+\.){3}[0-9]+") - for ip in $(echo $srv_ip|xargs -n1); do - if [ "${ip}" == "${real_ip}" ]; then - valid_domains="$valid_domains $domain" - nb=$(( nb + 1 )) - echo "- $domain" - fi - done -done - -if [ $nb -eq 0 ]; then - nb=`echo $domains|wc -l` - echo "No valid domains : $domains" >&2 -else - domains=$valid_domains -fi - -mkdir -p $CSR_DIR -m 0755 - -if [ $nb -eq 1 ]; then - openssl req -new -sha256 -key $SSL_KEY_DIR/${vhost}.key -config <(cat /etc/letsencrypt/openssl.cnf <(printf "CN=$domains")) -out $CSR_DIR/${vhost}.csr -elif [ $nb -gt 1 ]; then - san='' - for domain in $domains - do - san="$san,DNS:$domain" - done - san=`echo $san|sed 's/,//'` - openssl req -new -sha256 -key $SSL_KEY_DIR/${vhost}.key -reqexts SAN -config <(cat /etc/letsencrypt/openssl.cnf <(printf "[SAN]\nsubjectAltName=$san")) > $CSR_DIR/${vhost}.csr -fi - -if [ -f $CSR_DIR/${vhost}.csr ]; then - chmod 644 $CSR_DIR/${vhost}.csr - mkdir -p $SELF_SIGNED_DIR -m 0755 - openssl x509 -req -sha256 -days 365 -in $CSR_DIR/${vhost}.csr -signkey $SSL_KEY_DIR/${vhost}.key -out $SELF_SIGNED_DIR/${vhost}.pem - if [ -f $SELF_SIGNED_DIR/${vhost}.pem ]; then - chmod 644 $SELF_SIGNED_DIR/${vhost}.pem + + echo "$vhostfile" |grep -q apache2 + if [ "$?" -eq 0 ]; then + domains=$(grep -oE "^( )*[^#]+" "$vhostfile" |grep -oE "(ServerName|ServerAlias).*"|sed 's/ServerName//'|sed 's/ServerAlias//'|sed 's/\s\{1,\}//'|sort|uniq) fi -fi + valid_domains="" + nb=0 + + echo "Valid(s) domain(s) in $vhost :" + for domain in $domains; do + real_ip=$(dig +short "$domain"|grep -oE "([0-9]+\.){3}[0-9]+") + for ip in $(echo "$SRV_IP"|xargs -n1); do + if [ "${ip}" = "${real_ip}" ]; then + valid_domains="$valid_domains $domain" + nb=$(( nb + 1 )) + echo "* $domain -> $real_ip" + fi + done + done + + if [ "$nb" -eq 0 ]; then + nb=$(echo "$domains"|wc -l) + echo "* No valid domain found" + echo "All following(s) domain(s) will be used for CSR creation :" + for domain in $domains; do + echo "* $domain" + done + else + domains="$valid_domains" + fi + domains=$(echo "$domains"|xargs -n1) +} -if [ -d /etc/apache2 ]; then +make_key() { + openssl genrsa -out "$SSL_KEY_DIR/${vhost}.key" "$SSL_KEY_SIZE" 2>/dev/null + chown root: "$SSL_KEY_DIR/${vhost}.key" + chmod 600 "$SSL_KEY_DIR/${vhost}.key" +} + +make_csr() { + domains="$1" + nb=$(echo "$domains"|wc -l) + config_file="/tmp/make-csr-${vhost}.conf" + + mkdir -p "$CSR_DIR" -m 0755 + + if [ "$nb" -eq 1 ]; then + cat /etc/letsencrypt/openssl.cnf - > "$config_file" < "$config_file" < "$CSR_DIR/${vhost}.csr" + fi + + if [ -f "$CSR_DIR/${vhost}.csr" ]; then + chmod 644 "$CSR_DIR/${vhost}.csr" + mkdir -p "$SELF_SIGNED_DIR" -m 0755 + 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() { mkdir -p /etc/apache2/ssl - if [ ! -f /etc/apache2/ssl/${vhost}.conf ]; then - cat > /etc/apache2/ssl/${vhost}.conf < "/etc/apache2/ssl/${vhost}.conf" < /etc/nginx/ssl/${vhost}.conf < "/etc/nginx/ssl/${vhost}.conf" <&2 + exit 1 + fi + vhost=$(basename "$1" .conf) + local_ip=$(ip a|grep brd|cut -d'/' -f1|grep -oE "([0-9]+\.){3}[0-9]+") + + [ -f /etc/default/evoacme ] && . /etc/default/evoacme + [ -z "${SSL_KEY_DIR}" ] && SSL_KEY_DIR='/etc/ssl/private' + [ -z "${CSR_DIR}" ] && CSR_DIR='/etc/ssl/requests' + [ -z "${CRT_DIR}" ] && CRT_DIR='/etc/letsencrypt' + [ -z "${SELF_SIGNED_DIR}" ] && SELF_SIGNED_DIR='/etc/ssl/self-signed' + SSL_KEY_SIZE=$(grep default_bits /etc/letsencrypt/openssl.cnf|cut -d'=' -f2|xargs) + [ -n "${SRV_IP}" ] && SRV_IP="${SRV_IP} $local_ip" || SRV_IP="$local_ip" + + 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 + fi + + if [ -f "$SSL_KEY_DIR/${vhost}.key" ]; then + echo "$vhost key already exist, overwrite it ? (y)" + read REPLY + [ "$REPLY" = "Y" ] || [ "$REPLY" = "y" ] || exit 0 + rm -f "/etc/apache2/ssl/${vhost}.conf /etc/nginx/ssl/${vhost}.conf" + [ -h "${CRT_DIR}/${vhost}/live" ] && rm "${CRT_DIR}/${vhost}/live" + fi + + get_domains + make_key + make_csr "$domains" + which apache2ctl >/dev/null && mkconf_apache + which nginx >/dev/null && mkconf_nginx +} + +main "$@" diff --git a/evoacme/files/sudoers b/evoacme/files/sudoers deleted file mode 100644 index 4a43bce3..00000000 --- a/evoacme/files/sudoers +++ /dev/null @@ -1 +0,0 @@ -acme ALL=(ALL:ALL) NOPASSWD: /opt/certbot/certbot-auto diff --git a/evoacme/handlers/main.yml b/evoacme/handlers/main.yml index abaa8099..1ea11783 100644 --- a/evoacme/handlers/main.yml +++ b/evoacme/handlers/main.yml @@ -18,3 +18,8 @@ service: name: squid3 state: reloaded + +- name: reload squid + service: + name: squid + state: reloaded diff --git a/evoacme/tasks/certbot.yml b/evoacme/tasks/certbot.yml index 1677a22f..20658ec2 100644 --- a/evoacme/tasks/certbot.yml +++ b/evoacme/tasks/certbot.yml @@ -3,7 +3,7 @@ - block: - name: install jessie-backports include_role: - name: apt-repositories + name: apt tasks_from: backports.yml - name: Add exceptions for certbot dependances @@ -53,17 +53,3 @@ dest: /etc/cron.daily/certbot mode: "0755" -- name: Find squid3 config whitelist - shell: find /etc/squid3/whitelist-custom.conf /etc/squid3/whitelist.conf 2> /dev/null - failed_when: false - changed_when: false - check_mode: no - register: squid3_whitelist_files - -- name: Let's Encrypt OCSP server is authorized by squid - lineinfile: - dest: "{{ squid3_whitelist_files.stdout_lines | first }}" - line: "http://.*.letsencrypt.org/.*" - state: present - notify: reload squid3 - when: squid3_whitelist_files.stdout != "" diff --git a/evoacme/tasks/main.yml b/evoacme/tasks/main.yml index 07a1d5d2..beac178e 100644 --- a/evoacme/tasks/main.yml +++ b/evoacme/tasks/main.yml @@ -1,11 +1,9 @@ --- -- name: Fail if distribution is not supported - fail: - msg: "Error: '{{ ansible_os_family }} {{ ansible_distribution_release }}' is not a supported distribution." +- fail: + msg: only compatible with Debian >= 8 when: - - ansible_distribution_release != "jessie" - - ansible_distribution_release != "stretch" + - ansible_distribution != "Debian" or ansible_distribution_major_version | version_compare('8', '<') - include: certbot.yml diff --git a/evoacme/tasks/scripts.yml b/evoacme/tasks/scripts.yml index 930f1f25..01e61fdb 100644 --- a/evoacme/tasks/scripts.yml +++ b/evoacme/tasks/scripts.yml @@ -10,7 +10,7 @@ - name: Copy make-csr.sh script copy: src: files/make-csr.sh - dest: /usr/local/bin/make-csr + dest: /usr/local/sbin/make-csr owner: root group: root mode: "0755" @@ -18,7 +18,15 @@ - name: Copy evoacme script copy: src: files/evoacme.sh - dest: /usr/local/bin/evoacme + dest: /usr/local/sbin/evoacme owner: root group: root mode: "0755" + +- name: Delete scripts in old location + file: + path: "/usr/local/bin/{{ item }}" + state: absent + with_items: + - 'make-csr' + - 'evoacme' diff --git a/evoacme/templates/apache.conf.j2 b/evoacme/templates/apache.conf.j2 index 6cd3d2ea..014c4d3f 100644 --- a/evoacme/templates/apache.conf.j2 +++ b/evoacme/templates/apache.conf.j2 @@ -7,6 +7,5 @@ Alias /.well-known/acme-challenge {{ evoacme_acme_dir }}/.well-known/acme-challenge Options -Indexes - Allow from all Require all granted diff --git a/evoadmin/tasks/main.yml b/evoadmin/tasks/main.yml deleted file mode 100644 index 655aa81d..00000000 --- a/evoadmin/tasks/main.yml +++ /dev/null @@ -1,13 +0,0 @@ ---- - -- include: packages.yml - -- include: user.yml - -- include: config.yml - -- include: ssl.yml - -- include: web.yml - -- include: ftp.yml diff --git a/evocheck/README.md b/evocheck/README.md index b4438d3f..b669fe54 100644 --- a/evocheck/README.md +++ b/evocheck/README.md @@ -4,7 +4,7 @@ Install and run evocheck ; a script for checking various settings automatically. ## Tasks -The tasks in `main.yml` install the script. This is temporary as evocheck is a package on Debian which is a bit outdated for the moment. For OpenBSD, it should also be packaged, but the work is not done yet. +The roles does not install evocheck by default as it should be installed through dependencies. A separate `exec.yml` file can be imported manually in playbooks or roles to execute the script. Example : @@ -13,3 +13,8 @@ A separate `exec.yml` file can be imported manually in playbooks or roles to exe name: evocheck tasks_from: exec.yml ``` +## Variables + +We can force install via : +* `evocheck_force_install: local` : will copy the script provided by the role +* `evocheck_force_install: package` : will install the package via repositories diff --git a/evocheck/defaults/main.yml b/evocheck/defaults/main.yml index 8160768d..565849e3 100644 --- a/evocheck/defaults/main.yml +++ b/evocheck/defaults/main.yml @@ -1,2 +1,3 @@ --- +evocheck_force_install: False evocheck_bin_dir: /usr/share/scripts diff --git a/evocheck/files/evocheck.sh b/evocheck/files/evocheck.sh index b972d8be..4c08b930 100644 --- a/evocheck/files/evocheck.sh +++ b/evocheck/files/evocheck.sh @@ -204,7 +204,7 @@ if [ -e /etc/debian_version ]; then fi if [ "$IS_LISTCHANGESCONF" = 1 ]; then - egrep "(which=both|confirm=1)" /etc/apt/listchanges.conf | wc -l | grep -q ^2$ || echo 'IS_LISTCHANGESCONF FAILED!' + is_debianversion stretch || ( test -e /etc/apt/listchanges.conf && egrep "(which=both|confirm=1)" /etc/apt/listchanges.conf | wc -l | grep -q ^2$ || echo 'IS_LISTCHANGESCONF FAILED!' ) fi if [ "$IS_CUSTOMCRONTAB" = 1 ]; then @@ -220,7 +220,7 @@ if [ -e /etc/debian_version ]; then fi if [ "$IS_TMOUTPROFILE" = 1 ]; then - grep -q TMOUT= /etc/profile || echo 'IS_TMOUTPROFILE FAILED!' + grep -q TMOUT= /etc/profile /etc/profile.d/evolinux.sh || echo 'IS_TMOUTPROFILE FAILED!' fi if [ "$IS_ALERT5BOOT" = 1 ]; then diff --git a/evocheck/tasks/exec.yml b/evocheck/tasks/exec.yml index bee39ab9..244d0347 100644 --- a/evocheck/tasks/exec.yml +++ b/evocheck/tasks/exec.yml @@ -3,13 +3,13 @@ command: "{{ evocheck_bin_dir }}/evocheck.sh" register: evocheck_run changed_when: False - failed_when: evocheck_run.stdout != "" + failed_when: False check_mode: no tags: - evocheck-exec - debug: - var: evocheck_run - verbosity: 1 + var: evocheck_run.stdout_lines + when: evocheck_run.stdout != "" tags: - evocheck-exec diff --git a/evocheck/tasks/install_local.yml b/evocheck/tasks/install_local.yml new file mode 100644 index 00000000..d98ce0ae --- /dev/null +++ b/evocheck/tasks/install_local.yml @@ -0,0 +1,29 @@ +--- +- include: remount_usr_rw.yml + when: evocheck_bin_dir | search ("/usr") + +- name: Scripts dir is present + file: + path: "{{ evocheck_bin_dir }}" + state: directory + owner: root + group: root + mode: "0700" + +- name: Copy evocheck.sh + copy: + src: evocheck.sh + dest: "{{ evocheck_bin_dir }}/evocheck.sh" + mode: "0700" + owner: root + force: yes + tags: + - evocheck + +- name: Copy evocheck.cf + copy: + src: evocheck.cf + dest: /etc/evocheck.cf + force: no + tags: + - evocheck diff --git a/evocheck/tasks/install_package.yml b/evocheck/tasks/install_package.yml new file mode 100644 index 00000000..7a2f875e --- /dev/null +++ b/evocheck/tasks/install_package.yml @@ -0,0 +1,5 @@ +--- +- name: install evocheck from package + apt: + name: evocheck + state: installed diff --git a/evocheck/tasks/main.yml b/evocheck/tasks/main.yml index 664b7c00..769dbbfe 100644 --- a/evocheck/tasks/main.yml +++ b/evocheck/tasks/main.yml @@ -1,31 +1,7 @@ --- -- include: remount_usr_rw.yml - when: evocheck_bin_dir | search ("/usr") +- include: install_local.yml + when: evocheck_force_install == "local" -- name: Scripts dir is present - file: - path: "{{ evocheck_bin_dir }}" - state: directory - owner: root - group: root - mode: "0700" - -- name: Copy evocheck.sh - copy: - src: evocheck.sh - dest: "{{ evocheck_bin_dir }}/evocheck.sh" - mode: "0700" - owner: root - force: yes - backup: yes - tags: - - evocheck - -- name: Copy evocheck.cf - copy: - src: evocheck.cf - dest: /etc/evocheck.cf - force: no - tags: - - evocheck +- include: install_package.yml + when: evocheck_force_install == "package" diff --git a/evolinux-base/README.md b/evolinux-base/README.md index 7e51066c..8ef7a70e 100644 --- a/evolinux-base/README.md +++ b/evolinux-base/README.md @@ -21,7 +21,7 @@ Various tasks for Evolinux setup. ## Available variables -Each tasks group is included in the `main.yml` file with a condition based on a variable like `evolinux_hostname_include` (mostly `True` by default). The variables can be set to `False` to disable a . Finer grained tasks disabling is done in each group of tasks. +Each tasks group is included in the `main.yml` file with a condition based on a variable like `evolinux_hostname_include` (mostly `True` by default). The variables can be set to `False` to disable a task group. Finer grained tasks disabling is done in each group of tasks. Main variables are: @@ -33,7 +33,6 @@ Main variables are: * `evolinux_apt_hooks`: install APT hooks (default: `True`) * `evolinux_apt_remove_aptitude`: uninstall aptitude (default: `True`) * `evolinux_delete_nfs`: delete NFS tools (default: `True`) -* `evolinux_ntp_server`: custom NTP server host or IP (default: `Null`) * `evolinux_additional_packages`: optional additional packages to install (default: `[]`) * `evolinux_postfix_purge_exim`: purge Exim packages (default: `True`) ; * `evolinux_ssh_password_auth_addresses`: list of addresses that can authenticate with a password (default: `[]`) diff --git a/evolinux-base/defaults/main.yml b/evolinux-base/defaults/main.yml index 50635b05..e0c91fd1 100644 --- a/evolinux-base/defaults/main.yml +++ b/evolinux-base/defaults/main.yml @@ -65,7 +65,9 @@ evolinux_packages_system: True evolinux_packages_diagnostic: True evolinux_packages_hardware: True evolinux_packages_common: True +evolinux_packages_stretch: True evolinux_packages_serveur_base: True +evolinux_packages_purge_openntpd: True evolinux_packages_invalid_mta: True evolinux_packages_delete_nfs: True evolinux_packages_listchanges: True @@ -77,14 +79,22 @@ evolinux_system_include: True evolinux_system_chmod_tmp: True evolinux_system_locales: True + +evolinux_system_set_timezone: True evolinux_system_timezone: "Europe/Paris" -evolinux_system_vim_default: True + +evolinux_system_vim_skip_defaults: True +evolinux_system_vim_default_editor: True evolinux_system_profile: True evolinux_system_dirmode_adduser: True +evolinux_system_restrict_securetty: False +evolinux_system_set_timeout: True +evolinux_system_cron_verboselog: True +evolinux_system_cron_umask: True +evolinux_system_cron_random: True evolinux_system_alert5_init: True evolinux_system_alert5_enable: True evolinux_system_eni_auto: True -evolinux_system_ntp_server: False # root @@ -133,15 +143,6 @@ evolinux_default_www_include: True evolinux_default_www_files: True evolinux_default_www_ssl_cert: True -evolinux_default_www_ssl_subject: "/CN={{ ansible_fqdn }}" - -evolinux_default_www_nginx_vhost: True -evolinux_default_www_nginx_enabled: False - -evolinux_default_www_apache_vhost: True -evolinux_default_www_apache_enabled: False - -evolinux_default_www_redirect_url: "http://evolix.fr" # hardware diff --git a/evolinux-base/files/log2mail.service b/evolinux-base/files/log2mail.service new file mode 100644 index 00000000..e941cdb9 --- /dev/null +++ b/evolinux-base/files/log2mail.service @@ -0,0 +1,14 @@ +[Unit] +Description=Daemon watching logfiles and mailing lines matching patterns +After=network.target + +[Service] +Type=forking +ExecStart=/usr/sbin/log2mail -- -f /etc/log2mail/config +KillMode=control-group +Restart=always +User=log2mail +Group=adm + +[Install] +WantedBy=multi-user.target diff --git a/evolinux-base/files/root/gitconfig b/evolinux-base/files/root/gitconfig index 06e6b2a8..126f6f7f 100644 --- a/evolinux-base/files/root/gitconfig +++ b/evolinux-base/files/root/gitconfig @@ -1,22 +1,4 @@ -[core] - filemode = true - bare = false [color] - branch = auto - status = auto - diff = auto - interactive = auto - decorate = auto - grep = auto ui = true -[apply] - whitespace = nowarn [alias] - a = add - aa = add -A . - c = commit -v - ca = commit -v -a - d = diff --ignore-space-change --patience --no-prefix - dw = diff --word-diff lg = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative - s = status -s -b diff --git a/evolinux-base/handlers/main.yml b/evolinux-base/handlers/main.yml index dccd6e9f..80b7378e 100644 --- a/evolinux-base/handlers/main.yml +++ b/evolinux-base/handlers/main.yml @@ -52,6 +52,10 @@ name: apache2 state: reloaded +- name: restart cron + service: + name: cron + state: restarted - name: newaliases command: newaliases @@ -67,3 +71,4 @@ service: name: postfix state: reloaded + diff --git a/evolinux-base/tasks/apt.yml b/evolinux-base/tasks/apt.yml index 43369eca..bb0be3fc 100644 --- a/evolinux-base/tasks/apt.yml +++ b/evolinux-base/tasks/apt.yml @@ -1,10 +1,10 @@ --- - include_role: - name: apt-repositories + name: apt vars: - apt_repositories_install_basics: "{{ evolinux_apt_replace_default_sources }}" - apt_repositories_install_evolix_public: "{{ evolinux_apt_public_sources }}" + apt_install_basics: "{{ evolinux_apt_replace_default_sources }}" + apt_install_evolix_public: "{{ evolinux_apt_public_sources }}" - name: Setting apt config lineinfile: @@ -14,8 +14,8 @@ state: present mode: "0640" with_items: - - "APT::Install-Recommends \"0\";" - - "APT::Install-Suggests \"0\";" + - "APT::Install-Recommends \"false\";" + - "APT::Install-Suggests \"false\";" when: evolinux_apt_conf - name: DPKg invoke hooks @@ -26,8 +26,10 @@ state: present mode: "0640" with_items: - - "DPkg::Pre-Invoke { \"mount -oremount,exec /tmp && mount -oremount,rw /usr || true\"; };" - - "DPkg::Post-Invoke { \"mount -oremount /tmp && mount -oremount /usr || exit 0\"; };" + - "DPkg::Pre-Invoke { \"df /tmp | grep -q /tmp && mount -oremount,exec /tmp || 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 /usr | grep -q /usr && mount -oremount /usr || true\"; };" when: evolinux_apt_hooks - name: Remove Aptitude diff --git a/evolinux-base/tasks/default_www.yml b/evolinux-base/tasks/default_www.yml index 0fdf03f9..d27ad70f 100644 --- a/evolinux-base/tasks/default_www.yml +++ b/evolinux-base/tasks/default_www.yml @@ -20,18 +20,15 @@ src: default_www/index.html.j2 dest: /var/www/index.html mode: "0755" + force: no when: evolinux_default_www_files # SSL cert - block: - - name: ssl-cert package is installed - apt: - name: ssl-cert - state: present - name: Create private key and csr for default site ({{ ansible_fqdn }}) - command: openssl req -newkey rsa:2048 -sha256 -nodes -keyout /etc/ssl/private/{{ ansible_fqdn }}.key -out /etc/ssl/{{ ansible_fqdn }}.csr -batch -subj "{{ evolinux_default_www_ssl_subject }}" + command: openssl req -newkey rsa:2048 -sha256 -nodes -keyout /etc/ssl/private/{{ ansible_fqdn }}.key -out /etc/ssl/{{ ansible_fqdn }}.csr -batch -subj "/CN={{ ansible_fqdn }}" args: creates: "/etc/ssl/private/{{ ansible_fqdn }}.key" @@ -48,67 +45,4 @@ creates: "/etc/ssl/certs/{{ ansible_fqdn }}.crt" when: evolinux_default_www_ssl_cert -# Nginx vhost - -- name: is Nginx installed? - stat: - path: /etc/nginx/sites-available - check_mode: no - register: nginx_sites_available - -- block: - - name: nginx vhost is installed - template: - src: default_www/nginx_default_site.j2 - dest: /etc/nginx/sites-available/000-default - mode: "0640" - # force: yes - notify: reload nginx - tags: - - nginx - - - name: nginx vhost is enabled - file: - src: /etc/nginx/sites-available/000-default - dest: /etc/nginx/sites-enabled/000-default - state: link - notify: reload nginx - when: evolinux_default_www_nginx_enabled - tags: - - nginx - - when: evolinux_default_www_nginx_vhost and nginx_sites_available.stat.exists - - -# Apache vhost - -- name: is Apache installed? - stat: - path: /etc/apache2/sites-available - check_mode: no - register: apache_sites_available - -- block: - - name: Apache vhost is installed - template: - src: default_www/apache_default_site.j2 - dest: /etc/apache2/sites-available/000-default.conf - mode: "0640" - # force: yes - notify: reload apache - tags: - - apache - - - name: Apache vhost is enabled - file: - src: /etc/apache2/sites-available/000-default.conf - dest: /etc/apache2/sites-enabled/000-default.conf - state: link - notify: reload apache - when: evolinux_default_www_apache_enabled - tags: - - apache - - when: evolinux_default_www_apache_vhost and apache_sites_available.stat.exists - - meta: flush_handlers diff --git a/evolinux-base/tasks/fstab.yml b/evolinux-base/tasks/fstab.yml index 42ebb79d..6c8b122a 100644 --- a/evolinux-base/tasks/fstab.yml +++ b/evolinux-base/tasks/fstab.yml @@ -14,7 +14,6 @@ dest: /etc/fstab regexp: '([^#]\s+/home\s+\S+\s+)([a-z,]+)(\s+)' replace: '\1{{ evolinux_fstab_home_options | mandatory }}\3' - backup: yes notify: remount /home when: - "' /home ' in fstab_content.stdout" @@ -25,7 +24,6 @@ dest: /etc/fstab regexp: '([^#]\s+/tmp\s+\S+\s+)([a-z,]+)(\s+)' replace: '\1{{ evolinux_fstab_tmp_options | mandatory }}\3' - backup: yes when: - "' /tmp ' in fstab_content.stdout" - evolinux_fstab_tmp @@ -35,7 +33,6 @@ dest: /etc/fstab regexp: '([^#]\s+/usr\s+\S+\s+)([a-z,]+)(\s+)' replace: '\1{{ evolinux_fstab_usr_options | mandatory }}\3' - backup: yes when: - "' /usr ' in fstab_content.stdout" - evolinux_fstab_usr @@ -45,7 +42,6 @@ dest: /etc/fstab regexp: '([^#]\s+/var\s+\S+\s+)([a-z,]+)(\s+)' replace: '\1{{ evolinux_fstab_var_options | mandatory }}\3' - backup: yes notify: remount /var when: - "' /var ' in fstab_content.stdout" diff --git a/evolinux-base/tasks/hardware.yml b/evolinux-base/tasks/hardware.yml index c74b25fe..69ab0889 100644 --- a/evolinux-base/tasks/hardware.yml +++ b/evolinux-base/tasks/hardware.yml @@ -18,10 +18,10 @@ - name: Add non-free repo for Broadcom NetXtreme II include_role: - name: apt-repositories + name: apt tasks_from: basics.yml vars: - apt_repositories_basics_components: "main contrib non-free" + apt_basics_components: "main contrib non-free" when: broadcom|success ## RAID diff --git a/evolinux-base/tasks/log2mail.yml b/evolinux-base/tasks/log2mail.yml new file mode 100644 index 00000000..e6f624c1 --- /dev/null +++ b/evolinux-base/tasks/log2mail.yml @@ -0,0 +1,18 @@ +--- +- name: Deploy log2mail systemd unit + copy: + src: log2mail.service + dest: /etc/systemd/system/log2mail.service + mode: "0644" + +- name: Remove log2mail sysvinit service + file: + path: /etc/init.d/log2mail + state: absent + +- name: Enable and start log2mail service + systemd: + name: log2mail + daemon-reload: yes + state: started + enabled: yes diff --git a/evolinux-base/tasks/main.yml b/evolinux-base/tasks/main.yml index 44eb7f70..5c1ad594 100644 --- a/evolinux-base/tasks/main.yml +++ b/evolinux-base/tasks/main.yml @@ -1,4 +1,10 @@ --- + +- fail: + msg: only compatible with Debian >= 8 + when: + - ansible_distribution != "Debian" or ansible_distribution_major_version | version_compare('8', '<') + - name: Hostname include: hostname.yml when: evolinux_hostname_include @@ -54,3 +60,7 @@ - name: Customize for Orange FCE include: provider_orange_fce.yml when: evolinux_provider_orange_fce_include + +- name: Override Logmail service + include: log2mail.yml + when: evolinux_packages_serveur_base diff --git a/evolinux-base/tasks/packages.yml b/evolinux-base/tasks/packages.yml index a4a95dbb..effa7c0c 100644 --- a/evolinux-base/tasks/packages.yml +++ b/evolinux-base/tasks/packages.yml @@ -6,7 +6,6 @@ with_items: - locales - sudo - - ntp - ntpdate - lsb-release - dnsutils @@ -15,6 +14,8 @@ - conntrack - logrotate - bash-completion + - ssl-cert + - ca-certificates when: evolinux_packages_system - name: Install/Update diagnostic tools @@ -64,6 +65,22 @@ allow_unauthenticated: yes when: evolinux_packages_serveur_base +- name: Be sure that openntpd package is absent/purged + apt: + name: openntpd + state: absent + purge: yes + when: evolinux_packages_purge_openntpd + +- name: Install/Update packages for Stretch and later + apt: + name: "{{ item }}" + with_items: + - net-tools + when: + - evolinux_packages_stretch + - ansible_distribution_major_version | version_compare('9', '>=') + - name: Customize logcheck recipient lineinfile: dest: /etc/logcheck/logcheck.conf @@ -71,20 +88,6 @@ line: 'SENDMAILTO="{{ logcheck_alert_email or general_alert_email | mandatory }}"' when: evolinux_packages_logcheck_recipient -- name: is an MTA installed? - command: "dpkg -S /usr/sbin/sendmail" - check_mode: no - - register: mta_installed - failed_when: False - changed_when: False - -- name: Install lsb-invalid-mta - apt: - name: lsb-invalid-mta - when: evolinux_packages_invalid_mta and mta_installed.rc != 0 - - - name: Deleting rpcbin and nfs-common apt: name: "{{ item }}" @@ -105,6 +108,8 @@ with_items: - { option: "confirm", value: "1" } - { option: "which", value: "both" } - when: evolinux_packages_listchanges + when: + - evolinux_packages_listchanges + - ansible_distribution_release == "jessie" - meta: flush_handlers diff --git a/evolinux-base/tasks/root.yml b/evolinux-base/tasks/root.yml index 56aaa7cb..ffe64fe1 100644 --- a/evolinux-base/tasks/root.yml +++ b/evolinux-base/tasks/root.yml @@ -73,13 +73,11 @@ state: present with_items: - "syntax on" - - "set hlsearch" - "set background=dark" - "set expandtab" - "set tabstop=4" - - "set softtabstop=0" + - "set softtabstop=4" - "set shiftwidth=4" - - "set smarttab" when: evolinux_root_vim_conf - meta: flush_handlers diff --git a/evolinux-base/tasks/ssh.yml b/evolinux-base/tasks/ssh.yml index ddfbd38c..2b7273b5 100644 --- a/evolinux-base/tasks/ssh.yml +++ b/evolinux-base/tasks/ssh.yml @@ -1,29 +1,55 @@ --- -- name: verify Match Address directive - command: "grep 'Match Address' /etc/ssh/sshd_config" - changed_when: False - failed_when: False - check_mode: no +- debug: + msg: "Warning: empty 'evolinux_ssh_password_auth_addresses' variable, tasks will be skipped!" + when: evolinux_ssh_password_auth_addresses == [] - register: grep_matchaddress_ssh - -- name: Add Match Address sshd directive - lineinfile: +- name: Security directives for Evolinux + blockinfile: dest: /etc/ssh/sshd_config - line: "\nMatch Address {{ evolinux_ssh_password_auth_addresses | join(',') }}\n PasswordAuthentication yes" + block: | + Match Group evolinux-sudo + PasswordAuthentication no + Match Address {{ evolinux_ssh_password_auth_addresses | join(',') }} + PasswordAuthentication yes + marker: "# {mark} EVOLINUX PASSWORD RESTRICTIONS" + insertafter: EOF 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 != [] + when: not 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: verify Match Address directive +# command: "grep 'Match Address' /etc/ssh/sshd_config" +# 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: @@ -33,6 +59,8 @@ notify: reload sshd when: evolinux_ssh_disable_root +# 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. - name: disable AcceptEnv in ssh config replace: dest: /etc/ssh/sshd_config @@ -44,11 +72,9 @@ - name: Set log level to verbose (for Debian >= 9) replace: dest: /etc/ssh/sshd_config - regexp: '^LogLevel [A-Z]+' + regexp: '^#?LogLevel [A-Z]+' replace: "LogLevel VERBOSE" notify: reload sshd - when: - - ansible_distribution == "Debian" - - ansible_distribution_major_version | version_compare('9.0', '>=') + when: ansible_distribution_major_version | version_compare('9', '>=') - meta: flush_handlers diff --git a/evolinux-base/tasks/system.yml b/evolinux-base/tasks/system.yml index 732f52db..261ef1a9 100644 --- a/evolinux-base/tasks/system.yml +++ b/evolinux-base/tasks/system.yml @@ -25,29 +25,28 @@ when: evolinux_system_locales and default_locales | changed - name: Setting default timezone - lineinfile: - dest: /etc/timezone - regexp: '^\w+/\w+$' - line: "{{ evolinux_system_timezone | mandatory }}" - insertbefore: BOF - create: yes - register: change_timezone - when: evolinux_system_timezone != False - -- name: Reconfigure tzdata - command: dpkg-reconfigure --frontend noninteractive tzdata - when: evolinux_system_timezone != False and change_timezone | changed + timezone: + name: "{{ evolinux_system_timezone | mandatory }}" + notify: restart cron + when: evolinux_system_set_timezone # TODO : find a way to force the console-data configuration # non-interactively (like tzdata ↑) - include: remount_usr_rw.yml +- name: Ensure automagic vim conf is disabled + lineinfile: + dest: /etc/vim/vimrc + regexp: 'let g:skip_defaults_vim =' + line: 'let g:skip_defaults_vim = 1' + when: evolinux_system_vim_skip_defaults + - name: Setting vim as default editor alternatives: name: editor path: /usr/bin/vim.basic - when: evolinux_system_vim_default + when: evolinux_system_vim_default_editor - name: Add "umask 027" to /etc/profile.d/evolinux.sh lineinfile: @@ -72,47 +71,48 @@ line: "tty2" create: yes state: present - when: evolinux_system_dirmode_adduser + when: evolinux_system_restrict_securetty -- name: Setting TMOUT to deconnect inactive users +- name: Setting TMOUT to disconnect inactive users lineinfile: - dest: /etc/profile + dest: /etc/profile.d/evolinux.sh line: "export TMOUT=36000" + create: yes state: present - when: evolinux_system_dirmode_adduser + when: evolinux_system_set_timeout #- name: Customizing /etc/fstab +- name: Set verbose logging for cron deamon + lineinfile: + dest: /etc/default/cron + line: "EXTRA_OPTS='-L 15'" + create: yes + state: present + when: evolinux_system_cron_verboselog + - name: Modify default umask for cron deamon lineinfile: dest: /etc/default/cron line: "umask 022" create: yes state: present - when: evolinux_system_dirmode_adduser + when: evolinux_system_cron_umask - name: Randomize periodic crontabs replace: dest: /etc/crontab regexp: "{{ item.regexp }}" replace: "{{ item.replace }}" - backup: "{{ item.backup }}" with_items: - - {regexp: '^17((\s*\*){4})', replace: '{{ 59|random(start=1) }}\1', backup: "yes"} - - {regexp: '^25\s*6((\s*\*){3})', replace: '{{ 59|random(start=1) }} {{ [0,1,3,4,5,6,7]|random }}\1', backup: "no"} - - {regexp: '^47\s*6((\s*\*){2}\s*7)', replace: '{{ 59|random(start=1) }} {{ [0,1,3,4,5,6,7]|random }}\1', backup: "no"} - - {regexp: '^52\s*6(\s*1(\s*\*){2})', replace: '{{ 59|random(start=1) }} {{ [0,1,3,4,5,6,7]|random }}\1', backup: "no"} - when: evolinux_system_dirmode_adduser + - { regexp: '^17((\s*\*){4})', replace: '{{ 59|random(start=1) }}\1' } + - { regexp: '^25\s*6((\s*\*){3})', replace: '{{ 59|random(start=1) }} {{ [0,1,3,4,5,6,7]|random }}\1' } + - { regexp: '^47\s*6((\s*\*){2}\s*7)', replace: '{{ 59|random(start=1) }} {{ [0,1,3,4,5,6,7]|random }}\1' } + - { regexp: '^52\s*6(\s*1(\s*\*){2})', replace: '{{ 59|random(start=1) }} {{ [0,1,3,4,5,6,7]|random }}\1' } + when: evolinux_system_cron_random -# NTP server address - -- name: Configure NTP - replace: - dest: /etc/ntp.conf - regexp: "^server .*$" - replace: "server {{ evolinux_system_ntp_server }}" - backup: yes - when: evolinux_system_ntp_server != False +- include_role: + name: ntpd ## alert5 @@ -154,7 +154,6 @@ dest: /etc/network/interfaces regexp: "allow-hotplug" replace: "auto" - backup: yes when: evolinux_system_eni_auto and grep_hotplug_eni.rc == 0 - meta: flush_handlers diff --git a/evolinux-base/templates/default_www/apache_default_site.j2 b/evolinux-base/templates/default_www/apache_default_site.j2 deleted file mode 100644 index 8f29785a..00000000 --- a/evolinux-base/templates/default_www/apache_default_site.j2 +++ /dev/null @@ -1,55 +0,0 @@ - - ServerName {{ ansible_fqdn }} - ServerAdmin webmaster@localhost - DocumentRoot /var/www/ - - SSLEngine on - SSLCertificateFile /etc/ssl/certs/{{ ansible_fqdn }}.crt - SSLCertificateKeyFile /etc/ssl/private/{{ ansible_fqdn }}.key - SSLProtocol all -SSLv2 -SSLv3 - - # Redirect to HTTPS, execpt for server-status, because Munin plugin - # can't handle HTTPS! :( - RewriteEngine on - RewriteCond %{REQUEST_URI} !^/server-status.*$ [NC] - RewriteCond %{REQUEST_URI} !^/munin_opcache.php$ [NC] - RewriteRule ^/(.*) https://{{ ansible_fqdn }}/$1 [L,R=permanent] - - - Options FollowSymLinks - AllowOverride None - Deny from all - Include /etc/apache2/private_ipaddr_whitelist.conf - - - - Options Indexes FollowSymLinks MultiViews - AllowOverride None - - - - Deny from all - Allow from 127.0.0.1 - Include /etc/apache2/private_ipaddr_whitelist.conf - - - ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/ - - AllowOverride None - Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch - - - ErrorDocument 403 {{ evolinux_default_www_redirect_url }} - CustomLog /var/log/apache2/access.log vhost_combined - ErrorLog /var/log/apache2/error.log - LogLevel warn - - Alias /munin /var/cache/munin/www - Alias /phpmyadmin-SED_RANDOM /usr/share/phpmyadmin/ - IncludeOptional /etc/apache2/conf-available/phpmyadmin* - - - deny from all - - - diff --git a/evolinux-base/templates/default_www/index.html.j2 b/evolinux-base/templates/default_www/index.html.j2 index 25a967b4..f7d5c428 100644 --- a/evolinux-base/templates/default_www/index.html.j2 +++ b/evolinux-base/templates/default_www/index.html.j2 @@ -6,50 +6,49 @@ {{ ansible_hostname }} @@ -57,20 +56,22 @@

{{ ansible_hostname }}

-
diff --git a/evomaintenance/tasks/main.yml b/evomaintenance/tasks/main.yml index 9fbc10b4..4be99c58 100644 --- a/evomaintenance/tasks/main.yml +++ b/evomaintenance/tasks/main.yml @@ -1,7 +1,7 @@ --- - name: Install Evolix public repositry include_role: - name: apt-repositories + name: apt tasks_from: evolix_public.yml - name: evomaintenance is installed @@ -14,14 +14,19 @@ src: evomaintenance.j2 dest: /etc/evomaintenance.cf -- name: list users with a shell - shell: "cat /etc/passwd | grep -vE \"^root:\" | grep -E \":/[^:]+sh$\" | cut -d: -f6" - changed_when: False - check_mode: no - register: home_of_shell_users +# - name: list users with a shell +# shell: "cat /etc/passwd | grep -vE \"^root:\" | grep -E \":/[^:]+sh$\" | cut -d: -f6" +# changed_when: False +# check_mode: no +# register: home_of_shell_users +# +# - include: trap.yml home={{ item }} +# with_items: "{{ home_of_shell_users.stdout_lines }}" -- include: trap.yml home={{ item }} - with_items: "{{ home_of_shell_users.stdout_lines }}" +- name: Is minifirewall installed? + stat: + path: /etc/default/minifirewall + register: minifirewall_default_file - name: minifirewall section for evomaintenance lineinfile: @@ -29,9 +34,11 @@ line: "/sbin/iptables -A INPUT -p tcp --sport 5432 --dport 1024:65535 -s {{ item }} -m state --state ESTABLISHED,RELATED -j ACCEPT" insertafter: "^# EvoMaintenance" with_items: "{{ evomaintenance_hosts }}" + when: minifirewall_default_file.stat.exists - name: remove minifirewall example rule for the proxy lineinfile: dest: /etc/default/minifirewall regexp: '^#.*(--sport 5432).*(-s X\.X\.X\.X)' state: absent + when: minifirewall_default_file.stat.exists diff --git a/fail2ban/README.md b/fail2ban/README.md index 55168279..af94e38a 100644 --- a/fail2ban/README.md +++ b/fail2ban/README.md @@ -12,5 +12,6 @@ Main variables are : * `general_alert_email`: email address to send various alert messages (default: `root@localhost`). * `fail2ban_alert_email`: email address for messages sent to root (default: `general_alert_email`). +* `fail2ban_ignore_ips`: list of IPs to ignore (default: empty). The full list of variables (with default values) can be found in `defaults/main.yml`. diff --git a/fail2ban/defaults/main.yml b/fail2ban/defaults/main.yml index f08bdf6a..2fe40951 100644 --- a/fail2ban/defaults/main.yml +++ b/fail2ban/defaults/main.yml @@ -1,4 +1,4 @@ --- general_alert_email: "root@localhost" fail2ban_alert_email: Null -fail2ban_ignoreip: [] +fail2ban_ignore_ips: [] diff --git a/fail2ban/tasks/main.yml b/fail2ban/tasks/main.yml index b5583a98..7a47a0ce 100644 --- a/fail2ban/tasks/main.yml +++ b/fail2ban/tasks/main.yml @@ -1,4 +1,27 @@ --- +# We have to copy the local jail before installing the package +# or we risk being jailed by fail2ban + +- name: Prepare /etc/fail2ban + file: + path: /etc/fail2ban + state: directory + owner: root + group: root + mode: "0755" + tags: + - fail2ban + +- name: local jail is installed + template: + src: jail.local.j2 + dest: /etc/fail2ban/jail.local + mode: "0644" + force: no + notify: restart fail2ban + tags: + - fail2ban + - name: package is installed apt: name: fail2ban @@ -18,12 +41,3 @@ notify: restart fail2ban tags: - fail2ban - -- name: local jail is installed - template: - src: jail.local.j2 - dest: /etc/fail2ban/jail.local - mode: "0644" - notify: restart fail2ban - tags: - - fail2ban diff --git a/fail2ban/templates/jail.local.j2 b/fail2ban/templates/jail.local.j2 index 01b83d46..2f4d6bc3 100644 --- a/fail2ban/templates/jail.local.j2 +++ b/fail2ban/templates/jail.local.j2 @@ -3,11 +3,7 @@ [DEFAULT] # "ignoreip" can be an IP address, a CIDR mask or a DNS host -ignoreip = \ -{% for ip in fail2ban_ignoreip %} -{{ ip }} \ -{% endfor %} -127.0.0.1/8 +ignoreip = {{ (['127.0.0.1/8'] + fail2ban_ignore_ips) | join(' ') }} bantime = 600 maxretry = 3 diff --git a/filebeat/files/elasticsearch.key b/filebeat/files/elasticsearch.key new file mode 100644 index 00000000..1b50dcca --- /dev/null +++ b/filebeat/files/elasticsearch.key @@ -0,0 +1,31 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v2.0.14 (GNU/Linux) + +mQENBFI3HsoBCADXDtbNJnxbPqB1vDNtCsqhe49vFYsZN9IOZsZXgp7aHjh6CJBD +A+bGFOwyhbd7at35jQjWAw1O3cfYsKAmFy+Ar3LHCMkV3oZspJACTIgCrwnkic/9 +CUliQe324qvObU2QRtP4Fl0zWcfb/S8UYzWXWIFuJqMvE9MaRY1bwUBvzoqavLGZ +j3SF1SPO+TB5QrHkrQHBsmX+Jda6d4Ylt8/t6CvMwgQNlrlzIO9WT+YN6zS+sqHd +1YK/aY5qhoLNhp9G/HxhcSVCkLq8SStj1ZZ1S9juBPoXV1ZWNbxFNGwOh/NYGldD +2kmBf3YgCqeLzHahsAEpvAm8TBa7Q9W21C8vABEBAAG0RUVsYXN0aWNzZWFyY2gg +KEVsYXN0aWNzZWFyY2ggU2lnbmluZyBLZXkpIDxkZXZfb3BzQGVsYXN0aWNzZWFy +Y2gub3JnPokBOAQTAQIAIgUCUjceygIbAwYLCQgHAwIGFQgCCQoLBBYCAwECHgEC +F4AACgkQ0n1mbNiOQrRzjAgAlTUQ1mgo3nK6BGXbj4XAJvuZDG0HILiUt+pPnz75 +nsf0NWhqR4yGFlmpuctgCmTD+HzYtV9fp9qW/bwVuJCNtKXk3sdzYABY+Yl0Cez/ +7C2GuGCOlbn0luCNT9BxJnh4mC9h/cKI3y5jvZ7wavwe41teqG14V+EoFSn3NPKm +TxcDTFrV7SmVPxCBcQze00cJhprKxkuZMPPVqpBS+JfDQtzUQD/LSFfhHj9eD+Xe +8d7sw+XvxB2aN4gnTlRzjL1nTRp0h2/IOGkqYfIG9rWmSLNlxhB2t+c0RsjdGM4/ +eRlPWylFbVMc5pmDpItrkWSnzBfkmXL3vO2X3WvwmSFiQbkBDQRSNx7KAQgA5JUl +zcMW5/cuyZR8alSacKqhSbvoSqqbzHKcUQZmlzNMKGTABFG1yRx9r+wa/fvqP6OT +RzRDvVS/cycws8YX7Ddum7x8uI95b9ye1/Xy5noPEm8cD+hplnpU+PBQZJ5XJ2I+ +1l9Nixx47wPGXeClLqcdn0ayd+v+Rwf3/XUJrvccG2YZUiQ4jWZkoxsA07xx7Bj+ +Lt8/FKG7sHRFvePFU0ZS6JFx9GJqjSBbHRRkam+4emW3uWgVfZxuwcUCn1ayNgRt +KiFv9jQrg2TIWEvzYx9tywTCxc+FFMWAlbCzi+m4WD+QUWWfDQ009U/WM0ks0Kww +EwSk/UDuToxGnKU2dQARAQABiQEfBBgBAgAJBQJSNx7KAhsMAAoJENJ9ZmzYjkK0 +c3MIAIE9hAR20mqJWLcsxLtrRs6uNF1VrpB+4n/55QU7oxA1iVBO6IFu4qgsF12J +TavnJ5MLaETlggXY+zDef9syTPXoQctpzcaNVDmedwo1SiL03uMoblOvWpMR/Y0j +6rm7IgrMWUDXDPvoPGjMl2q1iTeyHkMZEyUJ8SKsaHh4jV9wp9KmC8C+9CwMukL7 +vM5w8cgvJoAwsp3Fn59AxWthN3XJYcnMfStkIuWgR7U2r+a210W6vnUxU4oN0PmM +cursYPyeV0NX/KQeUeNMwGTFB6QHS/anRaGQewijkrYYoTNtfllxIu9XYmiBERQ/ +qPDlGRlOgVTd9xUfHFkzB52c70E= +=92oX +-----END PGP PUBLIC KEY BLOCK----- diff --git a/filebeat/tasks/main.yml b/filebeat/tasks/main.yml index a18a02b5..bc038b93 100644 --- a/filebeat/tasks/main.yml +++ b/filebeat/tasks/main.yml @@ -1,15 +1,39 @@ --- -- name: Install Elastic sources list - include_role: - name: elastic-sources-list +- name: APT https transport is enabled + apt: + name: apt-transport-https + state: present + tags: + - filebeat + - packages + +- name: Elastic GPG key is installed + apt_key: + # url: https://artifacts.elastic.co/GPG-KEY-elasticsearch + data: "{{ lookup('file', 'elasticsearch.key') }}" + state: present + tags: + - filebeat + - packages + +- name: Elastic sources list is available + apt_repository: + repo: "deb https://artifacts.elastic.co/packages/5.x/apt stable main" + filename: elastic.list + state: present + update_cache: yes + tags: + - filebeat + - packages - name: Filebeat is installed apt: name: filebeat state: present tags: - - packages + - filebeat + - packages - name: Filebeat service is enabled service: diff --git a/haproxy-backports-preferences/.kitchen.yml b/haproxy-backports-preferences/.kitchen.yml deleted file mode 100644 index b21cc3db..00000000 --- a/haproxy-backports-preferences/.kitchen.yml +++ /dev/null @@ -1,28 +0,0 @@ ---- -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 - -suites: - - name: default - provisioner: - name: ansible_playbook - playbook: ./tests/test.yml - -transport: - max_ssh_sessions: 6 diff --git a/haproxy-backports-preferences/README.md b/haproxy-backports-preferences/README.md deleted file mode 100644 index ad4ffbf9..00000000 --- a/haproxy-backports-preferences/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# haproxy-backports-preferences - -Configure APT to prefer haproxy package from jessie-backports. - -There is no variable, just a files copied to `/etc/apt/preferences.d/`. diff --git a/haproxy-backports-preferences/handlers/main.yml b/haproxy-backports-preferences/handlers/main.yml deleted file mode 100644 index e68f5c28..00000000 --- a/haproxy-backports-preferences/handlers/main.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -- name: apt update - apt: - update_cache: yes diff --git a/haproxy-backports-preferences/meta/main.yml b/haproxy-backports-preferences/meta/main.yml deleted file mode 100644 index 9483c01e..00000000 --- a/haproxy-backports-preferences/meta/main.yml +++ /dev/null @@ -1,19 +0,0 @@ -galaxy_info: - author: Evolix - description: Configure APT to prefer haproxy package from jessie-backports - - issue_tracker_url: https://forge.evolix.org/projects/ansible-roles/issues - - license: GPLv2 - - min_ansible_version: 2.2 - - platforms: - - name: Debian - versions: - - jessie - -dependencies: [] - # List your role dependencies here, one per line. - # Be sure to remove the '[]' above if you add dependencies - # to this list. diff --git a/haproxy-backports-preferences/tasks/main.yml b/haproxy-backports-preferences/tasks/main.yml deleted file mode 100644 index 8d096541..00000000 --- a/haproxy-backports-preferences/tasks/main.yml +++ /dev/null @@ -1,10 +0,0 @@ ---- -- name: Prefer HAProxy package from jessie-backports - copy: - src: haproxy_preferences - dest: /etc/apt/preferences.d/999-haproxy - force: yes - mode: "0640" - notify: apt update - -- meta: flush_handlers diff --git a/haproxy-backports-preferences/tests/test.yml b/haproxy-backports-preferences/tests/test.yml deleted file mode 100644 index 8d667e49..00000000 --- a/haproxy-backports-preferences/tests/test.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -- hosts: test-kitchen - roles: - - role: haproxy-backports-preferences diff --git a/haproxy/README.md b/haproxy/README.md index 864a9601..9f597baa 100644 --- a/haproxy/README.md +++ b/haproxy/README.md @@ -8,7 +8,7 @@ Everything is in the `tasks/main.yml` file. ## Available variables -There is no variable. +* `haproxy_jessie_backports` : on Debian Jessie, we can prefer v1.7 from backports (default: `False`) ## Configuration templates diff --git a/haproxy/defaults/main.yml b/haproxy/defaults/main.yml new file mode 100644 index 00000000..ea4a8e38 --- /dev/null +++ b/haproxy/defaults/main.yml @@ -0,0 +1,3 @@ +--- + +haproxy_jessie_backports: False diff --git a/haproxy/files/check_haproxy_stats.pl b/haproxy/files/check_haproxy_stats.pl new file mode 100644 index 00000000..14d4fa45 --- /dev/null +++ b/haproxy/files/check_haproxy_stats.pl @@ -0,0 +1,282 @@ +#!/usr/bin/env perl +# vim: se et ts=4: + +# +# Copyright (C) 2012, Giacomo Montagner +# 2015, Yann Fertat, Romain Dessort, Jeff Palmer, +# Christophe Drevet-Droguet +# +# This program is free software; you can redistribute it and/or modify it +# under the same terms as Perl 5.10.1. +# For more details, see http://dev.perl.org/licenses/artistic.html +# +# This program is distributed in the hope that it will be +# useful, but without any warranty; without even the implied +# warranty of merchantability or fitness for a particular purpose. +# + +our $VERSION = "1.1.1"; + +open(STDERR, ">&STDOUT"); + +# CHANGELOG: +# 1.0.0 - first release +# 1.0.1 - fixed empty message if all proxies are OK +# 1.0.2 - add perfdata +# 1.0.3 - redirect stderr to stdout +# 1.0.4 - fix undef vars +# 1.0.5 - fix thresholds +# 1.1.0 - support for HTTP interface +# 1.1.1 - drop perl 5.10 requirement + +use strict; +use warnings; +use File::Basename qw/basename/; +use IO::Socket::UNIX; +use Getopt::Long; +my $lwp = eval { + require LWP::Simple; + LWP::Simple->import; + 1; +}; + +sub usage { + my $me = basename $0; + print <. + $me is distributed under GPL and the Artistic License 2.0 +SEE ALSO + Check out online haproxy documentation at +EOU +} + +my %check_statuses = ( + UNK => "unknown", + INI => "initializing", + SOCKERR => "socket error", + L4OK => "layer 4 check OK", + L4CON => "connection error", + L4TMOUT => "layer 1-4 timeout", + L6OK => "layer 6 check OK", + L6TOUT => "layer 6 (SSL) timeout", + L6RSP => "layer 6 protocol error", + L7OK => "layer 7 check OK", + L7OKC => "layer 7 conditionally OK", + L7TOUT => "layer 7 (HTTP/SMTP) timeout", + L7RSP => "layer 7 protocol error", + L7STS => "layer 7 status error", +); + +my @status_names = (qw/OK WARNING CRITICAL UNKNOWN/); + +# Defaults +my $swarn = 80.0; +my $scrit = 90.0; +my $sock = "/var/run/haproxy.sock"; +my $url; +my $user = ''; +my $pass = ''; +my $dump; +my $ignore_maint; +my $proxy; +my $no_proxy; +my $help; + +# Read command line +Getopt::Long::Configure ("bundling"); +GetOptions ( + "c|critical=i" => \$scrit, + "d|dump" => \$dump, + "h|help" => \$help, + "m|ignore-maint" => \$ignore_maint, + "p|proxy=s" => \$proxy, + "P|no-proxy=s" => \$no_proxy, + "s|sock|socket=s" => \$sock, + "U|url=s" => \$url, + "u|user|username=s" => \$user, + "x|pass|password=s" => \$pass, + "w|warning=i" => \$swarn, +); + +# Want help? +if ($help) { + usage; + exit 3; +} + +my $haproxy; +if ($url and $lwp) { + my $geturl = $url; + if ($user ne '') { + $url =~ /^([^:]*:\/\/)(.*)/; + $geturl = $1.$user.':'.$pass.'@'.$2; + } + $geturl .= ';csv'; + $haproxy = get($geturl); +} elsif ($url) { + my $haproxyio; + my $getcmd = "curl --insecure -s --fail " + . "--user '$user:$pass' '".$url.";csv'"; + open $haproxyio, "-|", $getcmd; + while (<$haproxyio>) { + $haproxy .= $_; + } + close($haproxyio); +} else { + # Connect to haproxy socket and get stats + my $haproxyio = new IO::Socket::UNIX ( + Peer => $sock, + Type => SOCK_STREAM, + ); + die "Unable to connect to haproxy socket: $sock\n$@" unless $haproxyio; + print $haproxyio "show stat\n" or die "Print to socket failed: $!"; + $haproxy = ''; + while (<$haproxyio>) { + $haproxy .= $_; + } + close($haproxyio); +} + +# Dump stats and exit if requested +if ($dump) { + print($haproxy); + exit 0; +} + +# Get labels from first output line and map them to their position in the line +my @hastats = ( split /\n/, $haproxy ); +my $labels = $hastats[0]; +die "Unable to retrieve haproxy stats" unless $labels; +chomp($labels); +$labels =~ s/^# // or die "Data format not supported."; +my @labels = split /,/, $labels; +{ + no strict "refs"; + my $idx = 0; + map { $$_ = $idx++ } @labels; +} + +# Variables I will use from here on: +our $pxname; +our $svname; +our $status; +our $slim; +our $scur; + +my @proxies = split ',', $proxy if $proxy; +my @no_proxies = split ',', $no_proxy if $no_proxy; +my $exitcode = 0; +my $msg; +my $checked = 0; +my $perfdata = ""; + +# Remove excluded proxies from the list if both -p and -P options are +# specified. +my %hash; +@hash{@no_proxies} = undef; +@proxies = grep{ not exists $hash{$_} } @proxies; + +foreach (@hastats) { + chomp; + next if /^#/; + next if /^[[:space:]]*$/; + my @data = split /,/, $_; + if (@proxies) { next unless grep {$data[$pxname] eq $_} @proxies; }; + if (@no_proxies) { next if grep {$data[$pxname] eq $_} @no_proxies; }; + + # Is session limit enforced? + if ($data[$slim]) { + $perfdata .= sprintf "%s-%s=%u;%u;%u;0;%u;", $data[$pxname], $data[$svname], $data[$scur], $swarn * $data[$slim] / 100, $scrit * $data[$slim] / 100, $data[$slim]; + + # Check current session # against limit + my $sratio = $data[$scur]/$data[$slim]; + if ($sratio >= $scrit / 100 || $sratio >= $swarn / 100) { + $exitcode = $sratio >= $scrit / 100 ? 2 : + $exitcode < 2 ? 1 : $exitcode; + $msg .= sprintf "%s:%s sessions: %.2f%%; ", $data[$pxname], $data[$svname], $sratio * 100; + } + } + + # Check of BACKENDS + if ($data[$svname] eq 'BACKEND') { + if ($data[$status] ne 'UP') { + $msg .= sprintf "BACKEND: %s is %s; ", $data[$pxname], $data[$status]; + $exitcode = 2; + } + # Check of FRONTENDS + } elsif ($data[$svname] eq 'FRONTEND') { + if ($data[$status] ne 'OPEN') { + $msg .= sprintf "FRONTEND: %s is %s; ", $data[$pxname], $data[$status]; + $exitcode = 2; + } + # Check of servers + } else { + if ($data[$status] ne 'UP') { + next if ($ignore_maint && $data[$status] eq 'MAINT'); + next if $data[$status] eq 'no check'; # Ignore server if no check is configured to be run + next if $data[$svname] eq 'sock-1'; + $exitcode = 2; + our $check_status; + $msg .= sprintf "server: %s:%s is %s", $data[$pxname], $data[$svname], $data[$status]; + $msg .= sprintf " (check status: %s)", $check_statuses{$data[$check_status]} if $check_statuses{$data[$check_status]}; + $msg .= "; "; + } + } + ++$checked; +} + +unless ($msg) { + $msg = @proxies ? sprintf("checked proxies: %s", join ', ', sort @proxies) : "checked $checked proxies."; +} +print "Check haproxy $status_names[$exitcode] - $msg|$perfdata\n"; +exit $exitcode; diff --git a/haproxy/files/haproxy_apt_preferences b/haproxy/files/haproxy_apt_preferences new file mode 100644 index 00000000..bae1e794 --- /dev/null +++ b/haproxy/files/haproxy_apt_preferences @@ -0,0 +1,3 @@ +Package: haproxy libssl1.0.0 +Pin: release a=jessie-backports +Pin-Priority: 999 diff --git a/haproxy/tasks/main.yml b/haproxy/tasks/main.yml index a699b366..054aec1a 100644 --- a/haproxy/tasks/main.yml +++ b/haproxy/tasks/main.yml @@ -5,6 +5,10 @@ state: installed tags: - haproxy + - packages + +- include: packages_jessie_backports.yml + when: ansible_distribution_release == "jessie" and haproxy_jessie_backports - name: Install HAProxy package apt: @@ -12,6 +16,7 @@ state: installed tags: - haproxy + - packages - name: Copy HAProxy configuration template: @@ -26,3 +31,6 @@ notify: reload haproxy tags: - haproxy + - config + +- include: nagios.yml diff --git a/haproxy/tasks/nagios.yml b/haproxy/tasks/nagios.yml new file mode 100644 index 00000000..eff711ac --- /dev/null +++ b/haproxy/tasks/nagios.yml @@ -0,0 +1,20 @@ +--- + +- name: "Install check_haproxy_stats script" + copy: + src: check_haproxy_stats.pl + dest: /usr/local/lib/nagios/plugins/check_haproxy_stats.pl + mode: "0755" + tags: + - haproxy + - nrpe + +- name: "Add check_haproxy to sudoers" + lineinfile: + dest: /etc/sudoers.d/evolinux + line: 'nagios ALL = NOPASSWD: /usr/local/lib/nagios/plugins/check_haproxy_stats.pl' + insertafter: '^nagios' + tags: + - haproxy + - nrpe + - sudo diff --git a/haproxy/tasks/packages_jessie_backports.yml b/haproxy/tasks/packages_jessie_backports.yml new file mode 100644 index 00000000..17218ee6 --- /dev/null +++ b/haproxy/tasks/packages_jessie_backports.yml @@ -0,0 +1,27 @@ +--- + +- include_role: + name: apt + tasks_from: backports.yml + tags: + - haproxy + - packages + +- name: Prefer HAProxy package from jessie-backports + copy: + src: haproxy_apt_preferences + dest: /etc/apt/preferences.d/999-haproxy + force: yes + mode: "0640" + register: haproxy_apt_preferences + tags: + - haproxy + - packages + +- name: update apt + apt: + update_cache: yes + when: haproxy_apt_preferences | changed + tags: + - haproxy + - packages diff --git a/ipsec/files/check_ipsecctl.sh b/ipsec/files/check_ipsecctl.sh deleted file mode 100644 index 4cdeaa94..00000000 --- a/ipsec/files/check_ipsecctl.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/sh -IPSECCTL="/sbin/ipsecctl -s sa" -STATUS=0 - -LINE1=`$IPSECCTL | grep "from $1 to $2" ` -if [ $? -eq 1 ]; then - STATUS=2; - OUTPUT1="No VPN from $1 to $2 " -fi - -LINE2=`$IPSECCTL | grep "from $2 to $1" ` -if [ $? -eq 1 ]; then - STATUS=2; - OUTPUT2="No VPN from $2 to $1" -fi - -if [ $STATUS -eq 0 ]; then - echo "VPN OK - $3 is up" - exit $STATUS -else - echo "VPN DOWN - $3 is down ($OUTPUT1 $OUTPUT2)" - exit $STATUS -fi diff --git a/ipsec/files/check_ipsecctl_multi.sh b/ipsec/files/check_ipsecctl_multi.sh deleted file mode 100644 index 09cf6aa2..00000000 --- a/ipsec/files/check_ipsecctl_multi.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/sh - -CHECK_IPSECCTL="/usr/local/libexec/nagios/check_ipsecctl.sh" -STATUS=0 -VPN_KO="" - -default_int=$(route -n show|grep default|awk '{ print $8 }') -default_ip=$(ifconfig $default_int|grep inet|awk '{ print $2 }') - -for vpn in $(ls /etc/ipsec/); do - vpn=$(basename $vpn .conf) - local_ip=$(grep -E "local_ip" /etc/ipsec/${vpn}.conf|grep -o "[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*") - ifconfig|grep -q $local_ip - [ $? -ne 0 ] && local_ip=$default_ip - remote_ip=$(grep -E "remote_ip" /etc/ipsec/${vpn}.conf|grep -o "[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*") - $CHECK_IPSECCTL $local_ip $remote_ip "$vpn" > /dev/null - if [ $? -ne 0 ]; then - STATUS=2 - VPN_KO="$VPN_KO $vpn" - fi -done - -if [ $STATUS -eq 0 ]; then - echo "ALL VPN(s) UP(s)" - exit 0 -else - echo "VPN(s) down(s) :$VPN_KO" - exit 2 -fi diff --git a/ipsec/tasks/main.yml b/ipsec/tasks/main.yml deleted file mode 100644 index 85d1b69a..00000000 --- a/ipsec/tasks/main.yml +++ /dev/null @@ -1,65 +0,0 @@ ---- -- name: Create /etc/ipsec dir - file: - path: /etc/ipsec - state: directory - mode: "0700" - owner: root - group: wheel - tags: - - ipsec - -- name: Enable and start isakmpd service - service: - name: isakmpd - arguments: '-K' - state: started - enabled: yes - tags: - - ipsec - -- name: Deploy nrpe scripts - copy: - src: "{{ item }}" - dest: /usr/local/libexec/nagios/ - mode: "0755" - with_items: - - 'check_ipsecctl.sh' - - 'check_ipsecctl_multi.sh' - tags: - - ipsec - -- name: Add sudo right to _nrpe for check ipsecctl - lineinfile: - dest: /etc/sudoers - line: "{{ item }}" - state: present - validate: "visudo -cf %s" - with_items: - - "_nrpe ALL=(root) NOPASSWD: /usr/local/libexec/nagios/check_ipsecctl_multi.sh" - - "_nrpe ALL=(root) NOPASSWD: /usr/local/libexec/nagios/check_ipsecctl.sh" - tags: - - ipsec - -- name: "Copy /etc/ipsec/{{ ipsec_name }}.conf" - template: - src: ipsec.conf.j2 - dest: "/etc/ipsec/{{ ipsec_name }}.conf" - mode: "0600" - owner: root - group: wheel - register: ipsec_conf - tags: - - ipsec - -- name: "Check {{ ipsec_name }} config" - command: "ipsecctl -nf /etc/ipsec/{{ ipsec_name }}.conf" - changed_when: false - tags: - - ipsec - -- name: "Reload ipsec {{ ipsec_name }}" - command: "ipsecctl -f /etc/ipsec/{{ ipsec_name }}.conf" - when: ipsec_conf.changed - tags: - - ipsec diff --git a/ipsec/templates/ipsec.conf.j2 b/ipsec/templates/ipsec.conf.j2 deleted file mode 100644 index 862cf686..00000000 --- a/ipsec/templates/ipsec.conf.j2 +++ /dev/null @@ -1,10 +0,0 @@ -local_ip="{{ ipsec_local_ip }}" -local_network="{{ ipsec_local_network }}" - -remote_ip_{{ ipsec_name }}="{{ ipsec_remote_ip }}" -remote_networks_{{ ipsec_name }}="{{ ipsec_remote_network }}" - -ike esp from $local_network to $remote_networks_{{ ipsec_name }} peer $remote_ip_{{ ipsec_name }} \ -main auth hmac-sha2-512 enc aes group modp4096 \ -quick auth hmac-sha2-512 enc aes group modp4096 \ -psk "{{ ipsec_psk }}" diff --git a/java8/tasks/main.yml b/java8/tasks/main.yml index 1ecebbee..22107bd5 100644 --- a/java8/tasks/main.yml +++ b/java8/tasks/main.yml @@ -5,7 +5,7 @@ - name: install jessie-backports include_role: - name: apt-repositories + name: apt tasks_from: backports.yml when: ansible_distribution_release == "jessie" @@ -14,7 +14,6 @@ name: openjdk-8-jre default_release: "{{ java8_apt_release }}" state: present - when: ansible_distribution_release == "jessie" tags: - java - packages diff --git a/jenkins/files/jenkins.key b/jenkins/files/jenkins.key new file mode 100644 index 00000000..bab880e5 --- /dev/null +++ b/jenkins/files/jenkins.key @@ -0,0 +1,144 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1 + +mQGiBEmFQG0RBACXScOxb6BTV6rQE/tcJopAEWsdvmE0jNIRWjDDzB7HovX6Anrq +n7+Vq4spAReSFbBVaYiiOx2cGDymj2dyx2i9NAI/9/cQXJOU+RPdDzHVlO1Edksp +5rKn0cGPWY5sLxRf8s/tO5oyKgwCVgTaB5a8gBHaoGms3nNC4YYf+lqlpwCgjbti +3u1iMIx6Rs+dG0+xw1oi5FUD/2tLJMx7vCUQHhPRupeYFPoD8vWpcbGb5nHfHi4U +8/x4qZspAIwvXtGw0UBHildGpqe9onp22Syadn/7JgMWhHoFw5Ke/rTMlxREL7pa +TiXuagD2G84tjJ66oJP1FigslJzrnG61y85V7THL61OFqDg6IOP4onbsdqHby4VD +zZj9A/9uQxIn5250AGLNpARStAcNPJNJbHOQuv0iF3vnG8uO7/oscB0TYb8/juxr +hs9GdSN0U0BxENR+8KWy5lttpqLMKlKRknQYy34UstQiyFgAQ9Epncu9uIbVDgWt +y7utnqXN033EyYkcWx5EhLAgHkC7wSzeSWABV3JSXN7CeeOif7QiS29oc3VrZSBL +YXdhZ3VjaGkgPGtrQGtvaHN1a2Uub3JnPohjBBMRAgAjAhsDBgsJCAcDAgQVAggD +BBYCAwECHgECF4AFAko/7vYCGQEACgkQm30y8tUFguabhgCgi54IQR4rpJZ/uUHe +ZB879zUWTQwAniQDBO+Zly7Fsvm0Mcvqvl02UzxCiGAEExECACAFAkmFQG0CGwMG +CwkIBwMCBBUCCAMEFgIDAQIeAQIXgAAKCRCbfTLy1QWC5qtXAJ9hPRisOhkexWXJ +nXQMl9cOTvm4LgCdGint1TONoZ2I4JtOiFzOmeP3ju3RzcvNyQEQAAEBAAAAAAAA +AAAAAAAA/9j/4AAQSkZJRgABAQEAYABgAAD/4QBgRXhpZgAASUkqAAgAAAAEADEB +AgAZAAAAPgAAABBRAQABAAAAAUOQABFRBAABAAAAEgsAABJRBAABAAAAEgsAAAAA +AABNYWNyb21lZGlhIEZpcmV3b3JrcyA0LjAAAP/bAEMACAYGBwYFCAcHBwkJCAoM +FA0MCwsMGRITDxQdGh8eHRocHCAkLicgIiwjHBwoNyksMDE0NDQfJzk9ODI8LjM0 +Mv/bAEMBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy +MjIyMjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIAK4AlgMBIgACEQEDEQH/xAAfAAAB +BQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgv/xAC1EAACAQMDAgQDBQUEBAAAAX0B +AgMABBEFEiExQQYTUWEHInEUMoGRoQgjQrHBFVLR8CQzYnKCCQoWFxgZGiUmJygp +KjQ1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoOEhYaHiImK +kpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4eLj +5OXm5+jp6vHy8/T19vf4+fr/xAAfAQADAQEBAQEBAQEBAAAAAAAAAQIDBAUGBwgJ +Cgv/xAC1EQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGh +scEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZ +WmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1 +tre4ubrCw8TFxsfIycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/2gAMAwEA +AhEDEQA/APcBI/8Afb86XzH/AL7fnUYpwqRknmN/fP50u9v7x/OmCgUASb2/vH86 +Xe394/nTBS0AP3t/eP50u4+p/OmUopgO3H1NO3H1NR5xThQA7cfWlyfU0ylFMQ/J +9aXPvTKdQAuaM0lLQAtJmiigAzRSdqKAKApwpopc1mUOpRSUopgKKWkFLQAueKzr +zXbCwk2Tzxq3cFwK8v8Aih8V30aaTQ9DKtegYnuTyIvZR3b+VfP1/q17fzvLc3Ms +sjHJZ2JJNGr2HZdT6j8U/FbR/DcKsM3VxLkpGh6AetcI37Ql4Zcx6LAYx2aUgmvD +1ju7obgJHA7nmmmG4TqjDHtS+ZXL1sfVPhT4yeH/ABFNHaXYbS71zhVnYGNz6B+n +4HFejK2RmvhJJSDiTj6ivYvht8XptE8rSPEEklxpxwkFyTue39j6p+op3a3Javsf +RuacDVaC4juIUmhkWSKRQyspyGB7ipgasgfmlpoNLmgBaKSigBaKM0UAUBS0lKKz +KFFLSUooAdWR4o1qLw/4bvtSmZVEMRK57t2H51rCvJPj7etD4WsbQMQJ7jkDuFBN +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 +=fBn8 +-----END PGP PUBLIC KEY BLOCK----- diff --git a/jenkins/handlers/main.yml b/jenkins/handlers/main.yml index 58b03f3f..b7d269cf 100644 --- a/jenkins/handlers/main.yml +++ b/jenkins/handlers/main.yml @@ -1,5 +1,10 @@ --- -- name: Reload Squid +- name: reload squid + service: + name: squid + state: reloaded + +- name: reload squid3 service: name: squid3 state: reloaded @@ -8,4 +13,3 @@ service: name: jenkins state: restarted - diff --git a/jenkins/tasks/main.yml b/jenkins/tasks/main.yml index 03daa2ed..88db3b90 100644 --- a/jenkins/tasks/main.yml +++ b/jenkins/tasks/main.yml @@ -1,32 +1,18 @@ --- + +- name: Include java8 role + include_role: + name: java8 + - name: Add jenkins GPG key apt_key: - url: https://jenkins-ci.org/debian/jenkins-ci.org.key - -- name: Check if Squid is present - stat: - path: /etc/squid3/whitelist-custom.conf - register: _squid3_whitelist - check_mode: no - -- name: Append jenkins repositories to Squid whitelist - lineinfile: - name: /etc/squid3/whitelist-custom.conf - line: "{{ item }}" - with_items: - - "http://pkg.jenkins-ci.org/.*" - - "http://mirrors.jenkins.io/.*" - - "http://jenkins.mirror.isppower.de/.*" - - "http://ftp.icm.edu.pl/.*" - notify: Reload Squid - when: _squid3_whitelist.stat.exists - -- meta: flush_handlers + # url: https://jenkins-ci.org/debian/jenkins-ci.org.key + data: "{{ lookup('file', 'jenkins.key') }}" - name: Add jenkins APT repository apt_repository: repo: deb http://pkg.jenkins-ci.org/debian-stable binary/ - filename: jenkins.list + filename: jenkins update_cache: yes - name: Install Jenkins diff --git a/kibana-proxy-nginx/README.md b/kibana-proxy-nginx/README.md deleted file mode 100644 index 637497f0..00000000 --- a/kibana-proxy-nginx/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# kibana - -Install kibana proxy configurations (with or without SSL) for Nginx. - -## Tasks - -Everything is in the `tasks/main.yml` file. - -## Available variables - -The only variables are derived from gathered facts. - -By default, Kibana will bind to localhost:5601. - -The configurations are installed but not enabled. diff --git a/kibana-proxy-nginx/meta/main.yml b/kibana-proxy-nginx/meta/main.yml deleted file mode 100644 index ffa851f0..00000000 --- a/kibana-proxy-nginx/meta/main.yml +++ /dev/null @@ -1,19 +0,0 @@ -galaxy_info: - author: Evolix - description: Install kibana proxy configurations (with or without SSL) for Nginx. - - issue_tracker_url: https://forge.evolix.org/projects/ansible-roles/issues - - license: GPLv2 - - min_ansible_version: 2.2 - - platforms: - - name: Debian - versions: - - jessie - -dependencies: [] - # List your role dependencies here, one per line. - # Be sure to remove the '[]' above if you add dependencies - # to this list. diff --git a/kibana/README.md b/kibana/README.md index feda6871..5d95b5a7 100644 --- a/kibana/README.md +++ b/kibana/README.md @@ -8,7 +8,9 @@ Everything is in the `tasks/main.yml` file. ## Available variables -The only variables are derived from gathered facts. +* `kibana_proxy_nginx` : configure an Nginx proxy (not enabled) for Kibana (default: `False`) ; +* `kibana_proxy_domain` : domain to use for the proxy ; +* `kibana_proxy_ssl_cert` : certificate to use for the proxy ; +* `kibana_proxy_ssl_key` : private key to use for the proxy ; By default, Kibana will bind to localhost:5601. -If Nginx is installed, a typical proxy configuration is copied into `/etc/nginx/sites-available`. It can be tweeked and enabled by hand. diff --git a/kibana-proxy-nginx/defaults/main.yml b/kibana/defaults/main.yml similarity index 86% rename from kibana-proxy-nginx/defaults/main.yml rename to kibana/defaults/main.yml index 28477d87..7e7555f1 100644 --- a/kibana-proxy-nginx/defaults/main.yml +++ b/kibana/defaults/main.yml @@ -1,4 +1,6 @@ --- +kibana_proxy_nginx: False + kibana_proxy_domain: "kibana.{{ ansible_fqdn }}" kibana_proxy_ssl_cert: "/etc/ssl/certs/{{ ansible_fqdn }}.crt" kibana_proxy_ssl_key: "/etc/ssl/private/{{ ansible_fqdn }}.key" diff --git a/kibana/files/elasticsearch.key b/kibana/files/elasticsearch.key new file mode 100644 index 00000000..1b50dcca --- /dev/null +++ b/kibana/files/elasticsearch.key @@ -0,0 +1,31 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v2.0.14 (GNU/Linux) + +mQENBFI3HsoBCADXDtbNJnxbPqB1vDNtCsqhe49vFYsZN9IOZsZXgp7aHjh6CJBD +A+bGFOwyhbd7at35jQjWAw1O3cfYsKAmFy+Ar3LHCMkV3oZspJACTIgCrwnkic/9 +CUliQe324qvObU2QRtP4Fl0zWcfb/S8UYzWXWIFuJqMvE9MaRY1bwUBvzoqavLGZ +j3SF1SPO+TB5QrHkrQHBsmX+Jda6d4Ylt8/t6CvMwgQNlrlzIO9WT+YN6zS+sqHd +1YK/aY5qhoLNhp9G/HxhcSVCkLq8SStj1ZZ1S9juBPoXV1ZWNbxFNGwOh/NYGldD +2kmBf3YgCqeLzHahsAEpvAm8TBa7Q9W21C8vABEBAAG0RUVsYXN0aWNzZWFyY2gg +KEVsYXN0aWNzZWFyY2ggU2lnbmluZyBLZXkpIDxkZXZfb3BzQGVsYXN0aWNzZWFy +Y2gub3JnPokBOAQTAQIAIgUCUjceygIbAwYLCQgHAwIGFQgCCQoLBBYCAwECHgEC +F4AACgkQ0n1mbNiOQrRzjAgAlTUQ1mgo3nK6BGXbj4XAJvuZDG0HILiUt+pPnz75 +nsf0NWhqR4yGFlmpuctgCmTD+HzYtV9fp9qW/bwVuJCNtKXk3sdzYABY+Yl0Cez/ +7C2GuGCOlbn0luCNT9BxJnh4mC9h/cKI3y5jvZ7wavwe41teqG14V+EoFSn3NPKm +TxcDTFrV7SmVPxCBcQze00cJhprKxkuZMPPVqpBS+JfDQtzUQD/LSFfhHj9eD+Xe +8d7sw+XvxB2aN4gnTlRzjL1nTRp0h2/IOGkqYfIG9rWmSLNlxhB2t+c0RsjdGM4/ +eRlPWylFbVMc5pmDpItrkWSnzBfkmXL3vO2X3WvwmSFiQbkBDQRSNx7KAQgA5JUl +zcMW5/cuyZR8alSacKqhSbvoSqqbzHKcUQZmlzNMKGTABFG1yRx9r+wa/fvqP6OT +RzRDvVS/cycws8YX7Ddum7x8uI95b9ye1/Xy5noPEm8cD+hplnpU+PBQZJ5XJ2I+ +1l9Nixx47wPGXeClLqcdn0ayd+v+Rwf3/XUJrvccG2YZUiQ4jWZkoxsA07xx7Bj+ +Lt8/FKG7sHRFvePFU0ZS6JFx9GJqjSBbHRRkam+4emW3uWgVfZxuwcUCn1ayNgRt +KiFv9jQrg2TIWEvzYx9tywTCxc+FFMWAlbCzi+m4WD+QUWWfDQ009U/WM0ks0Kww +EwSk/UDuToxGnKU2dQARAQABiQEfBBgBAgAJBQJSNx7KAhsMAAoJENJ9ZmzYjkK0 +c3MIAIE9hAR20mqJWLcsxLtrRs6uNF1VrpB+4n/55QU7oxA1iVBO6IFu4qgsF12J +TavnJ5MLaETlggXY+zDef9syTPXoQctpzcaNVDmedwo1SiL03uMoblOvWpMR/Y0j +6rm7IgrMWUDXDPvoPGjMl2q1iTeyHkMZEyUJ8SKsaHh4jV9wp9KmC8C+9CwMukL7 +vM5w8cgvJoAwsp3Fn59AxWthN3XJYcnMfStkIuWgR7U2r+a210W6vnUxU4oN0PmM +cursYPyeV0NX/KQeUeNMwGTFB6QHS/anRaGQewijkrYYoTNtfllxIu9XYmiBERQ/ +qPDlGRlOgVTd9xUfHFkzB52c70E= +=92oX +-----END PGP PUBLIC KEY BLOCK----- diff --git a/kibana/tasks/main.yml b/kibana/tasks/main.yml index 50b1285b..9cf74638 100644 --- a/kibana/tasks/main.yml +++ b/kibana/tasks/main.yml @@ -4,9 +4,32 @@ include_role: name: java8 -- name: Install Elastic sources list - include_role: - name: elastic-sources-list +- name: APT https transport is enabled + apt: + name: apt-transport-https + state: present + tags: + - kibana + - packages + +- name: Elastic GPG key is installed + apt_key: + # url: https://artifacts.elastic.co/GPG-KEY-elasticsearch + data: "{{ lookup('file', 'elasticsearch.key') }}" + state: present + tags: + - kibana + - packages + +- name: Elastic sources list is available + apt_repository: + repo: "deb https://artifacts.elastic.co/packages/5.x/apt stable main" + filename: elastic.list + state: present + update_cache: yes + tags: + - kibana + - packages - name: Kibana is installed apt: @@ -55,3 +78,6 @@ args: warn: no when: mount.rc == 0 and not mount.stdout_lines.0 | search("rw") + +- include: proxy_nginx.yml + when: kibana_proxy_nginx diff --git a/kibana-proxy-nginx/tasks/main.yml b/kibana/tasks/proxy_nginx.yml similarity index 100% rename from kibana-proxy-nginx/tasks/main.yml rename to kibana/tasks/proxy_nginx.yml diff --git a/kibana-proxy-nginx/templates/nginx_proxy_kibana_nossl.j2 b/kibana/templates/nginx_proxy_kibana_nossl.j2 similarity index 100% rename from kibana-proxy-nginx/templates/nginx_proxy_kibana_nossl.j2 rename to kibana/templates/nginx_proxy_kibana_nossl.j2 diff --git a/kibana-proxy-nginx/templates/nginx_proxy_kibana_ssl.j2 b/kibana/templates/nginx_proxy_kibana_ssl.j2 similarity index 97% rename from kibana-proxy-nginx/templates/nginx_proxy_kibana_ssl.j2 rename to kibana/templates/nginx_proxy_kibana_ssl.j2 index 8903ca76..ea2e06c9 100644 --- a/kibana-proxy-nginx/templates/nginx_proxy_kibana_ssl.j2 +++ b/kibana/templates/nginx_proxy_kibana_ssl.j2 @@ -11,7 +11,7 @@ server { server { charset utf-8; - listen 443 ssl spdy; + listen 443 ssl; server_name {{ kibana_proxy_domain }}; diff --git a/kvm-host/README.md b/kvm-host/README.md index ae6f24ef..15ed4e13 100644 --- a/kvm-host/README.md +++ b/kvm-host/README.md @@ -8,4 +8,4 @@ Everything is in the `tasks/main.yml` file. ## Available variables -There is no variable. +* `kvm_custom_libvirt_images_path`: a custom directory for libvirt images (default: empty) ; diff --git a/kvm-host/defaults/main.yml b/kvm-host/defaults/main.yml new file mode 100644 index 00000000..4c77a2ff --- /dev/null +++ b/kvm-host/defaults/main.yml @@ -0,0 +1,2 @@ +--- +kvm_custom_libvirt_images_path: '' diff --git a/kvm-host/tasks/images.yml b/kvm-host/tasks/images.yml index 00f85759..527eb048 100644 --- a/kvm-host/tasks/images.yml +++ b/kvm-host/tasks/images.yml @@ -1,15 +1,38 @@ --- -- name: Create images directory - file: - path: '/home/images' - state: directory - owner: root - group: libvirt - mode: 02775 -- name: Symlink for libvirt images directory - file: - src: '/home/images' - dest: '/var/lib/libvirt/images' - state: link - force: yes +- block: + - name: "Is {{ kvm_custom_libvirt_images_path }} present ?" + stat: + path: "{{ kvm_custom_libvirt_images_path }}" + check_mode: no + register: kvm_custom_libvirt_images_path_test + + - name: "read the real datadir" + command: readlink -f /var/lib/libvirt/images + changed_when: False + check_mode: no + register: kvm_libvirt_images_current_real_path_test + when: kvm_custom_libvirt_images_path != '' + +- block: + - name: "Move libvirt images to {{ kvm_custom_libvirt_images_path }}" + command: mv /var/lib/libvirt/images {{ kvm_custom_libvirt_images_path }} + args: + creates: "{{ kvm_custom_libvirt_images_path }}" + + - name: Fix owner/group/permissions + file: + path: "{{ kvm_custom_libvirt_images_path }}" + owner: root + group: libvirt + mode: "02775" + + - name: "Symlink {{ kvm_custom_libvirt_images_path }} to /var/lib/libvirt/images" + file: + src: "{{ kvm_custom_libvirt_images_path }}" + dest: '/var/lib/libvirt/images' + state: link + when: + - kvm_custom_libvirt_images_path != '' + - kvm_custom_libvirt_images_path != kvm_libvirt_images_current_real_path_test.stdout + - not kvm_custom_libvirt_images_path_test.stat.exists diff --git a/kvm-host/tasks/main.yml b/kvm-host/tasks/main.yml index c4d6e622..a3ee3556 100644 --- a/kvm-host/tasks/main.yml +++ b/kvm-host/tasks/main.yml @@ -1,4 +1,6 @@ --- + +## TODO: check why it's disabled #- include: ssh.yml - include: packages.yml diff --git a/kvm-host/tasks/packages.yml b/kvm-host/tasks/packages.yml index b4ddd22f..7188239a 100644 --- a/kvm-host/tasks/packages.yml +++ b/kvm-host/tasks/packages.yml @@ -3,9 +3,10 @@ apt: name: "{{ item }}" with_items: - - libvirt-bin - qemu-kvm - netcat-openbsd - bridge-utils - qemu-utils - virtinst + - libvirt-daemon-system + - libvirt-clients diff --git a/listupgrade/tasks/main.yml b/listupgrade/tasks/main.yml index 962ccf9b..74944eca 100644 --- a/listupgrade/tasks/main.yml +++ b/listupgrade/tasks/main.yml @@ -15,7 +15,6 @@ owner: root group: root force: yes - backup: yes - name: Create /etc/evolinux file: diff --git a/logstash/files/elasticsearch.key b/logstash/files/elasticsearch.key new file mode 100644 index 00000000..1b50dcca --- /dev/null +++ b/logstash/files/elasticsearch.key @@ -0,0 +1,31 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v2.0.14 (GNU/Linux) + +mQENBFI3HsoBCADXDtbNJnxbPqB1vDNtCsqhe49vFYsZN9IOZsZXgp7aHjh6CJBD +A+bGFOwyhbd7at35jQjWAw1O3cfYsKAmFy+Ar3LHCMkV3oZspJACTIgCrwnkic/9 +CUliQe324qvObU2QRtP4Fl0zWcfb/S8UYzWXWIFuJqMvE9MaRY1bwUBvzoqavLGZ +j3SF1SPO+TB5QrHkrQHBsmX+Jda6d4Ylt8/t6CvMwgQNlrlzIO9WT+YN6zS+sqHd +1YK/aY5qhoLNhp9G/HxhcSVCkLq8SStj1ZZ1S9juBPoXV1ZWNbxFNGwOh/NYGldD +2kmBf3YgCqeLzHahsAEpvAm8TBa7Q9W21C8vABEBAAG0RUVsYXN0aWNzZWFyY2gg +KEVsYXN0aWNzZWFyY2ggU2lnbmluZyBLZXkpIDxkZXZfb3BzQGVsYXN0aWNzZWFy +Y2gub3JnPokBOAQTAQIAIgUCUjceygIbAwYLCQgHAwIGFQgCCQoLBBYCAwECHgEC +F4AACgkQ0n1mbNiOQrRzjAgAlTUQ1mgo3nK6BGXbj4XAJvuZDG0HILiUt+pPnz75 +nsf0NWhqR4yGFlmpuctgCmTD+HzYtV9fp9qW/bwVuJCNtKXk3sdzYABY+Yl0Cez/ +7C2GuGCOlbn0luCNT9BxJnh4mC9h/cKI3y5jvZ7wavwe41teqG14V+EoFSn3NPKm +TxcDTFrV7SmVPxCBcQze00cJhprKxkuZMPPVqpBS+JfDQtzUQD/LSFfhHj9eD+Xe +8d7sw+XvxB2aN4gnTlRzjL1nTRp0h2/IOGkqYfIG9rWmSLNlxhB2t+c0RsjdGM4/ +eRlPWylFbVMc5pmDpItrkWSnzBfkmXL3vO2X3WvwmSFiQbkBDQRSNx7KAQgA5JUl +zcMW5/cuyZR8alSacKqhSbvoSqqbzHKcUQZmlzNMKGTABFG1yRx9r+wa/fvqP6OT +RzRDvVS/cycws8YX7Ddum7x8uI95b9ye1/Xy5noPEm8cD+hplnpU+PBQZJ5XJ2I+ +1l9Nixx47wPGXeClLqcdn0ayd+v+Rwf3/XUJrvccG2YZUiQ4jWZkoxsA07xx7Bj+ +Lt8/FKG7sHRFvePFU0ZS6JFx9GJqjSBbHRRkam+4emW3uWgVfZxuwcUCn1ayNgRt +KiFv9jQrg2TIWEvzYx9tywTCxc+FFMWAlbCzi+m4WD+QUWWfDQ009U/WM0ks0Kww +EwSk/UDuToxGnKU2dQARAQABiQEfBBgBAgAJBQJSNx7KAhsMAAoJENJ9ZmzYjkK0 +c3MIAIE9hAR20mqJWLcsxLtrRs6uNF1VrpB+4n/55QU7oxA1iVBO6IFu4qgsF12J +TavnJ5MLaETlggXY+zDef9syTPXoQctpzcaNVDmedwo1SiL03uMoblOvWpMR/Y0j +6rm7IgrMWUDXDPvoPGjMl2q1iTeyHkMZEyUJ8SKsaHh4jV9wp9KmC8C+9CwMukL7 +vM5w8cgvJoAwsp3Fn59AxWthN3XJYcnMfStkIuWgR7U2r+a210W6vnUxU4oN0PmM +cursYPyeV0NX/KQeUeNMwGTFB6QHS/anRaGQewijkrYYoTNtfllxIu9XYmiBERQ/ +qPDlGRlOgVTd9xUfHFkzB52c70E= +=92oX +-----END PGP PUBLIC KEY BLOCK----- diff --git a/logstash/tasks/main.yml b/logstash/tasks/main.yml index fcaef9bb..16e9ae79 100644 --- a/logstash/tasks/main.yml +++ b/logstash/tasks/main.yml @@ -6,11 +6,32 @@ tags: - packages -- name: Install Elastic sources list - include_role: - name: elastic-sources-list +- name: APT https transport is enabled + apt: + name: apt-transport-https + state: present tags: - - packages + - logstash + - packages + +- name: Elastic GPG key is installed + apt_key: + # url: https://artifacts.elastic.co/GPG-KEY-elasticsearch + data: "{{ lookup('file', 'elasticsearch.key') }}" + state: present + tags: + - logstash + - packages + +- name: Elastic sources list is available + apt_repository: + repo: "deb https://artifacts.elastic.co/packages/5.x/apt stable main" + filename: elastic.list + state: present + update_cache: yes + tags: + - logstash + - packages - name: Logstash is installed apt: diff --git a/lxc/README.md b/lxc/README.md new file mode 100644 index 00000000..c267d6b9 --- /dev/null +++ b/lxc/README.md @@ -0,0 +1,24 @@ +# lxc + +Install and configure lxc and create containers. + +## Tasks + +Everything is in the `tasks/main.yml` file. + +## Available variables + +Here is the list of available variables: + +* `lxc_unprivilegied_containers`: should LXC containers run in unprivilegied (non root) mode? Currently `lxc_unprivilegied_containers: true` does not work. Default: `false` +* `lxc_network_type`: network type to use. See lxc.container.conf(5). Default: `"none"` +* `lxc_mount_part`: partition to bind mount into containers. Default: `"/home"` +* `lxc_containers`: list of LXC containers to create. Default: `[]` (empty). + Eg.: + ``` + lxc_containers: + - name: php56 + release: jessie + - name: php70 + release: stretch + ``` diff --git a/lxc/defaults/main.yml b/lxc/defaults/main.yml new file mode 100644 index 00000000..e7e1c1ff --- /dev/null +++ b/lxc/defaults/main.yml @@ -0,0 +1,18 @@ +--- +# Should LXC containers run in unprivilegied (non root) mode? +lxc_unprivilegied_containers: false + +# Network type to use. See lxc.container.conf(5). +lxc_network_type: "none" + +# Partition to bind mount into containers. +lxc_mount_part: "/home" + +# List of LXC containers to create. +# Eg.: +# lxc_containers: +# - name: php56 +# release: jessie +# - name: php70 +# release: stretch +lxc_containers: [] diff --git a/lxc/tasks/create-container.yml b/lxc/tasks/create-container.yml new file mode 100644 index 00000000..8b35d66b --- /dev/null +++ b/lxc/tasks/create-container.yml @@ -0,0 +1,53 @@ +--- +- name: Check if container exists + command: "lxc-ls {{name}}" + changed_when: false + register: container_exists + +- name: Create container + command: "lxc-create -n {{name}} -t download -- --dist debian --release {{release}} --arch amd64" + when: container_exists.stdout_lines == [] + +- name: Disable network configuration inside container + replace: + name: "/var/lib/lxc/{{name}}/rootfs/etc/default/networking" + regexp: "^#CONFIGURE_INTERFACES=yes" + replace: CONFIGURE_INTERFACES=no + when: lxc_network_type == "none" + +- name: Disable interface shut down on halt inside container + lineinfile: + name: "/var/lib/lxc/{{name}}/rootfs/etc/default/halt" + line: "NETDOWN=no" + when: lxc_network_type == "none" and release != "stretch" + +- name: Make the container poweroff on SIGPWR (sent by lxc-stop) on jessie + file: + src: /lib/systemd/system/poweroff.target + dest: "/var/lib/lxc/{{name}}/rootfs/etc/systemd/system/sigpwr.target" + state: link + when: release == 'jessie' + +- name: Set the DNS resolvers + command: "cp /etc/resolv.conf /var/lib/lxc/{{name}}/rootfs/etc/" + +- name: Add hostname in /etc/hosts + lineinfile: + name: "/var/lib/lxc/{{name}}/rootfs/etc/hosts" + line: "127.0.0.1 {{name}}" + +- name: Fix permission on /dev + lineinfile: + name: "/var/lib/lxc/{{name}}/rootfs/etc/rc.local" + line: "chmod 755 /dev" + insertbefore: "^exit 0$" + when: release != 'stretch' + +- name: Check if container is running + command: "lxc-ls --running {{name}}" + changed_when: false + register: container_running + +- name: "Start {{name}} container" + command: "lxc-start -dn {{name}}" + when: container_running.stdout_lines == [] diff --git a/lxc/tasks/main.yml b/lxc/tasks/main.yml new file mode 100644 index 00000000..48ecf51b --- /dev/null +++ b/lxc/tasks/main.yml @@ -0,0 +1,24 @@ +--- +- name: Install lxc tools + apt: + name: lxc + +- name: Copy LXC default containers configuration + template: + src: default.conf + dest: /etc/lxc/ + +- name: Check if root has subuids + command: grep '^root:100000:10000$' /etc/subuid + failed_when: false + changed_when: false + register: root_subuids + when: lxc_unprivilegied_containers + +- name: Add subuid and subgid ranges to root + command: usermod -v 100000-199999 -w 100000-109999 root + when: lxc_unprivilegied_containers and root_subuids.rc + +- name: Create containers + include: "create-container.yml name={{item.name}} release={{item.release}}" + with_items: "{{lxc_containers}}" diff --git a/lxc/templates/default.conf b/lxc/templates/default.conf new file mode 100644 index 00000000..bf3501d3 --- /dev/null +++ b/lxc/templates/default.conf @@ -0,0 +1,25 @@ +{% if lxc_unprivilegied_containers %} +# Run containers in unprivilegied mode. +# Map both user and group IDs in range 0-9999 in the container to the IDs +# 100000-109999 on the host. +lxc.id_map = u 0 100000 10000 +lxc.id_map = g 0 100000 10000 + +{% endif %} +# Set the default network virtualization method. +lxc.network.type = {{lxc_network_type}} + +{% if lxc_mount_part %} +# Mount {{lxc_mount_part}} into containers. +# lxc.mount.entry = {{lxc_mount_part}} {{lxc_mount_part |replace('/', '')}} none bind 0 0 + +{% endif %} +# Only one tty is enough. +# This require that you disabled others tty ([2-6]) in systemd. +lxc.tty = 1 + +# Run 64bits containers +lxc.arch = x86_64 + +# Start containers on boot by default +lxc.start.auto = 1 diff --git a/minifirewall-tail/README.md b/minifirewall-tail/README.md deleted file mode 100644 index 6be689dd..00000000 --- a/minifirewall-tail/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# minifirewall-tail - -Compiles a `minifirewall.tail` file based on templates and source it at the end of minifirewall configuration. - -Templates are looked up in that order : -1. `{{ playbook_dir}}/templates/minifirewall-tail/minifirewall.{{ inventory_hostname}}.tail.j2` -2. `{{ playbook_dir}}/templates/minifirewall-tail/minifirewall.{{ host_group}}.tail.j2` (NB : `host_group` is not a core variable, it must be defined in `group_vars` files.) -3. `{{ playbook_dir}}/templates/minifirewall-tail/minifirewall.default.tail.j2` - -If nothing is found, the role falls back to the template embedded in the role : `templates/minifirewall.default.tail.j2` diff --git a/minifirewall-tail/meta/main.yml b/minifirewall-tail/meta/main.yml deleted file mode 100644 index 5cbe5e02..00000000 --- a/minifirewall-tail/meta/main.yml +++ /dev/null @@ -1,19 +0,0 @@ -galaxy_info: - author: Evolix - description: Additionla configuration for Minifirewall - - issue_tracker_url: https://forge.evolix.org/projects/ansible-roles/issues - - license: GPLv2 - - min_ansible_version: 2.2 - - platforms: - - name: Debian - versions: - - jessie - -dependencies: [] - # List your role dependencies here, one per line. - # Be sure to remove the '[]' above if you add dependencies - # to this list. diff --git a/minifirewall/README.md b/minifirewall/README.md index ab0e6abf..67b389f1 100644 --- a/minifirewall/README.md +++ b/minifirewall/README.md @@ -15,7 +15,18 @@ Everything is in the `tasks/main.yml` file. * `minifirewall_int_lan`: (default: IP/32) * `minifirewall_trusted_ips`: with IP/hosts should be trusted for full access (default: none) * `minifirewall_privilegied_ips`: with IP/hosts should be trusted for restricted access (default: none) - +* `minifirewall_tail_included` : source a "tail" file at the end of the main config file. (default: `False`) The full list of variables (with default values) can be found in `defaults/main.yml`. **Some IP/hosts must be configured or the server will be inaccessible via network.** + +## minifirewall-tail + +Compiles a `minifirewall.tail` file based on templates and source it at the end of minifirewall configuration. + +Templates are looked up in that order : +1. `{{ playbook_dir}}/templates/minifirewall-tail/minifirewall.{{ inventory_hostname}}.tail.j2` +2. `{{ playbook_dir}}/templates/minifirewall-tail/minifirewall.{{ host_group}}.tail.j2` (NB : `host_group` is not a core variable, it must be defined in `group_vars` files.) +3. `{{ playbook_dir}}/templates/minifirewall-tail/minifirewall.default.tail.j2` + +If nothing is found, the role falls back to the template embedded in the role : `templates/minifirewall.default.tail.j2` diff --git a/minifirewall/defaults/main.yml b/minifirewall/defaults/main.yml index 760b35cc..69e1e8fe 100644 --- a/minifirewall/defaults/main.yml +++ b/minifirewall/defaults/main.yml @@ -1,17 +1,19 @@ --- +minifirewall_tail_included: False + minifirewall_git_url: "https://forge.evolix.org/minifirewall.git" minifirewall_checkout_path: "/tmp/minifirewall" minifirewall_int: "{{ ansible_default_ipv4.interface }}" minifirewall_ipv6: "on" minifirewall_intlan: "{{ ansible_default_ipv4.address }}/32" -minifirewall_trusted_ips: [] +minifirewall_trusted_ips: ["0.0.0.0/0"] minifirewall_privilegied_ips: [] minifirewall_protected_ports_tcp: [22] minifirewall_protected_ports_udp: [] -minifirewall_public_ports_tcp: [25, 53, 443, 993, 995, 2222] -minifirewall_public_ports_udp: [53] -minifirewall_semipublic_ports_tcp: [20, 21, 22, 80, 110, 143] +minifirewall_public_ports_tcp: [22, 80, 443] +minifirewall_public_ports_udp: [] +minifirewall_semipublic_ports_tcp: [20, 21, 25] minifirewall_semipublic_ports_udp: [] minifirewall_private_ports_tcp: [5666] minifirewall_private_ports_udp: [] diff --git a/minifirewall/files/minifirewall b/minifirewall/files/minifirewall new file mode 100755 index 00000000..94260a96 --- /dev/null +++ b/minifirewall/files/minifirewall @@ -0,0 +1,385 @@ +#!/bin/sh + +# minifirewall is shellscripts for easy firewalling on a standalone server +# we used netfilter/iptables http://netfilter.org/ designed for recent Linux kernel +# See https://forge.evolix.org/projects/minifirewall + +# Copyright (c) 2007-2015 Evolix +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License. + +# Description +# script for standalone server + +# Start or stop minifirewall +# + +### BEGIN INIT INFO +# Provides: minfirewall +# Required-Start: +# Required-Stop: +# Should-Start: $network $syslog $named +# Should-Stop: $syslog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: start and stop the firewall +# Description: Firewall designed for standalone server +### END INIT INFO + +DESC="minifirewall" +NAME="minifirewall" + + +# Variables configuration +######################### + +# iptables paths +IPT=/sbin/iptables +IPT6=/sbin/ip6tables + +# TCP/IP variables +LOOPBACK='127.0.0.0/8' +CLASSA='10.0.0.0/8' +CLASSB='172.16.0.0/12' +CLASSC='192.168.0.0/16' +CLASSD='224.0.0.0/4' +CLASSE='240.0.0.0/5' +ALL='0.0.0.0' +BROAD='255.255.255.255' +PORTSROOT='0:1023' +PORTSUSER='1024:65535' + + +case "$1" in + start) + + echo "Start IPTables rules..." + +# Stop and warn if error! +set -e +trap 'echo "ERROR in minifirewall configuration (fix it now!) or script manipulation (fix yourself)." ' INT TERM EXIT + + +# sysctl network security settings +################################## + +# Don't answer to broadcast pings +echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts + +# Ignore bogus ICMP responses +echo 1 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses + +# Disable Source Routing +for i in /proc/sys/net/ipv4/conf/*/accept_source_route; do +echo 0 > $i +done + +# Enable TCP SYN cookies to avoid TCP-SYN-FLOOD attacks +# cf http://cr.yp.to/syncookies.html +echo 1 > /proc/sys/net/ipv4/tcp_syncookies + +# Disable ICMP redirects +for i in /proc/sys/net/ipv4/conf/*/accept_redirects; do +echo 0 > $i +done + +for i in /proc/sys/net/ipv4/conf/*/send_redirects; do +echo 0 > $i +done + +# Enable Reverse Path filtering : verify if responses use same network interface +for i in /proc/sys/net/ipv4/conf/*/rp_filter; do +echo 1 > $i +done + +# log des paquets avec adresse incoherente +for i in /proc/sys/net/ipv4/conf/*/log_martians; do +echo 1 > $i +done + +# IPTables configuration +######################## + +$IPT -N LOG_DROP +$IPT -A LOG_DROP -j LOG --log-prefix '[IPTABLES DROP] : ' +$IPT -A LOG_DROP -j DROP +$IPT -N LOG_ACCEPT +$IPT -A LOG_ACCEPT -j LOG --log-prefix '[IPTABLES ACCEPT] : ' +$IPT -A LOG_ACCEPT -j ACCEPT + +# Configuration +oldconfigfile="/etc/firewall.rc" +configfile="/etc/default/minifirewall" + +if test -f $oldconfigfile; then + echo "$oldconfigfile is deprecated, rename to $configfile" >&2 + exit 1 +fi + +if ! test -f $configfile; then + echo "$configfile does not exist" >&2 + exit 1 +fi + +tmpfile=`mktemp` +. $configfile 2>$tmpfile >&2 +if [ -s $tmpfile ]; then + echo "$configfile returns standard or error output (see below). Stopping." >&2 + cat $tmpfile + exit 1 +fi +rm $tmpfile + +# Trusted ip addresses +$IPT -N ONLYTRUSTED +$IPT -A ONLYTRUSTED -j LOG_DROP +for x in $TRUSTEDIPS + do + $IPT -I ONLYTRUSTED -s $x -j ACCEPT + done + +# Privilegied ip addresses +# (trusted ip addresses *are* privilegied) +$IPT -N ONLYPRIVILEGIED +$IPT -A ONLYPRIVILEGIED -j ONLYTRUSTED +for x in $PRIVILEGIEDIPS + do + $IPT -I ONLYPRIVILEGIED -s $x -j ACCEPT + done + +# Chain for restrictions (blacklist IPs/ranges) +$IPT -N NEEDRESTRICT + +# We allow all on loopback interface +$IPT -A INPUT -i lo -j ACCEPT +[ "$IPV6" != "off" ] && $IPT6 -A INPUT -i lo -j ACCEPT +# if OUTPUTDROP +$IPT -A OUTPUT -o lo -j ACCEPT +[ "$IPV6" != "off" ] && $IPT6 -A OUTPUT -o lo -j ACCEPT + +# We avoid "martians" packets, typical when W32/Blaster virus +# attacked windowsupdate.com and DNS was changed to 127.0.0.1 +# $IPT -t NAT -I PREROUTING -s $LOOPBACK -i ! lo -j DROP +$IPT -A INPUT -s $LOOPBACK ! -i lo -j DROP + + +# Local services restrictions +############################# + +# Allow services for $INTLAN (local server or local network) +$IPT -A INPUT -s $INTLAN -j ACCEPT + +# Enable protection chain for sensible services +for x in $SERVICESTCP1p + do + $IPT -A INPUT -p tcp --dport $x -j NEEDRESTRICT + done + +for x in $SERVICESUDP1p + do + $IPT -A INPUT -p udp --dport $x -j NEEDRESTRICT + done + +# Public service +for x in $SERVICESTCP1 + do + $IPT -A INPUT -p tcp --dport $x -j ACCEPT + [ "$IPV6" != "off" ] && $IPT6 -A INPUT -p tcp --dport $x -j ACCEPT + done + +for x in $SERVICESUDP1 + do + $IPT -A INPUT -p udp --dport $x -j ACCEPT + [ "$IPV6" != "off" ] && $IPT6 -A INPUT -p udp --dport $x -j ACCEPT + done + +# Privilegied services +for x in $SERVICESTCP2 + do + $IPT -A INPUT -p tcp --dport $x -j ONLYPRIVILEGIED + done + +for x in $SERVICESUDP2 + do + $IPT -A INPUT -p udp --dport $x -j ONLYPRIVILEGIED + done + +# Private services +for x in $SERVICESTCP3 + do + $IPT -A INPUT -p tcp --dport $x -j ONLYTRUSTED + done + +for x in $SERVICESUDP3 + do + $IPT -A INPUT -p udp --dport $x -j ONLYTRUSTED + done + + +# External services +################### + +# DNS authorizations +for x in $DNSSERVEURS + do + $IPT -A INPUT -p tcp ! --syn --sport 53 --dport $PORTSUSER -s $x -j ACCEPT + $IPT -A INPUT -p udp --sport 53 --dport $PORTSUSER -s $x -m state --state ESTABLISHED,RELATED -j ACCEPT + $IPT -A OUTPUT -o $INT -p udp -d $x --dport 53 --match state --state NEW -j ACCEPT + done + +# HTTP (TCP/80) authorizations +for x in $HTTPSITES + do + $IPT -A INPUT -p tcp ! --syn --sport 80 --dport $PORTSUSER -s $x -j ACCEPT + done + +# HTTPS (TCP/443) authorizations +for x in $HTTPSSITES + do + $IPT -A INPUT -p tcp ! --syn --sport 443 --dport $PORTSUSER -s $x -j ACCEPT + done + +# FTP (so complex protocol...) authorizations +for x in $FTPSITES + do + # requests on Control connection + $IPT -A INPUT -p tcp ! --syn --sport 21 --dport $PORTSUSER -s $x -j ACCEPT + # FTP port-mode on Data Connection + $IPT -A INPUT -p tcp --sport 20 --dport $PORTSUSER -s $x -j ACCEPT + # FTP passive-mode on Data Connection + # WARNING, this allow all connections on TCP ports > 1024 + $IPT -A INPUT -p tcp ! --syn --sport $PORTSUSER --dport $PORTSUSER -s $x -j ACCEPT + done + +# SSH authorizations +for x in $SSHOK + do + $IPT -A INPUT -p tcp ! --syn --sport 22 -s $x -j ACCEPT + done + +# SMTP authorizations +for x in $SMTPOK + do + $IPT -A INPUT -p tcp ! --syn --sport 25 --dport $PORTSUSER -j ACCEPT + done + +# secure SMTP (TCP/465 et TCP/587) authorizations +for x in $SMTPSECUREOK + do + $IPT -A INPUT -p tcp ! --syn --sport 465 --dport $PORTSUSER -j ACCEPT + $IPT -A INPUT -p tcp ! --syn --sport 587 --dport $PORTSUSER -j ACCEPT + done + +# NTP authorizations +for x in $NTPOK + do + $IPT -A INPUT -p udp --sport 123 -s $x -j ACCEPT + $IPT -A OUTPUT -o $INT -p udp -d $x --dport 123 --match state --state NEW -j ACCEPT + done + +# Always allow ICMP +$IPT -A INPUT -p icmp -j ACCEPT +[ "$IPV6" != "off" ] && $IPT6 -A INPUT -p icmpv6 -j ACCEPT + + +# IPTables policy +################# + +# by default DROP INPUT packets +$IPT -P INPUT DROP +[ "$IPV6" != "off" ] && $IPT6 -P INPUT DROP + +# by default, no FORWARING (deprecated for Virtual Machines) +#echo 0 > /proc/sys/net/ipv4/ip_forward +#$IPT -P FORWARD DROP +#$IPT6 -P FORWARD DROP + +# by default allow OUTPUT packets... but drop UDP packets (see OUTPUTDROP to drop OUTPUT packets) +$IPT -P OUTPUT ACCEPT +[ "$IPV6" != "off" ] && $IPT6 -P OUTPUT ACCEPT +$IPT -A OUTPUT -o $INT -p udp --dport 33434:33523 --match state --state NEW -j ACCEPT +$IPT -A OUTPUT -p udp --match state --state ESTABLISHED,RELATED -j ACCEPT +$IPT -A OUTPUT -p udp -j DROP +[ "$IPV6" != "off" ] && $IPT6 -A OUTPUT -o $INT -p udp --dport 33434:33523 --match state --state NEW -j ACCEPT +[ "$IPV6" != "off" ] && $IPT6 -A OUTPUT -p udp --match state --state ESTABLISHED,RELATED -j ACCEPT +[ "$IPV6" != "off" ] && $IPT6 -A OUTPUT -p udp -j DROP + +trap - INT TERM EXIT + + echo "...starting IPTables rules is now finish : OK" + ;; + + stop) + + echo "Flush all rules and accept everything..." + + # Delete all rules + $IPT -F INPUT + $IPT -F OUTPUT + $IPT -F LOG_DROP + $IPT -F LOG_ACCEPT + $IPT -F ONLYTRUSTED + $IPT -F ONLYPRIVILEGIED + $IPT -F NEEDRESTRICT + $IPT -t nat -F + $IPT -t mangle -F + [ "$IPV6" != "off" ] && $IPT6 -F INPUT + [ "$IPV6" != "off" ] && $IPT6 -F OUTPUT + + # Accept all + $IPT -P INPUT ACCEPT + $IPT -P OUTPUT ACCEPT + [ "$IPV6" != "off" ] && $IPT6 -P INPUT ACCEPT + [ "$IPV6" != "off" ] && $IPT6 -P OUTPUT ACCEPT + #$IPT -P FORWARD ACCEPT + #$IPT -t nat -P PREROUTING ACCEPT + #$IPT -t nat -P POSTROUTING ACCEPT + + # Delete non-standard chains + $IPT -X LOG_DROP + $IPT -X LOG_ACCEPT + $IPT -X ONLYPRIVILEGIED + $IPT -X ONLYTRUSTED + $IPT -X NEEDRESTRICT + + echo "...flushing IPTables rules is now finish : OK" + ;; + + status) + + $IPT -L -n -v --line-numbers + $IPT -t nat -L -n -v --line-numbers + $IPT -t mangle -L -n -v --line-numbers + $IPT6 -L -n -v --line-numbers + $IPT6 -t mangle -L -n -v --line-numbers + ;; + + reset) + + echo "Reset all IPTables counters..." + + $IPT -Z + $IPT -t nat -Z + $IPT -t mangle -Z + [ "$IPV6" != "off" ] && $IPT6 -Z + [ "$IPV6" != "off" ] && $IPT6 -t mangle -Z + + echo "...reseting IPTables counters is now finish : OK" + ;; + + restart) + + $0 stop + $0 start + ;; + + *) + + echo "Usage: $0 {start|stop|restart|status|reset|squid}" + exit 1 +esac + +exit 0 + diff --git a/minifirewall/files/minifirewall.conf b/minifirewall/files/minifirewall.conf new file mode 100644 index 00000000..12ea853f --- /dev/null +++ b/minifirewall/files/minifirewall.conf @@ -0,0 +1,99 @@ +# Configuration for minifirewall : https://forge.evolix.org/projects/minifirewall +# For fun, we keep last change from first CVS repository: +# version 0.1 - 12 juillet 2007 $Id: firewall.rc,v 1.2 2007/07/12 19:08:59 reg Exp $ + +# Main interface +INT='eth0' + +# IPv6 +IPV6=on + +# Trusted IPv4 local network +# ...will be often IP/32 if you don't trust anything +INTLAN='192.168.0.2/32' + +# Trusted IPv4 addresses for private and semi-public services +TRUSTEDIPS='62.212.121.90 88.179.18.233 31.170.8.4 31.170.9.129' + +# Privilegied IPv4 addresses for semi-public services +# (no need to add again TRUSTEDIPS) +PRIVILEGIEDIPS='' + + +# Local services IPv4/IPv6 restrictions +####################################### + +# Protected services +# (add also in Public services if needed) +SERVICESTCP1p='22' +SERVICESUDP1p='' + +# Public services (IPv4/IPv6) +SERVICESTCP1='25 53 443 993 995 2222' +SERVICESUDP1='53' + +# Semi-public services (IPv4) +SERVICESTCP2='20 21 22 80 110 143' +SERVICESUDP2='' + +# Private services (IPv4) +SERVICESTCP3='5666' +SERVICESUDP3='' + +# Standard output IPv4 access restrictions +########################################## + +# DNS authorizations +# (if you have local DNS server, set 0.0.0.0/0) +DNSSERVEURS='0.0.0.0/0' + +# HTTP authorizations +# (you can use DNS names but set cron to reload minifirewall regularly) +# (if you have HTTP proxy, set 0.0.0.0/0) +HTTPSITES='security.debian.org pub.evolix.net volatile.debian.org mirror.evolix.org backports.debian.org hwraid.le-vert.net zidane.evolix.net antispam00.evolix.org spamassassin.apache.org sa-update.space-pro.be sa-update.secnap.net www.sa-update.pccc.com sa-update.dnswl.org' + +# HTTPS authorizations +HTTPSSITES='0.0.0.0/0' + +# FTP authorizations +FTPSITES='' + +# SSH authorizations +SSHOK='0.0.0.0/0' + +# SMTP authorizations +SMTPOK='0.0.0.0/0' + +# SMTP secure authorizations (ports TCP/465 and TCP/587) +SMTPSECUREOK='' + +# NTP authorizations +NTPOK='0.0.0.0/0' + + +# IPv6 Specific rules +##################### + +# Example: allow SSH from Trusted IPv6 addresses +/sbin/ip6tables -A INPUT -i $INT -p tcp --dport 22 -s 2a01:9500:37:129::/64 -j ACCEPT + +# Example: allow input HTTP/HTTPS/SMTP/DNS traffic +/sbin/ip6tables -A INPUT -i $INT -p tcp --sport 80 --match state --state ESTABLISHED,RELATED -j ACCEPT +/sbin/ip6tables -A INPUT -i $INT -p tcp --sport 443 --match state --state ESTABLISHED,RELATED -j ACCEPT +/sbin/ip6tables -A INPUT -i $INT -p tcp --sport 25 --match state --state ESTABLISHED,RELATED -j ACCEPT +/sbin/ip6tables -A INPUT -i $INT -p udp --sport 53 --match state --state ESTABLISHED,RELATED -j ACCEPT +/sbin/ip6tables -A INPUT -i $INT -p tcp --sport 53 --match state --state ESTABLISHED,RELATED -j ACCEPT + +# Example: allow output DNS, NTP and traceroute traffic +/sbin/ip6tables -A OUTPUT -o $INT -p udp --dport 53 --match state --state NEW -j ACCEPT +/sbin/ip6tables -A OUTPUT -o $INT -p udp --dport 123 --match state --state NEW -j ACCEPT +#/sbin/ip6tables -A OUTPUT -o $INT -p udp --dport 33434:33523 --match state --state NEW -j ACCEPT + +# Example: allow DHCPv6 +/sbin/ip6tables -A INPUT -i $INT -p udp --dport 546 -d fe80::/64 -j ACCEPT +/sbin/ip6tables -A OUTPUT -o $INT -p udp --dport 547 -j ACCEPT + +# IPv4 Specific rules +##################### + +# /sbin/iptables ... diff --git a/minifirewall/tasks/config.yml b/minifirewall/tasks/config.yml index 0d91945f..80acf5d0 100644 --- a/minifirewall/tasks/config.yml +++ b/minifirewall/tasks/config.yml @@ -28,6 +28,9 @@ - fail: msg: You must provide at least 1 trusted IP when: minifirewall_trusted_ips == [] +- debug: + msg: "Warning: minifirewall_trusted_ips='0.0.0.0/0', the firewall is useless!" + when: minifirewall_trusted_ips == ["0.0.0.0/0"] - name: Configure IP addresses blockinfile: diff --git a/minifirewall/tasks/install.yml b/minifirewall/tasks/install.yml index 8e211fb9..47d72b44 100644 --- a/minifirewall/tasks/install.yml +++ b/minifirewall/tasks/install.yml @@ -1,37 +1,19 @@ --- -- name: clone git repository - git: - repo: "{{ minifirewall_git_url}}" - dest: "{{ minifirewall_checkout_path }}" - clone: yes - -# WARN: these tasks copy the file if there are not already there -# They don't update files. - -- name: is init script present? - stat: - path: /etc/init.d/minifirewall - check_mode: no - register: init_minifirewall - - name: init script is copied - command: "cp {{ minifirewall_checkout_path }}/minifirewall /etc/init.d/minifirewall" - when: not init_minifirewall.stat.exists - - -- name: is configuration present? - stat: - path: /etc/default/minifirewall - check_mode: no - register: default_minifirewall + copy: + src: minifirewall + dest: /etc/init.d/minifirewall + force: no + mode: "0700" + owner: root + group: root - name: configuration is copied - command: "cp {{ minifirewall_checkout_path }}/minifirewall.conf /etc/default/minifirewall" - when: not default_minifirewall.stat.exists - -- name: fix configuration rights - file: - path: /etc/default/minifirewall + copy: + src: minifirewall.conf + dest: /etc/default/minifirewall + force: no mode: "0600" - state: file + owner: root + group: root diff --git a/minifirewall/tasks/main.yml b/minifirewall/tasks/main.yml index 7727308b..851d1917 100644 --- a/minifirewall/tasks/main.yml +++ b/minifirewall/tasks/main.yml @@ -5,3 +5,6 @@ - include: config.yml - include: activate.yml + +- include: tail.yml + when: minifirewall_tail_included diff --git a/minifirewall-tail/tasks/main.yml b/minifirewall/tasks/tail.yml similarity index 100% rename from minifirewall-tail/tasks/main.yml rename to minifirewall/tasks/tail.yml diff --git a/minifirewall-tail/templates/minifirewall.default.tail.j2 b/minifirewall/templates/minifirewall.default.tail.j2 similarity index 100% rename from minifirewall-tail/templates/minifirewall.default.tail.j2 rename to minifirewall/templates/minifirewall.default.tail.j2 diff --git a/minifirewall/tests/test.yml b/minifirewall/tests/test.yml index 427cd2f3..43dd567f 100644 --- a/minifirewall/tests/test.yml +++ b/minifirewall/tests/test.yml @@ -2,5 +2,8 @@ - hosts: test-kitchen vars: - minifirewall_trusted_ips: ["{{ ansible_default_ipv4.address }}/24"] + pre_tasks: + - apt: + name: git roles: - role: minifirewall diff --git a/mongodb/files/server-3.4.asc b/mongodb/files/server-3.4.asc new file mode 100644 index 00000000..1d681f82 --- /dev/null +++ b/mongodb/files/server-3.4.asc @@ -0,0 +1,30 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1.4.11 (GNU/Linux) + +mQINBFaUNhsBEACkTlpL9xCrlirl77tahFzzd9ccTc5wP+M3oob18GIaMYKicjbR +h6J6ytCiXCkl65zYKvQdLkt8qlkBVc5DxGeJvD41IY3NzGPz+BZ9pFFBndAE+JEP +ng0ULLxzUDmWXIoukdHqf92BSizTFd2A8v+YGuwOkNBdPi/BHkwiViAaAKDZm/4k +9LZeOF0v7gZF89QD75NrSCKo5SGFRb8Cxi4KR4cS/jPuQVjd+B9fWkc74BUWE91t +3R87Uypd+1qnmoN6cOssLZ4s8n/cyOCkVphGmk1tDDhbEsI4knOqtPXaBHiC4lVI +ghpTHEDUuDfbQ7scySae8/YItTC/vVGngiJmZSfZU5AvVspe6rfkHQHqZs3gYMqj +XPl7acviEAZ7OiMp9diq6Kgp+xLRvRGL+jtUjLkP5O4gJlnxCm7YWrYfYA/vHULD +MyIGSBzuESGxL+Ygz+Dc0Aim9NPM5KhpV5FoAXNt50cn6n1adIwbUciRY0zBXKAI +Vj6D+j3e0ozsO+GGEpmQFAIo1h7CEn8VV61WaLz2F60LKR8d/DEMZ7SY8uznbzkm +TJCeCp/pTnPeGwkyJmJ78LAaKw2tSCeEAfRlnzPeQeanOnEX/wnAjHHAHewvGgQe +GW1QkEdy8zNmfODDf9wqknBShaFRHAOAQFEgBAkYHuT4SgHqW8TVDtF3CQARAQAB +tDdNb25nb0RCIDMuNCBSZWxlYXNlIFNpZ25pbmcgS2V5IDxwYWNrYWdpbmdAbW9u +Z29kYi5jb20+iQI+BBMBAgAoBQJWlDYbAhsDBQkDwmcABgsJCAcDAgYVCAIJCgsE +FgIDAQIeAQIXgAAKCRC8cR+boVcDxmtEEACSjnZcwcozGYS/8peH2P8yPxD2mXVQ +AJ8Pss+YBo8hpRaiA7BEY+FFthbSYEX8XRR/Bg9HjDk9CNXc221I0WcTRv3Sb718 +QutRd4ppdGtusgTHjUdYNDzctExU90vtJRvwI2oiz2YA8dM7mtTzUFpR4IQGopB4 +PmjEls6hkebTjjSaO9UmcLyip+S+rTZ9c8UQvBH7rNoe4QacmGi/l/uUo/q4J7nE +jtjpsemUK7LWY7YtB21F/hH3OrQkgQAoVv2q2xSaiLJeWsr33jgd4o4/d3QN1t/P +GkNIOEBdO/hM8uOj+hGD+tDphHzd9jGjALqV6lC2k9zNXyAFnTUwp0NL74hODv6z +daihKu4fTRU7S0eYSGc2sQDPiiQF5YkxAHqADnPmR2ZpBVVtbUNB31BDOYjTzRwq +tkLKRCgI29Kgut0Uhvq+/Hx+0485ndgzcqeaLhslUagZy1bXN3sDW4QYN2tPvP+P +2JDtGydsYGZCWA0FBRFdsSbruBSK/BkEpGhq97bE9vclfVchb989A47lgErusw5C +xtLxUGPmVc2dYmHJLUkgHszdcTLHwy8/arYMehG7RVzAEG55AueLsc9B0vSI0E6r +lvalHgoCttCynEzM4Ol1rcG9XtlCyKk4AeimYLE/cxlckDoIVVwrFXrRrhB41Asw +rP4l4xtk+nWHpg== +=F42J +-----END PGP PUBLIC KEY BLOCK----- diff --git a/mongodb/handlers/main.yml b/mongodb/handlers/main.yml index c651d98e..46a307cc 100644 --- a/mongodb/handlers/main.yml +++ b/mongodb/handlers/main.yml @@ -2,15 +2,6 @@ # handlers file for mongodb - name: restart mongodb service: - name: mongodb + name: mongod state: restarted -- name: reload squid - service: - name: squid - state: reloaded - -- name: reload squid3 - service: - name: squid3 - state: reloaded diff --git a/mongodb/tasks/main.yml b/mongodb/tasks/main.yml index f3c0c244..0caee268 100644 --- a/mongodb/tasks/main.yml +++ b/mongodb/tasks/main.yml @@ -1,29 +1,15 @@ --- -# tasks file for mongodb -- name: Check if Squid is present - stat: - path: /etc/squid3/whitelist-custom.conf - register: _squid3_whitelist - check_mode: no -- name: add keyserver to Squid whitelist - lineinfile: - dest: /etc/squid3/whitelist-custom.conf - line: "{{ item }}" - notify: reload squid3 - with_items: - - "http://keyserver.ubuntu.com/.*" - - "hkp://keyserver.ubuntu.com/.*" - - "http://repo.mongodb.org/.*" - when: _squid3_whitelist.stat.exists - -- meta: flush_handlers +- fail: + msg: only compatible with Debian 8 + when: + - ansible_distribution != "Debian" or ansible_distribution_release != "jessie" # Attention à bien indiquer le protocole et le port, sinon le firewall ne laisse pas passer - name: MongoDB public GPG Key apt_key: - keyserver: "hkp://keyserver.ubuntu.com:80" - id: "0C49F3730359A14518585931BC711F9BA15703C6" + # url: https://www.mongodb.org/static/pgp/server-3.4.asc + data: "{{ lookup('file', 'server-3.4.asc') }}" - name: enable APT sources list apt_repository: @@ -51,3 +37,8 @@ dest: /etc/logrotate.d/mongodb force: yes backup: no + +- name: enable mongod service + service: + name: mongod + enabled: yes diff --git a/monit/defaults/main.yml b/monit/defaults/main.yml index 39d28f24..2657f67d 100644 --- a/monit/defaults/main.yml +++ b/monit/defaults/main.yml @@ -1,7 +1,7 @@ --- monit_daemon_time: 60 monit_alert_dest: -monit_httpd_enable: true +monit_httpd_enable: True monit_httpd_port: 2812 monit_httpd_allow_items: - localhost diff --git a/clamav/defaults/main.yml b/munin/defaults/main.yml similarity index 100% rename from clamav/defaults/main.yml rename to munin/defaults/main.yml diff --git a/munin/tasks/debian.yml b/munin/tasks/debian.yml deleted file mode 100644 index cec24e62..00000000 --- a/munin/tasks/debian.yml +++ /dev/null @@ -1,87 +0,0 @@ ---- - -- name: Ensure that Munin is installed - apt: - name: '{{ item }}' - state: present - with_items: - - munin - - munin-node - - munin-plugins-core - - munin-plugins-extra - tags: - - munin - - packages - -- block: - - name: Replace localdomain in Munin config - replace: - dest: /etc/munin/munin.conf - regexp: 'localhost.localdomain' - replace: '{{ ansible_fqdn }}' - notify: restart munin-node - - - name: Rename the localdomain data dir - command: mv /var/lib/munin/localdomain /var/lib/munin/{{ ansible_domain }} - args: - creates: /var/lib/munin/{{ ansible_domain }} - removes: /var/lib/munin/localdomain - notify: restart munin-node - - when: not ansible_hostname == "localdomain" - tags: - - munin - -- name: Ensure some Munin plugins are disabled - file: - path: '/etc/munin/plugins/{{ item }}' - state: absent - with_items: - - http_loadtime - - exim_mailqueue - - exim_mailstats - - nfsd - - nfsd4 - - nfs_client - - nfs4_client - notify: restart munin-node - tags: - - munin - -- name: Ensure some Munin plugins are enabled - file: - src: "/usr/share/munin/plugins/{{ item }}" - dest: "/etc/munin/plugins/{{ item }}" - state: link - with_items: - - meminfo - - netstat_multi - - tcp - notify: restart munin-node - tags: - - munin - -- name: Enable sensors plugin unless VM detected - file: - src: /usr/share/munin/plugins/sensors_ - dest: /etc/munin/plugins/sensors_temp - state: link - when: ansible_virtualization_role != "guest" - notify: restart munin-node - tags: - - munin - -- name: adjustments for grsec kernel - blockinfile: - dest: /etc/munin/plugin-conf.d/munin-node - block: | - - [processes] - user root - - [vmstat] - user root - - [swap] - user root - when: ansible_kernel | search("-grs-") diff --git a/munin/tasks/main.yml b/munin/tasks/main.yml index bb765176..cec24e62 100644 --- a/munin/tasks/main.yml +++ b/munin/tasks/main.yml @@ -1,6 +1,87 @@ --- -- include: debian.yml - when: ansible_os_family == "Debian" -- include: openbsd.yml - when: ansible_os_family == "OpenBSD" +- name: Ensure that Munin is installed + apt: + name: '{{ item }}' + state: present + with_items: + - munin + - munin-node + - munin-plugins-core + - munin-plugins-extra + tags: + - munin + - packages + +- block: + - name: Replace localdomain in Munin config + replace: + dest: /etc/munin/munin.conf + regexp: 'localhost.localdomain' + replace: '{{ ansible_fqdn }}' + notify: restart munin-node + + - name: Rename the localdomain data dir + command: mv /var/lib/munin/localdomain /var/lib/munin/{{ ansible_domain }} + args: + creates: /var/lib/munin/{{ ansible_domain }} + removes: /var/lib/munin/localdomain + notify: restart munin-node + + when: not ansible_hostname == "localdomain" + tags: + - munin + +- name: Ensure some Munin plugins are disabled + file: + path: '/etc/munin/plugins/{{ item }}' + state: absent + with_items: + - http_loadtime + - exim_mailqueue + - exim_mailstats + - nfsd + - nfsd4 + - nfs_client + - nfs4_client + notify: restart munin-node + tags: + - munin + +- name: Ensure some Munin plugins are enabled + file: + src: "/usr/share/munin/plugins/{{ item }}" + dest: "/etc/munin/plugins/{{ item }}" + state: link + with_items: + - meminfo + - netstat_multi + - tcp + notify: restart munin-node + tags: + - munin + +- name: Enable sensors plugin unless VM detected + file: + src: /usr/share/munin/plugins/sensors_ + dest: /etc/munin/plugins/sensors_temp + state: link + when: ansible_virtualization_role != "guest" + notify: restart munin-node + tags: + - munin + +- name: adjustments for grsec kernel + blockinfile: + dest: /etc/munin/plugin-conf.d/munin-node + block: | + + [processes] + user root + + [vmstat] + user root + + [swap] + user root + when: ansible_kernel | search("-grs-") diff --git a/munin/tasks/openbsd.yml b/munin/tasks/openbsd.yml deleted file mode 100644 index fc9a1027..00000000 --- a/munin/tasks/openbsd.yml +++ /dev/null @@ -1,100 +0,0 @@ ---- - -- name: Ensure that Munin is installed - openbsd_pkg: - name: '{{ item }}' - state: present - with_items: - - munin-server - - munin-node - tags: - - munin - - packages - -- name: Set munin.conf file - template: - src: munin.conf.j2 - dest: /etc/munin/munin.conf - mode: "0644" - tags: - - munin - -- name: Create munin www directory - file: - path: '{{ munin_dir }}' - state: directory - owner: _munin - group: www - mode: "0755" - tags: - - munin - -- name: Set munin-node config - template: - src: munin-node.conf.j2 - dest: /etc/munin/munin-node.conf - mode: "0644" - notify: restart munin_node - tags: - - munin - -- name: Install munin cron - copy: - src: "crontab" - dest: "/var/cron/tabs/_munin" - owner: "_munin" - group: "crontab" - tags: - - munin - -- name: Enable munin plugins - file: - src: "/usr/local/libexec/munin/plugins/{{ item }}" - dest: "/etc/munin/plugins/{{ item }}" - state: link - with_items: - - cpu - - df - - df_inode - - load - - memory - - munin_stats - - netstat - - open_files - - pf_changes - - pf_searches - - pf_states - - processes - - systat - - uptime - - users - - vmstat - notify: restart munin_node - tags: - - munin - -- name: Enable network graphs - file: - src: "/usr/local/libexec/munin/plugins/if_" - dest: "/etc/munin/plugins/if_{{ item }}" - state: link - notify: restart munin_node - with_items: "{{ ansible_interfaces }}" - -- name: Enable sensors plugin unless VM detected - file: - src: /usr/local/libexec/munin/plugins/sensors_ - dest: /etc/munin/plugins/sensors_temp - state: link - when: ansible_vio0 is undefined - notify: restart munin_node - tags: - - munin - -- name: Activating munin_node - service: - name: munin_node - enabled: yes - state: started - tags: - - munin diff --git a/munin/templates/munin.conf.j2 b/munin/templates/munin.conf.j2 index 6c837aa3..27e9c97e 100644 --- a/munin/templates/munin.conf.j2 +++ b/munin/templates/munin.conf.j2 @@ -6,7 +6,7 @@ # defaulted to the values you see here. # #dbdir /var/db/munin -htmldir {{ munin_dir }} +#htmldir /var/cache/munin/www #logdir /var/log/munin #rundir /var/run/munin diff --git a/munin/vars/main.yml b/munin/vars/main.yml deleted file mode 100644 index 005a7989..00000000 --- a/munin/vars/main.yml +++ /dev/null @@ -1,2 +0,0 @@ ---- -munin_dir: /home/www/munin diff --git a/mysql/README.md b/mysql/README.md index e8a8399f..b1e4bf57 100644 --- a/mysql/README.md +++ b/mysql/README.md @@ -18,7 +18,7 @@ Tasks are extracted in several files, included in `tasks/main.yml` : ## Available variables -* `mysql_variant` : install Oracle's MySQL or MariaDB (default: `oracle`) ; +* `mysql_variant` : install Oracle's MySQL or MariaDB (default: `oracle`) [Debian 8 only]; * `mysql_replace_root_with_mysqladmin`: switch from `root` to `mysqladmin` user or not ; * `mysql_thread_cache_size`: number of threads for the cache ; * `mysql_innodb_buffer_pool_size`: amount of RAM dedicated to InnoDB ; @@ -30,4 +30,4 @@ Tasks are extracted in several files, included in `tasks/main.yml` : * `mysql_scripts_dir`: email address to send Log2mail messages to (default: `general_scripts_dir`). * `mysql_force_new_nrpe_password` : change the password for NRPE even if it exists already (default: `False`). -NB : changing the _datadir_ location can be done multiple times, as long as it is not restored to the default initial location, (because a symlink is created and can't be switched back, yet). +NB : changing the _datadir_ location can be done multiple times, as long as it is not restored to the default initial location, (because a symlink is created and can't be switched back, yet). diff --git a/mysql/defaults/main.yml b/mysql/defaults/main.yml index 3c2bbeb6..d56e5999 100644 --- a/mysql/defaults/main.yml +++ b/mysql/defaults/main.yml @@ -2,7 +2,7 @@ general_alert_email: "root@localhost" log2mail_alert_email: Null -general_scripts_dir: "/usr/local/bin" +general_scripts_dir: "/usr/share/scripts" mysql_scripts_dir: Null mysql_variant: oracle @@ -18,4 +18,7 @@ mysql_innodb_buffer_pool_size: '{{ (ansible_memtotal_mb * 0.3) | int }}M' mysql_cron_optimize: True mysql_cron_optimize_frequency: weekly +mysql_cron_mysqltuner: True +mysql_cron_mysqltuner_frequency: monthly + mysql_force_new_nrpe_password: False diff --git a/mysql/files/evolinux-defaults.cnf b/mysql/files/evolinux-defaults.cnf index 9e3f87d4..395ccac4 100644 --- a/mysql/files/evolinux-defaults.cnf +++ b/mysql/files/evolinux-defaults.cnf @@ -8,7 +8,8 @@ back_log = 100 # Maximum d'erreurs avant de blacklister un hote max_connect_errors = 10 # Loguer les requetes trop longues -slow_query_log = /var/log/mysql/mysql-slow.log +slow_query_log = 1 +slow_query_log_file = /var/log/mysql/mysql-slow.log long_query_time = 10 ###### Tailles @@ -57,3 +58,5 @@ innodb_thread_concurrency = 16 # charset utf8 par defaut character-set-server=utf8 collation-server=utf8_general_ci +# Patch MySQL 5.5.53 +secure-file-priv = "" diff --git a/mysql/files/mysqltuner.cron.sh b/mysql/files/mysqltuner.cron.sh new file mode 100644 index 00000000..5424aa90 --- /dev/null +++ b/mysql/files/mysqltuner.cron.sh @@ -0,0 +1,50 @@ +#!/bin/bash +set -e +export TERM=screen + +mem=$(free -m | grep Mem: | tr -s ' ' | cut -d ' ' -f2) +swap=$(free -m | grep Swap: | tr -s ' ' | cut -d ' ' -f2) +template=$(mktemp --tmpdir=/tmp evomysqltuner.XXX) +body=$(mktemp --tmpdir=/tmp evomysqltuner.XXX) +clientmail=$(grep EVOMAINTMAIL /etc/evomaintenance.cf | cut -d'=' -f2) +hostname=$(grep HOSTNAME /etc/evomaintenance.cf | cut -d'=' -f2) +hostname=${hostname%%.evolix.net} +# If hostname is composed with -, remove the first part. +if [[ $hostname =~ "-" ]]; then + hostname=$(echo $hostname | cut -d'-' -f2-) +fi + +# Remove temporary files on exit. +trap "rm $template $body" EXIT + +# Add port here if you have more than one instance! +instances="3306" +for instance in $instances; do + mysqltuner --port $instance --host 127.0.0.1 --forcemem $mem --forceswap $swap \ + | aha > /var/www/mysqlreport_${instance}.html + cat << EOT > $template +Content-Type: text/plain; charset="utf-8" +Reply-To: Équipe Evolix +From: Équipe Evolix +To: $clientmail +Subject: Rapport MySQL instance $instance pour votre serveur $hostname +EOT + cat << EOT > $body +Bonjour, + +Veuillez trouver ci-joint un rapport MySQL. +Celui-ci permet d'identifier aisément si des optimisations MySQL sont possibles. + +N'hésitez pas à nous indiquer par mail ou ticket quelles variables vous souhaiter +optimiser. + +Veuillez noter qu'il faudra redémarrer MySQL pour appliquer de nouveaux paramètres. + +Bien à vous, +-- +Rapport automatique Evolix +EOT + mutt -x -e 'set send_charset="utf-8"' -H $template \ + -a /var/www/mysqlreport_${instance}.html < $body +done +chmod 644 /var/www/mysqlreport*html diff --git a/mysql/handlers/main.yml b/mysql/handlers/main.yml index 35d5b5bf..80375330 100644 --- a/mysql/handlers/main.yml +++ b/mysql/handlers/main.yml @@ -13,3 +13,7 @@ service: name: mysql state: restarted + +- name: reload systemd + command: systemctl daemon-reload + diff --git a/mysql/tasks/config.yml b/mysql/tasks/config_jessie.yml similarity index 74% rename from mysql/tasks/config.yml rename to mysql/tasks/config_jessie.yml index fbd85f01..dcb83a61 100644 --- a/mysql/tasks/config.yml +++ b/mysql/tasks/config_jessie.yml @@ -1,5 +1,5 @@ --- -- name: Copy MySQL defaults config file +- name: "Copy MySQL defaults config file (jessie)" copy: src: evolinux-defaults.cnf dest: /etc/mysql/conf.d/z-evolinux-defaults.cnf @@ -10,13 +10,13 @@ tags: - mysql -- name: Copy MySQL custom config file +- name: "Copy MySQL custom config file (jessie)" template: src: evolinux-custom.cnf.j2 dest: /etc/mysql/conf.d/zzz-evolinux-custom.cnf owner: root group: root - mode: "0640" + mode: "0644" force: no tags: - mysql diff --git a/mysql/tasks/config_stretch.yml b/mysql/tasks/config_stretch.yml new file mode 100644 index 00000000..22b2d312 --- /dev/null +++ b/mysql/tasks/config_stretch.yml @@ -0,0 +1,34 @@ +--- +- name: "Copy MySQL defaults config file (Debian 9 or later)" + copy: + src: evolinux-defaults.cnf + dest: /etc/mysql/mariadb.conf.d/z-evolinux-defaults.cnf + owner: root + group: root + mode: "0644" + force: yes + tags: + - mysql + +- name: "Copy MySQL custom config file (Debian 9 or later)" + template: + src: evolinux-custom.cnf.j2 + dest: /etc/mysql/mariadb.conf.d/zzz-evolinux-custom.cnf + owner: root + group: root + mode: "0644" + force: no + tags: + - mysql + +- name: "Create a system config directory for systemd overrides (Debian 9 or later)" + file: + path: /etc/systemd/system/mariadb.service.d + state: directory + +- name: "Override MariaDB systemd unit (Debian 9 or later)" + template: + src: mariadb.systemd.j2 + dest: /etc/systemd/system/mariadb.service.d/evolinux.conf + force: yes + notify: reload systemd diff --git a/mysql/tasks/log2mail.yml b/mysql/tasks/log2mail.yml index fb256d26..568b6649 100644 --- a/mysql/tasks/log2mail.yml +++ b/mysql/tasks/log2mail.yml @@ -13,6 +13,8 @@ template: src: log2mail.j2 dest: /etc/log2mail/config/mysql.conf + owner: log2mail + group: adm mode: "0640" when: log2mail_config_dir.stat.exists tags: diff --git a/mysql/tasks/main.yml b/mysql/tasks/main.yml index 273960a9..dd9c2e99 100644 --- a/mysql/tasks/main.yml +++ b/mysql/tasks/main.yml @@ -1,10 +1,22 @@ --- -- include: packages.yml +- include: packages_stretch.yml + when: ansible_distribution_major_version | version_compare('9', '>=') -- include: users.yml +- include: packages_jessie.yml + when: ansible_distribution_release == "jessie" -- include: config.yml +- include: users_stretch.yml + when: ansible_distribution_major_version | version_compare('9', '>=') + +- include: users_jessie.yml + when: ansible_distribution_release == "jessie" + +- include: config_stretch.yml + when: ansible_distribution_major_version | version_compare('9', '>=') + +- include: config_jessie.yml + when: ansible_distribution_release == "jessie" - include: datadir.yml diff --git a/mysql/tasks/munin.yml b/mysql/tasks/munin.yml index 59560867..0903def1 100644 --- a/mysql/tasks/munin.yml +++ b/mysql/tasks/munin.yml @@ -10,10 +10,13 @@ - munin - block: - - name: Install libcache-cache-perl for Munin + - name: Install perl libraries for Munin apt: - name: libcache-cache-perl + name: "{{ item }}" state: present + with_items: + - libdbd-mysql-perl + - libcache-cache-perl - name: Enable core Munin plugins file: diff --git a/mysql/tasks/nrpe.yml b/mysql/tasks/nrpe.yml index 7cebcf50..88765193 100644 --- a/mysql/tasks/nrpe.yml +++ b/mysql/tasks/nrpe.yml @@ -20,7 +20,7 @@ - block: - name: Create a password for NRPE - shell: perl -e 'print map{("a".."z","A".."Z",0..9)[int(rand(62))]}(1..16)' + command: "apg -n 1 -m 16 -M lcN" register: mysql_nrpe_password changed_when: False @@ -28,6 +28,7 @@ mysql_user: name: nrpe password: '{{ mysql_nrpe_password.stdout }}' + priv: "*.*:REPLICATION CLIENT" config_file: /root/.my.cnf update_password: always state: present diff --git a/mysql/tasks/packages.yml b/mysql/tasks/packages_jessie.yml similarity index 100% rename from mysql/tasks/packages.yml rename to mysql/tasks/packages_jessie.yml diff --git a/mysql/tasks/packages_stretch.yml b/mysql/tasks/packages_stretch.yml new file mode 100644 index 00000000..d625f691 --- /dev/null +++ b/mysql/tasks/packages_stretch.yml @@ -0,0 +1,29 @@ +--- + +- name: Install MySQL packages + apt: + name: '{{ item }}' + update_cache: yes + state: present + with_items: + - mariadb-server + - mariadb-client + tags: + - mysql + - packages + +- name: MySQL is started + service: + name: mysql + state: started + tags: + - mysql + - services + +- name: apg package is installed + apt: + name: apg + state: present + tags: + - mysql + - packages diff --git a/mysql/tasks/users.yml b/mysql/tasks/users_jessie.yml similarity index 80% rename from mysql/tasks/users.yml rename to mysql/tasks/users_jessie.yml index 82c9b213..a8c22cf8 100644 --- a/mysql/tasks/users.yml +++ b/mysql/tasks/users_jessie.yml @@ -10,7 +10,7 @@ - mysql - name: create a password for mysqladmin - shell: perl -e 'print map{("a".."z","A".."Z",0..9)[int(rand(62))]}(1..16)' + command: "apg -n 1 -m 16 -M lcN" register: mysql_admin_password changed_when: False tags: @@ -46,14 +46,8 @@ - name: remove root user mysql_user: name: root - #host_all: yes - host: "{{ item }}" - config_file: "/etc/mysql/debian.cnf" + host_all: yes + config_file: "/root/.my.cnf" state: absent - with_items: - - "localhost" - - "127.0.0.1" - - "::1" - - "{{ ansible_hostname }}" tags: - mysql diff --git a/mysql/tasks/users_stretch.yml b/mysql/tasks/users_stretch.yml new file mode 100644 index 00000000..c57bd3ae --- /dev/null +++ b/mysql/tasks/users_stretch.yml @@ -0,0 +1,90 @@ +--- + +# dependency for mysql_user and mysql_db + +- name: python-mysqldb is installed (Ansible dependency) + apt: + name: python-mysqldb + state: present + tags: + - mysql + +- name: create a password for mysqladmin + command: "apg -n 1 -m 16 -M lcN" + register: mysql_admin_password + changed_when: False + tags: + - mysql + +- name: there is a mysqladmin user + mysql_user: + name: mysqladmin + password: '{{ mysql_admin_password.stdout }}' + priv: "*.*:ALL,GRANT" + update_password: on_create + state: present + config_file: "/etc/mysql/debian.cnf" + register: create_mysqladmin_user + tags: + - mysql + +- name: mysqladmin is the default user + ini_file: + dest: /root/.my.cnf + mode: "0600" + section: client + option: '{{ item.option }}' + value: '{{ item.value }}' + create: yes + with_items: + - { option: 'user', value: 'mysqladmin' } + - { option: password, value: '{{ mysql_admin_password.stdout }}' } + when: create_mysqladmin_user.changed + tags: + - mysql + + +- name: create a password for debian-sys-maint + command: "apg -n 1 -m 16 -M lcN" + register: mysql_debian_password + changed_when: False + tags: + - mysql + +- name: there is a debian-sys-maint user + mysql_user: + name: debian-sys-maint + password: '{{ mysql_debian_password.stdout }}' + priv: "*.*:ALL,GRANT" + update_password: on_create + state: present + config_file: "/root/.my.cnf" + register: create_debian_user + tags: + - mysql + +- name: store debian-sys-maint user credentials + ini_file: + dest: /etc/mysql/debian.cnf + mode: "0600" + section: "{{ item[0] }}" + option: '{{ item[1].option }}' + value: '{{ item[1].value }}' + create: yes + with_nested: + - [ "client", "mysql_upgrade" ] + - [ { option: 'user', value: 'debian-sys-maint' }, + { option: password, value: '{{ mysql_debian_password.stdout }}' } + ] + when: create_debian_user.changed + tags: + - mysql + +- name: remove root user + mysql_user: + name: root + host_all: yes + config_file: "/root/.my.cnf" + state: absent + tags: + - mysql diff --git a/mysql/tasks/utils.yml b/mysql/tasks/utils.yml index 58faeee4..d0fe71a8 100644 --- a/mysql/tasks/utils.yml +++ b/mysql/tasks/utils.yml @@ -1,8 +1,16 @@ --- +- name: Ensure scripts directory exists + file: + dest: "{{ mysql_scripts_dir or general_scripts_dir | mandatory }}" + mode: "0700" + state: directory + tags: + - mysql + # mytop -- name: Install mytop +- name: "Install mytop (jessie)" apt: name: mytop state: present @@ -10,6 +18,16 @@ - packages - mytop - mysql + when: ansible_distribution_release == "jessie" + +- name: "Install depends for mytop (Debian 9 or later)" + apt: + name: "{{ item }}" + with_items: + - mariadb-client-10.1 + - libconfig-inifiles-perl + - libterm-readkey-perl + when: ansible_distribution_major_version | version_compare('9', '>=') - name: Read debian-sys-maint password shell: cat /etc/mysql/debian.cnf | grep -m1 "password = .*" | cut -d" " -f3 @@ -34,10 +52,13 @@ when: (mysql_scripts_dir or general_scripts_dir) | search ("/usr") - name: Install mysqltuner - copy: - src: mysqltuner.pl - dest: "{{ mysql_scripts_dir or general_scripts_dir | mandatory }}/mysqltuner.pl" - mode: "0700" + # copy: + # src: mysqltuner.pl + # dest: "{{ mysql_scripts_dir or general_scripts_dir | mandatory }}/mysqltuner.pl" + # mode: "0700" + apt: + name: mysqltuner + state: present tags: - mysql - mysqltuner @@ -61,7 +82,7 @@ tags: - mysql -- name: "Cron dir is present" +- name: "Cron dir for optimize is present" file: path: "/etc/cron.{{ mysql_cron_optimize_frequency | mandatory }}" state: directory @@ -80,25 +101,41 @@ - name: "Disable cron to optimize MySQL" file: - dest: /etc/cron.weekly/mysql-optimize.sh + dest: /etc/cron.{{ mysql_cron_optimize_frequency | mandatory }}/mysql-optimize.sh state: absent when: not mysql_cron_optimize tags: - mysql +- name: "Cron dir for mysqltuner is present" + file: + path: "/etc/cron.{{ mysql_cron_mysqltuner_frequency | mandatory }}" + state: directory + mode: "0755" + owner: root + group: root + +- name: "Enable mysqltuner in cron" + copy: + src: mysqltuner.cron.sh + dest: /etc/cron.{{ mysql_cron_mysqltuner_frequency | mandatory }}/mysqltuner.sh + when: mysql_cron_mysqltuner + tags: + - mysql + +- name: "Disable mysqltuner in cron" + file: + dest: /etc/cron.{{ mysql_cron_mysqltuner_frequency | mandatory }}/mysqltuner.sh + state: absent + when: not mysql_cron_mysqltuner + tags: + - mysql + # my-add.sh - include: remount_usr_rw.yml when: (mysql_scripts_dir or general_scripts_dir) | search ("/usr") -- name: Ensure /usr/share/scripts exists - file: - dest: /usr/share/scripts - mode: "0700" - state: directory - tags: - - mysql - - name: Install my-add.sh copy: src: my-add.sh diff --git a/mysql/templates/mariadb.systemd.j2 b/mysql/templates/mariadb.systemd.j2 new file mode 100644 index 00000000..44f1f6e8 --- /dev/null +++ b/mysql/templates/mariadb.systemd.j2 @@ -0,0 +1,4 @@ +# {{ ansible_managed }} + +[Service] +ProtectHome=false diff --git a/nagios-nrpe/defaults/main.yml b/nagios-nrpe/defaults/main.yml index b02a8be5..c9ee2603 100644 --- a/nagios-nrpe/defaults/main.yml +++ b/nagios-nrpe/defaults/main.yml @@ -5,4 +5,6 @@ nagios_nrpe_ldap_passwd: LDAP_PASSWD nagios_nrpe_pgsql_passwd: PGSQL_PASSWD nagios_nrpe_amavis_from: "foobar@{{ ansible_domain }}" +nagios_nrpe_check_proxy_host: "www.example.com" + nagios_plugins_directory: "/usr/local/lib/nagios/plugins" diff --git a/nagios-nrpe/files/plugins/check_http_many b/nagios-nrpe/files/plugins/check_http_many index 90d8d9e2..e027e23a 100644 --- a/nagios-nrpe/files/plugins/check_http_many +++ b/nagios-nrpe/files/plugins/check_http_many @@ -35,7 +35,7 @@ check_state() { sites="" for site in $sites; do echo -n "Site ${site}: " >> $result - /usr/lib/nagios/plugins/check_http -f critical -I 127.0.0.1 -H ${site%%/*} -u /${site#*/} >> $result + /usr/lib/nagios/plugins/check_http -f critical -e 200 -I 127.0.0.1 -H ${site%%/*} -u /${site#*/} >> $result check_state $? done @@ -43,7 +43,7 @@ done sites="" for site in $sites; do echo -n "Site ${site}: " >> $result - /usr/lib/nagios/plugins/check_http -w4 -c6 -f critical -p 443 -S -I 127.0.0.1 -H ${site%%/*} -u /${site#*/} >> $result + /usr/lib/nagios/plugins/check_http -f critical -e 200 -p 443 -S -I 127.0.0.1 -H ${site%%/*} -u /${site#*/} >> $result check_state $? done diff --git a/nagios-nrpe/tasks/debian.yml b/nagios-nrpe/tasks/debian.yml deleted file mode 100644 index d50bc533..00000000 --- a/nagios-nrpe/tasks/debian.yml +++ /dev/null @@ -1,49 +0,0 @@ ---- -- name: packages are installed - apt: - name: "{{ item }}" - state: present - with_items: - - nagios-nrpe-server - - nagios-plugins - - nagios-plugins-basic - - nagios-plugins-common - - nagios-plugins-contrib - - nagios-plugins-standard - -- name: custom configuration is present - template: - src: evolix.cfg.j2 - dest: /etc/nagios/nrpe.d/evolix.cfg - notify: restart nagios-nrpe-server - -- name: Nagios config is secured - file: - dest: /etc/nagios/ - mode: "0750" - group: nagios - state: directory - notify: restart nagios-nrpe-server - -- include: remount_usr_rw.yml - when: nagios_plugins_directory | search ("/usr") - tags: - - nagios-plugins - -- name: Nagios plugins are installed - copy: - src: plugins/ - dest: "{{ nagios_plugins_directory }}/" - mode: "0755" - notify: restart nagios-nrpe-server - tags: - - nagios-plugins - -- name: Nagios lib is secured - file: - dest: /usr/local/lib/nagios/ - mode: "0755" - group: nagios - recurse: yes - state: directory - notify: restart nagios-nrpe-server diff --git a/nagios-nrpe/tasks/main.yml b/nagios-nrpe/tasks/main.yml index e723d322..dbb73903 100644 --- a/nagios-nrpe/tasks/main.yml +++ b/nagios-nrpe/tasks/main.yml @@ -1,10 +1,51 @@ --- -- include: debian.yml - when: ansible_os_family == "Debian" - tags: - - nagios +- name: packages are installed + apt: + name: "{{ item }}" + state: present + with_items: + - nagios-nrpe-server + - nagios-plugins + - nagios-plugins-basic + - nagios-plugins-common + - nagios-plugins-contrib + - nagios-plugins-standard -- include: openbsd.yml - when: ansible_os_family == "OpenBSD" +- name: custom configuration is present + template: + src: evolix.cfg.j2 + dest: /etc/nagios/nrpe.d/evolix.cfg + group: nagios + mode: "0640" + notify: restart nagios-nrpe-server + +- name: Nagios config is secured + file: + dest: /etc/nagios/ + mode: "0750" + group: nagios + state: directory + notify: restart nagios-nrpe-server + +- include: remount_usr_rw.yml + when: nagios_plugins_directory | search ("/usr") tags: - - nagios + - nagios-plugins + +- name: Nagios plugins are installed + copy: + src: plugins/ + dest: "{{ nagios_plugins_directory }}/" + mode: "0755" + notify: restart nagios-nrpe-server + tags: + - nagios-plugins + +- name: Nagios lib is secured + file: + dest: /usr/local/lib/nagios/ + mode: "0755" + group: nagios + recurse: yes + state: directory + notify: restart nagios-nrpe-server diff --git a/nagios-nrpe/tasks/openbsd.yml b/nagios-nrpe/tasks/openbsd.yml deleted file mode 100644 index 5229778e..00000000 --- a/nagios-nrpe/tasks/openbsd.yml +++ /dev/null @@ -1,42 +0,0 @@ ---- -- name: packages are installed - openbsd_pkg: - name: "{{ item }}" - state: present - with_items: - - nrpe-- - - monitoring-plugins - -- name: Create nrpe.d dir - file: - path: /etc/nrpe.d - state: directory - owner: root - group: wheel - mode: "0755" - -- name: Include nrpe.d dir in nrpe.cfg - lineinfile: - dest: /etc/nrpe.cfg - line: 'include_dir=/etc/nrpe.d' - -- name: custom configuration is present - template: - src: evolix_bsd.cfg.j2 - dest: /etc/nrpe.d/evolix.cfg - notify: restart nrpe - -- name: Nagios plugins are installed - copy: - src: plugins_bsd/ - dest: /usr/local/libexec/nagios/plugins/ - owner: root - group: wheel - mode: "0755" - notify: restart nrpe - -- name: Starting and enabling nrpe - service: - name: nrpe - enabled: yes - state: started diff --git a/nagios-nrpe/templates/evolix.cfg.j2 b/nagios-nrpe/templates/evolix.cfg.j2 index c0e434de..45223167 100644 --- a/nagios-nrpe/templates/evolix.cfg.j2 +++ b/nagios-nrpe/templates/evolix.cfg.j2 @@ -31,8 +31,8 @@ command[check_imaps]=/usr/lib/nagios/plugins/check_imap -S -H localhost -p 993 command[check_pop]=/usr/lib/nagios/plugins/check_pop -H localhost command[check_pops]=/usr/lib/nagios/plugins/check_pop -S -H localhost -p 995 command[check_ftp]=/usr/lib/nagios/plugins/check_ftp -H localhost -command[check_http]=/usr/lib/nagios/plugins/check_http -f follow -I 127.0.0.1 -H localhost -command[check_https]=/usr/lib/nagios/plugins/check_http -f follow -I 127.0.0.1 -S -p 443 -H ssl.evolix.net +command[check_http]=/usr/lib/nagios/plugins/check_http -e 200 -I 127.0.0.1 -H localhost +command[check_https]=/usr/lib/nagios/plugins/check_http -e 200 -I 127.0.0.1 -S -p 443 -H ssl.evolix.net command[check_bind]=/usr/lib/nagios/plugins/check_dig -l evolix.net -H localhost command[check_unbound]=/usr/lib/nagios/plugins/check_dig -l evolix.net -H localhost command[check_smb]=/usr/lib/nagios/plugins/check_tcp -H 127.0.0.1 -p 445 @@ -41,9 +41,10 @@ command[check_jboss-http]=/usr/lib/nagios/plugins/check_tcp -p 8080 command[check_jboss-ajp13]=/usr/lib/nagios/plugins/check_tcp -p 8009 command[check_tomcat-http]=/usr/lib/nagios/plugins/check_tcp -p 8080 command[check_tomcat-ajp13]=/usr/lib/nagios/plugins/check_tcp -p 8009 -command[check_proxy]=/usr/lib/nagios/plugins/check_http -H www.debian.org +command[check_proxy]=/usr/lib/nagios/plugins/check_http -H {{ nagios_nrpe_check_proxy_host }} command[check_redis]=/usr/lib/nagios/plugins/check_tcp -p 6379 command[check_clamd]=/usr/lib/nagios/plugins/check_clamd -H /var/run/clamav/clamd.ctl -v +command[check_clamav_db]=/usr/lib/nagios/plugins/check_file_age -w 86400 -c 172800 -f /var/lib/clamav/evolix.ndb command[check_ssl]=/usr/lib/nagios/plugins/check_http -f follow -I 127.0.0.1 -S -p 443 -H ssl.evolix.net -C 15,5 command[check_elasticsearch]=/usr/lib/nagios/plugins/check_http -I 127.0.0.1 -u /_cat/health?h=st -p 9200 -r 'red' --invert-regex command[check_memcached]=/usr/lib/nagios/plugins/check_tcp -H 127.0.0.1 -p 11211 diff --git a/newrelic-php/.kitchen.yml b/newrelic-php/.kitchen.yml deleted file mode 100644 index b21cc3db..00000000 --- a/newrelic-php/.kitchen.yml +++ /dev/null @@ -1,28 +0,0 @@ ---- -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 - -suites: - - name: default - provisioner: - name: ansible_playbook - playbook: ./tests/test.yml - -transport: - max_ssh_sessions: 6 diff --git a/newrelic-php/README.md b/newrelic-php/README.md deleted file mode 100644 index 36903349..00000000 --- a/newrelic-php/README.md +++ /dev/null @@ -1,14 +0,0 @@ -# newrelic-php - -Installation of NewRelic PHP agent. - -## Tasks - -Everything is in the `tasks/main.yml` file. - -A license key and an application name can be provided to pre-configure the agent. - -## Variables - -* `newrelic_license`: license key (default: empty). -* `newrelic_appname`: application name (default: empty). diff --git a/newrelic-php/meta/main.yml b/newrelic-php/meta/main.yml deleted file mode 100644 index 90f90d1b..00000000 --- a/newrelic-php/meta/main.yml +++ /dev/null @@ -1,19 +0,0 @@ -galaxy_info: - author: Evolix - description: Installation of NewRelic PHP agent. - - issue_tracker_url: https://forge.evolix.org/projects/ansible-roles/issues - - license: GPLv2 - - min_ansible_version: 2.2 - - platforms: - - name: Debian - versions: - - jessie - -dependencies: [] - # List your role dependencies here, one per line. - # Be sure to remove the '[]' above if you add dependencies - # to this list. diff --git a/newrelic-php/tests/test.yml b/newrelic-php/tests/test.yml deleted file mode 100644 index c85b0f1c..00000000 --- a/newrelic-php/tests/test.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -- hosts: test-kitchen - roles: - - role: newrelic-php diff --git a/newrelic-sources/.kitchen.yml b/newrelic-sources/.kitchen.yml deleted file mode 100644 index b21cc3db..00000000 --- a/newrelic-sources/.kitchen.yml +++ /dev/null @@ -1,28 +0,0 @@ ---- -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 - -suites: - - name: default - provisioner: - name: ansible_playbook - playbook: ./tests/test.yml - -transport: - max_ssh_sessions: 6 diff --git a/newrelic-sources/README.md b/newrelic-sources/README.md deleted file mode 100644 index 2b9ddb9d..00000000 --- a/newrelic-sources/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# newrelic-sources - -Installation of NewRelic repository for APT sources. - -## Tasks - -Everything is in the `tasks/main.yml` file. - -NB : the repository key is store in the role and not fetched online, for performance reasons. diff --git a/newrelic-sources/handlers/main.yml b/newrelic-sources/handlers/main.yml deleted file mode 100644 index 0a402c8b..00000000 --- a/newrelic-sources/handlers/main.yml +++ /dev/null @@ -1,10 +0,0 @@ ---- - -- name: Reload Squid - service: - name: squid3 - state: reloaded - -- name: apt update - apt: - update_cache: yes diff --git a/newrelic-sources/meta/main.yml b/newrelic-sources/meta/main.yml deleted file mode 100644 index 19506b43..00000000 --- a/newrelic-sources/meta/main.yml +++ /dev/null @@ -1,19 +0,0 @@ -galaxy_info: - author: Evolix - description: Installation of NewRelic repository for APT sources. - - issue_tracker_url: https://forge.evolix.org/projects/ansible-roles/issues - - license: GPLv2 - - min_ansible_version: 2.2 - - platforms: - - name: Debian - versions: - - jessie - -dependencies: [] - # List your role dependencies here, one per line. - # Be sure to remove the '[]' above if you add dependencies - # to this list. diff --git a/newrelic-sources/tests/test.yml b/newrelic-sources/tests/test.yml deleted file mode 100644 index 3813409e..00000000 --- a/newrelic-sources/tests/test.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -- hosts: test-kitchen - roles: - - role: newrelic-sources diff --git a/newrelic-sysmond/.kitchen.yml b/newrelic-sysmond/.kitchen.yml deleted file mode 100644 index b21cc3db..00000000 --- a/newrelic-sysmond/.kitchen.yml +++ /dev/null @@ -1,28 +0,0 @@ ---- -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 - -suites: - - name: default - provisioner: - name: ansible_playbook - playbook: ./tests/test.yml - -transport: - max_ssh_sessions: 6 diff --git a/newrelic-sysmond/README.md b/newrelic-sysmond/README.md deleted file mode 100644 index c63e4d05..00000000 --- a/newrelic-sysmond/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# newrelic-sysmond - -Installation of NewRelic sysmond. - -## Tasks - -Everything is in the `tasks/main.yml` file. - -if a license key is provided, the daemon is configured. - -## Variables - -* `newrelic_license`: license key (default: empty). diff --git a/newrelic-sysmond/defaults/main.yml b/newrelic-sysmond/defaults/main.yml deleted file mode 100644 index e2d18908..00000000 --- a/newrelic-sysmond/defaults/main.yml +++ /dev/null @@ -1,2 +0,0 @@ ---- -newrelic_license: "" diff --git a/newrelic-sysmond/handlers/main.yml b/newrelic-sysmond/handlers/main.yml deleted file mode 100644 index 5f5a2562..00000000 --- a/newrelic-sysmond/handlers/main.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- - -- name: restart newrelic-sysmond - systemd: - name: newrelic-sysmond - state: restarted diff --git a/newrelic-sysmond/tests/test.yml b/newrelic-sysmond/tests/test.yml deleted file mode 100644 index 69165293..00000000 --- a/newrelic-sysmond/tests/test.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -- hosts: test-kitchen - roles: - - role: newrelic-sysmond diff --git a/courier/.kitchen.yml b/newrelic/.kitchen.yml similarity index 100% rename from courier/.kitchen.yml rename to newrelic/.kitchen.yml diff --git a/newrelic/README.md b/newrelic/README.md new file mode 100644 index 00000000..ee22f3bc --- /dev/null +++ b/newrelic/README.md @@ -0,0 +1,17 @@ +# newrelic-sources + +Installation of NewRelic tools. + +## Tasks + +Everything is in the `tasks/main.yml` file. + +NB : the repository key is store in the role and not fetched online, for performance reasons. + +## Variables + +* `newrelic_license`: license key (default: empty). +* `newrelic_appname`: application name (default: empty). + +* `newrelic_php` : install the php module (default: `False`) +* `newrelic_sysmond` : install the sysmond agent (default: `True`) diff --git a/newrelic-php/defaults/main.yml b/newrelic/defaults/main.yml similarity index 50% rename from newrelic-php/defaults/main.yml rename to newrelic/defaults/main.yml index b568b78e..cddbcb0b 100644 --- a/newrelic-php/defaults/main.yml +++ b/newrelic/defaults/main.yml @@ -1,3 +1,7 @@ --- +newrelic_sysmond: True + +newrelic_php: False + newrelic_license: "" newrelic_appname: "" diff --git a/newrelic-sources/files/548C16BF.gpg b/newrelic/files/548C16BF.gpg similarity index 100% rename from newrelic-sources/files/548C16BF.gpg rename to newrelic/files/548C16BF.gpg diff --git a/newrelic/handlers/main.yml b/newrelic/handlers/main.yml new file mode 100644 index 00000000..4ad78be9 --- /dev/null +++ b/newrelic/handlers/main.yml @@ -0,0 +1,20 @@ +--- + +- name: reload squid3 + service: + name: squid3 + state: reloaded + +- name: reload squid + service: + name: squid + state: reloaded + +- name: apt update + apt: + update_cache: yes + +- name: restart newrelic-sysmond + systemd: + name: newrelic-sysmond + state: restarted diff --git a/newrelic-sysmond/meta/main.yml b/newrelic/meta/main.yml similarity index 88% rename from newrelic-sysmond/meta/main.yml rename to newrelic/meta/main.yml index cd47e809..b355644e 100644 --- a/newrelic-sysmond/meta/main.yml +++ b/newrelic/meta/main.yml @@ -1,6 +1,6 @@ galaxy_info: author: Evolix - description: Installation of NewRelic sysmond. + description: Installation of NewRelic tools. issue_tracker_url: https://forge.evolix.org/projects/ansible-roles/issues diff --git a/newrelic/tasks/main.yml b/newrelic/tasks/main.yml new file mode 100644 index 00000000..7537214d --- /dev/null +++ b/newrelic/tasks/main.yml @@ -0,0 +1,9 @@ +--- + +- include: sources.yml + +- include: php.yml + when: newrelic_php + +- include: sysmond.yml + when: newrelic_sysmond diff --git a/newrelic-php/tasks/main.yml b/newrelic/tasks/php.yml similarity index 96% rename from newrelic-php/tasks/main.yml rename to newrelic/tasks/php.yml index c5ce2fe5..712b42f2 100644 --- a/newrelic-php/tasks/main.yml +++ b/newrelic/tasks/php.yml @@ -1,6 +1,4 @@ --- -- include_role: - name: newrelic-sources - name: Pre-seed package configuration with app name debconf: @@ -41,3 +39,4 @@ - name: Install package for PHP apt: name: newrelic-php5 + state: installed diff --git a/newrelic-sources/tasks/main.yml b/newrelic/tasks/sources.yml similarity index 58% rename from newrelic-sources/tasks/main.yml rename to newrelic/tasks/sources.yml index 5a8ecf6b..b5b35fd0 100644 --- a/newrelic-sources/tasks/main.yml +++ b/newrelic/tasks/sources.yml @@ -1,21 +1,13 @@ --- + - name: Add dotdeb GPG key apt_key: # url: https://download.newrelic.com/548C16BF.gpg data: "{{ lookup('file', '548C16BF.gpg') }}" -- name: Append packages.dotdeb.org to Squid whitelist - lineinfile: - name: /etc/squid3/whitelist-custom.conf - line: "http://apt.newrelic.com/.*" - notify: Reload Squid - -- meta: flush_handlers - - name: Install NewRelic repository apt_repository: repo: "deb http://apt.newrelic.com/debian/ newrelic non-free" state: present filename: newrelic - -- meta: flush_handlers + update_cache: yes diff --git a/newrelic-sysmond/tasks/main.yml b/newrelic/tasks/sysmond.yml similarity index 88% rename from newrelic-sysmond/tasks/main.yml rename to newrelic/tasks/sysmond.yml index a586efbf..5d72a470 100644 --- a/newrelic-sysmond/tasks/main.yml +++ b/newrelic/tasks/sysmond.yml @@ -1,6 +1,4 @@ --- -- include_role: - name: newrelic-sources - name: Install system monitor daemon apt: diff --git a/amavis/tests/test.yml b/newrelic/tests/test.yml similarity index 62% rename from amavis/tests/test.yml rename to newrelic/tests/test.yml index b54bdaea..3a6d806e 100644 --- a/amavis/tests/test.yml +++ b/newrelic/tests/test.yml @@ -1,4 +1,4 @@ --- - hosts: test-kitchen roles: - - role: amavis + - role: newrelic diff --git a/newsyslog/README.md b/newsyslog/README.md deleted file mode 100644 index 2b974979..00000000 --- a/newsyslog/README.md +++ /dev/null @@ -1,5 +0,0 @@ -Role Name -========= - -Configure newsyslog by Evolix standard - diff --git a/newsyslog/files/newsyslog.conf b/newsyslog/files/newsyslog.conf deleted file mode 100644 index 5b51ebc8..00000000 --- a/newsyslog/files/newsyslog.conf +++ /dev/null @@ -1,15 +0,0 @@ -# Syslog for Pack Evolix -# MANAGED BY ANSIBLE, MODIFICATIONS WILL BE LOST -# logfile_name owner:group mode count size when flags -/var/cron/log root:wheel 600 52 * 168 Z -/var/log/authlog root:wheel 640 52 * 168 Z -/var/log/daemon 640 52 * 168 Z -/var/log/lpd-errs 640 7 * 24 Z -/var/log/maillog 640 52 * 168 Z -/var/log/messages 644 52 * 168 Z -/var/log/secure 600 52 * 168 Z -/var/log/wtmp 644 7 * $W6D4 ZB -/var/log/xferlog 640 7 250 * Z -/var/log/pflog 600 3 250 * ZB "pkill -HUP -u root -U root -t - -x pflogd" -/var/www/logs/access.log 644 4 * $W0 Z "pkill -USR1 -u root -U root -x httpd" -/var/www/logs/error.log 644 7 250 * Z "pkill -USR1 -u root -U root -x httpd" diff --git a/newsyslog/meta/main.yml b/newsyslog/meta/main.yml deleted file mode 100644 index a6ad9ab5..00000000 --- a/newsyslog/meta/main.yml +++ /dev/null @@ -1,15 +0,0 @@ -galaxy_info: - author: Evolix - description: Basic configuration of newsyslog - - issue_tracker_url: https://forge.evolix.org/projects/ansible-roles/issues - - license: GPLv2 - - min_ansible_version: 2.2 - - platforms: - - name: OpenBSD - versions: - - 6.1 - diff --git a/newsyslog/tasks/main.yml b/newsyslog/tasks/main.yml deleted file mode 100644 index a7ecf987..00000000 --- a/newsyslog/tasks/main.yml +++ /dev/null @@ -1,7 +0,0 @@ ---- - -#- include: debian.yml -# when: ansible_os_family == "Debian" - -- include: openbsd.yml - when: ansible_os_family == "OpenBSD" diff --git a/newsyslog/tasks/openbsd.yml b/newsyslog/tasks/openbsd.yml deleted file mode 100644 index 97926869..00000000 --- a/newsyslog/tasks/openbsd.yml +++ /dev/null @@ -1,13 +0,0 @@ ---- -# no need to enable any daemon, it's run (by default) with cron(8) -- name: Configuring newsyslog - copy: - src: newsyslog.conf - dest: /etc/newsyslog.conf - owner: root - group: wheel - mode: "0644" - backup: yes - tags: - - log - - newsyslog diff --git a/nginx-backports-preferences/.kitchen.yml b/nginx-backports-preferences/.kitchen.yml deleted file mode 100644 index b21cc3db..00000000 --- a/nginx-backports-preferences/.kitchen.yml +++ /dev/null @@ -1,28 +0,0 @@ ---- -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 - -suites: - - name: default - provisioner: - name: ansible_playbook - playbook: ./tests/test.yml - -transport: - max_ssh_sessions: 6 diff --git a/nginx-backports-preferences/README.md b/nginx-backports-preferences/README.md deleted file mode 100644 index 23f7000c..00000000 --- a/nginx-backports-preferences/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# nginx-backports-preferences - -Configure APT to prefer nginx package from jessie-backports. - -There is no variable, just a files copied to `/etc/apt/preferences.d/`. diff --git a/nginx-backports-preferences/handlers/main.yml b/nginx-backports-preferences/handlers/main.yml deleted file mode 100644 index e68f5c28..00000000 --- a/nginx-backports-preferences/handlers/main.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -- name: apt update - apt: - update_cache: yes diff --git a/nginx-backports-preferences/meta/main.yml b/nginx-backports-preferences/meta/main.yml deleted file mode 100644 index 34235bde..00000000 --- a/nginx-backports-preferences/meta/main.yml +++ /dev/null @@ -1,19 +0,0 @@ -galaxy_info: - author: Evolix - description: Configure APT to prefer Nginx package from jessie-backports - - issue_tracker_url: https://forge.evolix.org/projects/ansible-roles/issues - - license: GPLv2 - - min_ansible_version: 2.2 - - platforms: - - name: Debian - versions: - - jessie - -dependencies: [] - # List your role dependencies here, one per line. - # Be sure to remove the '[]' above if you add dependencies - # to this list. diff --git a/nginx-backports-preferences/tasks/main.yml b/nginx-backports-preferences/tasks/main.yml deleted file mode 100644 index 8184b317..00000000 --- a/nginx-backports-preferences/tasks/main.yml +++ /dev/null @@ -1,10 +0,0 @@ ---- -- name: Prefer Nginx package from jessie-backports - copy: - src: nginx_preferences - dest: /etc/apt/preferences.d/999-nginx - force: yes - mode: "0640" - notify: apt update - -- meta: flush_handlers diff --git a/nginx-backports-preferences/tests/test.yml b/nginx-backports-preferences/tests/test.yml deleted file mode 100644 index a4b0c2fd..00000000 --- a/nginx-backports-preferences/tests/test.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -- hosts: test-kitchen - roles: - - role: nginx-backports-preferences diff --git a/nginx-light/README.md b/nginx-light/README.md deleted file mode 100644 index 17d20719..00000000 --- a/nginx-light/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# nginx-light - -Install Nginx light with a simply default vhost config. - -Used for hypervisors and backups servers. - -## Tasks - -Everything is in the `tasks/main.yml` file. diff --git a/nginx-light/handlers/main.yml b/nginx-light/handlers/main.yml deleted file mode 100644 index d4e42ca0..00000000 --- a/nginx-light/handlers/main.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -- name: reload nginx - service: - name: nginx - state: reloaded diff --git a/nginx-light/tests/spec/nginx_light_spec.rb b/nginx-light/tests/spec/nginx_light_spec.rb deleted file mode 100644 index f7818739..00000000 --- a/nginx-light/tests/spec/nginx_light_spec.rb +++ /dev/null @@ -1,9 +0,0 @@ -require 'net/http' -require 'uri' - -require 'serverspec' -set :backend, :exec - -describe port(80) do - it { should be_listening } -end diff --git a/nginx-light/tests/test.yml b/nginx-light/tests/test.yml deleted file mode 100644 index 01e20fec..00000000 --- a/nginx-light/tests/test.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -- hosts: test-kitchen - roles: - - role: nginx-light diff --git a/nginx/README.md b/nginx/README.md index c724a0cc..d519608b 100644 --- a/nginx/README.md +++ b/nginx/README.md @@ -6,10 +6,18 @@ Install Nginx. Everything is in the `tasks/main.yml` file. +There are 2 modes : minimal and regular. + +The minimal mode is for servers without real web apps, and only access to munin graphs… + +The regular mode is for full fledged web services with optimized defaults. + ## Available variables Main variables are : +* `nginx_minimal` : very basic install and config (default: `False`) ; +* `nginx_jessie_backports` : on Debian Jessie, we can prefer v1.10 from backports (default: `False`) ; * `nginx_private_ipaddr_whitelist_present` : list of IP addresses to have in the private whitelist ; * `nginx_private_ipaddr_whitelist_absent` : list of IP addresses **not** to have in the whitelist ; * `nginx_private_htpasswd_present` : list of users to have in the private htpasswd ; diff --git a/nginx/defaults/main.yml b/nginx/defaults/main.yml index bff60300..16398ee4 100644 --- a/nginx/defaults/main.yml +++ b/nginx/defaults/main.yml @@ -1,6 +1,16 @@ --- + +nginx_minimal: False +nginx_jessie_backports: False + nginx_private_ipaddr_whitelist_present: [] nginx_private_ipaddr_whitelist_absent: [] nginx_private_htpasswd_present: [] nginx_private_htpasswd_absent: [] + +nginx_default_redirect_url: "http://evolix.fr" +nginx_evolinux_default_enabled: True + +# nginx_phpmyadmin_suffix: "" +# nginx_serverstatus_suffix: "" diff --git a/nginx-backports-preferences/files/nginx_preferences b/nginx/files/apt/nginx_preferences similarity index 57% rename from nginx-backports-preferences/files/nginx_preferences rename to nginx/files/apt/nginx_preferences index 5ff68c38..e8f693bd 100644 --- a/nginx-backports-preferences/files/nginx_preferences +++ b/nginx/files/apt/nginx_preferences @@ -1,3 +1,3 @@ -Package: nginx nginx-common nginx-doc nginx-extras nginx-extras-dbg nginx-full nginx-full-dbg nginx-light nginx-light-dbg libssl1.0.0 +Package: nginx nginx-common nginx-doc nginx-extras nginx-extras-dbg nginx-full nginx-full-dbg nginx-light nginx-light-dbg libnginx-mod-* libssl1.0.0 Pin: release a=jessie-backports Pin-Priority: 999 diff --git a/nginx/tasks/main.yml b/nginx/tasks/main.yml index caffaad1..e1144a39 100644 --- a/nginx/tasks/main.yml +++ b/nginx/tasks/main.yml @@ -1,141 +1,7 @@ --- -- name: Ensure Nginx is installed - apt: - name: nginx-full - state: present - notify: restart nginx - tags: - - nginx - - packages -# TODO: find a way to override the main configuration -# without touching the main file +- include: main_minimal.yml + when: nginx_minimal -- name: customize worker_connections - lineinfile: - dest: /etc/nginx/nginx.conf - regexp: '^(\s*worker_connections)\s+.+;' - line: ' worker_connections 1024;' - insertafter: 'events \{' - tags: - - nginx - -- name: use epoll - lineinfile: - dest: /etc/nginx/nginx.conf - regexp: '^(\s*use)\s+.+;' - line: ' use epoll;' - insertafter: 'events \{' - tags: - - nginx - -- name: Install Nginx http configuration - copy: - src: nginx/evolinux-defaults.conf - dest: /etc/nginx/conf.d/z-evolinux-defaults.conf - mode: "0640" - # force: yes - notify: reload nginx - tags: - - nginx - -# TODO: verify that those permissions are correct : -# not too strict for private_ipaddr_whitelist -# and not too loose for private_htpasswd - -- name: Copy private_ipaddr_whitelist - copy: - src: nginx/snippets/private_ipaddr_whitelist - dest: /etc/nginx/snippets/private_ipaddr_whitelist - owner: www-data - group: www-data - directory_mode: "0640" - mode: "0640" - force: no - notify: reload nginx - tags: - - nginx - -- name: add IP addresses to private IP whitelist - lineinfile: - dest: /etc/nginx/snippets/private_ipaddr_whitelist - line: "allow {{ item }};" - state: present - with_items: "{{ nginx_private_ipaddr_whitelist_present }}" - notify: reload nginx - tags: - - nginx - -- name: remove IP addresses from private IP whitelist - lineinfile: - dest: /etc/nginx/snippets/private_ipaddr_whitelist - line: "allow {{ item }};" - state: absent - with_items: "{{ nginx_private_ipaddr_whitelist_absent }}" - notify: reload nginx - tags: - - nginx - -- name: Copy private_htpasswd - copy: - src: nginx/snippets/private_htpasswd - dest: /etc/nginx/snippets/private_htpasswd - owner: www-data - group: www-data - directory_mode: "0640" - mode: "0640" - force: no - notify: reload nginx - tags: - - nginx - -- name: add user:pwd to private htpasswd - lineinfile: - dest: /etc/nginx/snippets/private_htpasswd - line: "{{ item }}" - state: present - with_items: "{{ nginx_private_htpasswd_present }}" - notify: reload nginx - tags: - - nginx - -- name: remove user:pwd from private htpasswd - lineinfile: - dest: /etc/nginx/snippets/private_htpasswd - line: "{{ item }}" - state: absent - with_items: "{{ nginx_private_htpasswd_absent }}" - notify: reload nginx - tags: - - nginx - -- name: Verify that the service is enabled and started - service: - name: nginx - enabled: yes - state: started - tags: - - nginx - -- name: Check if Munin is installed - stat: - path: /etc/munin/plugin-conf.d/munin-node - check_mode: no - register: stat_munin_node - tags: - - nginx - - munin - -- include: munin_vhost.yml - when: stat_munin_node.stat.exists - tags: - - nginx - - munin - -- include: munin_graphs.yml - when: stat_munin_node.stat.exists - tags: - - nginx - - munin - -- include: logrotate.yml +- include: main_regular.yml + when: not nginx_minimal diff --git a/nginx-light/tasks/main.yml b/nginx/tasks/main_minimal.yml similarity index 71% rename from nginx-light/tasks/main.yml rename to nginx/tasks/main_minimal.yml index cc727f28..281aed7f 100644 --- a/nginx-light/tasks/main.yml +++ b/nginx/tasks/main_minimal.yml @@ -1,5 +1,5 @@ --- -- name: Ensure Nginx (light) is installed +- name: Ensure Nginx is installed apt: name: "{{ item }}" state: present @@ -13,8 +13,8 @@ - name: Copy default vhost template: - src: default.j2 - dest: /etc/nginx/sites-available/default + src: evolinux-default.minimal.conf.j2 + dest: /etc/nginx/sites-available/evolinux-default.minimal.conf mode: 0644 notify: reload nginx tags: @@ -23,7 +23,7 @@ - name: Enable default vhost file: - src: /etc/nginx/sites-available/default + src: /etc/nginx/sites-available/evolinux-default.minimal.conf dest: /etc/nginx/sites-enabled/default state: link notify: reload nginx diff --git a/nginx/tasks/main_regular.yml b/nginx/tasks/main_regular.yml new file mode 100644 index 00000000..74580972 --- /dev/null +++ b/nginx/tasks/main_regular.yml @@ -0,0 +1,193 @@ +--- + +- include: packages_jessie.yml + when: ansible_distribution_release == "jessie" + +- include: packages_stretch.yml + when: ansible_distribution_major_version | version_compare('9', '>=') + +# TODO: find a way to override the main configuration +# without touching the main file + +- name: customize worker_connections + lineinfile: + dest: /etc/nginx/nginx.conf + regexp: '^(\s*worker_connections)\s+.+;' + line: ' worker_connections 1024;' + insertafter: 'events \{' + tags: + - nginx + +- name: use epoll + lineinfile: + dest: /etc/nginx/nginx.conf + regexp: '^(\s*use)\s+.+;' + line: ' use epoll;' + insertafter: 'events \{' + tags: + - nginx + +- name: Install Nginx http configuration + copy: + src: nginx/evolinux-defaults.conf + dest: /etc/nginx/conf.d/z-evolinux-defaults.conf + mode: "0640" + # force: yes + notify: reload nginx + tags: + - nginx + +# TODO: verify that those permissions are correct : +# not too strict for private_ipaddr_whitelist +# and not too loose for private_htpasswd + +- name: Copy private_ipaddr_whitelist + copy: + src: nginx/snippets/private_ipaddr_whitelist + dest: /etc/nginx/snippets/private_ipaddr_whitelist + owner: www-data + group: www-data + directory_mode: "0640" + mode: "0640" + force: no + notify: reload nginx + tags: + - nginx + +- name: add IP addresses to private IP whitelist + lineinfile: + dest: /etc/nginx/snippets/private_ipaddr_whitelist + line: "allow {{ item }};" + state: present + with_items: "{{ nginx_private_ipaddr_whitelist_present }}" + notify: reload nginx + tags: + - nginx + +- name: remove IP addresses from private IP whitelist + lineinfile: + dest: /etc/nginx/snippets/private_ipaddr_whitelist + line: "allow {{ item }};" + state: absent + with_items: "{{ nginx_private_ipaddr_whitelist_absent }}" + notify: reload nginx + tags: + - nginx + +- name: Copy private_htpasswd + copy: + src: nginx/snippets/private_htpasswd + dest: /etc/nginx/snippets/private_htpasswd + owner: www-data + group: www-data + directory_mode: "0640" + mode: "0640" + force: no + notify: reload nginx + tags: + - nginx + +- name: add user:pwd to private htpasswd + lineinfile: + dest: /etc/nginx/snippets/private_htpasswd + line: "{{ item }}" + state: present + with_items: "{{ nginx_private_htpasswd_present }}" + notify: reload nginx + tags: + - nginx + +- name: remove user:pwd from private htpasswd + lineinfile: + dest: /etc/nginx/snippets/private_htpasswd + line: "{{ item }}" + state: absent + with_items: "{{ nginx_private_htpasswd_absent }}" + notify: reload nginx + tags: + - nginx + +- name: nginx vhost is installed + template: + src: evolinux-default.conf.j2 + dest: /etc/nginx/sites-available/evolinux-default.conf + mode: "0640" + notify: reload nginx + tags: + - nginx + +- name: default vhost is enabled + file: + src: /etc/nginx/sites-available/evolinux-default.conf + dest: /etc/nginx/sites-enabled/default + state: link + force: yes + notify: reload nginx + when: nginx_evolinux_default_enabled + tags: + - nginx + +# - block: +# - name: generate random string for phpmyadmin suffix +# command: "apg -a 1 -M N -n 1" +# changed_when: False +# register: random_phpmyadmin_suffix +# +# - name: overwrite nginx_phpmyadmin_suffix +# set_fact: +# nginx_phpmyadmin_suffix: "{{ random_phpmyadmin_suffix.stdout }}" +# when: nginx_phpmyadmin_suffix == "" +# +# - name: replace phpmyadmin suffix in default site index +# replace: +# dest: /var/www/index.html +# regexp: '__PHPMYADMIN_SUFFIX__' +# replace: "{{ nginx_phpmyadmin_suffix }}" +# +# - block: +# - name: generate random string for serverstatus suffix +# command: "apg -a 1 -M N -n 1" +# changed_when: False +# register: random_serverstatus_suffix +# +# - name: overwrite nginx_serverstatus_suffix +# set_fact: +# nginx_serverstatus_suffix: "{{ random_phpmyadmin_suffix.stdout }}" +# when: nginx_serverstatus_suffix == "" +# +# - name: replace server-status suffix in default site index +# replace: +# dest: /var/www/index.html +# regexp: '__SERVERSTATUS_SUFFIX__' +# replace: "{{ nginx_serverstatus_suffix }}" + +- name: Verify that the service is enabled and started + service: + name: nginx + enabled: yes + state: started + tags: + - nginx + +- name: Check if Munin is installed + stat: + path: /etc/munin/plugin-conf.d/munin-node + check_mode: no + register: stat_munin_node + tags: + - nginx + - munin + +- include: munin_vhost.yml + when: stat_munin_node.stat.exists + tags: + - nginx + - munin + +- include: munin_graphs.yml + when: stat_munin_node.stat.exists + tags: + - nginx + - munin + +- include: logrotate.yml diff --git a/nginx/tasks/packages_jessie.yml b/nginx/tasks/packages_jessie.yml new file mode 100644 index 00000000..ce806ba2 --- /dev/null +++ b/nginx/tasks/packages_jessie.yml @@ -0,0 +1,11 @@ +- include: packages_jessie_backports.yml + when: ansible_distribution_release == "jessie" and nginx_jessie_backports + +- name: Ensure Nginx is installed + apt: + name: nginx-full + state: present + notify: restart nginx + tags: + - nginx + - packages diff --git a/nginx/tasks/packages_jessie_backports.yml b/nginx/tasks/packages_jessie_backports.yml new file mode 100644 index 00000000..b9c1eaf9 --- /dev/null +++ b/nginx/tasks/packages_jessie_backports.yml @@ -0,0 +1,27 @@ +--- + +- include_role: + name: apt + tasks_from: backports.yml + tags: + - nginx + - packages + +- name: Prefer Nginx packages from jessie-backports + copy: + src: apt/nginx_preferences + dest: /etc/apt/preferences.d/999-nginx + force: yes + mode: "0640" + register: nginx_apt_preferences + tags: + - nginx + - packages + +- name: update apt + apt: + update_cache: yes + when: nginx_apt_preferences | changed + tags: + - nginx + - packages diff --git a/nginx/tasks/packages_stretch.yml b/nginx/tasks/packages_stretch.yml new file mode 100644 index 00000000..637cb044 --- /dev/null +++ b/nginx/tasks/packages_stretch.yml @@ -0,0 +1,11 @@ +--- +# TODO: install "nginx" + only necessary modules, instead of "nginx-full" + +- name: Ensure Nginx is installed + apt: + name: nginx-full + state: present + notify: restart nginx + tags: + - nginx + - packages diff --git a/evolinux-base/templates/default_www/nginx_default_site.j2 b/nginx/templates/evolinux-default.conf.j2 similarity index 93% rename from evolinux-base/templates/default_www/nginx_default_site.j2 rename to nginx/templates/evolinux-default.conf.j2 index 803ff4ad..165f39f8 100644 --- a/evolinux-base/templates/default_www/nginx_default_site.j2 +++ b/nginx/templates/evolinux-default.conf.j2 @@ -7,7 +7,7 @@ server { } server { - listen 443 ssl spdy; + listen 443 ssl; # listen [::]:80 default_server ipv6only=on; ## listen for ipv6 ssl_certificate /etc/ssl/certs/{{ ansible_fqdn }}.crt; @@ -18,7 +18,7 @@ server { access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; - error_page 403 {{ evolinux_default_www_redirect_url }}; + error_page 403 {{ nginx_default_redirect_url }}; root /var/www; diff --git a/nginx-light/templates/default.j2 b/nginx/templates/evolinux-default.minimal.conf.j2 similarity index 100% rename from nginx-light/templates/default.j2 rename to nginx/templates/evolinux-default.minimal.conf.j2 diff --git a/nodejs/files/nodesource.gpg.key b/nodejs/files/nodesource.gpg.key new file mode 100644 index 00000000..1dc1d101 --- /dev/null +++ b/nodejs/files/nodesource.gpg.key @@ -0,0 +1,52 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1 +Comment: GPGTools - https://gpgtools.org + +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 +=CLGF +-----END PGP PUBLIC KEY BLOCK----- diff --git a/nodejs/tasks/main.yml b/nodejs/tasks/main.yml index 31e6bd0a..bd276dc7 100644 --- a/nodejs/tasks/main.yml +++ b/nodejs/tasks/main.yml @@ -11,8 +11,8 @@ - name: Node GPG key is installed apt_key: - url: https://deb.nodesource.com/gpgkey/nodesource.gpg.key - state: present + #url: https://deb.nodesource.com/gpgkey/nodesource.gpg.key + data: "{{ lookup('file', 'nodesource.gpg.key') }}" tags: - system - packages diff --git a/ntp/defaults/main.yml b/ntpd/defaults/main.yml similarity index 80% rename from ntp/defaults/main.yml rename to ntpd/defaults/main.yml index c48a2dd4..61a0846f 100644 --- a/ntp/defaults/main.yml +++ b/ntpd/defaults/main.yml @@ -1,6 +1,6 @@ --- ntpd_servers: -- 'pool.ntp.org' +- 'ntp.evolix.net' ntpd_acls: - '127.0.0.1' - '::1' diff --git a/ntp/handlers/main.yml b/ntpd/handlers/main.yml similarity index 100% rename from ntp/handlers/main.yml rename to ntpd/handlers/main.yml diff --git a/ntp/tasks/main.yml b/ntpd/tasks/main.yml similarity index 100% rename from ntp/tasks/main.yml rename to ntpd/tasks/main.yml diff --git a/ntp/templates/ntp.conf.j2 b/ntpd/templates/ntp.conf.j2 similarity index 99% rename from ntp/templates/ntp.conf.j2 rename to ntpd/templates/ntp.conf.j2 index e004ec6a..e57dad33 100644 --- a/ntp/templates/ntp.conf.j2 +++ b/ntpd/templates/ntp.conf.j2 @@ -18,7 +18,6 @@ filegen clockstats file clockstats type day enable # pool: #server pool.ntp.org - {% for server in ntpd_servers %} server {{ server }} {% endfor %} diff --git a/packweb-apache/README.md b/packweb-apache/README.md index a8bae5f0..d3f3f5b6 100644 --- a/packweb-apache/README.md +++ b/packweb-apache/README.md @@ -10,6 +10,6 @@ Everything is in the `tasks/main.yml` file for now. Main variables are : -* `log2mail_alert_email`: email address to send Log2mail messages to (default: `general_alert_email`). +* `packweb_enable_evoadmin_vhost` : enable VirtualHost for evoadmin (web interface to create web accounts) The full list of variables (with default values) can be found in `defaults/main.yml`. diff --git a/packweb-apache/defaults/main.yml b/packweb-apache/defaults/main.yml index 0301183f..8282d081 100644 --- a/packweb-apache/defaults/main.yml +++ b/packweb-apache/defaults/main.yml @@ -1,5 +1,10 @@ --- # defaults file for packweb-apache general_alert_email: "root@localhost" -log2mail_alert_email: Null + packweb_enable_evoadmin_vhost: True +packweb_fhs_retrictions: True +packweb_apache_modphp: True +packweb_apache_fpm: False + +packweb_phpmyadmin_suffix: "" diff --git a/packweb-apache/files/evolinux-itk.conf b/packweb-apache/files/evolinux-itk.conf deleted file mode 100644 index 4e25d84b..00000000 --- a/packweb-apache/files/evolinux-itk.conf +++ /dev/null @@ -1,10 +0,0 @@ - -StartServers 50 -MinSpareServers 20 -MaxSpareServers 30 -ServerLimit 250 -MaxClients 250 -MaxRequestsPerChild 0 -LimitUIDRange 0 6000 -LimitGIDRange 0 6000 - diff --git a/packweb-apache/files/info.php b/packweb-apache/files/info.php new file mode 100644 index 00000000..cf608608 --- /dev/null +++ b/packweb-apache/files/info.php @@ -0,0 +1,3 @@ + diff --git a/packweb-apache/files/userlogrotate b/packweb-apache/files/userlogrotate index 339101a9..9d45af6a 100644 --- a/packweb-apache/files/userlogrotate +++ b/packweb-apache/files/userlogrotate @@ -23,11 +23,6 @@ for log in access.log access-*.log error.log; do done done -for i in `ls -1 -d $HOMEPREFIX/*/log/php.log 2>/dev/null | grep -v \.bak\.`; do - USER=`user_for $i` - rotate $i www-$USER:$USER -done - for log in production.log delayed_job.log development.log test.log; do for i in `ls -1 -d $HOMEPREFIX/*/www/{,current/}log/$log 2>/dev/null | grep -v \.bak\.`; do USER=`user_for $i` @@ -35,4 +30,8 @@ for log in production.log delayed_job.log development.log test.log; do done done -apache2ctl restart > /dev/null +if /etc/init.d/apache2 status > /dev/null ; then \ + /etc/init.d/apache2 reload > /dev/null; \ +fi; + +test -x /usr/sbin/nginx && invoke-rc.d nginx rotate >/dev/null 2>&1 diff --git a/packweb-apache/files/userlogrotate_jessie b/packweb-apache/files/userlogrotate_jessie new file mode 100644 index 00000000..339101a9 --- /dev/null +++ b/packweb-apache/files/userlogrotate_jessie @@ -0,0 +1,38 @@ +#!/bin/bash + +DATE=`/bin/date +"%d-%m-%Y"` +HOMEPREFIX="/home" + +rotate () { + mv $1 $1.$DATE + gzip $1.$DATE + touch $1 + chown $2 $1 + chmod g+r $1 +} + +user_for() { + homedir=`echo $1 | sed "s#\($HOMEPREFIX/\([^/]\+\)\).*#\1#"` + stat -L -c '%G' $homedir +} + +for log in access.log access-*.log error.log; do + for i in `ls -1 -d $HOMEPREFIX/*/log/$log 2>/dev/null | grep -v \.bak\.`; do + USER=`user_for $i` + rotate $i root:$USER + done +done + +for i in `ls -1 -d $HOMEPREFIX/*/log/php.log 2>/dev/null | grep -v \.bak\.`; do + USER=`user_for $i` + rotate $i www-$USER:$USER +done + +for log in production.log delayed_job.log development.log test.log; do + for i in `ls -1 -d $HOMEPREFIX/*/www/{,current/}log/$log 2>/dev/null | grep -v \.bak\.`; do + USER=`user_for $i` + rotate $i $USER:$USER + done +done + +apache2ctl restart > /dev/null diff --git a/packweb-apache/tasks/apache.yml b/packweb-apache/tasks/apache.yml index 76756d10..31570944 100644 --- a/packweb-apache/tasks/apache.yml +++ b/packweb-apache/tasks/apache.yml @@ -21,47 +21,43 @@ name: '{{ item }}' state: present with_items: - - apache2-mpm-itk - - libapache2-mod-evasive - libapache2-mod-security2 + - modsecurity-crs + - apg + +- name: Additional modules are enabled + apache2_module: + name: '{{ item }}' + state: present + with_items: + - ssl + - include + - negotiation + - alias - name: Copy Apache settings for modules copy: - src: "{{ item }}" - dest: "/etc/apache2/conf-available/{{ item }}" + src: "evolinux-modsec.conf" + dest: "/etc/apache2/conf-available/evolinux-modsec.conf" + owner: root + group: root + mode: "0644" + force: no + +- name: Copy Apache settings for modules + template: + src: "evolinux-evasive.conf.j2" + dest: "/etc/apache2/conf-available/evolinux-evasive.conf" owner: root group: root mode: "0644" force: no - with_items: - - evolinux-itk.conf - - evolinux-evasive.conf - - evolinux-modsec.conf - name: Ensure Apache modules configs are enabled command: "a2enconf {{ item }}" register: command_result changed_when: "'Enabling' in command_result.stderr" with_items: - - evolinux-itk - evolinux-evasive - evolinux-modsec -- name: Check if log2mail is installed - command: "apt list --installed log2mail" - register: command_result - changed_when: False - -- debug: - var: command_result - verbosity: 1 - -- name: Add log2mail config for Apache segfaults - template: - src: log2mail-apache.j2 - dest: "/etc/log2mail/config/apache" - owner: root - group: root - mode: "0644" - force: no - when: "'log2mail' in command_result.stdout" diff --git a/packweb-apache/tasks/fhs_retrictions.yml b/packweb-apache/tasks/fhs_retrictions.yml new file mode 100644 index 00000000..2308db2a --- /dev/null +++ b/packweb-apache/tasks/fhs_retrictions.yml @@ -0,0 +1,68 @@ +--- + +- name: Remove read permission on some folders (/, /etc, ...) + shell: "test -d {{ item }} && chmod --verbose o-r {{ item }}" + register: command_result + changed_when: "'changed' in command_result.stdout" + failed_when: False + with_items: + - / + - /etc + - /usr + - /usr/bin + - /var + - /var/log + - /home + - /bin + - /sbin + - /lib + - /usr/lib + - /usr/include + - /usr/bin + - /usr/sbin + - /usr/share + - /usr/share/doc + - /etc/default + +- name: Set 750 permission on some folders (/var/log/apt, /var/log/munin, ...) + shell: "test -d {{ item }} && chmod --verbose 750 {{ item }}" + register: command_result + changed_when: "'changed' in command_result.stdout" + failed_when: False + with_items: + - /var/log/apt + - /var/lib/dpkg + - /var/log/munin + - /var/backups + - /etc/init.d + - /etc/apache2 + - /etc/network + - /etc/phpmyadmin + - /var/log/installer + +- name: Change group to www-data for /etc/phpmyadmin/ + file: + dest: /etc/phpmyadmin/ + group: www-data + +- name: Set u-s permission on some binaries (/bin/ping, /usr/bin/mtr, ...) + shell: "test -f {{ item }} && chmod --verbose u-s {{ item }}" + register: command_result + changed_when: "'changed' in command_result.stdout" + failed_when: False + with_items: + - /bin/ping + - /bin/ping6 + - /usr/bin/fping + - /usr/bin/fping6 + - /usr/bin/mtr + +- name: Set 640 permission on some files (/var/log/evolix.log, ...) + shell: "test -f {{ item }} && chmod --verbose 640 {{ item }}" + register: command_result + changed_when: "'changed' in command_result.stdout" + failed_when: False + with_items: + - /var/log/evolix.log + - /etc/warnquota.conf + diff --git a/packweb-apache/tasks/main.yml b/packweb-apache/tasks/main.yml index 8aa0f26c..2e835b24 100644 --- a/packweb-apache/tasks/main.yml +++ b/packweb-apache/tasks/main.yml @@ -1,8 +1,39 @@ --- +- fail: + msg: only compatible with Debian >= 8 + when: + - ansible_distribution != "Debian" or ansible_distribution_major_version | version_compare('8', '<') + - name: Include apache role include_role: - name: "apache" + name: apache + +- name: Include PHP role + include_role: + name: php + vars: + php_apache_enable: True + when: packweb_apache_modphp + +- name: Include PHP role + include_role: + name: php + vars: + php_fpm_enable: True + when: packweb_apache_fpm + +- name: install info.php + copy: + src: info.php + dest: /var/www/info.php + mode: "0644" + +- name: enable info.php link in default site index + lineinfile: + dest: /var/www/index.html + line: '
  • Infos PHP
  • ' + regexp: "Infos PHP" - name: Add elements to user account template file: @@ -24,11 +55,19 @@ - access.log - error.log -- name: Install userlogrotate +- name: "Install userlogrotate (jessie)" + copy: + src: userlogrotate_jessie + dest: /etc/cron.weekly/userlogrotate + mode: "0755" + when: ansible_distribution_release == "jessie" + +- name: "Install userlogrotate (Debian 9 or later)" copy: src: userlogrotate dest: /etc/cron.weekly/userlogrotate mode: "0755" + when: ansible_distribution_major_version | version_compare('9', '>=') - name: Force DIR_MODE to 0750 in /etc/adduser.conf lineinfile: @@ -38,86 +77,16 @@ - include: apache.yml -- include: php.yml - - include: phpmyadmin.yml - include: awstats.yml -- name: Remove read permission on some folders (/, /etc, ...) - shell: "test -d {{ item }} && chmod --verbose o-r {{ item }}" - register: command_result - changed_when: "'changed' in command_result.stdout" - failed_when: False - with_items: - - / - - /etc - - /usr - - /usr/bin - - /var - - /var/log - - /home - - /bin - - /sbin - - /lib - - /usr/lib - - /usr/include - - /usr/bin - - /usr/sbin - - /usr/share - - /usr/share/doc - - /etc/default - -- name: Set 750 permission on some folders (/var/log/apt, /var/log/munin, ...) - shell: "test -d {{ item }} && chmod --verbose 750 {{ item }}" - register: command_result - changed_when: "'changed' in command_result.stdout" - failed_when: False - with_items: - - /var/log/apt - - /var/lib/dpkg - - /var/log/munin - - /var/backups - - /var/cache/apt - - /etc/init.d - - /etc/apt - - /etc/apache2 - - /etc/network - - /etc/phpmyadmin - - /var/log/installer - -- name: Set u-s permission on some binaries (/bin/ping, /usr/bin/mtr, ...) - shell: "test -f {{ item }} && chmod --verbose u-s {{ item }}" - register: command_result - changed_when: "'changed' in command_result.stdout" - failed_when: False - with_items: - - /bin/ping - - /bin/ping6 - - /usr/bin/fping - - /usr/bin/fping6 - - /usr/bin/mtr - -- name: Set 640 permission on some files (/var/log/evolix.log, ...) - shell: "test -f {{ item }} && chmod --verbose 640 {{ item }}" - register: command_result - changed_when: "'changed' in command_result.stdout" - failed_when: False - with_items: - - /var/log/evolix.log - - /etc/warnquota.conf - -- name: Remove some log files (/var/log/mail.err, ...) - file: - path: "{{ item }}" - state: absent - with_items: - - /var/log/debug - - /var/log/mail.err - - /var/log/mail.warn +- include: fhs_retrictions.yml + when: packweb_fhs_retrictions - name: Install Evoadmin include_role: - name: evoadmin + name: webapps/evoadmin-web vars: evoadmin_enable_vhost: "{{ packweb_enable_evoadmin_vhost }}" + diff --git a/packweb-apache/tasks/php.yml b/packweb-apache/tasks/php.yml deleted file mode 100644 index ee65fd2f..00000000 --- a/packweb-apache/tasks/php.yml +++ /dev/null @@ -1,64 +0,0 @@ ---- - -- name: Install PHP5 packages - apt: - name: '{{ item }}' - state: present - with_items: - - libapache2-mod-php5 - - php5 - - php5-gd - - php5-imap - - php5-ldap - - php5-mcrypt - - php5-mysql - - php5-pgsql - - php-gettext - - php5-curl - - libssh2-php - tags: - - apache - -- name: Set variables for php config files - set_fact: - php5_apache5_defaults_file: /etc/php5/apache2/conf.d/z-evolinux_defaults.ini - php5_apache5_custom_file: /etc/php5/apache2/conf.d/zzz-evolinux_custom.ini - -- name: Set default values for PHP - ini_file: - dest: "{{ php5_apache5_defaults_file }}" - section: PHP - option: "{{ item.option }}" - value: "{{ item.value }}" - mode: "0644" - create: yes - with_items: - - { option: "short_open_tag", value: "Off" } - - { option: "expose_php", value: "Off" } - - { option: "display_errors", value: "Off" } - - { option: "log_errors", value: "On" } - - { option: "allow_url_fopen", value: "Off" } - notify: reload apache - -- name: Disable PHP exec function without evoadmin - ini_file: - dest: "{{ php5_apache5_defaults_file }}" - section: PHP - option: disable_functions - value: "exec,shell-exec,system,passthru,putenv,popen" - when: not packweb_enable_evoadmin_vhost - -- name: Don't disable PHP exec function with evoadmin - ini_file: - dest: "{{ php5_apache5_defaults_file }}" - section: PHP - option: disable_functions - value: "shell-exec,system,passthru,putenv,popen" - when: packweb_enable_evoadmin_vhost - -- name: Custom php.ini - copy: - dest: "{{ php5_apache5_custom_file }}" - content: | - # Put customized values here. - force: no diff --git a/packweb-apache/tasks/phpmyadmin.yml b/packweb-apache/tasks/phpmyadmin.yml index cc34067e..1e14be7e 100644 --- a/packweb-apache/tasks/phpmyadmin.yml +++ b/packweb-apache/tasks/phpmyadmin.yml @@ -2,8 +2,11 @@ - name: Install phpmyadmin apt: - name: phpmyadmin + name: '{{ item }}' state: present + with_items: + - phpmyadmin + - apg - name: Check if phpmyadmin default configuration is present stat: @@ -20,7 +23,37 @@ changed_when: "'Disabling' in command_result.stderr" when: pma_default_config.stat.exists -- name: Change group to www-data for /etc/phpmyadmin/ - file: - dest: /etc/phpmyadmin/ - group: www-data +- name: generate random string for phpmyadmin suffix + command: "apg -a 1 -M N -n 1" + changed_when: False + register: _random_phpmyadmin_suffix + +- name: overwrite packweb_phpmyadmin_suffix + set_fact: + packweb_phpmyadmin_suffix: "{{ _random_phpmyadmin_suffix.stdout }}" + when: packweb_phpmyadmin_suffix == "" + +- name: enable phpMyAdmin config + blockinfile: + dest: /etc/apache2/sites-available/000-evolinux-default.conf + marker: "# {mark} phpMyAdmin section" + block: | + Alias /phpmyadmin /var/www + Alias /phpmyadmin-{{ packweb_phpmyadmin_suffix }} /usr/share/phpmyadmin/ + Include /etc/phpmyadmin/apache.conf + + Require all denied + Include /etc/apache2/ipaddr_whitelist.conf + + +- name: enable phpmyadmin link in default site index + replace: + dest: /var/www/index.html + regexp: '' + replace: '
  • Accès PhpMyAdmin
  • ' + +- name: replace phpmyadmin suffix in default site index + replace: + dest: /var/www/index.html + regexp: '__PHPMYADMIN_SUFFIX__' + replace: "{{ packweb_phpmyadmin_suffix }}" diff --git a/packweb-apache/tasks/web-add.yml b/packweb-apache/tasks/web-add.yml deleted file mode 100644 index 60bc20a8..00000000 --- a/packweb-apache/tasks/web-add.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- - -# TODO: ... diff --git a/packweb-apache/files/evolinux-evasive.conf b/packweb-apache/templates/evolinux-evasive.conf.j2 similarity index 79% rename from packweb-apache/files/evolinux-evasive.conf rename to packweb-apache/templates/evolinux-evasive.conf.j2 index 15be182f..fd73ad81 100644 --- a/packweb-apache/files/evolinux-evasive.conf +++ b/packweb-apache/templates/evolinux-evasive.conf.j2 @@ -5,4 +5,5 @@ DOSSiteCount 30 DOSPageInterval 3 DOSSiteInterval 1 DOSBlockingPeriod 60 +DOSEmailNotify {{ general_alert_email }} diff --git a/php-fpm/.kitchen.yml b/php-fpm/.kitchen.yml deleted file mode 100644 index b21cc3db..00000000 --- a/php-fpm/.kitchen.yml +++ /dev/null @@ -1,28 +0,0 @@ ---- -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 - -suites: - - name: default - provisioner: - name: ansible_playbook - playbook: ./tests/test.yml - -transport: - max_ssh_sessions: 6 diff --git a/php-fpm/README.md b/php-fpm/README.md deleted file mode 100644 index bac322fe..00000000 --- a/php-fpm/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# PHP-FPM - -Installation and basic configuration of php-fpm - -## 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`. diff --git a/php-fpm/defaults/main.yml b/php-fpm/defaults/main.yml deleted file mode 100644 index ed97d539..00000000 --- a/php-fpm/defaults/main.yml +++ /dev/null @@ -1 +0,0 @@ ---- diff --git a/php-fpm/tasks/main.yml b/php-fpm/tasks/main.yml deleted file mode 100644 index 3131af3b..00000000 --- a/php-fpm/tasks/main.yml +++ /dev/null @@ -1,4 +0,0 @@ -- name: ensure packages are installed - apt: - name: php5-fpm - state: present diff --git a/dhcp/.kitchen.yml b/php/.kitchen.yml similarity index 100% rename from dhcp/.kitchen.yml rename to php/.kitchen.yml diff --git a/clamav/README.md b/php/README.md similarity index 75% rename from clamav/README.md rename to php/README.md index ba5fe895..e0a194ac 100644 --- a/clamav/README.md +++ b/php/README.md @@ -1,6 +1,6 @@ -# Clamav +# PHP -Installation and basic configuration of clamav +Installation and basic configuration of PHP ## Tasks diff --git a/php/defaults/main.yml b/php/defaults/main.yml new file mode 100644 index 00000000..ca243024 --- /dev/null +++ b/php/defaults/main.yml @@ -0,0 +1,5 @@ +--- + +php_fpm_enable: False +php_apache_enable: False +php_symfony_requirements: False diff --git a/php-fpm/handlers/main.yml b/php/handlers/main.yml similarity index 100% rename from php-fpm/handlers/main.yml rename to php/handlers/main.yml diff --git a/php-fpm/meta/main.yml b/php/meta/main.yml similarity index 100% rename from php-fpm/meta/main.yml rename to php/meta/main.yml diff --git a/php/tasks/apache.yml b/php/tasks/apache.yml new file mode 100644 index 00000000..df352848 --- /dev/null +++ b/php/tasks/apache.yml @@ -0,0 +1,73 @@ +--- + +- name: "Install mod_php packages (jessie)" + apt: + name: '{{ item }}' + state: present + with_items: + - libapache2-mod-php5 + - php5 + when: ansible_distribution_release == "jessie" + +- name: "Install mod_php packages (Debian 9 or later)" + apt: + name: '{{ item }}' + state: present + with_items: + - libapache2-mod-php + - php + when: ansible_distribution_major_version | version_compare('9', '>=') + +- name: "Set php.ini config for apache2 (jessie)" + set_fact: + php_apache_defaults_file: /etc/php5/apache2/conf.d/z-evolinux-defaults.ini + php_apache_custom_file: /etc/php5/apache2/conf.d/zzz-evolinux-custom.ini + when: ansible_distribution_release == "jessie" + +- name: "Set php.ini config for apache2 (Debian 9 or later)" + set_fact: + php_apache_defaults_file: /etc/php/7.0/apache2/conf.d/z-evolinux-defaults.ini + php_apache_custom_file: /etc/php/7.0/apache2/conf.d/zzz-evolinux-custom.ini + when: ansible_distribution_major_version | version_compare('9', '>=') + +- name: Set default values for PHP + ini_file: + dest: "{{ php_apache_defaults_file }}" + section: PHP + option: "{{ item.option }}" + value: "{{ item.value }}" + mode: "0644" + create: yes + with_items: + - { option: "short_open_tag", value: "Off" } + - { option: "expose_php", value: "Off" } + - { option: "display_errors", value: "Off" } + - { option: "log_errors", value: "On" } + - { option: "html_errors", value: "Off" } + - { option: "allow_url_fopen", value: "Off" } + +- name: Disable PHP functions + ini_file: + dest: "{{ php_apache_defaults_file }}" + section: PHP + option: disable_functions + value: "exec,shell-exec,system,passthru,putenv,popen" + +- name: Custom php.ini + copy: + dest: "{{ php_apache_custom_file }}" + content: | + ; Put customized values here. + ; default_charset = "ISO-8859-1" + force: no + +- name: "Set custom values for PHP to enable Symfony" + ini_file: + dest: "{{ php_apache_custom_file }}" + section: PHP + option: "{{ item.option }}" + value: "{{ item.value }}" + mode: "0644" + with_items: + - { option: "date.timezone", value: "Europe/Paris" } + when: php_symfony_requirements diff --git a/php/tasks/fpm.yml b/php/tasks/fpm.yml new file mode 100644 index 00000000..06dc4202 --- /dev/null +++ b/php/tasks/fpm.yml @@ -0,0 +1,104 @@ +--- + +- name: "Install PHP FPM packages (jessie)" + apt: + name: '{{ item }}' + state: present + with_items: + - php5-fpm + - php5 + when: ansible_distribution_release == "jessie" + +- name: "Install PHP FPM packages (Debian 9 or later)" + apt: + name: '{{ item }}' + state: present + with_items: + - php-fpm + - php + when: ansible_distribution_major_version | version_compare('9', '>=') + +- name: "Set config files for FPM (jessie)" + set_fact: + phpini_fpm_defaults_file: /etc/php5/fpm/conf.d/z-evolinux-defaults.ini + phpini_fpm_custom_file: /etc/php5/fpm/conf.d/zzz-evolinux-custom.ini + php_fpm_defaults_file: /etc/php5/fpm/pool.d/z-evolinux-defaults.conf + php_fpm_custom_file: /etc/php5/fpm/pool.d/zzz-evolinux-custom.conf + when: ansible_distribution_release == "jessie" + +- name: "Set config files for FPM (Debian 9 or later)" + set_fact: + phpini_fpm_defaults_file: /etc/php/7.0/fpm/conf.d/z-evolinux-defaults.ini + phpini_fpm_custom_file: /etc/php/7.0/fpm/conf.d/zzz-evolinux-custom.ini + php_fpm_defaults_file: /etc/php/7.0/fpm/pool.d/z-evolinux-defaults.conf + php_fpm_custom_file: /etc/php/7.0/fpm/pool.d/zzz-evolinux-custom.conf + when: ansible_distribution_major_version | version_compare('9', '>=') + +- name: Set default php.ini values for FPM + ini_file: + dest: "{{ phpini_fpm_defaults_file }}" + section: PHP + option: "{{ item.option }}" + value: "{{ item.value }}" + mode: "0644" + create: yes + with_items: + - { option: "short_open_tag", value: "Off" } + - { option: "expose_php", value: "Off" } + - { option: "display_errors", value: "Off" } + - { option: "log_errors", value: "On" } + - { option: "html_errors", value: "Off" } + - { option: "allow_url_fopen", value: "Off" } + +- name: Disable PHP functions for FPM + ini_file: + dest: "{{ phpini_fpm_defaults_file }}" + section: PHP + option: disable_functions + value: "exec,shell-exec,system,passthru,putenv,popen" + +- name: Custom php.ini for FPM + copy: + dest: "{{ phpini_fpm_custom_file }}" + content: | + ; Put customized values here. + force: no + +- name: Set default PHP FPM values + ini_file: + dest: "{{ php_fpm_defaults_file }}" + section: www + option: "{{ item.option }}" + value: "{{ item.value }}" + mode: "0644" + create: yes + with_items: + - { option: "pm", value: "ondemand" } + - { option: "pm.max_children", value: "100" } + - { option: "pm.process_idle_timeout", value: "10s" } + - { option: "slowlog", value: "log/$pool.log.slow" } + - { option: "request_slowlog_timeout", value: "5s" } + - { option: "pm.status_path", value: "/fpm_status" } + - { option: "request_terminate_timeout", value: "60s" } + - { option: "chroot", value: "/var/www/html" } + when: ansible_distribution_major_version | version_compare('9', '>=') + +- name: Custom PHP FPM values + copy: + dest: "{{ php_fpm_custom_file }}" + content: | + ; Put customized values here. + ; default_charset = "ISO-8859-1" + force: no + +- name: "Set custom values for PHP to enable Symfony" + ini_file: + dest: "{{ phpini_cli_custom_file }}" + section: PHP + option: "{{ item.option }}" + value: "{{ item.value }}" + mode: "0644" + with_items: + - { option: "date.timezone", value: "Europe/Paris" } + when: php_symfony_requirements + diff --git a/php/tasks/main.yml b/php/tasks/main.yml new file mode 100644 index 00000000..7ea4269c --- /dev/null +++ b/php/tasks/main.yml @@ -0,0 +1,19 @@ +--- + +- fail: + msg: only compatible with Debian >= 8 + when: + - ansible_distribution != "Debian" or ansible_distribution_major_version | version_compare('8', '<') + +- include: php_jessie.yml + when: ansible_distribution_release == "jessie" + +- include: php_stretch.yml + when: ansible_distribution_major_version | version_compare('9', '>=') + +- include: fpm.yml + when: php_fpm_enable + +- include: apache.yml + when: php_apache_enable + diff --git a/php/tasks/php_jessie.yml b/php/tasks/php_jessie.yml new file mode 100644 index 00000000..12f3a4f8 --- /dev/null +++ b/php/tasks/php_jessie.yml @@ -0,0 +1,65 @@ +--- + +- name: "Install PHP packages (jessie)" + apt: + name: '{{ item }}' + state: present + with_items: + - php5-cli + - php5-gd + - php5-imap + - php5-ldap + - php5-mcrypt + - php5-mysql + - php5-pgsql + - php-gettext + - php5-curl + - php5-ssh2 + - libphp-phpmailer + +- name: "Set php.ini config for CLI (jessie)" + set_fact: + phpini_cli_defaults_file: /etc/php5/cli/conf.d/z-evolinux-defaults.ini + phpini_cli_custom_file: /etc/php5/cli/conf.d/zzz-evolinux-custom.ini + +- name: "Set default php.ini values for CLI (jessie)" + ini_file: + dest: "{{ phpini_cli_defaults_file }}" + section: PHP + option: "{{ item.option }}" + value: "{{ item.value }}" + mode: "0644" + create: yes + with_items: + - { option: "short_open_tag", value: "Off" } + - { option: "expose_php", value: "Off" } + - { option: "display_errors", value: "Off" } + - { option: "log_errors", value: "On" } + - { option: "html_errors", value: "Off" } + - { option: "allow_url_fopen", value: "Off" } + +- name: "Disable PHP functions for CLI (jessie)" + ini_file: + dest: "{{ phpini_cli_defaults_file }}" + section: PHP + option: disable_functions + value: "exec,shell-exec,system,passthru,putenv,popen" + +- name: Custom php.ini for CLI + copy: + dest: "{{ phpini_cli_custom_file }}" + content: | + ; Put customized values here. + force: no + +- name: "Set custom values for PHP to enable Symfony (jessie)" + ini_file: + dest: "{{ phpini_cli_custom_file }}" + section: PHP + option: "{{ item.option }}" + value: "{{ item.value }}" + mode: "0644" + with_items: + - { option: "date.timezone", value: "Europe/Paris" } + when: php_symfony_requirements + diff --git a/php/tasks/php_stretch.yml b/php/tasks/php_stretch.yml new file mode 100644 index 00000000..4ed4c8b5 --- /dev/null +++ b/php/tasks/php_stretch.yml @@ -0,0 +1,66 @@ +--- + +- name: "Install PHP packages (Debian 9 or later)" + apt: + name: '{{ item }}' + state: present + with_items: + - php-cli + - php-gd + - php-imap + - php-ldap + - php-mcrypt + - php-mysql + - php-pgsql + - php-gettext + - php-curl + - php-ssh2 + - composer + - libphp-phpmailer + +- name: "Set php.ini config for CLI (Debian 9 or later)" + set_fact: + phpini_cli_defaults_file: /etc/php/7.0/cli/conf.d/z-evolinux-defaults.ini + phpini_cli_custom_file: /etc/php/7.0/cli/conf.d/zzz-evolinux-custom.ini + +- name: "Set default php.ini values for CLI (Debian 9 or later)" + ini_file: + dest: "{{ phpini_cli_defaults_file }}" + section: PHP + option: "{{ item.option }}" + value: "{{ item.value }}" + mode: "0644" + create: yes + with_items: + - { option: "short_open_tag", value: "Off" } + - { option: "expose_php", value: "Off" } + - { option: "display_errors", value: "Off" } + - { option: "log_errors", value: "On" } + - { option: "html_errors", value: "Off" } + - { option: "allow_url_fopen", value: "Off" } + +- name: "Disable PHP functions for CLI (Debian 9 or later)" + ini_file: + dest: "{{ phpini_cli_defaults_file }}" + section: PHP + option: disable_functions + value: "exec,shell-exec,system,passthru,putenv,popen" + +- name: "Custom php.ini for CLI (Debian 9 or later)" + copy: + dest: "{{ phpini_cli_custom_file }}" + content: | + ; Put customized values here. + ; default_charset = "ISO-8859-1" + force: no + +- name: "Set custom values for PHP to enable Symfony (Debian 9 or later)" + ini_file: + dest: "{{ phpini_cli_custom_file }}" + section: PHP + option: "{{ item.option }}" + value: "{{ item.value }}" + mode: "0644" + with_items: + - { option: "date.timezone", value: "Europe/Paris" } + when: php_symfony_requirements diff --git a/php-fpm/tests/test.yml b/php/tests/test.yml similarity index 100% rename from php-fpm/tests/test.yml rename to php/tests/test.yml diff --git a/postfix/tasks/main.yml b/postfix/tasks/main.yml index 3d7e59f3..49ccb2ac 100644 --- a/postfix/tasks/main.yml +++ b/postfix/tasks/main.yml @@ -20,7 +20,8 @@ group: root mode: "0644" force: yes - when: default_main_cf.stdout == "5450c05d65878e99dad696c7c722e511 -" + when: default_main_cf.stdout == "5450c05d65878e99dad696c7c722e511 -" or + default_main_cf.stdout == "30022953f1f61f002bfb72e163ecb27e -" notify: restart postfix - meta: flush_handlers diff --git a/postgresql/files/ACCC4CF8.asc b/postgresql/files/ACCC4CF8.asc new file mode 100644 index 00000000..8480576e --- /dev/null +++ b/postgresql/files/ACCC4CF8.asc @@ -0,0 +1,77 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +=DA1T +-----END PGP PUBLIC KEY BLOCK----- diff --git a/postgresql/tasks/pgdg-repo.yml b/postgresql/tasks/pgdg-repo.yml index 539debbc..ee42591e 100644 --- a/postgresql/tasks/pgdg-repo.yml +++ b/postgresql/tasks/pgdg-repo.yml @@ -15,7 +15,8 @@ - name: Add GPG key for PGDG repository apt_key: - url: http://apt.postgresql.org/pub/repos/apt/ACCC4CF8.asc + #url: http://apt.postgresql.org/pub/repos/apt/ACCC4CF8.asc + data: "{{ lookup('file', 'ACCC4CF8.asc') }}" - name: Add APT preference file template: diff --git a/proftpd/templates/evolinux.conf.j2 b/proftpd/templates/evolinux.conf.j2 index 2b62e1c0..d6e8b565 100644 --- a/proftpd/templates/evolinux.conf.j2 +++ b/proftpd/templates/evolinux.conf.j2 @@ -14,6 +14,7 @@ MaxClientsPerHost 20 PassivePorts 60000 61000 UseReverseDNS off IdentLookups off +TimesGMT off # Local permissions DefaultRoot ~ diff --git a/redmine/defaults/main.yml b/redmine/defaults/main.yml new file mode 100644 index 00000000..c87d09d3 --- /dev/null +++ b/redmine/defaults/main.yml @@ -0,0 +1,8 @@ +--- +puma_env: 'production' +puma_worker: 2 +puma_min_thread: 0 +puma_max_thread: 4 +redmine_db_name: "{{ redmine_user }}" +redmine_db_host: "localhost" +redmine_db_username: "{{ redmine_user }}" diff --git a/redmine/files/Gemfile.local b/redmine/files/Gemfile.local new file mode 100644 index 00000000..78486d1b --- /dev/null +++ b/redmine/files/Gemfile.local @@ -0,0 +1 @@ +gem "puma" diff --git a/redmine/files/profile b/redmine/files/profile new file mode 100644 index 00000000..57d0668e --- /dev/null +++ b/redmine/files/profile @@ -0,0 +1,23 @@ +# ~/.profile: executed by the command interpreter for login shells. + +umask 027 + +# if running bash +if [ -n "$BASH_VERSION" ]; then + # include .bashrc if it exists + if [ -f "$HOME/.bashrc" ]; then + . "$HOME/.bashrc" + fi +fi + +# set PATH so it includes gems bin +if [ -d "$HOME/bin" ] ; then + export PATH="$HOME/.gems/ruby/2.1.0/bin:$PATH" +fi + +# For systemctl --user +export XDG_RUNTIME_DIR=/run/user/$UID + +# Ruby vars +export RAILS_ENV=production +export BUNDLE_GEMFILE="$HOME/www/Gemfile" diff --git a/redmine/files/puma.service b/redmine/files/puma.service new file mode 100644 index 00000000..65aab8fb --- /dev/null +++ b/redmine/files/puma.service @@ -0,0 +1,17 @@ +[Unit] +Description=Puma HTTP server for Ruby Apps : %u +After=network.target + +[Service] +WorkingDirectory=%h/www +UMask=0027 +PIDFile=%h/ruby.pid +ExecStartPre=/bin/mkdir -m 0750 -p %h/run +ExecStart=/usr/bin/bundle exec puma --bind unix://%h/run/puma.sock?umask=0007 --pidfile %h/run/puma.pid --dir %h/www --config /etc/puma/%u.rb +ExecReload=/bin/kill -USR2 $MAINPID +KillMode=process +#Restart=on-failure + +[Install] +WantedBy=multi-user.target +Alias=puma.service diff --git a/redmine/tasks/main.yml b/redmine/tasks/main.yml new file mode 100644 index 00000000..f7ab97c4 --- /dev/null +++ b/redmine/tasks/main.yml @@ -0,0 +1,281 @@ +--- +- name: Install dependancy + apt: + name: "{{ item }}" + state: present + with_items: + - libpam-systemd + - ruby + - ruby-dev + - bundler + - imagemagick + - git-core + - git-svn + - gcc + - build-essential + - libxml2-dev + - libxslt1-dev + - libssl-dev + - libmagickwand-dev + - libmagickcore-dev + - libmysqlclient-dev + - python-mysqldb + tags: + - redmine + +#- name: +# lineinfile: +# with_items: +# - 'https://github.com/.*' +# - 'http://rubygems.org/.*' +# - 'http://.*.rubygems.org/.*' +# tags: +# - redmine + +- name: Deploy systemd unit + copy: + src: puma.service + dest: /etc/systemd/user/puma.service + mode: "0644" + tags: + - redmine + +- name: Create puma config dir + file: + path: /etc/puma + state: directory + mode: "0755" + owner: root + tags: + - redmine + +- name: Create redmine group + group: + name: "{{ redmine_user }}" + state: present + tags: + - redmine + +- name: Add www-data to redmine group + user: + name: www-data + groups: "{{ redmine_user }}" + append: yes + tags: + - redmine + +- name: Create redmine user + user: + name: "{{ redmine_user }}" + state: present + group: "{{ redmine_user }}" + createhome: yes + home: "/home/{{ redmine_user }}" + shell: /bin/bash + tags: + - redmine + +- name: Create required directory + file: + path: "{{ item }}" + state: directory + owner: "{{ redmine_user }}" + group: "{{ redmine_user }}" + mode: "0750" + with_items: + - "/home/{{ redmine_user }}" + - "/home/{{ redmine_user }}/files" + - "/home/{{ redmine_user }}/log" + tags: + - redmine + +- name: Touch Nginx logs file + file: + path: "/home/{{ redmine_user }}/log/{{ item }}" + state: touch + owner: "root" + group: "{{ redmine_user }}" + mode: "0640" + changed_when: false + with_items: + - nginx_access.log + - nginx_error.log + tags: + - redmine + +- name: Enable systemd user mode + command: "loginctl enable-linger {{ redmine_user }}" + changed_when: false + +- name: Set user .profile + copy: + src: profile + dest: "/home/{{ redmine_user }}/.profile" + owner: "{{ redmine_user }}" + group: "{{ redmine_user }}" + mode: "0640" + tags: + - redmine + +- name: Update or clone Redmine git + git: + repo: 'https://github.com/redmine/redmine.git' + dest: "/home/{{ redmine_user }}/www" + version: '3.4-stable' + umask: "027" + update: yes + become_user: "{{ redmine_user }}" + register: redmine_git_task + tags: + - redmine + +- name: Deploy custom Gemfile + copy: + src: Gemfile.local + dest: "/home/{{ redmine_user }}/www" + owner: "{{ redmine_user }}" + group: "{{ redmine_user }}" + mode: "0640" + register: redmine_local_gemfile_task + +- name: Get actual Mysql password + shell: "grep password /home/{{ redmine_user }}/.my.cnf | awk '{ print $3 }'" + register: redmine_get_mysql_password + check_mode: no + changed_when: False + failed_when: false + tags: + - redmine + +- name: Generate Mysql password + shell: perl -e 'print map{("a".."z","A".."Z",0..9)[int(rand(62))]}(1..16)' + register: redmine_generate_mysql_password + check_mode: no + changed_when: False + when: redmine_get_mysql_password.stdout == "" + tags: + - redmine + +- name: Set Mysql password + set_fact: + redmine_db_pass: "{{ redmine_generate_mysql_password.stdout | default(redmine_get_mysql_password.stdout) }}" + tags: + - redmine + +- name: Create Mysql database + mysql_db: + name: "{{ redmine_db_name }}" + config_file: "/root/.my.cnf" + state: present + tags: + - redmine + +- name: Create Mysql user + mysql_user: + name: "{{ redmine_db_username }}" + password: '{{ redmine_db_pass }}' + priv: "{{ redmine_user }}.*:ALL" + config_file: "/root/.my.cnf" + update_password: always + state: present + tags: + - redmine + +- name: Store credentials in my.cnf + ini_file: + dest: "/home/{{ redmine_user }}/.my.cnf" + owner: "{{ redmine_user }}" + group: "{{ redmine_user }}" + mode: "0600" + section: client + option: '{{ item.option }}' + value: '{{ item.value }}' + with_items: + - { option: 'user', value: "{{ redmine_db_username }}" } + - { option: 'database', value: "{{ redmine_db_name }}" } + - { option: 'password', value: '{{ redmine_db_pass }}' } + tags: + - redmine + +- name: Copy configurations file + template: + src: "{{ item }}.j2" + dest: "/home/{{ redmine_user }}/www/config/{{ item }}" + owner: "{{ redmine_user }}" + group: "{{ redmine_user }}" + mode: "0640" + with_items: + - 'configuration.yml' + - 'database.yml' + - 'additional_environment.rb' + tags: + - redmine + +- name: Update local gems with bundle + bundler: + state: present + gemfile: "/home/{{ redmine_user }}/www/Gemfile" + gem_path: "/home/{{ redmine_user }}/.gems" + user_install: yes + become_user: "{{ redmine_user }}" + when: redmine_git_task.changed or redmine_local_gemfile_task.changed + +- name: Migrate database with rake + shell: bundle exec rake -qf ~/www/Rakefile db:migrate + become_user: "{{ redmine_user }}" + become_method: sudo + become_flags: '-iu {{ redmine_user }}' + when: redmine_git_task.changed + +- name: Populate Mysql database + shell: bundle exec rake -qf ~/www/Rakefile redmine:load_default_data REDMINE_LANG=fr && touch ~/.populated + args: + creates: "/home/{{ redmine_user }}/.populated" + become_user: "{{ redmine_user }}" + become_method: sudo + become_flags: '-iu {{ redmine_user }}' + +- name: Generate secret token + shell: bundle exec rake -qf ~/www/Rakefile generate_secret_token + args: + creates: "/home/{{ redmine_user }}/www/config/initializers/secret_token.rb" + become_user: "{{ redmine_user }}" + become_method: sudo + become_flags: '-iu {{ redmine_user }}' + tags: + - redmine + +- name: Copy puma config + template: + src: puma.rb.j2 + dest: "/etc/puma/{{ redmine_user }}.rb" + owner: "{{ redmine_user }}" + group: "{{ redmine_user }}" + mode: "0640" + register: redmine_puma_config_task + tags: + - redmine + +- name: Start puma service + systemd: + name: puma + daemon_reload: yes + enabled: yes + state: started + user: yes + become_user: "{{ redmine_user }}" + become_method: sudo + become_flags: '-iu {{ redmine_user }}' + tags: + - redmine + +- name: Reload puma service + systemd: + name: puma + daemon_reload: yes + state: reloaded + user: yes + become_user: "{{ redmine_user }}" + become_method: sudo + become_flags: '-iu {{ redmine_user }}' + when: redmine_puma_config_task.changed diff --git a/redmine/templates/additional_environment.rb.j2 b/redmine/templates/additional_environment.rb.j2 new file mode 100644 index 00000000..b1211a2e --- /dev/null +++ b/redmine/templates/additional_environment.rb.j2 @@ -0,0 +1 @@ +config.paths['log'] = "/home/{{ redmine_user }}/log/redmine.log" diff --git a/redmine/templates/configuration.yml.j2 b/redmine/templates/configuration.yml.j2 new file mode 100644 index 00000000..3640cd65 --- /dev/null +++ b/redmine/templates/configuration.yml.j2 @@ -0,0 +1,11 @@ +production: + email_delivery: + delivery_method: :smtp + smtp_settings: + address: localhost + port: 25 + domain: "{{ ansible_domain }}" + ssl: false + enable_starttls_auto: false + attachments_storage_path: /home/{{ redmine_user }}/files + autologin_cookie_secure: true diff --git a/redmine/templates/database.yml.j2 b/redmine/templates/database.yml.j2 new file mode 100644 index 00000000..c694644c --- /dev/null +++ b/redmine/templates/database.yml.j2 @@ -0,0 +1,7 @@ +production: + adapter: mysql2 + database: {{ redmine_db_name }} + host: {{ redmine_db_host }} + username: {{ redmine_db_username }} + password: "{{ redmine_db_pass }}" + encoding: utf8 diff --git a/redmine/templates/puma.rb.j2 b/redmine/templates/puma.rb.j2 new file mode 100644 index 00000000..dd5ea5af --- /dev/null +++ b/redmine/templates/puma.rb.j2 @@ -0,0 +1,4 @@ +environment '{{ puma_env }}' +workers {{ puma_worker }} +threads {{ puma_min_thread }}, {{ puma_max_thread }} +tag 'Redmine {{ redmine_user }}' diff --git a/samba/.kitchen.yml b/samba/.kitchen.yml deleted file mode 100644 index b21cc3db..00000000 --- a/samba/.kitchen.yml +++ /dev/null @@ -1,28 +0,0 @@ ---- -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 - -suites: - - name: default - provisioner: - name: ansible_playbook - playbook: ./tests/test.yml - -transport: - max_ssh_sessions: 6 diff --git a/samba/README.md b/samba/README.md deleted file mode 100644 index 7e3f4f12..00000000 --- a/samba/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Amavis - -Installation and basic configuration of samba. - -## 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`. diff --git a/samba/defaults/main.yml b/samba/defaults/main.yml deleted file mode 100644 index ed97d539..00000000 --- a/samba/defaults/main.yml +++ /dev/null @@ -1 +0,0 @@ ---- diff --git a/samba/handlers/main.yml b/samba/handlers/main.yml deleted file mode 100644 index e5ff2eeb..00000000 --- a/samba/handlers/main.yml +++ /dev/null @@ -1,10 +0,0 @@ ---- -- name: restart nmbd - service: - name: nmbd - state: restarted - -- name: restart smbd - service: - name: smbd - state: restarted diff --git a/samba/meta/main.yml b/samba/meta/main.yml deleted file mode 100644 index caf4c3c0..00000000 --- a/samba/meta/main.yml +++ /dev/null @@ -1,19 +0,0 @@ -galaxy_info: - author: Evolix - description: Installation and basic configuration of samba. - - issue_tracker_url: https://forge.evolix.org/projects/ansible-roles/issues - - license: GPLv2 - - min_ansible_version: 2.2 - - platforms: - - name: Debian - versions: - - jessie - -dependencies: [] - # List your role dependencies here, one per line. - # Be sure to remove the '[]' above if you add dependencies - # to this list. diff --git a/samba/tasks/main.yml b/samba/tasks/main.yml deleted file mode 100644 index 79dba4b9..00000000 --- a/samba/tasks/main.yml +++ /dev/null @@ -1,4 +0,0 @@ -- name: ensure packages are installed - apt: - name: samba - state: present diff --git a/samba/tests/test.yml b/samba/tests/test.yml deleted file mode 100644 index 79e5cdab..00000000 --- a/samba/tests/test.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -- hosts: test-kitchen - roles: - - role: samba diff --git a/spamassassin/.kitchen.yml b/spamassassin/.kitchen.yml deleted file mode 100644 index b21cc3db..00000000 --- a/spamassassin/.kitchen.yml +++ /dev/null @@ -1,28 +0,0 @@ ---- -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 - -suites: - - name: default - provisioner: - name: ansible_playbook - playbook: ./tests/test.yml - -transport: - max_ssh_sessions: 6 diff --git a/spamassassin/README.md b/spamassassin/README.md deleted file mode 100644 index c337ed92..00000000 --- a/spamassassin/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Spamassassin - -Installation and basic configuration of spamassassin - -## 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`. diff --git a/spamassassin/defaults/main.yml b/spamassassin/defaults/main.yml deleted file mode 100644 index ed97d539..00000000 --- a/spamassassin/defaults/main.yml +++ /dev/null @@ -1 +0,0 @@ ---- diff --git a/spamassassin/handlers/main.yml b/spamassassin/handlers/main.yml deleted file mode 100644 index 7479d736..00000000 --- a/spamassassin/handlers/main.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -- name: restart spamassassin - service: - name: spamassassin - state: restarted diff --git a/spamassassin/meta/main.yml b/spamassassin/meta/main.yml deleted file mode 100644 index 53c77c38..00000000 --- a/spamassassin/meta/main.yml +++ /dev/null @@ -1,19 +0,0 @@ -galaxy_info: - author: Evolix - description: Installation and basic configuration of spamassassin. - - issue_tracker_url: https://forge.evolix.org/projects/ansible-roles/issues - - license: GPLv2 - - min_ansible_version: 2.2 - - platforms: - - name: Debian - versions: - - jessie - -dependencies: [] - # List your role dependencies here, one per line. - # Be sure to remove the '[]' above if you add dependencies - # to this list. diff --git a/spamassassin/tasks/main.yml b/spamassassin/tasks/main.yml deleted file mode 100644 index 0b6cc161..00000000 --- a/spamassassin/tasks/main.yml +++ /dev/null @@ -1,4 +0,0 @@ -- name: ensure packages are installed - apt: - name: spamassassin - state: present diff --git a/spamassassin/tests/test.yml b/spamassassin/tests/test.yml deleted file mode 100644 index 931049bd..00000000 --- a/spamassassin/tests/test.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -- hosts: test-kitchen - roles: - - role: spamassassin diff --git a/squid/README.md b/squid/README.md index d25e85c0..a2d5c29f 100644 --- a/squid/README.md +++ b/squid/README.md @@ -1,6 +1,6 @@ # squid -Installation and configuration of Squid as an outgoing proxy. +Installation and configuration of Squid ## Tasks @@ -12,7 +12,9 @@ A blank file is created at `/etc/squid3/whitelist-custom.conf` to add addresses * `squid_address` : IP address for internal/outgoing traffic (default: Ansible detected IPv4 address) ; * `squid_whitelist_items` : list of URL to add to the whitelist (default: `[]`) ; -* `general_alert_email`: email address to send various alert messages (default: `root@localhost`). +* `squid_localproxy_enable` : enable configuration for squid as local proxy (default: False) ; +* `general_alert_email`: email address to send various alert messages (default: `root@localhost`) ; * `log2mail_alert_email`: email address to send Log2mail messages to (default: `general_alert_email`). + The full list of variables (with default values) can be found in `defaults/main.yml`. diff --git a/squid/defaults/main.yml b/squid/defaults/main.yml index 8964de16..1a6db438 100644 --- a/squid/defaults/main.yml +++ b/squid/defaults/main.yml @@ -4,3 +4,5 @@ log2mail_alert_email: Null squid_address: "{{ ansible_default_ipv4.address }}" squid_whitelist_items: [] + +squid_localproxy_enable: False diff --git a/squid/files/default_squid b/squid/files/default_squid new file mode 100644 index 00000000..ae39d9ed --- /dev/null +++ b/squid/files/default_squid @@ -0,0 +1,2 @@ +CONFIG=/etc/squid/evolinux-defaults.conf +SQUID_ARGS="-YC -f $CONFIG" diff --git a/squid/files/evolinux-defaults.conf b/squid/files/evolinux-defaults.conf new file mode 100644 index 00000000..ef11ea69 --- /dev/null +++ b/squid/files/evolinux-defaults.conf @@ -0,0 +1,36 @@ +http_port 127.0.0.1:3128 +coredump_dir /var/spool/squid +max_filedescriptors 4096 + +acl SSL_ports port 443 +acl Safe_ports port 80 # http +acl Safe_ports port 21 # ftp +acl Safe_ports port 443 # https +acl Safe_ports port 70 # gopher +acl Safe_ports port 210 # wais +acl Safe_ports port 1025-65535 # unregistered ports +acl Safe_ports port 280 # http-mgmt +acl Safe_ports port 488 # gss-http +acl Safe_ports port 591 # filemaker +acl Safe_ports port 777 # multiling http +acl CONNECT method CONNECT +acl Whitelist_domains dstdom_regex -i "/etc/squid/evolinux-whitelist-defaults.conf" +acl Whitelist_domains dstdom_regex -i "/etc/squid/evolinux-whitelist-custom.conf" +include /etc/squid/evolinux-acl.conf + +http_access deny !Safe_ports +http_access deny CONNECT !SSL_ports +http_access allow localhost manager +http_access deny manager +include /etc/squid/evolinux-httpaccess.conf +http_access allow localhost +http_access deny all + +refresh_pattern ^ftp: 1440 20% 10080 +refresh_pattern ^gopher: 1440 0% 1440 +refresh_pattern -i (/cgi-bin/|\?) 0 0% 0 +refresh_pattern . 0 20% 4320 + +logformat combined %>a %[ui %[un [%tl] "%rm %ru HTTP/%rv" %>Hs %h" "%{User-Agent}>h" %Ss:%Sh +access_log /var/log/squid/access.log combined +include /etc/squid/evolinux-custom.conf diff --git a/squid/files/evolinux-httpaccess.conf b/squid/files/evolinux-httpaccess.conf new file mode 100644 index 00000000..7a4e00a2 --- /dev/null +++ b/squid/files/evolinux-httpaccess.conf @@ -0,0 +1,2 @@ +http_access deny !Whitelist_domains +http_access allow LOCAL diff --git a/squid/files/evolinux-whitelist-defaults.conf b/squid/files/evolinux-whitelist-defaults.conf new file mode 100644 index 00000000..ada4fcdc --- /dev/null +++ b/squid/files/evolinux-whitelist-defaults.conf @@ -0,0 +1,126 @@ +### Evolix & System +^.*\.evolix\.(net|org|com|fr)$ +^.*\.debian\.org$ +^www\.backports\.org$ +^backports\.debian\.org$ +^www\.kernel\.org$ +^hwraid\.le-vert\.net$ +^.*clamav\.net$ +^spamassassin\.apache\.org$ +^.*sa-update.*$ +^pear\.php\.net$ + +# Let's Encrypt +^.*\.letsencrypt.org$ + +# Other OCSP endpoint +^ocsp\.usertrust\.com$ + +### CMS / Wordpress / Drupal / ... +# Wordpress +^.*akismet\.com$ +^.*wordpress\.(org|com)$ +^.*gravatar\.com$ +^www\.wordpress-fr\.net$ +^pixel\.wp\.com$ +# Wordpress pingback +^rpc\.pingomatic\.com$ +^blo\.gs$ +^ping\.blo\.gs$ +^ping\.baidu\.com$ +^blogsearch\.google\.ru$ +^ping\.pubsub\.com$ +^rpc\.twingly\.com$ +^api\.feedster\.com$ +^api\.moreover\.com$ +^api\.moreover\.com$ +^www\.blogdigger\.com$ +^www\.blogshares\.com$ +^www\.blogsnow\.com$ +^www\.blogstreet\.com$ +^bulkfeeds\.net$ +^www\.newsisfree\.com$ +^ping\.feedburner\.com$ +^ping\.syndic8\.com$ +^ping\.weblogalot\.com$ +^rpc\.blogrolling\.com$ +^rpc\.technorati\.com$ +^rpc\.weblogs\.com$ +^www\.feedsubmitter\.com$ +^www\.pingerati\.net$ +^www\.pingmyblog\.com$ +^geourl\.org$ +^ipings\.com$ +^www\.weblogalot\.com$ +# Wordpress plugins +^.*wpml\.org$ +^www\.wpcube\.co\.uk$ +^.*wp-rocket\.me$ +^www\.yithemes\.com$ +^.*yoast\.com$ +^yarpp\.org$ +^repository\.kreaturamedia\.com$ +^api\.wp-events-plugin\.com$ +^updates\.themepunch\.com$ +^themeisle\.com$ +^download\.advancedcustomfields\.com$ +^wpcdn\.io$ +^vimeo\.com$ +^api\.genesistheme\.com$ +^www\.bolderelements\.net$ +# Magento Plugins +^extensions\.activo\.com$ +^amasty\.com$ +# Joomla +^.*.joomla\.org$ +^getk2\.org$ +^miwisoft\.com$ +^mijosoft\.com$ +^www\.joomlaworks\.net$ +^cdn\.joomlaworks\.org$ +^download\.regularlabs\.com$ +# Prestashop +^.*.prestashop\.com$ +^www\.presta-module\.com$ +^www\.presteamshop\.com$ +# Others +^.*.drupal\.org$ +^.*\.dotclear\.(net|org)$ +^www\.phpbb\.com$ +^www\.typolight\.org$ +^www\.spip\.net$ + +### Feeds / API / WS Tools / ... +# Google +^.*\.googleapis\.com$ +^.*\.google-analytics\.com$ +^blogsearch\.google\.(com|fr)$ +^csi\.gstatic\.com$ +^maps\.google\..*$ +^translate\.google\.com$ +^www\.google\.com$ +# Facebook +^.*\.facebook\.com$ +^.*\.fbcdn\.net$ +# Maxmind +^geolite\.maxmind\.com$ +# Others +#^.*amazon.com$ +^.*twitter\.com$ +^.*feedburner\.com$ +^.*openx\.(org|com|net)$ +^geoip-api\.meteor\.com$ +^www\.bing\.com$ +^www\.telize\.com$ +^.*ident\.me$ +^.*icanhazip\.com$ +^www\.express-mailing\.com$ +^bot\.whatismyipaddress\.com$ +^ipecho\.net$ +^keyserver\.ubuntu\.com$ +^repo\.mongodb\.org$ +^pkg\.jenkins-ci\.org$ +^mirrors\.jenkins\.io$ +^jenkins\.mirror\.isppower\.de$ +^ftp\.icm\.edu\.pl$ +^apt\.newrelic\.com$ diff --git a/squid/files/whitelist-custom.conf b/squid/files/whitelist-custom.conf deleted file mode 100644 index 5d930f2c..00000000 --- a/squid/files/whitelist-custom.conf +++ /dev/null @@ -1,2 +0,0 @@ -### Custom whitelist -# http://example.com/.* diff --git a/squid/files/whitelist-evolinux.conf b/squid/files/whitelist-evolinux.conf index 063df876..10bcd779 100644 --- a/squid/files/whitelist-evolinux.conf +++ b/squid/files/whitelist-evolinux.conf @@ -13,6 +13,9 @@ http://pear.php.net/.* # Let's Encrypt http://.*.letsencrypt.org/.* +# Other OCSP endpoint +http://ocsp.usertrust.com/.* + ### CMS / Wordpress / Drupal / ... # Wordpress http://.*akismet.com/.* @@ -114,6 +117,10 @@ http://.*icanhazip.com/.* http://www.express-mailing.com/.* http://bot.whatismyipaddress.com/.* http://ipecho.net/.* - -### Various / Manual entry -http://.*.s3.amazonaws.com/.* +http://keyserver.ubuntu.com/.* +http://repo.mongodb.org/.* +http://pkg.jenkins-ci.org/.* +http://mirrors.jenkins.io/.* +http://jenkins.mirror.isppower.de/.* +http://ftp.icm.edu.pl/.* +http://apt.newrelic.com/.* diff --git a/squid/handlers/main.yml b/squid/handlers/main.yml index 8173d655..4f5329b9 100644 --- a/squid/handlers/main.yml +++ b/squid/handlers/main.yml @@ -28,3 +28,6 @@ service: name: log2mail state: restarted + +- name: restart minifirewall + command: /etc/init.d/minifirewall restart diff --git a/squid/tasks/logrotate.yml b/squid/tasks/logrotate.yml index 3ac53a6e..975c3a96 100644 --- a/squid/tasks/logrotate.yml +++ b/squid/tasks/logrotate.yml @@ -2,5 +2,5 @@ - name: logrotate configuration template: src: logrotate.j2 - dest: /etc/logrotate.d/{{ squid_daemon }} + dest: /etc/logrotate.d/{{ squid_daemon_name }} force: no diff --git a/squid/tasks/main.yml b/squid/tasks/main.yml index adc8ea8f..7c080b44 100644 --- a/squid/tasks/main.yml +++ b/squid/tasks/main.yml @@ -1,42 +1,138 @@ --- -- name: Include OS-specific variables - include_vars: "{{ ansible_os_family }}-{{ ansible_distribution_release }}.yml" +- fail: + msg: only compatible with Debian >= 8 + when: + - ansible_distribution != "Debian" or ansible_distribution_major_version | version_compare('8', '<') -- name: package is installed +- name: "Set squid name (jessie)" + set_fact: + squid_daemon_name: squid3 + when: ansible_distribution_release == "jessie" + +- name: "Set squid name (Debian 9 or later)" + set_fact: + squid_daemon_name: squid + when: ansible_distribution_major_version | version_compare('9', '>=') + +- name: "Install Squid packages" apt: - name: "{{ squid_package }}" + name: '{{ item }}' state: present + with_items: + - "{{ squid_daemon_name }}" + - squidclient -- name: squid.conf is present +- name: "Set alternative config file (Debian 9 or later)" + copy: + src: default_squid + dest: /etc/default/squid + when: ansible_distribution_major_version | version_compare('9', '>=') + +- name: "squid.conf is present (jessie)" template: - src: squid.j2 - dest: "{{ squid_conf_file }}" - notify: "restart {{ squid_daemon }}" + src: squid.conf.j2 + dest: /etc/squid3/squid.conf + notify: "restart squid3" + when: ansible_distribution_release == "jessie" -- name: evolix whitelist is present +- name: "evolix whitelist is present (jessie)" copy: src: whitelist-evolinux.conf - dest: "{{ squid_conf_path }}/whitelist-evolinux.conf" - force: yes - backup: yes - notify: "reload {{ squid_daemon }}" - -- name: custom whitelist is present - copy: - src: whitelist-custom.conf - dest: "{{ squid_conf_path }}/whitelist-custom.conf" + dest: /etc/squid3/whitelist.conf force: no - notify: "reload {{ squid_daemon }}" + notify: "reload squid3" + when: ansible_distribution_release == "jessie" -- name: add some URL in whitelist +- name: "evolinux custom squid file (Debian 9 or later)" + copy: + src: evolinux-defaults.conf + dest: /etc/squid/evolinux-defaults.conf + notify: "restart squid" + when: ansible_distribution_major_version | version_compare('9', '>=') + +- name: "evolinux defaults whitelist (Debian 9 or later)" + copy: + src: evolinux-whitelist-defaults.conf + dest: /etc/squid/evolinux-whitelist-defaults.conf + notify: "reload squid" + when: ansible_distribution_major_version | version_compare('9', '>=') + +- name: "evolinux custom whitelist (Debian 9 or later)" + copy: + dest: /etc/squid/evolinux-whitelist-custom.conf + content: | + # Put customized values here. + force: no + when: ansible_distribution_major_version | version_compare('9', '>=') + +- name: "evolinux acl for local proxy (Debian 9 or later)" + template: + src: evolinux-acl.conf.j2 + dest: /etc/squid/evolinux-acl.conf + force: no + notify: "reload squid" + when: squid_localproxy_enable and ansible_distribution_major_version | version_compare('9', '>=') + +- name: "evolinux custom acl (Debian 9 or later)" + copy: + dest: /etc/squid/evolinux-acl.conf + content: | + # Put customized values here. + force: no + when: squid_localproxy_enable == False and ansible_distribution_major_version | version_compare('9', '>=') + +- name: "evolinux http_access for local proxy (Debian 9 or later)" + copy: + src: evolinux-httpaccess.conf + dest: /etc/squid/evolinux-httpaccess.conf + force: no + notify: "reload squid" + when: squid_localproxy_enable and ansible_distribution_major_version | version_compare('9', '>=') + +- name: "evolinux custom http_access (Debian 9 or later)" + copy: + dest: /etc/squid/evolinux-httpaccess.conf + content: | + # Put customized values here. + force: no + when: squid_localproxy_enable == False and ansible_distribution_major_version | version_compare('9', '>=') + +- name: "evolinux overrides for local proxy (Debian 9 or later)" + template: + src: evolinux-custom.conf.j2 + dest: /etc/squid/evolinux-custom.conf + force: no + notify: "reload squid" + when: squid_localproxy_enable and ansible_distribution_major_version | version_compare('9', '>=') + +- name: "evolinux custom overrides (Debian 9 or later)" + copy: + dest: /etc/squid/evolinux-custom.conf + content: | + # Put customized values here. + force: no + when: squid_localproxy_enable == False and ansible_distribution_major_version | version_compare('9', '>=') + +- name: add some URL in whitelist (Debian 8) lineinfile: insertafter: EOF - dest: "{{ squid_conf_path }}/whitelist-custom.conf" + dest: /etc/squid3/whitelist.conf line: "{{ item }}" state: present with_items: '{{ squid_whitelist_items }}' - notify: "reload {{ squid_daemon }}" + notify: "reload squid3" + when: ansible_distribution_major_version == '8' + +- name: add some URL in whitelist (Debian 9 or later) + lineinfile: + insertafter: EOF + dest: /etc/squid/evolinux-whitelist-custom.conf + line: "{{ item }}" + state: present + with_items: '{{ squid_whitelist_items }}' + notify: "reload squid" + when: ansible_distribution_major_version | version_compare('9', '>=') - include: logrotate.yml diff --git a/squid/tasks/minifirewall.yml b/squid/tasks/minifirewall.yml index 7f8217b0..5eea7675 100644 --- a/squid/tasks/minifirewall.yml +++ b/squid/tasks/minifirewall.yml @@ -11,12 +11,14 @@ dest: /etc/default/minifirewall regexp: "^(HTTPSITES='[^0-9])" replace: '#\1' + notify: restart minifirewall - name: all HTTPSITES are authorized in minifirewall lineinfile: dest: /etc/default/minifirewall line: "HTTPSITES='0.0.0.0/0'" insertafter: "^#HTTPSITES=" + notify: restart minifirewall - name: add iptables rules for the proxy lineinfile: @@ -29,10 +31,12 @@ - "/sbin/iptables -t nat -A OUTPUT -p tcp --dport 80 -d {{ squid_address }} -j ACCEPT" - "/sbin/iptables -t nat -A OUTPUT -p tcp --dport 80 -d 127.0.0.0/8 -j ACCEPT" - "/sbin/iptables -t nat -A OUTPUT -p tcp --dport 80 -j REDIRECT --to-port 8888" + notify: restart minifirewall - name: remove minifirewall example rule for the proxy lineinfile: dest: /etc/default/minifirewall regexp: '^#.*(-t nat).*(-d X\.X\.X\.X)' state: absent + notify: restart minifirewall when: minifirewall_test.stat.exists diff --git a/squid/templates/evolinux-acl.conf.j2 b/squid/templates/evolinux-acl.conf.j2 new file mode 100644 index 00000000..dbd83927 --- /dev/null +++ b/squid/templates/evolinux-acl.conf.j2 @@ -0,0 +1 @@ +acl LOCAL src {{ squid_address }}/32 diff --git a/squid/templates/evolinux-custom.conf.j2 b/squid/templates/evolinux-custom.conf.j2 new file mode 100644 index 00000000..cc465dc7 --- /dev/null +++ b/squid/templates/evolinux-custom.conf.j2 @@ -0,0 +1,4 @@ +http_port 8888 transparent +cache deny all +ignore_expect_100 on +tcp_outgoing_address {{ squid_address }} diff --git a/squid/templates/log2mail.j2 b/squid/templates/log2mail.j2 index 223c8e27..f01256c5 100644 --- a/squid/templates/log2mail.j2 +++ b/squid/templates/log2mail.j2 @@ -1,4 +1,4 @@ -file = /var/log/squid3/access.log +file = /var/log/{{ squid_daemon_name }}/access.log pattern = "TCP_DENIED" mailto = {{ log2mail_alert_email or general_alert_email | mandatory }} template = /etc/log2mail/mail diff --git a/squid/templates/logrotate.j2 b/squid/templates/logrotate.j2 index 409776b2..12597d7b 100644 --- a/squid/templates/logrotate.j2 +++ b/squid/templates/logrotate.j2 @@ -1,4 +1,4 @@ -/var/log/{{ squid_daemon }}/*.log { +/var/log/{{ squid_daemon_name }}/*.log { monthly compress rotate 12 @@ -6,6 +6,6 @@ create 640 proxy adm sharedscripts postrotate - test ! -e /var/run/{{ squid_daemon }}.pid || /usr/sbin/{{ squid_daemon }} -k rotate + test ! -e /var/run/{{ squid_daemon_name }}.pid || /usr/sbin/{{ squid_daemon_name }} -k rotate endscript } diff --git a/squid/templates/squid.j2 b/squid/templates/squid.conf.j2 similarity index 78% rename from squid/templates/squid.j2 rename to squid/templates/squid.conf.j2 index f0bafb91..108a3bc1 100644 --- a/squid/templates/squid.j2 +++ b/squid/templates/squid.conf.j2 @@ -8,8 +8,7 @@ acl localhost src 127.0.0.0/32 acl INTERNE src {{ squid_address }}/32 127.0.0.0/8 acl Safe_ports port 80 # http acl SSL_ports port 443 563 -acl WHITELIST url_regex "{{ squid_conf_path }}/whitelist-evolinux.conf" -acl WHITELIST url_regex "{{ squid_conf_path }}/whitelist-custom.conf" +acl WHITELIST url_regex "/etc/squid3/whitelist.conf" http_access deny !WHITELIST http_access allow INTERNE http_access deny all diff --git a/squid/vars/Debian-jessie.yml b/squid/vars/Debian-jessie.yml deleted file mode 100644 index c5326e3b..00000000 --- a/squid/vars/Debian-jessie.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -squid_package: squid3 -squid_daemon: squid3 -squid_conf_path: /etc/squid3 -squid_conf_file: /etc/squid3/squid.conf diff --git a/squid/vars/Debian-stretch.yml b/squid/vars/Debian-stretch.yml deleted file mode 100644 index 5e455921..00000000 --- a/squid/vars/Debian-stretch.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -squid_package: squid -squid_daemon: squid -squid_conf_path: /etc/squid -squid_conf_file: /etc/squid/squid.conf diff --git a/tomcat-instance/defaults/main.yml b/tomcat-instance/defaults/main.yml index e555e2cd..6a2ec877 100644 --- a/tomcat-instance/defaults/main.yml +++ b/tomcat-instance/defaults/main.yml @@ -1,2 +1,5 @@ --- +tomcat_instance_java_path: '/usr/lib/jvm/java-7-openjdk-amd64' tomcat_instance_root: '/srv/tomcat' +tomcat_instance_shutdown: "{{ tomcat_instance_port | int + 1 }}" +tomcat_instance_mps: 256 diff --git a/tomcat-instance/handlers/main.yml b/tomcat-instance/handlers/main.yml deleted file mode 100644 index 3849b184..00000000 --- a/tomcat-instance/handlers/main.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -- name: new aliases - command: newaliases diff --git a/tomcat-instance/tasks/check.yml b/tomcat-instance/tasks/check.yml index 996a0773..3c2319d0 100644 --- a/tomcat-instance/tasks/check.yml +++ b/tomcat-instance/tasks/check.yml @@ -21,17 +21,3 @@ #- name: Check use of http port # command: grep ' https://wiki.apache.org/tomcat/HowTo/FasterStartUp#Entropy_Source +JAVA_HOME="{{ tomcat_instance_java_path }}" +JAVA_OPTS="-server -Xmx{{ tomcat_instance_ram }}m -Xms{{ tomcat_instance_ram }}m -XX:MaxPermSize={{ tomcat_instance_mps }}m -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+CMSPermGenSweepingEnabled -XX:+CMSClassUnloadingEnabled -Xverify:none -Djava.security.egd=file:/dev/./urandom" diff --git a/tomcat/tasks/packages.yml b/tomcat/tasks/packages.yml index 158e1a06..033d4f0e 100644 --- a/tomcat/tasks/packages.yml +++ b/tomcat/tasks/packages.yml @@ -21,3 +21,9 @@ src: 'tomcat.service' dest: "/etc/systemd/user/tomcat.service" mode: "0755" + +- name: Disable default tomcat7 service + service: + name: tomcat7 + state: stopped + enabled: false diff --git a/unbound/tasks/main.yml b/unbound/tasks/main.yml index 33d4a4ff..209c6d0f 100644 --- a/unbound/tasks/main.yml +++ b/unbound/tasks/main.yml @@ -19,18 +19,6 @@ tags: - unbound -- name: Copy Unbound config - template: - src: unbound.conf.j2 - dest: /var/unbound/etc/unbound.conf - owner: root - group: wheel - mode: "0644" - when: ansible_distribution == "OpenBSD" - notify: reload unbound - tags: - - unbound - - name: Starting and enabling Unbound service: name: unbound diff --git a/unbound/templates/unbound.conf.j2 b/unbound/templates/unbound.conf.j2 index 2447ea41..73c03141 100644 --- a/unbound/templates/unbound.conf.j2 +++ b/unbound/templates/unbound.conf.j2 @@ -15,11 +15,7 @@ server: # root-hints: "/var/unbound/etc/named.cache" # Uncomment to enable DNSSEC validation. -{% if ansible_os_family == "OpenBSD" %} - auto-trust-anchor-file: "/var/unbound/db/root.key" -{% else %} #auto-trust-anchor-file: "/etc/unbound/root.key" -{% endif %} # Serve zones authoritatively from Unbound to resolver clients. # Not for external service. diff --git a/varnish/tasks/main.yml b/varnish/tasks/main.yml index 9671768f..ffd80889 100644 --- a/varnish/tasks/main.yml +++ b/varnish/tasks/main.yml @@ -34,12 +34,11 @@ tags: - varnish -- name: Modify Varnish configuration files +- name: Override Varnish systemd unit template: src: varnish.conf.j2 - dest: /etc/systemd/system/varnish.service.d/varnish.conf + dest: /etc/systemd/system/varnish.service.d/evolinux.conf force: yes - backup: yes notify: reload systemd tags: - varnish diff --git a/varnish/templates/varnish.conf.j2 b/varnish/templates/varnish.conf.j2 index a60462e2..275e8909 100644 --- a/varnish/templates/varnish.conf.j2 +++ b/varnish/templates/varnish.conf.j2 @@ -1,7 +1,5 @@ # {{ ansible_managed }} [Service] -ExecStart= ExecStart=/usr/sbin/varnishd -a {{ varnish_addresses | join(',') }} -T {{ varnish_management_address }} -f {{ varnish_config_file }} -S {{ varnish_secret_file }} -s {{ varnish_storage }} -p thread_pools={{ varnish_thread_pools }} -p thread_pool_add_delay={{ varnish_thread_pool_add_delay }} -p thread_pool_min={{ varnish_thread_pool_min }} -p thread_pool_max={{ varnish_thread_pool_max }} -ExecReload= ExecReload=/etc/varnish/reload-vcl.sh diff --git a/vrrpd/tasks/main.yml b/vrrpd/tasks/main.yml index ee1bad90..b4f9b118 100644 --- a/vrrpd/tasks/main.yml +++ b/vrrpd/tasks/main.yml @@ -1,7 +1,7 @@ --- - name: Install Evolix public repositry include_role: - name: apt-repositories + name: apt tasks_from: evolix_public.yml - name: Install vrrpd packages diff --git a/evoadmin/defaults/main.yml b/webapps/evoadmin-web/defaults/main.yml similarity index 53% rename from evoadmin/defaults/main.yml rename to webapps/evoadmin-web/defaults/main.yml index 30ba8010..58200cf1 100644 --- a/evoadmin/defaults/main.yml +++ b/webapps/evoadmin-web/defaults/main.yml @@ -9,6 +9,15 @@ evoadmin_log_dir: "{{ evoadmin_home_dir }}/log" evoadmin_scripts_dir: /usr/share/scripts/evoadmin/ evoadmin_host: "evoadmin.{{ ansible_fqdn }}" evoadmin_username: evoadmin -evoadmin_ssl_subject: "/CN={{ ansible_fqdn }}" evoadmin_enable_vhost: True + +evoadmin_tpl_servername: "{{ ansible_fqdn }}" +evoadmin_tpl_address: "{{ ansible_default_ipv4.address }}" +evoadmin_tpl_phpmyadmin_url: Null +evoadmin_tpl_cgi_suffix: Null +evoadmin_tpl_signature: evoadmin +evoadmin_tpl_mail_from: root@localhost +evoadmin_tpl_mail_bcc: Null +evoadmin_tpl_mail_standard: "{{ general_alert_email }}" +evoadmin_tpl_mail_urgent: "{{ general_alert_email }}" diff --git a/evoadmin/files/evolinux.conf.diff b/webapps/evoadmin-web/files/evolinux.conf.diff similarity index 100% rename from evoadmin/files/evolinux.conf.diff rename to webapps/evoadmin-web/files/evolinux.conf.diff diff --git a/evoadmin/handlers/main.yml b/webapps/evoadmin-web/handlers/main.yml similarity index 100% rename from evoadmin/handlers/main.yml rename to webapps/evoadmin-web/handlers/main.yml diff --git a/evoadmin/tasks/config.yml b/webapps/evoadmin-web/tasks/config.yml similarity index 100% rename from evoadmin/tasks/config.yml rename to webapps/evoadmin-web/tasks/config.yml diff --git a/evoadmin/tasks/ftp.yml b/webapps/evoadmin-web/tasks/ftp.yml similarity index 99% rename from evoadmin/tasks/ftp.yml rename to webapps/evoadmin-web/tasks/ftp.yml index e4eacabf..83913d01 100644 --- a/evoadmin/tasks/ftp.yml +++ b/webapps/evoadmin-web/tasks/ftp.yml @@ -11,6 +11,7 @@ remote_src: no src: evolinux.conf.diff dest: /etc/proftpd/conf.d/z-evolinux.conf + # Why 440? Because should be edited with ftpasswd. # So, readonly when opened with vim. # Then readable by group. diff --git a/webapps/evoadmin-web/tasks/main.yml b/webapps/evoadmin-web/tasks/main.yml new file mode 100644 index 00000000..185549aa --- /dev/null +++ b/webapps/evoadmin-web/tasks/main.yml @@ -0,0 +1,21 @@ +--- + +- include: packages.yml + +- include: user.yml + +- include: config.yml + +- include: ssl.yml + +- include: web.yml + +- include: ftp.yml + +- name: enable evoadmin-web link in default site index + blockinfile: + dest: /var/www/index.html + marker: "" + block: | +
  • Interface admin web (EvoAdmin-web)
  • + diff --git a/evoadmin/tasks/packages.yml b/webapps/evoadmin-web/tasks/packages.yml similarity index 60% rename from evoadmin/tasks/packages.yml rename to webapps/evoadmin-web/tasks/packages.yml index f0dd16d3..e0b1fe05 100644 --- a/evoadmin/tasks/packages.yml +++ b/webapps/evoadmin-web/tasks/packages.yml @@ -1,7 +1,7 @@ --- - include_role: - name: apt-repositories + name: apt tasks_from: evolix_public.yml - meta: flush_handlers @@ -10,8 +10,15 @@ apt: name: '{{ item }}' state: present - allow_unauthenticated: yes with_items: - php-pear - php-log + +- name: Install PHP5 packages + apt: + name: '{{ item }}' + state: present + allow_unauthenticated: yes + with_items: - php5-pam + when: ansible_distribution_release == "jessie" diff --git a/webapps/evoadmin-web/tasks/remount_usr_rw.yml b/webapps/evoadmin-web/tasks/remount_usr_rw.yml new file mode 100644 index 00000000..8c51aee2 --- /dev/null +++ b/webapps/evoadmin-web/tasks/remount_usr_rw.yml @@ -0,0 +1,15 @@ +--- +- 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 diff --git a/evoadmin/tasks/ssl.yml b/webapps/evoadmin-web/tasks/ssl.yml similarity index 93% rename from evoadmin/tasks/ssl.yml rename to webapps/evoadmin-web/tasks/ssl.yml index 1eb354fc..6bdf1421 100644 --- a/evoadmin/tasks/ssl.yml +++ b/webapps/evoadmin-web/tasks/ssl.yml @@ -7,7 +7,7 @@ state: present - name: Create private key and csr for default site ({{ ansible_fqdn }}) - command: openssl req -newkey rsa:2048 -sha256 -nodes -keyout /etc/ssl/private/{{ evoadmin_host }}.key -out /etc/ssl/{{ evoadmin_host }}.csr -batch -subj "{{ evoadmin_ssl_subject }}" + command: openssl req -newkey rsa:2048 -sha256 -nodes -keyout /etc/ssl/private/{{ evoadmin_host }}.key -out /etc/ssl/{{ evoadmin_host }}.csr -batch -subj "/CN={{ evoadmin_host }}" args: creates: "/etc/ssl/private/{{ evoadmin_host }}.key" diff --git a/evoadmin/tasks/user.yml b/webapps/evoadmin-web/tasks/user.yml similarity index 62% rename from evoadmin/tasks/user.yml rename to webapps/evoadmin-web/tasks/user.yml index e3442cd1..c5e5a35b 100644 --- a/evoadmin/tasks/user.yml +++ b/webapps/evoadmin-web/tasks/user.yml @@ -12,18 +12,45 @@ name: www-evoadmin state: present +- name: "Create www-evoadmin and add to group shadow (jessie)" + user: + name: www-evoadmin + groups: shadow + append: yes + when: ansible_distribution_release == "jessie" + +- name: "Create www-evoadmin (Debian 9 or later)" + user: + name: www-evoadmin + when: ansible_distribution_major_version | version_compare('9', '>=') + - name: Install Git apt: name: git state: present -- name: Clone evoadmin repository +- name: "Clone evoadmin repository (jessie)" git: repo: https://forge.evolix.org/evoadmin-web.git dest: "{{ evoadmin_document_root}}" + version: jessie update: no # Warning: Need sudo! become_user: "{{ evoadmin_username }}" + when: ansible_distribution_release == "jessie" + +- name: "Clone evoadmin repository (Debian 9 or later)" + git: + repo: https://forge.evolix.org/evoadmin-web.git + dest: "{{ evoadmin_document_root}}" + version: master + update: yes + # Warning: Need sudo! + become_user: "{{ evoadmin_username }}" + when: ansible_distribution_major_version | version_compare('9', '>=') + +- include: remount_usr_rw.yml + when: evoadmin_scripts_dir | search ("/usr") - name: "Create {{ evoadmin_scripts_dir }}" file: @@ -46,12 +73,6 @@ with_items: - "{{ evoadmin_home_dir}}/www" -- name: Add www-evoadmin to group shadow - user: - name: www-evoadmin - groups: shadow - append: yes - - name: Add evoadmin sudoers file template: src: sudoers.j2 diff --git a/evoadmin/tasks/web.yml b/webapps/evoadmin-web/tasks/web.yml similarity index 62% rename from evoadmin/tasks/web.yml rename to webapps/evoadmin-web/tasks/web.yml index 7bbc67be..0944c2cd 100644 --- a/evoadmin/tasks/web.yml +++ b/webapps/evoadmin-web/tasks/web.yml @@ -1,13 +1,22 @@ --- -- name: Set default values in /etc/php5/apache2/conf.d/z-evolinux_defaults.ini +- name: "Set custom values for PHP config (jessie)" ini_file: - dest: /etc/php5/apache2/conf.d/z-evolinux_defaults.ini + dest: /etc/php5/apache2/conf.d/zzz-evolinux-custom.ini section: PHP option: "disable_functions" value: "shell-exec,system,passthru,putenv,popen" notify: reload apache + when: ansible_distribution_release == "jessie" +- name: "Set custom values for PHP config (Debian 9 or later)" + ini_file: + dest: /etc/php/7.0/apache2/conf.d/zzz-evolinux-custom.ini + section: PHP + option: "disable_functions" + value: "shell-exec,system,passthru,putenv,popen" + notify: reload apache + when: ansible_distribution_major_version | version_compare('9', '>=') - name: Install evoadmin VHost template: @@ -34,9 +43,6 @@ src: config.local.php.j2 dest: "{{ evoadmin_document_root}}/conf/config.local.php" mode: "0644" + owner: evoadmin + group: evoadmin force: no - -- name: add www-evoadmin to shadow group - user: - name: www-evoadmin - groups: shadow diff --git a/evoadmin/templates/config.local.php.j2 b/webapps/evoadmin-web/templates/config.local.php.j2 similarity index 100% rename from evoadmin/templates/config.local.php.j2 rename to webapps/evoadmin-web/templates/config.local.php.j2 diff --git a/evoadmin/templates/evoadmin.conf.j2 b/webapps/evoadmin-web/templates/evoadmin.conf.j2 similarity index 100% rename from evoadmin/templates/evoadmin.conf.j2 rename to webapps/evoadmin-web/templates/evoadmin.conf.j2 diff --git a/evoadmin/templates/sudoers.j2 b/webapps/evoadmin-web/templates/sudoers.j2 similarity index 100% rename from evoadmin/templates/sudoers.j2 rename to webapps/evoadmin-web/templates/sudoers.j2 diff --git a/evoadmin/templates/web-add.conf.j2 b/webapps/evoadmin-web/templates/web-add.conf.j2 similarity index 100% rename from evoadmin/templates/web-add.conf.j2 rename to webapps/evoadmin-web/templates/web-add.conf.j2 diff --git a/evoadmin/templates/web-mail.tpl.j2 b/webapps/evoadmin-web/templates/web-mail.tpl.j2 similarity index 76% rename from evoadmin/templates/web-mail.tpl.j2 rename to webapps/evoadmin-web/templates/web-mail.tpl.j2 index 82d4f67d..262995c3 100644 --- a/evoadmin/templates/web-mail.tpl.j2 +++ b/webapps/evoadmin-web/templates/web-mail.tpl.j2 @@ -1,6 +1,6 @@ -From: %MAIL_FROM% +From: {{ evoadmin_tpl_mail_from }} To: RCPTTO -Bcc: %MAIL_BCC% +Bcc: {{ evoadmin_tpl_mail_bcc }} Subject: Parametres hebergement web : LOGIN Bonjour, @@ -11,7 +11,7 @@ Votre compte d'hebergement web a ete cree. * CONNEXION SFTP/SSH ********************************** -NOM DU SERVEUR : %SERVER_NAME% +NOM DU SERVEUR : {{ evoadmin_tpl_servername }} USER : LOGIN PASSWORD : PASSE1 @@ -20,10 +20,10 @@ PASSWORD : PASSE1 ***************************************** URL du site : -http://SERVERNAME +http://{{ evoadmin_tpl_servername }} URL des stats : -http://SERVERNAME/cgi-RANDOM/awstats.pl +http://{{ evoadmin_tpl_servername }}/cgi-RANDOM/awstats.pl (acces par IP ou login a demander !) Repertoire de connexion : HOME_DIR/LOGIN/ @@ -47,20 +47,20 @@ USER : LOGIN PASSWORD : PASSE2 NOM BASE : DBNAME URL interface d'admin : -%PMA_URL% +{{ evoadmin_tpl_phpmyadmin_url }} *********************************** * Rappels divers *********************************** Votre nom de domaine doit etre configure pour pointer -sur l'adresse IP %SERVER_ADDR% (enregistrement DNS A) -ou etre un alias de %SERVER_NAME% (enregistrement DNS CNAME). +sur l'adresse IP {{ evoadmin_tpl_address }} (enregistrement DNS A) +ou etre un alias de {{ evoadmin_tpl_servername }} (enregistrement DNS CNAME). Si vous avez besoin de faire des tests, vous devez ajouter la ligne suivante au fichier "/etc/hosts" sous Linux/Unix ou au fichier "system32\drivers\etc\hosts" sous Windows NT/XP : -%SERVER_ADDR% SERVERNAME +{{ evoadmin_tpl_address }} {{ evoadmin_tpl_servername }} Attention, par defaut, toutes les connexions vers l'exterieur sont bloquees. Si vous avez besoin de recuperer des donnees @@ -71,16 +71,16 @@ Afin de securiser au maximum le serveur, certaines URL particulieres sont non autorisees pour eviter diverses attaques (XSS, robots, trojans, injections, etc.). Exemple d'URL refusee : -http://SERVERNAME/cmd32.exe +http://{{ evoadmin_tpl_servername }}/cmd32.exe En cas de soucis avec votre application, prevenez-nous. Si vous desirez mettre en place des parametres particuliers -pour votre site (PHP, etc.) ou pour tout autre demande (scripts en crontab, +pour votre site (PHP, etc.) ou pour tout autre demande (scripts en crontab, etc.), n'hesitez pas a nous contacter a l'adresse -%MAIL_STANDARD% (ou %MAIL_URGENT% si votre demande est +{{ evoadmin_tpl_mail_standard }} (ou {{ evoadmin_tpl_mail_urgent }} si votre demande est urgente). Cordialement, --- -%FOOTER% \ No newline at end of file +-- +{{ evoadmin_tpl_signature }}