enfein / mieru

mieru is a socks5 / HTTP / HTTPS proxy to bypass censorship. 見える是一款 socks5 / HTTP / HTTPS 网络代理翻墙工具。
GNU General Public License v3.0
1.08k stars 137 forks source link

無法在 Asus 路由器 RT-AC86U 上執行 mita 伺服器 #11

Closed samho1234567 closed 2 years ago

samho1234567 commented 2 years ago

你好,本人打算在路由器上執行 mita 作為伺服器,於是編譯了 arm64 版本的執行檔,起初在 terminal 上成功執行 mieru helpmita help,不過,執行 mita status 時出錯。

第1個錯誤訊息:get mieru server status failed: ServerLifecycleService.GetStatus() failed: rpc error: code = Unavailable desc = connection error: desc = "transport: Error while dialing dial unix /var/run/mita.sock: connect: no such file or directory"

2022-06-02_181117


之後我在 var/run 新增了 mita.sock 文件,執行 mita status 成功,不過執行 mita appl/mnt/sda/mieru/mita apply config /mnt/sda/mieru/server_config.json 失敗

2022-06-02_180148


第2個錯誤訊息:get mieru server status failed: ServerLifecycleService.GetStatus() failed: rpc error: code = Unavailable desc = connection error: desc = "transport: Error while dialing dial unix /var/run/mita.sock: connect: connection refused"

2022-06-02_181659


可否像 hysteria 一樣推出無 tun 版本或路由器專用版本?謝謝

https://github.com/HyNetwork/hysteria/issues/105

enfein commented 2 years ago

samho1234567 你好,

你遇到和问题应该和 issue #7 是同一类情况。因为我们没有提供 arm64 的安装包,所以你只是编译了服务端的可执行文件,却没有启动服务端程序。在使用安装包的情况下,mita 会在安装后自动启动。请参照 issue #7 的讨论尝试解决。如果路由器的 Linux 版本支持 systemd,建议编写一个 systemd unit 文件,让服务端程序可以随路由器一同启动。

我们编译时使用了 CGO_ENABLED=0 环境变量,编译出来的可执行文件不依赖于外部动态链接库,不存在动态链接库版本不兼容的问题。

samho1234567 commented 2 years ago

作者你好,

因為 Asuswrt-Merlin 為精簡版 linux 版本,不支援 systemd ,所以無法執行 systemctl status mitajournalctl -xe -u mita --no-pager

我編譯了伺服器的可執行檔(即 arm64armv8),編譯時也使用了 CGO_ENABLED=0 環境變量,但由於系統不支援 systemd,啟動伺服器程式的解決方案為:按照 這篇教學文 編寫 mieru-check.sh 加入 services-start,以便隨系統一同啟動。

即使我手動加入 /var/run/mita.sock ,又遇到錯誤訊息 get mieru server status failed: ServerLifecycleService.GetStatus() failed: rpc error: code = Unavailable desc = connection error: desc = "transport: Error while dialing dial unix /var/run/mita.sock: connect: connection refused"

2022-06-03_121149

(我無聊地執行 x86_64 版本,當然執行失敗。)

samho1234567 commented 2 years ago

如果作者在下次更新能提供 arm64 版本的 mierumita,就方便大家使用 :smile:

enfein commented 2 years ago

咱们一点点来解决现在的问题。这个 /var/run/mita.sock 文件是一个 UNIX domain socket 文件,它必须是由 mita 进程创建。你自己创建一个同名文件是没有用的。为了创建这个文件,服务端程序 mita 必须处于运行状态。而让 mita 运行,又有几个前提条件:

第一,需要创建名为 mita 的用户和用户组,并把当前的用户加入 mita 用户组中。对应的指令是

sudo useradd --no-create-home --user-group mita
sudo usermod -a -G mita $USER
sudo reboot

第二,是创建 /etc/mita 目录存放服务端程序的配置文件。

sudo mkdir -p /etc/mita
sudo chmod 775 /etc/mita

做完这两步之后,使用 root 用户运行 mita

sudo ./mita run

之后 mita 就会创建那个 /var/run/mita.sock 文件,你也可以继续配置了。

上述步骤由于没有设置自启动,所以你的 SSH 退出登录之后 mita 进程也会退出。这是我之前推荐设置自启动的原因。

另外,当这个文件存在的时候,并不意味着 mita 一定正处于运行状态。查看运行状态,可以用 ps aux | grep mita 搜索是否有名叫 mita 的程序正在运行。如果没有运行,那些 mita 开头的指令都会报错的。

关于服务端程序的 arm 版本,我有一个不甚理解的地方。为了实现翻墙,服务端程序必须运行在墙外。你让 mita 运行在家庭路由器里,但是路由器应该是在墙内,结果翻不了墙。我不知道你是不是在搞套娃或者其他高级用法。如果确有比较强的 arm 版本需求,我可以考虑在新版本加入。这里的主要问题是 arm 硬件 Linux 平台比较分散,比如有些系统不支持 systemd,安装配置还是会有很多坑。

samho1234567 commented 2 years ago

謝謝你的教學

因為 Asuswrt-Merlin 為精簡版 linux 版本,不支援 systemd ,所以無法執行 systemctl status mita 或 journalctl -xe -u mita --no-pager 。

正如我上次所說,因為 Asuswrt-Merlin 為精簡版 linux 版本,所以這次也無法執行 sudouseraddusermod ,都顯示為 not found,但成功執行 mkdirchmod

2022-06-04_154320

2022-06-04_154459


基於 Asuswrt-Merlin 的特殊環境,跟據我以往安裝 Brook、Caddy、Hysteria、V2Ray及 Xray 等經驗,我先用瀏覽器下載執行檔,透過 WinSCP 將 mita 檔放入到 /mnt/sda/ 這個 外接 USB 隨身碟 資料夾中,而非 /etc/mita 目錄,然後執行

/mnt/sda/mieru/mita apply config /mnt/sda/mieru/server_config
/mnt/sda/mieru/mita start

2022-06-04_154852

錯誤訊息為:get mieru server status failed: ServerLifecycleService.GetStatus() failed: rpc error: code = Unavailable desc = connection error: desc = "transport: Error while dialing dial unix /var/run/mita.sock: connect: no such file or directory"

由此可見,mita 進程不會主動創建 /var/run/mita.sock 這個 UNIX domain socket 文件,因此無法執行 applystart 指令。

總言之,第一步及第二步並不適用於 Asuswrt-Merlin 路由器系統,因為我是將 mita 檔放入到 /mnt/sda/ 目錄,而非 /etc/mita 目錄;我登入時的用戶為管理員權制,不需要建立 mita 用戶和用戶租,

sudo useradd --no-create-home --user-group mita
sudo usermod -a -G mita $USER
sudo reboot
sudo mkdir -p /etc/mita
sudo chmod 775 /etc/mita

GoLang 的特色就是開箱即用,編譯後只有一個執行檔。我在執行其他軟件時,都是執行一句指令就能成功啟動,例如下圖的 Xray、Caddy、V2Ray、Snell,甚至是 Rust 的 Shadowsocks-rust

2022-06-04_153719

這些程式就是直接一句指令啟動,但我執行 /mnt/sda/mieru/mita start 卻失敗,可能是其他程式啟動時不需要建立 UNIX domain socket 文件,所以能直接執行。


本人身處牆外,所以把 mita 作為伺服器在家庭路由器上執行,讓其他牆內使用者測試。

如果提供 arm 版本,除了方便了我之外,也方便了其他擁有甲骨文 Oracle ARM 免費主機的用戶。謝謝。

enfein commented 2 years ago

如果路由器没有办法添加新的 Linux 用户,以现在的实现,是没有办法正确运行服务端软件的。mita 启动后会因 pkg/cli/server.go 文件中的 updateServerUDSPermission 函数报错而退出。

如果你想继续使用这台路由器做测试,我可以创建一个新的 git 分支,提供一个单独的补丁来暂时绕过这个问题。不过,我还是建议拿一台公有云服务器来测试,价格也只有一个月五美元而已。

关于和其他工具的比较,我知道那些只有单个可执行文件的工具提供了更大的灵活性,但是它们也相应会付出一定的代价。在稳定性方面,如果没有 systemd 来监视程序运行,当程序因为系统资源不足被杀掉,或者收到了信号而退出的时候,是不会重新启动的,这时候需要人工登录到服务器上进行故障排查,很麻烦。systemd 还解决了日志存放的问题,日志既不会丢失,也不会占满整个磁盘的空间。在安全性方面,像 shadowsocks 那种直接把用户名和密码作为程序启动参数的做法,是毫无安全可言的。mita 由于使用独立的用户,即便运行在分享的服务器里,如果你不提供合适的权限,别人也无法控制你的程序。

我们的客户端程序 mieru 只需单个可执行文件就可以工作。设计之初的想法是,如果需要运行在路由器等特殊硬件上,mieru 可以轻松胜任;服务端程序 mita 运行在云服务器上,那里是一个常规的 Linux 系统,具备 systemd 和创建用户等基本功能。没想到这次的使用场景比较特殊,在我们的意料之外,于是出现了现在的问题。

鉴于 ARM 架构在公有云逐渐普及,我们在后续的版本中会提供相应的可执行文件和安装包。

samho1234567 commented 2 years ago

非常感激作者建立 git 新分支,增添了作者的工作量 :slightly_frowning_face:

  1. 對 Asuswrt-Merlin 而言,軟件隨系統啟動的替代方法為,在/jffs/scripts/services-start 寫入以下內容:
#Mita Start
/mnt/sda/mieru/mita start > /dev/null 2>&1 &
#check mita every 15 minute
cru a check-mita "*/15 * * * * /jffs/scripts/mita-status.sh > /dev/null"
  1. 然後寫一個 Bash Script,命名為mita-status.sh,每15分鐘檢查進程是否執行中,如果進程被殺掉則重啟:
#! /bin/bash

mita=$(pgrep mita)

if [ -z "$mita" ] ; then
      /mnt/sda/mieru/mita start &
else
     :
fi

exit 0

再次感激作者造輪子,使翻牆協議和軟件百花齊放。多一種協議,多一種出路。:smile:

enfein commented 2 years ago

我刚刚上传了一个新的分支 no-mita-user。请切换到新的分支重新编译代码。

我假设你已经创建了 /etc/mita 文件夹。在 /jffs/scripts/services-start/jffs/scripts/mita-status.sh 中,把所有mita start 替换成 mita run,应该就可以继续使用了。我在文档中只提及了 mita start 这个指令,它假定 mita 后台程序已经被 systemd 启动,并通过 /var/run/mita.sock 向这个程序发送指令来启动网络代理服务。相应的,mita stop 只是停止网络代理服务,但是 mita 后台程序并没有退出。现在的情况是 mita 后台程序还没有启动,因此要使用 mita run 指令来启动它。因为正常情况下用户接触不到,因此 mita run 指令我在文档中没有提及。

通过

/mnt/sda/mieru/mita run > /dev/null 2>&1 &

启动 mita 后台程序之后,就可以跟随文档继续使用 /mnt/sda/mieru/mita ??? 指令完成剩下的安装工作了。

下午去做个核酸,如果还有什么需要讨论的,等我过一两天上线再回复。

samho1234567 commented 2 years ago

2022-06-05_130849

剛剛我編譯了 no-mita-user 分支,比較 main 分支與 no-mita-user 分支, no-mita-user 雖然解決了 mita run 的問題,不過 mita apply configmita start 仍然有錯誤。

/etc/mita/mita apply config /etc/mita/mita/server_config.json                                                                                                                                                                              
get mieru server status failed: ServerLifecycleService.GetStatus() failed: rpc error: code = Unavailable desc = connection error: desc = "transport: Error while dialing dial unix /var/run/mita.sock: connect: connection refused"                                            
/etc/mita/mita start                                                                                                                                                                                                                       
get mieru server status failed: ServerLifecycleService.GetStatus() failed: rpc error: code = Unavailable desc = connection error: desc = "transport: Error while dialing dial unix /var/run/mita.sock: connect: connection refused"                                            
/etc/mita/mita run                                                                                                                                                                                                                         
2022-06-05T13:58:28+08:00 INFO mieru server daemon RPC server is running

2022-06-05_132753

我透過執行 netstat -tulpn 指令發現,mita 似乎未能讀取 server_config.jsonmita run 執行成功可能只是假象。


2022-06-05_132548

相反,我以 shadowsocks 作例子,執行 nohup /mnt/sda/shadowsocks-rust/ssserver -c /mnt/sda/shadowsocks-rust/config.json & 之後,再執行 netstat -tulpn 可見,4832/ssserver 執行中,正在監聽 TCPUDP0.0.0.0:8443


由此可見,mita run 未必是真正的執行,因為相關進程在 netstat -tulpn 沒有執行。

enfein commented 2 years ago

如果遇到了 connection refused 错误,是因为 mita 后台程序没有启动。请尝试下面的操作:

  1. 在第一个窗口运行 ./mita run 并且不要退出。这里可以看到 mita 后台程序的日志。打印的日志请贴过来,有助于 debug。
  2. 之后,打开第二个窗口,运行 netstat -apn | grep mita。如果能找到,就说明 mita 后台程序正在运行,这是成功执行后续指令的基础。netstat -tulpn 不会显示 UNIX domain socket,所以先前你在里面查询 mita 是找不到的。
  3. 继续在第二个窗口运行 ./mita status./mita apply config ..../mita start 系列指令。运行所有这些指令的时候,请确保第一个窗口的 ./mita run 没有退出,否则又会回到一开始的 connection refused 错误。
samho1234567 commented 2 years ago

謝謝你的耐心指導,終於成功執行到 mita 伺服器:clap:。本人的 linux 知識為半桶水水平,有請多多指教:raised_hands:。

唯一的不足之處,就是 mita 必須放在 /etc/mita 目錄,否則無法執行,一旦路由器重啟後,/etc/mita 資料夾和所有內容都會消失:pensive:,需要重次複製 mita 執行檔。我的習慣是將軟件存放 /mnt/sda/ 外接 USB 隨身碟上,即使路由器重啟後,內容依然存在。這個 bug 略有不便。

  1. 第一個窗口訊息:

2022-06-06_180025

/etc/mita/mita run

2022-06-06T17:56:28+08:00 INFO mieru server daemon RPC server is running
2022-06-06T17:56:55+08:00 INFO return app status IDLE back to RPC caller
2022-06-06T17:57:20+08:00 INFO received start request from RPC caller
2022-06-06T17:57:20+08:00 INFO mieru server daemon socks5 server "[::]:8080" is running
2022-06-06T17:57:20+08:00 INFO mieru server daemon socks5 server "[::]:8080" is running
2022-06-06T17:57:20+08:00 INFO enabled metrics logging with duration 1m0s
2022-06-06T17:57:20+08:00 INFO completed start request from RPC caller
2022-06-06T18:00:21+08:00 INFO [metrics]
2022-06-06T18:00:21+08:00 INFO [metrics - connections] ActiveOpens=0 CurrEstablished=16 MaxConn=16 PassiveOpens=24
2022-06-06T18:00:21+08:00 INFO [metrics - server decryption] ServerDirectDecrypt=354 ServerFailedDirectDecrypt=0
2022-06-06T18:00:21+08:00 INFO [metrics - client decryption] ClientDirectDecrypt=0 ClientFailedDirectDecrypt=0
2022-06-06T18:00:21+08:00 INFO [metrics - UDP packets] InPkts=0 OutPkts=0
2022-06-06T18:00:21+08:00 INFO [metrics - KCP segments] EarlyRetransSegs=0 FastRetransSegs=0 InSegs=0 LostSegs=0 OutOfWindowSegs=0 OutSegs=0 RepeatSegs=0 RetransSegs=0
2022-06-06T18:00:21+08:00 INFO [metrics - UDP bytes] InBytes=0 OutBytes=0
2022-06-06T18:00:21+08:00 INFO [metrics - KCP bytes] BytesReceived=0 BytesSent=0 PaddingSent=0
2022-06-06T18:00:21+08:00 INFO [metrics - TCP bytes] InBytes=57787 OutBytes=2060283 PaddingSent=17645
2022-06-06T18:00:21+08:00 INFO [metrics - replay protection] ReplayKnownSession=0 ReplayNewSession=0
2022-06-06T18:00:21+08:00 INFO [metrics - UDP errors] KCPInErrors=0 KCPReceiveErrors=0 KCPSendErrors=0 UDPInErrors=0
2022-06-06T18:00:21+08:00 INFO [metrics - TCP errors] TCPReceiveErrors=0 TCPSendErrors=0
2022-06-06T18:00:21+08:00 INFO [metrics - server socks5 errors] ConnectionRefused=1 DNSResolveErrors=0 HandshakeErrors=4 HostUnreachable=1 NetworkUnreachable=0 UnsupportedCommand=0
2022-06-06T18:21:51+08:00 INFO received stop request from RPC caller                                                                 
2022-06-06T18:21:51+08:00 INFO stopping socks5 server(s)                                                                             
2022-06-06T18:21:51+08:00 INFO completed stop request from RPC caller                                                                
2022-06-06T18:21:51+08:00 INFO closing socks5 server listener                                                                        
2022-06-06T18:21:51+08:00 INFO mieru server daemon socks5 server "[::]:8080" is stopped                                              
2022-06-06T18:21:51+08:00 INFO closing socks5 server listener                                                                        
2022-06-06T18:21:51+08:00 INFO Listener [::]:8080: closed                                                                            
2022-06-06T18:21:51+08:00 INFO mieru server daemon socks5 server "[::]:8080" is stopped
  1. 第二個窗口訊息(略去部分密碼內容):

2022-06-06_181237

netstat -apn | grep mita
/etc/mita/mita apply config /etc/mita/server_config.json
/etc/mita/mita describe config
/etc/mita/mita start
/etc/mita/mita stop

如果作者將來有意為 mieru 提供 iOS 及 Android 用戶端,不知道 Shadowrocket 和 SagerNet 是否願意幫忙呢?

enfein commented 2 years ago

mita 可执行文件不需要放置在 /etc/mita 路径下,不过 mita 生成的二进制配置文件会放置在这个路径下,且这个路径暂时无法更改。这个路径被清空后需要用 mita apply config 重新写入配置文件,或者把之前的二进制配置文件复制进来。

至于在 iOS 和安卓平台支持 mieru 协议,如果能得到其他开源项目的支持,我希望可以借助已有的 APP 实现,而不是开发新的 APP,这样可以减轻开发者和用户的负担。