421 Role vbotka.freebsd.apache Virtual Host

Use case

Use iocage property host_hostname to create a jail. Use the role vbotka.freebsd.certificate to create SSL certificate. Use the role vbotka.freebsd.apache to configure Apache HTTP Server Virtual Host www.foo.bar.

Tree

shell> tree .
.
├── ansible.cfg
├── hosts
├── host_vars
│   ├── iocage_04
│   │   └── ansible-client-apache.yml
│   └── www-3
│       ├── apache.yml
│       └── certificate.yml
├── iocage.ini
├── pb-apache.yml
└── pb-certificate.yml

Synopsis

Requirements

Notes

  • iocage property host_hostname provides “The hostname of the jail.”. Please note that iocage option --name provides “NAME instead of a UUID for the new jail”.

  • In case of DHCP, host_hostname resolves, however --name does not.

ansible.cfg

[defaults]
gathering = explicit
callback_result_format = yaml
display_skipped_hosts = false

[connection]
pipelining = true

Inventory iocage.ini

iocage_04 ansible_host=10.1.0.29

[iocage]
iocage_04

[iocage:vars]
ansible_user=admin
ansible_become=true
ansible_python_interpreter=auto_silent

host_vars

host_vars/iocage_04/ansible-client-apache.yml
properties:
  notes: "vmm={{ inventory_hostname }}"
  bpf: 1
  dhcp: 1
  vnet: 1

clones_host_hostname:
  www-3:
    template: ansible_client_apache
host_vars/www-3/apache.yml
apache_install: false
apache_confd: false
apache_servername: www-3
apache_serveradmin: admin@www-3

apache_ssl: true
apache_sslengine: 'on'
apache_sslcertificatekeyfile: "/usr/local/etc/ssl/private/{{ apache_servername }}.key"
apache_sslcertificatefile: "/usr/local/etc/ssl/certs/{{ apache_servername }}.crt"

apache_httpd_conf_modules:
  - {module: socache_shmcb_module, mod: mod_socache_shmcb.so}
  - {module: ssl_module, mod: mod_ssl.so}

apache_vhosts: true
apache_vhost:
  - ServerName: www.foo.bar
    DocumentRoot: /usr/local/www/apache24/data-foo-bar/
    SSLCertificateFile: "/usr/local/etc/ssl/certs/www.foo.bar.crt"
    SSLCertificateKeyFile: "/usr/local/etc/ssl/private/www.foo.bar.key"
    redirect: false

apache_directory_blocks:
  - Directory: /usr/local/www/apache24/data/
    Includefile: usr-local-www-apache-data.conf
    Conf:
      - "DirectoryIndex index.html index.htm"
      - "Options Indexes FollowSymLinks"
      - "AllowOverride All"
      - "Require all granted"
  - Directory: /usr/local/www/apache24/data-foo-bar/
    Includefile: usr-local-www-apache-data-foo-bar.conf
    Conf:
      - "DirectoryIndex index.html index.htm"
      - "Options Indexes FollowSymLinks"
      - "AllowOverride All"
      - "Require all granted"
host_vars/www-3/certificate.yml
certificate_data_simple:
  - www-3
  - www.foo.bar

Create and start the jail

(env) > ansible-playbook vbotka.freebsd.pb_iocage_ansible_clients.yml \
                         -i iocage.ini \
                         -t clone_host_hostname -e clone_host_hostname=true
PLAY [Create and start jails. Optionally stop and destroy jails.] **************

TASK [Create clones host_hostname] *********************************************
changed: [iocage_04] => (item=www-3 ansible_client_apache)

TASK [Start clones host_hostname] **********************************************
changed: [iocage_04]

PLAY RECAP *********************************************************************
iocage_04                  : ok=2    changed=2    unreachable=0    failed=0    skipped=4    rescued=0    ignored=0   

Inventory hosts

hosts
www-3

[www]
www-3

[www:vars]
ansible_user=admin
ansible_become=true
ansible_python_interpreter=auto_silent

Playbook pb-certificate.yml

- name: Create SSL certificate.
  hosts: www
  gather_facts: true

  roles:
    - vbotka.freebsd.certificate

Playbook output - Display variables

(env) > ansible-playbook pb-certificate.yml -i hosts \
                         -t certificate_debug -e certificate_debug=true
PLAY [Create SSL certificate.] *************************************************

TASK [Gathering Facts] *********************************************************
ok: [www-3]

TASK [Vars: Include OS vars] ***************************************************
included: vbotka.freebsd.lib for www-3

TASK [vbotka.freebsd.lib : Al_include_os_vars_path_incr: vars from /scratch/collections/ansible_collections/vbotka/freebsd/roles/certificate/vars/defaults] ***
ok: [www-3] => (item=/scratch/collections/ansible_collections/vbotka/freebsd/roles/certificate/vars/defaults/default.yml)
ok: [www-3] => (item=/scratch/collections/ansible_collections/vbotka/freebsd/roles/certificate/vars/defaults/FreeBSD.yml)

TASK [vbotka.freebsd.lib : Al_include_os_vars_path_incr: vars from /scratch/collections/ansible_collections/vbotka/freebsd/roles/certificate/vars] ***
ok: [www-3] => (item=/scratch/collections/ansible_collections/vbotka/freebsd/roles/certificate/vars/defaults.yml)

TASK [vbotka.freebsd.certificate : Vars: Add certificate_data_simple to certificate_data] ***
ok: [www-3]

TASK [vbotka.freebsd.certificate : Debug certificate_debug=true] ***************
ok: [www-3] => 
    msg: |-
        certificate_role_version: 2.7.0
        ansible_role_name: vbotka.freebsd.certificate
        ansible_architecture: amd64
        ansible_os_family: FreeBSD
        ansible_distribution: FreeBSD
        ansible_distribution_major_version: 14
        ansible_distribution_version: 14.3
        ansible_distribution_release: 14.3-RELEASE
        ansible_python_version: 3.11.13

        certificate_sanity: True
        certificate_sanity_platform: True
        certificate_sanity_ansible_version: True
        certificate_sanity_packages: True

        certificate_debug_classified: False
        certificate_backup_conf: False

        certificate_default_backend: auto
        certificate_default_size: 4096
        certificate_default_type: RSA
        certificate_default_provider: selfsigned

        certificate_owner: root
        certificate_group: wheel
        certificate_dir_mode: 0755
        certificate_file_mode: 0644
        certificate_dir: /usr/local/etc/ssl
        certificate_dir_csr: /usr/local/etc/ssl/csr
        certificate_dir_certs: /usr/local/etc/ssl/certs

        certificate_private_owner: root
        certificate_private_group: wheel
        certificate_private_dir_mode: 0700
        certificate_private_file_mode: 0600
        certificate_private_dir: /usr/local/etc/ssl/private

        certificate_acme_owner: root
        certificate_acme_group: wheel
        certificate_acme_dir_mode_private: 0700
        certificate_acme_dir_mode_public: 0755
        certificate_acme_base_dir: /usr/local
        certificate_acme_dir: /usr/local/etc/letsencrypt
        certificate_acme_dir_csr: /usr/local/etc/letsencrypt/csr
        certificate_acme_dir_certs: /usr/local/etc/letsencrypt/archive
        certificate_acme_dir_private: /usr/local/etc/letsencrypt/keys
        certificate_acme_dir_challenges: /usr/local/www/apache24/data/.well-known/acme-challenge/
        certificate_acme_link_crt: False
        certificate_link_crt: False

        certificate_self_signed_command:
          []

        certificate_data:
          - passphrase: ************
            CN: www-3
            private: www-3.key
            csr: www-3.csr
            crt: www-3.crt
          - passphrase: ************
            CN: www.foo.bar
            private: www.foo.bar.key
            csr: www.foo.bar.csr
            crt: www.foo.bar.crt

        certificate_python_version: 311
        al_debug: False
        al_sanity_packages_required:
          FreeBSD:
            default: [py311-cryptography, py311-openssl, py311-acme, acme-tiny]
          Ubuntu:
            bionic: [python-openssl, python-cryptography, acme-tiny]
            cosmic: [python-openssl, python-cryptography, acme-tiny]
            default: [python3-openssl, python3-cryptography, acme-tiny]
            disco: [python-openssl, python-cryptography, acme-tiny]
            eoan: [python-openssl, python-cryptography, acme-tiny]
            focal:
            - [python-openssl, python3-openssl]
            - [python-cryptography, python3-cryptography]
            - acme-tiny

        freebsd_install_method: packages
        freebsd_use_packages: True
        freebsd_install_state: present
        freebsd_install_retries: 10
        freebsd_install_delay: 5
        freebsd_flavors_enable: False
        freebsd_flavors: [py311]

        certificate_supported_linux_family: ['RedHat', 'Debian']
        certificate_install: True
        certificate_packages:
          - security/py-cryptography
          - security/py-openssl
          - security/py-acme

        certificate_packages2:
          - security/py-acme-tiny

PLAY RECAP *********************************************************************
www-3                      : ok=6    changed=0    unreachable=0    failed=0    skipped=6    rescued=0    ignored=0   

Playbook output - Setup

(env) > ansible-playbook pb-certificate.yml -i hosts -t certificate_setup
PLAY [Create SSL certificate.] *************************************************

TASK [Gathering Facts] *********************************************************
ok: [www-3]

TASK [Vars: Include OS vars] ***************************************************
included: vbotka.freebsd.lib for www-3

TASK [vbotka.freebsd.lib : Al_include_os_vars_path_incr: vars from /scratch/collections/ansible_collections/vbotka/freebsd/roles/certificate/vars/defaults] ***
ok: [www-3] => (item=/scratch/collections/ansible_collections/vbotka/freebsd/roles/certificate/vars/defaults/default.yml)
ok: [www-3] => (item=/scratch/collections/ansible_collections/vbotka/freebsd/roles/certificate/vars/defaults/FreeBSD.yml)

TASK [vbotka.freebsd.lib : Al_include_os_vars_path_incr: vars from /scratch/collections/ansible_collections/vbotka/freebsd/roles/certificate/vars] ***
ok: [www-3] => (item=/scratch/collections/ansible_collections/vbotka/freebsd/roles/certificate/vars/defaults.yml)

TASK [vbotka.freebsd.certificate : Vars: Add certificate_data_simple to certificate_data] ***
ok: [www-3]

TASK [vbotka.freebsd.certificate : Packages: Install FreeBSD packages] *********
ok: [www-3] => (item=security/py-cryptography)
ok: [www-3] => (item=security/py-openssl)
ok: [www-3] => (item=security/py-acme)
ok: [www-3] => (item=security/py-acme-tiny)

TASK [vbotka.freebsd.certificate : Cert-dirs: Create public directories /usr/local/etc/ssl] ***
ok: [www-3] => (item=/usr/local/etc/ssl)
ok: [www-3] => (item=/usr/local/etc/ssl/certs)
ok: [www-3] => (item=/usr/local/etc/ssl/csr)

TASK [vbotka.freebsd.certificate : Cert-dirs: Create /usr/local/etc/ssl/private] ***
ok: [www-3]

TASK [vbotka.freebsd.certificate : Sanity: Get meta-data.] *********************
ok: [www-3]

TASK [vbotka.freebsd.certificate : Sanity: Get role_name.] *********************
ok: [www-3]

TASK [Sanity: Include al_sanity_platform from lib] *****************************
included: vbotka.freebsd.lib for www-3

TASK [vbotka.freebsd.lib : Al_sanity_platform: Setup. Collect minimal subset.] ***
ok: [www-3]

TASK [vbotka.freebsd.lib : Al_sanity_platform: Get supported platforms.] *******
ok: [www-3]

TASK [vbotka.freebsd.lib : Al_sanity_platform: Get supported versions of FreeBSD.] ***
ok: [www-3]

TASK [vbotka.freebsd.lib : Al_sanity_platform: Set test variables.] ************
included: /scratch/collections/ansible_collections/vbotka/freebsd/roles/lib/tasks/fn/al_include_sanity_platform_test_vars.yml for www-3

TASK [vbotka.freebsd.lib : Al_include_sanity_platform_test_vars: Set al_sanity_platform_test] ***
ok: [www-3]

TASK [vbotka.freebsd.lib : Al_include_sanity_platform_test_vars: Set al_sanity_platform_version_test] ***
ok: [www-3]

TASK [vbotka.freebsd.lib : Al_include_sanity_platform_test_vars: Set al_sanity_platform_version_test] ***
ok: [www-3]

TASK [Sanity: Include al_sanity_ansible_version from lib] **********************
included: vbotka.freebsd.lib for www-3

TASK [vbotka.freebsd.lib : Al_sanity_ansible_version: Get Ansible minimal version.] ***
ok: [www-3]

TASK [Sanity: Include al_sanity_packages from lib] *****************************
included: vbotka.freebsd.lib for www-3

TASK [vbotka.freebsd.lib : Al_sanity_packages: Setup. Gather minimal subset.] ***
ok: [www-3]

TASK [vbotka.freebsd.lib : Al_sanity_packages: Collect installed packages.] ****
ok: [www-3]

TASK [vbotka.freebsd.lib : Al_sanity_packages: Set list of installed packages.] ***
ok: [www-3]

PLAY RECAP *********************************************************************
www-3                      : ok=24   changed=0    unreachable=0    failed=0    skipped=37   rescued=0    ignored=0   

Playbook output - Create certificate

(env) > ansible-playbook pb-certificate.yml -i hosts -t certificate_openssl
PLAY [Create SSL certificate.] *************************************************

TASK [Gathering Facts] *********************************************************
ok: [www-3]

TASK [Vars: Include OS vars] ***************************************************
included: vbotka.freebsd.lib for www-3

TASK [vbotka.freebsd.lib : Al_include_os_vars_path_incr: vars from /scratch/collections/ansible_collections/vbotka/freebsd/roles/certificate/vars/defaults] ***
ok: [www-3] => (item=/scratch/collections/ansible_collections/vbotka/freebsd/roles/certificate/vars/defaults/default.yml)
ok: [www-3] => (item=/scratch/collections/ansible_collections/vbotka/freebsd/roles/certificate/vars/defaults/FreeBSD.yml)

TASK [vbotka.freebsd.lib : Al_include_os_vars_path_incr: vars from /scratch/collections/ansible_collections/vbotka/freebsd/roles/certificate/vars] ***
ok: [www-3] => (item=/scratch/collections/ansible_collections/vbotka/freebsd/roles/certificate/vars/defaults.yml)

TASK [vbotka.freebsd.certificate : Vars: Add certificate_data_simple to certificate_data] ***
ok: [www-3]

TASK [vbotka.freebsd.certificate : Cert-openssl-privatekey: Generate OpenSSL private keys.] ***
changed: [www-3] => (item=file:/usr/local/etc/ssl/private/www-3.key CN:www-3)
changed: [www-3] => (item=file:/usr/local/etc/ssl/private/www.foo.bar.key CN:www.foo.bar)

TASK [vbotka.freebsd.certificate : Cert-openssl-csr: Generate OpenSSL Certificate Signing Request.] ***
changed: [www-3] => (item= file:/usr/local/etc/ssl/csr/www-3.csr CN:www-3)
changed: [www-3] => (item= file:/usr/local/etc/ssl/csr/www.foo.bar.csr CN:www.foo.bar)

TASK [vbotka.freebsd.certificate : Cert-openssl-certificate: Generate and/or check OpenSSL certificates.] ***
changed: [www-3] => (item= file:/usr/local/etc/ssl/certs/www-3.crt CN:www-3)
changed: [www-3] => (item= file:/usr/local/etc/ssl/certs/www.foo.bar.crt CN:www.foo.bar)

PLAY RECAP *********************************************************************
www-3                      : ok=8    changed=3    unreachable=0    failed=0    skipped=9    rescued=0    ignored=0   

Playbook output - Display status

(env) > ansible-playbook pb-certificate.yml -i hosts -t certificate_openssl_stat
PLAY [Create SSL certificate.] *************************************************

TASK [Gathering Facts] *********************************************************
ok: [www-3]

TASK [Vars: Include OS vars] ***************************************************
included: vbotka.freebsd.lib for www-3

TASK [vbotka.freebsd.lib : Al_include_os_vars_path_incr: vars from /scratch/collections/ansible_collections/vbotka/freebsd/roles/certificate/vars/defaults] ***
ok: [www-3] => (item=/scratch/collections/ansible_collections/vbotka/freebsd/roles/certificate/vars/defaults/default.yml)
ok: [www-3] => (item=/scratch/collections/ansible_collections/vbotka/freebsd/roles/certificate/vars/defaults/FreeBSD.yml)

TASK [vbotka.freebsd.lib : Al_include_os_vars_path_incr: vars from /scratch/collections/ansible_collections/vbotka/freebsd/roles/certificate/vars] ***
ok: [www-3] => (item=/scratch/collections/ansible_collections/vbotka/freebsd/roles/certificate/vars/defaults.yml)

TASK [vbotka.freebsd.certificate : Vars: Add certificate_data_simple to certificate_data] ***
ok: [www-3]

TASK [vbotka.freebsd.certificate : Cert-openssl-stat: Get status of OpenSSL private keys, CSRs, and certificates.] ***
included: /scratch/collections/ansible_collections/vbotka/freebsd/roles/certificate/tasks/fn/cert-openssl-stat-item.yml for www-3 => (item=CN:www-3)
included: /scratch/collections/ansible_collections/vbotka/freebsd/roles/certificate/tasks/fn/cert-openssl-stat-item.yml for www-3 => (item=CN:www.foo.bar)

TASK [vbotka.freebsd.certificate : Cert-openssl-stat-item: Get status of OpenSSL private key, CSR, and certificate.] ***
ok: [www-3] => (item=/usr/local/etc/ssl/private/www-3.key)
ok: [www-3] => (item=/usr/local/etc/ssl/csr/www-3.csr)
ok: [www-3] => (item=/usr/local/etc/ssl/certs/www-3.crt)

TASK [vbotka.freebsd.certificate : Cert-openssl-stat-item: Display status of OpenSSL private key, CSR, and certificate.] ***
ok: [www-3] => 
    msg: |-
        - {exists: true, file: /usr/local/etc/ssl/private/www-3.key}
        - {exists: true, file: /usr/local/etc/ssl/csr/www-3.csr}
        - {exists: true, file: /usr/local/etc/ssl/certs/www-3.crt}

TASK [vbotka.freebsd.certificate : Cert-openssl-stat-item: Get status of OpenSSL private key, CSR, and certificate.] ***
ok: [www-3] => (item=/usr/local/etc/ssl/private/www.foo.bar.key)
ok: [www-3] => (item=/usr/local/etc/ssl/csr/www.foo.bar.csr)
ok: [www-3] => (item=/usr/local/etc/ssl/certs/www.foo.bar.crt)

TASK [vbotka.freebsd.certificate : Cert-openssl-stat-item: Display status of OpenSSL private key, CSR, and certificate.] ***
ok: [www-3] => 
    msg: |-
        - {exists: true, file: /usr/local/etc/ssl/private/www.foo.bar.key}
        - {exists: true, file: /usr/local/etc/ssl/csr/www.foo.bar.csr}
        - {exists: true, file: /usr/local/etc/ssl/certs/www.foo.bar.crt}

PLAY RECAP *********************************************************************
www-3                      : ok=11   changed=0    unreachable=0    failed=0    skipped=6    rescued=0    ignored=0   

Playbook pb-apache.yml

- name: Create Apache HTTP Server.
  hosts: www
  gather_facts: true

  roles:
    - vbotka.freebsd.apache

Playbook output - Create server

(env) > ansible-playbook pb-apache.yml -i hosts
PLAY [Create Apache HTTP Server.] **********************************************

TASK [Gathering Facts] *********************************************************
ok: [www-3]

TASK [Vars: Include OS vars.] **************************************************
included: vbotka.freebsd.lib for www-3

TASK [vbotka.freebsd.lib : Al_include_os_vars_path: Vars from /scratch/collections/ansible_collections/vbotka/freebsd/roles/apache/vars/defaults] ***
ok: [www-3]

TASK [vbotka.freebsd.apache : Httpd-conf: Configure parameters in /usr/local/etc/apache24/httpd.conf] ***
changed: [www-3] => (item={'regexp': 'ServerName', 'line': 'www-3'})
changed: [www-3] => (item={'regexp': 'ServerAdmin', 'line': 'admin@www-3'})
changed: [www-3] => (item={'regexp': 'ServerTokens', 'line': 'Prod'})

TASK [vbotka.freebsd.apache : Httpd-dirs: Configure directories in /usr/local/etc/apache24/Includes/] ***
changed: [www-3] => (item=/usr/local/www/apache24/data/)
changed: [www-3] => (item=/usr/local/www/apache24/data-foo-bar/)

TASK [vbotka.freebsd.apache : Httpd-modules: Load modules in /usr/local/etc/apache24/httpd.conf] ***
changed: [www-3] => (item={'module': 'socache_shmcb_module', 'mod': 'mod_socache_shmcb.so'})
changed: [www-3] => (item={'module': 'ssl_module', 'mod': 'mod_ssl.so'})

TASK [vbotka.freebsd.apache : Httpd-ssl: Present extra lines in /usr/local/etc/apache24/extra/httpd-ssl.conf] ***
changed: [www-3] => (item={'regexp': 'ServerName ', 'line': 'www-3:443'})
changed: [www-3] => (item={'regexp': 'ServerAdmin ', 'line': 'admin@www-3'})
ok: [www-3] => (item={'regexp': 'SSLEngine ', 'line': 'on'})
changed: [www-3] => (item={'regexp': 'SSLProtocol ', 'line': 'all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1'})
changed: [www-3] => (item={'regexp': 'SSLCipherSuite ', 'line': 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256'})
changed: [www-3] => (item={'regexp': 'SSLHonorCipherOrder ', 'line': 'on'})
changed: [www-3] => (item={'regexp': 'SSLCompression ', 'line': 'off'})
changed: [www-3] => (item={'regexp': 'SSLSessionTickets ', 'line': 'off'})
changed: [www-3] => (item={'regexp': 'SSLCertificateFile ', 'line': '/usr/local/etc/ssl/certs/www-3.crt'})
changed: [www-3] => (item={'regexp': 'SSLCertificateKeyFile ', 'line': '/usr/local/etc/ssl/private/www-3.key'})

TASK [vbotka.freebsd.apache : Httpd-ssl: SSL Listen in /usr/local/etc/apache24/extra/httpd-ssl.conf] ***
ok: [www-3] => (item=Listen 443)

TASK [vbotka.freebsd.apache : Httpd-ssl: SSL in /usr/local/etc/apache24/httpd.conf] ***
changed: [www-3] => (item=Include etc/apache24/extra/httpd-ssl.conf)

TASK [vbotka.freebsd.apache : Httpd-vhosts: Configure virtual hosts in /usr/local/etc/apache24/extra/] ***
changed: [www-3] => (item=www.foo.bar)

TASK [vbotka.freebsd.apache : Httpd-vhosts: Incl virtual hosts in /usr/local/etc/apache24/httpd.conf] ***
changed: [www-3] => (item=www.foo.bar)

TASK [vbotka.freebsd.apache : Rc-conf: Enable and Start Apache] ****************
changed: [www-3]

RUNNING HANDLER [vbotka.freebsd.apache : Enable and start apache] **************
changed: [www-3]

RUNNING HANDLER [vbotka.freebsd.apache : Restart apache] ***********************
changed: [www-3]

RUNNING HANDLER [vbotka.freebsd.apache : Reload apache] ************************
ok: [www-3]

PLAY RECAP *********************************************************************
www-3                      : ok=15   changed=10   unreachable=0    failed=0    skipped=28   rescued=0    ignored=0   

Create data-foo-bar

(env) > ssh admin@www-3 sudo cp -r /usr/local/www/apache24/data /usr/local/www/apache24/data-foo-bar

Results

  • Test the configuration

    (env) > ssh admin@www-3 sudo service apache24 configtest
    Performing sanity check on apache24 configuration:
    Syntax OK
    
  • The virtual host must resolve. For example,

    (env) > nslookup www-3
    Server:         127.0.0.53
    Address:        127.0.0.53#53
    
    Non-authoritative answer:
    Name:    www-3.example.com
    Address: 10.1.0.223
    
    (env) > grep www.foo.bar /etc/hosts
    10.1.0.223 www.foo.bar
    
  • In a browser, open the page https//www.foo.bar/. The content should be

    It works!