Обратный прокси Nginx не перенаправляет? - PullRequest
0 голосов
/ 07 октября 2018

Обновление

Детали в этом вопросе становятся длиннее, но я думаю, что он сужается до следующего:

По какой-то причине имя хоста имеет значение для Nginx, когда он пытается выяснить,прокси запрос.Если для имени хоста установлено значение git.example.com, запрос, по-видимому, не выполняется, но если он установлен на 203.0.113.2, то он проходит.Почему имя хоста имеет значение?

Подана проблема с Nginx здесь И docker compose

Начало исходного вопроса

Когда я вписываю IP-адрес обратного прокси-сервера прямо в панель браузера, он выполняет перенаправление.

При использовании URL-адреса, разрешенного с помощью записи /etc/hosts 203.0.113.2 git.example.com, отображается страница «Добро пожаловать в Ngnix».Есть идеи?Это конфигурация:

server {
    listen 203.0.113.2:80 default_server;
    server_name 203.0.113.2 git.example.com;

    proxy_set_header X-Real-IP  $remote_addr; # pass on real client IP

    location / {
        proxy_pass http://203.0.113.1:3000;
    }
}

Это файл docker-compose.yml, который используется для запуска всего этого:

version: '3'
services:
  gogs-nginx:
    build: ./proxy
    ports:
      - "80:80"
    networks:
      mk1net:
        ipv4_address: 203.0.113.2
  gogs:
    image: gogs/gogs
    ports:
      - "3000:3000"
    volumes: 
      - gogs-data:/data
    networks: 
      mk1net:
        ipv4_address: 203.0.113.3
volumes:
  gogs-data:
    external: true
networks:
  mk1net:
    ipam:
      config:
        - subnet: 203.0.113.0/24

Одна интересная вещь заключается в том, что я могу перейти к примеру:

http://203.0.113.2/issues

Журнал для указанного выше URL:

gogs-nginx_1 |203.0.113.1 - - [07 / Oct / 2018: 11: 28: 06 +0000] "GET / HTTP / 1.1" 200 38825 "-" "Mozilla / 5.0 (X11; Linux x86_64) AppleWebKit / 537.36 (KHTML, как Gecko) Chrome / 69.0.3497.100 Safari / 537.36 "" - "

Если я затем изменю 203.0.113.2 на git.example.com (так что URL в конечном итоге будет git.example.com, я получаю Nginxs" 404 ненайдено », и в журнале написано:

gogs-nginx_1 | 2018/10/07 11:31:34 [error] 8 # 8: * 10 open ()" / usr / share /nginx / html / Issues "сбой (2: нет такого файла или каталога), клиент: 203.0.113.1, сервер: localhost, запрос:" GET / Issues HTTP / 1.1 ", хост:" git.example.com "

Если я использую только http://git.example.com в качестве URL-адреса, я получаю приветственную страницу NGINX и следующий журнал:

gogs-nginx_1 | 203.0.113.1 - - [07 / Oct/ 2018: 11: 34: 39 +0000] "GET / HTTP / 1.1" 304 0 "-" "Mozilla / 5.0 (X11; Linux x86_64) AppleWebKit / 537.36 (KHTML, как Gecko) Chrome / 69.0.3497.100 Safari / 537.36"" - "

Похоже, Nginx понимает, что запрос для прокси, потому что он логs IP-адрес прокси-сервера, но он не перенаправляет на прокси-сервер и возвращает 304 ...

Использование Curl для выполнения запросов

Использование curl с параметром имени хоста, который предназначен для проксинапример:

curl -H 'Host: git.example.com' -si http://203.0.113.2

Результаты на странице приветствия Nginx:

    ole@mki:~/Gogs/.gogs/docker$ curl -H 'Host: git.example.com' -si http://203.0.113.2
    HTTP/1.1 200 OK
    Server: nginx/1.15.1
    Date: Sun, 07 Oct 2018 17:09:11 GMT
    Content-Type: text/html
    Content-Length: 612
    Last-Modified: Tue, 03 Jul 2018 13:27:08 GMT
    Connection: keep-alive
    ETag: "5b3b79ac-264"
    Accept-Ranges: bytes

    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    <style>
        body {
            width: 35em;
            margin: 0 auto;
            font-family: Tahoma, Verdana, Arial, sans-serif;
        }
    </style>
    </head>
    <body>
    <h1>Welcome to nginx!</h1>
    <p>If you see this page, the nginx web server is successfully installed and
    working. Further configuration is required.</p>

    <p>For online documentation and support please refer to
    <a href="http://nginx.org/">nginx.org</a>.<br/>
    Commercial support is available at
    <a href="http://nginx.com/">nginx.com</a>.</p>

    <p><em>Thank you for using nginx.</em></p>
    </body>
    </html>

Но если я изменю имя хоста на IP-адрес, как это:

Использование curlс параметром имени хоста, который нацелен на прокси-сервер следующим образом:

curl -H 'Host: 203.0.113.2' -si http://203.0.113.2

Тогда прокси-сервер работает как следует:

    ole@mki:~/Gogs/.gogs/docker$ curl -H 'Host: 203.0.113.2' -si http://203.0.113.2
    HTTP/1.1 302 Found
    Server: nginx/1.15.1
    Date: Sun, 07 Oct 2018 17:14:46 GMT
    Content-Type: text/html; charset=utf-8
    Content-Length: 34
    Connection: keep-alive
    Location: /user/login
    Set-Cookie: lang=en-US; Path=/; Max-Age=2147483647
    Set-Cookie: i_like_gogits=845bb09d69587b81; Path=/; HttpOnly
    Set-Cookie: _csrf=neGgBfG4LdOcdrdeA0snHjVGz4s6MTUzODkzMjQ4NjE5MzEzNzI3OQ%3D%3D; Path=/; Expires=Mon, 08 Oct 2018 17:14:46 GMT; HttpOnly
    Set-Cookie: redirect_to=%252F; Path=/

    <a href="/user/login">Found</a>.

1 Ответ

0 голосов
/ 07 октября 2018

Извините, я не смог понять, что происходит на вашей стороне, потому что информация иногда сбивает с толку, а иногда и неполная.Но Stackoverflow предоставляет отличное объяснение того, что считается хорошим вопросом: Как создать минимальный, полный и проверяемый пример , и поэтому я только что попытался реализовать минимальный пример системы, которую вы, вероятно, собираетесь использоватьbuild.

Ниже я предоставляю все файлы и покажу вам также тестовый запуск.

Файл № 1: docker-compose.yml

gogs:
  image: gogs/gogs

web:
  build: .
  ports:
  - 8000:80
  links:
  - gogs

Я устарелDocker на моем компьютере, и я не хочу беспокоиться о работе с сетями Docker, поэтому я только что связал оба контейнера, используя Docker links .Это самая важная часть, и ссылка гарантирует, что (1) наш контейнер web зависит от gogs;(2) мы можем ссылаться на gogs IP изнутри web как на gogs.Docker преобразует имя в IP-адрес, назначенный контейнеру.

Поскольку я хочу минимальный пример, я пропустил все остальное как не относящееся к делу.Например, volume.

Файл # 2: Dockerfile

Более новые версии Compose поддерживают config опции, указанные прямо в docker-compose.yml, но вместо этого мне нужен пользовательский Dockerfile,Это тривиально:

FROM nginx:stable-alpine
COPY gogs.conf /etc/nginx/conf.d

Файл № 3: gogs.conf

И, наконец, нам нужна конфигурация Nginx для прокси:

server {
  listen 80 default_server;

  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

  location / {
    proxy_pass http://gogs:3000;
  }
}

Вы можете заметить, что мы имеем в видудругой контейнер просто по имени gogs, и нам нужно знать, какой номер порта он предоставляет.Мы знаем: 3000.

Работает

$ docker-compose build
$ docker-compose up

Он работает и работает:

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
1f74293df630        g_web               "nginx -g 'daemon off"   2 minutes ago       Up 26 seconds       0.0.0.0:8000->80/tcp   g_web_1
dfa2dbaa6074        gogs/gogs           "/app/gogs/docker/sta"   2 minutes ago       Up 26 seconds       22/tcp, 3000/tcp       g_gogs_1

web Контейнер открыт для всего мира с номером порта 8000.

Тесты

по IP

Давайте запросить его по IP:

$ curl -si http://192.168.99.100:8000/
HTTP/1.1 302 Found
Server: nginx/1.14.0
Date: Sun, 07 Oct 2018 15:13:55 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 31
Connection: keep-alive
Location: /install
Set-Cookie: lang=en-US; Path=/; Max-Age=2147483647
Set-Cookie: i_like_gogits=50411f542e2ae8f8; Path=/; HttpOnly
Set-Cookie: _csrf=ZJxRPqnqayIbpAYgZ22zrPIOaSo6MTUzODkyNTIzNTQ2NTg5MDE1NA%3D%3D; Path=/; Expires=Mon, 08 Oct 2018 15:13:55 GMT; HttpOnly

<a href="/install">Found</a>.

Соответствующий файл журнала:

web_1   | 192.168.99.1 - - [07/Oct/2018:15:14:24 +0000] "GET / HTTP/1.1" 302 31 "-" "curl/7.61.1" "-"
gogs_1  | [Macaron] 2018-10-07 15:14:24: Started GET / for 192.168.99.1
gogs_1  | [Macaron] 2018-10-07 15:14:24: Completed GET / 302 Found in 199.519µs
gogs_1  | 2018/10/07 15:14:24 [TRACE] Session ID: 38d06d393a9e9d21
gogs_1  | 2018/10/07 15:14:24 [TRACE] CSRF Token: Xth986dFWhhj8w8vBdIqRZu4SbI6MTUzODkyNTI2NDYxMDYzNzAyNA==

Могупосмотрите из журнала, что (1) оба контейнера работают, и они были использованы для обработки запроса;(2) 192.168.99.1 - это IP-адрес моего хоста, что означает, что "gogs" успешно получает реальный IP-запрос через X-Forwarded-For.

по доменному имени

ОК, давайте запросим, ​​используя доменимя:

$ curl -H 'Host: g.example.com' -si http://192.168.99.100:8000/

Поверь мне, этого достаточно.Host - заголовок протокола HTTP для передачи имени домена.И любой браузер будет делать то же самое под капотом.

и соответствующий файл журнала будет -

gogs_1  | [Macaron] 2018-10-07 15:32:49: Started GET / for 192.168.99.1
gogs_1  | [Macaron] 2018-10-07 15:32:49: Completed GET / 302 Found in 618.701µs
gogs_1  | 2018/10/07 15:32:49 [TRACE] Session ID: 81f64d97e9c3dd1e
gogs_1  | 2018/10/07 15:32:49 [TRACE] CSRF Token: X5QyHM4LMIfn8OSJD1gwSSEyXV46MTUzODkyNjM2OTgyODQyMjExMA==
web_1   | 192.168.99.1 - - [07/Oct/2018:15:32:49 +0000] "GET / HTTP/1.1" 302 31 "-" "curl/7.61.1" "-"

Без изменений, все работает как положено.

...