Skip to content

Trojan

[!NOTE] This document is partially generated by AI.

Trojan is a protocol designed to bypass censorship by imitating the most common protocol, HTTPS. It aims to be undetectable by ISP firewalls. In yuhaiin, it is an outbound-only protocol.

  • TCP: Supported natively.
  • UDP: Supported via UDP over Stream. All UDP packets are encapsulated within a TCP stream to the Trojan server.
    • NAT Type: Full-Cone NAT. A single TCP stream can handle UDP packets to/from multiple remote destinations.

When configuring a Trojan outbound, the following fields are available in the trojan protocol slab:

  • password (string): The authentication secret. Trojan uses the hex-encoded SHA224 hash of this password to identify and authenticate the client to the server.
  • peer (string): (Optional) The hostname used for certificate verification. If your server certificate is issued for a specific domain name, and you are connecting via a different IP or host, set this field to match the certificate’s domain.

Trojan must be used on top of a TLS connection. A full protocol chain for Trojan typically looks like this:

  1. simple: Defines the physical server address and port (usually 443).
  2. tls: Handles the TLS handshake and encryption.
  3. trojan: Handles Trojan-specific authentication and data wrapping.
{
"name": "My-Trojan-Client",
"protocols": [
{
"simple": {
"host": "trojan.example.com",
"port": 443
}
},
{
"tls": {
"enable": true,
"servernames": ["trojan.example.com"]
}
},
{
"trojan": {
"password": "your-password"
}
}
]
}

Immediately after the TLS handshake, the client sends: sha224(password) + \r\n + command + address_type + address + port + \r\n The command is typically 1 (TCP) or 3 (UDP).

The implementation is found in pkg/net/proxy/trojan. It wraps a net.Conn (usually a *tls.Conn) and handles the protocol-specific header.