Skip to content

Commit df352bf

Browse files
author
dev0xz02
committed
merge: sync upstream features, fix imports, and pin gvisor
2 parents de5bcb0 + 159b85f commit df352bf

44 files changed

Lines changed: 1700 additions & 407 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/copilot-instructions.md

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
# 3X-UI Development Guide
2+
3+
## Project Overview
4+
3X-UI is a web-based control panel for managing Xray-core servers. It's a Go application using Gin web framework with embedded static assets and SQLite database. The panel manages VPN/proxy inbounds, monitors traffic, and provides Telegram bot integration.
5+
6+
## Architecture
7+
8+
### Core Components
9+
- **main.go**: Entry point that initializes database, web server, and subscription server. Handles graceful shutdown via SIGHUP/SIGTERM signals
10+
- **web/**: Primary web server with Gin router, HTML templates, and static assets embedded via `//go:embed`
11+
- **xray/**: Xray-core process management and API communication for traffic monitoring
12+
- **database/**: GORM-based SQLite database with models in `database/model/`
13+
- **sub/**: Subscription server running alongside main web server (separate port)
14+
- **web/service/**: Business logic layer containing InboundService, SettingService, TgBot, etc.
15+
- **web/controller/**: HTTP handlers using Gin context (`*gin.Context`)
16+
- **web/job/**: Cron-based background jobs for traffic monitoring, CPU checks, LDAP sync
17+
18+
### Key Architectural Patterns
19+
1. **Embedded Resources**: All web assets (HTML, CSS, JS, translations) are embedded at compile time using `embed.FS`:
20+
- `web/assets``assetsFS`
21+
- `web/html``htmlFS`
22+
- `web/translation``i18nFS`
23+
24+
2. **Dual Server Design**: Main web panel + subscription server run concurrently, managed by `web/global` package
25+
26+
3. **Xray Integration**: Panel generates `config.json` for Xray binary, communicates via gRPC API for real-time traffic stats
27+
28+
4. **Signal-Based Restart**: SIGHUP triggers graceful restart. **Critical**: Always call `service.StopBot()` before restart to prevent Telegram bot 409 conflicts
29+
30+
5. **Database Seeders**: Uses `HistoryOfSeeders` model to track one-time migrations (e.g., password bcrypt migration)
31+
32+
## Development Workflows
33+
34+
### Building & Running
35+
```bash
36+
# Build (creates bin/3x-ui.exe)
37+
go run tasks.json → "go: build" task
38+
39+
# Run with debug logging
40+
XUI_DEBUG=true go run ./main.go
41+
# Or use task: "go: run"
42+
43+
# Test
44+
go test ./...
45+
```
46+
47+
### Command-Line Operations
48+
The main.go accepts flags for admin tasks:
49+
- `-reset` - Reset all panel settings to defaults
50+
- `-show` - Display current settings (port, paths)
51+
- Use these by running the binary directly, not via web interface
52+
53+
### Database Management
54+
- DB path: Configured via `config.GetDBPath()`, typically `/etc/x-ui/x-ui.db`
55+
- Models: Located in `database/model/model.go` - Auto-migrated on startup
56+
- Seeders: Use `HistoryOfSeeders` to prevent re-running migrations
57+
- Default credentials: admin/admin (hashed with bcrypt)
58+
59+
### Telegram Bot Development
60+
- Bot instance in `web/service/tgbot.go` (3700+ lines)
61+
- Uses `telego` library with long polling
62+
- **Critical Pattern**: Must call `service.StopBot()` before any server restart to prevent 409 bot conflicts
63+
- Bot handlers use `telegohandler.BotHandler` for routing
64+
- i18n via embedded `i18nFS` passed to bot startup
65+
66+
## Code Conventions
67+
68+
### Service Layer Pattern
69+
Services inject dependencies (like xray.XrayAPI) and operate on GORM models:
70+
```go
71+
type InboundService struct {
72+
xrayApi xray.XrayAPI
73+
}
74+
75+
func (s *InboundService) GetInbounds(userId int) ([]*model.Inbound, error) {
76+
// Business logic here
77+
}
78+
```
79+
80+
### Controller Pattern
81+
Controllers use Gin context and inherit from BaseController:
82+
```go
83+
func (a *InboundController) getInbounds(c *gin.Context) {
84+
// Use I18nWeb(c, "key") for translations
85+
// Check auth via checkLogin middleware
86+
}
87+
```
88+
89+
### Configuration Management
90+
- Environment vars: `XUI_DEBUG`, `XUI_LOG_LEVEL`, `XUI_MAIN_FOLDER`
91+
- Config embedded files: `config/version`, `config/name`
92+
- Use `config.GetLogLevel()`, `config.GetDBPath()` helpers
93+
94+
### Internationalization
95+
- Translation files: `web/translation/translate.*.toml`
96+
- Access via `I18nWeb(c, "pages.login.loginAgain")` in controllers
97+
- Use `locale.I18nType` enum (Web, Api, etc.)
98+
99+
## External Dependencies & Integration
100+
101+
### Xray-core
102+
- Binary management: Download platform-specific binary (`xray-{os}-{arch}`) to bin folder
103+
- Config generation: Panel creates `config.json` dynamically from inbound/outbound settings
104+
- Process control: Start/stop via `xray/process.go`
105+
- gRPC API: Real-time stats via `xray/api.go` using `google.golang.org/grpc`
106+
107+
### Critical External Paths
108+
- Xray binary: `{bin_folder}/xray-{os}-{arch}`
109+
- Xray config: `{bin_folder}/config.json`
110+
- GeoIP/GeoSite: `{bin_folder}/geoip.dat`, `geosite.dat`
111+
- Logs: `{log_folder}/3xipl.log`, `3xipl-banned.log`
112+
113+
### Job Scheduling
114+
Uses `robfig/cron/v3` for periodic tasks:
115+
- Traffic monitoring: `xray_traffic_job.go`
116+
- CPU alerts: `check_cpu_usage.go`
117+
- IP tracking: `check_client_ip_job.go`
118+
- LDAP sync: `ldap_sync_job.go`
119+
120+
Jobs registered in `web/web.go` during server initialization
121+
122+
## Deployment & Scripts
123+
124+
### Installation Script Pattern
125+
Both `install.sh` and `x-ui.sh` follow these patterns:
126+
- Multi-distro support via `$release` variable (ubuntu, debian, centos, arch, etc.)
127+
- Port detection with `is_port_in_use()` using ss/netstat/lsof
128+
- Systemd service management with distro-specific unit files (`.service.debian`, `.service.arch`, `.service.rhel`)
129+
130+
### Docker Build
131+
Multi-stage Dockerfile:
132+
1. **Builder**: CGO-enabled build, runs `DockerInit.sh` to download Xray binary
133+
2. **Final**: Alpine-based with fail2ban pre-configured
134+
135+
### Key File Locations (Production)
136+
- Binary: `/usr/local/x-ui/`
137+
- Database: `/etc/x-ui/x-ui.db`
138+
- Logs: `/var/log/x-ui/`
139+
- Service: `/etc/systemd/system/x-ui.service.*`
140+
141+
## Testing & Debugging
142+
- Set `XUI_DEBUG=true` for detailed logging
143+
- Check Xray process: `x-ui.sh` script provides menu for status/logs
144+
- Database inspection: Direct SQLite access to x-ui.db
145+
- Traffic debugging: Check `3xipl.log` for IP limit tracking
146+
- Telegram bot: Logs show bot initialization and command handling
147+
148+
## Common Gotchas
149+
1. **Bot Restart**: Always stop Telegram bot before server restart to avoid 409 conflict
150+
2. **Embedded Assets**: Changes to HTML/CSS require recompilation (not hot-reload)
151+
3. **Password Migration**: Seeder system tracks bcrypt migration - check `HistoryOfSeeders` table
152+
4. **Port Binding**: Subscription server uses different port from main panel
153+
5. **Xray Binary**: Must match OS/arch exactly - managed by installer scripts
154+
6. **Session Management**: Uses `gin-contrib/sessions` with cookie store
155+
7. **IP Limitation**: Implements "last IP wins" - when client exceeds LimitIP, oldest connections are automatically disconnected via Xray API to allow newest IPs

DockerInit.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ case $1 in
2727
esac
2828
mkdir -p build/bin
2929
cd build/bin
30-
curl -sfLRO "https://github.com/XTLS/Xray-core/releases/download/v26.2.2/Xray-linux-${ARCH}.zip"
30+
curl -sfLRO "https://github.com/XTLS/Xray-core/releases/download/v26.2.6/Xray-linux-${ARCH}.zip"
3131
unzip "Xray-linux-${ARCH}.zip"
3232
rm -f "Xray-linux-${ARCH}.zip" geoip.dat geosite.dat
3333
mv xray "xray-linux-${FNAME}"

go.mod

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,32 @@
1-
module github.com/hxehex/4y-ui/v2
1+
module github.com/hxehex/4y-ui
22

3-
go 1.25.6
3+
go 1.26.0
44

55
require (
66
github.com/gin-contrib/gzip v1.2.5
77
github.com/gin-contrib/sessions v1.0.4
8-
github.com/gin-gonic/gin v1.11.0
8+
github.com/gin-gonic/gin v1.12.0
99
github.com/go-ldap/ldap/v3 v3.4.12
1010
github.com/goccy/go-json v0.10.5
1111
github.com/google/uuid v1.6.0
1212
github.com/gorilla/websocket v1.5.3
13+
github.com/hxehex/4y-ui/v2 v2.0.0-20260301120326-de5bcb05dd52
1314
github.com/joho/godotenv v1.5.1
14-
github.com/mymmrac/telego v1.5.0
15+
github.com/mymmrac/telego v1.6.0
1516
github.com/nicksnyder/go-i18n/v2 v2.6.1
1617
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
1718
github.com/pelletier/go-toml/v2 v2.2.4
1819
github.com/robfig/cron/v3 v3.0.1
19-
github.com/shirou/gopsutil/v4 v4.26.1
20+
github.com/shirou/gopsutil/v4 v4.26.2
2021
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
2122
github.com/valyala/fasthttp v1.69.0
2223
github.com/xlzd/gotp v0.1.0
23-
github.com/xtls/xray-core v1.260202.0
24+
github.com/xtls/xray-core v1.260206.0
2425
go.uber.org/atomic v1.11.0
25-
golang.org/x/crypto v0.47.0
26-
golang.org/x/sys v0.40.0
27-
golang.org/x/text v0.33.0
28-
google.golang.org/grpc v1.78.0
26+
golang.org/x/crypto v0.48.0
27+
golang.org/x/sys v0.41.0
28+
golang.org/x/text v0.34.0
29+
google.golang.org/grpc v1.79.1
2930
gorm.io/driver/sqlite v1.6.0
3031
gorm.io/gorm v1.31.1
3132
)
@@ -39,7 +40,7 @@ require (
3940
github.com/bytedance/sonic/loader v0.5.0 // indirect
4041
github.com/cloudflare/circl v1.6.3 // indirect
4142
github.com/cloudwego/base64x v0.1.6 // indirect
42-
github.com/ebitengine/purego v0.9.1 // indirect
43+
github.com/ebitengine/purego v0.10.0 // indirect
4344
github.com/gabriel-vasile/mimetype v1.4.13 // indirect
4445
github.com/gin-contrib/sse v1.1.0 // indirect
4546
github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667 // indirect
@@ -57,44 +58,44 @@ require (
5758
github.com/jinzhu/now v1.1.5 // indirect
5859
github.com/json-iterator/go v1.1.12 // indirect
5960
github.com/juju/ratelimit v1.0.2 // indirect
60-
github.com/klauspost/compress v1.18.3 // indirect
61+
github.com/klauspost/compress v1.18.4 // indirect
6162
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
6263
github.com/leodido/go-urn v1.4.0 // indirect
63-
github.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3 // indirect
64+
github.com/lufia/plan9stats v0.0.0-20260216142805-b3301c5f2a88 // indirect
6465
github.com/mattn/go-isatty v0.0.20 // indirect
65-
github.com/mattn/go-sqlite3 v1.14.33 // indirect
66+
github.com/mattn/go-sqlite3 v1.14.34 // indirect
6667
github.com/miekg/dns v1.1.72 // indirect
6768
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
6869
github.com/modern-go/reflect2 v1.0.2 // indirect
69-
github.com/pires/go-proxyproto v0.9.2 // indirect
70+
github.com/pires/go-proxyproto v0.11.0 // indirect
7071
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
7172
github.com/quic-go/qpack v0.6.0 // indirect
7273
github.com/quic-go/quic-go v0.59.0 // indirect
7374
github.com/refraction-networking/utls v1.8.2 // indirect
74-
github.com/rogpeppe/go-internal v1.14.1 // indirect
75-
github.com/sagernet/sing v0.7.18 // indirect
75+
github.com/sagernet/sing v0.8.0 // indirect
7676
github.com/sagernet/sing-shadowsocks v0.2.9 // indirect
7777
github.com/tklauser/go-sysconf v0.3.16 // indirect
7878
github.com/tklauser/numcpus v0.11.0 // indirect
7979
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
8080
github.com/ugorji/go/codec v1.3.1 // indirect
8181
github.com/valyala/bytebufferpool v1.0.0 // indirect
82-
github.com/valyala/fastjson v1.6.7 // indirect
82+
github.com/valyala/fastjson v1.6.10 // indirect
8383
github.com/vishvananda/netlink v1.3.1 // indirect
8484
github.com/vishvananda/netns v0.0.5 // indirect
8585
github.com/xtls/reality v0.0.0-20251116175510-cd53f7d50237 // indirect
8686
github.com/yusufpapurcu/wmi v1.2.4 // indirect
87+
go.mongodb.org/mongo-driver/v2 v2.5.0 // indirect
8788
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect
88-
golang.org/x/arch v0.23.0 // indirect
89-
golang.org/x/exp v0.0.0-20260112195511-716be5621a96 // indirect
90-
golang.org/x/mod v0.32.0 // indirect
91-
golang.org/x/net v0.49.0 // indirect
89+
golang.org/x/arch v0.24.0 // indirect
90+
golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa // indirect
91+
golang.org/x/mod v0.33.0 // indirect
92+
golang.org/x/net v0.51.0 // indirect
9293
golang.org/x/sync v0.19.0 // indirect
9394
golang.org/x/time v0.14.0 // indirect
94-
golang.org/x/tools v0.41.0 // indirect
95+
golang.org/x/tools v0.42.0 // indirect
9596
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
9697
golang.zx2c4.com/wireguard v0.0.0-20250521234502-f333402bd9cb // indirect
97-
google.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409 // indirect
98+
google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 // indirect
9899
google.golang.org/protobuf v1.36.11 // indirect
99100
gvisor.dev/gvisor v0.0.0-20260122175437-89a5d21be8f0 // indirect
100101
lukechampine.com/blake3 v1.4.1 // indirect

0 commit comments

Comments
 (0)