NFSの背景とセキュリティ上の課題
5台のWebサーバー群が合計500GBのメディアストレージに対して同時に読み書きを行うケースを想像してみてください。各サーバーに個別に保存するとディスク容量が無駄になり、rsyncなどで常時同期するとネットワーク帯域を圧迫しデータの不整合も発生しやすくなります。
NFSはこの課題をスマートに解決します。リモートサーバー上のディレクトリをローカルマシンに直接マウントできるため、アプリケーションはネットワーク越しであることを意識せず、内蔵ストレージと全く同じようにファイルの読み書きが可能です。
しかし、従来のNFSプロトコルには重大なセキュリティリスクが存在します。デフォルトのsec=sysモードでは、サーバーはクライアントから送信されるIPアドレスとUIDを盲信してしまいます。攻撃者が社内スイッチに見知らぬノートPCを接続し、IPを偽装してrootユーザー(UID 0)を作成するだけで、共有データ全体を消去できてしまう危険性があります。
セキュリティを担保するには、NFSv4とKerberos認証(sec=krb5pオプション)の併用が不可欠です。この仕組みにより、マウント前に有効な認証チケットの提示を義務付けると同時に、AES暗号化によってネットワークを流れる全データを暗号化し、パケット盗聴のリスクを根本から遮断するという2重の防御が実現します。
検証環境とインストール
今回の検証構成は、同一内部ネットワーク内の2台のLinuxマシンを使用します。
- NFS Server:
192.168.1.10(hostname:nfs-server.lab.local) - NFS Client:
192.168.1.20(hostname:nfs-client.lab.local) - KDC Domain:
LAB.LOCAL
重要な注意点: 2台のマシン間で時刻のズレが300秒(5分)を超えると、Kerberosはすべての認証チケットを拒絶します。必ずchronyまたはsystemd-timesyncdサービスが稼働し、時刻同期が正確に行われていることを確認してください。また、サーバーとクライアントの双方で正引きおよび逆引き(PTRレコード)のDNS名前解決が正常に動作している必要があります。
1. NFSサーバーでのインストール
Ubuntu/Debian環境では、リポジトリを更新して必要なパッケージをインストールします。
sudo apt update
sudo apt install -y nfs-kernel-server krb5-user
RHELやAlmaLinux 9を使用している場合:
sudo dnf install -y nfs-utils krb5-workstation
2. クライアントでのインストール
クライアントマシン側でも同様にインストールを行います。
# Ubuntu / Debian
sudo apt update
sudo apt install -y nfs-common krb5-user
# RHEL / AlmaLinux
sudo dnf install -y nfs-utils krb5-workstation
詳細設定手順
1. Kerberosプリンシパルの作成とKeytabのエクスポート
各ノードにはnfs/<FQDN>@REALM形式のサービスプリンシパルが必要です。この情報は/etc/krb5.keytabファイルに保存され、パスワードを入力することなくサーバーとクライアント間で相互認証を行います。
KDCサーバー上でプリンシパルを直接作成します。
# 両ホストのプリンシパルを作成
kadmin.local -q "addprinc -randkey nfs/[email protected]"
kadmin.local -q "addprinc -randkey nfs/[email protected]"
# 各ホスト用のkeytabを個別にエクスポート
kadmin.local -q "ktadd -k /tmp/server.keytab nfs/[email protected]"
kadmin.local -q "ktadd -k /tmp/client.keytab nfs/[email protected]"
各keytabファイルを安全なSCP経由でそれぞれの対象マシンの/etc/krb5.keytabへ転送します。転送後、アクセス権限を厳密に制限します。
sudo chmod 600 /etc/krb5.keytab
sudo chown root:root /etc/krb5.keytab
両方のマシンで/etc/idmapd.conf内のNFSv4マッピングドメインを統一します。
[General]
Domain = lab.local
2. サーバー側の共有ディレクトリ設定
実際の共有ストレージディレクトリを作成し、読み書き権限を設定します。
sudo mkdir -p /srv/nfs_share/project_data
sudo chmod -R 775 /srv/nfs_share/project_data
/etc/exportsファイルに共有ディレクトリのエクスポート設定を記述します。
sudo nano /etc/exports
次の設定行を追加します。
/srv/nfs_share/project_data 192.168.1.0/24(rw,sync,no_subtree_check,sec=krb5p)
各設定オプションの意味:
rw: クライアントに対して読み書き権限を許可します。sync: データが物理ディスクに安全に書き込まれた後でのみ成功応答を返します。予期せぬ停電時などのファイル破損リスクを軽減します。no_subtree_check: 親ディレクトリ階層のチェックを無効化します。これによりファイルアクセスのレスポンスが大幅に向上します。sec=krb5p: 最高レベルのセキュリティモード(Privacy)。パケットヘッダーおよびデータペイロード全体がAESでエンドツーエンド暗号化されます。
エクスポートテーブルを再読み込みし、Kerberos連携の中継を担うrpc-gssdサービスを再起動・有効化します。
sudo exportfs -rav
sudo systemctl restart rpc-gssd
sudo systemctl enable --now nfs-kernel-server
3. クライアントからのマウント
クライアント側でもマウント時にKerberosチケットを処理するため、rpc-gssdデーモンの起動が必須となります。
sudo systemctl enable --now rpc-gssd
マウントポイントを作成し、手動でマウントしてテストを実施します。
sudo mkdir -p /mnt/shared_data
sudo mount -t nfs4 -o sec=krb5p nfs-server.lab.local:/srv/nfs_share/project_data /mnt/shared_data
再起動時にも自動マウントされるよう、/etc/fstabに次のエントリを追加します。
nfs-server.lab.local:/srv/nfs_share/project_data /mnt/shared_data nfs4 sec=krb5p,_netdev,rsize=1048576,wsize=1048576 0 0
_netdevオプションは、ネットワークインターフェースがIPを取得するまでマウント処理を待機させます。このフラグがないと、Linuxの起動プロセスが停止(ハング)する原因になります。
rsize=1048576,wsize=1048576(1MBバッファ)のパラメータ指定は、パフォーマンスに劇的な差をもたらします。1Gbpsネットワーク経由で10GBのtar圧縮ファイルを転送したテストでは、デフォルトバッファの場合35〜40MB/sにとどまりましたが、バッファを1MBに拡張したところ、スループットは上限の112MB/sに達し、ネットワーク帯域の上限まで使い切る結果となりました。
動作確認とパフォーマンス監視
1. 書き込み権限とKerberosチケット機構の検証
マウントされたパーティションの状態を確認します。
df -hT /mnt/shared_data
検証用ユーザーのTGT(チケット授与チケット)を取得し、書き込みテストを行います。
# 個別ユーザーのKerberosチケットを取得
kinit [email protected]
# 共有ディレクトリへのファイル書き込みテスト
echo "NFS Kerberos testing OK" > /mnt/shared_data/test_sync.txt
cat /mnt/shared_data/test_sync.txt
kdestroyコマンドでチケットを破棄した状態で上記ファイルの編集を試みると、システムは即座にPermission deniedエラーを返します。これにより、単なるIPアドレスベースではなく、実際のKerberosチケットセッションによってデータが厳格に保護されていることが実証されます。
2. nfsstatとnfsiostatによるI/Oおよびレイテンシの監視
RPCリクエストの総数とキャッシュの有効性を確認します。
nfsstat -s # サーバー側の統計情報を表示
nfsstat -c # クライアント側の統計情報を表示
クライアントにsysstatパッケージをインストールしてnfsiostatコマンドを使用可能にします。
nfsiostat 2 5
上記コマンドは2秒間隔でメトリクスを収集し、5回分の測定結果を表示します。特に注視すべき3つの主要指標は以下の通りです。
- ops/s: 1秒あたりの読み取り/書き込みリクエスト数。
- kB/s: ネットワークインターフェースを通過する実際のデータ転送レート。
- avg RTT (Round Trip Time): クライアントがRPCリクエストを送信してからサーバーが応答を完了するまでの平均往復時間。
LAN環境においてavg RTTが20msを超えている場合、ストレージシステムのディスクI/O過負荷やネットワークスイッチでのパケットドロップが発生している可能性があります。サーバー側でiostat -xz 1を実行してI/O waitを確認し、ボトルネックの特定を行ってください。

