Skip to content

Commit

Permalink
new: add xray configs
Browse files Browse the repository at this point in the history
  • Loading branch information
hiddify-com committed Jul 25, 2024
1 parent 5b3735b commit c188323
Show file tree
Hide file tree
Showing 9 changed files with 448 additions and 33 deletions.
16 changes: 9 additions & 7 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
module github.com/hiddify/ray2sing

go 1.21.1
go 1.21.4

toolchain go1.22.3

require (
github.com/sagernet/sing v0.4.1
Expand All @@ -11,15 +13,15 @@ require (
require (
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/logrusorgru/aurora v2.0.3+incompatible // indirect
github.com/miekg/dns v1.1.59 // indirect
github.com/miekg/dns v1.1.61 // indirect
github.com/sagernet/sing-dns v0.2.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect
golang.org/x/mod v0.17.0 // indirect
golang.org/x/net v0.25.0 // indirect
golang.org/x/mod v0.18.0 // indirect
golang.org/x/net v0.27.0 // indirect
golang.org/x/sync v0.7.0 // indirect
golang.org/x/sys v0.21.0 // indirect
golang.org/x/tools v0.21.0 // indirect
golang.org/x/sys v0.22.0 // indirect
golang.org/x/tools v0.22.0 // indirect
)

replace github.com/sagernet/sing-box => github.com/hiddify/hiddify-sing-box v1.8.9-0.20240717205631-60d55deb81f9
replace github.com/sagernet/sing-box => github.com/hiddify/hiddify-sing-box v1.8.9-0.20240724225257-adf55aaf0721
47 changes: 24 additions & 23 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,20 @@ github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46t
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
github.com/google/pprof v0.0.0-20231101202521-4ca4178f5c7a h1:fEBsGL/sjAuJrgah5XqmmYsTLzJp/TO9Lhy39gkverk=
github.com/google/pprof v0.0.0-20231101202521-4ca4178f5c7a/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik=
github.com/hiddify/hiddify-sing-box v1.8.9-0.20240717205631-60d55deb81f9 h1:01JjBBilkGSza9eEVRN6XK7JDABbeDWgbYQN+/6j+tc=
github.com/hiddify/hiddify-sing-box v1.8.9-0.20240717205631-60d55deb81f9/go.mod h1:AlbX8EFeSVKjitRnpX2Zv6oD3IGhOFXiPq+4P71Io54=
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
github.com/google/pprof v0.0.0-20240528025155-186aa0362fba h1:ql1qNgCyOB7iAEk8JTNM+zJrgIbnyCKX/wdlyPufP5g=
github.com/google/pprof v0.0.0-20240528025155-186aa0362fba/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo=
github.com/hiddify/hiddify-sing-box v1.8.9-0.20240724225257-adf55aaf0721 h1:yt0l4Hhjto9o3k/rWNEQRGEh4bZEDgEDBvyUpA/2wSY=
github.com/hiddify/hiddify-sing-box v1.8.9-0.20240724225257-adf55aaf0721/go.mod h1:6+sp+GwVbdHDne/axYdOYBBZL1aXqVty27KqhQM175U=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8=
github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
github.com/miekg/dns v1.1.59 h1:C9EXc/UToRwKLhK5wKU/I4QVsBUc8kE6MkHBkeypWZs=
github.com/miekg/dns v1.1.59/go.mod h1:nZpewl5p6IvctfgrckopVx2OlSEHPRO/U4SYkRklrEk=
github.com/onsi/ginkgo/v2 v2.9.7 h1:06xGQy5www2oN160RtEZoTvnP2sPhEfePYmCDc2szss=
github.com/onsi/ginkgo/v2 v2.9.7/go.mod h1:cxrmXWykAwTwhQsJOPfdIDiJ+l2RYq7U8hFU+M/1uw0=
github.com/miekg/dns v1.1.61 h1:nLxbwF3XxhwVSm8g9Dghm9MHPaUZuqhPiGL+675ZmEs=
github.com/miekg/dns v1.1.61/go.mod h1:mnAarhS3nWaW+NVP2wTkYVIZyHNJ098SJZUki3eykwQ=
github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA=
github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
Expand All @@ -36,22 +37,22 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBseWJUpBw5I82+2U4M=
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y=
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM=
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc=
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc h1:O9NuF4s+E/PvMIy+9IUZB9znFwUIXEWSstNjek6VpVg=
golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc=
golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw=
golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA=
golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
1 change: 1 addition & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ var examples = map[string][]string{
},
"vless": {
"vless://[email protected]:443?encryption=none&fp=chrome&host=vless.229feb8b52a0e7e117ea76f8b591bcb3.workers.dev&path=%2F%3Fed%3D2048&security=tls&sni=vless.229feb8b52a0e7e117ea76f8b591bcb3.workers.dev&type=ws#رایگان | VLESS | @Helix_Servers | US🇺🇸 | 0️⃣1️⃣",
"vless://[email protected]:443?encryption=none&fp=chrome&host=vless.229feb8b52a0e7e117ea76f8b591bcb3.workers.dev&path=%2F%3Fed%3D2048&security=tls&sni=vless.229feb8b52a0e7e117ea76f8b591bcb3.workers.dev&type=ws&core=xray#رایگان | VLESS | @Helix_Servers | US🇺🇸 | 0️⃣1️⃣",
},
"vmess": {
"vmess://eyJhZGQiOiI1MS4xNjEuMTMwLjE3MyIsImFpZCI6IjAiLCJhbHBuIjoiIiwiZnAiOiIiLCJob3N0IjoiIiwiaWQiOiJkNDNlZTVlMy0xYjA3LTU2ZDctYjJlYS04ZDIyYzQ0ZmRjNjYiLCJuZXQiOiJ0Y3AiLCJwYXRoIjoiIiwicG9ydCI6IjgwODAiLCJzY3kiOiJjaGFjaGEyMC1wb2x5MTMwNSIsInNuaSI6IiIsInRscyI6IiIsInR5cGUiOiJub25lIiwidiI6IjIiLCJwcyI6Ilx1MDYzMVx1MDYyN1x1MDZjY1x1MDZhZlx1MDYyN1x1MDY0NiB8IFZNRVNTIHwgQFdhdGFzaGlfVlBOIHwgQVVcdWQ4M2NcdWRkZTZcdWQ4M2NcdWRkZmEgfCAwXHVmZTBmXHUyMGUzMVx1ZmUwZlx1MjBlMyJ9",
Expand Down
20 changes: 17 additions & 3 deletions ray2sing/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ var configTypes = map[string]ParserFunc{
"http://": HttpSingbox,
"https://": HttpsSingbox,
}
var xrayConfigTypes = map[string]ParserFunc{
"vmess://": VmessXray,
"vless://": VlessXray,
"trojan://": TrojanXray,
"direct://": DirectXray,
}

func processSingleConfig(config string) (outbound *T.Outbound, err error) {
defer func() {
Expand All @@ -47,9 +53,17 @@ func processSingleConfig(config string) (outbound *T.Outbound, err error) {
}()

var configSingbox *T.Outbound
for k, v := range configTypes {
if strings.HasPrefix(config, k) {
configSingbox, err = v(config)
if strings.Contains(config, "&core=xray") {
for k, v := range xrayConfigTypes {
if strings.HasPrefix(config, k) {
configSingbox, err = v(config)
}
}
} else {
for k, v := range configTypes {
if strings.HasPrefix(config, k) {
configSingbox, err = v(config)
}
}
}

Expand Down
204 changes: 204 additions & 0 deletions ray2sing/xraycommon.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
package ray2sing

import (
E "github.com/sagernet/sing/common/exceptions"

"strings"
)

func getTLSOptionsXray(decoded map[string]string) map[string]any {
if !(decoded["tls"] == "tls" || decoded["security"] == "tls") {
return nil
}
serverName := decoded["sni"]
if serverName == "" {
serverName = decoded["add"]
}
alpn := []string{"h2", "http/1.1"}
if alpnlink, ok := decoded["alpn"]; ok && alpnlink != "" {
alpn = strings.Split(alpnlink, ",")
}

fp := decoded["fp"]
if fp == "" {
// fp = "chrome"
}

return map[string]any{
"serverName": serverName,
"rejectUnknownSni": false,
"allowInsecure": decoded["insecure"] == "true",
"alpn": alpn,
// "minVersion": "1.2",
// "maxVersion": "1.3",
// "disableSystemRoot": false,
// "enableSessionResumption": true,
"fingerprint": fp,
}
}
func getRealityOptionsXray(decoded map[string]string) map[string]any {
if !(decoded["security"] == "reality") {
return nil
}
serverName := decoded["sni"]
if serverName == "" {
serverName = decoded["add"]
}
// alpn := []string{"h2", "http/1.1"}
// if alpnlink, ok := decoded["alpn"]; ok && alpnlink != "" {
// alpn = strings.Split(alpnlink, ",")
// }

fp := decoded["fp"]
if fp == "" {
// fp = "chrome"
}

return map[string]any{
"serverName": serverName,
"fingerprint": fp,
"shortId": decoded["sid"],
"spiderX": decoded["spx"],
"publicKey": decoded["pbk"],
}
}

func getMuxOptionsXray(decoded map[string]string) map[string]any {
if decoded["mux"] == "" {
return nil
}
return map[string]any{
"enabled": true,
"concurrency": toInt(decoded["mux"]),
// "xudpConcurrency": 16,
// "xudpProxyUDP443": "reject"
}
}
func getsplithttp(decoded map[string]string) map[string]any {
path := decoded["path"]
if path == "" {
path = "/"
}

return map[string]any{
"path": path,
"host": decoded["host"],
"headers": map[string]string{
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36",
},
// "maxUploadSize": 1000000,
// "maxConcurrentUploads": 10
}
}
func gethttpupgrade(decoded map[string]string) map[string]any {
path := decoded["path"]
if path == "" {
path = "/"
}

return map[string]any{
"path": path,
"host": decoded["host"],
"headers": map[string]string{
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36",
},
}
}
func getwebsocket(decoded map[string]string) map[string]any {
path := decoded["path"]
if path == "" {
path = "/"
}

return map[string]any{
"path": path,
"host": decoded["host"],
"headers": map[string]string{
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36",
},
}
}

func geth2(decoded map[string]string) map[string]any {
path := decoded["path"]
if path == "" {
path = "/"
}

return map[string]any{
"path": path,
"host": strings.Split(decoded["host"], ","),
"headers": map[string]string{
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36",
},
}
}

func getquic(decoded map[string]string) map[string]any {

return map[string]any{
"security": decoded["quicSecurity"],
"key": decoded["key"],
"header": map[string]string{
"type": decoded["headertype"],
},
}
}

func getgrpc(decoded map[string]string) map[string]any {

return map[string]any{
"authority": decoded["authority"],
"serviceName": decoded["servicename"],
"mode": decoded["mode"],
"user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36",
}
}

func getStreamSettingsXray(decoded map[string]string) (map[string]any, error) {

net, path := decoded["net"], decoded["path"]
if net == "" {
net = decoded["type"]
}
if path == "" {
path = decoded["servicename"]
}
// fmoption.Printf("\n\nheaderType:%s, net:%s, type:%s\n\n", decoded["headerType"], net, decoded["type"])
// if (decoded["type"] == "http" || decoded["headertype"] == "http") && net == "tcp" {
// net = "http"
// }
res := map[string]any{}
tls := getTLSOptionsXray(decoded)
if tls != nil {
res["security"] = "tls"
res["tlsSettings"] = tls
}
reality := getRealityOptionsXray(decoded)
if reality != nil {
res["security"] = "reality"
res["realitySettings"] = reality
}
res["network"] = net
switch net {
case "tcp":
res[net+"Settings"] = map[string]any{}

case "httpupgrade":
res[net+"Settings"] = gethttpupgrade(decoded)
case "ws":
res[net+"Settings"] = getwebsocket(decoded)
case "grpc":
res[net+"Settings"] = getgrpc(decoded)
case "quic":
res[net+"Settings"] = getquic(decoded)
case "splithttp":
res[net+"Settings"] = getsplithttp(decoded)
case "h2":
res[net+"Settings"] = geth2(decoded)
default:
return nil, E.New("unknown transport type: " + net)
}

return res, nil
}
43 changes: 43 additions & 0 deletions ray2sing/xraydirect.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package ray2sing

import (
"strings"

T "github.com/sagernet/sing-box/option"
)

func DirectXray(vlessURL string) (*T.Outbound, error) {
u, err := ParseUrl(vlessURL, 443)
if err != nil {
return nil, err
}
decoded := u.Params
// packetEncoding := decoded["packetencoding"]
// if packetEncoding==""{
// packetEncoding="xudp"
// }
frag, err := getOneOf(decoded, "frg", "fragment")
fragdata := map[string]any{}
if err != nil && frag != "" {
frags := strings.Split(frag, ",")
fragdata = map[string]any{
"packets": frags[0],
"length": frags[1],
"interval": frags[2],
}
}
return &T.Outbound{
Tag: u.Name,
Type: "xray",
XrayOptions: T.XrayOutboundOptions{
// DialerOptions: getDialerOptions(decoded),
XrayOutboundJson: map[string]any{
"protocol": "freedom",
"settings": map[string]any{
"fragment": fragdata,
},
"tag": u.Name,
},
},
}, nil
}
Loading

0 comments on commit c188323

Please sign in to comment.