Going-Dark

Defensive & Threat Intelligence vlatest активный

Система изоляции устройств для приватности, направленная на предотвращение несанкционированного lateral movement в сети.

vlatest
current

Установка
Полная пошаговая инструкция по сборке устройства на Raspberry Pi 4B (8 ГБ): установка Raspberry Pi OS (headless), усиление SSH, отключение IPv6, случайные MAC-адрес и hostname, настройка USB-C Ethernet и точки доступа, подготовка dnsmasq. Полное руководство (20+ разделов) — в README проекта, начиная с раздела «Предварительные требования».
показать оригинал переведено ИИ

Going Dark: USB-устройство для приватности на базе Raspberry Pi

Портативное USB Ethernet-устройство на Raspberry Pi для защиты вашей конфиденциальности

Знаете ли вы о растущей озабоченности европейских правоохранительных органов по поводу того, что люди уходят в тень? Так называемая Высокоуровневая группа (HLG) активно работает над подрывом сквозного шифрования, добиваясь доступа через задние двери к зашифрованным мессенджерам, облачным хранилищам и почтовым сервисам. EDRi разобрала критические изъяны в этом подходе: https://edri.org/?s=going+dark

Если вы ещё не ушли в тень, сейчас самое время!

Этот репозиторий — одновременно руководство и пошаговый учебник по настройке Raspberry Pi 4 в качестве USB Ethernet-устройства. Оно заставляет ваш компьютер направлять весь интернет-трафик через WireGuard VPN или прозрачный прокси Tor, фильтруя исходящий трафик, блокируя рекламу и трекеры, а также подменяя идентификатор устройства для повышения приватности.

ЧАСТЬ 1: БЭКЕНД

ЧАСТЬ 2: ФРОНТЕНД


ЧАСТЬ 1: БЭКЕНД

01 ВВЕДЕНИЕ

Впервые идея этого Ethernet-устройства на Raspberry Pi пришла к нам пять лет назад, когда Apple публично выпустила macOS Big Sur осенью 2020 года. Во время перехода мы заметили, что наша установка Little Snitch — хост-ориентированного межсетевого экрана — частично перестала работать. Конкретно: все процессы Apple больше не фильтровались. Странно.

Изучая проблему в интернете, мы наткнулись на статью исследователя в области безопасности Джеффри Пола под названием Ваш компьютер — не ваш. Его выводы пролили свет на суть проблемы, и мы настоятельно рекомендуем прочитать эту статью перед настройкой собственного устройства для приватности на Raspberry Pi.

Кратко: в современных версиях macOS есть встроенная возможность обходить внутренние межсетевые экраны и VPN. Кроме того, каждый компьютер Apple постоянно подключается к серверам Apple и сторонним сервисам (например, Fastly), чтобы передавать хеши запускаемых приложений — каждый раз, когда вы их открываете:
Это должно быть функцией безопасности для обнаружения вредоносного ПО. Она нужна, чтобы предотвратить запуск вредоносных или заблокированных приложений, если проверка онлайн-сертификата не проходит. Возможно, это и так, но это также означает, что Apple всегда может определить, когда вы в сети, где находитесь, как долго используете определённое ПО (например, VMWare Fusion) или когда запускаете Tor Browser вместо Safari.
Со временем этот сбор данных формирует крайне детализированный профиль ваших цифровых привычек, физических перемещений и паттернов активности. Хуже того, эту информацию можно потенциально сопоставить с другими большими данными от корпораций вроде Google, Microsoft и Facebook. Как метко замечает Джеффри Пол:

С октября 2012 года Apple является партнёром программы слежки PRISM сообщества военной разведки США, которая предоставляет федеральной полиции и армии США неограниченный доступ к этим данным без ордера, всякий раз, когда они его запрашивают. Мы рассматриваем это как крайне тревожное развитие событий: ещё один шаг в сторону надзорного капитализма, подрывающий конфиденциальность всех пользователей Apple.

Справедливости ради, Apple столкнулась с серьёзной критикой за эти практики. В результате некоторые из этих вторжений, такие как ContentFilterExclusionList, который позволял родным приложениям Apple обходить локальные брандмауэры и VPN, были отменены: Стена без дыры.

Согласно Apple, конфиденциальность — это фундаментальное право человека:

Конфиденциальность — это фундаментальное право человека. В Apple это также одна из наших основных ценностей. Ваши устройства важны для многих аспектов вашей жизни. То, чем вы делитесь из этих опытов, и с кем вы этим делитесь, должно зависеть только от вас. Мы разрабатываем продукты Apple так, чтобы защищать вашу конфиденциальность и давать вам контроль над вашей информацией. Это не всегда легко. Но это тот вид инноваций, в которые мы верим.

Однако заявлять о глубокой заботе о конфиденциальности пользователей, одновременно официально поддерживая Закон CLOUD и участвуя в программах вроде PRISM, означает двойные стандарты, которые не должны терпеться.

Кто может гарантировать, что что-то вроде ContentFilterExclusionList не вернётся тихо в одном из будущих обновлений? Мы считаем, что Apple нельзя доверять наши данные. Именно поэтому мы создали Raspberry Pi Ethernet Gadget — портативное внешнее устройство для фильтрации сети, предназначенное для того, чтобы максимально усложнить сбор данных.

Как справедливо отмечает Джеффри Пол: ваш компьютер — не ваш.
Но он должен быть вашим!


21 февраля 2025 года Apple отключила функцию расширенной защиты данных (ADP) для пользователей из Великобритании, вероятно, в ответ на секретное распоряжение правительства Великобритании, известное как Technical Capability Notice, выданное в рамках Закона о следственных полномочиях 2016 года. Уже 7 февраля 2025 года The Washington Post сообщила об утекшем документе, в котором предсказывался шаг Apple. В соответствии с требованиями Apple перестала предлагать ADP новым пользователям из Великобритании и объявила о планах отключить её для существующих пользователей. Этот шаг, вероятно, направлен на защиту пользователей Apple по всему миру, поскольку британские надзорные органы требуют доступа к зашифрованным резервным копиям Apple во всём мире.

Даже Google не может ни подтвердить, ни опровергнуть получение такого распоряжения, что указывает на то, что компания также получила аналогичное Technical Capability Notice.

«Правительство Великобритании предоставило себе возможность отправлять компаниям по всему миру уведомления, обязывающие их тайно подрывать безопасность своих пользователей, продуктов или услуг. Компания не может никому об этом рассказать, она даже не может публично признать, что получила такое уведомление. Она не может выразить несогласие, не может предупредить пользователей о том, что они пострадали, и не может оспорить это решение в открытом суде, потому что секретный приказ — это секрет. Это уведомление затрагивает миллионы людей, которые не имеют права узнать о его существовании».

Privacy International

Apple подала апелляцию в Трибунал по следственным полномочиям, оспаривая законность распоряжения правительства. Результат этой апелляции может иметь значительные последствия для конфиденциальности пользователей и объёма полномочий правительства в области надзора в Великобритании.

Однако это фактически означает, что все данные, хранящиеся в облаке пользователями из Великобритании, больше не защищены сквозным шифрованием. Вместо этого Apple хранит ключи шифрования, что означает, что компания должна передать их по требованию ордера.

Это не просто изменение политики: это прямая атака на шифрование и конфиденциальность в интернете в целом.

РЕКОМЕНДУЕМАЯ ЛИТЕРАТУРА:

Privacy International:
https://privacyinternational.org/news-analysis/5530/apple-and-long-secret-arm-uk-government https://privacyinternational.org/explainer/5531/pis-opinion-how-uk-government-making-security-harder-everyone

The Washington Post:
https://www.washingtonpost.com/technology/2025/02/07/apple-encryption-backdoor-uk/

Heise Online:
https://www.heise.de/en/news/Even-Google-cannot-deny-the-British-surveillance-order-10318847.html

Джеффри Пол:
https://sneak.berlin/20201112/your-computer-isnt-yours/#updates

Apple:
https://www.apple.com/ru/privacy/
https://www.apple.com/ru/legal/transparency/

PRISM и CLOUD Act:
https://ru.wikipedia.org/wiki/PRISM
https://www.reuters.com/article/us-apple-fbi-icloud-exclusive/exclusive-apple-dropped-plan-for-encrypting-backups-after-fbi-complained-sources-idUSKBN1ZK1CT
https://ru.wikipedia.org/wiki/CLOUD_Act

Objective Development:
https://blog.obdev.at/a-wall-without-a-hole/
https://blog.obdev.at/a-hole-in-the-wall/


02 ОСОБЕННОСТИ

GOING DARK: Это устройство для конфиденциальности на базе Raspberry Pi работает как портативный маршрутизатор, давая вам полный контроль над всем сетевым трафиком, включая собственные процессы Apple. Следуя нашему руководству, Wi-Fi вашего Mac будет полностью отключён. Вместо этого он будет подключаться к Raspberry Pi через USB-C, а Raspberry Pi будет управлять интернет-соединением.

1) РЕЖИМ 1: Фильтрация на уровне сети с AdGuardHome

В этом режиме ваше Ethernet-устройство фильтрует весь трафик через AdGuardHome — самовозводимый DNS-сервер, предназначенный для блокировки рекламы, трекеров и вредоносных доменов во всей сети. Для дополнительной конфиденциальности мы настраиваем Unbound как апстрим-резолвер DNS, что гарантирует, что ваши запросы разрешаются конфиденциально без зависимости от сторонних DNS-провайдеров. Кроме того, мы устанавливаем обширные списки блокировки, включая наш собственный «Ультимативный список блокировки Apple», который блокирует все домены, принадлежащие Apple. ПРЕДУПРЕЖДЕНИЕ: активация этого списка нарушит работу сервисов и программ Apple. Продолжайте с осторожностью.

2) РЕЖИМ 2: Зашифрованный VPN-туннель с WireGuard (необязательная настройка)

В этом режиме вы можете использовать Raspberry Pi как клиент WireGuard, что позволяет установить защищённый зашифрованный VPN-туннель. Вы можете подключиться к домашнему маршрутизатору (РЕКОМЕНДУЕТСЯ, если на нём установлен и настроен WireGuard) или к любому другому серверу WireGuard на ваш выбор (НЕ РЕКОМЕНДУЕТСЯ). Даже с включённым VPN AdGuardHome будет продолжать фильтровать рекламу и трекеры перед передачей DNS-запросов через зашифрованный туннель. Это обеспечивает как конфиденциальность, так и безопасность, сохраняя полную блокировку рекламы на уровне сети.

3) РЕЖИМ 3: Прозрачный прокси Tor

В этом режиме весь ваш интернет-трафик маршрутизируется через прозрачный прокси Tor, обеспечивая анонимность за счёт передачи соединений через сеть Tor. Даже в этой настройке AdGuardHome продолжает фильтровать рекламу и трекеры перед тем, как трафик попадает в сеть Tor, что улучшает конфиденциальность и сокращает ненужные соединения. Важное замечание: это не обязательно рекомендуемый подход для анонимности. Если ваша цель — частный просмотр веб-страниц, strongly рекомендуется использовать Tor Browser, так как он предоставляет дополнительные средства защиты, недоступные для прозрачного прокси.

4) Поддержка беспроводной точки доступа

Помимо подключения Mac через USB, ваше устройство для конфиденциальности на базе Raspberry Pi может также работать как беспроводная точка доступа, позволяя другим устройствам (например, смартфонам) подключаться и использовать РЕЖИМ 1, РЕЖИМ 2 или РЕЖИМ 3 для повышения конфиденциальности и безопасности. Важное замечание: если вы хотите подключить Raspberry Pi к Wi-Fi-сети, одновременно работая в режиме точки доступа, вам потребуется дополнительный Wi-Fi-адаптер. Для этого руководства мы используем ALFA AWUS036ACM, который работает «из коробки» и обеспечивает стабильное двухдиапазонное Wi-Fi-соединение.

5) Усиленная безопасность

Чтобы обеспечить максимальную безопасность, мы внедряем несколько уровней защиты: - Защита межсетевым экраном с помощью nftables – мы настраиваем nftables как надёжный межсетевой экран, динамически управляемый через диспетчер NetworkManager для плавного переключения между РЕЖИМОМ 1, РЕЖИМОМ 2 и РЕЖИМОМ 3, обеспечивая безопасную и стабильную работу. - Упрочнённая конфигурация SSH – безопасный доступ обеспечивается благодаря тщательно защищённой настройке SSH, что снижает векторы атак и улучшает общую целостность системы. - Контроль доступа пользователей – мы создаём отдельные учётные записи администратора и стандартного пользователя, следуя лучшим практикам безопасности, чтобы ограничить привилегии и снизить риски. - Автоматические обновления безопасности – неконтролируемые обновления гарантируют, что критически важное программное обеспечение остаётся актуальным, минимизируя уязвимости и повышая устойчивость системы.

6) Случайная идентификация устройства

Каждый раз, когда вы подключаетесь к общественной сети Wi-Fi, в журналах будет фиксироваться только идентификатор Ethernet-гаджета Raspberry Pi, а не вашего Mac. Это предотвращает возможность отслеживания вашего реального устройства операторами сети.

Для дальнейшего улучшения конфиденциальности:

  • Рандомизация MAC-адреса – Ethernet-гаджет генерирует новый случайный MAC-адрес при каждом перезапуске, что значительно усложняет отслеживание устройства.
  • Генерация случайного имени хоста – при каждом перезапуске Ethernet-гаджет выбирает случайное имя хоста из заранее определённого словаря, что затрудняет его идентификацию.

Эти меры гарантируют, что ваш цифровой след остаётся максимально анонимным при подключении к общественным сетям.

7) NTP-сервер с уважением к конфиденциальности

Чтобы поддерживать точное системное время, не жертвуя конфиденциальностью, мы настраиваем Ethernet-гаджет Raspberry Pi для использования NTP-серверов, уважающих конфиденциальность, с ntppool.org.

Основные функции: - Синхронизация времени с акцентом на конфиденциальность – обеспечивает обновление системного времени через доверенные NTP-серверы, избегая централизованных источников времени, нарушающих конфиденциальность. - Расширенная поддержка автономной работы – настроена для обработки длительных периодов простоя, что позволяет устройству подключаться к интернету даже после длительного отключения. - Локальный сервер времени для подключённых устройств – клиенты, использующие Ethernet-гаджет Raspberry Pi, могут синхронизировать системное время напрямую с встроенного NTP-сервера Pi. - Необязательно: для ещё большей надёжности мы рекомендуем установить аппаратные часы (модуль RTC), чтобы избежать проблем с синхронизацией.

8) Локальный веб-интерфейс

Для упрощения управления мы настраиваем локальный веб-интерфейс, который позволяет вам:

  • Легко переключаться между РЕЖИМОМ 1, РЕЖИМОМ 2 и РЕЖИМОМ 3
  • Подключать Raspberry Pi к внешним сетям Wi-Fi без использования команд терминала
  • Включать или отключать точку доступа одним кликом

Этот интуитивно понятный интерфейс обеспечивает удобное управление вашим Ethernet-гаджетом Raspberry Pi, позволяя легко настраивать параметры прямо из браузера.


03 ПРЕДВАРИТЕЛЬНЫЕ ТРЕБОВАНИЯ

АППАРАТНОЕ ОБЕСПЕЧЕНИЕ:

Для этой настройки мы используем Raspberry Pi 4B (8 ГБ). Чтобы обеспечить стабильную работу, важно использовать высококачественный кабель USB-C, поддерживающий быструю передачу данных. Кроме того, мы используем ALFA AWUS036ACM. Если вы выберете другой внешний Wi-Fi-адаптер, убедитесь, что он совместим с Raspberry Pi OS, и обновите имя интерфейса в этом руководстве соответственно! Надёжная карта microSD критически важна для плавной работы. Избегайте дешёвых, низкокачественных брендов. Мы настоятельно рекомендуем карты SanDisk с рейтингом A1, так как они предлагают отличную производительность. Карты microSD с высокой износостойкостью также являются отличным вариантом — они достаточно быстрые и обеспечивают превосходную долговечность на основе нашего опыта. Карта объёмом 32 ГБ более чем достаточна для этой настройки.

ДОПОЛНИТЕЛЬНО:

Активная система охлаждения для предотвращения перегрева, особенно в жаркие летние дни. Мы рекомендуем EP-0163 Ice Tower для эффективного охлаждения. Модуль часов реального времени (RTC), такой как RV3028, полезен для поддержания точной синхронизации времени, особенно когда Raspberry Pi остаётся выключенным или отключённым от сети в течение длительного времени. Он аккуратно размещается рядом с EP-0163 Ice Tower.

УСТАНОВКА RASPBERRY PI OS (настройка без монитора)

1. Скачайте и установите Raspberry Pi Imager

  • Скачайте официальный Raspberry Pi Imager и установите Raspberry Pi OS Lite (64-бит), основанную на Debian Bookworm.

2. Включите SSH и настройте сеть

  • Мы рекомендуем настройку без подключения периферийных устройств (headless), то есть вам не потребуются внешний монитор, мышь или клавиатура. Вместо этого вы можете выполнить всю настройку со своего компьютера.
  • Преимущество такой настройки в том, что она пропускает Мастер приветствия и позволяет удалённо подключиться к Raspberry Pi сразу после первого запуска.
  • Для этого убедитесь, что вы настроили имя пользователя, пароль и параметры сети в разделе настройки ОС в Raspberry Pi Imager. В этом руководстве мы используем Имя пользователя: term7. Если вы выберете другое имя пользователя, не забудьте заменить его везде, где оно встречается в этом руководстве.
  • Если вы не знаете, как настроить Raspberry Pi в первый раз, следуйте нашему подробному руководству по headless-установке: Руководство по настройке Raspberry Pi OS без монитора

3. Обновите систему

  • После установки обновите Raspberry Pi OS, как описано в приведённом выше руководстве. Дополнительные шаги из этого руководства выполнять не нужно.

4. Дополнительные настройки

Однако, если вам интересно, вы можете ознакомиться с: Настройки Z-Ram: эти оптимизации могут улучшить производительность системы, особенно на устройствах с небольшим объёмом оперативной памяти.
Настройки MOTD: настройка сообщения дня (MOTD) может улучшить опыт входа в систему, отображая полезную информацию о системе. Обе настройки не обязательны, но могут быть полезны.
ОТКЛЮЧЕНИЕ СВЕТОДИОДОВ: отключите все светодиоды, и ваш Raspberry Pi будет работать полностью в тёмном режиме, без каких-либо индикаторов состояния.
Пропустите разделы по управлению доступом пользователей, защите SSH и настройке межсетевого экрана. Эти вопросы будут полностью освещены в данном руководстве!

РАСШИРЕНИЕ ФАЙЛОВОЙ СИСТЕМЫ И ВКЛЮЧЕНИЕ ПРЕДСКАЗУЕМЫХ ИМЁН ИНТЕРФЕЙСОВ

Чтобы настроить Raspberry Pi, откройте инструмент настройки Raspberry Pi, выполнив:

sudo raspi-config

1. Расширение файловой системы

  • Перейдите в 6. Дополнительные параметры → A1 Расширить файловую систему.
  • Это гарантирует, что весь объём вашей SD-карты будет доступен.

2. Включение предсказуемых имён сетевых интерфейсов

  • Перейдите в 6. Дополнительные параметры → A2 Имена сетевых интерфейсов.
  • Включите предсказуемые имена сетевых интерфейсов. Это критически важно для данного руководства!

Мы работаем со встроенным Wi-Fi (wlan0) и внешним Wi-Fi-адаптером (wlx00c0caae6319), что является предсказуемым именем интерфейса для ALFA AWUS036ACM. Включив предсказуемые имена сетевых интерфейсов, мы можем надёжно различать встроенный и внешний Wi-Fi-адаптеры. Без этой настройки внешняя Wi-Fi-карта может иногда получать имя wlan0 вместо встроенного Wi-Fi, что может вызвать проблемы с настройками межсетевого экрана и маршрутизации.


04 КОНТРОЛЬ ДОСТУПА ПОЛЬЗОВАТЕЛЕЙ

Мы создаём отдельные учётные записи администратора и стандартного пользователя, следуя лучшим практикам безопасности, чтобы ограничить привилегии и снизить риски. Учётная запись администратора (admin) предназначена для обслуживания и настройки системы, а учётная запись стандартного пользователя (term7) используется для повседневных задач с минимальными правами.

Следуя принципу минимальных привилегий (PoLP), мы повышаем безопасность и минимизируем потенциальные векторы атак: эта настройка позволяет отключить вход от имени root через SSH, добавляя дополнительный уровень защиты. Даже если злоумышленник получит доступ, у него не будет прав администратора по умолчанию, что значительно снижает риск компрометации системы.

1. СОЗДАНИЕ НОВОГО ПОЛЬЗОВАТЕЛЯ-АДМИНИСТРАТОРА:

Чтобы создать выделенную учётную запись администратора, выполните следующую команду:

sudo adduser admin

Единственная обязательная деталь — надёжный пароль. Мы настоятельно рекомендуем использовать менеджер паролей, например KeePassXC, для безопасного хранения и управления вашими учётными данными.

Если вы предпочитаете сгенерировать надёжный пароль прямо из командной строки, используйте:

openssl rand -base64 48 | cut -c1-32

Эта команда генерирует 32-символьный случайный пароль с помощью генератора случайных чисел OpenSSL, который соответствует стандартам NIST SP 800-90A/B/C и использует ChaCha20 (или AES-CTR в более старых версиях), обеспечивая криптографическую стойкость. Результат непредсказуем и устойчив к атакам грубой силы.

После создания пользователя-администратора добавьте его во все необходимые группы, чтобы он имел доступ к требуемым функциям системы:

sudo usermod -a -G adm,tty,dialout,cdrom,audio,video,plugdev,games,users,input,netdev,gpio,i2c,spi,sudo,term7 admin

2. УДАЛЕНИЕ ПРАВ SUDO У СТАНДАРТНОГО ПОЛЬЗОВАТЕЛЯ:

Чтобы повысить безопасность, удалите права sudo у пользователя term7 и передайте их пользователю admin, при этом убедившись, что sudo теперь требует ввода пароля:

sudo sed -i 's/term7/admin/g' /etc/sudoers.d/010_pi-nopasswd
sudo sed -i 's/NOPASSWD: //g' /etc/sudoers.d/010_pi-nopasswd

Чтобы повысить безопасность, удалим стандартного пользователя (в этом примере — term7) из группы sudo, чтобы у него больше не было административных привилегий. Сначала войдите в систему под новым учётной записью администратора:

su admin

Теперь выполните следующую команду, чтобы удалить term7 из группы sudo (замените term7 на ваше фактическое имя стандартного пользователя):

sudo deluser term7 sudo

РАЗРЕШИТЕ СТАНДАРТНОМУ ПОЛЬЗОВАТЕЛЮ ВЫКЛЮЧАТЬ И ПЕРЕЗАГРУЖАТЬ ВАШ RASPBERRY PI:

Хотя у term7 больше нет полного доступа sudo, мы хотим разрешить ему перезагружать и выключать Raspberry Pi без переключения на администратора. Выполните следующую команду, чтобы создать новый файл политики sudo:

echo "term7 ALL = NOPASSWD: /usr/sbin/reboot, /usr/sbin/shutdown" | sudo tee /etc/sudoers.d/common_users > /dev/null

Это предоставляет term7 доступ без пароля к командам перезагрузки и выключения. Если вы хотите разрешить дополнительные команды без требования sudo, просто отредактируйте файл: /etc/sudoers.d/common_users


05 УСИЛЕНИЕ КОНФИГУРАЦИИ SSH

По умолчанию вы всё ещё можете подключаться по SSH напрямую к учётной записи администратора, что является риском для безопасности. Чтобы усилить безопасность SSH, мы изменим его конфигурацию.

Усиление порта - Изменение стандартного порта SSH (на порт 6666)

Сильные криптографические алгоритмы: - Шифры для надёжного шифрования (chacha20-poly1305, aes256-gcm) - Безопасный обмен ключами (curve25519-sha256, diffie-hellman-group16-sha512) - MAC для защиты от криптографических уязвимостей (hmac-sha2-512-etm)

Строгий контроль аутентификации - Отключение прямого входа под root - Ограничение доступа по SSH для определённых пользователей (term7) - Ограничение попыток аутентификации и сессий (MaxAuthTries 2, MaxSessions 2) - Принудительная аутентификация по SSH-ключу - Отключение входа по паролю - Отключение аутентификации с запросом-ответом (предотвращает атаки перебора)

Усиление сессий - Контроль времени ожидания и бездействия (ClientAliveInterval 300, ClientAliveCountMax 2) - Запрет входа с пустым паролем

Расширенное ведение журнала и мониторинг - Ведение журнала: фиксация неудачных попыток аутентификации, IP-адресов и подозрительных действий - Включение предупреждающего баннера

Подготовка: настройка аутентификации по SSH-ключу для безопасного доступа

Аутентификация по SSH-ключу безопаснее, чем аутентификация по паролю. Она использует пару криптографических ключей:

Закрытый ключ → Хранится в безопасности на вашем Mac.
Открытый ключ → Копируется на ваш Raspberry Pi.

После настройки только ваш Mac сможет подключаться к Raspberry Pi — если только ваш закрытый ключ не скомпрометирован.

1. Создание новой пары SSH-ключей на вашем Mac

Откройте Terminal на вашем Mac и выполните:

ssh-keygen -t ed25519 -C "your_email@example.com"

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

Расширенная безопасность
Для ещё более надёжной настройки рассмотрите возможность использования аппаратного ключа безопасности, например Nitrokey или YubiKey. Однако для них требуется дополнительная настройка, что выходит за рамки этого руководства. Возможно, мы рассмотрим их в отдельном руководстве в будущем.

2. Копирование открытого ключа на ваш Raspberry Pi

Выполните эту команду, заменив 192.168.1.123 на фактический локальный IP-адрес вашего Raspberry Pi:

ssh-copy-id -i ~/.ssh/id_ed25519.pub term7@192.168.1.123

Если ssh-copy-id не установлен в macOS, скопируйте ключ вручную с помощью:

cat ~/.ssh/id_ed25519.pub | ssh term7@192.168.1.123 'mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys'

3. Настройка SSH на вашем Mac для удобного доступа

Всё ещё на вашем Mac, отредактируйте файл конфигурации SSH:

nano ~/.ssh/config

Убедитесь, что эта строка присутствует: IdentityFile ~/.ssh/id_ed25519

Это гарантирует, что ваш Mac всегда будет использовать правильный закрытый ключ (id_ed25519) для аутентификации и предотвратит запрос пароля SSH, если аутентификация по ключу настроена правильно.

4. Повторный вход в учётную запись стандартного пользователя Raspberry Pi

После настройки аутентификации по SSH-ключу необходимо установить правильные разрешения для каталога .ssh и файла authorized_keys, чтобы SSH работал безопасно:

ssh term7@192.168.1.123

Замените 192.168.1.123 на фактический IP-адрес вашего Raspberry Pi!

5. Установка правильных разрешений для каталога и файлов SSH

В учётной записи стандартного пользователя выполните следующие команды на вашем Raspberry Pi:

chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

Это гарантирует, что только пользователь (term7) имеет доступ к каталогу .ssh и что только пользователь может читать и записывать файл authorized_keys.

6. Настройка предупреждающего баннера

Теперь войдите в учётную запись администратора:

su admin

Чтобы отображать предупреждающий баннер безопасности перед входом, скачайте и замените файл /etc/issue.net нашей предварительно настроенной версией из репозитория:

sudo curl -L -o /etc/issue.net "https://codeberg.org/term7/Going-Dark/raw/branch/main/Pi%20Configuration%20Files/ssh/issue.net"

Вы можете отредактировать текст баннера в соответствии с вашими требованиями:

sudo nano /etc/issue.net

7. Упрочнение конфигурации SSH

Самый быстрый способ упрочнить конфигурацию SSH — заменить её нашим предварительно настроенным файлом из этого репозитория.

Однако перед внесением изменений создайте резервную копию, чтобы не остаться без доступа в случае ошибки. Выполните эту команду для создания резервной копии:

sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak

Если что-то пойдёт не так, вы сможете восстановить исходный файл. Чтобы загрузить нашу упрочнённую конфигурацию, выполните команду:

sudo curl -L -o /etc/ssh/sshd_config "https://codeberg.org/term7/Going-Dark/raw/branch/main/Pi%20Configuration%20Files/ssh/sshd_config"

Это перезапишет ваш текущий стандартный файл конфигурации SSH. ВАЖНО: если вы используете стандартное имя пользователя, отличное от term7, вам нужно обновить эту строку: AllowUsers term7

Чтобы проверить и отредактировать файл перед применением изменений, откройте его в Nano:

sudo nano /etc/ssh/sshd_config

Найдите и замените term7 на ваше фактическое имя пользователя, затем сохраните (CTRL + X, затем Y, затем Enter).

8. Применение и тестирование новой конфигурации SSH

После внесения необходимых изменений перезапустите службу SSH:

sudo systemctl restart ssh

НЕ выходите из системы! На вашем Mac откройте новое окно терминала и проверьте доступ по SSH:

ssh term7@192.168.1.123 -p 6666

Не забудьте заменить 192.168.1.123 на фактический IP-адрес вашего Raspberry Pi!

Если подключение работает нормально, ваша новая упрочнённая конфигурация SSH успешно применена!
Поскольку вы всё ещё вошли в систему в исходном окне терминала, вы сможете устранить любые проблемы, если что-то не работает.

9. Восстановление после сбоя (при необходимости)

Если что-то пойдёт не так и вы останетесь без доступа, восстановите резервную копию. Получите доступ к вашему Raspberry Pi локально (используйте клавиатуру и монитор). Затем введите следующие команды:

sudo cp /etc/ssh/sshd_config.bak /etc/ssh/sshd_config
sudo systemctl restart ssh

Это восстановит вашу предыдущую рабочую конфигурацию SSH.


06 АВТОМАТИЧЕСКИЕ ОБНОВЛЕНИЯ

Поддержание вашего Raspberry Pi в актуальном состоянии критически важно для безопасности и стабильности. Вместо ручного обновления мы настраиваем автоматические обновления для установки обновлений безопасности и системы. Поскольку наш Raspberry Pi включается только когда мы работаем на Mac, нам нужно убедиться, что обновления запускаются после каждой перезагрузки. Кроме того, так как мы установим AdGuardHome (которому требуется время для применения списков фильтров), мы вводим задержку в 2 минуты перед началом процесса обновления.

1. Установка необходимых пакетов:

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

sudo apt install -y unattended-upgrades apt-listchanges

2. Включение обновлений Raspberry Pi OS:

По умолчанию обновления безопасности Debian включены. Однако нам нужно вручную добавить обновления Raspberry Pi. Выполните эту команду, чтобы изменить файл 50unattended-upgrades:

sudo sed -i '/"origin=Debian,codename=${distro_codename}-security,label=Debian-Security";/a\
        "origin=Raspbian,codename=${distro_codename},label=Raspbian";\
        "origin=Raspberry Pi Foundation,codename=${distro_codename},label=Raspberry Pi Foundation";' /etc/apt/apt.conf.d/50unattended-upgrades

Также разрешите автоматическое обновление пакетов из репозитория Debian:

sudo sed -i 's|^//\s*\("origin=Debian,codename=\${distro_codename}-updates"\);|\1;|' /etc/apt/apt.conf.d/50unattended-upgrades

Автоматическое удаление ненужных зависимостей:

sudo sed -i 's|^//\s*Unattended-Upgrade::Remove-Unused-Dependencies\s*"false";|Unattended-Upgrade::Remove-Unused-Dependencies "true";|' /etc/apt/apt.conf.d/50unattended-upgrades

3. Обеспечение выполнения обновлений после каждой перезагрузки:

Создайте таймер systemd, который будет ждать 2 минуты после загрузки перед запуском обновлений:

echo '[Unit]
Description=Unattended Upgrades Timer

[Timer]
OnBootSec=2min
Unit=unattended-upgrades.service

[Install]
WantedBy=multi-user.target' | sudo tee /etc/systemd/system/unattended-upgrades.timer > /dev/null

Это предотвращает слишком ранний запуск обновлений, пока AdGuardHome ещё инициализируется.
Теперь создайте службу systemd, которая будет выполнять автоматические обновления:

echo '[Unit]
Description=Unattended Upgrades
After=network.target

[Service]
Type=oneshot
ExecStart=/usr/bin/unattended-upgrade -d

[Install]
WantedBy=multi-user.target' | sudo tee /etc/systemd/system/unattended-upgrades.service > /dev/null

4. Активация и запуск таймера

Чтобы активировать таймер и службу systemd, выполните:

sudo systemctl daemon-reload
sudo systemctl enable unattended-upgrades.timer
sudo systemctl start unattended-upgrades.timer

После перезагрузки проверьте, активен ли таймер:

systemctl list-timers --all | grep unattended-upgrades

Если вы видите запись, таймер работает.

Чтобы проверить, были ли применены обновления, просмотрите журналы автоматических обновлений:

journalctl -u unattended-upgrades --no-pager

07 ОТКЛЮЧЕНИЕ IPv6

Хотя IPv6 предлагает преимущества, использование как IPv4, так и IPv6 (двойной стек) значительно усложняет настройку межсетевого экрана и увеличивает риски безопасности.

Почему отключать IPv6?

  • Большая площадь для атак → И IPv4, и IPv6 требуют отдельных правил межсетевого экрана, что увеличивает сложность и риск неправильной настройки.
  • Риски отслеживания → IPv6 может встраивать MAC-адрес устройства в свой IP (формат EUI-64), что позволяет злоумышленникам и рекламодателям отслеживать перемещения устройств между сетями.
  • Проблемы конфиденциальности → Без расширений конфиденциальности IPv6 адреса остаются статическими, что снижает анонимность по сравнению с динамическими адресами IPv4.

Поскольку нам не нужен IPv6, мы полностью отключим его, чтобы улучшить безопасность и упростить сетевые настройки.

1. Отключение IPv6 на уровне системы:

Навсегда отключите IPv6, изменив файл /etc/sysctl.conf:

echo -e "\n# Disable IPv6:\nnet.ipv6.conf.all.disable_ipv6 = 1\nnet.ipv6.conf.default.disable_ipv6 = 1\nnet.ipv6.conf.lo.disable_ipv6 = 1" | sudo tee -a /etc/sysctl.conf > /dev/null

Измените параметры загрузки в файле /boot/firmware/cmdline.txt, чтобы предотвратить загрузку IPv6 при старте:

sudo sed -i 's/$/ ipv6.disable=1/' /boot/firmware/cmdline.txt

Чтобы изменения вступили в силу, перезагрузите систему:

sudo reboot now

2. Удаление записей IPv6 из /etc/hosts:

Так как IPv6 теперь отключён, удалите все локальные IPv6-адреса из /etc/hosts, чтобы предотвратить ненужные попытки разрешения:

sudo sed -i '/::/d' /etc/hosts

08 СЛУЧАЙНЫЙ MAC-АДРЕС

По умолчанию современная Raspberry Pi OS использует NetworkManager для управления сетевыми интерфейсами, DHCP и настройками Wi-Fi. Чтобы улучшить конфиденциальность и снизить риск отслеживания, мы включим встроенную функцию рандомизации MAC-адресов в NetworkManager.

1. Включение рандомизации MAC-адреса:

Создайте файл конфигурации, чтобы включить случайные MAC-адреса для Wi-Fi и Ethernet:

echo '[device]
wifi.scan-rand-mac-address=yes

[connection]
wifi.cloned-mac-address=random
ethernet.cloned-mac-address=random
connection.stable-id=${CONNECTION}/${BOOT}' | sudo tee /etc/NetworkManager/conf.d/00-randomize.conf > /dev/null

2. Проверка рандомизации MAC-адреса:

Чтобы убедиться, что MAC-адрес изменяется динамически, выполните:

sudo nmcli device show | grep GENERAL.HWADDR

Теперь перезагрузите Raspberry Pi:

sudo reboot now

После перезагрузки системы войдите в Raspberry Pi (ещё раз проверьте, какой IP-адрес был назначен — скорее всего, он изменится после смены MAC-адреса!) и снова выполните следующую команду:

sudo nmcli device show | grep GENERAL.HWADDR

Если MAC-адрес отличается от предыдущего вывода, настройка рандомизации работает корректно.

⚠️ ВАЖНО: Побочный эффект рандомизации MAC-адреса заключается в том, что ваш маршрутизатор может назначить другой IP-адрес вашему Raspberry Pi. Если вы используете SSH, возможно, потребуется проверить новый IP-адрес Raspberry Pi и обновить подключение SSH соответственно.


09 СЛУЧАЙНОЕ ИМЯ УСТРОЙСТВА (HOSTNAME)

Многие сети фиксируют имена устройств (hostname) вместе с MAC-адресами и IP-адресами. Если имя устройства остаётся статичным, это создаёт уникальный отпечаток, который можно использовать для отслеживания устройства в разных сетях. Это означает, что даже если рандомизация MAC-адреса включена, фиксированное имя устройства всё равно может использоваться для его идентификации. Поэтому мы используем английский словарь, чтобы выбирать случайное слово для Raspberry Pi при каждой перезагрузке до подключения к сети.

1. Подготовка папок и загрузка словаря

Сначала создадим папки для хранения скриптов и словаря:

[ -d ~/tools ] || mkdir ~/tools && [ -d ~/tools/dict ] || mkdir ~/tools/dict
[ -d ~/script ] || mkdir ~/script && [ -d ~/script/randhost ] || mkdir ~/script/randhost

Скачайте и распакуйте английский словарь UK:

curl -L https://codeberg.org/term7/Going-Dark/raw/branch/main/misc/Dictionary/ukenglish.zip -o ~/tools/dict/ukenglish.zip && unzip -o ~/tools/dict/ukenglish.zip -d ~/tools/dict/ && rm ~/tools/dict/ukenglish.zip

2. Создание скрипта для рандомизации имени устройства

Создайте скрипт для рандомизации имени устройства:

echo '#!/bin/bash

# Random Hostname Generator
ALL_NON_RANDOM_WORDS=/home/admin/tools/dict/ukenglish.txt

# Count the number of words in the dictionary
non_random_words=$(wc -l < "$ALL_NON_RANDOM_WORDS")

# Generate a random index and select a word
WORD_INDEX=$(od -N3 -An -i /dev/urandom | awk -v r="$non_random_words" "{print int(1 + r * \$1 / 16777216)}")
NEW_HOSTNAME=$(sed -n "${WORD_INDEX}p" "$ALL_NON_RANDOM_WORDS")

# Change Static Hostname
hostnamectl set-hostname "$NEW_HOSTNAME"


# Update /etc/hosts safely
sed -i "/127.0.1.1/c\127.0.1.1       $NEW_HOSTNAME" /etc/hosts' | sudo tee /home/admin/script/randhost/hostname.sh > /dev/null

Убедитесь, что у скрипта правильные владельцы и права доступа:

sudo chmod 700 /home/admin/script/randhost/hostname.sh
sudo chown root:root /home/admin/script/randhost/hostname.sh

3. Создание системной службы для запуска скрипта при загрузке

echo '[Unit]
Description=Random Hostname Generator
Wants=network-pre.target
After=network-pre.target

[Service]
Type=oneshot
ExecStart=/usr/bin/bash /home/admin/script/randhost/hostname.sh
RemainAfterExit=yes
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target' | sudo tee /etc/systemd/system/hostname.service > /dev/null

4. Включение и запуск службы, проверка нового имени устройства

Включите службу:

sudo systemctl daemon-reload
sudo systemctl enable hostname.service

5. Тестирование службы

Вручную запустите службу:

sudo systemctl start hostname.service

Проверьте текущее имя устройства:

hostname

Если вы видите другое имя устройства, чем раньше, настройка работает корректно. Теперь ваш Raspberry Pi будет случайным образом выбирать новое имя устройства из словаря при каждой перезагрузке.


10 НАСТРОЙКА USB-C ETHERNET ГАДЖЕТА

В этом разделе мы настроим ваш Raspberry Pi как USB-C Ethernet гаджет, что позволит ему делиться интернет-подключением с компьютером через USB.

Чтобы настроить Raspberry Pi как USB-C Ethernet гаджет, необходимо:

  • Включить контроллер DWC2 USB и настроить параметры загрузки ядра.
  • Разрешить NetworkManager управлять USB-интерфейсом (usb0).
  • Настроить usb0 с статическим IP и отключить IPv6.
  • Включить IPv4-форвардинг для общего доступа к сети.

1. Включение контроллера DWC2 USB

Чтобы включить режим гаджета Ethernet, нужно активировать контроллер DWC2 USB и настроить параметры загрузки ядра. Добавьте необходимый оверлей в /boot/firmware/config.txt:

sudo sed -i '$a\dtoverlay=dwc2,dr_mode=peripheral' /boot/firmware/config.txt

Измените /boot/firmware/cmdline.txt, чтобы загрузить необходимые модули ядра:

sudo sed -i 's/$/ rootwait modules-load=dwc2,g_ether quiet/' /boot/firmware/cmdline.txt

2. Разрешение NetworkManager управлять usb0

По умолчанию NetworkManager может игнорировать интерфейс гаджета (usb0). Нам нужно изменить правила udev, чтобы разрешить это. Сначала скопируйте и измените необходимые правила udev:

sudo cp /usr/lib/udev/rules.d/85-nm-unmanaged.rules /etc/udev/rules.d/85-nm-unmanaged.rules

Затем обновите правило, чтобы NetworkManager управлял usb0:

sudo sed -i '/ENV{DEVTYPE}=="gadget"/s/ENV{NM_UNMANAGED}="1"/ENV{NM_UNMANAGED}="0"/' /etc/udev/rules.d/85-nm-unmanaged.rules

3. Настройка usb0 как статического интерфейса в NetworkManager

Мы назначим статический IP (192.168.77.1/24) интерфейсу usb0 и включим общий доступ к сети.
Создайте и настройте интерфейс:

sudo nmcli con add type ethernet ifname usb0 con-name usb0-static
sudo nmcli con modify usb0-static ipv4.addresses 192.168.77.1/24 ipv4.method shared
sudo nmcli con modify usb0-static connection.autoconnect yes connection.autoconnect-priority 50

Так как IPv6 отключён глобально, отключите его и для этого интерфейса:

sudo nmcli connection modify usb0-static ipv6.method disable

Обеспечьте стабильный MAC-адрес для usb0 — единственного интерфейса, для которого мы не хотим рандомизации MAC:

sudo nmcli connection modify usb0-static ethernet.cloned-mac-address permanent

4. Включение IPv4-форвардинга

Чтобы разрешить общий доступ к интернету с Raspberry Pi через Wi-Fi на подключённый компьютер, включите пересылку IPv4. Измените файл /etc/sysctl.conf:

sudo sed -i 's/^#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/' /etc/sysctl.conf

Это позволяет пересылку пакетов, давая Raspberry Pi возможность предоставлять доступ к интернету через usb0.

5. Примените изменения и перезагрузитесь

Чтобы все изменения вступили в силу, перезагрузите Raspberry Pi:

sudo reboot now

6. Проверьте доступ к интернету через USB-C Ethernet-гаджет Raspberry Pi

После перезагрузки ваш Raspberry Pi должен работать как USB-C Ethernet-гаджет через USB.

Подключитесь к Raspberry Pi, используя статический IP-адрес, назначенный интерфейсу usb0:

ssh term7@192.168.77.1 -p 6666

Проверьте подключение на вашем компьютере: перейдите в Настройки системы → Сеть и найдите RNDIS/Ethernet-гаджет. Вы должны увидеть зелёную точку с статусом: Подключено.

Поскольку ваш Raspberry Pi подключён к интернету через домашний маршрутизатор, ваш компьютер теперь должен получать доступ к интернету через Raspberry Pi. Отключите Wi-Fi на вашем Mac и проверьте, остаётся ли интернет-соединение.


11 НАСТРОЙКА БЕСПРОВОДНОЙ ТОЧКИ ДОСТУПА

В этой настройке мы хотим сконфигурировать wlan0 как беспроводную точку доступа, которую можно запускать вручную, а не запускать постоянно. Это даёт больший контроль над доступностью сети и помогает оптимизировать производительность системы.

Поскольку мы не хотим использовать wlan0 для доступа к интернету, мы настроим наш внешний Wi-Fi-адаптер — ALFA AWUS036ACM — для обработки интернет-соединения.

Почему использовать внешний Wi-Fi-адаптер?

ALFA AWUS036ACM обеспечивает значительно более высокую пропускную способность по сравнению со встроенным Wi-Fi Raspberry Pi (wlan0), особенно при подключении к порту USB 3.0. Использование внешнего адаптера гарантирует более высокую скорость и улучшенную стабильность, что делает его предпочтительным выбором для подключения к интернету.

Поскольку мы включили предсказуемые имена сетевых интерфейсов (см. 03 - ПРЕДВАРИТЕЛЬНЫЕ УСЛОВИЯ), наш внешний Wi-Fi-адаптер получает имя интерфейса: wlx00c0caae6319

⚠️ Важно: Если вы используете другой внешний Wi-Fi-адаптер, его имя интерфейса будет другим. Вам следует заменить wlx00c0caae6319 на фактическое имя вашего интерфейса во всём этом руководстве, во всех файлах конфигурации межсетевого экрана и любых сетевых командах или настройках.

1. Проверьте ваш внешний Wi-Fi-адаптер:

Перед продолжением убедитесь, что ваш внешний Wi-Fi-адаптер подключён и правильно соединён с Raspberry Pi. Чтобы узнать имя интерфейса ваших Wi-Fi-адаптеров, выполните следующую команду:

nmcli device status

Найдите ваш внешний Wi-Fi-адаптер в выводе. Обычно у него будет имя, начинающееся с wlx или wlan. Если вы не уверены, какой из них ваш внешний адаптер, сравните его со встроенным Wi-Fi (wlan0). У внешнего будет другое имя.

2. Переименуйте предварительно настроенные внешние подключения и отключите IPv6:

Чтобы стандартизировать имена подключений, выполните:

sudo nmcli con modify preconfigured connection.id "Wi-Fi"
sudo nmcli con modify "Wired connection 1" connection.id "Ethernet"

Отключите IPv6 для обоих подключений:

sudo nmcli connection modify Ethernet ipv6.method disable
sudo nmcli connection modify Wi-Fi ipv6.method disable

3. Настройте внешний Wi-Fi-адаптер (wlx00c0caae6319) для доступа к интернету:

Измените Wi-Fi-подключение для использования внешнего адаптера:

sudo nmcli con down Wi-Fi
sudo nmcli con modify Wi-Fi ifname wlx00c0caae6319

⚠️ Предупреждение: Используйте фактическое предсказуемое имя интерфейса вашего собственного Wi-Fi-адаптера!

Запустите внешнее Wi-Fi-подключение:

sudo nmcli con up Wi-Fi

Теперь ваш внешний Wi-Fi-адаптер должен обрабатывать интернет-соединение вместо wlan0.

4. Создайте точку доступа wlan0:

Добавьте новое подключение точки доступа (SSID: ONION):

sudo nmcli con add con-name Hotspot ifname wlan0 type wifi ssid "ONION"

Настройте точку доступа как точку доступа с общим доступом к сети:

sudo nmcli con modify Hotspot 802-11-wireless.mode ap 802-11-wireless.band bg ipv4.method shared
sudo nmcli con modify Hotspot ipv4.addresses 192.168.37.1/24

Настройте защиту Wi-Fi для точки доступа:

sudo nmcli con modify Hotspot wifi-sec.key-mgmt wpa-psk
sudo nmcli con modify Hotspot wifi-sec.proto rsn
sudo nmcli con modify Hotspot wifi-sec.pairwise ccmp
sudo nmcli con modify Hotspot wifi-sec.group ccmp
sudo nmcli con modify Hotspot wifi-sec.auth-alg open
sudo nmcli con modify Hotspot wifi-sec.pmf optional
sudo nmcli con modify Hotspot wifi-sec.psk "your-own-strong-wifi-password"

Отключите IPv6 для точки доступа:

sudo nmcli connection modify Hotspot ipv6.method disable

Запретите автоматическое подключение при запуске:

sudo nmcli connection modify Hotspot connection.autoconnect no

Точка доступа теперь настроена, но будет запускаться только при ручном включении.

5. ТЕСТ: Подключите ваши устройства к точке доступа:

Чтобы запустить точку доступа:

sudo nmcli con up Hotspot

Чтобы остановить точку доступа:

sudo nmcli con down Hotspot

Ваш Raspberry Pi теперь работает как управляемая вручную беспроводная точка доступа.
После запуска точки доступа вы можете подключить свой смартфон или другие устройства, используя:

  • SSID: ONION
  • Пароль: "your-own-strong-wifi-password"

12 НАСТРОЙКА NTP

По умолчанию Raspberry Pi синхронизирует время с помощью серверов NTP из пула Debian. Однако мы хотим настроить локальный NTP-сервер на Raspberry Pi, чтобы обеспечивать синхронизацию времени для подключённых клиентов. Кроме того, мы настроим наше устройство на использование внешних NTP-серверов, уважающих конфиденциальность, из проекта NTP Pool Project, чтобы гарантировать точную и безопасную синхронизацию времени. Таким образом, наш Mac будет синхронизировать время через Raspberry Pi, а не обращаться к time.apple.com, что дополнительно ограничивает способность Apple отслеживать наше устройство по запросам синхронизации времени.

Подробнее: Проект NTP Pool

1. Установка NTP:

Сначала установите пакет NTP. Это автоматически удалит systemd-timesyncd — стандартную службу синхронизации времени на Raspberry Pi:

sudo apt install -y ntp

2. Загрузка и применение конфигурации NTP:

Чтобы упростить настройку, загрузите предварительно настроенный файл конфигурации NTP из нашего репозитория:

sudo curl -L -o /etc/ntpsec/ntp.conf "https://codeberg.org/term7/Going-Dark/raw/branch/main/Pi%20Configuration%20Files/ntp/ntp.conf"

Эта конфигурация:
- Настраивает Raspberry Pi как NTP-сервер для клиентов локальной сети. - Использует несколько внешних серверов времени для отказоустойчивости. - Предотвращает серьезные проблемы с синхронизацией времени после длительных периодов отключения от сети.

3. Возможные проблемы:

Если Raspberry Pi остаётся отключённым от сети в течение длительного времени, его внутренние часы могут значительно отставать или спешить. Наши текущие настройки предотвращают отказ NTP от использования собственных локальных часов после длительного простоя. Без этих настроек большое расхождение во времени могло бы привести к невозможности подключения Raspberry Pi к интернету.
Если Raspberry Pi теряет доступ к интернету, он продолжит предоставлять время локальным клиентам на основе последней успешной синхронизации. Однако со временем могут накапливаться ошибки дрейфа часов, что потенциально повлияет на подключение к интернету и безопасные соединения (например, сертификаты TLS/SSL могут стать недействительными из-за неверного системного времени). Чтобы смягчить эту проблему, мы настоятельно рекомендуем установить модуль часов реального времени (RTC), который отслеживает время даже при отключении питания устройства.

Хотя локальным клиентам разрешено синхронизироваться с Raspberry Pi, они могут по-прежнему отдавать предпочтение внешним NTP-серверам, таким как Apple, Google или Microsoft. Чтобы гарантировать, что все сетевые устройства используют Raspberry Pi для синхронизации времени, позже мы настроим NetworkManager на использование встроенного dnsmasq в качестве DHCP-сервера. Эта настройка передаёт параметры NTP Raspberry Pi всем DHCP-клиентам, обеспечивая их автоматическую синхронизацию времени с Raspberry Pi. Это должно устранить необходимость ручной настройки на каждом устройстве.

Однако, если вы хотите настроить Mac на использование Raspberry Pi в качестве NTP-сервера, откройте новое окно терминала на Mac и временно отключите автоматическую настройку времени:

sudo systemsetup -setusingnetworktime off

Примечание: Эта команда может выдать ошибку ‘Error:-99’ из-за защиты целостности системы Apple (SIP). Однако, несмотря на эту ошибку, наши тесты показали, что настройка всё равно применяется корректно.

Следующая команда — это небольшой хак, так как Apple не документирует поддержку нескольких строк в этой команде. Официально systemsetup -setnetworktimeserver принимает только одну строку. Однако, несмотря на отсутствие документации, этот метод не вызывает ошибок и корректно форматирует файл конфигурации в нашем опыте. Мы хотим настроить Проект NTP Pool в качестве резервных серверов на случай, если Ethernet-гаджет Raspberry Pi недоступен:

sudo systemsetup -setnetworktimeserver "192.168.77.1
server 0.pool.ntp.org
server 1.pool.ntp.org
server 2.pool.ntp.org
server 3.pool.ntp.org"

Если вы предпочитаете избегать этого недокументированного метода, вы можете вручную ввести несколько серверов времени в Настройки системы > Дата и время. Разделяйте каждую запись запятой и заканчивайте точкой, например: 192.168.77.1, 0.pool.ntp.org, 1.pool.ntp.org, 2.pool.ntp.org, 3.pool.ntp.org

Если вы хотите синхронизировать время только через Raspberry Pi и соблюдать корректный синтаксис, документированный Apple, используйте вместо этого команду:

sudo systemsetup -setnetworktimeserver "192.168.77.1"

В конце снова включите автоматическую настройку времени:

sudo systemsetup -setusingnetworktime off

Проверьте, включена ли автоматическая настройка времени:

sudo systemsetup -getusingnetworktime

Чтобы проверить, использует ли macOS правильные настройки, выполните:

sudo systemsetup -getnetworktimeserver

Однако эта команда возвращает только первый сервер из списка!

4. Необязательно — Установка модуля RTC для надёжного отслеживания времени в автономном режиме:


В этом руководстве мы настроим модуль RTC RV3028. Если вы используете другой модуль RTC, следуйте соответствующим инструкциям по установке. Убедитесь, что вы подключены к вашему Raspberry Pi по SSH и вошли в систему под учётной записью admin.

Установите необходимые пакеты:

sudo apt install -y git python3-smbus

Создайте каталог сборки и перейдите в него:

[ -d ~/build ] || mkdir ~/build && cd ~/build

Клонируйте и установите библиотеку RV3028 для Python:

git clone https://github.com/pimoroni/rv3028-python
cd rv3028-python
sudo ./install.sh --unstable

Переместите примеры скриптов в отдельную папку:

sudo mv ~/Pimoroni/* ~/build/rv3028-python/examples
sudo rm -R /home/admin/Pimoroni

Включите связь по I2C:

sudo sed -i 's/^#dtparam=i2c_arm=on/dtparam=i2c_arm=on/' /boot/firmware/config.txt

Кроме того, чтобы активировать RTC RV3028, нужно загрузить правильный оверлей ядра. Выполните следующую команду, чтобы добавить необходимый оверлей в /boot/firmware/config.txt:

sudo sed -i '0,/^\[all\]/s//&\ndtoverlay=i2c-rtc,rv3028,backup-switchover-mode=1/' /boot/firmware/config.txt

Перезагрузите Raspberry Pi, чтобы изменения вступили в силу:

sudo reboot now

По умолчанию Raspberry Pi использует программные часы, имитирующие аппаратные. Поскольку у нас теперь есть реальный модуль RTC, удалите программные часы, чтобы избежать конфликтов:

sudo apt -y remove fake-hwclock
sudo update-rc.d -f fake-hwclock remove

Наконец, настройте NTP (ntpsec) для получения времени с модуля RTC:

sudo sed -i 's/^#rtcfile \/dev\/rtc0/rtcfile \/dev\/rtc0/' /etc/ntpsec/ntp.conf

Перезапустите NTP, чтобы применить изменения:

sudo systemctl restart ntpsec

13 ПОДГОТОВКА DNSMASQ

⚠ ВАЖНО: Выполнение глав 13–19 шаг за шагом в правильном порядке имеет критическое значение! Любая ошибка в конфигурации может вызвать проблемы с DNS, что приведёт к потере подключения к интернету для вашего Raspberry Pi и подключённых к нему клиентов — или даже полностью заблокирует доступ. Даже небольшие ошибки или пропущенные шаги могут привести к тому, что некоторые аспекты настройки не будут работать должным образом. Действуйте осторожно и точно следуйте каждому шагу.

В этом разделе мы настроим встроенный в NetworkManager Dnsmasq для управления службами DHCP и DNS.

Наши цели:

  • Перенаправлять все DNS-запросы с порта 53 на порт 5357, где их будет обрабатывать AdGuardHome.
  • Назначать DHCP-аренды устройствам, подключающимся через usb0 (Ethernet Gadget) и wlan0 (точка доступа Wi-Fi).
  • Обеспечить передачу клиентами своих имен хостов для улучшения ведения журнала в AdGuardHome.
  • Назначить статический IP-адрес нашему Mac (РАБОЧАЯ СТАНЦИЯ), чтобы AdGuardHome всегда его идентифицировал.
  • Рекламировать наш локальный NTP-сервер всем подключённым клиентам для синхронизации времени.

Правильно настроив Dnsmasq, мы создадим безопасную, конфиденциальную и надёжную локальную систему DNS и DHCP, обеспечивающую стабильную работу и беспрепятственную идентификацию устройств.

1. Настройка NetworkManager:

Чтобы правильно управлять DHCP и DNS с помощью NetworkManager, сначала нужно настроить его общие параметры, а затем настроить Dnsmasq для стандартных и общих сетевых интерфейсов.

Выполните следующую команду, чтобы создать и обновить /etc/NetworkManager/NetworkManager.conf:

echo '[main]
plugins=ifupdown,keyfile
dns=dnsmasq
dhcp=dnsmasq

[ifupdown]
managed=false' | sudo tee /etc/NetworkManager/NetworkManager.conf > /dev/null

Это гарантирует, что NetworkManager будет использовать Dnsmasq для DHCP и DNS.

2. Настройка Dnsmasq:

NetworkManager использует две разные папки конфигурации для Dnsmasq:

  • Стандартные интерфейсы (/etc/NetworkManager/dnsmasq.d/) → используется для lo (localhost).
  • Общие интерфейсы (/etc/NetworkManager/dnsmasq-shared.d/) → используется для общих сетей, таких как wlan0 и usb0.

Нам нужно настроить обе.

Создайте следующий файл конфигурации, чтобы все DNS-запросы перенаправлялись в AdGuardHome и применялись функции безопасности:

echo '# Redirect DNS to Adguard (localhost)
proxy-dnssec
server=127.0.0.1#5357
no-resolv
edns-packet-max=1232

# Prevent DNS leaks and block Bogus Private IP Responses
domain-needed
bogus-priv

# Prevent DNS rebinding attacks
stop-dns-rebind

# Prevent External Access to Local DNS
local-service

# Ensure Hostnames Resolve Properly
expand-hosts' | sudo tee /etc/NetworkManager/dnsmasq.d/00_dnsmasq-adguard.conf > /dev/null

Создайте файл конфигурации для общих интерфейсов, чтобы перенаправлять DNS-запросы в AdGuardHome и включить EDNS Client Subnet (ECS):

echo '# Redirect DNS to Adguard
proxy-dnssec
server=127.0.0.1#5357
no-resolv

# Enable EDNS Client Subnet (ECS) to pass client details
add-mac
add-subnet=32,128
edns-packet-max=1232

# Prevent DNS leaks and block Bogus Private IP Responses
domain-needed
bogus-priv

# Prevent DNS rebinding attacks
stop-dns-rebind

# Prevent External Access to Local DNS
local-service

# Ensure Hostnames Resolve Properly
expand-hosts' | sudo tee /etc/NetworkManager/dnsmasq-shared.d/00_dnsmasq-shared_adguard.conf > /dev/null

Настройте параметры DHCP для usb0 (Ethernet Gadget) и wlan0 (точка доступа Wi-Fi):

echo '########################################
# DHCP/DNS for usb0 -> ONlY ONE CLIENT #
########################################

# Assign static IP to WORKSTATION:
dhcp-host=WORKSTATION,192.168.77.77

# DHCP range:
dhcp-range=set:usb0,192.168.77.10,192.168.77.255,255.255.255.0,24h

# Default Gateway:
dhcp-option=tag:usb0,3,192.168.77.1

# DNS server:
dhcp-option=tag:usb0,6,192.168.77.1

# NTP server:
dhcp-option=tag:usb0,option:ntp-server,192.168.77.1

# Request hostnames:
dhcp-option=tag:usb0,12

############################################
# DHCP/DNS for wlan0 -> REQUEST  HOSTNAMES #
############################################

# DHCP range:
dhcp-range=set:wlan0,192.168.37.10,192.168.37.250,255.255.255.0,24h

# Default Gateway:
dhcp-option=tag:wlan0,3,192.168.37.1

# DNS server:
dhcp-option=tag:wlan0,6,192.168.37.1

# NTP server:
dhcp-option=tag:wlan0,option:ntp-server,192.168.37.1

# Request hostnames:
dhcp-option=tag:wlan0,12' | sudo tee /etc/NetworkManager/dnsmasq-shared.d/01_usb0-wlan0.conf > /dev/null

ВАЖНО: Эти изменения вступят в силу только после перезапуска NetworkManager. Однако, поскольку вы подключены по SSH, перезапуск NetworkManager прервёт ваше соединение. Единственный способ применить эти изменения без потери доступа — полная перезагрузка системы.

⚠ НЕ перезагружайте Raspberry Pi на этом этапе!

AdGuardHome и Unbound ещё не настроены, и нет правил брандмауэра для обеспечения правильной маршрутизации сети. Перезагрузка сейчас может нарушить подключение. Продолжайте выполнение оставшихся шагов настройки перед перезапуском.**

3. РАБОЧАЯ СТАНЦИЯ как имя хоста для вашего Mac:


Чтобы ваш Mac отображался как уникальный клиент в AdGuardHome, необходимо назначить ему статический IP-адрес (см. конфигурацию выше). Однако, так как на вашем Mac включена рандомизация MAC-адресов, его MAC-адрес не может служить надёжным идентификатором. Вместо этого мы зададим фиксированное имя хоста — WORKSTATION, что позволит стабильно назначать нужный статический IP. Откройте терминал на вашем Mac и выполните следующие команды для настройки имени хоста:

sudo scutil --set HostName WORKSTATION
sudo scutil --set LocalHostName WORKSTATION
sudo scutil --set ComputerName WORKSTATION
dscacheutil -flushcache

4. ИСПРАВЛЕНИЕ: Очистка аренд USB0

Когда включена рандомизация MAC-адресов, Dnsmasq может назначить другой IP-адрес после перезагрузки, так как видит новый MAC-адрес. Чтобы AdGuardHome стабильно распознавал WORKSTATION с правильным статическим IP, необходимо очищать файл /var/lib/NetworkManager/dnsmasq-usb0.leases перед запуском NetworkManager.

Войдите на свой Raspberry Pi под пользователем admin и подготовьте место для хранения скрипта:

[ -d ~/script ] || mkdir ~/script && [ -d ~/script/DNS ] || mkdir ~/script/DNS

Далее создайте скрипт очистки:

echo '#!/bin/bash
> /var/lib/NetworkManager/dnsmasq-usb0.leases' | sudo tee ~/script/DNS/clear-usb0-leases.sh > /dev/null

Сделайте скрипт исполняемым:

sudo chmod +x ~/script/DNS/clear-usb0-leases.sh

Создайте службу systemd, которая будет запускать этот скрипт перед стартом NetworkManager:

echo '[Unit]
Description=Clear dnsmasq leases for usb0
After=local-fs.target
Before=NetworkManager.service

[Service]
Type=oneshot
ExecStart=/home/admin/script/DNS/clear-usb0-leases.sh

[Install]
WantedBy=multi-user.target' | sudo tee /etc/systemd/system/clear-dnsmasq-leases.service > /dev/null

Перезагрузите systemd и активируйте службу, чтобы она запускалась при каждом выключении:

sudo systemctl daemon-reload
sudo systemctl enable clear-dnsmasq-leases.service

Теперь при каждом запуске Raspberry Pi файл dnsmasq-usb0.leases будет очищаться перед тем, как NetworkManager начнёт работу. Это гарантирует, что dnsmasq назначит правильный статический IP вашему WORKSTATION, даже если рандомизация MAC включена.


14 ПОДГОТОВКА UNBOUND

⚠ ВАЖНО: Выполнение глав 13–19 шаг за шагом в правильном порядке критически важно! Любая ошибка в конфигурации может вызвать проблемы с DNS, что приведёт к потере доступа к интернету для вашего Raspberry Pi и подключённых к нему клиентов — или даже полностью заблокирует вас. Даже небольшие ошибки или пропущенные шаги могут привести к тому, что некоторые аспекты настройки не будут работать как ожидалось. Действуйте осторожно и следуйте каждому шагу точно.

Unbound — это валидирующий (DNSSEC) и рекурсивный DNS-сервер, который кэширует запросы для повышения эффективности. Позже мы настроим AdGuardHome так, чтобы он использовал Unbound в качестве единственного вышестоящего DNS-сервера. Основная проблема традиционных DNS-резолверов — это доверие. При использовании стороннего DNS-провайдера мы должны доверять тому, что он не записывает, не анализирует и не продаёт данные наших DNS-запросов. Развёртывая Unbound, мы устраняем эту зависимость и получаем следующие преимущества:

КОНФИДЕНЦИАЛЬНОСТЬ: Unbound выполняет полное рекурсивное разрешение, то есть начинает процесс поиска DNS с корневых серверов имён и следует по иерархии, пока не достигнет авторитетного сервера имён, ответственного за запрашиваемый домен. Это устраняет зависимость от централизованного DNS-посредника, который мог бы фиксировать или анализировать наши запросы.

СКОРОСТЬ: AdGuardHome уже включает встроенный кэш DNS, но в сочетании с расширенными функциями кэширования Unbound — такими как aggressive-nsec, prefetch и serve-expired — время отклика на запросы ещё больше сокращается, а общая производительность улучшается.

НЕДОСТАТОК: Отсутствие шифрования

Один из основных минусов отказа от DNS-посредника — отсутствие шифрования. Запросы к корневым серверам имён и авторитетным DNS-серверам отправляются в открытом виде по UDP/TCP на порт 53, что делает их уязвимыми для перехвата и анализа.
Чтобы снизить этот риск, можно зашифровать DNS-запросы с помощью DNS-over-TLS (DoT). Однако в описанной здесь настройке мы не будем использовать этот вариант, так как корневые серверы имён (пока) не поддерживают DoT или DoH (DNS-over-HTTPS).
Это означает, что если мы выбираем отказ от сторонних DNS-резолверов, то должны также отказаться от шифрования. В то же время DNSSEC (включённый в Unbound) всё же обеспечивает преимущества в области безопасности, гарантируя, что DNS-ответы являются аутентичными (поступают от легитимного DNS-сервера) и не изменены (обеспечивается целостность данных). Хотя это не шифрует запросы, но предотвращает DNS-спуфинг и атаки «человек посередине», проверяя легитимность ответов.

В итоге цепочка DNS-запросов будет работать так:

Dnsmasq: порт 53 → AdGuardHome: порт 5357 → Unbound: порт 7353:

+----------------------+        +----------------------+        +-------------------+

|     User Device      |  DNS   |  NetworkManager DNS  |  DNS   |    AdGuardHome    |
| (Any App or Browser) | -----> |     dnsmasq: 53      | -----> |  Filtering: 5357  |
+----------------------+        +----------------------+        +-------------------+

                                                                      |
                                                                      | DNS
                                                                      v
                                                       +----------------------------+

                                                       |         Unbound            |
                                                       |  Recursive Resolver: 7353  |
                                                       |  - DNSSEC Validation       |
                                                       |  - Root-to-Auth Resolution |
                                                       |  - Caching Enabled         |
                                                       +----------------------------+

Это схема обработки DNS-запросов в Unbound — в этом примере клиент хочет посетить term7.info:

   +-------------------+                     +------------------------+

   |                   |                     |                        |
   |  Client: Browser  | ------------------->|   https://term7.info   |
   |                   |                     |                        |
   +-------------------+                     +------------------------+
             ^

            ||
term7.info? || IP: 89.147.108.191

            ||
            v
   +------------------+                                        +------------+ 

   |   AdGuardHome    |                          /------------>|    Root    |
   |  Filter + Cache  |                         //------------ |   Server   |
   +------------------+                .info?  //              +------------+ 
             ^                                //

            ||                               //
term7.info? || IP: 89.147.108.191           // .info!

            ||                             //
            v                             //
   +-------------------+  ---------------//       

   |      Unbound      | <---------------/    term7.info?      +--------------------------+ 
   |                   |  ------------------------------------>|        TLD Server        |
   | Recursive Caching | <------------------------------------ | Top Level Domain:  .info |
   |  Resolver DNSSEC  |  ---------------\    term7.info!      +--------------------------+
   +-------------------+ <---------------\\
                                          \\
                                           \\
                                            \\ term7.info -> IP? 
                                             \\
                          IP: 89.147.108.191  \\
                                               \\              +-------------------------------+
                                                \\------------>|   Authoritative Name Server   |
                                                 \------------ |           term7.info          |
                                                               +-------------------------------+

1. Установка Unbound:

sudo apt install -y unbound unbound-anchor

Наша конфигурация Unbound предназначена для рекурсивного DNS-резолвера с акцентом на конфиденциальность и высокую производительность, с поддержкой валидации DNSSEC, улучшенным кэшированием и усилением безопасности. Скачайте наш предварительно настроенный файл конфигурации Unbound из нашего репозитория:

2. Основная конфигурация Unbound:

sudo curl -L -o /etc/unbound/unbound.conf.d/unbound-dnssec.conf "https://codeberg.org/term7/Going-Dark/raw/branch/main/Pi%20Configuration%20Files/unbound/unbound-dnssec.conf"

Функции конфиденциальности и безопасности:

  • Исключает зависимость от внешних DNS-провайдеров, выполняя полное рекурсивное разрешение (запросы начинаются с корневых серверов).
  • Предотвращает утечки DNS, блокируя запросы для локальных/частных IP-адресов.
  • Улучшает валидацию DNSSEC для обеспечения подлинности DNS-ответов.
  • Защищает от DNS-спуфинга и атак перехвата.
  • Ограничивает передачу данных запросов вышестоящим серверам с помощью минимизации QNAME.
  • Блокирует запросы метаданных, чтобы скрыть детали сервера.
  • Реализует ограничение скорости для предотвращения злоупотреблений.

Улучшения производительности:

  • Агрессивное кэширование с длинными значениями TTL.
  • Включено опережающее кэширование для ускорения повторных запросов.
  • Оптимизированное использование потоков и памяти.
  • Минимизирует размеры DNS-ответов для снижения сетевой нагрузки.

3. Локальная конфигурация Unbound:

Теперь создадим второй файл конфигурации для определения локальных зон и включения обратных запросов для wlan0 и usb0, что позволит разрешать локальные имена хостов в нашей сети:

echo 'server:
    # Serve static local websites:
    local-zone: "adguard.home." static
    local-data: "adguard.home. IN A 192.168.77.1"

    #PTR Record for localhost
    local-data-ptr: "127.0.0.1 localhost"

    # Allow reverse lookups for wlan0 (192.168.37.x)
    local-zone: "37.168.192.in-addr.arpa." transparent
    local-data-ptr: "192.168.37.1 hotspot.local"

    # Allow reverse lookups for usb0 (192.168.77.x)
    local-zone: "77.168.192.in-addr.arpa." transparent
    local-data-ptr: "192.168.77.1 usb0.local"

######### CUSTOM RULES TO REACH LAN NETWORK #########

    # Use LAN DNS for private domain "lan."
    # Adjust "lan" to your private lan domain
    private-domain: "lan"
    private-address: 192.168.0.0/16
    domain-insecure: "lan."

    # EXAMPLE: Local override for the router hostname
    # Uncomment and adjust "router.lan" to match your setup
    # local-zone: "lan." transparent
    # local-data: "router.lan. IN A 192.168.1.1"

forward-zone:
    name: "1.168.192.in-addr.arpa."
    forward-addr: 192.168.1.1

#####################################################
# Allow Unbound to read hostnames from DHCP leases
auth-zone:
    name: "37.168.192.in-addr.arpa."
    zonefile: "/var/lib/unbound/unbound-wlan0.zone"
        fallback-enabled: yes

auth-zone:
    name: "77.168.192.in-addr.arpa."
    zonefile: "/var/lib/unbound/unbound-usb0.zone"
    fallback-enabled: yes' | sudo tee /etc/unbound/unbound.conf.d/local-zones.conf > /dev/null

Эта конфигурация особенно полезна по следующим причинам:

AdGuardHome сможет регистрировать имена хостов клиентов (если они предоставлены клиентом). Это позволяет видеть, какой клиент подключается к какому домену в журнале запросов.
Далее в этом руководстве мы настроим обратный прокси Nginx для обслуживания веб-интерфейса AdGuardHome. Наличие локального разрешения имен хостов гарантирует, что веб-интерфейс может надежно доступ через локальное доменное имя вместо IP-адреса.

4. Преобразование DHCP-аренд Dnsmasq в зонный файл Unbound:

Эта настройка не работает «из коробки» из-за двух ключевых проблем: Dnsmasq генерирует зонный файл, несовместимый с синтаксисом Unbound. Чтобы решить это, нам нужен скрипт, который преобразует файл аренды в формат, читаемый Unbound.
Кроме того, Dnsmasq должен запускать этот скрипт каждый раз, когда подключается новый клиент. Это обеспечивает автоматическое обновление зонного файла Unbound, сохраняя актуальность разрешения имен хостов.

Создайте скрипт, который преобразует файл аренды NetworkManager в формат, совместимый с Unbound:

sudo tee /home/admin/script/DNS/update-unbound-leases.sh > /dev/null << 'EOF'
#!/bin/bash

# Loop through each interface (wlan0 and usb0)
for iface in wlan0 usb0; do
    # Define lease file and corresponding Unbound zone file paths for the interface
    LEASE_FILE="/var/lib/NetworkManager/dnsmasq-${iface}.leases"
    UNBOUND_ZONE_FILE="/var/lib/unbound/unbound-${iface}.zone"

    # If the lease file doesn't exist or is empty, create a placeholder zone file
    if [[ ! -s "$LEASE_FILE" ]]; then
        echo "; Unbound generated zone file - No active leases found" > "$UNBOUND_ZONE_FILE"
        continue
    fi

    # Initialize a new Unbound zone file with a header comment
    echo "; Unbound generated zone file from dnsmasq leases" > "$UNBOUND_ZONE_FILE"

    # Process each lease entry in the lease file
    while read -r LEASE_TIME MAC_ADDR IP HOSTNAME CLIENTID; do
        # Skip the entry if the IP address is missing
        if [[ -z "$IP" ]]; then
            continue
        fi

        # Set hostname to 'UNKNOWN' if it's missing or a placeholder '*'
        if [[ -z "$HOSTNAME" || "$HOSTNAME" == "*" ]]; then
            HOSTNAME="UNKNOWN"
        fi

        # Convert the IP address into PTR record format (reverse order)
        PTR_IP=$(echo "$IP" | awk -F. '{print $4"."$3"."$2"."$1}')
        # Append the PTR record to the Unbound zone file
        echo "$PTR_IP.in-addr.arpa. 86400 IN PTR $HOSTNAME." >> "$UNBOUND_ZONE_FILE"
    done < "$LEASE_FILE"
done

# Reload Unbound to apply the updated zone files
systemctl reload unbound
EOF

Сделайте этот скрипт исполняемым:

sudo chmod +x ~/script/DNS/update-unbound-leases.sh

Настройте Dnsmasq на автоматический запуск скрипта при подключении клиента:

echo "" | sudo tee -a /etc/NetworkManager/dnsmasq-shared.d/00_dnsmasq-shared_adguard.conf > /dev/null
echo "# Script to reconfigure Unbound zonefile for PTR requests" | sudo tee -a /etc/NetworkManager/dnsmasq-shared.d/00_dnsmasq-shared_adguard.conf > /dev/null
echo "dhcp-script=/home/admin/script/DNS/update-unbound-leases.sh" | sudo tee -a /etc/NetworkManager/dnsmasq-shared.d/00_dnsmasq-shared_adguard.conf > /dev/null

5. Принудительное использование локального DNS и обновление файла hosts:

Чтобы все DNS-запросы направлялись через AdGuardHome и Unbound, нужно настроить NetworkManager на использование нашего локального резолвера:

sudo nmcli con modify Wi-Fi ipv4.dns 127.0.0.1
sudo nmcli con modify Ethernet ipv4.dns 127.0.0.1

6. ИСПРАВЛЕНИЕ: Автоматическое восстановление конфигурации Unbound при перезагрузке:

Далее в этом руководстве мы настроим VPN WIREGUARD и ПРОЗРАЧНЫЙ ПРОКСИ TOR. Каждый из этих режимов требует динамических изменений в конфигурации DNS Unbound.

Однако в редких случаях — например, если ваш Raspberry Pi аварийно завершает работу или вы забыли корректно отключить WireGuard или Tor — система может перезагрузиться с некорректной конфигурацией Unbound. Это может привести к потере подключения к интернету при запуске.

Чтобы предотвратить это, мы создадим простой скрипт и сервис systemd, который будет автоматически восстанавливать стандартные настройки Unbound при каждой загрузке Raspberry Pi.

Создайте новый скрипт, который сбрасывает Unbound к стандартной конфигурации с поддержкой DNSSEC:

sudo tee /home/admin/script/DNS/restore-unbound-config.sh << 'EOF'
#!/bin/bash

# Config Files
UNBOUND_MAIN_CONFIG="/etc/unbound/unbound.conf.d/unbound-dnssec.conf"
UNBOUND_CONFIG="/etc/unbound/unbound.conf.d/local-zones.conf"

# Restore Unbound main configuration
sed -i 's/do-not-query-localhost: no/do-not-query-localhost: yes/' "$UNBOUND_MAIN_CONFIG"
sed -i 's/val-permissive-mode: yes/val-permissive-mode: no/' "$UNBOUND_MAIN_CONFIG"

# Remove TorProxy or WireGuard DNS Config and add fallback setting
sed -i '/fallback-enabled: yes/,$d' "$UNBOUND_CONFIG"
echo "        fallback-enabled: yes" >> "$UNBOUND_CONFIG"
EOF

Сделайте скрипт исполняемым:

sudo chmod +x ~/script/DNS/restore-unbound-config.sh

Теперь создайте новый модуль сервиса для запуска скрипта перед стартом Unbound:

echo '[Unit]
Description=Restore Unbound configuration before Unbound starts
After=network.target
Before=unbound.service

[Service]
Type=oneshot
ExecStart=/home/admin/script/DNS/restore-unbound-config.sh

[Install]
WantedBy=multi-user.target' | sudo tee /etc/systemd/system/restore-unbound-config.service > /dev/null

Перезагрузите systemd и включите сервис, чтобы он запускался при каждой загрузке:

sudo systemctl daemon-reload
sudo systemctl enable restore-unbound-config.service

Отныне ваш Raspberry Pi будет автоматически восстанавливать корректную конфигурацию Unbound при запуске — обеспечивая подключение к интернету, даже если система ранее завершила работу неожиданно или с активным неправильным сетевым режимом.


15 ПОДГОТОВКА ADGUARDHOME


⚠ ВАЖНО: Выполнение глав 13–19 шаг за шагом в правильном порядке критически важно! Любая ошибка в конфигурации может вызвать проблемы с DNS, что приведёт к потере доступа к интернету для вашего Raspberry Pi и подключённых к нему клиентов — или даже полностью заблокирует вас. Даже небольшие ошибки или пропущенные шаги могут привести к тому, что некоторые аспекты настройки не будут работать должным образом. Действуйте осторожно и точно следуйте каждому шагу.

Теперь мы установим AdGuardHome — мощный DNS-фильтр, который блокирует рекламу, трекинговые домены и вредоносные сайты. Он улучшает конфиденциальность и безопасность для всех подключённых устройств, блокируя нежелательный контент на уровне DNS.

1. Установка AdGuardHome:

Перед установкой AdGuardHome убедитесь, что каталог сборки существует, и перейдите в него:

[ -d ~/build ] || mkdir ~/build && cd ~/build

Выполните следующую команду, чтобы загрузить и извлечь последнюю версию AdGuardHome:

curl -sSL https://github.com/AdguardTeam/AdGuardHome/releases/latest/download/AdGuardHome_linux_arm64.tar.gz | tar -xz

Затем перейдите в извлечённый каталог и запустите установку:

cd AdGuardHome && sudo ./AdGuardHome -s install

Примечание: Настройку AdGuardHome мы выполним позже в руководстве. На этом этапе установка только подготавливает систему.


16 СЕРТИФИКАТ SSL

⚠ ВАЖНО: Выполнение глав 13–19 шаг за шагом в правильном порядке критически важно! Любая ошибка в конфигурации может вызвать проблемы с DNS, что приведёт к потере доступа к интернету для вашего Raspberry Pi и подключённых к нему клиентов — или даже полностью заблокирует вас. Даже небольшие ошибки или пропущенные шаги могут привести к тому, что некоторые аспекты настройки не будут работать должным образом. Действуйте осторожно и точно следуйте каждому шагу.

В предыдущих главах мы настроили встроенный в NetworkManager Dnsmasq, включили обратные запросы через Unbound и установили AdGuardHome. Теперь нужно настроить шифрование с помощью самоподписанного сертификата, который будет использоваться NGINX для обслуживания adguard.home по HTTPS.
Цель — получить доступ к веб-интерфейсу AdGuardHome по локальному адресу: https://adguard.home
Кроме того, этот сертификат позволит AdGuardHome поддерживать зашифрованные DNS-запросы через DNS-over-HTTPS (DoH) в качестве резервного метода наряду с нашей конфигурацией Unbound.

1. Проверка наличия необходимых каталогов:

Выполните следующую команду, чтобы убедиться в наличии необходимых каталогов:

mkdir -p ~/tools/CA/SSL ~/script/SSL

2. Создание самоподписанного центра сертификации (CA):

Перейдите в каталог конфигурации Центра сертификации (CA):

cd ~/tools/CA

Создайте самоподписанный ключ и сертификат Центра сертификации (CA) (срок действия 10 лет, совместимый с Apple):

openssl req -x509 -new -nodes \
  -newkey rsa:2048 \
  -keyout term7-CA.key \
  -out term7-CA.pem \
  -days 3650 \
  -subj "/CN=term7-CA" \
  -addext "basicConstraints=critical,CA:true,pathlen:0" \
  -addext "keyUsage=critical,keyCertSign,cRLSign"

Убедитесь, что файлы принадлежат пользователю root и имеют правильные права доступа:

sudo chown root:root term7-CA.key term7-CA.pem term7-CA.srl
sudo chmod 600 term7-CA.key
sudo chmod 644 term7-CA.pem term7-CA.srl

3. Генерация SSL-сертификатов для adguard.home:

Перейдите в каталог конфигурации SSL:

cd ~/tools/CA/SSL

Создайте файл конфигурации OpenSSL для adguard.home:

echo '[ req ]
default_bits       = 2048
default_md         = sha256
prompt             = no
distinguished_name = req_distinguished_name
req_extensions     = v3_req

[ req_distinguished_name ]
CN = adguard.home

[ v3_req ]
subjectAltName = @alt_names
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth

[ alt_names ]
DNS.1 = adguard.home
IP.1 = 192.168.77.1' | sudo tee /home/admin/tools/CA/SSL/openssl-adguardhome.cnf > /dev/null

Теперь сгенерируйте закрытый ключ для adguard.home:

openssl genrsa -out adguard.home.key 2048

Создайте запрос на подпись сертификата (CSR):

openssl req -new -key adguard.home.key -out adguard.home.csr -config openssl-adguardhome.cnf

Подпишите запрос на подпись сертификата (CSR) с помощью Локального центра сертификации (CA):

sudo openssl x509 -req -in adguard.home.csr -CA ../term7-CA.pem -CAkey ../term7-CA.key -CAcreateserial -out adguard.home.crt -days 90 -extensions v3_req -extfile openssl-adguardhome.cnf

Создайте сертификат с полной цепочкой:

cat adguard.home.crt ../term7-CA.pem > adguard.home-fullchain.crt

4. Доверьте центр сертификации на вашем Raspberry Pi

Скопируйте сертификат CA в каталог доверенных сертификатов системы:

sudo cp ~/tools/CA/term7-CA.pem /usr/local/share/ca-certificates/term7-CA.crt

Обновите хранилище сертификатов системы:

sudo update-ca-certificates

5. Передача сертификата на ваш Mac

Поскольку мы применили строгий контроль доступа пользователей, вход от имени root запрещён. Чтобы передать сертификат на Mac, сначала скопируем его в учётную запись обычного пользователя:

sudo cp ~/tools/CA/term7-CA.pem /home/term7/

Теперь на вашем Mac откройте новое окно терминала и выполните следующую команду, чтобы безопасно скопировать сертификат в папку «Загрузки». После завершения передачи сразу удалите его из учётной записи обычного пользователя Raspberry Pi:

scp -P 8519 term7@192.168.77.1:term7-CA.pem ~/Downloads/ && ssh -p 8519 term7@192.168.77.1 "rm term7-CA.pem"

6. Установка и доверие сертификата в macOS

Выполните следующую команду, чтобы добавить сертификат в системное хранилище ключей macOS и отметить его как доверенный для всех пользователей:

sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain ~/Downloads/term7-CA.pem

Это гарантирует, что сертификат будет распознаваться как корневой центр сертификации, что позволит вам получить доступ к https://adguard.home без предупреждений о безопасности.

Если вы когда-нибудь захотите удалить этот сертификат, выполните:

sudo security delete-certificate -c "term7-CA" /Library/Keychains/System.keychain

7. Автоматическое обновление сертификата на вашем Raspberry Pi

Создайте скрипт обновления (он будет запускаться только если срок действия сертификата истекает в течение 30 дней):

sudo tee /home/admin/script/SSL/renew-cert.sh > /dev/null <<'EOF'
#!/bin/bash
set -euo pipefail
umask 077

# Where to store the log (overwrite on each run)
LOG_FILE="/home/admin/script/SSL/renewal.log"
mkdir -p "$(dirname "$LOG_FILE")"
: > "$LOG_FILE"

# ----- Timestamp every log line -----
if command -v ts >/dev/null 2>&1; then
  exec > >(ts "[%Y-%m-%d %H:%M:%S]" >> "$LOG_FILE") 2>&1
else
  exec > >(awk '{ print strftime("[%Y-%m-%d %H:%M:%S]"), $0; fflush(); }' >> "$LOG_FILE") 2>&1
fi

# ----- Config -----
CA_DIR="/home/admin/tools/CA"
SSL_DIR="$CA_DIR/SSL"
CA_CERT="$CA_DIR/term7-CA.pem"
CA_KEY="$CA_DIR/term7-CA.key"
CA_SERIAL="$CA_DIR/term7-CA.srl"
DAYS=825
DOMAINS=("adguard.home")
RESTART_SERVICES=("nginx" "AdGuardHome")

# --- Renewal loop ---
for DOMAIN in "${DOMAINS[@]}"; do
  CNF_FILE="$SSL_DIR/openssl-${DOMAIN//./}.cnf"
  CRT_FILE="$SSL_DIR/$DOMAIN.crt"
  KEY_FILE="$SSL_DIR/$DOMAIN.key"
  CSR_FILE="$SSL_DIR/$DOMAIN.csr"
  FULLCHAIN="$SSL_DIR/$DOMAIN-fullchain.crt"

  if [ ! -f "$CRT_FILE" ]; then
    DAYS_LEFT=0
  else
    ENDLINE="$(openssl x509 -enddate -noout -in "$CRT_FILE" 2>/dev/null || true)"
    if [[ "$ENDLINE" =~ ^notAfter= ]]; then
      EXPIRY_RAW="${ENDLINE#notAfter=}"
      EXPIRY_EPOCH=$(date -d "$EXPIRY_RAW" +%s)
      NOW_EPOCH=$(date +%s)
      SECS_LEFT=$(( EXPIRY_EPOCH - NOW_EPOCH ))
      DAYS_LEFT=$(( SECS_LEFT > 0 ? SECS_LEFT / 86400 : 0 ))
    else
      DAYS_LEFT=0
    fi
  fi

  if [ "$DAYS_LEFT" -gt 30 ]; then
    echo "$DOMAIN: certificate expiring in $DAYS_LEFT days — not renewing."
    continue
  else
    echo "$DOMAIN: certificate expiring in $DAYS_LEFT days — renewing..."
  fi

  openssl req -new -key "$KEY_FILE" -out "$CSR_FILE" -config "$CNF_FILE"
  openssl x509 -req \
    -in "$CSR_FILE" \
    -CA "$CA_CERT" -CAkey "$CA_KEY" \
    -CAserial "$CA_SERIAL" -CAcreateserial \
    -out "$CRT_FILE" \
    -days "$DAYS" \
    -extensions v3_req -extfile "$CNF_FILE"

  cat "$CRT_FILE" "$CA_CERT" > "$FULLCHAIN"

  NEW_END="$(openssl x509 -in "$CRT_FILE" -noout -enddate | sed 's/^notAfter=//')"
  echo "$DOMAIN: new certificate expires on $NEW_END"
done

# --- Restart services ---
for svc in "${RESTART_SERVICES[@]}"; do
  if systemctl is-enabled "$svc" >/dev/null 2>&1 || systemctl is-active "$svc" >/dev/null 2>&1; then
    sudo systemctl restart "$svc"
  fi
done
EOF

Сделайте скрипт исполняемым:

sudo chmod +x /home/admin/script/SSL/renew-cert.sh

В конце создайте задачу cron, которая запускает скрипт при каждой перезагрузке:

( sudo crontab -l 2>/dev/null | grep -v 'renew-cert.sh' ; \
  echo '@reboot /home/admin/script/SSL/renew-cert.sh' \
) | sudo crontab -

17 НАСТРОЙКА NGINX КАК ОБРАТНОГО ПРОКСИ

⚠ ВАЖНО: Выполнение глав 13–19 шаг за шагом в правильном порядке критически важно! Любая ошибка в конфигурации может вызвать проблемы с DNS, что приведёт к потере доступа к интернету для вашего Raspberry Pi и подключённых к нему клиентов — или даже полностью заблокирует вас. Даже небольшие ошибки или пропущенные шаги могут привести к тому, что некоторые аспекты настройки не будут работать как ожидается. Действуйте осторожно и точно следуйте каждому шагу.

В этом разделе мы настроим NGINX как обратный прокси для веб-интерфейса AdGuardHome. Это позволит нам безопасно предоставлять интерфейс, а также добавить дополнительные опции кастомизации.

1. Установка NGINX:

Сначала установите NGINX — современный и лёгкий веб-сервер:

sudo apt install -y nginx

По умолчанию NGINX настроен на прослушивание IPv6, но ранее мы отключили IPv6 на этой системе, поэтому служба nginx.service не сможет запуститься. Чтобы предотвратить это, нужно изменить файл конфигурации по умолчанию и отключить поддержку IPv6:

sudo sed -i 's/^\(\s*listen \[::\]:80 default_server;\)/# \1/' /etc/nginx/sites-available/default

2. Настройка NGINX как обратного прокси для AdGuardHome:

Теперь настроим NGINX для работы в качестве обратного прокси для веб-интерфейса AdGuardHome, а также для передачи запросов DNS-over-HTTPS (DoH) между подключёнными клиентами и AdGuardHome.
Выполните следующую команду, чтобы создать конфигурацию:

echo 'server {
    listen 192.168.77.1:443 ssl http2;

    server_name adguard.home;

    ssl_certificate /home/admin/tools/CA/SSL/adguard.home.crt;
    ssl_certificate_key /home/admin/tools/CA/SSL/adguard.home.key;

    # Proxy AdGuardHome Web Interface
    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    # Proxy DNS-over-HTTPS (DoH) Requests to AdGuardHome
    location /dns-query {
        proxy_pass https://127.0.0.1:7443/dns-query$is_args$args;
        proxy_ssl_server_name on;
        proxy_ssl_verify off;

        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        # Preserve query strings
        proxy_redirect off;
    }
}

server {
    listen 192.168.77.1:80;
    server_name adguard.home;

    # Redirect HTTP to HTTPS
    return 301 https://$host$request_uri;
}' | sudo tee /etc/nginx/sites-available/nginx-adguard > /dev/null

3. Активация конфигурации NGINX:

Чтобы активировать созданную конфигурацию NGINX:

sudo ln -s /etc/nginx/sites-available/nginx-adguard /etc/nginx/sites-enabled/

4. Проверка и перезапуск NGINX:

Перед перезапуском NGINX проверьте конфигурацию на наличие синтаксических ошибок:

sudo nginx -t

Если проверка прошла успешно, перезапустите NGINX:

sudo systemctl restart nginx

5. Обеспечение локального разрешения имени хоста:

Чтобы разрешить локальное разрешение имени adguard.home, выполните эту команду на вашем Mac и на Raspberry Pi:

grep -q '192\.168\.77\.1[[:space:]]\+adguard\.home' /etc/hosts || echo '192.168.77.1    adguard.home' | sudo tee -a /etc/hosts > /dev/null

⚠️ ВАЖНО: На этом этапе необходимые службы настроены, но брандмауэр ещё не настроен. Без правил брандмауэра маршрутизация не будет работать как ожидается, и ваша настройка может не функционировать корректно. Следующий раздел проведёт вас через настройку брандмауэра. Завершите этот раздел перед перезагрузкой Raspberry Pi.


18 БРАНДМАУЭР

⚠ ВАЖНО: Выполнение глав 13–19 шаг за шагом в правильном порядке критически важно! Любая ошибка в конфигурации может вызвать проблемы с DNS, что приведёт к потере доступа к интернету для вашего Raspberry Pi и подключённых к нему клиентов — или даже полностью заблокирует вас. Даже небольшие ошибки или пропущенные шаги могут привести к тому, что некоторые аспекты настройки не будут работать как ожидается. Действуйте осторожно и точно следуйте каждому шагу.

В этом разделе мы настроим nftables — современное приложение брандмауэра, которое установлено по умолчанию на вашем Raspberry Pi. Наше решение для брандмауэра разработано для максимальной безопасности, предотвращения несанкционированного доступа и обеспечения корректной работы только необходимых служб, защищая при этом подключённые устройства.

Чтобы избежать ошибок при ручной настройке, загрузите предварительно настроенную конфигурацию брандмауэра из репозитория:

sudo curl -L -o /etc/nftables.conf "https://codeberg.org/term7/Going-Dark/raw/branch/main/Pi%20 Configuration%20Files/nftables/nftables.conf"

Наш брандмауэр включает несколько механизмов безопасности для блокировки атак, обеспечения сегментации сети и предотвращения несанкционированного доступа:

1. Защита от несанкционированного доступа

  • Блокирует весь входящий трафик по умолчанию: разрешен только явно разрешённый трафик.
  • Ограничивает доступ по SSH: разрешает SSH (порт 6666) только из частной сети (usb0 и wlan0) и ограничивает количество попыток подключения по SSH до 3 в минуту, чтобы предотвратить атаки методом перебора.

2. Защита от сканирования сети и DDoS-атак

  • Смягчение последствий SYN Flood-атак: брандмауэр ограничивает новые TCP-соединения до 5 в секунду с всплеском до 10 пакетов.
  • Удаляет вредоносные пакеты: NULL-пакеты (часто используемые в скрытых сканированиях), XMAS-пакеты (используемые для сканирования портов) и некорректные комбинации флагов TCP, чтобы предотвратить атаки с помощью неправильно сформированных пакетов.

3. Ограничение доступа из интернета (минимальная поверхность атаки)

  • Блокирует ненужный входящий трафик из интернета.
  • Разрешает ограниченное количество ICMP-запросов (ping) — не более 3 в секунду.
  • Удаляет весь остальной внешний трафик, если он явно не разрешён.

4. Контроль над внутренним сетевым трафиком

  • DNS (AdGuardHome) на порту 5357 (UDP/TCP) → обеспечивает фильтрацию и логирование DNS-запросов.
  • DHCP (порты 67/68) → Требуется для назначения IP-адресов.
  • NTP (порт 123) → Обеспечивает точную синхронизацию времени.
  • HTTPS (порт 443) → Включает безопасный веб-доступ.
  • Все неразрешенные попытки подключения отклоняются с помощью TCP reset.

5. Принудительная фильтрация DNS

  • Перенаправляет все DNS-запросы клиентов на AdGuardHome (порт 5357) и предотвращает обход AdGuardHome → Обеспечивает фильтрацию DNS, чтобы все запросы регистрировались и фильтровались.

6. Изоляция устройств (предотвращение несанкционированного бокового перемещения)

  • Блокирует прямой трафик между usb0 (Ethernet Gadget) и wlan0 (точка доступа Wi-Fi). Это предотвращает обмен данными между клиентами в разных сетях, снижая риски безопасности.

7. Безопасный доступ в интернет через трансляцию сетевых адресов (NAT)

  • Маскирует весь исходящий трафик из частной сети (usb0, wlan0) в интернет → Скрывает внутренние IP-адреса и предотвращает прямое раскрытие подключенных устройств.

8. Отключение IPv6 (предотвращение утечек и атак через IPv6)

  • Отбрасывает весь IPv6-трафик, чтобы предотвратить потенциальные атаки или утечки через IPv6.
  • Обеспечивает, что весь трафик маршрутизируется через IPv4, который явно контролируется межсетевым экраном.

⚠️ ВАЖНО: Настройте межсетевой экран для вашего Wi-Fi-адаптера: Если вы используете адаптер, отличный от ALFA AWUS036ACM, межсетевой экран перестанет работать! Выполните следующие команды, чтобы обновить конфигурацию межсетевого экрана с предсказуемым именем интерфейса вашего адаптера:

WIFI='PREDICTABLE-INTERFACE-NAME'
sudo sed -i "s/\bwlx00c0caae6319\b/$WIFI/" /etc/nftables.conf

⚠ Замените PREDICTABLE-INTERFACE-NAME на фактическое имя вашего Wi-Fi-адаптера. Для получения инструкций обратитесь к разделу 03 - ПРЕДВАРИТЕЛЬНЫЕ ТРЕБОВАНИЯ и 11 НАСТРОЙКА БЕСПРОВОДНОЙ ТОЧКИ ДОСТУПА.

Включите nftables, чтобы правила межсетевого экрана сохранялись после перезагрузки:

sudo systemctl enable nftables

⚠️ ВАЖНО: Предотвратите перезапись правил межсетевого экрана NetworkManager!
По умолчанию NetworkManager может вмешиваться в настройки межсетевого экрана. Наша настройка слишком сложна, чтобы допускать это:

sudo sed -i '/^dhcp=dnsmasq$/a firewall-backend=none' /etc/NetworkManager/NetworkManager.conf

Перезагрузите систему, чтобы применить все изменения:

sudo reboot now

9. Установка fail2ban

Fail2ban следит за файлами журналов на предмет подозрительной активности (например, неудачные попытки входа по SSH) и реагирует, блокируя IP-адреса нарушителей с помощью правил межсетевого экрана. В нашей настройке SSH настроен на прослушивание порта 6666. Поскольку наша конфигурация nftables использует таблицу inet global, нам нужно создать выделенный набор Fail2ban и цепочку внутри этой таблицы.

sudo sed -i '/table inet global {/a\
\
    # Create the Fail2ban set\
    set f2b-sshd {\
        type ipv4_addr\
        flags timeout\
    }\
\
    # Create the Fail2ban chain that drops packets from IPs in the set\
    chain f2b-sshd {\
        ip saddr @f2b-sshd drop\
    }' /etc/nftables.conf

Далее подключите новую цепочку f2b-sshd к существующей цепочке inbound:

sudo sed -i '/^[[:space:]]*chain inbound {$/{
  n
  s/\(policy drop;\)/\1\
\
        # Check for banned IPs via Fail2ban\
        jump f2b-sshd/
}' /etc/nftables.conf

Установите fail2ban:

sudo apt install -y fail2ban

Создайте пользовательское действие Fail2ban для nftables:

echo '[Definition]

actionstart =
actionstop =

# When banning an IP, add it to the set with the given bantime.
actionban = /usr/sbin/nft add element inet global f2b-sshd \{ <ip> timeout <bantime>s \}

# When unbanning an IP, remove it from the set.
actionunban = /usr/sbin/nft delete element inet global f2b-sshd \{ <ip> \}' | sudo tee /etc/fail2ban/action.d/nftables-ssh.conf > /dev/null

Далее нужно настроить fail2ban для мониторинга SSH на порту 6666 с использованием systemd journal, который является стандартным механизмом ведения журналов на Raspberry Pi:

echo '[sshd]
enabled  = true
port     = 6666
filter   = sshd
backend  = systemd
findtime = 600
maxretry = 2
bantime  = 165600
ignoreip = 192.168.77.77
action   = nftables-ssh[name=sshd, port=6666, protocol=tcp]' | sudo tee /etc/fail2ban/jail.local > /dev/null

Эта конфигурация следит за SSH на порту 6666, и если IP-адрес дважды не проходит аутентификацию, он будет заблокирован на 46 часов путем добавления правила в nftables для отбрасывания его пакетов. Единственный IP-адрес, освобожденный от этой политики, — это 192.168.77.77, который принадлежит нашей РАБОЧЕЙ СТАНЦИИ, подключенной через интерфейс usb0.

Перезагрузите межсетевой экран:

sudo nft -f /etc/nftables.conf

Перезапустите fail2ban:

sudo systemctl restart fail2ban

Проверьте статус Fail2ban:

sudo fail2ban-client status sshd

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

sudo nft list set inet global f2b-sshd

19 НАСТРОЙКА ADGUARDHOME

⚠ ВАЖНО: Выполнение глав 13–19 шаг за шагом в правильном порядке имеет решающее значение! Любая ошибка в конфигурации может вызвать проблемы с DNS, что приведет к потере подключения к интернету для вашего Raspberry Pi и подключенных к нему клиентов — или даже полностью заблокирует вас. Даже небольшие ошибки или пропущенные шаги могут привести к тому, что некоторые аспекты настройки не будут работать должным образом. Действуйте осторожно и точно следуйте каждому шагу.

Этот репозиторий предоставляет предварительно настроенную конфигурацию AdGuardHome, которую мы настоятельно рекомендуем использовать. Она специально адаптирована для предотвращения распространенных конфликтов, таких как пересечение портов с NGINX для HTTPS. Кроме того, она обеспечивает бесшовную интеграцию с нашей настройкой, а именно:

  • Избегает пересечения портов с NGINX для HTTPS.
  • Назначает корректные порты DNS для совместимости.
  • Заранее настраивает необходимые пути к SSL-сертификатам из предыдущего раздела.
  • Использует Unbound в качестве единственного апстрим-резолвера для повышения конфиденциальности и безопасности.

Кроме того, эта конфигурация включает: - Заранее определённые резервные DNS-серверы для зашифрованных запросов (DNS-over-HTTPS), которые, по нашему мнению, вероятно, заслуживают доверия: - https://doh.mullvad.net/dns-query - https://dns.digitale-gesellschaft.ch/dns-query - https://anycast.uncensoreddns.org/dns-query - https://unicast.uncensoreddns.org/dns-query - https://doh.libredns.gr/dns-query - https://odvr.nic.cz/dns-query - https://doh.ffmuc.net/dns-query - Оптимизированные настройки кэширования для улучшения производительности. - Всесторонние опции ведения журнала и отладки. - Несколько DNS-фильтров для блокировки рекламы, трекеров и вредоносных доменов.

Используя эту настройку, вы можете избежать потенциальных проблем и обеспечить плавное развёртывание без лишних хлопот. Если вы не знаете точно, что делаете, мы рекомендуем не изменять наши Настройки шифрования и не использовать встроенный DHCP-сервер AdGuardHome. Мы настроили NetworkManager и Dnsmasq для обработки DHCP.

1. Остановите AdGuardHome:

Перед применением новой конфигурации остановите службу AdGuardHome:

sudo systemctl stop AdGuardHome

2. Загрузите файл конфигурации:

Получите заранее настроенную конфигурацию из репозитория:

sudo curl -L -o /home/admin/build/AdGuardHome/AdGuardHome.yaml "https://codeberg.org/term7/Going-Dark/raw/branch/main/Pi%20Configuration%20Files/adguard-home/AdGuardHome.yaml"

Ограничьте права доступа к файлу для повышения безопасности:

sudo chmod 600 ~/build/AdGuardHome/AdGuardHome.yaml

3. Измените пароль по умолчанию:

Поскольку это публичный репозиторий, пароль по умолчанию установлен как "default". Вы должны его изменить!

Чтобы сгенерировать хэшированный пароль bcrypt, установите пакет whois:

sudo apt install -y whois

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

PASSWORD='YOUR-NEW-PASSWORD'
sudo sed -i "s/^    password: default/    password: \"$(mkpasswd -m bcrypt "$PASSWORD")\"/" ~/build/AdGuardHome/AdGuardHome.yaml

⚠ Замените YOUR-NEW-PASSWORD на надёжный пароль по вашему выбору. Рассмотрите возможность использования менеджера паролей для генерации безопасного пароля.

4. Перезапустите AdGuardHome:

После обновления пароля перезапустите службу:

sudo systemctl start AdGuardHome

5. Войдите в веб-интерфейс AdGuardHome:

Теперь проверьте свою настройку:

  1. Отключите Wi-Fi на вашем Mac.
  2. Откройте браузер и перейдите по адресу https://adguard.home.
  3. Войдите под именем term7 с вашим NOVЫM-ПАРОЛЕМ.

ПОЗДРАВЛЯЕМ

Ваша установка AdGuardHome теперь полностью настроена и работает!

6. Проверьте валидацию DNSSEC:

Чтобы проверить, работает ли валидация DNSSEC, посетите этот сайт:
https://wander.science/projects/dns/dnssec-resolver-test/


20 БЛОКИРОВОЧНЫХ СПИСКОВ DNS

В этом разделе мы кратко рассмотрим блокировочные и разрешённые списки DNS — два важных инструмента для управления DNS-трафиком в AdGuardHome.

Заблокированные домены

AdGuardHome поддерживает список заблокированных доменов, которые будут явно заблокированы. По умолчанию в него входит только version.bind, но мы расширили этот список, чтобы охватить домены, обычно используемые для диагностики DNS, отладки или тестирования сети, а не для обычного просмотра веб-страниц или использования приложений. Блокировка этих доменов помогает усилить конфиденциальность, предотвращая утечку информации об IP и сервере, уменьшает ненужные DNS-запросы и предотвращает раскрытие внутренних деталей DNS:

  • version.bind
  • id.server
  • hostname.bind
  • devices.resolving.planetlab.google.com
  • whoami.ultradns.net
  • whoami.akamai.net
  • debug.opendns.com
  • resolver.dnscrypt.info
  • edns-client-subnet.test-ipv6.com
  • test.dnssec-or-not.net
  • porttest.dns-oarc.net

Пользовательские правила фильтрации

В этом разделе мы явно разрешаем домен check.torproject.org:

! Allow Tor Check
!
@@||torproject.org^$important

Этот домен используется позже в нашей настройке ПРОЗРАЧНЫЙ ПРОКСИ TOR, чтобы проверить маршрутизацию через Tor. Поскольку он блокируется одним из наших заранее настроенных блокировочных списков, мы добавляем его в белый список здесь, чтобы обеспечить его корректную работу. Вы можете добавить свои собственные пользовательские правила разрешения или блокировки в этом разделе в зависимости от вашего конкретного случая использования.

Заранее настроенные блокировочные списки

Наши блокировочные списки по умолчанию взяты из этого отличного репозитория GitHub, который поддерживает Герд Хагези: https://github.com/hagezi/dns-blocklists

Следующие списки включены по умолчанию в нашей конфигурации:

1.
Hagezi: Потоки данных угроз
Описание: Значительно повышает безопасность! Блокирует вредоносное ПО, криптоджекинг, спам, мошенничество и фишинг.
Количество записей: 962584 / 21 марта 2025

https://codeberg.org/hagezi/mirror2/raw/branch/main/dns-blocklists/adblock/tif.txt

2.
Hagezi: Multi ULTIMATE


Описание: Ultimate Sweeper — строго очищает интернет и защищает вашу конфиденциальность! Блокирует рекламу, партнёрские программы, трекинг, метрики, телеметрию, фишинг, вредоносное ПО, мошенничество, бесплатные хостинги, фейковые сайты, криптоджекинг и другой «мусор».
Количество записей: 334037 / 21 марта 2025

https://codeberg.org/hagezi/mirror2/raw/branch/main/dns-blocklists/adblock/ultimate.txt

3.
Hagezi: Список блокировки DNS для азартных игр
Описание: Блокирует контент, связанный с азартными играми.
Количество записей: 704324 / 21 марта 2025

https://codeberg.org/hagezi/mirror2/raw/branch/main/dns-blocklists/adblock/gambling.txt

4.
Hagezi: Список блокировки DNS для фейковых сайтов
Описание: Защищает от интернет-мошенничества, ловушек и подделок! Блокирует фейковые магазины, стриминговые платформы, подделки, платные ловушки и прочее.
Количество записей: 10744 / 20 марта 2025

https://codeberg.org/hagezi/mirror2/raw/branch/main/dns-blocklists/adblock/fake.txt

5.
Hagezi: Список блокировки DNS для всплывающих реклам
Описание: Блокирует назойливые и вредоносные всплывающие рекламные окна.
Количество записей: 100339 / 20 марта 2025

https://codeberg.org/hagezi/mirror2/raw/branch/main/dns-blocklists/adblock/popupads.txt

6.
Hagezi: Обход DoH/VPN/TOR/Proxy
Описание: Предотвращает попытки обхода вашего DNS, блокирует зашифрованный DNS, VPN, TOR, прокси.
Количество записей: 3888 / 20 марта 2025

https://codeberg.org/hagezi/mirror2/raw/branch/main/dns-blocklists/adblock/doh-vpn-proxy-bypass.txt

7.
Hagezi: Список блокировки DNS для трекеров Amazon
Описание: Блокирует встроенные трекеры Amazon, которые отслеживают вашу активность.
Количество записей: 334 / 8 марта 2025

https://codeberg.org/hagezi/mirror2/raw/branch/main/dns-blocklists/adblock/native.amazon.txt

8.
Hagezi: Список блокировки DNS для трекеров Windows/Office
Описание: Блокирует встроенные трекеры Windows/Office, которые отслеживают вашу активность.
Количество записей: 357 / 14 марта 2025

https://codeberg.org/hagezi/mirror2/raw/branch/main/dns-blocklists/adblock/native.winoffice.txt

9.
Hagezi: Список блокировки DNS для трекеров Apple
Описание: Блокирует встроенные трекеры Apple, которые отслеживают вашу активность.
Количество записей: 93 / 22 февраля 2025

https://codeberg.org/hagezi/mirror2/raw/branch/main/dns-blocklists/adblock/native.apple.txt

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

Этот список блокировки отключён по умолчанию и предназначен для опытных пользователей, которые хотят полностью ограничить онлайн-сервисы Apple. Это агрессивный список, блокирующий все известные домены Apple, а также множество сторонних сервисов, используемых инфраструктурой Apple.

⚠️ Предупреждение: включение этого списка полностью нарушит работу большинства сервисов Apple, включая (но не ограничиваясь): iCloud, Apple TV+, Apple Music, Apple Arcade, Apple Maps, Apple News+, Apple Pay, App Store, iMessage, FaceTime, FindMy и др.

Несмотря на широкий охват блокировки, мы активно поддерживаем минимальный список разрешённых доменов, необходимых для критических обновлений программного обеспечения и безопасности macOS.

10.
Term7: Полный список блокировки Apple
Описание: Полный список блокировки Apple — ВНИМАНИЕ: нарушает работу сервисов Apple
Комментарий: Разрешает критически важные обновления ПО и безопасности
Количество записей: 37 / 21 марта 2025

https://codeberg.org/term7/Break-Apple-Blocklist/raw/branch/main/Break-Apple-Blocklist.txt


21 WIREGUARD VPN

В этом разделе мы настроим Raspberry Pi в качестве клиента WireGuard, который можно активировать при необходимости. Эта настройка беспрепятственно работает с AdGuardHome, который будет продолжать фильтровать рекламу и блокировать вредоносные домены перед тем, как DNS-запросы будут передаваться через туннель WireGuard VPN. В нашей личной настройке мы установили сервер WireGuard на домашний маршрутизатор (с прошивкой OpenWRT). Когда мы путешествуем — будь то отель, аэропорт или работа из зарубежного кафе — наш Raspberry Pi передаёт весь сетевой трафик через защищённое, зашифрованное соединение WireGuard обратно на домашний маршрутизатор.
Это означает, что наш интернет-трафик защищён от локальных сетей и посторонних наблюдателей. Мы можем безопасно получать доступ к домашней сети и сервисам из любой точки мира, а устройства, подключённые к Raspberry Pi, будут выглядеть так, будто выходят в интернет с домашнего IP-адреса.

Вот как подключённое устройство будет выходить в интернет через наш WireGuard VPN:

+---------------------+       +-------------------------------+                 +-----------------------+

|                     |       |          RASPBERRY PI         |                 |                       |
|                     |       |                               |                 |                       |
|   Laptop / Phone    |  TCP  |        WIREGUARD CLIENT       |  encrypted TCP  |   WIREGUARD SERVER    |
|       NO VPN        | <---> |           10.13.0.1           | <-------------> |    --> Home Router    | 
|                     |  DNS  |                               |  encrypted DNS  |                       |
|                     |       |            Firewall           |                 |                       |
+---------------------+       +-------------------------------+                 +-----------------------+
                                              ^                                             ^

                                              |                                             |
                                          DNS |                                         TCP | DNS

                                              |                                             |
                                              v                                             v
                              +-------------------------------+                      +--------------+

                              |                               |                      |              |
                              |    AdGuardHome --> Unbound    |                      |   INTERNET   |
                              |   DNS Filtering + Forwarding  |                      |              |
                              |                               |                      +--------------+
                              +-------------------------------+

Примечание: Полное руководство по настройке сервера WireGuard на домашнем маршрутизаторе выходит за рамки этого туториала.

В этом руководстве мы предполагаем, что:

  • У вас уже есть доступ к серверу WireGuard.
  • У вас есть файл конфигурации клиента WireGuard, готовый к импорту.

Этот сервер может быть:

  • Самостоятельно развёрнутым экземпляром WireGuard на домашнем маршрутизаторе
  • Самостоятельно развёрнутым экземпляром WireGuard на виртуальном частном сервере (VPS)
  • Или доверенным VPN-провайдером, поддерживающим WireGuard

Если вы не используете собственный сервер, то Mullvad и ProtonVPN — надёжные варианты с акцентом на конфиденциальность. Они поддерживают WireGuard и позволяют скачивать конфигурационные файлы, которые работают без их приложений.

  1. ProtonVPN → Швейцарский провайдер, поддерживает WireGuard и позволяет генерировать клиентские профили (требуется платная подписка).
  2. Mullvad → Шведский провайдер, предлагает загрузку конфигураций WireGuard без приложений и без указания email.

Примечание: Оба заявляют о строгой политике отсутствия логов, но, как и в случае с любыми VPN-провайдерами, это доверие невозможно независимо проверить. Если вы используете коммерческий VPN, в конечном итоге вам придётся доверять провайдеру.

1. Скопируйте конфигурацию WireGuard на Raspberry Pi:

В этом руководстве мы будем использовать файл конфигурации WireGuard с именем term7.wireguard.conf. Замените это имя на своё, где бы оно ни встречалось.

Поскольку мы отключили вход от имени root, нужно скопировать файл конфигурации в учётную запись не-root пользователя на Raspberry Pi. На Mac откройте терминал и выполните:

scp -P 6666 ~/Desktop/wireguard-export/term7.wireguard.conf term7@192.168.77.1:/home/term7/

Теперь войдите в систему на Raspberry Pi под своей учётной записью администратора и подготовьте каталог для хранения файла конфигурации:

[ -d ~/tools ] || mkdir ~/tools && [ -d ~/tools/wireguard-export ] || mkdir ~/tools/wireguard-export

Переместите файл конфигурации в новое расположение:

sudo mv /home/term7/term7.wireguard.conf ~/tools/wireguard-export/term7.wireguard.conf

2. Импортируйте конфигурацию WireGuard с помощью NetworkManager:

NetworkManager имеет встроенную поддержку WireGuard. Мы используем её для импорта конфигурации:

sudo nmcli connection import type wireguard file ~/tools/wireguard-export/term7.wireguard.conf

После импорта рекомендуется сразу отключить соединение (на случай, если оно подключилось автоматически):

sudo nmcli con down term7.wireguard

Отключите автоподключение для этого VPN-профиля (мы будем активировать его вручную):

sudo nmcli con modify term7.wireguard connection.autoconnect no

Если у вас установлен WireGuard на домашнем маршрутизаторе и вы хотите иметь возможность доступа к веб-интерфейсу конфигурации и сервисам через браузер по VPN, добавьте необходимые маршруты для доступа к локальной сети (предполагаем, что веб-интерфейс маршрутизатора — 192.168.1.1):

sudo nmcli connection modify "term7.wireguard" +ipv4.routes "192.168.1.0/24"

Также установите рекомендуемое значение MTU:

sudo nmcli connection modify "term7.wireguard" wireguard.mtu 1380

3. Настройка межсетевого экрана для WireGuard:

Когда WireGuard активен, мы хотим настроить межсетевой экран так, чтобы трафик направлялся через VPN (term7.wireguard) вместо стандартного интерфейса Ethernet или Wi-Fi.

Сначала создайте необходимую структуру каталогов для конфигураций межсетевого экрана:

[ -d ~/script ] || mkdir ~/script && [ -d ~/script/nftables ] || mkdir ~/script/nftables

Создайте резервную копию стандартной конфигурации nftables:

sudo cp /etc/nftables.conf ~/script/nftables/nftables.conf

Скопируйте стандартные правила в качестве основы для конфигурации, специфичной для WireGuard:

sudo cp ~/script/nftables/nftables.conf ~/script/nftables/wireguard.conf

Обновите определение интерфейса в новой конфигурации, чтобы трафик направлялся через интерфейс WireGuard:

sudo sed -i '/DEV_WORLD = {/c\define DEV_WORLD = { term7.wireguard }' ~/script/nftables/wireguard.conf

Добавьте этот раздел в межсетевой экран, чтобы гарантировать, что TCP-сессии никогда не пытаются отправить пакеты, слишком большие для туннеля. Это происходит автоматически на уровне межсетевого экрана, поэтому вам не нужно вручную настраивать параметры MTU на клиентах:

sed -i '/^# ----- IPv6: drop all traffic -----/i \

# ----- MSS clamp for usb0/wlan0 -> WireGuard (avoid PMTU blackholes) -----\
table inet mangle {\
    chain fwd_mss {\
        type filter hook forward priority mangle; policy accept;\
\
        # Clamp SYN MSS to 1340 when forwarding from private LAN to WireGuard\
        iifname { usb0, wlan0 } oifname $DEV_WORLD tcp flags syn tcp option maxseg size set 1340\
    }\
}\
' ~/script/nftables/wireguard.conf

4. Динамическое применение правил межсетевого экрана с помощью скрипта-диспетчера:

Мы будем использовать скрипт NetworkManager, чтобы автоматически переключать конфигурации межсетевого экрана и стандартные настройки Unbound DNS при подключении или отключении WireGuard. Когда VPN активен, Unbound переходит в «режим VPN»: вместо выполнения рекурсивного разрешения DNS с использованием корневых серверов он теперь пересылает все DNS-запросы через зашифрованный туннель WireGuard. Эти пересланные запросы затем разрешаются на другой стороне туннеля. В нашем случае это наш домашний маршрутизатор, который настроен на использование DNS-over-HTTPS (DoH) для безопасного и конфиденциального разрешения DNS. Несмотря на переход к схеме пересылки, Unbound всё равно будет обеспечивать проверку DNSSEC, гарантируя, что DNS-ответы аутентифицированы и не были подделаны. Кроме того, скрипт перезапускает fail2ban, чтобы восстановить ранее заблокированные IP-адреса.

Создайте скрипт:

sudo tee /etc/NetworkManager/dispatcher.d/wireguard-handler > /dev/null << 'EOF'
#!/bin/bash

# Define Interfaces
WG_INTERFACE="term7.wireguard"

# Define Config Files
WG_RULES="/home/admin/script/nftables/wireguard.conf"
DEFAULT_RULES="/etc/nftables.conf"
UNBOUND_CONFIG="/etc/unbound/unbound.conf.d/local-zones.conf"

# Define WireGuard DNS Config
WG_DNS_CONFIG="# Upstream DNS via WireGuard\nforward-zone:\n    name: \".\"\n    forward-addr: 10.13.0.1"

case "$1" in
    $WG_INTERFACE)
        case "$2" in
            up)
                # Apply WireGuard firewall rules
                /usr/sbin/nft -f "$WG_RULES"

                # Append WireGuard DNS to Unbound if not already present
                if ! grep -Fxq "$WG_DNS_CONFIG" "$UNBOUND_CONFIG"; then
                    echo -e "\n$WG_DNS_CONFIG" | sudo tee -a "$UNBOUND_CONFIG" > /dev/null
                fi

                sudo systemctl restart unbound
                sudo systemctl restart fail2ban
                ;;
            down)
                # Restore default nftables rules
                /usr/sbin/nft -f "$DEFAULT_RULES"

                # Remove WireGuard DNS Config
                sed -i '/fallback-enabled: yes/,$d' "$UNBOUND_CONFIG"
                echo "        fallback-enabled: yes" | sudo tee -a "$UNBOUND_CONFIG" > /dev/null

                sudo systemctl restart unbound
                sudo systemctl restart fail2ban
                ;;
        esac
        ;;
esac
EOF

Сделайте скрипт исполняемым:

sudo chmod +x /etc/NetworkManager/dispatcher.d/wireguard-handler

5. Запуск/остановка подключения WireGuard:

Чтобы запустить WireGuard VPN:

sudo nmcli con up term7.wireguard

Чтобы остановить WireGuard VPN:

sudo nmcli con down term7.wireguard

6. Проверка валидации DNSSEC и утечек DNS:

Чтобы убедиться, что проверка DNSSEC всё ещё работает корректно, посетите:
https://wander.science/projects/dns/dnssec-resolver-test/

Чтобы проверить утечки DNS, используйте:
https://dnsleaktest.com

Единственный видимый IP-адрес должен принадлежать вашему VPN-провайдеру или DNS-серверу, настроенному на вашем домашнем маршрутизаторе или VPS. Если вы видите DNS-серверы вашего локального интернет-провайдера, туннель VPN или пересылка Unbound могут работать некорректно.


22 ПРОЗРАЧНЫЙ ПРОКСИ TOR

Наконец, мы установим Tor и настроим наш Raspberry Pi для работы в качестве прозрачного прокси Tor. Эта настройка может активироваться или деактивироваться вручную по мере необходимости. При активации весь трафик от подключённых устройств будет по-прежнему фильтроваться через AdGuardHome перед безопасной маршрутизацией через сеть Tor.

⚠️ ПРЕДУПРЕЖДЕНИЕ: Прозрачный прокси Tor — не рекомендуемый способ использования сети Tor. Если ваша цель — просто анонимный просмотр интернета, мы настоятельно рекомендуем использовать Tor Browser! Tor Browser специально разработан для обеспечения конфиденциальности и анонимности. Он стандартизирует поведение браузера, чтобы минимизировать отпечатки, и включает встроенную защиту от отслеживания, наблюдения через скрипты и утечек DNS. В отличие от этого, прозрачный прокси только перенаправляет сетевой трафик через сеть Tor. Он не предотвращает утечку идентифицирующей информации из приложений или браузеров. Использование обычного браузера через прозрачный прокси Tor почти наверняка всё равно раскроет уникальный отпечаток, подрывая основные преимущества использования Tor. Тем не менее, вы можете объединить прозрачный прокси Tor (для анонимизации всего системного трафика) с Tor Browser (для безопасного анонимного просмотра), чтобы извлечь выгоду из обеих функций: системной маршрутизации и защищённого браузера.

Тем не менее, правильно настроенный прозрачный прокси Tor может стать мощным инструментом для анонимизации общего трафика, защиты небраузерных приложений и создания среды, ориентированной на конфиденциальность. При правильной настройке с жёсткими правилами межсетевого экрана, защитой от утечек DNS и контролируемым сетевым доступом он позволяет создать надёжную «точку доступа конфиденциальности» типа «включил и работает» — идеальную для путешествий, общих сетей или защиты устройств без графического интерфейса. Именно этого мы и добиваемся в этом руководстве.

Вот как подключённое устройство будет выходить в интернет через наш прозрачный прокси Tor:

+---------------------+       +-------------------------------+                 +----------------------+

|                     |       |          RASPBERRY PI         |                 |                      |
|                     |       |                               |                 |    TOR ENTRY NODE    |
|   Laptop / Phone    |  TCP  |     TOR TRANSPARENT PROXY     |  encrypted TCP  |                      |
| (No Tor Installed)  | <---> |  10.192.0.1 / TransPort 9040  | <-------------> |  KNOWS your real IP  |
|                     |  DNS  |                               |                 | NOT your destination |
|                     |       |            Firewall           |                 |                      |
+---------------------+       +-------------------------------+                 +----------------------+
                                       ^                                            ^       ^

                                       |                                            |       |
                                   DNS |                                            |       |

                                       |                                            |       |
                                       V                                            |       |
                    +------------------------------+             encrypted DNS      |       |

                    |                              | <------------------------------/       |
                    |   AdGuardHome --> Unbound    |                                        | TCP / Onion Encryption 
                    |  DNS Filtering + Forwarding  |                                        |
                    |                              |                 DNS / Onion Encryption |
                    |  10.192.0.1 / DNS Port 9053  |                                        |
                    |     TOR TRANSPARENT PROXY    |                                        |
                    |                              |                                        v
                    +------------------------------+                            +----------------------+

                                                                                |                      |
                                                                                |    TOR RELAY NODE    |
                                                                                |                      |
                                                                                |     NEITHER knows    | 
                                                                                |        your IP       | 
                                                                                | NOR your destination |
                                                                                |                      |
                                                                                +----------------------+
                                                                                            ^

                                                                                            |
                                                                                            | TCP / Onion Encryption
                                                                                            |
                                                                     DNS / Onion Encryption |

                                                                                            |
                                                                                            v
                                                                                +----------------------+

                                                                                |                      |
                                                                                |     TOR EXIT NODE    |
                                                                                |                      |
                                                                                |  CANNOT know your IP | 
                                                                                |       but KNOWS      |
                                                                                |   your destination   |
                                                                                |                      |
                                                                                +----------------------+
                                                                                            ^

                                                                                            |
                                                                                        DNS | TCP

                                                                                            |
                                                                                            v
                                                                                    +--------------+

                                                                                    |              |
                                                                                    |   INTERNET   |
                                                                                    |              |
                                                                                    +--------------+

1. Установка Tor:

Чтобы установить пакет tor, выполните:

sudo apt install -y tor

2. Настройка прозрачного прокси Tor:

Начните с резервного копирования стандартной конфигурации Tor:

sudo cp /etc/tor/torrc /etc/tor/torrc.bak

Затем включите базовое ведение журнала и настройте Tor для работы в качестве фоновой службы:

sudo sed -i 's|^#Log notice file /var/log/tor/notices.log|Log notice file /var/log/tor/notices.log|; s|^#RunAsDaemon 1|RunAsDaemon 1|; s|^#DataDirectory /var/lib/tor|DataDirectory /var/lib/tor|' /etc/tor/torrc

Добавьте в файл torrc следующую конфигурацию:

sudo tee -a /etc/tor/torrc > /dev/null <<EOF

# Tor Transparent Proxy
VirtualAddrNetworkIPv4 10.192.0.0/12
AutomapHostsSuffixes .onion,.exit
AutomapHostsOnResolve 1


# Bind Transparent Proxy & DNSPort to localhost
TransPort 10.192.0.1:9040
DNSPort 10.192.0.1:9053
EOF

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

sudo systemctl stop tor@default
sudo systemctl disable tor@default

3. Создание фиктивного интерфейса NetworkManager:

Как и в случае с настройкой WireGuard, мы будем использовать выделенный интерфейс NetworkManager для активации и деактивации прозрачного прокси Tor. Создайте и настройте фиктивный интерфейс с именем torproxy:

sudo nmcli con add type dummy ifname torproxy con-name torproxy ipv4.method manual ipv4.addresses 10.192.0.1/32
sudo nmcli con modify torproxy ipv4.ignore-auto-routes yes
sudo nmcli con modify torproxy ipv4.never-default yes
sudo nmcli con modify torproxy ipv4.dns 10.192.0.1
sudo nmcli con modify torproxy autoconnect no

После создания подключения рекомендуется сразу его отключить (на случай автоматического подключения):

sudo nmcli con down torproxy

4. Межсетевой экран Tor:

Конфигурация межсетевого экрана для Tor сложнее, чем для WireGuard, так как требует явного перенаправления трафика и дополнительных мер защиты. Мы будем использовать предварительно настроенный набор правил, который можно загрузить из нашего репозитория.

Сначала убедитесь, что существует структура каталогов для конфигураций межсетевого экрана:

[ -d ~/script ] || mkdir ~/script && [ -d ~/script/nftables ] || mkdir ~/script/nftables

Затем загрузите конфигурацию межсетевого экрана для Tor:

sudo curl -L -o /home/admin/script/nftables/torproxy.conf "https://codeberg.org/term7/Going-Dark/raw/branch/main/Pi%20Configuration%20Files/nftables/torproxy.conf"

Этот межсетевой экран реализует все меры защиты, описанные в разделе 18 МЕЖСЕТЕВОЙ ЭКРАН, а также:

  • Перенаправляет весь TCP-трафик (кроме SSH на порту 6666) на TransPort Tor (9040).
  • Применяет перенаправление как в цепочке prerouting (для внешнего трафика клиентов), так и в цепочке output (для локального трафика), гарантируя, что все TCP-соединения forced через Tor.
  • Блокирует все входящие ICMP-эхо-запросы (пинги) из интернета для повышения скрытности.
  • Удаляет все фрагментированные IP-пакеты, которые могут использоваться для уклонения или сканирования.

Он также улучшает конфиденциальность, полностью блокируя ICMP-эхо-запросы из интернета. Кроме того, он удаляет все фрагментированные IP-пакеты, которые могут использоваться для сканирования или уклонения.

Управление трафиком, специфичное для Tor

Чтобы предотвратить петли маршрутизации или сбои в работе сервисов, межсетевой экран явно разрешает трафик, создаваемый самим процессом Tor, обходить перенаправление. Это гарантирует, что Tor может устанавливать цепочки без помех со стороны межсетевого экрана.

Цепочка forward в этой настройке межсетевого экрана строго ограничена. Она разрешает пересылку только трафика, который был маршрутизирован через Tor, и блокирует всю остальную межинтерфейсную пересылку для поддержания сильной изоляции.

Специальная обработка DNS

Межсетевой экран не отправляет DNS-трафик напрямую на DNS-порт Tor (9053). Вместо этого он продолжает перенаправлять DNS-запросы в AdGuardHome (порт 5357), который, в свою очередь, передаёт их в Unbound. Мы настроим Unbound так, чтобы он передавал все DNS-запросы на DNSPort Tor (9053), сохраняя фильтрацию DNS при полной анонимизации через Tor.

5. Динамическое применение правил межсетевого экрана с помощью скрипта-диспетчера:

Снова будем использовать скрипт-диспетчер NetworkManager для автоматического переключения межсетевого экрана и конфигурации DNS Unbound при подключении или отключении интерфейса torproxy. Кроме того, скрипт будет динамически запускать и останавливать сервис Tor по мере необходимости.

Когда Tor активен, Unbound переходит в «режим Tor»: вместо выполнения рекурсивного разрешения DNS с использованием корневых серверов он передаёт все DNS-запросы через прозрачный прокси Tor. Эти запросы затем разрешаются узлом выхода Tor.

Однако, поскольку встроенный в Tor резолвер DNS не возвращает записи, связанные с DNSSEC (например, DNSKEY или RRSIG), Unbound не может проверять DNSSEC в этой конфигурации, даже если он настроен на её обязательное использование. Чтобы предотвратить сбои в разрешении DNS и доступе в интернет, наш скрипт-диспетчер временно включает разрешительный режим DNSSEC и разрешает запросы к localhost (DNSPort Tor), когда прокси активен. При деактивации интерфейса восстанавливаются исходные безопасные настройки. Кроме того, скрипт перезапускает fail2ban, чтобы восстановить ранее заблокированные IP-адреса.

Создайте скрипт-диспетчер:

sudo tee /etc/NetworkManager/dispatcher.d/torproxy-handler > /dev/null << 'EOF'
#!/bin/bash

# Define Interfaces
TOR_INTERFACE="torproxy"

# Define Config Files
TOR_RULES="/home/admin/script/nftables/torproxy.conf"
DEFAULT_RULES="/etc/nftables.conf"
UNBOUND_MAIN_CONFIG="/etc/unbound/unbound.conf.d/unbound-dnssec.conf"
UNBOUND_CONFIG="/etc/unbound/unbound.conf.d/local-zones.conf"

# Define TorProxy  DNS Config
TOR_DNS_CONFIG="# Upstream DNS via Tor\nforward-zone:\n    name: \".\"\n    forward-addr: 10.192.0.1@9053"

case "$1" in
    $TOR_INTERFACE)
        case "$2" in
            up)
                # Apply Tor firewall rules
                /usr/sbin/nft -f "$TOR_RULES"

                # Start Tor service
                sudo systemctl start tor@default

                # Edit Unbound main configuration
                sed -i 's/do-not-query-localhost: yes/do-not-query-localhost: no/' "$UNBOUND_MAIN_CONFIG"
                sed -i 's/val-permissive-mode: no/val-permissive-mode: yes/' "$UNBOUND_MAIN_CONFIG"

                # Append TorProxy DNS to Unbound if not already present
                if ! grep -Fxq "$TOR_DNS_CONFIG" "$UNBOUND_CONFIG"; then
                    echo -e "\n$TOR_DNS_CONFIG" | sudo tee -a "$UNBOUND_CONFIG" > /dev/null
                fi

                sudo systemctl restart unbound
                sudo systemctl restart fail2ban
                ;;

            down)
                # Restore default nftables rules
                /usr/sbin/nft -f "$DEFAULT_RULES"

                # Stop Tor service
                sudo systemctl stop tor@default

                # Restore Unbound main configuration
                sed -i 's/do-not-query-localhost: no/do-not-query-localhost: yes/' "$UNBOUND_MAIN_CONFIG"
                sed -i 's/val-permissive-mode: yes/val-permissive-mode: no/' "$UNBOUND_MAIN_CONFIG"

                # Remove TorProxy DNS Config
                sed -i '/fallback-enabled: yes/,$d' "$UNBOUND_CONFIG"
                echo "        fallback-enabled: yes" | sudo tee -a "$UNBOUND_CONFIG" > /dev/null

                sudo systemctl restart unbound
                sudo systemctl restart fail2ban
                ;;
        esac
        ;;
esac
EOF

Сделайте скрипт исполняемым:

sudo chmod +x /etc/NetworkManager/dispatcher.d/torproxy-handler

6. Запуск/остановка прозрачного прокси Tor:

Чтобы запустить прозрачный прокси Tor:

sudo nmcli con up torproxy

Чтобы остановить прозрачный прокси Tor:

sudo nmcli con down torproxy

7. Тестирование прозрачного прокси Tor:

Чтобы проверить, что ваш Raspberry Pi корректно маршрутизирует трафик через сеть Tor, выполните на устройстве следующую команду:

curl https://check.torproject.org/api/ip

Вы должны получить JSON-ответ с IP-адресом узла выхода Tor, что подтвердит анонимизацию исходящего трафика.

Чтобы подтвердить, что подключённое клиентское устройство — например, ваш Mac — также маршрутизируется через Tor, откройте браузер и перейдите по адресу:
https://check.torproject.org

Если всё работает правильно, на странице отобразится сообщение о том, что ваш трафик идёт из сети Tor.

Чтобы проверить возможные утечки DNS, посетите:
https://dnsleaktest.com Если вы видите свой домашний IP-адрес или IP-адрес DNS-резолвера, который вы настроили вручную на устройстве или маршрутизаторе, это указывает на утечку DNS. В этом случае ваш Прозрачный прокси Tor не изолирует DNS-трафик должным образом, и, возможно, потребуется пересмотреть конфигурацию, чтобы убедиться, что DNS-запросы также направляются через Tor.


23 КРАТКИЙ ОБЗОР КОМАНД

На этом этапе ваш Raspberry Pi должен быть полностью функциональным и работать так, как задумано. Пока что переключение между различными режимами всё ещё требует входа по SSH и использования командной строки из учётной записи admin.

1. Управление точкой доступа:

Запустить точку доступа:

sudo nmcli con up Hotspot

Остановить точку доступа:

sudo nmcli con down Hotspot

2. Переключение VPN WireGuard:

Включить WireGuard:

sudo nmcli con up term7.wireguard

Отключить WireGuard:

sudo nmcli con down term7.wireguard

3. Переключение прозрачного прокси Tor:

Включить Прозрачный прокси Tor:

sudo nmcli con up torproxy

Отключить Прозрачный прокси Tor:

sudo nmcli con down torproxy

⚠️ Важно: Никогда не запускайте WireGuard и Tor одновременно. Всегда отключайте один перед активацией другого — одновременная работа обоих вызовет конфликты и нарушит маршрутизацию.

ЧТО ДАЛЬШЕ:

Это была Часть 1 данного репозитория. В следующих разделах Части 2 мы покажем, как настроить удобный интерфейс управления, к которому можно подключиться локально из браузера по адресу: https://going.dark


ЧАСТЬ 2: ИНТЕРФЕЙС

24 ЦЕЛЬ

Это начало Части 2.

В Части 1 этого руководства мы создали серверные службы на Raspberry Pi. Теперь пришло время объединить всё это в локальном веб-интерфейсе, который работает непосредственно на Pi и упрощает управление службами. Интерфейс предоставляется локально через USB-C (192.168.77.1) на ваш рабочий компьютер. Он интегрирует два приложения Flask (установленных под стандартной учётной записью пользователя term7):

portal.py — управляет сетевыми функциями, такими как VPN, Прокси Tor и Точка доступа. config.py — управляет системными функциями, такими как выключение, перезагрузка, автоматическая генерация нового случайного имени хоста и MAC-адреса, а также отображение диагностической информации системы и данных о времени.

Оба приложения предоставляют простые элементы управления на основе кнопок. Кроме того, интерфейс встраивает панель управления AdGuard Home, которую мы настроили ранее в Части 1.

В следующих шагах мы:

  • Установим дополнительные необходимые компоненты.
  • Настроим необходимые права пользователя (term7).
  • Создадим выделенные виртуальные окружения для приложений Flask.
  • Загрузим необходимые скрипты Python из этого репозитория.
  • Развернём полный веб-интерфейс, загрузив его код в /var/www/going.dark.

Обратите внимание:

⚠️ Предупреждение: Всегда проверяйте любой код перед его загрузкой или запуском. Не доверяйте слепо этому руководству или любому другому. Убедитесь, что код легитимен и безопасен. Если вы обнаружите ошибки, неиспользуемый код или у вас есть предложения по улучшениям, пожалуйста, сообщите нам!

Готовый веб-интерфейс управления позволит вам:

  • Подключать Raspberry Pi к новой сети Wi-Fi
  • Отключаться от Wi-Fi, чтобы перейти в офлайн-режим
  • Переключаться между режимами VPN, Tor и Clearnet
  • Запускать или останавливать точку доступа
  • Изменять учётные данные точки доступа
  • Генерировать QR-код для быстрого доступа к точке доступа с мобильных устройств
  • Выключать или перезагружать Raspberry Pi одним нажатием кнопки
  • Просматривать диагностическую информацию и статус системы
  • Проверять системные часы и синхронизацию NTP
  • Входить в AdGuard Home напрямую

25 ИЗМЕНЕНИЕ ПРАВ ПОЛЬЗОВАТЕЛЯ

Запуск приложений Flask под стандартной учётной записью с тщательно ограниченными правами sudo уменьшает поверхность атаки, предотвращает случайные изменения на уровне системы и соответствует установленным практикам безопасности. По этой причине мы позже установим наши приложения Flask под стандартной учётной записью пользователя (term7). Однако для обеспечения необходимой функциональности term7 должен получить права суперпользователя для небольшого набора команд, а именно тех, которые требуются для управления сетью (nmcli), сканирования сетей Wi-Fi (iw) и выполнения системных действий, таких как reboot и shutdown.

1. Вход под учётной записью admin

Переключитесь на учётную запись admin:

su admin

2. Добавление правила polkit для NetworkManager

Создайте новое правило polkit, чтобы предоставить term7 необходимые привилегии NetworkManager:

sudo sh -c 'cat >/etc/polkit-1/rules.d/10-allow-term7-nm.rules << "EOF"
polkit.addRule(function(action, subject) {
  if (subject.user == "term7") {
    if (
      action.id == "org.freedesktop.NetworkManager.network-control" ||
      action.id == "org.freedesktop.NetworkManager.settings.modify.system" ||
      action.id == "org.freedesktop.NetworkManager.wifi.share.open" ||
      action.id == "org.freedesktop.NetworkManager.wifi.share.protected" ||
      action.id == "org.freedesktop.NetworkManager.enable-disable-wifi"
    ) {
      return polkit.Result.YES;
    }
  }
});
EOF'

Перезапустите polkit, чтобы применить новое правило:

sudo systemctl restart polkit || sudo systemctl restart polkit-1

3. Расширение прав sudo для выбранных команд

В разделе 04 КОНТРОЛЬ ДОСТУПА ПОЛЬЗОВАТЕЛЕЙ мы уже настроили файл /etc/sudoers.d/common_users, чтобы разрешить term7 выполнять команды reboot и shutdown.

Теперь мы расширим этот файл дополнительными привилегиями для: - iw (сканирование Wi-Fi и дамп станций) - ограниченной команды nmcli, которая показывает только PSK точки доступа. Это понадобится позже, когда приложение Flask (с использованием segno) сгенерирует QR-код после того, как пользователь введёт новый SSID и пароль и подтвердит нажатием Enter.

Выполните следующее:

NMCLI="$(command -v nmcli)"
IW="$(command -v iw)"

sudo sed -i "s|\$|, ${IW} dev wlx00c0caae6319 scan trigger, ${IW} dev wlx00c0caae6319 scan dump, ${IW} dev wlan0 station dump, ${NMCLI} -s -g 802-11-wireless-security.psk connection show Hotspot|" /etc/sudoers.d/common_users

Привилегии разделены между polkit и sudoers не случайно. Операции NetworkManager, такие как подключение, отключение и управление профилями, обрабатываются через polkit, так как они чётко соответствуют его действиям D-Bus и считаются безопасными для стандартного пользователя после явного разрешения. В то же время команды вроде сканирования Wi-Fi, получения PSK точки доступа или выполнения системных действий, таких как reboot и shutdown, остаются заблокированными в sudoers. Это разделение гарантирует, что у term7 есть только те точные разрешения, которые необходимы, следуя принципу минимальных привилегий, при этом позволяя веб-интерфейсу работать в полной мере.


26 НАСТРОЙКА NGINX SSL ДЛЯ GOING DARK

Прежде чем создавать веб-интерфейс управления, сначала нужно настроить NGINX и создать второй SSL-сертификат для нового локального сайта going.dark. Этот процесс очень похож на то, что мы делали в 16 SSL-СЕРТИФИКАТ и 17 НАСТРОЙКА ОБРАТНОГО ПРОКСИ NGINX, где мы сгенерировали самоподписанный SSL-сертификат для adguard.home и настроили NGINX как обратный прокси. На этом этапе мы повторно используем существующий самоподписанный центр сертификации term7-CA для выпуска нового SSL-сертификата специально для going.dark.

1. Генерация SSL-сертификатов для going.dark:

Перейдите в каталог конфигурации SSL:

cd ~/tools/CA/SSL

Создайте файл конфигурации OpenSSL для going.dark:

echo '[ req ]
default_bits       = 2048
default_md         = sha256
prompt             = no
distinguished_name = req_distinguished_name
req_extensions     = v3_req

[ req_distinguished_name ]
CN = going.dark

[ v3_req ]
subjectAltName = @alt_names
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth

[ alt_names ]
DNS.1 = going.dark
IP.1 = 192.168.77.1' | sudo tee /home/admin/tools/CA/SSL/openssl-goingdark.cnf > /dev/null

Сгенерируйте закрытый ключ для going.dark:

openssl genrsa -out ~/tools/CA/SSL/going.dark.key 2048

Создайте запрос на подпись сертификата (CSR):

openssl req -new -key going.dark.key -out going.dark.csr -config openssl-goingdark.cnf

Подпишите запрос на подпись сертификата (CSR) существующим локальным центром сертификации (term7-CA):

sudo openssl x509 -req -in ~/tools/CA/SSL/going.dark.csr -CA ~/tools/CA/term7-CA.pem -CAkey ~/tools/CA/term7-CA.key -CAcreateserial -out ~/tools/CA/SSL/going.dark.crt -days 90 -extensions v3_req -extfile ~/tools/CA/SSL/openssl-goingdark.cnf

Создайте полный сертификат:

cat ~/tools/CA/SSL/going.dark.crt ~/tools/CA/term7-CA.pem > ~/tools/CA/SSL/going.dark-fullchain.crt

Вам не нужно заново доверять этим сертификатам на вашем Raspberry Pi или переносить локальный центр сертификации (term7-CA) на ваш Mac, так как это уже было сделано в 16 SSL-СЕРТИФИКАТ! Чтобы включить going.dark в существующий скрипт обновления сертификатов, выполните:

sed -i '/^DOMAINS=(/ {/going\.dark/! s/\(adguard\.home"\)[[:space:]]*)/\1 "going.dark")/ }' /home/admin/script/SSL/renew-cert.sh

2. Создание корневого каталога веб-сайта и минимальной HTML-страницы для тестирования:

Создайте корневой каталог веб-сайта:

sudo mkdir -p /var/www/going.dark

Добавьте простую тестовую веб-страницу. Позже мы заменим её интерфейсом управления:

echo '<!DOCTYPE html>
<html>
<head>
  <title>Going Dark</title>
</head>
<body>
<h1>Welcome to going.dark</h1>
This is your simple test site.</p>
</body>
</html>' | sudo tee /var/www/going.dark/index.html > /dev/null

Установите правильные права владения:

sudo chown -R www-data:www-data /var/www/going.dark

3. Настройка NGINX как обратного прокси для Going.Dark:

Создайте конфигурацию NGINX:

echo 'server {
    listen 443 ssl http2;

    server_name going.dark;

    ssl_certificate /home/admin/tools/CA/SSL/going.dark-fullchain.crt;
    ssl_certificate_key /home/admin/tools/CA/SSL/going.dark.key;

    location / {
        root /var/www/going.dark;
        index index.html;
    }
}

server {
    listen 80;
    server_name going.dark;

    return 301 https://$host$request_uri;
}' | sudo tee /etc/nginx/sites-available/nginx-goingdark > /dev/null

Активируйте новую конфигуцию сайта NGINX:

sudo ln -s /etc/nginx/sites-available/nginx-goingdark /etc/nginx/sites-enabled/

Проверьте конфигурацию на ошибки:

sudo nginx -t

Если тест пройдён успешно, перезапустите NGINX:

sudo systemctl restart nginx

4. Обеспечение локального разрешения имени хоста:

Добавьте going.dark в файл /etc/hosts на вашем Mac и Raspberry Pi, чтобы он разрешался локально:

sudo sed -i.bak 's/\(adguard\.home\)\([^ ]*\)/\1 going.dark\2/' /etc/hosts && sudo rm -f /etc/hosts.bak

5. Посетите тестовый сайт:

Чтобы убедиться, что всё настроено правильно, откройте веб-браузер на вашем Mac и перейдите по адресу: https://going.dark

Вы должны увидеть простую тестовую страницу, созданную ранее.

6. Развёртывание финальной конфигурации NGINX:

На этом этапе у нас уже работает AdGuard Home локально на 127.0.0.1:3000. Наше приложение portal.py позже будет работать на 127.0.0.1:5001, а config.py — на 127.0.0.1:5002.

Следующая команда запишет финальную конфигурацию NGINX для going.dark. Это перезапишет вашу предыдущую конфигурацию сайта NGINX:

echo 'server {
    listen 192.168.77.1:443 ssl http2;
    server_name going.dark;

    ssl_certificate     /home/admin/tools/CA/SSL/going.dark-fullchain.crt;
    ssl_certificate_key /home/admin/tools/CA/SSL/going.dark.key;

    # ---- Minimal global hardening ----
    add_header Permissions-Policy "geolocation=(), camera=(), microphone=(), bluetooth=(), midi=(), usb=()" always;
    add_header Referrer-Policy "no-referrer" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header Strict-Transport-Security "max-age=15552000" always;  # ~180 days

    # ---- Static site root ----
    location / {
        root  /var/www/going.dark;
        index index.html;
    }

    # ---- Canonicalize /portal -> /portal/ ----
    location = /portal { return 301 /portal/; }

    # ---- Serve portal assets as static files ----
    location = /portal/portal.css {
        alias /var/www/going.dark/portal/portal.css;
        default_type text/css;
        add_header Cache-Control "public, max-age=300";
    }
    location = /portal/portal.js {
        alias /var/www/going.dark/portal/portal.js;
        default_type application/javascript;
        add_header Cache-Control "public, max-age=300";
    }

    # ---- Proxy /portal/ to the Flask app on localhost:5001 ----
    location /portal/ {
        proxy_pass http://127.0.0.1:5001/;
        proxy_set_header Host              $host;
        proxy_set_header X-Real-IP         $remote_addr;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_read_timeout 60s;
    }

    # ---- Canonicalize /config -> /config/ ----
    location = /config { return 301 /config/; }

    # ---- Serve config assets as static files ----
    location = /config/config.css {
        alias /var/www/going.dark/config/config.css;
        default_type text/css;
        add_header Cache-Control "public, max-age=300";
    }
    location = /config/config.js {
        alias /var/www/going.dark/config/config.js;
        default_type application/javascript;
        add_header Cache-Control "public, max-age=60";
    }

    # ---- Proxy /config/ to the Flask app on localhost:5002 ----
    location /config/ {
        proxy_pass http://127.0.0.1:5002/;

        # Standard proxy headers
        proxy_set_header Host              $host;
        proxy_set_header X-Real-IP         $remote_addr;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        proxy_read_timeout 60s;
    }

    # ---- Canonicalize /adguard -> /adguard/ ----
    location = /adguard { return 301 /adguard/; }

    # ---- Same-origin path mount of AdGuard Home UI under /adguard/ ----
    location ^~ /adguard/ {
        # Strip the /adguard/ prefix before proxying upstream
        proxy_pass http://127.0.0.1:3000/;

        # Headers
        proxy_set_header Host              adguard.home;   # upstream expects this
        proxy_set_header X-Real-IP         $remote_addr;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # WebSocket support (live updates/logs)
        proxy_http_version 1.1;
        proxy_set_header Upgrade    $http_upgrade;
        proxy_set_header Connection "upgrade";

        proxy_read_timeout  300s;
        proxy_send_timeout  300s;

        # Cookie & path scoping so sessions are first-party to going.dark under /adguard/
        proxy_cookie_domain adguard.home going.dark;
        proxy_cookie_path   /           /adguard/;

        # ---- Rewrite upstream redirects (Location headers) to stay under /adguard/ ----
        proxy_redirect ~^(/.*)$ /adguard$1;
        proxy_redirect http://127.0.0.1:3000/  /adguard/;
        proxy_redirect https://127.0.0.1:3000/ /adguard/;
        proxy_redirect https://adguard.home/   /adguard/;


        # ---- Rewrite in-body root-relative URLs (HTML/CSS/JS/JSON) ----
        proxy_set_header Accept-Encoding "";   # allow sub_filter to see text (disable upstream compression)
        sub_filter_once off;
        sub_filter_types text/css application/javascript application/json;

        sub_filter 'href="/'               'href="/adguard/';
        sub_filter 'src="/'                'src="/adguard/';
        sub_filter 'action="/'             'action="/adguard/';
        sub_filter 'content="/'            'content="/adguard/';
        sub_filter 'url(/'                 'url(/adguard/';
        sub_filter 'fetch("/'              'fetch("/adguard/';
        sub_filter "fetch('/"              "fetch('/adguard/";
        sub_filter 'XMLHttpRequest("/'     'XMLHttpRequest("/adguard/';
        sub_filter "XMLHttpRequest('/"     "XMLHttpRequest('/adguard/";

        # Avoid caching admin UI/API
        add_header Cache-Control "no-store" always;

        # ---- Silence ad-tech header ----
        proxy_hide_header Permissions-Policy;
        proxy_hide_header Origin-Trial;
        add_header Permissions-Policy "geolocation=(), camera=(), microphone=(), bluetooth=(), midi=(), usb=()" always;
    }
}


# HTTP -> HTTPS redirect for going.dark
server {
    listen 192.168.77.1:80;
    server_name going.dark;
    return 301 https://$host$request_uri;
}
' | sudo tee /etc/nginx/sites-available/nginx-goingdark > /dev/null

На данном этапе статическая веб-страница и приложения Flask (portal.py и config.py) ещё не установлены или не запущены. Из-за этого перезапуск NGINX сейчас приведёт к ошибке при попытке проксировать запросы к этим сервисам.

Не перезапускайте NGINX пока. Продолжите настройку приложений Flask сначала, и только потом перезагрузите или перезапустите NGINX.


27 СОЗДАНИЕ ПРИЛОЖЕНИЙ FLASK

Войдите в систему под учётной записью admin и установите необходимые системные пакеты:

sudo apt install -y python3-flask python3-venv python3-pip

1. О приложении portal.py


Приложение Flask portal.py предоставляет веб-интерфейс, работающий на 127.0.0.1:5001 и доступный по адресу https://going.dark/portal. Шаблоны HTML встроены непосредственно в приложение, а вспомогательные файлы CSS (portal.css) и JavaScript (portal.js) будут обслуживаться из /var/www/going.dark/portal.

Через этот интерфейс вы сможете подключаться и отключаться от сетей Wi-Fi, запускать и останавливать точку доступа (с новым SSID и паролем, задаваемыми непосредственно из интерфейса), генерировать QR-код для удобного подключения мобильных клиентов к точке доступа, подключаться к вашему WireGuard VPN и маршрутизировать весь трафик через прозрачный прокси Tor. Приложение также отображает ваш текущий IP-адрес и его геолокацию на основе этого IP.

Это приложение интегрируется со следующими компонентами из Части 1:

Поскольку наши приложения Flask будут запускаться в стандартной учётной записи пользователя, необходимо выйти из учётной записи администратора:

exit

2. Подготовка расположения папки

От имени пользователя term7 создайте и перейдите в каталог приложения:

mkdir -p ~/portal && cd ~/portal

3. Настройка зависимостей Python в виртуальном окружении

Создайте виртуальное окружение для приложения Flask:

python3 -m venv .venv

Активируйте виртуальное окружение:

. .venv/bin/activate

Установите и зафиксируйте необходимые библиотеки Python:

pip install --upgrade pip
pip install gunicorn flask segno
pip freeze > requirements.txt

Деактивируйте виртуальное окружение:

deactivate

4. Загрузка portal.py

Загрузите скрипт приложения Flask в папку приложения:

curl -L -o /home/term7/portal/portal.py "https://codeberg.org/term7/Going-Dark/raw/branch/main/Web%20Interface%20Flask%20Apps/portal_app/portal.py"

5. Загрузка portal.css и portal.js

Вернитесь в учётную запись admin:

su admin

Создайте корневой веб-каталог для ресурсов портала:

sudo mkdir -p /var/www/going.dark/portal

Загрузите файлы фронтенда:

sudo curl -L -o /var/www/going.dark/portal/portal.js "https://codeberg.org/term7/Going-Dark/raw/branch/main/Web%20Interface%20Frontend%20Website/portal/portal.js"
sudo curl -L -o /var/www/going.dark/portal/portal.css "https://codeberg.org/term7/Going-Dark/raw/branch/main/Web%20Interface%20Frontend%20Website/portal/portal.css"

6. Создание systemd-сервиса для portal.py

Создайте файл модуля сервиса:

sudo tee /etc/systemd/system/portal.service >/dev/null <<'EOF'
[Unit]
Description=Portal App
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=term7
Group=term7
WorkingDirectory=/home/term7/portal
Environment="PYTHONUNBUFFERED=1"
Environment="PATH=/home/term7/portal/.venv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin"
ExecStart=/home/term7/portal/.venv/bin/python -m gunicorn -w 2 -k gthread --threads 8 --bind 127.0.0.1:5001 --access-logfile - --error-logfile - portal:app
Restart=on-failure
RestartSec=2

[Install]
WantedBy=multi-user.target
EOF

Перезагрузите systemd, затем активируйте и запустите сервис:

sudo systemctl daemon-reload
sudo systemctl enable --now portal.service

7. О файле config.py

Приложение Flask config.py предоставляет веб-интерфейс, работающий на 127.0.0.1:5002 и доступный по адресу https://going.dark/config. Как и в случае с portal.py, шаблоны HTML встроены непосредственно в приложение, а вспомогательные файлы CSS (config.css) и JavaScript (config.js) будут обслуживаться из /var/www/going.dark/config.

Через этот интерфейс вы можете выключить и перезагрузить Raspberry Pi. При перезагрузке приложение автоматически генерирует новую случайную идентичность устройства, назначая новый имя хоста и новый MAC-адрес. Кроме того, оно отображает системные часы, текущий NTP-сервер (последний узел, использованный для синхронизации времени), а также в панели в стиле MOTD показывает диагностическую информацию системы, включая текущую нагрузку, количество запущенных процессов, температуру процессора, использование памяти, использование swap и время работы. Приложение также напрямую интегрируется с веб-интерфейсом, который мы настроим в следующей главе: когда устройство отключено от сети, большинство элементов затемняется, а при возвращении онлайн они снова появляются.

Это приложение интегрируется со следующими компонентами из Части 1:

Поскольку наши приложения Flask будут запускаться в стандартной учётной записи пользователя, снова выйдите из сеанса администратора:

exit

8. Подготовка расположения папки

От имени пользователя term7 создайте и перейдите в каталог приложения:

mkdir -p ~/config && cd ~/config

9. Настройка зависимостей Python в виртуальном окружении

Создайте виртуальное окружение для приложения Flask:

python3 -m venv .venv

Активируйте виртуальное окружение:

. .venv/bin/activate

Установите и зафиксируйте необходимые библиотеки Python:

pip install --upgrade pip
pip install gunicorn flask
pip freeze > requirements.txt

Деактивируйте виртуальное окружение:

deactivate

10. Загрузка config.py

Загрузите скрипт приложения Flask в папку приложения:

curl -L -o /home/term7/config/config.py "https://codeberg.org/term7/Going-Dark/raw/branch/main/Web%20Interface%20Flask%20Apps/config_app/config.py"

5. Загрузка portal.css и portal.js

Вернитесь в учётную запись admin:

su admin

Создайте корневой веб-каталог для ресурсов конфигурации:

sudo mkdir -p /var/www/going.dark/config

Загрузите файлы фронтенда:

sudo curl -L -o /var/www/going.dark/config/config.js "https://codeberg.org/term7/Going-Dark/raw/branch/main/Web%20Interface%20Frontend%20Website/config/config.js"
sudo curl -L -o /var/www/going.dark/config/config.css "https://codeberg.org/term7/Going-Dark/raw/branch/main/Web%20Interface%20Frontend%20Website/config/config.css"

6. Создание systemd-сервиса для config.py

Создайте файл модуля сервиса:

sudo tee /etc/systemd/system/config.service >/dev/null <<'EOF'
[Unit]
Description=Config App
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=term7
Group=term7
WorkingDirectory=/home/term7/config
Environment="PYTHONUNBUFFERED=1"
Environment="PATH=/home/term7/config/.venv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin"
ExecStart=/home/term7/config/.venv/bin/python -m gunicorn -w 2 -k gthread --threads 8 --bind 127.0.0.1:5002 --access-logfile - --error-logfile - config:app
Restart=on-failure
RestartSec=2

[Install]
WantedBy=multi-user.target
EOF

Перезагрузите systemd, затем активируйте и запустите сервис:

sudo systemctl daemon-reload
sudo systemctl enable --now config.service

Не перезапускайте NGINX пока. Продолжите настройку фронтенд-сайта и только потом перезагрузите или перезапустите NGINX.


28 ЗАГРУЗКА ВЕБ-ИНТЕРФЕЙСА УПРАВЛЕНИЯ

После развёртывания фронтенд-сайт будет доступен по адресу https://going.dark. Макет intentionally простой: страница содержит три выдвижные панели, которые можно открывать и закрывать, каждая из которых встраивает iframe: Панель 1 размещает Portal.app, Панель 2 открывает Config.app, а Панель 3 загружает AdGuard Home.

Анимированный фон показывает умножающиеся шары, отражающие модель конфиденциальности Tor: один пользователь выделяется, но по мере появления новых пользователей и выравнивания трафика наблюдателю становится сложнее определить, кто есть кто. Основная идея заключается в том, что по мере роста толпы уменьшается уверенность в первоначальной идентичности.

1. Структура

Каждый файл содержит комментарии, описывающие назначение его разделов:

Главная страница /var/www/going.dark/index.html /var/www/going.dark/style.css

Ресурсы приложения Flask /var/www/going.dark/portal/portal.js /var/www/going.dark/portal/portal.css /var/www/going.dark/config/config.js /var/www/going.dark/config/config.css

Вспомогательные скрипты JavaScript /var/www/going.dark/assets/js/adguard.js /var/www/going.dark/assets/js/canvas.js /var/www/going.dark/assets/js/drawers.js /var/www/going.dark/assets/js/power.js

Ресурсы /var/www/going.dark/assets/fonts/* /var/www/going.dark/assets/favicon.png /var/www/going.dark/assets/term7.svg

2. Загрузка всех файлов

Создайте необходимые каталоги:

sudo mkdir -p /var/www/going.dark/assets/{js,fonts}

Загрузите HTML-, CSS- и JavaScript-файлы:

sudo curl -fL -o /var/www/going.dark/index.html "https://codeberg.org/term7/Going-Dark/raw/branch/main/Web%20Interface%20Frontend%20Website/index.html"
sudo curl -fL -o /var/www/going.dark/style.css "https://codeberg.org/term7/Going-Dark/raw/branch/main/Web%20Interface%20Frontend%20Website/style.css"
sudo curl -fL -o /var/www/going.dark/assets/js/adguard.js "https://codeberg.org/term7/Going-Dark/raw/branch/main/Web%20Interface%20Frontend%20Website/assets/js/adguard.js"
sudo curl -fL -o /var/www/going.dark/assets/js/canvas.js "https://codeberg.org/term7/Going-Dark/raw/branch/main/Web%20Interface%20Frontend%20Website/assets/js/canvas.js"
sudo curl -fL -o /var/www/going.dark/assets/js/drawers.js "https://codeberg.org/term7/Going-Dark/raw/branch/main/Web%20Interface%20Frontend%20Website/assets/js/drawers.js"
sudo curl -fL -o /var/www/going.dark/assets/js/power.js "https://codeberg.org/term7/Going-Dark/raw/branch/main/Web%20Interface%20Frontend%20Website/assets/js/power.js"

Загрузите значки и шрифты:

sudo curl -fL -o /var/www/going.dark/assets/favicon.png "https://codeberg.org/term7/Going-Dark/raw/branch/main/Web%20Interface%20Frontend%20Website/assets/favicon.png"
sudo curl -fL -o /var/www/going.dark/assets/term7.svg "https://codeberg.org/term7/Going-Dark/raw/branch/main/Web%20Interface%20Frontend%20Website/assets/term7.svg"
sudo curl -fL -o /var/www/going.dark/assets/fonts/ANON-DIGITAL_italic.ttf "https://codeberg.org/term7/Going-Dark/raw/branch/main/Web%20Interface%20Frontend%20Website/assets/fonts/ANON-DIGITAL_italic.ttf"
sudo curl -fL -o /var/www/going.dark/assets/fonts/ANON-DIGITAL_italic.woff "https://codeberg.org/term7/Going-Dark/raw/branch/main/Web%20Interface%20Frontend%20Website/assets/fonts/ANON-DIGITAL_italic.woff"
sudo curl -fL -o /var/www/going.dark/assets/fonts/ANON-DIGITAL_italic.woff2 "https://codeberg.org/term7/Going-Dark/raw/branch/main/Web%20Interface%20Frontend%20Website/assets/fonts/ANON-DIGITAL_italic.woff2"
sudo curl -fL -o /var/www/going.dark/assets/fonts/ANON-DIGITAL_normal.ttf "https://codeberg.org/term7/Going-Dark/raw/branch/main/Web%20Interface%20Frontend%20Website/assets/fonts/ANON-DIGITAL_normal.ttf"
sudo curl -fL -o /var/www/going.dark/assets/fonts/ANON-DIGITAL_normal.woff "https://codeberg.org/term7/Going-Dark/raw/branch/main/Web%20Interface%20Frontend%20Website/assets/fonts/ANON-DIGITAL_normal.woff"
sudo curl -fL -o /var/www/going.dark/assets/fonts/ANON-DIGITAL_normal.woff2 "https://codeberg.org/term7/Going-Dark/raw/branch/main/Web%20Interface%20Frontend%20Website/assets/fonts/ANON-DIGITAL_normal.woff2"
sudo curl -fL -o /var/www/going.dark/assets/fonts/Handwriting.ttf "https://codeberg.org/term7/Going-Dark/raw/branch/main/Web%20Interface%20Frontend%20Website/assets/fonts/Handwriting.ttf"
sudo curl -fL -o /var/www/going.dark/assets/fonts/Handwriting.woff "https://codeberg.org/term7/Going-Dark/raw/branch/main/Web%20Interface%20Frontend%20Website/assets/fonts/Handwriting.woff"
sudo curl -fL -o /var/www/going.dark/assets/fonts/Handwriting.woff2 "https://codeberg.org/term7/Going-Dark/raw/branch/main/Web%20Interface%20Frontend%20Website/assets/fonts/Handwriting.woff2"

3. Права собственности и разрешения

Поскольку файлы были загружены от имени root, по умолчанию они принадлежат root. Чтобы обеспечить единообразие прав собственности во всём корневом каталоге веб-сервера, настройте разрешения следующим образом:

sudo chown -R www-data:www-data /var/www/going.dark

4. Перезапуск NGINX

Наконец, перезапустите NGINX, чтобы изменения вступили в силу:

sudo nginx -t
sudo systemctl restart nginx
Войдите, чтобы оставить комментарий