Changeset - babda105c9cf
[Not reviewed]
0 2 1
Branko Majic (branko) - 9 years ago 2015-08-16 22:38:56
branko@majic.rs
MAR-16: Added option to common role for setting-up caching proxy for apt.
3 files changed with 15 insertions and 0 deletions:
0 comments (0 inline, 0 general)
docs/rolereference.rst
Show inline comments
 
@@ -8,407 +8,412 @@ 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:
 

	
 
* Configures apt to use caching proxy (if any was specified).
 
* 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
 
~~~~~~~~~~
 

	
 
**apt_proxy** (string, optional)
 
  URI of a caching proxy that should be used when retrieving the packages via
 
  apt. Default is no proxy.
 

	
 
**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``.
roles/common/tasks/main.yml
Show inline comments
 
---
 

	
 
- name: Enable use of proxy for retrieving system packages via apt
 
  template: src="apt_proxy.j2" dest="/etc/apt/apt.conf.d/00proxy"
 
            owner=root group=root mode=644
 
  when: apt_proxy is defined
 

	
 
- name: Disable use of proxy for retrieving system packages via apt
 
  file: path="/etc/apt/apt.conf.d/00proxy" state=absent
 
  when: apt_proxy is undefined
 

	
 
- name: Deploy pam-auth-update configuration file for enabling pam_umask
 
  copy: src=pam_umask dest=/usr/share/pam-configs/umask mode=644 owner=root group=root
 
  notify: Update PAM configuration
 

	
 
- name: Set login UMASK
 
  lineinfile: dest=/etc/login.defs state=present backrefs=yes regexp='^UMASK(\s+)' line='UMASK\g<1>027'
 

	
 
- name: Set home directory mask
 
  lineinfile: dest=/etc/adduser.conf state=present backrefs=yes regexp='^DIR_MODE=' line='DIR_MODE=0750'
 

	
 
- name: Install sudo
 
  apt: name=sudo state=present
 

	
 
- name: Install ssl-cert package
 
  apt: name=ssl-cert state=present
 

	
 
- name: Install common packages
 
  apt: name="{{ item }}" state="present"
 
  with_items: common_packages
 

	
 
- name: Set-up operating system groups
 
  group: name="{{ item.name }}" gid="{{ item.gid }}" state=present
 
  with_items: os_groups
 

	
 
- name: Set-up operating system user groups
 
  group: name="{{ item.name }}" gid="{{ item.uid }}" state=present
 
  with_items: os_users
 

	
 
- name: Set-up operating system users
 
  user: name="{{ item.name }}" uid="{{ item.uid }}" group="{{ item.name }}"
 
        groups="{{ item.additional_groups }}" append=yes shell=/bin/bash state=present
 
        password="{{ item.password }}"
 
  with_items: os_users
 

	
 
- name: Set-up authorised keys
 
  authorized_key: user="{{ item.0.name }}" key="{{ item.1 }}"
 
  with_subelements:
 
    - os_users
 
    - authorized_keys
 

	
 
- name: Disable remote logins for root
 
  lineinfile: dest="/etc/ssh/sshd_config" state=present regexp="^PermitRootLogin" line="PermitRootLogin no"
 
  notify:
 
    - Restart SSH
 

	
 
- name: Disable remote login authentication via password
 
  lineinfile: dest="/etc/ssh/sshd_config" state=present regexp="^PasswordAuthentication" line="PasswordAuthentication no"
 
  notify:
 
    - Restart SSH
 

	
 
- name: Deploy CA certificates
 
  copy: src="{{ item }}" dest="/etc/ssl/certs/{{ item | basename }}" mode=644 owner=root group=root
 
  with_items: ca_certificates
 
  notify:
 
    - Update CA certificate cache
 

	
 
- name: Install ferm (for firewall management)
 
  apt: name=ferm state=installed
 

	
 
- name: Configure ferm init script coniguration file
 
  copy: src=ferm dest=/etc/default/ferm owner=root group=root mode=644
 
  notify:
 
    - Restart ferm
 

	
 
- name: Create directory for storing ferm configuration files
 
  file: dest="/etc/ferm/conf.d/" mode=750 state=directory owner=root group=root
 

	
 
- name: Deploy main ferm configuration file
 
  copy: src=ferm.conf dest=/etc/ferm/ferm.conf
 
  notify:
 
    - Restart ferm
 

	
 
- name: Deploy ferm base rules
 
  template: src=00-base.conf.j2 dest=/etc/ferm/conf.d/00-base.conf
 
            owner=root group=root mode=640
 
  notify:
 
    - Restart ferm
 

	
 
- name: Enable ferm service
 
  service: name=ferm enabled=yes state=started
roles/common/templates/apt_proxy.j2
Show inline comments
 
new file 100644
 
Acquire::http::Proxy "{{ apt_proxy }}";
0 comments (0 inline, 0 general)