Skip to content

Commit

Permalink
layer4: Add support for the proxy_protocol handler
Browse files Browse the repository at this point in the history
  • Loading branch information
RussellLuo committed Jan 25, 2022
1 parent 0052f09 commit 1c9850e
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 29 deletions.
71 changes: 51 additions & 20 deletions layer4/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@

The layer4 Caddyfile (via [global options](https://github.com/caddyserver/caddy/pull/3990)) for [mholt/caddy-l4](https://github.com/mholt/caddy-l4).

Current supported handlers:
Currently supported handlers:

- l4echo (layer4.handlers.echo)
- l4proxy (layer4.handlers.proxy)
- `echo` (layer4.handlers.echo)
- `proxy_protocol` (layer4.handlers.proxy_protocol)
- `proxy` (layer4.handlers.proxy)

## Installation

Expand All @@ -15,34 +16,64 @@ $ xcaddy build --with github.com/RussellLuo/caddy-ext/layer4

## Caddyfile Syntax

### The `layer4` global option

```
layer4 {
# server 1
<listens...> {
l4echo
<handler>
...
}
# server 2
<listens...> {
l4proxy [<upstreams...>] {
# backends
to <upstreams...>
...
# load balancing
lb_policy <name> [<options...>]
lb_try_duration <duration>
lb_try_interval <interval>
# active health checking
health_port <port>
health_interval <interval>
health_timeout <duration>
}
<handler>
...
}
}
```

### Handlers

The `echo` handler:

```
echo
```

The `proxy_protocol` handler:

```
proxy_protocol {
timeout <duration>
allow <cidrs...>
}
```

The `proxy` handler:

```
proxy [<upstreams...>] {
# backends
to <upstreams...>
...
# load balancing
lb_policy <name> [<options...>]
lb_try_duration <duration>
lb_try_interval <interval>
# active health checking
health_port <port>
health_interval <interval>
health_timeout <duration>
# sending the PROXY protocol
proxy_protocol <version>
}
```


## Example

Expand All @@ -52,7 +83,7 @@ With the following Caddyfile:
{
layer4 {
:8080 {
l4proxy {
proxy {
to localhost:8081 localhost:8082
lb_policy round_robin
health_interval 5s
Expand Down
74 changes: 68 additions & 6 deletions layer4/caddyfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/mholt/caddy-l4/layer4"
"github.com/mholt/caddy-l4/modules/l4echo"
"github.com/mholt/caddy-l4/modules/l4proxy"
"github.com/mholt/caddy-l4/modules/l4proxyprotocol"
)

func init() {
Expand Down Expand Up @@ -43,12 +44,22 @@ func parseLayer4(d *caddyfile.Dispenser, _ interface{}) (interface{}, error) {

for d.NextBlock(1) {
switch d.Val() {
case "l4echo":
case "l4echo", "echo":
server.Routes = append(server.Routes, &layer4.Route{
HandlersRaw: []json.RawMessage{caddyconfig.JSONModuleObject(new(l4echo.Handler), "handler", "echo", nil)},
})
case "l4proxy":
handler, err := parseL4proxy(d)

case "proxy_protocol":
handler, err := parseProxyProtocol(d)
if err != nil {
return nil, err
}
server.Routes = append(server.Routes, &layer4.Route{
HandlersRaw: []json.RawMessage{caddyconfig.JSONModuleObject(handler, "handler", "proxy_protocol", nil)},
})

case "l4proxy", "proxy":
handler, err := parseProxy(d)
if err != nil {
return nil, err
}
Expand All @@ -69,9 +80,51 @@ func parseLayer4(d *caddyfile.Dispenser, _ interface{}) (interface{}, error) {
}, nil
}

// parseL4proxy sets up a "l4proxy" handler from Caddyfile tokens. Syntax:
// parseProxyProtocol sets up a "proxy_protocol" handler from Caddyfile tokens. Syntax:
//
// l4proxy [<upstreams...>] {
// proxy_protocol {
// timeout <duration>
// allow <cidrs...>
// }
//
func parseProxyProtocol(d *caddyfile.Dispenser) (*l4proxyprotocol.Handler, error) {
h := new(l4proxyprotocol.Handler)

// No same-line options are supported
if len(d.RemainingArgs()) > 0 {
return nil, d.ArgErr()
}

for nesting := d.Nesting(); d.NextBlock(nesting); {
switch d.Val() {
case "timeout":
if !d.NextArg() {
return nil, d.ArgErr()
}
timeout, err := caddy.ParseDuration(d.Val())
if err != nil {
return nil, d.Errf("parsing proxy_protocol timeout duration: %v", err)
}
h.Timeout = caddy.Duration(timeout)

case "allow":
args := d.RemainingArgs()
if len(args) == 0 {
return nil, d.ArgErr()
}
h.Allow = append(h.Allow, args...)

default:
return nil, d.ArgErr()
}
}

return h, nil
}

// parseL4proxy sets up a "proxy" handler from Caddyfile tokens. Syntax:
//
// proxy [<upstreams...>] {
// # backends
// to <upstreams...>
// ...
Expand All @@ -85,9 +138,12 @@ func parseLayer4(d *caddyfile.Dispenser, _ interface{}) (interface{}, error) {
// health_port <port>
// health_interval <interval>
// health_timeout <duration>
//
// # sending the PROXY protocol
// proxy_protocol <version>
// }
//
func parseL4proxy(d *caddyfile.Dispenser) (*l4proxy.Handler, error) {
func parseProxy(d *caddyfile.Dispenser) (*l4proxy.Handler, error) {
h := new(l4proxy.Handler)

appendUpstream := func(addresses ...string) {
Expand Down Expand Up @@ -211,6 +267,12 @@ func parseL4proxy(d *caddyfile.Dispenser) (*l4proxy.Handler, error) {
return nil, d.Errf("bad timeout value %s: %v", d.Val(), err)
}
h.HealthChecks.Active.Timeout = caddy.Duration(dur)

case "proxy_protocol":
if !d.NextArg() {
return nil, d.ArgErr()
}
h.ProxyProtocol = d.Val()
}
}

Expand Down
2 changes: 1 addition & 1 deletion layer4/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ go 1.14

require (
github.com/caddyserver/caddy/v2 v2.4.6
github.com/mholt/caddy-l4 v0.0.0-20211118173712-31d74d38aa3a
github.com/mholt/caddy-l4 v0.0.0-20220125094439-07bd718906ce
)
4 changes: 2 additions & 2 deletions layer4/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -725,8 +725,8 @@ github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyex
github.com/mholt/acmez v0.1.1/go.mod h1:8qnn8QA/Ewx8E3ZSsmscqsIjhhpxuy9vqdgbX2ceceM=
github.com/mholt/acmez v1.0.1 h1:J7uquHOKEmo71UDnVApy1sSLA0oF/r+NtVrNzMKKA9I=
github.com/mholt/acmez v1.0.1/go.mod h1:8qnn8QA/Ewx8E3ZSsmscqsIjhhpxuy9vqdgbX2ceceM=
github.com/mholt/caddy-l4 v0.0.0-20211118173712-31d74d38aa3a h1:SdsqNlUEMQkU0w75FqBaHAP4CKtfvr4/oGNbhSsr4zo=
github.com/mholt/caddy-l4 v0.0.0-20211118173712-31d74d38aa3a/go.mod h1:THjbirMPGk2ODmIfBKg/0VEDPVnM8ZXdKRXDJRaPlRE=
github.com/mholt/caddy-l4 v0.0.0-20220125094439-07bd718906ce h1:m3IZ/y8us8CQhvx+qw0P1X2kwlB3mmJO1he0ESp6IM4=
github.com/mholt/caddy-l4 v0.0.0-20220125094439-07bd718906ce/go.mod h1:THjbirMPGk2ODmIfBKg/0VEDPVnM8ZXdKRXDJRaPlRE=
github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
github.com/micromdm/scep/v2 v2.1.0 h1:2fS9Rla7qRR266hvUoEauBJ7J6FhgssEiq2OkSKXmaU=
github.com/micromdm/scep/v2 v2.1.0/go.mod h1:BkF7TkPPhmgJAMtHfP+sFTKXmgzNJgLQlvvGoOExBcc=
Expand Down

0 comments on commit 1c9850e

Please sign in to comment.