設置 Ubuntu
安裝 .NET Core Runtime
1
2
3
4
5
|
wget https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
sudo apt update
sudo apt install apt-transport-https
sudo apt install dotnet-runtime-3.1
|
安裝 Nginx
新增套件來源,新增檔案 /etc/apt/sources.list.d/nginx.list
1
2
3
|
#/etc/apt/sources.list.d/nginx.list.
deb https://nginx.org/packages/ubuntu/ focal nginx
deb-src https://nginx.org/packages/ubuntu/ focal nginx
|
安裝
1
2
|
sudo apt update
sudo apt install nginx -y
|
啟動、設定開機啟動
1
2
3
4
5
6
|
# 啟動 nginx
sudo systemctl start nginx
# 設置 nginx 開機啟動
sudo systemctl enable nginx
# 確認 nginx 運行狀態
sudo systemctl status nginx
|
設置 Nginx 反向代理本機的 5000 連接埠(之後 Kestrel 的 http 服務端口)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
server {
listen 80;
server_name example.com *.example.com;
location / {
proxy_pass http://127.0.0.1:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
|
重新載入 nginx 設定
1
|
sudo systemctl reload nginx
|
設定 kestrel service
將建置好的發佈檔案上傳,假設上傳到/var/www/helloapp
dll檔是helloapp.dll
。
將使用者改成www-data
1
|
sudo chmod -R www-data:www-data /var/www/helloapp
|
新增一個服務檔案/etc/systemd/system/kestrel-helloapp.service
,設置如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
# /etc/systemd/system/kestrel-helloapp.service
[Unit]
Description=Example .NET Web API App running on Ubuntu
[Service]
WorkingDirectory=/var/www/helloapp
# 呼叫安裝的 .net core 環境來執行 helloapp
ExecStart=/usr/bin/dotnet /var/www/helloapp/helloapp.dll
Restart=always
# 如果 .net core 服務崩潰的話 10秒後嘗試重新啟動
RestartSec=10
KillSignal=SIGINT
SyslogIdentifier=dotnet-example
User=www-data
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false
[Install]
WantedBy=multi-user.target
|
把服務設定為開機啟動
1
|
sudo systemctl enable kestrel-helloapp.service
|
查看 kestrel service 的執行日誌:journalctl -fu kestrel-helloapp.service
設置 .NET Core 程式碼
1
2
3
4
5
6
7
8
|
// 只在 Linux 啟用 Reverse Proxy 模式
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});
}
|
這裡是預設 nginx、運行 .net core 的 Kestrel 都在同一台機器上,
如果使用 127.0.0.0/8 、 [::1]以外的伺服器作為 proxy,也就是說 nginx 在其他機器上,
則需要在 ConfigureServices 裡面像這樣額外設定信任的伺服器:
1
2
3
4
|
services.Configure<ForwardedHeadersOptions>(options =>
{
options.KnownProxies.Add(IPAddress.Parse("10.0.0.100"));
});
|
Web api template 預設會將 http 導向至 https 協議 (也就是說會把 5000 重新導向至 5001)
因此 Nginx 如果是反向代理 5000 port,
則需要把 web api 當中的 middleware app.UseHttpsRedirection();
移除
(或是在 nginx 直接設置反向代理 .net core 的 https port)
安裝 Nginx
如果是用 Web Api 專案搭配前端開發 SPA,
可安裝擴充套件
Microsoft.AspNetCore.SpaServices.Extensions,
並且在 middleware 最後設置路由 app.UseSpa(spa => { });
。
也可以不安裝擴充套件改用以下的程式碼手動進行設定:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
// 搭配 vue router history mode 重寫路徑請求
app.Use(async (ctx, next) =>
{
await next();
bool is404 = ctx.Response.StatusCode == 404;
bool hasExt = Path.HasExtension(ctx.Request.Path.Value);
if (is404 && !hasExt)
{
ctx.Request.Path = "/index.html";
ctx.Response.StatusCode = 200;
await next();
}
});
|
強化安全性
設定 https
拿到憑證之後可以進行設定,
Nginx 裡面憑證設定方式可以參考 ssl 設定產生器。
如果要使用到自簽憑證可以用下面的方式產生:
1
2
3
4
|
sudo mkdir /etc/ssl/private
sudo chmod 700 /etc/ssl/private
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/nginx-selfsigned.key -out /etc/ssl/certs/nginx-selfsigned.crt
sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
|
接著在 Nginx.conf 檔案裡面設定:
1
2
3
|
ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
|
設置防火牆
安裝啟用 Linux 安全性模組 (LSM) 裡面的 ufw 防火牆,
只允許 ssh、http、https(也可以選擇不要允許 http):
1
2
3
4
5
|
sudo apt-get install ufw
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
|
隱藏 Nginx 資訊
編輯 src/http/ngx_http_header_filter_module.c
變更 Nginx 回應名稱:
1
2
|
static char ngx_http_server_string[] = "Server: Web Server" CRLF;
static char ngx_http_server_full_string[] = "Server: Web Server" CRLF;
|
Reference