Deploying a private Trojan VPN on a DigitalOcean VPS gives site owners, enterprises, and developers a robust, high-performance tunneling solution with full control over configuration, security, and IP allocation. This guide walks you through a detailed, step-by-step deployment on Ubuntu 20.04/22.04, covering DNS, TLS, Nginx reverse proxy, Trojan server configuration, systemd, firewall tuning, client configuration, and operational hardening. The instructions assume basic Linux familiarity and SSH access to a fresh DigitalOcean droplet.

Why choose Trojan on DigitalOcean?

Trojan is a protocol designed to resemble HTTPS traffic and evade DPI-based blocking while offering high-speed, low-latency tunneling. DigitalOcean droplets provide predictable performance, private networking, and easy snapshot/backups. Together they make an ideal platform for a dedicated-IP VPN service where you control the environment and the IP assigned to your VPN endpoint.

Prerequisites and planning

Before provisioning the VPS, prepare the following:

  • A domain name (eg. vpn.example.com). You will point an A record to the droplet’s public IP for TLS certificate issuance and to make traffic appear legitimate.
  • DigitalOcean account and API access (optional but useful for automation).
  • SSH key pair for secure login. Avoid password-based root login if possible.
  • Basic familiarity with systemd, Nginx, and JSON configuration files.

Step 1 — Create the droplet and configure DNS

Create a DigitalOcean droplet with Ubuntu 22.04 LTS (1 vCPU and 1GB RAM is fine for light use; scale up if serving many clients). During creation, add your SSH public key. After the droplet is created, note the public IP, and add an A record for your domain or subdomain pointing to that IP. Example: add A record vpn.example.com → 203.0.113.10. Wait for DNS propagation (usually a few minutes).

Step 2 — Initial server hardening

SSH into your droplet: ssh root@vpn.example.com (or use the public IP). Immediately perform basic hardening:

  • Update packages: apt update && apt upgrade -y
  • Create an unprivileged user: adduser deployer && usermod -aG sudo deployer
  • Disable root SSH login and optionally change SSH port in /etc/ssh/sshd_config, then restart sshd: systemctl reload sshd
  • Install essential packages: apt install -y nginx certbot git curl ufw

Step 3 — Obtain TLS certificates (Let’s Encrypt)

Trojan relies on valid TLS certs to blend with HTTPS. Use Certbot with the Nginx plugin or the standalone option. If Nginx is staged next, it’s convenient to use Certbot’s Nginx plugin:

  • Create a minimal Nginx server block for your domain to satisfy HTTP validation. Example server_name: vpn.example.com. Ensure port 80 is reachable.
  • Run: certbot –nginx -d vpn.example.com –agree-tos –no-eff-email -m you@example.com
  • Certs will be stored under /etc/letsencrypt/live/vpn.example.com/

Step 4 — Install and configure Nginx as a reverse proxy

Using Nginx as a front for Trojan makes traffic look like regular HTTPS and allows you to handle TLS and HTTP multiplexing cleanly. Create or edit /etc/nginx/sites-available/vpn.conf with the following key points:

  • Listen on 443 SSL with your certificate paths: /etc/letsencrypt/live/vpn.example.com/fullchain.pem and privkey.pem.
  • Use a server block with proxy_pass only for HTTP-multiplexed flows if you use WebSocket, or configure a stream block if you need raw TCP passthrough. For a standard Trojan setup you will proxy TLS to the local Trojan port (e.g., 127.0.0.1:4433) via proxy_pass in a stream context or use the TCP proxy module.
  • Harden headers (optional): disable server tokens, add HSTS, and tune SSL ciphers to modern recommendations.

After editing, test and reload Nginx: nginx -t && systemctl reload nginx.

Step 5 — Install Trojan server

There are two common implementations: the original trojan (trojan-gfw) and trojan-go. Trojan-go is popular for its performance and features (HTTP/2, WS, plugin hooks). Choose one and download the binary from its GitHub releases.

  • Example for trojan-go: download latest release tar.gz from GitHub, extract, and move binary to /usr/local/bin/.
  • Create a system user: useradd -r -s /sbin/nologin trojan

Next, create a JSON configuration file (example path: /etc/trojan/config.json). Key configuration sections:

  • “run_type”: “server”
  • “local_addr”: “127.0.0.1”, “local_port”: 4433 (trojan listens on local port: Nginx will forward TLS)
  • “remote_addr”: “127.0.0.1”, “remote_port”: 80 (if using HTTP reverse proxy to backend; often not used for pure tunneling)
  • “password”: [“your-strong-password-or-uuid”] — Trojan treats each password as an account. Use long UUID-like secrets.
  • TLS options: set “cert” and “key” paths to Let’s Encrypt files or set it to use SNI mode if Nginx handles TLS termination. If Nginx terminates TLS, trojan can be configured to accept plain TCP on localhost and Nginx will forward decrypted traffic; however, to keep end-to-end TLS, configure trojan to use the certificate directly and use Nginx only as a TCP passthrough (stream) or use SNI routing.

Sample minimal trojan-go config (conceptual)

Because full JSON is lengthy, include essential fields: run_type, local_addr, local_port, password, ssl {cert, key}, transports (enable websocket/tcp if needed), and log settings. Ensure file permissions are restrictive: chmod 600 /etc/trojan/config.json && chown trojan:trojan /etc/trojan/config.json.

Step 6 — systemd service and auto-start

Create a systemd unit file /etc/systemd/system/trojan.service with ExecStart pointing to /usr/local/bin/trojan-go -config /etc/trojan/config.json, set User=trojan, Restart=on-failure, and appropriate limits. Then enable and start:

  • systemctl daemon-reload
  • systemctl enable –now trojan
  • Check status and logs: systemctl status trojan and journalctl -u trojan -f

Step 7 — Firewall and port rules

Use UFW (or iptables) to restrict access. Basic rules:

  • Allow SSH from trusted IPs: ufw allow from 203.0.113.5 to any port 22 proto tcp (optional)
  • Allow HTTP and HTTPS for certificate renewal: ufw allow 80/tcp && ufw allow 443/tcp
  • Allow the trojan listening port if Nginx isn’t terminating TLS externally (e.g., ufw allow 4433/tcp for localhost-only it’s unnecessary).
  • Enable UFW: ufw enable

For stricter setups, bind trojan to 127.0.0.1 and only expose ports via Nginx stream or proxy on the same host, keeping remote access only to ports 80/443.

Step 8 — Client configuration and testing

On the client, use a Trojan-capable client (e.g., Trojan-Qt5, V2RayN with Trojan plugin, or trojan-go client). Create a profile with the following essentials:

  • Server: vpn.example.com, port 443 (or your configured port)
  • Password: the same string defined in server config
  • TLS: enabled, with SNI set to your domain (vpn.example.com), certificate verification enabled

Test connectivity and routing. Use curl or web browsers to verify remote endpoints. A simple test: with the client connected, run curl -I https://ifconfig.co to confirm the server IP and headers match expectations.

Operational considerations and hardening

To operate a secure, reliable Trojan VPN node, follow these best practices:

  • Monitoring: Set up logging rotation for trojan logs and monitor resource usage with tools like Netdata or Prometheus exporters.
  • Backups and snapshots: Use DigitalOcean snapshots to capture working states, and store backups of /etc/trojan and /etc/letsencrypt to recover configuration quickly.
  • Rate limiting and abuse prevention: Consider fail2ban to ban repeated malicious connection attempts, and use Nginx rate limiting if necessary.
  • Certificate renewal automation: Certbot auto-renews certificates; confirm postrenewal hooks reload Nginx and trojan if they directly use the cert files.
  • Key rotation: Periodically rotate passwords/UUIDs for accounts and maintain a secure secrets store for distribution to clients.
  • Network isolation: Use private networking and VPC features if you host multiple services to prevent lateral movement.

Troubleshooting common issues

Some typical problems and quick diagnostics:

  • Certificate errors: ensure domain resolves to the droplet IP and certs exist at the paths specified. Use openssl s_client -connect vpn.example.com:443 -servername vpn.example.com to inspect TLS handshake.
  • Connection refused: confirm trojan is running and listening (ss -ltnp | grep trojan) and that firewall rules permit the traffic path between Nginx and trojan.
  • Protocol mismatches: ensure client and server agree on TLS and transport settings (WS/HTTP2 vs TCP), and that Nginx stream/proxy configuration matches the trojan transport choice.
  • High latency or drops: monitor CPU and network usage on the droplet. Consider upgrading droplet size or using dedicated networking plans if load is high.

Deploying Trojan on a DigitalOcean VPS provides a flexible, performant, and privacy-respecting VPN experience when configured correctly. By combining a properly provisioned droplet, valid TLS certificates, an Nginx reverse proxy, and a well-tuned trojan server with systemd supervision, you achieve a production-ready private VPN endpoint suitable for enterprise or developer use. For ongoing management, integrate monitoring, automate backups, and apply security best practices.

For more guides, configuration examples, and best practice templates, visit Dedicated-IP-VPN at https://dedicated-ip-vpn.com/.