mirror of
https://github.com/r-smith/deceptifeed.git
synced 2025-11-02 21:23:39 +00:00
Add timeouts to http servers
This commit is contained in:
@@ -25,54 +25,65 @@ import (
|
|||||||
|
|
||||||
// StartHTTP initializes and starts an HTTP honeypot server. This is a fully
|
// StartHTTP initializes and starts an HTTP honeypot server. This is a fully
|
||||||
// functional HTTP server designed to log all incoming requests for analysis.
|
// functional HTTP server designed to log all incoming requests for analysis.
|
||||||
func StartHTTP(srv *config.Server) {
|
func StartHTTP(cfg *config.Server) {
|
||||||
// Get any custom headers, if provided.
|
// Get any custom headers, if provided.
|
||||||
headers := parseCustomHeaders(srv.Banner)
|
headers := parseCustomHeaders(cfg.Banner)
|
||||||
|
|
||||||
// Setup handler.
|
// Setup handler and server config.
|
||||||
mux := http.NewServeMux()
|
mux := http.NewServeMux()
|
||||||
mux.HandleFunc("/", handleConnection(srv, headers))
|
mux.HandleFunc("/", handleConnection(cfg, headers))
|
||||||
|
srv := &http.Server{
|
||||||
|
Addr: ":" + cfg.Port,
|
||||||
|
Handler: mux,
|
||||||
|
ErrorLog: log.New(io.Discard, "", log.LstdFlags),
|
||||||
|
ReadTimeout: 5 * time.Second,
|
||||||
|
WriteTimeout: 10 * time.Second,
|
||||||
|
IdleTimeout: 0,
|
||||||
|
}
|
||||||
|
|
||||||
// Start the HTTP server.
|
// Start the HTTP server.
|
||||||
fmt.Printf("Starting HTTP server on port: %s\n", srv.Port)
|
fmt.Printf("Starting HTTP server on port: %s\n", cfg.Port)
|
||||||
if err := http.ListenAndServe(":"+srv.Port, mux); err != nil {
|
if err := srv.ListenAndServe(); err != nil {
|
||||||
fmt.Fprintln(os.Stderr, "The HTTP server has terminated:", err)
|
fmt.Fprintln(os.Stderr, "The HTTP server has terminated:", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// StartHTTPS initializes and starts an HTTPS honeypot server. This is a fully
|
// StartHTTPS initializes and starts an HTTPS honeypot server. This is a fully
|
||||||
// functional HTTPS server designed to log all incoming requests for analysis.
|
// functional HTTPS server designed to log all incoming requests for analysis.
|
||||||
func StartHTTPS(srv *config.Server) {
|
func StartHTTPS(cfg *config.Server) {
|
||||||
// Get any custom headers, if provided.
|
// Get any custom headers, if provided.
|
||||||
headers := parseCustomHeaders(srv.Banner)
|
headers := parseCustomHeaders(cfg.Banner)
|
||||||
|
|
||||||
// Setup handler and initialize HTTPS config.
|
// Setup handler and initialize HTTPS config.
|
||||||
mux := http.NewServeMux()
|
mux := http.NewServeMux()
|
||||||
mux.HandleFunc("/", handleConnection(srv, headers))
|
mux.HandleFunc("/", handleConnection(cfg, headers))
|
||||||
server := &http.Server{
|
srv := &http.Server{
|
||||||
Addr: ":" + srv.Port,
|
Addr: ":" + cfg.Port,
|
||||||
Handler: mux,
|
Handler: mux,
|
||||||
ErrorLog: log.New(io.Discard, "", log.LstdFlags),
|
ErrorLog: log.New(io.Discard, "", log.LstdFlags),
|
||||||
|
ReadTimeout: 5 * time.Second,
|
||||||
|
WriteTimeout: 10 * time.Second,
|
||||||
|
IdleTimeout: 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the cert and key aren't found, generate a self-signed certificate.
|
// If the cert and key aren't found, generate a self-signed certificate.
|
||||||
if _, err := os.Stat(srv.CertPath); os.IsNotExist(err) {
|
if _, err := os.Stat(cfg.CertPath); os.IsNotExist(err) {
|
||||||
if _, err := os.Stat(srv.KeyPath); os.IsNotExist(err) {
|
if _, err := os.Stat(cfg.KeyPath); os.IsNotExist(err) {
|
||||||
// Generate a self-signed certificate.
|
// Generate a self-signed certificate.
|
||||||
cert, err := generateSelfSignedCert(srv.CertPath, srv.KeyPath)
|
cert, err := generateSelfSignedCert(cfg.CertPath, cfg.KeyPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintln(os.Stderr, "Failed to generate HTTPS certificate:", err)
|
fmt.Fprintln(os.Stderr, "Failed to generate HTTPS certificate:", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add cert to server config.
|
// Add cert to server config.
|
||||||
server.TLSConfig = &tls.Config{Certificates: []tls.Certificate{cert}}
|
srv.TLSConfig = &tls.Config{Certificates: []tls.Certificate{cert}}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start the HTTPS server.
|
// Start the HTTPS server.
|
||||||
fmt.Printf("Starting HTTPS server on port: %s\n", srv.Port)
|
fmt.Printf("Starting HTTPS server on port: %s\n", cfg.Port)
|
||||||
if err := server.ListenAndServeTLS(srv.CertPath, srv.KeyPath); err != nil {
|
if err := srv.ListenAndServeTLS(cfg.CertPath, cfg.KeyPath); err != nil {
|
||||||
fmt.Fprintln(os.Stderr, "The HTTPS server has terminated:", err)
|
fmt.Fprintln(os.Stderr, "The HTTPS server has terminated:", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -83,14 +94,14 @@ func StartHTTPS(srv *config.Server) {
|
|||||||
// HTML file specified in the configuration or a default page prompting for
|
// HTML file specified in the configuration or a default page prompting for
|
||||||
// basic HTTP authentication. Requests for any other URLs will return a 404
|
// basic HTTP authentication. Requests for any other URLs will return a 404
|
||||||
// error to the client.
|
// error to the client.
|
||||||
func handleConnection(srv *config.Server, customHeaders map[string]string) http.HandlerFunc {
|
func handleConnection(cfg *config.Server, customHeaders map[string]string) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
// Log details of the incoming HTTP request.
|
// Log details of the incoming HTTP request.
|
||||||
dst_ip, dst_port := getLocalAddr(r)
|
dst_ip, dst_port := getLocalAddr(r)
|
||||||
src_ip, src_port, _ := net.SplitHostPort(r.RemoteAddr)
|
src_ip, src_port, _ := net.SplitHostPort(r.RemoteAddr)
|
||||||
username, password, isAuth := r.BasicAuth()
|
username, password, isAuth := r.BasicAuth()
|
||||||
if isAuth {
|
if isAuth {
|
||||||
srv.Logger.LogAttrs(context.Background(), slog.LevelInfo, "",
|
cfg.Logger.LogAttrs(context.Background(), slog.LevelInfo, "",
|
||||||
slog.String("event_type", "http"),
|
slog.String("event_type", "http"),
|
||||||
slog.String("source_ip", src_ip),
|
slog.String("source_ip", src_ip),
|
||||||
slog.String("source_port", src_port),
|
slog.String("source_port", src_port),
|
||||||
@@ -112,7 +123,7 @@ func handleConnection(srv *config.Server, customHeaders map[string]string) http.
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
srv.Logger.LogAttrs(context.Background(), slog.LevelInfo, "",
|
cfg.Logger.LogAttrs(context.Background(), slog.LevelInfo, "",
|
||||||
slog.String("event_type", "http"),
|
slog.String("event_type", "http"),
|
||||||
slog.String("source_ip", src_ip),
|
slog.String("source_ip", src_ip),
|
||||||
slog.String("source_port", src_port),
|
slog.String("source_port", src_port),
|
||||||
@@ -135,8 +146,8 @@ func handleConnection(srv *config.Server, customHeaders map[string]string) http.
|
|||||||
fmt.Printf("[HTTP] %s %s %s %s\n", src_ip, r.Method, r.URL.Path, r.URL.RawQuery)
|
fmt.Printf("[HTTP] %s %s %s %s\n", src_ip, r.Method, r.URL.Path, r.URL.RawQuery)
|
||||||
|
|
||||||
// Update the threat feed with the source IP address from the request.
|
// Update the threat feed with the source IP address from the request.
|
||||||
if srv.SendToThreatFeed {
|
if cfg.SendToThreatFeed {
|
||||||
threatfeed.UpdateIoC(src_ip, srv.ThreatScore)
|
threatfeed.UpdateIoC(src_ip, cfg.ThreatScore)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If custom headers are provided, add each header and its value to the
|
// If custom headers are provided, add each header and its value to the
|
||||||
@@ -150,9 +161,9 @@ func handleConnection(srv *config.Server, customHeaders map[string]string) http.
|
|||||||
// For any other requests, return a '404 Not Found' response.
|
// For any other requests, return a '404 Not Found' response.
|
||||||
if r.URL.Path == "/" || r.URL.Path == "/index.html" {
|
if r.URL.Path == "/" || r.URL.Path == "/index.html" {
|
||||||
// The request is for the root or /index.html.
|
// The request is for the root or /index.html.
|
||||||
if len(srv.HtmlPath) > 0 {
|
if len(cfg.HtmlPath) > 0 {
|
||||||
// Serve the custom HTML file specified in the configuration.
|
// Serve the custom HTML file specified in the configuration.
|
||||||
http.ServeFile(w, r, srv.HtmlPath)
|
http.ServeFile(w, r, cfg.HtmlPath)
|
||||||
} else {
|
} else {
|
||||||
// Serve the default page that prompts the client for basic
|
// Serve the default page that prompts the client for basic
|
||||||
// authentication.
|
// authentication.
|
||||||
|
|||||||
@@ -68,14 +68,21 @@ func StartThreatFeed(cfg *config.ThreatFeed) {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// Setup handlers.
|
// Setup handlers and server config.
|
||||||
mux := http.NewServeMux()
|
mux := http.NewServeMux()
|
||||||
mux.HandleFunc("/", enforcePrivateIP(handleConnection))
|
mux.HandleFunc("/", enforcePrivateIP(handleConnection))
|
||||||
mux.HandleFunc("/empty/", enforcePrivateIP(serveEmpty))
|
mux.HandleFunc("/empty/", enforcePrivateIP(serveEmpty))
|
||||||
|
srv := &http.Server{
|
||||||
|
Addr: ":" + cfg.Port,
|
||||||
|
Handler: mux,
|
||||||
|
ReadTimeout: 5 * time.Second,
|
||||||
|
WriteTimeout: 30 * time.Second,
|
||||||
|
IdleTimeout: 0,
|
||||||
|
}
|
||||||
|
|
||||||
// Start the threat feed HTTP server.
|
// Start the threat feed HTTP server.
|
||||||
fmt.Printf("Starting Threat Feed server on port: %s\n", cfg.Port)
|
fmt.Printf("Starting Threat Feed server on port: %s\n", cfg.Port)
|
||||||
if err := http.ListenAndServe(":"+cfg.Port, mux); err != nil {
|
if err := srv.ListenAndServe(); err != nil {
|
||||||
fmt.Fprintln(os.Stderr, "The Threat Feed server has terminated:", err)
|
fmt.Fprintln(os.Stderr, "The Threat Feed server has terminated:", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user