Вариант обращения к домену некоторого сайта по другому домену или IP используя подмену на уровне расширения для браузера Firefox

Гобелен - кликните для возврата на главную

Не прошло и месяца а Фурмановская ЦРБ в очередной раз попала в историю. На этот раз сотрудница клеветала на пациентов, а именно огласку получил случай когда сотрудница назвала пациента алкашём.

Так почему бы не начать использовать обход блокировки YouTube при том что техническая возможность используя расширение nikolaevevge для браузера Mozilla Firefox уже появилась, а объем полезной(и не очень) информации на видеохостинге YouTube, по мнению некоторых диванных экспертов, меньше не стал.

Ровно 3 года назад произошло событие, которое подарило жителям планеты Змеля новый чистый праздник 6 апреля - в этот замечательный день земля забрала гнить негодяя и СПАМера Владимира Вольфовича Жириновского.

Как бы не обстояли дела в области культуры и IT-технологий, Самосвал писал статьи на связанные темы и планирует ещё написать.

На очередном конкурсе танцев, школьница отлично выступила.

Что использовать вместо Юбуст

Вот та самая информация: программа для продвижения канала YouTube, эта информация выложена уже несколько лет, при этом просмотров не много, а метод который описан в данном видео действительно помогает продвигать видео в YouTube.

Начал разбираться с информацией которая находится в HTTPS клиентском запросе рукопожатия.

Обратите внимание! Объект изображённый на гобилене может отличаться от общепринятого вида описанного объекта. Тут дело в том что художник видит именно так!

104 549 руб.

Описание товара

Доброго времени суток. Рассмотрим некоторое расширение для браузера Firefix(именно дня него) которое будет являться тестовым(прямого назначения у него нет, при этом это поможет разобраться в теме обхода DPI оборудования РКН блокирующего некоторый трафик). Предположим что есть некоторый домен, например examper1.ru его IP адрес 1.2.3.4 предположим что некоторый сайт в браузере Fireofx осуществляет загрузку изображения с указанного домена, например с адреса https://example1.ru/img.jpeg Возможно ли на уровне расширения Firefox перехватить обращение и перенаправить его по IP адресу, при этом так чтобы HTTP заголовок Host по прежнему содержал адрес домена. То есть чтобы в HTTPS в sni указывался только IP а HTTP заголовок остался без изменения.

Да, это возможно с помощью расширения для Firefox, но с некоторыми ограничениями и нюансами.

Как это можно реализовать?

Перехват запросов с помощью webRequest API

Firefox предоставляет API webRequest, которое позволяет перехватывать и модифицировать HTTP-запросы.

Перенаправление на IP с сохранением Host-заголовка

Можно перехватить запрос к https://example1.ru/img.jpeg.

Заменить URL на https://1.2.3.4/img.jpeg.

Установить заголовок Host: example1.ru.

Проблема с HTTPS и SNI

В HTTPS клиент (Firefox) отправляет SNI (Server Name Indication), который содержит исходное доменное имя (example1.ru).

Если сервер ожидает SNI example1.ru, а вы подменяете URL на IP, это может вызвать ошибку SSL, если сервер не принимает IP в SNI.

Обойти это можно только если сервер принимает IP в SNI или если Firefox позволяет подменить SNI (что маловероятно в стандартном API).

Пример кода расширения

Файл manifest.json

JSON
    
{
  "manifest_version": 2,
  "name": "DNS Override",
  "version": "1.0",
  "permissions": [
    "webRequest",
    "webRequestBlocking",
    "*://example1.ru/*"
  ],
  "background": {
    "scripts": ["background.js"]
  }
}

  

Файл background.js

JavaScript
    
function rewriteRequest(details) {
  const targetUrl = details.url.replace(
    "https://example1.ru/",
    "https://1.2.3.4/"
  );
  
  return {
    redirectUrl: targetUrl
  };
}
      
function modifyHeaders(details) {
  const headers = details.requestHeaders;
  for (let i = 0; i < headers.length; i++) {
    if (headers[i].name.toLowerCase() === "host") {
      headers[i].value = "example1.ru";
    }
  }
  
  return { requestHeaders: headers };
}
      
browser.webRequest.onBeforeRequest.addListener(
  rewriteRequest,
  { urls: ["*://example1.ru/*"] },
  ["blocking"]
);
      
browser.webRequest.onBeforeSendHeaders.addListener(
  modifyHeaders,
  { urls: ["*://1.2.3.4/*"] },
  ["blocking", "requestHeaders"]
);

  

Ограничения

SNI в HTTPS

Firefox не позволяет изменить SNI через стандартное API расширений.

Если сервер требует example1.ru в SNI, а браузер отправляет IP, соединение может не установиться.

HTTP vs HTTPS

Для HTTP этот метод работает.

Для HTTPS потребуется либо:

Настроить сервер принимать IP в SNI (редко поддерживается).

Использовать более низкоуровневые методы (например, прокси-расширения с модификацией TLS).

Альтернативные подходы

Проксирование через локальный сервер (например, SOCKS5 + подмена DNS).

Использование Firefox Enterprise Policies для принудительной подмены DNS.

DoH/DoT (DNS-over-HTTPS/DNS-over-TLS) с кастомным резолвером.

Вывод

Да, можно перенаправить запрос на IP с сохранением Host-заголовка, но для HTTPS SNI останется проблемой, если сервер строго проверяет домен. Для полного обхода DPI может потребоваться более сложное решение (например, туннелирование через прокси или VPN).

Да, я так же подумал, что если на уровне HTTPS заменить домен на IP это может приводить к проблемам с SSL ведь у IP не может быть SSL сертификата(или это не так и для IP так же можно выпустить SSL например от Let's encrypt?). Поэтому рассмотрим другой вариант. Возьмём 2 реальных домена которые привязаны к одному IP адресу. А именно blog.ivru.net и handmade-decor.ru давайте предположим что картинка загружается с 1-ого, при этом нужно чтобы в SNI был указан второй домен(а в HTTP остался первый). перепишите пожалуйста расширение под указанный вариант.

Если у вас два домена (blog.ivru.net и handmade-decor.ru) привязаны к одному IP-адресу, и сервер корректно обрабатывает оба имени в SNI, то можно сделать так:

Цель

Перехватить запрос к https://blog.ivru.net/img.jpg.

Перенаправить его на тот же IP, но подменить SNI на handmade-decor.ru.

При этом оставить HTTP-заголовок Host: blog.ivru.net.

Проблема

Firefox не позволяет напрямую менять SNI через стандартное webRequest API.

Но можно обойти это, если сервер принимает оба домена на одном IP:

Решение

Подмена URL на handmade-decor.ru (чтобы Firefox сам подставил нужный SNI).

Возврат оригинального Host: заголовка (чтобы сервер видел исходный домен).

Код расширения

manifest.json

JSON
    
{
  "manifest_version": 2,
  "name": "SNI Host Override",
  "version": "1.0",
  "permissions": [
    "webRequest",
    "webRequestBlocking",
    "*://blog.ivru.net/*",
    "*://handmade-decor.ru/*"
  ],
  "background": {
    "scripts": ["background.js"]
  }
}

  

background.js

JavaScript
    
function rewriteRequest(details) {
  // Меняем домен в URL, чтобы Firefox подставил нужный SNI
  const newUrl = details.url.replace(
    "https://blog.ivru.net/",
    "https://handmade-decor.ru/"
  );
  
  return { redirectUrl: newUrl };
}
      
function restoreHostHeader(details) {
  // Возвращаем исходный Host, чтобы сервер видел blog.ivru.net
  const headers = details.requestHeaders;
  for (let header of headers) {
    if (header.name.toLowerCase() === "host") {
      header.value = "blog.ivru.net";
    }
  }
  
  return { requestHeaders: headers };
}
      
// Перехватываем запрос к blog.ivru.net и подменяем URL
browser.webRequest.onBeforeRequest.addListener(
  rewriteRequest,
  { urls: ["*://blog.ivru.net/*"] },
  ["blocking"]
);
      
// Возвращаем исходный Host после подмены URL
browser.webRequest.onBeforeSendHeaders.addListener(
  restoreHostHeader,
  { urls: ["*://handmade-decor.ru/*"] },
  ["blocking", "requestHeaders"]
);

  

Как это работает?

Браузер пытается загрузить https://blog.ivru.net/img.jpg.

Расширение меняет URL на https://handmade-decor.ru/img.jpg → Firefox отправляет SNI handmade-decor.ru.

Затем расширение подменяет Host: обратно на blog.ivru.net → сервер видит исходный домен.

Ограничения

Работает, если:

Оба домена (blog.ivru.net и handmade-decor.ru) привязаны к одному IP.

Сервер корректно обрабатывает оба имени в SNI.

У handmade-decor.ru есть валидный SSL-сертификат (иначе Firefox отклонит соединение).

Не работает, если:

Сервер проверяет соответствие SNI и Host: (редко, но бывает).

Домены находятся на разных IP.

Альтернатива (если не работает)

Если сервер требует строгого соответствия SNI и Host:, можно:

Настроить прокси (например, SOCKS5) с подменой DNS.

Использовать Firefox с кастомными настройками network.security.ssl_tokens_cache (через about:config).

Развернуть локальный прокси (на Python/Go), который будет подменять SNI.

Если вам нужно что-то более сложное (например, полный обход DPI), уточните задачу — можно предложить другие методы.

Я ещё не попробовал то что Вы предложили выше. Ещё вопрос на связанную тему. Предположим есть тот же домен blog.ivru.net. Известен его IP. Предположим что Web-сервер этого домена отвечает на 2-х IP. Предположим по техническим причинам в DNS был оставлен только 1 IP, тем не менее по 2-ому IP сервер тоже ответит. Например системному администратору требуется проверить как работает сайт с 2-ого IP. Например этот IP 1.2.3.4 может ли сисадмин использовать расширение чтобы браузер не использовал DNS-запросов а обращался бы по нужному сисадмину IP а указанному домену. Задачу необходимо решать именно с использованием расширения Firefox, а не другими способами(в том числе поскольку это учебная задача и планируется выяснить применимость к этому вопросу использование расширений Firefox).

Да, системный администратор может использовать расширение Firefox, чтобы принудительно направлять запросы к домену blog.ivru.net на конкретный IP (1.2.3.4) без использования DNS.

Решение

Перехват запросов к blog.ivru.net через webRequest API.

Подмена URL на https://1.2.3.4, но с сохранением заголовка Host: blog.ivru.net.

Игнорирование DNS (поскольку запрос идёт напрямую по IP).

Код расширения

Файл manifest.json

JSON
    
{
  "manifest_version": 2,
  "name": "Force IP for Domain",
  "version": "1.0",
  "permissions": [
    "webRequest",
    "webRequestBlocking",
    "*://blog.ivru.net/*",
    "*://1.2.3.4/*"
  ],
  "background": {
    "scripts": ["background.js"]
  }
}

  

Файл background.js

JavaScript
    
function rewriteToIP(details) {
  // Заменяем домен на IP (HTTPS)
  const newUrl = details.url.replace(
    "https://blog.ivru.net/",
    "https://1.2.3.4/"
  );
  return { redirectUrl: newUrl };
}
      
function restoreHostHeader(details) {
  // Возвращаем оригинальный Host, чтобы сервер видел blog.ivru.net
  const headers = details.requestHeaders;
  for (let header of headers) {
    if (header.name.toLowerCase() === "host") {
      header.value = "blog.ivru.net";
    }
  }
  return { requestHeaders: headers };
}
      
// Перехватываем запросы к blog.ivru.net и подменяем на IP
browser.webRequest.onBeforeRequest.addListener(
  rewriteToIP,
  { urls: ["*://blog.ivru.net/*"] },
  ["blocking"]
);
      
// Подменяем Host-заголовок обратно на blog.ivru.net
browser.webRequest.onBeforeSendHeaders.addListener(
  restoreHostHeader,
  { urls: ["*://1.2.3.4/*"] },
  ["blocking", "requestHeaders"]
);

  

Как это работает?

Пользователь запрашивает https://blog.ivru.net/image.jpg.

Расширение меняет URL на https://1.2.3.4/image.jpg (DNS не используется).

Браузер подключается к 1.2.3.4, но отправляет Host: blog.ivru.net.

Сервер видит запрос к blog.ivru.net и отвечает (если настроен виртуальный хостинг).

Ограничения

Работает, если:

Сервер 1.2.3.4 принимает HTTPS-запросы с Host: blog.ivru.net.

У сервера есть валидный SSL-сертификат для blog.ivru.net (иначе будет ошибка SSL_ERROR_BAD_CERT_DOMAIN).

Не работает, если:

Сервер требует строгого соответствия SNI и Host: (редко).

У 1.2.3.4 нет SSL-сертификата для blog.ivru.net.

Дополнительные проверки

Проверить, отвечает ли 1.2.3.4 на запросы:

curl -vk --resolve "blog.ivru.net:443:1.2.3.4" https://blog.ivru.net/

(Если работает, то и расширение должно сработать.)

Если SSL невалидный, можно временно отключить проверку в Firefox (about:config → security.tls.version.min = 1), но это небезопасно.

Вывод

Да, расширение Firefox может принудительно направлять запросы к домену по конкретному IP, минуя DNS. Главное, чтобы сервер был корректно настроен.

Если нужно обойти проблему с SNI/SSL — можно рассмотреть вариант с подменой домена (как в предыдущем ответе) или локальным прокси.

Вы пишите: "У 1.2.3.4 нет SSL-сертификата для blog.ivru.net." - я так думаю что SSL действительно нет. А скажите пожалуйста если Web-сервер httpd(ОС CentOs 7) он будет применять сертификат к информации в SNI или Host? Я так думаю к первому, ведь до момента установки HTTPS соединения информация о HPPT заголовках включая Host ещё не расшифрована.

Вы абсолютно правы! Сервер (httpd на CentOS 7) проверяет SSL-сертификат на основе SNI, а не HTTP-заголовка Host.

Почему так?

SNI (Server Name Indication) передаётся до установки TLS-соединения в открытом виде (в ClientHello).

Браузер говорит: "Я хочу подключиться к blog.ivru.net, вот мой SNI".

Сервер должен предоставить валидный сертификат для blog.ivru.net, иначе соединение не установится.

HTTP-заголовок Host передаётся после установки TLS.

Если сервер принимает любой SNI (например, IP или другой домен), но потом смотрит Host, это не влияет на SSL-валидацию.

Что произойдёт в вашем случае?

Если у 1.2.3.4 нет сертификата для blog.ivru.net, то:

Браузер отправит SNI = 1.2.3.4 (если URL = https://1.2.3.4/).

Сервер предоставит сертификат для 1.2.3.4 (или default-сертификат).

Firefox увидит, что сертификат не соответствует blog.ivru.net → ошибка SSL_ERROR_BAD_CERT_DOMAIN.

Как можно обойти?

1. Подмена SNI через расширение (невозможно в Firefox)

Firefox не позволяет менять SNI через webRequest API. Это ограничение безопасности.

2. Использование домена в SNI, но IP в URL

Если: handmade-decor.ru и blog.ivru.net на одном IP,

Сервер имеет валидный сертификат для handmade-decor.ru, то можно:

Подменить URL на https://1.2.3.4/ (IP),

Но принудительно указать SNI = handmade-decor.ru (через низкоуровневые настройки или прокси).

3. Локальный прокси с подменой SNI

Написать простой прокси (на Python/SOCKS), который:

Принимает запросы к blog.ivru.net,

Подключается к 1.2.3.4, но подставляет нужный SNI.

Пример на Python (mitmproxy, socat или nginx reverse proxy).

4. Добавить IP в hosts и использовать самоподписанный сертификат

# /etc/hosts

1.2.3.4 blog.ivru.net

Затем импортировать самоподписанный сертификат blog.ivru.net в Firefox.

Вывод

HTTPD (CentOS 7) смотрит только SNI для SSL.

Если у 1.2.3.4 нет сертификата для blog.ivru.net — расширение не поможет, нужен либо:

Валидный сертификат для IP/домена,

Локальный прокси с подменой SNI,

Отключение проверки сертификата (небезопасно!).

Если задача учебная, лучше изучить проксирование с кастомным SNI — это даст полный контроль.

Вы пишите: "Если у 1.2.3.4 нет сертификата для blog.ivru.net — расширение не поможет, нужен либо" предположим у меня в httpd есть 2 виртуальных хоста. Один для IP 1.2.3.4 другой для blog.ivru.net которые ведут на один DocumentRoot и по сути обрабатывают таким образом один сайт. У домена blog.ivru.net есть SSL у IP своего SSL быть не может(ведь не может же у IP быть сертификата, правильно?) при этом для виртуального хоста по IP я указал SSL тот же что и у домена blog.ivru.net. При этом разве когда запрос вернётся браузеру, разве Fireofx будет проверять SSL для домена в Host а не тот что в SNI, а ведь там перед запросом уже домен был изменён на IP?

Давайте разберём ваш сценарий по шагам, чтобы понять, как работает проверка SSL в Firefox и Apache (httpd).

1. Ваша текущая настройка Apache (httpd)

У вас есть 2 виртуальных хоста в Apache:

Для домена blog.ivru.net

ServerName blog.ivru.net

Валидный SSL-сертификат (например, от Let's Encrypt).

DocumentRoot /var/www/html

Для IP 1.2.3.4

ServerName 1.2.3.4

Использует тот же SSL-сертификат, что и blog.ivru.net.

DocumentRoot /var/www/html (тот же сайт).

Это корректная настройка, если сервер Apache настроен принимать HTTPS для IP с чужим сертификатом (обычно требует ServerAlias или default-ssl).

2. Как работает SSL/TLS и проверка сертификата?

Когда Firefox подключается к сайту:

Шаг 1: SNI (Server Name Indication)

Браузер отправляет в ClientHello имя хоста (например, blog.ivru.net или 1.2.3.4).

Сервер Apache выбирает виртуальный хост на основе SNI (не на основе Host!).

Шаг 2: Сервер отправляет сертификат

Если SNI = blog.ivru.net → Apache отдаёт сертификат для blog.ivru.net.

Если SNI = 1.2.3.4 → Apache отдаёт сертификат, привязанный к виртуальному хосту IP (в вашем случае — тот же, что и для blog.ivru.net).

Шаг 3: Firefox проверяет сертификат

Браузер сравнивает домен в URL с Common Name (CN) или Subject Alternative Name (SAN) в сертификате.

Если URL = https://1.2.3.4/, а сертификат выдан для blog.ivru.net → ошибка SSL_ERROR_BAD_CERT_DOMAIN (так как IP ≠ домен).

3. Что произойдёт в вашем сценарии?

Случай 1: Запрос идёт напрямую к https://blog.ivru.net/

Всё работает:

SNI = blog.ivru.net → Apache отдаёт правильный сертификат.

Firefox видит, что сертификат валиден для blog.ivru.net.

Случай 2: Запрос идёт к https://1.2.3.4/ (с Host: blog.ivru.net)

Проблема:

SNI = 1.2.3.4 (так как URL содержит IP).

Apache отдаёт сертификат для blog.ivru.net (если настроено).

Firefox ожидает сертификат для 1.2.3.4, но получает для blog.ivru.net → ошибка SSL.

4. Можно ли обойти эту проблему?

Вариант 1: Добавить IP в SAN сертификата

Если у вас есть контроль над сертификатом, можно:

Включить 1.2.3.4 в Subject Alternative Name (SAN) сертификата.

Перевыпустить сертификат (например, через Let's Encrypt с --expand).

Тогда Firefox примет сертификат для 1.2.3.4.

Вариант 2: Подмена SNI (но Firefox не позволяет)

Расширения не могут менять SNI в Firefox. Нужен внешний прокси (например, Nginx или mitmproxy).

Вариант 3: Отключить проверку сертификата (небезопасно!)

В about:config Firefox:

  • security.tls.version.min = 1
  • security.ssl.require_safe_negotiation = false

Не рекомендуется (уязвимость к MITM-атакам).

5. Вывод

Firefox проверяет сертификат для домена в URL, а не в Host.

Если URL = https://1.2.3.4/, а сертификат выдан для blog.ivru.net → ошибка SSL.

Решение:

Либо использовать доменное имя в URL (не IP),

Либо добавить IP в SAN сертификата,

Либо использовать прокси с подменой SNI.

Если задача учебная, лучше всего попробовать выпустить сертификат с SAN для IP — это самый чистый способ.

Про то как создавать расширения для браузера Firefox я рассказал в этой статье и этом видео.

Другие товары

Вы так же можете прочитать следующие статьи: