update 04-22 18:55:32

This commit is contained in:
github-actions[bot] 2022-04-22 18:55:32 +08:00
parent 71071a8ab9
commit ed8e762f3f
28 changed files with 2477 additions and 22 deletions

View File

@ -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

132
luci-app-xray/Makefile Normal file
View 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
View 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)

View 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'

View File

@ -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

View 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"
}

View 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-----

View 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

View File

@ -0,0 +1,14 @@
#!/bin/sh
main() {
case "$1" in
list)
echo '{"statsquery":{},"statssys":{},"restartlogger":{}}'
;;
call)
shift
xray api $@
esac
}
main "$@"

View File

@ -0,0 +1,17 @@
{
"admin/services/xray": {
"title": "Xray",
"action": {
"type": "view",
"path": "xray"
},
"depends": {
"acl": [
"luci-app-xray"
],
"uci": {
"xray": true
}
}
}
}

View File

@ -0,0 +1,15 @@
{
"luci-app-xray": {
"description": "Grant access to xray configurations",
"read": {
"uci": [
"xray"
]
},
"write": {
"uci": [
"xray"
]
}
}
}

View 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

File diff suppressed because it is too large Load Diff

View 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)

View File

@ -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.

View File

@ -0,0 +1 @@
Remove this file to disable infinite retry on Xray startup.

View File

@ -0,0 +1 @@
See https://github.com/XTLS/Xray-core/pull/1000 for details.

View File

@ -0,0 +1 @@
200000000 222222222

View File

@ -0,0 +1 @@
44444444 55555555

View File

@ -0,0 +1 @@
8192 16384

View 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();
}
});

View File

@ -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
```
![](/Screenshots/screenshot_pc.jpg)

View File

@ -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/

View File

@ -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