When you use iisnode to host the Node.js blogging software Ghost on your IIS web server, and you set up an SSL certificate for your Ghost website, you may run into "too many redirects" issues when changing Ghost's config.js file. This happened to me, and here is the solution.
IIS acts as a reverse proxy for Node.js through iisnode, so Ghost itself only sees plain HTTP on localhost and keeps redirecting to HTTPS. Set enableXFF="true" on the iisnode element in web.config (or in iisnode.yml) and recycle the application pool.
I originally wrote this post in 2016 for Ghost 0.x hosted on IIS with iisnode. Ghost's config.js has since been replaced by JSON configuration files, but the reverse proxy principle still applies to any Node.js app behind IIS.
IIS acts as a reverse proxy for Node.js
The most important thing I forgot is that IIS acts as a reverse proxy for Node.js web applications when you install iisnode. I had my SSL certificate set up in IIS, put my HTTP to HTTPS redirect in place, and updated my Ghost url: and server: production environment config in config.js: I changed http to https.
Assuming all was correct and in place, I recycled my application pool, which is necessary for Ghost config changes, and refreshed my browser. Only to find an error HTTP 310 Too many redirects... Darn!
Here is how to resolve the "too many redirects" error in Ghost on IIS
TL;DR: read Ghost on Azure - (310) too many redirects with https problem solved to find the answer.
Undoing my config.js changes, the problem went away. Googling the "HTTP 310 Too many redirects" error, I found the above mentioned blog post, and all pieces fell into place:
IIS acts as a reverse proxy through iisnode for the Node.js web applications. Node.js runs its own HTTP web server on localhost. Doh! How could I forget... Anyway, create an iisnode.yml file in your web root (or edit the file if it exists), and add (or change):
enableXFF: true
From the iisnode configuration documentation:
The enableXFF setting controls whether iisnode adds or modifies the X-Forwarded-For request HTTP header with the IP address of the remote host.
After recycling your application pool, Ghost runs on HTTPS / port 443 in Node.js without problems. You can find more iisnode configuration settings in iisnode's sample web.config.
This means you don't have to create an iisnode.yml file if it doesn't exist. You can make your change in the web.config file instead:
<iisnode
node_env="%node_env%"
loggingEnabled="false"
debuggingEnabled="false"
devErrorsEnabled="false"
nodeProcessCommandLine=""c:\path\to\node.exe""
enableXFF="true"
/>
Once HTTPS works, take the next step and enable HTTP Strict Transport Security (HSTS) on IIS. Moving from WordPress? Read how I tried to export and migrate WordPress to Ghost.