spec.md 3.3 KB

ADDED Requirements

Requirement: Trojan is installed on the landing server

The trojan role SHALL download and install the Trojan binary (trojan-go or trojan-gfw) from release artifacts to a configurable path.

Scenario: Fresh installation

  • WHEN the trojan role runs on a landing server without Trojan installed
  • THEN the specified version of the Trojan binary is downloaded and installed
  • THEN the binary is executable and owned by a dedicated service user

Scenario: Version upgrade

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

Requirement: Trojan runs as a systemd service

The trojan role SHALL create a systemd unit file for Trojan and ensure it is enabled and started.

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 (with CAP_NET_BIND_SERVICE for port 443)

Requirement: TLS certificate is provisioned via Let's Encrypt

The trojan role SHALL use certbot to obtain a TLS certificate for the landing server's domain, with automatic renewal.

Scenario: Certificate provisioning

  • WHEN the trojan role runs with a configured domain name
  • THEN certbot obtains a TLS certificate for that domain
  • THEN the certificate and key are accessible to the Trojan service

Scenario: Certificate auto-renewal

  • WHEN the certificate is within 30 days of expiry
  • THEN certbot renews it automatically via systemd timer or cron
  • THEN the Trojan service is reloaded after renewal

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, presenting as a normal HTTPS server to non-Trojan clients.

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 web server (camouflage)

Requirement: Trojan configuration is templated

The landing server's Trojan configuration SHALL be generated from a Jinja2 template with variables for password, domain, TLS paths, and fallback settings.

Scenario: Configuration is generated from template

  • WHEN the trojan role runs
  • THEN a JSON config file is rendered from template
  • THEN the config file permissions are restricted (readable only by the service user)

Scenario: Configuration change triggers restart

  • WHEN a variable in group_vars/landing.yml is changed and the playbook is re-run
  • THEN the configuration file is updated
  • THEN the Trojan service is restarted

Requirement: Trojan credentials are managed via Ansible Vault

The landing server's Trojan password SHALL be defined in group_vars and encrypted with Ansible Vault.

Scenario: Password is not in plaintext in repository

  • WHEN the trojan role generates the configuration
  • THEN the password comes from an Ansible Vault-encrypted variable
  • THEN no plaintext password exists in version-controlled files