mirror of
https://github.com/alireza0/x-ui.git
synced 2026-03-14 05:23:09 +00:00
v0.5.0
This commit is contained in:
6
.github/workflows/release.yml
vendored
6
.github/workflows/release.yml
vendored
@@ -8,7 +8,7 @@ on:
|
||||
jobs:
|
||||
linuxamd64build:
|
||||
name: build x-ui amd64 version
|
||||
runs-on: ubuntu-18.04
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up Go
|
||||
@@ -46,7 +46,7 @@ jobs:
|
||||
prerelease: true
|
||||
linuxarm64build:
|
||||
name: build x-ui arm64 version
|
||||
runs-on: ubuntu-18.04
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up Go
|
||||
@@ -86,7 +86,7 @@ jobs:
|
||||
prerelease: true
|
||||
linuxs390xbuild:
|
||||
name: build x-ui s390x version
|
||||
runs-on: ubuntu-18.04
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up Go
|
||||
|
||||
58
README.md
58
README.md
@@ -18,6 +18,8 @@ xray panel supporting multi-protocol, **Multi-lang (English,Farsi,Chinese)**
|
||||
| REST API | :heavy_check_mark: |
|
||||
| Telegram BOT (admin + clients) | :heavy_check_mark: |
|
||||
| Backup database using Telegram BOT | :heavy_check_mark: |
|
||||
| Subscription link | :heavy_check_mark: |
|
||||
| Calculate expire date on first usage | :heavy_check_mark: |
|
||||
|
||||
**If you think this project is helpful to you, you may wish to give a** :star2:
|
||||
|
||||
@@ -31,15 +33,44 @@ xray panel supporting multi-protocol, **Multi-lang (English,Farsi,Chinese)**
|
||||
- Support for configuring more transport configurations
|
||||
- Traffic statistics, limit traffic, limit expiration time
|
||||
- Customizable xray configuration templates
|
||||
- Support subscription ( multi ) link
|
||||
- Detect users which are expiring or exceed traffic limit soon
|
||||
- Support https access panel (self-provided domain name + ssl certificate)
|
||||
- Support one-click SSL certificate application and automatic renewal
|
||||
- For more advanced configuration items, please refer to the panel
|
||||
|
||||
## API routes
|
||||
<details>
|
||||
<summary>Click for details</summary>
|
||||
- `/login` with `PUSH` user data: `{username: '', password: ''}` for login
|
||||
- `/xui/API/inbounds` base for following actions:
|
||||
| Method | Path | Action |
|
||||
| :----- |:---------:| ------:|
|
||||
| GET | "/" | Get all inbounds |
|
||||
| GET | "/get/:id" | Get inbound with inbound.id |
|
||||
| POST | "/add" | Add inbound |
|
||||
| POST | "/del/:id" | Delete Inbound |
|
||||
| POST | "/update/:id" | Update Inbound |
|
||||
| POST | "/addClient/" | Add Client to inbound |
|
||||
| POST | "/delClient/:email" | Delete Client |
|
||||
| POST | "/updateClient/:index" | Update Client |
|
||||
| POST | "/:id/resetClientTraffic/:email" | Reset Client's Traffic |
|
||||
| POST | "/resetAllTraffics" | Reset traffics of all inbounds |
|
||||
| POST | "/resetAllClientTraffics/:id" | Reset traffics of all clients in an inbound |
|
||||
</details>
|
||||
|
||||
# Screenshot from Inbouds page
|
||||
|
||||

|
||||

|
||||
|
||||
## suggestion system
|
||||
|
||||
- CentOS 8+
|
||||
- Ubuntu 20+
|
||||
- Debian 8+
|
||||
- Fedora 36+
|
||||
|
||||
# Install & Upgrade to latest version
|
||||
|
||||
```
|
||||
@@ -100,6 +131,8 @@ docker build -t x-ui .
|
||||
```
|
||||
|
||||
## SSL certificate application
|
||||
<details>
|
||||
<summary>Click for details</summary>
|
||||
|
||||
### Cloudflare
|
||||
|
||||
@@ -114,8 +147,11 @@ ln -s /snap/bin/certbot /usr/bin/certbot
|
||||
|
||||
certbot certonly --standalone --register-unsafely-without-email --non-interactive --agree-tos -d <Your Domain Name>
|
||||
```
|
||||
</details>
|
||||
|
||||
## Tg robot use
|
||||
<details>
|
||||
<summary>Click for details</summary>
|
||||
|
||||
> This feature and tutorial are provided by [FranzKafkaYu](https://github.com/FranzKafkaYu)
|
||||
|
||||
@@ -133,6 +169,7 @@ Set the robot-related parameters in the panel background, including:
|
||||
Reference syntax:
|
||||
|
||||
- 30 * * * * * //Notify at the 30s of each point
|
||||
- 0 */10 * * * * //Notify at the first second of each 10 minutes
|
||||
- @hourly // hourly notification
|
||||
- @daily // Daily notification (00:00 in the morning)
|
||||
- @every 8h // notify every 8 hours
|
||||
@@ -143,26 +180,19 @@ Reference syntax:
|
||||
- Login notification
|
||||
- CPU threshold notification
|
||||
- Threshold for Expiration time and Traffic to report in advance
|
||||
- Support client report if client's telegram username is added to the end of `email` like 'test123@telegram_username'
|
||||
- Support client report menu if client's telegram username added to the user's configurations
|
||||
- Support telegram traffic report searched with UID (VMESS/VLESS) or Password (TROJAN) - anonymously
|
||||
- Menu based bot
|
||||
- Search client by email ( only admin )
|
||||
- Check all inbounds
|
||||
- Check server status
|
||||
- Check Exhausted users
|
||||
- Check depleted users
|
||||
- Receive backup by request and in periodic reports
|
||||
</details>
|
||||
|
||||
|
||||
|
||||
## suggestion system
|
||||
|
||||
- CentOS 7+
|
||||
- Ubuntu 16+
|
||||
- Debian 8+
|
||||
- Fedora 36+
|
||||
|
||||
# common problem
|
||||
|
||||
# Common problem
|
||||
<details>
|
||||
<summary>Click for details</summary>
|
||||
## Migrating from v2-ui
|
||||
|
||||
First install the latest version of x-ui on the server where v2-ui is installed, and then use the following command to migrate, which will migrate the native v2-ui `All inbound account data` to x-ui,`Panel settings and username passwords are not migrated`
|
||||
@@ -192,7 +222,6 @@ find this in config :
|
||||
},
|
||||
```
|
||||
|
||||
|
||||
**the final output is like :**
|
||||
```json
|
||||
"policy": {
|
||||
@@ -211,6 +240,7 @@ find this in config :
|
||||
"routing": {
|
||||
```
|
||||
restart panel
|
||||
</details>
|
||||
|
||||
# a special thanks to
|
||||
- [HexaSoftwareTech](https://github.com/HexaSoftwareTech/)
|
||||
|
||||
@@ -1 +1 @@
|
||||
0.4.3
|
||||
0.5.0
|
||||
12
install.sh
12
install.sh
@@ -8,7 +8,7 @@ plain='\033[0m'
|
||||
cur_dir=$(pwd)
|
||||
|
||||
# check root
|
||||
[[ $EUID -ne 0 ]] && echo -e "${red}Fatal error:${plain} Please run this script with root privilege \n " && exit 1
|
||||
[[ $EUID -ne 0 ]] && echo -e "${red}Fatal error: ${plain} Please run this script with root privilege \n " && exit 1
|
||||
|
||||
# Check OS and set release variable
|
||||
if [[ -f /etc/os-release ]]; then
|
||||
@@ -47,17 +47,17 @@ os_version=""
|
||||
os_version=$(grep -i version_id /etc/os-release | cut -d \" -f2 | cut -d . -f1)
|
||||
|
||||
if [[ "${release}" == "centos" ]]; then
|
||||
if [[ ${os_version} -lt 7 ]]; then
|
||||
echo -e "${red} Please use CentOS 7 or higher ${plain}\n" && exit 1
|
||||
if [[ ${os_version} -lt 8 ]]; then
|
||||
echo -e "${red} Please use CentOS 8 or higher ${plain}\n" && exit 1
|
||||
fi
|
||||
elif [[ "${release}" == "ubuntu" ]]; then
|
||||
if [[ ${os_version} -lt 18 ]]; then
|
||||
echo -e "${red}please use Ubuntu 18 or higher version!${plain}\n" && exit 1
|
||||
if [[ ${os_version} -lt 20 ]]; then
|
||||
echo -e "${red}please use Ubuntu 20 or higher version! ${plain}\n" && exit 1
|
||||
fi
|
||||
|
||||
elif [[ "${release}" == "fedora" ]]; then
|
||||
if [[ ${os_version} -lt 36 ]]; then
|
||||
echo -e "${red}please use Fedora 36 or higher version!${plain}\n" && exit 1
|
||||
echo -e "${red}please use Fedora 36 or higher version! ${plain}\n" && exit 1
|
||||
fi
|
||||
|
||||
elif [[ "${release}" == "debian" ]]; then
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 112 KiB After Width: | Height: | Size: 324 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 107 KiB After Width: | Height: | Size: 316 KiB |
@@ -1,14 +1,10 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
import "github.com/gin-gonic/gin"
|
||||
|
||||
type APIController struct {
|
||||
BaseController
|
||||
|
||||
inboundController *InboundController
|
||||
settingController *SettingController
|
||||
}
|
||||
|
||||
func NewAPIController(g *gin.RouterGroup) *APIController {
|
||||
@@ -26,6 +22,12 @@ func (a *APIController) initRouter(g *gin.RouterGroup) {
|
||||
g.POST("/add", a.addInbound)
|
||||
g.POST("/del/:id", a.delInbound)
|
||||
g.POST("/update/:id", a.updateInbound)
|
||||
g.POST("/addClient/", a.addInboundClient)
|
||||
g.POST("/delClient/:email", a.delInboundClient)
|
||||
g.POST("/updateClient/:index", a.updateInboundClient)
|
||||
g.POST("/:id/resetClientTraffic/:email", a.resetClientTraffic)
|
||||
g.POST("/resetAllTraffics", a.resetAllTraffics)
|
||||
g.POST("/resetAllClientTraffics/:id", a.resetAllClientTraffics)
|
||||
|
||||
a.inboundController = NewInboundController(g)
|
||||
}
|
||||
@@ -45,3 +47,21 @@ func (a *APIController) delInbound(c *gin.Context) {
|
||||
func (a *APIController) updateInbound(c *gin.Context) {
|
||||
a.inboundController.updateInbound(c)
|
||||
}
|
||||
func (a *APIController) addInboundClient(c *gin.Context) {
|
||||
a.inboundController.addInboundClient(c)
|
||||
}
|
||||
func (a *APIController) delInboundClient(c *gin.Context) {
|
||||
a.inboundController.delInboundClient(c)
|
||||
}
|
||||
func (a *APIController) updateInboundClient(c *gin.Context) {
|
||||
a.inboundController.updateInboundClient(c)
|
||||
}
|
||||
func (a *APIController) resetClientTraffic(c *gin.Context) {
|
||||
a.inboundController.resetClientTraffic(c)
|
||||
}
|
||||
func (a *APIController) resetAllTraffics(c *gin.Context) {
|
||||
a.inboundController.resetAllTraffics(c)
|
||||
}
|
||||
func (a *APIController) resetAllClientTraffics(c *gin.Context) {
|
||||
a.inboundController.resetAllClientTraffics(c)
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
<link rel="stylesheet" href="{{ .base_path }}assets/ant-design-vue@1.7.2/antd.min.css">
|
||||
<link rel="stylesheet" href="{{ .base_path }}assets/element-ui@2.15.0/theme-chalk/display.css">
|
||||
<link rel="stylesheet" href="{{ .base_path }}assets/css/custom.css?{{ .cur_ver }}">
|
||||
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
|
||||
<style>
|
||||
[v-cloak] {
|
||||
display: none;
|
||||
|
||||
@@ -173,7 +173,7 @@
|
||||
return this.clientsBulkModal.inbound;
|
||||
},
|
||||
get delayedExpireDays() {
|
||||
return this.clientsBulkModal.expiryTime < 0 ? this.clientsBulkModal.expiryTime / -84600000 : 0;
|
||||
return this.clientsBulkModal.expiryTime < 0 ? this.clientsBulkModal.expiryTime / -84600000 : 0;
|
||||
},
|
||||
set delayedExpireDays(days){
|
||||
this.clientsBulkModal.expiryTime = -84600000 * days;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
this.clients = this.getClients(this.inbound.protocol, this.inbound.settings);
|
||||
this.index = index === null ? this.clients.length : index;
|
||||
this.isExpired = isEdit ? this.inbound.isExpiry(this.index) : false;
|
||||
this.delayedStart = false;
|
||||
if (!isEdit){
|
||||
this.addClient(this.inbound.protocol, this.clients);
|
||||
} else {
|
||||
@@ -100,7 +101,7 @@
|
||||
else return 'red'
|
||||
},
|
||||
get delayedExpireDays() {
|
||||
return clientModal.isEdit && this.client.expiryTime < 0 ? this.client.expiryTime / -84600000 : 0;
|
||||
return this.client && this.client.expiryTime < 0 ? this.client.expiryTime / -84600000 : 0;
|
||||
},
|
||||
set delayedExpireDays(days){
|
||||
this.client.expiryTime = -84600000 * days;
|
||||
|
||||
@@ -104,11 +104,11 @@
|
||||
<table v-if="infoModal.clientSettings.subId + infoModal.clientSettings.tgId" style="margin-bottom: 10px;">
|
||||
<tr v-if="infoModal.clientSettings.subId">
|
||||
<td>Subscription link</td>
|
||||
<td><a :href="[[ infoModal.subBase + infoModal.clientSettings.subId ]]" target="_blank">[[ infoModal.subBase + infoModal.clientSettings.subId ]]</a></td>
|
||||
<td><a :href="[[ subBase + infoModal.clientSettings.subId ]]" target="_blank">[[ subBase + infoModal.clientSettings.subId ]]</a></td>
|
||||
</tr>
|
||||
<tr v-if="infoModal.clientSettings.tgId">
|
||||
<td>Telegram Username</td>
|
||||
<td><a :href="[[ infoModal.tgBase + infoModal.clientSettings.tgId ]]" target="_blank">@[[ infoModal.clientSettings.tgId ]]</a></td>
|
||||
<td><a :href="[[ tgBase + infoModal.clientSettings.tgId ]]" target="_blank">@[[ infoModal.clientSettings.tgId ]]</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
</template>
|
||||
@@ -192,8 +192,6 @@
|
||||
link: null,
|
||||
index: null,
|
||||
isExpired: false,
|
||||
subBase: window.location.protocol + "//" + window.location.hostname + "/sub/",
|
||||
tgBase: "https://t.me/",
|
||||
show(dbInbound, index) {
|
||||
this.index = index;
|
||||
this.inbound = dbInbound.toInbound();
|
||||
@@ -240,8 +238,13 @@
|
||||
return infoModal.clientSettings.enable;
|
||||
}
|
||||
return infoModal.dbInbound.isEnable;
|
||||
}
|
||||
|
||||
},
|
||||
get subBase() {
|
||||
return window.location.protocol + "//" + window.location.hostname + (window.location.port ? ":" + window.location.port:"") + "/sub/";
|
||||
},
|
||||
get tgBase() {
|
||||
return "https://t.me/"
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
copyTextToClipboard(elmentId,content) {
|
||||
|
||||
@@ -33,6 +33,9 @@ import (
|
||||
//go:embed assets/*
|
||||
var assetsFS embed.FS
|
||||
|
||||
//go:embed assets/favicon.ico
|
||||
var favicon []byte
|
||||
|
||||
//go:embed html/*
|
||||
var htmlFS embed.FS
|
||||
|
||||
@@ -159,7 +162,9 @@ func (s *Server) initRouter() (*gin.Engine, error) {
|
||||
engine := gin.Default()
|
||||
|
||||
// Add favicon
|
||||
engine.StaticFile("/favicon.ico", "web/assets/favicon.ico")
|
||||
engine.GET("/favicon.ico", func(c *gin.Context) {
|
||||
c.Data(200, "image/x-icon", favicon)
|
||||
})
|
||||
|
||||
secret, err := s.settingService.GetSecret()
|
||||
if err != nil {
|
||||
|
||||
10
x-ui.sh
10
x-ui.sh
@@ -39,17 +39,17 @@ os_version=""
|
||||
os_version=$(grep -i version_id /etc/os-release | cut -d \" -f2 | cut -d . -f1)
|
||||
|
||||
if [[ "${release}" == "centos" ]]; then
|
||||
if [[ ${os_version} -lt 7 ]]; then
|
||||
echo -e "${red} Please use CentOS 7 or higher ${plain}\n" && exit 1
|
||||
if [[ ${os_version} -lt 8 ]]; then
|
||||
echo -e "${red} Please use CentOS 8 or higher ${plain}\n" && exit 1
|
||||
fi
|
||||
elif [[ "${release}" == "ubuntu" ]]; then
|
||||
if [[ ${os_version} -lt 18 ]]; then
|
||||
echo -e "${red}please use Ubuntu 18 or higher version!${plain}\n" && exit 1
|
||||
if [[ ${os_version} -lt 20 ]]; then
|
||||
echo -e "${red}please use Ubuntu 20 or higher version! ${plain}\n" && exit 1
|
||||
fi
|
||||
|
||||
elif [[ "${release}" == "fedora" ]]; then
|
||||
if [[ ${os_version} -lt 36 ]]; then
|
||||
echo -e "${red}please use Fedora 36 or higher version!${plain}\n" && exit 1
|
||||
echo -e "${red}please use Fedora 36 or higher version! ${plain}\n" && exit 1
|
||||
fi
|
||||
|
||||
elif [[ "${release}" == "debian" ]]; then
|
||||
|
||||
Reference in New Issue
Block a user