2021-09-15 15:05:27 +00:00
|
|
|
package http
|
|
|
|
|
|
|
|
import (
|
2021-09-15 16:52:18 +00:00
|
|
|
"bufio"
|
2021-09-15 16:13:16 +00:00
|
|
|
"fmt"
|
2021-09-22 06:47:32 +00:00
|
|
|
"runtime"
|
2021-09-15 15:05:27 +00:00
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/fasthttp/router"
|
2021-09-15 16:13:16 +00:00
|
|
|
"github.com/rs/zerolog"
|
2021-09-15 15:05:27 +00:00
|
|
|
"github.com/valyala/fasthttp"
|
|
|
|
|
|
|
|
"github.com/yunginnanet/HellPot/config"
|
|
|
|
"github.com/yunginnanet/HellPot/heffalump"
|
|
|
|
)
|
|
|
|
|
2021-11-08 04:07:14 +00:00
|
|
|
var log *zerolog.Logger
|
2021-09-15 16:13:16 +00:00
|
|
|
|
2021-09-15 15:05:27 +00:00
|
|
|
func getRealRemote(ctx *fasthttp.RequestCtx) string {
|
|
|
|
xrealip := string(ctx.Request.Header.Peek("X-Real-IP"))
|
|
|
|
if len(xrealip) > 0 {
|
|
|
|
return xrealip
|
|
|
|
}
|
|
|
|
return ctx.RemoteIP().String()
|
|
|
|
}
|
|
|
|
|
2021-09-15 16:52:18 +00:00
|
|
|
func hellPot(ctx *fasthttp.RequestCtx) {
|
2022-04-06 10:49:59 +00:00
|
|
|
path, pok := ctx.UserValue("path").(string)
|
|
|
|
if len(path) < 1 || !pok {
|
|
|
|
path = "/"
|
|
|
|
}
|
|
|
|
|
2021-09-15 15:05:27 +00:00
|
|
|
remoteAddr := getRealRemote(ctx)
|
|
|
|
slog := log.With().
|
2021-09-15 16:52:18 +00:00
|
|
|
Str("USERAGENT", string(ctx.UserAgent())).
|
2021-09-15 15:05:27 +00:00
|
|
|
Str("REMOTE_ADDR", remoteAddr).
|
|
|
|
Interface("URL", string(ctx.RequestURI())).Logger()
|
|
|
|
|
2022-04-06 10:49:59 +00:00
|
|
|
if config.Trace {
|
|
|
|
slog = slog.With().Str("caller", path).Logger()
|
|
|
|
}
|
|
|
|
|
2021-09-15 16:52:18 +00:00
|
|
|
slog.Info().Msg("NEW")
|
2021-09-15 15:05:27 +00:00
|
|
|
|
|
|
|
s := time.Now()
|
2021-09-15 16:52:18 +00:00
|
|
|
var n int64
|
|
|
|
|
|
|
|
ctx.SetBodyStreamWriter(func(bw *bufio.Writer) {
|
2021-09-15 17:33:48 +00:00
|
|
|
var err error
|
|
|
|
var wn int64
|
|
|
|
|
|
|
|
for {
|
|
|
|
wn, err = heffalump.DefaultHeffalump.WriteHell(bw)
|
|
|
|
n += wn
|
|
|
|
if err != nil {
|
2022-03-06 20:03:36 +00:00
|
|
|
slog.Trace().Err(err).Msg("END_ON_ERR")
|
2021-09-15 17:33:48 +00:00
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
2021-09-15 16:52:18 +00:00
|
|
|
|
2021-09-15 17:33:48 +00:00
|
|
|
slog.Info().
|
|
|
|
Int64("BYTES", n).
|
|
|
|
Dur("DURATION", time.Since(s)).
|
|
|
|
Msg("FINISH")
|
|
|
|
})
|
2021-09-15 15:05:27 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2021-09-15 16:52:18 +00:00
|
|
|
func getSrv(r *router.Router) fasthttp.Server {
|
2021-09-15 16:13:16 +00:00
|
|
|
if !config.RestrictConcurrency {
|
|
|
|
config.MaxWorkers = fasthttp.DefaultConcurrency
|
|
|
|
}
|
|
|
|
|
2021-11-08 04:07:14 +00:00
|
|
|
log = config.GetLogger()
|
|
|
|
|
2021-09-15 16:52:18 +00:00
|
|
|
return fasthttp.Server{
|
2021-09-15 16:13:16 +00:00
|
|
|
// User defined server name
|
|
|
|
// Likely not useful if behind a reverse proxy without additional configuration of the proxy server.
|
|
|
|
Name: config.FakeServerName,
|
|
|
|
|
|
|
|
/*
|
2021-09-15 16:52:18 +00:00
|
|
|
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.
|
2021-09-15 16:13:16 +00:00
|
|
|
*/
|
2021-09-15 17:33:48 +00:00
|
|
|
ReadTimeout: 5 * time.Second,
|
2021-09-15 16:13:16 +00:00
|
|
|
MaxRequestBodySize: 1 * 1024 * 1024,
|
|
|
|
|
|
|
|
// Help curb abuse of HellPot (we've always needed this badly)
|
2021-09-15 17:33:48 +00:00
|
|
|
MaxConnsPerIP: 10,
|
2021-09-15 16:13:16 +00:00
|
|
|
MaxRequestsPerConn: 2,
|
2021-09-15 17:33:48 +00:00
|
|
|
Concurrency: config.MaxWorkers,
|
2021-09-15 16:13:16 +00:00
|
|
|
|
|
|
|
// only accept GET requests
|
|
|
|
GetOnly: true,
|
|
|
|
|
2021-09-15 16:52:18 +00:00
|
|
|
// we don't care if a request ends up being handled by a different handler (in fact it probably will)
|
2021-09-15 16:13:16 +00:00
|
|
|
KeepHijackedConns: true,
|
|
|
|
|
|
|
|
CloseOnShutdown: true,
|
|
|
|
|
|
|
|
// No need to keepalive, our response is a sort of keep-alive ;)
|
|
|
|
DisableKeepalive: true,
|
|
|
|
|
|
|
|
Handler: r.Handler,
|
2022-02-07 10:12:02 +00:00
|
|
|
Logger: log,
|
2021-09-15 16:13:16 +00:00
|
|
|
}
|
2021-09-15 16:52:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Serve starts our HTTP server and request router
|
|
|
|
func Serve() error {
|
|
|
|
log = config.GetLogger()
|
2021-11-08 04:07:14 +00:00
|
|
|
l := config.HTTPBind + ":" + config.HTTPPort
|
2021-09-15 16:52:18 +00:00
|
|
|
|
|
|
|
r := router.New()
|
2022-02-07 10:12:02 +00:00
|
|
|
|
2022-04-06 10:49:59 +00:00
|
|
|
if config.MakeRobots && !config.CatchAll {
|
|
|
|
r.GET("/robots.txt", robotsTXT)
|
|
|
|
}
|
|
|
|
|
|
|
|
if !config.CatchAll {
|
|
|
|
for _, p := range config.Paths {
|
|
|
|
log.Trace().Str("caller", "router").Msg(p)
|
|
|
|
r.GET(fmt.Sprintf("/%s", p), hellPot)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
log.Trace().Msg("Catch-All mode enabled...")
|
|
|
|
r.GET("/", hellPot)
|
|
|
|
r.GET("/{path}", hellPot)
|
2021-09-15 16:52:18 +00:00
|
|
|
}
|
2021-09-15 16:13:16 +00:00
|
|
|
|
2021-09-15 16:52:18 +00:00
|
|
|
srv := getSrv(r)
|
2021-09-15 17:33:48 +00:00
|
|
|
|
2022-04-06 10:49:59 +00:00
|
|
|
//goland:noinspection GoBoolExpressions
|
2021-09-22 06:47:32 +00:00
|
|
|
if !config.UseUnixSocket || runtime.GOOS == "windows" {
|
2021-09-15 16:13:16 +00:00
|
|
|
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)
|
2021-09-15 15:05:27 +00:00
|
|
|
}
|