mirror of
https://github.com/kenzok8/small-package.git
synced 2026-02-08 07:37:13 +08:00
update 04-22 18:55:32
This commit is contained in:
132
luci-app-xray/Makefile
Normal file
132
luci-app-xray/Makefile
Normal file
@@ -0,0 +1,132 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-xray
|
||||
PKG_VERSION:=1.9.0
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_LICENSE:=MPLv2
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
PKG_MAINTAINER:=yichya <mail@yichya.dev>
|
||||
PKG_BUILD_PARALLEL:=1
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/$(PKG_NAME)
|
||||
SECTION:=Custom
|
||||
CATEGORY:=Extra packages
|
||||
TITLE:=LuCI Support for Xray
|
||||
DEPENDS:=+luci-base +xray-core +dnsmasq +ipset +firewall +iptables +iptables-mod-tproxy +ca-bundle
|
||||
PKGARCH:=all
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)/description
|
||||
LuCI Support for Xray (Client-side Rendered).
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)/config
|
||||
menu "luci-app-xray Configuration"
|
||||
depends on PACKAGE_$(PKG_NAME)
|
||||
|
||||
config PACKAGE_XRAY_INCLUDE_CLOUDFLARE_ORIGIN_ROOT_CA
|
||||
bool "Include Cloudflare Origin Root CA"
|
||||
default n
|
||||
|
||||
config PACKAGE_XRAY_INFINITE_RETRY_ON_STARTUP
|
||||
bool "Retry infinitely on Xray startup (may solve some startup problems)"
|
||||
default n
|
||||
|
||||
config PACKAGE_XRAY_RLIMIT_NOFILE_LARGE
|
||||
bool "Increase Max Open Files Limit (recommended)"
|
||||
default y
|
||||
|
||||
choice
|
||||
prompt "Limit memory use by setting rlimit_data (experimental)"
|
||||
default PACKAGE_XRAY_RLIMIT_DATA_UNLIMITED
|
||||
config PACKAGE_XRAY_RLIMIT_DATA_UNLIMITED
|
||||
bool "Not limited"
|
||||
config PACKAGE_XRAY_RLIMIT_DATA_SMALL
|
||||
bool "Small limit (about 50MB)"
|
||||
config PACKAGE_XRAY_RLIMIT_DATA_LARGE
|
||||
bool "Large limit (about 200MB)"
|
||||
endchoice
|
||||
|
||||
config PACKAGE_XRAY_OPTIONAL_FEATURE_1000
|
||||
bool "Include Optional Feature pull/1000 (metrics support))"
|
||||
default n
|
||||
|
||||
endmenu
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)/postinst
|
||||
#!/bin/sh
|
||||
if [[ ! -f $${IPKG_INSTROOT}/usr/share/xray/xray.init.replaced ]]; then
|
||||
if [[ ! -f $${IPKG_INSTROOT}/etc/init.d/xray ]]; then
|
||||
echo "echo This file does nothing" > $${IPKG_INSTROOT}/etc/init.d/xray
|
||||
fi
|
||||
mv $${IPKG_INSTROOT}/etc/init.d/xray $${IPKG_INSTROOT}/usr/share/xray/xray.init.replaced
|
||||
mkdir -p $${IPKG_INSTROOT}/etc/config
|
||||
mv $${IPKG_INSTROOT}/tmp/xray.conf $${IPKG_INSTROOT}/etc/config/xray
|
||||
fi
|
||||
rm -f $${IPKG_INSTROOT}/tmp/xray.conf
|
||||
mkdir -p $${IPKG_INSTROOT}/etc/init.d
|
||||
mv $${IPKG_INSTROOT}/tmp/xray.init $${IPKG_INSTROOT}/etc/init.d/xray
|
||||
if [[ -z "$${IPKG_INSTROOT}" ]]; then
|
||||
if [[ -f /etc/uci-defaults/xray ]]; then
|
||||
( . /etc/uci-defaults/xray ) && rm -f /etc/uci-defaults/xray
|
||||
fi
|
||||
rm -rf /tmp/luci-indexcache* /tmp/luci-modulecache
|
||||
fi
|
||||
exit 0
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)/conffiles
|
||||
/etc/config/xray
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)/install
|
||||
$(INSTALL_DIR) $(1)/tmp
|
||||
$(INSTALL_BIN) ./root/etc/init.d/xray $(1)/tmp/xray.init
|
||||
$(INSTALL_DATA) ./root/etc/config/xray $(1)/tmp/xray.conf
|
||||
$(INSTALL_DIR) $(1)/etc/luci-uploads/xray
|
||||
$(INSTALL_DIR) $(1)/etc/hotplug.d/iface
|
||||
$(INSTALL_BIN) ./root/etc/hotplug.d/iface/01-transparent-proxy-ipset $(1)/etc/hotplug.d/iface/01-transparent-proxy-ipset
|
||||
$(INSTALL_DIR) $(1)/etc/ssl/certs
|
||||
ifdef CONFIG_PACKAGE_XRAY_INCLUDE_CLOUDFLARE_ORIGIN_ROOT_CA
|
||||
$(INSTALL_DATA) ./root/etc/ssl/certs/origin_ca_ecc_root.pem $(1)/etc/ssl/certs/origin_ca_ecc_root.pem
|
||||
endif
|
||||
$(INSTALL_DIR) $(1)/etc/uci-defaults
|
||||
$(INSTALL_BIN) ./root/etc/uci-defaults/xray $(1)/etc/uci-defaults/xray
|
||||
$(INSTALL_DIR) $(1)/www/luci-static/resources/view
|
||||
$(INSTALL_DATA) ./root/www/luci-static/resources/view/xray.js $(1)/www/luci-static/resources/view/xray.js
|
||||
$(INSTALL_DIR) $(1)/usr/share/luci/menu.d
|
||||
$(INSTALL_DATA) ./root/usr/share/luci/menu.d/luci-app-xray.json $(1)/usr/share/luci/menu.d/luci-app-xray.json
|
||||
$(INSTALL_DIR) $(1)/usr/share/rpcd/acl.d
|
||||
$(INSTALL_DATA) ./root/usr/share/rpcd/acl.d/luci-app-xray.json $(1)/usr/share/rpcd/acl.d/luci-app-xray.json
|
||||
$(INSTALL_DIR) $(1)/usr/share/xray
|
||||
ifdef CONFIG_PACKAGE_XRAY_INFINITE_RETRY_ON_STARTUP
|
||||
$(INSTALL_DATA) ./root/usr/share/xray/infinite_retry $(1)/usr/share/xray/infinite_retry
|
||||
endif
|
||||
ifdef CONFIG_PACKAGE_XRAY_RLIMIT_NOFILE_LARGE
|
||||
$(INSTALL_DATA) ./root/usr/share/xray/rlimit_nofile_large $(1)/usr/share/xray/rlimit_nofile
|
||||
endif
|
||||
ifdef CONFIG_PACKAGE_XRAY_RLIMIT_DATA_SMALL
|
||||
$(INSTALL_DATA) ./root/usr/share/xray/rlimit_data_small $(1)/usr/share/xray/rlimit_data
|
||||
endif
|
||||
ifdef CONFIG_PACKAGE_XRAY_RLIMIT_DATA_LARGE
|
||||
$(INSTALL_DATA) ./root/usr/share/xray/rlimit_data_large $(1)/usr/share/xray/rlimit_data
|
||||
endif
|
||||
ifdef CONFIG_PACKAGE_XRAY_OPTIONAL_FEATURE_1000
|
||||
$(INSTALL_DATA) ./root/usr/share/xray/optional_feature_1000 $(1)/usr/share/xray/optional_feature_1000
|
||||
endif
|
||||
$(INSTALL_BIN) ./root/usr/share/xray/gen_ipset_rules.lua $(1)/usr/share/xray/gen_ipset_rules.lua
|
||||
$(INSTALL_BIN) ./root/usr/share/xray/gen_ipset_rules_extra_normal.lua $(1)/usr/share/xray/gen_ipset_rules_extra.lua
|
||||
$(INSTALL_BIN) ./root/usr/share/xray/gen_config.lua $(1)/usr/share/xray/gen_config.lua
|
||||
$(INSTALL_BIN) ./root/usr/share/xray/firewall_include.lua $(1)/usr/share/xray/firewall_include.lua
|
||||
$(INSTALL_DIR) $(1)/usr/libexec/rpcd
|
||||
$(INSTALL_BIN) ./root/usr/libexec/rpcd/xray $(1)/usr/libexec/rpcd/xray
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,$(PKG_NAME)))
|
||||
81
luci-app-xray/README.md
Normal file
81
luci-app-xray/README.md
Normal file
@@ -0,0 +1,81 @@
|
||||
# luci-app-xray
|
||||
|
||||
[luci-app-v2ray](https://github.com/yichya/luci-app-v2ray) refined to client side rendering (and switched to xray as well).
|
||||
|
||||
Focus on making the most of Xray (HTTP/HTTPS/Socks/TProxy inbounds, multiple protocols support, DNS server, bridge (reverse proxy), even HTTPS proxy server for actual HTTP services) while keeping thin and elegant.
|
||||
|
||||
## Warnings
|
||||
|
||||
* There will be a series of **BREAKING CHANGES** in the following months due to some major refactor of DNS module. Please read changelog carefully to know about breaking changes and always backup your configuration files before updating.
|
||||
* If you see `WARNING: at least one of asset files (geoip.dat, geosite.dat) is not found under /usr/share/xray. Xray may not work properly` and don't know what to do:
|
||||
* try `opkg update && opkg install xray-geodata` (at least OpenWrt 21.02 releases)
|
||||
* if that doesn't work or you are using OpenWrt 19.07 releases, see [#52](https://github.com/yichya/luci-app-xray/issues/52#issuecomment-856059905)
|
||||
* This project **DOES NOT SUPPORT** the following versions of OpenWrt due to the fact that client side rendering requires LuCI client side APIs shipped with at least OpenWrt 19.07 releases.
|
||||
* LEDE 17.01
|
||||
* OpenWrt 18.06
|
||||
* [Lean's OpenWrt Source](https://github.com/coolsnowwolf/lede) (which uses a variant of LuCI shipped with OpenWrt 18.06)
|
||||
|
||||
If this is your case, use Passwall or similar projects instead (you could find links in [XTLS/Xray-core](https://github.com/XTLS/Xray-core/)).
|
||||
* For OpenWrt 19.07 releases, you need to prepare your own xray-core package (just download from [Releases · yichya/openwrt-xray](https://github.com/yichya/openwrt-xray/releases) and install that) because building Xray from source requires Go 1.17 which is currently only available in at least OpenWrt 21.02 releases.
|
||||
* This project may change its code structure, configuration files format, user interface or dependencies quite frequently since it is still in its very early stage.
|
||||
|
||||
## Changelog 2022
|
||||
|
||||
* 2022-01-08 feat: bridge; add DomainStrategy for outbound; minor UI changes
|
||||
* 2022-01-31 fix: multiple hosts in lan access control; simplify init script
|
||||
* 2022-02-01 feat: refactor transparent-proxy-ipset to use lua
|
||||
* 2022-02-02 feat: return certain domain names as NXDOMAIN
|
||||
* 2022-02-03 fix: failed to start Xray when blocked domain list is empty
|
||||
* 2022-02-15 feat: add a large rlimit_data option
|
||||
* 2022-02-19 fix: rlimit_data and rlimit_nofile does not work together
|
||||
* 2022-02-20 fix: return a discarded address instead of nxdomain to let dnsmasq cache these queries
|
||||
* 2022-03-25 feat: remove web and add metrics configurations (recommended to use with [metrics support](https://github.com/XTLS/Xray-core/pull/1000))
|
||||
|
||||
## Changelog 2021
|
||||
|
||||
* 2021-01-01 feature: build Xray from source; various fixes about tproxy and logging
|
||||
* 2021-01-25 feature: Xray act as HTTPS server
|
||||
* 2021-01-29 fix: add ipset as dependency to fix transparent proxy problems; remove useless and faulty extra_command in init.d script
|
||||
* 2021-01-29 feature: decouple with Xray original binary and data files. Use [openwrt-xray](https://github.com/yichya/openwrt-xray) instead.
|
||||
* 2021-01-30 feature: select GeoIP set for direct connection. This is considered a **BREAKING** change because if unspecified, all IP addresses is forwarded through Xray.
|
||||
* 2021-03-17 feature: support custom configuration files by using Xray integrated [Multiple configuration files support](https://xtls.github.io/config/features/multiple.html). Check `/var/etc/xray/config.json` for tags of generated inbounds and outbounds.
|
||||
* 2021-03-20 fix: no longer be compatible with [OpenWrt Packages: xray-core](https://github.com/openwrt/packages/tree/master/net/xray-core) because of naming conflict of configuration file and init script. Again, use
|
||||
[openwrt-xray](https://github.com/yichya/openwrt-xray) instead.
|
||||
* 2021-03-21 feature: detailed fallback config for Xray HTTPS server
|
||||
* 2021-03-27 feature: check data files before using them. If data files don't exist, Xray will run in 'full' mode (all outgoing network traffic will be forwarded through Xray). Make sure you have a working server in this case or you have to disable Xray temporarily (SSH into your router and run `service xray stop`) for debugging. You can download data files from [Releases · XTLS/Xray-core](https://github.com/XTLS/xray-core/releases) or [Loyalsoldier/v2ray-rules-dat](https://github.com/Loyalsoldier/v2ray-rules-dat) and upload them to `/usr/share/xray` on your router, or just compile your firmware with data files included (recommended in most cases).
|
||||
* 2021-04-02 feature: utls fingerprint (currently not available for xtls and [will be supported in Xray-core v1.5.0](https://github.com/XTLS/Xray-core/pull/451))
|
||||
* 2021-04-06 feature: customize DNS bypass rules. This is considered a **BREAKING** change because if unspecified, all DNS requests is forwarded through Xray.
|
||||
* 2021-05-15 feature: add gRPC Transport settings; make init script infinite retry optional
|
||||
* 2021-07-03 fix: write upstream hostname to dnsmasq configurations to avoid infinite loop while resolving upstream hostname
|
||||
* 2021-08-31 feature: Accept more DNS server formats
|
||||
* 2021-09-19 fix: compatible with latest dnsmasq (2.86) by adding `strict-order` to dnsmasq options generated by luci-app-xray. This should not affect compatibility with earlier dnsmasq versions (mostly 2.85) but if you encounter problems please report.
|
||||
* 2021-09-26 fix: several issues related to HTTPS server
|
||||
* 2021-10-01 fix: parsing default gateway in some cases
|
||||
* 2021-10-06 feature: show information about asset files in LuCI; fix Xray startup when asset files are unavailable
|
||||
* 2021-10-08 feature: extra DNS Server Port to reduce possibility of temporary DNS lookup failures
|
||||
* 2021-10-09 fix: temporarily revert DNS over HTTPS related changes to avoid dnsmasq and iptables errors
|
||||
* 2021-10-12 fix: domain based routing if sniffing is enabled
|
||||
* 2021-10-19 feat: change upstream DNS resolve method to directly using Xray internal DNS server
|
||||
* 2021-11-14 feat: LAN access control for transparent proxy. Devices can be set to not being transparently proxied per MAC address.
|
||||
* 2021-11-15 feat: manual transparent proxy. A use case is accessing IPv6 only websites without any IPv6 address (for example, `192.0.2.1:443 -> tracker.byr.pt:443` and add hosts item `192.0.2.1 byr.pt`)
|
||||
* 2021-11-20 feat: alpn settings for outbound
|
||||
* 2021-11-21 fix: minor adjustments about service reloading, default DNS port, host hints, etc.
|
||||
* 2021-12-16 feat: expose log and policy settings
|
||||
* 2021-12-24 feat: grpc health check and initial window size
|
||||
* 2021-12-25 feat: be compatible with [OpenWrt Packages: xray-core](https://github.com/openwrt/packages/tree/master/net/xray-core) again (by replacing its UCI configuration file and init script upon install). Still supports using [openwrt-xray](https://github.com/yichya/openwrt-xray). This should work in most cases and your previous configuration file of luci-app-xray is also preserved, but if you encounter problems please report.
|
||||
* 2021-12-26 feat: support custom DNS port
|
||||
|
||||
## Changelog 2020
|
||||
* 2020-11-14 feature: basic transparent proxy function
|
||||
* 2020-11-15 fix: vless flow settings & compatible with busybox ip command
|
||||
* 2020-12-04 feature: add xtls-rprx-splice to flow
|
||||
* 2020-12-26 feature: allow to determine whether to use proxychains during build; trojan xtls flow settings
|
||||
|
||||
## Todo
|
||||
|
||||
* [x] LuCI ACL Settings
|
||||
* [x] migrate to xray-core
|
||||
* [x] better server role configurations
|
||||
* [x] transparent proxy access control for LAN
|
||||
* [x] try to be compatible with [OpenWrt Packages: xray-core](https://github.com/openwrt/packages/tree/master/net/xray-core)
|
||||
* [ ] Better DNS module implementation like DoH (may involve breaking changes)
|
||||
62
luci-app-xray/root/etc/config/xray
Normal file
62
luci-app-xray/root/etc/config/xray
Normal file
@@ -0,0 +1,62 @@
|
||||
config general
|
||||
option xray_bin '/usr/bin/xray'
|
||||
option mark '255'
|
||||
option tproxy_port_tcp '1080'
|
||||
option tproxy_port_udp '1081'
|
||||
option socks_port '1082'
|
||||
option http_port '1083'
|
||||
option dns_port '5300'
|
||||
option dns_count '3'
|
||||
option fast_dns '114.114.114.114'
|
||||
option secure_dns '8.8.8.8'
|
||||
option default_dns '1.1.1.1'
|
||||
list bypassed_domain_rules 'geosite:cn'
|
||||
list forwarded_domain_rules 'geosite:geolocation-!cn'
|
||||
list blocked_domain_rules 'geosite:category-ads'
|
||||
option transparent_proxy_enable '1'
|
||||
option wan_bp_list '/dev/null'
|
||||
option lan_target 'TP_SPEC_WAN_AC'
|
||||
option lan_ifaces 'br-lan'
|
||||
list wan_bp_ips '114.114.114.114'
|
||||
option xray_api '1'
|
||||
option main_server 'cfg024a8f'
|
||||
option tproxy_udp_server 'cfg034a8f'
|
||||
option tproxy_sniffing '1'
|
||||
option routing_domain_strategy 'AsIs'
|
||||
option conn_idle '300'
|
||||
option loglevel 'warning'
|
||||
option handshake '4'
|
||||
option uplink_only '2'
|
||||
option downlink_only '5'
|
||||
option buffer_size '512'
|
||||
|
||||
config servers
|
||||
option security 'auto'
|
||||
option transport 'tcp'
|
||||
option tcp_guise 'none'
|
||||
option tls '0'
|
||||
option tests_enabled 'none'
|
||||
option protocol 'vless'
|
||||
option server_port '443'
|
||||
option password '00000000-0000-0000-0000-000000000000'
|
||||
option vless_security 'none'
|
||||
option vless_encryption 'none'
|
||||
option server 'example.org'
|
||||
option alias 'VLESS XTLS Splice Example'
|
||||
option vless_flow 'xtls-rprx-splice'
|
||||
option vless_tls 'xtls'
|
||||
option vless_xtls_host 'example.org'
|
||||
option vless_xtls_insecure '0'
|
||||
|
||||
config servers
|
||||
option password 'supersecret'
|
||||
option transport 'tcp'
|
||||
option tcp_guise 'none'
|
||||
option server 'example.org'
|
||||
option server_port '443'
|
||||
option protocol 'trojan'
|
||||
option alias 'Trojan Example'
|
||||
option trojan_flow 'none'
|
||||
option trojan_tls 'tls'
|
||||
option trojan_tls_host 'example.org'
|
||||
option trojan_tls_insecure '0'
|
||||
@@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
DEFAULT_GATEWAY=$(ip route get 1.1.1.1 | grep -Eoe "src (\d+.\d+.\d+.\d+)" | awk '{print $NF}')
|
||||
if [ -n "$DEFAULT_GATEWAY" ] ; then
|
||||
logger -st transparent-proxy-ipset[$$] -p6 "default gateway available at $DEFAULT_GATEWAY"
|
||||
ipset -! restore <<-EOF
|
||||
create tp_spec_def_gw hash:net hashsize 64
|
||||
flush tp_spec_def_gw
|
||||
add tp_spec_def_gw $DEFAULT_GATEWAY
|
||||
EOF
|
||||
else
|
||||
logger -st transparent-proxy-ipset[$$] -p6 "default gateway not available, please wait for interface ready"
|
||||
fi
|
||||
162
luci-app-xray/root/etc/init.d/xray
Normal file
162
luci-app-xray/root/etc/init.d/xray
Normal file
@@ -0,0 +1,162 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
START=90
|
||||
STOP=15
|
||||
USE_PROCD=1
|
||||
NAME=xray
|
||||
|
||||
GENERATE_CONF="/usr/share/xray/gen_config.lua"
|
||||
FIREWALL_INCLUDE="/usr/share/xray/firewall_include.lua"
|
||||
|
||||
uci_get_by_type() {
|
||||
local ret=$(uci get ${NAME}.@$1[0].$2 2> /dev/null)
|
||||
echo ${ret:=$3}
|
||||
}
|
||||
|
||||
log_procd_set_param() {
|
||||
local type="$1"
|
||||
shift
|
||||
logger -st xray[$$] -p4 "Using procd_set_param $type" "$@"
|
||||
}
|
||||
|
||||
start_xray() {
|
||||
logger -st xray[$$] -p4 "Starting Xray from $1"
|
||||
procd_open_instance
|
||||
procd_set_param respawn 1 1 0
|
||||
procd_set_param command $1
|
||||
procd_append_param command run
|
||||
procd_append_param command -confdir
|
||||
procd_append_param command /var/etc/xray
|
||||
|
||||
local rlimit_nofile
|
||||
if [ -s /usr/share/xray/rlimit_nofile ] ; then
|
||||
rlimit_nofile="nofile=""$(cat /usr/share/xray/rlimit_nofile)"
|
||||
fi
|
||||
|
||||
local rlimit_data
|
||||
if [ -s /usr/share/xray/rlimit_data ] ; then
|
||||
rlimit_data="data=""$(cat /usr/share/xray/rlimit_data)"
|
||||
fi
|
||||
|
||||
# this param passing method is just so fucking weird
|
||||
if [ -z "${rlimit_nofile}" ] ; then
|
||||
if [ ! -z "${rlimit_data}" ]; then
|
||||
log_procd_set_param limits "${rlimit_data}"
|
||||
procd_set_param limits "${rlimit_data}"
|
||||
fi
|
||||
else
|
||||
if [ -z "${rlimit_data}" ]; then
|
||||
log_procd_set_param limits "${rlimit_nofile}"
|
||||
procd_set_param limits "${rlimit_nofile}"
|
||||
else
|
||||
log_procd_set_param limits "${rlimit_data}" "${rlimit_nofile}"
|
||||
procd_set_param limits "${rlimit_data}" "${rlimit_nofile}"
|
||||
fi
|
||||
fi
|
||||
|
||||
procd_set_param env XRAY_LOCATION_ASSET=/usr/share/xray
|
||||
procd_set_param stdout 1
|
||||
procd_set_param stderr 1
|
||||
procd_set_param file /etc/config/xray
|
||||
procd_set_param pidfile /var/run/xray.pid
|
||||
procd_close_instance
|
||||
}
|
||||
|
||||
gen_config_file() {
|
||||
mkdir -p /var/etc/xray
|
||||
rm -f /var/etc/xray/*
|
||||
if [ -s /usr/share/xray/infinite_retry ] ; then
|
||||
while [ ! -s /var/etc/xray/config.json ] ; do
|
||||
logger -st xray[$$] -p4 "(Re)generating Xray configuration files..."
|
||||
/usr/bin/lua ${GENERATE_CONF} > /var/etc/xray/config.json
|
||||
done
|
||||
else
|
||||
logger -st xray[$$] -p4 "Generating Xray configuration files..."
|
||||
/usr/bin/lua ${GENERATE_CONF} > /var/etc/xray/config.json
|
||||
fi
|
||||
local custom_config=$(uci_get_by_type general custom_config)
|
||||
[ ! "${#custom_config}" == "0" ] && echo ${custom_config} > /var/etc/xray/config_custom.json
|
||||
}
|
||||
|
||||
setup_firewall() {
|
||||
logger -st xray[$$] -p4 "Setting ipset rules..."
|
||||
lua /usr/share/xray/gen_ipset_rules.lua | ipset -! restore
|
||||
/etc/hotplug.d/iface/01-transparent-proxy-ipset
|
||||
|
||||
logger -st xray[$$] -p4 "Generating firewall rules..."
|
||||
/usr/bin/lua ${FIREWALL_INCLUDE} enable > $(uci get firewall.xray.path)
|
||||
|
||||
logger -st xray[$$] -p4 "Triggering firewall restart..."
|
||||
/etc/init.d/firewall restart > /dev/null 2>&1
|
||||
}
|
||||
|
||||
flush_firewall() {
|
||||
logger -st xray[$$] -p4 "Flushing firewall rules..."
|
||||
/usr/bin/lua ${FIREWALL_INCLUDE} flush > $(uci get firewall.xray.path)
|
||||
|
||||
logger -st xray[$$] -p4 "Triggering firewall restart..."
|
||||
/etc/init.d/firewall restart > /dev/null 2>&1
|
||||
|
||||
logger -st xray[$$] -p4 "Flushing ipset rules..."
|
||||
for setname in $(ipset -n list | grep "tp_spec"); do
|
||||
ipset -! destroy $setname
|
||||
done
|
||||
/etc/hotplug.d/iface/01-transparent-proxy-ipset
|
||||
}
|
||||
|
||||
setup_dnsmasq() {
|
||||
local dns_port=$(uci_get_by_type general dns_port)
|
||||
local dns_count=$(uci_get_by_type general dns_count 0)
|
||||
|
||||
echo "# Generated dnsmasq configurations by luci-app-xray" > /tmp/dnsmasq.d/xray.conf
|
||||
echo "strict-order" >> /tmp/dnsmasq.d/xray.conf
|
||||
echo "server=/#/127.0.0.1#${dns_port}" >> /tmp/dnsmasq.d/xray.conf
|
||||
local cur_port
|
||||
for cur_port in $(seq ${dns_port} $(expr ${dns_port} + ${dns_count})); do
|
||||
echo "server=127.0.0.1#${cur_port}" >> /tmp/dnsmasq.d/xray.conf
|
||||
done
|
||||
|
||||
logger -st xray[$$] -p4 $(cat /tmp/dnsmasq.d/xray.conf)
|
||||
/etc/init.d/dnsmasq restart > /dev/null 2>&1
|
||||
}
|
||||
|
||||
flush_dnsmasq() {
|
||||
rm /tmp/dnsmasq.d/xray.conf
|
||||
/etc/init.d/dnsmasq restart > /dev/null 2>&1
|
||||
}
|
||||
|
||||
create_when_enable() {
|
||||
[ "$(uci_get_by_type general transparent_proxy_enable)" == "1" ] || return 0
|
||||
logger -st xray[$$] -p4 "Setting dnsmasq and firewall for transparent proxy..."
|
||||
setup_dnsmasq
|
||||
setup_firewall
|
||||
}
|
||||
|
||||
flush_when_disable() {
|
||||
logger -st xray[$$] -p4 "Resetting dnsmasq and firewall configurations..."
|
||||
flush_dnsmasq
|
||||
flush_firewall
|
||||
}
|
||||
|
||||
start_service() {
|
||||
config_load $NAME
|
||||
mkdir -p /var/run /var/etc
|
||||
local xray_bin=$(uci_get_by_type general xray_bin)
|
||||
command -v ${xray_bin} > /dev/null 2>&1 || return 1
|
||||
gen_config_file
|
||||
start_xray ${xray_bin}
|
||||
create_when_enable || flush_when_disable
|
||||
}
|
||||
|
||||
stop_service() {
|
||||
flush_when_disable
|
||||
}
|
||||
|
||||
reload_service() {
|
||||
stop
|
||||
start
|
||||
}
|
||||
|
||||
service_triggers() {
|
||||
procd_add_reload_trigger "xray"
|
||||
}
|
||||
16
luci-app-xray/root/etc/ssl/certs/origin_ca_ecc_root.pem
Normal file
16
luci-app-xray/root/etc/ssl/certs/origin_ca_ecc_root.pem
Normal file
@@ -0,0 +1,16 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICiTCCAi6gAwIBAgIUXZP3MWb8MKwBE1Qbawsp1sfA/Y4wCgYIKoZIzj0EAwIw
|
||||
gY8xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1T
|
||||
YW4gRnJhbmNpc2NvMRkwFwYDVQQKExBDbG91ZEZsYXJlLCBJbmMuMTgwNgYDVQQL
|
||||
Ey9DbG91ZEZsYXJlIE9yaWdpbiBTU0wgRUNDIENlcnRpZmljYXRlIEF1dGhvcml0
|
||||
eTAeFw0xOTA4MjMyMTA4MDBaFw0yOTA4MTUxNzAwMDBaMIGPMQswCQYDVQQGEwJV
|
||||
UzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzEZ
|
||||
MBcGA1UEChMQQ2xvdWRGbGFyZSwgSW5jLjE4MDYGA1UECxMvQ2xvdWRGbGFyZSBP
|
||||
cmlnaW4gU1NMIEVDQyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwWTATBgcqhkjOPQIB
|
||||
BggqhkjOPQMBBwNCAASR+sGALuaGshnUbcxKry+0LEXZ4NY6JUAtSeA6g87K3jaA
|
||||
xpIg9G50PokpfWkhbarLfpcZu0UAoYy2su0EhN7wo2YwZDAOBgNVHQ8BAf8EBAMC
|
||||
AQYwEgYDVR0TAQH/BAgwBgEB/wIBAjAdBgNVHQ4EFgQUhTBdOypw1O3VkmcH/es5
|
||||
tBoOOKcwHwYDVR0jBBgwFoAUhTBdOypw1O3VkmcH/es5tBoOOKcwCgYIKoZIzj0E
|
||||
AwIDSQAwRgIhAKilfntP2ILGZjwajktkBtXE1pB4Y/fjAfLkIRUzrI15AiEA5UCL
|
||||
XYZZ9m2c3fKwIenMMojL1eqydsgqj/wK4p5kagQ=
|
||||
-----END CERTIFICATE-----
|
||||
16
luci-app-xray/root/etc/uci-defaults/xray
Normal file
16
luci-app-xray/root/etc/uci-defaults/xray
Normal file
@@ -0,0 +1,16 @@
|
||||
#!/bin/sh
|
||||
uci get xray.@general[-1] >/dev/null 2>&1 || uci add xray general >/dev/null 2>&1
|
||||
uci commit xray
|
||||
uci -q batch <<-EOF >/dev/null
|
||||
delete ucitrack.@xray[-1]
|
||||
add ucitrack xray
|
||||
set ucitrack.@xray[-1].init=xray
|
||||
commit ucitrack
|
||||
delete firewall.xray
|
||||
set firewall.xray=include
|
||||
set firewall.xray.type=script
|
||||
set firewall.xray.path=/var/etc/xray.include
|
||||
set firewall.xray.reload=1
|
||||
commit firewall
|
||||
EOF
|
||||
exit 0
|
||||
14
luci-app-xray/root/usr/libexec/rpcd/xray
Normal file
14
luci-app-xray/root/usr/libexec/rpcd/xray
Normal file
@@ -0,0 +1,14 @@
|
||||
#!/bin/sh
|
||||
|
||||
main() {
|
||||
case "$1" in
|
||||
list)
|
||||
echo '{"statsquery":{},"statssys":{},"restartlogger":{}}'
|
||||
;;
|
||||
call)
|
||||
shift
|
||||
xray api $@
|
||||
esac
|
||||
}
|
||||
|
||||
main "$@"
|
||||
17
luci-app-xray/root/usr/share/luci/menu.d/luci-app-xray.json
Normal file
17
luci-app-xray/root/usr/share/luci/menu.d/luci-app-xray.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"admin/services/xray": {
|
||||
"title": "Xray",
|
||||
"action": {
|
||||
"type": "view",
|
||||
"path": "xray"
|
||||
},
|
||||
"depends": {
|
||||
"acl": [
|
||||
"luci-app-xray"
|
||||
],
|
||||
"uci": {
|
||||
"xray": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
15
luci-app-xray/root/usr/share/rpcd/acl.d/luci-app-xray.json
Normal file
15
luci-app-xray/root/usr/share/rpcd/acl.d/luci-app-xray.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"luci-app-xray": {
|
||||
"description": "Grant access to xray configurations",
|
||||
"read": {
|
||||
"uci": [
|
||||
"xray"
|
||||
]
|
||||
},
|
||||
"write": {
|
||||
"uci": [
|
||||
"xray"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
65
luci-app-xray/root/usr/share/xray/firewall_include.lua
Normal file
65
luci-app-xray/root/usr/share/xray/firewall_include.lua
Normal file
@@ -0,0 +1,65 @@
|
||||
#!/usr/bin/lua
|
||||
local ucursor = require "luci.model.uci"
|
||||
|
||||
local flush = [[# firewall include file to stop transparent proxy
|
||||
ip rule del fwmark 251 lookup 251
|
||||
ip rule del fwmark 252 lookup 252
|
||||
ip route del local default dev lo table 251
|
||||
ip route del local default dev lo table 252
|
||||
iptables-save -c | grep -v "TP_SPEC" | iptables-restore -c]]
|
||||
local header = [[# firewall include file to start transparent proxy
|
||||
ip rule add fwmark 251 lookup 251
|
||||
ip rule add fwmark 252 lookup 252
|
||||
ip route add local default dev lo table 251
|
||||
ip route add local default dev lo table 252
|
||||
iptables-restore -n <<-EOF
|
||||
*nat
|
||||
COMMIT
|
||||
*mangle
|
||||
:TP_SPEC_LAN_AC - [0:0]
|
||||
:TP_SPEC_LAN_DG - [0:0]
|
||||
:TP_SPEC_WAN_AC - [0:0]
|
||||
:TP_SPEC_WAN_DG - [0:0]
|
||||
:TP_SPEC_WAN_FW - [0:0]
|
||||
-I PREROUTING 1 -m mark --mark 0xfc -j TP_SPEC_WAN_AC]]
|
||||
local lan = "-I PREROUTING 1 -i %s -j TP_SPEC_LAN_DG"
|
||||
local rules = [[-A OUTPUT -j TP_SPEC_WAN_DG
|
||||
-A TP_SPEC_LAN_AC -m set --match-set tp_spec_src_bp src -j RETURN
|
||||
-A TP_SPEC_LAN_AC -m set --match-set tp_spec_src_fw src -j TP_SPEC_WAN_FW
|
||||
-A TP_SPEC_LAN_AC -m set --match-set tp_spec_src_ac src -j TP_SPEC_WAN_AC
|
||||
-A TP_SPEC_LAN_AC -j TP_SPEC_WAN_AC
|
||||
-A TP_SPEC_LAN_DG -m set --match-set tp_spec_dst_sp dst -j RETURN
|
||||
-A TP_SPEC_LAN_DG -p tcp -j TP_SPEC_LAN_AC
|
||||
-A TP_SPEC_LAN_DG -p udp -j TP_SPEC_LAN_AC
|
||||
-A TP_SPEC_WAN_AC -m set --match-set tp_spec_dst_fw dst -j TP_SPEC_WAN_FW
|
||||
-A TP_SPEC_WAN_AC -m set --match-set tp_spec_dst_bp dst -j RETURN
|
||||
-A TP_SPEC_WAN_AC -j TP_SPEC_WAN_FW
|
||||
-A TP_SPEC_WAN_DG -m set --match-set tp_spec_dst_sp dst -j RETURN
|
||||
-A TP_SPEC_WAN_DG -m set --match-set tp_spec_dst_bp dst -j RETURN
|
||||
-A TP_SPEC_WAN_DG -m set --match-set tp_spec_def_gw dst -j RETURN
|
||||
-A TP_SPEC_WAN_DG -m mark --mark 0x%x -j RETURN
|
||||
-A TP_SPEC_WAN_DG -p tcp -j MARK --set-xmark 0xfc/0xffffffff
|
||||
-A TP_SPEC_WAN_DG -p udp -j MARK --set-xmark 0xfc/0xffffffff
|
||||
-A TP_SPEC_WAN_FW -p tcp -j TPROXY --on-port %d --on-ip 0.0.0.0 --tproxy-mark 0xfb/0xffffffff
|
||||
-A TP_SPEC_WAN_FW -p udp -j TPROXY --on-port %d --on-ip 0.0.0.0 --tproxy-mark 0xfb/0xffffffff
|
||||
COMMIT
|
||||
*filter
|
||||
COMMIT
|
||||
EOF]]
|
||||
|
||||
local proxy_section = ucursor:get_first("xray", "general")
|
||||
local proxy = ucursor:get_all("xray", proxy_section)
|
||||
|
||||
print(flush)
|
||||
if proxy.transparent_proxy_enable ~= "1" then
|
||||
do
|
||||
return
|
||||
end
|
||||
end
|
||||
if arg[1] == "enable" then
|
||||
print(header)
|
||||
print(string.format(lan, proxy.lan_ifaces))
|
||||
print(string.format(rules, tonumber(proxy.mark), proxy.tproxy_port_tcp, proxy.tproxy_port_udp))
|
||||
else
|
||||
print("# arg[1] == " .. arg[1] .. ", not enable")
|
||||
end
|
||||
1038
luci-app-xray/root/usr/share/xray/gen_config.lua
Normal file
1038
luci-app-xray/root/usr/share/xray/gen_config.lua
Normal file
File diff suppressed because it is too large
Load Diff
80
luci-app-xray/root/usr/share/xray/gen_ipset_rules.lua
Normal file
80
luci-app-xray/root/usr/share/xray/gen_ipset_rules.lua
Normal file
@@ -0,0 +1,80 @@
|
||||
#!/usr/bin/lua
|
||||
|
||||
local io = require("io")
|
||||
local ucursor = require "luci.model.uci"
|
||||
local proxy_section = ucursor:get_first("xray", "general")
|
||||
local proxy = ucursor:get_all("xray", proxy_section)
|
||||
local gen_ipset_rules_extra = dofile("/usr/share/xray/gen_ipset_rules_extra.lua")
|
||||
|
||||
local create_ipset_rules = [[create tp_spec_src_ac hash:mac hashsize 64
|
||||
create tp_spec_src_bp hash:mac hashsize 64
|
||||
create tp_spec_src_fw hash:mac hashsize 64
|
||||
create tp_spec_dst_sp hash:net hashsize 64
|
||||
create tp_spec_dst_bp hash:net hashsize 64
|
||||
create tp_spec_dst_fw hash:net hashsize 64
|
||||
create tp_spec_def_gw hash:net hashsize 64]]
|
||||
|
||||
local function create_ipset()
|
||||
print(create_ipset_rules)
|
||||
end
|
||||
|
||||
local function split_ipv4_host_port(val, port_default)
|
||||
local found, _, ip, port = val:find("([%d.]+):(%d+)")
|
||||
if found == nil then
|
||||
return val, tonumber(port_default)
|
||||
else
|
||||
return ip, tonumber(port)
|
||||
end
|
||||
end
|
||||
|
||||
local function lan_access_control()
|
||||
ucursor:foreach("xray", "lan_hosts", function(v)
|
||||
if v.bypassed == '0' then
|
||||
print(string.format("add tp_spec_src_fw %s", v.macaddr))
|
||||
else
|
||||
print(string.format("add tp_spec_src_bp %s", v.macaddr))
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
local function iterate_list(ln, set_name)
|
||||
local ip_list = proxy[ln]
|
||||
if ip_list == nil then
|
||||
return
|
||||
end
|
||||
for _, line in ipairs(ip_list) do
|
||||
print(string.format("add %s %s", set_name, line))
|
||||
end
|
||||
end
|
||||
|
||||
local function iterate_file(fn, set_name)
|
||||
if fn == nil then
|
||||
return
|
||||
end
|
||||
local f = io.open(fn)
|
||||
if f == nil then
|
||||
return
|
||||
end
|
||||
for line in io.lines(fn) do
|
||||
if line ~= "" then
|
||||
print(string.format("add %s %s", set_name, line))
|
||||
end
|
||||
end
|
||||
f:close()
|
||||
end
|
||||
|
||||
local function dns_ips()
|
||||
local fast_dns_ip, fast_dns_port = split_ipv4_host_port(proxy.fast_dns, 53)
|
||||
local secure_dns_ip, secure_dns_port = split_ipv4_host_port(proxy.secure_dns, 53)
|
||||
print(string.format("add tp_spec_dst_bp %s", fast_dns_ip))
|
||||
print(string.format("add tp_spec_dst_fw %s", secure_dns_ip))
|
||||
end
|
||||
|
||||
create_ipset()
|
||||
dns_ips()
|
||||
lan_access_control()
|
||||
iterate_list("wan_bp_ips", "tp_spec_dst_bp")
|
||||
iterate_file(proxy.wan_bp_list or "/dev/null", "tp_spec_dst_bp")
|
||||
iterate_list("wan_fw_ips", "tp_spec_dst_fw")
|
||||
iterate_file(proxy.wan_fw_list or "/dev/null", "tp_spec_dst_fw")
|
||||
gen_ipset_rules_extra(proxy)
|
||||
@@ -0,0 +1,20 @@
|
||||
#!/usr/bin/lua
|
||||
|
||||
local special_purpose_rules = [[add tp_spec_dst_sp 255.255.255.255
|
||||
add tp_spec_dst_sp 0.0.0.0/8
|
||||
add tp_spec_dst_sp 10.0.0.0/8
|
||||
add tp_spec_dst_sp 100.64.0.0/10
|
||||
add tp_spec_dst_sp 127.0.0.0/8
|
||||
add tp_spec_dst_sp 169.254.0.0/16
|
||||
add tp_spec_dst_sp 172.16.0.0/12
|
||||
add tp_spec_dst_sp 192.0.0.0/24
|
||||
add tp_spec_dst_sp 192.31.196.0/24
|
||||
add tp_spec_dst_sp 192.52.193.0/24
|
||||
add tp_spec_dst_sp 192.88.99.0/24
|
||||
add tp_spec_dst_sp 192.168.0.0/16
|
||||
add tp_spec_dst_sp 192.175.48.0/24
|
||||
add tp_spec_dst_sp 224.0.0.0/3]]
|
||||
|
||||
return function(proxy)
|
||||
print(special_purpose_rules)
|
||||
end
|
||||
BIN
luci-app-xray/root/usr/share/xray/geoip_list.pb
Normal file
BIN
luci-app-xray/root/usr/share/xray/geoip_list.pb
Normal file
Binary file not shown.
1
luci-app-xray/root/usr/share/xray/infinite_retry
Normal file
1
luci-app-xray/root/usr/share/xray/infinite_retry
Normal file
@@ -0,0 +1 @@
|
||||
Remove this file to disable infinite retry on Xray startup.
|
||||
1
luci-app-xray/root/usr/share/xray/optional_feature_1000
Normal file
1
luci-app-xray/root/usr/share/xray/optional_feature_1000
Normal file
@@ -0,0 +1 @@
|
||||
See https://github.com/XTLS/Xray-core/pull/1000 for details.
|
||||
1
luci-app-xray/root/usr/share/xray/rlimit_data_large
Normal file
1
luci-app-xray/root/usr/share/xray/rlimit_data_large
Normal file
@@ -0,0 +1 @@
|
||||
200000000 222222222
|
||||
1
luci-app-xray/root/usr/share/xray/rlimit_data_small
Normal file
1
luci-app-xray/root/usr/share/xray/rlimit_data_small
Normal file
@@ -0,0 +1 @@
|
||||
44444444 55555555
|
||||
1
luci-app-xray/root/usr/share/xray/rlimit_nofile_large
Normal file
1
luci-app-xray/root/usr/share/xray/rlimit_nofile_large
Normal file
@@ -0,0 +1 @@
|
||||
8192 16384
|
||||
719
luci-app-xray/root/www/luci-static/resources/view/xray.js
Normal file
719
luci-app-xray/root/www/luci-static/resources/view/xray.js
Normal file
@@ -0,0 +1,719 @@
|
||||
'use strict';
|
||||
'require view';
|
||||
'require uci';
|
||||
'require form';
|
||||
'require fs';
|
||||
'require network';
|
||||
'require tools.widgets as widgets';
|
||||
|
||||
function add_flow_and_stream_security_conf(s, tab_name, depends_field_name, protocol_name, have_xtls, client_side) {
|
||||
var o;
|
||||
|
||||
o = s.taboption(tab_name, form.ListValue, `${protocol_name}_tls`, _(`[${protocol_name}] Stream Security`))
|
||||
let odep = {}
|
||||
odep[depends_field_name] = protocol_name
|
||||
if (client_side) {
|
||||
o.depends(depends_field_name, protocol_name)
|
||||
o.value("none", "None")
|
||||
} else {
|
||||
odep["web_server_enable"] = "1"
|
||||
}
|
||||
o.value("tls", "TLS")
|
||||
if (have_xtls) {
|
||||
o.value("xtls", "XTLS")
|
||||
}
|
||||
o.depends(odep)
|
||||
o.rmempty = false
|
||||
o.modalonly = true
|
||||
|
||||
if (have_xtls) {
|
||||
o = s.taboption(tab_name, form.ListValue, `${protocol_name}_flow`, _(`[${protocol_name}][xtls] Flow`))
|
||||
let odep = {}
|
||||
odep[depends_field_name] = protocol_name
|
||||
odep[`${protocol_name}_tls`] = "xtls"
|
||||
o.value("none", "none")
|
||||
o.value("xtls-rprx-origin", "xtls-rprx-origin")
|
||||
o.value("xtls-rprx-origin-udp443", "xtls-rprx-origin-udp443")
|
||||
o.value("xtls-rprx-direct", "xtls-rprx-direct")
|
||||
o.value("xtls-rprx-direct-udp443", "xtls-rprx-direct-udp443")
|
||||
if (client_side) {
|
||||
o.value("xtls-rprx-splice", "xtls-rprx-splice")
|
||||
o.value("xtls-rprx-splice-udp443", "xtls-rprx-splice-udp443")
|
||||
} else {
|
||||
odep["web_server_enable"] = "1"
|
||||
}
|
||||
o.depends(odep)
|
||||
o.rmempty = false
|
||||
o.modalonly = true
|
||||
}
|
||||
|
||||
if (client_side) {
|
||||
o = s.taboption(tab_name, form.Value, `${protocol_name}_tls_host`, _(`[${protocol_name}][tls] Server Name`))
|
||||
o.depends(`${protocol_name}_tls`, "tls")
|
||||
o.rmempty = true
|
||||
o.modalonly = true
|
||||
|
||||
o = s.taboption(tab_name, form.Flag, `${protocol_name}_tls_insecure`, _(`[${protocol_name}][tls] Allow Insecure`))
|
||||
o.depends(`${protocol_name}_tls`, "tls")
|
||||
o.rmempty = false
|
||||
o.modalonly = true
|
||||
|
||||
o = s.taboption(tab_name, form.ListValue, `${protocol_name}_tls_fingerprint`, _(`[${protocol_name}][tls] Fingerprint`))
|
||||
o.depends(`${protocol_name}_tls`, "tls")
|
||||
o.value("", "(not set)")
|
||||
o.value("chrome", "chrome")
|
||||
o.value("firefox", "firefox")
|
||||
o.value("safari", "safari")
|
||||
o.value("randomized", "randomized")
|
||||
o.rmempty = true
|
||||
o.modalonly = true
|
||||
|
||||
o = s.taboption(tab_name, form.DynamicList, `${protocol_name}_tls_alpn`, _(`[${protocol_name}][tls] ALPN`))
|
||||
o.depends(`${protocol_name}_tls`, "tls")
|
||||
o.value("h2", "h2")
|
||||
o.value("http/1.1", "http/1.1")
|
||||
o.rmempty = true
|
||||
o.modalonly = true
|
||||
|
||||
if (have_xtls) {
|
||||
o = s.taboption(tab_name, form.Value, `${protocol_name}_xtls_host`, _(`[${protocol_name}][xtls] Server Name`))
|
||||
o.depends(`${protocol_name}_tls`, "xtls")
|
||||
o.rmempty = true
|
||||
o.modalonly = true
|
||||
|
||||
o = s.taboption(tab_name, form.Flag, `${protocol_name}_xtls_insecure`, _(`[${protocol_name}][xtls] Allow Insecure`))
|
||||
o.depends(`${protocol_name}_tls`, "xtls")
|
||||
o.rmempty = false
|
||||
o.modalonly = true
|
||||
|
||||
o = s.taboption(tab_name, form.DynamicList, `${protocol_name}_xtls_alpn`, _(`[${protocol_name}][xtls] ALPN`))
|
||||
o.depends(`${protocol_name}_tls`, "xtls")
|
||||
o.value("h2", "h2")
|
||||
o.value("http/1.1", "http/1.1")
|
||||
o.rmempty = true
|
||||
o.modalonly = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function check_resource_files(load_result) {
|
||||
let geoip_existence = false;
|
||||
let geoip_size = 0;
|
||||
let geosite_existence = false;
|
||||
let geosite_size = 0;
|
||||
let optional_features = {};
|
||||
for (const f of load_result) {
|
||||
if (f.name == "geoip.dat") {
|
||||
geoip_existence = true;
|
||||
geoip_size = '%.2mB'.format(f.size);
|
||||
}
|
||||
if (f.name == "geosite.dat") {
|
||||
geosite_existence = true;
|
||||
geosite_size = '%.2mB'.format(f.size);
|
||||
}
|
||||
if (f.name.startsWith("optional_feature_")) {
|
||||
optional_features[f.name] = true;
|
||||
}
|
||||
}
|
||||
return {
|
||||
geoip_existence: geoip_existence,
|
||||
geoip_size: geoip_size,
|
||||
geosite_existence: geosite_existence,
|
||||
geosite_size: geosite_size,
|
||||
optional_features: optional_features,
|
||||
}
|
||||
}
|
||||
|
||||
return view.extend({
|
||||
load: function () {
|
||||
return Promise.all([
|
||||
uci.load("xray"),
|
||||
fs.list("/usr/share/xray"),
|
||||
network.getHostHints()
|
||||
])
|
||||
},
|
||||
|
||||
render: function (load_result) {
|
||||
const config_data = load_result[0];
|
||||
const { geoip_existence, geoip_size, geosite_existence, geosite_size, optional_features } = check_resource_files(load_result[1]);
|
||||
let asset_file_status = _('WARNING: at least one of asset files (geoip.dat, geosite.dat) is not found under /usr/share/xray. Xray may not work properly. See <a href="https://github.com/yichya/luci-app-xray">here</a> for help.')
|
||||
if (geoip_existence) {
|
||||
if (geosite_existence) {
|
||||
asset_file_status = _('Asset files check: ') + `geoip.dat ${geoip_size}; geosite.dat ${geosite_size}. ` + _('Report issues or request for features <a href="https://github.com/yichya/luci-app-xray">here</a>.')
|
||||
}
|
||||
}
|
||||
|
||||
var m, s, o, ss;
|
||||
m = new form.Map('xray', _('Xray'), asset_file_status);
|
||||
|
||||
s = m.section(form.TypedSection, 'general');
|
||||
s.addremove = false;
|
||||
s.anonymous = true;
|
||||
|
||||
s.tab('general', _('General Settings'));
|
||||
|
||||
o = s.taboption('general', form.Value, 'xray_bin', _('Xray Executable Path'))
|
||||
|
||||
o = s.taboption('general', form.ListValue, 'main_server', _('Main Server'))
|
||||
o.datatype = "uciname"
|
||||
for (var v of uci.sections(config_data, "servers")) {
|
||||
o.value(v[".name"], v.alias || v.server + ":" + v.server_port)
|
||||
}
|
||||
|
||||
o = s.taboption('general', form.ListValue, 'tproxy_udp_server', _('TProxy UDP Server'))
|
||||
for (var v of uci.sections(config_data, "servers")) {
|
||||
o.value(v[".name"], v.alias || v.server + ":" + v.server_port)
|
||||
}
|
||||
|
||||
o = s.taboption('general', form.Flag, 'transparent_proxy_enable', _('Enable Transparent Proxy'), _('This enables DNS query forwarding and TProxy for both TCP and UDP connections.'))
|
||||
|
||||
o = s.taboption('general', form.Flag, 'tproxy_sniffing', _('Enable Sniffing'), _('If sniffing is enabled, requests will be routed according to domain settings in "DNS Settings" tab.'))
|
||||
o.depends("transparent_proxy_enable", "1")
|
||||
|
||||
o = s.taboption('general', form.Flag, 'route_only', _('Route Only'), _('Use sniffed domain for routing only but still access through IP. Reduces unnecessary DNS requests. See <a href="https://github.com/XTLS/Xray-core/commit/a3023e43ef55d4498b1afbc9a7fe7b385138bb1a">here</a> for help.'))
|
||||
o.depends({ "transparent_proxy_enable": "1", "tproxy_sniffing": "1" })
|
||||
|
||||
o = s.taboption('general', form.SectionValue, "xray_servers", form.GridSection, 'servers', _('Xray Servers'), _("Servers are referenced by index (order in the following list). Deleting servers may result in changes of upstream servers actually used by proxy and bridge."))
|
||||
ss = o.subsection
|
||||
ss.sortable = false
|
||||
ss.anonymous = true
|
||||
ss.addremove = true
|
||||
|
||||
ss.tab('general', _('General Settings'));
|
||||
|
||||
o = ss.taboption('general', form.Value, "alias", _("Alias (optional)"))
|
||||
o.rmempty = true
|
||||
|
||||
o = ss.taboption('general', form.Value, 'server', _('Server Hostname'))
|
||||
o.datatype = 'host'
|
||||
|
||||
o = ss.taboption('general', form.ListValue, 'domain_strategy', _('Domain Strategy'))
|
||||
o.value("UseIP")
|
||||
o.value("UseIPv4")
|
||||
o.value("UseIPv6")
|
||||
o.default = "UseIP"
|
||||
o.modalonly = true
|
||||
|
||||
o = ss.taboption('general', form.Value, 'server_port', _('Server Port'))
|
||||
o.datatype = 'port'
|
||||
o.placeholder = '443'
|
||||
|
||||
o = ss.taboption('general', form.Value, 'password', _('UserId / Password'), _('Fill user_id for vmess / VLESS, or password for shadowsocks / trojan (also supports <a href="https://github.com/XTLS/Xray-core/issues/158">Xray UUID Mapping</a>)'))
|
||||
o.modalonly = true
|
||||
|
||||
ss.tab('protocol', _('Protocol Settings'));
|
||||
|
||||
o = ss.taboption('protocol', form.ListValue, "protocol", _("Protocol"))
|
||||
o.value("vmess", "VMess")
|
||||
o.value("vless", "VLESS")
|
||||
o.value("trojan", "Trojan")
|
||||
o.value("shadowsocks", "Shadowsocks")
|
||||
o.rmempty = false
|
||||
|
||||
add_flow_and_stream_security_conf(ss, "protocol", "protocol", "trojan", true, true)
|
||||
|
||||
o = ss.taboption('protocol', form.ListValue, "shadowsocks_security", _("[shadowsocks] Encrypt Method"))
|
||||
o.depends("protocol", "shadowsocks")
|
||||
o.value("none", "none")
|
||||
o.value("aes-256-gcm", "aes-256-gcm")
|
||||
o.value("aes-128-gcm", "aes-128-gcm")
|
||||
o.value("chacha20-poly1305", "chacha20-poly1305")
|
||||
o.rmempty = false
|
||||
o.modalonly = true
|
||||
|
||||
add_flow_and_stream_security_conf(ss, "protocol", "protocol", "shadowsocks", false, true)
|
||||
|
||||
o = ss.taboption('protocol', form.ListValue, "vmess_security", _("[vmess] Encrypt Method"))
|
||||
o.depends("protocol", "vmess")
|
||||
o.value("none", "none")
|
||||
o.value("auto", "auto")
|
||||
o.value("aes-128-gcm", "aes-128-gcm")
|
||||
o.value("chacha20-poly1305", "chacha20-poly1305")
|
||||
o.rmempty = false
|
||||
o.modalonly = true
|
||||
|
||||
o = ss.taboption('protocol', form.ListValue, "vmess_alter_id", _("[vmess] AlterId"), _("Deprecated. Make sure you always use VMessAEAD."))
|
||||
o.depends("protocol", "vmess")
|
||||
o.value(0, "0 (this enables VMessAEAD)")
|
||||
o.value(1, "1")
|
||||
o.value(4, "4")
|
||||
o.value(16, "16")
|
||||
o.value(64, "64")
|
||||
o.value(256, "256")
|
||||
o.rmempty = false
|
||||
o.modalonly = true
|
||||
|
||||
add_flow_and_stream_security_conf(ss, "protocol", "protocol", "vmess", false, true)
|
||||
|
||||
o = ss.taboption('protocol', form.ListValue, "vless_encryption", _("[vless] Encrypt Method"))
|
||||
o.depends("protocol", "vless")
|
||||
o.value("none", "none")
|
||||
o.rmempty = false
|
||||
o.modalonly = true
|
||||
|
||||
add_flow_and_stream_security_conf(ss, "protocol", "protocol", "vless", true, true)
|
||||
|
||||
ss.tab('transport', _('Transport Settings'));
|
||||
|
||||
o = ss.taboption('transport', form.ListValue, 'transport', _('Transport'))
|
||||
o.value("tcp", "TCP")
|
||||
o.value("mkcp", "mKCP")
|
||||
o.value("ws", "WebSocket")
|
||||
o.value("h2", "HTTP/2")
|
||||
o.value("quic", "QUIC")
|
||||
o.value("grpc", "gRPC")
|
||||
o.rmempty = false
|
||||
|
||||
o = ss.taboption('transport', form.ListValue, "tcp_guise", _("[tcp] Fake Header Type"))
|
||||
o.depends("transport", "tcp")
|
||||
o.value("none", _("None"))
|
||||
o.value("http", "HTTP")
|
||||
o.rmempty = true
|
||||
o.modalonly = true
|
||||
|
||||
o = ss.taboption('transport', form.DynamicList, "http_host", _("[tcp][fake_http] Host"))
|
||||
o.depends("tcp_guise", "http")
|
||||
o.rmempty = true
|
||||
o.modalonly = true
|
||||
|
||||
o = ss.taboption('transport', form.DynamicList, "http_path", _("[tcp][fake_http] Path"))
|
||||
o.depends("tcp_guise", "http")
|
||||
o.rmempty = true
|
||||
o.modalonly = true
|
||||
|
||||
o = ss.taboption('transport', form.ListValue, "mkcp_guise", _("[mkcp] Fake Header Type"))
|
||||
o.depends("transport", "mkcp")
|
||||
o.value("none", _("None"))
|
||||
o.value("srtp", _("VideoCall (SRTP)"))
|
||||
o.value("utp", _("BitTorrent (uTP)"))
|
||||
o.value("wechat-video", _("WechatVideo"))
|
||||
o.value("dtls", "DTLS 1.2")
|
||||
o.value("wireguard", "WireGuard")
|
||||
o.rmempty = true
|
||||
o.modalonly = true
|
||||
|
||||
o = ss.taboption('transport', form.Value, "mkcp_mtu", _("[mkcp] Maximum Transmission Unit"))
|
||||
o.datatype = "uinteger"
|
||||
o.depends("transport", "mkcp")
|
||||
o.default = 1350
|
||||
o.rmempty = true
|
||||
o.modalonly = true
|
||||
|
||||
o = ss.taboption('transport', form.Value, "mkcp_tti", _("[mkcp] Transmission Time Interval"))
|
||||
o.datatype = "uinteger"
|
||||
o.depends("transport", "mkcp")
|
||||
o.default = 50
|
||||
o.rmempty = true
|
||||
o.modalonly = true
|
||||
|
||||
o = ss.taboption('transport', form.Value, "mkcp_uplink_capacity", _("[mkcp] Uplink Capacity"))
|
||||
o.datatype = "uinteger"
|
||||
o.depends("transport", "mkcp")
|
||||
o.default = 5
|
||||
o.rmempty = true
|
||||
o.modalonly = true
|
||||
|
||||
o = ss.taboption('transport', form.Value, "mkcp_downlink_capacity", _("[mkcp] Downlink Capacity"))
|
||||
o.datatype = "uinteger"
|
||||
o.depends("transport", "mkcp")
|
||||
o.default = 20
|
||||
o.rmempty = true
|
||||
o.modalonly = true
|
||||
|
||||
o = ss.taboption('transport', form.Value, "mkcp_read_buffer_size", _("[mkcp] Read Buffer Size"))
|
||||
o.datatype = "uinteger"
|
||||
o.depends("transport", "mkcp")
|
||||
o.default = 2
|
||||
o.rmempty = true
|
||||
o.modalonly = true
|
||||
|
||||
o = ss.taboption('transport', form.Value, "mkcp_write_buffer_size", _("[mkcp] Write Buffer Size"))
|
||||
o.datatype = "uinteger"
|
||||
o.depends("transport", "mkcp")
|
||||
o.default = 2
|
||||
o.rmempty = true
|
||||
o.modalonly = true
|
||||
|
||||
o = ss.taboption('transport', form.Flag, "mkcp_congestion", _("[mkcp] Congestion Control"))
|
||||
o.depends("transport", "mkcp")
|
||||
o.rmempty = true
|
||||
o.modalonly = true
|
||||
|
||||
o = ss.taboption('transport', form.Value, "mkcp_seed", _("[mkcp] Seed"))
|
||||
o.depends("transport", "mkcp")
|
||||
o.rmempty = true
|
||||
o.modalonly = true
|
||||
|
||||
o = ss.taboption('transport', form.ListValue, "quic_security", _("[quic] Security"))
|
||||
o.depends("transport", "quic")
|
||||
o.value("none", "none")
|
||||
o.value("aes-128-gcm", "aes-128-gcm")
|
||||
o.value("chacha20-poly1305", "chacha20-poly1305")
|
||||
o.rmempty = false
|
||||
o.modalonly = true
|
||||
|
||||
o = ss.taboption('transport', form.Value, "quic_key", _("[quic] Key"))
|
||||
o.depends("transport", "quic")
|
||||
o.rmempty = true
|
||||
o.modalonly = true
|
||||
|
||||
o = ss.taboption('transport', form.ListValue, "quic_guise", _("[quic] Fake Header Type"))
|
||||
o.depends("transport", "quic")
|
||||
o.value("none", _("None"))
|
||||
o.value("srtp", _("VideoCall (SRTP)"))
|
||||
o.value("utp", _("BitTorrent (uTP)"))
|
||||
o.value("wechat-video", _("WechatVideo"))
|
||||
o.value("dtls", "DTLS 1.2")
|
||||
o.value("wireguard", "WireGuard")
|
||||
o.rmempty = true
|
||||
o.modalonly = true
|
||||
|
||||
o = ss.taboption('transport', form.DynamicList, "h2_host", _("[http2] Host"))
|
||||
o.depends("transport", "h2")
|
||||
o.rmempty = true
|
||||
o.modalonly = true
|
||||
|
||||
o = ss.taboption('transport', form.Value, "h2_path", _("[http2] Path"))
|
||||
o.depends("transport", "h2")
|
||||
o.rmempty = true
|
||||
o.modalonly = true
|
||||
|
||||
o = ss.taboption('transport', form.Value, "grpc_service_name", _("[grpc] Service Name"))
|
||||
o.depends("transport", "grpc")
|
||||
o.rmempty = true
|
||||
o.modalonly = true
|
||||
|
||||
o = ss.taboption('transport', form.Flag, "grpc_multi_mode", _("[grpc] Multi Mode"))
|
||||
o.depends("transport", "grpc")
|
||||
o.rmempty = true
|
||||
o.modalonly = true
|
||||
|
||||
o = ss.taboption('transport', form.Flag, "grpc_health_check", _("[grpc] Health Check"))
|
||||
o.depends("transport", "grpc")
|
||||
o.rmempty = true
|
||||
o.modalonly = true
|
||||
|
||||
o = ss.taboption('transport', form.Value, "grpc_idle_timeout", _("[grpc] Idle Timeout"))
|
||||
o.depends({ "transport": "grpc", "grpc_health_check": "1" })
|
||||
o.rmempty = true
|
||||
o.modalonly = true
|
||||
o.default = 10
|
||||
o.datatype = 'integer'
|
||||
|
||||
o = ss.taboption('transport', form.Value, "grpc_health_check_timeout", _("[grpc] Health Check Timeout"))
|
||||
o.depends({ "transport": "grpc", "grpc_health_check": "1" })
|
||||
o.rmempty = true
|
||||
o.modalonly = true
|
||||
o.default = 20
|
||||
o.datatype = 'integer'
|
||||
|
||||
o = ss.taboption('transport', form.Flag, "grpc_permit_without_stream", _("[grpc] Permit Without Stream"))
|
||||
o.depends({ "transport": "grpc", "grpc_health_check": "1" })
|
||||
o.rmempty = true
|
||||
o.modalonly = true
|
||||
|
||||
o = ss.taboption('transport', form.Value, "grpc_initial_windows_size", _("[grpc] Initial Windows Size"), _("Set to 524288 to avoid Cloudflare sending ENHANCE_YOUR_CALM."))
|
||||
o.depends("transport", "grpc")
|
||||
o.rmempty = true
|
||||
o.modalonly = true
|
||||
o.default = 0
|
||||
o.datatype = 'integer'
|
||||
|
||||
o = ss.taboption('transport', form.Value, "ws_host", _("[websocket] Host"))
|
||||
o.depends("transport", "ws")
|
||||
o.rmempty = true
|
||||
o.modalonly = true
|
||||
|
||||
o = ss.taboption('transport', form.Value, "ws_path", _("[websocket] Path"))
|
||||
o.depends("transport", "ws")
|
||||
o.rmempty = true
|
||||
o.modalonly = true
|
||||
|
||||
s.tab('proxy', _('Proxy Settings'));
|
||||
|
||||
o = s.taboption('proxy', form.Value, 'tproxy_port_tcp', _('Transparent Proxy Port (TCP)'))
|
||||
o.datatype = 'port'
|
||||
o.default = 1080
|
||||
|
||||
o = s.taboption('proxy', form.Value, 'tproxy_port_udp', _('Transparent Proxy Port (UDP)'))
|
||||
o.datatype = 'port'
|
||||
o.default = 1080
|
||||
|
||||
o = s.taboption('proxy', form.Value, 'socks_port', _('Socks5 Proxy Port'))
|
||||
o.datatype = 'port'
|
||||
o.default = 1082
|
||||
|
||||
o = s.taboption('proxy', form.Value, 'http_port', _('HTTP Proxy Port'))
|
||||
o.datatype = 'port'
|
||||
o.default = 1083
|
||||
|
||||
o = s.taboption('proxy', form.Value, 'dns_port', _('Xray DNS Server Port'), _("Do not use port 53 (dnsmasq), port 5353 (mDNS) or other common ports"))
|
||||
o.datatype = 'port'
|
||||
o.default = 5300
|
||||
|
||||
o = s.taboption('proxy', form.Value, 'dns_count', _('Extra DNS Server Ports'), _('Listen for DNS Requests on multiple ports (all of which serves as dnsmasq upstream servers).<br/>For example if Xray DNS Server Port is 5300 and use 3 extra ports, 5300 - 5303 will be used for DNS requests.<br/>Increasing this value may help reduce the possibility of temporary DNS lookup failures.'))
|
||||
o.datatype = 'range(0, 50)'
|
||||
o.default = 0
|
||||
|
||||
o = s.taboption('proxy', form.Value, 'mark', _('Socket Mark Number'), _('Avoid proxy loopback problems with local (gateway) traffic'))
|
||||
o.datatype = 'range(1, 255)'
|
||||
o.default = 255
|
||||
|
||||
o = s.taboption('proxy', widgets.DeviceSelect, 'lan_ifaces', _("LAN Interface"))
|
||||
o.noaliases = true
|
||||
o.rmempty = false
|
||||
o.nocreate = true
|
||||
|
||||
o = s.taboption('proxy', form.SectionValue, "access_control_lan_hosts", form.TableSection, 'lan_hosts', _('LAN Hosts Access Control'), _("Will not enable transparent proxy for these MAC addresses."))
|
||||
|
||||
ss = o.subsection;
|
||||
ss.sortable = false
|
||||
ss.anonymous = true
|
||||
ss.addremove = true
|
||||
|
||||
o = ss.option(form.Value, "macaddr", _("MAC Address"))
|
||||
L.sortedKeys(load_result[2].hosts).forEach(function (mac) {
|
||||
o.value(mac, E([], [mac, ' (', E('strong', [load_result[2].hosts[mac].name || L.toArray(load_result[2].hosts[mac].ipaddrs || load_result[2].hosts[mac].ipv4)[0] || L.toArray(load_result[2].hosts[mac].ip6addrs || load_result[2].hosts[mac].ipv6)[0] || '?']), ')']));
|
||||
});
|
||||
|
||||
o.datatype = "macaddr"
|
||||
o.rmempty = false
|
||||
|
||||
o = ss.option(form.ListValue, "bypassed", _("Access Control Strategy"))
|
||||
o.value("0", "Always forwarded")
|
||||
o.value("1", "Always bypassed")
|
||||
o.rmempty = false
|
||||
|
||||
s.tab('dns', _('DNS Settings'));
|
||||
|
||||
o = s.taboption('dns', form.Value, 'fast_dns', _('Fast DNS'), _("DNS for resolving outbound domains and following bypassed domains"))
|
||||
o.datatype = 'or(ip4addr, ip4addrport)'
|
||||
o.placeholder = "114.114.114.114"
|
||||
|
||||
if (geosite_existence) {
|
||||
o = s.taboption('dns', form.DynamicList, "bypassed_domain_rules", _('Bypassed domain rules'), _('Specify rules like <code>geosite:cn</code> or <code>domain:bilibili.com</code>. See <a href="https://xtls.github.io/config/dns.html#dnsobject">documentation</a> for details.'))
|
||||
} else {
|
||||
o = s.taboption('dns', form.DynamicList, 'bypassed_domain_rules', _('Bypassed domain rules'), _('Specify rules like <code>domain:bilibili.com</code> or see <a href="https://xtls.github.io/config/dns.html#dnsobject">documentation</a> for details.<br/> In order to use Geosite rules you need a valid resource file /usr/share/xray/geosite.dat.<br/>Compile your firmware again with data files to use Geosite rules, or <a href="https://github.com/v2fly/domain-list-community">download one</a> and upload it to your router.'))
|
||||
}
|
||||
o.rmempty = true
|
||||
|
||||
o = s.taboption('dns', form.Value, 'secure_dns', _('Secure DNS'), _("DNS for resolving known polluted domains (specify forwarded domain rules here)"))
|
||||
o.datatype = 'or(ip4addr, ip4addrport)'
|
||||
o.placeholder = "1.1.1.1"
|
||||
|
||||
if (geosite_existence) {
|
||||
o = s.taboption('dns', form.DynamicList, "forwarded_domain_rules", _('Forwarded domain rules'), _('Specify rules like <code>geosite:geolocation-!cn</code> or <code>domain:youtube.com</code>. See <a href="https://xtls.github.io/config/dns.html#dnsobject">documentation</a> for details.'))
|
||||
} else {
|
||||
o = s.taboption('dns', form.DynamicList, 'forwarded_domain_rules', _('Forwarded domain rules'), _('Specify rules like <code>domain:youtube.com</code> or see <a href="https://xtls.github.io/config/dns.html#dnsobject">documentation</a> for details.<br/> In order to use Geosite rules you need a valid resource file /usr/share/xray/geosite.dat.<br/>Compile your firmware again with data files to use Geosite rules, or <a href="https://github.com/v2fly/domain-list-community">download one</a> and upload it to your router.'))
|
||||
}
|
||||
o.rmempty = true
|
||||
|
||||
o = s.taboption('dns', form.Value, 'default_dns', _('Default DNS'), _("DNS for resolving other sites (not in the rules above) and DNS records other than A or AAAA (TXT and MX for example)"))
|
||||
o.datatype = 'or(ip4addr, ip4addrport)'
|
||||
o.placeholder = "8.8.8.8"
|
||||
|
||||
if (geosite_existence) {
|
||||
o = s.taboption('dns', form.DynamicList, "blocked_domain_rules", _('Blocked domain rules'), _('Specify rules like <code>geosite:category-ads</code> or <code>domain:baidu.com</code>. See <a href="https://xtls.github.io/config/dns.html#dnsobject">documentation</a> for details.'))
|
||||
} else {
|
||||
o = s.taboption('dns', form.DynamicList, 'blocked_domain_rules', _('Blocked domain rules'), _('Specify rules like <code>domain:baidu.com</code> or see <a href="https://xtls.github.io/config/dns.html#dnsobject">documentation</a> for details.<br/> In order to use Geosite rules you need a valid resource file /usr/share/xray/geosite.dat.<br/>Compile your firmware again with data files to use Geosite rules, or <a href="https://github.com/v2fly/domain-list-community">download one</a> and upload it to your router.'))
|
||||
}
|
||||
o.rmempty = true
|
||||
|
||||
s.tab('access_control', _('Transparent Proxy Rules'));
|
||||
|
||||
if (geoip_existence) {
|
||||
o = s.taboption('access_control', form.Value, 'geoip_direct_code', _('GeoIP Direct Code'), _("Hosts in this GeoIP set will not be forwarded through Xray. Set to unspecified to forward all non-private hosts."))
|
||||
} else {
|
||||
o = s.taboption('access_control', form.Value, 'geoip_direct_code', _('GeoIP Direct Code'), _("Resource file /usr/share/xray/geoip.dat not exist. All network traffic will be forwarded. <br/> Compile your firmware again with data files to use this feature, or<br/><a href=\"https://github.com/v2fly/geoip\">download one</a> (maybe disable transparent proxy first) and upload it to your router."))
|
||||
o.readonly = true
|
||||
}
|
||||
o.value("cn", "cn")
|
||||
o.value("telegram", "telegram")
|
||||
o.datatype = "string"
|
||||
|
||||
o = s.taboption('access_control', form.ListValue, 'routing_domain_strategy', _('Routing Domain Strategy'), _("Domain resolution strategy when matching domain against rules."))
|
||||
o.value("AsIs", "AsIs")
|
||||
o.value("IPIfNonMatch", "IPIfNonMatch")
|
||||
o.value("IPOnDemand", "IPOnDemand")
|
||||
o.default = "AsIs"
|
||||
o.rmempty = false
|
||||
|
||||
o = s.taboption('access_control', form.DynamicList, "wan_bp_ips", _("Bypassed IP"), _("Requests to these IPs won't be forwarded through Xray."))
|
||||
o.datatype = "ip4addr"
|
||||
o.rmempty = false
|
||||
|
||||
o = s.taboption('access_control', form.DynamicList, "wan_fw_ips", _("Forwarded IP"))
|
||||
o.datatype = "ip4addr"
|
||||
o.rmempty = true
|
||||
|
||||
o = s.taboption('access_control', form.SectionValue, "access_control_manual_tproxy", form.GridSection, 'manual_tproxy', _('Manual Transparent Proxy'), _('Compared to iptables REDIRECT, Xray could do NAT46 / NAT64 (for example accessing IPv6 only sites). See <a href="https://github.com/v2ray/v2ray-core/issues/2233">FakeDNS</a> for details.'))
|
||||
|
||||
ss = o.subsection;
|
||||
ss.sortable = false
|
||||
ss.anonymous = true
|
||||
ss.addremove = true
|
||||
|
||||
o = ss.option(form.Value, "source_addr", _("Source Address"))
|
||||
o.datatype = "ipaddr"
|
||||
o.rmempty = true
|
||||
|
||||
o = ss.option(form.Value, "source_port", _("Source Port"))
|
||||
o.rmempty = true
|
||||
|
||||
o = ss.option(form.Value, "dest_addr", _("Destination Address"))
|
||||
o.datatype = "host"
|
||||
o.rmempty = true
|
||||
|
||||
o = ss.option(form.Value, "dest_port", _("Destination Port"))
|
||||
o.datatype = "port"
|
||||
o.rmempty = true
|
||||
|
||||
o = ss.option(form.ListValue, 'domain_strategy', _('Domain Strategy'))
|
||||
o.value("UseIP")
|
||||
o.value("UseIPv4")
|
||||
o.value("UseIPv6")
|
||||
o.default = "UseIP"
|
||||
o.modalonly = true
|
||||
|
||||
o = ss.option(form.Flag, 'force_forward', _('Force Forward'), _('This destination must be forwarded through Xray. (This option might be removed later.)'))
|
||||
o.modalonly = true
|
||||
|
||||
s.tab('xray_server', _('HTTPS Server'));
|
||||
|
||||
o = s.taboption('xray_server', form.Flag, 'web_server_enable', _('Enable Xray HTTPS Server'), _("This will start a HTTPS server at port 443 which serves both as an inbound for Xray and a reverse proxy web server."));
|
||||
o = s.taboption('xray_server', form.FileUpload, 'web_server_cert_file', _('Certificate File'));
|
||||
o.root_directory = "/etc/luci-uploads/xray"
|
||||
o.depends("web_server_enable", "1")
|
||||
|
||||
o = s.taboption('xray_server', form.FileUpload, 'web_server_key_file', _('Private Key File'));
|
||||
o.root_directory = "/etc/luci-uploads/xray"
|
||||
o.depends("web_server_enable", "1")
|
||||
|
||||
o = s.taboption('xray_server', form.ListValue, "web_server_protocol", _("Protocol"), _("Only protocols which support fallback are available."));
|
||||
o.value("vless", "VLESS")
|
||||
o.value("trojan", "Trojan")
|
||||
o.rmempty = false
|
||||
o.depends("web_server_enable", "1")
|
||||
|
||||
add_flow_and_stream_security_conf(s, "xray_server", "web_server_protocol", "vless", true, false)
|
||||
|
||||
add_flow_and_stream_security_conf(s, "xray_server", "web_server_protocol", "trojan", true, false)
|
||||
|
||||
o = s.taboption('xray_server', form.Value, 'web_server_password', _('UserId / Password'), _('Fill user_id for vmess / VLESS, or password for shadowsocks / trojan (also supports <a href="https://github.com/XTLS/Xray-core/issues/158">Xray UUID Mapping</a>)'))
|
||||
o.depends("web_server_enable", "1")
|
||||
|
||||
o = s.taboption('xray_server', form.Value, 'web_server_address', _('Default Fallback HTTP Server'), _("Only HTTP/1.1 supported here. For HTTP/2 upstream, use Fallback Servers below"))
|
||||
o.datatype = 'hostport'
|
||||
o.depends("web_server_enable", "1")
|
||||
|
||||
o = s.taboption('xray_server', form.SectionValue, "xray_server_fallback", form.GridSection, 'fallback', _('Fallback Servers'), _("Specify upstream servers here."))
|
||||
o.depends("web_server_enable", "1")
|
||||
|
||||
ss = o.subsection;
|
||||
ss.sortable = false
|
||||
ss.anonymous = true
|
||||
ss.addremove = true
|
||||
|
||||
o = ss.option(form.Value, "name", _("SNI"))
|
||||
o.rmempty = true
|
||||
|
||||
o = ss.option(form.Value, "alpn", _("ALPN"))
|
||||
o.rmempty = true
|
||||
|
||||
o = ss.option(form.Value, "path", _("Path"))
|
||||
o.rmempty = true
|
||||
|
||||
o = ss.option(form.Value, "xver", _("Xver"))
|
||||
o.datatype = "uinteger"
|
||||
o.rmempty = true
|
||||
|
||||
o = ss.option(form.Value, "dest", _("Destination Address"))
|
||||
o.datatype = 'hostport'
|
||||
o.rmempty = true
|
||||
|
||||
s.tab('extra_options', _('Extra Options'))
|
||||
|
||||
o = s.taboption('extra_options', form.ListValue, 'loglevel', _('Log Level'), _('Read Xray log in "System Log" or use <code>logread</code> command.'))
|
||||
o.value("debug")
|
||||
o.value("info")
|
||||
o.value("warning")
|
||||
o.value("error")
|
||||
o.value("none")
|
||||
o.default = "warning"
|
||||
|
||||
o = s.taboption('extra_options', form.Flag, 'access_log', _('Enable Access Log'), _('Access log will also be written to System Log.'))
|
||||
|
||||
o = s.taboption('extra_options', form.Flag, 'dns_log', _('Enable DNS Log'), _('DNS log will also be written to System Log.'))
|
||||
|
||||
o = s.taboption('extra_options', form.Flag, 'xray_api', _('Enable Xray API Service'), _('Xray API Service uses port 8080 and GRPC protocol. Also callable via <code>xray api</code> or <code>ubus call xray</code>. See <a href="https://xtls.github.io/document/command.html#xray-api">here</a> for help.'))
|
||||
|
||||
o = s.taboption('extra_options', form.Flag, 'stats', _('Enable Statistics'), _('Enable statistics of inbounds / outbounds data. Use Xray API to query values.'))
|
||||
|
||||
o = s.taboption('extra_options', form.Flag, 'observatory', _('Enable Observatory'), _('Enable latency measurement for TCP and UDP outbounds. Support for balancers and strategy will be added later.'))
|
||||
|
||||
o = s.taboption('extra_options', form.Value, 'handshake', _('Handshake Timeout'), _('Policy: Handshake timeout when connecting to upstream. See <a href="https://xtls.github.io/config/policy.html#levelpolicyobject">here</a> for help.'))
|
||||
o.datatype = 'uinteger'
|
||||
o.placeholder = 4
|
||||
o.default = 4
|
||||
|
||||
o = s.taboption('extra_options', form.Value, 'conn_idle', _('Connection Idle Timeout'), _('Policy: Close connection if no data is transferred within given timeout. See <a href="https://xtls.github.io/config/policy.html#levelpolicyobject">here</a> for help.'))
|
||||
o.datatype = 'uinteger'
|
||||
o.placeholder = 300
|
||||
o.default = 300
|
||||
|
||||
o = s.taboption('extra_options', form.Value, 'uplink_only', _('Uplink Only Timeout'), _('Policy: How long to wait before closing connection after server closed connection. See <a href="https://xtls.github.io/config/policy.html#levelpolicyobject">here</a> for help.'))
|
||||
o.datatype = 'uinteger'
|
||||
o.placeholder = 2
|
||||
o.default = 2
|
||||
|
||||
o = s.taboption('extra_options', form.Value, 'downlink_only', _('Downlink Only Timeout'), _('Policy: How long to wait before closing connection after client closed connection. See <a href="https://xtls.github.io/config/policy.html#levelpolicyobject">here</a> for help.'))
|
||||
o.datatype = 'uinteger'
|
||||
o.placeholder = 5
|
||||
o.default = 5
|
||||
|
||||
o = s.taboption('extra_options', form.Value, 'buffer_size', _('Buffer Size'), _('Policy: Internal cache size per connection. See <a href="https://xtls.github.io/config/policy.html#levelpolicyobject">here</a> for help.'))
|
||||
o.datatype = 'uinteger'
|
||||
o.placeholder = 512
|
||||
o.default = 512
|
||||
|
||||
o = s.taboption('extra_options', form.SectionValue, "xray_bridge", form.TableSection, 'bridge', _('Bridge'), _('Reverse proxy tool. Currently only client role (bridge) is supported. See <a href="https://xtls.github.io/config/reverse.html#bridgeobject">here</a> for help.'))
|
||||
|
||||
ss = o.subsection;
|
||||
ss.sortable = false
|
||||
ss.anonymous = true
|
||||
ss.addremove = true
|
||||
|
||||
o = ss.option(form.ListValue, "upstream", _("Upstream"))
|
||||
o.datatype = "uciname"
|
||||
for (var v of uci.sections(config_data, "servers")) {
|
||||
o.value(v[".name"], v.alias || v.server + ":" + v.server_port)
|
||||
}
|
||||
|
||||
o = ss.option(form.Value, "domain", _("Domain"))
|
||||
o.rmempty = false
|
||||
|
||||
o = ss.option(form.Value, "redirect", _("Redirect address"))
|
||||
o.datatype = "hostport"
|
||||
o.rmempty = false
|
||||
|
||||
if (Object.keys(optional_features).length > 0) {
|
||||
s.tab('optional_features', _('Optional Features'), _("Warning: all settings on this page are experimental, not guaranteed to be stable, and quite likely to be changed very frequently. Use at your own risk."))
|
||||
|
||||
if (optional_features["optional_feature_1000"]) {
|
||||
o = s.taboption('optional_features', form.Flag, 'metrics_server_enable', _('Enable Xray Metrics Server'), _("(<a href='https://github.com/XTLS/Xray-core/pull/1000'>#1000</a> Required) Enable built-in metrics server for pprof, expvars and prometheus exporter. "));
|
||||
|
||||
o = s.taboption('optional_features', form.Value, 'metrics_server_port', _('Xray Metrics Server Port'), _("Metrics may be sensitive so think twice before setting it as Default Fallback HTTP Server."))
|
||||
o.depends("metrics_server_enable", "1")
|
||||
o.datatype = 'port'
|
||||
o.placeholder = '18888'
|
||||
}
|
||||
}
|
||||
|
||||
s.tab('custom_options', _('Custom Options'))
|
||||
o = s.taboption('custom_options', form.TextValue, 'custom_config', _('Custom Configurations'), _('Check <code>/var/etc/xray/config.json</code> for tags of generated inbounds and outbounds. See <a href="https://xtls.github.io/config/features/multiple.html">here</a> for help'))
|
||||
o.monospace = true
|
||||
o.rows = 10
|
||||
|
||||
return m.render();
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user