测试已启用 HTTPS 但尚未配置域名的站点

2025-01-17#HTTPS#SNI

在搭建好Web站点并配置了SSL证书后,由于某些原因,还不能将正式的域名指向该该站。比如正在进行服务器迁移,必须确保新服务器一切正常,并在特定的时间才能进行切换。此时,该如何测试站点除了域名之外,已经配置正确?最显而易见的方式,其实就是修改域名解析。既然无法修改公共的DNS记录,那么可以修改本地的 hosts 文件;除此之外,还可以使用 cURL 或者编程实现。

修改本地 hosts 文件设置 IP 🔗

不同系统的 hosts 文件位置不同。在 macOS 和 Linux,它位于 /etc/hosts;而在 Windows系统,它位于 c:\Windows\System32\Drivers\etc\hosts。无论在哪种系统,都需要管理员权限才可以修改。比如记录为:

10.20.30.1 myapp.local

修改之后,重启浏览器即可测试站点。如果在使用 Chrome 浏览器,那么可以在 Developer Tools 的 Network 选项卡显示 Remote Address;这样在访问站点时,可进一步确认域名指向正确。

通过 SNI 访问服务器 🔗

对于 HTTP 请求,通常我们可以使用 IP 地址访问,并且设置 Host 请求头,服务器即可判断客户端请求的域名。但是,对于 HTTPS 的站点,在处理请求之前,客户端会与服务器建立 TLS 连接。在建立连接的过程中,客户端就会检查服务器的证书。此时服务器证书与请求的IP或者其他域名不配置,证书校验就会失败。因此,设置 Host 请求头是没有用的。

为此,客户端需要使用 SNI,告诉服务器请求的域名。

SNI 是 “Server Name Indication” 的缩写,即服务器名称指示 ,是一种 TLS(Transport Layer Security,传输层安全协议,其前身是 SSL,Secure Sockets Layer)扩展,用于在建立 TLS 连接时,客户端向服务器发送它想要访问的主机名。

以下示例中,假定站点的正式域名为 myapp.local,而站点暂时的域名为 myapp.cdn.local。我们最终期望使用前者访问站点,但目前前者并未指向站点;而 myapp.cdn.local 已经指向站点。

使用 cURL 设置 SNI 🔗

使用 --connect-to 参数即可:

curl --connect-to myapp.local:443:myapp.cdn.local:443 https://myapp.local

另一种方式使用 --resolve 参数。

使用程序设置 SNI 🔗

想在程序中使用 SNI,那么需要一些特殊的设置。我尝试使用 Python 实现类似 curl 的效果,没搞定;但是使用 Go 语言,使用标准库即可正常访问站点。代码如下:

package main

import (
	"crypto/tls"
	"log"
	"net/http"
	"net/http/httputil"
)

func main() {
	requestURL := "https://mapp.cdn.local"
	serverName := "myapp.local"

	transport := &http.Transport{
		TLSClientConfig: &tls.Config{
			ServerName: serverName,
		},
	}

	client := &http.Client{
		Transport: transport,
	}

	resp, err := client.Get(requestURL)
	if err != nil {
		log.Fatalf("Failed to make request: %v", err)
	}
	defer resp.Body.Close()

	dump, err := httputil.DumpResponse(resp, true)
	if err != nil {
		log.Fatalf("Failed to dump response: %v", err)
	}
	log.Printf("%s", dump)
}

参考资料 🔗


加载中...