[feature] fallback link calculation

Co-Authored-By: Alireza Ahmadi <alireza7@gmail.com>
This commit is contained in:
MHSanaei 2023-05-23 03:15:34 +03:30
parent c38e1e0cfe
commit 47ccc7b501
4 changed files with 57 additions and 10 deletions

View file

@ -38,6 +38,21 @@ func (s *SubService) GetSubs(subId string, host string) ([]string, []string, err
if clients == nil { if clients == nil {
continue continue
} }
if len(inbound.Listen) > 0 && inbound.Listen[0] == '@' {
fallbackMaster, err := s.getFallbackMaster(inbound.Listen)
if err == nil {
inbound.Listen = fallbackMaster.Listen
inbound.Port = fallbackMaster.Port
var stream map[string]interface{}
json.Unmarshal([]byte(inbound.StreamSettings), &stream)
var masterStream map[string]interface{}
json.Unmarshal([]byte(fallbackMaster.StreamSettings), &masterStream)
stream["security"] = masterStream["security"]
stream["tlsSettings"] = masterStream["tlsSettings"]
modifiedStream, _ := json.MarshalIndent(stream, "", " ")
inbound.StreamSettings = string(modifiedStream)
}
}
for _, client := range clients { for _, client := range clients {
if client.Enable && client.SubID == subId { if client.Enable && client.SubID == subId {
link := s.getLink(inbound, client.Email) link := s.getLink(inbound, client.Email)
@ -93,6 +108,19 @@ func (s *SubService) getClientTraffics(traffics []xray.ClientTraffic, email stri
return xray.ClientTraffic{} return xray.ClientTraffic{}
} }
func (s *SubService) getFallbackMaster(dest string) (*model.Inbound, error) {
db := database.GetDB()
var inbound *model.Inbound
err := db.Model(model.Inbound{}).
Where("JSON_TYPE(settings, '$.fallbacks') = 'array'").
Where("EXISTS (SELECT * FROM json_each(settings, '$.fallbacks') WHERE json_extract(value, '$.dest') = ?)", dest).
Find(&inbound).Error
if err != nil {
return nil, err
}
return inbound, nil
}
func (s *SubService) getLink(inbound *model.Inbound, email string) string { func (s *SubService) getLink(inbound *model.Inbound, email string) string {
switch inbound.Protocol { switch inbound.Protocol {
case "vmess": case "vmess":

View file

@ -39,6 +39,7 @@
this.client = settings.clients[clientIndex]; this.client = settings.clients[clientIndex];
remark = this.dbInbound.remark + "-" + this.client.email; remark = this.dbInbound.remark + "-" + this.client.email;
address = this.dbInbound.address; address = this.dbInbound.address;
this.subId = '';
this.qrcodes = []; this.qrcodes = [];
if (this.inbound.tls && !ObjectUtil.isArrEmpty(this.inbound.stream.tls.settings.domains)) { if (this.inbound.tls && !ObjectUtil.isArrEmpty(this.inbound.stream.tls.settings.domains)) {
this.inbound.stream.tls.settings.domains.forEach((domain) => { this.inbound.stream.tls.settings.domains.forEach((domain) => {

View file

@ -361,6 +361,7 @@
this.refreshing = true; this.refreshing = true;
const msg = await HttpUtil.post('/panel/inbound/list'); const msg = await HttpUtil.post('/panel/inbound/list');
if (!msg.success) { if (!msg.success) {
this.refreshing = false;
return; return;
} }
this.setInbounds(msg.obj); this.setInbounds(msg.obj);
@ -763,11 +764,32 @@
default: return client.id; default: return client.id;
} }
}, },
checkFallback(dbInbound) {
newDbInbound = new DBInbound(dbInbound);
if (dbInbound.listen.startsWith("@")){
rootInbound = this.inbounds.find((i) =>
i.tls &&
['trojan','vless'].includes(i.protocol) &&
i.settings.fallbacks.find(f => f.dest === dbInbound.listen)
);
if (rootInbound) {
newDbInbound.listen = rootInbound.listen;
newDbInbound.port = rootInbound.port;
newInbound = newDbInbound.toInbound();
newInbound.stream.security = 'tls';
newInbound.stream.tls = rootInbound.stream.tls;
newDbInbound.streamSettings = newInbound.stream.toString();
}
}
return newDbInbound;
},
showQrcode(dbInbound, clientIndex) { showQrcode(dbInbound, clientIndex) {
qrModal.show('{{ i18n "qrCode"}}', dbInbound, clientIndex); newDbInbound = this.checkFallback(dbInbound);
qrModal.show('{{ i18n "qrCode"}}', newDbInbound, clientIndex);
}, },
showInfo(dbInbound, index) { showInfo(dbInbound, index) {
infoModal.show(dbInbound, index); newDbInbound = this.checkFallback(dbInbound);
infoModal.show(newDbInbound, index);
}, },
switchEnable(dbInboundId) { switchEnable(dbInboundId) {
dbInbound = this.dbInbounds.find(row => row.id === dbInboundId); dbInbound = this.dbInbounds.find(row => row.id === dbInboundId);
@ -868,7 +890,8 @@
}, },
inboundLinks(dbInboundId) { inboundLinks(dbInboundId) {
dbInbound = this.dbInbounds.find(row => row.id === dbInboundId); dbInbound = this.dbInbounds.find(row => row.id === dbInboundId);
txtModal.show('{{ i18n "pages.inbounds.export"}}', dbInbound.genInboundLinks, dbInbound.remark); newDbInbound = this.checkFallback(dbInbound);
txtModal.show('{{ i18n "pages.inbounds.export"}}', newDbInbound.genInboundLinks, newDbInbound.remark);
}, },
exportAllLinks() { exportAllLinks() {
let copyText = ''; let copyText = '';

View file

@ -528,6 +528,7 @@ ssl_cert_issue_main() {
local domain="" local domain=""
read -p "Please enter your domain name to revoke the certificate: " domain read -p "Please enter your domain name to revoke the certificate: " domain
~/.acme.sh/acme.sh --revoke -d ${domain} ~/.acme.sh/acme.sh --revoke -d ${domain}
LOGI "Certificate revoked"
;; ;;
3) 3)
local domain="" local domain=""
@ -571,13 +572,7 @@ ssl_cert_issue() {
local certInfo=$(~/.acme.sh/acme.sh --list) local certInfo=$(~/.acme.sh/acme.sh --list)
LOGE "system already has certs here,can not issue again,current certs details:" LOGE "system already has certs here,can not issue again,current certs details:"
LOGI "$certInfo" LOGI "$certInfo"
read -p "Do you want to revoke the existing certificate? (yes/no): " choice exit 1
if [ "$choice" == "yes" ]; then
~/.acme.sh/acme.sh --revoke -d ${domain}
LOGI "Certificate revoked"
else
exit 1
fi
else else
LOGI "your domain is ready for issuing cert now..." LOGI "your domain is ready for issuing cert now..."
fi fi