アプリ開発ときどきアウトドア

主にJavaを使ったアプリ開発やトラブルシューティング等のノウハウ、キャンプや登山の紹介や体験談など。

1. システムエンジニアリング IIS 基盤技術

VisualStudioのIIS Expressで独自ドメインSSLを構成

投稿日:

シングルサインオンの検証等を想定し、開発環境の複数のWebアプリに独自ドメイン名+SSLを使用したい。
Visual Studio 2019で作成したWeb系プロジェクトを前提とし、IIS Expressに独自ドメイン名を設定し、SSLを使用する方法について説明します。

前提

  • Windows10環境のVisual Stuido 2019のWebプロジェクトを対象としています。
    (プロジェクト実行時に使用されるIIS Expressで独自ドメインを使用する。)
  • ExampleWebというWebアプリを例に説明を行います。
    既定で使用されるhttp/httpsのURLを次のに独自ドメインに変更する手順となります。
    ポート番号は環境で変動するため、適宜読み替えてください。
    変更前 変更後
    http://localhost:50131/
    https://localhost:44334/
    http://testserver1:50131/
    https://testserver1:44334/
  • 開発環境のローカルPCで閉じた検証を行う想定なので、この独自ドメイン名の実体はローカルホスト(127.0.0.1)とします。
  • IISマネージャがあればできる手順もありますが、基本的にはPowerShellのコマンドベースで実施する手順としています
  • ある程度知識がありお急ぎの場合は「簡易手順」をご覧ください。

簡易手順

ある程度の知識がある人向けのダイジェスト的な手順です。
不明な部分は後述の詳細手順を参照してください。

  1. 独自ドメイン名でアクセスできるようWindowsのhostsファイルにエントリを追加します。
    127.0.0.1 testserver1
  2. プロジェクトのプロパティで[デバッグ]を開き、アプリURLのサーバ名を独自ドメイン名に変更します。
  3. (PJフォルダ)\.vs\(PJ名)\config\applicationhost.configを開き、bindings要素に下記を追加し、既存のlocalhostに対するhttp/httpsは除外します。
    <binding protocol=”http” bindingInformation=”*:50131:testserver1″ />
    <binding protocol=”https” bindingInformation=”*:44334:testserver1″ />
  4. http.sysにURLを登録する。 ※以降、管理者権限のPowerShellで実行する想定
    netsh http add urlacl url=http://testserver1:50131/ user=Everyone
    netsh http add urlacl url=https://testserver1:44334/ user=Everyone
  5. 自己署名のサーバ証明書を作成します。
    New-SelfSignedCertificate -DnsName “testserver1” -CertStoreLocation Cert:\LocalMachine\My `
    -FriendlyName “TestServer1” -NotAfter (Get-Date).AddYears(10)
  6. httpsのURLに証明書を紐づけます。
    certhash値は証明書作成時に表示されるThumbprintの値、appidは登録を識別するための任意のGUIDであり、New-Guidコマンド等で別途生成できます。certstorename=MYはnetshのバグ回避のために付与します。
    netsh http add sslcert hostnameport=testserver1:44334 `
    certhash=72C6BDE7EDCF21E8CC3A6A0D957D3B81BEA6A208 `
    appid='{63b4fc59-dbe3-417a-a847-ae5b27adf0e1}’ `
    certstorename=MY
  7. 作成したサーバ証明書をエクスポートします。
    $cert = Get-ChildItem -Path Cert:\LocalMachine\My\72C6BDE7EDCF21E8CC3A6A0D957D3B81BEA6A208
    Export-Certificate -Cert $cert -FilePath testserver1.der -Type CERT
  8. 証明書を信頼します。
    ※全ユーザで信頼する場合、管理者権限のPowerShellで実行
    Import-Certificate -FilePath testserver1.der -CertStoreLocation Cert:\LocalMachine\Root
    ※実行ユーザのみで信頼する場合、管理者権限がないPowerShellで実行
    Import-Certificate -FilePath testserver1.der -CertStoreLocation Cert:\CurrentUser\Root
  9. プロジェクトをデバッグ開始し、ブラウザに証明書エラーが表示されないことを確認します。

詳細手順

簡易手順では記載されなかった詳細な手順を説明します。
簡易手順と同様な手順ですが、一致しているわけではないのでご了承ください。

独自ドメインを構成

IISで独自ドメインを使用できるようにIISを構成します。

ホスト名の登録

独自ドメイン名でアプリにアクセスできるようhostsファイルにサーバ名を登録します。
管理者権限でメモ帳を開き、hostsファイルを編集します。

...
127.0.0.1	testserver1
...

IISの構成変更

独自ドメインのhttp/httpsを公開できるよう構成を変更します。

  1. プロジェクトフォルダ・ファイルの退避
    念のため、プロジェクトフォルダを丸ごとコピー等して退避します。
    特に影響を受けるファイルは次の通りです。
    パス 説明
    [プロジェクトフォルダ]\.vs\[プロジェクト名]\config\
    applicationhost.config
    IISの構成ファイル。
    プロジェクト作成直後には存在しないが、デバッグ開始等を行うと自動的に作成される。
    [プロジェクトフォルダ]\Properties\
    launchSettings.json
    プロジェクトの構成ファイル。
    アプリURL等のデバッグ構成も含んでいる。
  2. プロジェクトのアプリURLを変更
    ソリューションエクスプローラーでプロジェクトのプロパティを開きます。
    [デバッグ]タブを選択し、アプリURLのホスト名を変更し、保存します(Ctrl+s等)。
  3. IISの構成ファイルの補正
    前述のアプリURLを変更して保存すると、自動的にIISの構成ファイルが変更されます。
    何度か変更を繰り返すとその分追加されてしまったり、httpsが追加されなかったり、期待通りの編集にならないので、次のように修正します。
    ...
          <site name="ExampleWeb" id="2">
            <application path="/" applicationPool="ExampleWeb AppPool">
              <virtualDirectory path="/" physicalPath="C:\...\ExampleWeb" />
            </application>
            <bindings>
              <!-- アプリURL変更後のオリジナル
              <binding protocol="http" bindingInformation="*:50131:localhost" />
              <binding protocol="https" bindingInformation="*:44334:localhost" />
                        <binding protocol="http" bindingInformation="*:50131:testserver1" />
              -->
              <!-- 手動で追加 -->
              <binding protocol="http" bindingInformation="*:50131:testserver1" />
              <binding protocol="https" bindingInformation="*:44334:testserver1" />
            </bindings>
          </site>
    ...
    
    • 8-9行目: “localhost”は使用しないのでコメントアウト。
      localhostもtestserver1も127.0.0.1であり、この定義を残していると起動時にポートが重複してエラーになるため。ポート番号を変えればよいのだが、煩雑になるのでこのようにしている。
    • 13行目: 前述のアプリURL変更時に自動的に追加されるエントリ。
      ブラウザでアクセスする際はSSL側を使用するので不要に思えるが、Visual StudioがIISを制御するために必要である。アプリURLに対応するこのエントリがないと「Web サーバー ‘IIS Express’ に接続できませんでした。」エラーになる。
    • 14行目: 前述のアプリURL変更時に自動的に追加されないので追加したエントリ。
      (9行目のエントリがあって)このエントリがないと、ブラウザアクセス時に次のエラーになってしまう。
      Bad Request – Invalid Hostname
      HTTP Error 400. The request hostname is invalid.

URLの登録

Windows環境におけるASP.NET Core用のWebサーバとしてhttp.sysがあります。
これはOSレベル(カーネルモードドライバ)で動作しており、HTTP関連の発着信を管理しています。
前節で構成したhttp/httpsを公開できるよう、http.sysにURLを登録します。
なお、管理者権限でアプリを実行する場合、このURL登録手順は不要です。

  1. http/httpsのURLの確認
    http/httpsのURLは、アプリURL変更時に開いたプロジェクトのプロパティでコピペできます。
    アプリURL変更直後はhttpsのURL表示がlocalhostのままになっているので、このプロパティウインドウを開き直す必要があります。
  2. http.sysを制御するためのnetsh httpコマンドを使ってURLを登録します。
    このコマンドの詳細はリファレンスを参照のこと。
    PS> netsh http add urlacl url=http://testserver1:50131/ user=Everyone
    
    URL 予約を正常に追加しました
    
    PS> netsh http add urlacl url=https://testserver1:44334/ user=Everyone
    
    URL 予約を正常に追加しました
    
    

    なお、URLの最後に必ず”/”を指定します。これが抜けると次のエラーになってしまいます。

    URL 予約を追加できませんでした。エラー: 87
    パラメーターが間違っています。

起動確認

IISが起動し、ブラウザでWebアプリを開けるかを確認します。

  1. プロジェクトのデバッグを開始します。
  2. IISが正常に起動することを確認します。
    出力ウインドウの出力先を「ASP.NET Coreサーバー」に変更し、次のようにIISが正常に開始していることを示すログを確認します。
    Starting IIS Express ...
    Successfully registered URL "http://testserver1:50131/" for site "ExampleWeb" application "/"
    Successfully registered URL "https://testserver1:44334/" for site "ExampleWeb" application "/"
    Registration completed for site "ExampleWeb"
    IIS Express is running.
    
  3. ブラウザでページを開けることを確認します。
    サーバ証明書のエラーが表示されるが、ページを表示できることを確認します。

自己署名サーバ証明書の作成と登録

自己署名サーバ証明書を作成し、http.sysに登録します。

サーバ証明書の作成

管理者権限のPowerShellで、New-SelfSignedCertificateコマンドを使って自己署名サーバ証明書を作成します。
makecertを使用する方法もありますが、これは非推奨になっています。
実行後に表示されるThumbprintは、証明書ハッシュであり、コマンドやツール等で証明書を識別するために使用します。(Windowsの証明書ウインドウの「拇印」項目でも確認できます。)

PS> New-SelfSignedCertificate -DnsName "testserver1" -CertStoreLocation Cert:\LocalMachine\My `
 -FriendlyName "TestServer1" -NotAfter (Get-Date).AddYears(10)

   PSParentPath: Microsoft.PowerShell.Security\Certificate::LocalMachine\My

Thumbprint                                Subject
----------                                -------
72C6BDE7EDCF21E8CC3A6A0D957D3B81BEA6A208  CN=testserver1
  • -DnsName: ドメイン名を指定します。
  • -CertStoreLocation: 作成した証明書の格納先を指定します。http.sysから参照できるよう証明書ストアとして「ローカルコンピューターの個人(\LocalMachine\My)」を指定します。
  • -FriendlyName: 管理ツール等で他の識別できるような任意の名前にします。
  • -NotAfter: 証明書の有効期限終了日時を指定します。ここでは10年後の日時を指定しています。

サーバ証明書の登録

httpsのURLで使用するサーバ証明書をhttp.sysに登録します。

  1. 登録時に使用する任意のGUIDの生成
    サーバ証明書の登録時に任意のGUIDを指定する必要があり、その値を作成します。
    PS> New-Guid
    Guid
    ----
    63b4fc59-dbe3-417a-a847-ae5b27adf0e1
    
  2. サーバ証明書の登録
    独自ドメイン名・ポート番号に対応するサーバ証明書をhttp.sysに登録します。
    管理者権限のPowerShell上で次のコマンドを実行します。
    PS> netsh http add sslcert hostnameport=testserver1:44334 `
     certhash=72C6BDE7EDCF21E8CC3A6A0D957D3B81BEA6A208 `
     appid='{63b4fc59-dbe3-417a-a847-ae5b27adf0e1}' `
     certstorename=MY
    
    SSL 証明書を正常に追加しました
    
    • certhash: 紐づける証明書を証明書のハッシュ値で指定します。前節のThumbprintの値か、Windows上で開いた証明書の「拇印」の値を指定します。
    • appid: 後でこの登録を識別するための任意のGUIDを指定します。前手順で作成したGUIDを指定します。
    • certstorename: 証明書のストア名を指定します。http.sysで参照するため、ローカルコンピューター(“LocalMachin”)のストアを指定する必要があります。
      既定値は「ローカルコンピュータの個人(\LocalMachine\My)」であり、本来であれば指定する必要はありませんが、netshのバグなのか指定しないと次のエラーになります。
      SSL 証明書を追加できませんでした。エラー: 87
      パラメーターが間違っています。

信頼するサーバ証明書として登録

サーバ証明書のエクスポート

後の手順で信頼する証明書として登録するために、作成したサーバ証明書をエクスポートします。
管理者権限のPowerShellで次のコマンドを実行します。

PS> $cert = Get-ChildItem -Path Cert:\LocalMachine\MyC6BDE7EDCF21E8CC3A6A0D957D3B81BEA6A208
PS> Export-Certificate -Cert $cert -FilePath testserver1.der -Type CERT

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       2020/04/06     14:17            802 testserver1.der
  • Get-ChildItemの-Pathには、証明書ストアにあるエクスポート対象の証明書ハッシュを指定します。
  • Export-Certificateの-FilePathは適宜書き換えてください。

信頼する証明書としての登録

実行ユーザでのみ信頼する場合、非管理者権限のPowerShellで次のようにコマンドを実行します。
登録先のストアは、実行ユーザの「信頼されたルート証明機関」である”\CurrentUser\Root”を指定しています。

PS> Import-Certificate -FilePath testserver1.der -CertStoreLocation Cert:\CurrentUser\Root         

   PSParentPath: Microsoft.PowerShell.Security\Certificate::CurrentUser\Root

Thumbprint                                Subject
----------                                -------
72C6BDE7EDCF21E8CC3A6A0D957D3B81BEA6A208  CN=testserver1

ローカルコンピュータの全ユーザで信頼する場合、管理者権限で次のコマンドを実行します。
登録先のストアはローカルコンピュータの「信頼されたルート証明機関」である”\LocalMachine\Root”を指定しています。

PS> Import-Certificate -FilePath testserver1.der -CertStoreLocation Cert:\LocalMachine\Root

   PSParentPath: Microsoft.PowerShell.Security\Certificate::LocalMachine\Root

Thumbprint                                Subject
----------                                -------
72C6BDE7EDCF21E8CC3A6A0D957D3B81BEA6A208  CN=testserver1

動作確認

デバッグを開始して、ブラウザでhttpsのURLを開きます。
証明書のエラーが表示されないことを確認します。

参考

作成したサーバ証明書の確認

作成したサーバ証明書は次の手順で確認できます。

  1. 管理者権限で管理コンソール(mmc.exe)を開き、[ファイル]-[スナップインの追加と削除]を選択します。
  2. スナップインの追加と削除ウインドウで[証明書]を追加します。
    この際、[コンピューターアカウント]-[ローカルコンピューター]を選択します。
  3. 作成したサーバ証明書は「個人」の「証明書」にあります。


(adsbygoogle = window.adsbygoogle || []).push({});


(adsbygoogle = window.adsbygoogle || []).push({});

-1. システムエンジニアリング, IIS, 基盤技術

執筆者:

関連記事

slf4jとlog4j2を使たデバッグログの出力方法

Webアプリやスタンドアロンアプリの開発でデバッグログやトレースログを出したい場合があります。 とりあえず、ロガーのログレベルをdebugやtraceに下げればいいや、と設定してもログが出力されない場 …

JavaでのZIP暗号化の考察

法務系業務を行うシステムを設計するにあたり、次のような要件がありました。 CSVファイルの暗号化方式として、当初からパスワード付きZIPファイルの使用を検討していたため、ZIP圧縮を使用する前提で調査 …

Javaでのパスワード付きzipファイルの圧縮/解凍方法(ZipCrypto/AES)

先日、JavaでのZIP暗号化の考察という記事を書きましたが、zip4jのメンテナンスが再開されており、バージョン2系が公開されていましたので、これを使って通常のzip圧縮/解凍、パスワード付きzip …

DOSバッチリファレンス

ちょっとした事でbatファイルを作成することが多い。 そのたびにネット検索するのが非効率なため、リファレンス化しようと思う。 そういう目的なので、自分がよく調べる項目に絞っている。 開発時の注意点 直 …

DB操作フレームワーク はJPA or mybatis?

開発に向けた準備で、開発標準を準備するフレームワーク(FW)チーム、それらを使って実装を行う業務チームが集まって、「DB操作を行うためのFWは何を使うか?」という協議になった。 FWチームは、FW・J …

プロフィール ゆっきーです。
都内でシステムエンジニアをやっています。
もっと詳細を見る