spec.md 4.3 KB

ADDED Requirements

Requirement: Trojan users are configured via YAML file

The trojan role SHALL read user credentials from a users.yml file located at the playbook root. The file SHALL define a trojan_users list where each entry contains name and password fields.

Scenario: Users file exists with multiple entries

  • WHEN users.yml contains trojan_users with entries [{name: alice, password: pass1}, {name: bob, password: pass2}]
  • THEN the Trojan configuration includes both users

Scenario: Users file is missing

  • WHEN users.yml does not exist and no trojan_users variable is defined elsewhere
  • THEN the playbook fails with a clear error message

Scenario: Users file is gitignored

  • WHEN the repository is inspected
  • THEN .gitignore contains an entry for users.yml

Requirement: Trojan binary is installed

The trojan role SHALL download and install the trojan-go binary from release artifacts to /usr/local/bin/trojan-go. The version SHALL be configurable via trojan_version.

Scenario: Fresh installation

  • WHEN the trojan role runs on a server without trojan-go installed
  • THEN the specified version of the binary is downloaded and installed
  • THEN the binary is executable

Scenario: Version upgrade

  • WHEN trojan_version is changed and the playbook is re-run
  • THEN the binary is replaced with the new version
  • THEN the Trojan service is restarted

Requirement: TLS certificate is provisioned via Let's Encrypt

The trojan role SHALL use certbot to obtain a TLS certificate for the configured domain. After provisioning or renewal, the certificate and key SHALL be copied to /etc/trojan-go/tls/ so the service user can read them.

Scenario: Certificate provisioning

  • WHEN the trojan role runs with a configured trojan_domain
  • THEN certbot obtains a TLS certificate for that domain
  • THEN the certificate and key are copied to /etc/trojan-go/tls/ owned by the trojan service user

Scenario: Certificate auto-renewal

  • WHEN the certificate is within 30 days of expiry
  • THEN certbot renews it automatically
  • THEN a deploy-hook copies the renewed certs to /etc/trojan-go/tls/
  • THEN the Trojan service is reloaded after renewal

Requirement: Trojan runs as a systemd service

The trojan role SHALL create a systemd unit file for trojan-go and ensure it is enabled and started. The unit SHALL include both AmbientCapabilities and CapabilityBoundingSet for CAP_NET_BIND_SERVICE.

Scenario: Service is running

  • WHEN the trojan role completes
  • THEN the Trojan systemd service is enabled and running
  • THEN the service runs under a dedicated non-root user
  • THEN the service user can read the TLS certificate and key files

Requirement: Trojan listens on port 443 with TLS

The Trojan service SHALL listen on port 443 and terminate TLS using the Let's Encrypt certificate.

Scenario: Trojan accepts connections on 443

  • WHEN a Trojan client connects to port 443 with valid credentials
  • THEN the connection is accepted and proxied

Scenario: Non-Trojan traffic is handled by fallback

  • WHEN a non-Trojan HTTPS request arrives on port 443
  • THEN Trojan forwards it to a local fallback endpoint (if configured)

Requirement: Trojan configuration is templated

The trojan role SHALL generate a JSON configuration file from a Jinja2 template. The config SHALL include: run_type, local_addr, local_port, remote_addr, remote_port, password array (from trojan_users), ssl section with cert/key paths, and log_level.

Scenario: Multi-user configuration is generated

  • WHEN the trojan role runs with multiple users defined
  • THEN the config file contains a password array with all user passwords
  • THEN each user can authenticate with their respective password

Scenario: Configuration change triggers restart

  • WHEN users.yml or trojan variables are changed and the playbook is re-run
  • THEN the configuration file is updated
  • THEN the Trojan service is restarted via handler

Requirement: Trojan port 443 is allowed through UFW

The trojan role SHALL allow port 443 through UFW.

Scenario: Firewall allows HTTPS port

  • WHEN the trojan role runs
  • THEN UFW allows incoming TCP traffic on port 443