Hello, Habr!
Recently, I found myself in a situation where I had to work inside a corporate network with limited internet access, and as you might guess from the title — Telegram was blocked there. I'm sure many people are familiar with this situation.
I can get by without messengers, but I specifically needed Telegram for work. Installing a client on the work machine was not possible, and using a personal laptop was not an option either. Another solution seemed to be using its , but as you might guess — that was also unavailable. I immediately ruled out the option of looking for an unofficial mirror (for quite obvious reasons).
Fortunately, Webogram is an open-source project, and its source code is available in its author's repository (Many thanks to him!)
The installation and launch itself is not complicated, but under conditions of operation within a network with blocked access to Telegram servers, you are more likely to face disappointment than success, as the web version sends requests to Telegram servers from the user's machine.
Fortunately, this can be quite straightforward (though not very obvious) to fix. I want to warn you that I am not the author of this solution. I was able to find it in , where a problem similar to mine was discussed. The solution that the user github proposed helped me a lot, but I am sure it can help someone else as well, which is why I decided to write this tutorial.
Below you will find a step-by-step guide for setting up your Webogram mirror and configuring its requests to Telegram servers using nginx.
As an example, I've chosen a freshly installed and updated Ubuntu Server 18.04.3.
Attention: This tutorial will not include instructions for configuring the domain in nginx. This needs to be done independently. The tutorial assumes that you already have a domain set up with SSL, and the server on which the setup is planned has access to Telegram servers (by any means of your choice).
Let's assume that the IP of this server is 10.23.0.3, and the domain name is mywebogram.localhost.
Based on these conditions, I will provide configuration examples. Don't forget to replace the values with your own.
So, let's get started:
To run Webogram, we need nodejs. By default, if we install it from the Ubuntu repositories, we will get nodejs version 8.x. We need version 12.x:
curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
sudo apt update && sudo apt -y install nodejsWe choose the location 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.gitThe next step is to install all dependencies required to run the application:
cd webogram && npm installLet's try to perform a test run. Execute the command:
npm startAfter that, we try to open in the browser
http://10.23.0.3:8000/app/index.htmlIf you did everything correctly up to this point, you will see the Webogram login page.
Now we need to configure the application to run as a service. To do this, we create a file
sudo touch /lib/systemd/system/webogram.serviceopen it in any editor and set it to look like this (insert your path to 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
After that, we execute the following commands:
Apply the changes
sudo systemctl daemon-reloadEnable auto-start:
sudo systemctl enable webogram.serviceStarting the service:
sudo systemctl start webogram.serviceAfter performing these 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 external requests.
We will use the udf utility (or any convenient method for you):
sudo ufw deny 8000In case you decided to use udf but it's turned off on the server — let's add some more rules (so it doesn't fall apart) and enable udf:
sudo ufw allow ssh
sudo ufw allow 80
sudo ufw allow 443
sudo ufw enableNext, we will proceed to change the nginx configuration.
As I warned above — it is assumed that your server already has a domain set up with ssl. I would like to point out that you will need to add to the domain configuration file for proper 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 we are adding to the nginx config:
- We modify the root location, which will proxy requests to port 8000, where Webogram responds.
- We secure the root location with basic authentication. This is merely a symbolic step to protect our application from prying eyes and bots. (And also to avoid blocking issues)
- A bunch of locations with proxy_pass to the Telegram servers are our endpoints through which we will proxy our requests.
We will also create a file /etc/nginx/passwd.htpasswd;, so nginx can verify user passwords.
sudo apt install apache2-utils
sudo htpasswd -c /etc/nginx/passwd.htpasswd tg 
We restart nginx:
sudo systemctl restart nginxNow Webogram will be available only at after entering the username and password that you defined when creating the htpasswd command.
There’s a little more to do: we will make some small changes to the project itself.
Open the file in your editor ~/webogram/app/js/lib/mtproto.js
And modify its beginning to look like this:
/*!
* Webogram v0.7.0 - messaging web application for MTProto
* https://github.com/zhukov/webogram
* Copyright (C) 2014 Igor Zhukov <igor.beatle@gmail.com>
* 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, it is necessary to refresh the application page in your browser.
Open the browser console and observe the network requests of the application. If everything works and the XHR requests go to your server — it means everything is done correctly, and Webogram is now proxied through nginx.

I hope this tutorial will be useful to someone other than me.
Thank you very much to everyone who read to the end.
If anyone has any difficulties or I've made any inaccuracies—I'm happy to respond and will try to help you in the comments or DMs.
Source: habr.com
