AVI: AKO and SAML

Introduction


NSX Advanced load balancer (AVI) is a 100% software-defined multi-cloud application services platform with Software Load Balancers, Intelligent WAF (iWAF), and Container Ingress.

All modern applications use load balancing nowadays. Load balancing is the process of distributing network traffic across multiple servers.

Authentication is an essential part of this.

SAML is an acronym used to describe the Security Assertion Markup Language (SAML). Its primary role in online security is that it enables you to access multiple web applications using one set of login credentials. It works by passing authentication information in a particular format between two parties, usually an identity provider (IDP) and a web application.

The goal of this blog

The goal of this blog is to explain how to configure SAML on an ingress/route using AKO.
I will be using Azure as IDP. SAML will be configured on ingress/route in AVI.
I will not explain how to install AVI or how to do the initial configuration of service engines or VirtualServices. SAML support for AKO is introduced in version 1.10.1 (more info)

Important note: The SSORule CRD is supported only for Avi Controller version 22.1.3 and above.
It only supports the configuration of OAuth and SAML SSO protocols currently. Also, the SSORule CRD is only supported for Enhanced Virtual Hosting (EVH). When the shard virtual service size is LARGEMEDIUM, or SMALL, the OAuth and SAML settings will only be configured on the EVH child virtual services.

What I am using

For my setup, I am using the following.
AVI 22.1.4-2p2
AKO 1.10.3
OpenShift 4.12
Azure

Azure setup

First I will setup Azure.

1. Create an enterprise application

Go to Azure portal->Azure Active Directory

Go to Enterprise application

Go to New application

Go to Create your own application

Give the application a name and select Integrate any other application and press Create.
The application will now be created.


2. Setup single sign-on

Go to 2. Setup single sign on

Go to SAML

Go to Basic SAML Configuration and press Edit

Go to Add identifier. This is the Entity ID, which should match with the config in AKO (See step 2, in the next chapter)
Go to Add reply URL. This is where the authentication token is sent to. This is pointing to my VS.
Add /sso/acs/ to the URL (Please note the trailing / )
Press Save

Go to SAML Certificates and press Edit
Change the signing Option to Sign SAML response and assertion

3. Adding users

In Azure go to Home->Azure Active Directory->Enterprise Applications->select your app
Go to Users and groups

Press none selected and select your user.

AVI setup

1. Create an SSO policy

Go to Templates->Security->Auth Profile and press Create

Type: Select SAML
Service Provider: Select use user-provided entity ID

IDP Metadata: This data needs to be downloaded from Azure.
In Azure go to Home->Azure Active Directory->Enterprise Applications->select your app->Single sign-on
Under SAML Certificates select download next to Federation Metadata XML.
Paste this XML in IDP Metadata. And press Save.

Go to Templates->Security->SSO policy and press Create

Type: Select SAML
Default Auth Profile: Select your Auth profile.

Support for multiple AssertionConsumerServiceURL

Starting with version 22.1.1 and 21.1.6, AVI supports AssertionConsumerServiceURL (ACS).
Many IDPs allow a single configuration (Relying Party Trust) to support multiple applications through the use of multiple Assertion Consumer URLs. For SP-initiated SSO, the SP can supply the required Assertion Consumer URL to be used for the IDP post-back to the application in the authentication request through either AssertionConsumerServiceURL or AssertionConsumerServiceIndex attributes. The IDP will post back to the requested URL.

I will be using ACS in my setup.
For it to work, I will create a new Entity ID (azure-oauth3)
The SSO URL for this would then be https://ingress-okd.k8s.nordic.fqdn.nl/sso/acs

2. Configure AKO

Please follow the AKO installation instructions, if you have not installed AKO already.
You can find them here
Import to change the values.yaml file, and enable EVH

enableEVH: true

Then install, or upgrade your AKO deployment.
Important note: By default ‘enableEVH’ is false. This means the VirtualServices are created in SNI mode.
This might mean a redeploy of all the VirtualServices.

helm install  --generate-name oci://projects.registry.vmware.com/ako/helm-charts/ako --version 1.10.3 -f values.yaml  --set ControllerSettings.controllerHost=192.168.11.71 --set avicredentials.username=admin --set avicredentials.password=VMware1\! --namespace=avi-system

Deploy the application in OpenShift

Time for deploying an application and testing out SAML.
I am using a simple application.

Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-front1
spec:
  replicas: 4
  selector:
    matchLabels:
      app: web-front1
  template:
    metadata:
      name: web-front1
      labels:
        app: web-front1
    spec:
      containers:
        - name: web-front1
          image: tacobayle/busybox-v1
          command: [ "sh", "-c"]
          args:
          - while true; do
              echo -e "HTTP/1.1 200 OK\n\n$(date)\nApp version is $(printenv AppVersion)\nNode is on nordiclab $(printenv MY_NODE_NAME)\nPod is $(printenv MY_POD_NAME)\nNamespace is $(printenv MY_POD_NAMESPACE)\nPod IP is $(printenv MY_POD_IP)\nPod Service account is $(printenv MY_POD_SERVICE_ACCOUNT)" | nc -l -p 8080;
            done;
          env:
            - name: MY_NODE_NAME
              valueFrom:
                fieldRef:
                  fieldPath: spec.nodeName
            - name: MY_POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: MY_POD_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
            - name: MY_POD_IP
              valueFrom:
                fieldRef:
                  fieldPath: status.podIP
            - name: MY_POD_SERVICE_ACCOUNT
              valueFrom:
                fieldRef:
                  fieldPath: spec.serviceAccountName
      restartPolicy: Always

Service

apiVersion: v1
kind: Service
metadata:
  name: web-front-1
spec:
  selector:
    app: web-front1
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
  type: NodePort

Route

apiVersion: route.openshift.io/v1
kind: Route
metadata:
  name: ingress-okd.k8s.nordic.fqdn.nl
spec:
  host: ingress-okd.k8s.nordic.fqdn.nl
  path: "/"
  to:
   kind: Service
   name: web-front-1
  port:
    targetPort: 8080
  tls:
    termination: edge
    insecureEdgeTerminationPolicy: Redirect
    certificate: |-
     -----BEGIN CERTIFICATE-----
     <snip>
     -----END CERTIFICATE-----
    key: |-
     -----BEGIN PRIVATE KEY-----
     <snip>
     -----END PRIVATE KEY-----

SAML HostRule

This one is very important. Due to a discovered issue in the handling of SAML on EVH, we need to set a specific option on the EVH Parent. The issue is addressed in the next AVI release.
In my setup, the Parent VirtualService is named ‘okd–Shared-L7-EVH-0’
The application-profile I created is named ‘parent-buffer’.
Go to: Templates->Applications and press create to create one of type HTTP.
Enable ‘Enable Request Body Buffering’ in the profile

Refer to this profile in the yaml file.

apiVersion: ako.vmware.com/v1alpha1
kind: HostRule
metadata:
   name: saml-hostrule
spec:
  virtualhost:
    fqdn: okd--Shared-L7-EVH-0
    fqdnType: Contains
    applicationProfile: "parent-buffer"

You can check the VirtualService in the GUI.
Go to: Applications->VirtualService and edit your VirtualService.
Check if your created profile is configured correctly.

SAML SSORule

apiVersion: ako.vmware.com/v1alpha2
kind: SSORule
metadata:
  name: my-ssorule
  namespace: demo
spec:
  fqdn: ingress-okd.k8s.nordic.fqdn.nl
  samlSpConfig:
    authnReqAcsType: SAML_AUTHN_REQ_ACS_TYPE_URL
    cookieName: WjNkWL
    cookieTimeout: 120
    entityID: azure-oauth3
    singleSignonURL: https://ingress-okd.k8s.nordic.fqdn.nl/sso/acs/
    useIdpSessionTimeout: false
  ssoPolicyRef: azure-oauth

Testing

You can check the VirtualService in the GUI.
Go to: Applications->VirtualService en edit your VirtualService.
Go to: Policies->Access
The config should look similar to this.

Open a web browser and go to the URL of your VS. In my case it is https://ingress-okd.k8s.nordic.fqdn.nl
Upon opening, the browser will redirect to Azure and ask for your Username and Password


If the user is authenticated, the browser will redirect back to the VS and AVI allows access to the VS.

Final words

Using Azure as IDP is just an example. It can be any IDP that supports SAML.
I hope this blog was useful.
If you have comments or suggestions, please let me know!

Leave Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.