Mapping Qualys PC Controls to CIS Level 1: A Practitioner's Guide
If you have spent time working with Qualys Policy Compliance (PC), you know that the platform ships with pre-built policies mapped to CIS Benchmarks. On the surface, this looks like a complete solution — connect Qualys to your assets, run the CIS policy, and get your compliance posture. In practice, the reality is more nuanced. Built-in controls do not always match the way your environment is configured, certain checks target deprecated directives that no longer exist in modern software versions, and some compliance requirements can only be validated through custom logic that the standard policy does not cover. This post covers how the mapping actually works, where the gaps appear, and how to fill them using User Defined Controls (UDCs).
How Qualys PC maps to CIS
Qualys ships pre-built policies for CIS Level 1 and Level 2 across major platforms — RHEL, Ubuntu, Windows Server, AIX, and others. Each control in the policy maps to a specific CIS recommendation number, which you can view alongside the technology check and remediation guidance in the Qualys interface. The controls are grouped into policy sections that mirror the CIS Benchmark structure — filesystem configuration, services, network parameters, logging and auditing, SSH server configuration, and so on. The Qualys control tests a specific configuration state and reports Pass, Fail, or Error for each asset it scans.
Where the gaps appear — a field reference
Gap type | Example | Recommended approach |
Check exists but logic doesn't match your env | CIS recommends AUTHPRIV logging to /var/log/secure, but your org uses auth.log | UDC with regex tuned to your specific config |
Check for deprecated directive | SSH RhostsRSAAuthentication — removed in OpenSSH 7.4 | Suppress the control; document exception with version evidence |
Multi-value configuration | AuthorizedKeysFile with non-default or multiple paths | UDC with ERE regex; avoid negative lookaheads (not supported) |
Script-based check needed | Home directory ownership across all local users — non-static paths | Script-based UDC using stat -c "%U" on Linux, istat on AIX |
Platform-specific behaviour | AIX bcastping=1 is the compliant state (opposite of Linux) | Separate UDC scoped to AIX asset group only |
Control uses wrong data collection | sshd_config file parse misses effective config from includes | Use sshd -T for effective running config instead |
Understanding Qualys regex types — BRE vs ERE vs PCRE
One of the most common sources of UDC failures is using the wrong regex syntax for the context. Qualys Policy Compliance uses different regex engines depending on where the regex is applied. Policy-level regex (the check that evaluates collected data against a pass/fail condition) uses BRE (Basic Regular Expression) syntax. Control-level regex (used for data collection, such as extracting values from a config file) uses ERE (Extended Regular Expression) syntax. Neither supports PCRE features like negative lookaheads or non-capturing groups. Understanding this distinction before writing UDC regex saves significant troubleshooting time.
Regex context | Engine | What works | What does not work |
Policy regex (pass/fail evaluation) | BRE | ^, \(, ., *, [[:space:]], \| | \s, \d, lookaheads, + (use \{1,\}) |
Control regex (data collection) | ERE | ^, \), +, ?, |, [[:space:]] | \s, \d, negative lookaheads (?!...) |
Script-based UDC | Shell/Python | Full language capability | N/A — use scripting for complex logic |
Common regex mistakes and fixes
Mistake | Effect | Fix |
Using \s+ in policy regex | No match — BRE does not support \s shorthand | Use [[:space:]]+ instead |
No leading whitespace handling | Misses config lines with spaces before the directive | Add ^[[:space:]]* at the start of the pattern |
Negative lookahead in ERE | Qualys ERE does not support (?!...) syntax | Rewrite as a positive match of the acceptable value set |
Cardinality set to ALL when one match is sufficient | Control fails if any non-matching line exists alongside a matching one | Set cardinality to AT LEAST ONE |
Regex anchored too strictly | Misses valid config variants (e.g. authpriv.* vs authpriv.info) | Use .* or specific alternation to cover valid variants |
Building a UDC — the process step by step
Start by reading the actual CIS control requirement — not just the Qualys control title. The title is often a shortened version that loses important nuance. Understand whether the check needs to read a configuration file, run a command, or evaluate script output. For file-based checks, identify the exact file path, the relevant directive, and the acceptable value formats. Write your regex pattern and test it against actual file content from a representative host before deploying in Qualys. A regex that looks correct on paper behaves differently when Qualys applies BRE parsing — whitespace handling, line endings, and character class support all matter.
A useful validation step before deploying a UDC: run the equivalent grep command manually on the target host. If grep finds the expected match, your regex logic is sound. Then verify the Qualys UDC reaches the same conclusion — if it does not, the issue is regex syntax compatibility, not logic.
Handling platform differences — AIX example
AIX behaves differently from Linux in ways that matter for CIS compliance checks. The kernel parameter equivalent to Linux's net.ipv4.icmp_echo_ignore_broadcasts on AIX is bcastping, managed through the no (network options) command. The compliant state on AIX is bcastping=1 — which is the opposite of what you might expect if you are used to Linux conventions. The remediation command is /usr/sbin/no -p -o bcastping=1. Any UDC covering this control must be scoped exclusively to AIX asset groups — applying it to Linux would produce incorrect results.
When to suppress vs when to create a UDC
Not every gap between your environment and a Qualys built-in control requires a UDC. For controls that check deprecated directives — SSH options removed in newer OpenSSH versions, for example — the right approach is to suppress the control in the policy and document the exception with evidence of the OpenSSH version in use. Creating a UDC to force a pass for a directive that does not exist in the binary adds complexity without adding security value. Reserve UDCs for cases where a real security requirement exists but the built-in control does not correctly evaluate your environment's implementation of it.
Closing
Qualys Policy Compliance gives you a strong foundation for CIS benchmark assessment, but real-world environments always have edge cases — deprecated directives, non-default configurations, platform-specific behaviors, and multi-value settings that the built-in controls cannot handle cleanly. The practitioners who get the most value from Qualys PC are those who understand where the built-in controls end and where UDCs begin — and who know how to build UDCs that correctly express their actual hardening requirements in a way the platform can evaluate, track, and report on over time.


