Changeset - 0079746d9a8b
[Not reviewed]
0 4 1
Branko Majic (branko) - 9 years ago 2015-05-06 21:54:56
branko@majic.rs
MAR-5: Updated the web server role to include deployment of some base packages for PHP and Python web apps.
5 files changed with 39 insertions and 0 deletions:
0 comments (0 inline, 0 general)
docs/rolereference.rst
Show inline comments
 
Role Reference
 
==============
 

	
 

	
 
Preseed
 
-------
 

	
 
The ``preseed`` role can be used for generating simple preseed files for Debian
 
Wheezy installations.
 

	
 
The generated preseed files allow simplified installation, with a single root
 
partition. A number of common parameters can be provided.
 

	
 

	
 
Parameters
 
~~~~~~~~~~
 

	
 
**ansible_key** (string, mandatory)
 
  SSH public key that should be deployed to authorized_keys truststore for
 
  operating system user ``root``. This is necessary for the bootstrap process
 
  to work since Debian Jessie does not allow password-based logins for root.
 

	
 
**preseed_directory** (mandatory)
 
    Destination directory where the preseed files should be stored.
 

	
 
**preseed_servers** (mandatory)
 
  List of servers for which a preseed file should be created. Each item in
 
  this list defines options for a single server. The options are as follows:
 

	
 
  **name** (string, mandatory)
 
    Name associated with the server. This name is used in the preseed
 
    configuration filename.
 

	
 
  **language** (string, mandatory)
 
    Language.
 

	
 
  **country** (string, mandatory)
 
    Country.
 

	
 
  **locale** (string, mandatory)
 
    Locale.
 

	
 
  **keymap** (string, mandatory)
 
    Keymap.
 

	
 
  **network_interface** (string, mandatory)
 
    Name of network interface (for example *eth0*) that should be
 
    configured.
 

	
 
  **network_auto** (boolean, mandatory)
 
    Specifies whether the network configuration should be automatic (using
 
    DHCP) or manual. If manual configuration is selected a number of
 
    additional options needs to be specified.
 

	
 
  **network_ip** (string, mandatory if **network_auto** is set to ``no``)
 
    IP address for the server network interface.
 

	
 
  **network_netmask** (string, mandatory if **network_auto** is set to ``no``)
 
    Netmask for the server network interface.
 

	
 
  **network_gateway** (string, mandatory if **network_auto** is set to ``no``)
 
    Default gateway for the server.
 

	
 
  **network_dns** (string, mandatory if **network_auto** is set to ``no``)
 
    Comma-separated list of DNS servers.
 

	
 
  **network_hostname** (string, mandatory if **network_auto** is set to ``no``)
 
    Server hostname.
 

	
 
  **network_domain** (string, mandatory if **network_auto** is set to ``no``)
 
    Server domain.
 

	
 
  **mirror_hostname** (string, mandatory)
 
    Resolvable hostname of FQDN where the Debian apt repositories can be
 
    found. Only HTTP mirrors are supported.
 

	
 
  **mirror_directory** (string, mandatory)
 
    Directory under which the Debian apt repositories can be found on the
 
    specified mirror.
 

	
 
  **mirror_proxy** (string, optional, default is *None*)
 
    An HTTP proxy that should be used for accessing the Debian apt
 
    repositories.
 

	
 
  **root_password** (string, mandatory)
 
    Initial password that should be set for the server during the
 
    installation.
 

	
 
  **timezone** (string, mandatory)
 
    Timezone that should be used when calculating server time. It is assumed
 
    that the local hardware clock is set to UTC.
 

	
 

	
 
Examples
 
~~~~~~~~
 

	
 
Here is an example configuration for a preseed file for two servers, one with
 
automatic and one with manual network configuration:
 

	
 
.. code-block:: yaml
 

	
 
  ---
 

	
 
  preseed_directory: /var/www/preseed/
 

	
 
  preseed_servers:
 
    - name: test1.example.com
 
      language: en
 
      country: SE
 
      locale: en_US.UTF-8
 
      keymap: us
 
      network_interface: eth0
 
      network_auto: yes
 
      mirror_hostname: ftp.se.debian.org
 
      mirror_directory: /debian
 
      mirror_proxy: http://proxy.example.com/
 
      root_password: testserver
 
      timezone: Europe/Stockholm
 
    - name: test2.example.com
 
      language: en
 
      country: SE
 
      locale: en_US.UTF-8
 
      keymap: us
 
      network_interface: eth0
 
      network_auto: no
 
      network_ip: 10.0.0.10
 
      network_netmask: 255.255.255.0
 
      network_gateway: 10.0.0.1
 
      network_dns: 10.0.0.2,10.0.0.3
 
      network_hostname: test1
 
      network_domain: example.com
 
      mirror_hostname: ftp.se.debian.org
 
      mirror_proxy: http://proxy.example.com/
 
      mirror_directory: /debian
 
      root_password: testserver
 
      timezone: Europe/Stockholm
 

	
 

	
 
Bootstrap
 
---------
 

	
 
The ``bootstrap`` role can be used for bootstraping a new server with
 
Ansible. In order to apply this role to a server, all that is necessary is root
 
access to the server (either via SSH or locally).
 

	
 
The role implements the following:
 

	
 
* Installs sudo package.
 
* Creates operating system user and group for Ansible (``ansible``).
 
* Sets-up an authorized_key for operating system user ``ansible`` (for remote
 
  SSH access).
 
* Configures sudo to allow operating system user ``ansible`` to run sudo
 
  commands without password authentication.
 
* Removes the Ansible user's key from the list of authorized keys for user root
 
  at the end of bootstrap process. This key was necessary only for the bootstrap
 
  process.
 

	
 

	
 
Parameters
 
~~~~~~~~~~
 

	
 
**ansible_key** (string, mandatory)
 
  SSH public key that should be deployed to authorized_keys truststore for
 
  operating system user ``ansible``.
 

	
 

	
 
Examples
 
~~~~~~~~
 

	
 
Since the role is meant to be used just after the server has been installed, and
 
using the ``root`` account, it is probably going to be invoked from a separate
 
playbook.
 

	
 
For example, a playbook (``bootstrap.yml``) could look something similar to:
 

	
 
.. code-block:: yaml
 

	
 
  ---
 

	
 
  - hosts: "{{ server }}"
 
    remote_user: root
 
    roles:
 
      - bootstrap
 
    vars:
 
      ansible_key: "{{ lookup('file', 'authorized_keys/ansible.pub') }}"
 

	
 
With such a playbook in place, it would be invoked with:
 

	
 
  ansible-playbook --ask-pass -e server=test1.example.com bootstrap.yml
 

	
 

	
 
Common
 
------
 

	
 
The ``common`` role can be used for applying a common configuration and
 
hardening across all servers, no matter what services they provide.
 

	
 
The role implements the following:
 

	
 
* Sets-up umask for all logins to ``0027``.
 
* Installs sudo.
 
* Installs additional base packages, as configured.
 
* Creates additional operating system groups, as configured.
 
* Creates additional operating system users, as configured.
 
* Hardens the SSH server by disabling remote ``root`` logins and password-based
 
  authentication.
 
* Allows traversing of directory ``/etc/ssl/private/`` to everyone. This lets
 
  you put TLS private keys in central location where any operating system user
 
  can reach them provided they have appropriate read/write rights on the file
 
  itself, and provided they know the exact path of the file.
 
* Deploys CA certificate files, normally used for truststore purposes, to
 
  ``/etc/ssl/certs/``.
 
* Installs ``ferm`` (for iptables management), configuring a basic firewall
 
  which allows ICMP echo requests (PING), incoming connection on TCP port 22
 
  (SSH), and also introduces rate-limitting for incoming ICMP echo request
 
  pacakges and (new) TCP connections. The rate-limitting is based on the source
 
  IP address, using the ``iptables hashlimit`` module.
 

	
 

	
 
Parameters
 
~~~~~~~~~~
 

	
 
**os_users** (list, optional)
 
  A list of operating system users that should be set-up on a server. Each item
 
  is a dictionary with the following options describing the user parameters:
 

	
 
  **name** (string, mandatory)
 
    Name of the operating system user that should be created. User's default
 
    group will have the same name as the user.
 

	
 
  **uid** (number, mandatory)
 
    UID for the operating system user. User's default group will have a GID
 
    identical to the user's UID.
 

	
 
  **additional_groups** (string, mandatory)
 
    Comma-separated list of additional groups that a user should belong to. If
 
    no additional groups should be appended to user's list of groups, set it to
 
    empty string (``""``).
 

	
 
  **authorized_keys** (list, mandatory)
 
    List of SSH public keys that should be deployed to user's authorized_keys
 
    truststore. If no authorized keys should be deployed, set it to empty list
 
    (``[]``).
 

	
 
  **password** (string, mandatory)
 
    Encrypted password that should be set for the user.
 

	
 
**os_groups** (list, optional)
 
  A list of operating system groups that should be set-up on a server. Each item
 
  is a dictionary with the following options describing the group parameters:
 

	
 
  **name** (string, mandatory)
 
    Name of the operating system group that should be created.
 

	
 
  **gid** (number, mandatory)
 
    GID for the operating system group.
 

	
 
**common_packages** (list, optional)
 
  List of additional operating system packages that should be installed on the
 
  server. Each element of the list should be a simple string denoting the name
 
  of the package.
 

	
 
**ca_certificates** (list, optional)
 
  List of additional CA certificate files that should be deployed on the
 
  server. Each element of the list should be a filepath to a CA certificate file
 
  on originating (Ansible) host that should be copied to destination
 
  server.
 

	
 
**incoming_connection_limit** (string, mandatory)
 
  Rate at which the incoming ICMP echo-request packages and new TCP connections
 
  will be accepted at. The value should be specified in the same format as value
 
  for the ``iptables hashlimit`` option ``--hashlimit-upto``.
 

	
 
**incoming_connection_limit_burst** (string, mandatory)
 
  Initial burst of packages that should be accepted when the client with
 
  distinct source IP address connects to the server for the first time (usually
 
  higher than ``incoming_connection_limit``), even if it would go above the
 
  specified connection limit.
 

	
 

	
 
Examples
 
~~~~~~~~
 

	
 
Here is an example configuration for setting-up some common users, groups, and
 
packages on all servers:
 

	
 
.. code-block:: yaml
 

	
 
  ---
 

	
 
  os_users:
 
    - name: admin
 
      uid: 1000
 
      additional_groups: sudo
 
      authorized_keys:
 
        - "{{ lookup('file', '/home/admin/.ssh/id_rsa.pub') }}"
 
      password: '$6$AaJRWtqyX5pk$IP8DUjgY0y2zqMom9BAc.O9qHoQWLFCmEsPRCika6l/Xh87cp2SnlMywH0.r4uEcbHnoicQG46V9VrJ8fxp2d.'
 
    - name: john
 
      uid: 1001
 
      additional_groups: ""
 
      authorized_keys: []
 
      password: '$6$AaJRWtqyX5pk$IP8DUjgY0y2zqMom9BAc.O9qHoQWLFCmEsPRCika6l/Xh87cp2SnlMywH0.r4uEcbHnoicQG46V9VrJ8fxp2d.'
 

	
 
  os_groups:
 
    - name: localusers
 
      gid: 2500
 

	
 
  common_packages:
 
    - emacs23-nox
 
    - screen
 
    - debconf-utils
 

	
 
  ca_certificates:
 
    - ../certs/truststore.pem
 

	
 
  incoming_connection_limit: 2/second
 

	
 
  incoming_connection_limit_burst: 6
 

	
 
.. _ldap_client:
 

	
 
LDAP Client
 
-----------
 

	
 
The ``ldap_client`` role can be used for setting-up an OpenLDAP client on
 
destination machine.
 

	
 
The role implements the following:
 

	
 
* Installs OpenLDAP client tools.
 
* Sets-up global configuration file for OpenLDAP clients at /etc/ldap/ldap.conf.
 

	
 

	
 
Parameters
 
~~~~~~~~~~
 

	
 
**ldap_client_config** (list, mandatory)
 
  A list of configuration options that should be put into the LDAP configuration
 
  file. Each item is a dictionary with the following options defining the
 
  configuration parameter:
 

	
 
  **comment** (string, mandatory)
 
    Comment that will be shown in the file just above the configuration option.
 

	
 
  **option** (string, mandatory)
 
    Name of configuration option.
 

	
 
  **value** (string, mandatory)
 
    Value for configuration option.
 

	
 

	
 
Examples
 
~~~~~~~~
 

	
 
Here is an example configuration for setting some common LDAP client options:
 

	
 
.. code-block:: yaml
 

	
 
  ---
 

	
 
  ldap_client_config:
 
    - comment: Set the base DN
 
      option: BASE
 
      value: dc=example,dc=com
 
    - comment: Set the default URI
 
      option: URI
 
      value: ldap://ldap.example.com/
 
    - comment: Set the truststore for TLS/SSL
 
      option: TLS_CACERT
 
      value: /etc/ssl/certs/example_ca.pem
 
    - commment: Force basic server certificate verification
 
      option: TLS_REQCERT
 
      value: demand
 
    - comment: Disable CRL checks for server certificate
 
      option: TLS_CRLCHECK
 
      value: none
 

	
 

	
 
LDAP Server
 
-----------
 

	
 
The ``ldap_server`` role can be used for setting-up an OpenLDAP server on
 
destination machine.
 

	
 
The role implements the following:
 

	
 
* Deploys LDAP TLS private key and certificate.
 
* Installs OpenLDAP server (package ``slapd``).
 
* Configures OpenLDAP server (base DN - domain, organisation, TLS, SSF, log levels).
 
* Sets-up separate log file for OpenLDAP server at ``/var/log/slapd.log`` (with
 
  log rotation included).
 
* Enables the ``memberof`` overlay on top of default database. The overlay is
 
  configured to keep track of membership changes for object class
 
  ``groupOfUniqueNames`` via attribute ``uniqueMember``. Enforcement of
 
  referential integrity is turned on as well (modifications of ``memberof``
 
  attribute will update corresponding group as well.
 
* Configures permissions.
 
* Creates LDAP entries.
 
* Configures firewall to allow incoming connections to the LDAP server.
 

	
 

	
 
Parameters
 
~~~~~~~~~~
 

	
 
**ldap_server_config** (list, mandatory)
 
  A dictionary of configuration options for OpenLDAP server. The following
 
  configuration options are available:
 

	
 
  **domain** (string, mandatory)
 
    Domain that should be used for constructing the base DN of default user LDAP
 
    database. This should be a sub-domain dedicated to organisation. The base DN
 
    will be constructed by putting all elements of the sub-domain as ``dc``
 
    entries (as per standard Debian convention). I.e. ``example.com`` would get
 
    transformed into ``dc=example,dc=com``.
 

	
 
  **organization** (string, mandatory)
 
    Organization that should be specified in the base DN entry.
 

	
 
  **log_level** (string, mandatory)
 
    Log level to use for the server. This should be compatible with OpenLDAP
 
    configuration option ``olcLogLevel``. See `OpenLDAP Administrator's Guide
 
    <http://www.openldap.org/doc/admin24/slapdconf2.html#cn=config>` for value
 
    description and syntax.
 

	
 
  **tls_certificate** (string, mandatory)
 
    Path to file on Ansible host that contains the X.509 certificate used for
 
    TLS for LDAP service. The file will be copied to directory
 
    ``/etc/ssl/certs/``.
 

	
 
  **tls_key** (string, mandatory)
 
    Path to file on Ansible host that contains the private key used for TLS for
 
    LDAP service. The file will be copied to directory ``/etc/ssl/private/``.
 

	
 
  **ssf** (number, mandatory)
 
    Minimum *Security Strength Factor* to require from all incoming
 
    connections. This applies for both remote and local connections.
 

	
 
**ldap_permissions** (list, mandatory)
 
  List of LDAP access controls to apply to directories served by the LDAP
 
  server. Each item is a dictionary with the following options describing the
 
  permissions:
 

	
 
  **filter** (string, mandatory)
 
    An LDAP filter that should be applied on base DN ``cn=config`` using
 
    sub-tree scope to locate the LDAP database for which the access control
 
    rules will be applied. For default user database this could be something in
 
    the lines of ``(olcSuffix=dc=example,dc=com)``.
 

	
 
  **rules** (list, mandatory)
 
    A list of access control rules that should be applied for the selected
 
    database. The access control rules listed will *replace* all existing
 
    rules, and will be added in the same order they are listed in. Each item is
 
    a string that constitutes a single access control rule. The format should be
 
    the same as described in `OpenLDAP Administrator's Guide
 
    <http://www.openldap.org/doc/admin24/access-control.html#Access%20Control%20via%20Dynamic%20Configuration>`.
 

	
 
**ldap_entries** (list, mandatory)
 
  List of entries that should be kept in the LDAP directory. Each item is a
 
  dictionary describing a single LDAP entry, with all of its attributes
 
  listed. The keys in this dictionary should be the attribute names. The values
 
  should be either strings, for setting a single attribute value, or a list of
 
  strings if it is necessary to set multiple values for the same attribute.
 

	
 

	
 
Examples
 
~~~~~~~~
 

	
 
Here is an example configuration for setting-up LDAP server:
 

	
 
.. code-block:: yaml
 

	
 
  ---
 

	
 
  ldap_server_config:
 
    domain: "example.com"
 
    organization: "Example Corporation"
 
    log_level: 256
 
    tls_certificate: ~/tls/ldap.example.com_ldap.pem
 
    tls_key: ~/tls/ldap.example.com_ldap.key
 
    ssf: 128
 
  
 
  ldap_permissions:
 
    - filter: '(olcSuffix=dc=example,dc=com)'
 
      rules:
 
        - >
 
          to *
 
          by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage
 
          by * break
 
        - >
 
          to attrs=userPassword,shadowLastChange
 
          by self write
 
          by anonymous auth
 
          by dn="cn=admin,dc=example,dc=com" write
 
          by * none
 
        - >
 
          to dn.base=""
 
          by * read
 
        - >
 
          to *
 
          by self write
 
          by dn="cn=admin,dc=example,dc=com" write
 
          by users read
 
          by * none
 
  
 
  ldap_entries:
 
    - dn: ou=people,dc=example,dc=com
 
      objectClass: organizationalUnit
 
      ou: people
 
    - dn: ou=groups,dc=example,dc=com
 
      objectClass: organizationalUnit
 
      ou: groups
 
    - dn: uid=john,dc=example,dc=com
 
      objectClass:
 
        - inetOrgPerson
 
        - simpleSecurityObject
 
      userPassword: somepassword
 
      uid: john
 
      cn: John Doe
 
      sn: Doe
 

	
 

	
 
Prosody
 
-------
 

	
 
The ``prosody`` role can be used for setting-up Prosody, an XMPP server, on
 
destination machine.
 

	
 
The role implements the following:
 

	
 
* Sets-up the Prosody apt repository.
 
* Deploys XMPP TLS private key and certificate.
 
* Installs Prosody.
 
* Configures Prosody.
 
* Configures firewall to allow incoming connections to the XMPP server.
 

	
 
Prosody is configured as follows:
 

	
 
* Modules enabled: roster, saslauth, tls, dialback, posix, private, vcard,
 
  version, uptime, time, ping, pep, register, admin_adhoc, announce, legacyauth.
 
* Self-registration is not allowed.
 
* TLS is configured. Legacy TLS is available on port 5223.
 
* Client-to-server communication requires encryption (TLS).
 
* Authentication is done via LDAP. For setting the LDAP TLS truststore, see
 
  :ref:`LDAP Client <ldap_client>`.
 
* Internal storage is used.
 
* For each domain specified, a dedicated conference/multi-user chat (MUC)
 
  service is set-up, with FQDN set to ``conference.DOMAIN``.
 
* For each domain specified, a dedicated file proxy service will be set-up, with
 
  FQDN set to ``proxy.DOMAIN``.
 

	
 

	
 
Parameters
 
~~~~~~~~~~
 

	
 
**prosody_administrators** (list, mandatory)
 
  List of Prosody users that should be granted administrator privileges over
 
  Prosody. Each item is a string with value equal to XMPP user ID
 
  (i.e. ``john.doe@example.com``).
 

	
 
**prosody_tls_key** (string, mandatory)
 
  Path to file on Ansible host that contains the private key used for TLS for
 
  XMPP service. The file will be copied to directory ``/etc/ssl/private/``.
 

	
 
**prosody_tls_certificate** (string, mandatory)
 
  Path to file on Ansible host that contains the X.509 certificate used for TLS
 
  for SMTP service. The file will be copied to directory ``/etc/ssl/certs/``.
 

	
 
**prosody_domains** (list, mandatory)
 
  List of domains that are served by this Prosody instance. Each item is a
 
  string specifying a domain.
 

	
 
**prosody_ldap_server** (string, mandatory)
 
  Fully qualified domain name, hostname, or IP address of the LDAP server used
 
  for user authentication and listing.
 

	
 
**prosody_ldap_bind_dn** (string, mandatory)
 
  Distinguished name of LDAP user used for authenticating to the LDAP
 
  server. This user is used for looking-up the users available on the
 
  server. Users themselves authenticate via their own account.
 

	
 
**prosody_ldap_password** (string, mandatory)
 
  Password used for authenticating to the LDAP server.
 

	
 
**prosody_ldap_filter** (string, mandatory)
 
  LDAP filter used for obtaining a list of users available on the Prosody
 
  server. Two special strings can be used for specifying the user and domain,
 
  ``$user``, and ``$host`` within. These will be replaced with real values in
 
  the filter every time a user is looked-up.
 

	
 
**prosody_ldap_scope** (string, mandatory)
 
  Scope for performing the LDAP search for obtaining a list of users available
 
  on the Prosody server.
 

	
 
**prosody_ldap_tls** (boolean, mandatory)
 
  Specifies whether to use STARTTLS extension when connecting to the LDAP server
 
  or not.
 

	
 
**prosody_ldap_base** (string, mandatory)
 
  Base DN under which the lists of users available on the Prosody should be
 
  looked-up.
 

	
 

	
 
Examples
 
~~~~~~~~
 

	
 
Here is an example configuration for setting-up XMPP server using Prosody:
 

	
 
.. code-block:: yaml
 

	
 
  ---
 

	
 
  prosody_administrators:
 
    - john.doe@example.com
 
  # These are default key and certificate that generated during Prosody
 
  # installation.
 
  prosody_tls_key: /etc/prosody/certs/localhost.key
 
  prosody_tls_certificate: /etc/prosody/certs/localhost.crt
 
  prosody_domains:
 
    - example.com
 
  prosody_ldap_server: ldap.example.com
 
  prosody_ldap_bind_dn: cn=xmpp,ou=services,dc=example,dc=com
 
  prosody_ldap_password: xmpp
 
  # This would require that the memberof overlay is available on LDAP server
 
  # side.
 
  prosody_ldap_filter: '(&(memberOf=cn=xmpp,ou=groups,dc=example,dc=com)(mail=$user@$host))'
 
  prosody_ldap_scope: "onelevel"
 
  prosody_ldap_tls: "true"
 
  prosody_ldap_base: "ou=people,dc=example,dc=com"
 

	
 

	
 
Mail Server
 
-----------
 

	
 
The ``mail_server`` role can be used for setting-up a complete mail server
 
solution, which includes both SMTP and IMAP service, on destination machine.
 

	
 
Postfix is used SMTP, while Dovecot is used for IMAP.
 

	
 
The role implements the following:
 

	
 
* Installs rsync.
 
* Deploys IMAP/SMTP TLS private keys and certificates.
 
* Installs and configures Dovecot, Postfix, ClamAV, and ClamAV Milter.
 
* Purges Exim4 configuration (just in case).
 
* Installs SWAKS (utility for testing SMTP servers).
 
* Sets-up the necessary directories and files under Postfix chroot.
 
* Configures firewall to allow incoming connections to the mail server. This
 
  includes set-up of redirection from TCP port 26 to TCP port 25 (alternate SMTP
 
  to work around common network blocks).
 

	
 
Deployed services are configured as follows:
 

	
 
* Both Postfix and Dovecot look-up available domains, users, and aliases in
 
  LDAP.
 
* Incoming and outgoing mail is scanned with ClamAV (via ClamAV
 
  Milter). Infected mails are rejected.
 
* Mail is stored in directory ``/var/MAIL_USER/DOMAIN/USER``, using ``Maildir``
 
  format.
 
* TLS is required for user log-ins for both SMTP and IMAP.
 
* RBL's are used for combating spam (if any is specified in configuration, see
 
  below).
 

	
 
Both Postfix and Dovecot expect a specific directory structure in LDAP when
 
doing look-ups:
 

	
 
* Postfix will log-in to LDAP as user
 
  ``cn=postfix,ou=services,MAIL_LDAP_ROOT_DN``.
 
* Dovecot will log-in to LDAP as user
 
  ``cn=dovecot,ou=services,MAIL_LDAP_ROOT_DN``.
 
* Domain entries need to be available as
 
  ``dc=DOMAIN,ou=domains,ou=mail,ou=services,MAIL_LDAP_ROOT_DN``.
 
* Alias entries need to be available as
 
  ``cn=ALIAS,ou=aliases,ou=mail,ou=services,MAIL_LDAP_ROOT_DN``.
 
* User entries are read from sub-tree (first-level only)
 
  ``ou=people,MAIL_LDAP_ROOT_DN``. Query filter used for finding users is
 
  ``(&(mail=%s)(memberOf=cn=mail,ou=groups,MAIL_LDAP_ROOT_DN))``. This allows
 
  group-based granting of mail services to users.
 

	
 

	
 
Parameters
 
~~~~~~~~~~
 

	
 
**mail_ldap_url** (string, mandatory)
 
  LDAP URL that should be used for connecting to the LDAP server for doing
 
  domain/user look-ups.
 

	
 
**mail_ldap_tls_truststore** (string, mandatory)
 
  Path to TLS truststore used for verifying the LDAP certificate. Should be in
 
  PEM format.
 

	
 
**mail_ldap_root_dn** (string, mandatory)
 
  Root DN in LDAP under where the entries (domains, users, aliases) can be
 
  found.
 

	
 
**mail_ldap_postfix_password** (string, mandatory)
 
  Password for authenticating the Postfix LDAP user.
 

	
 
**mail_ldap_dovecot_password** (string, mandatory)
 
  Password for authenticating the Dovecot LDAP user.
 

	
 
**mail_user** (string, mandatory)
 
  Name of the user that owns all the mail files.
 

	
 
**mail_user_uid** (integer, mandatory)
 
  UID of the user that owns all the mail files.
 

	
 
**mail_user_gid** (integer, mandatory)
 
  GID of the user that owns all the mail files.
 

	
 
**imap_tls_certificate** (string, mandatory)
 
  Path to file on Ansible host that contains the X.509 certificate used for TLS
 
  for IMAP and ManageSieve services. The file will be copied to directory
 
  ``/etc/ssl/certs/``.
 

	
 
**imap_tls_key** (string, mandatory)
 
  Path to file on Ansible host that contains the private key used for TLS for
 
  IMAP and ManageSieve services. The file will be copied to directory
 
  ``/etc/ssl/private/``.
 

	
 
**smtp_tls_certificate** (string, mandatory)
 
  Path to file on Ansible host that contains the X.509 certificate used for TLS
 
  for SMTP service. The file will be copied to directory ``/etc/ssl/certs/``.
 

	
 
**smtp_tls_key** (string, mandatory)
 
  Path to file on Ansible host that contains the private key used for TLS for
 
  SMTP service. The file will be copied to directory ``/etc/ssl/private/``.
 

	
 
**imap_folder_separator** (string, mandatory)
 
  Character used for separating the IMAP folders when clients are requesting
 
  listing from the server. Usually either slash(``/``) or dot(``.``).
 

	
 
**smtp_rbl** (list, mandatory)
 
  List of RBLs to use for detecting servers which send out spam. Each item is a
 
  string resembling the RBL domain.
 

	
 
**mail_postmaster** (string, mandatory)
 
  Mail address to use for the postmaster account in Dovecot.
 

	
 
**smtp_allow_relay_from** (list, mandatory)
 
  List of networks from which mail relaying is allowed even without
 
  authentication. Each item in the list is a string defining a network. The
 
  format must be compatible with Postfix ``mynetworks`` setting (for example:
 
  ``192.168.1.0/24``, ``myhost.example.com`` etc).
 

	
 

	
 
Examples
 
~~~~~~~~
 

	
 
Here is an example configuration for setting-up XMPP server using Prosody:
 

	
 
.. code-block:: yaml
 

	
 
  ---
 

	
 
  mail_ldap_url: ldap://ldap.example.com/
 
  mail_ldap_tls_truststore: /etc/ssl/certs/truststore.pem
 
  mail_ldap_root_dn: dc=example,dc=com
 
  mail_ldap_postfix_password: postfix
 
  mail_ldap_dovecot_password: dovecot
 

	
 
  mail_user: vmail
 
  mail_user_uid: 5000
 
  mail_user_gid: 5000
 

	
 
  imap_tls_certificate: ~/tls/mail.example.com_imap.pem
 
  imap_tls_key: ~/tls/mail.example.com_imap.key
 
  smtp_tls_certificate: ~/tls/mail.example.com_smtp.pem
 
  smtp_tls_key: ~/tls/mail.example.com_smtp.key
 
  imap_folder_separator: /
 
  smtp_rbl:
 
    - bl.spamcop.net
 
    - zen.spamhaus.org
 
  mail_postmaster: postmaster@example.com
 

	
 
  smtp_allow_relay_from:
 
    - ldap.example.com
 
    - xmpp.example.com
 

	
 

	
 
Mail Forwarder
 
--------------
 

	
 
The ``mail_forwarder`` role can be used for setting-up a local SMTP server for
 
sending out mails and receiving mails for local users. The SMTP server is
 
provided by Postfix.
 

	
 
SMTP service on server set-up this way is not meant to be exposed to the
 
Internet directly, and should receive delivery failures from the relay server
 
instead.
 

	
 
The role implements the following:
 

	
 
* Installs and configures Postfix.
 
* Purges Exim4 configuration (just in case).
 
* Sets-up aliases for the local recipients.
 
* Installs SWAKS (utility for testing SMTP servers).
 

	
 
Postfix is configured as follows:
 

	
 
* Local destinations are set-up.
 
* A relay host is set.
 
* TLS is enforced for relaying mails, with configurable truststore for server
 
  certificate verification.
 

	
 

	
 
Parameters
 
~~~~~~~~~~
 

	
 
**local_mail_aliases** (dictionary, mandatory)
 
  Dictionary defining the local aliases. Aliases defined this way will either be
 
  appended to default aliases on the server, or replace the existing entries (if
 
  the alias/recipient is already present). Keys in the dictionary are the local
 
  recipients/aliases, while the value provided should be a space-separated list
 
  of mail addresses (or local users) where the mails should be forwarded.
 

	
 
**smtp_relay_host** (string, mandatory)
 
  SMTP server via which the mails are sent out for non-local recipients.
 

	
 
**smtp_relay_truststore** (string, mandatory)
 
  Path to the file containing full X.509 CA certificate chain used for
 
  validating the server certificate presented by the relay server.
 

	
 

	
 
Examples
 
~~~~~~~~
 

	
 
Here is an example configuration for setting-up the mail forwarder:
 

	
 
.. code-block:: yaml
 

	
 
  ---
 

	
 
  # All mails sent to local user root will be forwarded to external account as
 
  # well.
 
  local_mail_aliases:
 
    root: "root john.doe@example.com"
 

	
 
  smtp_relay_host: mail.example.com
 

	
 
  smtp_relay_truststore: /etc/ssl/certs/example_ca_chain.pem
 

	
 

	
 
Web Server
 
----------
 

	
 
The ``web_server`` role can be used for setting-up a web server on destination
 
machine.
 

	
 
The role is supposed very lightweight, providing a basis for deployment of web
 
applications.
 

	
 
The role implements the following:
 

	
 
* Installs and configures nginx with a single, default vhost with a small static
 
  index page.
 
* Deploys the HTTPS TLS private key and certificate (for default vhost).
 
* Configures firewall to allow incoming connections to the web server.
 
* Installs and configures supervisor, virtualenv, and virtualenvwrapper as a
 
  common base for Python apps.
 
* Installs and configures PHP FPM as a common base for PHP apps.
 

	
 

	
 
Parameters
 
~~~~~~~~~~
 

	
 
**https_tls_key** (string, mandatory)
 
  Path to file on Ansible host that contains the private key used for TLS for
 
  HTTPS service. The file will be copied to directory ``/etc/ssl/private/``.
 

	
 
**https_tls_certificate** (string, mandatory)
 
  Path to file on Ansible host that contains the X.509 certificate used for TLS
 
  for HTTPS service. The file will be copied to directory ``/etc/ssl/certs/``.
 

	
 
**web_default_title** (string, mandatory)
 
  Title for the default web page shown to users (if no other vhosts were matched).
 

	
 
**web_default_message** (string, mandatory)
 
  Message for the default web page shown to users (if no other vhosts were
 
  matched).
 

	
 

	
 
Examples
 
~~~~~~~~
 

	
 
Here is an example configuration for setting-up XMPP server using Prosody:
 

	
 
.. code-block:: yaml
 

	
 
  ---
 

	
 
  https_tls_key: "{{ inventory_dir }}/tls/web.example.com_https.key"
 
  https_tls_certificate: "{{ inventory_dir }}/tls/web.example.com_https.pem"
 

	
 
  web_default_title: "Welcome to Example Inc."
 
  web_default_message: "You are attempting to access the web server using a wrong name or an IP address. Please check your URL."
roles/web_server/handlers/main.yml
Show inline comments
 
---
 

	
 
- name: Restart nginx
 
  service: name=nginx state=restarted
 

	
 
- name: Restart php5-fpm
 
  service: name=php5-fpm state=restarted
 
\ No newline at end of file
roles/web_server/tasks/main.yml
Show inline comments
 
---
 

	
 
- name: Install nginx
 
  apt: name=nginx state=installed
 

	
 
- name: Allow nginx user to traverse the directory with TLS private keys
 
  user: name=www-data append=yes groups=ssl-cert
 
  notify:
 
    - Restart nginx
 

	
 
- name: Deploy nginx TLS private key
 
  copy: dest="/etc/ssl/private/{{ https_tls_key | basename }}" src="{{ https_tls_key }}"
 
        mode=640 owner=root group=root
 
  notify:
 
    - Restart nginx
 

	
 
- name: Deploy nginx TLS certificate
 
  copy: dest="/etc/ssl/certs/{{ https_tls_certificate | basename }}" src="{{ https_tls_certificate }}"
 
        mode=644 owner=root group=root
 
  notify:
 
    - Restart nginx
 

	
 
- name: Deploy default vhost configuration
 
  template: src="nginx-default.j2" dest="/etc/nginx/sites-available/default"
 
             owner=root group=root mode=644
 
  notify:
 
    - Restart nginx
 

	
 
- name: Deploy firewall configuration for web server
 
  copy: src="ferm_http.conf" dest="/etc/ferm/conf.d/30-web.conf" owner=root group=root mode=640
 
  notify:
 
    - Restart ferm
 

	
 
- name: Remove the default Debian html files
 
  file: path="{{ item }}" state=absent
 
  with_items:
 
    - /var/www/html/index.nginx-debian.html
 
    - /var/www/html/
 

	
 
- name: Create directory for storing the default website page
 
  file: path="/var/www/default/" state=directory
 
        owner=root group=www-data mode=750
 

	
 
- name: Deploy the default index.html
 
  template: src="index.html.j2" dest=/var/www/default/index.html
 
            owner=root group=www-data mode=640
 

	
 
- name: Enable nginx service
 
  service: name=nginx enabled=yes state=started
 

	
 
- name: Install base packages for Python web applications
 
  apt: name="{{ item }}" state=installed
 
  with_items:
 
    - supervisor
 
    - virtualenv
 
    - virtualenvwrapper
 

	
 
- name: Install base packages for PHP web applications
 
  apt: name="{{ item }}" state=installed
 
  with_items:
 
    - php5-fpm
 

	
 
- name: Enable services used for running web applications
 
  service: name="{{ item }}" enabled=yes state=started
 
  with_items:
 
    - php5-fpm
 
    - supervisor
 

	
 
- name: Read timezone on server
 
  slurp: src=/etc/timezone
 
  register: server_timezone
 

	
 
- name: Configure timezone for PHP
 
  template: src="php_timezone.ini.j2" dest="{{ item }}/30-timezone.ini"
 
            owner=root group=root mode=644
 
  with_items:
 
    - /etc/php5/cli/conf.d/
 
    - /etc/php5/fpm/conf.d/
 
  notify:
 
    - Restart php5-fpm
 
\ No newline at end of file
roles/web_server/templates/php_timezone.ini.j2
Show inline comments
 
new file 100644
 
date.timezone = '{{ server_timezone.content | b64decode | trim }}'
testsite/group_vars/all.yml
Show inline comments
 
---
 
# Configuration for roles bootstrap and preseed.
 
ansible_key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
 

	
 
# Configuration for role 'common', shared across all servers.
 
os_users:
 
  - name: admin
 
    uid: 1000
 
    additional_groups: sudo
 
    authorized_keys:
 
      - "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
 
    password: '$6$/aerscJY6aevRG$ABBCymEDtk2mHW/dklre9dMEdgZNJvVHsGLCzgjGmy61FssZ.KW7ePcO2wsMGIkHcg3mZlrA4dhYh.APq9OQu0'
 
  - name: johndoe
 
    uid: 1001
 
    additional_groups: "office,developer"
 
    authorized_keys: []
 
    password: '$6$cJnUatae7cMz23fl$O3HE2TslnEaKaTDSZnvuDDrfqILAiuMV1wOPGVnkUQFxUu3gIWZOyO7AI1OWYkqeQMVBiezpSqYNiQy6NF6bi0'
 

	
 
os_groups:
 
  - name: office
 
    gid: 2000
 
  - name: developer
 
    gid: 2001
 

	
 
common_packages:
 
  - emacs24-nox
 
  - screen
 
  - debconf-utils
 
  - colordiff
 

	
 
ca_certificates:
 
  - "{{ inventory_dir }}/tls/example_ca_chain.pem"
 

	
 
incoming_connection_limit: 2/second
 

	
 
incoming_connection_limit_burst: 6
 
\ No newline at end of file
0 comments (0 inline, 0 general)