Skip to content

Commit 53db798

Browse files
committed
address review comments
1 parent c2a9871 commit 53db798

File tree

2 files changed

+591
-0
lines changed

2 files changed

+591
-0
lines changed
Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
// Licensed to Elasticsearch B.V. under one or more contributor
2+
// license agreements. See the NOTICE file distributed with
3+
// this work for additional information regarding copyright
4+
// ownership. Elasticsearch B.V. licenses this file to you under
5+
// the Apache License, Version 2.0 (the "License"); you may
6+
// not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
//go:build example
19+
20+
package proxytest
21+
22+
import (
23+
"context"
24+
"crypto/tls"
25+
"crypto/x509"
26+
"net"
27+
"net/http"
28+
"net/http/httptest"
29+
"os"
30+
"path/filepath"
31+
"testing"
32+
33+
"github.com/stretchr/testify/require"
34+
35+
"github.com/elastic/elastic-agent-libs/testing/certutil"
36+
)
37+
38+
// TestRunHTTPSProxy is an example of how to use the proxytest outside tests,
39+
// and it instructs how to perform a request through the proxy using cURL.
40+
// From the repo's root, run this test with:
41+
// go test -tags example -v -run TestRunHTTPSProxy$ ./testing/proxytest
42+
func TestRunHTTPSProxy(t *testing.T) {
43+
// Create a temporary directory to store certificates
44+
tmpDir := t.TempDir()
45+
46+
// ========================= generate certificates =========================
47+
serverCAKey, serverCACert, serverCAPair, err := certutil.NewRootCA(
48+
certutil.WithCNPrefix("server"))
49+
require.NoError(t, err, "error creating root CA")
50+
51+
serverCert, _, err := certutil.GenerateChildCert(
52+
"localhost",
53+
[]net.IP{net.IPv4(127, 0, 0, 1), net.IPv6loopback, net.IPv6zero},
54+
serverCAKey,
55+
serverCACert, certutil.WithCNPrefix("server"))
56+
require.NoError(t, err, "error creating server certificate")
57+
serverCACertPool := x509.NewCertPool()
58+
serverCACertPool.AddCert(serverCACert)
59+
60+
proxyCAKey, proxyCACert, proxyCAPair, err := certutil.NewRootCA(
61+
certutil.WithCNPrefix("proxy"))
62+
require.NoError(t, err, "error creating root CA")
63+
64+
proxyCert, proxyCertPair, err := certutil.GenerateChildCert(
65+
"localhost",
66+
[]net.IP{net.IPv4(127, 0, 0, 1), net.IPv6loopback, net.IPv6zero},
67+
proxyCAKey,
68+
proxyCACert,
69+
certutil.WithCNPrefix("proxy"))
70+
require.NoError(t, err, "error creating server certificate")
71+
72+
clientCAKey, clientCACert, clientCAPair, err := certutil.NewRootCA(
73+
certutil.WithCNPrefix("client"))
74+
require.NoError(t, err, "error creating root CA")
75+
clientCACertPool := x509.NewCertPool()
76+
clientCACertPool.AddCert(clientCACert)
77+
78+
_, clientCertPair, err := certutil.GenerateChildCert(
79+
"localhost",
80+
[]net.IP{net.IPv4(127, 0, 0, 1), net.IPv6loopback, net.IPv6zero},
81+
clientCAKey,
82+
clientCACert,
83+
certutil.WithCNPrefix("client"))
84+
require.NoError(t, err, "error creating server certificate")
85+
86+
// =========================== save certificates ===========================
87+
serverCACertFile := filepath.Join(tmpDir, "serverCA.crt")
88+
if err := os.WriteFile(serverCACertFile, serverCAPair.Cert, 0644); err != nil {
89+
t.Fatal(err)
90+
}
91+
serverCAKeyFile := filepath.Join(tmpDir, "serverCA.key")
92+
if err := os.WriteFile(serverCAKeyFile, serverCAPair.Key, 0644); err != nil {
93+
t.Fatal(err)
94+
}
95+
96+
proxyCACertFile := filepath.Join(tmpDir, "proxyCA.crt")
97+
if err := os.WriteFile(proxyCACertFile, proxyCAPair.Cert, 0644); err != nil {
98+
t.Fatal(err)
99+
}
100+
proxyCAKeyFile := filepath.Join(tmpDir, "proxyCA.key")
101+
if err := os.WriteFile(proxyCAKeyFile, proxyCAPair.Key, 0644); err != nil {
102+
t.Fatal(err)
103+
}
104+
proxyCertFile := filepath.Join(tmpDir, "proxyCert.crt")
105+
if err := os.WriteFile(proxyCertFile, proxyCertPair.Cert, 0644); err != nil {
106+
t.Fatal(err)
107+
}
108+
proxyKeyFile := filepath.Join(tmpDir, "proxyCert.key")
109+
if err := os.WriteFile(proxyKeyFile, proxyCertPair.Key, 0644); err != nil {
110+
t.Fatal(err)
111+
}
112+
113+
clientCACertFile := filepath.Join(tmpDir, "clientCA.crt")
114+
if err := os.WriteFile(clientCACertFile, clientCAPair.Cert, 0644); err != nil {
115+
t.Fatal(err)
116+
}
117+
clientCAKeyFile := filepath.Join(tmpDir, "clientCA.key")
118+
if err := os.WriteFile(clientCAKeyFile, clientCAPair.Key, 0644); err != nil {
119+
t.Fatal(err)
120+
}
121+
clientCertCertFile := filepath.Join(tmpDir, "clientCert.crt")
122+
if err := os.WriteFile(clientCertCertFile, clientCertPair.Cert, 0644); err != nil {
123+
t.Fatal(err)
124+
}
125+
clientCertKeyFile := filepath.Join(tmpDir, "clientCert.key")
126+
if err := os.WriteFile(clientCertKeyFile, clientCertPair.Key, 0644); err != nil {
127+
t.Fatal(err)
128+
}
129+
130+
// ========================== create target server =========================
131+
targetHost := "not-a-server.co"
132+
server := httptest.NewUnstartedServer(http.HandlerFunc(
133+
func(w http.ResponseWriter, r *http.Request) {
134+
_, _ = w.Write([]byte("It works!"))
135+
}))
136+
server.TLS = &tls.Config{
137+
Certificates: []tls.Certificate{*serverCert},
138+
MinVersion: tls.VersionTLS13,
139+
}
140+
server.StartTLS()
141+
t.Logf("target server running on %s", server.URL)
142+
143+
// ============================== create proxy =============================
144+
proxy := New(t,
145+
WithVerboseLog(),
146+
WithRequestLog("https", t.Logf),
147+
WithRewrite(targetHost+":443", server.URL[8:]),
148+
WithMITMCA(proxyCAKey, proxyCACert),
149+
WithHTTPClient(&http.Client{
150+
Transport: &http.Transport{
151+
TLSClientConfig: &tls.Config{
152+
RootCAs: serverCACertPool,
153+
MinVersion: tls.VersionTLS13,
154+
},
155+
},
156+
}),
157+
WithServerTLSConfig(&tls.Config{
158+
Certificates: []tls.Certificate{*proxyCert},
159+
ClientCAs: clientCACertPool,
160+
ClientAuth: tls.VerifyClientCertIfGiven,
161+
MinVersion: tls.VersionTLS13,
162+
}))
163+
err = proxy.StartTLS()
164+
require.NoError(t, err, "error starting proxy")
165+
t.Logf("proxy running on %s", proxy.LocalhostURL)
166+
defer proxy.Close()
167+
168+
// ============================ test instructions ==========================
169+
170+
u := "https://" + targetHost
171+
t.Logf("make request to %q using proxy %q", u, proxy.LocalhostURL)
172+
173+
t.Logf(`curl \
174+
--proxy-cacert %s \
175+
--proxy-cert %s \
176+
--proxy-key %s \
177+
--cacert %s \
178+
--proxy %s \
179+
%s`,
180+
proxyCACertFile,
181+
clientCertCertFile,
182+
clientCertKeyFile,
183+
proxyCACertFile,
184+
proxy.URL,
185+
u,
186+
)
187+
188+
t.Log("CTRL+C to stop")
189+
<-context.Background().Done()
190+
}

0 commit comments

Comments
 (0)