소스 검색

[wg] auto multi-peer and qrcode

Co-Authored-By: Alireza Ahmadi <[email protected]>
MHSanaei 1 년 전
부모
커밋
61489077d7

+ 38 - 2
web/assets/js/model/xray.js

@@ -1534,6 +1534,28 @@ class Inbound extends XrayCommonClass {
         return url.toString();
     }
 
+    getWireguardLink(address, port, remark, peerId) {
+        let txt = `[Interface]\n`
+        txt += `PrivateKey = ${this.settings.peers[peerId].privateKey}\n`
+        txt += `Address = ${this.settings.peers[peerId].allowedIPs[0]}\n`
+        txt += `DNS = 1.1.1.1, 1.0.0.1\n`
+        if (this.settings.mtu) {
+            txt += `MTU = ${this.settings.mtu}\n`
+        }
+        txt += `\n# ${remark}\n`
+        txt += `[Peer]\n`
+        txt += `PublicKey = ${this.settings.pubKey}\n`
+        txt += `AllowedIPs = 0.0.0.0/0, ::/0\n`
+        txt += `Endpoint = ${address}:${port}`
+        if (this.settings.peers[peerId].psk) {
+            txt += `\nPresharedKey = ${this.settings.peers[peerId].psk}`
+        }
+        if (this.settings.peers[peerId].keepAlive) {
+            txt += `\nPersistentKeepalive = ${this.settings.peers[peerId].keepAlive}\n`
+        }
+        return txt;
+    }
+
     genLink(address='', port=this.port, forceTls='same', remark='', client) {
         switch (this.protocol) {
             case Protocols.VMESS:
@@ -1580,6 +1602,7 @@ class Inbound extends XrayCommonClass {
     }
 
     genInboundLinks(remark = '', remarkModel = '-ieo') {
+        let addr = !ObjectUtil.isEmpty(this.listen) && this.listen !== "0.0.0.0" ? this.listen : location.hostname;
         if(this.clients){
            let links = [];
            this.clients.forEach((client) => {
@@ -1589,7 +1612,14 @@ class Inbound extends XrayCommonClass {
             });
             return links.join('\r\n');
         } else {
-            if(this.protocol == Protocols.SHADOWSOCKS && !this.isSSMultiUser) return this.genSSLink(this.listen, this.port, 'same', remark);
+            if(this.protocol == Protocols.SHADOWSOCKS && !this.isSSMultiUser) return this.genSSLink(addr, this.port, 'same', remark);
+            if(this.protocol == Protocols.WIREGUARD) {
+                let links = [];
+                this.settings.peers.forEach((p,index) => {
+                    links.push(this.getWireguardLink(addr,this.port,remark + remarkModel.charAt(0) + (index+1),index));
+                });
+                return links.join('\r\n');
+            }
             return '';
         }
     }
@@ -2297,9 +2327,13 @@ Inbound.WireguardSettings = class extends XrayCommonClass {
 };
 
 Inbound.WireguardSettings.Peer = class extends XrayCommonClass {
-    constructor(publicKey=Wireguard.generateKeypair().publicKey, psk='', allowedIPs=['0.0.0.0/0','::/0'], keepAlive=0) {
+    constructor(privateKey, publicKey, psk='', allowedIPs=['10.0.0.0/24'], keepAlive=0) {
         super();
+        this.privateKey = privateKey
         this.publicKey = publicKey;
+        if (!this.publicKey){
+            [this.publicKey, this.privateKey] = Object.values(Wireguard.generateKeypair())
+        }
         this.psk = psk;
         this.allowedIPs = allowedIPs;
         this.keepAlive = keepAlive;
@@ -2307,6 +2341,7 @@ Inbound.WireguardSettings.Peer = class extends XrayCommonClass {
 
     static fromJson(json={}){
         return new Inbound.WireguardSettings.Peer(
+            json.privateKey,
             json.publicKey,
             json.preSharedKey,
             json.allowedIPs,
@@ -2316,6 +2351,7 @@ Inbound.WireguardSettings.Peer = class extends XrayCommonClass {
 
     toJson() {
         return {
+            privateKey: this.privateKey,            
             publicKey: this.publicKey,
             preSharedKey: this.psk.length>0 ? this.psk : undefined,
             allowedIPs: this.allowedIPs,

+ 14 - 5
web/html/common/qrcode_modal.html

@@ -35,12 +35,21 @@
             this.client = client;
             this.subId = '';
             this.qrcodes = [];
-            this.inbound.genAllLinks(this.dbInbound.remark, app.remarkModel, client).forEach(l => {
-                this.qrcodes.push({
-                    remark: l.remark,
-                    link: l.link
+            if (this.inbound.protocol == Protocols.WIREGUARD){
+                this.inbound.genInboundLinks(dbInbound.remark).split('\r\n').forEach((l,index) =>{
+                    this.qrcodes.push({
+                        remark: "Peer " + (index+1),
+                        link: l
+                    });
                 });
-            });
+            } else {
+                this.inbound.genAllLinks(this.dbInbound.remark, app.remarkModel, client).forEach(l => {
+                    this.qrcodes.push({
+                        remark: l.remark,
+                        link: l.link
+                    });
+                });
+            }
             this.visible = true;
         },
         close: function () {

+ 9 - 26
web/html/xui/form/outbound.html

@@ -134,28 +134,10 @@
         <a-form-item label='{{ i18n "pages.xray.wireguard.endpoint" }}'>
             <a-input v-model.trim="peer.endpoint"></a-input>
         </a-form-item>
-        <a-form-item>
-            <template slot="label">
-                <a-tooltip>
-                    <template slot="title">
-                        <span>{{ i18n "reset" }}</span>
-                    </template>
-                    {{ i18n "pages.xray.wireguard.publicKey" }}
-                    <a-icon @click="peer.publicKey = publicKey=Wireguard.generateKeypair().publicKey"type="sync"> </a-icon>
-                </a-tooltip>
-            </template>
+        <a-form-item label='{{ i18n "pages.xray.wireguard.publicKey" }}'>
             <a-input v-model.trim="peer.publicKey"></a-input>
         </a-form-item>
-        <a-form-item>
-            <template slot="label">
-                <a-tooltip>
-                    <template slot="title">
-                        <span>{{ i18n "reset" }}</span>
-                    </template>
-                    {{ i18n "pages.xray.wireguard.psk" }}
-                    <a-icon @click="peer.psk = publicKey=Wireguard.generateKeypair().publicKey"type="sync"> </a-icon>
-                </a-tooltip>
-            </template>
+        <a-form-item label='{{ i18n "pages.xray.wireguard.psk" }}'>
             <a-input v-model.trim="peer.psk"></a-input>
         </a-form-item>
         <a-form-item>
@@ -189,7 +171,6 @@
         <a-form-item label='ID'>
             <a-input v-model.trim="outbound.settings.id"></a-input>
         </a-form-item>
-
  <!-- vless settings -->
  <template v-if="outbound.canEnableTlsFlow()">
         <a-form-item label='Flow'>
@@ -212,9 +193,8 @@
             <a-input v-model.trim="outbound.settings.pass"></a-input>
         </a-form-item>
     </template>
-
 <!-- trojan/shadowsocks -->
-    <template v-if="[Protocols.Trojan, Protocols.Shadowsocks].includes(outbound.protocol)">
+<template v-if="[Protocols.Trojan, Protocols.Shadowsocks].includes(outbound.protocol)">
         <a-form-item label='{{ i18n "password" }}'>
         <a-input v-model.trim="outbound.settings.password"></a-input>
         </a-form-item>
@@ -369,13 +349,15 @@
             <a-input v-model.trim="outbound.stream.tls.serverName"></a-input>
         </a-form-item>
         <a-form-item label="uTLS">
-            <a-select v-model="outbound.stream.tls.fingerprint" :dropdown-class-name="themeSwitcher.currentTheme">
+            <a-select v-model="outbound.stream.tls.fingerprint" 
+            :dropdown-class-name="themeSwitcher.currentTheme">
                 <a-select-option value=''>None</a-select-option>
                 <a-select-option v-for="key in UTLS_FINGERPRINT" :value="key">[[ key ]]</a-select-option>
             </a-select>
         </a-form-item>
         <a-form-item label="ALPN">
-            <a-select mode="multiple" :dropdown-class-name="themeSwitcher.currentTheme"
+            <a-select mode="multiple" 
+            :dropdown-class-name="themeSwitcher.currentTheme"
                 v-model="outbound.stream.tls.alpn">
                 <a-select-option v-for="alpn in ALPN_OPTION" :value="alpn">[[ alpn ]]</a-select-option>
             </a-select>
@@ -391,7 +373,8 @@
             <a-input v-model.trim="outbound.stream.reality.serverName"></a-input>
         </a-form-item>
         <a-form-item label="uTLS">
-            <a-select v-model="outbound.stream.reality.fingerprint" :dropdown-class-name="themeSwitcher.currentTheme">
+            <a-select v-model="outbound.stream.reality.fingerprint" 
+            :dropdown-class-name="themeSwitcher.currentTheme">
                 <a-select-option v-for="key in UTLS_FINGERPRINT" :value="key">[[ key ]]</a-select-option>
             </a-select>
         </a-form-item>

+ 9 - 3
web/html/xui/form/protocol/wireguard.html

@@ -38,10 +38,16 @@
                     <template slot="title">
                         <span>{{ i18n "reset" }}</span>
                     </template>
-                    {{ i18n "pages.xray.wireguard.publicKey" }}
-                    <a-icon @click="peer.publicKey = publicKey=Wireguard.generateKeypair().publicKey"type="sync"> </a-icon>
+                    {{ i18n "pages.xray.wireguard.secretKey" }}
+                    <a-icon @click="[peer.publicKey, peer.privateKey] = Object.values(Wireguard.generateKeypair())"type="sync"> </a-icon>
                 </a-tooltip>
             </template>
+            <a-input v-model.trim="peer.privateKey"></a-input>
+        </a-form-item>
+        <a-form-item>
+            <template slot="label">
+                {{ i18n "pages.xray.wireguard.publicKey" }}
+            </template>
             <a-input v-model.trim="peer.publicKey"></a-input>
         </a-form-item>
         <a-form-item>
@@ -51,7 +57,7 @@
                         <span>{{ i18n "reset" }}</span>
                     </template>
                     {{ i18n "pages.xray.wireguard.psk" }}
-                    <a-icon @click="peer.psk = publicKey=Wireguard.generateKeypair().publicKey"type="sync"> </a-icon>
+                    <a-icon @click="peer.psk = Wireguard.keyToBase64(Wireguard.generatePresharedKey())"type="sync"> </a-icon>
                 </a-tooltip>
             </template>
             <a-input v-model.trim="peer.psk"></a-input>

+ 37 - 11
web/html/xui/inbound_info_modal.html

@@ -179,10 +179,10 @@
         <template v-if="app.tgBotEnable && infoModal.clientSettings.tgId">
             <a-divider>Telegram ID</a-divider>
             <a-row>
-                <a-col :sx="24" :md="22"><a :href="[[ infoModal.tgLink ]]" target="_blank">@[[ infoModal.clientSettings.tgId ]]</a></a-col>
+                <a-col :sx="24" :md="22">[[ infoModal.clientSettings.tgId ]]</a-col>
                 <a-col :sx="24" :md="2" style="text-align: right;">
                     <a-tooltip title='{{ i18n "copy" }}'>
-                        <button class="ant-btn ant-btn-primary" id="copy-tg-link" @click="copyToClipboard('copy-tg-link', '@' + infoModal.clientSettings.tgId)">
+                        <button class="ant-btn ant-btn-primary" id="copy-tg-link" @click="copyToClipboard('copy-tg-link', infoModal.clientSettings.tgId)">
                             <a-icon type="snippets"></a-icon>
                         </button>
                     </a-tooltip>
@@ -283,24 +283,50 @@
             </tr>
         <template v-for="(peer, index) in inbound.settings.peers">
             <tr>
-                <td colspan="2"><a-tag>Peer [[ index + 1 ]]</a-tag></td>
+                <td colspan="2"><a-divider>Peer [[ index + 1 ]]</a-divider></td>
             </tr>
             <tr class="client-table-odd-row">
+                <td>{{ i18n "pages.xray.wireguard.secretKey" }}</td>
+                <td>[[ peer.privateKey ]]</td>
+            </tr>
+            <tr>
                 <td>{{ i18n "pages.xray.wireguard.publicKey" }}</td>
                 <td>[[ peer.publicKey ]]</td>
             </tr>
-            <tr>
+            <tr class="client-table-odd-row">
                 <td>{{ i18n "pages.xray.wireguard.psk" }}</td>
                 <td>[[ peer.psk ]]</td>
             </tr>
-            <tr class="client-table-odd-row">
+            <tr>
                 <td>{{ i18n "pages.xray.wireguard.allowedIPs" }}</td>
                 <td>[[ peer.allowedIPs.join(",") ]]</td>
             </tr>
-            <tr>
+            <tr class="client-table-odd-row">
                 <td>Keep Alive</td>
                 <td>[[ peer.keepAlive ]]</td>
             </tr>
+            <tr>
+                <td colspan="2">
+                    <a-row>
+                        <a-col :span="22" style="overflow-wrap: anywhere;">
+                            <a-tag color="blue">Config</a-tag>
+                            <div 
+                            v-html="infoModal.links[index].replaceAll(`\n`,`<br />`)"
+                            style="border-radius: 1rem; padding: 0.5rem;"
+                            class="client-table-odd-row"></div>
+                        </a-col>
+                        <a-col :span="2" style="text-align: right;">
+                            <a-tooltip title='{{ i18n "copy" }}'>
+                                <button class="ant-btn ant-btn-primary"
+                                    :id="'copy-url-link-'+index"
+                                    @click="copyToClipboard('copy-url-link-'+index, infoModal.links[index])">
+                                    <a-icon type="snippets"></a-icon>
+                                </button>
+                            </a-tooltip>
+                        </a-col>
+                    </a-row>
+                </td>
+            </tr>
         </table>
         </template>
     </template>
@@ -319,7 +345,6 @@
         index: null,
         isExpired: false,
         subLink: '',
-        tgLink: '',
         show(dbInbound, index) {
             this.index = index;
             this.inbound = dbInbound.toInbound();
@@ -327,14 +352,15 @@
             this.clientSettings = this.inbound.clients ? this.inbound.clients[index] : null;
             this.isExpired = this.inbound.clients ? this.inbound.isExpiry(index): this.dbInbound.isExpiry;
             this.clientStats = this.inbound.clients ? this.dbInbound.clientStats.find(row => row.email === this.clientSettings.email) : [];
-            this.links = this.inbound.genAllLinks(this.dbInbound.remark, app.remarkModel, this.clientSettings);
+            if (this.inbound.protocol == Protocols.WIREGUARD){
+                this.links = this.inbound.genInboundLinks(dbInbound.remark).split('\r\n')
+            } else {
+                this.links = this.inbound.genAllLinks(this.dbInbound.remark, app.remarkModel, this.clientSettings);
+            }
             if (this.clientSettings) {
                 if (this.clientSettings.subId) {
                     this.subLink = this.genSubLink(this.clientSettings.subId);
                 }
-                if (this.clientSettings.tgId) {
-                    this.tgLink = "https://t.me/" + this.clientSettings.tgId;
-                }
             }
             this.visible = true;
         },

+ 1 - 1
web/html/xui/inbounds.html

@@ -200,7 +200,7 @@
                                             <a-icon type="edit"></a-icon>
                                             {{ i18n "edit" }}
                                         </a-menu-item>
-                                        <a-menu-item key="qrcode" v-if="dbInbound.isSS && !dbInbound.toInbound().isSSMultiUser">
+                                        <a-menu-item key="qrcode" v-if="(dbInbound.isSS && !dbInbound.toInbound().isSSMultiUser) || dbInbound.isWireguard">
                                             <a-icon type="qrcode"></a-icon>
                                             {{ i18n "qrCode" }}
                                         </a-menu-item>