mirror of
https://github.com/sipeed/NanoKVM.git
synced 2026-09-11 00:22:56 -05:00
fix: preserve loopback access for host configuration
- Keep internal loopback HTTP APIs reachable when the server is bound to a specific non-loopback host by adding a dedicated 127.0.0.1 listener. - Move listener address helpers into utils and normalize HTTPS redirect hosts so IPv6 request hosts are not double-bracketed.
This commit is contained in:
@@ -1,9 +1,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strconv"
|
||||
@@ -73,18 +71,33 @@ func run() {
|
||||
|
||||
router.Init(r)
|
||||
|
||||
httpAddr := listenAddr(conf.Host, strconv.Itoa(conf.Port.Http))
|
||||
httpAddr := utils.ListenAddr(conf.Host, strconv.Itoa(conf.Port.Http))
|
||||
loopbackHTTPAddr := utils.ListenAddr("127.0.0.1", strconv.Itoa(conf.Port.Http))
|
||||
needsLoopbackHTTP := utils.NeedsDedicatedLoopbackListener(conf.Host)
|
||||
|
||||
if conf.Proto == "https" {
|
||||
httpsPortStr := strconv.Itoa(conf.Port.Https)
|
||||
|
||||
go func() {
|
||||
err := r.RunTLS(listenAddr(conf.Host, httpsPortStr), conf.Cert.Crt, conf.Cert.Key)
|
||||
err := r.RunTLS(utils.ListenAddr(conf.Host, httpsPortStr), conf.Cert.Crt, conf.Cert.Key)
|
||||
if err != nil {
|
||||
panic("start https server failed")
|
||||
}
|
||||
}()
|
||||
|
||||
if needsLoopbackHTTP {
|
||||
go func() {
|
||||
if err := middleware.ListenAndServeLoopbackHTTPRedirect(
|
||||
loopbackHTTPAddr,
|
||||
httpsPortStr,
|
||||
r,
|
||||
router.LoopbackHTTPAllowedPaths()...,
|
||||
); err != nil {
|
||||
panic("start loopback http server failed")
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
if err := middleware.ListenAndServeLoopbackHTTPRedirect(
|
||||
httpAddr,
|
||||
httpsPortStr,
|
||||
@@ -94,6 +107,14 @@ func run() {
|
||||
panic("start http server failed")
|
||||
}
|
||||
} else {
|
||||
if needsLoopbackHTTP {
|
||||
go func() {
|
||||
if err := r.Run(loopbackHTTPAddr); err != nil {
|
||||
panic("start loopback http server failed")
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
if err := r.Run(httpAddr); err != nil {
|
||||
panic("start http server failed")
|
||||
}
|
||||
@@ -103,10 +124,3 @@ func run() {
|
||||
func dispose() {
|
||||
common.GetKvmVision().Close()
|
||||
}
|
||||
|
||||
func listenAddr(host string, port string) string {
|
||||
if host == "" {
|
||||
return fmt.Sprintf(":%s", port)
|
||||
}
|
||||
return net.JoinHostPort(host, port)
|
||||
}
|
||||
|
||||
@@ -34,22 +34,29 @@ func ListenAndServeLoopbackHTTPRedirect(
|
||||
return
|
||||
}
|
||||
|
||||
host := req.Host
|
||||
if h, _, err := net.SplitHostPort(host); err == nil {
|
||||
host = h
|
||||
}
|
||||
|
||||
if strings.Contains(host, ":") {
|
||||
host = "[" + host + "]"
|
||||
}
|
||||
if httpsPort != "443" {
|
||||
host += ":" + httpsPort
|
||||
}
|
||||
|
||||
http.Redirect(w, req, "https://"+host+req.URL.RequestURI(), http.StatusTemporaryRedirect)
|
||||
http.Redirect(w, req, "https://"+redirectHost(req.Host, httpsPort)+req.URL.RequestURI(), http.StatusTemporaryRedirect)
|
||||
}))
|
||||
}
|
||||
|
||||
func redirectHost(requestHost string, httpsPort string) string {
|
||||
host := requestHost
|
||||
if h, _, err := net.SplitHostPort(requestHost); err == nil {
|
||||
host = h
|
||||
} else if strings.HasPrefix(host, "[") && strings.HasSuffix(host, "]") {
|
||||
host = strings.TrimPrefix(strings.TrimSuffix(host, "]"), "[")
|
||||
}
|
||||
|
||||
if httpsPort != "443" {
|
||||
return net.JoinHostPort(host, httpsPort)
|
||||
}
|
||||
|
||||
if strings.Contains(host, ":") && !strings.HasPrefix(host, "[") && !strings.HasSuffix(host, "]") {
|
||||
return "[" + host + "]"
|
||||
}
|
||||
|
||||
return host
|
||||
}
|
||||
|
||||
func allowByLoopbackInternalToken(req *http.Request) bool {
|
||||
return req != nil && isLoopbackRemote(req.RemoteAddr) && hasValidLoopbackHTTPToken(req)
|
||||
}
|
||||
|
||||
28
server/utils/listener.go
Normal file
28
server/utils/listener.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func ListenAddr(host string, port string) string {
|
||||
if host == "" {
|
||||
return fmt.Sprintf(":%s", port)
|
||||
}
|
||||
return net.JoinHostPort(host, port)
|
||||
}
|
||||
|
||||
func NeedsDedicatedLoopbackListener(host string) bool {
|
||||
host = strings.TrimSpace(strings.Trim(host, "[]"))
|
||||
if host == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
ip := net.ParseIP(host)
|
||||
if ip == nil {
|
||||
return !strings.EqualFold(host, "localhost")
|
||||
}
|
||||
|
||||
return !ip.IsLoopback() && !ip.IsUnspecified()
|
||||
}
|
||||
Reference in New Issue
Block a user