Skip to content

Commit

Permalink
feat: (WIP) Proxy Protocol Check for Traffic Endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
a18e committed Apr 12, 2024
1 parent c921f3f commit 9fa9b51
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 1 deletion.
1 change: 1 addition & 0 deletions acceptance-tests/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ require (
github.com/gorilla/websocket v1.5.1
github.com/onsi/ginkgo/v2 v2.16.0
github.com/onsi/gomega v1.31.1
github.com/pires/go-proxyproto v0.7.0
golang.org/x/crypto v0.21.0
golang.org/x/net v0.22.0
gopkg.in/yaml.v2 v2.4.0
Expand Down
2 changes: 2 additions & 0 deletions acceptance-tests/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ github.com/onsi/ginkgo/v2 v2.16.0 h1:7q1w9frJDzninhXxjZd+Y/x54XNjG/UlRLIYPZafsPM
github.com/onsi/ginkgo/v2 v2.16.0/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs=
github.com/onsi/gomega v1.31.1 h1:KYppCUK+bUgAZwHOu7EXVBKyQA6ILvOESHkn/tgoqvo=
github.com/onsi/gomega v1.31.1/go.mod h1:y40C95dwAD1Nz36SsEnxvfFe8FFfNxzI5eJ0EYGyAy0=
github.com/pires/go-proxyproto v0.7.0 h1:IukmRewDQFWC7kfnb66CSomk2q/seBuilHBYFwyq0Hs=
github.com/pires/go-proxyproto v0.7.0/go.mod h1:Vz/1JPY/OACxWGQNIRY2BeyDmpoaWmEP40O9LbuiFR4=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
Expand Down
96 changes: 96 additions & 0 deletions acceptance-tests/proxy_protocol_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package acceptance_tests

import (
"fmt"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
proxyproto "github.com/pires/go-proxyproto"
"io"
"net"
"net/http"
)

var _ = Describe("Proxy Protocol", func() {
opsfileProxyProtocol := `---
# Enable Proxy Protocol
- type: replace
path: /instance_groups/name=haproxy/jobs/name=haproxy/properties/ha_proxy/accept_proxy?
value: true
`
It("Correctly proxies Proxy Protocol requests", func() {
haproxyBackendPort := 12000
haproxyInfo, _ := deployHAProxy(baseManifestVars{
haproxyBackendPort: haproxyBackendPort,
haproxyBackendServers: []string{"127.0.1"},
deploymentName: deploymentNameForTestNode(),
}, []string{opsfileProxyProtocol}, map[string]interface{}{}, true)

closeLocalServer, localPort := startDefaultTestServer()
defer closeLocalServer()

closeTunnel := setupTunnelFromHaproxyToTestServer(haproxyInfo, haproxyBackendPort, localPort)
defer closeTunnel()

By("Sending a request with Proxy Protocol Header to HAProxy")
err := performProxyProtocolRequest(haproxyInfo.PublicIP, 443)
Expect(err).NotTo(HaveOccurred())

By("Sending a request without Proxy Protocol Header to HAProxy")
expect400(http.Get(fmt.Sprintf("http://%s", haproxyInfo.PublicIP)))
})
})

func performProxyProtocolRequest(ip string, port int) error {
// Dial some proxy listener e.g. https://github.com/mailgun/proxyproto
target, err := net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", ip, port))
if err != nil {
return err
}

conn, err := net.DialTCP("tcp", nil, target)
if err != nil {
return err
}

defer func(conn *net.TCPConn) {
_ = conn.Close()
}(conn)

// Create a proxyprotocol header or use HeaderProxyFromAddrs() if you
// have two conn's
header := &proxyproto.Header{
Version: 1,
Command: proxyproto.PROXY,
TransportProtocol: proxyproto.TCPv4,
SourceAddr: &net.TCPAddr{
IP: net.ParseIP("10.1.1.1"),
Port: 1000,
},
DestinationAddr: &net.TCPAddr{
IP: net.ParseIP(ip),
Port: port,
},
}
// After the connection was created write the proxy headers first
_, err = header.WriteTo(conn)
if err != nil {
return err
}

_, err = io.WriteString(conn, "GET / HTTP/1.1\r\n\r\n")
if err != nil {
return err
}

// Read the response
buf := make([]byte, 1024)
_, err = conn.Read(buf)
if err != nil {
return err
}
// Get HTTP status code
if string(buf[9:12]) != "200" {
return fmt.Errorf("expected HTTP status code 200, got %s", string(buf))
}
return nil
}
3 changes: 2 additions & 1 deletion ci/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ RUN /usr/bin/python3 -m pip install -r /requirements.txt
# Install go dependencies
ENV GOBIN=/usr/local/bin
RUN go install github.com/onsi/ginkgo/v2/ginkgo@latest && \
go install github.com/geofffranks/spruce/cmd/spruce@latest
go install github.com/geofffranks/spruce/cmd/spruce@latest && \
go install github.com/pires/go-proxyproto@latest
5 changes: 5 additions & 0 deletions ci/scripts/acceptance-tests
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ if [ -n "$FOCUS" ]; then
fi

cd ${REPO_ROOT:?required}

# TODO TEMPORARY: REMOVE BEFORE MERGE
git config --global --add safe.directory /repo
git config --global --add safe.directory /repo/src/ttar

echo "----- Pulling in any git submodules..."
git submodule update --init --recursive --force

Expand Down

0 comments on commit 9fa9b51

Please sign in to comment.