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
