Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamic reload of SSL certificates for NGINX Plus #4764

Merged
merged 57 commits into from
Dec 12, 2023
Merged
Show file tree
Hide file tree
Changes from 48 commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
232ae75
refactor helm args for deploy and daemonset, refactor several functio…
oseoin Dec 5, 2023
59c3f8e
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Dec 6, 2023
a83ec1e
fix lint warnings
oseoin Dec 6, 2023
ec73051
Merge branch 'helm-args-and-config-sig-refactor' of github.com:nginxi…
oseoin Dec 6, 2023
95cec66
lint-fixes
oseoin Dec 7, 2023
b32afbc
add flag for dynamic SSL reload
oseoin Dec 7, 2023
99b59e8
skip reload for certs if dynamic reload enabled
oseoin Dec 7, 2023
542e5e8
add dynamic certificate config
oseoin Dec 7, 2023
1d361eb
Merge branch 'main' into dynamic-reload-ssl
oseoin Dec 7, 2023
93c4260
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Dec 7, 2023
d7178c7
lint fixes
oseoin Dec 7, 2023
0f2c0d3
lint fixes
oseoin Dec 7, 2023
aa5347a
Merge branch 'dynamic-reload-ssl' of github.com:nginxinc/kubernetes-i…
oseoin Dec 7, 2023
dd41f82
Merge branch 'main' into dynamic-reload-ssl
oseoin Dec 8, 2023
2c59f5a
switch to template based reloading
oseoin Dec 8, 2023
7451781
switch to template based reloading
oseoin Dec 8, 2023
a85fa13
Merge branch 'main' into dynamic-reload-ssl
oseoin Dec 8, 2023
caead12
Merge branch 'dynamic-reload-ssl' of github.com:nginxinc/kubernetes-i…
oseoin Dec 8, 2023
584889c
Merge branch 'dynamic-reload-ssl' of github.com:nginxinc/kubernetes-i…
oseoin Dec 8, 2023
0e832a9
Merge branch 'dynamic-reload-ssl' of github.com:nginxinc/kubernetes-i…
oseoin Dec 8, 2023
aa0823a
Merge branch 'dynamic-reload-ssl' of github.com:nginxinc/kubernetes-i…
oseoin Dec 8, 2023
f454801
Merge branch 'dynamic-reload-ssl' of github.com:nginxinc/kubernetes-i…
oseoin Dec 8, 2023
fb6ea33
Merge branch 'main' into dynamic-reload-ssl
oseoin Dec 8, 2023
726bec6
trigger reloads on config change when dynamic reloads are enabled
oseoin Dec 8, 2023
5db4bf4
trigger reloads on config change when dynamic reloads are enabled
oseoin Dec 8, 2023
6902ceb
Merge branch 'dynamic-reload-ssl' of github.com:nginxinc/kubernetes-i…
oseoin Dec 8, 2023
2e9d62b
lint changes
oseoin Dec 8, 2023
77f3d0a
add certificate directory information to transportserver
oseoin Dec 11, 2023
7e27fe9
remove redundant manager changes
oseoin Dec 11, 2023
ae23006
remove redundant manager changes
oseoin Dec 11, 2023
83eeb3f
Merge branch 'dynamic-reload-ssl' of github.com:nginxinc/kubernetes-i…
oseoin Dec 11, 2023
16c2a45
fix bad merge
oseoin Dec 11, 2023
26e185e
fix lint issue
oseoin Dec 11, 2023
288b7db
add nolint for comparing file contents
oseoin Dec 11, 2023
91178e5
properly fix G304 in manager.go
oseoin Dec 11, 2023
a426dd0
add missing map for streams
oseoin Dec 11, 2023
d420a6d
add python test for dynamic SSL reloads
oseoin Dec 11, 2023
32b3a4c
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Dec 11, 2023
435e630
fix incorrect parameter value for transportServerConfig
oseoin Dec 11, 2023
2d2725a
Merge branch 'dynamic-reload-ssl' of github.com:nginxinc/kubernetes-i…
oseoin Dec 11, 2023
83e2558
refine TLS reload count test
oseoin Dec 11, 2023
e1be9ea
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Dec 11, 2023
3983f26
add secret checker for transportserver
oseoin Dec 11, 2023
4e113c8
dynamic reload test for virtualserver
oseoin Dec 11, 2023
3bd1d2d
Merge branch 'dynamic-reload-ssl' of github.com:nginxinc/kubernetes-i…
oseoin Dec 11, 2023
67cf342
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Dec 11, 2023
716c469
re-add secret log quote
oseoin Dec 11, 2023
183503d
Merge branch 'dynamic-reload-ssl' of github.com:nginxinc/kubernetes-i…
oseoin Dec 11, 2023
30b2f78
fix nil pointer on lbc.configMap
oseoin Dec 12, 2023
420e60e
stable sorting of upstreams for consistent config gen
oseoin Dec 12, 2023
d3853bc
transportserver dynamic reload test
oseoin Dec 12, 2023
a5b7867
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Dec 12, 2023
4bcf8db
add new tls certs for transportserver reload test
oseoin Dec 12, 2023
6db0b2d
Merge branch 'dynamic-reload-ssl' of github.com:nginxinc/kubernetes-i…
oseoin Dec 12, 2023
a98c6d0
Merge branch 'main' into dynamic-reload-ssl
oseoin Dec 12, 2023
a36a9f8
docs and upstream order stability for virtual server
oseoin Dec 12, 2023
cfd97c3
mr feedback - test renaming
oseoin Dec 12, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions charts/nginx-ingress/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -222,4 +222,5 @@ Build the args for the service binary.
- -ready-status={{ .Values.controller.readyStatus.enable }}
- -ready-status-port={{ .Values.controller.readyStatus.port }}
- -enable-latency-metrics={{ .Values.controller.enableLatencyMetrics }}
- -ssl-dynamic-reload={{ .Values.controller.enableSSLDynamicReload }}
{{- end -}}
8 changes: 8 additions & 0 deletions charts/nginx-ingress/values.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -1359,6 +1359,14 @@
"examples": [
false
]
},
"enableSSLDynamicReload": {
"type": "boolean",
"default": true,
"title": "Enable dynamic certificate reloads for NGINX Plus",
"examples": [
true
]
}
},
"examples": [
Expand Down
3 changes: 3 additions & 0 deletions charts/nginx-ingress/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,9 @@ controller:
## Configure root filesystem as read-only and add volumes for temporary data.
readOnlyRootFilesystem: false

## Enable dynamic reloading of certificates for NGINX Plus
enableSSLDynamicReload: true
oseoin marked this conversation as resolved.
Show resolved Hide resolved

rbac:
## Configures RBAC.
create: true
Expand Down
11 changes: 11 additions & 0 deletions cmd/nginx-ingress/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
"k8s.io/apimachinery/pkg/util/validation"
)

const (
dynamicSSLReloadParam = "ssl-dynamic-reload"
)

var (
healthStatus = flag.Bool("health-status", false,
`Add a location based on the value of health-status-uri to the default server. The location responds with the 200 status code for any request.
Expand Down Expand Up @@ -195,6 +199,8 @@

defaultHTTPSListenerPort = flag.Int("default-https-listener-port", 443, "Sets a custom port for the HTTPS `default_server`. [1024 - 65535]")

enableDynamicSSLReload = flag.Bool(dynamicSSLReloadParam, true, "Enable reloading of SSL Certificates without restarting the NGINX process. Requires -nginx-plus")

startupCheckFn func() error
)

Expand Down Expand Up @@ -269,6 +275,11 @@
if *ingressLink != "" && *externalService != "" {
glog.Fatal("ingresslink and external-service cannot both be set")
}

if *enableDynamicSSLReload && !*nginxPlus {
glog.V(3).Infof("%s flag requires -nginx-plus and will not be enabled", dynamicSSLReloadParam)
oseoin marked this conversation as resolved.
Show resolved Hide resolved
*enableDynamicSSLReload = false
}

Check warning on line 282 in cmd/nginx-ingress/flags.go

View check run for this annotation

Codecov / codecov/patch

cmd/nginx-ingress/flags.go#L279-L282

Added lines #L279 - L282 were not covered by tests
}

func initialChecks() {
Expand Down
25 changes: 14 additions & 11 deletions cmd/nginx-ingress/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@
EnableOIDC: *enableOIDC,
SSLRejectHandshake: sslRejectHandshake,
EnableCertManager: *enableCertManager,
DynamicSSLReload: *enableDynamicSSLReload,
StaticSSLPath: nginxManager.GetSecretsDir(),

Check warning on line 119 in cmd/nginx-ingress/main.go

View check run for this annotation

Codecov / codecov/patch

cmd/nginx-ingress/main.go#L118-L119

Added lines #L118 - L119 were not covered by tests
}

processNginxConfig(staticCfgParams, cfgParams, templateExecutor, nginxManager)
Expand All @@ -131,17 +133,18 @@

plusCollector, syslogListener, latencyCollector := createPlusAndLatencyCollectors(registry, constLabels, kubeClient, plusClient, staticCfgParams.NginxServiceMesh)
cnf := configs.NewConfigurator(configs.ConfiguratorParams{
NginxManager: nginxManager,
StaticCfgParams: staticCfgParams,
Config: cfgParams,
TemplateExecutor: templateExecutor,
TemplateExecutorV2: templateExecutorV2,
LatencyCollector: latencyCollector,
LabelUpdater: plusCollector,
IsPlus: *nginxPlus,
IsWildcardEnabled: isWildcardEnabled,
IsPrometheusEnabled: *enablePrometheusMetrics,
IsLatencyMetricsEnabled: *enableLatencyMetrics,
NginxManager: nginxManager,
StaticCfgParams: staticCfgParams,
Config: cfgParams,
TemplateExecutor: templateExecutor,
TemplateExecutorV2: templateExecutorV2,
LatencyCollector: latencyCollector,
LabelUpdater: plusCollector,
IsPlus: *nginxPlus,
IsWildcardEnabled: isWildcardEnabled,
IsPrometheusEnabled: *enablePrometheusMetrics,
IsLatencyMetricsEnabled: *enableLatencyMetrics,
IsDynamicSSLReloadEnabled: *enableDynamicSSLReload,

Check warning on line 147 in cmd/nginx-ingress/main.go

View check run for this annotation

Codecov / codecov/patch

cmd/nginx-ingress/main.go#L136-L147

Added lines #L136 - L147 were not covered by tests
})

controllerNamespace := os.Getenv("POD_NAMESPACE")
Expand Down
15 changes: 15 additions & 0 deletions internal/configs/commonhelpers/common_template_helpers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Package commonhelpers contains template helpers used in v1 and v2
package commonhelpers

import (
"strings"
)

// MakeSecretPath will return the path to the secret with the base secrets
// path replaced with the given variable
func MakeSecretPath(path, defaultPath, variable string, useVariable bool) string {
if useVariable {
return strings.Replace(path, defaultPath, variable, 1)
}
return path
}
63 changes: 63 additions & 0 deletions internal/configs/commonhelpers/common_template_helpers_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package commonhelpers

import (
"bytes"
"html/template"
"testing"
)

var helperFunctions = template.FuncMap{
"makeSecretPath": MakeSecretPath,
}

func TestMakeSecretPath(t *testing.T) {
t.Parallel()

tmpl := newMakeSecretPathTemplate(t)
testCases := []struct {
Secret string
Path string
Variable string
Enabled bool
expected string
}{
{
Secret: "/etc/nginx/secret/thing.crt",
Path: "/etc/nginx/secret",
Variable: "$secrets_path",
Enabled: true,
expected: "$secrets_path/thing.crt",
},
{
Secret: "/etc/nginx/secret/thing.crt",
Path: "/etc/nginx/secret",
Variable: "$secrets_path",
Enabled: false,
expected: "/etc/nginx/secret/thing.crt",
},
{
Secret: "/etc/nginx/secret/thing.crt",
expected: "/etc/nginx/secret/thing.crt",
},
}

for _, tc := range testCases {
var buf bytes.Buffer
err := tmpl.Execute(&buf, tc)
if err != nil {
t.Fatalf("Failed to execute the template %v", err)
}
if buf.String() != tc.expected {
t.Errorf("Template generated wrong config, got '%v' but expected '%v'.", buf.String(), tc.expected)
}
}
}

func newMakeSecretPathTemplate(t *testing.T) *template.Template {
t.Helper()
tmpl, err := template.New("testTemplate").Funcs(helperFunctions).Parse(`{{makeSecretPath .Secret .Path .Variable .Enabled}}`)
if err != nil {
t.Fatalf("Failed to parse template: %v", err)
}
return tmpl
}
2 changes: 2 additions & 0 deletions internal/configs/config_params.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ type StaticConfigParams struct {
EnableOIDC bool
SSLRejectHandshake bool
EnableCertManager bool
DynamicSSLReload bool
StaticSSLPath string
}

// GlobalConfigParams holds global configuration parameters. For now, it only holds listeners.
Expand Down
2 changes: 2 additions & 0 deletions internal/configs/configmaps.go
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,8 @@ func GenerateNginxMainConfig(staticCfgParams *StaticConfigParams, config *Config
InternalRouteServerName: staticCfgParams.InternalRouteServerName,
LatencyMetrics: staticCfgParams.EnableLatencyMetrics,
OIDC: staticCfgParams.EnableOIDC,
DynamicSSLReloadEnabled: staticCfgParams.DynamicSSLReload,
StaticSSLPath: staticCfgParams.StaticSSLPath,
}
return nginxCfg
}
Loading
Loading