2017-10-30 09:02:03 +00:00
|
|
|
package integration
|
|
|
|
|
|
|
|
import (
|
2024-01-09 16:00:07 +00:00
|
|
|
"bufio"
|
|
|
|
"net"
|
|
|
|
"testing"
|
2017-10-30 09:02:03 +00:00
|
|
|
"time"
|
|
|
|
|
2024-01-09 16:00:07 +00:00
|
|
|
"github.com/pires/go-proxyproto"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/stretchr/testify/suite"
|
2023-02-03 14:24:05 +00:00
|
|
|
"github.com/traefik/traefik/v3/integration/try"
|
2017-10-30 09:02:03 +00:00
|
|
|
)
|
|
|
|
|
2021-11-25 10:10:06 +00:00
|
|
|
type ProxyProtocolSuite struct {
|
|
|
|
BaseSuite
|
2024-01-09 16:00:07 +00:00
|
|
|
whoamiIP string
|
2021-11-25 10:10:06 +00:00
|
|
|
}
|
2017-10-30 09:02:03 +00:00
|
|
|
|
2024-01-09 16:00:07 +00:00
|
|
|
func TestProxyProtocolSuite(t *testing.T) {
|
|
|
|
suite.Run(t, new(ProxyProtocolSuite))
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *ProxyProtocolSuite) SetupSuite() {
|
|
|
|
s.BaseSuite.SetupSuite()
|
2021-11-25 10:10:06 +00:00
|
|
|
|
2024-01-09 16:00:07 +00:00
|
|
|
s.createComposeProject("proxy-protocol")
|
|
|
|
s.composeUp()
|
|
|
|
|
|
|
|
s.whoamiIP = s.getComposeServiceIP("whoami")
|
2017-10-30 09:02:03 +00:00
|
|
|
}
|
|
|
|
|
2024-01-09 16:00:07 +00:00
|
|
|
func (s *ProxyProtocolSuite) TearDownSuite() {
|
|
|
|
s.BaseSuite.TearDownSuite()
|
2019-08-26 12:40:04 +00:00
|
|
|
}
|
|
|
|
|
2024-01-09 16:00:07 +00:00
|
|
|
func (s *ProxyProtocolSuite) TestProxyProtocolTrusted() {
|
|
|
|
file := s.adaptFile("fixtures/proxy-protocol/proxy-protocol.toml", struct {
|
2017-10-30 09:02:03 +00:00
|
|
|
HaproxyIP string
|
|
|
|
WhoamiIP string
|
2024-01-09 16:00:07 +00:00
|
|
|
}{WhoamiIP: s.whoamiIP})
|
|
|
|
|
|
|
|
s.traefikCmd(withConfigFile(file))
|
|
|
|
|
|
|
|
err := try.GetRequest("http://127.0.0.1:8000/whoami", 10*time.Second)
|
|
|
|
require.NoError(s.T(), err)
|
|
|
|
|
|
|
|
content, err := proxyProtoRequest("127.0.0.1:8000", 1)
|
|
|
|
require.NoError(s.T(), err)
|
|
|
|
assert.Contains(s.T(), content, "X-Forwarded-For: 1.2.3.4")
|
|
|
|
|
|
|
|
content, err = proxyProtoRequest("127.0.0.1:8000", 2)
|
|
|
|
require.NoError(s.T(), err)
|
|
|
|
assert.Contains(s.T(), content, "X-Forwarded-For: 1.2.3.4")
|
2017-10-30 09:02:03 +00:00
|
|
|
}
|
|
|
|
|
2024-01-09 16:00:07 +00:00
|
|
|
func (s *ProxyProtocolSuite) TestProxyProtocolNotTrusted() {
|
|
|
|
file := s.adaptFile("fixtures/proxy-protocol/proxy-protocol.toml", struct {
|
2019-08-26 12:40:04 +00:00
|
|
|
HaproxyIP string
|
|
|
|
WhoamiIP string
|
2024-01-09 16:00:07 +00:00
|
|
|
}{WhoamiIP: s.whoamiIP})
|
|
|
|
|
|
|
|
s.traefikCmd(withConfigFile(file))
|
|
|
|
|
|
|
|
err := try.GetRequest("http://127.0.0.1:9000/whoami", 10*time.Second)
|
|
|
|
require.NoError(s.T(), err)
|
|
|
|
|
|
|
|
content, err := proxyProtoRequest("127.0.0.1:9000", 1)
|
|
|
|
require.NoError(s.T(), err)
|
|
|
|
assert.Contains(s.T(), content, "X-Forwarded-For: 127.0.0.1")
|
|
|
|
|
|
|
|
content, err = proxyProtoRequest("127.0.0.1:9000", 2)
|
|
|
|
require.NoError(s.T(), err)
|
|
|
|
assert.Contains(s.T(), content, "X-Forwarded-For: 127.0.0.1")
|
2019-08-26 12:40:04 +00:00
|
|
|
}
|
|
|
|
|
2024-01-09 16:00:07 +00:00
|
|
|
func proxyProtoRequest(address string, version byte) (string, error) {
|
|
|
|
// Open a TCP connection to the server
|
|
|
|
conn, err := net.Dial("tcp", address)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
defer conn.Close()
|
|
|
|
|
|
|
|
// Create a Proxy Protocol header with v1
|
|
|
|
proxyHeader := &proxyproto.Header{
|
|
|
|
Version: version,
|
|
|
|
Command: proxyproto.PROXY,
|
|
|
|
TransportProtocol: proxyproto.TCPv4,
|
|
|
|
DestinationAddr: &net.TCPAddr{
|
|
|
|
IP: net.ParseIP("127.0.0.1"),
|
|
|
|
Port: 8000,
|
|
|
|
},
|
|
|
|
SourceAddr: &net.TCPAddr{
|
|
|
|
IP: net.ParseIP("1.2.3.4"),
|
|
|
|
Port: 62541,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
// After the connection was created write the proxy headers first
|
|
|
|
_, err = proxyHeader.WriteTo(conn)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create an HTTP request
|
|
|
|
request := "GET /whoami HTTP/1.1\r\n" +
|
|
|
|
"Host: 127.0.0.1\r\n" +
|
|
|
|
"Connection: close\r\n" +
|
|
|
|
"\r\n"
|
|
|
|
|
|
|
|
// Write the HTTP request to the TCP connection
|
|
|
|
writer := bufio.NewWriter(conn)
|
|
|
|
_, err = writer.WriteString(request)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Flush the buffer to ensure the request is sent
|
|
|
|
err = writer.Flush()
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Read the response from the server
|
|
|
|
var content string
|
|
|
|
scanner := bufio.NewScanner(conn)
|
|
|
|
for scanner.Scan() {
|
|
|
|
content += scanner.Text() + "\n"
|
|
|
|
}
|
|
|
|
|
|
|
|
if scanner.Err() != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
return content, nil
|
2017-10-30 09:02:03 +00:00
|
|
|
}
|