File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 1+ # Add PROXY protocol support to caddy
2+
3+ ## Syntax
4+
5+ ```
6+ proxyprotocol *cidr* ... {
7+ timeout *val*
8+ }
9+ ```
10+
11+ - ** cidr** CIDR ranges to process PROXY headers from
12+ - ** val** duration value (e.g. 5s, 1m)
13+
14+ The default timeout is ` 5s ` . Set to ` 0 ` or ` none ` to disable the timeout.
15+
16+ ## Examples
17+
18+ ```
19+ # Enable from any source (probably don't want this in prod)
20+ proxyprotocol
21+
22+ # Enable from local subnet and fixed IP
23+ proxyprotocol 10.22.0.0/16 10.23.0.1/32
24+
25+ # Set header timeout
26+ proxyprotocol 10.22.0.0/16 10.23.0.1/32 {
27+ timeout 5s
28+ }
29+
30+ ```
Original file line number Diff line number Diff line change 1+ package proxyprotocol
2+
3+ import (
4+ "net"
5+ "os"
6+
7+ proxyproto "github.com/armon/go-proxyproto"
8+ "github.com/mholt/caddy"
9+ )
10+
11+ type Configs []Config
12+
13+ type Listener struct {
14+ net.Listener
15+ Configs []Config
16+ }
17+ type CaddyListener struct {
18+ * Listener
19+ }
20+
21+ func (c * CaddyListener ) File () (* os.File , error ) {
22+ return c .Listener .Listener .(caddy.Listener ).File ()
23+ }
24+
25+ func (c Configs ) NewListener (l net.Listener ) net.Listener {
26+ ln := & Listener {
27+ Listener : l ,
28+ Configs : []Config (c ),
29+ }
30+ if _ , ok := l .(caddy.Listener ); ok {
31+ return & CaddyListener {Listener : ln }
32+ }
33+ return ln
34+ }
35+
36+ func (l * Listener ) Accept () (net.Conn , error ) {
37+ c , err := l .Listener .Accept ()
38+ if err != nil {
39+ return nil , err
40+ }
41+
42+ addr , ok := c .RemoteAddr ().(* net.TCPAddr )
43+ if ! ok {
44+ return c , nil
45+ }
46+ for _ , cfg := range l .Configs {
47+ if cfg .Subnets == nil {
48+ return proxyproto .NewConn (c , cfg .Timeout ), nil
49+ }
50+ for _ , s := range cfg .Subnets {
51+ if s .Contains (addr .IP ) {
52+ return proxyproto .NewConn (c , cfg .Timeout ), nil
53+ }
54+ }
55+ }
56+ return c , nil
57+ }
Original file line number Diff line number Diff line change 1+ package proxyprotocol
2+
3+ import (
4+ "net"
5+ "time"
6+
7+ "github.com/mholt/caddy"
8+ "github.com/mholt/caddy/caddyhttp/httpserver"
9+ )
10+
11+ type Config struct {
12+ Timeout time.Duration
13+ Subnets []* net.IPNet
14+ }
15+
16+ func init () {
17+ caddy .RegisterPlugin ("proxyprotocol" , caddy.Plugin {
18+ ServerType : "http" ,
19+ Action : setup ,
20+ })
21+ }
22+
23+ func setup (c * caddy.Controller ) error {
24+ var configs []Config
25+ var err error
26+
27+ for c .Next () {
28+ var cfg Config
29+ for c .NextArg () {
30+ _ , n , err := net .ParseCIDR (c .Val ())
31+ if err != nil {
32+ return err
33+ }
34+ cfg .Subnets = append (cfg .Subnets , n )
35+ }
36+
37+ if c .NextBlock () {
38+ switch c .Val () {
39+ case "timeout" :
40+ if ! c .NextArg () {
41+ return c .ArgErr ()
42+ }
43+ cfg .Timeout , err = time .ParseDuration (c .Val ())
44+ if err != nil {
45+ return err
46+ }
47+ default :
48+ return c .ArgErr ()
49+ }
50+ }
51+ configs = append (configs , cfg )
52+ if c .NextBlock () {
53+ return c .ArgErr ()
54+ }
55+ }
56+ if configs != nil {
57+ httpserver .GetConfig (c ).AddListenerMiddleware (Configs (configs ).NewListener )
58+ }
59+
60+ return nil
61+ }
You can’t perform that action at this time.
0 commit comments