Deploying a high-performance, secure V2Ray server on a modern CentOS 9 host requires attention to system hardening, correct networking, and a reliable TLS setup. This guide walks you through a practical, production-ready deployment with granular technical details, covering everything from kernel tuning and firewall rules to V2Ray configuration and certificate automation. The target audience is site owners, enterprise administrators, and developers who need a dependable, maintainable proxy/VPN backend.

Prerequisites and initial hardening

Begin with a minimal CentOS 9 installation (x86_64) and ensure you have root or sudo access. Confirm the system is up to date and that you have a registered domain name pointed to the server’s public IP (A record).

  • Update packages: sudo dnf update -y
  • Create a limited admin user and enable SSH key authentication; disable password auth in /etc/ssh/sshd_config.
  • Set the timezone and synchronize time: sudo timedatectl set-timezone UTC, sudo dnf install -y chrony && sudo systemctl enable –now chronyd.
  • Ensure you have ports 80 and 443 reachable (for TLS) and one additional port for V2Ray inbound if not using WebSocket/Nginx.

Network and kernel tuning (recommended)

For higher connection counts and lower latency, tweak a few kernel parameters. Add the following to /etc/sysctl.d/99-v2ray.conf:

net.core.somaxconn = 1024
net.core.netdev_max_backlog = 2500
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_tw_reuse = 1
net.ipv4.ip_local_port_range = 1024 65535

Apply immediately with sudo sysctl –system. These settings reduce wait times for socket reuse and increase backlog sizes for heavy loads.

Install prerequisites: Nginx, Certbot, and tools

If you plan to use TLS with a reverse proxy (recommended for obfuscation and browser-friendly access), install Nginx and Certbot. On CentOS 9 use the EPEL and Nginx module streams:

  • sudo dnf install -y epel-release
  • sudo dnf module enable nginx:1.24 -y (choose the supported stream)
  • sudo dnf install -y nginx certbot python3-certbot-nginx

Enable and start Nginx: sudo systemctl enable –now nginx. Verify HTTP on port 80 is accessible (used for ACME validation).

Installing V2Ray core on CentOS 9

There are official V2Ray distributions and community scripts. For production, prefer installing the upstream release binary to avoid unpredictable changes.

  • Download the latest V2Ray release from the official GitHub releases page. For example: curl -L -o /tmp/v2ray.zip “https://github.com/v2fly/v2ray-core/releases/latest/download/v2ray-linux-64.zip”
  • Unzip and install binaries into /usr/local/bin: sudo unzip /tmp/v2ray.zip -d /tmp/v2ray && sudo install -m 755 /tmp/v2ray/v2ray /usr/local/bin/v2ray && sudo install -m 755 /tmp/v2ray/v2ctl /usr/local/bin/v2ctl
  • Create configuration and service dirs: sudo mkdir -p /etc/v2ray /var/log/v2ray

Create a systemd service file at /etc/systemd/system/v2ray.service with standard settings, or use this minimal unit:

[Unit] Description=V2Ray Service
After=network.target

[Service] User=nobody
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE
NoNewPrivileges=true
ExecStart=/usr/local/bin/v2ray -config /etc/v2ray/config.json
Restart=on-failure

[Install] WantedBy=multi-user.target

Reload systemd and enable the service: sudo systemctl daemon-reload && sudo systemctl enable –now v2ray. Initially the service will fail until a valid config exists; that’s expected.

Designing the V2Ray configuration

V2Ray supports multiple protocols: VMess, VLESS, Trojan, and more. For modern setups prefer VLESS+TLS with WebSocket or QUIC for better performance and reduced fingerprinting. Below are the key components you will configure in /etc/v2ray/config.json:

Inbound configuration

Use the “vless” inbound on a local port (e.g., 12345) when using Nginx as a TLS terminator and WebSocket passthrough. Example inbound snippet (conceptual):

{ “inbounds”: [ { “port”: 12345, “protocol”: “vless”, “settings”: { “clients”: [ { “id”: “UUID-GOES-HERE”, “flow”: “xtls-rprx-direct” } ] }, “streamSettings”: { “network”: “ws”, “wsSettings”: { “path”: “/ws-path” } } } ] }

Generate a UUID with sudo /usr/bin/uuidgen and replace the placeholder.

Outbound configuration

Typically use the default outbound which routes to the Internet (“freedom”). Add a DNS outbound or configure system DNS for name resolution.

{ “outbounds”: [ { “protocol”: “freedom”, “settings”: {} }, { “protocol”: “blackhole”, “tag”: “blocked”, “settings”: {} } ] }

Routing, logging, and policy

Define routing rules to block private IPs or route specific traffic to internal services. Configure log level to “warning” in production; set a file target in /var/log/v2ray/access.log and error.log with appropriate logrotate rules.

Reverse proxy with Nginx and TLS (Let’s Encrypt)

To make V2Ray traffic look like standard HTTPS, terminate TLS with Nginx and proxy WebSocket to the V2Ray inbound. Create an Nginx server block:

server {
listen 80; server_name your.domain.example;
location /.well-known/acme-challenge/ { root /var/www/html; }
location / { return 301 https://$host$request_uri; }
}

Obtain a certificate: sudo certbot –nginx -d your.domain.example –non-interactive –agree-tos -m you@domain.example. Certbot will update Nginx to use the certs in /etc/letsencrypt/live/your.domain.example/.

Modify the TLS server block to support proxying WebSocket and set headers:

server {
listen 443 ssl http2; server_name your.domain.example;
ssl_certificate /etc/letsencrypt/live/your.domain.example/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your.domain.example/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
add_header Strict-Transport-Security “max-age=31536000; includeSubDomains” always;
location /ws-path { proxy_redirect off; proxy_pass http://127.0.0.1:12345; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection “upgrade”; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; }
}

Reload Nginx: sudo systemctl reload nginx. This setup ensures TLS termination and forwards the WebSocket to V2Ray.

Firewall and SELinux considerations

CentOS 9 uses firewalld by default. Open required ports and restrict others:

  • Allow HTTP/HTTPS: sudo firewall-cmd –permanent –add-service=http && sudo firewall-cmd –permanent –add-service=https
  • If V2Ray listens on local-only ports (like 12345), block external access and only allow Nginx proxy: ensure V2Ray’s listen interface is 127.0.0.1 or set rich rules accordingly.
  • Reload: sudo firewall-cmd –reload

For SELinux, if you keep files in standard locations and use Nginx + Certbot packages, most policies will work. If you bind services to nonstandard ports or use custom binaries, set SELinux booleans or add policies. Temporarily check with sudo setenforce 0 only for debugging — do not leave SELinux disabled in production. Use audit2allow to generate a tailored policy if needed.

Start, enable, and test V2Ray

After you finalize /etc/v2ray/config.json, restart the service and check logs:

  • sudo systemctl restart v2ray
  • sudo journalctl -u v2ray -f to watch startup logs
  • Confirm Nginx is proxying: sudo tail -f /var/log/nginx/access.log

From a client, configure a V2Ray client with the same UUID, VLESS protocol, and WebSocket path. Test connectivity by browsing to an https site through the proxy or use curl with the proxy settings. If connections fail, check:

  • Nginx error logs (/var/log/nginx/error.log)
  • V2Ray error log (/var/log/v2ray/error.log)
  • firewalld and SELinux denials

Automation, maintenance, and monitoring

Set up certificate renewal checks (certbot installs a timer) and ensure systemd unit restarts on failure. For monitoring, integrate metrics using Prometheus exporters (V2Ray has third-party exporters) or basic uptime checks. Configure logrotate for V2Ray logs at /etc/logrotate.d/v2ray to prevent disk filling.

Security best practices

  • Use strong, unique UUIDs per client and rotate them periodically.
  • Limit inbound binding to 127.0.0.1 when using reverse proxy to mitigate direct access.
  • Harden SSH (change default port, disable root login, use key-based auth).
  • Enable fail2ban to protect against brute-force attempts on exposed services.
  • Keep V2Ray and system packages updated; subscribe to CVE notices or GitHub release notifications for v2fly/v2ray-core.

Troubleshooting checklist

  • Certificate problems: check /var/log/letsencrypt and certbot status. Ensure domain A record points correctly and port 80 is accessible for validation.
  • Connection resets: verify Nginx proxy headers include Upgrade and Connection for WebSocket, and that V2Ray streamSettings network matches Nginx path.
  • Permissions: check file ownership for /etc/v2ray and /var/log/v2ray; the service user must be able to read configs and write logs.
  • High latency: confirm kernel tuning, check network bandwidth, and consider enabling TLS session reuse or QUIC transport for lower latency.

This deployment pattern — V2Ray as an application backend with Nginx as the TLS/WebSocket terminator — provides strong security, good performance, and easy certificate management. It also creates a minimal fingerprint when observed on the network because traffic looks like standard HTTPS.

For further reference, consult the official V2Ray (v2fly) documentation for the exact JSON schema and advanced features like routing, multiplexing, and transport-level optimizations. When you’re ready to scale, consider using multiple nodes with centralized configuration management and metrics collection.

Learn more about secure deployments and dedicated IP solutions at Dedicated-IP-VPN: https://dedicated-ip-vpn.com/