package handler import ( "crypto/tls" "fmt" "io" "log" "net" "net/http" "os" "time" "github.com/bjdgyc/anylink/base" "github.com/bjdgyc/anylink/dbdata" "github.com/gorilla/mux" "github.com/pires/go-proxyproto" ) func startTls() { var ( err error addr = base.Cfg.ServerAddr ln net.Listener ) // 判断证书文件 // _, err = os.Stat(certFile) // if errors.Is(err, os.ErrNotExist) { // // 自动生成证书 // certs[0], err = selfsign.GenerateSelfSignedWithDNS("vpn.anylink") // } else { // // 使用自定义证书 // certs[0], err = tls.LoadX509KeyPair(certFile, keyFile) // } // 修复 CVE-2016-2183 // https://segmentfault.com/a/1190000038486901 // nmap -sV --script ssl-enum-ciphers -p 443 www.example.com cipherSuites := tls.CipherSuites() selectedCipherSuites := make([]uint16, 0, len(cipherSuites)) for _, s := range cipherSuites { selectedCipherSuites = append(selectedCipherSuites, s.ID) } // 设置tls信息 tlsConfig := &tls.Config{ NextProtos: []string{"http/1.1"}, MinVersion: tls.VersionTLS12, CipherSuites: selectedCipherSuites, GetCertificate: func(chi *tls.ClientHelloInfo) (*tls.Certificate, error) { base.Trace("GetCertificate", chi.ServerName) return dbdata.GetCertificateBySNI(chi.ServerName) }, // InsecureSkipVerify: true, } srv := &http.Server{ Addr: addr, Handler: initRoute(), TLSConfig: tlsConfig, ErrorLog: base.GetBaseLog(), ReadTimeout: 60 * time.Second, WriteTimeout: 60 * time.Second, } ln, err = net.Listen("tcp", addr) if err != nil { log.Fatal(err) } defer ln.Close() if base.Cfg.ProxyProtocol { ln = &proxyproto.Listener{ Listener: ln, ReadHeaderTimeout: 30 * time.Second, } } base.Info("listen server", addr) err = srv.ServeTLS(ln, "", "") if err != nil { base.Fatal(err) } } func initRoute() http.Handler { r := mux.NewRouter() r.HandleFunc("/", LinkHome).Methods(http.MethodGet) r.HandleFunc("/", LinkAuth).Methods(http.MethodPost) r.HandleFunc("/CSCOSSLC/tunnel", LinkTunnel).Methods(http.MethodConnect) r.HandleFunc("/otp_qr", LinkOtpQr).Methods(http.MethodGet) r.HandleFunc("/profile.xml", func(w http.ResponseWriter, r *http.Request) { b, _ := os.ReadFile(base.Cfg.Profile) w.Write(b) }).Methods(http.MethodGet) r.PathPrefix("/files/").Handler( http.StripPrefix("/files/", http.FileServer(http.Dir(base.Cfg.FilesPath)), ), ) // 健康检测 r.HandleFunc("/status", func(w http.ResponseWriter, r *http.Request) { io.WriteString(w, "ok") }).Methods(http.MethodGet) r.NotFoundHandler = http.HandlerFunc(notFound) return r } func notFound(w http.ResponseWriter, r *http.Request) { // fmt.Println(r.RemoteAddr) // hu, _ := httputil.DumpRequest(r, true) // fmt.Println("NotFound: ", string(hu)) w.WriteHeader(http.StatusNotFound) fmt.Fprintln(w, "404 page not found") }