7.9 KiB
title: "Set up UnifiedPush with Matrix support in Gentoo" slug: "set-up-unifiedpush-with-Matrix-support-in-gentoo" description: null date: 2021-09-10T14:49:16+02:00 type: posts draft: false tags: - UnifiedPush - nginx - Matrix - Gentoo toc: true ---
I set up UnifiedPush because I wanted push notifications in FluffyChat without talking to Google. This was a bit more difficult than I imagined, so I’m writing it down here. I will go into Gentoo specifics but a lot of this article should be useful for other Linux distributions and operating systems as well.
UnifiedPush works like this: You have a server and a notification-application on your phone. The notification-application connects to the server and receives push notifications from it. Other applications talk with the notification-application and get the notifications. At least that is how I understand it.
Install and configure the server
You can install www-apps/gotify-server-bin from ::tastytea or download the binary or use docker.
sudo eselect repository enable tastytea
sudo emaint sync -r tastytea
echo -e "www-apps/gotify-server-bin\n acct-user/gotify\n acct-group/gotify" \
| sudo tee /etc/portage/package.accept_keywords/gotify
sudo emerge -a www-apps/gotify-server-bin
Put config.yml
into /etc/gotify/
and edit it. I will assume that you changed
listenaddr
to [::1]
and port
to 7777
. An example config.yml
is in
/usr/share/doc/gotify-server-bin-*/config.example.yml.bz2
and in
the upstream repository. Now start the server.
sudo rc-service gotify-server-bin start
sudo rc-update add gotify-server-bin
Note
|
If you do not use the OpenRC init script or docker, be aware that the Gotify
server creates and uses a directory called data/ in its current path.
|
Configure nginx
You will need the lua module for nginx and lua-cjson. I will not cover TLS certificates here, there are many good guides about that already.
echo "www-servers/nginx NGINX_MODULES: http_lua" | sudo tee /etc/portage/package.use/gotify
echo "dev-lua/lua-cjson" | sudo tee -a /etc/portage/package.accept_keywords/gotify
sudo emerge -a1 www-servers/nginx
sudo emerge -a dev-lua/lua-cjson
sudo rc-service nginx restart
You may have to tell nginx its lua module where to find lua-cjson. In my case I
had to add lua_package_cpath "/usr/share/lua/5.1/?.so;;";
above the server
block. The ;;
means that the previous value of lua_package_cpath
should be
appended.
Copy the configuration example, edit server_name
, change
listen 80;
to listen [::]:443 ssl;
and listen 443 ssl;
and change
proxy_pass
to http://[::1]:7777
. You don’t need the upstream
bit.
Copy the configuration example for UnifiedPush into your
server
block and change proxy_pass
to http://[::1]:7777/message
.
Copy the configuration example for Matrix into your
server
block and change relay.example.tld
to your server_name
.
lua_package_cpath "/usr/share/lua/5.1/?.so;;";
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name push.example.org;
# access_log /var/log/nginx/push.example.org_log main;
error_log /var/log/nginx/push.example.org_log warn;
ssl_certificate /var/lib/dehydrated/certs/push.example.org/fullchain.pem;
ssl_certificate_key /var/lib/dehydrated/certs/push.example.org/privkey.pem;
location / {
proxy_pass http://[::1]:7777;
proxy_http_version 1.1;
# Ensuring it can use websockets
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
proxy_redirect http:// $scheme://;
# The proxy must preserve the host because gotify verifies the host with the origin
# for WebSocket connections
proxy_set_header Host $http_host;
# These sets the timeout so that the websocket can stay alive
proxy_connect_timeout 1m;
proxy_send_timeout 1m;
proxy_read_timeout 1m;
}
location /UP {
access_by_lua_block{
local json=require("cjson")
ngx.req.read_body()
local req = ngx.req.get_body_data()
local newreq = { ["message"] = req }
local body = json.encode(newreq)
ngx.req.set_body_data(body)
}
proxy_set_header Content-Type application/json;
proxy_pass http://[::1]:7777/message;
proxy_set_header Host $host;
}
location /_matrix/push/v1/notify {
set $target '';
if ($request_method = GET ) {
return 200 '{"gateway":"matrix","unifiedpush":{"gateway":"matrix"}}';
}
access_by_lua_block {
local cjson = require("cjson")
ngx.req.read_body()
local body = ngx.req.get_body_data()
local parsedBody = cjson.decode(body)
local accepted = "https://push.example.org/"
ngx.var.target = parsedBody["notification"]["devices"][1]["pushkey"]
ngx.req.set_body_data(body)
if(string.sub(ngx.var.target,1,string.len(accepted))~=accepted) then ngx.var.target="http://0.0.0.0/"
end
}
proxy_set_header Content-Type application/json;
proxy_set_header Host $host;
proxy_pass $target;
}
}
Reload nginx and change the admin password in the web interface.
Use UnifiedPush
Log into your Gotify server and add a new user. Install the Android application. Make sure you install “Gotify-UP” and not “Gotify”. Open Gotify-UP and register with your server. Applications supporting UnifiedPush should now register themselves on your server and show up in the “Apps” tab. You may have to restart the application first. Have a look at the readme of the upstream repository for help with disabling battery optimization and constant foreground notification.