如何配置一个新服务器
引言
我从高考后到现在出来工作两年,期间重新配置了许多电脑。
在学习和熟悉新软件,新技术的过程中。总是不可避免的弄坏一些配置文件。弄坏一些重要的服务配置。每次遇到一些稀奇古怪,没法找到原因的问题时。就需要重置操作系统,去彻底的解决这些严重影响使用的问题。
从到用Ghost镜像重装win系统,刷MIUI系统,到根据网上的教程一点点的配置好树莓派。刷OpenWRT路由器。再到在阿里云,AWS买域名,租服务器。再到折腾nas。在折腾的路上总是在重新配置操作系统。
这次想分享的是如何配置一个Linux的服务器,用来在公网设立自己的服务那种。(其他的配置可能以后心血来潮,可能永远也不会写)主要是从全新安装的系统,替换软件源,更新软件,配置用户,ssh,NGINX,docker这些初始的便捷工具和安全配置配置操作。
配置
SSH
首先是登录,我们肯定是希望用一种方便快捷的方式来访问我们的服务器。最好是不用记忆密码。最常用的访问协议就是SSH。为此,您将需要一个 SSH 密钥和一个新的用户帐户。在新提供的 VPS 上,您将以 root 身份登录,并且希望保护 root 帐户。首先在 VPS 或远程计算机上创建一个新的常规用户,并将他们添加到“ sudo”组,使用:
sudo adduser newuser
sudo usermod -aG sudo newuser现在在本地机器上运行:
ssh-keygen -t ed25519 -C "your_email@example.com"按照说明,它会询问您想在哪里保存文件,以及是否需要密码。确保你设置了一个字符串。将公钥复制到在本地计算机上运行的服务器:
ssh-copy-id -i ~/.ssh/id_ed25519.pub newuser@your_server_ip请记住 newuser@your-server-ip 是您试图将公钥复制到的用户名和远程设备。当您被提示输入密码时,它将是远程设备上帐户的密码,而不是您刚刚为 SSH 密钥设置的密码。一旦验证,它将复制到公钥,您现在可以通过 SSH 登录。要关闭用户名和密码登录,输入:
sudo nano /etc/ssh/sshd_config找到这些值并按照您在这里看到的设置它们。
Port 2222 # Change default port (use a number between 1024 and 65535)
PermitRootLogin no # Disable root login
PasswordAuthentication no # Disable password authentication
PubkeyAuthentication yes # Enable public key authentication
AuthorizedKeysFile .ssh/authorized_keys # Specify authorized_keys file location
AllowUsers newuser # Only allow specific users to login这将禁止在您将公钥复制到的用户下使用除 SSH 之外的所有登录方法。停止以根用户身份登录,只允许您指定的用户登录。按 Ctrl + S 保存,按 Ctrl + X 退出文件编辑器。重新启动 SSH:
sudo service ssh restart这可能会将您从会话中引导出来。如果是这样,那么现在就是测试其他登录方法的好时机,看看它们是否被拒绝,然后再继续。另外,这应该不言而喻,但你需要保持私人密钥的安全,如果你失去了它,你将无法进入远程了。您可以进一步锁定您的登录:
Protocol 2 # Use only SSH protocol version 2
MaxAuthTries 3 # Limit authentication attempts
ClientAliveInterval 300 # Client alive interval in seconds
ClientAliveCountMax 2 # Maximum client alive count现在,让我们深入了解一下用户,看看如何利用他们来实现一些组织和安全性。
用户管理
在管理 Linux 服务器时,用户非常重要。在服务器管理中有一个叫做“最小特权原则”的想法,这基本上意味着你想给一个应用程序或处理程序最小的特权数量,它需要做它的工作。根有无限的权力,没有应用程序真正需要这一点。为你运行的应用程序创建一个用户可以完成一些事情。如果您正在运行的应用程序受到损害,它可以限制潜在的损害。它在运行多个应用程序时增加了隔离性,有助于审计,这样你就可以知道哪个应用程序使用了哪些系统资源。
简而言之,用户是帮助组织系统的一种很好的方式,并且可以在出现问题时帮助您进行故障排除。要添加新用户,请运行:
sudo useradd -rms /usr/sbin/nologin -c "a comment" youruser这个命令创建一个用户,并为他们提供一个应用程序数据的主目录,但不允许作为用户登录。C 标志是可选的,但是很高兴知道用户是干什么的,比如“ RuningNextcloud”或者其他什么。将应用程序文件克隆到/opt 目录中,并使用:
sudo mkdir /opt/myapp这个命令创建一个用户,并为他们提供一个应用程序数据的主目录,但不允许作为用户登录。C 标志是可选的,但是很高兴知道用户是干什么的,比如“ RuningNextcloud”或者其他什么。将应用程序文件克隆到/opt 目录中,并使用:
sudo chown appuser:appuser /opt/myapp好的,这样你的登录就被锁定了,你应该对如何使用用户有一个不错的想法。接下来是日志。
日志
日志对于系统管理至关重要。它们跟踪系统健康状况,帮助解决问题和检测威胁。因此,您需要设置适当的日志旋转,这样它们就不会占用系统中太多的空间,而且更容易读取和管理。要设置适当的日志旋转,需要编辑位于/etc 中的 logrotate.conf 文件。单独的应用程序配置通常存储在/etc/logrotate.d/中,因此 NGINX 的示例配置类似于:
/var/log/nginx/*.log {
weekly
missingok
rotate 52
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
postrotate
[ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
endscript
}此配置每周轮换日志,保留52周的日志,压缩旧日志,使用正确的权限创建新日志,然后在轮换后通知 NGINX 重新打开日志文件。你可以用以下方法进行测试:
sudo logrotate -d /etc/logrotate.conf这将显示在没有实际旋转日志的情况下它将做什么。有了这些设置,您就可以开始执行更高级的操作,比如根据日志条目触发警报。现在,这对于单个服务器来说是很好的,但是如果您管理多个服务器,那么查看 Grafana Loki、 Graylog 和 Fluentd 等工具是一个好主意。我不会在这里详细说明,但如果你想提高你的日志游戏,这是一个体面的地方开始。
备份
备份,更重要的是,测试您的备份,在服务器管理中是极其重要的。请记住: 备份不是备份,除非您测试它。未经测试的备份基本上是无用的。
备份主要有三种类型。全速,差速,增量。完整备份是磁盘上所有数据的完整副本。需要最多的资源,但是最容易恢复。差异备份备份自上次完整备份以来的所有更改,这是在空间和恢复速度方面进行备份的中间策略。增量备份将备份自上次备份以来更改的数据,这是最快的备份选项,但也可能是最复杂的备份。
我是这么想的。我使用增量备份的东西,如照片和文档或项目文件和文件夹得到编辑了很多。我将使用一个完整的备份备份和整个服务器或磁盘。差异备份用于备份完整文件夹,如/etc、/opt 和 log 文件夹。
那储藏室呢?如果你遵循3-2-1规则,你就是黄金。数据的3个副本、2个存储类型和1个异地备份。我想说,如果这看起来太多,“离线”存储是最重要的,而不是一个跳过。在灾难性熔毁的情况下,拥有一个带有备份的硬盘是非常宝贵的。离线/离线备份也可以从勒索软件中拯救你。记住这一点。外面有大量的备份软件。是为了探索一些更专业的备份工具。具有文件同步、传输和可存储解决方案。我用的是同步器,博格人备份还有老式的 FTP。
请记住,备份、日志和服务器监视是一个基于您的需求而不断发展的过程。您实现的具体策略应该适合您的需求和数据的关键性。
网络安全配置
保护服务器安全的下一步是锁定那些不需要暴露在互联网上的端口,并禁止那些在不应该登录的时候尝试登录的东西。UFW 和 FAIL2Ban 是两个广泛使用的工具。它们简单易用,UFW 可以让你为端口设置通信规则,当它敲击一个不应该敲击的端口或者在一些预定义的规则之后他们没有登录时,Fail2Ban 将禁止和 IP 地址。UFW 或者 Uncomplicated Firewall 通常预装在许多 VPS 服务上,和 fail2Ban 一样,但是如果你在一台新机器上,你不确定,运行:
sudo apt install ufw
sudo apt install fail2ban** UFW**
以后我们会关注这个问题,现在让我们关注 UFW 的设置:
sudo ufw default deny incoming
sudo ufw allow outgoing这被认为是最佳实践,因为它遵循了我前面提到的“最少特权”的思想。它减少了您机器上的攻击面,并使您能够精确地控制您要暴露的内容。简而言之,这种配置在安全性和功能性之间创建了一种平衡。您的服务器可以根据需要连接到 Internet,但外部实体只能以您明确允许的方式连接到您的服务器。现在让我们允许一些东西进来。
sudo ufw allow ssh
sudo ufw allow 80
sudo ufw allow 443如果要运行 Web 服务器,则需要打开端口80和端口443。80是 HTTP,443是 HTTPS。默认情况下,端口22是 SSH,如果您更改了它,则需要指定端口,而不是使用“ allow SSH”命令。下面是一些其他有用的命令:
#List rules with numbers:
sudo ufw status numbered
#Delete by number:
sudo ufw delete NUMBER
#Delete by rule specification:
sudo ufw delete allow 80
#You can allow connections from specific IP addresses:
sudo ufw allow from 192.168.1.100
#You can also only allow an IP to connect to a specfic port with:
sudo ufw allow from 192.168.1.100 to any port 22
#If you neeed to allow a range of ports:
sudo ufw allow 6000:6007/tcp
#To further protect from brut force attacks you can rate limit specific ports with:
sudo ufw limit ssh
#This would limit port 22 to 6 connections in 30 seconds from a single IP. To see the status of the firewall you can use:
#Adding this goves you more info
sudo ufw status verbose
#and to reset incase you need to start over:
sudo ufw reset
#and to enable and disable:
sudo ufw enable
sudo ufw disable
#finaly to enable logging and adjusting the log level:
sudo ufw logging on
sudo ufw logging medium # levels are low, medium, high, full现在谈谈失败禁令。
** 失败禁令**
主配置位于/etc/fail2ban/jail.conf 中,但建议创建一个本地配置文件:
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local在 jail.local 部分的[ DEFAULT ]部分有一些基本设置,它们是:
bantime = 10m
findtime = 10m
maxretry = 5禁止时间是指知识产权被禁止的时间。查找时间是故障2Ban 查找重复故障的时间框架,最大重试是在 IP 被禁止之前的故障次数。你可以随意调整。您还可以设置自定义的 jails,Fail2Ban 也支持常用服务(如 SSH)的 jails。你甚至可以采取更多的步骤,但我认为这涵盖了基础。
NGINX
你可以使用的网络服务器有很多。Apache,Caddy,nginx,IIS 等等。我用的是 Nginx。这就是我所知道的,而且效果非常好。Nginx (发音为 engine-x)是一个 Web 服务器、反向代理和负载平衡器。作为一个 Web 服务器,它擅长于提供静态内容,并且能够以相当低的资源使用率处理并发连接的负载。作为一个反向代理,它可以位于您的应用服务器之前,并将流量转发给它们,同时链接应用程序的安全性。它的负载均衡方面可以有效地平衡服务器之间的流量,提高可靠性和可扩展性。
当通过 apt 安装时,nginx 的默认位置是/etc/nginx/nginx.conf 主要用于全局服务器配置,包括来自/etc/nginx/sites- 启用文件夹的文件。这种模块化结构可以方便地管理多个站点。需要注意的两个文件夹是启用站点的文件夹和可用站点的文件夹。您可以将可用的站点视为测试站点配置的临时场所,而启用的站点则用于实时站点和应用程序。通常的做法是在可用站点中的站点中设置和测试配置,然后当您准备启动并获得 SSL 证书时,将文件链接到支持站点的文件夹。你可以这样做:
ln -s /etc/nginx/sites-available/yoursitefile /etc/nginx/sites-enabled然后重新加载 nginx 并用以下命令再次检查 nginx 状态:
sudo systemctl reload nginx
sudo systemctl status nginx您的网站现在应该是活动的。
下面,我将向您展示一些 Nginx 站点配置的样板。一定要了解你的应用程序或网站的需求,因为这些只是起点。对于静态站点,这是一个不错的起点。
基本静态网站配置:
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
root /var/www/example.com/html;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;
# Logging
access_log /var/log/nginx/example.com.access.log;
error_log /var/log/nginx/example.com.error.log warn;
# SSL configuration (uncomment after running Certbot)
# listen 443 ssl http2;
# listen [::]:443 ssl http2;
# ssl_protocols TLSv1.2 TLSv1.3;
# ssl_prefer_server_ciphers on;
# ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
# Certbot will add its own SSL certificate paths
# ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
# ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
}代理通行证配置:
server {
listen 80;
listen [::]:80;
server_name app.example.com;
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;
# Logging
access_log /var/log/nginx/app.example.com.access.log;
error_log /var/log/nginx/app.example.com.error.log warn;
# SSL configuration (uncomment after running Certbot)
# listen 443 ssl http2;
# listen [::]:443 ssl http2;
# ssl_protocols TLSv1.2 TLSv1.3;
# ssl_prefer_server_ciphers on;
# ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
# Certbot will add its own SSL certificate paths
# ssl_certificate /etc/letsencrypt/live/app.example.com/fullchain.pem;
# ssl_certificate_key /etc/letsencrypt/live/app.example.com/privkey.pem;
}WebSocket 升级配置:
server {
listen 80;
listen [::]:80;
server_name ws.example.com;
location / {
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;
# WebSocket timeout settings
proxy_read_timeout 300s;
proxy_send_timeout 300s;
# Logging
access_log /var/log/nginx/ws.example.com.access.log;
error_log /var/log/nginx/ws.example.com.error.log warn;
# SSL configuration (uncomment after running Certbot)
# listen 443 ssl http2;
# listen [::]:443 ssl http2;
# ssl_protocols TLSv1.2 TLSv1.3;
# ssl_prefer_server_ciphers on;
# ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
# Certbot will add its own SSL certificate paths
# ssl_certificate /etc/letsencrypt/live/ws.example.com/fullchain.pem;
# ssl_certificate_key /etc/letsencrypt/live/ws.example.com/privkey.pem;
}基本配置用于服务一个简单的静态站点。它指定域名,监听端口80上的 IPv4和 IPv6,为站点设置根目录,用 try _ files 配置错误处理,添加一些保护常见网络漏洞的基本头,设置访问和错误的日志记录,并包括一个 SSL 部分被注释掉。大多数 SSL 配置将由 certbot 处理,但是其中有几行添加了一些 SSL 安全性,可以在 certbot 运行后取消注释。 代理传递配置类似于基本配置,但是它不直接服务文件,而是将请求代理到本地应用程序(在本例中,运行在端口3000上)。
第三个配置文件是面向需要网站连接的应用程序的,它很像代理传递配置,只是做了一些修改以允许 Web 套接字。
好吧,如果不谈 SSL,任何关于 Web 服务器的内容都是不完整的。对于临时用户来说,certbot 是平民最好的朋友。免费,快捷,而且他妈的管用。我使用的是 python 版本的 certbot。您可以使用以下命令安装:
sudo apt install certbot python3-certbot-nginx一旦安装完成,你可以简单地在终端中运行“ certbot”,这将检测到在您的站点启用的文件夹中的配置,并询问您想要做什么(更新,重新发行,等等..。.).沿着这条路走,Certbot 会给你指示,非常直接。 所以现在 certbot 在获得一个新的证书时会为你设置自动更新,所以这是一个坐下来忘记的任务。但是为了确保这个方法有效,你可以跑步:
sudo systemctl status certbot.timer如果它已经启动并运行了,那么如果您正在使用 systemd,那么应该可以运行了。
管理工具
关于使管理系统更容易的工具这个主题,我将介绍一些我在服务器上使用的工具,我认为这些工具使管理更好一些。不会对任何工具进行深入研究。所有这些都是可选的,没有特定的顺序。我在网站上找到了很多这样的网站,如果你像我一样是个终极瘾君子,这是个很好的浏览网站。
第一件工具,这是我个人必备清单。Btop 是资源的终端监视器。它显示了你的机器的 CPU、 RAM、磁盘、网络和运行的实时可视化使用统计数据,它是用 C + + 编写的,可以通过大多数软件包管理器安装。
对于有很多外部连接的服务器,例如 nostr 中继,使用类似的工具是有帮助的。Neoss 的目标是将通常的 ss 命令替换为基本用法。它提供了一个正在使用的 TCP 和 UDP 套接字及其各自统计信息的列表。与 SS 原始输出相比,它的主要优势在于其清晰而简单的 TUI (终端用户界面) ,允许您对连接到计算机的内容进行排序、刷新和导航。它是通过 NPM 安装的,这意味着需要安装 JavaScript。
GoAccess是一个基于终端的 Web 服务器日志分析器。它非常适合于在终端中快速实时查看日志,但它也可以生成实时 HTML、 JSON 和 CSV 报告。GoAccess 可以通过大多数软件包管理器安装,适用于所有平台。
列表中的下一个是它的一个强大的基于文本的文件管理器,具有两个面板显示和很多操作文件和目录的特性。它也是跨平台的,可以通过大多数软件包管理器安装。
在同一个服务器文件管理线程中是。这个在我的必备清单上。这个 Baobab 是用来寻找太空猪的。它很快,而且使用非常简单。它可以安装在大多数系统和包管理器上。Windows 将需要安装 Linux 子系统来使用它。
希望你能从中找到点用处。最后一个话题我想触及的是 DNS,这是一个有点话题,所以我不会做一个大规模的深入挖掘,但如果你自我托管它有助于有一些基本的 DNS 下来。没用的。
DNS
DNS 或域名系统是我们所知的互联网如何工作的核心部分。不管你喜欢还是不喜欢,如果你想接触到更广阔的互联网,这就是我们必须要做的。(我不喜欢它现在的样子,但我不会在这里打开那个蠕虫罐头。)基本上,把域名解析系统想象成电话簿。它允许你在每次需要搜索互联网时输入 duckduckgo.com 而不是“52.250.42.157”。它将人类容易记住的东西翻译成计算机所需的信息,从而实际访问“ duckduckgo.com”
如果您使用 VPS 托管,那么您真正需要知道的唯一一件事情是,在您决定使用某个域之后,如何将 A 记录指向服务器的 IP。几乎所有的 VPS 主机都可以为您提供静态 IP,所以这基本上是一个集合和忘记类型协议。
在家里主持会面临一些挑战。一个突出的问题是(我经常听到的一个有效的问题)没有静态 IP 地址。现在,随着设备的数量在线需要 IP 地址,我们做了很多杂耍,大多数 IP 地址是动态分配,除非你从你的 ISP 支付。但是有一个解决办法。这个问题的答案称为动态 DNS 或 DDNS。这允许每次 IP 地址更改时自动更新 DNS 服务器。建立动态 DNS 的方法有很多。您可以托管自己的服务或使用主机。这里有一个链接,可以查看一些主机和项目。
简而言之,它的工作原理是这样的。您选择了一个提供商或建立自己的提供商。你得到一个域,在你的家庭路由器或服务器上安装客户端,客户端定期检查 IP 地址是否有变化,如果有的话,它会更新你的域名服务器记录。
test.localhost
Docker
我不打算在这里介绍如何安装 Docker。无论如何,最好遵循官方的安装指南。但我想谈一些事情。首先,docker 对于测试新的应用程序非常有用。但我只能做到这样了。我个人不太喜欢使用 docker,在可能的情况下直接运行应用程序。以下是一些需要记住的利弊。
Docker Pros
一致性是一个很大的问题,它可以使开发、测试和部署之间的事情更加稳定,如果你的系统可以运行 docker,你可以运行大多数 docker 应用程序。它可以帮助隔离,减少应用程序之间的冲突。在某些情况下,它可以帮助提高效率,因为它比传统虚拟机占用更少的资源。它可以帮助扩展,因为可以很容易地旋转更多的容器,而且微服务架构可以很有用,因为您可以将应用程序分解为更小的可管理服务,从而允许对所述服务进行独立的扩展。最后,社区很大,所以文档很好,社区支持总是很有帮助,此外还有很多可以部署的 Docker 映像。
Docker Cons
我从管理费开始。虽然它比传统的 VM 更好,但是它比直接在主机上运行更多的资源,而且 I/O 操作可能会更慢。Docker 共享系统内核的事实意味着一个受损的应用程序可能会影响系统。持久数据是可行的,但是增加了一层复杂性,可能会导致新用户的数据丢失,这也使得备份更加复杂。使用 docker 的网络也可能更加复杂,使其不那么简单。值得注意的是,如果您使用 UFW 或防火墙作为防火墙,docker 会绕过这些规则。Docker 只与 iptables 兼容。另外,尽管管理良好的 Docker 容器可以帮助管理服务器资源,但是不正确的管理也会对资源造成损害。容器可能变得太大,影响磁盘大小,错误配置可能会使用太多的服务器资源。在监视和调试应用程序时,它还增加了额外的复杂性层,特别是在多个容器之间。
归根结底,这是你的系统。但我想列出一些利弊当涉及到使用 Docker。继续。
结语
对于服务器设置和工具的基础知识,这差不多就是这样了。有一个可以帮你做大部分事情。我写它是为了让我自己的服务器设置更快。你可以在这里得到它,它包括了我所有的必需品,并做了一些基本的配置。根据你自己的需要调整它,并且一如既往地保持安全,如果你有问题或者我在这篇文章中搞砸了什么,请通知我 nostr 或 simplex。
本篇文章是搬运的,在这篇文章的技术框架上增删改。加上些我自己的经验。
