👉 Please read the Code of Conduct before participating in the project.
mihomo-proxy-ros is a multi-architecture Docker container based on Mihomo, byedpi, zapret(nfqws; only amd64 and arm64) and zapret2(nfqws2; only amd64 and arm64)
supporting platforms ARM, ARM64, AMD64v1, AMD64v2, and AMD64v3.
The latest tag includes ARM, ARM64, and AMD64v3.
If you have AMD64v1 or AMD64v2, you need to pull the corresponding tag.
If you find this project useful, you can support it via donation:
USDT(TRC20): TWDDYD1nk5JnG6FxvEu2fyFqMCY9PcdEsJ
https://boosty.to/petersolomon/donate
The repository contains an interactive automated installation script for RouterOS MikroTik,
which also If set installs and runs standalone dnsproxy from AdGuardHome dnsproxy from AdGuardHome.
- 🌍 Multi-architecture: ARM, ARM64, AMD64v1-v3
- ⚙️ Automated installation via MikroTik terminal using the script at the end of this description
- 🔐 DPI bypass via ByeDPI (You can change the strategy in the container’s ENVs. For selecting strategies, there is an option called byedpi-orchestrator.)
- 🔐 DPI bypass using Zapret (nfqws) (amd64 and arm64 only) — strategies must be selected separately from the container according to the instructions from the author of zapret
- 🔐 DPI bypass using Zapret2 (nfqws2) (amd64 and arm64 only) — strategies must be selected separately from the container according to the instructions from the author of zapret2
- 🌐 DNSProxy: multi-resolve from multiple DNS servers, supports all DNS protocols (Optional)
- 🧩 Flexible routing and management of domain, IP, and AS pools via ENVs
- 🛡️ Ability to add multiple proxy links and subscriptions (including RemnaWave subscriptions with HWID) via ENVs
- 🚀 Integration of multiple WG, AWG VPNs by copying config files into the mount folder
During execution, the user is prompted to:
- Enter a single proxy link:
vless://,vmess://,ss://,trojan:// - If available — a subscription link:
Enter sublink http(s)://... URL
The script automatically performs:
- Router configuration
- Mangle and routing setup
- Container installation
- Domain pool formation for resources routed through proxies
This makes the project significantly simplify the setup process,
making it convenient even for inexperienced users,
and provides a flexible, ready-to-use proxy solution.
After installation, you can flexibly configure resource routing on the router itself by modifying the resources in the existing script or creating new ones (DNS_FWD, IPList),
as well as adding new links and other parameters via environment variables (ENV) for flexible routing and container logic configuration of mihomo-proxy-ros.
| ENVs | Default | Description |
|---|---|---|
TPROXY |
true |
In RoS>=7.21 on arm64 and adm64 architectures, NFTables is used by default in the container. If the TPROXY ENV is set to true, inbound TProxy (tcp, udp) will be used; if set to false, inbound Redirect (tcp) + TUN (udp) will be used |
DNS_MODE |
fake-ip |
DNS server operation mode DOCs |
NAMESERVER_POLICY |
— | Specifies which domains should be resolved by which DNS servers DOCs. ENV example: domain1#dns1,domain2#dns2 |
SNIFFER |
true |
Domain sniffer. Applied when routing by domains, when the domain is resolved not by mihomo |
FAKE_IP_RANGE |
198.18.0.0/15 |
Fake-IP pool range DOCs |
FAKE_IP_TTL |
1 |
Lifetime of FakeIP record in DNS cache in seconds DOCs |
FAKE_IP_FILTERXXX |
— | List of rules for DNS server operation in rule mode. |
EXTERNAL_UI_URL |
link | Web interface link (zip archive) DOCs |
LOG_LEVEL |
error |
mihomo log level (silent, error, warning, info, debug) DOCs |
HEALTHCHECK_URL |
https://www.gstatic.com/generate_204 |
Health-check URL |
HEALTHCHECK_URL_STATUS |
204 |
Expected health-checked status DOCs |
HEALTHCHECK_INTERVAL |
120 |
Health-check interval in seconds DOCs |
HEALTHCHECK_URL_BYEDPI |
https://www.facebook.com |
Health-check URL for BYEDPI proxy provider |
HEALTHCHECK_URL_STATUS_BYEDPI |
200 |
Expected health-check status DOCs for BYEDPI proxy provider |
HEALTHCHECK_URL_ZAPRET |
https://www.facebook.com |
URL health-check for all proxy providers ZAPRET and ZAPRET2 |
HEALTHCHECK_URL_STATUS_ZAPRET |
200 |
Expected health-check status DOCs for all proxy providers ZAPRET and ZAPRET2 |
HEALTHCHECK_PROVIDER |
true |
If true — health checks use HEALTHCHECK_URL, HEALTHCHECK_INTERVAL, HEALTHCHECK_URL_STATUS. If false — health checks use GROUP_URL, XXX_URL, GROUP_URL_STATUS, XXX_URL_STATUS, GROUP_INTERVAL, XXX_INTERVAL |
BYEDPI_CMDxx |
— | Strategy BYEDPI if BYEDPI_CMD is set, proxy output BYEDPI appears; if BYEDPI_CMD1 is set, proxy output BYEDPI_1 appears, and so on |
ZAPRET_CMDxx |
— | Strategy [Zapret(nfqws)] (https://github.com/bol-van/zapret), if ZAPRET_CMD is set, the proxy output ZAPRET appears; if ZAPRET_CMD1 is set, the proxy output ZAPRET_1 appears, and so on. The container contains bin files for fakes from the repository [zapret-discord-youtube] (https://github.com/Flowseal/zapret-discord-youtube), paths for their use /zapret-fakebin/quic_initial_www_google_com.bin, /zapret-fakebin/tls_clienthello_4pda_to.bin, /zapret-fakebin/tls_clienthello_max_ru.bin, /zapret-fakebin/tls_clienthello_www_google_com.bin, as well as txt list files /zapret-lists/ipset-all.txt, /zapret-lists/ipset-exclude.txt, /zapret-lists/list-exclude.txt, /zapret-lists/list-general.txt, /zapret-lists/list-google.txt |
ZAPRET2_CMDxx |
— | Strategy Zapret2(nfqws2), if ZAPRET2_CMD is set, proxy output ZAPRET2 appears, if ZAPRET2_CMD1 is set, proxy output ZAPRET2_1 appears, and so on |
ZAPRET_PACKETSxx |
12 |
Number of first packets that will pass through the ban queue. ZAPRET_PACKETS value for all nfqws by default. ZAPRET_PACKETSxx value for a specific proxy provider. Values other than natural numbers are treated as 0, and packets will always pass through the queue. |
ZAPRET2_PACKETSxx |
12 |
Number of first packets that will pass through the ban queue2. ZAPRET2_PACKETS is the default value for all nfqws2. ZAPRET2_PACKETSxx value for a specific proxy provider. Values other than natural numbers are treated as 0, and packets will always go through the queue. |
LINK0, LINK1... |
— | Proxy links vless://, vmess://, ss://, trojan://... For each proxy link, a separate proxy provider is created |
SUB_LINK0, SUB_LINK1... |
— | Subscriptions of type http(s)://... For each subscription, a separate proxy provider is created. Supports setting HWID individually for each subscription |
SUB_LINKxx_PROXY |
DIRECT |
Specifies through which proxy the subscription should be fetched. Example: SUB_LINK1_PROXY with value proxies1 → the subscription will be downloaded via the proxy proxies1 |
SUB_LINKxx_HEADERS |
— | Specification of headers for the subscription request with special headers. Example format: header1=value1#header2=value2. Example with x-hwid: x-hwid=xxx#x-device-os=xxx#x-ver-os=xxx#x-device-model=xxx#user-agent=xxx |
SUB_LINKxx_INTERVAL |
3600 |
Specifies the subscription update interval in seconds. ENV SUB_LINK_INTERVAL sets the default value for all. SUB_LINKxx_INTERVAL reassigns the interval for a specific subscription. |
SOCKS0, SOCKS1... |
— | SOCKS5 proxies . Each defined SOCKS5 proxy gets its own separate proxy-provider. ENV examples: server=192.168.88.3#port=1080#username=admin#password=admin#tls=true#fingerprint=chrome#skip-cert-verify=false#udp=false#ip-version=ipv4 or shorter server=192.168.88.3#port=1080#username=admin#password=admin All SOCKS5 config parameters are separated by # instead of the usual YAML/JSON syntax. |
XXX_DIALER_PROXY |
— | proxy provider parameter, see override dialer-proxy. Allows you to specify which proxy group to use for the connection. For example, you can specify that LINK1 should connect through the YouTube group - LINK1_DIALER_PROXY with the value YouTube |
GROUP |
— | A comma-separated list of proxy groups, for example telegram,youtube,google,ai,geoblock will create proxy groups TELEGRAM,YOUTUBE,GOOGLE,AI,GEOBLOCK. A proxy group is created only if it has at least one of the resources XXX_ or XXX_USE |
XXX_TYPE |
select |
Proxy group type . XXX is the proxy group name set in the GROUP ENV. For example, for GROUP ...,youtube,... → YOUTUBE_TYPE |
GROUP_URL |
https://www.gstatic.com/generate_204 |
Proxy health check URL used when HEALTHCHECK_PROVIDER=false and XXX_TYPE is url-test, fallback, or load-balance |
XXX_URL |
ENV GROUP_URL |
Sets the proxy health check URL for a specific proxy group when HEALTHCHECK_PROVIDER=false |
GROUP_URL_STATUS |
204 |
Expected status code for proxy health check used when HEALTHCHECK_PROVIDER=false and XXX_TYPE is url-test, fallback, or load-balance |
XXX_URL_STATUS |
ENV GROUP_URL_STATUS |
Sets the expected status code for proxy health check for a specific proxy group when HEALTHCHECK_PROVIDER=false |
GROUP_INTERVAL |
60 |
Proxy health check interval in seconds, used when HEALTHCHECK_PROVIDER=false and XXX_TYPE is url-test, fallback, or load-balance |
XXX_INTERVAL |
ENV GROUP_INTERVAL |
Sets the proxy health check interval for a specific proxy group when HEALTHCHECK_PROVIDER=false |
GROUP_TOLERANCE |
20 |
Difference for selecting the best proxy in ms, used for XXX_TYPE url-test |
XXX_TOLERANCE |
ENV GROUP_TOLERANCE |
Setting difference for selecting the best proxy for the proxy group |
GROUP_STRATEGY |
consistent-hashing |
Load balancing strategy, used for XXX_TYPE load-balance |
XXX_STRATEGY |
ENV GROUP_STRATEGY |
Setting load balancing strategy for the proxy group |
XXX_USE |
(all providers) in order LINKs, SUB_LINKs, WG,AWG, BYEDPI, DIRECT |
Comma-separated list of proxy providers to be used in the specified order for the proxy group, where XXX is the proxy group name set in the GROUP ENV. For example, for GROUP ...,youtube,... → YOUTUBE_USE with value BYEDPI,LINK1 will leave two proxy providers for the YOUTUBE group, with BYEDPI first and LINK1 second |
XXX_FILTER |
— | Proxy group filter, where XXX is the proxy group name set in the GROUP ENV. For example, for GROUP ...,youtube,... → YOUTUBE_FILTER with value RU|BYEDPI will leave proxies with the RF flag emoji and name BYEDPI for the YOUTUBE group |
XXX_EXCLUDE |
— | Proxy group exclude filter, where XXX is the proxy group name set in the GROUP ENV. For example, for GROUP ...,youtube,... → YOUTUBE_EXCLUDE with value RU|BYEDPI will exclude proxies with the RF flag emoji and name BYEDPI from the YOUTUBE group |
XXX_EXCLUDE_TYPE |
— | Proxy group filter by type, where XXX is the proxy group name set in the GROUP ENV. For example, for GROUP ...,youtube,... → YOUTUBE_EXCLUDE_TYPE with value vmess|direct will exclude vmess and direct type proxies from the YOUTUBE group |
XXX_DNS |
— | Ability to specify which DNS to use to resolve domains in proxy group XXX. Example value: https://dns.google/dns-query#disable-qtype-65=true&disable-ipv6=true Docs. This may be relevant, for example, for those who resolve AI through comss or other similar proxy DNS, i.e., set the required DNS for the AI group and select MihomoProxyRoS in the group. |
XXX_GEOSITE |
— | Comma-separated list of geosite for proxy group XXX. Actually creates a rule-set in rms format and corresponding routing rules to the proxy group, where XXX is the proxy group name set in the GROUP ENV. For example, for GROUP ...,geoblock,... → GEOBLOCK_GEOSITE with value intel,openai,xai will load domain lists for intel,openai,xai resources and route them to the GEOBLOCK proxy-group |
XXX_GEOIP |
— | Comma-separated list of geoip for proxy group XXX. Actually creates a rule-set in rms format and corresponding routing rules to the proxy group, where XXX is the proxy group name set in the GROUP ENV. For example, for GROUP ...,geoblock,... → GEOBLOCK_GEOIP with value netflix will load IP pools for netflix and route them to the GEOBLOCK proxy-group |
XXX_AS |
— | Comma-separated list of AS for proxy group XXX. Actually creates a rule-set in rms format and corresponding routing rules to the proxy group, where XXX is the proxy group name set in the GROUP ENV. For example, for GROUP ...,telegram,... → TELEGRAM_AS with value AS62041,AS59930,AS62014,AS211157,AS44907 will load IP pools for AS62041,AS59930,AS62014,AS211157,AS44907 and route them to the TELEGRAM proxy-group |
XXX_DOMAIN |
— | Comma-separated list of domains for proxy group XXX. Actually creates corresponding routing rules to the proxy group, where XXX is the proxy group name set in the GROUP ENV. For example, for GROUP ...,telegram,... → TELEGRAM_DOMAIN with value telegram.org,telegram.com will route the specified domains to the TELEGRAM proxy-group |
XXX_SUFFIX |
— | Comma-separated list of domain suffixes for proxy group XXX. Actually creates corresponding routing rules to the proxy group, where XXX is the proxy group name set in the GROUP ENV. For example, for GROUP ...,telegram,... → TELEGRAM_SUFFIX with value telegram.org,telegram.com will route the specified domains and their subdomains to the TELEGRAM proxy-group |
XXX_KEYWORD |
— | Comma-separated list of domain keywords for the proxy-group named XXX. Automatically creates corresponding rules that route matching domains to the proxy-group XXX. The group name XXX is taken from the GROUP environment variable (comma-separated list). Example: GROUP=...,telegram,... + TELEGRAM_KEYWORD=telegram,tg → all domains containing telegram or tg will be routed to the TELEGRAM proxy-group |
XXX_IPCIDR |
— | Comma-separated list of IP-CIDR for proxy group XXX. Actually creates corresponding routing rules to the proxy group, where XXX is the proxy group name set in the GROUP ENV. For example, for GROUP ...,telegram,... → TELEGRAM_IPCIDR with value 91.108.4.0/22,91.108.56.0/22 will route the specified subnets to the TELEGRAM proxy-group |
XXX_SRCIPCIDR |
— | Comma-separated list of SRC-IP-CIDR for the proxy group XXX. Actually creates corresponding routing rules that send traffic from these source IPs/subnets to the proxy group XXX. XXX is the proxy group name you specify in the ENV variable GROUP. Example: if GROUP contains ...,socks,..., then the variable SOCKS_IPCIDR with value 192.168.88.37/32,192.168.88.65/32 will route all traffic from these subnets to the proxy-group named SOCKS. |
XXX_PRIORITY |
— | Priority of proxy group XXX, in terms of the order of rules in rules. For example, YOUTUBE_PRIORITY with a value of 1 and TELEGRAM_PRIORITY with a value of 2 will create rules in rules in order, first YOUTUBE, then TELEGRAM. The default priority is 1000+. |
XXX_ICON |
— | Proxy group icon specify a link to the icon “url” |
XXX_HIDDEN |
false |
true/false, hides/shows the proxy group in the web panel. |
RULE_SETXXX_BASE64 |
— | String in the format base64#name, where base64-encoded list in the format [payload](https://wiki.metacubex.one/ru/config/rule-providers/# payload) and name is the name of the proxy group that will be created. Routing rules for this group with priority 2000+ will also be added automatically. Encoding strings such as DOMAIN-SUFFIX,ntc.party on the next line DOMAIN,abc.com will create a rule set with two rules. |
RULESXXX |
— | Routing rules of the Mihomo core, where XXX is the rule priority (order). For example, ENV RULES1 with the value AND,((NETWORK,udp),(DST-PORT,443)),REJECT will create a QUIC drop rule with priority 1, meaning it will be in the first position. These priorities are shared with the priorities of XXX_PRIORITY groups. |
WG, AWG configs need to be mounted to the container folder
/root/.config/mihomo/awg/, proxy providers will be created in the number of config files with their filenames.
Any proxy can be formatted in a
.yamlfile according to the documentation and mounted in the folder/root/.config/mihomo/proxies_mount/.
You can create a group from your list file in the payload format, the
name.txtfile, wherenameis the name of the proxy group that will be created. Routing rules for this group with a priority of 2000+ will also be added automatically. Mount it in the/root/.config/mihomo/rule_set_list/folder. Lines such asDOMAIN-SUFFIX,ntc.party, followed byDOMAIN,abc.comon the next line, will create a rule set with two rules.
Multiple VETH interfaces can be added to the container; they will appear as proxy outbounds in mihomo. You can choose which interface to send traffic through, and then, in RouterOS, use mangle to route it as desired, but traffic must be sent to the mihomo container only through the first interface in the list.
First, make sure you have the container package installed and that the necessary device-mode functions are enabled.
/system/device-mode/printEnable device-mode if necessary. Follow the instructions after executing the command below. You have 5 minutes to reboot the power supply or briefly press any button on the device (I recommend using any button).
/system/device-mode/update mode=advanced container=yes traffic-gen=yes🧩 Installation is done directly via MikroTik terminal —
just copy and paste the snippet below into the RouterOS terminal,
then the script automatically downloads from the repository and starts installation.
:global currentVersion [/system resource get version];
:global currentMinor [:pick $currentVersion ([:find $currentVersion "."] + 1) ([:find $currentVersion "."] + 3)];
:global r
:global statusPackage false
:global statusDeviceMode [/system/device-mode/get container]
:if ([:len [/system/package/find name=container available=no disabled=no]] >0) do={
:set statusPackage true
} else={
:put "Please check the installation of the container package"
}
:if ($statusDeviceMode=false) do={
:put "Please check /system/device-mode/print container enable"
}
:if ($currentMinor >= 21) do={
:put "Current version RouterOS 7.$currentMinor"
:set r [/tool fetch url=https://raw.githubusercontent.com/Medium1992/mihomo-proxy-ros/refs/heads/main/script21.rsc mode=https output=user as-value]
}
:if ($currentMinor = 20) do={
:put "Current version RouterOS 7.$currentMinor"
:set r [/tool fetch url=https://raw.githubusercontent.com/Medium1992/mihomo-proxy-ros/refs/heads/main/script.rsc mode=https output=user as-value]
}
:if ($currentMinor < 20) do={
:put "Current version RouterOS $currentVersion"
:put "Update to at least version RouterOS 7.20"
}
:if (($r->"status")="finished" and $statusPackage=true and $statusDeviceMode=true) do={
:global content ($r->"data")
:if ([:len $content] > 0) do={
:global s [:parse $content]
:log warning "script loading completed and started"
:put "script loading completed and started"
$s
/system/script/environment/remove [find where ]
}
}
If you find this project useful, you can support it via donation:
USDT(TRC20): TWDDYD1nk5JnG6FxvEu2fyFqMCY9PcdEsJ
https://boosty.to/petersolomon/donate