mount –bind機能について
お久しぶりです。mnakamuraです。 ブログの当番が回ってきましたので、今回はmount --bindについてご説明致します。 linuxにおけるmountとは、HDDやDVD-ROM、USBメモリといったファイルシステムを、 指定した領域にアクセス可能な状態にするコマンドです。 一般的なWindowsのデスクトップPCで言えば、外付けのHDDをケーブルでPC本体に繋ぎ、 HDDへファイルを保存したり、取り出したり出来る状態を思い浮かべて頂ければ 分かりやすいのではないでしょうか。 そんなmountコマンドですが、実はオプションで『-B』もしくは『--bind』を付与すると、 特定のディレクトリを別のディレクトリにマウントする事も出来るのです。 (※カーネルが2.4.0以降の場合) …そもそも、どういうシチュエーションで使うの? というお話ですが、例えばWebサイトの制作をAの業者に任せているとします。 制作がある程度進んだ段階で、今度はBの業者にも作業を依頼しました。 BはAの領域の一部にアクセスして作業しなければならないが、 その一部領域以外のAの領域にはセキュリティ上アクセスして欲しくない…。 要するに、Bに『Aの一部の領域のみにアクセスする権利』を与えたい。 そんな時に便利な機能になります。 Aの業者のユーザを『TestUserA』、Bの業者のユーザを『TestUserB』として、 検証用のサーバで試してみましょう。
■1.検証用のユーザーを2つ用意 ----------------------------------------------------------------------------------------------------- [root@mnakamura ~]# useradd TestUserA [root@mnakamura ~]# passwd TestUserA ユーザー TestUserA のパスワードを変更。 新しいパスワード: よくないパスワード: 辞書の単語に基づいています 新しいパスワードを再入力してください: passwd: 全ての認証トークンが正しく更新できました。 [root@mnakamura ~]# useradd TestUserB [root@mnakamura ~]# passwd TestUserB ユーザー TestUserB のパスワードを変更。 新しいパスワード: よくないパスワード: 辞書の単語に基づいています 新しいパスワードを再入力してください: passwd: 全ての認証トークンが正しく更新できました。 [root@mnakamura ~]# id TestUserA uid=510(TestUserA) gid=512(TestUserA) 所属グループ=512(TestUserA) [root@mnakamura ~]# id TestUserB uid=511(TestUserB) gid=513(TestUserB) 所属グループ=513(TestUserB) [root@mnakamura ~]# ll -d /home/TestUserA drwx------ 2 TestUserA TestUserA 4096 6月 8 16:26 2020 /home/TestUserA [root@mnakamura ~]# ll -d /home/TestUserB drwx------ 2 TestUserB TestUserB 4096 6月 8 16:26 2020 /home/TestUserB ----------------------------------------------------------------------------------------------------- Webサイト制作業者のAとBのユーザがそれぞれ出来たと仮定します。
■2.TestUserAの領域にファイル設置ディレクトリ作成 -------------------------------------------------------------------------------------------------- [root@mnakamura ~]# mkdir /home/TestUserA/Files [root@mnakamura ~]# touch /home/TestUserA/Files/Testfile1.txt [root@mnakamura ~]# touch /home/TestUserA/Files/Testfile2.txt [root@mnakamura ~]# touch /home/TestUserA/Files/Testfile3.txt [root@mnakamura ~]# ll -A /home/TestUserA/Files 合計 0 -rw-r--r-- 1 root root 0 6月 8 16:30 2020 Testfile1.txt -rw-r--r-- 1 root root 0 6月 8 16:30 2020 Testfile2.txt -rw-r--r-- 1 root root 0 6月 8 16:30 2020 Testfile3.txt [root@mnakamura ~]# chown -R TestUserA:TestUserA /home/TestUserA/ [root@mnakamura ~]# chmod -R 775 /home/TestUserA/ [root@mnakamura ~]# ll -d /home/TestUserA/ drwxrwxr-x 3 TestUserA TestUserA 4096 6月 8 16:30 2020 /home/TestUserA/ [root@mnakamura ~]# ll -AR /home/TestUserA/ /home/TestUserA/: 合計 16 -rwxrwxr-x 1 TestUserA TestUserA 18 3月 23 09:15 2017 .bash_logout -rwxrwxr-x 1 TestUserA TestUserA 176 3月 23 09:15 2017 .bash_profile -rwxrwxr-x 1 TestUserA TestUserA 124 3月 23 09:15 2017 .bashrc drwxrwxr-x 2 TestUserA TestUserA 4096 6月 8 16:30 2020 Files /home/TestUserA/Files: 合計 0 -rwxrwxr-x 1 TestUserA TestUserA 0 6月 8 16:30 2020 Testfile1.txt -rwxrwxr-x 1 TestUserA TestUserA 0 6月 8 16:30 2020 Testfile2.txt -rwxrwxr-x 1 TestUserA TestUserA 0 6月 8 16:30 2020 Testfile3.txt -------------------------------------------------------------------------------------------------- /home/TestUserA/Files が、 Aの業者が作成しているWebサイトのファイル置き場と仮定しましょう。 Testfileは実際のWebサイトの構成ファイルだと考えて下さい。
■3.TestUserBの領域にmount用のディレクトリを作成 -------------------------------------------------------------------------------------------------- [root@mnakamura ~]# mkdir /home/TestUserB/MountPoint [root@mnakamura ~]# chown -R TestUserB:TestUserB /home/TestUserB/ [root@mnakamura ~]# chmod -R 775 /home/TestUserB/ [root@mnakamura ~]# ll -d /home/TestUserB/ drwxrwxr-x 3 TestUserB TestUserB 4096 6月 8 17:13 2020 /home/TestUserB/ [root@mnakamura ~]# ll -AR /home/TestUserB/ /home/TestUserB/: 合計 16 -rwxrwxr-x 1 TestUserB TestUserB 18 3月 23 09:15 2017 .bash_logout -rwxrwxr-x 1 TestUserB TestUserB 176 3月 23 09:15 2017 .bash_profile -rwxrwxr-x 1 TestUserB TestUserB 124 3月 23 09:15 2017 .bashrc drwxrwxr-x 2 TestUserB TestUserB 4096 6月 8 17:13 2020 MountPoint /home/TestUserB/MountPoint: 合計 0 -------------------------------------------------------------------------------------------------- 新しい業者Bがプロジェクトに参入。Aの /home/TestUserA/Files の 領域にアクセスしたいですが、/home/TestUserA/ にはA社の機密ファイルがあるので、 そこを経由せずにピンポイントでアクセスする為に、 Bの領域 /home/TestUserB/ の配下にmount用の領域である /home/TestUserB/MountPoint を作成します。
■4.mount前の状態を比較 -------------------------------------------------------------------------------------------------- [root@mnakamura ~]# ll -A /home/TestUserA/Files 合計 0 -rwxrwxr-x 1 TestUserA TestUserA 0 6月 8 16:30 2020 Testfile1.txt -rwxrwxr-x 1 TestUserA TestUserA 0 6月 8 16:30 2020 Testfile2.txt -rwxrwxr-x 1 TestUserA TestUserA 0 6月 8 16:30 2020 Testfile3.txt [root@mnakamura ~]# ll -A /home/TestUserB/MountPoint 合計 0 -------------------------------------------------------------------------------------------------- mount前は当然、Webサイトの構成ファイルは /home/TestUserA/Files にのみ置かれています。 /home/TestUserB/MountPoint は空です。
■5.mount --bind実行 -------------------------------------------------------------------------------------------------- [root@mnakamura ~]# mount --bind /home/TestUserA/Files /home/TestUserB/MountPoint -------------------------------------------------------------------------------------------------- マウント元とマウント先を指定し、mount --bindします。
■6.再度マウント先とマウント元のディレクトリを比較 -------------------------------------------------------------------------------------------------- [root@mnakamura ~]# ll -A /home/TestUserA/Files 合計 0 -rwxrwxr-x 1 TestUserA TestUserA 0 6月 8 16:30 2020 Testfile1.txt -rwxrwxr-x 1 TestUserA TestUserA 0 6月 8 16:30 2020 Testfile2.txt -rwxrwxr-x 1 TestUserA TestUserA 0 6月 8 16:30 2020 Testfile3.txt [root@mnakamura ~]# ll -A /home/TestUserB/MountPoint 合計 0 -rwxrwxr-x 1 TestUserA TestUserA 0 6月 8 16:30 2020 Testfile1.txt -rwxrwxr-x 1 TestUserA TestUserA 0 6月 8 16:30 2020 Testfile2.txt -rwxrwxr-x 1 TestUserA TestUserA 0 6月 8 16:30 2020 Testfile3.txt -------------------------------------------------------------------------------------------------- すると… /home/TestUserB/MountPoint にアクセスすると、 /home/TestUserA/Files の中身が見えるではありませんか。 mountした事で、ピンポイントで中身が見えるようになったんですね。 では、実際にBの業者の立場になって、 TestUserBでサーバにアクセスしてみましょう。
■7.TestUserBに切り替えてmountしたディレクトリを見てみる -------------------------------------------------------------------------------------------------- [root@mnakamura ~]# su - TestUserB [TestUserB@mnakamura ~]$ whoami TestUserB [TestUserB@mnakamura ~]$ pwd /home/TestUserB [TestUserB@mnakamura ~]$ ll -A 合計 16 -rwxrwxr-x 1 TestUserB TestUserB 18 3月 23 09:15 2017 .bash_logout -rwxrwxr-x 1 TestUserB TestUserB 176 3月 23 09:15 2017 .bash_profile -rwxrwxr-x 1 TestUserB TestUserB 124 3月 23 09:15 2017 .bashrc drwxrwxr-x 2 TestUserA TestUserA 4096 6月 8 16:30 2020 MountPoint [TestUserB@mnakamura ~]$ cd MountPoint/ [TestUserB@mnakamura MountPoint]$ ll -A 合計 0 -rwxrwxr-x 1 TestUserA TestUserA 0 6月 8 16:30 2020 Testfile1.txt -rwxrwxr-x 1 TestUserA TestUserA 0 6月 8 16:30 2020 Testfile2.txt -rwxrwxr-x 1 TestUserA TestUserA 0 6月 8 16:30 2020 Testfile3.txt -------------------------------------------------------------------------------------------------- 上記の通り、TestUserBの領域から、TestUserAの領域を参照出来るようになりました。 但し、このままだと普通にFTPクライアントソフトで TestUserAのディレクトリには移動出来てしまいます。 なので、chroot設定等で移動出来ないようにしましょう。
■8.FTPクライアントソフト上で、他のTestUserA所有領域への移動制限 -------------------------------------------------------------------------------------------------- 今回はFTPでの接続を想定し、vsftpd.confの設定を変えて、chrootを利かせます。 [root@mnakamura ~]# grep -v -e '^\s#' -e '^\s$' /etc/vsftpd/vsftpd.conf anonymous_enable=YES local_enable=YES write_enable=YES local_umask=022 dirmessage_enable=YES xferlog_enable=YES connect_from_port_20=YES xferlog_std_format=YES listen=YES pam_service_name=vsftpd userlist_enable=YES tcp_wrappers=YES [root@mnakamura ~]# cp -ip /etc/vsftpd/vsftpd.conf{,.$(date +%Y%m%d)} [root@mnakamura ~]# ll -A /etc/vsftpd/vsftpd.conf{,.$(date +%Y%m%d)} -rw------- 1 root root 4599 3月 22 21:14 2017 /etc/vsftpd/vsftpd.conf -rw------- 1 root root 4599 3月 22 21:14 2017 /etc/vsftpd/vsftpd.conf.20200610 [root@mnakamura ~]# vsftpd -v vsftpd: version 2.2.2 vsftpdのバージョンが2.3.5以降の場合、 エラーが発生する可能性があります。その場合は allow_writeable_chroot=YES も追加するようにしましょう。 [root@mnakamura ~]# vi /etc/vsftpd/vsftpd.conf [root@mnakamura ~]# diff /etc/vsftpd/vsftpd.conf{,.$(date +%Y%m%d)} 96,97c96,97 < chroot_local_user=YES < chroot_list_enable=YES chroot_local_user=YES chroot_list_enable=YES 99c99 < chroot_list_file=/etc/vsftpd/chroot_list chroot_list_file=/etc/vsftpd/chroot_list [root@mnakamura ~]# vi /etc/vsftpd/chroot_list [root@mnakamura ~]# cat /etc/vsftpd/chroot_list TestUserA TestUserAは規制対象外にしておきましょう。 vsftpdを再起動します。 [root@mnakamura ~]# service vsftpd status vsftpd (pid 29573) を実行中… [root@mnakamura ~]# service vsftpd restart vsftpd を停止中: [ OK ] vsftpd 用の vsftpd を起動中: [ OK ] [root@mnakamura ~]# service vsftpd status vsftpd (pid 29640) を実行中… FTPクライアントソフトはFileZillaを使用してみましょう。 すると… TestUserAでFTP接続すると、/homeディレクトリが見えるので、 ここを経由して色々と移動出来ますが… TestUserBでFTP接続すると、/homeディレクトリが見えないので、 mount --bindされた領域以外のTestUserA領域へは移動出来ません。 これで作業用のMountPointディレクトリしかアクセス出来ない状況が完成しました。 --------------------------------------------------------------------------------------------------
その他、 chgrpによる所属グループの変更… chmodによるパーミッション変更… 等を利用して柔軟に制限をかける事が可能です。 望み通りの環境を作る為に、状況に応じて調整しましょう。 但し、mount --bindした状態でusermod等で対象ユーザの所属グループを変更すると、 mount --bindされた配下領域の所属グループも変更されたりする場合があるので、 そこは注意が必要です。 尚、通常のmount設定と同様、サーバを再起動するとmountが外れてしまうので、 再起動した際に自動的にmountされるようにしたい場合には、fstabに記載しましょう。
■ex.再起動しても自動的にmountされるようにする -------------------------------------------------------------------------------------------------- [root@mnakamura ~]# vi /etc/fstab [root@mnakamura ~]# tail -1 /etc/fstab /home/TestUserA/Files /home/TestUserB/MountPoint/ none bind 0 0 -------------------------------------------------------------------------------------------------- ちょっと記事が長くなってしまったので、 他にも色々紹介したい事はありますが割愛します。 今回はここまでで。またお会いしましょう。