Kim's blog

A public set of random notes I'd like to share

in English

en Français

in Italiano

in English

en Français

in Italiano

in English

en Français

in Italiano

I happened to come across this news that inspired this post post. The core point here isn't so much Bitcoin, but rather understanding what money actually is, specifically, the fact that it has to fulfill the three basic functions every economics student knows:

  1. unit of account, i.e. book money

  2. medium of exchange, i.e. peer-to-peer payments or face-to-face cash exchange

  3. store of value, i.e. setting money aside that can later be used for purchases or investments at a future date

But these are actually just a single function: being a tool for universal barter, meaning that all participants in an economic system accept in exchange for any good or service they intend to trade. The “store of value” concept is a bit of a red herring because it only works, and meets a real need, if the economy using that currency is functioning. In that case, the money saved today will allow for purchases or investments tomorrow, effectively “preserving” value, but it will only do so if the economy works and within the parameters of how it works (read: inflation). Furthermore, the distinction between a unit of account and a medium of exchange no longer makes sense in a digitized world, because face-to-face payments are electronic anyway; therefore, they are book money, not physical currency minted as metal objects or slips of paper.

Teaching this in school, IF this ends up being the El Salvador Bitcoin 2.0 curriculum, because right now I can't find it, I only see the news, is an excellent and REVOLUTIONARY thing. As a basic concept, it's actually pretty easy to explain even to children. Explaining why banking economics is a scam is also easy, even if you leave out all the significant layers of complexity regarding how banks and central banks operate. For anyone curious, I suggest this short clip from an old Colombian movie https://youtu.be/WpGhcDg7IJ4. It's not accurate in the details today, because money creation is largely in the hands of private banks through the fractional reserve system, not the central bank, which creates it against government bonds only for what the State requests and has a fairly complex interbank mechanism for dealing with the private banks below it, but in essence, it's still true.

If they also teach (and I doubt they will) the FORMAL, theoretical purpose of taxes, vs. taxation as theft, which is de facto what's happening in the West today, well, they'll raise generations that won't be so easily manipulated in financial terms, and that would be a first in centuries, maybe ever.

In other words, the potential and scope of this initiative are HUGE, and El Salvador, once a Socialist country devastated by a CIA coup, could reborn as a powerhouse that might truly become a little oasis of prosperity, despite its lack of defensibility and climate issues.

Today, those outside the crypto world don't know it, but the high cost of hardware, first video cards, then RAM, now NVMEs and storage in general, for the first time in IT history and only since a few years because until few years ago prices held steady or dropped, and the current crypto bear market, largely triggered by Wall Street (a Wall Street on its last swan song before World War III to save itself), are signs of how much ground crypto is gaining even among those who have ignored it until now, and how worried the banks are about losing control of the real economy, their lifeblood for sucking us all dry.

Bitcoin has many flaws, though not the ones most people think. But as of today, it has emerged and is holding its ground; it's big enough that it won't be easy to take down. That's why, on one hand, war is being waged against it, while on the other, Lightning transactions are exploding alongside Nostr, which is timidly starting to spread, creating the economic web that until now had failed (and still hasn't quite managed) to emerge. The underlying dream isn't as “easy” or “vast” as described by those who put it down in black and white, but it's holding up. The IT obsolescence of current society, which is dominated by banks and has sat above politics since at least WWII, rising with the betrayal of the French Revolution at its birth, is truly heading toward its sunset, along with its limits and its scandals of funds illegally frozen for those disliked by the establishment. They won't go without causing casualties, but this really is their final swan song.

I therefore invite any reader who has made it this far to reflect on this and get informed. It's too late to get in and become a millionaire with very little, meaning with low risk and a low barrier to entry, but it's not too late to still own some; it can still be done. Those who do will be much better off than those who keep sleeping, even if no one is going to be doing well in the storm we're already in, which is nothing compared to what almost certainly awaits us.

in English

en Français

in Italiano

in English

en Français

in Italiano

in English

en Français

in Italiano

in English

en Français

in Italiano

in English

en Français

in Italiano

A mini-article and RANT on how to deploy a trial Matrix homeserver for communications between family and friends without (mostly) depending on third-party services. “Mostly” implies that there are some dependencies:

  • owning a domain name

  • DNS management for this name to have an IPv4/v6 address reachable from the internet linked to your name

  • an internet connection

  • unfortunately, unlike XMPP, even if it's more convenient for various reasons, Matrix ties itself to other “trusted servers” and “vector.im”; it works without them too, but it's a bit crippled

For these reasons and plenty more besides, many people aren't fans of Matrix, but it has the advantage of working well enough once you've done a bit of swearing at the subpar documentation and various other issues. It's what you might call accessible for friends and family without IT skills, provided someone in the group sets up and maintains the instance for everyone else. Basically, you don't even need a third-party client; you can just provide Element web for those who want it. It has Android/iOS apps similar to the desktop version (along with various others that implement most of the features), so it's quite handy at the moment and might appeal to the many people jumping ship from Discord.

As a mobile client, I'd recommend Element Classic for now; for desktop, Element desktop. I'm not exactly thrilled with them, I think they're bloat monsters, but they get the job done and for starting out, I can't find anything better.

The initial minimum number of services is 3. Coturn to enable audio/video chat for those behind NAT/without IPv6, a Matrix server and a web server. Although not yet “production-ready”, after experimenting a bit with the Matrix servers available as NixOS modules, I chose Tuwunel, which is mature enough and doesn't seem to consume significant resources for a generic homeserver with family+friend only usage. Finally, a web server is needed to act as a proxy; in this case, I went with NGINX without a second thought. To get SSL without messing around with self-signed certificates or creating a CA for every client to avoid them, a dependency on Let's Encrypt/ACME is added.

I'll be updating this post soon with LiveKit and hopefully Element Call to support video conferencing for many participants (with the current setup you can do up to 3 or 4 max participants to a video-calls).

For now, I won't be covering the numerous “privacy” aspects of Matrix, such as how to manage room encryption, key backups, etc. There's a lot to it and it's a topic that takes time to explore, plus it doesn't make much sense for several reasons in a home test setup. So, let's get straight to the point.

Coturn

Some people complain about issues behind NAT; I haven't personally encountered them yet, so I'll just mention that if you try it and run into problems, you're not alone, but there's not much I can say firsthand as I haven't experienced them myself.

Thanks to the NixOS module, the configuration is fairly intuitive, even if you don't know anything about Coturn or the concept it implements beyond the vague idea of NAT traversal.

coturn = {
  enable = true;
  no-cli = true;
  no-tcp-relay = false;

  # these ports are default, exiplicit here for human reasons
  tls-listening-port = 5349;
  alt-tls-listening-port = 5350;
  listening-port = 3478;
  alt-listening-port = 3479;

  # port range for clients communications, pick at your option
  min-port = 43000;
  max-port = 43200;

  # to limit users ask for a pre-shared secret string
  use-auth-secret = true;
  static-auth-secret = "Pick a String Of Strange Text";

  # your DNS must resolv this subdomain (choose any name
  # you want, `turn' is just a common choice), ensure A and
  # AAAA records, SRV records are optional for Matrix
  realm = "turn.domain.tld";

  # not a good Nix practice, but quick and simple
  # ACME module save certs there
  cert = "/var/lib/acme/turn.domain.tld/full.pem";
  pkey = "/var/lib/acme/turn.domain.tld/key.pem";
  extraConfig = ''
    fingerprint
    allowed-peer-ip=192.168.100.1 # server internal IP
    external-ip=turn.domain.tld # server IP grabbed via DNS

    # ban private IP ranges
    no-multicast-peers
    denied-peer-ip=0.0.0.0-0.255.255.255
    denied-peer-ip=10.0.0.0-10.255.255.255
    denied-peer-ip=100.64.0.0-100.127.255.255
    denied-peer-ip=127.0.0.0-127.255.255.255
    denied-peer-ip=169.254.0.0-169.254.255.255
    denied-peer-ip=172.16.0.0-172.31.255.255
    denied-peer-ip=192.0.0.0-192.0.0.255
    denied-peer-ip=192.0.2.0-192.0.2.255
    denied-peer-ip=192.88.99.0-192.88.99.255
    denied-peer-ip=192.168.0.0-192.168.255.255
    denied-peer-ip=198.18.0.0-198.19.255.255
    denied-peer-ip=198.51.100.0-198.51.100.255
    denied-peer-ip=203.0.113.0-203.0.113.255
    denied-peer-ip=240.0.0.0-255.255.255.255
    denied-peer-ip=::1
    denied-peer-ip=64:ff9b::-64:ff9b::ffff:ffff
    denied-peer-ip=::ffff:0.0.0.0-::ffff:255.255.255.255
    denied-peer-ip=100::-100::ffff:ffff:ffff:ffff
    denied-peer-ip=2001::-2001:1ff:ffff:ffff:ffff:ffff:ffff:ffff
    denied-peer-ip=2002::-2002:ffff:ffff:ffff:ffff:ffff:ffff:ffff
    denied-peer-ip=fc00::-fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
    denied-peer-ip=fe80::-febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff
  ''; # extraConfig
}; # coturn

Now we need the relevant fw setup for this service, a simple NFTable extras could be

# coturn listening-port
udp dport 3478 accept
tcp dport 3478 accept

# coturn tls-listening-port
udp dport 5349 accept
tcp dport 5349 accept

# coturn alt-listening-port
udp dport 3479 accept
tcp dport 3479 accept

# coturn alt-tls-listening-port
udp dport 5350 accept
tcp dport 5350 accept

# coturn client signaling port range
udp dport { 63000-63100 } accept
#tcp dport { 63000-63100 } accept

# matrix port, here just to put all in one place...
tcp dport 8448 accept

for both IPv4 and IPv6 (if you have and anyone should) of course. Finally the NGINX proxy pass for Coturn.

virtualHosts."turn.domain.tld" = {
  enableACME = true;
  forceSSL = true;

  locations."/" = {
    # pick the right port for you
    proxyPass = "http://127.0.0.1:5349";
    proxyWebsockets = true;
    extraConfig = ''
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_read_timeout 3600s;
        proxy_send_timeout 3600s;
        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 $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header  Host $host;
        proxy_pass_header Authorization;
      ''; # extraConfig
  }; # locations."/"
}; # virtualHosts."turn.domain.tld"

Tuwunel

Given that the configuration will be practically the same regardless of which Matrix server you choose, adapting it between them is fairly straightforward

matrix-tuwunel = {
  enable = true;

  user = "tuwunel";
  group = "tuwunel";

  stateDirectory = "tuwunel";

  settings = {

    global = {

      # again choose as you like, just ensure the DNS is set up correctly,
      # again A and AAAA records, SRV are optional.
      server_name = "matrix.domain.tld";

      database_backup_path = "/var/lib/tw-backup";
      database_backups_to_keep = 1;
      new_user_displayname_suffix = "🥚";
      address = ["127.0.0.1" "::1"];
      port = [8489];

      allow_registration = true;

      # to be given to aspiring new users, they will be asked for it when
      # they register (make it a bit more safe than 2 words obviously)
      registration_token = "Another Secret";

      allow_encryption = true;

      # choose here, allowing means been able to communicate with all
      # federated matrix servers, the contrary means being tied to
      # this very server
      allow_federation = true;

      # for users, admins are always allowed
      allow_room_creation = true;

      grant_admin_to_first_user = true;
      federate_admin_room = false;

      # other servers to trust for keys of federated users
      # unfortunately mandatory to start...
      trusted_servers = [ "matrix.org" ];

      # the same you put in Coturn config, obviously
      turn_secret = "Pick a String Of Strange Text";

      turn_uris = [
        "turns:turn.domain.tld:5349?transport=udp"
        "turns:turn.domain.tld:5349?transport=tcp"
        "turn:turn.domain.tld:3478?transport=udp"
        "turn:turn.domain.tld:3478?transport=tcp"
      ]; # turn_uris

      well_known = {
        # the NGINX vhost listening for incoming client conn.
        client = "https://matrix.domain.tld:8448";
        server = "matrix.domain.tld";
      };

    }; # global
  }; # settings
}; # matrix-tuwunel

And again the relevant NGINX vhost

# tuwunel
virtualHosts."matrix.domain.tld" = {
  enableACME = true;
  forceSSL = true;

  listen = [
    # matrix clients expect 8448 and 443
    { addr = "0.0.0.0"; port = 8448; ssl = true; }
    { addr = "0.0.0.0"; port = 443; ssl = true; }
  ];

  extraConfig = ''
    merge_slashes off;
  '';

  locations = {

    "/" = {
      proxyPass = "http://127.0.0.1:8489";

      extraConfig = ''
        proxy_buffering off;
        proxy_set_header  Host $host;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
        client_max_body_size 150m;
      ''; # extraConfig

    }; # "/"

  }; # locations

}; # virtualHosts."matrix.domain.tld"

final touches

To allow Coturn and Tuwunel access to relevant SSL certs since ACME save them with it's system username and NGINX group (to allow NGINX reading them) the simplest thing is adding to system Coturn and Tuwunel groups the NGINX group. So:

users.users.turnserver.extraGroups = [ "nginx" ];
users.users.tuwunel.extraGroups = [ "nginx" ];

ACME config depend on your DNS provider, a generic example could be

acme = {
  acceptTerms = true;

  defaults = {
    email = "admin@domain.tld";

    # pick one from the list
    dnsProvider = "ovh";
    # the same
    credentialsFile = "/run/secrets/ovh.api";
  }; # defaults

  certs."domain.tld" = {
    domain = "domain.tld";
    group = "nginx";
    extraDomainNames = [
      "turn.domain.tld"
      "matrix.domain.tld"
    ]; # extraDomainNames
  }; # certs."domain.tld"
}; # acme

Register side, typically in it's WebUI you have to create an API key, assign some permissions to it, like GET, POST and DELETE etc. I can't document this part since depend on your provider, while most operate in nearly identical manners.

Clients

Once done well... You are ready to create the first user via a client, maybe like Element Desktop, and announce to your family and friends the possibility to interact with a Matrix client on your new server.

Users could register themselves providing the shared Tuwunel secret you give to them, obviously choosing as homeserver matrix.domain.tld and not the default matrix.org or something else.

If you federate they can join rooms and spaces (collection of rooms) in other servers, at the price for you of hosting other servers contents, the one of the chosen rooms/spaces, who could bit little or big and could be legal or illegal.

Encrypted rooms cant' be read by the server admin, so well... Choose depending on the kind of server you want to host.