We raise our Webogram instance with proxying through nginx

Hey Habr!

Recently, I got into a situation in which it was necessary to work inside a corporate network with incomplete access to the Internet and, as you can guess from the title, Telegram was blocked in it. I am sure that this situation is familiar to many.

I can do without instant messengers, but it was Telegram that I needed for work. It was not possible to install the client on a working machine, and it was also impossible to use a personal laptop. Another solution seems to be to use it official web version, but as you can guess - it was also unavailable. I immediately cross out the option of finding an unofficial mirror (I hope for quite obvious reasons).

Fortunately, Webogram is an open source project, the source code of which is available in github its author (For which many thanks to him!)
The installation and launch itself is not difficult, however, in operating conditions within a network with blocked access to Telegram servers, you will be more likely to be disappointed than successful, since the web version sends requests to Telegram servers from the user's machine.

Fortunately, this is a fairly simple (but not very obvious) fix. I want to warn you that I am not the author of this decision. I managed to find it in branch, which discussed a problem similar to mine. Solution suggested by github user tecknojock, it helped me a lot, however, I'm sure that it can help someone else, so I decided to write this tutorial.

Under the cut, you will find a step-by-step setup of your Webogram mirror and setting up proxying of its requests to Telegram servers using nginx.

As an example, I chose a freshly installed and updated Ubuntu Server 18.04.3.

Attention: Within this tutorial, there will be no instructions for setting up a domain in nginx. This must be done on your own. The tutorial assumes that you have already configured a domain with ssl, as well as the server itself, on which the configuration is planned, has access to the Telegram servers (in any way you like)

Let's assume that the ip of this server is 10.23.0.3, and the domain name is mywebogram.localhost

Based on these conventions, I will give examples of configurations. Don't forget to change the values ​​to your own.

So, let's start:

To run Webogram, we need nodejs. By default, if you install it from the Ubuntu repositories, we will get nodejs version 8.x. We need 12.x:

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

We choose the place where our Webogram will be based.

For example, let's place it in the root of the home directory. To do this, we clone the official repository to our server:

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

The next step is to install all the dependencies required to run the application:

cd webogram && npm install

Let's try a test run. Run the command:

npm start

After that, try to open in the browser

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

If you have done everything correctly up to this point, the Webogram authorization page will open.

Now we need to configure the application to run as a service. To do this, let's create a file

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

open it in any editor and give it the following look (enter your path to the 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

Then we execute the following commands:

Applying Changes

sudo systemctl daemon-reload

Enable autorun:

sudo systemctl enable webogram.service

We start the service:

sudo systemctl start webogram.service

After the completed actions, Webogram will continue to be available on port 8000.

Since we will configure access to our Webogram through nginx, we will close port 8000 for requests from outside.

We use the udf utility for this (or any method convenient for you):

sudo ufw deny 8000

In case you still decide to use udf, but it is disabled on the server, add more rules (so that everything does not fall apart) and enable udf:

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

Next, let's start changing the nginx configuration.

As I warned above, it is assumed that a domain with ssl is already configured on your server. I will only draw your attention to what will need to be added to the domain configuration file for correct operation:


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;
  }
}

What do we add to the nginx config:

  • We change the root location, which will proxy requests to port 8000, on which Webogram responds
  • We close the root location with basic-auth. This is a purely symbolic step to close our application from prying eyes and bots. (And also so that there are no problems with locks)
  • A bunch of locations with proxy_path on the Telegram servers are just our endpoints through which we will proxy our requests

Also, let's create a file /etc/nginx/passwd.htpasswd;so that nginx has something to check user passwords with.

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

We raise our Webogram instance with proxying through nginx

Restart nginx:

sudo systemctl restart nginx

Now Webogram will be available only at mywebogram.localhost/app/index.html after the username and password that you specified when creating the htpasswd command are entered.

There is not much left: we will make small changes to the project itself.

Open the file in the editor ~/webogram/app/js/lib/mtproto.js

And make it look like this:

/*!
 * 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
      }
...
 

After that, you need to refresh the page with the application in the browser.

Open the browser console and look at the application's network requests. If everything works, and XHR requests go to your server, then everything is done correctly, and Webogram is now proxied through nginx.

We raise our Webogram instance with proxying through nginx

I hope that this tutorial will be useful to someone else besides me.

Many thanks to everyone who read to the end.

If someone has any difficulties or I made some inaccuracies, I will answer with pleasure and try to help you in the comments or PM.

Source: habr.com

Add a comment