diff --git a/.gitignore b/.gitignore index edd199ff7..463d5ac0f 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,5 @@ build/ *.key *.dat trojan-go + +docs/.hugo_build.lock \ No newline at end of file diff --git a/docs/config.toml b/docs/config.toml index 0e10edc96..d8b8ebf6e 100755 --- a/docs/config.toml +++ b/docs/config.toml @@ -1,16 +1,27 @@ baseURL = "https://p4gefau1t.github.io/trojan-go" -languageCode = "zh-CN" +languageCode = "en-US" title = "Trojan-Go Docs" theme = "hugo-theme-techdoc" hasCJKLanguage = true metaDataFormat = "yaml" -defaultContentLanguage = "zh" +defaultContentLanguage = "en" defaultContentLanguageInSubdir= true enableMissingTranslationPlaceholders = false + +[languages] + [languages.zh] + languageName = '中文' + contentDir = 'content/zh' + weight = 1 + [languages.en] + languageName = 'English' + contentDir = 'content/en' + weight = 2 + [params] # Source Code repository section @@ -68,14 +79,19 @@ enableMissingTranslationPlaceholders = false # See https://gohugo.io/content-management/menus/ [menu] [[menu.main]] - name = "Home" - url = "/" + name = "English (DeepL)" + url = "/en/" weight = 1 + [[menu.main]] + name = "Chinese (original)" + url = "/zh/" + weight = 2 + [[menu.main]] name = "GitHub" url = "https://github.com/p4gefau1t" - weight = 2 + weight = 3 # Markup configure section # See https://gohugo.io/getting-started/configuration-markup/ diff --git a/docs/content/en/_index.md b/docs/content/en/_index.md new file mode 100644 index 000000000..431319e62 --- /dev/null +++ b/docs/content/en/_index.md @@ -0,0 +1,24 @@ +--- +title: "Introduction" +draft: false +weight: 10 +--- + +# Trojan-Go + +{{% panel status="notice" title="English translation" %}} +Note that the documentation for Trojan-Go was translated from original Chinese using the automatic translation service [DeepL](https://www.deepl.com/translator). Please submit a PR if you find any discrepancy. +{{% /panel %}} + + +Here is the documentation for Trojan-Go, you can find some tips on how to use it in the left navigation bar, as well as a full description of the configuration file. + +Trojan-Go is a complete Trojan proxy implemented in Go, compatible with the Trojan protocol and the original configuration file format. It supports and is compatible with most of the features of the Trojan-GFW version, and extends it with more useful features. + +The primary goal of Trojan-Go is to guarantee transmission security and stealth. With this in mind, the performance and ease of use of the transfer is improved as much as possible. + +If you encounter configuration and usage problems, find software bugs, or have better ideas, feel free to join Trojan-Go's [Telegram Feedback Group](https://t.me/trojan_go_chat). + +---- + +> Across the Great Wall, we can reach every corner in the world. diff --git a/docs/content/en/advance/_index.md b/docs/content/en/advance/_index.md new file mode 100644 index 000000000..6e93c875b --- /dev/null +++ b/docs/content/en/advance/_index.md @@ -0,0 +1,7 @@ +--- +title: "Advanced Configuration" +draft: false +weight: 30 +--- + +This section describes more complex methods of Trojan-Go configuration. Features that are not compatible with the original version of Trojan will be explicitly marked in the subsections. diff --git a/docs/content/en/advance/aead.md b/docs/content/en/advance/aead.md new file mode 100644 index 000000000..5e37b193c --- /dev/null +++ b/docs/content/en/advance/aead.md @@ -0,0 +1,36 @@ +--- +title: "Secondary encryption with Shadowsocks AEAD" +draft: false +weight: 8 +--- + +{{% panel status="caution" title="Compatibility" %}} +Note that Trojan does not support this feature +{{% /panel %}} + +The Trojan protocol itself is not encrypted and its security relies on the underlying TLS. in general, TLS security is good and there is no need to encrypt Trojan traffic again. However, there are some scenarios where you may not be able to guarantee the security of a TLS tunnel. + +- You use a Websocket, relayed through an untrusted CDN (e.g. a domestic CDN) + +- Your connection to the server is subject to a man-in-the-middle attack by GFW against TLS + +- Your certificate is invalid and you cannot verify its validity + +- You use a pluggable transport layer that cannot guarantee cryptographic security + +etc. + +Trojan-Go supports encryption of Trojan-Go using Shadowsocks AEAD. The essence of this is to add a layer of Shadowsocks AEAD encryption underneath the Trojan protocol. Both the server and client must be enabled and the password and encryption must be the same, otherwise communication will not be possible. + +To turn on AEAD encryption, simply add a ```shadowsocks``` option to + +```json +... +"shadowsocks": { + "enabled": true, + "method": "AES-128-GCM", + "password": "1234567890" +} +``` + +If omitted, AES-128-GCM is used by default. for more information, see the section "Complete Configuration Files". diff --git a/docs/content/en/advance/api.md b/docs/content/en/advance/api.md new file mode 100644 index 000000000..7740ebf56 --- /dev/null +++ b/docs/content/en/advance/api.md @@ -0,0 +1,117 @@ +--- +title: "Managing users dynamically using the API" +draft: false +weight: 10 +--- + +{{% panel status="caution" title="Compatibility" %}} +Note that Trojan does not support this feature +{{% /panel %}} + +Trojan-Go provides a set of APIs using gRPC, which supports the following features. + +- user information addition, deletion, and checking + +- traffic statistics + +- speed statistics + +- IP connection statistics + +Trojan-Go itself has integrated API control, i.e. you can use one Trojan-Go instance to control another Trojan-Go server. + +You need to add API settings to the configuration of the server you need to be controlled, e.g. + +```json +{ + ... + "api": { + "enabled": true, + "api_addr": "127.0.0.1", + "api_port": 10000, + } +} +``` + +Then start the Trojan-Go server + +```shell +. /trojan-go -config . /server.json +``` + +You can then use another Trojan-Go to connect to that server for administration, with the basic command format + +```shell +. /trojan-go -api-addr SERVER_API_ADDRESS -api COMMAND +``` + +where ```SERVER_API_ADDRESS``` is the API address and port, e.g. 127.0.0.1:10000 + +```COMMAND``` is the API command, the legal commands are + +- list List all users + +- get to get information about a user + +- set set the information of a user (add/remove/modify) + +Here are some examples + +1. list all user information + + ```shell + . /trojan-go -api-addr 127.0.0.1:10000 -api list + ``` + + All user information will be exported as json, the information includes the number of online IPs, live speed, total upload and download traffic, etc. Here is an example of the returned results + + ```json + [{"user":{"hash":"d63dc919e201d7bc4c825630d2cf25fdc93d4b2f0d46706d29038d01"},"status":{"traffic_total":{"upload_traffic":36393,"download_traffic":186478},"speed_current":{"upload_speed":25210,"download_speed":72384},"speed_limit":{"upload_speed":5242880,"download_speed":5242880},"ip_limit":50}}] + ``` + + All traffic units are bytes. + +2. Get a user's information + + You can use -target-password to specify the password, or -target-hash to specify the SHA224 hash of the target user's password. The format is the same as the list command + + ```shell + . /trojan-go -api-addr 127.0.0.1:10000 -api get -target-password password + ``` + + or + + ```shell + . /trojan-go -api-addr 127.0.0.1:10000 -api get -target-hash d63dc919e201d7bc4c825630d2cf25fdc93d4b2f0d46706d29038d01 + ``` + + The above two commands are equivalent. The following example uses the plaintext password in a uniform way, and the hash specifies a certain user in a similar way. + + The user information will be exported in the form of json in a format similar to the list command. Here is an example of the returned result + + ```json + {"user":{"hash":"d63dc919e201d7bc4c825630d2cf25fdc93d4b2f0d46706d29038d01"},"status":{"traffic_total":{"upload_traffic":36393,"download_traffic":186478},"speed_current":{"upload_speed":25210,"download_speed":72384},"speed_limit":{"upload_speed":5242880,"download_speed":5242880},"ip_limit":50}} + ``` + +3. add a user information + + ```shell + . /trojan-go -api-addr 127.0.0.1:10000 -api set -add-profile -target-password password + ``` + +4. delete a user information + + ```shell + . /trojan-go -api-addr 127.0.0.1:10000 -api set -delete-profile -target-password password + ``` + +5. modify a user information + + ```shell + . /trojan-go -api-addr 127.0.0.1:10000 -api set -modify-profile -target-password password \ + -ip-limit 3 \ + -upload-speed-limit 5242880 \ + -download-speed-limit 5242880 + ``` + + This command limits the upload and download speed to 5MiB/s for users with password, and the number of connected IPs is limited to 3. Note that the unit of 5242880 here is bytes. If you fill in 0 or a negative number, it means no limit is applied. diff --git a/docs/content/en/advance/customize-protocol-stack.md b/docs/content/en/advance/customize-protocol-stack.md new file mode 100644 index 000000000..f2816476e --- /dev/null +++ b/docs/content/en/advance/customize-protocol-stack.md @@ -0,0 +1,202 @@ +--- +title: "Custom Protocol Stack" +draft: false +weight: 8 +--- + +{{% panel status="caution" title="Compatibility" %}} +Note that Trojan does not support this feature +{{% /panel %}} + +Trojan-Go allows advanced users to customize the protocol stack. In custom mode, Trojan-Go will relinquish control of the protocol stack and allow users to manipulate the underlying protocol stack combinations. For example: + +- Creating one or more layers of TLS encryption on top of one layer of TLS + +- Use TLS to transport Websocket traffic, build another layer of TLS on top of the Websocket layer, and then use Shadowsocks AEAD on top of the second layer of TLS for encrypted transport + +- Encrypted transport of Trojan protocol using Shadowsocks AEAD on a TCP connection + +- Unwrap an inbound Trojan TLS traffic and repackage it with TLS as a new outbound Trojan traffic + +And so on. + + +{{% panel status="warning" title="Caution" %}} +Do not try to use this feature if you don't know anything about networking. Incorrect configuration may cause Trojan-Go to not work properly, or cause performance and security issues. +{{% /panel %}} + +Trojan-Go abstracts all protocols into tunnels, each of which may provide a client, which is responsible for sending, a server, which is responsible for receiving, or both. The custom protocol stack is how the custom tunnels are stacked. + +{{% panel status="notice" title="Prerequisite" %}} +Before proceeding with the configuration, please read the "Basic Introduction" section of the Developer's Guide to ensure that you understand how Trojan-Go works. +{{% /panel %}} + + +Here are the tunnels supported by Trojan-Go and their properties: + + +| Tunnel | Requires lower layer to provide streams | Requires lower layer to provide packages | Provides streams to upper layer | Provides packages to upper layer | Can be used as inbound | Can be used as outbound | +| ----------- | -------------- | -------------- | ------------ | ------------ | ------------ | ------------ | +| transport | n | n | y | y | y | y | +| dokodemo | n | n | y | y | y | n | +| tproxy | n | n | y | y | y | n | +| tls | y | n | y | n | y | y | +| trojan | y | n | y | y | y | y | +| mux | y | n | y | n | y | y | +| simplesocks | y | n | y | y | y | y | +| shadowsocks | y | n | y | n | y | y | +| websocket | y | n | y | n | y | y | +| freedom | n | n | y | y | n | y | +| socks | y | y | y | y | y | n | +| http | y | n | y | n | y | n | +| router | y | y | y | y | n | y | +| adapter | n | n | y | y | y | n | + + +A custom stack works by defining nodes in a tree/chain and naming them individually (tags) and adding configurations, and then describing the tree/chain using a directed path composed of the tags. For example, for a typical Trojan-Go server, it can be described as follows. + +Inbound, there are two paths, and the tls node will automatically identify trojan and websocket traffic and distribute it + +- transport->tls->trojan + +- transport->tls->websocket->trojan + +Outbound, there can only be one path + +- router->freedom + +For inbound, multiple paths are described starting from the root, forming a **multinomial tree** (which can also degenerate to a chain); graphs that do not satisfy the tree property will result in undefined behavior; for outbound, a **chain** must be described. + +Each path must satisfy the condition that. + +1. must start with a tunnel that **does not require lower layers to provide streams or packets** (transport/adapter/tproxy/dokodemo, etc.) + +2. must terminate with a tunnel that **provides packets and streams** to the upper layer (trojan/simplesocks/freedom, etc.) + +3. on outbound single chains, the tunnels must all be available as outbound. On all paths of the inbound, the tunnels must all be available as inbound. + +To enable custom stacks, specify ```run_type``` as custom, where all options other than ```inbound``` and ```outbound``` will be ignored. + +Here is an example of a protocol node that you can insert or reduce on top of this. The configuration file is configured using YAML for simplicity, you can also configure it using JSON, the effect is equivalent except for the difference in format. + +Client client.yaml + +```yaml +run-type: custom + +inbound: + node: + - protocol: adapter + tag: adapter + config: + local-addr: 127.0.0.1 + local-port: 1080 + - protocol: socks + tag: socks + config: + local-addr: 127.0.0.1 + local-port: 1080 + path: + path: - + - adapter + - socks + +outbound: + node: + - protocol: transport + tag: transport + config: + remote-addr: you_server + remote-port: 443 + + - protocol: tls + tag: tls + config: + ssl: + sni: localhost + key: server.key + cert: server.crt + + - protocol: trojan + tag: trojan + config: + password: + - password: 12345678 + + path: + -transport + - transport + - tls + - trojan + +``` + +server server.yaml + +```yaml +run-type: custom + +inbound: + node: + - protocol: websocket + tag: websocket + config: + websocket: + enabled: true + hostname: example.com + path: /ws + + - protocol: transport + tag: transport + config: + local-addr: 0.0.0.0 + local-port: 443 + remote-addr: 127.0.0.1 + remote-port: 80 + + - protocol: tls + tag: tls + config: + remote-addr: 127.0.0.1 + remote-port: 80 + ssl: + sni: localhost + key: server.key + cert: server.crt + + - protocol: trojan + tag: trojan1 + config: + remote-addr: 127.0.0.1 + remote-port: 80 + password: + - 12345678 + + - protocol: trojan + tag: trojan2 + config: + remote-addr: 127.0.0.1 + remote-port: 80 + password: + - 87654321 + + path: + - + - transport + - tls + - trojan1 + -transport + - transport + - tls + - websocket + - trojan2 + +outbound: + node: + - protocol: freedom + tag: freedom + + path: + -freedom + - freedom +``` diff --git a/docs/content/en/advance/forward.md b/docs/content/en/advance/forward.md new file mode 100644 index 000000000..1337ca1b5 --- /dev/null +++ b/docs/content/en/advance/forward.md @@ -0,0 +1,64 @@ +--- +title: "Tunnels and reverse proxies" +draft: false +weight: 5 +--- + +You can use Trojan-Go to set up tunnels. A typical application is to use Trojan-Go to set up a local, unpolluted DNS server, here is an example configuration + +```json +{ + "run_type": "forward", + "local_addr": "127.0.0.1", + "local_port": 53, + "remote_addr": "your_awesome_server", + "remote_port": 443, + "target_addr": "8.8.8.8", + "target_port": 53, + "password": [ + "your_awesome_password" + ] +} +``` + +forward is essentially a client, but you need to fill in the ```target_addr``` and ```target_port``` fields to indicate the target of the reverse proxy. + +After using this configuration file, the local 53 TCP and UDP ports will be listened to, and all TCP or UDP data sent to the local 53 port will be forwarded to the remote server ```your_awesome_server``` via TLS tunnel, and after the remote server gets a response, the data will be returned to the local 53 port via the tunnel. In other words, you can treat 127.0.0.1 as a DNS server, and the results of the local query and the remote server query are the same. You can use this configuration to bypass DNS pollution. + +On the same principle, you can build a Google mirror locally + +```json +{ + "run_type": "forward", + "local_addr": "127.0.0.1", + "local_port": 443, + "remote_addr": "your_awesome_server", + "remote_port": 443, + "target_addr": "www.google.com", + "target_port": 443, + "password": [ + "your_awesome_password" + ] +} +``` + +Visit ```https://127.0.0.1``` to access the Google homepage, but note that here the browser will raise a certificate error warning because the https certificate provided by the Google server is that of google.com, and the current domain is 127.0.0.1. + +Similarly, other proxy protocols can be used for forward transfers. For example, using Trojan-Go to transfer traffic from shadowsocks, the remote host opens the ss server and listens to 127.0.0.1:12345, and the remote server opens the normal Trojan-Go server on port 443. You can specify the configuration like this + +```json +{ + "run_type": "forward", + "local_addr": "0.0.0.0", + "local_port": 54321, + "remote_addr": "your_awesome_server", + "remote_port": 443, + "target_addr": "www.google.com", + "target_port": 12345, + "password": [ + "your_awesome_password" + ] +} +``` + +Thereafter, any TCP/UDP connection to the local port 54321 is equivalent to a connection to the remote port 12345. You can use the shadowsocks client to connect to local port 54321 and ss traffic will be transferred to the ss server on the remote port 12345 using trojan's tunnel connection. diff --git a/docs/content/en/advance/mux.md b/docs/content/en/advance/mux.md new file mode 100644 index 000000000..4dcbd0553 --- /dev/null +++ b/docs/content/en/advance/mux.md @@ -0,0 +1,44 @@ +--- +title: "Enabling multiplexing to improve network concurrency performance" +draft: false +weight: 1 +--- + +{{% panel status="caution" title="Compatibility" %}} +Note that Trojan does not support this feature +{{% /panel %}} + +Trojan-Go supports the use of multiplexing to improve network concurrency performance. + +The Trojan protocol is based on TLS, and before a secure TLS connection can be established, both sides of the connection need to negotiate and exchange keys to ensure the security of the subsequent communication. This process is known as the TLS handshake. + +The GFW currently censors and interferes with the TLS handshake, and due to egress network congestion, it usually takes nearly a second or more for an ordinary line to complete the TLS handshake. This can lead to increased latency for web browsing and video viewing. + +Trojan-Go uses multiplexing to solve this problem. Each established TLS connection will host multiple TCP connections. When a new proxy request arrives, instead of handshaking with the server to initiate a new TLS connection, existing TLS connections are reused whenever possible. This reduces the latency caused by frequent TLS handshakes and TCP handshakes. + +Enabling multiplexing will not increase your link speed (or even decrease it), and may increase the computational burden on the server and client. Roughly speaking, multiplexing can be interpreted as sacrificing network throughput and CPU power for lower latency. It can improve the usage experience in high concurrency scenarios, such as when browsing web pages containing a large number of images, or when sending a large number of UDP requests. + +To activate the ```mux``` module, just set the ```enabled``` field in the ```mux``` option to true, here is a client-side example + +```json +... +"mux" :{ + "enabled": true +} +``` + +Just configure the client side, the server side can be adapted automatically without configuring the ```mux``` option. + +The complete mux configuration is as follows + +```json +"mux": { + "enabled": false, + "concurrency": 8, + "idle_timeout": 60 +} +``` + +```concurrency``` is the maximum number of TCP connections that each TLS connection can carry. The larger this value is, the more each TLS connection is reused and the lower the latency due to handshaking. However, the greater the computational burden on the server and client will also be, which could potentially make your network throughput lower. If your line's TLS handshake is extremely slow, you can set this value to -1 and Trojan-Go will perform only one TLS handshake, using only one TLS connection for transmission. + +The ```idle_timeout``` refers to how long each TLS connection is idle before it is closed. Setting the timeout time **may** help reduce unnecessary long connection live confirmation (Keep Alive) traffic transmissions triggering GFW probes. You can set this value to -1 and TLS connections will be closed immediately when idle. diff --git a/docs/content/en/advance/nat.md b/docs/content/en/advance/nat.md new file mode 100644 index 000000000..3ad79710c --- /dev/null +++ b/docs/content/en/advance/nat.md @@ -0,0 +1,51 @@ +--- +title: "Transparent Proxy" +draft: false +weight: 11 +--- + +{{% panel status="caution" title="Compatibility" %}} +Note that Trojan does not fully support this feature (UDP) +{{% /panel %}} + +Trojan-Go supports transparent TCP/UDP proxies based on tproxy. + +To enable transparent proxy mode, change ```run_type``` to ```nat``` in a proper client configuration (see the basic configuration section for how to configure it) and modify the local listening port as required. + +After that you need to add iptables rules. Assuming that your gateway has two NICs, this configuration below forwards inbound packets from one of the NICs (LAN) to Trojan-Go, which sends them through a tunnel to the remote Trojan-Go server via the other NIC (Internet). You need to replace the following ```$SERVER_IP```, ```$TROJAN_GO_PORT```, ```$INTERFACE``` with your own configuration. + +```shell +# New TROJAN_GO chain +iptables -t mangle -N TROJAN_GO + +# Bypass Trojan-Go server address +iptables -t mangle -A TROJAN_GO -d $SERVER_IP -j RETURN + +# Bypass private addresses +iptables -t mangle -A TROJAN_GO -d 0.0.0.0/8 -j RETURN +iptables -t mangle -A TROJAN_GO -d 10.0.0.0/8 -j RETURN +iptables -t mangle -A TROJAN_GO -d 127.0.0.0/8 -j RETURN +iptables -t mangle -A TROJAN_GO -d 169.254.0.0/16 -j RETURN +iptables -t mangle -A TROJAN_GO -d 172.16.0.0/12 -j RETURN +iptables -t mangle -A TROJAN_GO -d 192.168.0.0/16 -j RETURN +iptables -t mangle -A TROJAN_GO -d 224.0.0.0/4 -j RETURN +iptables -t mangle -A TROJAN_GO -d 240.0.0.0/4 -j RETURN + +# Packets that do not hit the rule above, mark them +iptables -t mangle -A TROJAN_GO -j TPROXY -p tcp --on-port $TROJAN_GO_PORT --tproxy-mark 0x01/0x01 +iptables -t mangle -A TROJAN_GO -j TPROXY -p udp --on-port $TROJAN_GO_PORT --tproxy-mark 0x01/0x01 + +# All TCP/UDP packets flowing from $INTERFACE NIC, jump TROJAN_GO chain +iptables -t mangle -A PREROUTING -p tcp -i $INTERFACE -j TROJAN_GO +iptables -t mangle -A PREROUTING -p udp -i $INTERFACE -j TROJAN_GO + +# Add routes to re-enter the local loopback with marked packets +ip route add local default dev lo table 100 +ip rule add fwmark 1 lookup 100 +``` + +After configuration is complete **start with root privileges** Trojan-Go client. + +```shell +sudo trojan-go +``` diff --git a/docs/content/en/advance/nginx-relay.md b/docs/content/en/advance/nginx-relay.md new file mode 100644 index 000000000..62eca230d --- /dev/null +++ b/docs/content/en/advance/nginx-relay.md @@ -0,0 +1,113 @@ +--- +title: "A multi-path split relaying scheme based on SNI proxy" +draft: false +weight: 6 +--- + +## Preface + +Trojan is a tool for encrypted data transmission through TLS encapsulation. By using its TLS feature, we can achieve different paths of relaying on the same host port through SNI proxy. + +## Required tools and other preparations + +- Relay machine: nginx version 1.11.5 and above +- Landing machine: trojan server (no version required) + +## Configuration method + +For the sake of illustration, two relay hosts and two landing hosts are used here. +The four hosts are bound to the domain name (a/b/c/d).example.com as shown in the figure. +There are 4 paths to each other. They are a-c, a-d, b-c, and b-d, respectively. + +```text + +-----------------+ +--------------------+ + | +---------->+ | + | VPS RELAY A | | VPS ENDPOINT C | + +---->+ | +------>+ | + | | a.example.com | | | c.example.com | + | | +------+ | | + +----------+ | +-----------------+ | | +--------------------+ + | | | | | + | client +----+ | | + | | | | | + +----------+ | +-----------------+ | | +--------------------+ + | | | | | | | + | | VPS RELAY B | | +--->+ VPS ENDPOINT D | + +---->+ +---+ | | + | b.example.com | | d.example.com | + | +---------->+ | + +-----------------+ +--------------------+ +``` + +### Configure path domain names and corresponding certificates + +First we need to assign each path a separate domain name and make it resolve to the respective entry host. + +```text +a-c.example.com CNAME a.example.com +a-d.example.com CNAME a.example.com +b-c.example.com CNAME b.example.com +b-d.example.com CNAME b.example.com +``` + +Then we need to deploy certificates for all target paths on the landing host +HTTP authentication cannot be passed because the resolution record and the host IP do not match. Here it is recommended to use DNS authentication to issue certificates. +The specific DNS validation plugin needs to be chosen according to your domain DNS resolution host, here AWS Route 53 is used. + +```shell +certbot certonly --dns-route53 -d a-c.example.com -d b-c.example.com // on host C +certbot certonly --dns-route53 -d a-d.example.com -d b-d.example.com // on host D +``` + +### Configuring SNI proxy + +Here we use the ssl_preread module of nginx to implement the SNI proxy. +Please fix the nginx.conf file as follows after installing nginx. +Note that this is not an HTTP service, so please do not write it in the configuration of the virtual host. + +The corresponding configuration for host A is given here, and the same for host B. + +```nginx +stream { + map $ssl_preread_server_name $name { + a-c.example.com c.example.com; # Forward a-c path traffic to host C + a-d.example.com d.example.com; # Forward a-d path traffic to host D + + # If you need to configure other services on this host that take up port 443 (such as web services and Trojan services) + # Please make those services listen on other local ports (4000 is used here) + # All TLS requests that do not match the SNI above will be forwarded to this port, remove this line if you don't need it + default localhost:4000; + default localhost:4000; } + + server { + listen 443; # listen on port 443 + proxy_pass $name; + ssl_preread on; + ssl_preread on; } +} +``` + +### Configuring the landed Trojan service + +In the previous configuration we used a certificate to issue the domain names for all target paths, so here we can use a Trojan server to handle requests for all target paths. +The configuration of Trojan is no different from the usual configuration method, and an example is still provided here. Unrelated configuration has been omitted. + +```json +{ + "run_type": "server", + "local_addr": "0.0.0.0", + "local_port": 443, + "ssl": { + "cert": "/path/to/certificate.crt", + "key": "/path/to/private.key", + } + ... +} +``` + +Tip: If you need to use separate Trojan servers for different paths on the landed host (for example, if you need to access your own billing service), you can configure an SNI proxy on the landed machine and forward it to a different local Trojan server listening port. Since the configuration is basically the same as the process mentioned above, we will not repeat it here. + +## Summary + +With the configuration method described above, we can implement multi-entry, multi-exit, multi-stage trunking of Trojan traffic on a single port. +For multi-stage trunking, simply configure the SNI proxy on the intermediate nodes along the same lines. diff --git a/docs/content/en/advance/plugin.md b/docs/content/en/advance/plugin.md new file mode 100644 index 000000000..49f50b456 --- /dev/null +++ b/docs/content/en/advance/plugin.md @@ -0,0 +1,61 @@ +--- +title: "Using Shadowsocks Plugin/Pluggable Transport Layer" +draft: false +weight: 7 +--- + +{{% panel status="caution" title="Compatibility" %}} +Note that Trojan does not support this feature +{{% /panel %}} + + +Trojan-Go supports a pluggable transport layer. In principle, Trojan-Go can use any software that has TCP tunneling capabilities as a transport layer, such as v2ray, shadowsocks, kcp, etc. Also, Trojan-Go is compatible with Shadowsocks' SIP003 plugin standard, such as GoQuiet, v2ray-plugin, etc. You can also use Tor's transport layer plugins, such as obfs4, meek, etc. + +You can use these plugins to replace the TLS transport layer of Trojan-Go. + +With pluggable transport layer plugins turned on, the Trojan-Go client will transmit **traffic plaintext** directly to the client local plugins for processing. The client-side plug-in is responsible for encryption and obfuscation, and transmits the traffic to the server-side plug-in. The server-side plugin receives the traffic, decrypts and parses it, and transmits **traffic plaintext** to the server-side local Trojan-Go server. + +You can use any plugin to encrypt and obfuscate the traffic, just add the "transport_plugin" option, specify the path to the plugin's executable, and configure it properly. + +We recommend that you design your own protocols and develop your own plugins**. Because all existing plugins can not interface with Trojan-Go's features to combat active detection, and some plugins do not have encryption capabilities. If you are interested in developing plugins, feel free to check out the guidelines for plugin design in the "Implementation details and development guidelines" section. + +For example, you can use the SIP003-compliant v2ray-plugin, an example of which is shown below: + +{{% panel status="warning" title="Caution" %}} +This configuration uses websocket to transmit unencrypted trojan protocol in clear text, which is a security risk. This configuration is for demonstration purposes only. +{{% /panel %}} + +{{% panel status="danger" title="Warning" %}} +Do not use this configuration to penetrate GFW under any circumstances. +{{% /panel %}} + + +Server-side configuration. + +```json +... (omitted) +"transport_plugin": { + "enabled": true, + "type": "shadowsocks", + "command": ". /v2ray-plugin", + "arg": ["-server", "-host", "www.baidu.com"] +} +``` + +Client configuration. + +```json +... (omitted) +"transport_plugin": { + "enabled": true, + "type": "shadowsocks", + "command": ". /v2ray-plugin", + "arg": ["-host", "www.baidu.com"] +} +``` + +Note that the v2ray-plugin plugin needs to specify the ```-server``` parameter to distinguish between client and server. For more detailed instructions on the plugin, refer to the v2ray-plugin documentation. + +After starting Trojan-Go, you can see the output of v2ray-plugin startup. The plugin will disguise the traffic as websocket traffic and transmit it. + +Non-SIP003 standard plugins may require different configuration, you can specify ```type``` as ```other``` and specify the plugin address, plugin startup parameters, environment variables by yourself. diff --git a/docs/content/en/advance/router.md b/docs/content/en/advance/router.md new file mode 100644 index 000000000..ce047dd53 --- /dev/null +++ b/docs/content/en/advance/router.md @@ -0,0 +1,78 @@ +--- +title: "Domestic direct connection and ad blocking" +draft: false +weight: 3 +--- + +{{% panel status="caution" title="Compatibility" %}} +Note that Trojan does not support this feature +{{% /panel %}} + +Trojan-Go's built-in routing module can help you implement domestic direct connections, i.e., the client can connect directly to domestic websites without going through a proxy. + +The routing module can be configured with three policies (```bypass```, ```proxy```, ```block```) on the client side, and only the ```block``` policy can be used on the server side. + +Here is an example + +```json +{ + "run_type": "client", + "local_addr": "127.0.0.1", + "local_port": 1080, + "remote_addr": "your_server", + "remote_port": 443, + "password": [ + "your_password" + ], + "ssl": { + "sni": "your-domain-name.com" + }, + "mux" :{ + "enabled": true + }, + "router":{ + "enabled": true, + "bypass": [ + "geoip:cn", + "geoip:private", + "geosite:cn", + "geosite:geolocation-cn" + ], + "block": [ + "geosite:category-ads" + ], + "proxy": [ + "geosite:geolocation-!cn" + ] + } +} +``` + +This configuration file activates the router module, which uses a whitelist mode, and connects directly when matched to an IP/domain name from mainland China or the LAN. If it is the domain name of the advertising operator, it is directly disconnected. + +The required databases ```geoip.dat``` and ```geosite.dat``` are included in the release zip and can be used directly. They come from V2Ray's [domain-list-community](https://github.com/v2fly/domain-list-community) and [geoip](https://github.com/v2fly/geoip). + +You can specify a certain category of domains using forms like ```geosite:cn```, ```geosite:geolocation-!cn```, ```geosite:category-ads-all```, ```geosite:bilibili```, and all available tags can be found in [ domain-list-community](https://github.com/v2fly/domain-list-community) repository of [data](https://github.com/v2fly/domain-list-community/tree/master/data) directory. ```geosite.dat``` For more detailed usage instructions, refer to [V2Ray/Routing#List of predefined domains](https://www.v2fly.org/config/routing.html#预定义域名列表). + +You can specify a certain category of IPs using forms such as ```geoip:cn```, ```geoip:hk```, ```geoip:us```, and ```geoip:private```. ```geoip:private``` is a special entry that encompasses intranet IPs and reserved IPs, and the rest of the categories encompass individual country/region IP address segment. Refer to [Wikipedia](https://zh.wikipedia.org/wiki/%E5%9C%8B%E5%AE%B6%E5%9C%B0%E5%8D%80%E4%BB%A3%E7%A2%BC) for the country/region codes. + +You can also configure your own routing rules. For example, to block all example.com domains and their subdomains, as well as 192.168.1.0/24, add the following rule. + +```json +"block": [ + "domain:example.com", + "cidr:192.168.1.0/24" +] +``` + +The supported formats are + +- "domain:", subdomain match + +- "full:", full domain match + +- "regexp:", regular expression match + +- "cidr:", CIDR match + +For more details, please refer to the section "The Complete Configuration File". diff --git a/docs/content/en/advance/websocket.md b/docs/content/en/advance/websocket.md new file mode 100644 index 000000000..5c0bb364b --- /dev/null +++ b/docs/content/en/advance/websocket.md @@ -0,0 +1,53 @@ +--- +title: "CDN forwarding and resisting man-in-the-middle attacks using Websocket" +draft: false +weight: 2 +--- + +{{% panel status="caution" title="Compatibility" %}} +Note that Trojan does not support this feature +{{% /panel %}} + +Trojan-Go supports using TLS+Websocket to host the Trojan protocol, making it possible to relay traffic using CDNs. + +The Trojan protocol itself is not encrypted and relies on the outer layer of TLS for security, but once the traffic passes through the CDN, TLS is transparent to the CDN. Its service provider can review the plaintext content of the TLS. **If you are using an untrusted CDN (any CDN service registered and filed in mainland China should be considered untrusted), please make sure to turn on Shadowsocks AEAD to encrypt Webosocket traffic to avoid being identified and censored.** + +Add the websocket option to both the server and client configuration files and set its ```enabled``` field to true, and fill in the ```path``` field and the ```host``` field to enable websocket support. Here is a complete Websocket option: + +```json +"websocket": { + "enabled": true, + "path": "/your-websocket-path", + "host": "example.com" +} +``` + +```host``` is the host name, usually fill in the domain name. Client ```host``` is optional, fill in your domain name. If left blank, it will be filled in with ```remote_addr```. + +The ```path``` refers to the URL path where the websocket is located and must start with a slash ("/"). There are no special requirements for the path, just satisfy the basic URL format, but make sure that the ```path``` of the client and server are the same. The ```path``` should be a longer string to avoid direct active detection by GFW. + +The client's ```host``` will be included in the Websocket handshake HTTP request sent to the CDN server and must be valid; the server and client ```path``` must be the same, otherwise the Websocket handshake will not work. + +Here is an example of a client-side configuration file + +```json +{ + "run_type": "client", + "local_addr": "127.0.0.1", + "local_port": 1080, + "remote_addr": "www.your_awesome_domain_name.com", + "remote_port": 443, + "password": [ + "your_password" + ], + "websocket": { + "enabled": true, + "path": "/your-websocket-path", + "host": "example.com" + }, + "shadowsocks": { + "enabled": true, + "password": "12345678" + } +} +``` diff --git a/docs/content/en/basic/_index.md b/docs/content/en/basic/_index.md new file mode 100644 index 000000000..2f97e932e --- /dev/null +++ b/docs/content/en/basic/_index.md @@ -0,0 +1,7 @@ +--- +title: "Basic Configuration" +draft: false +weight: 20 +--- + +This section describes how to configure the basic Trojan-Go proxy server and client. diff --git a/docs/content/en/basic/config.md b/docs/content/en/basic/config.md new file mode 100644 index 000000000..d2df58114 --- /dev/null +++ b/docs/content/en/basic/config.md @@ -0,0 +1,101 @@ +--- +title: "Configuring Trojan-Go correctly" +draft: false +weight: 22 +--- + +The following section will describe how to properly configure Trojan-Go to completely hide your proxy node features. + +Before you start, you need + +- A server that is not blocked by GFW + +- A domain name, you can use a free domain name service such as .tk + +- Trojan-Go, which can be downloaded from the release page + +- Certificates and keys, which can be issued for free from agencies such as letsencrypt + +### Server-side configuration + +Our goal is to make your server behave the same as a normal HTTPS site. + +First you need an HTTP server, you can configure a local HTTP server using nginx, apache, caddy etc. or you can use someone else's HTTP server. the role of the HTTP server is to show a fully functional web page to GFW when it actively detects it. + +**You need to specify the address of this HTTP server in ```remote_addr``` and ```remote_port```. The ```remote_addr``` can be either an IP or a domain name. Trojan-Go will test if this HTTP server is working properly, and if not, Trojan-Go will refuse to start it.** + +The following is a more secure server configuration server.json, which requires you to configure an HTTP service on local port 80 (if necessary, you can also use another HTTP server for your website, such as "remote_addr": "example.com") and an HTTPS service on port 1234, or a static HTTP service that displays "400 Bad Request" static HTTP web service. (Optionally, you can delete the ```fallback_port``` field and skip this step) + +```json +{ + "run_type": "server", + "local_addr": "0.0.0.0", + "local_port": 443, + "remote_addr": "127.0.0.1", + "remote_port": 80, + "password": [ + "your_awesome_password" + ], + "ssl": { + "cert": "server.crt", + "key": "server.key", + "fallback_port": 1234 + } +} +``` + +This configuration file causes Trojan-Go to listen on port 443 on all IP addresses of the server (0.0.0.0), using server.crt and server.key as the certificate and key for the TLS handshake, respectively. You should use as complex a password as possible, while making sure that the client and server ```password``` are the same. Note that **Trojan-Go will check if your HTTP server ```http://remote_addr:remote_port``` is working properly. If your HTTP server is not working properly, Trojan-Go will refuse to start it.** + +When a client tries to connect to Trojan-Go's listening port, the following happens. + +- If the TLS handshake is successful and the contents of the TLS are detected as non-Trojan protocol (possibly an HTTP request, or an active probe from GFW). Trojan-Go proxies the TLS connection to the HTTP service on local 127.0.0.1:80. At this point it appears to the remote end that the Trojan-Go service is an HTTPS site. + +- If the TLS handshake is successful and is confirmed to be a Trojan protocol header with the correct password in it, then the server will parse the request from the client and proxy it, otherwise it is handled in the same way as in the previous step. + +- If the TLS handshake fails, the other party is using a protocol other than TLS to connect. At this point Trojan-Go proxies the TCP connection to an HTTPS service (or HTTP service) running on local 127.0.0.1:1234, returning an HTTP page displaying 400 Bad Reqeust. The ```fallback_port``` is an optional option, if not filled in, Trojan-Go will simply terminate the connection. Although it is optional, it is highly recommended to fill it in. + +You can verify this by visiting your domain ```https://your-domain-name.com``` using your browser. If it works properly, your browser will display a normal HTTPS-protected web page with the same content as the page on the server's native port 80. You can also use ```http://your-domain-name.com:443``` to verify that ```fallback_port``` is working properly. + +In fact, you can even use Trojan-Go as your HTTPS server to serve HTTPS to your website. Visitors can browse your site through Trojan-Go normally, without affecting each other and the proxy traffic. Note, however, that you should not build services with high real-time requirements at ```remote_port``` and ```fallback_port```. Trojan-Go will intentionally add a small delay when it identifies non-Trojan protocol traffic to resist GFW's time-based detection. + +Once configured, you can use the + +```shell +./trojan-go -config ./server.json +``` + +Start the server. + +### Client configuration + +The corresponding client configuration client.json + +```json +{ + "run_type": "client", + "local_addr": "127.0.0.1", + "local_port": 1080, + "remote_addr": "your_awesome_server", + "remote_port": 443, + "password": [ + "your_awesome_password" + ], + "ssl": { + "sni": "your-domain-name.com" + } +} +``` + +This client configuration enables Trojan-Go to open a socks5/http proxy listening on local port 1080 (auto-aware) with a remote server of your_awesome_server:443, your_awesome_server can be an IP or domain name. + +If you fill in ```remote_addr``` with a domain name, ```sni``` can be omitted. If you fill in ```remote_addr``` with the IP address, the ```sni``` field should be filled in with the corresponding domain name of the certificate you applied for, or the Common Name of the certificate you issued yourself, and it must be consistent. Note that the ```sni``` field is currently in the TLS protocol **explicit transmission** (the purpose is to make the server provide the corresponding certificate). GFW has been proven to have SNI detection and blocking capabilities, so do not fill in similar ```google.com``` and other domains that have been blocked, otherwise it is likely to cause your server to be blocked as well. + +After the configuration is done, you can use + +```shell +./trojan-go -config ./client.json +``` + +Start the client. + +More information about configuration files can be found in the left navigation bar. diff --git a/docs/content/en/basic/full-config.md b/docs/content/en/basic/full-config.md new file mode 100644 index 000000000..207b78261 --- /dev/null +++ b/docs/content/en/basic/full-config.md @@ -0,0 +1,367 @@ +--- +title: "Full configuration file" +draft: false +weight: 30 +--- + +The following is a complete configuration file with the required options + +- ```run_type``` + +- ```local_addr``` + +- ```local_port``` + +- ```remote_addr``` + +- ```remote_port``` + +For server ```server```,```key``` and ```cert```are required. + +For the client ```client```, the reverse proxy tunnel ```forward```, and the transparent proxy ```nat```, ```password``` is required + +The rest of the unfilled options are filled with the values given below. + +*Trojan-Go supports the more human-friendly YAML syntax, and the basic structure of the configuration file is the same as JSON, with equivalent effects. However, to comply with YAML naming conventions, you need to convert underscores ("_") to horizontal bars ("-"), e.g. ```remote_addr``` is ```remote-addr``` in YAML files* + +```json +{ + "run_type": *required*, + "local_addr": *required*, + "local_port": *required*, + "remote_addr": *required*, + "remote_port": *required*, + "log_level": 1, + "log_file": "", + "password": [], + "disable_http_check": false, + "udp_timeout": 60, + "ssl": { + "verify": true, + "verify_hostname": true, + "cert": *required*, + "key": *required*, + "key_password": "", + "cipher": "", + "curves": "", + "prefer_server_cipher": false, + "sni": "", + "alpn": [ + "http/1.1" + ], + "session_ticket": true, + "reuse_session": true, + "plain_http_response": "", + "fallback_addr": "", + "fallback_port": 0, + "fingerprint": "" + }, + "tcp": { + "no_delay": true, + "keep_alive": true, + "prefer_ipv4": false + }, + "mux": { + "enabled": false, + "concurrency": 8, + "idle_timeout": 60 + }, + "router": { + "enabled": false, + "bypass": [], + "proxy": [], + "block": [], + "default_policy": "proxy", + "domain_strategy": "as_is", + "geoip": "$PROGRAM_DIR$/geoip.dat", + "geosite": "$PROGRAM_DIR$/geosite.dat" + }, + "websocket": { + "enabled": false, + "path": "", + "host": "" + }, + "shadowsocks": { + "enabled": false, + "method": "AES-128-GCM", + "password": "" + }, + "transport_plugin": { + "enabled": false, + "type": "", + "command": "", + "option": "", + "arg": [], + "env": [] + }, + "forward_proxy": { + "enabled": false, + "proxy_addr": "", + "proxy_port": 0, + "username": "", + "password": "" + }, + "mysql": { + "enabled": false, + "server_addr": "localhost", + "server_port": 3306, + "database": "", + "username": "", + "password": "", + "check_rate": 60 + }, + "api": { + "enabled": false, + "api_addr": "", + "api_port": 0, + "ssl": { + "enabled": false, + "key": "", + "cert": "", + "verify_client": false, + "client_cert": [] + } + } +} +``` + +## Description + +### General options + +For client/nat/forward, ```remote_xxxx``` should be filled in with your trojan server address and port number, ```local_xxxx``` corresponds to the local open socks5/http proxy address (auto-adapted) + +For server, ```local_xxxx``` corresponds to the trojan server listening address (port 443 is highly recommended), ```remote_xxxx``` fills in the address of the HTTP service that proxies to when non-trojan traffic is recognized, usually filling in local port 80. + +```log_level``` specifies the log level. The higher the level, the less information will be output. Legitimate values are + +- 0 Outputs logs above Debug (all logs) + +- 1 Output Info and above logs + +- 2 Output Warning and above logs + +- 3 Output Error and above logs + +- 4 Output Fatal and above logs + +- 5 Do not output logs at all + +```log_file``` specifies the log output file path. If not specified, standard output is used. + +```password``` can be filled with multiple passwords. In addition to configuring passwords using the configuration file, trojan-go also supports configuring passwords using mysql, see below. The client's password can only pass the server's checksum and use the proxy service properly if it matches the password record in the server's configuration file or in the database. + +```disable_http_check``` Whether to disable HTTP masquerade server availability check. + +```udp_timeout``` UDP session timeout time. + +### ```ssl``` options + +```verify``` indicates whether the client (client/nat/forward) verifies the legitimacy of the certificate provided by the server, and is enabled by default. For security reasons, this option should not be selected false in real scenarios, otherwise it may suffer from man-in-the-middle attacks. If you use self-signed or self-issued certificates, turning on ```verify``` will cause the verification to fail. In this case, you should keep ```verify``` on, and then fill in the certificate of the server side in ```cert``` to connect normally. + +```verify_hostname``` indicates whether the server side verifies the consistency between the SNI provided by the client and the server side settings. If the server-side SNI field is left blank, the authentication will be forced off. + +The server side must fill in ```cert``` and ```key```, corresponding to the server's certificate and private key file, please pay attention to whether the certificate is valid/expired. If you use the certificate issued by authoritative CA, the client (client/nat/forward) can not fill in ```cert```. If you use self-signed or self-issued certificate, you should fill in the server certificate file at the ```cert```, otherwise it may cause the verification failure. + +```sni``` refers to the server name field in the TLS client request, which is generally the same as the Common Name of the certificate. If you use a certificate issued by an organization such as let'sencrypt, fill in your domain name here. For clients, if this is not filled in, it will be populated using ```remote_addr```. You should specify a valid SNI (consistent with the remote certificate CN), otherwise the client may not be able to verify the validity of the remote certificate and thus cannot connect; for the server, if this item is not filled in, the Common Name in the certificate will be used as the basis for SNI verification, supporting wildcards such as *.example.com. + +```fingerprint``` is used to specify the type of client-side TLS Client Hello fingerprint forgery to resist GFW's feature identification and blocking for TLS Client Hello fingerprint. trojan-go uses [utls](https://github.com/refraction-networking/utls) to perform fingerprint forgery, and Firefox fingerprints are forged by default. Legitimate values are + +- "", no fingerprint forgery is used (default) + +- "firefox", forging Firefox fingerprints + +- "chrome", to forge Chrome fingerprints + +- "ios", to forge iOS fingerprints + +Once the value of the fingerprint is set, client-side fields such as ```cipher```, ```curves```, ```alpn```, ```session_ticket``` that have the potential to affect the fingerprint will be overridden using the specific settings of that fingerprint. +```alpn``` specifies the protocol for application layer protocol negotiation for TLS. Transferring in TLS Client/Server Hello and negotiating the protocol used by the application layer is only used for fingerprint forgery and has no practical effect. **If a CDN is used, the wrong alpn field may result in negotiating with the CDN to get the wrong application layer protocol**. + +```prefer_server_cipher``` Does the client prefer to select the cryptographic suite provided by the server in the negotiation. + +```cipher``` The cryptography suite used by TLS. The ```cipher13``` field is merged with this field. You should only go ahead and fill this in to modify the TLS cipher suite used by trojan-go if you know exactly what you are doing. **Normally, you should leave this blank or leave it blank**. trojan-go will automatically choose the most appropriate cryptographic algorithm to improve performance and security based on the current hardware platform and the remote end. If required, cryptography suite names are separated by semicolons (":") in order of preference. go's TLS library deprecates some of the insecure cryptography suites in TLS1.2 and fully supports TLS1.3. by default, trojan-go will give preference to the more secure TLS1.3. + +```curves``` specifies the elliptic curve that TLS prefers to use in ECDHE. This should only be filled in if you know exactly what you are doing. The curve names are separated by semicolons (":") and are listed in order of preference. + +```plain_http_response``` refers to the raw data sent in plaintext (raw TCP data) when the server-side TLS handshake fails. This field is filled with the path to that file. It is recommended to use ```fallback_port``` instead of this field. + +The ```fallback_addr``` and ```fallback_port``` refer to the address to which trojan-go redirects the connection if the server-side TLS handshake fails. This is a feature of trojan-go to better conceal the server against active GFW detection, making the server's port 443 behave exactly the same as a normal server when encountering probes from non-TLS protocols. When a server accepts a connection but cannot perform a TLS handshake, if ```fallback_port``` is not empty, traffic will be proxied to fallback_addr:fallback_port. if ```fallback_addr``` is empty, it will be populated with ```remote_addr``` . For example, you can enable an https service locally using nginx, and when your server port 443 is requested by a non-TLS protocol (such as an http request), trojan-go will proxy to the local https server and nginx will return a 400 Bad Request page using the http protocol in plaintext. You can verify this by visiting ```http://your-domain-name.com:443``` using your browser. + +The path to the ```key_log``` file for the TLS key log. If filled in then key logging is turned on. **Logging keys will break TLS security, and this item should not be used for anything other than debugging.** + +### ```mux``` multiplexing options + +Multiplexing is a feature of trojan-go. If both the server and client are trojan-go, you can turn on mux multiplexing to reduce latency in high concurrency scenarios (you only need to turn on this option on the client side, the server side adapts automatically). + +Note that the point of multiplexing is to reduce handshake latency, not to improve link speed. Instead, it increases CPU and memory consumption on both the client and server side, which may cause speed degradation. + +```enabled``` Enables or disables multiplexing. + +```concurrency``` refers to the maximum number of connections a single TLS tunnel can carry, the default is 8. The higher the value, the lower the latency of TLS due to handshaking when multiple connections are concurrent, but the network throughput may be reduced, filling in a negative number or 0 means that all connections are carried using only one TLS tunnel. + +```idle_timeout``` Idle timeout. Indicates how long the TLS tunnel will be idle before it is closed, in seconds. If the value is negative or 0, then the TLS tunnel is closed as soon as it becomes idle. + +### ```router``` routing options + +Routing is a feature of trojan-go. trojan-go has three types of routing policies. + +- Proxy Proxy. Proxy the request through a TLS tunnel, with the trojan server and the destination address connected. + +- Bypass bypassing. Connects directly locally to the destination address. + +- Block blocking. Does not proxy the request and closes the connection directly. + +Fill in the ```proxy```, ```bypass```, ```block``` fields with the corresponding list geoip/geosite or routing rules, trojan-go then executes the corresponding routing policy according to the IP (CIDR) or domain in the list. The client (client) can configure three policies, the server (server) can only configure block policies. + +```enabled``` Enables or disables the routing module. + +```default_policy``` refers to the default policy to be used when all three lists fail to match. Legitimate values are + +- "proxy" + +- "bypass" + +- "block" + +Same meaning as above. + +```domain_strategy``` Domain resolution strategy, default "as_is". Legitimate values are. + +- "as_is" to match only within the domain rules in each list. + +- "ip_if_non_match", which first matches within the rules of the domain name in each list; if it does not match, it resolves to IP and then matches within the rules of the IP address in each list. This policy may lead to DNS leaks or contamination. + +- "ip_on_demand", resolves to IP first and matches within the IP address rules in each list; if it does not match, it matches within the domain name rules in each list. This policy may lead to DNS leaks or contamination. + +The ```geoip``` and ```geosite``` fields refer to the geoip and geosite database file paths, which by default use geoip.dat and geosite.dat in the directory where the program is located. you can also specify the working directory by specifying the environment variable TROJAN_GO_LOCATION_ASSET. + +### ```websocket``` option + +Websocket transfers are a feature of trojan-go. In the case of **normal direct connections to proxy nodes**, turning on this option will not improve your link speed (or possibly even drop it), nor will it improve your connection security. You should only use websocket in cases where you need to use a CDN for relaying, or use a server such as nginx to distribute based on paths. + +```enabled``` indicates whether to enable Websocket to carry traffic, the server side supports both general Trojan protocol and websocket-based Trojan protocol when enabled, the client side will only use websocket to carry all Trojan protocol traffic when enabled. + +```path``` refers to the URL path used by websocket, which must start with a slash ("/"), such as "/longlongwebsocketpath", and the server and client must be the same. + +```host``` is the host name used in HTTP requests during the Websocket handshake. The client uses ```remote_addr``` to fill in if left blank. If a CDN is used, this option is usually filled with the domain name. An incorrect ```host``` may cause the CDN to fail to forward the request. + +### ```shadowsocks``` AEAD encryption option + +This option is used to replace the deprecated obfuscated encryption and double TLS. if this option is set to enabled, a Shadowsocks AEAD encryption layer will be inserted under the Trojan protocol layer. That is, within the (already encrypted) TLS tunnel, all Trojan protocols will again be encrypted using the AEAD method. Note that this option is independent of whether Websocket is enabled or not. All Trojan traffic will be encrypted again, regardless of whether Websocket is on or not. + +Note that turning this option on will potentially degrade transport performance, and you should only enable this option if you do not trust the transport channel carrying the Trojan protocol. Example. + +- You are using a Websocket, relayed through an untrusted CDN (e.g. a domestic CDN) + +- Your connection to the server is subject to a man-in-the-middle attack by GFW against TLS + +- Your certificate is invalid, and you cannot verify the validity of the certificate + +- You use a pluggable transport layer that cannot guarantee cryptographic security + +etc. + +Thanks to the use of AEAD, trojan-go can correctly determine if the request is valid and is being actively probed, and respond accordingly. + +```enabled``` Enables or disables the Shadowsocks AEAD encryption Trojan protocol layer. + +```method``` encryption method. Legitimate values are. + +- "CHACHA20-IETF-POLY1305" + +- "AES-128-GCM" (default) + +- "AES-256-GCM" + +```password``` is used to generate the password for the master key. If AEAD encryption is enabled, you must ensure that the client and server are identical. + +### ```transport_plugin``` Transport layer plugin options + +```Enabled``` Whether to enable transport layer plug-in instead of TLS transport. Once transport layer plugin support is enabled, trojan-go will transmit **unencrypted TLS-encrypted trojan protocol traffic in plaintext to the plugin** to allow user-defined obfuscation and encryption of the traffic. + +```type``` plug-in types. The currently supported types are + +- "shadowsocks", which supports the shadowsocks obfuscation plugin conforming to the [SIP003](https://shadowsocks.org/en/spec/Plugin.html) standard. trojan-go will replace environment variables and modify its own configuration at startup according to the SIP003 standard (```remote_addr/remote_port/local_addr/local_port```) so that the plugin communicates directly with the remote end, while trojan-go only listens/connects to the plugin. + +- "plaintext", to use plaintext transfer. By selecting this option, trojan-go does not modify any address configuration (```remote_addr/remote_port/local_addr/local_port```) and does not start the plugin in ```command```, only the lowest TLS transport layer is removed and TCP plaintext transport is used. The purpose of this option is to support nginx and others to take over TLS and perform triage, and advanced users to perform debugging tests. **Please do not use plaintext transport mode directly to penetrate the firewall. ** + +- "other", other plugins. By selecting this, trojan-go will not modify any address configuration (```remote_addr/remote_port/local_addr/local_port```), but will start the plugins in ```command``` and pass in parameters and environment variables. + +The path to the ```command``` transport layer plugin executable. trojan-go will execute it along with it at startup. + +The ```arg``` transport layer plugin startup parameters. This is a list, e.g. ```["-config", "test.json"]```. + +```env``` transport layer plugin environment variables. This is a list, e.g. ```["VAR1=foo", "VAR2=bar"]```. + +```option``` Transport layer plug-in configuration (SIP003). For example ```"obfs=http;obfs-host=www.baidu.com"```. + +### ```tcp``` option + +```no_delay``` Whether TCP packets are sent directly without waiting for the buffer to fill up. + +```keep_alive``` Whether or not to enable TCP heartbeat survival detection. + +```prefer_ipv4``` Whether to give preference to IPv4 addresses. + +### ```mysql``` database options + +trojan-go is compatible with trojan's mysql-based approach to user management, but the more recommended approach is to use the API. + +```enabled``` indicates whether to enable the mysql database for user authentication. + +```check_rate``` is the interval in seconds for trojan-go to fetch user data from MySQL and update the cache. + +The other options can be named as such and will not be repeated. + +The users table structure is the same as the trojan version definition, here is an example of creating a users table. Note that password here refers to the value (string) of the password after SHA224 hashing, and the units of traffic download, upload, quota are bytes. You can add and remove users or specify their traffic quota by modifying their records in the users table of the database. trojan-go will automatically update the list of currently active users based on all their traffic quotas. If download+upload>quota, the trojan-go server will refuse the connection for that user. + +```mysql +CREATE TABLE users ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT, + username VARCHAR(64) NOT NULL, + password CHAR(56) NOT NULL, + quota BIGINT NOT NULL DEFAULT 0, + download BIGINT UNSIGNED NOT NULL DEFAULT 0, + upload BIGINT UNSIGNED NOT NULL DEFAULT 0, + PRIMARY KEY (id), + INDEX (password) +); +``` + +### ```forward_proxy``` preproxy option + +The forward proxy option allows to use other proxies to carry trojan-go's traffic + +```enabled``` Enables or disables the forward proxy (socks5). + +```proxy_addr``` The host address of the preproxy. + +```proxy_port``` The port number of the preproxy. + +```username``` ```password``` The user and password of the proxy, if left blank no authentication will be used. + +### ```api``` options + +trojan-go provides an API based on gRPC to support server-side and client-side management and statistics. You can implement client-side traffic and speed statistics, server-side traffic and speed statistics for each user, dynamic addition and deletion of users and speed limits, etc. + +```enabled``` Enables or disables the API function. + +```api_addr``` The address of the gRPC listener. + +```api_port``` The port gRPC is listening on. + +```ssl``` TLS related settings. + +- ```enabled``` Whether to use TLS for gRPC traffic. + +- ```key```, ```cert``` server private key and certificate. + +- ```verify_client``` Whether to certify client certificates. + +- ```client_cert``` If client authentication is enabled, fill in the list of certified client certificates here. + + +{{% panel status="warning" title="Warning" %}} +Do not expose API services without TLS bi-directional authentication directly to the Internet, otherwise it may lead to various security problems. +{{% /panel %}} diff --git a/docs/content/en/basic/trojan.md b/docs/content/en/basic/trojan.md new file mode 100644 index 000000000..3b27f4507 --- /dev/null +++ b/docs/content/en/basic/trojan.md @@ -0,0 +1,33 @@ +--- +title: "Trojan fundamentals" +draft: false +weight: 21 +--- + +This page will briefly describe the basics of how the Trojan protocol works. If you are not interested in how GFW and Trojan work, you can skip this section. However, for better security of your communication and node concealment, I recommend you read it. + +## Why Shadowsocks (with streaming passwords) is vulnerable to blocking + +Firewalls in the early days simply intercepted and censored outbound traffic, i.e. **passive detection**. Shadowsocks' encryption protocol was designed so that the transmitted packets themselves had almost no signature and appeared similar to a completely random stream of bits, which did work to bypass GFWs in the early days. + +Current GFWs have begun to use **active detection**. Specifically, when GFW finds a suspicious unrecognizable connection (high traffic, random byte streams, high bit ports, etc.), it will **actively connect** to this server port and replay the previously captured traffic (or replay it with some elaborate modifications.) The Shadowsocks server detects an abnormal connection and disconnects it. This abnormal traffic and disconnection is seen as a characteristic of a suspicious Shadowsocks server, and the server is added to GFW's suspicious list. This list does not necessarily take effect immediately, but during certain special sensitive periods, the servers in the suspicious list are blocked temporarily or permanently. Whether or not this suspicious list is blocked may be determined by human factors. + +If you want to know more, you can refer to [this article](https://gfw.report/blog/gfw_shadowsocks/). + +## How Trojan bypasses GFW + +In contrast to Shadowsocks, Trojan does not use custom encryption protocols to hide itself. Instead, it uses the well-characterized TLS protocol (TLS/SSL), which makes the traffic look the same as a normal HTTPS site. TLS is a well-established encryption system, and HTTPS means that it uses TLS to carry HTTP traffic. Using **correctly configured** encrypted TLS tunnels ensures that the transmission is + +- Confidentiality (GFW cannot know what is being transmitted) + +- Integrity (if the GFW tries to tamper with the transmitted ciphertext, both sides of the communication will find out) + +- Non-repudiation (GFWs cannot forge their identities to impersonate the server or client) + +- Forward security (GFWs cannot decrypt previously encrypted traffic even if the key is compromised) + +For passive detection, Trojan protocol traffic has exactly the same characteristics and behavior as HTTPS traffic. While HTTPS traffic accounts for more than half of the current Internet traffic, and the traffic is ciphertext after a successful TLS handshake, there is almost no feasible way to distinguish Trojan protocol traffic from it. + +For active detection, Trojan can correctly identify non-Trojan protocol traffic when the firewall actively connects to the Trojan server for detection. Unlike proxies such as Shadowsocks, Trojan does not disconnect at this point, but proxies this connection to a normal web server. In GFW's view, the server behaves exactly the same as a normal HTTPS website and it is impossible to tell if it is a Trojan proxy node. This is the reason why Trojan recommends using a legitimate domain name with an HTTPS certificate signed by an authoritative CA: this makes your server completely invisible to GFW using active detection to determine if it is a Trojan server. + +Therefore, in the current situation, the only way to identify and block Trojan connections is to use indiscriminate blocking (blocking a certain IP segment, a certain type of certificate, a certain type of domain name, or even blocking all outbound HTTPS connections across the country) or to launch a massive man-in-the-middle attack (hijacking all TLS traffic and hijacking the certificate to censor the content). For man-in-the-middle attacks, you can use Websocket's dual TLS countermeasures, which are explained in detail in the advanced configuration. diff --git a/docs/content/en/developer/_index.md b/docs/content/en/developer/_index.md new file mode 100644 index 000000000..0f3ce86c6 --- /dev/null +++ b/docs/content/en/developer/_index.md @@ -0,0 +1,7 @@ +--- +title: "Implementation details and development guidelines" +draft: false +weight: 40 +--- + +This section describes the details of the underlying Trojan-Go implementation and is aimed at developers. diff --git a/docs/content/en/developer/api.md b/docs/content/en/developer/api.md new file mode 100644 index 000000000..86d5d5ace --- /dev/null +++ b/docs/content/en/developer/api.md @@ -0,0 +1,28 @@ +--- +title: "API Development" +draft: false +weight: 100 +--- + +Trojan-Go implements an API based on gRPC, using protobuf to exchange data. The client can get the traffic and speed information; the server can get the traffic, speed, online situation of each user, and dynamically add and delete users and limit the speed. The API module can be activated by adding the ```api``` option to the configuration file. Here is an example, the meaning of each field can be found in the section [Full configuration file]({{< ref "full-config.md" >}} "Full configuration file"). + +```json +... +"api": { + "enabled": true, + "api_addr": "0.0.0.0", + "api_port": 10000, + "ssl": { + "enabled": true, + "cert": "api_cert.crt", + "key": "api_key.key", + "verify_client": true, + "client_cert": [ + "api_client_cert1.crt", + "api_client_cert2.crt" + ] + }, +} +``` + +If you need to implement an API client for interfacing, please refer to the api/service/api.proto file. diff --git a/docs/content/en/developer/build.md b/docs/content/en/developer/build.md new file mode 100644 index 000000000..e65a41c6e --- /dev/null +++ b/docs/content/en/developer/build.md @@ -0,0 +1,43 @@ +--- +title: "Compiling and customizing Trojan-Go" +draft: false +weight: 10 +--- + +Compilation requires Go version number higher than 1.14.x. Please check your compiler version before compiling. It is recommended to use snap to install and update go. + +The compilation is very simple and can be done using the Makefile preset steps + +```shell +make +make install #Install systemd services etc., optional +``` + +Or you can compile directly using Go: + +```shell +go build -tags "full" #compile full version +``` + +You can specify the target OS and architecture for cross-compilation by specifying the GOOS and GOARCH environment variables, for example + +```shell +GOOS=windows GOARCH=386 go build -tags "full" #windows x86 +GOOS=linux GOARCH=arm64 go build -tags "full" #linux arm64 +``` + +You can use release.sh for batch cross-compilation of multiple platforms, the release version uses this script for building. + +Most modules of Trojan-Go are pluggable. Import declarations for individual modules can be found in the build folder. If you don't need some of these features, or need to reduce the size of the executable, you can customize the module using build tags, for example + +```shell +go build -tags "full" #compile all modules +go build -tags "client" -trimpath -ldflags="-s -w -buildid=" #only client functionality, and remove symbol table to reduce size +go build -tags "server mysql" #Only server-side and mysql support +``` + +Using the full tag is equivalent to + +```shell +go build -tags "api client server forward nat other" +``` diff --git a/docs/content/en/developer/mux.md b/docs/content/en/developer/mux.md new file mode 100644 index 000000000..6852051bf --- /dev/null +++ b/docs/content/en/developer/mux.md @@ -0,0 +1,17 @@ +--- +title: "Multiplexing" +draft: false +weight: 30 +--- + +Trojan-Go uses [smux](https://github.com/xtaci/smux) to implement multiplexing. The simplesocks protocol is also implemented for proxy transfers. + +When multiplexing is enabled, the client first initiates a TLS connection, using the normal trojan protocol format, but filling in 0x7f (protocol.Mux) in the Command section of the protocol, identifying the connection as a multiplexed connection (similar to the upgrade of http), after which the connection is handed over to the smux client for management. After the server receives the request header, it is handed over to the smux server to parse all traffic for the connection. On each separated smux connection, the proxy destination is marked using the simplesocks protocol (the trojan protocol with the authentication part removed). The top-down protocol stack is as follows. + +| protocol | notes | +| -------------------- | ------------------ | +| Real Traffic | +| SimpleSocks | +| smux | +| Trojan | for Authentication | +| Underlying protocols | | diff --git a/docs/content/en/developer/overview.md b/docs/content/en/developer/overview.md new file mode 100644 index 000000000..78177cb62 --- /dev/null +++ b/docs/content/en/developer/overview.md @@ -0,0 +1,125 @@ +--- +title: "Basic introduction" +draft: false +weight: 1 +--- + +The core parts of Trojan-Go are + +- tunnel Specific implementation of each protocol + +- proxy proxy core + +- config configuration registration and parsing module + +- redirector Active spoof detection module + +- statistics user authentication and statistics module + +The source code can be found in the corresponding folder. + +## tunnel.Tunnel tunnel + +Trojan-Go abstracts all protocols (including routing functions, etc.) into tunnels (tunnel.Tunnel interface), each of which can be opened with a server (tunnel.Server interface) and a client (tunnel.Client). Each server can, from its underlying tunnel, strip and accept streams (tunnel.Conn) and packets (tunnel.PacketConn). Clients can create streams and packets to the underlying tunnel. + +Each tunnel does not care what the tunnels below it are, but each tunnel knows exactly what information is relevant for the other tunnels above this it. + +All tunnels require either stream or packet transport support from the lower layer, or both. All tunnels must provide stream transport support to the upper tunnels, but not necessarily packet transport. + +Tunnels may be server-only, client-only, or both. Tunnels that have both may be used as transport tunnels between Trojan-Go clients and servers. + +Note that a distinction is made between a server/client for Trojan-Go, and a server/client for a tunnel. Here is an example of a diagram that is easy to understand. + +```text + +Inbound GFW Outbound +-------> Tun.A server->Tun.B client -----> Tun.B server->Tun.C client -------> + (Trojan-Go client) (Trojan-Go server) + +```` + +The bottom tunnel is the transport layer, i.e. the tunnel that does not get or create streams and packets from other tunnels, acting as tunnel A or C in the above diagram. + +- transport, the pluggable transport layer + +- socks, socks5 proxy, only the tunnel server + +- tproxy, transparent proxy, tunnel server only + +- dokodemo, reverse proxy, tunnel server only + +- freedom, free outbound, tunnel client only + +These tunnels create streams and packets directly from TCP/UDP sockets and do not accept any tunnels added for their underlying layers. + +The other tunnels, in principle, can be combined and stacked in any way and in any number, as long as the lower layer can satisfy the packet and stream transport needs of the upper layer. These tunnels act as Tunnel B in the above diagram, and they have + +- trojan + +- websocket + +- mux + +- simplesocks + +- tls + +- router, routing function, tunneling client only + +None of them care about their lower layer tunneling implementation. However, they can be distributed to the upper layer tunnels based on the incoming flows and packets. + +For example, in this diagram, which is a typical Trojan-Go client and server, the individual tunnels are stacked from bottom to top in the following order + +- Tunnel A: transport->socks + +- Tunnel B: transport->tls->trojan + +- Tunnel C: freedom + +The actual tunnel stacking situation is a bit more complicated than this. A typical inbound tunnel is in the form of a multinomial tree, not a chain. See below for a detailed explanation. + +## proxy.Proxy core + +The role of the proxy core is to listen to the stack formed by combining and stacking the above tunnels, and to forward all the streams and packets extracted from the inbound stack (end nodes of multiple tunnel servers, see below), along with the corresponding meta information, to the outbound stack (a tunnel Client). + +Note that there can be multiple inbound protocol stacks, e.g., the client can extract streams and packets from both Socks5 and HTTP protocol stacks, the server can extract streams and packets from both the Websocket-hosted Trojan protocol and the TLS-hosted Trojan protocol, etc. However, there can be only one outbound protocol stack, e.g. only the TLS-bearing Trojan protocol is used for outbound. + +To describe how the inbound protocol stacks (tunnel servers) are combined and stacked, a multinomial tree is used to describe all the protocol stacks. You can see the process of building the tree in the proxy folder, for each component. + +The outbound protocol stack, on the other hand, is simpler and can be described using a simple list. + +So in effect, for a typical client/server with Websocket and Mux turned on, the tunnel stacking model in the above figure is + +Client + +- inbound (tree) + - transport (root) + - adapter Able to recognize HTTP and Socks traffic and distribute to upper layer protocols + - http (endpoint node) + - socks (end node) + +- outbound (chain) + - transport (root) + - tls + - websocket + - trojan + - mux + - simplesocks + +server-side + +- inbound (tree) + - transport (root) + - tls can identify HTTP and non-HTTP traffic and distribute + - websocket + - trojan (endpoint node) + - mux + - simplesocks (endpoint node) + - trojan can identify and distribute mux and normal trojan traffic (end node) + - mux + - simplesocks (end node) + +- Outbound (chain) + - freedom + +Note that the proxy core only extracts flows and packets from the end nodes of the tree formed by the tunnel and forwards them to a unique outbound station. The purpose of the multiple terminal nodes design is to make Trojan-Go compatible with both Websocket and Trojan protocol inbound connections, inbound connections with/without Mux enabled, and HTTP/Socks5 auto-identification. Each node in the tree with multiple sons has the ability to precisely identify and distribute flows and packets to different son nodes. This is consistent with our assumption that each protocol understands its upper layer bearer protocols. diff --git a/docs/content/en/developer/plugin.md b/docs/content/en/developer/plugin.md new file mode 100644 index 000000000..00cd7e940 --- /dev/null +++ b/docs/content/en/developer/plugin.md @@ -0,0 +1,39 @@ +--- +title: "Pluggable transport layer plug-in development" +draft: false +weight: 150 +--- + +Trojan-Go encourages the development of transport layer plugins to enrich protocol types and increase the strategic depth of the fight against GFW. + +The role of transport layer plugins is to replace TLS in tansport tunnels for transport encryption and obfuscation. + +The plug-in communicates with Trojan-Go based on TCP Socket, there is no coupling with Trojan-Go itself, and you can use any language and design pattern you like for development. We recommend developing with reference to the [SIP003](https://shadowsocks.org/en/spec/Plugin.html) standard. The plugins so developed can be used for both Trojan-Go and Shadowsocks. + +Trojan-Go uses only TCP for transmission (plaintext) when the plug-in functionality is enabled. Your plugin only needs to handle inbound TCP requests. You can convert this TCP traffic into any traffic format you like, such as QUIC, HTTP, or even ICMP. + +Trojan-Go plugin design principles, slightly different from Shadowsocks. + +1. the plugin itself can encrypt, obfuscate and integrity-check the transmitted content, as well as being resistant to replay attacks. + +2. the plug-in should forge an existing, common service (noted as X service) and its traffic, and on top of that embed its own encrypted content. + +3. The server-side plug-in, upon verifying that the content has been tampered with/replayed, **must hand over the connection to Trojan-Go for processing**. The specific steps are to send the read-in and unread-in content together to Trojan-Go and to establish a two-way connection instead of disconnecting it directly.Trojan-Go will establish a connection to a real X server, allowing the attacker to interact directly with the real X server. + +The explanation is as follows. + +The first principle, is due to the fact that the Trojan protocol itself is not encrypted. Replacing TLS with a transport layer plug-in will **completely trust the security of the plug-in**. + +The second principle, is inherited from the spirit of Trojan. The best place to hide a tree is a forest. + +The third principle, to take full advantage of Trojan-Go's anti-active-detection feature. Even if GFW is actively probing your server, your server can behave consistent with the X service and no other features. + +To make it easier to understand, let's take an example. + +1. Suppose your plugin is masquerading as MySQL traffic. The firewall sniffs through the traffic and finds that your MySQL traffic is unusually large and decides to actively connect to your server for active probing. + +2. The firewall connects to your server and sends a probe load to your Trojan-Go server-side plugin, which, after verification, finds that this abnormal connection is not proxy traffic and hands the connection over to Trojan-Go for processing. + +3. Trojan-Go finds this connection anomaly and redirects this connection to a real MySQL server. The firewall then starts interacting with a real MySQL server and finds that its behavior is no different from that of a real MySQL server and cannot block the server. + +Also, even if your protocol protocols and plug-ins do not satisfy principles 2 and 3, or even principle 1 very well, we encourage development as well. Because GFW only audits and blocks popular protocols, such protocols (earthen cryptography/earth protocols) can also remain very robust as long as they are not publicly published. diff --git a/docs/content/en/developer/simplesocks.md b/docs/content/en/developer/simplesocks.md new file mode 100644 index 000000000..5b8c5a686 --- /dev/null +++ b/docs/content/en/developer/simplesocks.md @@ -0,0 +1,21 @@ +--- +title: "SimpleSocks Protocol" +draft: false +weight: 50 +--- + +SimpleSocks protocol is a simple proxy protocol with no authentication mechanism, essentially Trojan protocol with sha224 removed. The purpose of using this protocol is to reduce the overhead when multiplexing. + +Only when multiplexing is enabled, the connections being multiplexed will use this protocol. That is, SimpleSocks is always carried by SMux. + +SimpleSocks is even simpler than Socks5, here is the header structure. + +```text ++-----+------+----------+----------+-----------+ +| CMD | ATYP | DST.ADDR | DST.PORT | Payload | ++-----+------+----------+----------+-----------+ +| 1 | 1 | Variable | 2 | Variable | ++-----+------+----------+----------+-----------+ +``` + +The definitions of the fields are the same as for the Trojan protocol and will not be repeated. diff --git a/docs/content/en/developer/trojan.md b/docs/content/en/developer/trojan.md new file mode 100644 index 000000000..f76a6de4e --- /dev/null +++ b/docs/content/en/developer/trojan.md @@ -0,0 +1,16 @@ +--- +title: "Trojan Protocol" +draft: false +weight: 20 +--- + +Trojan-Go follows the original trojan protocol, the exact format of which can be found in the [Trojan documentation](https://trojan-gfw.github.io/trojan/protocol) and will not be repeated here. + +By default, the trojan protocol is carried using TLS, and the protocol stack is as follows. + +| Protocol | +| ------------ | +| Real Traffic | +| Trojan | +| TLS | +| TCP | diff --git a/docs/content/en/developer/url.md b/docs/content/en/developer/url.md new file mode 100644 index 000000000..9d920a42a --- /dev/null +++ b/docs/content/en/developer/url.md @@ -0,0 +1,172 @@ +--- +title: "URL scheme (draft)" +draft: false +weight: 200 +--- + +## Changelog + +- encryption format to ss;method:password + +## Overview + +Thanks to @DuckSoft @StudentMain @phlinhng for discussing and contributing to the Trojan-Go URL scheme. **The URL scheme is currently a draft and needs more practice and discussion.** + +Trojan-Go **client** can accept URLs to locate server resources. The principles are as follows: + +- Comply with URL format specifications + +- Ensure human readability and machine friendliness + +- The purpose of URLs is to locate Trojan-Go node resources and facilitate resource sharing + +Note that embedding encoded data such as base64 in URLs is prohibited for human readability reasons. First, base64 encoding does not guarantee secure transmission, but is meant to transmit non-ASCII data over ASCII channels. Second, if you need to secure transmission when sharing URLs, encrypt the plaintext URLs instead of modifying the URL format. + +## Format + +The basic format is as follows, `$()` means that `encodeURIComponent` is required here. + +```text +trojan-go:// + $(trojan-password) + @ + trojan-host + : + port +/? + sni=$(tls-sni.com)& + type=$(original|ws|h2|h2+ws)& + host=$(websocket-host.com)& + path=$(/websocket/path)& + encryption=$(ss;aes-256-gcm;ss-password)& + plugin=$(...) +#$(descriptive-text) +``` + +For example + +```text +trojan-go://password1234@google.com/?sni=microsoft.com&type=ws&host=youtube.com&path=%2Fgo&encryption=ss%3Baes-256-gcm%3Afuckgfw +``` + +Since Trojan-Go is compatible with Trojan, the URL scheme for Trojan + +```text +trojan://password@remote_host:remote_port +``` + +is compatible and acceptable. It is equivalent to + +```text +trojan-go://password@remote_host:remote_port +``` + +Note that once a server uses a non-Trojan compatible feature, you must use ```trojan-go://``` to locate the server. This is designed so that Trojan-Go URLs are not incorrectly accepted by Trojan, and to avoid contaminating Trojan users with URL sharing. At the same time, Trojan-Go ensures compatibility with accepting Trojan's URLs. + +## Details + +Note: All parameter names and constant strings are case-sensitive. + +### `trojan-password` + +Trojan's password. +Cannot be omitted, cannot be an empty string, and is not recommended to contain non-ASCII printable characters. +Must be encoded with `encodeURIComponent`. + +### `trojan-host` + +Node IP / domain name. +Cannot be omitted and cannot be an empty string. +IPv6 address must be enclosed in square brackets. +IDN domain name (e.g. "Baidu.cn") must be in `xn--xxxxxx` format. + +### `port` + +Node port. +Default is `443` when omitted. +Must be an integer in `[1,65535]`. + +### `tls` or `allowInsecure` + +does not have this field. +TLS is always enabled by default, unless a transport plugin disables it. +TLS authentication must be enabled. Nodes that cannot use root CA to verify the identity of the server are not suitable for sharing. + +### `sni` + +SNI for custom TLS. +Defaults to the same value as `trojan-host` when omitted. Must not be an empty string. + +Must be encoded with `encodeURIComponent`. + +### `type` + +The type of the transfer. +Defaults to `original` when omitted, but may not be an empty string. +Currently the only available values are `original` and `ws`, in the future there may be `h2`, `h2+ws`, etc. + +When the value is `original`, the original Trojan transfer method is used and cannot be easily passed through CDN. +When the value is `ws`, Websocket over TLS is used. + +### `host` + +Custom HTTP `Host` header. +Can be omitted, when omitted the value is the same as `trojan-host`. +Can be an empty string, but may introduce unintended situations. + +Warning: If your port is not a standard port (not 80 / 443), the RFC standard states that `Host` should be followed by the port number, e.g. `example.com:44333`. Please use your own discretion as to whether to comply. + +The `encodeURIComponent` encoding must be used. + +### `path` + +Valid when transfer type `type` takes `ws`, `h2`, `h2+ws`. +It may not be omitted and may not be empty. +Must start with `/`. +You can use `&`, `#`, `? ` etc., but it must be a legal URL path. + +Must be encoded with `encodeURIComponent`. + +### `mux` + +does not have this field. +The current server always supports `mux` by default. +There are advantages and disadvantages to enabling `mux` or not, and it is up to the client to decide whether to enable it or not; the purpose of the URL is to locate server resources, not to specify user preferences. + +### `encryption` + +Encryption layer for securing Trojan traffic cryptographically. +Can be omitted, defaults to `none`, i.e. no encryption is used. +Cannot be an empty string. + +Must use encodeURIComponent encoding. + +When using the Shadowsocks algorithm for traffic encryption, the format is + +```text +ss;method:password +``` + +where ss is the fixed content and method is the encryption method, which must be one of the following. + +- `aes-128-gcm` +- `aes-256-gcm` +- `chacha20-ietf-poly1305` + +where `password` is the Shadowsocks password and must not be an empty string. +`password` does not need to be escaped if it contains a semicolon. +`password` should be an English printable ASCII character. + +Other encryption schemes to be determined. + +### `plugin` + +Additional plugin options. This field is reserved. +May be omitted, but may not be an empty string. + +### URL Fragment (# followed by content) + +Node description. +Not recommended to be omitted, not recommended to be an empty string. + +Must be encoded with `encodeURIComponent`. diff --git a/docs/content/en/developer/websocket.md b/docs/content/en/developer/websocket.md new file mode 100644 index 000000000..f838425b6 --- /dev/null +++ b/docs/content/en/developer/websocket.md @@ -0,0 +1,26 @@ +--- +title: "Websocket" +draft: false +weight: 40 +--- + +Since HTTPS is transparent to the CDN when using CDN transit, the CDN can review the content of the Websocket transfer. The Trojan protocol itself is transmitted in clear text, so to ensure security, a layer of Shadowsocks AEAD encryption layer can be added to obfuscate traffic characteristics and ensure security. + + +{{% panel status="warning" title="Caution" %}} +If you are using a CDN provided by an operator in China, please make sure to turn on AEAD encryption. +{{% /panel %}} + +When AEAD encryption is enabled, traffic carried by Websocket will be encrypted by Shadowsocks AEAD, see Shadowsocks white paper for the specific format of the header. + +After enabling Websocket support, the protocol stack is as follows. + +| Protocol | Remarks | +| ------------------------ | -------------------------- | +| Real Traffic | | +| SimpleSocks | If multiplexing is enabled | +| smux | If multiplexing is enabled | +| Trojan | | +| Shadowsocks | if encryption is enabled | +| Websocket | | +| Transport Layer Protocol | | diff --git a/docs/content/_index.md b/docs/content/zh/_index.md similarity index 100% rename from docs/content/_index.md rename to docs/content/zh/_index.md diff --git a/docs/content/advance/_index.md b/docs/content/zh/advance/_index.md similarity index 100% rename from docs/content/advance/_index.md rename to docs/content/zh/advance/_index.md diff --git a/docs/content/advance/aead.md b/docs/content/zh/advance/aead.md similarity index 100% rename from docs/content/advance/aead.md rename to docs/content/zh/advance/aead.md diff --git a/docs/content/advance/api.md b/docs/content/zh/advance/api.md similarity index 100% rename from docs/content/advance/api.md rename to docs/content/zh/advance/api.md diff --git a/docs/content/advance/customize-protocol-stack.md b/docs/content/zh/advance/customize-protocol-stack.md similarity index 100% rename from docs/content/advance/customize-protocol-stack.md rename to docs/content/zh/advance/customize-protocol-stack.md diff --git a/docs/content/advance/forward.md b/docs/content/zh/advance/forward.md similarity index 100% rename from docs/content/advance/forward.md rename to docs/content/zh/advance/forward.md diff --git a/docs/content/advance/mux.md b/docs/content/zh/advance/mux.md similarity index 100% rename from docs/content/advance/mux.md rename to docs/content/zh/advance/mux.md diff --git a/docs/content/advance/nat.md b/docs/content/zh/advance/nat.md similarity index 100% rename from docs/content/advance/nat.md rename to docs/content/zh/advance/nat.md diff --git a/docs/content/advance/nginx-relay.md b/docs/content/zh/advance/nginx-relay.md similarity index 100% rename from docs/content/advance/nginx-relay.md rename to docs/content/zh/advance/nginx-relay.md diff --git a/docs/content/advance/plugin.md b/docs/content/zh/advance/plugin.md similarity index 100% rename from docs/content/advance/plugin.md rename to docs/content/zh/advance/plugin.md diff --git a/docs/content/advance/router.md b/docs/content/zh/advance/router.md similarity index 100% rename from docs/content/advance/router.md rename to docs/content/zh/advance/router.md diff --git a/docs/content/advance/websocket.md b/docs/content/zh/advance/websocket.md similarity index 100% rename from docs/content/advance/websocket.md rename to docs/content/zh/advance/websocket.md diff --git a/docs/content/basic/_index.md b/docs/content/zh/basic/_index.md similarity index 100% rename from docs/content/basic/_index.md rename to docs/content/zh/basic/_index.md diff --git a/docs/content/basic/config.md b/docs/content/zh/basic/config.md similarity index 100% rename from docs/content/basic/config.md rename to docs/content/zh/basic/config.md diff --git a/docs/content/basic/full-config.md b/docs/content/zh/basic/full-config.md similarity index 100% rename from docs/content/basic/full-config.md rename to docs/content/zh/basic/full-config.md diff --git a/docs/content/basic/trojan.md b/docs/content/zh/basic/trojan.md similarity index 100% rename from docs/content/basic/trojan.md rename to docs/content/zh/basic/trojan.md diff --git a/docs/content/developer/_index.md b/docs/content/zh/developer/_index.md similarity index 100% rename from docs/content/developer/_index.md rename to docs/content/zh/developer/_index.md diff --git a/docs/content/developer/api.md b/docs/content/zh/developer/api.md similarity index 100% rename from docs/content/developer/api.md rename to docs/content/zh/developer/api.md diff --git a/docs/content/developer/build.md b/docs/content/zh/developer/build.md similarity index 100% rename from docs/content/developer/build.md rename to docs/content/zh/developer/build.md diff --git a/docs/content/developer/mux.md b/docs/content/zh/developer/mux.md similarity index 100% rename from docs/content/developer/mux.md rename to docs/content/zh/developer/mux.md diff --git a/docs/content/developer/overview.md b/docs/content/zh/developer/overview.md similarity index 100% rename from docs/content/developer/overview.md rename to docs/content/zh/developer/overview.md diff --git a/docs/content/developer/plugin.md b/docs/content/zh/developer/plugin.md similarity index 100% rename from docs/content/developer/plugin.md rename to docs/content/zh/developer/plugin.md diff --git a/docs/content/developer/simplesocks.md b/docs/content/zh/developer/simplesocks.md similarity index 100% rename from docs/content/developer/simplesocks.md rename to docs/content/zh/developer/simplesocks.md diff --git a/docs/content/developer/trojan.md b/docs/content/zh/developer/trojan.md similarity index 100% rename from docs/content/developer/trojan.md rename to docs/content/zh/developer/trojan.md diff --git a/docs/content/developer/url.md b/docs/content/zh/developer/url.md similarity index 100% rename from docs/content/developer/url.md rename to docs/content/zh/developer/url.md diff --git a/docs/content/developer/websocket.md b/docs/content/zh/developer/websocket.md similarity index 100% rename from docs/content/developer/websocket.md rename to docs/content/zh/developer/websocket.md