GNU/Linux >> Linux の 問題 >  >> Debian

同じサーバー(Debian、Ubuntu、CentOS)でApache、Nginx、HAProxyを実行する

サーバー管理者の場合は、ApacheやNginxなどのWebサーバーを選択している可能性があります。 アパッチ 1990年代からよく知られているWebサーバーです。 Nginx 2004年に最初に開発され、メモリフットプリントが軽量で、静的HTMLファイルの処理速度が速いため、すぐに注目を集めました。

ApacheとNginxはどちらも仮想ホスティングをサポートしています。つまり、同じサーバー上で複数のWebサイトまたはWebアプリケーションをホストできます。ただし、既存のWebサーバーを実行しているが、特定のWebアプリケーションで別のWebサーバーを使用する必要がある場合があります。パブリックIPアドレスのポート80または443は、1つのプロセスでのみ使用できます。 Apacheがポートを使用している場合、Nginxはそのポートを使用(またはバインド)できません。では、何ができるでしょうか?

NginxをApacheへのリバースプロキシとして構成できるため、NginxはHTTPリクエストをApacheにリダイレクトできます。私の経験では、これがトラブルシューティングできない奇妙な問題を引き起こしたことがあるため、これが常に最善の方法であるとは限らないことがわかりました。代わりに、NginxとApacheの両方のリバースプロキシとしてHAProxyを使用することを好みます。 。 HAProxyは、TCPおよびHTTPベースのアプリケーション向けの無料のオープンソース高可用性ロードバランサーおよびプロキシサーバーです。

同じサーバーでApache、Nginx、HAProxyを実行する

仕組みは次のとおりです。

  • Nginxは127.0.0.1:80と127.0.0.1:443でリッスンします
  • Apacheは127.0.0.2:80と127.0.0.2:443でリッスンします
  • HAProxyは、パブリックIPアドレスのポート80および443でリッスンします。ポート80のHTTPリクエストをポート443にリダイレクトします。リクエストがポート443に到着すると、HTTPSリクエストのSNI(サーバー名表示)ヘッダーを分析して、NginxとApacheのどちらのバックエンドを選択します。

実際、Cloudflare(CDNプロバイダー)もSNIヘッダーを使用して、HTTPSリクエストをオリジンサーバーにルーティングする方法を決定しています。

ステップ1:NginxとApacheを停止する

Debian、Ubuntu、CentOSでNginxを停止するには、

を実行します。
sudo systemctl stop nginx

Debian / UbuntuでApacheを停止するには、

を実行します。
sudo systemctl stop apache2

CentOSでApacheを停止するには、

を実行します。
sudo systemctl stop httpd

ステップ2:Nginxのリッスンポートを変更する

Nginxを127.0.0.1:80でリッスンさせる必要があります。 /etc/nginx/conf.d/にあるNginx構成ファイルを開きます または/etc / nginx / sites-enabled / 次の行を見つけます。

listen 80;

に変更

listen 127.0.0.1:80;

Nginxサーバーブロックでhttpsが有効になっている場合は、

も検索します。
listen 443 ssl;

そしてそれを

に変更します
listen 127.0.0.1:443 ssl;

Nginxメイン構成ファイル/etc/nginx/nginx.conf ポート80または443でリッスンしているデフォルトの仮想ホストが含まれている可能性があるため、このファイルも編集する必要がある場合があります。

変更を有効にするには、Nginxを再起動します。

sudo systemctl restart nginx

ステップ3:Apacheのリッスンポートを変更する

Apacheを127.0.0.2:80でリッスンさせる必要があります。

Debian / Ubuntu

DebianとUbuntuで、 /etc/apache2/ports.confを編集します ファイル。

sudo nano /etc/apache2/ports.conf

変更

Listen 80
Listen 443

宛先

Listen 127.0.0.2:80
Listen 127.0.0.2:443

ファイルを保存して閉じます。 / etc / apache2 / sites-enabled /にもアクセスします ディレクトリ、仮想ホストファイルを編集します。変更

<VirtualHost *:80>

宛先

<VirtualHost 127.0.0.2:80>

SSL仮想ホストがある場合は、それも変更します

<VirtualHost *:443>

宛先

<VirtualHost 127.0.0.2:443>

Apacheを再起動します。

sudo systemctl restart apache2

CentOS

CentOSで、 /etc/httpd/conf/httpd.confを編集します ファイル。

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

検索

Listen 80

に変更

Listen 127.0.0.2:80

ファイルを保存して閉じます。次に、 /etc/httpd/conf.d/に移動します ディレクトリ、仮想ホストファイルを編集します。変更

<VirtualHost *:80>

宛先

<VirtualHost 127.0.0.2:80>

SSL仮想ホストがある場合は、それも変更します

<VirtualHost *:443>

宛先

<VirtualHost 127.0.0.2:443>

/etc/httpd/conf.d/ssl.conf内 ファイル、あります

Listen 443 https

次のように変更します:

Listen 127.0.0.2:443 https

ファイルを保存して閉じます。変更を有効にするには、Apacheを再起動します。

sudo systemctl restart httpd

ステップ4:HAProxyを構成する

ディストリビューションにHAProxyをインストールします。

Debian / Ubuntu

sudo apt install haproxy

CentOS

sudo dnf install haproxy

HAProxy構成ファイルを編集します。

sudo nano /etc/haproxy/haproxy.cfg

ファイルの最後に次のコードスニペットを追加します。これにより、HAPorxyはパブリックIPアドレスのポート80でリッスンし、ポート80でHTTPリクエストをポート443にリダイレクトします。12.34.56.78をサーバーのパブリックIPアドレスに置き換えます。

>
frontend http
    bind 12.34.56.78:80
    mode http
    redirect scheme https code 301

次に、HTTPSフロントエンドも追加する必要があります。

frontend https
    bind 12.34.56.78:443
    mode tcp
    tcp-request inspect-delay 5s
    tcp-request content accept if { req_ssl_hello_type 1 }

次に、NginxとApacheのバックエンドを定義します。 チェック パラメータは、TCPパケットを送信することによってバックエンドでヘルスチェックを実行するようにHAProxyに指示します。

backend nginx
    mode tcp
    option ssl-hello-chk
    server nginx 127.0.0.1:443 check

backend apache
    mode tcp
    option ssl-hello-chk
    server apache 127.0.0.2:443 check

デフォルトのバックエンドは次のように定義できます:

default_backend nginx

HTTPSリクエストでSNIヘッダーを使用して、正しいバックエンドにリダイレクトします。たとえば、Nginxが domain1.comを提供している場合 Apacheはdomain2.comを提供しています 、次に次の2行を追加します。サブドメインが異なる限り、サブドメインを使用することもできます。

use_backend nginx if { req_ssl_sni -i domain1.com }
use_backend apache if { req_ssl_sni -i domain2.com }

default_backendに注意してください およびuse_backend ディレクティブはバックエンド定義の上に配置する必要があります。

frontend http
    bind 12.34.56.78:80
    mode http
    redirect scheme https code 301

frontend https
    bind 12.34.56.78:443
    mode tcp
    tcp-request inspect-delay 5s
    tcp-request content accept if { req_ssl_hello_type 1 }

    default_backend nginx

    use_backend nginx if { req_ssl_sni -i domain1.com }
    use_backend apache if { req_ssl_sni -i domain2.com }

backend nginx
    mode tcp
    option ssl-hello-chk
    server nginx 127.0.0.1:443 check

backend apache
    mode tcp
    option ssl-hello-chk
    server apache 127.0.0.2:443 check

上記の構成では、TLSのSNI(Server Name Indication)機能を利用してHTTPSトラフィックを区別しました。

  • domain1.comがTLSクライアントHelloにある場合、HAProxyはトラフィックを nginxにリダイレクトします バックエンド。
  • domain2.comがTLSクライアントHelloにある場合、HAProxyはトラフィックを apacheにリダイレクトします。 バックエンド。

クライアントがTLSClientHelloでサーバー名を指定しない場合、HAproxyはデフォルトのバックエンド(nginx)を使用します。

ファイルを保存して閉じます。次に、HAproxyを再起動します。

sudo systemctl restart haproxy

これで、Apache、Nginx、およびHAProxyを同じサーバーで実行できるようになりました。

クライアントのIPアドレスをバックエンドに転送する方法

デフォルトでは、ApacheとNginxはHAProxyのIPアドレスのみを表示できます。クライアントの実際のIPアドレスを取得するには、必ず send-proxy-v2を追加してください。 以下のようなHAProxyのバックエンド定義のオプション。

backend nginx
    mode tcp
    option ssl-hello-chk
    server nginx 127.0.0.1:443 send-proxy-v2 check

backend apache
    mode tcp
    option ssl-hello-chk
    server apache 127.0.0.2:443 send-proxy-v2 check

また、NginxとApacheにいくつかの構成を追加して機能させる必要があります。そうしないと、Webサイトにアクセスできなくなります。

Nginx

proxy_protocolを追加します Nginxでlisten 以下のようなディレクティブ。

listen 127.0.0.2:443 ssl http2 proxy_protocol;

次に、Nginx http {}に次の2つのディレクティブを追加します /etc/nginx/nginx.confのブロック ファイル。

set_real_ip_from 127.0.0.1;
real_ip_header proxy_protocol;

ファイルを保存して閉じます。次に、Nginxをリロードします。

sudo systemctl reload nginx

:ウェブサイトがCloudflare CDNの背後で実行されている場合は、 real_ip_header proxy_protocol;を変更する必要があります real_ip_header CF-Connecting-IP;へ クライアントの実際のIPアドレスを表示するため。このreal_ip_headerを追加することもできます /etc/nginx/nginx.confのグローバル構成をオーバーライドする個々のサーバーブロックファイルへのディレクティブ ファイル。

最後に、HAProxyを再起動します。

sudo systemctl restart haproxy

Apache

Debian / UbuntuでApacheを使用する場合は、 remoteipを有効にする必要があります モジュール。 (このモジュールはCentOSでデフォルトで有効になっています。)

sudo a2enmod remoteip

次に、Apache仮想ホスト構成ファイルに次の3行を追加します。

RemoteIPProxyProtocol On
RemoteIPHeader X-Forwarded-For
RemoteIPTrustedProxy 127.0.0.1

このように。

<VirtualHost 127.0.0.2:443>
    ServerName www.example.com
    RemoteIPProxyProtocol On
    RemoteIPHeader X-Forwarded-For
    RemoteIPTrustedProxy 127.0.0.1

ファイルを保存して閉じます。次に、 Combinedも変更する必要があります ログ形式。 Apacheのメイン構成ファイルを編集します。

sudo nano /etc/apache2/apache2.conf

または

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

次の行を見つけます。

LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined

次のように置き換えます:

LogFormat "%a %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined

ファイルを保存して閉じます。次に、変更を有効にするためにApacheを再起動します。

sudo systemctl restart apache2

または

sudo systemctl restart httpd

RemoteIPProxyProtocol On ディレクティブは、Apache2.4.31以降でのみ使用できます。 Apacheのバージョンを確認するには、

を実行します。
sudo apache2 -v

または

sudo httpd -v

Ubuntu18.04にはApache2.4.29が付属しています。 Apacheのバージョンがこの要件を満たしていない場合は、 send-proxy-v2を削除する必要があります HAProxyバックエンド定義で。 CentOS8にはApache2.4.37が付属しています。

最後に、HAProxyを再起動します。

sudo systemctl restart haproxy

新しい仮想ホストを追加する方法

ApacheおよびNginxWebサーバーがある場合、必要なバックエンドは2つだけです。1つはApache用、もう1つはNginx用です。

別のドメイン(またはサブドメイン)を追加する必要がある場合、HAProxyに新しいバックエンドを追加する必要はありません。代わりに、ApacheまたはNginxで新しいドメイン(またはサブドメイン)の新しい仮想ホストを作成してから、 use_backendを使用する必要があります。 トラフィックを正しいバックエンドにリダイレクトするためのHAProxyのディレクティブ。

frontend http
    bind 12.34.56.78:80
    mode http
    redirect scheme https code 301

frontend https
    bind 12.34.56.78:443
    mode tcp
    tcp-request inspect-delay 5s
    tcp-request content accept if { req_ssl_hello_type 1 }

    default_backend nginx

    use_backend nginx if { req_ssl_sni -i domain1.com }
    use_backend nginx if { req_ssl_sni -i sub.domain1.com }
    use_backend apache if { req_ssl_sni -i domain2.com }
    use_backend apache if { req_ssl_sni -i sub.domain2.com }

backend nginx
    mode tcp
    option ssl-hello-chk
    server nginx 127.0.0.1:443 check

backend apache
    mode tcp
    option ssl-hello-chk
    server apache 127.0.0.2:443 check

apacheの使用をお勧めします およびnginx 上記のコードのようなバックエンド名として、どのWebサーバーがどのアプリケーションをホストしているかがわかります。

新しいLet'sEncryptSSL証明書の取得

http-01チャレンジ

まず、Certbotapacheとnginxオーセンティケーターを使用してTLS証明書を取得する方法を理解する必要があります。

  • UbuntuでLet’sEncryptを使用してApacheでHTTPSを適切に有効にする
  • UbuntuでLet’sEncryptを使用してNginxでHTTPSを適切に有効にする

Certbotapacheとnginxオーセンティケーターはhttp-01を使用します チャレンジ。TCPポート80で動作します。HAProxyはTCPポート80を使用しているため、Certbot http-01 チャレンジは失敗する可能性があります。ただし、次の方法で動作させることができます。

  1. 自己署名証明書または別のドメインの証明書を使用して、ApacheまたはNginxでSSLホストを有効にします。
  2. 次に、通常どおりCertbotapacheとnginxオーセンティケーターを使用します。

このメソッドが機能するのは、Certbot http-01 チャレンジはTCPポート80からTCPポート443にリダイレクトでき、Certbotはポート443で無効な証明書を受け入れます。

dns-01チャレンジ

certbot dns-01を使用することもできます チャレンジ。ドメインの一時的なTXTレコードを作成して、実際にこのドメインを所有していることを証明することで機能します。これにより、TCPポート80とTCPポート443をバイパスできます。この方法の欠点は、すべてのドメインレジストラがサポートされているわけではないことです。

まず、CertbotDNSプラグインをインストールする必要があります。これらは、DebianおよびUbuntuソフトウェアリポジトリで利用可能ないくつかのDNSプラグインであり、

で見つけることができます。
apt search python3-certbot-dns

出力:

python3-certbot-dns-cloudflare/bionic,bionic 0.23.0-1 all
Cloudflare DNS plugin for Certbot

python3-certbot-dns-digitalocean/bionic,bionic 0.23.0-1 all
DigitalOcean DNS plugin for Certbot

python3-certbot-dns-dnsimple/bionic,bionic 0.23.0-1 all
DNSimple DNS plugin for Certbot

python3-certbot-dns-google/bionic,bionic 0.23.0-1 all
Google DNS plugin for Certbot

python3-certbot-dns-rfc2136/bionic,bionic 0.23.0-1 all
RFC 2136 DNS plugin for Certbot

python3-certbot-dns-route53/bionic,bionic 0.23.0-1 all
Route53 DNS plugin for Certbot

CentOS 8では、EPELリポジトリからCertbotDNSプラグインを見つけることができます。デフォルトのCentOSリポジトリからCertbotをインストールする必要があることに注意してください。

sudo dnf install certbot

EPELリポジトリからDNSプラグインを見つけます。

sudo dnf install epel-release
dnf search certbot-dns

出力:

python3-certbot-dns-ovh.noarch : OVH DNS Authenticator plugin for Certbot
python3-certbot-dns-nsone.noarch : NS1 DNS Authenticator plugin for Certbot
python3-certbot-dns-gehirn.noarch : Gehirn Infrastructure Service DNS Authenticator plugin for Certbot
python3-certbot-dns-google.noarch : Google Cloud DNS Authenticator plugin for Certbot
python3-certbot-dns-linode.noarch : Linode DNS Authenticator plugin for Certbot
python3-certbot-dns-luadns.noarch : LuaDNS Authenticator plugin for Certbot
python3-certbot-dns-rfc2136.noarch : RFC 2136 DNS Authenticator plugin for Certbot
python3-certbot-dns-route53.noarch : Route53 DNS Authenticator plugin for Certbot
python3-certbot-dns-cloudxns.noarch : CloudXNS DNS Authenticator plugin for Certbot
python3-certbot-dns-dnsimple.noarch : DNSimple DNS Authenticator plugin for Certbot
python3-certbot-dns-cloudflare.noarch : Cloudflare DNS Authenticator plugin for Certbot
python3-certbot-dns-cloudflare.noarch : Cloudflare DNS Authenticator plugin for Certbot
python3-certbot-dns-dnsmadeeasy.noarch : DNS Made Easy DNS Authenticator plugin for Certbot
python3-certbot-dns-sakuracloud.noarch : Sakura Cloud DNS Authenticator plugin for Certbot

使用しているDNSホスティングサービスに応じて、これらのプラグインの1つをインストールします。私はCloudflareを使用しているので、例としてCloudflareを使用します。次のコマンドを実行して、 python3-certbot-dns-cloudflareをインストールします Debian/Ubuntuのパッケージ。

sudo apt install python3-certbot-dns-cloudflare

次に、Cloudflareの構成ファイルを作成します。

sudo nano /etc/letsencrypt/cloudflare.ini

このファイルにCloudflareアカウントのメールアドレスとAPIキーを追加する必要があります。

# Cloudflare API credentials used by Certbot
dns_cloudflare_email = [email protected]
dns_cloudflare_api_key = 0123456789abcdef0123456789abcdef01234567

Cloudflare APIキーは、 https://dash.cloudflare.com/profileにあります。 。 Certbot Cloudflareプラグインは現在Cloudflareの「APIトークン」をサポートしていないため、認証には「グローバルAPIキー」を使用してください。

ファイルを保存して閉じます。 APIキーはCloudflareの2要素認証をバイパスするため、rootユーザーのみにこのファイルの読み取りを許可する必要があります。

sudo chmod 600 /etc/letsencrypt/cloudflare.ini

次に、certbotを実行します。

sudo certbot --agree-tos -a dns-cloudflare -i nginx --redirect --hsts --staple-ocsp --email [email protected] -d www.your-domain.com,your-domain.com

上記のコマンドでは、 dns-cloudflareを使用するように指定しました 新しいTLS証明書を取得し、 nginxを使用するオーセンティケーターとして HTTPSサーバーブロックを作成するプラグイン。 Apacheを使用している場合は、 nginxを置き換えます apacheを使用 。

このコマンドでは、 .iniのパスを入力するように求められます ファイルなので、 /etc/letsencrypt/cloudflare.iniと入力します Enterキーを押します。

SSL証明書を取得し、Webサーバー構成ファイルにインストールした後。 127.0.0.1:443または127.0.0.2:443でリッスンするようにする必要があります。たとえば、Nginxを使用している場合は、

listen 443 ssl

そしてそれを

に変更します
listen 127.0.0.1:443 ssl http2

また、ポート80を

に変更します
listen 127.0.0.1:80;

ファイルを保存して閉じます。次に、Webサーバーを再起動します。

一般的なエラー

1間違ったドメイン名

サーバー上に複数のNginx仮想ホストがあり、1つのドメイン名を入力すると、Webブラウザーが同じサーバーでホストされている別のドメイン名に移動する場合、Nginx仮想ホストファイル名の1つが終了していない可能性があります .confを使用 ファイル名拡張子が大きいため、Nginxはこの仮想ホストをロードしませんでした。ドメイン名にAAAAレコードを設定したが、IPv6でドメイン名を提供するようにNginxを構成しなかった可能性もあります。

上記はApacheWebサーバーにも当てはまります。

2ネットワークプロトコル違反

send-proxy-v2を設定した場合 HAProxyのヘッダーですが、 proxy_protocolを有効にしませんでした NginxまたはApacheでは、Webサイトに次のエラーが表示されます。

The site  has experienced a network protocol violation that cannot be repaired.

構成ファイルに変更を加えた後は、Nginx/Apacheを再起動することを忘れないでください。

3 PR_CONNECT_RESET_ERROR

proxy_protocolを有効にした場合 NginxまたはApacheで、ただし send-proxy-v2を設定しませんでした HAProxyのヘッダーの場合、Webサイトにこのエラーが表示されます。

secure connection failed. PR_CONNECT_RESET_ERROR

また、NginxまたはApacheのエラーログに次のエラーメッセージが表示されます。

broken header while reading PROXY protocol

構成ファイルに変更を加えた後は、Nginx/Apacheを再起動することを忘れないでください。

プロキシプロトコルを有効にした場合も注意してください 1つのApache/Nginx仮想ホストファイルで、他のすべての仮想ホストに対しても暗黙的に有効になります。そして、 proxy_protocolを無効にする方法が見つかりませんでした 個々の仮想ホスト用。同じサーバーでApacheとNginxを実行しているため、回避策は、Nginxでのみプロキシプロトコルを有効にし、Apacheでは有効にしないことです。仮想ホストがクライアントの実際のIPアドレスを取得する必要がない場合は、Apacheを使用するように仮想ホストを構成します。

更新 :127.0.0.4のような別のループバックアドレスに新しいApache/Nginx仮想ホストをセットアップできることに気づきました。このように、新しい仮想ホストはプロキシプロトコルを有効にしません。

4 PR_END_OF_FILE_ERROR

Apache / Nginxでプロキシプロトコルを有効にしたが、仮想ホストに直接アクセスしようとすると(HAProxyをバイパスして)、次のエラーが表示されます。

PR_END_OF_FILE_ERROR

5 SSL_ERROR_SYSCALL

curlコマンドを使用する場合:

curl -I https://example.com

そして、次のエラーが発生します

curl: (35) OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to example.com:443

このドメインのバックエンド定義を設定しなかったことが原因である可能性があります。


Debian
  1. CentOS 7、Ubuntu 18.04、Debian9にApacheHadoopをインストールする方法

  2. CentOS 7 / Ubuntu 18.04 / 16.04 /Debian9でDHCPサーバーを構成する方法

  3. Ubuntu 18.04 /Ubuntu16.04およびDebian9にPuppet6.xをインストールする方法

  1. Debian –64ビットのDebian/ ubuntuで32ビットのプログラムを実行する方法は?

  2. UbuntuでSQLServerを実行しますか?

  3. UbuntuとCentOSでNginxサーバーブロックを設定する方法

  1. Debian 9 /Ubuntu16.04サーバーでHAProxyを設定する方法

  2. Ubuntu 18.04 /Debian9にNginxをインストールして構成する方法

  3. CentOS8にApacheをインストールする