🔥 Feature: add IP ranges support to config.TrustedProxies (#1602)

* feat: add IP ranges support to config.TrustedProxies

* Added config example to README and moved IncrementIPRange to utils.
pull/1603/head
Ali Baran Eser 2021-10-28 01:46:39 +03:00 committed by GitHub
parent 743d8ec08c
commit cdbcfbec17
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 72 additions and 1 deletions

25
.github/README.md vendored
View File

@ -486,6 +486,31 @@ func main() {
</details>
### Using Trusted Proxy
📖 [Config](https://docs.gofiber.io/api/fiber#config)
```go
import (
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/recover"
)
func main() {
app := fiber.New(fiber.Config{
EnableTrustedProxyCheck: true,
TrustedProxies: []string{"0.0.0.0", "1.1.1.1/30"}, // IP address or IP address range
ProxyHeader: fiber.HeaderXForwardedFor},
})
// ...
log.Fatal(app.Listen(":3000"))
}
```
</details>
## 🧬 Internal Middleware
Here is a list of middleware that are included within the Fiber framework.

21
app.go
View File

@ -480,7 +480,7 @@ func New(config ...Config) *App {
app.config.trustedProxiesMap = make(map[string]struct{}, len(app.config.TrustedProxies))
for _, ip := range app.config.TrustedProxies {
app.config.trustedProxiesMap[ip] = struct{}{}
app.handleTrustedProxy(ip)
}
// Init app
@ -490,6 +490,25 @@ func New(config ...Config) *App {
return app
}
// Checks if the given IP address is a range whether or not, adds it to the trustedProxiesMap
func (app *App) handleTrustedProxy(ipAddress string) {
// Detects IP address is range whether or not
if strings.Contains(ipAddress, "/") {
// Parsing IP address
ip, ipnet, err := net.ParseCIDR(ipAddress)
if err != nil {
fmt.Printf("[Warning] IP range `%s` could not be parsed. \n", ipAddress)
return
}
// Iterates IP address which is between range
for ip := ip.Mask(ipnet.Mask); ipnet.Contains(ip); utils.IncrementIPRange(ip) {
app.config.trustedProxiesMap[ip.String()] = struct{}{}
}
return
}
app.config.trustedProxiesMap[ipAddress] = struct{}{}
}
// Mount attaches another app instance as a sub-router along a routing path.
// It's very useful to split up a large API as many independent routers and
// compose them as a single service using Mount. The fiber's error handler and

View File

@ -1034,6 +1034,22 @@ func Test_Ctx_IP_TrustedProxy(t *testing.T) {
utils.AssertEqual(t, "0.0.0.1", c.IP())
}
// go test -run Test_Ctx_IP_Range_TrustedProxy
func Test_Ctx_IP_Range_TrustedProxy(t *testing.T) {
t.Parallel()
app := New(Config{EnableTrustedProxyCheck: true, TrustedProxies: []string{"0.0.0.0", "1.1.1.1/30", "1.1.1.1/100"}, ProxyHeader: HeaderXForwardedFor})
c := app.AcquireCtx(&fasthttp.RequestCtx{})
defer app.ReleaseCtx(c)
expected := map[string]struct{}{
"0.0.0.0": {},
"1.1.1.0": {},
"1.1.1.1": {},
"1.1.1.2": {},
"1.1.1.3": {},
}
utils.AssertEqual(t, expected, app.config.trustedProxiesMap)
}
// go test -run Test_Ctx_IPs -parallel
func Test_Ctx_IPs(t *testing.T) {
t.Parallel()

View File

@ -8,6 +8,7 @@ import (
"crypto/rand"
"encoding/binary"
"encoding/hex"
"net"
"os"
"reflect"
"runtime"
@ -93,3 +94,13 @@ func GetArgument(arg string) bool {
}
return false
}
// IncrementIPRange Find available next IP address
func IncrementIPRange(ip net.IP) {
for j := len(ip) - 1; j >= 0; j-- {
ip[j]++
if ip[j] > 0 {
break
}
}
}