Skip to main content

Reverse proxy configuration

Why use reverse proxy

Indicium

A reverse proxy is a server that accepts requests from a client, forwards them to another server, and returns the server response to the client. To the client, it seems like they are communicating directly with the reverse proxy server without knowing that the traffic is being forwarded to another server.

  • Horizontal scaling is one of the most common reasons for using a reverse proxy. When multiple instances of Indicium are deployed, a load balancer is required to distribute the load among these instances. A load balancer acts as a reverse proxy by receiving incoming requests, forwarding them to an instance of Indicium, and returning the response to the client.
  • For security reasons, a reverse proxy can safeguard your Indicium servers from direct internet traffic. A typical approach is to position a gateway at the outer edge of the network, accessible over the internet. Meanwhile, your Indicium servers remain inaccessible directly from the internet. This gateway, acting as a reverse proxy, forwards traffic to an Indicium server and returns the response. It is usual to incorporate a WAF (Web Application Firewall) on such a gateway. This WAF examines incoming traffic against various rules and blocks potentially harmful requests. Some WAFs can also detect and counter Denial of Service attacks.
  • For better performance, you can use TLS offloading. TLS ensures secure communication between a client and a server (i.e., https://). While TLS is necessary for security, it can slightly affect performance because incoming traffic needs to be decrypted. When the traffic volume increases, this decryption process can consume a noticeable amount of resources on the web server. A common strategy is to secure the external communication channel (i.e., client ← https → reverse proxy) and use an 'insecure' internal communication channel (i.e., reverse proxy ← http → Indicium). This allows Indicium to focus its resources on its main tasks while the client still benefits from secure communication.

It is common for a single reverse proxy to handle all the mentioned roles.

The X-Forwarded- headers mechanism

Indicium can be used in a reverse proxy setup by taking advantage of the X-Forwarded- headers mechanism.

These headers include:

  • X-Forwarded-For

    • Should contain the original IP address of the client that is making the request.

    This header is mostly used for logging purposes only and not really needed by Indicium itself. The presence of this header can however trigger a verification check to assert that a request was sent by a trusted reverse proxy server.

  • X-Forwarded-Host

    • Used to tell Indicium what the host name of Indicium is from the client's point of view.

    This header is needed to correctly generate things such as redirect urls.

  • X-Forwarded-Proto

    • Contains the protocol (HTTP/HTTPS) that was used in the original request.

    This header is needed, for example, in situations where the public facing server is configured to force https but Indicium itself is only setup to use http. The public facing proxy server would send this header with a value of https to the internal Indicium, which would then know that any public facing urls in responses must also use the https scheme.

Configure reverse proxy

To make an Indicium installation aware that it is going to be used in a reverse proxy setup, some settings must be added to the appsettings.json configuration file.

These settings must be added to a ReverseProxy section on the root level of the config file. The reverse proxy feature must also be explicitly enabled by setting Enabled to true:

{
"ReverseProxy": {
"Enabled": true
}
}

Debug tracing for reverse proxy

Debug tracing logs information to Indicium's log file. This can help you troubleshoot issues with reverse proxy settings. See Log files.

To activate debug tracing for reverse proxy, add the TracingEnabled property to the ReverseProxy settings in the appsettings.json file:

"ReverseProxy": {
"Enabled": true,
"TracingEnabled": true
}

Allowing headers

To specify which of the X-Forwarded-* headers are allowed to be consumed by Indicium change the AllowedHeaders section with the desired combination of the values below:

{
"ReverseProxy": {
"AllowedHeaders": [
"XForwardedHost",
"XForwardedProto",
"XForwardedFor",
"All"
]
}
}

The All value is a shortcut to allow all three headers.

By default only XForwardedFor and XForwardedProto are allowed.

Overriding header names

To override the header names that Indicium should listen to for X-Forwarded-* values use the CustomHeaders section:

{
"ReverseProxy": {
"CustomHeaders": {
"XForwardedHost": "CUSTOM-FORWARDED-HOST",
"XForwardedProto": "CUSTOM-FORWARDED-PROTO",
"XForwardedFor": "CUSTOM-FORWARDED-FOR"
}
}
}

Restrict X-Forwarded-Host values

To restrict which host domains are allowed as values in the X-Forwarded-Host header use the AllowedHosts section:

{
"ReverseProxy": {
"AllowedHosts": [
"www.example.com",
"*.example.com"
]
}
}

Host values are subject to the following rules:

  • Values are compared using ordinal-ignore-case.
  • Port numbers must be excluded.
  • If the list is empty, all hosts are allowed.
  • A top-level wildcard * allows all non-empty hosts.
  • Subdomain wildcards are permitted but don't match the root domain. For example, *.example.com matches the subdomain foo.example.com but not the root domain example.com.
  • Unicode host names are allowed but are converted to Punycode for matching.
  • IPv6 addresses must include bounding brackets and be in conventional form (for example, [ABCD:EF01:2345:6789:ABCD:EF01:2345:6789]). IPv6 addresses aren't special-cased to check for logical equality between different formats, and no canonicalization is performed.

Failing to restrict the allowed hosts may allow an attacker to spoof links generated by the service.

By default all hosts are allowed.

Specify trusted proxies

By default Indicium only accepts X-Forwarded-For header values from proxies running on the same server. To grant other servers access specify their IP address in the KnownProxies section:

{
"ReverseProxy": {
"KnownProxies": [
"10.60.0.185"
]
}
}

Specify trusted networks

In addition to trusting proxies by specific IP it is also possible to grant multiple servers access by specifying network ranges using CIDR notation in the KnownNetworks section:

{
"ReverseProxy": {
"KnownNetworks": [
"10.60.0.0/16"
]
}
}

The above states a network IP 10.60.0.0 with a mask of 255.255.0.0. This would allow servers in the IP range 10.60.0.1 - 10.60.255.254 to send X-Forwarded-For headers.

Changing the path base of Indicium

Assume for a moment that there is an Indicium running on a server named internalserver. In addition to that there is a external facing proxy server named revproxy.

The revproxy server is configured to accept https requests on port 443 for domain www.example.com. It sends the requests it receives to the Indicium running on an IIS server at internalserver.example.com/indicium.

Because Indicium is running in the virtual app domain /indicium any requests that generate redirects or paths to static images etc. will be returned to the client as www.example.com/indicium/<request remainder>.

Since the reverse proxy acting as www.example.com is rerouting anything after the main domain to internalserver.example.com/indicium the actual request to the Indicium server becomes internalserver.example.com/indicium/indicium/<request remainder>.

This breaks a lot of things, including logging in via /account/ui/login.

To fix this issue, specify the path base according to the externally facing server using the ExternalPathBase option:

{
"ReverseProxy": {
"ExternalPathBase": "/"
}
}

When Indicium receives a request and detects that the host was changed using the X-Forwarded-Host header, it will also change the path base of the request to what was specified in ExternalPathBase.

In the above example internal requests that are made directly to the Indicium server will continue to use /indicium as the path base since those should not be sending the X-Forwarded-Host header.

Because the revproxy server running for www.example.com should send this header (to change the host back to www.example.com from internalserver.example.com), the path base is changed to / which fixes the url responses that the Indicium server generates since it now assumes that it is running on the server root.

Configuring IIS as a reverse proxy

To use IIS as a reverse proxy the following modules must be installed on the server:

X-Forwarded-For

To configure IIS to send the X-Forwarded-For header when Application Request Routing is triggered go to Application Request Routing Cache -> Server Proxy Settings from the main server menu.

In this screen there is a Custom Headers section with a field called Preserve client IP in the following header.

Set the value of this field to X-Forwarded-For (Note: it might already be configured this way after installing ARR).

ARR proxy settings

X-Forwarded-Host/Proto

Pick or add a site to use as the reverse proxy.

In this example a new site was added that was bound to use http on port 10100.

create website

Go to the URL Rewrite section of the site and click on View Server Variables:

go to server variables

In this screen one can specify which variables to use when a rewrite rule has been triggered. To whitelist the X-Forwarded-Host/Proto headers add the following variables as needed:

  • HTTP_X_FORWARDED_HOST
  • HTTP_X_FORWARDED_PROTO

In this case only X-Forwarded-Host was needed so HTTP_X_FORWARDED_HOST has been added as a server variable:

add server variables

Go back to the URL Rewrite section and start adding a reverse proxy rule:

add reverse proxy rule

Configure the Inbound Rules section to point to your internal server running Indicium. This values should contain the domain, port and virtual host path as needed but leave out the protocol.

In this example the domain is internalserver.yourdomain.com, the port is 8888 and Indicium itself is running on a virtual host application path called indicium.

configure reverse proxy rule

Once the rule has been added double click on it to start editing it once more.

edit inbound rule

Configure the rule to use the HTTP_X_FORWARDED server variables that were added earlier. This example only adds HTTP_X_FORWARDED_HOST and sets it to {HTTP_HOST} which will pass on the original host to the Indicium application.

set server variable

Another common example would be when the reverse proxy is secured by https but all internal trafic is off loaded to http (e.g. when the SSL offloading option is checked in IIS). In that case the Indicium server should be notified of this by adding the X-Forwarded-Proto header. This would mean that the HTTP_X_FORWARDED_PROTO variable must be added as a server variable and set to https on the inbound rule section of the rewrite rule.

Internet proxy

In some cases, Indicium requires internet access. Reasons can be, for example, automatic license renewal or a process flow in your application that uses an HTTP Connector.

If your network requires a proxy server, you can tell Indicium in various ways which proxy to use:

  • One way is to add the following section to Indicium's web.config.

When upgrading Indicium, make sure the web.config is manually updated, or the changes will be undone.

<aspNetCore processPath="dotnet" arguments=".\Indicium.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false" hostingModel="InProcess">
<environmentVariables>
<environmentVariable name="ALL_PROXY " value="https://username:password@serverproxy.corp.com:80" />
</environmentVariables>
</aspNetCore>
  • Another option is to add an environment variable to the system. The easiest way is to use the Windows Search and search for: "Edit the system environment variables". Then, open the Advanced tab and click the Environment variables button. Here, you can add the environment variables for the proxy. Use "ALL_PROXY" as a name. The required Value is the proxy server address.

    You can also set a separate proxy for HTTP or HTTPS. In that case, uses the following names:

    • HTTP_PROXY: Proxy server used for HTTP requests.
    • HTTPS_PROXY: Proxy server used for HTTPS requests.
    • ALL_PROXY: Proxy server used for both HTTP and HTTPS.
    • NO_PROXY: a comma-separated list of hostnames that do not require a proxy.

internet proxy New system variable


Was this article helpful?