init: 1.0.0

This commit is contained in:
Chang lue Tsen
2025-04-25 12:08:29 +09:00
commit 8addcc584b
1031 changed files with 76472 additions and 0 deletions
+27
View File
@@ -0,0 +1,27 @@
package loon
import (
"github.com/perfect-panel/ppanel-server/pkg/adapter/proxy"
)
func BuildLoon(servers []proxy.Proxy, uuid string) []byte {
uri := ""
for _, s := range servers {
switch s.Protocol {
case "vmess":
uri += buildVMess(s, uuid)
case "shadowsocks":
uri += buildShadowsocks(s, uuid)
case "trojan":
uri += buildTrojan(s, uuid)
case "vless":
uri += buildVless(s, uuid)
case "hysteria2":
uri += buildHysteria2(s, uuid)
default:
continue
}
}
return []byte(uri)
}
+34
View File
@@ -0,0 +1,34 @@
package loon
import (
"fmt"
"strconv"
"strings"
"github.com/perfect-panel/ppanel-server/pkg/adapter/proxy"
)
func buildHysteria2(data proxy.Proxy, password string) string {
hysteria2 := data.Option.(proxy.Hysteria2)
configs := []string{
fmt.Sprintf("%s=Hysteria2", data.Name),
data.Server,
strconv.Itoa(data.Port),
password,
"udp=true",
}
if hysteria2.ObfsPassword != "" {
configs = append(configs, "obfs=salamander", fmt.Sprintf("salamander-password=%s", hysteria2.ObfsPassword))
}
if hysteria2.SecurityConfig.SNI != "" {
configs = append(configs, fmt.Sprintf("sni=%s", hysteria2.SecurityConfig.SNI))
if hysteria2.SecurityConfig.AllowInsecure {
configs = append(configs, "skip-cert-verify=true")
} else {
configs = append(configs, "skip-cert-verify=false")
}
}
uri := strings.Join(configs, ",")
return uri + "\r\n"
}
+29
View File
@@ -0,0 +1,29 @@
package loon
import (
"testing"
"github.com/perfect-panel/ppanel-server/pkg/adapter/proxy"
)
func createSS() proxy.Proxy {
return proxy.Proxy{
Name: "Shadowsocks",
Server: "127.0.0.1",
Port: 10301,
Protocol: "shadowsocks",
Option: proxy.Shadowsocks{
Method: "aes-256-gcm",
ServerKey: "",
},
}
}
func TestBuildSS(t *testing.T) {
s := createSS()
password := "f0d0237d-193a-4cf5-99dd-b02207beaea6"
uri := buildShadowsocks(s, password)
t.Log(uri)
}
+49
View File
@@ -0,0 +1,49 @@
package loon
import (
"fmt"
"strconv"
"strings"
"github.com/perfect-panel/ppanel-server/pkg/adapter/proxy"
"github.com/perfect-panel/ppanel-server/pkg/tool"
"github.com/perfect-panel/ppanel-server/pkg/uuidx"
)
func buildShadowsocks(data proxy.Proxy, password string) string {
shadowsocks := data.Option.(proxy.Shadowsocks)
// If the method is 2022-blake3-chacha20-poly1305, it means that the server is a relay server
if shadowsocks.Method == "2022-blake3-chacha20-poly1305" {
return ""
}
if strings.Contains(shadowsocks.Method, "2022") {
serverKey, userKey := generateShadowsocks2022Password(shadowsocks, password)
password = fmt.Sprintf("%s:%s", serverKey, userKey)
}
configs := []string{
fmt.Sprintf("%s=Shadowsocks", data.Name),
data.Server,
strconv.Itoa(data.Port),
shadowsocks.Method,
password,
"fast-open=false",
"udp=true",
}
uri := strings.Join(configs, ",")
return uri + "\r\n"
}
func generateShadowsocks2022Password(ss proxy.Shadowsocks, password string) (string, string) {
// server key
var serverKey string
if ss.Method == "2022-blake3-aes-128-gcm" {
serverKey = tool.GenerateCipher(ss.ServerKey, 16)
password = uuidx.UUIDToBase64(password, 16)
} else {
serverKey = tool.GenerateCipher(ss.ServerKey, 32)
password = uuidx.UUIDToBase64(password, 32)
}
return serverKey, password
}
+44
View File
@@ -0,0 +1,44 @@
package loon
import (
"fmt"
"strings"
"github.com/perfect-panel/ppanel-server/pkg/adapter/proxy"
)
func buildTrojan(data proxy.Proxy, password string) string {
trojan := data.Option.(proxy.Trojan)
configs := []string{
fmt.Sprintf("%s=trojan", data.Name),
data.Server,
fmt.Sprintf("%d", data.Port),
"auto",
password,
"fast-open=false",
"udp=true",
}
if trojan.SecurityConfig.SNI != "" {
configs = append(configs, fmt.Sprintf("sni=%s", trojan.SecurityConfig.SNI))
}
if trojan.SecurityConfig.AllowInsecure {
configs = append(configs, "skip-cert-verify=true")
} else {
configs = append(configs, "skip-cert-verify=false")
}
if trojan.Transport == "websocket" {
configs = append(configs, "transport=ws")
if trojan.TransportConfig.Path != "" {
configs = append(configs, fmt.Sprintf("path=%s", trojan.TransportConfig.Path))
}
if trojan.TransportConfig.Host != "" {
configs = append(configs, fmt.Sprintf("host=%s", trojan.TransportConfig.Host))
}
}
uri := strings.Join(configs, ",")
return uri + "\r\n"
}
+62
View File
@@ -0,0 +1,62 @@
package loon
import (
"fmt"
"strconv"
"strings"
"github.com/perfect-panel/ppanel-server/pkg/adapter/proxy"
"github.com/perfect-panel/ppanel-server/pkg/logger"
)
func buildVless(data proxy.Proxy, password string) string {
vless := data.Option.(proxy.Vless)
// If flow is not empty, it means that the server is a relay server
if vless.Flow != "" {
return ""
}
configs := []string{
fmt.Sprintf("%s=vless", data.Name),
data.Server,
strconv.Itoa(data.Port),
"auto",
password,
"fast-open=false",
"udp=true",
"alterId=0",
}
switch vless.Transport {
case "tcp":
configs = append(configs, "transport=tcp")
case "websocket":
configs = append(configs, "transport=ws")
if vless.TransportConfig.Path != "" {
configs = append(configs, fmt.Sprintf("path=%s", vless.TransportConfig.Path))
}
if vless.TransportConfig.Host != "" {
configs = append(configs, fmt.Sprintf("host=%s", vless.TransportConfig.Host))
}
default:
logger.Info("Loon Unknown transport type: ", logger.Field("transport", vless.Transport))
return ""
}
if vless.Security == "tls" {
configs = append(configs, "over-tls=true", fmt.Sprintf("tls-name=%s", vless.SecurityConfig.SNI))
if vless.SecurityConfig.AllowInsecure {
configs = append(configs, "skip-cert-verify=true")
} else {
configs = append(configs, "skip-cert-verify=false")
}
} else if vless.Security == "reality" {
// Loon does not support reality security
logger.Info("Loon Unknown security type: ", logger.Field("security", vless.Security))
return ""
}
uri := strings.Join(configs, ",")
return uri + "\r\n"
}
+53
View File
@@ -0,0 +1,53 @@
package loon
import (
"fmt"
"strings"
"github.com/perfect-panel/ppanel-server/pkg/adapter/proxy"
"github.com/perfect-panel/ppanel-server/pkg/logger"
)
func buildVMess(data proxy.Proxy, password string) string {
vmess := data.Option.(proxy.Vmess)
configs := []string{
fmt.Sprintf("%s=vmess", data.Name),
data.Server,
fmt.Sprintf("%d", data.Port),
"auto",
password,
"fast-open=false",
"udp=true",
"alterId=0",
}
switch vmess.Transport {
case "tcp":
configs = append(configs, "transport=tcp")
case "websocket":
configs = append(configs, "transport=ws")
if vmess.TransportConfig.Path != "" {
configs = append(configs, fmt.Sprintf("path=%s", vmess.TransportConfig.Path))
}
if vmess.TransportConfig.Host != "" {
configs = append(configs, fmt.Sprintf("host=%s", vmess.TransportConfig.Host))
}
default:
logger.Info("Loon Unknown transport type: ", logger.Field("transport", vmess.Transport))
return ""
}
if vmess.Security == "tls" {
configs = append(configs, "over-tls=true", fmt.Sprintf("tls-name=%s", vmess.SecurityConfig.SNI))
if vmess.SecurityConfig.AllowInsecure {
configs = append(configs, "skip-cert-verify=true")
} else {
configs = append(configs, "skip-cert-verify=false")
}
}
uri := strings.Join(configs, ",")
return uri + "\r\n"
}