<ahref="https://github.com/kubernetes/ingress-nginx/edit/master/docs/deploy/hardening-guide.md"title="Edit this page"class="md-content__button md-icon">
<tdalign="left">2.1.1 Ensure only required modules are installed (Not Scored)</td>
<tdalign="left">OK</td>
<tdalign="left">Already only needed modules are installed, however proposals for further reduction are welcome</td>
<tdalign="left"></td>
</tr>
<tr>
<tdalign="left">2.1.2 Ensure HTTP WebDAV module is not installed (Scored)</td>
<tdalign="left">RISK TO BE ACCEPTED</td>
<tdalign="left">It is installed, see compile options <ahref="https://github.com/kubernetes/ingress-nginx/blob/master/images/nginx/rootfs/build.sh#L445">here</a>. Disabling that would require building own image for nginx ingress controller. The effort is too high in comparison to the achieved effect</td>
<tdalign="left"></td>
</tr>
<tr>
<tdalign="left">2.1.3 Ensure modules with gzip functionality are disabled (Scored)</td>
<tdalign="left">RISK TO BE ACCEPTED</td>
<tdalign="left">See previous answer</td>
<tdalign="left"></td>
</tr>
<tr>
<tdalign="left">2.1.4 Ensure the autoindex module is disabled (Scored)</td>
<tdalign="left">OK</td>
<tdalign="left">No autoindex configs so far in ingress defaults</td>
<tdalign="left">2.2.1 Ensure that NGINX is run using a non-privileged, dedicated service account (Not Scored)</td>
<tdalign="left">OK</td>
<tdalign="left">Pod configured as user www-data: <ahref="https://github.com/kubernetes/ingress-nginx/blob/0cbe783f43a9313c9c26136e888324b1ee91a72f/charts/ingress-nginx/values.yaml#L10">See this line in helm chart values</a>. Compiled with user www-data: <ahref="https://github.com/kubernetes/ingress-nginx/blob/5d67794f4fbf38ec6575476de46201b068eabf87/images/nginx/rootfs/build.sh#L529">See this line in build script</a></td>
<tdalign="left"></td>
</tr>
<tr>
<tdalign="left">2.2.2 Ensure the NGINX service account is locked (Scored)</td>
<tdalign="left">OK</td>
<tdalign="left">Docker design ensures this</td>
<tdalign="left"></td>
</tr>
<tr>
<tdalign="left">2.2.3 Ensure the NGINX service account has an invalid shell (Scored)</td>
<tdalign="left">OK</td>
<tdalign="left">Shell is nologin: <ahref="https://github.com/kubernetes/ingress-nginx/blob/5d67794f4fbf38ec6575476de46201b068eabf87/images/nginx/rootfs/build.sh#L613">see this line in build script</a></td>
<tdalign="left"></td>
</tr>
<tr>
<tdalign="left"></td>
<tdalign="left"></td>
<tdalign="left"></td>
<tdalign="left"></td>
</tr>
<tr>
<tdalign="left"><strong>2.3 Permissions and Ownership</strong></td>
<tdalign="left"></td>
<tdalign="left"></td>
<tdalign="left"></td>
</tr>
<tr>
<tdalign="left">2.3.1 Ensure NGINX directories and files are owned by root (Scored)</td>
<tdalign="left">OK</td>
<tdalign="left">Obsolete through docker-design and ingress controller needs to update the configs dynamically</td>
<tdalign="left"></td>
</tr>
<tr>
<tdalign="left">2.3.2 Ensure access to NGINX directories and files is restricted (Scored)</td>
<tdalign="left">OK</td>
<tdalign="left">See previous answer</td>
<tdalign="left"></td>
</tr>
<tr>
<tdalign="left">2.3.3 Ensure the NGINX process ID (PID) file is secured (Scored)</td>
<tdalign="left">OK</td>
<tdalign="left">No PID-File due to docker design</td>
<tdalign="left"></td>
</tr>
<tr>
<tdalign="left">2.3.4 Ensure the core dump directory is secured (Not Scored)</td>
<tdalign="left">OK</td>
<tdalign="left">No working_directory configured by default</td>
<tdalign="left">2.4.1 Ensure NGINX only listens for network connections on authorized ports (Not Scored)</td>
<tdalign="left">OK</td>
<tdalign="left">Ensured by automatic nginx.conf configuration</td>
<tdalign="left"></td>
</tr>
<tr>
<tdalign="left">2.4.2 Ensure requests for unknown host names are rejected (Not Scored)</td>
<tdalign="left">OK</td>
<tdalign="left">They are not rejected but send to the "default backend" delivering approriate errors (mostly 404)</td>
<tdalign="left"></td>
</tr>
<tr>
<tdalign="left">2.4.3 Ensure keepalive_timeout is 10 seconds or less, but not 0 (Scored)</td>
<tdalign="left">ACTION NEEDED</td>
<tdalign="left">Default is 75s</td>
<tdalign="left">configure keep-alive to 10 seconds <ahref="https://github.com/kubernetes/ingress-nginx/blob/master/docs/user-guide/nginx-configuration/configmap.md#keep-alive">according to this documentation</a></td>
</tr>
<tr>
<tdalign="left">2.4.4 Ensure send_timeout is set to 10 seconds or less, but not 0 (Scored)</td>
<tdalign="left">RISK TO BE ACCEPTED</td>
<tdalign="left">Not configured, however the nginx default is 60s</td>
<tdalign="left">Not configurable</td>
</tr>
<tr>
<tdalign="left"></td>
<tdalign="left"></td>
<tdalign="left"></td>
<tdalign="left"></td>
</tr>
<tr>
<tdalign="left"><strong>2.5 Information Disclosure</strong></td>
<tdalign="left"></td>
<tdalign="left"></td>
<tdalign="left"></td>
</tr>
<tr>
<tdalign="left">2.5.1 Ensure server_tokens directive is set to <code>off</code> (Scored)</td>
<tdalign="left">2.5.2 Ensure default error and index.html pages do not reference NGINX (Scored)</td>
<tdalign="left">ACTION NEEDED</td>
<tdalign="left">404 shows no version at all, 503 and 403 show "nginx", which is hardcoded <ahref="https://github.com/nginx/nginx/blob/master/src/http/ngx_http_special_response.c#L36">see this line in nginx source code</a></td>
<tdalign="left">configure custom error pages at least for 403, 404 and 503 and 500</td>
</tr>
<tr>
<tdalign="left">2.5.3 Ensure hidden file serving is disabled (Not Scored)</td>
<tdalign="left">ACTION NEEDED</td>
<tdalign="left">config not set</td>
<tdalign="left">configure a config.server-snippet Snippet, but beware of .well-known challenges or similar. Refer to the benchmark here please</td>
</tr>
<tr>
<tdalign="left">2.5.4 Ensure the NGINX reverse proxy does not enable information disclosure (Scored)</td>
<tdalign="left">ACTION NEEDED</td>
<tdalign="left">hide not configured</td>
<tdalign="left">configure hide-headers with array of "X-Powered-By" and "Server": <ahref="https://github.com/kubernetes/ingress-nginx/blob/master/docs/user-guide/nginx-configuration/configmap.md#hide-headers">according to this documentation</a></td>
</tr>
<tr>
<tdalign="left"></td>
<tdalign="left"></td>
<tdalign="left"></td>
<tdalign="left"></td>
</tr>
<tr>
<tdalign="left"><strong>3 Logging</strong></td>
<tdalign="left"></td>
<tdalign="left"></td>
<tdalign="left"></td>
</tr>
<tr>
<tdalign="left"></td>
<tdalign="left"></td>
<tdalign="left"></td>
<tdalign="left"></td>
</tr>
<tr>
<tdalign="left">3.1 Ensure detailed logging is enabled (Not Scored)</td>
<tdalign="left">OK</td>
<tdalign="left">Ningx ingress has a very detailled log format by default</td>
<tdalign="left"></td>
</tr>
<tr>
<tdalign="left">3.2 Ensure access logging is enabled (Scored)</td>
<tdalign="left">OK</td>
<tdalign="left">Access log is enabled by default</td>
<tdalign="left"></td>
</tr>
<tr>
<tdalign="left">3.3 Ensure error logging is enabled and set to the info logging level (Scored)</td>
<tdalign="left">OK</td>
<tdalign="left">Error log is configured by default. The log level does not matter, because it is all sent to STDOUT anyway</td>
<tdalign="left"></td>
</tr>
<tr>
<tdalign="left">3.4 Ensure log files are rotated (Scored)</td>
<tdalign="left">OBSOLETE</td>
<tdalign="left">Log file handling is not part of the nginx ingress and should be handled separatly</td>
<tdalign="left"></td>
</tr>
<tr>
<tdalign="left">3.5 Ensure error logs are sent to a remote syslog server (Not Scored)</td>
<tdalign="left">OBSOLETE</td>
<tdalign="left">See previous answer</td>
<tdalign="left"></td>
</tr>
<tr>
<tdalign="left">3.6 Ensure access logs are sent to a remote syslog server (Not Scored)</td>
<tdalign="left">OBSOLETE</td>
<tdalign="left">See previous answer</td>
<tdalign="left"></td>
</tr>
<tr>
<tdalign="left">3.7 Ensure proxies pass source IP information (Scored)</td>
<tdalign="left">Default ciphers are already good, but cipherlist.eu recommends even stronger ciphers</td>
<tdalign="left">Set controller.config.ssl-ciphers to "EECDH+AESGCM:EDH+AESGCM"</td>
</tr>
<tr>
<tdalign="left">4.1.6 Ensure custom Diffie-Hellman parameters are used (Scored)</td>
<tdalign="left">ACTION NEEDED</td>
<tdalign="left">No custom DH parameters are generated</td>
<tdalign="left">Generate dh parameters for each ingress deployment you use - <ahref="https://kubernetes.github.io/ingress-nginx/examples/customization/ssl-dh-param/">see here for a how to</a></td>
</tr>
<tr>
<tdalign="left">4.1.7 Ensure Online Certificate Status Protocol (OCSP) stapling is enabled (Scored)</td>
<tdalign="left">ACTION NEEDED</td>
<tdalign="left">Not enabled</td>
<tdalign="left">set via <ahref="https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/#enable-ocsp">this configuration parameter</a></td>
</tr>
<tr>
<tdalign="left">4.1.8 Ensure HTTP Strict Transport Security (HSTS) is enabled (Scored)</td>
<tdalign="left">OK</td>
<tdalign="left">HSTS is enabled by default</td>
<tdalign="left"></td>
</tr>
<tr>
<tdalign="left">4.1.9 Ensure HTTP Public Key Pinning is enabled (Not Scored)</td>
<tdalign="left">ACTION NEEDED / RISK TO BE ACCEPTED</td>
<tdalign="left">HKPK not enabled by default</td>
<tdalign="left">If lets encrypt is not used, set correct HPKP header. There are several ways to implement this - with the helm charts it works via controller.add-headers. If lets encrypt is used, this is complicated, a solution here is yet unknown</td>
</tr>
<tr>
<tdalign="left">4.1.10 Ensure upstream server traffic is authenticated with a client certificate (Scored)</td>
<tdalign="left">DEPENDS ON BACKEND</td>
<tdalign="left">Highly dependend on backends, not every backend allows configuring this, can also be mitigated via a service mesh</td>
<tdalign="left">If backend allows it, <ahref="https://kubernetes.github.io/ingress-nginx/examples/auth/client-certs/">manual is here</a></td>
</tr>
<tr>
<tdalign="left">4.1.11 Ensure the upstream traffic server certificate is trusted (Not Scored)</td>
<tdalign="left">DEPENDS ON BACKEND</td>
<tdalign="left">Highly dependend on backends, not every backend allows configuring this, can also be mitigated via a service mesh</td>
<tdalign="left">5.2.1 Ensure timeout values for reading the client header and body are set correctly (Scored)</td>
<tdalign="left">ACTION NEEDED</td>
<tdalign="left">Default timeout is 60s</td>
<tdalign="left">Set via <ahref="https://github.com/kubernetes/ingress-nginx/blob/master/docs/user-guide/nginx-configuration/configmap.md#client-header-timeout">this configuration parameter</a> and respective body aequivalent</td>
</tr>
<tr>
<tdalign="left">5.2.2 Ensure the maximum request body size is set correctly (Scored)</td>
<tdalign="left">ACTION NEEDED</td>
<tdalign="left">Default is 1m</td>
<tdalign="left">set via <ahref="https://github.com/kubernetes/ingress-nginx/blob/master/docs/user-guide/nginx-configuration/configmap.md#proxy-body-size">this configuration parameter</a></td>
</tr>
<tr>
<tdalign="left">5.2.3 Ensure the maximum buffer size for URIs is defined (Scored)</td>
<tdalign="left">ACTION NEEDED</td>
<tdalign="left">Default is 4 8k</td>
<tdalign="left">Set via <ahref="https://github.com/kubernetes/ingress-nginx/blob/master/docs/user-guide/nginx-configuration/configmap.md#large-client-header-buffers">this configuration parameter</a></td>
</tr>
<tr>
<tdalign="left">5.2.4 Ensure the number of connections per IP address is limited (Not Scored)</td>
<tdalign="left">OK/ACTION NEEDED</td>
<tdalign="left">No limit set</td>
<tdalign="left">Depends on use case, limit can be set via <ahref="https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#rate-limiting">these annotations</a></td>
</tr>
<tr>
<tdalign="left">5.2.5 Ensure rate limits by IP address are set (Not Scored)</td>
<tdalign="left">OK/ACTION NEEDED</td>
<tdalign="left">No limit set</td>
<tdalign="left">Depends on use case, limit can be set via <ahref="https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#rate-limiting">these annotations</a></td>
<scriptsrc="../../assets/javascripts/bundle.e9fe3281.min.js"></script><scriptid="__lang"type="application/json">{"clipboard.copy":"Copy to clipboard","clipboard.copied":"Copied to clipboard","search.config.lang":"en","search.config.pipeline":"trimmer, stopWordFilter","search.config.separator":"[\\s\\-]+","search.result.placeholder":"Type to start searching","search.result.none":"No matching documents","search.result.one":"1 matching document","search.result.other":"# matching documents"}</script>