Setup of an Etesync Server on Fedora 37
Etesync is a server-client system that allows syncing contact and calendar data in an end-to-end-encrypted (E2EE) fashion. This way you don't need to trust the server administrator and his ability to protect your data from himself, hackers, or other entities. Note that data is mostly securely transmitted via TLS/HTTPS between client and server nowadays. But with only client-server encryption you would still need to trust certain entities, which is not 100 percent security. E2EE gives you that 100 percent.
This concludes that with E2EE all you need is an open source client. You then can choose any service provider, and don't need to select carefully, or don't need to set up your own server. As explained, by using an open source E2EE client you don't need to trust the server (apart for some meta data for synchronisation that needs to stay unencrypted). But if you choose to set up your own server anyways, here is the step-by-step manual.
Wording in this tutorial
string |
meaning |
---|---|
foo.net |
domain |
xxxxxxxxx |
any string |
xx.xx.xxx.xx |
IPv4 address |
xxxx:xxx:xxxx:xxxx::1 |
IPv6 address |
Etebase
# Create user sudo useradd etebase sudo passwd etebase # Dependencies sudo dnf install python3-devel # Tools sudo dnf install argon2 # Download mkdir srv cd srv git clone https://github.com/etesync/server.git etebase # Virtual Environment sudo su etebase mkdir ~/pyenv python -m venv ~/pyenv/etebase source ~/pyenv/etebase/bin/activate pip install pip --upgrade # Patch requirements.txt # Only for Fedora 37/Python 3.11. Reason: Older versions of those packages # throw compile errors during PIP installation. sed -i 's/^uvloop==0.16.0$/uvloop==0.17.0/g' ~/srv/etebase/requirements.txt sed -i 's/^httptools==0.4.0$/httptools==0.5.0/g' ~/srv/etebase/requirements.txt sed -i 's/^cffi==1.15.0$/cffi==1.15.1/g' ~/srv/etebase/requirements.txt # Would cause an error when starting server. sed -i 's/^pydantic==1.9.0$/pydantic==1.10.2/g' ~/srv/etebase/requirements.txt # Install cd ~/srv/etebase pip install -r requirements.txt # Configure cp etebase-server.ini.example etebase-server.ini # (Exit etebase user and go back to normal user.) exit sudo mkdir -p /var/www/etebase/ sudo chown etebase /var/www/etebase/ sudo chgrp etebase /var/www/etebase/ sudo su etebase mkdir /var/www/etebase/static mkdir /var/www/etebase/media sed -i 's/^static_root = .*$/static_root = \/var\/www\/etebase\/static/g' etebase-server.ini sed -i 's/^media_root = .*$/media_root = \/var\/www\/etebase\/media/g' etebase-server.ini date +%s | argon2 udita-%a3ra -id -r > secret.txt sed -i s/^allowed_host1 = .*$/allowed_host1 = pim.foo.net/g etebase-server.ini
Firewall
Start it up:
sudo su etebase cd ~/srv/etebase/ source ~/pyenv/etebase/bin/activate uvicorn etebase_server.asgi:application --port 8000 --host 0.0.0.0
Visit http://xx.xx.xxx.xx:8000/
. It should say "It works!".
Nginx
[https://github.com/etesync/server/wiki/Production-setup-using-Nginx]
# Install sudo dnf install nginx # To have the server start at each boot: sudo systemctl enable nginx.service # To start the web server now: sudo systemctl start nginx.service # Prepare Django instance: ./manage.py collectstatic
Create sudo nvim /etc/nginx/conf.d/pim.foo.net.conf
(don't omit the
.conf
ending!), and edit:
server_name
client_max_body_size
alias
oflocation /static/
=> Full sudo nvim /etc/nginx/conf.d/pim.foo.net.conf
:
# the upstream component that nginx needs to connect to upstream etebase { # server unix:///var/sockets/etebase_server.sock; # for a file socket server 127.0.0.1:8001; # for a web port socket (we'll use this first) } # configuration of the server server { # the port your site will be served on listen 8000; # the domain name it will serve for server_name 65.21.187.48 pim.foo.net; # substitute your machine's IP address or domain name charset utf-8; # max upload size client_max_body_size 200M; # adjust to taste location /static { # /static not /static/ alias /var/www/etebase/static; # Project's static files } location / { proxy_pass http://etebase; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Host $server_name; } }
# Test sudo nginx -t # Restart sudo systemctl restart nginx # Start Gateway to Django instance sudo su etebase cd ~/srv/etebase/ source ~/pyenv/etebase/bin/activate uvicorn etebase_server.asgi:application --port 8001 --host 0.0.0.0 # (Test both IP address and domain in web browser.) # Change configuration to file socket
Nginx via file socket
Prepare directory for socket files (standart is /tmp
, which cannot be read
by nginx
user, if created by etebase
user!
[https://stackoverflow.com/a/22277617])
Change sudo nvim /etc/nginx/conf.d/pim.foo.net.conf
:
Run Uvicorn at boot
Test manually step in [Service]
(becoming sudo su etebase
, switching
dir, starting up)! Here may be errors difficult to find later.
sudo nvim /etc/systemd/system/etebase_server.service
:
[Unit] Description=Execute the etebase server. [Service] User=etebase WorkingDirectory=/home/etebase/srv/etebase/ ExecStart=/home/etebase/pyenv/etebase/bin/uvicorn etebase_server.asgi:application --uds /var/sockets/etebase_server.sock [Install] WantedBy=multi-user.target
sudo systemctl start etebase_server sudo systemctl enable etebase_server # After editing, a reload is necessary (restart not sufficient): sudo systemctl daemon-reload
Check on http://pim.foo.net:8000/
, it should show the "It works" message.
HTTPS
[https://github.com/etesync/server/wiki/Setup-HTTPS-for-Etebase]
# Install certificates sudo dnf install certbot sudo dnf install python3-certbot-nginx sudo ufw allow 80/tcp sudo certbot --nginx sudo ufw delete allow 80/tcp sudo ufw reload sudo ufw status # Firewall sudo ufw allow 443/tcp sudo ufw reload # Port 8000 not needed anymore sudo ufw delete allow 8000/tcp sudo ufw reload sudo ufw status
Go to https://pim.foo.net/
and check if "It works!" is shown.
Administration
Create a superuser with ./manage.py createsuperuser
.
Login at https://pim.foo.net/admin
Create a user, e.g. xxxxxxxxx
.
Go to the mobile phone app, choose "login", enter xxxxxxxxx
as username,
the password, and https://pim.foo.net/
as the server. You should be
logged in now.