treedown’s Report

システム管理者に巻き起こる様々な事象を読者の貴方へ報告するブログです。会社でも家庭でも"システム"に携わるすべての方の共感を目指しています。

※https化しました。その影響でしばらくリンク切れなどがあるかもしれませんが徐々に修正していきます。 リンク切れなどのお気づきの点がございましたらコメントなどでご指摘いただけますと助かります。

アクセス制限…しますよね(やったことないけど汗)

初めてsambaサーバでファイルサーバを構築した時にいざ設定となった段階でのセリフです。
いままで、Windows ServerでNT4時代からファイルサーバを(StorageEditionも含めて)各バージョンで構築と運用管理してきた実績はあったので、ある程度のスキルという点では自信を持っていたのですがsambaサーバだとそのスキルはほとんど役に立ちません。
sambaサーバを導入した時点でインフラはそれほどの規模ではありませんでした。そのため何とかなるかなと思ってアクセス制限を実現するために頑張って情報収集&検証にいそしみました。
まだまだ修行が足りないので至らない点がありますが、何かの参考になればと思います。
なお、文中でLinuxと記載がある箇所はDebian(Wheezyかjessieのいずれか)で試したときの内容です。

アクセス制限による制御パターンは

  1. ユーザが所属するグループでアクセス制限する
  2. ユーザIDでアクセス制限する
  3. アクセス拒否設定

の3パターンです。
現在の技術ではDefault Deny(Deny思考)なので「アクセス拒否」は特定の設定を記述せず、条件にマッチしなかった場合にデフォルトのアクセス拒否が適用されれば要件を満たせます。
なので、グループ制御とユーザ制御をsambaのconfigファイルに記述することで実現したいことは達成できると考えました。

まず必要になった知識としてLinuxではWindows Serverとグループアカウントの使い方が違うところでかなりはまり込んで時間を使ってしまいました。
Linuxではメイングループとサブグループがあります。
所属グループの確認にはidコマンドを使用します。
----------------------------------------------
$ id -a
uid=1501(user1) gid=1501(Users) groups=1601(company)
----------------------------------------------
これだとメイングループはgidで表示されているUsersグループです。
サブグループがgroupsで表示されているcompanyグループです。
この2つのグループにuser1というユーザは所属しています。
他のユーザも見てみましょう。idコマンドに続けてユーザIDを入力すると閲覧できます。
----------------------------------------------
$ id user2
uid=1502(user2) gid=1502(PowerUsers) groups=1501(Users)

$ id user3
uid=1503(user3) gid=1502(PowerUsers) groups=1601(company)
----------------------------------------------
user2とuser3は動作の違いを確認するため、所属グループの状態を変えてあります。

この3つのユーザが存在する前提でアクセス制御を設定します。
前回のUsers共有にアクセス制限を掛けるようにします。
----------------------------------------------
[Users]
    comment = Usersグループの共有
    path = /home/samba/share/Users
    browseable = no
    writable = yes
    valid users = @Users
    write list = @Users
    force create mode = 777
    force directory mode = 777
    force group = Users
    include = /etc/samba/Users.%G
    include = /etc/samba/Users/%U
###Users###
----------------------------------------------

sambaファイル共有はデフォルトリードオンリーです。なので
「writable = yes」を記述してこのフォルダは読み書き可能と明示する共有設定を記述します。
force create modeとforce directory modeでファイルやディレクトリの所有者でなくともアクセスを可能にし、ファイルシステムのアクセス権は使わずにsambaの共有のアクセス権だけで制御しています。
またforce groupをUsersに指定することで誰が作成したファイルであっても所有者グループは「Usersグループ」になるように設定してあります。

これらはデフォルトでファイルやディレクトリを作成すると、作成者ユーザ&グループで生成されてしまうため、共有フォルダ内のアクセス許可を得ているユーザであってもアクセスできなくなるために設定しています。
例えば、user2が作成したファイルやディレクトリは
drwxr-xr-x  2 user2 PowerUsers  4096 12月 30 00:42 test
-rwxrw-r--  1 user2 PowerUsers 19432  5月 24 14:01 test.txt
となってしまいます。
デフォルトは所有者=ユーザ、所有グループ=ユーザの所属するメイングループでファイルは生成されてしまうので、Users共有内にこのルールでディレクトリ&ファイルが生成されてしまうとUsersグループにアクセス許可を付与しているUsersフォルダのはずなのに、上記ディレクトリはr-x(読み取りと実行)ファイルはr--(リードオンリー)とアクセスが制限されてしまいます。
Usersグループに所属している全員が読み書き実行できることが共有フォルダの第一の使命なことと、複雑なことをするには知識がまだ不足している現状ですので、ファイルシステムレベルでのアクセス制御はここでは実施せず共有レベルのアクセス制御に留めています。
蛇足ですが、Windows Serverであればファイルシステム(NTFS)レベルでのアクセス制御がベストです。ファイルシステムのアクセス制御であればコンソールアクセスでもアクセス制御が適用されるから、というのがその理由です。

もともとは「valid users = @Users」と「write list = @Users」だけで制御すると思っていました。
ですが、アクセス権がないユーザがアクセスしたときにフォルダを見えなくするため「browseable = no」としたため「include = /etc/samba/Users.%G」を入れ、許可ユーザにだけ見えるように設定することとしました。
/etc/samba/に
----------------------------------------------
$ sudo touch /etc/samba/Users.Users
$ sudo vi /etc/samba/Users.Users
-------Users.Usersファイル編集-----------------
[Users]
    comment = Usersグループの共有
    path = /home/samba/share/Users
    browseable = yes
    inherit permission = yes
    inherit acls = yes
    valid users = @Users
    
###Users###
-------Users.Usersファイルここまで-------------
と、こうすることでsmb.confで指定した全ユーザ向けの「browseable = no」によるフォルダ不可視がUsersグループだけは「browseable = yes」で上書きされてUsersグループはフォルダが見えるようになります。
(重複オプションがあって見苦しいのはご容赦を)

ここまでで動作を確認すると

  • user1=読み書き可能
  • user2=読み書き可能、だがフォルダ不可視
  • user3=読み書き不可能

Usersグループでアクセス権制御を想定していたので、user2は/etc/samba/Users.Usersファイルに記述がある「browseable = yes」が効いてuser1と同一の動作をする予定でした。が、実際には/etc/samba/Users.Usersファイルの記述が適用されていないように見受けられ、困ってしまいました。(ここで煮詰まってしまいました。)
「%G」が変数だという説明だったので、これはメイングループという意味じゃないか?とふと思ったのですが、じゃあサブグループを表す変数は何か?が見つからなかったためにあえなく時間切れ(移行期限)を迎えました。
そこで、もう一つの「include = /etc/samba/Users/%U」でサブグループに所属するユーザ別に権限を付与するホワイトリストのような作りにすることにしました。
sambaのconfigは下にある行の設定が上書きされますので
    include = /etc/samba/Users.%G
    include = /etc/samba/Users/%U
この順番でconfigを記載すると、最終的にユーザ個別の設定が有効になります。
そこで、以下を追加設定することにしました。
----------------------------------------------
$ sudo mkdir /etc/samba/Users
$ sudo touch /etc/samba/Users/user2
$ sudo vi /etc/samba/Users/user2
-------user2ファイル編集-----------------
[Users]
    browseable = yes
    inherit permission = yes
    inherit acls = yes
    valid users = user2
    
###Users###
-------user2ファイルここまで-------------

ここまで実行すると、ディレクトリとファイルはこうなっています。
/etc/samba/
   ├─smb.conf
   │
   ├─Users.Users
   │ 
   └─Users
         └─user2

ちなみに/etc/samba/Users.PowerUsersを作成してアクセス許可を用意してもuser2はアクセス可能になりますが、今度はUsersグループに所属していないuser3がアクセスしたときにフォルダが表示されアクセス許可を取得しすることになってしまいます。
後々考えれば、それほどの規模ではないファイルサーバであれば、/etc/samba/Users/%Uだけの制御で十分でした。(とはいえ、「valid users = @Users」と「write list = @Users」としていますので、グループアカウントに対象のユーザ追加は実施しておきましょう。グループにユーザを追加するにはgpasswdコマンドが便利です。)
user3がuser2と同様にアクセスできるように追加する方法は以下の手順となります。
----------------------------------------------
$ sudo gpasswd -a user3 Users
$ sudo touch /etc/samba/Users/user3
$ sudo vi /etc/samba/Users/user3
-------user3ファイル編集-----------------
[Users]
    browseable = yes
    inherit permission = yes
    inherit acls = yes
    valid users = user3
    
###Users###
-------user3ファイルここまで-------------
登録したuser3を削除する(アクセス権はく奪)には以下の手順になります。
----------------------------------------------
$ sudo gpasswd -d user3 Users
$ sudo rm /etc/samba/Users/user3
----------------------------------------------
現在は規模が小規模なことと組織が流動的なことが相まって「include = /etc/samba/Users/%U」を主でアクセス制御しています。

共有フォルダの考え方は2つあって、それぞれを使い分けするとよさそうです。

  1. 部門(組織)フォルダ=グループ制御で可能=メイングループを部署名にしておく=「include = /etc/samba/Users.%G」
  2. プロジェクトフォルダ(部門横断フォルダ)=グループ制御では難しいのでユーザ個別制御=「include = /etc/samba/Users/%U」

メイングループを部署で固めておいて、基本はグループ制御=組織変更時にもグループ編集で実行、としておくと旧来からのアクセス権限管理で考え方は通用します。いちばん分かりやすいです。
ごちゃ混ぜにすると混乱するのは社内プロジェクトでワーキンググループ・チームが結成された際の共有フォルダです。これは各部署の代表者がタスクのために集合(いわゆる横串というやつですね。)することが多いので、グループで制御するよりもユーザ制御でアクセス権を付与したほうが分かりやすいです。
つまり、最初から「include = /etc/samba/Users.%G」を使わずに、
「include = /etc/samba/Users/%U」だけでアクセス制御する、
というほうが分かりやすいのではないかと考えています。
「/etc/samba/共有名/」ディレクトリ配下に「ユーザ名」ファイルが生成されるので、このユーザ名ファイルがそのままアクセス許可リストとなります。
(私はいまさらな状況になっていますので、悪しき2重管理となっています。ドンマイ。)

ここまでの設定を使う上での注意点:
ここまでのアクセス制御の設定では以下のポイントも確認しておいてください。
(1) コンソールやシェルでのアクセス許可をユーザに与えない。
ファイルシステムでアクセス制御をしていないからです。コンソールやシェルは管理者だけが使う前提で、この設定は成立しています。
どうしてもファイルシステムのアクセス権制御が必要な場合は、「vfs objects acl_xattr」をGoogle先生にお伺い立ててACLサポートについて調べると幸せになれるかもしれません。

(2) 管理者アクセス用の設定が不足している。
全グループにアクセス権を持つ管理用ユーザを1つ作成するか、各共有の末尾に「admin group = %管理者グループ名%」と追加することで管理者アクセス用の設定が成立します。共有フォルダ全体のバックアップやファイル操作、トラブルシューティングなどに使用するアクセス権です。
例えば後者「admin group」を使用する場合には、
----------------------------------------------
$ id admin
uid=1101(admin) gid=1001(admin)
----------------------------------------------
というユーザを用意しておき
smb.confの[Users]セクションの末尾に「admin group = @admin」と記述しておきます。
管理業務はadminグループ所属のユーザで実行すると幸せになれるでしょう。

アクセス権設定はサーバシステムを利用する企業の規模や取り巻く環境によって、軽作業にも重労働にもなります。

貴環境が軽作業で済むことをお祈りしております。