Merge pull request 'Release 10.5.0' (#124) from unstable into stable
Reviewed-on: #124
This commit is contained in:
commit
c85864a6a5
40
CHANGELOG.md
40
CHANGELOG.md
|
@ -20,6 +20,46 @@ The **patch** part changes incrementally at each release.
|
|||
|
||||
### Security
|
||||
|
||||
## [10.5.0] 2021-04-01
|
||||
|
||||
### Added
|
||||
|
||||
* apache: new variables for logrotate + server-status
|
||||
* filebeat: package can be upgraded to latest (default: False)
|
||||
* haproxy: possible admin access with login/pass
|
||||
* lxc-php: Add PHP 7.4 support
|
||||
* metricbeat: package can be upgraded to latest (default: False)
|
||||
* metricbeat: new variables to configure SSL mode
|
||||
* nagios-nrpe: new script check_phpfpm_multi
|
||||
* nginx: add access to server status on default VHost
|
||||
* postfix: add smtpd_relay_restrictions in configuration
|
||||
|
||||
### Changed
|
||||
|
||||
* apache: rotate logs daily instead of weekly
|
||||
* apache: deny requests to ^/evolinux_fpm_status-.*
|
||||
* certbot: use a fixed 1.9.0 version of the certbot-auto script (renamed "letsencrypt-auto")
|
||||
* certbot: use the legacy script on Debian 8 and 9
|
||||
* elasticsearch: log rotation is more readable/maintainable
|
||||
* evoacme: upstream release 21.01
|
||||
* evolinux-users: Add sudo rights for nagios for multi-php lxc
|
||||
* listupgrade: update script from upstream
|
||||
* minifirewall: change some defaults
|
||||
* nagios-nrpe: update check_phpfpm_status.pl & install perl dependencies
|
||||
* redis: use /run instead or /var/run
|
||||
* redis: escape password in Munin configuration
|
||||
|
||||
### Fixed
|
||||
|
||||
* bind9: added log files to apparmor definition so bind can run
|
||||
* filebeat: fix Ansible syntax error
|
||||
* nagios-nrpe: libfcgi-client-perl is not available before Debian 10
|
||||
* redis: socket/pid directories have the correct permissions
|
||||
|
||||
### Removed
|
||||
|
||||
* nginx: no more "minimal" mode, but the package remains customizable.
|
||||
|
||||
## [10.4.0] 2020-12-24
|
||||
|
||||
### Added
|
||||
|
|
|
@ -50,6 +50,8 @@ Before starting anything of importance, we suggest contacting us to discuss what
|
|||
|
||||
Our conventions are available in the "ansible-public":https://gitea.evolix.org/evolix/ansible-public repository, in the CONVENTIONS.md file.
|
||||
|
||||
All modifications should be documented in the CHANGELOG file, to help review releases. We encourage atomic commits, on a single role, and with the CHANGELOG in the same commit.
|
||||
|
||||
## Workflow
|
||||
|
||||
The ideal and most typical workflow is to create a branch, based on the "unstable" branch. The branch should have a descriptive name (a ticket/issue number is great). The branch can be treated as a pull-request or merge-request. It should be propery tested and reviewed before merging into "unstable".
|
||||
|
|
|
@ -11,6 +11,7 @@ apache_evolinux_default_enabled: True
|
|||
apache_evolinux_default_ssl_cert: /etc/ssl/certs/ssl-cert-snakeoil.pem
|
||||
apache_evolinux_default_ssl_key: /etc/ssl/private/ssl-cert-snakeoil.key
|
||||
|
||||
apache_serverstatus_host: 127.0.0.1
|
||||
apache_serverstatus_suffix: ""
|
||||
apache_serverstatus_suffix_file: "/etc/evolinux/apache_serverstatus_suffix"
|
||||
|
||||
|
@ -20,4 +21,5 @@ apache_munin_include: True
|
|||
general_alert_email: "root@localhost"
|
||||
log2mail_alert_email: Null
|
||||
|
||||
apache_serverstatus_host: 127.0.0.1
|
||||
apache_logrotate_frequency: daily
|
||||
apache_logrotate_rotate: 365
|
||||
|
|
|
@ -9,16 +9,19 @@ StartServers 50
|
|||
MinSpareServers 20
|
||||
MaxSpareServers 30
|
||||
MaxRequestsPerChild 0
|
||||
|
||||
<Directory /home/>
|
||||
AllowOverride None
|
||||
Require all granted
|
||||
# "Require not env XXX" is not supported :(
|
||||
Deny from env=GoAway
|
||||
</Directory>
|
||||
|
||||
<IfModule mod_ssl.c>
|
||||
SSLProtocol all -SSLv2 -SSLv3
|
||||
SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5:!RC4
|
||||
SSLProtocol all -SSLv2 -SSLv3
|
||||
SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5:!RC4
|
||||
</IfModule>
|
||||
|
||||
<Files ~ "\.(inc|bak)$">
|
||||
Require all denied
|
||||
</Files>
|
||||
|
@ -31,6 +34,10 @@ SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5:!RC4
|
|||
</IfModule>
|
||||
|
||||
<IfModule mpm_itk.c>
|
||||
LimitUIDRange 0 6000
|
||||
LimitGIDRange 0 6000
|
||||
LimitUIDRange 0 6000
|
||||
LimitGIDRange 0 6000
|
||||
</IfModule>
|
||||
|
||||
<LocationMatch "^/evolinux_fpm_status-.*">
|
||||
Require all denied
|
||||
</LocationMatch>
|
||||
|
|
|
@ -161,19 +161,19 @@
|
|||
tags:
|
||||
- apache
|
||||
|
||||
- name: "logrotate: rotate weekly"
|
||||
- name: "logrotate: {{ apache_logrotate_frequency }}"
|
||||
replace:
|
||||
dest: /etc/logrotate.d/apache2
|
||||
regexp: "(daily|weekly|monthly)"
|
||||
replace: "weekly"
|
||||
replace: "{{ apache_logrotate_frequency }}"
|
||||
tags:
|
||||
- apache
|
||||
|
||||
- name: "logrotate: keep 52 files"
|
||||
- name: "logrotate: rotate {{ apache_logrotate_rotate }}"
|
||||
replace:
|
||||
dest: /etc/logrotate.d/apache2
|
||||
regexp: '^(\s+rotate) \d+$'
|
||||
replace: '\1 52'
|
||||
replace: '\1 {{ apache_logrotate_rotate }}'
|
||||
tags:
|
||||
- apache
|
||||
|
||||
|
|
|
@ -2,6 +2,11 @@
|
|||
- name: reload systemd
|
||||
command: systemctl daemon-reload
|
||||
|
||||
- name: restart apparmor
|
||||
service:
|
||||
name: apparmor
|
||||
state: restarted
|
||||
|
||||
- name: restart bind
|
||||
service:
|
||||
name: bind9
|
||||
|
|
|
@ -8,6 +8,16 @@
|
|||
bind_chroot_path: /var/chroot-bind
|
||||
when: bind_chroot_set
|
||||
|
||||
- name: configure apparmor
|
||||
template:
|
||||
src: apparmor.usr.sbin.named.j2
|
||||
dest: /etc/apparmor.d/usr.sbin.named
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
force: yes
|
||||
notify: restart apparmor
|
||||
|
||||
- name: package are installed
|
||||
apt:
|
||||
name:
|
||||
|
|
95
bind/templates/apparmor.usr.sbin.named.j2
Normal file
95
bind/templates/apparmor.usr.sbin.named.j2
Normal file
|
@ -0,0 +1,95 @@
|
|||
# vim:syntax=apparmor
|
||||
# Last Modified: Tue Mar 9 14:17:50 EST 2021
|
||||
#include <tunables/global>
|
||||
|
||||
/usr/sbin/named flags=(attach_disconnected) {
|
||||
#include <abstractions/base>
|
||||
#include <abstractions/nameservice>
|
||||
|
||||
capability net_bind_service,
|
||||
capability setgid,
|
||||
capability setuid,
|
||||
capability sys_chroot,
|
||||
capability sys_resource,
|
||||
|
||||
# /etc/bind should be read-only for bind
|
||||
# /var/lib/bind is for dynamically updated zone (and journal) files.
|
||||
# /var/cache/bind is for slave/stub data, since we're not the origin of it.
|
||||
# See /usr/share/doc/bind9/README.Debian.gz
|
||||
/etc/bind/** r,
|
||||
/var/lib/bind/** rw,
|
||||
/var/lib/bind/ rw,
|
||||
/var/cache/bind/** lrw,
|
||||
/var/cache/bind/ rw,
|
||||
|
||||
# Database file used by allow-new-zones
|
||||
/var/cache/bind/_default.nzd-lock rwk,
|
||||
|
||||
# gssapi
|
||||
/etc/krb5.keytab kr,
|
||||
/etc/bind/krb5.keytab kr,
|
||||
|
||||
# ssl
|
||||
/etc/ssl/openssl.cnf r,
|
||||
|
||||
# root hints from dns-data-root
|
||||
/usr/share/dns/root.* r,
|
||||
|
||||
# GeoIP data files for GeoIP ACLs
|
||||
/usr/share/GeoIP/** r,
|
||||
|
||||
# dnscvsutil package
|
||||
/var/lib/dnscvsutil/compiled/** rw,
|
||||
|
||||
# Allow changing worker thread names
|
||||
owner @{PROC}/@{pid}/task/@{tid}/comm rw,
|
||||
|
||||
@{PROC}/net/if_inet6 r,
|
||||
@{PROC}/*/net/if_inet6 r,
|
||||
@{PROC}/sys/net/ipv4/ip_local_port_range r,
|
||||
/usr/sbin/named mr,
|
||||
/{,var/}run/named/named.pid w,
|
||||
/{,var/}run/named/session.key w,
|
||||
# support for resolvconf
|
||||
/{,var/}run/named/named.options r,
|
||||
|
||||
# some people like to put logs in /var/log/named/ instead of having
|
||||
# syslog do the heavy lifting.
|
||||
{{ bind_log_file }} rw,
|
||||
{{ bind_query_file }} rw,
|
||||
|
||||
# gssapi
|
||||
/var/lib/sss/pubconf/krb5.include.d/** r,
|
||||
/var/lib/sss/pubconf/krb5.include.d/ r,
|
||||
/var/lib/sss/mc/initgroups r,
|
||||
/etc/gss/mech.d/ r,
|
||||
|
||||
# ldap
|
||||
/etc/ldap/ldap.conf r,
|
||||
/{,var/}run/slapd-*.socket rw,
|
||||
|
||||
# dynamic updates
|
||||
/var/tmp/DNS_* rw,
|
||||
|
||||
# dyndb backends
|
||||
/usr/lib/bind/*.so rm,
|
||||
|
||||
# Samba DLZ
|
||||
/{usr/,}lib/@{multiarch}/samba/bind9/*.so rm,
|
||||
/{usr/,}lib/@{multiarch}/samba/gensec/*.so rm,
|
||||
/{usr/,}lib/@{multiarch}/samba/ldb/*.so rm,
|
||||
/{usr/,}lib/@{multiarch}/ldb/modules/ldb/*.so rm,
|
||||
/var/lib/samba/bind-dns/dns.keytab rk,
|
||||
/var/lib/samba/bind-dns/named.conf r,
|
||||
/var/lib/samba/bind-dns/dns/** rwk,
|
||||
/var/lib/samba/private/dns.keytab rk,
|
||||
/var/lib/samba/private/named.conf r,
|
||||
/var/lib/samba/private/dns/** rwk,
|
||||
/etc/samba/smb.conf r,
|
||||
/dev/urandom rwmk,
|
||||
owner /var/tmp/krb5_* rwk,
|
||||
|
||||
# Site-specific additions and overrides. See local/README for details.
|
||||
#include <local/usr.sbin.named>
|
||||
}
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
---
|
||||
|
||||
certbot_work_dir: /var/lib/letsencrypt
|
||||
certbot_custom_crontab: True
|
||||
|
|
1996
certbot/files/letsencrypt-auto
Normal file
1996
certbot/files/letsencrypt-auto
Normal file
|
@ -0,0 +1,1996 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# Download and run the latest release version of the Certbot client.
|
||||
#
|
||||
# NOTE: THIS SCRIPT IS AUTO-GENERATED AND SELF-UPDATING
|
||||
#
|
||||
# IF YOU WANT TO EDIT IT LOCALLY, *ALWAYS* RUN YOUR COPY WITH THE
|
||||
# "--no-self-upgrade" FLAG
|
||||
#
|
||||
# IF YOU WANT TO SEND PULL REQUESTS, THE REAL SOURCE FOR THIS FILE IS
|
||||
# letsencrypt-auto-source/letsencrypt-auto.template AND
|
||||
# letsencrypt-auto-source/pieces/bootstrappers/*
|
||||
|
||||
set -e # Work even if somebody does "sh thisscript.sh".
|
||||
|
||||
# Note: you can set XDG_DATA_HOME or VENV_PATH before running this script,
|
||||
# if you want to change where the virtual environment will be installed
|
||||
|
||||
# HOME might not be defined when being run through something like systemd
|
||||
if [ -z "$HOME" ]; then
|
||||
HOME=~root
|
||||
fi
|
||||
if [ -z "$XDG_DATA_HOME" ]; then
|
||||
XDG_DATA_HOME=~/.local/share
|
||||
fi
|
||||
if [ -z "$VENV_PATH" ]; then
|
||||
# We export these values so they are preserved properly if this script is
|
||||
# rerun with sudo/su where $HOME/$XDG_DATA_HOME may have a different value.
|
||||
export OLD_VENV_PATH="$XDG_DATA_HOME/letsencrypt"
|
||||
export VENV_PATH="/opt/eff.org/certbot/venv"
|
||||
fi
|
||||
VENV_BIN="$VENV_PATH/bin"
|
||||
BOOTSTRAP_VERSION_PATH="$VENV_PATH/certbot-auto-bootstrap-version.txt"
|
||||
LE_AUTO_VERSION="1.9.0"
|
||||
BASENAME=$(basename $0)
|
||||
USAGE="Usage: $BASENAME [OPTIONS]
|
||||
A self-updating wrapper script for the Certbot ACME client. When run, updates
|
||||
to both this script and certbot will be downloaded and installed. After
|
||||
ensuring you have the latest versions installed, certbot will be invoked with
|
||||
all arguments you have provided.
|
||||
|
||||
Help for certbot itself cannot be provided until it is installed.
|
||||
|
||||
--debug attempt experimental installation
|
||||
-h, --help print this help
|
||||
-n, --non-interactive, --noninteractive run without asking for user input
|
||||
--no-bootstrap do not install OS dependencies
|
||||
--no-permissions-check do not warn about file system permissions
|
||||
--no-self-upgrade do not download updates
|
||||
--os-packages-only install OS dependencies and exit
|
||||
--install-only install certbot, upgrade if needed, and exit
|
||||
-v, --verbose provide more output
|
||||
-q, --quiet provide only update/error output;
|
||||
implies --non-interactive
|
||||
|
||||
All arguments are accepted and forwarded to the Certbot client when run."
|
||||
export CERTBOT_AUTO="$0"
|
||||
|
||||
for arg in "$@" ; do
|
||||
case "$arg" in
|
||||
--debug)
|
||||
DEBUG=1;;
|
||||
--os-packages-only)
|
||||
OS_PACKAGES_ONLY=1;;
|
||||
--install-only)
|
||||
INSTALL_ONLY=1;;
|
||||
--no-self-upgrade)
|
||||
# Do not upgrade this script (also prevents client upgrades, because each
|
||||
# copy of the script pins a hash of the python client)
|
||||
NO_SELF_UPGRADE=1;;
|
||||
--no-permissions-check)
|
||||
NO_PERMISSIONS_CHECK=1;;
|
||||
--no-bootstrap)
|
||||
NO_BOOTSTRAP=1;;
|
||||
--help)
|
||||
HELP=1;;
|
||||
--noninteractive|--non-interactive)
|
||||
NONINTERACTIVE=1;;
|
||||
--quiet)
|
||||
QUIET=1;;
|
||||
renew)
|
||||
ASSUME_YES=1;;
|
||||
--verbose)
|
||||
VERBOSE=1;;
|
||||
-[!-]*)
|
||||
OPTIND=1
|
||||
while getopts ":hnvq" short_arg $arg; do
|
||||
case "$short_arg" in
|
||||
h)
|
||||
HELP=1;;
|
||||
n)
|
||||
NONINTERACTIVE=1;;
|
||||
q)
|
||||
QUIET=1;;
|
||||
v)
|
||||
VERBOSE=1;;
|
||||
esac
|
||||
done;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ $BASENAME = "letsencrypt-auto" ]; then
|
||||
# letsencrypt-auto does not respect --help or --yes for backwards compatibility
|
||||
NONINTERACTIVE=1
|
||||
HELP=0
|
||||
fi
|
||||
|
||||
# Set ASSUME_YES to 1 if QUIET or NONINTERACTIVE
|
||||
if [ "$QUIET" = 1 -o "$NONINTERACTIVE" = 1 ]; then
|
||||
ASSUME_YES=1
|
||||
fi
|
||||
|
||||
say() {
|
||||
if [ "$QUIET" != 1 ]; then
|
||||
echo "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
error() {
|
||||
echo "$@"
|
||||
}
|
||||
|
||||
# Support for busybox and others where there is no "command",
|
||||
# but "which" instead
|
||||
if command -v command > /dev/null 2>&1 ; then
|
||||
export EXISTS="command -v"
|
||||
elif which which > /dev/null 2>&1 ; then
|
||||
export EXISTS="which"
|
||||
else
|
||||
error "Cannot find command nor which... please install one!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Certbot itself needs root access for almost all modes of operation.
|
||||
# certbot-auto needs root access to bootstrap OS dependencies and install
|
||||
# Certbot at a protected path so it can be safely run as root. To accomplish
|
||||
# this, this script will attempt to run itself as root if it doesn't have the
|
||||
# necessary privileges by using `sudo` or falling back to `su` if it is not
|
||||
# available. The mechanism used to obtain root access can be set explicitly by
|
||||
# setting the environment variable LE_AUTO_SUDO to 'sudo', 'su', 'su_sudo',
|
||||
# 'SuSudo', or '' as used below.
|
||||
|
||||
# Because the parameters in `su -c` has to be a string,
|
||||
# we need to properly escape it.
|
||||
SuSudo() {
|
||||
args=""
|
||||
# This `while` loop iterates over all parameters given to this function.
|
||||
# For each parameter, all `'` will be replace by `'"'"'`, and the escaped string
|
||||
# will be wrapped in a pair of `'`, then appended to `$args` string
|
||||
# For example, `echo "It's only 1\$\!"` will be escaped to:
|
||||
# 'echo' 'It'"'"'s only 1$!'
|
||||
# │ │└┼┘│
|
||||
# │ │ │ └── `'s only 1$!'` the literal string
|
||||
# │ │ └── `\"'\"` is a single quote (as a string)
|
||||
# │ └── `'It'`, to be concatenated with the strings following it
|
||||
# └── `echo` wrapped in a pair of `'`, it's totally fine for the shell command itself
|
||||
while [ $# -ne 0 ]; do
|
||||
args="$args'$(printf "%s" "$1" | sed -e "s/'/'\"'\"'/g")' "
|
||||
shift
|
||||
done
|
||||
su root -c "$args"
|
||||
}
|
||||
|
||||
# Sets the environment variable SUDO to be the name of the program or function
|
||||
# to call to get root access. If this script already has root privleges, SUDO
|
||||
# is set to an empty string. The value in SUDO should be run with the command
|
||||
# to called with root privileges as arguments.
|
||||
SetRootAuthMechanism() {
|
||||
SUDO=""
|
||||
if [ -n "${LE_AUTO_SUDO+x}" ]; then
|
||||
case "$LE_AUTO_SUDO" in
|
||||
SuSudo|su_sudo|su)
|
||||
SUDO=SuSudo
|
||||
;;
|
||||
sudo)
|
||||
SUDO="sudo -E"
|
||||
;;
|
||||
'')
|
||||
# If we're not running with root, don't check that this script can only
|
||||
# be modified by system users and groups.
|
||||
NO_PERMISSIONS_CHECK=1
|
||||
;;
|
||||
*)
|
||||
error "Error: unknown root authorization mechanism '$LE_AUTO_SUDO'."
|
||||
exit 1
|
||||
esac
|
||||
say "Using preset root authorization mechanism '$LE_AUTO_SUDO'."
|
||||
else
|
||||
if test "`id -u`" -ne "0" ; then
|
||||
if $EXISTS sudo 1>/dev/null 2>&1; then
|
||||
SUDO="sudo -E"
|
||||
else
|
||||
say \"sudo\" is not available, will use \"su\" for installation steps...
|
||||
SUDO=SuSudo
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
if [ "$1" = "--cb-auto-has-root" ]; then
|
||||
shift 1
|
||||
else
|
||||
SetRootAuthMechanism
|
||||
if [ -n "$SUDO" ]; then
|
||||
say "Requesting to rerun $0 with root privileges..."
|
||||
$SUDO "$0" --cb-auto-has-root "$@"
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
# Runs this script again with the given arguments. --cb-auto-has-root is added
|
||||
# to the command line arguments to ensure we don't try to acquire root a
|
||||
# second time. After the script is rerun, we exit the current script.
|
||||
RerunWithArgs() {
|
||||
"$0" --cb-auto-has-root "$@"
|
||||
exit 0
|
||||
}
|
||||
|
||||
BootstrapMessage() {
|
||||
# Arguments: Platform name
|
||||
say "Bootstrapping dependencies for $1... (you can skip this with --no-bootstrap)"
|
||||
}
|
||||
|
||||
ExperimentalBootstrap() {
|
||||
# Arguments: Platform name, bootstrap function name
|
||||
if [ "$DEBUG" = 1 ]; then
|
||||
if [ "$2" != "" ]; then
|
||||
BootstrapMessage $1
|
||||
$2
|
||||
fi
|
||||
else
|
||||
error "FATAL: $1 support is very experimental at present..."
|
||||
error "if you would like to work on improving it, please ensure you have backups"
|
||||
error "and then run this script again with the --debug flag!"
|
||||
error "Alternatively, you can install OS dependencies yourself and run this script"
|
||||
error "again with --no-bootstrap."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
DeprecationBootstrap() {
|
||||
# Arguments: Platform name, bootstrap function name
|
||||
if [ "$DEBUG" = 1 ]; then
|
||||
if [ "$2" != "" ]; then
|
||||
BootstrapMessage $1
|
||||
$2
|
||||
fi
|
||||
else
|
||||
error "WARNING: certbot-auto support for this $1 is DEPRECATED!"
|
||||
error "Please visit certbot.eff.org to learn how to download a version of"
|
||||
error "Certbot that is packaged for your system. While an existing version"
|
||||
error "of certbot-auto may work currently, we have stopped supporting updating"
|
||||
error "system packages for your system. Please switch to a packaged version"
|
||||
error "as soon as possible."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
MIN_PYTHON_2_VERSION="2.7"
|
||||
MIN_PYVER2=$(echo "$MIN_PYTHON_2_VERSION" | sed 's/\.//')
|
||||
MIN_PYTHON_3_VERSION="3.6"
|
||||
MIN_PYVER3=$(echo "$MIN_PYTHON_3_VERSION" | sed 's/\.//')
|
||||
# Sets LE_PYTHON to Python version string and PYVER to the first two
|
||||
# digits of the python version.
|
||||
# MIN_PYVER and MIN_PYTHON_VERSION are also set by this function, and their
|
||||
# values depend on if we try to use Python 3 or Python 2.
|
||||
DeterminePythonVersion() {
|
||||
# Arguments: "NOCRASH" if we shouldn't crash if we don't find a good python
|
||||
#
|
||||
# If no Python is found, PYVER is set to 0.
|
||||
if [ "$USE_PYTHON_3" = 1 ]; then
|
||||
MIN_PYVER=$MIN_PYVER3
|
||||
MIN_PYTHON_VERSION=$MIN_PYTHON_3_VERSION
|
||||
for LE_PYTHON in "$LE_PYTHON" python3; do
|
||||
# Break (while keeping the LE_PYTHON value) if found.
|
||||
$EXISTS "$LE_PYTHON" > /dev/null && break
|
||||
done
|
||||
else
|
||||
MIN_PYVER=$MIN_PYVER2
|
||||
MIN_PYTHON_VERSION=$MIN_PYTHON_2_VERSION
|
||||
for LE_PYTHON in "$LE_PYTHON" python2.7 python27 python2 python; do
|
||||
# Break (while keeping the LE_PYTHON value) if found.
|
||||
$EXISTS "$LE_PYTHON" > /dev/null && break
|
||||
done
|
||||
fi
|
||||
if [ "$?" != "0" ]; then
|
||||
if [ "$1" != "NOCRASH" ]; then
|
||||
error "Cannot find any Pythons; please install one!"
|
||||
exit 1
|
||||
else
|
||||
PYVER=0
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
PYVER=$("$LE_PYTHON" -V 2>&1 | cut -d" " -f 2 | cut -d. -f1,2 | sed 's/\.//')
|
||||
if [ "$PYVER" -lt "$MIN_PYVER" ]; then
|
||||
if [ "$1" != "NOCRASH" ]; then
|
||||
error "You have an ancient version of Python entombed in your operating system..."
|
||||
error "This isn't going to work; you'll need at least version $MIN_PYTHON_VERSION."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# If new packages are installed by BootstrapDebCommon below, this version
|
||||
# number must be increased.
|
||||
BOOTSTRAP_DEB_COMMON_VERSION=1
|
||||
|
||||
BootstrapDebCommon() {
|
||||
# Current version tested with:
|
||||
#
|
||||
# - Ubuntu
|
||||
# - 14.04 (x64)
|
||||
# - 15.04 (x64)
|
||||
# - Debian
|
||||
# - 7.9 "wheezy" (x64)
|
||||
# - sid (2015-10-21) (x64)
|
||||
|
||||
# Past versions tested with:
|
||||
#
|
||||
# - Debian 8.0 "jessie" (x64)
|
||||
# - Raspbian 7.8 (armhf)
|
||||
|
||||
# Believed not to work:
|
||||
#
|
||||
# - Debian 6.0.10 "squeeze" (x64)
|
||||
|
||||
if [ "$QUIET" = 1 ]; then
|
||||
QUIET_FLAG='-qq'
|
||||
fi
|
||||
|
||||
apt-get $QUIET_FLAG update || error apt-get update hit problems but continuing anyway...
|
||||
|
||||
# virtualenv binary can be found in different packages depending on
|
||||
# distro version (#346)
|
||||
|
||||
virtualenv=
|
||||
# virtual env is known to apt and is installable
|
||||
if apt-cache show virtualenv > /dev/null 2>&1 ; then
|
||||
if ! LC_ALL=C apt-cache --quiet=0 show virtualenv 2>&1 | grep -q 'No packages found'; then
|
||||
virtualenv="virtualenv"
|
||||
fi
|
||||
fi
|
||||
|
||||
if apt-cache show python-virtualenv > /dev/null 2>&1; then
|
||||
virtualenv="$virtualenv python-virtualenv"
|
||||
fi
|
||||
|
||||
augeas_pkg="libaugeas0 augeas-lenses"
|
||||
|
||||
if [ "$ASSUME_YES" = 1 ]; then
|
||||
YES_FLAG="-y"
|
||||
fi
|
||||
|
||||
apt-get install $QUIET_FLAG $YES_FLAG --no-install-recommends \
|
||||
python \
|
||||
python-dev \
|
||||
$virtualenv \
|
||||
gcc \
|
||||
$augeas_pkg \
|
||||
libssl-dev \
|
||||
openssl \
|
||||
libffi-dev \
|
||||
ca-certificates \
|
||||
|
||||
|
||||
if ! $EXISTS virtualenv > /dev/null ; then
|
||||
error Failed to install a working \"virtualenv\" command, exiting
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# If new packages are installed by BootstrapRpmCommonBase below, version
|
||||
# numbers in rpm_common.sh and rpm_python3.sh must be increased.
|
||||
|
||||
# Sets TOOL to the name of the package manager
|
||||
# Sets appropriate values for YES_FLAG and QUIET_FLAG based on $ASSUME_YES and $QUIET_FLAG.
|
||||
# Note: this function is called both while selecting the bootstrap scripts and
|
||||
# during the actual bootstrap. Some things like prompting to user can be done in the latter
|
||||
# case, but not in the former one.
|
||||
InitializeRPMCommonBase() {
|
||||
if type dnf 2>/dev/null
|
||||
then
|
||||
TOOL=dnf
|
||||
elif type yum 2>/dev/null
|
||||
then
|
||||
TOOL=yum
|
||||
|
||||
else
|
||||
error "Neither yum nor dnf found. Aborting bootstrap!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$ASSUME_YES" = 1 ]; then
|
||||
YES_FLAG="-y"
|
||||
fi
|
||||
if [ "$QUIET" = 1 ]; then
|
||||
QUIET_FLAG='--quiet'
|
||||
fi
|
||||
}
|
||||
|
||||
BootstrapRpmCommonBase() {
|
||||
# Arguments: whitespace-delimited python packages to install
|
||||
|
||||
InitializeRPMCommonBase # This call is superfluous in practice
|
||||
|
||||
pkgs="
|
||||
gcc
|
||||
augeas-libs
|
||||
openssl
|
||||
openssl-devel
|
||||
libffi-devel
|
||||
redhat-rpm-config
|
||||
ca-certificates
|
||||
"
|
||||
|
||||
# Add the python packages
|
||||
pkgs="$pkgs
|
||||
$1
|
||||
"
|
||||
|
||||
if $TOOL list installed "httpd" >/dev/null 2>&1; then
|
||||
pkgs="$pkgs
|
||||
mod_ssl
|
||||
"
|
||||
fi
|
||||
|
||||
if ! $TOOL install $YES_FLAG $QUIET_FLAG $pkgs; then
|
||||
error "Could not install OS dependencies. Aborting bootstrap!"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# If new packages are installed by BootstrapRpmCommon below, this version
|
||||
# number must be increased.
|
||||
BOOTSTRAP_RPM_COMMON_VERSION=1
|
||||
|
||||
BootstrapRpmCommon() {
|
||||
# Tested with:
|
||||
# - Fedora 20, 21, 22, 23 (x64)
|
||||
# - Centos 7 (x64: on DigitalOcean droplet)
|
||||
# - CentOS 7 Minimal install in a Hyper-V VM
|
||||
# - CentOS 6
|
||||
|
||||
InitializeRPMCommonBase
|
||||
|
||||
# Most RPM distros use the "python" or "python-" naming convention. Let's try that first.
|
||||
if $TOOL list python >/dev/null 2>&1; then
|
||||
python_pkgs="$python
|
||||
python-devel
|
||||
python-virtualenv
|
||||
python-tools
|
||||
python-pip
|
||||
"
|
||||
# Fedora 26 starts to use the prefix python2 for python2 based packages.
|
||||
# this elseif is theoretically for any Fedora over version 26:
|
||||
elif $TOOL list python2 >/dev/null 2>&1; then
|
||||
python_pkgs="$python2
|
||||
python2-libs
|
||||
python2-setuptools
|
||||
python2-devel
|
||||
python2-virtualenv
|
||||
python2-tools
|
||||
python2-pip
|
||||
"
|
||||
# Some distros and older versions of current distros use a "python27"
|
||||
# instead of the "python" or "python-" naming convention.
|
||||
else
|
||||
python_pkgs="$python27
|
||||
python27-devel
|
||||
python27-virtualenv
|
||||
python27-tools
|
||||
python27-pip
|
||||
"
|
||||
fi
|
||||
|
||||
BootstrapRpmCommonBase "$python_pkgs"
|
||||
}
|
||||
|
||||
# If new packages are installed by BootstrapRpmPython3 below, this version
|
||||
# number must be increased.
|
||||
BOOTSTRAP_RPM_PYTHON3_LEGACY_VERSION=1
|
||||
|
||||
# Checks if rh-python36 can be installed.
|
||||
Python36SclIsAvailable() {
|
||||
InitializeRPMCommonBase >/dev/null 2>&1;
|
||||
|
||||
if "${TOOL}" list rh-python36 >/dev/null 2>&1; then
|
||||
return 0
|
||||
fi
|
||||
if "${TOOL}" list centos-release-scl >/dev/null 2>&1; then
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
# Try to enable rh-python36 from SCL if it is necessary and possible.
|
||||
EnablePython36SCL() {
|
||||
if "$EXISTS" python3.6 > /dev/null 2> /dev/null; then
|
||||
return 0
|
||||
fi
|
||||
if [ ! -f /opt/rh/rh-python36/enable ]; then
|
||||
return 0
|
||||
fi
|
||||
set +e
|
||||
if ! . /opt/rh/rh-python36/enable; then
|
||||
error 'Unable to enable rh-python36!'
|
||||
exit 1
|
||||
fi
|
||||
set -e
|
||||
}
|
||||
|
||||
# This bootstrap concerns old RedHat-based distributions that do not ship by default
|
||||
# with Python 2.7, but only Python 2.6. We bootstrap them by enabling SCL and installing
|
||||
# Python 3.6. Some of these distributions are: CentOS/RHEL/OL/SL 6.
|
||||
BootstrapRpmPython3Legacy() {
|
||||
# Tested with:
|
||||
# - CentOS 6
|
||||
|
||||
InitializeRPMCommonBase
|
||||
|
||||
if ! "${TOOL}" list rh-python36 >/dev/null 2>&1; then
|
||||
echo "To use Certbot on this operating system, packages from the SCL repository need to be installed."
|
||||
if ! "${TOOL}" list centos-release-scl >/dev/null 2>&1; then
|
||||
error "Enable the SCL repository and try running Certbot again."
|
||||
exit 1
|
||||
fi
|
||||
if [ "${ASSUME_YES}" = 1 ]; then
|
||||
/bin/echo -n "Enabling the SCL repository in 3 seconds... (Press Ctrl-C to cancel)"
|
||||
sleep 1s
|
||||
/bin/echo -ne "\e[0K\rEnabling the SCL repository in 2 seconds... (Press Ctrl-C to cancel)"
|
||||
sleep 1s
|
||||
/bin/echo -e "\e[0K\rEnabling the SCL repository in 1 second... (Press Ctrl-C to cancel)"
|
||||
sleep 1s
|
||||
fi
|
||||
if ! "${TOOL}" install "${YES_FLAG}" "${QUIET_FLAG}" centos-release-scl; then
|
||||
error "Could not enable SCL. Aborting bootstrap!"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# CentOS 6 must use rh-python36 from SCL
|
||||
if "${TOOL}" list rh-python36 >/dev/null 2>&1; then
|
||||
python_pkgs="rh-python36-python
|
||||
rh-python36-python-virtualenv
|
||||
rh-python36-python-devel
|
||||
"
|
||||
else
|
||||
error "No supported Python package available to install. Aborting bootstrap!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
BootstrapRpmCommonBase "${python_pkgs}"
|
||||
|
||||
# Enable SCL rh-python36 after bootstrapping.
|
||||
EnablePython36SCL
|
||||
}
|
||||
|
||||
# If new packages are installed by BootstrapRpmPython3 below, this version
|
||||
# number must be increased.
|
||||
BOOTSTRAP_RPM_PYTHON3_VERSION=1
|
||||
|
||||
BootstrapRpmPython3() {
|
||||
# Tested with:
|
||||
# - Fedora 29
|
||||
|
||||
InitializeRPMCommonBase
|
||||
|
||||
# Fedora 29 must use python3-virtualenv
|
||||
if $TOOL list python3-virtualenv >/dev/null 2>&1; then
|
||||
python_pkgs="python3
|
||||
python3-virtualenv
|
||||
python3-devel
|
||||
"
|
||||
else
|
||||
error "No supported Python package available to install. Aborting bootstrap!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
BootstrapRpmCommonBase "$python_pkgs"
|
||||
}
|
||||
|
||||
# If new packages are installed by BootstrapSuseCommon below, this version
|
||||
# number must be increased.
|
||||
BOOTSTRAP_SUSE_COMMON_VERSION=1
|
||||
|
||||
BootstrapSuseCommon() {
|
||||
# SLE12 don't have python-virtualenv
|
||||
|
||||
if [ "$ASSUME_YES" = 1 ]; then
|
||||
zypper_flags="-nq"
|
||||
install_flags="-l"
|
||||
fi
|
||||
|
||||
if [ "$QUIET" = 1 ]; then
|
||||
QUIET_FLAG='-qq'
|
||||
fi
|
||||
|
||||
if zypper search -x python-virtualenv >/dev/null 2>&1; then
|
||||
OPENSUSE_VIRTUALENV_PACKAGES="python-virtualenv"
|
||||
else
|
||||
# Since Leap 15.0 (and associated Tumbleweed version), python-virtualenv
|
||||
# is a source package, and python2-virtualenv must be used instead.
|
||||
# Also currently python2-setuptools is not a dependency of python2-virtualenv,
|
||||
# while it should be. Installing it explicitly until upstream fix.
|
||||
OPENSUSE_VIRTUALENV_PACKAGES="python2-virtualenv python2-setuptools"
|
||||
fi
|
||||
|
||||
zypper $QUIET_FLAG $zypper_flags in $install_flags \
|
||||
python \
|
||||
python-devel \
|
||||
$OPENSUSE_VIRTUALENV_PACKAGES \
|
||||
gcc \
|
||||
augeas-lenses \
|
||||
libopenssl-devel \
|
||||
libffi-devel \
|
||||
ca-certificates
|
||||
}
|
||||
|
||||
# If new packages are installed by BootstrapArchCommon below, this version
|
||||
# number must be increased.
|
||||
BOOTSTRAP_ARCH_COMMON_VERSION=1
|
||||
|
||||
BootstrapArchCommon() {
|
||||
# Tested with:
|
||||
# - ArchLinux (x86_64)
|
||||
#
|
||||
# "python-virtualenv" is Python3, but "python2-virtualenv" provides
|
||||
# only "virtualenv2" binary, not "virtualenv".
|
||||
|
||||
deps="
|
||||
python2
|
||||
python-virtualenv
|
||||
gcc
|
||||
augeas
|
||||
openssl
|
||||
libffi
|
||||
ca-certificates
|
||||
pkg-config
|
||||
"
|
||||
|
||||
# pacman -T exits with 127 if there are missing dependencies
|
||||
missing=$(pacman -T $deps) || true
|
||||
|
||||
if [ "$ASSUME_YES" = 1 ]; then
|
||||
noconfirm="--noconfirm"
|
||||
fi
|
||||
|
||||
if [ "$missing" ]; then
|
||||
if [ "$QUIET" = 1 ]; then
|
||||
pacman -S --needed $missing $noconfirm > /dev/null
|
||||
else
|
||||
pacman -S --needed $missing $noconfirm
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# If new packages are installed by BootstrapGentooCommon below, this version
|
||||
# number must be increased.
|
||||
BOOTSTRAP_GENTOO_COMMON_VERSION=1
|
||||
|
||||
BootstrapGentooCommon() {
|
||||
PACKAGES="
|
||||
dev-lang/python:2.7
|
||||
dev-python/virtualenv
|
||||
app-admin/augeas
|
||||
dev-libs/openssl
|
||||
dev-libs/libffi
|
||||
app-misc/ca-certificates
|
||||
virtual/pkgconfig"
|
||||
|
||||
ASK_OPTION="--ask"
|
||||
if [ "$ASSUME_YES" = 1 ]; then
|
||||
ASK_OPTION=""
|
||||
fi
|
||||
|
||||
case "$PACKAGE_MANAGER" in
|
||||
(paludis)
|
||||
cave resolve --preserve-world --keep-targets if-possible $PACKAGES -x
|
||||
;;
|
||||
(pkgcore)
|
||||
pmerge --noreplace --oneshot $ASK_OPTION $PACKAGES
|
||||
;;
|
||||
(portage|*)
|
||||
emerge --noreplace --oneshot $ASK_OPTION $PACKAGES
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# If new packages are installed by BootstrapFreeBsd below, this version number
|
||||
# must be increased.
|
||||
BOOTSTRAP_FREEBSD_VERSION=1
|
||||
|
||||
BootstrapFreeBsd() {
|
||||
if [ "$QUIET" = 1 ]; then
|
||||
QUIET_FLAG="--quiet"
|
||||
fi
|
||||
|
||||
pkg install -Ay $QUIET_FLAG \
|
||||
python \
|
||||
py27-virtualenv \
|
||||
augeas \
|
||||
libffi
|
||||
}
|
||||
|
||||
# If new packages are installed by BootstrapMac below, this version number must
|
||||
# be increased.
|
||||
BOOTSTRAP_MAC_VERSION=1
|
||||
|
||||
BootstrapMac() {
|
||||
if hash brew 2>/dev/null; then
|
||||
say "Using Homebrew to install dependencies..."
|
||||
pkgman=brew
|
||||
pkgcmd="brew install"
|
||||
elif hash port 2>/dev/null; then
|
||||
say "Using MacPorts to install dependencies..."
|
||||
pkgman=port
|
||||
pkgcmd="port install"
|
||||
else
|
||||
say "No Homebrew/MacPorts; installing Homebrew..."
|
||||
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
|
||||
pkgman=brew
|
||||
pkgcmd="brew install"
|
||||
fi
|
||||
|
||||
$pkgcmd augeas
|
||||
if [ "$(which python)" = "/System/Library/Frameworks/Python.framework/Versions/2.7/bin/python" \
|
||||
-o "$(which python)" = "/usr/bin/python" ]; then
|
||||
# We want to avoid using the system Python because it requires root to use pip.
|
||||
# python.org, MacPorts or HomeBrew Python installations should all be OK.
|
||||
say "Installing python..."
|
||||
$pkgcmd python
|
||||
fi
|
||||
|
||||
# Workaround for _dlopen not finding augeas on macOS
|
||||
if [ "$pkgman" = "port" ] && ! [ -e "/usr/local/lib/libaugeas.dylib" ] && [ -e "/opt/local/lib/libaugeas.dylib" ]; then
|
||||
say "Applying augeas workaround"
|
||||
mkdir -p /usr/local/lib/
|
||||
ln -s /opt/local/lib/libaugeas.dylib /usr/local/lib/
|
||||
fi
|
||||
|
||||
if ! hash pip 2>/dev/null; then
|
||||
say "pip not installed"
|
||||
say "Installing pip..."
|
||||
curl --silent --show-error --retry 5 https://bootstrap.pypa.io/get-pip.py | python
|
||||
fi
|
||||
|
||||
if ! hash virtualenv 2>/dev/null; then
|
||||
say "virtualenv not installed."
|
||||
say "Installing with pip..."
|
||||
pip install virtualenv
|
||||
fi
|
||||
}
|
||||
|
||||
# If new packages are installed by BootstrapSmartOS below, this version number
|
||||
# must be increased.
|
||||
BOOTSTRAP_SMARTOS_VERSION=1
|
||||
|
||||
BootstrapSmartOS() {
|
||||
pkgin update
|
||||
pkgin -y install 'gcc49' 'py27-augeas' 'py27-virtualenv'
|
||||
}
|
||||
|
||||
# If new packages are installed by BootstrapMageiaCommon below, this version
|
||||
# number must be increased.
|
||||
BOOTSTRAP_MAGEIA_COMMON_VERSION=1
|
||||
|
||||
BootstrapMageiaCommon() {
|
||||
if [ "$QUIET" = 1 ]; then
|
||||
QUIET_FLAG='--quiet'
|
||||
fi
|
||||
|
||||
if ! urpmi --force $QUIET_FLAG \
|
||||
python \
|
||||
libpython-devel \
|
||||
python-virtualenv
|
||||
then
|
||||
error "Could not install Python dependencies. Aborting bootstrap!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! urpmi --force $QUIET_FLAG \
|
||||
git \
|
||||
gcc \
|
||||
python-augeas \
|
||||
libopenssl-devel \
|
||||
libffi-devel \
|
||||
rootcerts
|
||||
then
|
||||
error "Could not install additional dependencies. Aborting bootstrap!"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
# Set Bootstrap to the function that installs OS dependencies on this system
|
||||
# and BOOTSTRAP_VERSION to the unique identifier for the current version of
|
||||
# that function. If Bootstrap is set to a function that doesn't install any
|
||||
# packages BOOTSTRAP_VERSION is not set.
|
||||
if [ -f /etc/debian_version ]; then
|
||||
Bootstrap() {
|
||||
BootstrapMessage "Debian-based OSes"
|
||||
BootstrapDebCommon
|
||||
}
|
||||
BOOTSTRAP_VERSION="BootstrapDebCommon $BOOTSTRAP_DEB_COMMON_VERSION"
|
||||
elif [ -f /etc/mageia-release ]; then
|
||||
# Mageia has both /etc/mageia-release and /etc/redhat-release
|
||||
DEPRECATED_OS=1
|
||||
elif [ -f /etc/redhat-release ]; then
|
||||
# Run DeterminePythonVersion to decide on the basis of available Python versions
|
||||
# whether to use 2.x or 3.x on RedHat-like systems.
|
||||
# Then, revert LE_PYTHON to its previous state.
|
||||
prev_le_python="$LE_PYTHON"
|
||||
unset LE_PYTHON
|
||||
DeterminePythonVersion "NOCRASH"
|
||||
|
||||
RPM_DIST_NAME=`(. /etc/os-release 2> /dev/null && echo $ID) || echo "unknown"`
|
||||
|
||||
if [ "$PYVER" -eq 26 -a $(uname -m) != 'x86_64' ]; then
|
||||
# 32 bits CentOS 6 and affiliates are not supported anymore by certbot-auto.
|
||||
DEPRECATED_OS=1
|
||||
fi
|
||||
|
||||
# Set RPM_DIST_VERSION to VERSION_ID from /etc/os-release after splitting on
|
||||
# '.' characters (e.g. "8.0" becomes "8"). If the command exits with an
|
||||
# error, RPM_DIST_VERSION is set to "unknown".
|
||||
RPM_DIST_VERSION=$( (. /etc/os-release 2> /dev/null && echo "$VERSION_ID") | cut -d '.' -f1 || echo "unknown")
|
||||
|
||||
# If RPM_DIST_VERSION is an empty string or it contains any nonnumeric
|
||||
# characters, the value is unexpected so we set RPM_DIST_VERSION to 0.
|
||||
if [ -z "$RPM_DIST_VERSION" ] || [ -n "$(echo "$RPM_DIST_VERSION" | tr -d '[0-9]')" ]; then
|
||||
RPM_DIST_VERSION=0
|
||||
fi
|
||||
|
||||
# Handle legacy RPM distributions
|
||||
if [ "$PYVER" -eq 26 ]; then
|
||||
# Check if an automated bootstrap can be achieved on this system.
|
||||
if ! Python36SclIsAvailable; then
|
||||
INTERACTIVE_BOOTSTRAP=1
|
||||
fi
|
||||
|
||||
Bootstrap() {
|
||||
BootstrapMessage "Legacy RedHat-based OSes that will use Python3"
|
||||
BootstrapRpmPython3Legacy
|
||||
}
|
||||
USE_PYTHON_3=1
|
||||
BOOTSTRAP_VERSION="BootstrapRpmPython3Legacy $BOOTSTRAP_RPM_PYTHON3_LEGACY_VERSION"
|
||||
|
||||
# Try now to enable SCL rh-python36 for systems already bootstrapped
|
||||
# NB: EnablePython36SCL has been defined along with BootstrapRpmPython3Legacy in certbot-auto
|
||||
EnablePython36SCL
|
||||
else
|
||||
# Starting to Fedora 29, python2 is on a deprecation path. Let's move to python3 then.
|
||||
# RHEL 8 also uses python3 by default.
|
||||
if [ "$RPM_DIST_NAME" = "fedora" -a "$RPM_DIST_VERSION" -ge 29 ]; then
|
||||
RPM_USE_PYTHON_3=1
|
||||
elif [ "$RPM_DIST_NAME" = "rhel" -a "$RPM_DIST_VERSION" -ge 8 ]; then
|
||||
RPM_USE_PYTHON_3=1
|
||||
elif [ "$RPM_DIST_NAME" = "centos" -a "$RPM_DIST_VERSION" -ge 8 ]; then
|
||||
RPM_USE_PYTHON_3=1
|
||||
else
|
||||
RPM_USE_PYTHON_3=0
|
||||
fi
|
||||
|
||||
if [ "$RPM_USE_PYTHON_3" = 1 ]; then
|
||||
Bootstrap() {
|
||||
BootstrapMessage "RedHat-based OSes that will use Python3"
|
||||
BootstrapRpmPython3
|
||||
}
|
||||
USE_PYTHON_3=1
|
||||
BOOTSTRAP_VERSION="BootstrapRpmPython3 $BOOTSTRAP_RPM_PYTHON3_VERSION"
|
||||
else
|
||||
Bootstrap() {
|
||||
BootstrapMessage "RedHat-based OSes"
|
||||
BootstrapRpmCommon
|
||||
}
|
||||
BOOTSTRAP_VERSION="BootstrapRpmCommon $BOOTSTRAP_RPM_COMMON_VERSION"
|
||||
fi
|
||||
fi
|
||||
|
||||
LE_PYTHON="$prev_le_python"
|
||||
elif [ -f /etc/os-release ] && `grep -q openSUSE /etc/os-release` ; then
|
||||
DEPRECATED_OS=1
|
||||
elif [ -f /etc/arch-release ]; then
|
||||
DEPRECATED_OS=1
|
||||
elif [ -f /etc/manjaro-release ]; then
|
||||
DEPRECATED_OS=1
|
||||
elif [ -f /etc/gentoo-release ]; then
|
||||
DEPRECATED_OS=1
|
||||
elif uname | grep -iq FreeBSD ; then
|
||||
DEPRECATED_OS=1
|
||||
elif uname | grep -iq Darwin ; then
|
||||
DEPRECATED_OS=1
|
||||
elif [ -f /etc/issue ] && grep -iq "Amazon Linux" /etc/issue ; then
|
||||
Bootstrap() {
|
||||
ExperimentalBootstrap "Amazon Linux" BootstrapRpmCommon
|
||||
}
|
||||
BOOTSTRAP_VERSION="BootstrapRpmCommon $BOOTSTRAP_RPM_COMMON_VERSION"
|
||||
elif [ -f /etc/product ] && grep -q "Joyent Instance" /etc/product ; then
|
||||
DEPRECATED_OS=1
|
||||
else
|
||||
DEPRECATED_OS=1
|
||||
fi
|
||||
|
||||
# We handle this case after determining the normal bootstrap version to allow
|
||||
# variables like USE_PYTHON_3 to be properly set. As described above, if the
|
||||
# Bootstrap function doesn't install any packages, BOOTSTRAP_VERSION should not
|
||||
# be set so we unset it here.
|
||||
if [ "$NO_BOOTSTRAP" = 1 ]; then
|
||||
Bootstrap() {
|
||||
:
|
||||
}
|
||||
unset BOOTSTRAP_VERSION
|
||||
fi
|
||||
|
||||
if [ "$DEPRECATED_OS" = 1 ]; then
|
||||
Bootstrap() {
|
||||
error "Skipping bootstrap because certbot-auto is deprecated on this system."
|
||||
}
|
||||
unset BOOTSTRAP_VERSION
|
||||
fi
|
||||
|
||||
# Sets PREV_BOOTSTRAP_VERSION to the identifier for the bootstrap script used
|
||||
# to install OS dependencies on this system. PREV_BOOTSTRAP_VERSION isn't set
|
||||
# if it is unknown how OS dependencies were installed on this system.
|
||||
SetPrevBootstrapVersion() {
|
||||
if [ -f $BOOTSTRAP_VERSION_PATH ]; then
|
||||
PREV_BOOTSTRAP_VERSION=$(cat "$BOOTSTRAP_VERSION_PATH")
|
||||
# The list below only contains bootstrap version strings that existed before
|
||||
# we started writing them to disk.
|
||||
#
|
||||
# DO NOT MODIFY THIS LIST UNLESS YOU KNOW WHAT YOU'RE DOING!
|
||||
elif grep -Fqx "$BOOTSTRAP_VERSION" << "UNLIKELY_EOF"
|
||||
BootstrapDebCommon 1
|
||||
BootstrapMageiaCommon 1
|
||||
BootstrapRpmCommon 1
|
||||
BootstrapSuseCommon 1
|
||||
BootstrapArchCommon 1
|
||||
BootstrapGentooCommon 1
|
||||
BootstrapFreeBsd 1
|
||||
BootstrapMac 1
|
||||
BootstrapSmartOS 1
|
||||
UNLIKELY_EOF
|
||||
then
|
||||
# If there's no bootstrap version saved to disk, but the currently selected
|
||||
# bootstrap script is from before we started saving the version number,
|
||||
# return the currently selected version to prevent us from rebootstrapping
|
||||
# unnecessarily.
|
||||
PREV_BOOTSTRAP_VERSION="$BOOTSTRAP_VERSION"
|
||||
fi
|
||||
}
|
||||
|
||||
TempDir() {
|
||||
mktemp -d 2>/dev/null || mktemp -d -t 'le' # Linux || macOS
|
||||
}
|
||||
|
||||
# Returns 0 if a letsencrypt installation exists at $OLD_VENV_PATH, otherwise,
|
||||
# returns a non-zero number.
|
||||
OldVenvExists() {
|
||||
[ -n "$OLD_VENV_PATH" -a -f "$OLD_VENV_PATH/bin/letsencrypt" ]
|
||||
}
|
||||
|
||||
# Given python path, version 1 and version 2, check if version 1 is outdated compared to version 2.
|
||||
# An unofficial version provided as version 1 (eg. 0.28.0.dev0) will be treated
|
||||
# specifically by printing "UNOFFICIAL". Otherwise, print "OUTDATED" if version 1
|
||||
# is outdated, and "UP_TO_DATE" if not.
|
||||
# This function relies only on installed python environment (2.x or 3.x) by certbot-auto.
|
||||
CompareVersions() {
|
||||
"$1" - "$2" "$3" << "UNLIKELY_EOF"
|
||||
import sys
|
||||
from distutils.version import StrictVersion
|
||||
|
||||
try:
|
||||
current = StrictVersion(sys.argv[1])
|
||||
except ValueError:
|
||||
sys.stdout.write('UNOFFICIAL')
|
||||
sys.exit()
|
||||
|
||||
try:
|
||||
remote = StrictVersion(sys.argv[2])
|
||||
except ValueError:
|
||||
sys.stdout.write('UP_TO_DATE')
|
||||
sys.exit()
|
||||
|
||||
if current < remote:
|
||||
sys.stdout.write('OUTDATED')
|
||||
else:
|
||||
sys.stdout.write('UP_TO_DATE')
|
||||
UNLIKELY_EOF
|
||||
}
|
||||
|
||||
# Create a new virtual environment for Certbot. It will overwrite any existing one.
|
||||
# Parameters: LE_PYTHON, VENV_PATH, PYVER, VERBOSE
|
||||
CreateVenv() {
|
||||
"$1" - "$2" "$3" "$4" << "UNLIKELY_EOF"
|
||||
#!/usr/bin/env python
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
|
||||
def create_venv(venv_path, pyver, verbose):
|
||||
if os.path.exists(venv_path):
|
||||
shutil.rmtree(venv_path)
|
||||
|
||||
stdout = sys.stdout if verbose == '1' else open(os.devnull, 'w')
|
||||
|
||||
if int(pyver) <= 27:
|
||||
# Use virtualenv binary
|
||||
environ = os.environ.copy()
|
||||
environ['VIRTUALENV_NO_DOWNLOAD'] = '1'
|
||||
command = ['virtualenv', '--no-site-packages', '--python', sys.executable, venv_path]
|
||||
subprocess.check_call(command, stdout=stdout, env=environ)
|
||||
else:
|
||||
# Use embedded venv module in Python 3
|
||||
command = [sys.executable, '-m', 'venv', venv_path]
|
||||
subprocess.check_call(command, stdout=stdout)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
create_venv(*sys.argv[1:])
|
||||
|
||||
UNLIKELY_EOF
|
||||
}
|
||||
|
||||
# Check that the given PATH_TO_CHECK has secured permissions.
|
||||
# Parameters: LE_PYTHON, PATH_TO_CHECK
|
||||
CheckPathPermissions() {
|
||||
"$1" - "$2" << "UNLIKELY_EOF"
|
||||
"""Verifies certbot-auto cannot be modified by unprivileged users.
|
||||
|
||||
This script takes the path to certbot-auto as its only command line
|
||||
argument. It then checks that the file can only be modified by uid/gid
|
||||
< 1000 and if other users can modify the file, it prints a warning with
|
||||
a suggestion on how to solve the problem.
|
||||
|
||||
Permissions on symlinks in the absolute path of certbot-auto are ignored
|
||||
and only the canonical path to certbot-auto is checked. There could be
|
||||
permissions problems due to the symlinks that are unreported by this
|
||||
script, however, issues like this were not caused by our documentation
|
||||
and are ignored for the sake of simplicity.
|
||||
|
||||
All warnings are printed to stdout rather than stderr so all stderr
|
||||
output from this script can be suppressed to avoid printing messages if
|
||||
this script fails for some reason.
|
||||
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
import os
|
||||
import stat
|
||||
import sys
|
||||
|
||||
|
||||
FORUM_POST_URL = 'https://community.letsencrypt.org/t/certbot-auto-deployment-best-practices/91979/'
|
||||
|
||||
|
||||
def has_safe_permissions(path):
|
||||
"""Returns True if the given path has secure permissions.
|
||||
|
||||
The permissions are considered safe if the file is only writable by
|
||||
uid/gid < 1000.
|
||||
|
||||
The reason we allow more IDs than 0 is because on some systems such
|
||||
as Debian, system users/groups other than uid/gid 0 are used for the
|
||||
path we recommend in our instructions which is /usr/local/bin. 1000
|
||||
was chosen because on Debian 0-999 is reserved for system IDs[1] and
|
||||
on RHEL either 0-499 or 0-999 is reserved depending on the
|
||||
version[2][3]. Due to these differences across different OSes, this
|
||||
detection isn't perfect so we only determine permissions are
|
||||
insecure when we can be reasonably confident there is a problem
|
||||
regardless of the underlying OS.
|
||||
|
||||
[1] https://www.debian.org/doc/debian-policy/ch-opersys.html#uid-and-gid-classes
|
||||
[2] https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/deployment_guide/ch-managing_users_and_groups
|
||||
[3] https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/system_administrators_guide/ch-managing_users_and_groups
|
||||
|
||||
:param str path: filesystem path to check
|
||||
:returns: True if the path has secure permissions, otherwise, False
|
||||
:rtype: bool
|
||||
|
||||
"""
|
||||
# os.stat follows symlinks before obtaining information about a file.
|
||||
stat_result = os.stat(path)
|
||||
if stat_result.st_mode & stat.S_IWOTH:
|
||||
return False
|
||||
if stat_result.st_mode & stat.S_IWGRP and stat_result.st_gid >= 1000:
|
||||
return False
|
||||
if stat_result.st_mode & stat.S_IWUSR and stat_result.st_uid >= 1000:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def main(certbot_auto_path):
|
||||
current_path = os.path.realpath(certbot_auto_path)
|
||||
last_path = None
|
||||
permissions_ok = True
|
||||
# This loop makes use of the fact that os.path.dirname('/') == '/'.
|
||||
while current_path != last_path and permissions_ok:
|
||||
permissions_ok = has_safe_permissions(current_path)
|
||||
last_path = current_path
|
||||
current_path = os.path.dirname(current_path)
|
||||
|
||||
if not permissions_ok:
|
||||
print('{0} has insecure permissions!'.format(certbot_auto_path))
|
||||
print('To learn how to fix them, visit {0}'.format(FORUM_POST_URL))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(sys.argv[1])
|
||||
|
||||
UNLIKELY_EOF
|
||||
}
|
||||
|
||||
if [ "$1" = "--le-auto-phase2" ]; then
|
||||
# Phase 2: Create venv, install LE, and run.
|
||||
|
||||
shift 1 # the --le-auto-phase2 arg
|
||||
|
||||
if [ "$DEPRECATED_OS" = 1 ]; then
|
||||
# Phase 2 damage control mode for deprecated OSes.
|
||||
# In this situation, we bypass any bootstrap or certbot venv setup.
|
||||
error "Your system is not supported by certbot-auto anymore."
|
||||
|
||||
if [ ! -d "$VENV_PATH" ] && OldVenvExists; then
|
||||
VENV_BIN="$OLD_VENV_PATH/bin"
|
||||
fi
|
||||
|
||||
if [ -f "$VENV_BIN/letsencrypt" -a "$INSTALL_ONLY" != 1 ]; then
|
||||
error "Certbot will no longer receive updates."
|
||||
error "Please visit https://certbot.eff.org/ to check for other alternatives."
|
||||
"$VENV_BIN/letsencrypt" "$@"
|
||||
exit 0
|
||||
else
|
||||
error "Certbot cannot be installed."
|
||||
error "Please visit https://certbot.eff.org/ to check for other alternatives."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
SetPrevBootstrapVersion
|
||||
|
||||
if [ -z "$PHASE_1_VERSION" -a "$USE_PYTHON_3" = 1 ]; then
|
||||
unset LE_PYTHON
|
||||
fi
|
||||
|
||||
INSTALLED_VERSION="none"
|
||||
if [ -d "$VENV_PATH" ] || OldVenvExists; then
|
||||
# If the selected Bootstrap function isn't a noop and it differs from the
|
||||
# previously used version
|
||||
if [ -n "$BOOTSTRAP_VERSION" -a "$BOOTSTRAP_VERSION" != "$PREV_BOOTSTRAP_VERSION" ]; then
|
||||
# Check if we can rebootstrap without manual user intervention: this requires that
|
||||
# certbot-auto is in non-interactive mode AND selected bootstrap does not claim to
|
||||
# require a manual user intervention.
|
||||
if [ "$NONINTERACTIVE" = 1 -a "$INTERACTIVE_BOOTSTRAP" != 1 ]; then
|
||||
CAN_REBOOTSTRAP=1
|
||||
fi
|
||||
# Check if rebootstrap can be done non-interactively and current shell is non-interactive
|
||||
# (true if stdin and stdout are not attached to a terminal).
|
||||
if [ \( "$CAN_REBOOTSTRAP" = 1 \) -o \( \( -t 0 \) -a \( -t 1 \) \) ]; then
|
||||
if [ -d "$VENV_PATH" ]; then
|
||||
rm -rf "$VENV_PATH"
|
||||
fi
|
||||
# In the case the old venv was just a symlink to the new one,
|
||||
# OldVenvExists is now false because we deleted the venv at VENV_PATH.
|
||||
if OldVenvExists; then
|
||||
rm -rf "$OLD_VENV_PATH"
|
||||
ln -s "$VENV_PATH" "$OLD_VENV_PATH"
|
||||
fi
|
||||
RerunWithArgs "$@"
|
||||
# Otherwise bootstrap needs to be done manually by the user.
|
||||
else
|
||||
# If it is because bootstrapping is interactive, --non-interactive will be of no use.
|
||||
if [ "$INTERACTIVE_BOOTSTRAP" = 1 ]; then
|
||||
error "Skipping upgrade because new OS dependencies may need to be installed."
|
||||
error "This requires manual user intervention: please run this script again manually."
|
||||
# If this is because of the environment (eg. non interactive shell without
|
||||
# --non-interactive flag set), help the user in that direction.
|
||||
else
|
||||
error "Skipping upgrade because new OS dependencies may need to be installed."
|
||||
error
|
||||
error "To upgrade to a newer version, please run this script again manually so you can"
|
||||
error "approve changes or with --non-interactive on the command line to automatically"
|
||||
error "install any required packages."
|
||||
fi
|
||||
# Set INSTALLED_VERSION to be the same so we don't update the venv
|
||||
INSTALLED_VERSION="$LE_AUTO_VERSION"
|
||||
# Continue to use OLD_VENV_PATH if the new venv doesn't exist
|
||||
if [ ! -d "$VENV_PATH" ]; then
|
||||
VENV_BIN="$OLD_VENV_PATH/bin"
|
||||
fi
|
||||
fi
|
||||
elif [ -f "$VENV_BIN/letsencrypt" ]; then
|
||||
# --version output ran through grep due to python-cryptography DeprecationWarnings
|
||||
# grep for both certbot and letsencrypt until certbot and shim packages have been released
|
||||
INSTALLED_VERSION=$("$VENV_BIN/letsencrypt" --version 2>&1 | grep "^certbot\|^letsencrypt" | cut -d " " -f 2)
|
||||
if [ -z "$INSTALLED_VERSION" ]; then
|
||||
error "Error: couldn't get currently installed version for $VENV_BIN/letsencrypt: " 1>&2
|
||||
"$VENV_BIN/letsencrypt" --version
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$LE_AUTO_VERSION" != "$INSTALLED_VERSION" ]; then
|
||||
say "Creating virtual environment..."
|
||||
DeterminePythonVersion
|
||||
CreateVenv "$LE_PYTHON" "$VENV_PATH" "$PYVER" "$VERBOSE"
|
||||
|
||||
if [ -n "$BOOTSTRAP_VERSION" ]; then
|
||||
echo "$BOOTSTRAP_VERSION" > "$BOOTSTRAP_VERSION_PATH"
|
||||
elif [ -n "$PREV_BOOTSTRAP_VERSION" ]; then
|
||||
echo "$PREV_BOOTSTRAP_VERSION" > "$BOOTSTRAP_VERSION_PATH"
|
||||
fi
|
||||
|
||||
say "Installing Python packages..."
|
||||
TEMP_DIR=$(TempDir)
|
||||
trap 'rm -rf "$TEMP_DIR"' EXIT
|
||||
# There is no $ interpolation due to quotes on starting heredoc delimiter.
|
||||
# -------------------------------------------------------------------------
|
||||
cat << "UNLIKELY_EOF" > "$TEMP_DIR/letsencrypt-auto-requirements.txt"
|
||||
# This is the flattened list of packages certbot-auto installs.
|
||||
# To generate this, do (with docker and package hashin installed):
|
||||
# ```
|
||||
# letsencrypt-auto-source/rebuild_dependencies.py \
|
||||
# letsencrypt-auto-source/pieces/dependency-requirements.txt
|
||||
# ```
|
||||
# If you want to update a single dependency, run commands similar to these:
|
||||
# ```
|
||||
# pip install hashin
|
||||
# hashin -r dependency-requirements.txt cryptography==1.5.2
|
||||
# ```
|
||||
ConfigArgParse==1.2.3 \
|
||||
--hash=sha256:edd17be986d5c1ba2e307150b8e5f5107aba125f3574dddd02c85d5cdcfd37dc
|
||||
certifi==2020.4.5.1 \
|
||||
--hash=sha256:1d987a998c75633c40847cc966fcf5904906c920a7f17ef374f5aa4282abd304 \
|
||||
--hash=sha256:51fcb31174be6e6664c5f69e3e1691a2d72a1a12e90f872cbdb1567eb47b6519
|
||||
cffi==1.14.0 \
|
||||
--hash=sha256:001bf3242a1bb04d985d63e138230802c6c8d4db3668fb545fb5005ddf5bb5ff \
|
||||
--hash=sha256:00789914be39dffba161cfc5be31b55775de5ba2235fe49aa28c148236c4e06b \
|
||||
--hash=sha256:028a579fc9aed3af38f4892bdcc7390508adabc30c6af4a6e4f611b0c680e6ac \
|
||||
--hash=sha256:14491a910663bf9f13ddf2bc8f60562d6bc5315c1f09c704937ef17293fb85b0 \
|
||||
--hash=sha256:1cae98a7054b5c9391eb3249b86e0e99ab1e02bb0cc0575da191aedadbdf4384 \
|
||||
--hash=sha256:2089ed025da3919d2e75a4d963d008330c96751127dd6f73c8dc0c65041b4c26 \
|
||||
--hash=sha256:2d384f4a127a15ba701207f7639d94106693b6cd64173d6c8988e2c25f3ac2b6 \
|
||||
--hash=sha256:337d448e5a725bba2d8293c48d9353fc68d0e9e4088d62a9571def317797522b \
|
||||
--hash=sha256:399aed636c7d3749bbed55bc907c3288cb43c65c4389964ad5ff849b6370603e \
|
||||
--hash=sha256:3b911c2dbd4f423b4c4fcca138cadde747abdb20d196c4a48708b8a2d32b16dd \
|
||||
--hash=sha256:3d311bcc4a41408cf5854f06ef2c5cab88f9fded37a3b95936c9879c1640d4c2 \
|
||||
--hash=sha256:62ae9af2d069ea2698bf536dcfe1e4eed9090211dbaafeeedf5cb6c41b352f66 \
|
||||
--hash=sha256:66e41db66b47d0d8672d8ed2708ba91b2f2524ece3dee48b5dfb36be8c2f21dc \
|
||||
--hash=sha256:675686925a9fb403edba0114db74e741d8181683dcf216be697d208857e04ca8 \
|
||||
--hash=sha256:7e63cbcf2429a8dbfe48dcc2322d5f2220b77b2e17b7ba023d6166d84655da55 \
|
||||
--hash=sha256:8a6c688fefb4e1cd56feb6c511984a6c4f7ec7d2a1ff31a10254f3c817054ae4 \
|
||||
--hash=sha256:8c0ffc886aea5df6a1762d0019e9cb05f825d0eec1f520c51be9d198701daee5 \
|
||||
--hash=sha256:95cd16d3dee553f882540c1ffe331d085c9e629499ceadfbda4d4fde635f4b7d \
|
||||
--hash=sha256:99f748a7e71ff382613b4e1acc0ac83bf7ad167fb3802e35e90d9763daba4d78 \
|
||||
--hash=sha256:b8c78301cefcf5fd914aad35d3c04c2b21ce8629b5e4f4e45ae6812e461910fa \
|
||||
--hash=sha256:c420917b188a5582a56d8b93bdd8e0f6eca08c84ff623a4c16e809152cd35793 \
|
||||
--hash=sha256:c43866529f2f06fe0edc6246eb4faa34f03fe88b64a0a9a942561c8e22f4b71f \
|
||||
--hash=sha256:cab50b8c2250b46fe738c77dbd25ce017d5e6fb35d3407606e7a4180656a5a6a \
|
||||
--hash=sha256:cef128cb4d5e0b3493f058f10ce32365972c554572ff821e175dbc6f8ff6924f \
|
||||
--hash=sha256:cf16e3cf6c0a5fdd9bc10c21687e19d29ad1fe863372b5543deaec1039581a30 \
|
||||
--hash=sha256:e56c744aa6ff427a607763346e4170629caf7e48ead6921745986db3692f987f \
|
||||
--hash=sha256:e577934fc5f8779c554639376beeaa5657d54349096ef24abe8c74c5d9c117c3 \
|
||||
--hash=sha256:f2b0fa0c01d8a0c7483afd9f31d7ecf2d71760ca24499c8697aeb5ca37dc090c
|
||||
chardet==3.0.4 \
|
||||
--hash=sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae \
|
||||
--hash=sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691
|
||||
configobj==5.0.6 \
|
||||
--hash=sha256:a2f5650770e1c87fb335af19a9b7eb73fc05ccf22144eb68db7d00cd2bcb0902
|
||||
cryptography==2.8 \
|
||||
--hash=sha256:02079a6addc7b5140ba0825f542c0869ff4df9a69c360e339ecead5baefa843c \
|
||||
--hash=sha256:1df22371fbf2004c6f64e927668734070a8953362cd8370ddd336774d6743595 \
|
||||
--hash=sha256:369d2346db5934345787451504853ad9d342d7f721ae82d098083e1f49a582ad \
|
||||
--hash=sha256:3cda1f0ed8747339bbdf71b9f38ca74c7b592f24f65cdb3ab3765e4b02871651 \
|
||||
--hash=sha256:44ff04138935882fef7c686878e1c8fd80a723161ad6a98da31e14b7553170c2 \
|
||||
--hash=sha256:4b1030728872c59687badcca1e225a9103440e467c17d6d1730ab3d2d64bfeff \
|
||||
--hash=sha256:58363dbd966afb4f89b3b11dfb8ff200058fbc3b947507675c19ceb46104b48d \
|
||||
--hash=sha256:6ec280fb24d27e3d97aa731e16207d58bd8ae94ef6eab97249a2afe4ba643d42 \
|
||||
--hash=sha256:7270a6c29199adc1297776937a05b59720e8a782531f1f122f2eb8467f9aab4d \
|
||||
--hash=sha256:73fd30c57fa2d0a1d7a49c561c40c2f79c7d6c374cc7750e9ac7c99176f6428e \
|
||||
--hash=sha256:7f09806ed4fbea8f51585231ba742b58cbcfbfe823ea197d8c89a5e433c7e912 \
|
||||
--hash=sha256:90df0cc93e1f8d2fba8365fb59a858f51a11a394d64dbf3ef844f783844cc793 \
|
||||
--hash=sha256:971221ed40f058f5662a604bd1ae6e4521d84e6cad0b7b170564cc34169c8f13 \
|
||||
--hash=sha256:a518c153a2b5ed6b8cc03f7ae79d5ffad7315ad4569b2d5333a13c38d64bd8d7 \
|
||||
--hash=sha256:b0de590a8b0979649ebeef8bb9f54394d3a41f66c5584fff4220901739b6b2f0 \
|
||||
--hash=sha256:b43f53f29816ba1db8525f006fa6f49292e9b029554b3eb56a189a70f2a40879 \
|
||||
--hash=sha256:d31402aad60ed889c7e57934a03477b572a03af7794fa8fb1780f21ea8f6551f \
|
||||
--hash=sha256:de96157ec73458a7f14e3d26f17f8128c959084931e8997b9e655a39c8fde9f9 \
|
||||
--hash=sha256:df6b4dca2e11865e6cfbfb708e800efb18370f5a46fd601d3755bc7f85b3a8a2 \
|
||||
--hash=sha256:ecadccc7ba52193963c0475ac9f6fa28ac01e01349a2ca48509667ef41ffd2cf \
|
||||
--hash=sha256:fb81c17e0ebe3358486cd8cc3ad78adbae58af12fc2bf2bc0bb84e8090fa5ce8
|
||||
distro==1.5.0 \
|
||||
--hash=sha256:0e58756ae38fbd8fc3020d54badb8eae17c5b9dcbed388b17bb55b8a5928df92 \
|
||||
--hash=sha256:df74eed763e18d10d0da624258524ae80486432cd17392d9c3d96f5e83cd2799
|
||||
enum34==1.1.10; python_version < '3.4' \
|
||||
--hash=sha256:a98a201d6de3f2ab3db284e70a33b0f896fbf35f8086594e8c9e74b909058d53 \
|
||||
--hash=sha256:c3858660960c984d6ab0ebad691265180da2b43f07e061c0f8dca9ef3cffd328 \
|
||||
--hash=sha256:cce6a7477ed816bd2542d03d53db9f0db935dd013b70f336a95c73979289f248
|
||||
funcsigs==1.0.2 \
|
||||
--hash=sha256:330cc27ccbf7f1e992e69fef78261dc7c6569012cf397db8d3de0234e6c937ca \
|
||||
--hash=sha256:a7bb0f2cf3a3fd1ab2732cb49eba4252c2af4240442415b4abce3b87022a8f50
|
||||
idna==2.9 \
|
||||
--hash=sha256:7588d1c14ae4c77d74036e8c22ff447b26d0fde8f007354fd48a7814db15b7cb \
|
||||
--hash=sha256:a068a21ceac8a4d63dbfd964670474107f541babbd2250d61922f029858365fa
|
||||
ipaddress==1.0.23 \
|
||||
--hash=sha256:6e0f4a39e66cb5bb9a137b00276a2eff74f93b71dcbdad6f10ff7df9d3557fcc \
|
||||
--hash=sha256:b7f8e0369580bb4a24d5ba1d7cc29660a4a6987763faf1d8a8046830e020e7e2
|
||||
josepy==1.3.0 \
|
||||
--hash=sha256:c341ffa403399b18e9eae9012f804843045764d1390f9cb4648980a7569b1619 \
|
||||
--hash=sha256:e54882c64be12a2a76533f73d33cba9e331950fda9e2731e843490b774e7a01c
|
||||
mock==1.3.0 \
|
||||
--hash=sha256:1e247dbecc6ce057299eb7ee019ad68314bb93152e81d9a6110d35f4d5eca0f6 \
|
||||
--hash=sha256:3f573a18be94de886d1191f27c168427ef693e8dcfcecf95b170577b2eb69cbb
|
||||
parsedatetime==2.5 \
|
||||
--hash=sha256:3b835fc54e472c17ef447be37458b400e3fefdf14bb1ffdedb5d2c853acf4ba1 \
|
||||
--hash=sha256:d2e9ddb1e463de871d32088a3f3cea3dc8282b1b2800e081bd0ef86900451667
|
||||
pbr==5.4.5 \
|
||||
--hash=sha256:07f558fece33b05caf857474a366dfcc00562bca13dd8b47b2b3e22d9f9bf55c \
|
||||
--hash=sha256:579170e23f8e0c2f24b0de612f71f648eccb79fb1322c814ae6b3c07b5ba23e8
|
||||
pyOpenSSL==19.1.0 \
|
||||
--hash=sha256:621880965a720b8ece2f1b2f54ea2071966ab00e2970ad2ce11d596102063504 \
|
||||
--hash=sha256:9a24494b2602aaf402be5c9e30a0b82d4a5c67528fe8fb475e3f3bc00dd69507
|
||||
pyRFC3339==1.1 \
|
||||
--hash=sha256:67196cb83b470709c580bb4738b83165e67c6cc60e1f2e4f286cfcb402a926f4 \
|
||||
--hash=sha256:81b8cbe1519cdb79bed04910dd6fa4e181faf8c88dff1e1b987b5f7ab23a5b1a
|
||||
pycparser==2.20 \
|
||||
--hash=sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0 \
|
||||
--hash=sha256:7582ad22678f0fcd81102833f60ef8d0e57288b6b5fb00323d101be910e35705
|
||||
pyparsing==2.4.7 \
|
||||
--hash=sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1 \
|
||||
--hash=sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b
|
||||
python-augeas==0.5.0 \
|
||||
--hash=sha256:67d59d66cdba8d624e0389b87b2a83a176f21f16a87553b50f5703b23f29bac2
|
||||
pytz==2020.1 \
|
||||
--hash=sha256:a494d53b6d39c3c6e44c3bec237336e14305e4f29bbf800b599253057fbb79ed \
|
||||
--hash=sha256:c35965d010ce31b23eeb663ed3cc8c906275d6be1a34393a1d73a41febf4a048
|
||||
requests==2.23.0 \
|
||||
--hash=sha256:43999036bfa82904b6af1d99e4882b560e5e2c68e5c4b0aa03b655f3d7d73fee \
|
||||
--hash=sha256:b3f43d496c6daba4493e7c431722aeb7dbc6288f52a6e04e7b6023b0247817e6
|
||||
requests-toolbelt==0.9.1 \
|
||||
--hash=sha256:380606e1d10dc85c3bd47bf5a6095f815ec007be7a8b69c878507068df059e6f \
|
||||
--hash=sha256:968089d4584ad4ad7c171454f0a5c6dac23971e9472521ea3b6d49d610aa6fc0
|
||||
six==1.15.0 \
|
||||
--hash=sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259 \
|
||||
--hash=sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced
|
||||
urllib3==1.25.9 \
|
||||
--hash=sha256:3018294ebefce6572a474f0604c2021e33b3fd8006ecd11d62107a5d2a963527 \
|
||||
--hash=sha256:88206b0eb87e6d677d424843ac5209e3fb9d0190d0ee169599165ec25e9d9115
|
||||
zope.component==4.6.1 \
|
||||
--hash=sha256:bfbe55d4a93e70a78b10edc3aad4de31bb8860919b7cbd8d66f717f7d7b279ac \
|
||||
--hash=sha256:d9c7c27673d787faff8a83797ce34d6ebcae26a370e25bddb465ac2182766aca
|
||||
zope.deferredimport==4.3.1 \
|
||||
--hash=sha256:57b2345e7b5eef47efcd4f634ff16c93e4265de3dcf325afc7315ade48d909e1 \
|
||||
--hash=sha256:9a0c211df44aa95f1c4e6d2626f90b400f56989180d3ef96032d708da3d23e0a
|
||||
zope.deprecation==4.4.0 \
|
||||
--hash=sha256:0d453338f04bacf91bbfba545d8bcdf529aa829e67b705eac8c1a7fdce66e2df \
|
||||
--hash=sha256:f1480b74995958b24ce37b0ef04d3663d2683e5d6debc96726eff18acf4ea113
|
||||
zope.event==4.4 \
|
||||
--hash=sha256:69c27debad9bdacd9ce9b735dad382142281ac770c4a432b533d6d65c4614bcf \
|
||||
--hash=sha256:d8e97d165fd5a0997b45f5303ae11ea3338becfe68c401dd88ffd2113fe5cae7
|
||||
zope.hookable==5.0.1 \
|
||||
--hash=sha256:0194b9b9e7f614abba60c90b231908861036578297515d3d6508eb10190f266d \
|
||||
--hash=sha256:0c2977473918bdefc6fa8dfb311f154e7f13c6133957fe649704deca79b92093 \
|
||||
--hash=sha256:17b8bdb3b77e03a152ca0d5ca185a7ae0156f5e5a2dbddf538676633a1f7380f \
|
||||
--hash=sha256:29d07681a78042cdd15b268ae9decffed9ace68a53eebeb61d65ae931d158841 \
|
||||
--hash=sha256:36fb1b35d1150267cb0543a1ddd950c0bc2c75ed0e6e92e3aaa6ac2e29416cb7 \
|
||||
--hash=sha256:3aed60c2bb5e812bbf9295c70f25b17ac37c233f30447a96c67913ba5073642f \
|
||||
--hash=sha256:3cac1565cc768911e72ca9ec4ddf5c5109e1fef0104f19f06649cf1874943b60 \
|
||||
--hash=sha256:3d4bc0cc4a37c3cd3081063142eeb2125511db3c13f6dc932d899c512690378e \
|
||||
--hash=sha256:3f73096f27b8c28be53ffb6604f7b570fbbb82f273c6febe5f58119009b59898 \
|
||||
--hash=sha256:522d1153d93f2d48aa0bd9fb778d8d4500be2e4dcf86c3150768f0e3adbbc4ef \
|
||||
--hash=sha256:523d2928fb7377bbdbc9af9c0b14ad73e6eaf226349f105733bdae27efd15b5a \
|
||||
--hash=sha256:5848309d4fc5c02150a45e8f8d2227e5bfda386a508bbd3160fed7c633c5a2fa \
|
||||
--hash=sha256:6781f86e6d54a110980a76e761eb54590630fd2af2a17d7edf02a079d2646c1d \
|
||||
--hash=sha256:6fd27921ebf3aaa945fa25d790f1f2046204f24dba4946f82f5f0a442577c3e9 \
|
||||
--hash=sha256:70d581862863f6bf9e175e85c9d70c2d7155f53fb04dcdb2f73cf288ca559a53 \
|
||||
--hash=sha256:81867c23b0dc66c8366f351d00923f2bc5902820a24c2534dfd7bf01a5879963 \
|
||||
--hash=sha256:81db29edadcbb740cd2716c95a297893a546ed89db1bfe9110168732d7f0afdd \
|
||||
--hash=sha256:86bd12624068cea60860a0759af5e2c3adc89c12aef6f71cf12f577e28deefe3 \
|
||||
--hash=sha256:9c184d8f9f7a76e1ced99855ccf390ffdd0ec3765e5cbf7b9cada600accc0a1e \
|
||||
--hash=sha256:acc789e8c29c13555e43fe4bf9fcd15a65512c9645e97bbaa5602e3201252b02 \
|
||||
--hash=sha256:afaa740206b7660d4cc3b8f120426c85761f51379af7a5b05451f624ad12b0af \
|
||||
--hash=sha256:b5f5fa323f878bb16eae68ea1ba7f6c0419d4695d0248bed4b18f51d7ce5ab85 \
|
||||
--hash=sha256:bd89e0e2c67bf4ac3aca2a19702b1a37269fb1923827f68324ac2e7afd6e3406 \
|
||||
--hash=sha256:c212de743283ec0735db24ec6ad913758df3af1b7217550ff270038062afd6ae \
|
||||
--hash=sha256:ca553f524293a0bdea05e7f44c3e685e4b7b022cb37d87bc4a3efa0f86587a8d \
|
||||
--hash=sha256:cab67065a3db92f636128d3157cc5424a145f82d96fb47159c539132833a6d36 \
|
||||
--hash=sha256:d3b3b3eedfdbf6b02898216e85aa6baf50207f4378a2a6803d6d47650cd37031 \
|
||||
--hash=sha256:d9f4a5a72f40256b686d31c5c0b1fde503172307beb12c1568296e76118e402c \
|
||||
--hash=sha256:df5067d87aaa111ed5d050e1ee853ba284969497f91806efd42425f5348f1c06 \
|
||||
--hash=sha256:e2587644812c6138f05b8a41594a8337c6790e3baf9a01915e52438c13fc6bef \
|
||||
--hash=sha256:e27fd877662db94f897f3fd532ef211ca4901eb1a70ba456f15c0866a985464a \
|
||||
--hash=sha256:e427ebbdd223c72e06ba94c004bb04e996c84dec8a0fa84e837556ae145c439e \
|
||||
--hash=sha256:e583ad4309c203ef75a09d43434cf9c2b4fa247997ecb0dcad769982c39411c7 \
|
||||
--hash=sha256:e760b2bc8ece9200804f0c2b64d10147ecaf18455a2a90827fbec4c9d84f3ad5 \
|
||||
--hash=sha256:ea9a9cc8bcc70e18023f30fa2f53d11ae069572a162791224e60cd65df55fb69 \
|
||||
--hash=sha256:ecb3f17dce4803c1099bd21742cd126b59817a4e76a6544d31d2cca6e30dbffd \
|
||||
--hash=sha256:ed794e3b3de42486d30444fb60b5561e724ee8a2d1b17b0c2e0f81e3ddaf7a87 \
|
||||
--hash=sha256:ee885d347279e38226d0a437b6a932f207f691c502ee565aba27a7022f1285df \
|
||||
--hash=sha256:fd5e7bc5f24f7e3d490698f7b854659a9851da2187414617cd5ed360af7efd63 \
|
||||
--hash=sha256:fe45f6870f7588ac7b2763ff1ce98cce59369717afe70cc353ec5218bc854bcc
|
||||
zope.interface==5.1.0 \
|
||||
--hash=sha256:0103cba5ed09f27d2e3de7e48bb320338592e2fabc5ce1432cf33808eb2dfd8b \
|
||||
--hash=sha256:14415d6979356629f1c386c8c4249b4d0082f2ea7f75871ebad2e29584bd16c5 \
|
||||
--hash=sha256:1ae4693ccee94c6e0c88a4568fb3b34af8871c60f5ba30cf9f94977ed0e53ddd \
|
||||
--hash=sha256:1b87ed2dc05cb835138f6a6e3595593fea3564d712cb2eb2de963a41fd35758c \
|
||||
--hash=sha256:269b27f60bcf45438e8683269f8ecd1235fa13e5411de93dae3b9ee4fe7f7bc7 \
|
||||
--hash=sha256:27d287e61639d692563d9dab76bafe071fbeb26818dd6a32a0022f3f7ca884b5 \
|
||||
--hash=sha256:39106649c3082972106f930766ae23d1464a73b7d30b3698c986f74bf1256a34 \
|
||||
--hash=sha256:40e4c42bd27ed3c11b2c983fecfb03356fae1209de10686d03c02c8696a1d90e \
|
||||
--hash=sha256:461d4339b3b8f3335d7e2c90ce335eb275488c587b61aca4b305196dde2ff086 \
|
||||
--hash=sha256:4f98f70328bc788c86a6a1a8a14b0ea979f81ae6015dd6c72978f1feff70ecda \
|
||||
--hash=sha256:558a20a0845d1a5dc6ff87cd0f63d7dac982d7c3be05d2ffb6322a87c17fa286 \
|
||||
--hash=sha256:562dccd37acec149458c1791da459f130c6cf8902c94c93b8d47c6337b9fb826 \
|
||||
--hash=sha256:5e86c66a6dea8ab6152e83b0facc856dc4d435fe0f872f01d66ce0a2131b7f1d \
|
||||
--hash=sha256:60a207efcd8c11d6bbeb7862e33418fba4e4ad79846d88d160d7231fcb42a5ee \
|
||||
--hash=sha256:645a7092b77fdbc3f68d3cc98f9d3e71510e419f54019d6e282328c0dd140dcd \
|
||||
--hash=sha256:6874367586c020705a44eecdad5d6b587c64b892e34305bb6ed87c9bbe22a5e9 \
|
||||
--hash=sha256:74bf0a4f9091131de09286f9a605db449840e313753949fe07c8d0fe7659ad1e \
|
||||
--hash=sha256:7b726194f938791a6691c7592c8b9e805fc6d1b9632a833b9c0640828cd49cbc \
|
||||
--hash=sha256:8149ded7f90154fdc1a40e0c8975df58041a6f693b8f7edcd9348484e9dc17fe \
|
||||
--hash=sha256:8cccf7057c7d19064a9e27660f5aec4e5c4001ffcf653a47531bde19b5aa2a8a \
|
||||
--hash=sha256:911714b08b63d155f9c948da2b5534b223a1a4fc50bb67139ab68b277c938578 \
|
||||
--hash=sha256:a5f8f85986197d1dd6444763c4a15c991bfed86d835a1f6f7d476f7198d5f56a \
|
||||
--hash=sha256:a744132d0abaa854d1aad50ba9bc64e79c6f835b3e92521db4235a1991176813 \
|
||||
--hash=sha256:af2c14efc0bb0e91af63d00080ccc067866fb8cbbaca2b0438ab4105f5e0f08d \
|
||||
--hash=sha256:b054eb0a8aa712c8e9030065a59b5e6a5cf0746ecdb5f087cca5ec7685690c19 \
|
||||
--hash=sha256:b0becb75418f8a130e9d465e718316cd17c7a8acce6fe8fe07adc72762bee425 \
|
||||
--hash=sha256:b1d2ed1cbda2ae107283befd9284e650d840f8f7568cb9060b5466d25dc48975 \
|
||||
--hash=sha256:ba4261c8ad00b49d48bbb3b5af388bb7576edfc0ca50a49c11dcb77caa1d897e \
|
||||
--hash=sha256:d1fe9d7d09bb07228650903d6a9dc48ea649e3b8c69b1d263419cc722b3938e8 \
|
||||
--hash=sha256:d7804f6a71fc2dda888ef2de266727ec2f3915373d5a785ed4ddc603bbc91e08 \
|
||||
--hash=sha256:da2844fba024dd58eaa712561da47dcd1e7ad544a257482392472eae1c86d5e5 \
|
||||
--hash=sha256:dcefc97d1daf8d55199420e9162ab584ed0893a109f45e438b9794ced44c9fd0 \
|
||||
--hash=sha256:dd98c436a1fc56f48c70882cc243df89ad036210d871c7427dc164b31500dc11 \
|
||||
--hash=sha256:e74671e43ed4569fbd7989e5eecc7d06dc134b571872ab1d5a88f4a123814e9f \
|
||||
--hash=sha256:eb9b92f456ff3ec746cd4935b73c1117538d6124b8617bc0fe6fda0b3816e345 \
|
||||
--hash=sha256:ebb4e637a1fb861c34e48a00d03cffa9234f42bef923aec44e5625ffb9a8e8f9 \
|
||||
--hash=sha256:ef739fe89e7f43fb6494a43b1878a36273e5924869ba1d866f752c5812ae8d58 \
|
||||
--hash=sha256:f40db0e02a8157d2b90857c24d89b6310f9b6c3642369852cdc3b5ac49b92afc \
|
||||
--hash=sha256:f68bf937f113b88c866d090fea0bc52a098695173fc613b055a17ff0cf9683b6 \
|
||||
--hash=sha256:fb55c182a3f7b84c1a2d6de5fa7b1a05d4660d866b91dbf8d74549c57a1499e8
|
||||
zope.proxy==4.3.5 \
|
||||
--hash=sha256:00573dfa755d0703ab84bb23cb6ecf97bb683c34b340d4df76651f97b0bab068 \
|
||||
--hash=sha256:092049280f2848d2ba1b57b71fe04881762a220a97b65288bcb0968bb199ec30 \
|
||||
--hash=sha256:0cbd27b4d3718b5ec74fc65ffa53c78d34c65c6fd9411b8352d2a4f855220cf1 \
|
||||
--hash=sha256:17fc7e16d0c81f833a138818a30f366696653d521febc8e892858041c4d88785 \
|
||||
--hash=sha256:19577dfeb70e8a67249ba92c8ad20589a1a2d86a8d693647fa8385408a4c17b0 \
|
||||
--hash=sha256:207aa914576b1181597a1516e1b90599dc690c095343ae281b0772e44945e6a4 \
|
||||
--hash=sha256:219a7db5ed53e523eb4a4769f13105118b6d5b04ed169a283c9775af221e231f \
|
||||
--hash=sha256:2b50ea79849e46b5f4f2b0247a3687505d32d161eeb16a75f6f7e6cd81936e43 \
|
||||
--hash=sha256:5903d38362b6c716e66bbe470f190579c530a5baf03dbc8500e5c2357aa569a5 \
|
||||
--hash=sha256:5c24903675e271bd688c6e9e7df5775ac6b168feb87dbe0e4bcc90805f21b28f \
|
||||
--hash=sha256:5ef6bc5ed98139e084f4e91100f2b098a0cd3493d4e76f9d6b3f7b95d7ad0f06 \
|
||||
--hash=sha256:61b55ae3c23a126a788b33ffb18f37d6668e79a05e756588d9e4d4be7246ab1c \
|
||||
--hash=sha256:63ddb992931a5e616c87d3d89f5a58db086e617548005c7f9059fac68c03a5cc \
|
||||
--hash=sha256:6943da9c09870490dcfd50c4909c0cc19f434fa6948f61282dc9cb07bcf08160 \
|
||||
--hash=sha256:6ad40f85c1207803d581d5d75e9ea25327cd524925699a83dfc03bf8e4ba72b7 \
|
||||
--hash=sha256:6b44433a79bdd7af0e3337bd7bbcf53dd1f9b0fa66bf21bcb756060ce32a96c1 \
|
||||
--hash=sha256:6bbaa245015d933a4172395baad7874373f162955d73612f0b66b6c2c33b6366 \
|
||||
--hash=sha256:7007227f4ea85b40a2f5e5a244479f6a6dfcf906db9b55e812a814a8f0e2c28d \
|
||||
--hash=sha256:74884a0aec1f1609190ec8b34b5d58fb3b5353cf22b96161e13e0e835f13518f \
|
||||
--hash=sha256:7d25fe5571ddb16369054f54cdd883f23de9941476d97f2b92eb6d7d83afe22d \
|
||||
--hash=sha256:7e162bdc5e3baad26b2262240be7d2bab36991d85a6a556e48b9dfb402370261 \
|
||||
--hash=sha256:814d62678dc3a30f4aa081982d830b7c342cf230ffc9d030b020cb154eeebf9e \
|
||||
--hash=sha256:8878a34c5313ee52e20aa50b03138af8d472bae465710fb954d133a9bfd3c38d \
|
||||
--hash=sha256:a66a0d94e5b081d5d695e66d6667e91e74d79e273eee95c1747717ba9cb70792 \
|
||||
--hash=sha256:a69f5cbf4addcfdf03dda564a671040127a6b7c34cf9fe4973582e68441b63fa \
|
||||
--hash=sha256:b00f9f0c334d07709d3f73a7cb8ae63c6ca1a90c790a63b5e7effa666ef96021 \
|
||||
--hash=sha256:b6ed71e4a7b4690447b626f499d978aa13197a0e592950e5d7020308f6054698 \
|
||||
--hash=sha256:bdf5041e5851526e885af579d2f455348dba68d74f14a32781933569a327fddf \
|
||||
--hash=sha256:be034360dd34e62608419f86e799c97d389c10a0e677a25f236a971b2f40dac9 \
|
||||
--hash=sha256:cc8f590a5eed30b314ae6b0232d925519ade433f663de79cc3783e4b10d662ba \
|
||||
--hash=sha256:cd7a318a15fe6cc4584bf3c4426f092ed08c0fd012cf2a9173114234fe193e11 \
|
||||
--hash=sha256:cf19b5f63a59c20306e034e691402b02055c8f4e38bf6792c23cad489162a642 \
|
||||
--hash=sha256:cfc781ce442ec407c841e9aa51d0e1024f72b6ec34caa8fdb6ef9576d549acf2 \
|
||||
--hash=sha256:dea9f6f8633571e18bc20cad83603072e697103a567f4b0738d52dd0211b4527 \
|
||||
--hash=sha256:e4a86a1d5eb2cce83c5972b3930c7c1eac81ab3508464345e2b8e54f119d5505 \
|
||||
--hash=sha256:e7106374d4a74ed9ff00c46cc00f0a9f06a0775f8868e423f85d4464d2333679 \
|
||||
--hash=sha256:e98a8a585b5668aa9e34d10f7785abf9545fe72663b4bfc16c99a115185ae6a5 \
|
||||
--hash=sha256:f64840e68483316eb58d82c376ad3585ca995e69e33b230436de0cdddf7363f9 \
|
||||
--hash=sha256:f8f4b0a9e6683e43889852130595c8854d8ae237f2324a053cdd884de936aa9b \
|
||||
--hash=sha256:fc45a53219ed30a7f670a6d8c98527af0020e6fd4ee4c0a8fb59f147f06d816c
|
||||
|
||||
# Contains the requirements for the letsencrypt package.
|
||||
#
|
||||
# Since the letsencrypt package depends on certbot and using pip with hashes
|
||||
# requires that all installed packages have hashes listed, this allows
|
||||
# dependency-requirements.txt to be used without requiring a hash for a
|
||||
# (potentially unreleased) Certbot package.
|
||||
|
||||
letsencrypt==0.7.0 \
|
||||
--hash=sha256:105a5fb107e45bcd0722eb89696986dcf5f08a86a321d6aef25a0c7c63375ade \
|
||||
--hash=sha256:c36e532c486a7e92155ee09da54b436a3c420813ec1c590b98f635d924720de9
|
||||
|
||||
certbot==1.9.0 \
|
||||
--hash=sha256:d5a804d32e471050921f7b39ed9859e2e9de02824176ed78f57266222036b53a \
|
||||
--hash=sha256:2ff9bf7d9af381c7efee22dec2dd6938d9d8fddcc9e11682b86e734164a30b57
|
||||
acme==1.9.0 \
|
||||
--hash=sha256:d8061b396a22b21782c9b23ff9a945b23e50fca2573909a42f845e11d5658ac5 \
|
||||
--hash=sha256:38a1630c98e144136c62eec4d2c545a1bdb1a3cd4eca82214be6b83a1f5a161f
|
||||
certbot-apache==1.9.0 \
|
||||
--hash=sha256:09528a820d57e54984d490100644cd8a6603db97bf5776f86e95795ecfacf23d \
|
||||
--hash=sha256:f47fb3f4a9bd927f4812121a0beefe56b163475a28f4db34c64dc838688d9e9e
|
||||
certbot-nginx==1.9.0 \
|
||||
--hash=sha256:bb2e3f7fe17f071f350a3efa48571b8ef40a8e4b6db9c6da72539206a20b70be \
|
||||
--hash=sha256:ab26a4f49d53b0e8bf0f903e58e2a840cda233fe1cbbc54c36ff17f973e57d65
|
||||
|
||||
UNLIKELY_EOF
|
||||
# -------------------------------------------------------------------------
|
||||
cat << "UNLIKELY_EOF" > "$TEMP_DIR/pipstrap.py"
|
||||
#!/usr/bin/env python
|
||||
"""A small script that can act as a trust root for installing pip >=8
|
||||
Embed this in your project, and your VCS checkout is all you have to trust. In
|
||||
a post-peep era, this lets you claw your way to a hash-checking version of pip,
|
||||
with which you can install the rest of your dependencies safely. All it assumes
|
||||
is Python 2.6 or better and *some* version of pip already installed. If
|
||||
anything goes wrong, it will exit with a non-zero status code.
|
||||
"""
|
||||
# This is here so embedded copies are MIT-compliant:
|
||||
# Copyright (c) 2016 Erik Rose
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to
|
||||
# deal in the Software without restriction, including without limitation the
|
||||
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
# sell copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
from __future__ import print_function
|
||||
from distutils.version import StrictVersion
|
||||
from hashlib import sha256
|
||||
from os import environ
|
||||
from os.path import join
|
||||
from shutil import rmtree
|
||||
try:
|
||||
from subprocess import check_output
|
||||
except ImportError:
|
||||
from subprocess import CalledProcessError, PIPE, Popen
|
||||
|
||||
def check_output(*popenargs, **kwargs):
|
||||
if 'stdout' in kwargs:
|
||||
raise ValueError('stdout argument not allowed, it will be '
|
||||
'overridden.')
|
||||
process = Popen(stdout=PIPE, *popenargs, **kwargs)
|
||||
output, unused_err = process.communicate()
|
||||
retcode = process.poll()
|
||||
if retcode:
|
||||
cmd = kwargs.get("args")
|
||||
if cmd is None:
|
||||
cmd = popenargs[0]
|
||||
raise CalledProcessError(retcode, cmd)
|
||||
return output
|
||||
import sys
|
||||
from tempfile import mkdtemp
|
||||
try:
|
||||
from urllib2 import build_opener, HTTPHandler, HTTPSHandler
|
||||
except ImportError:
|
||||
from urllib.request import build_opener, HTTPHandler, HTTPSHandler
|
||||
try:
|
||||
from urlparse import urlparse
|
||||
except ImportError:
|
||||
from urllib.parse import urlparse # 3.4
|
||||
|
||||
|
||||
__version__ = 1, 5, 1
|
||||
PIP_VERSION = '9.0.1'
|
||||
DEFAULT_INDEX_BASE = 'https://pypi.python.org'
|
||||
|
||||
|
||||
# wheel has a conditional dependency on argparse:
|
||||
maybe_argparse = (
|
||||
[('18/dd/e617cfc3f6210ae183374cd9f6a26b20514bbb5a792af97949c5aacddf0f/'
|
||||
'argparse-1.4.0.tar.gz',
|
||||
'62b089a55be1d8949cd2bc7e0df0bddb9e028faefc8c32038cc84862aefdd6e4')]
|
||||
if sys.version_info < (2, 7, 0) else [])
|
||||
|
||||
|
||||
# Be careful when updating the pinned versions here, in particular for pip.
|
||||
# Indeed starting from 10.0, pip will build dependencies in isolation if the
|
||||
# related projects are compliant with PEP 517. This is not something we want
|
||||
# as of now, so the isolation build will need to be disabled wherever
|
||||
# pipstrap is used (see https://github.com/certbot/certbot/issues/8256).
|
||||
PACKAGES = maybe_argparse + [
|
||||
# Pip has no dependencies, as it vendors everything:
|
||||
('11/b6/abcb525026a4be042b486df43905d6893fb04f05aac21c32c638e939e447/'
|
||||
'pip-{0}.tar.gz'.format(PIP_VERSION),
|
||||
'09f243e1a7b461f654c26a725fa373211bb7ff17a9300058b205c61658ca940d'),
|
||||
# This version of setuptools has only optional dependencies:
|
||||
('37/1b/b25507861991beeade31473868463dad0e58b1978c209de27384ae541b0b/'
|
||||
'setuptools-40.6.3.zip',
|
||||
'3b474dad69c49f0d2d86696b68105f3a6f195f7ab655af12ef9a9c326d2b08f8'),
|
||||
('c9/1d/bd19e691fd4cfe908c76c429fe6e4436c9e83583c4414b54f6c85471954a/'
|
||||
'wheel-0.29.0.tar.gz',
|
||||
'1ebb8ad7e26b448e9caa4773d2357849bf80ff9e313964bcaf79cbf0201a1648')
|
||||
]
|
||||
|
||||
|
||||
class HashError(Exception):
|
||||
def __str__(self):
|
||||
url, path, actual, expected = self.args
|
||||
return ('{url} did not match the expected hash {expected}. Instead, '
|
||||
'it was {actual}. The file (left at {path}) may have been '
|
||||
'tampered with.'.format(**locals()))
|
||||
|
||||
|
||||
def hashed_download(url, temp, digest):
|
||||
"""Download ``url`` to ``temp``, make sure it has the SHA-256 ``digest``,
|
||||
and return its path."""
|
||||
# Based on pip 1.4.1's URLOpener but with cert verification removed. Python
|
||||
# >=2.7.9 verifies HTTPS certs itself, and, in any case, the cert
|
||||
# authenticity has only privacy (not arbitrary code execution)
|
||||
# implications, since we're checking hashes.
|
||||
def opener(using_https=True):
|
||||
opener = build_opener(HTTPSHandler())
|
||||
if using_https:
|
||||
# Strip out HTTPHandler to prevent MITM spoof:
|
||||
for handler in opener.handlers:
|
||||
if isinstance(handler, HTTPHandler):
|
||||
opener.handlers.remove(handler)
|
||||
return opener
|
||||
|
||||
def read_chunks(response, chunk_size):
|
||||
while True:
|
||||
chunk = response.read(chunk_size)
|
||||
if not chunk:
|
||||
break
|
||||
yield chunk
|
||||
|
||||
parsed_url = urlparse(url)
|
||||
response = opener(using_https=parsed_url.scheme == 'https').open(url)
|
||||
path = join(temp, parsed_url.path.split('/')[-1])
|
||||
actual_hash = sha256()
|
||||
with open(path, 'wb') as file:
|
||||
for chunk in read_chunks(response, 4096):
|
||||
file.write(chunk)
|
||||
actual_hash.update(chunk)
|
||||
|
||||
actual_digest = actual_hash.hexdigest()
|
||||
if actual_digest != digest:
|
||||
raise HashError(url, path, actual_digest, digest)
|
||||
return path
|
||||
|
||||
|
||||
def get_index_base():
|
||||
"""Return the URL to the dir containing the "packages" folder.
|
||||
Try to wring something out of PIP_INDEX_URL, if set. Hack "/simple" off the
|
||||
end if it's there; that is likely to give us the right dir.
|
||||
"""
|
||||
env_var = environ.get('PIP_INDEX_URL', '').rstrip('/')
|
||||
if env_var:
|
||||
SIMPLE = '/simple'
|
||||
if env_var.endswith(SIMPLE):
|
||||
return env_var[:-len(SIMPLE)]
|
||||
else:
|
||||
return env_var
|
||||
else:
|
||||
return DEFAULT_INDEX_BASE
|
||||
|
||||
|
||||
def main():
|
||||
python = sys.executable or 'python'
|
||||
pip_version = StrictVersion(check_output([python, '-m', 'pip', '--version'])
|
||||
.decode('utf-8').split()[1])
|
||||
has_pip_cache = pip_version >= StrictVersion('6.0')
|
||||
index_base = get_index_base()
|
||||
temp = mkdtemp(prefix='pipstrap-')
|
||||
try:
|
||||
downloads = [hashed_download(index_base + '/packages/' + path,
|
||||
temp,
|
||||
digest)
|
||||
for path, digest in PACKAGES]
|
||||
# Calling pip as a module is the preferred way to avoid problems about pip self-upgrade.
|
||||
command = [python, '-m', 'pip', 'install', '--no-index', '--no-deps', '-U']
|
||||
# Disable cache since it is not used and it otherwise sometimes throws permission warnings:
|
||||
command.extend(['--no-cache-dir'] if has_pip_cache else [])
|
||||
command.extend(downloads)
|
||||
check_output(command)
|
||||
except HashError as exc:
|
||||
print(exc)
|
||||
except Exception:
|
||||
rmtree(temp)
|
||||
raise
|
||||
else:
|
||||
rmtree(temp)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
|
||||
UNLIKELY_EOF
|
||||
# -------------------------------------------------------------------------
|
||||
# Set PATH so pipstrap upgrades the right (v)env:
|
||||
PATH="$VENV_BIN:$PATH" "$VENV_BIN/python" "$TEMP_DIR/pipstrap.py"
|
||||
set +e
|
||||
if [ "$VERBOSE" = 1 ]; then
|
||||
"$VENV_BIN/pip" install --disable-pip-version-check --no-cache-dir --require-hashes -r "$TEMP_DIR/letsencrypt-auto-requirements.txt"
|
||||
else
|
||||
PIP_OUT=`"$VENV_BIN/pip" install --disable-pip-version-check --no-cache-dir --require-hashes -r "$TEMP_DIR/letsencrypt-auto-requirements.txt" 2>&1`
|
||||
fi
|
||||
PIP_STATUS=$?
|
||||
set -e
|
||||
if [ "$PIP_STATUS" != 0 ]; then
|
||||
# Report error. (Otherwise, be quiet.)
|
||||
error "Had a problem while installing Python packages."
|
||||
if [ "$VERBOSE" != 1 ]; then
|
||||
error
|
||||
error "pip prints the following errors: "
|
||||
error "====================================================="
|
||||
error "$PIP_OUT"
|
||||
error "====================================================="
|
||||
error
|
||||
error "Certbot has problem setting up the virtual environment."
|
||||
|
||||
if `echo $PIP_OUT | grep -q Killed` || `echo $PIP_OUT | grep -q "allocate memory"` ; then
|
||||
error
|
||||
error "Based on your pip output, the problem can likely be fixed by "
|
||||
error "increasing the available memory."
|
||||
else
|
||||
error
|
||||
error "We were not be able to guess the right solution from your pip "
|
||||
error "output."
|
||||
fi
|
||||
|
||||
error
|
||||
error "Consult https://certbot.eff.org/docs/install.html#problems-with-python-virtual-environment"
|
||||
error "for possible solutions."
|
||||
error "You may also find some support resources at https://certbot.eff.org/support/ ."
|
||||
fi
|
||||
rm -rf "$VENV_PATH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -d "$OLD_VENV_PATH" -a ! -L "$OLD_VENV_PATH" ]; then
|
||||
rm -rf "$OLD_VENV_PATH"
|
||||
ln -s "$VENV_PATH" "$OLD_VENV_PATH"
|
||||
fi
|
||||
|
||||
say "Installation succeeded."
|
||||
fi
|
||||
|
||||
# If you're modifying any of the code after this point in this current `if` block, you
|
||||
# may need to update the "$DEPRECATED_OS" = 1 case at the beginning of phase 2 as well.
|
||||
|
||||
if [ "$INSTALL_ONLY" = 1 ]; then
|
||||
say "Certbot is installed."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
"$VENV_BIN/letsencrypt" "$@"
|
||||
|
||||
else
|
||||
# Phase 1: Upgrade certbot-auto if necessary, then self-invoke.
|
||||
#
|
||||
# Each phase checks the version of only the thing it is responsible for
|
||||
# upgrading. Phase 1 checks the version of the latest release of
|
||||
# certbot-auto (which is always the same as that of the certbot
|
||||
# package). Phase 2 checks the version of the locally installed certbot.
|
||||
export PHASE_1_VERSION="$LE_AUTO_VERSION"
|
||||
|
||||
if [ ! -f "$VENV_BIN/letsencrypt" ]; then
|
||||
if ! OldVenvExists; then
|
||||
if [ "$HELP" = 1 ]; then
|
||||
echo "$USAGE"
|
||||
exit 0
|
||||
fi
|
||||
# If it looks like we've never bootstrapped before, bootstrap:
|
||||
Bootstrap
|
||||
fi
|
||||
fi
|
||||
if [ "$OS_PACKAGES_ONLY" = 1 ]; then
|
||||
say "OS packages installed."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
DeterminePythonVersion "NOCRASH"
|
||||
# Don't warn about file permissions if the user disabled the check or we
|
||||
# can't find an up-to-date Python.
|
||||
if [ "$PYVER" -ge "$MIN_PYVER" -a "$NO_PERMISSIONS_CHECK" != 1 ]; then
|
||||
# If the script fails for some reason, don't break certbot-auto.
|
||||
set +e
|
||||
# Suppress unexpected error output.
|
||||
CHECK_PERM_OUT=$(CheckPathPermissions "$LE_PYTHON" "$0" 2>/dev/null)
|
||||
CHECK_PERM_STATUS="$?"
|
||||
set -e
|
||||
# Only print output if the script ran successfully and it actually produced
|
||||
# output. The latter check resolves
|
||||
# https://github.com/certbot/certbot/issues/7012.
|
||||
if [ "$CHECK_PERM_STATUS" = 0 -a -n "$CHECK_PERM_OUT" ]; then
|
||||
error "$CHECK_PERM_OUT"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$NO_SELF_UPGRADE" != 1 ]; then
|
||||
TEMP_DIR=$(TempDir)
|
||||
trap 'rm -rf "$TEMP_DIR"' EXIT
|
||||
# ---------------------------------------------------------------------------
|
||||
cat << "UNLIKELY_EOF" > "$TEMP_DIR/fetch.py"
|
||||
"""Do downloading and JSON parsing without additional dependencies. ::
|
||||
|
||||
# Print latest released version of LE to stdout:
|
||||
python fetch.py --latest-version
|
||||
|
||||
# Download letsencrypt-auto script from git tag v1.2.3 into the folder I'm
|
||||
# in, and make sure its signature verifies:
|
||||
python fetch.py --le-auto-script v1.2.3
|
||||
|
||||
On failure, return non-zero.
|
||||
|
||||
"""
|
||||
|
||||
from __future__ import print_function, unicode_literals
|
||||
|
||||
from distutils.version import LooseVersion
|
||||
from json import loads
|
||||
from os import devnull, environ
|
||||
from os.path import dirname, join
|
||||
import re
|
||||
import ssl
|
||||
from subprocess import check_call, CalledProcessError
|
||||
from sys import argv, exit
|
||||
try:
|
||||
from urllib2 import build_opener, HTTPHandler, HTTPSHandler
|
||||
from urllib2 import HTTPError, URLError
|
||||
except ImportError:
|
||||
from urllib.request import build_opener, HTTPHandler, HTTPSHandler
|
||||
from urllib.error import HTTPError, URLError
|
||||
|
||||
PUBLIC_KEY = environ.get('LE_AUTO_PUBLIC_KEY', """-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6MR8W/galdxnpGqBsYbq
|
||||
OzQb2eyW15YFjDDEMI0ZOzt8f504obNs920lDnpPD2/KqgsfjOgw2K7xWDJIj/18
|
||||
xUvWPk3LDkrnokNiRkA3KOx3W6fHycKL+zID7zy+xZYBuh2fLyQtWV1VGQ45iNRp
|
||||
9+Zo7rH86cdfgkdnWTlNSHyTLW9NbXvyv/E12bppPcEvgCTAQXgnDVJ0/sqmeiij
|
||||
n9tTFh03aM+R2V/21h8aTraAS24qiPCz6gkmYGC8yr6mglcnNoYbsLNYZ69zF1XH
|
||||
cXPduCPdPdfLlzVlKK1/U7hkA28eG3BIAMh6uJYBRJTpiGgaGdPd7YekUB8S6cy+
|
||||
CQIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
""")
|
||||
|
||||
class ExpectedError(Exception):
|
||||
"""A novice-readable exception that also carries the original exception for
|
||||
debugging"""
|
||||
|
||||
|
||||
class HttpsGetter(object):
|
||||
def __init__(self):
|
||||
"""Build an HTTPS opener."""
|
||||
# Based on pip 1.4.1's URLOpener
|
||||
# This verifies certs on only Python >=2.7.9, and when NO_CERT_VERIFY isn't set.
|
||||
if environ.get('NO_CERT_VERIFY') == '1' and hasattr(ssl, 'SSLContext'):
|
||||
self._opener = build_opener(HTTPSHandler(context=cert_none_context()))
|
||||
else:
|
||||
self._opener = build_opener(HTTPSHandler())
|
||||
# Strip out HTTPHandler to prevent MITM spoof:
|
||||
for handler in self._opener.handlers:
|
||||
if isinstance(handler, HTTPHandler):
|
||||
self._opener.handlers.remove(handler)
|
||||
|
||||
def get(self, url):
|
||||
"""Return the document contents pointed to by an HTTPS URL.
|
||||
|
||||
If something goes wrong (404, timeout, etc.), raise ExpectedError.
|
||||
|
||||
"""
|
||||
try:
|
||||
# socket module docs say default timeout is None: that is, no
|
||||
# timeout
|
||||
return self._opener.open(url, timeout=30).read()
|
||||
except (HTTPError, IOError) as exc:
|
||||
raise ExpectedError("Couldn't download %s." % url, exc)
|
||||
|
||||
|
||||
def write(contents, dir, filename):
|
||||
"""Write something to a file in a certain directory."""
|
||||
with open(join(dir, filename), 'wb') as file:
|
||||
file.write(contents)
|
||||
|
||||
|
||||
def latest_stable_version(get):
|
||||
"""Return the latest stable release of letsencrypt."""
|
||||
metadata = loads(get(
|
||||
environ.get('LE_AUTO_JSON_URL',
|
||||
'https://pypi.python.org/pypi/certbot/json')).decode('UTF-8'))
|
||||
# metadata['info']['version'] actually returns the latest of any kind of
|
||||
# release release, contrary to https://wiki.python.org/moin/PyPIJSON.
|
||||
# The regex is a sufficient regex for picking out prereleases for most
|
||||
# packages, LE included.
|
||||
return str(max(LooseVersion(r) for r
|
||||
in metadata['releases'].keys()
|
||||
if re.match('^[0-9.]+$', r)))
|
||||
|
||||
|
||||
def verified_new_le_auto(get, tag, temp_dir):
|
||||
"""Return the path to a verified, up-to-date letsencrypt-auto script.
|
||||
|
||||
If the download's signature does not verify or something else goes wrong
|
||||
with the verification process, raise ExpectedError.
|
||||
|
||||
"""
|
||||
le_auto_dir = environ.get(
|
||||
'LE_AUTO_DIR_TEMPLATE',
|
||||
'https://raw.githubusercontent.com/certbot/certbot/%s/'
|
||||
'letsencrypt-auto-source/') % tag
|
||||
write(get(le_auto_dir + 'letsencrypt-auto'), temp_dir, 'letsencrypt-auto')
|
||||
write(get(le_auto_dir + 'letsencrypt-auto.sig'), temp_dir, 'letsencrypt-auto.sig')
|
||||
write(PUBLIC_KEY.encode('UTF-8'), temp_dir, 'public_key.pem')
|
||||
try:
|
||||
with open(devnull, 'w') as dev_null:
|
||||
check_call(['openssl', 'dgst', '-sha256', '-verify',
|
||||
join(temp_dir, 'public_key.pem'),
|
||||
'-signature',
|
||||
join(temp_dir, 'letsencrypt-auto.sig'),
|
||||
join(temp_dir, 'letsencrypt-auto')],
|
||||
stdout=dev_null,
|
||||
stderr=dev_null)
|
||||
except CalledProcessError as exc:
|
||||
raise ExpectedError("Couldn't verify signature of downloaded "
|
||||
"certbot-auto.", exc)
|
||||
|
||||
|
||||
def cert_none_context():
|
||||
"""Create a SSLContext object to not check hostname."""
|
||||
# PROTOCOL_TLS isn't available before 2.7.13 but this code is for 2.7.9+, so use this.
|
||||
context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
|
||||
context.verify_mode = ssl.CERT_NONE
|
||||
return context
|
||||
|
||||
|
||||
def main():
|
||||
get = HttpsGetter().get
|
||||
flag = argv[1]
|
||||
try:
|
||||
if flag == '--latest-version':
|
||||
print(latest_stable_version(get))
|
||||
elif flag == '--le-auto-script':
|
||||
tag = argv[2]
|
||||
verified_new_le_auto(get, tag, dirname(argv[0]))
|
||||
except ExpectedError as exc:
|
||||
print(exc.args[0], exc.args[1])
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
exit(main())
|
||||
|
||||
UNLIKELY_EOF
|
||||
# ---------------------------------------------------------------------------
|
||||
if [ "$PYVER" -lt "$MIN_PYVER" ]; then
|
||||
error "WARNING: couldn't find Python $MIN_PYTHON_VERSION+ to check for updates."
|
||||
elif ! REMOTE_VERSION=`"$LE_PYTHON" "$TEMP_DIR/fetch.py" --latest-version` ; then
|
||||
error "WARNING: unable to check for updates."
|
||||
fi
|
||||
|
||||
# If for any reason REMOTE_VERSION is not set, let's assume certbot-auto is up-to-date,
|
||||
# and do not go into the self-upgrading process.
|
||||
if [ -n "$REMOTE_VERSION" ]; then
|
||||
LE_VERSION_STATE=`CompareVersions "$LE_PYTHON" "$LE_AUTO_VERSION" "$REMOTE_VERSION"`
|
||||
|
||||
if [ "$LE_VERSION_STATE" = "UNOFFICIAL" ]; then
|
||||
say "Unofficial certbot-auto version detected, self-upgrade is disabled: $LE_AUTO_VERSION"
|
||||
elif [ "$LE_VERSION_STATE" = "OUTDATED" ]; then
|
||||
say "Upgrading certbot-auto $LE_AUTO_VERSION to $REMOTE_VERSION..."
|
||||
|
||||
# Now we drop into Python so we don't have to install even more
|
||||
# dependencies (curl, etc.), for better flow control, and for the option of
|
||||
# future Windows compatibility.
|
||||
"$LE_PYTHON" "$TEMP_DIR/fetch.py" --le-auto-script "v$REMOTE_VERSION"
|
||||
|
||||
# Install new copy of certbot-auto.
|
||||
# TODO: Deal with quotes in pathnames.
|
||||
say "Replacing certbot-auto..."
|
||||
# Clone permissions with cp. chmod and chown don't have a --reference
|
||||
# option on macOS or BSD, and stat -c on Linux is stat -f on macOS and BSD:
|
||||
cp -p "$0" "$TEMP_DIR/letsencrypt-auto.permission-clone"
|
||||
cp "$TEMP_DIR/letsencrypt-auto" "$TEMP_DIR/letsencrypt-auto.permission-clone"
|
||||
# Using mv rather than cp leaves the old file descriptor pointing to the
|
||||
# original copy so the shell can continue to read it unmolested. mv across
|
||||
# filesystems is non-atomic, doing `rm dest, cp src dest, rm src`, but the
|
||||
# cp is unlikely to fail if the rm doesn't.
|
||||
mv -f "$TEMP_DIR/letsencrypt-auto.permission-clone" "$0"
|
||||
fi # A newer version is available.
|
||||
fi
|
||||
fi # Self-upgrading is allowed.
|
||||
|
||||
RerunWithArgs --le-auto-phase2 "$@"
|
||||
fi
|
|
@ -19,5 +19,5 @@
|
|||
systemd:
|
||||
daemon_reload: yes
|
||||
|
||||
- name: install certbot-auto
|
||||
command: /usr/local/bin/certbot --noninteractive --install-only
|
||||
- name: install letsencrypt-auto
|
||||
command: /usr/local/bin/letsencrypt-auto --noninteractive --install-only --no-self-upgrade
|
||||
|
|
59
certbot/tasks/install-legacy.yml
Normal file
59
certbot/tasks/install-legacy.yml
Normal file
|
@ -0,0 +1,59 @@
|
|||
---
|
||||
|
||||
- name: certbot package is removed
|
||||
apt:
|
||||
name: certbot
|
||||
state: absent
|
||||
|
||||
- include_role:
|
||||
name: evolix/remount-usr
|
||||
|
||||
- name: Let's Encrypt script is present
|
||||
copy:
|
||||
src: letsencrypt-auto
|
||||
dest: /usr/local/bin/letsencrypt-auto
|
||||
mode: '0755'
|
||||
owner: root
|
||||
group: root
|
||||
force: yes
|
||||
notify: install letsencrypt-auto
|
||||
|
||||
- name: Check certbot script
|
||||
stat:
|
||||
path: /usr/local/bin/certbot
|
||||
register: certbot_path
|
||||
|
||||
- name: Rename certbot script if present
|
||||
command: "mv /usr/local/bin/certbot /usr/local/bin/certbot.bak"
|
||||
when: certbot_path.stat.exists
|
||||
|
||||
- name: Let's Encrypt script is symlinked as certbot
|
||||
file:
|
||||
src: "/usr/local/bin/letsencrypt-auto"
|
||||
dest: "/usr/local/bin/certbot"
|
||||
state: link
|
||||
|
||||
- name: systemd artefacts are absent
|
||||
file:
|
||||
dest: "{{ item }}"
|
||||
state: absent
|
||||
loop:
|
||||
- /etc/systemd/system/certbot.service
|
||||
- /etc/systemd/system/certbot.service.d
|
||||
- /etc/systemd/system/certbot.timer
|
||||
notify: systemd daemon-reload
|
||||
|
||||
- name: custom crontab is present
|
||||
copy:
|
||||
src: cron_jessie
|
||||
dest: /etc/cron.d/certbot
|
||||
force: yes
|
||||
when: certbot_custom_crontab
|
||||
|
||||
- name: disable self-upgrade
|
||||
ini_file:
|
||||
dest: "/etc/letsencrypt/cli.ini"
|
||||
section: null
|
||||
option: "no-self-upgrade"
|
||||
value: 0
|
||||
state: present
|
|
@ -1,35 +0,0 @@
|
|||
---
|
||||
|
||||
- name: certbot package is removed
|
||||
apt:
|
||||
name: certbot
|
||||
state: absent
|
||||
|
||||
- include_role:
|
||||
name: evolix/remount-usr
|
||||
|
||||
- name: Certbot script is downloaded
|
||||
get_url:
|
||||
url: https://dl.eff.org/certbot-auto
|
||||
dest: /usr/local/bin/certbot
|
||||
mode: '0755'
|
||||
owner: root
|
||||
group: root
|
||||
force: no
|
||||
notify: install certbot-auto
|
||||
|
||||
- name: systemd artefacts are absent
|
||||
file:
|
||||
dest: "{{ item }}"
|
||||
state: absent
|
||||
loop:
|
||||
- /etc/systemd/system/certbot.service
|
||||
- /etc/systemd/system/certbot.service.d
|
||||
- /etc/systemd/system/certbot.timer
|
||||
notify: systemd daemon-reload
|
||||
|
||||
- name: custom crontab is present
|
||||
copy:
|
||||
src: cron_jessie
|
||||
dest: /etc/cron.d/certbot
|
||||
force: yes
|
|
@ -7,17 +7,17 @@
|
|||
- ansible_distribution_major_version is version('8', '>=')
|
||||
msg: only compatible with Debian 9+
|
||||
|
||||
- name: Install from sources on Debian 8
|
||||
include: install-sources.yml
|
||||
- name: Install legacy script on Debian 8 and 9
|
||||
include: install-legacy.yml
|
||||
when:
|
||||
- ansible_distribution == "Debian"
|
||||
- ansible_distribution_major_version is version('8', '=')
|
||||
- ansible_distribution_major_version is version('10', '<')
|
||||
|
||||
- name: Install package on Debian 9+
|
||||
- name: Install package on Debian 10+
|
||||
include: install-package.yml
|
||||
when:
|
||||
- ansible_distribution == "Debian"
|
||||
- ansible_distribution_major_version is version('9', '>=')
|
||||
- ansible_distribution_major_version is version('10', '>=')
|
||||
|
||||
- include: acme-challenge.yml
|
||||
|
||||
|
|
|
@ -7,6 +7,5 @@
|
|||
Alias /.well-known/acme-challenge /var/lib/letsencrypt/.well-known/acme-challenge
|
||||
<Directory "/var/lib/letsencrypt/.well-known/acme-challenge">
|
||||
Options -Indexes
|
||||
Allow from all
|
||||
Require all granted
|
||||
</Directory>
|
||||
|
|
|
@ -5,5 +5,10 @@ LOG_DIR=/var/log/elasticsearch
|
|||
USER=elasticsearch
|
||||
MAX_AGE={{ elasticsearch_log_rotate_days | mandatory }}
|
||||
|
||||
find ${LOG_DIR} -type f -user ${USER} \( -name "*.log.????-??-??" -o -name "*-????-??-??.log" \) -exec gzip --best {} \;
|
||||
find ${LOG_DIR} -type f -user ${USER} \( -name "*.log.????-??-??.gz" -o -name "*-????-??-??.log.gz" \) -ctime +${MAX_AGE} -delete
|
||||
# Compress logs
|
||||
find ${LOG_DIR} -type f -user ${USER} -name "*.log.????-??-??" -exec gzip --best {} \;
|
||||
find ${LOG_DIR} -type f -user ${USER} -name "*-????-??-??.log" -exec gzip --best {} \;
|
||||
find ${LOG_DIR} -type f -user ${USER} -name "*.log.??" -not -name "*.gz" -exec gzip --best {} \;
|
||||
|
||||
# Delete old logs
|
||||
find ${LOG_DIR} -type f -user ${USER} -name "*gz" -ctime +${MAX_AGE} -delete
|
|
@ -14,7 +14,7 @@ show_version() {
|
|||
cat <<END
|
||||
evoacme version ${VERSION}
|
||||
|
||||
Copyright 2009-2020 Evolix <info@evolix.fr>,
|
||||
Copyright 2009-2021 Evolix <info@evolix.fr>,
|
||||
Victor Laborie <vlaborie@evolix.fr>,
|
||||
Jérémy Lecour <jlecour@evolix.fr>,
|
||||
Benoit Série <bserie@evolix.fr>
|
||||
|
@ -208,6 +208,7 @@ main() {
|
|||
[ "${TEST}" = "1" ] && CERTBOT_MODE="${CERTBOT_MODE} --test-cert"
|
||||
[ "${QUIET}" = "1" ] && CERTBOT_MODE="${CERTBOT_MODE} --quiet"
|
||||
[ "${DRY_RUN}" = "1" ] && CERTBOT_MODE="${CERTBOT_MODE} --dry-run"
|
||||
[ "${CERTBOT_SELF_UPGRADE}" = "0" ] && CERTBOT_MODE="${CERTBOT_MODE} --no-self-upgrade"
|
||||
|
||||
local CERTBOT_REGISTRATION="--agree-tos"
|
||||
if [ -n "${SSL_EMAIL}" ]; then
|
||||
|
@ -309,7 +310,7 @@ readonly QUIET=${QUIET:-"0"}
|
|||
readonly TEST=${TEST:-"0"}
|
||||
readonly DRY_RUN=${DRY_RUN:-"0"}
|
||||
|
||||
readonly VERSION="20.12"
|
||||
readonly VERSION="21.01"
|
||||
|
||||
# Read configuration file, if it exists
|
||||
[ -r /etc/default/evoacme ] && . /etc/default/evoacme
|
||||
|
@ -323,5 +324,6 @@ readonly LOG_DIR=${LOG_DIR:-"/var/log/evoacme"}
|
|||
readonly HOOKS_DIR=${HOOKS_DIR:-"${CRT_DIR}/renewal-hooks/deploy"}
|
||||
readonly SSL_MINDAY=${SSL_MINDAY:-"30"}
|
||||
readonly SSL_EMAIL=${SSL_EMAIL:-""}
|
||||
readonly CERTBOT_SELF_UPGRADE=${CERTBOT_SELF_UPGRADE:-"0"}
|
||||
|
||||
main ${ARGS}
|
||||
|
|
|
@ -13,7 +13,7 @@ show_version() {
|
|||
cat <<END
|
||||
make-csr version ${VERSION}
|
||||
|
||||
Copyright 2009-2020 Evolix <info@evolix.fr>,
|
||||
Copyright 2009-2021 Evolix <info@evolix.fr>,
|
||||
Victor Laborie <vlaborie@evolix.fr>,
|
||||
Jérémy Lecour <jlecour@evolix.fr>,
|
||||
Benoit Série <bserie@evolix.fr>
|
||||
|
@ -265,7 +265,7 @@ readonly ARGS=$@
|
|||
readonly VERBOSE=${VERBOSE:-"0"}
|
||||
readonly QUIET=${QUIET:-"0"}
|
||||
|
||||
readonly VERSION="20.12"
|
||||
readonly VERSION="21.01"
|
||||
|
||||
# Read configuration file, if it exists
|
||||
[ -r /etc/default/evoacme ] && . /etc/default/evoacme
|
||||
|
|
|
@ -13,7 +13,7 @@ show_version() {
|
|||
cat <<END
|
||||
vhost-domains version ${VERSION}
|
||||
|
||||
Copyright 2009-2020 Evolix <info@evolix.fr>,
|
||||
Copyright 2009-2021 Evolix <info@evolix.fr>,
|
||||
Victor Laborie <vlaborie@evolix.fr>,
|
||||
Jérémy Lecour <jlecour@evolix.fr>,
|
||||
Benoit Série <bserie@evolix.fr>
|
||||
|
@ -170,7 +170,7 @@ readonly ARGS=$@
|
|||
readonly VERBOSE=${VERBOSE:-"0"}
|
||||
readonly QUIET=${QUIET:-"0"}
|
||||
|
||||
readonly VERSION="20.12"
|
||||
readonly VERSION="21.01"
|
||||
|
||||
readonly SRV_IP=${SRV_IP:-""}
|
||||
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
---
|
||||
- name: Do no install certbot crontab
|
||||
set_fact:
|
||||
certbot_custom_crontab: False
|
||||
|
||||
- include_role:
|
||||
name: evolix/certbot
|
||||
|
||||
|
|
|
@ -6,6 +6,10 @@ nagios ALL = NOPASSWD: /usr/lib/nagios/plugins/check_procs
|
|||
nagios ALL = NOPASSWD: /usr/local/lib/nagios/plugins/check_minifirewall
|
||||
nagios ALL = NOPASSWD: /usr/local/lib/nagios/plugins/check_haproxy_stats
|
||||
nagios ALL = NOPASSWD: /usr/sbin/bkctld check
|
||||
nagios ALL = NOPASSWD: /usr/local/lib/nagios/plugins/check_phpfpm_multi /var/lib/lxc/php56/rootfs/etc/php5/fpm/pool.d/
|
||||
nagios ALL = NOPASSWD: /usr/local/lib/nagios/plugins/check_phpfpm_multi /var/lib/lxc/php70/rootfs/etc/php/7.0/fpm/pool.d/
|
||||
nagios ALL = NOPASSWD: /usr/local/lib/nagios/plugins/check_phpfpm_multi /var/lib/lxc/php73/rootfs/etc/php/7.3/fpm/pool.d/
|
||||
nagios ALL = NOPASSWD: /usr/local/lib/nagios/plugins/check_phpfpm_multi /var/lib/lxc/php74/rootfs/etc/php/7.4/fpm/pool.d/
|
||||
nagios ALL = (clamav) NOPASSWD: /usr/bin/clamscan /tmp/safe.txt
|
||||
|
||||
%{{ evolinux_sudo_group }} ALL=(ALL:ALL) ALL
|
||||
|
|
|
@ -21,3 +21,4 @@ filebeat_logstash_auth_password: ""
|
|||
filebeat_use_config_template: False
|
||||
filebeat_update_config: True
|
||||
filebeat_force_config: True
|
||||
filebeat_upgrade_package: False
|
||||
|
|
|
@ -30,7 +30,8 @@
|
|||
- name: Filebeat is installed
|
||||
apt:
|
||||
name: filebeat
|
||||
state: present
|
||||
state: "{% if filebeat_upgrade_package %}latest{% else %}present{% endif %}"
|
||||
notify: restart filebeat
|
||||
tags:
|
||||
- filebeat
|
||||
- packages
|
||||
|
@ -39,6 +40,7 @@
|
|||
systemd:
|
||||
name: filebeat
|
||||
enabled: yes
|
||||
notify: restart filebeat
|
||||
|
||||
- name: is logstash-plugin available?
|
||||
stat:
|
||||
|
|
|
@ -18,6 +18,10 @@ haproxy_chroot: /var/lib/haproxy
|
|||
|
||||
haproxy_stats_access_ips: []
|
||||
haproxy_stats_admin_ips: []
|
||||
haproxy_stats_users: []
|
||||
## use crypt(8) password encryption
|
||||
# haproxy_stats_users:
|
||||
# - { login: "", password: "" }
|
||||
haproxy_maintenance_ips: []
|
||||
haproxy_deny_ips: []
|
||||
|
||||
|
|
|
@ -35,18 +35,34 @@ defaults
|
|||
errorfile 504 /etc/haproxy/errors/504.http
|
||||
|
||||
{% if haproxy_stats_enable %}
|
||||
{% if haproxy_stats_users %}
|
||||
userlist stats_users
|
||||
{% for user in haproxy_stats_users | default([]) %}
|
||||
user {{ user.login }} password {{ user.password }}
|
||||
{% endfor %}
|
||||
|
||||
{% endif %}
|
||||
listen stats
|
||||
mode http
|
||||
bind {{ haproxy_stats_bind_directive }}
|
||||
|
||||
acl stats_access_ips src -f /etc/haproxy/stats_access_ips
|
||||
acl stats_admin_ips src -f /etc/haproxy/stats_admin_ips
|
||||
|
||||
stats enable
|
||||
stats refresh 10s
|
||||
stats uri {{ haproxy_stats_path }}
|
||||
stats show-legends
|
||||
stats show-node
|
||||
stats admin if { src -f /etc/haproxy/stats_admin_ips }
|
||||
stats admin if stats_admin_ips
|
||||
|
||||
{% if haproxy_stats_users %}
|
||||
acl stats_users http_auth(stats_users)
|
||||
stats http-request auth realm "HAProxy admin" if !stats_access_ips !stats_users
|
||||
{% else %}
|
||||
stats http-request deny if !stats_access_ips
|
||||
{% endif %}
|
||||
|
||||
http-request deny if !{ src -f /etc/haproxy/stats_access_ips }
|
||||
http-request set-log-level silent
|
||||
{% endif %}
|
||||
|
||||
|
|
16
keepalived/README.md
Normal file
16
keepalived/README.md
Normal file
|
@ -0,0 +1,16 @@
|
|||
# keepalived
|
||||
|
||||
Install Keepalived
|
||||
|
||||
## Tasks
|
||||
|
||||
Everything is in the `tasks/main.yml` file.
|
||||
|
||||
## Available variables
|
||||
|
||||
* `keepalived_interface` : Interface used by vrrpd instance (default is the interface reported by ansible_default_ipv4.interface)
|
||||
* `keepalived_role` : This can be either master or backup (default: `master`)
|
||||
* `keepalived_router_id` : Number between 0 and 255 used to differentiate multiple instances of vrrpd (default: `42`)
|
||||
* `keepalived_priority` : Used for electing MASTER, highest priority wins (default : `100` when keepalived_role is set to `master` otherwise `50`)
|
||||
* `keepalived_ip` : Address added or deleted on change to MASTER/BACKUP. This is mandatory (default: none)
|
||||
* `keepalived_password` : Password for accessing vrrpd. Should be the same on all machines. This is mandatory (default: none)
|
6
keepalived/defaults/main.yml
Normal file
6
keepalived/defaults/main.yml
Normal file
|
@ -0,0 +1,6 @@
|
|||
keepalived_interface: "{{ ansible_default_ipv4.interface }}"
|
||||
keepalived_role: "master"
|
||||
keepalived_router_id: "42"
|
||||
keepalived_priority: "{% if keepalived_role == 'master' %}100{% else %}50{% endif %}"
|
||||
keepalived_ip: ""
|
||||
keepalived_password: ""
|
53
keepalived/files/check_keepalived
Normal file
53
keepalived/files/check_keepalived
Normal file
|
@ -0,0 +1,53 @@
|
|||
#!/bin/bash
|
||||
|
||||
###############################################################
|
||||
# Check Keepalived State #
|
||||
# #
|
||||
# Author: Zhivko Todorov <ztodorov@neterra.net> #
|
||||
# Date: 01-Dec-2015 #
|
||||
# Version: 0.0.1 #
|
||||
# License: GPL #
|
||||
###############################################################
|
||||
|
||||
|
||||
# set to 'true' if the host is supposed to be in MASTER state
|
||||
# or set to 'false' if the host is supposed to be in BACKUP state
|
||||
# nrpe cannot receive external variables UNLESS is forced in config
|
||||
MASTER='true'
|
||||
|
||||
# checking if there are alive keepalived processes so we can trust the content of the notify 'state' file
|
||||
KEEPALIVENUM=`ps uax|grep '/usr/sbin/keepalived'|grep -v grep|wc -l|tr -d "\n"`
|
||||
|
||||
if [ $KEEPALIVENUM -gt 0 ]; then
|
||||
|
||||
KEEPALIVESTATE=`cat /var/run/keepalive.state`
|
||||
|
||||
if [ "$MASTER" == "true" ]; then
|
||||
|
||||
if [[ $KEEPALIVESTATE == *"MASTER"* ]];then
|
||||
echo $KEEPALIVESTATE
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ $KEEPALIVESTATE == *"BACKUP"* ]];then
|
||||
echo $KEEPALIVESTATE
|
||||
exit 2
|
||||
fi
|
||||
|
||||
else
|
||||
|
||||
if [[ $KEEPALIVESTATE == *"BACKUP"* ]];then
|
||||
echo $KEEPALIVESTATE
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ $KEEPALIVESTATE == *"MASTER"* ]];then
|
||||
echo $KEEPALIVESTATE
|
||||
exit 2
|
||||
fi
|
||||
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "Keepalived is in UNKNOWN state"
|
||||
exit 3
|
2
keepalived/files/notify.sh
Normal file
2
keepalived/files/notify.sh
Normal file
|
@ -0,0 +1,2 @@
|
|||
#!/bin/bash
|
||||
echo $1 $2 is in $3 state > /var/run/keepalive.state
|
10
keepalived/handlers/main.yml
Normal file
10
keepalived/handlers/main.yml
Normal file
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
- name: restart keepalived
|
||||
systemd:
|
||||
name: keepalived
|
||||
state: restarted
|
||||
|
||||
- name: restart nagios-nrpe-server
|
||||
service:
|
||||
name: nagios-nrpe-server
|
||||
state: restarted
|
59
keepalived/tasks/main.yml
Normal file
59
keepalived/tasks/main.yml
Normal file
|
@ -0,0 +1,59 @@
|
|||
- name: install Keepalived service
|
||||
apt:
|
||||
pkg: keepalived
|
||||
state: present
|
||||
tags:
|
||||
- keepalived
|
||||
|
||||
- name: Add notify.sh script for NRPE check
|
||||
file:
|
||||
src: notify.sh
|
||||
dest: /etc/keepalived/notify.sh
|
||||
mode: "0755"
|
||||
owner: root
|
||||
group: root
|
||||
force: yes
|
||||
notify: restart keepalived
|
||||
tags:
|
||||
- keepalived
|
||||
- nrpe
|
||||
|
||||
- name: check_keepalived is installed
|
||||
file:
|
||||
src: check_keepalived
|
||||
dest: /usr/local/lib/nagios/plugins/check_keepalived
|
||||
mode: "0755"
|
||||
owner: root
|
||||
group: root
|
||||
force: yes
|
||||
tags:
|
||||
- keepalived
|
||||
- nrpe
|
||||
|
||||
- name: Use check_keepalived for NRPE
|
||||
lineinfile:
|
||||
dest: /etc/nagios/nrpe.d/evolix.cfg
|
||||
regexp: 'command\[check_keepalived\]'
|
||||
replace: 'command[check_keepalived]=/usr/local/lib/nagios/plugins/check_keepalived'
|
||||
notify: restart nagios-nrpe-server
|
||||
tags:
|
||||
- keepalived
|
||||
- nrpe
|
||||
|
||||
- name: generate Keepalived configuration
|
||||
template:
|
||||
src: keepalived.conf.j2
|
||||
dest: /etc/keepalived/keepalived.conf
|
||||
mode: 0644
|
||||
notify: restart keepalived
|
||||
tags:
|
||||
- keepalived
|
||||
|
||||
- name: enable and restart Keepalived service
|
||||
systemd:
|
||||
name: keepalived
|
||||
daemon_reload: yes
|
||||
state: started
|
||||
enabled: yes
|
||||
tags:
|
||||
- keepalived
|
30
keepalived/templates/keepalived.conf.j2
Normal file
30
keepalived/templates/keepalived.conf.j2
Normal file
|
@ -0,0 +1,30 @@
|
|||
# {{ ansible_managed }}
|
||||
|
||||
vrrp_script chk_sshd {
|
||||
script "/usr/bin/pkill -0 sshd"
|
||||
interval 5
|
||||
weight -4
|
||||
fall 2
|
||||
rise 1
|
||||
}
|
||||
|
||||
vrrp_instance vrrp {
|
||||
interface {{ keepalived_interface | mandatory }}
|
||||
virtual_router_id {{ keepalived_router_id | mandatory }}
|
||||
state {{ keepalived_role | upper }}
|
||||
priority {{ keepalived_priority }}
|
||||
|
||||
virtual_ipaddress {
|
||||
{{ keepalived_ip | mandatory }}
|
||||
}
|
||||
|
||||
authentication {
|
||||
auth_type PASS
|
||||
auth_pass {{ keepalived_password | mandatory }}
|
||||
}
|
||||
|
||||
track_script {
|
||||
chk_sshd
|
||||
}
|
||||
notify /etc/keepalived/notify.sh
|
||||
}
|
|
@ -238,3 +238,27 @@ echo "$downloadstatus" | grep -q 'Download complete and in download only mode'
|
|||
if [ $? -ne 0 ]; then
|
||||
echo "$downloadstatus"
|
||||
fi;
|
||||
|
||||
|
||||
# Also, we try to update each container apt sources
|
||||
if which lxc-ls > /dev/null; then
|
||||
for container in $(lxc-ls); do
|
||||
|
||||
aptUpdateOutput=$(lxc-attach -n $container -- apt update 2>&1 | (egrep -ve '^(Listing|WARNING|$)' -e upgraded -e 'up to date' || true ))
|
||||
|
||||
if (echo "$aptUpdateOutput" | egrep "^Err(:[0-9]+)? http"); then
|
||||
echo "FATAL CONTAINER - Not able to fetch all sources (probably a pesky (mini)firewall). Please, fix me"
|
||||
exit 150
|
||||
fi
|
||||
|
||||
# Now we try to fetch all the packages for the next update session
|
||||
downloadstatus=$(lxc-attach -n $container -- apt dist-upgrade --assume-yes --download-only -q2 2>&1)
|
||||
echo "$downloadstatus" | grep -q 'Download complete and in download only mode'
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "$downloadstatus"
|
||||
fi;
|
||||
|
||||
done
|
||||
fi
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ php_conf_allow_url_fopen: "Off"
|
|||
php_conf_disable_functions: "exec,shell-exec,system,passthru,popen"
|
||||
|
||||
# Allows accessing a local mysql database using localhost
|
||||
lxc_php_create_mysql_link: False
|
||||
php_conf_mysql_socket_dir: /mysqld
|
||||
php_conf_mysql_default_socket: "{{ php_conf_mysql_socket_dir }}/mysqld.sock"
|
||||
|
||||
|
@ -17,3 +18,4 @@ lxc_php_container_releases:
|
|||
php56: "jessie"
|
||||
php70: "stretch"
|
||||
php73: "buster"
|
||||
php74: "buster"
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
---
|
||||
- name: Reload php74-fpm
|
||||
lxc_container:
|
||||
name: "{{ lxc_php_version }}"
|
||||
container_command: "systemctl reload php7.4-fpm"
|
||||
|
||||
- name: Reload php73-fpm
|
||||
lxc_container:
|
||||
name: "{{ lxc_php_version }}"
|
||||
|
|
|
@ -18,4 +18,7 @@
|
|||
- include: "php73.yml"
|
||||
when: lxc_php_version == "php73"
|
||||
|
||||
- include: "php74.yml"
|
||||
when: lxc_php_version == "php74"
|
||||
|
||||
- include: "misc.yml"
|
||||
|
|
|
@ -28,6 +28,6 @@
|
|||
name: "{{ lxc_php_version }}"
|
||||
container_config:
|
||||
- "lxc.mount.entry = /run/mysqld {{ php_conf_mysql_socket_dir | replace('/', '', 1) }} none bind,create=dir 0 0"
|
||||
when: php_conf_mysql_socket_dir is string
|
||||
when: lxc_php_create_mysql_link and php_conf_mysql_socket_dir is string
|
||||
notify: "Restart container"
|
||||
|
||||
|
|
55
lxc-php/tasks/php74.yml
Normal file
55
lxc-php/tasks/php74.yml
Normal file
|
@ -0,0 +1,55 @@
|
|||
---
|
||||
|
||||
- name: "{{ lxc_php_version }} - Install dependency packages"
|
||||
lxc_container:
|
||||
name: "{{ lxc_php_version }}"
|
||||
container_command: "DEBIAN_FRONTEND=noninteractive apt install -y wget apt-transport-https gnupg"
|
||||
|
||||
- name: "{{ lxc_php_version }} - Add sury repo"
|
||||
lineinfile:
|
||||
dest: "/var/lib/lxc/{{ lxc_php_version }}/rootfs/etc/apt/sources.list.d/sury.list"
|
||||
line: "{{ item }}"
|
||||
state: present
|
||||
create: yes
|
||||
mode: "0644"
|
||||
with_items:
|
||||
- "deb https://packages.sury.org/php/ buster main"
|
||||
- "deb http://pub.evolix.net/ buster-php74/"
|
||||
|
||||
- name: Grab pub.evolix.net GPG Key
|
||||
get_url:
|
||||
url: https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x0C016D3BD1195D30105837CC44975278B8612B5D
|
||||
dest: /var/lib/lxc/{{ lxc_php_version }}/rootfs/etc/apt/trusted.gpg.d/reg.asc
|
||||
mode: 0644
|
||||
checksum: sha256:a2e0f56ba433aa0740aad6eeeb43bb67df9ab943d76324382b39948a4c7ce840
|
||||
|
||||
- name: Grab packages.sury.org GPG Key
|
||||
get_url:
|
||||
url: https://packages.sury.org/php/apt.gpg
|
||||
dest: /var/lib/lxc/{{ lxc_php_version }}/rootfs/etc/apt/trusted.gpg.d/sury.gpg
|
||||
mode: 0644
|
||||
checksum: sha256:b3ea944563435e54bb64f181ee8bc26200985d09164cdc4c1702fc3ef051f19d
|
||||
|
||||
- name: "{{ lxc_php_version }} - Update APT cache"
|
||||
lxc_container:
|
||||
name: "{{ lxc_php_version }}"
|
||||
container_command: "DEBIAN_FRONTEND=noninteractive apt update"
|
||||
|
||||
- name: "{{ lxc_php_version }} - Install PHP packages"
|
||||
lxc_container:
|
||||
name: "{{ lxc_php_version }}"
|
||||
container_command: "DEBIAN_FRONTEND=noninteractive apt install -y php-fpm php-cli php-gd php-intl php-imap php-ldap php-mysql php-pgsql php-sqlite3 php-gettext php-curl php-zip php-mbstring php-zip composer libphp-phpmailer"
|
||||
|
||||
- name: "{{ lxc_php_version }} - Copy evolinux PHP configuration"
|
||||
template:
|
||||
src: z-evolinux-defaults.ini.j2
|
||||
dest: "{{ line_item }}"
|
||||
mode: "0644"
|
||||
notify: "Reload {{ lxc_php_version }}-fpm"
|
||||
with_items:
|
||||
- "/var/lib/lxc/{{ lxc_php_version }}/rootfs/etc/php/7.4/fpm/conf.d/z-evolinux-defaults.ini"
|
||||
- "/var/lib/lxc/{{ lxc_php_version }}/rootfs/etc/php/7.4/cli/conf.d/z-evolinux-defaults.ini"
|
||||
loop_control:
|
||||
loop_var: line_item
|
||||
|
||||
- include: "mail_opensmtpd.yml"
|
|
@ -7,12 +7,17 @@ metricbeat_elasticsearch_protocol: ""
|
|||
metricbeat_elasticsearch_auth_api_key: ""
|
||||
metricbeat_elasticsearch_auth_username: ""
|
||||
metricbeat_elasticsearch_auth_password: ""
|
||||
metricbeat_elasticsearch_ssl: False
|
||||
metricbeat_elasticsearch_ssl_certificate_authorities: []
|
||||
metricbeat_elasticsearch_ssl_certificate: ""
|
||||
metricbeat_elasticsearch_ssl_verification_mode: ""
|
||||
|
||||
metricbeat_processors_cloud_metadata: False
|
||||
|
||||
metricbeat_use_config_template: False
|
||||
metricbeat_update_config: True
|
||||
metricbeat_force_config: True
|
||||
metribeat_upgrade_package: False
|
||||
|
||||
# Example :
|
||||
# metricbeat_tags:
|
||||
|
|
|
@ -30,7 +30,8 @@
|
|||
- name: Metricbeat is installed
|
||||
apt:
|
||||
name: metricbeat
|
||||
state: present
|
||||
state: "{% if metribeat_upgrade_package %}latest{% else %}present{% endif %}"
|
||||
notify: restart metricbeat
|
||||
tags:
|
||||
- metricbeat
|
||||
- packages
|
||||
|
@ -39,6 +40,7 @@
|
|||
systemd:
|
||||
name: metricbeat
|
||||
enabled: yes
|
||||
notify: restart metricbeat
|
||||
|
||||
# When we don't use a config template (default)
|
||||
- block:
|
||||
|
|
|
@ -112,6 +112,18 @@ output.elasticsearch:
|
|||
{% if metricbeat_elasticsearch_auth_password %}
|
||||
password: "{{ metricbeat_elasticsearch_auth_password }}"
|
||||
{% endif %}
|
||||
{% if metricbeat_elasticsearch_ssl %}
|
||||
ssl.enabled: true
|
||||
{% if metricbeat_elasticsearch_ssl_certificate_authorities != [] %}
|
||||
ssl.certificate_authorities: ["{{ metricbeat_elasticsearch_ssl_certificate_authorities | join('", "') }}"]
|
||||
{% endif %}
|
||||
{% if metricbeat_elasticsearch_ssl_certificate %}
|
||||
ssl.certificate: "{{ metricbeat_elasticsearch_ssl_certificate }}"
|
||||
{% endif %}
|
||||
{% if metricbeat_elasticsearch_ssl_verification_mode %}
|
||||
ssl.verification_mode: "{{ metricbeat_elasticsearch_ssl_verification_mode }}"
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
# ------------------------------ Logstash Output -------------------------------
|
||||
#output.logstash:
|
||||
|
|
|
@ -18,7 +18,7 @@ DOCKER='off'
|
|||
INTLAN='192.168.0.2/32'
|
||||
|
||||
# Trusted IPv4 addresses for private and semi-public services
|
||||
TRUSTEDIPS='62.212.121.90 88.179.18.233 31.170.8.4 31.170.9.129'
|
||||
TRUSTEDIPS='31.170.9.129 62.212.121.90 31.170.8.4 82.65.34.85 54.37.106.210 51.210.84.146'
|
||||
|
||||
# Privilegied IPv4 addresses for semi-public services
|
||||
# (no need to add again TRUSTEDIPS)
|
||||
|
@ -30,15 +30,15 @@ PRIVILEGIEDIPS=''
|
|||
|
||||
# Protected services
|
||||
# (add also in Public services if needed)
|
||||
SERVICESTCP1p='22'
|
||||
SERVICESTCP1p='22222'
|
||||
SERVICESUDP1p=''
|
||||
|
||||
# Public services (IPv4/IPv6)
|
||||
SERVICESTCP1='25 53 443 993 995 22222'
|
||||
SERVICESUDP1='53'
|
||||
SERVICESTCP1='22222'
|
||||
SERVICESUDP1=''
|
||||
|
||||
# Semi-public services (IPv4)
|
||||
SERVICESTCP2='20 21 22 80 110 143'
|
||||
SERVICESTCP2='22'
|
||||
SERVICESUDP2=''
|
||||
|
||||
# Private services (IPv4)
|
||||
|
@ -55,7 +55,7 @@ DNSSERVEURS='0.0.0.0/0'
|
|||
# HTTP authorizations
|
||||
# (you can use DNS names but set cron to reload minifirewall regularly)
|
||||
# (if you have HTTP proxy, set 0.0.0.0/0)
|
||||
# HTTPSITES='security.debian.org security-cdn.debian.org pub.evolix.net volatile.debian.org mirror.evolix.org backports.debian.org hwraid.le-vert.net antispam00.evolix.org spamassassin.apache.org sa-update.space-pro.be sa-update.secnap.net www.sa-update.pccc.com sa-update.dnswl.org'
|
||||
# HTTPSITES='security.debian.org pub.evolix.net security-cdn.debian.org mirror.evolix.org backports.debian.org hwraid.le-vert.net antispam00.evolix.org spamassassin.apache.org sa-update.space-pro.be sa-update.secnap.net www.sa-update.pccc.com sa-update.dnswl.org ocsp.int-x3.letsencrypt.org'
|
||||
HTTPSITES='0.0.0.0/0'
|
||||
|
||||
# HTTPS authorizations
|
||||
|
|
82
nagios-nrpe/files/plugins/check_phpfpm_multi
Normal file
82
nagios-nrpe/files/plugins/check_phpfpm_multi
Normal file
|
@ -0,0 +1,82 @@
|
|||
#!/bin/bash
|
||||
|
||||
|
||||
function detect_pool_dir() {
|
||||
# Try to autodetect pool directory
|
||||
php_version=$(php --version |head -n1 | sed -E 's/^PHP ([0-9]\.[0-9]).*/\1/g')
|
||||
|
||||
if [[ $php_version =~ ^5. ]]; then
|
||||
echo "/etc/php5/fpm/pool.d/";
|
||||
else
|
||||
echo "/etc/php/$php_version/fpm/pool.d/";
|
||||
fi
|
||||
}
|
||||
|
||||
return=0
|
||||
nb_crit=0
|
||||
nb_warn=0
|
||||
nb_ok=0
|
||||
nb_unchk=0
|
||||
output=""
|
||||
|
||||
readonly POOL_FOLDER=${1:-$(detect_pool_dir)}
|
||||
|
||||
if [[ ! -d "$POOL_FOLDER" ]]; then
|
||||
echo "CRITICAL - $POOL_FOLDER does not exists"
|
||||
exit 2
|
||||
fi;
|
||||
|
||||
readonly POOL_FILES=$(find "$POOL_FOLDER" -name "*.conf")
|
||||
|
||||
for pool_file in $POOL_FILES; do
|
||||
|
||||
pool_name=$(grep "^\[" "$pool_file" | sed -E 's/^\[(.*)\].*$/\1/g')
|
||||
pool_status_path=$(grep -E "^pm.status_path\s?=" "$pool_file" | sed -E "s/.*=\s?'?([^']*)'?\s?$/\1/g")
|
||||
pool_listen=$(grep -E "^listen\s?=" "$pool_file" | sed -E 's/.*=\s?(.*)\s?$/\1/g')
|
||||
|
||||
if [[ "$pool_status_path" == '' ]]; then
|
||||
nb_unchk=$((nb_unchk + 1))
|
||||
output="${output}UNCHK - ${pool_name} (missing pm.status_path definition)\n"
|
||||
|
||||
continue;
|
||||
fi;
|
||||
|
||||
if [[ -S "$pool_listen" ]] || [[ ! "$pool_listen" =~ ':' ]]; then
|
||||
target=(-H 127.0.0.1 --unix "$pool_listen")
|
||||
else
|
||||
target=(-H "$(echo "$pool_listen" | cut -d':' -f1)" -p "$(echo "$pool_listen" | cut -d':' -f2 )")
|
||||
fi
|
||||
|
||||
result=$(perl /usr/local/lib/nagios/plugins/check_phpfpm_status.pl "${target[@]}" -u "$pool_status_path")
|
||||
ret="${?}"
|
||||
|
||||
if [ "${ret}" -ge 2 ]; then
|
||||
nb_crit=$((nb_crit + 1))
|
||||
output="${output}${result}\n"
|
||||
[ "${return}" -le 2 ] && return=2
|
||||
elif [ "${ret}" -ge 1 ]; then
|
||||
nb_warn=$((nb_warn + 1))
|
||||
output="${output}${result}\n"
|
||||
[ "${return}" -le 1 ] && return=1
|
||||
else
|
||||
nb_ok=$((nb_ok + 1))
|
||||
output="${output}$(echo "$result" | cut -d '|' -f1)\n"
|
||||
[ "${return}" -le 0 ] && return=0
|
||||
fi
|
||||
|
||||
|
||||
done;
|
||||
|
||||
|
||||
[ "${return}" -ge 0 ] && header="OK"
|
||||
[ "${return}" -ge 1 ] && header="WARNING"
|
||||
[ "${return}" -ge 2 ] && header="CRITICAL"
|
||||
|
||||
printf "%s - %s UNCHK / %s CRIT / %s WARN / %s OK\n\n" "${header}" "${nb_unchk}" "${nb_crit}" "${nb_warn}" "${nb_ok}"
|
||||
|
||||
printf "%b" "${output}" | grep -E "(CRITICAL|UNKNOWN)"
|
||||
printf "%b" "${output}" | grep -E "WARNING"
|
||||
printf "%b" "${output}" | grep -E "OK"
|
||||
printf "%b" "${output}" | grep -E "^UNCHK"
|
||||
|
||||
exit "${return}"
|
|
@ -1,6 +1,6 @@
|
|||
#!/usr/bin/env perl
|
||||
# check_phpfpm_status.pl
|
||||
# Version : 1.0
|
||||
# Version : 1.1
|
||||
# Author : regis.leroy at makina-corpus.com
|
||||
# based on previous apache status work by Dennis D. Spreen (dennis at spreendigital.de)
|
||||
# Based on check_apachestatus.pl v1.4 by
|
||||
|
@ -13,6 +13,7 @@
|
|||
# help : ./check_phpfpm_status.pl -h
|
||||
#
|
||||
# issues & updates: http://github.com/regilero/check_phpfpm_status
|
||||
# Unix socket support from https://github.com/magenbrot/check_phpfpm_status/tree/unix-socket-support
|
||||
use strict;
|
||||
use warnings;
|
||||
use Getopt::Long;
|
||||
|
@ -26,13 +27,13 @@ package main;
|
|||
binmode(STDOUT, ":utf8");
|
||||
|
||||
# Globals
|
||||
my $Version='1.0';
|
||||
my $Name=$0;
|
||||
my $Version= '1.1';
|
||||
my $Name= $0;
|
||||
|
||||
my $o_host = undef; # hostname
|
||||
my $o_host= undef; # hostname
|
||||
my $o_help= undef; # want some help ?
|
||||
my $o_port= undef; # port
|
||||
my $o_url = undef; # url to use, if not the default
|
||||
my $o_url= undef; # url to use, if not the default
|
||||
my $o_user= undef; # user for auth
|
||||
my $o_pass= ''; # password for auth
|
||||
my $o_realm= ''; # password for auth
|
||||
|
@ -44,34 +45,35 @@ my $o_crit_q_level= -1; # Number of Max Queue Reached that will cause an err
|
|||
my $o_warn_m_level= -1; # Number of Max Processes Reached that will cause a warning
|
||||
my $o_crit_m_level= -1; # Number of Max Processes Reached that will cause an error
|
||||
my $o_timeout= 15; # Default 15s Timeout
|
||||
my $o_warn_thresold=undef; # warning thresolds entry
|
||||
my $o_crit_thresold=undef; # critical thresolds entry
|
||||
my $o_warn_threshold= undef; # warning thresholds entry
|
||||
my $o_crit_threshold= undef; # critical thresholds entry
|
||||
my $o_debug= undef; # debug mode
|
||||
my $o_fastcgi= undef; # direct fastcgi mode (without an http->fastcgi proxy)
|
||||
my $o_unixsocket= undef; # use a UNIX socket (in direct fastcgi mode)
|
||||
my $o_servername= undef; # ServerName (host header in http request)
|
||||
my $o_https= undef; # SSL (HTTPS) mode
|
||||
my $o_verify_ssl= 0; # SSL verification, False by default
|
||||
my $o_cacert_file= undef; # Path to cacert.pem file
|
||||
|
||||
my $TempPath = '/tmp/'; # temp path
|
||||
my $MaxUptimeDif = 60*30; # Maximum uptime difference (seconds), default 30 minutes
|
||||
my $TempPath= '/tmp/'; # temp path
|
||||
my $MaxUptimeDif= 60*30; # Maximum uptime difference (seconds), default 30 minutes
|
||||
|
||||
my $phpfpm = 'PHP-FPM'; # Could be used to store version also
|
||||
my $phpfpm= 'PHP-FPM'; # Could be used to store version also
|
||||
|
||||
# functions
|
||||
sub show_versioninfo { print "$Name version : $Version\n"; }
|
||||
|
||||
sub print_usage {
|
||||
print "Usage: $Name -H <host ip> [-p <port>] [-s servername] [-t <timeout>] [-w <WARN_THRESOLD> -c <CRIT_THRESOLD>] [-V] [-d] [-f] [-u <url>] [-U user -P pass -r realm]\n";
|
||||
print "Usage: $Name -H <host ip> [-p <port>] [-s servername] [-t <timeout>] [-w <WARN_THRESHOLD> -c <CRIT_THRESHOLD>] [-V] [-d] [-f] [-u <url>] [-U user -P pass -r realm]\n";
|
||||
}
|
||||
sub nagios_exit {
|
||||
my ( $nickname, $status, $message, $perfdata , $silent) = @_;
|
||||
my %STATUSCODE = (
|
||||
'OK' => 0
|
||||
, 'WARNING' => 1
|
||||
, 'CRITICAL' => 2
|
||||
, 'UNKNOWN' => 3
|
||||
, 'PENDING' => 4
|
||||
'OK' => 0,
|
||||
'WARNING' => 1,
|
||||
'CRITICAL' => 2,
|
||||
'UNKNOWN' => 3,
|
||||
'PENDING' => 4,
|
||||
);
|
||||
if(!defined($silent)) {
|
||||
my $output = undef;
|
||||
|
@ -100,13 +102,15 @@ sub help {
|
|||
-H, --hostname=HOST
|
||||
name or IP address of host to check
|
||||
-p, --port=PORT
|
||||
Http port, or Fastcgi port when using --fastcgi
|
||||
HTTP port, or Fastcgi port when using --fastcgi
|
||||
-u, --url=URL
|
||||
Specific URL (only the path part of it in fact) to use, instead of the default "/fpm-status"
|
||||
-s, --servername=SERVERNAME
|
||||
ServerName, (host header of HTTP request) use it if you specified an IP in -H to match the good Virtualhost in your target
|
||||
-f, --fastcgi
|
||||
Connect directly to php-fpm via network or local socket, using fastcgi protocol instead of HTTP.
|
||||
--unixsocket
|
||||
Connect to php-fpm via UNIX socket, implies --fastcgi
|
||||
-U, --user=user
|
||||
Username for basic auth
|
||||
-P, --pass=PASS
|
||||
|
@ -114,7 +118,7 @@ sub help {
|
|||
-r, --realm=REALM
|
||||
Realm for basic auth
|
||||
-d, --debug
|
||||
Debug mode (show http request response)
|
||||
Debug mode (show request response)
|
||||
-t, --timeout=INTEGER
|
||||
timeout in seconds (Default: $o_timeout)
|
||||
-S, --ssl
|
||||
|
@ -136,50 +140,56 @@ sub help {
|
|||
prints version number
|
||||
|
||||
Note :
|
||||
3 items can be managed on this check, this is why -w and -c parameters are using 3 values thresolds
|
||||
- MIN_AVAILABLE_PROCESSES: Working with the number of available (Idle) and working process (Busy).
|
||||
3 items can be managed on this check, this is why -w and -c parameters are using 3 values thresholds
|
||||
- MIN_AVAILABLE_PROCESSES: Working with the number of available (Idle) and working processes (Busy).
|
||||
Generating WARNING and CRITICAL if you do not have enough Idle processes.
|
||||
- PROC_MAX_REACHED: the fpm-status report will show us how many times the max processes were reached sinc start,
|
||||
this script will record how many time this happended since last check, letting you fix thresolds for alerts
|
||||
- PROC_MAX_REACHED: the fpm-status report will show us how many times the max processes were reached since start,
|
||||
this script will record how many times this happened since last check, letting you fix thresholds for alerts
|
||||
- QUEUE_MAX_REACHED: the php-fpm report will show us how many times the max queue was reached since start,
|
||||
this script will record how many time this happended since last check, letting you fix thresolds for alerts
|
||||
this script will record how many times this happened since last check, letting you fix thresholds for alerts
|
||||
|
||||
Examples:
|
||||
|
||||
This will lead to CRITICAL if you have 0 Idle process, or you have reached the max processes 2 times between last check,
|
||||
or you have reached the max queue len 5 times. A Warning will be reached for 1 Idle process only:
|
||||
This will lead to CRITICAL if you have 0 idle processes or you reached the max processes 2 times between last check,
|
||||
or you reached the max queue len 5 times. A warning will be generated for 1 idle process only:
|
||||
|
||||
check_phpfpm_status.pl -H 10.0.0.10 -u /foo/my-fpm-status -s mydomain.example.com -t 8 -w 1,-1,-1 -c 0,2,5
|
||||
|
||||
this will generate WARNING and CRITICAL alerts only on the number of times you have reached the max process:
|
||||
This will generate WARNING and CRITICAL alerts only on the number of times you have reached the max processes:
|
||||
|
||||
check_phpfpm_status.pl -H 10.0.0.10 -u /foo/my-fpm-status -s mydomain.example.com -t 8 -w -1,10,-1 -c -1,20,-1
|
||||
|
||||
theses two equivalents will not generate any alert (if the php-fpm page is reachable) but could be used for graphics:
|
||||
These two equivalents will not generate any alert (if the php-fpm page is reachable) but could be used for graphing:
|
||||
|
||||
check_phpfpm_status.pl -H 10.0.0.10 -s mydomain.example.com -w -1,-1,-1 -c -1,-1,-1
|
||||
check_phpfpm_status.pl -H 10.0.0.10 -s mydomain.example.com
|
||||
|
||||
And this one is a basic starting example :
|
||||
And this one is a basic starting example:
|
||||
|
||||
check_phpfpm_status.pl -H 127.0.0.1 -s nagios.example.com -w 1,1,1 -c 0,2,2
|
||||
|
||||
All these examples used an HTTP proxy (like Nginx or Apache) in front of php-fpm. If php-fpm is listening on a tcp/ip socket
|
||||
you can also make a direct request on this port (9000 by default) using the fastcgi protocol. You'll need the FastCGI client
|
||||
tools enabled in Perl (check the README) and the command would use the -f or --fastcgi option (note that SSL or servername
|
||||
options are useless in this mode).
|
||||
This can be especially usefull if you use php-fpm in an isolated env, without the HTTP proxy support (like in a docker container):
|
||||
you can also make a direct request on this port (9000 by default) or to an UNIX socket by using the fastcgi protocol. You'll
|
||||
need the FastCGI client tools enabled in Perl (check the README) and the command would use the -f or --fastcgi and eventually
|
||||
the --unixsocket option (note that SSL or servername options are useless in this mode).
|
||||
This can be especially usefull if you use php-fpm in an isolated env, without the HTTP proxy support (like in a docker container).
|
||||
|
||||
Connect to an INET socket on port 9002:
|
||||
|
||||
check_phpfpm_status.pl -H 127.0.0.1 --fastcgi -p 9002 -w 1,1,1 -c 0,2,2
|
||||
|
||||
Connect to the UNIX socket listening in /run/php/php-fpm.sock with a non-standard URL:
|
||||
|
||||
check_phpfpm_status.pl -H 127.0.0.1 --fastcgi --unixsocket /run/php/php-fpm.sock -u /secret-status -w 1,1,1 -c 0,2,2
|
||||
|
||||
HTTPS/SSL:
|
||||
|
||||
Adding --ssl you can reach an https host:
|
||||
|
||||
check_phpfpm_status.pl -H 10.0.0.10 -s mydomain.example.com --ssl
|
||||
|
||||
Check --verify-ssl (false by defaut) --cacert and --sl for more options, like below
|
||||
(note that certificate checks never wortked on my side, add -d for full debug and
|
||||
Check --verify-ssl (false by default) --cacert and --sl for more options, like below
|
||||
(note that certificate checks never worked on my side, add -d for full debug and
|
||||
tell me if it worked for you, you may need up to date CPAN adn openSSL libs)
|
||||
|
||||
check_phpfpm_status.pl -H 10.0.0.10 -s mydomain.example.com --ssl TLSv1_2 --verify-ssl 1 --cacert /etc/ssl/cacert.pem
|
||||
|
@ -193,6 +203,7 @@ sub check_options {
|
|||
'h' => \$o_help, 'help' => \$o_help,
|
||||
'd' => \$o_debug, 'debug' => \$o_debug,
|
||||
'f' => \$o_fastcgi, 'fastcgi' => \$o_fastcgi,
|
||||
'unixsocket:s' => \$o_unixsocket,
|
||||
'H:s' => \$o_host, 'hostname:s' => \$o_host,
|
||||
's:s' => \$o_servername, 'servername:s' => \$o_servername,
|
||||
'S:s' => \$o_https, 'ssl:s' => \$o_https,
|
||||
|
@ -202,8 +213,8 @@ sub check_options {
|
|||
'r:s' => \$o_realm, 'realm:s' => \$o_realm,
|
||||
'p:i' => \$o_port, 'port:i' => \$o_port,
|
||||
'V' => \$o_version, 'version' => \$o_version,
|
||||
'w=s' => \$o_warn_thresold, 'warn=s' => \$o_warn_thresold,
|
||||
'c=s' => \$o_crit_thresold, 'critical=s' => \$o_crit_thresold,
|
||||
'w=s' => \$o_warn_threshold, 'warn=s' => \$o_warn_threshold,
|
||||
'c=s' => \$o_crit_threshold, 'critical=s' => \$o_crit_threshold,
|
||||
't:i' => \$o_timeout, 'timeout:i' => \$o_timeout,
|
||||
'x:i' => \$o_verify_ssl, 'verifyhostname:i' => \$o_verify_ssl,
|
||||
'verifyssl:i' => \$o_verify_ssl,
|
||||
|
@ -219,34 +230,37 @@ sub check_options {
|
|||
nagios_exit($phpfpm,"UNKNOWN","leaving","",1);
|
||||
};
|
||||
|
||||
if (defined($o_warn_thresold)) {
|
||||
($o_warn_p_level,$o_warn_m_level,$o_warn_q_level) = split(',', $o_warn_thresold);
|
||||
if (defined($o_warn_threshold)) {
|
||||
($o_warn_p_level,$o_warn_m_level,$o_warn_q_level) = split(',', $o_warn_threshold);
|
||||
} else {
|
||||
$o_warn_thresold = 'undefined'
|
||||
$o_warn_threshold = 'undefined'
|
||||
}
|
||||
if (defined($o_crit_thresold)) {
|
||||
($o_crit_p_level,$o_crit_m_level,$o_crit_q_level) = split(',', $o_crit_thresold);
|
||||
if (defined($o_crit_threshold)) {
|
||||
($o_crit_p_level,$o_crit_m_level,$o_crit_q_level) = split(',', $o_crit_threshold);
|
||||
} else {
|
||||
$o_crit_thresold = 'undefined'
|
||||
$o_crit_threshold = 'undefined'
|
||||
}
|
||||
if (defined($o_fastcgi) && defined($o_https)) {
|
||||
nagios_exit($phpfpm,"UNKNOWN","You cannot use both --fastcgi and --ssl options, we do not use http (nor https) when we use direct fastcgi access!");
|
||||
}
|
||||
if (defined($o_unixsocket) && not defined($o_fastcgi)) {
|
||||
$o_fastcgi = 1;
|
||||
}
|
||||
if (defined($o_debug)) {
|
||||
print("\nDebug thresolds: \nWarning: ($o_warn_thresold) => Min Idle: $o_warn_p_level Max Reached :$o_warn_m_level MaxQueue: $o_warn_q_level");
|
||||
print("\nCritical ($o_crit_thresold) => : Min Idle: $o_crit_p_level Max Reached: $o_crit_m_level MaxQueue : $o_crit_q_level\n");
|
||||
print("\nDEBUG thresholds: \nWarning: ($o_warn_threshold) => Min Idle: $o_warn_p_level Max Reached :$o_warn_m_level MaxQueue: $o_warn_q_level");
|
||||
print("\nCritical ($o_crit_threshold) => : Min Idle: $o_crit_p_level Max Reached: $o_crit_m_level MaxQueue : $o_crit_q_level\n");
|
||||
}
|
||||
if ((defined($o_warn_p_level) && defined($o_crit_p_level)) &&
|
||||
(($o_warn_p_level != -1) && ($o_crit_p_level != -1) && ($o_warn_p_level <= $o_crit_p_level)) ) {
|
||||
nagios_exit($phpfpm,"UNKNOWN","Check warning and critical values for IdleProcesses (1st part of thresold), warning level must be > crit level!");
|
||||
nagios_exit($phpfpm,"UNKNOWN","Check warning and critical values for IdleProcesses (1st part of threshold), warning level must be > crit level!");
|
||||
}
|
||||
if ((defined($o_warn_m_level) && defined($o_crit_m_level)) &&
|
||||
(($o_warn_m_level != -1) && ($o_crit_m_level != -1) && ($o_warn_m_level >= $o_crit_m_level)) ) {
|
||||
nagios_exit($phpfpm,"UNKNOWN","Check warning and critical values for MaxProcesses (2nd part of thresold), warning level must be < crit level!");
|
||||
nagios_exit($phpfpm,"UNKNOWN","Check warning and critical values for MaxProcesses (2nd part of threshold), warning level must be < crit level!");
|
||||
}
|
||||
if ((defined($o_warn_q_level) && defined($o_crit_q_level)) &&
|
||||
(($o_warn_q_level != -1) && ($o_crit_q_level != -1) && ($o_warn_q_level >= $o_crit_q_level)) ) {
|
||||
nagios_exit($phpfpm,"UNKNOWN","Check warning and critical values for MaxQueue (3rd part of thresold), warning level must be < crit level!");
|
||||
nagios_exit($phpfpm,"UNKNOWN","Check warning and critical values for MaxQueue (3rd part of threshold), warning level must be < crit level!");
|
||||
}
|
||||
# Check compulsory attributes
|
||||
if (!defined($o_host)) {
|
||||
|
@ -280,22 +294,38 @@ if (!defined($o_url)) {
|
|||
}
|
||||
|
||||
if (defined($o_fastcgi)) {
|
||||
# -- FASTCGI
|
||||
# -- FASTCGI
|
||||
eval "use FCGI::Client::Connection;";
|
||||
nagios_exit($phpfpm,"UNKNOWN","You need to activate FCGI::Client::Connection CPAN module for this feature: " . $@) if $@;
|
||||
eval "use IO::Socket::INET";
|
||||
nagios_exit($phpfpm,"UNKNOWN","You need to activate IO::Socket::INET CPAN module for this feature: " . $@) if $@;
|
||||
|
||||
my $sock;
|
||||
if (defined($o_unixsocket)) {
|
||||
eval "use IO::Socket::UNIX;";
|
||||
nagios_exit($phpfpm,"UNKNOWN","You need to activate IO::Socket::UNIX CPAN module for this feature: " . $@) if $@;
|
||||
if (!-S $o_unixsocket) {
|
||||
nagios_exit($phpfpm,"UNKNOWN","$o_unixsocket is not an UNIX socket");
|
||||
}
|
||||
$sock = IO::Socket::UNIX->new(
|
||||
Type => SOCK_STREAM(),
|
||||
Peer => $o_unixsocket,
|
||||
);
|
||||
if (!$sock) {
|
||||
nagios_exit($phpfpm,"CRITICAL", "Cannot connect to UNIX socket $o_unixsocket !");
|
||||
}
|
||||
} else {
|
||||
eval "use IO::Socket::INET;";
|
||||
nagios_exit($phpfpm,"UNKNOWN","You need to activate IO::Socket::INET CPAN module for this feature: " . $@) if $@;
|
||||
if (!defined($o_port)) {
|
||||
$o_port = 9000;
|
||||
}
|
||||
my $sock = IO::Socket::INET->new(
|
||||
$sock = IO::Socket::INET->new(
|
||||
PeerAddr => $override_ip,
|
||||
PeerPort => $o_port,
|
||||
);
|
||||
if (!$sock) {
|
||||
nagios_exit($phpfpm,"CRITICAL", "Cannot connect to $override_ip : $o_port !");
|
||||
}
|
||||
}
|
||||
my $fastcgiClient = FCGI::Client::Connection->new(sock => $sock);
|
||||
$url = $o_url;
|
||||
my $sname = undef;
|
||||
|
@ -315,16 +345,16 @@ if (defined($o_fastcgi)) {
|
|||
''
|
||||
);
|
||||
if (defined ($o_debug)) {
|
||||
print "\nDEBUG: FASCGI requested url\n";
|
||||
print "\nDEBUG: FASTCGI requested url\n";
|
||||
print $url;
|
||||
print "\nDEBUG: FASCGI response: STDERR\n";
|
||||
print "\nDEBUG: FASTCGI response: STDERR\n";
|
||||
print $stderr;
|
||||
}
|
||||
$response = fcgi_response->new($stdout, $o_debug);
|
||||
} else {
|
||||
# -- HTTP
|
||||
# -- HTTP
|
||||
eval "use LWP::UserAgent;";
|
||||
nagios_exit($phpfpm,"UNKNOWN","You need to activate LWP::UserAgent CPAN module for this feature: " . $@) if $@;
|
||||
nagios_exit($phpfpm,"UNKNOWN","You need to install LWP::UserAgent CPAN module for this feature: " . $@) if $@;
|
||||
#use LWP::UserAgent;
|
||||
|
||||
my $proto='http://';
|
||||
|
@ -397,7 +427,7 @@ if (defined($o_fastcgi)) {
|
|||
|
||||
if (!defined($o_cacert_file)) {
|
||||
eval "use Mozilla::CA;";
|
||||
nagios_exit($phpfpm,"UNKNOWN","You need to activate Mozilla::CA CPAN module for this feature, or use --cacert option: " . $@) if $@;
|
||||
nagios_exit($phpfpm,"UNKNOWN","You need to install Mozilla::CA CPAN module for this feature, or use --cacert option: " . $@) if $@;
|
||||
$o_cacert_file = Mozilla::CA::SSL_ca_file();
|
||||
}
|
||||
#$ssl_opts{"SSL_ca_path"} = '/usr/share/ca-certificates/mozilla/';
|
||||
|
@ -572,7 +602,7 @@ if ($response->is_success) {
|
|||
$LastMaxListenQueue = <$FH>;
|
||||
close ($FH);
|
||||
if (defined ($o_debug)) {
|
||||
print ("\nDebug: data from temporary file:\n");
|
||||
print ("\nDEBUG: data from temporary file:\n");
|
||||
print ("LastUptime: $LastUptime LastAcceptedConn: $LastAcceptedConn LastMaxChildrenReached: $LastMaxChildrenReached LastMaxListenQueue: $LastMaxListenQueue \n");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
- name: packages are installed
|
||||
- name: base nrpe & plugins packages are installed
|
||||
apt:
|
||||
name:
|
||||
- nagios-nrpe-server
|
||||
|
@ -12,6 +12,18 @@
|
|||
tags:
|
||||
- nagios-nrpe
|
||||
|
||||
|
||||
- name: custom plugin dependencies packages are installed
|
||||
apt:
|
||||
name:
|
||||
- libfcgi-client-perl
|
||||
state: present
|
||||
when:
|
||||
- ansible_distribution == "Debian"
|
||||
- ansible_distribution_major_version is version('10', '>=')
|
||||
tags:
|
||||
- nagios-plugins
|
||||
|
||||
- name: custom configuration is present
|
||||
template:
|
||||
src: evolix.cfg.j2
|
||||
|
|
|
@ -70,6 +70,11 @@ command[check_haproxy]=sudo {{ nagios_plugins_directory }}/check_haproxy_stats -
|
|||
command[check_minifirewall]=sudo {{ nagios_plugins_directory }}/check_minifirewall
|
||||
command[check_redis_instances]={{ nagios_plugins_directory }}/check_redis_instances
|
||||
command[check_hpraid]={{ nagios_plugins_directory }}/check_hpraid
|
||||
command[check_php-fpm]={{ nagios_plugins_directory }}/check_phpfpm_multi
|
||||
command[check_php-fpm56]=sudo {{ nagios_plugins_directory }}/check_phpfpm_multi /var/lib/lxc/php56/rootfs/etc/php5/fpm/pool.d/
|
||||
command[check_php-fpm70]=sudo {{ nagios_plugins_directory }}/check_phpfpm_multi /var/lib/lxc/php70/rootfs/etc/php/7.0/fpm/pool.d/
|
||||
command[check_php-fpm73]=sudo {{ nagios_plugins_directory }}/check_phpfpm_multi /var/lib/lxc/php73/rootfs/etc/php/7.3/fpm/pool.d/
|
||||
command[check_php-fpm74]=sudo {{ nagios_plugins_directory }}/check_phpfpm_multi /var/lib/lxc/php74/rootfs/etc/php/7.4/fpm/pool.d/
|
||||
|
||||
# Check HTTP "many". Use this to check many websites (http, https, ports, sockets and SSL certificates).
|
||||
# Beware! All checks must not take more than 10s!
|
||||
|
|
|
@ -4,7 +4,7 @@ nginx_minimal: False
|
|||
# backward compatibility with a previously used variable
|
||||
nginx_backports: "{{ nginx_jessie_backports | default(false, true) }}"
|
||||
|
||||
nginx_package_name: "nginx-full"
|
||||
nginx_default_package_name: "nginx-full"
|
||||
|
||||
nginx_default_ipaddr_whitelist_ips: []
|
||||
nginx_additional_ipaddr_whitelist_ips: []
|
||||
|
|
|
@ -1,7 +1,152 @@
|
|||
---
|
||||
|
||||
- include: main_minimal.yml
|
||||
- debug:
|
||||
msg: "Nginx minimal mode has been removed, falling back to normal mode."
|
||||
when: nginx_minimal
|
||||
|
||||
- include: main_regular.yml
|
||||
when: not nginx_minimal
|
||||
- include: packages.yml
|
||||
|
||||
- include: server_status_read.yml
|
||||
tags:
|
||||
- nginx
|
||||
|
||||
# TODO: find a way to override the main configuration
|
||||
# without touching the main file
|
||||
|
||||
- name: customize worker_connections
|
||||
lineinfile:
|
||||
dest: /etc/nginx/nginx.conf
|
||||
regexp: '^(\s*worker_connections)\s+.+;'
|
||||
line: ' worker_connections 1024;'
|
||||
insertafter: 'events \{'
|
||||
tags:
|
||||
- nginx
|
||||
|
||||
- name: use epoll
|
||||
lineinfile:
|
||||
dest: /etc/nginx/nginx.conf
|
||||
regexp: '^(\s*use)\s+.+;'
|
||||
line: ' use epoll;'
|
||||
insertafter: 'events \{'
|
||||
tags:
|
||||
- nginx
|
||||
|
||||
- name: Install Nginx http configuration
|
||||
copy:
|
||||
src: nginx/evolinux-defaults.conf
|
||||
dest: /etc/nginx/conf.d/z-evolinux-defaults.conf
|
||||
mode: "0640"
|
||||
# force: yes
|
||||
notify: reload nginx
|
||||
tags:
|
||||
- nginx
|
||||
|
||||
# TODO: verify that those permissions are correct :
|
||||
# not too strict for ipaddr_whitelist
|
||||
# and not too loose for private_htpasswd
|
||||
|
||||
- name: Copy ipaddr_whitelist
|
||||
copy:
|
||||
src: nginx/snippets/ipaddr_whitelist
|
||||
dest: /etc/nginx/snippets/ipaddr_whitelist
|
||||
owner: www-data
|
||||
group: www-data
|
||||
directory_mode: "0640"
|
||||
mode: "0640"
|
||||
force: no
|
||||
notify: reload nginx
|
||||
tags:
|
||||
- nginx
|
||||
- ips
|
||||
|
||||
- name: Include IP address whitelist task
|
||||
include: ip_whitelist.yml
|
||||
|
||||
- name: Copy private_htpasswd
|
||||
copy:
|
||||
src: nginx/snippets/private_htpasswd
|
||||
dest: /etc/nginx/snippets/private_htpasswd
|
||||
owner: www-data
|
||||
group: www-data
|
||||
directory_mode: "0640"
|
||||
mode: "0640"
|
||||
force: no
|
||||
notify: reload nginx
|
||||
tags:
|
||||
- nginx
|
||||
|
||||
- name: add user:pwd to private htpasswd
|
||||
lineinfile:
|
||||
dest: /etc/nginx/snippets/private_htpasswd
|
||||
line: "{{ item }}"
|
||||
state: present
|
||||
with_items: "{{ nginx_private_htpasswd_present }}"
|
||||
notify: reload nginx
|
||||
tags:
|
||||
- nginx
|
||||
|
||||
- name: remove user:pwd from private htpasswd
|
||||
lineinfile:
|
||||
dest: /etc/nginx/snippets/private_htpasswd
|
||||
line: "{{ item }}"
|
||||
state: absent
|
||||
with_items: "{{ nginx_private_htpasswd_absent }}"
|
||||
notify: reload nginx
|
||||
tags:
|
||||
- nginx
|
||||
|
||||
- name: nginx vhost is installed
|
||||
template:
|
||||
src: "{{ nginx_default_template_regular }}"
|
||||
dest: /etc/nginx/sites-available/evolinux-default.conf
|
||||
mode: "0640"
|
||||
force: "{{ nginx_force_default_template | default(False) }}"
|
||||
notify: reload nginx
|
||||
tags:
|
||||
- nginx
|
||||
|
||||
- name: default vhost is enabled
|
||||
file:
|
||||
src: /etc/nginx/sites-available/evolinux-default.conf
|
||||
dest: /etc/nginx/sites-enabled/default
|
||||
state: link
|
||||
force: yes
|
||||
notify: reload nginx
|
||||
when: nginx_evolinux_default_enabled
|
||||
tags:
|
||||
- nginx
|
||||
|
||||
- include: server_status_write.yml
|
||||
tags:
|
||||
- nginx
|
||||
|
||||
- name: Verify that the service is enabled and started
|
||||
service:
|
||||
name: nginx
|
||||
enabled: yes
|
||||
state: started
|
||||
tags:
|
||||
- nginx
|
||||
|
||||
- name: Check if Munin is installed
|
||||
stat:
|
||||
path: /etc/munin/plugin-conf.d/munin-node
|
||||
check_mode: no
|
||||
register: stat_munin_node
|
||||
tags:
|
||||
- nginx
|
||||
- munin
|
||||
|
||||
- include: munin_vhost.yml
|
||||
when: stat_munin_node.stat.exists
|
||||
tags:
|
||||
- nginx
|
||||
- munin
|
||||
|
||||
- include: munin_graphs.yml
|
||||
when: stat_munin_node.stat.exists
|
||||
tags:
|
||||
- nginx
|
||||
- munin
|
||||
|
||||
- include: logrotate.yml
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
---
|
||||
- name: Ensure Nginx is installed
|
||||
apt:
|
||||
name:
|
||||
- nginx-light
|
||||
- ssl-cert
|
||||
state: present
|
||||
notify: reload nginx
|
||||
tags:
|
||||
- nginx
|
||||
- packages
|
||||
|
||||
- name: Copy default vhost
|
||||
template:
|
||||
src: "{{ nginx_default_template_minimal }}"
|
||||
dest: /etc/nginx/sites-available/evolinux-default.minimal.conf
|
||||
mode: 0644
|
||||
force: "{{ nginx_force_default_template | default(False) }}"
|
||||
notify: reload nginx
|
||||
tags:
|
||||
- nginx
|
||||
- packages
|
||||
|
||||
- name: Enable default vhost
|
||||
file:
|
||||
src: /etc/nginx/sites-available/evolinux-default.minimal.conf
|
||||
dest: /etc/nginx/sites-enabled/default
|
||||
state: link
|
||||
notify: reload nginx
|
||||
tags:
|
||||
- nginx
|
||||
- packages
|
||||
|
||||
- name: Ensure Nginx is enabled
|
||||
service:
|
||||
name: nginx
|
||||
state: started
|
||||
enabled: yes
|
||||
tags:
|
||||
- nginx
|
|
@ -1,182 +0,0 @@
|
|||
---
|
||||
|
||||
- include: packages.yml
|
||||
|
||||
- include: server_status_read.yml
|
||||
tags:
|
||||
- nginx
|
||||
|
||||
# TODO: find a way to override the main configuration
|
||||
# without touching the main file
|
||||
|
||||
- name: customize worker_connections
|
||||
lineinfile:
|
||||
dest: /etc/nginx/nginx.conf
|
||||
regexp: '^(\s*worker_connections)\s+.+;'
|
||||
line: ' worker_connections 1024;'
|
||||
insertafter: 'events \{'
|
||||
tags:
|
||||
- nginx
|
||||
|
||||
- name: use epoll
|
||||
lineinfile:
|
||||
dest: /etc/nginx/nginx.conf
|
||||
regexp: '^(\s*use)\s+.+;'
|
||||
line: ' use epoll;'
|
||||
insertafter: 'events \{'
|
||||
tags:
|
||||
- nginx
|
||||
|
||||
- name: Install Nginx http configuration
|
||||
copy:
|
||||
src: nginx/evolinux-defaults.conf
|
||||
dest: /etc/nginx/conf.d/z-evolinux-defaults.conf
|
||||
mode: "0640"
|
||||
# force: yes
|
||||
notify: reload nginx
|
||||
tags:
|
||||
- nginx
|
||||
|
||||
# TODO: verify that those permissions are correct :
|
||||
# not too strict for ipaddr_whitelist
|
||||
# and not too loose for private_htpasswd
|
||||
|
||||
- name: Copy ipaddr_whitelist
|
||||
copy:
|
||||
src: nginx/snippets/ipaddr_whitelist
|
||||
dest: /etc/nginx/snippets/ipaddr_whitelist
|
||||
owner: www-data
|
||||
group: www-data
|
||||
directory_mode: "0640"
|
||||
mode: "0640"
|
||||
force: no
|
||||
notify: reload nginx
|
||||
tags:
|
||||
- nginx
|
||||
- ips
|
||||
|
||||
- name: Include IP address whitelist task
|
||||
include: ip_whitelist.yml
|
||||
|
||||
- name: Copy private_htpasswd
|
||||
copy:
|
||||
src: nginx/snippets/private_htpasswd
|
||||
dest: /etc/nginx/snippets/private_htpasswd
|
||||
owner: www-data
|
||||
group: www-data
|
||||
directory_mode: "0640"
|
||||
mode: "0640"
|
||||
force: no
|
||||
notify: reload nginx
|
||||
tags:
|
||||
- nginx
|
||||
|
||||
- name: add user:pwd to private htpasswd
|
||||
lineinfile:
|
||||
dest: /etc/nginx/snippets/private_htpasswd
|
||||
line: "{{ item }}"
|
||||
state: present
|
||||
with_items: "{{ nginx_private_htpasswd_present }}"
|
||||
notify: reload nginx
|
||||
tags:
|
||||
- nginx
|
||||
|
||||
- name: remove user:pwd from private htpasswd
|
||||
lineinfile:
|
||||
dest: /etc/nginx/snippets/private_htpasswd
|
||||
line: "{{ item }}"
|
||||
state: absent
|
||||
with_items: "{{ nginx_private_htpasswd_absent }}"
|
||||
notify: reload nginx
|
||||
tags:
|
||||
- nginx
|
||||
|
||||
- name: nginx vhost is installed
|
||||
template:
|
||||
src: "{{ nginx_default_template_regular }}"
|
||||
dest: /etc/nginx/sites-available/evolinux-default.conf
|
||||
mode: "0640"
|
||||
force: "{{ nginx_force_default_template | default(False) }}"
|
||||
notify: reload nginx
|
||||
tags:
|
||||
- nginx
|
||||
|
||||
- name: default vhost is enabled
|
||||
file:
|
||||
src: /etc/nginx/sites-available/evolinux-default.conf
|
||||
dest: /etc/nginx/sites-enabled/default
|
||||
state: link
|
||||
force: yes
|
||||
notify: reload nginx
|
||||
when: nginx_evolinux_default_enabled
|
||||
tags:
|
||||
- nginx
|
||||
|
||||
- include: server_status_write.yml
|
||||
tags:
|
||||
- nginx
|
||||
|
||||
# - block:
|
||||
# - name: generate random string for phpmyadmin suffix
|
||||
# command: "apg -a 1 -M N -n 1"
|
||||
# changed_when: False
|
||||
# register: random_phpmyadmin_suffix
|
||||
#
|
||||
# - name: overwrite nginx_phpmyadmin_suffix
|
||||
# set_fact:
|
||||
# nginx_phpmyadmin_suffix: "{{ random_phpmyadmin_suffix.stdout }}"
|
||||
# when: nginx_phpmyadmin_suffix == ""
|
||||
#
|
||||
# - name: replace phpmyadmin suffix in default site index
|
||||
# replace:
|
||||
# dest: /var/www/index.html
|
||||
# regexp: '__PHPMYADMIN_SUFFIX__'
|
||||
# replace: "{{ nginx_phpmyadmin_suffix }}"
|
||||
#
|
||||
# - block:
|
||||
# - name: generate random string for serverstatus suffix
|
||||
# command: "apg -a 1 -M N -n 1"
|
||||
# changed_when: False
|
||||
# register: random_serverstatus_suffix
|
||||
#
|
||||
# - name: overwrite nginx_serverstatus_suffix
|
||||
# set_fact:
|
||||
# nginx_serverstatus_suffix: "{{ random_phpmyadmin_suffix.stdout }}"
|
||||
# when: nginx_serverstatus_suffix == ""
|
||||
#
|
||||
# - name: replace server-status suffix in default site index
|
||||
# replace:
|
||||
# dest: /var/www/index.html
|
||||
# regexp: '__SERVERSTATUS_SUFFIX__'
|
||||
# replace: "{{ nginx_serverstatus_suffix }}"
|
||||
|
||||
- name: Verify that the service is enabled and started
|
||||
service:
|
||||
name: nginx
|
||||
enabled: yes
|
||||
state: started
|
||||
tags:
|
||||
- nginx
|
||||
|
||||
- name: Check if Munin is installed
|
||||
stat:
|
||||
path: /etc/munin/plugin-conf.d/munin-node
|
||||
check_mode: no
|
||||
register: stat_munin_node
|
||||
tags:
|
||||
- nginx
|
||||
- munin
|
||||
|
||||
- include: munin_vhost.yml
|
||||
when: stat_munin_node.stat.exists
|
||||
tags:
|
||||
- nginx
|
||||
- munin
|
||||
|
||||
- include: munin_graphs.yml
|
||||
when: stat_munin_node.stat.exists
|
||||
tags:
|
||||
- nginx
|
||||
- munin
|
||||
|
||||
- include: logrotate.yml
|
|
@ -1,3 +1,9 @@
|
|||
|
||||
|
||||
- set_fact:
|
||||
nginx_package_name_default: nginx-light
|
||||
when: nginx_minimal
|
||||
|
||||
- include: packages_backports.yml
|
||||
when: nginx_backports
|
||||
|
||||
|
@ -5,7 +11,7 @@
|
|||
|
||||
- name: Ensure Nginx is installed
|
||||
apt:
|
||||
name: "{{ nginx_package_name }}"
|
||||
name: "{{ nginx_package_name | default(nginx_default_package_name) }}"
|
||||
state: present
|
||||
tags:
|
||||
- nginx
|
||||
|
|
|
@ -44,6 +44,11 @@ server {
|
|||
fastcgi_pass unix:/var/run/munin/spawn-fcgi-munin-graph.sock;
|
||||
include fastcgi_params;
|
||||
}
|
||||
|
||||
location /server-status-{{ nginx_serverstatus_suffix | mandatory }} {
|
||||
stub_status on;
|
||||
access_log off;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
server {
|
||||
listen 80 default_server;
|
||||
listen [::]:80 default_server;
|
||||
|
||||
listen 443 ssl default_server;
|
||||
listen [::]:443 ssl default_server;
|
||||
|
||||
if ($host != "{{ ansible_fqdn }}") {
|
||||
rewrite ^ https://{{ ansible_fqdn }}$request_uri permanent;
|
||||
}
|
||||
|
||||
include snippets/snakeoil.conf;
|
||||
|
||||
if ($https != "on") {
|
||||
return 301 https://{{ ansible_fqdn }}$request_uri;
|
||||
}
|
||||
|
||||
root /var/www/;
|
||||
|
||||
location /munin {
|
||||
alias /var/cache/munin/www;
|
||||
}
|
||||
|
||||
index index.html;
|
||||
|
||||
server_name _;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ =404;
|
||||
}
|
||||
}
|
|
@ -158,63 +158,86 @@ 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
|
||||
=nmWU
|
||||
m5Tx4w2uF4/n3FBnABEBAAGJBEQEGAECAA8FAlwsRBECGwIFCQIKEgACKQkQFkaw
|
||||
G4blAxDBXSAEGQECAAYFAlwsRBEACgkQI+cWZ4i2Ph6B0g//cPis3v2M6XvAbVoM
|
||||
3GIMXnsVj1WAHuwA/ja7UfZJ9+kV/PiMLkAbW0fBj0/y0O3Ry12VVQGXhC+Vo4j6
|
||||
C8qwFP4OXa6EsxHXuvWMIztBaX1Kav613aXBtxp6tTrud0FFUh4sDc1RREb3tMr6
|
||||
y5cvFJgnrdWcX1gsl6ODcgWBGNc6ZX7H7j48hMR6KmNeZocW7p8W+BgDQJqXYwVN
|
||||
L15qOHzVAh0dWsFLE9gwBTmDCY03x9arxSNDGCXyxt6E77LbNVIoSRlEbkvi6j33
|
||||
nEbuERICYl6CltXQCyiVKjheJcLMjbgv5+bLCv2zfeJ/WyOmOGKpHRu+lBV1Gvli
|
||||
RxUblVlmjWPhYPBZXGyjII16Tqr+ilREcZFW+STccbrVct75JWLbxwlEmix+W1Hw
|
||||
SRCR+KHx3Cur4ZPMOBlPsFilOOsNa7ROUB56t7zv21Ef3BeeaCd9c4kzNGN8d1ic
|
||||
EqSXoWWPqgST0LZPtZyqWZVnWrHChVHfrioxhSnw8O3wY1A2GSahiCSvvjvOeEoJ
|
||||
yU21ZMw6AVyHCh6v42oYadBfGgFwNo5OCMhNxNy/CcUrBSDqyLVTM5QlNsT75Ys7
|
||||
kHHnc+Jk+xx4JpiyNCz5LzcPhlwpqnJQcjJdY1hDhK75Ormj/NfCMeZ8g1aVPX4x
|
||||
Eq8AMyZYhZ5/lmM+13Rdv8ZW6FK7HQ/+IAKzntxOjw0MzCXkksKdmIOZ2bLeOVI8
|
||||
aSLaUmoT5CLuoia9g7iFHlYrSY+01riRrAaPtYx0x8onfyVxL9dlW/Fv5+qc1fF5
|
||||
FxdhyIgdqgzm82TnXHu/haUxYmUvNrbsmmNl5UTTOf+YQHMccKFdYfZ2rCBtbN2n
|
||||
iXG1tuz2+k83pozu4mJ1rOOLNAsQoY3yR6OODte1FyOgp7blwDhTIoQb8/UiJ7CM
|
||||
BI3OPrfoXFAnhYoxeRSAN4UFu9/HIkqfaQgRPCZS1gNerWF6r6yz9AZWUZqjSJss
|
||||
jBqXCtK9bGbTYBZk+pw3H9Nd0RJ2WJ9qPqmlmUr1wdqct0ChsJx1xAT86QrssicJ
|
||||
/HFFmF45hlnGkHUBWLaVJt8YkLb/DqOIbVbwyCLQtJ80VQLEeupfmu5QNsTpntRY
|
||||
NKf8cr00uc8vSYXYFRxa5H5oRT1eoFEEjDDvokNnHXfT+Hya44IjYpzaqvAgeDp6
|
||||
sYlOdtWIv/V3s+trxACwTkRN7zw3lLTbT8PK9szK0fYZ5KHG1/AKH+mbZ6qNc/25
|
||||
PNbAFRtttLGuEIC3HJ12IAp2JdjioeD2OnWLu4ZeCT2CKKFsleZPrSyCrn3gyZPm
|
||||
fYvv5h2JbQNO6uweOrZENWX5SU43OBoplbuKJZsMP6p6NahuGnIeJLlv509JYAf/
|
||||
HN4ARyvvOpOJBFsEGAEIACYCGwIWIQRy7PRqVrStOckHu7cWRrAbhuUDEAUCYA3F
|
||||
QQUJB6PoMAIpwV0gBBkBAgAGBQJcLEQRAAoJECPnFmeItj4egdIP/3D4rN79jOl7
|
||||
wG1aDNxiDF57FY9VgB7sAP42u1H2SffpFfz4jC5AG1tHwY9P8tDt0ctdlVUBl4Qv
|
||||
laOI+gvKsBT+Dl2uhLMR17r1jCM7QWl9Smr+td2lwbcaerU67ndBRVIeLA3NUURG
|
||||
97TK+suXLxSYJ63VnF9YLJejg3IFgRjXOmV+x+4+PITEeipjXmaHFu6fFvgYA0Ca
|
||||
l2MFTS9eajh81QIdHVrBSxPYMAU5gwmNN8fWq8UjQxgl8sbehO+y2zVSKEkZRG5L
|
||||
4uo995xG7hESAmJegpbV0AsolSo4XiXCzI24L+fmywr9s33if1sjpjhiqR0bvpQV
|
||||
dRr5YkcVG5VZZo1j4WDwWVxsoyCNek6q/opURHGRVvkk3HG61XLe+SVi28cJRJos
|
||||
fltR8EkQkfih8dwrq+GTzDgZT7BYpTjrDWu0TlAeere879tRH9wXnmgnfXOJMzRj
|
||||
fHdYnBKkl6Flj6oEk9C2T7WcqlmVZ1qxwoVR364qMYUp8PDt8GNQNhkmoYgkr747
|
||||
znhKCclNtWTMOgFchwoer+NqGGnQXxoBcDaOTgjITcTcvwnFKwUg6si1UzOUJTbE
|
||||
++WLO5Bx53PiZPsceCaYsjQs+S83D4ZcKapyUHIyXWNYQ4Su+Tq5o/zXwjHmfINW
|
||||
lT1+MRKvADMmWIWef5ZjPtd0Xb/GVuhSCRAWRrAbhuUDEMTLEACyFHe0SPm4rMMA
|
||||
E6dyadTJP8wRoI2epQciRqitIhANhmJ244WyqPWV3tDTgH/TaWPV7DerL6d2jOnw
|
||||
mdfT5JeXkWrGf5Gxwz619UFx/S4VpPOQf4eJb1Z9WaOdQ87A9+BwwO8d+2XROhMm
|
||||
iAetVo6jhvil0xR5t9HYg/uUSUu+tlHXlwPjdlYHUwUnt8HftoefWLXJj8ADHir1
|
||||
slw7jjFR/INE2dWqk6Lx2Ala+3yHN7/vpfOYvY4EyTvIeyLSoVn0fzUrsIv3HQSR
|
||||
WogO3MykjkiMjNbhdH8CXbEiQ1MiFKsugyi0kY6HOIe3//+cZ4xXlQLsLRnV3xm9
|
||||
e/xGOte4M8o05JaUCrcsCmubOnqUIaZmDF9bITHI7bhkxLkvXopoxx4UodiL4PPG
|
||||
OarAdRD2Y73eI7W6QhqZt8267tsLx4qe0q8/pCr7gX60E9hOSx2NszyS0FPME2CI
|
||||
4vxVR+GxS8gzp5hFQ8OUaSC9a6eb4YI66bDhkRog0GrMagX3JJI2172blRyp8Fe7
|
||||
DAEUOb/xCcaKdv6waT+pqtrOaxDArDVRPVVqDlr1fY0lJis92ycBk4Gs8pAYiMEZ
|
||||
lGUoh5MouBEPP7HtfZTMlsQm8J5hq3cJ+AxUPSbGTWUCql7hGpT4S97mpyATuLnW
|
||||
qLZmBgDHhpHEmUQmONKSSpzSjjAS6LkCDQRcN/VvARAAoEHIkyjFDsfoCxA/b2qN
|
||||
jz+l8OI2WhAMdqxReg7JN9R61qbetj9RYIcWswPSO84c0ioRUk+xJavEFh/6Lg00
|
||||
QKwJKPf0kd1Us6SfqklxGczOaWNLyiM7JthFRNMp0qVX6NjLqGoCNO+d/+nNk6s2
|
||||
x4rLECj/EROmE3ZQQEo5nBXmPlhXpVem23rGfXEQvXDNqFmvqrP+Befn/+aDpo89
|
||||
QIm3sE8G0LfgcajIdSfgLH+NJTvOVAtXXVXJPK39Njr1aBzWTbWhLS2bji7DwP7h
|
||||
shdh7DE2rS623vlzvkkrms8oKkiRpKATdhQ8CEx+mhTFKCj6GtNqhwttCbf98N9G
|
||||
piHD0has65YtgQQjk2pLR62rZf6czagRfKbFQzXjl2JxS/bsHVhTkhyJFqgDcHCS
|
||||
Xe7K8uGTAE2AkakGhGyDJYqGVSl0w5IAU8dqDQMc0IpsVMbFk4nX4GgOwixwrzrg
|
||||
Ch0jRi+EwUHJYZHBAyzNCkr++D25R0gwNhPMjSKe8Ks6G3hH3XP/ZVlceW/gPfxR
|
||||
ixUTk/q7s3xPpPhLMREEpKS1aGcmYxEkrkVBDAzNYKdKP1MYwLn4lh4yNFXWlTCl
|
||||
nDyI6UODTHwt8xDddtnT9u+U+xc6OJiYcCOstl+ovS9HmM/Kt9VTEX9cckEEL1IS
|
||||
+9esQMr4b5X02Y1q9Q2uEucAEQEAAYkEWwQYAQgAJgIbAhYhBHLs9GpWtK05yQe7
|
||||
txZGsBuG5QMQBQJgDcVSBQkHmDbjAinBXSAEGQECAAYFAlw39W8ACgkQT3dnk2lH
|
||||
W6p0eg/+K2JJu1RbTSLJPFYQhLcxX+5d2unkuNLIy3kArtZuB992E2Fw00okPGtu
|
||||
PdSyk2ygh4DeYnwmabIWChi7LDp+YnqcI4GfMxNG6RsHs+A/77rLBST3BB1sejZp
|
||||
pmKCQZDSC2pvYaZBpS80UvftCZ9RFdY+kTC22Btn/5ekiQOfIqhUH9CyGWS/YlGc
|
||||
iomVIVn1hSPN8l4EpBCDtceRaephvzjQIZT3AxOfSlpwJviYjAOkSX4qWyIjC5Ke
|
||||
5kfEOldUuBN1JGAm45tKlrz/LD/+VOc2IWpbkOIAVSldUgpRyiIJQAZ80trNxrJI
|
||||
7ncaID8lAa7pBptJiL0KorRjk3c6Y7p830Nwe0J5e5+W1RzN4wlR8+9uuRyP8Mcw
|
||||
z/Hz2jwMiv38Vk4tAOe4PYNZuDnpjZ28yCpF3UUgvzjarubFAcg2jd8SauCQFlmO
|
||||
fvT+1qIMSeLmWBOdlzJTUpJRcZqnkEE4WtiMSlxyWVFvUwOmKSGi8CLoGW1Ksh9t
|
||||
hQ9zKhvVUiVoKn4Z79HXr4pX6rnp+mweJ2dEZtlqD7HxjVTlCHn9fzClt/Nt0h72
|
||||
1fJbS587AC/ZMgg5GV+GKu6Mij0sPAowUJVCIwN9uK/GHICZEAoMSngP8xzKnhU5
|
||||
FD38vwBvsqbKxTtICrv2NuwnQ0WBBQ58w5mv2RCMr2W6iegSKIAJEBZGsBuG5QMQ
|
||||
U8oQAMjiPEOFmgRcuhvhlzXT53d/1b8sfG4MV9c45xKE65L+kPoSGzvNWYumB2Kw
|
||||
Qzf8tWu+6PmOljj1Ofyilqm3bblOasHWgDGPTSOcBaVhl8nZrS3o2fzZy7aQKYE3
|
||||
gQBZ6+jzhHQzrnQURpR+s/mdSO3+Gs+6kBmh9dkIQ8U1cfaAbZgy17BipPZkpwjr
|
||||
ltTcDyJniQyEm7L6yV6MWt2TiFUA5IvyH+hTSKrLHnR7+lYDEo28wV8f8UcLrUpQ
|
||||
joiCOWZeNCubaIxHHoGtCE+zkhSsuW9lGSX0rzQlmx1vclrYwyMKhlpDOqy8kzdI
|
||||
Ws7VF3vCXRi6fWSA7apRtQQ7PbuZOOyYTaEkEuJ5CfWhFGy3eikiXilPk05ECZd3
|
||||
/uMB1dmPFKT+MbUDCA/b8amfkNTLg+RFNX+5isMLkrJ+8k13ueTp/PToGMIkYsbR
|
||||
+HRm0HmrdqGFPl7o+0xXUT4wGbQD8QfK81lzH1QQhsu+12OsFt+jQC3IDYiXOUBk
|
||||
zgkwMlt8C0vU0i/EElpqx/0n19iHv7XvPn5q0MdNBS5pW+DOho0D+z+NM9MWpYUu
|
||||
ymC/28jo8Olju+9DZuZwEUEbptmltcA8UQ5r4FHx4m3sfCmCs1QUeb8TPNL0x8OA
|
||||
XnADXbxMgGYTNX7YvdUw3a8M73stqnN9M8lUXln7ulOCee2z
|
||||
=IgpF
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
|
|
|
@ -24,8 +24,8 @@ dependencies:
|
|||
- { role: evolix/squid, squid_localproxy_enable: True }
|
||||
- { role: evolix/mysql, when: packweb_mysql_variant == "debian" }
|
||||
- { role: evolix/mysql-oracle, when: packweb_mysql_variant == "oracle" }
|
||||
- { role: evolix/lxc-php, lxc_php_version: php56, when: "'php56' in packweb_multiphp_versions" }
|
||||
- { role: evolix/lxc-php, lxc_php_version: php70, when: "'php70' in packweb_multiphp_versions" }
|
||||
- { role: evolix/lxc-php, lxc_php_version: php73, when: "'php73' in packweb_multiphp_versions" }
|
||||
- { role: evolix/lxc-php, lxc_php_version: php56, lxc_php_create_mysql_link: True, when: "'php56' in packweb_multiphp_versions" }
|
||||
- { role: evolix/lxc-php, lxc_php_version: php70, lxc_php_create_mysql_link: True, when: "'php70' in packweb_multiphp_versions" }
|
||||
- { role: evolix/lxc-php, lxc_php_version: php73, lxc_php_create_mysql_link: True, when: "'php73' in packweb_multiphp_versions" }
|
||||
- { role: evolix/webapps/evoadmin-web, evoadmin_enable_vhost: "{{ packweb_enable_evoadmin_vhost }}", evoadmin_multiphp_versions: "{{ packweb_multiphp_versions }}" }
|
||||
- { role: evolix/evoacme }
|
||||
|
|
|
@ -20,6 +20,8 @@ smtp_tls_protocols=!SSLv2,!SSLv3
|
|||
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
|
||||
smtp_tls_loglevel = 1
|
||||
|
||||
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
|
||||
|
||||
{% if postfix_slow_transport_include == True %}
|
||||
# Slow transports configuration
|
||||
minimal_backoff_time = 2h
|
||||
|
|
|
@ -384,6 +384,7 @@ strict_rfc821_envelopes = yes
|
|||
#par defaut, = yes
|
||||
#smtpd_reject_unlisted_recipient =
|
||||
|
||||
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
|
||||
|
||||
#######################
|
||||
# Section : Chiffrement
|
||||
|
|
5
postgresql/files/postgresql.service.override.conf
Normal file
5
postgresql/files/postgresql.service.override.conf
Normal file
|
@ -0,0 +1,5 @@
|
|||
[Service]
|
||||
OOMScoreAdjust=-1000
|
||||
Environment=PG_OOM_ADJUST_FILE=/proc/self/oom_score_adj
|
||||
Environment=PG_MASTER_OOM_SCORE_ADJ=-1000
|
||||
Environment=PG_CHILD_OOM_SCORE_ADJ=0
|
|
@ -1,8 +1,14 @@
|
|||
---
|
||||
- name: Ensure /etc/systemd/system/postgresql.service.d exists
|
||||
file:
|
||||
path: /etc/systemd/system/postgresql@.service.d
|
||||
state: directory
|
||||
recurse: true
|
||||
|
||||
- name: Override PostgreSQL systemd unit
|
||||
template:
|
||||
src: postgresql.service.j2
|
||||
dest: /etc/systemd/system/multi-user.target.wants/postgresql.service
|
||||
copy:
|
||||
src: postgresql.service.override.conf
|
||||
dest: /etc/systemd/system/postgresql@.service.d/override.conf
|
||||
force: yes
|
||||
notify:
|
||||
- reload systemd
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
# systemd service for managing all PostgreSQL clusters on the system. This
|
||||
# service is actually a systemd target, but we are using a service since
|
||||
# targets cannot be reloaded.
|
||||
|
||||
[Unit]
|
||||
Description=PostgreSQL RDBMS
|
||||
|
||||
[Service]
|
||||
OOMScoreAdjust=-1000
|
||||
Environment=PG_OOM_ADJUST_FILE=/proc/self/oom_score_adj
|
||||
Environment=PG_MASTER_OOM_SCORE_ADJ=-1000
|
||||
Environment=PG_CHILD_OOM_SCORE_ADJ=0
|
||||
Type=oneshot
|
||||
ExecStart=/bin/true
|
||||
ExecReload=/bin/true
|
||||
RemainAfterExit=on
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
|
@ -9,10 +9,10 @@ redis_port: 6379
|
|||
redis_bind_interface: 127.0.0.1
|
||||
|
||||
redis_socket_enabled: True
|
||||
redis_socket_dir_prefix: '/var/run/redis'
|
||||
redis_socket_dir_prefix: '/run/redis'
|
||||
redis_socket_perms: 770
|
||||
|
||||
redis_pid_dir_prefix: "/var/run/redis"
|
||||
redis_pid_dir_prefix: "/run/redis"
|
||||
|
||||
redis_timeout: 300
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
mode: "0640"
|
||||
create: yes
|
||||
marker: "# {mark} ANSIBLE MANAGED RULES FOR INSTANCE {{ redis_instance_name }}"
|
||||
content: |
|
||||
block: |
|
||||
file = {{ redis_log_dir }}/redis-server.log
|
||||
pattern = "Cannot allocate memory"
|
||||
mailto = {{ log2mail_alert_email or general_alert_email | mandatory }}
|
||||
|
|
|
@ -70,7 +70,21 @@
|
|||
tags:
|
||||
- redis
|
||||
|
||||
- name: "Instance '{{ redis_instance_name }}' other directories are present"
|
||||
- name: "Instance '{{ redis_instance_name }}' socket/pid directories are present"
|
||||
file:
|
||||
dest: "{{ item }}"
|
||||
mode: "0755"
|
||||
owner: "redis-{{ redis_instance_name }}"
|
||||
group: "redis-{{ redis_instance_name }}"
|
||||
follow: yes
|
||||
state: directory
|
||||
with_items:
|
||||
- "{{ redis_pid_dir }}"
|
||||
- "{{ redis_socket_dir }}"
|
||||
tags:
|
||||
- redis
|
||||
|
||||
- name: "Instance '{{ redis_instance_name }}' data/log directories are present"
|
||||
file:
|
||||
dest: "{{ item }}"
|
||||
mode: "0750"
|
||||
|
@ -79,8 +93,6 @@
|
|||
follow: yes
|
||||
state: directory
|
||||
with_items:
|
||||
- "{{ redis_pid_dir }}"
|
||||
- "{{ redis_socket_dir }}"
|
||||
- "{{ redis_data_dir }}"
|
||||
- "{{ redis_log_dir }}"
|
||||
tags:
|
||||
|
@ -110,7 +122,7 @@
|
|||
tags:
|
||||
- redis
|
||||
|
||||
- name: Systemd template for redis instances is installed (Debian 9 or later)
|
||||
- name: Systemd template for redis instances is installed (Debian 9)
|
||||
template:
|
||||
src: 'redis-server@stretch.service.j2'
|
||||
dest: '/etc/systemd/system/redis-server@.service'
|
||||
|
@ -119,7 +131,20 @@
|
|||
group: "root"
|
||||
when:
|
||||
- ansible_distribution == "Debian"
|
||||
- ansible_distribution_major_version is version('9', '>=')
|
||||
- ansible_distribution_major_version is version('9', '=')
|
||||
tags:
|
||||
- redis
|
||||
|
||||
- name: Systemd template for redis instances is installed (Debian 10 or later)
|
||||
template:
|
||||
src: 'redis-server@buster.service.j2'
|
||||
dest: '/etc/systemd/system/redis-server@.service'
|
||||
mode: "0644"
|
||||
owner: "root"
|
||||
group: "root"
|
||||
when:
|
||||
- ansible_distribution == "Debian"
|
||||
- ansible_distribution_major_version is version('10', '>=')
|
||||
tags:
|
||||
- redis
|
||||
|
||||
|
|
|
@ -4,5 +4,5 @@
|
|||
env.title_prefix Instance {{ redis_instance_name }}
|
||||
env.port {{ redis_port }}
|
||||
{% if redis_password %}
|
||||
env.password {{ redis_password }}
|
||||
env.password {{ redis_password | replace("#", "\#") }}
|
||||
{% endif %}
|
||||
|
|
35
redis/templates/redis-server@buster.service.j2
Normal file
35
redis/templates/redis-server@buster.service.j2
Normal file
|
@ -0,0 +1,35 @@
|
|||
[Unit]
|
||||
Description=Advanced key-value store
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=forking
|
||||
ExecStart=/usr/bin/redis-server {{ redis_conf_dir_prefix }}-%i/redis.conf
|
||||
PIDFile=/run/redis-%i/redis-server.pid
|
||||
TimeoutStopSec=0
|
||||
Restart=always
|
||||
User=redis-%i
|
||||
Group=redis-%i
|
||||
RuntimeDirectory=redis-%i
|
||||
|
||||
ExecStop=/bin/kill -s TERM $MAINPID
|
||||
|
||||
UMask=007
|
||||
PrivateTmp=yes
|
||||
LimitNOFILE=65535
|
||||
PrivateDevices=yes
|
||||
ProtectHome={{ redis_data_dir_prefix is match('/home') | ternary('no', 'yes') }}
|
||||
ReadOnlyDirectories=/
|
||||
ReadWriteDirectories=-{{ redis_data_dir_prefix }}-%i
|
||||
ReadWriteDirectories=-{{ redis_log_dir_prefix }}-%i
|
||||
ReadWriteDirectories=-{{ redis_pid_dir_prefix }}-%i
|
||||
ReadWriteDirectories=-{{ redis_socket_dir_prefix }}-%i
|
||||
CapabilityBoundingSet=~CAP_SYS_PTRACE
|
||||
|
||||
# redis-server writes its own config file when in cluster mode so we allow
|
||||
# writing there (NB. ProtectSystem=true over ProtectSystem=full)
|
||||
ProtectSystem=true
|
||||
ReadWriteDirectories=-{{ redis_conf_dir_prefix }}-%i
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
|
@ -5,7 +5,7 @@ After=network.target
|
|||
[Service]
|
||||
Type=forking
|
||||
ExecStart=/usr/bin/redis-server {{ redis_conf_dir_prefix }}-%i/redis.conf
|
||||
PIDFile=/var/run/redis-%i/redis-server.pid
|
||||
PIDFile=/run/redis-%i/redis-server.pid
|
||||
TimeoutStopSec=0
|
||||
Restart=always
|
||||
User=redis-%i
|
||||
|
|
|
@ -94,7 +94,7 @@ score ADDRESS_IN_SUBJECT 0.1
|
|||
score HELO_LH_HOME 1.0
|
||||
|
||||
#internal_networks 192.168.XXX/24
|
||||
trusted_networks 62.212.111.216 88.179.18.233 85.118.59.50 31.170.8.0/21
|
||||
trusted_networks 62.212.121.90 82.65.34.85 31.170.8.0/21
|
||||
#score ALL_TRUSTED 0.3
|
||||
score HELO_DYNAMIC_IPADDR 0.3
|
||||
|
||||
|
|
Loading…
Reference in a new issue