# Pantalaimon Setup Guide for Ement.el A comprehensive guide to setting up Pantalaimon, an E2EE-aware Matrix reverse proxy, for use with Ement.el in GNU Emacs. ## Table of Contents 1. [Overview](#overview) 2. [How It Works](#how-it-works) 3. [Prerequisites](#prerequisites) 4. [Installation](#installation) - [Fedora/RHEL](#fedorarhel) - [Debian/Ubuntu](#debianubuntu) - [Arch Linux](#arch-linux) - [macOS](#macos) - [From Source](#from-source-pip) - [Docker](#docker) 5. [Configuration](#configuration) 6. [Running Pantalaimon](#running-pantalaimon) 7. [Connecting Ement.el](#connecting-ementel) 8. [Device Verification](#device-verification) 9. [Importing Existing Keys](#importing-existing-keys) 10. [Systemd Service](#systemd-service-linux) 11. [Troubleshooting](#troubleshooting) 12. [Security Considerations](#security-considerations) 13. [Configuration Reference](#configuration-reference) --- ## Overview **Pantalaimon** is an E2EE (End-to-End Encryption) aware reverse proxy daemon for Matrix clients. Since Ement.el doesn't support Matrix encryption natively, Pantalaimon acts as a "good man in the middle" that transparently handles all encryption and decryption on behalf of your client. ``` ┌─────────────┐ plaintext ┌──────────────────┐ encrypted ┌────────────────┐ │ Ement.el │ ◄─────────────────► │ Pantalaimon │ ◄──────────────────► │ Homeserver │ │ (client) │ localhost:8009 │ (E2EE proxy) │ matrix.org:443 │ (Matrix) │ └─────────────┘ └──────────────────┘ └────────────────┘ ``` ### Key Features - Transparent encryption/decryption of messages - Device verification via `panctl` CLI tool - Support for multiple Matrix accounts - Key import/export for accessing message history - OS keyring integration for secure token storage --- ## How It Works 1. **You configure Pantalaimon** with your homeserver URL (e.g., `https://matrix.org`) 2. **Pantalaimon listens** on a local port (e.g., `localhost:8009`) 3. **Your client connects** to Pantalaimon instead of the homeserver directly 4. **Pantalaimon handles** all Olm/Megolm encryption operations 5. **Your client sees** decrypted messages as if encryption didn't exist --- ## Prerequisites ### Required - **libolm 3.1+** - The Olm cryptographic library - **Python 3.8+** - Pantalaimon is written in Python - **D-Bus** - For the control interface and notifications (Linux) - **A keyring service** - For secure token storage (recommended) ### Recommended - **gnome-keyring** or **kwallet** - OS keyring for token storage - **An already-verified Matrix client** - Element Desktop/Mobile for initial verification --- ## Installation ### Fedora/RHEL ```bash # Install dependencies sudo dnf install libolm libolm-devel python3-dbus gnome-keyring # Install pantalaimon via pip pip install --user pantalaimon[ui] # Or for Fedora Silverblue (toolbox/distrobox) toolbox enter sudo dnf install libolm libolm-devel python3-dbus gnome-keyring python3-pip pip install pantalaimon[ui] ``` ### Debian/Ubuntu ```bash # Install dependencies sudo apt update sudo apt install libolm3 libolm-dev python3-dbus gnome-keyring python3-pip # Install pantalaimon pip install --user pantalaimon[ui] # Add to PATH if needed echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc source ~/.bashrc ``` ### Arch Linux ```bash # Install from AUR (recommended) yay -S pantalaimon # Or from official repos + pip sudo pacman -S libolm python-dbus gnome-keyring pip install --user pantalaimon[ui] ``` ### macOS macOS requires additional setup for D-Bus: ```bash # Install Homebrew dependencies brew install dbus libolm # Configure D-Bus (required one-time setup) perl -pi -e's#(EXTERNAL)##' \ $(brew --prefix dbus)/share/dbus-1/session.conf brew services start dbus # You may need to restart your Mac for D-Bus to work properly # Set D-Bus environment variable (add to ~/.zshrc or ~/.bash_profile) export DBUS_SESSION_BUS_ADDRESS="unix:path=$(launchctl getenv DBUS_LAUNCHD_SESSION_BUS_SOCKET)" # Install pantalaimon pip3 install pantalaimon[ui] ``` ### From Source (pip) ```bash # Ensure libolm is installed first (see distro-specific instructions above) # Create a virtual environment (recommended) python3 -m venv ~/.local/share/pantalaimon-venv source ~/.local/share/pantalaimon-venv/bin/activate # Install pantalaimon with UI support pip install pantalaimon[ui] # The [ui] extra includes panctl and D-Bus notification support ``` ### Docker ```bash # Build the image docker build -t pantalaimon https://github.com/matrix-org/pantalaimon.git#master # Create config directory mkdir -p ~/.config/pantalaimon # Create configuration file (see Configuration section below) cat > ~/.config/pantalaimon/pantalaimon.conf << 'EOF' [Default] LogLevel = Debug [local-matrix] Homeserver = https://matrix.org ListenAddress = 0.0.0.0 ListenPort = 8009 SSL = False UseKeyring = False IgnoreVerification = True EOF # Run the container docker run -it --rm \ -v ~/.config/pantalaimon:/data \ -p 8009:8009 \ pantalaimon ``` --- ## Configuration Create the configuration file at `~/.config/pantalaimon/pantalaimon.conf`: ### Basic Configuration (matrix.org) ```ini [Default] LogLevel = Warning Notifications = On [matrix-org] Homeserver = https://matrix.org ListenAddress = localhost ListenPort = 8009 ``` ### Configuration for Custom Homeserver ```ini [Default] LogLevel = Warning Notifications = On [my-server] Homeserver = https://matrix.example.com ListenAddress = localhost ListenPort = 8009 SSL = True ``` ### Multiple Homeservers Each homeserver needs a unique port: ```ini [Default] LogLevel = Warning [matrix-org] Homeserver = https://matrix.org ListenAddress = localhost ListenPort = 8009 [my-work-server] Homeserver = https://matrix.work.example.com ListenAddress = localhost ListenPort = 8010 [my-home-server] Homeserver = https://matrix.home.example.net ListenAddress = localhost ListenPort = 8011 ``` ### Headless/Server Configuration (No Keyring) For servers or systems without a keyring: ```ini [Default] LogLevel = Info [matrix-org] Homeserver = https://matrix.org ListenAddress = localhost ListenPort = 8009 UseKeyring = No IgnoreVerification = True ``` **Warning:** With `UseKeyring = No`, access tokens are stored in plaintext in the database. Your client will need to re-authenticate if Pantalaimon restarts. --- ## Running Pantalaimon ### Manual Start ```bash # Start with default config location pantalaimon # Start with custom config pantalaimon -c /path/to/pantalaimon.conf # Start with debug logging pantalaimon --log-level debug # Start with custom data directory pantalaimon --data-path ~/.local/share/pantalaimon ``` ### Verify It's Running ```bash # Check if pantalaimon is listening curl -s http://localhost:8009/_matrix/client/versions | head -5 # Should output something like: # {"versions":["r0.0.1","r0.1.0",...]} ``` --- ## Connecting Ement.el Once Pantalaimon is running, configure Ement.el to connect through it: ### Method 1: Interactive Connection ```elisp ;; In Emacs, run: M-x ement-connect ;; When prompted for the server, enter: ;; http://localhost:8009 ;; ;; Use your normal Matrix credentials (@user:matrix.org, password) ``` ### Method 2: Elisp Configuration Add to your Emacs config: ```elisp ;; Connect to Matrix through Pantalaimon (defun my/ement-connect-pantalaimon () "Connect to Matrix via Pantalaimon proxy." (interactive) (ement-connect :uri-prefix "http://localhost:8009")) ;; Or set as default (setq ement-default-uri-prefix "http://localhost:8009") ``` ### Method 3: use-package Configuration ```elisp (use-package ement :ensure t :config ;; Always connect through Pantalaimon (setq ement-default-uri-prefix "http://localhost:8009") ;; Optional: Custom connection function (defun my/ement-connect-encrypted () "Connect to Matrix with E2EE via Pantalaimon." (interactive) (ement-connect :uri-prefix "http://localhost:8009"))) ``` ### First Login 1. Start Pantalaimon 2. Run `M-x ement-connect` in Emacs 3. Enter `http://localhost:8009` as the server 4. Login with your Matrix credentials 5. **At this point, encrypted messages won't be readable yet** - this is expected! --- ## Device Verification After connecting, you need to verify the Pantalaimon session to receive encryption keys. ### Using panctl (Recommended) `panctl` is an interactive CLI for managing Pantalaimon: ```bash # Start panctl panctl # You'll see a prompt: panctl> ``` ### List Available Commands ``` panctl> help Available commands: list-servers List connected servers list-users List users on a server list-devices List devices for a user start-verification Start device verification accept-verification Accept verification confirm-verification Confirm SAS verification cancel-verification Cancel verification import-keys Import E2E room keys export-keys Export E2E room keys ``` ### View Your Devices ``` panctl> list-devices @yourusername:matrix.org Devices for user @yourusername:matrix.org: - Display name: Element Desktop (Linux) Device id: ABCD1234 Device key: [key] Trust state: Verified - Display name: pantalaimon Device id: EFGH5678 Device key: [key] Trust state: Unverified ``` ### Start Verification You'll need another verified device (like Element on your phone or desktop): ``` panctl> start-verification @yourusername:matrix.org ABCD1234 ``` Where `ABCD1234` is the device ID of your **already verified** Element client. ### Complete Verification 1. **In Element:** You'll receive a verification request - accept it 2. **Compare emojis:** Both Element and panctl will show emoji sequences 3. **In panctl:** If emojis match, confirm: ``` panctl> confirm-verification @yourusername:matrix.org ABCD1234 ``` 4. **In Element:** Confirm the verification on that side too ### Alternative: Verify via Element You can also verify from Element's side: 1. Open Element Desktop/Mobile 2. Go to Settings → Security & Privacy → Sessions 3. Find "pantalaimon" in the session list 4. Click "Verify" and follow the prompts --- ## Importing Existing Keys To read **historical** encrypted messages, you need to import your room keys: ### Export Keys from Element 1. Open Element Desktop 2. Go to **Settings → Security & Privacy** 3. Click **"Export E2E room keys"** 4. Set a strong passphrase 5. Save the file (e.g., `element-keys.txt`) ### Import Keys into Pantalaimon ```bash panctl panctl> import-keys @yourusername:matrix.org /path/to/element-keys.txt # Enter the passphrase when prompted ``` You should see: ``` INFO: pantalaimon: Successfully imported keys for @yourusername:matrix.org from /path/to/element-keys.txt ``` ### Restart Ement.el After importing keys: 1. Disconnect from Ement: `M-x ement-disconnect` 2. Reconnect: `M-x ement-connect` 3. Historical encrypted messages should now be visible ### Clean Up **Delete the exported key file** after importing - it contains sensitive cryptographic material: ```bash rm /path/to/element-keys.txt ``` --- ## Systemd Service (Linux) Create a user systemd service for automatic startup: ### Create Service File ```bash mkdir -p ~/.config/systemd/user cat > ~/.config/systemd/user/pantalaimon.service << 'EOF' [Unit] Description=Pantalaimon Matrix E2EE Proxy After=network.target [Service] Type=simple ExecStart=%h/.local/bin/pantalaimon Restart=on-failure RestartSec=5 # If using a virtual environment: # ExecStart=%h/.local/share/pantalaimon-venv/bin/pantalaimon [Install] WantedBy=default.target EOF ``` ### Enable and Start ```bash # Reload systemd systemctl --user daemon-reload # Enable on login systemctl --user enable pantalaimon # Start now systemctl --user start pantalaimon # Check status systemctl --user status pantalaimon # View logs journalctl --user -u pantalaimon -f ``` ### Auto-start on Boot (Without Login) ```bash # Enable lingering for your user sudo loginctl enable-linger $USER ``` --- ## Troubleshooting ### "Unable to decrypt" after connecting **Cause:** Pantalaimon session not verified, or keys not imported. **Solution:** 1. Verify the pantalaimon device (see [Device Verification](#device-verification)) 2. Import your existing keys (see [Importing Existing Keys](#importing-existing-keys)) ### "Connection refused" on localhost:8009 **Cause:** Pantalaimon not running. **Solution:** ```bash # Check if running pgrep -a pantalaimon # Start it pantalaimon # Check for errors pantalaimon --log-level debug ``` ### "M_UNKNOWN_TOKEN" or authentication errors **Cause:** Access token expired or invalid. **Solution:** ```bash # Clear Pantalaimon's data and re-authenticate rm -rf ~/.local/share/pantalaimon pantalaimon # Restart # Then re-login via Ement.el ``` ### D-Bus errors on Linux **Cause:** D-Bus session not running or not accessible. **Solution:** ```bash # Check D-Bus echo $DBUS_SESSION_BUS_ADDRESS # If empty, ensure your session manager starts D-Bus # For systemd users: systemctl --user start dbus # Or set manually: export DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/$(id -u)/bus" ``` ### Keyring errors **Cause:** No keyring service available. **Solution:** ```bash # Install gnome-keyring sudo dnf install gnome-keyring # Fedora sudo apt install gnome-keyring # Debian/Ubuntu # Or disable keyring in config: # UseKeyring = No ``` ### Messages decrypt but then become unreadable **Cause:** Key rotation or session issues. **Solution:** 1. Re-export and re-import keys from Element 2. Restart Pantalaimon 3. Reconnect Ement.el ### panctl won't connect **Cause:** D-Bus not working or Pantalaimon not exposing D-Bus interface. **Solution:** ```bash # Ensure Pantalaimon was installed with UI support pip install pantalaimon[ui] # Check D-Bus is running dbus-daemon --session --print-address ``` --- ## Security Considerations ### Network Security - Pantalaimon listens on `localhost` by default - **keep it that way** - The connection between your client and Pantalaimon is **unencrypted** - Never expose Pantalaimon to the network without TLS ### Data Storage | Data | Location | Protection | |------|----------|------------| | Config | `~/.config/pantalaimon/` | File permissions | | Database | `~/.local/share/pantalaimon/` | Contains encryption keys! | | Access tokens | OS keyring or database | Depends on `UseKeyring` | ### Recommendations 1. **Use keyring:** Keep `UseKeyring = Yes` when possible 2. **Protect the data directory:** `chmod 700 ~/.local/share/pantalaimon` 3. **Run as your user:** Never run Pantalaimon as root 4. **Keep updated:** `pip install --upgrade pantalaimon` --- ## Configuration Reference ### [Default] Section | Key | Default | Description | |-----|---------|-------------| | `LogLevel` | `Warning` | `Error`, `Warning`, `Info`, `Debug` | | `Notifications` | `On` | Enable OS notifications | | `SSL` | `True` | Verify TLS certificates | ### [server-name] Sections | Key | Required | Default | Description | |-----|----------|---------|-------------| | `Homeserver` | **Yes** | - | Matrix server URL (e.g., `https://matrix.org`) | | `ListenAddress` | No | `localhost` | Address to bind | | `ListenPort` | No | `8009` | Port to listen on | | `Proxy` | No | - | HTTP proxy for outgoing connections | | `SSL` | No | `True` | Verify homeserver TLS | | `IgnoreVerification` | No | `False` | Skip device verification warnings | | `UseKeyring` | No | `Yes` | Store tokens in OS keyring | | `DropOldKeys` | No | `No` | Only keep latest room keys (saves space, loses history) | ### Example Complete Configuration ```ini [Default] LogLevel = Info Notifications = On SSL = True [matrix-org] Homeserver = https://matrix.org ListenAddress = localhost ListenPort = 8009 UseKeyring = Yes IgnoreVerification = False [work-server] Homeserver = https://matrix.work.example.com ListenAddress = localhost ListenPort = 8010 UseKeyring = Yes # Use corporate proxy Proxy = http://proxy.work.example.com:8080 ``` --- ## Quick Start Checklist - [ ] Install libolm and dependencies - [ ] Install pantalaimon: `pip install pantalaimon[ui]` - [ ] Create config: `~/.config/pantalaimon/pantalaimon.conf` - [ ] Start pantalaimon: `pantalaimon` - [ ] Connect Ement.el to `http://localhost:8009` - [ ] Verify device via panctl or Element - [ ] Import existing keys (optional, for history) - [ ] Set up systemd service (optional, for auto-start) - [ ] Delete key export file after import --- ## Resources - [Pantalaimon GitHub](https://github.com/matrix-org/pantalaimon) - [Ement.el GitHub](https://github.com/alphapapa/ement.el) - [Matrix E2EE Spec](https://spec.matrix.org/latest/client-server-api/#end-to-end-encryption) - [libolm](https://gitlab.matrix.org/matrix-org/olm) --- *Last updated: January 2026*