From 18c405703d4020d3341b37e1ccd414251a9f9ca6 Mon Sep 17 00:00:00 2001 From: Antonin Bas Date: Mon, 15 May 2023 18:21:54 -0700 Subject: [PATCH] Improve the cookieSecure config parameter We expose it in the Helm chart as security.cookieSecure. The default behavior when installing the Helm chart does not change: if HTTPS is enabled, it is set to true, otherwise it is set to false. However, by exposing it, we enable users who terminate TLS at Ingress (and hence keep HTTPS disabled in Antrea UI) to enable that option, which hardens security. We also enable it by default in the Viper config, which does not really have an impact on users. Note that it is not possible for a non-secure origin (HTTP website) to add the Secure attribute. Most modern browsers will not allow it and the cookie will be discarded. This is why we do not unconditionally set the Secure attribute. This restriction does not apply for localhost. Signed-off-by: Antonin Bas --- CONTRIBUTING.md | 2 +- build/charts/antrea-ui/README.md | 5 +++-- build/charts/antrea-ui/templates/NOTES.txt | 18 ++++++++++++------ .../antrea-ui/templates/_backend_conf.tpl | 2 +- build/charts/antrea-ui/templates/_helpers.tpl | 10 ++++++++++ .../charts/antrea-ui/templates/_nginx_conf.tpl | 3 ++- build/charts/antrea-ui/values.yaml | 12 ++++++++++-- docs/reference-deployments.md | 7 ++++--- pkg/config/server/config.go | 1 + 9 files changed, 44 insertions(+), 16 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index df75154f..e55925f3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -81,6 +81,6 @@ Kubeconfig file with enough permissions (using the default / admin Kubeconfig is the easiest way). 1. Build the backend with `make bin`. -2. Run the backend with `APP_ENV=dev ./bin/server -kubeconfig `. +2. Run the backend with `KUBECONFIG= APP_ENV=dev ./bin/server`. 3. Run the frontend with `cd client/web/antrea-ui/ && yarn start`. 4. You can access the UI in your browser by visiting `http://localhost:3000/`. diff --git a/build/charts/antrea-ui/README.md b/build/charts/antrea-ui/README.md index ed7d5ad5..3f5be336 100644 --- a/build/charts/antrea-ui/README.md +++ b/build/charts/antrea-ui/README.md @@ -20,7 +20,7 @@ Kubernetes: `>= 1.16.0-0` |-----|------|---------|-------------| | affinity | object | `{}` | Affinity for the Antrea UI Pod. | | backend.image | object | `{"pullPolicy":"IfNotPresent","repository":"antrea/antrea-ui-backend","tag":""}` | Container image to use for the Antrea UI backend. | -| backend.port | int | `8080` | Container port on which the backend will listen/ | +| backend.port | int | `8080` | Container port on which the backend will listen. | | backend.resources | object | `{}` | Resource requests and limits for the backend container. | | frontend.image | object | `{"pullPolicy":"IfNotPresent","repository":"antrea/antrea-ui-frontend","tag":""}` | Container image to use for the Antrea UI frontend. | | frontend.port | int | `3000` | Container port on which the frontend will listen. | @@ -30,7 +30,7 @@ Kubernetes: `>= 1.16.0-0` | https.auto.daysValid | int | `365` | Number of days for which the certificate will be valid. There is no automatic rotation with this method. | | https.auto.dnsNames | list | `[]` | DNS names to use in the certificate. | | https.auto.ipAddresses | list | `[]` | IP addresses to use in the certificate. | -| https.enable | bool | `false` | Enable HTTPS (only) for accessing the web UI. | +| https.enable | bool | `false` | Enable HTTPS (only) for accessing the web UI. When using an Ingress to terminate TLS, you do not need to enable HTTPS here. | | https.method | string | `"auto"` | Method for generating the TLS certificate for the web server. We support "auto", "user", "userCA", and "secret". With "auto", Helm will generate a new self-signed certificate every time the template function is executed. With "user", the user is responsible for providing a certificate and key, which will be used directly. With "userCA", the user is responsible for providing a CA certificate and key, which will be used to generate a signed certificate to be used by the web server. With "secret", the user is responsible for providing a secret of type kubernetes.io/tls, in the Namespace of the release. The secret must include the tls.crt and tls.key data fields. | | https.secret.secretName | string | `"antrea-ui-tls"` | Name of the secret containing the PEM data for the certificate and private key to use. Secret must be of type kubernetes.io/tls. The typical use case is a secret generated by cert-manager. The secret must exist in the Namespace of the Helm release (typically, kube-system). | | https.user | object | `{"cert":"","key":""}` | Use the provided TLS certificate and key. | @@ -47,6 +47,7 @@ Kubernetes: `>= 1.16.0-0` | nodeSelector | object | `{"kubernetes.io/os":"linux"}` | Node selector for the Antrea UI Pod. | | podAnnotations | object | `{}` | Annotations to be added to the Antrea UI Pod. | | podLabels | object | `{}` | Labels to be added to the Antrea UI Pod. | +| security.cookieSecure | bool | same as https.enable | Set the Secure attribute for Antrea UI cookies. The attribute is set by default when HTTPS is enabled in Antrea UI (by setting https.enable to true). When using an Ingress to terminate TLS, you should explicitly set cookieSecure to true for security hardening purposes. | | service.annotations | object | `{}` | Annotations to be added to the Service. | | service.externalTrafficPolicy | string | `nil` | Override the ExternalTrafficPolicy for the Service. Set it to Local to route Service traffic to Node-local endpoints only. | | service.labels | object | `{}` | Labels to be added to the Service. | diff --git a/build/charts/antrea-ui/templates/NOTES.txt b/build/charts/antrea-ui/templates/NOTES.txt index f9e3dfe5..2500e422 100644 --- a/build/charts/antrea-ui/templates/NOTES.txt +++ b/build/charts/antrea-ui/templates/NOTES.txt @@ -9,8 +9,8 @@ You are using version {{ .Chart.Version }} {{- $scheme = "https" }} {{- end }} -To access the UI, forward a local port to the antrea-ui service, and connect to -that port locally with your browser: +To access the UI, forward a local port to the antrea-ui service, and connect to that port locally +with your browser: $ kubectl -n {{ .Release.Namespace }} port-forward service/antrea-ui {{ $port }}:{{ .Values.service.port }} @@ -18,12 +18,18 @@ After running the command above, access "{{ $scheme }}://localhost:{{ $port }}" {{- if and .Values.https.enable (eq .Values.https.method "auto") }} -HTTPS is enabled to access the UI and a self-signed certificate was -automatically generated. You can access the certificate with the following -command: +HTTPS is enabled to access the UI and a self-signed certificate was automatically generated. You can +access the certificate with the following command: $ kubectl -n {{ .Release.Namespace }} get secret/antrea-ui-tls-helm -o jsonpath='{.data.tls\.crt}' | base64 --decode -{{ end -}} +{{- end }} + +{{- if and (not .Values.https.enable) (not (kindIs "bool" .Values.security.cookieSecure)) }} + +HTTPS is disabled. If you are using Ingress to expose the UI and you are terminating TLS at Ingress, +we recommend that you set security.cookieSecure to true. + +{{- end }} For the Antrea documentation, please visit https://antrea.io diff --git a/build/charts/antrea-ui/templates/_backend_conf.tpl b/build/charts/antrea-ui/templates/_backend_conf.tpl index b6039ae8..5749d852 100644 --- a/build/charts/antrea-ui/templates/_backend_conf.tpl +++ b/build/charts/antrea-ui/templates/_backend_conf.tpl @@ -3,5 +3,5 @@ addr: ":{{ .Values.backend.port }}" auth: basic: jwtKeyPath: "/app/jwt-key.pem" - cookieSecure: {{ .Values.https.enable }} + cookieSecure: {{ include "cookieSecure" . }} {{- end }} diff --git a/build/charts/antrea-ui/templates/_helpers.tpl b/build/charts/antrea-ui/templates/_helpers.tpl index eb0a50a5..8e9d2058 100644 --- a/build/charts/antrea-ui/templates/_helpers.tpl +++ b/build/charts/antrea-ui/templates/_helpers.tpl @@ -26,6 +26,16 @@ {{- print .Values.backend.image.repository ":" (include "backendImageTag" .) -}} {{- end -}} +{{- define "cookieSecure" -}} +{{- if eq .Values.security.cookieSecure true }} +{{- true }} +{{- else if eq .Values.security.cookieSecure false }} +{{- false }} +{{- else }} +{{- .Values.https.enable }} +{{- end }} +{{- end -}} + {{- define "validateValues" -}} {{- if .Values.https.enable -}} {{- if not ( has .Values.https.method ( list "auto" "user" "userCA" "secret" ) ) -}} diff --git a/build/charts/antrea-ui/templates/_nginx_conf.tpl b/build/charts/antrea-ui/templates/_nginx_conf.tpl index 85042d22..b4a972b7 100644 --- a/build/charts/antrea-ui/templates/_nginx_conf.tpl +++ b/build/charts/antrea-ui/templates/_nginx_conf.tpl @@ -33,7 +33,8 @@ server { proxy_hide_header Access-Control-Allow-Origin; proxy_pass http://127.0.0.1:{{ .Values.backend.port }}; # ensure the correct flags are set, even though the api server should already be setting them - {{- if .Values.https.enable }} + {{- $secure := include "cookieSecure" . -}} + {{- if eq $secure "true" }} proxy_cookie_flags ~ httponly secure samesite=strict; {{- else }} proxy_cookie_flags ~ httponly samesite=strict; diff --git a/build/charts/antrea-ui/values.yaml b/build/charts/antrea-ui/values.yaml index 12064154..31cad284 100644 --- a/build/charts/antrea-ui/values.yaml +++ b/build/charts/antrea-ui/values.yaml @@ -17,14 +17,22 @@ backend: repository: "antrea/antrea-ui-backend" pullPolicy: "IfNotPresent" tag: "" - # -- Container port on which the backend will listen/ + # -- Container port on which the backend will listen. port: 8080 # -- Resource requests and limits for the backend container. resources: {} +security: + # -- (bool) Set the Secure attribute for Antrea UI cookies. The attribute is set by default when HTTPS is + # enabled in Antrea UI (by setting https.enable to true). When using an Ingress to terminate TLS, + # you should explicitly set cookieSecure to true for security hardening purposes. + # @default -- same as https.enable + cookieSecure: + # HTTPS configuration for the Antrea UI. https: - # -- Enable HTTPS (only) for accessing the web UI. + # -- Enable HTTPS (only) for accessing the web UI. When using an Ingress to terminate TLS, you do + # not need to enable HTTPS here. enable: false # -- Method for generating the TLS certificate for the web server. We support "auto", "user", # "userCA", and "secret". With "auto", Helm will generate a new self-signed certificate every time diff --git a/docs/reference-deployments.md b/docs/reference-deployments.md index 04164c70..c9436ef1 100644 --- a/docs/reference-deployments.md +++ b/docs/reference-deployments.md @@ -239,11 +239,12 @@ spec: ### Install Antrea UI with Helm -You do not need any customization when installing the Antrea UI with Helm. Just -run: +You need very little customization when installing the Antrea UI with Helm. We +do recommend that you enable the [Secure attribute for cookies](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies) +when using HTTPS in order to harden security: ```bash -helm install antrea-ui antrea/antrea-ui --namespace kube-system +helm install antrea-ui antrea/antrea-ui --namespace kube-system --set security.cookieSecure=true ``` ### Create the Ingress Resource diff --git a/pkg/config/server/config.go b/pkg/config/server/config.go index 86a2cf9e..eb17ba85 100644 --- a/pkg/config/server/config.go +++ b/pkg/config/server/config.go @@ -80,6 +80,7 @@ func LoadConfig() (*Config, error) { // You can set defaults for configuration parameters here v.SetDefault("limits.maxLoginsPerSecond", DefaultMaxLoginsPerSecond) v.SetDefault("limits.maxTraceflowsPerHour", DefaultMaxTraceflowsPerHour) + v.SetDefault("auth.cookieSecure", true) // By default, look for a file named config (any supported extension) in the working directory. v.AddConfigPath(".")