服务器搭建

Posted by Steel Shadow on February 27, 2025

这篇文章中将会持续更新我的服务器相关内容。

2025.2.25 update

前段时间想到校园网 ipv6 免流,于是在 aws EC2 的一年免费使用机上配置了 ipv6 地址,之后用 trojan-go 代理在刚配置好的电脑下载了几百 GB 的游戏(地平线 5 和 everspace 2)。

单纯的我原以为 aws 的流量是免费的,后来才知道 aws 每月前 100GB 出站流量免费,后续要阶梯付费(入栈免费)。然后我就收到了 20$ 的账单!后续我开启了 support case Request for Fee Waiver in Free Tier Due to Mistaken Usage 。aws 也同意了我的请求,他们在审核后给我的账户加了响应金额的 credit。服务器之后还可以正常使用。

在工单处理期间(要求停止服务器),我在微软的 azure 上重新架设了服务器。实际体验下来,aws 的服务质量要比 azure 好很多(azure 的 support 居然要购买付费!)。github education 免费给 azure 100$ 的额度,并且 education 订阅的付费只有固定 ipv4 和超额流量。

主机图1 主机图2

下面介绍我的服务器搭建。

搭建准备

服务器

一个既可以连接国内又可以连接 Internet 的服务器。

Amazon Web Service EC2 免费试用 1 年,注册需支付方式。

github education 包含了 100 美元的 azure vps,额度没用完可以无线续期。

域名

注册证书时,一般 Certificate Authority(CA) 都要求一个域名,包括 Let's Encrypt

我在 namecheap 上购买了一年 steel-shadow.lol,1.98$。github education 上也有免费域名。

之后配置 DNS record 即可,将域名映射到 IP。

SSL/TLS 证书

Let's Encrypt 提供免费 SSL/TLS 证书,但是需要域名。

再使用 cerbotLet's Encrypt 获取证书。

Certbot ACME 客户端可以在不下线服务器的前提下自动执行证书颁发和安装。证书自动定时续期。

多个域名可以共用一个证书。

通配符域名证书的获取和 renew 似乎只能通过手动命令行进行,麻烦一些。

1
2
3
certbot certonly --manual --preferred-challenge dns \
-d "steel-shadow.me" \
-d "*.steel-shadow.me"

依照 certbot 的操作,为自己的域名获取证书即可。

关于域名和 IP 地址

我的服务器 ipv4 地址是动态的,在重启之后会变化(aws azure 均如此,购买静态地址更贵)。为了解决这个问题,我使用了 DDNS。

DDNS(Dynamic DNS) 是专门用来解决动态 IP 地址的问题的。在访问服务器时,使用域名代替动态 IP 地址。服务器端需要使用 DDNS 客户端,每隔一段时间向 DNS 服务商更新自己的 IP 地址。DNS 服务商一般都会提供自己的 DDNS 客户端或者接口,此处不赘述。

服务架构:反向代理

下面回归正题,聊聊我的服务器部署。

我目前的服务器的功能有:

  • nginx 架设网页(个人blog等)
  • 内网穿透 frp(校园网内使用可能是违规的,或许管理也是睁一只眼闭一只眼)
  • 云盘 cloudreve
  • trojan-go 代理
  • 邮件服务 docker mailserver
  • ….

有这么多服务,要怎么管理它们呢?这些服务一般都有自己的默认端口,如果把这些服务部署在同一个域名的不同端口上,那么每次添加新服务,都要修改 vps 的出站流量策略(开放端口)。访问起来也比较麻烦,要记住服务的端口号。还可能有公网扫描端口的恶意流量。

综上所述,我最终决定把这些服务都开在 443 端口,使用 nginx 进行反向代理和 SSL 加密。

nginx 反向代理图

初看这图有点迷糊,下面对上图的作解释。

我们知道,代理是一个中间服务器,位于客户端和目标服务器之间。它代表客户端向目标服务器发送请求,并将响应返回给客户端。例如 trojan-go 就是代理服务器端,而 clash 就是代理客户端。

反向代理也是一个中间服务器,但它位于客户端和多个后端服务器之间。客户端将请求发送给反向代理服务器,而反向代理服务器将请求转发给合适的后端服务器,并将响应返回给客户端。这里的 nginx 就是反向代理服务器。

反向代理的 IP 问题

如果使用反向代理,那么后端服务看到的流量来源 IP 就是本机 127.0.0.1。后端服务可能需要来源 IP 进行黑名单管理、日志记录等。

我们需要设法在反向代理的后端服务中显示真实的来源 IP。

在 nginx 中,这可以使用 proxy_protocol 实现。proxy_protocol 在 TCP 报文端的头部添加 IP 信息。因此两端必须同时开启或关闭 proxy_protocol,否则会产生错误。

在反向代理服务端和被转发到的后端,都开启 proxy_protocol 即可。对于不支持 proxy_protocol 的服务,需要使用一个中转的 nginx server 卸载 proxy_protocol。流量的真实 IP 就记录在这个 nginx server 上。

对于不支持 proxy_protocol 的后端服务,还有一个解决方法,在 HTTP 报文的 header 里添加字段 X-Forwarded-For,它的值就是真实的 IP。这个方法与 proxy_protocol 类似,只不过是在应用层 HTTP 实现(我的配置 cloudreve 中就使用了这个方法)。

nginx 反向代理配置

服务名称 SSL 加密 proxy_protocol
trojan-go 自带加密,但使用 nginx 的加密 不支持,需要中转卸载
frp 自带加密,nginx 无需加密 不支持,需要中转卸载
cloudreve 不自带加密,nginx 需加密 不支持,需要中转卸载
nginx 网页 nginx 加密 支持,直接开启即可

tips: 我没有为 frp 开启加密,因为已经使用了 frp auth 鉴权,并且我的 frp 的内网穿透流量本身也是加密过的。我认为没有必要再加密一次降低性能。

代理服务 Trojan-go

trojan-go 是 trojan 的变体。

为了伪装流量,trojan-go 需要一个伪装服务器。

Because typically a trojan server is to be assumed to be an HTTPS server, the listening socket is always a TLS socket. After performing TLS handshake, if the trojan server decides that the traffic is “other protocols”, it opens a tunnel between a preset endpoint (by default it is 127.0.0.1:80, the local HTTP server) to the client so the preset endpoint takes the control of the decrypted TLS traffic.

这里使用 Nginx ,我配置返回404。

我额外部署了个人 blog ,和其它项目。这些站点共用同一个通配符证书,使用 Nginx 反向代理 stream 分流。

BBR

BBR 是一种 Google 开发的 TCP 拥塞控制算法。作用有两个:

  1. 在有一定丢包率的网络链路上充分利用带宽。
  2. 降低网络链路上的 buffer 占用率,从而降低延迟。

总而言之,在网络环境较差时,显著提高网络速度、稳定性。

BBR 一键安装脚本

代理客户端

客户端选择支持 Trojan 的软件,我使用的是 Clash Verge Rev(MiHoMo 内核,clash 的继任者)。

1
2
3
4
5
6
7
proxies:
  - name: # 名称,proxy-groups 中使用,具体看 Clash 配置文档
    type: trojan
    udp: true # 支持 UDP
    server: trojan-go.steel-shadow.me # 使用了 SSL/TLS 证书的服务器位置
    port: 443
    password: # 前面配置的 password

邮件服务

我使用 docker mailserver 搭建邮件服务。不使用反向代理处理邮件服务,直接开放相应端口:

  • SMTP: 25 587 465
  • IMAP 993

需要注意的是,许多 VPS 服务商不开放 25 端口的出站流量,也就是说,无法直接使用服务器发送邮件。

要解决这个问题,只能使用 relay 转发邮件,使用 465 或者 587 端口,先将邮件发送给 relay 邮件服务器,再由它通过 25 端口代发。

我本来用 azure 的邮件转发服务,捣鼓了一下午,还是没配成。可能 azure 更适合大企业用户吧,反正我是被折磨得不行(support要额外付费)。

relay:私人邮箱

可以选用 gmail 的转发(SMTP服务的密码是应用专用密码,需要单独申请)。还可以将自己的邮件别名添加到 gmail(可选),gmail 设置中 send mail as。当然,选用QQ、163等其它邮箱都可以,只要配置好服务器的SMTP设置即可。

这些个人邮箱有一个问题,发出的邮件会显示由“你邮箱@域名(gmail/QQ 代表)”,这是因为邮件头的 From 和 Sender 不一致。这些 SMTP 服务器在 relay 邮件时,将 From 设置为 relay 的 SMTP 用户名。如果不想看到这种提示,可以尝试换用专门的邮件发送服务。

relay:专用邮件服务

github student 可以使用 mailgun 转发。

mailgun 实际上提供了一整个邮箱服务器,但是这里我们只使用它的 SMTP relay 功能。

使用 DNS txt 记录配置 DKIM SPF 后,即可开始使用 SMTP relay 服务。

TODO 家用主机服务器改造

如上所述,我目前只有海外的几台服务器,并且性能都及其低,1核cpu+1GB内存。我的家里还有一台闲置的台式机,于是我打算将其改造为一台服务器。为此,首先要解决网络问题。

我的家庭网络是移动宽带。安装网络时运营商装的光猫设置了防火墙和 NAT,我的网络也没有默认开启IPV6。

  1. 打客服电话,要网关的超级管理员账号和密码(客服可能不知道,会给你宽带师傅的联系方式)。

  2. 光猫改桥接模式。登录超管即可修改。教程此处略。

  3. 修改网络拓扑。我家里为了覆盖 WIFI 范围,装了 2 台路由器,原先都直接连接网关。如果把光猫设置为桥接并保持原拓扑结构不变,那么就只有1个路由器能拨号上网(只有一个账号)。我尝试单号多拨,无果。那就只能让 A 路由器连接光猫拨号,再让 B 路由器的 WAN 口连接 A 的 LAN 口。现在问题来了,当初装修房子的时候,就没有考虑过我这个需求,墙里的网线都已经铺好了。2个路由器在不同的房间,无法相互连线!而我发现这个问题的时候,距离我开学返校只有1天了,至此,我的家庭主机服务器改造计划就宣告失败了(暂时)。

  4. 路由器 openwrt 硬件刷机。时间不足,也没有仔细研究。