Skip to content

Commit 62d4ffc

Browse files
authored
Merge pull request #136 from scality/improvement/LOGC-54
LOGC-54: Add e2e test for TLS cipher suite and protocol in access logs
2 parents 18e9427 + 188558b commit 62d4ffc

3 files changed

Lines changed: 135 additions & 2 deletions

File tree

.github/workflows/e2e-tests.yaml

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ jobs:
3939
password: ${{ github.token }}
4040

4141
- name: Start Workbench
42-
uses: scality/workbench@v0.12.0
42+
uses: scality/workbench@v0.13.0
4343

4444
- name: Wait for all services
4545
run: |
@@ -112,6 +112,22 @@ jobs:
112112
fi
113113
echo "✓ S3 endpoint available"
114114
115+
echo "Waiting for S3 frontend (nginx) to be ready..."
116+
s3_frontend_ready=false
117+
for i in {1..30}; do
118+
if curl -sk https://localhost:443 >/dev/null 2>&1; then
119+
s3_frontend_ready=true
120+
break
121+
fi
122+
sleep 2
123+
done
124+
if [ "$s3_frontend_ready" = false ]; then
125+
echo "ERROR: S3 frontend (localhost:443) did not become available in time"
126+
docker logs workbench-s3-frontend || true
127+
exit 1
128+
fi
129+
echo "✓ S3 frontend available"
130+
115131
- name: Start log-courier
116132
env:
117133
LOG_COURIER_IMAGE: ghcr.io/${{ github.repository_owner }}/log-courier:${{ github.sha }}-debug

env/default/values.yaml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@ global:
44
features:
55
access_logging:
66
enabled: true
7+
s3_frontend:
8+
enabled: true
79

810
cloudserver:
9-
image: ghcr.io/scality/cloudserver:9.2.24
11+
image: ghcr.io/scality/cloudserver:9.2.32
1012

1113
vault:
1214
image: ghcr.io/scality/vault:7.84.0
@@ -19,3 +21,6 @@ clickhouse:
1921

2022
fluentbit:
2123
image: fluent/fluent-bit:3.0.2
24+
25+
nginx:
26+
image: nginx:1.27-alpine

test/e2e/tls_fields_test.go

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
package e2e_test
2+
3+
import (
4+
"bytes"
5+
"context"
6+
"crypto/tls"
7+
"net"
8+
"net/http"
9+
"os"
10+
"time"
11+
12+
"github.com/aws/aws-sdk-go-v2/aws"
13+
"github.com/aws/aws-sdk-go-v2/service/s3"
14+
. "github.com/onsi/ginkgo/v2"
15+
. "github.com/onsi/gomega"
16+
)
17+
18+
const (
19+
testS3FrontendEndpoint = "https://127.0.0.1:443"
20+
)
21+
22+
func newTLSS3Client(accessKeyID, secretAccessKey, endpoint string) *s3.Client {
23+
transport := &http.Transport{
24+
DialContext: (&net.Dialer{
25+
Timeout: 10 * time.Second,
26+
}).DialContext,
27+
TLSClientConfig: &tls.Config{
28+
InsecureSkipVerify: true, //nolint:gosec // self-signed cert in test environment
29+
},
30+
TLSHandshakeTimeout: 10 * time.Second,
31+
}
32+
33+
return s3.NewFromConfig(aws.Config{
34+
Region: testRegion,
35+
Credentials: aws.CredentialsProviderFunc(func(ctx context.Context) (aws.Credentials, error) {
36+
return aws.Credentials{
37+
AccessKeyID: accessKeyID,
38+
SecretAccessKey: secretAccessKey,
39+
}, nil
40+
}),
41+
HTTPClient: &http.Client{Transport: transport},
42+
}, func(o *s3.Options) {
43+
o.BaseEndpoint = aws.String(endpoint)
44+
o.UsePathStyle = true
45+
})
46+
}
47+
48+
var _ = Describe("TLS fields in access logs", func() {
49+
var testCtx *E2ETestContext
50+
51+
BeforeEach(func() {
52+
testCtx = setupE2ETest()
53+
})
54+
55+
AfterEach(func() {
56+
cleanupE2ETest(testCtx)
57+
})
58+
59+
It("logs CipherSuite and TLSVersion for requests through the S3 frontend", func(ctx context.Context) {
60+
endpoint := os.Getenv("E2E_S3_FRONTEND_ENDPOINT")
61+
if endpoint == "" {
62+
endpoint = testS3FrontendEndpoint
63+
}
64+
65+
accessKey := os.Getenv("E2E_S3_ACCESS_KEY_ID")
66+
if accessKey == "" {
67+
accessKey = testAccessKeyID
68+
}
69+
70+
secretKey := os.Getenv("E2E_S3_SECRET_ACCESS_KEY")
71+
if secretKey == "" {
72+
secretKey = testSecretAccessKey
73+
}
74+
75+
tlsClient := newTLSS3Client(accessKey, secretKey, endpoint)
76+
77+
testKey := "tls-test-object.txt"
78+
testContent := []byte("test data for TLS field verification")
79+
80+
_, err := tlsClient.PutObject(ctx, &s3.PutObjectInput{
81+
Bucket: aws.String(testCtx.SourceBucket),
82+
Key: aws.String(testKey),
83+
Body: bytes.NewReader(testContent),
84+
})
85+
Expect(err).NotTo(HaveOccurred(), "PUT through S3 frontend should succeed")
86+
87+
_, err = tlsClient.GetObject(ctx, &s3.GetObjectInput{
88+
Bucket: aws.String(testCtx.SourceBucket),
89+
Key: aws.String(testKey),
90+
})
91+
Expect(err).NotTo(HaveOccurred(), "GET through S3 frontend should succeed")
92+
93+
logs := testCtx.VerifyLogs(
94+
testCtx.ObjectOp("REST.PUT.OBJECT", testKey, 200).WithObjectSize(int64(len(testContent))),
95+
testCtx.ObjectOp("REST.GET.OBJECT", testKey, 200).WithBytesSent(int64(len(testContent))).WithObjectSize(int64(len(testContent))),
96+
)
97+
98+
for _, log := range logs {
99+
Expect(log.CipherSuite).NotTo(Equal("-"),
100+
"CipherSuite should be populated for TLS requests (got '-')")
101+
Expect(log.CipherSuite).NotTo(BeEmpty(),
102+
"CipherSuite should not be empty for TLS requests")
103+
104+
Expect(log.TLSVersion).NotTo(Equal("-"),
105+
"TLSVersion should be populated for TLS requests (got '-')")
106+
Expect(log.TLSVersion).NotTo(BeEmpty(),
107+
"TLSVersion should not be empty for TLS requests")
108+
Expect(log.TLSVersion).To(MatchRegexp(`^TLSv1\.[23]$`),
109+
"TLSVersion should be TLSv1.2 or TLSv1.3")
110+
}
111+
})
112+
})

0 commit comments

Comments
 (0)