{
  "title": "Practical Checklist: Implementing Least Functionality on Windows and Linux to Meet NIST SP 800-171 REV.2 / CMMC 2.0 Level 2 - Control - CM.L2-3.4.6",
  "date": "2026-04-12",
  "author": "Lakeridge Technologies",
  "featured_image": "/assets/images/blog/2026/4/practical-checklist-implementing-least-functionality-on-windows-and-linux-to-meet-nist-sp-800-171-rev2-cmmc-20-level-2-control-cml2-346.jpg",
  "content": {
    "full_html": "<p>Least functionality (NIST SP 800-171 / CMMC CM.L2-3.4.6) requires systems to provide only the services, protocols, ports, and applications necessary to perform assigned tasks; this post gives a practical, small-business–oriented checklist with concrete Windows and Linux steps, commands, and implementation notes to reduce attack surface and meet Compliance Framework expectations.</p>\n\n<h2>Understanding the control and practical objectives</h2>\n<p>Control CM.L2-3.4.6 is about minimizing what a system can do so adversaries have fewer ways to gain access, persist, or move laterally. For Compliance Framework implementation, your objectives are: inventory installed software and enabled services, remove or disable unnecessary functionality, enforce least privilege and application allowlists, and document exceptions through change control and risk acceptance. In a small business context (e.g., 10–50 endpoints, 2–5 servers), the focus should be pragmatic: make high-risk reductions first (open ports, remote services, unnecessary daemons) and automate enforcement where possible.</p>\n\n<h2>Practical Windows checklist (workstations & servers)</h2>\n<p>Start with inventory and baseline: use SCCM/Intune, PowerShell, or a simple script to list installed apps and running services (Get-Service, Get-WmiObject -Class Win32_Product). Audit listening ports with netstat or PowerShell: Get-NetTCPConnection | Where-Object { $_.State -eq 'Listen' } and correlate to services. Key actions: disable unneeded Windows services (e.g., Print Spooler on servers that do not print), remove SMBv1, remove optional features and roles not needed, and implement application allowlisting (AppLocker or Windows Defender Application Control).</p>\n\n<p>Concrete Windows commands and steps you can run today:\n- Disable Print Spooler (on non-printing servers): Stop-Service -Name Spooler -Force; Set-Service -Name Spooler -StartupType Disabled.\n- Remove SMBv1: Disable-WindowsOptionalFeature -Online -FeatureName SMB1Protocol; and verify: Get-SmbServerConfiguration | Select EnableSMB1Protocol.\n- List enabled services: Get-Service | Where-Object {$_.Status -eq 'Running'} | Sort-Object -Property Name.\n- Enforce application control using Group Policy: Computer Configuration → Windows Settings → Security Settings → Application Control Policies → AppLocker → Create rules (Default deny / allow-list approach). For smaller shops, use Microsoft Defender Application Control via Intune policies.\n- Use Windows features removal for roles you don't need: Get-WindowsFeature | Where Installed and then Uninstall-WindowsFeature Name.</p>\n\n<h2>Practical Linux checklist (servers & workstations)</h2>\n<p>On Linux start with discovery: list enabled services and listening sockets to identify unnecessary functionality. Useful commands:\n- List enabled services: systemctl list-unit-files --state=enabled\n- Show running services: systemctl --type=service --state=running\n- Show listening sockets: sudo ss -tuln or sudo lsof -i -P -n | grep LISTEN\n- List installed packages: Debian/Ubuntu: dpkg-query -l | less; RHEL/CentOS: rpm -qa | less\nTriage by risk: remove demo/unused packages (ftp, telnet, cups on headless servers, avahi/zeroconf on servers), disable unused services with systemctl disable --now, and remove packages with apt purge or yum remove.</p>\n\n<p>Concrete Linux commands and hardening examples:\n- Disable and stop a service: sudo systemctl disable --now avahi-daemon\n- Remove package: Debian/Ubuntu: sudo apt-get purge -y package-name && sudo apt-get autoremove -y; RHEL: sudo yum remove -y package-name\n- Harden SSH: edit /etc/ssh/sshd_config to set PermitRootLogin no, PasswordAuthentication no (if using keys), and restart: sudo systemctl restart sshd\n- Remove compilers from production hosts to reduce code-execution risk: sudo apt-get purge -y build-essential gcc g++\n- Firewall: enforce host firewall rules (ufw enable / firewall-cmd --permanent + --reload or nftables rules) to allow only required service ports.\n- Enforce Mandatory Access Controls (SELinux/AppArmor) in enforcing mode and apply minimal profiles for services.</p>\n\n<h2>Automation, documentation, and exception handling</h2>\n<p>Automate baseline enforcement with configuration management: Ansible playbooks, SCCM/Intune policies, or Puppet/Chef can remediate drift and scale least-functionality hardening. Example: an Ansible task that disables services listed in a variable, or a PowerShell DSC/GPO that enforces AppLocker rules. Maintain a configuration baseline and an approved-exception register that documents why a service/feature is enabled, compensating controls, owner, and review date. Use change control to test and approve each removal—especially on servers running custom apps.</p>\n\n<h2>Real-world small-business scenarios and tips</h2>\n<p>Scenario 1: A 3-server small firm (Domain Controller, File Server, Public Web VM). Actions: Domain Controller — remove interactive apps, disable USB mass storage via GPO if not needed, restrict admin tools to jump host; File Server — disable Print Spooler, remove SMBv1 and limit SMB to managed workstations; Web VM — remove GUI, disable SSH password auth and only allow key-based SFTP for deployments, restrict inbound ports to 80/443 only. Scenario 2: 15 laptops — deploy AppLocker or Defender Application Control, disable removable media where policy allows, restrict local admin rights, and use Intune to remove unapproved apps automatically. Tip: prioritize services that expose network ports and remote code execution (RPC, SMB, open web management interfaces) for immediate action.</p>\n\n<h2>Risks and compliance implications of not implementing least functionality</h2>\n<p>Failing to implement least functionality increases attack surface and the chance of compromise via unneeded services or software vulnerabilities. For Compliance Framework audits, absent least-functionality controls can lead to findings for CM.L2-3.4.6, remediation orders, and potential loss of contracts that require CMMC or NIST adherence. Operational risks include lateral movement after initial compromise, data exfiltration from unnecessary services, and difficulties meeting incident response objectives because noisy services obscure malicious activity.</p>\n\n<p>Summary: to meet CM.L2-3.4.6 in practice, perform a discovery and inventory, remove or disable unnecessary services and packages, enforce application allowlisting and least privilege, automate enforcement, and document exceptions; start with high-risk reductions (open ports, remote services, outdated protocols), validate changes in staging, and roll out using configuration management tools to maintain compliance across your Windows and Linux estate.</p>",
    "plain_text": "Least functionality (NIST SP 800-171 / CMMC CM.L2-3.4.6) requires systems to provide only the services, protocols, ports, and applications necessary to perform assigned tasks; this post gives a practical, small-business–oriented checklist with concrete Windows and Linux steps, commands, and implementation notes to reduce attack surface and meet Compliance Framework expectations.\n\nUnderstanding the control and practical objectives\nControl CM.L2-3.4.6 is about minimizing what a system can do so adversaries have fewer ways to gain access, persist, or move laterally. For Compliance Framework implementation, your objectives are: inventory installed software and enabled services, remove or disable unnecessary functionality, enforce least privilege and application allowlists, and document exceptions through change control and risk acceptance. In a small business context (e.g., 10–50 endpoints, 2–5 servers), the focus should be pragmatic: make high-risk reductions first (open ports, remote services, unnecessary daemons) and automate enforcement where possible.\n\nPractical Windows checklist (workstations & servers)\nStart with inventory and baseline: use SCCM/Intune, PowerShell, or a simple script to list installed apps and running services (Get-Service, Get-WmiObject -Class Win32_Product). Audit listening ports with netstat or PowerShell: Get-NetTCPConnection | Where-Object { $_.State -eq 'Listen' } and correlate to services. Key actions: disable unneeded Windows services (e.g., Print Spooler on servers that do not print), remove SMBv1, remove optional features and roles not needed, and implement application allowlisting (AppLocker or Windows Defender Application Control).\n\nConcrete Windows commands and steps you can run today:\n- Disable Print Spooler (on non-printing servers): Stop-Service -Name Spooler -Force; Set-Service -Name Spooler -StartupType Disabled.\n- Remove SMBv1: Disable-WindowsOptionalFeature -Online -FeatureName SMB1Protocol; and verify: Get-SmbServerConfiguration | Select EnableSMB1Protocol.\n- List enabled services: Get-Service | Where-Object {$_.Status -eq 'Running'} | Sort-Object -Property Name.\n- Enforce application control using Group Policy: Computer Configuration → Windows Settings → Security Settings → Application Control Policies → AppLocker → Create rules (Default deny / allow-list approach). For smaller shops, use Microsoft Defender Application Control via Intune policies.\n- Use Windows features removal for roles you don't need: Get-WindowsFeature | Where Installed and then Uninstall-WindowsFeature Name.\n\nPractical Linux checklist (servers & workstations)\nOn Linux start with discovery: list enabled services and listening sockets to identify unnecessary functionality. Useful commands:\n- List enabled services: systemctl list-unit-files --state=enabled\n- Show running services: systemctl --type=service --state=running\n- Show listening sockets: sudo ss -tuln or sudo lsof -i -P -n | grep LISTEN\n- List installed packages: Debian/Ubuntu: dpkg-query -l | less; RHEL/CentOS: rpm -qa | less\nTriage by risk: remove demo/unused packages (ftp, telnet, cups on headless servers, avahi/zeroconf on servers), disable unused services with systemctl disable --now, and remove packages with apt purge or yum remove.\n\nConcrete Linux commands and hardening examples:\n- Disable and stop a service: sudo systemctl disable --now avahi-daemon\n- Remove package: Debian/Ubuntu: sudo apt-get purge -y package-name && sudo apt-get autoremove -y; RHEL: sudo yum remove -y package-name\n- Harden SSH: edit /etc/ssh/sshd_config to set PermitRootLogin no, PasswordAuthentication no (if using keys), and restart: sudo systemctl restart sshd\n- Remove compilers from production hosts to reduce code-execution risk: sudo apt-get purge -y build-essential gcc g++\n- Firewall: enforce host firewall rules (ufw enable / firewall-cmd --permanent + --reload or nftables rules) to allow only required service ports.\n- Enforce Mandatory Access Controls (SELinux/AppArmor) in enforcing mode and apply minimal profiles for services.\n\nAutomation, documentation, and exception handling\nAutomate baseline enforcement with configuration management: Ansible playbooks, SCCM/Intune policies, or Puppet/Chef can remediate drift and scale least-functionality hardening. Example: an Ansible task that disables services listed in a variable, or a PowerShell DSC/GPO that enforces AppLocker rules. Maintain a configuration baseline and an approved-exception register that documents why a service/feature is enabled, compensating controls, owner, and review date. Use change control to test and approve each removal—especially on servers running custom apps.\n\nReal-world small-business scenarios and tips\nScenario 1: A 3-server small firm (Domain Controller, File Server, Public Web VM). Actions: Domain Controller — remove interactive apps, disable USB mass storage via GPO if not needed, restrict admin tools to jump host; File Server — disable Print Spooler, remove SMBv1 and limit SMB to managed workstations; Web VM — remove GUI, disable SSH password auth and only allow key-based SFTP for deployments, restrict inbound ports to 80/443 only. Scenario 2: 15 laptops — deploy AppLocker or Defender Application Control, disable removable media where policy allows, restrict local admin rights, and use Intune to remove unapproved apps automatically. Tip: prioritize services that expose network ports and remote code execution (RPC, SMB, open web management interfaces) for immediate action.\n\nRisks and compliance implications of not implementing least functionality\nFailing to implement least functionality increases attack surface and the chance of compromise via unneeded services or software vulnerabilities. For Compliance Framework audits, absent least-functionality controls can lead to findings for CM.L2-3.4.6, remediation orders, and potential loss of contracts that require CMMC or NIST adherence. Operational risks include lateral movement after initial compromise, data exfiltration from unnecessary services, and difficulties meeting incident response objectives because noisy services obscure malicious activity.\n\nSummary: to meet CM.L2-3.4.6 in practice, perform a discovery and inventory, remove or disable unnecessary services and packages, enforce application allowlisting and least privilege, automate enforcement, and document exceptions; start with high-risk reductions (open ports, remote services, outdated protocols), validate changes in staging, and roll out using configuration management tools to maintain compliance across your Windows and Linux estate."
  },
  "metadata": {
    "description": "A one-page, practical checklist for applying least functionality on Windows and Linux systems to satisfy NIST SP 800-171 Rev.2 / CMMC 2.0 Level 2 control CM.L2-3.4.6.",
    "permalink": "/practical-checklist-implementing-least-functionality-on-windows-and-linux-to-meet-nist-sp-800-171-rev2-cmmc-20-level-2-control-cml2-346.json",
    "categories": [],
    "tags": []
  }
}