NetScaler ingress controller

Authentication and authorization policies for Kubernetes with NetScaler

Authentication and authorization policies are used to enforce access restrictions to the resources hosted by an application or API server. While you can verify the identity using the authentication policies, authorization policies are used to verify whether a specified request has the necessary permissions to access a resource.

NetScaler provides a Kubernetes CustomResourceDefinition (CRD) called the Auth CRD that you can use with NetScaler Ingress Controller to define authentication policies on NetScaler.

Auth CRD definition

The Auth CRD is available in the NetScaler Ingress Controller GitHub repo at: auth-crd.yaml. The Auth CRD provides attributes for the various options that are required to define the authentication policies on NetScaler.

Auth CRD attributes

The Auth CRD provides the following attributes that you use to define the authentication policies:

  • servicenames
  • authentication_mechanism
  • authentication_providers
  • authentication_policies
  • authorization_policies

Servicenames

The name of the services for which the authentication and authorization policies need to be applied.

Authentication mechanism

The following authentication mechanisms are supported:

  • Using request headers:
    Enables user authentication using the request header. You can use this mechanism when the credentials or API keys are passed in a header (typically Authorization header). For example, you can use authentication using request headers for basic, digest, bearer authentication, or API keys.

  • Using forms: You can use this mechanism with user or web authentication including the relying party configuration for OpenID connect and the service provider configuration for SAML.

When the authentication mechanism is not specified, the default is authentication using the request header.

The following are the attributes for forms based authentication.

Attribute Description
authentication_host Specifies a fully qualified domain name (FQDN) to which the user must be redirected for ADC authentication service. This FQDN should be unique and should resolve to the front-end IP address of NetScaler with Ingress/service type LoadBalancer or the VIP address of the Listener CRD.
authentication_host_cert Specifies the name of the SSL certificate to be used with the authentication_host. This certificate is mandatory while performing authentication using the form.
ingress_name Specifies the Ingress name for which the authentication using forms is applicable.
ingressclass Specifies the ingress class so that only the ingress controller associated with the specified ingress class processes the resource. Otherwise, all the controllers in the cluster will process this resource.
lb_service_name Specifies the name of the service of type LoadBalancer for which the authentication using forms is applicable.
listener_name The name of the Listener CRD for which the authentication using forms is applicable.
vip Specifies the front-end IP address of the Ingress for which the authentication using forms is applicable. This attribute refers to the frontend-ip address provided with the Ingress. If there is more than one Ingress resource which uses the same frontend-ip, it is recommended to use vip.

Note:

  • While using forms, authentication can be enabled for all types of traffic. Currently, granular authentication is not supported.

  • Depending on the resource to which you need to apply form based authentication, you can use one of the ingress_name, lb_service_name, listener_name, or vip attributes to specify the resource.

Authentication providers

The providers define the authentication mechanism and parameters that are required for the authentication mechanism.

Basic authentication

Specifies that local authentication is used with the HTTP basic authentication scheme. To use basic authentication, you must create user accounts on the ingress NetScaler.

Note:

The user for local auth must be created on NetScaler VPX or NetScaler MPX. To create a user for local auth on NetScaler using the CLI, run the following command: add aaa user <username> -password <password>. For information on how to create a user for local auth on NetScaler using the GUI, see Configuring Local Users.

OAuth authentication

The OAuth authentication mechanism, requires an external identity provider to authenticate the client using oAuth2 and issue an Access token. When the client presents the Access token to a NetScaler as an access credential, the NetScaler validates the token using the configured values. If the token validation is successful then NetScaler grants access to the client.

OAuth authentication attributes

The following are the attributes for OAuth authentication:

Attribute Description
Issuer The identity (usually a URL) of the server whose tokens need to be accepted for authentication.
jwks_uri The URL of the endpoint that contains JWKs (JSON Web Key) for JWT (JSON Web Token) verification.
audience The identity of the service or application for which the token is applicable.
token_in_hdr The custom header name where the token is present. The default value is the Authorization header.
  Note: You can specify more than one header.
token_in_param The query parameter where the token is present.
signature_algorithms Specifies the list of signature algorithms which are allowed. By default HS256, RS256, and RS512 algorithms are allowed.
introspect_url The URL of the introspection endpoint of the authentication server (IdP). If the access token presented is an opaque token, introspection is used for the token verification.
client_credentials The name of the Kubernetes secrets object that contains the client id and client secret required to authenticate with the authentication server.
claims_to_save The list of claims to be saved. Claims are used to create authorization policies.

OpenID Connect (OIDC) is a simple identity layer on top of the OAuth 2.0 protocol. OIDC allows clients to verify the identity of the end-user based on the authentication performed by an authorization server, as well as to obtain basic profile information about the end-user. In addition to the OAuth attributes, you can use the following attributes to configure OIDC.

Attribute Description
metadata_url Specifies the URL that is used to get OAUTH or OIDC provider metadata.
user_field Specifies the attribute in the token from which the user name should be extracted. By default, NetScaler examines the email attribute for user ID.
default_group Specifies the group assigned to the request if authentication succeeds. This group is in addition to any extracted groups from the token.
grant_type Specifies the type of flow to the token end point. The default value is CODE.
pkce Specifies whether to enable Proof Key for Code Exchange (PKCE). The default value is ENABLED.
token_ep_auth_method Specifies the authentication method to be used with the token end point. The default value is client_secret_post.

SAML authentication

Security assertion markup language (SAML) is an XML-based open standard which enables authentication of users across products or organizations. The SAML authentication mechanism, requires an external identity provider to authenticate the client. SAML works by transferring the client identity from the identity provider to the NetScaler. On successful validation of the client identity, the NetScaler grants access to the client.

The following are the attributes for SAML authentication.

Attribute Description
metadata_url Specifies the URL used for obtaining SAML metadata.
metadata_refresh_interval Specifies the interval in minutes for fetching metadata from the specified metadata URL.
signing_cert Specifies the SSL certificate to sign requests from the service provider (SP) to the identity provider (IdP).
audience Specifies the identity of the service or application for which the token is applicable.
issuer_name Specifies the name used in requests sent from SP to IdP to identify the NetScaler.
binding Specifies the transport mechanism of the SAML message. The default value is POST.
artifact_resolution_service_url Specifies the URL of the artifact resolution service on IdP.
logout_binding Specifies the transport mechanism of the SAML logout. The default value is POST.
reject_unsigned_assertion Rejects unsigned SAML assertions. If this value is ON, it rejects assertion without signature.
user_field Specifies the SAML user ID specified in the SAML assertion
default_authentication_group Specifies the default group that is chosen when the authentication succeeds in addition to extracted groups.
skewtime Specifies the allowed clock skew time in minutes on an incoming SAML assertion.
attributes_to_save Specifies the list of attribute names separated by commas which needs to be extracted and stored as key-value pairs for the session on NetScaler.

LDAP authentication

LDAP (Lightweight Directory Access Protocol) is an open, vendor-neutral, industry standard application protocol for accessing and maintaining distributed directory information services over an Internet Protocol (IP) network. A common use of LDAP is to provide a central place to store user names and passwords. LDAP allows many different applications and services to connect to the LDAP server to validate users.

Note:

LDAP authentication is supported through both the authentication mechanisms using the request header or using forms.

The following are the attributes for LDAP authentication.

Attribute Description
server_ip Specifies the IP address assigned to the LDAP server.
server_name Specifies the LDAP server name as an FQDN.
server_port Specifies the port on which the LDAP server accepts connections. The default value is 389.
base Specifies the base node on which to start LDAP searches. If the LDAP server is running locally, the default value of base is dc=netscaler, dc=com.
server_login_credentials Specifies the Kubernetes secret object providing credentials to log in to the LDAP server. The secret data should have user name and password.
login_name Specifies the LDAP login name attribute. The NetScaler uses the LDAP login name to query external LDAP servers or Active Directories.
security_type Specifies the type of security used for communications between the NetScaler and the LDAP server. The default is TLS.
validate_server_cert Validates LDAP server certificates. The default value is NO.
hostname Specifies the host name for the LDAP server. If validate_server_cert is ON, this value must be the host name on the certificate from the LDAP. A host name mismatch causes a connection failure.
sub_attribute_name Specifies the LDAP group subattribute name. This attribute is used for group extraction from the LDAP server.
group_attribute_name Specifies the LDAP group attribute name. This attribute is used for group extraction on the LDAP server.
search_filter Specifies the string to be combined with the default LDAP user search string to form the search value. For example, if the search filter “vpnallowed=true” is combined with the LDAP login name “samaccount” and the user-supplied user name is “bob”, the result is the LDAP search string “”(&(vpnallowed=true)(samaccount=bob)””. Enclose the search string in two sets of double quotation marks.
auth_timeout Specifies the number of seconds the NetScaler waits for a response from the server. The default value is 3.
password_change Allows password change requests. The default value is DISABLED.
attributes_to_save List of attribute names separated by comma which needs to be fetched from the LDAP server and stored as key-value pairs for the session on NetScaler.

Authentication policies

The authentication_policies allow you to define the traffic selection criteria to apply the authentication mechanism and also to specify the provider that you want to use for the selected traffic.

Authentication policy supports two formats through which you can specify authentication rules:

  • resource format
  • expression format

The following are the attributes for policies with resource format:

Attribute Description
path An array of URL path prefixes that refer to a specific API endpoint. For example, /api/v1/products/.
method An array of HTTP methods. Allowed values are GET, PUT, POST, or DELETE. The traffic is selected if the incoming request URI matches with any of the paths and any of the listed methods. If the method is not specified then the path alone is used for the traffic selection criteria.
provider Specifies the authentication mechanism that needs to be used. If the authentication mechanism is not provided, then authentication is not performed.

The following attributes are for authentication policies with expression format:

Attribute Description
expression Specifies NetScaler expression to be evaluated based on authentication
provider Specifies the authentication mechanism that needs to be used. If the authentication mechanism is not provided, then authentication is not performed.

Note:

If you want to skip authentication for a specific end point, create a policy with the provider attribute set as empty list. Otherwise, the request is denied.

Authorization policies

Authorization policies allow you to define the traffic selection criteria to apply the authorization requirements for the selected traffic.

Authorization policy supports two formats through which the you can specify the authorization rules:

  • resource format
  • expression format

The following are the attributes for authorization policies with resource format:

Attribute Description
path An array of URL path prefixes that refer to a specific API endpoint. For example, /api/v1/products/.
method An array of HTTP methods. Allowed values are GET, PUT, POST, or DELETE.
claims Specifies the claims required to access a specific API endpoint. name indicates the claim name and values indicate the required permissions. You can have more than one claim. If an empty list is specified, it implies that authorization is not required.
  Note: Any claim that needs to be used for authorization, should be saved as part of authentication.

The following are the attributes for authorization policies with expression format:

Attribute Description
expression Specifies an expression to be evaluated for authorization.

Note:

NetScaler requires both authentication and authorization policies for the API traffic. Therefore, you must configure an authorization policy with an authentication policy. Even if you do not have any authorization checks, you must create an authorization policy with empty claims. Otherwise, the request is denied with a 403 error.

Note:

Authorization would be successful if the incoming request matches a policy (path, method, and claims). All policies are tried until there is a match. If it is required to selectively bypass authorization for a specific end point, an explicit policy needs to be created.

Deploy the Auth CRD

Perform the following to deploy the Auth CRD:

  1. Download the CRD (auth-crd.yaml).

  2. Deploy the Auth CRD using the following command:

    kubectl create -f auth-crd.yaml
    

    For example:

    root@master:~# kubectl create -f auth-crd.yaml
    
    customresourcedefinition.apiextensions.k8s.io/authpolicies.citrix.com created
    

How to write authentication and authorization policies

After you have deployed the CRD provided by NetScaler in the Kubernetes cluster, you can define the authentication policy configuration in a .yaml file. In the .yaml file, use authpolicy in the kind field and in the spec section add the Auth CRD attributes based on your requirement for the policy configuration.

After you deploy the .yaml file, NetScaler Ingress Controller applies the authentication policy configuration on NetScaler.

Local auth provider

The following is a sample authentication and authorization policy definition for the local-auth-provider type (local_auth.yaml).

  apiVersion: citrix.com/v1beta1
  kind: authpolicy
  metadata:
    name: authexample
  spec:
      servicenames:
      - frontend

      authentication_providers:
          - name: "local-auth-provider"
            basic_local_db:
                use_local_auth: 'YES'

      authentication_policies:
          - resource:
              path:
                - '/orders/'
                - '/shipping/'
              method: [GET, POST]
            provider: ["local-auth-provider"]
          
          # skip authentication for this
          - resource:
              path:
                - '/products/'
              method: [GET]
            provider: []

      authorization_policies:
          # skip authorization
          - resource:
              path: []
              method: []
              claims: []

The sample policy definition performs the following:

  • NetScaler performs the local authentication on the requests to the following:
    • GET or POST operation on orders and shipping end points.
  • NetScaler does not perform the authentication for GET operation on the products endpoint.
  • NetScaler does not apply any authorization permissions.

Note:

The user for local auth must be created on NetScaler VPX or NetScaler MPX. To create a user for local auth on NetScaler using the CLI, run the following command: add aaa user <username> -password <password>. For information on how to create a user for local auth on NetScaler using the GUI, see Configuring Local Users.

oAuth JWT verification

The following is a sample authentication and authorization policy definition for oAuth JWT verification (oauth_jwt_auth.yaml).

apiVersion: citrix.com/v1beta1
kind: authpolicy
metadata:
  name: authexample
spec:
    servicenames:
    - frontend

    authentication_providers:
      - name: "jwt-auth-provider"
        oauth:
          issuer: "https://sts.windows.net/tenant1/"
          jwks_uri: "https://login.microsoftonline.com/tenant1/discovery/v2.0/keys"
          audience : ["https://api.service.net"]
          claims_to_save : ["scope"]

    authentication_policies:
        - resource:
            path:
              - '/orders/'
              - '/shipping/'
            method: [GET, POST]
          provider: ["jwt-auth-provider"]
        
        # skip authentication for this
        - resource:
            path:
              - '/products/'
            method: [GET]
          provider: []

    authorization_policies:
        - resource:
            path:
              - '/orders/'
              - '/shipping/'
            method: [POST]
            claims: 
              - name: "scope"
                values: ["read", "write"]
        - resource:
            path:
              - '/orders/'
            method: [GET]
            claims: 
              - name: "scope"
                values: ["read"]
        # skip authorization, no claims required
        - resource:
            path:
              - '/shipping/'
            method: [GET]
            claims: []

The sample policy definition performs the following:

  • NetScaler performs JWT verification on the requests to the following:

    • The GET or POST operation on orders and shipping endpoints.
  • NetScaler skips authentication for the GET operation on the products endpoint.

  • NetScaler requires the scope claim with read and write permissions for POST operation on orders and shipping endpoints.

  • NetScaler requires the scope claim with the read permission for GET operation on the orders endpoint.

  • NetScaler does not need any permissions for GET operation on the shipping end point.

For OAuth, if the token is present in a custom header, it can be specified using the token_in_hdr attribute as follows:

      oauth:
        issuer: "https://sts.windows.net/tenant1/"
        jwks_uri: "https://login.microsoftonline.com/tenant1/discovery/v2.0/keys"
        audience : ["https://vault.azure.net"]
        token_in_hdr : [“custom-hdr1”]

Similarly, if the token is present in a query parameter, it can be specified using the token_in_param attribute as follows:

      oauth:
        issuer: "https://sts.windows.net/tenant1/"
        jwks_uri: "https://login.microsoftonline.com/tenant1/discovery/v2.0keys"
        audience : ["https://vault.azure.net"]
        token_in_param : [“query-param1”]

oAuth Introspection

The following is a sample authentication and authorization policy definition for oAuth JWT verification. (oauth_intro_auth.yaml)

  apiVersion: citrix.com/v1beta1
  kind: authpolicy
  metadata:
    name: authexample
  spec:
      servicenames:
      - frontend

      authentication_providers:
          - name: "introspect-provider"
            oauth:
              issuer: "ns-idp"
              jwks_uri: "https://idp.aaa/oauth/idp/certs"
              audience : ["https://api.service.net"]
              client_credentials: "oauthsecret"
              introspect_url: https://idp.aaa/oauth/idp/introspect
              claims_to_save : ["scope"]

      authentication_policies:
          - resource:
              path: []
              method: []
            provider: ["introspect-provider"]
          
      authorization_policies:
          - resource:
              path: []
              method: [POST]
              claims: 
              - name: "scope"
                values: ["read", "write"]
          - resource:
              path: []
              method: [GET]
              claims: 
              - name: "scope"
                values: ["read"]

The sample policy definition performs the following:

  • NetScaler performs the oAuth introspection as specified in the provider introspect-provider for all requests.

  • NetScaler requires the scope claim with read and write permissions for all POST requests.

  • NetScaler requires the scope claim with the read permission for all GET requests.

Creating a secrets object with client credentials for introspection

A Kubernetes secrets object is needed for configuring the OAuth introspection. You can create a secret object in a similar way as shown in the following example:

apiVersion: v1        
kind: Secret          
metadata:             
  name: oauthsecret
type: Opaque        
stringData:           
 client_id: "nsintro"
 client_secret: "nssintro"

Note:

Keys of the opaque secret object must be client_id and client_secret. A user can set the values for them as desired.

SAML authentication using forms

The following is an example for SAML authentication using forms. In the example, authhost-tls-cert-secret and saml-tls-cert-secret are Kubernetes TLS secrets referring to certificate and key.

Note:

When certkey.cert and certkey.key are certificate and key respectively for the authentication host, then the authhost-tls-cert-secret can be formed using the following command:

     kubectl create secret tls authhost-tls-cert-secret --key="certkey.key" --cert="certkey.cert

Similarly, you can use this command to form saml-tls-cert-secret with the required certificate and key.


apiVersion: citrix.com/v1beta1
kind: authpolicy
metadata:
  name: samlexample
spec:
    servicenames:
    - frontend

    authentication_mechanism:
      using_forms:
        authentication_host: "fqdn_authenticaton_host"
        authentication_host_cert:
          tls_secret: authhost-tls-cert-secret
        listener_name: “example-listener”

    authentication_providers:
        - name: "saml-auth-provider"
          saml:
              metadata_url: "https://idp.aaa/metadata/samlidp/aaa"
              signing_cert:
                  tls_secret: saml-tls-cert-secret

    authentication_policies:

        - resource:
            path: []
            method: []
          provider: ["saml-auth-provider"]

    authorization_policies:

        - resource:
            path: []
            method: []
            claims: []

<!--NeedCopy-->

The sample policy definition performs the following:

  • NetScaler performs SAML authentication as specified in the provider saml-auth-provider for all requests. Note: Granular authentication is not supported for the forms mechanism.

  • NetScaler requires the group claim with admin permission for all POST requests.

  • NetScaler does not require any specific permission for GET requests.

OpenID Connect authentication using forms

The following is an example for creating OpenID Connect authentication to configure NetScaler in a Relaying Party (RP) role to authenticate users for an external identity provider. The authentication_mechanism must be set to using_forms to trigger the OpenID Connect procedures.

apiVersion: citrix.com/v1beta1
kind: authpolicy
metadata:
  name: authoidc
spec:
    servicenames:
    - frontend
    authentication_mechanism:
        using_forms:
            authentication_host: "10.221.35.213"
            authentication_host_cert:
                 tls_secret: "oidc-tls-secret"
            ingress_name:  “example-ingress”

    authentication_providers:

        - name: "oidc-provider"
          oauth:
            audience : ["https://app1.citrix.com"]
            client_credentials: "oidcsecret"
            metadata_url: "https://10.221.35.214/oauth/idp/.well-known/openid-configuration"
            default_group: "groupA"
            user_field: "sub"
            pkce: "ENABLED"
            token_ep_auth_method: "client_secret_post"

    authentication_policies:

        - resource:
            path: []
            method: []
          provider: ["oidc-provider"]

    authorization_policies:

        #default - no authorization requirements
        - resource:
            path: []
            method: []
            claims: []
<!--NeedCopy-->

The sample policy definition performs the following:

  • NetScaler performs OIDC authentication (relying party) as specified in the provider oidc-provider for all requests.

    Note: Granular authentication is not supported for the forms mechanism.

  • NetScaler does not require any authorization permissions.

LDAP authentication using the request header

The following is an example for LDAP authentication using the request header.

In this example, ldapcredential is the Kubernetes secret referring to the LDAP server credentials. See the ldap_secret.yaml file for information on how to create LDAP server credentials.


apiVersion: citrix.com/v1beta1
kind: authpolicy
metadata:
  name: ldapexample
spec:
    servicenames:
    - frontend

    authentication_providers:
        - name: "ldap-auth-provider"
          ldap:
              server_ip: "192.2.156.160"
              base: 'dc=aaa,dc=local'
              login_name: accountname
              sub_attribute_name: CN
              server_login_credentials: ldapcredential

        - name: "local-auth-provider"
          basic_local_db:
              use_local_auth: 'YES'

    authentication_policies:

        - resource:
            path: []
            method: []
          provider: ["ldap-auth-provider"]


    authorization_policies:

        - resource:
            path: []
            method: []
            claims: []
<!--NeedCopy-->

Note: With the request header based authentication mechanism, granular authentication based on traffic is supported.

LDAP authentication using forms

In the example authhost-tls-cert-secret is the Kubernetes TLS secret referring to certificate and key.

When certkey.cert and certkey.key are certificate and key respectively for the authentication host, then the authhost-tls-cert-secret can be formed using the following command:

    kubectl create secret tls authhost-tls-cert-secret --key="certkey.key" --cert="certkey.cert

In this example, ldapcredential is the Kubernetes secret referring to the LDAP server credentials. See the ldap_secret.yaml file for information on how to create LDAP server credentials.

apiVersion: citrix.com/v1beta1
kind: authpolicy
metadata:
  name: ldapexample
spec:
    servicenames:
    - frontend

    authentication_mechanism:
      using_forms:
        authentication_host: "fqdn_authenticaton_host"
        authentication_host_cert:
          tls_secret: authhost-tls-cert-secret
        vip: "192.2.156.156"

    authentication_providers:
        - name: "ldap-auth-provider"
          ldap:
              server_ip: "192.2.156.160"
              base: 'dc=aaa,dc=local'
              login_name: accountname
              sub_attribute_name: CN
              server_login_credentials: ldapcredential

    authentication_policies:

        - resource:
            path: []
            method: []
          provider: ["ldap-auth-provider"]

    authorization_policies:

        - resource:
            path: []
            method: []
            claims: []

<!--NeedCopy-->

The sample policy definition performs the following:

  • NetScaler performs the LDAP authentication for entire traffic (all requests).
  • NetScaler does not apply any authorization permission.

The following is an example for LDAP_secret.yaml.

apiVersion: v1
kind: Secret
metadata:
  name: ldapcredential
type: Opaque
stringData:
  username: 'ldap_server_username'
  password: 'ldap_server_password'

<!--NeedCopy-->

Example for NetScaler expression support with Auth CRD

This example shows how you can specify NetScaler expressions along with authentication and authorization policies:

  apiVersion: citrix.com/v1beta1
  kind: authpolicy
  metadata:
    name: authexample
  spec:
      servicenames:
      - frontend

      authentication_mechanism:
        using_request_header: 'ON'

      authentication_providers:
          - name: "ldap-auth-provider"
            ldap:              
                server_ip: "192.2.156.160"
                base: 'dc=aaa,dc=local'
                login_name: accountname
                sub_attribute_name: CN
                server_login_credentials: ldapcredential
                # "memberof" attribute details are extracted from LDAP server.
                attributes_to_save: memberof

      authentication_policies:
          # Perform LDAP authentication for the host hotdrink.beverages.com
          - expression: 'HTTP.REQ.HOSTNAME.SET_TEXT_MODE(IGNORECASE).EQ("hotdrink.beverages.com")'
            provider: ["ldap-auth-provider"]


      authorization_policies:
          # ALLOW the session only if the authenticated user is associated with attribute "memberof" having value "grp4"
          - expression: 'aaa.user.attribute("memberof").contains("grp4")'
Authentication and authorization policies for Kubernetes with NetScaler