Merge pull request 'Release of EvoBSD 6.8.0' (#37) from dev into master
Reviewed-on: #37 Reviewed-by: Jérémy Lecour <jlecour@noreply.gitea.evolix.org>
This commit is contained in:
commit
f89751669f
30
.drone.yml
Normal file
30
.drone.yml
Normal file
|
@ -0,0 +1,30 @@
|
|||
---
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: default
|
||||
|
||||
steps:
|
||||
- name: lint markdown files
|
||||
image: pipelinecomponents/remark-lint:latest
|
||||
commands:
|
||||
- "remark --no-stdout --color --use preset-lint-recommended ."
|
||||
|
||||
- name: lint yaml files
|
||||
image: pipelinecomponents/yamllint:latest
|
||||
commands:
|
||||
- "yamllint ."
|
||||
|
||||
- name: lint ansible scripts
|
||||
image: pipelinecomponents/ansible-lint:latest
|
||||
commands:
|
||||
- >
|
||||
find . -maxdepth 1 -name '*.yml'
|
||||
| sort
|
||||
| grep -v '.drone.yml'
|
||||
| xargs ansible-playbook --syntax-check --list-tasks
|
||||
|
||||
- >
|
||||
find . -maxdepth 1 -name '*.yml'
|
||||
| sort
|
||||
| grep -v '.drone.yml'
|
||||
| xargs ansible-lint
|
75
CHANGELOG
Normal file
75
CHANGELOG
Normal file
|
@ -0,0 +1,75 @@
|
|||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [6.8.0] - 2020-10-23
|
||||
|
||||
### Added
|
||||
|
||||
- Add a PF tag to be able to skip that part when rerunning EvoBSD
|
||||
- Add a doas authorization for NRPE check_ipsecctl_critiques
|
||||
|
||||
### Changed
|
||||
|
||||
- The task mail.yml replace the former boot/reboot message only if it is untouched
|
||||
- Replace the variable used to set the email address in etc-git role - now using inventory_hostname
|
||||
- Not checking syspatch when OpenBSD <= 6.1
|
||||
- Amend fstab file adding noatime option to each entrie
|
||||
- Import evocheck v.6.7.7
|
||||
- Comment NRPE checks that cannot be used as is
|
||||
|
||||
### Fixed
|
||||
|
||||
- Add the creation of the NRPE plugins directory in nagios-nrpe role
|
||||
- Add collectd doas rights in the base role to avoid broking anything if EvoBSD is rerun without the collectd role included
|
||||
- Do not add the motd cron if the same line is already there but uncommented
|
||||
- Amend fstab entries only when the filesystem is ffs
|
||||
|
||||
## [6.7.2] - 2020-10-13
|
||||
|
||||
### Added
|
||||
|
||||
- Now handling deletion of evobackup crontab (replaced by daily.local cron)
|
||||
- Customize fstab with noexec and softdep
|
||||
- Collectd role
|
||||
|
||||
### Changed
|
||||
|
||||
- Improve rc.local file configuration
|
||||
- Update evocheck to version 6.7.5
|
||||
- Hide default daily output mail content (VERBOSESTATUS=0)
|
||||
- Add deletion of old log files in the OSPF role
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix duplicate evobackup cron if the entry is uncommented in daily.local
|
||||
|
||||
## [6.7.1] - 2020-09-10
|
||||
|
||||
### Added
|
||||
|
||||
- Add completions functions in root's profile dotfile
|
||||
- Add check_connections_state.sh NRPE plugin
|
||||
- Add an evocheck role
|
||||
- Add stricter ssh and doas access
|
||||
- Add an openvpn role
|
||||
- Add an OpenBGPd NRPE plugin
|
||||
- Add ospf and bgp roles
|
||||
- Add an unbound NRPE check since it is part of the base system
|
||||
- Add a motd-carp-state.sh script that checks the carp state and generates the /etc/motd file
|
||||
|
||||
### Changed
|
||||
|
||||
- Disable sndiod since it is not required on serveurs
|
||||
- Replace sudo with doas for script executions
|
||||
- Update evomaintenance version to 0.6.3
|
||||
- Disable mouse function in vim configuration
|
||||
- Drop openup since syspatch can apply stable patches now
|
||||
- Update evobackup script
|
||||
- Rewrite newsyslog configuration
|
||||
- Drop postgresql-client package since evomaintenance use an API now
|
|
@ -2,17 +2,17 @@
|
|||
|
||||
Contributions are welcome, as long as they respect our current workflow:
|
||||
|
||||
1. The master branch is only for releases. Once properly tested,
|
||||
the dev branch can be merged, the release tagged and a tar archive
|
||||
created.
|
||||
1. The master branch is only for releases. Once properly tested,
|
||||
the dev branch can be merged, the release tagged and a tar archive
|
||||
created.
|
||||
|
||||
2. The dev branch should never be commited to directly, unless
|
||||
you're updating the CHANGELOG file.
|
||||
2. The dev branch should never be commited to directly, unless
|
||||
you're updating the CHANGELOG file.
|
||||
|
||||
3. Use feature branches for anything else, once they've passed all
|
||||
CI tests and have been reviewed by other contributors through a
|
||||
pull request, they may be merged into the dev branch.
|
||||
3. Use feature branches for anything else, once they've passed all
|
||||
CI test, lints and have been reviewed by other contributors through a
|
||||
pull request, they may be merged into the dev branch.
|
||||
|
||||
|
||||
Open issues liberally, but please review closed and opened issues
|
||||
for duplicates before hand.
|
||||
for duplicates before hand.
|
||||
|
|
2
LICENSE
2
LICENSE
|
@ -1,6 +1,6 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2019 Evolix
|
||||
Copyright (c) 2020 Evolix
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
134
README.md
134
README.md
|
@ -1,4 +1,4 @@
|
|||
# EvoBSD 1.0
|
||||
# EvoBSD 6.8.0
|
||||
|
||||
EvoBSD is an ansible project used for customising OpenBSD hosts
|
||||
used by Evolix.
|
||||
|
@ -9,16 +9,24 @@ used by Evolix.
|
|||
Put your public key in the remote root's autorized_keys
|
||||
(/root/.ssh/authorized_keys)
|
||||
|
||||
1 - Install ansible's prerequisites
|
||||
1. Install ansible's prerequisites
|
||||
|
||||
```
|
||||
ansible-playbook prerequisite.yml -CDi hosts -l HOSTNAME
|
||||
```
|
||||
|
||||
2 - Run it
|
||||
2. Run it
|
||||
|
||||
First use (become_method: su) :
|
||||
|
||||
```
|
||||
ansible-playbook evolixisation.yml --ask-vault-pass -CDKi hosts -l HOSTNAME
|
||||
ansible-playbook evolixisation.yml --ask-vault-pass -CDki hosts -u root -l HOSTNAME
|
||||
```
|
||||
|
||||
Subsequent use (become_method: sudo) :
|
||||
|
||||
```
|
||||
ansible-playbook evolixisation.yml --ask-vault-pass -CDKi hosts --skip-tags pf -l HOSTNAME
|
||||
```
|
||||
|
||||
### Testing
|
||||
|
@ -26,100 +34,40 @@ ansible-playbook evolixisation.yml --ask-vault-pass -CDKi hosts -l HOSTNAME
|
|||
Changes can be tested by using [Packer](https://www.packer.io/) and
|
||||
[vmm(4)](https://man.openbsd.org/vmm.4) :
|
||||
|
||||
* This process depends on the [Go](https://golang.org/) programming language.
|
||||
* This process depends on the [Go](https://golang.org/) programming language.
|
||||
|
||||
**Packages**
|
||||
|
||||
Needing a Golang eco system and some basics
|
||||
|
||||
````
|
||||
pkg_add go-- packer-- git--
|
||||
````
|
||||
|
||||
* We use the [packer-builder-openbsd-vmm](https://github.com/double-p/packer-builder-openbsd-vmm) project to bridge Packer and vmm(4)
|
||||
|
||||
````
|
||||
git clone https://github.com/double-p/packer-builder-openbsd-vmm.git
|
||||
````
|
||||
|
||||
**builds**
|
||||
|
||||
Set ````GOPATH```` (default: ~/go), if the 1.4GB dependencies wont fit.
|
||||
|
||||
````
|
||||
make
|
||||
make install
|
||||
````
|
||||
|
||||
* You need your unprivileged user to be able to run vmctl(8) through doas(1)
|
||||
|
||||
```
|
||||
# pkg_add go packer
|
||||
echo "permit nopass myunprivilegeduser as root cmd /usr/sbin/vmctl" >> /etc/doas.conf
|
||||
```
|
||||
|
||||
* We use the [packer-builder-vmm](https://github.com/prep/packer-builder-vmm) project to bridge Packer and vmm(4)
|
||||
See packer-builder-openbsd-vmm/examples/README.examples for further instructions
|
||||
|
||||
```
|
||||
$ go get -u github.com/prep/packer-builder-vmm/cmd/packer-builder-vmm
|
||||
```
|
||||
|
||||
* Here is an example build file
|
||||
|
||||
```
|
||||
$ vim openbsd.json
|
||||
```
|
||||
|
||||
{
|
||||
"description": "OpenBSD installation on vmm(4)",
|
||||
|
||||
"variables": {
|
||||
"hostname": "evobsd",
|
||||
"domain": "example.com",
|
||||
|
||||
"password": "evolix"
|
||||
},
|
||||
|
||||
"builders": [
|
||||
{
|
||||
"type": "vmm",
|
||||
"vm_name": "evobsd",
|
||||
"disk_size": "2G",
|
||||
"format": "qcow2",
|
||||
"mem_size": "1024M",
|
||||
|
||||
"iso_urls": ["downloads/install64.fs", "https://ftp.nluug.nl/pub/OpenBSD/6.4/amd64/install64.fs"],
|
||||
"iso_checksum": "7aa4344cb39efbf67300f97ac7eec005b607e8c19d4e31a0a593a8ee2b7136e4",
|
||||
"iso_checksum_type": "sha256",
|
||||
|
||||
"boot_wait": "10s",
|
||||
"boot_command": [
|
||||
"S<enter>",
|
||||
|
||||
"cat <<EOF >disklabel.template<enter>",
|
||||
"/ 1G-* 100%<enter>",
|
||||
"EOF<enter>",
|
||||
|
||||
"cat <<EOF >install.conf<enter>",
|
||||
"System hostname = {{user `hostname`}}<enter>",
|
||||
"DNS domain name = {{user `domain`}}<enter>",
|
||||
"Password for root account = {{user `password`}}<enter>",
|
||||
"Do you expect to run the X Window System = no<enter>",
|
||||
"Setup a user = no<enter>",
|
||||
"Which disk is the root disk = sd1<enter>",
|
||||
"Use (A)uto layout, (E)dit auto layout, or create (C)ustom layout = c<enter>",
|
||||
"URL to autopartitioning template for disklabel = file://disklabel.template<enter>",
|
||||
"Location of sets = disk<enter>",
|
||||
"Is the disk partition already mounted = no<enter>",
|
||||
"Set name(s) = -bsd.rd<enter>",
|
||||
"Set name(s) = done<enter>",
|
||||
"Directory does not contain SHA256.sig. Continue without verification = yes<enter>",
|
||||
"What timezone are you in = Europe/Paris<enter>",
|
||||
"EOF<enter>",
|
||||
|
||||
"install -af install.conf<enter>",
|
||||
"<wait2m>",
|
||||
|
||||
"/sbin/halt -p<enter><wait15>"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
* You need your unprivileged user to be able to run vmctl(8) through doas(1)
|
||||
|
||||
```
|
||||
# echo "permit nopass myunprivilegeduser as root cmd /usr/sbin/vmctl" >> /etc/doas.conf
|
||||
```
|
||||
|
||||
* Build the virtual machine
|
||||
|
||||
```
|
||||
$ packer build openbsd.json
|
||||
```
|
||||
|
||||
* Start it
|
||||
|
||||
```
|
||||
doas vmctl start evobsd -cL -d output-vmm/evobsd.qcow2
|
||||
```
|
||||
|
||||
* Enable NAT on your host machine
|
||||
* Enable NAT on your host machine
|
||||
|
||||
```
|
||||
pass out on em0 inet from tap0:network to any nat-to (em0)
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
# yamllint disable rule:line-length
|
||||
# Playbook command
|
||||
# ansible-playbook evolixisation.yml --ask-vault-pass -CDKi hosts -l HOSTNAME
|
||||
# First use (become_method: su) :
|
||||
# ansible-playbook evolixisation.yml --ask-vault-pass -CDki hosts -u root -l HOSTNAME
|
||||
# Subsequent use (become_method: sudo) :
|
||||
# ansible-playbook evolixisation.yml --ask-vault-pass -CDKi hosts --skip-tags pf -l HOSTNAME
|
||||
|
||||
---
|
||||
- name: Evolixisation of an OpenBSD system
|
||||
|
@ -7,11 +11,13 @@
|
|||
become: true
|
||||
become_user: root
|
||||
become_method: sudo
|
||||
# become_method: su
|
||||
|
||||
|
||||
vars_files:
|
||||
- vars/main.yml
|
||||
# - vars/secrets.yml
|
||||
- vars/secrets.yml
|
||||
- vars/openbsd-secret.yml
|
||||
|
||||
roles:
|
||||
- etc-git
|
||||
|
@ -20,14 +26,20 @@
|
|||
- pf
|
||||
- accounts
|
||||
- nagios-nrpe
|
||||
- evocheck
|
||||
- post-install
|
||||
# - openvpn
|
||||
# - ospf
|
||||
# - bgp
|
||||
# - { role: collectd, collectd_server: "127.0.0.1" }
|
||||
|
||||
post_tasks:
|
||||
- include: "tasks/commit_etc_git.yml"
|
||||
vars:
|
||||
commit_message: "Ansible - Evolixisation"
|
||||
- include_role:
|
||||
name: evocheck
|
||||
tasks_from: exec.yml
|
||||
|
||||
environment:
|
||||
PKG_PATH: "http://ftp.openbsd.org/pub/OpenBSD/{{ ansible_distribution_version }}/packages/{{ ansible_architecture }}/"
|
||||
|
||||
# vim:ft=ansible
|
||||
# environment:
|
||||
# PKG_PATH: "http://ftp.openbsd.org/pub/OpenBSD/{{ ansible_distribution_version }}/packages/{{ ansible_architecture }}/"
|
||||
|
|
2
hosts
2
hosts
|
@ -2,4 +2,4 @@
|
|||
foo.example.com
|
||||
|
||||
[openbsd:vars]
|
||||
ansible_python_interpreter=/usr/local/bin/python2.7
|
||||
ansible_python_interpreter=/usr/local/bin/python3
|
||||
|
|
|
@ -2,15 +2,16 @@
|
|||
# ansible-playbook prerequisite.yml -CDi hosts -l HOSTNAME
|
||||
|
||||
---
|
||||
- hosts: all
|
||||
become: yes
|
||||
become_method: su
|
||||
user: root
|
||||
gather_facts: no
|
||||
- hosts: all
|
||||
become: true
|
||||
become_method: su
|
||||
user: root
|
||||
gather_facts: false
|
||||
|
||||
tasks:
|
||||
tasks:
|
||||
|
||||
- name: Install ansible's prerequisite
|
||||
raw: export PKG_PATH=http://ftp.eu.openbsd.org/pub/OpenBSD/$(uname -r)/packages/$(uname -p)/; pkg_add -z python-2
|
||||
# yamllint disable-line rule:line-length
|
||||
raw: export PKG_PATH=http://ftp.eu.openbsd.org/pub/OpenBSD/$(uname -r)/packages/$(uname -p)/; pkg_add -z python-3
|
||||
|
||||
# vim:ft=ansible
|
||||
|
|
6
roles/accounts/handlers/main.yml
Normal file
6
roles/accounts/handlers/main.yml
Normal file
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
|
||||
- name: reload sshd
|
||||
service:
|
||||
name: sshd
|
||||
state: reloaded
|
|
@ -1,7 +1,85 @@
|
|||
---
|
||||
- name: "Create {{ evobsd_ssh_group }} group"
|
||||
group:
|
||||
name: "{{ evobsd_ssh_group }}"
|
||||
system: true
|
||||
|
||||
- name: "Create {{ evobsd_sudo_group }} group"
|
||||
group:
|
||||
name: "{{ evobsd_sudo_group }}"
|
||||
system: true
|
||||
|
||||
- name: Create user accounts
|
||||
include: user.yml
|
||||
vars:
|
||||
user: "{{ item.value }}"
|
||||
with_dict: "{{ evolinux_users }}"
|
||||
when: evolinux_users != {}
|
||||
with_dict: "{{ evolix_users }}"
|
||||
when: evolix_users != {}
|
||||
|
||||
- name: verify AllowGroups directive
|
||||
command: "grep -E '^AllowGroups' /etc/ssh/sshd_config"
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
check_mode: false
|
||||
register: grep_allowgroups_ssh
|
||||
|
||||
- name: verify AllowUsers directive
|
||||
command: "grep -E '^AllowUsers' /etc/ssh/sshd_config"
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
check_mode: false
|
||||
register: grep_allowusers_ssh
|
||||
|
||||
- name: "Check that AllowUsers and AllowGroup do not override each other"
|
||||
assert:
|
||||
that: "not (grep_allowusers_ssh.rc == 0 and grep_allowgroups_ssh.rc == 0)"
|
||||
msg: "We can't deal with AllowUsers and AllowGroups at the same time"
|
||||
|
||||
- name: "If AllowGroups is present then use it"
|
||||
set_fact:
|
||||
ssh_allowgroups:
|
||||
"{{ (grep_allowgroups_ssh.rc == 0) or (grep_allowusers_ssh.rc != 0) }}"
|
||||
|
||||
- name: "Add AllowGroups sshd directive with '{{ evobsd_ssh_group }}'"
|
||||
lineinfile:
|
||||
dest: /etc/ssh/sshd_config
|
||||
line: "\nAllowGroups {{ evobsd_ssh_group }}"
|
||||
insertafter: 'Subsystem'
|
||||
validate: '/usr/sbin/sshd -t -f %s'
|
||||
notify: reload sshd
|
||||
when:
|
||||
- ssh_allowgroups
|
||||
- grep_allowgroups_ssh.rc == 1
|
||||
|
||||
- name: "Append '{{ evobsd_ssh_group }}' to AllowGroups sshd directive"
|
||||
replace:
|
||||
dest: /etc/ssh/sshd_config
|
||||
regexp: '^(AllowGroups ((?!\b{{ evobsd_ssh_group }}\b).)*)$'
|
||||
replace: '\1 {{ evobsd_ssh_group }}'
|
||||
validate: '/usr/sbin/sshd -t -f %s'
|
||||
notify: reload sshd
|
||||
when:
|
||||
- ssh_allowgroups
|
||||
- grep_allowgroups_ssh.rc == 0
|
||||
|
||||
- name: "Security directives for EvoBSD"
|
||||
blockinfile:
|
||||
dest: /etc/ssh/sshd_config
|
||||
marker: "# {mark} EVOBSD PASSWORD RESTRICTIONS"
|
||||
block: |
|
||||
Match Address {{ evolix_trusted_ips | join(',') }}
|
||||
PasswordAuthentication yes
|
||||
Match Group {{ evobsd_ssh_group }}
|
||||
PasswordAuthentication no
|
||||
insertafter: EOF
|
||||
validate: '/usr/sbin/sshd -t -f %s'
|
||||
notify: reload sshd
|
||||
when:
|
||||
- evolix_trusted_ips != []
|
||||
|
||||
- name: "Disable root login"
|
||||
replace:
|
||||
dest: /etc/ssh/sshd_config
|
||||
regexp: '^PermitRootLogin (yes|without-password|prohibit-password)'
|
||||
replace: "PermitRootLogin no"
|
||||
notify: reload sshd
|
||||
|
|
|
@ -1,16 +1,31 @@
|
|||
---
|
||||
- name: "Group '{{ user.name }}' is present"
|
||||
group:
|
||||
state: present
|
||||
name: "{{ user.name }}"
|
||||
gid: "{{ user.uid }}"
|
||||
|
||||
- name: "User '{{ user.name }}' is present"
|
||||
user:
|
||||
state: present
|
||||
name: '{{ user.name }}'
|
||||
uid: '{{ user.uid }}'
|
||||
password: '{{ user.password_hash_openbsd }}'
|
||||
group: "{{ user.name }}"
|
||||
groups: wheel
|
||||
shell: /bin/ksh
|
||||
append: yes
|
||||
append: true
|
||||
tags:
|
||||
- admin
|
||||
|
||||
- name: "Home directory for '{{ user.name }}' is only accesible by owner"
|
||||
file:
|
||||
name: '/home/{{ user.name }}'
|
||||
mode: "0700"
|
||||
owner: "{{ user.name }}"
|
||||
group: "{{ user.name }}"
|
||||
state: directory
|
||||
|
||||
- name: "SSH public keys for '{{ user.name }}' are present"
|
||||
authorized_key:
|
||||
user: "{{ user.name }}"
|
||||
|
@ -21,4 +36,20 @@
|
|||
loop_var: ssk_key
|
||||
when: user.ssh_keys is defined
|
||||
tags:
|
||||
- admin
|
||||
- admin
|
||||
|
||||
- name: "Add {{ user.name }} to {{ evobsd_ssh_group }} group"
|
||||
user:
|
||||
name: "{{ user.name }}"
|
||||
groups: "{{ evobsd_ssh_group }}"
|
||||
append: true
|
||||
tags:
|
||||
- admin
|
||||
|
||||
- name: "Add {{ user.name }} to {{ evobsd_sudo_group }} group"
|
||||
user:
|
||||
name: "{{ user.name }}"
|
||||
groups: "{{ evobsd_sudo_group }}"
|
||||
append: true
|
||||
tags:
|
||||
- admin
|
||||
|
|
|
@ -1,19 +1,39 @@
|
|||
---
|
||||
ntpd_servers:
|
||||
- "ntp.evolix.net"
|
||||
- "ntp.evolix.net"
|
||||
|
||||
general_alert_email: "root@localhost"
|
||||
general_technical_realm: "example.com"
|
||||
|
||||
evomaintenance_realm: "example.com"
|
||||
evomaintenance_alert_email: "evomaintenance-{{ inventory_hostname }}@{{ evomaintenance_realm }}"
|
||||
evomaintenance_hostname: "{{ inventory_hostname }}.{{ general_technical_realm }}"
|
||||
evomaintenance_pg_host: Null
|
||||
evomaintenance_pg_passwd: Null
|
||||
evomaintenance_pg_db: Null
|
||||
evomaintenance_pg_table: Null
|
||||
evomaintenance_alert_email:
|
||||
"evomaintenance-{{ inventory_hostname }}@{{ evomaintenance_realm }}"
|
||||
evomaintenance_hostname:
|
||||
"{{ inventory_hostname }}.{{ general_technical_realm }}"
|
||||
evomaintenance_pg_host: null
|
||||
evomaintenance_pg_passwd: null
|
||||
evomaintenance_pg_db: null
|
||||
evomaintenance_pg_table: null
|
||||
evomaintenance_from_domain: "{{ evomaintenance_realm }}"
|
||||
evomaintenance_from: "evomaintenance@{{ evomaintenance_from_domain }}"
|
||||
evomaintenance_full_from: "Evomaintenance <{{ evomaintenance_from }}>"
|
||||
evomaintenance_urgency_from: mama.doe@example.com
|
||||
evomaintenance_urgency_tel: "06.00.00.00.00"
|
||||
evomaintenance_install_vendor: false
|
||||
evomaintenance_force_config: true
|
||||
evomaintenance_api_endpoint: null
|
||||
evomaintenance_api_key: null
|
||||
evomaintenance_hook_api: true
|
||||
evomaintenance_hook_db: false
|
||||
evomaintenance_hook_commit: true
|
||||
evomaintenance_hook_mail: true
|
||||
evomaintenance_default_hosts: []
|
||||
evomaintenance_additional_hosts: []
|
||||
evomaintenance_hosts: >
|
||||
{{ evomaintenance_default_hosts
|
||||
| union(evomaintenance_additional_hosts)
|
||||
| unique }}
|
||||
|
||||
evobsd_path: >-
|
||||
"$HOME/bin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin"
|
||||
cron_root_path: "/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin"
|
||||
|
|
|
@ -4,82 +4,489 @@
|
|||
# Dependencies (all OS): git postgresql-client
|
||||
# Dependencies (Debian): sudo
|
||||
|
||||
# version 0.4.1
|
||||
# Copyright 2007-2018 Evolix <info@evolix.fr>
|
||||
# Copyright 2007-2019 Evolix <info@evolix.fr>, Gregory Colpart <reg@evolix.fr>,
|
||||
# Jérémy Lecour <jlecour@evolix.fr> and others.
|
||||
|
||||
VERSION="0.6.3"
|
||||
|
||||
show_version() {
|
||||
cat <<END
|
||||
evomaintenance version ${VERSION}
|
||||
|
||||
Copyright 2007-2019 Evolix <info@evolix.fr>,
|
||||
Gregory Colpart <reg@evolix.fr>,
|
||||
Jérémy Lecour <jlecour@evolix.fr>
|
||||
and others.
|
||||
|
||||
evomaintenance comes with ABSOLUTELY NO WARRANTY. This is free software,
|
||||
and you are welcome to redistribute it under certain conditions.
|
||||
See the GNU General Public Licence for details.
|
||||
END
|
||||
}
|
||||
|
||||
show_help() {
|
||||
cat <<END
|
||||
evomaintenance is a program that helps reporting what you've done on a server
|
||||
|
||||
Usage: evomaintenance
|
||||
or evomaintenance --message="add new host"
|
||||
or evomaintenance --no-api --no-mail --no-commit
|
||||
or echo "add new vhost" | evomaintenance
|
||||
|
||||
Options
|
||||
-m, --message=MESSAGE set the message from the command line
|
||||
--mail enable the mail hook (default)
|
||||
--no-mail disable the mail hook
|
||||
--db enable the database hook
|
||||
--no-db disable the database hook (default)
|
||||
--api enable the API hook (default)
|
||||
--no-api disable the API hook
|
||||
--commit enable the commit hook (default)
|
||||
--no-commit disable the commit hook
|
||||
--evocheck enable evocheck execution (default)
|
||||
--no-evocheck disable evocheck execution
|
||||
--auto use "auto" mode
|
||||
--no-auto use "manual" mode (default)
|
||||
-v, --verbose increase verbosity
|
||||
-n, --dry-run actions are not executed
|
||||
--help print this message and exit
|
||||
--version print version and exit
|
||||
END
|
||||
}
|
||||
|
||||
syslog() {
|
||||
if [ -x "${LOGGER_BIN}" ]; then
|
||||
${LOGGER_BIN} -t "evomaintenance" "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
get_system() {
|
||||
uname -s
|
||||
uname -s
|
||||
}
|
||||
|
||||
get_fqdn() {
|
||||
if [ "$(get_system)" = "Linux" ]; then
|
||||
hostname --fqdn
|
||||
elif [ "$(get_system)" = "OpenBSD" ]; then
|
||||
hostname
|
||||
else
|
||||
echo "OS not detected!"
|
||||
exit 1
|
||||
fi
|
||||
if [ "$(get_system)" = "Linux" ]; then
|
||||
hostname --fqdn
|
||||
elif [ "$(get_system)" = "OpenBSD" ]; then
|
||||
hostname
|
||||
else
|
||||
echo "OS not detected!"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
get_tty() {
|
||||
if [ "$(get_system)" = "Linux" ]; then
|
||||
ps -o tty= | tail -1
|
||||
elif [ "$(get_system)" = "OpenBSD" ]; then
|
||||
env | grep SSH_TTY | cut -d"/" -f3
|
||||
else
|
||||
echo "OS not detected!"
|
||||
exit 1
|
||||
fi
|
||||
if [ "$(get_system)" = "Linux" ]; then
|
||||
ps -o tty= | tail -1
|
||||
elif [ "$(get_system)" = "OpenBSD" ]; then
|
||||
env | grep SSH_TTY | cut -d"/" -f3
|
||||
else
|
||||
echo "OS not detected!"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
get_who() {
|
||||
who=$(LC_ALL=C who -m)
|
||||
who=$(LC_ALL=C who -m | tr -s ' ')
|
||||
|
||||
if [ -n "${who}" ]; then
|
||||
echo "${who}"
|
||||
else
|
||||
LC_ALL=C who | grep $(get_tty) | tr -s ' '
|
||||
fi
|
||||
if [ -n "${who}" ]; then
|
||||
echo "${who}"
|
||||
else
|
||||
LC_ALL=C who | grep "$(get_tty)" | tr -s ' '
|
||||
fi
|
||||
}
|
||||
|
||||
get_begin_date() {
|
||||
echo "$(date "+%Y") $(echo $(get_who) | cut -d" " -f3,4,5)"
|
||||
printf "%s %s" "$(date "+%Y")" "$(get_who | cut -d" " -f3,4,5)"
|
||||
}
|
||||
|
||||
get_ip() {
|
||||
ip=$(echo $(get_who) | cut -d" " -f6 | sed -e "s/^(// ; s/)$//")
|
||||
[ -z "${ip}" ] && ip="unknown (no tty)"
|
||||
[ "${ip}" = ":0" ] && ip="localhost"
|
||||
ip=$(get_who | cut -d" " -f6 | sed -e "s/^(// ; s/)$//")
|
||||
[ -z "${ip}" ] && ip="unknown (no tty)"
|
||||
[ "${ip}" = ":0" ] && ip="localhost"
|
||||
|
||||
echo "${ip}"
|
||||
echo "${ip}"
|
||||
}
|
||||
|
||||
get_end_date() {
|
||||
date +"%Y %b %d %H:%M"
|
||||
date +"%Y %b %d %H:%M"
|
||||
}
|
||||
|
||||
get_now() {
|
||||
date +"%Y-%m-%dT%H:%M:%S%z"
|
||||
date +"%Y-%m-%dT%H:%M:%S%z"
|
||||
}
|
||||
|
||||
get_complete_hostname() {
|
||||
REAL_HOSTNAME=$(get_fqdn)
|
||||
if [ "${HOSTNAME}" = "${REAL_HOSTNAME}" ]; then
|
||||
echo "${HOSTNAME}"
|
||||
else
|
||||
echo "${HOSTNAME} (${REAL_HOSTNAME})"
|
||||
fi
|
||||
}
|
||||
|
||||
get_repository_status() {
|
||||
dir=$1
|
||||
# tell Git where to find the repository and the work tree (no need to `cd …` there)
|
||||
export GIT_DIR="${dir}/.git" GIT_WORK_TREE="${dir}"
|
||||
# If the repository and the work tree exist, try to commit changes
|
||||
if [ -d "${GIT_DIR}" ] && [ -d "${GIT_WORK_TREE}" ]; then
|
||||
CHANGED_LINES=$(${GIT_BIN} status --porcelain | wc -l | tr -d ' ')
|
||||
if [ "${CHANGED_LINES}" != "0" ]; then
|
||||
STATUS=$(${GIT_BIN} status --short | tail -n ${GIT_STATUS_MAX_LINES})
|
||||
printf "%s\n%s\n" "${GIT_DIR} (last ${GIT_STATUS_MAX_LINES} lines)" "${STATUS}" | sed -e '/^$/d'
|
||||
fi
|
||||
fi
|
||||
# unset environment variables to prevent accidental influence on other git commands
|
||||
unset GIT_DIR GIT_WORK_TREE
|
||||
}
|
||||
|
||||
get_evocheck() {
|
||||
if [ -x "${EVOCHECK_BIN}" ]; then
|
||||
printf "Evocheck status :"
|
||||
EVOCHECK_OUT=$(${EVOCHECK_BIN})
|
||||
EVOCHECK_RC=$?
|
||||
|
||||
if [ "${EVOCHECK_RC}" = "0" ] && [ -z "${EVOCHECK_OUT}" ]; then
|
||||
printf " OK\n\n"
|
||||
else
|
||||
printf " ERROR\n%s\n\n" "${EVOCHECK_OUT}"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
print_log() {
|
||||
printf "*********** %s ***************\n" "$(get_now)"
|
||||
print_session_data
|
||||
printf "Hooks : commit=%s db=%s api=%s mail=%s\n"\
|
||||
"${HOOK_COMMIT}" "${HOOK_DB}" "${HOOK_API}" "${HOOK_MAIL}"
|
||||
if [ "${HOOK_MAIL}" = "1" ]; then
|
||||
printf "Mailto : %s\n" "${EVOMAINTMAIL}"
|
||||
fi
|
||||
}
|
||||
|
||||
print_session_data() {
|
||||
printf "Host : %s\n" "${HOSTNAME_TEXT}"
|
||||
printf "User : %s\n" "${USER}"
|
||||
printf "IP : %s\n" "${IP}"
|
||||
printf "Begin : %s\n" "${BEGIN_DATE}"
|
||||
printf "End : %s\n" "${END_DATE}"
|
||||
printf "Message : %s\n" "${MESSAGE}"
|
||||
}
|
||||
|
||||
is_repository_readonly() {
|
||||
if [ "$(get_system)" = "OpenBSD" ]; then
|
||||
partition=$(stat -f '%Sd' $1)
|
||||
mount | grep ${partition} | grep -q "read-only"
|
||||
else
|
||||
mountpoint=$(stat -c '%m' $1)
|
||||
findmnt ${mountpoint} --noheadings --output OPTIONS -O ro
|
||||
fi
|
||||
}
|
||||
remount_repository_readwrite() {
|
||||
if [ "$(get_system)" = "OpenBSD" ]; then
|
||||
partition=$(stat -f '%Sd' $1)
|
||||
mount -u -w /dev/${partition} 2>/dev/null
|
||||
else
|
||||
mountpoint=$(stat -c '%m' $1)
|
||||
mount -o remount,rw ${mountpoint}
|
||||
syslog "Re-mount ${mountpoint} as read-write to commit in repository $1"
|
||||
fi
|
||||
}
|
||||
remount_repository_readonly() {
|
||||
if [ "$(get_system)" = "OpenBSD" ]; then
|
||||
partition=$(stat -f '%Sd' $1)
|
||||
mount -u -r /dev/${partition} 2>/dev/null
|
||||
else
|
||||
mountpoint=$(stat -c '%m' $1)
|
||||
mount -o remount,ro ${mountpoint} 2>/dev/null
|
||||
syslog "Re-mount ${mountpoint} as read-only after commit to repository $1"
|
||||
fi
|
||||
}
|
||||
|
||||
hook_commit() {
|
||||
if [ -x "${GIT_BIN}" ]; then
|
||||
# loop on possible directories managed by GIT
|
||||
for dir in ${GIT_REPOSITORIES}; do
|
||||
# tell Git where to find the repository and the work tree (no need to `cd …` there)
|
||||
export GIT_DIR="${dir}/.git" GIT_WORK_TREE="${dir}"
|
||||
# reset variable used to track if a mount point is readonly
|
||||
READONLY_ORIG=0
|
||||
# If the repository and the work tree exist, try to commit changes
|
||||
if [ -d "${GIT_DIR}" ] && [ -d "${GIT_WORK_TREE}" ]; then
|
||||
CHANGED_LINES=$(${GIT_BIN} status --porcelain | wc -l | tr -d ' ')
|
||||
if [ "${CHANGED_LINES}" != "0" ]; then
|
||||
if [ "${DRY_RUN}" = "1" ]; then
|
||||
# STATS_SHORT=$(${GIT_BIN} diff --stat | tail -1)
|
||||
STATS=$(${GIT_BIN} diff --stat | tail -n ${GIT_STATUS_MAX_LINES})
|
||||
# GIT_COMMITS_SHORT=$(printf "%s\n%s : %s" "${GIT_COMMITS_SHORT}" "${GIT_DIR}" "${STATS_SHORT}" | sed -e '/^$/d')
|
||||
GIT_COMMITS=$(printf "%s\n%s\n%s" "${GIT_COMMITS}" "${GIT_DIR}" "${STATS}" | sed -e '/^$/d')
|
||||
else
|
||||
# remount mount point read-write if currently readonly
|
||||
is_repository_readonly ${dir} && { READONLY_ORIG=1; remount_repository_readwrite ${dir}; }
|
||||
# commit changes
|
||||
${GIT_BIN} add --all
|
||||
${GIT_BIN} commit --message "${MESSAGE}" --author="${USER} <${USER}@evolix.net>" --quiet
|
||||
# remount mount point read-only if it was before
|
||||
test "$READONLY_ORIG" = "1" && remount_repository_readonly ${dir}
|
||||
# Add the SHA to the log file if something has been committed
|
||||
SHA=$(${GIT_BIN} rev-parse --short HEAD)
|
||||
# STATS_SHORT=$(${GIT_BIN} show --stat | tail -1)
|
||||
STATS=$(${GIT_BIN} show --stat --pretty=format:"" | tail -n ${GIT_STATUS_MAX_LINES})
|
||||
# append commit data, without empty lines
|
||||
# GIT_COMMITS_SHORT=$(printf "%s\n%s : %s –%s" "${GIT_COMMITS_SHORT}" "${GIT_DIR}" "${SHA}" "${STATS_SHORT}" | sed -e '/^$/d')
|
||||
GIT_COMMITS=$(printf "%s\n%s : %s\n%s" "${GIT_COMMITS}" "${GIT_DIR}" "${SHA}" "${STATS}" | sed -e '/^$/d')
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
# unset environment variables to prevent accidental influence on other git commands
|
||||
unset GIT_DIR GIT_WORK_TREE
|
||||
done
|
||||
|
||||
if [ -n "${GIT_COMMITS}" ]; then
|
||||
# if [ "${VERBOSE}" = "1" ]; then
|
||||
printf "\n********** Commits ****************\n%s\n***********************************\n" "${GIT_COMMITS}"
|
||||
# fi
|
||||
if [ "${DRY_RUN}" != "1" ]; then
|
||||
echo "${GIT_COMMITS}" >> "${LOGFILE}"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
hook_db() {
|
||||
SQL_DETAILS=$(echo "${MESSAGE}" | sed "s/'/''/g")
|
||||
PG_QUERY="INSERT INTO evomaint(hostname,userid,ipaddress,begin_date,end_date,details) VALUES ('${HOSTNAME}','${USER}','${IP}','${BEGIN_DATE}',now(),'${SQL_DETAILS}')"
|
||||
|
||||
if [ "${VERBOSE}" = "1" ]; then
|
||||
printf "\n********** DB query **************\n%s\n***********************************\n" "${PG_QUERY}"
|
||||
fi
|
||||
if [ "${DRY_RUN}" != "1" ] && [ -x "${PSQL_BIN}" ]; then
|
||||
echo "${PG_QUERY}" | ${PSQL_BIN} "${PGDB}" "${PGTABLE}" -h "${PGHOST}"
|
||||
fi
|
||||
}
|
||||
|
||||
hook_api() {
|
||||
if [ "${VERBOSE}" = "1" ]; then
|
||||
printf "\n********** API call **************\n"
|
||||
printf "curl -f -s -S -X POST [REDACTED] -k -F api_key=[REDACTED] -F action=insertEvoMaintenance -F hostname=%s -F userid=%s -F ipaddress=%s -F begin_date=%s -F end_date='now()' -F details=%s" \
|
||||
"${HOSTNAME}" "${USER}" "${IP}" "${BEGIN_DATE}" "${MESSAGE}"
|
||||
printf "\n***********************************\n"
|
||||
fi
|
||||
|
||||
if [ "${DRY_RUN}" != "1" ] && [ -x "${CURL_BIN}" ]; then
|
||||
API_RETURN_STATUS=$(curl -f -s -S -X POST \
|
||||
"${API_ENDPOINT}" -k \
|
||||
-F api_key="${API_KEY}" \
|
||||
-F action=insertEvoMaintenance \
|
||||
-F hostname="${HOSTNAME}" \
|
||||
-F userid="${USER}" \
|
||||
-F ipaddress="${IP}" \
|
||||
-F begin_date="${BEGIN_DATE}" \
|
||||
-F end_date='now()' \
|
||||
-F details="${MESSAGE}")
|
||||
|
||||
# either cURL or the API backend can throw an error, otherwise it returns this JSON response
|
||||
if [ "$API_RETURN_STATUS" = '{"status":"Ok"}' ]; then
|
||||
echo "API call OK."
|
||||
else
|
||||
echo "API call FAILED."
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
format_mail() {
|
||||
cat <<EOTEMPLATE
|
||||
From: ${FULLFROM}
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
MIME-Version: 1.0
|
||||
Content-Transfer-Encoding: 8bit
|
||||
To: ${EVOMAINTMAIL}
|
||||
Subject: [evomaintenance] Intervention sur ${HOSTNAME_TEXT} (${USER})
|
||||
|
||||
Bonjour,
|
||||
|
||||
Une intervention vient de se terminer sur votre serveur.
|
||||
|
||||
Nom du serveur : ${HOSTNAME_TEXT}
|
||||
Personne ayant réalisée l'intervention : ${USER}
|
||||
Intervention réalisée depuis : ${IP}
|
||||
Début de l'intervention : ${BEGIN_DATE}
|
||||
Fin de l'intervention : ${END_DATE}
|
||||
|
||||
### Renseignements sur l'intervention
|
||||
${MESSAGE}
|
||||
###
|
||||
|
||||
EOTEMPLATE
|
||||
|
||||
if [ -n "${GIT_COMMITS}" ]; then
|
||||
cat << EOTEMPLATE
|
||||
### Commits
|
||||
${GIT_COMMITS}
|
||||
###
|
||||
|
||||
EOTEMPLATE
|
||||
fi
|
||||
|
||||
cat <<EOTEMPLATE
|
||||
Pour réagir à cette intervention, vous pouvez répondre à ce message
|
||||
(sur l'adresse mail ${FROM}). En cas d'urgence, utilisez
|
||||
l'adresse ${URGENCYFROM} ou notre téléphone portable d'astreinte
|
||||
(${URGENCYTEL})
|
||||
|
||||
Cordialement,
|
||||
--
|
||||
${FULLFROM}
|
||||
EOTEMPLATE
|
||||
}
|
||||
|
||||
hook_mail() {
|
||||
MAIL_CONTENT=$(format_mail)
|
||||
|
||||
if [ "${VERBOSE}" = "1" ]; then
|
||||
printf "\n********** Mail *******************\n%s\n***********************************\n" "${MAIL_CONTENT}"
|
||||
fi
|
||||
if [ "${DRY_RUN}" != "1" ] && [ -x "${SENDMAIL_BIN}" ]; then
|
||||
echo "${MAIL_CONTENT}" | ${SENDMAIL_BIN} -oi -t -f "${FROM}"
|
||||
fi
|
||||
}
|
||||
|
||||
hook_log() {
|
||||
if [ "${VERBOSE}" = "1" ]; then
|
||||
print_log
|
||||
fi
|
||||
if [ "${DRY_RUN}" != "1" ]; then
|
||||
print_log >> "${LOGFILE}"
|
||||
fi
|
||||
}
|
||||
|
||||
# load configuration if present.
|
||||
test -f /etc/evomaintenance.cf && . /etc/evomaintenance.cf
|
||||
|
||||
[ -n "${HOSTNAME}" ] || HOSTNAME=$(get_fqdn)
|
||||
[ -n "${EVOMAINTMAIL}" ] || EVOMAINTMAIL=evomaintenance-$(echo "${HOSTNAME}" | cut -d- -f1)@${REALM}
|
||||
[ -n "${LOGFILE}" ] || LOGFILE=/var/log/evomaintenance.log
|
||||
HOSTNAME=${HOSTNAME:-$(get_fqdn)}
|
||||
EVOMAINTMAIL=${EVOMAINTMAIL:-"evomaintenance-$(echo "${HOSTNAME}" | cut -d- -f1)@${REALM}"}
|
||||
LOGFILE=${LOGFILE:-"/var/log/evomaintenance.log"}
|
||||
HOOK_COMMIT=${HOOK_COMMIT:-"1"}
|
||||
HOOK_DB=${HOOK_DB:-"0"}
|
||||
HOOK_API=${HOOK_API:-"1"}
|
||||
HOOK_MAIL=${HOOK_MAIL:-"1"}
|
||||
DRY_RUN=${DRY_RUN:-"0"}
|
||||
VERBOSE=${VERBOSE:-"0"}
|
||||
AUTO=${AUTO:-"0"}
|
||||
EVOCHECK=${EVOCHECK:-"0"}
|
||||
GIT_STATUS_MAX_LINES=${GIT_STATUS_MAX_LINES:-20}
|
||||
API_ENDPOINT=${API_ENDPOINT:-""}
|
||||
|
||||
# initialize variables
|
||||
MESSAGE=""
|
||||
# GIT_COMMITS_SHORT=""
|
||||
GIT_COMMITS=""
|
||||
|
||||
# Parse options
|
||||
# based on https://gist.github.com/deshion/10d3cb5f88a21671e17a
|
||||
while :; do
|
||||
case $1 in
|
||||
-h|-\?|--help)
|
||||
show_help
|
||||
exit 0
|
||||
;;
|
||||
-V|--version)
|
||||
show_version
|
||||
exit 0
|
||||
;;
|
||||
-m|--message)
|
||||
# message options, with value speparated by space
|
||||
if [ -n "$2" ]; then
|
||||
MESSAGE=$2
|
||||
shift
|
||||
else
|
||||
printf 'ERROR: "--message" requires a non-empty option argument.\n' >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
--message=?*)
|
||||
# message options, with value speparated by =
|
||||
MESSAGE=${1#*=}
|
||||
;;
|
||||
--message=)
|
||||
# message options, without value
|
||||
printf 'ERROR: "--message" requires a non-empty option argument.\n' >&2
|
||||
exit 1
|
||||
;;
|
||||
--no-commit)
|
||||
# disable commit hook
|
||||
HOOK_COMMIT=0
|
||||
;;
|
||||
--commit)
|
||||
# enable commit hook
|
||||
HOOK_COMMIT=1
|
||||
;;
|
||||
--no-db)
|
||||
# disable DB hook
|
||||
HOOK_DB=0
|
||||
;;
|
||||
--db)
|
||||
# enable DB hook
|
||||
HOOK_DB=1
|
||||
;;
|
||||
--no-api)
|
||||
# disable API hook
|
||||
HOOK_API=0
|
||||
;;
|
||||
--api)
|
||||
# enable API hook
|
||||
HOOK_API=1
|
||||
;;
|
||||
--no-mail)
|
||||
# disable mail hook
|
||||
HOOK_MAIL=0
|
||||
;;
|
||||
--mail)
|
||||
# enable mail hook
|
||||
HOOK_MAIL=1
|
||||
;;
|
||||
--no-auto)
|
||||
# use "manual" mode
|
||||
AUTO=0
|
||||
;;
|
||||
--auto)
|
||||
# use "auto" mode
|
||||
AUTO=1
|
||||
;;
|
||||
-n|--dry-run)
|
||||
# disable actual commands
|
||||
DRY_RUN=1
|
||||
;;
|
||||
-v|--verbose)
|
||||
# print verbose information
|
||||
VERBOSE=1
|
||||
;;
|
||||
--)
|
||||
# End of all options.
|
||||
shift
|
||||
break
|
||||
;;
|
||||
-?*|[[:alnum:]]*)
|
||||
# ignore unknown options
|
||||
printf 'WARN: Unknown option (ignored): %s\n' "$1" >&2
|
||||
;;
|
||||
*)
|
||||
# Default case: If no more options then break out of the loop.
|
||||
break
|
||||
;;
|
||||
esac
|
||||
|
||||
shift
|
||||
done
|
||||
|
||||
|
||||
# Treat unset variables as an error when substituting.
|
||||
# Only after this line, because some config variables might be missing.
|
||||
set -u
|
||||
|
||||
REAL_HOSTNAME=$(get_fqdn)
|
||||
if [ "${HOSTNAME}" = "${REAL_HOSTNAME}" ]; then
|
||||
HOSTNAME_TEXT="${HOSTNAME}"
|
||||
else
|
||||
HOSTNAME_TEXT="${HOSTNAME} (${REAL_HOSTNAME})"
|
||||
fi
|
||||
|
||||
# Gather information
|
||||
HOSTNAME_TEXT=$(get_complete_hostname)
|
||||
# TTY=$(get_tty)
|
||||
# WHO=$(get_who)
|
||||
IP=$(get_ip)
|
||||
|
@ -90,109 +497,281 @@ USER=$(logname)
|
|||
PATH=${PATH}:/usr/sbin
|
||||
|
||||
SENDMAIL_BIN=$(command -v sendmail)
|
||||
GIT_BIN=$(command -v git)
|
||||
|
||||
GIT_REPOSITORIES="/etc /etc/bind"
|
||||
|
||||
# git statuses
|
||||
GIT_STATUSES=""
|
||||
|
||||
if test -x "${GIT_BIN}"; then
|
||||
# loop on possible directories managed by GIT
|
||||
for dir in ${GIT_REPOSITORIES}; do
|
||||
# tell Git where to find the repository and the work tree (no need to `cd …` there)
|
||||
export GIT_DIR="${dir}/.git" GIT_WORK_TREE="${dir}"
|
||||
# If the repository and the work tree exist, try to commit changes
|
||||
if test -d "${GIT_DIR}" && test -d "${GIT_WORK_TREE}"; then
|
||||
CHANGED_LINES=$(${GIT_BIN} status --porcelain | wc -l | tr -d ' ')
|
||||
if [ "${CHANGED_LINES}" != "0" ]; then
|
||||
STATUS=$(${GIT_BIN} status --short | tail -n 10)
|
||||
# append diff data, without empty lines
|
||||
GIT_STATUSES=$(printf "%s\n%s\n%s\n" "${GIT_STATUSES}" "${GIT_DIR} (last 10 lines)" "${STATUS}" | sed -e '/^$/d')
|
||||
fi
|
||||
fi
|
||||
# unset environment variables to prevent accidental influence on other git commands
|
||||
unset GIT_DIR GIT_WORK_TREE
|
||||
done
|
||||
if [ -n "${GIT_STATUSES}" ]; then
|
||||
echo "/!\ There are some uncommited changes. If you proceed, everything will be commited."
|
||||
echo "${GIT_STATUSES}"
|
||||
echo ""
|
||||
fi
|
||||
readonly SENDMAIL_BIN
|
||||
if [ "${HOOK_MAIL}" = "1" ] && [ -z "${SENDMAIL_BIN}" ]; then
|
||||
echo "No \`sendmail' command has been found, can't send mail." 2>&1
|
||||
fi
|
||||
|
||||
# get input from stdin
|
||||
echo "> Please, enter details about your maintenance"
|
||||
read TEXTE
|
||||
GIT_BIN=$(command -v git)
|
||||
readonly GIT_BIN
|
||||
if [ "${HOOK_COMMIT}" = "1" ] && [ -z "${GIT_BIN}" ]; then
|
||||
echo "No \`git' command has been found, can't commit changes" 2>&1
|
||||
fi
|
||||
|
||||
if [ "${TEXTE}" = "" ]; then
|
||||
PSQL_BIN=$(command -v psql)
|
||||
readonly PSQL_BIN
|
||||
if [ "${HOOK_DB}" = "1" ] && [ -z "${PSQL_BIN}" ]; then
|
||||
echo "No \`psql' command has been found, can't save to the database." 2>&1
|
||||
fi
|
||||
|
||||
CURL_BIN=$(command -v curl)
|
||||
readonly CURL_BIN
|
||||
if [ "${HOOK_API}" = "1" ] && [ -z "${CURL_BIN}" ]; then
|
||||
echo "No \`curl' command has been found, can't call the API." 2>&1
|
||||
fi
|
||||
|
||||
LOGGER_BIN=$(command -v logger)
|
||||
readonly LOGGER_BIN
|
||||
|
||||
if [ "${HOOK_API}" = "1" ] && [ -z "${API_ENDPOINT}" ]; then
|
||||
echo "No API endpoint specified, can't call the API." 2>&1
|
||||
fi
|
||||
|
||||
EVOCHECK_BIN="/usr/share/scripts/evocheck.sh"
|
||||
|
||||
GIT_REPOSITORIES="/etc /etc/bind /usr/share/scripts"
|
||||
|
||||
# initialize variable
|
||||
GIT_STATUSES=""
|
||||
# git statuses
|
||||
if [ -x "${GIT_BIN}" ]; then
|
||||
# loop on possible directories managed by GIT
|
||||
for dir in ${GIT_REPOSITORIES}; do
|
||||
RESULT=$(get_repository_status "${dir}")
|
||||
if [ -n "${RESULT}" ]; then
|
||||
# append diff data, without empty lines
|
||||
GIT_STATUSES=$(printf "%s\n%s\n" "${GIT_STATUSES}" "${RESULT}" | sed -e '/^$/d')
|
||||
fi
|
||||
unset RESULT
|
||||
done
|
||||
fi
|
||||
|
||||
# find out if running in interactive mode, or not
|
||||
if [ -t 0 ]; then
|
||||
INTERACTIVE=1
|
||||
else
|
||||
INTERACTIVE=0
|
||||
fi
|
||||
readonly INTERACTIVE
|
||||
|
||||
if [ "${INTERACTIVE}" = "1" ] && [ "${EVOCHECK}" = "1" ]; then
|
||||
get_evocheck
|
||||
fi
|
||||
if [ -n "${GIT_STATUSES}" ] && [ "${INTERACTIVE}" = "1" ]; then
|
||||
printf "/!\\\ There are some uncommited changes.\n%s\n\n" "${GIT_STATUSES}"
|
||||
fi
|
||||
|
||||
if [ -z "${MESSAGE}" ]; then
|
||||
if [ "${INTERACTIVE}" = "1" ]; then
|
||||
printf "> Please, enter details about your maintenance:\n"
|
||||
fi
|
||||
read -r MESSAGE
|
||||
fi
|
||||
|
||||
if [ -z "${MESSAGE}" ]; then
|
||||
echo "no value..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# recapitulatif
|
||||
BLOB=$(cat <<END
|
||||
Host : $HOSTNAME_TEXT
|
||||
User : $USER
|
||||
IP : $IP
|
||||
Begin : $BEGIN_DATE
|
||||
End : $END_DATE
|
||||
Message : $TEXTE
|
||||
END
|
||||
)
|
||||
print_session_data
|
||||
|
||||
echo ""
|
||||
echo "${BLOB}"
|
||||
echo ""
|
||||
echo "> Press <Enter> to submit, or <Ctrl+c> to cancel."
|
||||
read enter
|
||||
|
||||
# write log
|
||||
echo "----------- $(get_now) ---------------" >> "${LOGFILE}"
|
||||
echo "${BLOB}" >> "${LOGFILE}"
|
||||
|
||||
# git commit
|
||||
GIT_COMMITS=""
|
||||
|
||||
if test -x "${GIT_BIN}"; then
|
||||
# loop on possible directories managed by GIT
|
||||
for dir in ${GIT_REPOSITORIES}; do
|
||||
# tell Git where to find the repository and the work tree (no need to `cd …` there)
|
||||
export GIT_DIR="${dir}/.git" GIT_WORK_TREE="${dir}"
|
||||
# If the repository and the work tree exist, try to commit changes
|
||||
if test -d "${GIT_DIR}" && test -d "${GIT_WORK_TREE}"; then
|
||||
CHANGED_LINES=$(${GIT_BIN} status --porcelain | wc -l | tr -d ' ')
|
||||
if [ "${CHANGED_LINES}" != "0" ]; then
|
||||
${GIT_BIN} add --all
|
||||
${GIT_BIN} commit --message "${TEXTE}" --author="${USER} <${USER}@evolix.net>" --quiet
|
||||
# Add the SHA to the log file if something has been committed
|
||||
SHA=$(${GIT_BIN} rev-parse --short HEAD)
|
||||
STATS=$(${GIT_BIN} show --stat | tail -1)
|
||||
# append commit data, without empty lines
|
||||
GIT_COMMITS=$(printf "%s\n%s : %s –%s" "${GIT_COMMITS}" "${GIT_DIR}" "${SHA}" "${STATS}" | sed -e '/^$/d')
|
||||
fi
|
||||
if [ "${INTERACTIVE}" = "1" ] && [ "${AUTO}" = "0" ]; then
|
||||
if [ "${HOOK_COMMIT}" = "1" ] || [ "${HOOK_MAIL}" = "1" ] || [ "${HOOK_DB}" = "1" ]; then
|
||||
printf "\nActions to execute:\n"
|
||||
if [ "${HOOK_COMMIT}" = "1" ]; then
|
||||
printf "* commit changes in repositories\n"
|
||||
fi
|
||||
# unset environment variables to prevent accidental influence on other git commands
|
||||
unset GIT_DIR GIT_WORK_TREE
|
||||
done
|
||||
if [ -n "${GIT_COMMITS}" ]; then
|
||||
echo "${GIT_COMMITS}" >> "${LOGFILE}"
|
||||
if [ "${HOOK_MAIL}" = "1" ]; then
|
||||
printf "* send mail to %s\n" "${EVOMAINTMAIL}"
|
||||
fi
|
||||
if [ "${HOOK_DB}" = "1" ]; then
|
||||
printf "* save metadata to the database\n"
|
||||
fi
|
||||
if [ "${HOOK_API}" = "1" ]; then
|
||||
printf "* send metadata to the API\n"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
answer=""
|
||||
while :; do
|
||||
printf "> Let's continue? [Y,n,i,?] "
|
||||
read -r answer
|
||||
case $answer in
|
||||
[Yy]|"" )
|
||||
# force "auto" mode, but keep hooks settings
|
||||
AUTO=1
|
||||
break
|
||||
;;
|
||||
[Nn] )
|
||||
# force "auto" mode, and disable all hooks
|
||||
HOOK_COMMIT=0
|
||||
HOOK_MAIL=0
|
||||
HOOK_DB=0
|
||||
HOOK_API=0
|
||||
AUTO=1
|
||||
break
|
||||
;;
|
||||
[Ii] )
|
||||
# force "manual" mode
|
||||
AUTO=0
|
||||
break
|
||||
;;
|
||||
* )
|
||||
printf "y - yes, execute actions and exit\n"
|
||||
printf "n - no, don't execute actions and exit\n"
|
||||
printf "i - switch to interactive mode\n"
|
||||
printf "? - print this help\n"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
fi
|
||||
|
||||
# insert into PG
|
||||
# SQL_TEXTE=`echo "${TEXTE}" | sed "s/'/\\\\\\'/g ; s@/@\\\\\/@g ; s@\\&@et@g"`
|
||||
SQL_TEXTE=`echo "${TEXTE}" | sed "s/'/''/g"`
|
||||
if [ "${INTERACTIVE}" = "1" ] && [ "${AUTO}" = "0" ]; then
|
||||
# Commit hook
|
||||
if [ -n "${GIT_STATUSES}" ] && [ "${HOOK_COMMIT}" = "1" ]; then
|
||||
printf "/!\ There are some uncommited changes.\n%s\n\n" "${GIT_STATUSES}"
|
||||
|
||||
PG_QUERY="INSERT INTO evomaint(hostname,userid,ipaddress,begin_date,end_date,details) VALUES ('${HOSTNAME}','${USER}','${IP}','${BEGIN_DATE}',now(),'${SQL_TEXTE}')"
|
||||
echo "${PG_QUERY}" | psql ${PGDB} ${PGTABLE} -h ${PGHOST} --quiet
|
||||
y="Y"; n="n"
|
||||
answer=""
|
||||
while :; do
|
||||
printf "> Do you want to commit the changes? [%s] " "${y},${n}"
|
||||
read -r answer
|
||||
case $answer in
|
||||
[Yy] )
|
||||
hook_commit;
|
||||
break
|
||||
;;
|
||||
[Nn] )
|
||||
break
|
||||
;;
|
||||
"" )
|
||||
if [ "${HOOK_COMMIT}" = "1" ]; then
|
||||
hook_commit
|
||||
fi
|
||||
break
|
||||
;;
|
||||
* )
|
||||
echo "answer with a valid choice"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
|
||||
# send mail
|
||||
MAIL_TEXTE=$(echo "${TEXTE}" | sed -e "s@/@\\\\\/@g ; s@&@\\\\&@")
|
||||
MAIL_GIT_COMMITS=$(echo "${GIT_COMMITS}" | sed -e "s@/@\\\\\/@g ; s@&@\\\\&@")
|
||||
# Mail hook
|
||||
if [ "${HOOK_MAIL}" = "1" ]; then
|
||||
y="Y"; n="n"
|
||||
else
|
||||
y="y"; n="N"
|
||||
fi
|
||||
answer=""
|
||||
while :; do
|
||||
printf "> Do you want to send an email to <%s>? [%s] " "${EVOMAINTMAIL}" "${y},${n},e"
|
||||
read -r answer
|
||||
case $answer in
|
||||
[Yy] )
|
||||
hook_mail;
|
||||
break
|
||||
;;
|
||||
[Nn] )
|
||||
break
|
||||
;;
|
||||
[Ee] )
|
||||
printf "> To: [%s] " "${EVOMAINTMAIL}"
|
||||
read -r mail_recipient
|
||||
if [ -n "${mail_recipient}" ]; then
|
||||
EVOMAINTMAIL="${mail_recipient}"
|
||||
fi
|
||||
;;
|
||||
"" )
|
||||
if [ "${HOOK_MAIL}" = "1" ]; then
|
||||
hook_mail
|
||||
fi
|
||||
break
|
||||
;;
|
||||
* )
|
||||
echo "answer with a valid choice"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
cat /usr/share/scripts/evomaintenance.tpl | \
|
||||
sed -e "s/__TO__/${EVOMAINTMAIL}/ ; s/__HOSTNAME__/${HOSTNAME_TEXT}/ ; s/__USER__/${USER}/ ; s/__BEGIN_DATE__/${BEGIN_DATE}/ ; s/__END_DATE__/${END_DATE}/ ; s/__GIT_COMMITS__/${MAIL_GIT_COMMITS}/ ; s/__TEXTE__/${MAIL_TEXTE}/ ; s/__IP__/${IP}/ ; s/__FULLFROM__/${FULLFROM}/ ; s/__FROM__/${FROM}/ ; s/__URGENCYFROM__/${URGENCYFROM}/ ; s/__URGENCYTEL__/${URGENCYTEL}/" | \
|
||||
${SENDMAIL_BIN} -oi -t -f ${FROM}
|
||||
# Database hook
|
||||
if [ "${HOOK_DB}" = "1" ]; then
|
||||
y="Y"; n="n"
|
||||
else
|
||||
y="y"; n="N"
|
||||
fi
|
||||
answer=""
|
||||
while :; do
|
||||
printf "> Do you want to insert your message into the database? [%s] " "${y},${n}"
|
||||
read -r answer
|
||||
case $answer in
|
||||
[Yy] )
|
||||
hook_db;
|
||||
break
|
||||
;;
|
||||
[Nn] )
|
||||
break
|
||||
;;
|
||||
"" )
|
||||
if [ "${HOOK_DB}" = "1" ]; then
|
||||
hook_db
|
||||
fi
|
||||
break
|
||||
;;
|
||||
* )
|
||||
echo "answer with a valid choice"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# API hook
|
||||
if [ "${HOOK_API}" = "1" ]; then
|
||||
y="Y"; n="n"
|
||||
else
|
||||
y="y"; n="N"
|
||||
fi
|
||||
answer=""
|
||||
while :; do
|
||||
printf "> Do you want to send the metadata to the API? [%s] " "${y},${n}"
|
||||
read -r answer
|
||||
case $answer in
|
||||
[Yy] )
|
||||
hook_api;
|
||||
break
|
||||
;;
|
||||
[Nn] )
|
||||
break
|
||||
;;
|
||||
"" )
|
||||
if [ "${HOOK_API}" = "1" ]; then
|
||||
hook_api
|
||||
fi
|
||||
break
|
||||
;;
|
||||
* )
|
||||
echo "answer with a valid choice"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
|
||||
# Log hook
|
||||
hook_log
|
||||
|
||||
if [ "${INTERACTIVE}" = "0" ] || [ "${AUTO}" = "1" ]; then
|
||||
if [ "${HOOK_COMMIT}" = "1" ]; then
|
||||
hook_commit
|
||||
fi
|
||||
if [ "${HOOK_MAIL}" = "1" ]; then
|
||||
hook_mail
|
||||
fi
|
||||
if [ "${HOOK_DB}" = "1" ]; then
|
||||
hook_db
|
||||
fi
|
||||
if [ "${HOOK_API}" = "1" ]; then
|
||||
hook_api
|
||||
fi
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
|
15
roles/base/files/newsyslog.conf
Normal file
15
roles/base/files/newsyslog.conf
Normal file
|
@ -0,0 +1,15 @@
|
|||
# EvoBSD configuration file for newsyslog
|
||||
#
|
||||
# logfile_name owner:group mode count size when flags
|
||||
/var/cron/log root:wheel 600 52 * $W1 Z
|
||||
/var/log/authlog root:wheel 640 52 * $W1 Z
|
||||
/var/log/daemon 640 365 * $D0 Z
|
||||
/var/log/lpd-errs 640 7 * $D0 Z
|
||||
/var/log/maillog 640 52 * $W1 Z
|
||||
/var/log/messages 644 365 * $D0 Z
|
||||
/var/log/secure 600 52 * $W1 Z
|
||||
/var/log/wtmp 644 52 * $W1 B
|
||||
/var/log/xferlog 640 7 * $D0 Z
|
||||
/var/log/pflog 600 30 * $D0 ZB "pkill -HUP -u root -U root -t - -x pflogd"
|
||||
/var/www/logs/access.log 644 52 * $W1 Z "pkill -USR1 -u root -U root -x httpd"
|
||||
/var/www/logs/error.log 644 52 * $W1 Z "pkill -USR1 -u root -U root -x httpd"
|
|
@ -1,27 +0,0 @@
|
|||
# $OpenBSD: dot.profile,v 1.9 2010/12/13 12:54:31 millert Exp $
|
||||
#
|
||||
# sh/ksh initialization
|
||||
|
||||
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin:/usr/local/sbin:/usr/local/bin
|
||||
export PATH HOME TERM
|
||||
export PS1="\u@\h:\w\\$ "
|
||||
HISTFILE=$HOME/.histfile
|
||||
export HISTSIZE=10000
|
||||
export HISTCONTROL='ignoredups:ignorespace'
|
||||
export TMOUT=36000
|
||||
export PAGER=less
|
||||
umask 022
|
||||
|
||||
export ENV='~/.kshrc'
|
||||
|
||||
case "$-" in
|
||||
*i*) # interactive shell
|
||||
if [ -x /usr/bin/tset ]; then
|
||||
if [ X"$XTERM_VERSION" = X"" ]; then
|
||||
eval `/usr/bin/tset -sQ '-munknown:?vt220' $TERM`
|
||||
else
|
||||
eval `/usr/bin/tset -IsQ '-munknown:?vt220' $TERM`
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
esac
|
|
@ -9,3 +9,4 @@ set smarttab
|
|||
set backspace=indent,eol,start
|
||||
set showcmd
|
||||
set encoding=utf-8
|
||||
set mouse=""
|
||||
|
|
|
@ -1,222 +1,419 @@
|
|||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Script Evobackup plus ou moins forké
|
||||
# See https://forge.evolix.org/projects/evobackup
|
||||
#
|
||||
# Script Evobackup client
|
||||
# See https://gitea.evolix.org/evolix/evobackup
|
||||
#
|
||||
# Author: Gregory Colpart <reg@evolix.fr>
|
||||
# Contributors:
|
||||
# Romain Dessort <rdessort@evolix.fr>
|
||||
# Benoît Série <bserie@evolix.fr>
|
||||
# Tristan Pilat <tpilat@evolix.fr>
|
||||
# Victor Laborie <vlaborie@evolix.fr>
|
||||
# Jérémy Lecour <jlecour@evolix.fr>
|
||||
#
|
||||
# Licence: AGPLv3
|
||||
#
|
||||
# /!\ DON'T FORGET TO SET "MAIL" and "SERVERS" VARIABLES
|
||||
|
||||
# Fail on unassigned variables
|
||||
set -u
|
||||
|
||||
##### Configuration ###################################################
|
||||
|
||||
# email adress for notifications
|
||||
MAIL=jdoe@example.com
|
||||
|
||||
# list of hosts (hostname or IP) and SSH port for Rsync
|
||||
SERVERS="node0.backup.example.com:2XXX node1.backup.example.com:2XXX"
|
||||
|
||||
# Should we fallback on servers when the first is unreachable ?
|
||||
SERVERS_FALLBACK=${SERVERS_FALLBACK:-1}
|
||||
|
||||
# timeout (in seconds) for SSH connections
|
||||
SSH_CONNECT_TIMEOUT=${SSH_CONNECT_TIMEOUT:-30}
|
||||
|
||||
## We use /home/backup : feel free to use your own dir
|
||||
LOCAL_BACKUP_DIR="/home/backup"
|
||||
|
||||
# You can set "linux" or "bsd" manually or let it choose automatically
|
||||
SYSTEM=$(uname | tr '[:upper:]' '[:lower:]')
|
||||
|
||||
# Change these 2 variables if you have more than one backup cron
|
||||
PIDFILE="/var/run/evobackup.pid"
|
||||
LOGFILE="/var/log/evobackup.log"
|
||||
|
||||
## Enable/Disable tasks
|
||||
LOCAL_TASKS=${LOCAL_TASKS:-1}
|
||||
SYNC_TASKS=${SYNC_TASKS:-1}
|
||||
|
||||
##### SETUP AND FUNCTIONS #############################################
|
||||
|
||||
BEGINNING=$(/bin/date +"%d-%m-%Y ; %H:%M")
|
||||
|
||||
# shellcheck disable=SC2174
|
||||
mkdir -p -m 700 ${LOCAL_BACKUP_DIR}
|
||||
|
||||
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/sbin:/usr/local/bin
|
||||
|
||||
## lang = C for english outputs
|
||||
LANGUAGE=C
|
||||
LANG=C
|
||||
export LANGUAGE=C
|
||||
export LANG=C
|
||||
|
||||
## Force umask
|
||||
umask 077
|
||||
|
||||
## Initialize variable to store SSH connection errors
|
||||
SERVERS_SSH_ERRORS=""
|
||||
|
||||
# Call test_server with "HOST:PORT" string
|
||||
# It will return with 0 if the server is reachable.
|
||||
# It will return with 1 and a message on stderr if not.
|
||||
test_server() {
|
||||
item=$1
|
||||
# split HOST and PORT from the input string
|
||||
host=$(echo "${item}" | cut -d':' -f1)
|
||||
port=$(echo "${item}" | cut -d':' -f2)
|
||||
|
||||
# Test if the server is accepting connections
|
||||
ssh -q -o "ConnectTimeout ${SSH_CONNECT_TIMEOUT}" "${host}" -p "${port}" -t "exit"
|
||||
# shellcheck disable=SC2181
|
||||
if [ $? = 0 ]; then
|
||||
# SSH connection is OK
|
||||
return 0
|
||||
else
|
||||
# SSH connection failed
|
||||
new_error=$(printf "Failed to connect to \`%s' within %s seconds" "${item}" "${SSH_CONNECT_TIMEOUT}")
|
||||
SERVERS_SSH_ERRORS=$(printf "%s\n%s" "${SERVERS_SSH_ERRORS}" "${new_error}" | sed -e '/^$/d')
|
||||
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
# Call pick_server with an optional positive integer to get the nth server in the list.
|
||||
pick_server() {
|
||||
increment=${1:-0}
|
||||
list_length=$(echo "${SERVERS}" | wc -w)
|
||||
|
||||
if [ "${increment}" -ge "${list_length}" ]; then
|
||||
# We've reached the end of the list
|
||||
new_error="No more server available"
|
||||
SERVERS_SSH_ERRORS=$(printf "%s\n%s" "${SERVERS_SSH_ERRORS}" "${new_error}" | sed -e '/^$/d')
|
||||
|
||||
# Log errors to stderr
|
||||
printf "%s\n" "${SERVERS_SSH_ERRORS}" >&2
|
||||
# Log errors to logfile
|
||||
printf "%s\n" "${SERVERS_SSH_ERRORS}" >> $LOGFILE
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Extract the day of month, without leading 0 (which would give an octal based number)
|
||||
today=$(date +%e)
|
||||
# A salt is useful to randomize the starting point in the list
|
||||
# but stay identical each time it's called for a server (based on hostname).
|
||||
salt=$(hostname | cksum | cut -d' ' -f1)
|
||||
# Pick an integer between 0 and the length of the SERVERS list
|
||||
# It changes each day
|
||||
item=$(( (today + salt + increment) % list_length ))
|
||||
# cut starts counting fields at 1, not 0.
|
||||
field=$(( item + 1 ))
|
||||
|
||||
echo "${SERVERS}" | cut -d' ' -f${field}
|
||||
}
|
||||
|
||||
## Verify other evobackup process and kill if needed
|
||||
PIDFILE=/var/run/evobackup.pid
|
||||
if [ -e $PIDFILE ]; then
|
||||
# Killing the childs of evobackup.
|
||||
for pid in $(ps h --ppid $(cat $PIDFILE) -o pid | tr -s '\n' ' '); do
|
||||
kill -9 $pid;
|
||||
if [ -e "${PIDFILE}" ]; then
|
||||
pid=$(cat "${PIDFILE}")
|
||||
# Does process still exist ?
|
||||
if kill -0 ${pid} 2> /dev/null; then
|
||||
# Killing the childs of evobackup.
|
||||
for ppid in $(pgrep -P "${pid}"); do
|
||||
kill -9 "${ppid}";
|
||||
done
|
||||
# Then kill the main PID.
|
||||
kill -9 "${pid}"
|
||||
printf "%s is still running (PID %s). Process has been killed" "$0" "${pid}\n" >&2
|
||||
else
|
||||
rm -f ${PIDFILE}
|
||||
fi
|
||||
fi
|
||||
echo "$$" > ${PIDFILE}
|
||||
# shellcheck disable=SC2064
|
||||
trap "rm -f ${PIDFILE}" EXIT
|
||||
|
||||
##### LOCAL BACKUP ####################################################
|
||||
|
||||
if [ "${LOCAL_TASKS}" = "1" ]; then
|
||||
# You can comment or uncomment sections below to customize the backup
|
||||
|
||||
## OpenLDAP : example with slapcat
|
||||
# slapcat -l ${LOCAL_BACKUP_DIR}/ldap.bak
|
||||
|
||||
## MySQL
|
||||
|
||||
## example with global and compressed mysqldump
|
||||
# mysqldump --defaults-extra-file=/etc/mysql/debian.cnf -P 3306 \
|
||||
# --opt --all-databases --force --events --hex-blob | gzip --best > ${LOCAL_BACKUP_DIR}/mysql.bak.gz
|
||||
|
||||
## example with two dumps for each table (.sql/.txt) for all databases
|
||||
# for i in $(echo SHOW DATABASES | mysql --defaults-extra-file=/etc/mysql/debian.cnf -P 3306 \
|
||||
# | egrep -v "^(Database|information_schema|performance_schema|sys)" ); \
|
||||
# do mkdir -p -m 700 /home/mysqldump/$i ; chown -RL mysql /home/mysqldump ; \
|
||||
# mysqldump --defaults-extra-file=/etc/mysql/debian.cnf --force -P 3306 -Q --opt --events --hex-blob --skip-comments \
|
||||
# --fields-enclosed-by='\"' --fields-terminated-by=',' -T /home/mysqldump/$i $i; done
|
||||
|
||||
## example with SQL dump (schema only, no data) for each databases
|
||||
# mkdir -p -m 700 /home/mysqldump/
|
||||
# for i in $(mysql --defaults-extra-file=/etc/mysql/debian.cnf -P 3306 -e 'show databases' -s --skip-column-names \
|
||||
# | egrep -v "^(Database|information_schema|performance_schema|sys)"); do
|
||||
# mysqldump --defaults-extra-file=/etc/mysql/debian.cnf --force -P 3306 --no-data --databases $i > /home/mysqldump/${i}.schema.sql
|
||||
# done
|
||||
|
||||
## example with compressed SQL dump (with data) for each databases
|
||||
# mkdir -p -m 700 /home/mysqldump/
|
||||
# for i in $(mysql --defaults-extra-file=/etc/mysql/debian.cnf -P 3306 -e 'show databases' -s --skip-column-names \
|
||||
# | egrep -v "^(Database|information_schema|performance_schema|sys)"); do
|
||||
# mysqldump --defaults-extra-file=/etc/mysql/debian.cnf --force -P 3306 --events --hex-blob $i | gzip --best > /home/mysqldump/${i}.sql.gz
|
||||
# done
|
||||
|
||||
## example with *one* uncompressed SQL dump for *one* database (MYBASE)
|
||||
# mkdir -p -m 700 /home/mysqldump/MYBASE
|
||||
# chown -RL mysql /home/mysqldump/
|
||||
# mysqldump --defaults-extra-file=/etc/mysql/debian.cnf --force -Q \
|
||||
# --opt --events --hex-blob --skip-comments -T /home/mysqldump/MYBASE MYBASE
|
||||
|
||||
## example with mysqlhotcopy
|
||||
# mkdir -p -m 700 /home/mysqlhotcopy/
|
||||
# mysqlhotcopy BASE /home/mysqlhotcopy/
|
||||
|
||||
## example for multiples MySQL instances
|
||||
# mysqladminpasswd=$(grep -m1 'password = .*' /root/.my.cnf|cut -d" " -f3)
|
||||
# grep -E "^port\s*=\s*\d*" /etc/mysql/my.cnf |while read instance; do
|
||||
# instance=$(echo "$instance"|awk '{ print $3 }')
|
||||
# if [ "$instance" != "3306" ]
|
||||
# then
|
||||
# mysqldump -P $instance --opt --all-databases --hex-blob -u mysqladmin -p$mysqladminpasswd > ${LOCAL_BACKUP_DIR}/mysql.$instance.bak
|
||||
# fi
|
||||
# done
|
||||
|
||||
## PostgreSQL
|
||||
|
||||
## example with pg_dumpall (warning: you need space in ~postgres)
|
||||
# su - postgres -c "pg_dumpall > ~/pg.dump.bak"
|
||||
# mv ~postgres/pg.dump.bak ${LOCAL_BACKUP_DIR}/
|
||||
## another method with gzip directly piped
|
||||
# cd /var/lib/postgresql
|
||||
# sudo -u postgres pg_dumpall | gzip > ${LOCAL_BACKUP_DIR}/pg.dump.bak.gz
|
||||
# cd - > /dev/null
|
||||
|
||||
## example with all tables from MYBASE excepts TABLE1 and TABLE2
|
||||
# pg_dump -p 5432 -h 127.0.0.1 -U USER --clean -F t --inserts -f ${LOCAL_BACKUP_DIR}/pg-backup.tar -t 'TABLE1' -t 'TABLE2' MYBASE
|
||||
|
||||
## example with only TABLE1 and TABLE2 from MYBASE
|
||||
# pg_dump -p 5432 -h 127.0.0.1 -U USER --clean -F t --inserts -f ${LOCAL_BACKUP_DIR}/pg-backup.tar -T 'TABLE1' -T 'TABLE2' MYBASE
|
||||
|
||||
## MongoDB
|
||||
|
||||
## don't forget to create use with read-only access
|
||||
## > use admin
|
||||
## > db.createUser( { user: "mongobackup", pwd: "PASS", roles: [ "backup", ] } )
|
||||
# test -d ${LOCAL_BACKUP_DIR}/mongodump/ && rm -rf ${LOCAL_BACKUP_DIR}/mongodump/
|
||||
# mkdir -p -m 700 ${LOCAL_BACKUP_DIR}/mongodump/
|
||||
# mongodump --quiet -u mongobackup -pPASS -o ${LOCAL_BACKUP_DIR}/mongodump/
|
||||
# if [ $? -ne 0 ]; then
|
||||
# echo "Error with mongodump!"
|
||||
# fi
|
||||
|
||||
## Redis
|
||||
|
||||
## example with copy .rdb file
|
||||
# cp /var/lib/redis/dump.rdb ${LOCAL_BACKUP_DIR}/
|
||||
|
||||
## ElasticSearch
|
||||
|
||||
## Take a snapshot as a backup.
|
||||
## Warning: You need to have a path.repo configured.
|
||||
## See: https://wiki.evolix.org/HowtoElasticsearch#snapshots-et-sauvegardes
|
||||
# curl -s -XDELETE "localhost:9200/_snapshot/snaprepo/snapshot.daily" -o /tmp/es_delete_snapshot.daily.log
|
||||
# curl -s -XPUT "localhost:9200/_snapshot/snaprepo/snapshot.daily?wait_for_completion=true" -o /tmp/es_snapshot.daily.log
|
||||
## Clustered version here
|
||||
## It basically the same thing except that you need to check that NFS is mounted
|
||||
# if ss | grep ':nfs' | grep -q 'ip\.add\.res\.s1' && ss | grep ':nfs' | grep -q 'ip\.add\.res\.s2'
|
||||
# then
|
||||
# curl -s -XDELETE "localhost:9200/_snapshot/snaprepo/snapshot.daily" -o /tmp/es_delete_snapshot.daily.log
|
||||
# curl -s -XPUT "localhost:9200/_snapshot/snaprepo/snapshot.daily?wait_for_completion=true" -o /tmp/es_snapshot.daily.log
|
||||
# else
|
||||
# echo 'Cannot make a snapshot of elasticsearch, at least one node is not mounting the repository.'
|
||||
# fi
|
||||
## If you need to keep older snapshot, for example the last 10 daily snapshots, replace the XDELETE and XPUT lines by :
|
||||
# for snapshot in $(curl -s -XGET "localhost:9200/_snapshot/snaprepo/_all?pretty=true" | grep -Eo 'snapshot_[0-9]{4}-[0-9]{2}-[0-9]{2}' | head -n -10); do
|
||||
# curl -s -XDELETE "localhost:9200/_snapshot/snaprepo/${snapshot}" | grep -v -Fx '{"acknowledged":true}'
|
||||
# done
|
||||
# date=$(date +%F)
|
||||
# curl -s -XPUT "localhost:9200/_snapshot/snaprepo/snapshot_${date}?wait_for_completion=true" -o /tmp/es_snapshot_${date}.log
|
||||
|
||||
## RabbitMQ
|
||||
|
||||
## export config
|
||||
#rabbitmqadmin export ${LOCAL_BACKUP_DIR}/rabbitmq.config >> $LOGFILE
|
||||
|
||||
## MegaCli config
|
||||
|
||||
#megacli -CfgSave -f ${LOCAL_BACKUP_DIR}/megacli_conf.dump -a0 >/dev/null
|
||||
|
||||
## Dump system and kernel versions
|
||||
uname -a > ${LOCAL_BACKUP_DIR}/uname
|
||||
|
||||
## Dump network routes with mtr and traceroute (warning: could be long with aggressive firewalls)
|
||||
for addr in 8.8.8.8 www.evolix.fr travaux.evolix.net; do
|
||||
mtr -r ${addr} > ${LOCAL_BACKUP_DIR}/mtr-${addr}
|
||||
traceroute -n ${addr} > ${LOCAL_BACKUP_DIR}/traceroute-${addr} 2>&1
|
||||
done
|
||||
# Then kill the main PID.
|
||||
kill -9 $(cat $PIDFILE)
|
||||
echo "$0 tourne encore (PID `cat $PIDFILE`). Processus killé" >&2
|
||||
|
||||
## Dump process with ps
|
||||
ps auwwx >${LOCAL_BACKUP_DIR}/ps.out
|
||||
|
||||
if [ "${SYSTEM}" = "linux" ]; then
|
||||
## Dump network connections with ss
|
||||
ss -taupen > ${LOCAL_BACKUP_DIR}/netstat.out
|
||||
|
||||
## List Debian packages
|
||||
dpkg -l > ${LOCAL_BACKUP_DIR}/packages
|
||||
dpkg --get-selections > ${LOCAL_BACKUP_DIR}/packages.getselections
|
||||
apt-cache dumpavail > ${LOCAL_BACKUP_DIR}/packages.available
|
||||
|
||||
## Dump MBR / table partitions
|
||||
disks=$(lsblk -l | grep disk | grep -v -E '(drbd|fd[0-9]+)' | awk '{print $1}')
|
||||
for disk in ${disks}; do
|
||||
dd if="/dev/${disk}" of="${LOCAL_BACKUP_DIR}/MBR-${disk}" bs=512 count=1 2>&1 | grep -Ev "(records in|records out|512 bytes)"
|
||||
fdisk -l "/dev/${disk}" > "${LOCAL_BACKUP_DIR}/partitions-${disk}" 2>&1
|
||||
done
|
||||
cat ${LOCAL_BACKUP_DIR}/partitions-* > ${LOCAL_BACKUP_DIR}/partitions
|
||||
|
||||
## Dump iptables
|
||||
if [ -x /sbin/iptables ]; then
|
||||
{ /sbin/iptables -L -n -v; /sbin/iptables -t filter -L -n -v; } > ${LOCAL_BACKUP_DIR}/iptables.txt
|
||||
fi
|
||||
|
||||
## Dump findmnt(8) output
|
||||
FINDMNT_BIN=$(command -v findmnt)
|
||||
if [ -x ${FINDMNT_BIN} ]; then
|
||||
${FINDMNT_BIN} > ${LOCAL_BACKUP_DIR}/findmnt.txt
|
||||
fi
|
||||
else
|
||||
## Dump network connections with netstat
|
||||
netstat -finet -atn > ${LOCAL_BACKUP_DIR}/netstat.out
|
||||
|
||||
## List OpenBSD packages
|
||||
pkg_info -m > ${LOCAL_BACKUP_DIR}/packages
|
||||
|
||||
## Dump MBR / table partitions
|
||||
disklabel sd0 > ${LOCAL_BACKUP_DIR}/partitions
|
||||
|
||||
## Dump pf infos
|
||||
pfctl -sa > ${LOCAL_BACKUP_DIR}/pfctl-sa.txt
|
||||
|
||||
fi
|
||||
|
||||
## Dump rights
|
||||
#getfacl -R /var > ${LOCAL_BACKUP_DIR}/rights-var.txt
|
||||
#getfacl -R /etc > ${LOCAL_BACKUP_DIR}/rights-etc.txt
|
||||
#getfacl -R /usr > ${LOCAL_BACKUP_DIR}/rights-usr.txt
|
||||
#getfacl -R /home > ${LOCAL_BACKUP_DIR}/rights-home.txt
|
||||
|
||||
fi
|
||||
echo "$$" > $PIDFILE
|
||||
trap "rm -f $PIDFILE" EXIT
|
||||
|
||||
# Variable to choose different backup server with date
|
||||
NODE=$(expr `date +%d` % 2 + 2)
|
||||
##### REMOTE BACKUP ###################################################
|
||||
|
||||
# port SSH
|
||||
SSH_PORT=2XXX
|
||||
n=0
|
||||
server=""
|
||||
if [ "${SERVERS_FALLBACK}" = "1" ]; then
|
||||
# We try to find a suitable server
|
||||
while :; do
|
||||
server=$(pick_server "${n}")
|
||||
test $? = 0 || exit 2
|
||||
|
||||
# email adress for notifications
|
||||
MAIL={{ general_alert_email }}
|
||||
|
||||
# backup server used
|
||||
SRV=node$NODE.backup2.evolix.net
|
||||
|
||||
# choose "linux" or "bsd"
|
||||
SYSTEME=$(uname | tr '[:upper:]' '[:lower:]')
|
||||
|
||||
## We use /home/backup : feel free to use your own dir
|
||||
mkdir -p -m 700 /home/backup
|
||||
|
||||
## OpenLDAP : example with slapcat
|
||||
# slapcat -l /home/backup/ldap.bak
|
||||
|
||||
### MySQL
|
||||
|
||||
## example with global and compressed mysqldump
|
||||
# mysqldump --defaults-extra-file=/etc/mysql/debian.cnf -P 3306 \
|
||||
# --opt --all-databases --force --events --hex-blob | gzip --best > /home/backup/mysql.bak.gz
|
||||
|
||||
## example with two dumps for each table (.sql/.txt) for all databases
|
||||
# for i in $(echo SHOW DATABASES | mysql --defaults-extra-file=/etc/mysql/debian.cnf -P 3306 \
|
||||
# | egrep -v "^(Database|information_schema|performance_schema)" ); \
|
||||
# do mkdir -p /home/mysqldump/$i ; chown -RL mysql /home/mysqldump ; \
|
||||
# mysqldump --defaults-extra-file=/etc/mysql/debian.cnf --force -P 3306 -Q --opt --events --hex-blob --skip-comments -T \
|
||||
# /home/mysqldump/$i $i; done
|
||||
|
||||
## example with compressed SQL dump for each databases
|
||||
# mkdir -p /home/mysqldump/
|
||||
# for i in $(mysql --defaults-extra-file=/etc/mysql/debian.cnf -P 3306 -e 'show databases' -s --skip-column-names \
|
||||
# | egrep -v "^(Database|information_schema|performance_schema)"); do
|
||||
# mysqldump --defaults-extra-file=/etc/mysql/debian.cnf --force -P 3306 --events --hex-blob $i | gzip --best > /home/mysqldump/${i}.sql.gz
|
||||
# done
|
||||
|
||||
## example with *one* uncompressed SQL dump for *one* database (MYBASE)
|
||||
# mkdir -p -m 700 /home/mysqldump/MYBASE
|
||||
# chown -RL mysql /home/mysqldump/
|
||||
# mysqldump --defaults-extra-file=/etc/mysql/debian.cnf --force -Q \
|
||||
# --opt --events --hex-blob --skip-comments -T /home/mysqldump/MYBASE MYBASE
|
||||
|
||||
## example with mysqlhotcopy
|
||||
# mkdir -p /home/mysqlhotcopy/
|
||||
# mysqlhotcopy BASE /home/mysqlhotcopy/
|
||||
|
||||
## example for multiples MySQL instances
|
||||
# mysqladminpasswd=`cat /root/.my.cnf |grep -m1 'password = .*' |cut -d" " -f3`
|
||||
# grep -E "^port\s*=\s*\d*" /etc/mysql/my.cnf |while read instance; do
|
||||
# instance=$(echo $instance |tr -d '\t')
|
||||
# instance=${instance// /}
|
||||
# instance=${instance//port=/}
|
||||
# if [ "$instance" != "3306" ]
|
||||
# then
|
||||
# mysqldump -P $instance --opt --all-databases --hex-blob -u mysqladmin -p$mysqladminpasswd > /home/backup/mysql.$instance.bak
|
||||
# fi
|
||||
# done
|
||||
|
||||
### PostgreSQL
|
||||
|
||||
## example with pg_dumpall (warning: you need space in ~postgres)
|
||||
# su - postgres -c "pg_dumpall > ~/pg.dump.bak"
|
||||
# mv ~postgres/pg.dump.bak /home/backup/
|
||||
|
||||
## example with all tables from MYBASE excepts TABLE1 and TABLE2
|
||||
# pg_dump -p 5432 -h 127.0.0.1 -U USER --clean -F t --inserts -f /home/backup/pg-backup.tar -t 'TABLE1' -t 'TABLE2' MYBASE
|
||||
|
||||
## example with only TABLE1 and TABLE2 from MYBASE
|
||||
# pg_dump -p 5432 -h 127.0.0.1 -U USER --clean -F t --inserts -f /home/backup/pg-backup.tar -T 'TABLE1' -T 'TABLE2' MYBASE
|
||||
|
||||
## MongoDB : example with mongodump
|
||||
## don't forget to create use with read-only access
|
||||
## > use admin
|
||||
## > db.addUser("mongobackup", "PASS", true);
|
||||
# mongodump -u mongobackup -pPASS -o /home/backup/mongodump/ >/dev/null 2>&1 |grep -v "^connected to:"
|
||||
|
||||
## Redis : example with copy .rdb file
|
||||
# cp /var/lib/redis/dump.rdb /home/backup/
|
||||
|
||||
## ElasticSearch : example with rsync (warning: don't forget to use NFS if you have a cluster)
|
||||
## Disable ES translog flush
|
||||
# curl -s -XPUT 'localhost:9200/_settings' -d '{"index.translog.disable_flush": true}' >/dev/null
|
||||
## Flushes translog
|
||||
# curl -s 'localhost:9200/_flush' | grep -qe '"ok":true'
|
||||
## If it succeed, do an rsync of the datadir
|
||||
# if [ $? -eq 0 ]; then
|
||||
# rsync -a /var/lib/elasticsearch /home/backup/
|
||||
# else
|
||||
# echo "Error when flushing ES translog indexes."
|
||||
# fi
|
||||
## In any case re-enable translog flush
|
||||
# curl -s -XPUT 'localhost:9200/_settings' -d '{"index.translog.disable_flush": false}' > /dev/null
|
||||
|
||||
## Dump MBR / table partitions with dd and sfdisk
|
||||
## Linux
|
||||
# dd if=/dev/sda of=/home/backup/MBR bs=512 count=1 2>&1 | egrep -v "(records in|records out|512 bytes)"
|
||||
# sfdisk -d /dev/sda > /home/backup/partitions 2>&1 | egrep -v "(Warning: extended partition does not start at a cylinder boundary|DOS and Linux will interpret the contents differently)"
|
||||
## OpenBSD
|
||||
# disklabel sd0 > /home/backup/partitions
|
||||
|
||||
# backup MegaCli config
|
||||
#megacli -CfgSave -f /home/backup/megacli_conf.dump -a0 >/dev/null
|
||||
|
||||
## Dump network routes with mtr and traceroute (warning: could be long with aggressive firewalls)
|
||||
for addr in 8.8.8.8 backup.evolix.net www.evolix.fr www.evolix.net; do
|
||||
mtr -r $addr > /home/backup/mtr-${addr} 2>/dev/null
|
||||
traceroute -n $addr > /home/backup/traceroute-${addr} 2>/dev/null
|
||||
done
|
||||
|
||||
## Dump process with ps
|
||||
ps aux >/home/backup/ps.out
|
||||
|
||||
if [ $SYSTEME = "linux" ]; then
|
||||
## Dump network connections with netstat
|
||||
netstat -taupen >/home/backup/netstat.out
|
||||
|
||||
## List Debian packages
|
||||
dpkg -l >/home/backup/packages
|
||||
if test_server "${server}"; then
|
||||
break
|
||||
else
|
||||
server=""
|
||||
n=$(( n + 1 ))
|
||||
fi
|
||||
done
|
||||
else
|
||||
## Dump network connections with netstat
|
||||
netstat -finet -atn >/home/backup/netstat.out
|
||||
|
||||
## List OpenBSD packages
|
||||
pkg_info -m >/home/backup/packages
|
||||
# we force the server
|
||||
server=$(pick_server "${n}")
|
||||
fi
|
||||
|
||||
SSH_SERVER=$(echo "${server}" | cut -d':' -f1)
|
||||
SSH_PORT=$(echo "${server}" | cut -d':' -f2)
|
||||
|
||||
HOSTNAME=$(hostname)
|
||||
|
||||
DATE=$(/bin/date +"%d-%m-%Y")
|
||||
|
||||
DEBUT=$(/bin/date +"%d-%m-%Y ; %H:%M")
|
||||
|
||||
if [ $SYSTEME = "linux" ]; then
|
||||
if [ "${SYSTEM}" = "linux" ]; then
|
||||
rep="/bin /boot /lib /opt /sbin /usr"
|
||||
else
|
||||
rep="/bsd /bin /sbin /usr"
|
||||
fi
|
||||
|
||||
/usr/local/bin/rsync -avzh --stats --delete --delete-excluded --force --ignore-errors --partial \
|
||||
--exclude "lost+found" \
|
||||
--exclude ".nfs.*" \
|
||||
--exclude "/var/log" \
|
||||
--exclude "/var/log/evobackup*" \
|
||||
--exclude "/var/lib/mysql" \
|
||||
--exclude "/var/lib/postgres" \
|
||||
--exclude "/var/lib/postgresql" \
|
||||
--exclude "/var/lib/sympa" \
|
||||
--exclude "/var/lib/metche" \
|
||||
--exclude "/var/run" \
|
||||
--exclude "/var/lock" \
|
||||
--exclude "/var/state" \
|
||||
--exclude "/var/apt" \
|
||||
--exclude "/var/cache" \
|
||||
--exclude "/usr/src" \
|
||||
--exclude "/usr/doc" \
|
||||
--exclude "/usr/share/doc" \
|
||||
--exclude "/usr/obj" \
|
||||
--exclude "dev" \
|
||||
--exclude "/var/spool/postfix" \
|
||||
--exclude "/var/lib/amavis/amavisd.sock" \
|
||||
--exclude "/var/lib/munin/*tmp*" \
|
||||
--exclude "/var/lib/php5" \
|
||||
--exclude "/var/spool/squid" \
|
||||
--exclude "/var/lib/elasticsearch" \
|
||||
--exclude "/var/lib/amavis/tmp" \
|
||||
--exclude "/var/lib/clamav/*.tmp" \
|
||||
--exclude "/home/mysqltmp" \
|
||||
$rep \
|
||||
/etc \
|
||||
/root \
|
||||
/var \
|
||||
/home \
|
||||
-e "ssh -p $SSH_PORT" \
|
||||
root@${SRV}:/var/backup/ \
|
||||
| tail -30 >> /var/log/evobackup.log
|
||||
|
||||
FIN=$(/bin/date +"%d-%m-%Y ; %H:%M")
|
||||
if [ "${SYNC_TASKS}" = "1" ]; then
|
||||
# /!\ DO NOT USE COMMENTS in the rsync command /!\
|
||||
# It breaks the command and destroys data, simply remove (or add) lines.
|
||||
|
||||
echo "EvoBackup - $HOSTNAME - START $DEBUT" \
|
||||
>> /var/log/evobackup.log
|
||||
# Remote shell command
|
||||
RSH_COMMAND="ssh -p ${SSH_PORT} -o 'ConnectTimeout ${SSH_CONNECT_TIMEOUT}'"
|
||||
|
||||
echo "EvoBackup - $HOSTNAME - STOP $FIN" \
|
||||
>> /var/log/evobackup.log
|
||||
rsync -avzh --stats --delete --delete-excluded --force --ignore-errors --partial \
|
||||
--exclude "lost+found" \
|
||||
--exclude ".nfs.*" \
|
||||
--exclude "/var/log" \
|
||||
--exclude "/var/log/evobackup*" \
|
||||
--exclude "/var/lib/mysql" \
|
||||
--exclude "/var/lib/postgres" \
|
||||
--exclude "/var/lib/postgresql" \
|
||||
--exclude "/var/lib/sympa" \
|
||||
--exclude "/var/lib/metche" \
|
||||
--exclude "/var/run" \
|
||||
--exclude "/var/lock" \
|
||||
--exclude "/var/state" \
|
||||
--exclude "/var/apt" \
|
||||
--exclude "/var/cache" \
|
||||
--exclude "/usr/src" \
|
||||
--exclude "/usr/doc" \
|
||||
--exclude "/usr/share/doc" \
|
||||
--exclude "/usr/obj" \
|
||||
--exclude "dev" \
|
||||
--exclude "/var/spool/postfix" \
|
||||
--exclude "/var/lib/amavis/amavisd.sock" \
|
||||
--exclude "/var/lib/munin/*tmp*" \
|
||||
--exclude "/var/lib/php5" \
|
||||
--exclude "/var/spool/squid" \
|
||||
--exclude "/var/lib/elasticsearch" \
|
||||
--exclude "/var/lib/amavis/tmp" \
|
||||
--exclude "/var/lib/clamav/*.tmp" \
|
||||
--exclude "/home/mysqltmp" \
|
||||
--exclude "/var/lib/php/sessions" \
|
||||
${rep} \
|
||||
/etc \
|
||||
/root \
|
||||
/var \
|
||||
/home \
|
||||
-e "${RSH_COMMAND}" \
|
||||
"root@${SSH_SERVER}:/var/backup/" \
|
||||
| tail -30 >> $LOGFILE
|
||||
fi
|
||||
|
||||
tail -10 /var/log/evobackup.log | \
|
||||
mail -s "[info] EvoBackup - Client $HOSTNAME" \
|
||||
$MAIL
|
||||
##### REPORTING #######################################################
|
||||
|
||||
END=$(/bin/date +"%d-%m-%Y ; %H:%M")
|
||||
|
||||
printf "EvoBackup - %s - START %s ON %s (LOCAL_TASKS=%s SYNC_TASKS=%s)\n" \
|
||||
"${HOSTNAME}" "${BEGINNING}" "${SSH_SERVER}" "${LOCAL_TASKS}" "${SYNC_TASKS}" \
|
||||
>> $LOGFILE
|
||||
|
||||
printf "EvoBackup - %s - STOP %s ON %s (LOCAL_TASKS=%s SYNC_TASKS=%s)\n" \
|
||||
"${HOSTNAME}" "${END}" "${SSH_SERVER}" "${LOCAL_TASKS}" "${SYNC_TASKS}" \
|
||||
>> $LOGFILE
|
||||
|
||||
tail -10 $LOGFILE | \
|
||||
mail -s "[info] EvoBackup - Client ${HOSTNAME}" \
|
||||
${MAIL}
|
||||
|
|
|
@ -1,3 +1,33 @@
|
|||
---
|
||||
- name: newaliases
|
||||
shell: smtpctl update table aliases
|
||||
|
||||
- name: remount / noatime
|
||||
command: mount -u -o noatime /
|
||||
args:
|
||||
warn: false
|
||||
|
||||
- name: remount /var noatime
|
||||
command: mount -u -o noatime /var
|
||||
args:
|
||||
warn: false
|
||||
|
||||
- name: remount /usr noatime
|
||||
command: mount -u -o noatime /usr
|
||||
args:
|
||||
warn: false
|
||||
|
||||
- name: remount /tmp noexec
|
||||
command: mount -u -o noexec /tmp
|
||||
args:
|
||||
warn: false
|
||||
|
||||
- name: remount /tmp noatime
|
||||
command: mount -u -o noatime /tmp
|
||||
args:
|
||||
warn: false
|
||||
|
||||
- name: remount /home noatime
|
||||
command: mount -u -o noatime /home
|
||||
args:
|
||||
warn: false
|
||||
|
|
19
roles/base/tasks/cron.yml
Normal file
19
roles/base/tasks/cron.yml
Normal file
|
@ -0,0 +1,19 @@
|
|||
---
|
||||
- name: Customize PATH variable of root crontab
|
||||
cron:
|
||||
name: PATH
|
||||
env: true
|
||||
value: "{{ cron_root_path }}"
|
||||
tags:
|
||||
- cron
|
||||
|
||||
- name: Customize daily.local environment
|
||||
lineinfile:
|
||||
path: /etc/daily.local
|
||||
line: 'VERBOSESTATUS=0'
|
||||
insertbefore: BOF
|
||||
owner: root
|
||||
mode: "0644"
|
||||
create: true
|
||||
tags:
|
||||
- cron
|
|
@ -6,8 +6,6 @@
|
|||
owner: root
|
||||
group: wheel
|
||||
mode: "0640"
|
||||
backup: no
|
||||
backup: false
|
||||
tags:
|
||||
- doas
|
||||
|
||||
|
||||
- doas
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
- name: Customize root's .profile
|
||||
copy:
|
||||
src: profile
|
||||
template:
|
||||
src: profile.j2
|
||||
dest: /root/.profile
|
||||
tags:
|
||||
- admin
|
||||
|
@ -26,8 +26,8 @@
|
|||
- dotfiles
|
||||
|
||||
- name: Change default .profile skeleton
|
||||
copy:
|
||||
src: profile
|
||||
template:
|
||||
src: profile.j2
|
||||
dest: /etc/skel/.profile
|
||||
tags:
|
||||
- admin
|
||||
|
@ -39,10 +39,10 @@
|
|||
dest: /etc/skel/.profile
|
||||
insertafter: EOF
|
||||
line: 'trap "doas /usr/share/scripts/evomaintenance.sh" 0'
|
||||
create: yes
|
||||
create: true
|
||||
tags:
|
||||
- admin
|
||||
- dotfiles
|
||||
- admin
|
||||
- dotfiles
|
||||
|
||||
- name: Add vim configuration to dotfiles for new users
|
||||
copy:
|
||||
|
|
|
@ -6,7 +6,16 @@
|
|||
owner: root
|
||||
group: wheel
|
||||
mode: "0755"
|
||||
force: no
|
||||
force: false
|
||||
tags:
|
||||
- evobackup
|
||||
|
||||
- name: Fetch daily.local content
|
||||
command: 'grep "sh /usr/share/scripts/zzz_evobackup" /etc/daily.local'
|
||||
check_mode: false
|
||||
register: daily_local_content
|
||||
failed_when: false
|
||||
changed_when: false
|
||||
tags:
|
||||
- evobackup
|
||||
|
||||
|
@ -16,5 +25,18 @@
|
|||
line: '#sh /usr/share/scripts/zzz_evobackup'
|
||||
owner: root
|
||||
mode: "0644"
|
||||
create: true
|
||||
when:
|
||||
- not (daily_local_content.stdout
|
||||
| regex_search('sh /usr/share/scripts/zzz_evobackup'))
|
||||
tags:
|
||||
- evobackup
|
||||
|
||||
- name: Delete evobackup root crontab replaced by daily.local cron
|
||||
lineinfile:
|
||||
path: /var/cron/tabs/root
|
||||
regexp: '/usr/share/scripts/zzz_evobackup'
|
||||
validate: /usr/bin/crontab %s
|
||||
state: absent
|
||||
tags:
|
||||
- evobackup
|
||||
|
|
|
@ -10,10 +10,15 @@
|
|||
- evomaintenance
|
||||
|
||||
- name: Copy evomaintenance script and template
|
||||
copy: src={{ item.src }} dest={{ item.dest }} owner=root group=wheel mode="0755"
|
||||
copy:
|
||||
src: "{{ item.src }}"
|
||||
dest: "{{ item.dest }}"
|
||||
owner: 'root'
|
||||
group: 'wheel'
|
||||
mode: '0755'
|
||||
with_items:
|
||||
- { src: 'evomaintenance.sh', dest: '/usr/share/scripts/' }
|
||||
- { src: 'evomaintenance.tpl', dest: '/usr/share/scripts/' }
|
||||
- {src: 'evomaintenance.sh', dest: '/usr/share/scripts/'}
|
||||
- {src: 'evomaintenance.tpl', dest: '/usr/share/scripts/'}
|
||||
tags:
|
||||
- evomaintenance
|
||||
- script-evomaintenance
|
||||
|
@ -25,27 +30,6 @@
|
|||
owner: root
|
||||
group: wheel
|
||||
mode: "0600"
|
||||
backup: no
|
||||
backup: false
|
||||
tags:
|
||||
- evomaintenance
|
||||
|
||||
- name: Copy mailevomaintenance
|
||||
template:
|
||||
src: mailevomaintenance.sh.j2
|
||||
dest: /usr/share/scripts/mailevomaintenance.sh
|
||||
owner: root
|
||||
group: wheel
|
||||
mode: "0700"
|
||||
tags:
|
||||
- evomaintenance
|
||||
- mailevomaintenance
|
||||
|
||||
- name: Add mailevomaintenance cron
|
||||
cron:
|
||||
name: "mailevomaintenance"
|
||||
job: "/usr/share/scripts/mailevomaintenance.sh"
|
||||
minute: "50"
|
||||
hour: "22"
|
||||
disabled: yes
|
||||
tags:
|
||||
- mailevomaintenance
|
||||
|
|
138
roles/base/tasks/fstab.yml
Normal file
138
roles/base/tasks/fstab.yml
Normal file
|
@ -0,0 +1,138 @@
|
|||
---
|
||||
- name: Fetch fstab content
|
||||
command: "grep -v '^#' /etc/fstab"
|
||||
check_mode: false
|
||||
register: fstab_content
|
||||
failed_when: false
|
||||
changed_when: false
|
||||
tags:
|
||||
- fstab
|
||||
|
||||
- name: / partition is customized - softdep
|
||||
replace:
|
||||
dest: /etc/fstab
|
||||
regexp: '([^#]\s+/\s+ffs\s+rw)(.*)'
|
||||
replace: '\1,softdep\2'
|
||||
when:
|
||||
- fstab_content.stdout | regex_search('\s/\s')
|
||||
- not (fstab_content.stdout | regex_search('\s+/\s+ffs\s+rw,softdep'))
|
||||
tags:
|
||||
- fstab
|
||||
|
||||
- name: / partition is customized - noatime
|
||||
replace:
|
||||
dest: /etc/fstab
|
||||
regexp: '([^#]\s+/\s+ffs\s+rw)(\S*)(\s+.*)'
|
||||
replace: '\1\2,noatime\3'
|
||||
notify: remount / noatime
|
||||
when:
|
||||
- fstab_content.stdout | regex_search('\s/\s')
|
||||
- not (fstab_content.stdout | regex_search('\s+/\s+ffs\s+rw\S*noatime'))
|
||||
tags:
|
||||
- fstab
|
||||
|
||||
- name: /var partition is customized - softdep
|
||||
replace:
|
||||
dest: /etc/fstab
|
||||
regexp: '([^#]\s+/var\s+ffs\s+rw)(.*)'
|
||||
replace: '\1,softdep\2'
|
||||
when:
|
||||
- fstab_content.stdout | regex_search('\s/var\s')
|
||||
- not (fstab_content.stdout | regex_search('\s+/var\s+ffs\s+rw,softdep'))
|
||||
tags:
|
||||
- fstab
|
||||
|
||||
- name: /var partition is customized - noatime
|
||||
replace:
|
||||
dest: /etc/fstab
|
||||
regexp: '([^#]\s+/var\s+ffs\s+rw)(\S*)(\s+.*)'
|
||||
replace: '\1\2,noatime\3'
|
||||
notify: remount /var noatime
|
||||
when:
|
||||
- fstab_content.stdout | regex_search('\s/var\s')
|
||||
- not (fstab_content.stdout | regex_search('\s+/var\s+ffs\s+rw\S*noatime'))
|
||||
tags:
|
||||
- fstab
|
||||
|
||||
- name: /usr partition is customized - softdep
|
||||
replace:
|
||||
dest: /etc/fstab
|
||||
regexp: '([^#]\s+/usr\s+ffs\s+rw)(.*)'
|
||||
replace: '\1,softdep\2'
|
||||
when:
|
||||
- fstab_content.stdout | regex_search('\s/usr\s')
|
||||
- not (fstab_content.stdout | regex_search('\s+/usr\s+ffs\s+rw,softdep'))
|
||||
tags:
|
||||
- fstab
|
||||
|
||||
- name: /usr partition is customized - noatime
|
||||
replace:
|
||||
dest: /etc/fstab
|
||||
regexp: '([^#]\s+/usr\s+ffs\s+rw)(\S*)(\s+.*)'
|
||||
replace: '\1\2,noatime\3'
|
||||
notify: remount /usr noatime
|
||||
when:
|
||||
- fstab_content.stdout | regex_search('\s/usr\s')
|
||||
- not (fstab_content.stdout | regex_search('\s+/usr\s+ffs\s+rw\S*noatime'))
|
||||
tags:
|
||||
- fstab
|
||||
|
||||
- name: /tmp partition is customized - noexec
|
||||
replace:
|
||||
dest: /etc/fstab
|
||||
regexp: '([^#]\s+/tmp\s+ffs\s+rw(,softdep)*)(.*)'
|
||||
replace: '\1,noexec\3'
|
||||
notify: remount /tmp noexec
|
||||
when:
|
||||
- fstab_content.stdout | regex_search('\s/tmp\s')
|
||||
- not (fstab_content.stdout
|
||||
| regex_search('\s+/tmp\s+ffs\s+rw,(softdep,)*noexec'))
|
||||
tags:
|
||||
- fstab
|
||||
|
||||
- name: /tmp partition is customized - softdep
|
||||
replace:
|
||||
dest: /etc/fstab
|
||||
regexp: '([^#]\s+/tmp\s+ffs\s+rw)(.*)'
|
||||
replace: '\1,softdep\2'
|
||||
when:
|
||||
- fstab_content.stdout | regex_search('\s/tmp\s')
|
||||
- not (fstab_content.stdout
|
||||
| regex_search('\s+/tmp\s+ffs\s+rw,(noexec,)*softdep'))
|
||||
tags:
|
||||
- fstab
|
||||
|
||||
- name: /tmp partition is customized - noatime
|
||||
replace:
|
||||
dest: /etc/fstab
|
||||
regexp: '([^#]\s+/tmp\s+ffs\s+rw)(\S*)(\s+.*)'
|
||||
replace: '\1\2,noatime\3'
|
||||
notify: remount /tmp noatime
|
||||
when:
|
||||
- fstab_content.stdout | regex_search('\s/tmp\s')
|
||||
- not (fstab_content.stdout | regex_search('\s+/tmp\s+ffs\s+rw\S*noatime'))
|
||||
tags:
|
||||
- fstab
|
||||
|
||||
- name: /home partition is customized - softdep
|
||||
replace:
|
||||
dest: /etc/fstab
|
||||
regexp: '([^#]\s+/home\s+ffs\s+rw)(.*)'
|
||||
replace: '\1,softdep\2'
|
||||
when:
|
||||
- fstab_content.stdout | regex_search('\s/home\s')
|
||||
- not (fstab_content.stdout | regex_search('\s+/home\s+ffs\s+rw,softdep'))
|
||||
tags:
|
||||
- fstab
|
||||
|
||||
- name: /home partition is customized - noatime
|
||||
replace:
|
||||
dest: /etc/fstab
|
||||
regexp: '([^#]\s+/home\s+ffs\s+rw)(\S*)(\s+.*)'
|
||||
replace: '\1\2,noatime\3'
|
||||
notify: remount /home noatime
|
||||
when:
|
||||
- fstab_content.stdout | regex_search('\s/home\s')
|
||||
- not (fstab_content.stdout | regex_search('\s+/home\s+ffs\s+rw\S*noatime'))
|
||||
tags:
|
||||
- fstab
|
|
@ -1,9 +1,32 @@
|
|||
---
|
||||
- name: Fetch rc.local content
|
||||
command: "grep -v '^#' /etc/rc.local"
|
||||
check_mode: false
|
||||
register: rclocal_content
|
||||
failed_when: false
|
||||
changed_when: false
|
||||
tags:
|
||||
- misc
|
||||
|
||||
- name: Configure rc.local
|
||||
lineinfile:
|
||||
path: /etc/rc.local
|
||||
line: 'date | mail -s "boot/reboot of $(hostname -s)" {{ general_alert_email }}'
|
||||
create: yes
|
||||
line:
|
||||
'date | mail -s "boot/reboot of $(hostname -s)" {{ general_alert_email }}'
|
||||
insertbefore: 'echo'
|
||||
create: true
|
||||
when:
|
||||
- not (rclocal_content.stdout
|
||||
| regex_search('date \| mail -s (\"|\')boot/reboot of \$\(hostname -s\)'))
|
||||
tags:
|
||||
- misc
|
||||
|
||||
- name: Delete rc.local entry of boot/reboot not precising hostname
|
||||
lineinfile:
|
||||
path: /etc/rc.local
|
||||
regexp:
|
||||
"^.* mail -s (?!.*of.*).+$"
|
||||
state: absent
|
||||
tags:
|
||||
- misc
|
||||
|
||||
|
@ -12,7 +35,7 @@
|
|||
dest: /etc/mail/aliases
|
||||
regexp: "# root:"
|
||||
replace: "root: {{ general_alert_email }}"
|
||||
backup: no
|
||||
backup: false
|
||||
notify:
|
||||
- newaliases
|
||||
tags:
|
||||
|
|
|
@ -7,3 +7,6 @@
|
|||
- include: mail.yml
|
||||
- include: sudo.yml
|
||||
- include: evobackup.yml
|
||||
- include: newsyslog.yml
|
||||
- include: cron.yml
|
||||
- include: fstab.yml
|
||||
|
|
7
roles/base/tasks/newsyslog.yml
Normal file
7
roles/base/tasks/newsyslog.yml
Normal file
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
- name: Customize newsyslog
|
||||
copy:
|
||||
src: newsyslog.conf
|
||||
dest: /etc/newsyslog.conf
|
||||
tags:
|
||||
- newsyslog
|
|
@ -9,23 +9,20 @@
|
|||
|
||||
- name: Install packages (vim rsync mtr etc)
|
||||
openbsd_pkg:
|
||||
name: "{{ item }}"
|
||||
state: present
|
||||
with_items:
|
||||
- wget
|
||||
- vim--no_x11
|
||||
- rsync--
|
||||
- mtr--
|
||||
- iftop
|
||||
- postgresql-client
|
||||
name:
|
||||
- wget
|
||||
- vim--no_x11
|
||||
- rsync--
|
||||
- mtr--
|
||||
- iftop
|
||||
- sudo--
|
||||
tags:
|
||||
- pkg
|
||||
|
||||
- name: Install sudo
|
||||
openbsd_pkg:
|
||||
name: "{{ item }}"
|
||||
state: present
|
||||
with_items:
|
||||
- sudo--
|
||||
- name: Disable sndiod
|
||||
service:
|
||||
name: sndiod
|
||||
enabled: false
|
||||
state: stopped
|
||||
tags:
|
||||
- pkg
|
||||
|
|
|
@ -1,14 +1,32 @@
|
|||
---
|
||||
# dont't break the tab!
|
||||
- name: Configure sudoers umask
|
||||
lineinfile:
|
||||
dest: /etc/sudoers
|
||||
insertafter: '# Defaults specification'
|
||||
line: 'Defaults umask=0077'
|
||||
validate: 'visudo -cf %s'
|
||||
tags:
|
||||
- sudo
|
||||
|
||||
- name: Allow wheel group to run command as root in sudo
|
||||
lineinfile:
|
||||
dest: /etc/sudoers
|
||||
insertafter: '# and set environment variables.'
|
||||
line: '%wheel ALL=(ALL) SETENV: ALL'
|
||||
line: "%wheel\tALL=(ALL) SETENV: ALL"
|
||||
validate: 'visudo -cf %s'
|
||||
backup: no
|
||||
backup: false
|
||||
tags:
|
||||
- sudo
|
||||
- sudo
|
||||
|
||||
- name: Delete line with space instead of tab
|
||||
lineinfile:
|
||||
dest: /etc/sudoers
|
||||
line: "%wheel ALL=(ALL) SETENV: ALL"
|
||||
validate: 'visudo -cf %s'
|
||||
backup: false
|
||||
state: absent
|
||||
tags:
|
||||
- sudo
|
||||
|
||||
- name: Configure sudoers for evomaintenance and monitoring
|
||||
blockinfile:
|
||||
|
@ -18,12 +36,8 @@
|
|||
block: |
|
||||
Cmnd_Alias MAINT = /usr/share/scripts/evomaintenance.sh
|
||||
%wheel ALL=NOPASSWD: MAINT
|
||||
_nrpe ALL=(root) NOPASSWD: /usr/local/libexec/nagios/plugins/check_ipsecctl.sh
|
||||
_nrpe ALL=(root) NOPASSWD: /usr/local/libexec/nagios/check_mailq
|
||||
_nrpe ALL=(root) NOPASSWD: /usr/local/libexec/nagios/plugins/check_ospfd_simple
|
||||
%evolinux-sudo ALL=(ALL) SETENV: ALL
|
||||
validate: 'visudo -cf %s'
|
||||
backup: no
|
||||
backup: false
|
||||
tags:
|
||||
- sudo
|
||||
|
||||
|
||||
- sudo
|
||||
|
|
|
@ -1,11 +1,18 @@
|
|||
# {{ ansible_managed }}
|
||||
permit setenv {ENV PS1 SSH_AUTH_SOCK SSH_TTY} :wheel
|
||||
permit setenv {SSH_AUTH_SOCK SSH_TTY PKG_PATH HOME=/root ENV=/root/.profile} :{{ evobsd_sudo_group }}
|
||||
permit nopass root
|
||||
permit setenv {ENV PS1 SSH_AUTH_SOCK SSH_TTY} nopass :wheel as root cmd /usr/share/scripts/evomaintenance.sh
|
||||
permit nopass _nrpe cmd /usr/local/libexec/nagios/check_ipsecctl.sh
|
||||
permit nopass _nrpe as root cmd /sbin/bioctl args sd2
|
||||
permit nopass _nrpe as root cmd /usr/local/libexec/nagios/check_openbgpd
|
||||
permit setenv {ENV PS1 SSH_AUTH_SOCK SSH_TTY} nopass :{{ evobsd_ssh_group }} as root cmd /usr/share/scripts/evomaintenance.sh
|
||||
permit nopass _collectd as root cmd /bin/cat
|
||||
permit nopass _collectd as root cmd /usr/sbin/bgpctl
|
||||
permit nopass _nrpe as root cmd /sbin/bioctl args sd2
|
||||
permit nopass _nrpe as root cmd /usr/local/libexec/nagios/check_mailq
|
||||
permit nopass _nrpe as root cmd /usr/local/libexec/nagios/check_dhcp
|
||||
permit nopass _nrpe as root cmd /usr/local/libexec/nagios/plugins/check_ipsecctl.sh
|
||||
permit nopass _nrpe as root cmd /usr/local/libexec/nagios/plugins/check_ospfd_simple
|
||||
permit nopass _nrpe as root cmd /usr/local/libexec/nagios/plugins/check_ospfd
|
||||
permit nopass _nrpe as root cmd /usr/local/libexec/nagios/plugins/check_ospf6d
|
||||
permit nopass _nrpe as root cmd /usr/local/libexec/nagios/plugins/check_openbgpd
|
||||
permit nopass _nrpe as root cmd /usr/local/libexec/nagios/plugins/check_pf_states
|
||||
permit nopass _nrpe as root cmd /usr/local/libexec/nagios/plugins/check_connections_state.sh
|
||||
permit nopass _nrpe as root cmd /usr/local/libexec/nagios/plugins/check_packetfilter.sh
|
||||
permit nopass _nrpe as root cmd /usr/local/libexec/nagios/plugins/check_ipsecctl_critiques.sh
|
||||
|
|
|
@ -1,13 +1,20 @@
|
|||
HOSTNAME={{ evomaintenance_hostname }}
|
||||
EVOMAINTMAIL={{ evomaintenance_alert_email or general_alert_email | mandatory }}
|
||||
|
||||
export PGPASSWORD={{ evomaintenance_pg_passwd | mandatory }}
|
||||
export PGPASSWORD={{ evomaintenance_pg_passwd }}
|
||||
|
||||
PGDB={{ evomaintenance_pg_db | mandatory }}
|
||||
PGTABLE={{ evomaintenance_pg_table | mandatory }}
|
||||
PGHOST={{ evomaintenance_pg_host | mandatory }}
|
||||
PGDB={{ evomaintenance_pg_db }}
|
||||
PGTABLE={{ evomaintenance_pg_table }}
|
||||
PGHOST={{ evomaintenance_pg_host }}
|
||||
FROM={{ evomaintenance_from }}
|
||||
FULLFROM="{{ evomaintenance_full_from }}"
|
||||
URGENCYFROM={{ evomaintenance_urgency_from }}
|
||||
URGENCYTEL="{{ evomaintenance_urgency_tel }}"
|
||||
REALM="{{ evomaintenance_realm }}"
|
||||
API_ENDPOINT={{ evomaintenance_api_endpoint }}
|
||||
API_KEY={{ evomaintenance_api_key }}
|
||||
|
||||
HOOK_API={{ evomaintenance_hook_api | bool | ternary('1','0') }}
|
||||
HOOK_DB={{ evomaintenance_hook_db | bool | ternary('1','0') }}
|
||||
HOOK_COMMIT={{ evomaintenance_hook_commit | bool | ternary('1','0') }}
|
||||
HOOK_MAIL={{ evomaintenance_hook_mail | bool | ternary('1','0') }}
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
set -eu
|
||||
|
||||
cd /etc && _STATUS=$(/usr/local/bin/git status --porcelain)
|
||||
[ -n "${_STATUS}" ] || exit 0
|
||||
|
||||
if [ -e /etc/realname ]; then
|
||||
_HOSTNAME=$(/bin/cat /etc/realname)
|
||||
else
|
||||
_HOSTNAME=$(/bin/hostname)
|
||||
fi
|
||||
|
||||
|
||||
TMPFILE=$(/usr/bin/mktemp) || exit 1
|
||||
echo "Dear NOC,\n\nSome changes in /etc/ were not committed." >> $TMPFILE
|
||||
|
||||
echo "" >> $TMPFILE
|
||||
echo "${_STATUS}" >> $TMPFILE
|
||||
|
||||
echo "" >> $TMPFILE
|
||||
/usr/bin/last | head -n 10 >> $TMPFILE
|
||||
echo "" >> $TMPFILE
|
||||
echo "Please answer this mail to notify people when you've corrected the problem." >> $TMPFILE
|
||||
|
||||
/bin/cat $TMPFILE | mail -s "Verif etc-git ${_HOSTNAME}" noc@{{ evomaintenance_realm }}
|
||||
|
||||
/bin/rm $TMPFILE
|
56
roles/base/templates/profile.j2
Normal file
56
roles/base/templates/profile.j2
Normal file
|
@ -0,0 +1,56 @@
|
|||
# $OpenBSD: dot.profile,v 1.5 2018/02/02 02:29:54 yasuoka Exp $
|
||||
#
|
||||
# sh/ksh initialization
|
||||
|
||||
PATH="{{ evobsd_path }}"
|
||||
export PATH HOME TERM
|
||||
export PS1="\u@\h:\w\\$ "
|
||||
HISTFILE=$HOME/.histfile
|
||||
export HISTSIZE=10000
|
||||
export HISTCONTROL='ignoredups:ignorespace'
|
||||
export TMOUT=36000
|
||||
export PAGER=less
|
||||
umask 022
|
||||
|
||||
export ENV='~/.kshrc'
|
||||
|
||||
case "$-" in
|
||||
*i*) # interactive shell
|
||||
if [ -x /usr/bin/tset ]; then
|
||||
if [ X"$XTERM_VERSION" = X"" ]; then
|
||||
eval `/usr/bin/tset -sQ '-munknown:?vt220' $TERM`
|
||||
else
|
||||
eval `/usr/bin/tset -IsQ '-munknown:?vt220' $TERM`
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
PKG_LIST=$(ls -1 /var/db/pkg)
|
||||
|
||||
set -A complete_kill_1 -- -9 -HUP -INFO -KILL -TERM
|
||||
pgrep -q vmd
|
||||
if [ $? = 0 ]; then
|
||||
set -A complete_vmctl -- console load reload start stop reset status
|
||||
set -A complete_vmctl_2 -- $(vmctl status | awk '!/NAME/{print $NF}')
|
||||
fi
|
||||
if [ -d ~/.password-store ]; then
|
||||
PASS_LIST=$(
|
||||
cd ~/.password-store
|
||||
find . -type f -name \*.gpg | sed 's/^\.\///' | sed 's/\.gpg$//g'
|
||||
)
|
||||
|
||||
set -A complete_pass -- $PASS_LIST -c generate edit insert git
|
||||
set -A complete_pass_2 -- $PASS_LIST push
|
||||
fi
|
||||
set -A complete_pkg_delete -- $PKG_LIST
|
||||
set -A complete_pkg_info -- $PKG_LIST
|
||||
set -A complete_rcctl_1 -- disable enable get ls order set reload check restart stop start
|
||||
set -A complete_rcctl_2 -- $(ls /etc/rc.d)
|
||||
set -A complete_signify_1 -- -C -G -S -V
|
||||
set -A complete_signify_2 -- -q -p -x -c -m -t -z
|
||||
set -A complete_signify_3 -- -p -x -c -m -t -z
|
||||
set -A complete_make_1 -- install clean repackage reinstall
|
||||
set -A complete_gpg2 -- --refresh --receive-keys --armor --clearsign --sign --list-key --decrypt --verify --detach-sig
|
||||
set -A complete_git -- pull push mpull mpush status clone branch add rm checkout fetch show tag commit
|
||||
set -A complete_ifconfig_1 -- $(ifconfig | grep ^[a-z] | cut -d: -f1)
|
14
roles/bgp/README.md
Normal file
14
roles/bgp/README.md
Normal file
|
@ -0,0 +1,14 @@
|
|||
# BGP
|
||||
|
||||
Deployment of BGP check script with its cron, and a best route log cron.
|
||||
|
||||
## Tasks
|
||||
|
||||
Everything is in the `tasks/main.yml` file.
|
||||
|
||||
## Available variables
|
||||
|
||||
The full list of variables (with default values) can be found in `defaults/main.yml`.
|
||||
|
||||
* `bgp_mailto` : email address the output of the script will be sent to when a change is detected
|
||||
* `bgp_exclude_grep_command` : facultative grep -v command for some peers not to be checked
|
3
roles/bgp/defaults/main.yml
Normal file
3
roles/bgp/defaults/main.yml
Normal file
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
bgp_mailto: "foobar@example.com"
|
||||
bgp_exclude_grep_command: ""
|
52
roles/bgp/tasks/main.yml
Normal file
52
roles/bgp/tasks/main.yml
Normal file
|
@ -0,0 +1,52 @@
|
|||
---
|
||||
- name: Deploy bgp check script
|
||||
template:
|
||||
src: bgpd-check-peers.sh.j2
|
||||
dest: /usr/share/scripts/bgpd-check-peers.sh
|
||||
when: group_names | select('search','bgp') | list | count > 0
|
||||
tags:
|
||||
- bgp
|
||||
|
||||
- name: Cron job for bgp check script is installed
|
||||
cron:
|
||||
name: bgp check
|
||||
job: "/bin/sh /usr/share/scripts/bgpd-check-peers.sh"
|
||||
when: group_names | select('search','bgp') | list | count > 0
|
||||
tags:
|
||||
- bgp
|
||||
|
||||
- name: Create bgp log directory
|
||||
file:
|
||||
path: /var/log/bgp
|
||||
state: directory
|
||||
when: group_names | select('search','bgp') | list | count > 0
|
||||
tags:
|
||||
- bgp
|
||||
|
||||
- name: daily best routes cron job is installed
|
||||
cron:
|
||||
name: bgp best routes
|
||||
minute: 0
|
||||
hour: 4
|
||||
job: >
|
||||
/usr/sbin/bgpctl show rib selected
|
||||
> /var/log/bgp/rib-selected-$(date +\%F)
|
||||
when: group_names | select('search','bgp') | list | count > 0
|
||||
tags:
|
||||
- bgp
|
||||
|
||||
- name: weekly best routes clean up cron job is installed
|
||||
cron:
|
||||
name: bgp best routes clean up
|
||||
minute: 0
|
||||
hour: 4
|
||||
weekday: 0
|
||||
job: >
|
||||
/usr/bin/find /var/log/bgp/
|
||||
-type f
|
||||
-name "rib-selected-*"
|
||||
-mtime +30
|
||||
-exec rm {} \+
|
||||
when: group_names | select('search','bgp') | list | count > 0
|
||||
tags:
|
||||
- bgp
|
117
roles/bgp/templates/bgpd-check-peers.sh.j2
Executable file
117
roles/bgp/templates/bgpd-check-peers.sh.j2
Executable file
|
@ -0,0 +1,117 @@
|
|||
#!/bin/ksh
|
||||
|
||||
# Script writen by Daniel Jakots
|
||||
|
||||
# First we go through the list of neighbor and we write all the peer and
|
||||
# their status in "${_TMPDIR}"/bgp-status.
|
||||
|
||||
# Then we monitor if this file has changed between now and the previous run.
|
||||
|
||||
# If it did, we send a mail with the states of the different sessions.
|
||||
|
||||
set -u
|
||||
|
||||
PATH=$HOME/bin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:.
|
||||
|
||||
_MAILTO="{{ bgp_mailto }}"
|
||||
_TMPDIR=/tmp/check-bgp
|
||||
_PIDFILE="${_TMPDIR}"/bgpd-check-peers.pid
|
||||
|
||||
|
||||
if [ -e /etc/realname ]; then
|
||||
_REALNAME=$(cat /etc/realname)
|
||||
_HOSTNAME=$(hostname -s)
|
||||
else
|
||||
_HOSTNAME=$(hostname)
|
||||
fi
|
||||
|
||||
mkdir -p "${_TMPDIR}"
|
||||
|
||||
# Don't try to run if it's already running
|
||||
if [ -e "${_PIDFILE}" ]; then
|
||||
echo "$(date)" >> "${_TMPDIR}"/log
|
||||
exit 1
|
||||
else
|
||||
echo $$ >> "${_PIDFILE}"
|
||||
fi
|
||||
|
||||
# Create an history
|
||||
if [[ -f "${_TMPDIR}"/bgp-status ]] ; then
|
||||
mv "${_TMPDIR}"/bgp-status "${_TMPDIR}"/bgp-status.old
|
||||
else
|
||||
touch "${_TMPDIR}"/bgp-status
|
||||
touch "${_TMPDIR}"/bgp-status.old
|
||||
fi
|
||||
|
||||
# List peers and loops on them to list them and their BGP state
|
||||
bgpctl show neighbor | grep Description {{ bgp_exclude_grep_command }} | sed s,\ Description:\ ,,g > "${_TMPDIR}"/peers-list
|
||||
|
||||
while read _PEER
|
||||
do
|
||||
_STATUS=$(/usr/sbin/bgpctl show neighbor "${_PEER}" | grep state | awk '{print $4}' |tr -d ',')
|
||||
echo -n "${_PEER}" >> "${_TMPDIR}"/bgp-status
|
||||
echo -n " " >> "${_TMPDIR}"/bgp-status
|
||||
# we note only if it's established or not
|
||||
if ! [[ "${_STATUS}" = "Established" ]] ; then
|
||||
_STATUS="NotEstablished"
|
||||
fi
|
||||
echo "${_STATUS}" >> "${_TMPDIR}"/bgp-status
|
||||
|
||||
done <"${_TMPDIR}"/peers-list
|
||||
|
||||
# Check for difference with previous run
|
||||
different=$(diff -q "${_TMPDIR}"/bgp-status.old "${_TMPDIR}"/bgp-status)
|
||||
|
||||
if ! [[ -n "${different}" ]] ; then
|
||||
rm -f "${_PIDFILE}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# It changed so we're going to send a mail
|
||||
|
||||
_TMPMAILDIR="${_TMPDIR}"/mail
|
||||
mkdir -p "${_TMPMAILDIR}"
|
||||
|
||||
# go through sessions and list them depending on their BGP state
|
||||
echo "*** Session(s) OK ***\n" >> "${_TMPMAILDIR}"/bodyok
|
||||
while read _LINE
|
||||
do
|
||||
# _LINE is session + status
|
||||
_STATUS=$(echo "${_LINE##* }")
|
||||
_SESSION=$(echo "${_LINE}" | awk '{$NF=""}1')
|
||||
if [[ "${_STATUS}" = "Established" ]] ; then
|
||||
bgpctl show | grep "${_SESSION}" >> "${_TMPMAILDIR}"/bodyok
|
||||
else
|
||||
bgpctl show | grep "${_SESSION}" >> "${_TMPMAILDIR}"/bodynok
|
||||
fi
|
||||
done <"${_TMPDIR}"/bgp-status
|
||||
|
||||
# create the mail body
|
||||
|
||||
echo "Dear NOC,\n\nThe state of one or more BGP session(s) has changed:\n" > "${_TMPMAILDIR}"/header
|
||||
cat "${_TMPMAILDIR}"/header "${_TMPMAILDIR}"/bodyok > "${_TMPMAILDIR}"/body
|
||||
|
||||
_STATE="OK"
|
||||
if [[ -f "${_TMPMAILDIR}"/bodynok ]] ; then
|
||||
_STATE="NOT OK"
|
||||
echo "\n*** Session(s) on error ***\n" >> "${_TMPMAILDIR}"/body
|
||||
cat "${_TMPMAILDIR}"/bodynok >> "${_TMPMAILDIR}"/body
|
||||
fi
|
||||
|
||||
# show a diff
|
||||
echo "" >> "${_TMPMAILDIR}"/body
|
||||
echo "Diff is " >> "${_TMPMAILDIR}"/body
|
||||
diff -U0 "${_TMPDIR}"/bgp-status.old "${_TMPDIR}"/bgp-status >> "${_TMPMAILDIR}"/body
|
||||
|
||||
# Send the mail whether we have a realname or not
|
||||
if [ -n "${_REALNAME}" ]; then
|
||||
cat "${_TMPMAILDIR}"/body | mail -s "[BGP] ${_REALNAME} (${_HOSTNAME}) - State change - ${_STATE}" "${_MAILTO}"
|
||||
else
|
||||
cat "${_TMPMAILDIR}"/body | mail -s "[BGP] ${_HOSTNAME} - State change" "${_MAILTO}"
|
||||
fi
|
||||
|
||||
# cleaning
|
||||
if [[ -d "${_TMPMAILDIR}" ]] ; then
|
||||
rm -rf "${_TMPMAILDIR}"
|
||||
fi
|
||||
rm -f "${_PIDFILE}"
|
13
roles/collectd/README.md
Normal file
13
roles/collectd/README.md
Normal file
|
@ -0,0 +1,13 @@
|
|||
# Collectd
|
||||
|
||||
Installation and custom configuration of Collectd daemon.
|
||||
|
||||
## Tasks
|
||||
|
||||
Everything is in the `tasks/main.yml` file.
|
||||
|
||||
## Available variables
|
||||
|
||||
The full list of variables (with default values) can be found in `defaults/main.yml`.
|
||||
|
||||
* `collectd_server` : server to which the data will be sent (default: 127.0.0.1).
|
31
roles/collectd/defaults/main.yml
Normal file
31
roles/collectd/defaults/main.yml
Normal file
|
@ -0,0 +1,31 @@
|
|||
---
|
||||
|
||||
# destination server
|
||||
|
||||
collectd_server: "127.0.0.1"
|
||||
|
||||
# execution interval
|
||||
|
||||
collectd_interval: "300"
|
||||
|
||||
# exec plugin
|
||||
|
||||
collectd_plugin_exec_interval: "{{ collectd_interval }}"
|
||||
collectd_plugin_exec_ifq_drops: false
|
||||
collectd_plugin_exec_dns_stats: false # Based on unbound
|
||||
collectd_plugin_exec_dns_stats_interval: "{{ collectd_interval }}"
|
||||
|
||||
# others plugins
|
||||
|
||||
collectd_plugin_cpu: true
|
||||
collectd_plugin_df: true
|
||||
collectd_plugin_disk: true
|
||||
collectd_plugin_interface: true
|
||||
collectd_plugin_load: true
|
||||
collectd_plugin_memory: true
|
||||
collectd_plugin_pf: true
|
||||
collectd_plugin_processes: true
|
||||
collectd_plugin_swap: true
|
||||
collectd_plugin_tcpconns: true
|
||||
collectd_plugin_uptime: true
|
||||
collectd_plugin_users: true
|
3
roles/collectd/files/dns_stats.sh
Executable file
3
roles/collectd/files/dns_stats.sh
Executable file
|
@ -0,0 +1,3 @@
|
|||
#!/bin/ksh
|
||||
|
||||
echo "PUTVAL $(hostname)/dns_stats/count N:$(doas /bin/cat /var/log/daemon | grep "server stats" | grep -v "requestlist max" | awk '{print $13}' | tail -1)"
|
3
roles/collectd/files/ifq_drops.sh
Executable file
3
roles/collectd/files/ifq_drops.sh
Executable file
|
@ -0,0 +1,3 @@
|
|||
#!/bin/ksh
|
||||
|
||||
echo "PUTVAL $(hostname)/ifq_drops/count N:$(sysctl net.inet.ip.arpq.drops | awk -F= '{print $NF}')"
|
10
roles/collectd/handlers/main.yml
Normal file
10
roles/collectd/handlers/main.yml
Normal file
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
- name: restart collectd
|
||||
service:
|
||||
name: collectd
|
||||
state: restarted
|
||||
|
||||
- name: reload unbound
|
||||
service:
|
||||
name: unbound
|
||||
state: reloaded
|
97
roles/collectd/tasks/main.yml
Normal file
97
roles/collectd/tasks/main.yml
Normal file
|
@ -0,0 +1,97 @@
|
|||
---
|
||||
- name: Install Collectd package
|
||||
openbsd_pkg:
|
||||
name: "collectd"
|
||||
tags:
|
||||
- collectd
|
||||
|
||||
- name: Deploy Collectd configuration
|
||||
template:
|
||||
src: "collectd.conf.j2"
|
||||
dest: "/etc/collectd.conf"
|
||||
notify: restart collectd
|
||||
tags:
|
||||
- collectd
|
||||
|
||||
- name: Enabling Collectd
|
||||
service:
|
||||
name: collectd
|
||||
enabled: true
|
||||
tags:
|
||||
- collectd
|
||||
|
||||
- name: Create scripts directory for exec plugins
|
||||
file:
|
||||
path: /usr/local/share/collectd/scripts
|
||||
state: directory
|
||||
when: collectd_plugin_exec_ifq_drops or collectd_plugin_exec_dns_stats
|
||||
tags:
|
||||
- collectd
|
||||
|
||||
- name: Copy ifq_drops.sh
|
||||
copy:
|
||||
src: ifq_drops.sh
|
||||
dest: /usr/local/share/collectd/scripts/ifq_drops.sh
|
||||
mode: 0755
|
||||
force: true
|
||||
when: collectd_plugin_exec_ifq_drops
|
||||
tags:
|
||||
- collectd
|
||||
|
||||
- name: Remove ifq_drops.sh
|
||||
file:
|
||||
path: /usr/local/share/collectd/scripts/ifq_drops.sh
|
||||
state: absent
|
||||
when: not collectd_plugin_exec_ifq_drops
|
||||
tags:
|
||||
- collectd
|
||||
|
||||
- name: Copy dns_stats.sh
|
||||
copy:
|
||||
src: dns_stats.sh
|
||||
dest: /usr/local/share/collectd/scripts/dns_stats.sh
|
||||
mode: 0755
|
||||
force: true
|
||||
when: collectd_plugin_exec_dns_stats
|
||||
tags:
|
||||
- collectd
|
||||
|
||||
- name: Add stats DNS on unbound
|
||||
lineinfile:
|
||||
path: /var/unbound/etc/unbound.conf
|
||||
regexp: 'statistics-interval'
|
||||
line:
|
||||
' statistics-interval: {{ collectd_plugin_exec_dns_stats_interval }}'
|
||||
insertafter: 'hide-version:'
|
||||
backup: true
|
||||
notify: reload unbound
|
||||
when: collectd_plugin_exec_dns_stats
|
||||
tags:
|
||||
- collectd
|
||||
|
||||
- name: Remove dns_stats.sh
|
||||
file:
|
||||
path: /usr/local/share/collectd/scripts/dns_stats.sh
|
||||
state: absent
|
||||
when: not collectd_plugin_exec_dns_stats
|
||||
tags:
|
||||
- collectd
|
||||
|
||||
- name: Remove stats DNS on unbound
|
||||
lineinfile:
|
||||
path: /var/unbound/etc/unbound.conf
|
||||
regexp: 'statistics-interval'
|
||||
backup: true
|
||||
state: absent
|
||||
notify: reload unbound
|
||||
when: not collectd_plugin_exec_dns_stats
|
||||
tags:
|
||||
- collectd
|
||||
|
||||
- name: Add doas configuration for dns_stats.sh execution
|
||||
lineinfile:
|
||||
path: /etc/doas.conf
|
||||
line: 'permit nopass _collectd as root cmd /bin/cat'
|
||||
when: collectd_plugin_exec_dns_stats
|
||||
tags:
|
||||
- collectd
|
122
roles/collectd/templates/collectd.conf.j2
Normal file
122
roles/collectd/templates/collectd.conf.j2
Normal file
|
@ -0,0 +1,122 @@
|
|||
Interval {{ collectd_interval }}
|
||||
Timeout 2
|
||||
|
||||
LoadPlugin syslog
|
||||
<Plugin syslog>
|
||||
LogLevel warning
|
||||
</Plugin>
|
||||
|
||||
{% if (collectd_plugin_exec_ifq_drops is sameas true) or (collectd_plugin_exec_dns_stats is sameas true) %}
|
||||
<LoadPlugin exec>
|
||||
Interval {{ collectd_plugin_exec_interval }}
|
||||
</LoadPlugin>
|
||||
|
||||
<Plugin exec>
|
||||
{% if collectd_plugin_exec_ifq_drops is sameas true %}
|
||||
Exec "_collectd" "/usr/local/share/collectd/scripts/ifq_drops.sh"
|
||||
{% endif %}
|
||||
{% if collectd_plugin_exec_dns_stats is sameas true %}
|
||||
Exec "_collectd" "/usr/local/share/collectd/scripts/dns_stats.sh"
|
||||
{% endif %}
|
||||
</Plugin>
|
||||
|
||||
{% endif %}
|
||||
{% if collectd_plugin_load is sameas true %}
|
||||
LoadPlugin load
|
||||
{% endif %}
|
||||
{% if collectd_plugin_processes is sameas true %}
|
||||
LoadPlugin processes
|
||||
{% endif %}
|
||||
{% if collectd_plugin_uptime is sameas true %}
|
||||
LoadPlugin uptime
|
||||
{% endif %}
|
||||
{% if collectd_plugin_users is sameas true %}
|
||||
LoadPlugin users
|
||||
{% endif %}
|
||||
{% if collectd_plugin_pf is sameas true %}
|
||||
LoadPlugin pf
|
||||
{% endif %}
|
||||
|
||||
{% if collectd_plugin_df is sameas true %}
|
||||
LoadPlugin df
|
||||
<Plugin df>
|
||||
# expose host's mounts into container using -v /:/host:ro (location inside container does not matter much)
|
||||
# ignore rootfs; else, the root file-system would appear twice, causing
|
||||
# one of the updates to fail and spam the log
|
||||
## Seems to be fixed with collectd 5.5+
|
||||
## FSType rootfs
|
||||
# ignore the usual virtual / temporary file-systems
|
||||
FSType sysfs
|
||||
FSType proc
|
||||
FSType devtmpfs
|
||||
FSType devpts
|
||||
FSType tmpfs
|
||||
FSType fusectl
|
||||
FSType cgroup
|
||||
FSType overlay
|
||||
FSType debugfs
|
||||
FSType pstore
|
||||
FSType securityfs
|
||||
FSType hugetlbfs
|
||||
FSType squashfs
|
||||
FSType mqueue
|
||||
IgnoreSelected true
|
||||
|
||||
ReportByDevice false
|
||||
ReportInodes true # Default false
|
||||
ValuesAbsolute true
|
||||
ValuesPercentage true
|
||||
</Plugin>
|
||||
|
||||
{% endif %}
|
||||
{% if collectd_plugin_disk is sameas true %}
|
||||
LoadPlugin disk
|
||||
<Plugin "disk">
|
||||
#Disk "/^[hsv]d[a-z]/"
|
||||
IgnoreSelected false
|
||||
</Plugin>
|
||||
|
||||
{% endif %}
|
||||
{% if collectd_plugin_cpu is sameas true %}
|
||||
LoadPlugin cpu
|
||||
<Plugin cpu>
|
||||
ValuesPercentage true
|
||||
</Plugin>
|
||||
|
||||
{% endif %}
|
||||
{% if collectd_plugin_memory is sameas true %}
|
||||
LoadPlugin memory
|
||||
<Plugin memory>
|
||||
ValuesPercentage true
|
||||
</Plugin>
|
||||
|
||||
{% endif %}
|
||||
{% if collectd_plugin_swap is sameas true %}
|
||||
LoadPlugin swap
|
||||
<Plugin swap>
|
||||
ValuesPercentage true
|
||||
</Plugin>
|
||||
|
||||
{% endif %}
|
||||
{% if collectd_plugin_interface is sameas true %}
|
||||
LoadPlugin interface
|
||||
<Plugin interface>
|
||||
Interface "/^lo[0-9]*/"
|
||||
Interface "/^veth.*/"
|
||||
Interface "/^docker.*/"
|
||||
IgnoreSelected true
|
||||
ReportInactive false
|
||||
</Plugin>
|
||||
|
||||
{% endif %}
|
||||
{% if collectd_plugin_tcpconns is sameas true %}
|
||||
LoadPlugin tcpconns
|
||||
<Plugin "tcpconns">
|
||||
AllPortsSummary true
|
||||
</Plugin>
|
||||
|
||||
{% endif %}
|
||||
LoadPlugin network
|
||||
<Plugin "network">
|
||||
Server "{{ collectd_server }}" "25826"
|
||||
</Plugin>
|
|
@ -1,4 +1,4 @@
|
|||
---
|
||||
commit_message: Ansible run
|
||||
|
||||
etc_git_monitor_status: True
|
||||
etc_git_monitor_status: true
|
||||
|
|
|
@ -3,20 +3,20 @@
|
|||
command: git status --porcelain
|
||||
args:
|
||||
chdir: /etc
|
||||
changed_when: False
|
||||
changed_when: false
|
||||
register: git_status
|
||||
when: not ansible_check_mode
|
||||
ignore_errors: yes
|
||||
ignore_errors: true
|
||||
tags:
|
||||
- etc-git
|
||||
- commit-etc
|
||||
- etc-git
|
||||
- commit-etc
|
||||
|
||||
- debug:
|
||||
var: git_status
|
||||
verbosity: 3
|
||||
tags:
|
||||
- etc-git
|
||||
- commit-etc
|
||||
- etc-git
|
||||
- commit-etc
|
||||
|
||||
- name: fetch current Git user.email
|
||||
git_config:
|
||||
|
@ -24,33 +24,49 @@
|
|||
repo: /etc
|
||||
scope: local
|
||||
register: git_config_user_email
|
||||
ignore_errors: yes
|
||||
ignore_errors: true
|
||||
tags:
|
||||
- etc-git
|
||||
- commit-etc
|
||||
- etc-git
|
||||
- commit-etc
|
||||
|
||||
- name: set commit author
|
||||
set_fact:
|
||||
commit_author: '{% if ansible_env.SUDO_USER is not defined %}root{% else %}{{ ansible_env.SUDO_USER }}{% endif %}'
|
||||
commit_email: '{% if git_config_user_email.config_value is not defined or git_config_user_email.config_value == "" %}root@localhost{% else %}{{ git_config_user_email.config_value }}{% endif %}'
|
||||
commit_author: >
|
||||
{% if ansible_env.SUDO_USER is not defined %}
|
||||
root
|
||||
{% else %}
|
||||
{{ ansible_env.SUDO_USER }}
|
||||
{% endif %}
|
||||
commit_email: >
|
||||
{% if git_config_user_email.config_value is not defined
|
||||
or git_config_user_email.config_value == "" %}
|
||||
root@localhost
|
||||
{% else %}
|
||||
{{ git_config_user_email.config_value }}
|
||||
{% endif %}
|
||||
tags:
|
||||
- etc-git
|
||||
- commit-etc
|
||||
- etc-git
|
||||
- commit-etc
|
||||
|
||||
- name: /etc modifications are committed
|
||||
shell: "git add -A . && git commit -m \"{{ commit_message | mandatory }}\" --author \"{{ commit_author | mandatory }} <{{ commit_email | mandatory }}>\""
|
||||
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
|
||||
when: not ansible_check_mode and git_status.stdout != ""
|
||||
ignore_errors: yes
|
||||
ignore_errors: true
|
||||
tags:
|
||||
- etc-git
|
||||
- commit-etc
|
||||
- etc-git
|
||||
- commit-etc
|
||||
|
||||
- debug:
|
||||
var: etc_commit_end_run
|
||||
verbosity: 4
|
||||
tags:
|
||||
- etc-git
|
||||
- commit-etc
|
||||
- etc-git
|
||||
- commit-etc
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
args:
|
||||
chdir: /etc
|
||||
creates: /etc/.git/
|
||||
warn: no
|
||||
warn: false
|
||||
register: git_init
|
||||
tags:
|
||||
- etc-git
|
||||
|
@ -22,7 +22,7 @@
|
|||
name: user.email
|
||||
repo: /etc
|
||||
scope: local
|
||||
value: "root@{{ ansible_fqdn | default('localhost') }}"
|
||||
value: "root@{{ inventory_hostname }}.{{ general_technical_realm }}"
|
||||
tags:
|
||||
- etc-git
|
||||
|
||||
|
@ -48,11 +48,11 @@
|
|||
command: "git log"
|
||||
args:
|
||||
chdir: /etc
|
||||
warn: no
|
||||
changed_when: False
|
||||
failed_when: False
|
||||
warn: false
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
register: git_log
|
||||
check_mode: no
|
||||
check_mode: false
|
||||
tags:
|
||||
- etc-git
|
||||
|
||||
|
@ -60,7 +60,7 @@
|
|||
shell: "git add -A . && git commit -m \"Initial commit via Ansible\""
|
||||
args:
|
||||
chdir: /etc
|
||||
warn: no
|
||||
warn: false
|
||||
register: git_commit
|
||||
when: git_log.rc != 0 or (git_init is defined and git_init.changed)
|
||||
tags:
|
||||
|
@ -72,17 +72,31 @@
|
|||
line: '/usr/local/bin/git --git-dir /etc/.git gc --quiet'
|
||||
owner: root
|
||||
mode: "0644"
|
||||
create: yes
|
||||
create: true
|
||||
tags:
|
||||
- etc-git
|
||||
|
||||
- name: cron job for /etc/.git status is installed
|
||||
lineinfile:
|
||||
path: /etc/daily.local
|
||||
line: '/usr/local/bin/git --git-dir=/etc/.git --work-tree=/etc status --short'
|
||||
line:
|
||||
'/usr/local/bin/git --git-dir=/etc/.git --work-tree=/etc status --short'
|
||||
owner: root
|
||||
mode: "0644"
|
||||
create: yes
|
||||
create: true
|
||||
when: etc_git_monitor_status
|
||||
tags:
|
||||
- etc-git
|
||||
|
||||
- name: cron job for /etc/.git status is installed - next_part
|
||||
lineinfile:
|
||||
path: /etc/daily.local
|
||||
line: 'next_part "Checking /etc git status:"'
|
||||
insertbefore:
|
||||
'/usr/local/bin/git --git-dir=/etc/.git --work-tree=/etc status --short'
|
||||
owner: root
|
||||
mode: "0644"
|
||||
create: true
|
||||
when: etc_git_monitor_status
|
||||
tags:
|
||||
- etc-git
|
||||
|
@ -90,10 +104,13 @@
|
|||
- name: cron job for /etc/.git status is removed
|
||||
lineinfile:
|
||||
path: /etc/daily.local
|
||||
line: '/usr/local/bin/git --git-dir=/etc/.git --work-tree=/etc status --short'
|
||||
line: "{{ item }}"
|
||||
owner: root
|
||||
mode: "0644"
|
||||
state: absent
|
||||
with_items:
|
||||
- 'next_part "Checking /etc git status:"'
|
||||
- '/usr/local/bin/git --git-dir=/etc/.git --work-tree=/etc status --short'
|
||||
when: not etc_git_monitor_status
|
||||
tags:
|
||||
- etc-git
|
||||
|
@ -102,7 +119,13 @@
|
|||
cron:
|
||||
name: git status
|
||||
minute: 42
|
||||
job: "who > /dev/null || /usr/local/bin/git --git-dir=/etc/.git --work-tree=/etc status --short"
|
||||
job: >
|
||||
who
|
||||
> /dev/null
|
||||
|| /usr/local/bin/git
|
||||
--git-dir=/etc/.git
|
||||
--work-tree=/etc
|
||||
status --short
|
||||
when: etc_git_monitor_status
|
||||
tags:
|
||||
- etc-git
|
||||
|
@ -111,7 +134,13 @@
|
|||
cron:
|
||||
name: git status
|
||||
minute: 42
|
||||
job: "who > /dev/null || /usr/local/bin/git --git-dir=/etc/.git --work-tree=/etc status --short"
|
||||
job: >
|
||||
who
|
||||
> /dev/null
|
||||
|| /usr/local/bin/git
|
||||
--git-dir=/etc/.git
|
||||
--work-tree=/etc
|
||||
status --short
|
||||
state: absent
|
||||
when: not etc_git_monitor_status
|
||||
tags:
|
||||
|
|
13
roles/evocheck/README.md
Normal file
13
roles/evocheck/README.md
Normal file
|
@ -0,0 +1,13 @@
|
|||
# evocheck
|
||||
|
||||
Install and run evocheck ; a script for checking various settings automatically.
|
||||
|
||||
## Tasks
|
||||
|
||||
A separate `exec.yml` file can be imported manually in playbooks or roles to execute the script. Example :
|
||||
|
||||
```
|
||||
- include_role:
|
||||
name: evolix/evocheck
|
||||
tasks_from: exec.yml
|
||||
```
|
2
roles/evocheck/defaults/main.yml
Normal file
2
roles/evocheck/defaults/main.yml
Normal file
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
evocheck_bin_dir: /usr/share/scripts
|
5
roles/evocheck/files/evocheck.cf
Normal file
5
roles/evocheck/files/evocheck.cf
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Managed by Ansible
|
||||
#
|
||||
# Configuration for evocheck
|
||||
# Use this file to change configuration values defined in evocheck.sh
|
||||
# Ex : IS_TMP_1777=0
|
437
roles/evocheck/files/evocheck.sh
Normal file
437
roles/evocheck/files/evocheck.sh
Normal file
|
@ -0,0 +1,437 @@
|
|||
#!/bin/sh
|
||||
|
||||
# EvoCheck
|
||||
# Script to verify compliance of an OpenBSD server powered by Evolix
|
||||
|
||||
readonly VERSION="6.7.7"
|
||||
|
||||
# Disable LANG*
|
||||
|
||||
export LANG=C
|
||||
export LANGUAGE=C
|
||||
|
||||
|
||||
# Default return code : 0 = no error
|
||||
RC=0
|
||||
|
||||
# Verbose function
|
||||
verbose() {
|
||||
msg="${1:-$(cat /dev/stdin)}"
|
||||
[ "${VERBOSE}" -eq 1 ] && [ -n "${msg}" ] && echo "${msg}"
|
||||
}
|
||||
|
||||
# Source configuration file
|
||||
test -f /etc/evocheck.cf && . /etc/evocheck.cf
|
||||
|
||||
# Functions
|
||||
|
||||
show_help() {
|
||||
cat <<END
|
||||
NAME:
|
||||
evocheck - a system configuration verification tool
|
||||
|
||||
VERSION:
|
||||
${VERSION}
|
||||
|
||||
DESCRIPTION:
|
||||
A script that verifies Evolix conventions on OpenBSD servers
|
||||
|
||||
AUTHORS:
|
||||
Benoit Serie <bserie@evolix.fr>
|
||||
Gregory Colpart <reg@evolix.fr>
|
||||
Jeremy Dubois <jdubois@evolix.fr>
|
||||
Jeremy Lecour <jlecour@evolix.fr>
|
||||
Ludovic Poujol <lpoujol@evolix.fr>
|
||||
Romain Dessort <rdessort@evolix.fr>
|
||||
Tristan Pilat <tpilat@evolix.fr>
|
||||
Victor Laborie <vlaborie@evolix.fr>
|
||||
|
||||
USAGE: evocheck
|
||||
or evocheck --cron
|
||||
or evocheck --quiet
|
||||
or evocheck --verbose
|
||||
|
||||
OPTIONS:
|
||||
--cron disable a few checks
|
||||
-v, --verbose increase verbosity of checks
|
||||
-q, --quiet nothing is printed on stdout nor stderr
|
||||
-h, --help, --version print this message and exit
|
||||
|
||||
COPYRIGHT:
|
||||
evocheck comes with ABSOLUTELY NO WARRANTY. This is free software,
|
||||
and you are welcome to redistribute it under certain conditions.
|
||||
See the GNU General Public License v3.0 for details. 2009-2020
|
||||
END
|
||||
}
|
||||
|
||||
is_installed(){
|
||||
for pkg in "$@"; do
|
||||
pkg_info | grep -q $pkg || return 1
|
||||
done
|
||||
}
|
||||
|
||||
# logging
|
||||
failed() {
|
||||
check_name=$1
|
||||
shift
|
||||
check_comments=$*
|
||||
|
||||
RC=1
|
||||
if [ "${QUIET}" != 1 ]; then
|
||||
if [ -n "${check_comments}" ] && [ "${VERBOSE}" = 1 ]; then
|
||||
printf "%s FAILED! %s\n" "${check_name}" "${check_comments}" 2>&1
|
||||
else
|
||||
printf "%s FAILED!\n" "${check_name}" 2>&1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
# If --cron is passed, ignore some checks.
|
||||
if [ "$1" = "--cron" ]; then
|
||||
IS_KERNELUPTODATE=0
|
||||
IS_UPTIME=0
|
||||
fi
|
||||
|
||||
check_umasksudoers(){
|
||||
grep -E -qr "umask=0077" /etc/sudoers* || failed "IS_UMASKSUDOERS" "sudoers must set umask to 0077"
|
||||
}
|
||||
|
||||
check_tmpnoexec(){
|
||||
mount | grep "on /tmp" | grep -q noexec || failed "IS_TMPNOEXEC" "/tmp should be mounted with the noexec option"
|
||||
}
|
||||
|
||||
check_softdep(){
|
||||
if [ $(grep -c softdep /etc/fstab) -ne $(grep -c ffs /etc/fstab) ]; then
|
||||
failed "IS_SOFTDEP" "All partitions should have the softdep option"
|
||||
fi
|
||||
}
|
||||
|
||||
check_noatime(){
|
||||
if [ $(mount | grep -c noatime) -ne $(grep -c ffs /etc/fstab) ]; then
|
||||
failed "IS_NOATIME" "All partitions should be mounted with the noatime option"
|
||||
fi
|
||||
}
|
||||
|
||||
check_tmoutprofile(){
|
||||
grep -q TMOUT= /etc/skel/.profile /root/.profile || failed "IS_TMOUTPROFILE" "In order to fix, add 'export TMOUT=36000' to both /etc/skel/.profile and /root/.profile files"
|
||||
}
|
||||
|
||||
check_raidok(){
|
||||
egrep 'sd.*RAID' /var/run/dmesg.boot 1> /dev/null 2>&1
|
||||
RESULT=$?
|
||||
if [ $RESULT -eq 0 ]; then
|
||||
raid_device=$(egrep 'sd.*RAID' /var/run/dmesg.boot | awk '{ print $1 }' | tail -1)
|
||||
raid_status=$(bioctl $raid_device | grep softraid | awk '{ print $3 }')
|
||||
if [ $raid_status != "Online" ]; then
|
||||
failed "IS_RAIDOK" "One of the RAID disk members is faulty. Use bioctl -h $raid_device for more informations"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
check_evobackup(){
|
||||
if [ -f /etc/daily.local ]; then
|
||||
grep -qE "^sh /usr/share/scripts/zzz_evobackup" /etc/daily.local || failed "IS_EVOBACKUP" "Make sure 'sh /usr/share/scripts/zzz_evobackup' is present and activated in /etc/daily.local"
|
||||
else
|
||||
failed "IS_EVOBACKUP" "Make sure /etc/daily.local exists and 'sh /usr/share/scripts/zzz_evobackup' is present and activated in /etc/daily.local"
|
||||
fi
|
||||
}
|
||||
|
||||
check_uptodate(){
|
||||
if [ $(command -v syspatch) ]; then
|
||||
if syspatch -c | egrep "." 1> /dev/null 2>&1; then
|
||||
failed "IS_UPTODATE" "Security update available! Update with syspatch(8)!"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
check_uptime(){
|
||||
if [ $(uptime | cut -d" " -f 4) -gt 365 ]; then
|
||||
failed "IS_UPTIME" "The server is running for more than a year!"
|
||||
fi
|
||||
}
|
||||
|
||||
check_backupuptodate(){
|
||||
backup_dir="/home/backup"
|
||||
if [ -d "${backup_dir}" ]; then
|
||||
if [ -n "$(ls -A ${backup_dir})" ]; then
|
||||
for file in ${backup_dir}/*; do
|
||||
let "limit = $(date +"%s") - 172800"
|
||||
updated_at=$(stat -f "%m" "$file")
|
||||
|
||||
if [ -f "$file" ] && [ "$limit" -gt "$updated_at" ]; then
|
||||
failed "IS_BACKUPUPTODATE" "$file has not been backed up"
|
||||
test "${VERBOSE}" = 1 || break;
|
||||
fi
|
||||
done
|
||||
else
|
||||
failed "IS_BACKUPUPTODATE" "${backup_dir}/ is empty"
|
||||
fi
|
||||
else
|
||||
failed "IS_BACKUPUPTODATE" "${backup_dir}/ is missing"
|
||||
fi
|
||||
}
|
||||
|
||||
check_gitperms(){
|
||||
test -d /etc/.git && [ "$(stat -f %p /etc/.git/)" = "40700" ] || failed "IS_GITPERMS" "The directiry /etc/.git sould be in 700"
|
||||
}
|
||||
|
||||
check_advbase(){
|
||||
if ls /etc/hostname.carp* 1> /dev/null 2>&1; then
|
||||
bad_advbase=0
|
||||
for advbase in $(ifconfig carp | grep advbase | awk -F 'advbase' '{print $2}' | awk '{print $1}' | xargs); do
|
||||
if [[ "$advbase" -gt 5 ]]; then
|
||||
bad_advbase=1
|
||||
fi
|
||||
done
|
||||
if [[ "$bad_advbase" -eq 1 ]]; then
|
||||
failed "IS_ADVBASE" "At least one CARP interface has advbase greater than 5 seconds!"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
check_preempt(){
|
||||
if ls /etc/hostname.carp* 1> /dev/null 2>&1; then
|
||||
preempt=$(sysctl net.inet.carp.preempt | cut -d"=" -f2)
|
||||
if [[ "$preempt" -ne 1 ]]; then
|
||||
failed "IS_PREEMPT" "The preempt function is not activated! Please type 'sysctl net.inet.carp.preempt=1' in"
|
||||
fi
|
||||
if [ -f /etc/sysctl.conf ]; then
|
||||
grep -qE "^net.inet.carp.preempt=1" /etc/sysctl.conf || failed "IS_PREEMPT" "The preempt parameter is not permanently activated! Please add 'net.inet.carp.preempt=1' in /etc/sysctl.conf"
|
||||
else
|
||||
failed "IS_PREEMPT" "Make sure /etc/sysctl.conf exists and contains the line 'net.inet.carp.preempt=1'"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
check_rebootmail(){
|
||||
if [ -f /etc/rc.local ]; then
|
||||
grep -qE '^date \| mail -s "boot/reboot of' /etc/rc.local || failed "IS_REBOOTMAIL" "Make sure the line 'date | mail -s \"boot/reboot of \$hostname' is present in the /etc/rc.local file!"
|
||||
else
|
||||
failed "IS_REBOOTMAIL" "Make sure /etc/rc.local exist and 'date | mail -s \"boot/reboot of \$hostname' is present!"
|
||||
fi
|
||||
}
|
||||
|
||||
check_pfenabled(){
|
||||
if pfctl -si | grep Disabled 1> /dev/null 2>&1; then
|
||||
failed "IS_PFENABLED" "PF is disabled! Make sure pf=NO is absent from /etc/rc.conf.local and carefully run pfctl -e"
|
||||
fi
|
||||
}
|
||||
|
||||
check_pfcustom(){
|
||||
}
|
||||
|
||||
check_wheel(){
|
||||
if [ -f /etc/sudoers ]; then
|
||||
grep -qE "^%wheel.*$" /etc/sudoers || failed "IS_WHEEL" ""
|
||||
fi
|
||||
}
|
||||
|
||||
check_pkgmirror(){
|
||||
grep -qE "^https://cdn\.openbsd\.org/pub/OpenBSD" /etc/installurl || failed "IS_PKGMIRROR" "Check whether the right repo is present in the /etc/installurl file"
|
||||
}
|
||||
|
||||
check_history(){
|
||||
file=/root/.profile
|
||||
grep -qE "^HISTFILE=\$HOME/.histfile" $file && grep -qE "^export HISTSIZE=10000" $file || failed "IS_HISTORY" "Make sure both 'HISTFILE=$HOME/.histfile' and 'export HISTSIZE=10000' are present in /root/.profile"
|
||||
}
|
||||
|
||||
check_vim(){
|
||||
if ! is_installed vim; then
|
||||
failed "IS_VIM" "vim is not installed! Please add with pkg_add vim"
|
||||
fi
|
||||
}
|
||||
|
||||
check_ttyc0secure(){
|
||||
grep -Eqv "^ttyC0.*secure$" /etc/ttys || failed "IS_TTYC0SECURE" "First tty should be secured"
|
||||
}
|
||||
|
||||
check_customsyslog(){
|
||||
grep -q EvoBSD /etc/newsyslog.conf || failed "IS_CUSTOMSYSLOG" ""
|
||||
}
|
||||
|
||||
check_sudomaint(){
|
||||
file=/etc/sudoers
|
||||
grep -q "Cmnd_Alias MAINT = /usr/share/scripts/evomaintenance.sh" $file \
|
||||
&& grep -q "%wheel ALL=NOPASSWD: MAINT" $file \
|
||||
|| failed "IS_SUDOMAINT" ""
|
||||
}
|
||||
|
||||
check_nrpe(){
|
||||
if ! is_installed monitoring-plugins || ! is_installed nrpe; then
|
||||
failed "IS_NRPE" "nrpe and/or monitoring-plugins are not installed! Please add with pkg_add nrpe monitoring-plugins"
|
||||
fi
|
||||
}
|
||||
|
||||
check_rsync(){
|
||||
if ! is_installed rsync; then
|
||||
failed "IS_RSYNC" "rsync is not installed! Please add with pkg_add rsync"
|
||||
fi
|
||||
}
|
||||
|
||||
check_cronpath(){
|
||||
grep -q "/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/usr/share/scripts" /var/cron/tabs/root || failed "IS_CRONPATH" ""
|
||||
}
|
||||
|
||||
check_tmp1777(){
|
||||
ls -ld /tmp | grep -q drwxrwxrwt || failed "IS_TMP_1777" ""
|
||||
}
|
||||
|
||||
check_root0700(){
|
||||
ls -ld /root | grep -q drwx------ || failed "IS_ROOT_0700" ""
|
||||
}
|
||||
|
||||
check_usrsharescripts(){
|
||||
ls -ld /usr/share/scripts | grep -q drwx------ || failed "IS_USRSHARESCRIPTS" ""
|
||||
}
|
||||
|
||||
check_sshpermitrootno() {
|
||||
grep -qE ^PermitRoot /etc/ssh/sshd_config && ( grep -E -qi "PermitRoot.*no" /etc/ssh/sshd_config || failed "IS_SSHPERMITROOTNO" "" )
|
||||
}
|
||||
|
||||
check_evomaintenanceusers(){
|
||||
# Can be changed in evocheck.cf
|
||||
homeDir=${homeDir:-/home}
|
||||
sudoers="/etc/sudoers"
|
||||
for i in $( (grep "^User_Alias *ADMIN" $sudoers | cut -d= -f2 | tr -d " "; grep ^sudo /etc/group |cut -d: -f 4) | tr "," "\n" |sort -u); do
|
||||
grep -qs "^trap.*sudo.*evomaintenance.sh" ${homeDir}/${i}/.*profile
|
||||
if [ $? != 0 ]; then
|
||||
failed "IS_EVOMAINTENANCEUSERS" "$i doesn't have evomaintenance trap!"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
check_evomaintenanceconf(){
|
||||
file=/etc/evomaintenance.cf
|
||||
( test -e $file \
|
||||
&& test $(stat -f %p $file) = "100600" \
|
||||
&& grep "^export PGPASSWORD" $file |grep -qv "your-passwd" \
|
||||
&& grep "^PGDB" $file |grep -qv "your-db" \
|
||||
&& grep "^PGTABLE" $file |grep -qv "your-table" \
|
||||
&& grep "^PGHOST" $file |grep -qv "your-pg-host" \
|
||||
&& grep "^FROM" $file |grep -qv "jdoe@example.com" \
|
||||
&& grep "^FULLFROM" $file |grep -qv "John Doe <jdoe@example.com>" \
|
||||
&& grep "^URGENCYFROM" $file |grep -qv "mama.doe@example.com" \
|
||||
&& grep "^URGENCYTEL" $file |grep -qv "06.00.00.00.00" \
|
||||
&& grep "^REALM" $file |grep -qv "example.com" ) || failed "IS_EVOMAINTENANCECONF" ""
|
||||
}
|
||||
|
||||
check_sync(){
|
||||
if ifconfig carp | grep carp 1> /dev/null 2>&1; then
|
||||
sync_script=/usr/share/scripts/sync.sh
|
||||
if [ ! -f $sync_script ]; then
|
||||
failed "IS_SYNC" "The sync.sh script is absent! As a carp member, a sync.sh script should be present in /usr/share/scripts"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
check_defaultroute(){
|
||||
if [ -f /etc/mygate ]; then
|
||||
file_route=$(cat /etc/mygate)
|
||||
used_route=$(route -n show -priority 8 | grep default | awk '{print $2}')
|
||||
if [ "$file_route" != "$used_route" ]; then
|
||||
failed "IS_DEFAULTROUTE" "The default route in /etc/mygate is different from the one currently used"
|
||||
fi
|
||||
else
|
||||
failed "IS_DEFAULTROUTE" "The file /etc/mygate does not exist. Make sure you have the same default route in this file as the one currently in use."
|
||||
fi
|
||||
}
|
||||
|
||||
check_ntp(){
|
||||
if grep -q "server ntp.evolix.net" /etc/ntpd.conf; then
|
||||
if [ $(wc -l /etc/ntpd.conf | awk '{print $1}') -ne 1 ]; then
|
||||
failed "IS_NTP" "The /etc/ntpd.conf file should only contains \"server ntp.evolix.net\"."
|
||||
fi
|
||||
else
|
||||
failed "IS_NTP" "The configuration in /etc/ntpd.conf is not compliant. It should contains \"server ntp.evolix.net\"."
|
||||
fi
|
||||
}
|
||||
|
||||
check_openvpncronlog(){
|
||||
if /etc/rc.d/openvpn check > /dev/null 2>&1; then
|
||||
grep -q 'cp /var/log/openvpn.log /var/log/openvpn.log.$(date +\\%F) && echo "$(date +\\%F. .\\%R) - logfile turned over via cron" > /var/log/openvpn.log && gzip /var/log/openvpn.log.$(date +\\%F) && find /var/log/ -type f -name "openvpn.log.\*" -mtime .365 -exec rm {} \\+' /var/cron/tabs/root || failed "IS_OPENVPNCRONLOG" "OpenVPN is enabled but there is no log rotation in the root crontab, or the cron is not up to date (OpenVPN log rotation in newsyslog is not used because a restart is needed)."
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
main() {
|
||||
# Default return code : 0 = no error
|
||||
RC=0
|
||||
|
||||
test "${IS_UMASKSUDOERS:=1}" = 1 && check_umasksudoers
|
||||
test "${IS_TMPNOEXEC:=1}" = 1 && check_tmpnoexec
|
||||
test "${IS_SOFTDEP:=1}" = 1 && check_softdep
|
||||
test "${IS_NOATIME:=1}" = 1 && check_noatime
|
||||
test "${IS_TMOUTPROFILE:=1}" = 1 && check_tmoutprofile
|
||||
test "${IS_RAIDOK:=1}" = 1 && check_raidok
|
||||
test "${IS_EVOBACKUP:=1}" = 1 && check_evobackup
|
||||
test "${IS_UPTODATE:=1}" = 1 && check_uptodate
|
||||
test "${IS_UPTIME:=1}" = 1 && check_uptime
|
||||
test "${IS_BACKUPUPTODATE:=1}" = 1 && check_backupuptodate
|
||||
test "${IS_GITPERMS:=1}" = 1 && check_gitperms
|
||||
test "${IS_ADVBASE:=1}" = 1 && check_advbase
|
||||
test "${IS_PREEMPT:=1}" = 1 && check_preempt
|
||||
test "${IS_REBOOTMAIL:=1}" = 1 && check_rebootmail
|
||||
test "${IS_PFENABLED:=1}" = 1 && check_pfenabled
|
||||
test "${IS_PFCUSTOM:=1}" = 1 && check_pfcustom
|
||||
test "${IS_WHEEL:=1}" = 1 && check_wheel
|
||||
test "${IS_PKGMIRROR:=1}" = 1 && check_pkgmirror
|
||||
test "${IS_HISTORY:=1}" = 1 && check_history
|
||||
test "${IS_VIM:=1}" = 1 && check_vim
|
||||
test "${IS_TTYC0SECURE:=1}" = 1 && check_ttyc0secure
|
||||
test "${IS_CUSTOMSYSLOG:=1}" = 1 && check_customsyslog
|
||||
test "${IS_SUDOMAINT:=1}" = 1 && check_sudomaint
|
||||
test "${IS_NRPE:=1}" = 1 && check_nrpe
|
||||
test "${IS_RSYNC:=1}" = 1 && check_rsync
|
||||
test "${IS_CRONPATH:=1}" = 1 && check_cronpath
|
||||
test "${IS_TMP_1777:=1}" = 1 && check_tmp1777
|
||||
test "${IS_ROOT_0700:=1}" = 1 && check_root0700
|
||||
test "${IS_USRSHARESCRIPTS:=1}" = 1 && check_usrsharescripts
|
||||
test "${IS_SSHPERMITROOTNO:=1}" = 1 && check_sshpermitrootno
|
||||
test "${IS_EVOMAINTENANCEUSERS:=1}" = 1 && check_evomaintenanceusers
|
||||
test "${IS_EVOMAINTENANCECONF:=1}" = 1 && check_evomaintenanceconf
|
||||
test "${IS_SYNC:=1}" = 1 && check_sync
|
||||
test "${IS_DEFAULTROUTE:=1}" = 1 && check_defaultroute
|
||||
test "${IS_NTP:=1}" = 1 && check_ntp
|
||||
test "${IS_OPENVPNCRONLOG:=1}" = 1 && check_openvpncronlog
|
||||
|
||||
exit ${RC}
|
||||
}
|
||||
# Parse options
|
||||
# based on https://gist.github.com/deshion/10d3cb5f88a21671e17a
|
||||
while :; do
|
||||
case $1 in
|
||||
-h|-\?|--help|--version)
|
||||
show_help
|
||||
exit 0
|
||||
;;
|
||||
--cron)
|
||||
IS_KERNELUPTODATE=0
|
||||
IS_UPTIME=0
|
||||
;;
|
||||
-v|--verbose)
|
||||
VERBOSE=1
|
||||
;;
|
||||
-q|--quiet)
|
||||
QUIET=1
|
||||
VERBOSE=0
|
||||
;;
|
||||
--)
|
||||
# End of all options.
|
||||
shift
|
||||
break
|
||||
;;
|
||||
-?*|[[:alnum:]]*)
|
||||
# ignore unknown options
|
||||
printf 'WARN: Unknown option (ignored): %s\n' "$1" >&2
|
||||
;;
|
||||
*)
|
||||
# Default case: If no more options then break out of the loop.
|
||||
break
|
||||
;;
|
||||
esac
|
||||
|
||||
shift
|
||||
done
|
||||
|
||||
main ${ARGS}
|
15
roles/evocheck/tasks/exec.yml
Normal file
15
roles/evocheck/tasks/exec.yml
Normal file
|
@ -0,0 +1,15 @@
|
|||
---
|
||||
- name: run evocheck
|
||||
command: "{{ evocheck_bin_dir }}/evocheck.sh"
|
||||
register: evocheck_run
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
check_mode: false
|
||||
tags:
|
||||
- evocheck-exec
|
||||
|
||||
- debug:
|
||||
var: evocheck_run.stdout_lines
|
||||
when: evocheck_run.stdout != ""
|
||||
tags:
|
||||
- evocheck-exec
|
49
roles/evocheck/tasks/install.yml
Normal file
49
roles/evocheck/tasks/install.yml
Normal file
|
@ -0,0 +1,49 @@
|
|||
---
|
||||
- name: Scripts dir is present
|
||||
file:
|
||||
path: "{{ evocheck_bin_dir }}"
|
||||
state: directory
|
||||
owner: root
|
||||
group: wheel
|
||||
mode: "0700"
|
||||
tags:
|
||||
- evocheck
|
||||
|
||||
- name: Copy evocheck.sh
|
||||
copy:
|
||||
src: evocheck.sh
|
||||
dest: "{{ evocheck_bin_dir }}/evocheck.sh"
|
||||
mode: "0700"
|
||||
owner: root
|
||||
force: true
|
||||
tags:
|
||||
- evocheck
|
||||
|
||||
- name: Copy evocheck.cf
|
||||
copy:
|
||||
src: evocheck.cf
|
||||
dest: /etc/evocheck.cf
|
||||
force: false
|
||||
tags:
|
||||
- evocheck
|
||||
|
||||
- name: Add evocheck cron
|
||||
lineinfile:
|
||||
path: /etc/daily.local
|
||||
line: 'sh /usr/share/scripts/evocheck.sh --verbose --cron'
|
||||
owner: root
|
||||
mode: "0644"
|
||||
create: true
|
||||
tags:
|
||||
- evocheck
|
||||
|
||||
- name: Add evocheck cron next_part
|
||||
lineinfile:
|
||||
path: /etc/daily.local
|
||||
line: 'next_part "Evocheck output:"'
|
||||
insertbefore: 'sh /usr/share/scripts/evocheck.sh --verbose --cron'
|
||||
owner: root
|
||||
mode: "0644"
|
||||
create: true
|
||||
tags:
|
||||
- evocheck
|
2
roles/evocheck/tasks/main.yml
Normal file
2
roles/evocheck/tasks/main.yml
Normal file
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
- include: install.yml
|
|
@ -4,7 +4,7 @@
|
|||
name: net.inet.ip.forwarding
|
||||
value: 1
|
||||
state: present
|
||||
reload: yes
|
||||
reload: true
|
||||
tags:
|
||||
- net
|
||||
|
||||
|
@ -13,6 +13,6 @@
|
|||
name: net.inet6.ip6.forwarding
|
||||
value: 1
|
||||
state: present
|
||||
reload: yes
|
||||
reload: true
|
||||
tags:
|
||||
- net
|
||||
|
|
|
@ -8,6 +8,6 @@ Everything is in the `tasks/main.yml` file.
|
|||
|
||||
## Available variables
|
||||
|
||||
* `nagios_nrpe_allowed_hosts` : list of IP/hosts authorized (default: none).
|
||||
* `nagios_nrpe_allowed_hosts` : list of IP/hosts authorized (default: none).
|
||||
|
||||
The full list of variables (with default values) can be found in `defaults/main.yml`.
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
evolix_trusted_ips: []
|
||||
additional_trusted_ips: []
|
||||
# Let's merge evolix_trusted_ips with additional_trusted_ips
|
||||
nagios_nrpe_allowed_hosts: "{{ evolix_trusted_ips | union(additional_trusted_ips) | unique }}"
|
||||
nagios_nrpe_allowed_hosts:
|
||||
"{{ evolix_trusted_ips | union(additional_trusted_ips) | unique }}"
|
||||
nagios_nrpe_ldap_dc: "dc=DOMAIN,dc=EXT"
|
||||
nagios_nrpe_ldap_passwd: LDAP_PASSWD
|
||||
nagios_nrpe_pgsql_passwd: PGSQL_PASSWD
|
||||
|
|
87
roles/nagios-nrpe/files/plugins_bsd/check_connections_state.sh
Executable file
87
roles/nagios-nrpe/files/plugins_bsd/check_connections_state.sh
Executable file
|
@ -0,0 +1,87 @@
|
|||
#!/bin/sh
|
||||
|
||||
STATE=0
|
||||
MAIN_CONNECTION_PINGABLE_IP="31.170.8.95"
|
||||
MAIN_CONNECTION_GATEWAY="IP"
|
||||
MAIN_CONNECTION_IP="IP"
|
||||
SECOND_CONNECTION_PINGABLE_IP="31.170.8.243"
|
||||
INFO_MAIN_CONNECTION="IP - Description"
|
||||
INFO_SECOND_CONNECTION="IP - Description"
|
||||
CURRENT_GATEWAY=$(/usr/bin/netstat -nr | /usr/bin/grep "default" | /usr/bin/awk '{print $2}')
|
||||
|
||||
IS_GATEWAY_IN_FILE=1 # Check whether /etc/mygate has the IP of main connection
|
||||
IS_VPN_USING_MAIN_CONNECTION=1 # Check whether ipsecctl use the main connection
|
||||
IS_PF_USING_MAIN_CONNECTION=1 # Check whether PacketFilter has route-to using the main connection
|
||||
IS_MISCELLANEOUS=1 # Check miscellaneous things
|
||||
CHECK_CARP=0 # No check if host is backup
|
||||
|
||||
# No check if host is backup
|
||||
if [ "${CHECK_CARP}" = 1 ]; then
|
||||
CARP_STATUS=$(/sbin/ifconfig carp0 | /usr/bin/grep "status" | /usr/bin/awk '{print $2}')
|
||||
if [ "$CARP_STATUS" = "backup" ]; then
|
||||
echo "No check, I'm a backup"
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
# If main connection is UP but not used => critical and continue
|
||||
# If main connection is DOWN (used or not) => warning and exit
|
||||
/sbin/ping -c1 -w1 ${MAIN_CONNECTION_PINGABLE_IP} >/dev/null 2>&1
|
||||
if [ $? = 0 ]; then
|
||||
if [ "${CURRENT_GATEWAY}" != "${MAIN_CONNECTION_GATEWAY}" ]; then
|
||||
echo "Main connection is UP but not used as gateway !"
|
||||
STATE=2
|
||||
fi
|
||||
else
|
||||
echo "Main connection (${INFO_MAIN_CONNECTION}) is down"
|
||||
STATE=1
|
||||
IS_GATEWAY_IN_FILE=0
|
||||
IS_VPN_USING_MAIN_CONNECTION=0
|
||||
IS_PF_USING_MAIN_CONNECTION=0
|
||||
IS_MISCELLANEOUS=0
|
||||
fi
|
||||
|
||||
# If second connection is DOWN => critical and continue
|
||||
/sbin/ping -c1 -w1 ${SECOND_CONNECTION_PINGABLE_IP} >/dev/null 2>&1
|
||||
if [ $? != 0 ]; then
|
||||
echo "Second connection (${INFO_SECOND_CONNECTION}) is down"
|
||||
STATE=2
|
||||
fi
|
||||
|
||||
# Check whether /etc/mygate has the IP of main connection
|
||||
if [ "${IS_GATEWAY_IN_FILE}" = 1 ]; then
|
||||
/usr/bin/grep -q "${MAIN_CONNECTION_GATEWAY}" /etc/mygate
|
||||
if [ $? != 0 ]; then
|
||||
echo "Main connection is not set in /etc/mygate"
|
||||
STATE=2
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check whether ipsecctl use the main connection
|
||||
if [ "${IS_VPN_USING_MAIN_CONNECTION}" = 1 ]; then
|
||||
/sbin/ipsecctl -sa | /usr/bin/grep -q "${MAIN_CONNECTION_IP}"
|
||||
if [ $? != 0 ]; then
|
||||
echo "VPN is not using the main connection !"
|
||||
STATE=2
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check whether PacketFilter has route-to using the main connection
|
||||
if [ "${IS_PF_USING_MAIN_CONNECTION}" = 1 ]; then
|
||||
/sbin/pfctl -sr | /usr/bin/grep "route-to" | /usr/bin/grep -q "${MAIN_CONNECTION_GATEWAY}"
|
||||
if [ $? != 0 ]; then
|
||||
echo "PF is not using the main connection !"
|
||||
STATE=2
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check miscellaneous things
|
||||
if [ "${IS_MISCELLANEOUS}" = 1 ]; then
|
||||
echo
|
||||
fi
|
||||
|
||||
if [ "${STATE}" = 0 ]; then
|
||||
echo "OK - Main connection is UP and used, second connection is UP"
|
||||
fi
|
||||
|
||||
exit ${STATE}
|
401
roles/nagios-nrpe/files/plugins_bsd/check_openbgpd
Executable file
401
roles/nagios-nrpe/files/plugins_bsd/check_openbgpd
Executable file
|
@ -0,0 +1,401 @@
|
|||
#!/usr/bin/perl -T
|
||||
# $AFresh1: check_openbgpd,v 1.10 2015/03/26 03:44:15 andrew Exp $
|
||||
########################################################################
|
||||
# check_openbgpd *** A nagios check for OpenBSD bgpd
|
||||
#
|
||||
# 2009.11.12 #*#*# andrew fresh <andrew@afresh1.com>
|
||||
########################################################################
|
||||
#
|
||||
# MODIFIED VERSION FOR THE NEEDS OF EVOLIX
|
||||
# By Jérémy Dubois <jdubois@evolix.fr>
|
||||
#
|
||||
# Line 51 :
|
||||
# added « open STDERR, '>&STDOUT'; »
|
||||
#
|
||||
# Lines 123 to 126 :
|
||||
# added « or exit 2; »
|
||||
# commented « or die $! » and the 2 lines below
|
||||
#
|
||||
########################################################################
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use 5.010;
|
||||
use if $] >= 5.016, experimental => 'switch';
|
||||
|
||||
local %ENV = ();
|
||||
|
||||
my $NAGIOS_OUTPUT = 1;
|
||||
|
||||
my $LICENSE = <<'EOL';
|
||||
Copyright (c) 2009-2015 Andrew Fresh <andrew@afresh1.com>
|
||||
Permission to use, copy, modify, and distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
EOL
|
||||
|
||||
my $PROGNAME = 'check_openbgpd';
|
||||
my $BGPCTL = '/usr/sbin/bgpctl';
|
||||
|
||||
use POSIX;
|
||||
use Config;
|
||||
my $PREFIX;
|
||||
open STDERR, '>&STDOUT';
|
||||
|
||||
BEGIN {
|
||||
## no critic 'warnings'
|
||||
no warnings 'uninitialized';
|
||||
$PREFIX = "/usr/local" || '/usr/local'; # Magic for OpenBSD ports tree
|
||||
}
|
||||
use lib $PREFIX . '/libexec/nagios';
|
||||
use utils qw($TIMEOUT %ERRORS &support);
|
||||
|
||||
$SIG{'ALRM'} = sub {
|
||||
print("ERROR: $PROGNAME timeout\n");
|
||||
exit $ERRORS{'UNKNOWN'};
|
||||
};
|
||||
alarm($TIMEOUT);
|
||||
|
||||
my %CHECKS = getopt(@ARGV);
|
||||
if ( !%CHECKS ) {
|
||||
print_help();
|
||||
exit $ERRORS{'OK'};
|
||||
}
|
||||
|
||||
my @STATUS = read_status( $CHECKS{_SOCKET} );
|
||||
my %STATES = check_status( \@STATUS, \%CHECKS );
|
||||
|
||||
my $have_results = 0;
|
||||
my $state = 'OK';
|
||||
foreach
|
||||
my $error ( reverse sort { $ERRORS{$a} <=> $ERRORS{$b} } keys %ERRORS )
|
||||
{
|
||||
if ( exists $STATES{$error} ) {
|
||||
$have_results++;
|
||||
$state = $error if $ERRORS{$state} < $ERRORS{$error};
|
||||
|
||||
if ($NAGIOS_OUTPUT) {
|
||||
print $error . ' (' . scalar( @{ $STATES{$error} } ) . ')';
|
||||
if ( $error ne 'OK' ) {
|
||||
print '<br>';
|
||||
print map {" - $_<br>"} @{ $STATES{$error} };
|
||||
}
|
||||
}
|
||||
else {
|
||||
print $error . ' (' . scalar( @{ $STATES{$error} } ) . "):\n";
|
||||
foreach ( @{ $STATES{$error} } ) {
|
||||
print " $_\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( $have_results == 0 ) {
|
||||
print "No results found\n";
|
||||
}
|
||||
exit $ERRORS{$state};
|
||||
|
||||
sub read_status {
|
||||
my ($socket) = @_;
|
||||
my @S;
|
||||
|
||||
my @cmd = ($BGPCTL);
|
||||
if ($socket) {
|
||||
push @cmd, '-s', $socket;
|
||||
}
|
||||
push @cmd, 'show', 'summary';
|
||||
|
||||
#open my $fh, '<', 'output' # XXX
|
||||
open my $fh, '-|', @cmd or die "Couldn't open bgpctl: $!\n";
|
||||
while (<$fh>) {
|
||||
chomp;
|
||||
push @S, parse_line($_);
|
||||
}
|
||||
## no critic 'die'
|
||||
close $fh
|
||||
or exit 2;
|
||||
# or die $!
|
||||
# ? "Error closing sysctl pipe: $!\n"
|
||||
# : "Exit status $? from sysctl\n";
|
||||
|
||||
return grep { exists $_->{neighbor} && $_->{as} ne 'AS' } @S;
|
||||
}
|
||||
|
||||
sub parse_line {
|
||||
my ($c) = @_;
|
||||
my ( $neighbor, $as, $rcvd, $sent, $outq, $updown, $state, )
|
||||
= $c
|
||||
=~ /^(.*?)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s*$/xms;
|
||||
return {
|
||||
neighbor => $neighbor,
|
||||
as => $as,
|
||||
rcvd => $rcvd,
|
||||
sent => $sent,
|
||||
outq => $outq,
|
||||
updown => $updown,
|
||||
state => $state,
|
||||
line => $c,
|
||||
};
|
||||
}
|
||||
|
||||
sub parse_check {
|
||||
my $check = shift;
|
||||
|
||||
return { match => [] } unless $check;
|
||||
my @values = split /,\s*/xms, $check;
|
||||
|
||||
my %c = ( match => [] );
|
||||
foreach my $v (@values) {
|
||||
if ( $v =~ /:/xms ) {
|
||||
( $c{low}, $c{high} ) = split /:/xms, $v;
|
||||
}
|
||||
else {
|
||||
push @{ $c{match} }, $v;
|
||||
}
|
||||
}
|
||||
|
||||
foreach my $d ( 'low', 'high' ) {
|
||||
if ( defined $c{$d} ) {
|
||||
$c{$d} =~ s/[^-\d\.\%]//gxms;
|
||||
if ( !length $c{$d} ) {
|
||||
delete $c{$d};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return \%c;
|
||||
}
|
||||
|
||||
sub check_status {
|
||||
my ( $S, $C ) = @_;
|
||||
|
||||
my %states;
|
||||
my %neighbors = map { $_ => $C->{$_} } qw( _SOCKET _UNKNOWN );
|
||||
STATE: foreach my $s ( @{$S} ) {
|
||||
my $n = $s->{neighbor};
|
||||
$neighbors{$n} = $s;
|
||||
|
||||
my $result;
|
||||
|
||||
if ( my $c = $C->{$n} || $C->{_UNKNOWN} ) {
|
||||
CODE: foreach my $code ( 'CRITICAL', 'WARNING' ) {
|
||||
next CODE if ( ref $c->{$code} ne 'HASH' );
|
||||
my $data = $s->{state};
|
||||
|
||||
my $result = check_item( $data, $c->{$code} );
|
||||
|
||||
if ($result) {
|
||||
push @{ $states{$code} }, "[$n] $result";
|
||||
next STATE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
push @{ $states{CRITICAL} }, '[' . $n . '] Unknown Neighbor';
|
||||
next STATE;
|
||||
}
|
||||
|
||||
push @{ $states{OK} }, $n;
|
||||
}
|
||||
|
||||
foreach my $n ( keys %{$C} ) {
|
||||
if ( !exists $neighbors{$n} ) {
|
||||
push @{ $states{CRITICAL} }, '[' . $n . '] Missing Neighbor';
|
||||
}
|
||||
}
|
||||
|
||||
return %states;
|
||||
}
|
||||
|
||||
sub check_item {
|
||||
my ( $d, $c ) = @_;
|
||||
|
||||
my $result;
|
||||
|
||||
if ( $c->{match} && @{ $c->{match} } ) {
|
||||
foreach my $m ( @{ $c->{match} } ) {
|
||||
return if $m eq $d;
|
||||
}
|
||||
$result = 'State (' . $d . ') is outside of acceptable values';
|
||||
}
|
||||
|
||||
if ( $c->{low} || $c->{high} ) {
|
||||
$result = undef;
|
||||
my ( $num, $max ) = split m{/}xms, $d;
|
||||
$num =~ s/[^-\d\.]//gxms;
|
||||
|
||||
if ( !length $num ) {
|
||||
return 'State (' . $d . ') is not numeric';
|
||||
}
|
||||
|
||||
DIRECTION: foreach my $dir (qw( low high )) {
|
||||
if ( !$c->{$dir} ) { next DIRECTION; }
|
||||
|
||||
my $check = $c->{$dir};
|
||||
my $cnum = $num;
|
||||
|
||||
if ( $check =~ s/\%$//xms ) {
|
||||
if ( !defined $max ) {
|
||||
return 'max-prefix not specified and % check requested';
|
||||
}
|
||||
|
||||
# convert to percent
|
||||
$cnum = 100 * $cnum / $max;
|
||||
}
|
||||
|
||||
my @nums = ( $cnum, $check );
|
||||
my $abovebelow = 'below';
|
||||
my $symbol = '<';
|
||||
if ( $dir eq 'high' ) {
|
||||
@nums = ( $check, $cnum );
|
||||
$abovebelow = 'above';
|
||||
$symbol = '>';
|
||||
}
|
||||
|
||||
if ( $nums[0] < $nums[1] ) {
|
||||
return join q{ }, 'is', $abovebelow,
|
||||
'threshold (' . $d,
|
||||
$symbol, $c->{$dir} . ')';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
sub getopt {
|
||||
my (@argv) = @_;
|
||||
|
||||
my %checks;
|
||||
while (@argv) {
|
||||
state( $w, $c );
|
||||
|
||||
my $opt = shift @argv;
|
||||
for ($opt) {
|
||||
when ( '-V' || '--version' ) {
|
||||
print_revision( $PROGNAME, '$Revision: 1.10 $ ' );
|
||||
exit $ERRORS{'OK'}
|
||||
}
|
||||
when (/^-?-h(?:elp)?/xms) { print_help(); exit $ERRORS{'OK'} }
|
||||
when (/^-?-s(?:ocket)?/xms) { $checks{_SOCKET} = shift @argv }
|
||||
when (/^-?-w(?:arning)?/xms) { $w = parse_check( shift @argv ) }
|
||||
when (/^-?-c(?:ritical)?/xms) { $c = parse_check( shift @argv ) }
|
||||
when (/^-?-u(?:nknown)?/xms) {
|
||||
$checks{_UNKNOWN} = {
|
||||
WARNING => $w,
|
||||
CRITICAL => $c,
|
||||
};
|
||||
}
|
||||
when (/^-?-n(?:eighbor)?/xms) {
|
||||
while ( @argv && $argv[0] !~ /^-/xms ) {
|
||||
$checks{ shift @argv } = {
|
||||
WARNING => $w,
|
||||
CRITICAL => $c,
|
||||
};
|
||||
}
|
||||
}
|
||||
default { print_help(); exit $ERRORS{'UNKNOWN'} }
|
||||
}
|
||||
}
|
||||
return %checks;
|
||||
}
|
||||
|
||||
sub print_help {
|
||||
print <<"EOL";
|
||||
$PROGNAME - checks status of OpenBGPd peers
|
||||
$PROGNAME [ -s SOCKET ][ -w ENTRY ][ -c ENTRY ]( -u | -n NEIGHBOR )
|
||||
|
||||
Usage:
|
||||
-s, --socket SOCKET
|
||||
Path to bgpd socket to use. See -r in bgpd(8).
|
||||
-w, --warning RANGE or single ENTRY
|
||||
Exit with WARNING status if outside of RANGE or if != ENTRY
|
||||
May be entered multiple times.
|
||||
-c, --critical RANGE or single ENTRY
|
||||
Exit with CRITICAL status if outside of RANGE or if != ENTRY
|
||||
May be entered multiple times.
|
||||
-n, --neighbor NEIGHBOR
|
||||
The name of the Neighbor, can be a space separated list of neighbors.
|
||||
May be entered multiple times.
|
||||
-u, --unknown
|
||||
As if you specified -n for all unknown neighbors
|
||||
|
||||
ENTRY is a comma separated list of items to match against. Each item can be
|
||||
a RANGE or it will just be matched against the status.
|
||||
|
||||
RANGE is specified as two optional numbers separated with a colon (:). The
|
||||
check is that the value is between the two numbers. If either number is left
|
||||
off, that check is ignored.
|
||||
|
||||
If either number in a RANGE is specified as a percent, check is that
|
||||
max-prefix is specified and that the number is within the specified percent.
|
||||
|
||||
NEIGHBOR is the name that shows when running "bgpctl show summary"
|
||||
|
||||
Examples:
|
||||
(where many of the numbers would probably have to be multiplied by 1000)
|
||||
|
||||
Any time a NEIGHBOR is specified on the command line but does NOT show up in
|
||||
the output causes a CRITICAL result.
|
||||
|
||||
Any time a NEIGHBOR that is NOT specified on the command line shows up in the
|
||||
output causes a CRITICAL result. If -u is specified, it treats NEIGHBOR as if
|
||||
it were specified at that position.
|
||||
|
||||
|
||||
$PROGNAME -c Idle -n P1 -c 1:1 -n P2 -w 200:300 -c Active,10: -n P3
|
||||
|
||||
CRITICAL
|
||||
If P1 is any value but Idle.
|
||||
If P2 is any value but 1.
|
||||
If P3 is below 10 or any non-numeric value other than "Active".
|
||||
|
||||
WARNING
|
||||
If P3 is above 10 and below 200 or above 300.
|
||||
|
||||
|
||||
$PROGNAME -u -w 50%:70% -c 10%:90% -n P2 P3
|
||||
|
||||
No checks of unknown neighbors.
|
||||
|
||||
CRITICAL
|
||||
If P2 or P3 do not have max-prefix set or if they do but learned prefixes
|
||||
are below 10% or above 90% of max-prefix or any non-numeric value.
|
||||
|
||||
WARNING
|
||||
If P2 or P3 have learned prefixes below 50% or above 70% of max-prefix.
|
||||
|
||||
|
||||
$PROGNAME -w 50%:70% -c 10%:90% -u
|
||||
|
||||
CRITICAL
|
||||
If any neighbor does not have max-prefix set or if they do but learned
|
||||
prefixes are below 10% or above 90% of max-prefix or any non-numeric value.
|
||||
|
||||
WARNING
|
||||
If any neighbor have learned prefixes below 50% or above 70% of max-prefix.
|
||||
|
||||
EOL
|
||||
|
||||
print_revision( $PROGNAME, '$Revision: 1.10 $' );
|
||||
|
||||
print $LICENSE;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
sub print_revision {
|
||||
my ( $prog, $rev ) = @_;
|
||||
$rev =~ s/^\D+([\d\.]+)\D+$/v$1/xms;
|
||||
|
||||
say $prog, q{ }, $rev;
|
||||
|
||||
return;
|
||||
}
|
|
@ -1,9 +1,12 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# Wrapper of check_openvpn.pl, to use when the server is CARP backup and OpenVPN should not run
|
||||
|
||||
if netstat -an|grep '.1194' >/dev/null; then
|
||||
echo "VPN OK"
|
||||
return 0
|
||||
carp=$(/sbin/ifconfig carp0 | /usr/bin/grep 'status' |cut -d' ' -f2)
|
||||
|
||||
if [ $carp = 'backup' ]; then
|
||||
echo "No check, I'm a backup"
|
||||
return 0
|
||||
else
|
||||
echo "PROCESS NOT LISTENING"
|
||||
return 2
|
||||
/usr/local/libexec/nagios/plugins/check_openvpn.pl -H 127.0.0.1 -p 1195 -P PASSWORD
|
||||
fi
|
||||
|
|
215
roles/nagios-nrpe/files/plugins_bsd/check_openvpn.pl
Executable file
215
roles/nagios-nrpe/files/plugins_bsd/check_openvpn.pl
Executable file
|
@ -0,0 +1,215 @@
|
|||
#!/usr/bin/perl -w
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# Copyright (c) 2007 Jaime Gascon Romero <jgascon@gmail.com>
|
||||
#
|
||||
# License Information:
|
||||
# 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 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# $Id: check_openvpn.pl,v 1.1 2014/09/29 08:39:24 rdessort Exp $
|
||||
# $Revision: 1.1 $
|
||||
# Home Site: http://emergeworld.blogspot.com/
|
||||
# #####################################################################
|
||||
|
||||
use diagnostics;
|
||||
use strict;
|
||||
use Net::Telnet ();
|
||||
use Getopt::Long qw(:config no_ignore_case);
|
||||
use vars qw($PROGNAME $VERSION);
|
||||
use lib "/usr/local/libexec/nagios/";
|
||||
use utils qw(%ERRORS);
|
||||
|
||||
$PROGNAME = "check_openvpn";
|
||||
$VERSION = '$Revision: 1.1 $';
|
||||
|
||||
$ENV{'PATH'}='';
|
||||
$ENV{'BASH_ENV'}='';
|
||||
$ENV{'ENV'}='';
|
||||
|
||||
my ($opt_h, $opt_H, $opt_p, $opt_P, $opt_t, $opt_i, $opt_n, $opt_c, $opt_w, $opt_C, $opt_r);
|
||||
|
||||
sub print_help ();
|
||||
sub print_usage ();
|
||||
|
||||
GetOptions
|
||||
("h" => \$opt_h, "help" => \$opt_h,
|
||||
"H=s" => \$opt_H, "host=s" => \$opt_H,
|
||||
"p=i" => \$opt_p, "port=i" => \$opt_p,
|
||||
"P=s" => \$opt_P, "password=s" => \$opt_P,
|
||||
"t=i" => \$opt_t, "timeout=i" => \$opt_t,
|
||||
"i" => \$opt_i, "ip" => \$opt_i,
|
||||
"n" => \$opt_n, "numeric" => \$opt_n,
|
||||
"c" => \$opt_c, "critical" => \$opt_c,
|
||||
"w" => \$opt_w, "warning" => \$opt_w,
|
||||
"C=s" => \$opt_C, "common_name=s" => \$opt_C,
|
||||
"r=s" => \$opt_r, "remote_ip=s" => \$opt_r,
|
||||
) or exit $ERRORS{'UNKNOWN'};
|
||||
|
||||
# default values
|
||||
unless ( defined $opt_t ) {
|
||||
$opt_t = 10;
|
||||
}
|
||||
|
||||
if ($opt_h) {print_help(); exit $ERRORS{'OK'};}
|
||||
|
||||
if ( ! defined($opt_H) || ! defined($opt_p) ) {
|
||||
print_usage();
|
||||
exit $ERRORS{'UNKNOWN'}
|
||||
}
|
||||
|
||||
my @lines;
|
||||
my @clients;
|
||||
my @clients_ip;
|
||||
my $t;
|
||||
|
||||
eval {
|
||||
$t = new Net::Telnet (Timeout => $opt_t,
|
||||
Port => $opt_p,
|
||||
Prompt => '/END$/'
|
||||
);
|
||||
$t->open($opt_H);
|
||||
if ( defined $opt_P ) {
|
||||
$t->waitfor('/ENTER PASSWORD:$/');
|
||||
$t->print($opt_P);
|
||||
}
|
||||
$t->waitfor('/^$/');
|
||||
@lines = $t->cmd("status 2");
|
||||
$t->close;
|
||||
};
|
||||
|
||||
if ($@) {
|
||||
print "OpenVPN Critical: Can't connect to server\n";
|
||||
exit $ERRORS{'CRITICAL'};
|
||||
}
|
||||
|
||||
|
||||
if (defined $opt_i || defined $opt_r) {
|
||||
foreach (@lines) {
|
||||
if ($_ =~ /CLIENT_LIST,.*,(\d+\.\d+\.\d+\.\d+):\d+,/) {
|
||||
push @clients_ip, $1;
|
||||
}
|
||||
}
|
||||
if (defined $opt_i) {
|
||||
print "OpenVPN OK: "."@clients_ip ";
|
||||
exit $ERRORS{'OK'};
|
||||
} elsif (defined $opt_r) {
|
||||
if ( ! grep /\b$opt_r\b/, @clients_ip) {
|
||||
if (defined $opt_c) {
|
||||
print "OpenVPN CRITICAL: $opt_r don't found";
|
||||
exit $ERRORS{'CRITICAL'};
|
||||
} else {
|
||||
print "OpenVPN WARNING: $opt_r don't found";
|
||||
exit $ERRORS{'WARNING'};
|
||||
}
|
||||
}
|
||||
print "OpenVPN OK: "."@clients_ip ";
|
||||
exit $ERRORS{'OK'};
|
||||
}
|
||||
}
|
||||
|
||||
foreach (@lines) {
|
||||
if ($_ =~ /CLIENT_LIST,(.*),\d+\.\d+\.\d+\.\d+:\d+,/) {
|
||||
push @clients, $1;
|
||||
}
|
||||
}
|
||||
|
||||
if (defined $opt_C) {
|
||||
if ( ! grep /\b$opt_C\b/, @clients) {
|
||||
if (defined $opt_c) {
|
||||
print "OpenVPN CRITICAL: $opt_C don't found";
|
||||
exit $ERRORS{'CRITICAL'};
|
||||
} else {
|
||||
print "OpenVPN WARNING: $opt_C don't found";
|
||||
exit $ERRORS{'WARNING'};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (defined $opt_n) {
|
||||
print "OpenVPN OK: ".@clients." connected clients.";
|
||||
exit $ERRORS{'OK'};
|
||||
}
|
||||
|
||||
print "OpenVPN OK: "."@clients ";
|
||||
exit $ERRORS{'OK'};
|
||||
|
||||
#######################################################################
|
||||
###### Subroutines ####################################################
|
||||
|
||||
sub print_usage() {
|
||||
print "Usage: $PROGNAME -H | --host <IP or hostname> -p | --port <port number> [-P | --password] <password> [-t | --timeout] <timeout in seconds>
|
||||
[-i | --ip] [-n | --numeric] [-C | --common_name] <common_name> [-r | --remote_ip] <remote_ip> [-c | --critical] [-w | --warning]\n\n";
|
||||
print " $PROGNAME [-h | --help]\n";
|
||||
}
|
||||
|
||||
sub print_help() {
|
||||
print "$PROGNAME $VERSION\n\n";
|
||||
print "Copyright (c) 2007 Jaime Gascon Romero
|
||||
|
||||
Nagios plugin to check the clients connected to a openvpn server.
|
||||
|
||||
";
|
||||
print_usage();
|
||||
print "
|
||||
-H | --host
|
||||
IP address or hostname of the openvpn server.
|
||||
|
||||
-p | --port
|
||||
Management port interface of the openvpn server.
|
||||
|
||||
-P | --password
|
||||
Password for the management interface of the openvpn server.
|
||||
|
||||
-t | --timeout
|
||||
Timeout for the connection attempt. Optional, default 10 seconds.
|
||||
|
||||
|
||||
Optional parameters
|
||||
===================
|
||||
|
||||
-i | --ip
|
||||
Prints the IP address of the remote client instead of the common name.
|
||||
|
||||
-n | --numeric
|
||||
Prints the number of clients connected to the openvpn server.
|
||||
|
||||
|
||||
Matching Parameters
|
||||
===================
|
||||
|
||||
-C | --common_name
|
||||
The common name, as it is specified in the client certificate, who is wanted to check.
|
||||
|
||||
-r | --remote_ip
|
||||
The client remote ip address who is wanted to check.
|
||||
|
||||
-c | --critical
|
||||
Exits with CRITICAL status if the client specified by the common name or the remote ip address is not connected.
|
||||
|
||||
-w | --warning
|
||||
Exits with WARNING status if the client specified by the common name or the remote ip address is not connected.
|
||||
|
||||
|
||||
Other Parameters
|
||||
================
|
||||
|
||||
-h | --help
|
||||
Show this help.
|
||||
";
|
||||
|
||||
}
|
||||
|
||||
# vim:sts=2:sw=2:ts=2:et
|
|
@ -3,10 +3,16 @@
|
|||
. /usr/local/libexec/nagios/utils.sh
|
||||
|
||||
# check if ospfd is running
|
||||
if [[ "$(ospfctl show 2>&1)" = *"/var/run/ospfd.sock:"* ]]; then
|
||||
echo "CRITICAL - OSPFD not running"
|
||||
if ! ls /var/run/ospfd* > /dev/null 2>&1; then
|
||||
echo "CRITICAL - OSPFD not running, no socket found"
|
||||
exit "$STATE_CRITICAL"
|
||||
else
|
||||
echo "OK - OSPFD is running"
|
||||
exit "$STATE_OK"
|
||||
if ospfctl show 2>&1 | grep -q "Uptime"; then
|
||||
uptime=$(ospfctl show | grep Uptime | awk '{print $2}')
|
||||
echo "OK - OSPFD has been running for $uptime"
|
||||
exit "$STATE_OK"
|
||||
else
|
||||
echo "CRITICAL - OSPFD not running"
|
||||
exit "$STATE_CRITICAL"
|
||||
fi
|
||||
fi
|
||||
|
|
40
roles/nagios-nrpe/files/plugins_bsd/check_packetfilter.sh
Executable file
40
roles/nagios-nrpe/files/plugins_bsd/check_packetfilter.sh
Executable file
|
@ -0,0 +1,40 @@
|
|||
#!/bin/sh
|
||||
|
||||
. /usr/local/libexec/nagios/utils.sh
|
||||
|
||||
is_pf_disabled() {
|
||||
if [ -f /etc/rc.conf.local ]; then
|
||||
grep -q "pf=NO" /etc/rc.conf.local
|
||||
else
|
||||
# If /etc/rc.conf.local does not exist, pf cannot be disabled
|
||||
# If 0 then pf is disabled, so if /etc/rc.conf.local does not exist we have to return 1 => pf is not disabled
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
is_pf_started() {
|
||||
pfctl -si | grep -q "Status: Enabled for"
|
||||
}
|
||||
|
||||
main() {
|
||||
if ! is_pf_disabled; then
|
||||
if is_pf_started; then
|
||||
echo "OK: PacketFilter is enabled and started."
|
||||
exit "${STATE_OK}"
|
||||
else
|
||||
echo "CRITICAL: PacketFilter is enabled but not started."
|
||||
exit "${STATE_CRITICAL}"
|
||||
fi
|
||||
else
|
||||
if is_pf_started; then
|
||||
echo "WARNING: PacketFilter is started but not enabled."
|
||||
exit "${STATE_WARNING}"
|
||||
else
|
||||
echo "CRITICAL: PacketFilter is disabled and not started."
|
||||
exit "${STATE_CRITICAL}"
|
||||
fi
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
main
|
|
@ -3,8 +3,8 @@
|
|||
# Script writen by Evolix
|
||||
|
||||
_MAX_STATES_LIMIT=$(/sbin/pfctl -sm | /usr/bin/grep states | awk '{print $4}')
|
||||
_WARNING_STATES_LIMIT=$((_MAX_STATES_LIMIT*10/100))
|
||||
_CRTICAL_STATES_LIMIT=$((_MAX_STATES_LIMIT*15/100))
|
||||
_WARNING_STATES_LIMIT=$((_MAX_STATES_LIMIT*50/100))
|
||||
_CRTICAL_STATES_LIMIT=$((_MAX_STATES_LIMIT*65/100))
|
||||
|
||||
. /usr/local/libexec/nagios/utils.sh
|
||||
|
|
@ -1,17 +1,15 @@
|
|||
---
|
||||
- name: Install nrpe
|
||||
openbsd_pkg:
|
||||
name: "{{ item }}"
|
||||
name:
|
||||
- nrpe--
|
||||
state: present
|
||||
with_items:
|
||||
- nrpe--
|
||||
|
||||
- name: Install monitoring-plugins
|
||||
openbsd_pkg:
|
||||
name: "{{ item }}"
|
||||
name:
|
||||
- monitoring-plugins
|
||||
state: present
|
||||
with_items:
|
||||
- monitoring-plugins
|
||||
|
||||
- name: Create nrpe.d dir
|
||||
file:
|
||||
|
@ -32,29 +30,48 @@
|
|||
dest: /etc/nrpe.d/evolix.cfg
|
||||
notify: restart nrpe
|
||||
|
||||
- name: Nagios plugins are installed
|
||||
copy:
|
||||
src: plugins_bsd/
|
||||
dest: /usr/local/libexec/nagios/plugins/
|
||||
- name: Create nrpe plugins dir
|
||||
file:
|
||||
path: /usr/local/libexec/nagios/plugins/
|
||||
state: directory
|
||||
owner: root
|
||||
group: wheel
|
||||
mode: "0755"
|
||||
|
||||
- name: Nagios plugins are installed
|
||||
copy:
|
||||
src: plugins_bsd/{{ item.name }}
|
||||
dest: /usr/local/libexec/nagios/plugins/{{ item.name }}
|
||||
owner: root
|
||||
group: wheel
|
||||
mode: "0755"
|
||||
force: "{{ item.force }}"
|
||||
with_items:
|
||||
- {name: 'check_carp_if', force: true}
|
||||
- {name: 'check_connections_state.sh', force: false}
|
||||
- {name: 'check_ipsecctl.sh', force: false}
|
||||
- {name: 'check_openbgpd', force: true}
|
||||
- {name: 'check_openvpn', force: false}
|
||||
- {name: 'check_openvpn.pl', force: true}
|
||||
- {name: 'check_ospfd_simple', force: true}
|
||||
- {name: 'check_packetfilter.sh', force: true}
|
||||
- {name: 'check_pf_states', force: false}
|
||||
notify: restart nrpe
|
||||
|
||||
- name: Nagios plugins are installed - template
|
||||
template:
|
||||
src: plugins_bsd/{{ item }}.j2
|
||||
dest: /usr/local/libexec/nagios/plugins/{{ item }}
|
||||
src: plugins_bsd/{{ item.name }}.j2
|
||||
dest: /usr/local/libexec/nagios/plugins/{{ item.name }}
|
||||
owner: root
|
||||
group: wheel
|
||||
mode: "0755"
|
||||
force: "{{ item.force }}"
|
||||
with_items:
|
||||
- 'check_pf_states'
|
||||
- 'check_free_mem.sh'
|
||||
- {name: 'check_free_mem.sh', force: true}
|
||||
notify: restart nrpe
|
||||
|
||||
- name: Starting and enabling nrpe
|
||||
service:
|
||||
name: nrpe
|
||||
enabled: yes
|
||||
enabled: true
|
||||
state: started
|
||||
|
|
|
@ -2,37 +2,51 @@
|
|||
# Custom NRPE configuration file.
|
||||
# Part of the EvoBSD distribution.
|
||||
#
|
||||
# This is an Ansible managed file !
|
||||
# For local modifications use the /etc/nrpe.d/zzz_evolix.cfg file instead
|
||||
|
||||
# Allowed IPs
|
||||
allowed_hosts={{ nagios_nrpe_allowed_hosts | join(',') }}
|
||||
|
||||
# System checks
|
||||
command[check_users]=/usr/local/libexec/nagios/check_users -w 5 -c 10
|
||||
command[check_load]=/usr/local/libexec/nagios/check_load -w 15,10,5 -c 30,25,20
|
||||
command[check_disk1]=/usr/local/libexec/nagios/check_disk -x /lib/init/rw -x /dev -x /dev/shm -w 10% -c 3% -W 10% -K 3% -C -w 5% -c 2% -W 5% -K 2% -p /home
|
||||
command[check_zombie_procs]=/usr/local/libexec/nagios/check_procs -w 5 -c 10 -s Z
|
||||
command[check_total_procs]=/usr/local/libexec/nagios/check_procs -w 150 -c 200
|
||||
command[check_imap]=/usr/local/libexec/nagios/check_imap -H localhost
|
||||
command[check_swap]=/usr/local/libexec/nagios/check_swap --no-swap=ok -a -w 30% -c 20%
|
||||
|
||||
# Generic services checks
|
||||
command[check_smtp]=/usr/local/libexec/nagios/check_smtp -H localhost -f {{ general_alert_email }}
|
||||
command[check_dns]=/usr/local/libexec/nagios/check_dns -H evolix.net
|
||||
command[check_swap]=/usr/local/libexec/nagios/check_swap --no-swap=ok -a -w 30% -c 20%
|
||||
command[check_ntp]=/usr/local/libexec/nagios/check_ntp -H ntp.evolix.net
|
||||
command[check_http]=/usr/local/libexec/nagios/check_http -H localhost -p 80
|
||||
command[check_onduleur]=/usr/local/libexec/nagios/check_ups -H localhost -u onduleur
|
||||
# Pour check_mailq, ajouter dans sudo :
|
||||
# _nrpe ALL=NOPASSWD: /usr/local/libexec/nagios/check_mailq
|
||||
command[check_mailq]=sudo /usr/local/libexec/nagios/check_mailq -w 10 -c 20
|
||||
command[check_bind]=/usr/local/libexec/nagios/check_dig -l evolix.net -H localhost
|
||||
command[check_ntp]=/usr/local/libexec/nagios/check_ntp -H ntp-check.evolix.net
|
||||
command[check_ssh]=/usr/local/libexec/nagios/check_ssh -p 22 localhost
|
||||
command[check_proxy]=/usr/local/libexec/nagios/check_tcp -p PORT
|
||||
#command[check_vpn]=/usr/local/libexec/nagios/check_ping -H IPDISTANTE -p 1 -w 5000,100% -c 5000,100%
|
||||
command[check_vpn]=sudo /usr/local/libexec/nagios/plugins/check_ipsecctl.sh IPDISTANTE IPLOCALE "VPN MARSEILLE-ROME"
|
||||
command[check_openvpn]=/usr/local/libexec/nagios/plugins/check_openvpn
|
||||
command[check_pf_states]=doas /usr/local/libexec/nagios/plugins/check_pf_states
|
||||
command[check_carp1]=/usr/local/libexec/nagios/plugins/check_carp_if carp0 master
|
||||
command[check_mem]=/usr/local/libexec/nagios/plugins/check_free_mem.sh -w 20 -c 10
|
||||
command[check_dhcpclient]=/usr/local/libexec/nagios/check_dhcp -i INTERFACE
|
||||
command[check_smb]=/usr/local/libexec/nagios/check_tcp -H IPLOCALE -p 445
|
||||
#command[check_ospfd]=doas /usr/local/libexec/nagios/plugins/check_ospfd
|
||||
#command[check_ospf6d]=doas /usr/local/libexec/nagios/plugins/check_ospf6d
|
||||
command[check_ospfd_simple]=sudo /usr/local/libexec/nagios/plugins/check_ospfd_simple
|
||||
command[check_mailq]=doas /usr/local/libexec/nagios/check_mailq -w 10 -c 20
|
||||
|
||||
# Specific services checks
|
||||
command[check_imap]=/usr/local/libexec/nagios/check_imap -H localhost
|
||||
command[check_http]=/usr/local/libexec/nagios/check_http -H localhost -p 80
|
||||
command[check_bind]=/usr/local/libexec/nagios/check_dig -l evolix.net -H localhost
|
||||
command[check_unbound]=/usr/local/libexec/nagios/check_dig -l evolix.net -H localhost
|
||||
#command[check_proxy]=/usr/local/libexec/nagios/check_tcp -p PORT
|
||||
#command[check_smb]=/usr/local/libexec/nagios/check_tcp -H IPLOCALE -p 445
|
||||
command[check_mysql]=/usr/local/libexec/nagios/check_mysql -H 127.0.0.1 -f /etc/nrpe.d/.my.cnf
|
||||
#command[check_vpn]=/usr/local/libexec/nagios/check_ping -H IPDISTANTE -p 1 -w 5000,100% -c 5000,100%
|
||||
#command[check_dhcpd]=doas /usr/local/libexec/nagios/check_dhcp -i INTERFACE -s IP -u
|
||||
|
||||
# Local checks (not packaged)
|
||||
#command[check_openvpn]=/usr/local/libexec/nagios/plugins/check_openvpn.pl -H 127.0.0.1 -p 1195 -P PASSWORD
|
||||
#command[check_openvpn]=/usr/local/libexec/nagios/plugins/check_openvpn # Wrapper of check_openvpn.pl, to use when the server is CARP backup and OpenVPN should not run
|
||||
#command[check_carp1]=/usr/local/libexec/nagios/plugins/check_carp_if carp0 master
|
||||
command[check_mem]=/usr/local/libexec/nagios/plugins/check_free_mem.sh -w 20 -c 10
|
||||
#command[check_vpn]=doas /usr/local/libexec/nagios/plugins/check_ipsecctl.sh IPDISTANTE IPLOCALE "VPN MARSEILLE-ROME"
|
||||
command[check_pf_states]=doas /usr/local/libexec/nagios/plugins/check_pf_states
|
||||
command[check_ospfd]=doas /usr/local/libexec/nagios/plugins/check_ospfd
|
||||
command[check_ospf6d]=doas /usr/local/libexec/nagios/plugins/check_ospf6d
|
||||
command[check_ospfd_simple]=doas /usr/local/libexec/nagios/plugins/check_ospfd_simple
|
||||
command[check_bgpd]=doas /usr/local/libexec/nagios/plugins/check_openbgpd -u
|
||||
command[check_connections_state]=doas /usr/local/libexec/nagios/plugins/check_connections_state.sh
|
||||
command[check_packetfilter]=doas /usr/local/libexec/nagios/plugins/check_packetfilter.sh
|
||||
|
||||
# This is an Ansible managed file !
|
||||
# For local modifications use the /etc/nrpe.d/zzz_evolix.cfg file instead
|
||||
|
|
|
@ -64,7 +64,7 @@ __EOT
|
|||
# Total memory size (in MB)
|
||||
tot_mem=$(( `/sbin/sysctl -n hw.physmem` / BYTES_IN_MB))
|
||||
# Free memory size (in MB)
|
||||
{% if ansible_distribution_version | version_compare("6.2",'<') %}
|
||||
{% if ansible_distribution_version is version_compare("6.2",'<') %}
|
||||
free_mem=$(( `/usr/bin/vmstat | /usr/bin/tail -1 | /usr/bin/awk '{ print $5 }'` / KB_IN_MB ))
|
||||
{% else %}
|
||||
free_mem=$(/usr/bin/vmstat | /usr/bin/tail -1 | /usr/bin/awk '{ print $4 }' | tr -d 'M')
|
||||
|
|
13
roles/openvpn/README.md
Normal file
13
roles/openvpn/README.md
Normal file
|
@ -0,0 +1,13 @@
|
|||
# OpenVPN
|
||||
|
||||
Installation and custom configuration of OpenVPN server.
|
||||
|
||||
## Tasks
|
||||
|
||||
Everything is in the `tasks/main.yml` file.
|
||||
|
||||
## Available variables
|
||||
|
||||
The full list of variables (with default values) can be found in `defaults/main.yml`.
|
||||
|
||||
NOTE: Make sure you have already cloned shellpki in ~/GIT/
|
3
roles/openvpn/defaults/main.yml
Normal file
3
roles/openvpn/defaults/main.yml
Normal file
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
openvpn_lan: "192.168.42.0"
|
||||
openvpn_netmask: "255.255.255.0"
|
215
roles/openvpn/files/check_openvpn.pl
Executable file
215
roles/openvpn/files/check_openvpn.pl
Executable file
|
@ -0,0 +1,215 @@
|
|||
#!/usr/bin/perl -w
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# Copyright (c) 2007 Jaime Gascon Romero <jgascon@gmail.com>
|
||||
#
|
||||
# License Information:
|
||||
# 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 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# $Id: check_openvpn.pl,v 1.1 2014/09/29 08:39:24 rdessort Exp $
|
||||
# $Revision: 1.1 $
|
||||
# Home Site: http://emergeworld.blogspot.com/
|
||||
# #####################################################################
|
||||
|
||||
use diagnostics;
|
||||
use strict;
|
||||
use Net::Telnet ();
|
||||
use Getopt::Long qw(:config no_ignore_case);
|
||||
use vars qw($PROGNAME $VERSION);
|
||||
use lib "/usr/local/libexec/nagios/";
|
||||
use utils qw(%ERRORS);
|
||||
|
||||
$PROGNAME = "check_openvpn";
|
||||
$VERSION = '$Revision: 1.1 $';
|
||||
|
||||
$ENV{'PATH'}='';
|
||||
$ENV{'BASH_ENV'}='';
|
||||
$ENV{'ENV'}='';
|
||||
|
||||
my ($opt_h, $opt_H, $opt_p, $opt_P, $opt_t, $opt_i, $opt_n, $opt_c, $opt_w, $opt_C, $opt_r);
|
||||
|
||||
sub print_help ();
|
||||
sub print_usage ();
|
||||
|
||||
GetOptions
|
||||
("h" => \$opt_h, "help" => \$opt_h,
|
||||
"H=s" => \$opt_H, "host=s" => \$opt_H,
|
||||
"p=i" => \$opt_p, "port=i" => \$opt_p,
|
||||
"P=s" => \$opt_P, "password=s" => \$opt_P,
|
||||
"t=i" => \$opt_t, "timeout=i" => \$opt_t,
|
||||
"i" => \$opt_i, "ip" => \$opt_i,
|
||||
"n" => \$opt_n, "numeric" => \$opt_n,
|
||||
"c" => \$opt_c, "critical" => \$opt_c,
|
||||
"w" => \$opt_w, "warning" => \$opt_w,
|
||||
"C=s" => \$opt_C, "common_name=s" => \$opt_C,
|
||||
"r=s" => \$opt_r, "remote_ip=s" => \$opt_r,
|
||||
) or exit $ERRORS{'UNKNOWN'};
|
||||
|
||||
# default values
|
||||
unless ( defined $opt_t ) {
|
||||
$opt_t = 10;
|
||||
}
|
||||
|
||||
if ($opt_h) {print_help(); exit $ERRORS{'OK'};}
|
||||
|
||||
if ( ! defined($opt_H) || ! defined($opt_p) ) {
|
||||
print_usage();
|
||||
exit $ERRORS{'UNKNOWN'}
|
||||
}
|
||||
|
||||
my @lines;
|
||||
my @clients;
|
||||
my @clients_ip;
|
||||
my $t;
|
||||
|
||||
eval {
|
||||
$t = new Net::Telnet (Timeout => $opt_t,
|
||||
Port => $opt_p,
|
||||
Prompt => '/END$/'
|
||||
);
|
||||
$t->open($opt_H);
|
||||
if ( defined $opt_P ) {
|
||||
$t->waitfor('/ENTER PASSWORD:$/');
|
||||
$t->print($opt_P);
|
||||
}
|
||||
$t->waitfor('/^$/');
|
||||
@lines = $t->cmd("status 2");
|
||||
$t->close;
|
||||
};
|
||||
|
||||
if ($@) {
|
||||
print "OpenVPN Critical: Can't connect to server\n";
|
||||
exit $ERRORS{'CRITICAL'};
|
||||
}
|
||||
|
||||
|
||||
if (defined $opt_i || defined $opt_r) {
|
||||
foreach (@lines) {
|
||||
if ($_ =~ /CLIENT_LIST,.*,(\d+\.\d+\.\d+\.\d+):\d+,/) {
|
||||
push @clients_ip, $1;
|
||||
}
|
||||
}
|
||||
if (defined $opt_i) {
|
||||
print "OpenVPN OK: "."@clients_ip ";
|
||||
exit $ERRORS{'OK'};
|
||||
} elsif (defined $opt_r) {
|
||||
if ( ! grep /\b$opt_r\b/, @clients_ip) {
|
||||
if (defined $opt_c) {
|
||||
print "OpenVPN CRITICAL: $opt_r don't found";
|
||||
exit $ERRORS{'CRITICAL'};
|
||||
} else {
|
||||
print "OpenVPN WARNING: $opt_r don't found";
|
||||
exit $ERRORS{'WARNING'};
|
||||
}
|
||||
}
|
||||
print "OpenVPN OK: "."@clients_ip ";
|
||||
exit $ERRORS{'OK'};
|
||||
}
|
||||
}
|
||||
|
||||
foreach (@lines) {
|
||||
if ($_ =~ /CLIENT_LIST,(.*),\d+\.\d+\.\d+\.\d+:\d+,/) {
|
||||
push @clients, $1;
|
||||
}
|
||||
}
|
||||
|
||||
if (defined $opt_C) {
|
||||
if ( ! grep /\b$opt_C\b/, @clients) {
|
||||
if (defined $opt_c) {
|
||||
print "OpenVPN CRITICAL: $opt_C don't found";
|
||||
exit $ERRORS{'CRITICAL'};
|
||||
} else {
|
||||
print "OpenVPN WARNING: $opt_C don't found";
|
||||
exit $ERRORS{'WARNING'};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (defined $opt_n) {
|
||||
print "OpenVPN OK: ".@clients." connected clients.";
|
||||
exit $ERRORS{'OK'};
|
||||
}
|
||||
|
||||
print "OpenVPN OK: "."@clients ";
|
||||
exit $ERRORS{'OK'};
|
||||
|
||||
#######################################################################
|
||||
###### Subroutines ####################################################
|
||||
|
||||
sub print_usage() {
|
||||
print "Usage: $PROGNAME -H | --host <IP or hostname> -p | --port <port number> [-P | --password] <password> [-t | --timeout] <timeout in seconds>
|
||||
[-i | --ip] [-n | --numeric] [-C | --common_name] <common_name> [-r | --remote_ip] <remote_ip> [-c | --critical] [-w | --warning]\n\n";
|
||||
print " $PROGNAME [-h | --help]\n";
|
||||
}
|
||||
|
||||
sub print_help() {
|
||||
print "$PROGNAME $VERSION\n\n";
|
||||
print "Copyright (c) 2007 Jaime Gascon Romero
|
||||
|
||||
Nagios plugin to check the clients connected to a openvpn server.
|
||||
|
||||
";
|
||||
print_usage();
|
||||
print "
|
||||
-H | --host
|
||||
IP address or hostname of the openvpn server.
|
||||
|
||||
-p | --port
|
||||
Management port interface of the openvpn server.
|
||||
|
||||
-P | --password
|
||||
Password for the management interface of the openvpn server.
|
||||
|
||||
-t | --timeout
|
||||
Timeout for the connection attempt. Optional, default 10 seconds.
|
||||
|
||||
|
||||
Optional parameters
|
||||
===================
|
||||
|
||||
-i | --ip
|
||||
Prints the IP address of the remote client instead of the common name.
|
||||
|
||||
-n | --numeric
|
||||
Prints the number of clients connected to the openvpn server.
|
||||
|
||||
|
||||
Matching Parameters
|
||||
===================
|
||||
|
||||
-C | --common_name
|
||||
The common name, as it is specified in the client certificate, who is wanted to check.
|
||||
|
||||
-r | --remote_ip
|
||||
The client remote ip address who is wanted to check.
|
||||
|
||||
-c | --critical
|
||||
Exits with CRITICAL status if the client specified by the common name or the remote ip address is not connected.
|
||||
|
||||
-w | --warning
|
||||
Exits with WARNING status if the client specified by the common name or the remote ip address is not connected.
|
||||
|
||||
|
||||
Other Parameters
|
||||
================
|
||||
|
||||
-h | --help
|
||||
Show this help.
|
||||
";
|
||||
|
||||
}
|
||||
|
||||
# vim:sts=2:sw=2:ts=2:et
|
1
roles/openvpn/files/shellpki
Symbolic link
1
roles/openvpn/files/shellpki
Symbolic link
|
@ -0,0 +1 @@
|
|||
/home/tpilat/GIT/shellpki/
|
1
roles/openvpn/files/sudo_shellpki
Normal file
1
roles/openvpn/files/sudo_shellpki
Normal file
|
@ -0,0 +1 @@
|
|||
%shellpki ALL = (root) /usr/local/sbin/shellpki
|
5
roles/openvpn/handlers/main.yml
Normal file
5
roles/openvpn/handlers/main.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
- name: restart openvpn
|
||||
service:
|
||||
name: openvpn
|
||||
state: restarted
|
121
roles/openvpn/tasks/main.yml
Normal file
121
roles/openvpn/tasks/main.yml
Normal file
|
@ -0,0 +1,121 @@
|
|||
---
|
||||
- name: Install OpenVPN package
|
||||
openbsd_pkg:
|
||||
name: "openvpn--"
|
||||
tags:
|
||||
- openvpn
|
||||
|
||||
- name: Create /etc/openvpn directory
|
||||
file:
|
||||
path: /etc/openvpn
|
||||
state: directory
|
||||
owner: "root"
|
||||
group: "wheel"
|
||||
mode: "0755"
|
||||
tags:
|
||||
- openvpn
|
||||
|
||||
- name: Deploy OpenVPN configuration
|
||||
template:
|
||||
src: "server.conf.j2"
|
||||
dest: "/etc/openvpn/server.conf"
|
||||
mode: "0600"
|
||||
notify: restart openvpn
|
||||
tags:
|
||||
- openvpn
|
||||
|
||||
- name: Enabling OpenVPN
|
||||
service:
|
||||
name: openvpn
|
||||
enabled: true
|
||||
tags:
|
||||
- openvpn
|
||||
|
||||
- name: Set OpenVPN flag
|
||||
shell: 'rcctl set openvpn flags "--config /etc/openvpn/server.conf"'
|
||||
tags:
|
||||
- openvpn
|
||||
|
||||
- name: Create shellpki user
|
||||
user:
|
||||
name: "_shellpki"
|
||||
system: true
|
||||
state: present
|
||||
home: "/etc/shellpki/"
|
||||
shell: "/sbin/nologin"
|
||||
tags:
|
||||
- openvpn
|
||||
|
||||
- name: Copy some shellpki files
|
||||
copy:
|
||||
src: "{{ item.src }}"
|
||||
dest: "{{ item.dest }}"
|
||||
owner: root
|
||||
group: wheel
|
||||
mode: "{{ item.mode }}"
|
||||
force: true
|
||||
with_items:
|
||||
- src: 'files/shellpki/openssl.cnf'
|
||||
dest: '/etc/shellpki/openssl.cnf'
|
||||
mode: '0640'
|
||||
- src: 'files/shellpki/shellpki'
|
||||
dest: '/usr/local/sbin/shellpki'
|
||||
mode: '0755'
|
||||
tags:
|
||||
- openvpn
|
||||
|
||||
- name: Deploy DH PARAMETERS
|
||||
template:
|
||||
src: "dh2048.pem.j2"
|
||||
dest: "/etc/shellpki/dh2048.pem"
|
||||
mode: "0600"
|
||||
tags:
|
||||
- openvpn
|
||||
|
||||
- name: Create /etc/sudoers.d directory
|
||||
file:
|
||||
path: /etc/sudoers.d
|
||||
state: directory
|
||||
owner: "root"
|
||||
group: "wheel"
|
||||
mode: "0755"
|
||||
tags:
|
||||
- openvpn
|
||||
|
||||
- name: Include /etc/sudoers.d in sudoers configuration file
|
||||
lineinfile:
|
||||
path: /etc/sudoers
|
||||
line: '#includedir /etc/sudoers.d'
|
||||
tags:
|
||||
- openvpn
|
||||
|
||||
- name: Verify shellpki sudoers file presence
|
||||
copy:
|
||||
src: "sudo_shellpki"
|
||||
dest: "/etc/sudoers.d/shellpki"
|
||||
force: true
|
||||
mode: "0440"
|
||||
validate: '/usr/local/sbin/visudo -cf %s'
|
||||
tags:
|
||||
- openvpn
|
||||
|
||||
- name: Copy check_openvpn
|
||||
copy:
|
||||
src: "{{ item.src }}"
|
||||
dest: "{{ item.dest }}"
|
||||
owner: root
|
||||
group: wheel
|
||||
mode: "{{ item.mode }}"
|
||||
force: true
|
||||
with_items:
|
||||
- src: 'files/check_openvpn.pl'
|
||||
dest: '/usr/local/libexec/nagios/plugins/check_openvpn.pl'
|
||||
mode: '0755'
|
||||
tags:
|
||||
- openvpn
|
||||
|
||||
- name: Install needed package for check_openvpn
|
||||
openbsd_pkg:
|
||||
name: "p5-Net-Telnet"
|
||||
tags:
|
||||
- openvpn
|
8
roles/openvpn/templates/dh2048.pem.j2
Normal file
8
roles/openvpn/templates/dh2048.pem.j2
Normal file
|
@ -0,0 +1,8 @@
|
|||
-----BEGIN DH PARAMETERS-----
|
||||
MIIBCAKCAQEAuimweC/f5W/AIIFhLX256Bi5IU+AkN9sKZ9sxGx0xc3J8NwIBnEP
|
||||
R/2RgclJqJ8OodY70zeDHNLDyc01crGvihuupiWVlvQxS4osdhfdM+GoV9pcmCVr
|
||||
TRTybsUPkkm4rQ/SC7I2MxiYnXwDrrYnpMvBDaRZjoHlgTKjOGoYSd+DIDZSFKkv
|
||||
ASkXQkIC9FpvjnxfW5gtzzm6NheqgYUI2Y2QiqM6BmGVZiPcqyUpbWvRCcZLoPa2
|
||||
Z+FV9LxE4J7CX0ilTJXXhs3RaMlG8qZha3l0hEL4SAZp5xn74Ej/9hA5cWqnKEOQ
|
||||
aLfwADI4rPe9uTu9Qnw87DgM2tQeETBlmwIBAg==
|
||||
-----END DH PARAMETERS-----
|
26
roles/openvpn/templates/server.conf.j2
Normal file
26
roles/openvpn/templates/server.conf.j2
Normal file
|
@ -0,0 +1,26 @@
|
|||
user nobody
|
||||
group nogroup
|
||||
|
||||
local {{ ansible_default_ipv4.address }}
|
||||
port 1194
|
||||
proto udp
|
||||
dev tun
|
||||
mode server
|
||||
keepalive 10 120
|
||||
|
||||
cipher AES-128-CBC # AES
|
||||
#comp-lzo
|
||||
# compress (à partir d'OpenVPN 2.4)
|
||||
|
||||
persist-key
|
||||
persist-tun
|
||||
|
||||
status /var/log/openvpn-status.log
|
||||
log-append /var/log/openvpn.log
|
||||
|
||||
ca /etc/shellpki/cacert.pem
|
||||
cert /etc/shellpki/certs/{{ ansible_fqdn }}.crt
|
||||
key /etc/shellpki/private/{{ ansible_fqdn }}.key
|
||||
dh /etc/shellpki/dh2048.pem
|
||||
|
||||
server {{ openvpn_lan }} {{ openvpn_netmask }}
|
14
roles/ospf/README.md
Normal file
14
roles/ospf/README.md
Normal file
|
@ -0,0 +1,14 @@
|
|||
# OSPF
|
||||
|
||||
Deployment of OSPF check scripts with their cron.
|
||||
|
||||
## Tasks
|
||||
|
||||
Everything is in the `tasks/main.yml` file.
|
||||
|
||||
## Available variables
|
||||
|
||||
The full list of variables (with default values) can be found in `defaults/main.yml`.
|
||||
|
||||
* `ospf_mailto` : email address the output of the scripts will be sent to when a change is detected
|
||||
* `ospf_sed_command` : facultative sed command to modify the ospfctl output and add a name to IPs
|
3
roles/ospf/defaults/main.yml
Normal file
3
roles/ospf/defaults/main.yml
Normal file
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
ospf_mailto: "foobar@example.com"
|
||||
ospf_sed_command: ""
|
22
roles/ospf/tasks/main.yml
Normal file
22
roles/ospf/tasks/main.yml
Normal file
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
- name: Deploy ospf check scripts
|
||||
template:
|
||||
src: "{{ item }}.j2"
|
||||
dest: /usr/share/scripts/{{ item }}
|
||||
with_items:
|
||||
- "ospfd-check-peers.sh"
|
||||
- "ospf6d-check-peers.sh"
|
||||
when: group_names | select('search','ospf') | list | count > 0
|
||||
tags:
|
||||
- ospf
|
||||
|
||||
- name: Cron job for ospf check scripts is installed
|
||||
cron:
|
||||
name: "{{ item }} check"
|
||||
job: "/bin/sh /usr/share/scripts/{{ item }}-check-peers.sh"
|
||||
with_items:
|
||||
- ospfd
|
||||
- ospf6d
|
||||
when: group_names | select('search','ospf') | list | count > 0
|
||||
tags:
|
||||
- ospf
|
126
roles/ospf/templates/ospf6d-check-peers.sh.j2
Executable file
126
roles/ospf/templates/ospf6d-check-peers.sh.j2
Executable file
|
@ -0,0 +1,126 @@
|
|||
#!/bin/ksh
|
||||
|
||||
# Script writen by Daniel Jakots for BGP, adapted by Jeremy Dubois for OSPF
|
||||
|
||||
# First we go through the list of neighbor and we write all the peer and
|
||||
# their status in "${_TMPDIR}"/ospf6-status.
|
||||
|
||||
# Then we monitor if this file has changed between now and the previous run.
|
||||
|
||||
# If it did, we send a mail with the states of the different sessions.
|
||||
|
||||
set -u
|
||||
|
||||
PATH=$HOME/bin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:.
|
||||
|
||||
_MAILTO="{{ ospf_mailto }}"
|
||||
_TMPDIR=/tmp/check-ospf6
|
||||
_PIDFILE="${_TMPDIR}"/ospf6d-check-peers.pid
|
||||
|
||||
|
||||
if [ -e /etc/realname ]; then
|
||||
_REALNAME=$(cat /etc/realname)
|
||||
_HOSTNAME=$(hostname -s)
|
||||
else
|
||||
_HOSTNAME=$(hostname)
|
||||
fi
|
||||
|
||||
mkdir -p "${_TMPDIR}"
|
||||
|
||||
# Don't try to run if it's already running
|
||||
if [ -e "${_PIDFILE}" ]; then
|
||||
echo "$(date)" >> "${_TMPDIR}"/log
|
||||
exit 1
|
||||
else
|
||||
echo $$ >> "${_PIDFILE}"
|
||||
fi
|
||||
|
||||
# Create an history
|
||||
if [[ -f "${_TMPDIR}"/ospf6-status ]] ; then
|
||||
mv "${_TMPDIR}"/ospf6-status "${_TMPDIR}"/ospf6-status.old
|
||||
else
|
||||
touch "${_TMPDIR}"/ospf6-status
|
||||
touch "${_TMPDIR}"/ospf6-status.old
|
||||
fi
|
||||
|
||||
# List peers and loops on them to list them and their OSPF6 state
|
||||
ospf6ctl show neighbor | grep -v "^$" | grep -v "Uptime" | awk {'print $1'} > "${_TMPDIR}"/peers-list
|
||||
|
||||
while read _PEER
|
||||
do
|
||||
_STATUS=$(/usr/sbin/ospf6ctl show neighbor | grep "${_PEER} " | awk {'print $3'})
|
||||
echo -n "${_PEER}" >> "${_TMPDIR}"/ospf6-status
|
||||
echo -n " " >> "${_TMPDIR}"/ospf6-status
|
||||
if ([[ "${_STATUS}" = "FULL/BCKUP" ]] || [[ "${_STATUS}" = "FULL/DR" ]] || [[ "${_STATUS}" = "2-WAY/OTHER" ]] || [[ "${_STATUS}" = "FULL/OTHER" ]]) ; then
|
||||
_STATUS="UP"
|
||||
else
|
||||
_STATUS="DOWN"
|
||||
fi
|
||||
echo "${_STATUS}" >> "${_TMPDIR}"/ospf6-status
|
||||
|
||||
done <"${_TMPDIR}"/peers-list
|
||||
|
||||
# Check for difference with previous run
|
||||
different=$(diff -q "${_TMPDIR}"/ospf6-status.old "${_TMPDIR}"/ospf6-status)
|
||||
|
||||
if ! [[ -n "${different}" ]] ; then
|
||||
rm -f "${_PIDFILE}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# It changed so we're going to send a mail
|
||||
|
||||
_TMPMAILDIR="${_TMPDIR}"/mail
|
||||
mkdir -p "${_TMPMAILDIR}"
|
||||
|
||||
# go through sessions and list them depending on their OSPF6 state
|
||||
echo "*** Session(s) OK ***\n" >> "${_TMPMAILDIR}"/bodyok
|
||||
while read _LINE
|
||||
do
|
||||
# _LINE is session + status
|
||||
_STATUS=$(echo "${_LINE}" | awk {'print $2'})
|
||||
_SESSION=$(echo "${_LINE}" | awk {'print $1'})
|
||||
if [[ "${_STATUS}" = "UP" ]] ; then
|
||||
ospf6ctl show neighbor | grep "${_SESSION} " {{ ospf_sed_command }} >> "${_TMPMAILDIR}"/bodyok
|
||||
else
|
||||
ospf6ctl show neighbor | grep "${_SESSION} " {{ ospf_sed_command }} >> "${_TMPMAILDIR}"/bodynok
|
||||
fi
|
||||
done <"${_TMPDIR}"/ospf6-status
|
||||
|
||||
# create the mail body
|
||||
|
||||
echo "Dear NOC,\n\nThe state of one or more OSPF6 session(s) has changed:\n" > "${_TMPMAILDIR}"/header
|
||||
cat "${_TMPMAILDIR}"/header "${_TMPMAILDIR}"/bodyok > "${_TMPMAILDIR}"/body
|
||||
|
||||
_STATE="OK"
|
||||
if [[ -f "${_TMPMAILDIR}"/bodynok ]] ; then
|
||||
_STATE="NOT OK"
|
||||
echo "\n*** Session(s) on error ***\n" >> "${_TMPMAILDIR}"/body
|
||||
cat "${_TMPMAILDIR}"/bodynok >> "${_TMPMAILDIR}"/body
|
||||
fi
|
||||
|
||||
# Add some infos
|
||||
echo "\n\n*** Known OSPF routes ***\n" >> "${_TMPMAILDIR}"/body
|
||||
ospf6ctl show fib ospf >> "${_TMPMAILDIR}"/body
|
||||
|
||||
echo "\n\n*** Network used memory ***\n" >> "${_TMPMAILDIR}"/body
|
||||
netstat -m >> "${_TMPMAILDIR}"/body
|
||||
|
||||
echo "\n\n*** Server load ***\n" >> "${_TMPMAILDIR}"/body
|
||||
w >> "${_TMPMAILDIR}"/body
|
||||
|
||||
echo "\n\n*** Processes ***\n" >> "${_TMPMAILDIR}"/body
|
||||
top >> "${_TMPMAILDIR}"/body
|
||||
|
||||
# Send the mail whether we have a realname or not
|
||||
if [ -n "${_REALNAME}" ]; then
|
||||
cat "${_TMPMAILDIR}"/body | mail -s "[OSPF6] ${_REALNAME} (${_HOSTNAME}) - State change - ${_STATE}" "${_MAILTO}"
|
||||
else
|
||||
cat "${_TMPMAILDIR}"/body | mail -s "[OSPF6] ${_HOSTNAME} - State change - ${_STATE}" "${_MAILTO}"
|
||||
fi
|
||||
|
||||
# cleaning
|
||||
if [[ -d "${_TMPMAILDIR}" ]] ; then
|
||||
rm -rf "${_TMPMAILDIR}"
|
||||
fi
|
||||
rm -f "${_PIDFILE}"
|
127
roles/ospf/templates/ospfd-check-peers.sh.j2
Executable file
127
roles/ospf/templates/ospfd-check-peers.sh.j2
Executable file
|
@ -0,0 +1,127 @@
|
|||
#!/bin/ksh
|
||||
|
||||
# Script writen by Daniel Jakots for BGP, adapted by Jeremy Dubois for OSPF
|
||||
|
||||
# First we go through the list of neighbor and we write all the peer and
|
||||
# their status in "${_TMPDIR}"/ospf-status.
|
||||
|
||||
# Then we monitor if this file has changed between now and the previous run.
|
||||
|
||||
# If it did, we send a mail with the states of the different sessions.
|
||||
|
||||
set -u
|
||||
|
||||
PATH=$HOME/bin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:.
|
||||
|
||||
_MAILTO="{{ ospf_mailto }}"
|
||||
_TMPDIR=/tmp/check-ospf
|
||||
_PIDFILE="${_TMPDIR}"/ospfd-check-peers.pid
|
||||
|
||||
|
||||
if [ -e /etc/realname ]; then
|
||||
_REALNAME=$(cat /etc/realname)
|
||||
_HOSTNAME=$(hostname -s)
|
||||
else
|
||||
_HOSTNAME=$(hostname)
|
||||
fi
|
||||
|
||||
mkdir -p "${_TMPDIR}"
|
||||
|
||||
# Don't try to run if it's already running
|
||||
if [ -e "${_PIDFILE}" ]; then
|
||||
echo "$(date)" >> "${_TMPDIR}"/log
|
||||
exit 1
|
||||
else
|
||||
echo $$ >> "${_PIDFILE}"
|
||||
fi
|
||||
|
||||
# Create an history
|
||||
if [[ -f "${_TMPDIR}"/ospf-status ]] ; then
|
||||
mv "${_TMPDIR}"/ospf-status "${_TMPDIR}"/ospf-status.old
|
||||
else
|
||||
touch "${_TMPDIR}"/ospf-status
|
||||
touch "${_TMPDIR}"/ospf-status.old
|
||||
fi
|
||||
|
||||
# List peers and loops on them to list them and their OSPF state
|
||||
ospfctl show neighbor | grep -v "^$" | grep -v "Uptime" | awk {'print $1'} > "${_TMPDIR}"/peers-list
|
||||
|
||||
while read _PEER
|
||||
do
|
||||
_STATUS=$(/usr/sbin/ospfctl show neighbor | grep "${_PEER} " | awk {'print $3'})
|
||||
echo -n "${_PEER}" >> "${_TMPDIR}"/ospf-status
|
||||
echo -n " " >> "${_TMPDIR}"/ospf-status
|
||||
if ([[ "${_STATUS}" = "FULL/BCKUP" ]] || [[ "${_STATUS}" = "FULL/DR" ]] || [[ "${_STATUS}" = "2-WAY/OTHER" ]] || [[ "${_STATUS}" = "FULL/OTHER" ]]) ; then
|
||||
_STATUS="UP"
|
||||
else
|
||||
_STATUS="DOWN"
|
||||
fi
|
||||
echo "${_STATUS}" >> "${_TMPDIR}"/ospf-status
|
||||
|
||||
done <"${_TMPDIR}"/peers-list
|
||||
|
||||
# Check for difference with previous run
|
||||
different=$(diff -q "${_TMPDIR}"/ospf-status.old "${_TMPDIR}"/ospf-status)
|
||||
|
||||
if ! [[ -n "${different}" ]] ; then
|
||||
rm -f "${_PIDFILE}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# It changed so we're going to send a mail
|
||||
|
||||
_TMPMAILDIR="${_TMPDIR}"/mail
|
||||
mkdir -p "${_TMPMAILDIR}"
|
||||
|
||||
# go through sessions and list them depending on their OSPF state
|
||||
echo "*** Session(s) OK ***\n" >> "${_TMPMAILDIR}"/bodyok
|
||||
while read _LINE
|
||||
do
|
||||
# _LINE is session + status
|
||||
_STATUS=$(echo "${_LINE}" | awk {'print $2'})
|
||||
_SESSION=$(echo "${_LINE}" | awk {'print $1'})
|
||||
if [[ "${_STATUS}" = "UP" ]] ; then
|
||||
ospfctl show neighbor | grep "${_SESSION} " {{ ospf_sed_command }} >> "${_TMPMAILDIR}"/bodyok
|
||||
else
|
||||
ospfctl show neighbor | grep "${_SESSION} " {{ ospf_sed_command }} >> "${_TMPMAILDIR}"/bodynok
|
||||
fi
|
||||
done <"${_TMPDIR}"/ospf-status
|
||||
|
||||
# create the mail body
|
||||
|
||||
echo "Dear NOC,\n\nThe state of one or more OSPF session(s) has changed:\n" > "${_TMPMAILDIR}"/header
|
||||
cat "${_TMPMAILDIR}"/header "${_TMPMAILDIR}"/bodyok > "${_TMPMAILDIR}"/body
|
||||
|
||||
_STATE="OK"
|
||||
if [[ -f "${_TMPMAILDIR}"/bodynok ]] ; then
|
||||
_STATE="NOT OK"
|
||||
echo "\n*** Session(s) on error ***\n" >> "${_TMPMAILDIR}"/body
|
||||
cat "${_TMPMAILDIR}"/bodynok >> "${_TMPMAILDIR}"/body
|
||||
fi
|
||||
|
||||
# Add some infos
|
||||
echo "\n\n*** Known OSPF routes ***\n" >> "${_TMPMAILDIR}"/body
|
||||
ospfctl show fib ospf >> "${_TMPMAILDIR}"/body
|
||||
|
||||
echo "\n\n*** Network used memory ***\n" >> "${_TMPMAILDIR}"/body
|
||||
netstat -m >> "${_TMPMAILDIR}"/body
|
||||
|
||||
echo "\n\n*** Server load ***\n" >> "${_TMPMAILDIR}"/body
|
||||
w >> "${_TMPMAILDIR}"/body
|
||||
|
||||
echo "\n\n*** Processes ***\n" >> "${_TMPMAILDIR}"/body
|
||||
top >> "${_TMPMAILDIR}"/body
|
||||
|
||||
|
||||
# Send the mail whether we have a realname or not
|
||||
if [ -n "${_REALNAME}" ]; then
|
||||
cat "${_TMPMAILDIR}"/body | mail -s "[OSPF] ${_REALNAME} (${_HOSTNAME}) - State change - ${_STATE}" "${_MAILTO}"
|
||||
else
|
||||
cat "${_TMPMAILDIR}"/body | mail -s "[OSPF] ${_HOSTNAME} - State change - ${_STATE}" "${_MAILTO}"
|
||||
fi
|
||||
|
||||
# cleaning
|
||||
if [[ -d "${_TMPMAILDIR}" ]] ; then
|
||||
rm -rf "${_TMPMAILDIR}"
|
||||
fi
|
||||
rm -f "${_PIDFILE}"
|
|
@ -4,4 +4,6 @@
|
|||
src: pf.conf.j2
|
||||
dest: /etc/pf.conf
|
||||
mode: "0600"
|
||||
backup: yes
|
||||
backup: true
|
||||
tags:
|
||||
- pf
|
||||
|
|
|
@ -54,8 +54,8 @@ block log all
|
|||
#pass quick on $pfsync_if proto pfsync
|
||||
|
||||
pass out
|
||||
# 9999 = pfstat, 5666 = nrpe
|
||||
pass in on $ext_if proto tcp from <evolix> to (self) port { 9999, ssh, 5666 }
|
||||
# 5666 = nrpe
|
||||
pass in on $ext_if proto tcp from <evolix> to (self) port { ssh, 5666 }
|
||||
|
||||
# Block Attack
|
||||
# China 144.0.0.0/16 --> SSH
|
||||
|
|
|
@ -5,9 +5,10 @@ dnsPTRrecord=$(hostname)
|
|||
HardwareMark=$(sysctl hw.vendor| sed 's#hw.vendor=##')
|
||||
HardwareModel=$(sysctl hw.product| sed 's#hw.product=##')
|
||||
computerIP=$(ifconfig egress | grep inet | awk -v OFS="\n" '{ print $2, $NF }'| head -1)
|
||||
computerOS=OpenBSD
|
||||
computerKernel=$(sysctl kern.osrelease | sed 's#kern.osrelease=##')
|
||||
HardwareSerial=$(sysctl hw.serialno| sed 's#hw.serialno=##')
|
||||
computerOS="OpenBSD $computerKernel"
|
||||
HardwareSerial=$(sysctl hw.serialno 2>/dev/null | sed 's#hw.serialno=##')
|
||||
if [ -z $HardwareSerial ]; then sysctl hw | grep -qi qemu && HardwareSerial="Not Specified"; fi
|
||||
clientNumber="XXX"
|
||||
cpuMark=$(sysctl hw.model| sed 's#hw.model=##')
|
||||
cpuModel=$(sysctl hw.model| sed 's#hw.model=##')
|
||||
|
@ -62,8 +63,8 @@ HardwareSize: $cpuFreq
|
|||
HardwareType: CPU
|
||||
HardwareModel: $cpuModel
|
||||
|
||||
dn: HardwareName=ram0,EvoComputerName=${EvoComputerName},ou=computer,dc=evolix,dc=net
|
||||
HardwareName: ram0
|
||||
dn: HardwareName=mem,EvoComputerName=${EvoComputerName},ou=computer,dc=evolix,dc=net
|
||||
HardwareName: mem
|
||||
objectClass: EvoHardware
|
||||
HardwareSize: $mem
|
||||
HardwareType: mem
|
||||
|
@ -119,7 +120,7 @@ objectClass: EvoService
|
|||
ipServicePort: 22
|
||||
ServiceName: openssh
|
||||
ServiceType: ssh
|
||||
ServiceVersion: OpenSSH 6.7
|
||||
ServiceVersion: OpenSSH 8.3
|
||||
|
||||
dn: ServiceName=opensmtpd,EvoComputerName=${EvoComputerName},ou=computer,dc=evolix,dc=net
|
||||
ipServiceProtocol: tcp
|
||||
|
@ -128,13 +129,20 @@ objectClass: EvoService
|
|||
ServiceName: opensmtpd
|
||||
ipServicePort: 25
|
||||
ServiceType: smtp
|
||||
ServiceVersion: OpenSMTPD 5.4.3
|
||||
ServiceVersion: OpenSMTPD 6.7.1p1
|
||||
|
||||
dn: ServiceName=ntp,EvoComputerName=${EvoComputerName},ou=computer,dc=evolix,dc=net
|
||||
NagiosEnabled: TRUE
|
||||
objectClass: EvoService
|
||||
ServiceName: ntp
|
||||
ServiceType: ntp
|
||||
ServiceVersion: OpenNTPd 4.6
|
||||
ServiceVersion: OpenNTPd 6.2p3
|
||||
|
||||
dn: ServiceName=packetfilter,EvoComputerName=${EvoComputerName},ou=computer,dc=evolix,dc=net
|
||||
NagiosEnabled: TRUE
|
||||
objectClass: EvoService
|
||||
ServiceName: packetfilter
|
||||
ServiceType: firewall
|
||||
ServiceVersion: packetfilter
|
||||
|
||||
EOT
|
||||
|
|
47
roles/post-install/files/motd-carp-state.sh
Executable file
47
roles/post-install/files/motd-carp-state.sh
Executable file
|
@ -0,0 +1,47 @@
|
|||
#!/bin/sh
|
||||
|
||||
if [ ! -f /etc/motd-original ]; then
|
||||
cp /etc/motd /etc/motd-original
|
||||
fi
|
||||
|
||||
if [ ! -f /tmp/carp.state ]; then
|
||||
echo "unknown" > /tmp/carp.state
|
||||
fi
|
||||
|
||||
ifconfig carp0 | grep -q master
|
||||
master=$?
|
||||
ifconfig carp0 | grep -q backup
|
||||
backup=$?
|
||||
|
||||
if [ "$master" -eq 0 ]; then
|
||||
if [ $(cat /tmp/carp.state) = "master" ]; then
|
||||
# We already were master, no change
|
||||
exit 0
|
||||
fi
|
||||
cat /etc/motd-original - << EOF > /etc/motd
|
||||
__ ______ _____________________
|
||||
/ |/ / | / ___/_ __/ ____/ __ \
|
||||
/ /|_/ / /| | \__ \ / / / __/ / /_/ /
|
||||
/ / / / ___ |___/ // / / /___/ _, _/
|
||||
/_/ /_/_/ |_/____//_/ /_____/_/ |_|
|
||||
|
||||
EOF
|
||||
echo "master" > /tmp/carp.state
|
||||
elif [ "$backup" -eq 0 ]; then
|
||||
if [ $(cat /tmp/carp.state) = "backup" ]; then
|
||||
# We already were backup, no change
|
||||
exit 0
|
||||
fi
|
||||
cat /etc/motd-original - << EOF > /etc/motd
|
||||
____ ___ ________ ____ ______
|
||||
/ __ )/ | / ____/ //_/ / / / __ \
|
||||
/ __ / /| |/ / / ,< / / / / /_/ /
|
||||
/ /_/ / ___ / /___/ /| / /_/ / ____/
|
||||
/_____/_/ |_\____/_/ |_\____/_/
|
||||
|
||||
EOF
|
||||
echo "backup" > /tmp/carp.state
|
||||
else
|
||||
# No CARP
|
||||
exit 0
|
||||
fi
|
|
@ -2,3 +2,4 @@
|
|||
# tasks files
|
||||
- include: ldif.yml
|
||||
- include: update.yml
|
||||
- include: motd.yml
|
||||
|
|
25
roles/post-install/tasks/motd.yml
Normal file
25
roles/post-install/tasks/motd.yml
Normal file
|
@ -0,0 +1,25 @@
|
|||
---
|
||||
- name: Deploy dynamic motd script for CARP master or backup
|
||||
copy:
|
||||
src: motd-carp-state.sh
|
||||
dest: /usr/share/scripts/motd-carp-state.sh
|
||||
owner: root
|
||||
group: wheel
|
||||
mode: '0755'
|
||||
|
||||
- name: Fetch root crontab content
|
||||
command: >
|
||||
'grep "/bin/sh /usr/share/scripts/motd-carp-state.sh" /var/cron/tabs/root'
|
||||
check_mode: false
|
||||
register: root_crontab_content
|
||||
failed_when: false
|
||||
changed_when: false
|
||||
|
||||
- name: Cron job for dynamic motd script is installed
|
||||
cron:
|
||||
name: dynamic motd for CARP
|
||||
job: "/bin/sh /usr/share/scripts/motd-carp-state.sh"
|
||||
disabled: true
|
||||
when:
|
||||
- not (root_crontab_content.stdout
|
||||
| regex_search('/bin/sh /usr/share/scripts/motd-carp-state.sh'))
|
|
@ -1,9 +1,4 @@
|
|||
---
|
||||
- name: Fetch and install openup
|
||||
get_url:
|
||||
url: https://stable.mtier.org/openup
|
||||
dest: /usr/local/bin/openup
|
||||
mode: "0750"
|
||||
|
||||
- name: Install updates (erratas) with openup
|
||||
shell: /usr/local/bin/openup
|
||||
- name: Check and install updates (erratas) if available
|
||||
shell: /usr/sbin/syspatch
|
||||
when: ansible_distribution_version is version_compare("6.1",'>=')
|
||||
|
|
|
@ -3,19 +3,25 @@
|
|||
command: git status --porcelain
|
||||
args:
|
||||
chdir: /etc
|
||||
changed_when: False
|
||||
changed_when: false
|
||||
register: git_status
|
||||
when: not ansible_check_mode
|
||||
ignore_errors: yes
|
||||
ignore_errors: true
|
||||
tags:
|
||||
- commit-etc
|
||||
|
||||
- commit-etc
|
||||
# yamllint disable rule:line-length
|
||||
- name: /etc modifications are committed
|
||||
shell: "git add -A . && git commit -m \"{{ commit_message | default('Ansible run') }}\" --author=\"{{ ansible_env.SUDO_USER | default('Root') }} <{{ ansible_env.SUDO_USER | default('Root') }}@{{ general_technical_realm }}>\""
|
||||
shell: >
|
||||
git add -A .
|
||||
&& git commit
|
||||
-m "{{ commit_message | default('Ansible run') }}"
|
||||
--author="{{ ansible_env.SUDO_USER | default('Root') }}
|
||||
<{{ ansible_env.SUDO_USER | default('Root') }}@{{ general_technical_realm }}>"
|
||||
args:
|
||||
chdir: /etc
|
||||
register: etc_commit_end_evolinux
|
||||
when: not ansible_check_mode and git_status.stdout != ""
|
||||
ignore_errors: yes
|
||||
ignore_errors: true
|
||||
tags:
|
||||
- commit-etc
|
||||
- commit-etc
|
||||
# yamllint enable rule:line-length
|
||||
|
|
|
@ -3,26 +3,31 @@
|
|||
## Edit and uncomment to overwrite the default values ##
|
||||
########################################################
|
||||
|
||||
#ntpd_servers:
|
||||
#- "ntp.evolix.net"
|
||||
# ntpd_servers:
|
||||
# - "ntp.evolix.net"
|
||||
#
|
||||
#general_alert_email: "root@localhost"
|
||||
#general_technical_realm: "example.com"
|
||||
# general_alert_email: "root@localhost"
|
||||
# general_technical_realm: "example.com"
|
||||
#
|
||||
#evomaintenance_realm: "example.com"
|
||||
#evomaintenance_alert_email: "evomaintenance-{{ inventory_hostname }}@{{ evomaintenance_realm }}"
|
||||
#evomaintenance_hostname: "{{ inventory_hostname }}.{{ general_technical_realm }}"
|
||||
#evomaintenance_pg_host: Null
|
||||
#evomaintenance_pg_passwd: Null
|
||||
#evomaintenance_pg_db: Null
|
||||
#evomaintenance_pg_table: Null
|
||||
#evomaintenance_from_domain: "{{ evomaintenance_realm }}"
|
||||
#evomaintenance_from: "evomaintenance@{{ evomaintenance_from_domain }}"
|
||||
#evomaintenance_full_from: "Evomaintenance <{{ evomaintenance_from }}>"
|
||||
#evomaintenance_urgency_from: mama.doe@example.com
|
||||
#evomaintenance_urgency_tel: "06.00.00.00.00"
|
||||
# evomaintenance_realm: "example.com"
|
||||
# evomaintenance_alert_email:
|
||||
# "evomaintenance-{{ inventory_hostname }}@{{ evomaintenance_realm }}"
|
||||
# evomaintenance_hostname:
|
||||
# "{{ inventory_hostname }}.{{ general_technical_realm }}"
|
||||
# evomaintenance_pg_host: Null
|
||||
# evomaintenance_pg_passwd: Null
|
||||
# evomaintenance_pg_db: Null
|
||||
# evomaintenance_pg_table: Null
|
||||
# evomaintenance_from_domain: "{{ evomaintenance_realm }}"
|
||||
# evomaintenance_from: "evomaintenance@{{ evomaintenance_from_domain }}"
|
||||
# evomaintenance_full_from: "Evomaintenance <{{ evomaintenance_from }}>"
|
||||
# evomaintenance_urgency_from: mama.doe@example.com
|
||||
# evomaintenance_urgency_tel: "06.00.00.00.00"
|
||||
#
|
||||
#evolix_users:
|
||||
# evobsd_ssh_group: "foo-ssh"
|
||||
# evobsd_sudo_group: "foo-sudo"
|
||||
#
|
||||
# evolix_users:
|
||||
# foo:
|
||||
# name: foo
|
||||
# uid: 1042
|
||||
|
|
0
vars/openbsd-secret.yml
Normal file
0
vars/openbsd-secret.yml
Normal file
0
vars/secrets.yml
Normal file
0
vars/secrets.yml
Normal file
Loading…
Reference in a new issue