web-dev-qa-db-ja.com

DockerSwarmのnginxリバースプロキシ-502不良ゲートウェイ

「swarm.example.com」でdockerswarmを実行しています。サーバーには、「swarm.example.com:3000」からアクセスできるコンテナが実行されています。

サーバー「example.com」で、次のルールでnginxリバースプロキシを実行しています

server {
    listen 80;
    server_name app.example.com;

    location / {
        proxy_pass http://swarm.example.com:3000;
    }
}

App.example.comにアクセスしようとすると、502 Bad Gatwayエラーが発生します。私は何かが足りないのですか?

すべてのサーバーがCentOS7.6を実行しています

ありがとう!

1
Branislav B.

リバースプロキシを介してバックエンドにアクセスしようとすると、502 BadGatewayエラーが発生します。

$ wget -S --spider http://nginxtest.example.com/
Spider mode enabled. Check if remote file exists.
--2019-05-18 10:12:11--  http://nginxtest.example.com/
Resolving nginxtest.example.com (nginxtest.example.com)... 192.168.15.20
Connecting to nginxtest.example.com (nginxtest.example.com)|192.168.15.20|:80... connected.
HTTP request sent, awaiting response...
  HTTP/1.1 502 Bad Gateway
  Server: nginx/1.12.2
  Date: Sat, 18 May 2019 08:12:11 GMT
  Content-Type: text/html
  Content-Length: 3693
  Connection: keep-alive
  ETag: "5a9e5ebd-e6d"
Remote file does not exist -- broken link!!!

これはおそらく、selinuxがデフォルトでWebサーバーへの発信接続を許可していないためです。これは、通常、Webサーバーが許可しないためです。

/var/log/nginx/error.logに次のようなエントリがあります。

2019/05/18 10:12:11 [crit] 1041#0:* 5アップストリームへの接続中に192.168.15.52:3000へのconnect()が失敗しました(13:アクセスが拒否されました)、クライアント:146.140.37.47、サーバー:_、リクエスト: "HEAD/HTTP/1.1"、アップストリーム: " http://192.168.15.52:3000/ "、ホスト: "nginxtest.example.com"

さらに、次のようなエントリが/var/log/audit/audit.logにあります。

type = AVC msg = audit(1558167131.910:463):avc:denied {name_connect} for pid = 1041 comm = "nginx" dest = 3000 scontext = system_u:system_r:httpd_t:s0 tcontext = system_u:object_r:ntop_port_t:s0 tclass = tcp_socket permissive = 0 type = SYSCALL msg = audit(1558167131.910:463):Arch = c000003e syscall = 42 success = no exit = -13 a0 = 8 a1 = 562671c4eef0 a2 = 10 a3 = 7ffcfbc72530 items = 0 ppid = 1006 pid = 1041 auid = 4294967295 uid = 996 gid = 994 euid = 996 suid = 996 fsuid = 996 egid = 994 sgid = 994 fsgid = 994 tty =(none)ses = 4294967295 comm = "nginx" exe = "/ usr/sbin/nginx" subj = system_u:system_r:httpd_t:s0 key =(null)

次のコマンドを実行して、nginxが他のホストに接続できるようにします。

setsebool -P httpd_can_network_connect true

(パラメータ-p設定を永続化します。そうしないと、次回の再起動後にリセットされます。)

そして今、プロキシは機能します:

$ wget -S --spider http://nginxtest.example.com/
Spider mode enabled. Check if remote file exists.
--2019-05-18 10:15:14--  http://nginxtest.example.com/
Resolving nginxtest.example.com (nginxtest.example.com)... 192.168.15.20
Connecting to nginxtest.example.com (nginxtest.example.com)|192.168.15.20|:80... connected.
HTTP request sent, awaiting response...
  HTTP/1.1 200 OK
  Server: nginx/1.12.2
  Date: Sat, 18 May 2019 08:15:15 GMT
  Content-Type: text/html
  Content-Length: 40
  Connection: keep-alive
  Last-Modified: Sat, 18 May 2019 08:08:16 GMT
  ETag: "5cdfbd70-28"
  Accept-Ranges: bytes
Length: 40 [text/html]
Remote file exists and could contain further links,
but recursion is disabled -- not retrieving.

詳細を知りたい場合は、非常に詳細な nginx Webサイトのnginxとselinuxに関する記事 があります。

1