Merge branch 'XTLS:main' into main

This commit is contained in:
xqzr 2021-09-16 21:00:39 +08:00 committed by GitHub
commit 26029c5982
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
187 changed files with 12816 additions and 2635 deletions

View file

@ -11,6 +11,9 @@ jobs:
uses: actions/checkout@v2
with:
fetch-depth: 0
- uses: actions/setup-node@v2
with:
node-version: '16'
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
@ -22,6 +25,8 @@ jobs:
restore-keys: |
${{ runner.os }}-yarn-
- name: Install and Build
env:
XRAY_DOCS_USE_VITE: "true"
run: |
yarn install
yarn docs:build
@ -30,3 +35,15 @@ jobs:
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: docs/.vuepress/dist
- name: Build for Main Repository
env:
XRAY_DOCS_MAIN_REPO: "true"
run: |
yarn docs:build
- name: Deploy to main Repository
uses: peaceiris/actions-gh-pages@v3
with:
personal_token: ${{ secrets.ACTION_PERSONAL_TOKEN }}
publish_dir: docs/.vuepress/dist
external_repository: XTLS/XTLS.github.io
publish_branch: gh-pages-next

View file

@ -1,4 +1,5 @@
node_modules/
.vuepress/dist
.cache/
.temp/
dist/

View file

@ -1,18 +1,46 @@
import { defineUserConfig, DefaultThemeOptions } from "vuepress";
import { defineUserConfig } from "@vuepress/cli";
import type { DefaultThemeOptions } from "@vuepress/theme-default";
import * as sidebar from "./config/sidebar";
import * as navbar from "./config/navbar";
import * as path from "path";
const isProduction = process.env.NODE_ENV === "production";
const forMainRepo = process.env.XRAY_DOCS_MAIN_REPO === "true";
const useVite = process.env.XRAY_DOCS_USE_VITE === "true";
console.log("base:", forMainRepo ? "/" : "/Xray-docs-next/");
console.log(
"bundler:",
isProduction && !useVite ? "@vuepress/webpack" : "@vuepress/vite"
);
export default defineUserConfig<DefaultThemeOptions>({
theme: path.join(__dirname, "./theme"),
plugins: ["@vuepress/back-to-top", "vuepress-plugin-mermaidjs"],
base: "/Xray-docs-next/",
plugins: [
[
"@vuepress/plugin-search",
{
locales: {
"/": {
placeholder: "搜索",
},
},
},
],
["@vuepress/plugin-debug", !isProduction],
],
base: forMainRepo ? "/" : "/Xray-docs-next/",
locales: {
"/": {
lang: "zh-CN",
title: "Project X",
description: "Xray 官方文档",
},
"/en/": {
lang: "en-US",
title: "Project X",
description: "Official document of Xray",
},
},
themeConfig: {
smoothScroll: true,
@ -24,13 +52,19 @@ export default defineUserConfig<DefaultThemeOptions>({
enableToggle: true,
themePlugins: {
git: process.env.NODE_ENV === "production",
git: isProduction,
},
locales: {
"/": {
ToggleText: "切换主题",
repoLabel: "查看源码",
editLinkText: "帮助我们改善此页面!",
tip: "提示",
warning: "注意",
danger: "警告",
lastUpdatedText: "最近更改",
selectLanguageName: "简体中文",
selectLanguageText: "多语言",
selectLanguageAriaLabel: "多语言",
sidebar: {
"/config/": sidebar.getConfigSidebar(
"特性详解",
@ -60,6 +94,39 @@ export default defineUserConfig<DefaultThemeOptions>({
},
navbar: navbar.hans,
},
"/en/": {
repoLabel: "Source",
selectLanguageName: "English (WIP)",
// TODO: translation
sidebar: {
"/en/config/": sidebar.getConfigSidebar(
"特性详解",
"基础配置",
"入站代理",
"出站代理",
"底层传输",
"/en/config/"
),
"/en/document/level-0/": sidebar.getDocumentLv0Sidebar(
"小小白白话文",
"/en/document/level-0/"
),
"/en/document/level-1/": sidebar.getDocumentLv1Sidebar(
"入门技巧",
"/en/document/level-1/"
),
"/en/document/level-2/": sidebar.getDocumentLv2Sidebar(
"进阶技巧",
"/en/document/level-2/"
),
"/en/development/": sidebar.getDevelopmentSidebar(
"开发指南",
"协议详解",
"/en/development/"
),
},
navbar: navbar.en,
},
},
},
head: [["link", { rel: "icon", href: `/logo.png` }]],
@ -71,17 +138,5 @@ export default defineUserConfig<DefaultThemeOptions>({
extendsMarkdown: (md) => {
md.use(require("markdown-it-footnote"));
},
bundlerConfig: {
chainWebpack: (config) => {
config.module
.rule("webp")
.test(/\.(webp)(\?.*)?$/)
.use("file-loader")
.loader("file-loader")
.options({
name: `assets/img/[name].[hash:8].[ext]`,
});
},
},
//postcss: { plugins: [require("autoprefixer")] }
bundler: isProduction && !useVite ? "@vuepress/webpack" : "@vuepress/vite",
});

View file

@ -1,4 +1,4 @@
import { NavbarConfig } from "@vuepress/theme-default/lib/types/nav";
import { NavbarConfig } from "@vuepress/theme-default";
export const hans: NavbarConfig = [
{ text: "首页", link: "/" },
@ -6,12 +6,13 @@ export const hans: NavbarConfig = [
{ text: "配置指南", link: "/config/" },
{ text: "开发指南", link: "/development/" },
{ text: "使用指南", link: "/document/" },
{
text: "多语言",
ariaLabel: "Language Menu",
children: [
{ text: "简体中文", link: "/" },
{ text: "English", link: "/en" },
],
},
];
// TODO: translation
export const en: NavbarConfig = [
{ text: "首页", link: "/en" },
{ text: "大史记", link: "/en/about/news.md" },
{ text: "配置指南", link: "/en/config/" },
{ text: "开发指南", link: "/en/development/" },
{ text: "使用指南", link: "/en/document/" },
];

View file

@ -1,4 +1,4 @@
import { SidebarConfigArray } from "@vuepress/theme-default/lib/types/nav";
import { SidebarConfigArray } from "@vuepress/theme-default";
export function getConfigSidebar(
feature: string,
@ -11,20 +11,20 @@ export function getConfigSidebar(
return [
{
text: feature,
isGroup: true,
children: [
path + "features/vless.md",
path + "features/xtls.md",
path + "features/fallback.md",
path + "features/browser_dialer.md",
path + "features/env.md",
path + "features/multiple.md",
],
},
{
text: config,
isGroup: true,
children: [
path + "",
path + "log.md",
path + "api.md",
path + "dns.md",
path + "fakedns.md",
@ -39,7 +39,6 @@ export function getConfigSidebar(
},
{
text: inbound,
isGroup: true,
children: [
path + "inbounds/",
path + "inbounds/dokodemo.md",
@ -53,7 +52,6 @@ export function getConfigSidebar(
},
{
text: outbound,
isGroup: true,
children: [
path + "outbounds/",
path + "outbounds/blackhole.md",
@ -69,7 +67,6 @@ export function getConfigSidebar(
},
{
text: transport,
isGroup: true,
children: [
path + "transports/",
path + "transports/grpc.md",
@ -90,7 +87,6 @@ export function getDocumentLv0Sidebar(
return [
{
text: title,
isGroup: true,
children: [
path + "ch01-preface.md",
path + "ch02-preparation.md",
@ -113,7 +109,6 @@ export function getDocumentLv1Sidebar(
return [
{
text: title,
isGroup: true,
children: [
path + "fallbacks-lv1.md",
path + "routing-lv1-part1.md",
@ -132,7 +127,6 @@ export function getDocumentLv2Sidebar(
return [
{
text: title,
isGroup: true,
children: [
path + "transparent_proxy/transparent_proxy.md",
path + "tproxy.md",
@ -151,14 +145,12 @@ export function getDevelopmentSidebar(
return [
{
text: title,
isGroup: true,
children: [
path + "intro/compile.md",
path + "intro/design.md",
path + "intro/guide.md",
{
text: protocols,
isGroup: true,
children: [
path + "protocols/vless.md",
path + "protocols/vmess.md",

View file

@ -0,0 +1,70 @@
:root {
--c-brand: #407ce8;
--c-brand-light: #2e73ea;
--c-text-accent: #2e73ea;
--c-brand-lighter: rgba(46, 115, 234, 0.75);
--c-bg-light: rgba(95, 101, 106, 0.1);
--c-badge-tip: #44c98d;
--c-warning-text-accent: var(--c-text-accent);
--c-danger-text-accent: var(--c-text-accent);
--x-nav-text-hover: #0a51bd;
}
html.dark {
--c-bg: #262a31;
--c-bg-light: #31353e;
--c-bg-lighter: #3a4049;
--c-brand: #407ce8;
--c-brand-light: #2e73ea;
--c-brand-lighter: rgba(46, 115, 234, 0.8);
--c-warning-bg: rgba(185, 174, 119, 0.3);
--c-warning-text: #c0bebe;
--c-warning-text-accent: var(--c-text-accent);
--c-danger-title: #b40505;
--c-danger-bg: rgba(72, 56, 57, 0.4);
--c-danger-text: #c0bebe;
--c-danger-text-accent: var(--c-text-accent);
--c-bg-light: rgba(255, 255, 255, 0.1);
--x-nav-text-hover: #7ca6f2;
.badge.tip > a {
color: #305bac;
& > span > svg.icon.outbound {
color: #7d57b0;
}
}
}
.badge.tip > a {
color: #3c71c0;
& > span > svg.icon.outbound {
color: #ad74e1;
}
}
blockquote {
color: var(--c-text);
background-color: var(--c-bg-lighter);
border-left: 4px solid #17a2b8;
}
* {
scroll-behavior: smooth;
transition: background-color 0.1s ease;
@media screen and (prefers-reduced-motion: reduce) {
scroll-behavior: auto;
}
}
.meta-item.edit-link > a.meta-item-label {
color: var(--c-text-accent);
}
.sidebar {
scrollbar-color: var(--c-brand-lighter) var(--c-border);
}

View file

@ -1,3 +1 @@
# Xray-docs-next dark theme
Fork from https://github.com/tolking/vuepress-theme-default-prefers-color-scheme .
# Xray-docs-next theme

View file

@ -1,10 +1,10 @@
import { defineClientAppEnhance } from "@vuepress/client";
import Tab from "./components/Tab.vue";
import Tabs from "./components/Tabs.vue";
import "./styles/default/index.scss";
import Mermaid from "./components/Mermaid.vue";
export default defineClientAppEnhance(({ app, router, siteData }) => {
app.component("Tab", Tab);
app.component("Tabs", Tabs);
app.component("Mermaid", Mermaid);
});

View file

@ -0,0 +1,66 @@
<template>
<div v-html="payload.innerHtml"></div>
</template>
<script lang="ts">
import {
defineComponent,
onMounted,
nextTick,
toRef,
watch,
reactive,
} from "vue";
import { useDarkMode } from "@vuepress/theme-default/lib/client";
export default defineComponent({
name: "Mermaid",
props: {
identifier: String,
graph: String,
},
setup(props) {
const dark = useDarkMode();
const chartID = toRef(props, "identifier");
const rawGraph = toRef(props, "graph");
const html = reactive({ innerHtml: "" });
onMounted(() => {
nextTick(async function () {
const mermaid = await import("mermaid");
mermaid.default.initialize({
startOnLoad: false,
theme: dark.value ? "dark" : "default",
});
mermaid.default.render(
chartID.value,
decodeURI(rawGraph.value),
(svgCode, bindFunc) => {
html.innerHtml = svgCode;
}
);
});
});
watch(dark, async () => {
const mermaid = await import("mermaid");
mermaid.default.initialize({
startOnLoad: false,
theme: dark.value ? "dark" : "default",
});
mermaid.default.render(
chartID.value,
decodeURI(rawGraph.value),
(svgCode, bindFunc) => {
html.innerHtml = svgCode;
}
);
});
return {
tag: chartID,
payload: html,
};
},
});
</script>
<style scoped></style>

View file

@ -19,23 +19,23 @@ export default defineComponent({
},
},
data() {
let tag = this.title;
return {
tabID: "",
labelID: "",
tabID: tag,
};
},
beforeMount() {
let tag = "tab-" + Math.random().toString(36).substring(2);
this.tabID = tag;
this.labelID = tag + "-" + "label";
// Since Vue 3.0, we have no access to $children.
// So we need another approach to register our child components.
this.$parent.$data.children.push(this);
mounted() {
this.tabID = "tab-" + Math.random().toString(36).substring(2);
this.$parent.$data.children.push({ id: this.tabID, title: this.title });
},
computed: {
labelID(): String {
return this.tabID + "-label";
},
},
});
</script>
<style lang="scss" scoped>
@import "~bootstrap/scss/bootstrap";
@import "node_modules/bootstrap/scss/bootstrap";
</style>

View file

@ -4,9 +4,9 @@
<div :id="tag" class="nav nav-pills" role="tablist">
<button
v-for="tab of children"
:id="tab.labelID"
:aria-controls="tab.tabID"
:data-bs-target="'#' + tab.tabID"
:id="tab.id + '-label'"
:aria-controls="tab.id"
:data-bs-target="'#' + tab.id"
aria-selected="false"
class="nav-link"
data-bs-toggle="tab"
@ -41,9 +41,9 @@ export default defineComponent({
this.children = [];
},
mounted() {
this.$nextTick(function () {
const bootstrap = require("bootstrap");
let triggerEl = document.getElementById(this.children["0"].$data.labelID);
this.$nextTick(async function () {
const bootstrap = await import("bootstrap");
let triggerEl = document.getElementById(this.children["0"].id + "-label");
new bootstrap.Tab(triggerEl).show();
});
},
@ -59,9 +59,21 @@ export default defineComponent({
</script>
<style lang="scss" scoped>
@import "~bootstrap/scss/bootstrap";
@import "node_modules/bootstrap/scss/bootstrap";
button.nav-link {
color: var(--textColor);
color: var(--c-text-accent);
&:hover,
&:focus {
color: var(--x-nav-text-hover);
}
}
nav {
padding-bottom: 0.5rem;
border-bottom: 1px solid var(--c-border);
}
div.tab-content {
border-bottom: 1px solid var(--c-border);
}
</style>

View file

@ -1,49 +0,0 @@
<template>
<nav class="navbar-links toggle-bar">
<div class="navbar-links-item">
<a v-if="enable" class="nav-link" @click.prevent="toggleTheme">{{
text
}}</a>
</div>
</nav>
</template>
<script lang="ts">
import { defineComponent } from "vue";
import { useThemeLocaleData } from "@vuepress/plugin-theme-data/lib/client";
import { ToggleOptions } from "../types";
export default defineComponent({
data() {
return {
enable: false,
text: "",
};
},
mounted() {
const option = useThemeLocaleData<ToggleOptions>();
this.enable = option.value.enableToggle;
this.text = option.value.ToggleText;
},
methods: {
toggleTheme() {
const html = document.getElementsByTagName("html")[0];
let theme = html.getAttribute("theme");
if (theme == "light") {
html.setAttribute("theme", "dark");
} else if (theme == "dark") {
html.setAttribute("theme", "light");
} else {
html.setAttribute("theme", "light");
}
},
},
});
</script>
<style lang="scss" scoped>
.toggle-bar {
margin-left: 1.5rem;
}
</style>

View file

@ -1,14 +1,15 @@
import { path } from "@vuepress/utils";
import { Theme } from "@vuepress/core";
import { MermaidPlugin } from "./plugin/mermaidPlugin";
export const docsPlugin: Theme = (options, app) => {
return {
name: "xray-docs-theme",
extends: "@vuepress/theme-default",
layouts: {
Layout: path.resolve(__dirname, "layouts/Layout.vue"),
},
clientAppEnhanceFiles: path.resolve(__dirname, "clientAppEnhance.ts"),
extendsMarkdown: (md) => {
md.use(MermaidPlugin);
},
};
};

View file

@ -1,31 +0,0 @@
<template>
<ParentLayout>
<template v-slot:navbar-after>
<ThemeToggle />
</template>
</ParentLayout>
</template>
<script lang="ts">
import ParentLayout from "@vuepress/theme-default/lib/client/layouts/Layout.vue";
import ThemeToggle from "../components/ThemeToggle.vue";
import { defineComponent } from "vue";
export default defineComponent({
components: {
ParentLayout,
ThemeToggle,
},
beforeMount() {
function setTheme(newTheme) {
const html = document.getElementsByTagName("html")[0];
html.setAttribute("theme", newTheme);
}
var dark = window.matchMedia("(prefers-color-scheme: dark)");
dark.addEventListener("change", (e) => {
setTheme(e.matches ? "dark" : "light");
});
setTheme(dark.matches ? "dark" : "light");
},
});
</script>

View file

@ -0,0 +1,24 @@
// Reference: https://github.com/mermaid-js/mermaid
import { PluginSimple } from "markdown-it/lib";
import { hash } from "@vuepress/utils";
const MermaidPlugin: PluginSimple = function (md) {
const fence = md.renderer.rules.fence;
md.renderer.rules.fence = (...args) => {
const [tokens, idx] = args;
const { info } = tokens[idx];
if (info.trim() === "mermaid") {
const token = tokens[idx];
const key = `mermaid_${hash(idx)}`;
let { content } = token;
return `<Mermaid identifier="${key}" graph="${encodeURI(
content
)}"></Mermaid>`;
}
const rawCode = fence(...args);
return `${rawCode}`;
};
};
export { MermaidPlugin };

View file

@ -1,43 +0,0 @@
$accentLightColor: #2e73ea;
$textLightColor: #2c3e50;
$borderLightColor: #d3d5d9;
$codeBgLightColor: #282c34;
$arrowBgLightColor: #ccc;
$tipLightColor: #42b983;
$tipBackgroundLightColor: #eff2f7;
$warningLightColor: #e7c000;
$dangerLightColor: #cc0000;
$badgeTipLightColor: #5bdca2;
$badgeWarningLightColor: $warningLightColor;
$badgeDangerLightColor: $dangerLightColor;
$backgroundLightColor: #fff;
$kbdBackgroundLightColor: #eeeeee;
$kbdBorderLightColor: #ccc;
$tableBorderLightColor: #dfe2e5;
$tableBackgroundLightColor: #f6f8fa;
$metaItemLightColor: #767676;
$dangerBgLightColor: #ffe6e6;
$warningBgLightColor: rgba(255, 229, 100, 0.3);
$miniCodeBgLightColor: rgba(95, 101, 106, 0.1);
$accentDarkColor: #407ce8;
$textDarkColor: #c0bebe;
$borderDarkColor: #4e4e4e;
$codeBgDarkColor: #282c34;
$arrowBgDarkColor: #ccc;
$tipDarkColor: #42b983;
$tipBackgroundDarkColor: #373a3f;
$warningDarkColor: #e7c000;
$dangerDarkColor: #cc0000;
$badgeTipDarkColor: #18411a;
$badgeWarningDarkColor: #e4be04;
$badgeDangerDarkColor: #b00606;
$backgroundDarkColor: #25272a;
$kbdBackgroundDarkColor: #3c3c3c;
$kbdBorderDarkColor: #666b6f;
$tableBorderDarkColor: #666b6f;
$tableBackgroundDarkColor: #5b5b5b;
$metaItemDarkColor: #626262;
$dangerBgDarkColor: rgba(72, 56, 57, 0.3);
$warningBgDarkColor: rgba(185, 174, 119, 0.3);
$miniCodeBgDarkColor: rgba(255, 255, 255, 0.1);

View file

@ -1,51 +0,0 @@
@import "_variables";
html,
body {
background-color: var(--backgroundColor);
}
body {
color: var(--textColor);
}
a {
color: var(--accentColor);
}
p a code {
color: var(--accentColor);
}
kbd {
background: var(--kbdBackgroundColor);
border: solid 0.15rem var(--kbdBorderColor);
border-bottom: solid 0.25rem var(--kbdBorderColor);
}
blockquote {
color: var(--textColor);
background-color: var(--kbdBackgroundColor);
border-left: 4px solid #17a2b8;
}
h2 {
border-bottom: 1px solid var(--borderColor);
}
hr {
border-top: 1px solid var(--borderColor);
}
tr {
border-top: 1px solid var(--tableBorderColor);
&:nth-child(2n) {
background-color: var(--tableBackgroundColor);
}
}
th,
td {
border: 1px solid var(--tableBorderColor);
}

View file

@ -1,66 +0,0 @@
@import "@vuepress/plugin-palette/palette";
@import "_color";
$MQMobile: 719px;
$contentClass: ".theme-default-content";
html[theme="dark"] {
--accentColor: #{$accentDarkColor};
--textColor: #{$textDarkColor};
--borderColor: #{$borderDarkColor};
--codeBgColor: #{$codeBgDarkColor};
--arrowBgColor: #{$arrowBgDarkColor};
--tipColor: #{$tipDarkColor};
--tipBackgroundColor: #{$tipBackgroundDarkColor};
--warningColor: #{$warningDarkColor};
--dangerColor: #{$dangerDarkColor};
--badgeTipColor: #{$badgeTipDarkColor};
--badgeWarningColor: #{$badgeWarningDarkColor};
--badgeDangerColor: #{$badgeDangerDarkColor};
--backgroundColor: #{$backgroundDarkColor};
--kbdBackgroundColor: #{$kbdBackgroundDarkColor};
--kbdBorderColor: #{$kbdBorderDarkColor};
--tableBorderColor: #{$tableBorderDarkColor};
--tableBackgroundColor: #{$tableBackgroundDarkColor};
--metaItemColor: #{$metaItemDarkColor};
--dangerBgDarkColor: #{$dangerBgDarkColor};
--warningBgDarkColor: #{$warningBgDarkColor};
--miniCodeBgColor: #{$miniCodeBgDarkColor};
--textColorLighten10: #{lighten($textDarkColor, 7%)};
--textColorLighten25: #{lighten($textDarkColor, 10%)};
--textColorLighten40: #{lighten($textDarkColor, 15%)};
--accentColorLighten8: #{lighten($accentDarkColor, 8%)};
--accentColorLighten10: #{lighten($accentDarkColor, 10%)};
--accentColorLighten30: #{lighten($accentDarkColor, 30%)};
}
html {
--accentColor: #{$accentLightColor};
--textColor: #{$textLightColor};
--borderColor: #{$borderLightColor};
--codeBgColor: #{$codeBgLightColor};
--arrowBgColor: #{$arrowBgLightColor};
--tipColor: #{$tipLightColor};
--tipBackgroundColor: #{$tipBackgroundLightColor};
--warningColor: #{$warningLightColor};
--dangerColor: #{$dangerLightColor};
--badgeTipColor: #{$badgeTipLightColor};
--badgeWarningColor: #{$badgeWarningLightColor};
--badgeDangerColor: #{$badgeDangerLightColor};
--backgroundColor: #{$backgroundLightColor};
--kbdBackgroundColor: #{$kbdBackgroundLightColor};
--kbdBorderColor: #{$kbdBorderLightColor};
--tableBorderColor: #{$tableBorderLightColor};
--tableBackgroundColor: #{$tableBackgroundLightColor};
--metaItemColor: #{$metaItemLightColor};
--dangerBgDarkColor: #{$dangerBgLightColor};
--warningBgDarkColor: #{$warningBgLightColor};
--miniCodeBgColor: #{$miniCodeBgLightColor};
--textColorLighten10: #{lighten($textLightColor, 10%)};
--textColorLighten25: #{lighten($textLightColor, 20%)};
--textColorLighten40: #{lighten($textLightColor, 30%)};
--accentColorLighten8: #{lighten($accentLightColor, 8%)};
--accentColorLighten10: #{lighten($accentLightColor, 12%)};
--accentColorLighten30: #{lighten($accentLightColor, 30%)};
}

View file

@ -1,27 +0,0 @@
@import "_variables";
.arrow {
&.up {
border: {
bottom: 6px solid var(--arrowBgColor);
}
}
&.down {
border: {
top: 6px solid var(--arrowBgColor);
}
}
&.right {
border: {
left: 6px solid var(--arrowBgColor);
}
}
&.left {
border: {
right: 6px solid var(--arrowBgColor);
}
}
}

View file

@ -1,17 +0,0 @@
@import "_variables";
.badge {
color: var(--backgroundColor);
background-color: var(--badgeTipColor);
&.tip {
background-color: var(--badgeTipColor);
}
&.warning {
background-color: var(--badgeWarningColor);
}
&.danger {
background-color: var(--badgeDangerColor);
}
}

View file

@ -1,26 +0,0 @@
@use 'sass:color';
@import "_variables";
#{$contentClass} {
code {
color: var(--textColorLighten25);
background-color: var(--miniCodeBgColor);
}
}
#{$contentClass} {
pre {
background-color: var(--codeBgColor);
code {
color: var(--textColorLighten25);
background-color: transparent;
}
}
.line-number {
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
monospace;
}
}

View file

@ -1,42 +0,0 @@
@use 'sass:color';
@import "_variables";
.custom-container {
&.tip {
background-color: var(--tipBackgroundColor);
border-color: var(--tipColor);
}
&.warning {
background-color: var(--warningBgDarkColor);
border-color: var(--warningColor);
color: var(--textColor);
.custom-container-title {
color: var(--warningColor);
}
a {
color: var(--textColor);
}
}
&.danger {
background-color: var(--dangerBgDarkColor);
border-color: var(--dangerColor);
color: var(--textColor);
.custom-container-title {
color: var(--dangerColor);
}
a {
color: var(--textColor);
}
}
&.details {
background-color: var(--backgroundColor);
}
}

View file

@ -1,47 +0,0 @@
@import "_variables";
.dropdown-wrapper {
.dropdown-title {
color: var(--textColor);
}
.mobile-dropdown-title {
font-size inherit {
&:hover {
color: var(--accentColor);
}
}
}
.nav-dropdown {
.dropdown-item {
.dropdown-subtitle {
border-top: 1px solid var(--kbdBackgroundColor);
}
a {
&:hover {
color: var(--accentColor);
}
&.router-link-active {
color: var(--accentColor);
&::after {
border-left: 5px solid var(--accentColor);
}
}
}
}
}
}
@media (min-width: $MQMobile) {
.dropdown-wrapper {
.nav-dropdown {
background-color: var(--backgroundColor);
border: 1px solid var(--kbdBorderColor);
border-bottom-color: var(--kbdBorderColor);
}
}
}

View file

@ -1,51 +0,0 @@
@use 'sass:color';
@import "_variables";
.home {
.hero {
.description {
color: var(--textColorLighten40);
}
.action-button {
&.primary {
color: #fff;
background-color: var(--accentColor);
border-color: var(--accentColor);
&:hover {
background-color: var(--accentColorLighten8);
}
}
&.secondary {
color: var(--accentColor);
background-color: #fff;
border-color: var(--accentColor);
&:hover {
color: #fff;
background-color: var(--accentColorLighten8);
}
}
}
}
.features {
border-top: 1px solid var(--borderColor);
}
.feature {
h2 {
color: var(--textColorLighten10);
}
p {
color: var(--textColorLighten10);
}
}
.footer {
border-top: 1px solid var(--borderColor);
color: var(--textColorLighten10);
}
}

View file

@ -1,23 +0,0 @@
@use '_normalize';
@use 'arrow';
@use 'badge';
@use 'custom-container';
@use 'dropdown';
@use 'home';
@use 'layout';
@use 'navbar';
@use 'page';
@use 'plugins';
@use 'sidebar';
@use 'code';
@use '@vuepress/plugin-palette/style';
* {
scroll-behavior: smooth;
transition: background-color 0.1s ease;
@media screen and (prefers-reduced-motion: reduce) {
scroll-behavior: auto;
}
}

View file

@ -1,19 +0,0 @@
@import "_variables";
.navbar {
background-color: var(--backgroundColor);
border-bottom: 1px solid var(--borderColor);
}
.sidebar {
background-color: var(--backgroundColor);
border-right: 1px solid var(--borderColor);
scrollbar-color: var(--accentColorLighten8) var(--borderColor);
&::-webkit-scrollbar-track {
background-color: var(--borderColor);
}
&::-webkit-scrollbar-thumb {
background-color: var(--accentColorLighten8);
}
}

View file

@ -1,34 +0,0 @@
@use 'sass:color';
@import "_variables";
.navbar {
.site-name {
color: var(--textColor);
}
.navbar-links-wrapper {
background-color: var(--backgroundColor);
}
}
/**
* navbar-links
*/
.navbar-links {
a {
&:hover,
&.router-link-active {
color: var(--accentColor);
}
}
}
@media (min-width: $MQMobile) {
.navbar-links-item > a:not(.external) {
&:hover,
&.router-link-active {
border-bottom: 2px solid var(--accentColorLighten8);
}
}
}

View file

@ -1,21 +0,0 @@
@use 'sass:color';
@import "_variables";
.page-meta {
.meta-item {
.meta-item-label {
color: var(--textColorLighten25);
}
.meta-item-info {
color: var(--metaItemColor);
}
}
}
.page-nav {
.inner {
border-top: 1px solid var(--borderColor);
}
}

View file

@ -1,18 +0,0 @@
@use 'sass:color';
@import "_variables";
.back-to-top {
--back-to-top-color: #{var(--accentColor)};
--back-to-top-color-hover: #{var(--accentColorLighten30)};
}
#nprogress {
--nprogress-color: #{var(--accentColor)};
}
.DocSearch {
--docsearch-primary-color: #{var(--accentColor)};
--docsearch-highlight-color: var(--docsearch-primary-color);
--docsearch-searchbox-shadow: inset 0 0 0 2px var(--docsearch-primary-color);
}

View file

@ -1,27 +0,0 @@
@import "_variables";
.sidebar {
.navbar-links {
border-bottom: 1px solid var(--borderColor);
}
}
.sidebar-heading {
color: var(--textColor);
}
.sidebar-link {
color: var(--textColor);
}
a.sidebar-heading,
a.sidebar-link {
&.active {
color: var(--accentColor);
border-left-color: var(--accentColor);
}
&:hover {
color: var(--accentColor);
}
}

View file

@ -1 +0,0 @@
export * from "./toggle";

View file

@ -1,4 +0,0 @@
export interface ToggleOptions {
enableToggle?: boolean;
ToggleText?: string;
}

View file

@ -7,7 +7,9 @@ actions:
- text: 由此开始 →
link: /document/
type: primary
- text: 配置指南 →
link: /config/
type: secondary
features:
- title: 极速协议
details: 原创 VLESS 与 XTLS 协议摆脱冗余加密释放CPU算力

View file

@ -0,0 +1,37 @@
# Browser Dialer
<Badge text="BETA" type="warning"/> <Badge text="v1.4.1+" type="warning"/>
## Background
基于 [一年前的想法](https://github.com/v2ray/discussion/issues/754#issuecomment-647934994) ,利用原生 JS 实现了简洁的 WSS Browser Dialer达到了真实浏览器的 TLS 指纹、行为特征。
不过 WSS 仍存在 ALPN 明显的问题,所以下一步是浏览器转发 `HTTP/2`,`QUIC`
## Xray & JS
创造了一个非常简单、巧妙的通信机制:
- Xray 监听地址端口 A作为 HTTP 服务,浏览器访问 A加载网页中的 JS。
- JS 主动向 A 建立 WebSocket 连接成功后Xray 将连接发给 channel。
- 需要建立连接时Xray 从 channel 接收一个可用的连接,并发送目标 URL 和可选的 early data。
- JS 成功连接到目标后告知 Xray并继续用这个 conn 全双工双向转发数据,连接关闭行为同步。
- 连接使用后就会被关闭,但 JS 会确保始终有新空闲连接可用。
## Early data
根据浏览器的需求,对 early data 机制进行了如下调整:
- 服务端响应头会带有请求的 `Sec-WebSocket-Protocol`,这也初步混淆了 WSS 握手响应的长度特征。
- 用于浏览器的 early data 编码是 `base64.RawURLEncoding` 而不是 `StdEncoding`,服务端做了兼容。
- 此外,由于 [Xray-core#375](https://github.com/XTLS/Xray-core/pull/375) 推荐 `?ed=2048`,这个 PR 顺便将服务端一处 `MaxHeaderBytes` 扩至了 4096。 ~~(虽然好像不改也没问题)~~
## Configuration <Badge text="v1.4.1" type="warning"/>
这是一个探索的过程,目前两边都是 Xray-core v1.4.1 时的配置方式:
- 准备一份可用的 WSS 配置,注意 address 必须填域名,若需要指定 IP请配置 DNS 或系统 hosts。
- 若浏览器的流量也会经过 Xray-core务必将这个域名设为直连否则会造成流量回环。
- 设置环境变量指定要监听的地址端口,比如 `XRAY_BROWSER_DIALER = 127.0.0.1:8080`
- 先运行 Xray-core再用任意浏览器访问上面指定的地址端口还可以 `F12``Console``Network`
- 浏览器会限制 WebSocket 连接数,所以建议开启 `Mux.Cool`

View file

@ -38,7 +38,7 @@
支持填写 Unix domain socket格式为绝对路径形如 `"/dev/shm/domain.socket"`,可在开头加 `@` 代表 [abstract](https://www.man7.org/linux/man-pages/man7/unix.7.html)`@@` 则代表带 padding 的 abstract。
填写 Unix domain socket 时,`port``allocate` 将被忽略,协议目前可选 VLESS、VMess、Trojan传输方式可选 TCP、WebSocket、HTTP/2。
填写 Unix domain socket 时,`port``allocate` 将被忽略,协议目前可选 VLESS、VMess、Trojan传输方式可选 TCP、WebSocket、HTTP/2、gRPC
> `port`: number | "env:variable" | string
@ -93,7 +93,8 @@
{
"enabled": true,
"destOverride": ["http", "tls", "fakedns"],
"metadataOnly": false
"metadataOnly": false,
"domainsExcluded": []
}
```
@ -109,6 +110,14 @@
当启用时,将仅使用连接的元数据嗅探目标地址。此时,`http``tls` 将不能使用。
> `domainsExcluded`: [string] <Badge text="WIP" type="warning"/>
一个域名列表,如果流量探测结果在这个列表中时,将 **不会** 重置目标地址。
::: warning
目前,`domainsExcluded` 不支持类似路由中的域名匹配方式。此选项未来可能会改变,不保证跨版本兼容。
:::
### AllocateObject
```json

View file

@ -44,10 +44,10 @@ VLESS 是一个无状态的轻量传输协议,它分为入站和出站两部
注意这里是 decryption和 clients 同级。
decryption 和 vmess 协议的 encryption 的位置不同,是因为若套一层约定加密,服务端需要先解密才能知道是哪个用户。
> `fallbacks`: \[ [FallbackObject](../examples/fallback.md) \]
> `fallbacks`: \[ [FallbackObject](../features/fallback.md) \]
一个数组,包含一系列强大的回落分流配置(可选)。
fallbacks 的具体配置请点击 [FallbackObject](../examples/fallback.md#fallbacks-配置)
fallbacks 的具体配置请点击 [FallbackObject](../features/fallback.md#fallbacks-配置)
### ClientObject

View file

@ -86,7 +86,7 @@
}
```
> `network`: "tcp" | "kcp" | "ws" | "http" | "domainsocket" | "quic"
> `network`: "tcp" | "kcp" | "ws" | "http" | "domainsocket" | "quic" | "grpc"
连接的数据流所使用的传输方式类型,默认值为 `"tcp"`
@ -243,6 +243,7 @@ CipherSuites 用于配置受支持的密码套件列表, 每个套件名称之
```json
{
"ocspStapling": 3600,
"oneTimeLoading": false,
"usage": "encipherment",
"certificateFile": "/path/to/certificate.crt",
"keyFile": "/path/to/key.key",
@ -299,7 +300,14 @@ CipherSuites 用于配置受支持的密码套件列表, 每个套件名称之
> `ocspStapling`: number
ocspStapling 检查更新时间间隔。 单位:秒
OCSP 装订更新,与证书热重载的时间间隔。 单位:秒。默认值为 `3600`,即一小时。
> `oneTimeLoading`: true | false
仅加载一次。值为 `true` 时将关闭证书热重载功能与 ocspStapling 功能。
::: warning
当值为 `true` 时,将会关闭 OCSP 装订。
:::
> `usage`: "encipherment" | "verify" | "issue"

View file

@ -4,30 +4,30 @@
## 传输方式列表
> `tcpSettings`: [TcpObject](./tcp)
> `tcpSettings`: [TcpObject](./tcp.md)
针对 TCP 连接的配置。
> `wsSettings`: [WebSocketObject](./websocket)
> `wsSettings`: [WebSocketObject](./websocket.md)
针对 WebSocket 连接的配置。
> `dsSettings`: [DomainSocketObject](./domainsocket)
> `dsSettings`: [DomainSocketObject](./domainsocket.md)
针对 Domain Socket 连接的配置。
> `kcpSettings`: [KcpObject](./mkcp)
> `kcpSettings`: [KcpObject](./mkcp.md)
针对 mKCP 连接的配置。
> `httpSettings`: [HttpObject](./h2)
> `httpSettings`: [HttpObject](./h2.md)
针对 HTTP/2 连接的配置。
> `quicSettings`: [QuicObject](./quic)
> `quicSettings`: [QuicObject](./quic.md)
针对 QUIC 连接的配置。
> `grpcSettings`: [GRPCObject](./grpc)
> `grpcSettings`: [GRPCObject](./grpc.md)
针对 gRPC 连接的配置。

View file

@ -48,38 +48,6 @@ WebSocket 所使用的 HTTP 协议路径,默认值为 `"/"`。
默认值为空。
## Browser Dialer <Badge text="BETA" type="warning"/>
## Browser Dialer
### Background
[v2ray/discussion#754](https://github.com/v2ray/discussion/issues/754#issuecomment-647934994) 基于一年前的想法,原生 JS 实现了简洁的 WSS Browser Dialer真实浏览器的 TLS 指纹、行为特征。
不过 WSS 仍存在 ALPN 明显的问题,所以下一步是浏览器转发 HTTP/2、QUIC。
### Xray & JS
创造了一个非常简单、巧妙的通信机制:
- Xray 监听地址端口 A作为 HTTP 服务,浏览器访问 A加载网页中的 JS。
- JS 主动向 A 建立 WebSocket 连接成功后Xray 将连接发给 channel。
- 需要建立连接时Xray 从 channel 接收一个可用的连接,并发送目标 URL 和可选的 early data。
- JS 成功连接到目标后告知 Xray并继续用这个 conn 全双工双向转发数据,连接关闭行为同步。
- 连接使用后就会被关闭,但 JS 会确保始终有新空闲连接可用。
### Early data
根据浏览器的需求,对 early data 机制进行了如下调整:
- 服务端响应头会带有请求的 `Sec-WebSocket-Protocol`,这也初步混淆了 WSS 握手响应的长度特征。
- 用于浏览器的 early data 编码是 `base64.RawURLEncoding` 而不是 `StdEncoding`,服务端做了兼容。
- 此外,由于 [#375](https://github.com/XTLS/Xray-core/pull/375) 推荐 `?ed=2048`,这个 PR 顺便将服务端一处 `MaxHeaderBytes` 扩至了 4096。 ~~(虽然好像不改也没问题)~~
### Configuration <Badge text="v1.4.1" type="warning"/>
这是一个探索的过程,目前两边都是 Xray-core v1.4.1 时的配置方式:
- 准备一份可用的 WSS 配置,注意 address 必须填域名,若需要指定 IP请配置 DNS 或系统 hosts。
- 若浏览器的流量也会经过 Xray-core务必将这个域名设为直连否则会造成流量回环。
- 设置环境变量指定要监听的地址端口,比如 `XRAY_BROWSER_DIALER = 127.0.0.1:8080`
- 先运行 Xray-core再用任一浏览器访问上面指定的地址端口还可以 `F12``Console``Network`
- 浏览器会限制 WebSocket 连接数,所以建议开启 `Mux.Cool`
使用浏览器处理 TLS详见 [Browser Dialer](../features/browser_dialer.md)

View file

@ -28,7 +28,7 @@ Xray 内核提供了一个平台,在其之上可以进二次开发。
Xray 用到了很多种协议, 您可以通过各种途径获得协议的详细描述。
### [mKCP 协议](./protocols/vless.md)
### [VLESS 协议](./protocols/vless.md)
VLESS 是一个无状态的轻量传输协议,可以作为 Xray 客户端和服务器之间的桥梁。

View file

@ -32,11 +32,11 @@
随着 GFW 技术这十几年来不断的迭代升级,若要完成【自己动手科学上网】这个目标,需要做的事情已经包括但不限于:
1. 了解Linux系统基本命令
2. 了解网络传输协议
3. 有技术和经济能力完成VPS购买及管理
4. 有技术和经济能力完成域名购买及管理
5. 有技术能力完成TLS证书申请 等等。
- 了解 Linux 系统基本命令
- 了解网络传输协议
- 有技术和经济能力完成 VPS 购买及管理
- 有技术和经济能力完成域名购买及管理
- 有技术能力完成 TLS 证书申请 等等。
这就让【自建 VPS 科学上网】这个曾经简单的行为逐渐变成了令新人望而生畏的挑战。

View file

@ -9,15 +9,15 @@
1. 在 VPS 的后台安装 Debian 10 64bit 系统
2. 小本本记下 VPS 的 IP 地址(本文会用 `"100.200.300.400"` 来表示)
::: tip
**注意:** 这是一个故意写错的非法 IP请替换成你的真实 IP
这是一个故意写错的非法 IP请替换成你的真实 IP
:::
3. 小本本记下 VPS 的 SSH 远程登陆端口(Port)
4. 小本本记下 SSH 远程登录的用户名和密码
购买 VPS 是一个比较复杂的事情,建议先去学习一下相关知识,选择适合自己的经济能力和线路需求的即可。另外可以选择薅一些国际大厂的羊毛(比如甲骨文和谷歌提供的永久免费或限时免费的套餐)。总之,务必量力而行。
::: tip
**说明:** 关于选择 Debian 10 作为操作系统,这里稍微多说一句:不管你在网上听说了什么,不管哪个大神告诉你 XXX 版的 Linux 更好、XXX 版的 Linux 更牛,这些 Linux 的派系之争**跟现在的你半毛钱关系也没有**!使用 Debian 10 足以让你的 VPS 服务器在安全、稳健运行的同时得到足够的优化(如 cloud 专用内核、及时的 bbr 支持等)。等你对 Linux 熟悉之后,再回头去尝试其他的 Linux 发行版也不迟
::: tip 说明
关于选择 Debian 10 作为操作系统,这里稍微多说一句:不管你在网上听说了什么,不管哪个大神告诉你 XXX 版的 Linux 更好、XXX 版的 Linux 更牛,这些 Linux 的派系之争**跟现在的你半毛钱关系也没有**!使用 Debian 10 足以让你的 VPS 服务器在安全、稳健运行的同时得到足够的优化(如 cloud 专用内核、及时的 bbr 支持等)。等你对 Linux 熟悉之后,再回头去尝试其他的 Linux 发行版也不迟
:::
## 2.2 获取一个心仪的域名
@ -30,7 +30,7 @@
![添加A记录](./ch02-img01-a-name.png)
::: tip
**注意:** 这**不是**一个真实可用的网址,请替换成你的真实网址
这**不是**一个真实可用的网址,请替换成你的真实网址
:::
## 2.3 你本地电脑上需要安装的软件

View file

@ -64,14 +64,14 @@
4. 现在请输入第一条命令,获取更新信息
```
# apt update
```shell
apt update
```
5. 然后请输入第二条命令,并在询问是否继续安装 `(Y/n)` 时输入 `y` 并回车确认,开始安装
```
# apt upgrade
```shell
apt upgrade
```
6. 完整流程演示如下:

View file

@ -63,8 +63,8 @@ Linux 服务器的安全防护是一个纷繁复杂的巨大课题。无数的
3. 我们要做的第一件事,当然就是【用`nano`这个文本编辑器打开`SSH远程登录程序设置`】,在 Windows 下,你会【找到文件并双击】,在 Linux 下该怎么办呢?仔细看看上面的命令说明,是不是就很简单了?没错,就是:
```
# nano /etc/ssh/sshd_config
```shell
nano /etc/ssh/sshd_config
```
4. 文件打开后,你就进入了`nano`的界面,稍微观察一下,你会发现,它把重要的快捷键都显示在屏幕下方了(下图红框内),直接开卷考试、不用死记硬背,是不是很贴心呢?
@ -78,7 +78,7 @@ Linux 服务器的安全防护是一个纷繁复杂的巨大课题。无数的
- 说明:如果这一行开头有个`#`,证明这一行【不生效】(被注释掉了),你可像我一样在文件最后写一个不带`#`的,或者把`#`删掉就好。
::: warning
注意 本文以`9753`为例,就意味着随着本文的发布,这个端口会变成一个不大不小的特征,也许会被攻击者优先尝试、也许被 GFW 干扰、阻断。所以我强烈建议你用一个自己想到的其他端口,毕竟,你有 6 万多个端口可以自由选择。
本文以`9753`为例,就意味着随着本文的发布,这个端口会变成一个不大不小的特征,也许会被攻击者优先尝试、也许被 GFW 干扰、阻断。所以我强烈建议你用一个自己想到的其他端口,毕竟,你有 6 万多个端口可以自由选择。
:::
6. 我们要做的第三件事,是【保存文件并退出】
@ -88,8 +88,8 @@ Linux 服务器的安全防护是一个纷繁复杂的巨大课题。无数的
7. 我们最后要做的事,是【重启 ssh 服务,使变更生效】
```
# systemctl restart ssh
```shell
systemctl restart ssh
```
8. 完整流程演示如下:
@ -116,47 +116,47 @@ Linux 服务器的安全防护是一个纷繁复杂的巨大课题。无数的
2. 我们要做的第一件事,是【新增一个用户并设定登录密码】,名字你可以随便起,我这里以`vpsadmin`为例:
```
# adduser vpsadmin
```shell
adduser vpsadmin
```
执行命令后,根据提示操作即可。请务必设置一个用户密码(别忘记设置密码时你时看不到 `******` 的)。之后系统会询问你一些用户的附加信息,这些就可以无视,一路回车即可。
![建立新用户](./ch04-img03-adduser.png)
::: warning 注意
本文以`vpsadmin`为例,就意味着随着本文的发布,这个用户名也会变成一个不大不小的特征,也许会被攻击者优先尝试。所以和端口一样,我强烈建议你用一个自己想到的其他用户名。
:::
::: warning
本文以`vpsadmin`为例,就意味着随着本文的发布,这个用户名也会变成一个不大不小的特征,也许会被攻击者优先尝试。所以和端口一样,我强烈建议你用一个自己想到的其他用户名。
:::
4. 完整流程演示如下:
3. 完整流程演示如下:
![建立新用户](./ch04-img04-adduser-full.gif)
5. 我们要做的第二件事,是【安装`sudo`功能】(`sudo` 就是在关键时刻,让普通账户临时获得 `root` 的神力,战力全开拯救世界)
4. 我们要做的第二件事,是【安装`sudo`功能】(`sudo` 就是在关键时刻,让普通账户临时获得 `root` 的神力,战力全开拯救世界)
```
# apt update && apt install sudo
```shell
apt update && apt install sudo
```
聪明的你大概已经发现,这一行命令其实是两个命令。前一半 `apt update` 你之前已经见过并且用过了,是去服务器刷新软件版本信息。后面的 `apt install`
就是这一次要用到的【安装命令】。两条连接在一起,就是让系统去【刷新可用的最新软件,然后安装最新版的`sudo`程序】。 `&&` 则是把两个命令连起来执行的意思。
6. 我们要做的第三件事,是【把`vpsadmin`用户加入`sudo`名单里,让他有资格借用`root`的神力】
5. 我们要做的第三件事,是【把`vpsadmin`用户加入`sudo`名单里,让他有资格借用`root`的神力】
```
# visudo
```shell
visudo
```
`User Privilege Specification` 下加入一行 `vpsadmin ALL=(ALL) NOPASSWD: ALL` 即可。
::: warning 注意 我要特别说明的是`NOPASSWD`这个设置,它的意思是`vpsadmin`用户临时使用`root`权限时,不用额外输入密码。**这与一般的安全建议相反**
。我之所以如此推荐,是因为很多新人不顾危险坚持使用`root`账号就是因为用`root`时不用重复输入密码、觉得轻松。“两害相权取其轻”,我认为【直接用`root`用户的风险】大于【使用`sudo`
::: warning
我要特别说明的是`NOPASSWD`这个设置,它的意思是`vpsadmin`用户临时使用`root`权限时,不用额外输入密码。**这与一般的安全建议相反**。我之所以如此推荐,是因为很多新人不顾危险坚持使用`root`账号就是因为用`root`时不用重复输入密码、觉得轻松。“两害相权取其轻”,我认为【直接用`root`用户的风险】大于【使用`sudo`
时不用输密码的风险】,所以做了以上的建议。
如果你希望遵守传统习惯、每次使用`sudo`时需要输入密码,那么这一行改成 `vpsadmin ALL=(ALL:ALL) ALL` 即可。
:::
7. 完整流程演示如下:
6. 完整流程演示如下:
![建立新用户](./ch04-img05-sudo-full.gif)
@ -164,8 +164,8 @@ Linux 服务器的安全防护是一个纷繁复杂的巨大课题。无数的
1. 现在你已经逐渐熟悉 Linux 了,所以这次换你思考,我们要做的第一件事是什么呢?没错,还是【用`nano`编辑器打开`SSH远程登录程序设置`】,什么,你想不起来怎么操作了?那去复习一下上面的内容再回来吧!............ 正确答案:
```
# nano /etc/ssh/sshd_config
```shell
nano /etc/ssh/sshd_config
```
2. 找到`PermitRootLogin Yes`这一项,然后把它后面的设定值改为`no`即可。还记得怎么操作吗?............ 正确答案:
@ -180,8 +180,8 @@ Linux 服务器的安全防护是一个纷繁复杂的巨大课题。无数的
4. 重启 ssh 服务,让变更生效。还记得............ 算了直接公布正确答案:
```
# systemctl restart ssh
```shell
systemctl restart ssh
```
5. 完整流程演示如下:
@ -202,7 +202,7 @@ Linux 服务器的安全防护是一个纷繁复杂的巨大课题。无数的
所谓的【密钥验证】,就是生成【一对】相关联的密钥文件(公钥和私钥),然后把【公钥】上传到 VPS 备用。每次登录时SSH 会将【公钥】和【私钥】进行匹配,若验证是正确的【密钥对】,则验证通过。(换言之,你无需记忆和输入复杂的密码,只要保护好【私钥】这个文件不外泄即可)
::: warning 注意
::: warning
本文以 `RSA` 密钥举例,是因为 `RSA` 密钥在各种设备、各种 `SSH` 客户端中有广泛悠久的支持历史,且目前依然能提供够用的安全性。但它绝非唯一选择。
其他的常见密钥还有:
@ -222,7 +222,7 @@ Linux 服务器的安全防护是一个纷繁复杂的巨大课题。无数的
![生成密钥](./ch04-img08-puttygen-save.png)
::: warning 注意
::: warning
本图中是以 `2048` 位的 `RSA` 密钥为例的。但实际上,如果要获得与 `EDCSA/Ed25519``256` 位密钥相同的安全性,你需要使用 `3072` 位的 `RSA` 密钥。(即右下角的数字改成 `3072`
:::
@ -278,14 +278,14 @@ Linux 服务器的安全防护是一个纷繁复杂的巨大课题。无数的
3. 修改 `authorized_keys` 文件权限为 `600` (仅所有者可读可写)
```
$ chmod 600 ~/.ssh/authorized_keys
```shell
chmod 600 ~/.ssh/authorized_keys
```
4. 修改 SSH 配置。这个我们已经用了很多次,但现在我们已经从无所不能的`root`变成了普通用户`vpsadmin`,此时的我们是没有权限直接编辑 SSH 配置的。这时候就需要使用`sudo`命令了:
```
$ sudo nano /etc/ssh/sshd_config
```shell
sudo nano /etc/ssh/sshd_config
```
5. 找到(`ctrl+w`) `PasswordAuthentication` 改成 `no`
@ -294,8 +294,8 @@ Linux 服务器的安全防护是一个纷繁复杂的巨大课题。无数的
7. 重启 SSH 服务。(啰嗦君:别忘了现在需要使用`sudo`来获得权限)
```
$ sudo systemctl restart ssh
```shell
sudo systemctl restart ssh
```
8. 完整流程如下:
@ -316,7 +316,7 @@ Linux 服务器的安全防护是一个纷繁复杂的巨大课题。无数的
![WinSCP指定私钥位置](./ch04-img20-winscp-privatekey-location.png)
::: warning 注意
::: warning
任何需要借助 SSH 进行登录的软件都需要密钥验证了,软件过多,无法逐一展示,请根据你的需要自行设置好哦
:::

View file

@ -20,8 +20,8 @@
1. 这里用到的,都是之前已经详解过的命令,所以就不重复讲解了。看不懂的同学可以看看前面的章节哦。
```
$ sudo apt update && sudo apt install nginx
```shell
sudo apt update && sudo apt install nginx
```
2. 完成后Nginx 已经自动运行。此时打开 Windows 上的浏览器并输入 `http://100.200.300.400:80`,若看到下图的界面就说明 Nginx 已经正常在运行了。
@ -42,11 +42,11 @@
| `conf-02` | `/etc/nginx/nginx.conf` | Nginx 程序设置 |
3. 创建一个网站专用的文件夹`/home/vpsadmin/www/webpage/`并建立网页文件`index.html`
```
$ mkdir -p ~/www/webpage/ && nano ~/www/webpage/index.html
```shell
mkdir -p ~/www/webpage/ && nano ~/www/webpage/index.html
```
::: warning 注意
::: warning
如果你用的不是 `vpsadmin` 这个用户名,请务必理解这条命令中 `“~”` 符号的意义(这关系到【第 5 步】你要写的内容):
- 如果是 【非 `root` 用户】,`“~”` 就等价于 `/home/用户名`
@ -55,35 +55,42 @@
4. 把下面的内容完整的复制进去,然后保存(`ctrl+o`)退出(`ctrl+x`)
```
<html>
<!-- Text between angle brackets is an HTML tag and is not displayed.
```html
<html lang="">
<!-- Text between angle brackets is an HTML tag and is not displayed.
Most tags, such as the HTML and /HTML tags that surround the contents of
a page, come in pairs; some tags, like HR, for a horizontal rule, stand
alone. Comments, such as the text you're reading, are not displayed when
the Web page is shown. The information between the HEAD and /HEAD tags is
not displayed. The information between the BODY and /BODY tags is displayed.-->
<head>
<title>Enter a title, displayed at the top of the window.</title>
</head>
<!-- The information between the BODY and /BODY tags is displayed.-->
<body>
<h1>Enter the main heading, usually the same as the title.</h1>
<p>Be <b>bold</b> in stating your key points. Put them in a list: </p>
<ul>
<li>The first item in your list</li>
<li>The second item; <i>italicize</i> key words</li>
</ul>
<p>Improve your image by including an image. </p>
<p><img src="https://i.imgur.com/SEBww.jpg" alt="A Great HTML Resource"></p>
<p>Add a link to your favorite <a href="https://www.dummies.com/">Web site</a>.
Break up your page with a horizontal rule or two.
</p>
<hr>
<p>Finally, link to <a href="page2.html">another page</a> in your own Web site.</p>
<!-- And add a copyright notice.-->
<p>&#169; Wiley Publishing, 2011</p>
</body>
<head>
<title>Enter a title, displayed at the top of the window.</title>
</head>
<!-- The information between the BODY and /BODY tags is displayed.-->
<body>
<h1>Enter the main heading, usually the same as the title.</h1>
<p>Be <b>bold</b> in stating your key points. Put them in a list:</p>
<ul>
<li>The first item in your list</li>
<li>The second item; <i>italicize</i> key words</li>
</ul>
<p>Improve your image by including an image.</p>
<p>
<img src="https://i.imgur.com/SEBww.jpg" alt="A Great HTML Resource" />
</p>
<p>
Add a link to your favorite
<a href="https://www.dummies.com/">Web site</a>. Break up your page
with a horizontal rule or two.
</p>
<hr />
<p>
Finally, link to <a href="page2.html">another page</a> in your own Web
site.
</p>
<!-- And add a copyright notice.-->
<p>&#169; Wiley Publishing, 2011</p>
</body>
</html>
```
@ -91,8 +98,8 @@
1. 修改 `nginx.conf`
```
$ sudo nano /etc/nginx/nginx.conf
```shell
sudo nano /etc/nginx/nginx.conf
```
2. 将下面一段,添加在 `http{}` 内,然后保存(`ctrl+o`)退出(`ctrl+x`)。(记得将域名替换为之前准备好的、包含二级域名的真实域名)
@ -112,8 +119,8 @@
3. 让 `nginx` 重新载入配置使其生效
```
$ sudo systemctl reload nginx
```shell
sudo systemctl reload nginx
```
4. 完整的设置流程如下:

View file

@ -4,7 +4,7 @@
接下来我们要做的,是为我们的域名申请一个真实的 TLS 证书,使网站具备标准 TLS 加密的能力及 HTTPS 访问的能力。这就是 Xray 等现阶段安全代理工具确保流量充分加密最重要的工具。
::: warning 注意
::: warning
请不要轻易使用自签证书。它并没有让操作简单太多,但增加了无谓的风险(如中间人攻击)。
:::
@ -22,20 +22,20 @@
2. 运行安装脚本
```
$ wget -O - https://get.acme.sh | sh
```shell
wget -O - https://get.acme.sh | sh
```
3. 让 `acme.sh` 命令生效
```
$ . .bashrc
```shell
. .bashrc
```
4. 开启 `acme.sh` 的自动升级
```
$ acme.sh --upgrade --auto-upgrade
```shell
acme.sh --upgrade --auto-upgrade
```
5. 到这一步的完整流程如下图:
@ -48,8 +48,8 @@
1. 测试证书申请的命令如下(本文均以 `ECC` 证书为例,因为时至今日,实在没什么理由不用它):
```
$ acme.sh --issue --test -d 二级域名.你的域名.com -w /home/vpsadmin/www/webpage --keylength ec-256
```shell
acme.sh --issue --test -d 二级域名.你的域名.com -w /home/vpsadmin/www/webpage --keylength ec-256
```
::: warning 说明
@ -117,8 +117,8 @@
4. 如果这一步出错的话,你可以运行下面的命令,来查看详细的申请过程和具体的错误。(看不懂就隐藏掉敏感信息后,去 Xray 群里问吧)
```
$ acme.sh --issue --test -d 二级域名.你的域名.com -w /home/vpsadmin/www/webpage --keylength ec-256 --debug
```shell
acme.sh --issue --test -d 二级域名.你的域名.com -w /home/vpsadmin/www/webpage --keylength ec-256 --debug
```
嗯没错,就是在命令的最后加了一个 `--debug` 参数
@ -129,8 +129,8 @@
1. 申请正式证书的命令如下(即删掉 `--test` 参数,并在最后加入 `--force`参数):
```
$ acme.sh --issue -d 二级域名.你的域名.com -w /home/vpsadmin/www/webpage --keylength ec-256 --force
```shell
acme.sh --issue -d 二级域名.你的域名.com -w /home/vpsadmin/www/webpage --keylength ec-256 --force
```
::: warning 说明

View file

@ -7,7 +7,6 @@
其实这样的结构是我多番思考之后的决定,毕竟只有打好基础,才能在后面事半功倍快速反超。我在群里看到许多新人连`nano`都无法正确使用,也不会用`WinSCP`,远程手写编辑出来的`config.json`自然错误百出,连查错也变得举步维艰。
::: warning
经过了前 6 章的准备,各位已经跟我一起翻越了 Linux 基本操作、VPS 远程管理、网页搭建、域名管理、证书申请等等几座大山。是不是回头看看,觉得其实非常简单呢?现在我们有了如此扎实的准备,接下来安装和配置 Xray
时会有一种【水到渠成】的轻快感觉。
:::
@ -29,30 +28,32 @@
写本文时,安装脚本在使用非 root 账户时有一些小 bug所以我决定正好把这几步分开操作可以顺便说明一下 Linux 下的删除命令。
1. 小小白白 Linux 基础命令: | 编号 | 命令名称 | 命令说明 | |:--:|:--:|:--:| | `cmd-14` | `rm` | 删除命令 |
1. 小小白白 Linux 基础命令:
| 编号 | 命令名称 | 命令说明 |
| :------: | :------: | :------: |
| `cmd-14` | `rm` | 删除命令 |
2. 将安装脚本下载至本地:
```
$ wget https://github.com/XTLS/Xray-install/raw/main/install-release.sh
```shell
wget https://github.com/XTLS/Xray-install/raw/main/install-release.sh
```
3. 执行安装命令
```
$ sudo bash install-release.sh
```shell
sudo bash install-release.sh
```
4. 使用完成之后可以删除该脚本
```
$ rm ~/install-release.sh
```shell
rm ~/install-release.sh
```
::: warning 注意
使用 `rm` 命令删除文件的时候,默认其实就是删除现在所在的文件夹下的文件。但是,**我依然写了完整的路径** `~/install-release.sh`,这是我使用 `rm`
时的一个安全习惯、也是我把安装分成几步之后想强调一下的内容。如果你听过一些“程序员从删库到跑路”之类的段子,大概就知道为什么了。
::: warning
使用 `rm` 命令删除文件的时候,默认其实就是删除现在所在的文件夹下的文件。但是,**我依然写了完整的路径** `~/install-release.sh`,这是我使用 `rm` 时的一个安全习惯、也是我把安装分成几步之后想强调一下的内容。如果你听过一些“程序员从删库到跑路”之类的段子,大概就知道为什么了。
:::
5. 完整流程演示如下:
@ -67,22 +68,22 @@
1. 为了规避非 root 账户的各种潜在的权限困扰,我们在 vpsadmin 账户下建立一个证书文件夹
```
$ mkdir ~/xray_cert
```shell
mkdir ~/xray_cert
```
2. 使用`acme.sh``--install-cert`正确安装(拷贝)证书文件
```
$ acme.sh --install-cert -d 二级域名.你的域名.com --ecc \
```shell
acme.sh --install-cert -d 二级域名.你的域名.com --ecc \
--fullchain-file ~/xray_cert/xray.crt \
--key-file ~/xray_cert/xray.key
```
3. `xray.key`文件默认对其他用户不可读,所以需要赋予其可读性权限
```
$ chmod +r ~/xray_cert/xray.key
```shell
chmod +r ~/xray_cert/xray.key
```
4. 过程比较简单就不放动图了:
@ -91,17 +92,21 @@
5. `acme.sh` 会每 60 天检查一次证书并自动更新临期证书。但据我所知是它并不会自动将新证书安装给 `xray-core`,所以我们需要新增一个系统的自动周期任务来完成这一步。
1. 小小白白 Linux 基础命令: | 编号 | 命令名称 | 命令说明 | |:--:|:--:|:--:| | `cmd-15` | `crontab -e` | 编辑当前用户的定时任务 |
1. 小小白白 Linux 基础命令:
| 编号 | 命令名称 | 命令说明 |
| :------: | :----------: | :--------------------: |
| `cmd-15` | `crontab -e` | 编辑当前用户的定时任务 |
2. 建立一个脚本文件(`xray-cert-renew.sh`
```
$ nano ~/xray_cert/xray-cert-renew.sh
```shell
nano ~/xray_cert/xray-cert-renew.sh
```
3. 把下面的内容复制进去,记得替换你的真实域名,然后保存退出
```
```bash
#!/bin/bash
/home/vpsadmin/.acme.sh/acme.sh --install-cert -d a-name.yourdomain.com --ecc --fullchain-file /home/vpsadmin/xray_cert/xray.crt --key-file /home/vpsadmin/xray_cert/xray.key
@ -114,8 +119,7 @@
echo "Xray Restarted"
```
::: warning 注意
::: warning
经大家提醒,`acme.sh` 有一个 `reloadcmd` 命令,可以在证书更新时自动执行特定命令,那么就可以指定自动给 `Xray` 安装证书,但因为 `crontab` 是 Linux
系统中一个非常有用、非常常用的功能,所以本文保留 `crontab` 的方式来更新 `Xray` 证书。(对 `reloadcmd` 感兴趣的同学可以查看 `acme.sh`
的[官方文档](https://github.com/acmesh-official/acme.sh)
@ -127,14 +131,14 @@
4. 给这个文件增加【可执行】权限
```
$ chmod +x ~/xray_cert/xray-cert-renew.sh
chmod +x ~/xray_cert/xray-cert-renew.sh
```
5. 运行 `crontab -e`,添加一个自动任务【每月自动运行一次`xray-cert-renew.sh`】 (注意不要加`sudo`,因为我们增加的是`vpsadmin`
账户的自动任务。初次运行时会让你选择编辑器,当然是选择熟悉的`nano`啦!)
```
$ crontab -e
```shell
crontab -e
```
6. 把下面的内容增加在文件最后,保存退出即可。
@ -155,40 +159,43 @@
1. 生成一个合法的 `UUID` 并保存备用(`UUID`可以简单粗暴的理解为像指纹一样几乎不会重复的 ID
```
$ xray uuid
```shell
xray uuid
```
2. 建立日志文件及文件夹备用
1. 小小白白 Linux 基础命令: | 编号 | 命令名称 | 命令说明 | |:--:|:--:|:--:| | `cmd-16` | `touch` | 建立空白文件 |
1. 小小白白 Linux 基础命令:
| 编号 | 命令名称 | 命令说明 |
|:--:|:--:|:--:|
| `cmd-16` | `touch` | 建立空白文件 |
2. 在`vpsadmin`的文件夹内建立一个【日志专用文件夹】
```
$ mkdir ~/xray_log
```shell
mkdir ~/xray_log
```
3. 生成所需的两个日志文件(访问日志、错误日志)
```
$ touch ~/xray_log/access.log && touch ~/xray_log/error.log
```shell
touch ~/xray_log/access.log && touch ~/xray_log/error.log
```
::: warning 注意
::: warning
这个位置不是`Xray`标准的日志文件位置,放在这里是避免权限问题对新人的操作带来困扰。当你熟悉之后,建议回归默认位置: `/var/log/xray/access.log`
`/var/log/xray/error.log`
:::
4. 因为 Xray 默认是 nobody 用户使用,所以我们需要让其他用户也有“写”的权限(`*.log` 就是所有文件后缀是`log`的文件,此时`CLI`界面的效率优势就逐渐出现了)
```
$ chmod a+w ~/xray_log/*.log
```shell
chmod a+w ~/xray_log/*.log
```
3. 使用`nano`创建`Xray`的配置文件
```
$ sudo nano /usr/local/etc/xray/config.json
```shell
sudo nano /usr/local/etc/xray/config.json
```
4. 将下面的文件全部复制进去,并将之前生成的`UUID`填入第 61 行 `"id": "",` 之中。(填好之后的样子是 `"id": "uuiduuid-uuid-uuid-uuid-uuiduuiduuid"`
@ -304,17 +311,14 @@
1. 输入下面的命令,享受启动`Xray`的历史性时刻吧!!!
```
\$ sudo systemctl start xray
```shell
sudo systemctl start xray
```
2. 仅仅`start`我们并不能确定是否成功的开启了 Xray 的服务,要确定它的状态,就要用到下面的命令。
```
\$ sudo systemctl status xray
```shell
sudo systemctl status xray
```
@ -331,34 +335,26 @@
1. 若你需要暂时关闭 `Xray` 的服务,那就用`stop`命令
```
\$ sudo systemctl stop xray
```shell
sudo systemctl stop xray
```
2. 若你需要重启`Xray`的服务,那就用`restart`命令
```
\$ sudo systemctl restart xray
```shell
sudo systemctl restart xray
```
3. 若你需要禁用`Xray`的服务(电脑重启后禁止 Xray 自动运行),那就用`disable`命令
```
\$ sudo systemctl disable xray
```shell
sudo systemctl disable xray
```
4. 若你需要启用`Xray`的服务(电脑重启后确保 Xray 自动运行),那就用`enable`命令
```
\$ sudo systemctl enable xray
```shell
sudo systemctl enable xray
```
## 7.7 服务器优化之一:开启 BBR
@ -388,7 +384,7 @@
内核的稳定是一台服务器稳定运行的基石。**【BBR 测试版带来的细微性能差异绝对不值得更换不稳定的内核。】** 请选择你所在的 Linux 发行版所支持的最新内核,这样可以最大限度的保持服务器的长期稳定和兼容。
::: warning 注意
::: warning
所谓魔改`bbr`的【领先】是有非常强的时效性的。比如很多 `bbrplus` 脚本,因为几年来都没有更新,到现在还会把你的内核换成 `4.19`,要知道现在稳定如 Debian 已经是 `5.9`
的时代了,那么这个脚本放在 2018 年 1 月也许领先了一点,到 2018 年 10 月 4.19 正发布时就已经失去了意义,放在现在甚至可以说是完完全全的【降级】和【劣化】
:::
@ -414,10 +410,8 @@
1. 给 Debian 10 添加官方 `backports` 源,获取更新的软件库
```
\$ sudo nano /etc/apt/sources.list
```shell
sudo nano /etc/apt/sources.list
```
::: warning 说明
@ -434,8 +428,8 @@ deb http://deb.debian.org/debian buster-backports main
3. 刷新软件库并查询 Debian 官方的最新版内核并安装。请务必安装你的 VPS 对应的版本本文以比较常见的【amd64】为例
```
$ sudo apt update && sudo apt -t buster-backports install linux-image-amd64
```shell
sudo apt update && sudo apt -t buster-backports install linux-image-amd64
```
::: warning 注意
@ -451,8 +445,8 @@ $ sudo apt update && sudo apt -t buster-backports install linux-image-amd64
4. 修改 `kernel` 参数配置文件 `sysctl.conf` 并指定开启 `BBR`
```
$ sudo nano /etc/sysctl.conf
```shell
sudo nano /etc/sysctl.conf
```
::: warning 说明
@ -470,8 +464,8 @@ net.ipv4.tcp_congestion_control=bbr
6. 重启 VPS、使内核更新和`BBR`设置都生效
```
$ sudo reboot
```shell
sudo reboot
```
7. 完整流程演示如下:
@ -487,8 +481,8 @@ $ sudo reboot
如果你想确认 `BBR` 是否正确开启,可以使用下面的命令:
```
$ lsmod | grep bbr
```shell
lsmod | grep bbr
```
此时应该返回这样的结果:
@ -499,8 +493,8 @@ tcp_bbr
如果你想确认 `fq` 算法是否正确开启,可以使用下面的命令:
```
$ lsmod | grep fq
```shell
lsmod | grep fq
```
此时应该返回这样的结果:
@ -518,55 +512,43 @@ sch_fq
2. 编辑 Nginx 的配置文件
```
\$ sudo nano /etc/nginx/nginx.conf
```shell
sudo nano /etc/nginx/nginx.conf
```
3. 在我们设置过的 80 端口 Server 中加入下面的语句,并保存退出(可同时删除`root``index`两行)
```
return 301 https://$http_host$request_uri;
```
4. 在与 `80` 端口同级的位置增加一个本地端口监听来提供网页展示。本文以 `8080` 端口做演示。(可以是任意端口)
```
server {
listen 127.0.0.1:8080;
root /home/vpsadmin/www/webpage;
index index.html;
add_header Strict-Transport-Security "max-age=63072000" always;
listen 127.0.0.1:8080;
root /home/vpsadmin/www/webpage;
index index.html;
add_header Strict-Transport-Security "max-age=63072000" always;
}
```
5. 重启 Nginx 服务
```
\$ sudo systemctl restart nginx
```shell
sudo systemctl restart nginx
```
6. 修改 Xray 的回落设置,将回落从 `80` 端口改为 `8080` 端口。(找到 `"dest": 80`, 并改成 `"dest": 8080`
```
\$ sudo nano /usr/local/etc/xray/config.json
```shell
sudo nano /usr/local/etc/xray/config.json
```
7. 重启 `Xray` 服务,即完成了设置
```
\$ sudo systemctl restart xray
```shell
sudo systemctl restart xray
```
8. 完整流程演示如下:

View file

@ -25,7 +25,7 @@
:::warning 注意
**注意:** 请务必记得,`Xray` 的路由配置非常灵活,上面的说明只是无限可能性中的一种。
请务必记得,`Xray` 的路由配置非常灵活,上面的说明只是无限可能性中的一种。
借助 `geosite.dat``geoip.dat` 这两个文件可以很灵活的从【域名】和【IP】这两个角度、不留死角的控制流量流出的方向。这比曾经单一笼统的 `GFWList` 强大很多很多,可以做到非常细致的微调:比如可以指定 Apple 域名直连或转发、指定亚马逊域名代理或转发,百度的域名屏蔽等等。。。)
@ -99,7 +99,7 @@
- 请将 `serverName` 替换成你的真实域名
- 各个配置模块的说明我都已经(很啰嗦的)放在对应的配置点上了
```
```json
// REFERENCE:
// https://github.com/XTLS/Xray-examples
// https://xtls.github.io/config/
@ -111,156 +111,138 @@
// ├─ 4_inbounds 入站设置 - 什么流量可以流入Xray
// └─ 5_outbounds 出站设置 - 流出Xray的流量往哪里去
{
// 1_日志设置
// 注意本例中我默认注释掉了日志文件因为windows, macOS, Linux 需要写不同的路径,请自行配置
"log": {
// "access": "/home/local/xray_log/access.log", // 访问记录
// "error": "/home/local/xray_log/error.log", // 错误记录
"loglevel": "warning" // 内容从少到多: "none", "error", "warning", "info", "debug"
// 1_日志设置
// 注意本例中我默认注释掉了日志文件因为windows, macOS, Linux 需要写不同的路径,请自行配置
"log": {
// "access": "/home/local/xray_log/access.log", // 访问记录
// "error": "/home/local/xray_log/error.log", // 错误记录
"loglevel": "warning" // 内容从少到多: "none", "error", "warning", "info", "debug"
},
// 2_DNS设置
"dns": {
"servers": [
// 2.1 国外域名使用国外DNS查询
{
"address": "1.1.1.1",
"domains": ["geosite:geolocation-!cn"]
},
// 2.2 国内域名使用国内DNS查询并期待返回国内的IP若不是国内IP则舍弃用下一个查询
{
"address": "223.5.5.5",
"domains": ["geosite:cn"],
"expectIPs": ["geoip:cn"]
},
// 2.3 作为2.2的备份,对国内网站进行二次查询
{
"address": "114.114.114.114",
"domains": ["geosite:cn"]
},
// 2.4 最后的备份上面全部失败时用本机DNS查询
"localhost"
]
},
// 3_分流设置
// 所谓分流,就是将符合否个条件的流量,用指定`tag`的出站协议去处理对应配置的5.x内容
"routing": {
"domainStrategy": "AsIs",
"rules": [
// 3.1 广告域名屏蔽
{
"type": "field",
"domain": ["geosite:category-ads-all"],
"outboundTag": "block"
},
// 3.2 国内域名直连
{
"type": "field",
"domain": ["geosite:cn"],
"outboundTag": "direct"
},
// 3.3 国内IP直连
{
"type": "field",
"ip": ["geoip:cn", "geoip:private"],
"outboundTag": "direct"
},
// 3.4 国外域名代理
{
"type": "field",
"domain": ["geosite:geolocation-!cn"],
"outboundTag": "proxy"
}
// 3.5 默认规则
// 在Xray中任何不符合上述路由规则的流量都会默认使用【第一个outbound5.1】的设置所以一定要把转发VPS的outbound放第一个
]
},
// 4_入站设置
"inbounds": [
// 4.1 一般都默认使用socks5协议作本地转发
{
"tag": "socks-in",
"protocol": "socks",
"listen": "127.0.0.1", // 这个是通过socks5协议做本地转发的地址
"port": 10800, // 这个是通过socks5协议做本地转发的端口
"settings": {
"udp": true
}
},
// 4.2 有少数APP不兼容socks协议需要用http协议做转发则可以用下面的端口
{
"tag": "http-in",
"protocol": "http",
"listen": "127.0.0.1", // 这个是通过http协议做本地转发的地址
"port": 10801 // 这个是通过http协议做本地转发的端口
}
],
// 2_DNS设置
"dns": {
"servers": [
// 2.1 国外域名使用国外DNS查询
{
"address": "1.1.1.1",
"domains": [
"geosite:geolocation-!cn"
]
},
// 2.2 国内域名使用国内DNS查询并期待返回国内的IP若不是国内IP则舍弃用下一个查询
{
"address": "223.5.5.5",
"domains": [
"geosite:cn"
],
"expectIPs": [
"geoip:cn"
]
},
// 2.3 作为2.2的备份,对国内网站进行二次查询
{
"address": "114.114.114.114",
"domains": [
"geosite:cn"
]
},
// 2.4 最后的备份上面全部失败时用本机DNS查询
"localhost"
]
},
// 3_分流设置
// 所谓分流,就是将符合否个条件的流量,用指定`tag`的出站协议去处理对应配置的5.x内容
"routing": {
"domainStrategy": "AsIs",
"rules": [
// 3.1 广告域名屏蔽
{
"type": "field",
"domain": [
"geosite:category-ads-all"
],
"outboundTag": "block"
},
// 3.2 国内域名直连
{
"type": "field",
"domain": [
"geosite:cn"
],
"outboundTag": "direct"
},
// 3.3 国内IP直连
{
"type": "field",
"ip": [
"geoip:cn",
"geoip:private"
],
"outboundTag": "direct"
},
// 3.4 国外域名代理
{
"type": "field",
"domain": [
"geosite:geolocation-!cn"
],
"outboundTag": "proxy"
}
// 3.5 默认规则
// 在Xray中任何不符合上述路由规则的流量都会默认使用【第一个outbound5.1】的设置所以一定要把转发VPS的outbound放第一个
]
},
// 4_入站设置
"inbounds": [
// 4.1 一般都默认使用socks5协议作本地转发
{
"tag": "socks-in",
"protocol": "socks",
"listen": "127.0.0.1", // 这个是通过socks5协议做本地转发的地址
"port": 10800, // 这个是通过socks5协议做本地转发的端口
"settings": {
"udp": true
}
},
// 4.2 有少数APP不兼容socks协议需要用http协议做转发则可以用下面的端口
{
"tag": "http-in",
"protocol": "http",
"listen": "127.0.0.1", // 这个是通过http协议做本地转发的地址
"port": 10801 // 这个是通过http协议做本地转发的端口
}
],
// 5_出站设置
"outbounds": [
// 5_出站设置
"outbounds": [
// 5.1 默认转发VPS
// 一定放在第一个在routing 3.5 里面已经说明了,这等于是默认规则,所有不符合任何规则的流量都走这个
{
"tag": "proxy",
"protocol": "vless",
"settings": {
"vnext": [
{
"address": "a-name.yourdomain.com", // 替换成你的真实域名
"port": 443,
"users": [
{
"id": "uuiduuid-uuid-uuid-uuid-uuiduuiduuid", // 和服务器端的一致
"flow": "xtls-rprx-direct", // Windows, macOS 同学保持这个不变
// "flow": "xtls-rprx-splice", // Linux和安卓同学请改成Splice性能更强
"encryption": "none",
"level": 0
}
]
}
]
},
"streamSettings": {
"network": "tcp",
"security": "xtls",
"xtlsSettings": {
"serverName": "a-name.yourdomain.com", // 替换成你的真实域名
"allowInsecure": false // 禁止不安全证书
}
}
},
// 5.2 用`freedom`协议直连出站即当routing中指定'direct'流出时,调用这个协议做处理
{
"tag": "direct",
"protocol": "freedom"
},
// 5.3 用`blackhole`协议屏蔽流量即当routing中指定'block'时,调用这个协议做处理
{
"tag": "block",
"protocol": "blackhole"
{
"tag": "proxy",
"protocol": "vless",
"settings": {
"vnext": [
{
"address": "a-name.yourdomain.com", // 替换成你的真实域名
"port": 443,
"users": [
{
"id": "uuiduuid-uuid-uuid-uuid-uuiduuiduuid", // 和服务器端的一致
"flow": "xtls-rprx-direct", // Windows, macOS 同学保持这个不变
// "flow": "xtls-rprx-splice", // Linux和安卓同学请改成Splice性能更强
"encryption": "none",
"level": 0
}
]
}
]
},
"streamSettings": {
"network": "tcp",
"security": "xtls",
"xtlsSettings": {
"serverName": "a-name.yourdomain.com", // 替换成你的真实域名
"allowInsecure": false // 禁止不安全证书
}
]
}
},
// 5.2 用`freedom`协议直连出站即当routing中指定'direct'流出时,调用这个协议做处理
{
"tag": "direct",
"protocol": "freedom"
},
// 5.3 用`blackhole`协议屏蔽流量即当routing中指定'block'时,调用这个协议做处理
{
"tag": "block",
"protocol": "blackhole"
}
]
}
```
@ -277,7 +259,7 @@
1. 在 Windows 下,假设你的 `Xray` 程序位置是 `C:\Xray-windows-64\xray.exe`,配置文件位置是`C:\Xray-windows-64\config.json`,那么正确的启动命令就是:
```
```shell
C:\Xray-windows-64\xray.exe -c C:\Xray-windows-64\config.json
```
@ -287,8 +269,8 @@
2. 相似的,在 Linux 和 macOS 下,假设你的 `Xray` 程序位置是 `/usr/local/bin/xray`,配置文件位置是`/usr/local/etc/xray/config.json`,那么正确的启动命令就是
```
$ /usr/local/bin/xray -c /usr/local/etc/xray/config.json
```shell
/usr/local/bin/xray -c /usr/local/etc/xray/config.json
```
:::tip 说明

View file

@ -6,27 +6,29 @@
如果你用了《小小白白话文》中的[Xray 配置](../level-0/ch07-xray-server.md#_7-4-配置xray),并完成了[HTTP 自动跳转 HTTPS 优化](../level-0/ch07-xray-server.md#_7-8-服务器优化之二-开启http自动跳转https),那么你已经有了基于 `VLESS` 协议的简易回落:
```
"inbounds": [
```json
{
"inbounds": [
{
"port": 443,
"protocol": "vless",
"settings": {
"clients": [
...
],
"decryption": "none",
"fallbacks": [
{
"dest": 8080 // 默认回落到防探测的代理
}
]
},
"streamSettings": {
...
}
"port": 443,
"protocol": "vless",
"settings": {
"clients": [
// ... ...
],
"decryption": "none",
"fallbacks": [
{
"dest": 8080 // 默认回落到防探测的代理
}
]
},
"streamSettings": {
// ... ...
}
}
]
]
}
```
这一段配置用人话要怎么解释呢?
@ -113,7 +115,7 @@
为什么又要再次认识回落呢? 因为,上面仅仅说清楚了基于“协议”的、抵抗【主动探测】的初版回落。
在 [rprx](https://github.com/rprx) 不断开发迭代 `VLESS` 协议及 `fallback` 功能的过程种,逐渐发现,回落完全可以更加灵活强大,只要在保证抵抗【主动探测】的前提下,充分利用数据首包中的信息,其实可以做到多元素、多层次的回落。(如 `path`, `alpn` 等)
在 [RPRX](https://github.com/rprx) 不断开发迭代 `VLESS` 协议及 `fallback` 功能的过程种,逐渐发现,回落完全可以更加灵活强大,只要在保证抵抗【主动探测】的前提下,充分利用数据首包中的信息,其实可以做到多元素、多层次的回落。(如 `path`, `alpn` 等)
基于这个开发理念,【回落】功能才逐渐成长为现在的完全体,即完成了 `纯伪装 --> ws分流 --> 多协议多特征分流` 的进化。最终版甚至完全替代了以前要用 Web 服务器、其他工具才能完成的分流的功能。且由于上述的【回落/分流】处理都在首包判断阶段以毫秒级的速度完成、不涉及任何数据操作,所以几乎没有任何过程损耗。
@ -133,58 +135,56 @@
### 5.1 首先,我将服务器端配置的 443 监听段摘抄如下:
```
```json
{
"port": 443,
"protocol": "vless",
"settings": {
"clients": [
{
"id": "", // 填写你的 UUID
"flow": "xtls-rprx-direct",
"level": 0,
"email": "love@example.com"
}
],
"decryption": "none",
"fallbacks": [
{
"dest": 1310, // 默认回落到 Xray 的 Trojan 协议
"xver": 1
},
{
"path": "/websocket", // 必须换成自定义的 PATH
"dest": 1234,
"xver": 1
},
{
"path": "/vmesstcp", // 必须换成自定义的 PATH
"dest": 2345,
"xver": 1
},
{
"path": "/vmessws", // 必须换成自定义的 PATH
"dest": 3456,
"xver": 1
}
]
},
"streamSettings": {
"network": "tcp",
"security": "xtls",
"xtlsSettings": {
"alpn": [
"http/1.1"
],
"certificates": [
{
"certificateFile": "/path/to/fullchain.crt", // 换成你的证书,绝对路径
"keyFile": "/path/to/private.key" // 换成你的私钥,绝对路径
}
]
"port": 443,
"protocol": "vless",
"settings": {
"clients": [
{
"id": "", // 填写你的 UUID
"flow": "xtls-rprx-direct",
"level": 0,
"email": "love@example.com"
}
],
"decryption": "none",
"fallbacks": [
{
"dest": 1310, // 默认回落到 Xray 的 Trojan 协议
"xver": 1
},
{
"path": "/websocket", // 必须换成自定义的 PATH
"dest": 1234,
"xver": 1
},
{
"path": "/vmesstcp", // 必须换成自定义的 PATH
"dest": 2345,
"xver": 1
},
{
"path": "/vmessws", // 必须换成自定义的 PATH
"dest": 3456,
"xver": 1
}
]
},
"streamSettings": {
"network": "tcp",
"security": "xtls",
"xtlsSettings": {
"alpn": ["http/1.1"],
"certificates": [
{
"certificateFile": "/path/to/fullchain.crt", // 换成你的证书,绝对路径
"keyFile": "/path/to/private.key" // 换成你的私钥,绝对路径
}
]
}
},
}
}
```
这一段配置用人话要怎么解释呢?
@ -230,33 +230,33 @@
1. 后续处理回落至 `1310` 端口的流量,按照下面的配置验证、处理:
```
```json
{
"port": 1310,
"listen": "127.0.0.1",
"protocol": "trojan",
"settings": {
"clients": [
{
"password": "", // 填写你的密码
"level": 0,
"email": "love@example.com"
}
],
"fallbacks": [
{
"dest": 80 // 或者回落到其它也防探测的代理
}
]
},
"streamSettings": {
"network": "tcp",
"security": "none",
"tcpSettings": {
"acceptProxyProtocol": true
}
"port": 1310,
"listen": "127.0.0.1",
"protocol": "trojan",
"settings": {
"clients": [
{
"password": "", // 填写你的密码
"level": 0,
"email": "love@example.com"
}
],
"fallbacks": [
{
"dest": 80 // 或者回落到其它也防探测的代理
}
]
},
"streamSettings": {
"network": "tcp",
"security": "none",
"tcpSettings": {
"acceptProxyProtocol": true
}
},
}
}
```
看,神奇的事情发生了, `trojan` 协议这里又出现了一个新的 `fallbacks`。前面已经说过,`xray` 中的 `trojan` 协议也具有完整的回落能力,所以,此时 `trojan` 协议可以再次做判断和回落(这也就是传说中的套娃回落了):
@ -266,94 +266,94 @@
2. 后续处理回落至 `1234` 端口的流量,仔细看!它其实是 `vless+ws`
```
```json
{
"port": 1234,
"listen": "127.0.0.1",
"protocol": "vless",
"settings": {
"clients": [
{
"id": "", // 填写你的 UUID
"level": 0,
"email": "love@example.com"
}
],
"decryption": "none"
},
"streamSettings": {
"network": "ws",
"security": "none",
"wsSettings": {
"acceptProxyProtocol": true, // 提醒:若你用 Nginx/Caddy 等反代 WS需要删掉这行
"path": "/websocket" // 必须换成自定义的 PATH需要和分流的一致
}
"port": 1234,
"listen": "127.0.0.1",
"protocol": "vless",
"settings": {
"clients": [
{
"id": "", // 填写你的 UUID
"level": 0,
"email": "love@example.com"
}
],
"decryption": "none"
},
"streamSettings": {
"network": "ws",
"security": "none",
"wsSettings": {
"acceptProxyProtocol": true, // 提醒:若你用 Nginx/Caddy 等反代 WS需要删掉这行
"path": "/websocket" // 必须换成自定义的 PATH需要和分流的一致
}
},
}
}
```
3. 后续处理回落至 `2345` 端口的流量,仔细看!它其实是 `vmess直连`
```
```json
{
"port": 2345,
"listen": "127.0.0.1",
"protocol": "vmess",
"settings": {
"clients": [
{
"id": "", // 填写你的 UUID
"level": 0,
"email": "love@example.com"
}
]
},
"streamSettings": {
"network": "tcp",
"security": "none",
"tcpSettings": {
"acceptProxyProtocol": true,
"header": {
"type": "http",
"request": {
"path": [
"/vmesstcp" // 必须换成自定义的 PATH需要和分流的一致
]
}
}
"port": 2345,
"listen": "127.0.0.1",
"protocol": "vmess",
"settings": {
"clients": [
{
"id": "", // 填写你的 UUID
"level": 0,
"email": "love@example.com"
}
]
},
"streamSettings": {
"network": "tcp",
"security": "none",
"tcpSettings": {
"acceptProxyProtocol": true,
"header": {
"type": "http",
"request": {
"path": [
"/vmesstcp" // 必须换成自定义的 PATH需要和分流的一致
]
}
}
}
},
}
}
```
4. 后续处理回落至 `3456` 端口的流量,再仔细看!它其实是是 `vmess+ws(+cdn)`
::: warning
**说明:** 你没看错,这就是 v2fly 曾经推荐组合之一,并可完整支持 `CDN`。现已加入完美回落套餐哦!
::: warning 说明
你没看错,这就是 v2fly 曾经推荐组合之一,并可完整支持 `CDN`。现已加入完美回落套餐哦!
:::
```
```json
{
"port": 3456,
"listen": "127.0.0.1",
"protocol": "vmess",
"settings": {
"clients": [
{
"id": "", // 填写你的 UUID
"level": 0,
"email": "love@example.com"
}
]
},
"streamSettings": {
"network": "ws",
"security": "none",
"wsSettings": {
"acceptProxyProtocol": true, // 提醒:若你用 Nginx/Caddy 等反代 WS需要删掉这行
"path": "/vmessws" // 必须换成自定义的 PATH需要和分流的一致
}
"port": 3456,
"listen": "127.0.0.1",
"protocol": "vmess",
"settings": {
"clients": [
{
"id": "", // 填写你的 UUID
"level": 0,
"email": "love@example.com"
}
]
},
"streamSettings": {
"network": "ws",
"security": "none",
"wsSettings": {
"acceptProxyProtocol": true, // 提醒:若你用 Nginx/Caddy 等反代 WS需要删掉这行
"path": "/vmessws" // 必须换成自定义的 PATH需要和分流的一致
}
}
}
```

View file

@ -1,3 +1,7 @@
---
title: SNI 回落
---
# 通过 SNI 回落功能实现伪装与按域名分流
VLESS 是一种很轻的协议,和 Trojan 一样,不对流量进行复杂的加密和混淆,而是大隐隐于市,通过 TLS 协议加密,混杂在其他 HTTPS 流量中在墙内外穿进穿出。为了更好的伪装以应对主动探测Fallbacks 回落功能随 VLESS 同时出现。这篇教程将演示如何使用 Xray 中 VLESS 入站协议的回落功能配合 Nginx 或 Caddy 在保证伪装完全的前提下实现按域名分流。
@ -189,23 +193,25 @@ acme.sh --install-cert -d example.com --fullchain-file /etc/ssl/xray/cert.pem --
如果使用 Caddy 就大可不必如此繁杂了,因为它**可以**在同一端口上同时监听 HTTP/1.1 和 h2c配置改动如下
```json
"fallbacks": [
{
"fallbacks": [
{
"name": "example.com",
"path": "/vmessws",
"dest": 5000,
"xver": 1
"name": "example.com",
"path": "/vmessws",
"dest": 5000,
"xver": 1
},
{
"dest": 5001,
"xver": 1
"dest": 5001,
"xver": 1
},
{
"name": "blog.example.com",
"dest": 5002,
"xver": 1
"name": "blog.example.com",
"dest": 5002,
"xver": 1
}
]
]
}
```
## Nginx 配置

View file

@ -51,18 +51,20 @@
下面的入站配置示例,用大白话说就是:数据按照 `socks` 协议,通过 `10808` 端口,从本机 `127.0.0.1` 流入`Xray`。同时,`Xray` 将这个入站用 `[tag]` 命名为 `inbound-10808`
```
"inbounds": [
```json
{
"inbounds": [
{
"tag": "inbound-10808",
"protocol": "socks",
"listen": "127.0.0.1",
"port": 10808,
"settings": {
"udp": true
}
"tag": "inbound-10808",
"protocol": "socks",
"listen": "127.0.0.1",
"port": 10808,
"settings": {
"udp": true
}
}
]
]
}
```
**2.2 出站**
@ -73,36 +75,38 @@
下面的出站配置示例,用大白话说就是:数据按照 `VLESS` 协议,以 `tcp + xtls (direct)` 的方式、及其他相关设置,把流量发送给对应的 VPS。同时`Xray` 将这个出站用 `[tag]` 命名为 `proxy-out-vless`
```
"outbounds": [
```json
{
"outbounds": [
{
"tag": "proxy-out-vless",
"protocol": "vless",
"settings": {
"vnext": [
{
"address": "a-name.yourdomain.com",
"port": 443,
"users": [
{
"id": "uuiduuid-uuid-uuid-uuid-uuiduuiduuid",
"flow": "xtls-rprx-direct",
"encryption": "none",
"level": 0
}
]
}
"tag": "proxy-out-vless",
"protocol": "vless",
"settings": {
"vnext": [
{
"address": "a-name.yourdomain.com",
"port": 443,
"users": [
{
"id": "uuiduuid-uuid-uuid-uuid-uuiduuiduuid",
"flow": "xtls-rprx-direct",
"encryption": "none",
"level": 0
}
]
},
"streamSettings": {
"network": "tcp",
"security": "xtls",
"xtlsSettings": {
"serverName": "a-name.yourdomain.com"
}
}
]
},
"streamSettings": {
"network": "tcp",
"security": "xtls",
"xtlsSettings": {
"serverName": "a-name.yourdomain.com"
}
}
}
]
]
}
```
### 2.3 路由
@ -113,18 +117,18 @@
下面的路由配置示例,用大白话说就是:把所有通过 `[tag]="inbound-10808"` 入站流入 `Xray` 的流量,`100%` 全部流转导入 `[tag]="proxy-out-vless"` 的出站,没有任何分流或其他操作。
```
"routing": {
```json
{
"routing": {
"domainStrategy": "AsIs",
"rules": [
{
"type": "field",
"inboundTag": [
"inbound-10808"
],
"outboundTag": "proxy-out-vless"
}
{
"type": "field",
"inboundTag": ["inbound-10808"],
"outboundTag": "proxy-out-vless"
}
]
}
}
```
@ -201,21 +205,23 @@
在上例的基础上,我们已经有了 `[proxy]` 的出站 `"proxy-out-vless"`,所以它保持不变。显而易见,我们需要加入两个新的出站方式:`[block]``[direct]`,如下:
```
"outbounds": [
```json
{
"outbounds": [
{
"tag": "proxy-out-vless",
......
"tag": "proxy-out-vless"
// ... ...
},
{
"tag": "block",
"protocol": "blackhole"
"tag": "block",
"protocol": "blackhole"
},
{
"tag": "direct-out",
"protocol": "freedom"
"tag": "direct-out",
"protocol": "freedom"
}
]
]
}
```
上面的配置用大白话翻译如下:
@ -228,32 +234,28 @@
接下来就是见证奇迹的时刻了,我们可以用【路由】的配置把这些连接起来!
```
"routing": {
```json
{
"routing": {
"domainStrategy": "AsIs",
"rules": [
{
"type": "field",
"domain": [
"geosite:category-ads-all"
],
"outboundTag": "block"
},
{
"type": "field",
"domain": [
"geosite:cn"
],
"outboundTag": "direct-out"
},
{
"type": "field",
"domain": [
"geosite:geolocation-!cn"
],
"outboundTag": "proxy-out-vless"
}
{
"type": "field",
"domain": ["geosite:category-ads-all"],
"outboundTag": "block"
},
{
"type": "field",
"domain": ["geosite:cn"],
"outboundTag": "direct-out"
},
{
"type": "field",
"domain": ["geosite:geolocation-!cn"],
"outboundTag": "proxy-out-vless"
}
]
}
}
```
@ -360,23 +362,25 @@
上一步我们已经配置出了 **【默认科学上网、国内网站白名单直连】** 的规则。那么现在只要 **【把直连规则放在第一位】**,就立即变成了正好相反的 **【默认直连、国外网站白名单科学上网】** 规则。
是不是,非常简单?
是不是,非常简单?
```
"outbounds": [
```json
{
"outbounds": [
{
"tag": "direct-out",
"protocol": "freedom"
"tag": "direct-out",
"protocol": "freedom"
},
{
"tag": "proxy-out-vless",
......
"tag": "proxy-out-vless"
// ... ...
},
{
"tag": "block",
"protocol": "blackhole"
"tag": "block",
"protocol": "blackhole"
}
]
]
}
```
此时,路由规则其实变成了:
@ -416,4 +420,4 @@
请确保你已经读懂了上面的内容,因为这样,你就已经理解了【路由】功能的工作逻辑。有了这个基础,我们就可以继续分析【路由】功能更多更详细的配置方式和匹配条件了。
等你看完后面的内容,就完全可以自由的定制属于自己的路由规则啦!还等什么,让我们一起进入 [《路由 (routing) 功能简析(下)》](./routing-lv1-part2) 吧!
等你看完后面的内容,就完全可以自由的定制属于自己的路由规则啦!还等什么,让我们一起进入 [《路由 (routing) 功能简析(下)》](./routing-lv1-part2.md) 吧!

View file

@ -2,7 +2,7 @@
欢迎继续学习 `Xray` 的【路由】功能!
在 [《路由 (routing) 功能简析(上)》](./routing-lv1-part1) 中,我们已经对【路由】功能的工作逻辑有了清晰的理解,也基于 `geosite.dat` 文件做了简单的域名分流配置。
在 [《路由 (routing) 功能简析(上)》](./routing-lv1-part1.md) 中,我们已经对【路由】功能的工作逻辑有了清晰的理解,也基于 `geosite.dat` 文件做了简单的域名分流配置。
如前面所说,域名分流仅仅是【路由】功能的牛刀小试而已。下面就让我们来看看除了域名之外,还什么可以用做分流依据的东西吧!
@ -50,35 +50,31 @@
上述配置如下:
```
"routing": {
```json
{
"routing": {
"domainStrategy": "AsIs",
"rules": [
// 指定子域名直连
{
"type": "field",
"domain": [
"full:direct.yourdomain.com"
],
"outboundTag": "direct-out"
},
// 指定子域名转发VPS
{
"type": "field",
"domain": [
"full:proxy.yourdomain.com"
],
"outboundTag": "proxy-out-vless"
},
// 指定泛域名转发VPS
{
"type": "field",
"domain": [
"yourdomain.com"
],
"outboundTag": "proxy-out-vless"
}
// 指定子域名直连
{
"type": "field",
"domain": ["full:direct.yourdomain.com"],
"outboundTag": "direct-out"
},
// 指定子域名转发VPS
{
"type": "field",
"domain": ["full:proxy.yourdomain.com"],
"outboundTag": "proxy-out-vless"
},
// 指定泛域名转发VPS
{
"type": "field",
"domain": ["yourdomain.com"],
"outboundTag": "proxy-out-vless"
}
]
}
}
```
@ -92,27 +88,25 @@
上述配置如下:
```
"routing": {
```json
{
"routing": {
"domainStrategy": "AsIs",
"rules": [
// 本机内部地址、局域网地址直连
{
"type": "field",
"ip": [
"geoip:private"
],
"outboundTag": "direct-out"
},
// 国内IP集直连
{
"type": "field",
"ip": [
"geoip:cn"
],
"outboundTag": "direct-out"
}
// 本机内部地址、局域网地址直连
{
"type": "field",
"ip": ["geoip:private"],
"outboundTag": "direct-out"
},
// 国内IP集直连
{
"type": "field",
"ip": ["geoip:cn"],
"outboundTag": "direct-out"
}
]
}
}
```
@ -125,27 +119,25 @@
上述配置如下:
```
"routing": {
```json
{
"routing": {
"domainStrategy": "AsIs",
"rules": [
// 指定IP地址直连
{
"type": "field",
"ip": [
"223.5.5.5"
],
"outboundTag": "direct-out"
},
// 指定IP地址转发VPS
{
"type": "field",
"ip": [
"1.1.1.1"
],
"outboundTag": "proxy-out-vless"
}
// 指定IP地址直连
{
"type": "field",
"ip": ["223.5.5.5"],
"outboundTag": "direct-out"
},
// 指定IP地址转发VPS
{
"type": "field",
"ip": ["1.1.1.1"],
"outboundTag": "proxy-out-vless"
}
]
}
}
```
@ -157,19 +149,19 @@
你需要打开入站代理中的 `sniffing` 才能使用此种方式分流。
:::
```
"routing": {
```json
{
"routing": {
"domainStrategy": "AsIs",
"rules": [
// 指定 BT 协议直连
{
"type": "field",
"protocol": [
"bittorrent"
],
"outboundTag": "direct-out"
}
// 指定 BT 协议直连
{
"type": "field",
"protocol": ["bittorrent"],
"outboundTag": "direct-out"
}
]
}
}
```
@ -205,69 +197,58 @@
`[1-block] --> [2-direct] --> [3-proxy] --> [4-first-outbound]`
:::
```
"routing": {
```json
{
"routing": {
"domainStrategy": "AsIs",
"rules": [
// [1-block 广告流量屏蔽]
// 1.1 广告域名集屏蔽
{
"type": "field",
"domain": [
"geosite:category-ads-all"
],
"outboundTag": "block"
},
// [2-direct 国内流量直连]
// 2.1 国内域名集、指定子域名直连
{
"type": "field",
"domain": [
"geosite:cn",
"full:direct.yourdomain.com"
],
"outboundTag": "direct-out"
},
// 2.2 本机内部地址+局域网、国内IP、指定IP直连
{
"type": "field",
"ip": [
"geoip:private",
"geoip:cn",
"223.5.5.5"
],
"outboundTag": "direct-out"
},
// 2.3 BT协议流量直连
{
"type": "field",
"protocol": [
"bittorrent"
],
"outboundTag": "direct-out"
},
// [3-proxy 国外流量转发VPS]
// 3.1 国外域名集、指定子域名、指定泛域名转发VPS
{
"type": "field",
"domain": [
"geosite:geolocation-!cn",
"full:proxy.yourdomain.com",
"yourdomain.com"
],
"outboundTag": "proxy-out-vless"
},
// 3.2 指定IP转发VPS
{
"type": "field",
"ip": [
"1.1.1.1"
],
"outboundTag": "proxy-out-vless"
}
// [4-default-routing 第一条出站]
// 没有匹配到任何规则的流量,默认使用第一条出站处理
// [1-block 广告流量屏蔽]
// 1.1 广告域名集屏蔽
{
"type": "field",
"domain": ["geosite:category-ads-all"],
"outboundTag": "block"
},
// [2-direct 国内流量直连]
// 2.1 国内域名集、指定子域名直连
{
"type": "field",
"domain": ["geosite:cn", "full:direct.yourdomain.com"],
"outboundTag": "direct-out"
},
// 2.2 本机内部地址+局域网、国内IP、指定IP直连
{
"type": "field",
"ip": ["geoip:private", "geoip:cn", "223.5.5.5"],
"outboundTag": "direct-out"
},
// 2.3 BT协议流量直连
{
"type": "field",
"protocol": ["bittorrent"],
"outboundTag": "direct-out"
},
// [3-proxy 国外流量转发VPS]
// 3.1 国外域名集、指定子域名、指定泛域名转发VPS
{
"type": "field",
"domain": [
"geosite:geolocation-!cn",
"full:proxy.yourdomain.com",
"yourdomain.com"
],
"outboundTag": "proxy-out-vless"
},
// 3.2 指定IP转发VPS
{
"type": "field",
"ip": ["1.1.1.1"],
"outboundTag": "proxy-out-vless"
}
// [4-default-routing 第一条出站]
// 没有匹配到任何规则的流量,默认使用第一条出站处理
]
}
}
```
@ -325,21 +306,19 @@
为了实现上面的目标,他写出了以下路由规则:
```
"routing": {
```json
{
"routing": {
"domainStrategy": "AsIs",
"rules": [
{
"type": "field",
"ip": [
"223.5.5.5"
],
"domain": [
"full:direct.yourdomain.com"
],
"outboundTag": "direct-out"
}
{
"type": "field",
"ip": ["223.5.5.5"],
"domain": ["full:direct.yourdomain.com"],
"outboundTag": "direct-out"
}
]
}
}
```
@ -357,25 +336,23 @@
正确示范,自然就是将不同的匹配依据独立出来:
```
"routing": {
```json
{
"routing": {
"domainStrategy": "AsIs",
"rules": [
{
"type": "field",
"ip": [
"223.5.5.5"
],
"outboundTag": "direct-out"
},
{
"type": "field",
"domain": [
"full:direct.yourdomain.com"
],
"outboundTag": "direct-out"
}
{
"type": "field",
"ip": ["223.5.5.5"],
"outboundTag": "direct-out"
},
{
"type": "field",
"domain": ["full:direct.yourdomain.com"],
"outboundTag": "direct-out"
}
]
}
}
```

View file

@ -87,7 +87,7 @@ iptables -t mangle -A OUTPUT -j XRAY_SELF
iptables -t mangle -A OUTPUT -m owner ! --gid-owner 23333 -j XRAY_SELF
```
3. 修改运行 Xray 的方式,使其运行在 uid 为 0gid 为 23333 的用户上,参考[这里](#3-配置最大文件开数运行xray客户端)。
3. 修改运行 Xray 的方式,使其运行在 uid 为 0gid 为 23333 的用户上,参考[这里](#3-配置最大文件开数运行xray客户端)。
## 下面提供一个实现 tproxy 全局代理的完整配置过程
@ -122,11 +122,11 @@ iptables -t mangle -A OUTPUT -m owner ! --gid-owner 23333 -j XRAY_SELF
}
```
### 3. 配置最大文件开数&运行 Xray 客户端
### 3. 配置最大文件开数&运行 Xray 客户端
关于最大文件开数问题见: **[too many open files 问题](https://guide.v2fly.org/app/tproxy.html#解决-too-many-open-files-问题)**
关于最大文件开数问题见: **[too many open files 问题](https://guide.v2fly.org/app/tproxy.html#解决-too-many-open-files-问题)**
目前 Xray 服务端使用官方脚本安装的已经自动配置了最大文件开数,无需再修改。
目前 Xray 服务端使用官方脚本安装的已经自动配置了最大文件开数,无需再修改。
**安卓系统**
@ -142,15 +142,22 @@ ulimit -SHn 1000000
sudo -u xray_tproxy "运行Xray的命令"&
```
例如:
```bash
ulimit -SHn 1000000
sudo -u xray_tproxy xray -c /etc/xray/config.json &
```
_第一条命令_
改变最大打开文件数,只对当前终端有效,每次启动 Xray 前都要运行,该命令是设置客户端的最大文件大开数
改变最大打开文件数,只对当前终端有效,每次启动 Xray 前都要运行,该命令是设置客户端的最大文件开数
_第二条命令_
以 uid 为 0gid 不为 0 的用户来运行 Xray 客户端,后面加&代表放在后台运行
**检查最大文件开数是否设置成功**
**检查最大文件开数是否设置成功**
```bash
cat /proc/Xray的pid/limits

View file

@ -28,7 +28,7 @@ title: 出站流量重定向
<Tabs title="if-config">
<Tab title="fwmark">
<Tab title="fwmark1">
```ini
[Interface]
@ -71,7 +71,7 @@ PostDown = ip -6 rule delete table main suppress_prefixlength 0
</Tab>
<Tab title="sendThrough">
<Tab title="sendThrough1">
```ini
[Interface]
@ -140,7 +140,7 @@ lsmod | grep wireguard
<Tabs title="xray-config">
<Tab title="fwmark">
<Tab title="fwmark2">
```json
{
@ -228,7 +228,7 @@ lsmod | grep wireguard
</Tab>
<Tab title="sendThrough">
<Tab title="sendThrough2">
```json
{

View file

@ -191,7 +191,7 @@ nftables 配置与 iptables 配置二选一,不可同时使用。
<Tabs title="netfilter">
<Tab title="nftables">
<Tab title="nftables1">
```nftables
#!/usr/sbin/nft -f
@ -231,15 +231,14 @@ table ip xray {
}
```
::: tip
**使用方法**
::: tip 使用方法
将上述配置写入一个文件(如 `nft.conf`),之后将该文件赋予可执行权限,最后使用 root 权限执行该文件即可(`# ./nft.conf`)。
:::
</Tab>
<Tab title="iptables">
<Tab title="iptables1">
```bash
iptables -t mangle -N XRAY
@ -286,9 +285,9 @@ iptables -t mangle -A OUTPUT -j XRAY_SELF
<br/>
<Tabs title="netfilter">
<Tabs title="netfilter2">
<Tab title="nftables">
<Tab title="nftables2">
首先将已经编辑好的 nftables 配置文件移动到 `/etc` 目录下,并重命名为 `nftables.conf`。然后编辑 `/lib/systemd/system/nftables.service`
@ -319,7 +318,7 @@ WantedBy=sysinit.target
</Tab>
<Tab title="iptables">
<Tab title="iptables2">
关于 iptables 的永久化,建议直接安装 `iptables-persistent`

101
docs/en/README.md Normal file
View file

@ -0,0 +1,101 @@
---
home: true
heroImage: /LogoX2.png
heroText: Project X
tagline: 不畏浮云遮望眼 · 金睛如炬耀苍穹
actions:
- text: 由此开始 →
link: /document/
type: primary
- text: 配置指南 →
link: /config/
type: secondary
features:
- title: 极速协议
details: 原创 VLESS 与 XTLS 协议摆脱冗余加密释放CPU算力
- title: 自由组合
details: |
完善的回落机制,有效防止主动探测,多服务共享端口
- title: 超低占用
details: |
OpenWRT RaspberryPi 等各种精简设备皆可使用
- title: 强大路由
details: |
高可定制化的路由系统,满足各类使用需求,充分发挥网络性能
- title: 完整兼容
details: |
完整兼容 v2ray-core 配置文件与 API 调用
- title: 亲和力
details: |
活跃的社区讨论及贡献MPL 2.0 开源许可协议
footer: Licensed under CC-BY-SA 4.0 | Copyright 2020-Present Project X Community
---
## XTLS ? Xray ? V2Ray ?
**XTLS are brilliant ideas for TLS we study, while Xray is the best practice we maintain.**
- Xray-core 是 v2ray-core 的超集,含更好的整体性能和 XTLS 等一系列增强,且完全兼容 v2ray-core 的功能及配置。
- 只有一个可执行文件,含 ctl 的功能run 为默认指令
- 配置上完全兼容,环境变量和 API 对应要改为以 XRAY\_ 开头
- 全平台开放了裸协议的 ReadV
- 提供完整的 VLESS & Trojan XTLS 支持,均有 ReadV
- 提供了 XTLS 多种流控模式, 性能一骑绝尘!
> “配置兼容,整体更好”
- Xray-flutter 是一个优雅的跨平台图形界面工具. <Badge text="WIP" type="warning"/>
### 我们是谁?
> **It doesn't matter who we are. What matters is that we will keep riding and not look back.**
### 帮助 Xray 变得更强
欢迎帮助 Xray 变得更强!
- 🖥️ 帮助开发和测试 Xray, 提交高质量的 Pull request.
- 📩 在 [GitHub Issues](https://github.com/XTLS/Xray-core/issues) 或 [讨论区](https://github.com/XTLS/Xray-core/discussions)发起建设性或有意义的 issue 与 discussion.
- 📝 写下您的使用心得并提交至 Xray 的 [文档网站](https://github.com/XTLS/XTLS.github.io).
- 💬 在 Telegram 群帮助群友/灌水.
- **...事实上,每一份对 Xray 的支持都会让 Xray 变得更强大**
### Telegram
- [Project X 交流群](https://t.me/projectXray)
- 交流群可在底线之上随便水,不要撕逼,没有滥权。
- 有问题尽管随便问,知道的尽量回答。
- 禁政治,禁 NSFW
- [Project X 频道](https://t.me/projectXtls)
- 发布 Project X 的最新资讯
### 致谢
- 感谢所有人的支持!
- 感谢各类脚本、Docker 镜像、客户端支持...感谢所有帮忙完善生态的大佬们!
- 感谢为 Xray 网站和文档添砖加瓦的朋友们.
- 感谢提出有意义的建议和意见的朋友们.
- 感谢 Telegram 群每一位帮助群友的朋友.
### 更多关于 project X
- 如果你想知道更多关于 project X 的理念与密闻, 请点击[这里](./faq/about/)
- 如果你想知道更多关于 project X 的足迹与成长, 请点击[这里](./about/news.md)
### License
[Mozilla Public License Version 2.0](https://github.com/XTLS/Xray-core/blob/main/LICENSE)
### Stargazers over time
> Project X 的 GitHub 主仓库 Xray-core 已获 2000 starsProject X 群人数近 3000频道订阅数 1000+
[![Stargazers over time](https://starchart.cc/XTLS/Xray-core.svg)](https://starchart.cc/XTLS/Xray-core)

240
docs/en/about/news.md Normal file
View file

@ -0,0 +1,240 @@
---
sidebar: auto
---
# 大史记
## 2021.4.6
- VuePress Next.
- With Dark Mode.
## 2021.4.4
- 本文档迎来的新的首页。
- 本文档迎来了暗黑模式。
- ~~当然,暗黑模式还有各种各样的问题。具体的内容还需要慢慢调整。~~
- 另Telegram 群聊突破了 5000 人!还加入了 Anti-Spam 机器人!
- 🎉🎉🎉
## 2021.4.1 <Badge>[v1.4.2](https://github.com/XTLS/Xray-core/releases/tag/v1.4.2)</Badge>
- 不是愚人节玩笑,今天更新。
- 加入 Browser Dialer用与改变 TLS 指纹与行为。
- 加入 uTLS用与改变 TLS Client Hello 的指纹。
- 顺便修复了一大堆奇妙的问题,具体的内容见更新日志。
## 2021.3.25
<!-- prettier-ignore -->
没错还在变。 -_-
## 2021.3.15
文档网站正在悄悄的进行着某些神秘的变化。。。,🙊🙊🙊
## 2021.3.14 <Badge>[v1.4.0](https://github.com/XTLS/Xray-core/releases/tag/v1.4.0)</Badge>
- Happy Pi-Day!
- 这次是个大更新:
- 为链式代理引入了传输层支持。
- 为 Dialer 引入了 Domain Strategy解决奇妙的 DNS 问题。
- 添加了 gRPC 传输方式,与更快一点的 Multi Mode。
- 添加了 WebSocket Early-Data 功能,减少了 WebSocket 的延迟。
- 添加了 FakeDNS。
- 还修复了系列的问题,添加了各类功能,详情请见更新日志。
- 还是 VuePress 比较爽啊(
## 2021.3.3 <Badge>[1.3.1](https://github.com/XTLS/Xray-core/releases/tag/v1.3.1)</Badge>
- 这个版本使用了 Golang 1.16,正式原生支持 Apple Silicon。
- 同时修复了一个会导致 Panic 的 bug。~~Holmium\_认为这是在骗、在偷袭。~~
- 修复了几个遗留问题。
## 2021.2.14 <Badge>[1.3.0](https://github.com/XTLS/Xray-core/releases/tag/v1.3.0)</Badge>
- Happy 🐮 Year 🎉!
- v1.3.0 通过非常巧妙的机制实现了 V 系协议全部 FullCone同时保证了一定的兼容性。
- OHHHHHHHHHHHH
## 2021.01.31 <Badge>[1.2.4](https://github.com/XTLS/Xray-core/releases/tag/v1.2.4)</Badge>
- 解决两个“连接至标准 Socks 服务端时可能出错”的历史遗留问题。
- 似乎这个版本没有什么改变,但这只是暴风雨前的宁静。
- (没错我就是先知)
> 你个傻子,你拿的是 UNO 牌。
## 2021.01.25
- 全互联网最好最详细的秘籍入门篇同学们练熟了吗? 🍉 老师开始连载[秘籍第一层](../document/level-1/)咯...
- [英文版文档网站](../en)逐渐增加内容 ing, 感谢各位大佬的辛苦付出~!
## 2021.01.22 <Badge>[1.2.3](https://github.com/XTLS/Xray-core/releases/tag/v1.2.3)</Badge>
- 对 SS 协议的支持**又**变强了, 支持单端口多用户!
- 对 trojan 协议的支持也**又**变强了, trojan 的回落也解锁 SNI 分流的新姿势啦~!
- _(VLESS: 嘤嘤嘤)_
- UDP 奇奇怪怪的 BUG 被干掉了, 一个字, "稳定".
- 嗅探可以排除你不想嗅探的域名, 可以开启一些新玩法.
- 向发现问题->开 issue->自行测试->自行分析->自行找到问题->自行解决->然后给上下游提交 PR 的大佬 <img src="https://avatars2.githubusercontent.com/u/8384161?s=32" width="32px" height="32px" alt="a"/> [@Bohan Yang](https://github.com/bohanyang) 致敬!
- 其他美味小樱桃, 惯例更新品尝就对啦.
## 2021.01.19
- 一些数字
- 版本发布了 10&nbsp;&nbsp; 个 tag
- 解决掉了 100&nbsp; 个 issue
- 复刻了 300&nbsp; 个 fork
- 点了 2000 个 star
- 群 3000 个 人
## 2021.01.17
- 辛苦的翻译工作开始了, 感谢<img src="https://avatars2.githubusercontent.com/u/60207794?s=32" width="32px" height="32px" alt="a"/> [@玖柒 Max](https://github.com/jiuqi9997)和其他所有的翻译大佬们.
- [English version](https://xtls.github.io/en/)
## 2021.01.15 <Badge>[1.2.2](https://github.com/XTLS/Xray-core/releases/tag/v1.2.2)</Badge>
- 回落分流又解锁了奇怪的新姿势! 回落中可以根据 SNI 分流啦~!
- 之前预告的 UUID 修改正式上线.([往下看往下看](#2021.01.12))
- 日志现在看起来比上一次顺眼又更顺眼了一丢丢.
- 远程 DOH 和其他的 DNS 模式一样学会了走路由分流.
- 当然还有其他各种小糖果.(更新品尝就对了)
- 啊, 还有, 世界上第一個 M1 上跑起 Xray 的男人是 Anthony TSE
## 2021.01.12
- 将要到来的 UUID 修改, 支持自定义字符串和 UUID 之间的映射. 这意味着你将可以这样在配置文件中写 id 来对应用户.
- 客户端写 "id": "我爱 🍉 老师 1314",
- 服务端写 "id": "5783a3e7-e373-51cd-8642-c83782b807c5" (此 UUID 是 `我爱🍉老师1314` 的 UUID 映射)
- 🍉 老师的[小小白白话文](../document/level-0/)大结局, 撒花.
## 2021.01.10 <Badge>[1.2.1](https://github.com/XTLS/Xray-core/releases/tag/v1.2.1)</Badge>
- [小小白白话文](../document/level-0/)连载上线啦,🍉 老师呕心沥血之作, 手把手教你从什么都不会到熟练配置 Xray!
- (可能是整个互联网上, 最详细最有耐心的教你从 0 开始配置的教程)
- [透明代理](../document/level-2/)也增加了更多文章.
- 还有很多细节修改, 文档将会越来越规范!
- 感谢 [@ricuhkaen](https://github.com/ricuhkaen) , [@BioniCosmos](https://github.com/BioniCosmos), [@kirin](https://github.com/kirin10000)
* 大量的 UDP 相关修复, 甚至可以在育碧的土豆服务器上玩彩虹六号!
* Google Voice 应该也可以正常使用 v2rayNG 拨打了.
* 日志现在看起来更顺眼.
## 2021.01.07
- 礼貌和尊重本应是社区不需要明说的准则之一。
## 2021.01.05
- 文档网站正在悄悄的进行着某些神秘的变化。。。,🙊🙊🙊
## 2021.01.03
- 文档仓库第一个 PR。🎉
[透明代理TProxy配置教程 ](../document/level-2/tproxy.md) ,感谢<img src="https://avatars2.githubusercontent.com/u/41363844?s=32" width="32px" height="32px" alt="a"/> [@BioniCosmos](https://github.com/BioniCosmos)
- tg 群突破 2500。
## 2021.01.01
【祝大家新年快乐,嗨皮牛耶!】🎆🎇🎆 <Badge>[1.2.0](https://github.com/XTLS/Xray-core/releases/tag/v1.2.0)</Badge>
🎁 在元旦的最后几分钟v1.2.0 它来了,带着周五必更的惯例,带着各位贡献大佬的心血以及 @rprxx 的黑眼圈,不负众望的来了!
- 圣诞礼物[v1.1.5](#20201225)后的元旦礼物 🎁,游戏玩家大福利,全面 FullCone。
- UDP 还会继续增强!)
- 如果你已经拆过圣诞礼物,这次还有比圣诞礼物更精美的包装和小糖果哦。(同样不用问,更新品尝就对了)
- (不,下面不是广告,是里程碑。)
- Xray 是有史以来第一个不受限制的多协议平台:只需 Xray 即可解决问题,无需借力其它实现。
- 一人扛起了所有!支持各大主流协议!
- 一骑绝尘的性能!
- 日趋完善的功能!
- 可怕的生命力与社区亲和力!
- Xray 将继续保持前行! 因此 [Xray 需要更多的英雄!!](https://github.com/XTLS/Xray-core/discussions/56)
- PS请品请细品[release notes](https://github.com/XTLS/Xray-core/releases/tag/v1.2.0)每一句。似乎有一个小秘密小彩蛋 ~~(啊,有人敲门...我一会和你们说)~~
## 2020.12.29
透明代理的游戏玩家利好! Xray-core tproxy 入站, socks 出站 UDP FullCone 测试版, [TG 群](https://t.me/projectXray)火热测试中
## 2020.12.25 <Badge>[1.1.5](https://github.com/XTLS/Xray-core/releases/tag/v1.1.5)</Badge>
圣诞节快乐!
- 游戏玩家的圣诞礼物!你可以用 xray 爽快的打游戏啦!因为有了 SS/trojan UDP fullcone
- 你可以用你喜欢的格式写配置文件了,比如 yaml比如 toml...
- VLESS 的 UDP fullcone 和更多增强很快就到!)
- 无须再担心证书验证被墙OCSP stapling 已经上线!
- kirin 带来了一大波 脚本更新.[脚本在此](https://github.com/XTLS/Xray-install)
- 还有更多美味小樱桃!(不用问,更新品尝就对了)
## 2020.12.24
因为某些不可描述的原因Xray 的文档网站已在发布日前偷跑上线。
网址为:[没错你正在看的就是](https://xtls.github.io)
大家可以查阅各种内容也欢迎纠错/提出建议(可发往文档 github 仓库的 issue 区)
文档网站需要不断完善和增加内容,以及完善设计。
因此更欢迎大家一起为文档建设添砖加瓦。
[文档的仓库](https://github.com/XTLS/XTLS.github.io)
仓库的 readme 中有简略教程说明如何帮助 xray 改进文档网站.
欢迎大家查看,纠错,修改,增加心得。
## 2020.12.23
Xray-core Shadowsocks UDP FullCone 测试版, [TG 群](https://t.me/projectXray)火热测试中
## 2020.12.21
- Project X 群人数 2000+
- 群消息(含游戏群) 日均破万
## 2020.12.18 <Badge>[1.1.4](https://github.com/XTLS/Xray-core/releases/tag/v1.1.4)</Badge>
- 更低的启动内占用和内存使用优化
- 随意定制的 TLS 提高你的 SSL 评级
- 支持 XTLS 入站的 Splice 以及支持 trojan 的 XTLS
- 还有在您路由器上使用的 Splice 最佳使用模式建议
## 2020.12.17
鉴于日益增长群人数和游戏需求, 开启了[TG 游戏群](https://t.me/joinchat/UO4NixbB_XDQJOUjS6mHEQ)
## 2020.12.15
[安装脚本 dev 分支](https://github.com/XTLS/Xray-install/tree/dev)开启, 持续更新功能中.
## 2020.12.11 <Badge>[1.1.3](https://github.com/XTLS/Xray-core/releases/tag/v1.1.3)</Badge>
- 完整版本的 REDIRECT 透明代理模式.
- 软路由 splice 流控模式的优化建议.
## 2020.12.06 <Badge>[1.1.2](https://github.com/XTLS/Xray-core/releases/tag/v1.1.2)</Badge>
- 流控增加 splice 模式, Linux 限定, 性能一骑绝尘.
- 增强了 API 兼容
## 2020.12.04
增加 splice 模式
## 2020.11.27
- Project X 的 GitHub 主仓库 Xray-core 已获 500+ stars
- 登上了 GitHub Trending
- Project X 群人数破千,频道订阅数 500+
## 2020.11.25 <Badge>[1.0.0](https://github.com/XTLS/Xray-core/releases/tag/v1.0.0)</Badge>
Xray 的第一个版本.
- 基于 v2ray-core 修改而来,改动较大
- 全面增强, 性能卓越, 完全兼容
## 2020.11.23
project X start
> ~~梦开始的时候~~

77
docs/en/config/README.md Normal file
View file

@ -0,0 +1,77 @@
---
title: 配置文件
lang: zh-CN
---
> **这个章节将告诉您所有的 Xray 配置细节,掌握这些内容,在您手中 Xray 将发挥更大威力。**
## 概述
Xray 的配置文件为 json 格式, 客户端和服务端的配置格式没有区别, 只是实际的配置内容不一样。
形式如下:
```json
{
"log": {},
"api": {},
"dns": {},
"routing": {},
"policy": {},
"inbounds": [],
"outbounds": [],
"transport": {},
"stats": {},
"reverse": {},
"fakedns": {}
}
```
::: warning
如果你刚接触 Xray, 您可以先点击查看[快速入门中的配置运行](../document/install.md), 学习最基本的配置方式, 然后查看本章节内容以掌握所有 Xray 的配置方式。
:::
## 基础配置模块
> log:[LogObject](./log.md)
日志配置,控制 Xray 输出日志的方式.
> api:[ApiObject](./api.md)
提供了一些 API 接口供远程调用。
> dns: [DnsObject](./dns.md)
内置的 DNS 服务器. 如果没有配置此项,则使用系统的 DNS 设置。
> routing: [RoutingObject](./routing.md)
路由功能。可以设置规则分流数据从不同的 outbound 发出.
> policy: [PolicyObject](./policy.md)
本地策略,可以设置不同的用户等级和对应的策略设置。
> inbounds: \[ [InboundObject](./inbound.md) \]
一个数组,每个元素是一个入站连接配置。
> outbounds: \[ [OutboundObject](./outbound.md) \]
一个数组,每个元素是一个出站连接配置。
> transport: [TransportObject](./transport.md)
用于配置 Xray 其它服务器建立和使用网络连接的方式。
> stats: [StatsObject](./stats.md)
用于配置流量数据的统计。
> reverse: [ReverseObject](./reverse.md)
反向代理。可以把服务器端的流量向客户端转发,即逆向流量转发。
> fakedns: [FakeDnsObject](./fakedns.md)
FakeDNS 配置。可配合透明代理使用,以获取实际域名。

90
docs/en/config/api.md Normal file
View file

@ -0,0 +1,90 @@
# API 接口
API 接口配置提供了一些基于 [gRPC](https://grpc.io/)的 API 接口供远程调用。
可以通过 api 配置模块开启接口. 当 api 配置开启时Xray 会自建一个出站代理,须手动将所有的 API 入站连接通过 [路由规则配置](./routing.md) 指向这一出站代理。
请参考本节中的 [相关配置](#相关配置)
::: warning
大多数用户并不会用到此 API新手可以直接忽略这一项。
:::
## ApiObject
`ApiObject` 对应配置文件的 `api` 项。
```json
{
"api": {
"tag": "api",
"services": ["HandlerService", "LoggerService", "StatsService"]
}
}
```
> `tag`: string
出站代理标识。
> `services`: \[string\]
开启的 API 列表,可选的值见 [API 列表](#支持的-api-列表)。
## 相关配置
可以在 inbounds 配置中增加一个 api 的 inbound
```json
"inbounds": [
{
"listen": "127.0.0.1",
"port": 10085,
"protocol": "dokodemo-door",
"settings": {
"address": "127.0.0.1"
},
"tag": "api"
}
]
```
在路由配置中增加针对 api inbound 的路由规则
```json
"routing": {
"settings": {
"rules": [
{
"inboundTag": [
"api"
],
"outboundTag": "api",
"type": "field"
}
]
},
"strategy": "rules"
}
```
## 支持的 API 列表
### HandlerService
一些对于入站出站代理进行修改的 API可用的功能如下
- 添加一个新的入站代理;
- 添加一个新的出站代理;
- 删除一个现有的入站代理;
- 删除一个现有的出站代理;
- 在一个入站代理中添加一个用户(仅支持 VMess、VLESS、Trojan、Shadowsocksv1.3.0+
- 在一个入站代理中删除一个用户(仅支持 VMess、VLESS、Trojan、Shadowsocksv1.3.0+
### LoggerService
支持对内置 Logger 的重启,可配合 logrotate 进行一些对日志文件的操作。
### StatsService
内置的数据统计服务,详见 [统计信息](./stats.md)。

151
docs/en/config/dns.md Normal file
View file

@ -0,0 +1,151 @@
# 内置 DNS 服务器
## DNS 服务器
Xray 内置的 DNS 模块,主要有两大用途:
- 在路由阶段, 解析域名为 IP, 并且根据域名解析得到的 IP 进行规则匹配以分流. 是否解析域名及分流和路由配置模块中 `domainStrategy` 的值有关, 只有在设置以下两种值时,才会使用内置 DNS 服务器进行 DNS 查询:
- "IPIfNonMatch", 请求一个域名时,进行路由里面的 domain 进行匹配,若无法匹配到结果,则对这个域名使用内置 DNS 服务器进行 DNS 查询,并且使用查询返回的 IP 地址再重新进行 IP 路由匹配。
- "IPOnDemand", 当匹配时碰到任何基于 IP 的规则,将域名立即解析为 IP 进行匹配。
- 解析目标地址进行连接。
- 如 在 `freedom` 出站中,将 `domainStrategy` 设置为 `UseIP`, 由此出站发出的请求, 会先将域名通过内置服务器解析成 IP, 然后进行连接。
- 如 在 `sockopt` 中,将 `domainStrategy` 设置为 `UseIP`, 此出站发起的系统连接,将先由内置服务器解析为 IP, 然后进行连接。
::: tip TIP 1
内置 DNS 服务器所发出的 DNS 查询请求,会自动根据路由配置进行转发。
:::
::: tip TIP 2
只支持最基本的 IP 查询A 和 AAAA 记录)。其他查询不会进入内置 DNS 服务器。
:::
## DNS 处理流程
DNS 服务器配置模块可以配置多个 DNS 服务器, 并且指定优先匹配列表.
1. 查询的域名与某个 DNS 服务器指定的域名列表匹配时Xray 会优先使用这个 DNS 服务器进行查询。
2. 无匹配时, 按从上往下的顺序进行查询,并且会跳过 1 步骤中使用的最后一个服务器。
3. 只返回匹配 expectIPs 的 IP 列表。
DNS 服务器的处理流程示意图如下:
![](./dns_flow.png?classes=border,shadow)
## DnsObject
`DnsObject` 对应配置文件的 `dns` 项。
```json
{
"dns": {
"hosts": {
"baidu.com": "127.0.0.1"
},
"servers": [
"8.8.8.8",
"8.8.4.4",
{
"address": "1.2.3.4",
"port": 5353,
"domains": ["domain:xray.com"],
"expectIPs": ["geoip:cn"]
},
"localhost"
],
"clientIp": "1.2.3.4",
"tag": "dns_inbound"
}
}
```
> `hosts`: map{string: address}
静态 IP 列表,其值为一系列的 "域名": "地址"。其中地址可以是 IP 或者域名。在解析域名时,如果域名匹配这个列表中的某一项:
- 当该项的地址为 IP 时,则解析结果为该项的 IP
- 当该项的地址为域名时,会使用此域名进行 IP 解析,而不使用原始域名。
域名的格式有以下几种形式:
- 纯字符串:当此字符串完整匹配目标域名时,该规则生效。例如 "xray.com" 匹配 "xray.com",但不匹配 "www.xray.com"。
- 正则表达式:由 `"regexp:"` 开始,余下部分是一个正则表达式。当此正则表达式匹配目标域名时,该规则生效。例如 "regexp:\\\\.goo.\*\\\\.com\$" 匹配 "www.google.com"、"fonts.googleapis.com",但不匹配 "google.com"。
- 子域名 (推荐):由 `"domain:"` 开始,余下部分是一个域名。当此域名是目标域名或其子域名时,该规则生效。例如 "domain:xray.com" 匹配 "www.xray.com" 与 "xray.com",但不匹配 "wxray.com"。
- 子串:由 `"keyword:"` 开始,余下部分是一个字符串。当此字符串匹配目标域名中任意部分,该规则生效。比如 "keyword:sina.com" 可以匹配 "sina.com"、"sina.com.cn" 和 "www.sina.com",但不匹配 "sina.cn"。
- 预定义域名列表:由 `"geosite:"` 开头,余下部分是一个名称,如 `geosite:google` 或者 `geosite:cn`。名称及域名列表参考 [预定义域名列表](./routing.md#预定义域名列表)。
> `servers`: \[string | [ServerObject](#serverobject) \]
一个 DNS 服务器列表支持的类型有两种DNS 地址(字符串形式)和 [ServerObject](#serverobject) 。
当它的值是一个 DNS IP 地址时,如 `"8.8.8.8"`Xray 会使用此地址的 53 端口进行 DNS 查询。
当值为 `"localhost"` 时,表示使用本机预设的 DNS 配置。
当值是 `"https://host:port/dns-query"` 的形式,如 `"https://dns.google/dns-query"`Xray 会使用 `DNS over HTTPS` (RFC8484, 简称 DOH) 进行查询。有些服务商拥有 IP 别名的证书,可以直接写 IP 形式,比如 `https://1.1.1.1/dns-query`。也可使用非标准端口和路径,如 `"https://a.b.c.d:8443/my-dns-query"`
当值是 `"https+local://host:port/dns-query"` 的形式,如 `"https+local://dns.google/dns-query"`Xray 会使用 `DOH本地模式` 进行查询,即 DOH 请求不会经过 Routing/Outbound 等组件,直接对外请求,以降低耗时。一般适合在服务端使用。也可使用非标端口和路径。
当值是 `fakedns` 时,将使用 FakeDNS 功能进行查询。
::: tip TIP 1
当使用 `localhost` 时,本机的 DNS 请求不受 Xray 控制,需要额外的配置才可以使 DNS 请求由 Xray 转发。
:::
::: tip TIP 2
不同规则初始化得到的 DNS 客户端会在 Xray 启动日志中以 `info` 级别体现,比如 `local DOH``remote DOH``udp` 等模式。
:::
::: tip TIP 3
(v1.4.0+) 可以在 [日志](./log.md) 中打开 DNS 查询日志。
:::
> `clientIp`: string
用于 DNS 查询时通知服务器以指定 IP 位置。不能是私有地址。
> `tag`: string
由内置 DNS 发出的查询流量,除 `localhost``DOHL_` 模式外,都可以用此标识在路由使用 `inboundTag` 进行匹配。
### ServerObject
```json
{
"address": "1.2.3.4",
"port": 5353,
"domains": ["domain:xray.com"],
"expectIPs": ["geoip:cn"]
}
```
> `address`: address
一个 DNS 服务器列表支持的类型有两种DNS 地址(字符串形式)和 ServerObject 。
当它的值是一个 DNS IP 地址时,如 "8.8.8.8"Xray 会使用此地址的 53 端口进行 DNS 查询。
当值为 "localhost" 时,表示使用本机预设的 DNS 配置。
当值是 `"https://host:port/dns-query"` 的形式,如 `"https://dns.google/dns-query"`Xray 会使用 `DNS over HTTPS` (RFC8484, 简称 DOH) 进行查询。有些服务商拥有 IP 别名的证书,可以直接写 IP 形式,比如 `https://1.1.1.1/dns-query`。也可使用非标准端口和路径,如 `"https://a.b.c.d:8443/my-dns-query"`
当值是 `"https+local://host:port/dns-query"` 的形式,如 `"https+local://dns.google/dns-query"`Xray 会使用 DOH 本地模式 进行查询,即 DOH 请求不会经过 Routing/Outbound 等组件,直接对外请求,以降低耗时。一般适合在服务端使用。也可使用非标端口和路径。
当值是 `fakedns` 时,将使用 FakeDNS 功能进行查询。
> `port`: number
DNS 服务器端口,如 `53`。此项缺省时默认为 `53`。当使用 DOH 模式该项无效,非标端口应在 URL 中指定。
> `domains`: \[string\]
一个域名列表,此列表包含的域名,将优先使用此服务器进行查询。域名格式和 [路由配置](./routing.md#ruleobject) 中相同。
> `expectIPs`:\[string\]
一个 IP 范围列表,格式和 [路由配置](./routing.md#ruleobject) 中相同。
当配置此项时Xray DNS 会对返回的 IP 的进行校验,只返回包含 expectIPs 列表中的地址。
如果未配置此项,会原样返回 IP 地址。

BIN
docs/en/config/dns_flow.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 659 KiB

40
docs/en/config/fakedns.md Normal file
View file

@ -0,0 +1,40 @@
# FakeDNS
FakeDNS 通过伪造 DNS 以获取目标域名,能够降低 DNS 查询时的延迟、配合透明代理获取目标域名。
::: warning
FakeDNS 有可能会污染本地 DNS导致 Xray 关闭后“无法访问网络”。
:::
## FakeDNSObject
`FakeDNSObject` 对应配置文件的 `fakedns` 项。
```json
{
"ipPool": "198.18.0.0/16",
"poolSize": 65535
}
```
> `ipPool`: CIDR
FakeDNS 将使用此选项指定的 IP 块分配地址。
> `poolSize`: int
指定 FakeDNS 储存的 域名-IP 映射的最大数目。当映射数超过此值后,会按照 LRU 规则淘汰映射。默认为 65535。
### 如何使用?
FakeDNS 本质上是一个 [DNS 服务器](./dns.md#serverobject),能够与任意 DNS 规则配合使用。
::: tip
只有将 DNS 查询路由到 FakeDNS才能使其发挥作用。
:::
另外,你需要在入站中开启 `Sniffing` ,并使用 `fakedns` 目标地址重置。
::: warning
如果 FakeIP 没有被正确的还原为域名,将无法连接到服务器。
:::

View file

@ -0,0 +1,48 @@
# 环境变量
Xray 提供以下环境变量以供修改 Xray 的一些底层配置。
## XTLS 信息显示
### VLESS
- 名称:`xray.vless.xtls.show``XRAY_VLESS_XTLS_SHOW`
- 默认值:`""`
使用 VLESS 协议时,设置此环境变量为 true 时, 会在终端或日志中输出 XTLS 的相关信息.
::: tip
可打开此环境变量并根据是否有输出 XTLS 相关信息, 来确定 XTLS 是否成功被应用.
:::
### TROJAN
- 名称:`xray.trojan.xtls.show``XRAY_TROJAN_XTLS_SHOW`
- 默认值:`""`
使用 trojan 协议时, 设置此环境变量为 true 时, 会在终端或日志中输出 XTLS 的相关信息.
::: tip
可打开此环境变量并根据是否有输出 XTLS 相关信息, 来确定 XTLS 是否成功被应用.
:::
## 资源文件路径
- 名称:`xray.location.asset``XRAY_LOCATION_ASSET`
- 默认值:和 Xray 文件同路径。
这个环境变量指定了一个文件夹位置,这个文件夹应当包含 geoip.dat 和 geosite.dat 文件。
## 配置文件位置
- 名称:`xray.location.config``XRAY_LOCATION_CONFIG`
- 默认值:和 Xray 文件同路径。
这个环境变量指定了一个文件夹位置,这个文件夹应当包含 config.json 文件。
## 多配置目录
- 名称:`xray.location.confdir``XRAY_LOCATION_CONFDIR`
- 默认值:`""`
这个目录内的 `.json` 文件会按文件名顺序读取,作为多配置选项。

View file

@ -0,0 +1,100 @@
# Fallback 回落
> **Fallback 是 Xray 的最强大功能之一, 可有效防止主动探测, 自由配置常用端口多服务共享**
fallback 为 Xray 提供了高强度的防主动探测性, 并且具有独创的首包回落机制.
fallback 也可以将不同类型的流量根据 path 进行分流, 从而实现一个端口, 多种服务共享.
目前您可以在使用 VLESS 或者 trojan 协议时, 通过配置 fallbacks 来使用回落这一特性, 并且创造出非常丰富的组合玩法.
## fallbacks 配置
```json
"fallbacks": [
{
"dest": 80
}
]
```
> `fallbacks`: \[ [FallbackObject](#fallbackobject) \]
一个数组,包含一系列强大的回落分流配置。
### FallbackObject
```json
{
"name": "",
"alpn": "",
"path": "",
"dest": 80,
"xver": 0
}
```
**`fallbacks` 是一个数组,这里是其中一个子元素的配置说明。**
`fallbacks` 项是可选的,只能用于 TCP+TLS 传输组合
- 该项有子元素时,[Inbound TLS](../transport.md#tlsobject) 需设置 `"alpn":["http/1.1"]`。\*\*
通常,你需要先设置一组 `alpn``path` 均省略或为空的默认回落,然后再按需配置其它分流。
VLESS 会把 TLS 解密后首包长度 < 18 或协议版本无效身份认证失败的流量转发到 `dest` 指定的地址
其它传输组合必须删掉 `fallbacks` 项或所有子元素,此时也不会开启 FallbackVLESS 会等待读够所需长度,协议版本无效或身份认证失败时,将直接断开连接。
> `name`: string
尝试匹配 TLS SNI(Server Name Indication),空为任意,默认为 ""
> `alpn`: string
尝试匹配 TLS ALPN 协商结果,空为任意,默认为 ""
有需要时VLESS 才会尝试读取 TLS ALPN 协商结果,若成功,输出 info `realAlpn =` 到日志。
用途:解决了 Nginx 的 h2c 服务不能同时兼容 http/1.1 的问题Nginx 需要写两行 listen分别用于 1.1 和 h2c。
注意fallbacks alpn 存在 `"h2"` 时,[Inbound TLS](../transport.md#tlsobject) 需设置 `"alpn":["h2","http/1.1"]`,以支持 h2 访问。
::: tip
Fallback 内设置的 `alpn` 是匹配实际协商出的 ALPN而 Inbound TLS 设置的 `alpn` 是握手时可选的 ALPN 列表,两者含义不同。
:::
> `path`: string
尝试匹配首包 HTTP PATH空为任意默认为空非空则必须以 `/` 开头,不支持 h2c。
智能有需要时VLESS 才会尝试看一眼 PATH不超过 55 个字节;最快算法,并不完整解析 HTTP若成功输出 INFO 日志 `realPath =`
用途:分流其它 inbound 的 WebSocket 流量或 HTTP 伪装流量,没有多余处理、纯粹转发流量,理论性能比 Nginx 更强。
注意:**fallbacks 所在入站本身必须是 TCP+TLS**,这是分流至其它 WS 入站用的,被分流的入站则无需配置 TLS。
> `dest`: string | number
决定 TLS 解密后 TCP 流量的去向,目前支持两类地址:(该项必填,否则无法启动)
1. TCP格式为 `"addr:port"`,其中 addr 支持 IPv4、域名、IPv6若填写域名也将直接发起 TCP 连接(而不走内置的 DNS
2. Unix domain socket格式为绝对路径形如 `"/dev/shm/domain.socket"`,可在开头加 `@` 代表 [abstract](https://www.man7.org/linux/man-pages/man7/unix.7.html)`@@` 则代表带 padding 的 abstract。
若只填 port数字或字符串均可形如 `80``"80"`,通常指向一个明文 http 服务addr 会被补为 `"127.0.0.1"`)。
> `xver`: number
发送 [PROXY protocol](https://www.haproxy.org/download/2.2/doc/proxy-protocol.txt),专用于传递请求的真实来源 IP 和端口,填版本 1 或 2默认为 0即不发送。若有需要建议填 1。
目前填 1 或 2功能完全相同只是结构不同且前者可打印后者为二进制。Xray 的 TCP 和 WS 入站均已支持接收 PROXY protocol。
::: warning
若你正在 [配置 Nginx 接收 PROXY protocol](https://docs.nginx.com/nginx/admin-guide/load-balancer/using-proxy-protocol/#configuring-nginx-to-accept-the-proxy-protocol),除了设置 proxy_protocol 外,还需设置 set_real_ip_from否则可能会出问题。
:::
### 补充说明
- 将匹配到最精确的子元素,与子元素的排列顺序无关。若配置了几个 alpn 和 path 均相同的子元素,则会以最后的为准。
- 回落分流均是解密后 TCP 层的转发,而不是 HTTP 层,只在必要时检查首包 PATH。
- 您可以查看更多的关于 Fallbacks 的使用技巧和心得
- [Fallbacks 功能简析](../documents/level-1/fallbacks-lv1)
## Fallbacks 设计理论 <Badge text="WIP" type="warning"/>

View file

@ -0,0 +1,176 @@
# 多文件配置
Xray 程序支持使用多个配置文件。
多配置文件的主要作用在于分散不同作用模块配置,便于管理和维护。
该功能主要考虑是为了丰富 Xray 的生态链,比如对于 GUI 的客户端,一般只实现节点选择等固定的功能,对于太复杂的配置难以图形化实现;只需留一个 `confdir` 的自定义配置目录供配置复杂的功能;对于服务器的部署脚本,只需往 `confdir` 添加文件即可实现配置多种协议。
## 多文件启动
::: tip
启动信息中会提示依次读入的每个配置文件,留意启动信息是否符合你预设的顺序。
:::
```shell
$ xray run -confdir /etc/xray/confs
```
也可使用 `Xray.location.confdir``Xray_LOCATION_CONFDIR` 指定 `confdir`
参数 `-confdir` 的作用优先于环境变量,如果参数指定了有效的目录则不再读取环境变量中的路径。
## 规则说明
### 普通对象(`{}`
**在 json 的顶级对象当中,后者覆盖或补充前者。**
比如:
- base.json
```json
{
"log": {},
"api": {},
"dns": {},
"stats": {},
"policy": {},
"transport": {},
"routing": {},
"inbounds": []
}
```
- outbounds.json
```json
{
"outbounds": []
}
```
以多配置启动 Xray
```bash
$ xray run -confdir /etc/xray/confs
```
这两个配置文件的就等效于合成一起的整配置。当需要修改出口节点,只需要修改 `outbounds.json` 内容。
如果需要改编日志 log 的级别,也不需要改 `base.json`,只需后续增加一个配置:
- debuglog.json
```json
{
"log": {
"loglevel": "debug"
}
}
```
启动顺序放置在 base 后,即可输出 debug 级别的日志
### 数组(`[]`
在 json 配置中的`inbounds``outbounds`是数组结构,他们有特殊的规则:
- 当配置中的数组元素有 2 或以上,覆盖前者的 inbounds/oubounds
- 当配置中的数组元素只有 1 个时,查找原有`tag`相同的元素进行覆盖;若无法找到:
- 对于 inbounds添加至最后inbounds 内元素顺序无关)
- 对于 outbounds添加至最前outbounds 默认首选出口);但如果文件名含有 tail大小写均可添加至最后。
借助多配置,可以很方便为原有的配置添加不同协议的 inbound而不必修改原有配置。
以下例子不是有效配置,只为展示上述规则。
- 000.json
```json
{
"inbounds": [
{
"protocol": "socks",
"tag": "socks",
"port": 1234
}
]
}
```
- 001.json
```json
{
"inbounds": [
{
"protocol": "http",
"tag": "http"
}
]
}
```
- 002.json
```json
{
"inbounds": [
{
"protocol": "socks",
"tag": "socks",
"port": 4321
}
]
}
```
三个配置将会合成为:
```json
{
"inbounds": [
{
"protocol": "socks",
"tag": "socks",
"port": 4321 // < 002顺序在000后因此覆盖tag为socks的inbound端口为4321
},
{
"protocol": "http",
"tag": "http"
}
]
}
```
## 推荐的多文件列表
执行:
```bash
for BASE in 00_log 01_api 02_dns 03_routing 04_policy 05_inbounds 06_outbounds 07_transport 08_stats 09_reverse; do echo '{}' > "/etc/Xray/$BASE.json"; done
```
```bash
for BASE in 00_log 01_api 02_dns 03_routing 04_policy 05_inbounds 06_outbounds 07_transport 08_stats 09_reverse; do echo '{}' > "/usr/local/etc/Xray/$BASE.json"; done
```
```bash
.
├── 00_log.json
├── 01_api.json
├── 02_dns.json
├── 03_routing.json
├── 04_policy.json
├── 05_inbounds.json
├── 06_outbounds.json
├── 07_transport.json
├── 08_stats.json
└── 09_reverse.json
0 directories, 10 files
```

View file

@ -0,0 +1,46 @@
# VLESS 协议详解
> **VLESS 是原创的无状态的轻量传输协议, 也是 Xray 一切的开始**
## 协议详解 <Badge text="WIP" type="warning"/>
## 配置模板
[Xray-examples](https://github.com/xtls/Xray-examples) 有完整的 VLESS 配置示例供参考。(但目前不能保证其它协议的配置示例质量)
## 客户端开发指引
1. VLESS 协议本身还会有不兼容升级,但客户端配置文件参数基本上是只增不减的。**所以如果你开发了用 core 的客户端,现在就可以适配。** iOS 客户端的协议实现则需紧跟升级。
2. **视觉标准UI 标识请统一用 VLESS**,而不是 VLess / Vless / vless配置文件不受影响代码内则顺其自然。
3. `encryption` 应做成输入框而不是选择框,新配置的默认值应为 `none`,若用户置空则应代填 `none`
**以下为已支持图形化配置 VLESS 的部分客户端列表,推荐使用:**(排名不分先后顺序)
- OpenWrt
- [PassWall](https://github.com/xiaorouji/openwrt-passwall)
- [Hello World](https://github.com/jerrykuku/luci-app-vssr)
- [ShadowSocksR Plus+](https://github.com/fw876/helloworld)
- Windows
- [v2rayN](https://github.com/2dust/v2rayN)
- [Qv2ray](https://github.com/Qv2ray/Qv2ray)
- Android
- [v2rayNG](https://github.com/2dust/v2rayNG)
- [Kitsunebi](https://github.com/rurirei/Kitsunebi/tree/release_xtls)
- iOS / Mac
- [Shadowrocket](https://apps.apple.com/app/shadowrocket/id932747118)
## Fallbacks
Fallbacks 是 Xray 独创的新型协议回落模式解析, 可有效防止主动探测, 自由配置常用端口多服务共享.
目前 Xray 中的 VLESS 和 trojan 协议支持 Fallbacks.
- [Fallbacks 配置说明](../fallback/#fallbacks-配置)
- [Fallbacks 功能简析]()
- [Fallbacks 设计理论](../fallback/#fallbacks-设计理论)
## VLESS 分享链接标准
感谢 <img src="https://avatars2.githubusercontent.com/u/7822648?s=32" width="32px" height="32px" alt="a"/> [@DuckSoft](https://github.com/DuckSoft) 的提案!
目前为初步提案, 详情请见 [VMessAEAD / VLESS 分享链接标准提案](https://github.com/XTLS/Xray-core/issues/91)

View file

@ -0,0 +1,5 @@
# XTLS 深度剖析
> **XTLS 是 Xray 的原创黑科技, 也是使 Xray 性能一骑绝尘的核心动力**
<Badge text="WIP" type="warning"/>

135
docs/en/config/inbound.md Normal file
View file

@ -0,0 +1,135 @@
# 入站代理
入站连接用于接收发来的数据,可用的协议请见[inbound 可用协议列表](./inbounds/)。
## InboundObject
`InboundObject` 对应配置文件中 `inbounds` 项的一个子元素。
```json
{
"inbounds": [
{
"listen": "127.0.0.1",
"port": 1080,
"protocol": "协议名称",
"settings": {},
"streamSettings": {},
"tag": "标识",
"sniffing": {
"enabled": true,
"destOverride": ["http", "tls"]
},
"allocate": {
"strategy": "always",
"refresh": 5,
"concurrency": 3
}
}
]
}
```
> `listen`: address
监听地址IP 地址或 Unix domain socket默认值为 `"0.0.0.0"`,表示接收所有网卡上的连接.
可以指定一个系统可用的 IP 地址。
支持填写 Unix domain socket格式为绝对路径形如 `"/dev/shm/domain.socket"`,可在开头加 `@` 代表 [abstract](https://www.man7.org/linux/man-pages/man7/unix.7.html)`@@` 则代表带 padding 的 abstract。
填写 Unix domain socket 时,`port``allocate` 将被忽略,协议目前可选 VLESS、VMess、Trojan传输方式可选 TCP、WebSocket、HTTP/2。
> `port`: number | "env:variable" | string
端口。接受的格式如下:
- 整型数值:实际的端口号。
- 环境变量:以 `"env:"` 开头,后面是一个环境变量的名称,如 `"env:PORT"`。Xray 会以字符串形式解析这个环境变量。
- 字符串:可以是一个数值类型的字符串,如 `"1234"`;或者一个数值范围,如 `"5-10"` 表示端口 5 到端口 10这 6 个端口。
当只有一个端口时Xray 会在此端口监听入站连接。当指定了一个端口范围时,取决于 `allocate` 设置。
> `protocol`: string
连接协议名称,可选的协议类型见 [inbound 可用协议列表](./inbounds/)。
> `settings`: InboundConfigurationObject
具体的配置内容,视协议不同而不同。详见每个协议中的 `InboundConfigurationObject`
> `streamSettings`: [StreamSettingsObject](./transport.md#streamsettingsobject)
底层传输方式transport是当前 Xray 节点和其它节点对接的方式
> `tag`: string
> 此入站连接的标识,用于在其它的配置中定位此连接。
::: danger
当其不为空时,其值必须在所有 `tag` 中**唯一**。
:::
> `sniffing`: [SniffingObject](#sniffingobject)
流量探测主要作用于在透明代理等用途.
比如一个典型流程如下:
1. 如有一个设备上网,去访问 abc.com,首先设备通过 DNS 查询得到 abc.com 的 IP 是 1.2.3.4,然后设备会向 1.2.3.4 去发起连接.
2. 如果不设置嗅探,Xray 收到的连接请求是 1.2.3.4,并不能用于域名规则的路由分流.
3. 当设置了 sniffing 中的 enable 为 true,Xray 处理此连接的流量时,会从流量的数据中,嗅探出域名,即 abc.com
4. Xray 会把 1.2.3.4 重置为 abc.com.路由就可以根据域名去进行路由的域名规则的分流
因为变成了一个向 abc.com 请求的连接, 就可以做更多的事情, 除了路由域名规则分流, 还能重新做 DNS 解析等其他工作.
当设置了 sniffing 中的 enable 为 true, 还能嗅探出 bittorrent 类型的流量, 然后可以在路由中配置"protocol"项来设置规则处理 BT 流量, 比如服务端用来拦截 BT 流量, 或客户端固定转发 BT 流量到某个 VPS 去等.
> `allocate`: [AllocateObject](#allocateobject)
当设置了多个 port 时, 端口分配的具体设置
### SniffingObject
```json
{
"enabled": true,
"destOverride": ["http", "tls", "fakedns"],
"metadataOnly": false
}
```
> `enabled`: true | false
是否开启流量探测。
> `destOverride`: \["http" | "tls" | "fakedns" \]
当流量为指定类型时,按其中包括的目标地址重置当前连接的目标。
> `metadataOnly`: true | false
当启用时,将仅使用连接的元数据嗅探目标地址。此时,`http``tls` 将不能使用。
### AllocateObject
```json
{
"strategy": "always",
"refresh": 5,
"concurrency": 3
}
```
> `strategy`: "always" | "random"
端口分配策略。
- `"always"` 表示总是分配所有已指定的端口,`port` 中指定了多少个端口Xray 就会监听这些端口。
- `"random"` 表示随机开放端口,每隔 `refresh` 分钟在 `port` 范围中随机选取 `concurrency` 个端口来监听。
> `refresh`: number
随机端口刷新间隔,单位为分钟。最小值为 `2`,建议值为 `5`。这个属性仅当 `strategy` 设置为 `"random"` 时有效。
> `concurrency`: number
随机端口数量。最小值为 `1`,最大值为 `port` 范围的三分之一。建议值为 `3`

View file

@ -0,0 +1,33 @@
# Inbounds 协议
> 这个章节包含了目前所有可用于 Inbounds 的协议及具体配置细节.
## 协议列表
> [Dokodemo-door](./dokodemo.md)
Dokodemo door任意门可以监听一个本地端口并把所有进入此端口的数据发送至指定服务器的一个端口从而达到端口映射的效果。
> [HTTP](./http.md)
HTTP 协议
> [Socks](./socks.md)
标准 Socks 协议实现,兼容 [Socks 4](http://ftp.icm.edu.pl/packages/socks/socks4/SOCKS4.protocol)、Socks 4a 和 [Socks 5](http://ftp.icm.edu.pl/packages/socks/socks4/SOCKS4.protocol)。
> [VLESS](./vless.md)
VLESS 是一个无状态的轻量传输协议,可以作为 Xray 客户端和服务器之间的桥梁。
> [VMess](./vmess.md)
[VMess](../development/protocols/vmess.md) 是一个加密传输协议,,可以作为 Xray 客户端和服务器之间的桥梁。
> [Trojan](./trojan.md)
[Trojan](https://trojan-gfw.github.io/trojan/protocol) 协议
> [Shadowsocks](./shadowsocks.md)
[Shadowsocks](https://zh.wikipedia.org/wiki/Shadowsocks) 协议。

View file

@ -0,0 +1,50 @@
# Dokodemo-Door
Dokodemo door任意门可以监听一个本地端口并把所有进入此端口的数据发送至指定服务器的一个端口从而达到端口映射的效果。
## InboundConfigurationObject
```json
{
"address": "8.8.8.8",
"port": 53,
"network": "tcp",
"timeout": 0,
"followRedirect": false,
"userLevel": 0
}
```
> `address`: address
将流量转发到此地址。可以是一个 IP 地址,形如 `"1.2.3.4"`,或者一个域名,形如 `"xray.com"`。字符串类型。
`followRedirect`(见下文)为 `true` 时,`address` 可为空。
> `port`: number
将流量转发到目标地址的指定端口,范围 \[1, 65535\],数值类型。必填参数。
> `network`: "tcp" | "udp" | "tcp,udp"
可接收的网络协议类型。比如当指定为 `"tcp"` 时,仅会接收 TCP 流量。默认值为 `"tcp"`
> `timeout`: number
连接空闲的时间限制。单位为秒。默认值为 `300`。处理一个连接时,如果在 `timeout` 时间内,没有任何数据被传输,则中断该连接。
> `followRedirect`: true | false
当值为 `true`dokodemo-door 会识别出由 iptables 转发而来的数据,并转发到相应的目标地址。
可参考 [传输配置](../transport.md#sockoptobject) 中的 `tproxy` 设置。
> `userLevel`: number
用户等级,连接会使用这个用户等级对应的 [本地策略](../policy.md#levelpolicyobject)。
userLevel 的值, 对应 [policy](../policy.md#policyobject) 中 `level` 的值. 如不指定, 默认为 0。
## 透明代理配置样例
此部分请参考[透明代理TProxy配置教程](../../document/level-2/tproxy)。

View file

@ -0,0 +1,79 @@
# HTTP
HTTP 协议。
::: warning
**http 协议没有对传输加密,不适宜经公网中传输,更容易成为被人用作攻击的肉鸡。**
:::
`http` 入站更有意义的用法是在局域网或本机环境下监听,为其他程序提供本地服务。
::: tip TIP 1
`http proxy` 只能代理 tcp 协议udp 系的协议均不能通过。
:::
::: tip TIP 2
在 Linux 中使用以下环境变量即可在当前 session 使用全局 HTTP 代理(很多软件都支持这一设置,也有不支持的)。
- `export http_proxy=http://127.0.0.1:8080/` (地址须改成你配置的 HTTP 入站代理地址)
- `export https_proxy=$http_proxy`
:::
## InboundConfigurationObject
```json
{
"timeout": 0,
"accounts": [
{
"user": "my-username",
"pass": "my-password"
}
],
"allowTransparent": false,
"userLevel": 0
}
```
> `timeout`: number
连接空闲的时间限制。单位为秒。默认值为 `300`, 0 表示不限时。
处理一个连接时,如果在 `timeout` 时间内,没有任何数据被传输,则中断该连接。
> `accounts`: \[[AccountObject](#accountobject)\]
一个数组,数组中每个元素为一个用户帐号。默认值为空。
`accounts` 非空时HTTP 代理将对入站连接进行 Basic Authentication 验证。
> `allowTransparent`: true | false
当为 `true` 时,会转发所有 HTTP 请求,而非只是代理请求。
::: tip
若配置不当,开启此选项会导致死循环。
:::
> `userLevel`: number
用户等级,连接会使用这个用户等级对应的 [本地策略](../policy.md#levelpolicyobject)。
userLevel 的值, 对应 [policy](../policy.md#policyobject) 中 `level` 的值。 如不指定, 默认为 0。
### AccountObject
```json
{
"user": "my-username",
"pass": "my-password"
}
```
> `user`: string
用户名,字符串类型。必填。
> `pass`: string
密码,字符串类型。必填。

View file

@ -0,0 +1,87 @@
# Shadowsocks
[Shadowsocks](https://zh.wikipedia.org/wiki/Shadowsocks) 协议,兼容大部分其它版本的实现。
目前兼容性如下:
- 支持 TCP 和 UDP 数据包转发,其中 UDP 可选择性关闭;
- 推荐的加密方式:
- AES-256-GCM
- AES-128-GCM
- ChaCha20-Poly1305 或称 ChaCha20-IETF-Poly1305
- none 或 plain
不推荐的加密方式:
- AES-256-CFB
- AES-128-CFB
- ChaCha20
- ChaCha20-IETF
::: danger
"none" 不加密方式下,服务器端不会验证 "password" 中的密码。为确保安全性, 一般需要加上 TLS 并在传输层使用安全配置,例如 WebSocket 配置较长的 path
:::
## InboundConfigurationObject
```json
{
"settings": {
"clients": [
{
"password": "密码",
"method": "aes-256-gcm",
"level": 0,
"email": "love@xray.com"
}
],
"network": "tcp,udp"
}
}
```
> `network`: "tcp" | "udp" | "tcp,udp"
可接收的网络协议类型。比如当指定为 `"tcp"` 时,仅会接收 TCP 流量。默认值为 `"tcp"`
## ClientObject
```json
{
"password": "密码",
"method": "aes-256-gcm",
"level": 0,
"email": "love@xray.com"
}
```
::: tip
(v1.2.3+) Xray 支持 Shadowsocks 单端口多用户,但是需要将该入站所有用户的加密方式设置为 AEAD。
:::
> `method`: string
必填。
- 推荐的加密方式:
- AES-256-GCM
- AES-128-GCM
- ChaCha20-Poly1305 或称 ChaCha20-IETF-Poly1305
- none 或 plain
> `password`: string
必填,任意字符串。
Shadowsocks 协议不限制密码长度,但短密码会更可能被破解,建议使用 16 字符或更长的密码。
> `level`: number
用户等级,连接会使用这个用户等级对应的 [本地策略](../policy.md#levelpolicyobject)。
`level` 的值, 对应 [policy](../policy.md#levelpolicyobject) 中 `level` 的值。 如不指定, 默认为 0。
> `email`: string
用户邮箱,用于区分不同用户的流量(日志、统计)。

View file

@ -0,0 +1,75 @@
# Socks
标准 Socks 协议实现,兼容 [Socks 4](http://ftp.icm.edu.pl/packages/socks/socks4/SOCKS4.protocol)、Socks 4a 和 [Socks 5](http://ftp.icm.edu.pl/packages/socks/socks4/SOCKS4.protocol)。
::: danger
**socks 协议没有对传输加密,不适宜经公网中传输**
:::
`socks` 入站更有意义的用法是在局域网或本机环境下监听,为其他程序提供本地服务。
## InboundConfigurationObject
```json
{
"auth": "noauth",
"accounts": [
{
"user": "my-username",
"pass": "my-password"
}
],
"udp": false,
"ip": "127.0.0.1",
"userLevel": 0
}
```
> `auth`: "noauth" | "password"
Socks 协议的认证方式,支持 `"noauth"` 匿名方式和 `"password"` 用户密码方式。
默认值为 `"noauth"`
> `accounts`: \[ [AccountObject](#accountobject) \]
一个数组,数组中每个元素为一个用户帐号。
此选项仅当 `auth``password` 时有效。
默认值为空。
> `udp`: true | false
是否开启 UDP 协议的支持。
默认值为 `false`
> `ip`: address
当开启 UDP 时Xray 需要知道本机的 IP 地址。
默认值为 `"127.0.0.1"`
> `userLevel`: number
用户等级,连接会使用这个用户等级对应的 [本地策略](../policy.md#levelpolicyobject)。
userLevel 的值, 对应 [policy](../policy.md#policyobject) 中 `level` 的值。 如不指定, 默认为 0。
### AccountObject
```json
{
"user": "my-username",
"pass": "my-password"
}
```
> `user`: string
用户名,字符串类型。必填。
> `pass`: string
密码,字符串类型。必填。

View file

@ -0,0 +1,87 @@
# Trojan
[Trojan](https://trojan-gfw.github.io/trojan/protocol) 协议
::: danger
Trojan 被设计工作在正确配置的加密 TLS 隧道
:::
## InboundConfigurationObject
```json
{
"clients": [
{
"password": "password",
"email": "love@xray.com",
"level": 0,
"flow": "xtls-rprx-direct"
}
],
"fallbacks": [
{
"dest": 80
}
]
}
```
> `clients`: \[ [ClientObject](#clientobject) \]
一个数组,代表一组服务端认可的用户.
其中每一项是一个用户 [ClientObject](#clientobject)。
> `fallbacks`: \[ [FallbackObject](../examples/fallback.md) \]
一个数组,包含一系列强大的回落分流配置(可选)。
fallbacks 的具体配置请点击[FallbackObject](../examples/fallback.md#fallbacks-配置)
::: tip
Xray 的 Trojan 有完整的 fallbacks 支持,配置方式完全一致。
触发回落的条件也与 VLESS 类似:首包长度 < 58 或第 57 个字节不为 `\r`因为 Trojan 没有协议版本或身份认证失败
:::
### ClientObject
```json
{
"password": "password",
"email": "love@xray.com",
"level": 0,
"flow": "xtls-rprx-direct"
}
```
> `password`: string
必填,任意字符串。
> `email`: string
邮件地址,可选,用于标识用户
::: danger
如果存在多个 ClientObject, 请注意 email 不可以重复。
:::
> `level`: number
用户等级,连接会使用这个用户等级对应的 [本地策略](../policy.md#levelpolicyobject)。
userLevel 的值, 对应 [policy](../policy.md#policyobject) 中 `level` 的值。 如不指定, 默认为 0。
> `flow`: string
流控模式,用于选择 XTLS 的算法。
目前入站协议中有以下流控模式可选:
- `xtls-rprx-origin`:最初的流控模式,此时客户端仅可选择 `xtls-rprx-origin``xtls-rprx-origin-udp443` 这两种流控模式。该模式纪念价值大于实际使用价值。
- `xtls-rprx-direct`**推荐**,所有平台皆可使用的典型流控方式,此时客户端可选择任何流控模式
::: warning 注意
`flow` 被指定时,还需要将该入站协议的 `streamSettings.security` 一项指定为 `xtls``tlsSettings` 改为 `xtlsSettings`。详情请参考 [streamSettings](../transport.md#streamsettingsobject)。
:::
此外,目前 XTLS 仅支持 TCP、mKCP、DomainSocket 这三种传输方式。

View file

@ -0,0 +1,100 @@
# VLESS
::: danger
目前 VLESS 没有自带加密,请用于可靠信道,如 TLS。
目前 VLESS 不支持分享。
:::
VLESS 是一个无状态的轻量传输协议,它分为入站和出站两部分,可以作为 Xray 客户端和服务器之间的桥梁。
与 [VMess](./vmess.md) 不同VLESS 不依赖于系统时间,认证方式同样为 UUID但不需要 alterId。
## InboundConfigurationObject
```json
{
"clients": [
{
"id": "5783a3e7-e373-51cd-8642-c83782b807c5",
"level": 0,
"email": "love@xray.com",
"flow": "xtls-rprx-direct"
}
],
"decryption": "none",
"fallbacks": [
{
"dest": 80
}
]
}
```
> `clients`: \[ [ClientObject](#clientobject) \]
一个数组,代表一组服务端认可的用户.
其中每一项是一个用户 [ClientObject](#clientobject)。
> `decryption`: "none"
现阶段需要填 `"none"`,不能留空。
若未正确设置 decryption 的值,使用 Xray 或 -test 时会收到错误信息。
注意这里是 decryption和 clients 同级。
decryption 和 vmess 协议的 encryption 的位置不同,是因为若套一层约定加密,服务端需要先解密才能知道是哪个用户。
> `fallbacks`: \[ [FallbackObject](../features/fallback.md) \]
一个数组,包含一系列强大的回落分流配置(可选)。
fallbacks 的具体配置请点击 [FallbackObject](../features/fallback.md#fallbacks-配置)
### ClientObject
```json
{
"id": "5783a3e7-e373-51cd-8642-c83782b807c5",
"level": 0,
"email": "love@xray.com",
"flow": "xtls-rprx-direct"
}
```
> `id`: string
VLESS 的用户 ID可以是任意小于 30 字节的字符串, 也可以是一个合法的 UUID.
自定义字符串和其映射的 UUID 是等价的, 这意味着你将可以这样在配置文件中写 id 来标识同一用户,即
- 写 `"id": "我爱🍉老师1314"`,
- 或写 `"id": "5783a3e7-e373-51cd-8642-c83782b807c5"` (此 UUID 是 `我爱🍉老师1314` 的 UUID 映射)
其映射标准在 [VLESS UUID 映射标准:将自定义字符串映射为一个 UUIDv5](https://github.com/XTLS/Xray-core/issues/158)
你可以使用命令 `xray uuid -i "自定义字符串"` 生成自定义字符串所映射的的 UUID。
> 也可以使用命令 `xray uuid` 生成随机的 UUID.
> `level`: number
用户等级,连接会使用这个用户等级对应的 [本地策略](../policy.md#levelpolicyobject)。
level 的值, 对应 [policy](../policy.md#policyobject) 中 `level` 的值。 如不指定, 默认为 0。
> `email`: string
用户邮箱,用于区分不同用户的流量(会体现在日志、统计中)。
> `flow`: string
流控模式,用于选择 XTLS 的算法。
目前入站协议中有以下流控模式可选:
- `xtls-rprx-origin`:最初的流控模式,此时客户端仅可选择 `xtls-rprx-origin``xtls-rprx-origin-udp443` 这两种流控模式。该模式纪念价值大于实际使用价值。
- `xtls-rprx-direct`**推荐**,所有平台皆可使用的典型流控方式,此时客户端可选择任何流控模式
::: warning 注意
`flow` 被指定时,还需要将该入站协议的 `streamSettings.security` 一项指定为 `xtls``tlsSettings` 改为 `xtlsSettings`。详情请参考 [streamSettings](../transport.md#streamsettingsobject)。
:::
此外,目前 XTLS 仅支持 TCP、mKCP、DomainSocket 这三种传输方式。

View file

@ -0,0 +1,150 @@
# VMess
[VMess](../../development/protocols/vmess.md) 是一个加密传输协议,通常作为 Xray 客户端和服务器之间的桥梁。
::: danger
VMess 依赖于系统时间,请确保使用 Xray 的系统 UTC 时间误差在 90 秒之内,时区无关。在 Linux 系统中可以安装`ntp`服务来自动同步系统时间。
:::
## InboundConfigurationObject
```json
{
"clients": [
{
"id": "5783a3e7-e373-51cd-8642-c83782b807c5",
"level": 0,
"alterId": 0,
"email": "love@xray.com"
}
],
"default": {
"level": 0,
"alterId": 0
},
"detour": {
"to": "tag_to_detour"
},
"disableInsecureEncryption": false
}
```
> `clients`: \[ [ClientObject](#clientobject) \]
一个数组,代表一组服务端认可的用户.
其中每一项是一个用户[ClientObject](#clientobject)。
当此配置用作动态端口时Xray 会自动创建用户。
> `detour`: [DetourObject](#detourobject)
指示对应的出站协议使用另一个服务器。
> `default`: [DefaultObject](#defaultobject)
可选clients 的默认配置。仅在配合`detour`时有效。
> `disableInsecureEncryption`: true | false
是否禁止客户端使用不安全的加密方式,如果设置为 true 当客户端指定下列加密方式时,服务器会主动断开连接。
- `"none"`
- `"aes-128-cfb"`
默认值为`false`
### ClientObject
```json
{
"id": "5783a3e7-e373-51cd-8642-c83782b807c5",
"level": 0,
"alterId": 4,
"email": "love@xray.com"
}
```
> `id`: string
Vmess 的用户 ID可以是任意小于 30 字节的字符串, 也可以是一个合法的 UUID.
::: tip
自定义字符串和其映射的 UUID 是等价的, 这意味着你将可以这样在配置文件中写 id 来标识同一用户,即
- 写 `"id": "我爱🍉老师1314"`,
- 或写 `"id": "5783a3e7-e373-51cd-8642-c83782b807c5"` (此 UUID 是 `我爱🍉老师1314` 的 UUID 映射)
:::
其映射标准在 [VLESS UUID 映射标准:将自定义字符串映射为一个 UUIDv5](https://github.com/XTLS/Xray-core/issues/158)
你可以使用命令 `xray uuid -i "自定义字符串"` 生成自定义字符串所映射的的 UUID。
> 也可以使用命令 `xray uuid` 生成随机的 UUID.
> `level`: number
用户等级,连接会使用这个用户等级对应的 [本地策略](../policy.md#levelpolicyobject)。
level 的值, 对应 [policy](../policy.md#policyobject) 中 `level` 的值。 如不指定, 默认为 0。
> `alterId`: number
为了进一步防止被探测,一个用户可以在主 ID 的基础上,再额外生成多个 ID。这里只需要指定额外的 ID 的数量,推荐值为 0 代表启用 VMessAEAD。
最大值 65535。这个值不能超过服务器端所指定的值。
不指定的话,默认值是 0。
::: tip
客户端 AlterID 设置为 0 代表启用 VMessAEAD ;服务端为自动适配,可同时兼容启用和未开启 VMessAEAD 的客户端。
客户端可通过设置环境变量 `Xray_VMESS_AEAD_DISABLED=true` 强行禁用 VMessAEAD
:::
> `email`: string
用户邮箱地址,用于区分不同用户的流量。
### DetourObject
```json
{
"to": "tag_to_detour"
}
```
> `to`: string
一个 inbound 的`tag`, 指定的 inbound 的必须是使用 VMess 协议的 inbound.
### DefaultObject
```json
{
"level": 0,
"alterId": 0
}
```
> `level`: number
用户等级,连接会使用这个用户等级对应的 [本地策略](../policy.md#levelpolicyobject)。
level 的值, 对应 [policy](../policy.md#policyobject) 中 `level` 的值。 如不指定, 默认为 0。
> `alterId`: number
动态端口的默认`alterId`,默认值为`0`
## VMess MD5 认证信息 玷污机制
为了进一步对抗可能的探测和封锁,每个 VMess 认证数据的服务端结构都会包含一个一次写入的玷污状态标记,初始状态为无瑕状态,当服务器检测到重放探测时或者因为其他原因入站连接出错以致校验数据不正确时,该连接所对应的请求认证数据会被玷污。
被玷污的认证数据无法被用于建立连接,当攻击者或客户端使用被玷污的认证数据建立连接时,服务器会输出包含 `invalid user` `ErrTainted` 的错误信息,并阻止该连接。
当服务器没有受到重放攻击时,该机制对正常连接的客户端没有影响。
如果服务器正在被重放攻击,可能会出现连接不稳定的情况。
::: tip
拥有服务器 UUID 以及其他连接数据的恶意程序可能根据此机制对服务器发起拒绝服务攻击,受到此类攻击的服务可以通过修改 `proxy/vmess/validator.go` 文件中 `func (v \*TimedUserValidator) BurnTaintFuse(userHash []byte) error` 函数的 `atomic.CompareAndSwapUint32(pair.taintedFuse, 0, 1)` 语句为 `atomic.CompareAndSwapUint32(pair.taintedFuse, 0, 0)` 来解除服务器对此类攻击的安全保护机制。使用 VMessAEAD 认证机制的客户端不受到 VMess MD5 认证信息 玷污机制 的影响。
:::

47
docs/en/config/log.md Normal file
View file

@ -0,0 +1,47 @@
# 日志配置
日志配置,控制 Xray 输出日志的方式.
Xray 有两种日志, 访问日志和错误日志, 你可以分别配置两种日志的输出方式.
## LogObject
LogObject 对应配置文件的 `log` 项。
```json
{
"log": {
"access": "文件地址",
"error": "文件地址",
"loglevel": "warning",
"dnsLog": false
}
}
```
> `access`: string
访问日志的文件地址,其值是一个合法的文件地址,如`"/var/log/Xray/access.log"`Linux或者`"C:\\Temp\\Xray\\_access.log"`Windows。当此项不指定或为空值时表示将日志输出至 stdout。
- 特殊值`none`,即关闭 access log。
> `error`: string
错误日志的文件地址,其值是一个合法的文件地址,如`"/var/log/Xray/error.log"`Linux或者`"C:\\Temp\\Xray\\_error.log"`Windows。当此项不指定或为空值时表示将日志输出至 stdout。
- 特殊值`none`,即关闭 error log。
> `loglevel`: "debug" | "info" | "warning" | "error" | "none"
error 日志的级别, 指示 error 日志需要记录的信息.
默认值为 `"warning"`
- `"debug"`:调试程序时用到的输出信息。同时包含所有 `"info"` 内容。
- `"info"`:运行时的状态信息等,不影响正常使用。同时包含所有 `"warning"` 内容。
- `"warning"`:发生了一些并不影响正常运行的问题时输出的信息,但有可能影响用户的体验。同时包含所有 `"error"` 内容。
- `"error"`Xray 遇到了无法正常运行的问题,需要立即解决。
- `"none"`:不记录任何内容。
> `dnsLog`: bool
是否启用 DNS 查询日志,例如:`DOH//doh.server got answer: domain.com -> [ip1, ip2] 2.333ms`

112
docs/en/config/outbound.md Normal file
View file

@ -0,0 +1,112 @@
# 出站代理
出站连接用于发送数据,可用的协议请见 [outbound 可用协议列表](./outbounds/)。
## OutboundObject
`OutboundObject` 对应配置文件中 `outbounds` 项的一个子元素。
::: tip
列表中的第一个元素作为主 outbound。当路由匹配不存在或没有匹配成功时流量由主 outbound 发出。
:::
```json
{
"outbounds": [
{
"sendThrough": "0.0.0.0",
"protocol": "协议名称",
"settings": {},
"tag": "标识",
"streamSettings": {},
"proxySettings": {
"tag": "another-outbound-tag"
},
"mux": {}
}
]
}
```
> `sendThrough`: address
用于发送数据的 IP 地址,当主机有多个 IP 地址时有效,默认值为 `"0.0.0.0"`
> `protocol`: string
连接协议名称,可选的协议类型见 [outbound 可用协议列表](./outbounds/)。
> `settings`: OutboundConfigurationObject
具体的配置内容,视协议不同而不同。详见每个协议中的 `OutboundConfigurationObject`
> `tag`: string
此出站连接的标识,用于在其它的配置中定位此连接。
::: danger
当其不为空时,其值必须在所有 `tag`**唯一**
:::
> `streamSettings`: [StreamSettingsObject](./transport.md#streamsettingsobject)
底层传输方式transport是当前 Xray 节点和其它节点对接的方式
> `proxySettings`: [ProxySettingsObject](#proxysettingsobject)
出站代理配置。当出站代理生效时,此 outbound 的 `streamSettings` 将不起作用。
> `mux`: [MuxObject](#muxobject)
Mux 相关的具体配置。
### ProxySettingsObject
```json
{
"tag": "another-outbound-tag"
}
```
> `tag`: string
当指定另一个 outbound 的标识时,此 outbound 发出的数据,将被转发至所指定的 outbound 发出。
::: danger
这种转发方式**不经过**底层传输方式。如果需要使用支持底层传输方式的转发,请使用 [SockOpt.dialerProxy](./transport.md#sockoptobject)。
:::
::: danger
此选项与 SockOpt.dialerProxy 不兼容
:::
::: tip
兼容 v2fly/v2ray-core 的配置 [transportLayer](https://www.v2fly.org/config/outbounds.html#proxysettingsobject)
:::
### MuxObject
Mux 功能是在一条 TCP 连接上分发多个 TCP 连接的数据。实现细节详见 [Mux.Cool](../../development/protocols/muxcool)。Mux 是为了减少 TCP 的握手延迟而设计,而非提高连接的吞吐量。使用 Mux 看视频、下载或者测速通常都有反效果。Mux 只需要在客户端启用,服务器端自动适配。
`MuxObject` 对应 `OutboundObject` 中的 `mux` 项。
```json
{
"enabled": false,
"concurrency": 8
}
```
> `enabled`: true | false
是否启用 Mux 转发请求,默认值 `false`
> `concurrency`: number
最大并发连接数。最小值 `1`,最大值 `1024`,默认值 `8`
这个数值表示了一个 TCP 连接上最多承载的 Mux 连接数量。比如设置 `concurrency=8` 时,当客户端发出了 8 个 TCP 请求Xray 只会发出一条实际的 TCP 连接,客户端的 8 个请求全部由这个 TCP 连接传输。
::: tip
填负数时,如 `-1`,不加载 mux 模块。
:::

View file

@ -0,0 +1,41 @@
# Outbounds 可用协议列表
> **这个章节包含了目前所有可用于 Outbounds 的协议及具体配置细节.**
## 协议列表
> [Blackhole](./blackhole.md)
Blackhole黑洞是一个出站数据协议它会阻碍所有数据的出站配合 [路由Routing](../routing.md) 一起使用,可以达到禁止访问某些网站的效果。
> [DNS](./dns.md)
DNS 是一个出站协议,主要用于拦截和转发 DNS 查询。此出站协议只能接收 DNS 流量(包含基于 UDP 和 TCP 协议的查询),其它类型的流量会导致错误。
> [Freedom](./freedom.md)
Freedom 是一个出站协议,可以用来向任意网络发送(正常的) TCP 或 UDP 数据。
> [HTTP](./http.md)
HTTP 协议
> [Socks](./socks.md)
标准 Socks 协议实现,兼容 [Socks 4](http://ftp.icm.edu.pl/packages/socks/socks4/SOCKS4.protocol)、Socks 4a 和 [Socks 5](http://ftp.icm.edu.pl/packages/socks/socks4/SOCKS4.protocol)。
> [VLESS](./vless.md)
VLESS 是一个无状态的轻量传输协议,可以作为 Xray 客户端和服务器之间的桥梁。
> [VMess](./vmess.md)
[VMess](../development/protocols/vmess.md) 是一个加密传输协议,可以作为 Xray 客户端和服务器之间的桥梁。
> [Trojan](./trojan.md)
[Trojan](https://trojan-gfw.github.io/trojan/protocol) 协议。
> [Shadowsocks](./shadowsocks.md)
[Shadowsocks](https://zh.wikipedia.org/wiki/Shadowsocks) 协议。

View file

@ -0,0 +1,34 @@
# Blackhole
Blackhole黑洞是一个出站数据协议它会阻碍所有数据的出站配合 [路由配置](../routing.md) 一起使用,可以达到禁止访问某些网站的效果。
## OutboundConfigurationObject
```json
{
"response": {
"type": "none"
}
}
```
> `response`: [ResponseObject](#responseobject)
配置黑洞的响应数据。
Blackhole 会在收到待转发数据之后,发送指定的响应数据,然后关闭连接,待转发的数据将被丢弃。
如不指定此项Blackhole 将直接关闭连接。
### ResponseObject
```json
{
"type": "none"
}
```
> `type`: "http" | "none"
`type``"none"`默认值Blackhole 将直接关闭连接。
`type``"http"`Blackhole 会发回一个简单的 HTTP 403 数据包,然后关闭连接。

View file

@ -0,0 +1,31 @@
# DNS
DNS 是一个出站协议,主要用于拦截和转发 DNS 查询。
此出站协议只能接收 DNS 流量(包含基于 UDP 和 TCP 协议的查询),其它类型的流量会导致错误。
在处理 DNS 查询时,此出站协议会将 IP 查询(即 A 和 AAAA转发给内置的 [DNS 服务器](../dns.md)。其它类型的查询流量将被转发至它们原本的目标地址。
## OutboundConfigurationObject
```json
{
"network": "tcp",
"address": "1.1.1.1",
"port": 53
}
```
> `network`: "tcp" | "udp"
修改 DNS 流量的传输层协议,可选的值有 `"tcp"``"udp"`。当不指定时,保持来源的传输方式不变。
> `address`: address
修改 DNS 服务器地址。当不指定时,保持来源中指定的地址不变。
> `port`: number
修改 DNS 服务器端口。当不指定时,保持来源中指定的端口不变。
## DNS 配置实例 <Badge text="WIP" type="warning"/>

View file

@ -0,0 +1,44 @@
# Freedom
Freedom 是一个出站协议,可以用来向任意网络发送(正常的) TCP 或 UDP 数据。
## OutboundConfigurationObject
```json
{
"domainStrategy": "AsIs",
"redirect": "127.0.0.1:3366",
"userLevel": 0
}
```
> `domainStrategy`: "AsIs" | "UseIP" | "UseIPv4" | "UseIPv6"
在目标地址为域名时, 配置相应的值, Freedom 的行为模式如下:
- `"AsIs"`: Freedom 通过系统 DNS 服务器解析获取 IP, 向此域名发出连接.
- `"UseIP"``"UseIPv4"``"UseIPv6"`: Xray 使用 [内置 DNS 服务器](../dns.md) 解析获取 IP, 向此域名发出连接.
默认值为 `"AsIs"`
::: tip TIP 1
当使用 `"UseIP"` 模式,并且 [出站连接配置](../outbound.md#outboundobject) 中指定了 `sendThrough`Freedom 会根据 `sendThrough` 的值自动判断所需的 IP 类型IPv4 或 IPv6。
:::
::: tip TIP 2
当使用 `"UseIPv4"``"UseIPv6"` 模式时Freedom 会只使用对应的 IPv4 或 IPv6 地址。当 `sendThrough` 指定了不匹配的本地地址时,将导致连接失败。
:::
> `redirect`: address_port
Freedom 会强制将所有数据发送到指定地址(而不是 inbound 指定的地址)。
其值为一个字符串,样例:`"127.0.0.1:80"``":1234"`
当地址不指定时,如 `":443"`Freedom 不会修改原先的目标地址。
当端口为 `0` 时,如 `"xray.com: 0"`Freedom 不会修改原先的端口。
> `userLevel`: number
用户等级,连接会使用这个用户等级对应的 [本地策略](../policy.md#levelpolicyobject)。
userLevel 的值, 对应 [policy](../policy.md#policyobject) 中 `level` 的值。 如不指定, 默认为 0。

View file

@ -0,0 +1,82 @@
# HTTP
HTTP 协议。
::: danger
**http 协议没有对传输加密,不适宜经公网中传输,更容易成为被人用作攻击的肉鸡。**
:::
::: tip
`http` 只能代理 tcp 协议udp 系的协议均不能通过。
:::
## OutboundConfigurationObject
```json
{
"servers": [
{
"address": "192.168.108.1",
"port": 3128,
"users": [
{
"user": "my-username",
"pass": "my-password"
}
]
}
]
}
```
::: tip
目前 HTTP 协议 outbound 中 `streamSettings` 设置 `security``tlsSettings` 是生效的。
:::
> `servers`: \[ [ServerObject](#serverobject) \]
HTTP 服务器列表,其中每一项是一个服务器配置,若配置多个,循环使用 (RoundRobin)。
### ServerObject
```json
{
"address": "192.168.108.1",
"port": 3128,
"users": [
{
"user": "my-username",
"pass": "my-password"
}
]
}
```
> `address`: string
HTTP 代理服务器地址,必填。
> `port`: int
HTTP 代理服务器端口,必填。
> `user`: \[[AccountObject](#accountobject)\]
一个数组,数组中每个元素为一个用户帐号。默认值为空。
#### AccountObject
```json
{
"user": "my-username",
"pass": "my-password"
}
```
> `user`: string
用户名,字符串类型。必填。
> `pass`: string
密码,字符串类型。必填。

View file

@ -0,0 +1,92 @@
# Shadowsocks
[Shadowsocks](https://zh.wikipedia.org/wiki/Shadowsocks) 协议,兼容大部分其它版本的实现。
目前兼容性如下:
- 支持 TCP 和 UDP 数据包转发,其中 UDP 可选择性关闭;
- 推荐的加密方式:
- AES-256-GCM
- AES-128-GCM
- ChaCha20-Poly1305 或称 ChaCha20-IETF-Poly1305
- none 或 plain
不推荐的加密方式:
- AES-256-CFB
- AES-128-CFB
- ChaCha20
- ChaCha20-IETF
::: danger
"none" 不加密方式下,服务器端不会验证 "password" 中的密码。为确保安全性, 一般需要加上 TLS 并在传输层使用安全配置,例如 WebSocket 配置较长的 path
:::
## OutboundConfigurationObject
```json
{
"servers": [
{
"email": "love@xray.com",
"address": "127.0.0.1",
"port": 1234,
"method": "加密方式",
"password": "密码",
"level": 0
}
]
}
```
> `servers`: \[[ServerObject](#serverobject)\]
一个数组,代表一组 Shadowsocks 服务端设置, 其中每一项是一个 [ServerObject](#serverobject)。
### ServerObject
```json
{
"email": "love@xray.com",
"address": "127.0.0.1",
"port": 1234,
"method": "加密方式",
"password": "密码",
"level": 0
}
```
> `email`: string
邮件地址,可选,用于标识用户
> `address`: address
Shadowsocks 服务端地址,支持 IPv4、IPv6 和域名。必填。
> `port`: number
Shadowsocks 服务端端口。必填。
> `method`: string
必填。
- 推荐的加密方式:
- AES-256-GCM
- AES-128-GCM
- ChaCha20-Poly1305 或称 ChaCha20-IETF-Poly1305
- none 或 plain
> `password`: string
必填。任意字符串。
Shadowsocks 协议不限制密码长度,但短密码会更可能被破解,建议使用 16 字符或更长的密码。
> `level`: number
用户等级,连接会使用这个用户等级对应的 [本地策略](../policy.md#levelpolicyobject)。
`level` 的值, 对应 [policy](../policy.md#policyobject) 中 `level` 的值。 如不指定, 默认为 0。

View file

@ -0,0 +1,91 @@
# Socks
标准 Socks 协议实现,兼容 [Socks 4](http://ftp.icm.edu.pl/packages/socks/socks4/SOCKS4.protocol)、Socks 4a 和 [Socks 5](http://ftp.icm.edu.pl/packages/socks/socks4/SOCKS4.protocol)。
::: danger
**socks 协议没有对传输加密,不适宜经公网中传输**
:::
## OutboundConfigurationObject
```json
{
"servers": [
{
"address": "127.0.0.1",
"port": 1234,
"users": [
{
"user": "test user",
"pass": "test pass",
"level": 0
}
]
}
]
}
```
> `servers`: \[ [ServerObject](#serverobject) \]
Socks 服务器列表,其中每一项是一个服务器配置。
### ServerObject
```json
{
"address": "127.0.0.1",
"port": 1234,
"users": [
{
"user": "test user",
"pass": "test pass",
"level": 0
}
]
}
```
> `address`: address
服务器地址, 必填
::: tip
仅支持连接到 Socks 5 服务器。
:::
> `port`: number
服务器端口, 必填
> `users`: \[ [UserObject](#userobject) \]
一个数组表示的用户列表,数组中每个元素为一个用户配置。
当列表不为空时Socks 客户端会使用用户信息进行认证;如未指定,则不进行认证。
默认值为空。
#### UserObject
```json
{
"user": "test user",
"pass": "test pass",
"level": 0
}
```
> `user`: string
用户名,字符串类型。必填。
> `pass`: string
密码,字符串类型。必填。
> `level`: number
用户等级,连接会使用这个用户等级对应的 [本地策略](../policy.md#levelpolicyobject)。
userLevel 的值, 对应 [policy](../policy.md#policyobject) 中 `level` 的值。 如不指定, 默认为 0。

View file

@ -0,0 +1,104 @@
# Trojan
[Trojan](https://trojan-gfw.github.io/trojan/protocol) 协议
::: danger
Trojan 被设计工作在正确配置的加密 TLS 隧道
:::
## OutboundConfigurationObject
```json
{
"servers": [
{
"address": "127.0.0.1",
"port": 1234,
"password": "password",
"email": "love@xray.com",
"flow": "xtls-rprx-direct",
"level": 0
}
]
}
```
> `servers`: \[ [ServerObject](#serverobject) \]
一个数组,其中每一项是一个 [ServerObject](#serverobject)。
### ServerObject
```json
{
"address": "127.0.0.1",
"port": 1234,
"password": "password",
"email": "love@xray.com",
"flow": "xtls-rprx-direct",
"level": 0
}
```
> `address`: address
服务端地址,支持 IPv4、IPv6 和域名。必填。
> `port`: number
服务端端口,通常与服务端监听的端口相同。
> `password`: string
密码. 必填,任意字符串。
> `email`: string
邮件地址,可选,用于标识用户
> `flow`: string
流控模式,用于选择 XTLS 的算法。
目前出站协议中有以下流控模式可选:
- `xtls-rprx-origin`:最初的流控模式。该模式纪念价值大于实际使用价值
- `xtls-rprx-origin-udp443`:同 `xtls-rprx-origin`, 但放行了目标为 443 端口的 UDP 流量
- `xtls-rprx-direct`:所有平台皆可使用的典型流控模式
- `xtls-rprx-direct-udp443`:同 `xtls-rprx-direct`, 但是放行了目标为 443 端口的 UDP 流量
- `xtls-rprx-splice`Linux 平台下最建议使用的流控模式
- `xtls-rprx-splice-udp443`:同 `xtls-rprx-splice`, 但是放行了目标为 443 端口的 UDP 流量
::: warning 注意
`flow` 被指定时,还需要将该出站协议的 `streamSettings.security` 一项指定为 `xtls``tlsSettings` 改为 `xtlsSettings`。详情请参考 [streamSettings](../transport.md#streamsettingsobject)。
:::
此外,目前 XTLS 仅支持 TCP、mKCP、DomainSocket 这三种传输方式。
<!-- prettier-ignore -->
::: tip 关于 xtls-rprx-\*-udp443 流控模式
启用了 Xray-core 的 XTLS 时,通往 UDP 443 端口的流量默认会被拦截(一般情况下为 QUIC这样应用就不会使用 QUIC 而会使用 TLSXTLS 才会真正生效。实际上QUIC 本身也不适合被代理,因为 QUIC 自带了 TCP 的功能, 它作为 UDP 流量在通过 Trojan 协议传输时,底层协议为 TCP就相当于两层 TCP 了。
若不需要拦截,请在客户端填写 `xtls-rprx-*-udp443`,服务端不变。
:::
::: tip 关于 Splice 模式
Splice 是 Linux Kernel 提供的函数,系统内核直接转发 TCP不再经过 Xray 的内存大大减少了数据拷贝、CPU 上下文切换的次数。
:::
Splice 模式的的使用限制:
- Linux 环境
- 入站协议为 `Dokodemo door``Socks``HTTP` 等纯净的 TCP 连接, 或其它使用了 XTLS 的入站协议
- 出站协议为 VLESS + XTLS 或 Trojan + XTLS
此外,使用 Splice 时网速显示会滞后,这是特性,不是 bug。
需要注意的是,使用 mKCP 协议时不会使用 Splice是的虽然没有报错但实际上根本没用到
> `level`: number
用户等级,连接会使用这个用户等级对应的 [本地策略](../policy.md#levelpolicyobject)。
level 的值, 对应 [policy](../policy.md#policyobject) 中 `level` 的值。 如不指定, 默认为 0。

View file

@ -0,0 +1,142 @@
# VLESS
::: danger
目前 VLESS 没有自带加密,请用于可靠信道,如 TLS。
目前 VLESS 不支持分享。
:::
VLESS 是一个无状态的轻量传输协议,它分为入站和出站两部分,可以作为 Xray 客户端和服务器之间的桥梁。
与 [VMess](./vmess.md) 不同VLESS 不依赖于系统时间,认证方式同样为 UUID但不需要 alterId。
## OutboundConfigurationObject
```json
{
"vnext": [
{
"address": "example.com",
"port": 443,
"users": [
{
"id": "5783a3e7-e373-51cd-8642-c83782b807c5",
"encryption": "none",
"flow": "xtls-rprx-direct",
"level": 0
}
]
}
]
}
```
> `vnext`: \[ [ServerObject](#serverobject) \]
一个数组, 表示 VLESS 服务器列表,包含一组指向服务端的配置, 其中每一项是一个服务器配置。
### ServerObject
```json
{
"address": "example.com",
"port": 443,
"users": [
{
"id": "5783a3e7-e373-51cd-8642-c83782b807c5",
"encryption": "none",
"flow": "xtls-rprx-direct",
"level": 0
}
]
}
```
> `address`: address
服务端地址指向服务端支持域名、IPv4、IPv6。
> `port`: number
服务端端口,通常与服务端监听的端口相同。
> `users`: \[ [UserObject](#userobject) \]
数组, 一组服务端认可的用户列表, 其中每一项是一个用户配置
### UserObject
```json
{
"id": "5783a3e7-e373-51cd-8642-c83782b807c5",
"encryption": "none",
"flow": "xtls-rprx-direct",
"level": 0
}
```
> `id`: string
VLESS 的用户 ID可以是任意小于 30 字节的字符串, 也可以是一个合法的 UUID.
自定义字符串和其映射的 UUID 是等价的, 这意味着你将可以这样在配置文件中写 id 来标识同一用户,即
- 写 `"id": "我爱🍉老师1314"`,
- 或写 `"id": "5783a3e7-e373-51cd-8642-c83782b807c5"` (此 UUID 是 `我爱🍉老师1314` 的 UUID 映射)
其映射标准在 [VLESS UUID 映射标准:将自定义字符串映射为一个 UUIDv5](https://github.com/XTLS/Xray-core/issues/158)
你可以使用命令 `xray uuid -i "自定义字符串"` 生成自定义字符串所映射的的 UUID也可以使用命令 `xray uuid` 生成随机的 UUID。
> `encryption`: "none"
需要填 `"none"`,不能留空。
该要求是为了提醒使用者没有加密,也为了以后出加密方式时,防止使用者填错属性名或填错位置导致裸奔。
若未正确设置 encryption 的值,使用 Xray 或 -test 时会收到错误信息。
> `flow`: string
流控模式,用于选择 XTLS 的算法。
目前出站协议中有以下流控模式可选:
- `xtls-rprx-origin`:最初的流控模式。该模式纪念价值大于实际使用价值
- `xtls-rprx-origin-udp443`:同 `xtls-rprx-origin`, 但放行了目标为 443 端口的 UDP 流量
- `xtls-rprx-direct`:所有平台皆可使用的典型流控模式
- `xtls-rprx-direct-udp443`:同 `xtls-rprx-direct`, 但是放行了目标为 443 端口的 UDP 流量
- `xtls-rprx-splice`Linux 平台下最建议使用的流控模式
- `xtls-rprx-splice-udp443`:同 `xtls-rprx-splice`, 但是放行了目标为 443 端口的 UDP 流量
::: warning 注意
`flow` 被指定时,还需要将该出站协议的 `streamSettings.security` 一项指定为 `xtls``tlsSettings` 改为 `xtlsSettings`。详情请参考 [streamSettings](../transport.md#streamsettingsobject)。
此外,目前 XTLS 仅支持 TCP、mKCP、DomainSocket 这三种传输方式。
:::
<!-- prettier-ignore -->
::: tip 关于 xtls-rprx-*-udp443 流控模式
启用了 Xray-core 的 XTLS 时,通往 UDP 443 端口的流量默认会被拦截(一般情况下为 QUIC这样应用就不会使用 QUIC 而会使用 TLSXTLS 才会真正生效。实际上QUIC 本身也不适合被代理,因为 QUIC 自带了 TCP 的功能,它作为 UDP 流量在通过 VLESS 协议传输时,底层协议为 TCP就相当于两层 TCP 了。
若不需要拦截,请在客户端填写 `xtls-rprx-*-udp443`,服务端不变。
:::
::: tip 关于 Splice 模式
Splice 是 Linux Kernel 提供的函数,系统内核直接转发 TCP不再经过 Xray 的内存大大减少了数据拷贝、CPU 上下文切换的次数。
:::
Splice 模式的的使用限制:
- Linux 环境
- 入站协议为 `Dokodemo door``Socks``HTTP` 等纯净的 TCP 连接, 或其它使用了 XTLS 的入站协议
- 出站协议为 VLESS + XTLS 或 Trojan + XTLS
此外,使用 Splice 时网速显示会滞后,这是特性,不是 bug。
需要注意的是,使用 mKCP 协议时不会使用 Splice是的虽然没有报错但实际上根本没用到
> `level`: number
用户等级,连接会使用这个用户等级对应的 [本地策略](../policy.md#levelpolicyobject)。
level 的值, 对应 [policy](../policy.md#policyobject) 中 `level` 的值。 如不指定, 默认为 0。

View file

@ -0,0 +1,124 @@
# VMess
[VMess](../../development/protocols/vmess.md) 是一个加密传输协议,通常作为 Xray 客户端和服务器之间的桥梁。
::: danger
VMess 依赖于系统时间,请确保使用 Xray 的系统 UTC 时间误差在 90 秒之内,时区无关。在 Linux 系统中可以安装`ntp`服务来自动同步系统时间。
:::
## OutboundConfigurationObject
```json
{
"vnext": [
{
"address": "127.0.0.1",
"port": 37192,
"users": [
{
"id": "5783a3e7-e373-51cd-8642-c83782b807c5",
"alterId": 0,
"security": "auto",
"level": 0
}
]
}
]
}
```
> `vnext`\[ [ServerObject](#serverobject) \]
一个数组,包含一组的服务端配置.
其中每一项是一个服务端配置[ServerObject](#serverobject)。
### ServerObject
```json
{
"address": "127.0.0.1",
"port": 37192,
"users": []
}
```
> `address`: address
服务端地址,支持 IP 地址或者域名。
> `port`: number
服务端监听的端口号, 必填。
> `users`: \[ [UserObject](#userobject) \]
一个数组,代表一组服务端认可的用户.
其中每一项是一个用户[UserObject](#userobject)。
#### UserObject
```json
{
"id": "5783a3e7-e373-51cd-8642-c83782b807c5",
"alterId": 0,
"security": "auto",
"level": 0
}
```
> `id`string
Vmess 的用户 ID可以是任意小于 30 字节的字符串, 也可以是一个合法的 UUID.
自定义字符串和其映射的 UUID 是等价的, 这意味着你将可以这样在配置文件中写 id 来标识同一用户,即
- 写 `"id": "我爱🍉老师1314"`,
- 或写 `"id": "5783a3e7-e373-51cd-8642-c83782b807c5"` (此 UUID 是 `我爱🍉老师1314` 的 UUID 映射)
其映射标准在 [VLESS UUID 映射标准:将自定义字符串映射为一个 UUIDv5](https://github.com/XTLS/Xray-core/issues/158)
你可以使用命令 `xray uuid -i "自定义字符串"` 生成自定义字符串所映射的的 UUID, 也可以使用命令 `xray uuid` 生成随机的 UUID。
> `alterId`number
为了进一步防止被探测,一个用户可以在主 ID 的基础上,再额外生成多个 ID。这里只需要指定额外的 ID 的数量,推荐值为 0 代表启用 VMessAEAD。
最大值 65535。这个值不能超过服务器端所指定的值。
不指定的话,默认值是 0。
::: tip
客户端 AlterID 设置为 0 代表启用 VMessAEAD ;服务端为自动适配,可同时兼容启用和未开启 VMessAEAD 的客户端。
客户端可通过设置环境变量 `Xray_VMESS_AEAD_DISABLED=true` 强行禁用 VMessAEAD
:::
> `level`: number
用户等级,连接会使用这个用户等级对应的 [本地策略](../policy.md#levelpolicyobject)。
level 的值, 对应 [policy](../policy.md#policyobject) 中 `level` 的值。 如不指定, 默认为 0。
> `security`: "aes-128-gcm" | "chacha20-poly1305" | "auto" | "none" | "zero"
加密方式,客户端将使用配置的加密方式发送数据,服务器端自动识别,无需配置。
- `"aes-128-gcm"`:推荐在 PC 上使用
- `"chacha20-poly1305"`:推荐在手机端使用
- `"auto"`:默认值,自动选择(运行框架为 AMD64、ARM64 或 s390x 时为 aes-128-gcm 加密方式,其他情况则为 Chacha20-Poly1305 加密方式)
- `"none"`:不加密
* `"zero"`:不加密,也不进行消息认证 (v1.4.0+)
::: tip
推荐使用`"auto"`加密方式,这样可以永久保证安全性和兼容性。
`"none"` 伪加密方式会计算并验证数据包的校验数据,由于认证算法没有硬件支持,在部分平台可能速度比有硬件加速的 `"aes-128-gcm"` 还慢。
`"zero"` 伪加密方式不会加密消息也不会计算数据的校验数据,因此理论上速度会高于其他任何加密方式。实际速度可能受到其他因素影响。
不推荐在未开启 TLS 加密并强制校验证书的情况下使用 `"none"` `"zero"` 伪加密方式。
如果使用 CDN 或其他会解密 TLS 的中转平台或网络环境建立连接,不建议使用 `"none"` `"zero"` 伪加密方式。
无论使用哪种加密方式, VMess 的包头都会受到加密和认证的保护。
:::

122
docs/en/config/policy.md Normal file
View file

@ -0,0 +1,122 @@
# 本地策略
本地策略可以设置不同的用户等级和对应的策略设置比如连接超时设置。Xray 处理的每一个连接都对应一个用户按照用户的等级level应用不同的策略。
## PolicyObject
`PolicyObject` 对应配置文件的 `policy` 项。
```json
{
"policy": {
"levels": {
"0": {
"handshake": 4,
"connIdle": 300,
"uplinkOnly": 2,
"downlinkOnly": 5,
"statsUserUplink": false,
"statsUserDownlink": false,
"bufferSize": 4
}
},
"system": {
"statsInboundUplink": false,
"statsInboundDownlink": false,
"statsOutboundUplink": false,
"statsOutboundDownlink": false
}
}
}
```
> `level`: map{string: [LevelPolicyObject](#levelpolicyobject)}
一组键值对每个键是一个字符串形式的数字JSON 的要求),比如 `"0"``"1"` 等,双引号不能省略,此数字对应用户等级。每一个值是一个 [LevelPolicyObject](#levelpolicyobject).
::: tip
每个入站出站代理现在都可以设置用户等级Xray 会根据实际的用户等级应用不同的本地策略。
:::
> `system`: [SystemPolicyObject](#systempolicyobject)
Xray 系统级别的策略
### LevelPolicyObject
```json
{
"handshake": 4,
"connIdle": 300,
"uplinkOnly": 2,
"downlinkOnly": 5,
"statsUserUplink": false,
"statsUserDownlink": false,
"bufferSize": 10240
}
```
> `handshake`: number
连接建立时的握手时间限制。单位为秒。默认值为 `4`。在入站代理处理一个新连接时,在握手阶段如果使用的时间超过这个时间,则中断该连接。
> `connIdle`: number
连接空闲的时间限制。单位为秒。默认值为 `300`。inbound/outbound 处理一个连接时,如果在 `connIdle` 时间内,没有任何数据被传输(包括上行和下行数据),则中断该连接。
> `uplinkOnly`: number
当连接下行线路关闭后的时间限制。单位为秒。默认值为 `2`。当服务器(如远端网站)关闭下行连接时,出站代理会在等待 `uplinkOnly` 时间后中断连接。
> `downlinkOnly`: number
当连接上行线路关闭后的时间限制。单位为秒。默认值为 `5`。当客户端(如浏览器)关闭上行连接时,入站代理会在等待 `downlinkOnly` 时间后中断连接。
::: tip
在 HTTP 浏览的场景中,可以将 `uplinkOnly``downlinkOnly` 设为 `0`,以提高连接关闭的效率。
:::
> `statsUserUplink`: true | false
当值为 `true` 时,开启当前等级的所有用户的上行流量统计。
> `statsUserDownlink`: true | false
当值为 `true` 时,开启当前等级的所有用户的下行流量统计。
> `bufferSize`: number
每个连接的内部缓存大小。单位为 kB。当值为 `0` 时,内部缓存被禁用。
默认值:
- 在 ARM、MIPS、MIPSLE 平台上,默认值为 `0`
- 在 ARM64、MIPS64、MIPS64LE 平台上,默认值为 `4`
- 在其它平台上,默认值为 `512`
### SystemPolicyObject
```json
{
"statsInboundUplink": false,
"statsInboundDownlink": false,
"statsOutboundUplink": false,
"statsOutboundDownlink": false
}
```
> `statsInboundUplink`: true | false
当值为 `true` 时,开启所有入站代理的上行流量统计。
> `statsInboundDownlink`: true | false
当值为 `true` 时,开启所有入站代理的下行流量统计。
> `statsOutboundUplink`: true | false
当值为 `true` 时,开启所有出站代理的上行流量统计。
> `statsOutboundDownlink`: true | false
当值为 `true` 时,开启所有出站代理的下行流量统计。

230
docs/en/config/reverse.md Normal file
View file

@ -0,0 +1,230 @@
# 反向代理
反向代理可以把服务器端的流量向客户端转发,即逆向流量转发。
反向代理的大致工作原理如下:
- 假设在主机 A 中有一个网页服务器,这台主机没有公网 IP无法在公网上直接访问。另有一台主机 B它可以由公网访问。现在我们需要把 B 作为入口,把流量从 B 转发到 A。
- 在主机 A 中配置 Xray称为`bridge`,在 B 中也配置 Xray称为 `portal`
- `bridge` 会向 `portal` 主动建立连接,此连接的目标地址可以自行设定。`portal` 会收到两种连接,一是由 `bridge` 发来的连接,二是公网用户发来的连接。`portal` 会自动将两类连接合并。于是 `bridge` 就可以收到公网流量了。
- `bridge` 在收到公网流量之后,会将其原封不动地发给主机 A 中的网页服务器。当然,这一步需要路由的协作。
- `bridge` 会根据流量的大小进行动态的负载均衡。
::: tip
反向代理默认已开启 [Mux](../../development/protocols/muxcool/),请不要在其用到的 outbound 上再次开启 Mux。
:::
::: warning
反向代理功能尚处于测试阶段,可能会有一些问题。
:::
## ReverseObject
`ReverseObject` 对应配置文件的 `reverse` 项。
```json
{
"reverse": {
"bridges": [
{
"tag": "bridge",
"domain": "test.xray.com"
}
],
"portals": [
{
"tag": "portal",
"domain": "test.xray.com"
}
]
}
}
```
> `bridges`: \[[BridgeObject](#bridgeobject)\]
数组,每一项表示一个 `bridge`。每个 `bridge` 的配置是一个 [BridgeObject](#bridgeobject)。
> `portals`: \[[PortalObject](#portalobject)\]
数组,每一项表示一个 `portal`。每个 `portal` 的配置是一个 [PortalObject](#bridgeobject)。
### BridgeObject
```json
{
"tag": "bridge",
"domain": "test.xray.com"
}
```
> `tag`: string
所有由 `bridge` 发出的连接,都会带有这个标识。可以在 [路由配置](./routing.md) 中使用 `inboundTag` 进行识别。
> `domain`: string
指定一个域名,`bridge``portal` 建立的连接,都会使用这个域名进行发送。
这个域名只作为 `bridge``portal` 的通信用途,不必真实存在。
### PortalObject
```json
{
"tag": "portal",
"domain": "test.xray.com"
}
```
> `tag`: string
`portal` 的标识。在 [路由配置](./routing.md) 中使用 `outboundTag` 将流量转发到这个 `portal`
> `domain`: string
一个域名。当 `portal` 接收到流量时,如果流量的目标域名是此域名,则 `portal` 认为当前连接上 `bridge` 发来的通信连接。而其它流量则会被当成需要转发的流量。`portal` 所做的工作就是把这两类连接进行识别并拼接。
::: tip
一个 Xray 既可以作为 `bridge`,也可以作为 `portal`,也可以同时两者,以适用于不同的场景需要。
:::
## 完整配置样例
::: tip
在运行过程中,建议先启用 `bridge`,再启用 `portal`
:::
### bridge 配置
`bridge` 通常需要两个 outbound一个用于连接 `portal`,另一个用于发送实际的流量。也就是说,你需要用路由区分两种流量。
反向代理配置:
```json
{
"bridges": [
{
"tag": "bridge",
"domain": "test.xray.com"
}
]
}
```
outbound:
```json
{
"tag": "out",
"protocol": "freedom",
"settings": {
"redirect": "127.0.0.1:80" // 将所有流量转发到网页服务器
}
}
```
```json
{
"protocol": "vmess",
"settings": {
"vnext": [
{
"address": "portal 的 IP 地址",
"port": 1024,
"users": [
{
"id": "5783a3e7-e373-51cd-8642-c83782b807c5"
}
]
}
]
},
"tag": "interconn"
}
```
路由配置:
```json
{
"rules": [
{
"type": "field",
"inboundTag": ["bridge"],
"domain": ["full:test.xray.com"],
"outboundTag": "interconn"
},
{
"type": "field",
"inboundTag": ["bridge"],
"outboundTag": "out"
}
]
}
```
### portal 配置
`portal` 通常需要两个 inbound一个用于接收 `bridge` 的连接,另一个用于接收实际的流量。同时你也需要用路由区分两种流量。
反向代理配置:
```json
{
"portals": [
{
"tag": "portal",
"domain": "test.xray.com" // 必须和 bridge 的配置一样
}
]
}
```
inbound:
```json
{
"tag": "external",
"port": 80,
"protocol": "dokodemo-door",
"settings": {
"address": "127.0.0.1",
"port": 80,
"network": "tcp"
}
}
```
```json
{
"port": 1024,
"tag": "interconn",
"protocol": "vmess",
"settings": {
"clients": [
{
"id": "5783a3e7-e373-51cd-8642-c83782b807c5"
}
]
}
}
```
路由配置:
```json
{
"rules": [
{
"type": "field",
"inboundTag": ["external"],
"outboundTag": "portal"
},
{
"type": "field",
"inboundTag": ["interconn"],
"outboundTag": "portal"
}
]
}
```

205
docs/en/config/routing.md Normal file
View file

@ -0,0 +1,205 @@
# 路由
路由功能模块可以将入站数据按不同规则由不同的出站连接发出,以达到按需代理的目的。
如常见用法是分流国内外流量Xray 可以通过内部机制判断不同地区的流量,然后将它们发送到不同的出站代理。
## RoutingObject
`RoutingObject` 对应配置文件的 `routing` 项。
```json
{
"routing": {
"domainStrategy": "AsIs",
"rules": [],
"balancers": []
}
}
```
> `domainStrategy`: "AsIs" | "IPIfNonMatch" | "IPOnDemand"
域名解析策略,根据不同的设置使用不同的策略。
- `"AsIs"`:只使用域名进行路由选择。默认值。
- `"IPIfNonMatch"`:当域名没有匹配任何规则时,将域名解析成 IPA 记录或 AAAA 记录)再次进行匹配;
- 当一个域名有多个 A 记录时,会尝试匹配所有的 A 记录,直到其中一个与某个规则匹配为止;
- 解析后的 IP 仅在路由选择时起作用,转发的数据包中依然使用原始域名;
- `"IPOnDemand"`:当匹配时碰到任何基于 IP 的规则,将域名立即解析为 IP 进行匹配;
> `rules`: \[[RuleObject](#ruleobject)\]
对应一个数组,数组中每一项是一个规则。
对于每一个连接,路由将根据这些规则依次进行判断,当一个规则生效时,即将这个连接转发至它所指定的 `outboundTag``balancerTag`
::: tip
当没有匹配到任何规则时,流量默认由第一个 outbound 发出。
:::
> `balancers`: \[ [BalancerObject](#balancerobject) \]
一个数组,数组中每一项是一个负载均衡器的配置。
当一个规则指向一个负载均衡器时Xray 会通过此负载均衡器选出一个 outbound, 然后由它转发流量。
### RuleObject
```json
{
"type": "field",
"domain": ["baidu.com", "qq.com", "geosite:cn"],
"ip": ["0.0.0.0/8", "10.0.0.0/8", "fc00::/7", "fe80::/10", "geoip:cn"],
"port": "53,443,1000-2000",
"sourcePort": "53,443,1000-2000",
"network": "tcp",
"source": ["10.0.0.1"],
"user": ["love@xray.com"],
"inboundTag": ["tag-vmess"],
"protocol": ["http", "tls", "bittorrent"],
"attrs": "attrs[':method'] == 'GET'",
"outboundTag": "direct",
"balancerTag": "balancer"
}
```
::: danger
当多个属性同时指定时,这些属性需要**同时**满足,才可以使当前规则生效。
:::
> `type`: "field"
目前只支持`"field"`这一个选项。
> `domain`: \[string\]
一个数组,数组每一项是一个域名的匹配。有以下几种形式:
- 纯字符串:当此字符串匹配目标域名中任意部分,该规则生效。比如 "sina.com" 可以匹配 "sina.com"、"sina.com.cn" 和 "www.sina.com",但不匹配 "sina.cn"。
- 正则表达式:由 `"regexp:"` 开始,余下部分是一个正则表达式。当此正则表达式匹配目标域名时,该规则生效。例如 "regexp:\\\\.goo.\*\\\\.com\$" 匹配 "www.google.com" 或 "fonts.googleapis.com",但不匹配 "google.com"。
- 子域名(推荐):由 `"domain:"` 开始,余下部分是一个域名。当此域名是目标域名或其子域名时,该规则生效。例如 "domain:xray.com" 匹配 "www.xray.com"、"xray.com",但不匹配 "wxray.com"。
- 完整匹配:由 `"full:"` 开始,余下部分是一个域名。当此域名完整匹配目标域名时,该规则生效。例如 "full:xray.com" 匹配 "xray.com" 但不匹配 "www.xray.com"。
- 预定义域名列表:由 `"geosite:"` 开头,余下部分是一个名称,如 `geosite:google` 或者 `geosite:cn`。名称及域名列表参考 [预定义域名列表](#预定义域名列表)。
- 从文件中加载域名:形如 `"ext:file:tag"`,必须以 `ext:`(小写)开头,后面跟文件名和标签,文件存放在 [资源目录](./features/env.md#资源文件路径) 中,文件格式与 `geosite.dat` 相同,标签必须在文件中存在。
::: tip
`"ext:geoip.dat:cn"` 等价于 `"geoip:cn"`
:::
> `ip`: \[string\]
一个数组,数组内每一项代表一个 IP 范围。当某一项匹配目标 IP 时,此规则生效。有以下几种形式:
- IP形如 `"127.0.0.1"`
- [CIDR](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing):形如 `"10.0.0.0/8"`
- 预定义 IP 列表:此列表预置于每一个 Xray 的安装包中,文件名为 `geoip.dat`。使用方式形如 `"geoip:cn"`,必须以 `geoip:`(小写)开头,后面跟双字符国家代码,支持几乎所有可以上网的国家。
- 特殊值:`"geoip:private"`,包含所有私有地址,如 `127.0.0.1`
- 从文件中加载 IP形如 `"ext:file:tag"`,必须以 `ext:`(小写)开头,后面跟文件名和标签,文件存放在 [资源目录](./features/env.md#资源文件路径) 中,文件格式与 `geoip.dat` 相同标签必须在文件中存在。
> `port`number | string
目标端口范围,有三种形式:
- `"a-b"`a 和 b 均为正整数,且小于 65536。这个范围是一个前后闭合区间当目标端口落在此范围内时此规则生效。
- `a`a 为正整数,且小于 65536。当目标端口为 a 时,此规则生效。
- 以上两种形式的混合,以逗号 "," 分隔。形如:`"53,443,1000-2000"`
> `sourcePort`number | string
来源端口,有三种形式:
- `"a-b"`a 和 b 均为正整数,且小于 65536。这个范围是一个前后闭合区间当目标端口落在此范围内时此规则生效。
- `a`a 为正整数,且小于 65536。当目标端口为 a 时,此规则生效。
- 以上两种形式的混合,以逗号 "," 分隔。形如:`"53,443,1000-2000"`
> `network`: "tcp" | "udp" | "tcp,udp"
可选的值有 "tcp"、"udp" 或 "tcp,udp",当连接方式是指定的方式时,此规则生效。
> `source`: \[string\]
一个数组,数组内每一项代表一个 IP 范围,形式有 IP、CIDR、GeoIP 和从文件中加载 IP。当某一项匹配来源 IP 时,此规则生效。
> `user`: \[string\]
一个数组,数组内每一项是一个邮箱地址。当某一项匹配来源用户时,此规则生效。
> `inboundTag`: \[string\]
一个数组,数组内每一项是一个标识。当某一项匹配入站协议的标识时,此规则生效。
> `protocol`: \[ "http" | "tls" | "bittorrent" \]
一个数组,数组内每一项表示一种协议。当某一个协议匹配当前连接的协议类型时,此规则生效。
::: tip
必须开启入站代理中的 `sniffing` 选项, 才能嗅探出连接所使用的协议类型.
:::
> `attrs`: string
一段脚本,用于检测流量的属性值。当此脚本返回真值时,此规则生效。
脚本语言为 [Starlark](https://github.com/bazelbuild/starlark),它的语法是 Python 的子集。脚本接受一个全局变量 `attrs`,其中包含了流量相关的属性。
目前只有 http 入站代理会设置这一属性。
示例:
- 检测 HTTP GET`"attrs[':method'] == 'GET'"`
- 检测 HTTP Path`"attrs[':path'].startswith('/test')"`
- 检测 Content Type`"attrs['accept'].index('text/html') >= 0"`
> `outboundTag`: string
对应一个 outbound 的标识。
> `balancerTag`: string
对应一个 Balancer 的标识。
::: tip
`balancerTag``outboundTag` 须二选一。当同时指定时,`outboundTag` 生效。
:::
### BalancerObject
负载均衡器配置。当一个负载均衡器生效时,它会从指定的 outbound 中,按配置选出一个最合适的 outbound进行流量转发。
```json
{
"tag": "balancer",
"selector": []
}
```
> `tag`: string
此负载均衡器的标识,用于匹配 `RuleObject` 中的 `balancerTag`
> `selector`: \[ string \]
一个字符串数组,其中每一个字符串将用于和 outbound 标识的前缀匹配。在以下几个 outbound 标识中:`[ "a", "ab", "c", "ba" ]``"selector": ["a"]` 将匹配到 `[ "a", "ab" ]`
如果匹配到多个 outbound负载均衡器目前会从中随机选出一个作为最终的 outbound。
### 预定义域名列表
此列表预置于每一个 Xray 的安装包中,文件名为 `geosite.dat`。这个文件包含了一些常见的域名,使用方式:`geosite:filename`,如 `geosite:google` 表示对文件内符合 `google` 内包含的域名,进行路由筛选或 DNS 筛选。
常见的域名有:
- `category-ads`:包含了常见的广告域名。
- `category-ads-all`:包含了常见的广告域名,以及广告提供商的域名。
- `cn`:相当于 `geolocation-cn``tld-cn` 的合集。
- `apple`:包含了 Apple 旗下绝大部分域名。
- `google`:包含了 Google 旗下绝大部分域名。
- `microsoft`:包含了 Microsoft 旗下绝大部分域名。
- `facebook`:包含了 Facebook 旗下绝大部分域名。
- `twitter`:包含了 Twitter 旗下绝大部分域名。
- `telegram`:包含了 Telegram 旗下绝大部分域名。
- `geolocation-cn`:包含了常见的大陆站点域名。
- `geolocation-!cn`:包含了常见的非大陆站点域名,同时包含了 `tld-!cn`
- `tld-cn`:包含了 CNNIC 管理的用于中国大陆的顶级域名,如以 `.cn``.中国` 结尾的域名。
- `tld-!cn`:包含了非中国大陆使用的顶级域名,如以 `.hk`(香港)、`.tw`(台湾)、`.jp`(日本)、`.sg`(新加坡)、`.us`(美国)`.ca`(加拿大)等结尾的域名。

55
docs/en/config/stats.md Normal file
View file

@ -0,0 +1,55 @@
# 统计信息
用于配置 Xray 流量数据的统计。
## StatsObject
`StatsObject` 对应配置文件的 `stats` 项。
```json
{
"stats": {}
}
```
目前统计信息不需要任何参数,只要 `StatsObject` 项存在,内部的统计即会开启。
开启了统计以后, 只需在 [Policy](./policy.md) 中开启对应的项,就可以统计对应的数据。
## 获取统计信息
可以用 `xray api` 的相关命令获取统计信息.
目前已有的统计信息如下:
- 用户数据
- `user>>>[email]>>>traffic>>>uplink`
特定用户的上行流量,单位字节。
- `user>>>[email]>>>traffic>>>downlink`
特定用户的下行流量,单位字节。
::: tip
如果对应用户没有指定 Email则不会开启统计。
:::
- 全局数据
- `inbound>>>[tag]>>>traffic>>>uplink`
特定 inbound 的上行流量,单位字节。
- `inbound>>>[tag]>>>traffic>>>downlink`
特定 inbound 的下行流量,单位字节。
- `outbound>>>[tag]>>>traffic>>>uplink`
特定 outbound 的上行流量,单位字节。
- `outbound>>>[tag]>>>traffic>>>downlink`
特定 outbound 的下行流量,单位字节。

470
docs/en/config/transport.md Normal file
View file

@ -0,0 +1,470 @@
# 传输方式
传输方式transport是当前 Xray 节点和其它节点对接的方式。
传输方式指定了稳定的数据传输的方式。通常来说,一个网络连接的两端需要有对称的传输方式。比如一端用了 WebSocket那么另一个端也必须使用 WebSocket否则无法建立连接。
传输方式transport配置有两部分:
1. 全局配置([TransportObject](#transportobject)
2. 局部配置([StreamSettingsObject](#streamsettingsobject))。
- 局部配置时,可以指定每个单独的入站或出站用怎样的方式传输。
- 通常来说客户端和服务器对应的入站和出站需要使用同样的传输方式。当其配置指定了一种传输方式,但没有填写具体设置时,此传输方式会使用全局配置中的设置。
## TransportObject
`TransportObject` 对应配置文件的 `transport` 项。
```json
{
"transport": {
"tcpSettings": {},
"kcpSettings": {},
"wsSettings": {},
"httpSettings": {},
"quicSettings": {},
"dsSettings": {},
"grpcSettings": {}
}
}
```
> `tcpSettings`: [TcpObject](./transports/tcp.md)
针对 TCP 连接的配置。
> `kcpSettings`: [KcpObject](./transports/mkcp.md)
针对 mKCP 连接的配置。
> `wsSettings`: [WebSocketObject](./transports/websocket.md)
针对 WebSocket 连接的配置。
> `httpSettings`: [HttpObject](./transports/h2.md)
针对 HTTP/2 连接的配置。
> `quicSettings`: [QuicObject](./transports/quic.md)
针对 QUIC 连接的配置。
> `grpcSettings`: [GRPCObject](./transports/grpc.md)
针对 gRPC 连接的配置。
> `dsSettings`: [DomainSocketObject](./transports/domainsocket.md)
针对 Domain Socket 连接的配置。
## StreamSettingsObject
`StreamSettingsObject` 对应入站或出站中的 `streamSettings` 项。每一个入站或出站都可以分别配置不同的传输配置,都可以设置 `streamSettings` 来进行一些传输的配置。
```json
{
"network": "tcp",
"security": "none",
"tlsSettings": {},
"xtlsSettings": {},
"tcpSettings": {},
"kcpSettings": {},
"wsSettings": {},
"httpSettings": {},
"quicSettings": {},
"dsSettings": {},
"grpcSettings": {},
"sockopt": {
"mark": 0,
"tcpFastOpen": false,
"tproxy": "off",
"domainStrategy": "AsIs",
"dialerProxy": "",
"acceptProxyProtocol": false
}
}
```
> `network`: "tcp" | "kcp" | "ws" | "http" | "domainsocket" | "quic"
连接的数据流所使用的传输方式类型,默认值为 `"tcp"`
> `security`: "none" | "tls" | "xtls"
是否启用传输层加密,支持的选项有
- `"none"` 表示不加密(默认值)
- `"tls"` 表示使用 [TLS](https://en.wikipedia.org/wiki/base/transport_Layer_Security)。
- `"xtls"` 表示使用 [XTLS](./features/xtls.md)。
> `tlsSettings`: [TLSObject](#tlsobject)
TLS 配置。TLS 由 Golang 提供,通常情况下 TLS 协商的结果为使用 TLS 1.3,不支持 DTLS。
> `xtlsSettings`: [XTLSObject](#tlsobject)
XTLS 配置。XTLS 是 Xray 的原创黑科技, 也是使 Xray 性能一骑绝尘的核心动力。 XTLS 与 TLS 有相同的安全性, 配置方式也和 TLS 一致.
点击此处查看 [XTLS 的技术细节剖析](./features/xtls.md)
::: tip
TLS / XTLS 是目前最安全的传输加密方案, 且外部看来流量类型和正常上网具有一致性。 启用 XTLS 并且配置合适的 XTLS 流控模式, 可以在保持和 TLS 相同的安全性的前提下,
性能达到数倍甚至十几倍的提升。 当 `security` 的值从 `tls` 改为 `xtls` 时, 只需将 `tlsSettings` 修改成为 `xtlsSettings`
:::
> `tcpSettings`: [TcpObject](./transports/tcp.md)
当前连接的 TCP 配置,仅当此连接使用 TCP 时有效。配置内容与上面的全局配置相同。
> `kcpSettings`: [KcpObject](./transports/mkcp.md)
当前连接的 mKCP 配置,仅当此连接使用 mKCP 时有效。配置内容与上面的全局配置相同。
> `wsSettings`: [WebSocketObject](./transports/websocket.md)
当前连接的 WebSocket 配置,仅当此连接使用 WebSocket 时有效。配置内容与上面的全局配置相同。
> `httpSettings`: [HttpObject](./transports/h2.md)
当前连接的 HTTP/2 配置,仅当此连接使用 HTTP/2 时有效。配置内容与上面的全局配置相同。
> `quicSettings`: [QUICObject](./transports/quic.md)
当前连接的 QUIC 配置,仅当此连接使用 QUIC 时有效。配置内容与上面的全局配置相同。
> `grpcSettings`: [GRPCObject](./transports/grpc.md)
当前连接的 gRPC 配置,仅当此连接使用 gRPC 时有效。配置内容与上面的全局配置相同。
> `dsSettings`: [DomainSocketObject](./transports/domainsocket.md)
当前连接的 Domain socket 配置,仅当此连接使用 Domain socket 时有效。配置内容与上面的全局配置相同。
> `sockopt`: [SockoptObject](#sockoptobject)
透明代理相关的具体配置。
### TLSObject
```json
{
"serverName": "xray.com",
"allowInsecure": false,
"alpn": ["h2", "http/1.1"],
"minVersion": "1.2",
"maxVersion": "1.3",
"preferServerCipherSuites": true,
"cipherSuites": "此处填写你需要的加密套件名称,每个套件名称之间用:进行分隔",
"certificates": [],
"disableSystemRoot": false,
"enableSessionResumption": false,
"fingerprint": ""
}
```
> `serverName`: string
指定服务器端证书的域名,在连接由 IP 建立时有用。
当目标连接由域名指定时,比如在 Socks 入站接收到了域名,或者由 Sniffing 功能探测出了域名,这个域名会自动用于 `serverName`,无须手动配置。
> `alpn`: \[ string \]
一个字符串数组,指定了 TLS 握手时指定的 ALPN 数值。默认值为 `["h2", "http/1.1"]`
> `minVersion`: \[ string \]
minVersion 为可接受的最小 SSL/TLS 版本。
> `maxVersion`: \[ string \]
maxVersion 为可接受的最大 SSL/TLS 版本。
> `preferServerCipherSuites`: true | false
指示服务器选择客户端最喜欢的密码套件 或 服务器最优选的密码套件。
如果为 true 则为使用服务器的最优选的密码套件
> `cipherSuites`: \[ string \]
CipherSuites 用于配置受支持的密码套件列表, 每个套件名称之间用:进行分隔.
你可以在 [这里](https://golang.org/src/crypto/tls/cipher_suites.go#L500)或 [这里](https://golang.org/src/crypto/tls/cipher_suites.go#L44)
找到 golang 加密套件的名词和说明
::: danger
以上两项配置为非必要选项,正常情况下不影响安全性 在未配置的情况下 golang 根据设备自动选择. 若不熟悉, 请勿配置此选项, 填写不当引起的问题自行负责
:::
> `allowInsecure`: true | false
是否允许不安全连接(仅用于客户端)。默认值为 `false`
当值为 `true`Xray 不会检查远端主机所提供的 TLS 证书的有效性。
::: danger
出于安全性考虑,这个选项不应该在实际场景中选择 true否则可能遭受中间人攻击。
:::
> `disableSystemRoot`: true | false
是否禁用操作系统自带的 CA 证书。默认值为 `false`
当值为 `true`Xray 只会使用 `certificates` 中指定的证书进行 TLS 握手。当值为 `false`Xray 只会使用操作系统自带的 CA 证书进行 TLS 握手。
> `enableSessionResumption`: true | false
此参数的设置为 false 时, ClientHello 里没有 session_ticket 这个扩展。 通常来讲 go 语言程序的 ClientHello 里并没有用到这个扩展, 因此建议保持默认值。 默认值为 `false`
> `fingerprint` : "" | "chrome" | "firefox" | "safari" | "randomized"
此参数用于配置指定 `TLS Client Hello` 的指纹。当其值为空时表示不启用此功能。启用后Xray 将通过 uTLS 库 **模拟** `TLS` 指纹,或随机生成。
::: tip
此功能仅 **模拟** `TLS Client Hello` 的指纹,行为、其他指纹与 Golang 相同。如果你希望更加完整地模拟浏览器 `TLS`
指纹与行为,可以使用 [Browser Dialer](./transports/websocket.md#browser-dialer)。
:::
- `"chrome" | "firefox" | "safari"`: 模拟 Chrome / Firefox / Safari 的 TLS 指纹
- `"randomized"`: 使用随机指纹
> `certificates`: \[ [CertificateObject](#certificateobject) \]
证书列表,其中每一项表示一个证书(建议 fullchain
::: tip
如果要在 ssllibs 或者 myssl 获得 A/A+ 等级的评价,
请参考 [这里](https://github.com/XTLS/Xray-core/discussions/56#discussioncomment-215600).
:::
#### CertificateObject
```json
{
"ocspStapling": 3600,
"usage": "encipherment",
"certificateFile": "/path/to/certificate.crt",
"keyFile": "/path/to/key.key",
"certificate": [
"--BEGIN CERTIFICATE--",
"MIICwDCCAaigAwIBAgIRAO16JMdESAuHidFYJAR/7kAwDQYJKoZIhvcNAQELBQAw",
"ADAeFw0xODA0MTAxMzU1MTdaFw0xODA0MTAxNTU1MTdaMAAwggEiMA0GCSqGSIb3",
"DQEBAQUAA4IBDwAwggEKAoIBAQCs2PX0fFSCjOemmdm9UbOvcLctF94Ox4BpSfJ+",
"3lJHwZbvnOFuo56WhQJWrclKoImp/c9veL1J4Bbtam3sW3APkZVEK9UxRQ57HQuw",
"OzhV0FD20/0YELou85TwnkTw5l9GVCXT02NG+pGlYsFrxesUHpojdl8tIcn113M5",
"pypgDPVmPeeORRf7nseMC6GhvXYM4txJPyenohwegl8DZ6OE5FkSVR5wFQtAhbON",
"OAkIVVmw002K2J6pitPuJGOka9PxcCVWhko/W+JCGapcC7O74palwBUuXE1iH+Jp",
"noPjGp4qE2ognW3WH/sgQ+rvo20eXb9Um1steaYY8xlxgBsXAgMBAAGjNTAzMA4G",
"A1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAA",
"MA0GCSqGSIb3DQEBCwUAA4IBAQBUd9sGKYemzwPnxtw/vzkV8Q32NILEMlPVqeJU",
"7UxVgIODBV6A1b3tOUoktuhmgSSaQxjhYbFAVTD+LUglMUCxNbj56luBRlLLQWo+",
"9BUhC/ow393tLmqKcB59qNcwbZER6XT5POYwcaKM75QVqhCJVHJNb1zSEE7Co7iO",
"6wIan3lFyjBfYlBEz5vyRWQNIwKfdh5cK1yAu13xGENwmtlSTHiwbjBLXfk+0A/8",
"r/2s+sCYUkGZHhj8xY7bJ1zg0FRalP5LrqY+r6BckT1QPDIQKYy615j1LpOtwZe/",
"d4q7MD/dkzRDsch7t2cIjM/PYeMuzh87admSyL6hdtK0Nm/Q",
"--END CERTIFICATE--"
],
"key": [
"--BEGIN RSA PRIVATE KEY--",
"MIIEowIBAAKCAQEArNj19HxUgoznppnZvVGzr3C3LRfeDseAaUnyft5SR8GW75zh",
"bqOeloUCVq3JSqCJqf3Pb3i9SeAW7Wpt7FtwD5GVRCvVMUUOex0LsDs4VdBQ9tP9",
"GBC6LvOU8J5E8OZfRlQl09NjRvqRpWLBa8XrFB6aI3ZfLSHJ9ddzOacqYAz1Zj3n",
"jkUX+57HjAuhob12DOLcST8np6IcHoJfA2ejhORZElUecBULQIWzjTgJCFVZsNNN",
"itieqYrT7iRjpGvT8XAlVoZKP1viQhmqXAuzu+KWpcAVLlxNYh/iaZ6D4xqeKhNq",
"IJ1t1h/7IEPq76NtHl2/VJtbLXmmGPMZcYAbFwIDAQABAoIBAFCgG4phfGIxK9Uw",
"qrp+o9xQLYGhQnmOYb27OpwnRCYojSlT+mvLcqwvevnHsr9WxyA+PkZ3AYS2PLue",
"C4xW0pzQgdn8wENtPOX8lHkuBocw1rNsCwDwvIguIuliSjI8o3CAy+xVDFgNhWap",
"/CMzfQYziB7GlnrM6hH838iiy0dlv4I/HKk+3/YlSYQEvnFokTf7HxbDDmznkJTM",
"aPKZ5qbnV+4AcQfcLYJ8QE0ViJ8dVZ7RLwIf7+SG0b0bqloti4+oQXqGtiESUwEW",
"/Wzi7oyCbFJoPsFWp1P5+wD7jAGpAd9lPIwPahdr1wl6VwIx9W0XYjoZn71AEaw4",
"bK4xUXECgYEA3g2o9WqyrhYSax3pGEdvV2qN0VQhw7Xe+jyy98CELOO2DNbB9QNJ",
"8cSSU/PjkxQlgbOJc8DEprdMldN5xI/srlsbQWCj72wXxXnVnh991bI2clwt7oYi",
"pcGZwzCrJyFL+QaZmYzLxkxYl1tCiiuqLm+EkjxCWKTX/kKEFb6rtnMCgYEAx0WR",
"L8Uue3lXxhXRdBS5QRTBNklkSxtU+2yyXRpvFa7Qam+GghJs5RKfJ9lTvjfM/PxG",
"3vhuBliWQOKQbm1ZGLbgGBM505EOP7DikUmH/kzKxIeRo4l64mioKdDwK/4CZtS7",
"az0Lq3eS6bq11qL4mEdE6Gn/Y+sqB83GHZYju80CgYABFm4KbbBcW+1RKv9WSBtK",
"gVIagV/89moWLa/uuLmtApyEqZSfn5mAHqdc0+f8c2/Pl9KHh50u99zfKv8AsHfH",
"TtjuVAvZg10GcZdTQ/I41ruficYL0gpfZ3haVWWxNl+J47di4iapXPxeGWtVA+u8",
"eH1cvgDRMFWCgE7nUFzE8wKBgGndUomfZtdgGrp4ouLZk6W4ogD2MpsYNSixkXyW",
"64cIbV7uSvZVVZbJMtaXxb6bpIKOgBQ6xTEH5SMpenPAEgJoPVts816rhHdfwK5Q",
"8zetklegckYAZtFbqmM0xjOI6bu5rqwFLWr1xo33jF0wDYPQ8RHMJkruB1FIB8V2",
"GxvNAoGBAM4g2z8NTPMqX+8IBGkGgqmcYuRQxd3cs7LOSEjF9hPy1it2ZFe/yUKq",
"ePa2E8osffK5LBkFzhyQb0WrGC9ijM9E6rv10gyuNjlwXdFJcdqVamxwPUBtxRJR",
"cYTY2HRkJXDdtT0Bkc3josE6UUDvwMpO0CfAETQPto1tjNEDhQhT",
"--END RSA PRIVATE KEY--"
]
}
```
> `ocspStapling`: number
ocspStapling 检查更新时间间隔。 单位:秒
> `usage`: "encipherment" | "verify" | "issue"
证书用途,默认值为 `"encipherment"`
- `"encipherment"`:证书用于 TLS 认证和加密。
- `"verify"`:证书用于验证远端 TLS 的证书。当使用此项时,当前证书必须为 CA 证书。
- `"issue"`:证书用于签发其它证书。当使用此项时,当前证书必须为 CA 证书。
::: tip TIP 1
在 Windows 平台上可以将自签名的 CA 证书安装到系统中,即可验证远端 TLS 的证书。
:::
::: tip TIP 2
当有新的客户端请求时,假设所指定的 `serverName``"xray.com"`Xray 会先从证书列表中寻找可用于 `"xray.com"` 的证书,如果没有找到,则使用任一 `usage`
`"issue"` 的证书签发一个适用于 `"xray.com"` 的证书,有效期为一小时。并将新的证书加入证书列表,以供后续使用。
:::
::: tip TIP 3
`certificateFile``certificate` 同时指定时Xray 优先使用 `certificateFile``keyFile``key` 也一样。
:::
::: tip TIP 4
`usage``"verify"` 时,`keyFile``key` 可均为空。
:::
::: tip TIP 5
使用 `xray tls cert` 可以生成自签名的 CA 证书。
:::
::: tip TIP 6
如已经拥有一个域名, 可以使用工具便捷的获取免费第三方证书,如[acme.sh](https://github.com/acmesh-official/acme.sh)
:::
> `certificateFile`: string
证书文件路径,如使用 OpenSSL 生成,后缀名为 .crt。
> `certificate`: \[ string \]
一个字符串数组,表示证书内容,格式如样例所示。`certificate``certificateFile` 二者选一。
> `keyFile`: string
密钥文件路径,如使用 OpenSSL 生成,后缀名为 .key。目前暂不支持需要密码的 key 文件。
> `key`: \[ string \]
一个字符串数组,表示密钥内容,格式如样例如示。`key``keyFile` 二者选一。
### SockoptObject
```json
{
"mark": 0,
"tcpFastOpen": false,
"tproxy": "off",
"domainStrategy": "AsIs",
"dialerProxy": "",
"acceptProxyProtocol": false
}
```
> `mark`: number
一个整数。当其值非零时,在 ountbound 连接以此数值上标记 SO_MARK。
- 仅适用于 Linux 系统。
- 需要 CAP_NET_ADMIN 权限。
> `tcpFastOpen`: true | false | number
是否启用 [TCP Fast Open](https://zh.wikipedia.org/wiki/TCP%E5%BF%AB%E9%80%9F%E6%89%93%E5%BC%80)。
当其值为 `true``正整数`时,启用 TFO当其值为 `false``负数`时,强制关闭 TFO当此项不存在或为 `0` 时,使用系统默认设置。 可用于 inbound/outbound。
- 仅在以下版本(或更新版本)的操作系统中可用:
- Windows 10 (1607)
- Mac OS 10.11 / iOS 9
- Linux 3.16:需要通过内核参数 `net.ipv4.tcp_fastopen` 进行设定,此参数是一个 bitmap`0x1` 代表客户端允许启用,`0x2` 代表服务器允许启用;默认值为 `0x1`,如果服务器要启用
TFO请把此内核参数值设为 `0x3`
- FreeBSD 10.3 (Server) / 12.0 (Client):需要把内核参数 `net.inet.tcp.fastopen.server_enabled`
以及 `net.inet.tcp.fastopen.client_enabled` 设为 `1`
- 对于 Inbound此处所设定的`正整数`代表 [待处理的 TFO 连接请求数上限](https://tools.ietf.org/html/rfc7413#section-5.1) **注意并非所有操作系统都支持在此设定**
- Linux / FreeBSD此处的设定的`正整数`值代表上限,可接受的最大值为 2147483647`true` 时将取 `256`;注意在 Linux`net.core.somaxconn`
会限制此值的上限,如果超过了 `somaxconn`,请同时提高 `somaxconn`
- Mac OS此处为 `true``正整数`时,仅代表启用 TFO上限需要通过内核参数 `net.inet.tcp.fastopen_backlog` 单独设定。
- Windows此处为 `true``正整数`时,仅代表启用 TFO。
- 对于 Outbound设定为 `true``正整数`在任何操作系统都仅表示启用 TFO。
> `tproxy`: "redirect" | "tproxy" | "off"
是否开启透明代理(仅适用于 Linux
- `"redirect"`:使用 Redirect 模式的透明代理。支持所有基于 IPv4/6 的 TCP 和 UDP 连接。
- `"tproxy"`:使用 TProxy 模式的透明代理。支持所有基于 IPv4/6 的 TCP 和 UDP 连接。
- `"off"`:关闭透明代理。
透明代理需要 Root 或 `CAP\_NET\_ADMIN` 权限。
::: danger
当 [Dokodemo-door](./inbounds/dokodemo.md) 中指定了 `followRedirect``true`,且 Sockopt 设置中的`tproxy` 为空时Sockopt
设置中的`tproxy` 的值会被设为 `"redirect"`
:::
> `domainStrategy`: "AsIs" | "UseIP" | "UseIPv4" | "UseIPv6"
在之前的版本中,当 Xray 尝试使用域名建立系统连接时,域名的解析由系统完成,不受 Xray
控制。这导致了在 [非标准 Linux 环境中无法解析域名](https://github.com/v2ray/v2ray-core/issues/1909) 等问题。为此Xray 1.3.1 为 Sockopt 引入了 Freedom
中的 domainStrategy解决了此问题。
在目标地址为域名时, 配置相应的值, SystemDialer 的行为模式如下:
- `"AsIs"`: 通过系统 DNS 服务器解析获取 IP, 向此域名发出连接。
- `"UseIP"``"UseIPv4"``"UseIPv6"`: 使用[内置 DNS 服务器](./dns.md)解析获取 IP 后, 直接向此 IP 发出连接。
默认值为 `"AsIs"`
::: danger
启用了此功能后,不当的配置可能会导致死循环。
一句话版本:连接到服务器,需要等待 DNS 查询结果;完成 DNS 查询,需要连接到服务器。
> Tony: 先有鸡还是先有蛋?
详细解释:
1. 触发条件代理服务器proxy.com。内置 DNS 服务器,非 Local 模式。
2. Xray 尝试向 proxy.com 建立 TCP 连接 **前** ,通过内置 DNS 服务器查询 proxy.com。
3. 内置 DNS 服务器向 dns.com 建立连接,并发送查询,以获取 proxy.com 的 IP。
4. **不当的** 的路由规则,导致 proxy.com 代理了步骤 3 中发出的查询。
5. Xray 尝试向 proxy.com 建立另一个 TCP 连接。
6. 在建立连接前,通过内置 DNS 服务器查询 proxy.com。
7. 内置 DNS 服务器复用步骤 3 中的连接,发出查询。
8. 问题出现。步骤 3 中连接的建立,需要等待步骤 7 中的查询结果;步骤 7 完成查询,需要等待步骤 3 中的连接完全建立。
9. Good Game
解决方案:
- 改内置 DNS 服务器的分流。
- 用 Hosts。
- ~~如果你还是不知道解决方案,就别用这个功能了。~~
因此,**不建议** 经验不足的用户擅自使用此功能。
:::
> `dialerProxy`: ""
一个出站代理的标识。当值不为空时,将使用指定的 outbound 发出连接。 此选项可用于支持底层传输方式的链式转发。
::: danger
此选项与 PorxySettingsObject.Tag 不兼容
:::
> `acceptProxyProtocol`: true | false
仅用于 inbound指示是否接收 PROXY protocol。
[PROXY protocol](https://www.haproxy.org/download/2.2/doc/proxy-protocol.txt) 专用于传递请求的真实来源 IP 和端口,**若你不了解它,请先忽略该项**。
常见的反代软件(如 HAProxy、Nginx都可以配置发送它VLESS fallbacks xver 也可以发送它。
填写 `true` 时,最底层 TCP 连接建立后,请求方必须先发送 PROXY protocol v1 或 v2否则连接会被关闭。

View file

@ -0,0 +1,33 @@
# 传输方式列表
这个章节包含了目前所有的传输方式及相关的具体配置.
## 传输方式列表
> `tcpSettings`: [TcpObject](./tcp.md)
针对 TCP 连接的配置。
> `wsSettings`: [WebSocketObject](./websocket.md)
针对 WebSocket 连接的配置。
> `dsSettings`: [DomainSocketObject](./domainsocket.md)
针对 Domain Socket 连接的配置。
> `kcpSettings`: [KcpObject](./mkcp.md)
针对 mKCP 连接的配置。
> `httpSettings`: [HttpObject](./h2.md)
针对 HTTP/2 连接的配置。
> `quicSettings`: [QuicObject](./quic.md)
针对 QUIC 连接的配置。
> `grpcSettings`: [GRPCObject](./grpc.md)
针对 gRPC 连接的配置。

View file

@ -0,0 +1,43 @@
# Domain Socket
::: danger
推荐写到 [inbounds](../inbound.md) 的 `listen` 处,传输方式可选 TCP、WebSocket、HTTP/2.
未来这里的 DomainSocket 可能会被弃用。
:::
Domain Socket 使用标准的 Unix domain socket 来传输数据。
它的优势是使用了操作系统内建的传输通道,而不会占用网络缓存。
理论上相比起本地环回网络local loopback来说Domain socket 速度略快一些。
目前仅可用于支持 Unix domain socket 的平台,如 Linux 和 macOS。在 Windows 10 Build 17036 前不可用。
如果指定了 domain socket 作为传输方式,在入站出站代理中配置的端口和 IP 地址将会失效,所有的传输由 domain socket 取代。
## DomainSocketObject
`DomainSocketObject` 对应传输配置的 `dsSettings` 项。
```json
{
"path": "/path/to/ds/file",
"abstract": false,
"padding": false
}
```
> `path`: string
一个合法的文件路径。
::: danger
在运行 Xray 之前,这个文件必须不存在。
:::
> `abstract`: true | false
是否为 abstract domain socket默认值 `false`
> `padding`: true | false
abstract domain socket 是否带 padding默认值 `false`

View file

@ -0,0 +1,51 @@
# gRPC
基于 gRPC 的传输方式。
它基于 HTTP/2 协议,理论上可以通过其它支持 HTTP/2 的服务器(如 Nginx进行中转。
gRPCHTTP/2内置多路复用不建议使用 gRPC 与 HTTP/2 时启用 mux.cool。
::: warning ⚠⚠⚠
- gRPC 不支持指定 Host。请在出站代理地址中填写 **正确的域名** ,或在 `(x)tlsSettings` 中填写 `ServerName`,否则无法连接。
- gRPC 不支持回落到其他服务。
- gRPC 服务存在被主动探测的风险。建议使用 Caddy 或 Nginx 等反向代理工具,通过 Path 前置分流。
:::
::: tip
如果您使用 Caddy 或 Nginx 等反向代理,请注意下列事项:
- 请确定反向代理服务器开启了 HTTP/2
- 请使用 HTTP/2 或 h2c (Caddy)grpc_pass (Nginx) 连接到 Xray。
- 普通模式的 Path 为 `/${serviceName}/Tun`, Multi 模式为 `/${serviceName}/TunMulti`
:::
::: tip
如果你正在使用回落,请注意下列事项:
- 不建议回落到 gRPC存在被主动探测的风险。
- 请确认`h2` 位于 (x)tlsSettings.alpn 中的第一顺位,否则 gRPCHTTP/2可能无法完成 TLS 握手。
- gRPC 无法通过进行 Path 分流。
:::
## GRPCObject
`GRPCObject` 对应传输配置的 `grpcSettings` 项。
```json
{
"serviceName": "name",
"multiMode": false
}
```
> `serviceName`: string
一个字符串,指定服务名称,**类似于** HTTP/2 中的 Path。
客户端会使用此名称进行通信,服务端会验证服务名称是否匹配。
> `multiMode`: bool <Badge text="BETA" type="warning"/>
一个布尔值。表示是否启用 `multiMode`
这是一个 **实验性** 选项,可能不会被长期保留,也不保证跨版本兼容。此模式在 **测试环境中** 能够带来约 20% 的性能提升,实际效果因传输速率不同而不同。

View file

@ -0,0 +1,44 @@
# HTTP/2
基于 HTTP/2 的传输方式。
它完整按照 HTTP/2 标准实现,可以通过其它的 HTTP 服务器(如 Nginx进行中转。
由 HTTP/2 的建议,客户端和服务器必须同时开启 TLS 才可以正常使用这个传输方式。
HTTP/2 内置多路复用,不建议使用 HTTP/2 时启用 mux.cool。
::: tip
当前版本的 HTTP/2 的传输方式并不强制要求服务器端有 TLS 配置.
这使得可以在特殊用途的分流部署环境中,由外部网关组件完成 TLS 层对话Xray 作为后端应用,网关和 Xray 间使用称为 `h2c` 的明文 http/2 进行通讯。
:::
::: warning
⚠️ 如果你正在使用回落,请注意下列事项:
- 请确认 (x)tlsSettings.alpn 中包含 h2否则 HTTP/2 无法完成 TLS 握手。
- HTTP/2 无法通过进行 Path 分流,建议使用 SNI 分流。
:::
## HttpObject
`HttpObject` 对应传输配置的 `httpSettings` 项。
```json
{
"host": ["xray.com"],
"path": "/random/path"
}
```
> `host`: \[string\]
一个字符串数组,每一个元素是一个域名。
客户端会随机从列表中选出一个域名进行通信,服务器会验证域名是否在列表中。
> `path` string
HTTP 路径,由 `/` 开头, 客户端和服务器必须一致。
默认值为 `"/"`

View file

@ -0,0 +1,146 @@
# mKCP
mKCP 使用 UDP 来模拟 TCP 连接。
mKCP 牺牲带宽来降低延迟。传输同样的内容mKCP 一般比 TCP 消耗更多的流量。
::: tip
请确定主机上的防火墙配置正确
:::
## KcpObject
`KcpObject` 对应传输配置的 `kcpSettings` 项。
```json
{
"mtu": 1350,
"tti": 20,
"uplinkCapacity": 5,
"downlinkCapacity": 20,
"congestion": false,
"readBufferSize": 1,
"writeBufferSize": 1,
"header": {
"type": "none"
},
"seed": "Password"
}
```
> `mtu`: number
最大传输单元maximum transmission unit
请选择一个介于 576 - 1460 之间的值。
默认值为 `1350`
> `tti`: number
传输时间间隔transmission time interval单位毫秒msmKCP 将以这个时间频率发送数据。
请选译一个介于 10 - 100 之间的值。
默认值为 `50`
> `uplinkCapacity`: number
上行链路容量,即主机发出数据所用的最大带宽,单位 MB/s注意是 Byte 而非 bit。
可以设置为 0表示一个非常小的带宽。
默认值 `5`
> `downlinkCapacity`: number
下行链路容量,即主机接收数据所用的最大带宽,单位 MB/s注意是 Byte 而非 bit。
可以设置为 0表示一个非常小的带宽。
默认值 `20`
::: tip
`uplinkCapacity``downlinkCapacity` 决定了 mKCP 的传输速度。
以客户端发送数据为例,客户端的 `uplinkCapacity` 指定了发送数据的速度,而服务器端的 `downlinkCapacity` 指定了接收数据的速度。两者的值以较小的一个为准。
推荐把 `downlinkCapacity` 设置为一个较大的值,比如 100`uplinkCapacity` 设为实际的网络速度。当速度不够时,可以逐渐增加 `uplinkCapacity` 的值,直到带宽的两倍左右。
:::
> `congestion`: true | false
是否启用拥塞控制。
开启拥塞控制之后Xray 会自动监测网络质量,当丢包严重时,会自动降低吞吐量;当网络畅通时,也会适当增加吞吐量。
默认值为 `false`
> `readBufferSize`: number
单个连接的读取缓冲区大小,单位是 MB。
默认值为 `2`
> `writeBufferSize`: number
单个连接的写入缓冲区大小,单位是 MB。
默认值为 `2`
::: tip
`readBufferSize``writeBufferSize` 指定了单个连接所使用的内存大小。
在需要高速传输时,指定较大的 `readBufferSize``writeBufferSize` 会在一定程度上提高速度,但也会使用更多的内存。
在网速不超过 20MB/s 时,默认值 1MB 可以满足需求;超过之后,可以适当增加 `readBufferSize``writeBufferSize` 的值,然后手动平衡速度和内存的关系。
:::
> `header`: [HeaderObject](#headerobject)
数据包头部伪装设置
> `seed`: string
可选的混淆密码,使用 AES-128-GCM 算法混淆流量数据,客户端和服务端需要保持一致。
本混淆机制不能用于保证通信内容的安全,但可能可以对抗部分封锁。
> 目前测试环境下开启此设置后没有出现原版未混淆版本的封端口现象
### HeaderObject
```json
{
"type": "none"
}
```
> `type`: string
伪装类型,可选的值有:
- `"none"`:默认值,不进行伪装,发送的数据是没有特征的数据包。
- `"srtp"`:伪装成 SRTP 数据包,会被识别为视频通话数据(如 FaceTime
- `"utp"`:伪装成 uTP 数据包,会被识别为 BT 下载数据。
- `"wechat-video"`:伪装成微信视频通话的数据包。
- `"dtls"`:伪装成 DTLS 1.2 数据包。
- `"wireguard"`:伪装成 WireGuard 数据包。(并不是真正的 WireGuard 协议)
## 鸣谢
- [@skywind3000](https://github.com/skywind3000) 发明并实现了 KCP 协议。
- [@xtaci](https://github.com/xtaci) 将 KCP 由 C 语言实现翻译成 Go。
- [@xiaokangwang](https://github.com/xiaokangwang) 测试 KCP 与 Xray 的整合并提交了最初的 PR。
## 对 KCP 协议的改进
### 更小的协议头
原生 KCP 协议使用了 24 字节的固定头部,而 mKCP 修改为数据包 18 字节确认ACK包 16 字节。更小的头部有助于躲避特征检查,并加快传输速度。
另外,原生 KCP 的单个确认包只能确认一个数据包已收到,也就是说当 KCP 需要确认 100 个数据已收到时,它会发出 24 \* 100 = 2400 字节的数据。其中包含了大量重复的头部数据造成带宽的浪费。mKCP 会对多个确认包进行压缩100 个确认包只需要 16 + 2 + 100 \* 4 = 418 字节,相当于原生的六分之一。
### 确认包重传
原生 KCP 协议的确认ACK包只发送一次如果确认包丢失则一定会导致数据重传造成不必要的带宽浪费。而 mKCP 会以一定的频率重发确认包,直到发送方确认为止。单个确认包的大小为 22 字节,相比起数据包的 1000 字节以上,重传确认包的代价要小得多。
### 连接状态控制
mKCP 可以有效地开启和关闭连接。当远程主机主动关闭连接时,连接会在两秒钟之内释放;当远程主机断线时,连接会在最多 30 秒内释放。
原生 KCP 不支持这个场景。

View file

@ -0,0 +1,74 @@
# QUIC
QUIC 全称 Quick UDP Internet Connection是由 Google 提出的使用 UDP 进行多路并发传输的协议。其主要优势是:
1. 减少了握手的延迟1-RTT 或 0-RTT
2. 多路复用,并且没有 TCP 的阻塞问题
3. 连接迁移,(主要是在客户端)当由 Wifi 转移到 4G 时,连接不会被断开。
QUIC 目前处于实验期,使用了正在标准化过程中的 IETF 实现,不能保证与最终版本的兼容性。
- 默认设定:
- 12 字节的 Connection ID
- 30 秒没有数据通过时自动断开连接 (可能会影响一些长连接的使用)
## QuicObject
`QuicObject` 对应传输配置的 `quicSettings` 项。
::: danger
对接的两端的配置必须完全一致,否则连接失败。
QUIC 强制要求开启 TLS在传输配置中没有开启 TLS 时Xray 会自行签发一个证书进行 TLS 通讯。
:::
```json
{
"security": "none",
"key": "",
"header": {
"type": "none"
}
}
```
> `security`: "none" | "aes-128-gcm" | "chacha20-poly1305"
加密方式。
此加密是对 QUIC 数据包的加密,加密后数据包无法被探测。
默认值为不加密。
> `key`: string
加密时所用的密钥。
可以是任意字符串。当 `security` 不为 `"none"` 时有效。
> `header`: [HeaderObject](#headerobject)
数据包头部伪装设置
### HeaderObject
```json
{
"type": "none"
}
```
> `type`: string
伪装类型,可选的值有:
- `"none"`:默认值,不进行伪装,发送的数据是没有特征的数据包。
- `"srtp"`:伪装成 SRTP 数据包,会被识别为视频通话数据(如 FaceTime
- `"utp"`:伪装成 uTP 数据包,会被识别为 BT 下载数据。
- `"wechat-video"`:伪装成微信视频通话的数据包。
- `"dtls"`:伪装成 DTLS 1.2 数据包。
- `"wireguard"`:伪装成 WireGuard 数据包。(并不是真正的 WireGuard 协议)
::: tip
当加密和伪装都不启用时,数据包即为原始的 QUIC 数据包,可以与其它的 QUIC 工具对接。
为了避免被探测,建议加密或伪装至少开启一项。
:::

View file

@ -0,0 +1,148 @@
# TCP
TCP 传输模式是目前推荐使用的传输模式之一.
可以和各种协议有多种组合模式.
## TcpObject
`TcpObject` 对应传输配置的 `tcpSettings` 项。
```json
{
"acceptProxyProtocol": false,
"header": {
"type": "none"
}
}
```
> `acceptProxyProtocol`: true | false
仅用于 inbound指示是否接收 PROXY protocol。
[PROXY protocol](https://www.haproxy.org/download/2.2/doc/proxy-protocol.txt) 专用于传递请求的真实来源 IP 和端口,**若你不了解它,请先忽略该项**。
常见的反代软件(如 HAProxy、Nginx都可以配置发送它VLESS fallbacks xver 也可以发送它。
填写 `true` 时,最底层 TCP 连接建立后,请求方必须先发送 PROXY protocol v1 或 v2否则连接会被关闭。
默认值为 `false`
> `header`: [NoneHeaderObject](#noneheaderobject) | [HttpHeaderobject](#httpheaderobject)
数据包头部伪装设置,默认值为 `NoneHeaderObject`
::: tip
HTTP 伪装无法被其它 HTTP 服务器(如 Nginx分流但可以被 VLESS fallbacks path 分流。
:::
### NoneHeaderObject
不进行伪装
```json
{
"type": "none"
}
```
> `type`: "none"
指定不进行伪装
### HttpHeaderObject
HTTP 伪装配置必须在对应的入站出站连接上同时配置,且内容必须一致。
```json
{
"type": "http",
"request": {},
"response": {}
}
```
> `type`: "http"
指定进行 HTTP 伪装
> `request`: [HTTPRequestObject](#httprequestobject)
HTTP 请求
> `response`: [HTTPResponseObject](#httpresponseobject)
HTTP 响应
#### HTTPRequestObject
```json
{
"version": "1.1",
"method": "GET",
"path": ["/"],
"headers": {
"Host": ["www.baidu.com", "www.bing.com"],
"User-Agent": [
"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
"Mozilla/5.0 (iPhone; CPU iPhone OS 10_0_2 like Mac OS X) AppleWebKit/601.1 (KHTML, like Gecko) CriOS/53.0.2785.109 Mobile/14A456 Safari/601.1.46"
],
"Accept-Encoding": ["gzip, deflate"],
"Connection": ["keep-alive"],
"Pragma": "no-cache"
}
}
```
> `version`: string
HTTP 版本,默认值为 `"1.1"`
> `method`: string
HTTP 方法,默认值为 `"GET"`
> `path`: \[ string \]
路径,一个字符串数组。默认值为 `["/"]`。当有多个值时,每次请求随机选择一个值。
> `headers`: map{ string, \[ string \]}
HTTP 头,一个键值对,每个键表示一个 HTTP 头的名称,对应的值是一个数组。
每次请求会附上所有的键,并随机选择一个对应的值。默认值见上方示例。
#### HTTPResponseObject
```json
{
"version": "1.1",
"status": "200",
"reason": "OK",
"headers": {
"Content-Type": ["application/octet-stream", "video/mpeg"],
"Transfer-Encoding": ["chunked"],
"Connection": ["keep-alive"],
"Pragma": "no-cache"
}
}
```
> `version`: string
HTTP 版本,默认值为 `"1.1"`
> `status`: string
HTTP 状态,默认值为 `"200"`
> `reason`: string
HTTP 状态说明,默认值为 `"OK"`
> `headers`: map {string, \[ string \]}
HTTP 头,一个键值对,每个键表示一个 HTTP 头的名称,对应的值是一个数组。
每次请求会附上所有的键,并随机选择一个对应的值。默认值见上方示例。

Some files were not shown because too many files have changed in this diff Show more