mirror of
https://github.com/EvgenyNerush/easy-xray.git
synced 2024-11-21 16:25:23 +03:00
add CDN support at the second ip address
This commit is contained in:
parent
78762bbb58
commit
520bca6992
9 changed files with 530 additions and 19 deletions
1
CDN.md
Normal file
1
CDN.md
Normal file
|
@ -0,0 +1 @@
|
|||
TODO
|
32
CDN.ru.md
Normal file
32
CDN.ru.md
Normal file
|
@ -0,0 +1,32 @@
|
|||
#### Дополнительный канал связи
|
||||
|
||||
Если вы делитесь доступом к своему серверу с другими людьми, рано или поздно IP-адрес вашего сервера может утечь к РКН, который добавит его
|
||||
в список блокируемых сайтов, доступ к серверу при этом пропадёт. Если же сервер работает через сеть доставки контента (content delivery
|
||||
network, CDN), то для доступа используется не IP-адрес, а доменное имя. Для того, чтобы заблокировать сервер в этом случае нужно будет
|
||||
заблокировать один из серверов доменных имён CDN-провайдера (на котором "резолвится" ваше доменное имя). На этом сервере имён может
|
||||
резолвиться большое число других сайтов (в том числе российских), и в случае блокировки они тоже перестанут работать. Так что, возможно, РКН
|
||||
не станет идти на такие риски и не будет блокировать ваш сервер даже в случае обнаружения.
|
||||
|
||||
CDN от Cloudflare позволяет бесплатно транспортировать grpc-трафик, однако вам потребуется купить какое-либо доменное имя. Чтобы понять
|
||||
общую концепцию работы xray через CDN, прочитайте [вот эту статью](https://habr.com/ru/articles/761798/).
|
||||
|
||||
**До запуска установки xray** скопируйте ваши сертификаты Cloudflare `cert.pem` и `cert.key` в директорию со скриптом `ex.sh`!
|
||||
|
||||
Vless не может быть сконфигурирован с fallback при использовании grpc, соответственно, не может противостоять атаке active-probing. Поэтому
|
||||
помимо xray нужно установить веб-сервер **nginx**, который будет обеспечивать перенаправление на сайт-заглушку. Easy-xray сгенерирует
|
||||
"сайт" для nginx, который слушает IPv6 адрес и перенаправляет реальных пользователей на xray-сервер, слушающий на 127.0.0.1:50051. При
|
||||
настройке easy-xray (при выполнении команды `sudo ./ex.sh install` или `./ex.sh conf`) укажите ваше доменное имя, и следуйте дальнейшим
|
||||
инструкциям. После установки нужно проверить конфигурацию nginx и запустить его с помощью команд
|
||||
|
||||
```
|
||||
sudo nginx -t
|
||||
sudo systemctl start nginx
|
||||
```
|
||||
|
||||
Если при попытке зайти на ваш "сайт" из браузера редирект (fallback) на сайт-заглушку не происходит (error 502, bad gateway), возможно,
|
||||
политики SELinux запрещают nginx выполнять сетевые соединения. Чтобы это исправить, выполните команду
|
||||
|
||||
```
|
||||
sudo setsebool -P httpd_can_network_connect 1
|
||||
```
|
||||
|
|
@ -29,7 +29,7 @@ can
|
|||
First you need a Linux server (VPS) with [jq](https://jqlang.github.io/jq/) and `openssl` installed, they can be found in repositories of
|
||||
almost all popular Linux distributions. Then download whole `easy-xray` folder to the VPS, make the script `ex.sh` executable, and run a
|
||||
desired command with it. Use `./ex.sh help` to see the list of all available commands and `./ex.sh install` to start interactive prompt
|
||||
that installs and configures XRay.
|
||||
that installs and configures XRay. Do not use easy-xray for user `root`, use usual user and `sudo` instead.
|
||||
|
||||
```
|
||||
chmod +x ex.sh
|
||||
|
@ -40,6 +40,9 @@ sudo ./ex.sh install
|
|||
Now you have `conf` folder with server and client configs and some user configs. Server config is properly installed and XRay is running.
|
||||
Time to share configs or *links* with users! To generate config in the link form, use `./ex.sh link user_config_file.json`.
|
||||
|
||||
If your VPS have both IPv4 and IPv6 addressess, easy-xray can be configured such that IPv6 address is used for access with grpc-tls
|
||||
protocol via CDN (e.g. Cloudflare). See [CDN instruction](CDN.md) for details.
|
||||
|
||||
#### Docker
|
||||
|
||||
Script `ex.sh` is written without Docker in mind, but can be used with Docker. Download `easy-xray` folder (main branch) and build the
|
||||
|
|
|
@ -31,7 +31,8 @@ VLESS-Reality) не шифрует уже зашифрованный https-тр
|
|||
установить [jq](https://jqlang.github.io/jq/) и `openssl` - их можно найти в репозиторияx практически всех популярных Linux дистрибутивов.
|
||||
Затем скачайте `easy-xray` (всю директорию целиком), сделайте исполняемым файл `ex.sh` и запустите нужную команду. Используйте `./ex.sh
|
||||
help` для получения списка всех команд и короткой справки по ним. Для установки и настройки xray используйте `./ex.sh install` - эта команда
|
||||
предложит вам ввести ip-адрес вашего сервера, адрес сайта, под который ваш сервер будет маскироваться, и имена пользователей.
|
||||
предложит вам ввести ip-адрес вашего сервера, адрес сайта, под который ваш сервер будет маскироваться, и имена пользователей. Не
|
||||
используйте easy-xray для пользователя root, используйте обычного пользователя и sudo!
|
||||
|
||||
```
|
||||
chmod +x ex.sh
|
||||
|
@ -43,6 +44,10 @@ sudo ./ex.sh install
|
|||
будет должным образом установлен, а xray - запущен с ним. Настало время раздать конфиги пользователям! Для многих графических клиентов
|
||||
удобно использовать конфиги в виде ссылок, которые можно сгенерировать командой `./ex.sh link user_config_file.json`.
|
||||
|
||||
Если у вашего VPS сервера есть два IP-адреса (IPv4 и IPv6), easy-xray может быть сконфигурирован так, чтобы IPv6-адрес
|
||||
использовался для доступа через сеть CDN от Cloudflare по протоколу grpc-tls. См. детали в [инструкции](CDN.ru.md).
|
||||
|
||||
|
||||
#### Docker
|
||||
|
||||
Скрипт `ex.sh` написан прежде всего для использования в системе с systemd, однако может быть использован и в Docker. Для этого скачайте
|
||||
|
|
131
ex.sh
131
ex.sh
|
@ -137,7 +137,17 @@ conf () {
|
|||
check_command jq "needed for operations with configs"
|
||||
check_command openssl "needed for strong random numbers excluding some types of attacks"
|
||||
#
|
||||
echo -e "Enter IPv4 or IPv6 address of your xray server, or its domain name:"
|
||||
echo -e "Enter domain name to use with IPv6 and CDN (e.g. Cloudflare),
|
||||
or leave blank for simple default configuration:"
|
||||
read server_name4cdn
|
||||
#
|
||||
if [ -v $server_name4cdn ]
|
||||
then
|
||||
echo -e "Enter IPv4 or IPv6 address of your xray server, or its domain name:"
|
||||
else
|
||||
check_command sed "needed to make nginx's site to use cdn"
|
||||
echo -e "Enter IPv4 address of your xray server:"
|
||||
fi
|
||||
read address
|
||||
if [ -v $address ]
|
||||
then
|
||||
|
@ -145,11 +155,11 @@ conf () {
|
|||
exit 1
|
||||
fi
|
||||
id=$(xray uuid) # random uuid for VLESS
|
||||
echo -e "Generate private and public keys? (Y/n)"
|
||||
echo -e "Generate xray private and public keys? (Y/n)"
|
||||
read answer
|
||||
if [ ! -v $answer ] && [ $answer = 'n' ]
|
||||
then
|
||||
echo -e "Enter private and public keys delimited by a space:"
|
||||
echo -e "Enter xray private and public keys delimited by a space:"
|
||||
read answer
|
||||
private_key=$(echo $answer | cut -d " " -f 1) # get the first field of fields delimited by spaces
|
||||
public_key=$(echo $answer | cut -d " " -f 2)
|
||||
|
@ -217,10 +227,33 @@ Better if it is quite popular and not blocked in your country:
|
|||
email="love@xray.com"
|
||||
#
|
||||
unsafe_mkdir conf
|
||||
#
|
||||
if [ -v $server_name4cdn ]
|
||||
then
|
||||
listen="0.0.0.0"
|
||||
else
|
||||
listen=$address # otherwise xray will listen also at ip6
|
||||
# grpc service name (location); letters and digits only
|
||||
echo -e "Enter grpc service name or hit Enter to autogenerate:"
|
||||
read service_name
|
||||
if [ -v ${service_name} ]
|
||||
then
|
||||
service_name=$(openssl rand -base64 9 | sed 's![^[:alnum:]]!!g')
|
||||
fi
|
||||
# config for nginx; `!` in sed allows not to escape special characters such as dot and plus sign
|
||||
cat ./template_site4cdn.conf \
|
||||
| sed "s!server_domain_name!${server_name4cdn}!" \
|
||||
| sed "s!www.youtube.com!${fake_site}!" \
|
||||
| sed "s!your_service_name!${service_name}!" \
|
||||
> ./conf/site4cdn.conf
|
||||
cp ./conf/site4cdn.conf /etc/nginx/sites-enabled/
|
||||
fi
|
||||
#
|
||||
## Make server config ##
|
||||
jsonc2json template_config_server.jsonc \
|
||||
| jq ".inbounds[1].settings.clients[0].id=\"${id}\"
|
||||
| .inbounds[2].settings.clients[0].id=\"${id}\"
|
||||
| .inbounds[1].listen=\"${listen}\"
|
||||
| .inbounds[1].settings.clients[0].email=\"${email}\"
|
||||
| .inbounds[2].settings.clients[0].email=\"${email}\"
|
||||
| .inbounds[1].streamSettings.realitySettings.dest=\"${fake_site}:443\"
|
||||
|
@ -230,7 +263,9 @@ Better if it is quite popular and not blocked in your country:
|
|||
| .inbounds[1].streamSettings.realitySettings.privateKey=\"${private_key}\"
|
||||
| .inbounds[2].streamSettings.realitySettings.privateKey=\"${private_key}\"
|
||||
| .inbounds[1].streamSettings.realitySettings.shortIds=[ \"${short_id}\" ]
|
||||
| .inbounds[2].streamSettings.realitySettings.shortIds=[ \"${short_id}\" ]" \
|
||||
| .inbounds[2].streamSettings.realitySettings.shortIds=[ \"${short_id}\" ]
|
||||
| .inbounds[3].settings.clients[0].id=\"${id}\"
|
||||
| .inbounds[3].streamSettings.grpcSettings.serviceName=\"${service_name}\" " \
|
||||
> ./conf/config_server.json
|
||||
# make the user (not root) the owner of the file
|
||||
[[ $SUDO_USER ]] && chown "$SUDO_USER:$SUDO_USER" ./conf/config_server.json
|
||||
|
@ -271,6 +306,24 @@ Better if it is quite popular and not blocked in your country:
|
|||
echo -e "${red}config files are not generated${normal}"
|
||||
exit 1
|
||||
fi
|
||||
## Make main client config_cdn ##
|
||||
if [ ! -v $server_name4cdn ]
|
||||
then
|
||||
jsonc2json template_config_client_cdn.jsonc \
|
||||
| jq ".outbounds[0].settings.vnext[0].address=\"${server_name4cdn}\"
|
||||
| .outbounds[0].settings.vnext[0].users[0].id=\"${id}\"
|
||||
| .outbounds[0].streamSettings.grpcSettings.serviceName=\"${service_name}\"" \
|
||||
> ./conf/config_client_cdn.json
|
||||
# make the user (not root) an owner of a file
|
||||
[[ $SUDO_USER ]] && chown "$SUDO_USER:$SUDO_USER" ./conf/config_client_cdn.json
|
||||
if [ -f "./conf/config_client_cdn.json" ]
|
||||
then
|
||||
echo -e "${green}config_cdn file is generated${normal}"
|
||||
else
|
||||
echo -e "${red}config_cdn file is not generated${normal}"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# the main part of `./ex.sh add` command, adds config for given users and updates server config
|
||||
|
@ -339,6 +392,11 @@ no new config created fot it${normal}"
|
|||
ok1=$(cat ./conf/config_client.json | jq ".outbounds[0].settings.vnext[0].users[0].id=\"${id}\" | .outbounds[0].settings.vnext[0].users[0].email=\"${username}@example.com\" | .outbounds[0].streamSettings.realitySettings.shortId=\"${short_id}\"" > ./conf/config_client_${username}.json)
|
||||
# then make the user (not root) an owner of a file
|
||||
[[ $SUDO_USER ]] && chown "$SUDO_USER:$SUDO_USER" ./conf/config_client_${username}.json
|
||||
if [ -f "./conf/config_client_cdn.json" ]
|
||||
then
|
||||
cat ./conf/config_client_cdn.json | jq ".outbounds[0].settings.vnext[0].users[0].id=\"${id}\"" > ./conf/config_client_${username}_cdn.json
|
||||
[[ $SUDO_USER ]] && chown "$SUDO_USER:$SUDO_USER" ./conf/config_client_${username}_cdn.json
|
||||
fi
|
||||
fi
|
||||
# update server config
|
||||
client="
|
||||
|
@ -348,9 +406,13 @@ no new config created fot it${normal}"
|
|||
\"flow\": \"xtls-rprx-vision\"
|
||||
}
|
||||
"
|
||||
# update server config
|
||||
grpc_client_id="
|
||||
{
|
||||
\"id\": \"${id}\"
|
||||
}
|
||||
"
|
||||
cp ./conf/config_server.json ./conf/tmp_server_config.json
|
||||
ok2=$(cat ./conf/tmp_server_config.json | jq ".inbounds[1].settings.clients += [${client}] | .inbounds[1].streamSettings.realitySettings.shortIds += [\"${short_id}\"]" > ./conf/config_server.json)
|
||||
ok2=$(cat ./conf/tmp_server_config.json | jq ".inbounds[1].settings.clients += [${client}] | .inbounds[1].streamSettings.realitySettings.shortIds += [\"${short_id}\"] | .inbounds[3].settings.clients += [${grpc_client_id}]" > ./conf/config_server.json)
|
||||
# then make the user (not root) an owner of a file
|
||||
[[ $SUDO_USER ]] && chown "$SUDO_USER:$SUDO_USER" ./conf/config_server.json
|
||||
if $ok1 && $ok2
|
||||
|
@ -449,6 +511,16 @@ sudo ./ex.sh install${normal}"
|
|||
echo -e "${red}customgeo.dat not copied to ${dat_dir}${normal}"
|
||||
exit 1
|
||||
fi
|
||||
# for cert.pem
|
||||
mkdir -p /etc/ssl/certs/
|
||||
# for cert.key
|
||||
mkdir -p /etc/ssl/private/
|
||||
# for nginx's 'site'
|
||||
mkdir -p /etc/nginx/sites-enabled/
|
||||
#
|
||||
cp -b ./cert.pem /etc/ssl/certs/
|
||||
cp -b ./cert.key /etc/ssl/private/
|
||||
cp -b ./nginx.conf /etc/nginx/nginx.conf
|
||||
else
|
||||
echo -e "${red}xray not installed, something goes wrong${normal}"
|
||||
exit 1
|
||||
|
@ -547,14 +619,19 @@ then
|
|||
echo -e "${yellow}no config for user ${username}${normal}"
|
||||
else
|
||||
short_id=$(jq ".outbounds[0].streamSettings.realitySettings.shortId" $config)
|
||||
id=$(jq ".outbounds[0].settings.vnext[0].users[0].id" $config)
|
||||
cp ./conf/config_server.json ./conf/tmp_server_config.json
|
||||
# update server config
|
||||
ok1=$(cat ./conf/tmp_server_config.json | jq "del(.inbounds[1].settings.clients[] | select(.email == \"${username}@example.com\")) | del(.inbounds[1].streamSettings.realitySettings.shortIds[] | select(. == ${short_id}))" > ./conf/config_server.json)
|
||||
ok1=$(cat ./conf/tmp_server_config.json | jq "del(.inbounds[1].settings.clients[] | select(.email == \"${username}@example.com\")) | del(.inbounds[1].streamSettings.realitySettings.shortIds[] | select(. == ${short_id})) | del(.inbounds[3].settings.clients[] | select(.id == ${id}))" > ./conf/config_server.json)
|
||||
# then make the user (not root) an owner of a file
|
||||
[[ $SUDO_USER ]] && chown "$SUDO_USER:$SUDO_USER" ./conf/config_server.json
|
||||
if [ $command = "del" ]
|
||||
then
|
||||
ok2=$(rm ./conf/config_client_${username}.json)
|
||||
if [ -f "./conf/config_client_${username}_cdn.json" ]
|
||||
then
|
||||
rm ./conf/config_client_${username}_cdn.json
|
||||
fi
|
||||
if $ok1 && $ok2
|
||||
then
|
||||
rm ./conf/tmp_server_config.json
|
||||
|
@ -602,17 +679,26 @@ then
|
|||
exit 1
|
||||
fi
|
||||
check_command jq "needed for operations with configs"
|
||||
id=$(strip_quotes $(jq ".outbounds[0].settings.vnext[0].users[0].id" $conf_file))
|
||||
address=$(strip_quotes $(jq ".outbounds[0].settings.vnext[0].address" $conf_file))
|
||||
if [[ $address == *":"* ]] # address contains ':', as IPv6 does
|
||||
network=$(strip_quotes $(jq ".outbounds[0].streamSettings.network" $conf_file))
|
||||
if [ $network = "tcp" ] # tls-vless-reality config
|
||||
then
|
||||
address="[${address}]"
|
||||
id=$(strip_quotes $(jq ".outbounds[0].settings.vnext[0].users[0].id" $conf_file))
|
||||
address=$(strip_quotes $(jq ".outbounds[0].settings.vnext[0].address" $conf_file))
|
||||
if [[ $address == *":"* ]] # address contains ':', as IPv6 does
|
||||
then
|
||||
address="[${address}]"
|
||||
fi
|
||||
port=$(jq ".outbounds[0].settings.vnext[0].port" $conf_file)
|
||||
public_key=$(strip_quotes $(jq ".outbounds[0].streamSettings.realitySettings.publicKey" $conf_file))
|
||||
server_name=$(strip_quotes $(jq ".outbounds[0].streamSettings.realitySettings.serverName" $conf_file))
|
||||
short_id=$(strip_quotes $(jq ".outbounds[0].streamSettings.realitySettings.shortId" $conf_file))
|
||||
link="vless://${id}@${address}:${port}?fragment=&security=reality&encryption=none&pbk=${public_key}&fp=chrome&type=tcp&flow=xtls-rprx-vision&sni=${server_name}&sid=${short_id}#easy-xray+%F0%9F%97%BD"
|
||||
else # grpc config
|
||||
id=$(strip_quotes $(jq ".outbounds[0].settings.vnext[0].users[0].id" $conf_file))
|
||||
address=$(strip_quotes $(jq ".outbounds[0].settings.vnext[0].address" $conf_file))
|
||||
service_name=$(strip_quotes $(jq ".outbounds[0].streamSettings.grpcSettings.serviceName" $conf_file))
|
||||
link="vless://${id}@${address}:443?security=tls&encryption=none&type=grpc&serviceName=${service_name}#easy-xray+%F0%9F%97%BD+CDN"
|
||||
fi
|
||||
port=$(jq ".outbounds[0].settings.vnext[0].port" $conf_file)
|
||||
public_key=$(strip_quotes $(jq ".outbounds[0].streamSettings.realitySettings.publicKey" $conf_file))
|
||||
server_name=$(strip_quotes $(jq ".outbounds[0].streamSettings.realitySettings.serverName" $conf_file))
|
||||
short_id=$(strip_quotes $(jq ".outbounds[0].streamSettings.realitySettings.shortId" $conf_file))
|
||||
link="vless://${id}@${address}:${port}?fragment=&security=reality&encryption=none&pbk=${public_key}&fp=chrome&type=tcp&flow=xtls-rprx-vision&sni=${server_name}&sid=${short_id}#easy-xray+%F0%9F%97%BD"
|
||||
echo -e "${yellow}don't forget to share misc/customgeo4hiddify.txt or misc/customgeo4nekoray.txt as well
|
||||
${green}here is your link:${normal}"
|
||||
echo $link
|
||||
|
@ -709,6 +795,12 @@ then
|
|||
ok1=$(cat ${to}/config_client.json | jq ".outbounds[0].settings.vnext[0].users[0].id=\"${id}\" | .outbounds[0].settings.vnext[0].users[0].email=\"${uname_from_email}@example.com\" | .outbounds[0].streamSettings.realitySettings.shortId=\"${short_id}\"" > ${to}/config_client_${uname_from_email}.json)
|
||||
# then make the user (not root) an owner of a file
|
||||
[[ $SUDO_USER ]] && chown "$SUDO_USER:$SUDO_USER" ${to}/config_client_${uname_from_email}.json
|
||||
#
|
||||
if [ -f "./conf/config_client_cdn.json" ]
|
||||
then
|
||||
cat ./conf/config_client_cdn.json | jq ".outbounds[0].settings.vnext[0].users[0].id=\"${id}\"" > ./conf/config_client_${uname_from_email}_cdn.json
|
||||
[[ $SUDO_USER ]] && chown "$SUDO_USER:$SUDO_USER" ./conf/config_client_${username}_cdn.json
|
||||
fi
|
||||
# update server config
|
||||
client="
|
||||
{
|
||||
|
@ -717,8 +809,13 @@ then
|
|||
\"flow\": \"xtls-rprx-vision\"
|
||||
}
|
||||
"
|
||||
grpc_client_id="
|
||||
{
|
||||
\"id\": \"${id}\"
|
||||
}
|
||||
"
|
||||
cp ${to}/config_server.json ${to}/tmp_server_config.json
|
||||
ok2=$(cat ${to}/tmp_server_config.json | jq ".inbounds[1].settings.clients += [${client}] | .inbounds[1].streamSettings.realitySettings.shortIds += [\"${short_id}\"]" > ${to}/config_server.json)
|
||||
ok2=$(cat ${to}/tmp_server_config.json | jq ".inbounds[1].settings.clients += [${client}] | .inbounds[1].streamSettings.realitySettings.shortIds += [\"${short_id}\"] | .inbounds[3].settings.clients += [${grpc_client_id}]" > ${to}/config_server.json)
|
||||
# then make the user (not root) an owner of a file
|
||||
[[ $SUDO_USER ]] && chown "$SUDO_USER:$SUDO_USER" ${to}/config_server.json
|
||||
if $ok1 && $ok2
|
||||
|
|
85
nginx.conf
Normal file
85
nginx.conf
Normal file
|
@ -0,0 +1,85 @@
|
|||
# For more information on configuration, see:
|
||||
# * Official English Documentation: http://nginx.org/en/docs/
|
||||
# * Official Russian Documentation: http://nginx.org/ru/docs/
|
||||
|
||||
user nginx;
|
||||
worker_processes auto;
|
||||
error_log /var/log/nginx/error.log;
|
||||
pid /run/nginx.pid;
|
||||
|
||||
# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
|
||||
include /usr/share/nginx/modules/*.conf;
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||
'$status $body_bytes_sent "$http_referer" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||
|
||||
access_log /var/log/nginx/access.log main;
|
||||
|
||||
sendfile on;
|
||||
tcp_nopush on;
|
||||
tcp_nodelay on;
|
||||
keepalive_timeout 65;
|
||||
types_hash_max_size 4096;
|
||||
|
||||
include /etc/nginx/mime.types;
|
||||
include /etc/nginx/sites-enabled/*;
|
||||
default_type application/octet-stream;
|
||||
|
||||
# Load modular configuration files from the /etc/nginx/conf.d directory.
|
||||
# See http://nginx.org/en/docs/ngx_core_module.html#include
|
||||
# for more information.
|
||||
include /etc/nginx/conf.d/*.conf;
|
||||
|
||||
#server {
|
||||
# listen 80;
|
||||
# listen [::]:80;
|
||||
# server_name _;
|
||||
# root /usr/share/nginx/html;
|
||||
|
||||
# # Load configuration files for the default server block.
|
||||
# include /etc/nginx/default.d/*.conf;
|
||||
|
||||
# error_page 404 /404.html;
|
||||
# location = /404.html {
|
||||
# }
|
||||
|
||||
# error_page 500 502 503 504 /50x.html;
|
||||
# location = /50x.html {
|
||||
# }
|
||||
#}
|
||||
|
||||
# Settings for a TLS enabled server.
|
||||
#
|
||||
# server {
|
||||
# listen 443 ssl http2;
|
||||
# listen [::]:443 ssl http2;
|
||||
# server_name _;
|
||||
# root /usr/share/nginx/html;
|
||||
#
|
||||
# ssl_certificate "/etc/pki/nginx/server.crt";
|
||||
# ssl_certificate_key "/etc/pki/nginx/private/server.key";
|
||||
# ssl_session_cache shared:SSL:1m;
|
||||
# ssl_session_timeout 10m;
|
||||
# ssl_ciphers PROFILE=SYSTEM;
|
||||
# ssl_prefer_server_ciphers on;
|
||||
#
|
||||
# # Load configuration files for the default server block.
|
||||
# include /etc/nginx/default.d/*.conf;
|
||||
#
|
||||
# error_page 404 /404.html;
|
||||
# location = /40x.html {
|
||||
# }
|
||||
#
|
||||
# error_page 500 502 503 504 /50x.html;
|
||||
# location = /50x.html {
|
||||
# }
|
||||
# }
|
||||
|
||||
}
|
||||
|
229
template_config_client_cdn.jsonc
Normal file
229
template_config_client_cdn.jsonc
Normal file
|
@ -0,0 +1,229 @@
|
|||
// This config is based on
|
||||
// https://github.com/XTLS/Xray-examples/blob/main/VLESS-TCP-XTLS-Vision-REALITY/REALITY.ENG.md
|
||||
{
|
||||
"log": {
|
||||
"access": "none",
|
||||
"error": "",
|
||||
"loglevel": "warning",
|
||||
"dnsLog": false
|
||||
},
|
||||
// Turns on traffic statistics, see https://xtls.github.io/en/config/stats.html#statsobject
|
||||
// and https://xtls.github.io/en/config/policy.html#policyobject
|
||||
// and special "api" tag below
|
||||
"stats": {
|
||||
},
|
||||
"policy": {
|
||||
"levels": {
|
||||
// default level
|
||||
"0": {
|
||||
"statsUserUplink": true,
|
||||
"statsUserDownlink": true
|
||||
}
|
||||
},
|
||||
"system": {
|
||||
"statsOutboundUplink": true,
|
||||
"statsOutboundDownlink": true
|
||||
}
|
||||
},
|
||||
// enables API interface https://xtls.github.io/en/config/api.html#apiobject
|
||||
"api": {
|
||||
"tag": "api",
|
||||
"services": [ "StatsService" ]
|
||||
},
|
||||
// client-side inbound configuration
|
||||
"inbounds": [
|
||||
// gRPC API inbound, used to get statistics
|
||||
{
|
||||
"listen": "127.0.0.1",
|
||||
"port": 8080,
|
||||
"protocol": "dokodemo-door",
|
||||
"settings": {
|
||||
"address": "127.0.0.1"
|
||||
},
|
||||
"tag": "api"
|
||||
},
|
||||
// socks proxy
|
||||
{
|
||||
"tag": "socks",
|
||||
"port": 800,
|
||||
"listen": "127.0.0.1",
|
||||
"protocol": "socks",
|
||||
// used to make transparent proxies, see https://xtls.github.io/en/config/inbound.html#sniffingobject
|
||||
"sniffing": {
|
||||
"enabled": true,
|
||||
"destOverride": [
|
||||
"http",
|
||||
"tls"
|
||||
],
|
||||
"routeOnly": true
|
||||
},
|
||||
// settings of inbound "protocol" (see above)
|
||||
"settings": {
|
||||
"auth": "noauth",
|
||||
"udp": true
|
||||
}
|
||||
},
|
||||
// http/https proxy
|
||||
{
|
||||
"tag": "http",
|
||||
"port": 801,
|
||||
"listen": "127.0.0.1",
|
||||
"protocol": "http",
|
||||
// used to make transparent proxies, see https://xtls.github.io/en/config/inbound.html#sniffingobject
|
||||
"sniffing": {
|
||||
"enabled": true,
|
||||
"destOverride": [
|
||||
"http",
|
||||
"tls"
|
||||
],
|
||||
"routeOnly": true
|
||||
},
|
||||
// settings of inbound "protocol" (see above)
|
||||
"settings": {
|
||||
"auth": "noauth",
|
||||
"udp": true
|
||||
}
|
||||
}
|
||||
],
|
||||
// client-side outbound configuration
|
||||
"outbounds": [
|
||||
// fallback, see `routing` section
|
||||
{
|
||||
"tag": "proxy",
|
||||
"protocol": "vless",
|
||||
"settings": {
|
||||
"vnext": [
|
||||
{
|
||||
"address": "server_domain_name",
|
||||
"port": 443,
|
||||
"users": [
|
||||
{
|
||||
// should match server side
|
||||
"id": "client_id",
|
||||
"encryption": "none"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"streamSettings": {
|
||||
"network": "grpc",
|
||||
"security": "tls",
|
||||
"grpcSettings": {
|
||||
// should match server side
|
||||
"serviceName": "your_service_name",
|
||||
// for Cloudflare CDN, see this example https://github.com/XTLS/Xray-examples/blob/main/VLESS-GRPC/client.json
|
||||
// and https://xtls.github.io/en/config/transports/grpc.html#grpcobject
|
||||
"idle_timeout": 60,
|
||||
"permit_without_stream": true,
|
||||
"initial_windows_size": 35536
|
||||
},
|
||||
"tlsSettings": {
|
||||
"alpn": ["h2"],
|
||||
"fingerprint": "chrome"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
// this outbound is to guide traffic to local sites not through the server
|
||||
// but directly from the client; `tag` is just an outbound label
|
||||
"tag": "direct",
|
||||
"protocol": "freedom",
|
||||
"settings": {}
|
||||
},
|
||||
// for that should be blocked
|
||||
{
|
||||
"protocol": "blackhole",
|
||||
"tag": "block"
|
||||
}
|
||||
],
|
||||
// Forward each inbound connections to corresponding `outboundTag`. If no rules match,
|
||||
// the traffic is sent out by the first outbound in `outbounds` section.
|
||||
"routing": {
|
||||
"domainStrategy": "AsIs",
|
||||
"rules": [
|
||||
{
|
||||
"type": "field",
|
||||
"inboundTag": [
|
||||
"api"
|
||||
],
|
||||
"outboundTag": "api"
|
||||
},
|
||||
// guide udp traffic to `direct` outbound
|
||||
{
|
||||
"type": "field",
|
||||
"network": "udp",
|
||||
"outboundTag": "direct"
|
||||
},
|
||||
// block localhost connections through xray
|
||||
{
|
||||
"type": "field",
|
||||
"ip": [
|
||||
"geoip:private"
|
||||
],
|
||||
"outboundTag": "block"
|
||||
},
|
||||
// guide bittorent traffic to `direct` outbound
|
||||
{
|
||||
"type": "field",
|
||||
"protocol": [ "bittorrent" ],
|
||||
"outboundTag": "direct"
|
||||
},
|
||||
// traffic to popular ports of torrent trackers
|
||||
// and to popular ports of torrent clients
|
||||
{
|
||||
"type": "field",
|
||||
"port": "6969,6881-6889",
|
||||
"outboundTag": "direct"
|
||||
},
|
||||
// traffic from popular ports of torrent clients
|
||||
{
|
||||
"type": "field",
|
||||
"sourcePort": "6881-6889",
|
||||
"outboundTag": "direct"
|
||||
},
|
||||
// exceptions for some *.ru sites that shouldn't be blocked or accessed directly
|
||||
{
|
||||
"type": "field",
|
||||
"domain": [
|
||||
"ext:customgeo.dat:coherence-extra-exceptions"
|
||||
],
|
||||
"outboundTag": "proxy"
|
||||
},
|
||||
// guide domestic sites traffic to `direct` outbound
|
||||
{
|
||||
"type": "field",
|
||||
"domain": [
|
||||
"geosite:cn",
|
||||
"domain:cn",
|
||||
// punycode for national Chinese top-level domains .中国, .中國, .公司, .网络
|
||||
"domain:xn--fiqs8s",
|
||||
"domain:xn--fiqz9s",
|
||||
"domain:xn--55qx5d",
|
||||
"domain:xn--io0a7i",
|
||||
"domain:ru",
|
||||
// punycode for cyrillic Russian top-level domain .рф
|
||||
"domain:xn--p1ai",
|
||||
"domain:by",
|
||||
// punycode for national Belorussian top-level domain .бел
|
||||
"domain:xn--90ais",
|
||||
"domain:ir",
|
||||
// extra domains that are used by domestic sites, see https://github.com/EvgenyNerush/coherence-grabber/tree/main
|
||||
"ext:customgeo.dat:coherence-extra",
|
||||
"ext:customgeo.dat:coherence-extra-plus"
|
||||
],
|
||||
"outboundTag": "direct"
|
||||
},
|
||||
{
|
||||
"type": "field",
|
||||
"ip": [
|
||||
"geoip:cn",
|
||||
"geoip:ru",
|
||||
"geoip:by",
|
||||
"geoip:ir"
|
||||
],
|
||||
"outboundTag": "direct"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
|
@ -246,6 +246,30 @@
|
|||
],
|
||||
"routeOnly": true
|
||||
}
|
||||
},
|
||||
// this inbound can be used with Nginx configured to listen grpc on IPv6 address;
|
||||
// vless can't give a reasonable fallback when used with grpc, but nginx can;
|
||||
// see 'CDN' section in Readme for details
|
||||
{
|
||||
"tag": "grpc",
|
||||
"listen": "127.0.0.1",
|
||||
"port": 50051,
|
||||
"protocol": "vless",
|
||||
"settings": {
|
||||
"clients": [
|
||||
{
|
||||
"id": "client_id"
|
||||
}
|
||||
],
|
||||
"decryption": "none"
|
||||
},
|
||||
"streamSettings": {
|
||||
"network": "grpc",
|
||||
"grpcSettings": {
|
||||
// nginx config should contain `location /your_service_name`
|
||||
"serviceName": "your_service_name"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
// server-side outbound configuration
|
||||
|
|
35
template_site4cdn.conf
Normal file
35
template_site4cdn.conf
Normal file
|
@ -0,0 +1,35 @@
|
|||
server {
|
||||
# listen ip6 addresses
|
||||
listen [::]:443 ssl http2 so_keepalive=on;
|
||||
|
||||
# your server domain name in CDN, for instance myserver.example.com
|
||||
server_name server_domain_name;
|
||||
|
||||
# fallback: proxy_pass redirects request to another server
|
||||
location / {
|
||||
proxy_pass https://www.youtube.com;
|
||||
}
|
||||
|
||||
|
||||
# path to certificates (self-signed or from Cloudflare)
|
||||
ssl_certificate /etc/ssl/certs/cert.pem;
|
||||
ssl_certificate_key /etc/ssl/private/cert.key;
|
||||
|
||||
|
||||
client_header_timeout 52w;
|
||||
keepalive_timeout 52w;
|
||||
# secret location; should match that in the xray server config
|
||||
location /your_service_name {
|
||||
if ($content_type !~ "application/grpc") {
|
||||
# redirect to the root location
|
||||
return 302 /;
|
||||
}
|
||||
client_max_body_size 0;
|
||||
client_body_buffer_size 512k;
|
||||
grpc_set_header X-Real-IP $remote_addr;
|
||||
client_body_timeout 52w;
|
||||
grpc_read_timeout 52w;
|
||||
# connect to xray on localhost
|
||||
grpc_pass grpc://127.0.0.1:50051;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue