﻿# 如何在 Linux 正確建立自簽憑證並讓 ASP.NET Core 網站可以順利進行連線

我最近漸漸的嘗試將各種前後端開發環境搬遷到 Linux 環境下，無論是在 WSL 或是原生的 Linux 的效能表現都比 Windows 來的出色。然而在微服務架構下，服務與服務間的通訊經常需要使用 TLS/SSL 憑證進行加密連線，但是自簽憑證在 Linux 底下預設是不受信任的，必須特別處理才能解決服務間的安全連線的信任問題。這篇文章我將說明這個過程與解決方法。

### 產生自簽憑證並註冊到 Linux 作業系統

1.  安裝 [mkcert](https://github.com/FiloSottile/mkcert) 工具
    
    我現在自簽憑證不太用 OpenSSL 了，因為 [mkcert](https://github.com/FiloSottile/mkcert) 實在太香、太好用了！👍
    
    ```bash
    mkdir -p ~/.local/bin
    curl -sSL https://github.com/FiloSottile/mkcert/releases/download/v1.4.4/mkcert-v1.4.4-linux-amd64 -o ~/.local/bin/mkcert
    chmod 755 ~/.local/bin/mkcert
    
    . ~/.profile
    ```
    
2.  將 mkcert 產生的 Root CA 憑證加入到 system trust store
    
    ```bash
    mkcert -install
    ```
    
    這個命令會自動 `sudo` 並執行更新系統信任的憑證儲存區(system trust store)，這個 `mkcert -install` 命令等同於以下兩行指令：
    
    ```bash
    sudo cp ~/.local/share/mkcert/rootCA.pem /usr/local/share/ca-certificates/
    sudo update-ca-certificates
    ```
    

### 產生 TLS 憑證並設定 ASP.NET Core 的 Kestrel 使用指定憑證

1.  建立 ASP.NET Core Web API 專案
    
    ```bash
    mkdir myapi; cd myapi; dotnet new webapi --exclude-launch-settings
    dotnet run
    ```
    
    使用 cURL 連接 HTTPS 端點
    
    ```bash
    curl https://localhost:5001/weatherforecast
    ```
    
    此時會直接顯示以下錯誤，這是因為 .NET CLI 產生的自簽憑證沒有受信任的關係：
    
    ```
    curl: (60) SSL certificate problem: unable to get local issuer certificate
    More details here: https://curl.haxx.se/docs/sslcerts.html
    
    curl failed to verify the legitimacy of the server and therefore could not
    establish a secure connection to it. To learn more about this situation and
    how to fix it, please visit the web page mentioned above.
    ```
    
2.  使用 `mkcert` 產生 PKCS#12 憑證: `localhost.pfx`
    
    以下設定 `localhost` 與 `127.0.0.1` 為 TLS/SSL 憑證的 SAN (Subject Alternative Name)，並儲存成 `localhost.pfx` 檔案！
    
    ```bash
    mkcert -pkcs12 -p12-file localhost.pfx localhost 127.0.0.1
    ```
    
    > 使用 `mkcert` 建立的 PKCS#12 憑證密碼寫死為 `changeit` 而且不能指定其他密碼！
    
3.  調整 ASP.NET Core 的 `appsettings.json` 設定檔
    
    ```json
    {
      "Kestrel": {
        "Certificates": {
          "Default": {
            "Path": "localhost.pfx",
            "Password": "changeit"
          }
        }
      },
      "Logging": {
        "LogLevel": {
          "Default": "Information",
          "Microsoft.AspNetCore": "Warning"
        }
      },
      "AllowedHosts": "*"
    }
    ```
    
4.  啟動 ASP.NET Core 的 Kestrel 開發伺服器
    
    ```bash
    dotnet run
    ```
    
5.  使用 cURL 測試網站連線
    
    ```bash
    curl https://localhost:5001/weatherforecast
    ```
    
    此時應該就不會再出現任何錯誤了！ 👍
    

### 相關連結

-   [FiloSottile/mkcert: A simple zero-config tool to make locally trusted development certificates with any names you'd like.](https://github.com/FiloSottile/mkcert)
-   [Certificate is invalid exception on Linux](https://github.com/dotnet/tye/blob/main/docs/tutorials/hello-tye/00_run_locally.md#certificate-is-invalid-exception-on-linux)
