From 9208b92d001348b6fc60a2df5ed839cd321e86f5 Mon Sep 17 00:00:00 2001 From: SunBK201 Date: Sun, 17 Dec 2023 14:57:42 +0800 Subject: [PATCH] feat: use procd --- README.md | 6 +++--- cmd/ua3f.go | 55 +++++++++++++++++++++++++++++++++++++++++++++++++--- install.sh | 6 +++--- ua3f.service | 37 +++++++++++++++++++++++++---------- 4 files changed, 85 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index eebc9ec..9c364d6 100644 --- a/README.md +++ b/README.md @@ -51,9 +51,9 @@ sudo -u shellclash /root/ua3f ### Clash 的配置建议 -请确保 `PROCESS-NAME,ua3f,DIRECT` 置于规则列表顶部,`MATCH,ua3f` 置于规则列表底部。 - -可以在 `PROCESS-NAME,ua3f,DIRECT` 与 `MATCH,ua3f` 之间按需加入自定义加密代理规则。如果上述 2 条规则之间加入 DIRECT 规则,请确保匹配该规则的流量属于非 HTTP 协议流量。 +- Clash 建议选用 Meta 内核。 +- 请确保 `PROCESS-NAME,ua3f,DIRECT` 置于规则列表顶部,`MATCH,ua3f` 置于规则列表底部。 +- 可以在 `PROCESS-NAME,ua3f,DIRECT` 与 `MATCH,ua3f` 之间按需加入自定义加密代理规则。如果上述 2 条规则之间加入 DIRECT 规则,请确保匹配该规则的流量属于非 HTTP 协议流量。 ```yaml proxies: diff --git a/cmd/ua3f.go b/cmd/ua3f.go index 12682a1..4512dcd 100644 --- a/cmd/ua3f.go +++ b/cmd/ua3f.go @@ -20,6 +20,7 @@ import ( var version = "0.1.3" var payloadByte []byte var cache *expirable.LRU[string, string] +var HTTP_METHOD = []string{"GET", "POST", "HEAD", "PUT", "DELETE", "OPTIONS", "TRACE", "CONNECT"} var whitelist = []string{ "MicroMessenger Client", "ByteDancePcdn", @@ -119,6 +120,49 @@ func Socks5Auth(client net.Conn) (err error) { return nil } +// func Socks5UDP() { +// https://datatracker.ietf.org/doc/html/rfc1928 +// // _, _ = client.Write([]byte{0x05, 0x00, 0x00, 0x01, 0x7f, 0, 0, 0x1, 0x04, 0x38}) +// _, _ = client.Write([]byte{0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x04, 0x38}) +// server, _ := net.ListenUDP("udp", &net.UDPAddr{IP: net.IPv4zero, Port: 1080}) +// _, _ = server.Read(buf[:4]) +// frag, atyp := buf[2], buf[3] +// addr := "" +// switch atyp { +// case 1: +// n, err = server.Read(buf[:4]) +// if n != 4 { +// return nil, "", errors.New("invalid IPv4:" + err.Error()) +// } +// addr = fmt.Sprintf("%d.%d.%d.%d", buf[0], buf[1], buf[2], buf[3]) +// case 3: +// n, err = server.Read(buf[:1]) +// if n != 1 { +// return nil, "", errors.New("invalid hostname:" + err.Error()) +// } +// addrLen := int(buf[0]) +// n, err = server.Read(buf[:addrLen]) +// if n != addrLen { +// return nil, "", errors.New("invalid hostname:" + err.Error()) +// } +// addr = string(buf[:addrLen]) +// case 4: +// return nil, "", errors.New("IPv6: no supported yet") +// default: +// return nil, "", errors.New("invalid atyp") +// } +// n, err = server.Read(buf[:2]) +// port := binary.BigEndian.Uint16(buf[:2]) +// destAddrPort := fmt.Sprintf("%s:%d", addr, port) +// logrus.Debug(fmt.Sprintf("Connecting %s", destAddrPort)) +// dest, err := net.Dial("udp", destAddrPort) +// if err != nil { +// return nil, destAddrPort, errors.New("dial dst:" + err.Error()) +// } +// logrus.Debug(fmt.Sprintf("Connected %s", destAddrPort)) +// +// } + func Socks5Connect(client net.Conn) (net.Conn, string, error) { buf := make([]byte, 256) n, err := io.ReadFull(client, buf[:4]) @@ -126,8 +170,14 @@ func Socks5Connect(client net.Conn) (net.Conn, string, error) { return nil, "", errors.New("read header:" + err.Error()) } ver, cmd, _, atyp := buf[0], buf[1], buf[2], buf[3] - if ver != 5 || cmd != 1 { - return nil, "", errors.New("invalid ver/cmd") + if ver != 5 { + return nil, "", errors.New("invalid ver") + } + if cmd == 3 { + return nil, "", errors.New("not support UDP") + } + if cmd != 1 { + return nil, "", errors.New("invalid cmd, only support connect") } addr := "" switch atyp { @@ -246,7 +296,6 @@ func CopyPileline(dst io.Writer, src io.Reader, destAddrPort string) { return } hint := string(buf[0:7]) - HTTP_METHOD := []string{"GET", "POST", "HEAD", "PUT", "DELETE", "OPTIONS", "TRACE", "CONNECT"} is_http := false for _, v := range HTTP_METHOD { if strings.HasPrefix(hint, v) { diff --git a/install.sh b/install.sh index c130d13..ca3dc8f 100755 --- a/install.sh +++ b/install.sh @@ -49,8 +49,8 @@ fi tar zxf $ua3f_tar && rm -f $ua3f_tar chmod +x ua3f -if [ -f "ua3f.service" ]; then - rm "ua3f.service" +if [ -f "/etc/init.d/ua3f.service" ]; then + rm "/etc/init.d/ua3f.service" fi wget https://blog.sunbk201.site/cdn/ua3f.service if [ $? -ne 0 ]; then @@ -62,5 +62,5 @@ mv ua3f.service /etc/init.d/ && chmod +x /etc/init.d/ua3f.service if [ $? -eq 0 ]; then echo "Install UA3F Success." - echo "Use /etc/init.d/ua3f.service {start|stop|restart} to control UA3F." + echo "Use /etc/init.d/ua3f.service {start|stop|restart|enable} to control UA3F." fi \ No newline at end of file diff --git a/ua3f.service b/ua3f.service index 60e3201..ea06dd4 100755 --- a/ua3f.service +++ b/ua3f.service @@ -1,19 +1,36 @@ #!/bin/sh /etc/rc.common +USE_PROCD=1 + START=99 -start() { - echo "ua3f is starting" +NAME="ua3f" +PROG="/root/$NAME" + +start_service() { + chmod o+w /var/log + + procd_open_instance "$NAME" + procd_set_param command "$PROG" + procd_append_param command -b "127.0.0.1" + procd_append_param command -p 1080 + procd_append_param command -f "FFF" + procd_append_param command -l info + + procd_set_param respawn + procd_set_param stdout 1 + procd_set_param stderr 1 + if id -u shellclash &> /dev/null; then - sudo -u shellclash /root/ua3f &> /dev/null & + procd_set_param user shellclash elif id -u nobody &> /dev/null; then - sudo -u nobody /root/ua3f &> /dev/null & - else - /root/ua3f &> /dev/null & + procd_set_param user nobody fi + + procd_close_instance } -stop() { - echo "ua3f is stopping" - killall ua3f -} +reload_service() { + stop + start +} \ No newline at end of file