概要
タイトルの通り、Ubuntu24.04にEFSのファイルシステムをマウントして利用する方法を備忘録として残します。
今回実装する構成は以下の通りです。
- UbuntuからはEFSマウントヘルパーを使用してファイルシステムをマウント
- マウントポイントを使用し、ファイルシステム内の「/App」をルートディレクトリとしてマウント
- IAM認証を使用し、クライアント(Ubuntu)からのアクセスを制御
Ubuntu24.04は執筆時点(2025/3/13)で検証されていませんが試していきます。
EFSについて
NFSによる共有ファイルシステムストレージをサーバーレスで提供するフルマネージドサービスです。
Linux OSのEC2やオンプレミスのサーバーから利用でき、ファイルシステムの簡単な作成・管理が可能で、ストレージは自動拡張・縮小してくれます。
マウント方式
マウント方式は「標準の Linux NFS クライアント」「EFS マウントヘルパー」の二つです。
ファイルシステムを作成すると親切に各方式でのマウントコマンドを提供してくれます。
後述するマウントポイントを作成した場合、マウントポイント毎のマウントコマンドが提供されます
NFSクライアントでのマウントオプションはAWS推奨の値となっています。
どちらの方式を選ぶかは自由ではありますが、基本EFSマウントヘルパーでのマウントがおススメです。
公式でもおススメされていますし、後述するIAM認証またはアクセスポイントを利用する場合はEFSマウントヘルパーの利用が必須です。
EFS ファイルシステムをマウントするには、EFS マウントヘルパーを使用することをお勧めします。
EFS マウントヘルパーを使用することによってのみ、EFS アクセスポイントを使用して EFS ファイルシステムをマウントできます。
IAM 認可を使用してクライアントによるアクセスをコントロールするには、EFS マウントヘルパーを使用して Amazon EFS ファイルシステムをマウントする必要があります。
アクセスポイント
ファイルシステム内のディレクトリに対するアクセス制限をするための機能です。
アクセスポイント毎に「対象のルートディレクトリ」「POSIXユーザー」「POSIXグループ」を設定します。
クライアント(接続元)はアクセスポイントに対してマウントを実施し、アクセスポイント経由でファイルの作成・閲覧・削除を行います。
アクセスポイント経由で作成したファイルは、アクセスポイントに設定したPOSIXユーザー及びグループの権限となります。
つまり、クライアントによらない権限の設定が可能になります。
NFSクライアントでマウントした場合は、EFSファイルシステムの/
(ルートディレクトリ)をマウントすることになります。その場合の 権限はroot:root 0755
となります。
また、ファイルシステムにアクセスする際の権限は接続元ユーザーの権限になるためデフォルトではrootユーザー以外の書き込みができない状態です。
仮にマウントポイントを/
に設定した場合でも、書き込む際の権限は設定したPOSIXユーザー・グループの権限になるため書き込みができません。
どうしてもという場合は、/
の権限を変更する必要があります。
ちなみに、Security HubコントロールのEFS.3ではアクセスポイントで/
を利用することは非推奨です。
Path の値が / (ファイルシステムのデフォルトのルートディレクトリ) に設定されていると、このコントロールは失敗します。
IAM認証
アイデンティティベースポリシー(IAMポリシー)もしくはファイルシステムポリシー(バケットポリシーのようなリソースベースポリシー)を使った、ファイルシステムに対するアクセスを制御をするための機能です。
バケットポリシーと同じ考え方で、どちらか一方で許可されていれば指定したアクションが許可されます。
ファイルシステム作成時のファイルシステムポリシーは何も記載されていないので(フルアクセス許可)、ファイルシステムには匿名のクライアントからアクセスすることが可能です。そのため、デフォルトではマウントターゲットに紐づけるセキュリティグループでのIP制限のみとなります。
ちなみに、ファイルシステムポリシーで制御できるActionは以下3つです。
Action | 概要 |
---|---|
elasticfilesystem:ClientMount | ファイルシステムへの読み取り専用アクセス |
elasticfilesystem:ClientWrite | ファイルシステムへの書き込みアクセス |
elasticfilesystem:ClientRootAccess | rootユーザーを使用したファイルシステムへのアクセス |
実践
それでは実際にEC2からEFSファイルシステムをマウントしていきます。
環境はGitHubで公開しています。
各コードとデプロイ方法を用意してますのでお試しください。
EFSの設定
ファイルシステムポリシー
ファイルシステムポリシーは以下の通りです。
- 1つ目のStatementで、EC2のIAMロール(iam-role-ec2)からマウントターゲット経由でのみ、「rootユーザーの使用」「書き込み」「読み込み」を許可しています
- 2つ目のStatementで、クライアントからファイルシステムへの接続にTLSを強制しています
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowEFSAccess",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::[AccountID]:role/iam-role-ec2"
},
"Action": [
"elasticfilesystem:ClientRootAccess",
"elasticfilesystem:ClientWrite",
"elasticfilesystem:ClientMount"
],
"Resource": "*",
"Condition": {
"Bool": {
"elasticfilesystem:AccessedViaMountTarget": "true"
}
}
},
{
"Sid": "DenyNotTls",
"Effect": "Deny",
"Principal": {
"AWS": "*"
},
"Action": "*",
"Resource": "*",
"Condition": {
"Bool": {
"aws:SecureTransport": "false"
}
}
}
]
}
アクセスポイント
ルートディレクトリパス
ルートディレクトリパスは/App
としています。
POSIXユーザーID・POSIXグループID
ユーザーIDは1500
、グループIDは1500
としています。
今回セカンダリグループIDは未設定です。
[セカンダリグループIDの利用用途]
ファイルシステム内のディレクトリが階層構造(親子関係)となっている際、
子側のディレクトリ内に、親側のPOSIXユーザーからのファイル操作を許可したい場合などが考えられます。
子側のアクセスポイントのセカンダリグループIDに、親側のPOSIXグループIDを設定することで実現します。
ルートディレクトリ作成のアクセス許可
設定は以下の通りです。
この機能は、ルートディレクトリパス
で指定したディレクトリがファイルシステム内に無い場合に、指定したユーザーID/グループID/権限でディレクトリを作成してくれる機能となります。
手動で作成済みの場合は不要ですし、その場合に本設定で指定した値に上書きされることはありません。
ただし存在しない場合に指定していないとマウントエラーになります。
アクセスポイントのルートディレクトリがマウント時間前にすでに存在する場合、既存のアクセス許可はアクセスポイントによって上書きされません。
Amazon EFS では、OwnUid、OwnGID、およびパーミッションがディレクトリに指定されている場合にのみ、アクセスポイントルートディレクトリが作成されます。この情報を指定しない場合、Amazon EFS はルートディレクトリを作成しません。ルートディレクトリが存在しない場合に、アクセスポイントを使用してマウントしようとすると、失敗します。
クライアントの設定
EFSマウントヘルパーインストール
Ubuntu24.04にEFSマウントヘルパーをインストールしていきます。
EFSマウントヘルパーが含まれるamazon-efs-utils
パッケージは、Amazon Linux AMIリポジトリで公開されています。
つまり、Amazon Linux以外のLinux OSはbuildする必要があります。
そのため、GitHubのREADMEを参考にbuildしていきます。
パッケージリスト更新
$ sudo apt-get update
Hit:1 http://ap-northeast-1.ec2.archive.ubuntu.com/ubuntu noble InRelease
Hit:2 http://ap-northeast-1.ec2.archive.ubuntu.com/ubuntu noble-updates InRelease
Hit:3 http://ap-northeast-1.ec2.archive.ubuntu.com/ubuntu noble-backports InRelease
Hit:4 http://security.ubuntu.com/ubuntu noble-security InRelease
Reading package lists... Done
必要なパッケージインストール
$ sudo apt-get -y install git binutils rustc cargo pkg-config libssl-dev gettext
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
~省略~
Running kernel seems to be up-to-date.
Restarting services...
/etc/needrestart/restart.d/systemd-manager
systemctl restart acpid.service chrony.service cron.service irqbalance.service multipathd.service packagekit.service polkit.service rsyslog.service systemd-journald.service systemd-networkd.service systemd-resolved.service systemd-udevd.service udisks2.service
Service restarts being deferred:
systemctl restart ModemManager.service
/etc/needrestart/restart.d/dbus.service
systemctl restart getty@tty1.service
systemctl restart networkd-dispatcher.service
systemctl restart serial-getty@ttyS0.service
systemctl restart snap.amazon-ssm-agent.amazon-ssm-agent.service
systemctl restart systemd-logind.service
systemctl restart unattended-upgrades.service
No containers need to be restarted.
No user sessions are running outdated binaries.
No VM guests are running outdated hypervisor (qemu) binaries on this host.
リポジトリClone
$ cd && git clone https://github.com/aws/efs-utils
Cloning into 'efs-utils'...
remote: Enumerating objects: 1864, done.
remote: Counting objects: 100% (395/395), done.
remote: Compressing objects: 100% (127/127), done.
remote: Total 1864 (delta 315), reused 273 (delta 265), pack-reused 1469 (from 3)
Receiving objects: 100% (1864/1864), 907.76 KiB | 13.75 MiB/s, done.
Resolving deltas: 100% (1176/1176), done.
build
$ cd efs-utils && ./build-deb.sh
+ pwd
+ BASE_DIR=/home/ssm-user/efs-utils
+ BUILD_ROOT=/home/ssm-user/efs-utils/build/debbuild
+ VERSION=2.2.1
+ RELEASE=1
+ dpkg --print-architecture
+ ARCH=amd64
+ DEB_SYSTEM_RELEASE_PATH=/etc/os-release
+ export VERSION RELEASE ARCH
+ echo Cleaning deb build workspace
Cleaning deb build workspace
+ rm -rf /home/ssm-user/efs-utils/build/debbuild
+ mkdir -p /home/ssm-user/efs-utils/build/debbuild
+ echo Creating application directories
Creating application directories
+ mkdir -p /home/ssm-user/efs-utils/build/debbuild/etc/amazon/efs
+ mkdir -p /home/ssm-user/efs-utils/build/debbuild/etc/init/
+ mkdir -p /home/ssm-user/efs-utils/build/debbuild/etc/systemd/system
+ mkdir -p /home/ssm-user/efs-utils/build/debbuild/sbin
+ mkdir -p /home/ssm-user/efs-utils/build/debbuild/usr/bin
+ mkdir -p /home/ssm-user/efs-utils/build/debbuild/var/log/amazon/efs
+ mkdir -p /home/ssm-user/efs-utils/build/debbuild/usr/share/man/man8
+ echo Building efs-proxy
Building efs-proxy
+ cd src/proxy
+ cargo build --release --manifest-path /home/ssm-user/efs-utils/src/proxy/Cargo.toml
~省略~
+ DEB=/home/ssm-user/efs-utils/build/debbuild/amazon-efs-utils-2.2.1-1_amd64.deb
+ ar r /home/ssm-user/efs-utils/build/debbuild/amazon-efs-utils-2.2.1-1_amd64.deb /home/ssm-user/efs-utils/build/debbuild/debian-binary
ar: creating /home/ssm-user/efs-utils/build/debbuild/amazon-efs-utils-2.2.1-1_amd64.deb
+ ar r /home/ssm-user/efs-utils/build/debbuild/amazon-efs-utils-2.2.1-1_amd64.deb /home/ssm-user/efs-utils/build/debbuild/control.tar.gz
+ ar r /home/ssm-user/efs-utils/build/debbuild/amazon-efs-utils-2.2.1-1_amd64.deb /home/ssm-user/efs-utils/build/debbuild/data.tar.gz
+ echo Copying deb to output directory
Copying deb to output directory
+ cp /home/ssm-user/efs-utils/build/debbuild/amazon-efs-utils-2.2.1-1_amd64.deb build/
amazon-efs-utilsパッケージインストール
$ sudo apt-get -y install ./build/amazon-efs-utils*deb
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Note, selecting 'amazon-efs-utils' instead of './build/amazon-efs-utils-2.2.1-1_amd64.deb'
~省略~
Running kernel seems to be up-to-date.
Restarting services...
Service restarts being deferred:
/etc/needrestart/restart.d/dbus.service
systemctl restart getty@tty1.service
systemctl restart networkd-dispatcher.service
systemctl restart serial-getty@ttyS0.service
systemctl restart systemd-logind.service
systemctl restart unattended-upgrades.service
No containers need to be restarted.
No user sessions are running outdated binaries.
No VM guests are running outdated hypervisor (qemu) binaries on this host.
N: Download is performed unsandboxed as root as file '/home/ssm-user/efs-utils/build/amazon-efs-utils-2.2.1-1_amd64.deb' couldn't be accessed by user '_apt'. - pkgAcquire::Run (13: Permission denied)
インストール済み確認
$ dpkg -l | grep amazon-efs-utils
ii amazon-efs-utils 2.2.1-1 amd64 This package provides utilities for simplifying the use of EFS file systems
アクセスポイントのマウント
アクセスポイントページ画面右上のアタッチ
を押すと、当該アクセスポイントへのEFSマウントヘルパーを使ったマウントコマンドが表示されます。こちらのコマンドを今回の要件に合わせてオプションやマウント先ディレクトリを修正してマウントしていきます。
今回は以下の条件に合わせてマウントしていきます。
- tlsでの接続
- IAM認証での接続
-
ssm-user
の/home/ssm-user/efs
にマウント
$ id
uid=1001(ssm-user) gid=1001(ssm-user) groups=1001(ssm-user)
$
$
$ cd && mkdir efs && ls -al
total 36
drwxr-x--- 5 ssm-user ssm-user 4096 Mar 13 06:46 .
drwxr-xr-x 4 root root 4096 Mar 13 05:26 ..
-rw-r--r-- 1 ssm-user ssm-user 220 Mar 31 2024 .bash_logout
-rw-r--r-- 1 ssm-user ssm-user 3771 Mar 31 2024 .bashrc
drwxr-xr-x 3 ssm-user ssm-user 4096 Mar 13 05:43 .cargo
-rw------- 1 ssm-user ssm-user 20 Mar 13 05:59 .lesshst
-rw-r--r-- 1 ssm-user ssm-user 807 Mar 31 2024 .profile
drwxr-xr-x 2 ssm-user ssm-user 4096 Mar 13 06:46 efs
drwxr-xr-x 10 ssm-user ssm-user 4096 Mar 13 05:43 efs-utils
$
$
$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/root 6.8G 3.7G 3.1G 55% /
tmpfs 3.9G 0 3.9G 0% /dev/shm
tmpfs 1.6G 892K 1.6G 1% /run
tmpfs 5.0M 0 5.0M 0% /run/lock
efivarfs 128K 4.1K 119K 4% /sys/firmware/efi/efivars
/dev/nvme0n1p16 881M 76M 744M 10% /boot
/dev/nvme0n1p15 105M 6.1M 99M 6% /boot/efi
$
# ファイルシステムID及びアクセスポイントIDは環境に合わせて修正
$ sudo mount -t efs -o tls,iam,accesspoint=fsap-XXXX fs-XXXX:/ /home/ssm-user/efs
/home/ssm-user/efs is already mounted, please run 'mount' command to verify
$
$
$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/root 6.8G 4.1G 2.7G 61% /
tmpfs 3.9G 0 3.9G 0% /dev/shm
tmpfs 1.6G 976K 1.6G 1% /run
tmpfs 5.0M 0 5.0M 0% /run/lock
efivarfs 128K 4.1K 119K 4% /sys/firmware/efi/efivars
/dev/nvme0n1p16 881M 133M 687M 17% /boot
/dev/nvme0n1p15 105M 6.1M 99M 6% /boot/efi
127.0.0.1:/ 8.0E 0 8.0E 0% /home/ssm-user/efs
マウントしたディレクトリはルートディレクトリのアクセス許可
で設定した権限になっていますね。
$ ls -al
total 36
drwxr-x--- 5 ssm-user ssm-user 4096 Mar 13 06:46 .
drwxr-xr-x 4 root root 4096 Mar 13 05:26 ..
-rw-r--r-- 1 ssm-user ssm-user 220 Mar 31 2024 .bash_logout
-rw-r--r-- 1 ssm-user ssm-user 3771 Mar 31 2024 .bashrc
drwxr-xr-x 3 ssm-user ssm-user 4096 Mar 13 05:43 .cargo
-rw------- 1 ssm-user ssm-user 20 Mar 13 05:59 .lesshst
-rw-r--r-- 1 ssm-user ssm-user 807 Mar 31 2024 .profile
drwxr-xr-x 2 1500 1500 6144 Mar 13 06:47 efs
drwxr-xr-x 10 ssm-user ssm-user 4096 Mar 13 05:43 efs-utils
再起動後も自動マウントするために/etc/fstab
に設定を追記します。
# ファイルシステムID及びアクセスポイントIDは環境に合わせて修正
fs-XXXX:/ /home/ssm-user/efs efs defaults_netdev,noresvport,tls,iam,accesspoint=fsap-XXXX 0 0
動作確認
実際にファイルをマウントした/home/ssm-user/efs
ディレクトリに作成してみます。
作成したファイルはPOSIXユーザー
で設定したUID/GIDになっていますね。
$ id && pwd && ls -al
uid=1001(ssm-user) gid=1001(ssm-user) groups=1001(ssm-user)
/home/ssm-user
total 36
drwxr-x--- 5 ssm-user ssm-user 4096 Mar 13 07:13 .
drwxr-xr-x 4 root root 4096 Mar 13 05:26 ..
-rw-r--r-- 1 ssm-user ssm-user 220 Mar 31 2024 .bash_logout
-rw-r--r-- 1 ssm-user ssm-user 3771 Mar 31 2024 .bashrc
drwxr-xr-x 3 ssm-user ssm-user 4096 Mar 13 05:43 .cargo
-rw------- 1 ssm-user ssm-user 20 Mar 13 05:59 .lesshst
-rw-r--r-- 1 ssm-user ssm-user 807 Mar 31 2024 .profile
drwxr-xr-x 2 1500 1500 6144 Mar 13 07:13 efs
drwxr-xr-x 10 ssm-user ssm-user 4096 Mar 13 05:43 efs-utils
$
$
$ touch efs/test.txt
$
$
$ ls -al efs
total 12
drwxr-xr-x 2 1500 1500 6144 Mar 13 07:14 .
drwxr-x--- 5 ssm-user ssm-user 4096 Mar 13 07:13 ..
-rw-r--r-- 1 1500 1500 0 Mar 13 07:14 test.txt
まとめ
今回、Ubuntu24.04にEFSマウントヘルパーを使用してEFSファイルシステムをマウントしました。
冒頭でも記載したように公式ではUbuntu24.04の検証がされていないという状況なので、
本番運用での使用は要検討かと思いますが、一応動きはするという結果になりました。
この記事が誰かの役に立てば幸いです。