SiamCafe.net Blog
Technology

NFS v4 Kerberos สำหรับมือใหม่ Step by Step

nfs v4 kerberos สำหรบมอใหม step by step
NFS v4 Kerberos สำหรับมือใหม่ Step by Step | SiamCafe Blog
2026-05-16· อ. บอม — SiamCafe.net· 1,530 คำ

NFS v4 Kerberos สำหรับมือใหม่คืออะไร

NFS v4 (Network File System version 4) เป็นโปรโตคอลสำหรับแชร์ไฟล์ผ่านเครือข่าย ใช้กันแพร่หลายในระบบ Linux/Unix Kerberos เป็นโปรโตคอล authentication ที่ใช้ tickets แทน passwords ช่วยเพิ่มความปลอดภัย การรวม NFS v4 กับ Kerberos ช่วยให้การแชร์ไฟล์มี strong authentication, encryption และ data integrity ป้องกัน man-in-the-middle attacks และ unauthorized access เหมาะสำหรับองค์กรที่ต้องการ secure file sharing

NFS v4 vs NFS v3

# nfs_comparison.py — NFS v4 vs v3
import json

class NFSComparison:
    COMPARISON = {
        "security": {"v3": "AUTH_SYS (UID/GID only, weak)", "v4": "Kerberos (krb5, krb5i, krb5p)"},
        "firewall": {"v3": "หลาย ports (111, 2049, random)", "v4": "Port 2049 เท่านั้น"},
        "protocol": {"v3": "UDP + TCP", "v4": "TCP only"},
        "statefulness": {"v3": "Stateless", "v4": "Stateful (locking built-in)"},
        "acl": {"v3": "ไม่รองรับ NFSv4 ACLs", "v4": "รองรับ rich ACLs (Windows-compatible)"},
        "idmapping": {"v3": "UID/GID mapping", "v4": "user@domain string mapping"},
        "performance": {"v3": "ดี", "v4": "ดีกว่า (compound operations, delegation)"},
    }

    KERBEROS_MODES = {
        "krb5": {
            "name": "krb5 (Authentication Only)",
            "description": "ยืนยันตัวตนด้วย Kerberos ticket",
            "encryption": "ไม่เข้ารหัส data",
            "performance": "เร็วที่สุด",
            "use_case": "Trusted network, ต้องการแค่ authentication",
        },
        "krb5i": {
            "name": "krb5i (Authentication + Integrity)",
            "description": "ยืนยันตัวตน + ตรวจสอบว่า data ไม่ถูกแก้ไขระหว่างทาง",
            "encryption": "Integrity checksum (ไม่เข้ารหัส content)",
            "performance": "ปานกลาง",
            "use_case": "ป้องกัน man-in-the-middle tampering",
        },
        "krb5p": {
            "name": "krb5p (Authentication + Integrity + Privacy)",
            "description": "ยืนยันตัวตน + integrity + เข้ารหัส data ทั้งหมด",
            "encryption": "Full encryption (AES-256)",
            "performance": "ช้าที่สุด (CPU overhead จาก encryption)",
            "use_case": "Sensitive data, untrusted network",
        },
    }

    def show_comparison(self):
        print("=== NFS v4 vs v3 ===\n")
        for key, vals in self.COMPARISON.items():
            print(f"  {key:<14} v3: {vals['v3'][:35]:<38} v4: {vals['v4']}")

    def show_kerberos_modes(self):
        print(f"\n=== Kerberos Modes ===\n")
        for key, mode in self.KERBEROS_MODES.items():
            print(f"[{mode['name']}]")
            print(f"  {mode['description']}")
            print(f"  Encryption: {mode['encryption']}")
            print(f"  Performance: {mode['performance']}")
            print()

comp = NFSComparison()
comp.show_comparison()
comp.show_kerberos_modes()

ขั้นตอนการติดตั้ง KDC Server

# kdc_setup.py — Kerberos KDC Server setup
import json

class KDCSetup:
    STEPS = """
# Step 1: ติดตั้ง Kerberos KDC (Key Distribution Center)
# Server: kdc.example.com

# Install packages
sudo apt install krb5-kdc krb5-admin-server -y  # Debian/Ubuntu
sudo yum install krb5-server krb5-libs -y        # RHEL/CentOS

# Step 2: Configure /etc/krb5.conf
[libdefaults]
    default_realm = EXAMPLE.COM
    dns_lookup_realm = false
    dns_lookup_kdc = false

[realms]
    EXAMPLE.COM = {
        kdc = kdc.example.com
        admin_server = kdc.example.com
    }

[domain_realm]
    .example.com = EXAMPLE.COM
    example.com = EXAMPLE.COM

# Step 3: Create Kerberos database
sudo kdb5_util create -s -r EXAMPLE.COM

# Step 4: Create admin principal
sudo kadmin.local -q "addprinc admin/admin@EXAMPLE.COM"

# Step 5: Start services
sudo systemctl enable --now krb5-kdc
sudo systemctl enable --now krb5-admin-server
"""

    PRINCIPALS = """
# Create principals for NFS
sudo kadmin.local

# NFS server principal
addprinc -randkey nfs/nfs-server.example.com@EXAMPLE.COM

# NFS client principal
addprinc -randkey nfs/nfs-client.example.com@EXAMPLE.COM

# User principals
addprinc user1@EXAMPLE.COM
addprinc user2@EXAMPLE.COM

# Export keytabs
ktadd -k /tmp/nfs-server.keytab nfs/nfs-server.example.com@EXAMPLE.COM
ktadd -k /tmp/nfs-client.keytab nfs/nfs-client.example.com@EXAMPLE.COM

# Copy keytabs to respective servers
scp /tmp/nfs-server.keytab nfs-server:/etc/krb5.keytab
scp /tmp/nfs-client.keytab nfs-client:/etc/krb5.keytab
"""

    def show_steps(self):
        print("=== KDC Setup ===")
        print(self.STEPS[:600])

    def show_principals(self):
        print(f"\n=== Create Principals ===")
        print(self.PRINCIPALS[:500])

kdc = KDCSetup()
kdc.show_steps()
kdc.show_principals()

NFS Server & Client Configuration

# nfs_config.py — NFS v4 Kerberos configuration
import json

class NFSConfig:
    SERVER_SETUP = """
# NFS Server Setup (nfs-server.example.com)

# Step 1: Install packages
sudo apt install nfs-kernel-server nfs-common -y

# Step 2: Copy krb5.conf from KDC
sudo scp kdc:/etc/krb5.conf /etc/krb5.conf

# Step 3: Copy keytab
# (keytab should already be at /etc/krb5.keytab)
sudo klist -k /etc/krb5.keytab  # Verify

# Step 4: Configure /etc/exports
/shared    *(sec=krb5p, rw, sync, no_subtree_check, root_squash)
/data      10.0.0.0/24(sec=krb5i, rw, sync, no_subtree_check)
/public    *(sec=krb5, ro, sync)

# Step 5: Enable ID mapping
echo "Domain = example.com" >> /etc/idmapd.conf

# Step 6: Configure /etc/default/nfs-common
NEED_GSSD=yes

# Step 7: Start services
sudo systemctl enable --now nfs-server
sudo systemctl enable --now rpc-gssd
sudo exportfs -rav
"""

    CLIENT_SETUP = """
# NFS Client Setup (nfs-client.example.com)

# Step 1: Install packages
sudo apt install nfs-common -y

# Step 2: Copy krb5.conf from KDC
sudo scp kdc:/etc/krb5.conf /etc/krb5.conf

# Step 3: Copy keytab
# (keytab should already be at /etc/krb5.keytab)

# Step 4: Enable ID mapping
echo "Domain = example.com" >> /etc/idmapd.conf

# Step 5: Configure /etc/default/nfs-common
NEED_GSSD=yes

# Step 6: Start gssd
sudo systemctl enable --now rpc-gssd

# Step 7: Mount NFS share
sudo mkdir -p /mnt/shared
sudo mount -t nfs4 -o sec=krb5p nfs-server.example.com:/shared /mnt/shared

# Step 8: Verify
mount | grep nfs4
ls -la /mnt/shared

# Step 9: fstab (persistent mount)
echo "nfs-server:/shared /mnt/shared nfs4 sec=krb5p,_netdev 0 0" >> /etc/fstab
"""

    def show_server(self):
        print("=== NFS Server Setup ===")
        print(self.SERVER_SETUP[:600])

    def show_client(self):
        print(f"\n=== NFS Client Setup ===")
        print(self.CLIENT_SETUP[:600])

config = NFSConfig()
config.show_server()
config.show_client()

Troubleshooting

# troubleshooting.py — Common NFS Kerberos issues
import json
import random

class NFSTroubleshooting:
    COMMON_ISSUES = {
        "clock_skew": {
            "error": "Clock skew too great",
            "cause": "เวลาระหว่าง KDC, server, client ต่างกัน > 5 นาที",
            "fix": "ติดตั้ง NTP: sudo apt install chrony && sudo systemctl enable --now chronyd",
        },
        "keytab": {
            "error": "No Kerberos credentials available",
            "cause": "Keytab ไม่ถูกต้องหรือไม่มี principal ที่ต้องการ",
            "fix": "ตรวจ: klist -k /etc/krb5.keytab, สร้างใหม่: kadmin → ktadd",
        },
        "dns": {
            "error": "Cannot resolve hostname",
            "cause": "DNS ไม่ resolve hostname ถูกต้อง (forward + reverse)",
            "fix": "ตั้ง DNS: A record + PTR record, หรือ /etc/hosts",
        },
        "gssd": {
            "error": "mount.nfs4: Operation not permitted",
            "cause": "rpc-gssd service ไม่ทำงาน",
            "fix": "sudo systemctl restart rpc-gssd && journalctl -u rpc-gssd",
        },
        "permission": {
            "error": "Permission denied",
            "cause": "User ไม่มี Kerberos ticket หรือ UID mapping ผิด",
            "fix": "kinit user@EXAMPLE.COM && klist, ตรวจ idmapd.conf",
        },
    }

    DEBUG_COMMANDS = [
        "klist                         # ดู Kerberos tickets",
        "klist -k /etc/krb5.keytab     # ดู keytab entries",
        "kinit user@EXAMPLE.COM        # ขอ ticket ใหม่",
        "rpcdebug -m nfs -s all        # Enable NFS debug",
        "rpcdebug -m rpc -s all        # Enable RPC debug",
        "journalctl -u rpc-gssd -f     # ดู gssd logs",
        "journalctl -u nfs-server -f   # ดู NFS server logs",
        "showmount -e nfs-server       # ดู exports",
        "nfsstat -s                    # NFS server statistics",
    ]

    def show_issues(self):
        print("=== Common Issues ===\n")
        for key, issue in self.COMMON_ISSUES.items():
            print(f"[{issue['error']}]")
            print(f"  Cause: {issue['cause']}")
            print(f"  Fix: {issue['fix']}")
            print()

    def show_debug(self):
        print("=== Debug Commands ===")
        for cmd in self.DEBUG_COMMANDS[:6]:
            print(f"  $ {cmd}")

ts = NFSTroubleshooting()
ts.show_issues()
ts.show_debug()

Automation Script

# automation.py — NFS Kerberos automation
import json
import random

class NFSAutomation:
    ANSIBLE_PLAYBOOK = """
# nfs-kerberos.yml — Ansible playbook
---
- name: Setup NFS v4 Kerberos
  hosts: nfs_servers
  become: yes
  vars:
    realm: EXAMPLE.COM
    domain: example.com
    kdc_host: kdc.example.com
    exports:
      - path: /shared
        options: "*(sec=krb5p, rw, sync, no_subtree_check)"

  tasks:
    - name: Install NFS packages
      apt:
        name: [nfs-kernel-server, nfs-common, krb5-user]
        state: present

    - name: Configure krb5.conf
      template:
        src: krb5.conf.j2
        dest: /etc/krb5.conf

    - name: Copy keytab
      copy:
        src: "keytabs/{{ inventory_hostname }}.keytab"
        dest: /etc/krb5.keytab
        mode: '0600'

    - name: Configure idmapd
      lineinfile:
        path: /etc/idmapd.conf
        regexp: '^#?Domain'
        line: "Domain = {{ domain }}"

    - name: Configure exports
      template:
        src: exports.j2
        dest: /etc/exports
      notify: reload nfs

    - name: Enable services
      systemd:
        name: "{{ item }}"
        enabled: yes
        state: started
      loop:
        - nfs-server
        - rpc-gssd

  handlers:
    - name: reload nfs
      command: exportfs -rav
"""

    def show_playbook(self):
        print("=== Ansible Playbook ===")
        print(self.ANSIBLE_PLAYBOOK[:600])

    def health_check(self):
        print(f"\n=== NFS Health Check ===")
        checks = [
            {"check": "KDC service", "status": "OK"},
            {"check": "NTP sync (< 5 min skew)", "status": "OK"},
            {"check": "Keytab valid", "status": "OK"},
            {"check": "rpc-gssd running", "status": "OK"},
            {"check": "NFS exports active", "status": "OK"},
            {"check": "Kerberos ticket valid", "status": random.choice(["OK", "WARN: expires in 2h"])},
        ]
        for c in checks:
            print(f"  [{c['status']:>25}] {c['check']}")

auto = NFSAutomation()
auto.show_playbook()
auto.health_check()

FAQ - คำถามที่พบบ่อย

Q: krb5, krb5i, krb5p เลือกอันไหนดี?

A: krb5: เร็วที่สุด แต่ data ไม่ encrypted (trusted LAN) krb5i: กลางๆ ป้องกัน data tampering (แนะนำสำหรับ most cases) krb5p: ปลอดภัยที่สุด data encrypted ทั้งหมด (sensitive data, untrusted network) เริ่มด้วย krb5i → upgrade เป็น krb5p ถ้าต้องการ encryption

Q: NFS v4 Kerberos ช้ากว่า NFS v3 ไหม?

A: krb5: ใกล้เคียง v3 (overhead เฉพาะ authentication) krb5i: ช้ากว่า 5-10% (checksum computation) krb5p: ช้ากว่า 20-40% (encryption/decryption) Tips: ใช้ AES-256 (เร็วกว่า DES), NIC ที่รองรับ hardware offload

Q: ต้องมี DNS server ไหม?

A: แนะนำอย่างยิ่ง Kerberos ต้องการ forward + reverse DNS ที่ถูกต้อง ถ้าไม่มี DNS: ใช้ /etc/hosts ได้ แต่จัดการยากเมื่อ scale ปัญหาที่พบบ่อยที่สุดของ Kerberos = DNS configuration ผิด

Q: NFS v4 Kerberos ใช้กับ Windows ได้ไหม?

A: ได้ Windows มี NFS client built-in (Services for NFS) Active Directory = Kerberos KDC อยู่แล้ว Cross-realm trust ระหว่าง Linux KDC กับ AD ได้ NFSv4 ACLs compatible กับ Windows ACLs

📖 บทความที่เกี่ยวข้อง

MySQL Window Functions สำหรับมือใหม่ Step by Stepอ่านบทความ → Uptime Kuma Monitoring สำหรับมือใหม่ Step by Stepอ่านบทความ → GraphQL Federation สำหรับมือใหม่ Step by Stepอ่านบทความ → PHP Symfony สำหรับมือใหม่ Step by Stepอ่านบทความ → Elixir Phoenix LiveView สำหรับมือใหม่ Step by Stepอ่านบทความ →

📚 ดูบทความทั้งหมด →