Настройка сервера прокси¶
Inventory API Proxy Servers¶
All 11 servers proxy HTTPS traffic to the backend (10.99.87.249:8080 via 212.70.189.60:5011).
SSH key: ~/.ssh/id_ed25519_shivavpn. Nginx timeouts: connect 3s / read 15s / send 10s.
| # | Hostname | IP | Location | Domains | Client usage |
|---|---|---|---|---|---|
| 1 | km-proxy01 (MAIN) | 212.70.189.60 | Riga, Latvia | api.shivavpn.io, api.shivavpn.com, api-v2.shivavpn.io, api.shiva-app.io | Desktop, Android |
| 2 | proxy-dev | 212.70.189.61 | Riga, Latvia | dev.shivavpn.io | Dev/testing only |
| 3 | vpn-vdsina-russia-04 | 88.210.53.146 | Netherlands | 88.210.53.146.sslip.io, api.shiva-app.io | Desktop, Android |
| 4 | proxy-monovm-netherlands-01 | 79.110.52.167 | Netherlands | 79.110.52.167.sslip.io | Desktop, Android |
| 5 | Lithuania #1 | 213.197.140.69 | Lithuania | 213.197.140.69.sslip.io | Desktop, Android |
| 6 | Lithuania #2 | 213.197.140.70 | Lithuania | 213.197.140.70.sslip.io | Desktop, Android |
| 7 | proxy-thehosting-austria-01 | 5.181.21.90 | Austria | 5.181.21.90.sslip.io | — |
| 8 | proxy-thehosting-poland-01 | 2.56.125.33 | Poland | 2.56.125.33.sslip.io | Android |
| 9 | proxy-thehosting-germany-01 | 94.131.111.10 | Germany | 94.131.111.10.sslip.io | Android |
| 10 | proxy-thehosting-uk-01 | 45.159.248.55 | UK | 45.159.248.55.sslip.io | Android |
| 11 | proxy-thehosting-netherlands-01 | 45.67.231.125 | Netherlands | 45.67.231.125.sslip.io | Android |
SSH (km-proxy01): ssh -i ~/.ssh/id_ed25519_shivavpn -p 2255 root@212.70.189.60
SSH (others): ssh -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519_shivavpn root@<IP>
Ansible inventory
km-proxy01 and proxy-dev are NOT in Ansible inventory (manually managed). Lithuania servers (213.197.140.69/70) and TheHosting servers need to be added to Ansible.
Client Failover¶
Desktop (Rust): Hardcoded endpoints → Firebase Remote Config → DNS TXT (apis2.shiwa.se). No persistence — starts from first endpoint on restart.
Android: Cycles through 20 hardcoded URLs sequentially. Saves the last successful URL to SharedPreferences.
iOS: Firebase Remote Config (api_proxies key). Hardcoded fallback IPs.
Adding a New Proxy Server¶
Прокси должен настраиваться отдельно. На нем не должен работать сервис VPN, поскольку они используют один порт.
Для настройки средствами Ansible проверяем что в разделе proxy есть нужный нам сервер
Теперь выполняем команду:
Будет настроен Nginx и самоподписанные сертификаты
После этого будет настроен домен вида <IP сервера>.sslip.io это бесплатный сервис для преобразования IP в домен.
После этого будет выпущен сертификат через certbot.
\
В случае если на этапе выпуска сертификата что-то пошло не так выполняем следующие шаги¶
Создаем файл /etc/nginx/conf.d/proxy.conf с содержимым по примеру ./ansible/roles/server-ubuntu/templates/nginx/conf/proxy_prepare.conf.j2
server {
server_name <IP сервера>.sslip.io;
listen 80;
location ~ /.well-known {
location ~ /.well-known/acme-challenge/(.*) {
default_type "text/plain";
root /var/www/letsencrypt;
}
}
}
Выполняем перезапуск Nginx
Теперь выпускаем сертификат вручную, например так:
certbot certonly --agree-tos --register-unsafely-without-email --no-eff-email --webroot -w /var/www/letsencrypt -d 88.210.53.146.sslip.io
В результате нам выведется следующее
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Found the following certs:
Certificate Name: 88.210.53.146.sslip.io
Serial Number: 5d9a033ace8c4abd483c88eec1bc78d4c82
Key Type: RSA
Domains: 88.210.53.146.sslip.io
Expiry Date: 2026-01-11 07:04:13+00:00 (VALID: 89 days)
Certificate Path: /etc/letsencrypt/live/88.210.53.146.sslip.io/fullchain.pem
Private Key Path: /etc/letsencrypt/live/88.210.53.146.sslip.io/privkey.pem
The following renewal configurations were invalid:
/etc/letsencrypt/renewal/88.210.53.146.sslip.io.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Нам важно только два поля
Certificate Path: /etc/letsencrypt/live/88.210.53.146.sslip.io/fullchain.pem
Private Key Path: /etc/letsencrypt/live/88.210.53.146.sslip.io/privkey.pem
Теперь берем файл из нашего репо ./ansible/roles/server-ubuntu/templates/nginx/conf/proxy.conf.j2 и заменяем там поля
api_ip — IP адрес бекенда
api_port — порт для https подключения к бекенду
ansible_host — IP адрес нашего прокси сервера
Все эти переменные указаны в нашем файле инвентаря ./inventory/servers.ini
upstream api_https_upstream {
server {{ api_ip }}:{{ api_port }};
keepalive 32;
}
...
server {
server_name {{ ansible_host }}.sslip.io;
listen 80;
location ~ /.well-known {
location ~ /.well-known/acme-challenge/(.*) {
default_type "text/plain";
root /var/www/letsencrypt;
}
}
}
...
server {
server_name {{ ansible_host }}.sslip.io;
...
ssl_certificate /etc/letsencrypt/live/{{ ansible_host }}.sslip.io/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/{{ ansible_host }}.sslip.io/privkey.pem;
...
}
После этого перезапускаем nginx
\ После этого наш прокси нужно прописать в Firebase, чтобы приложения могли его использовать
Для этого переходим в раздел настроек каждого приложения
https://console.firebase.google.com/project/shiva-vpn-ios/config/env/firebase
https://console.firebase.google.com/project/shiva-vpn-desktop/config/env/firebase
https://console.firebase.google.com/project/shiva-android-915b0/config/env/firebase
В каждом из них есть переменная api_proxy или подобная, нужно добавить новый сервер аналогично имеющимся. Либо через домен, либо через IP.
Пример для iOS: