How to Set Up a Reverse Proxy with IIS ARR on Windows Server 2025
A reverse proxy sits between clients and one or more backend servers, forwarding requests transparently. In a Windows Server 2025 environment, IIS with Application Request Routing (ARR) is the native solution for reverse proxying, offering deep integration with IIS features like URL Rewrite, SSL termination, compression, logging, and custom headers. ARR is used in two distinct modes: as a simple reverse proxy that forwards all or selective traffic to a single backend, and as a load balancer that distributes traffic across a server farm. This guide focuses on the reverse proxy use case — routing specific URL paths to backend services, handling SSL termination at the IIS layer, configuring timeouts, and managing multi-backend routing with URL Rewrite conditions. A comparison with nginx as an alternative is also provided to help you make the right choice for your environment.
Prerequisites
- Windows Server 2025 with IIS installed (Web Server role via Server Manager)
- Administrative access to IIS Manager and the server
- ARR 3.0 module installed (download from IIS.net or via Microsoft Web Platform Installer)
- URL Rewrite 2.1 module installed (available from the same source — required by ARR)
- One or more backend servers or processes listening on known ports (e.g., Node.js on :3000, a Flask app on :8000)
- An SSL certificate if you plan to terminate HTTPS at IIS
Step 1: Install ARR and URL Rewrite
ARR and URL Rewrite are not included in the default IIS installation. Download both from the IIS.net website or use the Web Platform Installer (WebPI):
# Using Web Platform Installer from command line (if WebPI is installed)
webpicmd /Install /Products:"ARR" /AcceptEULA
webpicmd /Install /Products:"UrlRewrite2" /AcceptEULA
Alternatively, download the MSI installers directly:
- ARR 3.0:
https://www.iis.net/downloads/microsoft/application-request-routing - URL Rewrite 2.1:
https://www.iis.net/downloads/microsoft/url-rewrite
After installation, verify both modules appear in IIS Manager. Click the server root node in IIS Manager — you should see Application Request Routing Cache and URL Rewrite icons in the Features view.
Step 2: Enable the Proxy Feature in ARR
ARR’s proxy mode must be explicitly enabled at the server level before any rules will function:
- In IIS Manager, click the server root node (top of the tree)
- Double-click Application Request Routing Cache
- In the right-hand Actions pane, click Server Proxy Settings
- Check Enable proxy
- Click Apply
This single setting enables the proxy engine globally. Without it, URL Rewrite rules that reference backend servers will fail silently.
Step 3: Configure a Basic Reverse Proxy Rule
Create a new IIS site (or use an existing one), then add a web.config file in the site root with a URL Rewrite rule to proxy all traffic to a backend service:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="ReverseProxy-All" stopProcessing="true">
<match url="(.*)" />
<action type="Rewrite"
url="http://localhost:3000/{R:1}"
appendQueryString="true" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
This rule captures everything after the domain and forwards it to a backend running on port 3000 on the same machine. The {R:1} back-reference preserves the request path.
Step 4: Route Specific Paths to Different Backends
A common architecture routes /api/* requests to one backend (e.g., a Node.js API) while serving everything else from a static site or different application. Use URL Rewrite conditions to implement path-based routing:
<configuration>
<system.webServer>
<rewrite>
<rules>
<!-- Route /api/ requests to Node.js backend -->
<rule name="Proxy-API" stopProcessing="true">
<match url="^api/(.*)" />
<action type="Rewrite"
url="http://localhost:3000/api/{R:1}"
appendQueryString="true" />
</rule>
<!-- Route /app/ requests to Python Flask backend -->
<rule name="Proxy-Flask" stopProcessing="true">
<match url="^app/(.*)" />
<action type="Rewrite"
url="http://localhost:8000/{R:1}"
appendQueryString="true" />
</rule>
<!-- All other traffic served by IIS directly (static files) -->
</rules>
</rewrite>
</system.webServer>
</configuration>
Step 5: Preserve the Host Header and Handle Forwarded Headers
By default, ARR rewrites the Host header to match the backend address. Backend applications that inspect the Host header (for virtual host routing or CSRF validation) will receive the wrong value. Fix this by preserving the original host and adding standard forwarded headers:
<system.webServer>
<rewrite>
<rules>
<rule name="ReverseProxy" stopProcessing="true">
<match url="(.*)" />
<serverVariables>
<set name="HTTP_X_FORWARDED_FOR" value="{REMOTE_ADDR}" />
<set name="HTTP_X_FORWARDED_PROTO" value="https" />
<set name="HTTP_X_FORWARDED_HOST" value="{HTTP_HOST}" />
</serverVariables>
<action type="Rewrite"
url="http://localhost:3000/{R:1}"
appendQueryString="true" />
</rule>
</rules>
</rewrite>
</system.webServer>
To allow server variable overrides in URL Rewrite rules, you must whitelist the variables at the IIS level. Open IIS Manager → URL Rewrite at the server root → View Server Variables → Add each variable name (HTTP_X_FORWARDED_FOR, HTTP_X_FORWARDED_PROTO, HTTP_X_FORWARDED_HOST).
Step 6: SSL Termination at ARR
Terminate SSL at IIS and communicate with backends over plain HTTP on the loopback interface. Bind an SSL certificate to the IIS site:
- In IIS Manager, select your site → Bindings → Add
- Type: https, Port: 443, SSL certificate: select from the store
- Click OK
Force HTTP to HTTPS with a redirect rule before the proxy rule:
<rule name="HTTP to HTTPS Redirect" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="^OFF$" />
</conditions>
<action type="Redirect"
url="https://{HTTP_HOST}/{R:1}"
redirectType="Permanent" />
</rule>
Step 7: Configure Timeout and Retry Settings
For backends with longer response times (reports, data exports, slow queries), increase ARR’s timeout values:
# In IIS Manager: Application Request Routing Cache → Server Proxy Settings
# Or configure via appcmd:
%windir%system32inetsrvappcmd.exe set config -section:system.webServer/proxy /timeout:"00:05:00" /commit:apphost
# Set response buffer size for large backend responses (in KB)
%windir%system32inetsrvappcmd.exe set config -section:system.webServer/proxy /responseBufferThreshold:0 /commit:apphost
The default ARR timeout is 2 minutes. Set it to match the longest expected backend response time plus a margin.
Step 8: ARR vs. Nginx as a Reverse Proxy on Windows
Both ARR and nginx can serve as reverse proxies on Windows Server 2025. The choice depends on your requirements:
- ARR: Native IIS integration, managed via GUI, supports Windows authentication pass-through, integrates with IIS logging and certificates, built-in load balancing UI, Windows service management. Best choice when the rest of your stack is IIS-based.
- Nginx (Windows port): Lighter resource footprint for pure proxy workloads, familiar configuration syntax for Linux teams, better documented for advanced upstream patterns, active open-source community. The Windows build is not officially supported by Nginx Inc. for production use and lacks some features available on Linux.
- For most Windows Server 2025 deployments with an existing IIS infrastructure, ARR is the correct choice. For new greenfield deployments where the team has strong Linux experience, consider running nginx in a Windows container or migrating to a Linux host.
Conclusion
IIS ARR provides a powerful, natively integrated reverse proxy solution for Windows Server 2025. With URL Rewrite rules you can route traffic to multiple backend services based on URL path, query string, or any request header, while preserving forwarded headers and terminating SSL at the IIS boundary. The configuration shown in this guide covers the majority of real-world reverse proxy scenarios — from single-backend proxying to multi-service path-based routing with HTTPS enforcement. Monitor proxy performance in IIS logs and use the ARR Cache dashboard in IIS Manager to observe upstream response times and error rates.