SSL Orchestrator Advanced Use Cases: DNS Sinkholing

Introduction

One's mind probably doesn't gravitate to DNS security when thinking about an SSL visibility solution, but as I've already demonstrated in the DNS-over-HTTPS Detection use case, modern DNS architectures do have an interesting integration story. Now to be clear, we're not talking about DNS security in the sense of securing the DNS infrastructure, but rather, the DNS techniques used in the detection and mitigation of malware threats. Do a search on "DNS malware security", and you'll get pages upon pages of vendor solutions. But basically, it goes like this: A DNS malware security solution detects anomalous behavior, maybe some command-and-control (C&C) activity coming from an internal client, and when that client then makes a DNS request for a suspected C&C site, the DNS resolver instead returns one of two response options:

  • A DNS blackhole response: The resolver essentially sends an NXDOMAIN response. A DNS blackhole is diverting to nothing. In many cases the client request just dies there, as if the remote site just doesn't exist. But this is not a guarantee. In fact, in some modern browsers, if one DNS resource doesn't work, it'll just try another, potentially even switching to DNS-over-HTTPS (DoH) or DNS-over-TLS (DoT) to get a response.
  • A DNS sinkhole response: The resolver sends back an IP address that points to a local blocking server. A DNS sinkhole is diverting to something. This one is interesting primarily because it doesn't give the client an opportunity to try another resolver. The sinkhole destination is then able to respond to the client's request, so instead of just dying, the user might get a "we're watching you..." page instead.

In any case, this article focuses on the sinkhole technique. Expanding on this, the sinkhole comprises two components:

  • The DNS security solution itself: I'll be intentionally vague here because, frankly, any vendor DNS malware security solution will work, assuming it supports "sinkholing". And as you'll see below, this can even be done with static DNS solutions.
  • The sinkhole destination: This is where I'll focus the SSL Orchestrator integration. Under other circumstances, a client for example trying to access https://www.some-malicious-site.com, would get a DNS sinkhole response pointing to an internal blocking server. The client then initiates a TLS handshake to this server (believing it's the real site), and would get a certificate error because the server certificate on that blocking server doesn't match the Internet hostname requested by the client.

Hopefully you can see now where SSL Orchestrator fits into the sinkhole destination use case. We'll use SSL Orchestrator as the sinkhole destination enabling dynamic server certificate minting for whatever the client is asking for, and for generating the blocking content. It's worth noting, that the sinkhole action doesn't require any packets to flow to the malicious site. Without further ado, let's dig into how to set this up.

SSL Orchestrator Use Case: DNS Sinkholing

The SSL Orchestrator sinkhole solution will require two configurations:

  • A sinkhole internal virtual server that simply hosts the "blank" certificate that SSL Orchestrator will use to mint a trusted server certificate to the client.
  • An SSL Orchestrator outbound L3 topology modified to listen on the sinkhole destination IP, and inject the blocking response content.

You'll find additional information on these configurations in the accompanying Github repo

Note: Minimum BIG-IP requirement for this solution is version 16.x.

__________________________

Sinkhole internal virtual server

  • Optional Step: Easy-install: The following Bash script builds all of the necessary objects for the internal virtual server configuration.You can either use this to handle steps 1 to 4 automatically, or follow the steps below to create these manually. Step 5 must be done manually.

 

curl -s https://raw.githubusercontent.com/f5devcentral/sslo-script-tools/main/sslo-dns-sinkhole/create-sinkhole-internal-config.sh | bash

 

  • Step 1: Create the sinkhole certificate and key. The sinkhole certificate is specifically crafted to contain an empty Subject field. SSL Orchestrator is able to dynamically modify the subject-alternative-name field in the forged certificate, which is the only value of the two required by modern browsers.
openssl req -x509 -newkey rsa:2048 -sha256 -days 3650 -nodes \
-keyout "sinkhole.key" \
-out "sinkhole.crt" \
-subj "/" \
-config <(printf "[req]\n
distinguished_name=dn\n
x509_extensions=v3_req\n
[dn]\n\n
[v3_req]\n
keyUsage=critical,digitalSignature,keyEncipherment\n
extendedKeyUsage=serverAuth,clientAuth")
  • Step 2: Install the sinkhole certificate and key to the BIG-IP. Either manually install the new certificate and key to the BIG-IP, or use the following TMSH transaction:

    (echo create cli transaction
    echo install sys crypto key sinkhole-cert from-local-file "$(pwd)/sinkhole.key"
    echo install sys crypto cert sinkhole-cert from-local-file "$(pwd)/sinkhole.crt"
    echo submit cli transaction
    ) | tmsh
  • Step 3: Create a client SSL profile that uses the sinkhole certificate and key. Either manually create a client SSL profile and bind the sinkhole certificate and key, or use the following TMSH command:

    tmsh create ltm profile client-ssl sinkhole-clientssl cert sinkhole-cert key sinkhole-cert 
  • Step 4: Create the sinkhole "internal" virtual server. This virtual server simply hosts the client SSL profile and sinkhole certificate SSL Orchestrator will use to forge a blocking certificate.

    • Type: Standard
    • Source Address: 0.0.0.0/0
    • Destination Address/Mask: 0.0.0.0/0
    • Service Port: 9999 (does not really matter)
    • HTTP Profile (Client): http
    • SSL Profile (Client): the sinkhole client SSL profile
    • VLANs and Tunnel Traffic: select "Enabled on..." and leave the Selected box empty

    or use the following TMSH command to create this virtual server:

    tmsh create ltm virtual sinkhole-internal-vip destination 0.0.0.0:9999 profiles replace-all-with { tcp http sinkhole-clientssl } vlans-enabled​
  • Step 5: Create the sinkhole target iRule. This iRule will be placed on the SSL Orchestrator topology to steer traffic to the sinkhole internal virtual server. Notice the contents of the HTTP_REQUEST event. This is the HTML blocking page content. Edit this at will to meet your local requirements.

    when CLIENT_ACCEPTED {
        virtual "sinkhole-internal-vip"
    }
    when CLIENTSSL_CLIENTHELLO priority 800 {
        if {[SSL::extensions exists -type 0]} {
            binary scan [SSL::extensions -type 0] @9a* SNI
        }
    
        if { [info exists SNI] } {
            SSL::forward_proxy extension 2.5.29.17 "critical,DNS:${SNI}"
        }
    }
    when HTTP_REQUEST {
        HTTP::respond 403 content "<html><head></head><body><h1>Site Blocked!</h1></body></html>"
    }​

________________________

SSL Orchestrator modified outbound L3 topology

To create the SSL Orchestrator outbound L3 topology configuration, in the SSL Orchestrator UI, create a new Topology. Any section not mentioned below can be skipped.

  • Topology Properties

    • Protocol: TCP
    • SSL Orchestrator Topologies: select L3 Outbound
  • SSL Configuration

    • Click on "Show Advanced Setting"
    • CA Certificate Key Chain: Select the correct client-trusted internal signing CA certificate and key
    • Expire Certificate Response: Mask
    • Untrusted Certificate Response: Mask
  • Security Policy

    • Delete the Pinners_Rule. You won't need this in the sinkhole destination service
  • Interception Rule

    • Destination Address/Mask: Enter the client-facing IP address/mask of the sinkhole target
    • Ingress Network/VLANs: Select the client-facing VLAN
    • Protocol Settings/SSL Configurations: Ensure the previously created SSL configuration is selected

Ignore all other settings and Deploy. Once deployed, navigate to the Interception Rules tab and edit the new topology interception rule.

  • Resources/iRules: Add the sinkhole-target-rule iRule

Ignore all other settings and Deploy.

Testing

As I alluded earlier, anything that supports sending an alternate "sinkhole" IP in a DNS response will do. The simplest way to test is to create a local /etc/hosts entry on a client, directing some Internet URL to your sinkhole destination IP. You should then be able to request the HTTPS and HTTP URL for that site in the client browser and get forwarded to the blocking content.

In an environment where DoH and DoT requests are allowed to reach external resolvers (ex. Cloudflare), you could also integrate this sinkhole solution with the SSL Orchestrator DNS-over-HTTPS Detection use case. The accompanying Githup repo includes an alternative version of the DoH detection iRule that supports injecting a sinkhole IP address.

And finally, presenting a static HTML blocking page is just one possible option here. We're talking about F5 BIG-IP and iRules here, so the possibilities are near limitless. For example, instead of sending back static HTML, you could issue a redirect. That redirect could target a more formal "splash" page, and you could even send request information with the redirect to make that splash page more dynamic. 

 

when HTTP_REQUEST {
  HTTP::redirect "https://splash.f5labs.com/?cats=gis-dns-block&client_ip=[IP::client_addr]&type=dns&url=[URI::encode [b64encode [HTTP::host]]"
}

 

Here I'm generating a redirect that includes the blocking reason (gis-dns-block), the client IP, the type (dns), and the URI/base64-encoded request URL.

Summary

With an iRule and just a few configured objects we have been able to implement a capability on top of SSL Orchestrator to provide a key function of a DNS malware security solution. This is just one of the many interesting benefits of SSL Orchestrator.

 

Updated Sep 19, 2023
Version 2.0

Was this article helpful?

No CommentsBe the first to comment