找回密码
 立即注册
首页 业界区 业界 如何不购买域名在云服务器上搭建HTTPS服务 ...

如何不购买域名在云服务器上搭建HTTPS服务

豌笆 4 天前
step 1: 事前准备

step 1.1: 云服务器

购买一台云服务器(带有弹性公网IP),阿里云,腾讯云,华为云什么的都可以。
选择ubuntu系统
开放安全组策略(把你需要的协议/端口暴露出来):

  • TCP:22:ssh
  • TCP:80:HTTP
  • TCP:443:HTTPS
  • ICMP:ping
这里我们强烈不推荐暴露所有的端口,根据权限最小化原则,仅应该暴露你需要的端口
1.png

step 1.2: Caddy

官方文档:https://caddy2.dengxiaolong.com/docs/install
仓库地址:https://github.com/caddyserver/caddy
Caddy是一个强大的反向代理工具,当然也可以被用作站点服务器。本文使用Caddy作为主要配置工具。
安装脚本:
  1. sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
  2. curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
  3. curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
  4. sudo apt update
  5. sudo apt install caddy
复制代码
安装完成后,应当显示:
  1. ~# caddy --version
  2. v2.9.1
复制代码
step 1.3: Apifox

这里安利一波Apifox,可以非常方便的进行接口管理,构造自动化测试等工作,支持RESTful风格的API等。
界面简洁优雅,使用非常方便,并且对于个人开发者来说完全免费,符合我个人的审美观念。
2.png

step 2:获取证书

众所周知,HTTPS相比于HTTP,其最大的特性就是使用了SSL/TLS对数据进行加密。
我们依赖证书链使用TLS在客户端和服务器之间建立可信连接,具体原理比较复杂这里不多解释。
一般来说,证书是要由CA来进行签发,如果你购买了域名,自然会获取对应的证书。
但是,此处我们没有购买形似example.com的域名,而是类似149.33.138.14这样的裸露公网IP,这就需要我们提前获取对于裸IP的证书支持。
但遗憾的是,绝大部分针对裸IP的证书都需要收费。
毕竟,奇迹和魔法可不是免费的,https和域名当然也不是,大家都是穷人,尽量还是少花点钱。
step 2.1 获取免费证书

所幸,这里有一个方法,可以对裸IP获取90天的免费证书,到期相同方法续期即可
该服务由zeroSSL提供,我们使用的Caddy也是zeroSSL下的项目之一
这个教程写的还挺详细的,这里就不抄过来了:https://www.landiannews.com/archives/93605.html
但是,这里我们需要保证IP地址+文件夹+文件能够访问,这里我们需要使用Caddy先建立一个最简单的HTTP server,从服务器上获取静态文件
首先查看80端口(http),确保未被监听:
  1. root@hcss-ecs-0ef3:~# sudo lsof -i :80
  2. root@hcss-ecs-0ef3:~#
复制代码
在当前路径下创建Caddyfile(可以理解为配置文件),需要设定为http,file_server支持静态文件访问,/var/www/html为server的根文件目录
  1. http://149.33.138.14 {
  2.     root * /var/www/html
  3.     file_server
  4. }
复制代码
创建.well-known/pki-validation/路径并且将文件拷贝到路径下:
  1. sudo mkdir -p /var/www/html/.well-known/pki-validation
  2. sudo cp /path/to/{filename}.txt /var/www/html/.well-known/pki-validation/
复制代码
caddy的管理端口默认为localhost:2019,如果发现端口被占用,可以通过sudo lsof -i :2019查看是谁占用了
有可能是自动启动的caddy systemd service和手动启动的caddy发生冲突了
这里我们选择手动启动,将service disable掉:
  1. sudo systemctl status caddy
  2. sudo systemctl stop caddy
  3. sudo systemctl status caddy
复制代码
此时应当观察到service状态为Active: inactive (dead),确定port 2019无人监听后可以重新手动启动caddy:
  1. sudo caddy stop
  2. caddy fmt --overwrite
  3. sudo caddy start
复制代码
如果想要更改默认2019端口,可以配置CADDY_ADMIN环境变量,此处不再赘述。
此时再次查看80端口(http),应当已经被监听:
  1. root@hcss-ecs-0ef3:~# sudo lsof -i :80
  2. COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
  3. caddy   65370 root    9u  IPv6 562057      0t0  TCP *:http (LISTEN)
复制代码
此时可以开始验证http server是否能够被访问,查看是否有文件内容:
方法一:curl -X GET http://149.33.138.14/.well-known/pki-validation/{filename}.txt
3.png

方法二:使用Apifox,设置GET方法和request:
4.png

至此,HTTP server设置并验证完毕,返回zeroSSL,点击验证并签发证书,下载文件列表如下:

  • certificate.crt:根节点证书
  • ca_bundle.crt:中间节点证书
  • private.key:密钥
5.png

将以上证书文件上传到服务器中。
step 2.2 搭建https server

step 2.2.1 验证证书合法性

我们将证书存储在/etc/caddy/ssl路径下,统一管理:
  1. sudo mkdir -p /etc/caddy/ssl
  2. sudo cp certificate.crt /etc/caddy/ssl/
  3. sudo cp ca_bundle.crt /etc/caddy/ssl/
  4. sudo cp your_private.key /etc/caddy/ssl/
复制代码
设置权限:
  1. sudo chmod 600 /etc/caddy/ssl/*
  2. sudo chown -R root:root /etc/caddy/ssl/
复制代码
验证证书链是否完成,应当输出OK:
  1. openssl verify -CAfile /etc/caddy/ssl/ca_bundle.crt /etc/caddy/ssl/certificate.crt
复制代码
验证私钥和证书是否匹配,两者输出应当相同:
  1. openssl x509 -noout -modulus -in /etc/caddy/ssl/certificate.crt | openssl md5
  2. openssl rsa -noout -modulus -in /etc/caddy/ssl/private.key | openssl md5
复制代码
出于使用简单的考虑,我们首先拼接证书链:
  1. cat /etc/caddy/ssl/certificate.crt /etc/caddy/ssl/ca_bundle.crt > /etc/caddy/ssl/fullchain.crt
复制代码
再次验证证书内容:
  1. openssl x509 -in /etc/caddy/ssl/fullchain.crt -text -noout
  2. openssl rsa -in /etc/caddy/ssl/private.key -check
复制代码
step 2.2.2 搭建

首先查看443端口(https),确保未被监听:
  1. root@hcss-ecs-0ef3:~# sudo lsof -i :443
  2. root@hcss-ecs-0ef3:~#
复制代码
修改Caddyfile,这是一个最简单的server配置:
  1. {
  2.         default_sni 149.33.138.14
  3. }
  4. https://149.33.138.14 {
  5.         tls /etc/caddy/ssl/fullchain.crt /etc/caddy/ssl/private.key
  6.         respond "Hello, world!" 200
  7. }
复制代码
重新启动caddy服务:
  1. sudo caddy stop
  2. caddy fmt --overwrite
  3. sudo caddy start
复制代码
此时在另一台服务器上运行:
  1. openssl s_client -connect 149.33.138.14:443 -servername 149.33.138.14
复制代码
Verify return code应当返回:0 (ok)
6.png

在另一台服务器上执行curl -kv https://149.33.138.14/,可以查看到连接全过程:
  1. xiao@DESKTOP-S896N2C:~$ curl -kv https://149.33.138.14/
  2. *   Trying 149.33.138.14:443...
  3. * Connected to 149.33.138.14 (149.33.138.14) port 443 (#0)
  4. * ALPN, offering h2
  5. * ALPN, offering http/1.1
  6. * TLSv1.0 (OUT), TLS header, Certificate Status (22):
  7. * TLSv1.3 (OUT), TLS handshake, Client hello (1):
  8. * TLSv1.2 (IN), TLS header, Certificate Status (22):
  9. * TLSv1.3 (IN), TLS handshake, Server hello (2):
  10. * TLSv1.2 (IN), TLS header, Finished (20):
  11. * TLSv1.2 (IN), TLS header, Supplemental data (23):
  12. * TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
  13. * TLSv1.2 (IN), TLS header, Supplemental data (23):
  14. * TLSv1.3 (IN), TLS handshake, Certificate (11):
  15. * TLSv1.2 (IN), TLS header, Supplemental data (23):
  16. * TLSv1.3 (IN), TLS handshake, CERT verify (15):
  17. * TLSv1.2 (IN), TLS header, Supplemental data (23):
  18. * TLSv1.3 (IN), TLS handshake, Finished (20):
  19. * TLSv1.2 (OUT), TLS header, Finished (20):
  20. * TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
  21. * TLSv1.2 (OUT), TLS header, Supplemental data (23):
  22. * TLSv1.3 (OUT), TLS handshake, Finished (20):
  23. * SSL connection using TLSv1.3 / TLS_AES_128_GCM_SHA256
  24. * ALPN, server accepted to use h2
  25. * Server certificate:
  26. *  subject: CN=119.3.178.14
  27. *  start date: Mar 22 00:00:00 2025 GMT
  28. *  expire date: Jun 20 23:59:59 2025 GMT
  29. *  issuer: C=AT; O=ZeroSSL; CN=ZeroSSL RSA Domain Secure Site CA
  30. *  SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
  31. * Using HTTP2, server supports multiplexing
  32. * Connection state changed (HTTP/2 confirmed)
  33. * Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
  34. * TLSv1.2 (OUT), TLS header, Supplemental data (23):
  35. * TLSv1.2 (OUT), TLS header, Supplemental data (23):
  36. * TLSv1.2 (OUT), TLS header, Supplemental data (23):
  37. * Using Stream ID: 1 (easy handle 0x559918bdf9f0)
  38. * TLSv1.2 (OUT), TLS header, Supplemental data (23):
  39. > GET / HTTP/2
  40. > Host: 149.33.138.14
  41. > user-agent: curl/7.81.0
  42. > accept: */*
  43. >
  44. * TLSv1.2 (IN), TLS header, Supplemental data (23):
  45. * TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
  46. * TLSv1.2 (IN), TLS header, Supplemental data (23):
  47. * Connection state changed (MAX_CONCURRENT_STREAMS == 250)!
  48. * TLSv1.2 (OUT), TLS header, Supplemental data (23):
  49. * TLSv1.2 (IN), TLS header, Supplemental data (23):
  50. * TLSv1.2 (IN), TLS header, Supplemental data (23):
  51. * TLSv1.2 (IN), TLS header, Supplemental data (23):
  52. < HTTP/2 200
  53. < alt-svc: h3=":443"; ma=2592000
  54. < content-type: text/plain; charset=utf-8
  55. < server: Caddy
  56. < content-length: 13
  57. < date: Sun, 23 Mar 2025 08:07:31 GMT
  58. <
  59. * TLSv1.2 (IN), TLS header, Supplemental data (23):
  60. * Connection #0 to host 149.33.138.14 left intact
复制代码
通过Apifox访问,能够正确响应输出: Hello, world!:
7.png

在浏览器中也能够正常访问,且没有任何安全问题:
8.png

至此,一个最简单的HTTPS server搭建完成。
过程中会踩的坑和可能遇到的问题

搭建http server时无法访问

表现:
  1. 2025/03/22 18:52:20.394 INFO    http.auto_https server is listening only on the HTTPS port but has no TLS connection policies; adding one to enable TLS{"server_name": "srv0", "https_port": 443}
  2. 2025/03/22 18:52:20.394 INFO    http.auto_https enabling automatic HTTP->HTTPS redirects        {"server_name": "srv0"}
复制代码
原因:http请求被重定向,可能是由于Caddyfile写成了这样:
  1. 119.3.178.14 {
  2.     root * /var/www/html
  3.     file_server
  4. }
复制代码
解决方案:单纯一个caddy已经可以作为http server了,但是会caddy自动重定向http到https,所以需要显式指定http
启动caddy失败

首先看日志,lsof监测对应端口是否被占用。
手动启动的和自动启动的systemd.service是有冲突的,只能启动一个,使用的Caddyfile也不同
https无法访问 Verify return code: 21 (unable to verify the first certificate)

openssl验证出现:Verify return code: 21 (unable to verify the first certificate)
https://github.com/caddyserver/caddy/issues/6344中提出了该问题,是由于client找不到裸ip server的server name(域名则无事)
所以在Caddyfile中一定需要:
  1. {
  2.         default_sni 119.3.178.14
  3. }
复制代码
请求返回 405 The method is not allowed for the requested URL

这个问题大概率是由于混合使用了GET和POST方法,比如获取文件的方式是GET
curl -v 报错 TLSv1.3 (IN), TLS alert, internal error (592):

如果证书链分开,caddy似乎无法以这种方式建立TLS可信连接:
  1.     tls /etc/caddy/ssl/certificate.crt /etc/caddy/ssl/your_private.key {
  2.         ca_root /etc/caddy/ssl/ca_bundle.crt
  3.     }
复制代码
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册