Merge branch 'unstable' into stable

This commit is contained in:
Jérémy Lecour 2017-08-09 01:21:16 -04:00 committed by Jérémy Lecour
commit 6ff38593a0
40 changed files with 955 additions and 313 deletions

View file

@ -1,2 +1,3 @@
---
admin_users: {}
admin_users_group: adm

View file

@ -1,137 +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.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: uidisbusy.rc == 0
- 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
# 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: '^# ForceCommand cvs server'
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

View file

@ -0,0 +1,11 @@
---
- include: user.yml
- include: profile.yml
- include: ssh.yml
- include: sudo.yml
- meta: flush_handlers

View file

@ -1,15 +1,11 @@
---
- debug:
msg: "Warning: empty variable 'admin_users' admin-users tasks will skipped!"
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" and admin_users != {}
# - include: adduser_openbsd.yml user={{ item.value }}
# with_dict: "{{ admin_users }}"
# when: ansible_distribution == "OpenBSD"
when: admin_users != {}

View file

@ -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

66
admin-users/tasks/ssh.yml Normal file
View file

@ -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

View file

@ -0,0 +1,26 @@
---
- name: Verify Evolinux sudoers file presence
template:
src: sudoers_{{ ansible_distribution_release }}.j2
dest: /etc/sudoers.d/evolinux
force: no
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:
- ansible_distribution == "Debian"
- ansible_distribution_major_version | version_compare('9', '<')
- not copy_sudoers_evolinux.changed

View file

@ -0,0 +1,46 @@
---
- 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.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: uidisbusy.rc == 0
- name: "Create {{ admin_users_group }}"
group:
name: "{{ admin_users_group }}"
- name: "Add user to sudo group (Stretch)"
user:
name: '{{ user.name }}'
groups: 'sudo,{{ admin_users_group }}'
append: yes
when: ansible_distribution_release == "stretch"
- name: "Fix perms on homedirectory for '{{ user.name }}'"
file:
name: '/home/{{ user.name }}'
mode: "0700"
state: directory

View file

@ -0,0 +1,8 @@
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
%sudo ALL = NOPASSWD: MAINT

View file

@ -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`.

View file

@ -12,3 +12,6 @@ apache_evolinux_default_ssl_key: /etc/ssl/private/ssl-cert-snakeoil.key
apache_phpmyadmin_set: False
apache_phpmyadmin_suffix: ""
apache_serverstatus_suffix: ""
general_alert_email: "root@localhost"
log2mail_alert_email: Null

View file

@ -22,3 +22,10 @@ SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5:!RC4
<Files ~ "\.(inc|bak)$">
Require all denied
</Files>
<IfModule mod_status.c>
ExtendedStatus On
<IfModule mod_proxy.c>
ProxyStatus On
</IfModule>
</IfModule>

View file

@ -38,6 +38,7 @@
- expires
- headers
- cgi
notify: reload apache
tags:
- apache
@ -49,6 +50,7 @@
group: root
mode: "0640"
force: yes
notify: reload apache
tags:
- apache
@ -60,9 +62,16 @@
group: root
mode: "0640"
force: no
notify: reload apache
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 }}"
register: command_result
@ -70,6 +79,7 @@
with_items:
- z-evolinux-defaults.conf
- zzz-evolinux-custom.conf
notify: reload apache
tags:
- apache

View file

@ -38,67 +38,85 @@
LogLevel warn
<IfModule mod_ssl.c>
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]
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]
</IfModule>
<Location /munin_opcache.php>
Require ip 127.0.0.1
Require local
</Location>
<IfModule mod_status.c>
<Location /server-status>
SetHandler server-status
include /etc/apache2/private_ipaddr_whitelist.conf
Require local
</Location>
</IfModule>
</VirtualHost>
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName {{ ansible_fqdn }}
#ServerAlias {{ ansible_fqdn }}
<VirtualHost *:443>
ServerName {{ ansible_fqdn }}
#ServerAlias {{ ansible_fqdn }}
DocumentRoot /var/www/
DocumentRoot /var/www/
<Directory />
Include /etc/apache2/private_ipaddr_whitelist.conf
</Directory>
<Directory /var/www/>
Options -Indexes
Require all denied
Include /etc/apache2/private_ipaddr_whitelist.conf
</Directory>
<Directory />
Include /etc/apache2/private_ipaddr_whitelist.conf
</Directory>
<Directory /var/www/>
Options -Indexes
Require all denied
Include /etc/apache2/private_ipaddr_whitelist.conf
</Directory>
SSLEngine on
SSLCertificateFile {{ apache_evolinux_default_ssl_cert }}
SSLCertificateKeyFile {{ apache_evolinux_default_ssl_key }}
SSLEngine on
SSLCertificateFile {{ apache_evolinux_default_ssl_cert }}
SSLCertificateKeyFile {{ apache_evolinux_default_ssl_key }}
# We override these 2 Directory directives setted in apache2.conf.
# We want no access except from allowed IP address.
<Directory />
Include /etc/apache2/private_ipaddr_whitelist.conf
</Directory>
# We override these 2 Directory directives setted in apache2.conf.
# We want no access except from allowed IP address.
<Directory />
Include /etc/apache2/private_ipaddr_whitelist.conf
</Directory>
# Munin. We need to set Directory directive as Alias take precedence.
Alias /munin /var/cache/munin/www
<Directory /var/cache/munin/>
Require all denied
Include /etc/apache2/private_ipaddr_whitelist.conf
</Directory>
<Directory /usr/lib/munin/cgi/>
Options -Indexes
Require all denied
Include /etc/apache2/private_ipaddr_whitelist.conf
</Directory>
# Munin. We need to set Directory directive as Alias take precedence.
Alias /munin /var/cache/munin/www
<Directory /var/cache/munin/>
Require all denied
Include /etc/apache2/private_ipaddr_whitelist.conf
</Directory>
<Directory /usr/lib/munin/cgi/>
Options -Indexes
Require all denied
Include /etc/apache2/private_ipaddr_whitelist.conf
</Directory>
# For CGI Scripts. We need to set Directory directive as ScriptAlias take precedence.
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
<Directory /usr/lib/cgi-bin>
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Require all denied
Include /etc/apache2/private_ipaddr_whitelist.conf
</Directory>
# For CGI Scripts. We need to set Directory directive as ScriptAlias take precedence.
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
<Directory /usr/lib/cgi-bin>
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Require all denied
Include /etc/apache2/private_ipaddr_whitelist.conf
</Directory>
CustomLog /var/log/apache2/access.log vhost_combined
ErrorLog /var/log/apache2/error.log
LogLevel warn
</VirtualHost>
CustomLog /var/log/apache2/access.log vhost_combined
ErrorLog /var/log/apache2/error.log
LogLevel warn
<IfModule mod_status.c>
<Location /server-status>
SetHandler server-status
include /etc/apache2/private_ipaddr_whitelist.conf
Require local
</Location>
</IfModule>
</VirtualHost>
</IfModule>

View file

@ -0,0 +1,3 @@
Package: python-docker
Pin: release a=jessie-backports
Pin-Priority: 999

View file

@ -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

View file

@ -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'
- include: jessie_backports.yml
when: ansible_distribution_release == 'jessie'
- name: Add Docker's official GPG key
apt_key:
url: "https://download.docker.com/linux/debian/gpg"
state: present
- name: Install Docker repo keys
apt_key:
keyserver: pgp.mit.edu
id: 58118E89F3A912897C070ADBF76221572C52609D
- 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

View file

@ -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 %}
}

View file

@ -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

View file

@ -1,10 +1,7 @@
---
- name: restart elasticsearch
service:
name: elasticsearch
state: restarted
- name: reload elasticsearch unit
systemd:
daemon_reload: yes
name: elasticsearch
state: restarted

View file

@ -38,6 +38,6 @@
option: "LimitMEMLOCK"
value: "infinity"
notify:
- reload elasticsearch unit
- restart elasticsearch
tags:
- config

View file

@ -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"
```

View file

@ -16,8 +16,19 @@
tags:
- commit-etc
- name: fetch current Git user.email
git_config:
name: user.email
repo: /etc
scope: local
register: git_config_user_email
- name: set commit author
set_fact:
etc_git_commit_options: "{% if ansible_env.SUDO_USER %} --author \"{{ ansible_env.SUDO_USER }} <{{ git_config_user_email.config_value }}>\"{% endif %}"
- name: /etc modifications are committed
shell: "git add -A . && git commit -m \"{{ commit_message | mandatory }}\""
shell: "git add -A . && git commit -m \"{{ commit_message | mandatory }}\"{{ etc_git_commit_options }}"
args:
chdir: /etc
register: etc_commit_end_run

View file

@ -1,12 +1,12 @@
---
- name: Git is installed
- name: Git is installed (Debian)
apt:
name: git
state: present
when: ansible_os_family == "Debian"
- name: Git is installed
- name: Git is installed (OpenBSD)
openbsd_pkg:
name: git
state: present
@ -21,11 +21,11 @@
register: git_init
- name: Git user.email is configured
ini_file:
dest: /etc/.git/config
section: user
option: email
value: "<root@{{ ansible_fqdn | default('localhost.localdomain') }}>"
git_config:
name: user.email
repo: /etc
scope: local
value: "root@{{ ansible_fqdn | default('localhost') }}"
- name: /etc/.git is secure
file:

View file

@ -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

View file

@ -25,6 +25,9 @@
# Warning: Need sudo!
become_user: "{{ evoadmin_username }}"
- include: remount_usr_rw.yml
when: evoadmin_scripts_dir | search ("/usr")
- name: "Create {{ evoadmin_scripts_dir }}"
file:
dest: "{{ evoadmin_scripts_dir }}"

View file

@ -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:

View file

@ -1,29 +1,51 @@
---
- 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:
- 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 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 != []
- 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:

View file

@ -23,15 +23,22 @@
- 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:
dest: /etc/default/minifirewall
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

385
minifirewall/files/minifirewall Executable file
View file

@ -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

View file

@ -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 ...

View file

@ -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

View file

@ -15,6 +15,8 @@
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

View file

@ -119,7 +119,7 @@
- name: default vhost is enabled
file:
src: /etc/nginx/sites-available/evolinux-default.conf
dest: /etc/nginx/sites-enabled/default.conf
dest: /etc/nginx/sites-enabled/default
state: link
force: yes
notify: reload nginx

View file

@ -4,7 +4,7 @@
name: apt
tasks_from: backports.yml
tags:
- haproxy
- nginx
- packages
- name: Prefer Nginx packages from jessie-backports

View file

@ -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`.

View file

@ -1,5 +1,4 @@
---
# defaults file for packweb-apache
general_alert_email: "root@localhost"
log2mail_alert_email: Null
packweb_enable_evoadmin_vhost: True

View file

@ -1,4 +1,15 @@
- name: ensure packages are installed
- name: Ensure php5-fpm package is installed
apt:
name: php5-fpm
state: present
when: ansible_distribution_major_version | version_compare('8', '<=')
tags:
- php-fpm
- name: Ensure php-fpm packages is installed
apt:
name: php-fpm
state: present
when: ansible_distribution_major_version | version_compare('9', '>=')
tags:
- php-fpm