FICUSONLINE F9E
Nginx Proxy on Azure Windows Server
マイクロソフトのクラウドサービスAzureに登録すると、用途別に12ヶ月無料で利用できるサービスが幾つか提供されますが、最も実用的なサービスである仮想マシンは、LinuxとWindowsでOS毎に別々に利用できます。
Takanobu FuseAdministrator

14 min read

2 years ago

Cloud / Server

利用条件は、Standard B1s (1 vcpu、1 GiB メモリ)、ディスク:Premium SSD 64GB、動的IPv4アドレスとなっています。無料サービスのページから仮想マシンを作成する場合、これら無料枠で使用できる条件をデフォルトで選択してくれますが、OSの選択に制限があります。無料を前提条件として仮想マシンのページから直接作成する場合、OSの選択肢などが増えますが、デフォルトのディスクサイズ(32GBがデフォルトで割当てられた場合、後から無料枠の64GBに変更できます)が無料枠の64GBを超えてしまったり(Windows10, Windows Server 2019以降、より小さなディスクサイズへの変更不可)、静的IPがデフォルトで割当てられる(作成時点で動的に変更可)など課金トラップへの注意が必要です。

仮想マシンの作成は、パズルのようにCPU、メモリ、OS、ディスク、IPアドレス(動的か静的)という各ピースを組合せていく作業です。

無料枠のLinuxはOSも最新のものが選択でき、用途も多岐にわたり実用的なのですが、無料枠でWindowsを選択した場合、実質Windows Server 2016以前のOSしか選択肢はありません。無料でも一体何に使えば良いのか自分には分かりませんが、プロキシサーバ程度の負荷であれば問題なく利用できると考え、Nginxによるプロキシサーバを構築することにしました。リモートデスクトップの操作PowerShellの習得、忘れていたコマンドプロンプトの操作を思い出す良い機会にもなります。

Azure Nginx Proxy


構築プロセス

  1. VM(Virtual Machine)の作成(OS:Windows Server 2016)

  2. Ubuntu端末からVMへ接続(Remmina)

  3. Nginx, Certbot, OpenSSLのインストール(PowerShell, コマンドプロンプトによる操作)

  4. タスクスケジューラへの登録


1. VM(Virtual Machine)の作成(OS:Windows Server 2016)

Azureへの登録を済ませた上で、無料サービスのページからWindows仮想マシンを選択します。リソースグループ、仮想マシン名、Windowsのユーザ名とパスワードなどを入力。イメージはWindows (Windows Server 2016 Datacenter)を選択して下さい(イメージは任意)。サイズはデフォルト(B1s, 1CPU,1GBメモリ)です。リモートデスクトップのためのポートRDP(3389)、ウェブサーバ用ポートHTTP(80), HTTPS(443)オープン(許可)にします。OSのライセンスは必要ありません。確認及び作成ボタンをクリックすると仮想マシンが作成されます。作成後、仮想マシンの概要を確認して下さい(リンク先ボタンが表示されます)。

以降の作業で、仮想マシンの概要ページから任意のDNS名を登録しておくとIPアドレスを直接入力する手間が省けます。

Screenshot From 2022 12 14 16 53 53


2. Ubuntu端末からVMへ接続(Remmina)

作成した仮想マシンWindows Serverへの推奨接続方法はリモートデスクトップ(RDP)によるものなので、Ubuntuの標準リモートデスクトップアプリであるRemminaを使用して接続します。

注) 接続する前に、接続先で使用するキーボードのレイアウト (Japanese) をRemmina側の設定で指定して下さい。

Screenshot From 2022 12 05 16 11 20

まず初めにRemminaでインポートする接続先情報(IPアドレスまたはDNS名)が記載されたRDPファイルを仮想マシンの接続ページからダウンロードします。

Screenshot From 2022 11 30 16 13 54

次にRemminaで上記ダウンロードしたRDPファイルをインポートして下さい。

インポートすると接続先リストが表示されるので、ここをダブルクリックすると仮想マシンWindows Serverのコマンドプロンプト画面が表示されます。

Screenshot From 2022 11 30 16 15 48

以下仮想マシン上のコマンドプロンプト画面。

Screenshot From 2022 11 30 16 16 34

コマンドプロンプトにpowershellと入力してPowerShellを起動します。

Screenshot From 2022 11 30 17 50 45

WIndows Server 2016 PowerShell リファレンス
https://learn.microsoft.com/en-us/powershell/module/activedirectory/?view=windowsserver2016-ps

Windowsコマンドリファレンス
https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/windows-commands


3. Nginx, Certbot, OpenSSLのインストール(PowerShell, コマンドプロンプトによる操作)

3-1. PowerShellによるファイヤーウォールルール設定

OSのファイヤーウォールのため、デフォルトでは外部からウェブサーバへのアクセスが拒否されます。このためポート番号80.443へのアクセスを許可する設定をNew-NetFirewallRuleにより行います。

PS > New-NetFirewallRule -DisplayName 'HTTP-Inbound' -Direction Inbound -Action Allow -Protocol TCP -LocalPort @('80', '443')

Name                  : {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
DisplayName           : HTTP-Inbound
Description           :
DisplayGroup          :
Group                 :
Enabled               : True
Profile               : Any
Platform              : {}
Direction             : Inbound
Action                : Allow
EdgeTraversalPolicy   : Block
LooseSourceMapping    : False
LocalOnlyMapping      : False
Owner                 :
PrimaryStatus         : OK
Status                : The rule was parsed successfully from the store. (65536)
EnforcementStatus     : NotApplicable
PolicyStoreSource     : PersistentStore
PolicyStoreSourceType : Local

参考)上記ルールを除外する場合 Remove-NetFirewallRule

PS > Remove-NetFirewallRule -DisplayName 'HTTP-Inbound'

3-2. Nginxのダウンロード・インストール・起動

Nginx for Windows
https://nginx.org/en/docs/windows.html

ダウンロード
https://nginx.org/en/download.html

Invoke-WebRequestによるダウンロード。ダウンロード先フォルダは任意。

Expand-Archiveによる展開。展開したフォルダー内で起動コマンドstart nginxを実行すると起動します(この時点では設定ファイル未設定)。

PS > Invoke-WebRequest -Uri https://nginx.org/download/nginx-1.23.2.zip -Outfile ./nginx.zip
PS > Expand-Archive nginx.zip
PS > cd nginx/nginx-1.23.2
PS > start nginx

プロセス確認(tasklist)

PS > tasklist /fi "imagename eq nginx.exe"

Image Name           PID Session Name     Session#    Mem Usage
=============== ======== ============== ========== ============
nginx.exe            652 Console                 0      2 780 K
nginx.exe           1332 Console                 0      3 112 K

動作が確認できたら取り敢えず一時停止します。

PS > ./nginx.exe -s stop

コマンドプロンプトによるnginxコマンド

PowerShellで実行する場合には "nginx" を "./nginx.exe" に置き換えること。

Commands Description
nginx -s stop fast shutdown
nginx -s quit graceful shutdown
nginx -s reload changing configuration, starting new worker processes with a new configuration, graceful shutdown of old worker processes
nginx -s reopen re-opening log files

3-3. Certbotのダウンロード・インストール

SSL/TLS認証のため、Let's Encryptによる認証手続きをCertbotにより行います。

Certbot Windowsインストールインストラクション
https://certbot.eff.org/instructions?ws=nginx&os=windows

PowerShellで任意のディレクトリにダウンロード

PS > invoke-webrequest -uri https://dl.eff.org/certbot-beta-installer-win_amd64.exe -outfile ./certbot-beta-installer-win_amd64.exe

Windowsコンソールに戻りインストーラーを実行

PS > exit

C:\ > certbot-beta-installer-win_amd64.exe

以下コマンドプロンプトによる作業ですがPowerShellで全て置き換えられる筈です。

ヘルプで動作確認

C:\ > "program files/certbot/bin/certbot" --help
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

  certbot [SUBCOMMAND] [options] [-d DOMAIN] [-d DOMAIN] ...

Certbot can obtain and install HTTPS/TLS/SSL certificates.  By default,
it will attempt to use a webserver both for obtaining and installing the
certificate. The most common SUBCOMMANDS and flags are:

obtain, install, and renew certificates:
    (default) run   Obtain & install a certificate in your current webserver
    certonly        Obtain or renew a certificate, but do not install it
    renew           Renew all previously obtained certificates that are near
expiry
    enhance         Add security enhancements to your existing configuration
   -d DOMAINS       Comma-separated list of domains to obtain a certificate for
.....
.....

スタンドアローンモードで認証手続き

注) メールアドレスとドメインの入力が必要。認証取得には、ポート:80をオープンにする必要があるため、ウェブサーバは停止してから実行すること。

以下のディレクトリに認証ファイルが保存されます。

C:\ > "program files/certbot/bin/certbot" certonly --standalone
.....
.....
Successfully received certificate.
Certificate is saved at: C:\Certbot\live\ficus.myvnc.com\fullchain.pem
Key is saved at:         C:\Certbot\live\ficus.myvnc.com\privkey.pem
.....
.....

ここでWindowsにインストールされたnginxのディレクトリ構成を確認

C:\nginx\nginx-1.23.2 > dir
 Volume in drive C is Windows
 Volume Serial Number is 58AD-4A66

 Directory of C:\nginx\nginx-1.23.2

12/03/2022  05:07 AM     < DIR>          .
12/03/2022  05:07 AM     < DIR>          ..
12/03/2022  12:22 AM     < DIR>          conf
12/01/2022  08:15 AM     < DIR>          contrib
12/01/2022  08:15 AM     < DIR>          docs
12/03/2022  05:23 AM     < DIR>          html
12/03/2022  02:48 AM     < DIR>          logs
10/19/2022  01:38 PM         3,799,552 nginx.exe
12/01/2022  08:15 AM     < DIR>          temp
               2 File(s)      3,799,556 bytes
               8 Dir(s)  23,975,211,008 bytes free

新規設定ファイルを格納するためのconf.dフォルダを作成(mkdir)

C:\nginx\nginx-1.23.2 > dir conf
 Volume in drive C is Windows
 Volume Serial Number is 58AD-4A66

 Directory of C:\nginx\nginx-1.23.2\conf

12/03/2022  12:22 AM     < DIR>          .
12/03/2022  12:22 AM     < DIR>          ..
12/03/2022  02:34 AM     < DIR>          conf.d
10/19/2022  01:39 PM             1,103 fastcgi.conf
10/19/2022  01:39 PM             1,032 fastcgi_params
10/19/2022  01:39 PM             2,946 koi-utf
10/19/2022  01:39 PM             2,326 koi-win
10/19/2022  01:39 PM             5,448 mime.types
12/03/2022  02:15 PM               731 nginx.conf
10/19/2022  01:39 PM               653 scgi_params
10/19/2022  01:39 PM               681 uwsgi_params
10/19/2022  01:39 PM             3,736 win-utf
               9 File(s)         18,656 bytes
               3 Dir(s)  23,979,286,528 bytes free

conf.d/*confファイルを読み込むため、親設定ファイルを編集。

C:\ > notepad conf/nginx.conf

pid        logs/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    include conf.d/*.conf;

}

リバースプロキシとしての設定ファイルを新規に作成(Certbotにより作成された認証ファイルの指定など)

C:\ > notepad conf/conf.d/default.conf

server {
    server_name ficus.myvnc.com;
    server_tokens off;
    # access_log  /var/log/nginx/access.log;
    # error_log   /var/log/nginx/error.log error;

    location / {
        proxy_pass https://xx.xx.xx.xx:8080;
        proxy_set_header Host ficus.myvnc.com;
        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;

    }

    listen 443 ssl;
    ssl_certificate C:\Certbot\live\ficus.myvnc.com\fullchain.pem;
    ssl_certificate_key C:\Certbot\live\ficus.myvnc.com\privkey.pem;
    include C:\Certbot\options-ssl-nginx.conf;
    #ssl_dhparam C:\Certbot\ssl-dhparams.pem; 
}


server {
    if ($host = ficus.myvnc.com) {
        return 301 https://$host$request_uri;
    } 

    server_name ficus.myvnc.com;

    listen 80;
    return 404; 

}

上記nginxの設定ファイルで指定したSSLの設定ファイルを新規に作成

C:\ > notepad \Certbot\options-ssl-nginx.conf

# This file contains important security parameters. If you modify this file
# manually, Certbot will be unable to automatically provide future security
# updates. Instead, Certbot will print and log an error message with a path to
# the up-to-date file that you will need to refer to when manually updating
# this file.

ssl_session_cache shared:le_nginx_SSL:10m;
ssl_session_timeout 1440m;
ssl_session_tickets off;

ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;

ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384";

3-4. OpenSSLのダウンロード・インストール

SSL接続のセキュリティ強化のため、Nginxにdiffie-hellmanのキー交換による暗号化ルールを適用します。

OpenSSLでサーバとクライアント側で公開キー作成に必要なパラメータを含んだpemファイルを作成します。

OpenSSL Wikiによると幾つかのサイトでバイナリが配布されています。
https://wiki.openssl.org/index.php/Binaries

今回は以下のサイトからインストーラをダウンロード。
https://slproweb.com/products/Win32OpenSSL.html

Win64 OpenSSL v3.0.7 Light

PS C:\> Invoke-WebRequest -Uri https://slproweb.com/download/Win64OpenSSL_Light-3_0_7.exe -Outfile ./Win64OpenSSL_Light-3_0_7.exe

インストール

PS C:\> .\Win64OpenSSL_Light-3_0_7.exe

Windowsコンソールでバイナリファイル openssl.exe 確認

C:\> dir "\program files\OpenSSl-Win64\bin"
 Volume in drive C is Windows
 Volume Serial Number is 58AD-4A66

 Directory of C:\program files\OpenSSl-Win64\bin

12/04/2022  02:53 AM     < DIR>          .
12/04/2022  02:53 AM     < DIR>          ..
11/01/2022  10:14 AM             8,299 CA.pl
11/01/2022  10:14 AM            71,168 capi.dll
11/01/2022  10:14 AM            46,592 dasync.dll
11/01/2022  10:14 AM           157,184 legacy.dll
11/01/2022  10:14 AM         5,140,992 libcrypto-3-x64.dll
11/01/2022  10:14 AM           776,192 libssl-3-x64.dll
11/01/2022  10:14 AM            83,456 loader_attic.dll
11/01/2022  10:14 AM           717,824 openssl.exe
11/01/2022  10:14 AM            49,152 ossltest.dll
11/01/2022  10:14 AM            58,368 padlock.dll
12/04/2022  02:53 AM     < DIR>          PEM
11/01/2022  10:14 AM             7,638 progs.pl
11/01/2022  10:14 AM            38,400 p_test.dll
11/01/2022  10:14 AM             6,946 tsget.pl
              13 File(s)      7,162,211 bytes
               3 Dir(s)  24,056,950,784 bytes free

dhparam.pem の作成

C:\ > "\program files\OpenSSl-Win64\bin\openssl" dhparam -out \Certbot\dhparam.pem 4096

このファイルをnginxの設定ファイル(conf/conf.d/default.conf)のsslセクションで指定(既に記述済でアンコメント:#除外)して下さい。

nginxの起動(nginx.exeのディレクトリで実行)

C:\ > start nginx

4. タスクスケジューラへの登録

4-1. Certbot更新スケジュール

インストールしたCertbotの更新コマンド (certbot renew)は、インストール時にタスクスケジューラへ登録されているようです。

PS > Get-ScheduledTask

TaskPath                                       TaskName                          State
--------                                       --------                          -----
\                                              Certbot Renew Task                Ready
\Microsoft\Windows\.NET Framework\             .NET Framework NGEN v4.0.30319    Ready
\Microsoft\Windows\.NET Framework\             .NET Framework NGEN v4.0.30319 64 Ready

.....
.....

Certbot(認証更新コマンド)の実行スケジュール確認(問題なければ0を表示)

PS > Get-ScheduledTaskInfo -TaskName "Certbot Renew Task"


LastRunTime        : 12/19/2022 12:33:33 PM
LastTaskResult     : 0
NextRunTime        : 12/19/2022 11:16:16 PM
NumberOfMissedRuns : 0
TaskName           : Certbot Renew Task
TaskPath           :
PSComputerName     :

4-2. Nginxの自動起動

タスクスケジューラによる方法と専用アプリNSSMによる方法がありますが、今回はタスクスケジューラにより、Nginx起動バッチファイルがシステム起動時に発動するようにします。

Nginx起動バッチファイルをnginx.exeが格納されているデイレクトリ内で作成
start.bat

@ECHO OFF
REM Start Nginx
tasklist /FI "IMAGENAME eq nginx.exe" 2>NUL | find /I /N "nginx.exe">NUL
IF NOT "%ERRORLEVEL%"=="0" (
   REM Nginx is NOT running, so start it
   c:
   cd \nginx
   start nginx.exe
   ECHO Nginx started.
) else (
   ECHO Nginx is already running.
)

schtask コマンドによるタスクスケジュール登録

PS > schtasks /create /tn nginx-proxy /tr c:\nginx\start.bat /sc onstart /ru System

タスクスケジュール確認(問題なければ0表示)

PS C:\> Get-ScheduledTaskInfo -TaskName "nginx-proxy"


LastRunTime        : 12/7/2022 1:31:31 PM
LastTaskResult     : 0
NextRunTime        :
NumberOfMissedRuns : 0
TaskName           : nginx-proxy
TaskPath           :
PSComputerName     :

schtasks create
https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/schtasks-create

本ブログの内容についての追加・補足などは下記フォーラム記事でフォローします。
Azure導入メモ