Storage Hardening
MinIO AIStor supports kernel-level storage protection to prevent accidental deletion of data directories by system administrators while allowing the MinIO AIStor process full control over managed drives.
This protection is critical for production environments where a mistyped rm -rf /drive* command could result in catastrophic data loss.
Protection model
Storage hardening provides:
- MinIO AIStor process: Full read/write/delete access to managed drives.
- Host OS (including root): Read-only access to protected directories.
- Kernel-level enforcement: Protection cannot be bypassed through normal filesystem operations.
- No performance impact: Both implementations add negligible overhead.
Choose an implementation
MinIO AIStor provides two storage protection implementations:
| Feature | SELinux | eBPF LSM |
|---|---|---|
| Kernel version | Any (built into most enterprise distros) | Supported on all AIStor-compatible kernels |
| Best for | RHEL, CentOS, Fedora | Ubuntu, Debian, other distros |
| Configuration | Policy files and labels | Kernel parameter + daemon |
| Process tracking | Static labels | Automatic (daemon scans for MinIO AIStor processes) |
| Maturity | 20+ years in production | Newer, but production-ready |
Recommendations:
- RHEL/CentOS/Fedora: Use SELinux (better integration, native support)
- Ubuntu/Debian: Use eBPF LSM (default kernel support, no SELinux required)
- Other distributions: Use eBPF LSM for universal compatibility
SELinux-based protection
Use SELinux-based storage protection on RHEL, CentOS, Fedora, and other SELinux-enabled systems.
Prerequisites
- RHEL 8/9, CentOS 8/9, Fedora, or any Linux distribution with SELinux.
- SELinux in enforcing or permissive mode (not disabled).
- SELinux policy development tools.
Check SELinux status:
getenforce
The output should be Enforcing or Permissive.
If the output is Disabled, enable SELinux first:
# Edit SELinux config
sudo vi /etc/selinux/config
# Set SELINUX=enforcing
SELINUX=enforcing
# Reboot required
sudo reboot
Install required tools:
sudo dnf install -y policycoreutils-python-utils selinux-policy-devel
Automated setup
Use the setup script for automatic installation:
curl -O https://raw.githubusercontent.com/miniohq/eos/master/scripts/setup-selinux-protection.sh
chmod +x setup-selinux-protection.sh
sudo ./setup-selinux-protection.sh
The script performs the following actions:
- Verifies SELinux is enabled.
- Installs required packages.
- Creates and compiles the SELinux policy module.
- Labels the MinIO AIStor binary and data directories.
- Creates a hardened systemd service.
- Validates the protection is working.
Manual setup
For manual installation or customization, follow these steps.
Create the SELinux policy module
Create a file named minio_storage.te:
policy_module(minio_storage, 1.0.0)
require {
type unconfined_t;
type user_t;
type sysadm_t;
type init_t;
class dir { add_name create getattr ioctl link lock open read remove_name rename reparent rmdir search setattr unlink watch watch_reads write };
class file { append create getattr ioctl link lock map open read rename setattr unlink write };
}
# Define MinIO domain
type minio_t;
type minio_exec_t;
type minio_data_t;
# MinIO binary type
files_type(minio_exec_t)
# MinIO data directories type
files_type(minio_data_t)
# Allow MinIO domain to be entered from init
init_daemon_domain(minio_t, minio_exec_t)
domain_type(minio_t)
# MinIO process has FULL access to minio_data_t
allow minio_t minio_data_t:dir { add_name create getattr ioctl link lock open read remove_name rename reparent rmdir search setattr unlink watch watch_reads write };
allow minio_t minio_data_t:file { append create getattr ioctl link lock map open read rename setattr unlink write };
# All other processes can ONLY read, CANNOT delete or write
allow unconfined_t minio_data_t:dir { getattr open read search };
allow unconfined_t minio_data_t:file { getattr open read };
allow user_t minio_data_t:dir { getattr open read search };
allow user_t minio_data_t:file { getattr open read };
allow sysadm_t minio_data_t:dir { getattr open read search };
allow sysadm_t minio_data_t:file { getattr open read };
# MinIO network access
corenet_tcp_bind_generic_node(minio_t)
corenet_tcp_connect_http_port(minio_t)
corenet_tcp_bind_http_port(minio_t)
corenet_tcp_bind_generic_port(minio_t)
corenet_udp_bind_generic_port(minio_t)
# MinIO system permissions
kernel_read_system_state(minio_t)
dev_read_urand(minio_t)
fs_getattr_xattr_fs(minio_t)
files_read_etc_files(minio_t)
miscfiles_read_localization(minio_t)
sysnet_dns_name_resolve(minio_t)
# Allow MinIO to execute itself
allow minio_t minio_exec_t:file { execute execute_no_trans getattr map open read };
Compile and install the policy
# Compile the policy module
checkmodule -M -m -o minio_storage.mod minio_storage.te
# Package the module
semodule_package -o minio_storage.pp -m minio_storage.mod
# Install the policy module
semodule -i minio_storage.pp
# Verify installation
semodule -l | grep minio_storage
Label the MinIO AIStor binary
# Set file context for MinIO AIStor binary
semanage fcontext -a -t minio_exec_t "/usr/local/bin/minio"
# Apply the label
restorecon -v /usr/local/bin/minio
# Verify the label
ls -Z /usr/local/bin/minio
The output should show system_u:object_r:minio_exec_t:s0.
Label data directories
For each drive that MinIO AIStor manages:
# Add file context rules for each drive
semanage fcontext -a -t minio_data_t "/drive1(/.*)?"
semanage fcontext -a -t minio_data_t "/drive2(/.*)?"
semanage fcontext -a -t minio_data_t "/drive3(/.*)?"
semanage fcontext -a -t minio_data_t "/drive4(/.*)?"
# Apply labels recursively
restorecon -R -v /drive1 /drive2 /drive3 /drive4
# Verify labels
ls -Z /drive1
The output should show system_u:object_r:minio_data_t:s0.
Verify SELinux protection
Test that protection is working:
# Create a test file (as MinIO AIStor or with proper context)
sudo -u minio-user touch /drive1/test-file
# Try to delete as root (should fail)
sudo rm /drive1/test-file
# Expected: rm: cannot remove '/drive1/...': Permission denied
Check that processes are running in the correct SELinux domain:
# Check MinIO AIStor process context
ps -eZ | grep minio
# Expected: system_u:system_r:minio_t:s0
# Check file contexts
ls -Z /drive1
# Expected: system_u:object_r:minio_data_t:s0
eBPF LSM-based protection
Use eBPF LSM-based storage protection on Ubuntu, Debian, and other distributions without SELinux.
Prerequisites
- AIStor-compatible Linux kernel with eBPF LSM support.
CONFIG_BPF_LSM=ykernel configuration.lsm=...,bpfkernel boot parameter.- Root access for installation.
Check kernel support:
# Check kernel version
uname -r
# Check if eBPF LSM is enabled
cat /sys/kernel/security/lsm | grep -q bpf && echo "Supported" || echo "Not supported"
# Check kernel configuration (if available)
grep CONFIG_BPF_LSM /boot/config-$(uname -r)
Enable eBPF LSM
If eBPF LSM is not in the LSM list, enable it via kernel boot parameters.
Install required packages
Automated setup
Use the setup script for automatic installation:
curl -O https://raw.githubusercontent.com/miniohq/eos/master/scripts/setup-ebpf-protection.sh
chmod +x setup-ebpf-protection.sh
sudo ./setup-ebpf-protection.sh
The script performs the following actions:
- Checks kernel support for eBPF LSM.
- Installs required dependencies.
- Builds the eBPF program and userspace loader.
- Installs the binary to
/usr/local/bin/minio-protect. - Creates and starts a systemd service.
- Validates the installation.
Manual setup
For manual installation or customization, follow these steps.
Verify kernel support
# Check eBPF LSM support
if ! cat /sys/kernel/security/lsm | grep -q bpf; then
echo "eBPF LSM not enabled - add 'bpf' to kernel boot parameters"
exit 1
fi
echo "Kernel support: OK"
Build the eBPF program
cd scripts/ebpf
# Generate vmlinux.h (kernel data structures)
bpftool btf dump file /sys/kernel/btf/vmlinux format c > vmlinux.h
# Build using Makefile
make clean build
# Verify binary was created
ls -lh minio-protect
Install the binary
# Install to system path
sudo install -m 755 minio-protect /usr/local/bin/
# Test installation
/usr/local/bin/minio-protect check
Create the systemd service
Create /etc/systemd/system/minio-protect.service:
[Unit]
Description=MinIO AIStor Storage Protection (eBPF)
Documentation=man:minio-protect(8)
DefaultDependencies=no
Before=minio.service
After=local-fs.target
[Service]
Type=simple
ExecStart=/usr/local/bin/minio-protect
Restart=always
RestartSec=5s
# Security hardening
NoNewPrivileges=yes
PrivateTmp=yes
ProtectSystem=strict
ProtectHome=yes
# Requires root for eBPF
User=root
Group=root
[Install]
WantedBy=multi-user.target
Enable and start the service
sudo systemctl daemon-reload
sudo systemctl enable minio-protect
sudo systemctl start minio-protect
sudo systemctl status minio-protect
Verify eBPF protection
Test that protection is working:
# Create a test file
sudo touch /drive1/test-file
# Try to delete as root (should fail)
sudo rm /drive1/test-file
# Expected: rm: cannot remove '/drive1/test-file': Operation not permitted
# Verify file still exists
ls -l /drive1/test-file
Check service status:
# Service status
sudo systemctl status minio-protect
# View logs
sudo journalctl -u minio-protect -f
# Check if MinIO AIStor processes are being tracked
sudo journalctl -u minio-protect | grep "Tracking MinIO process"
How eBPF protection works
The minio-protect daemon automatically:
- Scans for MinIO AIStor processes every 5 seconds.
- Identifies processes by binary name containing “minio”.
- Adds the process ID to the eBPF map of allowed processes.
- Tracks child processes spawned by MinIO AIStor.
- Removes stale process IDs when processes exit.
By default, the protection covers directories matching:
/drive[0-9]+/*(for example, /drive1, /drive2)/data[0-9]+/*(for example, /data1, /data2)
The eBPF LSM hooks intercept:
unlink()- File deletionrmdir()- Directory deletionrename()- Moving files out of protected directories
Troubleshooting
MinIO AIStor cannot start
If MinIO AIStor fails to start after enabling protection:
MinIO AIStor cannot write to drives
If MinIO AIStor cannot write to protected drives:
Protection not blocking root
If root can still delete files:
Security considerations
Defense in depth
Storage hardening is one layer of defense. Implement additional measures:
- Regular backups to separate storage
- Filesystem snapshots (ZFS, Btrfs, LVM)
- Restricted SSH access with key-based authentication
- Multi-factor authentication for administrative access
- Monitoring for unauthorized access attempts
Limitations
Both implementations have known limitations:
| Limitation | Mitigation |
|---|---|
| Root can disable the protection service | Monitor service status, use systemd protections |
| Root can change kernel parameters via reboot | Use TPM/UEFI Secure Boot to protect boot parameters |
| Direct block device access bypasses filesystem | Use disk encryption, monitor block device access |