mihomo: sync upstream

last commit: 30b31d9d65
This commit is contained in:
gitea-action 2024-09-25 05:44:33 +08:00
parent 300ac6e0dd
commit 7316cfde5d
15 changed files with 9518 additions and 0 deletions

94
mihomo/Makefile Normal file
View File

@ -0,0 +1,94 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=mihomo
PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/MetaCubeX/mihomo.git
PKG_SOURCE_DATE:=2024-09-23
PKG_SOURCE_VERSION:=59a2b24593fce55244cf3ad3817855b0b1b7f6b3
PKG_MIRROR_HASH:=3d8848f5b4967e401195cb3ea7a03c97a2b6eeb5c5e625e758e9ba51581c5492
PKG_LICENSE:=MIT
PKG_MAINTAINER:=Joseph Mory <morytyann@gmail.com>
PKG_BUILD_DEPENDS:=golang/host
PKG_BUILD_PARALLEL:=1
PKG_BUILD_FLAGS:=no-mips16
PKG_BUILD_VERSION:=alpha-59a2b24
PKG_BUILD_TIME:=$(shell date -u -Iseconds)
GO_PKG:=github.com/metacubex/mihomo
GO_PKG_LDFLAGS_X:=$(GO_PKG)/constant.Version=$(PKG_BUILD_VERSION) $(GO_PKG)/constant.BuildTime=$(PKG_BUILD_TIME)
GO_PKG_TAGS:=with_gvisor
include $(INCLUDE_DIR)/package.mk
include $(TOPDIR)/feeds/packages/lang/golang/golang-package.mk
define Package/mihomo
SECTION:=net
CATEGORY:=Network
TITLE:=A rule based proxy in Go.
URL:=https://wiki.metacubex.one
DEPENDS:=$(GO_ARCH_DEPENDS) +ca-bundle +curl +yq firewall4 +kmod-nft-tproxy +ip-full +kmod-tun +procd-ujail
USERID:=mihomo=7890:mihomo=7890
endef
define Package/mihomo/description
A rule based proxy in Go.
endef
define Package/mihomo/conffiles
/etc/config/mihomo
/etc/mihomo/mixin.yaml
/etc/mihomo/nftables/reserved_ip.nft
/etc/mihomo/nftables/reserved_ip6.nft
endef
define Package/mihomo/install
$(call GoPackage/Package/Install/Bin,$(1))
$(INSTALL_DIR) $(1)/etc/mihomo
$(INSTALL_DIR) $(1)/etc/mihomo/scripts
$(INSTALL_DIR) $(1)/etc/mihomo/nftables
$(INSTALL_DIR) $(1)/etc/mihomo/profiles
$(INSTALL_DIR) $(1)/etc/mihomo/run
$(INSTALL_DIR) $(1)/etc/mihomo/run/rules
$(INSTALL_DIR) $(1)/etc/mihomo/run/ui
$(INSTALL_DATA) $(CURDIR)/files/mixin.yaml $(1)/etc/mihomo/mixin.yaml
$(INSTALL_BIN) $(CURDIR)/files/scripts/constants.sh $(1)/etc/mihomo/scripts/constants.sh
$(INSTALL_BIN) $(CURDIR)/files/scripts/tun.sh $(1)/etc/mihomo/scripts/tun.sh
$(INSTALL_BIN) $(CURDIR)/files/nftables/hijack.nft $(1)/etc/mihomo/nftables/hijack.nft
$(INSTALL_BIN) $(CURDIR)/files/nftables/reserved_ip.nft $(1)/etc/mihomo/nftables/reserved_ip.nft
$(INSTALL_BIN) $(CURDIR)/files/nftables/reserved_ip6.nft $(1)/etc/mihomo/nftables/reserved_ip6.nft
$(INSTALL_BIN) $(CURDIR)/files/nftables/geoip_cn.nft $(1)/etc/mihomo/nftables/geoip_cn.nft
$(INSTALL_BIN) $(CURDIR)/files/nftables/geoip6_cn.nft $(1)/etc/mihomo/nftables/geoip6_cn.nft
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_CONF) $(CURDIR)/files/mihomo.conf $(1)/etc/config/mihomo
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_BIN) $(CURDIR)/files/mihomo.init $(1)/etc/init.d/mihomo
$(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_BIN) $(CURDIR)/files/uci-defaults/init.sh $(1)/etc/uci-defaults/99_init_mihomo
$(INSTALL_BIN) $(CURDIR)/files/uci-defaults/migrate.sh $(1)/etc/uci-defaults/99_migrate_mihomo
$(INSTALL_DIR) $(1)/etc/capabilities
$(INSTALL_DATA) $(CURDIR)/files/capabilities.json $(1)/etc/capabilities/mihomo.json
$(INSTALL_DIR) $(1)/lib/upgrade/keep.d
$(INSTALL_DATA) $(CURDIR)/files/mihomo.upgrade $(1)/lib/upgrade/keep.d/mihomo
endef
define Build/Prepare
$(Build/Prepare/Default)
$(RM) -r $(PKG_BUILD_DIR)/rules/logic_test
endef
$(eval $(call GoBinPackage,mihomo))
$(eval $(call BuildPackage,mihomo))

View File

@ -0,0 +1,47 @@
{
"permitted": [
"CAP_FOWNER",
"CAP_DAC_OVERRIDE",
"CAP_DAC_READ_SEARCH",
"CAP_SYS_PTRACE",
"CAP_NET_ADMIN",
"CAP_NET_BIND_SERVICE",
"CAP_NET_RAW"
],
"effective": [
"CAP_FOWNER",
"CAP_DAC_OVERRIDE",
"CAP_DAC_READ_SEARCH",
"CAP_SYS_PTRACE",
"CAP_NET_ADMIN",
"CAP_NET_BIND_SERVICE",
"CAP_NET_RAW"
],
"bounding": [
"CAP_FOWNER",
"CAP_DAC_OVERRIDE",
"CAP_DAC_READ_SEARCH",
"CAP_SYS_PTRACE",
"CAP_NET_ADMIN",
"CAP_NET_BIND_SERVICE",
"CAP_NET_RAW"
],
"inheritable": [
"CAP_FOWNER",
"CAP_DAC_OVERRIDE",
"CAP_DAC_READ_SEARCH",
"CAP_SYS_PTRACE",
"CAP_NET_ADMIN",
"CAP_NET_BIND_SERVICE",
"CAP_NET_RAW"
],
"ambient": [
"CAP_FOWNER",
"CAP_DAC_OVERRIDE",
"CAP_DAC_READ_SEARCH",
"CAP_SYS_PTRACE",
"CAP_NET_ADMIN",
"CAP_NET_BIND_SERVICE",
"CAP_NET_RAW"
]
}

132
mihomo/files/mihomo.conf Normal file
View File

@ -0,0 +1,132 @@
config status 'status'
config config 'config'
option 'init' '1'
option 'enabled' '0'
option 'scheduled_restart' '0'
option 'cron_expression' '0 3 * * *'
option 'profile' 'subscription:subscription'
option 'mixin' '1'
option 'test_profile' '1'
config proxy 'proxy'
option 'transparent_proxy' '1'
option 'tcp_transparent_proxy_mode' 'tproxy'
option 'udp_transparent_proxy_mode' 'tproxy'
option 'ipv4_dns_hijack' '1'
option 'ipv6_dns_hijack' '1'
option 'ipv4_proxy' '1'
option 'ipv6_proxy' '0'
option 'router_proxy' '1'
option 'lan_proxy' '1'
option 'access_control_mode' 'all'
option 'acl_ip' ''
option 'acl_ip6' ''
option 'acl_mac' ''
option 'bypass_china_mainland_ip' '0'
option 'acl_tcp_dport' '0-65535'
option 'acl_udp_dport' '0-65535'
config subscription 'subscription'
option 'name' 'default'
option 'url' 'http://example.com/default.yaml'
option 'user_agent' 'mihomo'
config mixin 'mixin'
option 'log_level' 'info'
option 'mode' 'rule'
option 'match_process' 'off'
option 'outbound_interface' ''
option 'ipv6' '0'
option 'tcp_keep_alive_idle' '600'
option 'tcp_keep_alive_interval' '15'
option 'ui_name' 'metacubexd'
option 'ui_url' 'https://mirror.ghproxy.com/https://github.com/MetaCubeX/metacubexd/archive/refs/heads/gh-pages.zip'
option 'api_port' '9090'
option 'api_secret' ''
option 'selection_cache' '1'
option 'allow_lan' '1'
option 'http_port' '8080'
option 'socks_port' '1080'
option 'mixed_port' '7890'
option 'redir_port' '7891'
option 'tproxy_port' '7892'
option 'authentication' '1'
option 'tun_stack' 'system'
option 'tun_mtu' '9000'
option 'tun_gso' '1'
option 'tun_gso_max_size' '65536'
option 'tun_endpoint_independent_nat' '0'
option 'dns_port' '1053'
option 'dns_mode' 'fake-ip'
option 'fake_ip_range' '198.18.0.1/16'
option 'fake_ip_filter' '0'
list 'fake_ip_filters' '+.lan'
list 'fake_ip_filters' '+.local'
option 'fake_ip_cache' '1'
option 'dns_respect_rules' '0'
option 'dns_ipv6' '0'
option 'dns_system_hosts' '0'
option 'dns_hosts' '0'
option 'hosts' '0'
option 'dns_nameserver' '0'
option 'dns_nameserver_policy' '0'
option 'geoip_format' 'dat'
option 'geodata_loader' 'memconservative'
option 'geosite_url' 'https://mirror.ghproxy.com/https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geosite.dat'
option 'geoip_mmdb_url' 'https://mirror.ghproxy.com/https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip-lite.metadb'
option 'geoip_dat_url' 'https://mirror.ghproxy.com/https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip-lite.dat'
option 'geoip_asn_url' 'https://mirror.ghproxy.com/https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/GeoLite2-ASN.mmdb'
option 'geox_auto_update' '0'
option 'geox_update_interval' '24'
config authentication
option 'enabled' '1'
option 'username' 'mihomo'
option 'password' ''
config host
option 'enabled' '0'
option 'domain_name' 'localhost'
list 'ip' '127.0.0.1'
list 'ip' '::1'
config nameserver
option 'enabled' '1'
option 'type' 'default-nameserver'
list 'nameserver' '223.5.5.5'
list 'nameserver' '119.29.29.29'
config nameserver
option 'enabled' '1'
option 'type' 'proxy-server-nameserver'
list 'nameserver' 'https://dns.alidns.com/dns-query'
list 'nameserver' 'https://doh.pub/dns-query'
config nameserver
option 'enabled' '1'
option 'type' 'nameserver'
list 'nameserver' 'https://dns.alidns.com/dns-query'
list 'nameserver' 'https://doh.pub/dns-query'
config nameserver
option 'enabled' '0'
option 'type' 'fallback'
list 'nameserver' 'https://dns.cloudflare.com/dns-query'
list 'nameserver' 'https://dns.google/dns-query'
config nameserver_policy
option 'enabled' '1'
option 'matcher' 'geosite:cn,private'
list 'nameserver' 'https://dns.alidns.com/dns-query'
list 'nameserver' 'https://doh.pub/dns-query'
config nameserver_policy
option 'enabled' '1'
option 'matcher' 'geosite:geolocation-!cn'
list 'nameserver' 'https://dns.cloudflare.com/dns-query'
list 'nameserver' 'https://dns.google/dns-query'
config editor 'editor'
config log 'log'

522
mihomo/files/mihomo.init Normal file
View File

@ -0,0 +1,522 @@
#!/bin/sh /etc/rc.common
START=99
STOP=10
USE_PROCD=1
. "$IPKG_INSTROOT/lib/functions/network.sh"
. "$IPKG_INSTROOT/etc/mihomo/scripts/constants.sh"
start_service() {
# clear log
clear_all_log
# load config
config_load mihomo
# check if enabled
local enabled
config_get_bool enabled "config" "enabled" 0
if [ "$enabled" == 0 ]; then
log "App is disabled."
log "Exiting..."
return
fi
log "App is enabled."
log "Starting..."
# get config
## app config
local scheduled_restart cron_expression profile mixin test_profile fast_reload
config_get_bool scheduled_restart "config" "scheduled_restart" 0
config_get cron_expression "config" "cron_expression"
config_get profile "config" "profile"
config_get_bool mixin "config" "mixin" 0
config_get_bool test_profile "config" "test_profile" 0
config_get_bool fast_reload "config" "fast_reload" 0
## proxy config
### transparent proxy
local transparent_proxy tcp_transparent_proxy_mode udp_transparent_proxy_mode ipv4_dns_hijack ipv6_dns_hijack ipv4_proxy ipv6_proxy router_proxy lan_proxy
config_get_bool transparent_proxy "proxy" "transparent_proxy" 0
config_get tcp_transparent_proxy_mode "proxy" "tcp_transparent_proxy_mode" "tproxy"
config_get udp_transparent_proxy_mode "proxy" "udp_transparent_proxy_mode" "tproxy"
config_get_bool ipv4_dns_hijack "proxy" "ipv4_dns_hijack" 0
config_get_bool ipv6_dns_hijack "proxy" "ipv6_dns_hijack" 0
config_get_bool ipv4_proxy "proxy" "ipv4_proxy" 0
config_get_bool ipv6_proxy "proxy" "ipv6_proxy" 0
config_get_bool router_proxy "proxy" "router_proxy" 0
config_get_bool lan_proxy "proxy" "lan_proxy" 0
### access control
local access_control_mode bypass_china_mainland_ip acl_tcp_dport acl_udp_dport
config_get access_control_mode "proxy" "access_control_mode"
config_get_bool bypass_china_mainland_ip "proxy" "bypass_china_mainland_ip" 0
config_get acl_tcp_dport "proxy" "acl_tcp_dport" "0-65535"
config_get acl_udp_dport "proxy" "acl_udp_dport" "0-65535"
## mixin config
### general
local mode match_process outbound_interface ipv6 tcp_keep_alive_idle tcp_keep_alive_interval log_level
config_get mode "mixin" "mode" "rule"
config_get match_process "mixin" "match_process" "off"
config_get outbound_interface "mixin" "outbound_interface"
config_get_bool ipv6 "mixin" "ipv6" 0
config_get tcp_keep_alive_idle "mixin" "tcp_keep_alive_idle" 600
config_get tcp_keep_alive_interval "mixin" "tcp_keep_alive_interval" 15
config_get log_level "mixin" "log_level" "info"
### external control
local ui_name ui_url api_port api_secret selection_cache
config_get ui_name "mixin" "ui_name"
config_get ui_url "mixin" "ui_url"
config_get api_port "mixin" "api_port" "9090"
config_get api_secret "mixin" "api_secret" "666666"
config_get_bool selection_cache "mixin" "selection_cache" 0
### inbound
local allow_lan http_port socks_port mixed_port redir_port tproxy_port authentication
config_get_bool allow_lan "mixin" "allow_lan" 0
config_get http_port "mixin" "http_port" "8080"
config_get socks_port "mixin" "socks_port" "1080"
config_get mixed_port "mixin" "mixed_port" "7890"
config_get redir_port "mixin" "redir_port" "7891"
config_get tproxy_port "mixin" "tproxy_port" "7892"
config_get_bool authentication "mixin" "authentication" 0
### tun
local tun_stack tun_mtu tun_gso tun_gso_max_size tun_endpoint_independent_nat
config_get tun_stack "mixin" "tun_stack" "system"
config_get tun_mtu "mixin" "tun_mtu" "9000"
config_get_bool tun_gso "mixin" "tun_gso" 0
config_get tun_gso_max_size "mixin" "tun_gso_max_size" "65536"
config_get_bool tun_endpoint_independent_nat "mixin" "tun_endpoint_independent_nat" 0
### dns
local dns_port dns_mode fake_ip_range fake_ip_filter fake_ip_filter_mode fake_ip_cache dns_respect_rules dns_ipv6 dns_system_hosts dns_hosts hosts dns_nameserver dns_nameserver_policy
config_get dns_port "mixin" "dns_port" "1053"
config_get dns_mode "mixin" "dns_mode" "redir-host"
config_get fake_ip_range "mixin" "fake_ip_range" "198.18.0.1/16"
config_get_bool fake_ip_filter "mixin" "fake_ip_filter" 0
config_get fake_ip_filter_mode "mixin" "fake_ip_filter_mode" "blacklist"
config_get_bool fake_ip_cache "mixin" "fake_ip_cache" 0
config_get_bool dns_respect_rules "mixin" "dns_respect_rules" 0
config_get_bool dns_ipv6 "mixin" "dns_ipv6" 0
config_get_bool dns_system_hosts "mixin" "dns_system_hosts" 0
config_get_bool dns_hosts "mixin" "dns_hosts" 0
config_get_bool hosts "mixin" "hosts" 0
config_get_bool dns_nameserver "mixin" "dns_nameserver" 0
config_get_bool dns_nameserver_policy "mixin" "dns_nameserver_policy" 0
### geox
local geoip_format geodata_loader geosite_url geoip_mmdb_url geoip_dat_url geoip_asn_url geox_auto_update geox_update_interval
config_get geoip_format "mixin" "geoip_format" "mmdb"
config_get geodata_loader "mixin" "geodata_loader" "memconservative"
config_get geosite_url "mixin" "geosite_url"
config_get geoip_mmdb_url "mixin" "geoip_mmdb_url"
config_get geoip_dat_url "mixin" "geoip_dat_url"
config_get geoip_asn_url "mixin" "geoip_asn_url"
config_get_bool geox_auto_update "mixin" "geox_auto_update" 0
config_get geox_update_interval "mixin" "geox_update_interval" "24"
# prepare
local tproxy_enable; tproxy_enable=0
if [[ "$tcp_transparent_proxy_mode" == "tproxy" || "$udp_transparent_proxy_mode" == "tproxy" ]]; then
tproxy_enable=1
fi
local tun_enable; tun_enable=0
if [[ "$tcp_transparent_proxy_mode" == "tun" || "$udp_transparent_proxy_mode" == "tun" ]]; then
tun_enable=1
fi
# get profile
if [[ "$profile" == "file:"* ]]; then
local profile_name; profile_name=$(basename "${profile/file:/}")
cp -f "$PROFILES_DIR/$profile_name" "$RUN_PROFILE_PATH"
log "Use Profile: $profile_name"
elif [[ "$profile" == "subscription:"* ]]; then
local subscription_section; subscription_section="${profile/subscription:/}"
local subscription_name subscription_url subscription_user_agent
config_get subscription_name "$subscription_section" "name"
config_get subscription_url "$subscription_section" "url"
config_get subscription_user_agent "$subscription_section" "user_agent"
curl -s --connect-timeout 15 --retry 3 -o "$RUN_PROFILE_PATH" -L -H "User-Agent: $subscription_user_agent" "$subscription_url"
if [ "$?" != 0 ]; then
log "Subscription download failed."
log "Exiting..."
return
fi
log "Use Subscription: $subscription_name"
else
return
fi
# mixin
if [ "$mixin" == 0 ]; then
log "Mixin is disabled, only mixin neccesary config."
# do mixin
log_level="$log_level" ipv6="$ipv6" \
ui_path="ui" ui_name="$ui_name" ui_url="$ui_url" api_listen="0.0.0.0:$api_port" api_secret="$api_secret" \
http_port="$http_port" socks_port="$socks_port" mixed_port="$mixed_port" redir_port="$redir_port" tproxy_port="$tproxy_port" \
tun_enable="$tun_enable" tun_stack="$tun_stack" tun_device="$TUN_DEVICE" tun_mtu="$tun_mtu" tun_gso="$tun_gso" tun_gso_max_size="$tun_gso_max_size" tun_endpoint_independent_nat="$tun_endpoint_independent_nat" \
dns_enable="true" dns_listen="0.0.0.0:$dns_port" \
yq -M -i '
.log-level = env(log_level) | .ipv6 = env(ipv6) == 1 |
.external-ui = env(ui_path) | .external-ui-name = env(ui_name) | .external-ui-url = env(ui_url) | .external-controller = env(api_listen) | .secret = env(api_secret) |
.port = env(http_port) | .socks-port = env(socks_port) | .mixed-port = env(mixed_port) | .redir-port = env(redir_port) | .tproxy-port = env(tproxy_port) |
.tun.enable = env(tun_enable) == 1 | .tun.stack = env(tun_stack) | .tun.device = env(tun_device) | .tun.mtu = env(tun_mtu) | .tun.gso = env(tun_gso) == 1 | .tun.gso-max-size = env(tun_gso_max_size) | .tun.endpoint-independent-nat = env(tun_endpoint_independent_nat) == 1 |
.dns.enable = env(dns_enable) | .dns.listen = env(dns_listen)
' "$RUN_PROFILE_PATH"
else
log "Mixin is enabled, mixin all config."
# do mixin
log_level="$log_level" mode="$mode" match_process="$match_process" tcp_keep_alive_idle="$tcp_keep_alive_idle" tcp_keep_alive_interval="$tcp_keep_alive_interval" ipv6="$ipv6" \
ui_path="ui" ui_name="$ui_name" ui_url="$ui_url" api_listen="0.0.0.0:$api_port" api_secret="$api_secret" selection_cache="$selection_cache" \
allow_lan="$allow_lan" http_port="$http_port" socks_port="$socks_port" mixed_port="$mixed_port" redir_port="$redir_port" tproxy_port="$tproxy_port" \
tun_enable="$tun_enable" tun_stack="$tun_stack" tun_device="$TUN_DEVICE" tun_mtu="$tun_mtu" tun_gso="$tun_gso" tun_gso_max_size="$tun_gso_max_size" tun_endpoint_independent_nat="$tun_endpoint_independent_nat" \
dns_enable="true" dns_listen="0.0.0.0:$dns_port" dns_mode="$dns_mode" fake_ip_range="$fake_ip_range" fake_ip_cache="$fake_ip_cache" \
dns_respect_rules="$dns_respect_rules" dns_ipv6="$dns_ipv6" dns_system_hosts="$dns_system_hosts" dns_hosts="$dns_hosts" \
geoip_format="$geoip_format" geodata_loader="$geodata_loader" geosite_url="$geosite_url" geoip_mmdb_url="$geoip_mmdb_url" geoip_dat_url="$geoip_dat_url" geoip_asn_url="$geoip_asn_url" \
geox_auto_update="$geox_auto_update" geox_update_interval="$geox_update_interval" \
yq -M -i '
.log-level = env(log_level) | .mode = env(mode) | .find-process-mode = env(match_process) | .keep-alive-idle = env(tcp_keep_alive_idle) | .keep-alive-interval = env(tcp_keep_alive_interval) | .ipv6 = env(ipv6) == 1 |
.external-ui = env(ui_path) | .external-ui-name = env(ui_name) | .external-ui-url = env(ui_url) | .external-controller = env(api_listen) | .secret = env(api_secret) | .profile.store-selected = env(selection_cache) == 1 |
.allow-lan = env(allow_lan) == 1 | .port = env(http_port) | .socks-port = env(socks_port) | .mixed-port = env(mixed_port) | .redir-port = env(redir_port) | .tproxy-port = env(tproxy_port) |
.tun.enable = env(tun_enable) == 1 | .tun.stack = env(tun_stack) | .tun.device = env(tun_device) | .tun.mtu = env(tun_mtu) | .tun.gso = env(tun_gso) == 1 | .tun.gso-max-size = env(tun_gso_max_size) | .tun.endpoint-independent-nat = env(tun_endpoint_independent_nat) == 1 |
.dns.enable = env(dns_enable) | .dns.listen = env(dns_listen) | .dns.enhanced-mode = env(dns_mode) | .dns.fake-ip-range = env(fake_ip_range) | .profile.store-fake-ip = env(fake_ip_cache) == 1 |
.dns.respect-rules = env(dns_respect_rules) == 1 | .dns.ipv6 = env(dns_ipv6) == 1 | .dns.use-system-hosts = env(dns_system_hosts) == 1 | .dns.use-hosts = env(dns_hosts) == 1 |
.geodata-mode = env(geoip_format) == "dat" | .geodata-loader = env(geodata_loader) | .geox-url.geosite = env(geosite_url) | .geox-url.mmdb = env(geoip_mmdb_url) | .geox-url.geoip = env(geoip_dat_url) | .geox-url.asn = env(geoip_asn_url) |
.geo-auto-update = env(geox_auto_update) == 1 | .geo-update-interval = env(geox_update_interval)
' "$RUN_PROFILE_PATH"
if [ "$authentication" == 1 ]; then
yq -M -i 'del(.authentication)' "$RUN_PROFILE_PATH"
config_foreach mixin_authentications "authentication"
fi
if [ "$fake_ip_filter" == 1 ]; then
fake_ip_filter_mode="$fake_ip_filter_mode" \
yq -M -i 'del(.dns.fake-ip-filter) | .dns.fake-ip-filter-mode = env(fake_ip_filter_mode)' "$RUN_PROFILE_PATH"
config_list_foreach "mixin" "fake_ip_filters" mixin_fake_ip_filters
fi
if [ "$hosts" == 1 ]; then
yq -M -i 'del(.hosts)' "$RUN_PROFILE_PATH"
config_foreach mixin_hosts "host"
fi
if [ "$dns_nameserver" == 1 ]; then
yq -M -i 'del(.dns.default-nameserver) | del(.dns.proxy-server-nameserver) | del(.dns.nameserver) | del(.dns.fallback)' "$RUN_PROFILE_PATH"
config_foreach mixin_nameservers "nameserver"
fi
if [ "$dns_nameserver_policy" == 1 ]; then
yq -M -i 'del(.dns.nameserver-policy)' "$RUN_PROFILE_PATH"
config_foreach mixin_nameserver_policies "nameserver_policy"
fi
# mixin file
if [ -s "$MIXIN_FILE_PATH" ]; then
yq ea -M -i '. as $item ireduce ({}; . * $item ) | ... comments=""' "$RUN_PROFILE_PATH" "$MIXIN_FILE_PATH"
fi
fi
yq -M -i 'del (.bind-address)' "$RUN_PROFILE_PATH"
if [ "$tun_enable" == 1 ]; then
yq -M -i '.tun.auto-route = false | .tun.auto-redirect = false | .tun.auto-detect-interface = false | .tun.dns-hijack = []' "$RUN_PROFILE_PATH"
fi
if [ -n "$outbound_interface" ]; then
local outbound_device
network_get_device outbound_device "$outbound_interface"
if [ -n "$outbound_device" ]; then
outbound_device="$outbound_device" yq -M -i '.interface-name = env(outbound_device)' "$RUN_PROFILE_PATH"
fi
fi
# test profile
if [ "$test_profile" == 1 ]; then
log "Profile testing..."
if ($PROG -d "$RUN_DIR" -t >> "$RUN_CORE_LOG_PATH" 2>&1); then
log "Profile test passed!"
else
log "Profile test failed!"
log "Exiting..."
return
fi
fi
# start core
log "Start Core"
procd_open_instance mihomo
procd_set_param command /bin/sh -c "$PROG -d $RUN_DIR >> $RUN_CORE_LOG_PATH 2>&1"
procd_set_param file "$RUN_PROFILE_PATH"
if [ "$fast_reload" == 1 ]; then
procd_set_param reload_signal HUP
fi
procd_set_param respawn
procd_set_param user "$MIHOMO_USER"
procd_set_param group "$MIHOMO_GROUP"
procd_add_jail mihomo requirejail procfs
procd_add_jail_mount "$PROG" /etc/TZ /etc/localtime /etc/hosts /etc/ssl/certs
procd_add_jail_mount_rw "$RUN_DIR" /dev/net
procd_set_param capabilities /etc/capabilities/mihomo.json
procd_set_param no_new_privs 1
procd_close_instance
# transparent proxy
if [ "$transparent_proxy" == 1 ]; then
log "Transparent Proxy is enabled."
log "Transparent Proxy: Start hijack."
# prepare
if [ "$tproxy_enable" == 1 ]; then
if [ "$ipv4_proxy" == 1 ]; then
ip route add local default dev lo table "$TPROXY_ROUTE_TABLE"
fi
if [ "$ipv6_proxy" == 1 ]; then
ip -6 route add local default dev lo table "$TPROXY_ROUTE_TABLE"
fi
fi
if [ "$tun_enable" == 1 ]; then
ip tuntap add dev "$TUN_DEVICE" mode tun vnet_hdr
ip link set "$TUN_DEVICE" up
if [ "$ipv4_proxy" == 1 ]; then
ip route add unicast default dev $TUN_DEVICE table "$TUN_ROUTE_TABLE"
fi
if [ "$ipv6_proxy" == 1 ]; then
ip -6 route add unicast default dev $TUN_DEVICE table "$TUN_ROUTE_TABLE"
fi
$TUN_SH
fi
local tcp_route_table
if [ "$tcp_transparent_proxy_mode" == "tproxy" ]; then
tcp_route_table="$TPROXY_ROUTE_TABLE"
elif [ "$tcp_transparent_proxy_mode" == "tun" ]; then
tcp_route_table="$TUN_ROUTE_TABLE"
fi
if [ -n "$tcp_route_table" ]; then
if [ "$ipv4_proxy" == 1 ]; then
ip rule add pref "$TCP_RULE_PREF" fwmark "$FW_MARK/$FW_MARK_MASK" ipproto tcp table "$tcp_route_table"
fi
if [ "$ipv6_proxy" == 1 ]; then
ip -6 rule add pref "$TCP_RULE_PREF" fwmark "$FW_MARK/$FW_MARK_MASK" ipproto tcp table "$tcp_route_table"
fi
fi
local udp_route_table
if [ "$udp_transparent_proxy_mode" == "tproxy" ]; then
udp_route_table="$TPROXY_ROUTE_TABLE"
elif [ "$udp_transparent_proxy_mode" == "tun" ]; then
udp_route_table="$TUN_ROUTE_TABLE"
fi
if [ -n "$udp_route_table" ]; then
if [ "$ipv4_proxy" == 1 ]; then
ip rule add pref "$UDP_RULE_PREF" fwmark "$FW_MARK/$FW_MARK_MASK" ipproto udp table "$udp_route_table"
fi
if [ "$ipv6_proxy" == 1 ]; then
ip -6 rule add pref "$UDP_RULE_PREF" fwmark "$FW_MARK/$FW_MARK_MASK" ipproto udp table "$udp_route_table"
fi
fi
nft -f "$HIJACK_NFT" -D FW_MARK="$FW_MARK" -D FW_MARK_MASK="$FW_MARK_MASK" -D MIHOMO_USER="$MIHOMO_USER" -D TUN_DEVICE="$TUN_DEVICE" -D DNS_PORT="$dns_port" -D REDIR_PORT="$redir_port" -D TPROXY_PORT="$tproxy_port"
nft -f "$RESERVED_IP_NFT"
nft -f "$RESERVED_IP6_NFT"
nft add element inet "$FW_TABLE" fake_ip \{ "$fake_ip_range" \}
# dns hijack
if [ "$ipv4_dns_hijack" == 1 ]; then
log "Transparent Proxy: IPv4 DNS Hijack is enabled, IPv4 dns request will redirect to the core."
nft add element inet "$FW_TABLE" dns_hijack_nfproto \{ ipv4 \}
fi
if [ "$ipv6_dns_hijack" == 1 ]; then
log "Transparent Proxy: IPv6 DNS Hijack is enabled, IPv6 dns request will redirect to the core."
nft add element inet "$FW_TABLE" dns_hijack_nfproto \{ ipv6 \}
fi
# proxy
if [ "$ipv4_proxy" == 1 ]; then
log "Transparent Proxy: IPv4 Proxy is enabled, set proxy for IPv4 traffic."
nft add element inet "$FW_TABLE" proxy_nfproto \{ ipv4 \}
fi
if [ "$ipv6_proxy" == 1 ]; then
log "Transparent Proxy: IPv6 Proxy is enabled, set proxy for IPv6 traffic."
nft add element inet "$FW_TABLE" proxy_nfproto \{ ipv6 \}
fi
# bypass china mainland ip
if [ "$bypass_china_mainland_ip" == 1 ]; then
log "Transparent Proxy: Bypass china mainland ip is enabled."
if [ "$ipv4_proxy" == 1 ]; then
nft -f "$GEOIP_CN_NFT"
fi
if [ "$ipv6_proxy" == 1 ]; then
nft -f "$GEOIP6_CN_NFT"
fi
fi
# destination port to proxy
log "Transparent Proxy: Destination TCP Port to Proxy: $acl_tcp_dport."
log "Transparent Proxy: Destination UDP Port to Proxy: $acl_udp_dport."
local acl_dport
for acl_dport in $acl_tcp_dport; do
nft add element inet "$FW_TABLE" acl_dport \{ "tcp" . "$acl_dport" \}
done
for acl_dport in $acl_udp_dport; do
nft add element inet "$FW_TABLE" acl_dport \{ "udp" . "$acl_dport" \}
done
# router proxy
if [ "$router_proxy" == 1 ]; then
log "Transparent Proxy: Router Proxy is enabled, set proxy for router."
nft insert rule inet "$FW_TABLE" nat_output jump router_dns_hijack
if [ "$tcp_transparent_proxy_mode" == "redirect" ]; then
nft add rule inet "$FW_TABLE" nat_output meta l4proto tcp jump router_redirect
else
nft add rule inet "$FW_TABLE" mangle_output meta l4proto tcp jump router_reroute
fi
nft add rule inet "$FW_TABLE" mangle_output meta l4proto udp jump router_reroute
fi
# lan proxy
if [ "$lan_proxy" == 1 ]; then
log "Transparent Proxy: Lan Proxy is enabled, set proxy for lan."
# access control
if [ "$access_control_mode" == "all" ]; then
log "Transparent Proxy: Access Control is using all mode, set proxy for all client."
elif [ "$access_control_mode" == "allow" ]; then
log "Transparent Proxy: Access Control is using allow mode, set proxy for client which is in acl."
elif [ "$access_control_mode" == "block" ]; then
log "Transparent Proxy: Access Control is using block mode, set proxy for client which is not in acl."
fi
config_list_foreach "proxy" "acl_ip" add_acl_ip
config_list_foreach "proxy" "acl_ip6" add_acl_ip6
config_list_foreach "proxy" "acl_mac" add_acl_mac
nft insert rule inet "$FW_TABLE" dstnat jump "${access_control_mode}_dns_hijack"
if [ "$tcp_transparent_proxy_mode" == "redirect" ]; then
nft add rule inet "$FW_TABLE" dstnat meta l4proto tcp jump "${access_control_mode}_redirect"
else
nft add rule inet "$FW_TABLE" mangle_prerouting meta l4proto tcp jump "${access_control_mode}_${tcp_transparent_proxy_mode}"
fi
nft add rule inet "$FW_TABLE" mangle_prerouting meta l4proto udp jump "${access_control_mode}_${udp_transparent_proxy_mode}"
fi
fi
# cron
if [[ "$scheduled_restart" == 1 && -n "$cron_expression" ]]; then
log "Add crontab for scheduled restart."
echo "$cron_expression /etc/init.d/mihomo restart #mihomo" >> "/etc/crontabs/root"
/etc/init.d/cron restart
fi
log "Start Successful!"
}
service_stopped() {
cleanup
}
reload_service() {
cleanup
start
}
service_triggers() {
procd_add_reload_trigger "mihomo"
}
cleanup() {
# delete routing policy
ip rule del ipproto tcp table "$TPROXY_ROUTE_TABLE" > /dev/null 2>&1
ip rule del ipproto udp table "$TPROXY_ROUTE_TABLE" > /dev/null 2>&1
ip rule del ipproto tcp table "$TUN_ROUTE_TABLE" > /dev/null 2>&1
ip rule del ipproto udp table "$TUN_ROUTE_TABLE" > /dev/null 2>&1
ip -6 rule del ipproto tcp table "$TPROXY_ROUTE_TABLE" > /dev/null 2>&1
ip -6 rule del ipproto udp table "$TPROXY_ROUTE_TABLE" > /dev/null 2>&1
ip -6 rule del ipproto tcp table "$TUN_ROUTE_TABLE" > /dev/null 2>&1
ip -6 rule del ipproto udp table "$TUN_ROUTE_TABLE" > /dev/null 2>&1
# delete routing table
ip route flush table "$TPROXY_ROUTE_TABLE" > /dev/null 2>&1
ip route flush table "$TUN_ROUTE_TABLE" > /dev/null 2>&1
ip -6 route flush table "$TPROXY_ROUTE_TABLE" > /dev/null 2>&1
ip -6 route flush table "$TUN_ROUTE_TABLE" > /dev/null 2>&1
# delete tun
ip link set "$TUN_DEVICE" down > /dev/null 2>&1
ip tuntap del dev "$TUN_DEVICE" mode tun > /dev/null 2>&1
# delete hijack
nft delete table inet "$FW_TABLE" > /dev/null 2>&1
local handles handle
handles=$(nft --json list table inet fw4 | yq '.nftables[] | select(has("rule")) | .rule | select(.family == "inet" and .table == "fw4" and .chain == "input" and .expr[0].match.right == "tun") | .handle')
for handle in $handles; do
nft delete rule inet fw4 input handle "$handle"
done
handles=$(nft --json list table inet fw4 | yq '.nftables[] | select(has("rule")) | .rule | select(.family == "inet" and .table == "fw4" and .chain == "forward" and .expr[0].match.right == "tun") | .handle')
for handle in $handles; do
nft delete rule inet fw4 forward handle "$handle"
done
# delete cron
sed -i '/#mihomo/d' "/etc/crontabs/root" > /dev/null 2>&1
/etc/init.d/cron restart
}
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$RUN_APP_LOG_PATH"
}
clear_all_log() {
echo -n > "$RUN_APP_LOG_PATH"
echo -n > "$RUN_CORE_LOG_PATH"
}
mixin_authentications() {
local section="$1"
local enabled username password
config_get_bool enabled "$section" "enabled" 0
config_get username "$section" "username"
config_get password "$section" "password"
if [ "$enabled" == 0 ]; then
return
fi
authentication="$username:$password" yq -M -i '.authentication += [env(authentication)]' "$RUN_PROFILE_PATH"
}
mixin_fake_ip_filters() {
domain_name="$1" yq -M -i '.dns.fake-ip-filter += [env(domain_name)]' "$RUN_PROFILE_PATH"
}
mixin_hosts() {
local section="$1"
local enabled domain_name
config_get_bool enabled "$section" "enabled" 0
config_get domain_name "$section" "domain_name"
if [ "$enabled" == 0 ]; then
return
fi
config_list_foreach "$section" "ip" mixin_host "$domain_name"
}
mixin_host() {
ip="$1" domain_name="$2" yq -M -i '.hosts.[env(domain_name)] += [env(ip)]' "$RUN_PROFILE_PATH"
}
mixin_nameservers() {
local section="$1"
local enabled type
config_get_bool enabled "$section" "enabled" 0
config_get type "$section" "type"
if [ "$enabled" == 0 ]; then
return
fi
config_list_foreach "$section" "nameserver" mixin_nameserver "$type"
}
mixin_nameserver() {
nameserver="$1" type="$2" yq -M -i '.dns.[env(type)] += [env(nameserver)]' "$RUN_PROFILE_PATH"
}
mixin_nameserver_policies() {
local section="$1"
local enabled matcher
config_get_bool enabled "$section" "enabled" 0
config_get matcher "$section" "matcher"
if [ "$enabled" == 0 ]; then
return
fi
config_list_foreach "$section" "nameserver" mixin_nameserver_policy "$matcher"
}
mixin_nameserver_policy() {
nameserver="$1" matcher="$2" yq -M -i '.dns.nameserver-policy.[env(matcher)] += [env(nameserver)]' "$RUN_PROFILE_PATH"
}
add_acl_ip() {
nft add element inet "$FW_TABLE" acl_ip \{ "$1" \}
}
add_acl_ip6() {
nft add element inet "$FW_TABLE" acl_ip6 \{ "$1" \}
}
add_acl_mac() {
nft add element inet "$FW_TABLE" acl_mac \{ "$1" \}
}

View File

@ -0,0 +1 @@
/etc/mihomo

28
mihomo/files/mixin.yaml Normal file
View File

@ -0,0 +1,28 @@
# Mixin File
# You can set any mihomo profile's config at here, it will mixin to the profile.
#
# For example:
#
# global-client-fingerprint: chrome # set fingerprint for TLS transport
# experimental: # experimental config
# quic-go-disable-gso: false # disable quic-go GSO support
# quic-go-disable-ecn: false # disable quic-go ECN support
# dialer-ip4p-convert: false # IP4P support
# proxies: # overwrite proxies
# - name: "PROXY"
# type: ss
# server: proxy.example.com
# port: 443
# cipher: chacha20-ietf-poly1305
# password: "password"
# rules: # overwrite rules
# - DOMAIN,google.com,PROXY
# - DOMAIN-SUFFIX,google.com,PROXY
# - DOMAIN-KEYWORD,google,PROXY
# - DOMAIN-REGEX,^google.*com,PROXY
# - GEOSITE,google,PROXY
# - GEOSITE,cn,DIRECT
# - IP-CIDR,8.8.8.8/32,DIRECT,no-resolve
# - GEOIP,telegram,DIRECT
# - GEOIP,cn,DIRECT
# - Match,PROXY

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,198 @@
#!/usr/sbin/nft -f
table inet mihomo {
set dns_hijack_nfproto {
type nf_proto
flags interval
}
set proxy_nfproto {
type nf_proto
flags interval
}
set china_ip {
type ipv4_addr
flags interval
}
set china_ip6 {
type ipv6_addr
flags interval
}
set reserved_ip {
type ipv4_addr
flags interval
auto-merge
}
set reserved_ip6 {
type ipv6_addr
flags interval
auto-merge
}
set fake_ip {
type ipv4_addr
flags interval
}
set acl_dport {
type inet_proto . inet_service
flags interval
auto-merge
}
set acl_ip {
type ipv4_addr
flags interval
auto-merge
}
set acl_ip6 {
type ipv6_addr
flags interval
auto-merge
}
set acl_mac {
type ether_addr
flags interval
auto-merge
}
chain router_dns_hijack {
meta nfproto @dns_hijack_nfproto meta l4proto { tcp, udp } th dport 53 oifname lo meta skuid != $MIHOMO_USER counter redirect to :$DNS_PORT
}
chain all_dns_hijack {
meta nfproto @dns_hijack_nfproto meta l4proto { tcp, udp } th dport 53 counter redirect to :$DNS_PORT
}
chain allow_dns_hijack {
meta nfproto @dns_hijack_nfproto meta l4proto { tcp, udp } th dport 53 ip saddr @acl_ip counter redirect to :$DNS_PORT
meta nfproto @dns_hijack_nfproto meta l4proto { tcp, udp } th dport 53 ip6 saddr @acl_ip6 counter redirect to :$DNS_PORT
meta nfproto @dns_hijack_nfproto meta l4proto { tcp, udp } th dport 53 ether saddr @acl_mac counter redirect to :$DNS_PORT
}
chain block_dns_hijack {
meta nfproto @dns_hijack_nfproto meta l4proto { tcp, udp } th dport 53 ip saddr @acl_ip counter return
meta nfproto @dns_hijack_nfproto meta l4proto { tcp, udp } th dport 53 ip6 saddr @acl_ip6 counter return
meta nfproto @dns_hijack_nfproto meta l4proto { tcp, udp } th dport 53 ether saddr @acl_mac counter return
meta nfproto @dns_hijack_nfproto meta l4proto { tcp, udp } th dport 53 counter redirect to :$DNS_PORT
}
chain all_redirect {
meta nfproto @proxy_nfproto meta l4proto { tcp, udp } counter redirect to :$REDIR_PORT
}
chain allow_redirect {
meta nfproto @proxy_nfproto meta l4proto { tcp, udp } ip saddr @acl_ip counter redirect to :$REDIR_PORT
meta nfproto @proxy_nfproto meta l4proto { tcp, udp } ip6 saddr @acl_ip6 counter redirect to :$REDIR_PORT
meta nfproto @proxy_nfproto meta l4proto { tcp, udp } ether saddr @acl_mac counter redirect to :$REDIR_PORT
}
chain block_redirect {
meta nfproto @proxy_nfproto meta l4proto { tcp, udp } ip saddr @acl_ip counter return
meta nfproto @proxy_nfproto meta l4proto { tcp, udp } ip6 saddr @acl_ip6 counter return
meta nfproto @proxy_nfproto meta l4proto { tcp, udp } ether saddr @acl_mac counter return
meta nfproto @proxy_nfproto meta l4proto { tcp, udp } counter redirect to :$REDIR_PORT
}
chain all_tproxy {
meta nfproto @proxy_nfproto meta l4proto { tcp, udp } meta mark set mark ^ $FW_MARK tproxy to :$TPROXY_PORT counter accept
}
chain allow_tproxy {
meta nfproto @proxy_nfproto meta l4proto { tcp, udp } ip saddr @acl_ip meta mark set mark ^ $FW_MARK tproxy ip to :$TPROXY_PORT counter accept
meta nfproto @proxy_nfproto meta l4proto { tcp, udp } ip6 saddr @acl_ip6 meta mark set mark ^ $FW_MARK tproxy ip6 to :$TPROXY_PORT counter accept
meta nfproto @proxy_nfproto meta l4proto { tcp, udp } ether saddr @acl_mac meta mark set mark ^ $FW_MARK tproxy to :$TPROXY_PORT counter accept
}
chain block_tproxy {
meta nfproto @proxy_nfproto meta l4proto { tcp, udp } ip saddr @acl_ip counter return
meta nfproto @proxy_nfproto meta l4proto { tcp, udp } ip6 saddr @acl_ip6 counter return
meta nfproto @proxy_nfproto meta l4proto { tcp, udp } ether saddr @acl_mac counter return
meta nfproto @proxy_nfproto meta l4proto { tcp, udp } meta mark set mark ^ $FW_MARK tproxy to :$TPROXY_PORT counter accept
}
chain all_tun {
meta nfproto @proxy_nfproto meta l4proto { tcp, udp } meta mark set mark ^ $FW_MARK counter
}
chain allow_tun {
meta nfproto @proxy_nfproto meta l4proto { tcp, udp } ip saddr @acl_ip meta mark set mark ^ $FW_MARK counter
meta nfproto @proxy_nfproto meta l4proto { tcp, udp } ip6 saddr @acl_ip6 meta mark set mark ^ $FW_MARK counter
meta nfproto @proxy_nfproto meta l4proto { tcp, udp } ether saddr @acl_mac meta mark set mark ^ $FW_MARK counter
}
chain block_tun {
meta nfproto @proxy_nfproto meta l4proto { tcp, udp } ip saddr @acl_ip counter return
meta nfproto @proxy_nfproto meta l4proto { tcp, udp } ip6 saddr @acl_ip6 counter return
meta nfproto @proxy_nfproto meta l4proto { tcp, udp } ether saddr @acl_mac counter return
meta nfproto @proxy_nfproto meta l4proto { tcp, udp } meta mark set mark ^ $FW_MARK counter
}
chain router_redirect {
meta nfproto @proxy_nfproto meta l4proto { tcp, udp } counter redirect to :$REDIR_PORT
}
chain router_reroute {
meta nfproto @proxy_nfproto meta l4proto { tcp, udp } meta mark set mark ^ $FW_MARK counter accept
}
chain dstnat {
type nat hook prerouting priority dstnat + 1; policy accept;
fib daddr type local counter return
ct direction reply counter return
ip daddr @reserved_ip counter return
ip6 daddr @reserved_ip6 counter return
ip daddr @china_ip counter return
ip6 daddr @china_ip6 counter return
meta l4proto . th dport != @acl_dport ip daddr != @fake_ip counter return
meta nfproto ipv6 meta l4proto . th dport != @acl_dport counter return
}
chain nat_output {
type nat hook output priority filter; policy accept;
meta skuid $MIHOMO_USER counter return
fib daddr type local counter return
ct direction reply counter return
ip daddr @reserved_ip counter return
ip6 daddr @reserved_ip6 counter return
ip daddr @china_ip counter return
ip6 daddr @china_ip6 counter return
meta l4proto . th dport != @acl_dport ip daddr != @fake_ip counter return
meta nfproto ipv6 meta l4proto . th dport != @acl_dport counter return
}
chain mangle_prerouting {
type filter hook prerouting priority mangle; policy accept;
meta l4proto { tcp, udp } iifname lo meta mark & $FW_MARK_MASK == $FW_MARK tproxy to :$TPROXY_PORT counter accept
meta l4proto { tcp, udp } iifname $TUN_DEVICE counter return
fib daddr type local counter return
ct direction reply counter return
ip daddr @reserved_ip counter return
ip6 daddr @reserved_ip6 counter return
ip daddr @china_ip counter return
ip6 daddr @china_ip6 counter return
meta l4proto . th dport != @acl_dport ip daddr != @fake_ip counter return
meta nfproto ipv6 meta l4proto . th dport != @acl_dport counter return
meta l4proto { tcp, udp } th dport 53 counter return
}
chain mangle_output {
type route hook output priority mangle; policy accept;
meta skuid $MIHOMO_USER counter return
fib daddr type local counter return
ct direction reply counter return
ip daddr @reserved_ip counter return
ip6 daddr @reserved_ip6 counter return
ip daddr @china_ip counter return
ip6 daddr @china_ip6 counter return
meta l4proto . th dport != @acl_dport ip daddr != @fake_ip counter return
meta nfproto ipv6 meta l4proto . th dport != @acl_dport counter return
meta l4proto { tcp, udp } th dport 53 counter return
}
}

View File

@ -0,0 +1,19 @@
#!/usr/sbin/nft -f
table inet mihomo {
set reserved_ip {
type ipv4_addr
flags interval
elements = {
0.0.0.0/8,
10.0.0.0/8,
127.0.0.0/8,
100.64.0.0/10,
169.254.0.0/16,
172.16.0.0/12,
192.168.0.0/16,
224.0.0.0/4,
240.0.0.0/4
}
}
}

View File

@ -0,0 +1,23 @@
#!/usr/sbin/nft -f
table inet mihomo {
set reserved_ip6 {
type ipv6_addr
flags interval
elements = {
::/128,
::1/128,
::ffff:0:0/96,
100::/64,
64:ff9b::/96,
2001::/32,
2001:10::/28,
2001:20::/28,
2001:db8::/32,
2002::/16,
fc00::/7,
fe80::/10,
ff00::/8
}
}
}

View File

@ -0,0 +1,38 @@
#!/bin/sh
# permission
MIHOMO_USER="mihomo"
MIHOMO_GROUP="mihomo"
# routing
FW_TABLE="mihomo"
FW_MARK="0x80"
FW_MARK_MASK="0xFF"
TCP_RULE_PREF="1024"
UDP_RULE_PREF="1025"
TPROXY_ROUTE_TABLE="80"
TUN_ROUTE_TABLE="81"
TUN_DEVICE="tun"
# paths
PROG="/usr/bin/mihomo"
HOME_DIR="/etc/mihomo"
PROFILES_DIR="$HOME_DIR/profiles"
MIXIN_FILE_PATH="$HOME_DIR/mixin.yaml"
RUN_DIR="$HOME_DIR/run"
RUN_APP_LOG_PATH="$RUN_DIR/app.log"
RUN_CORE_LOG_PATH="$RUN_DIR/core.log"
RUN_PROFILE_PATH="$RUN_DIR/config.yaml"
RUN_UI_DIR="$RUN_DIR/ui"
# scripts
SH_DIR="$HOME_DIR/scripts"
TUN_SH="$SH_DIR/tun.sh"
# nftables
NFT_DIR="$HOME_DIR/nftables"
HIJACK_NFT="$NFT_DIR/hijack.nft"
RESERVED_IP_NFT="$NFT_DIR/reserved_ip.nft"
RESERVED_IP6_NFT="$NFT_DIR/reserved_ip6.nft"
GEOIP_CN_NFT="$NFT_DIR/geoip_cn.nft"
GEOIP6_CN_NFT="$NFT_DIR/geoip6_cn.nft"

View File

@ -0,0 +1,17 @@
#!/bin/sh
. "$IPKG_INSTROOT/lib/functions.sh"
. "$IPKG_INSTROOT/etc/mihomo/scripts/constants.sh"
config_load mihomo
config_get enabled "config" "enabled" 0
config_get tcp_transparent_proxy_mode "proxy" "tcp_transparent_proxy_mode"
config_get udp_transparent_proxy_mode "proxy" "udp_transparent_proxy_mode"
if [ "$enabled" == 1 ] && [[ "$tcp_transparent_proxy_mode" == "tun" || "$udp_transparent_proxy_mode" == "tun" ]]; then
nft insert rule inet fw4 input iifname "$TUN_DEVICE" counter accept
nft insert rule inet fw4 forward oifname "$TUN_DEVICE" counter accept
nft insert rule inet fw4 forward iifname "$TUN_DEVICE" counter accept
fi
exit 0

View File

@ -0,0 +1,34 @@
#!/bin/sh
. "$IPKG_INSTROOT/etc/mihomo/scripts/constants.sh"
# add firewall include for tun
uci -q batch <<-EOF > /dev/null
delete firewall.mihomo
set firewall.mihomo=include
set firewall.mihomo.type=script
set firewall.mihomo.path=$TUN_SH
set firewall.mihomo.fw4_compatible=1
commit firewall
EOF
# check mihomo.config.init
init=$(uci -q get mihomo.config.init); [ -z "$init" ] && return
# generate random string for api secret and authentication password
random=$(awk 'BEGIN{srand(); print int(rand() * 1000000)}')
# set mihomo.mixin.api_secret
uci set mihomo.mixin.api_secret="$random"
# set mihomo.@authentication[0].password
uci set mihomo.@authentication[0].password="$random"
# remove mihomo.config.init
uci del mihomo.config.init
# commit
uci commit mihomo
# exit with 0
exit 0

View File

@ -0,0 +1,9 @@
#!/bin/sh
. "$IPKG_INSTROOT/etc/mihomo/scripts/constants.sh"
# commit
uci commit mihomo
# exit with 0
exit 0