В предыдущем посте, я описывал, что такое shadowsock и как он позволяет поднять зашифрованый канал связи через локальный прокси. В этой статье, я хочу поделится способом как можно замаскировать трафик shadowsock используя плагин v2ray. Подобная маскировка может быть полезной когда требуется обойти фильтры провайдера которые фильтруют трафик используя сложные алгоритмы DPI — глубокого анализа данных, что позволяет фильтрующим системам резать запросы отправленные через VPN или TOR, shadowsocks и плагин v2ray вполне могут решить эту проблему.
! Важное дополнение. Данный материал приводится исключительно в образовательных и исследовательских целях. Не в коем случае не повторяйте это в реальности, если подобное запрещено законодательством страны в которой вы живете !
Что потребуется для настройки:
- Отдельный хостинг, можете попробовать, например, вот этот
- Локальный компьютер с Mac OS ( но на любой машине c *nix тоже заработает с минимальными изменениями )
Первое что потребуется сделать, это установка shadowsock о которой можно почитать тут — Устанавливаем Shadowsocks на свой сервер
Сразу же после того как вы установили shadownsock обезательно настройти фаервол сервера, чтобы он не блокировал трафик shadowsocks, я использую обычно ufw интерфейс к iptables, но можно настроить напрямую задав правила iptables
# Очистка всех правил iptables ufw disable ufw reset ufw default deny incoming ufw default allow outgoing iptables -F iptables -X iptables -t nat -F iptables -t nat -X iptables -t mangle -F iptables -t mangle -X iptables -P INPUT ACCEPT iptables -P FORWARD ACCEPT iptables -P OUTPUT ACCEPT # Добавление базовых правил ufw allow 'OpenSSH' # потребуется для настройки v2ray ufw allow 'Nginx Full' # этот порт оставляем для shadowsock ufw allow 8080/tcp # Проверем! Тут важно, если порт SSH не открыт то сессия будет завершена и вы не сможете подключиться снова ufw list # если все верно, то включаем ufw enable
Теперь нужно приступить к установки плагина для shadowsocks. В моей системе на сервере его не было поэтому я скачивал из репозитория, только перед скачиванием архива нужно проверить какая у вас система на сервере и выбрать подходящий архив для своей системы ( amd64/368/etc )
wget https://github.com/shadowsocks/v2ray-plugin/releases/download/v1.3.2/v2ray-plugin-linux-386-v1.3.2.tar.gz tar -xzf v2ray-plugin-linux-368-*.tar.gz mv v2ray-plugin_linux_amd64 /usr/local/bin/v2ray-plugin chmod +x /usr/local/bin/v2ray-plugin
Теперь нужно поправить конифги сервера shadawsocks ( ss-server ) я создал конфиг в директории /etc для этого, но его можно создать где угодно, главное при запуске ss-server указать путь к нему
{ "server":["0.0.0.0","::1"], "mode":"tcp_and_udp", "server_port":8080, "password":"password", "timeout":300, "method":"chacha20-ietf-poly1305", "plugin": "v2ray-plugin", "plugin_opts": "server;tls;host=mydomain.ru;cert=/etc/letsencrypt/archive/mydomain.ru/fullchain1.pem;key=/etc/letsencrypt/archive/mydomain.ru/privkey1.pem", "fast_open": true }
Теперь подробнее об параметрах:
- server — тут нужно указать ip по которым можно будет подключаться к серверу по протоколу shadowsock для создания зашифрованого туннеля, 0.0.0.0 — разрешает все подключения для ip4, ::1 — разрешает все подключения для ip6 соответственно
- mode — разрешает устанавливать соединение и по tcp и по udp
- password — пароль подключения
- method — метод шифрования, в данном случае приведен метод chacha20-ietf-poly1305 это быстрый безопасный метод потокового шифрования, если по каким-то причинам нужен другой, то список поддерживаемых методов можно узнать командой ss-server —help
- plugin — подключаем плагин маскировки v2ray-plugin
- plugin_opts — тут передаются настройки для плагина v2ray-plugin, но о них я напишу далее более подробно
- fast_open — ускоряет tcp соединение
Тут требуется более подробно остановится на плагине и переданных опциях
v2ray-plugin для Shadowsocks — это плагин, который добавляет поддержку протокола VMess (из проекта V2Ray) к Shadowsocks, маскируя трафик под обычный HTTPS и улучшая обход блокировок. Для того чтобы он заработал потребуется реальный домен и сертификат безопасности ( подойдет letsencrypt ), поэтому на данном этапе нужно запустить web сервер и привязать к нему какой-либо домен или субдомен, например, вот так можно настроить nginx для v2ray:
server { if ($host = mydomain.ru) { return 301 https://$host$request_uri; } # managed by Certbot listen 80; server_name mydomain.ru; return 301 https://$host$request_uri; } server { listen 443 ssl; server_name mydomain.ru; location / { # Встраиваем плеер с радио (пример для Lofi Girl) add_header Content-Type text/html; return 200 ' <!DOCTYPE html> <html> <head> <title>Стрим 24 онлайн</title> </head> <body> <iframe src="https://www.youtube.com/embed/jfKfPfyJRdk?autoplay=1" allow="autoplay; fullscreen" allowfullscreen ></iframe> </body> </html> '; } ssl_certificate /etc/letsencrypt/live/mydomain.ru/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/mydomain.ru/privkey.pem; # managed by Certbot }
Как видите тут для примера я использовал генерацию сертификатов командой Cerbot но можно создать сертификат любым способом. После настройки web сервера и создания сертификатов под ваш домен требуется прописать пути к сертификату в настройках плагина в shadownsock.json
server;tls;host=mydomain.ru;cert=/etc/letsencrypt/archive/mydomain.ru/fullchain1.pem;key=/etc/letsencrypt/archive/mydomain.ru/privkey1.pem
тут важно отметить, что в конфигрурации сервера в опциях плагина вначале требуется указать server и еще один важный момент, опция не понимает путь к символьной ссылке поэтому потребуется указать путь на реальный файл ( не знаю почему так, но с указанием символьной ссылки у меня не получилось запуститься ) так же нужно будет учитывать это при обновлении сертификата ( например в кроджобе автоматического обновления сертификата можно указать так же выполнение своего скрипта который будет редактировать /etc/shadowsock.json и прописывать путь к актуальным обновленным сертфикатам
На этом в целом настройка конфига на сервере закончина. Далее потребуется перезапустить сам сервис. В прошлой статье про shadownsock я показывал как запустить ss сервер при помощи сервиса из пакета shadowsocks-libev но с добавлением плагина v2ray перестал работать запуск поэтому я решил написать свою службу для запуска, тут приведу интсрукции как создать новую службу и добавить ее в systemctl на сервер с Ubuntu
vim /etc/systemd/system/shadowsocks.service
и добавляем туда
[Unit] Description=Shadowsocks Server with V2Ray-Plugin After=network.target [Service] Type=simple # Запуск сервера с подготовленным конфигом с плагином v2ray ExecStart=/usr/bin/ss-server -c /etc/shadowsocks.json Restart=always RestartSec=3 Environment="HOME=/tmp" # Если используете TLS-сертификаты: ReadWritePaths=/etc/letsencrypt/live/mydomain.ru/ ReadWritePaths=/etc/letsencrypt/archive/mydomain.ru/ NoNewPrivileges=no [Install] WantedBy=multi-user.target ~
После добавления регистрируем новую службу командой
systemctl daemon-reload
И запускаем сервис
systemctl start shadowsocks systemctl enable shadowsocks
На этом серверная часть готова и можно переходить к настройкам клиента.
Есть множество клиентов для разных систем и мобильных ОС, я решил использовать для себя самый простой консольный клиент ss-local а для этого потребуется установить его на ваш компьютер в зависимости от того какая у вас система, на маке это выглядет так
brew install shadowsocks-libev
И установка вручную плагина v2ray так как в репозитории brew его нет
wget https://github.com/shadowsocks/v2ray-plugin/releases/download/v1.3.2/v2ray-plugin-darwin-amd64-v1.3.2.tar.gz tar -xzf v2ray-plugin-darwin-amd64-v1.3.2.tar.gz sudo mv v2ray-plugin_darwin_amd64 /usr/local/bin/v2ray-plugin sudo chmod +x /usr/local/bin/v2ray-plugin
И далее я реализовал небольшой скрипт bash для использования ss-local
vim ss-tunnel.sh
#!/bin/bash # Путь к конфигурационному файлу CONFIG_FILE="$HOME/.ss/config.json" LOG_FILE="/tmp/ss-local.log" # Проверяем наличие конфига if [ ! -f "$CONFIG_FILE" ]; then echo -e "\033[31mОшибка:\033[0m Конфигурационный файл $CONFIG_FILE не найден." exit 1 fi # Получаем локальный порт из конфига LOCAL_PORT=$(jq -r '.local_port' "$CONFIG_FILE" 2>/dev/null || { echo -e "\033[33mПредупреждение:\033[0m Не удалось прочитать local_port, используем 1080" echo "1080" }) ss_stop() { pkill -f "ss-local -c $CONFIG_FILE" } ss_start() { echo "Запускаем ss-local с конфигом $CONFIG_FILE..." ss-local -c "$CONFIG_FILE" -v &> "$LOG_FILE" & SS_LOCAL_PID=$! # Даем время на подключение for i in {1..5}; do echo -n "." sleep 1 done echo } ss_check() { CHECK_URL="https://ifconfig.me" echo "Проверяем подключение через SOCKS5 (порт $LOCAL_PORT)..." if curl --socks5 "127.0.0.1:$LOCAL_PORT" --connect-timeout 10 -s "$CHECK_URL" &> /dev/null; then EXTERNAL_IP=$(curl --socks5 "127.0.0.1:$LOCAL_PORT" -s "$CHECK_URL") echo -e "\033[32mУспех!\033[0m Туннель работает. Ваш внешний IP: $EXTERNAL_IP" echo "Для остановки выполните: pkill -f 'ss-local -c $CONFIG_FILE'" else echo -e "\033[31mОшибка!\033[0m Не удалось подключиться через туннель." echo "Последние строки лога:" tail -n 5 "$LOG_FILE" kill -9 "$SS_LOCAL_PID" &> /dev/null exit 1 fi } ss_log() { tail -f $LOG_FILE } ss_status() { if lsof -i :1080 >/dev/null 2>&1; then echo echo "🟢 PROXY: 1080" echo else echo echo "🔴 PROXY: DISCONECT" echo fi } case "$1" in start) ss_start ;; stop) ss_stop ;; restart) ss_stop sleep 2 ss_start ;; status) ss_status ;; log) ss_log ;; *) echo "Использование: $0 {start|stop|restart|status|log}" exit 1 esac exit 0
Основная команда запуска тут ss-local -c «$CONFIG_FILE» -v &> «$LOG_FILE» &
в которую передается конфиг $CONFIG_FILE, я использую отдельную директорию в домашней директории пользователя для хранения конфига ~/.ss/config.json
Содержимое config.json на стороне клиента должно быть таким:
{ "server": "<ip_server>", "server_port": 8080, "local_port": 1080, "password": "password", "method": "chacha20-ietf-poly1305", "plugin": "v2ray-plugin", "plugin_opts": "tls;host=mydomain.ru", "timeout": 300 }
Тут более менее понятно:
- server — указываете ip вашего сервера
- server_port — указываете порт сервера на котором запущен ss ( мы настроили выше сервер на раобту с портом 8080 )
- local_port — указывается локальный порт клиента на котором будет стартовать sock5 служба
- plugin — v2ray для маскировки трафика
- method — должен совпадать с серверным методом шифрования
- plugin_opts — тут нужно указать tsl; и ваш реальный домен на вашем хосте сертификаты которого прописаны в серверном конфиге
Все! После теперь можно добавить прав скрипту и можно попробовать запустить тоннель shadownsocks замаскерованный под https запрос
chmod +x ss-tonnel.sh ./ss-tunnel.sh
После этого должна запуститься служба на порту 1080 через которую можно будет подключить приложение поддерживающие прокси соединения для установки безопасного замаскированного канала соединения. Проверить можно например исполнив команду curl с подключением через прокси на 1080 порту
curl --socks5 "127.0.0.1:1080 https://ifconfig.me
В ответ на команду должен прейти ответ с ip сервера
Что можно добавить из плюшек, например, если вы хотите пропустить весь трафик через защищенный замаскированный канал, то используйте VPN подключенный через ss тоннель.
Для мониторинга соединения можно использовать небольшой скрипт в .zshrc который будет отображать активность proxy
vim ~/.zshrc ... function proxy_status() { if lsof -i :1080 >/dev/null 2>&1; then echo "🟢 PROXY: %F{green}1080%f" else echo "🔴 PROXY: %F{red}DISCONECT%f" fi } ... # автообновление промпта TMOUT=5 # и далее в удобное место добавляете PROMPT='... $(proxy_status) ... ' # для
На этом пока что все.