FedoraでNFS Serverをインストール・設定する:SELinuxとfirewalldを使ってLAN内で安全にディレクトリを共有する

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

NFS Serverを5分でインストール(クイックスタート)

FedoraサーバーでNFSを運用し、/dataディレクトリをdevチームの約6名で共有しています。毎朝それぞれの端末からマウントして使っています。初期セットアップに必要なコマンドはわずかです:

# NFS serverのインストール
sudo dnf install nfs-utils -y

# 共有ディレクトリの作成
sudo mkdir -p /srv/nfs/shared
sudo chmod 755 /srv/nfs/shared

# exportsの定義
echo "/srv/nfs/shared 192.168.1.0/24(rw,sync,no_subtree_check)" | sudo tee -a /etc/exports

# サービスの起動とenable
sudo systemctl enable --now nfs-server

# exportsのリロード
sudo exportfs -ra

信頼できる社内ネットワークでテスト中であれば、クライアントからすぐにマウントして接続確認してみてください。ただし、FedoraはデフォルトでSELinux EnforcingとfirewalldがどちらもONになっているため、次の2つのセクションを飛ばすと、ほぼ確実に半日デバッグしてもマウントできないという状況に陥ります。

各ステップの詳細解説

1. NFSの仕組み

インストールが完了すると、3つのコアデーモンが起動します。rpc.nfsdはクライアントからの接続を受け付けて処理し、rpc.mountdはマウントリクエストを担当し、rpcbindがそれらの間でポートマッパーとして機能します。起動直後の状態確認:

sudo systemctl status nfs-server
sudo showmount -e localhost    # 現在のexportリストを確認

2. /etc/exportsの書き方

/etc/exportsは、どのディレクトリをどのホストにどの権限で共有するかを定義するファイルです。実際の例をいくつか示します:

# サブネット全体にread-write共有
/srv/nfs/shared  192.168.1.0/24(rw,sync,no_subtree_check)

# 特定のマシンにread-only共有
/srv/nfs/docs    192.168.1.100(ro,sync)

# 複数のホストに異なる権限で共有
/srv/nfs/public  192.168.1.0/24(rw,sync) 10.0.0.5(ro,sync)

押さえておくべき重要なオプションをまとめます:

  • rw / ro:read-writeまたはread-only
  • sync:クライアントへの応答前にディスクへ書き込む — asyncより安全
  • no_subtree_check:subtreeチェックを無効化し、クライアントが開いているファイルがリネームされた際のエラーを減らす
  • all_squash:すべてのUID/GIDをnfsnobodyにマッピング — クライアントユーザーに実際の権限を与えたくない場合に適している
  • no_root_squash:クライアントのrootはサーバーのrootと同等。本当に必要でリスクを十分理解している場合のみ使用

このファイルを編集したら毎回、以下でリロードします:

sudo exportfs -ra
sudo exportfs -v    # アクティブなオプションを含めてexportを表示

3. firewalldの設定

最もよく見落とされるステップです。NFSはポート2049だけでなく、思っている以上に多くのサービスを開放する必要があります:

# 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

# 確認
sudo firewall-cmd --list-services

全体に開放するのではなく、社内サブネットのみに制限したい場合は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 — 思ったより難しくない

以前はsetenforce 0SELinuxを無効化してさっさと終わらせる習慣がありました。しかし、セキュリティのデフォルト設定を無効にしたことで発生したproductionサーバーへの侵害事例をいくつか読んでからは、その習慣を完全にやめました。NFSの場合、適切なbooleanをいくつかONにするだけで解決します:

# NFS関連のbooleanをすべて表示
getsebool -a | grep nfs

# read-writeおよびread-onlyエクスポートを許可
sudo setsebool -P nfs_export_all_rw 1
sudo setsebool -P nfs_export_all_ro 1

# クライアントがNFSをホームディレクトリとしてマウントする場合
sudo setsebool -P use_nfs_home_dirs 1

共有ディレクトリが/srv/nfs以外の場所(例:/data/shared)にある場合、正しいSELinuxコンテキストを設定する必要があります:

# カスタムディレクトリにNFSコンテキストを設定
sudo semanage fcontext -a -t nfs_t "/data/shared(/.*)?" 
sudo restorecon -Rv /data/shared

# コンテキストが正しく設定されているか確認
ls -lZ /data/shared

ファイアウォールの設定が正しいのに「Permission denied」が出る場合、まず次のコマンドを実行します:

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

応用編:ポートの固定とNFS v4

firewall rulesを安定させるためのポート固定

デフォルトでは、rpc.mountdnlockmgrは動的ポートを使用するため、再起動のたびに変化し、リブート後にfirewall rulesが無効になります。/etc/nfs.confで固定しましょう:

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

[lockd]
port=32803
udp-port=32769

[statd]
port=662

これらのポートをファイアウォールに追加してから再起動します:

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

クライアントからマウント

# クライアントマシンにclientツールをインストール
sudo dnf install nfs-utils -y

# 手動マウントのテスト
sudo mount -t nfs 192.168.1.10:/srv/nfs/shared /mnt/test
df -h /mnt/test
ls -la /mnt/test

# テスト後にアンマウント
sudo umount /mnt/test

起動時に自動マウントするには、/etc/fstabに追加します:

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

_netdevオプションは思った以上に重要です。これはsystemdにネットワークの準備ができてからマウントするよう指示します。このオプションがないと、NFSサーバーがまだ起動していない場合にクライアントマシンが起動時にハングする可能性があります。

6ヶ月のproduction運用から得た実践的なTips

接続中のクライアントを監視:

sudo showmount -a              # マウント中のクライアント一覧
sudo nfsstat -s                # サーバー統計
sudo nfsstat -c                # クライアント統計(クライアントマシンで実行)

UID/GID不一致の対処 — これは思っている以上によく起こります。サーバーとクライアントで同じユーザーのUIDが異なり、マウントできていても理由不明のpermission deniedが発生するケースです:

# 現在のユーザーのUIDを確認
id username

# 解決策:すべてを固定のUID/GIDにマッピング
/srv/nfs/shared 192.168.1.0/24(rw,sync,all_squash,anonuid=1000,anongid=1000)

NFS v4.2の使用で最新機能(sparse fileサポート、サーバーサイドコピー、セキュリティ強化)を活用:

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

# 使用中のバージョンを確認
cat /proc/mounts | grep nfs

実験前にexportsをバックアップ:

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

サーバーがサポートするNFSバージョンを確認:

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

# 不要なNFS v2を無効化(攻撃対象領域を縮小)
echo "-2" | sudo tee /proc/fs/nfsd/versions

Fedoraをメインの開発マシンとして2年間使っていますが、パッケージの更新速度には満足しています。FedoraのNFSは、SELinuxとfirewalldのせいで他のディストリビューションより複雑に見えます。しかしそれこそがこのセットアップが堅牢な理由です。多くのディストリビューションにはないデフォルトの2層の保護があります。最初に20分かけて正しく設定しておけば、後のデバッグに費やす何時間もの時間を節約できます。

Share: