Secure Application Introspection

Locate “the good, the bad, and the ugly” data with a transparent proxy.

Have you been frustrated with various enterprise/cloud solutions’ APIs implementation or documentation where a single case-sensitive data field entry delays progress? Does the solution have undocumented features for older client tools? Do you wish to know what your mobile apps or laptop sends to the internet?

Utilizing a proxy can help with all the above, and if the process is quick and straightforward, so much the better.

Typically for a proxy, there may be quite a bit of effort and steps. You may need to modify a client host/mobile phone to redirect web traffic with OS environmental variables of HTTP_PROXY and HTTPS_PROXY or adjustment of the underlying OS network/iptables. Prior, we typically set up the open-source Jmeter proxy with the OS environment variables to capture secure traffic data. This process works well for most applications. Additionally, the Firefox browser allows manual modification using a proxy without dependence on the OS environment settings if we wish to capture the user experience and any data challenges.

The example below of modifying a Firefox browser to use a “manual proxy configuration” instead of system/auto configurations.

To ensure accurate capture of web traffic submissions, a more thorough method is needed as the above process may fail if client tools or mobile apps cannot detect OS environmental variables.

We have found a perfect combination within the open-source tool of MITMproxy with podman and the embedded VPN feature of WireGuard.

The process in six (6) steps:

  1. Deployment of the WireGuard VPN client on the client host (MS Win/Linux/Mobile)
  2. Deployment of MITMproxy using podman (or docker) with WireGuard mode/configuration
  3. Edit the wireguard.conf file to have the correct public IP address and import this file to the WireGuard VPN client and establish the VPN connection.
  4. Copy the mitmproxy-ca-cert.cer to the client component Java or OS keystore (if needed) as a trusted CA cert.
  5. Open the MITMproxy Web UI or monitor the command line dashboard
  6. Execute your test on the client host and view the results in the MITMproxy Web UI for both request and response.

MITMproxy UI with WireGuard mode enabled.

The WireGuard client configuration will be provided in three (3) places: the MITMproxy logs (podman logs mitmproxy), the text file wireguard.conf (if podman/docker volumes are enabled), and the MITMproxy UI. The QR code is enabled for mobile phone use, but since the public IP address provided is not correct in this view, you will need to manually edit this configuration on your mobile phone during those use-cases to have the correct endpoint IP address.

MITMproxy UI with standard proxy configuration mode.

Bash Script:

Script to deploy MITMproxy with podman on a linux OS with two (2) configurations: Wireguard mode for any client applications that do not honor HTTP_PROXY/HTTPS_PROXY and Standard proxy mode. This bash script allows a shared volume to use the SAME certs to avoid managing different certs upon restart of the container.

#!/bin/bash
######################################################################################
#
#  Deploy MITMproxy with two (2) configurations:
#
#     MITMProxy with WireGuard mode enabled (UDP 51820) and Web UI (TCP 8081)
#     MITMProxy with standard proxy enabled (TCP 9080) and Web UI (TCP 9081)
#
#  Notes:  Use podman exec to check path and env variables
#    - Binaries:  dnf -y install podman 
#    - Use shared folder to avoid having two (2) different configuration files for both copies
#    - Do not forget the :z for -v volumes to avoid permissions issues
#    - Do not forget quotes around env -e variables
#    - Use --rm as needed
#    - Use this switch as needed, but do not leave it on:   --log-level debug \
#
#   Basic:  podman run -it -v /tmp/mitmproxy/:/home/mitmproxy/.mitmproxy:z -p 8080:8080 mitmproxy/mitmproxy
#   Logs:   podman logs mitmproxy-wireguard
#   Shell:  podman exec -it -u root mitmproxy bash
#
#  Options Ref.  https://docs.mitmproxy.org/stable/concepts-options/
#   - added stream_large_bodies=10m to lower impact to mitmproxy due
#       to possible large json/xml payloads 
#
#  ANA 07/2023
#
######################################################################################

MITMPROXY_HOMEPATH=/tmp/mitmproxy
echo ""
echo "You may delete the shared folder of ${MITMPROXY_HOMEPATH}"
echo "to remove prior configuration of mitmproxy certs & wireguard.conf files"
echo ""
#sudo rm -rf ${MITMPROXY_HOMEPATH}

mkdir -p ${MITMPROXY_HOMEPATH}
chmod -R 777 ${MITMPROXY_HOMEPATH}
ls -hlrt ${MITMPROXY_HOMEPATH}

echo ""
echo " Starting mitmproxy-wireguard proxy "
podman rm mitmproxy-wireguard -f  &>/dev/null
podman run -d -it --name mitmproxy-wireguard \
   -p 51820:51820/udp -p 8081:8081 \
   -l mitmproxy \
   -v ${MITMPROXY_HOMEPATH}:/home/mitmproxy/.mitmproxy:z  \
    docker.io/mitmproxy/mitmproxy \
    mitmweb --mode wireguard --ssl-insecure  --web-host 0.0.0.0 --web-port 8081 --set stream_large_bodies=10m


echo ""
echo " Starting mitmproxy-default proxy "
podman rm mitmproxy-default -f  &>/dev/null
podman run -d -it --name mitmproxy-default \
    -p 9080:9080 -p 9081:9081 \
    -l mitmproxy  \
    -v ${MITMPROXY_HOMEPATH}:/home/mitmproxy/.mitmproxy:z  \
     docker.io/mitmproxy/mitmproxy \
     mitmweb --set listen_port=9080 --web-host 0.0.0.0 --web-port 9081

echo ""
echo ""
echo "###############################################################################"
echo ""
echo " Running Podman Containers for MITMproxy"
sleep 5
podman ps -a --no-trunc | grep -i mitmproxy
echo ""
echo "###############################################################################"
podman logs  mitmproxy-default
echo ""
echo " Monitor the mitmproxy-default UI @ http://$(curl -s ifconfig.me):9081 "
echo "###############################################################################"
podman logs  mitmproxy-wireguard
echo ""
echo " Monitor the mitmproxy-wireguard UI @ http://$(curl -s ifconfig.me):8081 "
echo "###############################################################################"
echo ""
echo "Please update the mitmproxy wireguard client configuration endpoint address to:  $(curl -s ifconfig.me)"
echo ""
echo "###############################################################################"
echo ""

MITMproxy CERTS:

Add mitmproxy-ca-cert to the trusted root certs folder on your client host OS keystore (MS Win: certlm.msc) and/or if there is a java keystore for the client tool, please add the mitmproxy-ca-cert.cer as a trusted cert. keytool -import -trustcacerts -file mitm-ca-proxy.cer -alias mitmproxy -keystore capam.keystore

WireGuard client configuration:

To ensure that only selected web traffic is monitored through wireguard VPN to mitmproxy, make changes to the wireguard.conf file before importing it. Specifically, update the AllowedIPs address field to include a single IP address. Additionally, modify the endpoint field to direct traffic to the public IP address of the mitmproxy host on UDP port 51820. If deploying mitmproxy on AWS or other cloud hosts, confirm that the firewall/security groups permit TCP 8080, 8081, 9080, 9091, and UDP 51820. Once you have activated the WireGuard client, test your processes on the host and monitor the MITMproxy UI for updates.

An example of data captured between two (2) CLI tools. These CLI tools did not honor the OS environmental variables of HTTP_PROXY & HTTPS_PROXY. Using the MITMproxy with WireGuard process, we can now confirm the delta submission behavior that was masked by the CLI tools. This process was useful to confirm that MS Powershell was removing special characters for a password string, e.g. ! (exclamation mark).

Example of script deploying two (2) MITMproxy containers

Adding wildcard certificates to Virtual Appliance

While preparing to enable a feature within the Identity Suite Virtual Appliance for TLS encryption for the Provisioning Tier to send notification events, we noticed some challenges that we wish to clarify.

The Identity Suite Virtual Appliance has four (4) web services that use pre-built self-signed certificates when first deployed. Documentation is provided to change these certificates/key using aliases or soft-links.

One of the challenges we discovered is the Provisioning Tier may be using an older version of libcurl & OpenSSL that have constraints that need to be managed. These libraries are used during the web submission to the IME ETACALLBACK webservice. We will review the processes to capture these error messages and how to address them.

We will introduce the use of Let’s Encrypt wildcard certificates into the four (4) web services and the Provisioning Server’s ETACALLBACK use of a valid public root certificate.

The Apache HTTPD service is used for both a forward proxy (TCP 443) to the three (3) Wildfly Services and service for the vApp Management Console (TCP 10443). The Apache HTTPD service SSL certs use the path /etc/pki/tls/certs/localhost.crt for a self-signed certificate. A soft-link is used to redirect this to a location that the ‘config’ service ID has access to modify. The same is true for the private key.

/etc/pki/tls/certs/localhost.crt -> /opt/CA/VirtualAppliance/custom/apache-ssl-certificates/localhost.crt

/etc/pki/tls/private/localhost.key -> /opt/CA/VirtualAppliance/custom/apache-ssl-certificates/localhost.key

A view of the Apache HTTPD SSL self-signed certificate and key.

The three (3) Wildfly services are deployed for the Identity Manager, Identity Governance and Identity Portal components. The configuration for TLS security is defined within the primary Wildfly configuration file of standalone.xml. The current configuration is already setup with the paths to PKCS12 keystore files of:

/opt/CA/VirtualAppliance/custom/wildfly-ssl-certificates/caim-srv

/opt/CA/VirtualAppliance/custom/wildfly-ssl-certificates/caig-srv

/opt/CA/VirtualAppliance/custom/wildfly-ssl-certificates/caip-srv

A view of the three (3) Wildfly PKCS12 keystore files and view of the self-signed cert/key with the pseudo hostname of the vApp host.

Provisioning Server process for TLS enablement for IME ETACALLBACK process.

Step 1. Ensure that the Provisioning Server is enabled to send data/notification events to the IME.

Step 2. Within the IME Management Console, there is a baseURL parameter. This string is sent down to the Provisioning Server upon restart of the IME, and appended to a list. This list is viewable and manageable within the Provisioning Manager UI under [System/Identity Manager Setup]. The URL string will be appended with the string ETACALLBACK/?env=identityEnv. Within this Provisioning Server, we can manage which URLs have priority in the list. This list is a failover list and not load-balancing. We have the opportunity to introduce an F5 or similar load balancer URL, but we should enable TLS security prior.

Step 3. Added the public root CA Cert or CA chain certs to the following location. [System/Domain Configuration/Identity Manager Server/Trusted CA Bundle]. This PEM file may be placed in the Provisioning Server bin folder with no path or may use a fully qualified path to the PEM file. Note: The Provisioning Server is using a version of openssl/libcurl that will report errors that can be managed with wildcard certificates. We will show the common errors in this blog entry.

Let’sEncrypt https://letsencrypt.org/ Certificates

Let’sEncrypt Certificates offers a free service to build wildcard certificates. We are fond of using their DNS method to request a wildcard certificate.

sudo certbot certonly --manual  --preferred-challenges dns -d *.aks.iam.anapartner.dev --register-unsafely-without-email

Let’s Encrypt will provide four (4) files to be used. [certN.pem, privkeyN.pem, chainN.pem, fullchainN.pem]

cert1.pem   [The primary server side wildcard cert]

privkey1.pem   [The primary server side private key associated with the wildcard cert]

chain1.pem   [The intermediate chain certs that are needed to validate the cert1 cert]

fullchain1.pem    [two files together in the correct order of  cert1.pem and chain1.pem.]  

NOTE:  fullchain1.pem is the file you typically would use as the cert for a solution, so the solution will also have the intermediate CA chain certs for validation]

Important Note: One of the root public certs was cross-signed by another root public cert that expired. Most solutions are able to manage this challenge, but the provisioning service ETACALLBACK has a challenge with an expired certificate, but there are replacements for this expired certificate that we will walk through. Ref: https://letsencrypt.org/docs/dst-root-ca-x3-expiration-september-2021/

Create a new CA chain PEM files for LE (Let’s Encrypt) validation to use with the Provisioning Server.

CERT=lets-encrypt-r3.pem;curl -s -O -L https://letsencrypt.org/certs/$CERT ; openssl x509 -text -noout -in $CERT | grep -i -e issue -e not -e subject ; ls -lart $CERT

CERT=isrgrootx1.pem;curl -s -O -L https://letsencrypt.org/certs/$CERT ; openssl x509 -text -noout -in $CERT | grep -i -e issue -e not -e subject ; ls -lart $CERT

CERT=isrg-root-x2.pem;curl -s -O -L https://letsencrypt.org/certs/$CERT ; openssl x509 -text -noout -in $CERT | grep -i -e issue -e not -e subject ; ls -lart $CERT

cat lets-encrypt-r3.pem isrgrootx1.pem isrg-root-x2.pem > combine-chain-letsencrypt.pem

Replacing the certificates for the vApp Apache, Wildfly (3), and Provisioning Server (ETACALLBACK)

Apache HTTPD Service (TCP 443/10443) (May need to reboot vApp)

cp -r -p  /home/config/aks.iam.anapartner.dev/fullchain2.pem /opt/CA/VirtualAppliance/custom/apache-ssl-certificates/localhost.crt

cp -r -p  /home/config/aks.iam.anapartner.dev/privkey2.pem  /opt/CA/VirtualAppliance/custom/apache-ssl-certificates/localhost.key

Wildfly Services (TCP 8443/8444/84445) for IM, IG, and IP (restart services after update)

View of the Wildfly (Java) services for IM, IG, and IP (restart services after update)
openssl pkcs12 -export -inkey /home/config/aks.iam.anapartner.dev/privkey2.pem -in /home/config/aks.iam.anapartner.dev/fullchain2.pem -out /opt/CA/VirtualAppliance/custom/wildfly-ssl-certificates/caim-srv -password pass:changeit
restart_im

openssl pkcs12 -export -inkey /home/config/aks.iam.anapartner.dev/privkey2.pem -in /home/config/aks.iam.anapartner.dev/fullchain2.pem -out /opt/CA/VirtualAppliance/custom/wildfly-ssl-certificates/caig-srv -password pass:changeit
restart_ig

openssl pkcs12 -export -inkey /home/config/aks.iam.anapartner.dev/privkey2.pem -in /home/config/aks.iam.anapartner.dev/fullchain2.pem -out /opt/CA/VirtualAppliance/custom/wildfly-ssl-certificates/caip-srv -password pass:changeit
restart_ip

Provisioning Server ETACALLBACK public certificate location (restart imps service) [Place in bin folder]

su - imps
cp -r -p /home/config/aks.iam.anapartner.dev/combine-chain-letsencrypt.pem /opt/CA/IdentityManager/ProvisioningServer/bin/
imps stop; imps start

Validation of updated services.

Use openssl s_client to validate certificates being used. Examples below for TCP 443 and 8443

true | openssl s_client -connect vapp143.aks.iam.anapartner.dev:443 -CAfile combine-chain-letsencrypt.pem  | grep "Verify return code"

true | openssl s_client -connect vapp143.aks.iam.anapartner.dev:8443 -CAfile combine-chain-letsencrypt.pem  | grep "Verify return code"

To view all certs in the chain, use the below openssl s_client command with -showcerts switch:

true | openssl s_client -connect vapp143.aks.iam.anapartner.dev:443 -CAfile combine-chain-letsencrypt.pem  -showcerts

true | openssl s_client -connect vapp143.aks.iam.anapartner.dev:8443 -CAfile combine-chain-letsencrypt.pem  -showcerts

Validate with browsers and view the HTTPS lock symbol to view the certificate

Test with an update to a Provisioning Global User’s attribute [Note: No need to sync to accounts]. Ensure that the Identity Manager Setup Log Level = DEBUG to monitor this submission with the Provisioning Server etanotifyXXXXXXX.log.

A view of the submission for updating the Global User’s Description via IMPS (IM Provisioning Server) etanotifyXXXXXXX.log. The configuration will be loaded for using the URLs defined. Then we can monitor for the submission of the update.

Finally, a view using the IME VST (View Submitted Tasks) for the ETACALLBACK process using the task Provisioning Modify User.

Common TLS errors seen with the Provisioning Server ETACALLBACK

Ensure that the configuration is enabled for debug log level, so we may view these errors to correct them. [rc=77] will occur if the PEM file does not exist or is not in the correct path. [rc=51] will occur if the URL defined does not match the exact server-side certificate (this is a good reason to use a wildcard certificate or adjust your URL FQDN to match the cert subject (CN=XXXX) value. [rc=60] will occur if the remote web service is using a self-signed certificate or if the certificate has any expiration dates within the certificate or chain or the public root CA cert.

Other Error messages (curl)

If you see an error message with Apache HTTPD (TCP 443) with curl about “curl: (60) Peer certificate cannot be authenticated with known CA certificates”, please ignore this, as the vApp does not have the “ca-bundle.crt” configuration enabled. See RedHat note: https://access.redhat.com/solutions/523823

References

https://knowledge.broadcom.com/external/article?articleId=54198
https://community.broadcom.com/HigherLogic/System/DownloadDocumentFile.ashx?DocumentFileKey=849ea21f-cc5a-4eac-9988-465a75165cf1
https://curl.se/libcurl/c/libcurl-env.html
https://knowledge.broadcom.com/external/article/204213/how-to-setup-inbound-notifications-to-us.html
https://knowledge.broadcom.com/external/article/213480/how-to-replace-the-vapp-wildfly-ssl-cert.html https://www.stephenwagner.com/2021/09/30/sophos-dst-root-ca-x3-expiration-problems-fix/

OpenShift on VMware Workstation

RedHat OpenShift is one of the container orchestration platforms that provides an enterprise-grade solution for deploying, running, and managing applications on public, on-premise, or hybrid cloud environments.

This blog entry outlines the high-level architecture of a LAB OpenShift on-prem cloud environment built on VMware Workstation infrastructure.

Red Hat OpenShift and the customized ISO image with Red Hat Core OS provide a straightforward process to build your lab and can help lower the training cost. You may watch the end-to-end process in the video below or follow this blog entry to understand the overall process.

Requirements:

  • Red Hat Developer Account w/ Red Hat Developer Subscription for Individuals
  • Local DNS to resolve a minimum of three (3) addresses for OpenShift. (api.[domain], api-int.[domain], *.apps.[domain])
  • DHCP Server (may use VMware Workstation NAT’s DHCP)
  • Storage (recommend using NFS for on-prem deployment/lab) for OpenShift logging/monitoring & any db/dir data to be retained.
  • SSH Terminal Program w/ SSH Key.
  • Browser(s)
  • Front Loader/Load Balancer (HAProxy)
  • VMware Workstation Pro 16.x
  • Specs: (We used more than the minimum recommended by OpenShift to prepare for other applications)
    • Three (3) Control Planes Nodes @ 8 vCPU/16 GB RAM/100 GB HDD with “Red Hat Enterprise Linux 8 x64 bit” Guest OS Type
    • Four (4) Worker Nodes @ 4 vCPU/16 GB RAM/100 GB HDD with “Red Hat Enterprise Linux 8 x64” Guest OS Type

Post-Efforts: Apply these to provide additional value. [Included as examples]

  • Add entropy service (haveged) to all nodes/pods to increase security & performance.
  • Let’sEncrypt wild card certs for *.[DOMAIN] and *.apps.[DOMAIN] to avoid self-signed certs for external UIs. Avoid using “thisisunsafe” within the Chrome browser to access the local OpenShift console.
  • Update OpenShift Ingress to be aware of more than two (2) worker nodes.
  • Update OpenShift to use NFS as default storage.

Below is a view of our footprint to deploy the OpenShift 4.x environment on a local data center hosted by VMware Workstation.

Red Hat OpenShift provides three (3) options to deploy. Cloud, Datacenter, Local. Local is similar to minikube for your laptop/workstation with a few pods. Red Hat OpenShift license for Cloud requires deployment on other vendors’ sites for the nodes (cpu/ram/disk) and load balancers. If you deploy OpenShift on AWS and GCP, plan a budget of $500/mo per resource for the assets.

After reviewing the open-source OKD solution and the various OpenShift deployment methods, we selected the “DataCenter” option within OpenShift. Two (2) points made this decision easy.

  • Red Hat OpenShift offers a sixty (60) day eval license.
    • This license can be restarted for another sixty (60) days if you delete/archive the last cluster.
  • Red Hat OpenShift provides a customized ISO image with Red Hat Core OS, ignition yaml files, and an embedded SSH Public Key, that does a lot of the heavy lifting for setting up the cluster.

The below screen showcases the process that Red Hat uses to build a bootstrap ISO image using Red Hat Core OS, Ignition yaml files (to determine node type of control plane/worker node), and the embedded SSH Key. This process provides a lot of value to building a cluster and streamlines the effort.

DNS Requirement

The minimal DNS entries required for OpenShift is three (3) addresses.

api.[domain]

api-int.[domain]

*.apps.[domain]

https://docs.openshift.com/container-platform/4.11/installing/installing_platform_agnostic/installing-platform-agnostic.html

Front Load Balancer (HAProxy)

Update HAproxy.cfg as needed for IP addresses / Ports. To avoid deployment of HAProxy twice, we use the “bind” command to join two (2) HAproxy configuration files together to prevent conflict on port 80/443 redirect for both OpenShift and another application deployed on OpenShift.

# Global settings
# Set $IP_RANGE as an OS ENV or Global variable before running HAPROXY
#   Important: If using VMworkstation NAT ensure this range is correctly defined to
#   avoid error message with x509 error on port 22623 upon startup on control planes
#
#   Ensure 3XXXX PORT is defined correct from the ingress
#    - We have predefined these ports to 32080 and 32443 for helm deployment of ingress
#    oc -n ingress get svc
#
#---------------------------------------------------------------------
global
    setenv IP_RANGE 192.168.243
    setenv HA_BIND_IP1 192.168.2.101
    setenv HA_BIND_IP2 192.168.2.111
    maxconn     20000
    log         /dev/log local0 info
    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    user        haproxy
    group       haproxy
    daemon

    # turn on stats unix socket
    stats socket /var/lib/haproxy/stats

#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
#---------------------------------------------------------------------
defaults
    log                     global
    mode                    http
    option                  httplog
    option                  dontlognull
    option                  http-server-close
    option                  redispatch
    option forwardfor       except 127.0.0.0/8
    retries                 3
    maxconn                 20000
    timeout http-request    10000ms
    timeout http-keep-alive 10000ms
    timeout check           10000ms
    timeout connect         40000ms
    timeout client          300000ms
    timeout server          300000ms
    timeout queue           50000ms

# Enable HAProxy stats
# Important Note:  Patch OpenShift Ingress to allow internal RHEL CoreOS haproxy to run on additional worker nodes
#  oc patch -n openshift-ingress-operator ingresscontroller/default --patch '{"spec":{"replicas": 7}}' --type=merge
#
listen stats
    bind :9000
    stats uri /
    stats refresh 10000ms

# Kube API Server
frontend k8s_api_frontend
    bind :6443
    default_backend k8s_api_backend
    mode tcp
    option tcplog

backend k8s_api_backend
    mode tcp
    balance source
    server      ocp-cp-1_6443        "$IP_RANGE".128:6443 check
    server      ocp-cp-2_6443        "$IP_RANGE".129:6443 check
    server      ocp-cp-3_6443        "$IP_RANGE".130:6443 check

# OCP Machine Config Server
frontend ocp_machine_config_server_frontend
    mode tcp
    bind :22623
    default_backend ocp_machine_config_server_backend
    option tcplog

backend ocp_machine_config_server_backend
    mode tcp
    balance source
    server      ocp-cp-1_22623        "$IP_RANGE".128:22623 check
    server      ocp-cp-2_22623        "$IP_RANGE".129:22623 check
    server      ocp-cp-3_22623        "$IP_RANGE".130:22623 check

# OCP Machine Config Server #2
frontend ocp_machine_config_server_frontend2
    mode tcp
    bind :22624
    default_backend ocp_machine_config_server_backend2
    option tcplog

backend ocp_machine_config_server_backend2
    mode tcp
    balance source
    server      ocp-cp-1_22624        "$IP_RANGE".128:22624 check
    server      ocp-cp-2_22624        "$IP_RANGE".129:22624 check
    server      ocp-cp-3_22624        "$IP_RANGE".130:22624 check


# OCP Ingress - layer 4 tcp mode for each. Ingress Controller will handle layer 7.
frontend ocp_http_ingress_frontend
    bind "$HA_BIND_IP1":80
    default_backend ocp_http_ingress_backend
    mode tcp
    option tcplog

backend ocp_http_ingress_backend
    balance source
    mode tcp
    server      ocp-w-1_80     "$IP_RANGE".131:80 check
    server      ocp-w-2_80     "$IP_RANGE".132:80 check
    server      ocp-w-3_80     "$IP_RANGE".133:80 check
    server      ocp-w-4_80     "$IP_RANGE".134:80 check
    server      ocp-w-5_80     "$IP_RANGE".135:80 check
    server      ocp-w-6_80     "$IP_RANGE".136:80 check
    server      ocp-w-7_80     "$IP_RANGE".137:80 check

frontend ocp_https_ingress_frontend
    bind "$HA_BIND_IP1":443
    default_backend ocp_https_ingress_backend
    mode tcp
    option tcplog

backend ocp_https_ingress_backend
    mode tcp
    balance source
    server      ocp-w-1_443     "$IP_RANGE".131:443 check
    server      ocp-w-2_443     "$IP_RANGE".132:443 check
    server      ocp-w-3_443     "$IP_RANGE".133:443 check
    server      ocp-w-4_443     "$IP_RANGE".134:443 check
    server      ocp-w-5_443     "$IP_RANGE".135:443 check
    server      ocp-w-6_443     "$IP_RANGE".136:443 check
    server      ocp-w-7_443     "$IP_RANGE".137:443 check

######################################################################################

# VIPAUTHHUB Ingress
frontend vip_http_ingress_frontend
    bind "$HA_BIND_IP2":80
    mode tcp
    option forwardfor
    option http-server-close
    default_backend vip_http_ingress_backend

backend vip_http_ingress_backend
    mode tcp
    balance roundrobin
    server      vip-w-1_32080     "$IP_RANGE".131:32080 check fall 3 rise 2 send-proxy-v2
    server      vip-w-2_32080     "$IP_RANGE".132:32080 check fall 3 rise 2 send-proxy-v2
    server      vip-w-3_32080     "$IP_RANGE".133:32080 check fall 3 rise 2 send-proxy-v2
    server      vip-w-4_32080     "$IP_RANGE".134:32080 check fall 3 rise 2 send-proxy-v2
    server      vip-w-5_32080     "$IP_RANGE".135:32080 check fall 3 rise 2 send-proxy-v2
    server      vip-w-6_32080     "$IP_RANGE".136:32080 check fall 3 rise 2 send-proxy-v2
    server      vip-w-7_32080     "$IP_RANGE".137:32080 check fall 3 rise 2 send-proxy-v2

frontend vip_https_ingress_frontend
    bind "$HA_BIND_IP2":443
    # mgmt-sspfqdn
    acl is_mgmt_ssp hdr_end(host) -i mgmt-ssp.okd.anapartner.dev
    use_backend vip_ingress-nodes_mgmt-nodeport if is_mgmt_ssp
    mode tcp
    #option forwardfor
    option http-server-close
    default_backend vip_https_ingress_backend

backend vip_https_ingress_backend
    mode tcp
    balance roundrobin
    server      vip-w-1_32443     "$IP_RANGE".131:32443 check fall 3 rise 2 send-proxy-v2
    server      vip-w-2_32443     "$IP_RANGE".132:32443 check fall 3 rise 2 send-proxy-v2
    server      vip-w-3_32443     "$IP_RANGE".133:32443 check fall 3 rise 2 send-proxy-v2
    server      vip-w-4_32443     "$IP_RANGE".134:32443 check fall 3 rise 2 send-proxy-v2
    server      vip-w-5_32443     "$IP_RANGE".135:32443 check fall 3 rise 2 send-proxy-v2
    server      vip-w-6_32443     "$IP_RANGE".136:32443 check fall 3 rise 2 send-proxy-v2
    server      vip-w-7_32443     "$IP_RANGE".137:32443 check fall 3 rise 2 send-proxy-v2

backend vip_ingress-nodes_mgmt-nodeport
    mode tcp
    balance roundrobin
    server      vip-w-1_32443     "$IP_RANGE".131:32443 check fall 3 rise 2 send-proxy-v2
    server      vip-w-2_32443     "$IP_RANGE".132:32443 check fall 3 rise 2 send-proxy-v2
    server      vip-w-3_32443     "$IP_RANGE".133:32443 check fall 3 rise 2 send-proxy-v2
    server      vip-w-4_32443     "$IP_RANGE".134:32443 check fall 3 rise 2 send-proxy-v2
    server      vip-w-5_32443     "$IP_RANGE".135:32443 check fall 3 rise 2 send-proxy-v2
    server      vip-w-6_32443     "$IP_RANGE".136:32443 check fall 3 rise 2 send-proxy-v2
    server      vip-w-7_32443     "$IP_RANGE".137:32443 check fall 3 rise 2 send-proxy-v2

######################################################################################

Use the following commands to add 2nd IP address to one NIC on the main VMware Workstation Host, where NIC = eno1 and 2nd IP address = 192.168.2.111

nmcli dev show eno1
sudo nmcli dev mod eno1 +ipv4.address 192.168.2.111/24

VMware Workstation Hosts / Nodes

When building the VMware hosts, ensure that you use Guest Type “Red Hat Enterprise Linux 8 x64” to match the embedded Red Hat Core OS provided in an ISO image. Otherwise, DHCP services may not work correctly, and when the VMware host boots, it may not receive an IP address.

The VMware hosts for Control Planes Nodes are recommended to be 8 vCPU, 16 GB RAM, and 100 HDD. The VMware hosts for Worker Nodes are recommended to be 4 vCPU, 16 GB RAM, and 100 HDD.
OpenShift requires a minimum of three (3) Control Plane Nodes and two (2) Worker Nodes. Please check with any solution you may deploy and adjust the parameters as needed. We will deploy four (4) Worker Nodes for Symantec VIP Auth Hub solution. And horizontally scale the solution with more worker nodes for Symantec API Manager and Siteminder.

Before starting any of these images, create a local snapshot as a “before” state. This will allow you to redeploy with minimal impact if there is any issue.

Before starting the deployment, you may wish to create a new NAT VMware Network, to avoid impacting any existing VMware images on the same address range. We will be adjusting the dhcpd.conf and dhcpd.leases files for this network.

To avoid an issue with reverse DNS lookup within PODS and Containers, remove a default value from dhcpd.conf. Stop vmware network, remove or comment out the line “option domain-name localdomain;” , remove any dhcpd.leases information, then restart the vmware network.

ls -lart /etc/vmware/vmnet8/dhcpd/dhcpd.leases ; echo ""
sudo /usr/bin/vmware-networks --stop ; echo ""
sudo cp /dev/null /etc/vmware/vmnet8/dhcpd/dhcpd.leases ; echo ""
ls -lart /etc/vmware/vmnet8/dhcpd/dhcpd.leases ; echo ""
cat      /etc/vmware/vmnet8/dhcpd/dhcpd.leases ; echo ""
sudo /usr/bin/vmware-networks --start ; echo ""
ls -lart /etc/vmware/vmnet8/dhcpd/dhcpd.leases ; echo ""
cat      /etc/vmware/vmnet8/dhcpd/dhcpd.leases ; echo ""

OpenShift / Kubernetes / Helm Command Line Binaries

Download these two (2) client packages to have three (3) binaries for interfacing with OpenShift/Kubernetes API Server.

Download Openshift Binaries for remote management (on main host)
#########################
sudo su -
cd /tmp/openshift
curl -skOL https://mirror.openshift.com/pub/openshift-v4/clients/helm/latest/helm-linux-amd64.tar.gz ; tar -zxvf helm-linux-amd64.tar.gz
curl -skOL https://mirror.openshift.com/pub/openshift-v4/x86_64/clients/ocp/stable/openshift-client-linux.tar.gz ; tar -zxvf openshift-client-linux.tar.gz
mv -f oc /usr/bin/oc
mv -f kubectl /usr/bin/kubectl
mv -f helm-linux-amd64 /usr/local/bin/helm
oc version
helm version
kubectl version

Start an OpenShift Cluster Deployment

OpenID Configuration with OpenShift

Post-deployment step: After you have deployed OpenShift cluster, you will be asked to create an IDP to authenticate other accounts. Below is an example with OpenShift and MS Azure. The image below showcases the parameters and values to be shared between the two solutions.

Entropy DaemonSet for OpenShift Nodes/Pods

We can validate the entropy on an OpenShift nodes or Pod via use of /dev/random. We prefer to emulate a 1000 password changes that showcase how rapidly the entropy pool of 4K is depleted when a security process accesses it. Example of the single line bash code.

Validate Entropy in Openshift Nodes [Before/After use of Haveged Deployment]
#########################
(counter=1;MAX=1001;time while [ $counter -le $MAX ]; do echo "";echo "##########  $counter ##########" ; echo "Entropy = `cat /proc/sys/kernel/random/entropy_avail`  out of 4096"; echo "" ; time dd if=/dev/random bs=8 count=1 2>/dev/null | base64; counter=$(( $counter + 1 )); done;)

To deploy an entropy daemonset, we can leverage what is documented by Broadcom/Symantec in their VIP Auth Hub documentation. https://techdocs.broadcom.com/us/en/symantec-security-software/identity-security/vip-authentication-hub/2022-Oct/operating/troubleshooting/checking-entropy-level.html#concept.dita_d3303fde-e786-4fd4-b0b6-e3a28fd60a82

$ cat <<EOF > | kubectl apply -f -
apiVersion: apps/v1
kind: DaemonSet
metadata:
  namespace: kube-system
  labels:
    run: haveged
  name: haveged
spec:
  selector:
    matchLabels:
      run: haveged
  template:
    metadata:
      labels:
        run: haveged
    spec:
      containers:
      - image: hortonworks/haveged:1.1.0
        name: haveged
        securityContext:
          privileged: true
      tolerations:
      - effect: NoSchedule
        operator: Exists
EOF

Patch OpenShift Workers

If the number of OpenShift Workers is greater than two (2), then you will need to patch the OpenShift Ingress controller to scale up to the number of worker nodes.

WORKERS=`oc get nodes | grep worker | wc -l`

echo ""
echo "######################################################################"
echo "# of Worker replicas in OpenShift Ingress Prior to update"
echo "oc get -n openshift-ingress-operator ingresscontroller -o yaml | grep -i replicas:"
#echo "######################################################################"
echo ""
oc patch -n openshift-ingress-operator ingresscontroller/default --patch "{\"spec\":{\"replicas\": ${WORKERS}}}" --type=merge

LetsEncrypt Certs for OpenShift Ingress and API Server

The certs with OpenShift are self-signed. This is not an issue until you attempt to access the local OpenShift console with a browser and are stopped from accessing the UI by newer security enforcement in the browsers. To avoid this challenge, we recommend switching the certs to LetsEncrypt. There are many examples how to rotate the certs. We used the below link to rotate the certs. https://docs.openshift.com/container-platform/4.12/security/certificates/replacing-default-ingress-certificate.html

echo "Installing ConfigMap for the Default Ingress Controllers"
oc delete configmap letsencrypt-fullchain-ca -n  openshift-config &>/dev/null
oc create configmap letsencrypt-fullchain-ca \
     --from-file=ca-bundle.crt=${CHAINFILE} \
     -n openshift-config

oc patch proxy/cluster \
     --type=merge \
     --patch='{"spec":{"trustedCA":{"name":"letsencrypt-fullchain-ca"}}}'

echo "Installing Certificates for the Default Ingress Controllers"
oc delete secret letsencrypt-certs -n openshift-ingress &>/dev/null
oc create secret tls letsencrypt-certs \
  --cert=${CHAINFILE} \
  --key=${KEYFILE} \
  -n openshift-ingress


echo "Backup prior version of ingresscontroller"
oc get ingresscontroller default -n openshift-ingress-operator -o yaml > /tmp/ingresscontroller.$DATE.yaml
oc patch ingresscontroller.operator default -n openshift-ingress-operator --type=merge --patch='{"spec": { "defaultCertificate": { "name": "letsencrypt-certs" }}}'


echo "Installing Certificates for the API Endpoint"
oc delete secret letsencrypt-certs  -n openshift-config  &>/dev/null
oc create secret tls letsencrypt-certs \
  --cert=${CHAINFILE} \
  --key=${KEYFILE} \
  -n openshift-config

echo "Backup prior version of apiserver"
oc get apiserver cluster -o yaml > /tmp/apiserver_cluster.$DATE.yaml
oc patch apiserver cluster --type merge --patch="{\"spec\": {\"servingCerts\": {\"namedCertificates\": [ { \"names\": [  \"$LE_API\"  ], \"servingCertificate\": {\"name\": \"letsencrypt-certs\" }}]}}}"

echo "#####################################################################################"
echo "true | openssl s_client -connect api.${DOMAIN}:443 --showcerts --servername api.${DOMAIN}"
echo ""


echo "It may take 5-10 minutes for the OpenShift Ingress/API Pods to cycle with the new certs"
echo "You may monitor with:  watch -n 2 'oc get pod -A | grep -i -v -e running -e complete'  "
echo ""
echo "Per Openshift documentation use the below command to monitor the state of the API server"
echo "ensure PROGRESSING column states False as the status before continuing with deployment"
echo ""
echo "oc get clusteroperators kube-apiserver "

Please reach out if you wish to learn more or have ANA assist with Kubernetes / OpenShift opportunities.