目录
第 5 步:创建示例WeatherForecast Web API
第 10 步:使用Certbot和LetsEncrypt的SSL证书
介绍
我想在真实的HTTPS域下托管一些简单的应用程序。这篇文章描述了我用Digital Ocean Droplet做这件事的尝试。这实际上很容易,但有一些有趣的故事。
在截图中,我在写这篇文章时实际上正在经历一个真正的Droplet创建/配置过程。写完这篇文章后,Droplet将被删除,因此我在这里可能提供的任何安全信息都无关紧要。
除了创建VM之外,此处描述的步骤也适用于其他VM提供商,例如Azure或AWS。
步骤
第 0 步:在您的计算机上安装WinSCP和PuTTY
使用WinSCP和PuTTY使用远程服务器要方便得多,因此请在本地计算机上安装这些应用程序。
第 1 步:创建一个Droplet
注册Digital Ocean并创建一个Droplet。
重要提示:确保创建Ubuntu 18.04 (LTS) x64 droplet!Ubuntu 20.04不是一个快乐的.NET露营者!
使用基本计划和 CPU 选项“带 SSD 的常规英特尔”,每月 5 美元:
对于身份验证,我选择了密码选项而不是SSH密钥选项。
密码要求有点有趣:
第 2 步:安装openssh-server
我不想使用Digital Ocean的控制台,因为PuTTY有点复杂(例如,复制和粘贴真的很容易。)也就是说,我们必须从控制台开始。
创建Droplet后,您将在“资源”选项卡中看到它:
单击它,您将在右侧看到Console链接:
单击它,您将自动以root身份登录:
首先,通过运行以下命令确保Ubuntu的版本是最新的:
sudo apt update
由于Ubuntu 18没有安装openssh,请使用以下命令安装:
sudo apt install openssh-server
你会看到这个提示:
选择了默认的“保持当前安装的本地版本”。
第 3 步:连接PuTTY
记下Droplet的IP地址。复制IP——当您将鼠标悬停在IP上时,会出现一个方便的复制按钮。打开Putty并输入IP:
然后单击“打开”按钮并使用您分配的密码以root身份登录。您将首先看到:
单击接受并完成登录过程,您应该会看到类似以下内容:
第 4 步:安装.NET 6
在PuTTY终端窗口中运行这些命令,如下所述:在Linux上使用Snap安装.NET——.NET | 微软文档。
最简单的方法是复制下面代码块中的每一行,左键单击终端窗口,然后右键单击粘贴。
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安装,命令是不同的,如下所述:在Debian上安装.NET——.NET | 微软文档。
重要的!我使用最新版本的Ubuntu和Ubuntu VirtualBox尝试了上述命令,并在安装了.NET时,尝试运行示例Weather Forecast .NET应用程序导致了这个错误:GLIBC_2.2.5 not defined in file libpthread.so.0 with link time reference,具有讽刺意味的是,我最终使用了Debian VirtualBox镜像,因为这是人们说的唯一“有效”的解决方案。
检查.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 run只是返回到命令行,这意味着您使用错误版本的Ubuntu创建了Droplet!
按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:
在证书提示上单击是:
在右侧面板上,导航到/home/testapi/Properties:
双击launchSettings.json并:
在这条线上:
"applicationUrl": "https://localhost:7176;http://localhost:5129",
删除“https”路由并将本地主机更改为5000:
"applicationUrl": "http://localhost:5000",
保存文件——编辑器窗口右上角的“磁盘”图标。
使用以下命令重新启动 Web API:
dotnet build
dotnet run
你应该看到:
请注意,Web API现在正在侦听端口5000,而不是侦听https。
第 8 步:配置Nginx
再次在WinSCP中,导航到/etc/nginx/site-available:
并双击“默认”。
编辑“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 http://localhost: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 http://localhost:5000;
以及一些代理设置选项。
重要提示:我们必须使用localhost,而不是127.0.0.1,否则Web API将不会响应。
使用以下命令重新加载Nginx:
sudo /etc/init.d/nginx reload
第 9 步:测试Web API
您现在应该能够浏览到Web API:
第 10 步:使用Certbot和LetsEncrypt的SSL证书
这里有一篇很好的文章:如何设置Nginx Certbot (haydenjames.io)
此时,您必须注册一个域。编辑域上的DNS记录,创建两条A记录。我使用Namecheap,因此我的域temporalagency.com的A记录看起来像这样。您的A记录中的IP应该是您的Droplet的IP地址。
在安装SSL证书之前,您必须等待24小时左右才能通过Internet渗透。
同时,您可以安装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记录时间通过Inernet的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创建了一个新的服务器定义文件,重点是:
1、监听443端口:
server {
# SSL configuration
#
listen 443 ssl ;
listen [::]:443 ssl
2、服务器名称已配置:
server_name www.temporalagency.com temporalagency.com; # managed by Certbot
3、证书设置:
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
4、配置了重定向(假设您要求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或Debian当前的LTS版本的VirtualBox镜像测试Linux系统的部署很有用的。简单来说:
- 从Oracle下载并安装VirtualBox
- 下载所需的Ubuntu或Debian镜像
- 如果您安装Debian:在Debian上安装.NET——.NET | 微软文档
- 如果您安装Ubuntu:在Linux上使用Snap安装.NET——.NET | 微软文档
如果您安装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。
要在本地计算机上将 VirtualBox镜像与PuTTY和WinSCP一起使用,您需要创建一个网桥作为适配器2,与设置中的类似:
结论
在本文中:
- 我们创建了一个Digital Ocean Droplet。
- 选择了正确版本的Ubuntu以便与.NET 6配合使用。
- 在我们的本地计算机上安装了PuTTY和WinSCP,以便轻松访问Droplet。
- 为Droplet配置了我们的域注册器。
- 在Droplet上:
- 安装了.NET 6。
- 安装了Nginx。
- 创建了一个测试Web API。
- 为SSL配置了我们的Droplet。
- 将.NET Web API修改为不使用HTTPS重定向。
- 使用certbot通过LetsEncrypt创建90证书。
最终结果是有效HTTPS Web API的功能演示!
https://www.codeproject.com/Articles/5326406/Create-a-Digital-Ocean-Droplet-for-NET-Core-Web-AP