Проксирование запросов в nginx с помощью proxy_pass

Введение

Просто настроить gitlab за nginx в режиме proxy_pass не представляет никакой сложности. Трудности возникают именно тогда, когда вы хотите использовать встроенный Container Registry. Я несколько раз подходил к этой задаче и каждый раз отступал, либо отказываясь от registry, либо от nginx proxy.

Без прокси неудобно, так как чаще всего, если у вас есть какая-та инфраструктура, а не одиночный сервер, смотреть напрямую в интернет у вас будет какой-то шлюз, а не сам сервис. Так удобно разграничивать доступ, контролировать и перенаправлять подключения, следить за сертификатами, балансировать нагрузку и т.д. В общем, я использую его всегда, когда это возможно и оправдано (почти всегда).

С registry не получалось корректно настроить работу за прокси. Я перепробовал все советы, что только нашел в интернете. Перечитал всю документацию, но так ничего не получилось. Команда docker login успешно отрабатывала на сервере, а вот запушить образ в реджистри gitlab никак не получалось. Получал ошибку.

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

Installation

Download the latest stable version of the release tarball of this module from github (http://github.com/yaoweibin/nginx_tcp_proxy_module)

$ wget 'http://nginx.org/download/nginx-1.2.1.tar.gz'
$ tar -xzvf nginx-1.2.1.tar.gz
$ cd nginx-1.2.1/
$ patch -p1 < /path/to/nginx_tcp_proxy_module/tcp.patch

$ ./configure --add-module=/path/to/nginx_tcp_proxy_module

$ make
$ make install

Synopsis

    http {
        server {
            listen 80;
    
            location /status {
                tcp_check_status;
            }
        }
    }
    #You can also include tcp_proxy.conf file individually
    #include /path/to/tcp_proxy.conf;
    tcp {
        upstream cluster {
            # simple round-robin
            server 192.168.0.1:80;
            server 192.168.0.2:80;
    		
            check interval=3000 rise=2 fall=5 timeout=1000;
    		
            #check interval=3000 rise=2 fall=5 timeout=1000 type=ssl_hello;
    
            #check interval=3000 rise=2 fall=5 timeout=1000 type=http;
            #check_http_send "GET / HTTP/1.0\r\n\r\n";
            #check_http_expect_alive http_2xx http_3xx;
        }
    
        server {
            listen 8888;
            ...
            proxy_pass cluster;
        }
    }

Description

This module actually include many modules:

ngx_tcp_module,
ngx_tcp_core_module, 
ngx_tcp_upstream_module, 
ngx_tcp_proxy_module,
ngx_tcp_websocket_module, 
ngx_tcp_ssl_module,
ngx_tcp_upstream_ip_hash_module

All these modules work together to support TCP proxy with Nginx. I also added other features:

ip_hash,
upstream server health check,
status monitor

The motivation of writing these modules is Nginx’s high performance and robustness. At first, I developed this module just for general TCP proxy. And now, this module is frequently used in websocket reverse proxying.

Note, You can’t use the same listening port with HTTP modules.

Установка VestaCP на VPS, использование docker для понижения версии PHP

Доброго времени!
Оставлю тут решение для своего хостинга на VPS за 5 евро, в основном с целью сохранить реализацию решения по своей проблеме.
Несколько лет назад я арендовал выделенный сервер под 20+ сайтов, файлообменник, базу даных на PostgreSQL для 1С, почтовый сервер IMAP. В качестве панели управления использовал ISPmanager с «вечной» лицензией, в качестве ОС был использован изначально CentOS 7 (или даже 6), который я не очень уважаю, больше нравится Debian/Ubuntu. В дальнейшем проекты уходили в соцсети, сайты переставали быть необходимыми, доменные имена освобождались.
В 2019 году я понял, что реально крутится мой сайт и два сайта клиентов, потребность в IMAP с хранением писем на хостинге только у меня, файлообменники так же ушли в облачные сервисы.
Что делать, если один сайт на хостинге не работает с PHP выше 5.4

Деплой приложения на Laravel 7 на Ubuntu & Nginx

Tutorial

Решил я тут своё портфолио сделать на Laravel 7. Чтобы главная страница была лендингом, а всю информацию на ней можно было менять с помощью админки. Не суть. Дело дошло до деплоя. Нашел пару хороших туториалов, как это сделать на полноценном сервере со всеми заморочками. В деплое я не очень силен, я вообще больше фронт, чем фулстек. И, если писать и тестить на PHP я еще могу, то до управления сервером и т.п. я еще не дорос. Но пришлось разбираться.

Сейчас пройдемся по всем шагам, начиная с запуска через SSH и заканчивая рабочим сайтом. Постараемся обойти все подводные камни.

Возможно, вы сможете найти аналогичные инструкции в интернете. Ведь я же в конце концов нашел. Правда не в одном месте, не без помощи StackOverflow и вряд ли на русском. Я помучился. Поэтому решил вам жизнь упростить.

Defining an Upstream Context for Load Balancing Proxied Connections

In the previous examples, we demonstrated how to do a simple http proxy to a single backend server. Nginx allows us to easily scale this configuration out by specifying entire pools of backend servers that we can pass requests to.

We can do this by using the directive to define a pool of servers. This configuration assumes that any one of the listed servers is capable of handling a client’s request. This allows us to scale out our infrastructure with almost no effort. The directive must be set in the http context of your Nginx configuration.

Let’s look at a simple example:

In the above example, we’ve set up an upstream context called . Once defined, this name will be available for use within proxy passes as if it were a regular domain name. As you can see, within our server block we pass any request made to to the pool we defined above. Within that pool, a host is selected by applying a configurable algorithm. By default, this is just a simple round-robin selection process (each request will be routed to a different host in turn).

Changing the Upstream Balancing Algorithm

You can modify the balancing algorithm used by the upstream pool by including directives or flags within the upstream context:

  • (round robin): The default load balancing algorithm that is used if no other balancing directives are present. Each server defined in the upstream context is passed requests sequentially in turn.
  • : Specifies that new connections should always be given to the backend that has the least number of active connections. This can be especially useful in situations where connections to the backend may persist for some time.
  • : This balancing algorithm distributes requests to different servers based on the client’s IP address. The first three octets are used as a key to decide on the server to handle the request. The result is that clients tend to be served by the same server each time, which can assist in session consistency.
  • : This balancing algorithm is mainly used with memcached proxying. The servers are divided based on the value of an arbitrarily provided hash key. This can be text, variables, or a combination. This is the only balancing method that requires the user to provide data, which is the key that should be used for the hash.

When changing the balancing algorithm, the block may look something like this:

In the above example, the server will be selected based on which one has the least connections. The directive could be set in the same way to get a certain amount of session “stickiness”.

As for the method, you must provide the key to hash against. This can be whatever you wish:

The above example will distribute requests based on the value of the client ip address and port. We also added the optional parameter , which implements the ketama consistent hashing algorithm. Basically, this means that if your upstream servers change, there will be minimal impact on your cache.

Setting Server Weight for Balancing

In declarations of the backend servers, by default, each servers is equally “weighted”. This assumes that each server can and should handle the same amount of load (taking into account the effects of the balancing algorithms). However, you can also set an alternative weight to servers during the declaration:

In the above example, will receive three times the traffic as the other two servers. By default, each server is assigned a weight of one.

Передача https через nginx с помощью proxy pass

Если у вас сайт работает по https, то достаточно настроить ssl только на nginx_srv, если вы не беспокоитесь за передачу информации от nginx_srv к blog_srv. Она может осуществляться по незащищенному протоколу. Рассмотрю пример с бесплатным сертификатом let’s encrypt. Это как раз один из кейсов, когда я использую proxy_pass. Очень удобно настроить на одном сервере автоматическое получение всех необходимых сертификатов. Подробно я рассматривал отдельно. Сейчас будем считать, что у вас стоит certbot и все готово для нового сертификата, который потом будет автоматически обновляться.

Для этого нам надо на nginx_srv добавить еще один location — /.well-known/acme-challenge/. Полная секция server нашего тестового сайта на момент получения сертификата будет выглядеть вот так:

Перечитывайте конфиг nginx и получайте сертификат. После этого конфиг меняется на следующий:

Проверяем, что получилось.

Шаг 1 — Пример конфига NGINX

В этом сценарии используется специально созданный файл nginx.conf, основанный на полном примере из NGINX Wiki. Вы можете просмотреть конфигурацию в редакторе, открыв nginx.conf

Исходный конфиг nginx

Конфигурации NGINX обычно имеют три ключевых элемента:

  1. Настройка сервера NGINX, структуры журналов и функциональности Gzip. Это определяется глобально во всех случаях.
  2. Настройка NGINX для приема запросов на хост one.example.com на порту 8080.
  3. Настройка целевого местоположения, как обрабатывать трафик для разных частей URL.

Не вся конфигурация будет применяться к Envoy Proxy, и вам не нужно настраивать некоторые параметры. Envoy Proxy имеет четыре ключевых типа, которые поддерживают базовую инфраструктуру, предлагаемую NGINX. Ядро это:

  • Слушатели: Они определяют, как Envoy Proxy принимает входящие запросы. В настоящее время Envoy Proxy поддерживает только слушателей на основе TCP. Как только соединение установлено, оно передается на набор фильтров для обработки.
  • Фильтры: Они являются частью конвейерной архитектуры, которая может обрабатывать входящие и исходящие данные. Данная функциональность включает фильтры, такие как Gzip, который сжимает данные перед отправкой их клиенту.
  • Маршрутизаторы: Они перенаправляют трафик в требуемый пункт назначения, определенный как кластер.
  • Кластеры: Они определяют конечную точку для трафика и параметры конфигурации.

Мы будем использовать эти четыре компонента для создания конфигурации Envoy Proxy чтобы соответстветствовать определенной конфигурации NGINX. Цель Envoy работа с API и динамическая конфигурация. В этом случае базовая конфигурация будет использовать статические, жестко заданные параметры из NGINX.

Deconstructing a Basic HTTP Proxy Pass

The most straight-forward type of proxy involves handing off a request to a single server that can communicate using http. This type of proxy is known as a generic “proxy pass” and is handled by the aptly named directive.

The directive is mainly found in location contexts. It is also valid in blocks within a location context and in contexts. When a request matches a location with a directive inside, the request is forwarded to the URL given by the directive.

Let’s take a look at an example:

In the above configuration snippet, no URI is given at the end of the server in the definition. For definitions that fit this pattern, the URI requested by the client will be passed to the upstream server as-is.

For example, when a request for is handled by this block, the request URI will be sent to the server as .

Let’s take a look at the alternative scenario:

In the above example, the proxy server is defined with a URI segment on the end (). When a URI is given in the definition, the portion of the request that matches the location definition is replaced by this URI during the pass.

For example, a request for on the Nginx server will be passed to the upstream server as . The is replaced by . This is an important point to keep in mind.

Sometimes, this kind of replacement is impossible. In these cases, the URI at the end of the definition is ignored and either the original URI from the client or the URI as modified by other directives will be passed to the upstream server.

For instance, when the location is matched using regular expressions, Nginx cannot determine which part of the URI matched the expression, so it sends the original client request URI. Another example is when a rewrite directive is used within the same location, causing the client URI to be rewritten, but still handled in the same block. In this case, the rewritten URI will be passed.

Шифрование

Теперь настроим SSL-подключение. Nginx должен быть собран с модулем mail_ssl_module — проверяем командой:

nginx -V

При отсутствии необходимого модуля, пересобираем nginx.

После редактируем наш конфигурационный файл:

vi /etc/nginx/nginx.conf

Генерируем сертификат:

mkdir -p /etc/ssl/nginx

openssl req -new -x509 -days 1461 -nodes -out /etc/ssl/nginx/public.crt -keyout /etc/ssl/nginx/private.key -subj «/C=RU/ST=SPb/L=SPb/O=Global Security/OU=IT Department/CN=test.dmosk.local/CN=test»

* где /etc/ssl/nginx/ — каталог хранения сертификатов, subj — индивидуальные настройки для сертификата.

Перезапускаем nginx:

systemctl restart nginx

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock
detector