Skip to content

dovlet808/hostinger-vps-bot

Repository files navigation

Hostinger VPS Manager Bot

A Telegram bot that automates the full lifecycle of a Hostinger VPS used as a personal VPN server: change physical location, reinstall the OS, harden the network, install 3x-ui, and provision VLESS+Reality inbounds — all from a chat window.

🇷🇺 Русская версия · 🐛 Debugging story


What it does

Capability Mechanism
Change VPS physical location Browser automation via Chrome DevTools Protocol (Hostinger's Cloudflare-protected panel)
Reset / set root password Hostinger HTTPS API
Power management (start / stop / reboot) Hostinger HTTPS API
Install 3x-ui + UFW + cron + ICMP hardening + BBR SSH + expect / pipe automation
Create VLESS+Reality inbounds with custom remark and uTLS fingerprint 3x-ui REST API
Generate ready-to-use vless:// links Direct from API + on-server xray x25519
Manage UFW firewall (open / close ports with strict format validation) SSH
Run arbitrary SSH commands SSH

The bot is single-user — it ignores any chat that isn't the configured TG_CHAT_ID.


Setup flow in Telegram

/install_xui   →  panel port?  →  ⚙️ install + harden + BBR  →  ✅ panel link

/setup_inbound →  Reality / TLS+CDN  →  panel port  →  inbound port  →
                  dest (auto-completes :443 if omitted)  →  SNI list  →
                  custom remark  →  fingerprint (Chrome/Safari/iOS/Android)  →
                  ✅ inbound created + vless:// link

/firewall      →  Open / Close / List / Reload  →
                  strict format PORT/tcp or PORT/udp

End-to-end: from a freshly relocated VPS to a working VPN connection in ~10 minutes, without touching SSH or the panel manually.


Architecture

┌─────────────┐         ┌──────────────────┐         ┌──────────────┐
│  Telegram   │◄───────►│      bot.py      │◄───────►│  Hostinger   │
│   (you)     │         │  (asyncio,       │   API   │   API        │
└─────────────┘         │   conversation   │         └──────────────┘
                        │   handlers)      │
                        │                  │         ┌──────────────┐
                        │                  │◄───────►│   Chrome     │
                        │                  │   CDP   │  (CF bypass) │
                        │                  │         └──────────────┘
                        │                  │
                        │                  │         ┌──────────────┐
                        │                  │◄───────►│   Hostinger  │
                        │                  │   SSH   │   VPS        │
                        │                  │         │              │
                        │                  │   HTTP  │   3x-ui API  │
                        │                  │◄───────►│              │
                        └─────────┬────────┘         └──────────────┘
                                  │
                                  ▼
                          ┌──────────────┐
                          │  parsers.py  │
                          │   (pure      │
                          │   logic, 9   │
                          │   functions, │
                          │   95 tests)  │
                          └──────────────┘

parsers.py extracts pure-logic functions (output parsing, URL building, ICMP rule manipulation, port validation) so they can be unit-tested without SSH/HTTP dependencies. The same functions are also embedded into remote SSH commands via inspect.getsource() — single source of truth, zero drift between local and remote execution.


Installation

1. System packages

sudo apt install google-chrome-stable python3-venv python3-pip

2. Project setup

git clone <your-repo-url>
cd hostinger-vps-bot
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
playwright install chromium
playwright install-deps chromium

3. Configure secrets

cp .env.example api_tokens.env
chmod 600 api_tokens.env
nano api_tokens.env   # fill in your tokens

The bot reads from api_tokens.env — see .env.example for all variables.

4. Make Chrome launcher executable

chmod +x start_chrome.sh

Daily operation

Terminal 1 — dedicated Chrome with Hostinger session:

./start_chrome.sh
# Log in to https://hpanel.hostinger.com manually, pass the Cloudflare check.
# Keep this window open.

Terminal 2 — the bot:

source venv/bin/activate
python3 bot.py

Telegram commands

Command What it does
/start /help List commands
/status Current VPS info (IP, location, hostname, state)
/check Test Chrome CDP connection
Location & Password
/change Change VPS location → auto-reset password
/resetpwd Reset root password to env value
/setpwd Set custom root password
Power
/stop /poweron /reboot Power management
VPN
/install_xui Install 3x-ui + UFW + cron + ICMP + BBR
/setup_inbound Create VLESS inbound (Reality / TLS+CDN), with custom remark and uTLS choice
Firewall
/firewall Open / close ports (strict PORT/tcp or PORT/udp), list rules, reload
Advanced
/ssh Run any command on VPS
/cancel Abort any in-progress flow

Testing

pip install -r requirements-dev.txt
pytest -v
pytest --cov=parsers --cov-report=term-missing

95 tests · 100 % coverage of parsers.py. Each test class corresponds to a real bug from the project's history — see DEBUGGING.md.

The 9 parser functions:

Function Responsibility
parse_x25519_output Handle both legacy and new xray output formats
normalize_web_base_path Canonicalize 3x-ui's webBasePath
harden_icmp_rules Convert ICMP ACCEPT → DROP in before.rules (Ubuntu marker quirks)
build_panel_url Build URLs that work as bases AND for direct display
is_bbr_active Parse sysctl output for BBR status
is_xui_install_marker Read READY/MISSING probe result
parse_ufw_port_spec Strict PORT/tcp or PORT/udp validation
ensure_port_suffix Auto-complete apple.comapple.com:443
parse_sni_list Comma-separated SNI list with whitespace + empty handling

Limits (Hostinger-side)

Limit Value
Location changes 1 per 30 days
Available locations 9 (EU + Asia + US)
Setup time per change 5–10 minutes
State after /change All VPS data wiped

Project layout

hostinger-vps-bot/
├── bot.py                  # main bot, ~2000 lines
├── parsers.py              # pure-logic functions (testable)
├── test_parsers.py         # 95 pytest cases
├── data_centers.json       # Hostinger location ID reference
├── start_chrome.sh         # Chrome launcher with CDP
├── requirements.txt        # runtime deps
├── requirements-dev.txt    # + pytest
├── .env.example            # secrets template
├── .gitignore              # ignores api_tokens.env, venv, caches
├── README.md               # this file
├── README.ru.md            # Russian version
├── DEBUGGING.md            # the bug-hunting story
├── DEBUGGING.ru.md         # Russian version
└── LICENSE                 # MIT

Security notes

  • api_tokens.env is .gitignored and should be chmod 600
  • The Chrome profile (~/chrome-bot-profile/) is separate from your personal browser
  • The bot enforces chat_id checks on every handler — only TG_CHAT_ID can issue commands
  • /setpwd deletes the password message from chat after reading it

License

MIT — see LICENSE.

About

Telegram bot for full-cycle Hostinger VPS automation: location change via Chrome CDP, 3x-ui install, VLESS+Reality inbounds. Python, asyncio, paramiko, Playwright. 95 unit tests · 100 % parser coverage.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors