Skip to content

AxonOps — AI-Native Control Plane for Open Source Data Platforms

Cassandra Operating System Security

Cassandra's security depends on the underlying operating system. A compromised OS grants full access to data files, configuration, and credentials regardless of Cassandra-level security controls. This guide covers Linux security practices essential for production Cassandra deployments.


The Center for Internet Security (CIS) publishes consensus-based security configuration guidelines. CIS Benchmarks provide prescriptive hardening standards with specific configuration values.

BenchmarkApplicability
CIS Red Hat Enterprise Linux 8/9RHEL-based Cassandra hosts
CIS Ubuntu Linux 22.04/24.04 LTSUbuntu-based Cassandra hosts
CIS Amazon Linux 2/2023AWS EC2 deployments
CIS Oracle Linux 8/9Oracle Cloud deployments
CIS Distribution Independent LinuxGeneral Linux guidance
LevelDescriptionUse Case
Level 1Essential security settings, minimal performance impactProduction baseline
Level 2Defense-in-depth, may reduce functionalityHigh-security environments
STIGAligned with DISA STIG requirementsGovernment/DoD systems

Section 1 – Initial Setup

ControlRecommendationCassandra Notes
1.1.xFilesystem configurationSeparate partitions for /var/lib/cassandra
1.4.xSecure boot settingsUEFI Secure Boot where supported
1.5.xProcess hardeningASLR, core dump restrictions

Section 2 – Services

ControlRecommendationCassandra Notes
2.1.xRemove unnecessary servicesDisable X11, CUPS, Avahi
2.2.xDisable unnecessary clientsRemove FTP, telnet clients

Section 3 – Network Configuration

ControlRecommendationCassandra Notes
3.1.xDisable unused network protocolsDisable DCCP, SCTP, RDS
3.2.xNetwork parameters (host)IP forwarding, ICMP redirects
3.4.xFirewall configurationRestrict to Cassandra ports only

Section 4 – Logging and Auditing

ControlRecommendationCassandra Notes
4.1.xConfigure auditdLog Cassandra file access
4.2.xConfigure loggingCentralize logs, protect integrity

Section 5 – Access, Authentication, Authorization

ControlRecommendationCassandra Notes
5.2.xSSH configurationKey-based auth, no root login
5.3.xPAM configurationPassword complexity, lockout
5.4.xUser accountsService account restrictions
5.5.xRoot login restrictionsLimit root access methods

Section 6 – System Maintenance

ControlRecommendationCassandra Notes
6.1.xFile permissionsCassandra data/config permissions
6.2.xUser and group settingsVerify cassandra user configuration
Terminal window
# CIS-CAT Pro (commercial)
./Assessor-CLI.sh -b benchmarks/CIS_Red_Hat_Enterprise_Linux_9_Benchmark_v1.0.0.xml
# OpenSCAP (open source)
sudo yum install scap-security-guide openscap-scanner
sudo oscap xccdf eval --profile cis \
--results results.xml \
--report report.html \
/usr/share/xml/scap/ssg/content/ssg-rhel9-ds.xml
# Lynis (open source)
sudo lynis audit system --profile server

Defense Information Systems Agency (DISA) Security Technical Implementation Guides (STIGs) provide security hardening standards required for U.S. Department of Defense systems.

AspectCIS BenchmarksDISA STIGs
AuthorityIndustry consensusU.S. DoD mandate
ScopeGeneral best practiceDoD/government compliance
SeverityLevels 1, 2CAT I, II, III
FormatPDF, automated toolsXCCDF, manual checklists
UpdatesQuarterlyAs needed
CostFree (benchmarks), paid (tools)Free
CategoryDescriptionRemediation Timeline
CAT IHigh severity, direct exploitation riskImmediate
CAT IIMedium severity, potential for exploitationWithin 30 days
CAT IIILow severity, defense-in-depthWithin 90 days
STIGVersionApplication
Red Hat Enterprise Linux 8/9 STIGCurrentRHEL hosts
Ubuntu 20.04/22.04 STIGCurrentUbuntu hosts
General Purpose Operating System STIGCurrentAll Linux
Application Security and Development STIGCurrentCassandra application

Authentication (SRG-OS-000xxx)

/etc/security/faillock.conf
# V-230332: Lock accounts after 3 failed attempts
deny = 3
unlock_time = 900
fail_interval = 900
# V-230340: Password minimum length
# /etc/security/pwquality.conf
minlen = 15

Access Control (SRG-OS-000xxx)

Terminal window
# V-230386: Set permissions on /etc/passwd
chmod 644 /etc/passwd
# V-230388: Set permissions on /etc/shadow
chmod 000 /etc/shadow
# V-230483: Disable core dumps for SUID programs
echo '* hard core 0' >> /etc/security/limits.conf
echo 'fs.suid_dumpable = 0' >> /etc/sysctl.d/99-stig.conf

Audit and Accountability (SRG-OS-000xxx)

Terminal window
# V-230398: Audit privileged commands
-a always,exit -F path=/usr/bin/sudo -F perm=x -F auid>=1000 -F auid!=unset -k priv_cmd
# V-230402: Audit file deletions
-a always,exit -F arch=b64 -S unlink,unlinkat,rename,renameat -F auid>=1000 -F auid!=unset -k delete

System Integrity (SRG-OS-000xxx)

Terminal window
# V-230222: Enable FIPS mode (if required)
fips-mode-setup --enable
# V-230264: Install AIDE for file integrity
sudo yum install aide
sudo aide --init
Terminal window
# SCAP Compliance Checker (SCC)
# Download from DoD Cyber Exchange: https://public.cyber.mil/stigs/scap/
./scc -u /path/to/stig-benchmark.xml
# OpenSCAP with STIG profile
sudo oscap xccdf eval --profile stig \
--results stig-results.xml \
--report stig-report.html \
/usr/share/xml/scap/ssg/content/ssg-rhel9-ds.xml
# Ansible STIG roles
ansible-galaxy install RedHatOfficial.rhel9_stig
ansible-playbook -i inventory stig-playbook.yml

Some hardening controls may conflict with Cassandra requirements. Document exceptions with compensating controls:

ControlConflictCompensating Control
Disable IPv6May be needed for clusterFirewall IPv6, use IPv4 for Cassandra
noexec on /tmpJVM may use /tmp for JITUse dedicated Java temp directory
Strict umaskCassandra file sharingSet umask in cassandra-env.sh
Password expirationService accountsUse locked accounts, no password auth
Session timeoutLong-running repairsExclude cassandra processes
cassandra-env.sh
# Configure Java to use dedicated temp directory
JVM_OPTS="$JVM_OPTS -Djava.io.tmpdir=/var/lib/cassandra/tmp"
Terminal window
# Create dedicated temp directory
sudo mkdir -p /var/lib/cassandra/tmp
sudo chown cassandra:cassandra /var/lib/cassandra/tmp
sudo chmod 750 /var/lib/cassandra/tmp

Most regulatory frameworks mandate timely patching of security vulnerabilities:

FrameworkPatching Requirement
PCI DSS 4.0Requirement 6.3.3: Critical patches within 30 days
SOC 2CC6.1: Logical and physical access controls including patch management
HIPAA§164.308(a)(5)(ii)(B): Protection from malicious software
CIS ControlsControl 7: Continuous vulnerability management
NIST 800-53SI-2: Flaw remediation
SeverityCVSS ScoreResponse TimeAction
Critical9.0 – 10.024-72 hoursEmergency patch window
High7.0 – 8.97-14 daysPriority scheduling
Medium4.0 – 6.930 daysStandard maintenance
Low0.1 – 3.990 daysNext scheduled window
Terminal window
# 1. Check available security updates
sudo yum check-update --security # RHEL/CentOS
sudo apt list --upgradable # Debian/Ubuntu
# 2. Review CVEs affecting installed packages
sudo yum updateinfo list security
sudo apt-get changelog <package>
# 3. Test in non-production first
# Apply patches to staging environment
# Run integration tests
# Verify Cassandra functionality
# 4. Apply to production (rolling)
# One node at a time
nodetool drain
sudo systemctl stop cassandra
sudo yum update --security -y
sudo systemctl start cassandra
# Wait for node to rejoin and stream
nodetool status
Terminal window
# /etc/yum/yum-cron.conf (RHEL/CentOS)
[commands]
update_cmd = security
apply_updates = yes
# Exclude Cassandra packages from auto-update
# (manual control for database software)
[base]
exclude = cassandra* java*
Terminal window
# /etc/apt/apt.conf.d/50unattended-upgrades (Debian/Ubuntu)
Unattended-Upgrade::Allowed-Origins {
"${distro_id}:${distro_codename}-security";
};
# Blacklist database packages
Unattended-Upgrade::Package-Blacklist {
"cassandra";
"openjdk-";
};

Cassandra should run under a dedicated unprivileged user account:

Terminal window
# Create cassandra user (if not created by package)
sudo groupadd -r cassandra
sudo useradd -r -g cassandra -d /var/lib/cassandra -s /sbin/nologin cassandra
# Verify account properties
id cassandra
# uid=xxx(cassandra) gid=xxx(cassandra) groups=xxx(cassandra)
# Ensure no login shell
grep cassandra /etc/passwd
# cassandra:x:xxx:xxx::/var/lib/cassandra:/sbin/nologin
PropertyRecommended SettingPurpose
Shell/sbin/nologin or /bin/falsePrevent interactive login
Home directory/var/lib/cassandraContain data access
PasswordLocked (! or *)Prevent password authentication
System account-r flagUID below 1000
Terminal window
# Lock the cassandra account password
sudo passwd -l cassandra
# Verify account is locked
sudo passwd -S cassandra
# cassandra L 2024-01-15 0 99999 7 -1 (Password locked.)
# Remove from any unnecessary groups
sudo gpasswd -d cassandra wheel 2>/dev/null || true
/etc/ssh/sshd_config
# Disable root login
PermitRootLogin no
# Deny cassandra service account SSH access
DenyUsers cassandra
# Restrict SSH to specific users/groups
AllowGroups sysadmins dba-team
# Disable password authentication (use keys)
PasswordAuthentication no
PubkeyAuthentication yes
# Set idle timeout
ClientAliveInterval 300
ClientAliveCountMax 2
# Restrict SSH protocol
Protocol 2
Terminal window
# Apply SSH configuration
sudo systemctl reload sshd
/etc/sudoers.d/cassandra-admin
# Allow DBA team to manage Cassandra service
%dba-team ALL=(ALL) /usr/bin/systemctl start cassandra
%dba-team ALL=(ALL) /usr/bin/systemctl stop cassandra
%dba-team ALL=(ALL) /usr/bin/systemctl restart cassandra
%dba-team ALL=(ALL) /usr/bin/systemctl status cassandra
%dba-team ALL=(ALL) /usr/bin/nodetool *
%dba-team ALL=(ALL) /usr/bin/cqlsh
# Require password for sudo
Defaults:%dba-team timestamp_timeout=5
# Log all sudo commands
Defaults log_output
Defaults!/usr/bin/sudoreplay !log_output

Terminal window
# Cassandra directories
sudo chown -R cassandra:cassandra /var/lib/cassandra
sudo chown -R cassandra:cassandra /var/log/cassandra
sudo chown -R root:cassandra /etc/cassandra
# Permissions
sudo chmod 750 /var/lib/cassandra
sudo chmod 750 /var/log/cassandra
sudo chmod 750 /etc/cassandra
# Data directories
sudo chmod 700 /var/lib/cassandra/data
sudo chmod 700 /var/lib/cassandra/commitlog
sudo chmod 700 /var/lib/cassandra/saved_caches
sudo chmod 700 /var/lib/cassandra/hints
# Configuration files
sudo chmod 640 /etc/cassandra/cassandra.yaml
sudo chmod 640 /etc/cassandra/cassandra-env.sh
sudo chmod 600 /etc/cassandra/jmxremote.password
PathOwnerGroupModeNotes
/var/lib/cassandracassandracassandra750Data root
/var/lib/cassandra/datacassandracassandra700SSTable data
/var/lib/cassandra/commitlogcassandracassandra700Commit logs
/var/log/cassandracassandracassandra750Log files
/etc/cassandrarootcassandra750Configuration
/etc/cassandra/cassandra.yamlrootcassandra640Main config
/etc/cassandra/*.passwordrootcassandra600Credentials
/etc/fstab
# Data volume - noexec prevents binary execution
/dev/sdb1 /var/lib/cassandra ext4 defaults,noexec,nodev,nosuid 0 2
# Log volume
/dev/sdc1 /var/log/cassandra ext4 defaults,noexec,nodev,nosuid 0 2
Mount OptionPurpose
noexecPrevent execution of binaries on data volumes
nodevPrevent device file interpretation
nosuidIgnore setuid/setgid bits
/etc/aide.conf
# AIDE (Advanced Intrusion Detection Environment)
sudo yum install aide
/etc/cassandra CONTENT_EX
/var/lib/cassandra/data DATAONLY
!/var/lib/cassandra/commitlog
!/var/lib/cassandra/saved_caches
# Initialize database
sudo aide --init
sudo mv /var/lib/aide/aide.db.new.gz /var/lib/aide/aide.db.gz
# Check for changes
sudo aide --check

/etc/sysctl.d/99-cassandra-security.conf
# Network security
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
net.ipv4.conf.all.log_martians = 1
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.icmp_ignore_bogus_error_responses = 1
net.ipv4.tcp_syncookies = 1
# Disable IPv6 if not needed
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
# Memory protection
kernel.randomize_va_space = 2
kernel.dmesg_restrict = 1
kernel.kptr_restrict = 2
# Core dump restrictions
fs.suid_dumpable = 0
kernel.core_pattern = |/bin/false
Terminal window
# Apply settings
sudo sysctl --system
/etc/security/limits.d/cassandra.conf
# File descriptors (required for Cassandra)
cassandra soft nofile 1048576
cassandra hard nofile 1048576
# Process limits
cassandra soft nproc 32768
cassandra hard nproc 32768
# Memory lock (for JVM)
cassandra soft memlock unlimited
cassandra hard memlock unlimited
# Address space
cassandra soft as unlimited
cassandra hard as unlimited
Terminal window
# Disable core dumps globally
echo '* hard core 0' >> /etc/security/limits.conf
# Or restrict to specific directory with proper permissions
# /etc/sysctl.d/99-coredump.conf
kernel.core_pattern = /var/crash/core.%e.%p.%t
Terminal window
# Secure core dump directory if enabled
sudo mkdir -p /var/crash
sudo chmod 700 /var/crash

SELinux Compatibility

SELinux in enforcing mode frequently causes issues with Cassandra. There is no official SELinux policy module for Cassandra, and the JVM's dynamic behavior (JIT compilation, memory-mapped files, native library loading) conflicts with SELinux's access control model.

Most production Cassandra deployments use one of these approaches:

ModeSettingUse Case
Permissivesetenforce 0Log violations without blocking (recommended for most)
DisabledSELINUX=disabledSimpler operations, use other compensating controls
Enforcingsetenforce 1Only if mandated by compliance (requires significant effort)
Terminal window
# Check current status
getenforce
sestatus
# Set to permissive (immediate, non-persistent)
sudo setenforce 0
# Set to permissive (persistent)
sudo sed -i 's/^SELINUX=enforcing/SELINUX=permissive/' /etc/selinux/config

Compensating Controls When SELinux is Disabled/Permissive

Section titled “Compensating Controls When SELinux is Disabled/Permissive”

If SELinux is not in enforcing mode, implement these compensating controls:

ControlPurpose
Filesystem permissionsRestrict access to Cassandra directories
Dedicated service accountRun Cassandra as unprivileged user
Firewall rulesLimit network access to required ports
auditd rulesMonitor file access and process execution
systemd hardeningUse ProtectSystem, PrivateTmp, NoNewPrivileges

For environments where SELinux enforcing mode is mandated, expect significant troubleshooting. A custom policy must be developed iteratively:

Terminal window
# 1. Start in permissive mode to collect denials
sudo setenforce 0
# 2. Start Cassandra and exercise all functionality
sudo systemctl start cassandra
# Run repairs, backups, streaming, etc.
# 3. Generate policy from collected denials
sudo grep cassandra /var/log/audit/audit.log | audit2allow -M cassandra-local
sudo semodule -i cassandra-local.pp
# 4. Test in enforcing mode
sudo setenforce 1
sudo systemctl restart cassandra
# 5. Repeat steps 2-4 until all operations work

Common denial categories requiring policy rules:

Denial TypeCause
mmap_fileJVM memory-mapped files
execmemJIT compilation
name_bindBinding to ports 7000, 7001, 9042
file writeSSTable creation, commit logs
unix_stream_socketInternal JVM communication
/etc/apparmor.d/usr.sbin.cassandra
#include <tunables/global>
/usr/sbin/cassandra {
#include <abstractions/base>
#include <abstractions/java>
# Binary and libraries
/usr/share/cassandra/** r,
/usr/share/cassandra/lib/*.jar r,
# Configuration
/etc/cassandra/ r,
/etc/cassandra/** r,
# Data directories
/var/lib/cassandra/ rw,
/var/lib/cassandra/** rwk,
# Logs
/var/log/cassandra/ rw,
/var/log/cassandra/** rw,
# Temp
/tmp/ r,
/tmp/cassandra-* rwk,
# Network
network inet stream,
network inet dgram,
# Java
/usr/lib/jvm/** mr,
/proc/*/fd/ r,
/proc/sys/vm/max_map_count r,
}
Terminal window
# Load profile
sudo apparmor_parser -r /etc/apparmor.d/usr.sbin.cassandra
sudo aa-enforce /usr/sbin/cassandra

/etc/audit/rules.d/cassandra.rules
# Monitor Cassandra configuration changes
-w /etc/cassandra/ -p wa -k cassandra_config
# Monitor Cassandra data directory access
-w /var/lib/cassandra/ -p wa -k cassandra_data
# Monitor Cassandra binary execution
-w /usr/share/cassandra/bin/ -p x -k cassandra_exec
# Monitor authentication files
-w /etc/cassandra/jmxremote.password -p rwa -k cassandra_auth
-w /etc/cassandra/jmxremote.access -p rwa -k cassandra_auth
# Monitor user/group changes
-w /etc/passwd -p wa -k identity
-w /etc/group -p wa -k identity
-w /etc/shadow -p wa -k identity
# Monitor sudo usage
-w /etc/sudoers -p wa -k sudoers
-w /etc/sudoers.d/ -p wa -k sudoers
# Log all commands run by cassandra user
-a always,exit -F arch=b64 -F euid=cassandra -S execve -k cassandra_commands
Terminal window
# Load audit rules
sudo augenrules --load
sudo systemctl restart auditd
# Search audit logs
sudo ausearch -k cassandra_config
sudo ausearch -k cassandra_auth -ts today
/etc/rsyslog.d/cassandra.conf
# Forward audit logs to central SIEM
if $programname == 'audit' then @@siem.example.com:514
# Forward Cassandra logs
$ModLoad imfile
$InputFileName /var/log/cassandra/system.log
$InputFileTag cassandra:
$InputFileStateFile cassandra-system-log
$InputFileSeverity info
$InputFileFacility local0
$InputRunFileMonitor
local0.* @@siem.example.com:514

/etc/systemd/system/cassandra.service.d/security.conf
[Service]
# Run as unprivileged user
User=cassandra
Group=cassandra
# Restrict filesystem access
ProtectSystem=full
ProtectHome=true
ReadWritePaths=/var/lib/cassandra /var/log/cassandra
ReadOnlyPaths=/etc/cassandra
# Restrict kernel access
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
# Restrict device access
PrivateDevices=true
# Disable privilege escalation
NoNewPrivileges=true
# Restrict capabilities
CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_IPC_LOCK
AmbientCapabilities=CAP_NET_BIND_SERVICE CAP_IPC_LOCK
# Restrict system calls (may need tuning)
SystemCallFilter=@system-service
SystemCallErrorNumber=EPERM
# Private temp directory
PrivateTmp=true
# Restrict network
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
# Limit resources
LimitNOFILE=1048576
LimitNPROC=32768
LimitMEMLOCK=infinity
Terminal window
# Reload systemd
sudo systemctl daemon-reload
sudo systemctl restart cassandra

  • OS installed from verified media
  • Minimal installation (no GUI, unnecessary packages removed)
  • All security patches applied
  • Dedicated service account created
  • SSH hardened (keys only, root disabled)
  • Firewall configured
  • Separate partitions for data, logs, OS
  • Correct ownership and permissions
  • Mount options applied (noexec, nodev, nosuid)
  • File integrity monitoring configured
  • Sudo configured with least privilege
  • Service account locked
  • SELinux permissive/disabled with compensating controls (or enforcing if mandated)
  • Audit logging enabled
  • Automated security updates (OS packages)
  • Vulnerability scanning scheduled
  • Audit logs reviewed
  • Access reviews performed
  • Patch compliance monitored