diff --git a/README.md b/README.md
index 5d6cc10..97fa3c4 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@
HellPot is an endless honeypot based on [Heffalump](https://github.com/carlmjohnson/heffalump) that sends unruly HTTP bots to hell.
-Notably it implements a [toml configuration file](https://github.com/spf13/viper), has [JSON logging](https://github.com/rs/zerolog), and comes with significant performance gains.
+Notably it implements a [toml configuration file](https://github.com/knadh/koanf), has [JSON logging](https://github.com/rs/zerolog), and comes with significant performance gains.
![Exploding Heffalump](https://tcp.ac/i/H8O9M.gif)
@@ -60,6 +60,15 @@ In the event of a missing configuration file, HellPot will attempt to place it's
## Configuration Reference
+
+> [!TIP]
+> Configuration values can be overridden with environment variables prefixed with `HELLPOT_`.
+> When using this method, replace underscores in configuration keys with two underscores.
+>
+> e.g:
+> to set `http.bind_addr` via env, set `HELLPOT_HTTP_BIND__ADDR="x.x.x.x"`
+
+
```toml
[deception]
# Used as "Server" HTTP header. Note that reverse proxies may hide this.
@@ -108,7 +117,12 @@ In the event of a missing configuration file, HellPot will attempt to place it's
restrict_concurrency = false
```
-## Example Web Server Config (nginx)
+### Example Reverse Proxy Configs
+
+#### nginx
+
+
+ nginx
```nginx
location '/robots.txt' {
@@ -124,7 +138,12 @@ location '/wp-login.php' {
}
```
-## Example Web Server Config (apache)
+
+
+#### Apache
+
+
+ apache (mod_proxy + mod_proxy_http)
All nonexisting URLs are being reverse proxied to a HellPot instance on localhost, which is set to catchall. Traffic served by HellPot is rate limited to 5 KiB/s.
@@ -161,6 +180,8 @@ All nonexisting URLs are being reverse proxied to a HellPot instance on localhos
```
+
+
## Related Suffering
- https://github.com/ginger51011/pandoras_pot
diff --git a/go.mod b/go.mod
index 6b47102..24d7bf2 100644
--- a/go.mod
+++ b/go.mod
@@ -5,36 +5,29 @@ go 1.19
require (
git.tcp.direct/kayos/common v0.9.7
github.com/fasthttp/router v1.5.1
+ github.com/knadh/koanf/parsers/toml v0.1.0
+ github.com/knadh/koanf/providers/env v0.1.0
+ github.com/knadh/koanf/providers/file v0.1.0
+ github.com/knadh/koanf/v2 v2.1.1
github.com/rs/zerolog v1.33.0
github.com/spf13/afero v1.11.0
- github.com/spf13/viper v1.19.0
github.com/valyala/fasthttp v1.55.0
golang.org/x/term v0.21.0
)
require (
github.com/andybalholm/brotli v1.1.0 // indirect
- github.com/fsnotify/fsnotify v1.7.0 // indirect
- github.com/hashicorp/hcl v1.0.0 // indirect
+ github.com/fsnotify/fsnotify v1.6.0 // indirect
+ github.com/go-viper/mapstructure/v2 v2.0.0-alpha.1 // indirect
github.com/klauspost/compress v1.17.9 // indirect
- github.com/magiconair/properties v1.8.7 // indirect
+ github.com/knadh/koanf/maps v0.1.1 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
- github.com/mitchellh/mapstructure v1.5.0 // indirect
- github.com/pelletier/go-toml/v2 v2.2.2 // indirect
- github.com/sagikazarmark/locafero v0.4.0 // indirect
- github.com/sagikazarmark/slog-shim v0.1.0 // indirect
+ github.com/mitchellh/copystructure v1.2.0 // indirect
+ github.com/mitchellh/reflectwalk v1.0.2 // indirect
+ github.com/pelletier/go-toml v1.9.5 // indirect
github.com/savsgio/gotils v0.0.0-20240303185622-093b76447511 // indirect
- github.com/sourcegraph/conc v0.3.0 // indirect
- github.com/spf13/cast v1.6.0 // indirect
- github.com/spf13/pflag v1.0.5 // indirect
- github.com/subosito/gotenv v1.6.0 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
- go.uber.org/atomic v1.9.0 // indirect
- go.uber.org/multierr v1.9.0 // indirect
- golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
golang.org/x/sys v0.21.0 // indirect
golang.org/x/text v0.16.0 // indirect
- gopkg.in/ini.v1 v1.67.0 // indirect
- gopkg.in/yaml.v3 v3.0.1 // indirect
)
diff --git a/go.sum b/go.sum
index ed168e0..b0e7909 100644
--- a/go.sum
+++ b/go.sum
@@ -3,79 +3,53 @@ git.tcp.direct/kayos/common v0.9.7/go.mod h1:mmTOIi7k99yygTa1FSOZNoFEEbSTOQV/QpT
github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
-github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/fasthttp/router v1.5.1 h1:uViy8UYYhm5npJSKEZ4b/ozM//NGzVCfJbh6VJ0VKr8=
github.com/fasthttp/router v1.5.1/go.mod h1:WrmsLo3mrerZP2VEXRV1E8nL8ymJFYCDTr4HmnB8+Zs=
-github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
-github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
-github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
+github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
+github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
+github.com/go-viper/mapstructure/v2 v2.0.0-alpha.1 h1:TQcrn6Wq+sKGkpyPvppOz99zsMBaUOKXq6HSv655U1c=
+github.com/go-viper/mapstructure/v2 v2.0.0-alpha.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
-github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
-github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
-github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
-github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
-github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
-github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
-github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
+github.com/knadh/koanf/maps v0.1.1 h1:G5TjmUh2D7G2YWf5SQQqSiHRJEjaicvU0KpypqB3NIs=
+github.com/knadh/koanf/maps v0.1.1/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI=
+github.com/knadh/koanf/parsers/toml v0.1.0 h1:S2hLqS4TgWZYj4/7mI5m1CQQcWurxUz6ODgOub/6LCI=
+github.com/knadh/koanf/parsers/toml v0.1.0/go.mod h1:yUprhq6eo3GbyVXFFMdbfZSo928ksS+uo0FFqNMnO18=
+github.com/knadh/koanf/providers/env v0.1.0 h1:LqKteXqfOWyx5Ab9VfGHmjY9BvRXi+clwyZozgVRiKg=
+github.com/knadh/koanf/providers/env v0.1.0/go.mod h1:RE8K9GbACJkeEnkl8L/Qcj8p4ZyPXZIQ191HJi44ZaQ=
+github.com/knadh/koanf/providers/file v0.1.0 h1:fs6U7nrV58d3CFAFh8VTde8TM262ObYf3ODrc//Lp+c=
+github.com/knadh/koanf/providers/file v0.1.0/go.mod h1:rjJ/nHQl64iYCtAW2QQnF0eSmDEX/YZ/eNFj5yR6BvA=
+github.com/knadh/koanf/v2 v2.1.1 h1:/R8eXqasSTsmDCsAyYj+81Wteg8AqrV9CP6gvsTsOmM=
+github.com/knadh/koanf/v2 v2.1.1/go.mod h1:4mnTRbZCK+ALuBXHZMjDfG9y714L7TykVnZkXbMU3Es=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
-github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
-github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
-github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
-github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
+github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
+github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
+github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
+github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
+github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
+github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
-github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
-github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8=
github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
-github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ=
-github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4=
-github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
-github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
github.com/savsgio/gotils v0.0.0-20240303185622-093b76447511 h1:KanIMPX0QdEdB4R3CiimCAbxFrhB3j7h0/OvpYGVQa8=
github.com/savsgio/gotils v0.0.0-20240303185622-093b76447511/go.mod h1:sM7Mt7uEoCeFSCBM+qBrqvEo+/9vdmj19wzp3yzUhmg=
-github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
-github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY=
-github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0=
-github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
-github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
-github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
-github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI=
-github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg=
-github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
-github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
-github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
-github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
-github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
-github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
-github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
-github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
-github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
-github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
+github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v1.55.0 h1:Zkefzgt6a7+bVKHnu/YaYSOPfNYNisSVBo/unVCf8k8=
github.com/valyala/fasthttp v1.55.0/go.mod h1:NkY9JtkrpPKmgwV3HTaS2HWaJss9RSIsRVfcxxoHiOM=
-go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
-go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
-go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI=
-go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ=
-golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g=
-golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
@@ -84,11 +58,5 @@ golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA=
golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0=
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
-gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
-gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
-gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
-gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
-gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
nullprogram.com/x/rng v1.1.0 h1:SMU7DHaQSWtKJNTpNFIFt8Wd/KSmOuSDPXrMFp/UMro=
diff --git a/internal/config/config.go b/internal/config/config.go
index 5caeca6..c357e1a 100644
--- a/internal/config/config.go
+++ b/internal/config/config.go
@@ -1,26 +1,27 @@
package config
import (
- "bytes"
"fmt"
- "io"
"os"
"path/filepath"
"runtime"
"strconv"
"strings"
+ "github.com/knadh/koanf/providers/env"
+ "github.com/knadh/koanf/providers/file"
"github.com/rs/zerolog"
- "github.com/spf13/viper"
+
+ "github.com/knadh/koanf/parsers/toml"
+ viper "github.com/knadh/koanf/v2"
)
// generic vars
var (
- noColorForce = false
- customconfig = false
- home string
- prefConfigLocation string
- snek = viper.New()
+ noColorForce = false
+ customconfig = false
+ home string
+ snek = viper.New(".")
)
// exported generic vars
@@ -33,25 +34,33 @@ var (
Filename string
)
-func writeConfig() {
+func writeConfig() string {
+ prefConfigLocation, _ := os.UserConfigDir()
+
if _, err := os.Stat(prefConfigLocation); os.IsNotExist(err) {
if err = os.MkdirAll(prefConfigLocation, 0o750); err != nil {
println("error writing new config: " + err.Error())
os.Exit(1)
}
}
- Filename = prefConfigLocation + "/" + "config.toml"
- if err := snek.SafeWriteConfigAs(Filename); err != nil {
- fmt.Println("Failed to write new configuration file to '" + Filename + "': " + err.Error())
+ Filename = filepath.Join(prefConfigLocation, "config.toml")
+
+ tomld, terr := toml.Parser().Marshal(snek.All())
+ if terr != nil {
+ fmt.Println("Failed to marshal new configuration file: " + terr.Error())
+ os.Exit(1)
+ }
+
+ if err := os.WriteFile(Filename, tomld, 0o600); err != nil {
+ println("error writing new config: " + err.Error())
os.Exit(1)
}
+
+ return Filename
}
// Init will initialize our toml configuration engine and define our default configuration values which can be written to a new configuration file if desired
func Init() {
- snek.SetConfigType("toml")
- snek.SetConfigName("config")
-
argParse()
if customconfig {
@@ -61,70 +70,59 @@ func Init() {
setDefaults()
- for _, loc := range getConfigPaths() {
- snek.AddConfigPath(loc)
- }
+ chosen := ""
- if err := snek.MergeInConfig(); err != nil {
- println("Error reading configuration file: " + err.Error())
- println("Writing new configuration file...")
- writeConfig()
- }
+ uconf, _ := os.UserConfigDir()
- if len(Filename) < 1 {
- Filename = snek.ConfigFileUsed()
+ switch runtime.GOOS {
+ case "windows":
+ //
+ default:
+ if _, err := os.Stat(filepath.Join("/etc/", Title, "config.toml")); err == nil {
+ chosen = filepath.Join("/etc/", Title, "config.toml")
+ }
}
- snek.SetEnvKeyReplacer(strings.NewReplacer(".", "_", "-", "_"))
- snek.SetEnvPrefix(Title)
+ if chosen == "" && uconf == "" && home != "" {
+ uconf = filepath.Join(home, ".config")
+ }
- snek.AutomaticEnv()
+ if chosen == "" && uconf != "" {
+ chosen = filepath.Join(uconf, Title, "config.toml")
+ }
- associateExportedVariables()
-}
+ if chosen == "" {
+ if _, err := os.Stat("./config.toml"); err == nil {
+ chosen = "./config.toml"
+ }
+ }
-func getConfigPaths() (paths []string) {
- paths = append(paths, "./")
- //goland:noinspection GoBoolExpressions
- if runtime.GOOS != "windows" {
- paths = append(paths,
- prefConfigLocation, "/etc/"+Title+"/", "../", "../../")
+ if chosen == "" {
+ println("No configuration file found, writing new configuration file...")
+ chosen = writeConfig()
}
- return
-}
-func loadCustomConfig(path string) {
- /* #nosec */
- cf, err := os.Open(path)
- if err != nil {
- println("Error opening specified config file: " + path)
+ Filename = chosen
+
+ if err := snek.Load(file.Provider(chosen), toml.Parser()); err != nil {
+ println("Error opening specified config file: " + chosen)
println(err.Error())
os.Exit(1)
}
- Filename, err = filepath.Abs(path)
- if len(Filename) < 1 || err != nil {
- Filename = path
- }
-
- defer func(f *os.File) {
- if fcerr := f.Close(); fcerr != nil {
- fmt.Println("failed to close file handler for config file: ", fcerr.Error())
- }
- }(cf)
+ /* snek.SetEnvKeyReplacer(strings.NewReplacer(".", "_", "-", "_"))
+ snek.SetEnvPrefix(Title)
+ snek.AutomaticEnv()
+ */
+ associateExportedVariables()
+}
- buf, err1 := io.ReadAll(cf)
- err2 := snek.ReadConfig(bytes.NewBuffer(buf))
+func loadCustomConfig(path string) {
+ Filename, _ = filepath.Abs(path)
- switch {
- case err1 != nil:
- fmt.Println("config file read fatal error during i/o: ", err1.Error())
+ if err := snek.Load(file.Provider(Filename), toml.Parser()); err != nil {
+ fmt.Println("failed to load specified config file: ", err.Error())
os.Exit(1)
- case err2 != nil:
- fmt.Println("config file read fatal error during parse: ", err2.Error())
- os.Exit(1)
- default:
- break
}
customconfig = true
@@ -162,20 +160,29 @@ func processOpts() {
}
for key, opt := range stringOpt {
- *opt = snek.GetString(key)
+ *opt = snek.String(key)
}
for key, opt := range strSliceOpt {
- *opt = snek.GetStringSlice(key)
+ *opt = snek.Strings(key)
}
for key, opt := range boolOpt {
- *opt = snek.GetBool(key)
+ *opt = snek.Bool(key)
}
for key, opt := range intOpt {
- *opt = snek.GetInt(key)
+ *opt = snek.Int(key)
}
}
func associateExportedVariables() {
+ _ = snek.Load(env.Provider("HELLPOT_", ".", func(s string) string {
+ s = strings.TrimPrefix(s, "HELLPOT_")
+ s = strings.ToLower(s)
+ s = strings.ReplaceAll(s, "__", " ")
+ s = strings.ReplaceAll(s, "_", ".")
+ s = strings.ReplaceAll(s, " ", "_")
+ return s
+ }), nil)
+
processOpts()
if noColorForce {
@@ -183,8 +190,8 @@ func associateExportedVariables() {
}
if UseUnixSocket {
- UnixSocketPath = snek.GetString("http.unix_socket_path")
- parsedPermissions, err := strconv.ParseUint(snek.GetString("http.unix_socket_permissions"), 8, 32)
+ UnixSocketPath = snek.String("http.unix_socket_path")
+ parsedPermissions, err := strconv.ParseUint(snek.String("http.unix_socket_permissions"), 8, 32)
if err == nil {
UnixSocketPermissions = uint32(parsedPermissions)
}
diff --git a/internal/config/defaults.go b/internal/config/defaults.go
index c3c172d..0d0241a 100644
--- a/internal/config/defaults.go
+++ b/internal/config/defaults.go
@@ -1,28 +1,15 @@
package config
import (
- "fmt"
"io"
"os"
- "path"
"runtime"
"time"
+ "github.com/knadh/koanf/parsers/toml"
"github.com/spf13/afero"
)
-func init() {
- var err error
- if home, err = os.UserHomeDir(); err != nil {
- panic(err)
- }
- if len(defOpts) == 0 {
- panic("default options map is empty")
- }
- defOpts["logger"]["directory"] = path.Join(home, ".local", "share", Title, "logs")
- prefConfigLocation = path.Join(home, ".config", Title)
-}
-
var (
configSections = []string{"logger", "http", "performance", "deception", "ssh"}
defNoColor = false
@@ -67,28 +54,28 @@ var defOpts = map[string]map[string]interface{}{
}
func gen(memfs afero.Fs) {
- target := fmt.Sprintf("%s.toml", Title)
- if err := snek.SafeWriteConfigAs("config.toml"); err != nil {
- print(err.Error())
- os.Exit(1)
- }
- var f afero.File
- var err error
- f, err = memfs.Open("config.toml")
- if err != nil {
+ var (
+ dat []byte
+ err error
+ f afero.File
+ )
+ if dat, err = snek.Marshal(toml.Parser()); err != nil {
println(err.Error())
os.Exit(1)
}
- nf, err := os.Create(target) // #nosec G304
- if err != nil {
+ if f, err = memfs.Create("config.toml"); err != nil {
println(err.Error())
os.Exit(1)
}
- if _, err = io.Copy(nf, f); err != nil {
+ var n int
+ if n, err = f.Write(dat); err != nil || n != len(dat) {
+ if err == nil {
+ err = io.ErrShortWrite
+ }
println(err.Error())
os.Exit(1)
}
- print("default configuration successfully written to " + target)
+ println("Default config written to config.toml")
os.Exit(0)
}
@@ -99,10 +86,25 @@ func setDefaults() {
defNoColor = true
}
for _, def := range configSections {
- snek.SetDefault(def, defOpts[def])
+ for key, val := range defOpts[def] {
+ if _, ok := val.(map[string]interface{}); !ok {
+ if err := snek.Set(def+"."+key, val); err != nil {
+ println(err.Error())
+ os.Exit(1)
+ }
+ continue
+ }
+ for k, v := range val.(map[string]interface{}) {
+ if err := snek.Set(def+"."+key+"."+k, v); err != nil {
+ println(err.Error())
+ os.Exit(1)
+ }
+ }
+ continue
+ }
}
+
if GenConfig {
- snek.SetFs(memfs)
gen(memfs)
}
}
diff --git a/internal/config/logger.go b/internal/config/logger.go
index c5c0c22..92a7373 100644
--- a/internal/config/logger.go
+++ b/internal/config/logger.go
@@ -19,7 +19,7 @@ var (
)
func prepLogDir() {
- logDir = snek.GetString("logger.directory")
+ logDir = snek.String("logger.directory")
if err := os.MkdirAll(logDir, 0750); err != nil {
println("cannot create log directory: " + logDir + "(" + err.Error() + ")")
os.Exit(1)
@@ -31,7 +31,7 @@ func prepLogDir() {
func StartLogger(pretty bool, targets ...io.Writer) zerolog.Logger {
logFileName := "HellPot"
- if snek.GetBool("logger.use_date_filename") {
+ if snek.Bool("logger.use_date_filename") {
tn := strings.ReplaceAll(time.Now().Format(time.RFC822), " ", "_")
tn = strings.ReplaceAll(tn, ":", "-")
logFileName = logFileName + "_" + tn