mirror of
https://github.com/Gouryella/drip.git
synced 2026-03-02 16:20:57 +00:00
feat(server): Adds server configuration management commands and metric monitoring functionality.
- Add a new `server config` command to display server configuration. - Supports displaying the full token via the --full flag. - Add the metrics-token configuration option for monitoring access control. - Integrate Prometheus metrics monitoring system - Add the /metrics endpoint to provide monitoring data in Prometheus format. - Add detailed metric collection for tunnels, connections, traffic, etc. - Add a link to the metrics endpoint on the homepage refactor: Refactor the token display logic to support full display options. - Refactor the token mask logic in the configuration display - Supports controlling the token display method via the configFull flag. build: Update dependency versions - Updated github.com/spf13/cobra from v1.10.1 to v1.10.2 - Updated golang.org/x/crypto from v0.45.0 to v0.46.0 - Updated golang.org/x/net from v0.47.0 to v0.48.0 - Update golang.org/x/sys from v0.38.0 to v0.39.0 - Added several new indirect dependency packages, including Prometheus-related components. - Update the versions of several existing dependency packages.
This commit is contained in:
@@ -20,6 +20,7 @@ import (
|
||||
"drip/internal/shared/pool"
|
||||
"drip/internal/shared/protocol"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
@@ -33,18 +34,20 @@ var bufioReaderPool = sync.Pool{
|
||||
const openStreamTimeout = 3 * time.Second
|
||||
|
||||
type Handler struct {
|
||||
manager *tunnel.Manager
|
||||
logger *zap.Logger
|
||||
domain string
|
||||
authToken string
|
||||
manager *tunnel.Manager
|
||||
logger *zap.Logger
|
||||
domain string
|
||||
authToken string
|
||||
metricsToken string
|
||||
}
|
||||
|
||||
func NewHandler(manager *tunnel.Manager, logger *zap.Logger, domain string, authToken string) *Handler {
|
||||
func NewHandler(manager *tunnel.Manager, logger *zap.Logger, domain string, authToken string, metricsToken string) *Handler {
|
||||
return &Handler{
|
||||
manager: manager,
|
||||
logger: logger,
|
||||
domain: domain,
|
||||
authToken: authToken,
|
||||
manager: manager,
|
||||
logger: logger,
|
||||
domain: domain,
|
||||
authToken: authToken,
|
||||
metricsToken: metricsToken,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,6 +60,10 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
h.serveStats(w, r)
|
||||
return
|
||||
}
|
||||
if r.URL.Path == "/metrics" {
|
||||
h.serveMetrics(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
subdomain := h.extractSubdomain(r.Host)
|
||||
if subdomain == "" {
|
||||
@@ -346,7 +353,7 @@ func (h *Handler) serveHomePage(w http.ResponseWriter, r *http.Request) {
|
||||
<code>drip http 3000</code><br><br>
|
||||
<code>drip https 443</code><br><br>
|
||||
<code>drip tcp 5432</code>
|
||||
<p><a href="/health">Health Check</a> | <a href="/stats">Statistics</a></p>
|
||||
<p><a href="/health">Health Check</a> | <a href="/stats">Statistics</a> | <a href="/metrics">Prometheus Metrics</a></p>
|
||||
</body>
|
||||
</html>`
|
||||
|
||||
@@ -375,7 +382,7 @@ func (h *Handler) serveHealth(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func (h *Handler) serveStats(w http.ResponseWriter, r *http.Request) {
|
||||
if h.authToken != "" {
|
||||
if h.metricsToken != "" {
|
||||
// Only accept token via Authorization header (Bearer token)
|
||||
// URL query parameters are insecure (logged, cached, visible in browser history)
|
||||
var token string
|
||||
@@ -384,9 +391,9 @@ func (h *Handler) serveStats(w http.ResponseWriter, r *http.Request) {
|
||||
token = strings.TrimPrefix(authHeader, "Bearer ")
|
||||
}
|
||||
|
||||
if token != h.authToken {
|
||||
if token != h.metricsToken {
|
||||
w.Header().Set("WWW-Authenticate", `Bearer realm="stats"`)
|
||||
http.Error(w, "Unauthorized: provide token via 'Authorization: Bearer <token>' header", http.StatusUnauthorized)
|
||||
http.Error(w, "Unauthorized: provide metrics token via 'Authorization: Bearer <token>' header", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -426,6 +433,26 @@ func (h *Handler) serveStats(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write(data)
|
||||
}
|
||||
|
||||
func (h *Handler) serveMetrics(w http.ResponseWriter, r *http.Request) {
|
||||
if h.metricsToken != "" {
|
||||
// Only accept token via Authorization header (Bearer token)
|
||||
var token string
|
||||
authHeader := r.Header.Get("Authorization")
|
||||
if strings.HasPrefix(authHeader, "Bearer ") {
|
||||
token = strings.TrimPrefix(authHeader, "Bearer ")
|
||||
}
|
||||
|
||||
if token != h.metricsToken {
|
||||
w.Header().Set("WWW-Authenticate", `Bearer realm="metrics"`)
|
||||
http.Error(w, "Unauthorized: provide metrics token via 'Authorization: Bearer <token>' header", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Serve Prometheus metrics
|
||||
promhttp.Handler().ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
type bufferedReadWriteCloser struct {
|
||||
*bufio.Reader
|
||||
net.Conn
|
||||
|
||||
Reference in New Issue
Block a user