mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2025-05-03 05:38:49 +00:00
Merge branch 'MHSanaei:main' into main
This commit is contained in:
commit
cc9f6639a1
15 changed files with 761 additions and 60 deletions
|
@ -477,7 +477,7 @@ Ingresa el ID de chat de usuario en el campo de entrada número 4. Las cuentas d
|
||||||
|
|
||||||
#### Uso
|
#### Uso
|
||||||
|
|
||||||
- [Documentación de API](https://documenter.getpostman.com/view/5146551/2sAXxP8Y12)
|
- [Documentación de API](https://www.postman.com/hsanaei/3x-ui/collection/q1l5l0u/3x-ui)
|
||||||
- `/login` con `POST` datos de usuario: `{username: '', password: ''}` para iniciar sesión
|
- `/login` con `POST` datos de usuario: `{username: '', password: ''}` para iniciar sesión
|
||||||
- `/panel/api/inbounds` base para las siguientes acciones:
|
- `/panel/api/inbounds` base para las siguientes acciones:
|
||||||
|
|
||||||
|
@ -507,7 +507,7 @@ Ingresa el ID de chat de usuario en el campo de entrada número 4. Las cuentas d
|
||||||
- `client.password` para TROJAN
|
- `client.password` para TROJAN
|
||||||
- `client.email` para Shadowsocks
|
- `client.email` para Shadowsocks
|
||||||
|
|
||||||
- [<img src="https://run.pstmn.io/button.svg" alt="Run In Postman" style="width: 128px; height: 32px;">](https://god.gw.postman.com/run-collection/5146551-e6aac565-e0e2-46df-acff-2607a51bbd04?action=collection%2Ffork&source=rip_markdown&collection-url=entityId%3D5146551-e6aac565-e0e2-46df-acff-2607a51bbd04%26entityType%3Dcollection%26workspaceId%3Dd64f609f-485a-4951-9b8f-876b3f917124)
|
- [<img src="https://run.pstmn.io/button.svg" alt="Run In Postman" style="width: 128px; height: 32px;">](https://app.getpostman.com/run-collection/5146551-dda3cab3-0e33-485f-96f9-d4262f437ac5?action=collection%2Ffork&source=rip_markdown&collection-url=entityId%3D5146551-dda3cab3-0e33-485f-96f9-d4262f437ac5%26entityType%3Dcollection%26workspaceId%3Dd64f609f-485a-4951-9b8f-876b3f917124)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## Variables de Entorno
|
## Variables de Entorno
|
||||||
|
|
|
@ -476,7 +476,7 @@ Enter the user ID in input field number 4. The Telegram accounts with this id wi
|
||||||
|
|
||||||
#### Usage
|
#### Usage
|
||||||
|
|
||||||
- [API Documentation](https://documenter.getpostman.com/view/5146551/2sAXxP8Y12)
|
- [API Documentation](https://www.postman.com/hsanaei/3x-ui/collection/q1l5l0u/3x-ui)
|
||||||
- `/login` with `POST` user data: `{username: '', password: ''}` for login
|
- `/login` with `POST` user data: `{username: '', password: ''}` for login
|
||||||
- `/panel/api/inbounds` base for following actions:
|
- `/panel/api/inbounds` base for following actions:
|
||||||
|
|
||||||
|
@ -507,7 +507,7 @@ Enter the user ID in input field number 4. The Telegram accounts with this id wi
|
||||||
- `client.password` for TROJAN
|
- `client.password` for TROJAN
|
||||||
- `client.email` for Shadowsocks
|
- `client.email` for Shadowsocks
|
||||||
|
|
||||||
- [<img src="https://run.pstmn.io/button.svg" alt="Run In Postman" style="width: 128px; height: 32px;">](https://god.gw.postman.com/run-collection/5146551-e6aac565-e0e2-46df-acff-2607a51bbd04?action=collection%2Ffork&source=rip_markdown&collection-url=entityId%3D5146551-e6aac565-e0e2-46df-acff-2607a51bbd04%26entityType%3Dcollection%26workspaceId%3Dd64f609f-485a-4951-9b8f-876b3f917124)
|
- [<img src="https://run.pstmn.io/button.svg" alt="Run In Postman" style="width: 128px; height: 32px;">](https://app.getpostman.com/run-collection/5146551-dda3cab3-0e33-485f-96f9-d4262f437ac5?action=collection%2Ffork&source=rip_markdown&collection-url=entityId%3D5146551-dda3cab3-0e33-485f-96f9-d4262f437ac5%26entityType%3Dcollection%26workspaceId%3Dd64f609f-485a-4951-9b8f-876b3f917124)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## Environment Variables
|
## Environment Variables
|
||||||
|
|
|
@ -470,7 +470,7 @@ WARP встроен, и дополнительная установка не т
|
||||||
|
|
||||||
#### Использование
|
#### Использование
|
||||||
|
|
||||||
- [API документация](https://documenter.getpostman.com/view/5146551/2sAXxP8Y12)
|
- [API документация](https://www.postman.com/hsanaei/3x-ui/collection/q1l5l0u/3x-ui)
|
||||||
- `/login` с `POST`-данными: `{username: '', password: ''}` для входа
|
- `/login` с `POST`-данными: `{username: '', password: ''}` для входа
|
||||||
- `/panel/api/inbounds` это базовый путь для следующих действий:
|
- `/panel/api/inbounds` это базовый путь для следующих действий:
|
||||||
|
|
||||||
|
@ -504,7 +504,7 @@ WARP встроен, и дополнительная установка не т
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
|
||||||
- [<img src="https://run.pstmn.io/button.svg" alt="Run In Postman" style="width: 128px; height: 32px;">](https://god.gw.postman.com/run-collection/5146551-e6aac565-e0e2-46df-acff-2607a51bbd04?action=collection%2Ffork&source=rip_markdown&collection-url=entityId%3D5146551-e6aac565-e0e2-46df-acff-2607a51bbd04%26entityType%3Dcollection%26workspaceId%3Dd64f609f-485a-4951-9b8f-876b3f917124)
|
- [<img src="https://run.pstmn.io/button.svg" alt="Run In Postman" style="width: 128px; height: 32px;">](https://app.getpostman.com/run-collection/5146551-dda3cab3-0e33-485f-96f9-d4262f437ac5?action=collection%2Ffork&source=rip_markdown&collection-url=entityId%3D5146551-dda3cab3-0e33-485f-96f9-d4262f437ac5%26entityType%3Dcollection%26workspaceId%3Dd64f609f-485a-4951-9b8f-876b3f917124)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## Переменные среды
|
## Переменные среды
|
||||||
|
|
|
@ -465,7 +465,7 @@ Web 面板通过 Telegram Bot 支持每日流量、面板登录、数据库备
|
||||||
|
|
||||||
#### 使用
|
#### 使用
|
||||||
|
|
||||||
- [API 文档](https://documenter.getpostman.com/view/5146551/2sAXxP8Y12)
|
- [API 文档](https://www.postman.com/hsanaei/3x-ui/collection/q1l5l0u/3x-ui)
|
||||||
- `/login` 使用 `POST` 用户名称 & 密码: `{username: '', password: ''}` 登录
|
- `/login` 使用 `POST` 用户名称 & 密码: `{username: '', password: ''}` 登录
|
||||||
- `/panel/api/inbounds` 以下操作的基础:
|
- `/panel/api/inbounds` 以下操作的基础:
|
||||||
|
|
||||||
|
@ -495,7 +495,7 @@ Web 面板通过 Telegram Bot 支持每日流量、面板登录、数据库备
|
||||||
- `client.password` TROJAN
|
- `client.password` TROJAN
|
||||||
- `client.email` Shadowsocks
|
- `client.email` Shadowsocks
|
||||||
|
|
||||||
- [<img src="https://run.pstmn.io/button.svg" alt="Run In Postman" style="width: 128px; height: 32px;">](https://god.gw.postman.com/run-collection/5146551-e6aac565-e0e2-46df-acff-2607a51bbd04?action=collection%2Ffork&source=rip_markdown&collection-url=entityId%3D5146551-e6aac565-e0e2-46df-acff-2607a51bbd04%26entityType%3Dcollection%26workspaceId%3Dd64f609f-485a-4951-9b8f-876b3f917124)
|
- [<img src="https://run.pstmn.io/button.svg" alt="Run In Postman" style="width: 128px; height: 32px;">](https://app.getpostman.com/run-collection/5146551-dda3cab3-0e33-485f-96f9-d4262f437ac5?action=collection%2Ffork&source=rip_markdown&collection-url=entityId%3D5146551-dda3cab3-0e33-485f-96f9-d4262f437ac5%26entityType%3Dcollection%26workspaceId%3Dd64f609f-485a-4951-9b8f-876b3f917124)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## 环境变量
|
## 环境变量
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
2.4.6
|
2.4.7
|
|
@ -238,6 +238,7 @@ func (s *SubService) genVmessLink(inbound *model.Inbound, email string) string {
|
||||||
headers, _ := splithttp["headers"].(map[string]interface{})
|
headers, _ := splithttp["headers"].(map[string]interface{})
|
||||||
obj["host"] = searchHost(headers)
|
obj["host"] = searchHost(headers)
|
||||||
}
|
}
|
||||||
|
obj["mode"] = splithttp["mode"].(string)
|
||||||
}
|
}
|
||||||
security, _ := stream["security"].(string)
|
security, _ := stream["security"].(string)
|
||||||
obj["tls"] = security
|
obj["tls"] = security
|
||||||
|
@ -389,6 +390,7 @@ func (s *SubService) genVlessLink(inbound *model.Inbound, email string) string {
|
||||||
headers, _ := splithttp["headers"].(map[string]interface{})
|
headers, _ := splithttp["headers"].(map[string]interface{})
|
||||||
params["host"] = searchHost(headers)
|
params["host"] = searchHost(headers)
|
||||||
}
|
}
|
||||||
|
params["mode"] = splithttp["mode"].(string)
|
||||||
}
|
}
|
||||||
security, _ := stream["security"].(string)
|
security, _ := stream["security"].(string)
|
||||||
if security == "tls" {
|
if security == "tls" {
|
||||||
|
@ -586,6 +588,7 @@ func (s *SubService) genTrojanLink(inbound *model.Inbound, email string) string
|
||||||
headers, _ := splithttp["headers"].(map[string]interface{})
|
headers, _ := splithttp["headers"].(map[string]interface{})
|
||||||
params["host"] = searchHost(headers)
|
params["host"] = searchHost(headers)
|
||||||
}
|
}
|
||||||
|
params["mode"] = splithttp["mode"].(string)
|
||||||
}
|
}
|
||||||
security, _ := stream["security"].(string)
|
security, _ := stream["security"].(string)
|
||||||
if security == "tls" {
|
if security == "tls" {
|
||||||
|
@ -783,6 +786,7 @@ func (s *SubService) genShadowsocksLink(inbound *model.Inbound, email string) st
|
||||||
headers, _ := splithttp["headers"].(map[string]interface{})
|
headers, _ := splithttp["headers"].(map[string]interface{})
|
||||||
params["host"] = searchHost(headers)
|
params["host"] = searchHost(headers)
|
||||||
}
|
}
|
||||||
|
params["mode"] = splithttp["mode"].(string)
|
||||||
}
|
}
|
||||||
|
|
||||||
security, _ := stream["security"].(string)
|
security, _ := stream["security"].(string)
|
||||||
|
|
|
@ -19,6 +19,11 @@ const supportLangs = [
|
||||||
value: "zh-TW",
|
value: "zh-TW",
|
||||||
icon: "🇹🇼",
|
icon: "🇹🇼",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "日本語",
|
||||||
|
value: "ja-JP",
|
||||||
|
icon: "🇯🇵",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "Русский",
|
name: "Русский",
|
||||||
value: "ru-RU",
|
value: "ru-RU",
|
||||||
|
|
|
@ -113,6 +113,12 @@ const USERS_SECURITY = {
|
||||||
ZERO: "zero",
|
ZERO: "zero",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const MODE_OPTION = {
|
||||||
|
AUTO: "auto",
|
||||||
|
PACKET_UP: "packet-up",
|
||||||
|
STREAM_UP: "stream-up",
|
||||||
|
};
|
||||||
|
|
||||||
Object.freeze(Protocols);
|
Object.freeze(Protocols);
|
||||||
Object.freeze(SSMethods);
|
Object.freeze(SSMethods);
|
||||||
Object.freeze(TLS_FLOW_CONTROL);
|
Object.freeze(TLS_FLOW_CONTROL);
|
||||||
|
@ -125,6 +131,7 @@ Object.freeze(USAGE_OPTION);
|
||||||
Object.freeze(DOMAIN_STRATEGY_OPTION);
|
Object.freeze(DOMAIN_STRATEGY_OPTION);
|
||||||
Object.freeze(TCP_CONGESTION_OPTION);
|
Object.freeze(TCP_CONGESTION_OPTION);
|
||||||
Object.freeze(USERS_SECURITY);
|
Object.freeze(USERS_SECURITY);
|
||||||
|
Object.freeze(MODE_OPTION);
|
||||||
|
|
||||||
class XrayCommonClass {
|
class XrayCommonClass {
|
||||||
|
|
||||||
|
@ -528,7 +535,8 @@ class SplitHTTPStreamSettings extends XrayCommonClass {
|
||||||
maxConnections: 0,
|
maxConnections: 0,
|
||||||
cMaxReuseTimes: "64-128",
|
cMaxReuseTimes: "64-128",
|
||||||
cMaxLifetimeMs: 0
|
cMaxLifetimeMs: 0
|
||||||
}
|
},
|
||||||
|
mode = MODE_OPTION.AUTO,
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
this.path = path;
|
this.path = path;
|
||||||
|
@ -540,6 +548,7 @@ class SplitHTTPStreamSettings extends XrayCommonClass {
|
||||||
this.noSSEHeader = noSSEHeader;
|
this.noSSEHeader = noSSEHeader;
|
||||||
this.xPaddingBytes = xPaddingBytes;
|
this.xPaddingBytes = xPaddingBytes;
|
||||||
this.xmux = xmux;
|
this.xmux = xmux;
|
||||||
|
this.mode = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
addHeader(name, value) {
|
addHeader(name, value) {
|
||||||
|
@ -561,6 +570,7 @@ class SplitHTTPStreamSettings extends XrayCommonClass {
|
||||||
json.noSSEHeader,
|
json.noSSEHeader,
|
||||||
json.xPaddingBytes,
|
json.xPaddingBytes,
|
||||||
json.xmux,
|
json.xmux,
|
||||||
|
json.mode,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -579,7 +589,8 @@ class SplitHTTPStreamSettings extends XrayCommonClass {
|
||||||
maxConnections: this.xmux.maxConnections,
|
maxConnections: this.xmux.maxConnections,
|
||||||
cMaxReuseTimes: this.xmux.cMaxReuseTimes,
|
cMaxReuseTimes: this.xmux.cMaxReuseTimes,
|
||||||
cMaxLifetimeMs: this.xmux.cMaxLifetimeMs
|
cMaxLifetimeMs: this.xmux.cMaxLifetimeMs
|
||||||
}
|
},
|
||||||
|
mode: this.mode,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1329,6 +1340,7 @@ class Inbound extends XrayCommonClass {
|
||||||
const splithttp = this.stream.splithttp;
|
const splithttp = this.stream.splithttp;
|
||||||
obj.path = splithttp.path;
|
obj.path = splithttp.path;
|
||||||
obj.host = splithttp.host?.length > 0 ? splithttp.host : this.getHeader(splithttp, 'host');
|
obj.host = splithttp.host?.length > 0 ? splithttp.host : this.getHeader(splithttp, 'host');
|
||||||
|
obj.mode = splithttp.mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (security === 'tls') {
|
if (security === 'tls') {
|
||||||
|
@ -1401,6 +1413,7 @@ class Inbound extends XrayCommonClass {
|
||||||
const splithttp = this.stream.splithttp;
|
const splithttp = this.stream.splithttp;
|
||||||
params.set("path", splithttp.path);
|
params.set("path", splithttp.path);
|
||||||
params.set("host", splithttp.host?.length > 0 ? splithttp.host : this.getHeader(splithttp, 'host'));
|
params.set("host", splithttp.host?.length > 0 ? splithttp.host : this.getHeader(splithttp, 'host'));
|
||||||
|
params.set("mode", splithttp.mode);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1504,6 +1517,7 @@ class Inbound extends XrayCommonClass {
|
||||||
const splithttp = this.stream.splithttp;
|
const splithttp = this.stream.splithttp;
|
||||||
params.set("path", splithttp.path);
|
params.set("path", splithttp.path);
|
||||||
params.set("host", splithttp.host?.length > 0 ? splithttp.host : this.getHeader(splithttp, 'host'));
|
params.set("host", splithttp.host?.length > 0 ? splithttp.host : this.getHeader(splithttp, 'host'));
|
||||||
|
params.set("mode", splithttp.mode);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1586,6 +1600,7 @@ class Inbound extends XrayCommonClass {
|
||||||
const splithttp = this.stream.splithttp;
|
const splithttp = this.stream.splithttp;
|
||||||
params.set("path", splithttp.path);
|
params.set("path", splithttp.path);
|
||||||
params.set("host", splithttp.host?.length > 0 ? splithttp.host : this.getHeader(splithttp, 'host'));
|
params.set("host", splithttp.host?.length > 0 ? splithttp.host : this.getHeader(splithttp, 'host'));
|
||||||
|
params.set("mode", splithttp.mode);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,6 +77,12 @@ const USERS_SECURITY = {
|
||||||
ZERO: "zero",
|
ZERO: "zero",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const MODE_OPTION = {
|
||||||
|
AUTO: "auto",
|
||||||
|
PACKET_UP: "packet-up",
|
||||||
|
STREAM_UP: "stream-up",
|
||||||
|
};
|
||||||
|
|
||||||
Object.freeze(Protocols);
|
Object.freeze(Protocols);
|
||||||
Object.freeze(SSMethods);
|
Object.freeze(SSMethods);
|
||||||
Object.freeze(TLS_FLOW_CONTROL);
|
Object.freeze(TLS_FLOW_CONTROL);
|
||||||
|
@ -85,6 +91,7 @@ Object.freeze(ALPN_OPTION);
|
||||||
Object.freeze(OutboundDomainStrategies);
|
Object.freeze(OutboundDomainStrategies);
|
||||||
Object.freeze(WireguardDomainStrategy);
|
Object.freeze(WireguardDomainStrategy);
|
||||||
Object.freeze(USERS_SECURITY);
|
Object.freeze(USERS_SECURITY);
|
||||||
|
Object.freeze(MODE_OPTION);
|
||||||
|
|
||||||
|
|
||||||
class CommonClass {
|
class CommonClass {
|
||||||
|
@ -320,16 +327,22 @@ class HttpUpgradeStreamSettings extends CommonClass {
|
||||||
}
|
}
|
||||||
|
|
||||||
class SplitHTTPStreamSettings extends CommonClass {
|
class SplitHTTPStreamSettings extends CommonClass {
|
||||||
constructor(path = '/', host = '') {
|
constructor(
|
||||||
|
path = '/',
|
||||||
|
host = '',
|
||||||
|
mode = '',
|
||||||
|
) {
|
||||||
super();
|
super();
|
||||||
this.path = path;
|
this.path = path;
|
||||||
this.host = host;
|
this.host = host;
|
||||||
|
this.mode = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromJson(json = {}) {
|
static fromJson(json = {}) {
|
||||||
return new SplitHTTPStreamSettings(
|
return new SplitHTTPStreamSettings(
|
||||||
json.path,
|
json.path,
|
||||||
json.host,
|
json.host,
|
||||||
|
json.mode,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -337,6 +350,7 @@ class SplitHTTPStreamSettings extends CommonClass {
|
||||||
return {
|
return {
|
||||||
path: this.path,
|
path: this.path,
|
||||||
host: this.host,
|
host: this.host,
|
||||||
|
mode: this.mode,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -710,7 +724,7 @@ class Outbound extends CommonClass {
|
||||||
} else if (network === 'httpupgrade') {
|
} else if (network === 'httpupgrade') {
|
||||||
stream.httpupgrade = new HttpUpgradeStreamSettings(json.path, json.host);
|
stream.httpupgrade = new HttpUpgradeStreamSettings(json.path, json.host);
|
||||||
} else if (network === 'splithttp') {
|
} else if (network === 'splithttp') {
|
||||||
stream.splithttp = new SplitHTTPStreamSettings(json.path, json.host);
|
stream.splithttp = new SplitHTTPStreamSettings(json.path, json.host, json.mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (json.tls && json.tls == 'tls') {
|
if (json.tls && json.tls == 'tls') {
|
||||||
|
@ -754,7 +768,7 @@ class Outbound extends CommonClass {
|
||||||
} else if (type === 'httpupgrade') {
|
} else if (type === 'httpupgrade') {
|
||||||
stream.httpupgrade = new HttpUpgradeStreamSettings(path, host);
|
stream.httpupgrade = new HttpUpgradeStreamSettings(path, host);
|
||||||
} else if (type === 'splithttp') {
|
} else if (type === 'splithttp') {
|
||||||
stream.splithttp = new SplitHTTPStreamSettings(path, host);
|
stream.splithttp = new SplitHTTPStreamSettings(path, host, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (security == 'tls') {
|
if (security == 'tls') {
|
||||||
|
|
|
@ -380,6 +380,11 @@
|
||||||
<a-form-item label='{{ i18n "path" }}'>
|
<a-form-item label='{{ i18n "path" }}'>
|
||||||
<a-input v-model.trim="outbound.stream.splithttp.path"></a-input>
|
<a-input v-model.trim="outbound.stream.splithttp.path"></a-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
<a-form-item label='Mode'>
|
||||||
|
<a-select v-model="outbound.stream.splithttp.mode" :dropdown-class-name="themeSwitcher.currentTheme">
|
||||||
|
<a-select-option v-for="key in MODE_OPTION" :value="key">[[ key ]]</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,12 @@
|
||||||
</a-input>
|
</a-input>
|
||||||
</a-input-group>
|
</a-input-group>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
<a-form-item label='Mode'>
|
||||||
|
<a-select v-model="inbound.stream.splithttp.mode" style="width: 50%"
|
||||||
|
:dropdown-class-name="themeSwitcher.currentTheme">
|
||||||
|
<a-select-option v-for="key in MODE_OPTION" :value="key">[[ key ]]</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
<a-form-item label="Max Concurrent Upload">
|
<a-form-item label="Max Concurrent Upload">
|
||||||
<a-input v-model.trim="inbound.stream.splithttp.scMaxConcurrentPosts"></a-input>
|
<a-input v-model.trim="inbound.stream.splithttp.scMaxConcurrentPosts"></a-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
|
|
@ -58,6 +58,14 @@
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</template>
|
</template>
|
||||||
|
<template v-if="inbound.isSplithttp">
|
||||||
|
<tr>
|
||||||
|
<td>Mode</td>
|
||||||
|
<td>
|
||||||
|
<a-tag>[[ inbound.stream.splithttp.mode ]]</a-tag>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</template>
|
||||||
<template v-if="inbound.isKcp">
|
<template v-if="inbound.isKcp">
|
||||||
<tr>
|
<tr>
|
||||||
<td>kcp {{ i18n "encryption" }}</td>
|
<td>kcp {{ i18n "encryption" }}</td>
|
||||||
|
|
|
@ -588,8 +588,12 @@ func (s *InboundService) DelInboundClient(inboundId int, clientId string) (bool,
|
||||||
logger.Debug("Client deleted by api:", email)
|
logger.Debug("Client deleted by api:", email)
|
||||||
needRestart = false
|
needRestart = false
|
||||||
} else {
|
} else {
|
||||||
logger.Debug("Unable to del client by api:", err1)
|
if strings.Contains(err1.Error(), fmt.Sprintf("User %s not found.", email)) {
|
||||||
needRestart = true
|
logger.Debug("User is already deleted. Nothing to do more...")
|
||||||
|
} else {
|
||||||
|
logger.Debug("Error in deleting client by api:", err1)
|
||||||
|
needRestart = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
s.xrayApi.Close()
|
s.xrayApi.Close()
|
||||||
}
|
}
|
||||||
|
@ -713,10 +717,14 @@ func (s *InboundService) UpdateInboundClient(data *model.Inbound, clientId strin
|
||||||
if oldClients[clientIndex].Enable {
|
if oldClients[clientIndex].Enable {
|
||||||
err1 := s.xrayApi.RemoveUser(oldInbound.Tag, oldEmail)
|
err1 := s.xrayApi.RemoveUser(oldInbound.Tag, oldEmail)
|
||||||
if err1 == nil {
|
if err1 == nil {
|
||||||
logger.Debug("Old client deleted by api:", clients[0].Email)
|
logger.Debug("Old client deleted by api:", oldEmail)
|
||||||
} else {
|
} else {
|
||||||
logger.Debug("Error in deleting client by api:", err1)
|
if strings.Contains(err1.Error(), fmt.Sprintf("User %s not found.", oldEmail)) {
|
||||||
needRestart = true
|
logger.Debug("User is already deleted. Nothing to do more...")
|
||||||
|
} else {
|
||||||
|
logger.Debug("Error in deleting client by api:", err1)
|
||||||
|
needRestart = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if clients[0].Enable {
|
if clients[0].Enable {
|
||||||
|
@ -1037,12 +1045,8 @@ func (s *InboundService) disableInvalidInbounds(tx *gorm.DB) (bool, int64, error
|
||||||
if err1 == nil {
|
if err1 == nil {
|
||||||
logger.Debug("Inbound disabled by api:", tag)
|
logger.Debug("Inbound disabled by api:", tag)
|
||||||
} else {
|
} else {
|
||||||
if strings.Contains(err1.Error(), fmt.Sprintf("User %s not found.", tag)) {
|
logger.Debug("Error in disabling inbound by api:", err1)
|
||||||
logger.Debug("User is already disabled. Nothing to do more...")
|
needRestart = true
|
||||||
} else {
|
|
||||||
logger.Debug("Error in disabling client by api:", err1)
|
|
||||||
needRestart = true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s.xrayApi.Close()
|
s.xrayApi.Close()
|
||||||
|
|
597
web/translation/translate.ja_JP.toml
Normal file
597
web/translation/translate.ja_JP.toml
Normal file
|
@ -0,0 +1,597 @@
|
||||||
|
"username" = "ユーザー名"
|
||||||
|
"password" = "パスワード"
|
||||||
|
"login" = "ログイン"
|
||||||
|
"confirm" = "確認"
|
||||||
|
"cancel" = "キャンセル"
|
||||||
|
"close" = "閉じる"
|
||||||
|
"copy" = "コピー"
|
||||||
|
"copied" = "コピー済み"
|
||||||
|
"download" = "ダウンロード"
|
||||||
|
"remark" = "備考"
|
||||||
|
"enable" = "有効化"
|
||||||
|
"protocol" = "プロトコル"
|
||||||
|
"search" = "検索"
|
||||||
|
"filter" = "フィルター"
|
||||||
|
"loading" = "読み込み中..."
|
||||||
|
"second" = "秒"
|
||||||
|
"minute" = "分"
|
||||||
|
"hour" = "時間"
|
||||||
|
"day" = "日"
|
||||||
|
"check" = "確認"
|
||||||
|
"indefinite" = "無期限"
|
||||||
|
"unlimited" = "無制限"
|
||||||
|
"none" = "なし"
|
||||||
|
"qrCode" = "QRコード"
|
||||||
|
"info" = "詳細情報"
|
||||||
|
"edit" = "編集"
|
||||||
|
"delete" = "削除"
|
||||||
|
"reset" = "リセット"
|
||||||
|
"copySuccess" = "コピー成功"
|
||||||
|
"sure" = "確定"
|
||||||
|
"encryption" = "暗号化"
|
||||||
|
"transmission" = "伝送"
|
||||||
|
"host" = "ホスト"
|
||||||
|
"path" = "パス"
|
||||||
|
"camouflage" = "偽装"
|
||||||
|
"status" = "ステータス"
|
||||||
|
"enabled" = "有効"
|
||||||
|
"disabled" = "無効"
|
||||||
|
"depleted" = "消耗済み"
|
||||||
|
"depletingSoon" = "間もなく消耗"
|
||||||
|
"offline" = "オフライン"
|
||||||
|
"online" = "オンライン"
|
||||||
|
"domainName" = "ドメイン名"
|
||||||
|
"monitor" = "監視"
|
||||||
|
"certificate" = "証明書"
|
||||||
|
"fail" = "失敗"
|
||||||
|
"success" = "成功"
|
||||||
|
"getVersion" = "バージョン取得"
|
||||||
|
"install" = "インストール"
|
||||||
|
"clients" = "クライアント"
|
||||||
|
"usage" = "利用状況"
|
||||||
|
"secretToken" = "シークレットトークン"
|
||||||
|
"remained" = "残り"
|
||||||
|
"security" = "セキュリティ"
|
||||||
|
"secAlertTitle" = "セキュリティアラート"
|
||||||
|
"secAlertSsl" = "この接続は安全ではありません。TLSを有効にしてデータ保護を行うまで、機密情報を入力しないでください。"
|
||||||
|
"secAlertConf" = "一部の設定は脆弱です。潜在的な脆弱性を防ぐために、セキュリティプロトコルを強化することをお勧めします。"
|
||||||
|
"secAlertSSL" = "セキュアな接続がありません。データ保護のためにTLS証明書をインストールしてください。"
|
||||||
|
"secAlertPanelPort" = "デフォルトのポートにはセキュリティリスクがあります。ランダムなポートまたは特定のポートを設定してください。"
|
||||||
|
"secAlertPanelURI" = "デフォルトのURIパスは安全ではありません。複雑なURIパスを設定してください。"
|
||||||
|
"secAlertSubURI" = "サブスクリプションのデフォルトURIパスは安全ではありません。複雑なURIパスを設定してください。"
|
||||||
|
"secAlertSubJsonURI" = "JSONサブスクリプションのデフォルトURIパスは安全ではありません。複雑なURIパスを設定してください。"
|
||||||
|
|
||||||
|
[menu]
|
||||||
|
"dashboard" = "ダッシュボード"
|
||||||
|
"inbounds" = "インバウンド一覧"
|
||||||
|
"settings" = "パネル設定"
|
||||||
|
"xray" = "Xray設定"
|
||||||
|
"logout" = "ログアウト"
|
||||||
|
"link" = "リンク管理"
|
||||||
|
|
||||||
|
[pages.login]
|
||||||
|
"hello" = "こんにちは"
|
||||||
|
"title" = "ようこそ"
|
||||||
|
"loginAgain" = "ログインセッションが切れました。再度ログインしてください。"
|
||||||
|
|
||||||
|
[pages.login.toasts]
|
||||||
|
"invalidFormData" = "データ形式エラー"
|
||||||
|
"emptyUsername" = "ユーザー名を入力してください"
|
||||||
|
"emptyPassword" = "パスワードを入力してください"
|
||||||
|
"wrongUsernameOrPassword" = "ユーザー名またはパスワードが間違っています"
|
||||||
|
"successLogin" = "ログイン成功"
|
||||||
|
|
||||||
|
[pages.index]
|
||||||
|
"title" = "システムステータス"
|
||||||
|
"memory" = "メモリ"
|
||||||
|
"hard" = "ハードディスク"
|
||||||
|
"xrayStatus" = "Xray"
|
||||||
|
"stopXray" = "停止"
|
||||||
|
"restartXray" = "再起動"
|
||||||
|
"xraySwitch" = "バージョン"
|
||||||
|
"xraySwitchClick" = "切り替えるバージョンを選択してください"
|
||||||
|
"xraySwitchClickDesk" = "慎重に選択してください。古いバージョンは現在の設定と互換性がない可能性があります。"
|
||||||
|
"operationHours" = "システム稼働時間"
|
||||||
|
"systemLoad" = "システム負荷"
|
||||||
|
"systemLoadDesc" = "過去1、5、15分間のシステム平均負荷"
|
||||||
|
"connectionTcpCountDesc" = "システム内のすべてのTCP接続数"
|
||||||
|
"connectionUdpCountDesc" = "システム内のすべてのUDP接続数"
|
||||||
|
"connectionCount" = "接続数"
|
||||||
|
"upSpeed" = "総アップロード速度"
|
||||||
|
"downSpeed" = "総ダウンロード速度"
|
||||||
|
"totalSent" = "システム起動以降の送信データ量"
|
||||||
|
"totalReceive" = "システム起動以降の受信データ量"
|
||||||
|
"xraySwitchVersionDialog" = "Xrayバージョン切り替え"
|
||||||
|
"xraySwitchVersionDialogDesc" = "Xrayのバージョンを切り替えますか?"
|
||||||
|
"dontRefresh" = "インストール中、このページをリロードしないでください"
|
||||||
|
"logs" = "ログ"
|
||||||
|
"config" = "設定"
|
||||||
|
"backup" = "バックアップと復元"
|
||||||
|
"backupTitle" = "データベースのバックアップと復元"
|
||||||
|
"backupDescription" = "データベースを復元する前にバックアップすることをお勧めします"
|
||||||
|
"exportDatabase" = "バックアップ"
|
||||||
|
"importDatabase" = "復元"
|
||||||
|
|
||||||
|
[pages.inbounds]
|
||||||
|
"title" = "インバウンド一覧"
|
||||||
|
"totalDownUp" = "総アップロード / ダウンロード"
|
||||||
|
"totalUsage" = "総使用量"
|
||||||
|
"inboundCount" = "インバウンド数"
|
||||||
|
"operate" = "メニュー"
|
||||||
|
"enable" = "有効化"
|
||||||
|
"remark" = "備考"
|
||||||
|
"protocol" = "プロトコル"
|
||||||
|
"port" = "ポート"
|
||||||
|
"traffic" = "トラフィック"
|
||||||
|
"details" = "詳細情報"
|
||||||
|
"transportConfig" = "トランスポート設定"
|
||||||
|
"expireDate" = "有効期限"
|
||||||
|
"resetTraffic" = "トラフィックリセット"
|
||||||
|
"addInbound" = "インバウンド追加"
|
||||||
|
"generalActions" = "一般操作"
|
||||||
|
"create" = "追加"
|
||||||
|
"update" = "更新"
|
||||||
|
"modifyInbound" = "インバウンド修正"
|
||||||
|
"deleteInbound" = "インバウンド削除"
|
||||||
|
"deleteInboundContent" = "インバウンドを削除してもよろしいですか?"
|
||||||
|
"deleteClient" = "クライアント削除"
|
||||||
|
"deleteClientContent" = "クライアントを削除してもよろしいですか?"
|
||||||
|
"resetTrafficContent" = "トラフィックをリセットしてもよろしいですか?"
|
||||||
|
"copyLink" = "リンクをコピー"
|
||||||
|
"address" = "アドレス"
|
||||||
|
"network" = "ネットワーク"
|
||||||
|
"destinationPort" = "宛先ポート"
|
||||||
|
"targetAddress" = "宛先アドレス"
|
||||||
|
"monitorDesc" = "空白にするとすべてのIPを監視"
|
||||||
|
"meansNoLimit" = "= 無制限(単位:GB)"
|
||||||
|
"totalFlow" = "総トラフィック"
|
||||||
|
"leaveBlankToNeverExpire" = "空白にすると期限なし"
|
||||||
|
"noRecommendKeepDefault" = "デフォルト値を保持することをお勧めします"
|
||||||
|
"certificatePath" = "ファイルパス"
|
||||||
|
"certificateContent" = "ファイル内容"
|
||||||
|
"publicKey" = "公開鍵"
|
||||||
|
"privatekey" = "秘密鍵"
|
||||||
|
"clickOnQRcode" = "QRコードをクリックしてコピー"
|
||||||
|
"client" = "クライアント"
|
||||||
|
"export" = "リンクエクスポート"
|
||||||
|
"clone" = "複製"
|
||||||
|
"cloneInbound" = "複製"
|
||||||
|
"cloneInboundContent" = "このインバウンドルールは、ポート(Port)、リスニングIP(Listening IP)、クライアント(Clients)を除くすべての設定がクローンされます"
|
||||||
|
"cloneInboundOk" = "クローン作成"
|
||||||
|
"resetAllTraffic" = "すべてのインバウンドトラフィックをリセット"
|
||||||
|
"resetAllTrafficTitle" = "すべてのインバウンドトラフィックをリセット"
|
||||||
|
"resetAllTrafficContent" = "すべてのインバウンドトラフィックをリセットしてもよろしいですか?"
|
||||||
|
"resetInboundClientTraffics" = "クライアントトラフィックをリセット"
|
||||||
|
"resetInboundClientTrafficTitle" = "すべてのクライアントトラフィックをリセット"
|
||||||
|
"resetInboundClientTrafficContent" = "このインバウンドクライアントのすべてのトラフィックをリセットしてもよろしいですか?"
|
||||||
|
"resetAllClientTraffics" = "すべてのクライアントトラフィックをリセット"
|
||||||
|
"resetAllClientTrafficTitle" = "すべてのクライアントトラフィックをリセット"
|
||||||
|
"resetAllClientTrafficContent" = "すべてのクライアントのトラフィックをリセットしてもよろしいですか?"
|
||||||
|
"delDepletedClients" = "トラフィックが尽きたクライアントを削除"
|
||||||
|
"delDepletedClientsTitle" = "トラフィックが尽きたクライアントを削除"
|
||||||
|
"delDepletedClientsContent" = "トラフィックが尽きたすべてのクライアントを削除してもよろしいですか?"
|
||||||
|
"email" = "メールアドレス"
|
||||||
|
"emailDesc" = "メールアドレスは一意でなければなりません"
|
||||||
|
"IPLimit" = "IP制限"
|
||||||
|
"IPLimitDesc" = "設定値を超えるとインバウンドトラフィックが無効になります。(0 = 無効)"
|
||||||
|
"IPLimitlog" = "IPログ"
|
||||||
|
"IPLimitlogDesc" = "IP履歴ログ(無効なインバウンドトラフィックを有効にするには、ログをクリアしてください)"
|
||||||
|
"IPLimitlogclear" = "ログをクリア"
|
||||||
|
"setDefaultCert" = "パネル設定から証明書を設定"
|
||||||
|
"telegramDesc" = "TelegramチャットIDを提供してください。(ボットで'/id'コマンドを使用)または(@userinfobot)"
|
||||||
|
"subscriptionDesc" = "サブスクリプションURLを見つけるには、“詳細情報”に移動してください。また、複数のクライアントに同じ名前を使用することができます。"
|
||||||
|
"info" = "情報"
|
||||||
|
"same" = "同じ"
|
||||||
|
"inboundData" = "インバウンドデータ"
|
||||||
|
"exportInbound" = "インバウンドルールをエクスポート"
|
||||||
|
"import" = "インポート"
|
||||||
|
"importInbound" = "インバウンドルールをインポート"
|
||||||
|
|
||||||
|
[pages.client]
|
||||||
|
"add" = "クライアント追加"
|
||||||
|
"edit" = "クライアント編集"
|
||||||
|
"submitAdd" = "クライアント追加"
|
||||||
|
"submitEdit" = "変更を保存"
|
||||||
|
"clientCount" = "クライアント数"
|
||||||
|
"bulk" = "一括作成"
|
||||||
|
"method" = "方法"
|
||||||
|
"first" = "最初"
|
||||||
|
"last" = "最後"
|
||||||
|
"prefix" = "プレフィックス"
|
||||||
|
"postfix" = "サフィックス"
|
||||||
|
"delayedStart" = "初回使用後に開始"
|
||||||
|
"expireDays" = "期間"
|
||||||
|
"days" = "日"
|
||||||
|
"renew" = "自動更新"
|
||||||
|
"renewDesc" = "期限が切れた後に自動更新。(0 = 無効)(単位:日)"
|
||||||
|
|
||||||
|
[pages.inbounds.toasts]
|
||||||
|
"obtain" = "取得"
|
||||||
|
|
||||||
|
[pages.inbounds.stream.general]
|
||||||
|
"request" = "リクエスト"
|
||||||
|
"response" = "レスポンス"
|
||||||
|
"name" = "名前"
|
||||||
|
"value" = "値"
|
||||||
|
|
||||||
|
[pages.inbounds.stream.tcp]
|
||||||
|
"version" = "バージョン"
|
||||||
|
"method" = "方法"
|
||||||
|
"path" = "パス"
|
||||||
|
"status" = "ステータス"
|
||||||
|
"statusDescription" = "ステータス説明"
|
||||||
|
"requestHeader" = "リクエストヘッダー"
|
||||||
|
"responseHeader" = "レスポンスヘッダー"
|
||||||
|
|
||||||
|
[pages.settings]
|
||||||
|
"title" = "パネル設定"
|
||||||
|
"save" = "保存"
|
||||||
|
"infoDesc" = "ここでのすべての変更は、保存してパネルを再起動する必要があります"
|
||||||
|
"restartPanel" = "パネル再起動"
|
||||||
|
"restartPanelDesc" = "パネルを再起動してもよろしいですか?再起動後にパネルにアクセスできない場合は、サーバーでパネルログを確認してください"
|
||||||
|
"actions" = "操作"
|
||||||
|
"resetDefaultConfig" = "デフォルト設定にリセット"
|
||||||
|
"panelSettings" = "一般"
|
||||||
|
"securitySettings" = "セキュリティ設定"
|
||||||
|
"TGBotSettings" = "Telegramボット設定"
|
||||||
|
"panelListeningIP" = "パネル監視IP"
|
||||||
|
"panelListeningIPDesc" = "デフォルトではすべてのIPを監視する"
|
||||||
|
"panelListeningDomain" = "パネル監視ドメイン"
|
||||||
|
"panelListeningDomainDesc" = "デフォルトで空白の場合、すべてのドメインとIPアドレスを監視する"
|
||||||
|
"panelPort" = "パネル監視ポート"
|
||||||
|
"panelPortDesc" = "再起動で有効"
|
||||||
|
"publicKeyPath" = "パネル証明書公開鍵ファイルパス"
|
||||||
|
"publicKeyPathDesc" = "'/'で始まる絶対パスを入力"
|
||||||
|
"privateKeyPath" = "パネル証明書秘密鍵ファイルパス"
|
||||||
|
"privateKeyPathDesc" = "'/'で始まる絶対パスを入力"
|
||||||
|
"panelUrlPath" = "パネルURLルートパス"
|
||||||
|
"panelUrlPathDesc" = "'/'で始まり、'/'で終わる必要があります"
|
||||||
|
"pageSize" = "ページサイズ"
|
||||||
|
"pageSizeDesc" = "インバウンドテーブルのページサイズを定義します。0を設定すると無効化されます"
|
||||||
|
"remarkModel" = "備考モデルと区切り記号"
|
||||||
|
"datepicker" = "日付ピッカー"
|
||||||
|
"datepickerPlaceholder" = "日付を選択"
|
||||||
|
"datepickerDescription" = "日付選択カレンダーで有効期限を指定する"
|
||||||
|
"sampleRemark" = "備考の例"
|
||||||
|
"oldUsername" = "旧ユーザー名"
|
||||||
|
"currentPassword" = "旧パスワード"
|
||||||
|
"newUsername" = "新しいユーザー名"
|
||||||
|
"newPassword" = "新しいパスワード"
|
||||||
|
"telegramBotEnable" = "Telegramボットを有効にする"
|
||||||
|
"telegramBotEnableDesc" = "Telegramボット機能を有効にする"
|
||||||
|
"telegramToken" = "Telegramボットトークン"
|
||||||
|
"telegramTokenDesc" = "'@BotFather'から取得したTelegramボットトークン"
|
||||||
|
"telegramProxy" = "SOCKS5プロキシ"
|
||||||
|
"telegramProxyDesc" = "SOCKS5プロキシを有効にしてTelegramに接続する(ガイドに従って設定を調整)"
|
||||||
|
"telegramAPIServer" = "Telegram APIサーバー"
|
||||||
|
"telegramAPIServerDesc" = "使用するTelegram APIサーバー。空白の場合はデフォルトサーバーを使用する"
|
||||||
|
"telegramChatId" = "管理者チャットID"
|
||||||
|
"telegramChatIdDesc" = "Telegram管理者チャットID(複数の場合はカンマで区切る)@userinfobotで取得するか、ボットで'/id'コマンドを使用して取得する"
|
||||||
|
"telegramNotifyTime" = "通知時間"
|
||||||
|
"telegramNotifyTimeDesc" = "定期的なTelegramボット通知時間を設定する(crontab時間形式を使用)"
|
||||||
|
"tgNotifyBackup" = "データベースバックアップ"
|
||||||
|
"tgNotifyBackupDesc" = "レポート付きのデータベースバックアップファイルを送信"
|
||||||
|
"tgNotifyLogin" = "ログイン通知"
|
||||||
|
"tgNotifyLoginDesc" = "誰かがパネルにログインしようとしたときに、ユーザー名、IPアドレス、時間を表示する"
|
||||||
|
"sessionMaxAge" = "セッション期間"
|
||||||
|
"sessionMaxAgeDesc" = "ログイン状態を保持する期間(単位:分)"
|
||||||
|
"expireTimeDiff" = "有効期限通知のしきい値"
|
||||||
|
"expireTimeDiffDesc" = "このしきい値に達した場合、有効期限に関する通知を受け取る(単位:日)"
|
||||||
|
"trafficDiff" = "トラフィック消耗しきい値"
|
||||||
|
"trafficDiffDesc" = "このしきい値に達した場合、トラフィック消耗に関する通知を受け取る(単位:GB)"
|
||||||
|
"tgNotifyCpu" = "CPU負荷通知しきい値"
|
||||||
|
"tgNotifyCpuDesc" = "CPU負荷がこのしきい値を超えた場合、通知を受け取る(単位:%)"
|
||||||
|
"timeZone" = "タイムゾーン"
|
||||||
|
"timeZoneDesc" = "定時タスクはこのタイムゾーンの時間に従って実行される"
|
||||||
|
"subSettings" = "サブスクリプション設定"
|
||||||
|
"subEnable" = "サブスクリプションサービスを有効にする"
|
||||||
|
"subEnableDesc" = "サブスクリプションサービス機能を有効にする"
|
||||||
|
"subListen" = "監視IP"
|
||||||
|
"subListenDesc" = "サブスクリプションサービスが監視するIPアドレス(空白にするとすべてのIPを監視)"
|
||||||
|
"subPort" = "監視ポート"
|
||||||
|
"subPortDesc" = "サブスクリプションサービスが監視するポート番号(使用されていないポートである必要があります)"
|
||||||
|
"subCertPath" = "公開鍵パス"
|
||||||
|
"subCertPathDesc" = "サブスクリプションサービスで使用する公開鍵ファイルのパス('/'で始まる)"
|
||||||
|
"subKeyPath" = "秘密鍵パス"
|
||||||
|
"subKeyPathDesc" = "サブスクリプションサービスで使用する秘密鍵ファイルのパス('/'で始まる)"
|
||||||
|
"subPath" = "URIパス"
|
||||||
|
"subPathDesc" = "サブスクリプションサービスで使用するURIパス('/'で始まり、'/'で終わる)"
|
||||||
|
"subDomain" = "監視ドメイン"
|
||||||
|
"subDomainDesc" = "サブスクリプションサービスが監視するドメイン(空白にするとすべてのドメインとIPを監視)"
|
||||||
|
"subUpdates" = "更新間隔"
|
||||||
|
"subUpdatesDesc" = "クライアントアプリケーションでサブスクリプションURLの更新間隔(単位:時間)"
|
||||||
|
"subEncrypt" = "エンコード"
|
||||||
|
"subEncryptDesc" = "サブスクリプションサービスが返す内容をBase64エンコードする"
|
||||||
|
"subShowInfo" = "利用情報を表示"
|
||||||
|
"subShowInfoDesc" = "クライアントアプリで残りのトラフィックと日付情報を表示する"
|
||||||
|
"subURI" = "リバースプロキシURI"
|
||||||
|
"subURIDesc" = "プロキシ後ろのサブスクリプションURLのURIパスに使用する"
|
||||||
|
"fragment" = "フラグメント"
|
||||||
|
"fragmentDesc" = "TLS helloパケットのフラグメントを有効にする"
|
||||||
|
"fragmentSett" = "設定"
|
||||||
|
"noisesDesc" = "Noisesを有効にする"
|
||||||
|
"noisesSett" = "Noises設定"
|
||||||
|
"mux" = "マルチプレクサ"
|
||||||
|
"muxDesc" = "確立されたストリーム内で複数の独立したストリームを伝送する"
|
||||||
|
"muxSett" = "マルチプレクサ設定"
|
||||||
|
"direct" = "直接接続"
|
||||||
|
"directDesc" = "特定の国のドメインまたはIP範囲に直接接続する"
|
||||||
|
|
||||||
|
|
||||||
|
[pages.xray]
|
||||||
|
"title" = "Xray 設定"
|
||||||
|
"save" = "保存"
|
||||||
|
"restart" = "Xray 再起動"
|
||||||
|
"basicTemplate" = "基本設定"
|
||||||
|
"advancedTemplate" = "高度な設定"
|
||||||
|
"generalConfigs" = "一般設定"
|
||||||
|
"generalConfigsDesc" = "これらのオプションは一般設定を決定します"
|
||||||
|
"logConfigs" = "ログ"
|
||||||
|
"logConfigsDesc" = "ログはサーバーのパフォーマンスに影響を与える可能性があるため、必要な場合にのみ有効にすることをお勧めします"
|
||||||
|
"blockConfigs" = "防御フィルター"
|
||||||
|
"blockConfigsDesc" = "これらのオプションは、特定のプロトコルやウェブサイトへのユーザー接続をブロックします"
|
||||||
|
"basicRouting" = "基本ルーティング"
|
||||||
|
"blockConnectionsConfigsDesc" = "これらのオプションにより、特定のリクエスト元の国に基づいてトラフィックをブロックします。"
|
||||||
|
"directConnectionsConfigsDesc" = "直接接続により、特定のトラフィックが他のサーバーを経由しないようにします。"
|
||||||
|
"blockips" = "IPをブロック"
|
||||||
|
"blockdomains" = "ドメインをブロック"
|
||||||
|
"directips" = "直接IP"
|
||||||
|
"directdomains" = "直接ドメイン"
|
||||||
|
"ipv4Routing" = "IPv4 ルーティング"
|
||||||
|
"ipv4RoutingDesc" = "このオプションはIPv4のみを介してターゲットドメインへルーティングします"
|
||||||
|
"warpRouting" = "WARP ルーティング"
|
||||||
|
"warpRoutingDesc" = "注意:これらのオプションを使用する前に、パネルのGitHubの手順に従って、サーバーにsocks5プロキシモードでWARPをインストールしてください。WARPはCloudflareサーバー経由でトラフィックをウェブサイトにルーティングします。"
|
||||||
|
"Template" = "高度なXray設定テンプレート"
|
||||||
|
"TemplateDesc" = "最終的なXray設定ファイルはこのテンプレートに基づいて生成されます"
|
||||||
|
"FreedomStrategy" = "Freedom プロトコル戦略"
|
||||||
|
"FreedomStrategyDesc" = "Freedomプロトコル内のネットワークの出力戦略を設定する"
|
||||||
|
"RoutingStrategy" = "ルーティングドメイン戦略設定"
|
||||||
|
"RoutingStrategyDesc" = "DNS解決の全体的なルーティング戦略を設定する"
|
||||||
|
"Torrent" = "BitTorrent プロトコルをブロック"
|
||||||
|
"TorrentDesc" = "BitTorrentの使用を禁止する"
|
||||||
|
"Family" = "ファミリー保護"
|
||||||
|
"FamilyDesc" = "アダルトコンテンツや悪意のあるサイトをブロックする"
|
||||||
|
"Inbounds" = "インバウンドルール"
|
||||||
|
"InboundsDesc" = "特定のクライアントからのトラフィックを受け入れる"
|
||||||
|
"Outbounds" = "アウトバウンドルール"
|
||||||
|
"Balancers" = "負荷分散"
|
||||||
|
"OutboundsDesc" = "アウトバウンドトラフィックの送信方法を設定する"
|
||||||
|
"Routings" = "ルーティングルール"
|
||||||
|
"RoutingsDesc" = "各ルールの優先順位が重要です"
|
||||||
|
"completeTemplate" = "すべて"
|
||||||
|
"logLevel" = "ログレベル"
|
||||||
|
"logLevelDesc" = "エラーログのレベルを指定し、記録する情報を示します"
|
||||||
|
"accessLog" = "アクセスログ"
|
||||||
|
"accessLogDesc" = "アクセスログのファイルパス。特殊値 'none' はアクセスログを無効にします"
|
||||||
|
"errorLog" = "エラーログ"
|
||||||
|
"errorLogDesc" = "エラーログのファイルパス。特殊値 'none' はエラーログを無効にします"
|
||||||
|
"dnsLog" = "DNS ログ"
|
||||||
|
"dnsLogDesc" = "DNSクエリのログを有効にするかどうか"
|
||||||
|
"maskAddress" = "アドレスをマスク"
|
||||||
|
"maskAddressDesc" = "IPアドレスをマスクし、有効にするとログに表示されるIPアドレスを自動的に置き換えます"
|
||||||
|
|
||||||
|
[pages.xray.rules]
|
||||||
|
"first" = "最初"
|
||||||
|
"last" = "最後"
|
||||||
|
"up" = "上へ"
|
||||||
|
"down" = "下へ"
|
||||||
|
"source" = "ソース"
|
||||||
|
"dest" = "宛先アドレス"
|
||||||
|
"inbound" = "インバウンド"
|
||||||
|
"outbound" = "アウトバウンド"
|
||||||
|
"balancer" = "負荷分散"
|
||||||
|
"info" = "情報"
|
||||||
|
"add" = "ルール追加"
|
||||||
|
"edit" = "ルール編集"
|
||||||
|
"useComma" = "カンマ区切りの項目"
|
||||||
|
|
||||||
|
[pages.xray.outbound]
|
||||||
|
"addOutbound" = "アウトバウンド追加"
|
||||||
|
"addReverse" = "リバース追加"
|
||||||
|
"editOutbound" = "アウトバウンド編集"
|
||||||
|
"editReverse" = "リバース編集"
|
||||||
|
"tag" = "タグ"
|
||||||
|
"tagDesc" = "一意のタグ"
|
||||||
|
"address" = "アドレス"
|
||||||
|
"reverse" = "リバース"
|
||||||
|
"domain" = "ドメイン"
|
||||||
|
"type" = "タイプ"
|
||||||
|
"bridge" = "ブリッジ"
|
||||||
|
"portal" = "ポータル"
|
||||||
|
"intercon" = "インターコネクション"
|
||||||
|
"settings" = "設定"
|
||||||
|
"accountInfo" = "アカウント情報"
|
||||||
|
"outboundStatus" = "アウトバウンドステータス"
|
||||||
|
"sendThrough" = "送信経路"
|
||||||
|
|
||||||
|
[pages.xray.balancer]
|
||||||
|
"addBalancer" = "負荷分散追加"
|
||||||
|
"editBalancer" = "負荷分散編集"
|
||||||
|
"balancerStrategy" = "戦略"
|
||||||
|
"balancerSelectors" = "セレクター"
|
||||||
|
"tag" = "タグ"
|
||||||
|
"tagDesc" = "一意のタグ"
|
||||||
|
"balancerDesc" = "balancerTagとoutboundTagは同時に使用できません。同時に使用された場合、outboundTagのみが有効になります。"
|
||||||
|
|
||||||
|
[pages.xray.wireguard]
|
||||||
|
"secretKey" = "シークレットキー"
|
||||||
|
"publicKey" = "公開鍵"
|
||||||
|
"allowedIPs" = "許可されたIP"
|
||||||
|
"endpoint" = "エンドポイント"
|
||||||
|
"psk" = "共有キー"
|
||||||
|
"domainStrategy" = "ドメイン戦略"
|
||||||
|
|
||||||
|
[pages.xray.dns]
|
||||||
|
"enable" = "DNSを有効にする"
|
||||||
|
"enableDesc" = "組み込みDNSサーバーを有効にする"
|
||||||
|
"tag" = "DNSインバウンドタグ"
|
||||||
|
"tagDesc" = "このタグはルーティングルールでインバウンドタグとして使用できます"
|
||||||
|
"strategy" = "クエリ戦略"
|
||||||
|
"strategyDesc" = "ドメイン名解決の全体的な戦略"
|
||||||
|
"add" = "サーバー追加"
|
||||||
|
"edit" = "サーバー編集"
|
||||||
|
"domains" = "ドメイン"
|
||||||
|
"expectIPs" = "期待されるIP"
|
||||||
|
|
||||||
|
|
||||||
|
[pages.xray.fakedns]
|
||||||
|
"add" = "フェイクDNS追加"
|
||||||
|
"edit" = "フェイクDNS編集"
|
||||||
|
"ipPool" = "IPプールサブネット"
|
||||||
|
"poolSize" = "プールサイズ"
|
||||||
|
|
||||||
|
|
||||||
|
[pages.settings.security]
|
||||||
|
"admin" = "管理者"
|
||||||
|
"secret" = "セキュリティトークン"
|
||||||
|
"loginSecurity" = "ログインセキュリティ"
|
||||||
|
"loginSecurityDesc" = "追加の認証を追加してセキュリティを向上させる"
|
||||||
|
"secretToken" = "セキュリティトークン"
|
||||||
|
"secretTokenDesc" = "このトークンを安全な場所に保管してください。このトークンはログインに使用され、紛失すると回復できません。"
|
||||||
|
|
||||||
|
[pages.settings.toasts]
|
||||||
|
"modifySettings" = "設定を変更"
|
||||||
|
"getSettings" = "設定を取得"
|
||||||
|
"modifyUser" = "管理者を変更"
|
||||||
|
"originalUserPassIncorrect" = "旧ユーザー名または旧パスワードが間違っています"
|
||||||
|
"userPassMustBeNotEmpty" = "新しいユーザー名と新しいパスワードは空にできません"
|
||||||
|
|
||||||
|
[tgbot]
|
||||||
|
"keyboardClosed" = "❌ カスタムキーボードが閉じられました!"
|
||||||
|
"noResult" = "❗ 結果がありません!"
|
||||||
|
"noQuery" = "❌ クエリが見つかりませんでした!もう一度コマンドを使用してください!"
|
||||||
|
"wentWrong" = "❌ 問題が発生しました!"
|
||||||
|
"noIpRecord" = "❗ IP記録がありません!"
|
||||||
|
"noInbounds" = "❗ インバウンド接続が見つかりません!"
|
||||||
|
"unlimited" = "♾ 無制限"
|
||||||
|
"add" = "追加"
|
||||||
|
"month" = "月"
|
||||||
|
"months" = "月"
|
||||||
|
"day" = "日"
|
||||||
|
"days" = "日"
|
||||||
|
"hours" = "時間"
|
||||||
|
"unknown" = "不明"
|
||||||
|
"inbounds" = "インバウンド接続"
|
||||||
|
"clients" = "クライアント"
|
||||||
|
"offline" = "🔴 オフライン"
|
||||||
|
"online" = "🟢 オンライン"
|
||||||
|
|
||||||
|
[tgbot.commands]
|
||||||
|
"unknown" = "❗ 不明なコマンド"
|
||||||
|
"pleaseChoose" = "👇 選択してください:\r\n"
|
||||||
|
"help" = "🤖 このボットをご利用いただきありがとうございます!サーバーから特定のデータを提供し、必要な変更を行うことができます。\r\n\r\n"
|
||||||
|
"start" = "👋 こんにちは、<i>{{ .Firstname }}</i>。\r\n"
|
||||||
|
"welcome" = "🤖 <b>{{ .Hostname }}</b> 管理ボットへようこそ。\r\n"
|
||||||
|
"status" = "✅ ボットは正常に動作しています!"
|
||||||
|
"usage" = "❗ 検索するテキストを入力してください!"
|
||||||
|
"getID" = "🆔 あなたのIDは:<code>{{ .ID }}</code>"
|
||||||
|
"helpAdminCommands" = "Xray Coreを再起動するには:\r\n<code>/restart force</code>\r\n\r\nクライアントの電子メールを検索するには:\r\n<code>/usage [電子メール]</code>\r\n\r\nインバウンド(クライアントの統計情報を含む)を検索するには:\r\n<code>/inbound [備考]</code>\r\n\r\nTelegramチャットID:\r\n<code>/id</code>"
|
||||||
|
"helpClientCommands" = "統計情報を検索するには、次のコマンドを使用してください:\r\n<code>/usage [電子メール]</code>\r\n\r\nTelegramチャットID:\r\n<code>/id</code>"
|
||||||
|
"restartUsage" = "\r\n\r\n<code>/restart force</code>"
|
||||||
|
"restartSuccess" = "✅ 操作成功!"
|
||||||
|
"restartFailed" = "❗ 操作エラー。\r\n\r\n<code>エラー: {{ .Error }}</code>"
|
||||||
|
"xrayNotRunning" = "❗ Xray Core は動作していません。"
|
||||||
|
|
||||||
|
[tgbot.messages]
|
||||||
|
"cpuThreshold" = "🔴 CPU使用率は{{ .Percent }}%、しきい値{{ .Threshold }}%を超えました"
|
||||||
|
"selectUserFailed" = "❌ ユーザーの選択に失敗しました!"
|
||||||
|
"userSaved" = "✅ Telegramユーザーが保存されました。"
|
||||||
|
"loginSuccess" = "✅ パネルに正常にログインしました。\r\n"
|
||||||
|
"loginFailed" = "❗️ パネルのログインに失敗しました。\r\n"
|
||||||
|
"report" = "🕰 定期報告:{{ .RunTime }}\r\n"
|
||||||
|
"datetime" = "⏰ 日時:{{ .DateTime }}\r\n"
|
||||||
|
"hostname" = "💻 ホスト名:{{ .Hostname }}\r\n"
|
||||||
|
"version" = "🚀 X-UI バージョン:{{ .Version }}\r\n"
|
||||||
|
"xrayVersion" = "📡 Xray バージョン: {{ .XrayVersion }}\r\n"
|
||||||
|
"ipv6" = "🌐 IPv6:{{ .IPv6 }}\r\n"
|
||||||
|
"ipv4" = "🌐 IPv4:{{ .IPv4 }}\r\n"
|
||||||
|
"ip" = "🌐 IP:{{ .IP }}\r\n"
|
||||||
|
"ips" = "🔢 IPアドレス:\r\n{{ .IPs }}\r\n"
|
||||||
|
"serverUpTime" = "⏳ サーバー稼働時間:{{ .UpTime }} {{ .Unit }}\r\n"
|
||||||
|
"serverLoad" = "📈 サーバー負荷:{{ .Load1 }}, {{ .Load2 }}, {{ .Load3 }}\r\n"
|
||||||
|
"serverMemory" = "📋 サーバーメモリ:{{ .Current }}/{{ .Total }}\r\n"
|
||||||
|
"tcpCount" = "🔹 TCP接続数:{{ .Count }}\r\n"
|
||||||
|
"udpCount" = "🔸 UDP接続数:{{ .Count }}\r\n"
|
||||||
|
"traffic" = "🚦 トラフィック:{{ .Total }} (↑{{ .Upload }},↓{{ .Download }})\r\n"
|
||||||
|
"xrayStatus" = "ℹ️ Xrayステータス:{{ .State }}\r\n"
|
||||||
|
"username" = "👤 ユーザー名:{{ .Username }}\r\n"
|
||||||
|
"password" = "👤 パスワード: {{ .Password }}\r\n"
|
||||||
|
"time" = "⏰ 時間:{{ .Time }}\r\n"
|
||||||
|
"inbound" = "📍 インバウンド:{{ .Remark }}\r\n"
|
||||||
|
"port" = "🔌 ポート:{{ .Port }}\r\n"
|
||||||
|
"expire" = "📅 有効期限:{{ .Time }}\r\n"
|
||||||
|
"expireIn" = "📅 残り時間:{{ .Time }}\r\n"
|
||||||
|
"active" = "💡 有効:{{ .Enable }}\r\n"
|
||||||
|
"enabled" = "🚨 有効化済み:{{ .Enable }}\r\n"
|
||||||
|
"online" = "🌐 接続ステータス:{{ .Status }}\r\n"
|
||||||
|
"email" = "📧 メール:{{ .Email }}\r\n"
|
||||||
|
"upload" = "🔼 アップロード↑:{{ .Upload }}\r\n"
|
||||||
|
"download" = "🔽 ダウンロード↓:{{ .Download }}\r\n"
|
||||||
|
"total" = "📊 合計:{{ .UpDown }} / {{ .Total }}\r\n"
|
||||||
|
"TGUser" = "👤 Telegramユーザー:{{ .TelegramID }}\r\n"
|
||||||
|
"exhaustedMsg" = "🚨 消耗済みの {{ .Type }}:\r\n"
|
||||||
|
"exhaustedCount" = "🚨 消耗済みの {{ .Type }} 数量:\r\n"
|
||||||
|
"onlinesCount" = "🌐 オンラインクライアント:{{ .Count }}\r\n"
|
||||||
|
"disabled" = "🛑 無効化:{{ .Disabled }}\r\n"
|
||||||
|
"depleteSoon" = "🔜 間もなく消耗:{{ .Deplete }}\r\n\r\n"
|
||||||
|
"backupTime" = "🗄 バックアップ時間:{{ .Time }}\r\n"
|
||||||
|
"refreshedOn" = "\r\n📋🔄 更新時間:{{ .Time }}\r\n\r\n"
|
||||||
|
"yes" = "✅ はい"
|
||||||
|
"no" = "❌ いいえ"
|
||||||
|
|
||||||
|
[tgbot.buttons]
|
||||||
|
"closeKeyboard" = "❌ キーボードを閉じる"
|
||||||
|
"cancel" = "❌ キャンセル"
|
||||||
|
"cancelReset" = "❌ リセットをキャンセル"
|
||||||
|
"cancelIpLimit" = "❌ IP制限をキャンセル"
|
||||||
|
"confirmResetTraffic" = "✅ トラフィックをリセットしますか?"
|
||||||
|
"confirmClearIps" = "✅ IPをクリアしますか?"
|
||||||
|
"confirmRemoveTGUser" = "✅ Telegramユーザーを削除しますか?"
|
||||||
|
"confirmToggle" = "✅ ユーザーを有効/無効にしますか?"
|
||||||
|
"dbBackup" = "データベースバックアップを取得"
|
||||||
|
"serverUsage" = "サーバーの使用状況"
|
||||||
|
"getInbounds" = "インバウンド情報を取得"
|
||||||
|
"depleteSoon" = "間もなく消耗"
|
||||||
|
"clientUsage" = "使用状況を取得"
|
||||||
|
"onlines" = "オンラインクライアント"
|
||||||
|
"commands" = "コマンド"
|
||||||
|
"refresh" = "🔄 更新"
|
||||||
|
"clearIPs" = "❌ IPをクリア"
|
||||||
|
"removeTGUser" = "❌ Telegramユーザーを削除"
|
||||||
|
"selectTGUser" = "👤 Telegramユーザーを選択"
|
||||||
|
"selectOneTGUser" = "👤 1人のTelegramユーザーを選択:"
|
||||||
|
"resetTraffic" = "📈 トラフィックをリセット"
|
||||||
|
"resetExpire" = "📅 有効期限を変更"
|
||||||
|
"ipLog" = "🔢 IPログ"
|
||||||
|
"ipLimit" = "🔢 IP制限"
|
||||||
|
"setTGUser" = "👤 Telegramユーザーを設定"
|
||||||
|
"toggle" = "🔘 有効/無効"
|
||||||
|
"custom" = "🔢 カスタム"
|
||||||
|
"confirmNumber" = "✅ 確認: {{ .Num }}"
|
||||||
|
"confirmNumberAdd" = "✅ 追加を確認:{{ .Num }}"
|
||||||
|
"limitTraffic" = "🚧 トラフィック制限"
|
||||||
|
"getBanLogs" = "禁止ログ"
|
||||||
|
"allClients" = "すべてのクライアント"
|
||||||
|
|
||||||
|
[tgbot.answers]
|
||||||
|
"successfulOperation" = "✅ 成功!"
|
||||||
|
"errorOperation" = "❗ 操作エラー。"
|
||||||
|
"getInboundsFailed" = "❌ インバウンド情報の取得に失敗しました。"
|
||||||
|
"getClientsFailed" = "❌ クライアントの取得に失敗しました。"
|
||||||
|
"canceled" = "❌ {{ .Email }}:操作がキャンセルされました。"
|
||||||
|
"clientRefreshSuccess" = "✅ {{ .Email }}:クライアントが正常に更新されました。"
|
||||||
|
"IpRefreshSuccess" = "✅ {{ .Email }}:IPが正常に更新されました。"
|
||||||
|
"TGIdRefreshSuccess" = "✅ {{ .Email }}:クライアントのTelegramユーザーが正常に更新されました。"
|
||||||
|
"resetTrafficSuccess" = "✅ {{ .Email }}:トラフィックが正常にリセットされました。"
|
||||||
|
"setTrafficLimitSuccess" = "✅ {{ .Email }}:トラフィック制限が正常に保存されました。"
|
||||||
|
"expireResetSuccess" = "✅ {{ .Email }}:有効期限の日数が正常にリセットされました。"
|
||||||
|
"resetIpSuccess" = "✅ {{ .Email }}:IP制限数が正常に保存されました:{{ .Count }}。"
|
||||||
|
"clearIpSuccess" = "✅ {{ .Email }}:IPが正常にクリアされました。"
|
||||||
|
"getIpLog" = "✅ {{ .Email }}:IPログの取得。"
|
||||||
|
"getUserInfo" = "✅ {{ .Email }}:Telegramユーザー情報の取得。"
|
||||||
|
"removedTGUserSuccess" = "✅ {{ .Email }}:Telegramユーザーが正常に削除されました。"
|
||||||
|
"enableSuccess" = "✅ {{ .Email }}:正常に有効化されました。"
|
||||||
|
"disableSuccess" = "✅ {{ .Email }}:正常に無効化されました。"
|
||||||
|
"askToAddUserId" = "設定が見つかりませんでした!\r\n管理者に問い合わせて、設定にTelegramユーザーのChatIDを使用してください。\r\n\r\nあなたのユーザーChatID:<code>{{ .TgUserID }}</code>"
|
||||||
|
"chooseClient" = "インバウンド {{ .Inbound }} のクライアントを選択"
|
||||||
|
"chooseInbound" = "インバウンドを選択"
|
113
x-ui.sh
113
x-ui.sh
|
@ -1116,76 +1116,119 @@ ssl_cert_issue() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ssl_cert_issue_CF() {
|
ssl_cert_issue_CF() {
|
||||||
echo -E ""
|
local existing_webBasePath=$(/usr/local/x-ui/x-ui setting -show true | grep -Eo 'webBasePath: .+' | awk '{print $2}')
|
||||||
LOGD "******Instructions for use******"
|
local existing_port=$(/usr/local/x-ui/x-ui setting -show true | grep -Eo 'port: .+' | awk '{print $2}')
|
||||||
LOGI "This Acme script requires the following data:"
|
LOGI "****** Instructions for Use ******"
|
||||||
LOGI "1.Cloudflare Registered e-mail"
|
LOGI "Follow the steps below to complete the process:"
|
||||||
LOGI "2.Cloudflare Global API Key"
|
LOGI "1. Cloudflare Registered E-mail."
|
||||||
LOGI "3.The domain name that has been resolved dns to the current server by Cloudflare"
|
LOGI "2. Cloudflare Global API Key."
|
||||||
LOGI "4.The script applies for a certificate. The default installation path is /root/cert "
|
LOGI "3. The Domain Name."
|
||||||
confirm "Confirmed?[y/n]" "y"
|
LOGI "4. Once the certificate is issued, you will be prompted to set the certificate for the panel (optional)."
|
||||||
|
LOGI "5. The script also supports automatic renewal of the SSL certificate after installation."
|
||||||
|
|
||||||
|
confirm "Do you confirm the information and wish to proceed? [y/n]" "y"
|
||||||
|
|
||||||
if [ $? -eq 0 ]; then
|
if [ $? -eq 0 ]; then
|
||||||
# check for acme.sh first
|
# Check for acme.sh first
|
||||||
if ! command -v ~/.acme.sh/acme.sh &>/dev/null; then
|
if ! command -v ~/.acme.sh/acme.sh &>/dev/null; then
|
||||||
echo "acme.sh could not be found. we will install it"
|
echo "acme.sh could not be found. We will install it."
|
||||||
install_acme
|
install_acme
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
LOGE "install acme failed, please check logs"
|
LOGE "Install acme failed, please check logs."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
CF_Domain=""
|
CF_Domain=""
|
||||||
CF_GlobalKey=""
|
certPath="/root/cert-CF"
|
||||||
CF_AccountEmail=""
|
|
||||||
certPath=/root/cert
|
|
||||||
if [ ! -d "$certPath" ]; then
|
if [ ! -d "$certPath" ]; then
|
||||||
mkdir $certPath
|
mkdir -p $certPath
|
||||||
else
|
else
|
||||||
rm -rf $certPath
|
rm -rf $certPath
|
||||||
mkdir $certPath
|
mkdir -p $certPath
|
||||||
fi
|
fi
|
||||||
|
|
||||||
LOGD "Please set a domain name:"
|
LOGD "Please set a domain name:"
|
||||||
read -p "Input your domain here:" CF_Domain
|
read -p "Input your domain here: " CF_Domain
|
||||||
LOGD "Your domain name is set to:${CF_Domain}"
|
LOGD "Your domain name is set to: ${CF_Domain}"
|
||||||
|
|
||||||
|
# Set up Cloudflare API details
|
||||||
|
CF_GlobalKey=""
|
||||||
|
CF_AccountEmail=""
|
||||||
LOGD "Please set the API key:"
|
LOGD "Please set the API key:"
|
||||||
read -p "Input your key here:" CF_GlobalKey
|
read -p "Input your key here: " CF_GlobalKey
|
||||||
LOGD "Your API key is:${CF_GlobalKey}"
|
LOGD "Your API key is: ${CF_GlobalKey}"
|
||||||
|
|
||||||
LOGD "Please set up registered email:"
|
LOGD "Please set up registered email:"
|
||||||
read -p "Input your email here:" CF_AccountEmail
|
read -p "Input your email here: " CF_AccountEmail
|
||||||
LOGD "Your registered email address is:${CF_AccountEmail}"
|
LOGD "Your registered email address is: ${CF_AccountEmail}"
|
||||||
|
|
||||||
|
# Set the default CA to Let's Encrypt
|
||||||
~/.acme.sh/acme.sh --set-default-ca --server letsencrypt
|
~/.acme.sh/acme.sh --set-default-ca --server letsencrypt
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
LOGE "Default CA, Lets'Encrypt fail, script exiting..."
|
LOGE "Default CA, Let'sEncrypt fail, script exiting..."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
export CF_Key="${CF_GlobalKey}"
|
export CF_Key="${CF_GlobalKey}"
|
||||||
export CF_Email=${CF_AccountEmail}
|
export CF_Email="${CF_AccountEmail}"
|
||||||
|
|
||||||
|
# Issue the certificate using Cloudflare DNS
|
||||||
~/.acme.sh/acme.sh --issue --dns dns_cf -d ${CF_Domain} -d *.${CF_Domain} --log
|
~/.acme.sh/acme.sh --issue --dns dns_cf -d ${CF_Domain} -d *.${CF_Domain} --log
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
LOGE "Certificate issuance failed, script exiting..."
|
LOGE "Certificate issuance failed, script exiting..."
|
||||||
exit 1
|
exit 1
|
||||||
else
|
else
|
||||||
LOGI "Certificate issued Successfully, Installing..."
|
LOGI "Certificate issued successfully, Installing..."
|
||||||
fi
|
fi
|
||||||
~/.acme.sh/acme.sh --installcert -d ${CF_Domain} -d *.${CF_Domain} --ca-file /root/cert/ca.cer \
|
|
||||||
--cert-file /root/cert/${CF_Domain}.cer --key-file /root/cert/${CF_Domain}.key \
|
# Install the certificate
|
||||||
--fullchain-file /root/cert/fullchain.cer
|
mkdir -p ${certPath}/${CF_Domain}
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
LOGE "Failed to create directory: ${certPath}/${CF_Domain}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
~/.acme.sh/acme.sh --installcert -d ${CF_Domain} -d *.${CF_Domain} \
|
||||||
|
--fullchain-file ${certPath}/${CF_Domain}/fullchain.pem \
|
||||||
|
--key-file ${certPath}/${CF_Domain}/privkey.pem
|
||||||
|
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
LOGE "Certificate installation failed, script exiting..."
|
LOGE "Certificate installation failed, script exiting..."
|
||||||
exit 1
|
exit 1
|
||||||
else
|
else
|
||||||
LOGI "Certificate installed Successfully,Turning on automatic updates..."
|
LOGI "Certificate installed successfully, Turning on automatic updates..."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Enable auto-update
|
||||||
~/.acme.sh/acme.sh --upgrade --auto-upgrade
|
~/.acme.sh/acme.sh --upgrade --auto-upgrade
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
LOGE "Auto update setup Failed, script exiting..."
|
LOGE "Auto update setup failed, script exiting..."
|
||||||
ls -lah cert
|
|
||||||
chmod 755 $certPath
|
|
||||||
exit 1
|
exit 1
|
||||||
else
|
else
|
||||||
LOGI "The certificate is installed and auto-renewal is turned on, Specific information is as follows"
|
LOGI "The certificate is installed and auto-renewal is turned on. Specific information is as follows:"
|
||||||
ls -lah cert
|
ls -lah ${certPath}/${CF_Domain}
|
||||||
chmod 755 $certPath
|
chmod 755 ${certPath}/${CF_Domain}
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Prompt user to set panel paths after successful certificate installation
|
||||||
|
read -p "Would you like to set this certificate for the panel? (y/n): " setPanel
|
||||||
|
if [[ "$setPanel" == "y" || "$setPanel" == "Y" ]]; then
|
||||||
|
local webCertFile="${certPath}/${CF_Domain}/fullchain.pem"
|
||||||
|
local webKeyFile="${certPath}/${CF_Domain}/privkey.pem"
|
||||||
|
|
||||||
|
if [[ -f "$webCertFile" && -f "$webKeyFile" ]]; then
|
||||||
|
/usr/local/x-ui/x-ui cert -webCert "$webCertFile" -webCertKey "$webKeyFile"
|
||||||
|
LOGI "Panel paths set for domain: $CF_Domain"
|
||||||
|
LOGI " - Certificate File: $webCertFile"
|
||||||
|
LOGI " - Private Key File: $webKeyFile"
|
||||||
|
echo -e "${green}Access URL: https://${CF_Domain}:${existing_port}${existing_webBasePath}${plain}"
|
||||||
|
restart
|
||||||
|
else
|
||||||
|
LOGE "Error: Certificate or private key file not found for domain: $CF_Domain."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
LOGI "Skipping panel path setting."
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
show_menu
|
show_menu
|
||||||
|
|
Loading…
Reference in a new issue