mirror of
https://github.com/yunginnanet/HellPot
synced 2024-06-28 08:40:48 +00:00
Continue: fasthttp implementation
This commit is contained in:
parent
4f98911b65
commit
234be70893
@ -1,6 +1,10 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
|
||||
"github.com/yunginnanet/HellPot/config"
|
||||
@ -17,9 +21,19 @@ func init() {
|
||||
if config.Debug {
|
||||
log.Debug().Msg("debug enabled")
|
||||
}
|
||||
log.Info().Str("config", config.Filename).Msg("initialization finished")
|
||||
log.Info().Str("file", config.Filename).Msg("current config")
|
||||
log.Info().Str("file", config.CurrentLogFile).Msg("current log")
|
||||
}
|
||||
|
||||
func main() {
|
||||
log.Error().Err(http.Serve()).Msg("HTTP err")
|
||||
stopChan := make(chan os.Signal, 1)
|
||||
signal.Notify(stopChan, syscall.SIGINT, syscall.SIGTERM)
|
||||
|
||||
go func() {
|
||||
log.Error().Err(http.Serve()).Msg("HTTP err")
|
||||
}()
|
||||
|
||||
<-stopChan // wait for SIGINT
|
||||
log.Warn().Msg("Shutting down server...")
|
||||
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ const (
|
||||
Title = "HellPot"
|
||||
)
|
||||
|
||||
// "http"
|
||||
var (
|
||||
// BindAddr is defined via our toml configuration file. It is the address that HellPot listens on.
|
||||
BindAddr string
|
||||
@ -24,6 +25,21 @@ var (
|
||||
// Paths are defined via our toml configuration file. These are the paths that HellPot will present for "robots.txt"
|
||||
// These are also the paths that HellPot will respond for. Other paths will throw a warning and will serve a 404.
|
||||
Paths []string
|
||||
|
||||
UseUnixSocket bool
|
||||
UnixSocketPath = ""
|
||||
)
|
||||
|
||||
// "performance"
|
||||
var (
|
||||
RestrictConcurrency bool
|
||||
MaxWorkers int
|
||||
)
|
||||
|
||||
// "diception"
|
||||
var (
|
||||
// FakeServerName is our configured value for the "Server: " response header when serving HTTP clients
|
||||
FakeServerName string
|
||||
)
|
||||
|
||||
var (
|
||||
@ -124,7 +140,7 @@ func Init() {
|
||||
|
||||
func setDefaults() {
|
||||
var (
|
||||
configSections = []string{"logger", "http"}
|
||||
configSections = []string{"logger", "http", "performance", "diception"}
|
||||
deflogdir = home + "/.config/" + Title + "/logs/"
|
||||
defNoColor = false
|
||||
)
|
||||
@ -141,13 +157,22 @@ func setDefaults() {
|
||||
"use_date_filename": true,
|
||||
}
|
||||
Opt["http"] = map[string]interface{}{
|
||||
"bind_addr": "127.0.0.1",
|
||||
"bind_port": "8080",
|
||||
"use_unix_socket": false,
|
||||
"unix_socket": "/var/run/hellpot",
|
||||
"bind_addr": "127.0.0.1",
|
||||
"bind_port": "8080",
|
||||
"paths": []string{
|
||||
"wp-login.php",
|
||||
"wp-login",
|
||||
},
|
||||
}
|
||||
Opt["performance"] = map[string]interface{}{
|
||||
"restrict_concurrency": false,
|
||||
"max_workers": 256,
|
||||
}
|
||||
Opt["diception"] = map[string]interface{}{
|
||||
"server_name": "nginx",
|
||||
}
|
||||
|
||||
for _, def := range configSections {
|
||||
snek.SetDefault(def, Opt[def])
|
||||
@ -221,6 +246,14 @@ func associate() {
|
||||
BindAddr = snek.GetString("http.bind_addr")
|
||||
BindPort = snek.GetString("http.bind_port")
|
||||
Paths = snek.GetStringSlice("http.paths")
|
||||
UseUnixSocket = snek.GetBool("http.use_unix_socket")
|
||||
FakeServerName = snek.GetString("diception.server_name")
|
||||
RestrictConcurrency = snek.GetBool("performance.restrict_concurrency")
|
||||
MaxWorkers = snek.GetInt("performance.max_workers")
|
||||
|
||||
if UseUnixSocket {
|
||||
UnixSocketPath = snek.GetString("http.unix_socket_path")
|
||||
}
|
||||
|
||||
if Debug {
|
||||
zerolog.SetGlobalLevel(zerolog.DebugLevel)
|
||||
|
@ -49,6 +49,12 @@ func (h *Heffalump) putBuffer(buf []byte) {
|
||||
// WriteHell writes markov chain heffalump hell to the provided io.Writer
|
||||
// https://github.com/carlmjohnson/heffalump
|
||||
func (h *Heffalump) WriteHell(w io.Writer) int64 {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
log.Error().Interface("caller", r).Msg("panic recovered!")
|
||||
}
|
||||
}()
|
||||
|
||||
buf := h.getBuffer()
|
||||
defer h.putBuffer(buf)
|
||||
|
||||
|
@ -1,81 +0,0 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"github.com/yunginnanet/HellPot/config"
|
||||
)
|
||||
|
||||
var log = config.GetLogger()
|
||||
|
||||
func listenOnUnixSocket(addr string, srv *http.Server) error {
|
||||
var err error
|
||||
var unixAddr *net.UnixAddr
|
||||
var unixListener *net.UnixListener
|
||||
socketPath := strings.TrimPrefix(addr, "unix:")
|
||||
unixAddr, err = net.ResolveUnixAddr("unix", socketPath)
|
||||
if err == nil {
|
||||
// Always unlink sockets before listening on them
|
||||
_ = syscall.Unlink(socketPath)
|
||||
unixListener, err = net.ListenUnix("unix", unixAddr)
|
||||
if err == nil {
|
||||
err = srv.Serve(unixListener)
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func listen() {
|
||||
addr := config.BindAddr
|
||||
port := config.BindPort
|
||||
//listenOnUnixDomain := true
|
||||
|
||||
log.Info().Str("bind_addr", addr).Str("bind_port", port).
|
||||
Msg("Listening and serving HTTP...")
|
||||
|
||||
/* if !strings.HasPrefix(addr, "unix:") {
|
||||
listenOnUnixDomain = false
|
||||
}
|
||||
|
||||
if listenOnUnixDomain {
|
||||
err = listenOnUnixSocket(addr, srv)
|
||||
} else {
|
||||
err = srv.ListenAndServe()
|
||||
}*/
|
||||
|
||||
// log.Warn().Err(err).Msg("HTTP_STOP")
|
||||
}
|
||||
|
||||
func StartPot() {
|
||||
|
||||
// subscribe to SIGINT signals
|
||||
stopChan := make(chan os.Signal, 1)
|
||||
signal.Notify(stopChan, syscall.SIGINT, syscall.SIGTERM)
|
||||
|
||||
/*r := mux.NewRouter()
|
||||
|
||||
r.HandleFunc("/{path}", heffalump.DefaultHoneypot)
|
||||
|
||||
srv := &http.Server{Handler: r}
|
||||
|
||||
*/
|
||||
go listen()
|
||||
|
||||
<-stopChan // wait for SIGINT
|
||||
log.Warn().Msg("Shutting down server...")
|
||||
|
||||
/*
|
||||
// shut down gracefully, but wait no longer than 5 seconds before halting
|
||||
ctx, c := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer c()
|
||||
if err := srv.Shutdown(ctx); err != nil {
|
||||
log.Debug().Caller().Err(err)
|
||||
}
|
||||
log.Info().Msg("Server gracefully stopped")
|
||||
*/
|
||||
}
|
@ -23,5 +23,4 @@ func robotsTXT(ctx *fasthttp.RequestCtx) {
|
||||
if _, err := fmt.Fprintf(ctx, robotsTxt+paths+"\r\n"); err != nil {
|
||||
log.Error().Err(err).Msg("SERVE_ROBOTS_ERROR")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -1,15 +1,21 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/fasthttp/router"
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/valyala/fasthttp"
|
||||
|
||||
"github.com/yunginnanet/HellPot/config"
|
||||
"github.com/yunginnanet/HellPot/heffalump"
|
||||
)
|
||||
|
||||
var log zerolog.Logger
|
||||
|
||||
func getRealRemote(ctx *fasthttp.RequestCtx) string {
|
||||
xrealip := string(ctx.Request.Header.Peek("X-Real-IP"))
|
||||
if len(xrealip) > 0 {
|
||||
@ -53,10 +59,83 @@ func scopeCheck(ctx *fasthttp.RequestCtx) {
|
||||
|
||||
}
|
||||
|
||||
func listenOnUnixSocket(addr string, r *router.Router) error {
|
||||
var err error
|
||||
var unixAddr *net.UnixAddr
|
||||
var unixListener *net.UnixListener
|
||||
unixAddr, err = net.ResolveUnixAddr("unix", addr)
|
||||
if err == nil {
|
||||
// Always unlink sockets before listening on them
|
||||
if err2 := syscall.Unlink(addr); err2 != nil {
|
||||
panic(err2)
|
||||
}
|
||||
unixListener, err = net.ListenUnix("unix", unixAddr)
|
||||
if err == nil {
|
||||
err = fasthttp.Serve(unixListener, r.Handler)
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Serve starts our HTTP server and request router
|
||||
func Serve() error {
|
||||
log = config.GetLogger()
|
||||
|
||||
l := fmt.Sprintf("%s:%s", config.BindAddr, config.BindPort)
|
||||
|
||||
r := router.New()
|
||||
r.GET("/robots.txt", robotsTXT)
|
||||
r.GET("/{path}", scopeCheck)
|
||||
return fasthttp.ListenAndServe(":8080", r.Handler)
|
||||
|
||||
if !config.RestrictConcurrency {
|
||||
config.MaxWorkers = fasthttp.DefaultConcurrency
|
||||
}
|
||||
|
||||
srv := fasthttp.Server{
|
||||
// User defined server name
|
||||
// Likely not useful if behind a reverse proxy without additional configuration of the proxy server.
|
||||
Name: config.FakeServerName,
|
||||
|
||||
/*
|
||||
from fasthttp docs: "By default request read timeout is unlimited."
|
||||
My thinking here is avoiding some sort of weird oversized GET query just in case.
|
||||
*/
|
||||
ReadTimeout: 5 * time.Second,
|
||||
MaxRequestBodySize: 1 * 1024 * 1024,
|
||||
|
||||
// Help curb abuse of HellPot (we've always needed this badly)
|
||||
MaxConnsPerIP: 1,
|
||||
MaxRequestsPerConn: 2,
|
||||
Concurrency: config.MaxWorkers,
|
||||
|
||||
// only accept GET requests
|
||||
GetOnly: true,
|
||||
|
||||
// we don't care if a request ends up being handled by a different handler
|
||||
// it shouldn't for now, but this may prevent future bugs
|
||||
KeepHijackedConns: true,
|
||||
|
||||
CloseOnShutdown: true,
|
||||
|
||||
|
||||
|
||||
// No need to keepalive, our response is a sort of keep-alive ;)
|
||||
DisableKeepalive: true,
|
||||
|
||||
|
||||
|
||||
Handler: r.Handler,
|
||||
}
|
||||
|
||||
if !config.UseUnixSocket {
|
||||
log.Info().Str("caller", l).Msg("Listening and serving HTTP...")
|
||||
return srv.ListenAndServe(l)
|
||||
}
|
||||
|
||||
if len(config.UnixSocketPath) < 1 {
|
||||
log.Fatal().Msg("unix_socket_path configuration directive appears to be empty")
|
||||
}
|
||||
|
||||
log.Info().Str("caller", config.UnixSocketPath).Msg("Listening and serving HTTP...")
|
||||
return listenOnUnixSocket(config.UnixSocketPath, r)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user