Hướng dẫn cài đặt và cấu hình NFS Server trên Fedora: Chia sẻ thư mục trong mạng nội bộ an toàn với SELinux và firewalld

Fedora tutorial - IT technology blog
Fedora tutorial - IT technology blog

Cài NFS Server trong 5 phút (Quick Start)

Mình chạy NFS trên Fedora server để chia sẻ thư mục /data cho team dev khoảng 6 người, mỗi sáng mount vào từ máy cá nhân. Bước setup ban đầu chỉ cần vài lệnh:

# Cài NFS server
sudo dnf install nfs-utils -y

# Tạo thư mục chia sẻ
sudo mkdir -p /srv/nfs/shared
sudo chmod 755 /srv/nfs/shared

# Khai báo exports
echo "/srv/nfs/shared 192.168.1.0/24(rw,sync,no_subtree_check)" | sudo tee -a /etc/exports

# Khởi động và enable dịch vụ
sudo systemctl enable --now nfs-server

# Reload exports
sudo exportfs -ra

Nếu đang test trên mạng nội bộ tin cậy, thử mount từ client ngay để xem kết nối được chưa. Nhưng với Fedora mặc định — SELinux Enforcing và firewalld đều bật sẵn — bỏ qua hai phần tiếp theo thì gần như chắc chắn sẽ ngồi debug cả buổi mà mount vẫn không lên.

Giải thích chi tiết từng bước

1. NFS hoạt động như thế nào

Cài xong, bạn có ba daemon cốt lõi: rpc.nfsd nhận và xử lý kết nối từ client, rpc.mountd lo phần mount requests, rpcbind làm port mapper giữa chúng. Kiểm tra trạng thái ngay sau khi start:

sudo systemctl status nfs-server
sudo showmount -e localhost    # xem danh sách exports hiện tại

2. Cú pháp /etc/exports

File /etc/exports là nơi bạn khai báo thư mục nào chia sẻ, cho host nào, với quyền gì. Vài ví dụ thực tế:

# Chia sẻ read-write cho cả subnet
/srv/nfs/shared  192.168.1.0/24(rw,sync,no_subtree_check)

# Chia sẻ read-only cho một máy cụ thể
/srv/nfs/docs    192.168.1.100(ro,sync)

# Chia sẻ với nhiều host, quyền khác nhau
/srv/nfs/public  192.168.1.0/24(rw,sync) 10.0.0.5(ro,sync)

Mấy option quan trọng cần nắm:

  • rw / ro: read-write hoặc read-only
  • sync: ghi xuống disk trước khi phản hồi client — an toàn hơn async
  • no_subtree_check: tắt subtree checking, giảm lỗi khi file bị rename trong lúc client đang mở
  • all_squash: map tất cả UID/GID về nfsnobody — phù hợp khi không muốn user client có quyền thật
  • no_root_squash: root client = root server, chỉ dùng khi thật sự cần và hiểu rõ rủi ro

Sau mỗi lần sửa file này, reload bằng:

sudo exportfs -ra
sudo exportfs -v    # xem exports kèm options đang active

3. Cấu hình firewalld

Đây là bước hay bị bỏ qua nhất. NFS cần mở nhiều service hơn bạn nghĩ — không phải chỉ port 2049:

# Mở các service cần thiết cho NFS
sudo firewall-cmd --permanent --add-service=nfs
sudo firewall-cmd --permanent --add-service=rpc-bind
sudo firewall-cmd --permanent --add-service=mountd

sudo firewall-cmd --reload

# Xác nhận
sudo firewall-cmd --list-services

Nếu muốn giới hạn chỉ cho subnet nội bộ thay vì mở toàn bộ, dùng zone internal:

sudo firewall-cmd --permanent --zone=internal --add-service=nfs
sudo firewall-cmd --permanent --zone=internal --add-service=rpc-bind
sudo firewall-cmd --permanent --zone=internal --add-service=mountd
sudo firewall-cmd --permanent --zone=internal --add-source=192.168.1.0/24
sudo firewall-cmd --reload

4. SELinux — Không khó như bạn nghĩ

Mình từng có thói quen setenforce 0 để tắt SELinux cho xong việc nhanh. Sau vài lần đọc về các vụ breach trên server production do security defaults bị tắt, mình bỏ thói quen đó hẳn. Với NFS, chỉ cần bật đúng vài boolean là xong:

# Xem tất cả boolean liên quan NFS
getsebool -a | grep nfs

# Cho phép export read-write và read-only
sudo setsebool -P nfs_export_all_rw 1
sudo setsebool -P nfs_export_all_ro 1

# Nếu client mount NFS để dùng làm home directory
sudo setsebool -P use_nfs_home_dirs 1

Nếu thư mục chia sẻ không nằm trong /srv/nfs (ví dụ bạn dùng /data/shared), cần gán SELinux context đúng:

# Gán context NFS cho thư mục custom
sudo semanage fcontext -a -t nfs_t "/data/shared(/.*)?" 
sudo restorecon -Rv /data/shared

# Kiểm tra context đã đúng chưa
ls -lZ /data/shared

Khi gặp “Permission denied” dù đã cấu hình firewall đúng, đây là lệnh đầu tiên mình chạy:

sudo ausearch -m avc -ts recent | tail -30

Nâng cao: Cố định ports và NFS v4

Cố định ports để firewall rules hoạt động ổn định

Mặc định, rpc.mountdnlockmgr dùng port dynamic — thay đổi sau mỗi lần restart, khiến firewall rules bị vô hiệu sau khi reboot. Cố định chúng trong /etc/nfs.conf:

sudo nano /etc/nfs.conf
[mountd]
port=892

[lockd]
port=32803
udp-port=32769

[statd]
port=662

Mở thêm các port này trong firewall rồi restart:

sudo firewall-cmd --permanent --add-port=892/tcp
sudo firewall-cmd --permanent --add-port=892/udp
sudo firewall-cmd --permanent --add-port=32803/tcp
sudo firewall-cmd --permanent --add-port=32769/udp
sudo firewall-cmd --permanent --add-port=662/tcp
sudo firewall-cmd --permanent --add-port=662/udp
sudo firewall-cmd --reload
sudo systemctl restart nfs-server

Mount từ client

# Cài client tools trên máy client
sudo dnf install nfs-utils -y

# Test mount thủ công
sudo mount -t nfs 192.168.1.10:/srv/nfs/shared /mnt/test
df -h /mnt/test
ls -la /mnt/test

# Unmount sau khi test
sudo umount /mnt/test

Để mount tự động khi boot, thêm vào /etc/fstab:

192.168.1.10:/srv/nfs/shared  /mnt/shared  nfs  defaults,_netdev  0 0

Option _netdev quan trọng hơn bạn nghĩ — nó báo systemd chờ network sẵn sàng trước khi mount. Thiếu option này, máy client có thể treo ở boot nếu NFS server chưa lên kịp.

Tips thực tế sau 6 tháng chạy production

Theo dõi clients đang kết nối:

sudo showmount -a              # danh sách client đang mount
sudo nfsstat -s                # server statistics
sudo nfsstat -c                # client statistics (chạy ở máy client)

Xử lý UID/GID mismatch — tình huống này gặp thường hơn tưởng: user trên server và client có UID khác nhau, mount lên rồi nhưng vẫn bị permission denied mà không rõ tại sao:

# Xem UID của user hiện tại
id username

# Giải pháp: map tất cả về UID/GID cố định
/srv/nfs/shared 192.168.1.0/24(rw,sync,all_squash,anonuid=1000,anongid=1000)

Dùng NFS v4.2 để có tính năng mới nhất (sparse file support, server-side copy, improved security):

sudo mount -t nfs -o vers=4.2 192.168.1.10:/srv/nfs/shared /mnt/shared

# Xác nhận version đang dùng
cat /proc/mounts | grep nfs

Backup exports trước khi thử nghiệm:

sudo cp /etc/exports /etc/exports.bak.$(date +%Y%m%d)

Kiểm tra NFS version server hỗ trợ:

cat /proc/fs/nfsd/versions
# Output: +2 +3 +4 +4.1 +4.2

# Disable NFS v2 nếu không cần (giảm attack surface)
echo "-2" | sudo tee /proc/fs/nfsd/versions

Mình dùng Fedora làm máy development chính đã 2 năm và khá hài lòng với tốc độ cập nhật package. NFS trên Fedora trông phức tạp hơn distro khác vì SELinux và firewalld. Nhưng đó chính xác là lý do setup này vững hơn — hai lớp bảo vệ mặc định mà nhiều distro không có. Dành thêm 20 phút cấu hình đúng từ đầu sẽ tiết kiệm nhiều giờ debug sau.

Share: