Skip to Content
Network Devices

Secure Cisco ACI with cnspec

Scan a Cisco ACI fabric through its APIC controller cluster against security and compliance best practices with cnspec.

Scan your Cisco Application Centric Infrastructure (ACI) fabric to find security risks before they become incidents. cnspec connects to the Cisco Application Policy Infrastructure Controller (APIC) cluster through the APIC REST API and evaluates the controllers, the fabric switches, fabric-wide settings, certificates, AAA with its local users, roles, security domains, and RADIUS, TACACS+, and LDAP servers, management access over HTTPS, HTTP, SSH, and Telnet, and the faults the fabric reports.

Cisco APIC is one of the network devices cnspec can assess. For the full list of supported devices, see the network device scanning overview. New to cnspec? Start with the quickstart.

The Cisco APIC resources are experimental. Field names and behavior can change in a future cnspec release.

What cnspec scans

cnspec connects to one controller and reads the configuration of the whole APIC cluster and the ACI fabric it manages. The scan produces one asset for the fabric, named after its fabric domain, with the platform cisco-apic. The asset reports the APIC software version in Cisco's notation, such as 6.0(5h), which is the form Cisco security advisories use.

The fabric's leaf and spine switches appear as cisco.apic.fabricNode resources you can query, but cnspec doesn't create a separate asset for each switch. To assess a switch's own configuration, scan it directly with the Cisco network devices provider.

The scan doesn't cover tenants, application profiles, endpoint groups, contracts, pod policies, or fabric access policies.

Prerequisites

To scan a Cisco ACI fabric with cnspec, you must have:

  • cnspec installed on your workstation
  • Network access to the APIC REST API (default port 443) on any controller in the cluster
  • An APIC account with the read-all role in the all security domain

Give cnspec access to your fabric

cnspec reads from the APIC and never changes its configuration. It removes secret values as soon as it receives them, so user passwords, one-time password seeds, RADIUS, TACACS+, and LDAP keys, key ring private keys, and other secrets never reach a check or a scan report. SNMP community names are also redacted because the name is the community string.

Create a read-only account

Create a dedicated local account with the read-all role in the all security domain. From the APIC CLI, run:

apic1# configure
apic1(config)# username mondoo
apic1(config-username)# domain all
apic1(config-username-domain)# role read-all privilege read

An account in a narrower security domain can't see the objects outside that domain. If the account isn't allowed to read an object, cnspec reports an access denied error for it. It never treats the object as empty, so a check can't mistake missing evidence for an unconfigured feature.

Choose an authentication method

cnspec supports two ways to authenticate to the APIC:

  • Password: cnspec logs in once per scan, refreshes the session token as needed, and logs out when the scan ends, including when it fails.
  • Certificate signature: cnspec signs every request with the private key of an X.509 certificate attached to the user. No session is opened, so there is no token to refresh and no login rate limit. We recommend this method for scheduled, unattended scans.

To set up certificate signature authentication, create a key pair and a self-signed certificate:

openssl req -new -newkey rsa:2048 -days 365 -nodes -x509 -keyout mondoo.key -out mondoo.crt -subj '/CN=mondoo'

Then, in the APIC GUI, go to Admin > AAA > Users, open the mondoo user, and add the contents of mondoo.crt as a user certificate. The name you give the certificate is the value of the --certificate-name option. Keep mondoo.key on the machine that runs cnspec.

Test your connection

Before running a full scan, verify that cnspec can connect by opening a cnspec shell. For APIC_HOST, substitute the hostname or IP address of any controller in the cluster:

cnspec shell apic --hostname APIC_HOST --username mondoo --ask-pass

To authenticate with a certificate instead of a password:

cnspec shell apic --hostname APIC_HOST --username mondoo --certificate-name mondoo -i ./mondoo.key

If the account authenticates against a remote AAA server such as LDAP, RADIUS, or TACACS+, pass the APIC login domain:

cnspec shell apic --hostname APIC_HOST --username mondoo --login-domain LOGIN_DOMAIN --ask-pass

Controllers ship with a self-signed certificate. To skip TLS certificate verification for a controller that still uses it, add --insecure.

If cnspec connects successfully and shows a prompt, you're ready to scan.

Connection options

OptionDescription
--hostnameHostname or IP address of any controller in the APIC cluster (required)
--portREST API port (default: 443)
--usernameUsername for authentication (default: admin)
--password, -pPassword for authentication
--ask-passPrompt for the password
--identity-file, -iRSA private key for certificate signature authentication (requires --certificate-name)
--certificate-nameName of the certificate attached to the user, for certificate signature authentication
--login-domainAPIC login domain of a user who authenticates against a remote AAA server
--insecure, -kSkip TLS certificate verification (for the factory self-signed certificate)

Scanning more than one ACI fabric? Use an inventory file to define every APIC cluster and its credentials in one place, then scan them all with a single cnspec scan --inventory-file command.

Scan a Cisco ACI fabric

To scan a fabric, use the cnspec scan command:

cnspec scan apic --hostname APIC_HOST --username mondoo --ask-pass

When the scan completes, cnspec prints a pass or fail result for each check and an overall risk score. To output results in other formats such as JSON, JUnit, or SARIF, read Report Results.

You can write your own policies to check your ACI fabrics against the controls that matter to your organization.

Example checks

You can interactively explore and test checks using the cnspec shell. To open a shell connected to your APIC cluster:

cnspec shell apic --hostname APIC_HOST --username mondoo --ask-pass

Below are some example queries and checks you can run from the shell.

List the controllers in the cluster

cnspec> cisco.apic.controllers { name version health }

Find fabric switches that aren't active

cnspec> cisco.apic.fabric.nodes.where(role != "controller" && fabricState != "active") { name serialNumber }

Ensure the password policy requires at least 12 characters

cnspec> cisco.apic.aaa.passwordPolicy { strengthCheckEnabled == true minimumLength >= 12 historyCount >= 5 }

Ensure account lockout is enabled

cnspec> cisco.apic.aaa.lockoutPolicy.enabled == true

Find enabled local users whose password never expires

cnspec> cisco.apic.aaa.users.where(enabled && passwordLifetimeDays == 0) { name }

Ensure LDAP servers use TLS with strict certificate validation

cnspec> cisco.apic.aaa.ldapServers.all(sslEnabled == true && sslValidationLevel == "strict")

Show the default authentication realm

cnspec> cisco.apic.aaa.defaultAuthentication { realm providerGroup.name fallbackCheck }

Ensure Telnet is disabled in every management access policy

cnspec> cisco.apic.management.accessPolicies.all(telnet == null || telnet.enabled == false)

Ensure HTTP is disabled or redirects to HTTPS

cnspec> cisco.apic.management.accessPolicies.all(httpServer.enabled == false || httpServer.redirectToHttps == true)

Ensure TLS 1.0 and 1.1 are disabled

cnspec> cisco.apic.management.accessPolicies.all(httpsServer.tlsVersions.none(_ == "TLSv1" || _ == "TLSv1.1"))

Ensure SSH doesn't offer SHA-1 key exchange

cnspec> cisco.apic.management.sshServer.kexAlgorithms.none(_ == /sha1/)

Ensure the web UI idle timeout is 15 minutes or less

cnspec> cisco.apic.management.session.uiIdleTimeoutSeconds <= 900

Ensure the HTTPS certificate doesn't expire in the next 30 days

cnspec> cisco.apic.management.httpsServer.certificate.certificate.notAfter > time.now + 30 * time.day

Review fabric-wide security settings

cnspec> cisco.apic.fabric.settings { enforceSubnetCheck coopStrictMode rogueEndpointControlEnabled mcpEnabled }

List unacknowledged critical faults

cnspec> cisco.apic.faults.where(severity == "critical" && acknowledged == false) { code description node.name }

Learn more

On this page