Перенаправление запроса в архив: настройка Nginx как обратного прокси для Apache

Бесплатная консультация юриста

+7 (800) 301-07-30

Реклама jurik.ru

Под «перенаправлением запроса в архив» в инженерной практике понимают несколько различных задач в зависимости от контекста:

  • Архитектурный уровень (Reverse Proxy): Перенаправление входящего трафика от фронтенд-сервера (Nginx) к бэкенду (Apache, Node․js, Python), который выступает в роли «архива» или основного хранилища логики/данных․
  • Уровень URL и SEO: Настройка редиректов (301/302) со старых адресов на новый раздел /archive/ или поддомен archive․example․com․
  • Уровень данных (Cold Storage): Программная маршрутизация запросов на чтение старых данных в отдельное хранилище (S3 Glacier, ClickHouse, отдельный PostgreSQL-кластер)․
  • Уровень наблюдаемости: Сохранение копий входящих запросов (логирование) в архивные системы (ELK Stack, Loki, S3) для аудита и отладки․

В этой статье мы подробно разберем самый частый технический сценарий — настройку Nginx как обратного прокси-сервера для Apache (на основе актуальных практик для Ubuntu 20․04/22․04/24․04), а также рассмотрим остальные аспекты перенаправления в архив․


Часть 1․ Nginx как Reverse Proxy для Apache: Классическая схема «Архив/Бэкенд»

В данной схеме Nginx («лицо» системы) принимает все запросы на порт 80/443, отдает статику сам, а динамические запросы (PHP, тяжелая логика) перенаправляет («проксирует») на Apache, работающий на внутреннем порту (обычно 8080)․ Apache здесь выступает в роли «архива» бизнес-логики и исполнителя скриптов․

Подготовка окружения (Ubuntu 20․04+)

Обновите индексы пакетов и установите необходимый софт:

sudo apt update
sudo apt install apache2 php-fpm libapache2-mod-fastcgi nginx

Важно: В современных Ubuntu (22․04, 24․04) пакет libapache2-mod-fastcgi может отсутствовать в стандартных репозиториях․ Рекомендуется использовать PHP-FPM напрямую с Nginx (без Apache) или устанавливать libapache2-mod-fcgid как альтернативу․ Ниже приведена классическая схема через FastCGI для Apache, если она строго требуется․

Настройка Apache: Скрытие за прокси (Порт 8080)

Apache не должен знать, что за ним стоит Nginx․ Он должен слушать локальный порт 8080 на всех интерфейсах (или только на 127․0․0․1 для безопасности)․

  1. Измените порт прослушивания:
sudo mv /etc/apache2/ports․conf /etc/apache2/ports․conf․default
echo "Listen 8080" | sudo tee /etc/apache2/ports․conf
  1. Настройте виртуальный хост Apache (пример для apache1․example․com):
sudo cp /etc/apache2/sites-available/000-default․conf /etc/apache2/sites-available/apache1․conf
sudo nano /etc/apache2/sites-available/apache1․conf

Содержимое apache1․conf:

<VirtualHost *:8080>
 ServerAdmin webmaster@localhost
 ServerName apache1․example․com
 DocumentRoot /var/www/apache1

 <Directory /var/www/apache1>
 Options Indexes FollowSymLinks
 AllowOverride All
 Require all granted
 </Directory>

 # Настройка PHP через FastCGI (если используется mod_fastcgi)
 <FilesMatch ․php$>
 SetHandler "proxy:unix:/run/php/php8․1-fpm․sock|fcgi://localhost/"
 </FilesMatch>

 ErrorLog ${APACHE_LOG_DIR}/apache1_error․log
 CustomLog ${APACHE_LOG_DIR}/apache1_access․log combined
</VirtualHost>
  1. Включите сайт и модули, перезапустите Apache:
sudo a2ensite apache1
sudo a2enmod proxy_fcgi setenvif rewrite headers
sudo systemctl restart apache2

Настройка Nginx: Проксирование запросов в Apache (Архив)

Создаем конфиг для Nginx, который будет перенаправлять динамические запросы на Apache․

sudo nano /etc/nginx/sites-available/apache1․example․com

Пример конфигурации с перенаправлением (проксированием) в «архив» (Apache):

server {
 listen 80;
 listen [::]:80;
 server_name apache1․example․com www․apache1․example․com;
 root /var/www/apache1;
 # 1․ Статику отдает Nginx сразу (быстро, без нагрузки на Apache)
 location / {
 try_files $uri $uri/ /index․php$is_args$args;
 }

 # 2․ Обработка PHP — ПЕРЕНАПРАВЛЕНИЕ ЗАПРОСА В АРХИВ (Apache на 8080)
 location ~ ․php$ {
 # Важно: передаем заголовки, чтобы Apache видел реальный IP клиента
 proxy_set_header X-Real-IP $remote_addr;
 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 proxy_set_header Host $host;
 proxy_set_header X-Forwarded-Proto $scheme;
 
 # Отключаем буферизацию для стриминга/долгих скриптов
 proxy_buffering off;
  # Само перенаправление на бэкенд (Apache)
 proxy_pass http://127․0․0․1:8080;
 }

 # 3․ Запрет доступа к скрытым файлам и бэкапам
 location ~ /․(htaccess|htpasswd|git|svn) {
 deny all;
 } 
 # Логирование на стороне Nginx (архив входящих запросов)
 access_log /var/log/nginx/apache1_access․log;
 error_log /var/log/nginx/apache1_error․log;
}

Активация и проверка

sudo ln -s /etc/nginx/sites-available/apache1․example․com /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Проверка: Создайте /var/www/apache1/info․php с содержимым <?php phpinfo; ?>․ Откройте в браузере http://apache1․example․com/info․php․ В блоке Server API должно быть Apache 2․0 Handler, а в $_SERVER['SERVER_PORT'] — 8080 (или 80, если настроен mod_rpaf/mod_remoteip)․

Решение проблемы реального IP (mod_remoteip)

По умолчанию Apache видит IP-адрес Nginx (127․0․0․1)․ Чтобы «архив» (Apache) видел реальные IP посетителей:

  1. Установите модуль: sudo a2enmod remoteip
  2. Создайте конфиг /etc/apache2/conf-available/remoteip․conf:
RemoteIPHeader X-Real-IP
RemoteIPInternalProxy 127․0․0․1
  1. Включите и перезапустите: sudo a2enconf remoteip && sudo systemctl restart apache2

Часть 2․ Перенаправление URL на архивный раздел (SEO и Редиректы)

Если задача — переместить старый контент в раздел /archive/ или на поддомен archive․site․com, используются директивы rewrite (Nginx) или RedirectMatch (Apache)․

Nginx: Редирект старой структуры в /archive/

server {
 # ․․․
 
 # Редирект всех старых статей /blog/old-post -> /archive/blog/old-post (301 Permanent)
 location ~ ^/blog/(․)$ {
 return 301 /archive/blog/$1;
 }

 # Или редирект на поддомен архива
 location ~ ^/old-section/(․)$ {
 return 301 https://archive․example;com/old-section/$1;
 }
 
 # Сама отдача архива (статичные файлы)
 location /archive/ {
 root /var/www/;
 # Можно добавить заголовки кэширования на долгое время
 expires 1y;
 add_header Cache-Control "public, immutable";
 }
}

Apache (․htaccess): Редирект в архив

RewriteEngine On

RewriteRule ^legacy/(․)$ /archive/legacy/$1 [R=301,L]

RewriteCond %{HTTP_HOST} ^example․com$ [NC]
RewriteRule ^legacy/(․)$ https://archive․example․com/legacy/$1 [R=301,L,NC]

Часть 3․ Архивирование запросов на уровне приложения (Data Tier)

В высоконагруженных системах «горячие» данные лежат в быстрой БД (PostgreSQL, MySQL, Redis), а «холодные» (старше 1 года) уходят в архивное хранилище (ClickHouse, S3/Parquet, отдельный PG-кластер)․

Паттерн «Proxy / Router» в коде (Python/Go/Node․js)

Приложение само решает, куда идти за данными․

# Псевдокод (Python/FastAPI пример)
@app․get("/api/data/{item_id}")
async def get_data(item_id: int, db_hot: Session, db_archive: Session):
 # 1․ Пытаемся найти в горячей БД
 item = db_hot․query(Item)․filter(Item․id == item_id)․first
 
 if item:
 return item
 
 # 2․ Перенаправляем запрос в АРХИВ (Cold Storage)
 # Логируем факт обращения к архиву (метрики)
 METRICS․archive_hits․inc
  archived_item = db_archive․query(ArchivedItem)․filter(ArchivedItem․id == item_id)․first
 
 if archived_item:
 # Опционально: вернуть с заголовком X-Data-Source: archive
 return JSONResponse(content=archived_item, headers={"X-Data-Source": "archive"})
 
 raise HTTPException(status_code=404, detail="Not found in hot or archive")

PostgreSQL: Таблицы-наследники (Table Inheritance) или Partitioning

Нативное перенаправление запросов внутри БД:

-- Создаем партиционированную таблицу (PostgreSQL 10+)
CREATE TABLE logs (
 id bigserial,
 created_at timestamptz NOT NULL,
 data jsonb
) PARTITION BY RANGE (created_at);

-- Горячая партиция (текущий месяц)
CREATE TABLE logs_hot PARTITION OF logs
 FOR VALUES FROM ('2026-07-01') TO ('2026-08-01');

-- Архивные партиции (прошлые месяцы) — можно вынести на другой Tablespace (диск)
CREATE TABLE logs_2026_06 PARTITION OF logs
 FOR VALUES FROM ('2026-06-01') TO ('2026-07-01')
 TABLESPACE slow_disk_storage;

-- Запрос SELECT * FROM logs WHERE created_at > '2026-06-15'
-- САМ ПЕРЕНАПРАВИТ ЧТЕНИЕ в нужную партицию (в т․ч․ в архив на медленном диске)․

Часть 4․ Архивирование самих запросов (Request Logging / Audit Log)

Часто «перенаправить запрос в архив» означает: «Сохранить полную копию HTTP-запроса (Headers, Body, IP, Time) в надежное хранилище для аудита/безопасности»․

Nginx: Сохранение полного тела запроса в JSON (для ELK/Loki)

http {
 log_format json_analytics escape=json
 '{'
 '"time": "$time_iso8601", '
 '"remote_addr": "$remote_addr", '
 '"request_id": "$request_id", '
 '"method": "$request_method", '
 '"uri": "$request_uri", '
 '"status": $status, '
 '"body_bytes_sent": $body_bytes_sent, '
 '"request_body": "$request_body", ' # Требует: client_max_body_size и lua/nginx-module или ngx_http_js_module для больших тел
 '"upstream_addr": "$upstream_addr", '
 '"upstream_response_time": "$upstream_response_time"'
 '}';

 access_log /var/log/nginx/access․json json_analytics;
 
 # Отправка в Syslog (для пересылки в SIEM/Архив логов)
 # access_log syslog:server=logs․archive․local:514,facility=local7,tag=nginx,severity=info json_analytics;
}

Vector / Fluent Bit / Filebeat: Агент для отправки в Архив (S3 / ClickHouse / Elasticsearch)

Современный подход, не писать логи на диск сервера, а стримить их агентом․

# Пример конфига Vector (vector․toml), перенаправление логов в S3 (Архив)
[sources․nginx_logs]
 type = "file"
 include = ["/var/log/nginx/access․json"]
 read_from = "end"
 fingerprinting = true

[transforms․parse_json]
 type = "remap"
 inputs = ["nginx_logs"]
 source = 'parse_json(․message)'
[sinks․s3_archive]
 type = "aws_s3"
 inputs = ["transforms․parse_json"]
 bucket = "my-company-logs-archive"
 region = "us-east-1"
 key_prefix = "nginx/%Y/%m/%d/"
 compression = "gzip"
 encoding = "ndjson"
 
 # Буферизация перед отправкой в архив
 [sinks․s3_archive․buffer]
 type = "disk"
 max_size = 104857600 # 100MB
 when_full = "block"

Часть 5․ Чек-лист безопасности при перенаправлении в архив/бэкенд

При настройке любого вида проксирования или редиректа на «архивные» системы:

  1. Заголовки доверия (Trust Headers): Всегда валидируйте X-Forwarded-For, X-Real-IP на бэкенде․ Настройте список доверенных прокси (CIDR) в Apache (RemoteIPInternalProxy) или в коде приложения․
  2. Защита от SSRF (Server-Side Request Forgery): Если «архив» — это внутренний API, убедитесь, что Nginx/приложение не позволяет злоумышленнику перенаправить запрос на http://169․254․169․254 (метаданные облака) или http://localhost:22․
  3. Таймауты: Архивные системы часто медленные․ Увеличьте proxy_read_timeout (Nginx) / Timeout (Apache) / HTTP-клиент таймауты в коде․
  4. Идемпотентность: Перенаправляйте в архив только безопасные методы (GET, HEAD, OPTIONS)․ POST/PUT/DELETE в архив (read-only replica) должны блокироваться на уровне прокси или БД․
  5. Шифрование в транзите: Даже внутри VPC используйте mTLS или хотя бы HTTPS между Nginx и Apache / Приложением и Архивной БД․

«Перенаправление запроса в архив» — это мультилейерная задача:

  • На уровне L7 (Nginx/Apache) — это настройка proxy_pass на бэкенд (как в примере с Ubuntu 20․04) или return 301 /archive/ для SEO․
  • На уровне приложения — это роутинг чтения в Cold Storage (ClickHouse, S3, Partitioned Tables)․
  • На уровне наблюдаемости — это стриминг логов запросов в долговременное хранилище (Vector -> S3/ELK)․

Выбирайте подход в зависимости от цели: производительность (разделение статики/динамики через Nginx->Apache), соответствие GDPR/152-ФЗ (архивирование логов в S3 с шифрованием) или UX/SEO (аккуратные 301 редиректы на архивный поддомен)․


Статья подготовлена на основе актуальных практик DevOps и системного администрирования Linux (Ubuntu/Debian)․ Версии ПО: Nginx 1․18+/1․24+, Apache 2․4+, PHP 8․1+․ Дата актуальности: ․