From 967931fd25b76d905f62d2772db454dafce73e6d Mon Sep 17 00:00:00 2001 From: Ethan Knowlton Date: Sun, 8 Oct 2023 14:46:51 -0400 Subject: [PATCH 1/2] Enable use of Environment Variables I didn't want to kep the API Key in a file because it could be exposed so I thought a environment variable would be good. Might of got carried away and didn't need to put all config options in environment variables. commit ba35fa73512a5d0d868c9e9147f55fe50db0ec99 Author: Ethan Knowlton Date: Sat Oct 7 22:35:31 2023 -0400 removed debug statement commit 3808cc26dfac70e5c205df807b26855bf4562196 Author: Ethan Knowlton Date: Sat Oct 7 22:32:27 2023 -0400 Could Cause Problems Shouldn't need to run make as super user, but usually you would run `make install`. I could add this to the install step and remove the install from all step but it could mess up publishing to ip.level.io. Just going to remove it for now. commit aa0cb39b08e71e1ef897f2d3f3a4fc7e5aff4c03 Author: Ethan Knowlton Date: Sat Oct 7 20:05:14 2023 -0400 adding env variables to readme --- .dockerignore | 3 +- .gitignore | 1 + Dockerfile | 6 +- Makefile | 8 +-- README.md | 21 +++++++ cmd/echoip/main.go | 115 +++++++++++++++-------------------- config/config.go | 135 +++++++++++++++++++++++++++++++++++++++++ docker-compose.yaml | 8 +++ etc/echoip/config.toml | 2 +- go.mod | 5 +- go.sum | 11 ++-- 11 files changed, 233 insertions(+), 82 deletions(-) create mode 100644 config/config.go diff --git a/.dockerignore b/.dockerignore index 30ecf57..18fb1ea 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,2 +1,3 @@ Dockerfile -Dockerfile.geoip \ No newline at end of file +/etc/systemd +Dockerfile.geoip diff --git a/.gitignore b/.gitignore index 56d06b1..6337cb2 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ .vscode/ .idea/ /bin/ +.envrc diff --git a/Dockerfile b/Dockerfile index 7a4c32a..8e0d960 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ # Build -FROM golang:1.15-buster AS build -WORKDIR /go/src/github.com/mpolden/echoip +FROM golang:1.18-buster AS build +WORKDIR /go/src/github.com/levelsoftware/echoip COPY . . # Must build without cgo because libc is unavailable in runtime image @@ -8,7 +8,7 @@ ENV GO111MODULE=on CGO_ENABLED=0 RUN make # Run -FROM scratch +FROM alpine EXPOSE 8080 COPY --from=build /go/bin/echoip /opt/echoip/ diff --git a/Makefile b/Makefile index ea19fd9..059eb74 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ DOCKER ?= docker -DOCKER_IMAGE ?= mpolden/echoip +DOCKER_IMAGE ?= levelsoftware/echoip OS := $(shell uname) ifeq ($(OS),Linux) TAR_OPTS := --wildcards @@ -22,11 +22,11 @@ check-fmt: lint: check-fmt vet -install: install-config +install: go install ./... install-config: - sudo install -D etc/echoip/config.toml /etc/echoip/config.toml + install -D etc/echoip/config.toml /etc/echoip/config.toml databases := GeoLite2-City GeoLite2-Country GeoLite2-ASN @@ -51,7 +51,7 @@ docker-multiarch-builder: $(DOCKER) run --rm --privileged multiarch/qemu-user-static --reset -p yes docker-build: - $(DOCKER) build -t $(DOCKER_IMAGE) . + $(DOCKER) build -t $(DOCKER_IMAGE) . docker-login: @echo "$(DOCKER_PASSWORD)" | $(DOCKER) login -u "$(DOCKER_USERNAME)" --password-stdin diff --git a/README.md b/README.md index c10182e..b71038e 100644 --- a/README.md +++ b/README.md @@ -132,6 +132,27 @@ CityFile = "" AsnFile = "" ``` +### Environment Variables for Configuration +You can also use environment variables for configuration, most likely used for Docker. + +``` +ECHOIP_LISTEN=":8080" +ECHOIP_TEMPLATE_DIR="html/" +ECHOIP_REDIS_URL="redis://localhost:6379" +ECHOIP_DATABASE="ipstack" +ECHOIP_IPSTACK_API_KEY="askdfj39sjdkf29dsjfk39sdfkj3" +ECHOIP_GEOIP_COUNTRY_FILE="/full/path/to/file.db" +ECHOIP_GEOIP_CITY_FILE="/full/path/to/file.db" +ECHOIP_GEOIP_ASN_FILE="/full/path/to/file.db" +ECHOIP_CACHE_TTL=3600 +ECHOIP_REVERSE_LOOKUP=true +ECHOIP_PORT_LOOKUP=true +ECHOIP_SHOW_SPONSOR=true +ECHOIP_PROFILE=false +ECHOIP_IPSTACK_USE_HTTPS=true +ECHOIP_IPSTACK_ENABLE_SECURITY=true +``` + ### Caching with Redis You can connect EchoIP to a Redis client to cache each request per IP. You can configure the life of the key in `config.CacheTtl`. diff --git a/cmd/echoip/main.go b/cmd/echoip/main.go index 3d43e53..37ecdd2 100644 --- a/cmd/echoip/main.go +++ b/cmd/echoip/main.go @@ -9,6 +9,7 @@ import ( "github.com/BurntSushi/toml" "github.com/levelsoftware/echoip/cache" + "github.com/levelsoftware/echoip/config" "github.com/levelsoftware/echoip/http" "github.com/levelsoftware/echoip/iputil" "github.com/levelsoftware/echoip/iputil/geo" @@ -33,61 +34,40 @@ func init() { log.SetFlags(log.Lshortfile) } -type IPStack struct { - ApiKey string - UseHttps bool - EnableSecurity bool -} - -type GeoIP struct { - CountryFile string - CityFile string - AsnFile string -} - -type Config struct { - Listen string - TemplateDir string - RedisUrl string - CacheTtl int - ReverseLookup bool - PortLookup bool - ShowSponsor bool - TrustedHeaders []string - - Database string - Profile bool - - IPStack IPStack - GeoIP GeoIP -} - func main() { - file, err := os.Open("/etc/echoip/config.toml") + runConfig, err := config.GetConfig() + if err != nil { - panic(err) + log.Fatalf("Error building configuration: %s", err) } + + file, err := os.Open("/etc/echoip/config.toml") defer file.Close() - var config Config - - b, err := io.ReadAll(file) if err != nil { - panic(err) + log.Printf("Error opening config file (/etc/echoip/config.toml): %s", err) } - err = toml.Unmarshal(b, &config) - if err != nil { - panic(err) + if err == nil { + var b []byte + b, err = io.ReadAll(file) + if err != nil { + log.Printf("Error reading config file (/etc/echoip/config.toml): %s", err) + } + + err = toml.Unmarshal(b, &runConfig) + if err != nil { + log.Fatalf("Error parsing config file: %s", err) + } } var parser parser.Parser - if config.Database == "geoip" { + if runConfig.Database == "geoip" { log.Print("Using GeoIP for IP database") geo, err := geo.Open( - config.GeoIP.CountryFile, - config.GeoIP.CityFile, - config.GeoIP.AsnFile, + runConfig.GeoIP.CountryFile, + runConfig.GeoIP.CityFile, + runConfig.GeoIP.AsnFile, ) if err != nil { log.Fatal(err) @@ -95,27 +75,27 @@ func main() { parser = &geo } - if config.Database == "ipstack" { - log.Print("Using GeoIP for IP database") - if config.IPStack.EnableSecurity { - log.Print("Enable Security Module ( Requires Professional Plus account )") + if runConfig.Database == "ipstack" { + log.Print("Using IP Stack for IP database") + if runConfig.IPStack.EnableSecurity { + log.Print("Enable IP Stack Security Module ( Requires Professional Plus account )") } - enableSecurity := ipstackApi.ParamEnableSecurity(config.IPStack.EnableSecurity) - apiKey := ipstackApi.ParamToken(config.IPStack.ApiKey) - useHttps := ipstackApi.ParamUseHTTPS(config.IPStack.UseHttps) - if config.IPStack.UseHttps { + enableSecurity := ipstackApi.ParamEnableSecurity(runConfig.IPStack.EnableSecurity) + apiKey := ipstackApi.ParamToken(runConfig.IPStack.ApiKey) + useHttps := ipstackApi.ParamUseHTTPS(runConfig.IPStack.UseHttps) + if runConfig.IPStack.UseHttps { log.Print("Use IP Stack HTTPS API ( Requires non-free account )") } if err := ipstackApi.Init(apiKey, enableSecurity, useHttps); err != nil { - log.Fatal(err) + log.Fatalf("Error initializing IP Stack client: %s", err) } ips := ipstack.IPStack{} parser = &ips } var serverCache cache.Cache - if len(config.RedisUrl) > 0 { - redisCache, err := cache.RedisCache(config.RedisUrl) + if len(runConfig.RedisUrl) > 0 { + redisCache, err := cache.RedisCache(runConfig.RedisUrl) serverCache = &redisCache if err != nil { log.Fatal(err) @@ -124,34 +104,35 @@ func main() { serverCache = &cache.Null{} } - server := http.New(parser, serverCache, config.CacheTtl, config.Profile) - server.IPHeaders = config.TrustedHeaders + server := http.New(parser, serverCache, runConfig.CacheTtl, runConfig.Profile) + server.IPHeaders = runConfig.TrustedHeaders - if _, err := os.Stat(config.TemplateDir); err == nil { - server.Template = config.TemplateDir + if _, err := os.Stat(runConfig.TemplateDir); err == nil { + server.Template = runConfig.TemplateDir } else { - log.Printf("Not configuring default handler: Template not found: %s", config.TemplateDir) + log.Printf("Not configuring default handler: Template not found: %s", runConfig.TemplateDir) } - if config.ReverseLookup { + if runConfig.ReverseLookup { log.Println("Enabling reverse lookup") server.LookupAddr = iputil.LookupAddr } - if config.PortLookup { + if runConfig.PortLookup { log.Println("Enabling port lookup") server.LookupPort = iputil.LookupPort } - if config.ShowSponsor { + if runConfig.ShowSponsor { log.Println("Enabling sponsor logo") - server.Sponsor = config.ShowSponsor + server.Sponsor = runConfig.ShowSponsor } - if len(config.TrustedHeaders) > 0 { - log.Printf("Trusting remote IP from header(s): %s", config.TrustedHeaders) + if len(runConfig.TrustedHeaders) > 0 { + log.Printf("Trusting remote IP from header(s): %s", runConfig.TrustedHeaders) } - if config.Profile { + if runConfig.Profile { log.Printf("Enabling profiling handlers") } - log.Printf("Listening on http://%s", config.Listen) - if err := server.ListenAndServe(config.Listen); err != nil { + + log.Printf("Listening on http://%s", runConfig.Listen) + if err := server.ListenAndServe(runConfig.Listen); err != nil { log.Fatal(err) } } diff --git a/config/config.go b/config/config.go new file mode 100644 index 0000000..3a4b4e2 --- /dev/null +++ b/config/config.go @@ -0,0 +1,135 @@ +package config + +import ( + "os" + "strconv" +) + +type IPStack struct { + ApiKey string + UseHttps bool + EnableSecurity bool +} + +type GeoIP struct { + CountryFile string + CityFile string + AsnFile string +} + +type Config struct { + Listen string + TemplateDir string + RedisUrl string + CacheTtl int + ReverseLookup bool + PortLookup bool + ShowSponsor bool + TrustedHeaders []string + + Database string + Profile bool + + IPStack IPStack + GeoIP GeoIP +} + +func GetConfig() (Config, error) { + defaultConfig := Config{ + Listen: getenv_string("ECHOIP_LISTEN", ":8080"), + TemplateDir: getenv_string("ECHOIP_TEMPLATE_DIR", "html/"), + RedisUrl: getenv_string("ECHOIP_REDIS_URL", ""), + TrustedHeaders: nil, + Database: getenv_string("ECHOIP_DATABASE", "geoip"), + IPStack: IPStack{ + ApiKey: getenv_string("ECHOIP_IPSTACK_API_KEY", ""), + }, + GeoIP: GeoIP{ + CountryFile: getenv_string("ECHOIP_GEOIP_COUNTRY_FILE", ""), + CityFile: getenv_string("ECHOIP_GEOIP_CITY_FILE", ""), + AsnFile: getenv_string("ECHOIP_GEOIP_ASN_FILE", ""), + }, + } + + cacheTtl, err := getenv_int("ECHOIP_CACHE_TTL", 3600) + if err != nil { + return Config{}, err + } + defaultConfig.CacheTtl = cacheTtl + + reverseLookup, err := getenv_bool("ECHOIP_REVERSE_LOOKUP", false) + if err != nil { + return Config{}, err + } + defaultConfig.ReverseLookup = reverseLookup + + portLookup, err := getenv_bool("ECHOIP_PORT_LOOKUP", false) + if err != nil { + return Config{}, err + } + defaultConfig.PortLookup = portLookup + + showSponsor, err := getenv_bool("ECHOIP_SHOW_SPONSOR", false) + if err != nil { + return Config{}, err + } + defaultConfig.ShowSponsor = showSponsor + + profile, err := getenv_bool("ECHOIP_PROFILE", false) + if err != nil { + return Config{}, err + } + defaultConfig.Profile = profile + + ipStackUseHttps, err := getenv_bool("ECHOIP_IPSTACK_USE_HTTPS", false) + if err != nil { + return Config{}, err + } + defaultConfig.IPStack.UseHttps = ipStackUseHttps + + ipStackEnableSecurity, err := getenv_bool("ECHOIP_IPSTACK_ENABLE_SECURITY", false) + if err != nil { + return Config{}, err + } + defaultConfig.IPStack.EnableSecurity = ipStackEnableSecurity + + return defaultConfig, nil +} + +func getenv_int(key string, fallback int) (int, error) { + value := os.Getenv(key) + + if len(value) > 0 { + intValue, err := strconv.Atoi(value) + if err != nil { + return 0, err + } + + return intValue, nil + } + + return fallback, nil +} + +func getenv_string(key string, fallback string) string { + value := os.Getenv(key) + if len(value) == 0 { + return fallback + } + return value +} + +func getenv_bool(key string, fallback bool) (bool, error) { + value := os.Getenv(key) + + if len(value) > 0 { + boolValue, err := strconv.ParseBool(value) + if err != nil { + return false, err + } + + return boolValue, nil + } + + return fallback, nil +} diff --git a/docker-compose.yaml b/docker-compose.yaml index d52d03b..30de17a 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,6 +1,14 @@ version: '3.8' services: + echoip: + image: hub.01a.in/echoip:latest + environment: + - ECHOIP_DATABASE="ipstack" + - ECHOIP_IPSTACK_API_KEY="ipstack" + ports: + - '8080:8080' + cache: image: redis:6.2-alpine restart: always diff --git a/etc/echoip/config.toml b/etc/echoip/config.toml index f369a47..a4ff37d 100644 --- a/etc/echoip/config.toml +++ b/etc/echoip/config.toml @@ -1,5 +1,5 @@ Listen = ":8080" -TemplateDir = "html/index.html" +TemplateDir = "html" RedisUrl = "redis://localhost:6379" CacheTtl = 3600 # in seconds ReverseLookup = true diff --git a/go.mod b/go.mod index 8d8d475..dd74956 100644 --- a/go.mod +++ b/go.mod @@ -18,6 +18,7 @@ require ( github.com/vmihailenco/go-tinylfu v0.2.2 // indirect github.com/vmihailenco/msgpack/v5 v5.3.4 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect - golang.org/x/sync v0.1.0 // indirect - golang.org/x/sys v0.4.0 // indirect + golang.org/x/net v0.14.0 // indirect + golang.org/x/sync v0.3.0 // indirect + golang.org/x/sys v0.11.0 // indirect ) diff --git a/go.sum b/go.sum index 016aac8..11a4dd1 100644 --- a/go.sum +++ b/go.sum @@ -128,15 +128,17 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= -golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw= golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= +golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= +golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -160,8 +162,9 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -174,8 +177,8 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k= golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= From d70ee291d4a6af2bc46bea7b773fb81ac375b72c Mon Sep 17 00:00:00 2001 From: Ethan Knowlton Date: Sun, 8 Oct 2023 18:39:18 -0400 Subject: [PATCH 2/2] forgot to come back for trusted headers --- README.md | 1 + cmd/echoip/main.go | 4 +--- config/config.go | 13 ++++++++----- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index b71038e..a7fe331 100644 --- a/README.md +++ b/README.md @@ -140,6 +140,7 @@ ECHOIP_LISTEN=":8080" ECHOIP_TEMPLATE_DIR="html/" ECHOIP_REDIS_URL="redis://localhost:6379" ECHOIP_DATABASE="ipstack" +ECHOIP_TRUSTED_HEADERS="X-Real-IP,X-Forwaded-For" ECHOIP_IPSTACK_API_KEY="askdfj39sjdkf29dsjfk39sdfkj3" ECHOIP_GEOIP_COUNTRY_FILE="/full/path/to/file.db" ECHOIP_GEOIP_CITY_FILE="/full/path/to/file.db" diff --git a/cmd/echoip/main.go b/cmd/echoip/main.go index 37ecdd2..166e7f9 100644 --- a/cmd/echoip/main.go +++ b/cmd/echoip/main.go @@ -46,9 +46,7 @@ func main() { if err != nil { log.Printf("Error opening config file (/etc/echoip/config.toml): %s", err) - } - - if err == nil { + } else { var b []byte b, err = io.ReadAll(file) if err != nil { diff --git a/config/config.go b/config/config.go index 3a4b4e2..93d5c6e 100644 --- a/config/config.go +++ b/config/config.go @@ -3,6 +3,7 @@ package config import ( "os" "strconv" + "strings" ) type IPStack struct { @@ -36,11 +37,10 @@ type Config struct { func GetConfig() (Config, error) { defaultConfig := Config{ - Listen: getenv_string("ECHOIP_LISTEN", ":8080"), - TemplateDir: getenv_string("ECHOIP_TEMPLATE_DIR", "html/"), - RedisUrl: getenv_string("ECHOIP_REDIS_URL", ""), - TrustedHeaders: nil, - Database: getenv_string("ECHOIP_DATABASE", "geoip"), + Listen: getenv_string("ECHOIP_LISTEN", ":8080"), + TemplateDir: getenv_string("ECHOIP_TEMPLATE_DIR", "html/"), + RedisUrl: getenv_string("ECHOIP_REDIS_URL", ""), + Database: getenv_string("ECHOIP_DATABASE", "geoip"), IPStack: IPStack{ ApiKey: getenv_string("ECHOIP_IPSTACK_API_KEY", ""), }, @@ -93,6 +93,9 @@ func GetConfig() (Config, error) { } defaultConfig.IPStack.EnableSecurity = ipStackEnableSecurity + trustedHeaders := getenv_string("ECHOIP_TRUSTED_HEADERS", "") + defaultConfig.TrustedHeaders = strings.Split(trustedHeaders, ",") + return defaultConfig, nil }