{
  "title": "How to Harden Linux and Windows Servers for NIST SP 800-171 REV.2 / CMMC 2.0 Level 2 - Control - CM.L2-3.4.7: Disable Unnecessary Daemons, Services, and Listening Ports",
  "date": "2026-04-11",
  "author": "Lakeridge Technologies",
  "featured_image": "/assets/images/blog/2026/4/how-to-harden-linux-and-windows-servers-for-nist-sp-800-171-rev2-cmmc-20-level-2-control-cml2-347-disable-unnecessary-daemons-services-and-listening-ports.jpg",
  "content": {
    "full_html": "<p>Control CM.L2-3.4.7 in the Compliance Framework requires organizations to disable unnecessary daemons, services, and listening ports to reduce attack surface and protect Controlled Unclassified Information (CUI); this post gives practical, auditable steps for Linux and Windows servers to meet NIST SP 800-171 Rev.2 / CMMC 2.0 Level 2 expectations, including commands, automation ideas, and small-business examples.</p>\n\n<h2>Implementation Overview</h2>\n<p>Start with a clear inventory and baseline: identify every server’s purpose, the services required for that purpose, and the expected open ports. For each host create a documented baseline (for example: Web server — httpd/nginx, port 80/443; File server — Samba/SMB, ports 445/139), then map installed daemons/services to that baseline. Use the baseline as the source of truth for change control: if a service must be added later, require a documented exception with risk acceptance and compensating controls (firewall rules, MFA, monitoring).</p>\n\n<h3>Linux: discovery and removal/disable steps</h3>\n<p>On Linux, discovery and remediation are straightforward with systemd, netstat/ss, and package managers. Commands to discover listening services: `ss -tuln` or `netstat -tulpn`. To map sockets to packages/processes: `lsof -i -P -n` and `ps -ef | grep <pid>`. List installed services and unit files: `systemctl list-unit-files --type=service` and running services `systemctl list-units --type=service --state=running`. To disable a service: `sudo systemctl disable --now <service>.service`. To prevent package reinstallations or dependencies from re-enabling services, remove unnecessary packages with `yum remove`, `apt-get purge`, or `dnf remove`. Example: a small business web host that no longer needs FTP should `systemctl disable --now vsftpd` and `yum remove vsftpd`, then verify ports with `ss -tuln`. Use firewalls (ufw, firewalld, iptables/nftables) to block unexpected ports: `ufw deny 21` or `firewall-cmd --permanent --remove-service=ftp && firewall-cmd --reload`. For servers using init or SysV, use `chkconfig <service> off` or update-rc.d on Debian systems.</p>\n\n<h3>Windows: discovery and remediation</h3>\n<p>On Windows, use PowerShell and built-in tools to enumerate and disable services and listening ports. Discover listening ports with `netstat -ano | findstr LISTEN` or PowerShell: `Get-NetTCPConnection -State Listen | Select-Object LocalAddress,LocalPort,OwningProcess`. Map PIDs to services: `Get-Process -Id <PID> -FileVersionInfo` and `tasklist /svc /fi \"PID eq <PID>\"`. List services: `Get-WmiObject -Class Win32_Service | Select Name,StartMode,State,DisplayName`. To stop and disable a service: `Stop-Service -Name \"ServiceName\"; Set-Service -Name \"ServiceName\" -StartupType Disabled` or use `sc config ServiceName start= disabled`. For automated baselines, deploy Group Policy Preferences or an SCCM configuration baseline to enforce StartupType Disabled for nonessential services. Use Windows Firewall or Defender Firewall to restrict listening ports (example: `New-NetFirewallRule -DisplayName \"Block SMB\" -Direction Inbound -LocalPort 445 -Protocol TCP -Action Block`). For services like Print Spooler on servers that do not need printing, stop and disable `Spooler` and remove the role if installed.</p>\n\n<h2>Automation, Scanning, and Continuous Monitoring</h2>\n<p>Manual changes must be codified into automation and regular scans. Implement periodic network scans (Nmap, Nessus, OpenVAS) to detect unexpected open ports and compare results to baselines. On Linux, use configuration management (Ansible, Puppet, Chef) to enforce disabled services: an Ansible task can ensure `state: stopped` and `enabled: no`. On Windows, use Desired State Configuration (DSC) or SCCM to enforce service states. Enable audit logging: auditd rules on Linux to log socket openings or service starts, and Windows Event Logging (enable Service Control Manager auditing and use Sysmon to track process/connection events). Integrate findings with your SIEM to create alerts for deviations from the baseline (e.g., a previously disabled service becomes active). Schedule quarterly penetrations or vulnerability assessments and remediate findings through ticketing with evidence of changes for compliance auditors.</p>\n\n<h2>Real-World Small-Business Scenarios</h2>\n<p>Example 1: Small accounting firm runs a file server plus one public web server. The web host should run only nginx (80/443) — disable FTP, Telnet, database instances bound to 0.0.0.0, and any RPC or Samba services not required. Example command sequence: `ss -tuln` -> identify `:21` -> `systemctl disable --now vsftpd` -> `apt-get purge vsftpd` -> `ufw deny 21`. Example 2: A Windows-based project server used for collaboration doesn’t need print services or IIS: run `Get-WmiObject -Class Win32_Service | Where {$_.Name -eq \"Spooler\" -or $_.Name -eq \"W3SVC\"}` then stop/disable non-required ones, and deploy a Group Policy to prevent reinstallation. For small businesses without full IT teams, use managed configuration tools, documented checklists, and weekly vulnerability scan reports from a third-party managed service to stay compliant.</p>\n\n<h2>Compliance Tips and Best Practices</h2>\n<p>Document every baseline and exception to satisfy auditability: include the business reason, risk analysis, compensating controls, owner, and expiration for temporary exceptions. Tie service inventories to asset inventory and change control tickets. Adopt CIS Benchmarks or vendor hardening guides as the baseline and maintain versioned baselines in source control. Use role-based access control so only authorized admins can change service states, and require multi-factor authentication for privileged access. Retain logs for the period required by your compliance policy and demonstrate that monitoring alerts are acted on (include timestamps and ticket references) to prove ongoing compliance with CM.L2-3.4.7.</p>\n\n<h2>Risks of Not Disabling Unnecessary Services</h2>\n<p>Failing to disable unnecessary daemons and listening ports increases attack surface — attackers can exploit vulnerable services, gain initial access, move laterally, or exfiltrate CUI. Unnecessary services often run with elevated privileges or have poor patch coverage, creating easy attack vectors (e.g., exposed database ports or legacy SMB/NetBIOS services). From a compliance perspective, failing to document baselines and exceptions, or showing repeat deviations, can result in failed assessments, breach notification obligations, lost contracts, and financial penalties for inadequate CUI protection.</p>\n\n<p>Summary: To meet CM.L2-3.4.7, maintain a documented baseline of required services, use discovery tools (ss/netstat, lsof, Get-NetTCPConnection/netstat) to find listening ports, remove or disable unneeded daemons with systemctl/Set-Service/sc, enforce baselines with configuration management or Group Policy, and continuously scan and log to detect drift; document exceptions and link changes to change control for auditable compliance. These practical steps, when combined with monitoring and automation, will reduce risk and help demonstrate adherence to NIST SP 800-171 Rev.2 / CMMC 2.0 Level 2 requirements.</p>",
    "plain_text": "Control CM.L2-3.4.7 in the Compliance Framework requires organizations to disable unnecessary daemons, services, and listening ports to reduce attack surface and protect Controlled Unclassified Information (CUI); this post gives practical, auditable steps for Linux and Windows servers to meet NIST SP 800-171 Rev.2 / CMMC 2.0 Level 2 expectations, including commands, automation ideas, and small-business examples.\n\nImplementation Overview\nStart with a clear inventory and baseline: identify every server’s purpose, the services required for that purpose, and the expected open ports. For each host create a documented baseline (for example: Web server — httpd/nginx, port 80/443; File server — Samba/SMB, ports 445/139), then map installed daemons/services to that baseline. Use the baseline as the source of truth for change control: if a service must be added later, require a documented exception with risk acceptance and compensating controls (firewall rules, MFA, monitoring).\n\nLinux: discovery and removal/disable steps\nOn Linux, discovery and remediation are straightforward with systemd, netstat/ss, and package managers. Commands to discover listening services: `ss -tuln` or `netstat -tulpn`. To map sockets to packages/processes: `lsof -i -P -n` and `ps -ef | grep `. List installed services and unit files: `systemctl list-unit-files --type=service` and running services `systemctl list-units --type=service --state=running`. To disable a service: `sudo systemctl disable --now .service`. To prevent package reinstallations or dependencies from re-enabling services, remove unnecessary packages with `yum remove`, `apt-get purge`, or `dnf remove`. Example: a small business web host that no longer needs FTP should `systemctl disable --now vsftpd` and `yum remove vsftpd`, then verify ports with `ss -tuln`. Use firewalls (ufw, firewalld, iptables/nftables) to block unexpected ports: `ufw deny 21` or `firewall-cmd --permanent --remove-service=ftp && firewall-cmd --reload`. For servers using init or SysV, use `chkconfig  off` or update-rc.d on Debian systems.\n\nWindows: discovery and remediation\nOn Windows, use PowerShell and built-in tools to enumerate and disable services and listening ports. Discover listening ports with `netstat -ano | findstr LISTEN` or PowerShell: `Get-NetTCPConnection -State Listen | Select-Object LocalAddress,LocalPort,OwningProcess`. Map PIDs to services: `Get-Process -Id  -FileVersionInfo` and `tasklist /svc /fi \"PID eq \"`. List services: `Get-WmiObject -Class Win32_Service | Select Name,StartMode,State,DisplayName`. To stop and disable a service: `Stop-Service -Name \"ServiceName\"; Set-Service -Name \"ServiceName\" -StartupType Disabled` or use `sc config ServiceName start= disabled`. For automated baselines, deploy Group Policy Preferences or an SCCM configuration baseline to enforce StartupType Disabled for nonessential services. Use Windows Firewall or Defender Firewall to restrict listening ports (example: `New-NetFirewallRule -DisplayName \"Block SMB\" -Direction Inbound -LocalPort 445 -Protocol TCP -Action Block`). For services like Print Spooler on servers that do not need printing, stop and disable `Spooler` and remove the role if installed.\n\nAutomation, Scanning, and Continuous Monitoring\nManual changes must be codified into automation and regular scans. Implement periodic network scans (Nmap, Nessus, OpenVAS) to detect unexpected open ports and compare results to baselines. On Linux, use configuration management (Ansible, Puppet, Chef) to enforce disabled services: an Ansible task can ensure `state: stopped` and `enabled: no`. On Windows, use Desired State Configuration (DSC) or SCCM to enforce service states. Enable audit logging: auditd rules on Linux to log socket openings or service starts, and Windows Event Logging (enable Service Control Manager auditing and use Sysmon to track process/connection events). Integrate findings with your SIEM to create alerts for deviations from the baseline (e.g., a previously disabled service becomes active). Schedule quarterly penetrations or vulnerability assessments and remediate findings through ticketing with evidence of changes for compliance auditors.\n\nReal-World Small-Business Scenarios\nExample 1: Small accounting firm runs a file server plus one public web server. The web host should run only nginx (80/443) — disable FTP, Telnet, database instances bound to 0.0.0.0, and any RPC or Samba services not required. Example command sequence: `ss -tuln` -> identify `:21` -> `systemctl disable --now vsftpd` -> `apt-get purge vsftpd` -> `ufw deny 21`. Example 2: A Windows-based project server used for collaboration doesn’t need print services or IIS: run `Get-WmiObject -Class Win32_Service | Where {$_.Name -eq \"Spooler\" -or $_.Name -eq \"W3SVC\"}` then stop/disable non-required ones, and deploy a Group Policy to prevent reinstallation. For small businesses without full IT teams, use managed configuration tools, documented checklists, and weekly vulnerability scan reports from a third-party managed service to stay compliant.\n\nCompliance Tips and Best Practices\nDocument every baseline and exception to satisfy auditability: include the business reason, risk analysis, compensating controls, owner, and expiration for temporary exceptions. Tie service inventories to asset inventory and change control tickets. Adopt CIS Benchmarks or vendor hardening guides as the baseline and maintain versioned baselines in source control. Use role-based access control so only authorized admins can change service states, and require multi-factor authentication for privileged access. Retain logs for the period required by your compliance policy and demonstrate that monitoring alerts are acted on (include timestamps and ticket references) to prove ongoing compliance with CM.L2-3.4.7.\n\nRisks of Not Disabling Unnecessary Services\nFailing to disable unnecessary daemons and listening ports increases attack surface — attackers can exploit vulnerable services, gain initial access, move laterally, or exfiltrate CUI. Unnecessary services often run with elevated privileges or have poor patch coverage, creating easy attack vectors (e.g., exposed database ports or legacy SMB/NetBIOS services). From a compliance perspective, failing to document baselines and exceptions, or showing repeat deviations, can result in failed assessments, breach notification obligations, lost contracts, and financial penalties for inadequate CUI protection.\n\nSummary: To meet CM.L2-3.4.7, maintain a documented baseline of required services, use discovery tools (ss/netstat, lsof, Get-NetTCPConnection/netstat) to find listening ports, remove or disable unneeded daemons with systemctl/Set-Service/sc, enforce baselines with configuration management or Group Policy, and continuously scan and log to detect drift; document exceptions and link changes to change control for auditable compliance. These practical steps, when combined with monitoring and automation, will reduce risk and help demonstrate adherence to NIST SP 800-171 Rev.2 / CMMC 2.0 Level 2 requirements."
  },
  "metadata": {
    "description": "Step-by-step guidance for identifying and disabling unnecessary daemons, services, and listening ports to meet NIST SP 800-171 Rev.2 / CMMC 2.0 Level 2 Control CM.L2-3.4.7 with practical Linux and Windows commands, automation, and small-business scenarios.",
    "permalink": "/how-to-harden-linux-and-windows-servers-for-nist-sp-800-171-rev2-cmmc-20-level-2-control-cml2-347-disable-unnecessary-daemons-services-and-listening-ports.json",
    "categories": [],
    "tags": []
  }
}