Apache
Contents
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 Timeout 1200 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 allow,deny Deny from all </LimitExcept> </Directory> LogFormat "%t \"%v -> %U\" \"%{Referer}i %r\" %>s %Bb %Ts # %h (%a) %u \"%{User-Agent}i\"" custom
506d504
#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 #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 SSLProtocol all -SSLv2 -SSLv3 Header always set Strict-Transport-Security "max-age=15768000;includeSubDomains" SSLInsecureRenegotiation off SSLHonorCipherOrder on #SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW 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)