Import x-panel source
14
.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: xeefei
|
||||
patreon: # Replace with a single Patreon username
|
||||
open_collective: # Replace with a single Open Collective username
|
||||
ko_fi: # Replace with a single Ko-fi username
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
liberapay: # Replace with a single Liberapay username
|
||||
issuehunt: # Replace with a single IssueHunt username
|
||||
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
|
||||
polar: # Replace with a single Polar username
|
||||
buy_me_a_coffee: xeefeiz
|
||||
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
||||
77
.github/ISSUE_TEMPLATE/bug_report.yaml
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
name: Bug report
|
||||
description: Create a report to help us improve
|
||||
title: "Bug report"
|
||||
labels: ["bug"]
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thank you for reporting a bug! Please fill out the following information.
|
||||
|
||||
- type: textarea
|
||||
id: what-happened
|
||||
attributes:
|
||||
label: Describe the bug
|
||||
description: A clear and concise description of what the bug is.
|
||||
placeholder: My problem is...
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: how-repeat-problem
|
||||
attributes:
|
||||
label: How to repeat the problem?
|
||||
description: Sequence of actions that allow you to reproduce the bug
|
||||
placeholder: |
|
||||
1. Open `Inbounds` page
|
||||
2. ...
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: expected-action
|
||||
attributes:
|
||||
label: Expected action
|
||||
description: What's going to happen
|
||||
placeholder: Must be...
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: textarea
|
||||
id: received-action
|
||||
attributes:
|
||||
label: Received action
|
||||
description: What's really happening
|
||||
placeholder: It's actually happening...
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: input
|
||||
id: xui-version
|
||||
attributes:
|
||||
label: x-panel Version
|
||||
description: Which version of x-panel are you using?
|
||||
placeholder: 2.X.X
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: xray-version
|
||||
attributes:
|
||||
label: Xray-core Version
|
||||
description: Which version of Xray-core are you using?
|
||||
placeholder: 2.X.X
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: checkboxes
|
||||
id: checklist
|
||||
attributes:
|
||||
label: Checklist
|
||||
description: Please check all the checkboxes
|
||||
options:
|
||||
- label: This bug report is written entirely in English.
|
||||
required: true
|
||||
- label: This bug report is new and no one has reported it before me.
|
||||
required: true
|
||||
39
.github/ISSUE_TEMPLATE/feature_request.yaml
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
name: Feature request
|
||||
description: Suggest an idea for this project
|
||||
title: "Feature request"
|
||||
labels: ["enhancement"]
|
||||
|
||||
body:
|
||||
- type: textarea
|
||||
id: is-related-problem
|
||||
attributes:
|
||||
label: Is your feature request related to a problem?
|
||||
description: A clear and concise description of what the problem is.
|
||||
placeholder: I'm always frustrated when...
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: solution
|
||||
attributes:
|
||||
label: Describe the solution you'd like
|
||||
description: A clear and concise description of what you want to happen.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: alternatives
|
||||
attributes:
|
||||
label: Describe alternatives you've considered
|
||||
description: A clear and concise description of any alternative solutions or features you've considered.
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: checkboxes
|
||||
id: checklist
|
||||
attributes:
|
||||
label: Checklist
|
||||
description: Please check all the checkboxes
|
||||
options:
|
||||
- label: This feature report is written entirely in English.
|
||||
required: true
|
||||
22
.github/ISSUE_TEMPLATE/question.yaml
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
name: Question
|
||||
description: Describe this issue template's purpose here.
|
||||
title: "Question"
|
||||
labels: ["question"]
|
||||
|
||||
body:
|
||||
- type: textarea
|
||||
id: question
|
||||
attributes:
|
||||
label: Question
|
||||
placeholder: I have a question, ..., how can I solve it?
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: checkboxes
|
||||
id: checklist
|
||||
attributes:
|
||||
label: Checklist
|
||||
description: Please check all the checkboxes
|
||||
options:
|
||||
- label: This question is written entirely in English.
|
||||
required: true
|
||||
20
.github/pull_request_template.yml
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
## What is the pull request?
|
||||
|
||||
<!-- Briefly describe the changes introduced by this pull request -->
|
||||
|
||||
## Which part of the application is affected by the change?
|
||||
|
||||
- [ ] Frontend
|
||||
- [ ] Backend
|
||||
|
||||
## Type of Changes
|
||||
|
||||
- [ ] Bug fix
|
||||
- [ ] New feature
|
||||
- [ ] Refactoring
|
||||
- [ ] Other
|
||||
|
||||
## Screenshots
|
||||
|
||||
<!-- Add screenshots to illustrate the changes -->
|
||||
<!-- Remove this section if it is not applicable. -->
|
||||
40
.gitignore
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
# Ignore editor and IDE settings
|
||||
.idea/
|
||||
.vscode/
|
||||
.cache/
|
||||
.sync*
|
||||
|
||||
# Ignore log files
|
||||
*.log
|
||||
|
||||
# Ignore temporary files
|
||||
tmp/
|
||||
*.tar.gz
|
||||
|
||||
# Ignore build and distribution directories
|
||||
backup/
|
||||
bin/
|
||||
dist/
|
||||
release/
|
||||
node_modules/
|
||||
|
||||
# Ignore compiled binaries
|
||||
main
|
||||
|
||||
# Ignore script and executable files
|
||||
/release.sh
|
||||
/x-ui
|
||||
|
||||
# Ignore OS specific files
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Ignore Go build files
|
||||
*.exe
|
||||
x-ui.db
|
||||
|
||||
# Ignore Docker specific files
|
||||
docker-compose.override.yml
|
||||
|
||||
# Ignore .env (Environment Variables) file
|
||||
.env
|
||||
7
DockerEntrypoint.sh
Normal file
@@ -0,0 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Start fail2ban
|
||||
[ $XUI_ENABLE_FAIL2BAN == "true" ] && fail2ban-client -x start
|
||||
|
||||
# Run x-ui
|
||||
exec /app/x-ui
|
||||
40
DockerInit.sh
Executable file
@@ -0,0 +1,40 @@
|
||||
#!/bin/sh
|
||||
case $1 in
|
||||
amd64)
|
||||
ARCH="64"
|
||||
FNAME="amd64"
|
||||
;;
|
||||
i386)
|
||||
ARCH="32"
|
||||
FNAME="i386"
|
||||
;;
|
||||
armv8 | arm64 | aarch64)
|
||||
ARCH="arm64-v8a"
|
||||
FNAME="arm64"
|
||||
;;
|
||||
armv7 | arm | arm32)
|
||||
ARCH="arm32-v7a"
|
||||
FNAME="arm32"
|
||||
;;
|
||||
armv6)
|
||||
ARCH="arm32-v6"
|
||||
FNAME="armv6"
|
||||
;;
|
||||
*)
|
||||
ARCH="64"
|
||||
FNAME="amd64"
|
||||
;;
|
||||
esac
|
||||
mkdir -p build/bin
|
||||
cd build/bin
|
||||
curl -sfLRO "https://github.com/XTLS/Xray-core/releases/download/v26.4.17/Xray-linux-${ARCH}.zip"
|
||||
unzip "Xray-linux-${ARCH}.zip"
|
||||
rm -f "Xray-linux-${ARCH}.zip" geoip.dat geosite.dat
|
||||
mv xray "xray-linux-${FNAME}"
|
||||
wget -q https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat
|
||||
wget -q https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat
|
||||
wget -q -O geoip_IR.dat https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geoip.dat
|
||||
wget -q -O geosite_IR.dat https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geosite.dat
|
||||
wget -q -O geoip_RU.dat https://github.com/runetfreedom/russia-v2ray-rules-dat/releases/latest/download/geoip.dat
|
||||
wget -q -O geosite_RU.dat https://github.com/runetfreedom/russia-v2ray-rules-dat/releases/latest/download/geosite.dat
|
||||
cd ../../
|
||||
54
Dockerfile
Normal file
@@ -0,0 +1,54 @@
|
||||
# ========================================================
|
||||
# ----->> Stage: Builder
|
||||
# ========================================================
|
||||
FROM golang:1.26-alpine AS builder
|
||||
WORKDIR /app
|
||||
ARG TARGETARCH
|
||||
|
||||
RUN apk --no-cache --update add \
|
||||
build-base \
|
||||
gcc \
|
||||
wget \
|
||||
unzip
|
||||
|
||||
COPY . .
|
||||
|
||||
ENV CGO_ENABLED=1
|
||||
ENV CGO_CFLAGS="-D_LARGEFILE64_SOURCE"
|
||||
RUN go build -ldflags "-w -s" -o build/x-ui main.go
|
||||
RUN ./DockerInit.sh "$TARGETARCH"
|
||||
|
||||
# ========================================================
|
||||
# ----->> Stage: Final Image of X-Panel
|
||||
# ========================================================
|
||||
FROM alpine
|
||||
ENV TZ=Asia/Tehran
|
||||
WORKDIR /app
|
||||
|
||||
RUN apk add --no-cache --update \
|
||||
ca-certificates \
|
||||
tzdata \
|
||||
fail2ban \
|
||||
bash
|
||||
|
||||
COPY --from=builder /app/build/ /app/
|
||||
COPY --from=builder /app/DockerEntrypoint.sh /app/
|
||||
COPY --from=builder /app/x-ui.sh /usr/bin/x-ui
|
||||
|
||||
|
||||
# Configure fail2ban
|
||||
RUN rm -f /etc/fail2ban/jail.d/alpine-ssh.conf \
|
||||
&& cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local \
|
||||
&& sed -i "s/^\[ssh\]$/&\nenabled = false/" /etc/fail2ban/jail.local \
|
||||
&& sed -i "s/^\[sshd\]$/&\nenabled = false/" /etc/fail2ban/jail.local \
|
||||
&& sed -i "s/#allowipv6 = auto/allowipv6 = auto/g" /etc/fail2ban/fail2ban.conf
|
||||
|
||||
RUN chmod +x \
|
||||
/app/DockerEntrypoint.sh \
|
||||
/app/x-ui \
|
||||
/usr/bin/x-ui
|
||||
|
||||
ENV XUI_ENABLE_FAIL2BAN="true"
|
||||
VOLUME [ "/etc/x-ui" ]
|
||||
CMD [ "./x-ui" ]
|
||||
ENTRYPOINT [ "/app/DockerEntrypoint.sh" ]
|
||||
674
LICENSE
Normal file
@@ -0,0 +1,674 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed...
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
||||
56
README.ar_EG.md
Normal file
@@ -0,0 +1,56 @@
|
||||
[English](/README.md) | [فارسی](/README.fa_IR.md) | [العربية](/README.ar_EG.md) | [中文](/README.zh_CN.md) | [Español](/README.es_ES.md) | [Русский](/README.ru_RU.md)
|
||||
|
||||
<p align="center">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="./media/X-Panel.png">
|
||||
<img alt="3x-ui" src="./media/X-Panel.png">
|
||||
</picture>
|
||||
</p>
|
||||
|
||||
[](https://github.com/xeefei/x-panel/releases)
|
||||
[](https://github.com/xeefei/x-panel/actions)
|
||||
[](#)
|
||||
[](https://github.com/xeefei/x-panel/releases/latest)
|
||||
[](https://www.gnu.org/licenses/gpl-3.0.en.html)
|
||||
|
||||
**3X-UI** — لوحة تحكم متقدمة مفتوحة المصدر تعتمد على الويب مصممة لإدارة خادم Xray-core. توفر واجهة سهلة الاستخدام لتكوين ومراقبة بروتوكولات VPN والوكيل المختلفة.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> هذا المشروع مخصص للاستخدام الشخصي والاتصال فقط، يرجى عدم استخدامه لأغراض غير قانونية، يرجى عدم استخدامه في بيئة الإنتاج.
|
||||
|
||||
كمشروع محسن من مشروع X-UI الأصلي، يوفر 3X-UI استقرارًا محسنًا ودعمًا أوسع للبروتوكولات وميزات إضافية.
|
||||
|
||||
## البدء السريع
|
||||
|
||||
```
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/xeefei/x-panel/master/install.sh)
|
||||
```
|
||||
|
||||
للحصول على الوثائق الكاملة، يرجى زيارة [ويكي المشروع](https://github.com/xeefei/x-panel/wiki).
|
||||
|
||||
## شكر خاص إلى
|
||||
|
||||
- [alireza0](https://github.com/alireza0/)
|
||||
|
||||
## الاعتراف
|
||||
|
||||
- [Iran v2ray rules](https://github.com/chocolate4u/Iran-v2ray-rules) (الترخيص: **GPL-3.0**): _قواعد توجيه v2ray/xray و v2ray/xray-clients المحسنة مع النطاقات الإيرانية المدمجة وتركيز على الأمان وحظر الإعلانات._
|
||||
- [Russia v2ray rules](https://github.com/runetfreedom/russia-v2ray-rules-dat) (الترخيص: **GPL-3.0**): _يحتوي هذا المستودع على قواعد توجيه V2Ray محدثة تلقائيًا بناءً على بيانات النطاقات والعناوين المحظورة في روسيا._
|
||||
|
||||
## دعم المشروع
|
||||
|
||||
**إذا كان هذا المشروع مفيدًا لك، فقد ترغب في إعطائه**:star2:
|
||||
|
||||
<p align="left">
|
||||
<a href="https://buymeacoffee.com/mhsanaei" target="_blank">
|
||||
<img src="./media/buymeacoffe.png" alt="Image">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
- USDT (TRC20): `TXncxkvhkDWGts487Pjqq1qT9JmwRUz8CC`
|
||||
- POL (polygon): `0x41C9548675D044c6Bfb425786C765bc37427256A`
|
||||
- LTC (Litecoin): `ltc1q2ach7x6d2zq0n4l0t4zl7d7xe2s6fs7a3vspwv`
|
||||
|
||||
## النجوم عبر الزمن
|
||||
|
||||
[](https://starchart.cc/xeefei/x-panel)
|
||||
502
README.es_ES.md
Normal file
@@ -0,0 +1,502 @@
|
||||
[English](/README.md) | [Chinese](/README.zh.md) | [Español](/README.es_ES.md)
|
||||
|
||||
<p align="center"><a href="#"><img src="./media/X-Panel.png" alt="Image"></a></p>
|
||||
|
||||
**Un Panel Web Avanzado • Construido sobre Xray Core**
|
||||
|
||||
[](https://github.com/xeefei/x-panel/releases)
|
||||
[](#)
|
||||
[](#)
|
||||
[](#)
|
||||
[](https://www.gnu.org/licenses/gpl-3.0.en.html)
|
||||
|
||||
> **Descargo de responsabilidad:** Este proyecto es solo para aprendizaje personal y comunicación, por favor no lo uses con fines ilegales, por favor no lo uses en un entorno de producción
|
||||
|
||||
**Si este proyecto te es útil, podrías considerar darle una**:star2:
|
||||
|
||||
<p align="left">
|
||||
<a href="https://buymeacoffee.com/xeefeiz" target="_blank">
|
||||
<img src="./media/buymeacoffe.png" alt="Image">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
- Sponsorship Address (USDT):
|
||||
- TRC20 ---->>> `TYQEmQp1P65u9bG7KPehgJdvuokfb72YkZ`
|
||||
- Polygon ---->>> `0xd20eBE429c2398793178e015B2ca1Dc42601f3Eb`
|
||||
- Solana ---->>> `7qVEZuV98QTDN5qUmsFwvqTSvkYpmLtNf8o1sh1mppwR`
|
||||
- BSC/BEP20 ---->>> `0xd20eBE429c2398793178e015B2ca1Dc42601f3Eb`
|
||||
|
||||
## Instalar y Actualizar
|
||||
|
||||
```
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/xeefei/x-panel/master/install.sh)
|
||||
```
|
||||
|
||||
## Instalar una Versión Personalizada
|
||||
|
||||
Para instalar la versión deseada, agrega la versión al final del comando de instalación. Por ejemplo, ver `v2.4.1`:
|
||||
|
||||
```
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/xeefei/x-panel/master/install.sh) v2.4.1
|
||||
```
|
||||
|
||||
## Certificado SSL
|
||||
|
||||
<details>
|
||||
<summary>Haz clic para el Certificado SSL</summary>
|
||||
|
||||
### Cloudflare
|
||||
|
||||
El script de gestión tiene una aplicación de certificado SSL incorporada para Cloudflare. Para usar este script para colocar un certificado, necesitas lo siguiente:
|
||||
|
||||
- Correo electrónico registrado en Cloudflare
|
||||
- Clave Global de API de Cloudflare
|
||||
- El nombre de dominio se ha resuelto en el servidor actual a través de Cloudflare
|
||||
|
||||
**1:** Ejecuta el comando`x-ui`en la terminal, luego elige `Certificado SSL de Cloudflare`.
|
||||
|
||||
|
||||
### Certbot
|
||||
```
|
||||
apt-get install certbot -y
|
||||
certbot certonly --standalone --agree-tos --register-unsafely-without-email -d yourdomain.com
|
||||
certbot renew --dry-run
|
||||
```
|
||||
|
||||
***Consejo:*** *Certbot también está integrado en el script de gestión. Puedes ejecutar el comando `x-ui` , luego elegir `Gestión de Certificados SSL`.*
|
||||
|
||||
</details>
|
||||
|
||||
## Instalación y Actualización Manual
|
||||
|
||||
<details>
|
||||
<summary>Haz clic para más detalles de la instalación manual</summary>
|
||||
|
||||
#### Uso
|
||||
|
||||
1. Para descargar la última versión del paquete comprimido directamente en tu servidor, ejecuta el siguiente comando:
|
||||
|
||||
```sh
|
||||
ARCH=$(uname -m)
|
||||
case "${ARCH}" in
|
||||
x86_64 | x64 | amd64) XUI_ARCH="amd64" ;;
|
||||
i*86 | x86) XUI_ARCH="386" ;;
|
||||
armv8* | armv8 | arm64 | aarch64) XUI_ARCH="arm64" ;;
|
||||
armv7* | armv7) XUI_ARCH="armv7" ;;
|
||||
armv6* | armv6) XUI_ARCH="armv6" ;;
|
||||
armv5* | armv5) XUI_ARCH="armv5" ;;
|
||||
*) XUI_ARCH="amd64" ;;
|
||||
esac
|
||||
|
||||
|
||||
wget https://github.com/xeefei/x-panel/releases/latest/download/x-ui-linux-${XUI_ARCH}.tar.gz
|
||||
```
|
||||
|
||||
2. Una vez que se haya descargado el paquete comprimido, ejecuta los siguientes comandos para instalar o actualizar x-ui:
|
||||
|
||||
```sh
|
||||
ARCH=$(uname -m)
|
||||
case "${ARCH}" in
|
||||
x86_64 | x64 | amd64) XUI_ARCH="amd64" ;;
|
||||
i*86 | x86) XUI_ARCH="386" ;;
|
||||
armv8* | armv8 | arm64 | aarch64) XUI_ARCH="arm64" ;;
|
||||
armv7* | armv7) XUI_ARCH="armv7" ;;
|
||||
armv6* | armv6) XUI_ARCH="armv6" ;;
|
||||
armv5* | armv5) XUI_ARCH="armv5" ;;
|
||||
*) XUI_ARCH="amd64" ;;
|
||||
esac
|
||||
|
||||
cd /root/
|
||||
rm -rf x-ui/ /usr/local/x-ui/ /usr/bin/x-ui
|
||||
tar zxvf x-ui-linux-${XUI_ARCH}.tar.gz
|
||||
chmod +x x-ui/x-ui x-ui/bin/xray-linux-* x-ui/x-ui.sh
|
||||
cp x-ui/x-ui.sh /usr/bin/x-ui
|
||||
cp -f x-ui/x-ui.service /etc/systemd/system/
|
||||
mv x-ui/ /usr/local/
|
||||
systemctl daemon-reload
|
||||
systemctl enable x-ui
|
||||
systemctl restart x-ui
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## Instalar con Docker
|
||||
|
||||
<details>
|
||||
<summary>Haz clic para más detalles del Docker</summary>
|
||||
|
||||
#### Uso
|
||||
|
||||
1. Instala Docker:
|
||||
|
||||
```sh
|
||||
bash <(curl -sSL https://get.docker.com)
|
||||
```
|
||||
|
||||
2. Clona el Repositorio del Proyecto:
|
||||
|
||||
```sh
|
||||
git clone https://github.com/xeefei/x-panel.git
|
||||
cd 3x-ui
|
||||
```
|
||||
|
||||
3. Inicia el Servicio
|
||||
|
||||
```sh
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
O tambien
|
||||
|
||||
```sh
|
||||
docker run -itd \
|
||||
-e XRAY_VMESS_AEAD_FORCED=false \
|
||||
-v $PWD/db/:/etc/x-ui/ \
|
||||
-v $PWD/cert/:/root/cert/ \
|
||||
--network=host \
|
||||
--restart=unless-stopped \
|
||||
--name 3x-ui \
|
||||
ghcr.io/xeefei/x-panel:latest
|
||||
```
|
||||
|
||||
actualizar a la última versión
|
||||
|
||||
```sh
|
||||
cd 3x-ui
|
||||
docker compose down
|
||||
docker compose pull 3x-ui
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
eliminar 3x-ui de docker
|
||||
|
||||
```sh
|
||||
docker stop 3x-ui
|
||||
docker rm 3x-ui
|
||||
cd --
|
||||
rm -r 3x-ui
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
|
||||
## SO Recomendados
|
||||
|
||||
- Ubuntu 20.04+
|
||||
- Debian 11+
|
||||
- CentOS 8+
|
||||
- Fedora 36+
|
||||
- Arch Linux
|
||||
- Manjaro
|
||||
- Armbian
|
||||
- AlmaLinux 9+
|
||||
- Rockylinux 9+
|
||||
- OpenSUSE Tubleweed
|
||||
|
||||
## Arquitecturas y Dispositivos Compatibles
|
||||
|
||||
<details>
|
||||
<summary>Haz clic para detalles de arquitecturas y dispositivos compatibles</summary>
|
||||
|
||||
Nuestra plataforma ofrece compatibilidad con una amplia gama de arquitecturas y dispositivos, garantizando flexibilidad en diversos entornos informáticos. A continuación se presentan las principales arquitecturas que admitimos:
|
||||
|
||||
- **amd64**: Esta arquitectura predominante es la estándar para computadoras personales y servidores, y admite la mayoría de los sistemas operativos modernos sin problemas.
|
||||
|
||||
- **x86 / i386**: Ampliamente adoptada en computadoras de escritorio y portátiles, esta arquitectura cuenta con un amplio soporte de numerosos sistemas operativos y aplicaciones, incluidos, entre otros, Windows, macOS y sistemas Linux.
|
||||
|
||||
- **armv8 / arm64 / aarch64**: Diseñada para dispositivos móviles y embebidos contemporáneos, como teléfonos inteligentes y tabletas, esta arquitectura está ejemplificada por dispositivos como Raspberry Pi 4, Raspberry Pi 3, Raspberry Pi Zero 2/Zero 2 W, Orange Pi 3 LTS, entre otros.
|
||||
|
||||
- **armv7 / arm / arm32**: Sirve como arquitectura para dispositivos móviles y embebidos más antiguos, y sigue siendo ampliamente utilizada en dispositivos como Orange Pi Zero LTS, Orange Pi PC Plus, Raspberry Pi 2, entre otros.
|
||||
|
||||
- **armv6 / arm / arm32**: Orientada a dispositivos embebidos muy antiguos, esta arquitectura, aunque menos común, todavía se utiliza. Dispositivos como Raspberry Pi 1, Raspberry Pi Zero/Zero W, dependen de esta arquitectura.
|
||||
|
||||
- **armv5 / arm / arm32**: Una arquitectura más antigua asociada principalmente con sistemas embebidos tempranos, es menos común hoy en día pero aún puede encontrarse en dispositivos heredados como versiones antiguas de Raspberry Pi y algunos teléfonos inteligentes más antiguos.
|
||||
</details>
|
||||
|
||||
## Idiomas
|
||||
|
||||
- Inglés
|
||||
- Farsi
|
||||
- Chino
|
||||
- Ruso
|
||||
- Vietnamita
|
||||
- Español
|
||||
- Indonesio
|
||||
- Ucraniano
|
||||
|
||||
|
||||
## Características
|
||||
|
||||
- Monitoreo del Estado del Sistema
|
||||
- Búsqueda dentro de todas las reglas de entrada y clientes
|
||||
- Tema Oscuro/Claro
|
||||
- Soporta multiusuario y multiprotocolo
|
||||
- Soporta protocolos, incluyendo VMess, VLESS, Trojan, Shadowsocks, Dokodemo-door, Socks, HTTP, wireguard
|
||||
- Soporta Protocolos nativos XTLS, incluyendo RPRX-Direct, Visión, REALITY
|
||||
- Estadísticas de tráfico, límite de tráfico, límite de tiempo de vencimiento
|
||||
- Plantillas de configuración de Xray personalizables
|
||||
- Soporta acceso HTTPS al panel (dominio proporcionado por uno mismo + certificado SSL)
|
||||
- Soporta la solicitud y renovación automática de certificados SSL con un clic
|
||||
- Para elementos de configuración más avanzados, consulta el panel
|
||||
- Corrige rutas de API (la configuración del usuario se creará con la API)
|
||||
- Soporta cambiar las configuraciones por diferentes elementos proporcionados en el panel.
|
||||
- Soporta exportar/importar base de datos desde el panel
|
||||
|
||||
|
||||
## Configuración Predeterminada del Panel
|
||||
|
||||
<details>
|
||||
<summary>Haz clic para ver los detalles de la configuración predeterminada</summary>
|
||||
|
||||
### Nombre de Usuario & Contraseña & Ruta Base Web:
|
||||
|
||||
Estos se generarán aleatoriamente si no los modificas.
|
||||
|
||||
- **Puerto:** el puerto predeterminado para el panel es `2053`
|
||||
|
||||
### Gestión de la Base de Datos:
|
||||
|
||||
Puedes realizar copias de seguridad y restauraciones de la base de datos directamente desde el panel.
|
||||
|
||||
### Ruta Base Web
|
||||
- /etc/x-ui/x-ui.db
|
||||
- **Ruta de Configuración de Xray:**
|
||||
- /usr/local/x-ui/bin/config.json
|
||||
- **Ruta del Panel Web sin Implementar SSL:**
|
||||
- http://ip:2053/panel
|
||||
- http://domain:2053/panel
|
||||
- **Ruta del Panel Web con Implementación de SSL:**
|
||||
- https://domain:2053/panel
|
||||
|
||||
</details>
|
||||
|
||||
1. **Restablecer la Ruta Base Web:**
|
||||
- Abre tu terminal.
|
||||
- Ejecuta el comando `x-ui`.
|
||||
- Selecciona la opción `Restablecer la Ruta Base Web`.
|
||||
|
||||
2. **Generar o Personalizar la Ruta:**
|
||||
- La ruta se generará aleatoriamente, o puedes ingresar una ruta personalizada.
|
||||
|
||||
3. **Ver Configuración Actual:**
|
||||
- Para ver tu configuración actual, utiliza el comando `x-ui settings` en el terminal o selecciona `Ver Configuración Actual` en `x-ui`.
|
||||
|
||||
### Recomendación de Seguridad:
|
||||
- Para mayor seguridad, utiliza una palabra larga y aleatoria en la estructura de tu URL.
|
||||
|
||||
**Ejemplos:**
|
||||
- `http://ip:port/*webbasepath*/panel`
|
||||
- `http://domain:port/*webbasepath*/panel`
|
||||
|
||||
</details>
|
||||
|
||||
## Configuración de WARP
|
||||
|
||||
<details>
|
||||
<summary>Haz clic para ver los detalles de la configuración de WARP</summary>
|
||||
|
||||
#### Uso
|
||||
|
||||
**Para versiones `v2.1.0` y posteriores:**
|
||||
|
||||
WARP está integrado, no se requiere instalación adicional. Simplemente habilita la configuración necesaria en el panel.
|
||||
|
||||
</details>
|
||||
|
||||
## Límite de IP
|
||||
|
||||
<details>
|
||||
<summary>Haz clic para ver los detalles del límite de IP</summary>
|
||||
|
||||
#### Uso
|
||||
|
||||
**Nota:** El Límite de IP no funcionará correctamente cuando uses Túnel IP.
|
||||
|
||||
- **Para versiones hasta `v1.6.1`:**
|
||||
- El límite de IP está integrado en el panel.
|
||||
|
||||
**Para versiones `v1.7.0` y posteriores:**
|
||||
|
||||
Para habilitar la funcionalidad de límite de IP, necesitas instalar `fail2ban` y los archivos requeridos siguiendo estos pasos:
|
||||
|
||||
1. Ejecuta el comando `x-ui` en el terminal, luego elige `Gestión de Límite de IP`.
|
||||
2. Verás las siguientes opciones:
|
||||
|
||||
- **Cambiar la Duración del Bloqueo:** Ajustar la duración de los bloqueos.
|
||||
- **Desbloquear a Todos:** Levantar todos los bloqueos actuales.
|
||||
- **Revisar los Registros:** Revisar los registros.
|
||||
- **Estado de Fail2ban:** Verificar el estado de `fail2ban`.
|
||||
- **Reiniciar Fail2ban:** Reiniciar el servicio `fail2ban`.
|
||||
- **Desinstalar Fail2ban:** Desinstalar Fail2ban con la configuración.
|
||||
|
||||
3. Agrega una ruta para el registro de acceso en el panel configurando `Xray Configs/log/Access log` a `./access.log`, luego guarda y reinicia Xray.
|
||||
|
||||
- **Para versiones anteriores a `v2.1.3`:**
|
||||
- Necesitas configurar manualmente la ruta del registro de acceso en tu configuración de Xray:
|
||||
|
||||
```sh
|
||||
"log": {
|
||||
"access": "./access.log",
|
||||
"dnsLog": false,
|
||||
"loglevel": "warning"
|
||||
},
|
||||
```
|
||||
|
||||
- **Para versiones `v2.1.3` y posteriores:**
|
||||
- Hay una opción para configurar `access.log` directamente desde el panel.
|
||||
|
||||
</details>
|
||||
|
||||
## Bot de Telegram
|
||||
|
||||
<details>
|
||||
<summary>Haz clic para más detalles del bot de Telegram</summary>
|
||||
|
||||
#### Uso
|
||||
|
||||
El panel web admite tráfico diario, inicio de sesión en el panel, copia de seguridad de la base de datos, estado del sistema, información del cliente y otras notificaciones y funciones a través del Bot de Telegram. Para usar el bot, debes establecer los parámetros relacionados con el bot en el panel, que incluyen:
|
||||
|
||||
- Token de Telegram
|
||||
- ID de chat de administrador(es)
|
||||
- Hora de Notificación (en sintaxis cron)
|
||||
- Notificación de Fecha de Caducidad
|
||||
- Notificación de Capacidad de Tráfico
|
||||
- Copia de seguridad de la base de datos
|
||||
- Notificación de Carga de CPU
|
||||
|
||||
|
||||
**Sintaxis de referencia:**
|
||||
|
||||
- `30 \* \* \* \* \*` - Notifica a los 30s de cada punto
|
||||
- `0 \*/10 \* \* \* \*` - Notifica en el primer segundo de cada 10 minutos
|
||||
- `@hourly` - Notificación por hora
|
||||
- `@daily` - Notificación diaria (00:00 de la mañana)
|
||||
- `@weekly` - Notificación semanal
|
||||
- `@every 8h` - Notifica cada 8 horas
|
||||
|
||||
### Funcionalidades del Bot de Telegram
|
||||
|
||||
- Reporte periódico
|
||||
- Notificación de inicio de sesión
|
||||
- Notificación de umbral de CPU
|
||||
- Umbral de Notificación para Fecha de Caducidad y Tráfico para informar con anticipación
|
||||
- Soporte para menú de reporte de cliente si el nombre de usuario de Telegram del cliente se agrega a las configuraciones de usuario
|
||||
- Soporte para reporte de tráfico de Telegram buscado con UUID (VMESS/VLESS) o Contraseña (TROJAN) - anónimamente
|
||||
- Bot basado en menú
|
||||
- Buscar cliente por correo electrónico (solo administrador)
|
||||
- Ver todas las Entradas
|
||||
- Ver estado del servidor
|
||||
- Ver clientes agotados
|
||||
- Recibir copia de seguridad bajo demanda y en informes periódicos
|
||||
- Bot multilingüe
|
||||
|
||||
### Configuración del Bot de Telegram
|
||||
|
||||
- Inicia [Botfather](https://t.me/BotFather) en tu cuenta de Telegram:
|
||||

|
||||
|
||||
- Crea un nuevo bot usando el comando /newbot: Te hará 2 preguntas, Un nombre y un nombre de usuario para tu bot. Ten en cuenta que el nombre de usuario debe terminar con la palabra "bot".
|
||||

|
||||
|
||||
- Inicia el bot que acabas de crear. Puedes encontrar el enlace a tu bot aquí.
|
||||

|
||||
|
||||
- Ingresa a tu panel y configura los ajustes del bot de Telegram como se muestra a continuación:
|
||||

|
||||
|
||||
Ingresa el token de tu bot en el campo de entrada número 3.
|
||||
Ingresa el ID de chat de usuario en el campo de entrada número 4. Las cuentas de Telegram con esta ID serán los administradores del bot. (Puedes ingresar más de uno, solo sepáralos con ,)
|
||||
|
||||
- ¿Cómo obtener el ID de chat de Telegram? Usa este [bot](https://t.me/useridinfobot), Inicia el bot y te dará el ID de chat del usuario de Telegram.
|
||||

|
||||
|
||||
</details>
|
||||
|
||||
## Rutas de API
|
||||
|
||||
<details>
|
||||
<summary>Haz clic para más detalles de las rutas de API</summary>
|
||||
|
||||
#### Uso
|
||||
|
||||
- `/login` con `POST` datos de usuario: `{username: '', password: ''}` para iniciar sesión
|
||||
- `/panel/api/inbounds` base para las siguientes acciones:
|
||||
|
||||
| Método | Ruta | Acción |
|
||||
| :----: | ---------------------------------- | --------------------------------------------------------- |
|
||||
| `GET` | `"/list"` | Obtener todas los Entradas |
|
||||
| `GET` | `"/get/:id"` | Obtener Entrada con inbound.id |
|
||||
| `GET` | `"/getClientTraffics/:email"` | Obtener Tráficos del Cliente con email |
|
||||
| `GET` | `"/createbackup"` | El bot de Telegram envía copia de seguridad a los admins |
|
||||
| `POST` | `"/add"` | Agregar Entrada |
|
||||
| `POST` | `"/del/:id"` | Eliminar Entrada |
|
||||
| `POST` | `"/update/:id"` | Actualizar Entrada |
|
||||
| `POST` | `"/clientIps/:email"` | Dirección IP del Cliente |
|
||||
| `POST` | `"/clearClientIps/:email"` | Borrar Dirección IP del Cliente |
|
||||
| `POST` | `"/addClient"` | Agregar Cliente a la Entrada |
|
||||
| `POST` | `"/:id/delClient/:clientId"` | Eliminar Cliente por clientId\* |
|
||||
| `POST` | `"/updateClient/:clientId"` | Actualizar Cliente por clientId\* |
|
||||
| `POST` | `"/:id/resetClientTraffic/:email"` | Restablecer Tráfico del Cliente |
|
||||
| `POST` | `"/resetAllTraffics"` | Restablecer tráfico de todos las Entradas |
|
||||
| `POST` | `"/resetAllClientTraffics/:id"` | Restablecer tráfico de todos los clientes en una Entrada |
|
||||
| `POST` | `"/delDepletedClients/:id"` | Eliminar clientes agotados de la entrada (-1: todos) |
|
||||
| `POST` | `"/onlines"` | Obtener usuarios en línea (lista de correos electrónicos) |
|
||||
|
||||
\*- El campo `clientId` debe llenarse por:
|
||||
|
||||
- `client.id` para VMESS y VLESS
|
||||
- `client.password` para TROJAN
|
||||
- `client.email` para Shadowsocks
|
||||
|
||||
|
||||
- [Documentación de API](https://documenter.getpostman.com/view/16802678/2s9YkgD5jm)
|
||||
- [<img src="https://run.pstmn.io/button.svg" alt="Run In Postman" style="width: 128px; height: 32px;">](https://app.getpostman.com/run-collection/16802678-1a4c9270-ac77-40ed-959a-7aa56dc4a415?action=collection%2Ffork&source=rip_markdown&collection-url=entityId%3D16802678-1a4c9270-ac77-40ed-959a-7aa56dc4a415%26entityType%3Dcollection%26workspaceId%3D2cd38c01-c851-4a15-a972-f181c23359d9)
|
||||
</details>
|
||||
|
||||
## Variables de Entorno
|
||||
|
||||
<details>
|
||||
<summary>Haz clic para más detalles de las variables de entorno</summary>
|
||||
|
||||
#### Uso
|
||||
|
||||
| Variable | Tipo | Predeterminado |
|
||||
| -------------- | :--------------------------------------------: | :------------- |
|
||||
| XUI_LOG_LEVEL | `"debug"` \| `"info"` \| `"warn"` \| `"error"` | `"info"` |
|
||||
| XUI_DEBUG | `boolean` | `false` |
|
||||
| XUI_BIN_FOLDER | `string` | `"bin"` |
|
||||
| XUI_DB_FOLDER | `string` | `"/etc/x-ui"` |
|
||||
| XUI_LOG_FOLDER | `string` | `"/var/log"` |
|
||||
|
||||
Ejemplo:
|
||||
|
||||
```sh
|
||||
XUI_BIN_FOLDER="bin" XUI_DB_FOLDER="/etc/x-ui" go build main.go
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## Vista previa
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
## Un agradecimiento especial a
|
||||
|
||||
- [alireza0](https://github.com/alireza0/)
|
||||
|
||||
## Reconocimientos
|
||||
|
||||
赞助地址(USDT/TRC20):TYQEmQp1P65u9bG7KPehgJdvuokfb72YkZ
|
||||
|
||||
- [Iran v2ray rules](https://github.com/chocolate4u/Iran-v2ray-rules) (Licencia: **GPL-3.0**): _Reglas de enrutamiento mejoradas de v2ray/xray y v2ray/xray-clients con dominios iraníes integrados y un enfoque en seguridad y bloqueo de anuncios._
|
||||
- [Vietnam Adblock rules](https://github.com/vuong2023/vn-v2ray-rules) (License: **GPL-3.0**): _Un dominio alojado en Vietnam y una lista de bloqueo con la máxima eficiencia para vietnamitas._
|
||||
|
||||
## Estrellas a lo largo del tiempo
|
||||
|
||||
[](https://starchart.cc/xeefei/x-panel)
|
||||
52
README.fa_IR.md
Normal file
@@ -0,0 +1,52 @@
|
||||
<p align="center"><a href="#"><img src="./media/X-Panel.png" alt="Image"></a></p>
|
||||
|
||||
**---------------------------------------一个更好的面板 • 基于Xray Core构建------------------------------**
|
||||
|
||||
|
||||
[](https://github.com/xeefei/x-panel/releases)
|
||||
[](https://github.com/xeefei/x-panel/actions)
|
||||
[](#)
|
||||
[](https://github.com/xeefei/x-panel/releases/latest)
|
||||
[](https://www.gnu.org/licenses/gpl-3.0.en.html)
|
||||
|
||||
**3X-UI** — یک پنل کنترل پیشرفته مبتنی بر وب با کد باز که برای مدیریت سرور Xray-core طراحی شده است. این پنل یک رابط کاربری آسان برای پیکربندی و نظارت بر پروتکلهای مختلف VPN و پراکسی ارائه میدهد.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> این پروژه فقط برای استفاده شخصی و ارتباطات است، لطفاً از آن برای اهداف غیرقانونی استفاده نکنید، لطفاً از آن در محیط تولید استفاده نکنید.
|
||||
|
||||
به عنوان یک نسخه بهبود یافته از پروژه اصلی X-UI، 3X-UI پایداری بهتر، پشتیبانی گستردهتر از پروتکلها و ویژگیهای اضافی را ارائه میدهد.
|
||||
|
||||
## شروع سریع
|
||||
|
||||
```
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/xeefei/x-panel/master/install.sh)
|
||||
```
|
||||
|
||||
برای مستندات کامل، لطفاً به [ویکی پروژه](https://github.com/xeefei/x-panel/wiki) مراجعه کنید.
|
||||
|
||||
## تشکر ویژه از
|
||||
|
||||
- [alireza0](https://github.com/alireza0/)
|
||||
|
||||
## قدردانی
|
||||
|
||||
- [Iran v2ray rules](https://github.com/chocolate4u/Iran-v2ray-rules) (مجوز: **GPL-3.0**): _قوانین مسیریابی بهبود یافته v2ray/xray و v2ray/xray-clients با دامنههای ایرانی داخلی و تمرکز بر امنیت و مسدود کردن تبلیغات._
|
||||
- [Russia v2ray rules](https://github.com/runetfreedom/russia-v2ray-rules-dat) (مجوز: **GPL-3.0**): _این مخزن شامل قوانین مسیریابی V2Ray بهروزرسانی شده خودکار بر اساس دادههای دامنهها و آدرسهای مسدود شده در روسیه است._
|
||||
|
||||
## پشتیبانی از پروژه
|
||||
|
||||
**اگر این پروژه برای شما مفید است، میتوانید به آن یک**:star2: بدهید
|
||||
|
||||
<p align="left">
|
||||
<a href="https://buymeacoffee.com/mhsanaei" target="_blank">
|
||||
<img src="./media/buymeacoffe.png" alt="Image">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
- USDT (TRC20): `TXncxkvhkDWGts487Pjqq1qT9JmwRUz8CC`
|
||||
- POL (polygon): `0x41C9548675D044c6Bfb425786C765bc37427256A`
|
||||
- LTC (Litecoin): `ltc1q2ach7x6d2zq0n4l0t4zl7d7xe2s6fs7a3vspwv`
|
||||
|
||||
## ستارهها در طول زمان
|
||||
|
||||
[](https://starchart.cc/MHSanaei/3x-ui)
|
||||
938
README.md
Normal file
@@ -0,0 +1,938 @@
|
||||
<p align="center"><a href="#"><img src="./media/X-Panel.png" alt="Image"></a></p>
|
||||
|
||||
**---------------------------------------一个更好的面板 • 基于Xray Core构建------------------------------**
|
||||
|
||||
|
||||
[](https://github.com/xeefei/x-panel/releases)
|
||||
[](https://github.com/xeefei/x-panel/actions)
|
||||
[](#)
|
||||
[](https://github.com/xeefei/x-panel/releases/latest)
|
||||
[](https://www.gnu.org/licenses/gpl-3.0.en.html)
|
||||
|
||||
> **声明:** 此项目仅供个人学习、交流使用,请遵守当地法律法规,勿用于非法用途;请勿用于生产环境。
|
||||
|
||||
> **注意:** 在使用此项目和〔教程〕过程中,若因违反以上声明使用规则而产生的一切后果由使用者自负。
|
||||
|
||||
**如果此项目对你有用,请给一个**:star2:
|
||||
|
||||
<p align="left">
|
||||
<a href="https://buymeacoffee.com/xeefeiz" target="_blank">
|
||||
<img src="./media/buymeacoffe.png" alt="Image">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
- “支持项目”赞助地址(USDT):
|
||||
- TRC20 ---->>> `TYQEmQp1P65u9bG7KPehgJdvuokfb72YkZ`
|
||||
- Polygon ---->>> `0xd20eBE429c2398793178e015B2ca1Dc42601f3Eb`
|
||||
- Solana ---->>> `7qVEZuV98QTDN5qUmsFwvqTSvkYpmLtNf8o1sh1mppwR`
|
||||
- BSC/BEP20 ---->>> `0xd20eBE429c2398793178e015B2ca1Dc42601f3Eb`
|
||||
|
||||
## [【X-Panel面板】交流群:https://t.me/XUI_CN](https://t.me/XUI_CN)
|
||||
## [【X-Panel面板】详细安装流程步骤:https://xeefei.blogspot.com/2025/09/x-panel.html](https://xeefei.blogspot.com/2025/09/x-panel.html)
|
||||
|
||||
|
||||
------------
|
||||
## ✰怎么购买【授权码】使用〔X-Panel-Pro版 面板〕?✰
|
||||
#### 1、【授权码】100/15U一个,一机一码,一直有效,永久使用,包括:重装,后期的升级/更新,都能使用,但是不能用于不同的机器,所以推荐稳定使用的机器用【授权码】,注:“授权码”属虚拟商品,购买之后,一经激活生效,概不退款,
|
||||
#### 2、对于一年期限(年付/年抛)的机器,后期可以【换绑】,为什么要有时间限制?就是为了防止,有些人拿【授权码】滥用,
|
||||
#### 3、购买方式/渠道联系机器人:[https://t.me/Buy_ShouQuan_Bot](https://t.me/Buy_ShouQuan_Bot)
|
||||
|
||||
#### 4、经常换的机器,去使用“免费基础版”就行,目前【安装界面】是有“两种方式”可选择的,
|
||||
|
||||
#### 5、对于有业务需求,比如做 TK 的,做〔跨境电商〕的,如果很多机器,比如:20台,50台,或者 100台 以上机器的宝子,若都要用【收费Pro版】的话,可以用【批量授权】:5 ——> 20台,8折,尾号:5555 ,20 ——> 50台,7折,尾号:66666 ,50 ——> 100台,6折,尾号:777777 ,100 ——> 200台,5折,尾号:8888888,200台 ——> 以上,4折,尾号:99999999,以上列举出来的,就是【批量折扣】的统一“优惠”。注:〔批量授权码〕要求最低5台以上,是“一码通用”,一个“授权码”,可以绑定验证多台 VPS 机器,并且有专属的“豹子号”授权码。
|
||||

|
||||
————————————————————————————————
|
||||
|
||||
#### 6、若您需要购买【授权码】,请跟下面这个“机器人”去对话,
|
||||
|
||||
#### ———————————————-
|
||||
|
||||
#### [https://t.me/Buy_ShouQuan_Bot](https://t.me/Buy_ShouQuan_Bot)
|
||||
#### (授权码购买机器人)
|
||||
|
||||
#### ———————————————-
|
||||
|
||||
#### 输入:/start 或 购买,即可“在线下单”,
|
||||
|
||||
#### 7、弹出【购买页面】,选择或输入“数量”,付款了支付系统会收到回调,金额到账之后,就会通过那个机器人【发放授权码】给您,整个流程,是【全自助】的“自动处理”方式,若您是〔增加配额〕,基本也是一样的流程,
|
||||
|
||||
#### 8、请注意:机器人发给您的所有信息,尽量都去自己【耐心阅读】一遍,“使用说明”,以及〔VIP 群〕的信息,也全部都包含在里面的,
|
||||
|
||||
#### 9、按照之前您安装更新〔X-Panel 面板〕的方式,直接重新输入【安装命令】,选择【2】,就能去,把之前的【免费版】,“无缝升级”到最新的【Pro版】。
|
||||
|
||||
————————————————————————————————
|
||||
#### 10、不能重复用于不同的机器 VPS,后期视情况不定时会上涨价格;对于〔X-Panel 面板〕后期的“新功能”,都将在【付费Pro版】中进行更新,
|
||||
|
||||
#### 11、目前的【安装界面】,是有:两种可选,“免费基础版”一样可用,只是后期不再提供技术支持和重大更新,另外,在【免费基础版】中,【一键配置】功能将不再可用,全部放到了【付费Pro版】中,
|
||||
|
||||
#### 12、后期的开发精力,全部会放到【付费Pro版】中,免费基础版不删库,持续保留,会大幅降低更新频率,后期只会同步更新 Xray 那边的【内核版本】等基础,想继续用的不影响,只是没有【新功能】可用,翻墙也足够。
|
||||
|
||||

|
||||
|
||||
------------
|
||||
## ✰〔X-Panel-Pro版 面板〕已实现的功能✰
|
||||
#### 1、新增 -【付费Pro版】的面板后台UI,添加醒目的“X-Panel-Pro”标识,
|
||||
#### 2、优化 -【付费Pro版】TG端 【版本更新】提示功能,增加详细的“更新说明”,
|
||||
#### 3、增加〔Pro版面板后台〕,使用 Reality 协议时,可点击随机更换所偷的域名,
|
||||
#### 4、新增 -【付费Pro版】TG端 的【发送授权报告】,增加“唯一授权防伪码”,
|
||||
#### 5、优化 -【付费Pro版】安装脚本界面,增加【Pro版】该有的“明确标识”,
|
||||
#### 6、优化 -【付费Pro版】TG端的显示方式,增加该有的“会员标识”,
|
||||
#### 7、新增 -【付费Pro版】安装脚本,有“网页版SSH工具”可选部署,脚本中〔第26选项〕,
|
||||
#### 8、新增 - 【付费Pro版】安装脚本,有“线路和IP质量检测”可去使用,脚本中〔第27选项〕,
|
||||
#### 9、新增 - 【付费Pro版】安装脚本,有“地区服务器DNS检测”可去使用,脚本中〔第28选项〕,
|
||||
#### 10、新增 -【付费Pro版】---->>>TG端,同步有“网页版SSH工具”可选安装,
|
||||
#### 11、优化 - 【付费Pro版】---->>>TG端,点击“服务器状态”时的“版本号显示”,
|
||||
#### 12、说明 - 【付费Pro版】TG端中,使用命令:/webssh,安装“网页版SSH”,
|
||||
#### 13、优化 -〔Pro版〕中的〔一键配置〕功能,有更友好的提示方式,
|
||||
#### 14、新增 -【付费Pro版】---->>>面板后台的【首页 UI】,目前是有“5种”可选:标准布局 (默认),炫彩动画,深海科技,暮光薰衣,和幽林秘境;你喜欢什么类型的主题,就去点击“选定”之后,就不会自动变了,若后期需要更换,就重选,
|
||||
#### 15、新增 -【付费Pro版】---->>>在“创建入站”时,可以在页面上更加方便地选择【重置流量】的方式:有每日重置,每周重置,按月重置,或从不重置,
|
||||
#### 16、新增 -〔X-Panel 面板〕----->>【付费Pro版】TG端“每日报告”,可定制【发送内容】,自己可点击“打开或关闭”,并且可以选择【发送时间】,可按天,或者每周,每月发,
|
||||
#### 17、优化 -【付费Pro版】的“授权码验证机制”,增加【后台联网验证】,以及“机器指纹”等属性,
|
||||
#### 18、新增 -〔X-Panel 面板〕----->>【付费Pro版】TG端“多面板管理”,一个机器人可同时管理其他面板,可以很丝滑地远程操作【被控端 VPS】,
|
||||
#### 19、新增 -〔X-Panel 面板〕----->>【付费Pro版】TG端“获取节点链接”功能,支持【本机】和【远程被控端 VPS】都能获取,开发此功能的目的在于:不用进〔面板后台〕,就能在 TG端 获取到之前已经创建过的“链接”,
|
||||
#### 20、新增 -〔X-Panel 面板〕----->>【付费Pro版】“一键部署中转节点”,解决了不懂配置的麻烦,已实现:远程Socks5创建 --> 本机路由配置 --> 本机入口创建 --> 生成“二维码和链接”,“小手一点”,直接可用,
|
||||
#### 21、新增 -〔X-Panel 面板〕----->>【申请安装证书】“第18选项”,有“备用方式申请证书”,当用常规方式【1】申请不下来时,可以试试“备用方式”,
|
||||
#### 22、新增 -〔X-Panel 面板〕----->>【申请安装证书】“第18选项”,有“可自定义证书路径”,自己进入 VPS 中“手动上传证书”,复制路径,在脚本中填入即可,
|
||||
#### 23、新增 -〔X-Panel 面板〕----->>【付费Pro版】“深度调优脚本”,包含 BBR+FQ, TCP Fast Open, 内存缓冲区及队列优化,在〔Pro版〕脚本中“第29选项”可直接用,
|
||||
#### 24、新增 -〔X-Panel 面板〕----->>【付费Pro版】“首页会员等级”显示,能够明确展示:自己的会员等级,授权码信息,以及“版本更新”提示,
|
||||
#### 25、新增 -〔X-Panel 面板〕----->>【付费Pro版】“节点上/下线TG通知”功能,对于【拼车】的宝子,能明确知道:哪个节点,什么时候上线?或者下线时间,做到“心中有数”,
|
||||
#### 26、新增 -〔X-Panel 面板〕----->>【付费Pro版】“签到得积分”功能,后期针对有【积分】的宝子,会不断推出:相应的【特权】和【福利待遇】,
|
||||
#### 27、新增 -〔X-Panel 面板〕----->>【付费Pro版】“TG端签到得积分”功能,推出:积分查询,积分换购,授权码查询,修改用户名,积分转移/打赏,以及“积分排行榜”,
|
||||
#### 28、新增 -〔X-Panel 面板〕----->>【付费Pro版】“TG端签到得积分”功能,推出【“积分换购”的可用功能】:A、消耗1000积分“自助重置换绑时间”,B、消耗5000积分“自助换购一个普通授权码”,
|
||||
#### 29、新增 -〔X-Panel 面板〕----->>【付费Pro版】“创建数据快照 + 远程急救还原”的提示功能: 可直观通过「终端UI界面」看到具体「备份 + 还原」步骤;用法:面板报错“崩了”,不用像之前那样:卸载面板 -->> 重装面板,更不用很麻烦去“重装系统”解决,直接:远程急救还原,前提就是:你自己要知道,在面板“正常运行”的时候,去「备份数据快照」,
|
||||
#### 30、新增 -〔X-Panel 面板〕----->>【付费Pro版】“每月重置流量”功能:可输入1—31之间的任意数字,比如:输入12,即代表“每月12号”「重置入站流量」,以便提供更友好的“重置流量方式”,
|
||||
#### 31、新增 -〔X-Panel 面板〕----->>【付费Pro版】“批量部署节点”功能:可直接在面板后台的“一键配置”中去使用,点击一次可批量部署生成10条「VLESS + TCP + Reality + Vision」协议组合的入站,
|
||||
#### 32、新增 -〔X-Panel 面板〕----->>【付费Pro版】“购买机器人”功能,可自助全自动在“机器人”中:购买授权码,增加配额,充值积分,自助重置换绑等,联系:[https://t.me/Buy_ShouQuan_Bot](https://t.me/Buy_ShouQuan_Bot) 。
|
||||

|
||||
|
||||
------------
|
||||
## ✰你必须要看的【重要安全提示/警告】✰
|
||||
#### 1、请勿使用【http明文模式】登录管理面板,因为明文会造成信息泄露;这个安全问题社区讨论过,
|
||||
#### 2、可使用设置【SSH端口转发功能】去登录面板或安装证书之后用https加密方式登录;两种方式选择其一,
|
||||

|
||||
#### 3、若无域名那就按照脚本提示去做【ssh转发】;有域名则可选择更加安全的【申请安装证书】方式,
|
||||
#### 4、Windows电脑首先通过快捷键【Win + R】调出运行窗口,在里面输入【cmd】打开本地终端服务,
|
||||

|
||||

|
||||

|
||||

|
||||
#### 5、若在搭建之前没有翻墙加密,则【http明文模式】登录面板有很大的信息泄露安全风险,那建议你第一次搭建成功之后,去修改用户/密码,和访问路径,后期则通过搭建好的代理加密访问,
|
||||

|
||||
#### 6、在做【ssh转发】过程中,本地电脑的终端不能关闭,保持打开不能断开;且每一次要登录〔X-Panel面板〕管理后台都要做【ssh转发】,因为关闭之后就失效了。
|
||||

|
||||
#### PS:上述两种方法:【ssh端口转发】或申请安装证书的目的都是为了更安全地登录面板,而至于搭建的其他流程和步骤,都是一样的;如果你已经【申请安装证书】了,并不会受到其他什么额外影响,就不用去折腾【ssh转发】了,直接用 【https://你的域名:端口/路径】 去登录你的面板管理后台就行了。
|
||||
|
||||
------------
|
||||
## 如何在〔X-Panel-Pro 面板〕中去使用【一个机器人管理多面板】功能?
|
||||
#### 1、先购买【授权码】安装好〔X-Panel-Pro 面板〕,进入后台,在【主从管理】界面,
|
||||

|
||||
#### 2、点击【添加被控端 VPS】,按照要求填入面板登录地址,用户名和密码,备注等信息,
|
||||

|
||||
#### 3、然后点击【配置本机“主控机器人”】,跳转到【机器人设置页面】,输入token令牌配置好,
|
||||

|
||||

|
||||
#### 4、现在重启本机 VPS,打开TG端机器人,即可看到【切换控制 VPS】等菜单,切换操作即可使用。
|
||||

|
||||

|
||||
|
||||
------------
|
||||
## 如何在〔X-Panel-Pro 面板〕中去使用【一键部署中转节点】的功能?
|
||||
#### 1、先购买【授权码】安装好〔X-Panel-Pro 面板〕,进入后台,在【主从管理】界面,
|
||||
#### 2、点击【添加中转机 VPS】,按照要求填入面板登录地址,用户名和密码,备注等信息,
|
||||

|
||||
#### 3、然后点击列表页中的【一键部署中转】,即可在后续的流程中,自动进入配置流程,
|
||||

|
||||
#### 4、稍等片刻,本机配置好的话就几秒,全自动给您生成了【二维码和中转链接】,复制可用,
|
||||

|
||||
#### 5、记得要去放行【本机】和【远程中转机】对应的端口,也可点击【检测中转节点】功能去看是否通?
|
||||

|
||||
|
||||
------------
|
||||
## ✰如何从其他x-ui版本迁移到〔X-Panel面板〕?✰
|
||||
#### 1、若你用的是伊朗老哥的3X-UI,是可以直接〔覆盖安装〕的,因为数据库文件等位置是没有改变的,所以直接覆盖安装,并不会影响你〔原有节点及配置〕等数据;安装命令如下:
|
||||
```
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/xeefei/x-panel/master/install.sh)
|
||||
```
|
||||
#### 2、若你之前用的是Docker方式安装,那先进入容器里面/命令:docker exec -it 容器id /bin/sh,再执行以上脚本命令直接【覆盖安装】即可,
|
||||
#### 3、若你用的是之前F佬的x-ui或者其他分支版本,那直接覆盖安装的话,并不能确保一定就能够兼容?建议你先去备份〔数据库〕配置文件,再进行安装〔X-Panel面板〕。
|
||||
|
||||
|
||||
------------
|
||||
## 安装之前的准备
|
||||
- 购买一台性能还不错的VPS,可通过本页底部链接购买,
|
||||
- PS:若你不想升级系统,则可以跳过此步骤。
|
||||
- 若你需要更新/升级系统,Debian系统可用如下命令:
|
||||
```
|
||||
apt update
|
||||
apt upgrade -y
|
||||
apt dist-upgrade -y
|
||||
apt autoclean
|
||||
apt autoremove -y
|
||||
```
|
||||
- 查看系统当前版本:
|
||||
```
|
||||
cat /etc/debian_version
|
||||
```
|
||||
- 查看内核版本:
|
||||
```
|
||||
uname -r
|
||||
```
|
||||
- 列出所有内核:
|
||||
```
|
||||
dpkg --list | grep linux-image
|
||||
```
|
||||
- 更新完成后执行重新引导:
|
||||
```
|
||||
update-grub
|
||||
```
|
||||
- 完成以上步骤之后输入reboot重启系统
|
||||
|
||||
------------
|
||||
## 【搬瓦工】重装/升级系统之后SSH连不上如何解决?
|
||||
- 【搬瓦工】重装/升级系统会恢复默认22端口,如果需要修改SSH的端口号,您需要进行以下步骤:
|
||||
- 以管理员身份使用默认22端口登录到SSH服务器
|
||||
- 打开SSH服务器的配置文件进行编辑,SSH配置文件通常位于/etc/ssh/sshd_config
|
||||
- 找到"Port"选项,并将其更改为您想要的端口号
|
||||
- Port <新端口号>,请将<新端口号>替换为您想要使用的端口号
|
||||
- 保存文件并退出编辑器
|
||||
- 重启服务器以使更改生效
|
||||
|
||||
------------
|
||||
## 安装 & 升级
|
||||
- 使用〔X-Panel面板〕脚本一般情况下,安装完成创建入站之后,端口是默认关闭的,所以必须进入脚本选择【22】去放行端口
|
||||
- 要使用【自动续签】证书功能,也必须放行【80】端口,保持80端口是打开的,才会每3个月自动续签一次
|
||||
|
||||
- 【全新安装】请执行以下脚本:
|
||||
```
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/xeefei/x-panel/master/install.sh)
|
||||
```
|
||||
#### 如果执行了上面的代码但是报错,证明你的系统里面没有curl这个软件,请执行以下命令先安装curl软件,安装curl之后再去执行上面代码,
|
||||
```
|
||||
apt update -y&&apt install -y curl&&apt install -y socat
|
||||
```
|
||||
|
||||
- 若要对版本进行升级,可直接通过脚本选择【2】,如下图:
|
||||

|
||||

|
||||
- 在到这一步必须要注意:要保留旧设置的话,需要输入【n】
|
||||

|
||||
|
||||
|
||||
## 安装指定版本
|
||||
|
||||
若要安装指定的版本,请使用以下安装命令。 e.g., ver `v26.2.15`:
|
||||
|
||||
```
|
||||
VERSION=v26.2.15 && bash <(curl -Ls "https://raw.githubusercontent.com/xeefei/x-panel/$VERSION/install.sh") $VERSION
|
||||
```
|
||||
------------
|
||||
## 若你的VPS默认有防火墙,请在安装完成之后放行指定端口
|
||||
- 放行【面板登录端口】
|
||||
- 放行出入站管理协议端口
|
||||
- 如果要申请安装证书并每3个月【自动续签】证书,请确保80和443端口是放行打开的
|
||||
- 可通过此脚本的第【21】选项去安装防火墙进行管理,如下图:
|
||||

|
||||
- 若要一次性放行多个端口或一整个段的端口,用英文逗号隔开。
|
||||
#### PS:若你的VPS没有防火墙,则所有端口都是能够ping通的,可自行选择是否进入脚本安装防火墙保证安全,但安装了防火墙必须放行相应端口。
|
||||
|
||||
------------
|
||||
## 如何在〔X-Panel面板〕中使用简单快捷的【一键配置】生成功能?
|
||||
#### 1、进入后台,并且你已经【安装了证书】,可在【添加入站】处看到,
|
||||

|
||||
#### 2、点击【一键配置】,在弹出的页面中【按需选择】去生成协议配置即可,
|
||||

|
||||
#### 3、直接复制【链接】,导入软件;若后台出现【醒目提示】,那就手动放行【相应端口】,
|
||||

|
||||
#### 4、若你是用【TG端电报机器人】的【一键配置】生成功能,那直接点击就用,
|
||||

|
||||
#### 5、选择好自己想要【一键创建】的协议组合类型,点击之后稍作等待,
|
||||

|
||||
#### 6、TG端【一键配置】创建成功之后,二维码和链接地址机器人会发送给你,如下:
|
||||

|
||||
|
||||
------------
|
||||
## 如何在〔X-Panel 项目〕中进行【抽奖游戏】赢奖品?
|
||||
#### 1、必须绑定好【TG端机器人】,怎么绑定?去看下面“绑定机器人”那部分教程,
|
||||
#### 2、在【TG端】直接点击【娱乐抽奖】菜单,就会弹出【每日幸运】抽奖游戏,
|
||||

|
||||
#### 3、点击【进行抽奖】,就可“全凭手气”得到随机的抽奖结果,如下图所示,
|
||||

|
||||
#### 4、在你【中奖】之后,截完整的“中奖页面”图片给交流群内管理员,即可兑奖。
|
||||

|
||||
|
||||
------------
|
||||
## 安装证书开启https方式实现域名登录访问管理面板/----->>偷自己
|
||||
#### PS:如果不需要以上功能或无域名,可以跳过这步;建议申请证书,
|
||||
##### 1、把自己的域名托管到CF,并解析到自己VPS的IP,不要开启【小云朵】,
|
||||
##### 2、如果要申请安装证书并每3个月【自动续签】证书,请确保80和443端口是放行打开的,
|
||||
##### 3、输入x-ui命令进入面板管理脚本,通过选择第【18】选项去进行安装,若使用 18 ---> 1方式不能申请下来,那就用 18--->5 备用方式去申请,或者也可用【19选项】去申请,
|
||||

|
||||
##### 4、首先输入解析好的【域名】进行验证,然后可以默认用【80端口】,直接回车申请,
|
||||

|
||||
##### 5、进入后台【面板设置】—–>【常规】中,会看到脚本已经自动填好了证书公钥、私钥路径,
|
||||
##### 6、点击左上角的【保存】和【重启面板】,即可用自己域名进行登录管理;也可按照后续方法实现【自己偷自己】。
|
||||
|
||||
------------
|
||||
## 登录面板进行【常规】设置
|
||||
### 特别是如果在安装过程中,全部都是默认【回车键】安装的话,用户名/密码/访问路径是随机的,而面板监听端口默认是:13688,可自行进入面板更改,
|
||||
##### 1、填写自己想要设置的【面板监听端口】,并去登录SSH放行,
|
||||
##### 2、更改自己想要设置的【面板登录访问路径】,后续加上路径登录访问,
|
||||

|
||||
##### 3、其他:安全设定和电报机器人等配置,可自行根据需求去进行设置,
|
||||
##### 4、强烈建议配置电报机器人,使用【TG端】可方便远程接管 VPS 服务器,
|
||||

|
||||
##### 5、面板设置【改动保存】之后,都需要点击左上角【重启面板】,才能生效。
|
||||
#### PS:若你在正确完成了上述步骤之后,你没有安装证书的情况下,去用【ssh转发】的方式却不能访问面板,那请检查一下是不是你的浏览器自动默认开启了https模式,需要手动调整一下改成http方式,把“s”去掉,即可访问成功;或查看一下是不是对应的端口被占用?
|
||||
|
||||
------------
|
||||
## 创建【入站协议】和添加【客户端】,并测试上网
|
||||
##### 1、点击左边【入站列表】,然后【添加入站】,传输方式保持【TCP】不变,尽量选择主流的vless+reality+vision协议组合,
|
||||

|
||||
##### 2、在选择reality安全选项时,偷的域名可以使用默认的,要使用其他的,请替换尽量保持一致就行,比如Apple、Yahoo,VPS所在地区的旅游、学校网站等;如果要实现【偷自己】,请参看后续【如何偷自己】的说明部分;而私钥/公钥部分,可以直接点击下方的【Get New Cert】获取一个随机的,
|
||||
##### 3、在创建reality安全选项过程中,至于其他诸如:PROXY Protocol,HTTP 伪装,TPROXY,External Proxy等等选项,若无特殊要求,保持默认设置即可,不用去动它们,
|
||||

|
||||
##### 4、创建好入站协议之后,默认只有一个客户端,可根据自己需求继续添加;重点:并编辑客户端,选择【Flow流控】为xtls-rprx-vision,
|
||||

|
||||
##### 5、其他:流量限制,到期时间,客户TG的ID等选项根据自己需求填写,
|
||||

|
||||
##### 6、一定要放行端口之后,确保端口能够ping通,再导入软件,
|
||||
##### 7、点击二维码或者复制链接导入到v2rayN等软件中进行测试。
|
||||
|
||||
------------
|
||||
## 备份与恢复/迁移数据库(以Debian系统为例)
|
||||
#### 一、备份:通过配置好电报管理机器人,可点击管理机器人的“相应菜单按钮”获取【备份配置】文件,有x-ui.db和config.json两个文件,可自行下载保存到自己电脑里面,
|
||||

|
||||
#### 二、搭建:在新的VPS中全新安装好〔X-Panel面板〕,通过脚本放行之前配置的所有端口,一次性放行多个端口请用【英文逗号】分隔,
|
||||
#### 三、若需要安装证书,则提前把域名解析到新的VPS对应的IP,并且去输入x-ui选择第【18】选项去安装,并记录公钥/私钥的路径,无域名则跳过这一步,
|
||||
#### 四、恢复:SSH登录服务器找到/etc/x-ui/x-ui.db和/usr/local/x-ui/bin/config.json文件位置,上传之前的两个备份文件,进行覆盖,
|
||||

|
||||
##### PS:把之前通过自动备份下载得到的两个文件上传覆盖掉旧文件,重启〔X-Panel面板〕即可【迁移成功】;即使迁移过程中出现问题,你是有备份文件的,不用担心,多试几次。
|
||||

|
||||
#### 五、若安装了证书,去核对/更改一下证书的路径,一般是同一个域名的话,位置在:/root/cert/域名/fullchain.pem,路径是相同的就不用更改,
|
||||
#### 六、重启面板/重启服务器,让上述步骤生效即可,这时可以看到所有配置都是之前自己常用的,包括面板用户名、密码,入站、客户端,电报机器人配置等。
|
||||
#### PS:若您使用的是【Pro版】,则可直接使用:“创建数据快照 + 远程急救还原”功能,对面板数据库和配置文件进行操作。
|
||||
|
||||
------------
|
||||
## 安装完成后如何设置调整成【中文界面】?
|
||||
- 方法一:通过管理后台【登录页面】调整,登录时可以选择,如下图:
|
||||

|
||||
- 方法二:通过在管理后台-->【面板设置】中去选择设置,如下图:
|
||||

|
||||
- 【TG机器人】设置中文:通过在管理后台-->【面板设置】-->【机器人配置】中去选择设置,并建议打开数据库备份和登录通知,如下图:
|
||||

|
||||
|
||||
------------
|
||||
## 用〔X-Panel面板〕如何实现【自己偷自己】?
|
||||
- 其实很简单,只要你为面板设置了证书,
|
||||
- 开启了HTTPS登录,就可以将〔X-Panel面板〕自身作为Web Server,
|
||||
- 无需Nginx等,这里给一个示例:
|
||||
- 其中目标网站(Dest)请填写面板监听端口,
|
||||
- 可选域名(SNI)填写面板登录域名,
|
||||
- 如果您使用其他web server(如nginx)等,
|
||||
- 将目标网站改为对应监听端口也可。
|
||||
- 需要说明的是,如果您处于白名单地区,自己“偷”自己并不适合你;
|
||||
- 其次,可选域名一项实际上可以填写任意SNI,只要客户端保持一致即可,不过并不推荐这样做。
|
||||
- 配置方法如下图所示:
|
||||

|
||||
|
||||
------------
|
||||
## 〔子域名〕被墙针对特征
|
||||
#### 网络表现:
|
||||
##### 1、可以Ping通域名和IP地址,
|
||||
##### 2、子域名无法打开〔X-Panel面板〕管理界面,
|
||||
##### 3、什么都正常就是不能上网;
|
||||
|
||||
#### 问题:
|
||||
##### 你的子域名被墙针对了:无法上网!
|
||||
|
||||
#### 解决方案:
|
||||
##### 1、更换为新的子域名,
|
||||
##### 2、解析新的子域名到VPS的IP,
|
||||
##### 3、重新去安装新证书,
|
||||
##### 4、重启〔X-Panel面板〕和服务器,
|
||||
##### 5、重新去获取链接并测试上网。
|
||||
#### PS:若通过以上步骤还是不能正常上网,则重装VPS服务器OS系统,以及〔X-Panel面板〕全部重新安装,之后就正常了!
|
||||
|
||||
------------
|
||||
## 用〔X-Panel面板〕如何开启【设备限制】功能?
|
||||
##### 1、进入后台在【添加入站】的时候,弹出来的页面就能有【设备数量】输入框,
|
||||

|
||||
##### 2、通过步骤1设置完成后,在后台的【入站列表】页面也有对应的同步数据显示。
|
||||

|
||||
##### 3、具体要查看【设备限制】功能的封禁情况,就进入〔X-Panel面板〕后台用日志查看。
|
||||

|
||||
##### 4、以下图片里面,详细阐述了我们的〔设备限制〕功能,跟3X-UI原本就有的〔IP Limit〕之间的区别对比。
|
||||

|
||||
|
||||
------------
|
||||
## 用〔X-Panel面板〕如何开启【独立限速】功能?
|
||||
##### 1、进入后台在【添加入站】的时候,弹出来的页面在【客户/用户】那里就能输入具体数字,
|
||||

|
||||
##### 2、也可以在添加好一个【入站】之后,点击【添加客户端】去找到【独立限速】输入框,
|
||||

|
||||
##### 3、当你想批量一次性创建多个【客户/用户】时,同样可以使用【独立限速】功能,
|
||||

|
||||

|
||||
##### 4、若后期你想更改某一个【客户端/用户】的限制速率,那就自己先找到,然后点击【编辑】即可,
|
||||

|
||||
##### 5、具体要查看【独立限速】功能的启用情况,就进入〔X-Panel面板〕后台用日志查看。
|
||||

|
||||
|
||||
------------
|
||||
## 用〔X-Panel面板〕如何开启【每月流量自动重置】?
|
||||
##### 1、进入后台的【入站列表】,选择需要设置的【客户端】,
|
||||

|
||||
##### 2、要注意是编辑【入站】下面的【客户端】,才会有效果,
|
||||
##### 2、并不是编辑【入站】,所以不要弄错对象,如下图所示:
|
||||

|
||||
|
||||
|
||||
------------
|
||||
## 在自己的VPS服务器部署【订阅转换】功能
|
||||
### 如何把vless/vmess等协议转换成Clash/Surge等软件支持的格式?
|
||||
##### 1、进入脚本输入x-ui命令调取面板,选择第【25】选项安装订阅转换模块,
|
||||
##### 2、等待安装【订阅转换】成功之后,访问地址:https://你的域名:15268 ,
|
||||

|
||||
##### 3、因为在转换过程中需要调取后端API,所以请确保端口 8000 和 15268 是打开放行的,
|
||||
##### 4、直接复制脚本中提供的【登录地址】,进入后台,点击【节点列表】,如下图:
|
||||

|
||||
##### 5、接下来点击左边侧边栏的【订阅列表】去【添加订阅】,按照下图中去操作,
|
||||

|
||||
##### 6、最后一步,点击【客户端】,即可导入Clash等软件中使用。
|
||||

|
||||

|
||||
|
||||
------------
|
||||
## 常见的翻墙软件/工具:
|
||||
- [1、Windows系统v2rayN:https://github.com/2dust/v2rayN](https://github.com/2dust/v2rayN)
|
||||
- [2、安卓手机版【v2rayNG】:https://github.com/2dust/v2rayNG](https://github.com/2dust/v2rayNG)
|
||||
- [3、苹果手机IOS【小火箭】:https://apple02.com/(自己购买)](https://apple02.com/)
|
||||
- [4、苹果MacOS电脑【Clash Verge】:https://github.com/clash-verge-rev/clash-verge-rev/releases](https://github.com/clash-verge-rev/clash-verge-rev/releases)
|
||||
[或v2rayN:https://github.com/2dust/v2rayN](https://github.com/2dust/v2rayN)
|
||||
|
||||
------------
|
||||
## 如何保护自己的IP不被墙被封?
|
||||
##### 1、使用的代理协议要安全,加密是必备,推荐使用vless+reality+vision协议组合,
|
||||
##### 2、因为有时节点会共享,在不同的地区,多个省份之间不要共同连接同一个IP,
|
||||
##### 3、连接同一个IP就算了,不要同一个端口,不要同IP+同端口到处漫游,要分开,
|
||||
##### 4、同一台VPS,不要在一天内一直大流量去下载东西使用,不要流量过高要切换,
|
||||
##### 5、创建【入站协议】的时候,尽量用【高位端口】,比如40000--65000之间的端口号。
|
||||
#### 提醒:为什么在特殊时期,比如:两会,春节等被封得最严重最惨?
|
||||
##### 尼玛同一个IP+同一个端口号,多个省份去漫游,跟开飞机场一样!不封你,封谁的IP和端口?
|
||||
#### 总结:不要多终端/多省份/多个朋友/共同使用同一个IP和端口号!使用〔X-Panel面板〕多创建几个【入站】,
|
||||
#### 多做几条备用,各用各的!各行其道才比较安全!GFW的思维模式是干掉机场,机场的特征个人用户不要去沾染,自然IP就保护好了。
|
||||
|
||||
------------
|
||||
## SSL 认证
|
||||
|
||||
<details>
|
||||
<summary>点击查看 SSL 认证</summary>
|
||||
|
||||
### ACME
|
||||
|
||||
要使用 ACME 管理 SSL 证书:
|
||||
|
||||
1. 确保您的域名已正确解析到服务器,
|
||||
2. 输入“x-ui”命令并选择“SSL 证书管理”,
|
||||
3. 您将看到以下选项:
|
||||
|
||||
- **获取证书** ----获取SSL证书
|
||||
- **吊销证书** ----吊销现有的SSL证书
|
||||
- **续签证书** ----强制续签SSL证书
|
||||
- **显示所有证书** ----显示服务器中所有能用的证书
|
||||
- **设置面板证书路径** ----指定面板要使用的证书
|
||||
|
||||
|
||||
### Certbot
|
||||
|
||||
安装和使用 Certbot:
|
||||
|
||||
```sh
|
||||
apt-get install certbot -y
|
||||
certbot certonly --standalone --agree-tos --register-unsafely-without-email -d yourdomain.com
|
||||
certbot renew --dry-run
|
||||
```
|
||||
|
||||
### Cloudflare
|
||||
|
||||
管理脚本具有用于 Cloudflare 的内置 SSL 证书应用程序。若要使用此脚本申请证书,需要满足以下条件:
|
||||
|
||||
- Cloudflare 邮箱地址
|
||||
- Cloudflare Global API Key
|
||||
- 域名已通过 cloudflare 解析到当前服务器
|
||||
|
||||
**如何获取 Cloudflare全局API密钥:**
|
||||
|
||||
1. 在终端中输入“x-ui”命令,然后选择“CF SSL 证书”。
|
||||
2. 访问链接: [Cloudflare API Tokens](https://dash.cloudflare.com/profile/api-tokens).
|
||||
3. 点击“查看全局 API 密钥”(如下图所示):
|
||||

|
||||
4. 您可能需要重新验证您的帐户。之后,将显示 API 密钥(请参见下面的屏幕截图):
|
||||

|
||||
|
||||
使用时,只需输入您的“域名”、“电子邮件”和“API KEY”即可。示意图如下:
|
||||

|
||||
|
||||
|
||||
</details>
|
||||
|
||||
------------
|
||||
## 手动安装 & 升级
|
||||
|
||||
<details>
|
||||
<summary>点击查看 手动安装 & 升级</summary>
|
||||
|
||||
#### 使用
|
||||
|
||||
1. 若要将最新版本的压缩包直接下载到服务器,请运行以下命令:
|
||||
|
||||
```sh
|
||||
ARCH=$(uname -m)
|
||||
case "${ARCH}" in
|
||||
x86_64 | x64 | amd64) XUI_ARCH="amd64" ;;
|
||||
i*86 | x86) XUI_ARCH="386" ;;
|
||||
armv8* | armv8 | arm64 | aarch64) XUI_ARCH="arm64" ;;
|
||||
armv7* | armv7) XUI_ARCH="armv7" ;;
|
||||
armv6* | armv6) XUI_ARCH="armv6" ;;
|
||||
armv5* | armv5) XUI_ARCH="armv5" ;;
|
||||
s390x) echo 's390x' ;;
|
||||
*) XUI_ARCH="amd64" ;;
|
||||
esac
|
||||
|
||||
|
||||
wget https://github.com/xeefei/x-panel/releases/latest/download/x-ui-linux-${XUI_ARCH}.tar.gz
|
||||
```
|
||||
|
||||
2. 下载压缩包后,执行以下命令安装或升级 x-ui:
|
||||
|
||||
```sh
|
||||
ARCH=$(uname -m)
|
||||
case "${ARCH}" in
|
||||
x86_64 | x64 | amd64) XUI_ARCH="amd64" ;;
|
||||
i*86 | x86) XUI_ARCH="386" ;;
|
||||
armv8* | armv8 | arm64 | aarch64) XUI_ARCH="arm64" ;;
|
||||
armv7* | armv7) XUI_ARCH="armv7" ;;
|
||||
armv6* | armv6) XUI_ARCH="armv6" ;;
|
||||
armv5* | armv5) XUI_ARCH="armv5" ;;
|
||||
s390x) echo 's390x' ;;
|
||||
*) XUI_ARCH="amd64" ;;
|
||||
esac
|
||||
|
||||
cd /root/
|
||||
rm -rf x-ui/ /usr/local/x-ui/ /usr/bin/x-ui
|
||||
tar zxvf x-ui-linux-${XUI_ARCH}.tar.gz
|
||||
chmod +x x-ui/x-ui x-ui/bin/xray-linux-* x-ui/x-ui.sh
|
||||
cp x-ui/x-ui.sh /usr/bin/x-ui
|
||||
cp -f x-ui/x-ui.service /etc/systemd/system/
|
||||
mv x-ui/ /usr/local/
|
||||
systemctl daemon-reload
|
||||
systemctl enable x-ui
|
||||
systemctl restart x-ui
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
------------
|
||||
## 通过Docker安装
|
||||
|
||||
<details>
|
||||
<summary>点击查看 通过Docker安装</summary>
|
||||
|
||||
#### 使用
|
||||
|
||||
|
||||
1. **安装Docker**
|
||||
|
||||
```sh
|
||||
bash <(curl -sSL https://get.docker.com)
|
||||
```
|
||||
|
||||
|
||||
2. **克隆项目仓库**
|
||||
|
||||
```sh
|
||||
git clone https://github.com/xeefei/x-panel.git
|
||||
cd x-panel
|
||||
```
|
||||
|
||||
3. **启动服务**:
|
||||
|
||||
```sh
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
添加 ```--pull always``` 标志使 docker 在拉取更新的镜像时自动重新创建容器。有关更多信息,请参阅:https://docs.docker.com/reference/cli/docker/container/run/#pull
|
||||
|
||||
**或**
|
||||
|
||||
```sh
|
||||
docker run -itd \
|
||||
-e XRAY_VMESS_AEAD_FORCED=false \
|
||||
-v $PWD/db/:/etc/x-ui/ \
|
||||
-v $PWD/cert/:/root/cert/ \
|
||||
--network=host \
|
||||
--restart=unless-stopped \
|
||||
--name x-panel \
|
||||
ghcr.io/xeefei/x-panel:latest
|
||||
```
|
||||
|
||||
4. **更新至最新版本**
|
||||
|
||||
```sh
|
||||
cd x-panel
|
||||
docker compose down
|
||||
docker compose pull x-panel
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
5. **从Docker中删除x-panel **
|
||||
|
||||
```sh
|
||||
docker stop x-panel
|
||||
docker rm x-panel
|
||||
cd --
|
||||
rm -r x-panel
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
------------
|
||||
## 建议使用的操作系统
|
||||
|
||||
- Ubuntu 20.04+
|
||||
- Debian 11+
|
||||
- CentOS 8+
|
||||
- OpenEuler 22.03+
|
||||
- Fedora 36+
|
||||
- Arch Linux
|
||||
- Manjaro
|
||||
- Armbian
|
||||
- AlmaLinux 8.0+
|
||||
- Rocky Linux 8+
|
||||
- Oracle Linux 8+
|
||||
- OpenSUSE Tubleweed
|
||||
- Amazon Linux 2023
|
||||
|
||||
------------
|
||||
## 支持的架构和设备
|
||||
<details>
|
||||
<summary>点击查看 支持的架构和设备</summary>
|
||||
|
||||
我们的平台提供与各种架构和设备的兼容性,确保在各种计算环境中的灵活性。以下是我们支持的关键架构:
|
||||
|
||||
- **amd64**: 这种流行的架构是个人计算机和服务器的标准,可以无缝地适应大多数现代操作系统。
|
||||
|
||||
- **x86 / i386**: 这种架构在台式机和笔记本电脑中被广泛采用,得到了众多操作系统和应用程序的广泛支持,包括但不限于 Windows、macOS 和 Linux 系统。
|
||||
|
||||
- **armv8 / arm64 / aarch64**: 这种架构专为智能手机和平板电脑等当代移动和嵌入式设备量身定制,以 Raspberry Pi 4、Raspberry Pi 3、Raspberry Pi Zero 2/Zero 2 W、Orange Pi 3 LTS 等设备为例。
|
||||
|
||||
- **armv7 / arm / arm32**: 作为较旧的移动和嵌入式设备的架构,它仍然广泛用于Orange Pi Zero LTS、Orange Pi PC Plus、Raspberry Pi 2等设备。
|
||||
|
||||
- **armv6 / arm / arm32**: 这种架构面向非常老旧的嵌入式设备,虽然不太普遍,但仍在使用中。Raspberry Pi 1、Raspberry Pi Zero/Zero W 等设备都依赖于这种架构。
|
||||
|
||||
- **armv5 / arm / arm32**: 它是一种主要与早期嵌入式系统相关的旧架构,目前不太常见,但仍可能出现在早期 Raspberry Pi 版本和一些旧智能手机等传统设备中。
|
||||
</details>
|
||||
|
||||
------------
|
||||
## Languages
|
||||
|
||||
- English(英语)
|
||||
- Farsi(伊朗语)
|
||||
- Simplified Chinese(简体中文)
|
||||
- Traditional Chinese(繁体中文)
|
||||
- Russian(俄语)
|
||||
- Vietnamese(越南语)
|
||||
- Spanish(西班牙语)
|
||||
- Indonesian (印度尼西亚语)
|
||||
- Ukrainian(乌克兰语)
|
||||
- Turkish(土耳其语)
|
||||
- Português (葡萄牙语)
|
||||
|
||||
------------
|
||||
## 项目特点
|
||||
|
||||
- 系统状态查看与监控
|
||||
- 可搜索所有入站和客户端信息
|
||||
- 深色/浅色主题随意切换
|
||||
- 支持多用户和多协议
|
||||
- 支持多种协议,包括 VMess、VLESS、Trojan、Shadowsocks、Dokodemo-door、Socks、HTTP、wireguard
|
||||
- 支持 XTLS 原生协议,包括 RPRX-Direct、Vision、REALITY
|
||||
- 流量统计、流量限制、过期时间限制
|
||||
- 可自定义的 Xray配置模板
|
||||
- 支持HTTPS访问面板(自备域名+SSL证书)
|
||||
- 支持一键式SSL证书申请和自动续签证书
|
||||
- 更多高级配置项目请参考面板去进行设定
|
||||
- 修复了 API 路由(用户设置将使用 API 创建)
|
||||
- 支持通过面板中提供的不同项目更改配置。
|
||||
- 支持从面板导出/导入数据库
|
||||
|
||||
## 默认面板设置
|
||||
|
||||
<details>
|
||||
|
||||
<summary>点击查看 默认设置</summary>
|
||||
|
||||
### 默认信息
|
||||
|
||||
- **端口**
|
||||
- 13688
|
||||
- **用户名 & 密码 & 访问路径**
|
||||
- 当您跳过设置时,这些信息会随机生成,
|
||||
- 您也可以在安装的时候自定义访问路径。
|
||||
- **数据库文件路径:**
|
||||
- /etc/x-ui/x-ui.db
|
||||
- **Xray 配置文件路径:**
|
||||
- /usr/local/x-ui/bin/config.json
|
||||
- **面板链接(有SSL):**
|
||||
- https://你的域名:13688/访问路径/panel
|
||||
|
||||
</details>
|
||||
|
||||
------------
|
||||
## [WARP 配置](https://gitlab.com/fscarmen/warp)
|
||||
|
||||
<details>
|
||||
<summary>点击查看 WARP 配置</summary>
|
||||
|
||||
#### 使用
|
||||
|
||||
**对于版本 `v2.1.0` 及更高版本:**
|
||||
|
||||
WARP 是内置的,无需额外安装;只需在面板中打开必要的配置即可。
|
||||
|
||||
**如果要在 v2.1.0 之前使用 WARP 路由**,请按照以下步骤操作:
|
||||
|
||||
**1.** 在 **SOCKS Proxy Mode** 模式中安装Wrap
|
||||
|
||||
- **Account Type (free, plus, team):** Choose the appropriate account type.
|
||||
- **Enable/Disable WireProxy:** Toggle WireProxy on or off.
|
||||
- **Uninstall WARP:** Remove the WARP application.
|
||||
|
||||
**2.** 如果您已经安装了 warp,您可以使用以下命令卸载:
|
||||
|
||||
```sh
|
||||
warp u
|
||||
```
|
||||
|
||||
**3.** 在面板中打开您需要的配置
|
||||
|
||||
配置:
|
||||
|
||||
- Block Ads
|
||||
- Route Google, Netflix, Spotify, and OpenAI (ChatGPT) traffic to WARP
|
||||
- Fix Google 403 error
|
||||
|
||||
|
||||
</details>
|
||||
|
||||
------------
|
||||
## IP 限制
|
||||
|
||||
<details>
|
||||
<summary>点击查看 IP 限制</summary>
|
||||
|
||||
#### 使用
|
||||
|
||||
**注意:** 使用 IP 隧道时,IP 限制无法正常工作。
|
||||
|
||||
- 对于 `v1.6.1`之前的版本 :
|
||||
|
||||
- IP 限制 已被集成在面板中。
|
||||
|
||||
- 对于 `v1.7.0` 以及更新的版本:
|
||||
|
||||
- 要使 IP 限制正常工作,您需要按照以下步骤安装 fail2ban 及其所需的文件:
|
||||
|
||||
1. 使用面板内置的 `x-ui` 指令
|
||||
2. 选择 `IP Limit Management`.
|
||||
3. 根据您的需要选择合适的选项。
|
||||
|
||||
- 确保您的 Xray 配置上有 ./access.log 。在 v2.1.3 之后,我们有一个选项。
|
||||
|
||||
```sh
|
||||
"log": {
|
||||
"access": "./access.log",
|
||||
"dnsLog": false,
|
||||
"loglevel": "warning"
|
||||
},
|
||||
```
|
||||
- 您需要在Xray配置中手动设置〔访问日志〕的路径。
|
||||
|
||||
</details>
|
||||
|
||||
------------
|
||||
## Telegram 机器人
|
||||
|
||||
<details>
|
||||
<summary>点击查看 Telegram 机器人</summary>
|
||||
|
||||
#### 使用
|
||||
|
||||
Web 面板通过 Telegram Bot 支持每日流量、面板登录、数据库备份、系统状态、客户端信息等通知和功能。要使用机器人,您需要在面板中设置机器人相关参数,包括:
|
||||
|
||||
- 电报令牌
|
||||
- 管理员聊天 ID
|
||||
- 通知时间(cron 语法)
|
||||
- 到期日期通知
|
||||
- 流量上限通知
|
||||
- 数据库备份
|
||||
- CPU 负载通知
|
||||
|
||||
|
||||
**参考:**
|
||||
|
||||
- `30 \* \* \* \* \*` - 在每个点的 30 秒处通知
|
||||
- `0 \*/10 \* \* \* \*` - 每 10 分钟的第一秒通知
|
||||
- `@hourly` - 每小时通知
|
||||
- `@daily` - 每天通知 (00:00)
|
||||
- `@weekly` - 每周通知
|
||||
- `@every 8h` - 每8小时通知
|
||||
|
||||
### Telegram Bot 功能
|
||||
|
||||
- 定期报告
|
||||
- 登录通知
|
||||
- CPU 阈值通知
|
||||
- 提前报告的过期时间和流量阈值
|
||||
- 如果将客户的电报用户名添加到用户的配置中,则支持客户端报告菜单
|
||||
- 支持使用UUID(VMESS/VLESS)或密码(TROJAN)搜索报文流量报告 - 匿名
|
||||
- 基于菜单的机器人
|
||||
- 通过电子邮件搜索客户端(仅限管理员)
|
||||
- 检查所有入库
|
||||
- 检查服务器状态
|
||||
- 检查耗尽的用户
|
||||
- 根据请求和定期报告接收备份
|
||||
- 多语言机器人
|
||||
|
||||
### 注册 Telegram bot
|
||||
|
||||
- 与 [Botfather](https://t.me/BotFather) 对话:
|
||||

|
||||
|
||||
- 使用 /newbot 创建新机器人:你需要提供机器人名称以及用户名,注意名称中末尾要包含“bot”
|
||||

|
||||
|
||||
- 启动您刚刚创建的机器人。可以在此处找到机器人的链接。
|
||||

|
||||
|
||||
- 输入您的面板并配置 Telegram 机器人设置,如下所示:
|
||||

|
||||
|
||||
在输入字段编号 3 中输入机器人令牌。
|
||||
在输入字段编号 4 中输入用户 ID。具有此 id 的 Telegram 帐户将是机器人管理员。 (您可以输入多个,只需将它们用“ ,”分开即可)
|
||||
|
||||
- 如何获取TG ID? 使用 [bot](https://t.me/useridinfobot), 启动机器人,它会给你 Telegram 用户 ID。
|
||||

|
||||
|
||||
</details>
|
||||
|
||||
------------
|
||||
## API 路由
|
||||
|
||||
<details>
|
||||
<summary>点击查看 API 路由</summary>
|
||||
|
||||
#### 使用
|
||||
|
||||
- `/login` 使用 `POST` 用户名称 & 密码: `{username: '', password: ''}` 登录
|
||||
- `/panel/api/inbounds` 以下操作的基础:
|
||||
|
||||
| 方法 | 路径 | 操作 |
|
||||
| :----: | ---------------------------------- | ------------------------------------------- |
|
||||
| `GET` | `"/list"` | 获取所有入站 |
|
||||
| `GET` | `"/get/:id"` | 获取所有入站以及inbound.id |
|
||||
| `GET` | `"/getClientTraffics/:email"` | 通过电子邮件获取客户端流量 |
|
||||
| `GET` | `"/getClientTrafficsById/:id"` | 通过用户ID获取客户端流量 |
|
||||
| `GET` | `"/createbackup"` | Telegram 机器人向管理员发送备份 |
|
||||
| `POST` | `"/add"` | 添加入站 |
|
||||
| `POST` | `"/del/:id"` | 删除入站 |
|
||||
| `POST` | `"/update/:id"` | 更新入站 |
|
||||
| `POST` | `"/clientIps/:email"` | 客户端 IP 地址 |
|
||||
| `POST` | `"/clearClientIps/:email"` | 清除客户端 IP 地址 |
|
||||
| `POST` | `"/addClient"` | 将客户端添加到入站 |
|
||||
| `POST` | `"/:id/delClient/:clientId"` | 通过 clientId\* 删除客户端 |
|
||||
| `POST` | `"/updateClient/:clientId"` | 通过 clientId\* 更新客户端 |
|
||||
| `POST` | `"/:id/resetClientTraffic/:email"` | 重置客户端的流量 |
|
||||
| `POST` | `"/resetAllTraffics"` | 重置所有入站的流量 |
|
||||
| `POST` | `"/resetAllClientTraffics/:id"` | 重置入站中所有客户端的流量 |
|
||||
| `POST` | `"/delDepletedClients/:id"` | 删除入站耗尽的客户端 (-1: all) |
|
||||
| `POST` | `"/onlines"` | 获取在线用户 ( 电子邮件列表 ) |
|
||||
|
||||
- 使用`clientId` 项应该填写下列数据:
|
||||
|
||||
- `client.id` for VMESS and VLESS
|
||||
- `client.password` for TROJAN
|
||||
- `client.email` for Shadowsocks
|
||||
|
||||
|
||||
|
||||
- [API 文档](https://documenter.getpostman.com/view/16802678/2s9YkgD5jm)
|
||||
|
||||
- [<img src="https://run.pstmn.io/button.svg" alt="Run In Postman" style="width: 128px; height: 32px;">](https://app.getpostman.com/run-collection/16802678-1a4c9270-ac77-40ed-959a-7aa56dc4a415?action=collection%2Ffork&source=rip_markdown&collection-url=entityId%3D16802678-1a4c9270-ac77-40ed-959a-7aa56dc4a415%26entityType%3Dcollection%26workspaceId%3D2cd38c01-c851-4a15-a972-f181c23359d9)
|
||||
</details>
|
||||
|
||||
------------
|
||||
## 环境变量
|
||||
|
||||
<details>
|
||||
<summary>点击查看 环境变量</summary>
|
||||
|
||||
#### Usage
|
||||
|
||||
| 变量 | Type | 默认 |
|
||||
| -------------- | :--------------------------------------------: | :------------ |
|
||||
| XUI_LOG_LEVEL | `"debug"` \| `"info"` \| `"warn"` \| `"error"` | `"info"` |
|
||||
| XUI_DEBUG | `boolean` | `false` |
|
||||
| XUI_BIN_FOLDER | `string` | `"bin"` |
|
||||
| XUI_DB_FOLDER | `string` | `"/etc/x-ui"` |
|
||||
| XUI_LOG_FOLDER | `string` | `"/var/log"` |
|
||||
|
||||
例子:
|
||||
|
||||
```sh
|
||||
XUI_BIN_FOLDER="bin" XUI_DB_FOLDER="/etc/x-ui" go build main.go
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
------------
|
||||
## 预览
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
------------
|
||||
## 广告赞助
|
||||
- 如果你觉得本项目对你有用,而且你也恰巧有这方面的需求,你也可以选择通过我的购买链接赞助我。
|
||||
- [1、搬瓦工GIA高端线路,仅推荐购买GIA套餐:https://bandwagonhost.com/aff.php?aff=75015](https://bandwagonhost.com/aff.php?aff=75015)
|
||||
- [2、Dmit高端GIA线路:https://www.dmit.io/aff.php?aff=9326](https://www.dmit.io/aff.php?aff=9326)
|
||||
- [3、Gomami亚太顶尖优化线路:https://gomami.io/aff.php?aff=174](https://gomami.io/aff.php?aff=174)
|
||||
- [4、ISIF优质亚太优化线路:https://cloud.isif.net/login?affiliation_code=333](https://cloud.isif.net/login?affiliation_code=333)
|
||||
- [5、ZoroCloud全球优质原生家宽&住宅双lSP,跨境首选:https://my.zorocloud.com/aff.php?aff=1072](https://my.zorocloud.com/aff.php?aff=1072)
|
||||
- [6、三网直连 IEPL / IPLC 直播流量转发:https://idc333.top/#register/BCUZXNELNO](https://idc333.top/#register/BCUZXNELNO)
|
||||
- [7、Bagevm优质落地鸡(原生IP全解锁):https://www.bagevm.com/aff.php?aff=754](https://www.bagevm.com/aff.php?aff=754)
|
||||
- [8、白丝云【4837线路】实惠量大管饱:https://cloudsilk.io/aff.php?aff=706](https://cloudsilk.io/aff.php?aff=706)
|
||||
- [9、RackNerd极致性价比机器:https://my.racknerd.com/aff.php?aff=15268&pid=912](https://my.racknerd.com/aff.php?aff=15268&pid=912)
|
||||
|
||||
------------
|
||||
## 特别感谢
|
||||
|
||||
- [MHSanaei](https://github.com/MHSanaei/)
|
||||
- [alireza0](https://github.com/alireza0/)
|
||||
- [FranzKafkaYu](https://github.com/FranzKafkaYu/)
|
||||
- [vaxilu](https://github.com/vaxilu/)
|
||||
|
||||
------------
|
||||
## 致谢
|
||||
|
||||
- [Iran v2ray rules](https://github.com/chocolate4u/Iran-v2ray-rules) (License: **GPL-3.0**): _Enhanced v2ray/xray and v2ray/xray-clients routing rules with built-in Iranian domains and a focus on security and adblocking._
|
||||
- [Vietnam Adblock rules](https://github.com/vuong2023/vn-v2ray-rules) (License: **GPL-3.0**): _A hosted domain hosted in Vietnam and blocklist with the most efficiency for Vietnamese._
|
||||
|
||||
------------
|
||||
## Star 趋势
|
||||
|
||||
[](https://starchart.cc/xeefei/x-panel)
|
||||
56
README.ru_RU.md
Normal file
@@ -0,0 +1,56 @@
|
||||
[English](/README.md) | [فارسی](/README.fa_IR.md) | [العربية](/README.ar_EG.md) | [中文](/README.zh_CN.md) | [Español](/README.es_ES.md) | [Русский](/README.ru_RU.md)
|
||||
|
||||
<p align="center">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="./media/X-Panel.png">
|
||||
<img alt="3x-ui" src="./media/X-Panel.png">
|
||||
</picture>
|
||||
</p>
|
||||
|
||||
[](https://github.com/xeefei/x-panel/releases)
|
||||
[](https://github.com/xeefei/x-panel/actions)
|
||||
[](#)
|
||||
[](https://github.com/xeefei/x-panel/releases/latest)
|
||||
[](https://www.gnu.org/licenses/gpl-3.0.en.html)
|
||||
|
||||
**3X-UI** — продвинутая панель управления с открытым исходным кодом на основе веб-интерфейса, разработанная для управления сервером Xray-core. Предоставляет удобный интерфейс для настройки и мониторинга различных VPN и прокси-протоколов.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Этот проект предназначен только для личного использования, пожалуйста, не используйте его в незаконных целях и в производственной среде.
|
||||
|
||||
Как улучшенная версия оригинального проекта X-UI, 3X-UI обеспечивает повышенную стабильность, более широкую поддержку протоколов и дополнительные функции.
|
||||
|
||||
## Быстрый старт
|
||||
|
||||
```
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/xeefei/x-panel/master/install.sh)
|
||||
```
|
||||
|
||||
Полную документацию смотрите в [вики проекта](https://github.com/xeefei/x-panel/wiki).
|
||||
|
||||
## Особая благодарность
|
||||
|
||||
- [alireza0](https://github.com/alireza0/)
|
||||
|
||||
## Благодарности
|
||||
|
||||
- [Iran v2ray rules](https://github.com/chocolate4u/Iran-v2ray-rules) (Лицензия: **GPL-3.0**): _Улучшенные правила маршрутизации для v2ray/xray и v2ray/xray-clients со встроенными иранскими доменами и фокусом на безопасность и блокировку рекламы._
|
||||
- [Russia v2ray rules](https://github.com/runetfreedom/russia-v2ray-rules-dat) (Лицензия: **GPL-3.0**): _Этот репозиторий содержит автоматически обновляемые правила маршрутизации V2Ray на основе данных о заблокированных доменах и адресах в России._
|
||||
|
||||
## Поддержка проекта
|
||||
|
||||
**Если этот проект полезен для вас, вы можете поставить ему**:star2:
|
||||
|
||||
<p align="left">
|
||||
<a href="https://buymeacoffee.com/mhsanaei" target="_blank">
|
||||
<img src="./media/buymeacoffe.png" alt="Image">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
- USDT (TRC20): `TXncxkvhkDWGts487Pjqq1qT9JmwRUz8CC`
|
||||
- POL (polygon): `0x41C9548675D044c6Bfb425786C765bc37427256A`
|
||||
- LTC (Litecoin): `ltc1q2ach7x6d2zq0n4l0t4zl7d7xe2s6fs7a3vspwv`
|
||||
|
||||
## Звезды с течением времени
|
||||
|
||||
[](https://starchart.cc/xeefei/x-panel)
|
||||
938
README.zh.md
Normal file
@@ -0,0 +1,938 @@
|
||||
<p align="center"><a href="#"><img src="./media/X-Panel.png" alt="Image"></a></p>
|
||||
|
||||
**---------------------------------------一个更好的面板 • 基于Xray Core构建------------------------------**
|
||||
|
||||
|
||||
[](https://github.com/xeefei/x-panel/releases)
|
||||
[](https://github.com/xeefei/x-panel/actions)
|
||||
[](#)
|
||||
[](https://github.com/xeefei/x-panel/releases/latest)
|
||||
[](https://www.gnu.org/licenses/gpl-3.0.en.html)
|
||||
|
||||
> **声明:** 此项目仅供个人学习、交流使用,请遵守当地法律法规,勿用于非法用途;请勿用于生产环境。
|
||||
|
||||
> **注意:** 在使用此项目和〔教程〕过程中,若因违反以上声明使用规则而产生的一切后果由使用者自负。
|
||||
|
||||
**如果此项目对你有用,请给一个**:star2:
|
||||
|
||||
<p align="left">
|
||||
<a href="https://buymeacoffee.com/xeefeiz" target="_blank">
|
||||
<img src="./media/buymeacoffe.png" alt="Image">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
- “支持项目”赞助地址(USDT):
|
||||
- TRC20 ---->>> `TYQEmQp1P65u9bG7KPehgJdvuokfb72YkZ`
|
||||
- Polygon ---->>> `0xd20eBE429c2398793178e015B2ca1Dc42601f3Eb`
|
||||
- Solana ---->>> `7qVEZuV98QTDN5qUmsFwvqTSvkYpmLtNf8o1sh1mppwR`
|
||||
- BSC/BEP20 ---->>> `0xd20eBE429c2398793178e015B2ca1Dc42601f3Eb`
|
||||
|
||||
## [【X-Panel面板】交流群:https://t.me/XUI_CN](https://t.me/XUI_CN)
|
||||
## [【X-Panel面板】详细安装流程步骤:https://xeefei.blogspot.com/2025/09/x-panel.html](https://xeefei.blogspot.com/2025/09/x-panel.html)
|
||||
|
||||
|
||||
------------
|
||||
## ✰怎么购买【授权码】使用〔X-Panel-Pro版 面板〕?✰
|
||||
#### 1、【授权码】100/15U一个,一机一码,一直有效,永久使用,包括:重装,后期的升级/更新,都能使用,但是不能用于不同的机器,所以推荐稳定使用的机器用【授权码】,注:“授权码”属虚拟商品,购买之后,一经激活生效,概不退款,
|
||||
#### 2、对于一年期限(年付/年抛)的机器,后期可以【换绑】,为什么要有时间限制?就是为了防止,有些人拿【授权码】滥用,
|
||||
#### 3、购买方式/渠道联系机器人:[https://t.me/Buy_ShouQuan_Bot](https://t.me/Buy_ShouQuan_Bot)
|
||||
|
||||
#### 4、经常换的机器,去使用“免费基础版”就行,目前【安装界面】是有“两种方式”可选择的,
|
||||
|
||||
#### 5、对于有业务需求,比如做 TK 的,做〔跨境电商〕的,如果很多机器,比如:20台,50台,或者 100台 以上机器的宝子,若都要用【收费Pro版】的话,可以用【批量授权】:5 ——> 20台,8折,尾号:5555 ,20 ——> 50台,7折,尾号:66666 ,50 ——> 100台,6折,尾号:777777 ,100 ——> 200台,5折,尾号:8888888,200台 ——> 以上,4折,尾号:99999999,以上列举出来的,就是【批量折扣】的统一“优惠”。注:〔批量授权码〕要求最低5台以上,是“一码通用”,一个“授权码”,可以绑定验证多台 VPS 机器,并且有专属的“豹子号”授权码。
|
||||

|
||||
————————————————————————————————
|
||||
|
||||
#### 6、若您需要购买【授权码】,请跟下面这个“机器人”去对话,
|
||||
|
||||
#### ———————————————-
|
||||
|
||||
#### [https://t.me/Buy_ShouQuan_Bot](https://t.me/Buy_ShouQuan_Bot)
|
||||
#### (授权码购买机器人)
|
||||
|
||||
#### ———————————————-
|
||||
|
||||
#### 输入:/start 或 购买,即可“在线下单”,
|
||||
|
||||
#### 7、弹出【购买页面】,选择或输入“数量”,付款了支付系统会收到回调,金额到账之后,就会通过那个机器人【发放授权码】给您,整个流程,是【全自助】的“自动处理”方式,若您是〔增加配额〕,基本也是一样的流程,
|
||||
|
||||
#### 8、请注意:机器人发给您的所有信息,尽量都去自己【耐心阅读】一遍,“使用说明”,以及〔VIP 群〕的信息,也全部都包含在里面的,
|
||||
|
||||
#### 9、按照之前您安装更新〔X-Panel 面板〕的方式,直接重新输入【安装命令】,选择【2】,就能去,把之前的【免费版】,“无缝升级”到最新的【Pro版】。
|
||||
|
||||
————————————————————————————————
|
||||
#### 10、不能重复用于不同的机器 VPS,后期视情况不定时会上涨价格;对于〔X-Panel 面板〕后期的“新功能”,都将在【付费Pro版】中进行更新,
|
||||
|
||||
#### 11、目前的【安装界面】,是有:两种可选,“免费基础版”一样可用,只是后期不再提供技术支持和重大更新,另外,在【免费基础版】中,【一键配置】功能将不再可用,全部放到了【付费Pro版】中,
|
||||
|
||||
#### 12、后期的开发精力,全部会放到【付费Pro版】中,免费基础版不删库,持续保留,会大幅降低更新频率,后期只会同步更新 Xray 那边的【内核版本】等基础,想继续用的不影响,只是没有【新功能】可用,翻墙也足够。
|
||||
|
||||

|
||||
|
||||
------------
|
||||
## ✰〔X-Panel-Pro版 面板〕已实现的功能✰
|
||||
#### 1、新增 -【付费Pro版】的面板后台UI,添加醒目的“X-Panel-Pro”标识,
|
||||
#### 2、优化 -【付费Pro版】TG端 【版本更新】提示功能,增加详细的“更新说明”,
|
||||
#### 3、增加〔Pro版面板后台〕,使用 Reality 协议时,可点击随机更换所偷的域名,
|
||||
#### 4、新增 -【付费Pro版】TG端 的【发送授权报告】,增加“唯一授权防伪码”,
|
||||
#### 5、优化 -【付费Pro版】安装脚本界面,增加【Pro版】该有的“明确标识”,
|
||||
#### 6、优化 -【付费Pro版】TG端的显示方式,增加该有的“会员标识”,
|
||||
#### 7、新增 -【付费Pro版】安装脚本,有“网页版SSH工具”可选部署,脚本中〔第26选项〕,
|
||||
#### 8、新增 - 【付费Pro版】安装脚本,有“线路和IP质量检测”可去使用,脚本中〔第27选项〕,
|
||||
#### 9、新增 - 【付费Pro版】安装脚本,有“地区服务器DNS检测”可去使用,脚本中〔第28选项〕,
|
||||
#### 10、新增 -【付费Pro版】---->>>TG端,同步有“网页版SSH工具”可选安装,
|
||||
#### 11、优化 - 【付费Pro版】---->>>TG端,点击“服务器状态”时的“版本号显示”,
|
||||
#### 12、说明 - 【付费Pro版】TG端中,使用命令:/webssh,安装“网页版SSH”,
|
||||
#### 13、优化 -〔Pro版〕中的〔一键配置〕功能,有更友好的提示方式,
|
||||
#### 14、新增 -【付费Pro版】---->>>面板后台的【首页 UI】,目前是有“5种”可选:标准布局 (默认),炫彩动画,深海科技,暮光薰衣,和幽林秘境;你喜欢什么类型的主题,就去点击“选定”之后,就不会自动变了,若后期需要更换,就重选,
|
||||
#### 15、新增 -【付费Pro版】---->>>在“创建入站”时,可以在页面上更加方便地选择【重置流量】的方式:有每日重置,每周重置,按月重置,或从不重置,
|
||||
#### 16、新增 -〔X-Panel 面板〕----->>【付费Pro版】TG端“每日报告”,可定制【发送内容】,自己可点击“打开或关闭”,并且可以选择【发送时间】,可按天,或者每周,每月发,
|
||||
#### 17、优化 -【付费Pro版】的“授权码验证机制”,增加【后台联网验证】,以及“机器指纹”等属性,
|
||||
#### 18、新增 -〔X-Panel 面板〕----->>【付费Pro版】TG端“多面板管理”,一个机器人可同时管理其他面板,可以很丝滑地远程操作【被控端 VPS】,
|
||||
#### 19、新增 -〔X-Panel 面板〕----->>【付费Pro版】TG端“获取节点链接”功能,支持【本机】和【远程被控端 VPS】都能获取,开发此功能的目的在于:不用进〔面板后台〕,就能在 TG端 获取到之前已经创建过的“链接”,
|
||||
#### 20、新增 -〔X-Panel 面板〕----->>【付费Pro版】“一键部署中转节点”,解决了不懂配置的麻烦,已实现:远程Socks5创建 --> 本机路由配置 --> 本机入口创建 --> 生成“二维码和链接”,“小手一点”,直接可用,
|
||||
#### 21、新增 -〔X-Panel 面板〕----->>【申请安装证书】“第18选项”,有“备用方式申请证书”,当用常规方式【1】申请不下来时,可以试试“备用方式”,
|
||||
#### 22、新增 -〔X-Panel 面板〕----->>【申请安装证书】“第18选项”,有“可自定义证书路径”,自己进入 VPS 中“手动上传证书”,复制路径,在脚本中填入即可,
|
||||
#### 23、新增 -〔X-Panel 面板〕----->>【付费Pro版】“深度调优脚本”,包含 BBR+FQ, TCP Fast Open, 内存缓冲区及队列优化,在〔Pro版〕脚本中“第29选项”可直接用,
|
||||
#### 24、新增 -〔X-Panel 面板〕----->>【付费Pro版】“首页会员等级”显示,能够明确展示:自己的会员等级,授权码信息,以及“版本更新”提示,
|
||||
#### 25、新增 -〔X-Panel 面板〕----->>【付费Pro版】“节点上/下线TG通知”功能,对于【拼车】的宝子,能明确知道:哪个节点,什么时候上线?或者下线时间,做到“心中有数”,
|
||||
#### 26、新增 -〔X-Panel 面板〕----->>【付费Pro版】“签到得积分”功能,后期针对有【积分】的宝子,会不断推出:相应的【特权】和【福利待遇】,
|
||||
#### 27、新增 -〔X-Panel 面板〕----->>【付费Pro版】“TG端签到得积分”功能,推出:积分查询,积分换购,授权码查询,修改用户名,积分转移/打赏,以及“积分排行榜”,
|
||||
#### 28、新增 -〔X-Panel 面板〕----->>【付费Pro版】“TG端签到得积分”功能,推出【“积分换购”的可用功能】:A、消耗1000积分“自助重置换绑时间”,B、消耗5000积分“自助换购一个普通授权码”,
|
||||
#### 29、新增 -〔X-Panel 面板〕----->>【付费Pro版】“创建数据快照 + 远程急救还原”的提示功能: 可直观通过「终端UI界面」看到具体「备份 + 还原」步骤;用法:面板报错“崩了”,不用像之前那样:卸载面板 -->> 重装面板,更不用很麻烦去“重装系统”解决,直接:远程急救还原,前提就是:你自己要知道,在面板“正常运行”的时候,去「备份数据快照」,
|
||||
#### 30、新增 -〔X-Panel 面板〕----->>【付费Pro版】“每月重置流量”功能:可输入1—31之间的任意数字,比如:输入12,即代表“每月12号”「重置入站流量」,以便提供更友好的“重置流量方式”,
|
||||
#### 31、新增 -〔X-Panel 面板〕----->>【付费Pro版】“批量部署节点”功能:可直接在面板后台的“一键配置”中去使用,点击一次可批量部署生成10条「VLESS + TCP + Reality + Vision」协议组合的入站,
|
||||
#### 32、新增 -〔X-Panel 面板〕----->>【付费Pro版】“购买机器人”功能,可自助全自动在“机器人”中:购买授权码,增加配额,充值积分,自助重置换绑等,联系:[https://t.me/Buy_ShouQuan_Bot](https://t.me/Buy_ShouQuan_Bot) 。
|
||||

|
||||
|
||||
------------
|
||||
## ✰你必须要看的【重要安全提示/警告】✰
|
||||
#### 1、请勿使用【http明文模式】登录管理面板,因为明文会造成信息泄露;这个安全问题社区讨论过,
|
||||
#### 2、可使用设置【SSH端口转发功能】去登录面板或安装证书之后用https加密方式登录;两种方式选择其一,
|
||||

|
||||
#### 3、若无域名那就按照脚本提示去做【ssh转发】;有域名则可选择更加安全的【申请安装证书】方式,
|
||||
#### 4、Windows电脑首先通过快捷键【Win + R】调出运行窗口,在里面输入【cmd】打开本地终端服务,
|
||||

|
||||

|
||||

|
||||

|
||||
#### 5、若在搭建之前没有翻墙加密,则【http明文模式】登录面板有很大的信息泄露安全风险,那建议你第一次搭建成功之后,去修改用户/密码,和访问路径,后期则通过搭建好的代理加密访问,
|
||||

|
||||
#### 6、在做【ssh转发】过程中,本地电脑的终端不能关闭,保持打开不能断开;且每一次要登录〔X-Panel面板〕管理后台都要做【ssh转发】,因为关闭之后就失效了。
|
||||

|
||||
#### PS:上述两种方法:【ssh端口转发】或申请安装证书的目的都是为了更安全地登录面板,而至于搭建的其他流程和步骤,都是一样的;如果你已经【申请安装证书】了,并不会受到其他什么额外影响,就不用去折腾【ssh转发】了,直接用 【https://你的域名:端口/路径】 去登录你的面板管理后台就行了。
|
||||
|
||||
------------
|
||||
## 如何在〔X-Panel-Pro 面板〕中去使用【一个机器人管理多面板】功能?
|
||||
#### 1、先购买【授权码】安装好〔X-Panel-Pro 面板〕,进入后台,在【主从管理】界面,
|
||||

|
||||
#### 2、点击【添加被控端 VPS】,按照要求填入面板登录地址,用户名和密码,备注等信息,
|
||||

|
||||
#### 3、然后点击【配置本机“主控机器人”】,跳转到【机器人设置页面】,输入token令牌配置好,
|
||||

|
||||

|
||||
#### 4、现在重启本机 VPS,打开TG端机器人,即可看到【切换控制 VPS】等菜单,切换操作即可使用。
|
||||

|
||||

|
||||
|
||||
------------
|
||||
## 如何在〔X-Panel-Pro 面板〕中去使用【一键部署中转节点】的功能?
|
||||
#### 1、先购买【授权码】安装好〔X-Panel-Pro 面板〕,进入后台,在【主从管理】界面,
|
||||
#### 2、点击【添加中转机 VPS】,按照要求填入面板登录地址,用户名和密码,备注等信息,
|
||||

|
||||
#### 3、然后点击列表页中的【一键部署中转】,即可在后续的流程中,自动进入配置流程,
|
||||

|
||||
#### 4、稍等片刻,本机配置好的话就几秒,全自动给您生成了【二维码和中转链接】,复制可用,
|
||||

|
||||
#### 5、记得要去放行【本机】和【远程中转机】对应的端口,也可点击【检测中转节点】功能去看是否通?
|
||||

|
||||
|
||||
------------
|
||||
## ✰如何从其他x-ui版本迁移到〔X-Panel面板〕?✰
|
||||
#### 1、若你用的是伊朗老哥的3X-UI,是可以直接〔覆盖安装〕的,因为数据库文件等位置是没有改变的,所以直接覆盖安装,并不会影响你〔原有节点及配置〕等数据;安装命令如下:
|
||||
```
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/xeefei/x-panel/master/install.sh)
|
||||
```
|
||||
#### 2、若你之前用的是Docker方式安装,那先进入容器里面/命令:docker exec -it 容器id /bin/sh,再执行以上脚本命令直接【覆盖安装】即可,
|
||||
#### 3、若你用的是之前F佬的x-ui或者其他分支版本,那直接覆盖安装的话,并不能确保一定就能够兼容?建议你先去备份〔数据库〕配置文件,再进行安装〔X-Panel面板〕。
|
||||
|
||||
|
||||
------------
|
||||
## 安装之前的准备
|
||||
- 购买一台性能还不错的VPS,可通过本页底部链接购买,
|
||||
- PS:若你不想升级系统,则可以跳过此步骤。
|
||||
- 若你需要更新/升级系统,Debian系统可用如下命令:
|
||||
```
|
||||
apt update
|
||||
apt upgrade -y
|
||||
apt dist-upgrade -y
|
||||
apt autoclean
|
||||
apt autoremove -y
|
||||
```
|
||||
- 查看系统当前版本:
|
||||
```
|
||||
cat /etc/debian_version
|
||||
```
|
||||
- 查看内核版本:
|
||||
```
|
||||
uname -r
|
||||
```
|
||||
- 列出所有内核:
|
||||
```
|
||||
dpkg --list | grep linux-image
|
||||
```
|
||||
- 更新完成后执行重新引导:
|
||||
```
|
||||
update-grub
|
||||
```
|
||||
- 完成以上步骤之后输入reboot重启系统
|
||||
|
||||
------------
|
||||
## 【搬瓦工】重装/升级系统之后SSH连不上如何解决?
|
||||
- 【搬瓦工】重装/升级系统会恢复默认22端口,如果需要修改SSH的端口号,您需要进行以下步骤:
|
||||
- 以管理员身份使用默认22端口登录到SSH服务器
|
||||
- 打开SSH服务器的配置文件进行编辑,SSH配置文件通常位于/etc/ssh/sshd_config
|
||||
- 找到"Port"选项,并将其更改为您想要的端口号
|
||||
- Port <新端口号>,请将<新端口号>替换为您想要使用的端口号
|
||||
- 保存文件并退出编辑器
|
||||
- 重启服务器以使更改生效
|
||||
|
||||
------------
|
||||
## 安装 & 升级
|
||||
- 使用〔X-Panel面板〕脚本一般情况下,安装完成创建入站之后,端口是默认关闭的,所以必须进入脚本选择【22】去放行端口
|
||||
- 要使用【自动续签】证书功能,也必须放行【80】端口,保持80端口是打开的,才会每3个月自动续签一次
|
||||
|
||||
- 【全新安装】请执行以下脚本:
|
||||
```
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/xeefei/x-panel/master/install.sh)
|
||||
```
|
||||
#### 如果执行了上面的代码但是报错,证明你的系统里面没有curl这个软件,请执行以下命令先安装curl软件,安装curl之后再去执行上面代码,
|
||||
```
|
||||
apt update -y&&apt install -y curl&&apt install -y socat
|
||||
```
|
||||
|
||||
- 若要对版本进行升级,可直接通过脚本选择【2】,如下图:
|
||||

|
||||

|
||||
- 在到这一步必须要注意:要保留旧设置的话,需要输入【n】
|
||||

|
||||
|
||||
|
||||
## 安装指定版本
|
||||
|
||||
若要安装指定的版本,请使用以下安装命令。 e.g., ver `v26.2.15`:
|
||||
|
||||
```
|
||||
VERSION=v26.2.15 && bash <(curl -Ls "https://raw.githubusercontent.com/xeefei/x-panel/$VERSION/install.sh") $VERSION
|
||||
```
|
||||
------------
|
||||
## 若你的VPS默认有防火墙,请在安装完成之后放行指定端口
|
||||
- 放行【面板登录端口】
|
||||
- 放行出入站管理协议端口
|
||||
- 如果要申请安装证书并每3个月【自动续签】证书,请确保80和443端口是放行打开的
|
||||
- 可通过此脚本的第【21】选项去安装防火墙进行管理,如下图:
|
||||

|
||||
- 若要一次性放行多个端口或一整个段的端口,用英文逗号隔开。
|
||||
#### PS:若你的VPS没有防火墙,则所有端口都是能够ping通的,可自行选择是否进入脚本安装防火墙保证安全,但安装了防火墙必须放行相应端口。
|
||||
|
||||
------------
|
||||
## 如何在〔X-Panel面板〕中使用简单快捷的【一键配置】生成功能?
|
||||
#### 1、进入后台,并且你已经【安装了证书】,可在【添加入站】处看到,
|
||||

|
||||
#### 2、点击【一键配置】,在弹出的页面中【按需选择】去生成协议配置即可,
|
||||

|
||||
#### 3、直接复制【链接】,导入软件;若后台出现【醒目提示】,那就手动放行【相应端口】,
|
||||

|
||||
#### 4、若你是用【TG端电报机器人】的【一键配置】生成功能,那直接点击就用,
|
||||

|
||||
#### 5、选择好自己想要【一键创建】的协议组合类型,点击之后稍作等待,
|
||||

|
||||
#### 6、TG端【一键配置】创建成功之后,二维码和链接地址机器人会发送给你,如下:
|
||||

|
||||
|
||||
------------
|
||||
## 如何在〔X-Panel 项目〕中进行【抽奖游戏】赢奖品?
|
||||
#### 1、必须绑定好【TG端机器人】,怎么绑定?去看下面“绑定机器人”那部分教程,
|
||||
#### 2、在【TG端】直接点击【娱乐抽奖】菜单,就会弹出【每日幸运】抽奖游戏,
|
||||

|
||||
#### 3、点击【进行抽奖】,就可“全凭手气”得到随机的抽奖结果,如下图所示,
|
||||

|
||||
#### 4、在你【中奖】之后,截完整的“中奖页面”图片给交流群内管理员,即可兑奖。
|
||||

|
||||
|
||||
------------
|
||||
## 安装证书开启https方式实现域名登录访问管理面板/----->>偷自己
|
||||
#### PS:如果不需要以上功能或无域名,可以跳过这步;建议申请证书,
|
||||
##### 1、把自己的域名托管到CF,并解析到自己VPS的IP,不要开启【小云朵】,
|
||||
##### 2、如果要申请安装证书并每3个月【自动续签】证书,请确保80和443端口是放行打开的,
|
||||
##### 3、输入x-ui命令进入面板管理脚本,通过选择第【18】选项去进行安装,若使用 18 ---> 1方式不能申请下来,那就用 18--->5 备用方式去申请,或者也可用【19选项】去申请,
|
||||

|
||||
##### 4、首先输入解析好的【域名】进行验证,然后可以默认用【80端口】,直接回车申请,
|
||||

|
||||
##### 5、进入后台【面板设置】—–>【常规】中,会看到脚本已经自动填好了证书公钥、私钥路径,
|
||||
##### 6、点击左上角的【保存】和【重启面板】,即可用自己域名进行登录管理;也可按照后续方法实现【自己偷自己】。
|
||||
|
||||
------------
|
||||
## 登录面板进行【常规】设置
|
||||
### 特别是如果在安装过程中,全部都是默认【回车键】安装的话,用户名/密码/访问路径是随机的,而面板监听端口默认是:13688,可自行进入面板更改,
|
||||
##### 1、填写自己想要设置的【面板监听端口】,并去登录SSH放行,
|
||||
##### 2、更改自己想要设置的【面板登录访问路径】,后续加上路径登录访问,
|
||||

|
||||
##### 3、其他:安全设定和电报机器人等配置,可自行根据需求去进行设置,
|
||||
##### 4、强烈建议配置电报机器人,使用【TG端】可方便远程接管 VPS 服务器,
|
||||

|
||||
##### 5、面板设置【改动保存】之后,都需要点击左上角【重启面板】,才能生效。
|
||||
#### PS:若你在正确完成了上述步骤之后,你没有安装证书的情况下,去用【ssh转发】的方式却不能访问面板,那请检查一下是不是你的浏览器自动默认开启了https模式,需要手动调整一下改成http方式,把“s”去掉,即可访问成功;或查看一下是不是对应的端口被占用?
|
||||
|
||||
------------
|
||||
## 创建【入站协议】和添加【客户端】,并测试上网
|
||||
##### 1、点击左边【入站列表】,然后【添加入站】,传输方式保持【TCP】不变,尽量选择主流的vless+reality+vision协议组合,
|
||||

|
||||
##### 2、在选择reality安全选项时,偷的域名可以使用默认的,要使用其他的,请替换尽量保持一致就行,比如Apple、Yahoo,VPS所在地区的旅游、学校网站等;如果要实现【偷自己】,请参看后续【如何偷自己】的说明部分;而私钥/公钥部分,可以直接点击下方的【Get New Cert】获取一个随机的,
|
||||
##### 3、在创建reality安全选项过程中,至于其他诸如:PROXY Protocol,HTTP 伪装,TPROXY,External Proxy等等选项,若无特殊要求,保持默认设置即可,不用去动它们,
|
||||

|
||||
##### 4、创建好入站协议之后,默认只有一个客户端,可根据自己需求继续添加;重点:并编辑客户端,选择【Flow流控】为xtls-rprx-vision,
|
||||

|
||||
##### 5、其他:流量限制,到期时间,客户TG的ID等选项根据自己需求填写,
|
||||

|
||||
##### 6、一定要放行端口之后,确保端口能够ping通,再导入软件,
|
||||
##### 7、点击二维码或者复制链接导入到v2rayN等软件中进行测试。
|
||||
|
||||
------------
|
||||
## 备份与恢复/迁移数据库(以Debian系统为例)
|
||||
#### 一、备份:通过配置好电报管理机器人,可点击管理机器人的“相应菜单按钮”获取【备份配置】文件,有x-ui.db和config.json两个文件,可自行下载保存到自己电脑里面,
|
||||

|
||||
#### 二、搭建:在新的VPS中全新安装好〔X-Panel面板〕,通过脚本放行之前配置的所有端口,一次性放行多个端口请用【英文逗号】分隔,
|
||||
#### 三、若需要安装证书,则提前把域名解析到新的VPS对应的IP,并且去输入x-ui选择第【18】选项去安装,并记录公钥/私钥的路径,无域名则跳过这一步,
|
||||
#### 四、恢复:SSH登录服务器找到/etc/x-ui/x-ui.db和/usr/local/x-ui/bin/config.json文件位置,上传之前的两个备份文件,进行覆盖,
|
||||

|
||||
##### PS:把之前通过自动备份下载得到的两个文件上传覆盖掉旧文件,重启〔X-Panel面板〕即可【迁移成功】;即使迁移过程中出现问题,你是有备份文件的,不用担心,多试几次。
|
||||

|
||||
#### 五、若安装了证书,去核对/更改一下证书的路径,一般是同一个域名的话,位置在:/root/cert/域名/fullchain.pem,路径是相同的就不用更改,
|
||||
#### 六、重启面板/重启服务器,让上述步骤生效即可,这时可以看到所有配置都是之前自己常用的,包括面板用户名、密码,入站、客户端,电报机器人配置等。
|
||||
#### PS:若您使用的是【Pro版】,则可直接使用:“创建数据快照 + 远程急救还原”功能,对面板数据库和配置文件进行操作。
|
||||
|
||||
------------
|
||||
## 安装完成后如何设置调整成【中文界面】?
|
||||
- 方法一:通过管理后台【登录页面】调整,登录时可以选择,如下图:
|
||||

|
||||
- 方法二:通过在管理后台-->【面板设置】中去选择设置,如下图:
|
||||

|
||||
- 【TG机器人】设置中文:通过在管理后台-->【面板设置】-->【机器人配置】中去选择设置,并建议打开数据库备份和登录通知,如下图:
|
||||

|
||||
|
||||
------------
|
||||
## 用〔X-Panel面板〕如何实现【自己偷自己】?
|
||||
- 其实很简单,只要你为面板设置了证书,
|
||||
- 开启了HTTPS登录,就可以将〔X-Panel面板〕自身作为Web Server,
|
||||
- 无需Nginx等,这里给一个示例:
|
||||
- 其中目标网站(Dest)请填写面板监听端口,
|
||||
- 可选域名(SNI)填写面板登录域名,
|
||||
- 如果您使用其他web server(如nginx)等,
|
||||
- 将目标网站改为对应监听端口也可。
|
||||
- 需要说明的是,如果您处于白名单地区,自己“偷”自己并不适合你;
|
||||
- 其次,可选域名一项实际上可以填写任意SNI,只要客户端保持一致即可,不过并不推荐这样做。
|
||||
- 配置方法如下图所示:
|
||||

|
||||
|
||||
------------
|
||||
## 〔子域名〕被墙针对特征
|
||||
#### 网络表现:
|
||||
##### 1、可以Ping通域名和IP地址,
|
||||
##### 2、子域名无法打开〔X-Panel面板〕管理界面,
|
||||
##### 3、什么都正常就是不能上网;
|
||||
|
||||
#### 问题:
|
||||
##### 你的子域名被墙针对了:无法上网!
|
||||
|
||||
#### 解决方案:
|
||||
##### 1、更换为新的子域名,
|
||||
##### 2、解析新的子域名到VPS的IP,
|
||||
##### 3、重新去安装新证书,
|
||||
##### 4、重启〔X-Panel面板〕和服务器,
|
||||
##### 5、重新去获取链接并测试上网。
|
||||
#### PS:若通过以上步骤还是不能正常上网,则重装VPS服务器OS系统,以及〔X-Panel面板〕全部重新安装,之后就正常了!
|
||||
|
||||
------------
|
||||
## 用〔X-Panel面板〕如何开启【设备限制】功能?
|
||||
##### 1、进入后台在【添加入站】的时候,弹出来的页面就能有【设备数量】输入框,
|
||||

|
||||
##### 2、通过步骤1设置完成后,在后台的【入站列表】页面也有对应的同步数据显示。
|
||||

|
||||
##### 3、具体要查看【设备限制】功能的封禁情况,就进入〔X-Panel面板〕后台用日志查看。
|
||||

|
||||
##### 4、以下图片里面,详细阐述了我们的〔设备限制〕功能,跟3X-UI原本就有的〔IP Limit〕之间的区别对比。
|
||||

|
||||
|
||||
------------
|
||||
## 用〔X-Panel面板〕如何开启【独立限速】功能?
|
||||
##### 1、进入后台在【添加入站】的时候,弹出来的页面在【客户/用户】那里就能输入具体数字,
|
||||

|
||||
##### 2、也可以在添加好一个【入站】之后,点击【添加客户端】去找到【独立限速】输入框,
|
||||

|
||||
##### 3、当你想批量一次性创建多个【客户/用户】时,同样可以使用【独立限速】功能,
|
||||

|
||||

|
||||
##### 4、若后期你想更改某一个【客户端/用户】的限制速率,那就自己先找到,然后点击【编辑】即可,
|
||||

|
||||
##### 5、具体要查看【独立限速】功能的启用情况,就进入〔X-Panel面板〕后台用日志查看。
|
||||

|
||||
|
||||
------------
|
||||
## 用〔X-Panel面板〕如何开启【每月流量自动重置】?
|
||||
##### 1、进入后台的【入站列表】,选择需要设置的【客户端】,
|
||||

|
||||
##### 2、要注意是编辑【入站】下面的【客户端】,才会有效果,
|
||||
##### 2、并不是编辑【入站】,所以不要弄错对象,如下图所示:
|
||||

|
||||
|
||||
|
||||
------------
|
||||
## 在自己的VPS服务器部署【订阅转换】功能
|
||||
### 如何把vless/vmess等协议转换成Clash/Surge等软件支持的格式?
|
||||
##### 1、进入脚本输入x-ui命令调取面板,选择第【25】选项安装订阅转换模块,
|
||||
##### 2、等待安装【订阅转换】成功之后,访问地址:https://你的域名:15268 ,
|
||||

|
||||
##### 3、因为在转换过程中需要调取后端API,所以请确保端口 8000 和 15268 是打开放行的,
|
||||
##### 4、直接复制脚本中提供的【登录地址】,进入后台,点击【节点列表】,如下图:
|
||||

|
||||
##### 5、接下来点击左边侧边栏的【订阅列表】去【添加订阅】,按照下图中去操作,
|
||||

|
||||
##### 6、最后一步,点击【客户端】,即可导入Clash等软件中使用。
|
||||

|
||||

|
||||
|
||||
------------
|
||||
## 常见的翻墙软件/工具:
|
||||
- [1、Windows系统v2rayN:https://github.com/2dust/v2rayN](https://github.com/2dust/v2rayN)
|
||||
- [2、安卓手机版【v2rayNG】:https://github.com/2dust/v2rayNG](https://github.com/2dust/v2rayNG)
|
||||
- [3、苹果手机IOS【小火箭】:https://apple02.com/(自己购买)](https://apple02.com/)
|
||||
- [4、苹果MacOS电脑【Clash Verge】:https://github.com/clash-verge-rev/clash-verge-rev/releases](https://github.com/clash-verge-rev/clash-verge-rev/releases)
|
||||
[或v2rayN:https://github.com/2dust/v2rayN](https://github.com/2dust/v2rayN)
|
||||
|
||||
------------
|
||||
## 如何保护自己的IP不被墙被封?
|
||||
##### 1、使用的代理协议要安全,加密是必备,推荐使用vless+reality+vision协议组合,
|
||||
##### 2、因为有时节点会共享,在不同的地区,多个省份之间不要共同连接同一个IP,
|
||||
##### 3、连接同一个IP就算了,不要同一个端口,不要同IP+同端口到处漫游,要分开,
|
||||
##### 4、同一台VPS,不要在一天内一直大流量去下载东西使用,不要流量过高要切换,
|
||||
##### 5、创建【入站协议】的时候,尽量用【高位端口】,比如40000--65000之间的端口号。
|
||||
#### 提醒:为什么在特殊时期,比如:两会,春节等被封得最严重最惨?
|
||||
##### 尼玛同一个IP+同一个端口号,多个省份去漫游,跟开飞机场一样!不封你,封谁的IP和端口?
|
||||
#### 总结:不要多终端/多省份/多个朋友/共同使用同一个IP和端口号!使用〔X-Panel面板〕多创建几个【入站】,
|
||||
#### 多做几条备用,各用各的!各行其道才比较安全!GFW的思维模式是干掉机场,机场的特征个人用户不要去沾染,自然IP就保护好了。
|
||||
|
||||
------------
|
||||
## SSL 认证
|
||||
|
||||
<details>
|
||||
<summary>点击查看 SSL 认证</summary>
|
||||
|
||||
### ACME
|
||||
|
||||
要使用 ACME 管理 SSL 证书:
|
||||
|
||||
1. 确保您的域名已正确解析到服务器,
|
||||
2. 输入“x-ui”命令并选择“SSL 证书管理”,
|
||||
3. 您将看到以下选项:
|
||||
|
||||
- **获取证书** ----获取SSL证书
|
||||
- **吊销证书** ----吊销现有的SSL证书
|
||||
- **续签证书** ----强制续签SSL证书
|
||||
- **显示所有证书** ----显示服务器中所有能用的证书
|
||||
- **设置面板证书路径** ----指定面板要使用的证书
|
||||
|
||||
|
||||
### Certbot
|
||||
|
||||
安装和使用 Certbot:
|
||||
|
||||
```sh
|
||||
apt-get install certbot -y
|
||||
certbot certonly --standalone --agree-tos --register-unsafely-without-email -d yourdomain.com
|
||||
certbot renew --dry-run
|
||||
```
|
||||
|
||||
### Cloudflare
|
||||
|
||||
管理脚本具有用于 Cloudflare 的内置 SSL 证书应用程序。若要使用此脚本申请证书,需要满足以下条件:
|
||||
|
||||
- Cloudflare 邮箱地址
|
||||
- Cloudflare Global API Key
|
||||
- 域名已通过 cloudflare 解析到当前服务器
|
||||
|
||||
**如何获取 Cloudflare全局API密钥:**
|
||||
|
||||
1. 在终端中输入“x-ui”命令,然后选择“CF SSL 证书”。
|
||||
2. 访问链接: [Cloudflare API Tokens](https://dash.cloudflare.com/profile/api-tokens).
|
||||
3. 点击“查看全局 API 密钥”(如下图所示):
|
||||

|
||||
4. 您可能需要重新验证您的帐户。之后,将显示 API 密钥(请参见下面的屏幕截图):
|
||||

|
||||
|
||||
使用时,只需输入您的“域名”、“电子邮件”和“API KEY”即可。示意图如下:
|
||||

|
||||
|
||||
|
||||
</details>
|
||||
|
||||
------------
|
||||
## 手动安装 & 升级
|
||||
|
||||
<details>
|
||||
<summary>点击查看 手动安装 & 升级</summary>
|
||||
|
||||
#### 使用
|
||||
|
||||
1. 若要将最新版本的压缩包直接下载到服务器,请运行以下命令:
|
||||
|
||||
```sh
|
||||
ARCH=$(uname -m)
|
||||
case "${ARCH}" in
|
||||
x86_64 | x64 | amd64) XUI_ARCH="amd64" ;;
|
||||
i*86 | x86) XUI_ARCH="386" ;;
|
||||
armv8* | armv8 | arm64 | aarch64) XUI_ARCH="arm64" ;;
|
||||
armv7* | armv7) XUI_ARCH="armv7" ;;
|
||||
armv6* | armv6) XUI_ARCH="armv6" ;;
|
||||
armv5* | armv5) XUI_ARCH="armv5" ;;
|
||||
s390x) echo 's390x' ;;
|
||||
*) XUI_ARCH="amd64" ;;
|
||||
esac
|
||||
|
||||
|
||||
wget https://github.com/xeefei/x-panel/releases/latest/download/x-ui-linux-${XUI_ARCH}.tar.gz
|
||||
```
|
||||
|
||||
2. 下载压缩包后,执行以下命令安装或升级 x-ui:
|
||||
|
||||
```sh
|
||||
ARCH=$(uname -m)
|
||||
case "${ARCH}" in
|
||||
x86_64 | x64 | amd64) XUI_ARCH="amd64" ;;
|
||||
i*86 | x86) XUI_ARCH="386" ;;
|
||||
armv8* | armv8 | arm64 | aarch64) XUI_ARCH="arm64" ;;
|
||||
armv7* | armv7) XUI_ARCH="armv7" ;;
|
||||
armv6* | armv6) XUI_ARCH="armv6" ;;
|
||||
armv5* | armv5) XUI_ARCH="armv5" ;;
|
||||
s390x) echo 's390x' ;;
|
||||
*) XUI_ARCH="amd64" ;;
|
||||
esac
|
||||
|
||||
cd /root/
|
||||
rm -rf x-ui/ /usr/local/x-ui/ /usr/bin/x-ui
|
||||
tar zxvf x-ui-linux-${XUI_ARCH}.tar.gz
|
||||
chmod +x x-ui/x-ui x-ui/bin/xray-linux-* x-ui/x-ui.sh
|
||||
cp x-ui/x-ui.sh /usr/bin/x-ui
|
||||
cp -f x-ui/x-ui.service /etc/systemd/system/
|
||||
mv x-ui/ /usr/local/
|
||||
systemctl daemon-reload
|
||||
systemctl enable x-ui
|
||||
systemctl restart x-ui
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
------------
|
||||
## 通过Docker安装
|
||||
|
||||
<details>
|
||||
<summary>点击查看 通过Docker安装</summary>
|
||||
|
||||
#### 使用
|
||||
|
||||
|
||||
1. **安装Docker**
|
||||
|
||||
```sh
|
||||
bash <(curl -sSL https://get.docker.com)
|
||||
```
|
||||
|
||||
|
||||
2. **克隆项目仓库**
|
||||
|
||||
```sh
|
||||
git clone https://github.com/xeefei/x-panel.git
|
||||
cd x-panel
|
||||
```
|
||||
|
||||
3. **启动服务**:
|
||||
|
||||
```sh
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
添加 ```--pull always``` 标志使 docker 在拉取更新的镜像时自动重新创建容器。有关更多信息,请参阅:https://docs.docker.com/reference/cli/docker/container/run/#pull
|
||||
|
||||
**或**
|
||||
|
||||
```sh
|
||||
docker run -itd \
|
||||
-e XRAY_VMESS_AEAD_FORCED=false \
|
||||
-v $PWD/db/:/etc/x-ui/ \
|
||||
-v $PWD/cert/:/root/cert/ \
|
||||
--network=host \
|
||||
--restart=unless-stopped \
|
||||
--name x-panel \
|
||||
ghcr.io/xeefei/x-panel:latest
|
||||
```
|
||||
|
||||
4. **更新至最新版本**
|
||||
|
||||
```sh
|
||||
cd x-panel
|
||||
docker compose down
|
||||
docker compose pull x-panel
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
5. **从Docker中删除x-panel **
|
||||
|
||||
```sh
|
||||
docker stop x-panel
|
||||
docker rm x-panel
|
||||
cd --
|
||||
rm -r x-panel
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
------------
|
||||
## 建议使用的操作系统
|
||||
|
||||
- Ubuntu 20.04+
|
||||
- Debian 11+
|
||||
- CentOS 8+
|
||||
- OpenEuler 22.03+
|
||||
- Fedora 36+
|
||||
- Arch Linux
|
||||
- Manjaro
|
||||
- Armbian
|
||||
- AlmaLinux 8.0+
|
||||
- Rocky Linux 8+
|
||||
- Oracle Linux 8+
|
||||
- OpenSUSE Tubleweed
|
||||
- Amazon Linux 2023
|
||||
|
||||
------------
|
||||
## 支持的架构和设备
|
||||
<details>
|
||||
<summary>点击查看 支持的架构和设备</summary>
|
||||
|
||||
我们的平台提供与各种架构和设备的兼容性,确保在各种计算环境中的灵活性。以下是我们支持的关键架构:
|
||||
|
||||
- **amd64**: 这种流行的架构是个人计算机和服务器的标准,可以无缝地适应大多数现代操作系统。
|
||||
|
||||
- **x86 / i386**: 这种架构在台式机和笔记本电脑中被广泛采用,得到了众多操作系统和应用程序的广泛支持,包括但不限于 Windows、macOS 和 Linux 系统。
|
||||
|
||||
- **armv8 / arm64 / aarch64**: 这种架构专为智能手机和平板电脑等当代移动和嵌入式设备量身定制,以 Raspberry Pi 4、Raspberry Pi 3、Raspberry Pi Zero 2/Zero 2 W、Orange Pi 3 LTS 等设备为例。
|
||||
|
||||
- **armv7 / arm / arm32**: 作为较旧的移动和嵌入式设备的架构,它仍然广泛用于Orange Pi Zero LTS、Orange Pi PC Plus、Raspberry Pi 2等设备。
|
||||
|
||||
- **armv6 / arm / arm32**: 这种架构面向非常老旧的嵌入式设备,虽然不太普遍,但仍在使用中。Raspberry Pi 1、Raspberry Pi Zero/Zero W 等设备都依赖于这种架构。
|
||||
|
||||
- **armv5 / arm / arm32**: 它是一种主要与早期嵌入式系统相关的旧架构,目前不太常见,但仍可能出现在早期 Raspberry Pi 版本和一些旧智能手机等传统设备中。
|
||||
</details>
|
||||
|
||||
------------
|
||||
## Languages
|
||||
|
||||
- English(英语)
|
||||
- Farsi(伊朗语)
|
||||
- Simplified Chinese(简体中文)
|
||||
- Traditional Chinese(繁体中文)
|
||||
- Russian(俄语)
|
||||
- Vietnamese(越南语)
|
||||
- Spanish(西班牙语)
|
||||
- Indonesian (印度尼西亚语)
|
||||
- Ukrainian(乌克兰语)
|
||||
- Turkish(土耳其语)
|
||||
- Português (葡萄牙语)
|
||||
|
||||
------------
|
||||
## 项目特点
|
||||
|
||||
- 系统状态查看与监控
|
||||
- 可搜索所有入站和客户端信息
|
||||
- 深色/浅色主题随意切换
|
||||
- 支持多用户和多协议
|
||||
- 支持多种协议,包括 VMess、VLESS、Trojan、Shadowsocks、Dokodemo-door、Socks、HTTP、wireguard
|
||||
- 支持 XTLS 原生协议,包括 RPRX-Direct、Vision、REALITY
|
||||
- 流量统计、流量限制、过期时间限制
|
||||
- 可自定义的 Xray配置模板
|
||||
- 支持HTTPS访问面板(自备域名+SSL证书)
|
||||
- 支持一键式SSL证书申请和自动续签证书
|
||||
- 更多高级配置项目请参考面板去进行设定
|
||||
- 修复了 API 路由(用户设置将使用 API 创建)
|
||||
- 支持通过面板中提供的不同项目更改配置。
|
||||
- 支持从面板导出/导入数据库
|
||||
|
||||
## 默认面板设置
|
||||
|
||||
<details>
|
||||
|
||||
<summary>点击查看 默认设置</summary>
|
||||
|
||||
### 默认信息
|
||||
|
||||
- **端口**
|
||||
- 13688
|
||||
- **用户名 & 密码 & 访问路径**
|
||||
- 当您跳过设置时,这些信息会随机生成,
|
||||
- 您也可以在安装的时候自定义访问路径。
|
||||
- **数据库文件路径:**
|
||||
- /etc/x-ui/x-ui.db
|
||||
- **Xray 配置文件路径:**
|
||||
- /usr/local/x-ui/bin/config.json
|
||||
- **面板链接(有SSL):**
|
||||
- https://你的域名:13688/访问路径/panel
|
||||
|
||||
</details>
|
||||
|
||||
------------
|
||||
## [WARP 配置](https://gitlab.com/fscarmen/warp)
|
||||
|
||||
<details>
|
||||
<summary>点击查看 WARP 配置</summary>
|
||||
|
||||
#### 使用
|
||||
|
||||
**对于版本 `v2.1.0` 及更高版本:**
|
||||
|
||||
WARP 是内置的,无需额外安装;只需在面板中打开必要的配置即可。
|
||||
|
||||
**如果要在 v2.1.0 之前使用 WARP 路由**,请按照以下步骤操作:
|
||||
|
||||
**1.** 在 **SOCKS Proxy Mode** 模式中安装Wrap
|
||||
|
||||
- **Account Type (free, plus, team):** Choose the appropriate account type.
|
||||
- **Enable/Disable WireProxy:** Toggle WireProxy on or off.
|
||||
- **Uninstall WARP:** Remove the WARP application.
|
||||
|
||||
**2.** 如果您已经安装了 warp,您可以使用以下命令卸载:
|
||||
|
||||
```sh
|
||||
warp u
|
||||
```
|
||||
|
||||
**3.** 在面板中打开您需要的配置
|
||||
|
||||
配置:
|
||||
|
||||
- Block Ads
|
||||
- Route Google, Netflix, Spotify, and OpenAI (ChatGPT) traffic to WARP
|
||||
- Fix Google 403 error
|
||||
|
||||
|
||||
</details>
|
||||
|
||||
------------
|
||||
## IP 限制
|
||||
|
||||
<details>
|
||||
<summary>点击查看 IP 限制</summary>
|
||||
|
||||
#### 使用
|
||||
|
||||
**注意:** 使用 IP 隧道时,IP 限制无法正常工作。
|
||||
|
||||
- 对于 `v1.6.1`之前的版本 :
|
||||
|
||||
- IP 限制 已被集成在面板中。
|
||||
|
||||
- 对于 `v1.7.0` 以及更新的版本:
|
||||
|
||||
- 要使 IP 限制正常工作,您需要按照以下步骤安装 fail2ban 及其所需的文件:
|
||||
|
||||
1. 使用面板内置的 `x-ui` 指令
|
||||
2. 选择 `IP Limit Management`.
|
||||
3. 根据您的需要选择合适的选项。
|
||||
|
||||
- 确保您的 Xray 配置上有 ./access.log 。在 v2.1.3 之后,我们有一个选项。
|
||||
|
||||
```sh
|
||||
"log": {
|
||||
"access": "./access.log",
|
||||
"dnsLog": false,
|
||||
"loglevel": "warning"
|
||||
},
|
||||
```
|
||||
- 您需要在Xray配置中手动设置〔访问日志〕的路径。
|
||||
|
||||
</details>
|
||||
|
||||
------------
|
||||
## Telegram 机器人
|
||||
|
||||
<details>
|
||||
<summary>点击查看 Telegram 机器人</summary>
|
||||
|
||||
#### 使用
|
||||
|
||||
Web 面板通过 Telegram Bot 支持每日流量、面板登录、数据库备份、系统状态、客户端信息等通知和功能。要使用机器人,您需要在面板中设置机器人相关参数,包括:
|
||||
|
||||
- 电报令牌
|
||||
- 管理员聊天 ID
|
||||
- 通知时间(cron 语法)
|
||||
- 到期日期通知
|
||||
- 流量上限通知
|
||||
- 数据库备份
|
||||
- CPU 负载通知
|
||||
|
||||
|
||||
**参考:**
|
||||
|
||||
- `30 \* \* \* \* \*` - 在每个点的 30 秒处通知
|
||||
- `0 \*/10 \* \* \* \*` - 每 10 分钟的第一秒通知
|
||||
- `@hourly` - 每小时通知
|
||||
- `@daily` - 每天通知 (00:00)
|
||||
- `@weekly` - 每周通知
|
||||
- `@every 8h` - 每8小时通知
|
||||
|
||||
### Telegram Bot 功能
|
||||
|
||||
- 定期报告
|
||||
- 登录通知
|
||||
- CPU 阈值通知
|
||||
- 提前报告的过期时间和流量阈值
|
||||
- 如果将客户的电报用户名添加到用户的配置中,则支持客户端报告菜单
|
||||
- 支持使用UUID(VMESS/VLESS)或密码(TROJAN)搜索报文流量报告 - 匿名
|
||||
- 基于菜单的机器人
|
||||
- 通过电子邮件搜索客户端(仅限管理员)
|
||||
- 检查所有入库
|
||||
- 检查服务器状态
|
||||
- 检查耗尽的用户
|
||||
- 根据请求和定期报告接收备份
|
||||
- 多语言机器人
|
||||
|
||||
### 注册 Telegram bot
|
||||
|
||||
- 与 [Botfather](https://t.me/BotFather) 对话:
|
||||

|
||||
|
||||
- 使用 /newbot 创建新机器人:你需要提供机器人名称以及用户名,注意名称中末尾要包含“bot”
|
||||

|
||||
|
||||
- 启动您刚刚创建的机器人。可以在此处找到机器人的链接。
|
||||

|
||||
|
||||
- 输入您的面板并配置 Telegram 机器人设置,如下所示:
|
||||

|
||||
|
||||
在输入字段编号 3 中输入机器人令牌。
|
||||
在输入字段编号 4 中输入用户 ID。具有此 id 的 Telegram 帐户将是机器人管理员。 (您可以输入多个,只需将它们用“ ,”分开即可)
|
||||
|
||||
- 如何获取TG ID? 使用 [bot](https://t.me/useridinfobot), 启动机器人,它会给你 Telegram 用户 ID。
|
||||

|
||||
|
||||
</details>
|
||||
|
||||
------------
|
||||
## API 路由
|
||||
|
||||
<details>
|
||||
<summary>点击查看 API 路由</summary>
|
||||
|
||||
#### 使用
|
||||
|
||||
- `/login` 使用 `POST` 用户名称 & 密码: `{username: '', password: ''}` 登录
|
||||
- `/panel/api/inbounds` 以下操作的基础:
|
||||
|
||||
| 方法 | 路径 | 操作 |
|
||||
| :----: | ---------------------------------- | ------------------------------------------- |
|
||||
| `GET` | `"/list"` | 获取所有入站 |
|
||||
| `GET` | `"/get/:id"` | 获取所有入站以及inbound.id |
|
||||
| `GET` | `"/getClientTraffics/:email"` | 通过电子邮件获取客户端流量 |
|
||||
| `GET` | `"/getClientTrafficsById/:id"` | 通过用户ID获取客户端流量 |
|
||||
| `GET` | `"/createbackup"` | Telegram 机器人向管理员发送备份 |
|
||||
| `POST` | `"/add"` | 添加入站 |
|
||||
| `POST` | `"/del/:id"` | 删除入站 |
|
||||
| `POST` | `"/update/:id"` | 更新入站 |
|
||||
| `POST` | `"/clientIps/:email"` | 客户端 IP 地址 |
|
||||
| `POST` | `"/clearClientIps/:email"` | 清除客户端 IP 地址 |
|
||||
| `POST` | `"/addClient"` | 将客户端添加到入站 |
|
||||
| `POST` | `"/:id/delClient/:clientId"` | 通过 clientId\* 删除客户端 |
|
||||
| `POST` | `"/updateClient/:clientId"` | 通过 clientId\* 更新客户端 |
|
||||
| `POST` | `"/:id/resetClientTraffic/:email"` | 重置客户端的流量 |
|
||||
| `POST` | `"/resetAllTraffics"` | 重置所有入站的流量 |
|
||||
| `POST` | `"/resetAllClientTraffics/:id"` | 重置入站中所有客户端的流量 |
|
||||
| `POST` | `"/delDepletedClients/:id"` | 删除入站耗尽的客户端 (-1: all) |
|
||||
| `POST` | `"/onlines"` | 获取在线用户 ( 电子邮件列表 ) |
|
||||
|
||||
- 使用`clientId` 项应该填写下列数据:
|
||||
|
||||
- `client.id` for VMESS and VLESS
|
||||
- `client.password` for TROJAN
|
||||
- `client.email` for Shadowsocks
|
||||
|
||||
|
||||
|
||||
- [API 文档](https://documenter.getpostman.com/view/16802678/2s9YkgD5jm)
|
||||
|
||||
- [<img src="https://run.pstmn.io/button.svg" alt="Run In Postman" style="width: 128px; height: 32px;">](https://app.getpostman.com/run-collection/16802678-1a4c9270-ac77-40ed-959a-7aa56dc4a415?action=collection%2Ffork&source=rip_markdown&collection-url=entityId%3D16802678-1a4c9270-ac77-40ed-959a-7aa56dc4a415%26entityType%3Dcollection%26workspaceId%3D2cd38c01-c851-4a15-a972-f181c23359d9)
|
||||
</details>
|
||||
|
||||
------------
|
||||
## 环境变量
|
||||
|
||||
<details>
|
||||
<summary>点击查看 环境变量</summary>
|
||||
|
||||
#### Usage
|
||||
|
||||
| 变量 | Type | 默认 |
|
||||
| -------------- | :--------------------------------------------: | :------------ |
|
||||
| XUI_LOG_LEVEL | `"debug"` \| `"info"` \| `"warn"` \| `"error"` | `"info"` |
|
||||
| XUI_DEBUG | `boolean` | `false` |
|
||||
| XUI_BIN_FOLDER | `string` | `"bin"` |
|
||||
| XUI_DB_FOLDER | `string` | `"/etc/x-ui"` |
|
||||
| XUI_LOG_FOLDER | `string` | `"/var/log"` |
|
||||
|
||||
例子:
|
||||
|
||||
```sh
|
||||
XUI_BIN_FOLDER="bin" XUI_DB_FOLDER="/etc/x-ui" go build main.go
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
------------
|
||||
## 预览
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
------------
|
||||
## 广告赞助
|
||||
- 如果你觉得本项目对你有用,而且你也恰巧有这方面的需求,你也可以选择通过我的购买链接赞助我。
|
||||
- [1、搬瓦工GIA高端线路,仅推荐购买GIA套餐:https://bandwagonhost.com/aff.php?aff=75015](https://bandwagonhost.com/aff.php?aff=75015)
|
||||
- [2、Dmit高端GIA线路:https://www.dmit.io/aff.php?aff=9326](https://www.dmit.io/aff.php?aff=9326)
|
||||
- [3、Gomami亚太顶尖优化线路:https://gomami.io/aff.php?aff=174](https://gomami.io/aff.php?aff=174)
|
||||
- [4、ISIF优质亚太优化线路:https://cloud.isif.net/login?affiliation_code=333](https://cloud.isif.net/login?affiliation_code=333)
|
||||
- [5、ZoroCloud全球优质原生家宽&住宅双lSP,跨境首选:https://my.zorocloud.com/aff.php?aff=1072](https://my.zorocloud.com/aff.php?aff=1072)
|
||||
- [6、三网直连 IEPL / IPLC 直播流量转发:https://idc333.top/#register/BCUZXNELNO](https://idc333.top/#register/BCUZXNELNO)
|
||||
- [7、Bagevm优质落地鸡(原生IP全解锁):https://www.bagevm.com/aff.php?aff=754](https://www.bagevm.com/aff.php?aff=754)
|
||||
- [8、白丝云【4837线路】实惠量大管饱:https://cloudsilk.io/aff.php?aff=706](https://cloudsilk.io/aff.php?aff=706)
|
||||
- [9、RackNerd极致性价比机器:https://my.racknerd.com/aff.php?aff=15268&pid=912](https://my.racknerd.com/aff.php?aff=15268&pid=912)
|
||||
|
||||
------------
|
||||
## 特别感谢
|
||||
|
||||
- [MHSanaei](https://github.com/MHSanaei/)
|
||||
- [alireza0](https://github.com/alireza0/)
|
||||
- [FranzKafkaYu](https://github.com/FranzKafkaYu/)
|
||||
- [vaxilu](https://github.com/vaxilu/)
|
||||
|
||||
------------
|
||||
## 致谢
|
||||
|
||||
- [Iran v2ray rules](https://github.com/chocolate4u/Iran-v2ray-rules) (License: **GPL-3.0**): _Enhanced v2ray/xray and v2ray/xray-clients routing rules with built-in Iranian domains and a focus on security and adblocking._
|
||||
- [Vietnam Adblock rules](https://github.com/vuong2023/vn-v2ray-rules) (License: **GPL-3.0**): _A hosted domain hosted in Vietnam and blocklist with the most efficiency for Vietnamese._
|
||||
|
||||
------------
|
||||
## Star 趋势
|
||||
|
||||
[](https://starchart.cc/xeefei/x-panel)
|
||||
938
README.zh_CN.md
Normal file
@@ -0,0 +1,938 @@
|
||||
<p align="center"><a href="#"><img src="./media/X-Panel.png" alt="Image"></a></p>
|
||||
|
||||
**---------------------------------------一个更好的面板 • 基于Xray Core构建------------------------------**
|
||||
|
||||
|
||||
[](https://github.com/xeefei/x-panel/releases)
|
||||
[](https://github.com/xeefei/x-panel/actions)
|
||||
[](#)
|
||||
[](https://github.com/xeefei/x-panel/releases/latest)
|
||||
[](https://www.gnu.org/licenses/gpl-3.0.en.html)
|
||||
|
||||
> **声明:** 此项目仅供个人学习、交流使用,请遵守当地法律法规,勿用于非法用途;请勿用于生产环境。
|
||||
|
||||
> **注意:** 在使用此项目和〔教程〕过程中,若因违反以上声明使用规则而产生的一切后果由使用者自负。
|
||||
|
||||
**如果此项目对你有用,请给一个**:star2:
|
||||
|
||||
<p align="left">
|
||||
<a href="https://buymeacoffee.com/xeefeiz" target="_blank">
|
||||
<img src="./media/buymeacoffe.png" alt="Image">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
- “支持项目”赞助地址(USDT):
|
||||
- TRC20 ---->>> `TYQEmQp1P65u9bG7KPehgJdvuokfb72YkZ`
|
||||
- Polygon ---->>> `0xd20eBE429c2398793178e015B2ca1Dc42601f3Eb`
|
||||
- Solana ---->>> `7qVEZuV98QTDN5qUmsFwvqTSvkYpmLtNf8o1sh1mppwR`
|
||||
- BSC/BEP20 ---->>> `0xd20eBE429c2398793178e015B2ca1Dc42601f3Eb`
|
||||
|
||||
## [【X-Panel面板】交流群:https://t.me/XUI_CN](https://t.me/XUI_CN)
|
||||
## [【X-Panel面板】详细安装流程步骤:https://xeefei.blogspot.com/2025/09/x-panel.html](https://xeefei.blogspot.com/2025/09/x-panel.html)
|
||||
|
||||
|
||||
------------
|
||||
## ✰怎么购买【授权码】使用〔X-Panel-Pro版 面板〕?✰
|
||||
#### 1、【授权码】100/15U一个,一机一码,一直有效,永久使用,包括:重装,后期的升级/更新,都能使用,但是不能用于不同的机器,所以推荐稳定使用的机器用【授权码】,注:“授权码”属虚拟商品,购买之后,一经激活生效,概不退款,
|
||||
#### 2、对于一年期限(年付/年抛)的机器,后期可以【换绑】,为什么要有时间限制?就是为了防止,有些人拿【授权码】滥用,
|
||||
#### 3、购买方式/渠道联系机器人:[https://t.me/Buy_ShouQuan_Bot](https://t.me/Buy_ShouQuan_Bot)
|
||||
|
||||
#### 4、经常换的机器,去使用“免费基础版”就行,目前【安装界面】是有“两种方式”可选择的,
|
||||
|
||||
#### 5、对于有业务需求,比如做 TK 的,做〔跨境电商〕的,如果很多机器,比如:20台,50台,或者 100台 以上机器的宝子,若都要用【收费Pro版】的话,可以用【批量授权】:5 ——> 20台,8折,尾号:5555 ,20 ——> 50台,7折,尾号:66666 ,50 ——> 100台,6折,尾号:777777 ,100 ——> 200台,5折,尾号:8888888,200台 ——> 以上,4折,尾号:99999999,以上列举出来的,就是【批量折扣】的统一“优惠”。注:〔批量授权码〕要求最低5台以上,是“一码通用”,一个“授权码”,可以绑定验证多台 VPS 机器,并且有专属的“豹子号”授权码。
|
||||

|
||||
————————————————————————————————
|
||||
|
||||
#### 6、若您需要购买【授权码】,请跟下面这个“机器人”去对话,
|
||||
|
||||
#### ———————————————-
|
||||
|
||||
#### [https://t.me/Buy_ShouQuan_Bot](https://t.me/Buy_ShouQuan_Bot)
|
||||
#### (授权码购买机器人)
|
||||
|
||||
#### ———————————————-
|
||||
|
||||
#### 输入:/start 或 购买,即可“在线下单”,
|
||||
|
||||
#### 7、弹出【购买页面】,选择或输入“数量”,付款了支付系统会收到回调,金额到账之后,就会通过那个机器人【发放授权码】给您,整个流程,是【全自助】的“自动处理”方式,若您是〔增加配额〕,基本也是一样的流程,
|
||||
|
||||
#### 8、请注意:机器人发给您的所有信息,尽量都去自己【耐心阅读】一遍,“使用说明”,以及〔VIP 群〕的信息,也全部都包含在里面的,
|
||||
|
||||
#### 9、按照之前您安装更新〔X-Panel 面板〕的方式,直接重新输入【安装命令】,选择【2】,就能去,把之前的【免费版】,“无缝升级”到最新的【Pro版】。
|
||||
|
||||
————————————————————————————————
|
||||
#### 10、不能重复用于不同的机器 VPS,后期视情况不定时会上涨价格;对于〔X-Panel 面板〕后期的“新功能”,都将在【付费Pro版】中进行更新,
|
||||
|
||||
#### 11、目前的【安装界面】,是有:两种可选,“免费基础版”一样可用,只是后期不再提供技术支持和重大更新,另外,在【免费基础版】中,【一键配置】功能将不再可用,全部放到了【付费Pro版】中,
|
||||
|
||||
#### 12、后期的开发精力,全部会放到【付费Pro版】中,免费基础版不删库,持续保留,会大幅降低更新频率,后期只会同步更新 Xray 那边的【内核版本】等基础,想继续用的不影响,只是没有【新功能】可用,翻墙也足够。
|
||||
|
||||

|
||||
|
||||
------------
|
||||
## ✰〔X-Panel-Pro版 面板〕已实现的功能✰
|
||||
#### 1、新增 -【付费Pro版】的面板后台UI,添加醒目的“X-Panel-Pro”标识,
|
||||
#### 2、优化 -【付费Pro版】TG端 【版本更新】提示功能,增加详细的“更新说明”,
|
||||
#### 3、增加〔Pro版面板后台〕,使用 Reality 协议时,可点击随机更换所偷的域名,
|
||||
#### 4、新增 -【付费Pro版】TG端 的【发送授权报告】,增加“唯一授权防伪码”,
|
||||
#### 5、优化 -【付费Pro版】安装脚本界面,增加【Pro版】该有的“明确标识”,
|
||||
#### 6、优化 -【付费Pro版】TG端的显示方式,增加该有的“会员标识”,
|
||||
#### 7、新增 -【付费Pro版】安装脚本,有“网页版SSH工具”可选部署,脚本中〔第26选项〕,
|
||||
#### 8、新增 - 【付费Pro版】安装脚本,有“线路和IP质量检测”可去使用,脚本中〔第27选项〕,
|
||||
#### 9、新增 - 【付费Pro版】安装脚本,有“地区服务器DNS检测”可去使用,脚本中〔第28选项〕,
|
||||
#### 10、新增 -【付费Pro版】---->>>TG端,同步有“网页版SSH工具”可选安装,
|
||||
#### 11、优化 - 【付费Pro版】---->>>TG端,点击“服务器状态”时的“版本号显示”,
|
||||
#### 12、说明 - 【付费Pro版】TG端中,使用命令:/webssh,安装“网页版SSH”,
|
||||
#### 13、优化 -〔Pro版〕中的〔一键配置〕功能,有更友好的提示方式,
|
||||
#### 14、新增 -【付费Pro版】---->>>面板后台的【首页 UI】,目前是有“5种”可选:标准布局 (默认),炫彩动画,深海科技,暮光薰衣,和幽林秘境;你喜欢什么类型的主题,就去点击“选定”之后,就不会自动变了,若后期需要更换,就重选,
|
||||
#### 15、新增 -【付费Pro版】---->>>在“创建入站”时,可以在页面上更加方便地选择【重置流量】的方式:有每日重置,每周重置,按月重置,或从不重置,
|
||||
#### 16、新增 -〔X-Panel 面板〕----->>【付费Pro版】TG端“每日报告”,可定制【发送内容】,自己可点击“打开或关闭”,并且可以选择【发送时间】,可按天,或者每周,每月发,
|
||||
#### 17、优化 -【付费Pro版】的“授权码验证机制”,增加【后台联网验证】,以及“机器指纹”等属性,
|
||||
#### 18、新增 -〔X-Panel 面板〕----->>【付费Pro版】TG端“多面板管理”,一个机器人可同时管理其他面板,可以很丝滑地远程操作【被控端 VPS】,
|
||||
#### 19、新增 -〔X-Panel 面板〕----->>【付费Pro版】TG端“获取节点链接”功能,支持【本机】和【远程被控端 VPS】都能获取,开发此功能的目的在于:不用进〔面板后台〕,就能在 TG端 获取到之前已经创建过的“链接”,
|
||||
#### 20、新增 -〔X-Panel 面板〕----->>【付费Pro版】“一键部署中转节点”,解决了不懂配置的麻烦,已实现:远程Socks5创建 --> 本机路由配置 --> 本机入口创建 --> 生成“二维码和链接”,“小手一点”,直接可用,
|
||||
#### 21、新增 -〔X-Panel 面板〕----->>【申请安装证书】“第18选项”,有“备用方式申请证书”,当用常规方式【1】申请不下来时,可以试试“备用方式”,
|
||||
#### 22、新增 -〔X-Panel 面板〕----->>【申请安装证书】“第18选项”,有“可自定义证书路径”,自己进入 VPS 中“手动上传证书”,复制路径,在脚本中填入即可,
|
||||
#### 23、新增 -〔X-Panel 面板〕----->>【付费Pro版】“深度调优脚本”,包含 BBR+FQ, TCP Fast Open, 内存缓冲区及队列优化,在〔Pro版〕脚本中“第29选项”可直接用,
|
||||
#### 24、新增 -〔X-Panel 面板〕----->>【付费Pro版】“首页会员等级”显示,能够明确展示:自己的会员等级,授权码信息,以及“版本更新”提示,
|
||||
#### 25、新增 -〔X-Panel 面板〕----->>【付费Pro版】“节点上/下线TG通知”功能,对于【拼车】的宝子,能明确知道:哪个节点,什么时候上线?或者下线时间,做到“心中有数”,
|
||||
#### 26、新增 -〔X-Panel 面板〕----->>【付费Pro版】“签到得积分”功能,后期针对有【积分】的宝子,会不断推出:相应的【特权】和【福利待遇】,
|
||||
#### 27、新增 -〔X-Panel 面板〕----->>【付费Pro版】“TG端签到得积分”功能,推出:积分查询,积分换购,授权码查询,修改用户名,积分转移/打赏,以及“积分排行榜”,
|
||||
#### 28、新增 -〔X-Panel 面板〕----->>【付费Pro版】“TG端签到得积分”功能,推出【“积分换购”的可用功能】:A、消耗1000积分“自助重置换绑时间”,B、消耗5000积分“自助换购一个普通授权码”,
|
||||
#### 29、新增 -〔X-Panel 面板〕----->>【付费Pro版】“创建数据快照 + 远程急救还原”的提示功能: 可直观通过「终端UI界面」看到具体「备份 + 还原」步骤;用法:面板报错“崩了”,不用像之前那样:卸载面板 -->> 重装面板,更不用很麻烦去“重装系统”解决,直接:远程急救还原,前提就是:你自己要知道,在面板“正常运行”的时候,去「备份数据快照」,
|
||||
#### 30、新增 -〔X-Panel 面板〕----->>【付费Pro版】“每月重置流量”功能:可输入1—31之间的任意数字,比如:输入12,即代表“每月12号”「重置入站流量」,以便提供更友好的“重置流量方式”,
|
||||
#### 31、新增 -〔X-Panel 面板〕----->>【付费Pro版】“批量部署节点”功能:可直接在面板后台的“一键配置”中去使用,点击一次可批量部署生成10条「VLESS + TCP + Reality + Vision」协议组合的入站,
|
||||
#### 32、新增 -〔X-Panel 面板〕----->>【付费Pro版】“购买机器人”功能,可自助全自动在“机器人”中:购买授权码,增加配额,充值积分,自助重置换绑等,联系:[https://t.me/Buy_ShouQuan_Bot](https://t.me/Buy_ShouQuan_Bot) 。
|
||||

|
||||
|
||||
------------
|
||||
## ✰你必须要看的【重要安全提示/警告】✰
|
||||
#### 1、请勿使用【http明文模式】登录管理面板,因为明文会造成信息泄露;这个安全问题社区讨论过,
|
||||
#### 2、可使用设置【SSH端口转发功能】去登录面板或安装证书之后用https加密方式登录;两种方式选择其一,
|
||||

|
||||
#### 3、若无域名那就按照脚本提示去做【ssh转发】;有域名则可选择更加安全的【申请安装证书】方式,
|
||||
#### 4、Windows电脑首先通过快捷键【Win + R】调出运行窗口,在里面输入【cmd】打开本地终端服务,
|
||||

|
||||

|
||||

|
||||

|
||||
#### 5、若在搭建之前没有翻墙加密,则【http明文模式】登录面板有很大的信息泄露安全风险,那建议你第一次搭建成功之后,去修改用户/密码,和访问路径,后期则通过搭建好的代理加密访问,
|
||||

|
||||
#### 6、在做【ssh转发】过程中,本地电脑的终端不能关闭,保持打开不能断开;且每一次要登录〔X-Panel面板〕管理后台都要做【ssh转发】,因为关闭之后就失效了。
|
||||

|
||||
#### PS:上述两种方法:【ssh端口转发】或申请安装证书的目的都是为了更安全地登录面板,而至于搭建的其他流程和步骤,都是一样的;如果你已经【申请安装证书】了,并不会受到其他什么额外影响,就不用去折腾【ssh转发】了,直接用 【https://你的域名:端口/路径】 去登录你的面板管理后台就行了。
|
||||
|
||||
------------
|
||||
## 如何在〔X-Panel-Pro 面板〕中去使用【一个机器人管理多面板】功能?
|
||||
#### 1、先购买【授权码】安装好〔X-Panel-Pro 面板〕,进入后台,在【主从管理】界面,
|
||||

|
||||
#### 2、点击【添加被控端 VPS】,按照要求填入面板登录地址,用户名和密码,备注等信息,
|
||||

|
||||
#### 3、然后点击【配置本机“主控机器人”】,跳转到【机器人设置页面】,输入token令牌配置好,
|
||||

|
||||

|
||||
#### 4、现在重启本机 VPS,打开TG端机器人,即可看到【切换控制 VPS】等菜单,切换操作即可使用。
|
||||

|
||||

|
||||
|
||||
------------
|
||||
## 如何在〔X-Panel-Pro 面板〕中去使用【一键部署中转节点】的功能?
|
||||
#### 1、先购买【授权码】安装好〔X-Panel-Pro 面板〕,进入后台,在【主从管理】界面,
|
||||
#### 2、点击【添加中转机 VPS】,按照要求填入面板登录地址,用户名和密码,备注等信息,
|
||||

|
||||
#### 3、然后点击列表页中的【一键部署中转】,即可在后续的流程中,自动进入配置流程,
|
||||

|
||||
#### 4、稍等片刻,本机配置好的话就几秒,全自动给您生成了【二维码和中转链接】,复制可用,
|
||||

|
||||
#### 5、记得要去放行【本机】和【远程中转机】对应的端口,也可点击【检测中转节点】功能去看是否通?
|
||||

|
||||
|
||||
------------
|
||||
## ✰如何从其他x-ui版本迁移到〔X-Panel面板〕?✰
|
||||
#### 1、若你用的是伊朗老哥的3X-UI,是可以直接〔覆盖安装〕的,因为数据库文件等位置是没有改变的,所以直接覆盖安装,并不会影响你〔原有节点及配置〕等数据;安装命令如下:
|
||||
```
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/xeefei/x-panel/master/install.sh)
|
||||
```
|
||||
#### 2、若你之前用的是Docker方式安装,那先进入容器里面/命令:docker exec -it 容器id /bin/sh,再执行以上脚本命令直接【覆盖安装】即可,
|
||||
#### 3、若你用的是之前F佬的x-ui或者其他分支版本,那直接覆盖安装的话,并不能确保一定就能够兼容?建议你先去备份〔数据库〕配置文件,再进行安装〔X-Panel面板〕。
|
||||
|
||||
|
||||
------------
|
||||
## 安装之前的准备
|
||||
- 购买一台性能还不错的VPS,可通过本页底部链接购买,
|
||||
- PS:若你不想升级系统,则可以跳过此步骤。
|
||||
- 若你需要更新/升级系统,Debian系统可用如下命令:
|
||||
```
|
||||
apt update
|
||||
apt upgrade -y
|
||||
apt dist-upgrade -y
|
||||
apt autoclean
|
||||
apt autoremove -y
|
||||
```
|
||||
- 查看系统当前版本:
|
||||
```
|
||||
cat /etc/debian_version
|
||||
```
|
||||
- 查看内核版本:
|
||||
```
|
||||
uname -r
|
||||
```
|
||||
- 列出所有内核:
|
||||
```
|
||||
dpkg --list | grep linux-image
|
||||
```
|
||||
- 更新完成后执行重新引导:
|
||||
```
|
||||
update-grub
|
||||
```
|
||||
- 完成以上步骤之后输入reboot重启系统
|
||||
|
||||
------------
|
||||
## 【搬瓦工】重装/升级系统之后SSH连不上如何解决?
|
||||
- 【搬瓦工】重装/升级系统会恢复默认22端口,如果需要修改SSH的端口号,您需要进行以下步骤:
|
||||
- 以管理员身份使用默认22端口登录到SSH服务器
|
||||
- 打开SSH服务器的配置文件进行编辑,SSH配置文件通常位于/etc/ssh/sshd_config
|
||||
- 找到"Port"选项,并将其更改为您想要的端口号
|
||||
- Port <新端口号>,请将<新端口号>替换为您想要使用的端口号
|
||||
- 保存文件并退出编辑器
|
||||
- 重启服务器以使更改生效
|
||||
|
||||
------------
|
||||
## 安装 & 升级
|
||||
- 使用〔X-Panel面板〕脚本一般情况下,安装完成创建入站之后,端口是默认关闭的,所以必须进入脚本选择【22】去放行端口
|
||||
- 要使用【自动续签】证书功能,也必须放行【80】端口,保持80端口是打开的,才会每3个月自动续签一次
|
||||
|
||||
- 【全新安装】请执行以下脚本:
|
||||
```
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/xeefei/x-panel/master/install.sh)
|
||||
```
|
||||
#### 如果执行了上面的代码但是报错,证明你的系统里面没有curl这个软件,请执行以下命令先安装curl软件,安装curl之后再去执行上面代码,
|
||||
```
|
||||
apt update -y&&apt install -y curl&&apt install -y socat
|
||||
```
|
||||
|
||||
- 若要对版本进行升级,可直接通过脚本选择【2】,如下图:
|
||||

|
||||

|
||||
- 在到这一步必须要注意:要保留旧设置的话,需要输入【n】
|
||||

|
||||
|
||||
|
||||
## 安装指定版本
|
||||
|
||||
若要安装指定的版本,请使用以下安装命令。 e.g., ver `v26.2.15`:
|
||||
|
||||
```
|
||||
VERSION=v26.2.15 && bash <(curl -Ls "https://raw.githubusercontent.com/xeefei/x-panel/$VERSION/install.sh") $VERSION
|
||||
```
|
||||
------------
|
||||
## 若你的VPS默认有防火墙,请在安装完成之后放行指定端口
|
||||
- 放行【面板登录端口】
|
||||
- 放行出入站管理协议端口
|
||||
- 如果要申请安装证书并每3个月【自动续签】证书,请确保80和443端口是放行打开的
|
||||
- 可通过此脚本的第【21】选项去安装防火墙进行管理,如下图:
|
||||

|
||||
- 若要一次性放行多个端口或一整个段的端口,用英文逗号隔开。
|
||||
#### PS:若你的VPS没有防火墙,则所有端口都是能够ping通的,可自行选择是否进入脚本安装防火墙保证安全,但安装了防火墙必须放行相应端口。
|
||||
|
||||
------------
|
||||
## 如何在〔X-Panel面板〕中使用简单快捷的【一键配置】生成功能?
|
||||
#### 1、进入后台,并且你已经【安装了证书】,可在【添加入站】处看到,
|
||||

|
||||
#### 2、点击【一键配置】,在弹出的页面中【按需选择】去生成协议配置即可,
|
||||

|
||||
#### 3、直接复制【链接】,导入软件;若后台出现【醒目提示】,那就手动放行【相应端口】,
|
||||

|
||||
#### 4、若你是用【TG端电报机器人】的【一键配置】生成功能,那直接点击就用,
|
||||

|
||||
#### 5、选择好自己想要【一键创建】的协议组合类型,点击之后稍作等待,
|
||||

|
||||
#### 6、TG端【一键配置】创建成功之后,二维码和链接地址机器人会发送给你,如下:
|
||||

|
||||
|
||||
------------
|
||||
## 如何在〔X-Panel 项目〕中进行【抽奖游戏】赢奖品?
|
||||
#### 1、必须绑定好【TG端机器人】,怎么绑定?去看下面“绑定机器人”那部分教程,
|
||||
#### 2、在【TG端】直接点击【娱乐抽奖】菜单,就会弹出【每日幸运】抽奖游戏,
|
||||

|
||||
#### 3、点击【进行抽奖】,就可“全凭手气”得到随机的抽奖结果,如下图所示,
|
||||

|
||||
#### 4、在你【中奖】之后,截完整的“中奖页面”图片给交流群内管理员,即可兑奖。
|
||||

|
||||
|
||||
------------
|
||||
## 安装证书开启https方式实现域名登录访问管理面板/----->>偷自己
|
||||
#### PS:如果不需要以上功能或无域名,可以跳过这步;建议申请证书,
|
||||
##### 1、把自己的域名托管到CF,并解析到自己VPS的IP,不要开启【小云朵】,
|
||||
##### 2、如果要申请安装证书并每3个月【自动续签】证书,请确保80和443端口是放行打开的,
|
||||
##### 3、输入x-ui命令进入面板管理脚本,通过选择第【18】选项去进行安装,若使用 18 ---> 1方式不能申请下来,那就用 18--->5 备用方式去申请,或者也可用【19选项】去申请,
|
||||

|
||||
##### 4、首先输入解析好的【域名】进行验证,然后可以默认用【80端口】,直接回车申请,
|
||||

|
||||
##### 5、进入后台【面板设置】—–>【常规】中,会看到脚本已经自动填好了证书公钥、私钥路径,
|
||||
##### 6、点击左上角的【保存】和【重启面板】,即可用自己域名进行登录管理;也可按照后续方法实现【自己偷自己】。
|
||||
|
||||
------------
|
||||
## 登录面板进行【常规】设置
|
||||
### 特别是如果在安装过程中,全部都是默认【回车键】安装的话,用户名/密码/访问路径是随机的,而面板监听端口默认是:13688,可自行进入面板更改,
|
||||
##### 1、填写自己想要设置的【面板监听端口】,并去登录SSH放行,
|
||||
##### 2、更改自己想要设置的【面板登录访问路径】,后续加上路径登录访问,
|
||||

|
||||
##### 3、其他:安全设定和电报机器人等配置,可自行根据需求去进行设置,
|
||||
##### 4、强烈建议配置电报机器人,使用【TG端】可方便远程接管 VPS 服务器,
|
||||

|
||||
##### 5、面板设置【改动保存】之后,都需要点击左上角【重启面板】,才能生效。
|
||||
#### PS:若你在正确完成了上述步骤之后,你没有安装证书的情况下,去用【ssh转发】的方式却不能访问面板,那请检查一下是不是你的浏览器自动默认开启了https模式,需要手动调整一下改成http方式,把“s”去掉,即可访问成功;或查看一下是不是对应的端口被占用?
|
||||
|
||||
------------
|
||||
## 创建【入站协议】和添加【客户端】,并测试上网
|
||||
##### 1、点击左边【入站列表】,然后【添加入站】,传输方式保持【TCP】不变,尽量选择主流的vless+reality+vision协议组合,
|
||||

|
||||
##### 2、在选择reality安全选项时,偷的域名可以使用默认的,要使用其他的,请替换尽量保持一致就行,比如Apple、Yahoo,VPS所在地区的旅游、学校网站等;如果要实现【偷自己】,请参看后续【如何偷自己】的说明部分;而私钥/公钥部分,可以直接点击下方的【Get New Cert】获取一个随机的,
|
||||
##### 3、在创建reality安全选项过程中,至于其他诸如:PROXY Protocol,HTTP 伪装,TPROXY,External Proxy等等选项,若无特殊要求,保持默认设置即可,不用去动它们,
|
||||

|
||||
##### 4、创建好入站协议之后,默认只有一个客户端,可根据自己需求继续添加;重点:并编辑客户端,选择【Flow流控】为xtls-rprx-vision,
|
||||

|
||||
##### 5、其他:流量限制,到期时间,客户TG的ID等选项根据自己需求填写,
|
||||

|
||||
##### 6、一定要放行端口之后,确保端口能够ping通,再导入软件,
|
||||
##### 7、点击二维码或者复制链接导入到v2rayN等软件中进行测试。
|
||||
|
||||
------------
|
||||
## 备份与恢复/迁移数据库(以Debian系统为例)
|
||||
#### 一、备份:通过配置好电报管理机器人,可点击管理机器人的“相应菜单按钮”获取【备份配置】文件,有x-ui.db和config.json两个文件,可自行下载保存到自己电脑里面,
|
||||

|
||||
#### 二、搭建:在新的VPS中全新安装好〔X-Panel面板〕,通过脚本放行之前配置的所有端口,一次性放行多个端口请用【英文逗号】分隔,
|
||||
#### 三、若需要安装证书,则提前把域名解析到新的VPS对应的IP,并且去输入x-ui选择第【18】选项去安装,并记录公钥/私钥的路径,无域名则跳过这一步,
|
||||
#### 四、恢复:SSH登录服务器找到/etc/x-ui/x-ui.db和/usr/local/x-ui/bin/config.json文件位置,上传之前的两个备份文件,进行覆盖,
|
||||

|
||||
##### PS:把之前通过自动备份下载得到的两个文件上传覆盖掉旧文件,重启〔X-Panel面板〕即可【迁移成功】;即使迁移过程中出现问题,你是有备份文件的,不用担心,多试几次。
|
||||

|
||||
#### 五、若安装了证书,去核对/更改一下证书的路径,一般是同一个域名的话,位置在:/root/cert/域名/fullchain.pem,路径是相同的就不用更改,
|
||||
#### 六、重启面板/重启服务器,让上述步骤生效即可,这时可以看到所有配置都是之前自己常用的,包括面板用户名、密码,入站、客户端,电报机器人配置等。
|
||||
#### PS:若您使用的是【Pro版】,则可直接使用:“创建数据快照 + 远程急救还原”功能,对面板数据库和配置文件进行操作。
|
||||
|
||||
------------
|
||||
## 安装完成后如何设置调整成【中文界面】?
|
||||
- 方法一:通过管理后台【登录页面】调整,登录时可以选择,如下图:
|
||||

|
||||
- 方法二:通过在管理后台-->【面板设置】中去选择设置,如下图:
|
||||

|
||||
- 【TG机器人】设置中文:通过在管理后台-->【面板设置】-->【机器人配置】中去选择设置,并建议打开数据库备份和登录通知,如下图:
|
||||

|
||||
|
||||
------------
|
||||
## 用〔X-Panel面板〕如何实现【自己偷自己】?
|
||||
- 其实很简单,只要你为面板设置了证书,
|
||||
- 开启了HTTPS登录,就可以将〔X-Panel面板〕自身作为Web Server,
|
||||
- 无需Nginx等,这里给一个示例:
|
||||
- 其中目标网站(Dest)请填写面板监听端口,
|
||||
- 可选域名(SNI)填写面板登录域名,
|
||||
- 如果您使用其他web server(如nginx)等,
|
||||
- 将目标网站改为对应监听端口也可。
|
||||
- 需要说明的是,如果您处于白名单地区,自己“偷”自己并不适合你;
|
||||
- 其次,可选域名一项实际上可以填写任意SNI,只要客户端保持一致即可,不过并不推荐这样做。
|
||||
- 配置方法如下图所示:
|
||||

|
||||
|
||||
------------
|
||||
## 〔子域名〕被墙针对特征
|
||||
#### 网络表现:
|
||||
##### 1、可以Ping通域名和IP地址,
|
||||
##### 2、子域名无法打开〔X-Panel面板〕管理界面,
|
||||
##### 3、什么都正常就是不能上网;
|
||||
|
||||
#### 问题:
|
||||
##### 你的子域名被墙针对了:无法上网!
|
||||
|
||||
#### 解决方案:
|
||||
##### 1、更换为新的子域名,
|
||||
##### 2、解析新的子域名到VPS的IP,
|
||||
##### 3、重新去安装新证书,
|
||||
##### 4、重启〔X-Panel面板〕和服务器,
|
||||
##### 5、重新去获取链接并测试上网。
|
||||
#### PS:若通过以上步骤还是不能正常上网,则重装VPS服务器OS系统,以及〔X-Panel面板〕全部重新安装,之后就正常了!
|
||||
|
||||
------------
|
||||
## 用〔X-Panel面板〕如何开启【设备限制】功能?
|
||||
##### 1、进入后台在【添加入站】的时候,弹出来的页面就能有【设备数量】输入框,
|
||||

|
||||
##### 2、通过步骤1设置完成后,在后台的【入站列表】页面也有对应的同步数据显示。
|
||||

|
||||
##### 3、具体要查看【设备限制】功能的封禁情况,就进入〔X-Panel面板〕后台用日志查看。
|
||||

|
||||
##### 4、以下图片里面,详细阐述了我们的〔设备限制〕功能,跟3X-UI原本就有的〔IP Limit〕之间的区别对比。
|
||||

|
||||
|
||||
------------
|
||||
## 用〔X-Panel面板〕如何开启【独立限速】功能?
|
||||
##### 1、进入后台在【添加入站】的时候,弹出来的页面在【客户/用户】那里就能输入具体数字,
|
||||

|
||||
##### 2、也可以在添加好一个【入站】之后,点击【添加客户端】去找到【独立限速】输入框,
|
||||

|
||||
##### 3、当你想批量一次性创建多个【客户/用户】时,同样可以使用【独立限速】功能,
|
||||

|
||||

|
||||
##### 4、若后期你想更改某一个【客户端/用户】的限制速率,那就自己先找到,然后点击【编辑】即可,
|
||||

|
||||
##### 5、具体要查看【独立限速】功能的启用情况,就进入〔X-Panel面板〕后台用日志查看。
|
||||

|
||||
|
||||
------------
|
||||
## 用〔X-Panel面板〕如何开启【每月流量自动重置】?
|
||||
##### 1、进入后台的【入站列表】,选择需要设置的【客户端】,
|
||||

|
||||
##### 2、要注意是编辑【入站】下面的【客户端】,才会有效果,
|
||||
##### 2、并不是编辑【入站】,所以不要弄错对象,如下图所示:
|
||||

|
||||
|
||||
|
||||
------------
|
||||
## 在自己的VPS服务器部署【订阅转换】功能
|
||||
### 如何把vless/vmess等协议转换成Clash/Surge等软件支持的格式?
|
||||
##### 1、进入脚本输入x-ui命令调取面板,选择第【25】选项安装订阅转换模块,
|
||||
##### 2、等待安装【订阅转换】成功之后,访问地址:https://你的域名:15268 ,
|
||||

|
||||
##### 3、因为在转换过程中需要调取后端API,所以请确保端口 8000 和 15268 是打开放行的,
|
||||
##### 4、直接复制脚本中提供的【登录地址】,进入后台,点击【节点列表】,如下图:
|
||||

|
||||
##### 5、接下来点击左边侧边栏的【订阅列表】去【添加订阅】,按照下图中去操作,
|
||||

|
||||
##### 6、最后一步,点击【客户端】,即可导入Clash等软件中使用。
|
||||

|
||||

|
||||
|
||||
------------
|
||||
## 常见的翻墙软件/工具:
|
||||
- [1、Windows系统v2rayN:https://github.com/2dust/v2rayN](https://github.com/2dust/v2rayN)
|
||||
- [2、安卓手机版【v2rayNG】:https://github.com/2dust/v2rayNG](https://github.com/2dust/v2rayNG)
|
||||
- [3、苹果手机IOS【小火箭】:https://apple02.com/(自己购买)](https://apple02.com/)
|
||||
- [4、苹果MacOS电脑【Clash Verge】:https://github.com/clash-verge-rev/clash-verge-rev/releases](https://github.com/clash-verge-rev/clash-verge-rev/releases)
|
||||
[或v2rayN:https://github.com/2dust/v2rayN](https://github.com/2dust/v2rayN)
|
||||
|
||||
------------
|
||||
## 如何保护自己的IP不被墙被封?
|
||||
##### 1、使用的代理协议要安全,加密是必备,推荐使用vless+reality+vision协议组合,
|
||||
##### 2、因为有时节点会共享,在不同的地区,多个省份之间不要共同连接同一个IP,
|
||||
##### 3、连接同一个IP就算了,不要同一个端口,不要同IP+同端口到处漫游,要分开,
|
||||
##### 4、同一台VPS,不要在一天内一直大流量去下载东西使用,不要流量过高要切换,
|
||||
##### 5、创建【入站协议】的时候,尽量用【高位端口】,比如40000--65000之间的端口号。
|
||||
#### 提醒:为什么在特殊时期,比如:两会,春节等被封得最严重最惨?
|
||||
##### 尼玛同一个IP+同一个端口号,多个省份去漫游,跟开飞机场一样!不封你,封谁的IP和端口?
|
||||
#### 总结:不要多终端/多省份/多个朋友/共同使用同一个IP和端口号!使用〔X-Panel面板〕多创建几个【入站】,
|
||||
#### 多做几条备用,各用各的!各行其道才比较安全!GFW的思维模式是干掉机场,机场的特征个人用户不要去沾染,自然IP就保护好了。
|
||||
|
||||
------------
|
||||
## SSL 认证
|
||||
|
||||
<details>
|
||||
<summary>点击查看 SSL 认证</summary>
|
||||
|
||||
### ACME
|
||||
|
||||
要使用 ACME 管理 SSL 证书:
|
||||
|
||||
1. 确保您的域名已正确解析到服务器,
|
||||
2. 输入“x-ui”命令并选择“SSL 证书管理”,
|
||||
3. 您将看到以下选项:
|
||||
|
||||
- **获取证书** ----获取SSL证书
|
||||
- **吊销证书** ----吊销现有的SSL证书
|
||||
- **续签证书** ----强制续签SSL证书
|
||||
- **显示所有证书** ----显示服务器中所有能用的证书
|
||||
- **设置面板证书路径** ----指定面板要使用的证书
|
||||
|
||||
|
||||
### Certbot
|
||||
|
||||
安装和使用 Certbot:
|
||||
|
||||
```sh
|
||||
apt-get install certbot -y
|
||||
certbot certonly --standalone --agree-tos --register-unsafely-without-email -d yourdomain.com
|
||||
certbot renew --dry-run
|
||||
```
|
||||
|
||||
### Cloudflare
|
||||
|
||||
管理脚本具有用于 Cloudflare 的内置 SSL 证书应用程序。若要使用此脚本申请证书,需要满足以下条件:
|
||||
|
||||
- Cloudflare 邮箱地址
|
||||
- Cloudflare Global API Key
|
||||
- 域名已通过 cloudflare 解析到当前服务器
|
||||
|
||||
**如何获取 Cloudflare全局API密钥:**
|
||||
|
||||
1. 在终端中输入“x-ui”命令,然后选择“CF SSL 证书”。
|
||||
2. 访问链接: [Cloudflare API Tokens](https://dash.cloudflare.com/profile/api-tokens).
|
||||
3. 点击“查看全局 API 密钥”(如下图所示):
|
||||

|
||||
4. 您可能需要重新验证您的帐户。之后,将显示 API 密钥(请参见下面的屏幕截图):
|
||||

|
||||
|
||||
使用时,只需输入您的“域名”、“电子邮件”和“API KEY”即可。示意图如下:
|
||||

|
||||
|
||||
|
||||
</details>
|
||||
|
||||
------------
|
||||
## 手动安装 & 升级
|
||||
|
||||
<details>
|
||||
<summary>点击查看 手动安装 & 升级</summary>
|
||||
|
||||
#### 使用
|
||||
|
||||
1. 若要将最新版本的压缩包直接下载到服务器,请运行以下命令:
|
||||
|
||||
```sh
|
||||
ARCH=$(uname -m)
|
||||
case "${ARCH}" in
|
||||
x86_64 | x64 | amd64) XUI_ARCH="amd64" ;;
|
||||
i*86 | x86) XUI_ARCH="386" ;;
|
||||
armv8* | armv8 | arm64 | aarch64) XUI_ARCH="arm64" ;;
|
||||
armv7* | armv7) XUI_ARCH="armv7" ;;
|
||||
armv6* | armv6) XUI_ARCH="armv6" ;;
|
||||
armv5* | armv5) XUI_ARCH="armv5" ;;
|
||||
s390x) echo 's390x' ;;
|
||||
*) XUI_ARCH="amd64" ;;
|
||||
esac
|
||||
|
||||
|
||||
wget https://github.com/xeefei/x-panel/releases/latest/download/x-ui-linux-${XUI_ARCH}.tar.gz
|
||||
```
|
||||
|
||||
2. 下载压缩包后,执行以下命令安装或升级 x-ui:
|
||||
|
||||
```sh
|
||||
ARCH=$(uname -m)
|
||||
case "${ARCH}" in
|
||||
x86_64 | x64 | amd64) XUI_ARCH="amd64" ;;
|
||||
i*86 | x86) XUI_ARCH="386" ;;
|
||||
armv8* | armv8 | arm64 | aarch64) XUI_ARCH="arm64" ;;
|
||||
armv7* | armv7) XUI_ARCH="armv7" ;;
|
||||
armv6* | armv6) XUI_ARCH="armv6" ;;
|
||||
armv5* | armv5) XUI_ARCH="armv5" ;;
|
||||
s390x) echo 's390x' ;;
|
||||
*) XUI_ARCH="amd64" ;;
|
||||
esac
|
||||
|
||||
cd /root/
|
||||
rm -rf x-ui/ /usr/local/x-ui/ /usr/bin/x-ui
|
||||
tar zxvf x-ui-linux-${XUI_ARCH}.tar.gz
|
||||
chmod +x x-ui/x-ui x-ui/bin/xray-linux-* x-ui/x-ui.sh
|
||||
cp x-ui/x-ui.sh /usr/bin/x-ui
|
||||
cp -f x-ui/x-ui.service /etc/systemd/system/
|
||||
mv x-ui/ /usr/local/
|
||||
systemctl daemon-reload
|
||||
systemctl enable x-ui
|
||||
systemctl restart x-ui
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
------------
|
||||
## 通过Docker安装
|
||||
|
||||
<details>
|
||||
<summary>点击查看 通过Docker安装</summary>
|
||||
|
||||
#### 使用
|
||||
|
||||
|
||||
1. **安装Docker**
|
||||
|
||||
```sh
|
||||
bash <(curl -sSL https://get.docker.com)
|
||||
```
|
||||
|
||||
|
||||
2. **克隆项目仓库**
|
||||
|
||||
```sh
|
||||
git clone https://github.com/xeefei/x-panel.git
|
||||
cd x-panel
|
||||
```
|
||||
|
||||
3. **启动服务**:
|
||||
|
||||
```sh
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
添加 ```--pull always``` 标志使 docker 在拉取更新的镜像时自动重新创建容器。有关更多信息,请参阅:https://docs.docker.com/reference/cli/docker/container/run/#pull
|
||||
|
||||
**或**
|
||||
|
||||
```sh
|
||||
docker run -itd \
|
||||
-e XRAY_VMESS_AEAD_FORCED=false \
|
||||
-v $PWD/db/:/etc/x-ui/ \
|
||||
-v $PWD/cert/:/root/cert/ \
|
||||
--network=host \
|
||||
--restart=unless-stopped \
|
||||
--name x-panel \
|
||||
ghcr.io/xeefei/x-panel:latest
|
||||
```
|
||||
|
||||
4. **更新至最新版本**
|
||||
|
||||
```sh
|
||||
cd x-panel
|
||||
docker compose down
|
||||
docker compose pull x-panel
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
5. **从Docker中删除x-panel **
|
||||
|
||||
```sh
|
||||
docker stop x-panel
|
||||
docker rm x-panel
|
||||
cd --
|
||||
rm -r x-panel
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
------------
|
||||
## 建议使用的操作系统
|
||||
|
||||
- Ubuntu 20.04+
|
||||
- Debian 11+
|
||||
- CentOS 8+
|
||||
- OpenEuler 22.03+
|
||||
- Fedora 36+
|
||||
- Arch Linux
|
||||
- Manjaro
|
||||
- Armbian
|
||||
- AlmaLinux 8.0+
|
||||
- Rocky Linux 8+
|
||||
- Oracle Linux 8+
|
||||
- OpenSUSE Tubleweed
|
||||
- Amazon Linux 2023
|
||||
|
||||
------------
|
||||
## 支持的架构和设备
|
||||
<details>
|
||||
<summary>点击查看 支持的架构和设备</summary>
|
||||
|
||||
我们的平台提供与各种架构和设备的兼容性,确保在各种计算环境中的灵活性。以下是我们支持的关键架构:
|
||||
|
||||
- **amd64**: 这种流行的架构是个人计算机和服务器的标准,可以无缝地适应大多数现代操作系统。
|
||||
|
||||
- **x86 / i386**: 这种架构在台式机和笔记本电脑中被广泛采用,得到了众多操作系统和应用程序的广泛支持,包括但不限于 Windows、macOS 和 Linux 系统。
|
||||
|
||||
- **armv8 / arm64 / aarch64**: 这种架构专为智能手机和平板电脑等当代移动和嵌入式设备量身定制,以 Raspberry Pi 4、Raspberry Pi 3、Raspberry Pi Zero 2/Zero 2 W、Orange Pi 3 LTS 等设备为例。
|
||||
|
||||
- **armv7 / arm / arm32**: 作为较旧的移动和嵌入式设备的架构,它仍然广泛用于Orange Pi Zero LTS、Orange Pi PC Plus、Raspberry Pi 2等设备。
|
||||
|
||||
- **armv6 / arm / arm32**: 这种架构面向非常老旧的嵌入式设备,虽然不太普遍,但仍在使用中。Raspberry Pi 1、Raspberry Pi Zero/Zero W 等设备都依赖于这种架构。
|
||||
|
||||
- **armv5 / arm / arm32**: 它是一种主要与早期嵌入式系统相关的旧架构,目前不太常见,但仍可能出现在早期 Raspberry Pi 版本和一些旧智能手机等传统设备中。
|
||||
</details>
|
||||
|
||||
------------
|
||||
## Languages
|
||||
|
||||
- English(英语)
|
||||
- Farsi(伊朗语)
|
||||
- Simplified Chinese(简体中文)
|
||||
- Traditional Chinese(繁体中文)
|
||||
- Russian(俄语)
|
||||
- Vietnamese(越南语)
|
||||
- Spanish(西班牙语)
|
||||
- Indonesian (印度尼西亚语)
|
||||
- Ukrainian(乌克兰语)
|
||||
- Turkish(土耳其语)
|
||||
- Português (葡萄牙语)
|
||||
|
||||
------------
|
||||
## 项目特点
|
||||
|
||||
- 系统状态查看与监控
|
||||
- 可搜索所有入站和客户端信息
|
||||
- 深色/浅色主题随意切换
|
||||
- 支持多用户和多协议
|
||||
- 支持多种协议,包括 VMess、VLESS、Trojan、Shadowsocks、Dokodemo-door、Socks、HTTP、wireguard
|
||||
- 支持 XTLS 原生协议,包括 RPRX-Direct、Vision、REALITY
|
||||
- 流量统计、流量限制、过期时间限制
|
||||
- 可自定义的 Xray配置模板
|
||||
- 支持HTTPS访问面板(自备域名+SSL证书)
|
||||
- 支持一键式SSL证书申请和自动续签证书
|
||||
- 更多高级配置项目请参考面板去进行设定
|
||||
- 修复了 API 路由(用户设置将使用 API 创建)
|
||||
- 支持通过面板中提供的不同项目更改配置。
|
||||
- 支持从面板导出/导入数据库
|
||||
|
||||
## 默认面板设置
|
||||
|
||||
<details>
|
||||
|
||||
<summary>点击查看 默认设置</summary>
|
||||
|
||||
### 默认信息
|
||||
|
||||
- **端口**
|
||||
- 13688
|
||||
- **用户名 & 密码 & 访问路径**
|
||||
- 当您跳过设置时,这些信息会随机生成,
|
||||
- 您也可以在安装的时候自定义访问路径。
|
||||
- **数据库文件路径:**
|
||||
- /etc/x-ui/x-ui.db
|
||||
- **Xray 配置文件路径:**
|
||||
- /usr/local/x-ui/bin/config.json
|
||||
- **面板链接(有SSL):**
|
||||
- https://你的域名:13688/访问路径/panel
|
||||
|
||||
</details>
|
||||
|
||||
------------
|
||||
## [WARP 配置](https://gitlab.com/fscarmen/warp)
|
||||
|
||||
<details>
|
||||
<summary>点击查看 WARP 配置</summary>
|
||||
|
||||
#### 使用
|
||||
|
||||
**对于版本 `v2.1.0` 及更高版本:**
|
||||
|
||||
WARP 是内置的,无需额外安装;只需在面板中打开必要的配置即可。
|
||||
|
||||
**如果要在 v2.1.0 之前使用 WARP 路由**,请按照以下步骤操作:
|
||||
|
||||
**1.** 在 **SOCKS Proxy Mode** 模式中安装Wrap
|
||||
|
||||
- **Account Type (free, plus, team):** Choose the appropriate account type.
|
||||
- **Enable/Disable WireProxy:** Toggle WireProxy on or off.
|
||||
- **Uninstall WARP:** Remove the WARP application.
|
||||
|
||||
**2.** 如果您已经安装了 warp,您可以使用以下命令卸载:
|
||||
|
||||
```sh
|
||||
warp u
|
||||
```
|
||||
|
||||
**3.** 在面板中打开您需要的配置
|
||||
|
||||
配置:
|
||||
|
||||
- Block Ads
|
||||
- Route Google, Netflix, Spotify, and OpenAI (ChatGPT) traffic to WARP
|
||||
- Fix Google 403 error
|
||||
|
||||
|
||||
</details>
|
||||
|
||||
------------
|
||||
## IP 限制
|
||||
|
||||
<details>
|
||||
<summary>点击查看 IP 限制</summary>
|
||||
|
||||
#### 使用
|
||||
|
||||
**注意:** 使用 IP 隧道时,IP 限制无法正常工作。
|
||||
|
||||
- 对于 `v1.6.1`之前的版本 :
|
||||
|
||||
- IP 限制 已被集成在面板中。
|
||||
|
||||
- 对于 `v1.7.0` 以及更新的版本:
|
||||
|
||||
- 要使 IP 限制正常工作,您需要按照以下步骤安装 fail2ban 及其所需的文件:
|
||||
|
||||
1. 使用面板内置的 `x-ui` 指令
|
||||
2. 选择 `IP Limit Management`.
|
||||
3. 根据您的需要选择合适的选项。
|
||||
|
||||
- 确保您的 Xray 配置上有 ./access.log 。在 v2.1.3 之后,我们有一个选项。
|
||||
|
||||
```sh
|
||||
"log": {
|
||||
"access": "./access.log",
|
||||
"dnsLog": false,
|
||||
"loglevel": "warning"
|
||||
},
|
||||
```
|
||||
- 您需要在Xray配置中手动设置〔访问日志〕的路径。
|
||||
|
||||
</details>
|
||||
|
||||
------------
|
||||
## Telegram 机器人
|
||||
|
||||
<details>
|
||||
<summary>点击查看 Telegram 机器人</summary>
|
||||
|
||||
#### 使用
|
||||
|
||||
Web 面板通过 Telegram Bot 支持每日流量、面板登录、数据库备份、系统状态、客户端信息等通知和功能。要使用机器人,您需要在面板中设置机器人相关参数,包括:
|
||||
|
||||
- 电报令牌
|
||||
- 管理员聊天 ID
|
||||
- 通知时间(cron 语法)
|
||||
- 到期日期通知
|
||||
- 流量上限通知
|
||||
- 数据库备份
|
||||
- CPU 负载通知
|
||||
|
||||
|
||||
**参考:**
|
||||
|
||||
- `30 \* \* \* \* \*` - 在每个点的 30 秒处通知
|
||||
- `0 \*/10 \* \* \* \*` - 每 10 分钟的第一秒通知
|
||||
- `@hourly` - 每小时通知
|
||||
- `@daily` - 每天通知 (00:00)
|
||||
- `@weekly` - 每周通知
|
||||
- `@every 8h` - 每8小时通知
|
||||
|
||||
### Telegram Bot 功能
|
||||
|
||||
- 定期报告
|
||||
- 登录通知
|
||||
- CPU 阈值通知
|
||||
- 提前报告的过期时间和流量阈值
|
||||
- 如果将客户的电报用户名添加到用户的配置中,则支持客户端报告菜单
|
||||
- 支持使用UUID(VMESS/VLESS)或密码(TROJAN)搜索报文流量报告 - 匿名
|
||||
- 基于菜单的机器人
|
||||
- 通过电子邮件搜索客户端(仅限管理员)
|
||||
- 检查所有入库
|
||||
- 检查服务器状态
|
||||
- 检查耗尽的用户
|
||||
- 根据请求和定期报告接收备份
|
||||
- 多语言机器人
|
||||
|
||||
### 注册 Telegram bot
|
||||
|
||||
- 与 [Botfather](https://t.me/BotFather) 对话:
|
||||

|
||||
|
||||
- 使用 /newbot 创建新机器人:你需要提供机器人名称以及用户名,注意名称中末尾要包含“bot”
|
||||

|
||||
|
||||
- 启动您刚刚创建的机器人。可以在此处找到机器人的链接。
|
||||

|
||||
|
||||
- 输入您的面板并配置 Telegram 机器人设置,如下所示:
|
||||

|
||||
|
||||
在输入字段编号 3 中输入机器人令牌。
|
||||
在输入字段编号 4 中输入用户 ID。具有此 id 的 Telegram 帐户将是机器人管理员。 (您可以输入多个,只需将它们用“ ,”分开即可)
|
||||
|
||||
- 如何获取TG ID? 使用 [bot](https://t.me/useridinfobot), 启动机器人,它会给你 Telegram 用户 ID。
|
||||

|
||||
|
||||
</details>
|
||||
|
||||
------------
|
||||
## API 路由
|
||||
|
||||
<details>
|
||||
<summary>点击查看 API 路由</summary>
|
||||
|
||||
#### 使用
|
||||
|
||||
- `/login` 使用 `POST` 用户名称 & 密码: `{username: '', password: ''}` 登录
|
||||
- `/panel/api/inbounds` 以下操作的基础:
|
||||
|
||||
| 方法 | 路径 | 操作 |
|
||||
| :----: | ---------------------------------- | ------------------------------------------- |
|
||||
| `GET` | `"/list"` | 获取所有入站 |
|
||||
| `GET` | `"/get/:id"` | 获取所有入站以及inbound.id |
|
||||
| `GET` | `"/getClientTraffics/:email"` | 通过电子邮件获取客户端流量 |
|
||||
| `GET` | `"/getClientTrafficsById/:id"` | 通过用户ID获取客户端流量 |
|
||||
| `GET` | `"/createbackup"` | Telegram 机器人向管理员发送备份 |
|
||||
| `POST` | `"/add"` | 添加入站 |
|
||||
| `POST` | `"/del/:id"` | 删除入站 |
|
||||
| `POST` | `"/update/:id"` | 更新入站 |
|
||||
| `POST` | `"/clientIps/:email"` | 客户端 IP 地址 |
|
||||
| `POST` | `"/clearClientIps/:email"` | 清除客户端 IP 地址 |
|
||||
| `POST` | `"/addClient"` | 将客户端添加到入站 |
|
||||
| `POST` | `"/:id/delClient/:clientId"` | 通过 clientId\* 删除客户端 |
|
||||
| `POST` | `"/updateClient/:clientId"` | 通过 clientId\* 更新客户端 |
|
||||
| `POST` | `"/:id/resetClientTraffic/:email"` | 重置客户端的流量 |
|
||||
| `POST` | `"/resetAllTraffics"` | 重置所有入站的流量 |
|
||||
| `POST` | `"/resetAllClientTraffics/:id"` | 重置入站中所有客户端的流量 |
|
||||
| `POST` | `"/delDepletedClients/:id"` | 删除入站耗尽的客户端 (-1: all) |
|
||||
| `POST` | `"/onlines"` | 获取在线用户 ( 电子邮件列表 ) |
|
||||
|
||||
- 使用`clientId` 项应该填写下列数据:
|
||||
|
||||
- `client.id` for VMESS and VLESS
|
||||
- `client.password` for TROJAN
|
||||
- `client.email` for Shadowsocks
|
||||
|
||||
|
||||
|
||||
- [API 文档](https://documenter.getpostman.com/view/16802678/2s9YkgD5jm)
|
||||
|
||||
- [<img src="https://run.pstmn.io/button.svg" alt="Run In Postman" style="width: 128px; height: 32px;">](https://app.getpostman.com/run-collection/16802678-1a4c9270-ac77-40ed-959a-7aa56dc4a415?action=collection%2Ffork&source=rip_markdown&collection-url=entityId%3D16802678-1a4c9270-ac77-40ed-959a-7aa56dc4a415%26entityType%3Dcollection%26workspaceId%3D2cd38c01-c851-4a15-a972-f181c23359d9)
|
||||
</details>
|
||||
|
||||
------------
|
||||
## 环境变量
|
||||
|
||||
<details>
|
||||
<summary>点击查看 环境变量</summary>
|
||||
|
||||
#### Usage
|
||||
|
||||
| 变量 | Type | 默认 |
|
||||
| -------------- | :--------------------------------------------: | :------------ |
|
||||
| XUI_LOG_LEVEL | `"debug"` \| `"info"` \| `"warn"` \| `"error"` | `"info"` |
|
||||
| XUI_DEBUG | `boolean` | `false` |
|
||||
| XUI_BIN_FOLDER | `string` | `"bin"` |
|
||||
| XUI_DB_FOLDER | `string` | `"/etc/x-ui"` |
|
||||
| XUI_LOG_FOLDER | `string` | `"/var/log"` |
|
||||
|
||||
例子:
|
||||
|
||||
```sh
|
||||
XUI_BIN_FOLDER="bin" XUI_DB_FOLDER="/etc/x-ui" go build main.go
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
------------
|
||||
## 预览
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
------------
|
||||
## 广告赞助
|
||||
- 如果你觉得本项目对你有用,而且你也恰巧有这方面的需求,你也可以选择通过我的购买链接赞助我。
|
||||
- [1、搬瓦工GIA高端线路,仅推荐购买GIA套餐:https://bandwagonhost.com/aff.php?aff=75015](https://bandwagonhost.com/aff.php?aff=75015)
|
||||
- [2、Dmit高端GIA线路:https://www.dmit.io/aff.php?aff=9326](https://www.dmit.io/aff.php?aff=9326)
|
||||
- [3、Gomami亚太顶尖优化线路:https://gomami.io/aff.php?aff=174](https://gomami.io/aff.php?aff=174)
|
||||
- [4、ISIF优质亚太优化线路:https://cloud.isif.net/login?affiliation_code=333](https://cloud.isif.net/login?affiliation_code=333)
|
||||
- [5、ZoroCloud全球优质原生家宽&住宅双lSP,跨境首选:https://my.zorocloud.com/aff.php?aff=1072](https://my.zorocloud.com/aff.php?aff=1072)
|
||||
- [6、三网直连 IEPL / IPLC 直播流量转发:https://idc333.top/#register/BCUZXNELNO](https://idc333.top/#register/BCUZXNELNO)
|
||||
- [7、Bagevm优质落地鸡(原生IP全解锁):https://www.bagevm.com/aff.php?aff=754](https://www.bagevm.com/aff.php?aff=754)
|
||||
- [8、白丝云【4837线路】实惠量大管饱:https://cloudsilk.io/aff.php?aff=706](https://cloudsilk.io/aff.php?aff=706)
|
||||
- [9、RackNerd极致性价比机器:https://my.racknerd.com/aff.php?aff=15268&pid=912](https://my.racknerd.com/aff.php?aff=15268&pid=912)
|
||||
|
||||
------------
|
||||
## 特别感谢
|
||||
|
||||
- [MHSanaei](https://github.com/MHSanaei/)
|
||||
- [alireza0](https://github.com/alireza0/)
|
||||
- [FranzKafkaYu](https://github.com/FranzKafkaYu/)
|
||||
- [vaxilu](https://github.com/vaxilu/)
|
||||
|
||||
------------
|
||||
## 致谢
|
||||
|
||||
- [Iran v2ray rules](https://github.com/chocolate4u/Iran-v2ray-rules) (License: **GPL-3.0**): _Enhanced v2ray/xray and v2ray/xray-clients routing rules with built-in Iranian domains and a focus on security and adblocking._
|
||||
- [Vietnam Adblock rules](https://github.com/vuong2023/vn-v2ray-rules) (License: **GPL-3.0**): _A hosted domain hosted in Vietnam and blocklist with the most efficiency for Vietnamese._
|
||||
|
||||
------------
|
||||
## Star 趋势
|
||||
|
||||
[](https://starchart.cc/xeefei/x-panel)
|
||||
144
config/config.go
Normal file
@@ -0,0 +1,144 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
//go:embed version
|
||||
var version string
|
||||
|
||||
//go:embed name
|
||||
var name string
|
||||
|
||||
type LogLevel string
|
||||
|
||||
const (
|
||||
Debug LogLevel = "debug"
|
||||
Info LogLevel = "info"
|
||||
Notice LogLevel = "notice"
|
||||
Warn LogLevel = "warn"
|
||||
Error LogLevel = "error"
|
||||
)
|
||||
|
||||
func GetVersion() string {
|
||||
return strings.TrimSpace(version)
|
||||
}
|
||||
|
||||
func GetName() string {
|
||||
return strings.TrimSpace(name)
|
||||
}
|
||||
|
||||
func GetLogLevel() LogLevel {
|
||||
if IsDebug() {
|
||||
return Debug
|
||||
}
|
||||
logLevel := os.Getenv("XUI_LOG_LEVEL")
|
||||
if logLevel == "" {
|
||||
return Info
|
||||
}
|
||||
return LogLevel(logLevel)
|
||||
}
|
||||
|
||||
func IsDebug() bool {
|
||||
return os.Getenv("XUI_DEBUG") == "true"
|
||||
}
|
||||
|
||||
func GetBinFolderPath() string {
|
||||
binFolderPath := os.Getenv("XUI_BIN_FOLDER")
|
||||
if binFolderPath == "" {
|
||||
binFolderPath = "bin"
|
||||
}
|
||||
return binFolderPath
|
||||
}
|
||||
|
||||
func getBaseDir() string {
|
||||
exePath, err := os.Executable()
|
||||
if err != nil {
|
||||
return "."
|
||||
}
|
||||
exeDir := filepath.Dir(exePath)
|
||||
exeDirLower := strings.ToLower(filepath.ToSlash(exeDir))
|
||||
if strings.Contains(exeDirLower, "/appdata/local/temp/") || strings.Contains(exeDirLower, "/go-build") {
|
||||
wd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return "."
|
||||
}
|
||||
return wd
|
||||
}
|
||||
return exeDir
|
||||
}
|
||||
|
||||
func GetDBFolderPath() string {
|
||||
dbFolderPath := os.Getenv("XUI_DB_FOLDER")
|
||||
if dbFolderPath != "" {
|
||||
return dbFolderPath
|
||||
}
|
||||
if runtime.GOOS == "windows" {
|
||||
return getBaseDir()
|
||||
}
|
||||
return "/etc/x-ui"
|
||||
}
|
||||
|
||||
func GetDBPath() string {
|
||||
return fmt.Sprintf("%s/%s.db", GetDBFolderPath(), GetName())
|
||||
}
|
||||
|
||||
func GetLogFolder() string {
|
||||
logFolderPath := os.Getenv("XUI_LOG_FOLDER")
|
||||
if logFolderPath != "" {
|
||||
return logFolderPath
|
||||
}
|
||||
if runtime.GOOS == "windows" {
|
||||
return filepath.Join(".", "log")
|
||||
}
|
||||
return "/var/log"
|
||||
}
|
||||
|
||||
func copyFile(src, dst string) error {
|
||||
in, err := os.Open(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer in.Close()
|
||||
|
||||
out, err := os.Create(dst)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer out.Close()
|
||||
|
||||
_, err = io.Copy(out, in)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return out.Sync()
|
||||
}
|
||||
|
||||
func init() {
|
||||
if runtime.GOOS != "windows" {
|
||||
return
|
||||
}
|
||||
if os.Getenv("XUI_DB_FOLDER") != "" {
|
||||
return
|
||||
}
|
||||
oldDBFolder := "/etc/x-ui"
|
||||
oldDBPath := fmt.Sprintf("%s/%s.db", oldDBFolder, GetName())
|
||||
newDBFolder := GetDBFolderPath()
|
||||
newDBPath := fmt.Sprintf("%s/%s.db", newDBFolder, GetName())
|
||||
_, err := os.Stat(newDBPath)
|
||||
if err == nil {
|
||||
return // new exists
|
||||
}
|
||||
_, err = os.Stat(oldDBPath)
|
||||
if os.IsNotExist(err) {
|
||||
return // old does not exist
|
||||
}
|
||||
_ = copyFile(oldDBPath, newDBPath) // ignore error
|
||||
}
|
||||
1
config/name
Normal file
@@ -0,0 +1 @@
|
||||
x-ui
|
||||
1
config/version
Normal file
@@ -0,0 +1 @@
|
||||
26.4.25
|
||||
218
database/db.go
Normal file
@@ -0,0 +1,218 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"io/fs"
|
||||
"log"
|
||||
"os"
|
||||
"path"
|
||||
"slices"
|
||||
"time"
|
||||
|
||||
"x-ui/config"
|
||||
"x-ui/database/model"
|
||||
"x-ui/util/crypto"
|
||||
"x-ui/xray"
|
||||
|
||||
"gorm.io/driver/sqlite"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/logger"
|
||||
)
|
||||
|
||||
var db *gorm.DB
|
||||
|
||||
const (
|
||||
defaultUsername = "admin"
|
||||
defaultPassword = "admin"
|
||||
)
|
||||
|
||||
func initModels() error {
|
||||
models := []any{
|
||||
&model.User{},
|
||||
&model.Inbound{},
|
||||
&model.OutboundTraffics{},
|
||||
&model.Setting{},
|
||||
&model.InboundClientIps{},
|
||||
&xray.ClientTraffic{},
|
||||
&model.HistoryOfSeeders{},
|
||||
&LinkHistory{}, // 把 LinkHistory 表也迁移
|
||||
&model.LotteryWin{}, // 新增 抽奖游戏LotteryWin 数据模型
|
||||
}
|
||||
for _, model := range models {
|
||||
if err := db.AutoMigrate(model); err != nil {
|
||||
log.Printf("Error auto migrating model: %v", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func initUser() error {
|
||||
empty, err := isTableEmpty("users")
|
||||
if err != nil {
|
||||
log.Printf("Error checking if users table is empty: %v", err)
|
||||
return err
|
||||
}
|
||||
if empty {
|
||||
hashedPassword, err := crypto.HashPasswordAsBcrypt(defaultPassword)
|
||||
|
||||
if err != nil {
|
||||
log.Printf("Error hashing default password: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
user := &model.User{
|
||||
Username: defaultUsername,
|
||||
Password: hashedPassword,
|
||||
}
|
||||
return db.Create(user).Error
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func runSeeders(isUsersEmpty bool) error {
|
||||
empty, err := isTableEmpty("history_of_seeders")
|
||||
if err != nil {
|
||||
log.Printf("Error checking if users table is empty: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if empty && isUsersEmpty {
|
||||
hashSeeder := &model.HistoryOfSeeders{
|
||||
SeederName: "UserPasswordHash",
|
||||
}
|
||||
return db.Create(hashSeeder).Error
|
||||
} else {
|
||||
var seedersHistory []string
|
||||
db.Model(&model.HistoryOfSeeders{}).Pluck("seeder_name", &seedersHistory)
|
||||
|
||||
if !slices.Contains(seedersHistory, "UserPasswordHash") && !isUsersEmpty {
|
||||
var users []model.User
|
||||
db.Find(&users)
|
||||
|
||||
for _, user := range users {
|
||||
hashedPassword, err := crypto.HashPasswordAsBcrypt(user.Password)
|
||||
if err != nil {
|
||||
log.Printf("Error hashing password for user '%s': %v", user.Username, err)
|
||||
return err
|
||||
}
|
||||
db.Model(&user).Update("password", hashedPassword)
|
||||
}
|
||||
|
||||
hashSeeder := &model.HistoryOfSeeders{
|
||||
SeederName: "UserPasswordHash",
|
||||
}
|
||||
return db.Create(hashSeeder).Error
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func isTableEmpty(tableName string) (bool, error) {
|
||||
var count int64
|
||||
err := db.Table(tableName).Count(&count).Error
|
||||
return count == 0, err
|
||||
}
|
||||
|
||||
func InitDB(dbPath string) error {
|
||||
dir := path.Dir(dbPath)
|
||||
err := os.MkdirAll(dir, fs.ModePerm)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var gormLogger logger.Interface
|
||||
|
||||
if config.IsDebug() {
|
||||
gormLogger = logger.Default
|
||||
} else {
|
||||
gormLogger = logger.Discard
|
||||
}
|
||||
|
||||
c := &gorm.Config{
|
||||
Logger: gormLogger,
|
||||
}
|
||||
db, err = gorm.Open(sqlite.Open(dbPath), c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := initModels(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
isUsersEmpty, err := isTableEmpty("users")
|
||||
|
||||
if err := initUser(); err != nil {
|
||||
return err
|
||||
}
|
||||
return runSeeders(isUsersEmpty)
|
||||
}
|
||||
|
||||
func CloseDB() error {
|
||||
if db != nil {
|
||||
sqlDB, err := db.DB()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return sqlDB.Close()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetDB() *gorm.DB {
|
||||
return db
|
||||
}
|
||||
|
||||
func IsNotFound(err error) bool {
|
||||
return err == gorm.ErrRecordNotFound
|
||||
}
|
||||
|
||||
func IsSQLiteDB(file io.ReaderAt) (bool, error) {
|
||||
signature := []byte("SQLite format 3\x00")
|
||||
buf := make([]byte, len(signature))
|
||||
_, err := file.ReadAt(buf, 0)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return bytes.Equal(buf, signature), nil
|
||||
}
|
||||
|
||||
func Checkpoint() error {
|
||||
// Update WAL
|
||||
err := db.Exec("PRAGMA wal_checkpoint;").Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// HasUserWonToday 检查指定用户今天是否已经中过奖
|
||||
// 〔中文注释〕:【修正】将 gorm.DB() 替换为全局变量 db
|
||||
func HasUserWonToday(userID int64) (bool, error) {
|
||||
now := time.Now()
|
||||
startOfDay := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
|
||||
endOfDay := startOfDay.Add(24 * time.Hour)
|
||||
|
||||
var count int64
|
||||
// 在 lottery_wins 表中查找符合条件(用户ID匹配且中奖日期在今天之内)的记录数量
|
||||
err := db.Model(&model.LotteryWin{}).Where("user_id = ? AND win_date >= ? AND win_date < ?", userID, startOfDay, endOfDay).Count(&count).Error
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return count > 0, nil
|
||||
}
|
||||
|
||||
// RecordUserWin 记录用户的中奖信息
|
||||
// 〔中文注释〕:【修正】将 gorm.DB() 替换为全局变量 db
|
||||
func RecordUserWin(userID int64, prize string) error {
|
||||
winRecord := &model.LotteryWin{
|
||||
UserID: userID,
|
||||
Prize: prize,
|
||||
WinDate: time.Now(),
|
||||
}
|
||||
// 在 lottery_wins 表中创建一条新的记录
|
||||
return db.Create(winRecord).Error
|
||||
}
|
||||
65
database/history.go
Normal file
@@ -0,0 +1,65 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"time"
|
||||
"gorm.io/gorm" // 【中文注释】: 确保 gorm 被导入,以便在函数签名中使用
|
||||
)
|
||||
|
||||
// LinkHistory GORM aodel for link_history table
|
||||
type LinkHistory struct {
|
||||
Id int `gorm:"primaryKey"`
|
||||
Type string `gorm:"type:varchar(255);not null"`
|
||||
Link string `gorm:"type:text;not null"`
|
||||
CreatedAt time.Time `gorm:"not null"`
|
||||
}
|
||||
|
||||
// AddLinkHistory 在一个事务中添加新链接记录并修剪旧记录。
|
||||
// 它确保了操作的原子性:所有更改要么全部应用,要么全部回滚。
|
||||
func AddLinkHistory(record *LinkHistory) error {
|
||||
// 【核心修正】: 使用 GORM 的事务功能来包装所有的数据库写入和删除操作。
|
||||
// 这样可以确保数据的一致性。
|
||||
return db.Transaction(func(tx *gorm.DB) error {
|
||||
// 1. 添加新记录
|
||||
// 【重要】: 在事务内部,必须使用 tx 变量,而不是全局的 db 变量。
|
||||
if err := tx.Create(record).Error; err != nil {
|
||||
return err // 如果这里出错,事务将自动回滚
|
||||
}
|
||||
|
||||
// 2. 修剪旧记录,仅保留最近的 10 条
|
||||
var count int64
|
||||
// 【重要】: 使用 tx 进行计数
|
||||
if err := tx.Model(&LinkHistory{}).Count(&count).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if count > 10 {
|
||||
limit := int(count) - 10
|
||||
var recordsToDelete []LinkHistory
|
||||
// 【重要】: 使用 tx 查找要删除的记录
|
||||
if err := tx.Order("created_at asc").Limit(limit).Find(&recordsToDelete).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if len(recordsToDelete) > 0 {
|
||||
// 【重要】: 使用 tx 删除记录
|
||||
if err := tx.Delete(&recordsToDelete).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 【核心修正】: 从此函数中移除了 Checkpoint() 调用。
|
||||
// 事务成功后返回 nil,GORM 会自动提交事务。
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// GetLinkHistory retrieves the 10 most recent link records
|
||||
func GetLinkHistory() ([]*LinkHistory, error) {
|
||||
var histories []*LinkHistory
|
||||
err := db.Order("created_at desc").Limit(10).Find(&histories).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return histories, nil
|
||||
}
|
||||
11
database/model/lottery_win.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package model
|
||||
|
||||
import "time"
|
||||
|
||||
// LotteryWin 用于记录用户的中奖历史
|
||||
type LotteryWin struct {
|
||||
ID int64 `gorm:"primaryKey"`
|
||||
UserID int64 `gorm:"index"` // Telegram 用户 ID
|
||||
Prize string // 奖品等级,如 "一等奖"
|
||||
WinDate time.Time // 中奖日期
|
||||
}
|
||||
124
database/model/model.go
Normal file
@@ -0,0 +1,124 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"x-ui/util/json_util"
|
||||
"x-ui/xray"
|
||||
)
|
||||
|
||||
type Protocol string
|
||||
|
||||
const (
|
||||
VMESS Protocol = "vmess"
|
||||
VLESS Protocol = "vless"
|
||||
Tunnel Protocol = "tunnel"
|
||||
HTTP Protocol = "http"
|
||||
Trojan Protocol = "trojan"
|
||||
Shadowsocks Protocol = "shadowsocks"
|
||||
Socks Protocol = "socks"
|
||||
WireGuard Protocol = "wireguard"
|
||||
)
|
||||
|
||||
type User struct {
|
||||
Id int `json:"id" gorm:"primaryKey;autoIncrement"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
type Inbound struct {
|
||||
Id int `json:"id" form:"id" gorm:"primaryKey"`
|
||||
UserId int `json:"-"`
|
||||
Up int64 `json:"up" form:"up"`
|
||||
Down int64 `json:"down" form:"down"`
|
||||
Total int64 `json:"total" form:"total"`
|
||||
AllTime int64 `json:"allTime" form:"allTime" gorm:"default:0"`
|
||||
Remark string `json:"remark" form:"remark"`
|
||||
Enable bool `json:"enable" form:"enable"`
|
||||
ExpiryTime int64 `json:"expiryTime" form:"expiryTime"`
|
||||
|
||||
// 中文注释: 新增设备限制字段,用于存储每个入站的设备数限制。
|
||||
// gorm:"column:device_limit;default:0" 定义了数据库中的字段名和默认值。
|
||||
DeviceLimit int `json:"deviceLimit" form:"deviceLimit" gorm:"column:device_limit;default:0"`
|
||||
|
||||
ClientStats []xray.ClientTraffic `gorm:"foreignKey:InboundId;references:Id" json:"clientStats" form:"clientStats"`
|
||||
|
||||
// config part
|
||||
Listen string `json:"listen" form:"listen"`
|
||||
Port int `json:"port" form:"port"`
|
||||
Protocol Protocol `json:"protocol" form:"protocol"`
|
||||
Settings string `json:"settings" form:"settings"`
|
||||
StreamSettings string `json:"streamSettings" form:"streamSettings"`
|
||||
Tag string `json:"tag" form:"tag" gorm:"unique"`
|
||||
Sniffing string `json:"sniffing" form:"sniffing"`
|
||||
}
|
||||
|
||||
type OutboundTraffics struct {
|
||||
Id int `json:"id" form:"id" gorm:"primaryKey;autoIncrement"`
|
||||
Tag string `json:"tag" form:"tag" gorm:"unique"`
|
||||
Up int64 `json:"up" form:"up" gorm:"default:0"`
|
||||
Down int64 `json:"down" form:"down" gorm:"default:0"`
|
||||
Total int64 `json:"total" form:"total" gorm:"default:0"`
|
||||
}
|
||||
|
||||
type InboundClientIps struct {
|
||||
Id int `json:"id" gorm:"primaryKey;autoIncrement"`
|
||||
ClientEmail string `json:"clientEmail" form:"clientEmail" gorm:"unique"`
|
||||
Ips string `json:"ips" form:"ips"`
|
||||
}
|
||||
|
||||
type HistoryOfSeeders struct {
|
||||
Id int `json:"id" gorm:"primaryKey;autoIncrement"`
|
||||
SeederName string `json:"seederName"`
|
||||
}
|
||||
|
||||
func (i *Inbound) GenXrayInboundConfig() *xray.InboundConfig {
|
||||
listen := i.Listen
|
||||
if listen != "" {
|
||||
listen = fmt.Sprintf("\"%v\"", listen)
|
||||
}
|
||||
return &xray.InboundConfig{
|
||||
Listen: json_util.RawMessage(listen),
|
||||
Port: i.Port,
|
||||
Protocol: string(i.Protocol),
|
||||
Settings: json_util.RawMessage(i.Settings),
|
||||
StreamSettings: json_util.RawMessage(i.StreamSettings),
|
||||
Tag: i.Tag,
|
||||
Sniffing: json_util.RawMessage(i.Sniffing),
|
||||
}
|
||||
}
|
||||
|
||||
type Setting struct {
|
||||
Id int `json:"id" form:"id" gorm:"primaryKey;autoIncrement"`
|
||||
Key string `json:"key" form:"key"`
|
||||
Value string `json:"value" form:"value"`
|
||||
}
|
||||
|
||||
type Client struct {
|
||||
ID string `json:"id"`
|
||||
Security string `json:"security"`
|
||||
Password string `json:"password"`
|
||||
|
||||
// 中文注释: 新增“限速”字段,单位 KB/s,0 表示不限速。
|
||||
SpeedLimit int `json:"speedLimit" form:"speedLimit"`
|
||||
|
||||
Flow string `json:"flow"`
|
||||
Email string `json:"email"`
|
||||
LimitIP int `json:"limitIp"`
|
||||
TotalGB int64 `json:"totalGB" form:"totalGB"`
|
||||
ExpiryTime int64 `json:"expiryTime" form:"expiryTime"`
|
||||
Enable bool `json:"enable" form:"enable"`
|
||||
TgID int64 `json:"tgId" form:"tgId"`
|
||||
SubID string `json:"subId" form:"subId"`
|
||||
Comment string `json:"comment" form:"comment"`
|
||||
Reset int `json:"reset" form:"reset"`
|
||||
CreatedAt int64 `json:"created_at,omitempty"`
|
||||
UpdatedAt int64 `json:"updated_at,omitempty"`
|
||||
}
|
||||
|
||||
type VLESSSettings struct {
|
||||
Clients []Client `json:"clients"`
|
||||
Decryption string `json:"decryption"`
|
||||
Encryption string `json:"encryption"`
|
||||
Fallbacks []any `json:"fallbacks"`
|
||||
}
|
||||
289
dnsjc.sh
Normal file
@@ -0,0 +1,289 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -u
|
||||
set -o pipefail
|
||||
|
||||
COUNT=${COUNT:-10}
|
||||
TOPN=${TOPN:-30}
|
||||
SLEEP_META=${SLEEP_META:-0.15}
|
||||
META_CACHE_DIR="${META_CACHE_DIR:-/tmp/dns_meta_cache}"
|
||||
mkdir -p "$META_CACHE_DIR" >/dev/null 2>&1 || true
|
||||
|
||||
# deps
|
||||
require_cmd() { command -v "$1" >/dev/null 2>&1 || { echo "missing dependency: $1"; exit 1; }; }
|
||||
require_cmd curl
|
||||
require_cmd awk
|
||||
require_cmd sed
|
||||
require_cmd tr
|
||||
require_cmd grep
|
||||
require_cmd ping
|
||||
|
||||
PING_BIN="ping"
|
||||
PING6_BIN="ping -6"
|
||||
if command -v ping6 >/dev/null 2>&1; then
|
||||
PING6_BIN="ping6"
|
||||
fi
|
||||
|
||||
# color banner (red)
|
||||
if [ -t 1 ] && [ "${TERM:-}" != "dumb" ]; then
|
||||
RED=$'\033[1;31m'
|
||||
RESET=$'\033[0m'
|
||||
else
|
||||
RED=""
|
||||
RESET=""
|
||||
fi
|
||||
echo ""
|
||||
printf "%b\n\n" "${RED}〔X-Panel-Pro 面板〕专属 “服务器 DNS 检测”${RESET}"
|
||||
|
||||
# extract valid IPs (IPv4 strict / IPv6 loose)
|
||||
extract_ips() {
|
||||
sed -E 's/<[^>]+>/ /g' \
|
||||
| tr -c '0-9A-Fa-f:.' '\n' \
|
||||
| grep -E '(^([0-9]{1,3}\.){3}[0-9]{1,3}$)|(^([0-9A-Fa-f]{0,4}:){2,7}[0-9A-Fa-f]{0,4}$)' \
|
||||
| awk '!seen[$0]++' \
|
||||
| awk -F. '
|
||||
$0 ~ /:/ { print; next }
|
||||
NF==4 {
|
||||
ok=1
|
||||
for(i=1;i<=4;i++){
|
||||
if($i !~ /^[0-9]+$/ || $i<0 || $i>255){ ok=0; break }
|
||||
}
|
||||
if(ok) print $0
|
||||
}
|
||||
'
|
||||
}
|
||||
|
||||
# filter private/reserved IPv4
|
||||
is_public_ipv4() {
|
||||
local ip="$1"; IFS=. read -r a b c d <<<"$ip" || return 1
|
||||
if ((a==10)) || ((a==127)) || ((a==192 && b==168)) || ((a==169 && b==254)) \
|
||||
|| ((a==172 && b>=16 && b<=31)) || ((a==100 && b>=64 && b<=127)) \
|
||||
|| ((a==0)) || ((a>=224)); then
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# normalize country to slug
|
||||
normalize_country_to_slug() {
|
||||
local raw="$1"
|
||||
local x compact
|
||||
x=$(printf '%s' "$raw" | tr '[:upper:]' '[:lower:]')
|
||||
x=$(printf '%s' "$x" | sed -E 's/^[[:space:]]+|[[:space:]]+$//g')
|
||||
compact=$(printf '%s' "$x" | sed -E 's/[^a-z0-9]+//g')
|
||||
case "$compact" in
|
||||
jp) echo "japan"; return;;
|
||||
kr|rok) echo "southkorea"; return;;
|
||||
us|usa) echo "unitedstates"; return;;
|
||||
uk|gb) echo "unitedkingdom"; return;;
|
||||
ae|uae) echo "unitedarabemirates"; return;;
|
||||
hk) echo "hongkong"; return;;
|
||||
tw) echo "taiwan"; return;;
|
||||
cn) echo "china"; return;;
|
||||
de) echo "germany"; return;;
|
||||
fr) echo "france"; return;;
|
||||
it) echo "italy"; return;;
|
||||
es) echo "spain"; return;;
|
||||
ru) echo "russia"; return;;
|
||||
sg) echo "singapore"; return;;
|
||||
th) echo "thailand"; return;;
|
||||
vn) echo "vietnam"; return;;
|
||||
ph) echo "philippines"; return;;
|
||||
id) echo "indonesia"; return;;
|
||||
my) echo "malaysia"; return;;
|
||||
au) echo "australia"; return;;
|
||||
nz) echo "newzealand"; return;;
|
||||
nl) echo "netherlands"; return;;
|
||||
be) echo "belgium"; return;;
|
||||
pl) echo "poland"; return;;
|
||||
cz) echo "czechia"; return;;
|
||||
ch) echo "switzerland"; return;;
|
||||
at) echo "austria"; return;;
|
||||
se) echo "sweden"; return;;
|
||||
no) echo "norway"; return;;
|
||||
fi) echo "finland"; return;;
|
||||
pt) echo "portugal"; return;;
|
||||
ro) echo "romania"; return;;
|
||||
hu) echo "hungary"; return;;
|
||||
sk) echo "slovakia"; return;;
|
||||
si) echo "slovenia"; return;;
|
||||
gr) echo "greece"; return;;
|
||||
ie) echo "ireland"; return;;
|
||||
mx) echo "mexico"; return;;
|
||||
ca) echo "canada"; return;;
|
||||
br) echo "brazil"; return;;
|
||||
ar) echo "argentina"; return;;
|
||||
cl) echo "chile"; return;;
|
||||
za) echo "southafrica"; return;;
|
||||
esac
|
||||
x=$(printf '%s' "$x" | sed -E 's/[[:space:]]+//g')
|
||||
echo "$x"
|
||||
}
|
||||
|
||||
# fetch IPs from publicdnsserver page
|
||||
fetch_country_ips() {
|
||||
local slug="$1"
|
||||
local url="https://publicdnsserver.com/${slug}/"
|
||||
local html
|
||||
html=$(curl -sL --max-time 15 "$url" || true)
|
||||
[ -z "$html" ] && { echo ""; return 0; }
|
||||
printf '%s' "$html" | extract_ips
|
||||
}
|
||||
|
||||
# metadata (ip-api) with 1h cache
|
||||
get_meta_json() {
|
||||
local ip="$1"
|
||||
local cache="$META_CACHE_DIR/$ip.json"
|
||||
local epoch mtime age
|
||||
if [ -s "$cache" ]; then
|
||||
epoch=$(date +%s)
|
||||
if mtime=$(stat -c %Y "$cache" 2>/dev/null); then
|
||||
age=$((epoch - mtime))
|
||||
if [ "$age" -lt 3600 ]; then
|
||||
cat "$cache"; return 0
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
local resp
|
||||
resp=$(curl -s --max-time 5 "http://ip-api.com/json/$ip?fields=status,message,country,city,as,asname,org,isp,query")
|
||||
if [ -n "$resp" ]; then
|
||||
printf '%s' "$resp" >"$cache" 2>/dev/null || true
|
||||
printf '%s' "$resp"
|
||||
else
|
||||
printf '{"status":"fail","country":"","city":"","as":"","asname":"","org":"","isp":"","query":"%s"}' "$ip"
|
||||
fi
|
||||
sleep "$SLEEP_META"
|
||||
}
|
||||
|
||||
# poor-man's json getter (no jq)
|
||||
json_get() {
|
||||
echo "$1" | sed -n "s/.*\"$2\":\"\([^\"]*\)\".*/\1/p"
|
||||
}
|
||||
|
||||
# parse ping output (returns: loss,min,avg,max,mdev)
|
||||
parse_ping() {
|
||||
local out; out=$(cat)
|
||||
local loss min avg max mdev rtt
|
||||
loss=$(printf '%s\n' "$out" | LC_ALL=C grep -Eo '[0-9]+(\.[0-9]+)?% packet loss' | sed -E 's/%.*//')
|
||||
[ -z "$loss" ] && loss="100.0"
|
||||
rtt=$(printf '%s\n' "$out" | LC_ALL=C grep -E 'min/avg/max' | tail -n1 | awk -F'=' '{print $2}' | awk '{print $1}')
|
||||
if [ -n "$rtt" ]; then
|
||||
IFS=/ read -r min avg max mdev <<<"$rtt"
|
||||
else
|
||||
min="N/A"; avg="N/A"; max="N/A"; mdev="N/A"
|
||||
fi
|
||||
printf '%s,%s,%s,%s,%s\n' "$loss" "$min" "$avg" "$max" "$mdev"
|
||||
}
|
||||
|
||||
# main
|
||||
read -rp "请输入英文国家名(如 Japan / United States / South Korea;或 ISO 两字母,如 JP): " USER_REGION || USER_REGION=""
|
||||
SLUG=$(normalize_country_to_slug "${USER_REGION:-}")
|
||||
[ -z "$SLUG" ] && SLUG="japan"
|
||||
|
||||
MAP_IPS_RAW=$(fetch_country_ips "$SLUG")
|
||||
|
||||
declare -a TARGETS TMP_LIST RESULTS
|
||||
declare -A seen
|
||||
|
||||
while IFS= read -r ip; do
|
||||
[ -z "$ip" ] && continue
|
||||
if [[ "$ip" == *:* ]]; then
|
||||
TARGETS+=("$ip")
|
||||
else
|
||||
if is_public_ipv4 "$ip"; then
|
||||
TARGETS+=("$ip")
|
||||
fi
|
||||
fi
|
||||
done < <(printf '%s\n' "$MAP_IPS_RAW" | awk 'NF{if(!seen[$0]++){print}}')
|
||||
|
||||
for ip in "${TARGETS[@]}"; do
|
||||
if [ -z "${seen[$ip]+x}" ]; then
|
||||
TMP_LIST+=("$ip"); seen["$ip"]=1
|
||||
fi
|
||||
[ "${#TMP_LIST[@]}" -ge "$TOPN" ] && break
|
||||
done
|
||||
TARGETS=("${TMP_LIST[@]}")
|
||||
|
||||
for must in 1.1.1.1 8.8.8.8; do
|
||||
if [ -z "${seen[$must]+x}" ]; then
|
||||
TARGETS+=("$must"); seen["$must"]=1
|
||||
fi
|
||||
done
|
||||
|
||||
N=${#TARGETS[@]}
|
||||
printf "地区: %s(slug: %s)| 目标数: %d | 每个目标 ping 次数: %d\n" "${USER_REGION:-N/A}" "$SLUG" "$N" "$COUNT"
|
||||
printf "将测试的目标:%s\n" "$(printf '%s ' "${TARGETS[@]}")"
|
||||
echo "开始测试 ......"
|
||||
|
||||
if [ "$N" -eq 0 ]; then
|
||||
echo "未找到可用目标。"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
idx=0
|
||||
for ip in "${TARGETS[@]}"; do
|
||||
idx=$((idx+1))
|
||||
pct=$(( idx * 100 / (N==0 ? 1 : N) ))
|
||||
|
||||
printf "进度: [%d/%d | %3d%%] #%d 正在测试: %s\r" "$idx" "$N" "$pct" "$idx" "$ip"
|
||||
|
||||
if [[ "$ip" == *:* ]]; then
|
||||
out=$(LC_ALL=C $PING6_BIN -n -c "$COUNT" -i 0.2 -w $((COUNT+4)) "$ip" 2>&1 || true)
|
||||
else
|
||||
out=$(LC_ALL=C $PING_BIN -n -c "$COUNT" -i 0.2 -w $((COUNT+4)) "$ip" 2>&1 || true)
|
||||
fi
|
||||
|
||||
stats=$(printf '%s' "$out" | parse_ping)
|
||||
IFS=, read -r loss min avg max mdev <<<"$stats"
|
||||
|
||||
meta=$(get_meta_json "$ip")
|
||||
country=$(json_get "$meta" country); [ -z "$country" ] && country="N/A"
|
||||
city=$(json_get "$meta" city); [ -z "$city" ] && city="N/A"
|
||||
asfull=$(json_get "$meta" as); [ -z "$asfull" ] && asfull="N/A"
|
||||
asname=$(json_get "$meta" asname); [ -z "$asname" ] && asname="N/A"
|
||||
org=$(json_get "$meta" org)
|
||||
isp=$(json_get "$meta" isp)
|
||||
|
||||
asn=$(printf '%s' "$asfull" | sed -n 's/.*\(AS[0-9][0-9]*\).*/\1/p')
|
||||
[ -z "$asn" ] && asn="N/A"
|
||||
|
||||
company="$asname"
|
||||
[ -z "$company" ] || [ "$company" = "N/A" ] && company="$org"
|
||||
[ -z "$company" ] || [ "$company" = "N/A" ] && company="$isp"
|
||||
[ -z "$company" ] && company="N/A"
|
||||
|
||||
printf "进度: [%d/%d | %3d%%] #%d 正在测试: %-39s | 丢包 %s%% | 最小 %sms | 平均 %sms | 最大 %sms | 抖动 %sms\n" \
|
||||
"$idx" "$N" "$pct" "$idx" "$ip" "$loss" "$min" "$avg" "$max" "$mdev"
|
||||
|
||||
sortkey="$avg"; [[ "$sortkey" == "N/A" || -z "$sortkey" ]] && sortkey=999999999
|
||||
RESULTS+=("$sortkey\t$idx\t$ip\t$country/$city\t$asn\t$company\t$loss\t$min\t$avg\t$max\t$mdev")
|
||||
done
|
||||
echo
|
||||
|
||||
HEADER=$'编号\t目标\t地区\tASN\t公司\t丢包\t最小(ms)\t平均(ms)\t最大(ms)\t抖动'
|
||||
BODY=$(
|
||||
printf '%b\n' "${RESULTS[@]}" \
|
||||
| LC_ALL=C sort -t$'\t' -k1,1n \
|
||||
| cut -f2- \
|
||||
| while IFS=$'\t' read -r idx0 ip region asn company loss min avg max mdev; do
|
||||
printf '%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n' \
|
||||
"$idx0" "$ip" "$region" "$asn" "$company" \
|
||||
"$(printf '%.1f%%' "${loss:-0}")" \
|
||||
"${min:-N/A}" "${avg:-N/A}" "${max:-N/A}" "${mdev:-N/A}"
|
||||
done
|
||||
)
|
||||
|
||||
if command -v column >/dev/null 2>&1; then
|
||||
{ printf '%s\n' "$HEADER"; printf '%s\n' "$BODY"; } | column -t -s $'\t'
|
||||
else
|
||||
printf "%-4s %-39s %-18s %-8s %-28s %-6s %-9s %-9s %-9s %-7s\n" \
|
||||
"编号" "目标" "地区" "ASN" "公司" "丢包" "最小(ms)" "平均(ms)" "最大(ms)" "抖动"
|
||||
printf -- "-----------------------------------------------------------------------------------------------\n"
|
||||
printf '%s\n' "$BODY" | while IFS=$'\t' read -r idx0 ip region asn company loss min avg max mdev; do
|
||||
printf "%-4s %-39s %-18s %-8s %-28s %-6s %-9s %-9s %-9s %-7s\n" \
|
||||
"$idx0" "$ip" "$region" "$asn" "$company" \
|
||||
"$loss" "$min" "$avg" "$max" "$mdev"
|
||||
done
|
||||
|
||||
fi
|
||||
|
||||
16
docker-compose.yml
Normal file
@@ -0,0 +1,16 @@
|
||||
services:
|
||||
x-panel:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: ./Dockerfile
|
||||
container_name: x-panel_app
|
||||
# hostname: yourhostname <<--- optional
|
||||
volumes:
|
||||
- $PWD/db/:/etc/x-ui/
|
||||
- $PWD/cert/:/root/cert/
|
||||
environment:
|
||||
XRAY_VMESS_AEAD_FORCED: "false"
|
||||
XUI_ENABLE_FAIL2BAN: "true"
|
||||
tty: true
|
||||
network_mode: host
|
||||
restart: unless-stopped
|
||||
100
go.mod
Normal file
@@ -0,0 +1,100 @@
|
||||
module x-ui
|
||||
|
||||
go 1.26.2
|
||||
|
||||
replace gvisor.dev/gvisor => gvisor.dev/gvisor v0.0.0-20260122175437-89a5d21be8f0
|
||||
|
||||
require (
|
||||
github.com/gin-contrib/gzip v1.2.6
|
||||
github.com/gin-contrib/sessions v1.1.0
|
||||
github.com/gin-gonic/gin v1.12.0
|
||||
github.com/goccy/go-json v0.10.6
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/joho/godotenv v1.5.1
|
||||
github.com/mymmrac/telego v1.8.0
|
||||
github.com/nicksnyder/go-i18n/v2 v2.6.1
|
||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
|
||||
github.com/pelletier/go-toml/v2 v2.3.0
|
||||
github.com/robfig/cron/v3 v3.0.1
|
||||
github.com/shirou/gopsutil/v4 v4.26.3
|
||||
github.com/valyala/fasthttp v1.70.0
|
||||
github.com/xlzd/gotp v0.1.0
|
||||
github.com/xtls/xray-core v1.260327.0
|
||||
go.uber.org/atomic v1.11.0
|
||||
golang.org/x/crypto v0.50.0
|
||||
golang.org/x/text v0.36.0
|
||||
google.golang.org/grpc v1.80.0
|
||||
gorm.io/driver/sqlite v1.6.0
|
||||
gorm.io/gorm v1.31.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/andybalholm/brotli v1.2.1 // indirect
|
||||
github.com/apernet/quic-go v0.59.1-0.20260217092621-db4786c77a22 // indirect
|
||||
github.com/bytedance/gopkg v0.1.4 // indirect
|
||||
github.com/bytedance/sonic v1.15.0 // indirect
|
||||
github.com/bytedance/sonic/loader v0.5.1 // indirect
|
||||
github.com/cloudflare/circl v1.6.3 // indirect
|
||||
github.com/cloudwego/base64x v0.1.6 // indirect
|
||||
github.com/ebitengine/purego v0.10.0 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.13 // indirect
|
||||
github.com/gin-contrib/sse v1.1.1 // indirect
|
||||
github.com/go-ole/go-ole v1.3.0 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.30.2 // indirect
|
||||
github.com/goccy/go-yaml v1.19.2 // indirect
|
||||
github.com/google/btree v1.1.3 // indirect
|
||||
github.com/gorilla/context v1.1.2 // indirect
|
||||
github.com/gorilla/securecookie v1.1.2 // indirect
|
||||
github.com/gorilla/sessions v1.4.0 // indirect
|
||||
github.com/gorilla/websocket v1.5.3 // indirect
|
||||
github.com/grbit/go-json v0.11.0 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/juju/ratelimit v1.0.2 // indirect
|
||||
github.com/klauspost/compress v1.18.5 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
|
||||
github.com/leodido/go-urn v1.4.0 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20260330125221-c963978e514e // indirect
|
||||
github.com/mattn/go-isatty v0.0.21 // indirect
|
||||
github.com/mattn/go-sqlite3 v1.14.42 // indirect
|
||||
github.com/miekg/dns v1.1.72 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/pires/go-proxyproto v0.12.0 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
|
||||
github.com/quic-go/qpack v0.6.0 // indirect
|
||||
github.com/quic-go/quic-go v0.59.0 // indirect
|
||||
github.com/refraction-networking/utls v1.8.3-0.20260301010127-aa6edf4b11af // indirect
|
||||
github.com/rogpeppe/go-internal v1.14.1 // indirect
|
||||
github.com/sagernet/sing v0.8.9 // indirect
|
||||
github.com/sagernet/sing-shadowsocks v0.2.9 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.16 // indirect
|
||||
github.com/tklauser/numcpus v0.11.0 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.3.1 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fastjson v1.6.10 // indirect
|
||||
github.com/vishvananda/netlink v1.3.1 // indirect
|
||||
github.com/vishvananda/netns v0.0.5 // indirect
|
||||
github.com/xtls/reality v0.0.0-20260322125925-9234c772ba8f // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.4 // indirect
|
||||
go.mongodb.org/mongo-driver/v2 v2.5.1 // indirect
|
||||
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect
|
||||
golang.org/x/arch v0.26.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f // indirect
|
||||
golang.org/x/mod v0.35.0 // indirect
|
||||
golang.org/x/net v0.53.0 // indirect
|
||||
golang.org/x/sync v0.20.0 // indirect
|
||||
golang.org/x/sys v0.43.0 // indirect
|
||||
golang.org/x/time v0.15.0 // indirect
|
||||
golang.org/x/tools v0.44.0 // indirect
|
||||
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
|
||||
golang.zx2c4.com/wireguard v0.0.0-20250521234502-f333402bd9cb // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260420184626-e10c466a9529 // indirect
|
||||
google.golang.org/protobuf v1.36.11 // indirect
|
||||
gvisor.dev/gvisor v0.0.0-20260424012932-95eb8fa6e7a6 // indirect
|
||||
lukechampine.com/blake3 v1.4.1 // indirect
|
||||
)
|
||||
256
go.sum
Normal file
@@ -0,0 +1,256 @@
|
||||
github.com/BurntSushi/toml v1.6.0 h1:dRaEfpa2VI55EwlIW72hMRHdWouJeRF7TPYhI+AUQjk=
|
||||
github.com/BurntSushi/toml v1.6.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||
github.com/andybalholm/brotli v1.2.1 h1:R+f5xP285VArJDRgowrfb9DqL18yVK0gKAW/F+eTWro=
|
||||
github.com/andybalholm/brotli v1.2.1/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY=
|
||||
github.com/apernet/quic-go v0.59.1-0.20260217092621-db4786c77a22 h1:00ziBGnLWQEcR9LThDwvxOznJJquJ9bYUdmBFnawLMU=
|
||||
github.com/apernet/quic-go v0.59.1-0.20260217092621-db4786c77a22/go.mod h1:Npbg8qBtAZlsAB3FWmqwlVh5jtVG6a4DlYsOylUpvzA=
|
||||
github.com/bytedance/gopkg v0.1.4 h1:oZnQwnX82KAIWb7033bEwtxvTqXcYMxDBaQxo5JJHWM=
|
||||
github.com/bytedance/gopkg v0.1.4/go.mod h1:v1zWfPm21Fb+OsyXN2VAHdL6TBb2L88anLQgdyje6R4=
|
||||
github.com/bytedance/sonic v1.15.0 h1:/PXeWFaR5ElNcVE84U0dOHjiMHQOwNIx3K4ymzh/uSE=
|
||||
github.com/bytedance/sonic v1.15.0/go.mod h1:tFkWrPz0/CUCLEF4ri4UkHekCIcdnkqXw9VduqpJh0k=
|
||||
github.com/bytedance/sonic/loader v0.5.1 h1:Ygpfa9zwRCCKSlrp5bBP/b/Xzc3VxsAW+5NIYXrOOpI=
|
||||
github.com/bytedance/sonic/loader v0.5.1/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCcdf5x77udYiSJRo=
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cloudflare/circl v1.6.3 h1:9GPOhQGF9MCYUeXyMYlqTR6a5gTrgR/fBLXvUgtVcg8=
|
||||
github.com/cloudflare/circl v1.6.3/go.mod h1:2eXP6Qfat4O/Yhh8BznvKnJ+uzEoTQ6jVKJRn81BiS4=
|
||||
github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M=
|
||||
github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/ebitengine/purego v0.10.0 h1:QIw4xfpWT6GWTzaW5XEKy3HXoqrJGx1ijYHzTF0/ISU=
|
||||
github.com/ebitengine/purego v0.10.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
|
||||
github.com/gabriel-vasile/mimetype v1.4.13 h1:46nXokslUBsAJE/wMsp5gtO500a4F3Nkz9Ufpk2AcUM=
|
||||
github.com/gabriel-vasile/mimetype v1.4.13/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=
|
||||
github.com/ghodss/yaml v1.0.1-0.20220118164431-d8423dcdf344 h1:Arcl6UOIS/kgO2nW3A65HN+7CMjSDP/gofXL4CZt1V4=
|
||||
github.com/ghodss/yaml v1.0.1-0.20220118164431-d8423dcdf344/go.mod h1:GIjDIg/heH5DOkXY3YJ/wNhfHsQHoXGjl8G8amsYQ1I=
|
||||
github.com/gin-contrib/gzip v1.2.6 h1:OtN8DplD5DNZCSLAnQ5HxRkD2qZ5VU+JhOrcfJrcRvg=
|
||||
github.com/gin-contrib/gzip v1.2.6/go.mod h1:BQy8/+JApnRjAVUplSGZiVtD2k8GmIE2e9rYu/hLzzU=
|
||||
github.com/gin-contrib/sessions v1.1.0 h1:00mhHfNEGF5sP2fwxa98aRqj1FOJdL6IkR86n2hOiBo=
|
||||
github.com/gin-contrib/sessions v1.1.0/go.mod h1:TyYZDIs6qCQg2SOoYPgMT9pAkmZceVNEJMcv5qbIy60=
|
||||
github.com/gin-contrib/sse v1.1.1 h1:uGYpNwTacv5R68bSGMapo62iLTRa9l5zxGCps4hK6ko=
|
||||
github.com/gin-contrib/sse v1.1.1/go.mod h1:QXzuVkA0YO7o/gun03UI1Q+FTI8ZV/n5t03kIQAI89s=
|
||||
github.com/gin-gonic/gin v1.12.0 h1:b3YAbrZtnf8N//yjKeU2+MQsh2mY5htkZidOM7O0wG8=
|
||||
github.com/gin-gonic/gin v1.12.0/go.mod h1:VxccKfsSllpKshkBWgVgRniFFAzFb9csfngsqANjnLc=
|
||||
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
|
||||
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
|
||||
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
|
||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||
github.com/go-playground/validator/v10 v10.30.2 h1:JiFIMtSSHb2/XBUbWM4i/MpeQm9ZK2xqPNk8vgvu5JQ=
|
||||
github.com/go-playground/validator/v10 v10.30.2/go.mod h1:mAf2pIOVXjTEBrwUMGKkCWKKPs9NheYGabeB04txQSc=
|
||||
github.com/goccy/go-json v0.10.6 h1:p8HrPJzOakx/mn/bQtjgNjdTcN+/S6FcG2CTtQOrHVU=
|
||||
github.com/goccy/go-json v0.10.6/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||
github.com/goccy/go-yaml v1.19.2 h1:PmFC1S6h8ljIz6gMRBopkjP1TVT7xuwrButHID66PoM=
|
||||
github.com/goccy/go-yaml v1.19.2/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
|
||||
github.com/golang/mock v1.7.0-rc.1 h1:YojYx61/OLFsiv6Rw1Z96LpldJIy31o+UHmwAUMJ6/U=
|
||||
github.com/golang/mock v1.7.0-rc.1/go.mod h1:s42URUywIqd+OcERslBJvOjepvNymP31m3q8d/GkuRs=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
|
||||
github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
||||
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gorilla/context v1.1.2 h1:WRkNAv2uoa03QNIc1A6u4O7DAGMUVoopZhkiXWA2V1o=
|
||||
github.com/gorilla/context v1.1.2/go.mod h1:KDPwT9i/MeWHiLl90fuTgrt4/wPcv75vFAZLaOOcbxM=
|
||||
github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kXD8ePA=
|
||||
github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo=
|
||||
github.com/gorilla/sessions v1.4.0 h1:kpIYOp/oi6MG/p5PgxApU8srsSw9tuFbt46Lt7auzqQ=
|
||||
github.com/gorilla/sessions v1.4.0/go.mod h1:FLWm50oby91+hl7p/wRxDth9bWSuk0qVL2emc7lT5ik=
|
||||
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
|
||||
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/grbit/go-json v0.11.0 h1:bAbyMdYrYl/OjYsSqLH99N2DyQ291mHy726Mx+sYrnc=
|
||||
github.com/grbit/go-json v0.11.0/go.mod h1:IYpHsdybQ386+6g3VE6AXQ3uTGa5mquBme5/ZWmtzek=
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/juju/ratelimit v1.0.2 h1:sRxmtRiajbvrcLQT7S+JbqU0ntsb9W2yhSdNN8tWfaI=
|
||||
github.com/juju/ratelimit v1.0.2/go.mod h1:qapgC/Gy+xNh9UxzV13HGGl/6UXNN+ct+vwSgWNm/qk=
|
||||
github.com/klauspost/compress v1.18.5 h1:/h1gH5Ce+VWNLSWqPzOVn6XBO+vJbCNGvjoaGBFW2IE=
|
||||
github.com/klauspost/compress v1.18.5/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ=
|
||||
github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y=
|
||||
github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
||||
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
|
||||
github.com/lufia/plan9stats v0.0.0-20260330125221-c963978e514e h1:Q6MvJtQK/iRcRtzAscm/zF23XxJlbECiGPyRicsX+Ak=
|
||||
github.com/lufia/plan9stats v0.0.0-20260330125221-c963978e514e/go.mod h1:autxFIvghDt3jPTLoqZ9OZ7s9qTGNAWmYCjVFWPX/zg=
|
||||
github.com/mattn/go-isatty v0.0.21 h1:xYae+lCNBP7QuW4PUnNG61ffM4hVIfm+zUzDuSzYLGs=
|
||||
github.com/mattn/go-isatty v0.0.21/go.mod h1:ZXfXG4SQHsB/w3ZeOYbR0PrPwLy+n6xiMrJlRFqopa4=
|
||||
github.com/mattn/go-sqlite3 v1.14.42 h1:MigqEP4ZmHw3aIdIT7T+9TLa90Z6smwcthx+Azv4Cgo=
|
||||
github.com/mattn/go-sqlite3 v1.14.42/go.mod h1:pjEuOr8IwzLJP2MfGeTb0A35jauH+C2kbHKBr7yXKVQ=
|
||||
github.com/miekg/dns v1.1.72 h1:vhmr+TF2A3tuoGNkLDFK9zi36F2LS+hKTRW0Uf8kbzI=
|
||||
github.com/miekg/dns v1.1.72/go.mod h1:+EuEPhdHOsfk6Wk5TT2CzssZdqkmFhf8r+aVyDEToIs=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/mymmrac/telego v1.8.0 h1:EvIprWo9Cn0MHgumvvqNXPAXO1yJj3pu2cdCCeDxbow=
|
||||
github.com/mymmrac/telego v1.8.0/go.mod h1:pdLV346EgVuq7Xrh3kMggeBiazeHhsdEoK0RTEOPXRM=
|
||||
github.com/nicksnyder/go-i18n/v2 v2.6.1 h1:JDEJraFsQE17Dut9HFDHzCoAWGEQJom5s0TRd17NIEQ=
|
||||
github.com/nicksnyder/go-i18n/v2 v2.6.1/go.mod h1:Vee0/9RD3Quc/NmwEjzzD7VTZ+Ir7QbXocrkhOzmUKA=
|
||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 h1:lDH9UUVJtmYCjyT0CI4q8xvlXPxeZ0gYCVvWbmPlp88=
|
||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
|
||||
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
|
||||
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
||||
github.com/pelletier/go-toml/v2 v2.3.0 h1:k59bC/lIZREW0/iVaQR8nDHxVq8OVlIzYCOJf421CaM=
|
||||
github.com/pelletier/go-toml/v2 v2.3.0/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
|
||||
github.com/pires/go-proxyproto v0.12.0 h1:TTCxD66dU898tahivkqc3hoceZp7P44FnorWyo9d5vM=
|
||||
github.com/pires/go-proxyproto v0.12.0/go.mod h1:qUvfqUMEoX7T8g0q7TQLDnhMjdTrxnG0hvpMn+7ePNI=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU=
|
||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
||||
github.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8=
|
||||
github.com/quic-go/qpack v0.6.0/go.mod h1:lUpLKChi8njB4ty2bFLX2x4gzDqXwUpaO1DP9qMDZII=
|
||||
github.com/quic-go/quic-go v0.59.0 h1:OLJkp1Mlm/aS7dpKgTc6cnpynnD2Xg7C1pwL6vy/SAw=
|
||||
github.com/quic-go/quic-go v0.59.0/go.mod h1:upnsH4Ju1YkqpLXC305eW3yDZ4NfnNbmQRCMWS58IKU=
|
||||
github.com/refraction-networking/utls v1.8.3-0.20260301010127-aa6edf4b11af h1:er2acxbi3N1nvEq6HXHUAR1nTWEJmQfqiGR8EVT9rfs=
|
||||
github.com/refraction-networking/utls v1.8.3-0.20260301010127-aa6edf4b11af/go.mod h1:jkSOEkLqn+S/jtpEHPOsVv/4V4EVnelwbMQl4vCWXAM=
|
||||
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
|
||||
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
|
||||
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
|
||||
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
||||
github.com/sagernet/sing v0.8.9 h1:iX8FyMrWNl/divVgTe7cLT9n36v6bfzfnCYlcM1cLaU=
|
||||
github.com/sagernet/sing v0.8.9/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
|
||||
github.com/sagernet/sing-shadowsocks v0.2.9 h1:Paep5zCszRKsEn8587O0MnhFWKJwDW1Y4zOYYlIxMkM=
|
||||
github.com/sagernet/sing-shadowsocks v0.2.9/go.mod h1:TE/Z6401Pi8tgr0nBZcM/xawAI6u3F6TTbz4nH/qw+8=
|
||||
github.com/shirou/gopsutil/v4 v4.26.3 h1:2ESdQt90yU3oXF/CdOlRCJxrP+Am1aBYubTMTfxJ1qc=
|
||||
github.com/shirou/gopsutil/v4 v4.26.3/go.mod h1:LZ6ewCSkBqUpvSOf+LsTGnRinC6iaNUNMGBtDkJBaLQ=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
github.com/tklauser/go-sysconf v0.3.16 h1:frioLaCQSsF5Cy1jgRBrzr6t502KIIwQ0MArYICU0nA=
|
||||
github.com/tklauser/go-sysconf v0.3.16/go.mod h1:/qNL9xxDhc7tx3HSRsLWNnuzbVfh3e7gh/BmM179nYI=
|
||||
github.com/tklauser/numcpus v0.11.0 h1:nSTwhKH5e1dMNsCdVBukSZrURJRoHbSEQjdEbY+9RXw=
|
||||
github.com/tklauser/numcpus v0.11.0/go.mod h1:z+LwcLq54uWZTX0u/bGobaV34u6V7KNlTZejzM6/3MQ=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||
github.com/ugorji/go/codec v1.3.1 h1:waO7eEiFDwidsBN6agj1vJQ4AG7lh2yqXyOXqhgQuyY=
|
||||
github.com/ugorji/go/codec v1.3.1/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4=
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasthttp v1.70.0 h1:LAhMGcWk13QZWm85+eg8ZBNbrq5mnkWFGbHMUJHIdXA=
|
||||
github.com/valyala/fasthttp v1.70.0/go.mod h1:oDZEHHkJ/Buyklg6uURmYs19442zFSnCIfX3j1FY3pE=
|
||||
github.com/valyala/fastjson v1.6.10 h1:/yjJg8jaVQdYR3arGxPE2X5z89xrlhS0eGXdv+ADTh4=
|
||||
github.com/valyala/fastjson v1.6.10/go.mod h1:e6FubmQouUNP73jtMLmcbxS6ydWIpOfhz34TSfO3JaE=
|
||||
github.com/vishvananda/netlink v1.3.1 h1:3AEMt62VKqz90r0tmNhog0r/PpWKmrEShJU0wJW6bV0=
|
||||
github.com/vishvananda/netlink v1.3.1/go.mod h1:ARtKouGSTGchR8aMwmkzC0qiNPrrWO5JS/XMVl45+b4=
|
||||
github.com/vishvananda/netns v0.0.5 h1:DfiHV+j8bA32MFM7bfEunvT8IAqQ/NzSJHtcmW5zdEY=
|
||||
github.com/vishvananda/netns v0.0.5/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
|
||||
github.com/xlzd/gotp v0.1.0 h1:37blvlKCh38s+fkem+fFh7sMnceltoIEBYTVXyoa5Po=
|
||||
github.com/xlzd/gotp v0.1.0/go.mod h1:ndLJ3JKzi3xLmUProq4LLxCuECL93dG9WASNLpHz8qg=
|
||||
github.com/xtls/reality v0.0.0-20260322125925-9234c772ba8f h1:iy2JRioxmUpoJ3SzbFPyTxHZMbR/rSHP7dOOgYaq1O8=
|
||||
github.com/xtls/reality v0.0.0-20260322125925-9234c772ba8f/go.mod h1:DsJblcWDGt76+FVqBVwbwRhxyyNJsGV48gJLch0OOWI=
|
||||
github.com/xtls/xray-core v1.260327.0 h1:g4TzxMwyPrxslZh6uD+FiG3lXKTrnNO+b4ky2OhogHE=
|
||||
github.com/xtls/xray-core v1.260327.0/go.mod h1:OXMlhBloFry8mw0KwWLWLd3RQyXJzEYsCGlgsX36h60=
|
||||
github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
|
||||
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
|
||||
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
|
||||
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
go.mongodb.org/mongo-driver/v2 v2.5.1 h1:j2U/Qp+wvueSpqitLCSZPT/+ZpVc1xzuwdHWwl7d8ro=
|
||||
go.mongodb.org/mongo-driver/v2 v2.5.1/go.mod h1:yOI9kBsufol30iFsl1slpdq1I0eHPzybRWdyYUs8K/0=
|
||||
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
|
||||
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
|
||||
go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48=
|
||||
go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8=
|
||||
go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0=
|
||||
go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs=
|
||||
go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18=
|
||||
go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew=
|
||||
go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI=
|
||||
go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA=
|
||||
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
|
||||
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||
go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y=
|
||||
go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU=
|
||||
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
|
||||
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
||||
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBseWJUpBw5I82+2U4M=
|
||||
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y=
|
||||
golang.org/x/arch v0.26.0 h1:jZ6dpec5haP/fUv1kLCbuJy6dnRrfX6iVK08lZBFpk4=
|
||||
golang.org/x/arch v0.26.0/go.mod h1:0X+GdSIP+kL5wPmpK7sdkEVTt2XoYP0cSjQSbZBwOi8=
|
||||
golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI=
|
||||
golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q=
|
||||
golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f h1:W3F4c+6OLc6H2lb//N1q4WpJkhzJCK5J6kUi1NTVXfM=
|
||||
golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f/go.mod h1:J1xhfL/vlindoeF/aINzNzt2Bket5bjo9sdOYzOsU80=
|
||||
golang.org/x/mod v0.35.0 h1:Ww1D637e6Pg+Zb2KrWfHQUnH2dQRLBQyAtpr/haaJeM=
|
||||
golang.org/x/mod v0.35.0/go.mod h1:+GwiRhIInF8wPm+4AoT6L0FA1QWAad3OMdTRx4tFYlU=
|
||||
golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA=
|
||||
golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs=
|
||||
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
|
||||
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=
|
||||
golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||
golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg=
|
||||
golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164=
|
||||
golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U=
|
||||
golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno=
|
||||
golang.org/x/tools v0.44.0 h1:UP4ajHPIcuMjT1GqzDWRlalUEoY+uzoZKnhOjbIPD2c=
|
||||
golang.org/x/tools v0.44.0/go.mod h1:KA0AfVErSdxRZIsOVipbv3rQhVXTnlU6UhKxHd1seDI=
|
||||
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeunTOisW56dUokqW/FOteYJJ/yg=
|
||||
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI=
|
||||
golang.zx2c4.com/wireguard v0.0.0-20250521234502-f333402bd9cb h1:whnFRlWMcXI9d+ZbWg+4sHnLp52d5yiIPUxMBSt4X9A=
|
||||
golang.zx2c4.com/wireguard v0.0.0-20250521234502-f333402bd9cb/go.mod h1:rpwXGsirqLqN2L0JDJQlwOboGHmptD5ZD6T2VmcqhTw=
|
||||
gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4=
|
||||
gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260420184626-e10c466a9529 h1:XF8+t6QQiS0o9ArVan/HW8Q7cycNPGsJf6GA2nXxYAg=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260420184626-e10c466a9529/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
|
||||
google.golang.org/grpc v1.80.0 h1:Xr6m2WmWZLETvUNvIUmeD5OAagMw3FiKmMlTdViWsHM=
|
||||
google.golang.org/grpc v1.80.0/go.mod h1:ho/dLnxwi3EDJA4Zghp7k2Ec1+c2jqup0bFkw07bwF4=
|
||||
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
|
||||
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gorm.io/driver/sqlite v1.6.0 h1:WHRRrIiulaPiPFmDcod6prc4l2VGVWHz80KspNsxSfQ=
|
||||
gorm.io/driver/sqlite v1.6.0/go.mod h1:AO9V1qIQddBESngQUKWL9yoH93HIeA1X6V633rBwyT8=
|
||||
gorm.io/gorm v1.31.1 h1:7CA8FTFz/gRfgqgpeKIBcervUn3xSyPUmr6B2WXJ7kg=
|
||||
gorm.io/gorm v1.31.1/go.mod h1:XyQVbO2k6YkOis7C2437jSit3SsDK72s7n7rsSHd+Gs=
|
||||
gvisor.dev/gvisor v0.0.0-20260122175437-89a5d21be8f0 h1:Lk6hARj5UPY47dBep70OD/TIMwikJ5fGUGX0Rm3Xigk=
|
||||
gvisor.dev/gvisor v0.0.0-20260122175437-89a5d21be8f0/go.mod h1:QkHjoMIBaYtpVufgwv3keYAbln78mBoCuShZrPrer1Q=
|
||||
lukechampine.com/blake3 v1.4.1 h1:I3Smz7gso8w4/TunLKec6K2fn+kyKtDxr/xcQEN84Wg=
|
||||
lukechampine.com/blake3 v1.4.1/go.mod h1:QFosUxmjB8mnrWFSNwKmvxHpfY72bmD2tQ0kBMM3kwo=
|
||||
622
install.sh
Normal file
@@ -0,0 +1,622 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ==========================================================
|
||||
# X-Panel 统一安装脚本 (付费/免费二合一)
|
||||
# 作者: X-Panel
|
||||
# ==========================================================
|
||||
|
||||
red='\033[0;31m'
|
||||
green='\033[0;32m'
|
||||
blue='\033[0;34m'
|
||||
yellow='\033[0;33m'
|
||||
plain='\033[0m'
|
||||
|
||||
# check root
|
||||
[[ $EUID -ne 0 ]] && echo -e "${red}致命错误: ${plain} 请使用 root 权限运行此脚本\n" && exit 1
|
||||
|
||||
# ----------------------------------------------------------
|
||||
# 获取机器唯一硬件标识 (HWID)
|
||||
# ----------------------------------------------------------
|
||||
get_hwid() {
|
||||
local machine_id=""
|
||||
|
||||
# 1. 优先尝试获取 DMI Product UUID (VPS 硬件 ID,重装系统通常不变)
|
||||
if [[ -r /sys/class/dmi/id/product_uuid ]]; then
|
||||
machine_id=$(cat /sys/class/dmi/id/product_uuid)
|
||||
|
||||
# 2. 其次尝试获取 eth0 网卡 MAC 地址 (大部分 VPS 重装后 MAC 不变)
|
||||
elif [[ -r /sys/class/net/eth0/address ]]; then
|
||||
machine_id=$(cat /sys/class/net/eth0/address)
|
||||
|
||||
# 3. 如果都失败,才使用 machine-id (重装会变,作为最后兜底)
|
||||
elif [[ -f /etc/machine-id ]]; then
|
||||
machine_id=$(cat /etc/machine-id)
|
||||
else
|
||||
machine_id=$(hostname)
|
||||
fi
|
||||
|
||||
# 取 MD5 作为唯一指纹,确保格式统一
|
||||
echo -n "$machine_id" | md5sum | awk '{print $1}'
|
||||
}
|
||||
|
||||
# ----------------------------------------------------------
|
||||
# 函数:付费Pro版安装逻辑 (install_paid_version)
|
||||
# ----------------------------------------------------------
|
||||
# 此函数负责获取授权码和IP + 机器指纹,并从远程授权服务器获取并执行付费脚本
|
||||
#
|
||||
install_paid_version() {
|
||||
echo ""
|
||||
echo -e "${green}您正在安装/升级/更新 【X-Panel 付费Pro版】${plain}"
|
||||
echo ""
|
||||
echo -e "${yellow}------------------------------------------------------${plain}"
|
||||
echo ""
|
||||
|
||||
# 1. 提示用户输入授权码
|
||||
read -p "$(echo -e "${yellow}请输入您的授权码 (License Key): ${plain}")" auth_key
|
||||
echo ""
|
||||
|
||||
if [ -z "$auth_key" ]; then
|
||||
echo -e "${red}错误: 您没有输入授权码。${plain}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 2. 获取本机的公共 IPv4 地址
|
||||
echo -e "${green}正在获取本机 IP 地址......${plain}"
|
||||
vps_ip=$(curl -s4m8 ip.sb -k | head -n 1)
|
||||
|
||||
if [ -z "$vps_ip" ]; then
|
||||
echo -e "${red}致命错误: 未能获取服务器的公共 IP 地址。${plain}"
|
||||
echo -e "${red}请检查您的网络连接或 curl 是否正常工作。${plain}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 3. [新增] 获取本机硬件指纹
|
||||
vps_hwid=$(get_hwid)
|
||||
|
||||
echo -e "${green}本机 IP: ${vps_ip}${plain}"
|
||||
echo -e "${green}机器指纹: ${vps_hwid}${plain}" # 调试用
|
||||
echo ""
|
||||
|
||||
# 4. 设置您的授权服务器地址
|
||||
AUTH_SERVER_URL="https://auth.x-panel.vip/install_pro.php"
|
||||
|
||||
echo -e "${green}正在连接〔远程授权服务器〕进行验证......${plain}"
|
||||
echo ""
|
||||
echo -e "${yellow}请稍候.........${plain}"
|
||||
|
||||
# 5. 将服务器响应保存到变量
|
||||
response=$(curl -sL --connect-timeout 20 -X POST -d "key=${auth_key}&ip=${vps_ip}&hwid=${vps_hwid}" "${AUTH_SERVER_URL}")
|
||||
|
||||
# 6. 简单判断响应是否为空
|
||||
if [ -z "$response" ]; then
|
||||
echo -e "${red}错误: 无法连接到授权服务器或服务器无响应。${plain}"
|
||||
echo -e "${yellow}请检查网络连接或联系管理员。${plain}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 7. 判断是否包含 PHP 错误 (如 Syntax error 或 Fatal error)
|
||||
# 如果 PHP 报错,通常会包含 "Fatal error" 或 "Parse error" 字样
|
||||
if echo "$response" | grep -qE "Fatal error|Parse error"; then
|
||||
echo -e "${red}错误: 授权服务器发生内部错误。${plain}"
|
||||
echo -e "详细信息: $response"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 8. 执行脚本
|
||||
bash <(echo "$response")
|
||||
|
||||
exit 0
|
||||
}
|
||||
|
||||
|
||||
# ----------------------------------------------------------
|
||||
# 函数:免费基础版安装逻辑 (install_free_version)
|
||||
# ----------------------------------------------------------
|
||||
install_free_version() {
|
||||
echo ""
|
||||
echo -e "${green}您选择了安装 【X-Panel 免费基础版】${plain}"
|
||||
echo ""
|
||||
echo -e "${green}即将开始执行标准安装流程...${plain}"
|
||||
sleep 2
|
||||
|
||||
cur_dir=$(pwd)
|
||||
|
||||
# Check OS and set release variable
|
||||
if [[ -f /etc/os-release ]]; then
|
||||
source /etc/os-release
|
||||
release=$ID
|
||||
elif [[ -f /usr/lib/os-release ]]; then
|
||||
source /usr/lib/os-release
|
||||
release=$ID
|
||||
else
|
||||
echo ""
|
||||
echo -e "${red}检查服务器操作系统失败,请联系作者!${plain}" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo ""
|
||||
echo -e "${green}---------->>>>>目前服务器的操作系统为: $release${plain}"
|
||||
|
||||
arch() {
|
||||
case "$(uname -m)" in
|
||||
x86_64 | x64 | amd64 ) echo 'amd64' ;;
|
||||
i*86 | x86 ) echo '386' ;;
|
||||
armv8* | armv8 | arm64 | aarch64 ) echo 'arm64' ;;
|
||||
armv7* | armv7 | arm ) echo 'armv7' ;;
|
||||
armv6* | armv6 ) echo 'armv6' ;;
|
||||
armv5* | armv5 ) echo 'armv5' ;;
|
||||
s390x) echo 's390x' ;;
|
||||
*) echo -e "${green}不支持的CPU架构! ${plain}" && rm -f install.sh && exit 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
echo ""
|
||||
# check_glibc_version() {
|
||||
# glibc_version=$(ldd --version | head -n1 | awk '{print $NF}')
|
||||
|
||||
# required_version="2.32"
|
||||
# if [[ "$(printf '%s\n' "$required_version" "$glibc_version" | sort -V | head -n1)" != "$required_version" ]]; then
|
||||
# echo -e "${red}------>>>GLIBC版本 $glibc_version 太旧了! 要求2.32或以上版本${plain}"
|
||||
# echo -e "${green}-------->>>>请升级到较新版本的操作系统以便获取更高版本的GLIBC${plain}"
|
||||
# exit 1
|
||||
# fi
|
||||
# echo -e "${green}-------->>>>GLIBC版本: $glibc_version(符合高于2.32的要求)${plain}"
|
||||
# }
|
||||
# check_glibc_version
|
||||
|
||||
# echo ""
|
||||
echo -e "${yellow}---------->>>>>当前系统的架构为: $(arch)${plain}"
|
||||
echo ""
|
||||
last_version=$(curl -Ls "https://api.github.com/repos/xeefei/x-panel/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
|
||||
# 获取 x-ui 版本
|
||||
xui_version=$(/usr/local/x-ui/x-ui -v)
|
||||
|
||||
# 检查 xui_version 是否为空
|
||||
if [[ -z "$xui_version" ]]; then
|
||||
echo ""
|
||||
echo -e "${red}------>>>当前服务器没有安装任何 x-ui 系列代理面板${plain}"
|
||||
echo ""
|
||||
echo -e "${green}-------->>>>片刻之后脚本将会自动引导安装〔X-Panel面板〕${plain}"
|
||||
else
|
||||
# 检查版本号中是否包含冒号
|
||||
if [[ "$xui_version" == *:* ]]; then
|
||||
echo -e "${green}---------->>>>>当前代理面板的版本为: ${red}其他 x-ui 分支版本${plain}"
|
||||
echo ""
|
||||
echo -e "${green}-------->>>>片刻之后脚本将会自动引导安装〔X-Panel面板〕${plain}"
|
||||
else
|
||||
echo -e "${green}---------->>>>>当前代理面板的版本为: ${red}〔X-Panel面板〕v${xui_version}${plain}"
|
||||
fi
|
||||
fi
|
||||
echo ""
|
||||
echo -e "${yellow}---------------------->>>>>〔X-Panel面板〕最新版为:${last_version}${plain}"
|
||||
sleep 4
|
||||
|
||||
os_version=$(grep -i version_id /etc/os-release | cut -d \" -f2 | cut -d . -f1)
|
||||
|
||||
if [[ "${release}" == "arch" ]]; then
|
||||
echo "您的操作系统是 ArchLinux"
|
||||
elif [[ "${release}" == "manjaro" ]]; then
|
||||
echo "您的操作系统是 Manjaro"
|
||||
elif [[ "${release}" == "armbian" ]]; then
|
||||
echo "您的操作系统是 Armbian"
|
||||
elif [[ "${release}" == "alpine" ]]; then
|
||||
echo "您的操作系统是 Alpine Linux"
|
||||
elif [[ "${release}" == "opensuse-tumbleweed" ]]; then
|
||||
echo "您的操作系统是 OpenSUSE Tumbleweed"
|
||||
elif [[ "${release}" == "centos" ]]; then
|
||||
if [[ ${os_version} -lt 8 ]]; then
|
||||
echo -e "${red} 请使用 CentOS 8 或更高版本 ${plain}\n" && exit 1
|
||||
fi
|
||||
elif [[ "${release}" == "ubuntu" ]]; then
|
||||
if [[ ${os_version} -lt 20 ]]; then
|
||||
echo -e "${red} 请使用 Ubuntu 20 或更高版本!${plain}\n" && exit 1
|
||||
fi
|
||||
elif [[ "${release}" == "fedora" ]]; then
|
||||
if [[ ${os_version} -lt 36 ]]; then
|
||||
echo -e "${red} 请使用 Fedora 36 或更高版本!${plain}\n" && exit 1
|
||||
fi
|
||||
elif [[ "${release}" == "debian" ]]; then
|
||||
if [[ ${os_version} -lt 11 ]]; then
|
||||
echo -e "${red} 请使用 Debian 11 或更高版本 ${plain}\n" && exit 1
|
||||
fi
|
||||
elif [[ "${release}" == "almalinux" ]]; then
|
||||
if [[ ${os_version} -lt 9 ]]; then
|
||||
echo -e "${red} 请使用 AlmaLinux 9 或更高版本 ${plain}\n" && exit 1
|
||||
fi
|
||||
elif [[ "${release}" == "rocky" ]]; then
|
||||
if [[ ${os_version} -lt 9 ]]; then
|
||||
echo -e "${red} 请使用 RockyLinux 9 或更高版本 ${plain}\n" && exit 1
|
||||
fi
|
||||
elif [[ "${release}" == "oracle" ]]; then
|
||||
if [[ ${os_version} -lt 8 ]]; then
|
||||
echo -e "${red} 请使用 Oracle Linux 8 或更高版本 ${plain}\n" && exit 1
|
||||
fi
|
||||
else
|
||||
echo -e "${red}此脚本不支持您的操作系统。${plain}\n"
|
||||
echo "请确保您使用的是以下受支持的操作系统之一:"
|
||||
echo "- Ubuntu 20.04+"
|
||||
echo "- Debian 11+"
|
||||
echo "- CentOS 8+"
|
||||
echo "- Fedora 36+"
|
||||
echo "- Arch Linux"
|
||||
echo "- Manjaro"
|
||||
echo "- Armbian"
|
||||
echo "- Alpine Linux"
|
||||
echo "- AlmaLinux 9+"
|
||||
echo "- Rocky Linux 9+"
|
||||
echo "- Oracle Linux 8+"
|
||||
echo "- OpenSUSE Tumbleweed"
|
||||
exit 1
|
||||
|
||||
fi
|
||||
|
||||
install_base() {
|
||||
case "${release}" in
|
||||
ubuntu | debian | armbian)
|
||||
apt-get update && apt-get install -y -q wget curl sudo tar tzdata
|
||||
;;
|
||||
centos | rhel | almalinux | rocky | ol)
|
||||
yum -y --exclude=kernel* update && yum install -y -q wget curl sudo tar tzdata
|
||||
;;
|
||||
fedora | amzn | virtuozzo)
|
||||
dnf -y --exclude=kernel* update && dnf install -y -q wget curl sudo tar tzdata
|
||||
;;
|
||||
arch | manjaro | parch)
|
||||
pacman -Sy && pacman -S --noconfirm wget curl sudo tar tzdata
|
||||
;;
|
||||
alpine)
|
||||
apk update && apk add --no-cache wget curl sudo tar tzdata
|
||||
;;
|
||||
opensuse-tumbleweed)
|
||||
zypper refresh && zypper -q install -y wget curl sudo tar timezone
|
||||
;;
|
||||
*)
|
||||
apt-get update && apt-get install -y -q wget curl sudo tar tzdata
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
gen_random_string() {
|
||||
local length="$1"
|
||||
local random_string=$(LC_ALL=C tr -dc 'a-zA-Z0-9' </dev/urandom | fold -w "$length" | head -n 1)
|
||||
echo "$random_string"
|
||||
}
|
||||
|
||||
# This function will be called when user installed x-ui out of security
|
||||
config_after_install() {
|
||||
echo -e "${yellow}安装/更新完成! 为了您的面板安全,建议修改面板设置 ${plain}"
|
||||
echo ""
|
||||
read -p "$(echo -e "${green}想继续修改吗?${red}选择“n”以保留旧设置${plain} [y/n]?--->>请输入:")" config_confirm
|
||||
if [[ "${config_confirm}" == "y" || "${config_confirm}" == "Y" ]]; then
|
||||
read -p "请设置您的用户名: " config_account
|
||||
echo -e "${yellow}您的用户名将是: ${config_account}${plain}"
|
||||
read -p "请设置您的密码: " config_password
|
||||
echo -e "${yellow}您的密码将是: ${config_password}${plain}"
|
||||
read -p "请设置面板端口: " config_port
|
||||
echo -e "${yellow}您的面板端口号为: ${config_port}${plain}"
|
||||
read -p "请设置面板登录访问路径: " config_webBasePath
|
||||
echo -e "${yellow}您的面板访问路径为: ${config_webBasePath}${plain}"
|
||||
echo -e "${yellow}正在初始化,请稍候...${plain}"
|
||||
/usr/local/x-ui/x-ui setting -username ${config_account} -password ${config_password}
|
||||
echo -e "${yellow}用户名和密码设置成功!${plain}"
|
||||
/usr/local/x-ui/x-ui setting -port ${config_port}
|
||||
echo -e "${yellow}面板端口号设置成功!${plain}"
|
||||
/usr/local/x-ui/x-ui setting -webBasePath ${config_webBasePath}
|
||||
echo -e "${yellow}面板登录访问路径设置成功!${plain}"
|
||||
echo ""
|
||||
else
|
||||
echo ""
|
||||
sleep 1
|
||||
echo -e "${red}--------------->>>>Cancel...--------------->>>>>>>取消修改...${plain}"
|
||||
echo ""
|
||||
if [[ ! -f "/etc/x-ui/x-ui.db" ]]; then
|
||||
local usernameTemp=$(head -c 10 /dev/urandom | base64)
|
||||
local passwordTemp=$(head -c 10 /dev/urandom | base64)
|
||||
local webBasePathTemp=$(gen_random_string 15)
|
||||
/usr/local/x-ui/x-ui setting -username ${usernameTemp} -password ${passwordTemp} -webBasePath ${webBasePathTemp}
|
||||
echo ""
|
||||
echo -e "${yellow}检测到为全新安装,出于安全考虑将生成随机登录信息:${plain}"
|
||||
echo -e "###############################################"
|
||||
echo -e "${green}用户名: ${usernameTemp}${plain}"
|
||||
echo -e "${green}密 码: ${passwordTemp}${plain}"
|
||||
echo -e "${green}访问路径: ${webBasePathTemp}${plain}"
|
||||
echo -e "###############################################"
|
||||
echo -e "${green}如果您忘记了登录信息,可以在安装后通过 x-ui 命令然后输入${red}数字 10 选项${green}进行查看${plain}"
|
||||
else
|
||||
echo -e "${green}此次操作属于版本升级,保留之前旧设置项,登录方式保持不变${plain}"
|
||||
echo ""
|
||||
echo -e "${green}如果您忘记了登录信息,您可以通过 x-ui 命令然后输入${red}数字 10 选项${green}进行查看${plain}"
|
||||
echo ""
|
||||
echo ""
|
||||
fi
|
||||
fi
|
||||
sleep 1
|
||||
echo -e ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
|
||||
echo ""
|
||||
/usr/local/x-ui/x-ui migrate
|
||||
}
|
||||
|
||||
echo ""
|
||||
install_x-ui() {
|
||||
cd /usr/local/
|
||||
|
||||
# Download resources
|
||||
if [ $# == 0 ]; then
|
||||
last_version=$(curl -Ls "https://api.github.com/repos/xeefei/x-panel/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
|
||||
if [[ ! -n "$last_version" ]]; then
|
||||
echo -e "${red}获取 X-Panel 版本失败,可能是 Github API 限制,请稍后再试${plain}"
|
||||
exit 1
|
||||
fi
|
||||
echo ""
|
||||
echo -e "-----------------------------------------------------"
|
||||
echo -e "${green}--------->>获取 X-Panel 最新版本:${yellow}${last_version}${plain}${green},开始安装...${plain}"
|
||||
echo -e "-----------------------------------------------------"
|
||||
echo ""
|
||||
sleep 2
|
||||
echo -e "${green}---------------->>>>>>>>>安装进度50%${plain}"
|
||||
sleep 3
|
||||
echo ""
|
||||
echo -e "${green}---------------->>>>>>>>>>>>>>>>>>>>>安装进度100%${plain}"
|
||||
echo ""
|
||||
sleep 2
|
||||
wget -N --no-check-certificate -O /usr/local/x-ui-linux-$(arch).tar.gz https://github.com/xeefei/x-panel/releases/download/${last_version}/x-ui-linux-$(arch).tar.gz
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo -e "${red}下载 X-Panel 失败, 请检查服务器是否可以连接至 GitHub? ${plain}"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
last_version=$1
|
||||
url="https://github.com/xeefei/x-panel/releases/download/${last_version}/x-ui-linux-$(arch).tar.gz"
|
||||
echo ""
|
||||
echo -e "--------------------------------------------"
|
||||
echo -e "${green}---------------->>>>开始安装 X-Panel 免费基础版$1${plain}"
|
||||
echo -e "--------------------------------------------"
|
||||
echo ""
|
||||
sleep 2
|
||||
echo -e "${green}---------------->>>>>>>>>安装进度50%${plain}"
|
||||
sleep 3
|
||||
echo ""
|
||||
echo -e "${green}---------------->>>>>>>>>>>>>>>>>>>>>安装进度100%${plain}"
|
||||
echo ""
|
||||
sleep 2
|
||||
wget -N --no-check-certificate -O /usr/local/x-ui-linux-$(arch).tar.gz ${url}
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo -e "${red}下载 X-Panel $1 失败, 请检查此版本是否存在 ${plain}"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
wget -O /usr/bin/x-ui-temp https://raw.githubusercontent.com/xeefei/x-panel/main/x-ui.sh
|
||||
|
||||
# Stop x-ui service and remove old resources
|
||||
if [[ -e /usr/local/x-ui/ ]]; then
|
||||
systemctl stop x-ui
|
||||
rm /usr/local/x-ui/ -rf
|
||||
fi
|
||||
|
||||
sleep 3
|
||||
echo -e "${green}------->>>>>>>>>>>检查并保存安装目录${plain}"
|
||||
echo ""
|
||||
tar zxvf x-ui-linux-$(arch).tar.gz
|
||||
rm x-ui-linux-$(arch).tar.gz -f
|
||||
|
||||
cd x-ui
|
||||
chmod +x x-ui
|
||||
chmod +x x-ui.sh
|
||||
|
||||
# Check the system's architecture and rename the file accordingly
|
||||
if [[ $(arch) == "armv5" || $(arch) == "armv6" || $(arch) == "armv7" ]]; then
|
||||
mv bin/xray-linux-$(arch) bin/xray-linux-arm
|
||||
chmod +x bin/xray-linux-arm
|
||||
fi
|
||||
chmod +x x-ui bin/xray-linux-$(arch)
|
||||
|
||||
# Update x-ui cli and se set permission
|
||||
mv -f /usr/bin/x-ui-temp /usr/bin/x-ui
|
||||
chmod +x /usr/bin/x-ui
|
||||
sleep 2
|
||||
echo -e "${green}------->>>>>>>>>>>保存成功${plain}"
|
||||
sleep 2
|
||||
echo ""
|
||||
config_after_install
|
||||
|
||||
ssh_forwarding() {
|
||||
# 获取 IPv4 和 IPv6 地址
|
||||
v4=$(curl -s4m8 http://ip.sb -k)
|
||||
v6=$(curl -s6m8 http://ip.sb -k)
|
||||
local existing_webBasePath=$(/usr/local/x-ui/x-ui setting -show true | grep -Eo 'webBasePath(访问路径): .+' | awk '{print $2}')
|
||||
local existing_port=$(/usr/local/x-ui/x-ui setting -show true | grep -Eo 'port(端口号): .+' | awk '{print $2}')
|
||||
local existing_cert=$(/usr/local/x-ui/x-ui setting -getCert true | grep -Eo 'cert: .+' | awk '{print $2}')
|
||||
local existing_key=$(/usr/local/x-ui/x-ui setting -getCert true | grep -Eo 'key: .+' | awk '{print $2}')
|
||||
|
||||
if [[ -n "$existing_cert" && -n "$existing_key" ]]; then
|
||||
echo -e "${green}面板已安装证书采用SSL保护${plain}"
|
||||
echo ""
|
||||
local existing_cert=$(/usr/local/x-ui/x-ui setting -getCert true | grep -Eo 'cert: .+' | awk '{print $2}')
|
||||
domain=$(basename "$(dirname "$existing_cert")")
|
||||
echo -e "${green}登录访问面板URL: https://${domain}:${existing_port}${green}${existing_webBasePath}${plain}"
|
||||
fi
|
||||
echo ""
|
||||
if [[ -z "$existing_cert" && -z "$existing_key" ]]; then
|
||||
echo -e "${red}警告:未找到证书和密钥,面板不安全!${plain}"
|
||||
echo ""
|
||||
echo -e "${green}------->>>>请按照下述方法设置〔ssh转发〕<<<<-------${plain}"
|
||||
echo ""
|
||||
|
||||
# 检查 IP 并输出相应的 SSH 和浏览器访问信息
|
||||
if [[ -z $v4 ]]; then
|
||||
echo -e "${green}1、本地电脑客户端转发命令:${plain} ${blue}ssh -L [::]:15208:127.0.0.1:${existing_port}${blue} root@[$v6]${plain}"
|
||||
echo ""
|
||||
echo -e "${green}2、请通过快捷键【Win + R】调出运行窗口,在里面输入【cmd】打开本地终端服务${plain}"
|
||||
echo ""
|
||||
echo -e "${green}3、请在终端中成功输入服务器的〔root密码〕,注意区分大小写,用以上命令进行转发${plain}"
|
||||
echo ""
|
||||
echo -e "${green}4、请在浏览器地址栏复制${plain} ${blue}[::1]:15208${existing_webBasePath}${plain} ${green}进入〔X-Panel面板〕登录界面"
|
||||
echo ""
|
||||
echo -e "${red}注意:若不使用〔ssh转发〕请为X-Panel面板配置安装证书再行登录管理后台${plain}"
|
||||
elif [[ -n $v4 && -n $v6 ]]; then
|
||||
echo -e "${green}1、本地电脑客户端转发命令:${plain} ${blue}ssh -L 15208:127.0.0.1:${existing_port}${blue} root@$v4${plain} ${yellow}或者 ${blue}ssh -L [::]:15208:127.0.0.1:${existing_port}${blue} root@[$v6]${plain}"
|
||||
echo ""
|
||||
echo -e "${green}2、请通过快捷键【Win + R】调出运行窗口,在里面输入【cmd】打开本地终端服务${plain}"
|
||||
echo ""
|
||||
echo -e "${green}3、请在终端中成功输入服务器的〔root密码〕,注意区分大小写,用以上命令进行转发${plain}"
|
||||
echo ""
|
||||
echo -e "${green}4、请在浏览器地址栏复制${plain} ${blue}127.0.0.1:15208${existing_webBasePath}${plain} ${yellow}或者${plain} ${blue}[::1]:15208${existing_webBasePath}${plain} ${green}进入〔X-Panel面板〕登录界面"
|
||||
echo ""
|
||||
echo -e "${red}注意:若不使用〔ssh转发〕请为X-Panel面板配置安装证书再行登录管理后台${plain}"
|
||||
else
|
||||
echo -e "${green}1、本地电脑客户端转发命令:${plain} ${blue}ssh -L 15208:127.0.0.1:${existing_port}${blue} root@$v4${plain}"
|
||||
echo ""
|
||||
echo -e "${green}2、请通过快捷键【Win + R】调出运行窗口,在里面输入【cmd】打开本地终端服务${plain}"
|
||||
echo ""
|
||||
echo -e "${green}3、请在终端中成功输入服务器的〔root密码〕,注意区分大小写,用以上命令进行转发${plain}"
|
||||
echo ""
|
||||
echo -e "${green}4、请在浏览器地址栏复制${plain} ${blue}127.0.0.1:15208${existing_webBasePath}${plain} ${green}进入〔X-Panel面板〕登录界面"
|
||||
echo ""
|
||||
echo -e "${red}注意:若不使用〔ssh转发〕请为X-Panel面板配置安装证书再行登录管理后台${plain}"
|
||||
echo ""
|
||||
fi
|
||||
fi
|
||||
}
|
||||
# 执行ssh端口转发
|
||||
ssh_forwarding
|
||||
|
||||
cp -f x-ui.service /etc/systemd/system/
|
||||
systemctl daemon-reload
|
||||
systemctl enable x-ui
|
||||
systemctl start x-ui
|
||||
systemctl stop warp-go >/dev/null 2>&1
|
||||
wg-quick down wgcf >/dev/null 2>&1
|
||||
ipv4=$(curl -s4m8 ip.p3terx.com -k | sed -n 1p)
|
||||
ipv6=$(curl -s6m8 ip.p3terx.com -k | sed -n 1p)
|
||||
systemctl start warp-go >/dev/null 2>&1
|
||||
wg-quick up wgcf >/dev/null 2A>&1
|
||||
|
||||
echo ""
|
||||
echo -e "------->>>>${green}X-Panel 免费基础版 ${last_version}${plain}<<<<安装成功,正在启动..."
|
||||
sleep 1
|
||||
echo ""
|
||||
echo -e " ---------------------"
|
||||
echo -e " |${green}X-Panel 控制菜单用法 ${plain}|${plain}"
|
||||
echo -e " | ${yellow}一个更好的面板 ${plain}|${plain}"
|
||||
echo -e " | ${yellow}基于Xray Core构建 ${plain}|${plain}"
|
||||
echo -e "--------------------------------------------"
|
||||
echo -e "x-ui - 进入管理脚本"
|
||||
echo -e "x-ui start - 启动 X-Panel 面板"
|
||||
echo -e "x-ui stop - 关闭 X-Panel 面板"
|
||||
echo -e "x-ui restart - 重启 X-Panel 面板"
|
||||
echo -e "x-ui status - 查看 X-Panel 状态"
|
||||
echo -e "x-ui settings - 查看当前设置信息"
|
||||
echo -e "x-ui enable - 启用 X-Panel 开机启动"
|
||||
echo -e "x-ui disable - 禁用 X-Panel 开机启动"
|
||||
echo -e "x-ui log - 查看 X-Panel 运行日志"
|
||||
echo -e "x-ui banlog - 检查 Fail2ban 禁止日志"
|
||||
echo -e "x-ui update - 更新 X-Panel 面板"
|
||||
echo -e "x-ui custom - 自定义 X-Panel 版本"
|
||||
echo -e "x-ui install - 安装 X-Panel 面板"
|
||||
echo -e "x-ui uninstall - 卸载 X-Panel 面板"
|
||||
echo -e "--------------------------------------------"
|
||||
echo ""
|
||||
# if [[ -n $ipv4 ]]; then
|
||||
# echo -e "${yellow}面板 IPv4 访问地址为:${green}http://$ipv4:${config_port}/${config_webBasePath}${plain}"
|
||||
# fi
|
||||
# if [[ -n $ipv6 ]]; then
|
||||
# echo -e "${yellow}面板 IPv6 访问地址为:${green}http://[$ipv6]:${config_port}/${config_webBasePath}${plain}"
|
||||
# fi
|
||||
# echo -e "请自行确保此端口没有被其他程序占用,${yellow}并且确保${red} ${config_port} ${yellow}端口已放行${plain}"
|
||||
sleep 3
|
||||
echo -e ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
|
||||
echo ""
|
||||
echo -e "${yellow}----->>>X-Panel面板和Xray启动成功<<<-----${plain}"
|
||||
}
|
||||
|
||||
# 设置VPS中的时区/时间为【上海时间】
|
||||
sudo timedatectl set-timezone Asia/Shanghai
|
||||
|
||||
install_base
|
||||
install_x-ui $1
|
||||
echo ""
|
||||
echo -e "----------------------------------------------"
|
||||
sleep 4
|
||||
info=$(/usr/local/x-ui/x-ui setting -show true)
|
||||
echo -e "${info}${plain}"
|
||||
echo ""
|
||||
echo -e "若您忘记了上述面板信息,后期可通过x-ui命令进入脚本${red}输入数字〔10〕选项获取${plain}"
|
||||
echo ""
|
||||
echo -e "----------------------------------------------"
|
||||
echo ""
|
||||
sleep 2
|
||||
echo -e "${green}安装/更新完成,若在使用过程中有任何问题${plain}"
|
||||
echo -e "${yellow}请先描述清楚所遇问题加〔X-Panel面板〕交流群${plain}"
|
||||
echo -e "${yellow}在TG群中${red} https://t.me/XUI_CN ${yellow}截图进行反馈${plain}"
|
||||
echo ""
|
||||
echo -e "----------------------------------------------"
|
||||
echo ""
|
||||
echo -e "${green}〔X-Panel面板〕项目地址:${yellow}https://github.com/xeefei/x-panel${plain}"
|
||||
echo ""
|
||||
echo -e "${green} 详细安装教程:${yellow}https://xeefei.blogspot.com/2025/09/x-panel.html${plain}"
|
||||
echo ""
|
||||
echo -e "----------------------------------------------"
|
||||
echo ""
|
||||
echo -e "-------------->>>>>>>赞 助 推 广 区<<<<<<<<-------------------"
|
||||
echo ""
|
||||
echo -e "${green}1、搬瓦工GIA高端线路:${yellow}https://bandwagonhost.com/aff.php?aff=75015${plain}"
|
||||
echo ""
|
||||
echo -e "${green}2、Dmit高端GIA线路:${yellow}https://www.dmit.io/aff.php?aff=9326${plain}"
|
||||
echo ""
|
||||
echo -e "${green}3、Gomami亚太顶尖优化线路:${yellow}https://gomami.io/aff.php?aff=174${plain}"
|
||||
echo ""
|
||||
echo -e "${green}4、ISIF优质亚太优化线路:${yellow}https://cloud.isif.net/login?affiliation_code=333${plain}"
|
||||
echo ""
|
||||
echo -e "${green}5、ZoroCloud全球优质原生家宽&住宅双lSP,跨境首选:${yellow}https://my.zorocloud.com/aff.php?aff=1072${plain}"
|
||||
echo ""
|
||||
echo -e "${green}6、三网直连 IEPL / IPLC 直播流量转发:${yellow}https://idc333.top/#register/BCUZXNELNO${plain}"
|
||||
echo ""
|
||||
echo -e "${green}7、Bagevm优质落地鸡(原生IP全解锁):${yellow}https://www.bagevm.com/aff.php?aff=754${plain}"
|
||||
echo ""
|
||||
echo -e "${green}8、白丝云〔4837线路〕实惠量大管饱:${yellow}https://cloudsilk.io/aff.php?aff=706${plain}"
|
||||
echo ""
|
||||
echo -e "${green}9、RackNerd极致性价比机器:${yellow}https://my.racknerd.com/aff.php?aff=15268&pid=912${plain}"
|
||||
echo ""
|
||||
echo -e "----------------------------------------------"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# 免费版安装逻辑函数 (install_free_version) 结束
|
||||
|
||||
# ----------------------------------------------------------
|
||||
# 脚本主菜单
|
||||
# ----------------------------------------------------------
|
||||
main_menu() {
|
||||
echo -e "${green}======================================================${plain}"
|
||||
echo -e " 欢迎使用 ${yellow}〔X-Panel 面板〕${plain} 一键安装脚本"
|
||||
echo -e "${green}======================================================${plain}"
|
||||
echo ""
|
||||
echo -e "请选择您要安装的版本:"
|
||||
echo ""
|
||||
echo -e " ${green}1)${plain} 安装 ${yellow}〔X-Panel 面板〕免费基础版${plain} (GitHub 开源项目)"
|
||||
echo ""
|
||||
echo -e " ${green}2)${plain} 安装 ${yellow}〔X-Panel 面板〕付费Pro版${plain} (需要购买授权码)"
|
||||
echo ""
|
||||
read -p "请输入您的选择 (1 或 2): " version_choice
|
||||
echo ""
|
||||
|
||||
case "$version_choice" in
|
||||
1)
|
||||
# 如果选择1,调用免费版函数
|
||||
install_free_version
|
||||
;;
|
||||
2)
|
||||
# 如果选择2,调用付费版函数
|
||||
install_paid_version
|
||||
;;
|
||||
*)
|
||||
echo -e "${red}输入无效, 退出安装。${plain}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# ----------------------------------------------------------
|
||||
# 脚本执行入口
|
||||
# ----------------------------------------------------------
|
||||
clear
|
||||
main_menu
|
||||
128
logger/logger.go
Normal file
@@ -0,0 +1,128 @@
|
||||
package logger
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/op/go-logging"
|
||||
)
|
||||
|
||||
var (
|
||||
logger *logging.Logger
|
||||
logBuffer []struct {
|
||||
time string
|
||||
level logging.Level
|
||||
log string
|
||||
}
|
||||
)
|
||||
|
||||
func init() {
|
||||
InitLogger(logging.INFO)
|
||||
}
|
||||
|
||||
func InitLogger(level logging.Level) {
|
||||
newLogger := logging.MustGetLogger("x-ui")
|
||||
var err error
|
||||
var backend logging.Backend
|
||||
var format logging.Formatter
|
||||
ppid := os.Getppid()
|
||||
|
||||
backend, err = logging.NewSyslogBackend("")
|
||||
if err != nil {
|
||||
println(err)
|
||||
backend = logging.NewLogBackend(os.Stderr, "", 0)
|
||||
}
|
||||
if ppid > 0 && err != nil {
|
||||
format = logging.MustStringFormatter(`%{time:2006/01/02 15:04:05} %{level} - %{message}`)
|
||||
} else {
|
||||
format = logging.MustStringFormatter(`%{level} - %{message}`)
|
||||
}
|
||||
|
||||
backendFormatter := logging.NewBackendFormatter(backend, format)
|
||||
backendLeveled := logging.AddModuleLevel(backendFormatter)
|
||||
backendLeveled.SetLevel(level, "x-ui")
|
||||
newLogger.SetBackend(backendLeveled)
|
||||
|
||||
logger = newLogger
|
||||
}
|
||||
|
||||
func Debug(args ...any) {
|
||||
logger.Debug(args...)
|
||||
addToBuffer("DEBUG", fmt.Sprint(args...))
|
||||
}
|
||||
|
||||
func Debugf(format string, args ...any) {
|
||||
logger.Debugf(format, args...)
|
||||
addToBuffer("DEBUG", fmt.Sprintf(format, args...))
|
||||
}
|
||||
|
||||
func Info(args ...any) {
|
||||
logger.Info(args...)
|
||||
addToBuffer("INFO", fmt.Sprint(args...))
|
||||
}
|
||||
|
||||
func Infof(format string, args ...any) {
|
||||
logger.Infof(format, args...)
|
||||
addToBuffer("INFO", fmt.Sprintf(format, args...))
|
||||
}
|
||||
|
||||
func Notice(args ...any) {
|
||||
logger.Notice(args...)
|
||||
addToBuffer("NOTICE", fmt.Sprint(args...))
|
||||
}
|
||||
|
||||
func Noticef(format string, args ...any) {
|
||||
logger.Noticef(format, args...)
|
||||
addToBuffer("NOTICE", fmt.Sprintf(format, args...))
|
||||
}
|
||||
|
||||
func Warning(args ...any) {
|
||||
logger.Warning(args...)
|
||||
addToBuffer("WARNING", fmt.Sprint(args...))
|
||||
}
|
||||
|
||||
func Warningf(format string, args ...any) {
|
||||
logger.Warningf(format, args...)
|
||||
addToBuffer("WARNING", fmt.Sprintf(format, args...))
|
||||
}
|
||||
|
||||
func Error(args ...any) {
|
||||
logger.Error(args...)
|
||||
addToBuffer("ERROR", fmt.Sprint(args...))
|
||||
}
|
||||
|
||||
func Errorf(format string, args ...any) {
|
||||
logger.Errorf(format, args...)
|
||||
addToBuffer("ERROR", fmt.Sprintf(format, args...))
|
||||
}
|
||||
|
||||
func addToBuffer(level string, newLog string) {
|
||||
t := time.Now()
|
||||
if len(logBuffer) >= 10240 {
|
||||
logBuffer = logBuffer[1:]
|
||||
}
|
||||
|
||||
logLevel, _ := logging.LogLevel(level)
|
||||
logBuffer = append(logBuffer, struct {
|
||||
time string
|
||||
level logging.Level
|
||||
log string
|
||||
}{
|
||||
time: t.Format("2006/01/02 15:04:05"),
|
||||
level: logLevel,
|
||||
log: newLog,
|
||||
})
|
||||
}
|
||||
|
||||
func GetLogs(c int, level string) []string {
|
||||
var output []string
|
||||
logLevel, _ := logging.LogLevel(level)
|
||||
|
||||
for i := len(logBuffer) - 1; i >= 0 && len(output) <= c; i-- {
|
||||
if logBuffer[i].level <= logLevel {
|
||||
output = append(output, fmt.Sprintf("%s %s - %s", logBuffer[i].time, logBuffer[i].level, logBuffer[i].log))
|
||||
}
|
||||
}
|
||||
return output
|
||||
}
|
||||
649
main.go
Normal file
@@ -0,0 +1,649 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
// "os/exec"
|
||||
// "strings"
|
||||
"syscall"
|
||||
_ "unsafe"
|
||||
// 中文注释: 新增了 time 和 x-ui/job 的导入,这是运行定时任务所必需的包
|
||||
"time"
|
||||
|
||||
"x-ui/web/job"
|
||||
"x-ui/config"
|
||||
"x-ui/database"
|
||||
"x-ui/logger"
|
||||
"x-ui/sub"
|
||||
"x-ui/util/crypto"
|
||||
"x-ui/web"
|
||||
"x-ui/web/global"
|
||||
"x-ui/web/service"
|
||||
"x-ui/xray"
|
||||
|
||||
"github.com/joho/godotenv"
|
||||
"github.com/op/go-logging"
|
||||
)
|
||||
|
||||
// runWebServer 是【设备限制】项目的主执行函数
|
||||
func runWebServer() {
|
||||
log.Printf("Starting %v %v", config.GetName(), config.GetVersion())
|
||||
|
||||
switch config.GetLogLevel() {
|
||||
case config.Debug:
|
||||
logger.InitLogger(logging.DEBUG)
|
||||
case config.Info:
|
||||
logger.InitLogger(logging.INFO)
|
||||
case config.Notice:
|
||||
logger.InitLogger(logging.NOTICE)
|
||||
case config.Warn:
|
||||
logger.InitLogger(logging.WARNING)
|
||||
case config.Error:
|
||||
logger.InitLogger(logging.ERROR)
|
||||
default:
|
||||
log.Fatalf("Unknown log level: %v", config.GetLogLevel())
|
||||
}
|
||||
|
||||
godotenv.Load()
|
||||
|
||||
err := database.InitDB(config.GetDBPath())
|
||||
if err != nil {
|
||||
log.Fatalf("Error initializing database: %v", err)
|
||||
}
|
||||
|
||||
// 〔中文注释〕: 1. 初始化所有需要的服务实例
|
||||
xrayService := service.XrayService{}
|
||||
settingService := service.SettingService{}
|
||||
serverService := service.ServerService{}
|
||||
// 还需要 InboundService 等,按需添加
|
||||
inboundService := service.InboundService{}
|
||||
lastStatus := service.Status{}
|
||||
|
||||
// 创建 Xray API 实例
|
||||
xrayApi := xray.XrayAPI{}
|
||||
|
||||
// 注入到 XrayService 中
|
||||
xrayService.SetXrayAPI(xrayApi)
|
||||
|
||||
// 注入到 InboundService 中
|
||||
inboundService.SetXrayAPI(xrayApi)
|
||||
|
||||
// 〔中文注释〕: 2. 初始化 TG Bot 服务 (如果已启用)
|
||||
tgEnable, err := settingService.GetTgbotEnabled()
|
||||
if err != nil {
|
||||
logger.Warningf("无法获取 Telegram Bot 设置: %v", err)
|
||||
}
|
||||
|
||||
var tgBotService service.TelegramService
|
||||
if tgEnable {
|
||||
// 将所有需要的服务作为参数传递进去,确保返回的 tgBotService 是一个完全初始化的、可用的实例。
|
||||
tgBot := service.NewTgBot(&inboundService, &settingService, &serverService, &xrayService, &lastStatus)
|
||||
tgBotService = tgBot
|
||||
}
|
||||
|
||||
// 〔中文注释〕: 3. 【核心步骤】执行依赖注入
|
||||
// 将 tgBotService 实例注入到 serverService 中。
|
||||
// 这样 serverService 内部的 tgService 字段就不再是 nil 了。
|
||||
serverService.SetTelegramService(tgBotService)
|
||||
// 同理,也为 InboundService 注入
|
||||
inboundService.SetTelegramService(tgBotService)
|
||||
|
||||
var server *web.Server
|
||||
|
||||
// 〔中文注释〕: 调用我们刚刚改造过的 web.NewServer,把功能完整的 serverService 传进去。
|
||||
server = web.NewServer(serverService)
|
||||
// 将 tgBotService 注入到 web.Server 中,使其在 web.go/Server.Start() 中可用
|
||||
if tgBotService != nil {
|
||||
// 〔中文注释〕: 这里的注入是为了让 Web Server 可以在启动时调用 Tgbot.Start()
|
||||
// 同时,也确保了 Web 层的回调处理能使用到这个完整的 Bot 实例
|
||||
server.SetTelegramService(tgBotService)
|
||||
}
|
||||
|
||||
global.SetWebServer(server)
|
||||
err = server.Start()
|
||||
if err != nil {
|
||||
log.Fatalf("Error starting web server: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
var subServer *sub.Server
|
||||
subServer = sub.NewServer()
|
||||
global.SetSubServer(subServer)
|
||||
err = subServer.Start()
|
||||
if err != nil {
|
||||
log.Fatalf("Error starting sub server: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// 中文注释: 在面板服务启动后,我们在这里启动设备限制的后台任务
|
||||
go func() {
|
||||
// 中文注释: 等待5秒,确保面板和Xray服务已基本稳定,避免任务启动过早
|
||||
time.Sleep(10 * time.Second)
|
||||
|
||||
// 中文注释: 创建一个定时器。这里的 "10 * time.Second" 就是任务执行的间隔时间。
|
||||
// 您可以修改 10 为 2 或 1,来实现更短的延迟。
|
||||
// 例如: time.NewTicker(2 * time.Second) 就是2秒执行一次。
|
||||
ticker := time.NewTicker(10 * time.Second)
|
||||
defer ticker.Stop()
|
||||
|
||||
// 〔中文注释〕: 步骤一:在循环外部,只声明一次 tgBotService 变量。
|
||||
// 我们将其声明为接口类型,初始值为 nil。
|
||||
var tgBotService service.TelegramService
|
||||
|
||||
// 〔中文注释〕: 步骤二:检查 Telegram Bot 是否在面板设置中启用。
|
||||
settingService := service.SettingService{}
|
||||
tgEnable, err := settingService.GetTgbotEnabled()
|
||||
if err != nil {
|
||||
logger.Warningf("无法获取 Telegram Bot 设置: %v, 设备限制通知功能可能无法使用", err)
|
||||
}
|
||||
|
||||
// 〔中文注释〕: 步骤三:如果 Bot 已启用,则初始化实例并赋值给上面声明的变量。
|
||||
// 注意这里使用的是 `=` 而不是 `:=`,因为我们是给已存在的变量赋值。
|
||||
if tgEnable {
|
||||
tgBotService = new(service.Tgbot)
|
||||
}
|
||||
|
||||
// 〔中文注释〕:步骤四:创建任务实例时,将 xrayService 和 可能为 nil 的 tgBotService 一同传入。
|
||||
// 这样做是安全的,因为 check_client_ip_job.go 内部的 SendMessage 调用前,会先判断服务实例是否可用。
|
||||
checkJob := job.NewCheckDeviceLimitJob(&xrayService, tgBotService)
|
||||
|
||||
|
||||
// 中文注释: 使用一个无限循环,每次定时器触发,就执行一次任务的 Run() 函数
|
||||
for {
|
||||
<-ticker.C
|
||||
checkJob.Run()
|
||||
}
|
||||
}()
|
||||
|
||||
sigCh := make(chan os.Signal, 1)
|
||||
// Trap shutdown signals
|
||||
signal.Notify(sigCh, syscall.SIGHUP, syscall.SIGTERM)
|
||||
for {
|
||||
sig := <-sigCh
|
||||
|
||||
switch sig {
|
||||
case syscall.SIGHUP:
|
||||
logger.Info("Received SIGHUP signal. Restarting servers...")
|
||||
|
||||
err := server.Stop()
|
||||
if err != nil {
|
||||
logger.Debug("Error stopping web server:", err)
|
||||
}
|
||||
err = subServer.Stop()
|
||||
if err != nil {
|
||||
logger.Debug("Error stopping sub server:", err)
|
||||
}
|
||||
|
||||
server = web.NewServer(serverService)
|
||||
// 重新注入 tgBotService
|
||||
if tgBotService != nil {
|
||||
server.SetTelegramService(tgBotService)
|
||||
}
|
||||
global.SetWebServer(server)
|
||||
err = server.Start()
|
||||
if err != nil {
|
||||
log.Fatalf("Error restarting web server: %v", err)
|
||||
return
|
||||
}
|
||||
log.Println("Web server restarted successfully.")
|
||||
|
||||
subServer = sub.NewServer()
|
||||
global.SetSubServer(subServer)
|
||||
err = subServer.Start()
|
||||
if err != nil {
|
||||
log.Fatalf("Error restarting sub server: %v", err)
|
||||
return
|
||||
}
|
||||
log.Println("Sub server restarted successfully.")
|
||||
|
||||
default:
|
||||
server.Stop()
|
||||
subServer.Stop()
|
||||
log.Println("Shutting down servers.")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func resetSetting() {
|
||||
err := database.InitDB(config.GetDBPath())
|
||||
if err != nil {
|
||||
fmt.Println("Failed to initialize database:", err)
|
||||
return
|
||||
}
|
||||
|
||||
settingService := service.SettingService{}
|
||||
err = settingService.ResetSettings()
|
||||
if err != nil {
|
||||
fmt.Println("Failed to reset settings(重置设置失败):", err)
|
||||
} else {
|
||||
fmt.Println("Settings successfully reset ---->>重置设置成功")
|
||||
}
|
||||
}
|
||||
|
||||
func showSetting(show bool) {
|
||||
// 执行 shell 命令获取 IPv4 地址
|
||||
// cmdIPv4 := exec.Command("sh", "-c", "curl -s4m8 ip.p3terx.com -k | sed -n 1p")
|
||||
// outputIPv4, err := cmdIPv4.Output()
|
||||
// if err != nil {
|
||||
// log.Fatal(err)
|
||||
// }
|
||||
|
||||
// 执行 shell 命令获取 IPv6 地址
|
||||
// cmdIPv6 := exec.Command("sh", "-c", "curl -s6m8 ip.p3terx.com -k | sed -n 1p")
|
||||
// outputIPv6, err := cmdIPv6.Output()
|
||||
// if err != nil {
|
||||
// log.Fatal(err)
|
||||
// }
|
||||
|
||||
// 去除命令输出中的换行符
|
||||
// ipv4 := strings.TrimSpace(string(outputIPv4))
|
||||
// ipv6 := strings.TrimSpace(string(outputIPv6))
|
||||
// 定义转义字符,定义不同颜色的转义字符
|
||||
const (
|
||||
Reset = "\033[0m"
|
||||
Red = "\033[31m"
|
||||
Green = "\033[32m"
|
||||
Yellow = "\033[33m"
|
||||
)
|
||||
if show {
|
||||
settingService := service.SettingService{}
|
||||
port, err := settingService.GetPort()
|
||||
if err != nil {
|
||||
fmt.Println("get current port failed, error info(获取当前端口失败,错误信息):", err)
|
||||
}
|
||||
|
||||
webBasePath, err := settingService.GetBasePath()
|
||||
if err != nil {
|
||||
fmt.Println("get webBasePath failed, error info(获取访问路径失败,错误信息):", err)
|
||||
}
|
||||
|
||||
certFile, err := settingService.GetCertFile()
|
||||
if err != nil {
|
||||
fmt.Println("get cert file failed, error info:", err)
|
||||
}
|
||||
keyFile, err := settingService.GetKeyFile()
|
||||
if err != nil {
|
||||
fmt.Println("get key file failed, error info:", err)
|
||||
}
|
||||
|
||||
userService := service.UserService{}
|
||||
userModel, err := userService.GetFirstUser()
|
||||
if err != nil {
|
||||
fmt.Println("get current user info failed, error info(获取当前用户信息失败,错误信息):", err)
|
||||
}
|
||||
|
||||
if userModel.Username == "" || userModel.Password == "" {
|
||||
fmt.Println("current username or password is empty --->>当前用户名或密码为空")
|
||||
}
|
||||
|
||||
fmt.Println("")
|
||||
fmt.Println(Yellow + "----->>>以下为面板重要信息,请自行记录保存<<<-----" + Reset)
|
||||
fmt.Println(Green + "Current panel settings as follows (当前面板设置如下):" + Reset)
|
||||
fmt.Println("")
|
||||
if certFile == "" || keyFile == "" {
|
||||
fmt.Println(Red + "------>> 警告:面板未安装证书进行SSL保护" + Reset)
|
||||
} else {
|
||||
fmt.Println(Green + "------>> 面板已安装证书采用SSL保护" + Reset)
|
||||
}
|
||||
fmt.Println("")
|
||||
hasDefaultCredential := func() bool {
|
||||
return userModel.Username == "admin" && crypto.CheckPasswordHash(userModel.Password, "admin")
|
||||
}()
|
||||
if hasDefaultCredential == true {
|
||||
fmt.Println(Red + "------>> 警告:使用了默认的admin账号/密码,容易被扫描" + Reset)
|
||||
} else {
|
||||
fmt.Println(Green + "------>> 为非默认admin账号/密码,请牢记" + Reset)
|
||||
}
|
||||
fmt.Println("")
|
||||
fmt.Println(Green + fmt.Sprintf("port(端口号): %d", port) + Reset)
|
||||
fmt.Println(Green + fmt.Sprintf("webBasePath(访问路径): %s", webBasePath) + Reset)
|
||||
fmt.Println(Green + "PS:为安全起见,不显示账号和密码" + Reset)
|
||||
fmt.Println(Green + "若您已经忘记账号/密码,请用脚本选项〔6〕重新设置" + Reset)
|
||||
|
||||
fmt.Println("")
|
||||
fmt.Println("--------------------------------------------------")
|
||||
// 根据条件打印带颜色的字符串
|
||||
// if ipv4 != "" {
|
||||
// fmt.Println("")
|
||||
// formattedIPv4 := fmt.Sprintf("%s %s%s:%d%s" + Reset,
|
||||
// Green+"面板 IPv4 访问地址------>>",
|
||||
// Yellow+"http://",
|
||||
// ipv4,
|
||||
// port,
|
||||
// Yellow+webBasePath + Reset)
|
||||
// fmt.Println(formattedIPv4)
|
||||
// fmt.Println("")
|
||||
// }
|
||||
|
||||
// if ipv6 != "" {
|
||||
// fmt.Println("")
|
||||
// formattedIPv6 := fmt.Sprintf("%s %s[%s%s%s]:%d%s%s",
|
||||
// Green+"面板 IPv6 访问地址------>>", // 绿色的提示信息
|
||||
// Yellow+"http://", // 黄色的 http:// 部分
|
||||
// Yellow, // 黄色的[ 左方括号
|
||||
// ipv6, // IPv6 地址
|
||||
// Yellow, // 黄色的] 右方括号
|
||||
// port, // 端口号
|
||||
// Yellow+webBasePath, // 黄色的 Web 基础路径
|
||||
// Reset) // 重置颜色
|
||||
// fmt.Println(formattedIPv6)
|
||||
// fmt.Println("")
|
||||
// }
|
||||
fmt.Println(Green + ">>>>>>>>注:若您安装了〔证书〕,请使用您的域名用https方式登录" + Reset)
|
||||
fmt.Println("")
|
||||
fmt.Println("--------------------------------------------------")
|
||||
fmt.Println("")
|
||||
// fmt.Println("↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑")
|
||||
fmt.Println(fmt.Sprintf("%s请确保 %s%d%s 端口已打开放行%s",Green, Red, port, Green, Reset))
|
||||
fmt.Println(Yellow + "请自行确保此端口没有被其他程序占用" + Reset)
|
||||
// fmt.Println(Green + "若要登录访问面板,请复制上面的地址到浏览器" + Reset)
|
||||
fmt.Println("")
|
||||
fmt.Println("--------------------------------------------------")
|
||||
fmt.Println("")
|
||||
}
|
||||
}
|
||||
|
||||
func updateTgbotEnableSts(status bool) {
|
||||
settingService := service.SettingService{}
|
||||
currentTgSts, err := settingService.GetTgbotEnabled()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
logger.Infof("current enabletgbot status[%v],need update to status[%v]", currentTgSts, status)
|
||||
if currentTgSts != status {
|
||||
err := settingService.SetTgbotEnabled(status)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
} else {
|
||||
logger.Infof("SetTgbotEnabled[%v] success", status)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func updateTgbotSetting(tgBotToken string, tgBotChatid string, tgBotRuntime string) {
|
||||
err := database.InitDB(config.GetDBPath())
|
||||
if err != nil {
|
||||
fmt.Println("Error initializing database(初始化数据库出错):", err)
|
||||
return
|
||||
}
|
||||
|
||||
settingService := service.SettingService{}
|
||||
|
||||
if tgBotToken != "" {
|
||||
err := settingService.SetTgBotToken(tgBotToken)
|
||||
if err != nil {
|
||||
fmt.Printf("Error setting Telegram bot token(设置TG电报机器人令牌出错): %v\n", err)
|
||||
return
|
||||
}
|
||||
logger.Info("Successfully updated Telegram bot token ----->>已成功更新TG电报机器人令牌")
|
||||
}
|
||||
|
||||
if tgBotRuntime != "" {
|
||||
err := settingService.SetTgbotRuntime(tgBotRuntime)
|
||||
if err != nil {
|
||||
fmt.Printf("Error setting Telegram bot runtime(设置TG电报机器人通知周期出错): %v\n", err)
|
||||
return
|
||||
}
|
||||
logger.Infof("Successfully updated Telegram bot runtime to (已成功将TG电报机器人通知周期设置为) [%s].", tgBotRuntime)
|
||||
}
|
||||
|
||||
if tgBotChatid != "" {
|
||||
err := settingService.SetTgBotChatId(tgBotChatid)
|
||||
if err != nil {
|
||||
fmt.Printf("Error setting Telegram bot chat ID(设置TG电报机器人管理者聊天ID出错): %v\n", err)
|
||||
return
|
||||
}
|
||||
logger.Info("Successfully updated Telegram bot chat ID ----->>已成功更新TG电报机器人管理者聊天ID")
|
||||
}
|
||||
}
|
||||
|
||||
func updateSetting(port int, username string, password string, webBasePath string, listenIP string, resetTwoFactor bool) {
|
||||
err := database.InitDB(config.GetDBPath())
|
||||
if err != nil {
|
||||
fmt.Println("Database initialization failed(初始化数据库失败):", err)
|
||||
return
|
||||
}
|
||||
|
||||
settingService := service.SettingService{}
|
||||
userService := service.UserService{}
|
||||
|
||||
if port > 0 {
|
||||
err := settingService.SetPort(port)
|
||||
if err != nil {
|
||||
fmt.Println("Failed to set port(设置端口失败):", err)
|
||||
} else {
|
||||
fmt.Printf("Port set successfully(端口设置成功): %v\n", port)
|
||||
}
|
||||
}
|
||||
|
||||
if username != "" || password != "" {
|
||||
err := userService.UpdateFirstUser(username, password)
|
||||
if err != nil {
|
||||
fmt.Println("Failed to update username and password(更新用户名和密码失败):", err)
|
||||
} else {
|
||||
fmt.Println("Username and password updated successfully ------>>用户名和密码更新成功")
|
||||
}
|
||||
}
|
||||
|
||||
if webBasePath != "" {
|
||||
err := settingService.SetBasePath(webBasePath)
|
||||
if err != nil {
|
||||
fmt.Println("Failed to set base URI path(设置访问路径失败):", err)
|
||||
} else {
|
||||
fmt.Println("Base URI path set successfully ------>>设置访问路径成功")
|
||||
}
|
||||
}
|
||||
|
||||
if resetTwoFactor {
|
||||
err := settingService.SetTwoFactorEnable(false)
|
||||
|
||||
if err != nil {
|
||||
fmt.Println("Failed to reset two-factor authentication(设置两步验证失败):", err)
|
||||
} else {
|
||||
settingService.SetTwoFactorToken("")
|
||||
fmt.Println("Two-factor authentication reset successfully --------->>设置两步验证成功")
|
||||
}
|
||||
}
|
||||
|
||||
if listenIP != "" {
|
||||
err := settingService.SetListen(listenIP)
|
||||
if err != nil {
|
||||
fmt.Println("Failed to set listen IP(设置监听IP失败):", err)
|
||||
} else {
|
||||
fmt.Printf("listen %v set successfully --------->>设置监听IP成功", listenIP)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func updateCert(publicKey string, privateKey string) {
|
||||
err := database.InitDB(config.GetDBPath())
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
if (privateKey != "" && publicKey != "") || (privateKey == "" && publicKey == "") {
|
||||
settingService := service.SettingService{}
|
||||
err = settingService.SetCertFile(publicKey)
|
||||
if err != nil {
|
||||
fmt.Println("set certificate public key failed(设置证书公钥失败):", err)
|
||||
} else {
|
||||
fmt.Println("set certificate public key success --------->>设置证书公钥成功")
|
||||
}
|
||||
|
||||
err = settingService.SetKeyFile(privateKey)
|
||||
if err != nil {
|
||||
fmt.Println("set certificate private key failed(设置证书私钥失败):", err)
|
||||
} else {
|
||||
fmt.Println("set certificate private key success --------->>设置证书私钥成功")
|
||||
}
|
||||
} else {
|
||||
fmt.Println("both public and private key should be entered ------>>必须同时输入证书公钥和私钥")
|
||||
}
|
||||
}
|
||||
|
||||
func GetCertificate(getCert bool) {
|
||||
if getCert {
|
||||
settingService := service.SettingService{}
|
||||
certFile, err := settingService.GetCertFile()
|
||||
if err != nil {
|
||||
fmt.Println("get cert file failed, error info:", err)
|
||||
}
|
||||
keyFile, err := settingService.GetKeyFile()
|
||||
if err != nil {
|
||||
fmt.Println("get key file failed, error info:", err)
|
||||
}
|
||||
|
||||
fmt.Println("cert:", certFile)
|
||||
fmt.Println("key:", keyFile)
|
||||
}
|
||||
}
|
||||
|
||||
func GetListenIP(getListen bool) {
|
||||
if getListen {
|
||||
|
||||
settingService := service.SettingService{}
|
||||
ListenIP, err := settingService.GetListen()
|
||||
if err != nil {
|
||||
log.Printf("Failed to retrieve listen IP: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println("listenIP:", ListenIP)
|
||||
}
|
||||
}
|
||||
|
||||
func migrateDb() {
|
||||
inboundService := service.InboundService{}
|
||||
|
||||
err := database.InitDB(config.GetDBPath())
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Println("Start migrating database... ---->>开始迁移数据库...")
|
||||
inboundService.MigrateDB()
|
||||
fmt.Println("Migration done! ------------>>迁移完成!")
|
||||
}
|
||||
|
||||
func main() {
|
||||
if len(os.Args) < 2 {
|
||||
runWebServer()
|
||||
return
|
||||
}
|
||||
|
||||
var showVersion bool
|
||||
flag.BoolVar(&showVersion, "v", false, "show version")
|
||||
|
||||
runCmd := flag.NewFlagSet("run", flag.ExitOnError)
|
||||
|
||||
settingCmd := flag.NewFlagSet("setting", flag.ExitOnError)
|
||||
var port int
|
||||
var username string
|
||||
var password string
|
||||
var webBasePath string
|
||||
var listenIP string
|
||||
var getListen bool
|
||||
var webCertFile string
|
||||
var webKeyFile string
|
||||
var tgbottoken string
|
||||
var tgbotchatid string
|
||||
var enabletgbot bool
|
||||
var tgbotRuntime string
|
||||
var reset bool
|
||||
var show bool
|
||||
var getCert bool
|
||||
var resetTwoFactor bool
|
||||
settingCmd.BoolVar(&reset, "reset", false, "Reset all settings")
|
||||
settingCmd.BoolVar(&show, "show", false, "Display current settings")
|
||||
settingCmd.IntVar(&port, "port", 0, "Set panel port number")
|
||||
settingCmd.StringVar(&username, "username", "", "Set login username")
|
||||
settingCmd.StringVar(&password, "password", "", "Set login password")
|
||||
settingCmd.StringVar(&webBasePath, "webBasePath", "", "Set base path for Panel")
|
||||
settingCmd.StringVar(&listenIP, "listenIP", "", "set panel listenIP IP")
|
||||
settingCmd.BoolVar(&resetTwoFactor, "resetTwoFactor", false, "Reset two-factor authentication settings")
|
||||
settingCmd.BoolVar(&getListen, "getListen", false, "Display current panel listenIP IP")
|
||||
settingCmd.BoolVar(&getCert, "getCert", false, "Display current certificate settings")
|
||||
settingCmd.StringVar(&webCertFile, "webCert", "", "Set path to public key file for panel")
|
||||
settingCmd.StringVar(&webKeyFile, "webCertKey", "", "Set path to private key file for panel")
|
||||
settingCmd.StringVar(&tgbottoken, "tgbottoken", "", "Set token for Telegram bot")
|
||||
settingCmd.StringVar(&tgbotRuntime, "tgbotRuntime", "", "Set cron time for Telegram bot notifications")
|
||||
settingCmd.StringVar(&tgbotchatid, "tgbotchatid", "", "Set chat ID for Telegram bot notifications")
|
||||
settingCmd.BoolVar(&enabletgbot, "enabletgbot", false, "Enable notifications via Telegram bot")
|
||||
|
||||
oldUsage := flag.Usage
|
||||
flag.Usage = func() {
|
||||
oldUsage()
|
||||
fmt.Println()
|
||||
fmt.Println("Commands:")
|
||||
fmt.Println(" run run web panel")
|
||||
fmt.Println(" migrate migrate form other/old x-ui")
|
||||
fmt.Println(" setting set settings")
|
||||
}
|
||||
|
||||
flag.Parse()
|
||||
if showVersion {
|
||||
fmt.Println(config.GetVersion())
|
||||
return
|
||||
}
|
||||
|
||||
switch os.Args[1] {
|
||||
case "run":
|
||||
err := runCmd.Parse(os.Args[2:])
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
runWebServer()
|
||||
case "migrate":
|
||||
migrateDb()
|
||||
case "setting":
|
||||
err := settingCmd.Parse(os.Args[2:])
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
if reset {
|
||||
resetSetting()
|
||||
} else {
|
||||
updateSetting(port, username, password, webBasePath, listenIP, resetTwoFactor)
|
||||
}
|
||||
if show {
|
||||
showSetting(show)
|
||||
}
|
||||
if getListen {
|
||||
GetListenIP(getListen)
|
||||
}
|
||||
if getCert {
|
||||
GetCertificate(getCert)
|
||||
}
|
||||
if (tgbottoken != "") || (tgbotchatid != "") || (tgbotRuntime != "") {
|
||||
updateTgbotSetting(tgbottoken, tgbotchatid, tgbotRuntime)
|
||||
}
|
||||
if enabletgbot {
|
||||
updateTgbotEnableSts(enabletgbot)
|
||||
}
|
||||
case "cert":
|
||||
err := settingCmd.Parse(os.Args[2:])
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
if reset {
|
||||
updateCert("", "")
|
||||
} else {
|
||||
updateCert(webCertFile, webKeyFile)
|
||||
}
|
||||
default:
|
||||
fmt.Println("Invalid subcommands ----->>无效命令")
|
||||
fmt.Println()
|
||||
runCmd.Usage()
|
||||
fmt.Println()
|
||||
settingCmd.Usage()
|
||||
}
|
||||
}
|
||||
BIN
media/01-overview-dark.png
Normal file
|
After Width: | Height: | Size: 253 KiB |
BIN
media/01-overview-light.png
Normal file
|
After Width: | Height: | Size: 248 KiB |
BIN
media/02-inbounds-dark.png
Normal file
|
After Width: | Height: | Size: 240 KiB |
BIN
media/02-inbounds-light.png
Normal file
|
After Width: | Height: | Size: 240 KiB |
BIN
media/03-add-inbound-dark.png
Normal file
|
After Width: | Height: | Size: 44 KiB |
BIN
media/03-add-inbound-light.png
Normal file
|
After Width: | Height: | Size: 44 KiB |
BIN
media/04-add-client-dark.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
BIN
media/04-add-client-light.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
BIN
media/05-settings-dark.png
Normal file
|
After Width: | Height: | Size: 277 KiB |
BIN
media/05-settings-light.png
Normal file
|
After Width: | Height: | Size: 266 KiB |
BIN
media/06-configs-dark.png
Normal file
|
After Width: | Height: | Size: 202 KiB |
BIN
media/06-configs-light.png
Normal file
|
After Width: | Height: | Size: 206 KiB |
BIN
media/07-bot-dark.png
Normal file
|
After Width: | Height: | Size: 62 KiB |
BIN
media/07-bot-light.png
Normal file
|
After Width: | Height: | Size: 255 KiB |
BIN
media/1.png
Normal file
|
After Width: | Height: | Size: 187 KiB |
BIN
media/10.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
media/11.png
Normal file
|
After Width: | Height: | Size: 636 KiB |
BIN
media/12.png
Normal file
|
After Width: | Height: | Size: 990 KiB |
BIN
media/13.png
Normal file
|
After Width: | Height: | Size: 965 KiB |
BIN
media/14.png
Normal file
|
After Width: | Height: | Size: 94 KiB |
BIN
media/15.png
Normal file
|
After Width: | Height: | Size: 88 KiB |
BIN
media/16.png
Normal file
|
After Width: | Height: | Size: 122 KiB |
BIN
media/17.png
Normal file
|
After Width: | Height: | Size: 153 KiB |
BIN
media/18.png
Normal file
|
After Width: | Height: | Size: 101 KiB |
BIN
media/19.png
Normal file
|
After Width: | Height: | Size: 135 KiB |
BIN
media/2.png
Normal file
|
After Width: | Height: | Size: 254 KiB |
BIN
media/20.png
Normal file
|
After Width: | Height: | Size: 288 KiB |
BIN
media/21.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
media/22.png
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
media/23.png
Normal file
|
After Width: | Height: | Size: 85 KiB |
BIN
media/24.png
Normal file
|
After Width: | Height: | Size: 128 KiB |
BIN
media/25.png
Normal file
|
After Width: | Height: | Size: 404 KiB |
BIN
media/26.png
Normal file
|
After Width: | Height: | Size: 245 KiB |
BIN
media/27.png
Normal file
|
After Width: | Height: | Size: 385 KiB |
BIN
media/28.png
Normal file
|
After Width: | Height: | Size: 256 KiB |
BIN
media/29.png
Normal file
|
After Width: | Height: | Size: 221 KiB |
BIN
media/3.png
Normal file
|
After Width: | Height: | Size: 63 KiB |
BIN
media/30.png
Normal file
|
After Width: | Height: | Size: 722 KiB |
BIN
media/31.png
Normal file
|
After Width: | Height: | Size: 172 KiB |
BIN
media/32.png
Normal file
|
After Width: | Height: | Size: 261 KiB |
BIN
media/33.png
Normal file
|
After Width: | Height: | Size: 401 KiB |
BIN
media/34.png
Normal file
|
After Width: | Height: | Size: 304 KiB |
BIN
media/35.png
Normal file
|
After Width: | Height: | Size: 210 KiB |
BIN
media/36.png
Normal file
|
After Width: | Height: | Size: 375 KiB |
BIN
media/37.png
Normal file
|
After Width: | Height: | Size: 97 KiB |
BIN
media/38.png
Normal file
|
After Width: | Height: | Size: 163 KiB |
BIN
media/39.png
Normal file
|
After Width: | Height: | Size: 2.1 MiB |
BIN
media/3X-UI.png
Normal file
|
After Width: | Height: | Size: 223 KiB |
BIN
media/3x-ui-dark.png
Normal file
|
After Width: | Height: | Size: 226 KiB |
BIN
media/3x-ui-light.png
Normal file
|
After Width: | Height: | Size: 224 KiB |
BIN
media/4.png
Normal file
|
After Width: | Height: | Size: 92 KiB |
BIN
media/40.png
Normal file
|
After Width: | Height: | Size: 137 KiB |
BIN
media/41.png
Normal file
|
After Width: | Height: | Size: 150 KiB |
BIN
media/42.png
Normal file
|
After Width: | Height: | Size: 122 KiB |
BIN
media/43.png
Normal file
|
After Width: | Height: | Size: 139 KiB |
BIN
media/44.png
Normal file
|
After Width: | Height: | Size: 99 KiB |
BIN
media/45.png
Normal file
|
After Width: | Height: | Size: 85 KiB |
BIN
media/47.png
Normal file
|
After Width: | Height: | Size: 176 KiB |
BIN
media/48.png
Normal file
|
After Width: | Height: | Size: 112 KiB |
BIN
media/49.png
Normal file
|
After Width: | Height: | Size: 101 KiB |
BIN
media/5.png
Normal file
|
After Width: | Height: | Size: 346 KiB |
BIN
media/50.png
Normal file
|
After Width: | Height: | Size: 124 KiB |
BIN
media/51.png
Normal file
|
After Width: | Height: | Size: 127 KiB |
BIN
media/52.png
Normal file
|
After Width: | Height: | Size: 121 KiB |
BIN
media/53.png
Normal file
|
After Width: | Height: | Size: 104 KiB |
BIN
media/54.png
Normal file
|
After Width: | Height: | Size: 164 KiB |
BIN
media/55.png
Normal file
|
After Width: | Height: | Size: 111 KiB |
BIN
media/56.png
Normal file
|
After Width: | Height: | Size: 83 KiB |
BIN
media/57.png
Normal file
|
After Width: | Height: | Size: 48 KiB |