PCI-DSS Security Checklist for E-commerce: Complete Implementation Guide

Introduction

The Payment Card Industry Data Security Standard (PCI-DSS) is a comprehensive set of security requirements designed to protect cardholder data and ensure secure payment processing across the global payment card ecosystem. For e-commerce businesses and the Linux system administrators who support them, PCI-DSS compliance is not optional—it's a mandatory requirement enforced by payment card brands (Visa, Mastercard, American Express, Discover, JCB) that affects every organization that stores, processes, or transmits cardholder data.

This comprehensive technical guide provides Linux system administrators with practical, command-line driven approaches to implementing and maintaining PCI-DSS compliance on e-commerce infrastructure. Whether you're managing a small online store or a large-scale e-commerce platform, this guide covers the essential security controls, configuration procedures, and auditing commands necessary to meet PCI-DSS requirements.

Understanding PCI-DSS Scope and Applicability

PCI-DSS applies to any organization that accepts, transmits, or stores payment card data, regardless of size or transaction volume. The standard consists of 12 core requirements organized into 6 major goals:

  1. Build and Maintain a Secure Network and Systems
  2. Protect Cardholder Data
  3. Maintain a Vulnerability Management Program
  4. Implement Strong Access Control Measures
  5. Regularly Monitor and Test Networks
  6. Maintain an Information Security Policy

The consequences of non-compliance are severe: monthly fines ranging from $5,000 to $100,000, increased transaction fees, potential loss of ability to process credit cards, and significant reputational damage following a breach. According to the Verizon Data Breach Investigations Report, the average cost of a payment card data breach exceeds $3.86 million, making prevention through PCI-DSS compliance a critical business imperative.

PCI-DSS Validation Levels

Organizations are classified into four merchant levels based on annual transaction volume:

  • Level 1: Over 6 million transactions annually (requires annual on-site audit by QSA)
  • Level 2: 1-6 million transactions annually (requires annual Self-Assessment Questionnaire)
  • Level 3: 20,000-1 million e-commerce transactions annually (requires annual SAQ)
  • Level 4: Fewer than 20,000 e-commerce transactions or up to 1 million total transactions (requires annual SAQ)

Regardless of level, all merchants must comply with all 12 PCI-DSS requirements. The validation method differs, but the technical security controls remain the same.

Cardholder Data Environment (CDE)

A critical concept in PCI-DSS is the Cardholder Data Environment (CDE)—the people, processes, and technologies that store, process, or transmit cardholder data or sensitive authentication data. Properly defining and segmenting your CDE is essential for limiting PCI-DSS scope and reducing compliance complexity.

Cardholder Data (CHD) includes:

  • Primary Account Number (PAN) - the 16-digit card number
  • Cardholder Name
  • Expiration Date
  • Service Code

Sensitive Authentication Data (SAD) includes (must NEVER be stored post-authorization):

  • Full magnetic stripe data
  • CAV2/CVC2/CVV2/CID security codes
  • PIN/PIN Block

Why PCI-DSS Matters for Linux Administrators

As a Linux system administrator, you are responsible for implementing and maintaining the technical controls that protect cardholder data. This includes network segmentation, encryption, access controls, logging, vulnerability management, and incident response. Your configurations, scripts, and procedures directly impact your organization's PCI-DSS compliance status and, by extension, its ability to process credit card payments.

This guide provides you with the practical knowledge and command-line tools to implement PCI-DSS requirements effectively, pass audits, and maintain a secure e-commerce environment.

PCI-DSS Requirements Overview

The 12 PCI-DSS Requirements

Before diving into implementation, let's review all 12 requirements:

  1. Install and maintain a firewall configuration to protect cardholder data
  2. Do not use vendor-supplied defaults for system passwords and other security parameters
  3. Protect stored cardholder data
  4. Encrypt transmission of cardholder data across open, public networks
  5. Protect all systems against malware and regularly update anti-virus software
  6. Develop and maintain secure systems and applications
  7. Restrict access to cardholder data by business need-to-know
  8. Identify and authenticate access to system components
  9. Restrict physical access to cardholder data
  10. Track and monitor all access to network resources and cardholder data
  11. Regularly test security systems and processes
  12. Maintain a policy that addresses information security for all personnel

Each requirement contains multiple sub-requirements with specific testing procedures. We'll address the most technically relevant requirements for Linux system administrators.

Implementation Steps

Requirement 1: Install and Maintain Network Security Controls

Network security is the first line of defense in protecting cardholder data. PCI-DSS requires properly configured firewalls that restrict inbound and outbound traffic to only what's necessary for business operations.

1.1: Configure Firewall Rules

Install and Configure iptables/nftables:

# Check current firewall status
sudo iptables -L -n -v
sudo systemctl status iptables

# For nftables (newer systems)
sudo nft list ruleset
sudo systemctl status nftables

# Install iptables if not present
sudo apt-get install -y iptables iptables-persistent # Debian/Ubuntu
sudo yum install -y iptables-services # RHEL/CentOS

# Create PCI-DSS compliant firewall ruleset
cat > /etc/iptables/rules.v4 << 'EOF'
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]

# Allow loopback
-A INPUT -i lo -j ACCEPT

# Allow established connections
-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# Allow SSH (from specific management IPs only - adjust as needed)
-A INPUT -p tcp -s 192.168.1.0/24 --dport 22 -m conntrack --ctstate NEW -j ACCEPT

# Allow HTTPS for e-commerce traffic
-A INPUT -p tcp --dport 443 -m conntrack --ctstate NEW -j ACCEPT

# Allow HTTP (only if redirecting to HTTPS)
-A INPUT -p tcp --dport 80 -m conntrack --ctstate NEW -j ACCEPT

# ICMP (ping) - limited
-A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/s -j ACCEPT

# Drop everything else and log
-A INPUT -j LOG --log-prefix "iptables-dropped: " --log-level 4
-A INPUT -j DROP

# Output rules - restrict outbound to necessary services only
-A OUTPUT -j ACCEPT

COMMIT
EOF

# Apply firewall rules
sudo iptables-restore < /etc/iptables/rules.v4

# Make rules persistent across reboots
sudo netfilter-persistent save
sudo systemctl enable netfilter-persistent

# Verify rules
sudo iptables -L -n -v --line-numbers

Configure firewalld (RHEL/CentOS):

# Start and enable firewalld
sudo systemctl enable firewalld
sudo systemctl start firewalld

# Set default zone to drop
sudo firewall-cmd --set-default-zone=drop

# Create PCI-DSS zone for CDE
sudo firewall-cmd --permanent --new-zone=pci-cde
sudo firewall-cmd --permanent --zone=pci-cde --set-target=DROP

# Allow only necessary services
sudo firewall-cmd --permanent --zone=pci-cde --add-service=https
sudo firewall-cmd --permanent --zone=pci-cde --add-service=ssh
sudo firewall-cmd --permanent --zone=pci-cde --add-source=192.168.1.0/24

# Enable logging for denied packets
sudo firewall-cmd --permanent --zone=pci-cde --add-rich-rule='rule family="ipv4" log prefix="firewall-denied: " level="info" limit value="1/s"'

# Reload firewall
sudo firewall-cmd --reload

# Verify configuration
sudo firewall-cmd --list-all-zones
sudo firewall-cmd --zone=pci-cde --list-all

1.2: Network Segmentation

Network segmentation isolates the CDE from other networks, reducing PCI-DSS scope and limiting potential breach impact.

# Verify network interfaces and segmentation
ip addr show
ip route show

# Check for VLAN configuration (if using VLANs for segmentation)
cat /proc/net/vlan/config

# Configure network segmentation with iptables
# Example: Separate CDE (192.168.10.0/24) from corporate network (192.168.1.0/24)

sudo iptables -N CDE-FORWARD
sudo iptables -A FORWARD -s 192.168.10.0/24 -j CDE-FORWARD
sudo iptables -A FORWARD -d 192.168.10.0/24 -j CDE-FORWARD

# Allow only specific traffic from corporate to CDE (e.g., management)
sudo iptables -A CDE-FORWARD -s 192.168.1.100 -d 192.168.10.0/24 -p tcp --dport 22 -j ACCEPT

# Allow CDE to access specific external services (payment gateway)
sudo iptables -A CDE-FORWARD -s 192.168.10.0/24 -d 203.0.113.0/24 -p tcp --dport 443 -j ACCEPT

# Drop all other inter-network traffic
sudo iptables -A CDE-FORWARD -j LOG --log-prefix "CDE-segmentation-drop: "
sudo iptables -A CDE-FORWARD -j DROP

# Save rules
sudo netfilter-persistent save

1.3: Firewall Review and Documentation

PCI-DSS requires at least semi-annual firewall rule reviews:

# Create firewall review script
cat > /root/pci-scripts/firewall_review.sh << 'EOF'
#!/bin/bash
# PCI-DSS Firewall Configuration Review

REVIEW_FILE="/var/log/pci-audit/firewall_review_$(date +%Y%m%d).txt"
mkdir -p /var/log/pci-audit

exec > >(tee -a "$REVIEW_FILE")
exec 2>&1

echo "========================================"
echo "PCI-DSS FIREWALL CONFIGURATION REVIEW"
echo "Date: $(date)"
echo "Reviewer: $(whoami)"
echo "========================================"
echo ""

echo "=== Current Firewall Rules ==="
if command -v iptables &> /dev/null; then
    iptables -L -n -v --line-numbers
elif command -v firewall-cmd &> /dev/null; then
    firewall-cmd --list-all-zones
fi
echo ""

echo "=== Open Ports ==="
ss -tulpn | grep LISTEN
echo ""

echo "=== Firewall Logs (Last 100 Denied Connections) ==="
grep "iptables-dropped\|firewall-denied" /var/log/messages /var/log/syslog 2>/dev/null | tail -100
echo ""

echo "=== Network Interfaces ==="
ip addr show
echo ""

echo "=== Routing Table ==="
ip route show
echo ""

echo "=== Review Checklist ==="
echo "[ ] All rules documented with business justification?"
echo "[ ] Deny-all rule present as default?"
echo "[ ] Only necessary ports open?"
echo "[ ] SSH restricted to management IPs only?"
echo "[ ] Outbound traffic restricted to necessary destinations?"
echo "[ ] CDE properly segmented from other networks?"
echo "[ ] Firewall logs enabled and monitored?"
echo ""

echo "Review completed: $(date)"
echo "Report saved to: $REVIEW_FILE"

EOF

chmod +x /root/pci-scripts/firewall_review.sh

# Schedule semi-annual reviews
echo "0 9 1 1,7 * /root/pci-scripts/firewall_review.sh | mail -s 'Semi-Annual Firewall Review' [email protected]" | sudo crontab -

Requirement 2: Change Vendor-Supplied Defaults

Using default passwords and configurations is a primary attack vector. PCI-DSS requires changing all vendor defaults before deploying systems.

2.1: Change Default Passwords

# Audit for default/weak passwords (requires john or similar)
sudo apt-get install -y john # Debian/Ubuntu
sudo yum install -y john # RHEL/CentOS

# Extract password hashes for testing
sudo unshadow /etc/passwd /etc/shadow > /tmp/passwords.txt

# Test for weak passwords (this may take time)
john --wordlist=/usr/share/john/password.lst /tmp/passwords.txt

# Securely delete the test file
shred -vfz /tmp/passwords.txt

# Enforce strong password policies
sudo apt-get install -y libpam-pwquality # Debian/Ubuntu
sudo yum install -y libpwquality # RHEL/CentOS

# Configure password quality requirements
sudo tee /etc/security/pwquality.conf << 'EOF'
# PCI-DSS Password Requirements
minlen = 12
dcredit = -1  # At least 1 digit
ucredit = -1  # At least 1 uppercase
lcredit = -1  # At least 1 lowercase
ocredit = -1  # At least 1 special character
maxrepeat = 2
maxclassrepeat = 3
gecoscheck = 1
dictcheck = 1
usercheck = 1
enforcing = 1
EOF

# Configure PAM to use pwquality
sudo sed -i 's/pam_unix.so/pam_unix.so remember=4/' /etc/pam.d/common-password

2.2: Remove or Disable Unnecessary Services

# List all running services
systemctl list-units --type=service --state=running

# Identify and disable unnecessary services
# Example services to consider disabling in CDE:
UNNECESSARY_SERVICES="
cups
avahi-daemon
bluetooth
"

for service in $UNNECESSARY_SERVICES; do
    if systemctl is-active --quiet "$service"; then
        echo "Disabling $service"
        sudo systemctl stop "$service"
        sudo systemctl disable "$service"
    fi
done

# Remove unnecessary packages
sudo apt-get autoremove -y # Debian/Ubuntu
sudo yum autoremove -y # RHEL/CentOS

# Verify no unnecessary network services
sudo netstat -tulpn | grep LISTEN
sudo ss -tulpn | grep LISTEN

2.3: Configure Secure Defaults

# SSH Hardening for PCI-DSS
sudo tee /etc/ssh/sshd_config.d/pci-hardening.conf << 'EOF'
# PCI-DSS SSH Hardening

# Protocol and encryption
Protocol 2
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key

# Strong ciphers only
Ciphers [email protected],[email protected],aes256-ctr,aes192-ctr,aes128-ctr
MACs [email protected],[email protected],hmac-sha2-512,hmac-sha2-256
KexAlgorithms curve25519-sha256,[email protected],ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256

# Authentication
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
ChallengeResponseAuthentication no
UsePAM yes

# Session settings
ClientAliveInterval 300
ClientAliveCountMax 2
LoginGraceTime 60
MaxAuthTries 3
MaxSessions 2

# Access control
AllowUsers admin_user deploy_user
DenyUsers root

# Logging
LogLevel VERBOSE
SyslogFacility AUTH

# Other security settings
PermitEmptyPasswords no
PermitUserEnvironment no
X11Forwarding no
PrintMotd no
PrintLastLog yes
TCPKeepAlive yes
Compression no
AllowAgentForwarding no
AllowTcpForwarding no
GatewayPorts no
PermitTunnel no
EOF

# Restart SSH to apply changes
sudo systemctl restart sshd

# Verify SSH configuration
sudo sshd -T | grep -E "(ciphers|macs|kexalgorithms|permitrootlogin|passwordauthentication)"

2.4: Database Security Hardening

# MySQL/MariaDB security hardening
mysql -u root -p << 'EOF'
-- Remove anonymous users
DELETE FROM mysql.user WHERE User='';

-- Remove remote root access
DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1');

-- Remove test database
DROP DATABASE IF EXISTS test;
DELETE FROM mysql.db WHERE Db='test' OR Db='test\\_%';

-- Change default ports (optional but recommended)
-- Edit /etc/mysql/my.cnf: port = 3307

-- Disable LOAD DATA LOCAL INFILE
SET GLOBAL local_infile = 0;

-- Enable SSL for connections
-- Configure ssl-ca, ssl-cert, ssl-key in my.cnf

FLUSH PRIVILEGES;
EOF

# Secure MySQL configuration file
sudo tee -a /etc/mysql/mariadb.conf.d/50-server.cnf << 'EOF'

# PCI-DSS MySQL Security Settings
[mysqld]
# Bind to localhost only (unless replication required)
bind-address = 127.0.0.1

# Disable local infile
local-infile = 0

# Enable SSL/TLS
# ssl-ca = /etc/mysql/ssl/ca-cert.pem
# ssl-cert = /etc/mysql/ssl/server-cert.pem
# ssl-key = /etc/mysql/ssl/server-key.pem

# Logging for PCI compliance
log_error = /var/log/mysql/error.log
general_log = 1
general_log_file = /var/log/mysql/general.log
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow-query.log
long_query_time = 2

# Security settings
skip-show-database
skip-symbolic-links

EOF

sudo systemctl restart mysql

Requirement 3: Protect Stored Cardholder Data

This is arguably the most critical PCI-DSS requirement. PCI-DSS mandates strong encryption for stored cardholder data and prohibits storage of sensitive authentication data post-authorization.

3.1: Data Retention and Disposal

CRITICAL: Minimize cardholder data storage. Best practice is to not store it at all—use tokenization or point-to-point encryption instead.

# Create data inventory script for cardholder data
cat > /root/pci-scripts/cardholder_data_inventory.sh << 'EOF'
#!/bin/bash
# PCI-DSS Cardholder Data Inventory

REPORT_FILE="/var/log/pci-audit/chd_inventory_$(date +%Y%m%d).txt"
mkdir -p /var/log/pci-audit

exec > >(tee -a "$REPORT_FILE")

echo "========================================"
echo "CARDHOLDER DATA INVENTORY"
echo "Date: $(date)"
echo "========================================"
echo ""

# WARNING: Be extremely careful with these searches in production
# Consider running during maintenance windows

echo "=== Searching for PAN Patterns (Sample Check) ==="
# PAN regex pattern (basic - for demonstration)
PAN_PATTERN="[0-9]{4}[- ]?[0-9]{4}[- ]?[0-9]{4}[- ]?[0-9]{4}"

# Search logs (limit results)
echo "Checking log files for PAN exposure..."
grep -rE "$PAN_PATTERN" /var/log/*.log 2>/dev/null | wc -l
echo "WARNING: If any PANs found in logs, this is a PCI violation!"
echo ""

# Check database for cardholder data
echo "=== Database Cardholder Data Check ==="
mysql -u root -p -e "
SELECT
    TABLE_SCHEMA,
    TABLE_NAME,
    COLUMN_NAME
FROM
    INFORMATION_SCHEMA.COLUMNS
WHERE
    COLUMN_NAME REGEXP 'card|pan|cvv|track'
    AND TABLE_SCHEMA NOT IN ('information_schema', 'mysql', 'performance_schema', 'sys');
"
echo ""

echo "=== File System PAN Search (Limited) ==="
# Search for potential PAN in file names (very limited search)
find /var/www -type f -name "*card*" -o -name "*payment*" 2>/dev/null | head -20
echo ""

echo "Inventory completed: $(date)"
echo ""
echo "CRITICAL ACTIONS REQUIRED:"
echo "1. Verify all identified cardholder data storage is necessary"
echo "2. Ensure all stored PANs are encrypted"
echo "3. Confirm NO sensitive authentication data (CVV2, full track data) is stored"
echo "4. Implement data retention policy and purge unnecessary data"

EOF

chmod +x /root/pci-scripts/cardholder_data_inventory.sh

3.2: Encrypt Stored Cardholder Data

# If you MUST store cardholder data, use strong encryption

# Database-level encryption (MySQL/MariaDB)
mysql -u root -p << 'EOF'
-- Create encrypted table for cardholder data (example)
-- DO NOT use this structure without proper key management

CREATE TABLE IF NOT EXISTS payment_tokens (
    token_id INT AUTO_INCREMENT PRIMARY KEY,
    encrypted_pan VARBINARY(256),
    cardholder_name VARCHAR(255),
    expiration_date VARCHAR(7),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    INDEX idx_token (token_id)
) ENGINE=InnoDB;

-- Example encryption query (requires proper key management)
-- INSERT INTO payment_tokens (encrypted_pan, cardholder_name)
-- VALUES (AES_ENCRYPT('4111111111111111', 'encryption_key'), 'John Doe');

-- Example decryption query
-- SELECT token_id, AES_DECRYPT(encrypted_pan, 'encryption_key') as pan FROM payment_tokens;

EOF

# Application-level encryption script example
cat > /usr/local/bin/pan_encrypt << 'EOF'
#!/bin/bash
# PCI-DSS PAN Encryption Utility
# In production, use proper key management system (KMS)

if [ "$#" -ne 1 ]; then
    echo "Usage: $0 <pan>"
    exit 1
fi

PAN="$1"
KEY_FILE="/etc/pci/encryption.key"

# Validate PAN format (basic Luhn check should be added)
if [[ ! "$PAN" =~ ^[0-9]{13,19}$ ]]; then
    echo "Error: Invalid PAN format"
    exit 1
fi

# Encrypt PAN
echo -n "$PAN" | openssl enc -aes-256-cbc -salt -pbkdf2 -pass file:"$KEY_FILE" | base64

EOF

chmod +x /usr/local/bin/pan_encrypt
chmod 700 /usr/local/bin/pan_encrypt

3.3: Protect Encryption Keys

# Create secure key storage directory
sudo mkdir -p /etc/pci/keys
sudo chmod 700 /etc/pci/keys

# Generate encryption keys (example - use HSM in production)
sudo openssl rand -base64 32 > /etc/pci/keys/data_encryption.key
sudo chmod 400 /etc/pci/keys/data_encryption.key
sudo chown root:root /etc/pci/keys/data_encryption.key

# Key rotation script
cat > /root/pci-scripts/rotate_encryption_keys.sh << 'EOF'
#!/bin/bash
# PCI-DSS Encryption Key Rotation
# Run annually or as required by policy

KEY_DIR="/etc/pci/keys"
BACKUP_DIR="/secure/backups/keys"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)

# Backup current key
mkdir -p "$BACKUP_DIR"
cp "$KEY_DIR/data_encryption.key" "$BACKUP_DIR/data_encryption.key.$TIMESTAMP"

# Generate new key
openssl rand -base64 32 > "$KEY_DIR/data_encryption.key.new"
chmod 400 "$KEY_DIR/data_encryption.key.new"

echo "New encryption key generated: $KEY_DIR/data_encryption.key.new"
echo "MANUAL STEPS REQUIRED:"
echo "1. Re-encrypt all cardholder data with new key"
echo "2. Test decryption with new key"
echo "3. Replace old key: mv data_encryption.key.new data_encryption.key"
echo "4. Securely destroy old key backup after verification"

EOF

chmod +x /root/pci-scripts/rotate_encryption_keys.sh

3.4: Render PAN Unreadable (Masking)

# PAN masking function for display/logs
cat > /usr/local/bin/mask_pan << 'EOF'
#!/bin/bash
# Mask PAN for display (show only last 4 digits)

if [ "$#" -ne 1 ]; then
    echo "Usage: $0 <pan>"
    exit 1
fi

PAN="$1"

# Remove spaces and dashes
PAN_CLEAN="${PAN//[-  ]/}"

# Get length
PAN_LENGTH=${#PAN_CLEAN}

if [ "$PAN_LENGTH" -lt 13 ] || [ "$PAN_LENGTH" -gt 19 ]; then
    echo "Invalid PAN length"
    exit 1
fi

# Mask all but last 4
MASKED=$(echo "$PAN_CLEAN" | sed 's/.*\(....\)/************\1/')

echo "$MASKED"

EOF

chmod +x /usr/local/bin/mask_pan

# Example usage:
# mask_pan "4111-1111-1111-1111"
# Output: ************1111

Requirement 4: Encrypt Transmission of Cardholder Data

All cardholder data transmitted across public networks must be encrypted using strong cryptography.

4.1: Strong Cryptography for Transmission

# Install and configure TLS 1.2+ for web servers

# Apache TLS Configuration
sudo tee /etc/apache2/conf-available/pci-ssl.conf << 'EOF'
# PCI-DSS TLS Configuration for Apache

<IfModule mod_ssl.c>
    # Enable only TLS 1.2 and 1.3
    SSLProtocol -all +TLSv1.2 +TLSv1.3

    # Strong cipher suites only
    SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256
    SSLHonorCipherOrder on

    # Enable HSTS
    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"

    # Disable SSL compression
    SSLCompression off

    # Enable OCSP stapling
    SSLUseStapling on
    SSLStaplingCache "shmcb:logs/ssl_stapling(32768)"

    # Session tickets
    SSLSessionTickets off
</IfModule>
EOF

sudo a2enconf pci-ssl
sudo a2enmod ssl headers
sudo systemctl reload apache2

# Nginx TLS Configuration
sudo tee /etc/nginx/conf.d/pci-ssl.conf << 'EOF'
# PCI-DSS TLS Configuration for Nginx

# Enable only TLS 1.2 and 1.3
ssl_protocols TLSv1.2 TLSv1.3;

# Strong cipher suites
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256';
ssl_prefer_server_ciphers on;

# SSL session configuration
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_session_tickets off;

# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;

# Security headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;

# Disable SSL compression
ssl_compression off;

EOF

sudo nginx -t
sudo systemctl reload nginx

# Verify TLS configuration
openssl s_client -connect localhost:443 -tls1_2
openssl s_client -connect localhost:443 -tls1_3

# Test SSL configuration with external tool
# testssl.sh --fast https://yourdomain.com

4.2: SSL/TLS Certificate Management

# Install Let's Encrypt certificates
sudo apt-get install -y certbot python3-certbot-apache # Apache
sudo apt-get install -y certbot python3-certbot-nginx # Nginx

# Obtain certificate
sudo certbot --apache -d yourdomain.com -d www.yourdomain.com # Apache
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com # Nginx

# Automate renewal
sudo systemctl enable certbot.timer
sudo systemctl start certbot.timer

# Verify certificate details
openssl x509 -in /etc/letsencrypt/live/yourdomain.com/cert.pem -text -noout

# Check certificate expiration
echo | openssl s_client -servername yourdomain.com -connect yourdomain.com:443 2>/dev/null | openssl x509 -noout -dates

# Certificate monitoring script
cat > /root/pci-scripts/certificate_monitor.sh << 'EOF'
#!/bin/bash
# PCI-DSS SSL Certificate Monitoring

CERT_DIR="/etc/letsencrypt/live"
ALERT_EMAIL="[email protected]"
WARN_DAYS=30

for domain_dir in "$CERT_DIR"/*; do
    if [ -d "$domain_dir" ]; then
        DOMAIN=$(basename "$domain_dir")
        CERT_FILE="$domain_dir/cert.pem"

        if [ -f "$CERT_FILE" ]; then
            EXPIRY=$(openssl x509 -enddate -noout -in "$CERT_FILE" | cut -d= -f2)
            EXPIRY_EPOCH=$(date -d "$EXPIRY" +%s)
            NOW_EPOCH=$(date +%s)
            DAYS_LEFT=$(( ($EXPIRY_EPOCH - $NOW_EPOCH) / 86400 ))

            if [ "$DAYS_LEFT" -lt "$WARN_DAYS" ]; then
                echo "WARNING: Certificate for $DOMAIN expires in $DAYS_LEFT days!" | mail -s "SSL Certificate Expiration Warning" "$ALERT_EMAIL"
            fi

            echo "$DOMAIN: $DAYS_LEFT days until expiration"
        fi
    fi
done

EOF

chmod +x /root/pci-scripts/certificate_monitor.sh

# Schedule daily certificate checks
echo "0 8 * * * /root/pci-scripts/certificate_monitor.sh" | sudo crontab -

Requirement 5: Protect Against Malware

While Linux is less susceptible to traditional malware, PCI-DSS still requires anti-malware protection, particularly for systems that interact with Windows systems or process file uploads.

5.1: Install and Configure Anti-Malware

# Install ClamAV
sudo apt-get install -y clamav clamav-daemon # Debian/Ubuntu
sudo yum install -y clamav clamav-scanner clamav-update # RHEL/CentOS

# Update virus definitions
sudo systemctl stop clamav-freshclam
sudo freshclam
sudo systemctl start clamav-freshclam
sudo systemctl enable clamav-freshclam

# Configure ClamAV daemon
sudo systemctl enable clamav-daemon
sudo systemctl start clamav-daemon

# Scan uploaded files directory
sudo clamscan -r -i /var/www/html/uploads --log=/var/log/clamav/scan.log

# Automated scanning script
cat > /root/pci-scripts/malware_scan.sh << 'EOF'
#!/bin/bash
# PCI-DSS Automated Malware Scanning

SCAN_DIRS="/var/www /home /tmp /opt"
LOG_FILE="/var/log/clamav/scheduled_scan_$(date +%Y%m%d).log"
ALERT_EMAIL="[email protected]"

# Update virus definitions
freshclam --quiet

# Run scan
clamscan -r -i $SCAN_DIRS --log="$LOG_FILE"

# Check for infections
INFECTED=$(grep "Infected files:" "$LOG_FILE" | awk '{print $3}')

if [ "$INFECTED" != "0" ]; then
    echo "MALWARE DETECTED! See log: $LOG_FILE" | mail -s "URGENT: Malware Detection Alert" "$ALERT_EMAIL"
    # Optionally quarantine infected files
    grep "FOUND" "$LOG_FILE" | awk '{print $1}' | while read file; do
        sudo mv "$file" "/var/quarantine/$(basename $file).$(date +%s)"
    done
fi

echo "Scan completed: $(date)" >> "$LOG_FILE"

EOF

chmod +x /root/pci-scripts/malware_scan.sh

# Schedule daily scans
echo "0 2 * * * /root/pci-scripts/malware_scan.sh" | sudo crontab -

Requirement 6: Develop and Maintain Secure Systems

This requirement focuses on vulnerability management and secure development practices.

6.1: Patch Management

# Configure automatic security updates (Debian/Ubuntu)
sudo apt-get install -y unattended-upgrades apt-listchanges

sudo tee /etc/apt/apt.conf.d/50unattended-upgrades << 'EOF'
Unattended-Upgrade::Allowed-Origins {
    "${distro_id}:${distro_codename}-security";
    "${distro_id}ESMApps:${distro_codename}-apps-security";
    "${distro_id}ESM:${distro_codename}-infra-security";
};

Unattended-Upgrade::AutoFixInterruptedDpkg "true";
Unattended-Upgrade::MinimalSteps "true";
Unattended-Upgrade::Remove-Unused-Dependencies "true";
Unattended-Upgrade::Automatic-Reboot "false";
Unattended-Upgrade::Automatic-Reboot-Time "03:00";

Unattended-Upgrade::Mail "[email protected]";
Unattended-Upgrade::MailReport "on-change";
EOF

sudo dpkg-reconfigure -plow unattended-upgrades

# Configure automatic updates (RHEL/CentOS)
sudo yum install -y yum-cron

sudo tee /etc/yum/yum-cron.conf << 'EOF'
[commands]
update_cmd = security
apply_updates = yes
random_sleep = 360

[emitters]
system_name = None
emit_via = email
email_from = root@localhost
email_to = [email protected]
email_host = localhost

[base]
debuglevel = -2
skip_broken = True
assumeyes = True
EOF

sudo systemctl enable yum-cron
sudo systemctl start yum-cron

# Patch monitoring script
cat > /root/pci-scripts/patch_status.sh << 'EOF'
#!/bin/bash
# PCI-DSS Patch Status Report

REPORT_FILE="/var/log/pci-audit/patch_status_$(date +%Y%m%d).txt"
mkdir -p /var/log/pci-audit

exec > >(tee -a "$REPORT_FILE")

echo "========================================"
echo "PCI-DSS PATCH STATUS REPORT"
echo "Date: $(date)"
echo "========================================"
echo ""

if command -v apt &> /dev/null; then
    echo "=== Available Security Updates (Debian/Ubuntu) ==="
    sudo apt-get update -qq
    sudo apt-get upgrade -s | grep -i security | wc -l
    sudo apt-get upgrade -s | grep -i security

elif command -v yum &> /dev/null; then
    echo "=== Available Security Updates (RHEL/CentOS) ==="
    sudo yum check-update --security
fi

echo ""
echo "=== Kernel Version ==="
uname -r
echo "Latest available kernel:"
if command -v apt &> /dev/null; then
    apt-cache policy linux-image-generic | grep Candidate
elif command -v yum &> /dev/null; then
    yum list kernel | tail -1
fi

echo ""
echo "=== Last System Update ==="
if [ -f /var/log/apt/history.log ]; then
    grep "End-Date" /var/log/apt/history.log | tail -1
elif [ -f /var/log/yum.log ]; then
    tail -10 /var/log/yum.log
fi

echo ""
echo "Report saved to: $REPORT_FILE"

EOF

chmod +x /root/pci-scripts/patch_status.sh

# Schedule weekly patch reports
echo "0 9 * * 1 /root/pci-scripts/patch_status.sh | mail -s 'Weekly Patch Status Report' [email protected]" | sudo crontab -

6.2: Vulnerability Scanning

# Install and configure vulnerability scanner (OpenVAS/Nessus alternative)
# Using Lynis for host-based security scanning

sudo apt-get install -y lynis # Debian/Ubuntu
sudo yum install -y lynis # RHEL/CentOS

# Run security audit
sudo lynis audit system --quick --report-file /var/log/pci-audit/lynis_$(date +%Y%m%d).log

# Automated quarterly vulnerability scans
cat > /root/pci-scripts/vulnerability_scan.sh << 'EOF'
#!/bin/bash
# PCI-DSS Quarterly Vulnerability Scan

REPORT_DIR="/var/log/pci-audit/quarterly_scan_$(date +%Y_Q%q)"
mkdir -p "$REPORT_DIR"

echo "Running PCI-DSS Quarterly Vulnerability Scan..."
echo "Started: $(date)"

# System security audit with Lynis
sudo lynis audit system --auditor "PCI-Compliance-Team" --report-file "$REPORT_DIR/lynis_full.log"

# Network vulnerability scan (internal)
# For external scans, use ASV (Approved Scanning Vendor)
sudo nmap -sV -sC -O --script vuln localhost -oN "$REPORT_DIR/nmap_vulnerability.txt"

# Check for common vulnerabilities
echo "=== Checking for Common Vulnerabilities ===" > "$REPORT_DIR/manual_checks.txt"

# Shellshock
echo "Shellshock test:" >> "$REPORT_DIR/manual_checks.txt"
env x='() { :;}; echo vulnerable' bash -c "echo this is a test" 2>&1 >> "$REPORT_DIR/manual_checks.txt"

# Heartbleed
echo "Heartbleed test:" >> "$REPORT_DIR/manual_checks.txt"
openssl version 2>&1 >> "$REPORT_DIR/manual_checks.txt"

# Generate summary report
cat > "$REPORT_DIR/SUMMARY.txt" << SUMMARY
PCI-DSS Quarterly Vulnerability Scan
Date: $(date)
Performed by: $(whoami)

Scan Components:
1. Lynis system security audit
2. Nmap vulnerability scan
3. Common vulnerability checks

REQUIRED ACTIONS:
1. Review all findings in this directory
2. Remediate high and critical vulnerabilities within 30 days
3. Remediate medium vulnerabilities within 90 days
4. Document remediation or risk acceptance for each finding
5. Schedule external ASV scan for internet-facing systems

Next quarterly scan due: $(date -d "+3 months" +%Y-%m-%d)

SUMMARY

echo "Scan completed: $(date)"
echo "Results saved to: $REPORT_DIR"
echo "Please review and remediate findings according to PCI-DSS timelines."

EOF

chmod +x /root/pci-scripts/vulnerability_scan.sh

# Note: External quarterly scans must be performed by PCI-SSC Approved Scanning Vendor (ASV)

Requirement 7: Restrict Access to Cardholder Data by Business Need-to-Know

Implement strict access controls based on job responsibilities and least privilege.

7.1: Role-Based Access Control (RBAC)

# Create PCI-DSS specific user groups
sudo groupadd pci-admin
sudo groupadd pci-developer
sudo groupadd pci-readonly
sudo groupadd pci-dpo

# Assign users to groups based on job role
sudo usermod -aG pci-admin john_admin
sudo usermod -aG pci-developer jane_dev
sudo usermod -aG pci-readonly audit_user

# Configure directory permissions for cardholder data
sudo mkdir -p /opt/payment-app/data
sudo chown root:pci-admin /opt/payment-app/data
sudo chmod 2770 /opt/payment-app/data # SGID to maintain group ownership

# Create read-only audit directory
sudo mkdir -p /opt/payment-app/audit
sudo chown root:pci-readonly /opt/payment-app/audit
sudo chmod 2750 /opt/payment-app/audit

# Database access control
mysql -u root -p << 'EOF'
-- Create role-specific database users

-- Application user (minimal privileges)
CREATE USER IF NOT EXISTS 'app_user'@'localhost' IDENTIFIED BY 'strong_password';
GRANT SELECT, INSERT, UPDATE ON payment_db.orders TO 'app_user'@'localhost';
GRANT SELECT, INSERT ON payment_db.transactions TO 'app_user'@'localhost';

-- Admin user (full access to payment database)
CREATE USER IF NOT EXISTS 'pci_admin'@'localhost' IDENTIFIED BY 'strong_password';
GRANT ALL PRIVILEGES ON payment_db.* TO 'pci_admin'@'localhost';

-- Read-only audit user
CREATE USER IF NOT EXISTS 'audit_user'@'localhost' IDENTIFIED BY 'strong_password';
GRANT SELECT ON payment_db.* TO 'audit_user'@'localhost';

-- Revoke unnecessary global privileges
REVOKE ALL PRIVILEGES ON *.* FROM 'app_user'@'localhost';

FLUSH PRIVILEGES;
EOF

# Access review script
cat > /root/pci-scripts/access_review.sh << 'EOF'
#!/bin/bash
# PCI-DSS Access Review (Quarterly Requirement)

REPORT_FILE="/var/log/pci-audit/access_review_$(date +%Y%m%d).txt"
mkdir -p /var/log/pci-audit

exec > >(tee -a "$REPORT_FILE")

echo "========================================"
echo "PCI-DSS ACCESS REVIEW"
echo "Date: $(date)"
echo "========================================"
echo ""

echo "=== PCI Group Memberships ==="
for group in pci-admin pci-developer pci-readonly pci-dpo; do
    echo "Group: $group"
    getent group $group | cut -d: -f4
    echo ""
done

echo "=== Users with Sudo Privileges ==="
grep -rE "^%|^[a-zA-Z]" /etc/sudoers /etc/sudoers.d/ 2>/dev/null | grep -v "^#"
echo ""

echo "=== Database User Privileges ==="
mysql -u root -p -e "
SELECT User, Host,
    Select_priv, Insert_priv, Update_priv, Delete_priv,
    Create_priv, Drop_priv, Grant_priv
FROM mysql.user
WHERE User NOT IN ('root', 'mysql.sys', 'mysql.session', 'debian-sys-maint');
"
echo ""

echo "=== SSH Authorized Keys ==="
for user in $(getent passwd | awk -F: '$3 >= 1000 {print $1}'); do
    if [ -f "/home/$user/.ssh/authorized_keys" ]; then
        echo "User: $user"
        wc -l "/home/$user/.ssh/authorized_keys"
        echo ""
    fi
done

echo "=== Recent Login Activity ==="
last -10
echo ""

echo "========================================"
echo "REVIEW CHECKLIST:"
echo "[ ] All user access still required for job function?"
echo "[ ] No terminated employees with active access?"
echo "[ ] Least privilege principle maintained?"
echo "[ ] All sudo access justified and documented?"
echo "[ ] Database user privileges appropriate?"
echo "[ ] SSH keys belong to current employees only?"
echo "========================================"
echo ""
echo "Report saved to: $REPORT_FILE"

EOF

chmod +x /root/pci-scripts/access_review.sh

# Schedule quarterly access reviews
echo "0 9 1 1,4,7,10 * /root/pci-scripts/access_review.sh | mail -s 'Quarterly Access Review' [email protected]" | sudo crontab -

Requirement 8: Identify and Authenticate Access

Implement strong authentication mechanisms for all system access.

8.1: Multi-Factor Authentication (MFA)

# Install and configure Google Authenticator for SSH MFA
sudo apt-get install -y libpam-google-authenticator # Debian/Ubuntu
sudo yum install -y google-authenticator # RHEL/CentOS

# Configure PAM for SSH MFA
sudo tee -a /etc/pam.d/sshd << 'EOF'
# Google Authenticator MFA
auth required pam_google_authenticator.so nullok
EOF

# Update SSH configuration
sudo tee -a /etc/ssh/sshd_config.d/pci-mfa.conf << 'EOF'
# PCI-DSS Multi-Factor Authentication
ChallengeResponseAuthentication yes
AuthenticationMethods publickey,keyboard-interactive
EOF

sudo systemctl restart sshd

# User setup script (run as each user)
cat > /usr/local/bin/setup-mfa << 'EOF'
#!/bin/bash
# User MFA Setup Script

echo "Setting up Multi-Factor Authentication for $(whoami)"
echo "You will be shown a QR code to scan with your authenticator app."
echo ""

google-authenticator -t -d -f -r 3 -R 30 -w 3

echo ""
echo "MFA setup complete!"
echo "Next SSH login will require your authenticator code."

EOF

chmod +x /usr/local/bin/setup-mfa

8.2: Password Policy Enforcement

# Configure password aging
sudo tee -a /etc/login.defs << 'EOF'

# PCI-DSS Password Policy
PASS_MAX_DAYS   90
PASS_MIN_DAYS   1
PASS_WARN_AGE   7
PASS_MIN_LEN    12
EOF

# Apply to existing users
for user in $(getent passwd | awk -F: '$3 >= 1000 {print $1}'); do
    sudo chage -M 90 -m 1 -W 7 "$user"
done

# Configure account lockout
sudo tee -a /etc/pam.d/common-auth << 'EOF'

# PCI-DSS Account Lockout (6 failed attempts, 30 minute lockout)
auth required pam_tally2.so deny=6 unlock_time=1800 onerr=fail audit
EOF

# Check lockout status for user
sudo pam_tally2 --user=username

# Unlock user manually if needed
# sudo pam_tally2 --user=username --reset

# Session timeout configuration
sudo tee -a /etc/profile.d/pci-timeout.sh << 'EOF'
# PCI-DSS Session Timeout (15 minutes of inactivity)
TMOUT=900
readonly TMOUT
export TMOUT
EOF

chmod +x /etc/profile.d/pci-timeout.sh

Requirement 10: Track and Monitor All Access to Network Resources and Cardholder Data

Comprehensive logging and monitoring are essential for PCI-DSS compliance.

10.1: Audit Logging Configuration

# Install and configure auditd
sudo apt-get install -y auditd audispd-plugins # Debian/Ubuntu
sudo yum install -y audit audispd-plugins # RHEL/CentOS

# Configure PCI-DSS audit rules
sudo tee /etc/audit/rules.d/pci-dss.rules << 'EOF'
# PCI-DSS Audit Rules

## Remove any existing rules
-D

## Buffer Size (increase if needed)
-b 8192

## Failure Mode (2 = panic/halt system on audit failure - use with caution)
-f 1

## Audit the audit logs
-w /var/log/audit/ -k audit_logs

## Monitor cardholder data access
-w /opt/payment-app/data/ -p rwxa -k cardholder_data_access
-w /var/www/html/checkout/ -p rwxa -k payment_page_access

## Database access monitoring
-w /var/lib/mysql/ -p rwxa -k database_access
-w /etc/mysql/ -p wa -k database_config_change

## Authentication and authorization
-w /etc/passwd -p wa -k user_modification
-w /etc/group -p wa -k group_modification
-w /etc/shadow -p wa -k password_modification
-w /etc/sudoers -p wa -k sudo_modification
-w /etc/sudoers.d/ -p wa -k sudo_modification

## SSH access
-w /etc/ssh/sshd_config -p wa -k ssh_config_change
-w /home/*/.ssh/authorized_keys -p wa -k ssh_key_change

## Network configuration
-w /etc/hosts -p wa -k network_config
-w /etc/network/ -p wa -k network_config
-w /etc/sysconfig/network-scripts/ -p wa -k network_config

## System calls for file operations
-a always,exit -F arch=b64 -S open -S openat -F success=0 -k file_access_failed
-a always,exit -F arch=b64 -S unlink -S unlinkat -S rename -S renameat -k file_deletion

## Privilege escalation
-a always,exit -F arch=b64 -S setuid -S setgid -S setreuid -S setregid -k privilege_escalation

## Process execution
-a always,exit -F arch=b64 -S execve -k process_execution

## Kernel module loading
-w /sbin/insmod -p x -k kernel_modules
-w /sbin/rmmod -p x -k kernel_modules
-w /sbin/modprobe -p x -k kernel_modules

## Make configuration immutable (requires reboot to change)
-e 2
EOF

# Load audit rules
sudo augenrules --load

# Start and enable auditd
sudo systemctl enable auditd
sudo systemctl start auditd

# Verify rules loaded
sudo auditctl -l

10.2: Log Collection and Review

# Centralized logging configuration with rsyslog
sudo tee /etc/rsyslog.d/pci-remote-logging.conf << 'EOF'
# PCI-DSS Centralized Logging

# Send all logs to central log server
*.* @@log-server.example.com:514

# Local copies for redundancy
*.* /var/log/all.log

# Ensure logs are timestamped
$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat
EOF

sudo systemctl restart rsyslog

# Log review script
cat > /root/pci-scripts/log_review.sh << 'EOF'
#!/bin/bash
# PCI-DSS Daily Log Review

REPORT_FILE="/var/log/pci-audit/log_review_$(date +%Y%m%d).txt"
mkdir -p /var/log/pci-audit

exec > >(tee -a "$REPORT_FILE")

echo "========================================"
echo "PCI-DSS DAILY LOG REVIEW"
echo "Date: $(date)"
echo "========================================"
echo ""

echo "=== Failed Authentication Attempts ==="
grep "Failed password" /var/log/auth.log 2>/dev/null | wc -l
grep "Failed password" /var/log/auth.log 2>/dev/null | tail -20
echo ""

echo "=== Sudo Usage ==="
grep "sudo" /var/log/auth.log 2>/dev/null | grep -v "session opened" | tail -20
echo ""

echo "=== Cardholder Data Access ==="
sudo ausearch -k cardholder_data_access -ts today 2>/dev/null | grep -c "type=PATH"
sudo ausearch -k cardholder_data_access -ts today 2>/dev/null | tail -20
echo ""

echo "=== Database Access ==="
sudo ausearch -k database_access -ts today 2>/dev/null | wc -l
echo ""

echo "=== File Deletions ==="
sudo ausearch -k file_deletion -ts today 2>/dev/null | wc -l
sudo ausearch -k file_deletion -ts today 2>/dev/null | tail -10
echo ""

echo "=== Privilege Escalation ==="
sudo ausearch -k privilege_escalation -ts today 2>/dev/null | wc -l
sudo ausearch -k privilege_escalation -ts today 2>/dev/null | tail -10
echo ""

echo "=== Network Connections ==="
ss -tupn | grep ESTAB | grep -v "127.0.0.1" | head -20
echo ""

echo "=== Apache/Nginx Errors ==="
tail -50 /var/log/apache2/error.log /var/log/nginx/error.log 2>/dev/null | grep -i "error\|warning"
echo ""

echo "=== MySQL Errors ==="
tail -50 /var/log/mysql/error.log 2>/dev/null | grep -i "error\|warning"
echo ""

echo "Review completed: $(date)"
echo "Report saved to: $REPORT_FILE"
echo ""
echo "ALERTS REQUIRING IMMEDIATE ATTENTION:"
echo "[ ] Unusual failed authentication patterns?"
echo "[ ] Unauthorized cardholder data access?"
echo "[ ] Unexpected privilege escalations?"
echo "[ ] Database access from unknown sources?"
echo "[ ] Suspicious network connections?"

EOF

chmod +x /root/pci-scripts/log_review.sh

# Schedule daily log reviews
echo "30 8 * * * /root/pci-scripts/log_review.sh | mail -s 'Daily PCI Log Review' [email protected]" | sudo crontab -

10.3: Time Synchronization

# Install and configure NTP
sudo apt-get install -y chrony # Debian/Ubuntu
sudo yum install -y chrony # RHEL/CentOS

# Configure NTP servers
sudo tee /etc/chrony/chrony.conf << 'EOF'
# PCI-DSS Time Synchronization

# Use pool of NTP servers
pool 0.pool.ntp.org iburst
pool 1.pool.ntp.org iburst
pool 2.pool.ntp.org iburst
pool 3.pool.ntp.org iburst

# Record rate of clock drift
driftfile /var/lib/chrony/drift

# Allow NTP client access from local network
allow 192.168.1.0/24

# Serve time even if not synchronized
local stratum 10

# Log measurements
logdir /var/log/chrony
log measurements statistics tracking
EOF

sudo systemctl enable chronyd
sudo systemctl restart chronyd

# Verify time synchronization
chronyc tracking
chronyc sources -v

# Monitor time drift
cat > /root/pci-scripts/time_sync_check.sh << 'EOF'
#!/bin/bash
# PCI-DSS Time Synchronization Verification

REPORT_FILE="/var/log/pci-audit/time_sync_$(date +%Y%m%d).log"

exec > >(tee -a "$REPORT_FILE")

echo "Time Synchronization Check: $(date)"
echo ""

# Check if chronyd is running
if systemctl is-active --quiet chronyd; then
    echo "chronyd service: RUNNING"
else
    echo "chronyd service: NOT RUNNING - CRITICAL!"
fi

echo ""
echo "=== Tracking Status ==="
chronyc tracking

echo ""
echo "=== Source Statistics ==="
chronyc sources -v

echo ""
echo "=== Current System Time ==="
date
timedatectl

echo ""
OFFSET=$(chronyc tracking | grep "System time" | awk '{print $4}')
echo "Current offset: $OFFSET seconds"

if (( $(echo "$OFFSET > 1.0" | bc -l) )); then
    echo "WARNING: Time offset exceeds 1 second!"
fi

EOF

chmod +x /root/pci-scripts/time_sync_check.sh

# Schedule daily time sync verification
echo "0 9 * * * /root/pci-scripts/time_sync_check.sh" | sudo crontab -

Requirement 11: Regularly Test Security Systems and Processes

Regular security testing ensures controls remain effective.

11.1: Intrusion Detection System (IDS)

# Install and configure OSSEC HIDS
wget -q -O - https://updates.atomicorp.com/installers/atomic | sudo bash
sudo yum install -y ossec-hids-server # or ossec-hids-agent

# Configure OSSEC for PCI-DSS
sudo tee -a /var/ossec/etc/ossec.conf << 'EOF'
<ossec_config>
  <!-- PCI-DSS specific rules -->
  <syscheck>
    <frequency>7200</frequency>

    <!-- Monitor cardholder data directories -->
    <directories check_all="yes" realtime="yes">/opt/payment-app/data</directories>
    <directories check_all="yes" realtime="yes">/var/www/html/checkout</directories>
    <directories check_all="yes">/etc,/usr/bin,/usr/sbin</directories>
    <directories check_all="yes">/bin,/sbin,/boot</directories>

    <!-- Ignore frequently changing directories -->
    <ignore>/var/log</ignore>
    <ignore>/var/cache</ignore>
  </syscheck>

  <rootcheck>
    <frequency>7200</frequency>
  </rootcheck>

  <alerts>
    <log_alert_level>3</log_alert_level>
    <email_alert_level>7</email_alert_level>
  </alerts>

  <email_notification>yes</email_notification>
  <smtp_server>smtp.example.com</smtp_server>
  <email_from>[email protected]</email_from>
  <email_to>[email protected]</email_to>
</ossec_config>
EOF

sudo /var/ossec/bin/ossec-control restart

# Alternative: Fail2ban with enhanced PCI rules
sudo tee /etc/fail2ban/jail.local << 'EOF'
[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 3
destemail = [email protected]
sendername = PCI-Security-Alert
action = %(action_mwl)s

[sshd]
enabled = true
maxretry = 3

[apache-auth]
enabled = true
maxretry = 3

[apache-noscript]
enabled = true

[apache-overflows]
enabled = true

[apache-badbots]
enabled = true

[php-url-fopen]
enabled = true

[nginx-http-auth]
enabled = true

EOF

sudo systemctl restart fail2ban

11.2: File Integrity Monitoring (FIM)

# Configure AIDE for file integrity monitoring
sudo apt-get install -y aide aide-common # Debian/Ubuntu
sudo yum install -y aide # RHEL/CentOS

# Configure AIDE for PCI-DSS
sudo tee /etc/aide/aide.conf << 'EOF'
# PCI-DSS File Integrity Monitoring Configuration

# Database locations
database=file:/var/lib/aide/aide.db
database_out=file:/var/lib/aide/aide.db.new
database_new=file:/var/lib/aide/aide.db.new

# Report settings
verbose=5
report_url=stdout
report_url=file:/var/log/aide/aide.log

# Custom rules for different file types
PCI_READONLY = R+b+sha512
PCI_LOGS = >
PCI_GROWING = p+l+u+g+i+n+S

# Critical system directories
/bin PCI_READONLY
/sbin PCI_READONLY
/usr/bin PCI_READONLY
/usr/sbin PCI_READONLY
/lib PCI_READONLY
/lib64 PCI_READONLY
/etc PCI_READONLY

# Application and data directories
/opt/payment-app PCI_READONLY
/var/www/html PCI_READONLY

# Configuration files
/etc/ssh/sshd_config PCI_READONLY
/etc/mysql PCI_READONLY
/etc/apache2 PCI_READONLY
/etc/nginx PCI_READONLY

# Log files (monitor size/attributes only)
/var/log PCI_LOGS

# Exclude frequently changing files
!/var/log/.*
!/var/cache/.*
!/var/tmp/.*
EOF

# Initialize AIDE database
sudo aideinit
sudo mv /var/lib/aide/aide.db.new /var/lib/aide/aide.db

# Run integrity check
sudo aide --check

# Automated daily FIM checks
cat > /root/pci-scripts/file_integrity_check.sh << 'EOF'
#!/bin/bash
# PCI-DSS File Integrity Monitoring

REPORT_FILE="/var/log/pci-audit/fim_$(date +%Y%m%d).txt"
ALERT_EMAIL="[email protected]"

# Run AIDE check
aide --check > "$REPORT_FILE" 2>&1

# Check for changes
if grep -q "changed:" "$REPORT_FILE"; then
    echo "FILE INTEGRITY VIOLATION DETECTED!" | mail -s "URGENT: File Integrity Alert" -a "$REPORT_FILE" "$ALERT_EMAIL"
fi

# Update database weekly
if [ "$(date +%u)" -eq 7 ]; then
    aide --update
    mv /var/lib/aide/aide.db.new /var/lib/aide/aide.db
fi

EOF

chmod +x /root/pci-scripts/file_integrity_check.sh

# Schedule daily FIM checks
echo "0 3 * * * /root/pci-scripts/file_integrity_check.sh" | sudo crontab -

PCI-DSS Compliance Checklist

Here's a comprehensive checklist with verification commands:

# Create PCI-DSS compliance verification script
cat > /root/pci-scripts/pci_compliance_check.sh << 'EOF'
#!/bin/bash
# PCI-DSS Compliance Verification Checklist

REPORT_FILE="/var/log/pci-audit/compliance_check_$(date +%Y%m%d).txt"
mkdir -p /var/log/pci-audit

exec > >(tee -a "$REPORT_FILE")
exec 2>&1

echo "========================================"
echo "PCI-DSS COMPLIANCE VERIFICATION"
echo "Date: $(date)"
echo "Auditor: $(whoami)"
echo "========================================"
echo ""

# Requirement 1: Firewall Configuration
echo "=== Requirement 1: Firewall Configuration ==="
echo "[ ] Firewall installed and configured:"
systemctl is-active iptables firewalld 2>/dev/null
iptables -L -n | head -20
echo ""

# Requirement 2: Vendor Defaults
echo "=== Requirement 2: Change Vendor Defaults ==="
echo "[ ] Default passwords changed (manual verification required)"
echo "[ ] Unnecessary services disabled:"
systemctl list-units --type=service --state=running | wc -l
echo ""

# Requirement 3: Protect Stored Data
echo "=== Requirement 3: Protect Stored Cardholder Data ==="
echo "[ ] Disk encryption enabled:"
lsblk -o NAME,FSTYPE,MOUNTPOINT | grep -c crypt
echo "[ ] Database encryption enabled:"
mysql -u root -p -e "SHOW VARIABLES LIKE '%encrypt%';" 2>/dev/null | grep -c ON
echo ""

# Requirement 4: Encrypt Transmission
echo "=== Requirement 4: Encrypt Transmission ==="
echo "[ ] Strong TLS configured:"
openssl s_client -connect localhost:443 -tls1_2 2>&1 | grep -E "Protocol|Cipher"
echo ""

# Requirement 5: Anti-Malware
echo "=== Requirement 5: Protect Against Malware ==="
echo "[ ] Anti-malware installed:"
systemctl is-active clamav-daemon 2>/dev/null
clamscan --version
echo ""

# Requirement 6: Secure Systems
echo "=== Requirement 6: Secure Systems and Applications ==="
echo "[ ] Security updates applied:"
if command -v apt &> /dev/null; then
    apt list --upgradable 2>/dev/null | grep -i security | wc -l
elif command -v yum &> /dev/null; then
    yum check-update --security 2>/dev/null | wc -l
fi
echo ""

# Requirement 7: Restrict Access
echo "=== Requirement 7: Restrict Access by Need-to-Know ==="
echo "[ ] Role-based access control implemented:"
getent group | grep pci | wc -l
echo ""

# Requirement 8: Identify and Authenticate
echo "=== Requirement 8: Unique IDs and Authentication ==="
echo "[ ] MFA configured:"
grep "pam_google_authenticator" /etc/pam.d/sshd 2>/dev/null | wc -l
echo "[ ] Password policy enforced:"
grep "PASS_MAX_DAYS" /etc/login.defs
echo ""

# Requirement 9: Physical Access (manual)
echo "=== Requirement 9: Restrict Physical Access ==="
echo "[ ] Physical access controls (manual verification required)"
echo ""

# Requirement 10: Track and Monitor
echo "=== Requirement 10: Track and Monitor Access ==="
echo "[ ] Audit logging enabled:"
systemctl is-active auditd
echo "[ ] Audit rules count:"
auditctl -l | wc -l
echo "[ ] Time synchronization:"
chronyc tracking | grep "System time"
echo ""

# Requirement 11: Test Security Systems
echo "=== Requirement 11: Test Security Systems ==="
echo "[ ] IDS/IPS deployed:"
systemctl is-active fail2ban ossec 2>/dev/null
echo "[ ] File integrity monitoring:"
which aide
echo "[ ] Last vulnerability scan:"
ls -lt /var/log/pci-audit/quarterly_scan_* 2>/dev/null | head -1
echo ""

# Requirement 12: Security Policy (manual)
echo "=== Requirement 12: Information Security Policy ==="
echo "[ ] Security policy documented (manual verification required)"
echo "[ ] Risk assessment performed (manual verification required)"
echo "[ ] Incident response plan in place (manual verification required)"
echo ""

echo "========================================"
echo "COMPLIANCE CHECK COMPLETED"
echo "Report saved to: $REPORT_FILE"
echo "========================================"
echo ""
echo "NEXT STEPS:"
echo "1. Review all unchecked items"
echo "2. Remediate any gaps identified"
echo "3. Complete manual verification items"
echo "4. Document all findings and remediations"
echo "5. Schedule next compliance check"

EOF

chmod +x /root/pci-scripts/pci_compliance_check.sh

Conclusion

PCI-DSS compliance for e-commerce platforms requires comprehensive technical controls, rigorous procedures, and continuous monitoring. This guide has provided you with practical, command-line driven implementations of the most critical PCI-DSS requirements for Linux system administrators.

Key Takeaways

1. Network Security is Foundational: Properly configured firewalls, network segmentation, and restricted access to the CDE form the foundation of PCI-DSS compliance.

2. Encryption is Mandatory: Both stored cardholder data and data in transit must be protected with strong encryption. Use TLS 1.2+ for transmission and AES-256 for storage.

3. Access Control is Critical: Implement role-based access control, enforce least privilege, use multi-factor authentication, and regularly review all user access.

4. Logging and Monitoring are Essential: Comprehensive audit logging, daily log review, file integrity monitoring, and intrusion detection are required for both compliance and breach detection.

5. Vulnerability Management is Ongoing: Regular patching, quarterly vulnerability scans by an ASV, and annual penetration testing are mandatory requirements.

6. Documentation is Required: All security policies, procedures, configurations, and compliance activities must be thoroughly documented.

Maintaining Compliance

PCI-DSS compliance is not a one-time project but an ongoing program:

  • Daily: Log review, security monitoring, backup verification
  • Weekly: Patch status review, access log analysis
  • Monthly: Firewall rule review, user access verification
  • Quarterly: Vulnerability scans (internal and external by ASV), access reviews, policy updates
  • Annually: Penetration testing, comprehensive compliance audit, policy review

Final Recommendations

  1. Minimize Scope: The less cardholder data you store, process, or transmit, the smaller your compliance scope. Consider using payment tokenization services.

  2. Automate Everything Possible: Use the scripts provided in this guide to automate compliance tasks, reducing human error and ensuring consistency.

  3. Engage a QSA: For Level 1 merchants or complex environments, engage a Qualified Security Assessor (QSA) to ensure proper compliance.

  4. Stay Updated: PCI-DSS standards evolve. Stay current with the latest version and guidance from the PCI Security Standards Council.

  5. Security First: View PCI-DSS not as a compliance burden but as a framework for building a secure e-commerce infrastructure that protects your customers and your business.

By implementing the controls and procedures outlined in this guide, you'll not only achieve PCI-DSS compliance but also build a robust security posture that protects against the ever-evolving threat landscape in e-commerce.