Skip to content

Commit

Permalink
Add support proxyprotocol v2
Browse files Browse the repository at this point in the history
  • Loading branch information
c0va23 authored and traefiker committed Aug 26, 2019
1 parent 4ec90c5 commit e1831c4
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 16 deletions.
6 changes: 5 additions & 1 deletion docs/content/routing/entrypoints.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,11 @@ entryPoints:

## ProxyProtocol

Traefik supports [ProxyProtocol](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt).
Traefik supports [ProxyProtocol](https://www.haproxy.org/download/2.0/doc/proxy-protocol.txt) version 1 and 2.

If proxyprotocol header parsing is enabled for the entry point, this entry point can accept connections with or without proxyprotocol headers.

If the proxyprotocol header is passed, then the version is determined automatically.

??? example "Enabling Proxy Protocol with Trusted IPs"

Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ require (
github.com/VividCortex/gohistogram v1.0.0 // indirect
github.com/abbot/go-http-auth v0.0.0-00010101000000-000000000000
github.com/abronan/valkeyrie v0.0.0-20190802193736-ed4c4a229894
github.com/armon/go-proxyproto v0.0.0-20190211145416-68259f75880e
github.com/c0va23/go-proxyprotocol v0.9.1
github.com/cenkalti/backoff/v3 v3.0.0
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc // indirect
github.com/containous/alice v0.0.0-20181107144136-d83ebdd94cbd
Expand Down
5 changes: 3 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,15 @@ github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190808125512-07798873deee/go.mod
github.com/aliyun/aliyun-oss-go-sdk v0.0.0-20190307165228-86c17b95fcd5/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
github.com/apache/thrift v0.12.0 h1:pODnxUFNcjP9UTLZGTdeh+j16A8lJbRvD3rOtrk/7bs=
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
github.com/armon/go-proxyproto v0.0.0-20190211145416-68259f75880e h1:h0gP0hBU6DsA5IQduhLWGOEfIUKzJS5hhXQBSgHuF/g=
github.com/armon/go-proxyproto v0.0.0-20190211145416-68259f75880e/go.mod h1:QmP9hvJ91BbJmGVGSbutW19IC0Q9phDCLGaomwTJbgU=
github.com/aws/aws-sdk-go v1.16.23/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go v1.23.0 h1:ilfJN/vJtFo1XDFxB2YMBYGeOvGZl6Qow17oyD4+Z9A=
github.com/aws/aws-sdk-go v1.23.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/c0va23/go-proxyprotocol v0.9.1 h1:5BCkp0fDJOhzzH1lhjUgHhmZz9VvRMMif1U2D31hb34=
github.com/c0va23/go-proxyprotocol v0.9.1/go.mod h1:TNjUV+llvk8TvWJxlPYAeAYZgSzT/iicNr3nWBWX320=
github.com/cenkalti/backoff/v3 v3.0.0 h1:ske+9nBpD9qZsTBoF41nW5L+AIuFBKMeze18XQ3eG1c=
github.com/cenkalti/backoff/v3 v3.0.0/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs=
github.com/census-instrumentation/opencensus-proto v0.2.0 h1:LzQXZOgg4CQfE6bFvXGM30YZL1WW/M337pXml+GrcZ4=
Expand Down Expand Up @@ -203,6 +203,7 @@ github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfU
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903 h1:LbsanbbD6LieFkXbj9YNNBupiGHJgFeLpO0j0Fza1h8=
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0 h1:28o5sBqPkBsMGnC6b4MvE2TzSr5/AT4c/1fLqVGIwlk=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
Expand Down
61 changes: 55 additions & 6 deletions integration/proxy_protocol_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,34 @@ func (s *ProxyProtocolSuite) TestProxyProtocolTrusted(c *check.C) {
gatewayIP := s.composeProject.Container(c, "haproxy").NetworkSettings.Gateway
haproxyIP := s.composeProject.Container(c, "haproxy").NetworkSettings.IPAddress
whoamiIP := s.composeProject.Container(c, "whoami").NetworkSettings.IPAddress

file := s.adaptFile(c, "fixtures/proxy-protocol/with.toml", struct {
HaproxyIP string
WhoamiIP string
}{HaproxyIP: haproxyIP, WhoamiIP: whoamiIP})
defer os.Remove(file)

cmd, display := s.traefikCmd(withConfigFile(file))
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()

err = try.GetRequest("http://"+haproxyIP+"/whoami", 500*time.Millisecond,
try.StatusCodeIs(http.StatusOK),
try.BodyContains("X-Forwarded-For: "+gatewayIP))
c.Assert(err, checker.IsNil)
}

func (s *ProxyProtocolSuite) TestProxyProtocolV2Trusted(c *check.C) {
gatewayIP := s.composeProject.Container(c, "haproxy").NetworkSettings.Gateway
haproxyIP := s.composeProject.Container(c, "haproxy").NetworkSettings.IPAddress
whoamiIP := s.composeProject.Container(c, "whoami").NetworkSettings.IPAddress

file := s.adaptFile(c, "fixtures/proxy-protocol/with.toml", struct {
HaproxyIP string
WhoamiIP string
}{haproxyIP, whoamiIP})
}{HaproxyIP: haproxyIP, WhoamiIP: whoamiIP})
defer os.Remove(file)

cmd, display := s.traefikCmd(withConfigFile(file))
Expand All @@ -33,18 +57,42 @@ func (s *ProxyProtocolSuite) TestProxyProtocolTrusted(c *check.C) {
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()

err = try.GetRequest("http://"+haproxyIP+"/whoami", 500*time.Millisecond, try.StatusCodeIs(http.StatusOK), try.BodyContains("X-Forwarded-For: "+gatewayIP))
display(c)
err = try.GetRequest("http://"+haproxyIP+":81/whoami", 500*time.Millisecond,
try.StatusCodeIs(http.StatusOK),
try.BodyContains("X-Forwarded-For: "+gatewayIP))
c.Assert(err, checker.IsNil)
}

func (s *ProxyProtocolSuite) TestProxyProtocolNotTrusted(c *check.C) {
haproxyIP := s.composeProject.Container(c, "haproxy").NetworkSettings.IPAddress
whoamiIP := s.composeProject.Container(c, "whoami").NetworkSettings.IPAddress

file := s.adaptFile(c, "fixtures/proxy-protocol/without.toml", struct {
HaproxyIP string
WhoamiIP string
}{HaproxyIP: haproxyIP, WhoamiIP: whoamiIP})
defer os.Remove(file)

cmd, display := s.traefikCmd(withConfigFile(file))
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()

err = try.GetRequest("http://"+haproxyIP+"/whoami", 500*time.Millisecond,
try.StatusCodeIs(http.StatusOK),
try.BodyContains("X-Forwarded-For: "+haproxyIP))
c.Assert(err, checker.IsNil)
}

func (s *ProxyProtocolSuite) TestProxyProtocolV2NotTrusted(c *check.C) {
haproxyIP := s.composeProject.Container(c, "haproxy").NetworkSettings.IPAddress
whoamiIP := s.composeProject.Container(c, "whoami").NetworkSettings.IPAddress

file := s.adaptFile(c, "fixtures/proxy-protocol/without.toml", struct {
HaproxyIP string
WhoamiIP string
}{haproxyIP, whoamiIP})
}{HaproxyIP: haproxyIP, WhoamiIP: whoamiIP})
defer os.Remove(file)

cmd, display := s.traefikCmd(withConfigFile(file))
Expand All @@ -53,7 +101,8 @@ func (s *ProxyProtocolSuite) TestProxyProtocolNotTrusted(c *check.C) {
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()

err = try.GetRequest("http://"+haproxyIP+"/whoami", 500*time.Millisecond, try.StatusCodeIs(http.StatusOK), try.BodyContains("X-Forwarded-For: "+haproxyIP))
display(c)
err = try.GetRequest("http://"+haproxyIP+":81/whoami", 500*time.Millisecond,
try.StatusCodeIs(http.StatusOK),
try.BodyContains("X-Forwarded-For: "+haproxyIP))
c.Assert(err, checker.IsNil)
}
11 changes: 10 additions & 1 deletion integration/resources/haproxy/haproxy.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,15 @@ frontend TestServerTest
mode tcp
default_backend TestServerNodes

frontend TestServerTestV2
bind 0.0.0.0:81
mode tcp
default_backend TestServerNodesV2

backend TestServerNodes
mode tcp
server TestServer01 172.17.0.1:8000 send-proxy
server TestServer01 172.17.0.1:8000 send-proxy

backend TestServerNodesV2
mode tcp
server TestServer01 172.17.0.1:8000 send-proxy-v2
9 changes: 4 additions & 5 deletions pkg/server/server_entrypoint_tcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"sync"
"time"

"github.com/armon/go-proxyproto"
proxyprotocol "github.com/c0va23/go-proxyprotocol"
"github.com/containous/traefik/v2/pkg/config/static"
"github.com/containous/traefik/v2/pkg/ip"
"github.com/containous/traefik/v2/pkg/log"
Expand Down Expand Up @@ -240,10 +240,9 @@ func buildProxyProtocolListener(ctx context.Context, entryPoint *static.EntryPoi

log.FromContext(ctx).Infof("Enabling ProxyProtocol for trusted IPs %v", entryPoint.ProxyProtocol.TrustedIPs)

return &proxyproto.Listener{
Listener: listener,
SourceCheck: sourceCheck,
}, nil
return proxyprotocol.NewDefaultListener(listener).
WithSourceChecker(sourceCheck).
WithLogger(log.FromContext(ctx)), nil
}

func buildListener(ctx context.Context, entryPoint *static.EntryPoint) (net.Listener, error) {
Expand Down

0 comments on commit e1831c4

Please sign in to comment.