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

Sourabh Shirhatti による投稿By Sourabh Shirhatti

このガイドでは、Ubuntu 16.04 サーバーで本稼働対応の ASP.NET Core 環境をセットアップする方法について説明します。This guide explains setting up a production-ready ASP.NET Core environment on an Ubuntu 16.04 Server.

注意

Ubuntu 14.04 のsupervisord Kestrel プロセスを監視するためのソリューションとしてはお勧めします。For Ubuntu 14.04, supervisord is recommended as a solution for monitoring the Kestrel process. systemd Ubuntu 14.04 では使用できません。systemd isn't available on Ubuntu 14.04. このドキュメントの以前のバージョンを参照してくださいです。See previous version of this document.

このガイドでは:This guide:

  • リバース プロキシ サーバーの背後にある既存の ASP.NET Core アプリケーションを配置します。Places an existing ASP.NET Core app behind a reverse proxy server.
  • リバース プロキシ サーバーを設定すると、Kestrel web サーバーに要求を転送します。Sets up the reverse proxy server to forward requests to the Kestrel web server.
  • デーモンとしての起動時に web アプリが実行されることを確認します。Ensures the web app runs on startup as a daemon.
  • Web アプリを再起動するプロセスの管理ツールを構成します。Configures a process management tool to help restart the web app.

必須コンポーネントPrerequisites

  1. Ubuntu 16.04 サーバーへのアクセスと sudo 特権が与えられた標準ユーザー アカウントAccess to an Ubuntu 16.04 Server with a standard user account with sudo privilege
  2. 既存の ASP.NET Core アプリケーションAn existing ASP.NET Core app

アプリ経由でコピーします。Copy over the app

実行dotnet 発行サーバーで実行できる自己完結型のディレクトリに、アプリのパッケージを開発環境からです。Run dotnet publish from the dev environment to package an app into a self-contained directory that can run on the server.

どのようなツールを使用してサーバーに ASP.NET Core アプリケーションのコピーは、組織のワークフロー (たとえば、SCP、FTP など) に統合します。Copy the ASP.NET Core app to the server using whatever tool integrates into the organization's workflow (for example, SCP, FTP). 次のようにアプリをテストします。Test the app, for example:

  • コマンドラインから実行dotnet <app_assembly>.dllです。From the command line, run dotnet <app_assembly>.dll.
  • ブラウザーで、http://<serveraddress>:<port> に移動し、アプリが Linux で動作することを検証します。In a browser, navigate to http://<serveraddress>:<port> to verify the app works on Linux.

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

リバース プロキシは、動的な web アプリの送信用の共通のセットアップです。A reverse proxy is a common setup for serving dynamic web apps. リバース プロキシは、HTTP 要求を終了し、ASP.NET Core アプリケーションに転送します。A reverse proxy terminates the HTTP request and forwards it to the ASP.NET Core app.

リバース プロキシ サーバーを利用する理由Why use a reverse proxy server?

Kestrel は、ASP.NET Core から動的なコンテンツを提供しているに便利です。Kestrel is great for serving dynamic content from ASP.NET Core. ただし、web サービス機能は、IIS、Apache、Nginx などのサーバーと豊富な機能としてはありません。However, the web serving capabilities aren't as feature rich as servers such as IIS, Apache, or Nginx. リバース プロキシ サーバーは、静的なコンテンツ、要求をキャッシュ、要求、および HTTP サーバーからの SSL ターミネーションを圧縮するなどの作業をオフロードできます。A reverse proxy server can offload work such as serving static content, caching requests, compressing requests, and SSL termination from the HTTP server. リバース プロキシ サーバーは専用コンピューター上に置かれることもあれば、HTTP サーバーと並んで展開されることもあります。A reverse proxy server may reside on a dedicated machine or may be deployed alongside an HTTP server.

このガイドの目的のために、単一インスタンスの Nginx が使用されます。For the purposes of this guide, a single instance of Nginx is used. HTTP サーバーと並んで、同じサーバー上で実行されます。It runs on the same server, alongside the HTTP server. 要件に基づき、異なる設定が選択すること。Based on requirements, a different setup may be chosen.

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

認証ミドルウェアの任意の型を使用する場合、転送ヘッダー ミドルウェアが最初に実行する必要があります。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.

呼び出す、 UseForwardedHeadersメソッドStartup.Configure呼び出す前にUseAuthenticationまたは類似の認証スキームのミドルウェア。Invoke the UseForwardedHeaders method in Startup.Configure before calling UseAuthentication or similar authentication scheme middleware. 転送するミドルウェアを構成、X-Forwarded-ForX-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.

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

sudo apt-get install nginx

注意

省略可能な Nginx モジュールをインストールする場合ソースから Nginx を構築する必要があります。If optional Nginx modules will be installed, building Nginx from source might be required.

apt-get を利用し、Nginx をインストールします。Use apt-get to install Nginx. インストーラーにより System V init スクリプトが作成されます。このスクリプトがシステム起動時に Nginx をデーモンとして実行します。The installer creates a System V init script that runs Nginx as daemon on system startup. Nginx は初めてのインストールとなるので、次を実行して明示的に起動します。Since Nginx was installed for the first time, explicitly start it by running:

sudo service nginx start

ブラウザーで Nginx の既定のランディング ページが表示されることを確認します。Verify a browser displays the default landing page for Nginx.

Nginx を構成するConfigure Nginx

ASP.NET Core アプリケーションに要求を転送するリバース プロキシとして Nginx を構成するには、変更 /etc/nginx/sites-available/defaultです。To configure Nginx as a reverse proxy to forward requests to your ASP.NET Core app, modify /etc/nginx/sites-available/default. テキスト エディターで開き、中身を次のものに変更します。Open it in a text editor, and replace the contents with the following:

server {
    listen        80;
    server_name   example.com *.example.com;
    location / {
        proxy_pass         http://localhost:5000;
        proxy_http_version 1.1;
        proxy_set_header   Upgrade $http_upgrade;
        proxy_set_header   Connection keep-alive;
        proxy_set_header   Host $http_host;
        proxy_cache_bypass $http_upgrade;
    }
}

ない場合server_nameNginx の一致が既定のサーバーを使用します。When no server_name matches, Nginx uses the default server. 既定のサーバーが定義されていない場合、最初のサーバー構成ファイルでは、既定のサーバーです。If no default server is defined, the first server in the configuration file is the default server. ベスト プラクティスとして、構成ファイルで 444 のステータス コードを返す特定の既定のサーバーを追加します。As a best practice, add a specific default server which returns a status code of 444 in your configuration file. 既定のサーバーの構成例を示します。A default server configuration example is:

server {
    listen   80 default_server;
    # listen [::]:80 default_server deferred;
    return   444;
}

上記の構成ファイルと、既定のサーバーと Nginx はホスト ヘッダーを持つポート 80 でパブリック トラフィックを受け付けるexample.comまたは*.example.comです。With the preceding configuration file and default server, Nginx accepts public traffic on port 80 with host header example.com or *.example.com. これらのホストと一致しない要求 Kestrel に転送されません。Requests not matching these hosts won't get forwarded to Kestrel. Nginx で Kestrel に一致する要求を転送するhttp://localhost:5000です。Nginx forwards the matching requests to Kestrel at http://localhost:5000. 参照してくださいnginx が要求をどのように処理するか詳細についてはします。See How nginx processes a request for more information.

警告

適切なを指定するserver_name ディレクティブセキュリティの脆弱性にアプリを公開します。Failure to specify a proper server_name directive exposes your app to security vulnerabilities. サブドメイン ワイルドカード バインド (たとえば、 *.example.com) 全体の親ドメインを制御する場合、このセキュリティ上のリスクは発生しません (to *.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.

Nginx 構成が確立されると、実行sudo nginx -t構成ファイルの構文を確認します。Once the Nginx configuration is established, run sudo nginx -t to verify the syntax of the configuration files. 構成ファイルのテストが成功した場合は、強制的に実行して、変更を取得する Nginxsudo nginx -s reloadです。If the configuration file test is successful, force Nginx to pick up the changes by running sudo nginx -s reload.

アプリの監視Monitoring the app

サーバーがセットアップへの要求を転送するhttp://<serveraddress>:80で Kestrel で実行されている ASP.NET Core アプリケーションにログオンhttp://127.0.0.1:5000です。The server is setup to forward requests made to http://<serveraddress>:80 on to the ASP.NET Core app running on Kestrel at http://127.0.0.1:5000. ただし、Nginx は Kestrel プロセスを管理するセットアップをされていません。However, Nginx isn't set up to manage the Kestrel process. systemdを起動し、基になる web アプリを監視するサービス ファイルを作成するために使用できます。systemd can be used to 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

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

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

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

[Install]
WantedBy=multi-user.target

注: 場合、ユーザー www データ使用されていない、構成によって、ここで定義したユーザー必要がありますで最初に作成されファイルの適切な所有権を指定します。Note: If the user www-data isn't used by the configuration, the user defined here must be created first and given proper ownership for files. 注: Linux には、区別するファイル システム。Note: Linux has a case-sensitive file system. 設定する ASPNETCORE_ENVIRONMENT"Production"、構成ファイルの検索中にappsettings です。Production.jsonではなく、 appsettings.production.jsonです。Setting ASPNETCORE_ENVIRONMENT to "Production" results in searching for the configuration file appsettings.Production.json, not appsettings.production.json.

注意

環境変数を読み取る構成プロバイダーのいくつかの値 (たとえば、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 Ubuntu
    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. 妨げている可能性があるすべてのファイアウォールがなければ、リモート コンピューターからアクセスできることもです。It's also accessible from a remote machine, barring any firewall that might be blocking. 応答ヘッダーの検査、Serverヘッダー Kestrel によって処理される ASP.NET Core アプリケーションを示しています。Inspecting the response headers, the Server header shows the ASP.NET Core app being 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

Web アプリから Kestrel を使用して、使用して管理systemd、すべてのイベントとプロセスは、一元的な履歴に記録されます。Since the web app using Kestrel is managed using systemd, all events and processes are logged to a centralized journal. ただし、このジャーナルには、systemd が管理するすべてのサービスとプロセスのすべてのエントリが含まれます。However, this journal includes all entries for all 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

さらに絞り込むには、時間オプションとして --since today--until 1 hour ago、あるいはこの 2 つの組み合わせを利用すれば、返されるエントリの数を減らすことができます。For further filtering, time options such as --since today, --until 1 hour ago or a combination of these can reduce the amount of entries returned.

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

アプリをセキュリティで保護します。Securing the app

AppArmor を有効にするEnable AppArmor

Linux セキュリティ モジュール (LSM) は、Linux 2.6 以降では Linux カーネルの一部であるフレームワークです。Linux Security Modules (LSM) is a framework that's part of the Linux kernel since Linux 2.6. LSM は、セキュリティ モジュールのさまざまな実装に対応しています。LSM supports different implementations of security modules. AppArmor は Mandatory Access Control システムを実装する LSM です。このシステムは、プログラムのリソース範囲を限定できます。AppArmor is a LSM that implements a Mandatory Access Control system which allows confining the program to a limited set of resources. AppArmor が有効であり、正しく構成されていることを確認します。Ensure AppArmor is enabled and properly configured.

ファイアウォールを構成します。Configuring the firewall

使用されていないすべての外部ポートを閉じます。Close off all external ports that are not in use. ufw (uncomplicated firewall/複雑ではないファイアウォール) は iptables のフロント エンドとなり、ファイアウォールを構成するためのコマンド ライン インターフェイスを提供します。Uncomplicated firewall (ufw) provides a front end for iptables by providing a command line interface for configuring the firewall. いることを確認ufw必要なポートのトラフィックを許可するように構成します。Verify that ufw is configured to allow traffic on any ports needed.

sudo apt-get install ufw
sudo ufw enable

sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

Nginx のセキュリティを強化するSecuring Nginx

Nginx の既定のディストリビューションでは SSL が有効になっていません。The default distribution of Nginx doesn't enable SSL. 追加のセキュリティ機能を有効にするには、ソースからビルドします。To enable additional security features, build from source.

ソースをダウンロードし、ビルド依存関係をインストールするDownload the source and install the build dependencies

# Install the build dependencies
sudo apt-get update
sudo apt-get install build-essential zlib1g-dev libpcre3-dev libssl-dev libxslt1-dev libxml2-dev libgd2-xpm-dev libgeoip-dev libgoogle-perftools-dev libperl-dev

# Download Nginx 1.10.0 or latest
wget http://www.nginx.org/download/nginx-1.10.0.tar.gz
tar zxf nginx-1.10.0.tar.gz

Nginx 応答名を変更するChange the Nginx response name

src/http/ngx_http_header_filter_module.c を編集します。Edit src/http/ngx_http_header_filter_module.c:

static char ngx_http_server_string[] = "Server: Web Server" CRLF;
static char ngx_http_server_full_string[] = "Server: Web Server" CRLF;

オプションを構成し、ビルドするConfigure the options and build

正規表現には PCRE ライブラリが必要です。The PCRE library is required for regular expressions. 正規表現は、ngx_http_rewrite_module の場所ディレクティブで使用されます。Regular expressions are used in the location directive for the ngx_http_rewrite_module. http_ssl_module により HTTPS プロトコル サポートが追加されます。The http_ssl_module adds HTTPS protocol support.

ように web アプリケーション ファイアウォールの使用を検討ModSecurityにアプリを強化します。Consider using a web app firewall like ModSecurity to harden the app.

./configure
--with-pcre=../pcre-8.38
--with-zlib=../zlib-1.2.8
--with-http_ssl_module
--with-stream
--with-mail=dynamic

SSL を構成するConfigure SSL

  • ポートで HTTPS トラフィックをリッスンするようにサーバーを構成する443を信頼された証明書機関 (CA) によって発行された有効な証明書を指定します。Configure the server to listen to HTTPS traffic on port 443 by specifying a valid certificate issued by a trusted Certificate Authority (CA).

  • 次のプラクティスを採用することによって、セキュリティを強化する /etc/nginx/nginx.confファイル。Harden the security by employing some of the practices depicted in the following /etc/nginx/nginx.conf file. たとえば、強力な暗号を選択したり、HTTP 経由のすべてのトラフィックを HTTPS にリダイレクトしたりします。Examples include choosing a stronger cipher and redirecting all traffic over HTTP to HTTPS.

  • HTTP Strict-Transport-Security (HSTS) ヘッダーを追加すると、クライアントが行う後続のすべての要求が HTTPS 経由のみになります。Adding an HTTP Strict-Transport-Security (HSTS) header ensures all subsequent requests made by the client are over HTTPS only.

  • Strict トランスポート セキュリティ ヘッダーを追加しないが、適切な選択またはmax-age場合は SSL は、今後は無効にします。Don't add the Strict-Transport-Security header or chose an appropriate max-age if SSL will be disabled in the future.

/etc/nginx/proxy.conf 構成ファイルを追加します。Add the /etc/nginx/proxy.conf configuration file:

proxy_redirect 			off;
proxy_set_header 		Host 			$host;
proxy_set_header		X-Real-IP 		$remote_addr;
proxy_set_header		X-Forwarded-For	$proxy_add_x_forwarded_for;
proxy_set_header    X-Forwarded-Proto $scheme;
client_max_body_size 	10m;
client_body_buffer_size 128k;
proxy_connect_timeout 	90;
proxy_send_timeout 		90;
proxy_read_timeout 		90;
proxy_buffers			32 4k;

/etc/nginx/nginx.conf 構成ファイルを編集します。Edit the /etc/nginx/nginx.conf configuration file. この例では、1 つの構成ファイルに http セクションと server セクションの両方が含まれています。The example contains both http and server sections in one configuration file.

http {
    include    /etc/nginx/proxy.conf;
    limit_req_zone $binary_remote_addr zone=one:10m rate=5r/s;
    server_tokens off;

    sendfile on;
    keepalive_timeout 29; # Adjust to the lowest possible value that makes sense for your use case.
    client_body_timeout 10; client_header_timeout 10; send_timeout 10;

    upstream hellomvc{
        server localhost:5000;
    }

    server {
        listen *:80;
        add_header Strict-Transport-Security max-age=15768000;
        return 301 https://$host$request_uri;
    }

    server {
        listen *:443    ssl;
        server_name     example.com;
        ssl_certificate /etc/ssl/certs/testCert.crt;
        ssl_certificate_key /etc/ssl/certs/testCert.key;
        ssl_protocols TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;
        ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
        ssl_ecdh_curve secp384r1;
        ssl_session_cache shared:SSL:10m;
        ssl_session_tickets off;
        ssl_stapling on; #ensure your cert is capable
        ssl_stapling_verify on; #ensure your cert is capable

        add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
        add_header X-Frame-Options DENY;
        add_header X-Content-Type-Options nosniff;

        #Redirects all traffic
        location / {
            proxy_pass  http://hellomvc;
            limit_req   zone=one burst=10 nodelay;
        }
    }
}

Nginx をクリックジャッキングから守るSecure Nginx from clickjacking

クリックジャッキングは、感染したユーザーのクリックを集めるという悪意のある手法です。Clickjacking is a malicious technique to collect an infected user's clicks. クリックジャッキングは被害者 (訪問者) をだまし、感染したサイトでクリックさせます。Clickjacking tricks the victim (visitor) into clicking on an infected site. X-フレームのオプションを使用、サイトをセキュリティで保護します。Use X-FRAME-OPTIONS to secure the site.

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

sudo nano /etc/nginx/nginx.conf

add_header X-Frame-Options "SAMEORIGIN"; を追加し、ファイルを保存し、Nginx を再起動します。Add the line add_header X-Frame-Options "SAMEORIGIN"; and save the file, then restart Nginx.

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

このヘッダーは応答コンテンツの種類をオーバーライドしないようにブラウザーに指示するので、ほとんどのブラウザーで MIME スニッフィングが阻止されます。This header prevents most browsers from MIME-sniffing a response away from the declared content type, as the header instructs the browser not to override the response content type. nosniff オプションを指定すると、サーバーがコンテンツを "text/html" と読むとき、ブラウザーはそれを "text/html" として表示します。With the nosniff option, if the server says the content is "text/html", the browser renders it as "text/html".

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

sudo nano /etc/nginx/nginx.conf

add_header X-Content-Type-Options "nosniff"; を追加し、ファイルを保存し、Nginx を再起動します。Add the line add_header X-Content-Type-Options "nosniff"; and save the file, then restart Nginx.