Hysteria 2 on a VPS: installation and setup in 10 minutes
TL;DR
Hysteria 2 is a proxy protocol built on QUIC/UDP with TLS encryption. On a VPS, it lets you set up a personal secure proxy server with a domain and valid certificate: the server can be installed in a few minutes, and the client connects through Hysteria 2, sing-box, Nekoray, Hiddify, or other compatible applications.
- A basic server requires only 1 vCPU, 1 GB RAM, 10 GB SSD, and a public IPv4 address.
- You need a domain with an A record pointing to the server IP and open TCP/80, TCP/443, and UDP/443 ports.
- The server runs as a systemd service and uses a Let's Encrypt TLS certificate.
- Authentication is configured with one long password in the
/etc/hysteria/config.yamlfile. - The primary Hysteria 2 port is UDP/443; TCP/443 is only required for a regular HTTPS service and is not mandatory for the proxy itself.
- The configuration and certificates must be regularly copied to an external server or S3 storage.
What we are setting up and why
This guide sets up your own Hysteria 2 server on Ubuntu Server 24.04 LTS. Hysteria 2 uses QUIC running over UDP and TLS 1.3 to encrypt traffic. The client connects to your domain name, authenticates, and sends internet traffic through the VPS.
Such a server is useful when you need a personal proxy for a laptop, phone, home computer, or small team. Unlike public VPNs, you control the IP address, configuration, logs, access password, and updates. At the same time, a VPS does not make traffic “anonymous”: destination websites still see the server IP, and the VPS provider may see infrastructure metadata.
After setup, you will have:
- a domain name pointing to the VPS;
- a valid Let's Encrypt TLS certificate;
- a
hysteria-server.serviceservice that starts after reboot; - a protected UDP port 443 accessible only through Hysteria 2 authentication;
- a client YAML configuration for a Windows, Linux, macOS, Android, or iOS client that supports Hysteria 2;
- a backup of the configuration and certificates.
Why Hysteria 2
The main difference between Hysteria 2 and a classic VPN is the transport. WireGuard uses its own UDP protocol, OpenVPN is often used over UDP or TCP, while Hysteria 2 transfers data via QUIC with TLS. QUIC can handle packet loss and network path changes better, which can be useful on mobile networks and unstable connections.
| Tool | Primary transport | Typical use | Feature |
|---|---|---|---|
| Hysteria 2 | QUIC / UDP | Personal proxy | TLS, high resilience to packet loss |
| WireGuard | UDP | Full-network VPN | Simple and fast IP-layer tunnel |
| OpenVPN | UDP or TCP | Corporate VPNs | Mature ecosystem, higher overhead |
| Shadowsocks | TCP / UDP | Proxy | Lightweight design, but a different obfuscation model |
Self-hosted or a ready-made VPN service
A ready-made VPN service is convenient: you do not need to administer a server, renew a certificate, or track updates. However, you share infrastructure with other users, do not manage the server configuration, and must trust the service operator.
Self-hosted Hysteria 2 requires basic Linux administration, but provides an independent server, control over keys, and the ability to change providers simply by deploying the configuration on another VPS. For one or two users, this is usually the simplest personal infrastructure scenario.
Use the server in accordance with the laws of your country, data center rules, and the terms of the services you connect to. Hysteria 2 is a networking tool, not a means of bypassing legal obligations.
What VPS configuration is needed for this task
Hysteria 2 itself consumes little memory and CPU. The load depends not on the number of configurations, but on the number of simultaneous clients, channel speed, encryption, and traffic volume. For personal use, network quality and the absence of strict UDP restrictions are usually more important than a large amount of disk space.
| Scenario | CPU | RAM | Disk | Network |
|---|---|---|---|---|
| 1–3 personal devices | 1 vCPU | 1 GB | 10–20 GB SSD | 100 Mbps, from 1 TB of traffic |
| Family or small team of up to 10 people | 2 vCPU | 2 GB | 20 GB SSD | 100–300 Mbps, from 3 TB of traffic |
| Consistently high load | 4 vCPU | 4 GB | 40 GB SSD | 1 Gbps, high or unlimited traffic allowance |
A practical starting option: 1 vCPU, 1 GB RAM, 20 GB NVMe/SSD, a public IPv4 address, a 100 Mbps connection, and UDP enabled. For this scenario, you can choose a VPS with the specified characteristics or a similar virtual server from another provider.
When a VPS is enough
A VPS is suitable almost always: for a personal proxy, several devices, a small family, remote work, and test environments. Hysteria 2 does not store large databases and does not require dedicated storage. Even at speeds of hundreds of megabits, the bottleneck is usually the connection limit or monthly traffic quota rather than computing resources.
When dedicated is needed
A dedicated server makes sense if dozens of users consistently consume hundreds of megabits or gigabits, if you need guaranteed CPU without the noisy neighbor effect, multiple network IPs, custom routing rules, or a very large monthly traffic volume. For a single user, dedicated is almost always excessive.
How to choose a location
Location affects latency, routing, and speed. Choose a region close to the primary users: the lower the RTT, the more responsive websites, calls, and interactive applications will be. Before ordering, check whether the provider allows UDP/443 and whether QUIC is filtered. Also keep in mind that the server IP address will determine the available regional versions of websites and services.
You will need an A record for the domain, for example hy.example.com, pointing to the VPS IPv4 address. If you enable IPv6, add an AAAA record only if the server actually has working public IPv6 and the required UDP port is open in the firewall.
Preparing the server
The following assumes a clean Ubuntu 24.04 LTS server with SSH access as the root user. Perform the initial connection from a local terminal. Before disabling root login, make sure that SSH key login under the new user works in a separate terminal window.
Update the system and install basic utilities
This command updates the package index, installs all available updates, and adds tools for the firewall, certificates, and diagnostics.
apt update && apt upgrade -y
apt install -y curl wget ca-certificates gnupg ufw fail2ban certbot qrencode
Reboot the server if the kernel was updated. After rebooting, reconnect via SSH.
reboot
Create a separate administrator
Replace admin with your username. The command creates an account, home directory, and adds the user to the sudo group.
adduser admin
usermod -aG sudo admin
Create a key on your local computer if you do not already have one. Do not transfer the private key to the server or send it through messengers.
ssh-keygen -t ed25519 -a 100 -C "admin@local"
Copy the public key to the server. Specify your VPS IP address.
ssh-copy-id admin@SERVER_IP
Test the new login in a separate terminal before changing SSH settings.
ssh admin@SERVER_IP
Disable root login and password authentication
Open the SSH configuration in the nano editor.
sudo nano /etc/ssh/sshd_config
Add or modify the following settings. If a line already exists in the file, edit it instead of creating a duplicate.
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
KbdInteractiveAuthentication no
Check the syntax and restart the SSH service. Do not close the current session until you have verified again that key-based login works.
sudo sshd -t && sudo systemctl restart ssh
Configure the firewall
TCP/80 is required to issue a certificate through HTTP-01. Hysteria 2 accepts traffic on UDP/443. SSH remains open only because the server needs to be managed. If you have a static home IP, you can later restrict SSH to that address only.
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/udp
sudo ufw enable
sudo ufw status verbose
Do not open TCP/443 unless necessary. The Hysteria 2 setup in this article uses UDP/443. TCP/443 will be required if you later deploy Caddy, Nginx, or another web server for a website or reverse proxy.
Enable Fail2ban
Fail2ban primarily protects SSH from password and key brute-force attempts. With password authentication disabled, the risk is already lower, but the service is still useful as an additional layer of protection.
sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd
Check DNS before issuing the certificate
Create an A record in the DNS panel. The example uses the domain hy.example.com. Substitute your own domain name and the actual server IP.
dig +short A hy.example.com
curl -4 ifconfig.me
The first command should display the VPS IP, and the second the server's public IPv4 address. If the addresses differ, do not continue: Let's Encrypt will not be able to verify domain ownership.
Installing Hysteria 2 — step by step
As of early 2026, it is recommended to use the current stable Hysteria 2 branch rather than the old Hysteria 1. Before installation, check the latest release number in the project's official repository. This example uses the official installer: it downloads the appropriate binary, creates a systemd service, and creates the /etc/hysteria directory.
Issue a Let's Encrypt TLS certificate
Certbot in standalone mode temporarily starts a small HTTP server on TCP/80. Make sure the port is open in UFW and in the provider's control panel. Replace the email address and domain with your own.
sudo certbot certonly --standalone \
--agree-tos \
--no-eff-email \
--email [email protected] \
-d hy.example.com
After success, the certificate will be located in the following directory:
sudo ls -la /etc/letsencrypt/live/hy.example.com/
We are interested in the fullchain.pem and privkey.pem files. Do not publish the contents of privkey.pem: it is a private TLS key.
Download and install Hysteria 2
The command below runs the official installer. Before running it, it is useful to view the script in a browser or download it separately for auditing, especially if the server is used in production infrastructure.
bash <(curl -fsSL https://get.hy2.sh/)
The installer usually prompts you to select installation of the server component. After completion, check the binary version. A version in the v2.x.x format is expected.
hysteria version
Check which unit files were created. In most installations, the server is named hysteria-server.service.
sudo systemctl list-unit-files | grep hysteria
Create a secure access password
The Hysteria 2 password is not a Linux user password. It is a separate secret that must be known by the server and every authorized client. Generate at least 32 random characters.
openssl rand -base64 36
Save the value in a password manager. For automatic substitution into the configuration, you can temporarily store it in a variable for the current shell session. The variable will disappear after restarting the terminal.
export HY2_PASSWORD='ВСТАВЬТЕ_СЮДА_СГЕНЕРИРОВАННЫЙ_ПАРОЛЬ'
Prepare the configuration directory
The installer most often already creates the directory. The command below ensures that it exists and restricts configuration reading to the root user.
sudo install -d -m 700 /etc/hysteria
sudo touch /etc/hysteria/config.yaml
sudo chmod 600 /etc/hysteria/config.yaml
At this point, the binary is installed, the certificate has been issued, and the server is ready for configuration.
Server and client configuration
Hysteria 2 uses YAML. A minimal server configuration specifies the listening address, TLS certificate, and authentication password. For a personal server, it is best not to enable obfuscation unless necessary: it complicates troubleshooting and does not replace TLS.
Server configuration
Open the file:
sudo nano /etc/hysteria/config.yaml
Paste the configuration. Replace the domain and password. Port :443 means listening on UDP/443 on all network interfaces.
listen: :443
tls:
cert: /etc/letsencrypt/live/hy.example.com/fullchain.pem
key: /etc/letsencrypt/live/hy.example.com/privkey.pem
auth:
type: password
password: "ВСТАВЬТЕ_ДЛИННЫЙ_СЛУЧАЙНЫЙ_ПАРОЛЬ"
masquerade:
type: proxy
proxy:
url: https://www.cloudflare.com/
rewriteHost: true
The masquerade block defines the response to ordinary HTTP requests if they reach the server rather than as valid Hysteria 2 traffic. It does not affect client password authentication. Specify an available HTTPS website as the URL; do not use your own domain if it does not have a separate web server.
It is best not to store the secret in a Git repository, screenshots, or public notes. For a single personal machine, it is acceptable to store the password directly in a file with 600 permissions. In automation commands, you can use an environment variable, but do not expose it through shell history or the process list.
Certificate permissions
Hysteria runs with root privileges in a typical systemd configuration and can read the Let's Encrypt key. Check the paths to rule out typos.
sudo test -r /etc/letsencrypt/live/hy.example.com/fullchain.pem && echo "cert OK"
sudo test -r /etc/letsencrypt/live/hy.example.com/privkey.pem && echo "key OK"
Start the service
The command enables automatic startup after reboot and immediately starts the server.
sudo systemctl enable --now hysteria-server.service
sudo systemctl status hysteria-server.service --no-pager
If the unit has a different name, use the output of the systemctl list-unit-files | grep hysteria command from the previous section. On successful startup, the status should be active (running).
Check the UDP port
The command shows the process listening on UDP/443. Hysteria should appear in the output.
sudo ss -lunp | grep ':443'
Hysteria 2 client configuration
Create a client.yaml file on the client computer. It is suitable for the Hysteria 2 CLI client and contains only the required parameters. The domain and password values must exactly match those on the server.
server: hy.example.com:443
auth: "ВСТАВЬТЕ_ДЛИННЫЙ_СЛУЧАЙНЫЙ_ПАРОЛЬ"
tls:
sni: hy.example.com
insecure: false
socks5:
listen: 127.0.0.1:1080
http:
listen: 127.0.0.1:8080
The insecure: false parameter is essential: the client verifies the certificate and the name in the certificate. Do not set true as a “quick fix” for a TLS error. If verification fails, fix the DNS, device date, SNI, or certificate.
After starting the client, the local SOCKS5 proxy will be available at 127.0.0.1:1080, and the HTTP proxy at 127.0.0.1:8080. In your browser or application, specify SOCKS5 127.0.0.1, port 1080. Do not listen for SOCKS5 on 0.0.0.0, otherwise other devices on the network may use the local proxy.
Starting the client via CLI
If the Hysteria 2 binary is installed on the client, start it with this command:
hysteria -c client.yaml client
For graphical clients, import the values manually: protocol type Hysteria 2, address hy.example.com, port 443, password, SNI hy.example.com, and certificate verification enabled. Field names depend on the application, but the meaning of the parameters is the same.
Automatic certificate renewal
Certbot on Ubuntu installs a systemd timer. However, Hysteria must be restarted after certificate files are updated; otherwise, the process will continue using the old certificate in memory. Create a deploy hook.
sudo install -d -m 755 /etc/letsencrypt/renewal-hooks/deploy
sudo nano /etc/letsencrypt/renewal-hooks/deploy/restart-hysteria.sh
Add the following script:
#!/bin/sh
systemctl restart hysteria-server.service
Make the file executable and test safe renewal mode.
sudo chmod 755 /etc/letsencrypt/renewal-hooks/deploy/restart-hysteria.sh
sudo certbot renew --dry-run
Functionality testing
Testing should proceed in three stages: the server service, port availability, and actual traffic flow through the client. Do not limit yourself to the systemd status: the service may be running, while UDP may be blocked by the provider's firewall or the domain may point to another IP.
Check the server logs
Display the last 100 log lines and keep the log stream open during the first client connection.
sudo journalctl -u hysteria-server.service -n 100 --no-pager
sudo journalctl -u hysteria-server.service -f
During normal startup, there should be no certificate read, YAML syntax, or port binding errors. The address already in use error means that UDP/443 is already occupied by another process.
Check DNS and the certificate
From the client machine, verify that the domain resolves to the correct IPv4 address. Regular curl does not test Hysteria 2 because it is not an HTTP server, but a DNS check is still required.
dig +short hy.example.com
ping -c 3 hy.example.com
Ping may be blocked by network rules and is not definitive diagnostics. More important are that the IP address from dig matches the VPS IP and that the Hysteria client connects successfully.
Check traffic through SOCKS5
After starting the client process, make a request through the local SOCKS5 proxy. The command should display your VPS's public IP, not your home provider's IP.
curl --proxy socks5h://127.0.0.1:1080 https://ifconfig.me/ip
echo
The socks5h option makes curl resolve the domain name through the proxy rather than locally. This is useful for verifying that DNS requests for this request also pass through the remote server.
Check speed and packet loss
First measure the normal VPS speed, then test through the proxy. To quickly test downloading a large file, use any permitted public resource. If the speed is noticeably lower than expected, check the plan limit, CPU load, route, and whether UDP filtering is present.
top
sudo ss -s
sudo journalctl -u hysteria-server.service --since "10 minutes ago"
Do not judge quality based on a single speed test: the result depends on the route to the test server, time of day, and the client network. For a real assessment, check websites, video calls, file downloads, and the mobile network.
Backups and Maintenance
Hysteria 2 does not store a user database in the basic setup, so backups are simpler than for GitLab or Mattermost. However, losing the configuration, TLS key, and domain details will still complicate recovery. A backup should not remain only on the same VPS: if the server is deleted, it will be lost along with the data.
What to back up
/etc/hysteria/config.yaml— server configuration and access password;/etc/letsencrypt/— certificates, private keys, and renewal settings;/etc/ufw/— UFW rules, if you changed them manually;/etc/ssh/sshd_configand additional files from/etc/ssh/sshd_config.d/;- a list of installed software and systemd settings;
- a separately saved client configuration or connection parameters.
You do not need to back up the Hysteria binary itself: it can be downloaded again from the official release. It is more important to preserve the verified configuration and secrets.
Simple archive backup with rsync
The example below copies critical directories to a separate backup VPS over SSH. On the backup server, create the backup user, the /srv/backups/hysteria directory, and a separate SSH key with restricted permissions in advance.
sudo nano /usr/local/sbin/backup-hysteria.sh
Script contents:
#!/bin/bash
set -euo pipefail
DATE=$(date +%F)
BACKUP_DIR="/tmp/hysteria-backup-${DATE}"
REMOTE="backup@BACKUP_SERVER_IP:/srv/backups/hysteria/"
mkdir -p "${BACKUP_DIR}"
tar -czf "${BACKUP_DIR}/hysteria-config.tar.gz" \
/etc/hysteria \
/etc/letsencrypt \
/etc/ufw \
/etc/ssh/sshd_config \
/etc/ssh/sshd_config.d 2>/dev/null
rsync -a --delete "${BACKUP_DIR}/" "${REMOTE}"
rm -rf "${BACKUP_DIR}"
Make the script executable and run it manually. Always verify the first run before adding it to cron.
sudo chmod 700 /usr/local/sbin/backup-hysteria.sh
sudo /usr/local/sbin/backup-hysteria.sh
For a production setup, restic or borg is preferable: they encrypt content, support deduplication, snapshot history, and storage in S3-compatible buckets. If you use rsync, SSH provides encryption during transfer, but the files themselves on the backup server will be accessible to its administrator.
Add a cron job
Open root's crontab and run the backup daily at night. The log will be useful for diagnosing failed copies.
sudo crontab -e
30 3 * /usr/local/sbin/backup-hysteria.sh >> /var/log/hysteria-backup.log 2>&1
Updating Hysteria 2
For a personal server, update Hysteria 2 during a short maintenance window once a month or after important security releases. Before updating, create a backup, read the changelog, and save the current version. An update usually interrupts active connections for a few seconds.
hysteria version
sudo /usr/local/bin/hysteria version
sudo systemctl stop hysteria-server.service
sudo cp /usr/local/bin/hysteria /root/hysteria.backup
sudo systemctl start hysteria-server.service
The specific update command depends on the installation method and may be available in the official installer. After updating, always run hysteria version, check the systemd status and client connection. If the new version does not start, restore the binary and configuration from the backup.
A “rolling update” is not needed for a single server: use a short maintenance window. For multiple servers, update one node first, verify it, then switch clients or the load balancer to it and update the rest.
Troubleshooting and FAQ
The Hysteria 2 service does not start: what should I check?
First, run sudo systemctl status hysteria-server.service --no-pager and sudo journalctl -u hysteria-server.service -n 100 --no-pager. The most common causes are incorrect YAML indentation, an invalid path to fullchain.pem or privkey.pem, UDP/443 already being in use, or unescaped characters in the password. Use spaces rather than tabs, and enclose the password in double quotes. After fixing the issue, run sudo systemctl restart hysteria-server.service.
Certbot reports that it could not complete the HTTP-01 challenge. How do I fix it?
Check the A record with dig +short hy.example.com: it must point to the VPS IP. Make sure TCP/80 is open both in UFW and in the provider panel's external firewall. The command sudo ss -ltnp | grep ':80' will show whether the port is occupied by a web server. If Nginx or Caddy is already listening on TCP/80, use certbot with the webroot method or temporarily stop the web server while issuing the certificate.
The client shows the TLS certificate verification failed error. What should I do?
Do not enable insecure: true as a permanent solution. Check that the client specifies sni: hy.example.com, not the VPS IP address, and that this exact domain is listed in the certificate. Verify the date and time on the client device. Also make sure the domain DNS points to the correct server. If the certificate was issued recently, check the file paths and restart Hysteria after renewal.
The server is running, but the client cannot connect and there are no events in the logs. Why?
Most likely, UDP/443 is blocked before reaching the server. Check sudo ufw status, the presence of the 443/udp ALLOW rule, and the network firewall in the VPS panel. Some networks, especially corporate or guest Wi-Fi networks, restrict UDP or QUIC. Test the connection from a mobile network. Also make sure the server is actually listening on UDP/443: sudo ss -lunp | grep ':443'.
Why is the speed low through Hysteria 2?
Compare the speed without the proxy and through the proxy, then check CPU usage with top during the test. The cause may be the VPS bandwidth limit, monthly traffic quota, a congested route, restrictions on the client network side, or UDP packet loss. Choose a location closer to the user and test several destinations. Do not increase speed parameters in the configuration blindly: first make sure the issue is not with the provider's connection.
What is the minimum suitable VPS configuration?
For one user or several personal devices, 1 vCPU, 1 GB RAM, 10 GB SSD, and a public IPv4 address are sufficient at minimum. You need available UDP traffic and open UDP/443. It is better to choose 20 GB of disk space right away: this provides room for updates, logs, and certificates. For networking, a reasonable minimum is 100 Mbps and 1 TB of traffic per month, but for active video streaming or downloads, a larger quota is more important.
Which should I choose for this task — a VPS or dedicated server?
For Hysteria 2, almost always start with a VPS. It is cheaper, deploys quickly, and provides enough resources for a personal proxy or small team. A dedicated server is needed for consistently high load, dozens of active users, a requirement for guaranteed CPU, 1 Gbps without heavy virtualization, or very high traffic volumes. Moving to a dedicated server does not change the Hysteria configuration itself: simply transfer the domain, certificate, and YAML file.
Can multiple devices connect using one password?
Technically, yes, and it is a convenient option for a single owner. The drawback is that if the password leaks, you will have to replace it on the server and on all devices. For a family or team, use separate credentials if your Hysteria 2 management setup and client support this, or create separate servers or configurations. Never publish a client configuration with a real password publicly.
Do I need to open TCP/443?
For a minimal Hysteria 2 configuration over QUIC, you need UDP/443, not TCP/443. TCP/80 is required only when issuing and renewing a certificate with the HTTP-01 method. TCP/443 can remain closed if there is no website or reverse proxy on the server. Open additional ports only for a specific purpose: this reduces the attack surface and simplifies firewall rule diagnostics.
Security and Practical Limitations
A working proxy server is more than just a YAML file. Minimum security includes SSH keys, disabled root login, a firewall, regular updates, and backups. The most common cause of small VPS compromise is not a Hysteria vulnerability, but a weak SSH password, an exposed administration panel, or a forgotten service that is not being updated.
Post-setup checklist
- SSH login is allowed only with keys.
- Remote login for the root user is disabled.
- Only SSH, TCP/80, and UDP/443 are open.
- Ubuntu security updates are installed.
- The Hysteria password contains at least 32 random characters.
- TLS verification is enabled on clients.
- Certbot successfully completes
renew --dry-run. - Configuration and certificates are copied outside the VPS.
- Recovery of at least one backup has been tested.
Do not publish secrets
The client file contains the server address and password. It must not be sent to public chats, added to GitHub, included in screenshots, or stored in an unsecured cloud document. If the configuration was sent to the wrong person, consider the password compromised: generate a new one, modify the server YAML, restart the service, and update all clients.
Monitor traffic
Check traffic usage in the VPS panel and system logs. An unusual increase in outgoing traffic may indicate a password leak or unauthorized use of the server. If you suspect compromise, immediately replace the Hysteria password, SSH keys if necessary, update the system, and review login logs.
sudo journalctl -u hysteria-server.service --since "24 hours ago"
sudo last -a | head -20
sudo apt update && sudo apt upgrade -y
Hysteria 2 limitations
Hysteria 2 depends on UDP availability. In some corporate networks, hotels, educational institutions, and public Wi-Fi networks, UDP may be restricted or work unreliably. In this case, it is useful to have a backup method of remote access, such as WireGuard or a regular HTTPS service for administration. Do not remove SSH access until you have tested the Hysteria connection from the real networks you plan to use.
Conclusions and Next Steps
Hysteria 2 is now running on the VPS with a TLS certificate, password authentication, firewall, and automatic certificate renewal. The client connects to your domain over UDP/443 and creates a local SOCKS5 or HTTP proxy.
- Test the connection from your home network, mobile internet, and work Wi-Fi.
- Set up an encrypted backup on a separate VPS or S3 storage and test recovery.
- Update Ubuntu and Hysteria 2 once a month, and as load grows, monitor traffic, CPU, and route quality.
If several people will use the server, separate access credentials, document password changes, and prepare a procedure for migration to a new IP or more powerful server in advance.