Skip to content

Fortified IDDocs

IIS with ARR and URL Rewrite

This configuration makes IIS on Windows Server 2025 act as a secure reverse proxy in front of several internal HTTPS services running on different localhost ports.

It solves these problems:

  • It exposes multiple backend applications through one public IIS site on standard HTTPS port 443, instead of requiring users to access 8443, 8450, 8446 or 8445 directly.
  • It routes requests by path, so /access, /saml, /oidc , /forms , /pwdreset and /portal each go to the correct internal service. Requests to / will be routed to /portal.
  • It preserves the original public host header, which many applications need for URL generation, redirects, SAML, cookies, and validation logic.
  • It adds X-Forwarded-Proto: https and X-Forwarded-Port: 443, so backend apps know the original client connection was HTTPS on the public endpoint, even though IIS is proxying the request internally.
  • It allows IIS/ARR to connect to backend HTTPS services even if those internal certificates are self-signed, expired, or have hostname mismatches.

In practical terms, this is useful when you want users to access one external URL such as https://yourserver/access while the real applications stay bound internally to https://localhost:8443, https://localhost:8450, and https://localhost:8445.

The main issue it solves is publishing internal web apps securely behind a single IIS entry point without changing the applications to listen directly on the public interface.

Windows 2025 with Admin privileges

  • IIS
  • URL Rewrite
  • Application Request Routing (ARR)

Official downloads:

In IIS Manager:

  • Select the server
  • Open Application Request Routing Cache
  • Click Server Proxy Settings
  • Check Enable proxy

Run as Administrator:

%windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/proxy /preserveHostHeader:"True" /commit:apphost

Add X-Forwarded-Proto and X-Forwarded-Port

Section titled “Add X-Forwarded-Proto and X-Forwarded-Port”

In IIS, on the site used (such as Default Web Site):

  • Open URL Rewrite
  • Click View Server Variables...
  • Add:
    • HTTP_X_FORWARDED_PROTO
    • HTTP_X_FORWARDED_PORT
  • Create web.config for the site used (C:\inetpub\wwwroot for Default Web Site) with this content:
<configuration>
<system.webServer>
<caching enabled="false" enableKernelCache="false" />
<urlCompression doStaticCompression="false" doDynamicCompression="false" />
<rewrite>
<rules>
<rule name="Proxy access" stopProcessing="true">
<match url="^access(/.*)?$" />
<serverVariables>
<set name="HTTP_X_FORWARDED_PROTO" value="https" />
<set name="HTTP_X_FORWARDED_PORT" value="443" />
</serverVariables>
<action type="Rewrite" url="https://127.0.0.1:8443/{R:0}" />
</rule>
<rule name="Proxy saml" stopProcessing="true">
<match url="^saml(/.*)?$" />
<serverVariables>
<set name="HTTP_X_FORWARDED_PROTO" value="https" />
<set name="HTTP_X_FORWARDED_PORT" value="443" />
</serverVariables>
<action type="Rewrite" url="https://127.0.0.1:8443/{R:0}" />
</rule>
<rule name="Proxy oidc" stopProcessing="true">
<match url="^oidc(/.*)?$" />
<serverVariables>
<set name="HTTP_X_FORWARDED_PROTO" value="https" />
<set name="HTTP_X_FORWARDED_PORT" value="443" />
</serverVariables>
<action type="Rewrite" url="https://127.0.0.1:8443/{R:0}" />
</rule>
<rule name="Proxy forms" stopProcessing="true">
<match url="^forms(/.*)?$" />
<serverVariables>
<set name="HTTP_X_FORWARDED_PROTO" value="https" />
<set name="HTTP_X_FORWARDED_PORT" value="443" />
</serverVariables>
<action type="Rewrite" url="https://127.0.0.1:8450/{R:0}" />
</rule>
<rule name="Proxy portal" stopProcessing="true">
<match url="^portal(/.*)?$" />
<serverVariables>
<set name="HTTP_X_FORWARDED_PROTO" value="https" />
<set name="HTTP_X_FORWARDED_PORT" value="443" />
</serverVariables>
<action type="Rewrite" url="https://127.0.0.1:8445/{R:0}" />
</rule>
<rule name="Proxy pwdreset" stopProcessing="true">
<match url="^pwdreset(/.*)?$" />
<serverVariables>
<set name="HTTP_X_FORWARDED_PROTO" value="https" />
<set name="HTTP_X_FORWARDED_PORT" value="443" />
</serverVariables>
<action type="Rewrite" url="https://127.0.0.1:8446/{R:0}" />
</rule>
<rule name="Proxy root" stopProcessing="true">
<match url=".*" />
<serverVariables>
<set name="HTTP_X_FORWARDED_PROTO" value="https" />
<set name="HTTP_X_FORWARDED_PORT" value="443" />
</serverVariables>
<action type="Rewrite" url="https://127.0.0.1:8445/{R:0}" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>

Disable reverseRewriteHostInResponseHeaders

Section titled “Disable reverseRewriteHostInResponseHeaders”

In IIS Manager:

  1. Go to server node
  2. Open Configuration Editor
  3. Navigate to: system.webServer/proxy
  4. Set reverseRewriteHostInResponseHeaders = False

OPTIONAL - Disable SSL validation against the backend

Section titled “OPTIONAL - Disable SSL validation against the backend”

If you want IIS to ignore CN/name mismatch, expired certificates, and unknown CA errors, run this as Administrator:

reg add "HKLM\SOFTWARE\Microsoft\IIS Extensions\Application Request Routing\Parameters" /v SecureConnectionIgnoreFlags /t REG_DWORD /d 13056 /f

Issue iisreset as administrator in order to restart the IIS.

iisreset

Go to one of the url patterns previously configured and verify the service is reachable

Example: https://servername.company.org/portal