Ещё более изощренный обход блокировок с помощью Shadowsocks + V2Ray + Cloudflare March 19, 2022 on Savely Krasovsky's blog

В прошлой статье я разобрал вариант с Cloak, однако меня не устроила умеренная сложность конфигурации клиентской части, а также меньшая популярность и, следовательно, развитие проекта по сравнению с V2Ray.

Использование Cloudflare в описанном ниже способе позволило повысить пропускную способность канала. На Нидерландском сервере я получил в районе 450 мегабит через Cloudflare, вместо 250-300 напрямую с Cloak.

План

Весь трафик завернуть на Cloudflare, который отправит его к нам на VPS. Сдобрить обфускацией от V2Ray и сам сервер спрятать под видом совершенно безобидного ресурса.

На практике это будет выглядеть как-то так

Ингредиенты

  1. VPS в Европе.
  2. Домен в любой зоне (желательно не .ru/.su/.рф)
  3. Аккаунт на Cloudflare.
  4. shadowsocks-rust.
  5. v2ray-plugin (лучше использовать форк, там свежий v2ray-core).
  6. HTTP-сервер, nginx в нашем случае.
  7. SSL-сертификат полученный от Let’s Encrypt или непосредственно Cloudflare.

Рецепт

  1. Ставим в систему shadowsocks-rust и v2ray-plugin, сконфигурировать их легко вот таким конфигом в /etc/shadowsocks-rust/v2ray.json:
{
  "server": "localhost",
  "server_port": 8443,
  "method": "chacha20-ietf-poly1305",
  "password": "yourpass",
  "plugin": "v2ray-plugin",
  "plugin_opts": "server"
}
  1. Создаём для Shadowsocks systemd-сервис по аналогии с прошлой статьёй (пункты 5-7).
  2. Получаем сертификат через certbot или через Cloudflare. Детально расписывать не буду, инструкций в интернете масса.
  3. Ставим nginx, заводим следующий конфиг в /etc/nginx/sites-available/v2ray:
server {
	listen 80;
	server_name _;

	return 301 https://$host$request_uri;
}

server {
	listen 443 ssl http2;
	server_name yourdomain.wtf;

	ssl_certificate			/etc/letsencrypt/live/yourdomain.wtf/fullchain.pem;
	ssl_certificate_key		/etc/letsencrypt/live/yourdomain.wtf/privkey.pem;
	ssl_trusted_certificate		/etc/letsencrypt/live/yourdomain.wtf/chain.pem;

	# Здесь можно проксировать запросы на какой-нибудь весёлый сайт
	location / {
		proxy_pass https://innocent.domain.lol;
	}

	# Локацию можно сделать длинной, чтобы её никто не смог угадать.
	location /v2ray {
		proxy_set_header	Host		$http_host;
		proxy_set_header	Upgrade		$http_upgrade;
		proxy_set_header	Connection	"upgrade";

		proxy_http_version 1.1;
		proxy_buffering off;
		proxy_redirect off;

		proxy_pass http://localhost:8443/;
	}
}

Не забудьте сделать symlink и перезагрузить nginx:

# ln -s /etc/nginx/sites-available/v2ray /etc/nginx/sites-enabled/v2ray
# systemctl reload nginx
  1. Заходим в Cloudflare в раздел DNS, создаём A-запись, указывающую на ваш сервер, оставляем Proxy включенным.
  2. В разделе SSL/TLS включаем режим Full (strict), минимальную версию TLS можно повысить до 1.2/1.3 в зависимости от поддержки актуальных протоколов вашими устройствами.
  3. Наконец настроим клиент:
{
  "server": "yourdomain.wtf",
  "server_port": 443,
  "method": "chacha20-ietf-poly1305",
  "password": "yourpass",
  "plugin": "v2ray-plugin",
  "plugin_opts": "tls;host=yourdomain.wtf;path=/v2ray",
  "local_address": "localhost",
  "local_port": 1080
}

Рекомендации

Опционально можно прокачать производительность, и увеличить безопасность. Максимальное количество файлов рассчитано по формуле 1 ядро = 65536 файловых дескриптора.

/etc/sysctl.d/20-shadowsocks.conf
# options for shadowsocks
fs.file-max = 262144
net.core.rmem_max = 8388608
net.core.wmem_max = 8388608
net.core.rmem_default = 8388608
net.core.wmem_default = 8388608
net.core.optmem_max = 8388608
net.core.netdev_max_backlog = 262144
net.core.somaxconn = 262144
net.ipv4.ip_local_port_range = 1024 65535
net.ipv4.tcp_mem = 25600 51200 102400
net.ipv4.tcp_rmem = 4096 1048576 4194304
net.ipv4.tcp_wmem = 4096 1048576 4194304
net.ipv4.tcp_fastopen=3
net.ipv4.tcp_low_latency = 1
net.ipv4.tcp_no_metrics_save = 1
net.ipv4.tcp_adv_win_scale = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_keepalive_time = 150
net.ipv4.tcp_keepalive_probes = 5
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_synack_retries = 1
net.ipv4.tcp_slow_start_after_idle=0
net.ipv4.tcp_max_syn_backlog = 65536
net.ipv4.tcp_max_tw_buckets = 720000
net.ipv4.tcp_mtu_probing = 1
/etc/nginx/nginx.conf
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
	worker_connections 4096;
	multi_accept on;
	use epoll;
	epoll_events 512;
}

http {

	##
	# Basic Settings
	##

	sendfile on;
	tcp_nopush on;
	tcp_nodelay on;
	keepalive_timeout 60;
	client_body_timeout 12;
	client_header_timeout 12;
	send_timeout 30;
	keepalive_requests 2000;
	reset_timedout_connection on;
	types_hash_max_size 2048;
	server_tokens off;
	server_names_hash_max_size 4096;

	client_body_buffer_size 128K;
	client_header_buffer_size 3m;
	client_body_in_single_buffer on;
	client_max_body_size 8m;
	large_client_header_buffers 4 256k;

	open_file_cache max=200000 inactive=20s;
	open_file_cache_valid 30s;
	open_file_cache_min_uses 2;
	open_file_cache_errors on;

	include /etc/nginx/whitelist.conf;

	include /etc/nginx/mime.types;
	default_type application/octet-stream;

	##
	# SSL Settings
	##

	ssl_session_timeout 1d;
	ssl_session_cache shared:MozSSL:10m;
	ssl_session_tickets off;

	ssl_protocols TLSv1.3;
	ssl_prefer_server_ciphers off;

	ssl_stapling on;
	ssl_stapling_verify on;

	##
	# Logging Settings
	##

	#access_log /var/log/nginx/access.log;
	error_log /var/log/nginx/error.log crit;

	##
	# Gzip Settings
	##

	gzip off;

	# gzip_vary on;
	# gzip_proxied any;
	# gzip_comp_level 6;
	# gzip_buffers 16 8k;
	# gzip_http_version 1.1;
	# gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

	##
	# Virtual Host Configs
	##

	include /etc/nginx/conf.d/*.conf;
	include /etc/nginx/sites-enabled/*;
}
/etc/nginx/whitelist.conf
allow 173.245.48.0/20;
allow 103.21.244.0/22;
allow 103.22.200.0/22;
allow 103.31.4.0/22;
allow 141.101.64.0/18;
allow 108.162.192.0/18;
allow 190.93.240.0/20;
allow 188.114.96.0/20;
allow 197.234.240.0/22;
allow 198.41.128.0/17;
allow 162.158.0.0/15;
allow 104.16.0.0/13;
allow 104.24.0.0/14;
allow 172.64.0.0/13;
allow 131.0.72.0/22;

allow 2400:cb00::/32;
allow 2606:4700::/32;
allow 2803:f800::/32;
allow 2405:b500::/32;
allow 2405:8100::/32;
allow 2a06:98c0::/29;
allow 2c0f:f248::/32;

deny all;
/etc/security/limits.conf

Добавляем:

session required pam_limits.so
/etc/security/limits.conf

Добавляем:

* soft nofile 262144
* hard nofile 262144
/etc/shadowsocks-rust/v2ray.json

Конфигурацию v2ray можно привести к следующему виду:

{
  "server": "localhost",
  "server_port": 8443,
  "password": "yourpass",
  "method": "chacha20-ietf-poly1305",
  "timeout": 7200,
  "no_delay": true,
  "nofile": 262144,
  "fast_open": true,
  "plugin": "v2ray-plugin",
  "plugin_opts": "server"
}