spla

de vegades escric

Markdown?

provant markdown prova

codi

Què és Akkoma? és un “fork” de #Pleroma però més “cool”, tal com diuen els seus desenvolupadors:

“a smallish microblogging platform, aka the cooler pleroma”

Akkoma és, per tant, el programari que s'executa en el servidor i que permet ser una part de la xarxa social plena de servidors que s'entenen entre sí gràcies al protocol #ActivityPub i que formen l'Univers d'instàncies Federades, el famós #fedivers. Akkoma és un dels programaris dels molts que emplenen aquest fedivers.

Quines funcionalitats fan que el programari #Akkoma sigui tant interessant i pràctic?

Publicar només per a usuaris locals

Sense mencionar a ningú, només els usuaris locals ho veuen. Qualsevol tema que es vulgui comentar o compartir només amb els usuaris locals o que l'administrador o moderadors del servidor vulguin anunciar-lis pot utilitzar aquesta funcionalitat. És tant fàcil com prémer l'icona “Local” abans de publicar.

línia de temps Local

Línia de temps Bombolla

En aquesta línia de temps es veuen tots els apunts dels servidors amics configurats per l'administrador del servidor. De molta utilitat per als usuaris nous, ja que hi poden trobar ràpidament a qui seguir sense haver d'abocar-se a la línia de temps federada que acostuma a ser una riada de publicacions escrites amb llengües diferents i que passa molt ràpida.

Línia de temps Bombolla FE Línia de temps Bombolla BE

Suport markdown

S'explica sol. Podem configurar el nostre compte per a que publiqui els apunts amb suport Markdown per defecte.

Reaccions emoji

Estem acostumats a prémer l'icona de l'estrella quan volem afavorir una publicació. També podem reaccionar a la mateixa amb emojis, tants com vulguem, i altres usuaris poden reaccionar amb emojis diferents al nostre o amb el mateix simplement clicant-hi al damunt (hi ha un comptador al costat de cada emoji).

reaccions emoji

Cites

No, no van del que potser estàs pensant. Aquesta funcionalitat permet respondre tot citant l'apunt original, fins i tot els nostres. Mostra gràficament l'apunt citat i al damunt el que li hem respòs.

citar un apunt

Converses amb vista d'arbre

Genial! amb altres programaris és difícil per no dir impossible entendre o veure qui està responen a qui en una conversa. Això s'ha acabat! a Akkoma tenim la vista d'arbre.

vista d'arbre interfície web vista d'arbre configuració

Mostrar el favicon del servidor al costat del usuari

Va bé per a saber quin programari és el servidor del usuari en qüestió, sense haver d'obrir el seu perfil públic.

favicon

Saber si un usuari és un bot

De vegades ens passa que responem a una publicació esperant alguna interacció i al veure que no n'hi ha mirem el perfil del usuari, adonant-nos que és un bot. A Akkoma es veu directament si un usuari és un bot perquè el programari afegeix un petit robot damunt del seu avatar, no cal obrir cap perfil.

Robot en avatar

El repositori de Akkoma és en un servidor #Gitea

Tenir el repositori oficial en un servidor Gitea és un punt més a favor.

I fins aquí les més destacades però en té moltes més que fan que Akkoma sigui un ferm candidat a destronar a Mastodon.

Ja tenim acabat i funcionant a plena satisfacció el nostre programa #Python i ens agradaria compartir-lo a PyPi, l'index universal de paquets Python. Tenir-lo allà permet que qualsevol persona que el vulgui instal·lar en el seu ordinador o servidor només li caldrà fer el famós pip install nom_del_paquet.

Estructura

El que cal fer és tenir tots els fitxers necessaris per a executar-lo dins d'un sub directori. Com a exemple utilitzaré el cas real del meu Python wrapper for Akkoma API.

.
├── akkoma
│   ├── Akkoma.py
│   ├── __init__.py
├── LICENSE
├── README.md
├── setup.py
├── tests  

En el sub directori akkoma hi hem de tenir tant el codi que hem programat (el fitxer Akkoma.py) com __init__.py, que serveix per a que Python tracti aquest sub directori com un contenidor de paquets si __init__.py és un arxiu buid o aprofitar-lo per a inicialitzar el nostre programa. Per a no fer massa complexe aquesta entrada recomano llegir aquest enllaç per a entendre millor aquests conceptes.
Hi tenim un altre sub directori, test, que per ara el podem deixar buit. En l'arrel del projecte cal tenir la llicència que li vulguem posar (LICENSE), el inevitable README.md on expliquem com funciona el nostre programa i setup.py, molt important perquè descriu el paquet, diu a setuptools com construir-lo, com pujar-lo a PyPi i què es mostrarà allà.

setup.py

El rovell de l'ou. Aquest és el setup.py real que he utilitzat:

import setuptools

VERSION = '0.1.6'

with open('README.md', 'r', encoding='utf-8') as fh:
    long_description = fh.read()

setuptools.setup(
    name='Akkoma.py',
    version=VERSION,
    author='el_nostre_usuari_a_PyPi',
    author_email='adreça@correu.cat',
    description='Python wrapper for the [Akkoma](https://akkoma.dev/AkkomaGang/akkoma) API.',
    packages=['akkoma'],
    long_description=long_description,
    long_description_content_type='text/markdown',
    url='https://git.mastodont.cat/spla/Akkoma.py',
    install_requires=['pytz', 'requests', 'python-dateutil', 'decorator'],
    project_urls={
        'Bug Tracker': 'https://git.mastodont.cat/spla/Akkoma.py/issues',
    },
    keywords='akkoma api microblogging',
    classifiers=[
        "License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
        "Topic :: Software Development :: Libraries :: Python Modules",
        "Topic :: Communications",
        "Intended Audience :: Developers",
        'Programming Language :: Python :: 3',
    ],
    python_requires = ">=3.8",
)  

La primera línia importa el mòdul setuptools (imprescindible per a construir el paquet). Definim la versió que li volem donar en la segona línia amb VERSION. La tercera obté el contingut de README.md que és el que es mostrarà a PyPi. setuptools.setup descriu el paquet, l'autor, la pàgina del projecte (recomanable tenir un repositori git i posar aquí les urls al mateix), els mòduls que necessitarà el nostre paquet per a executar-se (la línia install_requires), les paraules clau amb keywords (que venen a ser com els hashtags), ón es classifica el projecte amb classifiers (la llista sencera dels que podem usar és aquí) i quina versió de #Python cal per a executar el paquet amb python_requires (en aquest cas ha de ser igual o major a la versió 3.8).
Abans de construir el paquet i pujar-lo a PyPi cal que ens hi registrem. Quan ja tenim el registre fet ja ho tenim tot per a construir el paquet!

Construir el paquet

És tant fàcil com executar això en el directori arrel del projecte:

python -m build

Si no tenim instal·lat el mòdul build donarà un error. Cap problema!

pip install build  

I tornem a executar python -m build. Al final de moltes línies que ens mostrarà el constructor, veurem una línia final que diu:

Successfully built Akkoma.py-0.1.6.tar.gz and Akkoma.py-0.1.6-py3-none-any.whl

Perfecte! Tot llest per a pujar-lo a PyPi. Però un moment, primer ens cal el mòdul twine que facilita molt la tasca:

pip install twine

Ara sí:

python -m twine upload dist/*

Ens demanarà l'usuari i contrasenya de PyPi (ens hi hem registrat abans). Si tot va bé, ens donarà el missatge final on diu la URL del nostre paquet a PyPi i ja tindrem el primer paquet a l'abast de tot el món pythonista mundial.

  • instal·lar el paquete pg_repack (a Ubuntu 20.04 LTS el paquet a instal·lar és postgresql-12-repack)
  • editar postgresql.conf i afegir:

shared_preload_libraries = 'pg_repack' 
 * reiniciar Postgresql


Dins de la base de dades i amb permís de super usuari cal crear l’extensió pg_repack:


CREATE EXTENSION pg_repack;

 * des de la consola executar, per cada una de les taules de la base de dades:

pg_repack -x -d <base de dades> --table <taula>

El paràmetre x li diu a pg_repack que només els index però també podem fer repack a les taules (és el que faig amb la base de dades de Mastodon):

pg_repack -d <base de dades> --table <taula>

Podem crear un arxiu bash per a fer al repack a totes les taules de manera automatitzada.

Quan executem aquest fitxer bash, paciència, pot trigar una estona llarga en fer el repack a totes les taules però tampoc massa. Ja està, ja hem recuperat espai de disc dur.
Nota: en el meu cas de mastodont.cat, desprès d'esborrar 1.600 usuaris inactius, la base de dades de Mastodon ha baixat d'ocupar 30GB a només 20.

Instal·lar #Mastodon en una #Raspberry Pi 4B amb 4 o 8 GB de RAM, segona part

Configurar Mastodon

Desprès dels passos de la primera part ara ens tocava configurar Mastodon:

RAILS_ENV=production bundle exec rake mastodon:setup

Primer ens pregunta el nom del domini (domain name). En el meu cas és mamut.freeddns.org:

Your instance is identified by its domain name. Changing it afterward will break things. Domain name: mamut.freeddns.org

A continuació pregunta si volem activar el mode un sol usuari, mode que desactiva els registres i mostra el nostre perfil per defecte quan algú visiti l'instància:

Single user mode disables registrations and redirects the landing page to your public profile. Do you want to enable single user mode? (y/N) y

No volem Docker:

Are you using Docker to run Mastodon? (Y/n) n

En les següents preguntes simplement premem la tecla Enter:

PostgreSQL host: /var/run/postgresql
PostgreSQL port: 5432
Name of PostgreSQL user: mastodon
Password of PostgreSQL user:

Dirà que Database configuration works!. Perfecte! Seguim. Ara la configuració de Redis, També premem Enter en totes les questions:

Redis host: localhost
Redis port: 6379
Redis password: 

I també li agradarà: Redis configuration works!. Seguim!
Ara pregunta si volem desar els fitxers multi mèdia en el núvol. Responem que no:

Do you want to store uploaded files on the cloud? (y/N) N

I li diem que sí a enviar correus des de localhost:

Do you want to send e-mails from localhost? (y/N) y

Des de quina adreça? premem enter després de canviar notifications per notificacions:

E-mail address to send e-mails "from": (Mastodon <notificacions@mamut.freeddns.org>)

No volem enviar cap correu de prova:

Send a test e-mail with this configuration right now? (Y/n) N

Ja hem acabat. Ara pregunta si desem la configuració:

This configuration will be written to .env.production. Save configuration? (Y/n) Y

Ara diu això, li diem que sí:

Now that configuration is saved, the database schema must be loaded.If the database already exists, this will erase its contents. Prepare the database now? (Y/n) Y

Quan acabi:

Created database 'mastodon_production'. Done!

I el pas final, compilar els assets (aquí és on la Raspberry Pi 3B+ deia “de cap manera, que només tinc 1GB de RAM!”:

Compile the assets now? (Y/n)  Y

Trigarà uns minuts, paciència! Quan hagi acabat dirà:

Compiled all packs in /home/mastodon/live/public/packs. Done! All done! You can now power on the Mastodon server

Ens permet crear l'admin, doncs sí, nosaltres mateixos:

Do you want to create an admin user straight away? (Y/n) Y

Pregunta nom d'usuari i adreça de correu electrònic. Responem el que vulguem i ens retornarà una contrasenya. La desem ben desada per més tard!

Ja podem tornar al usuari root.

nginx

Copiem la plantilla per a nginx de mastodon:

cp /home/mastodon/live/dist/nginx.conf /etc/nginx/sites-available/mastodon

Editem el fitxer copiat per a canviar example.com per el nostre domini mamut.freeddns.org (apareix dues vegades) i desem els canvis. Comprovem que a nginx li agrada fent nginx -t. Si no dona cap error carreguem la nova configuració:

systemctl reload nginx

Certificat SSL

Per a obtenir el certificat SSL fem el següent:

certbot --nginx -d mamut.freeddns.org

Si ens dona l'error nginx: [emerg] no "ssl_certificate" is defined for the "listen ... ssl" directive in /etc/nginx/sites-enabled/mastodon:33, tornem a editar el fitxer /etc/nginx/sites-available/mastodoni comentem la línia del error, en aquest exemple la línia 33. Desem els canvis i tornem a provar:

certbot --nginx -d mamut.freeddns.org

Si tot ha anat bé:

Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/mamut.freeddns.org/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/mamut.freeddns.org/privkey.pem

unitats systemd

Copiem les tres unitats systemd necessàries:

cp /home/mastodon/live/dist/mastodon-*.service /etc/systemd/system/

Informem a systemd:

systemctl daemon-reload

I (ja era hora!) iniciem Mastodon:

systemctl enable --now mastodon-web mastodon-sidekiq mastodon-streaming

Encara que tinguem que parar la Raspberry per qualsevol motiu, aquest enable de dalt farà que Mastodon torni a posar-se en marxa quan engeguem de nou la Raspi.

Ja estem! podem visitar el nostre servidor Mastodon executant-se en la Raspberry de casa!

Instal·lar #Mastodon en una #Raspberry Pi 4B amb 4 o 8 GB de RAM, primera part

El sistema operatiu de la meva Raspberry és Ubuntu 22.04.1 LTS (GNU/Linux 5.15.0-1021-raspi aarch64). Aquests passos funcionen perfectament en totes les Raspberry que corrin el mateix sistema operatiu però haurien de servir també per a les que utilitzin Raspbian. Si el teu sistema operatiu no és Ubuntu el pots instal·lar seguint les instruccions oficials adients.

Cal comentar abans de començar que per a poder instal·lar Mastodon ens calen, com a mínim, 4GB de RAM. El motiu és que amb menys RAM no podrem compilar els assets de Mastodon. Ho sé perquè vaig voler provar-ho en la 3B+ que només té 1GB de RAM...

Servei DDNS

Per a que el servidor Mastodon que volem instal·lar federi amb el #fedivers ens cal crear un compte en un servei DDNS. Un dels molts que hi ha que té certa fama i permet actualitzar la IP pública via la seva API és Dynu {d}DNS. Creem un compte en l'enllaç anterior i en la secció Dynamic DNS Service premem el botó + Add. En el camp Host de Option 1: Use Our Domain Name hi escribim el subdomini que vulguem, en el meu cas he posat mamut, i després triem el domini dels que hi ha disponibles a Top Level, en el meu cas freeddns.org. Acabem prement el botó Add de sota. Ja tenim un nom de domini per el nostre Mastodon! Per tot aquest tutorial serà mamut.freeddns.org.

IP dinàmica, IP pública

El més segur és que a casa tinguem IP dinàmica. Per a que la resta de servidors del fedivers ens puguin trobar hem de actualitzar el servei DDNS amb la IP pública (la IP dinàmica que ens assigna el nostre proveidor d'Internet).
Dynu {d}DNS permet fer-ho mitjançant la seva #API, Genial, m'agrada molt #Python i programar el meu propi codi. Dit i fet, si seguim els pasos del meu repositori dynuapi tindrem la Raspberry enviant cada 30 minuts la seva IP pública al servei DDNS.
Abans de fer-ho, ens cal saber quina és la API-Key del nostre compte a Dynu {d}DNS. La tenim en la secció API Credentials del panel de control. Ens cal perquè dynuapi ens la demanarà.

Port forwarding

Cal redirigir els ports 80 i 443 del router principal de casa cap a la IP local de la Raspberry. En la secció Port forwarding del tutorial de Akkoma explico com es fa.

Requisits de Mastodon

Aquest tutorial està basat en la documentació oficial.

Com a root instal·lem els següents paquets del sistema operatiu:

apt install -y curl wget gnupg apt-transport-https lsb-release ca-certificates

També ens cal Node.js:

curl -sL https://deb.nodesource.com/setup_16.x | bash -
apt-get install -y nodejs

I els paquets següents:

apt install -y \
imagemagick ffmpeg libpq-dev libxml2-dev libxslt1-dev file git-core \ g++ libprotobuf-dev protobuf-compiler pkg-config nodejs gcc autoconf \
bison build-essential libssl-dev libyaml-dev libreadline6-dev \
zlib1g-dev libncurses5-dev libffi-dev libgdbm-dev \
nginx redis-server redis-tools postgresql postgresql-contrib \
certbot python3-certbot-nginx libidn11-dev libicu-dev libjemalloc-dev

Yarn

Executem aquestes dues línies:

corepack enable
yarn set version classic

Ruby

Primer afegim l'usuari mastodon:

adduser --disabled-login mastodon

I canviem a ell:

su - mastodon

Mastodon necessita Ruby, executem aquestes sis línies una a una:

git clone https://github.com/rbenv/rbenv.git ~/.rbenv
cd ~/.rbenv && src/configure && make -C src
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(rbenv init -)"' >> ~/.bashrc
exec bash
git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build

Ara ja podem instal.lar la versió de Ruby correcte:

RUBY_CONFIGURE_OPTS=--with-jemalloc rbenv install 3.0.4

I fem que sigui global:

rbenv global 3.0.4

Necessitem el primer 'gem' bundler:

gem install bundler --no-document

Tornem al usuari root:

exit

Postgresql

Hem de crear l'usuari/rol mastodon a Postgresql:

sudo -u postgres psql

I en el prompt creem l'usuari:

CREATE USER mastodon CREATEDB;

Ja podem sortir:

\q

I tornem al usuari mastodon:

su - mastodon

Clonar Mastodon

Instal·lem (clonem) Mastodon des d'el repositori oficial al directori local live i hi entrem:

git clone https://github.com/mastodon/mastodon.git live && cd live

La darrera versió estable:

git checkout $(git tag -l | grep -v 'rc[0-9]*$' | sort -V | tail -n 1)

Les darreres dependències de Ruby i JavaScript, línia a línia:

bundle config deployment 'true'
bundle config without 'development test'
bundle install -j$(getconf _NPROCESSORS_ONLN)
yarn install --pure-lockfile

Configurarem Mastodon en la segona part.

Instal·lar #Akkoma en una #Raspberry Pi 3B+ (o superior), segona part

En la primera part vam veure els primers passos. En aquesta entrada veurem els finals:

  • instal·lar les dependències
  • instal·lar nginx
  • obtenir un certificat SSL
  • clonar Akkoma
  • instal·lar el gestor de versions Elixir/Erlang asdf

Instal·lar nginx

No té cap misteri, com a root:

apt install nginx

Activem la unitat systemd per a assegurar que quan engeguem la nostre Raspberry (si és que la parem mai) també s'iniciï nginx i iniciem nginx ara mateix:

systemctl enable nginx && systemctl start nginx

Confirmem que tenim nginx en marxa:

systemctl status nginx

En una de les línies hem de veure que diu “active”.

Obtenir certificat SSL

Si volem federar amb tot el fedivers, el domini de l'instància Akkoma que estem muntant ha de ser accessible sí o sí de manera segura amb el protocol https. Ens cal obtenir un certificat. Si no tenim instal·lat el paquet certbot fem-ho ara:

apt install certbot

Com a root, obtenim el certificat per a nginx així:

certbot certonly -d akkoma.ddns.net --standalone  

Es queixarà d'aquest problema perquè tenim nginx en marxa:

Problem binding to port 80: Could not bind to IPv4 or IPv6.

Parem nginx i tornem a provar-ho:

systemctl stop nginx
certbot certonly -d akkoma.ddns.net --standalone

Si certbot ens dona l'error Timeout during connect (likely firewall problem) és perquè tenim el firewall amb els ports 80 i 443 tancats. Si el firewall és ufw els obrim així de fàcil:

ufw allow 'Nginx Full'

Tornem a provar:

certbot certonly -d akkoma.ddns.net --standalone

Si tot ha anat bé ho sabrem:

Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/akkoma.ddns.net/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/akkoma.ddns.net/privkey.pem

Clonar Akkoma

Encara no hem creat l'usuari akkoma:

useradd -r -s /bin/false -m -d /var/lib/akkoma -U akkoma

Creem el directori on clonarem Akkoma i fem propietari al usuari akkoma:
mkdir -p /opt/akkoma
chown -R akkoma:akkoma /opt/akkoma
I com a usuari akkoma clonem la darrera versió estable des d'el repositori:

sudo -Hu akkoma git clone https://akkoma.dev/AkkomaGang/akkoma.git /opt/akkoma  

instal·lar asdf i compilar Akkoma

Un problema potencial quan instal·lem els paquets Elixir i Erlang amb el gestor de paquets del sistema operatiu és que una actualització d'aquests paquets pot provocar que la nostra flamant instància Akkoma deixi de funcionar (ha passat amb diverses instàncies del fedivers). Per evitar això és una bona idea instal·lar el gestor de versions asdf.

Canviem al directori i al usuari akkoma:
cd /opt/akkoma
sudo -Hu akkoma bash
Ara hem de crear un nou fitxer anomenat .tool-versions, on posarem les versions d'Elixir i Erlang que volem per al nostre Akkoma:

elixir 1.14.0 erlang 25.1.1

Desem els canvis i clonem asdf des de la font. La darrera versió estable en el moment d'escriure aquesta entrada és la v0.11.0:

git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.11.0

Ara afegim a .bashrc les rutes adients:

echo ". $HOME/.asdf/asdf.sh" >> ~/.bashrc echo ". $HOME/.asdf/completions/asdf.bash" >> ~/.bashrc

I les carreguem amb:

exec bash

El següent pas és afegir els dos plugins, tant de Elixir com de Erlang:
asdf plugin-add erlang
asdf plugin-add elixir
Instal·lem i compilem tot plegat (trigarà uns quants minuts, paciència):

asdf install

Pot donar algun error xxxx is missing... no passa res, calma. Si et diu Erlang/OTP 25.2 (asdf_25.2) has been successfully built vol dir que tot ha anat bé i podem continuar.

Executem línia a línia els passos següents per a compilar Akkoma:
mix local.hex --force mix local.rebar --force mix deps.get MIX_ENV=prod mix compile
Quan hagi acabat veurem Generated pleroma app. Ara cal que generem la configuració de l'instància:

MIX_ENV=prod mix pleroma.instance gen

Anem responem a totes les preguntes que ens fa, la primera i més important és el domini, en aquest cas és akkoma.ddns.net. Quan acabi haurà generat la configuració a config/generated_config.exs. L'hem de moure a config/prod.secret.exs:

mv config/{generated_config.exs,prod.secret.exs}

Ara toca crear la base de dades Postgresql. Sortim del usuari akkoma i encara dins de /opt/akkoma, com a root fem:

sudo -Hu postgres psql -f config/setup_db.psql

Tornem al usuari akkoma i executem ecto.migrate per a crear totes les taules de la base de dades:

MIX_ENV=prod mix ecto.migrate

Altre cop com a root, copiem l'unitat systemd al lloc adient:

cp /opt/akkoma/installation/akkoma.service /etc/systemd/system/akkoma.service

Editem l'unitat systemd, comentant la línia que diu ExecStart=/usr/bin/mix phx.serveri afegint a sota les dues línies que veiem a continuació:

;ExecStart=/usr/bin/mix phx.server Environment=“PATH=/var/lib/akkoma/.asdf/shims:/var/lib/akkoma/.asdf/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin” ExecStart=/var/lib/akkoma/.asdf/shims/mix phx.server

Desem els canvis i els recarreguem amb systemctl daemon-reload i ja podem posar en marxa la nostra flamant instància Akkoma:

systemctl enable akkoma && systemctl start akkoma

Podem confirmar que tot va bé mirant l'status: systemctl status akkoma

Possibles problemes relacionats amb les llibreries Crypto

Si Akkoma no engega podem veure el motiu amb:

journalctl -xfe -u akkoma.service

Si hi veiem errors relacionats amb rsaEncryption o public_key o private_key o RSAPrivateKey, és molt possible que el nostre Ubuntu no tingui instal·lada la llibreia libssl adient. Amb Ubuntu Server 22.04.2 LTS ho he sol·lucionat així:

Descarregar i instal·lar libssl1.1 (per a Ubuntu Server 22.04.2 LTS):

wget http://nz2.archive.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2.18_amd64.deb dpkg -i libssl1.1_1.1.1f-1ubuntu2.18_amd64.deb

Nota: em va donar una pista de com sol·lucionar el problema la versió OTP que vaig provar d'instal·lar al veure que no em funcionava aquesta. Ho tinc publicat a mastodont.cat:

Unable to load Crypto Library

nginx

Copiem la configuració exemple per a nginx: cp /opt/akkoma/installation/nginx/akkoma.nginx /etc/nginx/sites-available/akkoma.nginx

Ara ja podem afegir a la configuració de nginx on tenim el certificat. Editem la configuració exemple que hem copiat a dalt i assegurem tenir aquestes dues línies que diuen on trobar els certificats obtinguts:

ssl_certificate /etc/letsencrypt/live/akkoma.ddns.net/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/akkoma.ddns.net/privkey.pem;

Canviem example.tld a server_name per akkoma.ddns.net en els dos blocs server.

Desem els canvis i enllaçament la configuració en el directori sites-enabled per a que nginx la tingui en compte:

ln -s /etc/nginx/sites-available/akkoma.nginx /etc/nginx/sites-enabled/akkoma.nginx

Ara assegurem que a nginx li agrada:

nginx -t

Si respon test is succesful ja podem reiniciar nginx per a que la carregui:

systemctl restart nginx

Engegar Akkoma

Amb el navegador ja podem visitar-la!

Veurem que ems diu “Welcome to Akkoma! If you are seeinf this page, your server works!” però a sota demanarà que hi instal·lem un frontend:

cd /opt/akkoma && sudo -Hu akkoma bash MIX_ENV=prod mix pleroma.frontend install pleroma-fe --ref stable

I ja està, si tornem al navegador ja veurem el nostre Akkoma amb frontend!

Crear l'usuari admin

Ep! un moment! voldràs fer-te admin suposo!

cd /opt/akkoma && sudo -Hu akkoma bash

Per a crear l'usuari amb drets d'administració:

MIX_ENV=prod mix pleroma.user new <usuari> <adreça de correu> --admin

Aquesta línia de dalt et genera un enllaç per a establir la contrasenya del usuari admin que has creat.

Per a poder fer tasques d'admin et cal instal·lar el frontend adient:

MIX_ENV=prod mix pleroma.frontend install admin-fe --ref stable

Ja està! A gaudir de la teva sobirania digital!

Instal·lar #Akkoma en una #Raspberry Pi 3B+ (o superior), primera part

El sistema operatiu de la meva Raspberry és Ubuntu 20.04 LTS (GNU/Linux 5.4.0-1065-raspi aarch64). Aquests passos funcionen perfectament en totes les Raspberry que corrin el mateix sistema operatiu però haurien de servir també per a les que utilitzin Raspbian.

Els passos resumits son aquests:

  • instal·lar les dependències necessàries
  • configurar un hostname en un servei DDNS
  • instal·lar el programa DUC en la Raspberry per a informar al servei DDNS de la seva IP pública
  • Fer un “Port Forwarding” en el router de casa dels ports 80 i 443, per a que apuntin a la IP local de la Raspberry
  • Instal·lar nginx
  • Obtenir certificat SSL per el hostname obtingut del servei DDNS
  • Instal·lar Akkoma

Instal·lar les dependències

Actualitzem el sistema operatiu:

sudo apt update
sudo apt full-upgrade

Instal·lem els paquets mínims necessaris:

sudo apt install git build-essential postgresql postgresql-contrib cmake libmagic-dev automake libncurses5-dev

I els paquets opcionals:

sudo apt install imagemagick ffmpeg libimage-exiftool-perl

Configurar un hostname en el servei DDNS

Abans de tot ens cal un servei #DDNS (Dynamic DNS) on crear el hostname del nostre servidor Akkoma. Ho necessitem perquè volem que la nostra instància Akkoma sigui accessible des d'internet. Configurarem un hostname en el nostre servei DDNS, per exemple a noip però n'hi ha d'altres, i aquest servei DDNS serà qui resoldrà aquest hostname a la IP pública de la Raspberry.
noip ens permet obtenir gratuïtament un sol hostname (suficient!), on només podem escriure el nom de subdomini per a un dels quatre dominis disponibles. En el meu cas vaig escollir el domini “ddns.net” amb el subdomini, escrit per mi, “akkoma”: akkoma.ddns.net

Instal·lar el Dynamic Update Client (DUC) en la Raspi.

Com que el més segur és que a casa tinguem IP dinàmica, la Raspberry haurà de informar al servei DDNS de quina IP pública té. Per a fer tal cosa haurem de seguir les instruccions necessàries per a instal·lar el programa DUC.
Descarreguem el client DUC a la nostre PI, en el directori /usr/local/src/

Com a root:

cd /usr/local/src/

descarreguem DUC:

wget http://www.noip.com/client/linux/noip-duc-linux.tar.gz

el descomprimim:

tar xf noip-duc-linux.tar.gz

entrem en el directori creat al descomprimir:

cd noip-2.1.9-1/

i executem:

make install

Ens demanarà iniciar sessió en el nostre compte de noip, doncs li donem usuari i contrasenya. Seguint com a usuari root, crearem la configuració per defecte de DUC:

/usr/local/bin/noip2 -C

Ens demanarà altre cop l'usuari i contrasenya del compte a noip. Si ara executem

/usr/local/bin/noip2

ja hauria d'enviar la IP pública al servei DDNS de noip. Evidentment no és bona idea haver d'executar-ho manualment per tant ens anirà d'allò més bé un servei systemd que ho executi automàticament al engegar la Raspberry o desprès d'un reinici pel motiu que sigui.
Creem el servei noip2.service:

vim /etc/systemd/system/noip2.service

amb el següent contingut:

[Unit] Description=noip2 service

[Service] Type=forking ExecStart=/usr/local/bin/noip2 Restart=always

[Install] WantedBy=default.target

Desem els canvis. Com que volem que s'activi al engegar o reiniciar-se la Raspberry, activem el servei:

systemctl enable noip2.service

i l'iniciem ara mateix:

systemctl start noip2.service.

Podem saber si tot va bé consultant l'estat:

systemctl status noip2.service

Port Forwarding

Per a que Akkoma funcioni perfectament ens cal que totes les peticions d'altres servidors del #fedivers que vagin cap el nostre node es dirigeixin a la Raspberry. Aquestes peticions es fan a dos ports TCP, el 80 (http) i el 443 (https). La sol·lució a això es diu Port Forwarding. Hauriem de poder accedir al router principal de casa (el que ens dona o lloga el nostre proveïdor d'internet). Normalment la IP del router és 192.168.1.1, des d'el navegador visitem aquesta IP. Si ens demana usuari i contrasenya el més probable és que les tinguem escrites en una etiqueta enganxada en la part inferior del router. Un cop dins del router cerquem l'opció “Port Forwarding” o “Redireccionar puertos”. I afegim dues redireccions, una per el port 80 i la segona per el port 443. Tots els routers son pràcticament iguals, per a fer un “Port Forwarding” acostumen a demanar-nos:

Service name < hi posem http Port Range < 80 Local IP < la IP local de la Raspberry (ha de ser IP fixa, no serveix que la obtingui via DHCP des d'el router), per exemple 192.168.1.3 Local Port < 80 Protocol < TCP

Apliquem/desem la primera redirecció i afegim la segona:

Service name < hi posem https Port Range < 443 Local IP < la IP local de la Raspberry (ha de ser IP fixa, no serveix que la obtingui via DHCP des d'el router), per exemple 192.168.1.3 Local Port < 443 Protocol < TCP

Apliquem/desem el canvis i ja podem tancar sessió del router. Ja tenim preparats tant la Raspberry com el nostre router. En la segona part veurem com instal·lar nginx, obtenir un certificat SSL per el nostre flamant nom de domini que apuntarà a la nostra instància #Akkoma i, a la fi, instal·lar Akkoma.

En la primera part vam veure els primers passos. En aquesta entrada veurem els finals:

  • instal·lar nginx
  • obtenir un certificat SSL
  • clonar Pleroma
  • instal·lar el gestor de versions Elixir/Erlang asdf

Instal·lar nginx

No té cap misteri, com a root:

apt install nginx

Activem la unitat systemd per a assegurar que quan engeguem la nostre Raspberry (si és que la parem mai) també s'iniciï nginx i iniciem nginx ara mateix:

systemctl enable nginx && systemctl start nginx

Confirmem que tenim nginx en marxa:

systemctl status nginx

En una de les línies hem de veure que diu “active”.

Obtenir certificat SSL

Si volem federar amb tot el fedivers, el domini de l'instància Pleroma que estem muntant ha de ser accessible sí o sí de manera segura amb el protocol https. Ens cal obtenir un certificat. Si no tenim instal·lat el paquet certbot fem-ho ara:

apt install certbot

Com a root, obtenim el certificat per a nginx així:

certbot certonly -d aarch.ddns.net —standalone

Es queixarà d'aquest problema perquè tenim nginx en marxa:

Problem binding to port 80: Could not bind to IPv4 or IPv6.

Parem nginx i tornem a provar-ho:

systemctl stop nginx
certbot certonly -d aarch.ddns.net —standalone

Si certbot ens dona l'error Timeout during connect (likely firewall problem) és perquè tenim el firewall amb els ports 80 i 443 tancats. Si el firewall és ufw els obrim així de fàcil:

ufw allow 'Nginx Full'

Tornem a provar:

certbot certonly -d aarch.ddns.net —standalone

Si tot ha anat bé ho sabrem:

Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/aarch.ddns.net/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/aarch.ddns.net/privkey.pem

### Clonar Pleroma

Encara no hem creat l'usuari pleroma:

useradd -r -s /bin/false -m -d /var/lib/pleroma -U pleroma

Creem el directori on clonarem Pleroma i fem propietari al usuari pleroma:

mkdir -p /opt/pleroma
chown -R pleroma:pleroma /opt/pleroma

I com a usuari pleroma clonem la darrera versió estable des d'el repositori:

sudo -Hu pleroma git clone -b stable https://git.pleroma.social/pleroma/pleroma /opt/pleroma

instal·lar asdf i compilar Pleroma

Un problema potencial quan instal·lem els paquets Elixir i Erlang amb el gestor de paquets del sistema operatiu és que una actualització d'aquests paquets pot provocar que la nostra flamant instància Pleroma deixi de funcionar (ha passat amb diverses instàncies del fedivers). Per evitar això és una bona idea instal·lar el gestor de versions asdf.

Canviem al directori i al usuari pleroma:

cd /opt/pleroma
sudo -Hu pleroma bash

Ara hem de crear un nou fitxer anomenat .tool-versions, on posarem les versions d'Elixir i Erlang que volem per al nostra Pleroma:

elixir 1.14.0 erlang 25.1.1

Desem els canvis i clonem asdf des de la font. La darrera versió estable en el moment d'escriure aquesta entrada és la v0.11.3:

git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.11.3

Ara afegim a .bashrc les rutes adients:

echo ". $HOME/.asdf/asdf.sh" >> ~/.bashrc
echo ". $HOME/.asdf/completions/asdf.bash" >> ~/.bashrc

I les carreguem amb:

exec bash

El següent pas és afegir els dos plugins, tant de Elixir com de Erlang:

asdf plugin-add erlang
asdf plugin-add elixir

Instal·lem i compilem tot plegat (trigarà uns quants minuts, paciència):

asdf install

Pot donar algun error xxxx is missing... no passa res, calma. Si et diu Erlang/OTP 25.2 (asdf_25_2) has been successfully built vol dir que tot ha anat bé i podem continuar.

Executem línia a línia els passos següents per a compilar Pleroma:

mix local.hex --force
mix local.rebar --force
mix deps.get
MIX_ENV=prod mix compile

Quan hagi acabat veurem Generated pleroma app. Ara cal que generem la configuració de l'instància:

MIX_ENV=prod mix pleroma.instance gen

Anem responent a totes les preguntes que ens fa, la primera i més important és el domini, en aquest cas és aarch.ddns.net. Quan acabi haurà generat la configuració a config/generated_config.exs. L'hem de moure a config/prod.secret.exs:

mv config/{generated_config.exs,prod.secret.exs}

Ara toca crear la base de dades Postgresql. Sortim del usuari pleroma i encara dins de /opt/pleroma, com a root fem:

sudo -Hu postgres psql -f config/setup_db.psql

Tornem al usuari pleroma i executem ecto.migrate per a crear totes les taules de la base de dades:

MIX_ENV=prod mix ecto.migrate

Altre cop com a root, copiem l'unitat systemd al lloc adient:

cp /opt/pleroma/installation/pleroma.service /etc/systemd/system/pleroma.service

Editem l'unitat systemd, comentant la línia que diu

ExecStart=/usr/bin/mix phx.server

i afegint a sota les dues línies que veiem a continuació:

;ExecStart=/usr/bin/mix phx.server
Environment="PATH=/var/lib/pleroma/.asdf/shims:/var/lib/pleroma/.asdf/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
ExecStart=/var/lib/pleroma/.asdf/shims/mix phx.server

Recarreguem els canvis amb systemctl daemon-reload i ja podem posar en marxa la nostra flamant instància Pleroma:

systemctl enable pleroma && systemctl start pleroma

nginx

Com a root, copiem la configuració d'exemple per a nginx:

cp /opt/pleroma/installation/pleroma.nginx /etc/nginx/sites-available/pleroma.nginx

I l'enllacem per a activar-la:

ln -s /etc/nginx/sites-available/pleroma.nginx /etc/nginx/sites-enabled/pleroma.nginx

Ara ja podem configurar nginx per dir-li on tenim el certificat creat abans. Editem /etc/nginx/sites-available/pleroma.nginx i assegurem tenir aquestes dues línies que diuen on trobar els certificats obtinguts:

sslcertificate /etc/letsencrypt/live/aarch.ddns.net/fullchain.pem; sslcertificate_key /etc/letsencrypt/live/aarch.ddns.net/privkey.pem;

En els dos blocs server hem de substituir example.tld per el nostre domini aarch.ddns.net.

Desem els canvis.

Ara assegurem que a nginx li agrada:

nginx -t

Si respon test is succesful ja podem reiniciar nginx per a que la carregui:

systemctl restart nginx

Primera visita al nostre Pleroma

Amb el navegador ja podem visitar l'instància Pleroma!

Ep! un moment! voldràs fer-te admin suposo!

sudo -Hu pleroma bash
MIX_ENV=prod mix pleroma.user new <nom_usuari> <adreça de correu> --admin

La segona línia et genera un enllaç per a establir la contrasenya del usuari admin que has creat.

Ja està! A gaudir de la teva sobirania digital!

Hi ha diversos proveïdors de serveis #DDNS que ens permeten poder accedir remotament a la nostre Raspberry on hi podem tenir instal·lats serveis com ara Nextcloud, Akkoma (servidor social fork de Pleroma) etc. Això és possible gràcies a que aquests proveïdors de DDNS apunten a la IP pública de la Raspberry quan escrivim en el navegador el domini que hi hem escollit. Sempre és millor no dependre de tercers així que aquest és el motiu per el que escric aquesta entrada.

requisits

Ens cal tenir registrat un domini propi i que el registrador del domini ens permeti fer delegació de DNS. També ens cal tenir el nostre propi servidor DNS (Bind9), que gràcies a la delegació passarà a ser el servidor autoritari per el nostre domini.
Suposem que el nostre domini registrat és elnostredomini.cat i el subdomini que apuntarà a la Raspberry és raspberry.elnostredomini.cat.

dnssec

El més segur és que a casa tinguem IP dinàmica (si no és així aquest article no té sentit) per tant ens caldrà enviar-la periòdicament al nostre servidor #DNS Bind9. Entra en joc #dnssec. dnssec farà una connexió segura al nostre Bind9 i actualitzarà el registre del domini o subdomini que li diguem. El primer pas és crear la dnssec key:

ddns-confgen -s raspberry.elnostredomini.cat

Ens respondrà això:

To activate this key, place the following in named.conf, and in a separate keyfile on the system or systems from which nsupdate will be run: key “ddns-key.raspberry.elnostredomini.cat” { algorithm hmac-sha256; secret “lLeySmmWp2TrF0qSlSyblQOp7wTTNxWoDkFYUaTyGtk=”; };

Then, in the “zone” statement for the zone containing the name “raspberry.elnostredomini.cat”, place an “update-policy” statement like this one, adjusted as needed for your preferred permissions: update-policy { grant ddns-key.raspberry.elnostredomini.cat name raspberry.elnostredomini.cat ANY; };

After the keyfile has been placed, the following command will execute nsupdate using this key: nsupdate -k

Editem /etc/bind/named.conf.local i hi afegim la key:

... key “ddns-key.raspberry.elnostredomini.cat” { algorithm hmac-sha256; secret “lLeySmmWp2TrF0qSlSyblQOp7wTTNxWoDkFYUaTyGtk=”; };

zone “elnostredomini.cat” { type master; file “/var/lib/bind/db.elnostredomini.cat”; update-policy { grant ddns-key.elnostredomini.cat name elnostredomini.cat. ANY; }; }; ...

Reiniciem el servidor Bind9:

systemctl restart bind9

configurar el client

Ara hem de crear el fitxer que contingui la key generada, per exemple a /etc/ddnsupdate.key, on la hi posem:

key “ddns-key.raspberry.elnostredomini.cat” { algorithm hmac-sha256; secret “lLeySmmWp2TrF0qSlSyblQOp7wTTNxWoDkFYUaTyGtk=”; };

I també hem de crear el bash script que s'executarà periòdicament, enviant la IP pública al nostre servidor DNS Bind9, actualitzant si cal el registre del subdomini raspberry.elnostredomini.cat. Per exemple /usr/local/bin/ddnsupdate:

#!/bin/bash

MYIP=$(dig +short myip.opendns.com @resolver1.opendns.com)

KEY=/etc/ddnsupdate.key NS=ns1.elnostredomini.cat DOMAIN=raspberry.elnostredomini.cat. ZONE=elnostredomini.cat.

nsupdate -k $KEY -v << EOF server $NS zone $ZONE update delete $DOMAIN A update add $DOMAIN 30 A $MYIP send EOF

El fem executable:

chmod +x /usr/local/bin/ddnsupdate

Afegim una tasca cron perquè volem que l'script bash s'executi periòdicament:

crontab -e

i afegim la tasca en qüestió:

... */5 * * * * /usr/local/bin/ddnsupdate > /dev/null 2>&1 ...

Ja estem.