NaviServer Modules – 5.1.0
nsssl - Network Driver for HTTPS socket communications
The driver module nsssl is used for the socket communication over HTTPS. The module shares the configuration parameters of nssock and adds additional parameters. This driver requires a NaviServer installation with the configuration option --with-openssl enabled.
This module supports all configuration options of nssock module, plus in addition the following configuration options:
is a required parameter, nsssl won't load without it. The parameter points to a file containing the server certificate chain in PEM format. The file must be sorted starting with the subject's certificate (actual server certificate), followed by intermediate CA certificates if applicable, and ending at the highest level (root) CA.
When no separate key parameter is specified, the certificate file is expected to also contain the server's private key in PEM format (combined file, as in previous NaviServer versions).
The PEM file can contain DH parameters (see the example below how to add these).
optional parameter specifying a separate file containing the server's private key in PEM format.
When key is provided, the private key is loaded from this file instead of the certificate file. This allows deployments with separate certificate chain and private key files.
When key is not specified, the private key is expected to be included in the certificate file (combined PEM file), which is the default and backward-compatible behavior.
Specifying a key without a certificate is not allowed.
When the server receives a hangup signal (HUP), the certificate and private key are reloaded without server restart. The signal can be send also from a script executed in the server:
ns_kill [pid] 1 ;# SIGHUP has signal number 1
defines which ciphers will be used. The ciphers are defined in the OpenSSL "CIPHER LIST FORMAT" https://www.openssl.org/docs/manmaster/apps/ciphers.html. By default nsssl uses all ciphers; recommended cipher suites are published on various sources, such as e.g.: https://wiki.mozilla.org/Security/Server_Side_TLS
defines which ciphersuites for TLSv1.3 (and probably beyond). Due to the major differences between ciphersuites up to TLSv1.2 OpenSSL has decided to configure ciphersuited for TLSv1.3 differently, by using this parameter. For details, consult: https://wiki.openssl.org/index.php/TLS1.3
defines which protocols are enabled; by default all protocols are enabled. It is recommended to deactivate SSLv2 and SSLv3 as shown in the example above.
specifies, whether nsssl should send a client certificate request to the client. The certificate returned (if any) is checked. If the verification process fails, the TLS/SSL handshake is immediately terminated with an alert message containing the reason for the verification failure.
This parameter activates OCSP Stapling for TLS/SSL connections (default off). OCSP Stapling allows a client to check during connection startup the state of the server certificate at the server of the issuer of the certificate (in particular, whether the certificate was revoked or not).
NaviServer performs two level of caching: in-memory caching and disk caching. When the server receives the first TLS request with OCSP stapling turned on, it checks for an already retrieved OCSP response. The disk cache file is saved in the "log" directory of the server and uses the serial number of the certificate to be checked as filename with ".der" as extension. When the disk cache file does not exist, an HTTP/HTTPS request is made to the server issuing the servers certificate as defined by the Authority Information Access (AIA) Extension. The names of the file and the HTTP/HTTPS request for the OCSP response can be obtained from the system log of the server:
... ... Warning: OCSP cache file does not exist: /usr/local/ns/logs/XXX.der ... ... Notice: OCSP command: ns_http run http://ocsp.int-x3.letsencrypt.org/YYYY ...
Note that the .der file can be obtained as well by other means, e.g. via the program "curl". In case an application requires OCSP stapling and the server cannot make requests to the external server e.g. a cron tab can refresh the .der file regularly.
curl http://ocsp.int-x3.letsencrypt.org/YYYY --output /usr/local/ns/logs/XXX.der
For more details about OCSP, see: https://tools.ietf.org/html/rfc6960 OCSP support requires OpenSSL 1.1.0 or newer.
Optionally make OCSP requests more verbose in the log file.
specify the directory for lookup of certificates for mass virtual hosting (see admin-config).
can be used to specify additional header fields be sent on every request handled by this driver. The example above, HTTP Strict Transport Security (HSTS) is enabled.
Obtain the password for the server’s private key included in the PEM file using the configured helper script.
Provide a name for the SSL key log file.
When this parameter is set, NaviServer writes TLS session secrets into the specified file. These secrets can be used by external analysis tools such as Wireshark or tshark to decrypt TLS traffic for debugging and troubleshooting.
If tlskeylogFile is set to a non-empty string, the given filename is used for key logging. The file is opened in append mode, and each new TLS session secret is written as it is negotiated.
If tlskeylogFile is set to an empty string (), NaviServer falls back to the standard environment variable SSLKEYLOGFILE to determine the output file name. This environment variable is widely supported in browsers and other OpenSSL-based applications.
Operational notes: TLS key logging exposes sensitive material that can be used to decrypt TLS connections. This feature should only be enabled in controlled environments for debugging or protocol analysis, and the key log file must be protected or removed once debugging is complete.
The server’s private key can be provided either embedded in the certificate file or via a separate key file.
certificate chain file (certificate)
optional private key file (key)
If no key is specified, the certificate file is expected to contain:
the leaf certificate
any required intermediate certificates
the server’s private key
If the private key is unencrypted, the corresponding file must be carefully protected. In general, passwords should not be stored in plain text on a public server without sufficient safeguards.
NaviServer provides several mechanisms for supplying the private key pass phrase without embedding it directly in configuration files. The mechanisms are evaluated in the following order:
Output of the configured helper script (tlskeyScript)
Environment variable derived from the PEM filename (TLS_KEY_PASS_<FILENAME>)
Generic fallback environment variable (TLS_KEY_PASS)
Interactive prompt on stdin if all else fails (legacy mode)
The first option is recommended for integration with a secrets manager, as it allows retrieval of the pass phrase at startup.
The filename used for deriving the environment variable is the one from which the private key is loaded (i.e., key when specified, otherwise certificate).
The second option derives the environment variable name from the filename. The variable name starts with TLS_KEY_PASS_. The remainder is formed by converting the filename to uppercase and replacing all non-alphanumeric characters with underscores (_). This makes it convenient to handle multiple certificates.
The third option (TLS_KEY_PASS) provides a simpler approach when only a single certificate/key is in use.
If none of these mechanisms succeed, NaviServer falls back to prompting for the pass phrase on stdin during startup.
The module is typically loaded per server (specified below in the variable "server"):
ns_section ns/server/$server/modules {
ns_param nsssl nsssl.so
}
ns_section ns/server/$server/module/nsssl {
ns_param certificate /usr/local/ns/modules/nsssl/server.pem ;# required, PEM format
ns_param key /usr/local/ns/modules/nsssl/server.key ;# optional, PEM format
ns_param address 0.0.0.0
ns_param port 443
ns_param ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384"
ns_param ciphersuites "TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256"
ns_param protocols "!SSLv2:!SSLv3:!TLSv1.0:!TLSv1.1"
ns_param OCSPstapling on
ns_param verify 0
ns_param extraheaders {
strict-transport-security "max-age=31536000; includeSubDomains"
x-frame-options SAMEORIGIN
x-content-type-options nosniff
}
}
This amount of configuration is sufficient for many installations, but often one needs different security setting (path the to certificate, port, ciphers, etc.) or additional settings from nssock such as e.g. writerthreads, maxinput or maxupload.
Below is an example, how a web site can create a self-signed certificate in PEM format.
openssl req -new -x509 -sha256 -newkey rsa:2048 -days 365 -nodes \
-keyout host.key -out host.cert.pem
# combined file (default NaviServer behavior)
cat host.cert.pem host.key > server.pem
# optional: separate files
# certificate: host.cert.pem
# key: host.key
# optional: adding DH params (obsolete for OpenSSL 1.1 or newer)
# openssl dhparam 2048 >> server.pem
Example: Setting a pass phrase via environment variable in a systemd service file with ExecStartPre:
ExecStartPre=/bin/bash -c '\
PASS=$(aws secretsmanager get-secret-value \
--secret-id websrv/tls-pass-phrase \
--query SecretString --output text) && \
/bin/systemctl set-environment TLS_KEY_PASS="$PASS"
…
ExecStart=/usr/local/ns/bin/nsd ...
For discussion and more examples see admin-config.