解决 Shadowsocks Windows 在线配置更新失败的问题
Shadowsocks Windows 已经超过一年没有更新,最近在使用 Shadowsocks Windows 的在线配置订阅 SIP008 链接时,提示更新失败。
打开日志显示如下:
2023-10-23 20:51:11.9093|WARN|Shadowsocks.Controller.ShadowsocksController|System.Net.Http.HttpRequestException: 发送请求时出错。 ---> System.Net.WebException: 请求被中止: 未能创建 SSL/TLS 安全通道。
在 System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
在 System.Net.Http.HttpClientHandler.GetResponseCallback(IAsyncResult ar)
--- 内部异常堆栈跟踪的结尾 ---
在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
在 Shadowsocks.Controller.Service.OnlineConfigResolver.<GetOnline>d__0.MoveNext()
--- 引发异常的上一位置中堆栈跟踪的末尾 ---
在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
在 Shadowsocks.Controller.ShadowsocksController.<UpdateOnlineConfigInternal>d__109.MoveNext()
--- 引发异常的上一位置中堆栈跟踪的末尾 ---
在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
在 Shadowsocks.Controller.ShadowsocksController.<UpdateOnlineConfig>d__110.MoveNext()
可以看出是 SSL/TLS 的原因,尝试一下发现是订阅地址开启了强制 TLS1.3,Shadowsocks Windows 支持的 TLS 版本太低。
测试发现 Shadowsocks Windows 获取订阅链接只支持 TLS1.0。
解决方法:
降低提供订阅链接服务器的 TLS 版本,但是需要知道的是 TLS1.0 以及不再安全,降低有风险
本地开启代理把订阅链接转为HTTP,这里使用 Golang 写了一个简单的代理
package main
import (
"fmt"
"log"
"net/http"
"net/http/httputil"
"net/url"
"strings"
)
func handleRequestAndRedirect(res http.ResponseWriter, req *http.Request) {
// 获取原始请求的路径
path := req.URL.Path
if path == "/favicon.ico" {
return
}
parts := strings.SplitN(path, "/", 3)
domain := parts[1]
path = "/" + parts[2]
// 去掉前缀的 "/localhost:8080"
targetURL := "https://" + domain
// 解析目标 URL
target, err := url.Parse(targetURL)
if err != nil {
log.Fatal(err)
}
// 创建反向代理
proxy := httputil.NewSingleHostReverseProxy(target)
// 修改请求头
req.URL.Host = target.Host
req.URL.Scheme = target.Scheme
req.Header.Set("X-Forwarded-Host", req.Header.Get("Host"))
req.Host = target.Host
req.URL.Path = path
// 转发请求至目标 URL
proxy.ServeHTTP(res, req)
}
func main() {
// 创建处理函数
http.HandleFunc("/", handleRequestAndRedirect)
// 启动服务并监听端口
fmt.Println("Starting server on port 10086...")
log.Fatal(http.ListenAndServe("localhost:10086", nil))
}
运行 golang 代码,然后将订阅链接 https:// 替换成 http://localhost:10086/ 然后更新,以后每次更新前都需要先运行 golang 代码。