解决 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。

解决方法:

  1. 降低提供订阅链接服务器的 TLS 版本,但是需要知道的是 TLS1.0 以及不再安全,降低有风险

  2. 本地开启代理把订阅链接转为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 代码。

Subscribe to 小机场
Receive the latest updates directly to your inbox.
Mint this entry as an NFT to add it to your collection.
Verification
This entry has been permanently stored onchain and signed by its creator.