Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-pages.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorVladimir Shushlin <v.shushlin@gmail.com>2022-02-17 13:27:27 +0300
committerVladimir Shushlin <v.shushlin@gmail.com>2022-02-21 16:44:20 +0300
commit62a6491652aa6975d9ecf3b9e258766c886d49d4 (patch)
tree18a2ddf45d3e997dbb8ea6a6c27a7da26d6f88be /test
parent92fb5e54ad42ed489c4dd93eec69fb5876d11efe (diff)
feat: Add TLS rate limits
Changelog: added
Diffstat (limited to 'test')
-rw-r--r--test/acceptance/helpers_test.go12
-rw-r--r--test/acceptance/ratelimiter_test.go157
2 files changed, 168 insertions, 1 deletions
diff --git a/test/acceptance/helpers_test.go b/test/acceptance/helpers_test.go
index c44058ba..1b514a85 100644
--- a/test/acceptance/helpers_test.go
+++ b/test/acceptance/helpers_test.go
@@ -602,3 +602,15 @@ func copyFile(dest, src string) error {
_, err = io.Copy(destFile, srcFile)
return err
}
+
+// RequireMetricEqual requests prometheus metrics and makes sure metric is there
+func RequireMetricEqual(t *testing.T, metricsAddress, metricWithValue string) {
+ resp, err := http.Get(fmt.Sprintf("http://%s/metrics", metricsAddress))
+ require.NoError(t, err)
+
+ defer resp.Body.Close()
+ body, err := io.ReadAll(resp.Body)
+ require.NoError(t, err)
+
+ require.Contains(t, string(body), metricWithValue)
+}
diff --git a/test/acceptance/ratelimiter_test.go b/test/acceptance/ratelimiter_test.go
index 02ba54f5..365ba4cd 100644
--- a/test/acceptance/ratelimiter_test.go
+++ b/test/acceptance/ratelimiter_test.go
@@ -3,6 +3,7 @@ package acceptance_test
import (
"fmt"
"net/http"
+ "strconv"
"testing"
"time"
@@ -77,7 +78,7 @@ func TestIPRateLimits(t *testing.T) {
}
}
-func TestDomainateLimits(t *testing.T) {
+func TestDomainRateLimits(t *testing.T) {
testhelpers.StubFeatureFlagValue(t, feature.EnforceDomainRateLimits.EnvVariable, true)
for name, tc := range ratelimitedListeners {
@@ -112,6 +113,160 @@ func TestDomainateLimits(t *testing.T) {
}
}
+func TestTLSRateLimits(t *testing.T) {
+ rateLimit := 5
+
+ tests := map[string]struct {
+ spec ListenSpec
+ options []processOption
+ sourceIP string
+ featureName string
+ enforceEnabled bool
+ limitName string
+ }{
+ "https_with_domain_limit": {
+ spec: httpsListener,
+ options: []processOption{
+ withExtraArgument("metrics-address", ":42345"),
+ withExtraArgument("rate-limit-tls-domain", fmt.Sprint(rateLimit)),
+ withExtraArgument("rate-limit-tls-domain-burst", fmt.Sprint(rateLimit)),
+ },
+ sourceIP: "127.0.0.1",
+ featureName: feature.EnforceDomainTLSRateLimits.EnvVariable,
+ enforceEnabled: true,
+ limitName: "tls_connections_by_domain",
+ },
+ "https_with_domain_limit_not_enforced": {
+ spec: httpsListener,
+ options: []processOption{
+ withExtraArgument("metrics-address", ":42345"),
+ withExtraArgument("rate-limit-tls-domain", fmt.Sprint(rateLimit)),
+ withExtraArgument("rate-limit-tls-domain-burst", fmt.Sprint(rateLimit)),
+ },
+ sourceIP: "127.0.0.1",
+ featureName: feature.EnforceDomainTLSRateLimits.EnvVariable,
+ enforceEnabled: false,
+ limitName: "tls_connections_by_domain",
+ },
+ "https_with_ip_limit": {
+ spec: httpsListener,
+ options: []processOption{
+ withExtraArgument("metrics-address", ":42345"),
+ withExtraArgument("rate-limit-tls-source-ip", fmt.Sprint(rateLimit)),
+ withExtraArgument("rate-limit-tls-source-ip-burst", fmt.Sprint(rateLimit)),
+ },
+ sourceIP: "127.0.0.1",
+ featureName: feature.EnforceIPTLSRateLimits.EnvVariable,
+ enforceEnabled: true,
+ limitName: "tls_connections_by_source_ip",
+ },
+ "https_with_ip_limit_not_enforced": {
+ spec: httpsListener,
+ options: []processOption{
+ withExtraArgument("metrics-address", ":42345"),
+ withExtraArgument("rate-limit-tls-source-ip", fmt.Sprint(rateLimit)),
+ withExtraArgument("rate-limit-tls-source-ip-burst", fmt.Sprint(rateLimit)),
+ },
+ sourceIP: "127.0.0.1",
+ featureName: feature.EnforceIPTLSRateLimits.EnvVariable,
+ enforceEnabled: false,
+ limitName: "tls_connections_by_source_ip",
+ },
+ "proxyv2_with_domain_limit": {
+ spec: httpsProxyv2Listener,
+ options: []processOption{
+ withExtraArgument("metrics-address", ":42345"),
+ withExtraArgument("rate-limit-tls-domain", fmt.Sprint(rateLimit)),
+ withExtraArgument("rate-limit-tls-domain-burst", fmt.Sprint(rateLimit)),
+ },
+ sourceIP: "10.1.1.1",
+ featureName: feature.EnforceDomainTLSRateLimits.EnvVariable,
+ enforceEnabled: true,
+ limitName: "tls_connections_by_domain",
+ },
+ "proxyv2_with_domain_limit_not_enforced": {
+ spec: httpsProxyv2Listener,
+ options: []processOption{
+ withExtraArgument("metrics-address", ":42345"),
+ withExtraArgument("rate-limit-tls-domain", fmt.Sprint(rateLimit)),
+ withExtraArgument("rate-limit-tls-domain-burst", fmt.Sprint(rateLimit)),
+ },
+ sourceIP: "10.1.1.1",
+ featureName: feature.EnforceDomainTLSRateLimits.EnvVariable,
+ enforceEnabled: false,
+ limitName: "tls_connections_by_domain",
+ },
+ "proxyv2_with_ip_limit": {
+ spec: httpsProxyv2Listener,
+ options: []processOption{
+ withExtraArgument("metrics-address", ":42345"),
+ withExtraArgument("rate-limit-tls-source-ip", fmt.Sprint(rateLimit)),
+ withExtraArgument("rate-limit-tls-source-ip-burst", fmt.Sprint(rateLimit)),
+ },
+ sourceIP: "10.1.1.1",
+ featureName: feature.EnforceIPTLSRateLimits.EnvVariable,
+ enforceEnabled: true,
+ limitName: "tls_connections_by_source_ip",
+ },
+ "proxyv2_with_ip_limit_not_enforced": {
+ spec: httpsProxyv2Listener,
+ options: []processOption{
+ withExtraArgument("metrics-address", ":42345"),
+ withExtraArgument("rate-limit-tls-source-ip", fmt.Sprint(rateLimit)),
+ withExtraArgument("rate-limit-tls-source-ip-burst", fmt.Sprint(rateLimit)),
+ },
+ sourceIP: "10.1.1.1",
+ featureName: feature.EnforceIPTLSRateLimits.EnvVariable,
+ enforceEnabled: false,
+ limitName: "tls_connections_by_source_ip",
+ },
+ }
+
+ for name, tt := range tests {
+ t.Run(name, func(t *testing.T) {
+ testhelpers.StubFeatureFlagValue(t, tt.featureName, tt.enforceEnabled)
+
+ options := append(tt.options, withListeners([]ListenSpec{tt.spec}))
+ logBuf := RunPagesProcess(t, options...)
+
+ for i := 0; i < 10; i++ {
+ rsp, err := makeTLSRequest(t, tt.spec)
+
+ if i >= rateLimit {
+ assertLogFound(t, logBuf, []string{
+ "TLS connection rate-limited",
+ "\"req_host\":\"group.gitlab-example.com\"",
+ fmt.Sprintf("\"source_ip\":\"%s\"", tt.sourceIP),
+ "\"enforced\":" + strconv.FormatBool(tt.enforceEnabled)})
+
+ if tt.enforceEnabled {
+ require.Error(t, err)
+ require.Contains(t, err.Error(), "remote error: tls: internal error")
+ }
+
+ continue
+ }
+
+ require.NoError(t, err)
+ require.NoError(t, rsp.Body.Close())
+ require.Equal(t, http.StatusOK, rsp.StatusCode, "request: %d failed", i)
+ }
+ expectedMetric := fmt.Sprintf(
+ "gitlab_pages_rate_limit_blocked_count{enforced=\"%t\",limit_name=\"%s\"} 5",
+ tt.enforceEnabled, tt.limitName)
+
+ RequireMetricEqual(t, "127.0.0.1:42345", expectedMetric)
+ })
+ }
+}
+
+func makeTLSRequest(t *testing.T, spec ListenSpec) (*http.Response, error) {
+ req, err := http.NewRequest("GET", "https://group.gitlab-example.com/project", nil)
+ require.NoError(t, err)
+
+ return spec.Client().Do(req)
+}
+
func assertLogFound(t *testing.T, logBuf *LogCaptureBuffer, expectedLogs []string) {
t.Helper()