Sometimes I have to configure sites that are no actually in my control, I only host and administer them. But site development/update is done by somebody else. Or it could be a PHP (yuck!) hosted on IIS.

Today I had to enable a bunch of sites to be served over HTTPS, all these sites sit under one IP, but under different subdomains. Unfortunately IIS does not have ability to configure from UI host header for HTTPS connections. So you have to drop down to command line:

appcmd set site /site.name:"<SiteName>" /+bindings.[protocol='https',bindingInformation='*:443:subdomain.domain.com']

And then in web.config add redirection to HTTPS, but make sure URL Rewrite is installed on server (check if %SystemRoot%\system32\inetsrv\rewrite.dll file is present):

<configuration>
    <system.webServer>
        <rewrite>
            <rules>
                <clear />
                <rule name="Redirect to https" stopProcessing="true">
                    <match url="(.*)" />
                    <conditions>
                        <add input="{HTTPS}" pattern="off" ignoreCase="true" />
                    </conditions>
                    <action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" redirectType="Permanent" appendQueryString="false" />
                </rule>
            </rules>
        </rewrite>
    </system.webServer>
</configuration>

And add STS header to all the requests:

<configuration>
    <system.webServer>
        <httpProtocol>
          <customHeaders>
            <remove name="X-Powered-By"/>
            <add name="Strict-Transport-Security" value="max-age=31536000"/>
          </customHeaders>
        </httpProtocol>
    </system.webServer>
</configuration>

Just writing down the steps for myself, so I don’t have to search this stuff over again in 6 months time.

I remember I had to fix this issue about a year ago. And I completely forgotten how to do this. And the same problem strikes again.

The issue was with a web-site (MVC5, 4.5.1 .Net) running on IIS. And I had an issue when trying to get data from SQL Server.
The connection did not go through whatever I did.

The fix was quite simple. All I needed to do is to change the AppPool underlying user to be “NetworkService” instead of “ApplicationPoolIdentity”:

  1. In IIS, in list of Application Pools find the one which works with your site.
  2. In Advanced Settings (link on right) for that AppPool find Section Process Model and Identity setting first
  3. Change Identity to be NetworkService
  4. Restart AppPool and the web-site.

This is possibly one of the reasons that can cause the issue. There is a million of other reasons this can happen, but I have checked most of them before started semi-randomly poking about with app pools and IIS settings.

There is an opinion in the online community that HTTP Headers in your application must not be giving out information about your site. But in every StackOverflow question about removing headers, there always will be someone saying “why bother?”. Well.. don’t bother if you don’t want to. You are quite right, there are ways to detect what server and technologies are used to serve the site. But I do not know any of these techniques, so I’ll keep removing headers from my applications.

Also it seemes that IIS insists on providing Server header with every request and there is no way to remove it via web.config. To get rid of this header I have seen people going out of their way with HTTP Modules and UrlScan. But in MVC4 (not sure about version 3 – never tried it there) and IIS 7.5 you can easily do that in you Glabal.asax.cs file.

In the application request life-cycle there is EndRequest() event that can do what we want:

    protected void Application_EndRequest()
    {
        // removing excessive headers. They don't need to see this.
        Response.Headers.Remove("Server");
    }

Much the same way you can remove any other header from the reply: X-Powered-By, X-AspNetMvc-Version and etc. But for these there are legit ways to do that through web.config.

Many times you need to give permissions to modify files for web-sites running on IIS.
If you are using the Application Pools identity, you’ll have to use the following usernames:
Set the domain as the local machine. For user type IIS AppPool\DefaultAppPool or IIS AppPool\<AppPoolName>.

Source: http://www.iis.net/learn/manage/configuring-security/application-pool-identities

The problem I faced with with Drupal installation – I could not give right permissions to the upload folder to store files as required.
I had the solution for IIS6, but IIS7 have different user set-up, so new solution was required.
After some fiddling about, I stumbled across this solution:

  1. Create a normal Windows user for your Drupal install. Create a password too.
  2. Create an application pool for your Drupal install. Set the application pool’s identity to your windows user: in IIS7 double click the new application pool and then Advanced Settings -> Process Model -> Identity
  3. Set your website to use that application pool
  4. In web-site go to Authentication -> Anonymous Authentication -> Edit -> Set to Application pool identity:
  5. Give (or deny) the Windows user full control to the sites\default directory

So, what all this does is give the Drupal install privilege isolation. It can only write files in the sites\default directory, but not your settings.php. It can still create needed cache file, uploads, etc.