mirror of
https://github.com/yusing/godoxy.git
synced 2025-06-09 13:02:33 +02:00
added cidr_whitelist middleware
This commit is contained in:
parent
ed887a5cfc
commit
e8c3e4c75f
2 changed files with 106 additions and 1 deletions
|
@ -12,7 +12,7 @@
|
||||||
- [Real IP](#real-ip)
|
- [Real IP](#real-ip)
|
||||||
- [Custom](#custom)
|
- [Custom](#custom)
|
||||||
- [Cloudflare](#cloudflare)
|
- [Cloudflare](#cloudflare)
|
||||||
- [Modify request or response](#modify-request-or-response)
|
- [CIDR Whitelist](#cidr-whitelist)
|
||||||
- [Set headers](#set-headers)
|
- [Set headers](#set-headers)
|
||||||
- [Add headers](#add-headers)
|
- [Add headers](#add-headers)
|
||||||
- [Hide headers](#hide-headers)
|
- [Hide headers](#hide-headers)
|
||||||
|
@ -147,6 +147,8 @@ location / {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
[🔼Back to top](#table-of-content)
|
||||||
|
|
||||||
#### Cloudflare
|
#### Cloudflare
|
||||||
|
|
||||||
This is a preset for Cloudflare
|
This is a preset for Cloudflare
|
||||||
|
@ -169,6 +171,28 @@ app1:
|
||||||
|
|
||||||
[🔼Back to top](#table-of-content)
|
[🔼Back to top](#table-of-content)
|
||||||
|
|
||||||
|
### CIDR Whitelist
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# docker labels
|
||||||
|
proxy.app1.middlewares.cidr_whitelist.allow: |
|
||||||
|
- 10.0.0.0/8
|
||||||
|
- 192.168.0.0/16
|
||||||
|
# optional (default: 403)
|
||||||
|
proxy.app1.middlewares.cidr_whitelist.status_code: 403
|
||||||
|
# optional (default: "IP not allowed")
|
||||||
|
proxy.app1.middlewares.cidr_whitelist.message: "IP not allowed"
|
||||||
|
|
||||||
|
# include file
|
||||||
|
app1:
|
||||||
|
middlewares:
|
||||||
|
whitelist:
|
||||||
|
cidr:
|
||||||
|
- 10.0.0.0/8
|
||||||
|
- 192.168.0.0/16
|
||||||
|
status_code: 403 # default
|
||||||
|
message: "IP not allowed" # default
|
||||||
|
|
||||||
### Modify request or response
|
### Modify request or response
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
|
@ -365,6 +389,8 @@ You may use them with `<middleware_name>@file`
|
||||||
|
|
||||||
See [example](../internal/net/http/middleware/test_data/middleware_compose.yml)
|
See [example](../internal/net/http/middleware/test_data/middleware_compose.yml)
|
||||||
|
|
||||||
|
[🔼Back to top](#table-of-content)
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
### Authentik (untested, experimental)
|
### Authentik (untested, experimental)
|
||||||
|
|
79
internal/net/http/middleware/cidr_whitelist.go
Normal file
79
internal/net/http/middleware/cidr_whitelist.go
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
package middleware
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
D "github.com/yusing/go-proxy/internal/docker"
|
||||||
|
E "github.com/yusing/go-proxy/internal/error"
|
||||||
|
"github.com/yusing/go-proxy/internal/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
type cidrWhitelist struct {
|
||||||
|
*cidrWhitelistOpts
|
||||||
|
m *Middleware
|
||||||
|
}
|
||||||
|
|
||||||
|
type cidrWhitelistOpts struct {
|
||||||
|
Allow []*types.CIDR
|
||||||
|
StatusCode int
|
||||||
|
Message string
|
||||||
|
|
||||||
|
trustedAddr map[string]struct{} // cache for trusted IPs
|
||||||
|
}
|
||||||
|
|
||||||
|
var CIDRWhiteList = &cidrWhitelist{
|
||||||
|
m: &Middleware{
|
||||||
|
labelParserMap: D.ValueParserMap{
|
||||||
|
"allow": D.YamlStringListParser,
|
||||||
|
"statusCode": D.IntParser,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var cidrWhitelistDefaults = func() *cidrWhitelistOpts {
|
||||||
|
return &cidrWhitelistOpts{
|
||||||
|
Allow: []*types.CIDR{},
|
||||||
|
StatusCode: http.StatusForbidden,
|
||||||
|
Message: "IP not allowed",
|
||||||
|
trustedAddr: make(map[string]struct{}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCIDRWhitelist(opts OptionsRaw) (*Middleware, E.NestedError) {
|
||||||
|
wl := new(cidrWhitelist)
|
||||||
|
wl.m = &Middleware{
|
||||||
|
impl: wl,
|
||||||
|
before: wl.checkIP,
|
||||||
|
}
|
||||||
|
wl.cidrWhitelistOpts = cidrWhitelistDefaults()
|
||||||
|
err := Deserialize(opts, wl.cidrWhitelistOpts)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(wl.cidrWhitelistOpts.Allow) == 0 {
|
||||||
|
return nil, E.Missing("allow range")
|
||||||
|
}
|
||||||
|
return wl.m, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wl *cidrWhitelist) checkIP(next http.Handler, w ResponseWriter, r *Request) {
|
||||||
|
var ok bool
|
||||||
|
if _, ok = wl.trustedAddr[r.RemoteAddr]; !ok {
|
||||||
|
ip := net.IP(r.RemoteAddr)
|
||||||
|
for _, cidr := range wl.cidrWhitelistOpts.Allow {
|
||||||
|
if cidr.Contains(ip) {
|
||||||
|
wl.trustedAddr[r.RemoteAddr] = struct{}{}
|
||||||
|
ok = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !ok {
|
||||||
|
w.WriteHeader(wl.StatusCode)
|
||||||
|
w.Write([]byte(wl.Message))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
next.ServeHTTP(w, r)
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue