This commit is contained in:
Alireza Ahmadi
2023-04-04 01:26:59 +02:00
parent 1246b54ffa
commit 357630b077
13 changed files with 103 additions and 43 deletions

View File

@@ -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

View File

@@ -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
![inbounds](./media/inbounds.png)
![Dark inbounds](./media/inbounds-dark.png)
## 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/)

View File

@@ -1 +1 @@
0.4.3
0.5.0

View File

@@ -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

View File

@@ -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)
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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
View File

@@ -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