NIST Cybersecurity Framework Implementation

The NIST Cybersecurity Framework (CSF) organizes security controls into five core functions—Identify, Protect, Detect, Respond, and Recover—providing a structured approach to managing cybersecurity risk on Linux infrastructure. This guide maps practical Linux controls to each NIST CSF function, covering risk assessment, security monitoring, access management, and incident response planning.

Prerequisites

  • Linux server (Ubuntu 20.04+ or CentOS/Rocky 8+) with root access
  • Basic familiarity with the NIST CSF document (available free at nist.gov)
  • Tools: auditd, fail2ban, rsyslog, and a backup solution
  • Optional: a SIEM or centralized logging platform

Identify: Asset Inventory and Risk Assessment

The Identify function establishes the foundation. You must know what you have before you can protect it.

# Generate a hardware and software asset inventory
sudo lshw -short > /var/log/nist/hardware-inventory.txt

# Installed software
dpkg -l > /var/log/nist/software-inventory.txt 2>/dev/null || \
  rpm -qa > /var/log/nist/software-inventory.txt

# Network services (what is exposed)
sudo ss -tlnp > /var/log/nist/network-services.txt

# Running processes
ps auxf > /var/log/nist/running-processes.txt

Scan the network to identify all hosts in your environment:

sudo apt install nmap   # Ubuntu
sudo dnf install nmap   # CentOS/Rocky

# Identify function: map all active hosts
sudo nmap -sn 192.168.1.0/24 -oN /var/log/nist/network-hosts.txt

# Identify open ports on this host
sudo nmap -sV localhost -oN /var/log/nist/host-ports.txt

Document data flows and classify data sensitivity:

# Find files accessible to all users (potential data exposure)
sudo find / -type f -perm -o+r -not -path "/proc/*" -not -path "/sys/*" \
  2>/dev/null | grep -E "\.(conf|key|pem|env|sql)" > /var/log/nist/exposed-files.txt

# Identify SUID/SGID binaries (privilege escalation risk)
sudo find / -type f \( -perm -4000 -o -perm -2000 \) -not -path "/proc/*" \
  2>/dev/null > /var/log/nist/suid-files.txt

Protect: Access Control and Hardening

The Protect function covers the controls that limit exposure.

# NIST CSF PR.AC: Identity management and access control

# Disable unused accounts
sudo usermod -L unused-account

# Remove accounts with no login shell that aren't system accounts
awk -F: '$7 !~ /(nologin|false)/ && $3 >= 1000 {print $1}' /etc/passwd

# Enforce SSH hardening
sudo tee /etc/ssh/sshd_config.d/nist-hardening.conf << 'EOF'
PermitRootLogin no
PasswordAuthentication no
MaxAuthTries 3
LoginGraceTime 30
X11Forwarding no
AllowTcpForwarding no
ClientAliveInterval 300
ClientAliveCountMax 2
EOF
sudo systemctl reload sshd

Apply system hardening (NIST CSF PR.IP):

# Kernel hardening via sysctl
sudo tee /etc/sysctl.d/99-nist.conf << 'EOF'
# Network security
net.ipv4.ip_forward = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.tcp_syncookies = 1
net.ipv6.conf.all.accept_redirects = 0

# Kernel hardening
kernel.dmesg_restrict = 1
kernel.kptr_restrict = 2
kernel.randomize_va_space = 2
fs.protected_hardlinks = 1
fs.protected_symlinks = 1
EOF

sudo sysctl -p /etc/sysctl.d/99-nist.conf

Configure the firewall (PR.AC-5 – Network integrity):

# UFW (Ubuntu)
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh
sudo ufw allow 443/tcp
sudo ufw enable

# firewalld (CentOS/Rocky)
sudo firewall-cmd --set-default-zone=drop
sudo firewall-cmd --add-service=ssh --permanent
sudo firewall-cmd --add-service=https --permanent
sudo firewall-cmd --reload

Protect: Data Security and Encryption

# PR.DS: Data security controls

# Verify disk encryption
sudo cryptsetup status /dev/mapper/data-volume 2>/dev/null || echo "No LUKS volume found"

# Encrypt sensitive configuration files
sudo apt install gnupg   # Ubuntu

# Encrypt a file
gpg --symmetric --cipher-algo AES256 /etc/app/database.conf

# Check for world-writable files
sudo find / -type f -perm -0002 -not -path "/proc/*" -not -path "/sys/*" \
  2>/dev/null > /var/log/nist/world-writable.txt

# Fix permissions on sensitive directories
sudo chmod 700 /root
sudo chmod 750 /etc/sudoers.d
sudo chmod 640 /etc/shadow

Detect: Security Monitoring

The Detect function requires continuous monitoring to identify cybersecurity events.

# DE.CM: Continuous monitoring

# Install and configure fail2ban (brute-force detection)
sudo apt install fail2ban   # Ubuntu
sudo dnf install fail2ban   # CentOS/Rocky

sudo tee /etc/fail2ban/jail.d/nist.conf << 'EOF'
[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 5

[sshd]
enabled = true
port = ssh
maxretry = 3
bantime = 86400
EOF

sudo systemctl enable --now fail2ban

Set up intrusion detection with AIDE:

# Install AIDE (file integrity monitoring)
sudo apt install aide   # Ubuntu
sudo dnf install aide   # CentOS/Rocky

# Initialize the database
sudo aideinit   # Ubuntu
sudo aide --init   # CentOS/Rocky

# Move database into place
sudo mv /var/lib/aide/aide.db.new /var/lib/aide/aide.db

# Run a check
sudo aide --check 2>&1 | tee /var/log/nist/aide-check-$(date +%Y%m%d).txt

Configure auditd for NIST monitoring requirements:

sudo tee /etc/audit/rules.d/nist.rules << 'EOF'
# DE.AE: Anomalies and events detection

# Authentication events
-w /var/log/auth.log -p wa -k nist_auth
-w /etc/passwd -p wa -k nist_identity
-w /etc/sudoers -p wa -k nist_access

# System calls of interest
-a always,exit -F arch=b64 -S open -F exit=-EACCES -k nist_access_denied
-a always,exit -F arch=b64 -S open -F exit=-EPERM -k nist_access_denied

# Privileged command execution
-a always,exit -F arch=b64 -S execve -F euid=0 -k nist_privileged

# Network changes
-a always,exit -F arch=b64 -S sethostname -S setdomainname -k nist_network
EOF

sudo augenrules --load && sudo systemctl restart auditd

Respond: Incident Response

NIST CSF RS controls require a documented incident response plan.

# Create incident triage script
sudo tee /usr/local/bin/nist-incident-triage.sh << 'SCRIPT'
#!/bin/bash
# NIST CSF RS.RP - Incident Response Plan Execution
INCIDENT_ID="INC-$(date +%Y%m%d%H%M%S)"
EVIDENCE_DIR="/var/log/nist/incidents/$INCIDENT_ID"
mkdir -p "$EVIDENCE_DIR"

echo "=== NIST Incident Response Initiated ===" | tee "$EVIDENCE_DIR/triage.log"
echo "Incident ID: $INCIDENT_ID" | tee -a "$EVIDENCE_DIR/triage.log"
echo "Timestamp: $(date -u)" | tee -a "$EVIDENCE_DIR/triage.log"
echo "Hostname: $(hostname)" | tee -a "$EVIDENCE_DIR/triage.log"

# Collect evidence
who > "$EVIDENCE_DIR/active_sessions.txt"
netstat -antp > "$EVIDENCE_DIR/network.txt" 2>/dev/null
ps auxf > "$EVIDENCE_DIR/processes.txt"
sudo last -n 100 > "$EVIDENCE_DIR/recent_logins.txt"
sudo journalctl --since "2 hours ago" > "$EVIDENCE_DIR/recent_journal.txt"
sudo ausearch -ts "2 hours ago" > "$EVIDENCE_DIR/audit_log.txt" 2>/dev/null
sudo fail2ban-client status > "$EVIDENCE_DIR/fail2ban_status.txt" 2>/dev/null

echo "Evidence collected. Review: $EVIDENCE_DIR" | tee -a "$EVIDENCE_DIR/triage.log"
echo "Next: Escalate to security team and notify management per RS.CO controls"
SCRIPT

sudo chmod +x /usr/local/bin/nist-incident-triage.sh

Recover: Backup and Restoration

NIST CSF RC controls require recovery planning and tested restore procedures.

# RC.RP: Recovery planning

# Configure automated backups with restic
sudo apt install restic

# Set up backup repository
export RESTIC_REPOSITORY="sftp:backup@backup-server:/backups/$(hostname)"
export RESTIC_PASSWORD_FILE="/etc/restic/password"

restic init

# Backup script aligned with RC.RP-1
sudo tee /usr/local/bin/nist-backup.sh << 'SCRIPT'
#!/bin/bash
export RESTIC_REPOSITORY="sftp:backup@backup-server:/backups/$(hostname)"
export RESTIC_PASSWORD_FILE="/etc/restic/password"

# Perform backup
restic backup \
  /etc \
  /var/www \
  /var/data \
  --tag "nist-rc-backup" \
  --exclude "*.log" \
  --exclude "/var/data/temp"

# Verify backup integrity (RC.RP control)
restic check

# Keep 7 daily, 4 weekly, 12 monthly snapshots
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 12 --prune

echo "Backup completed at $(date)"
SCRIPT

sudo chmod +x /usr/local/bin/nist-backup.sh

# Schedule daily backups
(sudo crontab -l 2>/dev/null; echo "0 2 * * * /usr/local/bin/nist-backup.sh >> /var/log/nist/backup.log 2>&1") | sudo crontab -

Control Mapping Reference

NIST CSF FunctionControlLinux Implementation
Identify (ID.AM)Asset Managementlshw, nmap inventory
Protect (PR.AC)Access ControlSSH hardening, PAM, sudo
Protect (PR.DS)Data SecurityLUKS, file permissions
Protect (PR.IP)Protective Technologysysctl, firewall
Detect (DE.CM)Continuous Monitoringauditd, AIDE, fail2ban
Detect (DE.AE)Anomaly Detectionauditd rules, SIEM
Respond (RS.RP)Response PlanningIncident script
Recover (RC.RP)Recovery Planningrestic backups

Troubleshooting

AIDE check reports many false positives:

# After intentional changes, reinitialize the database
sudo aide --update
sudo mv /var/lib/aide/aide.db.new /var/lib/aide/aide.db
# Review the AIDE config to exclude volatile paths
sudo nano /etc/aide/aide.conf
# Add: !/var/log to exclude logs

fail2ban not banning IPs:

sudo fail2ban-client status sshd
sudo journalctl -u fail2ban -n 50
# Check that the log path matches your system
grep "logpath" /etc/fail2ban/jail.d/nist.conf

auditd filling disk:

# Limit audit log size
sudo nano /etc/audit/auditd.conf
# Set: max_log_file = 50  (MB)
# Set: max_log_file_action = ROTATE
# Set: num_logs = 10
sudo systemctl restart auditd

Conclusion

The NIST Cybersecurity Framework gives Linux administrators a structured way to organize and prioritize security controls across the five core functions. By implementing asset inventory, access hardening, continuous monitoring with auditd and AIDE, a documented incident response process, and tested backup procedures, you create a defensible security posture aligned with NIST guidelines. Revisit each function quarterly to assess gaps and update controls as your infrastructure evolves.