Configure Apache

Allow HTTP/HTTPS traffic

Add to your service’s Pillar file:

apache:
  public_access: True

This will:

  • Open ports 80 (HTTP) and 443 (HTTPS)

  • Install the Apache service

  • Enable the mod_http2, mod_md and mod_ssl Apache modules

  • Enable an Apache configuration for acquiring Let’s Encrypt certificates

If you are only using Apache to serve Python apps, continue from Configure Python apps.

Bind addresses

If the server has multiple web servers for different IPs, add to your service’s Pillar file:

apache:
  ipv4: 65.21.93.181
  ipv6: 2a01:4f9:3b:45ca::2
  wait_for_networking: True

Add sites

Add to your service’s Pillar file:

apache:
  public_access: True
  sites:
    ocds-docs-live:
      configuration: docs
      servername: standard.open-contracting.org
      serveraliases: ['myalias.open-contracting.org']
      context:
        mykey: myvalue

This will:

  • Create a /etc/apache2/sites-available/ocds-docs-live.conf file that includes a /etc/apache2/sites-available/ocds-docs-live.conf.include file, which, together, will:

    • If apache.public_access is True and https isn’t False:

    • Create a virtual host serving port 80

    • Set the virtual host’s servername and serveraliases, if any

  • Symlink the new file from the /etc/apache2/sites-enabled directory

  • Reload the Apache service if the configuration changed

The example above uses the docs configuration. The keys of the context mapping are made available as variables in the configuration template.

Note

To delete a virtual host, follow these instructions.

Reference: What to use When

Add basic authentication

  1. Add, in a private Pillar file:

    apache:
      sites:
        SITE:
          htpasswd:
            NAME: PASSWORD
    

    This will add the user to the /etc/apache2/.htpasswd-SITE file.

  2. Reference the htpasswd file from an Apache configuration file. For example:

    <Location "/">
        AuthName "My Site"
        AuthType Basic
        AuthUserFile /etc/apache2/.htpasswd-SITE
        Require valid-user
    </Location>
    
  3. Or, use the proxy configuration in your service’s Pillar file:

apache:
  public_access: True
  sites:
    kingfisher-collect:
      configuration: proxy
      servername: collect.data.open-contracting.org
      context:
        documentroot: /home/collect/scrapyd
        proxypass: http://localhost:6800/
        authname: Kingfisher Scrapyd

Note

To delete an htpasswd entry, follow these instructions.

Acquire SSL certificates

If apache.public_access is True and https isn’t False, mod_md is used to acquire SSL certificates from Let’s Encrypt. If the server name is new, you must:

  1. Add a CNAME record.

    Attention

    Let’s Encrypt will reach a Failed Validation limit if DNS is not propagated.

  2. Deploy the service, if not already done.

  3. mod_md will request a certificate from Let’s Encrypt. Check for a message in /var/log/apache2/error.log, replacing TARGET:

    ./run.py TARGET cmd.run 'grep "Managed Domain" /var/log/apache2/error.log'
    

    For example:

    AH10059: The Managed Domain ssl-test.open-contracting.org has been setup and changes will be activated on next (graceful) server restart.
    
  4. Reload the Apache service, replacing TARGET:

    ./run.py TARGET service.reload apache2
    

The service should now be available at its https:// web address.

Test

Test the HTTP redirect, replacing SERVERNAME:

$ curl -I http://SERVERNAME
HTTP/1.1 301 Moved Permanently
Date: Fri, 11 Dec 2020 12:34:56 GMT
Server: Apache/2.4.46 (Ubuntu)
Location: https://SERVERNAME/
Content-Type: text/html; charset=iso-8859-1

Test the HTTPS response:

$ curl -IL https://SERVERNAME
HTTP/2 200
date: Fri, 11 Dec 2020 04:26:57 GMT
server: Apache/2.4.46 (Ubuntu)
strict-transport-security: max-age=15768000

Check the certificates’ status:

curl https://SERVERNAME/.httpd/certificate-status

Check md-status, replacing TARGET:

./run.py TARGET cmd.run 'curl -sS http://localhost/md-status'

Each certificate’s OCSP "status" should be "good".

You can test the SSL configuration using SSL Labs.

Troubleshoot

In case of error, see mod_md’s troubleshooting guide. If you need to test the acquisition of certificates, use Let’s Encrypt’s staging environment.

Enable Apache modules

You might need to enable Apache modules to use non-core directives in your configuration files.

There are state files for common modules:

apache.modules.headers

Provides Header and RequestHeader directives.

apache.modules.http2

Provides support for the HTTP/2 protocol.

apache.modules.md

Acquires SSL certificates from Let’s Encrypt.

apache.modules.passenger

Adds the Passenger app server.

apache.modules.proxy

Adds ProxyPass, ProxyPreserveHost and other directives. Included by apache.modules.proxy_http and apache.modules.proxy_uwsgi.

apache.modules.proxy_fcgi

Provides supports for the FastCGI protocol in ProxyPass directives. Included by the php-fpm state file.

apache.modules.proxy_http

Provides support for HTTP/HTTPS requests in ProxyPass directives. Included by the python_apps state file.

apache.modules.proxy_uwsgi

Provides supports for the uWSGI protocol in ProxyPass directives. Included by the python_apps state file.

apache.modules.rewrite

Adds the mod_rewrite rule-based rewriting engine to rewrite requested URLs on the fly.

apache.modules.ssl

Included and required by apache.modules.md.

To enable a module, include the relevant state file in your service’s state file. For example:

include:
  - apache.modules.headers

To disable an Apache module, follow these instructions.

If you need another module, consider adding a state file under the salt/apache/modules directory.

Note

The following state files are not used presently:

  • apache.modules.deflate

  • apache.modules.expires

  • apache.modules.remoteip

Configure Apache modules

autoindex

mod_autoindex is disabled by default. To enable it:

apache:
  modules:
    mod_autoindex:
      enabled: True

md

You can configure mod_md by adding Apache directives to your service’s Pillar file. For example:

apache:
  public_access: True
  modules:
    mod_md:
      MDMessageCmd: /opt/postgresql-certificates.sh

To test your configuration, use Let’s Encrypt’s staging environment, in order to avoid the duplicate certificate limit:

apache:
  public_access: True
  modules:
    mod_md:
      MDMessageCmd: /opt/postgresql-certificates.sh
      MDCertificateAuthority: https://acme-staging-v02.api.letsencrypt.org/directory

You can then remove the /etc/apache2/md/staging/DOMAIN and /etc/apache2/md/domains/DOMAIN directories as often as needed, and re-acquire certificates.

Tip

If you use the MDMessageCmd or MDNotifyCmd directives, add LogLevel: md:debug during testing, and check the Apache error log for lines containing cmd(:

tail -f /var/log/apache2/error.log