diff --git a/content/ngf/how-to/data-plane-configuration.md b/content/ngf/how-to/data-plane-configuration.md index 560b91d240..b090a63669 100644 --- a/content/ngf/how-to/data-plane-configuration.md +++ b/content/ngf/how-to/data-plane-configuration.md @@ -272,6 +272,44 @@ of a few arguments. {{< /call-out >}} --- +## Configure the data plane log format + +NGINX records client requests immediately after each request is processed. You can use the `NginxProxy` resource to dynamically configure the access log format. + +The following command creates a basic `NginxProxy` that defines a custom log format `$remote_addr - [$time_local] "$request" $status $body_bytes_sent`: + +```yaml +kubectl apply -f - <}} File destinations in `logging.accessLog` are not currently supported it is always set to `/dev/stdout`. {{< /call-out >}} + +--- + ### Run NGINX Gateway Fabric with NGINX in debug mode To run NGINX Gateway Fabric with NGINX in debug mode, during [installation]({{< ref "/ngf/install/" >}}), follow these additional steps: @@ -327,12 +365,11 @@ kind: NginxProxy metadata: name: ngf-proxy-config spec: - config: - rewriteClientIP: - mode: ProxyProtocol - trustedAddresses: - - type: CIDR - value: "76.89.90.11/24" + rewriteClientIP: + mode: ProxyProtocol + trustedAddresses: + - type: CIDR + value: "76.89.90.11/24" EOF ``` @@ -364,8 +401,6 @@ spec: terminationGracePeriodSeconds: 90 replicas: 2 service: - annotations: - service.beta.kubernetes.io/aws-load-balancer-type: "nlb" type: LoadBalancer loadBalancerIP: "192.87.9.1" EOF diff --git a/content/ngf/overview/gateway-api-compatibility.md b/content/ngf/overview/gateway-api-compatibility.md index 79a5b503e1..bf82faf374 100644 --- a/content/ngf/overview/gateway-api-compatibility.md +++ b/content/ngf/overview/gateway-api-compatibility.md @@ -22,7 +22,7 @@ Learn which Gateway API resources NGINX Gateway Fabric supports and to which lev | [TLSRoute](#tlsroute) | Supported | Not supported | Not supported | v1alpha2 | Experimental | | [TCPRoute](#tcproute) | Not supported | Not supported | Not supported | v1alpha2 | Experimental | | [UDPRoute](#udproute) | Not supported | Not supported | Not supported | v1alpha2 | Experimental | -| [BackendTLSPolicy](#backendtlspolicy) | Partially Supported | Supported | Partially supported | v1alpha3 | Experimental | +| [BackendTLSPolicy](#backendtlspolicy) | Partially Supported | Supported | Partially supported | v1 | Standard | | [Custom policies](#custom-policies) | N/A | N/A | Supported | N/A | N/A | {{< /table >}} @@ -73,6 +73,7 @@ NGINX Gateway Fabric supports a single GatewayClass resource configured with the a different GatewayClass name is provided to the controller via the command-line argument. - `SupportedVersion/True/SupportedVersion` - `SupportedVersion/False/UnsupportedVersion` + - `supportedFeatures` - supported. ### Gateway @@ -107,7 +108,10 @@ See the [controller]({{< ref "/ngf/reference/cli-help.md#controller">}}) command - `addresses`: Valid IPAddresses will be added to the `externalIP` field in the related Services fronting NGINX. Users should ensure that the IP Family of the address matches the IP Family set in the NginxProxy resource (default is dual, meaning both IPv4 and IPv6), otherwise there may be networking issues. - `type`: Partially supported. Allowed value: `IPAddress`. - `value`: Partially supported. Dynamic address allocation when value is unspecified is not supported. - - `backendTLS`: Not supported. + - `TLS`: + - `frontend`: Not supported. + - `backend`: + - `clientCertificateRef`: Supported. - `allowedListeners`: Not supported. - `status` - `addresses`: Partially supported (LoadBalancer and ClusterIP). @@ -322,7 +326,7 @@ Fields: {{< table >}} | Resource | Core Support Level | Extended Support Level | Implementation-Specific Support Level | API Version | API Release Channel | |------------------|---------------------|------------------------|---------------------------------------|-------------|---------------------| -| BackendTLSPolicy | Partially Supported | Supported | Partially Supported | v1alpha3 | Experimental | +| BackendTLSPolicy | Supported | Supported | Partially Supported | v1 | Standard | {{< /table >}} Fields: @@ -348,6 +352,10 @@ Fields: - `conditions`: Partially supported. Supported (Condition/Status/Reason): - `Accepted/True/PolicyReasonAccepted` - `Accepted/False/PolicyReasonInvalid` + - `Accepted/False/NoValidCACertificate` + - `ResolvedRefs/True/ResolvedRefs` + - `ResolvedRefs/False/InvalidCACertificateRef` + - `ResolvedRefs/False/InvalidKind` {{< call-out "note" >}} If multiple `backendRefs` are defined for a HTTPRoute rule, all the referenced Services *must* have matching BackendTLSPolicy configuration. BackendTLSPolicy configuration is considered to be matching if 1. CACertRefs reference the same ConfigMap, or 2. WellKnownCACerts are the same, and 3. Hostname is the same. {{< /call-out >}} diff --git a/content/ngf/reference/api.md b/content/ngf/reference/api.md index 6307f9ab7e..1fb0c7bbb3 100644 --- a/content/ngf/reference/api.md +++ b/content/ngf/reference/api.md @@ -27,8 +27,6 @@ Resource Types:
  • NginxGateway
  • -ObservabilityPolicy -
  • SnippetsFilter
  • UpstreamSettingsPolicy @@ -125,8 +123,8 @@ ClientKeepAlive targetRef
    - -sigs.k8s.io/gateway-api/apis/v1alpha2.LocalPolicyTargetReference + +sigs.k8s.io/gateway-api/apis/v1.LocalPolicyTargetReference @@ -143,8 +141,8 @@ Support: Gateway, HTTPRoute, GRPCRoute.

    status
    - -sigs.k8s.io/gateway-api/apis/v1alpha2.PolicyStatus + +sigs.k8s.io/gateway-api/apis/v1.PolicyStatus @@ -245,114 +243,6 @@ NginxGatewayStatus -

    ObservabilityPolicy - -

    -

    -

    ObservabilityPolicy is a Direct Attached Policy. It provides a way to configure observability settings for -the NGINX Gateway Fabric data plane. Used in conjunction with the NginxProxy CRD that is attached to the -GatewayClass parametersRef.

    -

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    FieldDescription
    -apiVersion
    -string
    - -gateway.nginx.org/v1alpha1 - -
    -kind
    -string -
    ObservabilityPolicy
    -metadata
    - - -Kubernetes meta/v1.ObjectMeta - - -
    -Refer to the Kubernetes API documentation for the fields of the -metadata field. -
    -spec
    - - -ObservabilityPolicySpec - - -
    -

    Spec defines the desired state of the ObservabilityPolicy.

    -
    -
    - - - - - - - - - -
    -tracing
    - - -Tracing - - -
    -(Optional) -

    Tracing allows for enabling and configuring tracing.

    -
    -targetRefs
    - - -[]sigs.k8s.io/gateway-api/apis/v1alpha2.LocalPolicyTargetReference - - -
    -

    TargetRefs identifies the API object(s) to apply the policy to. -Objects must be in the same namespace as the policy. -Support: HTTPRoute, GRPCRoute.

    -
    -
    -status
    - - -sigs.k8s.io/gateway-api/apis/v1alpha2.PolicyStatus - - -
    -

    Status defines the state of the ObservabilityPolicy.

    -

    SnippetsFilter

    @@ -542,8 +432,8 @@ UpstreamKeepAlive targetRefs
    - -[]sigs.k8s.io/gateway-api/apis/v1alpha2.LocalPolicyTargetReference + +[]sigs.k8s.io/gateway-api/apis/v1.LocalPolicyTargetReference @@ -561,8 +451,8 @@ Support: Service

    status
    - -sigs.k8s.io/gateway-api/apis/v1alpha2.PolicyStatus + +sigs.k8s.io/gateway-api/apis/v1.PolicyStatus @@ -794,8 +684,8 @@ ClientKeepAlive targetRef
    - -sigs.k8s.io/gateway-api/apis/v1alpha2.LocalPolicyTargetReference + +sigs.k8s.io/gateway-api/apis/v1.LocalPolicyTargetReference @@ -1085,55 +975,6 @@ Logging -

    ObservabilityPolicySpec - -

    -

    -(Appears on: -ObservabilityPolicy) -

    -

    -

    ObservabilityPolicySpec defines the desired state of the ObservabilityPolicy.

    -

    - - - - - - - - - - - - - - - - - -
    FieldDescription
    -tracing
    - - -Tracing - - -
    -(Optional) -

    Tracing allows for enabling and configuring tracing.

    -
    -targetRefs
    - - -[]sigs.k8s.io/gateway-api/apis/v1alpha2.LocalPolicyTargetReference - - -
    -

    TargetRefs identifies the API object(s) to apply the policy to. -Objects must be in the same namespace as the policy. -Support: HTTPRoute, GRPCRoute.

    -

    Size (string alias)

    @@ -1314,7 +1155,6 @@ and the status of the SnippetsFilter with respect to each controller.

    (Appears on: -Tracing, Telemetry, Tracing)

    @@ -1355,154 +1195,6 @@ Format: must have all ‘“’ escaped and must not contain any &ls -

    TraceContext -(string alias)

    -

    -

    -(Appears on: -Tracing) -

    -

    -

    TraceContext specifies how to propagate traceparent/tracestate headers.

    -

    - - - - - - - - - - - - - - - - -
    ValueDescription

    "extract"

    TraceContextExtract uses an existing trace context from the request, so that the identifiers -of a trace and the parent span are inherited from the incoming request.

    -

    "ignore"

    TraceContextIgnore skips context headers processing.

    -

    "inject"

    TraceContextInject adds a new context to the request, overwriting existing headers, if any.

    -

    "propagate"

    TraceContextPropagate updates the existing context (combines extract and inject).

    -
    -

    TraceStrategy -(string alias)

    -

    -

    -(Appears on: -Tracing) -

    -

    -

    TraceStrategy defines the tracing strategy.

    -

    - - - - - - - - - - - - -
    ValueDescription

    "parent"

    TraceStrategyParent enables tracing and only records spans if the parent span was sampled.

    -

    "ratio"

    TraceStrategyRatio enables ratio-based tracing, defaulting to 100% sampling rate.

    -
    -

    Tracing - -

    -

    -(Appears on: -ObservabilityPolicySpec) -

    -

    -

    Tracing allows for enabling and configuring OpenTelemetry tracing.

    -

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    FieldDescription
    -strategy
    - - -TraceStrategy - - -
    -

    Strategy defines if tracing is ratio-based or parent-based.

    -
    -ratio
    - -int32 - -
    -(Optional) -

    Ratio is the percentage of traffic that should be sampled. Integer from 0 to 100. -By default, 100% of http requests are traced. Not applicable for parent-based tracing. -If ratio is set to 0, tracing is disabled.

    -
    -context
    - - -TraceContext - - -
    -(Optional) -

    Context specifies how to propagate traceparent/tracestate headers. -Default: https://nginx.org/en/docs/ngx_otel_module.html#otel_trace_context

    -
    -spanName
    - -string - -
    -(Optional) -

    SpanName defines the name of the Otel span. By default is the name of the location for a request. -If specified, applies to all locations that are created for a route. -Format: must have all ‘“’ escaped and must not contain any ‘$’ or end with an unescaped ‘\’ -Examples of invalid names: some-$value, quoted-“value”-name, unescaped

    -
    -spanAttributes
    - - -[]SpanAttribute - - -
    -(Optional) -

    SpanAttributes are custom key/value attributes that are added to each span.

    -

    UpstreamKeepAlive

    @@ -1637,8 +1329,8 @@ UpstreamKeepAlive targetRefs
    - -[]sigs.k8s.io/gateway-api/apis/v1alpha2.LocalPolicyTargetReference + +[]sigs.k8s.io/gateway-api/apis/v1.LocalPolicyTargetReference @@ -1969,8 +1661,8 @@ Tracing targetRefs
    - -[]sigs.k8s.io/gateway-api/apis/v1alpha2.LocalPolicyTargetReference + +[]sigs.k8s.io/gateway-api/apis/v1.LocalPolicyTargetReference @@ -1989,8 +1681,8 @@ be unique across all targetRef entries in the ObservabilityPolicy.

    status
    - -sigs.k8s.io/gateway-api/apis/v1alpha2.PolicyStatus + +sigs.k8s.io/gateway-api/apis/v1.PolicyStatus @@ -2847,6 +2539,53 @@ bool +

    NginxAccessLog + +

    +

    +(Appears on: +NginxLogging) +

    +

    +

    NginxAccessLog defines the configuration for an NGINX access log.

    +

    + + + + + + + + + + + + + + + + + +
    FieldDescription
    +disable
    + +bool + +
    +(Optional) +

    Disable turns off access logging when set to true.

    +
    +format
    + +string + +
    +(Optional) +

    Format specifies the custom log format string. +If not specified, NGINX default ‘combined’ format is used. +For now only path /dev/stdout can be used. +See https://nginx.org/en/docs/http/ngx_http_log_module.html#log_format

    +

    NginxErrorLogLevel (string alias)

    @@ -2940,6 +2679,21 @@ AgentLogLevel re-roll of the NGINX deployment.

    + + +accessLog
    + + +NginxAccessLog + + + + +(Optional) +

    AccessLog defines the access log settings, including format itself and disabling option. +For now only path /dev/stdout can be used.

    + +

    NginxPlus @@ -3303,8 +3057,8 @@ Tracing targetRefs
    - -[]sigs.k8s.io/gateway-api/apis/v1alpha2.LocalPolicyTargetReference + +[]sigs.k8s.io/gateway-api/apis/v1.LocalPolicyTargetReference diff --git a/content/ngf/traffic-security/secure-backend.md b/content/ngf/traffic-security/secure-backend.md index 3475fd9666..a885e2e3e5 100644 --- a/content/ngf/traffic-security/secure-backend.md +++ b/content/ngf/traffic-security/secure-backend.md @@ -1,5 +1,5 @@ --- -title: Securing backend traffic +title: Securing backend traffic using mutual TLS weight: 200 toc: true nd-content-type: how-to @@ -7,27 +7,48 @@ nd-product: FABRIC nd-docs: DOCS-1423 --- -Learn how to encrypt HTTP traffic between NGINX Gateway Fabric and your backend pods. +Learn how to encrypt HTTP traffic between NGINX Gateway Fabric and your backend pods using mutual TLS between Gateway and Backend applications. ## Overview -In this guide, we will show how to specify the TLS configuration of the connection from the Gateway to a backend pod with the Service API object using a [BackendTLSPolicy](https://gateway-api.sigs.k8s.io/api-types/backendtlspolicy/). - -The intended use-case is when a service or backend owner is managing their own TLS and NGINX Gateway Fabric needs to know how to connect to this backend pod that has its own certificate over HTTPS. +In this guide, you configure the TLS connection from the Gateway to a secure application using [BackendTLSPolicy](https://gateway-api.sigs.k8s.io/api-types/backendtlspolicy/) together with the Gateway’s backend TLS settings. The examples show how to validate the backend’s certificate and present a client certificate, so that traffic between the Gateway and the application is protected with mutual TLS. + +The intended use case is when a service or backend owner manages their own HTTPS configuration and certificates, and NGINX Gateway Fabric needs to know how to connect securely to this backend over HTTPS while also proving its own identity with a client certificate. This ensures that all traffic between the Gateway and the application is secured. + +The following diagram shows how the mTLS handshake takes place between NGINX Gateway Fabric and the secure-app application: + +```mermaid +sequenceDiagram + participant client as Client + participant gw as NGINX Gateway Fabric + participant app as secure-app Application + + client->>gw: Request + gw->>app: HTTPS request + gw->>app: start TLS handshake + app->>gw: request client certificate + gw->>app: present client certificate from Secret: gateway-presents-this-cert-for-validation + app->>app: validate client certificate using ConfigMap: validate-gateway-cert-against-this-ca + app->>gw: present backend certificate + gw->>gw: validate backend certificate using BackendTLSPolicy and ConfigMap: backend-cert + app->>gw: complete TLS handshake + app-->>gw: HTTPS response + gw-->>client: Response +``` ## Note on Gateway API Experimental Features -{{< call-out "important" >}} BackendTLSPolicy is a Gateway API resource from the experimental release channel. {{< /call-out >}} +{{< call-out "important" >}} [GatewayBackendTLS](https://gateway-api.sigs.k8s.io/reference/spec/#gatewaybackendtls) is an experimental field. {{< /call-out >}} {{< include "/ngf/installation/install-gateway-api-experimental-features.md" >}} ## Before you begin -- [Install]({{< ref "/ngf/install/" >}}) NGINX Gateway Fabric with experimental features enabled. +- [Install]({{< ref "/ngf/install/" >}}) NGINX Gateway Fabric. ## Set up -Create the **secure-app** application in Kubernetes by copying and pasting the following block into your terminal: +Create the **secure-app** application in Kubernetes. This application presents its own TLS certificate and requires and validates a client certificate from the Gateway. Copy and paste the following block into your terminal: ```yaml kubectl apply -f - < --- -## Send Traffic without backend TLS configuration +## Send traffic without mutual TLS configured -Using the external IP address and port for the NGINX Service, we can send traffic to our secure-app application. To show what happens if we send plain HTTP traffic from NGINX to our `secure-app`, let's try sending a request before we create the backend TLS configuration. +Using the external IP address and port for the NGINX Service, send traffic to the secure-app application. To show what happens before we configure backend TLS and have the Gateway present its client certificate for verification, send a request now and observe how the connection to the application fails with a bad request error. {{< call-out "note" >}}If you have a DNS record allocated for `secure-app.example.com`, you can send the request directly to that hostname, without needing to resolve.{{< /call-out >}} @@ -200,20 +287,51 @@ curl --resolve secure-app.example.com:$GW_PORT:$GW_IP http://secure-app.example.

    400 Bad Request

    The plain HTTP request was sent to HTTPS port
    -
    nginx/1.25.3
    +
    nginx/1.29.2
    ``` -We can see we a status 400 Bad Request message from NGINX. +We can see a status 400 Bad Request message from NGINX. --- -## Create the backend TLS configuration +## Configure TLS for Gateway and Backend applications {{< call-out "note" >}} This example uses a `ConfigMap` to store the CA certificate, but you can also use a `Secret`. This could be a better option if integrating with [cert-manager](https://cert-manager.io/). The `Secret` should have a `ca.crt` key that holds the contents of the CA certificate. {{< /call-out >}} -To configure the backend TLS termination, first we will create the ConfigMap that holds the `ca.crt` entry for verifying our self-signed certificates: +We need to create a Secret that holds the Gateway’s client certificate and update the Gateway so that it presents this certificate to the backend to verify its identity. In this example, the certificate is signed by a CA labeled `gateway`. Create the `Secret` and `Gateway` in Kubernetes by copying and pasting the following block into your terminal: + +```yaml +kubectl apply -f - < Annotations: -API Version: gateway.networking.k8s.io/v1alpha3 +API Version: gateway.networking.k8s.io/v1 Kind: BackendTLSPolicy Metadata: - Creation Timestamp: 2024-05-15T12:02:38Z + Creation Timestamp: 2025-11-13T23:28:36Z Generation: 1 - Resource Version: 19380 - UID: b3983a6e-92f1-4a98-b2af-64b317d74528 + Resource Version: 1288 + UID: d7e3f026-afe3-44d1-aed5-c168e954b52f Spec: Target Refs: - Group: - Kind: Service - Name: secure-app + Group: + Kind: Service + Name: secure-app Validation: Ca Certificate Refs: - Group: + Group: Kind: ConfigMap Name: backend-cert Hostname: secure-app.example.com @@ -317,8 +435,15 @@ Status: Name: gateway Namespace: default Conditions: - Last Transition Time: 2024-05-15T12:02:38Z - Message: BackendTLSPolicy is accepted by the Gateway + Last Transition Time: 2025-11-13T23:28:37Z + Message: All CACertificateRefs are resolved + Observed Generation: 1 + Reason: ResolvedRefs + Status: True + Type: ResolvedRefs + Last Transition Time: 2025-11-13T23:28:37Z + Message: The Policy is accepted + Observed Generation: 1 Reason: Accepted Status: True Type: Accepted @@ -330,7 +455,7 @@ Events: ## Send traffic with backend TLS configuration -Now let's try sending traffic again: +Now send traffic again: ```shell curl --resolve secure-app.example.com:$GW_PORT:$GW_IP http://secure-app.example.com:$GW_PORT/ @@ -340,6 +465,17 @@ curl --resolve secure-app.example.com:$GW_PORT:$GW_IP http://secure-app.example. hello from pod secure-app ``` +To verify that the backend validated the gateway’s client certificate, inspect the logs of the `secure-app` pod and check the reported client subject: + +```shell +POD_NAME=$(kubectl get pod -l app=secure-app -o jsonpath='{.items[0].metadata.name}') +kubectl logs "$POD_NAME" +``` + +```text +10.244.0.145 ssl_client_verify=SUCCESS ssl_client_subject=CN=gateway +``` + --- ## See also @@ -348,3 +484,4 @@ To learn more about configuring backend TLS termination using the Gateway API, s - [Backend TLS Policy](https://gateway-api.sigs.k8s.io/api-types/backendtlspolicy/) - [Backend TLS Policy GEP](https://gateway-api.sigs.k8s.io/geps/gep-1897/) +- [Gateway Backend TLS](https://gateway-api.sigs.k8s.io/reference/spec/#gatewaybackendtls) diff --git a/layouts/shortcodes/version-ngf.html b/layouts/shortcodes/version-ngf.html index 7e541aec69..cc6612c36e 100644 --- a/layouts/shortcodes/version-ngf.html +++ b/layouts/shortcodes/version-ngf.html @@ -1 +1 @@ -2.2.2 \ No newline at end of file +2.3.0 \ No newline at end of file