OSごとに違うファイルシステムの保護機能

Microsoftはオープンソース化を行ったPowerShell Coreから、WindowsのみならずmacOSとLinuxもサポート対象に加えるようになった。これはPowerShell Coreが利用しているコア技術がオープンソース化され、さらにその技術がmacOSとLinuxをサポートしているために実現できたことだった。

WindowsもmacOSもLinuxも大体似たような機能を提供しているのでこうしたことが可能になるわけだが、それでも超えられない部分がいくつかある。その1つが、ファイルシステムだ。ファイルシステムが提供する基本的な機能はどのOSも同じなのだが、ファイルシステムのアクセス保護やリソース保護のアプローチがWindowsとUNIX系ではかなり異なっているため、この部分を双方に対応したものにするのには苦労する。

PowerShellではないのだが、Microsoftの取り組みとして同じ問題にあたったのが「WSL (Windows Subsystem for Linux)」だ。WindowsでLinuxバイナリを実行する機能であるWSLの最初の実装系となるバージョン1はレイヤ技術を採用しており、Linuxが使用するファイルシステムとしてWindowsのファイルシステムを利用している。Linuxから利用できるように専用のドライバを噛ませており、Linuxバイナリからファイルシステムへのアクセスが発生した段階でドライバを経由してWindowsのファイルシステムを利用する仕組みを採用している。

こうしたレイヤ技術は、UNIX系のOSでは比較的利用されていることが多い。しかし、Windowsの場合、ファイルシステムのリソース保護の概念がUNIX系のファイルシステムと異なっているため、どうにもうまくなじみきれなかった。動作するには動作するのだが、Windows側の保護機構のなかでLinux側の保護機構がさらに動作するような状態になるため、動作は遅くなり、そして仕組みもわかりづらくなっている。Microsoftはこうした問題を解消するため、次のバージョンとなるWSL2では仮想化技術であるHyper-Vを使った実装に変更している。

同じようなことはPowerShell Coreでも起こっていた。PowerShellがもともとWindowsプラットフォームで開発されているためか、UNIX系ファイルシステムのアクセス保護/リソース保護の情報がうまく扱われていなかった。例えばdir (Get-ChildItem)でLinuxのファイルやディレクトリの情報を表示させると、Windows風のファイルシステム情報が表示されてしまう。これはLinuxやmacOS側からするとマイナスポイントだろう。肝心の保護情報が抜け落ちてしまっており、管理向けのシェルとして使うには大きな問題だと言える。

PowerShell 7.0.0 Preview 5での動作

この状況はPowerShell 7.0.0 Preview 6で改善された。ちょっとしたことではあるのだが、PowerShell 7をLinuxやmacOSで活用する上ではなくてはならない改善となっている。

まず、PowerShell 7.0.0 Preview 5での動作を確認してみよう。ここではUbuntu 18.04 LTSで動作を確認している。

PowerShell 7.0.0 Preview 5

PowerShell 7.0.0 Preview 5でlsコマンドをオプション「-l」付きで実行すると、次のような出力が得られる。これはUbuntu 18.04 LTSが用意しているlsコマンドの実行結果なので、Linuxネイティブなコマンドの実行結果だ。ファイル保護機能であるパーミッション情報、そのユーザーとグループ情報などが表示されていることが確認できる。

ls -lの実行結果 (Ubuntu 18.04 LTS)

ここでdir (Get-ChildItemコマンドレット)を実行すると、次のような出力結果が得られる。

PowerShell 7.0.0 Preview 5でdirの実行結果

Linuxでのパーミッション情報に相当する部分が「Mode」に表示されているのだが、多くの情報が落ちてしまっていることがわかる。ユーザやグループのデータも抜けているし、ディレクトリに至ってはサイズ情報も表示されていない。Windowsでdirを実行したときのような出力まで出力結果が削減されてしまっていることがわかる。

Windowsを使っているユーザーがLinuxやmacOSでこの出力を得た場合には特に問題ないかもしれないが、普段macOSやLinuxを使っているユーザーがこの出力しか得られないということになると、かなり問題だ。OSを切り分けてdirとlsで処理を書くということもできるが、できればGet-ChildItemを使ってどのプラットフォームでも動くようにスクリプトを書きたい。このままではLinuxやmacOSでの動作を大雑把なものにする必要がある。

PowerShell 7.0.0 Preview 6での動作

次は、PowerShell 7.0.0 Preview 6で動作を確認してみよう。

PowerShell 7.0.0 Preview 6

当然だが、lsコマンドの実行結果は先ほどと同じになる。

ls -lの実行結果 (Ubuntu 18.04 LTS)

dir (Get-ChildItemコマンドレット)を実行すると、次のような出力結果が得られる。表示される情報が増えている点に注目したい。

PowerShell 7.0.0 Preview 6でdirの実行結果

大きく目を引くのはPowerShell 7.0.0 Preview 5では「Mode」と表示されていた部分が「UnixMode User Group」と大きく変わった点にある。Modeと違い、UnixModeにはユーザー・グループ・その他のすべてのパーミッション情報が含まれている。ユーザーとグループの情報も表示されているし、UNIX的な出力になった。

ディレクトリのサイズも表示されるようになった点にも注目だ。UNIX系OSではディレクトリにもサイズが表示されることが多い(ベースとなっているUFSではディレクトもファイルでありサイズがあるため)。確かに、dirの出力スタイルはWindowsのdirコマンドのままだが、情報としては「ls -l」と同じレベルのデータが表示されるようになった。小さな変化ではあるのだが、LinuxやmacOSで使っていくためには必須の改善が取り込まれたといえる。

今後さらに対応が進むかもしれない

ファイルシステムにおける保護機構はOSごとに異なっている。UNIX系のOSは保護ドメインと言われる仕組みがベースにあることが多く、これにファイルシステムごとに拡張機能があったり、アクセス制御リスト、またはまったく異なるセキュリティ機能でアクセス制御機能が提供されていたりする。

Windowsのファイル保護機能はこうしたUNIX系OSとは異なっている。最初から複数のユーザーが利用することを前提としたUNIX系のOSと、ユーザーが1人で使用するOSとして出発しているWindowsとでは、ファイルシステムに求められる前提が異なっているためだ。読み書きといった最低限の機能は大体同じなのだが、そもそものアクセス保護の概念が異なっているので、なかなか同じように扱えるようにするのは難しいのだ。

最終的にどこまでこういったUNIX系のアクセス保護機能にPowerShell 7側で対応していくかは今後のユーザーの要望次第ということになると思うが、特にLinuxでのPowerShell 7の使用が進めば、もっと多くのアクセス制御機能がPowerShell 7から制御できるようになる可能性がある。今後のバージョンでこういった機能がどこまで取り込まれてくるのか、今後も注目していきたい。

参考資料