はじめに
この記事は、Linux サーバ間で NFS 共有フォルダをマウントしているものの、「cp: cannot create regular file '...': Permission denied」や「rsync: mkstemp failed: Operation not permitted (1)」といったエラーでファイルがコピーできずに困っているシステム管理者・エンジニアを対象にしています。
記事を読み終えると、NFS の「権限エラー」の本質的な原因である UID/GID の不一致を見極め、idmapd・anonuid/anongid・Squash 設定を正しく調整して、マウント先にスムーズにファイルをコピーできるようになります。
前提知識
- Linux の基本コマン(mount, cp, rsync, chmod, chown)が使える
/etc/exportsでの NFS エクスポート設定経験- UID/GID、chmod ビット、mask 計算の意味をある程度理解している
なぜ NFS だけ「パーミッション denied」が出やすいのか
NFS(Network File System)は、サーバ側のファイルシステムを「まるでローカルディスクのように」見せるプロトコルです。しかし、「見せ方」は UID/GID の数字そのまでなため、次の 2 つの条件が揃うと書き込めなくなります。
- クライアント側のユーザー UID ≠ サーバ側の所有者 UID
- サーバ側で「all_squash」や「root_squash」が有効で、匿名 UID(通常は 65534=nobody)に強制されている
結果、クライアント側で root や一般ユーザーがファイルを作成しようとしても、サーバ側では「nobody」として処理され、ディレクトリのパーミッションが 755 だと書き込めず「Permission denied」が出るというわけです。
切り分けから解決まで:実践編
ステップ1:現状の UID/GID を確認する
まず、クライアントとサーバの両方で、操作したいユーザーと共有ディレクトリの所有者を確認します。
Bash# クライアント側 $ id kazu uid=1005(kazu) gid=1005(kazu) groups=1005(kazu) # サーバ側 $ id kazu uid=2005(kazu) gid=2005(kaz) groups=2005(kazu) $ ls -ld /export/share drwxr-xr-x 2 kazu 2005 4096 Jun 1 14:00 /export/share
この例では、UID が 1005 ≠ 2005 で不一致です。これが「コピーできない」根本原因です。
ステップ2:サーバ側の /etc/exports を読み解く
次に、サーバ側のエクスポート設定を確認しましょう。
/export/share 192.0.2.0/24(rw,async,no_subtree_check,all_squash,anonuid=99,anongid=99)
all_squash:「誰が来ても匿名ユーザーに強制」anonuid/anongid=99:匿名ユーザーを 99(nobody)に固定
この状態でクライアントが「kazu(UID1005)」として接続しても、サーバ側では「UID99」で書き込もうとするため、ディレクトリの owner が 2005 では書き込めない、という構図です。
ステップ3:ID マッピングデーモン(idmapd)を使う(推奨)
UID/GID の数字を揃えられない場合(大規模 LDAP 環境など)は、ID マッピングで解決します。
- サーバ・クライアント両方で
/etc/idmapd.confを編集
[General]
Domain = local.domain
[Mapping]
Nobody-User = nobody
Nobody-Group = nogroup
- サービスを再起動
Bash# CentOS/RHEL sudo systemctl restart nfs-idmapd # Ubuntu/Debian sudo systemctl restart nfs-common
/etc/exportsでall_squashを外し、代わりにroot_squashのみ残す
/export/share 192.0.2.0/24(rw,async,no_subtree_check,root_squash)
- マウントし直すと、クライアント UID1005 → サーバ UID1005 のまま接続できるため、書き込み可能になります。
ステップ4:数字を揃えるのが早い場合(小規模環境)
LDAP や中央認証を使っていない小規模環境なら、UID/GID を単純に揃えるのが最速です。
Bash# サーバ側 $ sudo usermod -u 1005 kazu $ sudo groupmod -g 1005 kazu $ sudo find /export -user 2005 -exec chown -h 1005:1005 {} \;
マウントし直して cp してみると、今度はエラーなくコピーできます。
ステップ5: Squash 設定を見直す(root 書き込みが必要な場合)
バックアップスクリプトなど、root で書き込みたいケースでは、以下のどちらかを選びます。
- セキュリティ重視:
root_squash維持+ anonuid=0(root)にして、root に書き込ませる - 完全信任:
no_root_squash設定(LAN 内のみ推奨)
# 例:no_root_squash(完全信任)
/export/share 192.0.2.0/24(rw,async,no_subtree_check,no_root_squash)
ハマりポイント:マウントオプション「vers」も影響する
NFSv4 以降では ID マッピングが必須ですが、クライアントが「vers=3」でマウントしていると idmapd が効かないことがあります。マウントオプションを見直しましょう。
Bash$ sudo mount -t nfs -o vers=4,sec=sys server:/export/share /mnt
解決策まとめ
- UID/GID の不一致を「
idコマンド」で可視化する /etc/exportsのall_squashとanonuid/anongidの組み合わせを見直す- 大規模環境 → idmapd 利用、小規模環境 → UID/GID 揃える
- root 書き込みが必要 →
no_root_squashまたは anonuid=0 - 念のため NFS バージョン(vers=3/4)も確認
まとめ
本記事では、Linux で「NFS マウント先にファイルがコピーできない」問題の真の原因である UID/GID の不一致を特定し、
- idmapd を使った ID マッピング
- UID/GID 数字揃え
- all_squash / root_squash / no_root_squash の使い分け
という 3 パターンの解決策を紹介しました。
正しく設定すれば、今まで「Permission denied」で断念していたバッチもバックアップも、スムーズに動作します。
次回は「NFSv4 + Kerberos 認証」でセキュアな環境を構築する方法を解説予定です。
参考資料
- Red Hat Customer Portal – NFS idmapd Configuration
- Ubuntu Manpage – exports(5)
- 「基礎から学ぶ Linux ファイルシステム & ストレージ入門」株式会社翔泳社 (2023)
