# 如何設定 ASP.NET Core 在發行到 IIS 時移除 X-Powered-By 標頭

最近我們公司有一個新的網站即將上線，在做資安檢核的時候發現網站有回應一個 `X-Powered-By` 標頭，一般來說我們都會透過修改 `Web.config` 的方式移除這個標頭，但我希望這個動作可以在 CI/CD 的時候自動完成，而不是每次都手動調整 `Web.config` 設定檔。我之前在 [如何透過 dotnet publish 調整 ASP․NET Core 部署到 IIS 的 Web.config 內容](/post/2023/03/30/How-to-set-environment-name-for-webconfig-when-run-dotnet-publish) 文章中已經介紹了許多 ASP.NET Core 發行到 IIS 的設定技巧，今天我想來做出一點補充，讓我們可以在透過 `dotnet publish` 發行網站時調整 `Web.config` 的任意設定內容。

![image](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/df60ab3db6701bf7c886-0e4f60ed-e448-482e-b768-c16370acb094.webp)

### 移除 X-Powered-By 標頭的 Web.config 設定

首先，我先來看一下一個 ASP.NET Core 發行後的 `Web.config` 檔案加上移除 `X-Powered-By` 標頭的設定內容，如下：

```xml
<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <system.webServer>

        <httpProtocol>
            <customHeaders>
                <remove name="X-Powered-By" />
            </customHeaders>
        </httpProtocol>

    </system.webServer>
</configuration>
```

這裡的重點就是 `<system.webServer>` 底下的 `<httpProtocol>` 區段設定！

### 移除 Server 標頭的 Web.config 設定

若要完整移除 `Server` 標頭，則需要在 `<security>` 區段中加上 `<requestFiltering removeServerHeader="true" />` 設定，如下：

```xml
<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <system.webServer>

        <security>
            <requestFiltering removeServerHeader="true" />
        </security>

    </system.webServer>
</configuration>
```

這裡的重點就是 `<system.webServer>` 底下的 `<security>` 區段設定！

### 設定 dotnet publish 發行網站時自動調整 Web.config

這裡我們會用到一個古老的 [Web.config Transformations](https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/iis/transform-webconfig?view=aspnetcore-6.0&WT.mc_id=DT-MVP-4015686#build-configuration) 技巧，這個技巧從以前的 .NET Framework 延續到 ASP.NET Core 都還能使用，所以只要你會寫 Transformations 的語法，就可以很容易的達成 Web.config 內容轉換的目的。

這個設定很簡單，你只要準備一個 `web.{CONFIGURATION}.config` 檔案即可，其他什麼都不用設定！

> 這裡的 `{CONFIGURATION}` 是一個代表「發行組態」的變數，可以是 `Debug` 或 `Release` 或其他你自己定義的組態名稱。

我們在發行時都會用 `Release` 組態，所以我們只要準備一個 `web.Release.config` 檔案即可，內容如下：

```xml
<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
    <location>
        <system.webServer>
            <security xdt:Transform="InsertIfMissing">
                <requestFiltering removeServerHeader="true" />
            </security>
            <httpProtocol xdt:Transform="InsertIfMissing">
                <customHeaders>
                    <remove name="X-Powered-By" />
                </customHeaders>
            </httpProtocol>
        </system.webServer>
    </location>
</configuration>
```

就這樣，其他什麼都不用改，你在執行 `dotnet publish` 時，只要特別指定 `-c Release`，就會在發行過程中自動調整 `Web.config` 的內容了！

```bash
dotnet publish -c Release
```

發行成功後的內容如下：

```xml
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <location path="." inheritInChildApplications="false">
    <system.webServer>
      <handlers>
        <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
      </handlers>
      <aspNetCore processPath="dotnet" arguments=".\mvc1.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="inprocess" />
      <security>
          <requestFiltering removeServerHeader="true" />
      </security>
      <httpProtocol>
        <customHeaders>
          <remove name="X-Powered-By"/>
        </customHeaders>
      </httpProtocol>
    </system.webServer>
  </location>
</configuration>
```

### 發行時排除特定檔案

雖然上述設定很簡單的就可以達成目標，但是發行後的資料夾中會多出一個 `web.Release.config` 檔案，這個檔案其實是沒有用的，所以我們可以在發行時排除這個檔案。

如果你不想要 `web.Release.config` 檔案出現在發行的結果中，你可以在 `*.csproj` 檔案中加上以下排除發行的設定：

```xml
<ItemGroup>
  <Content Update="web.Release.config" CopyToPublishDirectory="Never" />
</ItemGroup>
```

> 這裡的 `CopyToPublishDirectory="Never"` 設定是指不要複製該檔案到發行目錄中。

### 相關連結

-   [Transform web.config | Microsoft Learn](https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/iis/transform-webconfig?view=aspnetcore-6.0&WT.mc_id=DT-MVP-4015686#build-configuration)
-   [c# - Remove HTTP server and X-Powered-By headers - Stack Overflow](https://stackoverflow.com/a/66020744/910074)
-   [web config - Remove "Server" header from ASP.NET Core 2.1 application - Stack Overflow](https://stackoverflow.com/a/55520636/910074)
