Піднімаємо свій інстанс Webogram із проксуванням через nginx

Привіт, Хабре!

Нещодавно я потрапив у ситуацію, в якій необхідно було працювати всередині корпоративної мережі з неповним доступом до інтернету і як ви можете здогадатися за заголовком — Telegram у ній було заблоковано. Впевнений, що ця ситуація знайома багатьом.

Я цілком можу обходитися без месенджерів, проте саме Telegram мені був потрібен для роботи. Встановити клієнт на робочу машину було неможливо, використовувати особистий ноутбук — теж. Ще одним рішенням вважається використовувати його офіційну веб-версію, але як ви можете здогадатися - вона була недоступна. Варіант із пошуком неофіційного дзеркала я одразу викреслюю (сподіваюся з цілком очевидних причин).

На щастя, Webogram - це opensource-проект, вихідний код якого доступний в GitHub його автора (За що велике йому спасибі!)
Сама установка і запуск не являє собою нічого складного, проте, в умовах експлуатації всередині мережі із заблокованим доступом до серверів Telegram на вас швидше чекає розчарування, ніж успіх, оскільки веб-версія відправляє запити на сервери Telegram з машини користувача.

На щастя, це досить просто (але не дуже очевидно) виправити. Хочу попередити, що я не є автором цього рішення. Мені вдалося знайти його в гілці, в якій обговорювалася проблема, схожа на мою. Рішення, яке запропонував користувач github tecknojock, мені дуже допомогло, однак, впевнений, що воно може допомогти ще комусь, тому зважився на написання даного туторіалу.

Під катом на вас чекає покрокове налаштування свого дзеркала Webogram та налаштування проксування його запитів до серверів Telegram з використанням nginx.

Як приклад я вибрав щойно встановлену та оновлену Ubuntu Server 18.04.3.

Увага: В рамках цього туторіалу не буде інструкцій з налаштування домену в nginx. Це потрібно зробити самостійно. Туторіал припускає, що у вас вже налаштований домен з ssl, а також сам сервер, на якому планується налаштування, має доступ до серверів Telegram (будь-яким на ваш смак способом)

Припустимо, що ip даного сервера 10.23.0.3, а доменне ім'я mywebogram.localhost

Відштовхуючись від цих умовностей, я наводитиму приклади конфігурацій. Не забувайте міняти значення на свої.

Отже, приступимо:

Для запуску Webogram нам необхідний nodejs. За замовчуванням, якщо встановлювати його з репозиторіїв Ubuntu, ми отримаємо nodejs версії 8.x. Нам потрібна 12.x:

curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash - 
sudo apt update && sudo apt -y install nodejs

Вибираємо місце, де базуватиметься наш Webogram.

Для прикладу – розмістимо його докорінно домашньої директорії. Для цього клонуємо офіційний репозиторій до себе на сервер:

cd ~ && git clone https://github.com/zhukov/webogram.git

Наступний крок — встановити всі залежності, необхідні для запуску програми:

cd webogram && npm install

Спробуємо здійснити тестовий запуск. Виконайте команду:

npm start

Після чого, пробуємо відкрити у браузері

 http://10.23.0.3:8000/app/index.html

Якщо до цього моменту ви все робили правильно, у вас відкриється сторінка авторизації Webogram.

Тепер нам необхідно налаштувати запуск програми як сервіс. Для цього створимо файл

sudo touch /lib/systemd/system/webogram.service

відкриємо його в будь-якому редакторі і надамо наступного вигляду (вписуємо свій шлях до WorkDirectory)

[Unit]
Description=Webogram mirror
[Service]
WorkingDirectory=/home/tg/webogram
ExecStart=/usr/bin/npm start
SuccessExitStatus=143
TimeoutStopSec=10
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target

Після чого виконуємо наступні команди:

Застосовуємо зміни

sudo systemctl daemon-reload

Включаємо автозапуск:

sudo systemctl enable webogram.service

Запускаємо сервіс:

sudo systemctl start webogram.service

Після виконання дій Webogram продовжить бути доступний на порту 8000.

Так як ми налаштовуватимемо доступ до нашого Webogram через nginx — закриємо порт 8000 для запитів з-за.

Використовуємо для цього утиліту udf (або будь-який зручний для вас спосіб):

sudo ufw deny 8000

На випадок, якщо все ж таки вирішили використовувати udf, але він вимкнений на сервері - додаємо ще правил (щоб все не розвалилося) і включаємо udf:

sudo ufw allow ssh
sudo ufw allow 80
sudo ufw allow 443
sudo ufw enable

Далі, почнемо змінювати конфігурацію nginx.

Як і попереджав вище — передбачається, що у Вашому сервері вже налаштований домен з ssl. Зверну Вашу увагу лише на те, що необхідно буде додати конфігураційний файл домену для коректної роботи:


server {
...
  location ^~ /pluto/apiw1/ {
    proxy_pass https://pluto.web.telegram.org/apiw1/;
  }
  location ^~ /venus/apiw1/ {
    proxy_pass https://venus.web.telegram.org/apiw1/;
  }
  location ^~ /aurora/apiw1/ {
    proxy_pass https://aurora.web.telegram.org/apiw1/;
  }
  location ^~ /vesta/apiw1/ {
    proxy_pass https://vesta.web.telegram.org/apiw1/;
  }
  location ^~ /flora/apiw1/ {
    proxy_pass https://flora.web.telegram.org/apiw1/;
  }
  location ^~ /pluto-1/apiw1/ {
    proxy_pass https://pluto-1.web.telegram.org/apiw1/;
  }
  location ^~ /venus-1/apiw1/ {
    proxy_pass https://venus-1.web.telegram.org/apiw1/;
  }
  location ^~ /aurora-1/apiw1/ {
    proxy_pass https://aurora-1.web.telegram.org/apiw1/;
  }
  location ^~ /vesta-1/apiw1/ {
    proxy_pass https://vesta-1.web.telegram.org/apiw1/;
  }
  location ^~ /flora-1/apiw1/ {
    proxy_pass https://flora-1.web.telegram.org/apiw1/;
  }
  location ^~ /DC1/ {
    proxy_pass http://149.154.175.10:80/;
  }
  location ^~ /DC2/ {
    proxy_pass http://149.154.167.40:80/;
  }
  location ^~ /DC3/ {
    proxy_pass http://149.154.175.117:80/;
  }
  location ^~ /DC4/ {
    proxy_pass http://149.154.175.50:80/;
  }
  location ^~ /DC5/ {
    proxy_pass http://149.154.167.51:80/;
  }
  location ^~ /DC6/ {
    proxy_pass http://149.154.175.100:80/;
  }
  location ^~ /DC7/ {
    proxy_pass http://149.154.167.91:80/;
  }
  location ^~ /DC8/ {
    proxy_pass http://149.154.171.5:80/;
  }
 location / {
    auth_basic "tg";
    auth_basic_user_file /etc/nginx/passwd.htpasswd;
    proxy_pass http://localhost:8000/;
    proxy_read_timeout 90s;
    proxy_connect_timeout 90s;
    proxy_send_timeout 90s;
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $remote_addr;
  }
}

Що ми додаємо в конфіг nginx:

  • Змінюємо кореневий location, який проксуватиме запити на порт 8000, за яким відповідає Webogram
  • Кореневий location закриваємо за допомогою basic-auth. Це чисто символічний крок, щоб закрити нашу програму від сторонніх очей і ботів. (А також щоб не було проблем з блокуваннями)
  • Купа location з proxy_path на сервері Telegram — це якраз наші ендпоінти, через які ми проксуватимемо наші запити

Також створимо файл /etc/nginx/passwd.htpasswd;щоб nginx було з чим звіряти паролі користувачів.

sudo apt install apache2-utils
sudo htpasswd -c /etc/nginx/passwd.htpasswd tg

Піднімаємо свій інстанс Webogram із проксуванням через nginx

Перезапускаємо nginx:

sudo systemctl restart nginx

Тепер Webogram буде доступний лише за адресою mywebogram.localhost/app/index.html після того, як буде введено логін та пароль, який ви визначили при створенні команди htpasswd.

Залишилося небагато: внесемо невеликі зміни до самого проекту.

Відкрийте у редакторі файл ~/webogram/app/js/lib/mtproto.js

І приведіть його початок до такого вигляду:

/*!
 * Webogram v0.7.0 - messaging web application for MTProto
 * https://github.com/zhukov/webogram
 * Copyright (C) 2014 Igor Zhukov <[email protected]>
 * https://github.com/zhukov/webogram/blob/master/LICENSE
 */

angular.module('izhukov.mtproto', ['izhukov.utils'])

  .factory('MtpDcConfigurator', function () {
    var sslSubdomains = ['pluto', 'venus', 'aurora', 'vesta', 'flora']

    var dcOptions = Config.Modes.test
      ? [
        {id: 1, host: 'mywebogram.localhost/DC1',  port: 80},
        {id: 2, host: 'mywebogram.localhost/DC2',  port: 80},
        {id: 3, host: 'mywebogram.localhost/DC3', port: 80}
      ]
      : [
        {id: 1, host: 'mywebogram.localhost/DC4',  port: 80},
        {id: 2, host: 'mywebogram.localhost/DC5',  port: 80},
        {id: 3, host: 'mywebogram.localhost/DC6', port: 80},
        {id: 4, host: 'mywebogram.localhost/DC7',  port: 80},
        {id: 5, host: 'mywebogram.localhost/DC8',   port: 80}
      ]

    var chosenServers = {}

    function chooseServer (dcID, upload) {
      if (chosenServers[dcID] === undefined) {
        var chosenServer = false,
          i, dcOption

        if (Config.Modes.ssl || !Config.Modes.http) {
          var subdomain = sslSubdomains[dcID - 1] + (upload ? '-1' : '')
          var path = Config.Modes.test ? 'apiw_test1' : '/apiw1/'
          chosenServer = 'https://mywebogram.localhost/' + subdomain + path
          return chosenServer
        }
       for (i = 0; i < dcOptions.length; i++) {
          dcOption = dcOptions[i]
          if (dcOption.id == dcID) {
            chosenServer = 'http://' + dcOption.host + '/apiw1'
            break
          }
        }
        chosenServers[dcID] = chosenServer
      }
...
 

Після цього необхідно оновити сторінку з додатком у браузері.

Відкрийте консоль браузера та перегляньте мережні запити програми. Якщо все працює, і XHR запити йдуть на ваш сервер - значить, все зроблено правильно, і Webogram тепер проксується через nginx.

Піднімаємо свій інстанс Webogram із проксуванням через nginx

Сподіваюся, що цей туторіал буде корисним ще комусь крім мене.

Дуже дякую всім, хто дочитав до кінця.

Якщо у когось виникли складнощі або я припустився якихось неточностей — із задоволенням відповім і постараюся вам допомогти у коментарях чи лс.

Джерело: habr.com

Додати коментар або відгук