Skip to main content
Version: 8.2411.x.x RR

BackendConnectorServlet

The BackendConnectorServlet forwards HTTP/HTTPS requests to content providers in the backend, using HTTP/HTTPS over TCP/IP.

Connecting to the backend and forwarding requests is the only responsibility of this servlet.

It does not support load balancing, rewriting, cookie caching, or similar operations. To configure these tasks, use the following filters:

  • load balancing -->
    • LuaFilter (for a possible setup, see the example loadbalancing_servlets.example that is provided in the nevisProxy package)
    • LoadBalancerServlet
  • rewriting --> RewriteFilter, LuaFilter (see the rewriting section further down)
  • cookie caching --> CookieCacheFilter

The advantages of using the BackendConnectorServlet instead of the Http(s)ConnectorServlet:

  • The BackendConnectorServlet is easier to configure and troubleshoot due to focused responsibility.
  • The BackendConnectorServlet will be optimized for more performance in the near future.
Classname
ch::nevis::nevisproxy::servlet::connector::http::BackendConnectorServlet
Library
libBackendServlet.so.1
TraceGroup
BC.Tracer.DebugProfile.NPBackendSrv

Configuration

InetAddress

Type: string
Usage Constraints: required
Syntax: <hostname>[:<portnumber>]

Describes the host and port of the backend to connect to. If no <portNumber> is given then the following defaults are taken:

  • 80 for plain connections
  • 443 for secure connections

You can also set a dynamic address with the following syntax: <source>:<name>;[<source>:<name>;], where:

  • <source>: ENV, AUTH, HEADER, PARAM, or SESSION.
  • <name>: the name in the given source.

For example SESSION:host; will get the host to connect to the attribute "host" in the session.

InetAddress.MaxBufferedDynamic

Type: integer
Range: min: 1, max: 1000
Usage Constraints: optional
Default: 100

This parameter is only evaluated if a dynamic InetAddress is configured. It sets the maximum number of host addresses to buffer. For optimal usage, you should set it at least to the maximal number of dynamic addresses that may be used.

HostName

Type: string
Usage Constraints: optional

Defines the value to send to the backend as Host Header. If you do not set this attribute, the value of the attribute InetAddress will be sent. According to RFC-2616, when non-standard ports are used, the port number also has to be included here.

Secure

Type: boolean
Default: true
Secure default: true

Defines whether to open a secure (HTTPS) or not secure (HTTP) connection to the backend.

note

The following attributes with the Secure. prefix will be only evaluated if this attribute is true.

Secure.Protocol

Type: string
Syntax: [all][+/-][TLSv1] [+/-][TLSv1.1] [+/-][TLSv1.2] [+/-][TLSv1.3]
Default: -all +TLSv1.2 +TLSv1.3
Secure default: -all +TLSv1.2 +TLSv1.3

No sign means +. Separate each entry in the SSL protocol list by a blank.

caution

Some backends may not understand TLSv1.3 and thus cannot tell the proxy to downgrade.

Secure.CipherSuites

Type: string
Default and secure default: ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256

This attribute defines the SSL cipher suite to use. You can set all ciphers that are supported by OpenSSL. You can have maximal 2 newline separated lines with the following syntax:
[protocol] cipher-spec

where:

  • protocol: The optional protocol specifier can configure the Cipher Suite for a specific SSL version. Possible values include "SSL" for all SSL Protocols up to and including TLSv1.2 and "TLSv1.3" for TLSv1.3. If not set, then SSL is taken.
  • cipher-spec: colon-separated cipher-spec string consisting of OpenSSL cipher specifications to configure the Cipher Suite the server is permitted to negotiate in the SSL handshake phase

For a list of TLSv1.3 cipher names, see the OpenSSL documentation (https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_ciphersuites.html).

Secure.ConnectionRetries

Type: integer
Usage Constraints: min: 0, max: 100
Default: 0

This attribute is only evaluated if the attribute Secure is set to "true". Sometimes an TLS connection fails because of some unknown problem (such as a network problem). This parameter specifies how many times the servlet should try to connect before giving up.

Secure.CACertificateFile

Type: string
Usage Constraints: optional, mandatory if Secure.CheckPeerHostname is enabled

Specifies the file containing the CA certificate(s) that are used to check whether the peer’s node certificate is trusted. All the certificates in the file will be verified. PEM encoded files are supported. Nevis PKCS#11 URLs are not supported. If the attribute Secure.CACertificateFile attribute is not specified, the peer certificate will be trusted automatically.
For security reasons it is recommended that you always specify the Secure.CACertificateFile attribute.

Secure.ClientCertificateFile

Type: string
Usage Constraints: optional

Specifies the X509 node certificate that will be sent to the application server (if requested by a SSL/TLS CertificateRequest message). PEM encoded files are supported for node certificates and certificate chains, and Nevis PKCS#11 URLs are supported for node certificates. If the file contains a certificate chain then the certificates must be in PEM format and must be sorted starting with the subject's certificate (actual client or server certificate), followed by intermediate CA certificates if applicable, and ending at the highest level (root) CA.

In case of a pkcs#11 based HSM (f.ex. Securosys) you can extract the certificate in PEM format via a command similar to this:

/opt/nevisproxy/bin/openssl storeutl -engine /opt/nevisproxy/lib/libnevisproxypkcs11engine.so 'pkcs11:library=/usr/local/primus/lib/libprimusP11.so&dologin=true&objectlabel=proxy.cert&type=cert&pinenv=PKCS11_PIN'

If you specify a certificate chain for an pkcs#11 based HSM then the pkcs#11 URL has to be specified in the parameter Secure.ClientKeyFile.

Client certificates are experimental when using TLSv1.3.

Secure.ClientKeyFile

Type: string
Usage Constraints: optional

The key for a TLS client certificate may be provided either in the same file as the certificate (specified with the Secure.ClientCertificateFile attribute), or it may be provided in a separate file specified with the Secure.ClientKeyFile attribute. Configure the Secure.ClientCertificateFile attribute only if both the certificate and the key are contained in the same file.

Secure.CheckPeerHostname

Type: boolean
Default and secure default: true

If enabled, among other validations, the DNS name will be checked against the CN/SAN of the certificate. Setting this parameter also requires setting the Secure.CACertificateFile.

Secure.CheckPeerHostname.AllowWildcards

Type: boolean
Default and secure default: false

If set to "true", the system will also accept certificates containing wildcards.

caution

For security reasons, we recommend setting this parameter to "false" in production.

Secure.SNISupport

Type: boolean
Default: true

Enables SNI support for this servlet. In case the backend has multiple name-based virtual servers configured with different certificates, the servlet can securely indicate, as part of the TLS handshake, to which one it intends to connect to. This indication happens at the beginning of the connection. It depends on the backend whether the indication is continuously checked.

Secure.CrlFile

Type: string
Usage Constraints: optional

Defines the path to a CRL file (PEM format). This path is automatically reloaded if the file is replaced by a newer one. The file modification check takes place in the time interval configured in the navajo.xml file (in the periodicity attribute of the Timer section).

Secure.Cache

Type: Enum
Possible Values: OFF, ON
Default: OFF

  • ON: saves the internal data of the TLS connection of the proxy and backend in the cache. The server then either agrees to reuse the session or it starts a full handshake to create a new session.
  • OFF: does not cache any SSL-connection data.

Secure.OpenSSLConfCmd

Type: newline-separated string of name/value pairs
Usage Constraints: optional, advanced

This parameter exposes OpenSSL's SSL_CONF API to the proxy, allowing a flexible configuration of OpenSSL parameters without the need to implement additional parameters when new features are added to OpenSSL.

For a list of supported command names, see the section Supported configuration file commands in the SSL_CONF_cmd(3) manual page for OpenSSL. Some of the Secure.OpenSSLConfCmd commands can be used as an alternative to existing parameters (such as Secure.CipherSuites or Secure.Protocol), although the syntax and the allowable values for the parameters may sometimes differ.

First consider if your goal can be achieved using the other parameters available. Contact support before using this parameter.

KeepAlive

Type: boolean
Default and secure default: true

Pools TCP connections for later reuse. If set to "false", the connection is closed after use, and a new TCP connection will be established for the next request.

Only enable this attribute if the web server supports the keep-alive feature in an acceptable range. If this is not the case, KeepAlive should be disabled.

KeepAlive.ConnectionPoolSize

Type: integer
Default: 100

This attribute is only evaluated if the attribute KeepAlive is set to "true".

This attribute defines the number of pooled TCP connections. A TCP connection is only put in the pool if it does not exceed the configured size.

DNSCache.ttl

Type: integer
Unit: seconds
Default: 86400 (1 day)

Specifies the time period in seconds to cache DNS info, before the system will retrieve the IP address again. The IP adress is set in the attribute InetAddress.

ConnectTimeout

Type: integer
Unit: milliseconds
Default: 10000 (10 sec)

Defines the timeout in milliseconds to open the TCP connection to the content provider.

  • Lower this timeout for fast recovery.
  • Raise this timeout if your server has networking problems and the proxy receives "connection refused" errors, even though the server is up, running, and responding to connect requests.

RequestTimeout

Type: integer
Unit: milliseconds
Default: 120000 (2 min)

Defines the TCP timeout in milliseconds for the reading of the response from the web server.

ResponseLineSize

Type: integer
Default: 4096

Defines the maximum allowed line size in the HTTP header of the response.

LoadBalanceMultipleIPs

Type: boolean
Default: false

If set to true, and the InetAddress DNS lookup matches more than one IP address, then a LoadBalancerServlet is used to load balance the request over the IP addresses.

LoadBalanceMultipleIPs.RetryTimeout

Type: integer
Default: 10

The parameter is only evaluated if LoadBalanceMultipleIPs is true.

The configured value is passed as parameter 'RetryTimeout' to the generated LoadBalancerServlet.

ForwardProxy

Type: string
Usage Constraints: optional
Syntax: <hostname>:<portnumber>

The attribute ForwardProxy specifies the INET address of the forward HTTP proxy to use. This feature requires the forward proxy and the backend to accept HTTP/1.1 connections.

ForwardProxy.Username

Type: string
Usage Constraints: optional

Username for the proxy authorization header. Must be configured if ForwardProxy.Password is set. Cannot contain :.

ForwardProxy.Password

Type: string
Usage Constraints: optional

Password for the proxy authorization header. Must be configured if ForwardProxy.Username is set.

URLEncoding

Type: Enum
Possible values: AUTO, ENABLE, DISABLE
Default: AUTO

  • If set to "ENABLE", this attribute encodes forbidden characters in the outgoing URI from nevisProxy to the back-end application. For example, the attribute changes the URI /UIFont CMSStyle.swift into /UIFont%20CMSStyle.swift.
  • If set to 'AUTO' it does or does not encode the forbidden characters depending on the value of the deprecated bc property 'org.apache.request.ParsedUri' and of the configured value of the parameter AllowEncodedSlashes.
  • If set to 'DISABLE', then it will not encode the forbidden characters.

ViaHeader

Type: boolean
Default: false

When set to true, it adds the proxy's host name to the via response header so that clients can detect whether the HTTP response came from the proxy or from the content provider.

EnableMetrics

Type: boolean
Usage Constraints: optional
Default: false

Controls the OpenTelemetry metrics generation of the servlet. If disabled, the servlet won't forward usage data as metrics.

Rewriting

For body and header rewriting the profiles RewriteResponseRequestUri and RewriteResponsePathInfo can be used, together with a LuaFilter. The profile to use depends on the URL you want to send to the backend.

If you want to send the same URL like the url from the frontend then you may have to use the profile RewriteResponseRequestUri. If you want to send the URL without the path where the servlet is mapped to, then the profile RewriteResponsePathInfo has to be used.

The profile RewriteResponseRequestUri

This profile may be needed if the configured BackendConnectorServlet should be called with exactly the same url like we got from the browser. As long as your backend doesn't send any URLs containing the hostname (f.ex. href="/the/path"), then no profile needs to be added. If there are URLs starting with the hostname (f.ex. href="https://my.host/the/path"), then this profile needs to be added.

The profile has to be used like this:

<filter>
<filter-name>MappingTypeRequestUriRewriteLuaFilter</filter-name>
<filter-class>ch::nevis::isiweb4::filter::lua::LuaFilter</filter-class>
<init-param>
<param-name>Profile</param-name>
<param-value>RewriteResponseRequestUri</param-value>
</init-param>
</filter>

and mapped directly to the BackendConnectorServlet. Here an example where the BackendConnectorServlet is called MyBackendConnector:

<filter-mapping>
<filter-name>MappingTypeRequestUriRewriteLuaFilter</filter-name>
<servlet-name>MyBackendConnector</servlet-name>
</filter-mapping>

The profile RewriteResponseRequestUri has the following parameters

If you expect compressed bodies from the backend you should map an InflateFilter between the LuaFilter and the backend:

<filter>
<filter-name>InflateFilter</filter-name>
<filter-class>ch::nevis::isiweb4::filter::inflate::InflateFilter</filter-class>
</filter>
...
<filter-mapping>
<filter-name>MappingTypeRequestUriRewriteLuaFilter</filter-name>
<servlet-name>MyBackendConnector</servlet-name>
</filter-mapping>
<filter-mapping>
<filter-name>InflateFilter</filter-name>
<servlet-name>MyBackendConnector</servlet-name>
</filter-mapping>

RewriteResponseRequestUri_ContentTypes

Type: string
Default:

text/html:html
application/xhtml:html
text/css:css
application/javascript:javascript
text/javascript:javascript
application/x%-javascript:javascript

Defines a new line separated list of strings with this syntax: <content-type>:<rule>

where:
<content-type>: the content-type as define in the Content-Type header <rule>: the rule to use. If it is set to html, then html rewriting will be done. For any other string, a parameter RewriteResponseRequestUri_Regex_<rule> has to be defined.

RewriteResponseRequestUriRegex<rule>

Type: string
Default:

RewriteResponseRequestUri_Regex_css=
(url%(%s*["']?)([^%)]*)(%s*%))
RewriteResponseRequestUri_Regex_javascript=
(Image%([^%0]*.*%.src%s*=%s*['"]?)([^;]*)([;]?)
(location%.href%s*=%s*['"]?)([^;]*)([;]?)
(document%.location%s*=%s*['"]?)([^;]*)([;]?)
(window%.open%s*%(%s*['"]?)([^%)]*)([%)]?)

For each <rule> configred in the parameter RewriteResponseRequestUri_ContentTypes a newline separated list of regex rules has to be configured. Each line has the following syntax:
(<regex for the prefix>)(<regex containing the URL>)(<regex for the postfix>)

Keep in mind that the regex have to be written using the LUA regex syntax.

The profile RewriteResponsePathInfo

This profile is needed if the configured BackendConnectorServlet should be called without the part of the URL on which the BackendConnectorServlet is mapped to. For example, if you have this mapping for a BackendConnectorServlet called MyBackendConnector:

<servlet-mapping>
<servlet-name>MyBackendConnector</servlet-name>
<url-pattern>/app/*</url-pattern>
</servlet-mapping>

and the frontend asks for this URL: /app/path/index.html, then the URL /path/index.html will be sent to the backend.

The profile has to be used like this:

<filter>
<filter-name>MappingTypePathInfoRewriteLuaFilter</filter-name>
<filter-class>ch::nevis::isiweb4::filter::lua::LuaFilter</filter-class>
<init-param>
<param-name>Profile</param-name>
<param-value>RewriteResponsePathInfo</param-value>
</init-param>
</filter>

and mapped directly to the BackendConnectorServlet. Here an example where the BackendConnectorServlet is called MyBackendConnector:

<filter-mapping>
<filter-name>MappingTypePathInfoRewriteLuaFilter</filter-name>
<servlet-name>MyBackendConnector</servlet-name>
</filter-mapping>

If you expect compressed bodies from the backend you should map an InflateFilter between the LuaFilter and the backend:

<filter>
<filter-name>InflateFilter</filter-name>
<filter-class>ch::nevis::isiweb4::filter::inflate::InflateFilter</filter-class>
</filter>
...
<filter-mapping>
<filter-name>MappingTypePathInfoRewriteLuaFilter</filter-name>
<servlet-name>MyBackendConnector</servlet-name>
</filter-mapping>
<filter-mapping>
<filter-name>InflateFilter</filter-name>
<servlet-name>MyBackendConnector</servlet-name>
</filter-mapping>

The profile RewriteResponsePathInfo has the following parameters

RewriteResponsePathInfo_ContentTypes

Type: string
Default:

text/html:html
application/xhtml:html
text/css:css
application/javascript:javascript
text/javascript:javascript
application/x%-javascript:javascript

Defines a new line separated list of strings with this syntax: <content-type>:<rule>

where:
<content-type>: the content-type as define in the Content-Type header <rule>: the rule to use. If it is set to html, then html rewriting will be done. For any other string, a parameter RewriteResponsePathInfo_Regex_<rule> has to be defined.

RewriteResponsePathInfoRegex<rule>

Type: string
Default:

RewriteResponsePathInfo_Regex_css=
(url%(%s*["']?)([^%)]*)(%s*%))
RewriteResponsePathInfo_Regex_javascript=
(Image%([^%0]*.*%.src%s*=%s*['"]?)([^;]*)([;]?)
(location%.href%s*=%s*['"]?)([^;]*)([;]?)
(document%.location%s*=%s*['"]?)([^;]*)([;]?)
(window%.open%s*%(%s*['"]?)([^%)]*)([%)]?)

For each <rule> configred in the parameter RewriteResponsePathInfo_ContentTypes a newline separated list of regex rules has to be configured. Each line has the following syntax:
(<regex for the prefix>)(<regex containing the URL>)(<regex for the postfix>)

Keep in mind that the regex have to be written using the LUA regex syntax.