Prechádzať zdrojové kódy

feat(vpn): integrate PPP profile resolution into L2TP and PPTP client configs and bump cache buster

Proxmox Router 1 týždeň pred
rodič
commit
32b4494502

+ 44 - 3
internal/vpn/l2tp.go

@@ -23,6 +23,7 @@ const (
 type L2TPManager struct {
 	mu        sync.Mutex
 	instances []L2TPInstance
+	pppServer *PPPServerManager
 }
 
 func NewL2TPManager() *L2TPManager {
@@ -33,6 +34,10 @@ func NewL2TPManager() *L2TPManager {
 	return m
 }
 
+func (m *L2TPManager) SetPPPServer(ps *PPPServerManager) {
+	m.pppServer = ps
+}
+
 func (m *L2TPManager) load() {
 	data, err := os.ReadFile(L2TPInstancesStorePath)
 	if err == nil {
@@ -168,6 +173,11 @@ func (m *L2TPManager) regenerateXl2tpdConf() error {
 		if prof == "" {
 			prof = "default-encryption"
 		}
+		var profObj *PPPProfile
+		if m.pppServer != nil {
+			profObj = m.pppServer.GetProfile(prof)
+		}
+
 		optFile := fmt.Sprintf("/etc/ppp/options.l2tpd.%s", inst.Name)
 		sb.WriteString(fmt.Sprintf("[lac %s]\n", inst.Name))
 		sb.WriteString(fmt.Sprintf("lns = %s\n", inst.ConnectTo))
@@ -185,11 +195,42 @@ func (m *L2TPManager) regenerateXl2tpdConf() error {
 		optSb.WriteString("ipcp-accept-remote\n")
 		optSb.WriteString("refuse-eap\n")
 		optSb.WriteString("require-mschap-v2\n")
-		if strings.EqualFold(prof, "default") {
-			optSb.WriteString("nomppe\n")
+
+		if profObj != nil {
+			switch strings.ToLower(profObj.UseEncryption) {
+			case "no":
+				optSb.WriteString("nomppe\n")
+			case "yes":
+				optSb.WriteString("mppe-128\n")
+			default:
+				optSb.WriteString("require-mppe-128\n")
+			}
+			if profObj.DNSServers != "" {
+				for _, dns := range strings.Split(profObj.DNSServers, ",") {
+					dns = strings.TrimSpace(dns)
+					if dns != "" {
+						optSb.WriteString(fmt.Sprintf("ms-dns %s\n", dns))
+					}
+				}
+			}
+			if profObj.LocalAddress != "" && profObj.RemoteAddress != "" {
+				local := strings.TrimSpace(profObj.LocalAddress)
+				remote := strings.TrimSpace(profObj.RemoteAddress)
+				if strings.Contains(remote, "-") {
+					remote = strings.TrimSpace(strings.Split(remote, "-")[0])
+				}
+				if local != "" && remote != "" {
+					optSb.WriteString(fmt.Sprintf("%s:%s\n", local, remote))
+				}
+			}
 		} else {
-			optSb.WriteString("require-mppe-128\n")
+			if strings.EqualFold(prof, "default") {
+				optSb.WriteString("nomppe\n")
+			} else {
+				optSb.WriteString("require-mppe-128\n")
+			}
 		}
+
 		optSb.WriteString("noccp\n")
 		optSb.WriteString("noauth\n")
 		optSb.WriteString("mtu 1410\n")

+ 9 - 3
internal/vpn/manager.go

@@ -11,14 +11,20 @@ type Manager struct {
 }
 
 func NewManager() *Manager {
+	pppServer := NewPPPServerManager()
+	l2tpMgr := NewL2TPManager()
+	l2tpMgr.SetPPPServer(pppServer)
+	pptpMgr := NewPPTPManager()
+	pptpMgr.SetPPPServer(pppServer)
+
 	return &Manager{
 		PPPoE:     NewPPPoEManager(),
 		WireGuard: NewWireGuardManager(),
-		PPTP:      NewPPTPManager(),
-		L2TP:      NewL2TPManager(),
+		PPTP:      pptpMgr,
+		L2TP:      l2tpMgr,
 		IPSec:     NewIPSecManager(),
 		EoIP:      NewEoIPManager(),
-		PPPServer: NewPPPServerManager(),
+		PPPServer: pppServer,
 	}
 }
 

+ 6 - 0
internal/vpn/ppp_server.go

@@ -247,6 +247,12 @@ func (m *PPPServerManager) ListProfiles() []*PPPProfile {
 	return list
 }
 
+func (m *PPPServerManager) GetProfile(name string) *PPPProfile {
+	m.mu.RLock()
+	defer m.mu.RUnlock()
+	return m.profiles[name]
+}
+
 func (m *PPPServerManager) SaveProfile(p *PPPProfile) error {
 	m.mu.Lock()
 	defer m.mu.Unlock()

+ 42 - 3
internal/vpn/pptp.go

@@ -21,6 +21,7 @@ const (
 type PPTPManager struct {
 	mu        sync.Mutex
 	instances []PPTPInstance
+	pppServer *PPPServerManager
 }
 
 func NewPPTPManager() *PPTPManager {
@@ -31,6 +32,10 @@ func NewPPTPManager() *PPTPManager {
 	return m
 }
 
+func (m *PPTPManager) SetPPPServer(ps *PPPServerManager) {
+	m.pppServer = ps
+}
+
 func (m *PPTPManager) load() {
 	data, err := os.ReadFile(PPTPInstancesStorePath)
 	if err == nil {
@@ -176,16 +181,50 @@ func (m *PPTPManager) generatePeerConfig(inst PPTPInstance) error {
 	if prof == "" {
 		prof = "default-encryption"
 	}
+	var profObj *PPPProfile
+	if m.pppServer != nil {
+		profObj = m.pppServer.GetProfile(prof)
+	}
 
 	var sb strings.Builder
 	sb.WriteString(fmt.Sprintf("# MikroTik-Style PPTP Client: %s (Profile: %s)\n", inst.Name, prof))
 	sb.WriteString(fmt.Sprintf("pty \"pptp %s --nolaunchpppd\"\n", inst.ConnectTo))
 	sb.WriteString(fmt.Sprintf("name %q\n", inst.Username))
 	sb.WriteString("remotename PPTP\n")
-	if strings.EqualFold(prof, "default") && !inst.RequireMPPE {
-		sb.WriteString("nomppe\n")
+
+	if profObj != nil {
+		switch strings.ToLower(profObj.UseEncryption) {
+		case "no":
+			sb.WriteString("nomppe\n")
+		case "yes":
+			sb.WriteString("mppe-128\n")
+		default:
+			sb.WriteString("require-mppe-128\n")
+		}
+		if profObj.DNSServers != "" {
+			for _, dns := range strings.Split(profObj.DNSServers, ",") {
+				dns = strings.TrimSpace(dns)
+				if dns != "" {
+					sb.WriteString(fmt.Sprintf("ms-dns %s\n", dns))
+				}
+			}
+		}
+		if profObj.LocalAddress != "" && profObj.RemoteAddress != "" {
+			local := strings.TrimSpace(profObj.LocalAddress)
+			remote := strings.TrimSpace(profObj.RemoteAddress)
+			if strings.Contains(remote, "-") {
+				remote = strings.TrimSpace(strings.Split(remote, "-")[0])
+			}
+			if local != "" && remote != "" {
+				sb.WriteString(fmt.Sprintf("%s:%s\n", local, remote))
+			}
+		}
 	} else {
-		sb.WriteString("require-mppe-128\n")
+		if strings.EqualFold(prof, "default") && !inst.RequireMPPE {
+			sb.WriteString("nomppe\n")
+		} else {
+			sb.WriteString("require-mppe-128\n")
+		}
 	}
 	if inst.DefaultRoute {
 		sb.WriteString("defaultroute\n")

+ 16 - 4
internal/web/static/app.js

@@ -2326,7 +2326,10 @@ async function loadL2TP(populateInputs = true) {
   }
 }
 
-function openAddL2TPModal() {
+async function openAddL2TPModal() {
+  if (!state.pppProfiles || state.pppProfiles.length === 0) {
+    await fetchPPPProfilesList();
+  }
   document.getElementById('l2tp-modal-title').innerText = 'Add L2TP Client Interface';
   document.getElementById('l2tp-modal-name').value = `l2tp-out${(state.l2tpList || []).length + 1}`;
   document.getElementById('l2tp-modal-name').readOnly = false;
@@ -2342,7 +2345,10 @@ function openAddL2TPModal() {
   document.getElementById('l2tp-modal').classList.remove('hidden');
 }
 
-function openEditL2TPModal(name) {
+async function openEditL2TPModal(name) {
+  if (!state.pppProfiles || state.pppProfiles.length === 0) {
+    await fetchPPPProfilesList();
+  }
   const inst = (state.l2tpList || []).find(i => i.name === name);
   if (!inst) return;
 
@@ -2515,7 +2521,10 @@ async function loadPPTP(populateInputs = true) {
   }
 }
 
-function openAddPPTPModal() {
+async function openAddPPTPModal() {
+  if (!state.pppProfiles || state.pppProfiles.length === 0) {
+    await fetchPPPProfilesList();
+  }
   document.getElementById('pptp-modal-title').innerText = 'Add PPTP Client Interface';
   document.getElementById('pptp-modal-name').value = `pptp-out${(state.pptpList || []).length + 1}`;
   document.getElementById('pptp-modal-name').readOnly = false;
@@ -2531,7 +2540,10 @@ function openAddPPTPModal() {
   document.getElementById('pptp-modal').classList.remove('hidden');
 }
 
-function openEditPPTPModal(name) {
+async function openEditPPTPModal(name) {
+  if (!state.pppProfiles || state.pppProfiles.length === 0) {
+    await fetchPPPProfilesList();
+  }
   const inst = (state.pptpList || []).find(i => i.name === name);
   if (!inst) return;
 

+ 1 - 1
internal/web/static/index.html

@@ -9357,6 +9357,6 @@
   </div>
 
   <datalist id="fw-addrlist-datalist"></datalist>
-  <script src="app.js?v=5.5"></script>
+  <script src="app.js?v=7.1"></script>
 </body>
 </html>