feat: Add initial files
This commit is contained in:
12 files changed
+1229
No files matched your search
@@ -0,0 +1,397 @@
|
||||
Attribution 4.0 International
|
||||
|
||||
=======================================================================
|
||||
|
||||
Creative Commons Corporation ("Creative Commons") is not a law firm and
|
||||
does not provide legal services or legal advice. Distribution of
|
||||
Creative Commons public licenses does not create a lawyer-client or
|
||||
other relationship. Creative Commons makes its licenses and related
|
||||
information available on an "as-is" basis. Creative Commons gives no
|
||||
warranties regarding its licenses, any material licensed under their
|
||||
terms and conditions, or any related information. Creative Commons
|
||||
disclaims all liability for damages resulting from their use to the
|
||||
fullest extent possible.
|
||||
|
||||
Using Creative Commons Public Licenses
|
||||
|
||||
Creative Commons public licenses provide a standard set of terms and
|
||||
conditions that creators and other rights holders may use to share
|
||||
original works of authorship and other material subject to copyright
|
||||
and certain other rights specified in the public license below. The
|
||||
following considerations are for informational purposes only, are not
|
||||
exhaustive, and do not form part of our licenses.
|
||||
|
||||
Considerations for licensors: Our public licenses are
|
||||
intended for use by those authorized to give the public
|
||||
permission to use material in ways otherwise restricted by
|
||||
copyright and certain other rights. Our licenses are
|
||||
irrevocable. Licensors should read and understand the terms
|
||||
and conditions of the license they choose before applying it.
|
||||
Licensors should also secure all rights necessary before
|
||||
applying our licenses so that the public can reuse the
|
||||
material as expected. Licensors should clearly mark any
|
||||
material not subject to the license. This includes other CC-
|
||||
licensed material, or material used under an exception or
|
||||
limitation to copyright. More considerations for licensors:
|
||||
wiki.creativecommons.org/Considerations_for_licensors
|
||||
|
||||
Considerations for the public: By using one of our public
|
||||
licenses, a licensor grants the public permission to use the
|
||||
licensed material under specified terms and conditions. If
|
||||
the licensor's permission is not necessary for any reason--for
|
||||
example, because of any applicable exception or limitation to
|
||||
copyright--then that use is not regulated by the license. Our
|
||||
licenses grant only permissions under copyright and certain
|
||||
other rights that a licensor has authority to grant. Use of
|
||||
the licensed material may still be restricted for other
|
||||
reasons, including because others have copyright or other
|
||||
rights in the material. A licensor may make special requests,
|
||||
such as asking that all changes be marked or described.
|
||||
Although not required by our licenses, you are encouraged to
|
||||
respect those requests where reasonable. More considerations
|
||||
for the public:
|
||||
wiki.creativecommons.org/Considerations_for_licensees
|
||||
|
||||
=======================================================================
|
||||
|
||||
Creative Commons Attribution 4.0 International Public License
|
||||
|
||||
By exercising the Licensed Rights (defined below), You accept and agree
|
||||
to be bound by the terms and conditions of this Creative Commons
|
||||
Attribution 4.0 International Public License ("Public License"). To the
|
||||
extent this Public License may be interpreted as a contract, You are
|
||||
granted the Licensed Rights in consideration of Your acceptance of
|
||||
these terms and conditions, and the Licensor grants You such rights in
|
||||
consideration of benefits the Licensor receives from making the
|
||||
Licensed Material available under these terms and conditions.
|
||||
|
||||
|
||||
Section 1 -- Definitions.
|
||||
|
||||
a. Adapted Material means material subject to Copyright and Similar
|
||||
Rights that is derived from or based upon the Licensed Material
|
||||
and in which the Licensed Material is translated, altered,
|
||||
arranged, transformed, or otherwise modified in a manner requiring
|
||||
permission under the Copyright and Similar Rights held by the
|
||||
Licensor. For purposes of this Public License, where the Licensed
|
||||
Material is a musical work, performance, or sound recording,
|
||||
Adapted Material is always produced where the Licensed Material is
|
||||
synched in timed relation with a moving image.
|
||||
|
||||
b. Adapter's License means the license You apply to Your Copyright
|
||||
and Similar Rights in Your contributions to Adapted Material in
|
||||
accordance with the terms and conditions of this Public License.
|
||||
|
||||
c. Copyright and Similar Rights means copyright and/or similar rights
|
||||
closely related to copyright including, without limitation,
|
||||
performance, broadcast, sound recording, and Sui Generis Database
|
||||
Rights, without regard to how the rights are labeled or
|
||||
categorized. For purposes of this Public License, the rights
|
||||
specified in Section 2(b)(1)-(2) are not Copyright and Similar
|
||||
Rights.
|
||||
|
||||
d. Effective Technological Measures means those measures that, in the
|
||||
absence of proper authority, may not be circumvented under laws
|
||||
fulfilling obligations under Article 11 of the WIPO Copyright
|
||||
Treaty adopted on December 20, 1996, and/or similar international
|
||||
agreements.
|
||||
|
||||
e. Exceptions and Limitations means fair use, fair dealing, and/or
|
||||
any other exception or limitation to Copyright and Similar Rights
|
||||
that applies to Your use of the Licensed Material.
|
||||
|
||||
f. Licensed Material means the artistic or literary work, database,
|
||||
or other material to which the Licensor applied this Public
|
||||
License.
|
||||
|
||||
g. Licensed Rights means the rights granted to You subject to the
|
||||
terms and conditions of this Public License, which are limited to
|
||||
all Copyright and Similar Rights that apply to Your use of the
|
||||
Licensed Material and that the Licensor has authority to license.
|
||||
|
||||
h. Licensor means the individual(s) or entity(ies) granting rights
|
||||
under this Public License.
|
||||
|
||||
i. Share means to provide material to the public by any means or
|
||||
process that requires permission under the Licensed Rights, such
|
||||
as reproduction, public display, public performance, distribution,
|
||||
dissemination, communication, or importation, and to make material
|
||||
available to the public including in ways that members of the
|
||||
public may access the material from a place and at a time
|
||||
individually chosen by them.
|
||||
|
||||
j. Sui Generis Database Rights means rights other than copyright
|
||||
resulting from Directive 96/9/EC of the European Parliament and of
|
||||
the Council of 11 March 1996 on the legal protection of databases,
|
||||
as amended and/or succeeded, as well as other essentially
|
||||
equivalent rights anywhere in the world.
|
||||
|
||||
k. You means the individual or entity exercising the Licensed Rights
|
||||
under this Public License. Your has a corresponding meaning.
|
||||
|
||||
|
||||
Section 2 -- Scope.
|
||||
|
||||
a. License grant.
|
||||
|
||||
1. Subject to the terms and conditions of this Public License,
|
||||
the Licensor hereby grants You a worldwide, royalty-free,
|
||||
non-sublicensable, non-exclusive, irrevocable license to
|
||||
exercise the Licensed Rights in the Licensed Material to:
|
||||
|
||||
a. reproduce and Share the Licensed Material, in whole or
|
||||
in part; and
|
||||
|
||||
b. produce, reproduce, and Share Adapted Material.
|
||||
|
||||
2. Exceptions and Limitations. For the avoidance of doubt, where
|
||||
Exceptions and Limitations apply to Your use, this Public
|
||||
License does not apply, and You do not need to comply with
|
||||
its terms and conditions.
|
||||
|
||||
3. Term. The term of this Public License is specified in Section
|
||||
6(a).
|
||||
|
||||
4. Media and formats; technical modifications allowed. The
|
||||
Licensor authorizes You to exercise the Licensed Rights in
|
||||
all media and formats whether now known or hereafter created,
|
||||
and to make technical modifications necessary to do so. The
|
||||
Licensor waives and/or agrees not to assert any right or
|
||||
authority to forbid You from making technical modifications
|
||||
necessary to exercise the Licensed Rights, including
|
||||
technical modifications necessary to circumvent Effective
|
||||
Technological Measures. For purposes of this Public License,
|
||||
simply making modifications authorized by this Section 2(a)
|
||||
(4) never produces Adapted Material.
|
||||
|
||||
5. Downstream recipients.
|
||||
|
||||
a. Offer from the Licensor -- Licensed Material. Every
|
||||
recipient of the Licensed Material automatically
|
||||
receives an offer from the Licensor to exercise the
|
||||
Licensed Rights under the terms and conditions of this
|
||||
Public License.
|
||||
|
||||
b. No downstream restrictions. You may not offer or impose
|
||||
any additional or different terms or conditions on, or
|
||||
apply any Effective Technological Measures to, the
|
||||
Licensed Material if doing so restricts exercise of the
|
||||
Licensed Rights by any recipient of the Licensed
|
||||
Material.
|
||||
|
||||
6. No endorsement. Nothing in this Public License constitutes or
|
||||
may be construed as permission to assert or imply that You
|
||||
are, or that Your use of the Licensed Material is, connected
|
||||
with, or sponsored, endorsed, or granted official status by,
|
||||
the Licensor or others designated to receive attribution as
|
||||
provided in Section 3(a)(1)(A)(i).
|
||||
|
||||
b. Other rights.
|
||||
|
||||
1. Moral rights, such as the right of integrity, are not
|
||||
licensed under this Public License, nor are publicity,
|
||||
privacy, and/or other similar personality rights; however, to
|
||||
the extent possible, the Licensor waives and/or agrees not to
|
||||
assert any such rights held by the Licensor to the limited
|
||||
extent necessary to allow You to exercise the Licensed
|
||||
Rights, but not otherwise.
|
||||
|
||||
2. Patent and trademark rights are not licensed under this
|
||||
Public License.
|
||||
|
||||
3. To the extent possible, the Licensor waives any right to
|
||||
collect royalties from You for the exercise of the Licensed
|
||||
Rights, whether directly or through a collecting society
|
||||
under any voluntary or waivable statutory or compulsory
|
||||
licensing scheme. In all other cases the Licensor expressly
|
||||
reserves any right to collect such royalties.
|
||||
|
||||
|
||||
Section 3 -- License Conditions.
|
||||
|
||||
Your exercise of the Licensed Rights is expressly made subject to the
|
||||
following conditions.
|
||||
|
||||
a. Attribution.
|
||||
|
||||
1. If You Share the Licensed Material (including in modified
|
||||
form), You must:
|
||||
|
||||
a. retain the following if it is supplied by the Licensor
|
||||
with the Licensed Material:
|
||||
|
||||
i. identification of the creator(s) of the Licensed
|
||||
Material and any others designated to receive
|
||||
attribution, in any reasonable manner requested by
|
||||
the Licensor (including by pseudonym if
|
||||
designated);
|
||||
|
||||
ii. a copyright notice;
|
||||
|
||||
iii. a notice that refers to this Public License;
|
||||
|
||||
iv. a notice that refers to the disclaimer of
|
||||
warranties;
|
||||
|
||||
v. a URI or hyperlink to the Licensed Material to the
|
||||
extent reasonably practicable;
|
||||
|
||||
b. indicate if You modified the Licensed Material and
|
||||
retain an indication of any previous modifications; and
|
||||
|
||||
c. indicate the Licensed Material is licensed under this
|
||||
Public License, and include the text of, or the URI or
|
||||
hyperlink to, this Public License.
|
||||
|
||||
2. You may satisfy the conditions in Section 3(a)(1) in any
|
||||
reasonable manner based on the medium, means, and context in
|
||||
which You Share the Licensed Material. For example, it may be
|
||||
reasonable to satisfy the conditions by providing a URI or
|
||||
hyperlink to a resource that includes the required
|
||||
information.
|
||||
|
||||
3. If requested by the Licensor, You must remove any of the
|
||||
information required by Section 3(a)(1)(A) to the extent
|
||||
reasonably practicable.
|
||||
|
||||
4. If You Share Adapted Material You produce, the Adapter's
|
||||
License You apply must not prevent recipients of the Adapted
|
||||
Material from complying with this Public License.
|
||||
|
||||
|
||||
Section 4 -- Sui Generis Database Rights.
|
||||
|
||||
Where the Licensed Rights include Sui Generis Database Rights that
|
||||
apply to Your use of the Licensed Material:
|
||||
|
||||
a. for the avoidance of doubt, Section 2(a)(1) grants You the right
|
||||
to extract, reuse, reproduce, and Share all or a substantial
|
||||
portion of the contents of the database;
|
||||
|
||||
b. if You include all or a substantial portion of the database
|
||||
contents in a database in which You have Sui Generis Database
|
||||
Rights, then the database in which You have Sui Generis Database
|
||||
Rights (but not its individual contents) is Adapted Material; and
|
||||
|
||||
c. You must comply with the conditions in Section 3(a) if You Share
|
||||
all or a substantial portion of the contents of the database.
|
||||
|
||||
For the avoidance of doubt, this Section 4 supplements and does not
|
||||
replace Your obligations under this Public License where the Licensed
|
||||
Rights include other Copyright and Similar Rights.
|
||||
|
||||
|
||||
Section 5 -- Disclaimer of Warranties and Limitation of Liability.
|
||||
|
||||
a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
|
||||
EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
|
||||
AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
|
||||
ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
|
||||
IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
|
||||
WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
|
||||
ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
|
||||
KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
|
||||
ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
|
||||
|
||||
b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
|
||||
TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
|
||||
NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
|
||||
INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
|
||||
COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
|
||||
USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
|
||||
ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
|
||||
DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
|
||||
IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
|
||||
|
||||
c. The disclaimer of warranties and limitation of liability provided
|
||||
above shall be interpreted in a manner that, to the extent
|
||||
possible, most closely approximates an absolute disclaimer and
|
||||
waiver of all liability.
|
||||
|
||||
|
||||
Section 6 -- Term and Termination.
|
||||
|
||||
a. This Public License applies for the term of the Copyright and
|
||||
Similar Rights licensed here. However, if You fail to comply with
|
||||
this Public License, then Your rights under this Public License
|
||||
terminate automatically.
|
||||
|
||||
b. Where Your right to use the Licensed Material has terminated under
|
||||
Section 6(a), it reinstates:
|
||||
|
||||
1. automatically as of the date the violation is cured, provided
|
||||
it is cured within 30 days of Your discovery of the
|
||||
violation; or
|
||||
|
||||
2. upon express reinstatement by the Licensor.
|
||||
|
||||
For the avoidance of doubt, this Section 6(b) does not affect any
|
||||
right the Licensor may have to seek remedies for Your violations
|
||||
of this Public License.
|
||||
|
||||
c. For the avoidance of doubt, the Licensor may also offer the
|
||||
Licensed Material under separate terms or conditions or stop
|
||||
distributing the Licensed Material at any time; however, doing so
|
||||
will not terminate this Public License.
|
||||
|
||||
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
|
||||
License.
|
||||
|
||||
|
||||
Section 7 -- Other Terms and Conditions.
|
||||
|
||||
a. The Licensor shall not be bound by any additional or different
|
||||
terms or conditions communicated by You unless expressly agreed.
|
||||
|
||||
b. Any arrangements, understandings, or agreements regarding the
|
||||
Licensed Material not stated herein are separate from and
|
||||
independent of the terms and conditions of this Public License.
|
||||
|
||||
|
||||
Section 8 -- Interpretation.
|
||||
|
||||
a. For the avoidance of doubt, this Public License does not, and
|
||||
shall not be interpreted to, reduce, limit, restrict, or impose
|
||||
conditions on any use of the Licensed Material that could lawfully
|
||||
be made without permission under this Public License.
|
||||
|
||||
b. To the extent possible, if any provision of this Public License is
|
||||
deemed unenforceable, it shall be automatically reformed to the
|
||||
minimum extent necessary to make it enforceable. If the provision
|
||||
cannot be reformed, it shall be severed from this Public License
|
||||
without affecting the enforceability of the remaining terms and
|
||||
conditions.
|
||||
|
||||
c. No term or condition of this Public License will be waived and no
|
||||
failure to comply consented to unless expressly agreed to by the
|
||||
Licensor.
|
||||
|
||||
d. Nothing in this Public License constitutes or may be interpreted
|
||||
as a limitation upon, or waiver of, any privileges and immunities
|
||||
that apply to the Licensor or You, including from the legal
|
||||
processes of any jurisdiction or authority.
|
||||
|
||||
|
||||
=======================================================================
|
||||
|
||||
Creative Commons is not a party to its public
|
||||
licenses. Notwithstanding, Creative Commons may elect to apply one of
|
||||
its public licenses to material it publishes and in those instances
|
||||
will be considered the “Licensor.” The text of the Creative Commons
|
||||
public licenses is dedicated to the public domain under the CC0 Public
|
||||
Domain Dedication. Except for the limited purpose of indicating that
|
||||
material is shared under a Creative Commons public license or as
|
||||
otherwise permitted by the Creative Commons policies published at
|
||||
creativecommons.org/policies, Creative Commons does not authorize the
|
||||
use of the trademark "Creative Commons" or any other trademark or logo
|
||||
of Creative Commons without its prior written consent including,
|
||||
without limitation, in connection with any unauthorized modifications
|
||||
to any of its public licenses or any other arrangements,
|
||||
understandings, or agreements concerning use of licensed material. For
|
||||
the avoidance of doubt, this paragraph does not form part of the
|
||||
public licenses.
|
||||
|
||||
Creative Commons may be contacted at creativecommons.org.
|
||||
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
# Xray Subnet Mimicry (10.0.0.0/8)
|
||||
|
||||
> [!CAUTION]
|
||||
> **EDUCATIONAL PURPOSES ONLY**
|
||||
> This project is designed as a technical demonstration of Xray-core's routing capabilities and private subnet mimicry. It is NOT intended for restriction evasion or illegal activities. Use this knowledge responsibly and in compliance with your local laws.
|
||||
|
||||
This repository provides a minimal example of how to mimic a contiguous `10.0.0.0/8` private subnet across three distinct servers using **Xray-core** and **reverse tunneling**.
|
||||
|
||||
---
|
||||
|
||||
## Technical Deep-Dive & Architecture
|
||||
|
||||
### The Virtual Subnet Concept
|
||||
We are constructing a "Flat Network" (Layer 3) over the public internet. Each node is an authoritative gateway for its own `/16` segment of the `10.0.0.0/8` range.
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
subgraph Hub ["Server A (Hub / Portal) - 10.1.0.0/16"]
|
||||
A_Local["🖥️ Host / Local Clients"]
|
||||
A_Xray{"⚛️ Xray Core"}
|
||||
A_DNS["🛡️ AdGuard (10.1.1.3)"]
|
||||
A_Nginx["🌐 Nginx (10.1.1.4)"]
|
||||
|
||||
A_Local -- "TPROXY" --> A_Xray
|
||||
A_Xray -.-> A_DNS
|
||||
A_Xray -.-> A_Nginx
|
||||
end
|
||||
|
||||
subgraph SpokeB ["Server B (Spoke / Bridge) - 10.2.0.0/16"]
|
||||
B_Local["🖥️ Host / Local Clients"]
|
||||
B_Xray{"⚛️ Xray Core"}
|
||||
|
||||
B_Local -- "TPROXY" --> B_Xray
|
||||
end
|
||||
|
||||
subgraph SpokeC ["Server C (Spoke / Bridge) - 10.3.0.0/16"]
|
||||
C_Local["🖥️ Host / Local Clients"]
|
||||
C_Xray{"⚛️ Xray Core"}
|
||||
|
||||
C_Local -- "TPROXY" --> C_Xray
|
||||
end
|
||||
|
||||
%% Main Tunnels
|
||||
B_Xray -- "VLESS (Direct)" --> A_Xray
|
||||
A_Xray -- "VLESS (Reverse)" --> B_Xray
|
||||
C_Xray -- "VLESS (Direct)" --> A_Xray
|
||||
A_Xray -- "VLESS (Reverse)" --> C_Xray
|
||||
|
||||
%% Example Routing Flow
|
||||
B_Local -.-> |"1. Dest: 10.3.x.x"| B_Xray
|
||||
A_Xray -.-> |"2. Route to C"| C_Xray
|
||||
C_Xray -.-> |"3. Deliver"| C_Local
|
||||
```
|
||||
|
||||
### The Science of Interception (TPROXY)
|
||||
Unlike `REDIRECT` which only works for TCP and changes the destination IP to the proxy's IP, **TPROXY** (Transparent Proxy) allows the proxy to intercept both TCP and UDP while preserving the original packet headers.
|
||||
|
||||
* **Mechanism:** When a packet for `10.x.x.x` enters the `PREROUTING` or `OUTPUT` chain, the Linux Mangle table marks it with `0x1`.
|
||||
* **Preservation:** Xray's `tunnel` inbound (which intercepts the host's traffic) uses `\"sockopt\": { \"tproxy\": \"tproxy\" }` to read the original destination IP from the socket metadata, allowing it to route the packet as if it were the intended gateway.
|
||||
* **Resource:** [Linux Kernel TPROXY Documentation](https://www.kernel.org/doc/Documentation/networking/tproxy.txt)
|
||||
|
||||
### Policy Routing (Table 100)
|
||||
While the `iptables` rules in our firewall *mark* intercepted packets (with `0x1`), marking alone does not change where a packet goes. The standard Linux routing table only cares about the destination IP. If a packet is destined for `10.3.x.x` but there is no physical route, the kernel will send it to the default gateway (the public internet), which will simply drop it.
|
||||
|
||||
To make the kernel route traffic based on our firewall mark, we use **Policy Routing**:
|
||||
1. **The Rule (`ip rule`):** `ip rule add fwmark 1 lookup 100` tells the Linux networking stack: *"Before doing normal routing, if a packet has firewall mark 1, ignore the main routing table and use Table 100 instead."*
|
||||
2. **The Table (`ip route`):** `ip route add local default dev lo table 100` populates Table 100 with a single rule: *"Treat ALL destination IPs as if they belong to this local machine (`local default`), and route them to the internal loopback interface (`dev lo`)."*
|
||||
3. **The Handoff:** Because the packet is forced onto the local loopback interface, the `TPROXY` mechanism can finally grab it. Xray, which is listening on `127.0.0.1:12345` with the `tproxy` socket option, intercepts the packet and reads its original destination.
|
||||
4. **Loop Prevention:** We use `sockopt: { \"mark\": 255 }` in Xray's outbounds. This "exempts" Xray's own outbound traffic from being caught by our `iptables` rules (since 255 is not 1), preventing an infinite loop where Xray proxies its own traffic.
|
||||
|
||||
### The Reverse Proxy Mechanism (Bridge & Portal)
|
||||
To allow a server behind NAT (Spoke) to be reachable by the Hub, Xray implements a sophisticated Reverse Proxy architecture.
|
||||
|
||||
* **Bridge (The Spoke):** The Bridge actively initiates a connection to the Portal. It acts as the "Client" for the tunnel but functionally behaves as a server once the tunnel is open.
|
||||
* **Portal (The Hub):** The Portal listens for these incoming Bridge connections. It uses a "Dummy Domain" (configured in the `reverse` object) to identify the Bridge. When a packet for Spoke B arrives at the Hub, the Hub relays it through the already-open connection from Spoke B. [Xray Reverse Proxy Documentation](https://xtls.github.io/en/config/reverse.html)
|
||||
* **Multiplexing (Mux):** Xray uses [Mux.cool](https://xtls.github.io/en/development/protocols/muxcool.html) by default over these tunnels. This allows hundreds of virtual connections (TCP/UDP streams) to be packed into a single physical TLS connection between the Bridge and the Portal, significantly reducing overhead and bypassing NAT timeouts.
|
||||
* **VLESS Transport:** We use VLESS with XTLS for high-performance data encapsulation. [Xray VLESS](https://xtls.github.io/en/config/outbounds/vless.html)
|
||||
|
||||
## Setup Guide
|
||||
|
||||
### Phase 0: Prerequisites (Server A only)
|
||||
Before starting, Server A (the Hub) requires a valid SSL certificate for Xray's XTLS-Vision.
|
||||
1. Point your domain (`A-DOMAIN`) to Server A's public IP.
|
||||
2. Generate an SSL certificate (e.g., via Let's Encrypt / Certbot) so that it is available at `/etc/letsencrypt/live/A-DOMAIN/` on the host.
|
||||
|
||||
### Phase 1: Security & Identity
|
||||
Each connection needs its own cryptographic "Key" (UUID).
|
||||
1. **Generate 4 UUIDs**:
|
||||
```bash
|
||||
docker run --rm ghcr.io/xtls/xray-core uuid
|
||||
```
|
||||
2. **Mapping**:
|
||||
* `UUID_B_REVERSE`: Tunnel control for Server B.
|
||||
* `UUID_B_DIRECT`: Data traffic for Server B.
|
||||
* `UUID_C_REVERSE`: Tunnel control for Server C.
|
||||
* `UUID_C_DIRECT`: Data traffic for Server C.
|
||||
|
||||
### Phase 2: Host Networking (The Glue)
|
||||
On **EVERY** server node:
|
||||
|
||||
1. **Initialize Routing**: Run [routing.sh](./routing.sh). This sets up the kernel parameters and the custom routing Table 100.
|
||||
2. **Firewall Injection**: Open `/etc/ufw/before.rules` and find the `*filter` header.
|
||||
**CRITICAL PLACEMENT:** Insert the contents of your node's `before.rules` file immediately after these lines. The provided files contain `COMMIT` commands and new table declarations specifically crafted to be pasted here without breaking UFW.
|
||||
```bash
|
||||
*filter
|
||||
:ufw-before-input - [0:0]
|
||||
:ufw-before-output - [0:0]
|
||||
:ufw-before-forward - [0:0]
|
||||
:ufw-not-local - [0:0]
|
||||
# End required lines
|
||||
```
|
||||
**Files to Copy:**
|
||||
* **Server A**: Copy [a/before.rules](./a/before.rules)
|
||||
* **Server B**: Copy [b/before.rules](./b/before.rules)
|
||||
* **Server C**: Copy [c/before.rules](./c/before.rules)
|
||||
3. **Reload**: `sudo ufw reload`
|
||||
|
||||
### Phase 3: Deployment
|
||||
1. **Update Configs**: In each `xray.jsonc`, replace:
|
||||
* `REPLACE_WITH_UUID_...` with your generated IDs.
|
||||
* `A-DOMAIN` with your public domain.
|
||||
* `A-EXTERNAL-IP` with Server A's public IP.
|
||||
2. **Launch**: `docker compose up -d` in the `a/`, `b/`, and `c/` directories.
|
||||
*(Note: On Server A, Docker Compose automatically creates the `10.1.0.0/16` bridge network and assigns static IPs to the AdGuard (`10.1.1.3`) and Nginx (`10.1.1.4`) containers.)*
|
||||
|
||||
## Educational Resources & References
|
||||
* **Xray-core Official Documentation:** [XTLS.github.io](https://xtls.github.io/)
|
||||
* **Project X (Xray) GitHub:** [XTLS/Xray-core](https://github.com/XTLS/Xray-core)
|
||||
* **Understanding TPROXY:** [Cloudflare Blog: TPROXY](https://blog.cloudflare.com/how-we-built-spectrum/) - excellent deep dive into how transparent proxying works at scale.
|
||||
|
||||
## Copyright & License
|
||||
|
||||
**Information described here** is licensed under the [CC-BY-4.0](./LICENSE).
|
||||
|
||||
Software and tools mentioned or used within this repository are licensed individually under their respective terms and conditions by their original authors.
|
||||
|
||||
---
|
||||
|
||||
AI Assistance: Information in this repository was enhanced and formatted with the use of Large Generative Models _(sadly, they are incapable of correctly setting up the processes described here by themselves - otherwise, this repository wouldn't exist)_.
|
||||
|
||||
Copyright © 2026 Vladimir Eremin
|
||||
@@ -0,0 +1,50 @@
|
||||
# /etc/ufw/before.rules for Server A (10.1.0.0/16)
|
||||
#
|
||||
# These rules MUST be placed after the default boilerplate in UFW.
|
||||
# They handle the transparent interception of 10.0.0.0/8 traffic.
|
||||
|
||||
COMMIT
|
||||
|
||||
*mangle
|
||||
# Create custom chains for Xray interception
|
||||
:XRAY - [0:0]
|
||||
:XRAY_MASK - [0:0]
|
||||
:DIVERT - [0:0]
|
||||
|
||||
# --- PREROUTING CHAIN (Traffic from other containers/nodes) ---
|
||||
# Don't intercept traffic for our own local subnet
|
||||
-A XRAY -d 10.1.0.0/16 -j RETURN
|
||||
# Don't intercept traffic outside the 10.0.0.0/8 mimicry range
|
||||
-A XRAY ! -d 10.0.0.0/8 -j RETURN
|
||||
# Avoid infinite loops by ignoring traffic already marked by Xray
|
||||
-A XRAY -m mark --mark 0xff -j RETURN
|
||||
# Transparently proxy UDP/TCP to Xray on port 12345 and mark with 0x1
|
||||
-A XRAY -p udp -j TPROXY --on-ip 127.0.0.1 --on-port 12345 --tproxy-mark 1
|
||||
-A XRAY -p tcp -j TPROXY --on-ip 127.0.0.1 --on-port 12345 --tproxy-mark 1
|
||||
-A PREROUTING -j XRAY
|
||||
|
||||
# --- OUTPUT CHAIN (Traffic originating from the server itself) ---
|
||||
# Similar logic to XRAY: exclude local, exclude non-mimicry, exclude marked
|
||||
-A XRAY_MASK -d 10.1.0.0/16 -j RETURN
|
||||
-A XRAY_MASK ! -d 10.0.0.0/8 -j RETURN
|
||||
-A XRAY_MASK -m mark --mark 0xff -j RETURN
|
||||
# Mark traffic for table 100 routing (handled by routing.sh)
|
||||
-A XRAY_MASK -p udp -j MARK --set-mark 1
|
||||
-A XRAY_MASK -p tcp -j MARK --set-mark 1
|
||||
-A OUTPUT -j XRAY_MASK
|
||||
|
||||
# --- DIVERT Optimization ---
|
||||
# Helps maintain established TCP connections more efficiently
|
||||
-A DIVERT -j MARK --set-mark 1
|
||||
-A DIVERT -j ACCEPT
|
||||
-I PREROUTING -p tcp -m socket -j DIVERT
|
||||
|
||||
COMMIT
|
||||
|
||||
*filter
|
||||
# Allow the traffic we've marked and intercepted to pass through the firewall
|
||||
-A ufw-before-forward -s 10.1.0.0/16 -d 10.1.0.0/16 -j ACCEPT
|
||||
-A ufw-before-forward -s 10.1.0.0/16 -d 10.0.0.0/8 -m mark --mark 0x1 -j ACCEPT
|
||||
|
||||
-A ufw-before-input -s 10.1.0.0/16 -d 10.1.0.0/16 -j ACCEPT
|
||||
-A ufw-before-input -s 10.1.0.0/16 -d 10.0.0.0/8 -m mark --mark 0x1 -j ACCEPT
|
||||
@@ -0,0 +1,57 @@
|
||||
name: 'a'
|
||||
|
||||
services:
|
||||
xray:
|
||||
image: ghcr.io/xtls/xray-core:26.1.23
|
||||
container_name: a-xray
|
||||
network_mode: host
|
||||
volumes:
|
||||
- ./xray.jsonc:/etc/xray/config.jsonc:ro
|
||||
- /etc/letsencrypt/live:/etc/letsencrypt/live:ro
|
||||
command: -c '/etc/xray/config.jsonc'
|
||||
restart: unless-stopped
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
- NET_RAW
|
||||
|
||||
nginx:
|
||||
image: nginxinc/nginx-unprivileged:1.29-alpine
|
||||
container_name: a-nginx
|
||||
networks:
|
||||
direct:
|
||||
ipv4_address: 10.1.1.4
|
||||
restart: unless-stopped
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
|
||||
adguard:
|
||||
image: adguard/adguardhome:v0.107.72
|
||||
container_name: root-adguard
|
||||
volumes:
|
||||
- adguard-work:/opt/adguardhome/work
|
||||
- adguard-conf:/opt/adguardhome/conf
|
||||
networks:
|
||||
direct:
|
||||
ipv4_address: 10.1.1.3
|
||||
restart: unless-stopped
|
||||
cap_add:
|
||||
- NET_BIND_SERVICE
|
||||
- SYS_NICE
|
||||
- CAP_CHOWN
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
|
||||
networks:
|
||||
direct:
|
||||
name: a-direct
|
||||
driver: bridge
|
||||
ipam:
|
||||
config:
|
||||
- subnet: 10.1.0.0/16 # Using the full /16 as defined for Server A
|
||||
gateway: 10.1.0.1
|
||||
|
||||
volumes:
|
||||
adguard-work:
|
||||
name: a-adguard-work
|
||||
adguard-conf:
|
||||
name: a-adguard-conf
|
||||
+169
@@ -0,0 +1,169 @@
|
||||
{
|
||||
// ==========================================
|
||||
// SERVER A: CENTRAL HUB (Subnet: 10.1.0.0/16)
|
||||
// ==========================================
|
||||
// This node is the "Master Router" for your 10.0.0.0/8 mimicry.
|
||||
// It handles:
|
||||
// 1. Inbound connections from Spokes (B & C).
|
||||
// 2. DNS Resolution (via AdGuard Home).
|
||||
// 3. Routing between all 10.x.x.x subnets.
|
||||
|
||||
"log": {
|
||||
"loglevel": "info"
|
||||
},
|
||||
|
||||
"dns": {
|
||||
"servers": [
|
||||
// Centralized DNS for the entire 10.0.0.0/8 network.
|
||||
// AdGuard Home is expected to be reachable at 10.1.1.3.
|
||||
"10.1.1.3"
|
||||
]
|
||||
},
|
||||
|
||||
"inbounds": [
|
||||
{
|
||||
// MAIN PUBLIC INBOUND
|
||||
// Listens on 443 for incoming connections from Server B and C.
|
||||
// Uses VLESS with XTLS-Vision for high performance and modern encryption.
|
||||
"address": "0.0.0.0",
|
||||
"port": 443,
|
||||
"protocol": "vless",
|
||||
"tag": "proxy-direct",
|
||||
"sniffing": {
|
||||
"enabled": true,
|
||||
"destOverride": ["http", "tls", "quic"],
|
||||
"routeOnly": true
|
||||
},
|
||||
"settings": {
|
||||
"clients": [
|
||||
// SERVER B: Two connections - one for reverse tunnel, one for direct proxy.
|
||||
{
|
||||
"email": "b-reverse",
|
||||
"id": "REPLACE_WITH_UUID_B_REVERSE",
|
||||
"reverse": { "tag": "reverse-b" }
|
||||
},
|
||||
{
|
||||
"email": "b-direct",
|
||||
"id": "REPLACE_WITH_UUID_B_DIRECT"
|
||||
},
|
||||
// SERVER C: Similar setup to B.
|
||||
{
|
||||
"email": "c-reverse",
|
||||
"id": "REPLACE_WITH_UUID_C_REVERSE",
|
||||
"reverse": { "tag": "reverse-c" }
|
||||
},
|
||||
{
|
||||
"email": "c-direct",
|
||||
"id": "REPLACE_WITH_UUID_C_DIRECT"
|
||||
}
|
||||
],
|
||||
"flow": "xtls-rprx-vision",
|
||||
"decryption": "none",
|
||||
"fallbacks": [
|
||||
{
|
||||
// CAMOUFLAGE: If an unauthorized user hits 443, forward them to Nginx.
|
||||
// This hides the fact that an Xray instance is running.
|
||||
"dest": "10.1.1.4:8080"
|
||||
}
|
||||
]
|
||||
},
|
||||
"streamSettings": {
|
||||
"network": "tcp",
|
||||
"security": "tls",
|
||||
"tlsSettings": {
|
||||
"alpn": ["h2", "http/1.1"],
|
||||
"certificates": [
|
||||
{
|
||||
// Path to SSL certificates (mapped via Docker volumes).
|
||||
"certificateFile": "/etc/letsencrypt/live/A-DOMAIN/fullchain.pem",
|
||||
"keyFile": "/etc/letsencrypt/live/A-DOMAIN/privkey.pem"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
// TPROXY INBOUND (Host Interception)
|
||||
// This inbound "catches" traffic from the host's kernel that was
|
||||
// marked by IPTables (before.rules).
|
||||
"tag": "proxy-enclave",
|
||||
"listen": "127.0.0.1",
|
||||
"port": 12345,
|
||||
"protocol": "tunnel",
|
||||
"settings": {
|
||||
"network": "tcp,udp",
|
||||
"followRedirect": true
|
||||
},
|
||||
"sniffing": {
|
||||
"enabled": true,
|
||||
"destOverride": ["http", "tls", "quic"],
|
||||
"routeOnly": true
|
||||
},
|
||||
"streamSettings": {
|
||||
"sockopt": {
|
||||
"tproxy": "tproxy",
|
||||
"mark": 255 // Mark 255 prevents Xray from intercepting its own output.
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
"outbounds": [
|
||||
{
|
||||
// FREEDOM OUTBOUND: Standard direct connection to the internet.
|
||||
"tag": "forward-direct",
|
||||
"protocol": "freedom",
|
||||
"settings": {
|
||||
"domainStrategy": "UseIP"
|
||||
},
|
||||
"streamSettings": {
|
||||
"sockopt": {
|
||||
"mark": 255
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
// DNS OUTBOUND: Ensures all DNS traffic is sent to the local AdGuard resolver.
|
||||
"tag": "forward-dns",
|
||||
"protocol": "dns",
|
||||
"settings": {
|
||||
"address": "10.1.1.3",
|
||||
"port": 53,
|
||||
"nonIPQuery": "skip"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
"routing": {
|
||||
"domainStrategy": "IPIfNonMatch",
|
||||
"rules": [
|
||||
{
|
||||
// Enforce centralized DNS for all queries.
|
||||
"port": "53",
|
||||
"network": "udp,tcp",
|
||||
"outboundTag": "forward-dns"
|
||||
},
|
||||
{
|
||||
// Internal subnet 10.1.x.x traffic is handled directly on this node.
|
||||
"inboundTag": ["proxy-direct"],
|
||||
"ip": ["10.1.0.0/16"],
|
||||
"outboundTag": "forward-direct"
|
||||
},
|
||||
{
|
||||
// TRAFFIC TO SPOKE B (10.2.x.x):
|
||||
// If traffic is destined for Server B's range, send it through
|
||||
// the reverse tunnel initiated by Server B.
|
||||
"inboundTag": ["proxy-enclave"],
|
||||
"ip": ["10.2.0.0/16"],
|
||||
"outboundTag": "reverse-b"
|
||||
},
|
||||
{
|
||||
// TRAFFIC TO SPOKE C (10.3.x.x):
|
||||
// Similar to above, send through Server C's reverse tunnel.
|
||||
"inboundTag": ["proxy-enclave"],
|
||||
"ip": ["10.3.0.0/16"],
|
||||
"outboundTag": "reverse-c"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
# /etc/ufw/before.rules for Server B (10.2.0.0/16)
|
||||
#
|
||||
# These rules handle the transparent interception of 10.0.0.0/8 traffic
|
||||
# destined for other nodes (e.g., 10.1.x.x or 10.3.x.x).
|
||||
|
||||
COMMIT
|
||||
|
||||
*mangle
|
||||
:XRAY - [0:0]
|
||||
:XRAY_MASK - [0:0]
|
||||
:DIVERT - [0:0]
|
||||
|
||||
# Intercept Prerouting traffic (e.g. from local containers)
|
||||
-A XRAY -d 10.2.0.0/16 -j RETURN
|
||||
-A XRAY ! -d 10.0.0.0/8 -j RETURN
|
||||
-A XRAY -m mark --mark 0xff -j RETURN
|
||||
-A XRAY -p udp -j TPROXY --on-ip 127.0.0.1 --on-port 12345 --tproxy-mark 1
|
||||
-A XRAY -p tcp -j TPROXY --on-ip 127.0.0.1 --on-port 12345 --tproxy-mark 1
|
||||
-A PREROUTING -j XRAY
|
||||
|
||||
# Intercept Output traffic (originating from the server itself)
|
||||
-A XRAY_MASK -d 10.2.0.0/16 -j RETURN
|
||||
-A XRAY_MASK ! -d 10.0.0.0/8 -j RETURN
|
||||
-A XRAY_MASK -m mark --mark 0xff -j RETURN
|
||||
-A XRAY_MASK -p udp -j MARK --set-mark 1
|
||||
-A XRAY_MASK -p tcp -j MARK --set-mark 1
|
||||
-A OUTPUT -j XRAY_MASK
|
||||
|
||||
-A DIVERT -j MARK --set-mark 1
|
||||
-A DIVERT -j ACCEPT
|
||||
-I PREROUTING -p tcp -m socket -j DIVERT
|
||||
|
||||
COMMIT
|
||||
|
||||
*filter
|
||||
# Allow internal traffic between our subnet and the mimicry range
|
||||
-A ufw-before-forward -s 10.2.0.0/16 -d 10.2.0.0/16 -j ACCEPT
|
||||
-A ufw-before-forward -s 10.2.0.0/16 -d 10.0.0.0/8 -m mark --mark 0x1 -j ACCEPT
|
||||
|
||||
-A ufw-before-input -s 10.2.0.0/16 -d 10.2.0.0/16 -j ACCEPT
|
||||
-A ufw-before-input -s 10.2.0.0/16 -d 10.0.0.0/8 -m mark --mark 0x1 -j ACCEPT
|
||||
@@ -0,0 +1,14 @@
|
||||
name: 'b'
|
||||
|
||||
services:
|
||||
xray:
|
||||
image: ghcr.io/xtls/xray-core:26.1.23
|
||||
container_name: b-xray
|
||||
network_mode: host
|
||||
volumes:
|
||||
- ./xray.jsonc:/etc/xray/config.jsonc:ro
|
||||
command: -c '/etc/xray/config.jsonc'
|
||||
restart: unless-stopped
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
- NET_RAW
|
||||
+137
@@ -0,0 +1,137 @@
|
||||
{
|
||||
// ==========================================
|
||||
// SERVER B: SPOKE NODE (Subnet: 10.2.0.0/16)
|
||||
// ==========================================
|
||||
// This node initiates a reverse tunnel to Server A.
|
||||
// It allows Server A to reach clients in the 10.2.x.x range.
|
||||
|
||||
"log": {
|
||||
"loglevel": "info"
|
||||
},
|
||||
|
||||
"dns": {
|
||||
"servers": [
|
||||
// Queries are forwarded to Server A's central DNS (AdGuard).
|
||||
"10.1.1.3"
|
||||
]
|
||||
},
|
||||
|
||||
"inbounds": [
|
||||
{
|
||||
// TPROXY INBOUND
|
||||
// Intercepts traffic for the 10.0.0.0/8 subnet from the local host.
|
||||
"tag": "proxy-enclave",
|
||||
"listen": "127.0.0.1",
|
||||
"port": 12345,
|
||||
"protocol": "tunnel",
|
||||
"settings": {
|
||||
"network": "tcp,udp",
|
||||
"followRedirect": true
|
||||
},
|
||||
"sniffing": {
|
||||
"enabled": true,
|
||||
"destOverride": ["http", "tls", "quic"],
|
||||
"routeOnly": true
|
||||
},
|
||||
"streamSettings": {
|
||||
"sockopt": {
|
||||
"tproxy": "tproxy",
|
||||
"mark": 255
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
"outbounds": [
|
||||
{
|
||||
// FREEDOM OUTBOUND: Standard breakout for the local internet.
|
||||
"protocol": "freedom",
|
||||
"tag": "forward-direct",
|
||||
"settings": {
|
||||
"domainStrategy": "UseIP"
|
||||
},
|
||||
"streamSettings": {
|
||||
"sockopt": {
|
||||
"mark": 255
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
// REVERSE TUNNEL INITIATION
|
||||
// This outbound initiates the connection to Server A.
|
||||
// Once established, Server A can send packets BACK through this tunnel.
|
||||
"protocol": "vless",
|
||||
"tag": "forward-a-reverse",
|
||||
"settings": {
|
||||
"address": "A-EXTERNAL-IP",
|
||||
"port": 443,
|
||||
"id": "REPLACE_WITH_UUID_B_REVERSE",
|
||||
"level": 0,
|
||||
"encryption": "none",
|
||||
"flow": "xtls-rprx-vision",
|
||||
"reverse": {
|
||||
"tag": "reverse-b"
|
||||
}
|
||||
},
|
||||
"streamSettings": {
|
||||
"network": "tcp",
|
||||
"security": "tls",
|
||||
"tlsSettings": {
|
||||
"serverName": "A-DOMAIN",
|
||||
"allowInsecure": false,
|
||||
"fingerprint": "chrome",
|
||||
"alpn": ["h2", "http/1.1"]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
// STANDARD PROXY OUTBOUND
|
||||
// Used for routing non-local 10.x.x.x traffic through Server A.
|
||||
"protocol": "vless",
|
||||
"tag": "forward-a",
|
||||
"settings": {
|
||||
"address": "A-EXTERNAL-IP",
|
||||
"port": 443,
|
||||
"id": "REPLACE_WITH_UUID_B_DIRECT",
|
||||
"level": 0,
|
||||
"encryption": "none",
|
||||
"flow": "xtls-rprx-vision"
|
||||
},
|
||||
"streamSettings": {
|
||||
"network": "tcp",
|
||||
"security": "tls",
|
||||
"tlsSettings": {
|
||||
"serverName": "A-DOMAIN",
|
||||
"allowInsecure": false,
|
||||
"fingerprint": "chrome",
|
||||
"alpn": ["h2", "http/1.1"]
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
"routing": {
|
||||
"rules": [
|
||||
{
|
||||
// Traffic from local host for other subnets (A or C) goes to Server A.
|
||||
"inboundTag": [ "proxy-enclave" ],
|
||||
"outboundTag": "forward-a"
|
||||
},
|
||||
{
|
||||
// Traffic arriving from Server A via the tunnel goes to local subnet breakout.
|
||||
"inboundTag": [ "reverse-b" ],
|
||||
"outboundTag": "forward-direct"
|
||||
},
|
||||
{
|
||||
// Ensure local 10.2.x.x traffic does not enter the tunnel loop.
|
||||
"ip": ["10.2.0.0/16"],
|
||||
"outboundTag": "forward-direct"
|
||||
},
|
||||
{
|
||||
// Route everything else in 10.0.0.0/8 to Server A for relay.
|
||||
"ip": ["10.0.0.0/8"],
|
||||
"outboundTag": "forward-a"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
# /etc/ufw/before.rules for Server C (10.3.0.0/16)
|
||||
#
|
||||
# These rules handle the transparent interception of 10.0.0.0/8 traffic
|
||||
# destined for other nodes (e.g., 10.1.x.x or 10.2.x.x).
|
||||
|
||||
COMMIT
|
||||
|
||||
*mangle
|
||||
:XRAY - [0:0]
|
||||
:XRAY_MASK - [0:0]
|
||||
:DIVERT - [0:0]
|
||||
|
||||
# Intercept Prerouting traffic (e.g. from local containers)
|
||||
-A XRAY -d 10.3.0.0/16 -j RETURN
|
||||
-A XRAY ! -d 10.0.0.0/8 -j RETURN
|
||||
-A XRAY -m mark --mark 0xff -j RETURN
|
||||
-A XRAY -p udp -j TPROXY --on-ip 127.0.0.1 --on-port 12345 --tproxy-mark 1
|
||||
-A XRAY -p tcp -j TPROXY --on-ip 127.0.0.1 --on-port 12345 --tproxy-mark 1
|
||||
-A PREROUTING -j XRAY
|
||||
|
||||
# Intercept Output traffic (originating from the server itself)
|
||||
-A XRAY_MASK -d 10.3.0.0/16 -j RETURN
|
||||
-A XRAY_MASK ! -d 10.0.0.0/8 -j RETURN
|
||||
-A XRAY_MASK -m mark --mark 0xff -j RETURN
|
||||
-A XRAY_MASK -p udp -j MARK --set-mark 1
|
||||
-A XRAY_MASK -p tcp -j MARK --set-mark 1
|
||||
-A OUTPUT -j XRAY_MASK
|
||||
|
||||
-A DIVERT -j MARK --set-mark 1
|
||||
-A DIVERT -j ACCEPT
|
||||
-I PREROUTING -p tcp -m socket -j DIVERT
|
||||
|
||||
COMMIT
|
||||
|
||||
*filter
|
||||
# Allow internal traffic between our subnet and the mimicry range
|
||||
-A ufw-before-forward -s 10.3.0.0/16 -d 10.3.0.0/16 -j ACCEPT
|
||||
-A ufw-before-forward -s 10.3.0.0/16 -d 10.0.0.0/8 -m mark --mark 0x1 -j ACCEPT
|
||||
|
||||
-A ufw-before-input -s 10.3.0.0/16 -d 10.3.0.0/16 -j ACCEPT
|
||||
-A ufw-before-input -s 10.3.0.0/16 -d 10.0.0.0/8 -m mark --mark 0x1 -j ACCEPT
|
||||
@@ -0,0 +1,14 @@
|
||||
name: 'c'
|
||||
|
||||
services:
|
||||
xray:
|
||||
image: ghcr.io/xtls/xray-core:26.1.23
|
||||
container_name: c-xray
|
||||
network_mode: host
|
||||
volumes:
|
||||
- ./xray.jsonc:/etc/xray/config.jsonc:ro
|
||||
command: -c '/etc/xray/config.jsonc'
|
||||
restart: unless-stopped
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
- NET_RAW
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
{
|
||||
// ==========================================
|
||||
// SERVER C: SPOKE NODE (Subnet: 10.3.0.0/16)
|
||||
// ==========================================
|
||||
// This node is identical in purpose to Server B,
|
||||
// but it is the authority for the 10.3.x.x range.
|
||||
|
||||
"log": {
|
||||
"loglevel": "info"
|
||||
},
|
||||
|
||||
"dns": {
|
||||
"servers": [
|
||||
// Queries are forwarded to Server A's central DNS.
|
||||
"10.1.1.3"
|
||||
]
|
||||
},
|
||||
|
||||
"inbounds": [
|
||||
{
|
||||
// TPROXY INBOUND
|
||||
"tag": "proxy-enclave",
|
||||
"listen": "127.0.0.1",
|
||||
"port": 12345,
|
||||
"protocol": "tunnel",
|
||||
"settings": {
|
||||
"network": "tcp,udp",
|
||||
"followRedirect": true
|
||||
},
|
||||
"sniffing": {
|
||||
"enabled": true,
|
||||
"destOverride": ["http", "tls", "quic"],
|
||||
"routeOnly": true
|
||||
},
|
||||
"streamSettings": {
|
||||
"sockopt": {
|
||||
"tproxy": "tproxy",
|
||||
"mark": 255
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
"outbounds": [
|
||||
{
|
||||
// FREEDOM OUTBOUND
|
||||
"protocol": "freedom",
|
||||
"tag": "forward-direct",
|
||||
"settings": {
|
||||
"domainStrategy": "UseIP"
|
||||
},
|
||||
"streamSettings": {
|
||||
"sockopt": {
|
||||
"mark": 255
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
// REVERSE TUNNEL INITIATION (Hubward)
|
||||
"protocol": "vless",
|
||||
"tag": "forward-a-reverse",
|
||||
"settings": {
|
||||
"address": "A-EXTERNAL-IP",
|
||||
"port": 443,
|
||||
"id": "REPLACE_WITH_UUID_C_REVERSE",
|
||||
"level": 0,
|
||||
"encryption": "none",
|
||||
"flow": "xtls-rprx-vision",
|
||||
"reverse": {
|
||||
"tag": "reverse-c"
|
||||
}
|
||||
},
|
||||
"streamSettings": {
|
||||
"network": "tcp",
|
||||
"security": "tls",
|
||||
"tlsSettings": {
|
||||
"serverName": "A-DOMAIN",
|
||||
"allowInsecure": false,
|
||||
"fingerprint": "chrome",
|
||||
"alpn": ["h2", "http/1.1"]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
// STANDARD PROXY OUTBOUND (Hubward)
|
||||
"protocol": "vless",
|
||||
"tag": "forward-a",
|
||||
"settings": {
|
||||
"address": "A-EXTERNAL-IP",
|
||||
"port": 443,
|
||||
"id": "REPLACE_WITH_UUID_C_DIRECT",
|
||||
"level": 0,
|
||||
"encryption": "none",
|
||||
"flow": "xtls-rprx-vision"
|
||||
},
|
||||
"streamSettings": {
|
||||
"network": "tcp",
|
||||
"security": "tls",
|
||||
"tlsSettings": {
|
||||
"serverName": "A-DOMAIN",
|
||||
"allowInsecure": false,
|
||||
"fingerprint": "chrome",
|
||||
"alpn": ["h2", "http/1.1"]
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
"routing": {
|
||||
"rules": [
|
||||
{
|
||||
"inboundTag": [ "proxy-enclave" ],
|
||||
"outboundTag": "forward-a"
|
||||
},
|
||||
{
|
||||
"inboundTag": [ "reverse-c" ],
|
||||
"outboundTag": "forward-direct"
|
||||
},
|
||||
{
|
||||
// Local 10.3.x.x traffic is breakout directly.
|
||||
"ip": ["10.3.0.0/16"],
|
||||
"outboundTag": "forward-direct"
|
||||
},
|
||||
{
|
||||
// All other 10.x.x.x traffic is proxied to Server A.
|
||||
"ip": ["10.0.0.0/8"],
|
||||
"outboundTag": "forward-a"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Xray Subnet Mimicry - Routing Setup Script
|
||||
# This script configures the Linux kernel and routing tables to allow
|
||||
# Xray to intercept and route traffic for the 10.0.0.0/8 subnet.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
echo "Applying routing configuration..."
|
||||
|
||||
# 1. Enable IP Forwarding
|
||||
# This is required for the server to act as a router/gateway.
|
||||
sudo sysctl -w net.ipv4.ip_forward=1
|
||||
|
||||
# 2. IP Rule for mark 0x1 -> table 100
|
||||
# Any packet marked with 0x1 (by our iptables/TPROXY rules)
|
||||
# will be forced to use routing table 100.
|
||||
if sudo ip rule show | grep -q 'fwmark 0x1 lookup 100'; then
|
||||
echo "IP rule for mark 0x1 already exists."
|
||||
else
|
||||
sudo ip rule add fwmark 0x1 lookup 100 priority 100
|
||||
echo "IP rule added for mark 0x1."
|
||||
fi
|
||||
|
||||
# 3. Local route in table 100
|
||||
# In table 100, we route everything to the local loopback.
|
||||
# This "tricks" the kernel into handing the packet to our TPROXY inbound
|
||||
# listening on 127.0.0.1:12345.
|
||||
if sudo ip route show table 100 2>/dev/null | grep -q 'local default dev lo'; then
|
||||
echo "Local route in table 100 already exists."
|
||||
else
|
||||
sudo ip route add local 0.0.0.0/0 dev lo table 100
|
||||
echo "Local route added to table 100."
|
||||
fi
|
||||
|
||||
echo "Routing configuration applied successfully."
|
||||
exit 0
|
||||
Reference in new issue
Block a user