security
18195 TopicsDynamic import of data groups
Hello. We use data groups for various kind of black lists, such as undesirable user agents, for instance. That's really efficient, but requires a BigIP administrator intervention for any update. We'd like to switch authoritative origin for those lists to an external location, such as an internal git repository, in order to allow trusted people without access to the administration interface to update those lists in auditable manner, as we do for instance with our firewalls using "dynamic list" feature. There seems to be no such native fonctionality in BigIPs, as even "external" dynamic lists actually relies on files hosted on local filesystem, not to arbitrary URLs. We could probably use a cron task to implement a pull-based update mechanism, or use the API to periodically push changes, but I'm not sure of the reliability of such ad-hoc mechanism, and the potential consequences in case of failure. Is there any alternative for such kind of configuration delegation ? Regards, Guillaume126Views0likes4CommentsAutomating TLS Certificates in Kubernetes with cert-manager and F5 Distributed Cloud DNS
Introduction If you run workloads in Kubernetes or Open Shift, you've almost certainly dealt with TLS certificates. You need them everywhere — Ingress controllers, internal services, mutual TLS between microservices, and API gateways. Managing them by hand is error-prone and doesn't scale: certificates expire silently, rotation is forgotten, and the person who originally created the wildcard cert is now working somewhere else. cert-manager solves this elegantly. It's a Kubernetes-native certificate controller that automates the issuance, renewal, and management of TLS certificates. It speaks ACME — the same protocol Let's Encrypt uses — but ACME is a standard, not a Let's Encrypt exclusive. You can point cert-manager at: Let's Encrypt (free, public, widely trusted) ZeroSSL, Buypass, Google Trust Services — other public CAs supporting ACME Step CA / HashiCorp Vault / Smallstep — for private PKI running inside your infrastructure Any commercial CA that has implemented an ACME endpoint This means the same workflow, the same Kubernetes manifests, and the same tooling can back both your public-facing services and your internal, corporate-signed certificates. One operator to rule them all. Why DNS-01 Challenge? ACME offers multiple ways to prove you own a domain. The most common is the HTTP-01 challenge, where the ACME server checks a well-known URL on your domain. It works well, but has limitations: The endpoint must be publicly reachable on port 80 It cannot issue wildcard certificates (*.example.com) The DNS-01 challenge takes a different approach: cert-manager (via a solver webhook) creates a _acme-challenge.example.com TXT record in your DNS zone. The ACME server checks for this record. Once verified, the TXT record is cleaned up automatically. Benefits: Works behind firewalls — no inbound HTTP needed Supports wildcard certificates — a single *.example.com certificate covers all subdomains Fully automated — the webhook handles record creation and deletion If your DNS is managed by F5 Distributed Cloud (F5 XC), you can now wire this entire flow together with the open-source cert-manager-webhook-f5xc solver. Architecture Overview Here's what happens when cert-manager issues a certificate using the F5 XC webhook: Developer applies Certificate manifest ▼ cert-manager creates Order + Challenge ▼ cert-manager calls webhook (DNS-01 solver) ▼ Webhook calls F5 XC DNS API → Creates TXT record: _acme-challenge.example.com ▼ ACME server (Let's Encrypt / other) validates the TXT record ▼ Webhook cleans up the TXT record ▼ cert-manager stores the issued certificate in a Kubernetes Secret The webhook runs as a standard Kubernetes Deployment inside your cluster, registered with cert-manager via a ValidatingWebhookConfiguration. It receives solver calls from cert-manager and translates them into F5 XC DNS API calls using an API token you provide as a Kubernetes Secret. Prerequisites Before we start, make sure you have the following in place: A Kubernetes cluster (1.21+) cert-manager installed (v1.14+) kubectl apply -f https://github.com/cert-manager/cert-manager/releases/latest/download/cert-manager.yaml Helm 3.8+ An F5 Distributed Cloud tenant with DNS management enabled Your domain's DNS zone managed in F5 XC F5 XC credentials for DNS API access — either an API Token or a Client Certificate (P12); see Step 1 below for details Least privilege note: The service account or user whose credentials you use must have permission to manage DNS records. As of the time of writing, the built-in role f5xc-dns-management-admin is sufficient. Avoid using tenant-admin or other overly broad roles — the webhook only needs to create and delete TXT records in your DNS zone. Step 1: Prepare F5 XC Credentials The webhook supports two authentication methods against the F5 XC DNS API: an API Token or a Client Certificate (P12). Both are stored as a Kubernetes Secret in the cert-manager namespace. Obtaining credentials in F5 XC Console Regardless of which method you choose, the service account must have sufficient permissions to manage DNS records. Follow the least-privilege principle: In the F5 XC Console, navigate to Account Settings → Administration. Create a dedicated service credential under IAM and assign it the f5xc-dns-management-admin role in the system namespace — this is the minimum required role as of the time of writing and grants access to DNS Zone Management without unnecessary privileges elsewhere in the tenant. Or use an existing account privileges under Personal Management credentials. Generate the credentials of your preferred type (API Token or API Certificate) Option A: API Token (simpler, recommended for most setups) Take the API Token obtained from the F5XC console and use it with the following command kubectl create secret generic f5xc-api-token \ --namespace cert-manager \ --from-literal=token=<YOUR_F5XC_API_TOKEN> Option B: Client Certificate (P12) F5 XC also supports certificate-based authentication using a P12 (PKCS#12) client certificate, which may be preferred in environments. Use the certificate and password generated in the previous step and store it as a Secret: kubectl create secret generic f5xc-client-cert \ --namespace cert-manager \ --from-file=certificate.p12=<PATH_TO_YOUR.p12> \ --from-literal=password=<P12_PASSWORD> Refer to the webhook documentation for the exact certificateSecretRef fields to use in the solver config when choosing this method. Verify the secret was created: kubectl get secret f5xc-api-token -n cert-manager Step 2: Install the Webhook via Helm The chart is published as an OCI artifact on GitHub Container Registry. Install it into the cert-manager namespace: helm install cert-manager-webhook-f5xc \ oci://ghcr.io/wenkow/charts/cert-manager-webhook-f5xc \ --namespace cert-managerbaba Check the rollout: kubectl rollout status \ deployment cert-manager-webhook-f5xc \ -n cert-manager kubectl get pods -n cert-manager Step 3: Configure a ClusterIssuer A ClusterIssuer tells cert-manager which ACME server to use and how to solve challenges. Here we're pointing it at Let's Encrypt production and configuring the F5 XC DNS-01 solver. Note on groupName: The field appears twice in the YAML below and serves different purposes. At the webhook level, it's a fixed identifier (acme.f5xc.io) that tells cert-manager which registered webhook to call. Inside config, it's the RRSet group name within your F5 XC DNS zone — a logical container for DNS records created by the webhook. You can choose any name; F5 XC will create the group if it doesn't exist. clusterissuer.yaml: apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt-f5xc-prod spec: acme: email: admin@example.com server: https://acme-v02.api.letsencrypt.org/directory privateKeySecretRef: name: letsencrypt-f5xc-prod-account-key solvers: - dns01: webhook: # Fixed identifier — tells cert-manager which webhook to call groupName: acme.f5xc.io solverName: f5xc config: # Your F5 XC tenant name (subdomain part of your console URL) tenantName: my-tenant # RRSet group name in F5 XC DNS zone groupName: "cert-manager" # ttl: 120 # optional, default is 120 seconds apiTokenSecretRef: name: f5xc-api-token key: token # If using certificate-based auth instead of a token, replace # apiTokenSecretRef with certificateSecretRef — see webhook docs. Apply it: kubectl apply -f clusterissuer.yaml Verify it's ready: kubectl get clusterissuer letsencrypt-f5xc-prod Step 4: Request a Certificate Now the fun part. Create a Certificate resource. Note that we're requesting both the apex domain and a wildcard — something that's only possible with DNS-01. certificate.yaml: apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: example-tls namespace: default spec: secretName: example-tls issuerRef: name: letsencrypt-f5xc-prod kind: ClusterIssuer dnsNames: - example.com - "*.example.com" Apply it: kubectl apply -f certificate.yaml Step 5: Watch the Certificate Lifecycle This is where it gets satisfying to watch. cert-manager creates an Order, which spawns one or more Challenge objects. Each Challenge triggers the F5 XC webhook to create a DNS TXT record. Watch Certificate status kubectl get certificate example-tls -n default -w Inspect the Order kubectl get orders -n default kubectl describe order example-tls-1-3552197254 -n default Status: Authorizations: Challenges: Token: <token> Type: dns-01 URL: https://acme-v02.api.letsencrypt.org/acme/chall/... Identifier: example.com Initial State: valid URL: https://acme-v02.api.letsencrypt.org/acme/authz/... Wildcard: true Challenges: Token: <token> Type: dns-01 URL: https://acme-v02.api.letsencrypt.org/acme/chall/... Identifier: example.com Initial State: valid URL: https://acme-v02.api.letsencrypt.org/acme/authz/... Wildcard: false Certificate: REDACTED Finalize URL: https://acme-v02.api.letsencrypt.org/acme/finalize/... State: valid URL: https://acme-v02.api.letsencrypt.org/acme/order/... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Complete 8m37s cert-manager-orders Order completed successfully Inspect the Challenges before it's done kubectl get challenges -n default kubectl describe challenge example-tls-<1234567890> -n default Verify the Issued Certificate kubectl get secret example-tls -n default -o jsonpath='{.data.tls\.crt}' \ | base64 -d | openssl x509 -noout -text | grep -E "Subject:|DNS:|Not After" Not After : Aug 19 19:22:31 2026 GMT Subject: CN = example.com DNS:*.example.com, DNS:example.com Both the apex domain and the wildcard are covered by a single certificate. Using a Custom or Internal ACME Server One of the most powerful aspects of this setup is that the ACME server is completely configurable. If you run an internal CA — for example HashiCorp Vault with the ACME secrets engine, or Step CA — just change the server field in your ClusterIssuer: spec: acme: email: admin@internal.example.com server: https://vault.internal.example.com/v1/pki/acme/directory # or # server: https://step-ca.internal.example.com/acme/acme/directory The webhook doesn't care which ACME server you use — it only handles the DNS side of the challenge. This makes the setup equally useful for: Internet-facing services using Let's Encrypt Internal services using a corporate CA Mixed environments where different ClusterIssuer objects point to different CAs, all sharing the same F5 XC DNS solver Troubleshooting Tips Challenge stays in pending for a long time Check the webhook logs for API errors: kubectl logs -n cert-manager -l app=cert-manager-webhook-f5xc --tail=50 READY: False on ClusterIssuer Usually means cert-manager couldn't register an ACME account. Check that the email field is valid and the ACME server URL is reachable. TXT record not appearing in F5 XC - Verify that the credentials you stored in the Secret have the right DNS permissions. In F5 XC Console, check that the service account has the f5xc-dns-management-admin role (or equivalent). API token permission issues will typically surface as 403 Forbidden errors in the webhook logs. Summary The cert-manager-webhook-f5xc project closes the loop between F5 Distributed Cloud DNS and the Kubernetes-native certificate management ecosystem. With a few manifests and a Helm install, you get: Fully automated certificate issuance and renewal — no manual interventions, no expiry surprises Wildcard certificate support out of the box via DNS-01 ACME provider flexibility — works with Let's Encrypt, commercial CAs, or your internal PKI Clean Kubernetes-native UX — certificates are just resources; the entire lifecycle is observable with standard kubectl commands The webhook is open source, available on GitHub and packaged on Artifact Hub. Contributions and feedback are welcome. Related Resources cert-manager documentation cert-manager DNS01 webhook reference F5 Distributed Cloud DNS Management docs GitHub: Wenkow/cert-manager-webhook-f5xc Artifact Hub: cert-manager-webhook-f5xc114Views2likes1CommentAWAF Detection Inconsistency Between Similar Test Payloads
Hi everyone, I'm testing F5 AWAF against several attack payloads in a lab environment (crAPI). I noticed some inconsistent detection behavior and would like to know whether this is expected, a signature coverage issue, or a content profile configuration issue. Environment F5 AWAF / ASM Wildcard URL policy Attack signatures enabled Form Data, JSON, and XML request body handling configured Default content profile set to "Apply value and content signatures and detect threat campaigns" Case 1 - Command Injection The following payload is detected: POST /clam.php Content-Type: application/x-www-form-urlencoded cmd=cat /etc/passwd AWAF triggers: Unix "cmd" parameter execution attempt However, the following payload is not detected: POST /clam.php Content-Type: application/x-www-form-urlencoded cmd=127.0.0.1 && ls /etc The request body is visible in the event logs, so parsing appears to be working correctly. Has anyone observed similar behavior with command execution signatures? Case 2 - Multipart Form Data AWAF successfully detects directory traversal inside multipart/form-data: Content-Disposition: form-data; name="/static/img/../../etc/passwd" test However, some multipart XSS payloads are not detected, for example: Content-Disposition: form-data; name="random" <x/Onpointerrawupdate=confirm()>xxxxx while other XSS payloads such as onerror-based payloads are detected and blocked. Questions Is this expected signature coverage behavior? Are command execution signatures expected to detect payloads like:127.0.0.1 && ls /etc Are there known limitations for newer event handlers such as:onpointerrawupdate= Would enabling Base64 Decoding in Header-Based Content Profiles have any effect on these cases, or is this unrelated because the payloads are not Base64 encoded? Are there recommended Signature Sets or Evasion settings that improve detection for these payloads? Any guidance would be appreciated.17Views0likes0CommentsAutomating F5 Application Delivery and Security Platform Deployments
The F5 ADSP Architecture Automation Project The F5 Application Delivery and Security Platform (ADSP) reduces the complexity of modern applications by integrating operations, traffic management, performance optimization, and security controls into a single platform with multiple deployment options. This series outlines practical steps anyone can take to put these ideas into practice using the F5 ADSP Architectures GitHub repo and related projects. Each article in the series highlights a different deployment example. The examples can be run locally or integrated into CI/CD pipelines following DevSecOps practices. The repositories are community-supported and intended as reference code for demos, workshops, or as a stepping stone for your own F5 ADSP deployments. If you find any bugs or have any enhancement requests, open an issue, or better yet, contribute. The F5 Application Delivery and Security Platform (F5 ADSP) F5 ADSP addresses four core areas: how you operate day-to-day, how you deploy at scale, how you secure against evolving threats, and how you deliver reliably across environments. Each comes with its own challenges, but together they define the foundation for keeping systems fast, stable, and safe. xOps — day-to-day operations, observability, and lifecycle management Deployment — getting workloads where they need to go, at the scale they need Delivery — traffic management across hybrid and multi-cloud environments Security — protecting applications and APIs from current threats Each architecture deployment example in this series is designed to cover at least three of the four core areas. This ensures the examples demonstrate how multiple components of the platform work together in practice, rather than showcasing any single feature in isolation. DevSecOps: Integrating security into the software delivery lifecycle is a necessary part of building and maintaining secure applications. This project incorporates DevSecOps practices by using supported APIs and tooling, with each use case including a GitHub repository containing IaC code, CI/CD integration examples, and telemetry options. In practice across the series, that means Terraform for infrastructure and F5 configuration, GitHub Actions as the pipeline runner, federated cloud identity instead of long lived keys, secrets handled through the platform rather than committed, and vulnerable target applications so the security controls can be exercised end-to-end. Contribute The repos are community-supported. Open an issue, send a PR, or port a use case to another cloud. Resources: F5 Application Delivery and Security Platform GitHub Repo and Automation Guide ADSP Architecture Article Series: Automating F5 ADSP Deployments (Intro) Automating F5 ADSP Deployments (Part 1 - F5 XC WAF and BIG-IP Adv. WAF) Automating F5 ADSP Deployments (Part 2 - F5 XC WAF and NGINX App Protect) Automating F5 ADSP Deployments (Part 3 - F5 XC API Protection and NGINX Ingress) Automating F5 ADSP Deployments (Part 4 - F5 XC BOT Defense and BIG-IP AdvWAF) Automating F5 ADSP Deployments (Part 5 - F5 XC, BIG-IP APM, CIS, and NGINX Ingress) Minimizing Security Complexity: Managing Distributed WAF Policies682Views3likes0CommentsDeploying an NGINX App across Kubernetes Multi-clusters with F5 BIG-IP Container Ingress Services
This tutorial simulates orchestrating multiple clusters using a single Kubernetes control plane with separate kubeconfig contexts, the same F5 CIS configuration patterns apply to genuinely separate Kubernetes clusters across different networks, cloud regions, or data centers. The simulation approach allows configuration testing without requiring multiple physical or cloud infrastructure environments.91Views1like0CommentsAPM URL encoding Hardening?
Some companies still use on-prem Sharepoint.. and Sharepoint is what it is. We have had multiple servers deployed for quite some while now with ASM tuned for its quirks and so on. However - after upgrading to version 17.5.1.6 from 17.5.1.5 we noticed some rather strange behaviors. Like the edit modal button stopped working on certain sites, the upload button stopped working amongst some of the stuff. After some testing and stripping of functions we noticed that it started working when removing the APM policy. So the cogs started turning, what could be the issue with APM? Finally figured out that the links which did not work where not encoded, and the links which worked were. So after some tweaking I got to building a simple http request rewrite iRule for simply encoding the stuff before sending to server. But I do have some qualms about it - Are there any security risks according to you dear people that I might introduce by deploying this externally? Would you have solved it in any other way? basically it's this: when HTTP_REQUEST { # Re-encode characters that are illegal in URIs per RFC 3986 §2.2 / §3.4 set orig_uri [HTTP::uri] set new_uri [string map { "\{" "%7B" "\}" "%7D" "|" "%7C" "\\" "%5C" "^" "%5E" "`" "%60" " " "%20" } $orig_uri] if { $new_uri ne $orig_uri } { HTTP::uri $new_uri } }Solved148Views0likes2CommentsBIG-IQ CM Logs Not Receiving
Once the disk space has been released, you need to rectify the condition below by running the provided command # for idx in $(curl -ks -u admin:admin https://localhost:9200/_cat/indices | awk '{print $3}'); do if [ $idx != ".opendistro_security" ]; then curl -k -u admin:admin -X PUT "https://localhost:9200/$(echo $(echo $idx | cut -d\+ -f1)*)/_settings?pretty" -H 'Content-Type: application/json' -d'{"index.blocks.read_only_allow_delete": false}'; fi; done31Views0likes0CommentsSSL Orchestrator Advanced Use Cases: Client Certificate Constrained Delegation (C3D) Support
Introduction F5 BIG-IP is synonymous with "flexibility". You likely have few other devices in your architecture that provide the breadth of capabilities that come native with the BIG-IP platform. And for each and every BIG-IP product module, the opportunities to expand functionality are almost limitless. In this article series we examine the flexibility options of the F5 SSL Orchestrator in a set of "advanced" use cases. If you haven't noticed, the world has been steadily moving toward encrypted communications. Everything from web, email, voice, video, chat, and IoT is now wrapped in TLS, and that's a good thing. The problem is, malware - that thing that creates havoc in your organization, that exfiltrates personnel records to the Dark Web - isn't stopped by encryption. TLS 1.3 and multi-factor authentication don't eradicate malware. The only reasonable way to defend against it is to catch it in the act, and an entire industry of security products are designed for just this task. But ironically, encryption makes this hard. You can't protect against what you can't see. F5 SSL Orchestrator simplifies traffic decryption and malware inspection, and dynamically orchestrates traffic to your security stack. But it does much more than that. SSL Orchestrator is built on top of F5's BIG-IP platform, and as stated earlier, is abound with flexibility. SSL Orchestrator Use Case: Client Certificate Constrained Delegation (C3D) Using certificates to authenticate is one of the oldest and most reliable forms of authentication. While not every application supports modern federated access or multi-factor schemes, you'll be hard-pressed to find something that doesn't minimally support authentication over TLS with certificates. And coupled with hardware tokens like smart cards, certificates can enable one of the most secure multi-factor methods available. But certificate-based authentication has always presented a unique challenge to security architectures. Certificate "mutual TLS" authentication requires an end-to-end TLS handshake. When a server indicates a requirement for the client to submit its certificate, the client must send both its certificate, and a digitally-signed hash value. This hash value is signed (i.e. encrypted) with the client's private key. Should a device between the client and server attempt to decrypt and re-encrypt, it would be unable to satisfy the server's authentication request by virtue of not having access to the client's private key (to create the signed hash). This makes encrypted malware inspection complicated, often requiring a total bypass of inspection to sites that require mutual TLS authentication. Fortunately, F5 has an elegant solution to this challenge in the form of Client Certificate Constrained Delegation, affectionally referred to as "C3D". The concept is reasonably straightforward. In very much the same way that SSL forward proxy re-issues a remote server certificate to local clients, C3D can re-issue a remote client certificate to local servers. A local server can continue to enforce secure mutual TLS authentication, while allowing the BIG-IP to explicitly decrypt and re-encrypt in the middle. This presents an immediate advantage in basic load balancing, where access to the unencrypted data allows the BIG-IP greater control over persistence. In the absence of this, persistence would typically be limited to IP address affinity. But of course, access to the unencrypted data also allows the content to be scanned for malicious malware. C3D actually takes this concept of certificate re-signing to a higher level though. The "constrained delegation" portion of the name implies a characteristic much like Kerberos constrained delegation, where (arbitrary) attributes can be inserted into the re-signed token, like the PAC attributes in a Kerberos ticket, to inform the server about the client. Servers for their part can then simply filter on client certificates issued by the BIG-IP (to prevent direct access), and consume any additional attributes in the certificate to understand how better to handle the client. With C3D you can maintain strong mutual TLS authentication all the way through to your servers, while allowing the BIG-IP to more effectively manage availability. And combined with SSL Orchestrator, C3D can enable decryption and inspection of content for malware inspection. This article describes how to configure SSL Orchestrator to enable C3D for inbound decrypted inspection. Arguably, most of what follows is the C3D configuration itself, as the integration with SSL Orchestrator is pretty simple. Note that Client Certificate Constrained Delegation (C3D) is included with Local Traffic Manager (LTM) 13.0 and beyond, but for integration with SSL Orchestrator you should be running 14.1 or later.To learn more about C3D, please see the following resources: K14065425: Configuring Client Certificate Constrained Delegation (C3D): https://support.f5.com/csp/article/K14065425 Manual Chapter: SSL Traffic Management: https://techdocs.f5.com/en-us/bigip-15-1-0/big-ip-system-ssl-administration/ssl-traffic-management.html#GUID-B4D2529E-D1B0-4FE2-8C7F-C3774ADE1ED2 SSL::c3d iRule reference - not required to use C3D, but adds powerful functionality https://clouddocs.f5.com/api/irules/SSL__c3d.html The integration of C3D with SSL Orchestrator involves effectively replacing the client and server SSL profiles that the SSL Orchestrator topology creates, with C3D SSL profiles. This is done programmatically with an iRule, so no "non-strict" customization is required at the topology. Also note that an inbound (reverse proxy) SSL Orchestrator topology will take the form of a "gateway mode" deployment (a routed path to multiple applications), or "application mode" deployment (a single application instance hosted at the BIG-IP). See section 2.5 of the SSL Orchestrator deployment guide for a deeper examination of gateway and application modes: https://clouddocs.f5.com/sslo-deployment-guide/ The C3D integration is only applicable to application mode deployments. Configuration C3D itself involves the creation of client and server SSL profiles: Create a new Client SSL profile: Configuration Certificate Key Chain: public-facing server certificate and private key. This will be the certificate and key presented to the client on inbound request. It will likely be the same certificate and key defined in the SSL Orchestrator inbound topology. Client Authentication Client Certificate: require Trusted Certificate Authorities: bundle that can validate client certificate. This is a certificate bundle used to verify the client's certificate, and will contain all of the client certificate issuer CAs. Advertised Certificate Authorities: optional CA hints bundle. Not expressly required, but this certificate bundle is forwarded to the client during the TLS handshake to "hint" at the correct certificate, based on issuer. Client Certificate Constrained Delegation Client Certificate Constrained Delegation: Enabled Client Fallback Certificate (new in 15.1): option to select a default client certificate if client does not send one. This option was introduced in 15.1 and provides the means to select an alternate (local) certificate if the client does not present one. The primary use case here might be to select a "template" certificate, and use an iRule function to insert arbitrary attributes. OCSP: optional client certificate revocation control. This option defines an OCSP revocation provider for the client certificate. Unknown OCSP Response Control (new in 15.1): determines what happens when OCSP returns Unknown. If an OCSP revocation provider is selected, this option defines what to do if the response to the OCSP query is "unknown". Create a new Server SSL profile: Configuration Certificate: default.crt. The certificate and key here are used as "templates" for the re-signed client certificate. Key: default.key Client Certificate Configuration Delegation Client Certificate Constrained Delegation: Enabled CA Certificate: local forging CA cert. This is the CA certificate used to re-sign the client certificate. This CA must be trusted by the local servers. CA Key: local forging CA key CA Passphrase: optional CA passphrase Certificate Extensions: extensions from the real client cert to be included in the forged cert. This is the list of certificate extensions to be copied from the original certificate to the re-issued certificate. Custom Extension: additional extensions to copy to forged cert from real cert (OID). This option allows you to insert additional extensions to be copied, as OID values. Additional considerations: Under normal conditions, the F5 and backend server attempt to resume existing SSL sessions, whereby the server doesn’t send a Certificate Request message. The effect is that all connections to the backend server use the same forged client cert. There are two ways to get around this: Set a zero-length cache value in the server SSL profile, or Set server authentication frequency to ‘always’ in the server SSL profile CA certificate considerations: A valid signing CA certificate should possess the following attributes. While it can work in some limited scenarios, a self-signed server certificate is generally not an adequate option for the signing CA. keyUsage: certificate extension containing "keyCertSign" and "digitalSignature" attributes basicConstraints: certificate extension containing "CA = true" (for Yes), marked as "Critical" With the client and server SSL profiles built, the C3D configuration is basically done. To integrate with an inbound SSL Orchestrator topology, create a simple iRule and add it to the topology's Interception Rule configuration. Modify the SSL profile paths below to reflect the profiles you created earlier. ### Modify the SSL profile paths below to match real C3D SSL profiles when CLIENT_ACCEPTED priority 250 { ## set clientssl set cmd1 "SSL::profile /Common/c3d-clientssl" ; eval $cmd1 } when SERVER_CONNECTED priority 250 { ## set serverssl SSL::profile "/Common/c3d-serverssl" } In the SSL Orchestrator UI, either from topology workflow, or directly from the corresponding Interception Rule configuration, add the above iRule and deploy. The above iRule programmatically overrides the SSL profiles applied to the Interception Rule (virtual server), effectively enabling C3D support. At this point, the virtual server will request a client certificate, perform revocation checks if defined, and then mint a local copy of the client certificate to pass to the backend server. Optionally, you can insert additional certificate attributes via the server SSL profile configuration, or more dynamically through additional iRule logic: ### Added in 15.1 - allows you to send a forged cert to the server ### irrespective of the client side authentication (ex. APM SSO), ### and insert arbitrary values when SERVERSSL_SERVERCERT { ### The following options allow you to override/replace a submitted ### client cert. For example, a minted client certificate can be sent ### to the server irrespective of the client side authentication method. ### This certificate "template" could be defined locally in the iRule ### (Base64-encoded), pulled from an iFile, or some other certificate source. # set cert1 [b64decode "LS0tLS1a67f7e226f..."] # set cert1 [ifile get template-cert] ### In order to use a template cert, it must first be converted to DER format # SSL::c3d cert [X509::pem2der $cert1] ### Insert arbitrary attributes (OID:value) SSL::c3d extension 1.3.6.1.4.1.3375.3.1 "TEST" } If you've configured the above, a server behind SSL Orchestrator that requires mutual TLS authentication can receive minted client certificates from external users, and SSL Orchestrator can explicitly decrypt and pass traffic to the set of malware inspection tools. You can look at the certificate sent to the server by injecting a tcpdump packet between the BIG-IP and server, then open in Wireshark. tcpdump -lnni [VLAN] -Xs0 -w capture.pcap [additional filters] Finally, you might be asking what to do with certificate attributes injected by C3D, and really it depends on what the server can support. The below is a basic example in an Apache config file to block a client certificate that doesn't contain your defined attribute. <Directory /> SSLRequire "HTTP/%h" in PeerExtList("1.3.6.1.4.1.3375.3.1") RewriteEngine on RewriteCond %{SSL::SSL_CLIENT_VERIFY} !=SUCCESS RewriteRule .? - [F] ErrorDocument 403 "Delegation to SPN HTTP/%h failed. Please pass a valid client certificate" </Directory> And there you have it. In just a few steps you've configured your SSL Orchestrator to integrate with Client Certificate Constrained Delegation to support mutual TLS authentication, and along the way you have hopefully recognized the immense flexibility at your command. Updates As of F5 BIG-IP 16.1.3, there are some new C3D capabilities: C3D has been updated to encode and return the commonName (CN) found in the client certificate subject field in printableString format if possible, otherwise the value will be encoded as UTF8. C3D has been updated to support inserting a subject commonName (CN) via 'SSL::c3d subject commonName' command: when CLIENTSSL_HANDSHAKE { if {[SSL::cert count] > 0} { SSL::c3d subject commonName [X509::subject [SSL::cert 0] commonName] } } C3D has been updated to support inserting a Subject Alternative Name (SAN) and Authority Info Access (AIA) via 'SSL::c3d extension' commands: when CLIENTSSL_HANDSHAKE { ## Insert Subject Alternative Name (SAN) value SSL::c3d extension SAN "DNS:*.test-client.com, IP:1.1.1.1" ### Insert Authority Info Access (AIA) value SSL::c3d extension AIA "ocsp,https://ocsp.entrust.net.com; caIssuer, https://aia.entrust.net/l1m-chain256.cer" } C3D has been updated to add the Authority Key Identifier (AKI) extension to the client certificate if the CA certificate has a Subject Key Identifier (SKI) extension. Another interesting use case is copying the real client certificate Subject Key Identifier (SKI) to the minted client certificate. By default, the minted client certificate will not contain an SKI value, but it's easy to configure C3D to copy the origin cert's SKI by modifying the C3D server SSL profile. In the "Custom extension" field of the C3D section, add 2.5.29.14 as an available extension. __________________________________________ As of F5 BIG-IP 17.1.0 (SSL Orchestrator 11.0), C3D has been integrated natively. Now, for a deployed Inbound topology, the C3D SSL profiles are listed in the Protocol Settings section of the Interception Rules tab. You can replace the client and server SSL profiles created by SSL Orchestrator, with C3D SSL profiles in the Interception Rules tab to support C3D. The C3D support is now extended to both Gateway and Application modes. __________________________________________ As of F5 BIG-IP 21.1, there are some new C3D capabilities: C3D adds a new option in the server SSL profile to enable overriding the certificate start date. This overrides the notBefore (valid-from) attribute of forged certificates to dynamically set the certificate's start time to align with the exact time of certificate forging. C3D adds a new option in the server SSL profile to enable caching of forged certificates. This reduces the need to repeatedly generate them for similar transactions, thereby improving efficiency during high-traffic scenarios, and reducing computational overhead in TLS proxy flows. C3D adds a new iRule command to keep or override the notBefore date in the forged certificate. when CLIENTSSL_HANDSHAKE { ## Update forged certificate lifespan SSL::c3d cert_lifespan [1-8760] } C3D adds a new iRule command to override the forged certificate lifespan. when CLIENTSSL_HANDSHAKE { ## Override the forged certificate notBefore date SSL::c3d cert_start_date [ override | original ] } C3D adds a new iRule command to inject X.509 keyUsage attributes into the forged certificate. when CLIENTSSL_HANDSHAKE { ## Injects KeyUsage constraints into the forged certificate SSL::c3d extension KU "digitalSignature, keyEncipherment" } C3D adds a new iRule command to inject X.509 extendedKeyUsage attributes into the forged certificate. when CLIENTSSL_HANDSHAKE { ## Injects extendedKeyUsage constraints into the forged certificate SSL::c3d extension EKU "serverAuth, clientAuth" } C3D adds a new iRule command to inject X.509 subjectDirectoryAttributes into the forged certificate. when CLIENTSSL_HANDSHAKE { ## Injects subjectDirectoryAttributes constraints into the forged certificate SSL::c3d extension SDA "dateOfBirth:20000101000000Z, countryOfCitizenship:US" } Note that certificate extensions enabled in the C3D server SSL profile configuration are copy operations. When enabled they copy the selected attributes from the origin certificate. The iRule commands are write operations. They allow you to specify new attribute values.4.7KViews2likes3CommentsHow to use F5 Distributed Cloud to block (OFAC) Sanctioned Countries
Over the last several days, the climate has changed significantly in Eastern Europe, and I have been getting asked a lot about the possibility of blocking Office of Foreign Assets Control - Sanctioned Countries (OFAC) with F5 Distributed Cloud, and how to do it. The answer is quite simple; yes we can do it and its a pretty simple configuration. I think its also important to point out that this same process can be used to configure any other required GeoFencing policies as well. Do we also have ways to block DDOS and provide WAAP services? Also yes, but outside the scope of this article. In this article, I will focus on how to deploy & create: [Namespace] Service Policies Origin Pool(s) to send traffic to Distributed listener / load balancer with the security policy assigned View Security Events. Level Set Most of this article will be based around ClickOps deployment of this use-case. That said, the F5 Distributed Cloud is an API first platform, so everything can be done with your tools of choice for interaction with declarative APIs. I will include JSON manifests of the configured items as well to provide examples of what delcarations will resemble, as well as support direct import into the distributed cloud. It would be possible to say, set the policy configuration JSON into github as a source of truth, and have webhooks set up to push to the platform any time a change is made to ensure configurations stay within proper alignment. Who do we block? Before we can start blocking things, we need to know what exactly to block, so we need to acquire a list of OFAC Sanctioned Countries. There are a couple of options here as well. CSV straight from the source: https://home.treasury.gov/policy-issues/office-of-foreign-assets-control-sanctions-programs-and-information Dig through available data sources on Data.Gov: https://catalog.data.gov/dataset/consolidated-non-sdn-sanctions-list Third Party ACL Sites like Country Block List: https://www.countryipblocks.net/ofac.php (I cannot personally vouch for the accuracy of this content.) For the sake of brevity here, I will focus on just some top level country sanctions based on country code versus IP Subnet, but thats up to preference. Configuration Log in to your F5 Distributed Cloud Console. (If you do not have a tenant today, you should reach out to your F5 Account Team immediately and rectify the situation!) Service Policies for everyone! There are a couple of options for service policies in the platform. Shared Policies: Policies created in the Shared namespace, can be shared globally within your tenant. Benefit: Globally set policy baseline for all applications in your tenant. Namespace Policies: Policies created in a Namespace can only be shared within that namespace. Benefit: Namespace service policies applied by default to all listeners / load balancers. For this example, we will create the policy in a namespace. From the tiles, select Load Balancers, and then we need to ensure that we are in the proper namespace. (As with everyting on the platform, there are multiple ways to get places, and multple ways to configure things, so this will only cover 1 example of how.) Now we need to expand Security, hover over Service Policies, Click Service Policies, and in the new window click Add service policy. Populate the Name under metadata, leave attachment as Any Server, and set Select Policy Rules to Denied Sources. Now, we could use IP blocks, but for this example we will just use the Country List configuration parameter and enter country codes. This will pull from GeoIP validation. UPDATE: I have been getting a lot of notes on this article based on Ukraine versus Crimea, and how to specify since its not seperated out as a country code. Can we Allow Ukraine and block Crimea? Absolutely! For Crimea, we need to pull from another database, so for this example I am going to pull from https://bgpview.io/search/Crimea and we are going to block by ASN. So within our service policy, click Add item under BGP ASN Set. And on this screen we enter in all the ASN's that we discovered from the previous link. Then click Apply. (Making sure to now remove Ukraine from our Block List.) Then we need to determine Default Action. This is where you can cause some pain for yourself, so pay special attention when selecting Default action (“Default Action for requests from sources that do not belong to this list”), if you are using Next Policy, ensure the next policy allows traffic, or set the Default action to Allow, or the application will not receive any traffic. In this example I will only be using one policy, so I will set the Default Action to Allow (as noted in the JSON). Save and Exit. UPDATE 2: OK, you guys are killing me! Can we go to City Level or target regions outside of ASN? Yes! Here is how you do that. (I should plan better in the future for less edits!) Just to keep things clean, lets add a new Service Policy. This time, under Select Policy Rules, we are going to select Custom Rule List from the drop down. Then from here, we want to click Configure under Rules, then Add Item. Give our new rule a name, and click Configure under Rule Specification. From here, we are going to change the dropdown under Clients - Client Selection from Any Client to Group of Clients by Label Selector. Then under Selector Expression, Add Label. In the available selections you will find geoip.ves.io/city, country, and region (as well as some really cool IP Intelligence options but those are out of scope for this article.). Lets do a Region first to see how that works. Selct geoip.ves.io/region, then =, then start typing a region, for example Crimea. Once we have it set, scroll down and click Apply. Now, lets add another rule, but this time we are going to select city. We are already blocking Russia in our earlier policy, but just for an example lets add = Moscow. Now scroll down and click Apply. Thats it! Now we have policies to block based on GeoIP Country, Region, and City, as well as BGP ASN. We can apply all of them to our application at the same time. Now, lets say you just want to cheat, and copy and paste some JSON in, or you want to build it into a pipeline. You can go and check out the API specifications for Service Policy here: https://docs.cloud.f5.com/docs/api/service-policy The JSON would resemble the following for our first policy: { "metadata": { "name": "coleman-ofac-deny", "namespace": "m-coleman", "labels": {}, "annotations": {}, "description": "", "disable": false }, "spec": { "algo": "FIRST_MATCH", "any_server": {}, "rules": [ { "kind": "service_policy_rule", "uid": "c12f8c5d-44c2-495c-83e8-30842e9e0a7f", "tenant": "f5-sa-rnxeudss", "namespace": "m-coleman", "name": "ves-io-service-policy-coleman-ofac-deny-asn-list" }, { "kind": "service_policy_rule", "uid": "5d24d0d0-6c6b-4c7b-b5b3-4bec67c2ffed", "tenant": "f5-sa-rnxeudss", "namespace": "m-coleman", "name": "ves-io-service-policy-coleman-ofac-deny-country-list" }, { "kind": "service_policy_rule", "uid": "f9df0b83-21de-4c13-aebf-4e27fc580ed0", "tenant": "f5-sa-rnxeudss", "namespace": "m-coleman", "name": "ves-io-service-policy-coleman-ofac-deny-default-action" } ], "deny_list": { "ip_prefix_set": [], "asn_list": { "as_numbers": [ 204791, 205515, 208090, 28761, 41269, 43222, 43564, 49617, 59744, 8654 ] }, "asn_set": [], "country_list": [ "COUNTRY_BY", "COUNTRY_BA", "COUNTRY_BI", "COUNTRY_CF", "COUNTRY_CU", "COUNTRY_IR", "COUNTRY_IQ", "COUNTRY_KP", "COUNTRY_XK", "COUNTRY_LY", "COUNTRY_MK", "COUNTRY_SO", "COUNTRY_SD", "COUNTRY_SY", "COUNTRY_ZW", "COUNTRY_CD", "COUNTRY_LB", "COUNTRY_NI", "COUNTRY_RU", "COUNTRY_SS", "COUNTRY_VE", "COUNTRY_YE" ], "tls_fingerprint_classes": [], "tls_fingerprint_values": [], "default_action_allow": {} }, "simple_rules": [] } } And our second policy JSON puts us over the limit for the article, but all JSON from these configs are in the attached file. Origin Pools Origin Pools are where we send traffic to, so if you are familiar with BIG-IP its just the Pool, and if you are familiar with NGINX its our Upstream. All of the settings and nerd knobs that are part of origin pools are out of scope of this article, so we are just going to point our origin at a single public IP and move on. To create an Origin Pool, Expand the Manage Block, hover over Load Balancers, click Origin Pools, and then Add Origin Pool. Give the Origin Pool a Name under Metadata. Then under Origin Servers click Add Item so we can add an upstream server. For this example I am going to use a Public DNS Name of Origin Server, but you should use whichever applies best to your situation. Click Add Item once done, which will return us to the Origin Pool Config. Make sure to select the correct port, and any TLS settings for your environment. Click Save and Exit. Load Balancer / Listener Now that we have somewhere to send traffic, we need a way to receive traffic and assign security policies. We will be staying within scope for this use-case as well and not highlighting all of the details within the load balancer configuration. To create a Load Balancer, Expand the Manage Block, hover over Load Balancers, click HTTP Load Balancers, and then Add HTTP load balancer. Set a Name under Metadata. Under Basic Configuration, Domains, add a domain for the application. If you have delegated a DNS zone to the platform, we can automate DNS (and make certificate management super easy, but not required). Under Default Origin Servers, click Add Item, and in the Origin Pool drop down, select the pool that was created previously, then click Add Item. For VIP configuration we will leave as Advertise on Internet. You will notice under Security Configuration, Service Policies are already set to Apply Namespace Service Policies. Since I have a few policies in my namespace already, and I want to demonstrate OFAC policies, I am going to change this to Apply Specified Service Policies, and under Apply Specified Service Policies click Configure and select the previously created policy, then click Apply. From here click Save and Exit. Testing Using a VPN we can make sure that our policy is up and running. Since we did not configure a custom response page of any sort we should just get a 403 - Forbidden page. While users accessing from non OFAC countries will be able to access the application. Reporting We should be able to access the security events now as well, Expand Virtual Hosts, HTTP Load Balancers, and then over the load balancer we created earlier a hyperlink for Security Monitoring will show up, click it. We can see in the dashboard a L7 security event, and if we select Security Events, we will see that our VPN based request was flagged (l7_policy_sec_event, Rule to match CountryList). If its not totally legible, I VPN'd to Belarus and tried to access the page. Hint: Being able to use the JSON to copy policies is really great, I have used this in action with several customers to show how quickly we can backup and copy policies between environments in a few seconds. Thats it, now your web application is blocking traffic from OFAC sanctioned countries, and anyone else you want to keep out.7.4KViews9likes3Comments