Add makefile and a way to easily overwrite configuration

parent af584e23
......@@ -18,5 +18,3 @@ _build
rebar3.crashdump
*~
config/prod*
config/proxy*
deploy/*.retry
INSTALL_BASE:=/opt
INSTALL_TO:=$(INSTALL_BASE)
REBAR3:=./rebar3
SERVICE:=/etc/systemd/system/mtproto-proxy.service
LOGDIR:=/var/log/mtproto-proxy
USER:=mtproto-proxy
all: config/prod-sys.config config/prod-vm.args
$(REBAR3) as prod release
config/prod-sys.config: config/sys.config.example
[ -f $@ ] && diff $^ $@ || true
cp -i -b $^ $@
config/prod-vm.args: config/vm.args.example
[ -f $@ ] && diff $^ $@ || true
cp -i -b $^ $@
$(LOGDIR):
mkdir -p $(LOGDIR)
chown $(USER) $(LOGDIR)
install: $(LOGDIR)
sudo useradd -r $(USER) || true
cp -n -r _build/prod/rel/mtp_proxy $(INSTALL_BASE)
mkdir -p $(INSTALL_BASE)/mtp_proxy/log
chmod 777 $(INSTALL_BASE)/mtp_proxy/log
cp -n config/mtproto-proxy.service $(SERVICE)
systemctl daemon-reload
uninstall:
# TODO: ensure service is stopped
rm $(SERVICE)
rm -r $(INSTALL_BASE)/mtp_proxy
systemctl daemon-reload
......@@ -15,10 +15,27 @@ Features
* Small codebase compared to oficial one
* A lots of metrics could be exported (optional)
How to start
------------
How to start - quick
--------------------
```
sudo apt install erlang-nox erlang-dev build-essential
git clone https://github.com/seriyps/mtproto_proxy.git
cd mtproto_proxy/
cp config/vm.args.example config/prod-vm.args
cp config/sys.config.example config/prod-sys.config
# configure your port, secret, ad_tag. See [Settings](#settings) below.
nano config/prod-sys.config
make && sudo make install
sudo systemctl enable mtproto-proxy
sudo systemctl start mtproto-proxy
```
How to start - detailed
--------------------
Install deps (ubuntu 18.04)
### Install deps (ubuntu 18.04)
```
sudo apt install erlang-nox erlang-dev build-essential
......@@ -28,68 +45,137 @@ You need Erlang version 20 or higher! If your version is older, please, check
[Erlang solutions esl-erlang package](https://www.erlang-solutions.com/resources/download.html)
or use [kerl](https://github.com/kerl/kerl).
Get the code:
### Get the code:
```
git clone https://github.com/seriyps/mtproto_proxy.git
cd mtproto_proxy/
```
Update settings (see [Settings](#settings)).
### Create config file
see [Settings](#settings).
Compile:
### Build and install
```
./rebar3 release
make && sudo make install
```
Make sure your limit of open files is high enough! Check `ulimit -n`.
You may need to tweak your `/etc/security/limits.conf` or systemd `LimitNOFILE`
to be able to handle more than ~500 clients.
This will:
* install proxy into `/opt/mtp_proxy`
* create a system user
* install systemd service
* create a directory for logs in `/var/log/mtproto-proxy`
* Configure ulimit of max open files and `CAP_NET_BIND_SERVICE` by systemd
Start with interactive console (recommended for testing)
### Start and enable start on system start-up
```
./_build/default/rel/mtp_proxy/bin/mtp_proxy console
sudo systemctl enable mtproto-proxy
sudo systemctl start mtproto-proxy
```
Or start in foreground (recommended for systemd service)
Done! Proxy is up and ready to serve now!
```
./_build/default/rel/mtp_proxy/bin/mtp_proxy foreground
```
### Stop / uninstall
Or start in background (to run as a service without supervision)
Stop:
```
./_build/default/rel/mtp_proxy/bin/mtp_proxy start
sudo systemctl stop mtproto-proxy
```
Stop proxy started in background
Uninstall:
```
./_build/default/rel/mtp_proxy/bin/mtp_proxy stop
sudo systemctl stop mtproto-proxy
sudo systemctl disable mtproto-proxy
sudo make uninstall
```
Logs can be found at
```
./_build/default/rel/mtp_proxy/log/
/var/log/mtproto-proxy/application.log
```
Settings
--------
See `src/mtproto_proxy.app.src`.
All possible documanted configuration options could be found
in `src/mtproto_proxy.app.src`. Do not edit this file!
To change configuration, edit `config/prod-sys.config`:
Comments in this file start from `%%`.
Default port is 1443 and default secret is `d0d6e111bada5511fcce9584deadbeef`.
Secret key and proxy URL will be printed on start.
Secret key will be printed on start.
The easiest way to update config right now is to edit `config/prod-sys.config`
and then re-install proxy by
```
sudo make uninstall && make && sudo make install
```
### Change default port / secret / ad tag
To change default settings, change `mtproto_proxy` section as:
```
{mtproto_proxy,
%% see src/mtproto_proxy.app.src for examples.
%% DO NOT EDIT src/mtproto_proxy.app.src!!!
[
{ports,
[#{name => mtp_handler1,
listen_ip => "0.0.0.0",
port => 1443,
secret => <<"d0d6e111bada5511fcce9584deadbeef">>,
tag => <<"dcbe8f1493fa4cd9ab300891c0b5b326">>}
]}
]},
{lager,
<...>
```
(so, remove `%%`s) and replace `port` / `secret` / `tag` with yours.
### Listen on multiple ports / IPs
You can start proxy on many IP addresses or ports with different secrets/ad tags.
To do so, just add more configs to `ports` section, separated by comma, eg:
```
{mtproto_proxy,
%% see src/mtproto_proxy.app.src for examples.
%% DO NOT EDIT src/mtproto_proxy.app.src!!!
[
{ports,
[#{name => mtp_handler_1,
listen_ip => "0.0.0.0",
port => 1443,
secret => <<"d0d6e111bada5511fcce9584deadbeef">>,
tag => <<"dcbe8f1493fa4cd9ab300891c0b5b326">>},
#{name => mtp_handler_2,
listen_ip => "0.0.0.0",
port => 2443,
secret => <<"100000000000000000000000000000001">>,
tag => <<"cf8e6baff125ed5f661a761e69567711">>}
]}
]},
{lager,
<...>
```
Each section should have unique `name`!
Helpers
-------
Number of connections in background mode
Number of connections
```
./_build/default/rel/mtp_proxy/bin/mtp_proxy eval 'lists:sum([proplists:get_value(all_connections, L) || {_, L} <- ranch:info()]).'
/opt/mtp_proxy/bin/mtp_proxy eval 'lists:sum([proplists:get_value(all_connections, L) || {_, L} <- ranch:info()]).'
```
[Unit]
SourcePath=/opt/mtp_proxy/bin/mtp_proxy
Description=Starts the mtproto_proxy server
After=local-fs.target
After=remote-fs.target
After=network-online.target
After=systemd-journald-dev-log.socket
After=nss-lookup.target
Wants=network-online.target
Requires=epmd.service
[Service]
Type=simple
User=mtproto-proxy
Group=mtproto-proxy
Environment="RUNNER_LOG_DIR=/var/log/mtproto-proxy"
Restart=on-failure
TimeoutSec=1min
IgnoreSIGPIPE=no
KillMode=process
GuessMainPID=no
RemainAfterExit=no
LimitNOFILE=40960
AmbientCapabilities=CAP_NET_BIND_SERVICE
ExecStart=/opt/mtp_proxy/bin/mtp_proxy foreground
ExecStop=/opt/mtp_proxy/bin/mtp_proxy stop
TimeoutStopSec=15s
\ No newline at end of file
%% -*- mode: erlang -*-
[
{mtproto_proxy,
%% see src/mtproto_proxy.app.src for examples.
%% DO NOT EDIT src/mtproto_proxy.app.src!!!
[
%% {ports,
%% [#{name => mtp_handler1,
%% listen_ip => "0.0.0.0",
%% port => 1443,
%% secret => <<"d0d6e111bada5511fcce9584deadbeef">>,
%% tag => <<"dcbe8f1493fa4cd9ab300891c0b5b326">>}
%% ]}
]},
%% Logging config
{lager,
[{log_root, "/var/log/mtproto-proxy"},
{crash_log, "crash.log"},
{handlers,
[
{lager_console_backend,
[{level, critical}]},
{lager_file_backend,
[{file, "application.log"},
{level, info},
%% Do fsync only on critical messages
{sync_on, critical},
%% If we logged more than X messages in a second, flush the rest
{high_water_mark, 300},
%% If we hit hwm and msg queue len is >X, flush the queue
{flush_queue, true},
{flush_threshold, 2000},
%% How often to check if log should be rotated
{check_interval, 5000},
%% Rotate when file size is 100MB+
{size, 104857600}
]}
]}]}
].
-sname mtproto_proxy
-setcookie mtproto-proxy-cookie
## this one is essential for >500 connections
+K true
\ No newline at end of file
......@@ -15,8 +15,15 @@
%% {sys_config, "./config/sys.config"},
%% {vm_args, "./config/vm.args"},
{dev_mode, false},
{include_erts, false},
{extended_start_script, true}]
}.
{profiles,
[{prod,
[{relx, [{dev_mode, false},
{sys_config, "./config/prod-sys.config"},
{vm_args, "./config/prod-vm.args"},
{include_erts, true}]}]
}]
}.
......@@ -31,13 +31,13 @@
%% Interface to listen for incoming connections
%% If not set, 0.0.0.0 will be used
{listen_ip, {0, 0, 0, 0}},
{listen_ip, "0.0.0.0"},
%% You can add as much as you want. Names and ports should be unique
{ports, [#{name => mtp_handler,
port => 1443,
%% You can tell it to listen on specific IP.
%% If not set, top-level listen_ip will be used.
%% listen_ip => {1, 2, 3, 4},
%% listen_ip => "1.2.3.4",
%% secret should be 32 hex chars [0-9a-f]
secret => <<"d0d6e111bada5511fcce9584deadbeef">>,
......
......@@ -31,9 +31,10 @@ stop(_State) ->
%% Internal functions
%%====================================================================
start_proxy(#{name := Name, port := Port, secret := Secret, tag := Tag} = P) ->
ListenIp = maps:get(
ListenIpStr = maps:get(
listen_ip, P,
application:get_env(?APP, listen_ip, {0, 0, 0, 0})),
application:get_env(?APP, listen_ip, "0.0.0.0")),
{ok, ListenIp} = inet:parse_ipv4_address(ListenIpStr),
NumAcceptors = application:get_env(?APP, num_acceptors, 60),
MaxConnections = application:get_env(?APP, max_connections, 10240),
Res =
......@@ -44,8 +45,12 @@ start_proxy(#{name := Name, port := Port, secret := Secret, tag := Tag} = P) ->
{num_acceptors, NumAcceptors},
{max_connections, MaxConnections}],
mtp_handler, [Secret, Tag]),
io:format("Proxy started on ~s:~p with secret: ~s~n",
[inet:ntoa(ListenIp), Port, Secret]),
Url = io_lib:format(
"https://t.me/proxy?server=~s&port=~w&secret=~s",
[application:get_env(?APP, external_ip, ListenIpStr),
Port, Secret]),
io:format("Proxy started on ~s:~p with secret: ~s, tag: ~s~nUrl: ~s~n",
[ListenIpStr, Port, Secret, Tag, Url]),
Res.
stop_proxy(#{name := Name}) ->
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment