diff --git a/server/admin/api_base.go b/server/admin/api_base.go index 42dfd01..61c81a6 100644 --- a/server/admin/api_base.go +++ b/server/admin/api_base.go @@ -67,6 +67,14 @@ func Login(w http.ResponseWriter, r *http.Request) { data["admin_user"] = adminUser data["expires_at"] = expiresAt + ck := &http.Cookie{ + Name: "jwt", + Value: tokenString, + Path: "/", + HttpOnly: true, + } + http.SetCookie(w, ck) + RespSucess(w, data) } @@ -76,6 +84,8 @@ func authMiddleware(next http.Handler) http.Handler { w.Header().Set("Access-Control-Allow-Methods", "GET,POST,OPTIONS") w.Header().Set("Access-Control-Allow-Headers", "*") if r.Method == http.MethodOptions { + // 正式环境不支持 OPTIONS + w.WriteHeader(http.StatusForbidden) return } diff --git a/server/admin/server.go b/server/admin/server.go index 3cabb99..b162755 100644 --- a/server/admin/server.go +++ b/server/admin/server.go @@ -10,6 +10,7 @@ import ( "github.com/arl/statsviz" "github.com/bjdgyc/anylink/base" "github.com/bjdgyc/anylink/dbdata" + "github.com/bjdgyc/anylink/pkg/utils" "github.com/gorilla/handlers" "github.com/gorilla/mux" ) @@ -20,6 +21,13 @@ var UiData embed.FS func StartAdmin() { r := mux.NewRouter() + // 所有路由添加安全头 + r.Use(func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + utils.SetSecureHeader(w) + next.ServeHTTP(w, req) + }) + }) r.Use(authMiddleware) r.Use(handlers.CompressHandler) diff --git a/server/handler/link_auth.go b/server/handler/link_auth.go index 2e9bf8f..ca43bdd 100644 --- a/server/handler/link_auth.go +++ b/server/handler/link_auth.go @@ -49,7 +49,7 @@ func LinkAuth(w http.ResponseWriter, r *http.Request) { return } // fmt.Printf("%+v \n", cr) - setCommonHeader(w) + // setCommonHeader(w) if cr.Type == "logout" { // 退出删除session信息 if cr.SessionToken != "" { diff --git a/server/handler/link_base.go b/server/handler/link_base.go index 7581bcc..48e2258 100644 --- a/server/handler/link_base.go +++ b/server/handler/link_base.go @@ -3,7 +3,6 @@ package handler import ( "encoding/xml" "log" - "net/http" "os/exec" ) @@ -42,28 +41,6 @@ type macAddressList struct { MacAddress string `xml:"mac-address"` } -func setCommonHeader(w http.ResponseWriter) { - // Content-Length Date 默认已经存在 - w.Header().Set("Server", "AnyLinkOpenSource") - w.Header().Set("Content-Type", "text/html; charset=utf-8") - w.Header().Set("Cache-Control", "no-store,no-cache") - w.Header().Set("Pragma", "no-cache") - w.Header().Set("Transfer-Encoding", "chunked") - w.Header().Set("Connection", "keep-alive") - w.Header().Set("X-Frame-Options", "deny") - w.Header().Set("X-Content-Type-Options", "nosniff") - w.Header().Set("Content-Security-Policy", "default-src 'none'") - w.Header().Set("X-Permitted-Cross-Domain-Policies", "none") - w.Header().Set("Referrer-Policy", "no-referrer") - w.Header().Set("Clear-Site-Data", "cache,cookies,storage") - w.Header().Set("Cross-Origin-Embedder-Policy", "require-corp") - w.Header().Set("Cross-Origin-Opener-Policy", "same-origin") - w.Header().Set("Cross-Origin-Resource-Policy", "same-origin") - w.Header().Set("X-XSS-Protection", "0") - w.Header().Set("X-Aggregate-Auth", "1") - w.Header().Set("Strict-Transport-Security", "max-age=31536000; includeSubDomains") -} - func execCmd(cmdStrs []string) error { for _, cmdStr := range cmdStrs { cmd := exec.Command("sh", "-c", cmdStr) diff --git a/server/handler/link_home.go b/server/handler/link_home.go index a2dc30b..066e6f1 100644 --- a/server/handler/link_home.go +++ b/server/handler/link_home.go @@ -13,7 +13,7 @@ func LinkHome(w http.ResponseWriter, r *http.Request) { // fmt.Println(r.RemoteAddr) // hu, _ := httputil.DumpRequest(r, true) // fmt.Println("DumpHome: ", string(hu)) - w.Header().Set("Server", "AnyLinkOpenSource") + w.Header().Set("Content-Type", "text/html; charset=utf-8") connection := strings.ToLower(r.Header.Get("Connection")) userAgent := strings.ToLower(r.UserAgent()) if connection == "close" && (strings.Contains(userAgent, "anyconnect") || strings.Contains(userAgent, "openconnect")) { diff --git a/server/handler/server.go b/server/handler/server.go index 34fd016..06d72d5 100644 --- a/server/handler/server.go +++ b/server/handler/server.go @@ -12,6 +12,7 @@ import ( "github.com/bjdgyc/anylink/base" "github.com/bjdgyc/anylink/dbdata" + "github.com/bjdgyc/anylink/pkg/utils" "github.com/gorilla/mux" "github.com/pires/go-proxyproto" ) @@ -86,6 +87,14 @@ func startTls() { func initRoute() http.Handler { r := mux.NewRouter() + // 所有路由添加安全头 + r.Use(func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + utils.SetSecureHeader(w) + next.ServeHTTP(w, req) + }) + }) + r.HandleFunc("/", LinkHome).Methods(http.MethodGet) r.HandleFunc("/", LinkAuth).Methods(http.MethodPost) r.HandleFunc("/CSCOSSLC/tunnel", LinkTunnel).Methods(http.MethodConnect) diff --git a/server/pkg/utils/secure_header.go b/server/pkg/utils/secure_header.go new file mode 100644 index 0000000..a0a3b31 --- /dev/null +++ b/server/pkg/utils/secure_header.go @@ -0,0 +1,27 @@ +package utils + +import "net/http" + +// 设置安全的header头 +func SetSecureHeader(w http.ResponseWriter) { + // Content-Length Date 默认已经存在 + w.Header().Set("Server", "AnyLinkOpenSource") + // w.Header().Set("Content-Type", "text/html; charset=utf-8") + w.Header().Set("Cache-Control", "no-store,no-cache") + w.Header().Set("Pragma", "no-cache") + w.Header().Set("Transfer-Encoding", "chunked") + w.Header().Set("Connection", "keep-alive") + w.Header().Set("X-Frame-Options", "deny") + w.Header().Set("X-Content-Type-Options", "nosniff") + w.Header().Set("X-Download-Options", "noopen") + w.Header().Set("Content-Security-Policy", "default-src 'self' 'unsafe-inline'") + w.Header().Set("X-Permitted-Cross-Domain-Policies", "none") + w.Header().Set("Referrer-Policy", "no-referrer") + // w.Header().Set("Clear-Site-Data", "cache,cookies,storage") + w.Header().Set("Cross-Origin-Embedder-Policy", "require-corp") + w.Header().Set("Cross-Origin-Opener-Policy", "same-origin") + w.Header().Set("Cross-Origin-Resource-Policy", "same-origin") + w.Header().Set("X-XSS-Protection", "0") + w.Header().Set("X-Aggregate-Auth", "1") + w.Header().Set("Strict-Transport-Security", "max-age=31536000") +}