commit 60b8ecdd4c2c236f99159d825c1c5306ced36602 Author: Alan Orth Date: Sun Aug 17 00:35:57 2014 +0300 Initial commit Signed-off-by: Alan Orth diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6ff331c --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +hosts diff --git a/README.md b/README.md new file mode 100644 index 0000000..81e49fd --- /dev/null +++ b/README.md @@ -0,0 +1,8 @@ +## Mjanja webserver + +Playbooks for base and initial configuration of Mjanja web server. + +### To use +Create a new Ubuntu 14.04 host, add a user account, copy your SSH public key, then execute: + + ansible-playbook site.yml -i hosts -K diff --git a/group_vars/all b/group_vars/all new file mode 100644 index 0000000..a66208d --- /dev/null +++ b/group_vars/all @@ -0,0 +1,10 @@ +--- +# file: group_vars/all + +dns_domain: mjanja.co.ke + +tls_cipher_suite: "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128:AES256:AES:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK" + +ssh_allowed_users: aorth + +# vim: set ts=2 sw=2: diff --git a/roles/common/files/cron-apt/3-download b/roles/common/files/cron-apt/3-download new file mode 100644 index 0000000..93d2631 --- /dev/null +++ b/roles/common/files/cron-apt/3-download @@ -0,0 +1,2 @@ +autoclean -y +upgrade -y -o APT::Get::Show-Upgraded=true diff --git a/roles/common/files/cron-apt/config b/roles/common/files/cron-apt/config new file mode 100644 index 0000000..fdaf311 --- /dev/null +++ b/roles/common/files/cron-apt/config @@ -0,0 +1,6 @@ +# Configuration for cron-apt. For further information about the possible +# configuration settings see the README file. + +MAILTO="a.orth@cgiar.org" +MAILON="error" +OPTIONS="-o quiet=1 -o Dir::Etc::SourceList=/etc/apt/security.sources.list -o Dir::Etc::SourceParts=\"/dev/null\"" diff --git a/roles/common/files/cron-apt/security.sources.list b/roles/common/files/cron-apt/security.sources.list new file mode 100644 index 0000000..21ac7b1 --- /dev/null +++ b/roles/common/files/cron-apt/security.sources.list @@ -0,0 +1 @@ +deb http://security.ubuntu.com/ubuntu precise-security main universe diff --git a/roles/common/handlers/main.yml b/roles/common/handlers/main.yml new file mode 100644 index 0000000..f90def7 --- /dev/null +++ b/roles/common/handlers/main.yml @@ -0,0 +1,14 @@ +--- +# file: roles/common/handlers/main.yml + +- name: restart iptables + service: name=iptables state=restarted + +- name: restart iptables-persistent + service: name=iptables-persistent state=restarted + +- name: restart sshd + service: name={{ sshd_service_name }} state=restarted + +- name: reload sysctl + command: sysctl -p /etc/sysctl.conf diff --git a/roles/common/tasks/iptables_Debian.yml b/roles/common/tasks/iptables_Debian.yml new file mode 100644 index 0000000..edc8c93 --- /dev/null +++ b/roles/common/tasks/iptables_Debian.yml @@ -0,0 +1,10 @@ +--- +- name: Install iptables-persistent + apt: pkg=iptables-persistent update_cache=yes + tags: firewall + +- name: Copy /etc/iptables/rules.v4 + template: src=iptables.j2 dest=/etc/iptables/rules.v4 owner=root mode=0600 + notify: + - restart iptables-persistent + tags: firewall diff --git a/roles/common/tasks/main.yml b/roles/common/tasks/main.yml new file mode 100644 index 0000000..33a5bcc --- /dev/null +++ b/roles/common/tasks/main.yml @@ -0,0 +1,38 @@ +--- +# not needed on OpenStack images... +#- name: Set hostname +# hostname: name={{ inventory_hostname }} +# tags: hostname +# +#- name: Add hostname to /etc/hosts +# lineinfile: dest=/etc/hosts insertafter=^127.0.0.1 line='127.0.1.1 {{ inventory_hostname }}' +# tags: hostname + +- include: packages_Ubuntu.yml + when: "ansible_distribution == 'Ubuntu'" + tags: packages + +- include: iptables_Debian.yml + when: ansible_os_family == 'Debian' + +- name: Reconfigure /etc/ssh/sshd_config + template: src=sshd_config_{{ansible_distribution}}-{{ansible_distribution_version}}.j2 dest=/etc/ssh/sshd_config owner=root group=root mode=0600 + notify: + - restart sshd + tags: sshd + +- name: Reconfigure /etc/sysctl.conf + template: src=sysctl_{{ ansible_distribution }}.j2 dest=/etc/sysctl.conf owner=root group=root mode=0644 + notify: + - reload sysctl + tags: sysctl + +- name: Reconfigure /etc/rc.local + when: "ansible_distribution == 'CentOS'" + template: src=rc.local_{{ ansible_distribution }}.j2 dest=/etc/rc.d/rc.local owner=root group=root mode=0755 + +- name: Reconfigure /etc/rc.local + when: "ansible_distribution == 'Debian'" + template: src=rc.local_{{ ansible_distribution }}.j2 dest=/etc/rc.local owner=root group=root mode=0755 + +# vim: set sw=2 ts=2: diff --git a/roles/common/tasks/packages_Ubuntu.yml b/roles/common/tasks/packages_Ubuntu.yml new file mode 100644 index 0000000..f8ed1fc --- /dev/null +++ b/roles/common/tasks/packages_Ubuntu.yml @@ -0,0 +1,50 @@ +--- +- name: Configure apt mirror + template: src=sources.list.j2 dest=/etc/apt/sources.list owner=root group=root mode=0644 + +- name: Add GPG key for Extras repo + apt_key: id=0x3E5C1192 url=http://keyserver.ubuntu.com/pks/lookup?op=get&search=0x16126D3A3E5C1192 state=present + +- name: Upgrade base OS + apt: upgrade=dist update_cache=yes + +- name: Install base packages + apt: pkg={{ item }} + with_items: + - ntp + - git + - tmux + - iotop + - htop + - strace + - s3cmd + - cron-apt + - safe-rm + - debian-goodies + - mosh + - python-pycurl # for ansible's apt_repository + - sysv-rc-conf + - lzop + - vim + +- name: Security hardening (CIS Benchmark 1.0) + apt: pkg={{ item }} state=absent purge=yes + with_items: + - whoopsie # CIS 4.1 + - apport # CIS 4.1 + +- name: Remove annoying packages + apt: pkg={{ item }} state=absent purge=yes + with_items: + - command-not-found + - command-not-found-data + - python3-commandnotfound + +- name: Configure cron-apt (config) + copy: src=cron-apt/config dest=/etc/cron-apt/config mode=0644 owner=root group=root + +- name: Configure cron-apt (config) + copy: src=cron-apt/3-download dest=/etc/cron-apt/action.d/3-download mode=0644 owner=root group=root + +- name: Configure cron-apt (security) + copy: src=cron-apt/security.sources.list dest=/etc/apt/security.sources.list mode=0644 owner=root group=root diff --git a/roles/common/templates/iptables.j2 b/roles/common/templates/iptables.j2 new file mode 100644 index 0000000..590a781 --- /dev/null +++ b/roles/common/templates/iptables.j2 @@ -0,0 +1,20 @@ +*filter +:INPUT ACCEPT [0:0] +:FORWARD ACCEPT [0:0] +:OUTPUT ACCEPT [0:0] +-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT +-A INPUT -p icmp -j ACCEPT +-A INPUT -i lo -j ACCEPT + +-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -s 0.0.0.0/0 -j ACCEPT +-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -s 0.0.0.0/0 -j ACCEPT + +{% if extra_iptables_rules is defined %} +{% for rule in extra_iptables_rules %} +-A INPUT -p {{ rule.protocol }} -m state --state NEW -m {{ rule.protocol }} --dport {{ rule.port }} -s {{ ghetto_ipsets[rule.acl].src }} -j ACCEPT +{% endfor %} +{% endif %} + +-A INPUT -j REJECT --reject-with icmp-host-prohibited +-A FORWARD -j REJECT --reject-with icmp-host-prohibited +COMMIT diff --git a/roles/common/templates/rc.local_Ubuntu.j2 b/roles/common/templates/rc.local_Ubuntu.j2 new file mode 100644 index 0000000..886c61c --- /dev/null +++ b/roles/common/templates/rc.local_Ubuntu.j2 @@ -0,0 +1,19 @@ +#!/bin/sh -e +# +# rc.local +# +# This script is executed at the end of each multiuser runlevel. +# Make sure that the script will "exit 0" on success or any other +# value on error. +# +# In order to enable or disable this script just change the execution +# bits. +# +# By default this script does nothing. + +# VMs should use deadline IO sched +{% for device in ansible_devices %} +echo deadline > /sys/block/{{ device }}/queue/scheduler +{% endfor %} + +exit 0 diff --git a/roles/common/templates/sources.list.j2 b/roles/common/templates/sources.list.j2 new file mode 100644 index 0000000..f58fe99 --- /dev/null +++ b/roles/common/templates/sources.list.j2 @@ -0,0 +1,16 @@ +############################################################# +################### OFFICIAL UBUNTU REPOS ################### +############################################################# + +###### Ubuntu Main Repos +deb http://{{ apt_mirror }}/ubuntu/ {{ ansible_distribution_release }} main restricted universe multiverse + +###### Ubuntu Update Repos +deb http://{{ apt_mirror }}/ubuntu/ {{ ansible_distribution_release }}-security main restricted universe multiverse +deb http://{{ apt_mirror }}/ubuntu/ {{ ansible_distribution_release }}-updates main restricted universe multiverse + +###### Ubuntu Partner Repo +deb http://archive.canonical.com/ubuntu {{ ansible_distribution_release }} partner + +###### Ubuntu Extras Repo +deb http://extras.ubuntu.com/ubuntu {{ ansible_distribution_release }} main diff --git a/roles/common/templates/sshd_config_Ubuntu-14.04.j2 b/roles/common/templates/sshd_config_Ubuntu-14.04.j2 new file mode 100644 index 0000000..0bfde8c --- /dev/null +++ b/roles/common/templates/sshd_config_Ubuntu-14.04.j2 @@ -0,0 +1,98 @@ +# Package generated configuration file +# See the sshd_config(5) manpage for details + +# What ports, IPs and protocols we listen for +Port 22 +# Use these options to restrict which interfaces/protocols sshd will bind to +#ListenAddress :: +#ListenAddress 0.0.0.0 +Protocol 2 +# HostKeys for protocol version 2 +HostKey /etc/ssh/ssh_host_rsa_key +HostKey /etc/ssh/ssh_host_ecdsa_key +HostKey /etc/ssh/ssh_host_ed25519_key +#Privilege Separation is turned on for security +UsePrivilegeSeparation yes + +# Lifetime and size of ephemeral version 1 server key +KeyRegenerationInterval 3600 +ServerKeyBits 1024 + +# Logging +SyslogFacility AUTH +LogLevel INFO + +# Authentication: +LoginGraceTime 120 +PermitRootLogin without-password +StrictModes yes + +RSAAuthentication yes +PubkeyAuthentication yes +#AuthorizedKeysFile %h/.ssh/authorized_keys + +# Don't read the user's ~/.rhosts and ~/.shosts files +IgnoreRhosts yes +# For this to work you will also need host keys in /etc/ssh_known_hosts +RhostsRSAAuthentication no +# similar for protocol version 2 +HostbasedAuthentication no +# Uncomment if you don't trust ~/.ssh/known_hosts for RhostsRSAAuthentication +#IgnoreUserKnownHosts yes + +# To enable empty passwords, change to yes (NOT RECOMMENDED) +PermitEmptyPasswords no + +# Change to yes to enable challenge-response passwords (beware issues with +# some PAM modules and threads) +ChallengeResponseAuthentication no + +# Change to no to disable tunnelled clear text passwords +#PasswordAuthentication yes + +# Kerberos options +#KerberosAuthentication no +#KerberosGetAFSToken no +#KerberosOrLocalPasswd yes +#KerberosTicketCleanup yes + +# GSSAPI options +GSSAPIAuthentication no +GSSAPICleanupCredentials yes + +X11Forwarding no +X11DisplayOffset 10 +PrintMotd no +PrintLastLog yes +TCPKeepAlive yes +#UseLogin no + +#MaxStartups 10:30:60 +#Banner /etc/issue.net + +# Allow client to pass locale environment variables +AcceptEnv LANG LC_* + +Subsystem sftp /usr/lib/openssh/sftp-server + +# Set this to 'yes' to enable PAM authentication, account processing, +# and session processing. If this is enabled, PAM authentication will +# be allowed through the ChallengeResponseAuthentication and +# PasswordAuthentication. Depending on your PAM configuration, +# PAM authentication via ChallengeResponseAuthentication may bypass +# the setting of "PermitRootLogin without-password". +# If you just want the PAM account and session checks to run without +# PAM authentication, then enable this but set PasswordAuthentication +# and ChallengeResponseAuthentication to 'no'. +UsePAM yes + +# bettercrypto.org - June, 2014 +Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes128-ctr +MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,hmac-ripemd160 +KexAlgorithms curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1 + +{% if ssh_allowed_users is defined and ssh_allowed_users %} +# Is there a list of allowed users? +# Is it populated? (An empty list is 'None', which evaluates as False in Python) +AllowUsers {{ ssh_allowed_users }} +{% endif %} diff --git a/roles/common/templates/sysctl_Ubuntu.j2 b/roles/common/templates/sysctl_Ubuntu.j2 new file mode 100644 index 0000000..b41877d --- /dev/null +++ b/roles/common/templates/sysctl_Ubuntu.j2 @@ -0,0 +1,98 @@ +# +# /etc/sysctl.conf - Configuration file for setting system variables +# See /etc/sysctl.d/ for additional system variables +# See sysctl.conf (5) for information. +# + +#kernel.domainname = example.com + +# Uncomment the following to stop low-level messages on console +#kernel.printk = 3 4 1 3 + +##############################################################3 +# Functions previously found in netbase +# + +# Uncomment the next two lines to enable Spoof protection (reverse-path filter) +# Turn on Source Address Verification in all interfaces to +# prevent some spoofing attacks +#net.ipv4.conf.default.rp_filter=1 +#net.ipv4.conf.all.rp_filter=1 + +# Uncomment the next line to enable TCP/IP SYN cookies +# See http://lwn.net/Articles/277146/ +# Note: This may impact IPv6 TCP sessions too +#net.ipv4.tcp_syncookies=1 + +# Uncomment the next line to enable packet forwarding for IPv4 +#net.ipv4.ip_forward=1 + +# Uncomment the next line to enable packet forwarding for IPv6 +# Enabling this option disables Stateless Address Autoconfiguration +# based on Router Advertisements for this host +#net.ipv6.conf.all.forwarding=1 + + +################################################################### +# Additional settings - these settings can improve the network +# security of the host and prevent against some network attacks +# including spoofing attacks and man in the middle attacks through +# redirection. Some network environments, however, require that these +# settings are disabled so review and enable them as needed. +# +# Do not accept ICMP redirects (prevent MITM attacks) +#net.ipv4.conf.all.accept_redirects = 0 +#net.ipv6.conf.all.accept_redirects = 0 +# _or_ +# Accept ICMP redirects only for gateways listed in our default +# gateway list (enabled by default) +# net.ipv4.conf.all.secure_redirects = 1 +# +# Do not send ICMP redirects (we are not a router) +#net.ipv4.conf.all.send_redirects = 0 +# +# Do not accept IP source route packets (we are not a router) +#net.ipv4.conf.all.accept_source_route = 0 +#net.ipv6.conf.all.accept_source_route = 0 +# +# Log Martian Packets +#net.ipv4.conf.all.log_martians = 1 +# + +# CIS Benchmark Adjustments +# See: https://github.com/alanorth/securekickstarts +kernel.randomize_va_space = 2 +net.ipv4.ip_forward = 0 +net.ipv4.conf.all.send_redirects = 0 +net.ipv4.conf.default.send_redirects = 0 +net.ipv4.conf.all.accept_source_route = 0 +net.ipv4.conf.default.accept_source_route = 0 +net.ipv4.conf.all.accept_redirects = 0 +net.ipv4.conf.default.accept_redirects = 0 +net.ipv4.conf.all.secure_redirects = 0 +net.ipv4.conf.default.secure_redirects = 0 +net.ipv4.conf.all.log_martians = 1 +net.ipv4.conf.default.log_martians = 1 +net.ipv4.icmp_echo_ignore_broadcasts = 1 +net.ipv4.icmp_ignore_bogus_error_responses = 1 +net.ipv4.conf.all.rp_filter = 1 +net.ipv4.conf.default.rp_filter = 1 +net.ipv4.tcp_syncookies = 1 + +# TCP stuff +# See: http://fasterdata.es.net/host-tuning/linux/ +# increase TCP max buffer size settable using setsockopt() +net.core.rmem_max = 16777216 +net.core.wmem_max = 16777216 +# increase Linux autotuning TCP buffer limit +net.ipv4.tcp_rmem = 4096 87380 16777216 +net.ipv4.tcp_wmem = 4096 65536 16777216 +# increase the length of the processor input queue +net.core.netdev_max_backlog = 30000 +{# Linode kernels don't have htcp, and kernels after 2.6.32 don't have buggy cubic #} +{% if "linode" not in ansible_kernel and ansible_kernel < "2.6.33" %} +# recommended default congestion control is htcp +net.ipv4.tcp_congestion_control=htcp +{% endif %} +# recommended for hosts with jumbo frames enabled +#net.ipv4.tcp_mtu_probing=1 diff --git a/roles/mariadb/tasks/main.yml b/roles/mariadb/tasks/main.yml new file mode 100644 index 0000000..e92831f --- /dev/null +++ b/roles/mariadb/tasks/main.yml @@ -0,0 +1,36 @@ +--- +- name: Add GPG key for MariaDB repo + apt_key: id=0xcbcb082a1bb943db url=http://keyserver.ubuntu.com/pks/lookup?op=get&search=0xcbcb082a1bb943db + tags: mariadb + +- name: Add MariaDB 10.0 repo + apt_repository: repo="deb http://sgp1.mirrors.digitalocean.com/mariadb/repo/10.0/ubuntu {{ ansible_distribution_release }} main" state=present + tags: mariadb + +- name: Install mariadb-server + apt: name={{ item }} state=present update_cache=yes + with_items: + - mariadb-server + # - python-mysqldb # for ansible + tags: mariadb + +- name: Start and enable MariaDB Service + service: name=mysql state=started enabled=true + tags: mariadb + +# 'localhost' needs to be the last item for idempotency, see +# http://ansible.cc/docs/modules.html#mysql-user +- name: Update MariaDB root password for all root accounts + mysql_user: name=root host={{ item }} password={{ mariadb_root_password }} + with_items: + - "{{ inventory_hostname }}" + - 127.0.0.1 + - ::1 + - localhost + tags: mariadb + +- name: Create .my.conf file with root credentials + template: src=.my.cnf.j2 dest=/root/.my.cnf owner=root mode=0600 + tags: mariadb + +# vim: set ts=2 sw=2: diff --git a/roles/mariadb/templates/.my.cnf.j2 b/roles/mariadb/templates/.my.cnf.j2 new file mode 100644 index 0000000..0a8e76c --- /dev/null +++ b/roles/mariadb/templates/.my.cnf.j2 @@ -0,0 +1,3 @@ +[client] +user=root +password={{ mariadb_root_password }} diff --git a/roles/munin/files/munin.conf b/roles/munin/files/munin.conf new file mode 100644 index 0000000..d5b3879 --- /dev/null +++ b/roles/munin/files/munin.conf @@ -0,0 +1,145 @@ +# Example configuration file for Munin, generated by 'make build' + +# The next three variables specifies where the location of the RRD +# databases, the HTML output, logs and the lock/pid files. They all +# must be writable by the user running munin-cron. They are all +# defaulted to the values you see here. +# +#dbdir /var/lib/munin +#htmldir /var/cache/munin/www +#logdir /var/log/munin +#rundir /var/run/munin + +# Where to look for the HTML templates +# +#tmpldir /etc/munin/templates + +# Where to look for the static www files +# +#staticdir /etc/munin/static + +# temporary cgi files are here. note that it has to be writable by +# the cgi user (usually nobody or httpd). +# +# cgitmpdir /var/lib/munin/cgi-tmp + +# (Exactly one) directory to include all files from. +includedir /etc/munin/munin-conf.d + +# You can choose the time reference for "DERIVE" like graphs, and show +# "per minute", "per hour" values instead of the default "per second" +# +#graph_period second + +# Graphics files are generated either via cron or by a CGI process. +# See http://munin-monitoring.org/wiki/CgiHowto2 for more +# documentation. +# Since 2.0, munin-graph has been rewritten to use the cgi code. +# It is single threaded *by design* now. +# +#graph_strategy cron + +# munin-cgi-graph is invoked by the web server up to very many times at the +# same time. This is not optimal since it results in high CPU and memory +# consumption to the degree that the system can thrash. Again the default is +# 6. Most likely the optimal number for max_cgi_graph_jobs is the same as +# max_graph_jobs. +# +#munin_cgi_graph_jobs 6 + +# If the automatic CGI url is wrong for your system override it here: +# +#cgiurl_graph /munin-cgi/munin-cgi-graph + +# max_size_x and max_size_y are the max size of images in pixel. +# Default is 4000. Do not make it too large otherwise RRD might use all +# RAM to generate the images. +# +#max_size_x 4000 +#max_size_y 4000 + +# HTML files are normally generated by munin-html, no matter if the +# files are used or not. You can change this to on-demand generation +# by following the instructions in http://munin-monitoring.org/wiki/CgiHowto2 +# +# Notes: +# - moving to CGI for HTML means you cannot have graph generated by cron. +# - cgi html has some bugs, mostly you still have to launch munin-html by hand +# +#html_strategy cron + +# munin-update runs in parallel. +# +# The default max number of processes is 16, and is probably ok for you. +# +# If set too high, it might hit some process/ram/filedesc limits. +# If set too low, munin-update might take more than 5 min. +# +# If you want munin-update to not be parallel set it to 0. +# +#max_processes 16 + +# RRD updates are per default, performed directly on the rrd files. +# To reduce IO and enable the use of the rrdcached, uncomment it and set it to +# the location of the socket that rrdcached uses. +# +#rrdcached_socket /var/run/rrdcached.sock + +# Drop somejuser@fnord.comm and anotheruser@blibb.comm an email everytime +# something changes (OK -> WARNING, CRITICAL -> OK, etc) +#contact.someuser.command mail -s "Munin notification" somejuser@fnord.comm +#contact.anotheruser.command mail -s "Munin notification" anotheruser@blibb.comm +# +# For those with Nagios, the following might come in handy. In addition, +# the services must be defined in the Nagios server as well. +#contact.nagios.command /usr/bin/send_nsca nagios.host.comm -c /etc/nsca.conf + +# a simple host tree +[localhost.localdomain] + address 127.0.0.1 + use_node_name yes + +# +# A more complex example of a host tree +# +## First our "normal" host. +# [fii.foo.com] +# address foo +# +## Then our other host... +# [fay.foo.com] +# address fay +# +## IPv6 host. note that the ip adress has to be in brackets +# [ip6.foo.com] +# address [2001::1234:1] +# +## Then we want totals... +# [foo.com;Totals] #Force it into the "foo.com"-domain... +# update no # Turn off data-fetching for this "host". +# +# # The graph "load1". We want to see the loads of both machines... +# # "fii=fii.foo.com:load.load" means "label=machine:graph.field" +# load1.graph_title Loads side by side +# load1.graph_order fii=fii.foo.com:load.load fay=fay.foo.com:load.load +# +# # The graph "load2". Now we want them stacked on top of each other. +# load2.graph_title Loads on top of each other +# load2.dummy_field.stack fii=fii.foo.com:load.load fay=fay.foo.com:load.load +# load2.dummy_field.draw AREA # We want area instead the default LINE2. +# load2.dummy_field.label dummy # This is needed. Silly, really. +# +# # The graph "load3". Now we want them summarised into one field +# load3.graph_title Loads summarised +# load3.combined_loads.sum fii.foo.com:load.load fay.foo.com:load.load +# load3.combined_loads.label Combined loads # Must be set, as this is +# # not a dummy field! +# +## ...and on a side note, I want them listen in another order (default is +## alphabetically) +# +# # Since [foo.com] would be interpreted as a host in the domain "com", we +# # specify that this is a domain by adding a semicolon. +# [foo.com;] +# node_order Totals fii.foo.com fay.foo.com +# diff --git a/roles/munin/handlers/main.yml b/roles/munin/handlers/main.yml new file mode 100644 index 0000000..1d51061 --- /dev/null +++ b/roles/munin/handlers/main.yml @@ -0,0 +1,4 @@ +--- +# file: roles/munin/handlers/main.yml +- name: restart munin-node + service: name=munin-node state=restarted diff --git a/roles/munin/tasks/main.yml b/roles/munin/tasks/main.yml new file mode 100644 index 0000000..77b917c --- /dev/null +++ b/roles/munin/tasks/main.yml @@ -0,0 +1,6 @@ +--- +- include: munin.yml + tags: munin + +- include: munin-node.yml + tags: munin-node diff --git a/roles/munin/tasks/munin-node.yml b/roles/munin/tasks/munin-node.yml new file mode 100644 index 0000000..96d8e20 --- /dev/null +++ b/roles/munin/tasks/munin-node.yml @@ -0,0 +1,27 @@ +--- +- name: Install munin-node + action: "{{ ansible_pkg_mgr }} name={{ item }} state=latest" + with_items: + - munin-node + +# some nice things to have for munin-node on Ubuntu +- name: Install munin-node deps + when: ansible_distribution == "Ubuntu" + apt: name={{ item }} state=present + with_items: + - libwww-perl #for munin's nginx_status check + +- name: Create munin-node.conf + template: src=munin-node.conf.j2 dest=/etc/munin/munin-node.conf + notify: + - restart munin-node + +- name: Configure munin-node + shell: munin-node-configure --shell --families=contrib,auto | sh -x + notify: + - restart munin-node + +- name: Start munin-node + service: name=munin-node state=started enabled=true + +# vim: set ts=2 sw=2: diff --git a/roles/munin/tasks/munin.yml b/roles/munin/tasks/munin.yml new file mode 100644 index 0000000..bed4cc8 --- /dev/null +++ b/roles/munin/tasks/munin.yml @@ -0,0 +1,10 @@ +--- +- name: Install munin package + action: "{{ ansible_pkg_mgr }} name={{ item }} state=latest" + with_items: + - munin + +- name: Create munin configuration file + template: src=munin.conf.j2 dest=/etc/munin/munin.conf owner=root group=root mode=0644 + +# vim: set ts=2 sw=2: diff --git a/roles/munin/templates/munin-node.conf.j2 b/roles/munin/templates/munin-node.conf.j2 new file mode 100644 index 0000000..1c2db82 --- /dev/null +++ b/roles/munin/templates/munin-node.conf.j2 @@ -0,0 +1,71 @@ +# +# Example config-file for munin-node +# + +log_level 4 +{% if ansible_distribution == "Ubuntu" %} +log_file /var/log/munin/munin-node.log +{% else %} +log_file /var/log/munin-node/munin-node.log +{% endif %} +pid_file /var/run/munin/munin-node.pid + +background 1 +setsid 1 + +user root +group root + +# This is the timeout for the whole transaction. +# Units are in sec. Default is 15 min +# +# global_timeout 900 + +# This is the timeout for each plugin. +# Units are in sec. Default is 1 min +# +# timeout 60 + +# Regexps for files to ignore +ignore_file [\#~]$ +ignore_file DEADJOE$ +ignore_file \.bak$ +ignore_file %$ +ignore_file \.dpkg-(tmp|new|old|dist)$ +ignore_file \.rpm(save|new)$ +ignore_file \.pod$ + +# Set this if the client doesn't report the correct hostname when +# telnetting to localhost, port 4949 +# +host_name {{ inventory_hostname }} + +# A list of addresses that are allowed to connect. This must be a +# regular expression, since Net::Server does not understand CIDR-style +# network notation unless the perl module Net::CIDR is installed. You +# may repeat the allow line as many times as you'd like + +allow ^127\.0\.0\.1$ +allow ^::1$ + +# If you have installed the Net::CIDR perl module, you can use one or more +# cidr_allow and cidr_deny address/mask patterns. A connecting client must +# match any cidr_allow, and not match any cidr_deny. Note that a netmask +# *must* be provided, even if it's /32 +# +# Example: +# +# cidr_allow 127.0.0.1/32 +# cidr_allow 192.0.2.0/24 +# cidr_deny 192.0.2.42/32 + +{% if munin_master_host is defined %} +cidr_allow {{ munin_master_host }} +{% endif %} + +# Which address to bind to; +host * +# host 127.0.0.1 + +# And which port +port 4949 diff --git a/roles/munin/templates/munin.conf.j2 b/roles/munin/templates/munin.conf.j2 new file mode 100644 index 0000000..6aff1a0 --- /dev/null +++ b/roles/munin/templates/munin.conf.j2 @@ -0,0 +1,145 @@ +# Example configuration file for Munin, generated by 'make build' + +# The next three variables specifies where the location of the RRD +# databases, the HTML output, logs and the lock/pid files. They all +# must be writable by the user running munin-cron. They are all +# defaulted to the values you see here. +# +#dbdir /var/lib/munin +#htmldir /var/cache/munin/www +#logdir /var/log/munin +#rundir /var/run/munin + +# Where to look for the HTML templates +# +#tmpldir /etc/munin/templates + +# Where to look for the static www files +# +#staticdir /etc/munin/static + +# temporary cgi files are here. note that it has to be writable by +# the cgi user (usually nobody or httpd). +# +# cgitmpdir /var/lib/munin/cgi-tmp + +# (Exactly one) directory to include all files from. +includedir /etc/munin/munin-conf.d + +# You can choose the time reference for "DERIVE" like graphs, and show +# "per minute", "per hour" values instead of the default "per second" +# +#graph_period second + +# Graphics files are generated either via cron or by a CGI process. +# See http://munin-monitoring.org/wiki/CgiHowto2 for more +# documentation. +# Since 2.0, munin-graph has been rewritten to use the cgi code. +# It is single threaded *by design* now. +# +#graph_strategy cron + +# munin-cgi-graph is invoked by the web server up to very many times at the +# same time. This is not optimal since it results in high CPU and memory +# consumption to the degree that the system can thrash. Again the default is +# 6. Most likely the optimal number for max_cgi_graph_jobs is the same as +# max_graph_jobs. +# +#munin_cgi_graph_jobs 6 + +# If the automatic CGI url is wrong for your system override it here: +# +#cgiurl_graph /munin-cgi/munin-cgi-graph + +# max_size_x and max_size_y are the max size of images in pixel. +# Default is 4000. Do not make it too large otherwise RRD might use all +# RAM to generate the images. +# +#max_size_x 4000 +#max_size_y 4000 + +# HTML files are normally generated by munin-html, no matter if the +# files are used or not. You can change this to on-demand generation +# by following the instructions in http://munin-monitoring.org/wiki/CgiHowto2 +# +# Notes: +# - moving to CGI for HTML means you cannot have graph generated by cron. +# - cgi html has some bugs, mostly you still have to launch munin-html by hand +# +#html_strategy cron + +# munin-update runs in parallel. +# +# The default max number of processes is 16, and is probably ok for you. +# +# If set too high, it might hit some process/ram/filedesc limits. +# If set too low, munin-update might take more than 5 min. +# +# If you want munin-update to not be parallel set it to 0. +# +#max_processes 16 + +# RRD updates are per default, performed directly on the rrd files. +# To reduce IO and enable the use of the rrdcached, uncomment it and set it to +# the location of the socket that rrdcached uses. +# +#rrdcached_socket /var/run/rrdcached.sock + +# Drop somejuser@fnord.comm and anotheruser@blibb.comm an email everytime +# something changes (OK -> WARNING, CRITICAL -> OK, etc) +#contact.someuser.command mail -s "Munin notification" somejuser@fnord.comm +#contact.anotheruser.command mail -s "Munin notification" anotheruser@blibb.comm +# +# For those with Nagios, the following might come in handy. In addition, +# the services must be defined in the Nagios server as well. +#contact.nagios.command /usr/bin/send_nsca nagios.host.comm -c /etc/nsca.conf + +# a simple host tree +[{{ inventory_hostname }}.{{ dns_domain }}] + address 127.0.0.1 + use_node_name yes + +# +# A more complex example of a host tree +# +## First our "normal" host. +# [fii.foo.com] +# address foo +# +## Then our other host... +# [fay.foo.com] +# address fay +# +## IPv6 host. note that the ip adress has to be in brackets +# [ip6.foo.com] +# address [2001::1234:1] +# +## Then we want totals... +# [foo.com;Totals] #Force it into the "foo.com"-domain... +# update no # Turn off data-fetching for this "host". +# +# # The graph "load1". We want to see the loads of both machines... +# # "fii=fii.foo.com:load.load" means "label=machine:graph.field" +# load1.graph_title Loads side by side +# load1.graph_order fii=fii.foo.com:load.load fay=fay.foo.com:load.load +# +# # The graph "load2". Now we want them stacked on top of each other. +# load2.graph_title Loads on top of each other +# load2.dummy_field.stack fii=fii.foo.com:load.load fay=fay.foo.com:load.load +# load2.dummy_field.draw AREA # We want area instead the default LINE2. +# load2.dummy_field.label dummy # This is needed. Silly, really. +# +# # The graph "load3". Now we want them summarised into one field +# load3.graph_title Loads summarised +# load3.combined_loads.sum fii.foo.com:load.load fay.foo.com:load.load +# load3.combined_loads.label Combined loads # Must be set, as this is +# # not a dummy field! +# +## ...and on a side note, I want them listen in another order (default is +## alphabetically) +# +# # Since [foo.com] would be interpreted as a host in the domain "com", we +# # specify that this is a domain by adding a semicolon. +# [foo.com;] +# node_order Totals fii.foo.com fay.foo.com +# diff --git a/roles/munin/templates/tomcat.conf.j2 b/roles/munin/templates/tomcat.conf.j2 new file mode 100644 index 0000000..cd5e416 --- /dev/null +++ b/roles/munin/templates/tomcat.conf.j2 @@ -0,0 +1,5 @@ +[tomcat_*] + env.host 127.0.0.1 + env.port 8081 + env.user {{ munin_tomcat_user }} + env.password {{ munin_tomcat_password }} diff --git a/roles/nginx/files/munin.conf b/roles/nginx/files/munin.conf new file mode 100644 index 0000000..46941fb --- /dev/null +++ b/roles/nginx/files/munin.conf @@ -0,0 +1,23 @@ +# nginx status module + munin aliases +server { + listen localhost:80; + + location /nginx_status { + stub_status on; + access_log off; + allow 127.0.0.1; + deny all; + } + + location /munin/static/ { + alias /etc/munin/static/; + expires modified +1w; + } + + location /munin/ { + alias /var/cache/munin/www/; + expires modified +310s; + } +} + +# vim: set ts=4 sw=4: diff --git a/roles/nginx/files/nginx.conf b/roles/nginx/files/nginx.conf new file mode 100644 index 0000000..ff0346a --- /dev/null +++ b/roles/nginx/files/nginx.conf @@ -0,0 +1,41 @@ + +user nginx; +worker_processes auto; + +error_log /var/log/nginx/error.log error; +pid /var/run/nginx.pid; + + +events { + worker_connections 1024; +} + + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + server_tokens off; + + access_log off; + + sendfile on; + #tcp_nopush on; + + keepalive_timeout 65; + + gzip on; + gzip_vary on; + gzip_min_length 860; + gzip_disable "msie6"; + gzip_http_version 1.1; + gzip_types text/plain text/css text/xml application/rss+xml application/javascript; + + client_max_body_size 12m; + + include /etc/nginx/conf.d/*.conf; +} diff --git a/roles/nginx/handlers/main.yml b/roles/nginx/handlers/main.yml new file mode 100644 index 0000000..3125c04 --- /dev/null +++ b/roles/nginx/handlers/main.yml @@ -0,0 +1,5 @@ +--- +- name: reload nginx + service: name=nginx state=reloaded + +# vim: set ts=2 sw=2: diff --git a/roles/nginx/tasks/main.yml b/roles/nginx/tasks/main.yml new file mode 100644 index 0000000..ec8fb55 --- /dev/null +++ b/roles/nginx/tasks/main.yml @@ -0,0 +1,48 @@ +--- +- name: Add nginx.org apt signing key + apt_key: url=http://nginx.org/keys/nginx_signing.key state=present + tags: nginx + +- name: Add nginx.org stable repo + apt_repository: repo="deb http://nginx.org/packages/ubuntu/ {{ ansible_distribution_release }} nginx" state=present + tags: nginx + +- name: Install nginx + apt: pkg=nginx update_cache=yes + tags: nginx + +- name: Copy nginx config + copy: src={{ item }} dest=/etc/nginx/{{ item }} mode=0644 owner=root group=root + with_items: + - nginx.conf + notify: + - reload nginx + tags: nginx + +- name: Remove default nginx vhost + file: path=/etc/nginx/conf.d/default.conf state=absent + tags: nginx + +# need to modularize so we can have different vhosts in different files (apples.com and bananas.com in separate config files) +- name: Configure nginx vhosts + template: src={{ item }} dest=/etc/nginx/conf.d/{{ inventory_hostname }}.conf mode=0644 owner=root group=root + with_first_found: + - "../templates/{{ inventory_hostname }}.conf.j2" + - "../templates/default.conf.j2" + notify: + - reload nginx + tags: nginx + +- name: Configure munin vhost + copy: src=munin.conf dest=/etc/nginx/conf.d/munin.conf mode=0644 owner=root group=root + notify: + - reload nginx + tags: nginx + +- name: Generate 2048-bit dhparam + command: openssl dhparam -out dhparam.pem 2048 chdir=/etc/ssl/certs creates=dhparam.pem + tags: nginx + +- name: Start & enable nginx service + service: name=nginx state=started enabled=yes + tags: nginx diff --git a/roles/nginx/templates/default.conf.j2 b/roles/nginx/templates/default.conf.j2 new file mode 100644 index 0000000..90a47d3 --- /dev/null +++ b/roles/nginx/templates/default.conf.j2 @@ -0,0 +1,9 @@ +server { + listen 80; + server_name localhost; + + location / { + root /usr/share/nginx/html; + index index.html index.htm; + } +} diff --git a/roles/nginx/templates/web01.conf.j2 b/roles/nginx/templates/web01.conf.j2 new file mode 100644 index 0000000..c8d9eb7 --- /dev/null +++ b/roles/nginx/templates/web01.conf.j2 @@ -0,0 +1,35 @@ +server { + listen 80 default_server; + listen [::]:80 default_server ipv6only=on; + + root /usr/share/nginx/html; + + server_name web01.mjanja.co.ke; + + location / { + try_files $uri $uri/ =404; + } + + error_page 404 /404.html; + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } + + location ~ \.php$ { + # Zero-day exploit defense. + # http://forum.nginx.org/read.php?2,88845,page=3 + # Won't work properly (404 error) if the file is not stored on this server, which is entirely possible with php-fpm/php-fcgi. + # Comment the 'try_files' line out if you set up php-fpm/php-fcgi on another machine. And then cross your fingers that you won't get hacked. + try_files $uri =404; + + #NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini + fastcgi_split_path_info ^(.+\.php)(/.+)$; + + fastcgi_pass php5-fpm-sock; + fastcgi_index index.php; + # set script path relative to document root in server block + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + include fastcgi_params; + } +} diff --git a/roles/php5-fpm/files/www.conf b/roles/php5-fpm/files/www.conf new file mode 100644 index 0000000..2d1ad23 --- /dev/null +++ b/roles/php5-fpm/files/www.conf @@ -0,0 +1,392 @@ +; Start a new pool named 'www'. +; the variable $pool can we used in any directive and will be replaced by the +; pool name ('www' here) +[www] + +; Per pool prefix +; It only applies on the following directives: +; - 'slowlog' +; - 'listen' (unixsocket) +; - 'chroot' +; - 'chdir' +; - 'php_values' +; - 'php_admin_values' +; When not set, the global prefix (or /usr) applies instead. +; Note: This directive can also be relative to the global prefix. +; Default Value: none +;prefix = /path/to/pools/$pool + +; Unix user/group of processes +; Note: The user is mandatory. If the group is not set, the default user's group +; will be used. +user = nginx +group = nginx + +; The address on which to accept FastCGI requests. +; Valid syntaxes are: +; 'ip.add.re.ss:port' - to listen on a TCP socket to a specific address on +; a specific port; +; 'port' - to listen on a TCP socket to all addresses on a +; specific port; +; '/path/to/unix/socket' - to listen on a unix socket. +; Note: This value is mandatory. +listen = /var/run/php5-fpm.sock + +; Set listen(2) backlog. +; Default Value: 65535 (-1 on FreeBSD and OpenBSD) +;listen.backlog = 65535 + +; Set permissions for unix socket, if one is used. In Linux, read/write +; permissions must be set in order to allow connections from a web server. Many +; BSD-derived systems allow connections regardless of permissions. +; Default Values: user and group are set as the running user +; mode is set to 0660 +listen.owner = nginx +listen.group = nginx +;listen.mode = 0660 + +; List of ipv4 addresses of FastCGI clients which are allowed to connect. +; Equivalent to the FCGI_WEB_SERVER_ADDRS environment variable in the original +; PHP FCGI (5.2.2+). Makes sense only with a tcp listening socket. Each address +; must be separated by a comma. If this value is left blank, connections will be +; accepted from any ip address. +; Default Value: any +;listen.allowed_clients = 127.0.0.1 + +; Specify the nice(2) priority to apply to the pool processes (only if set) +; The value can vary from -19 (highest priority) to 20 (lower priority) +; Note: - It will only work if the FPM master process is launched as root +; - The pool processes will inherit the master process priority +; unless it specified otherwise +; Default Value: no set +; priority = -19 + +; Choose how the process manager will control the number of child processes. +; Possible Values: +; static - a fixed number (pm.max_children) of child processes; +; dynamic - the number of child processes are set dynamically based on the +; following directives. With this process management, there will be +; always at least 1 children. +; pm.max_children - the maximum number of children that can +; be alive at the same time. +; pm.start_servers - the number of children created on startup. +; pm.min_spare_servers - the minimum number of children in 'idle' +; state (waiting to process). If the number +; of 'idle' processes is less than this +; number then some children will be created. +; pm.max_spare_servers - the maximum number of children in 'idle' +; state (waiting to process). If the number +; of 'idle' processes is greater than this +; number then some children will be killed. +; ondemand - no children are created at startup. Children will be forked when +; new requests will connect. The following parameter are used: +; pm.max_children - the maximum number of children that +; can be alive at the same time. +; pm.process_idle_timeout - The number of seconds after which +; an idle process will be killed. +; Note: This value is mandatory. +pm = dynamic + +; The number of child processes to be created when pm is set to 'static' and the +; maximum number of child processes when pm is set to 'dynamic' or 'ondemand'. +; This value sets the limit on the number of simultaneous requests that will be +; served. Equivalent to the ApacheMaxClients directive with mpm_prefork. +; Equivalent to the PHP_FCGI_CHILDREN environment variable in the original PHP +; CGI. The below defaults are based on a server without much resources. Don't +; forget to tweak pm.* to fit your needs. +; Note: Used when pm is set to 'static', 'dynamic' or 'ondemand' +; Note: This value is mandatory. +pm.max_children = 5 + +; The number of child processes created on startup. +; Note: Used only when pm is set to 'dynamic' +; Default Value: min_spare_servers + (max_spare_servers - min_spare_servers) / 2 +pm.start_servers = 2 + +; The desired minimum number of idle server processes. +; Note: Used only when pm is set to 'dynamic' +; Note: Mandatory when pm is set to 'dynamic' +pm.min_spare_servers = 1 + +; The desired maximum number of idle server processes. +; Note: Used only when pm is set to 'dynamic' +; Note: Mandatory when pm is set to 'dynamic' +pm.max_spare_servers = 3 + +; The number of seconds after which an idle process will be killed. +; Note: Used only when pm is set to 'ondemand' +; Default Value: 10s +;pm.process_idle_timeout = 10s; + +; The number of requests each child process should execute before respawning. +; This can be useful to work around memory leaks in 3rd party libraries. For +; endless request processing specify '0'. Equivalent to PHP_FCGI_MAX_REQUESTS. +; Default Value: 0 +;pm.max_requests = 500 + +; The URI to view the FPM status page. If this value is not set, no URI will be +; recognized as a status page. It shows the following informations: +; pool - the name of the pool; +; process manager - static, dynamic or ondemand; +; start time - the date and time FPM has started; +; start since - number of seconds since FPM has started; +; accepted conn - the number of request accepted by the pool; +; listen queue - the number of request in the queue of pending +; connections (see backlog in listen(2)); +; max listen queue - the maximum number of requests in the queue +; of pending connections since FPM has started; +; listen queue len - the size of the socket queue of pending connections; +; idle processes - the number of idle processes; +; active processes - the number of active processes; +; total processes - the number of idle + active processes; +; max active processes - the maximum number of active processes since FPM +; has started; +; max children reached - number of times, the process limit has been reached, +; when pm tries to start more children (works only for +; pm 'dynamic' and 'ondemand'); +; Value are updated in real time. +; Example output: +; pool: www +; process manager: static +; start time: 01/Jul/2011:17:53:49 +0200 +; start since: 62636 +; accepted conn: 190460 +; listen queue: 0 +; max listen queue: 1 +; listen queue len: 42 +; idle processes: 4 +; active processes: 11 +; total processes: 15 +; max active processes: 12 +; max children reached: 0 +; +; By default the status page output is formatted as text/plain. Passing either +; 'html', 'xml' or 'json' in the query string will return the corresponding +; output syntax. Example: +; http://www.foo.bar/status +; http://www.foo.bar/status?json +; http://www.foo.bar/status?html +; http://www.foo.bar/status?xml +; +; By default the status page only outputs short status. Passing 'full' in the +; query string will also return status for each pool process. +; Example: +; http://www.foo.bar/status?full +; http://www.foo.bar/status?json&full +; http://www.foo.bar/status?html&full +; http://www.foo.bar/status?xml&full +; The Full status returns for each process: +; pid - the PID of the process; +; state - the state of the process (Idle, Running, ...); +; start time - the date and time the process has started; +; start since - the number of seconds since the process has started; +; requests - the number of requests the process has served; +; request duration - the duration in µs of the requests; +; request method - the request method (GET, POST, ...); +; request URI - the request URI with the query string; +; content length - the content length of the request (only with POST); +; user - the user (PHP_AUTH_USER) (or '-' if not set); +; script - the main script called (or '-' if not set); +; last request cpu - the %cpu the last request consumed +; it's always 0 if the process is not in Idle state +; because CPU calculation is done when the request +; processing has terminated; +; last request memory - the max amount of memory the last request consumed +; it's always 0 if the process is not in Idle state +; because memory calculation is done when the request +; processing has terminated; +; If the process is in Idle state, then informations are related to the +; last request the process has served. Otherwise informations are related to +; the current request being served. +; Example output: +; ************************ +; pid: 31330 +; state: Running +; start time: 01/Jul/2011:17:53:49 +0200 +; start since: 63087 +; requests: 12808 +; request duration: 1250261 +; request method: GET +; request URI: /test_mem.php?N=10000 +; content length: 0 +; user: - +; script: /home/fat/web/docs/php/test_mem.php +; last request cpu: 0.00 +; last request memory: 0 +; +; Note: There is a real-time FPM status monitoring sample web page available +; It's available in: ${prefix}/share/fpm/status.html +; +; Note: The value must start with a leading slash (/). The value can be +; anything, but it may not be a good idea to use the .php extension or it +; may conflict with a real PHP file. +; Default Value: not set +;pm.status_path = /status + +; The ping URI to call the monitoring page of FPM. If this value is not set, no +; URI will be recognized as a ping page. This could be used to test from outside +; that FPM is alive and responding, or to +; - create a graph of FPM availability (rrd or such); +; - remove a server from a group if it is not responding (load balancing); +; - trigger alerts for the operating team (24/7). +; Note: The value must start with a leading slash (/). The value can be +; anything, but it may not be a good idea to use the .php extension or it +; may conflict with a real PHP file. +; Default Value: not set +;ping.path = /ping + +; This directive may be used to customize the response of a ping request. The +; response is formatted as text/plain with a 200 response code. +; Default Value: pong +;ping.response = pong + +; The access log file +; Default: not set +;access.log = log/$pool.access.log + +; The access log format. +; The following syntax is allowed +; %%: the '%' character +; %C: %CPU used by the request +; it can accept the following format: +; - %{user}C for user CPU only +; - %{system}C for system CPU only +; - %{total}C for user + system CPU (default) +; %d: time taken to serve the request +; it can accept the following format: +; - %{seconds}d (default) +; - %{miliseconds}d +; - %{mili}d +; - %{microseconds}d +; - %{micro}d +; %e: an environment variable (same as $_ENV or $_SERVER) +; it must be associated with embraces to specify the name of the env +; variable. Some exemples: +; - server specifics like: %{REQUEST_METHOD}e or %{SERVER_PROTOCOL}e +; - HTTP headers like: %{HTTP_HOST}e or %{HTTP_USER_AGENT}e +; %f: script filename +; %l: content-length of the request (for POST request only) +; %m: request method +; %M: peak of memory allocated by PHP +; it can accept the following format: +; - %{bytes}M (default) +; - %{kilobytes}M +; - %{kilo}M +; - %{megabytes}M +; - %{mega}M +; %n: pool name +; %o: output header +; it must be associated with embraces to specify the name of the header: +; - %{Content-Type}o +; - %{X-Powered-By}o +; - %{Transfert-Encoding}o +; - .... +; %p: PID of the child that serviced the request +; %P: PID of the parent of the child that serviced the request +; %q: the query string +; %Q: the '?' character if query string exists +; %r: the request URI (without the query string, see %q and %Q) +; %R: remote IP address +; %s: status (response code) +; %t: server time the request was received +; it can accept a strftime(3) format: +; %d/%b/%Y:%H:%M:%S %z (default) +; %T: time the log has been written (the request has finished) +; it can accept a strftime(3) format: +; %d/%b/%Y:%H:%M:%S %z (default) +; %u: remote user +; +; Default: "%R - %u %t \"%m %r\" %s" +;access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%" + +; The log file for slow requests +; Default Value: not set +; Note: slowlog is mandatory if request_slowlog_timeout is set +;slowlog = log/$pool.log.slow + +; The timeout for serving a single request after which a PHP backtrace will be +; dumped to the 'slowlog' file. A value of '0s' means 'off'. +; Available units: s(econds)(default), m(inutes), h(ours), or d(ays) +; Default Value: 0 +;request_slowlog_timeout = 0 + +; The timeout for serving a single request after which the worker process will +; be killed. This option should be used when the 'max_execution_time' ini option +; does not stop script execution for some reason. A value of '0' means 'off'. +; Available units: s(econds)(default), m(inutes), h(ours), or d(ays) +; Default Value: 0 +;request_terminate_timeout = 0 + +; Set open file descriptor rlimit. +; Default Value: system defined value +;rlimit_files = 1024 + +; Set max core size rlimit. +; Possible Values: 'unlimited' or an integer greater or equal to 0 +; Default Value: system defined value +;rlimit_core = 0 + +; Chroot to this directory at the start. This value must be defined as an +; absolute path. When this value is not set, chroot is not used. +; Note: you can prefix with '$prefix' to chroot to the pool prefix or one +; of its subdirectories. If the pool prefix is not set, the global prefix +; will be used instead. +; Note: chrooting is a great security feature and should be used whenever +; possible. However, all PHP paths will be relative to the chroot +; (error_log, sessions.save_path, ...). +; Default Value: not set +;chroot = + +; Chdir to this directory at the start. +; Note: relative path can be used. +; Default Value: current directory or / when chroot +chdir = / + +; Redirect worker stdout and stderr into main error log. If not set, stdout and +; stderr will be redirected to /dev/null according to FastCGI specs. +; Note: on highloaded environement, this can cause some delay in the page +; process time (several ms). +; Default Value: no +catch_workers_output = yes + +; Limits the extensions of the main script FPM will allow to parse. This can +; prevent configuration mistakes on the web server side. You should only limit +; FPM to .php extensions to prevent malicious users to use other extensions to +; exectute php code. +; Note: set an empty value to allow all extensions. +; Default Value: .php +;security.limit_extensions = .php .php3 .php4 .php5 + +; Pass environment variables like LD_LIBRARY_PATH. All $VARIABLEs are taken from +; the current environment. +; Default Value: clean env +;env[HOSTNAME] = $HOSTNAME +;env[PATH] = /usr/local/bin:/usr/bin:/bin +;env[TMP] = /tmp +;env[TMPDIR] = /tmp +;env[TEMP] = /tmp + +; Additional php.ini defines, specific to this pool of workers. These settings +; overwrite the values previously defined in the php.ini. The directives are the +; same as the PHP SAPI: +; php_value/php_flag - you can set classic ini defines which can +; be overwritten from PHP call 'ini_set'. +; php_admin_value/php_admin_flag - these directives won't be overwritten by +; PHP call 'ini_set' +; For php_*flag, valid values are on, off, 1, 0, true, false, yes or no. + +; Defining 'extension' will load the corresponding shared extension from +; extension_dir. Defining 'disable_functions' or 'disable_classes' will not +; overwrite previously defined php.ini values, but will append the new value +; instead. + +; Note: path INI options can be relative and will be expanded with the prefix +; (pool, global or /usr) + +; Default Value: nothing is defined by default except the values in php.ini and +; specified at startup with the -d argument +;php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f www@my.domain.com +;php_flag[display_errors] = off +;php_admin_value[error_log] = /var/log/fpm-php.www.log +;php_admin_flag[log_errors] = on +;php_admin_value[memory_limit] = 32M diff --git a/roles/php5-fpm/handlers/main.yml b/roles/php5-fpm/handlers/main.yml new file mode 100644 index 0000000..2ce2736 --- /dev/null +++ b/roles/php5-fpm/handlers/main.yml @@ -0,0 +1,5 @@ +--- +- name: restart php5-fpm + service: name=php5-fpm state=restarted + +# vim: set ts=2 sw=2: diff --git a/roles/php5-fpm/tasks/main.yml b/roles/php5-fpm/tasks/main.yml new file mode 100644 index 0000000..2b20118 --- /dev/null +++ b/roles/php5-fpm/tasks/main.yml @@ -0,0 +1,24 @@ +--- +- name: Install php5-fpm and deps + apt: name={{ item }} state=present update_cache=yes + with_items: + - php5-fpm + # probably belong in wordpress role + - php5-mysql + - php5-gd + - php5-curl + tags: php5-fpm + +- name: Copy php5-fpm pool config + copy: src=www.conf dest=/etc/php5/fpm/pool.d/www.conf owner=root group=root mode=0644 + notify: restart php5-fpm + tags: php5-fpm + +# re-configure php to only process exact paths, see: +# http://codex.wordpress.org/Nginx +- name: Update php.ini + lineinfile: dest=/etc/php5/fpm/php.ini regexp=^;cgi.fix_pathinfo line=cgi.fix_pathinfo=0 + notify: restart php5-fpm + tags: php5-fpm + +# vim: set ts=2 sw=2: diff --git a/site.yml b/site.yml new file mode 100644 index 0000000..552f3b2 --- /dev/null +++ b/site.yml @@ -0,0 +1,17 @@ +--- +# file: site.yml + +- name: Configure mjanja.co.ke + hosts: web + sudo: yes + roles: + - common + - mariadb + - nginx + - php5-fpm +# - wordpress + - munin + vars_files: + - "vars/{{ ansible_os_family }}.yml" + +# vim: set sw=2 ts=2: diff --git a/vars/Debian.yml b/vars/Debian.yml new file mode 100644 index 0000000..fda2c7a --- /dev/null +++ b/vars/Debian.yml @@ -0,0 +1,8 @@ +--- + +# sshd service name is `ssh` on Debian/Ubuntu, but it's +# `sshd` on CentOS +sshd_service_name: ssh + +# default Kenyan Ubuntu mirror +apt_mirror: ubuntu.mirror.ac.ke