Apache 搭載の Linux で ASP.NET Core をホストするHost ASP.NET Core on Linux with Apache

作成者: Shayne BoyerBy Shayne Boyer

このガイドでは、CentOS 7 上にリバース プロキシ サーバーとして Apache をセットアップし、Kestrel 上で実行されている ASP.NET Core Web アプリに HTTP トラフィックを転送する方法について説明します。Using this guide, learn how to set up Apache as a reverse proxy server on CentOS 7 to redirect HTTP traffic to an ASP.NET Core web app running on Kestrel. mod_proxy 拡張機能および関連するモジュールは、サーバーのリバース プロキシを作成します。The mod_proxy extension and related modules create the server's reverse proxy.

必須コンポーネントPrerequisites

  1. CentOS 7 を実行しているサーバーと、sudo 特権を持つ標準ユーザー アカウントServer running CentOS 7 with a standard user account with sudo privilege
  2. ASP.NET Core アプリASP.NET Core app

アプリの発行Publish the app

リリース構成の自己完結型の展開として CentOS 7 ランタイム (centos.7-x64) にアプリを発行します。Publish the app as a self-contained deployment in Release configuration for the CentOS 7 runtime (centos.7-x64). bin/Release/netcoreapp2.0/centos.7-x64/publish フォルダーの内容を、SCP、FTP、またはその他のファイル転送方法を使ってサーバーにコピーします。Copy the contents of the bin/Release/netcoreapp2.0/centos.7-x64/publish folder to the server using SCP, FTP, or other file transfer method.

注意

運用展開シナリオの場合、継続的インテグレーション ワークフローが、アプリの発行処理とサーバーへの資産のコピーを行います。Under a production deployment scenario, a continuous integration workflow does the work of publishing the app and copying the assets to the server.

プロキシ サーバーを構成するConfigure a proxy server

リバース プロキシは、動的 Web アプリを提供するための一般的な仕組みです。A reverse proxy is a common setup for serving dynamic web apps. リバース プロキシは HTTP 要求を終了させ、ASP.NET アプリに転送します。The reverse proxy terminates the HTTP request and forwards it to the ASP.NET app.

プロキシ サーバーは、クライアント要求を処理せずに他のサーバーに転送するサーバーです。A proxy server is one which forwards client requests to another server instead of fulfilling requests itself. リバース プロキシは、一般的に任意のクライアントに代わって固定の送信先に転送します。A reverse proxy forwards to a fixed destination, typically on behalf of arbitrary clients. このガイドでは、Kestrel が ASP.NET Core アプリを提供しているものと同じサーバー上で実行されるリバース プロキシとして Apache を構成します。In this guide, Apache is configured as the reverse proxy running on the same server that Kestrel is serving the ASP.NET Core app.

要求はリバース プロキシによって転送されます。そのため、Microsoft.AspNetCore.HttpOverrides パッケージの Forwarded Headers Middleware を使用します。Because requests are forwarded by reverse proxy, use the Forwarded Headers Middleware from the Microsoft.AspNetCore.HttpOverrides package. リダイレクト URI とその他のセキュリティ ポリシーを正しく機能させるために、このミドルウェアは、X-Forwarded-Proto ヘッダーを利用して、Request.Scheme を更新します。The middleware updates the Request.Scheme, using the X-Forwarded-Proto header, so that redirect URIs and other security policies work correctly.

任意の認証ミドルウェアを使用する場合は、Forwarded Headers Middleware を最初に実行する必要があります。When using any type of authentication middleware, the Forwarded Headers Middleware must run first. この順序により、認証ミドルウェアはヘッダーの値を利用して、正しいリダイレクト URI を生成できます。This ordering ensures that the authentication middleware can consume the header values and generate correct redirect URIs.

UseAuthentication や同様の認証スキームのミドルウェアを呼び出す前に、Startup.ConfigureUseForwardedHeaders メソッドを呼び出します。Invoke the UseForwardedHeaders method in Startup.Configure before calling UseAuthentication or similar authentication scheme middleware. ミドルウェアを構成して、X-Forwarded-For および X-Forwarded-Proto ヘッダーを転送します。Configure the middleware to forward the X-Forwarded-For and X-Forwarded-Proto headers:

app.UseForwardedHeaders(new ForwardedHeadersOptions
{
    ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});

app.UseAuthentication();

ミドルウェアに対して ForwardedHeadersOptions が指定されていない場合、転送される既定のヘッダーは None です。If no ForwardedHeadersOptions are specified to the middleware, the default headers to forward are None.

プロキシ サーバーとロード バランサーの背後でホストされているアプリでは、追加の構成が必要になる場合があります。Additional configuration might be required for apps hosted behind proxy servers and load balancers. 詳細については、「プロキシ サーバーとロード バランサーを使用するために ASP.NET Core を構成する」を参照してください。For more information, see Configure ASP.NET Core to work with proxy servers and load balancers.

Apache をインストールするInstall Apache

CentOS パッケージを最新の安定したバージョンに更新します。Update CentOS packages to their latest stable versions:

sudo yum update -y

1 つの yum コマンドで、CentOS に Apache Web サーバーをインストールします。Install the Apache web server on CentOS with a single yum command:

sudo yum -y install httpd mod_ssl

コマンド実行後の出力例:Sample output after running the command:

Downloading packages:
httpd-2.4.6-40.el7.centos.4.x86_64.rpm               | 2.7 MB  00:00:01
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
Installing : httpd-2.4.6-40.el7.centos.4.x86_64      1/1 
Verifying  : httpd-2.4.6-40.el7.centos.4.x86_64      1/1 

Installed:
httpd.x86_64 0:2.4.6-40.el7.centos.4

Complete!

注意

この例では、CentOS 7 のバージョンが 64 ビットなので、出力は httpd.86_64 を反映しています。In this example, the output reflects httpd.86_64 since the CentOS 7 version is 64 bit. Apache がインストールされている場所を確認するには、コマンド プロンプトから whereis httpd を実行します。To verify where Apache is installed, run whereis httpd from a command prompt.

Apache をリバース プロキシとして構成するConfigure Apache for reverse proxy

Apache の構成ファイルは、/etc/httpd/conf.d/ ディレクトリ内にあります。Configuration files for Apache are located within the /etc/httpd/conf.d/ directory. /etc/httpd/conf.modules.d/ 内のモジュール構成ファイルに加え、拡張子が .conf のファイルがアルファベット順で処理されます。このディレクトリには、モジュールの読み込みに必要な構成ファイルが含まれています。Any file with the .conf extension is processed in alphabetical order in addition to the module configuration files in /etc/httpd/conf.modules.d/, which contains any configuration files necessary to load modules.

アプリ用に hellomvc.conf という名前の構成ファイルを作成します。Create a configuration file, named hellomvc.conf, for the app:

<VirtualHost *:80>
    ProxyPreserveHost On
    ProxyPass / http://127.0.0.1:5000/
    ProxyPassReverse / http://127.0.0.1:5000/
    ServerName www.example.com
    ServerAlias *.example.com
    ErrorLog ${APACHE_LOG_DIR}hellomvc-error.log
    CustomLog ${APACHE_LOG_DIR}hellomvc-access.log common
</VirtualHost>

VirtualHost ブロックは、サーバー上の 1 つまたは複数のファイルに複数回出現することができます。The VirtualHost block can appear multiple times, in one or more files on a server. 上記の構成ファイルでは、Apache はポート 80 でパブリック トラフィックを受け入れます。In the preceding configuration file, Apache accepts public traffic on port 80. ドメイン www.example.com が提供されており、別名 *.example.com は同じ Web サイトに解決されます。The domain www.example.com is being served, and the *.example.com alias resolves to the same website. 詳しくは、「名前ベースのバーチャル ホスト」をご覧ください。See Name-based virtual host support for more information. 要求は、ルートにおいて、127.0.0.1 にあるサーバーのポート 5000 にプロキシされます。Requests are proxied at the root to port 5000 of the server at 127.0.0.1. 双方向通信の場合は、ProxyPassProxyPassReverse が必要です。For bi-directional communication, ProxyPass and ProxyPassReverse are required.

警告

VirtualHost ブロックで適切な ServerName ディレクティブを指定しないと、アプリにセキュリティ上の脆弱性が生じます。Failure to specify a proper ServerName directive in the VirtualHost block exposes your app to security vulnerabilities. 親ドメイン全体を制御する場合、サブドメイン ワイルドカード バインド (たとえば、*.example.com) にこのセキュリティ リスクはありません (脆弱である *.com とは対照的)。Subdomain wildcard binding (for example, *.example.com) doesn't pose this security risk if you control the entire parent domain (as opposed to *.com, which is vulnerable). 詳細については、rfc7230 セクション-5.4 を参照してください。See rfc7230 section-5.4 for more information.

ErrorLog および CustomLog ディレクティブを使って、VirtualHost ごとにログを構成できます。Logging can be configured per VirtualHost using ErrorLog and CustomLog directives. ErrorLog は、サーバーがエラーをログに記録する場所です。CustomLog には、ログ ファイルのファイル名と形式を設定します。ErrorLog is the location where the server logs errors, and CustomLog sets the filename and format of log file. この例では、要求の情報がログに記録される場所です。In this case, this is where request information is logged. 1 つの要求につき 1 行が記録されます。There's one line for each request.

ファイルを保存し、構成をテストします。Save the file and test the configuration. すべてに合格すると、応答は Syntax [OK] になります。If everything passes, the response should be Syntax [OK].

sudo service httpd configtest

Apache を再起動します。Restart Apache:

sudo systemctl restart httpd
sudo systemctl enable httpd

アプリの監視Monitoring the app

これで、http://localhost:80 に対して行われた要求を Kestrel で実行されている ASP.NET Core アプリ (http://127.0.0.1:5000) に転送するように Apache が設定されました。Apache is now setup to forward requests made to http://localhost:80 to the ASP.NET Core app running on Kestrel at http://127.0.0.1:5000. ただし、Apache は Kestrel プロセスを管理するようには設定されていません。However, Apache isn't set up to manage the Kestrel process. systemd を使って、基礎 Web アプリを起動して監視するサービス ファイルを作成します。Use systemd and create a service file to start and monitor the underlying web app. systemd は init システムであり、プロセスを起動、停止、管理するためのさまざまな高性能機能を提供します。systemd is an init system that provides many powerful features for starting, stopping, and managing processes.

サービス ファイルを作成するCreate the service file

次のように、サービス定義ファイルを作成します。Create the service definition file:

sudo nano /etc/systemd/system/kestrel-hellomvc.service

アプリのサービス ファイルの例を次に示します。An example service file for the app:

[Unit]
Description=Example .NET Web API App running on CentOS 7

[Service]
WorkingDirectory=/var/aspnetcore/hellomvc
ExecStart=/usr/local/bin/dotnet /var/aspnetcore/hellomvc/hellomvc.dll
Restart=always
# Restart service after 10 seconds if dotnet service crashes
RestartSec=10
SyslogIdentifier=dotnet-example
User=apache
Environment=ASPNETCORE_ENVIRONMENT=Production 

[Install]
WantedBy=multi-user.target

注意

ユーザーapache が構成で使用されない場合、ユーザーを先に作成し、ファイルの適切な所有権を与える必要があります。User — If the user apache isn't used by the configuration, the user must be created first and given proper ownership for files.

注意

構成プロバイダーが環境変数を読み取れるようにするために、一部の値 (たとえば SQL の接続文字列) をエスケープする必要があります。Some values (for example, SQL connection strings) must be escaped for the configuration providers to read the environment variables. 次のコマンドを使用して、構成ファイルで使用するために適切にエスケープされた値を生成します。Use the following command to generate a properly escaped value for use in the configuration file:

systemd-escape "<value-to-escape>"

ファイルを保存し、サービスを有効にします。Save the file and enable the service:

systemctl enable kestrel-hellomvc.service

サービスを起動し、動作を確認します。Start the service and verify that it's running:

systemctl start kestrel-hellomvc.service
systemctl status kestrel-hellomvc.service

● kestrel-hellomvc.service - Example .NET Web API App running on CentOS 7
    Loaded: loaded (/etc/systemd/system/kestrel-hellomvc.service; enabled)
    Active: active (running) since Thu 2016-10-18 04:09:35 NZDT; 35s ago
Main PID: 9021 (dotnet)
    CGroup: /system.slice/kestrel-hellomvc.service
            └─9021 /usr/local/bin/dotnet /var/aspnetcore/hellomvc/hellomvc.dll

リバース プロキシが構成され、Kestrel は systemd 経由で管理されます。これで Web アプリは完全に構成され、http://localhost でローカル コンピューター上のブラウザーからアクセスできます。With the reverse proxy configured and Kestrel managed through systemd, the web app is fully configured and can be accessed from a browser on the local machine at http://localhost. 応答ヘッダーを調べると、Server ヘッダーでは ASP.NET Core アプリが Kestrel によって提供されていることが示されています。Inspecting the response headers, the Server header indicates that the ASP.NET Core app is served by Kestrel:

HTTP/1.1 200 OK
Date: Tue, 11 Oct 2016 16:22:23 GMT
Server: Kestrel
Keep-Alive: timeout=5, max=98
Connection: Keep-Alive
Transfer-Encoding: chunked

ログを表示するViewing logs

Kestrel を使う Web アプリは systemd を使って管理されるため、イベントとプロセスは中央のジャーナルに記録されます。Since the web app using Kestrel is managed using systemd, events and processes are logged to a centralized journal. ただし、このジャーナルには、systemd によって管理されるすべてのサービスとプロセスのエントリが含まれます。However, this journal includes entries for all of the services and processes managed by systemd. kestrel-hellomvc.service 固有の項目を表示するには、次のコマンドを使用します。To view the kestrel-hellomvc.service-specific items, use the following command:

sudo journalctl -fu kestrel-hellomvc.service

時間フィルタリングの場合は、コマンドで時間のオプションを指定します。For time filtering, specify time options with the command. たとえば、現在の日付でフィルター処理するには --since today を使い、前の 1 時間のエントリを参照するには --until 1 hour ago を使います。For example, use --since today to filter for the current day or --until 1 hour ago to see the previous hour's entries. 詳しくは、journalctl の man ページをご覧ください。For more information, see the man page for journalctl.

sudo journalctl -fu kestrel-hellomvc.service --since "2016-10-18" --until "2016-10-18 04:00"

アプリのセキュリティ保護Securing the app

ファイアウォールを構成するConfigure firewall

Firewalld は、ネットワーク ゾーンをサポートするファイアウォールを管理するための動的デーモンです。Firewalld is a dynamic daemon to manage the firewall with support for network zones. ポートとパケットのフィルター処理は、iptables によって引き続き管理できます。Ports and packet filtering can still be managed by iptables. Firewalld は既定でインストールされます。Firewalld should be installed by default. yum を使ってパッケージをインストールしたり、インストールされていることを確認したりできます。yum can be used to install the package or verify it's installed.

sudo yum install firewalld -y

アプリに必要なポートのみを開くには、firewalld を使います。Use firewalld to open only the ports needed for the app. この場合、ポート 80 と 443 が使用されています。In this case, port 80 and 443 are used. 次のコマンドは、ポート 80 と 443 が永続的に開かれるように設定します。The following commands permanently set ports 80 and 443 to open:

sudo firewall-cmd --add-port=80/tcp --permanent
sudo firewall-cmd --add-port=443/tcp --permanent

ファイアウォールの設定を再度読み込みます。Reload the firewall settings. 既定のゾーンで使用できるサービスとポートを確認します。Check the available services and ports in the default zone. オプションは firewall-cmd -h を調べることで使用できます。Options are available by inspecting firewall-cmd -h.

sudo firewall-cmd --reload
sudo firewall-cmd --list-all
public (default, active)
interfaces: eth0
sources: 
services: dhcpv6-client
ports: 443/tcp 80/tcp
masquerade: no
forward-ports: 
icmp-blocks: 
rich rules: 

SSL の構成SSL configuration

SSL 用に Apache を構成するには、mod_ssl モジュールを使います。To configure Apache for SSL, the mod_ssl module is used. httpd モジュールがインストールされていると、mod_ssl モジュールもインストールされています。When the httpd module was installed, the mod_ssl module was also installed. インストールされていない場合は、yum を使って構成に追加します。If it wasn't installed, use yum to add it to the configuration.

sudo yum install mod_ssl

SSL を強制するには、mod_rewrite モジュールをインストールして URL の書き換えを有効にします。To enforce SSL, install the mod_rewrite module to enable URL rewriting:

sudo yum install mod_rewrite

hellomvc.conf ファイルを変更して、URL の書き換えを有効にし、ポート 443 での通信をセキュリティで保護します。Modify the hellomvc.conf file to enable URL rewriting and secure communication on port 443:

<VirtualHost *:80>
    RewriteEngine On
    RewriteCond %{HTTPS} !=on
    RewriteRule ^/?(.*) https://%{SERVER_NAME}/ [R,L]
</VirtualHost>

<VirtualHost *:443>
    ProxyPreserveHost On
    ProxyPass / http://127.0.0.1:5000/
    ProxyPassReverse / http://127.0.0.1:5000/
    ErrorLog /var/log/httpd/hellomvc-error.log
    CustomLog /var/log/httpd/hellomvc-access.log common
    SSLEngine on
    SSLProtocol all -SSLv2
    SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:!RC4+RSA:+HIGH:+MEDIUM:!LOW:!RC4
    SSLCertificateFile /etc/pki/tls/certs/localhost.crt
    SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
</VirtualHost>

注意

この例では、ローカルで生成された証明書を使います。This example is using a locally-generated certificate. SSLCertificateFile は、ドメイン名のプライマリ証明書ファイルです。SSLCertificateFile should be the primary certificate file for the domain name. SSLCertificateKeyFile は、CSR の作成時に生成されるキー ファイルです。SSLCertificateKeyFile should be the key file generated when CSR is created. SSLCertificateChainFile は、証明機関から提供された中間証明書ファイル (存在する場合) です。SSLCertificateChainFile should be the intermediate certificate file (if any) that was supplied by the certificate authority.

ファイルを保存し、構成をテストします。Save the file and test the configuration:

sudo service httpd configtest

Apache を再起動します。Restart Apache:

sudo systemctl restart httpd

Apache に関するその他の推奨事項Additional Apache suggestions

その他のヘッダーAdditional headers

悪意のある攻撃から防御するために、変更または追加する必要があるヘッダーがいくつかあります。In order to secure against malicious attacks, there are a few headers that should either be modified or added. 必ず mod_headers モジュールをインストールします。Ensure that the mod_headers module is installed:

sudo yum install mod_headers

Apache をクリックジャッキング攻撃から保護するSecure Apache from clickjacking attacks

クリックジャッキングは "UI 着せ替え攻撃" とも呼ばれ、Web サイトの訪問者を騙して現在訪れているものとは異なるページのリンクやボタンをクリックさせる悪意のある攻撃です。Clickjacking, also known as a UI redress attack, is a malicious attack where a website visitor is tricked into clicking a link or button on a different page than they're currently visiting. サイトをセキュリティで保護するには、X-FRAME-OPTIONS を使います。Use X-FRAME-OPTIONS to secure the site.

httpd.conf ファイルを編集します。Edit the httpd.conf file:

sudo nano /etc/httpd/conf/httpd.conf

Header append X-FRAME-OPTIONS "SAMEORIGIN" を追加します。Add the line Header append X-FRAME-OPTIONS "SAMEORIGIN". ファイルを保存します。Save the file. Apache を再起動します。Restart Apache.

MIME タイプ スニッフィングMIME-type sniffing

X-Content-Type-Options ヘッダーは、Internet Explorer を "MIME スニッフィング" から防ぎます (ファイルの内容からファイルの Content-Type を判断します)。The X-Content-Type-Options header prevents Internet Explorer from MIME-sniffing (determining a file's Content-Type from the file's content). サーバーが nosniff オプションを指定して Content-Type ヘッダーを text/html に設定すると、Internet Explorer はファイルの内容に関係なく text/html として内容をレンダリングします。If the server sets the Content-Type header to text/html with the nosniff option set, Internet Explorer renders the content as text/html regardless of the file's content.

httpd.conf ファイルを編集します。Edit the httpd.conf file:

sudo nano /etc/httpd/conf/httpd.conf

Header set X-Content-Type-Options "nosniff" を追加します。Add the line Header set X-Content-Type-Options "nosniff". ファイルを保存します。Save the file. Apache を再起動します。Restart Apache.

負荷分散Load Balancing

この例では、同じインスタンス コンピューターに CentOS 7 と Kestrel をインストールし、Apache をセットアップおよび構成する方法を示します。This example shows how to setup and configure Apache on CentOS 7 and Kestrel on the same instance machine. 単一障害点を持たないように、mod_proxy_balancer を使い、VirtualHost を変更することで、Apache プロキシ サーバーの背後で複数インスタンスの Web アプを管理できるようにします。In order to not have a single point of failure; using mod_proxy_balancer and modifying the VirtualHost would allow for managing multiple instances of the web apps behind the Apache proxy server.

sudo yum install mod_proxy_balancer

次に示す構成ファイルでは、ポート 5001 上で実行するように hellomvc アプリの追加インスタンスを設定しています。In the configuration file shown below, an additional instance of the hellomvc app is setup to run on port 5001. Proxy セクションは、2 メンバーのバランサー構成を使って byrequests を負荷分散するように設定されています。The Proxy section is set with a balancer configuration with two members to load balance byrequests.

<VirtualHost *:80>
    RewriteEngine On
    RewriteCond %{HTTPS} !=on
    RewriteRule ^/?(.*) https://%{SERVER_NAME}/ [R,L]
</VirtualHost>

<VirtualHost *:443>
    ProxyPass / balancer://mycluster/ 

    ProxyPassReverse / http://127.0.0.1:5000/
    ProxyPassReverse / http://127.0.0.1:5001/

    <Proxy balancer://mycluster>
        BalancerMember http://127.0.0.1:5000
        BalancerMember http://127.0.0.1:5001 
        ProxySet lbmethod=byrequests
    </Proxy>

    <Location />
        SetHandler balancer
    </Location>
    ErrorLog /var/log/httpd/hellomvc-error.log
    CustomLog /var/log/httpd/hellomvc-access.log common
    SSLEngine on
    SSLProtocol all -SSLv2
    SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:!RC4+RSA:+HIGH:+MEDIUM:!LOW:!RC4
    SSLCertificateFile /etc/pki/tls/certs/localhost.crt
    SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
</VirtualHost>

速度の制限Rate Limits

httpd モジュールに含まれる mod_ratelimit を使って、クライアントの帯域幅を制限できます。Using mod_ratelimit, which is included in the httpd module, the bandwidth of clients can be limited:

sudo nano /etc/httpd/conf.d/ratelimit.conf

次のファイルの例では、ルートの場所の下での帯域幅を 600 KB/秒に制限しています。The example file limits bandwidth as 600 KB/sec under the root location:

<IfModule mod_ratelimit.c>
    <Location />
        SetOutputFilter RATE_LIMIT
        SetEnv rate-limit 600
    </Location>
</IfModule>