Apache

From The Linux Source
Jump to: navigation, search

Policy

  • Unneeded/unused modules (in httpd.conf) must be disabled.
  • Modules externally activated by default (ssl/php/perl/python/svn) must be disabled (httpd.conf is modified to use a conf.d-run directory instead of conf.d).
  • Unused features (CGI/SSI/etc) must be disabled.
  • Directory listing from / (recursive from / on filesystem, i.e. not confined to document_root) must be disabled.
  • Server side TRACE/TRACK must be disabled, to minimize the attack surface of the apache authentication stack.
  • Any URL requiring authentication must use https.
  • Management/Status/Configuration pages such as; apache-info, apache-status, balancer-manager, jmx-console, web-console, etc. must be disallowed for any externally accessed URL's.
  • Name & URL's must be masked so that only the IP info is shown for any externally accessed URL's (see "mask server name & URL's" in "Vhost Example" section under "Apache").
  • A CentOS 7 Secure image must be used for web servers or proxy servers.
  • The configuration file must utilize the following approved SSL settings:
    • SSLProtocol all -SSLv2 -SSLv3
    • Header always set Strict-Transport-Security "max-age=15768000;includeSubDomains"
    • Header onsuccess set Strict-Transport-Security "max-age=15768000;includeSubDomains"
    • SSLInsecureRenegotiation off
    • SSLHonorCipherOrder on
    • SSLCipherSuite "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4"

Overview

Our Changes
The Apache configuration has been modified slightly to address several security concerns.
When installing additional apache modules, and some optional software, a config file is added to the conf.d directory, which automatically enables the module/software by default. However, most of these are not actually wanted or needed, nor ever get used. In our case, these end up being disabled by default, since we actually use a conf.d-run directory instead (the module/software configs that are actually needed/desired are copied from conf.d to conf.d-run).
We also create vhost.d (for http URL's) and vhost-ssl.d (for https URL's) directories for virtual host/URL config files. Our current policy is to also include a 0-mask file in these directories which does not serve out any of the sites (when going to the servers IP), but require a valid URL to get to a real/application page.
There are some slight differences with enterprise 7 (and newer/Fedora), which changes the vhost naming, with conf.vhost.d and conf.vhost-ssl.d directories. 7 also adds a conf.modules.d, and thus has our corresponding conf.modules.d-run directory is configured/added.
SSL/Certificates
For IP/certs used for any/all URL's, the first cert defined for the IP (in our mask file) is the cert used for all subsequent URL definitions for that IP (essentially all other cert directives are unused/ignored). To use more than one cert (or more than one domain where wildcard certs are used), additional IP's would need to be used (and the mask section duplicated for the additional IP).
Note: recent changes to kickstart no longer install a cert on every system. This breaks Apache, as it will not start out of the chute from kickstart. Install a valid prod or non-prod cert via yum to resolve.
Note: 2.2.9 added support for ProxyPassReverse balancer://

Documentation References

Enterprise 6

http://httpd.apache.org/docs/2.2/
http://httpd.apache.org/docs/2.2/mod/mod_proxy.html
http://httpd.apache.org/docs/2.2/howto/auth.html

Enterprise 7

http://httpd.apache.org/docs/2.4/
http://httpd.apache.org/docs/2.4/mod/mod_proxy.html
http://httpd.apache.org/docs/2.4/howto/auth.html

VHost Example

Note: the mask section we put in a file named 0-mask (we add the '0-' so it shows up in the dir listing first, i.e. it gets loaded first by apache), the real virtual host (or many virtual host files) should be in their own file(s) based on their URL(s) (a file named 'syslog' in this case)

# mask server name & url's
<VirtualHost 172.16.1.11:443>
   ServerName 172.16.1.11
   DocumentRoot /home/httpd/syslog1/public_html

   # ssl settings
   Header edit Set-Cookie ^(.*)$ $1;Secure;HttpOnly
   SSLEngine on
   SSLCertificateFile /etc/pki/tls/certs/star.example.com.crt
   SSLCertificateKeyFile /etc/pki/tls/private/star.example.com.key
   SSLCertificateChainFile /etc/pki/tls/certs/gd_bundle.crt
   #SSLCARevocationFile /etc/pki/tls/certs/LatestCRL.pem

   # uncomment if used for the real url's below
   #SSLVerifyClient require
   #SSLVerifyDepth  10
   #SSLCACertificateFile /etc/pki/tls/certs/companyCA.crt
</VirtualHost>

# real url's below
<VirtualHost 172.16.1.11:443>
   ServerName syslog.example.com
   ServerAlias syslog1.prd.example.net syslog1
   DocumentRoot /home/httpd/syslog1/public_html
   ServerAdmin webmaster@example.com

   SetOutputFilter DEFLATE

   # settings for being a proxy
   #ProxyTimeout 1200
   #ProxyStatus Full
   #Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED
   # load balancer settings for multiple app servers
   #<Proxy balancer://cluster1>
   #   BalancerMember http://172.16.1.12:8080 route=1
   #   BalancerMember http://172.16.1.13:8080 route=2
   #   ProxySet stickysession=ROUTEID
   #</Proxy>
   #ProxyPass        /apache-info      !
   #ProxyPass        /apache-status    !
   #ProxyPass        /balancer-manager !
   #ProxyPass        /jmx-console      !
   #ProxyPass        /web-console      !
   # single app server settings
   #ProxyPass        /               http://172.16.1.12:8080/app-path/
   #ProxyPassReverse /               http://172.16.1.12:8080/app-path/
   # multiple app servers settings
   #ProxyPass / balancer://cluster1/app-path/
   #ProxyPassReverse / balancer://cluster1/app-path/

   # turn on some minimal caching (on disk) - causes issues where authentication is used
   #CacheEnable disk /
   #CacheRoot "/var/cache/mod_proxy"
   #CacheDirLevels 3
   #CacheDirLength 5
   #CacheIgnoreCacheControl On
   #CacheMaxFileSize 100000
   #CacheIgnoreNoLastMod On
   #CacheMaxExpire 1209600
   #CacheIgnoreQueryString On

   # ssl settings
   Header edit Set-Cookie ^(.*)$ $1;Secure;HttpOnly
   SSLEngine on
   SSLCertificateFile /etc/pki/tls/certs/star.example.com.crt
   SSLCertificateKeyFile /etc/pki/tls/private/star.example.com.key
   SSLCertificateChainFile /etc/pki/tls/certs/gd_bundle.crt
   #SSLCARevocationFile /etc/pki/tls/certs/LatestCRL.pem

   # require client certs
   #SSLVerifyClient require
   #SSLVerifyDepth  10
   #SSLCACertificateFile /etc/pki/tls/certs/companyCA.crt

   # logging
   ErrorLog logs/syslog1-error_log
   # for log analyzers
   CustomLog logs/syslog1-access_log combined
   # for humans
   CustomLog logs/syslog1-custom_log custom
</VirtualHost>

VirtualHost line should have :80 instead of :443 if not ssl/https (and should be in vhost.d dir) All SSL* lines are ssl only, do not include these if not ssl/https Proxy* lines are only if this is a proxy for another app server(s) or a local app (use appropriate IP's)

Proxy VHost Example

Note: the mask section should be/is in a file named 0-mask, the real virtual host(s) (syslog in this case) should be in their own file(s) based on their URL (a file named 'syslog' in this case)

# mask server name & url's
<VirtualHost 172.16.1.11:443>
   ServerName 172.16.1.11
   DocumentRoot /home/httpd/syslog1/public_html

   # ssl settings
   Header edit Set-Cookie ^(.*)$ $1;Secure;HttpOnly
   SSLEngine on
   SSLCertificateFile /etc/pki/tls/certs/star.example.com.crt
   SSLCertificateKeyFile /etc/pki/tls/private/star.example.com.key
   SSLCertificateChainFile /etc/pki/tls/certs/gd_bundle.crt
   #SSLCARevocationFile /etc/pki/tls/certs/LatestCRL.pem

   # uncomment if used for the real url's below
   # require client certs
   #SSLVerifyClient require
   #SSLVerifyDepth  10
   #SSLCACertificateFile /etc/pki/tls/certs/companyCA.crt
</VirtualHost>

# real url's below
<VirtualHost 172.16.1.11:443>
   ServerName syslog1.example.com
   ServerAlias syslog1.prd.example.net syslog1
   DocumentRoot /home/httpd/syslog1/public_html
   ServerAdmin webmaster@example.com

   SetOutputFilter DEFLATE

   # settings for being a proxy
   ProxyTimeout 1200
   ProxyStatus Full
   SSLProxyEngine on
   # load balancer settings for multiple app servers
   #Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED
   #<Proxy balancer://cluster1>
   #   BalancerMember http://172.16.1.12:8080 route=1
   #   BalancerMember http://172.16.1.13:8080 route=2
   #   ProxySet stickysession=ROUTEID
   #</Proxy>
   ProxyPass        /apache-info      !
   ProxyPass        /apache-status    !
   ProxyPass        /balancer-manager !
   ProxyPass        /jmx-console      !
   ProxyPass        /web-console      !
   # single app server settings
   #ProxyPass        /               http://172.16.1.12:8080/app-path/
   #ProxyPassReverse /               http://172.16.1.12:8080/app-path/
   # multiple app servers settings (requires Header & Proxy balancer section above)
   #ProxyPass / balancer://cluster1/app-path/
   #ProxyPassReverse / balancer://cluster1/app-path/

   # turn on some minimal caching (on disk) - causes issues where authentication is used
   #CacheEnable disk /
   #CacheRoot "/var/cache/mod_proxy"
   #CacheDirLevels 3
   #CacheDirLength 5
   #CacheIgnoreCacheControl On
   #CacheMaxFileSize 100000
   #CacheIgnoreNoLastMod On
   #CacheMaxExpire 1209600
   #CacheIgnoreQueryString On

   # ssl settings
   Header edit Set-Cookie ^(.*)$ $1;Secure;HttpOnly
   SSLEngine on
   SSLCertificateFile /etc/pki/tls/certs/star.example.com.crt
   SSLCertificateKeyFile /etc/pki/tls/private/star.example.com.key
   SSLCertificateChainFile /etc/pki/tls/certs/gd_bundle.crt
   #SSLCARevocationFile /etc/pki/tls/certs/LatestCRL.pem

   # require client certs
   #SSLVerifyClient require
   #SSLVerifyDepth  10
   #SSLCACertificateFile /etc/pki/tls/certs/companyCA.crt

   # logging
   ErrorLog logs/syslog1-error_log
   # for log analyzers
   CustomLog logs/syslog1-access_log combined
   # for humans
   CustomLog logs/syslog1-custom_log custom
</VirtualHost>

httpd.conf Example

We change the following lines in the default ssl.conf file

ServerTokens Prod

KeepAlive On

#LoadModule authn_file_module modules/mod_authn_file.so
#LoadModule authn_alias_module modules/mod_authn_alias.so
#LoadModule authn_anon_module modules/mod_authn_anon.so
#LoadModule authn_dbm_module modules/mod_authn_dbm.so

#LoadModule authz_owner_module modules/mod_authz_owner.so
#LoadModule authz_groupfile_module modules/mod_authz_groupfile.so
#LoadModule authz_dbm_module modules/mod_authz_dbm.so

#LoadModule ldap_module modules/mod_ldap.so
#LoadModule authnz_ldap_module modules/mod_authnz_ldap.so
#LoadModule include_module modules/mod_include.so

#LoadModule logio_module modules/mod_logio.so
#LoadModule env_module modules/mod_env.so
#LoadModule ext_filter_module modules/mod_ext_filter.so

#LoadModule expires_module modules/mod_expires.so

#LoadModule dav_module modules/mod_dav.so

#LoadModule dav_fs_module modules/mod_dav_fs.so
#LoadModule vhost_alias_module modules/mod_vhost_alias.so
#LoadModule negotiation_module modules/mod_negotiation.so

#LoadModule actions_module modules/mod_actions.so
#LoadModule speling_module modules/mod_speling.so
#LoadModule userdir_module modules/mod_userdir.so

#LoadModule substitute_module modules/mod_substitute.so
#LoadModule rewrite_module modules/mod_rewrite.so
#LoadModule proxy_module modules/mod_proxy.so
#LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
#LoadModule proxy_ftp_module modules/mod_proxy_ftp.so
#LoadModule proxy_http_module modules/mod_proxy_http.so
#LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
#LoadModule proxy_connect_module modules/mod_proxy_connect.so

#LoadModule suexec_module modules/mod_suexec.so

#LoadModule cgi_module modules/mod_cgi.so
#LoadModule version_module modules/mod_version.so

Include conf.d-run/*.conf

ExtendedStatus On

   Options FollowSymLinks

<Directory /home/httpd/*/public_html>
   AllowOverride None
   Options FollowSymLinks
   <Limit GET POST OPTIONS>
      Order allow,deny
      Allow from all
   </Limit>
   <LimitExcept GET POST OPTIONS>
      Order deny,allow
      Deny from all
   </LimitExcept>
</Directory>

LogFormat "%t \"%v -> %U\" \"%{Referer}i %r\" %>s %Bb %Ts # %h (%a) %u \"%{User-Agent}i\"" custom
#LogFormat "%t \"%v -> %U\" \"%{Referer}i %r\" %>s %Bb %Ob %Ts # %h (%a) %Ib %u \"%{User-Agent}i\"" customio

ServerSignature Off

    Options MultiViews FollowSymLinks

#AddLanguage ca .ca
#AddLanguage cs .cz .cs
#AddLanguage da .dk
#AddLanguage de .de
#AddLanguage el .el
#AddLanguage en .en
#AddLanguage eo .eo
#AddLanguage es .es
#AddLanguage et .et
#AddLanguage fr .fr
#AddLanguage he .he
#AddLanguage hr .hr
#AddLanguage it .it
#AddLanguage ja .ja
#AddLanguage ko .ko
#AddLanguage ltz .ltz
#AddLanguage nl .nl
#AddLanguage nn .nn
#AddLanguage no .no
#AddLanguage pl .po
#AddLanguage pt .pt
#AddLanguage pt-BR .pt-br
#AddLanguage ru .ru
#AddLanguage sv .sv
#AddLanguage zh-CN .zh-cn
#AddLanguage zh-TW .zh-tw

#LanguagePriority en ca cs da de el eo es et fr he hr it ja ko ltz nl nn no pl pt pt-BR ru sv zh-CN zh-TW

#ForceLanguagePriority Prefer Fallback

#AddHandler type-map var

#AddType text/html .shtml
#AddOutputFilter INCLUDES .shtml

<Location /server-status>
    SetHandler server-status
    Order deny,allow
    Deny from all
    Allow from 127.0.0.1 10.117.100
</Location>

<Location /server-info>
    SetHandler server-info
    Order deny,allow
    Deny from all
    Allow from 127.0.0.1 10.117.100
</Location>

# Security Directives
# note: FileETag changes break DAV
FileETag MTime Size
TraceEnable Off
Header always append X-Frame-Options SAMEORIGIN

Include conf/vhost.d/*

SSL Example

We change the following lines in the default ssl.conf file (make sure there is no SSLProtocol & SSLCipherSuite lines in any VirtualHost configurations, or setting the default SSLProtocol & SSLCipherSuite lines in ssl.conf have no effect)
Note: for ent 7, the last line is Include conf.vhost-ssl.d/*.conf

#<VirtualHost _default_:443>

#SSLEngine on

SSLProtocol all -SSLv2 -SSLv3

Header always set Strict-Transport-Security "max-age=15768000;includeSubDomains"
SSLInsecureRenegotiation off
SSLHonorCipherOrder on
SSLCipherSuite "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4"

#SSLCertificateFile /etc/pki/tls/certs/localhost.crt

#SSLCertificateKeyFile /etc/pki/tls/private/localhost.key

#<Files ~ ".(cgi|shtml|phtml|php3?)$">
#    SSLOptions +StdEnvVars
#</Files>
#<Directory "/var/www/cgi-bin">
#    SSLOptions +StdEnvVars
#</Directory>

#</VirtualHost>

Include conf/vhost-ssl.d/*

Files/Directories Layout

Files

(before ent 7)

/etc/httpd/conf/httpd.conf - main config (available from subversion)
/etc/httpd/conf.d-run/ssl.conf - ssl config (available from subversion)
/etc/httpd/conf/vhost-ssl.d/0-mask (mask config & NameVirtualhost setting)
/etc/httpd/conf/vhost-ssl.d/`hostname -s` (default virtual host config)

(ent 7)

/etc/httpd/conf/httpd.conf - main config (minimal config - see conf.d-run (active/in use) or /usr/share/doc/httpd-2.4.*/ (not active) for others, available from subversion)
/etc/httpd/conf.d-run/ssl.conf - ssl config (ssl related directives, available from subversion)
/etc/httpd/conf.d-run/ - additional config files of misc Directives (/home/httpd perms, apache TimeOuts, status pages settings, etc.)
/etc/httpd/conf.vhost-ssl.d/0-mask.conf (mask config & NameVirtualhost setting)
/etc/httpd/conf.vhost-ssl.d/`hostname -s`.conf (default virtual host config)
/etc/httpd/conf.modules.d-run/00-ssl.conf - ssl config (LoadModule setting only)
/etc/httpd/conf.modules.d-run/ - additional LoadModule configs (needed to make apache function, proxy modules, etc.)

Dirs

Notes: The use of .d-run directories protects the currently configured apache from being affected by updates changes and insecure additions of configuration files from installation of new packages. We want additions to be disabled by default, per policy. If a feature is needed, the file is copied from the corresponding .d directory to the .d-run equivalent (ex; from conf.d to conf.d-run).

(before ent 7)

/etc/httpd/
|-- conf            : (main apache conf dir)
|   |-- vhost-ssl.d : (ssl virtual host files)
|   `-- vhost.d     : (non-ssl virtual host files)
|-- conf.d          : (unused, new installs/updates go here)
|-- conf.d-run      : (real/runtime conf.d dir)
|-- logs            : (link to /var/log/httpd/)
|-- modules         : (link to /usr/lib64/httpd/modules/)
`-- run             : (link to /var/run/httpd/)

(ent 7)

/etc/httpd/
|-- conf               : (main apache conf dir)
|-- conf.d             : (unused, new installs/updates go here)
|-- conf.d-run         : (real/runtime conf.d dir)
|-- conf.modules.d     : (unused, new installs/updates go here)
|-- conf.modules.d-run : (real/runtime conf.modules.d dir)
|-- conf.vhost-ssl.d   : (ssl virtual host files)
|-- conf.vhost.d       : (non-ssl virtual host files)
|-- logs               : (link to /var/log/httpd/)
|-- modules            : (link to /usr/lib64/httpd/modules/)
`-- run                : (link to /run/httpd/)

Apache Quick Reference

Commands

Preferred Restart (does not disconnect users/no downtime)

# service httpd graceful

Status

# service httpd status

Test Configuration

# service httpd configtest

Misc Settings

Port 80/http redirect to https

Redirect Permanent / https://wiki.example.com/

redirect to login page

Redirect Permanent / https://beagle.example.com/WORMS/login.htm

Enable compression

SetOutputFilter DEFLATE

Interesting URL's

https://hostname/apache-status (current traffic)
https://hostname/apache-info   (configuration)