Armadilloフォーラム

FTPサーバのホームディレクトリをUSBメモリにする方法

k.sato

2024年1月15日 9時41分

佐藤です。

お世話になっております。

以前、フォーラムで「FTP サーバの構築(ABOS)」の質問をしております。
https://armadillo.atmark-techno.com/forum/armadillo/17264

現在のコンテナの環境はalpineで
FTPのログインユーザーを管理するのにバーチャルユーザを教えていただき使用しています。
https://blog.asial.co.jp/1028/

●/etc/vsftpd/vsftpd.confは下記を追加しています。

# Linuxアカウントユーザーでのログインを許可
local_enable=YES
# 書き込みOK
write_enable=YES
# umask
local_umask=022
# ログインしたユーザーを全て「guest」扱いする
guest_enable=YES
# guest扱いされたユーザーがマッピングされるLinuxアカウント
guest_username=atmark
# バーチャルユーザーにローカルユーザーと同様の権限を与える
virtual_use_local_privs=YES

●Armadillo Base OS:コンテナ内でUSBメモリやSDカードを使用する方法
https://armadillo.atmark-techno.com/blog/15349/13918

FTPのログインユーザーをatmarkとしたので、上記を参考にapp.confに追加しました。
add_volumes /var/app/volumes/usb:/home/atmark

この追加によりFFFTPからUSBメモリの内容を取得しファイルのダウンロードはできました。
しかしFFFTPからファイルをアップロードすると「553 Could not create file. 」のエラーで失敗します。
add_volumes /var/app/volumes/usb:/home/atmark」をコメントアウトするとアップロードできます。
これは何か権限が足りないのでしょうか?
/home/atmarkに書込権限は与えています。

以上、よろしくお願い致します。

コメント

at_makoto.sato

2024年1月15日 18時12分

USBメモリをマウントする時に以下のようにするとどうでしょうか。

armadillo:~# mount -t exfat -o uid=1000,gid=1000 /dev/sda1 /var/app/volumes/usb

k.sato

2024年1月16日 11時29分

佐藤です。

回答ありがとうございます。

> USBメモリをマウントする時に以下のようにするとどうでしょうか。

armadillo:~# mount -t exfat -o uid=1000,gid=1000 /dev/sda1 /var/app/volumes/usb

rulesファイルを修正することで書き込み可能となりました。

armadillo:~# cat /etc/udev/rules.d/99-usb_mem.rules
KERNEL=="sda1",SUBSYSTEM=="block",ACTION=="add", RUN+="/bin/mount -t vfat -o uid=1000,gid=1000 /var/app/volumes/usb"

また、コンテナ起動時にUSBメモリが挿さっているとFFFTPから内容が確認できるのですが、
コンテナ起動後にUSBメモリを挿したとき読めません。

何かいい方法がありましたら教えていただけますか?

at_dominique.m…

2024年1月16日 12時36分

佐藤さん、

横からすみません、
マルティネです。

> rulesファイルを修正することで書き込み可能となりました。

(ちなみに fstab にオプションを設定した方が分かりやすいかもしれません)

> また、コンテナ起動時にUSBメモリが挿さっているとFFFTPから内容が確認できるのですが、
> コンテナ起動後にUSBメモリを挿したとき読めません。

マウントしているディレクトリを変更する必要がありますがボリュームの :shared オプションを使って /var/app/volumes/usb ではなく、一つのディレクトリをはさむと mount がコンテナにもマウントされることもできます

コンテナの /home に atmark 以外のディレクトリが無ければ、以下のでできます。

- baseos 側 (fstab, udev rule)に mount point を /var/app/volumes/usb/atmark に変更
- コンテナ の設定ファイルに 「add_volumes /var/app/volumes/usb:/home/atmark」を「add_volumes /var/app/volumes/usb:/home:shared」に変更
- (podman_start -a か再起動でコンテナリスタート)

いかがでしょうか。

(コンテナの /home に他のディレクトリがある場合は symlink か何か別の方法で工夫が必要です)

よろしくお願いします

k.sato

2024年1月30日 10時57分

マルティネ様

佐藤です。
確認と回答が遅くなり申し訳ございません。

> マウントしているディレクトリを変更する必要がありますがボリュームの :shared オプションを使って /var/app/volumes/usb ではなく、一つのディレクトリをはさむと mount がコンテナにもマウントされることもできます
>
> コンテナの /home に atmark 以外のディレクトリが無ければ、以下のでできます。
コンテナ内の/homeにはatmarkディレクトリしかありません。

> - baseos 側 (fstab, udev rule)に mount point を /var/app/volumes/usb/atmark に変更
/etc/fstab

/dev/sda1       /var/app/volumes/usb/atmark     vfat    noauto                          0 0

/etc/udev/rules.d/99-usb_mem.rules

KERNEL=="sda1",SUBSYSTEM=="block",ACTION=="add", RUN+="/bin/mount /var/app/volumes/usb/atmark"

> - コンテナ の設定ファイルに 「add_volumes /var/app/volumes/usb:/home/atmark」を「add_volumes /var/app/volumes/usb:/home:shared」に変更
/etc/atmark/containers/my_project.conf

add_volumes /var/app/volumes/usb:/home/shared

> - (podman_start -a か再起動でコンテナリスタート)
上記の変更をしてArmadillo-640を再起動しましたが、
ホストの/var/app/volumes/usbにマウントされていないため下記の修正を行い再起動しました。
/etc/atmark/containers/my_project.conf

add_volumes /var/app/volumes/usb/atmark:/home/atmark:shared

すると起動後にUSBメモリを挿入した場合でもFFFTPで接続したときホームディレクトリにUSBメモリの内容が表示されました。
ありがとうございます。

また、このUSBメモリを抜去するときはどういう手順を踏めばよろしいでしょうか?

> > rulesファイルを修正することで書き込み可能となりました。
> (ちなみに fstab にオプションを設定した方が分かりやすいかもしれません)
fstabのオプションの設定方法を教えていただけませんか?

/dev/sda1       /var/app/volumes/usb/atmark     vfat    rw,noauto                          0 0

としてみたのですがファイルのアップロードはできませんでした。

以上、よろしくお願い致します。

at_dominique.m…

2024年2月1日 9時49分

佐藤さん、

マルティネです。

> add_volumes /var/app/volumes/usb:/home/shared
...
> add_volumes /var/app/volumes/usb/atmark:/home/atmark:shared

細かいですが、/var/app/volumes/usb:/home/shared でも /var/app/volumes/usb/atmark:/home/atmark:shared でもなく /var/app/volumes/usb:/home:shared を提案していました。

その 「:shared」の意味は「このディレクトリの中に他のマウントポイントがあれば共有します」という意味ですが、マウントポイント自体は共有されてませんので、たどり着いた実装ではおそらくコンテナ起動後にマウントしてもコンテナでは察知されないと思います。
そのため、わざわざ親ディレクトリで指定していました。

> また、このUSBメモリを抜去するときはどういう手順を踏めばよろしいでしょうか?

これもまた色々ありますので説明すると長くなりますが…
一番安全なのは、どうにかしてアプリケーションに「ハードウェアの安全な取り外し」機能を追加することです。
ftp 等でファイルを書込みした後に安全に書き込まれているかどうかを確認しないと、最後に書き込まれたファイルが故障されるおそれがあります(vfat では journal やファイルシステム全体の安全性を保証する機能もないので、他のファイルまでに影響ある可能性もあります)。
書込みの途中だけではなくて、vsftpd のコードを確認したところ書込みの後に fsync() などの命令を発行しないので、linux がすきなタイミング(デフォルトでは最大30秒後)に実際の USB メモリへ書込みを行います。

そういう機能を追加できれば、umount で USB を取り外す準備を行ってを待ってから安全に取り外せます。

そういう機能を追加できない、よく分からない環境でユーザーがいつでも取り外せるようにしたければ、マウントオプションに「sync」も追加して linux に書込みを送らせないようにする必要があります。それでしたら udev ルールで取り外した際の反応として umount すればいいと思います(実際にアクセス中で故障の可能性ものこりますし、外された場合に umount できなくて、コンテナのリスタートが必要になるかもしれません)

ややっこしくてなんだかすみません…

> > > rulesファイルを修正することで書き込み可能となりました。
> > (ちなみに fstab にオプションを設定した方が分かりやすいかもしれません)
> fstabのオプションの設定方法を教えていただけませんか?
>

> /dev/sda1       /var/app/volumes/usb/atmark     vfat    rw,noauto                          0 0
> 

> としてみたのですがファイルのアップロードはできませんでした。

rw,noauto ではなく、mount -t vfat -o uid=... のオプションを設定していたようですので、fstab にも「uid=1000,gid=1000,noauto」のオプションが必要ではないかと思いますが、どうでしょうか。

よろしくお願いします。

k.sato

2024年2月1日 15時23分

マルティネ様

佐藤です。

> rw,noauto ではなく、mount -t vfat -o uid=... のオプションを設定していたようですので、fstab にも「uid=1000,gid=1000,noauto」のオプションが必要ではないかと思いますが、どうでしょうか。
「uid=1000,gid=1000,noauto」の修正でアップロードできるようになりました。
ありがとうございます。

> 細かいですが、/var/app/volumes/usb:/home/shared でも /var/app/volumes/usb/atmark:/home/atmark:shared でもなく /var/app/volumes/usb:/home:shared を提案していました。
> その 「:shared」の意味は「このディレクトリの中に他のマウントポイントがあれば共有します」という意味ですが、マウントポイント自体は共有されてませんので、たどり着いた実装ではおそらくコンテナ起動後にマウントしてもコンテナでは察知されないと思います。
> そのため、わざわざ親ディレクトリで指定していました。
add_volumes /var/app/volumes/usb:/home:shared
を指定するとFFFTPで接続したときに「/home」がホームディレクトリにマウントされていたようなので変更したのですが、
本日、再度「add_volumes /var/app/volumes/usb:/home:shared」すると「/home/atmark」にマウントされました。
確認ミスしていたと思われます。
申し訳ございません。

USBメモリを抜去するのは結構複雑なのですね。

代わりにmicroSDカードを使用しようと思います。
/etc/fstabに下記を追加し

/dev/mmcblk1p1  /var/app/volumes/sd             ext4    defaults                                         0 0

/etc/atmark/containers/my_project.confへは下記を追加しました。

add_volumes /var/app/volumes/sd:/home/atmark                   #SDを/home/atmarkにマウント

この状態でFFFTPから接続するとmicroSDカードの内容は確認できたのですがファイルアップロードできません。

/dev/mmcblk1p1  /var/app/volumes/sd             ext4    uid=1000,gid=1000,defaults      0 0

USBメモリを書き込めるようにしたように「uid=1000,gid=1000,defaults」と追加したのですが
ls /var/app/volumes/sd」で確認してもmicroSDカードの内容がマウントされていません。

mount」で確認しても「/dev/mmcblk1p1」が存在しませんでした。

オプションの指定方法が間違っているのだと思いますが、
microSDカードをFTPでアップロード可能なようにマウントするとき「/etc/fstab」のオプションはどのようにすればよろしいでしょうか?

以上、よろしくお願い致します。

at_dominique.m…

2024年2月1日 15時37分

k.satoさん、

マルティネです。

> /dev/mmcblk1p1  /var/app/volumes/sd             ext4    uid=1000,gid=1000,defaults      0 0

ext4 に uid/gid のマウントオプションがないですので、こちらのパーティションをマウントするとエラーしますね。
vfat/exfat ではユーザーの情報が記載されてないためにマウントで上書きできますが、ext4 等の場合は最初のマウントで root ユーザーとして chown か chmod をする必要があります。 (mkfs.ext4 の -E root_owner でファイルシステム生成時にも設定できます)

例えば (uid=.. .を fstab から外した後)一度以下のコマンドで準備しておけば書込み出きるようになると思います。

mount /var/app/volumes/sd
chmod 4777 /var/app/volumes/sd

よろしくお願いします。

k.sato

2024年2月1日 16時24分

マルティネ様

佐藤です。

素早い回答ありがとうございます。

> 例えば (uid=.. .を fstab から外した後)一度以下のコマンドで準備しておけば書込み出きるようになると思います。

mount /var/app/volumes/sd
chmod 4777 /var/app/volumes/sd

/etc/fstabはこの状態で上記を行うということでしょうか?

/dev/mmcblk1p1  /var/app/volumes/sd             ext4    defaults                                         0 0
armadillo:/# mount /var/app/volumes/sd/
mount: mounting /dev/mmcblk1p1 on /var/app/volumes/sd failed: Resource busy
armadillo:/# chmod 4777 /var/app/volumes/sd
armadillo:/#

chmod 4777 /var/app/volumes/sd」を実行するとFFFTPでファイルがアップロードできました。

# launch app
#set_command python3 /vol_app/src/main.py
set_command sh /startup.sh

今までmy_project.confで起動コマンドをstartup.shに変更しその中でchmodをしていたのですが、
chmod 4777 /var/app/volumes/sd」はホストのディレクトリなのでエラーしますか?

microSDカードの自動マウント後に「chmod 4777 /var/app/volumes/sd」が行われるようにするにはどこに記述すればよいですか?

at_dominique.m…

2024年2月2日 16時30分

佐藤さん、

マルティネです。

> > 例えば (uid=.. .を fstab から外した後)一度以下のコマンドで準備しておけば書込み出きるようになると思います。
>

> mount /var/app/volumes/sd
> chmod 4777 /var/app/volumes/sd
> 

すみません、"tmp式"の chmod (どのユーザーでもファイルを作れますがオーナーにしかファイルを削除できない)を勘違いしてましたので訂正させてください。
chmod コマンドは「chmod 1777 /var/app/volumes/sd」でした。

本件で特に差はないので、修正してもしなくてもいいですが、参考までに。

> /etc/fstabはこの状態で上記を行うということでしょうか?

はい、一度 chmod を行えばマウント時に設定するオプションはありません。

> # launch app
> #set_command python3 /vol_app/src/main.py
> set_command sh /startup.sh

> 今までmy_project.confで起動コマンドをstartup.shに変更しその中でchmodをしていたのですが、
> 「chmod 4777 /var/app/volumes/sd」はホストのディレクトリなのでエラーしますか?

マウントされてない状態で chmod を実行してもエラーはしませんが、マウントする際に上書きされますので startup.sh に入れなくていいです。

> microSDカードの自動マウント後に「chmod 4777 /var/app/volumes/sd」が行われるようにするにはどこに記述すればよいですか?

ずっと同じ SD カードを使うのであれば、毎回 chmod をする必要はないです。
違う SD カードを対応したい場合は mount 直後に chmod する必要がありますので、mount を実行するところ(udev のルール?)に追加できます。

よろしくお願いします

k.sato

2024年2月14日 9時55分

マルティネ様

佐藤です。
お世話になっております。

> すみません、"tmp式"の chmod (どのユーザーでもファイルを作れますがオーナーにしかファイルを削除できない)を勘違いしてましたので訂正させてください。
> chmod コマンドは「chmod 1777 /var/app/volumes/sd」でした。
>
> 本件で特に差はないので、修正してもしなくてもいいですが、参考までに。
承知しました。

> はい、一度 chmod を行えばマウント時に設定するオプションはありません。

> ずっと同じ SD カードを使うのであれば、毎回 chmod をする必要はないです。
一度chmodを行えば電源を落としても権限がそのままのことを確認しました。
ありがとうございます。

> ずっと同じ SD カードを使うのであれば、毎回 chmod をする必要はないです。
> 違う SD カードを対応したい場合は mount 直後に chmod する必要がありますので、mount を実行するところ(udev のルール?)に追加できます。
現在は/etc/fstabでmountを実行しています。

また、コンテナ内のCLIメニューアプリからSDカードのフォーマットを行いたいのですがやり方はありますか?
ホストで手動でコマンドを試しているのですが「mkfs.ext4」のところでエラーとなります。

armadillo:~# umount /var/app/volumes/sd/
armadillo:~# mkfs.ext4 /dev/mmcblk1p1
mke2fs 1.47.0 (5-Feb-2023)
/dev/mmcblk1p1 is apparently in use by the system; will not make a filesystem here!

コンテナでsdカードを使用しているからなのでしょうか?

よろしくお願い致します。