Назад | Перейти на главную страницу

Обратный прокси nginx для Docker Swarm - 502 плохой шлюз

Я запускаю рой докеров на "swarm.example.com". На сервере работает контейнер, к которому можно получить доступ по адресу "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 ошибка. Я что-то упускаю ?

Все серверы работают под управлением CentOS 7.6.

Спасибо!

Попытка получить доступ к бэкэнду через обратный прокси приводит к ошибке 502 Bad Gateway:

$ 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 по умолчанию не разрешает исходящие соединения для веб-серверов, потому что обычно они этого не делают.

Вы найдете подобные записи в /var/log/nginx/error.log:

2019/05/18 10:12:11 [критический] 1041 # 0: * 5 connect () to 192.168.15.52:3000 не удалось (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} для 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 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 = (ноль)

Выполните следующую команду, чтобы разрешить 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 и selinux на сайте nginx.