Trojan-Go на Ubuntu 24.04: пошаговая установка
Если провайдер режет OpenVPN и WireGuard по сигнатуре трафика, а VLESS Reality кажется избыточно сложным, Trojan-Go — рабочий средний вариант: протокол буквально притворяется обычным HTTPS-сайтом, причём с настоящим доменом и настоящим сертификатом от Let's Encrypt, а не с самоподписанной подделкой. Разберём установку с нуля на Ubuntu 24.04: домен, TLS, конфигурация Trojan-Go и связка с Nginx, который отдаёт сайт-прикрытие любому, кто постучится без правильного пароля.
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Что такое Trojan-Go и зачем нужна маскировка
Trojan-Go — переписанный на Go форк оригинального проекта Trojan, с добавленными мультиплексированием (mux), поддержкой WebSocket-транспорта и плагинов на манер Shadowsocks. Идея протокола осталась прежней и в этом его сила: сервер поднимает обычный TLS 1.3 на 443-м порту с реальным сертификатом, и снаружи соединение неотличимо от захода на любой HTTPS-сайт. Отличие VPN-клиента от браузера скрыто не в TLS-рукопожатии, а внутри уже зашифрованного потока — там передаётся пароль, и только сервер, зная его, распознаёт «своего» клиента.
Ключевая разница с VLESS Reality: Reality заимствует TLS-рукопожатие чужого настоящего сайта, не имея собственного сертификата. Trojan-Go идёт другим путём — у него свой домен и свой валидный сертификат от публичного удостоверяющего центра. Если клиент подключается с неверным паролем (или это вообще не Trojan-клиент, а сканер DPI или обычный браузер), сервер прозрачно перенаправляет соединение на локальный веб-сервер, который отдаёт настоящий сайт. Активная проверка домена — «зайти и посмотреть, что там» — не выдаёт VPN, потому что там действительно лежит сайт.
Плата за это — необходимость в реальном домене, привязанном к серверу, и постоянной поддержке сертификата. Это чуть больше подготовки, чем для WireGuard или Shadowsocks, но не сложнее, чем для любого HTTPS-сайта на Nginx.
Что понадобится: домен и сервер
Перед установкой убедитесь, что есть:
- VPS с Ubuntu 24.04 — хватает 1 vCPU и 1 ГБ RAM, диска достаточно нескольких гигабайт;
- домен или поддомен, у которого A-запись указывает на IP сервера (например,
vpn.example.com); - открытые порты 80/tcp (для выпуска и продления сертификата) и 443/tcp (для самого Trojan-Go).
Если ещё не выбирали, под какой сценарий брать сервер и протокол, посмотрите гид по выбору протокола VPN — Trojan-Go имеет смысл именно там, где важна маскировка под легитимный HTTPS-трафик, а не просто быстрый личный туннель.
Проверить, что A-запись уже применилась, можно так:
dig +short vpn.example.com
Вывод должен совпадать с IP вашего сервера. Без этого шага certbot не сможет подтвердить владение доменом, а клиенты будут получать ошибку сертификата.
Арендуйте сервер под свои задачи!
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверNginx как сайт-прикрытие
Сначала поднимаем обычный сайт — именно его увидит любой, кто зайдёт на домен без Trojan-пароля. Ставим Nginx и минимальную статику:
apt update && apt install -y nginx
mkdir -p /var/www/decoy
Положите в /var/www/decoy любую правдоподобную статику — шаблон лендинга, документацию, страницу-заглушку компании. Важно, чтобы сайт выглядел живым, а не как явный «пустой» decoy-шаблон с одной строчкой текста — это тоже частая примета обфусцированного VPN при ручной проверке.
Конфиг /etc/nginx/sites-available/decoy:
server {
listen 80;
listen [::]:80;
server_name vpn.example.com;
root /var/www/decoy;
index index.html;
location /.well-known/acme-challenge/ {
root /var/www/decoy;
}
}
Обратите внимание: Nginx слушает только 80-й порт. 443-й порт целиком отдаётся Trojan-Go — Nginx на нём работать не будет, это принципиально для схемы. Активируйте конфиг и перезапустите:
ln -s /etc/nginx/sites-available/decoy /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx
systemctl enable nginx
Откройте http://vpn.example.com в браузере — должна отдаться ваша заглушка. Если материал про Nginx как таковой интересен отдельно, есть разбор Nginx как reverse-proxy на Ubuntu 24.04 — здесь роль Nginx проще: только фолбэк-сайт, без проксирования наружу.
Сертификат Let's Encrypt
Ставим certbot и получаем сертификат через уже работающий на 80-м порту Nginx (webroot-режим — Trojan-Go пока не занял 443-й, конфликтов не будет):
apt install -y certbot
certbot certonly --webroot -w /var/www/decoy -d vpn.example.com
Certbot спросит e-mail для уведомлений об истечении и попросит согласиться с условиями. После успешного выпуска сертификат и ключ окажутся в:
/etc/letsencrypt/live/vpn.example.com/fullchain.pem
/etc/letsencrypt/live/vpn.example.com/privkey.pem
Продление у certbot автоматическое через systemd-таймер (certbot.timer), но после каждого продления Trojan-Go нужно перезапустить, чтобы он подхватил новые файлы — сам процесс не отслеживает их изменение налету. Добавьте deploy-хук:
mkdir -p /etc/letsencrypt/renewal-hooks/deploy
cat > /etc/letsencrypt/renewal-hooks/deploy/trojan-go.sh << 'EOF'
#!/bin/bash
systemctl restart trojan-go
EOF
chmod +x /etc/letsencrypt/renewal-hooks/deploy/trojan-go.sh
Если раньше не занимались автоматизацией сертификатов, есть отдельный подробный разбор установки Let's Encrypt SSL на VPS — там про webroot, DNS-01 и типичные грабли продления.
Установка Trojan-Go
Готового пакета в репозиториях Ubuntu нет — ставим бинарник из релизов проекта p4gefau1t/trojan-go на GitHub. Проверьте актуальную версию на странице релизов и подставьте её вместо примера:
cd /usr/local/src
wget https://github.com/p4gefau1t/trojan-go/releases/download/<версия>/trojan-go-linux-amd64.zip
apt install -y unzip
unzip trojan-go-linux-amd64.zip -d trojan-go
mv trojan-go/trojan-go /usr/local/bin/trojan-go
chmod +x /usr/local/bin/trojan-go
mkdir -p /etc/trojan-go
Проверьте, что бинарник рабочий:
trojan-go --version
Конфигурация: TLS и фолбэк на Nginx
Всё поведение задаётся одним JSON-файлом /etc/trojan-go/config.json. Ключевые параметры — порт 443 для приёма клиентов, пароль (или несколько), пути к сертификату и, главное, remote_addr/remote_port — адрес фолбэка, куда уходит трафик без верного пароля:
{
"run_type": "server",
"local_addr": "0.0.0.0",
"local_port": 443,
"remote_addr": "127.0.0.1",
"remote_port": 80,
"password": [
"замените-на-длинный-случайный-пароль"
],
"ssl": {
"cert": "/etc/letsencrypt/live/vpn.example.com/fullchain.pem",
"key": "/etc/letsencrypt/live/vpn.example.com/privkey.pem",
"sni": "vpn.example.com"
},
"mux": {
"enabled": true
},
"websocket": {
"enabled": false
}
}
Логика простая: Trojan-Go сам терминирует TLS на 443-м порту (сертификат берёт из тех же файлов, что выпустил certbot). Дальше он читает первые байты расшифрованного потока — если это валидный Trojan-заголовок с верным паролем из списка, соединение превращается в прокси-туннель. Если нет — весь трафик как есть прозрачно перенаправляется на remote_addr:remote_port, то есть на локальный Nginx (127.0.0.1:80), который и отдаёт настоящий сайт. Именно эта пара «TLS с настоящим сертификатом + фолбэк на реальный HTTP-сервер» и называется «работой поверх Nginx» — Nginx физически не участвует в обработке VPN-трафика, а служит витриной для всех остальных.
Пароль генерируйте длинным и случайным, не словарным словом:
openssl rand -base64 24
Держите файл config.json в правах 600 — в нём открытым текстом лежит пароль:
chmod 600 /etc/trojan-go/config.json
Автозапуск через systemd и проверка
Unit-файла в архиве нет, создаём вручную /etc/systemd/system/trojan-go.service:
[Unit]
Description=Trojan-Go Service
After=network.target nginx.service
[Service]
Type=simple
ExecStart=/usr/local/bin/trojan-go -config /etc/trojan-go/config.json
Restart=on-failure
RestartSec=5s
User=root
[Install]
WantedBy=multi-user.target
Применяем и включаем автозапуск:
systemctl daemon-reload
systemctl enable trojan-go
systemctl start trojan-go
systemctl status trojan-go
В статусе должно быть active (running). Если сервис падает сразу после старта — почти всегда дело в правах на файлы сертификата (процесс запущен под root, так что обычно проблем нет) или в синтаксической ошибке JSON — проверьте вывод journalctl -u trojan-go -n 50.
Откройте порты в firewall, если используете ufw — подробный разбор настройки есть в статье про UFW на Ubuntu 24.04:
ufw allow 80/tcp
ufw allow 443/tcp
Проверка со стороны сервера — запрос без пароля должен получить содержимое decoy-сайта, а не ошибку:
curl -sk https://vpn.example.com | head
Для реального подключения нужен Trojan-совместимый клиент (например, приложение на базе trojan-go или Xray с протоколом trojan, поддерживается большинством кроссплатформенных клиентов через строку trojan://пароль@vpn.example.com:443?sni=vpn.example.com#имя-профиля). Подставьте свой пароль и домен — клиент подключится, пройдёт TLS-рукопожатие как к обычному сайту, и уже внутри туннеля пароль подтвердит, что это не случайный визитёр.
Арендуйте сервер под свои задачи!
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Чем Trojan-Go принципиально отличается от Shadowsocks?
Shadowsocks шифрует трафик собственным протоколом, который при внимательном DPI-анализе можно отличить от стандартного TLS по статистическим признакам пакетов. Trojan-Go использует настоящий TLS 1.3 с валидным сертификатом — по форме рукопожатия он неотличим от HTTPS. Сравнение сценариев есть в статье Shadowsocks или VLESS — что выбрать.
Можно ли обойтись без своего домена?
Нет — без домена не выпустить сертификат от публичного CA, а без валидного сертификата теряется весь смысл протокола: клиент-браузер моментально увидит предупреждение о недоверенном сертификате при попытке зайти на IP напрямую. Это главное архитектурное отличие от VLESS Reality, где чужой сертификат заимствуется без собственного домена.
Что если certbot не может подтвердить домен?
Чаще всего порт 80 закрыт в firewall или A-запись ещё не применилась (DNS может кэшироваться до нескольких часов). Проверьте dig +short ваш-домен и curl -I http://ваш-домен/.well-known/acme-challenge/test — должен быть ответ от сервера, а не таймаут.
Нужно ли включать websocket-транспорт?
Не обязательно для базовой настройки. WebSocket полезен, когда трафик дополнительно проксируется через CDN (например, Cloudflare) — тогда Trojan-Go-соединение прячется за обычный веб-запрос ещё на один уровень. Для прямого подключения к своему серверу это не нужно и добавляет лишнюю задержку.
Как добавить несколько пользователей с разными паролями?
Просто перечислите несколько строк в массиве password в config.json и перезапустите сервис — каждый пароль работает независимо, отдельных учётных записей заводить не нужно.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →