This commit is contained in:
2025-03-15 10:17:07 +00:00
parent 1a53a9a8f3
commit 78f5fbf51a
24 changed files with 2915 additions and 282 deletions

View File

@@ -0,0 +1,152 @@
package main
import (
"crypto/tls"
"flag"
"fmt"
"log"
"net"
"net/http"
"os"
"os/signal"
"syscall"
"github.com/darkit/goproxy"
"github.com/darkit/goproxy/config"
)
func main() {
// 解析命令行参数
var (
listenAddr = flag.String("listen", ":443", "HTTPS监听地址")
httpAddr = flag.String("http", ":80", "HTTP监听地址用于重定向到HTTPS")
targetAddr = flag.String("target", "http://localhost:8080", "目标服务地址")
certFile = flag.String("cert", "server.crt", "TLS证书文件")
keyFile = flag.String("key", "server.key", "TLS私钥文件")
autoRedirect = flag.Bool("redirect", true, "自动将HTTP请求重定向到HTTPS")
insecureSkipVerify = flag.Bool("insecure", false, "跳过目标HTTPS验证")
)
flag.Parse()
// 检查证书和私钥文件
if !fileExists(*certFile) || !fileExists(*keyFile) {
log.Printf("证书或私钥文件不存在: %s, %s", *certFile, *keyFile)
if *autoRedirect {
log.Printf("将只启动HTTP服务")
} else {
log.Fatalf("无法启动HTTPS服务请提供有效的证书和私钥文件")
}
}
// 创建配置
cfg := config.DefaultConfig()
// 配置反向代理
cfg.ReverseProxy = true // 启用反向代理模式
cfg.ListenAddr = *listenAddr // HTTPS监听地址
cfg.TargetAddr = *targetAddr // 目标地址
cfg.DecryptHTTPS = true // 启用HTTPS
cfg.TLSCert = *certFile // 证书文件
cfg.TLSKey = *keyFile // 私钥文件
cfg.PreserveClientIP = true // 保留客户端IP
cfg.AddXForwardedFor = true // 添加X-Forwarded-For头
cfg.InsecureSkipVerify = *insecureSkipVerify // 是否跳过目标HTTPS验证
// 创建代理实例
proxy := goproxy.New(&goproxy.Options{
Config: cfg,
})
// 创建HTTPS服务器
httpsServer := &http.Server{
Addr: *listenAddr,
Handler: proxy,
TLSConfig: &tls.Config{
MinVersion: tls.VersionTLS12,
},
}
// 创建HTTP重定向服务器
var httpServer *http.Server
if *autoRedirect {
httpServer = &http.Server{
Addr: *httpAddr,
Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// 构建重定向URL
host := r.Host
// 如果Host包含端口去除端口
if h, _, err := net.SplitHostPort(host); err == nil {
host = h
}
// 构建HTTPS URL
target := "https://" + host
// 如果HTTPS端口不是443添加端口
if *listenAddr != ":443" {
_, port, _ := net.SplitHostPort(*listenAddr)
if port != "" && port != "443" {
target = "https://" + host + ":" + port
}
}
// 添加路径和查询参数
target += r.URL.Path
if r.URL.RawQuery != "" {
target += "?" + r.URL.RawQuery
}
// 重定向
http.Redirect(w, r, target, http.StatusMovedPermanently)
}),
}
}
// 优雅退出
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
// 启动HTTPS服务器
if fileExists(*certFile) && fileExists(*keyFile) {
go func() {
fmt.Printf("HTTPS反向代理启动在 %s转发到 %s\n", *listenAddr, *targetAddr)
if err := httpsServer.ListenAndServeTLS(*certFile, *keyFile); err != nil && err != http.ErrServerClosed {
log.Printf("HTTPS服务器启动失败: %v\n", err)
}
}()
}
// 启动HTTP重定向服务器
if *autoRedirect && httpServer != nil {
go func() {
fmt.Printf("HTTP重定向服务启动在 %s\n", *httpAddr)
if err := httpServer.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Printf("HTTP服务器启动失败: %v\n", err)
}
}()
}
// 等待退出信号
<-quit
fmt.Println("服务器正在关闭...")
// 关闭服务器
if httpServer != nil {
if err := httpServer.Close(); err != nil {
log.Printf("HTTP服务器关闭失败: %v\n", err)
}
}
if fileExists(*certFile) && fileExists(*keyFile) {
if err := httpsServer.Close(); err != nil {
log.Printf("HTTPS服务器关闭失败: %v\n", err)
}
}
fmt.Println("服务器已关闭")
}
// 检查文件是否存在
func fileExists(filename string) bool {
info, err := os.Stat(filename)
if os.IsNotExist(err) {
return false
}
return !info.IsDir()
}