読者です 読者をやめる 読者になる 読者になる

IIS - MWAでWebアプリのIP制限を操作する

MWA(Microsoft.Web.Administration)を使って、IIS上にあるWebアプリのIP制限を操作するC#のコードを書いてみましたので残しておきます。

MWAを使うにはプロジェクトの参照にMicrosoft.Web.Administration.dllを追加する必要があります。私のローカル環境(Windows 8.1)にはIISが入っているためかこちらのパスにdllがありましたが、ない場合はWindows Serverからコピーするといいようです。

C:\Windows\System32\inetsrv\Microsoft.Web.Administration.dll

IP制限を行う

Webサイト「Default Web Site」のWebアプリケーション「webapp」にIP制限を行うサンプルコードです。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Web.Administration;

namespace ConsoleApp {
    class Program {
        static void Main(string[] args) {
            using(var manager = new ServerManager()) {
                // applicationHost.configからIP制限を行うセクションを取得
                var config = manager.GetApplicationHostConfiguration();
                var section = config.GetSection(
                    "system.webServer/security/ipSecurity",
                    "Default Web Site/webapp");

                // リストにないIPアドレスからのアクセスを拒否
                section["allowUnlisted"] = false;

                // 例として192.168.100.1からのアクセスを許可
                var elements = section.GetCollection();
                var element = elements.CreateElement("add");
                element["allowed"] = true;
                element["ipAddress"] = "192.168.100.1";
                elements.Add(element);

                // コミット
                manager.CommitChanges();
            }
        }
    }
}

ServerManagerを使って、applicationHost.configのsystem.webServer/security/ipSecurityセクションの情報を取得しています。 そしてIP制限などを設定した後に、CommitChangesを呼び出して変更を保存するといった流れです。

最初、セクション情報を取得する部分を次のようにGetWebConfigurationメソッドを使っていたのですが、セクションに対して変更を加えると例外が発生してハマりました。

var config = manager.GetWebConfiguration("Default Web Site", "/webapp");
var section = config.GetSection("system.webServer/security/ipSecurity");

例外の内容です。

型 'System.IO.FileLoadException' のハンドルされていない例外が Microsoft.Web.Administration.dll で発生しました

追加情報:この構成セクションをこのパスで使用できません。この問題は、親レベルでセクションがロックされているときに発生します。ロック状態は既定で設定されているか (overrideModeDefault="Deny")、または overrideMode="Deny" もしくは従来の allowOverride="false" を含んだ場所タグによって明示的に設定されます。

機能の委任(←わかっていない)が関係するのかも?と思いつつも正直わからない部分なのでまた調べてみたいと思います。

IP制限の状態を取得する

さきほど変更したIP制限の状態を確認してみます。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Web.Administration;

namespace ConsoleApp {
    class Program {
        static void Main(string[] args) {
            using(var manager = new ServerManager()) {
                // applicationHost.configからIP制限を行うセクションを取得
                var config = manager.GetApplicationHostConfiguration();
                var section = config.GetSection(
                    "system.webServer/security/ipSecurity",
                    "Default Web Site/webapp");

                // 状態を表示
                Console.WriteLine("allowUnlisted:" + section["allowUnlisted"]);
                foreach(var element in section.GetCollection()) {
                    Console.WriteLine("allowed:{0}, ipAddress:{1}, subnetMask:{2}", 
                        element["allowed"], element["ipAddress"], element["subnetMask"]);
                }
            }
        }
    }
}

実行結果です。

allowUnlisted:False
allowed:True, ipAddress:192.168.100.1, subnetMask:255.255.255.255

参考