Sysinternals の Process Monitor を使い、謎のローカルネットワークファイルアクセス失敗のトラブルシューティングをします。
あるWeb アプリケーションの要件としてローカルネットワークに存在するファイルを取得して Web 画面に表示させます。この Web アプリケーションは .NET Core Module で IIS 上で動作します。
Visual Studio で ASP.NET Core アプリケーションの開発時は実は IIS は任意で、Launch Profile を変更することで IIS を使わず通常の .exe のように直接起動できます。.NET Core Debugging with WSL 2 で WSL 2 でもデバッグできるようになります!
Windows Explorer やコマンドでそれを単独で起動できたり、別のPCにコピーして通常 .exe みたいに簡易に起動できたりしますのですごく便利です。
ローカルネットワークにあるファイルを取得して表示するには色々方法がありますが、その一つは Directory.EnumerateFileSystemEntries です。ローカルで単独 .exe を実行して問題なく ¥¥hogeIP¥directory01 のようにアクセスできた後、ローカルの IIS にデプロイして、問題なく動作したことを確認。
よし、用意されていたテスト環境の AWS EC2 の IIS にデプロイしようぜ!
デプロイ完了し、テストしてみたら、あれ、なぜディレクトリ内のファイルの表示ができてないんだ?
空っぽだぞ!👀
Windows Explorer で ¥¥hogeIP¥directory01 は普通にアクセスできたので、権限まわりが怪しい?😤
エラーログを見てみたら、確かに Directory.EnumerateFileSystemEntries の結果にファイルエントリがなくて、特に Exception もありません。プログラム側で try catch で潰している訳でもありません。権限問題であれば、API の Docs によると SecurityException や UnauthorizedAccessException が出ているはず。それがないのが、謎です。
単独 .exe で実行してみよう。 hoge.exe --urls http://*:5001 のようにポートを指定して起動します。あれ、単独で実行した場合は普通にアクセスできたぞ!ファイル一覧をちゃんと表示されました。
もしかしたら IIS 関連の権限がダメなのかな?
ダメもとで Windows の資格情報マネージャーで IP 認証情報を登録しておくと、どうでしょう?
うーん、状況変わらず。
試しに IIS の アプリケーションプールアイデンティティアカウントを変更して管理者に設定してみよう。セキュリティ上ではオススメしないけど、とりあえず原因究明が先だ!
管理者に変更してみても同じくアクセスできませんでした・・・IIS に最強の Administrator 権限割り当てやがったぞ!w
タスクマネージャーでちゃんと Administrator になっていることも確認できましたし。
Sysinternals の Process Explorer でも確認しよう!
Process Explorer で IIS ワーカープロセス (w3wp.exe) の子プロセスで Administrator として実行されていることも確認できましたので、まだアクセスできないのはなぜだ?
こうなりましたら、Sysinternals の Process Monitor でも使ってみますか!
まず、単独 .exe で実行した時のログを取ります。
はい、Result が SUCCESS で Detail にファイル名もちゃんと出ていますね。
では、IIS で実行した時のログに比較してみましょう。
おや、 LOGON FAILURE だと?
その違いは何だ?
待てよ。もしかして、Windows の Session ID が違うから?単独 .exe の場合の Windows Session ID は?
IIS の場合は?
ビンゴ!
そっか、そりゃそうだ。システムとして実行するので Windows Session ID=0 は当たり前。
Windows Session ID の違いで単独 .exe との動作が同じと保証できないもんね。LOGON FAILURE というログも取れましたので、調査報告としての原因はこれで材料が揃いました。
Web アプリケーション側の対応として、ネットワークパスのそれぞれの認証情報をアプリケーション設定で変更可能にしておいて、アクセスする前にアプリケーション側が判断して該当サーバへ認証させます。そうすると、ディレクトリ内のファイルをちゃんと取得できるようになりました。
とりあえず問題解決!
普段なかなか使う場面がないですが、何年ぶりに Process Monitor を使ったかな?
Directory.EnumerateFileSystemEntries はなぜ SecurityException や UnauthorizedAccessException をトリガーしていないのか、謎のままですが🙄。ローカルの Windows 10 で再現してみるとちゃんと例外が出ていますので、 Windows Server だと基本管理者として実行しているから管理者にはそんな例外なんて矛盾しているからトリガーしないとか?🤷♂️
まとめ
アプリケーション側にエラーが出力されなくて、正常動作と見なした謎の挙動には、Process Monitor を使ってトラブルシューティングし、ローカルネットワークのファイル取得失敗時のより OS レベルのログを取得することで原因特定と問題解決に繋がりました。🎉🎉🎉🎊🎊🎊
Top comments (0)