update 04-22 18:55:32
This commit is contained in:
parent
71071a8ab9
commit
ed8e762f3f
|
@ -9,7 +9,7 @@ LUCI_TITLE:=LuCI support for quickstart
|
|||
LUCI_DEPENDS:=+quickstart +shadow-utils +shadow-useradd +luci-app-store +mount-utils
|
||||
LUCI_PKGARCH:=all
|
||||
|
||||
PKG_VERSION:=0.3.3-2
|
||||
PKG_VERSION:=0.3.6-1
|
||||
# PKG_RELEASE MUST be empty for luci.mk
|
||||
PKG_RELEASE:=
|
||||
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -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)))
|
|
@ -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)
|
|
@ -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
|
|
@ -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"
|
||||
}
|
|
@ -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-----
|
|
@ -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
|
|
@ -0,0 +1,14 @@
|
|||
#!/bin/sh
|
||||
|
||||
main() {
|
||||
case "$1" in
|
||||
list)
|
||||
echo '{"statsquery":{},"statssys":{},"restartlogger":{}}'
|
||||
;;
|
||||
call)
|
||||
shift
|
||||
xray api $@
|
||||
esac
|
||||
}
|
||||
|
||||
main "$@"
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"admin/services/xray": {
|
||||
"title": "Xray",
|
||||
"action": {
|
||||
"type": "view",
|
||||
"path": "xray"
|
||||
},
|
||||
"depends": {
|
||||
"acl": [
|
||||
"luci-app-xray"
|
||||
],
|
||||
"uci": {
|
||||
"xray": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"luci-app-xray": {
|
||||
"description": "Grant access to xray configurations",
|
||||
"read": {
|
||||
"uci": [
|
||||
"xray"
|
||||
]
|
||||
},
|
||||
"write": {
|
||||
"uci": [
|
||||
"xray"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
File diff suppressed because it is too large
Load Diff
|
@ -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
|
Binary file not shown.
|
@ -0,0 +1 @@
|
|||
Remove this file to disable infinite retry on Xray startup.
|
|
@ -0,0 +1 @@
|
|||
See https://github.com/XTLS/Xray-core/pull/1000 for details.
|
|
@ -0,0 +1 @@
|
|||
200000000 222222222
|
|
@ -0,0 +1 @@
|
|||
44444444 55555555
|
|
@ -0,0 +1 @@
|
|||
8192 16384
|
|
@ -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();
|
||||
}
|
||||
});
|
|
@ -94,7 +94,7 @@ make -j1 V=s
|
|||
### For Lean openwrt 18.06 LuCI
|
||||
|
||||
```
|
||||
wget --no-check-certificate https://github.com/jerrykuku/luci-theme-argon/releases/download/v1.7.0/luci-theme-argon_1.7.0-20200909_all.ipk
|
||||
wget --no-check-certificate https://github.com/jerrykuku/luci-theme-argon/releases/download/v1.7.3/luci-theme-argon-18.06_1.7.3-20220421_all.ipk
|
||||
opkg install luci-theme-argon*.ipk
|
||||
```
|
||||
|
||||
|
@ -102,7 +102,8 @@ opkg install luci-theme-argon*.ipk
|
|||
|
||||
```
|
||||
opkg install luci-compat
|
||||
wget --no-check-certificate https://github.com/jerrykuku/luci-theme-argon/releases/download/v2.2.5/luci-theme-argon_2.2.5-20200914_all.ipk
|
||||
opkg install luci-lib-ipkg
|
||||
wget --no-check-certificate https://github.com/jerrykuku/luci-theme-argon/releases/download/v2.2.9/luci-theme-argon_2.2.9-20211016-1_all.ipk
|
||||
opkg install luci-theme-argon*.ipk
|
||||
```
|
||||

|
||||
|
|
|
@ -10,7 +10,7 @@ include $(TOPDIR)/rules.mk
|
|||
PKG_ARCH_quickstart:=$(ARCH)
|
||||
|
||||
PKG_NAME:=quickstart
|
||||
PKG_VERSION:=0.3.3
|
||||
PKG_VERSION:=0.3.6
|
||||
PKG_RELEASE:=1
|
||||
PKG_SOURCE:=$(PKG_NAME)-binary-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://fw.koolcenter.com/binary/quickstart/
|
||||
|
|
|
@ -6,7 +6,7 @@ USE_PROCD=1
|
|||
|
||||
start_service() {
|
||||
procd_open_instance
|
||||
procd_set_param command /usr/sbin/quickstart
|
||||
procd_set_param command /usr/sbin/quickstart serve
|
||||
procd_set_param stderr 1
|
||||
procd_set_param respawn
|
||||
procd_close_instance
|
||||
|
|
Loading…
Reference in New Issue