# This file is rendered by CFEngine
# manual edits will be reverted.

ServerSignature Off
ServerTokens ProductOnly
ServerName {{{vars.sys.fqhost}}}
ServerRoot "{{{vars.sys.workdir}}}/httpd"
{{^classes.cfe_enterprise_disable_plain_http}}
# ENT-10411
# ENT-10646 - Listen 80 often causes IPv6 related errors, specifying ipv4 squashes them.
#   Unclear why the same is not an issue for 443
#   To enable listening on ipv6 add Listen [::]:80
Listen 0.0.0.0:{{{vars.cfe_internal_hub_vars.http_port}}}
{{/classes.cfe_enterprise_disable_plain_http}}

PidFile "{{{vars.mission_portal_apache_from_stage.httpd_pid_file}}}"

# Modules
# Note: Not all modules that are built are loaded.
# Find built modules in {{{vars.sys.workdir}}}/httpd/modules

# Our default log format uses features provided by these modules
LoadModule log_config_module modules/mod_log_config.so
LoadModule logio_module modules/mod_logio.so

# We use the Header directive which is provided by this module
LoadModule headers_module modules/mod_headers.so

# We use the BrowserMatch directive which is provided by this module
LoadModule setenvif_module modules/mod_setenvif.so

# Associates the requested filename's extensions with the file's behavior
# (handlers and filters) and content (mime-type, language, character set and
# encoding)
LoadModule mime_module modules/mod_mime.so

# Provides for "trailing slash" redirects and serving directory index files
LoadModule dir_module modules/mod_dir.so

# Used for mapping in some nicer URL names
# TODO Consider removal after 3.20 is EOL (used by transition in 3.16)
LoadModule alias_module modules/mod_alias.so

# Required for http->https redirection and handling indexes
LoadModule rewrite_module modules/mod_rewrite.so

# Required for secure access
LoadModule ssl_module modules/mod_ssl.so

# Required to drop privledges
LoadModule unixd_module modules/mod_unixd.so

# Required for use of Order and Require commands
LoadModule access_compat_module modules/mod_access_compat.so

# Required for SSL Session Caching
LoadModule socache_shmcb_module modules/mod_socache_shmcb.so

# Required to log into mission portal
LoadModule authz_core_module modules/mod_authz_core.so


# TRACE can be useful for debugging, but can be abused to perform Cross-Site
# Tracing (XST) attacheks in order to obtain access to user cooking via
# malicious scripting on the client side.

TraceEnable off

# The 'HttpOnly' flag makes the cookie inaccessible to client-side scripts,
# preventing it from being stolen using malicious client side scripts. The
# absence of this flag increases the likelihood of an attacker being able to
# compromise the user's cookie via a malicious script. When the 'secure' flag is
# used, the cookie is only sent over an encrypted HTTPS channel, and not over
# unencrypted HTTP.

Header edit Set-Cookie ^(.*)$ $1;HttpOnly;Secure

<IfModule userdir_module>
# This module should not be loaded, this is just an extra measure.
  UserDir disabled
</IfModule>

<IfModule !mpm_netware_module>
  <IfModule !mpm_winnt_module>
    User cfapache
    Group cfapache
  </IfModule>
</IfModule>

# Server configuration
# ServerAdmin root@localhost
DocumentRoot "{{{vars.cfe_internal_hub_vars.public_docroot}}}"

<Directory />
    Order deny,allow
    Deny from all
    Options FollowSymLinks

    AllowOverride None
</Directory>

<IfModule dir_module>
    DirectoryIndex index.html index.php
</IfModule>

<FilesMatch "^\.ht">
    Order allow,deny
    Deny from all
    Satisfy All
</FilesMatch>

ErrorLog "logs/error_log"
{{#data:cfengine_enterprise_mission_portal_debug_php_fpm}}
LogLevel warn rewrite:trace6 proxy:debug proxy_fcgi:debug dir:debug
{{/data:cfengine_enterprise_mission_portal_debug_php_fpm}}
{{^data:cfengine_enterprise_mission_portal_debug_php_fpm}}
LogLevel warn
{{/data:cfengine_enterprise_mission_portal_debug_php_fpm}}

<IfModule log_config_module>
    LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
    LogFormat "%h %l %u %t \"%r\" %>s %b" common
    LogFormat "%h %l %{username}n %t \"%r\" %>s %b" common_with_apache_notes_username

    <IfModule logio_module>
      LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
    </IfModule>

    CustomLog "logs/access_log" common_with_apache_notes_username
</IfModule>

<IfModule mime_module>
    TypesConfig conf/mime.types
    AddType application/x-compress .Z
    AddType application/x-gzip .gz .tgz
</IfModule>

<IfModule ssl_module>
  # Include conf/extra/httpd-ssl.conf
  # This content used to be included from an external file
  # /var/cfengine/httpd/conf/extra/httpd-ssl.conf

  Listen {{{vars.cfe_internal_hub_vars.https_port}}}

  AddType application/x-x509-ca-cert .crt
  AddType application/x-pkcs7-crl    .crl

  SSLPassPhraseDialog  builtin
  SSLSessionCache        "shmcb:{{{vars.sys.workdir}}}/httpd/logs/ssl_scache(512000)"
  SSLSessionCacheTimeout  300
  SSLSessionTickets Off

  # OCSP stapling is an extension that aims to improve SSL negotiation
  # performance while mainting visitor privacy. Disabled because of
  # issues with self signed certs.

  SSLUseStapling off
  # SSLStaplingCache "shmcb:logs/stabling-cache(150000)"

  # TLS Compression should be disabled to avoid CRIME
  # https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2012-4929
  # SSLCompression off
  # As part of security hardening we minimize the features provided by OpenSSL.
  # Case in point, we build openssl 3 without support for compression. As such,
  # we do not explicitly disable SSL Compression beginning with CFEngine
  # Enteprprise 3.21.0 as apache is unable to then validate the configuration.

  # This is not explicitly enabled to allow the requesting client the first
  # choice of support ciphers
  #  SSLHonorCipherOrder On

  # We expect that openssl is upgraded with each release and that the most
  # recent openssl version possible will be used and that it defines ciphers
  # considered HIGH appropriately. We use HIGH to get a good balance between
  # browser compatibility and security. Use ~{{vars.sys.workdir}}/openssl ciphers
  # -v HIGH~ to see what ciphers are considered HIGH security.

  # SSLCipherSuite HIGH

  # A more secure setting might be:
  # SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH

  SSLCipherSuite {{{vars.def.cfe_enterprise_mission_portal_apache_sslciphersuite}}}

  # The SSL protocol versions allowed
  SSLProtocol {{{vars.def.cfe_enterprise_mission_portal_apache_sslprotocol}}}

  SSLRandomSeed startup builtin
  SSLRandomSeed connect builtin

  <VirtualHost _default_:{{{vars.cfe_internal_hub_vars.https_port}}}>
    DocumentRoot "{{{vars.cfe_internal_hub_vars.public_docroot}}}"
    Alias "/api" "{{{vars.cfe_internal_hub_vars.docroot}}}/api"
    Alias "/api/static" "{{{vars.cfe_internal_hub_vars.docroot}}}/api/static"
    Alias "/ldap" "{{{vars.cfe_internal_hub_vars.docroot}}}/ldap"
    ServerName {{{vars.sys.fqhost}}}:{{{vars.cfe_internal_hub_vars.https_port}}}
    # ServerAdmin root@localhost
    ErrorLog "{{{vars.cfe_internal_hub_vars.error_log}}}"
    LogFormat "%h %l %{username}n %t \"%r\" %>s %b"
    TransferLog "{{{vars.cfe_internal_hub_vars.access_log}}}"

    SSLEngine on
    SSLCertificateFile "{{{vars.cfe_internal_hub_vars.SSLCertificateFile}}}"
    SSLCertificateKeyFile "{{{vars.cfe_internal_hub_vars.SSLCertificateKeyFile}}}"
{{#classes.cfe_enterprise_have_SSLCACertificateFile_defined}}
    SSLCACertificateFile "{{{vars.cfe_internal_hub_vars.SSLCACertificateFile}}}"
{{/classes.cfe_enterprise_have_SSLCACertificateFile_defined}}

    # Enable Strict Transport Security to prevent HTTPS users from
    # accessing http content.
    Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"
    Header always set X-Frame-Options DENY
    Header always set X-Content-Type-Options nosniff

    Header always set Content-Security-Policy \
    "frame-ancestors 'self'; \
    default-src 'self'; \
    script-src 'self' 'unsafe-inline'; \
    style-src 'self' 'unsafe-inline' fonts.googleapis.com; \
    object-src 'none'; \
    frame-src 'self'; \
    child-src 'self'; \
    img-src 'self' data: blob: avatars.githubusercontent.com badges.gitter.im fonts.gstatic.com kiwiirc.com raw.githubusercontent.com raw.github.com; \
    font-src 'self' data: fonts.googleapis.com fonts.gstatic.com; \
    connect-src 'self' fonts.gstatic.com fonts.googleapis.com; \
    manifest-src 'self'; \
    base-uri 'self'; \
    form-action 'self'; \
    media-src 'self'; \
    worker-src 'self' blob:;"

    <FilesMatch "\.(cgi|shtml|phtml|php)$">
        SSLOptions +StdEnvVars
    </FilesMatch>

    <Directory "{{{vars.sys.workdir}}}/httpd/cgi-bin">
        SSLOptions +StdEnvVars
        AllowOverride None
    </Directory>

    BrowserMatch "MSIE [2-5]" \
         nokeepalive ssl-unclean-shutdown \
         downgrade-1.0 force-response-1.0

    CustomLog "{{{vars.cfe_internal_hub_vars.ssl_request_log}}}" \
          "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
  </VirtualHost>

</IfModule>


# Timeout defaults to 60 but that is too short for some operations on slower hub hardware
Timeout 120

{{#classes.mission_portal_http2_enabled}}
# Use mod_http2
LoadModule http2_module modules/mod_http2.so
# Prefer http2 protocol
Protocols h2 h2c http/1.1

# Setup php to be handled by php-fpm. Required for use of mod_http2 due to threading issues in php.
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so
# Need to pass auth headers to fpm
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
<FilesMatch \.php$>
SetHandler "proxy:fcgi://127.0.0.1:9000"
</FilesMatch>
{{/classes.mission_portal_http2_enabled}}
{{^classes.mission_portal_http2_enabled}}
LoadModule php{{{vars.cfe_internal_hub_vars.php_version}}}_module       modules/libphp{{{vars.cfe_internal_hub_vars.php_version}}}.so
AddHandler php{{{vars.cfe_internal_hub_vars.php_version}}}-script       .php
AddType    application/x-httpd-php-source php{{{vars.cfe_internal_hub_vars.php_version}}}
{{/classes.mission_portal_http2_enabled}}

<Directory "{{{vars.cfe_internal_hub_vars.public_docroot}}}">

    Options -Indexes +FollowSymLinks +MultiViews
    Order deny,allow

    AllowOverride None

  <IfModule rewrite_module>
    RewriteEngine On

    {{#classes.mission_portal_index_php_redirect_enabled}}
    # redirect from `index.php/path` to `/path`
    RewriteCond %{REQUEST_URI} !(.*)/api/(.*) [NC]  #do not apply redirect to internal APIs for backward compatibility
    RewriteCond %{THE_REQUEST} /index\.php/(.+)\sHTTP [NC]
    RewriteRule ^ /%1 [NE,L,R]
    {{/classes.mission_portal_index_php_redirect_enabled}}

    RewriteCond %{REQUEST_FILENAME} -s [OR]
    RewriteCond %{REQUEST_FILENAME} -l [OR]
    RewriteCond %{REQUEST_FILENAME} -d
    RewriteRule ^.*$ - [NC,L]
    RewriteRule ^(.*)$ /index.php/$1 [NC,L]
  </IfModule>
</Directory>

<Directory "{{{vars.cfe_internal_hub_vars.docroot}}}/api">

    Order deny,allow
    AllowOverride None

  <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteRule ^static/(.+)$ static/$1 [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$ dispatch.php [QSA,L]
  </IfModule>
</Directory>

<Directory "{{{vars.cfe_internal_hub_vars.docroot}}}/api/static">

    Order deny,allow
    AllowOverride None

  # What do we use mod_mime for?
  <IfModule mod_mime.c>
    AddType text/csv .csv
    AddType application/pdf .pdf
    AddType application/json .json
  </IfModule>
</Directory>

<Directory "{{{vars.cfe_internal_hub_vars.docroot}}}/ldap">

    Order deny,allow
    AllowOverride None

  <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [QSA,L]
  </IfModule>
</Directory>

<Directory "{{{vars.cfe_internal_hub_vars.docroot}}}/system">
  # Whats in here that got a specific deny?
  Deny from all
  AllowOverride None
</Directory>
