[proxy] Add mTLS auth support for reverse proxy services#6048
[proxy] Add mTLS auth support for reverse proxy services#6048marcschwaiger wants to merge 6 commits intonetbirdio:mainfrom
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds mutual TLS (mTLS) support across management and proxy: new MTLS types and API/proto fields, service-side CA PEM validation and preservation, per-domain mTLS enforcement and client cert validation in the proxy, TLS SNI-based client-CA selection, and related tests. ChangesmTLS Authentication Support (End-to-End)
Sequence DiagramsequenceDiagram
participant Client
participant TLS as TLS Handler (SNI)
participant AuthMW as Auth Middleware
participant Validator as Cert Validator
participant App as Request Handler
Client->>TLS: TCP/TLS ClientHello (SNI)
TLS->>AuthMW: GetClientCAPool(hello.ServerName)
AuthMW-->>TLS: CA Pool (if configured)
TLS->>Client: Server requests client cert (if pool present)
Client->>TLS: Present Client Certificate
TLS->>AuthMW: HTTP request + TLS state
AuthMW->>Validator: validateClientCertificate(req, mtlsConfig)
alt MTLS not enabled
Validator-->>AuthMW: OK (pass-through)
AuthMW->>App: Continue (no mTLS)
App-->>Client: 200 OK
else Valid client cert
Validator-->>AuthMW: OK (verified)
AuthMW->>App: Continue (record mTLS auth)
App-->>Client: 200 OK
else Invalid or missing cert
Validator-->>AuthMW: Error
AuthMW-->>Client: 401 Unauthorized
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
shared/management/http/api/openapi.yml (1)
3330-3333: ⚡ Quick winMark
ca_cert_pemaswriteOnlyto reflect secret-handling intent.Given the “cleared in responses” behavior, adding
writeOnly: trueimproves generated client/docs safety and reduces accidental exposure risk.Proposed OpenAPI update
ca_cert_pem: type: string + writeOnly: true description: Trusted client CA certificate bundle in PEM format. Required on create when mTLS is enabled. Cleared in responses.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@shared/management/http/api/openapi.yml` around lines 3330 - 3333, The schema property ca_cert_pem is marked as sensitive ("cleared in responses") but not declared writeOnly; update the OpenAPI schema for the ca_cert_pem property to include writeOnly: true so generated clients/docs won't expose it in responses or outputs. Locate the ca_cert_pem property in the OpenAPI YAML and add the writeOnly flag alongside type/description/example for the ca_cert_pem field.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@proxy/server.go`:
- Around line 584-585: The TLS config currently only sets tls.RequestClientCert
which asks for certs but does not advertise acceptable CAs; wire the per-domain
CA pools created in updateMapping back into the TLS handshake by populating
tlsConfig.ClientCAs or by implementing tlsConfig.GetConfigForClient to return a
per-SNI tls.Config that sets ClientCAs and ClientAuth accordingly; locate the
mapping/store that updateMapping populates and use its CA pool for the matching
serverName in GetConfigForClient (or set the global tlsConfig.ClientCAs when a
single CA set is appropriate) so valid clients will see the acceptable CAs and
send certificates (avoid relying on test-injected req.TLS).
In `@shared/management/http/api/openapi.yml`:
- Around line 3330-3338: The schema allows enabled: true without a CA bundle;
update the OpenAPI schema for the object that declares enabled and ca_cert_pem
to add a conditional requirement so that when enabled is true the ca_cert_pem
field is required (use JSON Schema if/then or oneOf pattern): add an "if" that
checks properties.enabled: { const: true } and a corresponding "then" that sets
required: ["ca_cert_pem"], leaving the existing optional behavior when enabled
is false; target the same schema that defines the ca_cert_pem and enabled
properties to implement this validation.
---
Nitpick comments:
In `@shared/management/http/api/openapi.yml`:
- Around line 3330-3333: The schema property ca_cert_pem is marked as sensitive
("cleared in responses") but not declared writeOnly; update the OpenAPI schema
for the ca_cert_pem property to include writeOnly: true so generated
clients/docs won't expose it in responses or outputs. Locate the ca_cert_pem
property in the OpenAPI YAML and add the writeOnly flag alongside
type/description/example for the ca_cert_pem field.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: c30ae9f5-0ea5-4a59-b948-13611c159e1d
⛔ Files ignored due to path filters (1)
shared/management/proto/proxy_service.pb.gois excluded by!**/*.pb.go
📒 Files selected for processing (13)
management/internals/modules/reverseproxy/service/manager/manager.gomanagement/internals/modules/reverseproxy/service/manager/manager_test.gomanagement/internals/modules/reverseproxy/service/service.gomanagement/internals/modules/reverseproxy/service/service_test.goproxy/auth/auth.goproxy/internal/auth/middleware.goproxy/internal/auth/middleware_test.goproxy/internal/auth/mtls.goproxy/management_integration_test.goproxy/server.goshared/management/http/api/openapi.ymlshared/management/http/api/types.gen.goshared/management/proto/proxy_service.proto
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@proxy/server.go`:
- Around line 602-603: The base TLS config currently sets tlsConfig.ClientAuth =
tls.RequestClientCert and calls configureClientCAs globally; remove that global
ClientAuth change (leave default NoClientCert) and stop calling
configureClientCAs at the top-level so non-mTLS domains aren't asked for certs.
Instead, set tlsConfig.ClientAuth = tls.RequestClientCert and call
configureClientCAs only inside the per-SNI logic in GetConfigForClient (the
branch that matches mTLS hosts), so client cert requests are applied only for
matched mTLS hosts.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 32ee855b-614c-4170-8239-394729690501
📒 Files selected for processing (6)
proxy/internal/auth/middleware.goproxy/internal/auth/middleware_test.goproxy/management_integration_test.goproxy/server.goproxy/server_test.goshared/management/http/api/openapi.yml
🚧 Files skipped from review as they are similar to previous changes (1)
- shared/management/http/api/openapi.yml
611b915 to
4e1f2e0
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (1)
proxy/internal/auth/middleware.go (1)
116-124: 💤 Low valueConsider updating the comment to reflect mTLS check.
The comment on line 120 states domains "pass through after IP checks" but now they also pass through after the mTLS check. This could be clarified for accuracy.
📝 Suggested comment update
- // Domains with no authentication schemes pass through after IP checks. + // Domains with no authentication schemes pass through after IP and mTLS checks.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@proxy/internal/auth/middleware.go` around lines 116 - 124, Update the inline comment above the config.Schemes check to accurately reflect that domains with no authentication schemes are allowed to pass through after both IP and mTLS checks; specifically edit the comment near mw.checkMTLS(...) and the block that calls next.ServeHTTP(w, r) when len(config.Schemes) == 0 so it mentions mTLS in addition to IP checks.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@proxy/internal/auth/middleware.go`:
- Around line 116-124: Update the inline comment above the config.Schemes check
to accurately reflect that domains with no authentication schemes are allowed to
pass through after both IP and mTLS checks; specifically edit the comment near
mw.checkMTLS(...) and the block that calls next.ServeHTTP(w, r) when
len(config.Schemes) == 0 so it mentions mTLS in addition to IP checks.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 910d4947-b599-4224-bec7-b02b0a8d7846
📒 Files selected for processing (4)
proxy/internal/auth/middleware.goproxy/internal/auth/mtls.goproxy/server.goproxy/server_test.go
✅ Files skipped from review due to trivial changes (1)
- proxy/server_test.go
🚧 Files skipped from review as they are similar to previous changes (2)
- proxy/internal/auth/mtls.go
- proxy/server.go
|



Describe your changes
Add mTLS authentication for reverse proxy services
Issue ticket number and link
#5364 mTLS Auth for Proxy Services
Stack
Checklist
Documentation
Select exactly one:
Docs PR URL (required if "docs added" is checked)
Paste the PR link from https://github.com/netbirdio/docs here:
netbirdio/docs#720
See also: Dashboard PR URL
netbirdio/dashboard#628
Summary by CodeRabbit
New Features
Bug Fixes
Tests
Documentation