De Debian à NixOs

Quand j’étais jeune le débat était: programmation spaghetti vs programmation structurée. Ça parait irréel mais quand on a 1ko de mémoire et 8ko de rom l’art du jonglage est plus prisé que l’art de la structure. Aujourd’hui le débat est programmation procédurale vs programmation fonctionnelle pure. Ce ne sera plus un débat dans quelques dizaines d’années et on se demandera comme les gens ne voyait pas cette évidence.

On vit la même chose pour les distributions: ça a commencé par pas grand chose de plus que le référencement de fichiers tar pour devenir de plus en plus conceptuel afin d’apporter de la cohérence, de la sécurité et de l’ergonomie. Un saut majeur est réalisé par NixOs. Le même saut que le passage de la programmation procédurale à la programmation fonctionnelle pure (qui est au cœur de NixOs).

NixOs a une représentation conceptuelle de la distribution: une installation est le résultat d’une fonction pure qui prend en argument la description de ce que vous désirez avoir. En pratique vous décrivez ce que vous désirez avoir dans des fichiers dans /etc/nixos et nixos l’installe.

Par exemple:

  • Pas de “apt-get install thunderbird”, vous écrivez “thunderbird” dans une liste dans un des fichiers dans /etc/nixos. Donc vous n’avez plus à mémoriser ce que vous avez installé ou configuré, tout est dans /etc/nixos. Gros SOULAGEMENT!
  • Même si vous installez apache2, tout se fait dans /etc/nixos, mais vous pouvez reprendre des grandes parties de configuration apache, on peut voir NixOs comme, entre autres, une surcouche à toutes les configurations se trouvant dans etc.
  • Fini les problèmes de configuration du type “il faut mettre ça avant ça” ou “ce flag est à true donc on ne peut pas définir ce paramètre”: Le langage Nix est mathématique et les incohérences sont détectées ou impossibles.
  • NixOs fournit une archive de taille paramétrable des installations antérieures, donc si vous avez cassé quelque chose il suffit de booter sur une ancienne version (le menu du boot est mis à jour).
  • D’un ordinateur on peut en configurer et gérer d’autres (ou des conteneurs), autant que l’on veut. Fini l’IP de la gateway ou le nom du réseau local dupliqué: vous pouvez l’écrire à un endroit unique.
  • Dupliquer une installation est super simple puisqu’elle est entièrement décrite.
  • Quand le langage de configuration d’un logiciel est archaïque (comme l’excellent rsnapshot), vous pouvez utiliser le langage Nix pour contourner les problèmes.
  • NixOs compartimente les paquets, cela évite les problèmes d’incompatibilité et permet d’installer plusieurs versions (par exemple plusieurs PosgreSQL ou plusieurs apache2). Fini les “je veux bien t’installer ceci mais il faudra déinstaller cela”. Il permet quand même de partager des fichiers identiques entre paquets.
  • Le côté très structuré favorise la sécurité. Par exemple créer un paquet est une description : url des sources, dépendances etc. Les possibilités d’introduire des vulnérabilités sont réduites. Par exemple pour apache2, le mainteneur n’a de liberté que dans la production de ce fichier nix (accessible par le lien “Source” sur https://search.nixos.org/packages. Vous pouvez facilement vérifier par vous même que le mainteneur n’a pas introduit de vulnérabilité.


Quelques concepts

Un fichier .nix

Votre répertoire /etc/nixos (le chemin est un standard mais il peut être ailleur) sera peuplé de fichiers “.nix” que vous organisez comme vous le souhaitez. Un “.nix” est simplement un bout de code en langage Nix même si souvent ça ressemble à un fichier de configuration. Et comme Nix est un langage fonctionnel pure un bout de code nix est toujours une valeur (un nombre, un ensemble d’attributs, une fonction etc). Cela rend la description de vos machines très libre. Très souvent un .nix est une fonction, par exemple:

{ host }:
{
        boot_partition="BOOT_RESC";
        root_partition="rescue";
        pruneGenerations = host.zone.pruneGenerations.enduser;
}

La partie { host }: indique que c’est une fonction à un argument (host).
Le reste “{ …. }” est la valeur retournée par la fonction, ici un ensemble d’attributs.
Mais ce .nix est aussi valide “{x,y}:x+y”, c’est la fonction addition. Cette fonction prend en argument une ensemble d’attributs et retourne un nombre.
Mais on peut définir une fonction prenant directement les nombres: “x: y: x+y”. Ça se lit: c’est la fonction qui prend x en argument et qui retourne la fonction qui prend y en argument et qui retourne x+y. Par exemple:

let 
  add_v1= {x,y}:x+y;
  add_v2= x:y: x+y;
in
  (add_v1 {1,2}) + (add_v2 3 4)

Est une valeur qui vaut 10. (add_v2 3) est une fonction, elle ajoute 3 à son argument. Par exemple:

let
  add_v2= x:y: x+y;
  f = add_v2 3;
in
  f 4

Est une valeur qui vaut 7.

/etc/nixos/flake.nix

Quand on utilise Flakes (c’est optionnel mais devient un standard), le fichier flake.nix (nom conventionnel) contient la description des différents ordinateurs. Pour que NixOs fournisse une fonction pure (sans effet de bord) alors que les paquets peuvent changer, il faut fournir en argument les paramètres décrivant “de quoi on part”. C’est pourquoi un flake.nix comporte deux parties: inputs et outputs. C’est à dire : de quoi ont part et ce que l’on obtient. Donc vous dites que vous partez de telle version de NixOs (inputs) et dans outputs vous décrivez les machines que vous désirez.

Dans ce petit exemple on part de la distribution instable de NixOs et de “nur” puis ont décrit les machines (une seule ici). “mysystem” est le nom de la machine, elle est décrite dans “configuration.nix” et pourra utiliser “inputs” comme argument dans ses fonctions.

Pour que ce flake.nix soit une fonction pure il manque une chose: en effet la distribution change et produirait donc des installations différentes. C’est pourquoi un /etc/nixos/flake.lock est créé automatiquement à la première interprétation pour fixer la version. Donc si vous recopier votre /etc/nixos sur une autre machine cela produira la même installation aux mêmes versions de logiciels.
Le principe de flake.nix sert aussi à tout ce qui “produit à partir de”. Par exemple on peut utiliser un flake.nix pour produire un package.

Organisation

Nous avons vu que nous pouvons organiser la configuration de manière très libre. Voici une base d’organisation que je trouve confortable et puissante. Imaginons la gestion de toutes les machines de GreenPeace:

  • zone/<nom-zone>/host/<nom-machine>: le répertoire de configuration d’une machine. On découpe en zones, par exemple “paris” pour le siège à Paris.
  • lib/ : vos .nix partagés entre machines
  • store/ : vos fichiers non .nix partagés

Chaque zone pourra aussi avoir un dossier lib, store etc si il y a des spécificités.

Vous avez aussi besoin de paramètres, au niveau du host, de la zone et globalement. Exemple de paramètres: l’email de l’administrateur principal ou des IPs de DNS. C’est une très bonne chose de séparer les paramètres du reste car ils peuvent être utilisés par vos librairies. On utilisera le même découpage:

  • organisation.nix : le fichier principal de configuration de greenpeace (comme le nom, l’email de l’administrateur principal etc).
  • zone/<nom-zone>/zone.nix : les paramètres de la zone.
  • zone/<nom-zone>/host/<nom-machine>/host.nix : les paramètres de la machine.

Pour éviter que les librairies aient trois arguments (orga,zone,host) et pour rendre le système plus souple je trouve préférable que chaque host.nix reprenne les paramètres de la zone (par une variable “zone”) et la zone de l’organisation. Ainsi “host” contient tous les paramètres.

Unix/Linux safe remote commands

Do you need to execute some commands from batch scripts on a remote host but don’t want to allow full shell access? For a single command, you can use sshd’s ForceCommand, but it allows only one command per account. This text explains how you can execute safe, remote, limited multiple commands.

The trick :

  • Create a special, unique, passwordless user for remote commands, such as “sudo_lover”.
  • ForceCommand‘ runs a Python script named “use_sudo,” which acts like a safe version of “sudo $SSH_ORIGINAL_COMMAND”. You can configure allowed commands with sudo.
  • use_sudo‘ logs commands (auth.log), making it easy to add a command by almost a copy and paste (for example, configuring rsync without the log would be almost impossible).

One drawback is the difficulty in redirecting STDOUT/STDERR. To redirect STDOUT, I use a second program named “out_to,” which takes the file to redirect to and the command to execute.

cat use_sudo
#!/usr/bin/python3
import os
import shlex
import logging
import logging.handlers
from logging.handlers import SysLogHandler

# logger configuration : auth.info
syslogHandler = logging.handlers.SysLogHandler(address='/dev/log', facility="auth")
formatter = logging.Formatter('use_sudo: %(levelname)s - %(message)s')
syslogHandler.setFormatter(formatter)

logger = logging.getLogger('use_sudo')
logger.setLevel(logging.INFO)
logger.addHandler(syslogHandler)

command_from_env = os.environ.get("SSH_ORIGINAL_COMMAND")
if(not command_from_env):
    print("SSH_ORIGINAL_COMMAND is undefined.")
    exit(1)
command_with_arguments = shlex.split(command_from_env)
logger.info(str(command_with_arguments))

command_for_sudo = [f"/usr/bin/sudo -n {command_with_arguments[0]} ...",'-n'] + command_with_arguments
os.execv("/usr/bin/sudo", command_for_sudo)

cat out_to
#!/usr/bin/python3
import os
import sys
import subprocess

arguments = sys.argv
outfile=arguments[1]
command = arguments[2:]
with open(outfile, 'w') as outfile_h:
    try:
        subprocess.run(command, stdin=sys.stdin, stdout=outfile_h, stderr=sys.stderr, check=True)
    except subprocess.CalledProcessError as e:
        print(f"Error while executing : {e}")

Pain au levain : c’est bien plus facile qu’on ne le dit

mon levain

Il existe déjà beaucoup de ressources sur le pain au levain mais j’ai rarement vu cette information: il est difficile de louper son pain au levain. J’en fais depuis des années, des petites fournées (environ 2kg) et quelques fois plus grosses (environ 6kg), j’ai essayé beaucoup de choses et j’ai très rarement eu des déboires malgré mon laxisme et mes expérimentations (que je décris plus bas).

Alors pourquoi voit-on tant de recettes qui peuvent donner l’impression que c’est difficile ? Je pense que ça vient de quelques biais cognitifs comme le biais de complexité.

Le laissé allé qui ne pose pas/peu de problème

mon pain
  • Mettre de l’eau du robinet directement. L’eau contient du chlore qui est un désinfectant et a donc tendance à détruire le levain, mais en pratique je n’ai pas eu de problème (il n’y a probablement pas assez de chlore pour tout tuer).
  • Mettre de l’eau froide. On met bien le levain au frigo, il sera plus vigoureux avec de l’eau tiède et donc ça va temporairement un peu le calmer, mais ça va.
  • Faire un seul pétrissage. J’ai la flemme de pétrir plusieurs fois et je trouve que j’ai du (très) bon pain avec un seul, donc je pétris puis je mets en moules.
  • Laxisme sur les durées : on aura plus ou moins de travail du levain, mais tant qu’il a levé ça va. J’ai même connu un boulanger qui faisait du pain avec un très gros travail du levain qui rendait le pain assez acide, et il le vendait bien.
  • Quantité d’eau. J’ai toujours fait au pif et les variations peuvent être franchement importantes. L’élasticité obtenue par pétrissage quand il y a du gluten est certes bien agréable au touché, et c’est un indicateur d’un pétrissage suffisant, mais c’est tout, on peut faire du très bon pain avec une pâte poisseuse. Par contre l’eau a une influence sur la levée et une pâte ferme aura tendance à moins lever et surtout moins gonfler dans le four (mais ça va très bien quand même).
  • Oublier de fendre le dessus avant la levée : il s’ouvrira de manière moins pratique et moins esthétique mais ça va.
  • Laisser le levain longtemps au frigo (2/4 semaines). Il suffit d’un peu de levain encore vivant pour faire repartir la bête. Mais il m’ait arrivé de le perdre après des vacances.
  • Ne pas mettre d’eau dans le four : la flemme, je ne le fais pas, à la place je fais une pâte assez humide et j’humidifie bien le dessus après la mise en moule.
  • Congeler le pain : ça marche si bien pour le pain complet qu’il serait bien difficile de dire qu’il a été congelé.

Mes petits déboires

  • Oublier de prendre du levain chef. Erreur fatale :). Pour ne pas oublier je mets le récipient à levain à un endroit stratégique et avec le temps je n’oublie plus.
  • Contamination : en plein été, sous environ 30°C, ça a tourné (l’odeur ne laissait aucun doute), probablement un mauvais lavage des mains de ma part avant pétrissage. Une bonne habitude est de toujours sentir voir goûter. Le levain est vivant et on en apprend beaucoup en le sentant (odeur d’alcool = j’ai la dalle, odeur un peu aigre = j’ai bien mangé).
  • Panaris : il faut se laver les mains méticuleusement après pétrissage, j’utilise maintenant une brosse à ongle puis une brosse à dent pour la finition.

Vive l’expérimentation et la qualité

Vous pouvez mettre plein de sortes de farines, de graines, des amandes, noisettes, raisins etc. Il y a beaucoup de choses possibles et en général ça sera bien meilleur que ce que produit le boulanger moyen. Vous pourrez aussi diminuer le sel (surtout avec du pain goûteux) et ainsi prolonger votre vie. Vous pourrez acheter des ingrédients de qualité pour avoir du pain de luxe à moindre coût.

Moi aussi je le bichonne

Comme la plupart des personnes faisant son pain au levain, j’aime à faire des extras pour essayer de rendre mon levain heureux et avoir ainsi du meilleur pain. Par exemple je fait reposer l’eau pour que le chlore s’évapore ou encore je le nourris tous les jours (je parts de très petit pour que ça corresponde au temps inter-fournées sans avoir à jeter). Ais-je ainsi améliorer la qualité ? J’aime à le croire mais je suis loin d’en être sûr.

Impôts français : comprendre le formulaire 2086 de déclaration des + et – values sur les actifs numériques

Objectif et avertissement

Remplir le formulaire 2086 est tellement problématique que je n’ai pas trouvé d’explications sur les parties posant problème. En général les articles sur le sujet dirigent vers des logiciels, écrivent que c’est compliqué mais n’expliquent pas la partie difficile. Les logiciels sont souvent payants et ou intrusifs, sauf CryptoFiscaFacile et coin2086 mais ces dernier demandent un peu de connaissances informatique et coin2086 ne prend pas en compte les trades crypto/crypto.

Cette page n’a pas pour but d’expliquer tout autour de la déclaration des pertes et revenus liées aux cryptomonnaies, mais juste la partie qui n’est pas expliquée ailleurs et qui est difficile à comprendre. Pour faciliter la compréhension je néglige les calculs de soulte (je pense que c’est rarement utilisé) et de frais.

D’autre part j’avertis que je suis un particulier et que je peux me tromper, c’est à vous d’apprécier la justesse de ce document et je ne suis en aucun cas responsable des erreurs que vous pourriez produire du fait de cette lecture. Ce document a pour but de permettre la compréhension et non de fournir une méthode.

L’idée du ministère des finances

À la base l’idée est louable : ne pas rentrer dans le détail des opérations pour ne pas avoir à gérer la complexité des transactions. Pour cela on doit considérer l’ensemble du portefeuille crypto. Mais comme il faut calculer les gains et les pertes, quand on vend une partie de ce portefeuille, il faut connaître le prix de vente mais aussi le prix d’achat de la partie vendue. Pour éviter d’entrer dans les détails du portefeuille il faut utiliser non pas le prix d’achat réel de la partie vendue, mais le prix d’achat du portefeuille total juste avant la vente ainsi que la proportion vendue de ce portefeuille.

Comment est réalisé le calcul “plus-values et moins-values”

Omettons les informations secondaires comme les frais et soultes: la plus value est la somme en euros récupérée de la vente moins son prix d’achat (en considérant toujours la partie vendue comme une proportion du porte-feuille). Pour calculer ce prix d’achat on doit calculer la proportion du portefeuille vendu : c’est le “(ligne 217 : montant vendu) / (ligne 212 : valeur du portefeuille au moment de la vente)” et la multiplier par le prix d’achat total du portefeuille, c’est le “(ligne 223)”. Par exemple si on a acquis 1000€ de cryptomonnaie et que “(ligne 217) / (ligne 212)” = 300/1200= 0,25, alors c’est que l’on considère que l’on vend 1/4 du portefeuille, donc si on vend pour 300€ cela fait un profit de 300-1000×0,25=50€.

Du besoin de calculer le “prix total d’acquisition du portefeuille”

Comme on vient de le voir, il est nécessaire d’avoir la notion de “prix d’achat du portefeuille” actuel afin de déterminer le prix d’achat de la fraction vendue. Mais un portefeuille subit des mouvements de ventes et d’achats. Pour réaliser ce calcul, l’idée est d’additionner tous les achats en euros de cryptomonnaies depuis le début (pas seulement l’année en cours), c’est la ligne 220, cela détermine le prix d’achat (en €) cumulé du portefeuille. Puis de retrancher de ce total les prix d’achat des parties déjà vendues. La somme des prix d’achat des parties déjà vendues est la ligne 221. Cette ligne est déroutante car elle est nommée “fractions du capital initial” et sa définition m’est incompréhensible (et contient une coquille pour ajouter à la difficulté (ou -> où)) mais on voit dans la fin de leur exemple que c’est bien ce dont je parle.

Il vous faudra donc, à chaque cession, récupérer le prix d’achat de la proportion du portefeuille vendu, c’est à dire “[(ligne 223)*((ligne 217)/(ligne 212))]”, de manière à cumuler ces valeurs, ce cumul étant la ligne 221 : “Fractions du capital initial contenues dans le prix total d’acquisition” (si vous vous sentez mal c’est normal, lol).

Du besoin de calculer la valeur totale du portefeuille au moment de la vente

Comme on l’a vu dans le calcul de la plus value (ligne 212), le calcul de la proportion du portefeuille vendu implique le calcul de la valeur du portefeuille (total) au moment de la vente. Il faut donc tous les cours de toutes vos cryptos pour chaque vente!

Exemple et étalage des profits

  1. Achat de 1000€ d’ETH, achat de 1000 000€ de EUR-L (stable coin €).
  2. Vente des ETHs qui ont doublés: 2000€ de vente,
    proportion (ligne 217)/(ligne 212) = 2000/1 002 000,
    prix d’acquisition net (ligne 223) = 1 001 000,
    profit 2000-(1 001 000*(2000/1 002 000))=2€ (normal, voir la suite).
    Prix d’achat de la proportion du portefeuille vendu = (ligne 220)*((ligne 217)/(ligne 212)) = 1 001 000 * 2000/1 002 000 = 1998 (ça serait 1000 si on séparait les ETH des EUR-L, mais on doit raisonner globalement).
  3. Vente des EUR-L :
    proportion 1000 000/1000 000=1.
    Prix total d’acquisition (ligne 220)= 1 001 000.
    (ligne 221) partie du prix d’acquisition déjà vendu = 1998 (récupéré du 2.).
    (ligne 223) = (ligne 220) – (ligne 221) = 1 001 000 – 1998 = 999 002.
    Plus value = 1 000 000 – 999002 * 1000 000/1000 000 = 998€

On retrouve donc bien au final les 1000€ de profit des ETHs, mais le mode de calcul global a différé la prise en compte du bénéfice.

Questions ouvertes

Merci d’utiliser les commentaires pour aider à y répondre.

Simplification possible du “prix total d’acquisition du portefeuille” ?

Il parait bizarre d’accumuler (ligne 220) tous les achats, avec les années ça peut représenter une somme importantes si les transactions sont nombreuses et imposer de garder des justificatifs indéfiniment. Le document ne précise pas si c’est antérieurement dans l’année fiscale ou de manière absolue. De plus le but étant d’avoir la différence (ligne 220) – (ligne 221), correspondant au prix total d’acquisition net, on arrive d’après moi au même résultat si chaque année on oublie la partie déjà traitée, c’est à dire que l’on part en début d’année avec une ligne 221 à 0 et un prix total d’acquisition (ligne 220) purgé de la partie déjà vendus les années antérieures. Une autre possibilité de simplification serait de remettre à 0 quand on vend tout.

Cessions multiples et proches

Certaines fonctions des exchanges (Kraken , Binance etc) permettent de négocier une vente en directe avec les acheteurs ce qui peut séparer la vente en de multiples parties à des prix différents. Je suppose que l’on peut regrouper en une seule vente si tout a lieu le même jour ?

Ressources

Vidéo youtube

Notice officielle

How to route specific traffic through a VPN on Linux with nftables

Introduction

Here I explain a strong solution to route traffic to a VPN using the group of the processes. We discuss security at the end. After the configuration, if you want to run ktorrent using the VPN you just have to run sudo -g vpn_euro ktorrent. You will be able to use serveral VPN and no VPN the same time, per process.

Continue reading How to route specific traffic through a VPN on Linux with nftables