使用真实 SSL 证书和域名创建 Digital Ocean Droplet 来托管 .NET Core Web API





5.00/5 (12投票s)
我想在真实的 HTTPS 域名下托管一些简单的应用程序。本文将介绍我使用 Digital Ocean Droplet 来实现这一目标的经历。
引言
我想在真实的 HTTPS 域名下托管一些简单的应用程序。本文将介绍我使用 Digital Ocean Droplet 来实现这一目标的经历。实际上非常简单,但遇到了一些有趣的挑战。
在截图演示中,我正在边写边走查实际 Droplet 的创建/配置过程。写完本文后,该 Droplet 将会被删除,因此我可能在这里展示的任何安全信息都是无关紧要的。
除了创建虚拟机之外,这里描述的步骤也适用于 Azure 或 AWS 等其他虚拟机提供商。
步骤
步骤 0:在您的计算机上安装 WinSCP 和 PuTTY
使用 WinSCP 和 PuTTY 处理远程服务器会更方便,请在您的本地计算机上安装这些应用程序。
步骤 1:创建 Droplet
注册 Digital Ocean 并创建一个 Droplet。
重要提示:请确保您创建的是 Ubuntu 18.04 (LTS) x64 Droplet!Ubuntu 20.04 与 .NET 不太兼容!
使用 Basic 计划和 CPU 选项“Regular Intel with SSD”,价格为 5 美元/月。
对于身份验证,我选择了 **Password** 选项而不是 SSH keys 选项。
密码要求有点特别。
步骤 2:安装 openssh-server
我不想使用 Digital Ocean 的控制台,因为 PuTTY 功能更强大(例如,复制粘贴非常容易)。话虽如此,我们必须先从控制台开始。
创建 Droplet 后,您将在 **Resources** 选项卡中看到它。
点击它,您将在右侧看到 **Console** 链接。
点击它,您将自动以 root 用户登录。
首先,通过运行以下命令确保 Ubuntu 版本是最新的:
sudo apt update
由于 Ubuntu 18 没有安装 openssh,请使用以下命令安装:
sudo apt install openssh-server
您将看到此提示。
选择默认的“**保留当前安装的本地版本**”。
步骤 3:使用 PuTTY 连接
记下 Droplet 的 IP 地址。复制 IP 地址——当您将鼠标悬停在 IP 地址上时,会出现一个方便的 **Copy** 按钮。打开 Putty 并输入 IP 地址。
然后点击 **Open** 按钮,并使用您分配的密码作为 root 用户登录。您将首先看到。
点击 **Accept** 并完成登录过程,您应该会看到类似以下内容:
步骤 4:安装 .NET 6
在 PuTTY 终端窗口中运行这些命令,如 Install .NET on Linux with Snap - .NET | Microsoft Docs 中所述。
最简单的方法是复制下面代码块中的每一行,然后在终端窗口中左键单击,然后右键单击粘贴。
sudo snap install dotnet-sdk --classic --channel=6.0
sudo snap alias dotnet-sdk.dotnet dotnet
sudo snap install dotnet-runtime-60 --classic
export DOTNET_ROOT=/snap/dotnet-sdk/current
请注意,对于 Debian 安装,命令是不同的,如 Install .NET on Debian - .NET | Microsoft Docs 中所述。
重要提示! 我在 Ubuntu 虚拟机中使用最新版本的 Ubuntu 尝试了上述命令,虽然 .NET 安装成功,但在尝试运行示例 Weather Forecast .NET 应用程序时出现了此错误:GLIBC_2.2.5 not defined in file libpthread.so.0 with link time reference
。因此,讽刺的是,我最终使用了 Debian 虚拟机镜像,因为这是人们说“有效”的唯一解决方案。话虽如此,
使用以下命令检查 .NET 6 安装:
sudo dotnet --info
您应该会看到:
(细心的读者会注意到我的 Droplet 名称变了——我最初安装了 Ubuntu 20.04,然后发现它与 .NET 6 不兼容!)
步骤 5:创建示例 WeatherForecast Web API
再次在 PuTTY 控制台中,复制并粘贴:
从 /home 文件夹创建 testapi
,然后:
cd /home
mkdir testapi
cd testapi
dotnet new webapi
dotnet build
dotnet run
您应该会看到:
如果您不这样做——如果 dotnet
命令只是返回到命令行,则意味着您创建 Droplet 时使用的 Ubuntu 版本不正确!
按 **Ctrl+C** 停止 Web API。我们稍后需要进行一些配置更改。
步骤 6:安装 Nginx
我使用 Nginx 是因为它支持反向代理,正如我们稍后将看到的,这对于将传入请求路由到 .NET Web API 应用程序是必需的。
使用以下命令安装 Nginx:
sudo apt-get install nginx
并使用以下命令启动服务器:
sudo /etc/init.d/nginx start
我们将更改 Nginx 的配置,所以这个命令
sudo /etc/init.d/nginx reload
用于重新加载 Nginx,了解它很有用。
步骤 7:配置 .NET 启动设置
我们不希望 .NET 管理 HTTPS 连接——这将由 Nginx 完成,所以我们打开 WinSCP。
在证书提示中点击 **Yes**。
在右侧面板中,导航到 /home/testapi/Properties。
双击 launchSettings.json 文件,然后:
在此行上:
"applicationUrl": "https://:7176;https://:5129",
删除 "https
" 路由并将 localhost 改为 5000
,使其读作:
"applicationUrl": "https://:5000",
保存文件——在编辑器窗口的右上角有一个“磁盘”图标。
使用以下命令重启 Web API:
dotnet build
dotnet run
您应该会看到:
请注意,Web API 现在正在监听端口 5000,而不是监听 https。
步骤 8:配置 Nginx
再次在 WinSCP 中,导航到 /etc/nginx/site-available。
双击 "default"。
编辑 "location
" 配置,使其读作:
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
# try_files $uri $uri/ =404;
proxy_pass https://: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;
}
我们在这里所做的更改是注释掉 "try_files
" 选项,最重要的是,添加 proxy_pass
行:
proxy_pass https://:5000;
以及一些代理设置选项。
重要提示:我们必须使用 localhost,而不是 127.0.0.1,否则 Web API 将不会响应。
使用以下命令重新加载 Nginx:
sudo /etc/init.d/nginx reload
步骤 9:测试 Web API
您现在应该能够浏览到 Web API 了。
步骤 10:使用 Certbot 和 LetsEncrypt 设置 SSL 证书
这里有一个很好的教程:How to Set Up an Nginx Certbot (haydenjames.io)。
此时,您必须有一个已注册的域名。编辑域名的 DNS 记录,创建两个 A 记录。我使用 Namecheap,所以我的域名 temporalagency.com 的 A 记录如下。您 A 记录中的 IP 地址应该是您 Droplet 的 IP 地址。
您需要等待大约 24 小时,让 DNS 记录在互联网上生效,然后才能安装 SSL 证书。
在此期间,您可以安装 Certbot:
sudo apt install python-certbot-nginx
防火墙也应该使用以下命令进行配置:
ufw allow ssh
ufw enable
ufw allow http
ufw allow https
sudo ufw allow 'Nginx Full'
sudo ufw status
最后一条命令显示防火墙状态,运行上述命令后,它应该看起来像这样:
一旦您等待 A 记录通过互联网 DNS 系统更新,您就可以运行此命令:
sudo certbot --nginx -d [domain].[ext] -d www.[domain].[ext]
其中 [domain]
是您的域名,[ext]
是通用顶级域名,例如 com
、org
、net
等。系统会提示您输入用于警报的电子邮件地址以及一些其他选择性问题,包括是否应自动将 http 重定向到 https,我对此回答“是”。
此时,您应该可以使用 https://www.[domain].[ext]/WeatherService
访问 Web API,例如,使用我的域名 temporalagency.com。
要手动续订证书(每 90 天过期一次),您可以使用此命令:
sudo certbot renew --dry-run
但是,证书应该会自动续订。您可以使用以下命令验证它是否在 systemd
定时器中:
systemctl list-timers
您应该会看到:
Certbot 服务每几个小时运行一次——这并不意味着它每次运行时都会刷新证书!
Certbot 做了什么?
如果您查看 Nginx 文件夹中的 default
文件,您会发现 certbot 创建了一个新的服务器定义文件,关键点是:
- 监听端口 443。
server { # SSL configuration # listen 443 ssl ; listen [::]:443 ssl ;
- 服务器名称已配置。
server_name www.temporalagency.com temporalagency.com; # managed by Certbot
- 证书已设置。
ssl_certificate /etc/letsencrypt/live/temporalagency.com/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/temporalagency.com/privkey.pem; # managed by Certbot
- 已配置重定向(假设您要求 certbot 将 http 重定向到 https)。
server { if ($host = www.temporalagency.com) { return 301 https://$host$request_uri; } # managed by Certbot if ($host = temporalagency.com) { return 301 https://$host$request_uri; } # managed by Certbot listen 80 ; listen [::]:80 ; server_name www.temporalagency.com temporalagency.com; return 404; # managed by Certbot
步骤 11:发布并保持 Web API 运行
最后,我们希望在关闭 PuTTY 窗口后 Web API 保持运行,或者在服务器重启时自动重启。
首先,注释掉该行:
// app.UseHttpsRedirection();
因为 Nginx 正在处理 https 重定向。
接下来,创建一个应用程序的发布版本:
dotnet publish --configuration Release
这会创建一个 Publish 文件夹,我们可以在 WinSCP 中看到它。
使用 WinSCP,在 /etc/systemd/system 中创建一个服务定义文件。
例如,我将其命名为 "testapi.service
"。
文件内容(来自 此处)应读作:
[Unit]
Description=Example .NET Web API App running on Ubuntu
[Service]
WorkingDirectory=/var/www/PUBLISH_DIRECTORY
ExecStart=/usr/bin/dotnet /var/www/MYAPP_DIRECTORY/STARUP_PROJECT_NAME.dll
Restart=always
# Restart service after 10 seconds if the dotnet service crashes:
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
但是,/var/www/PUBLISH_DIRECTORY 和 /var/www/MYAPP_DIRECTORY/STARUP_PROJECT_NAME.dll 需要相应地替换,由于我的服务位于 home/testapi,我使用了:
分别是 /home/testapi/bin/Release/net6.0/publish/ 和 /home/testapi/bin/Release/net6.0/publish/testapi.dll。
WorkingDirectory=/home/testapi/bin/Release/net6.0/publish
ExecStart=/snap/dotnet-sdk/current/dotnet /home/testapi/bin/Release/net6.0/publish/testapi.dll
重要提示:请注意 dotnet 的路径——服务需要绝对路径。
保存文件并使用以下命令启用服务(显然,将服务名称替换为您选择的服务名称):
sudo systemctl enable testapi.service
使用以下命令启动服务:
sudo systemctl start testapi.service
如果需要停止服务,请使用:
sudo systemctl stop testapi.service
测试服务在重启后是否启动:
sudo reboot
等待一分钟左右让 Droplet 重启,然后测试 Web API 是否正常工作。
步骤 12:可选 - 设置 VirtualBox
我不太愿意在 Droplet 上测试代码,虽然我显然可以在 Windows 中开发 .NET 6 应用程序,但我认为使用 Ubuntu 18.04 或当前 LTS 版本的 Debian 的 VirtualBox 镜像来测试部署到 Linux 系统很有用。简而言之:
- 从 Oracle 下载并安装 VirtualBox。
- 下载所需的 Ubuntu 或 Debian 镜像。
- 如果安装 Debian:Install .NET on Debian - .NET | Microsoft Docs。
- 如果安装 Ubuntu: Install .NET on Linux with Snap - .NET | Microsoft Docs。
如果安装 Debian,您需要编辑 Debian 服务器上的 /etc/network/interfaces 文件,使其与以下内容类似,具体取决于您的 IP 地址和名称服务器。
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).
source /etc/network/interfaces.d/*
# The loopback network interface
auto lo
iface lo inet loopback
# The primary network interface
allow-hotplug eth0
iface eth0 inet static
address 192.168.10.115
netmask 255.255.255.0
gateway 192.168.10.1
dns-nameservers 8.8.8.8 192.168.10.1
另外请注意,Debian 镜像已经安装了 openssh
。
要从本地计算机使用 PuTTY 和 WinSCP 连接 VirtualBox 镜像,您需要在设置中创建网络桥接作为 Adapter 2,类似如下:
结论
本文内容
- 我们创建了一个 Digital Ocean Droplet。
- 选择了正确的 Ubuntu 版本以兼容 .NET 6。
- 在本地计算机上安装了 PuTTY 和 WinSCP,以便轻松访问 Droplet。
- 为 Droplet 配置了域名注册商。
- 在 Droplet 上:
- 安装了 .NET 6。
- 安装了 Nginx。
- 创建了一个测试 Web API。
- 为 Droplet 配置了 SSL。
- 修改了 .NET Web API 以不使用 HTTPS 重定向。
- 使用 certbot 创建了一个包含 90 天证书的 LetsEncrypt 证书。
最终结果是一个功能正常的有效 HTTPS Web API 演示!
历史
- 2022年3月1日:初始版本