summaryrefslogtreecommitdiff
path: root/internal/control/reality.go
diff options
context:
space:
mode:
authorsergei <sergei@em-sysadmin.xyz>2026-04-14 06:23:55 +0400
committersergei <sergei@em-sysadmin.xyz>2026-04-14 06:23:55 +0400
commit3d51aa455006903345f554a2dd90034993796114 (patch)
tree62a7be2faf047f5eb7886feebc3b815556f03d7f /internal/control/reality.go
downloadvpnem-3d51aa455006903345f554a2dd90034993796114.tar.gz
vpnem-3d51aa455006903345f554a2dd90034993796114.tar.bz2
vpnem-3d51aa455006903345f554a2dd90034993796114.zip
vpnem: VPN infrastructure with load-balanced multi-protocol nodesHEADmain
- Multi-protocol VPS nodes (VLESS-REALITY + Hysteria2 + SOCKS5) - Smart load balancing via recommendation API - Windows/Linux client (Go + Wails + sing-box) - Server API with RealIP detection and connection tracking - Auto-deployment via vpnui control plane - Silent Windows installer with UAC elevation - Load-based server recommendation (no sticky sessions) - Best Server one-click connection workflow
Diffstat (limited to 'internal/control/reality.go')
-rw-r--r--internal/control/reality.go64
1 files changed, 64 insertions, 0 deletions
diff --git a/internal/control/reality.go b/internal/control/reality.go
new file mode 100644
index 0000000..301a674
--- /dev/null
+++ b/internal/control/reality.go
@@ -0,0 +1,64 @@
+package control
+
+import (
+ "crypto/rand"
+ "encoding/base64"
+ "encoding/hex"
+ "fmt"
+ "strings"
+
+ "golang.zx2c4.com/wireguard/wgctrl/wgtypes"
+)
+
+const defaultRealityServerName = "www.nokia.com"
+
+func ensureRealityProfile(protocol *ProtocolProfile) error {
+ if protocol == nil || protocol.Type != "vless-reality" {
+ return nil
+ }
+ if protocol.Reality == nil {
+ protocol.Reality = &VLESSRealityProfile{}
+ }
+ if strings.TrimSpace(protocol.Reality.ServerName) == "" {
+ protocol.Reality.ServerName = defaultRealityServerName
+ }
+ if protocol.Reality.ServerPort == 0 {
+ protocol.Reality.ServerPort = 443
+ }
+ if strings.TrimSpace(protocol.Reality.Fingerprint) == "" {
+ protocol.Reality.Fingerprint = "chrome"
+ }
+ if strings.TrimSpace(protocol.Reality.PrivateKey) == "" || strings.TrimSpace(protocol.Reality.PublicKey) == "" {
+ privateKey, publicKey, err := generateRealityKeyPair()
+ if err != nil {
+ return err
+ }
+ protocol.Reality.PrivateKey = privateKey
+ protocol.Reality.PublicKey = publicKey
+ }
+ if strings.TrimSpace(protocol.Reality.ShortID) == "" {
+ shortID, err := generateRealityShortID()
+ if err != nil {
+ return err
+ }
+ protocol.Reality.ShortID = shortID
+ }
+ return nil
+}
+
+func generateRealityKeyPair() (privateKey string, publicKey string, err error) {
+ privateKeyPair, err := wgtypes.GeneratePrivateKey()
+ if err != nil {
+ return "", "", err
+ }
+ publicKeyPair := privateKeyPair.PublicKey()
+ return base64.RawURLEncoding.EncodeToString(privateKeyPair[:]), base64.RawURLEncoding.EncodeToString(publicKeyPair[:]), nil
+}
+
+func generateRealityShortID() (string, error) {
+ var raw [8]byte
+ if _, err := rand.Read(raw[:]); err != nil {
+ return "", fmt.Errorf("generate reality short id: %w", err)
+ }
+ return hex.EncodeToString(raw[:]), nil
+}