Author: Pedro Lucas Porcellis <porcellis@eletrotupi.com>
wip
content/blog/a-magia-do-git-rebase.en.md | 129 content/blog/anunciando-hidrocor.md | 8 content/blog/comunidades-foss-devem-ser-construidas-com-foss.en.md | 83 content/blog/comunidades-foss-devem-ser-construidas-com-foss.md | 68 content/blog/minitest-a-elegancia-da-simplicidade.md | 7 content/blog/protonmail-e-a-falsa-privacidade.en.md | 92 content/new-server.html | 214 dynlib.html | 369 editing.html | 99
diff --git a/content/blog/a-magia-do-git-rebase.en.md b/content/blog/a-magia-do-git-rebase.en.md new file mode 100644 index 0000000000000000000000000000000000000000..c04e6b65c4c22763bb922f682e79ac525a71a0e8 --- /dev/null +++ b/content/blog/a-magia-do-git-rebase.en.md @@ -0,0 +1,129 @@ +--- +title: "The wonders of Git Rebase" +date: 2021-04-29 +draft: false +tags: ["git"] +--- + +One of the tools I find more useful on `git`, and which [I love the most][toot] +is `git-rebase(1)`. It works around the premise that originally bought git to +control version systems: that you *can and should* rework your repository +history, to make it more organized and readable. + +[toot]: https://alfazema.club/@eletrotupi/105984543604974096 + +Around the world, each project stablish its one convention of how to work with +git, some of them use techniques like git-flow, others, just a branch and tags, +others divide between `master/main` and a `production/release` branch. The +company I work for convention is to always create a specific branch to work on a +new feature, bug fix or whatever. Having done that, I adopt the discipline to +(1) keep it up to date with the parent branch using `git pull --rebase +origin/parent_branch` and (2) as I work on it, I try to keep it tidy using `git +rebase -i HEAD~N`. + +## Rebase + +The rebase command has a very simple behavior, essencially it does not execute a +merge (or does not generate a commit that introduces the changes upstream unto +your local copy), rebase temporally remove all your work, pull newer commits +unto your branch and then sequencially applies your patches on this updated +branch state. The benefit being: the branch ends up updated and only contains a +list of your newer commits, on a very coherent and readable way. + +The `-i` parameter on the command, is a shortcut for git start a interactive +rebase, starting from the commit I have asked for [^1]. For example, `git rebase +-i HEAD~5` will start a rebase up until my last 5 commits. It will proceed to +show you this: + +[^1]: `HEAD~N`, means essencially from my HEAD commit up until N commits before + this. + +```ini +pick 9fdd140 hooks: Flesh out the Hook::Destroy service test +pick ecb296e resource: Flesh out the resource test +pick bd115a0 hooks: Generate token when subscribing +pick fcaba9d hooks: Flesh out the handler test +pick 3926d4b doc: Add document about testing + +# Rebase bed2ff9..3926d4b onto bed2ff9 (5 commands) +# +# Commands: +# p, pick <commit> = use commit +# r, reword <commit> = use commit, but edit the commit message +# e, edit <commit> = use commit, but stop for amending +# s, squash <commit> = use commit, but meld into previous commit +# f, fixup <commit> = like "squash", but discard this commit's log message +# x, exec <command> = run command (the rest of the line) using shell +# b, break = stop here (continue rebase later with 'git rebase --continue') +# d, drop <commit> = remove commit +# l, label <label> = label current HEAD with a name +# t, reset <label> = reset HEAD to a label +# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>] +# . create a merge commit using the original merge commit's +# . message (or the oneline, if no original merge commit was +# . specified). Use -c <commit> to reword the commit message. +# +# These lines can be re-ordered; they are executed from top to bottom. +# +# If you remove a line here THAT COMMIT WILL BE LOST. +# +# However, if you remove everything, the rebase will be aborted. +# +``` + +That means, it will show my last five commits, and ask me what I want to do with +them, presenting me the options to pick, remove or edit (`edit` or `reword`) or +join them (`fixup`, `squash`). + +## Discipline + +My work plan, usually is the following: as I keep advancing on my work, I commit +them locally, in a very vague way so I can understand what sort of milestone +that represents. Whenever I feel I can present this work upstream I use _rebase_ +to rewrite, split or join commits forming a narrative of coherent and readable +sequential steps. + +Seeking to write this narrative, I strive to write atomic changes that themself +are capable of answer the question of _what has been done?_ and _will this break +the tests that exists?_ [^2] + +[^2]: That means no `fix tests` or `fix typo` commits. + +A experience that has helped me a lot on this purpose, was to contribute to +projects that utilize a public developer mailing list [^3], sending patches +instead of creating Pull Requests. Specially because the work logic changes with +that. The way to work presented by tools like Github, GitLab and other similar +derivations is to create a PR and keep adding commits _ad infinitum_ until the +work on it is ready to merge. Yet, the logic behind git via email is of trying +to be assertive as possible, avoiding sending giant patchsets [^4] with changes +all over the place. One of the ways to deal with patchsets is that is possible +to apply only a subset of the overall changes presented, and ask revision for +specific patches that need some more work. + +[^3]: Which is the way git has been designed to work, notable mailing list + driven developments examples are the Linux Kernel, git, cgit, dwm and other + suckless tools, Que é o formato de contribuição do qual o git foi feito para + funcionar originalmente, coreutils, musl-libc, freedesktop, vim, emacs, *BSD + and many others. + +[^4]: A patch is a commit, and a patchset is a collection of patches, somewhat + akin to a PR. + +Applying this logic, I strive to break a long patchset into several different +patchsets [^5], each one with the most possible atomic patches, with a good +description, organized by modules or systems [^6]. + +[^5]: A example here could be organize _includes_, remove white spaces or any + other cosmetic changes on the source code that hasn't a direct connection to + what I was originally writing. + +[^6]: I generally like to use the following format for my commits: `system: + subsystem, description of what this commit does` and describe why this change + is necessary and my approach on the commit message. + +Concluding: git is fantastic. Having discipline to utilize it and learn how it +works is a must for any programmer. One of the main differences between git and +other VCS before him is that the history of the repository is not written in +stone, is not read-only. Besides that, git has an extensive offline +documentation on its manpages available to you to study it. I would strong +recommend you to read git-rebase(1), giteveryday(7) and gitrevisions(7). diff --git a/content/blog/anunciando-hidrocor.md b/content/blog/anunciando-hidrocor.md new file mode 100644 index 0000000000000000000000000000000000000000..3f347ba33e6c2e65f72d533950fa29f72aecc0c5 --- /dev/null +++ b/content/blog/anunciando-hidrocor.md @@ -0,0 +1,8 @@ +--- +title: "Anunciando: hidrocor" +date: 2021-10-03 +draft: false +tags: [] +--- + + diff --git a/content/blog/comunidades-foss-devem-ser-construidas-com-foss.en.md b/content/blog/comunidades-foss-devem-ser-construidas-com-foss.en.md new file mode 100644 index 0000000000000000000000000000000000000000..5dc625af36bfbd17bfc5352ab4ad864425ee2574 --- /dev/null +++ b/content/blog/comunidades-foss-devem-ser-construidas-com-foss.en.md @@ -0,0 +1,83 @@ +--- +title: "Comunidades Foss Devem Ser Construidas Com Foss" +date: 2021-06-17T00:19:43-03:00 +draft: true +tags: [] +--- + +Recently, I've been noticed that some free software communities have been set a +foot unto proprietary platforms [^1]. + +<details> + <summary>Disclaimer</summary> + + <p> + In this article I'll be using interchambeable the terms <strong>free + software</strong> and <strong>open source</strong>. The reason is to use a + single word, even though I comprehend they represent different concepts. + </p> +</details> + +[^1]: O [libera.chat]() por exemplo, se tornou o lar de projetos FOSS, mas mantém + seus perfis oficiais em lugares como o Facebook e Twitter + +This annoys me for a very obvious reason: I don't expect that a free software be +anchored on a proprietary platform. It seems to me undoubtedly incoherent. Few +people perceive that, but each free software brought unto this world, serves as +a contra-point to it's proprietary peer, a contra-point that believes that the +commoning and the collective is better than individual and property. + +With that in mind, it's at least strange when a community of a free +software/hardware is organized around or participate of a proprietary platform. + +Some makers, will argue about lacking of good free software to built +communities, and that proprietary software are more friendly, or even that "it's +where our community is". Look, according to the FSF's definition of free +software or even OSI, one of the most crucial points is the fact that free +software empowers people to collaborate, it allows you to contribute directly +with this software. Using this path, you can not only directly build and improve +this so called "bad platforms", the mere act of using them, can help to validate +and boost whoever built or maintain it. + +So, if I'm a FOSS developer and whish that the options of free software +proliferate, and that the quality improve and that the ecosystem as a whole +flourishes, it is necessary that I bet my horses on the options that exists +today, and that I build together as well. This bet is only _part of the process_ +and can't be see as a mere accessory. + +There are dozens of tools built on open protocols, standardized and portable +between different architectures, OSes, etc. Tools that are not isolated into +some proprietary software, surrounded with walls, harvestening everyones data +and even inacessible for a part of people that wishes to be part of your +community. + +Some tools, like Discord are well known to + +proliferate, you have to cast your lot with more open source tools. They're +equally suited to the task as, say, Discord. + +Choosing proprietary tools and platforms can also easily serve to reduce your +pool of potential contributors who don't want to use proprietary tools, and +especially those who don't want to install proprietary software on their own +computers, like the Discord client. + +Some people simply cannot use something like Discord at all - it has a high +hardware requirements floor, poor to mediocre Linux support and completely +absent support for systems like BSD, not to mention grave accessibility +problems. Only an open protocol enables anyone to build the clients that suit +their needs, and are not dependent on the whims of some corporate board of +director's determination of your merit (i.e. financial exploitability) as a +participant. + +Muitas dessas ferramentas, como por exemplo Discord são conhecidos por exigirem +muitos recursos para pouco benefícios que de fato entregam, lugares como +Facebook também são mundialmente conhecidos por minerar dados e violar a +privacidade dos seus usuários. Qual a justificativa de um software livre +construído como um contra-ponto estar utilizando essas plataformas? + +Escolher participar e construir comunidades em cima de softwares proprietários é +uma escolha contraditória por si só, e ela ameaça justamente afastar as pessoas +dos ideais do pelo qual você construiu o seu software em primeiro lugar, dê a +chance e construa sua comunidade em cima do que é aberto, livre e público. E +contribua para que esse ecosistema como um todo cresça ainda mais, esse é o +espírito do software livre. diff --git a/content/blog/comunidades-foss-devem-ser-construidas-com-foss.md b/content/blog/comunidades-foss-devem-ser-construidas-com-foss.md new file mode 100644 index 0000000000000000000000000000000000000000..63377958df017ff9da90bd491f10b593d8bc653a --- /dev/null +++ b/content/blog/comunidades-foss-devem-ser-construidas-com-foss.md @@ -0,0 +1,68 @@ +--- +title: "Comunidades FOSS devem ser Construidas com FOSS" +date: 2021-06-17 +draft: false +tags: [] +--- + +Recentemente tenho notado que diversas comunidades de software livre [^1] tem se +ancorado em cima de softwares que não são livres tampouco de código aberto. + +<details> + <summary>Aviso</summary> + + <p> + Nesse texto vou mencionar de forma intercambeável software + <strong>livre</strong> e <strong>código aberto</strong>. As razões são + apenas por trabalhar como um único conceito, mesmo conhecendo e + compreendendo as diferenças éticas e conceituais de cada termo. + </p> +</details> + +[^1]: O [libera.chat]() por exemplo, se tornou o lar de projetos FOSS, mas mantém + seus perfis oficiais em lugares como o Facebook e Twitter + +Isso me incomoda por uma razão obvia, eu não espero que um software livre esteja +ancorado em cima de uma plataforma proprietária. Me parece indubitavelmente +incoerente. Poucas pessoas percebem isso, mas a cada software livre trazido +nesse mundo, ele serve como um contra-ponto ao seu par proprietário, um +contraponto que acredita que o _comum_ e _coletivo_ é melhor do que a +individualidade e a propriedade. + +Pensando nisso, é no mínimo estranho quando uma comunidade de um +software/hardware aberto está organizada em torno ou participa de uma plataforma +proprietária. + +Alguns criadores, argumentam da falta de bons software livres para construir +comunidades, que os softwares proprietários são mais amigáveis, ou que é "onde a +comunidade está". Veja bem, de acordo com a definição de software livre da FSF +ou da OSI, um dos pontos mais cruciais é o fato de que permite que as pessoas +possam colaborar, eu posso diretamente contribuir com a construção desse +software. Tendo isso em mente, eu não só posso ajudar a construir e melhorar +essas ditas plataformas ruins, como eu utilizar elas pode inclusive impulsionar +e validar o trabalho feito por quem a criou/mantém. + +Então veja, se eu sou um desenvolvedor de software livre e desejo que as opções +de softwares livres se proliferem, que a qualidade do mesmo melhore e que o +ecosistema como um todo floreie, é necessário que eu aposte meus cavalos nas +opções que existem hoje, e que eu construa junto também. Essa aposta é _parte do +processo_ e não pode ser vista como um mero acessório. + +Existem dezenas de ferramentas construídas em cima de protocolos abertos, +padronizados e portáveis em diferentes arquiteturas, sistemas operacionais, etc. +Ferramentas essas que não estão isoladas em algum software proprietário, rodeado +de muros, lucrando com os dados de todo mundo e inacessíveis para uma parte da +comunidade que deseja poder participar. + +Muitas dessas ferramentas, como por exemplo Discord são conhecidos por exigirem +muitos recursos para pouco benefícios que de fato entregam, lugares como +Facebook também são mundialmente conhecidos por minerar dados e violar a +privacidade dos seus usuários. Qual a justificativa de um software livre +construído como um contra-ponto estar utilizando essas plataformas? + +Escolher participar e construir comunidades em cima de softwares proprietários é +uma escolha contraditória por si só, e ela ameaça justamente afastar as pessoas +dos ideais do pelo qual você construiu o seu software em primeiro lugar, dê a +chance e construa sua comunidade em cima do que é aberto, livre e público. E +contribua para que esse ecosistema como um todo cresça ainda mais, esse é o +espírito do software livre. diff --git a/content/blog/minitest-a-elegancia-da-simplicidade.md b/content/blog/minitest-a-elegancia-da-simplicidade.md new file mode 100644 index 0000000000000000000000000000000000000000..e9cb28838cecc71b2c99e0c5ada547a67de0dcd9 --- /dev/null +++ b/content/blog/minitest-a-elegancia-da-simplicidade.md @@ -0,0 +1,7 @@ +--- +title: "Minitest a Elegancia Da Simplicidade" +date: 2021-04-09T09:40:31-03:00 +draft: true +tags: [] +--- + diff --git a/content/blog/protonmail-e-a-falsa-privacidade.en.md b/content/blog/protonmail-e-a-falsa-privacidade.en.md new file mode 100644 index 0000000000000000000000000000000000000000..0bcc46cb98a0b14cb1add59295a9c137273ed072 --- /dev/null +++ b/content/blog/protonmail-e-a-falsa-privacidade.en.md @@ -0,0 +1,92 @@ +--- +title: "Protonmail and the false sense of privacy" +date: 2021-09-24 +draft: false +tags: ["opinion", "privacy"] +--- + +I like e-mail as a means of communication, specially for three factors: (1) is +built around open protocols (2) is, at a certain degree, universal and the +foundation of having a identity online while being accessible and simple (3) it +exists at least 50 years. With that being said, some necessities arise that +weren't given too much thought when it were created originally: the desire for +privately communicate with others. + +There's a some options to obtain private communication when using email, but +none of those are really simple and when they do present as simple, I usually +get suspicious. For instance, some weeks ago, there was a headline about a +activist going to jail after Protonmail ~~leaked~~ delivered the IP address (and +by which you can obtain the localization of someone) of this activist. It's at +least odd, given that Protonmail advertise itself as if it's **the** way of +"securely sending emails", "regain your privacy", "don't let anyone spy the +content of your emails". In a certain way, posing as a magnificent and +innovative tecnology that with one stroke magically solves the hairy and ugly +problem that is sending emails privately. This is pure marketing, as it seems. + +Some people would even argue that this is a strategy known as _Embrace, Extend, +Extinguish_ and perhaps it is. This strategy works by adopting a technology that +exists already in the wild, "fixing" it and eventually when a large portion of +its users are using the "improved" version, they kill the old one, efectually +locking users at the new, proprietary one. + +The best weapon for this strategy is marketing. You need it to introject into +users the idea that in order to communicate privately, you'll need a Proton mail +account — after all, the rest is arcaic and complex — and barely mentions that +they use open standards and technologies. That anyone with a computer can use: +all you need is to generate a PGP key-pair [^1] and distribute your public key +to other people so they can send you encrypted emails. + +Not only marketing do, of course, there's also the lack of transparent +communication. Instead of doing like Gmail, which practically makes impossible +to send emails using your personal PGP key, Protonmail allows you, but they dont +make it too easy. The only documentation about it, is hidden on a FAQ, and I +only discovered by poking at the docs, which by the way is not even translated. +Not only this, but Proton tricks you into feeling very insecured about doing +this whole process, showing you messages that yell "don't do this, invite this +contact to join our beautiful Proton family instead". + +Além disso, fazer falsas promessas de que eles não guardam nenhuma informação, +contudo esse caso nos mostra que, sim eles guardam seu IP, sabe-se lá o que +mais. + +E o pior problema de todos, é que essas pessoas que utilizam esse serviço, já +estão com seus emails sequestrados, afinal para utilizar o Protonmail você +precisa criar uma conta que te disponibiliza um email `fulano@protonmail.com`. + +Ou seja, se você quiser e precisar migrar para outro domínio, ou outro serviço, +tens que garantir que todos os teus contatos e todos os lugares que +possívelmente queiram entrar em contato com você saibam do seu novo email, o que +não aconteceria se você utiliza um domínio próprio para email +(`fulano@meudominio.com.br`). + +Esse último ponto eu considero grave, porque te priva de conseguir migrar entre +provedores. Se você se sentir ameaçado ou achar que não quer mais usar o +Protonmail, você tem um trabalho longo pela frente para conseguir sair do +serviço, o que em geral faz as pessoas permanecerem, mesmo que não queiram mais +utilizar. + +A solução, infelizmente, não é simples. Privacidade e criptografia é um direito +fundamental, e ele com certeza não deve estar nas mãos de empresas e +corporações. A forma mais simples, mesmo que pareça um absurdo, é de +organizações hospedarem seu próprio serviço de email, dentro do seu domínio e +usuários criarem e distribuirem as suas chaves públicas. + +Sim, você pode hospedar seu próprio servidor de email, basta ter um servidor e +um domínio na internet. Sei que isso parece uma tarefa herculiana, mas não é. A +escolha aqui está mais ligada a decisão entre praticidade versus segurança. +Conforto versus privacidade. + +Se organizações querem lidar com a questão de email, a melhor forma é trabalhar +em conjunto para construir ferramentas abertas que permitam o ecosistema +florescer, trabalhar para criar processos, protocolos e utilitários que tornem +mais simples alguém hospedar seu próprio email. A lógica é construir pontes para +independência e não levantar muros "seguros". + +[^1]: Diversos clientes de email, como o mutt, Mozilla Thunderbird, oferecem de + forma transparente acesso à criptografia PGP, afinal PGP já existe há 30 anos, + e seu formato padronizado e aberto pode ser lido no RFC 4880 (em 88 páginas), + implementações existem à rodo e sua variante mais famosa é o GNU PGP, ou `gpg` + que provavelmente já está instalado em seu computador, seja ele Linux, BSD ou + macOS. O único que como sempre, fica de fora da festa é o Windows, que + necessita do programa `gpg4win` instalado, apesar que ele tem uma interface + gráfica simples e intuitiva ao contrário dos seus irmãos do Unix. diff --git a/content/new-server.html b/content/new-server.html new file mode 100644 index 0000000000000000000000000000000000000000..2850859d3dbf430ad05a8ca54b23150f03e12876 --- /dev/null +++ b/content/new-server.html @@ -0,0 +1,214 @@ +<h1>New Server Checklist</h1> +<label> + <input type="checkbox" /> Set root password +</label> +<label> + <input type="checkbox" /> Generate fresh sshd host keys +</label> +<label> + <input type="checkbox" /> Create admin user +</label> +<label> + <input type="checkbox" /> Add admin to doas group and test doas +</label> +<label> + <input type="checkbox" /> SSH key added to admin's authorized_keys +</label> +<label> + <input type="checkbox" /> Disable root login via ssh +</label> +<label> + <input type="checkbox" /> Disable password login via ssh +</label> +<label> + <input type="checkbox" /> Set hostname +</label> +<label> + <input type="checkbox" /> Run system updates +</label> +<label> + <input type="checkbox" /> Reboot +</label> +<label> + <input type="checkbox" /> Install & test postfix +</label> + +<style> +label { display: block; } +pre { background: #eee; max-width: 720px; padding: 0.5rem; } +</style> + +<h1>doas.conf</h1> + +<pre> +# see doas.conf(5) for configuration details + +# Uncomment to allow group "admin" to become root +# permit :admin +permit nopass :admin +permit nopass deploy cmd apk args upgrade -U +permit nopass deploy cmd service args SERVICE restart +permit nopass acme cmd nginx args -s reload +</pre> + +<h1>acme setup</h1> +<p> +TODO: a package could be made to automate many of these steps +</p> +<label> + <input type="checkbox" /> + <code>doas apk add uacme openssl moreutils</code> +</label> + +<label> + <input type="checkbox" /> + <code>doas useradd -md /var/lib/acme -s /sbin/nologin acme</code> +</label> + +<label> + <input type="checkbox" /> + <code>doas mkdir -p /etc/ssl/uacme/private /var/www/.well-known/acme-challenge</code> +</label> + +<label> + <input type="checkbox" /> + <code>doas chown acme:acme /etc/ssl/uacme /etc/ssl/uacme/private</code> +</label> + +<label> + <input type="checkbox" /> + <code>doas chmod g+rX /etc/ssl/uacme /etc/ssl/uacme/private</code> +</label> + +<label> + <input type="checkbox" /> + <code>doas chown acme:acme /var/www/.well-known/acme-challenge</code> +</label> + +<label> + <input type="checkbox" /> + <code>doas touch /var/log/acme.log</code> +</label> + +<label> + <input type="checkbox" /> + <code>doas chown acme:acme /var/log/acme.log</code> +</label> + +<label> + <input type="checkbox" /> + <code>doas vim /usr/local/bin/acme-update-certs</code> +<pre style="margin-left: 1.5rem">#!/bin/sh -eu +exec >>/var/log/acme.log 2>&1 +date + +stats() { + cert="/etc/ssl/uacme/$1/cert.pem" + if ! [ -e "$cert" ] + then + return + fi + expiration=$(date -d"$(openssl x509 -enddate -noout -in "$cert" \ + | cut -d= -f2)" -D'%b %d %H:%M:%S %Y GMT' +'%s') + printf '# TYPE certificate_expiration gauge\n' + printf '# HELP certificate_expiration Timestamp when SSL certificate will expire\n' + printf 'certificate_expiration{instance="%s"} %s\n' "$1" "$expiration" +} + +acme() { + site=$1 + shift + /usr/bin/uacme -v -h /usr/share/uacme/uacme.sh issue $site $* || true + stats $site | curl --data-binary @- https://push.metrics.sr.ht/metrics/job/$site +} + +acme DOMAIN SUBDOMAIN... +doas nginx -s reload</pre> +</label> + +<label> + <input type="checkbox" /> + <code>doas chmod +x /usr/local/bin/acme-update-certs</code> +</label> + +<label> + <input type="checkbox" /> + <code>doas usermod -aG acme nginx</code> +</label> + +<label> + <input type="checkbox" /> + <code>doas -u acme uacme new sir@cmpwn.com</code> +</label> + +<label> + <input type="checkbox" /> + <code>doas -u acme crontab -e</code> +<pre style="margin-left: 1.5rem">MAILTO=sir@cmpwn.com +0 0 * * * chronic /usr/local/bin/acme-update-certs</pre> + </code> +</label> + +<label> + <input type="checkbox" /> Update nginx configuration + (<code>ssl_certificate{,_key}</code> commented) +</label> + +<label> + <input type="checkbox" /> + <code>doas -u acme /usr/local/bin/acme-update-certs</code> +</label> + +<label> + <input type="checkbox" /> + <code>cat /var/log/acme.log # verify success</code> +</label> + +<label> + <input type="checkbox" /> Update nginx configuration +</label> + +<label> + <input type="checkbox" /> + <code>doas chmod -R g+rX /etc/ssl/uacme /etc/ssl/uacme/private</code> +</label> + +<label> + <input type="checkbox" /> + <code>doas nginx -s reload</code> +</label> + +<label> + <input type="checkbox" /> Verify website has working SSL +</label> + +<h2>nginx config</h2> + +<pre> +server { + listen 80; + listen [::]:80; + server_name DOMAIN; + + location / { + return 302 https://$server_name$request_uri; + } + + location ^~ /.well-known { + root /var/www; + } +} + +server { + listen 443 ssl http2; + listen [::]:443 ssl http2; + server_name DOMAIN; + ssl_certificate /etc/ssl/uacme/DOMAIN/cert.pem; + ssl_certificate_key /etc/ssl/uacme/private/DOMAIN/key.pem; + + gzip on; + gzip_types text/css text/html; + + # ... +} +</pre> diff --git a/dynlib.html b/dynlib.html new file mode 100644 index 0000000000000000000000000000000000000000..81febd660c3fd27cd7771c7bc69ff60cacf4624b --- /dev/null +++ b/dynlib.html @@ -0,0 +1,369 @@ +<!doctype html> +<html lang="en"> +<meta charset="utf-8" /> +<title>Dynamic linking</title> +<style> +body { max-width: 720px; margin: 0 auto } +img { display: block; margin: 0 auto } +small { display: block; text-align: center } +th, td { padding-right: 4rem; text-align: left } +</style> +<h1>Dynamic linking</h1> +<h2>Do your installed programs share dynamic libraries?</h2> + +<p> +Findings: <strong>not really</strong> + +<p> +Over half of your libraries are used by fewer than 0.1% of your executables. + +<img src="https://l.sr.ht/PSEG.svg" alt="A plot showing that the number of times a dynamic library is used shows exponential decay" /> +<small>Number of times each dynamic library is required by a program</small> + +<p> +<strong>libs.awk</strong> +<pre> +/\t.*\.so.*/ { + n=split($1, p, "/") + split(p[n], l, ".") + lib=l[1] + if (libs[lib] == "") { + libs[lib] = 0 + } + libs[lib] += 1 +} +END { + for (lib in libs) { + print libs[lib] "\t" lib + } +} +</pre> + +<p> +<strong>Usage</strong> + +<pre> +$ find /usr/bin -type f -executable -print \ + | xargs ldd 2>/dev/null \ + | awk -f libs.awk \ + | sort -rn > results.txt +$ awk '{ print NR "\t" $1 }' < results.txt > nresults.txt +$ gnuplot +gnuplot> plot 'nresults.txt' +</pre> + +<p> +<a href="/dynlib.txt">my results</a> + +<p> +<pre> +$ find /usr/bin -type f -executable -print | wc -l +5688 +$ head -n20 < results.txt +4496 libc +4484 linux-vdso +4483 ld-linux-x86-64 +2654 libm +2301 libdl +2216 libpthread +1419 libgcc_s +1301 libz +1144 libstdc++ +805 liblzma +785 librt +771 libXdmcp +771 libxcb +771 libXau +755 libX11 +703 libpcre +667 libglib-2 +658 libffi +578 libresolv +559 libXext +</pre> + +<h2>Is loading dynamically linked programs faster?</h2> + +<p> +Findings: <strong>definitely not</strong> + +<table> + <thead> + <tr> + <th>Linkage</th> + <th>Avg. startup time</th> + </tr> + </thead> + <tbody> + <tr> + <td>Dynamic</td> + <td style="text-align: right">137263 ns</td> + </tr> + <tr> + <td>Static</td> + <td style="text-align: right">64048 ns</td> + </tr> + </tbody> +</table> + +<p> +<strong>ex.c</strong> +<pre> +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <unistd.h> + +int main(int argc, char *argv[]) { + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + fprintf(stdout, "%ld\t", ts.tv_nsec); + fflush(stdout); + if (argc == 1) { + char *args[] = { "", "", NULL }; + execvp(argv[0], args); + } else { + fprintf(stdout, "\n"); + } + return 0; +} +</pre> + +<p> +<strong>test.sh</strong> +<pre> +#!/bin/sh +i=0 +while [ $i -lt 1000 ] +do + ./ex + i=$((i+1)) +done +</pre> + +<p> +<strong>My results</strong> +<pre> +$ musl-gcc -o ex ex.c +$ ./test.sh | awk 'BEGIN { sum = 0 } { sum += $2-$1 } END { print sum / NR }' +137263 +$ musl-gcc -static -o ex ex.c +$ ./test.sh | awk 'BEGIN { sum = 0 } { sum += $2-$1 } END { print sum / NR }' +64048 +</pre> + +<h2>Wouldn't statically linked executables be huge?</h2> + +<p> +Findings: <strong>not really</strong> + +<p> +On average, dynamically linked executables use only 4.6% of the symbols on +offer from their dependencies. A good linker will remove unused symbols. + +<img src="https://l.sr.ht/WzUp.svg" alt="A box plot showing most results are <5%, with outliers evenly distributed up to 100%" /> +<small>% of symbols requested by dynamically linked programs from the libraries that it depends on</small> + +<p> +<strong>nsyms.go</strong> +<pre> +package main + +import ( + "bufio" + "fmt" + "os" + "os/exec" + "path/filepath" + "strings" +) + +func main() { + ldd := exec.Command("ldd", os.Args[1]) + rc, err := ldd.StdoutPipe() + if err != nil { + panic(err) + } + ldd.Start() + + var libpaths []string + scan := bufio.NewScanner(rc) + for scan.Scan() { + line := scan.Text()[1:] /* \t */ + sp := strings.Split(line, " ") + var lib string + if strings.Contains(line, "=>") { + lib = sp[2] + } else { + lib = sp[0] + } + if !filepath.IsAbs(lib) { + lib = "/usr/lib/" + lib + } + libpaths = append(libpaths, lib) + } + ldd.Wait() + rc.Close() + + syms := make(map[string]interface{}) + for _, path := range libpaths { + objdump := exec.Command("objdump", "-T", path) + rc, err := objdump.StdoutPipe() + if err != nil { + panic(err) + } + objdump.Start() + scan := bufio.NewScanner(rc) + for i := 0; scan.Scan(); i++ { + if i < 4 { + continue + } + line := scan.Text() + sp := strings.Split(line, " ") + if len(sp) < 5 { + continue + } + sym := sp[len(sp)-1] + syms[sym] = nil + } + objdump.Wait() + rc.Close() + } + + objdump := exec.Command("objdump", "-R", os.Args[1]) + rc, err = objdump.StdoutPipe() + if err != nil { + panic(err) + } + objdump.Start() + used := make(map[string]interface{}) + scan = bufio.NewScanner(rc) + for i := 0; scan.Scan(); i++ { + if i < 5 { + continue + } + sp := strings.Split(scan.Text(), " ") + if len(sp) < 3 { + continue + } + sym := sp[len(sp)-1] + used[sym] = nil + } + objdump.Wait() + rc.Close() + + if len(syms) != 0 && len(used) != 0 && len(used) <= len(syms) { + fmt.Printf("%50s\t%d\t%d\t%f\n", os.Args[1], len(syms), len(used), + float64(len(used)) / float64(len(syms))) + } +} +</pre> + +<p> +<strong>Usage</strong> +<pre> +$ find /usr/bin -type f -executable -print | xargs -n1 ./nsyms > results.txt +$ awk '{ n += $4 } END { print n / NR }' < results.txt +</pre> + +<p> +<a href="/nsyms.txt">my results</a> + +<h2>Will security vulnerabilities in libraries that have been statically linked + cause large or unmanagable updates?</h2> + +<p> +Findings: <strong>not really</strong> + +<p> +Not including libc, the only libraries which had "critical" or "high" severity +vulnerabilities in 2019 which affected over 100 binaries on my system were dbus, +gnutls, cairo, libssh2, and curl. 265 binaries were affected by the rest. + +<p> +The total download cost to upgrade all binaries on my system which were affected +by CVEs in 2019 is 3.8 GiB. This is reduced to 1.0 GiB if you eliminate glibc. + +<p> +It is also unknown if any of these vulnerabilities would have been introduced +<em>after</em> the last build date for a given statically linked binary; if so +that binary would not need to be updated. Many vulnerabilities are also limited +to a specific code path or use-case, and binaries which do not invoke that code +path in their dependencies will not be affected. A process to ascertain this +information in the wake of a vulnerability could be automated. + +<p> +<a href="https://lists.archlinux.org/pipermail/arch-security/">arch-security</a> + +<p> +<strong>extractcves.py</strong> +<pre> +import email.utils +import mailbox +import re +import shlex +import time + +pacman_re = re.compile(r'pacman -Syu .*') +severity_re = re.compile(r'Severity: (.*)') + +mbox = mailbox.mbox("arch-security.mbox") +for m in mbox.items(): + m = m[1] + date = m["Date"] + for part in m.walk(): + if part.is_multipart(): + continue + content_type = part.get_content_type() + [charset] = part.get_charsets("utf-8") + if content_type == 'text/plain': + body = part.get_payload(decode=True).decode(charset) + break + pkgs = pacman_re.findall(body) + severity = severity_re.findall(body) + date = email.utils.parsedate(date) + if len(pkgs) == 0 or date is None: + continue + if date[0] <= 2018 or date[0] > 2019: + continue + severity = severity[0] + args = shlex.split(pkgs[0]) + pkg = args[2].split(">=")[0] + print(pkg, severity) +</pre> + +<pre> +$ python3 extractcves.py | grep Critical > cves.txt +$ xargs pacman -Ql < cves.txt | grep \\.so | awk '{print $1}' | sort -u>affected.txt +# Manually remove packages like Firefox, Thunderbird, etc; write remainder.txt +$ xargs pacman -Ql < remainder.txt | grep '/usr/lib/.*.so$' | awk '{ print $2 }' > libs.txt +$ ldd /usr/bin/* >ldd.txt +$ ./scope.sh <libs.txt | sort -nr >sobjects.txt +</pre> + +<p> +<a href="/sobjects.txt">sobjects.txt</a> is a sorted list of shared objects and +the number of executables that link to them. To find the total size of affected +binaries, I ran the following command: + +<pre style="overflow-x: scroll"> +# With libc +$ egrep -la 'libc.so|libm.so|libdl.so|libpthread.so|librt.so|libresolv.so|libdbus-1.so|libgnutls.so|libcairo.so|libutil.so|libssh2.so|libcurl.so|libcairo-gobject.so|libcrypt.so|libspice-server.so|libarchive.so|libSDL2-2.0.so|libmvec.so|libmagic.so|libtextstyle.so|libgettextlib-0.20.2.so|libgettextsrc-0.20.2.so|libMagickWand-7.Q16HDRI.so|libMagickCore-7.Q16HDRI.so|libbfd-2.34.0.so|libpolkit-gobject-1.so|libwebkit2gtk-4.0.so|libjavascriptcoregtk-4.0.so|libpolkit-agent-1.so|libgs.so|libctf.so|libSDL.so|libopcodes-2.34.0.so|libQt5WebEngine.so|libQt5WebEngineCore.so|libctf-nobfd.so|libcairo-script-interpreter.so' /usr/bin/* | xargs wc -c +# Without libc +$ egrep -la 'libdbus-1.so|libgnutls.so|libcairo.so|libssh2.so|libcurl.so|libcairo-gobject.so|libcrypt.so|libspice-server.so|libarchive.so|libSDL2-2.0.so|libmvec.so|libmagic.so|libtextstyle.so|libgettextlib-0.20.2.so|libgettextsrc-0.20.2.so|libMagickWand-7.Q16HDRI.so|libMagickCore-7.Q16HDRI.so|libbfd-2.34.0.so|libpolkit-gobject-1.so|libwebkit2gtk-4.0.so|libjavascriptcoregtk-4.0.so|libpolkit-agent-1.so|libgs.so|libctf.so|libSDL.so|libopcodes-2.34.0.so|libQt5WebEngine.so|libQt5WebEngineCore.so|libctf-nobfd.so|libcairo-script-interpreter.so' /usr/bin/* | xargs wc -c +</pre> + +<h2>Doesn't static linking prevent <abbr title="address space layout randomization, a security technique">ASLR</abbr> from working?</h2> + +<p> +<strong>No</strong>. + +<p> +We've had ASLR for statically linked binaries for some time now. It's called <a href="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81498">static PIE</a>. + +<h2>Test environment</h2> +<ul> + <li>Arch Linux, up-to-date as of 2020-06-25</li> + <li>2188 packages installed</li> + <li>gcc 10.1.0</li> +</ul> diff --git a/editing.html b/editing.html new file mode 100644 index 0000000000000000000000000000000000000000..7b08430bb35877b3a6a1bef2eeac8818c3918aa6 --- /dev/null +++ b/editing.html @@ -0,0 +1,99 @@ +<!doctype html> +<html lang="en"> +<meta charset="utf-8" /> +<title>Videos of people editing text</title> +<style> +body { + max-width: 720px; + margin: 0 auto; +} + +video { + display: block; + width: 720px; + margin-top: 1rem; +} +</style> +<h1>Videos of people editing text</h1> +<p> +Videos of people editing text, explaining the shortcuts they use, and +recordings of their keyboards as they work. The purpose of this page is to +provide a reference for people writing new software which involves text editing +tasks. + +<p> +These videos are licensed with +<a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, which +permits re-distribution and modification so long as attribution is provided and +derivative works use the same license. + +<p> +<a href="#contribute">Can you contribute your own?</a> + +<h2>Resources</h2> +<ul> + <li> + <a href="https://lord.io/blog/2019/text-editing-hates-you-too/"> + Text Editing Hates You Too + </a> + </li> + <li> + <a href="https://gankra.github.io/blah/text-hates-you/"> + Text Rendering Hates You + </a> + </li> +</ul> + +<h2>Videos</h2> + +<video src="https://yukari.sr.ht/drew-devault-keyboard.webm" controls> + Your browser must support HTML5 video and webm to play this video. +</video> + +<dl> + <dt>Source</dt> + <dd>Drew DeVault</dd> + <dt>Language</dt> + <dd>English</dd> + <dt>Keyboard</dt> + <dd>Kinesis Freestyle Pro; ANSI layout; QWERTY</dd> + <dt>Operating system</dt> + <dd>Linux 5.7.6</dd> + <dt>Software</dt> + <dd>gedit 3.36.2 (GTK+ 3.24.20), alacritty 0.5.0.1564.g3233ede0, vim 8.2.0814</dd> + <dt>Tags</dt> + <dd>#english #en #en-us #ansi #qwerty #modal-editing</dd> +</dl> + +<h2 id="contribute">Contribute</h2> +<p> +I would be interested in adding your video to this page, provided that it +demonstrates one of the following qualities which is not yet represented by +another video: + +<ul> + <li>A natural language not yet represented</li> + <li>An operating system not yet represented</li> + <li>A keyboard layout or design not yet represented</li> + <li>Software with novel editing features</li> + <li>A novel workflow, e.g. screen reader or dictation software</li> +</ul> + +<p> +When preparing your video, please use a camera to capture a video of your +keyboard. I recommend <a href="https://obsproject.com/">OBS</a> to capture a +recording of both your screen and keyboard, as well as audio from your +microphone. Please narrate your workflow in English, and include details which +seem "obvious" to you; they might not be obvious to someone else. Contact +<a href="mailto:sir@cmpwn.com">Drew DeVault <sir@cmpwn.com></a> +to list your video. Please include the following details: + +<ul> + <li>Your name, for attribution</li> + <li>The natural language you are demonstrating input for</li> + <li>Your keyboard model and layout</li> + <li>Your operating system and the names & version numbers of your software</li> +</ul> + +<p> +Thank you!