SiamCafe · Blog
Ceph Storage Cluster Security Hardening
บทความ

Ceph Storage Cluster Security Hardening

เผยแพร่ 28 พฤษภาคม 2569

Ceph Security Hardening

Ceph Storage Cluster Security Hardening CephX Encryption Network Firewall Access Control Audit SELinux dmcrypt TLS ป้องกันแฮก

LayerThreatMitigationPriority
AuthenticationUnauthorized AccessCephX + Least PrivilegeCritical
Encryption (Transit)Traffic Sniffingmsgr2 secure + TLSCritical
Encryption (Rest)Disk Theftdmcrypt + SSE-KMSHigh
NetworkNetwork AttackFirewall + Separate NetworksCritical
Access ControlOver-privilegePer-pool CapabilitiesHigh
AuditUndetected BreachLogging + MonitoringHigh

CephX Authentication

# === CephX Authentication Hardening ===

# สร้าง User เฉพาะ Application (Least Privilege)
# ceph auth get-or-create client.webapp \
#   mon 'allow r' \
#   osd 'allow rw pool=webapp-data' \
#   -o /etc/ceph/ceph.client.webapp.keyring
#
# สร้าง User สำหรับ Backup (Read-only)
# ceph auth get-or-create client.backup \
#   mon 'allow r' \
#   osd 'allow r pool=webapp-data' \
#   -o /etc/ceph/ceph.client.backup.keyring
#
# ตรวจสอบ User ทั้งหมด
# ceph auth ls
#
# ลบ User ที่ไม่ใช้
# ceph auth del client.oldapp
#
# ตั้ง Keyring Permission
# chmod 600 /etc/ceph/ceph.client.webapp.keyring
# chown ceph:ceph /etc/ceph/ceph.client.webapp.keyring
#
# ceph.conf Security Settings
# [global]
# auth_cluster_required = cephx
# auth_service_required = cephx
# auth_client_required = cephx
# cephx_require_signatures = true
# cephx_cluster_require_signatures = true
# cephx_service_require_signatures = true

from dataclasses import dataclass

@dataclass
class CephUser:
    user: str
    mon_cap: str
    osd_cap: str
    purpose: str
    risk: str

users = [
    CephUser("client.admin",
        "allow *", "allow *",
        "Cluster Administration เท่านั้น",
        "CRITICAL - ไม่ใช้กับ Application"),
    CephUser("client.webapp",
        "allow r", "allow rw pool=webapp-data",
        "Application อ่านเขียนเฉพาะ Pool",
        "LOW - จำกัดเฉพาะ Pool"),
    CephUser("client.backup",
        "allow r", "allow r pool=webapp-data",
        "Backup Read-only",
        "LOW - อ่านได้อย่างเดียว"),
    CephUser("client.monitoring",
        "allow r", "allow r",
        "Monitoring ดูสถานะ Cluster",
        "LOW - Read-only ทุก Pool"),
    CephUser("client.rgw.gateway",
        "allow rwx", "allow rwx pool=.rgw.*",
        "RGW Service Account",
        "MEDIUM - จำกัดเฉพาะ RGW Pools"),
]

print("=== Ceph Users (Least Privilege) ===")
for u in users:
    print(f"  [{u.user}] Risk: {u.risk}")
    print(f"    mon: '{u.mon_cap}' | osd: '{u.osd_cap}'")
    print(f"    Purpose: {u.purpose}")

Encryption Configuration

# === Ceph Encryption Setup ===

# Data in Transit - msgr2 secure mode
# ceph.conf:
# [global]
# ms_cluster_mode = secure
# ms_service_mode = secure
# ms_client_mode = secure
# ms_mon_cluster_mode = secure
#
# Dashboard TLS
# ceph dashboard set-ssl-certificate -i dashboard.crt
# ceph dashboard set-ssl-certificate-key -i dashboard.key
# ceph mgr module enable dashboard
#
# RGW TLS (via Beast frontend)
# [client.rgw.gateway]
# rgw_frontends = beast ssl_port=443 ssl_certificate=/etc/ceph/rgw.pem
#
# Data at Rest - OSD dmcrypt
# ceph-volume lvm create --dmcrypt --data /dev/sdb
# # Key stored in Monitor automatically
#
# RGW Server-Side Encryption with Vault
# [client.rgw.gateway]
# rgw_crypt_s3_kms_backend = vault
# rgw_crypt_vault_addr = https://vault.example.com:8200
# rgw_crypt_vault_token = s.xxxxxxxxxxxx
# rgw_crypt_vault_secret_engine = kv
# rgw_crypt_vault_prefix = /v1/secret/data

@dataclass
class EncryptionConfig:
    layer: str
    method: str
    config: str
    key_management: str

encryption = [
    EncryptionConfig("Data in Transit (Cluster)",
        "msgr2 Secure Mode",
        "ms_cluster_mode = secure",
        "CephX Keys (automatic)"),
    EncryptionConfig("Data in Transit (Client)",
        "msgr2 Secure Mode",
        "ms_client_mode = secure",
        "CephX Keys (automatic)"),
    EncryptionConfig("Data at Rest (OSD)",
        "LUKS/dmcrypt",
        "ceph-volume lvm create --dmcrypt",
        "Keys in Monitor Keyring"),
    EncryptionConfig("Data at Rest (RGW)",
        "SSE-KMS (Vault)",
        "rgw_crypt_s3_kms_backend = vault",
        "HashiCorp Vault KMS"),
    EncryptionConfig("Dashboard",
        "TLS Certificate",
        "ceph dashboard set-ssl-certificate",
        "PKI / Let's Encrypt"),
    EncryptionConfig("RGW API",
        "TLS (Beast SSL)",
        "rgw_frontends = beast ssl_port=443",
        "PKI / Let's Encrypt"),
]

print("=== Encryption Configuration ===")
for e in encryption:
    print(f"  [{e.layer}] {e.method}")
    print(f"    Config: {e.config}")
    print(f"    Key: {e.key_management}")

Network & Firewall

# === Network Security & Firewall Rules ===

# Firewall Rules (firewalld)
# # Monitor nodes
# firewall-cmd --zone=ceph --add-port=3300/tcp --permanent  # msgr2
# firewall-cmd --zone=ceph --add-port=6789/tcp --permanent  # msgr1
#
# # OSD nodes
# firewall-cmd --zone=ceph --add-port=6800-7300/tcp --permanent
#
# # Dashboard
# firewall-cmd --zone=mgmt --add-port=8443/tcp --permanent
#
# # RGW
# firewall-cmd --zone=public --add-port=443/tcp --permanent
#
# # Restrict source IPs
# firewall-cmd --zone=ceph --add-source=10.0.0.0/24 --permanent
# firewall-cmd --reload
#
# ceph.conf Network Separation
# [global]
# public_network = 10.0.1.0/24
# cluster_network = 10.0.2.0/24

@dataclass
class FirewallRule:
    service: str
    port: str
    zone: str
    source: str
    note: str

rules = [
    FirewallRule("Monitor (msgr2)", "3300/tcp",
        "ceph", "10.0.0.0/24 (Ceph nodes + Clients)",
        "จำกัดเฉพาะ Ceph Network"),
    FirewallRule("Monitor (msgr1)", "6789/tcp",
        "ceph", "10.0.0.0/24",
        "Legacy protocol ปิดถ้าใช้ msgr2 อย่างเดียว"),
    FirewallRule("OSD", "6800-7300/tcp",
        "cluster", "10.0.2.0/24 (Cluster Network only)",
        "เปิดเฉพาะ Cluster Network ไม่เปิด Public"),
    FirewallRule("Dashboard", "8443/tcp",
        "mgmt", "10.0.100.0/24 (Management Network)",
        "เข้าผ่าน VPN หรือ Bastion Host เท่านั้น"),
    FirewallRule("RGW (S3 API)", "443/tcp",
        "public", "Application Subnet",
        "ผ่าน Load Balancer + WAF ถ้าเปิด Public"),
]

print("=== Firewall Rules ===")
for r in rules:
    print(f"  [{r.service}] Port: {r.port}")
    print(f"    Zone: {r.zone} | Source: {r.source}")
    print(f"    Note: {r.note}")

เคล็ดลับ

  • Least Privilege: สร้าง User เฉพาะ Application สิทธิ์น้อยที่สุด
  • Network: แยก Public กับ Cluster Network เสมอ
  • dmcrypt: เปิด dmcrypt ทุก OSD ป้องกัน Disk Theft
  • Vault: ใช้ HashiCorp Vault สำหรับ KMS ไม่เก็บ Key ใน Config
  • Update: อัพเดท Ceph Security Patches ทันเวลา

Ceph Security Hardening คืออะไร

เสริมความปลอดภัย Ceph CephX Encryption Network Firewall Access Control Audit SELinux dmcrypt TLS Vault ป้องกันแฮก ทุก Layer

อ่านเพิ่ม: Fail2ban ป้องกัน Brute Force บน Linux Server · อ่านเพิ่ม: MinIO S3 Compatible Storage self-hosted ทดแทน AWS S3 · อ่านเพิ่ม: Linux Server Hardening Checklist 2026 ทำให้ Server ปลอดภัย