-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.json
1 lines (1 loc) · 254 KB
/
index.json
1
[{"content":"Obarun e S6 O S6 - Skarnet.org\u0026rsquo;s Small \u0026amp; Secure Supervision Software Suite inclui um init, um dos vários projectos que se rebelaram contra o SystemD afirmando que havia maneiras melhores e/ou mais simples de fazer a mesma coisa. Para quem?\r\nApesar de a implementação oficial do S6 ter começado por ser no Alpine Linux, por alguma razão o autor agora colabora com o Adélie Linux, que já explorei antes.\nNo entanto, a expressão mais madura do S6-init encontra-se no Obarun, uma distribuição baseada em Arch e, tanto quanto sei, sem a colaboração do autor do S6, apesar de serem todos franceses. Isto porque o S6 ainda não definiu uma maneira de organizar as dependências entre os serviços (e sendo zelota do \u0026ldquo;Caminho do UNIX\u0026rdquo;, talvez nunca o venha a fazer), o que significa que alguém tem de fazê-lo; a contribuição do Obarun é um conjunto de scripts chamado 66\nPor isso, para experimentar o S6 tive de instalar o Obarun; sendo baseado em Arch, temi o pior, mas comparado com o Adélie até foi relativamente simples.\n\r\rNotas de instalação O locale PT-UTF8 causa erros de caracter na consola texto (configuração errada no grub.cfg?)\n\r\rRefiz a instalação no locale en_GB-UTF8 e funcionou. Em modo minimal, o NAT do VirtualBox fornece o valore da opção nameserver (opção DHCP 5) que é escrita em /etc/resolv.conf, mas em NATnetwork não, é necessário editar o /etc/resolv.conf à mão. Bug do VirtualBox? A \u0026ldquo;NAT Network\u0026rdquo; ainda tem muitos bugs, e talvez um deles seja que as opções DHCP não são transmitidas, mas não cheguei a usar um packet sniffer para verificar\u0026hellip; S6/66 (v.6.3+) O 66, como disse, é uma camada de gestão sobre o sistema S6, que se baseia na criação de um conjunto de árvores, que são criadas pelo utilizador e que são um meio-termo entre a ordem numérica/alfabética do SysV-init e o grafo dinamicamente actualizado do SystemD.\nExemplo: instalar SSHD O serviço sshd instala-se com\n1 pacman -S --needed openssh 66 fase 1: service script O service script que controla o serviço openssh não é instalado automaticamente; tem de ser criado, ou obtido dos scripts que existem no repositório observice. Os service scripts existentes neste repo podem ser listados com\n1 pacman -Sl observice Para instalar o service script,\n1 pacman -S sshd-66serv Para que o sistema saiba que o serviço foi adicionado,\n1 66-enable sshd Agora já podemos ver o conteúdo do service script com\n1 66-inservice sshd Name : sshd\rVersion : 0.2.1\rIn tree : Status : Type : classic\rDescription : ssh daemon\rSource : /usr/lib/66/service/sshd\rLive : /run/66/scandir/0/sshd\rDependencies : sshd-log\rExternal dependencies : None\rOptional dependencies : None\rStart script : foreground { exec ssh-keygen -A } execl-cmdline -s { /usr/sbin/sshd -f ${conf_file} ${cmd_args} }\rStop script : None\rEnvironment source : /etc/66/conf/sshd/0.2.1\rEnvironment file : environment variables from: /etc/66/conf/sshd/0.2.1/.sshd\rconf_file=!/etc/ssh/sshd_config\rcmd_args=!-D\rLog name : sshd-log\rLog destination : /var/log/66/sshd\rLog file : None\r 66 fase 2: configurar as dependências No entanto, os serviços antes de serem iniciados têm de ser adicionados a uma tree, que codifica as dependências dos serviços.\nPara ver e manipular as trees, usa-se o comando 66-intree (a partir da versão 0.6x do 66)\nAcho muito útil a opção -g que mostra a estrutura de dependências dos serviços que se encontram configurados nas trees.\n1 66-intree -g Name : boot\rInitialized : yes\rEnabled : no\rStarts after : None\rCurrent : no\rAllowed : root\rSymlinks : svc-source db-source\rContents : /\r├─(144,Enabled,classic) tty-earlier@tty12\r├─(up,Enabled,oneshot) system-hostname\r├─(up,Enabled,oneshot) mount-run\r├─(up,Enabled,oneshot) populate-run\r├─(up,Enabled,oneshot) mount-tmp\r├─(up,Enabled,oneshot) populate-tmp\r├─(up,Enabled,oneshot) mount-proc\r├─(up,Enabled,oneshot) mount-sys\r├─(up,Enabled,oneshot) populate-sys\r├─(up,Enabled,oneshot) mount-dev\r├─(up,Enabled,oneshot) mount-pts\r├─(up,Enabled,oneshot) mount-shm\r├─(up,Enabled,oneshot) populate-dev\r├─(up,Enabled,oneshot) mount-cgroups\r├─(up,Enabled,bundle) 00\r├─(up,Enabled,bundle) all-Mount\r├─(up,Enabled,oneshot) system-hwclock\r├─(up,Enabled,oneshot) modules-kernel\r├─(up,Enabled,oneshot) system-random\r├─(up,Enabled,oneshot) modules-system\r├─(up,Enabled,oneshot) system-sysctl\r├─(184,Enabled,longrun) udevd-log\r├─(359,Enabled,longrun) udevd\r├─(up,Enabled,oneshot) udevadm\r├─(up,Enabled,oneshot) system-fontnkey\r├─(up,Enabled,oneshot) system-fsck\r├─(up,Enabled,oneshot) mount-fstab\r├─(up,Enabled,bundle) all-System\r├─(up,Enabled,oneshot) mount-rw\r├─(up,Enabled,oneshot) mount-netfs\r├─(up,Enabled,oneshot) local-loop\r├─(up,Enabled,oneshot) local-sethostname\r├─(up,Enabled,oneshot) local-time\r├─(up,Enabled,oneshot) local-authfiles\r├─(up,Enabled,oneshot) local-tmpfiles\r├─(up,Enabled,oneshot) local-dmesg\r├─(up,Enabled,bundle) all-Local\r├─(up,Enabled,oneshot) all-Runtime\r├─(up,Enabled,bundle) All\r├─(580,Enabled,longrun) tty-rc@tty1\r├─(579,Enabled,longrun) tty-rc@tty2\r└─(up,Enabled,module) boot@system\rName : root\rInitialized : yes\rEnabled : yes\rStarts after : None\rCurrent : yes\rAllowed : root\rSymlinks : svc-source db-source\rContents : /\r├─(567,Enabled,classic) dhcpcd-log\r└─(566,Enabled,classic) dhcpcd\r Para activar o serviço e iniciá-lo na altura correcta do processo de arranque, criamos uma nova tree net (que correrá serviços que dependem de a rede estar configurada) a seguir à tree root (onde neste momento está o serviço dhcpcd que configura a rede):\n1 66-tree –S root -nE net 66-tree: info: Created successfully tree: net\r66-tree: info: Enabled successfully tree: net\r66-tree: info: Ordered successfully tree: net starts after tree: root\r Depois de criar a nova tree, adiciona-se o serviço sshd a essa tree:\n1 66-enable -t net sshd 66-enable: info: Enabled successfully: sshd\r E finalmente activam-se todos os serviços da tree:\n1 66-all -t net up 66-all: info: Initialized successfully: sshd-log\r66-all: info: Initialized successfully: sshd\r66-all: info: Initialization: no atomic services into tree: net\r66-all: info: sshd-log: started successfully\r66-all: info: sshd: started successfully\r E agora já nos podemos ligar ao Obarun por SSH.\nPodemos ver as alterações que foram feitas repetindo o comando 66-intree -g\nName : boot\rInitialized : yes\rEnabled : no\rStarts after : None\rCurrent : no\rAllowed : root\rSymlinks : svc-source db-source\rContents : /\r├─(144,Enabled,classic) tty-earlier@tty12\r├─(up,Enabled,oneshot) system-hostname\r├─(up,Enabled,oneshot) mount-run\r├─(up,Enabled,oneshot) populate-run\r├─(up,Enabled,oneshot) mount-tmp\r├─(up,Enabled,oneshot) populate-tmp\r├─(up,Enabled,oneshot) mount-proc\r├─(up,Enabled,oneshot) mount-sys\r├─(up,Enabled,oneshot) populate-sys\r├─(up,Enabled,oneshot) mount-dev\r├─(up,Enabled,oneshot) mount-pts\r├─(up,Enabled,oneshot) mount-shm\r├─(up,Enabled,oneshot) populate-dev\r├─(up,Enabled,oneshot) mount-cgroups\r├─(up,Enabled,bundle) 00\r├─(up,Enabled,bundle) all-Mount\r├─(up,Enabled,oneshot) system-hwclock\r├─(up,Enabled,oneshot) modules-kernel\r├─(up,Enabled,oneshot) system-random\r├─(up,Enabled,oneshot) modules-system\r├─(up,Enabled,oneshot) system-sysctl\r├─(184,Enabled,longrun) udevd-log\r├─(359,Enabled,longrun) udevd\r├─(up,Enabled,oneshot) udevadm\r├─(up,Enabled,oneshot) system-fontnkey\r├─(up,Enabled,oneshot) system-fsck\r├─(up,Enabled,oneshot) mount-fstab\r├─(up,Enabled,bundle) all-System\r├─(up,Enabled,oneshot) mount-rw\r├─(up,Enabled,oneshot) mount-netfs\r├─(up,Enabled,oneshot) local-loop\r├─(up,Enabled,oneshot) local-sethostname\r├─(up,Enabled,oneshot) local-time\r├─(up,Enabled,oneshot) local-authfiles\r├─(up,Enabled,oneshot) local-tmpfiles\r├─(up,Enabled,oneshot) local-dmesg\r├─(up,Enabled,bundle) all-Local\r├─(up,Enabled,oneshot) all-Runtime\r├─(up,Enabled,bundle) All\r├─(580,Enabled,longrun) tty-rc@tty1\r├─(579,Enabled,longrun) tty-rc@tty2\r└─(up,Enabled,module) boot@system\rName : root\rInitialized : yes\rEnabled : yes\rStarts after : None\rCurrent : yes\rAllowed : root\rSymlinks : svc-source db-source\rContents : /\r├─(565,Enabled,classic) sshd-log\r├─(567,Enabled,classic) dhcpcd-log\r├─(566,Enabled,classic) dhcpcd\r└─(564,Enabled,classic) sshd\rName : net\rInitialized : yes\rEnabled : yes\rStarts after : root\rCurrent : no\rAllowed : root\rSymlinks : svc-source db-source\rContents : /\r├─(565,Enabled,classic) sshd-log\r└─(564,Enabled,classic) sshd\r\nConclusão Sim, as \u0026ldquo;árvores\u0026rdquo; do 66 permitem gerir as dependências dos serviços de forma ligeiramente mais intuitiva do que os clássicos scripts numerados do SysV-init, mas estão muito longe da facilidade de utilização dos service units do SystemD, que são declarativos.\nAlém disso, a instalação e configuração dos service units é muitas vezes automatizada pelos package managers das distribuições que suportam SystemD, e como são declarativos, basta criar o service unit e depois o SystemD se encarregará de extrair as dependências e paralelismos nos serviços configurados. Apesar de o 66 suportar o arranque paralelo de serviços através do uso das trees, tem de ser o administrador a definir exactamente a ordem de arranque de cada serviço.\nPara quem quiser mais controlo do que aquele que o SystemD oferece por defeito, é óptimo, ou pelo menos melhor que o SysV-init, mas é igualmente (ou mais) trabalhoso. Os scripts 66 ajudam um pouco, mas não muito.\nClaro que o que falta ao S6, OpenRC, Runit, etc, é as milhares de horas de programação que foram investidas no SystemD e a quantidade neste caso tem uma qualidade em si mesma. Em comparação, todos estes inits são um bolo ao qual falta o fermento para subir.\nSe estiver interessado em contribuir para este projecto, eles precisam de si.\n","description":"Uma alternativa ao SystemD","id":0,"section":"unixlike","tags":null,"title":"S6-init no Obarun","uri":"https://tiagojsilva.github.io/pt/unixlike/meme/arch_manjaro/2021-12-02_obarun-install/"},{"content":"Para este sistema, que eventualmente vai ser um servidor chamado verynice, criei uma VM com 256MB de RAM e 640MB de disco.\n\r\rO TinyCore1 é uma instalação Linux muito especial, devotada a sistemas com muito poucos recursos. Vou usar a versão CorePlus, a mais \u0026ldquo;luxuosa\u0026rdquo;, com ambiente gráfico e possibilidade de instalação em disco, mas há versões Core muito mais frugais que correm alegremente de uma pen USB carregando-se para uma RAMdrive no arranque.\nO seu modo de funcionamento é muito particular, porque o core do sistema é completamente separado das aplicações e configurações, e estas só são aplicadas no arranque seguinte se forem explicitamente guardadas.\nMuito poucas concessões são feitas à conveniência e user-friendliness, todos os comandos da shell por defeito (busybox)2 são extremamente simplificados em relação a uma distribuição Linux normal e os utilitários de gestão são os do Unix/Linux de há dez anos.\nInstalação Descarrega-se do site da distribuição TinyCore (http://tinycorelinux.net/) o instalador da versão CorePlus (na página Downloads, http://tinycorelinux.net/11.x/x86/release/CorePlus-current.iso)\nColoca-se o ISO na drive óptica virtual da VM e inicia-se a VM.\nEscolhe-se a opção por defeito: FLWM topside\n\r\rNa doca ao fundo do ecrã, abre-se a aplicação tc-install3\n\r\rEscolhem-se as opções: Frugal, Whole disk, e depois desta última, o disco sda. Confirmar que Install boot loader está activado. Clicar em \u0026gt;\n\r\rFormatting Options: ext4 \u0026gt;\n\r\rBoot options a colocar no instalador (consultar a lista apresentada no ecrã, ou o capítulo 10 do livro oficial do Tiny Core Linux, Into the Core):\ntce=sda1 home=sda1 opt=sda1 nodhcp showapps safebackup cron syslog host=verynice kmap=qwerty/pt-latin1.kmap\r(Mude o hostname para algo mais adequado para si, obviamente)\nO teclado está em layout US, por isso:\n o caracter = está na tecla « e o caracter / está na tecla – \nClicar em \u0026gt;\n\r\rTipo de instalação Eu escolhi Core and X/GUI Desktop mas seguindo este guia, talvez não seja necessário o GUI e se possa escolher Core Only\nA única extensão que se vai instalar é Non-US keyboard layout support\nClicar em \u0026gt;\n\r\rNa realidade, depois de ter o CoreLinux instalado e a rede configurada, esta extensão pode-se instalar com bastante facilidade a partir do gestor de extensões, por isso também não é obrigatório utilizar o instalador CorePlus para ter teclados internacionais, um instalador mais leve seria suficiente. Mas esta é a opção mais geral.\nO mesmo pode não ser verdade para o suporte a placas Wi-Fi, que também se escolhe neste painel mas que eu não testei.\nRevêm-se as configurações e clica-se em Proceed\n\r\rClicar no ícone Exit da doca, opção Shutdown, OK\n\r\rQuando a instalação terminar, retirar o ISO da drive óptica e reiniciar a VM.\nConfigurações iniciais Mudar as opções de arranque Se for preciso mudar as boot options: editar /mnt/sda1/tce/boot/extlinux/extlinux.conf e mudar o conteúdo da linha APPEND\nTeclado português Abrir o Terminal e testar uma tecla específica do teclado PT-pt; se o resultado não for o esperado (o boot option kmap não estiver a activar o layout PT-pt), usar o comando\n1 echo \u0026#39;loadkmap \u0026lt; /usr/share/kmap/qwerty/pt-latin1.kmap\u0026#39; \u0026gt;\u0026gt; /opt/bootsync.sh o caracter - está na tecla ' o caracter / está na tecla – o caracter ' está na tecla º Seguido de (já explicarei estes comandos):\n1 2 filetool.sh -b sudo reboot \r\r\rConfigurar permanência Sem este passo, o TinyCore Linux não vai guardar automaticamente as alterações que fizermos à configuração, porque depois de cada reinício, todas as configurações são perdidas excepto aquelas que dissermos que queremos guardar (o que tem vantagens e desvantagens).\nO processo abaixo configura a gravação automática das configurações em caso de shutdown do sistema, através do script que o sistema corre automaticamente durante o shutdown.\n1 vi /opt/shutdown.sh Por baixo da linha #put user shutdown commands here, acrescentar:\n1 filetool.sh -b Guardar e sair. O comando para forçar a gravação desta alteração é, claro,\n1 filetool.sh -b Mudar a palavra passe do utilizador por defeito (tc) 1 passwd Colocar uma palavra-passe que lhe apeteça.\nAdicionar um ficheiro de configuração à Permanência Para guardar um ficheiro de configuraçºao, como o ficheiro das palavras-passe, depois de um reinício (dar-lhe permanência), o caminho do ficheiro a guardar, menos o / inicial, é colocado no ficheiro /opt/.filetool.lst\n1 2 sudo echo \u0026#39;etc/shadow\u0026#39; \u0026gt;\u0026gt; /opt/.filetool.lst filetool.sh -b Rede Para configurar uma interface de rede numa versão do CoreLinux com o ambiente gráfico, usar o comando sudo network numa janela de terminal (estes valores servem apenas de exemplo):\nInterface: eth0\nDHCP Broadcast: no\nIP Address: 10.123.130.6\nNet mask: 255.255.255.248\nBroadcast: 10.123.130.7\nGateway: 10.123.130.1\nNameServers: 1.1.1.1, 8.8.8.8\nSave Configuration: yes\nApply\n\r\rTestar com ping 1.1.1.1\nConfirmar a configuração com cat /opt/eth0.sh\nDeve ser:\n#!/bin/sh\rpkill udhcpc\rifconfig eth0 10.123.130.6 netmask 255.255.255.248 broadcast 10.123.130.7 up\rroute add default gw 10.123.130.1\recho nameserver 1.1.1.1 /etc/resolv.conf\recho nameserver 8.8.8.8 /etc/resolv.conf\r\nPara configurar a rede sem se ter acesso ao modo gráfico, basta copiar a informação acima para /opt/eth0.sh\nConfirmar que o /opt/eth0.sh está configurado para ser adicionado à permanência com o comando\n1 cat /opt/.filetool.lst | grep eth0 opt/eth0.sh\r Se não estiver,\n1 echo \u0026#34;opt/eth0.sh\u0026#34; \u0026gt;\u0026gt; /opt/.filetool.lst \u0026amp;\u0026amp; filetool.sh -b Aliases Os aliases do utilizador por defeito (tc) estão em ~/.ashrc. Acrescentei estes aliases que julgo úteis:\n1 2 3 4 #filtrar o syslog echo \u0026#34;alias log=\u0026#39;grep /var/log/messages -e\u0026#39;\u0026#34; \u0026gt;\u0026gt; ~/.ashrc #usar sudo com aliases\t echo \u0026#34;alias sudo=\u0026#39;sudo \u0026#39;\u0026#34; \u0026gt;\u0026gt; ~/.ashrc\t E seria bom ter esses aliases (e os outros, como ll='ls -l' e especialmente rm='rm -i') se estivermos numa rootshell; copiar os ficheiros necessários para a pasta /root e dizer ao CoreLinux que queremos guardar o conteúdo da pasta /root entre arranques:\n1 2 sudo cp /home/tc/.ashrc /root/.ashrc \u0026amp;\u0026amp; sudo chown root:root /root/.ashrc echo \u0026#34;root\u0026#34; \u0026gt;\u0026gt; /opt/.filetool.lst \u0026amp;\u0026amp; filetool.sh -b Configurar Time Zone Fonte\nConfirmar que estamos na pasta home do utilizador: cd ~\nAssegurar que temos ligação ao exterior (por exemplo, ping 1.1.1.1)\nO comando tce-fetch.sh descarrega uma extensão sem a instalar. Neste caso queremos a extensão tzdata.tcz (Time Zone data.TCextension Zipped)\n1 tce-fetch.sh tzdata.tcz O CoreLinux pode montar as extensões directamente para leitura (é, de resto, como ele \u0026ldquo;instala\u0026rdquo; uma extensão). Criar uma pasta e montar:\n1 2 mkdir tztemp sudo mount tzdata.tcz tztemp -t squashfs -o loop,ro Copiar a informação de timezone de Lisboa para o local por defeito, /etc/localtime\n1 sudo cp -a tztemp/usr/local/share/zoneinfo/Europe/Lisbon /etc/localtime Dar permanência à configuração:\n1 2 sudo echo \u0026#34;etc/localtime\u0026#34; \u0026gt;\u0026gt; /opt/.filetool.lst filetool.sh -b Acesso remoto por OpenSSH Fonte\nAssegurar que temos ligação ao exterior (por exemplo, ping 1.1.1.1)\nO comando tce-load -wi instala directamente uma extensão de modo permanente:\n1 tce-load -wi openssh.tcz Criamos a configuração do serviço OpenSSH copiando a configuração por defeito fornecida com a extensão:\n1 2 cd /usr/local/etc/ssh sudo cp -a sshd_config.orig sshd_config Arrancamos o serviço com o script fornecido pela extensão:\n1 sudo /usr/local/etc/init.d/openssh start Verificar o serviço com\n1 netstat -anp | grep 22 Tcp\t0\t0 0.0.0.0:22\t0.0.0.0:*\tLISTEN\r1470/sshd\r Primeira ligação Com o sshd_config que vem por defeito com a extensão é obrigatório ter uma palavra-passe configurada para o utilizador inicial tc, por isso se a palavra-passe não estiver configurada é necessário fazê-lo agora (é possível configurar host-based auth ou chaves assimétricas, mas só depois de editar o sshd_config)\n1 2 3 passwd #Colocar a palavra-passe do costume duas vezes sudo echo \u0026#34;etc/shadow\u0026#34; \u0026gt;\u0026gt; /opt/.filetool.lst \u0026amp;\u0026amp; filetool.sh -b Testar, logando por SSH com um cliente (como o PuTTY em Windows):\n\r\rGarantir que as configurações do SSH são guardadas:\n1 sudo echo \u0026#34;usr/local/etc/ssh\u0026#34; \u0026gt;\u0026gt; /opt/.filetool.lst \u0026amp;\u0026amp; filetool.sh -b Colocar o serviço a arrancar com o sistema Ai, que me deu aqui um baque de nostalgia\u0026hellip; Era assim que se fazia antes do SystemD:\n1 sudo echo \u0026#39;usr/local/etc/init.d/openssh start \u0026amp;\u0026#39; \u0026gt;\u0026gt; /opt/bootlocal.sh \u0026amp;\u0026amp; filetool.sh -b (Aaahhhh\u0026hellip; nem por isso. O SystemD é um enorme avanço sobre tricotar shell scripts e gerir dependências à unha, mas seria mais pesado que o resto do CoreLinux inteiro\u0026hellip;)\nInstalar um editor de texto (vim) Chamar o gestor de aplicações em modo texto:\n1 tce-ab S)earch\rEnter starting chars of desired extension, e.g. abi:\r Escrever vim, tecla Enter\ntce - Tiny Core Extension browser\r1. gvim-base.tcz\r2. gvim-doc.tcz\r3. gvim.tcz\r4. gvim-tutor.tcz\r5. vim-locale.tcz\r6. vim.tcz\rEnter selection ( 1 - 6 ) or (q)uit:\r6\r\nÉ mostrada a informação About da extensão; q para sair e mostrar o menu:\nA)bout I)nstall O)nDemand D)epends T)ree F)iles siZ)e L)ist S)earch P)rovides K)eywords or Q)uit:\ri\rvim.tcz.dep OK\rDownloading: gvim-base.tcz\rConnecting to repo.tinycorelinux.net (89.22.99.37:80)\rsaving to 'gvim-base.tcz'\rgvim-base.tcz 100% |************************************************************************************| 8036k 0:00:00 ETA\r'gvim-base.tcz' saved\rgvim-base.tcz: OK\rDownloading: ncursesw.tcz\rConnecting to repo.tinycorelinux.net (89.22.99.37:80)\rsaving to 'ncursesw.tcz'\rncursesw.tcz 100% |************************************************************************************| 212k 0:00:00 ETA\r'ncursesw.tcz' saved\rncursesw.tcz: OK\rDownloading: vim.tcz\rConnecting to repo.tinycorelinux.net (89.22.99.37:80)\rsaving to 'vim.tcz'\rvim.tcz 100% |************************************************************************************| 1432k 0:00:00 ETA\r'vim.tcz' saved\rvim.tcz: OK\rvim.tcz\rA)bout I)nstall O)nDemand D)epends T)ree F)iles siZ)e L)ist S)earch P)rovides K)eywords or Q)uit:\r\nQ para sair ou S, P, ou K, para encontrar mais extensões a instalar. Por exemplo, coreutils.tcz instala os comandos GNU/POSIX mais vulgares em versões mais completas que as integradas no busybox, e bash.tcz instala essa shell em vez do busybox (mas como o TinyCore não nos segura nas mãozinhas, é necessário ir ao /etc/passwd mudar a login shell do utilizador, configurar o /etc/passwd para ser guardado no backup, e fazer o backup)\nConfigurar o vim 1 2 cd ~ vim .vimrc Configurar no ficheiro as opções desejadas (uma vez que está na pasta /home/tc/, será guardado automaticamente pelas boot options que demos, nomeadamente home=sda1).\nUma sugestão para um .vimrc está na página Dotfiles.\nDepois de o ter configurado a nosso gosto, seria bom manter a configuração mesmo quando estamos a editar um ficheiro como o utilizador root. Para conseguir isso, copia-se o .vimrc para a pasta pessoal do root:\n1 2 sudo cp /home/tc/.vimrc /root sudo chown root:root /root/.vimrc (ver a secção Aliases para o comando que adiciona a pasta /root à Permanência, se já não estiver)\nCliente NTP Se o relógio de sistema não estiver correcto a comunicação entre um serviço local e os servidores na WAN pode ser recusada por estes últimos. E numa VM VirtualBox sem GuestAdditions, o relógio vai estar quase sempre errado.\nApesar de existir um pacote chrony para o TinyCore, usei apenas um cliente NTP4 muito básico, porque estava interessado em aligeirar o mais possível o sistema .\n1 tce-load -wi ntpclient.tcz Downloading: ntpclient.tcz\rConnecting to repo.tinycorelinux.net (89.22.99.37:80)\rsaving to 'ntpclient.tcz'\rntpclient.tcz 100% |********************************| 12288 0:00:00 ETA\r'ntpclient.tcz' saved\rntpclient.tcz: OK\r Configurar o cliente Colocar no /opt/bootlocal.sh três instruções com diferentes propósitos:\n1) Actualizar o relógio durante o arranque5 Caso não tenhamos DNS disponível nesta fase do arranque, precisamos de usar directamente IPs e não nomes, por isso não podemos usar uma pool. Neste caso, vamos pedir a hora aos servidores da Hora Legal de Portugal6\n1 echo \u0026#34;ntpclient -c 1 -s -t -h 194.117.47.42 || ntpclient -c 1 -s -t -h 194.117.47.44\u0026#34; \u0026gt;\u0026gt; /opt/bootlocal.sh 2) Sincronizar o RTC Mas o TinyCore, até lhe dizerem o contrário, ignora esta hora e vai sempre buscar a hora do relógio de hardware, que sem Guest Additions não sabe perguntar ao host e arranca na mesma hora em que a VM foi desligada. Depois de recebermos a hora de sistema a partir de um servidor NTP, temos de actualizar o relógio de hardware com o comando hwclock -w\n1 echo \u0026#34;hwclock -w\u0026#34; \u0026gt;\u0026gt; /opt/bootlocal.sh 3) Corrigir o desvio de tempo Depois é não deixar que o relógio se vá desviando durante a operação do sistema, criando um processo que verifica periodicamente o tempo correcto:6\n1 echo \u0026#34;/usr/local/bin/ntpclient -c 0 -l -t -i 300 -h 3.pt.pool.ntp.org \u0026amp;\u0026#34; \u0026gt;\u0026gt; /opt/bootlocal.sh Um detalhe importante é que em caso de reboot, o relógio avança uma hora, mas correndo os dois primeiros comandos manualmente no final do arranque o tempo fica imediatamente corrigido. Não sei se é bug ou problema da minha configuração, tentei todas as combinações de UTC e localtime no Virtualbox e no TinyCore e não resolveu.\nComeçando de desligado, funciona bem.\r Conclusão O TinyCoreLinux é muito pequeno, mas isso tem os seus custos.\nTudo tem de ser configurado, tudo tem de ser definido como persistente.\nComporta-se mais como um container do que como uma instalação vulgar.\nNisso, tem boa companhia, porque o AlpineLinux tem exactamente a mesma atitude, e também é muito popular como base para containers (é o default do Docker) e sistemas embedded.\nNo entanto, parece-me que o TinyCore já começa a dar demasiado trabalho para aquilo que poupa em recursos. Já não estamos assim tão desesperados, geralmente.\nPara um sistema realmente minimalista, existe uma versão ainda mais reduzida, o MicroCoreLinux (ou simplesmente Core), sem ambiente gráfico e com apenas 8MB.\nPara algo que me permitiria ser produtivo rapidamente, tenho esperança no AlpineLinux, que vou tentar testar em breve.\n http://distro.ibiblio.org/tinycorelinux/\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n https://busybox.net/\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n http://tinycorelinux.net/install.html\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n -c = count \u0026lt;vezes\u0026gt;; -s = set; -t = trust; -h = host \u0026lt;endereço_servidor_NTP\u0026gt;\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n http://oal.ul.pt/hora-legal/como-acertar/\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n -c 0 = sem limite de tentativas; -l = lock; -i = intervalo ; este comando usa nomes e presume-se que existe resolução DNS\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n ","description":"Pequeno mas duro de roer","id":1,"section":"unixlike","tags":null,"title":"TinyCore Linux - Passos iniciais","uri":"https://tiagojsilva.github.io/pt/unixlike/meme/2021-10-29_tinycorelinux-install/"},{"content":"PKI baseada em OpenSSL (parte 1) Fontes:\nhttps://openssl-ca.readthedocs.io/en/latest/index.html\nhttps://www.golinuxcloud.com/tutorial-pki-certificates-authority-ocsp/\nhttps://social.technet.microsoft.com/wiki/contents/articles/2900.offline-root-certification-authority-ca.aspx\nhttps://pki-tutorial.readthedocs.io/en/latest/index.html\nRoot CA airgapped É suposto o sistema que contém a RootCA ser airgapped, ter acesso controlado, e ser ligado apenas para emissão de novas CAs e revogação de CAs comprometidas. Neste exemplo, podemos colocar tudo no mesmo servidor mas deve-se tentar separar o mais possível a estrutura da RootCA das outras CAs.\nO primeiro passo é criar uma Root Certification Authority (RootCA), que só vai criar outras CAs.\nMudar para o utilizador root\n1 2 3 4 5 6 7 mkdir /root/ca \u0026amp;\u0026amp; cd $_ mkdir /root/ca/{certs,crl,newcerts,private} chmod 700 /root/ca/private touch /root/ca/index.txt echo 1000 \u0026gt; /root/ca/serial echo 1000 \u0026gt; /root/ca/crlnumber cat \u0026gt; /root/ca/openssl.cnf /root/ca/openssl.cnf\n\r\rExpandir\r\r# OpenSSL root CA configuration file.\r# Copy to '/root/ca/openssl.cnf.\r[ ca ]\r# 'man ca'\rdefault_ca = CA_default\r[ CA_default ]\r# Directory and file locations.\rdir = /root/ca\rcerts = $dir/certs\rcrl_dir = $dir/crl\rnew_certs_dir = $dir/newcerts\rdatabase = $dir/index.txt\rserial = $dir/serial\rRANDFILE = $dir/private/.rand\r# The root key and root certificate.\rprivate_key = $dir/private/ca.key.pem\rcertificate = $dir/certs/ca.cert.pem\r# For certificate revocation lists.\rcrlnumber = $dir/crlnumber\rcrl = $dir/crl/ca.crl.pem\rcrl_extensions = crl_ext\rdefault_crl_days = 385\r# SHA-1 is deprecated, so use SHA-2 instead.\rdefault_md = sha512\rname_opt = ca_default\rcert_opt = ca_default\rdefault_days = 375\rpreserve = no\rpolicy = policy_strict\r[ policy_strict ]\r# The root CA should only sign intermediate certificates that match.\r# See the POLICY FORMAT section of 'man ca'.\rcountryName = match\rstateOrProvinceName = match\rorganizationName = match\rorganizationalUnitName = optional\rcommonName = supplied\remailAddress = optional\r[ policy_loose ]\r# Allow the intermediate CA to sign a more diverse range of certificates.\r# See the POLICY FORMAT section of the 'ca' man page.\rcountryName = optional\rstateOrProvinceName = optional\rlocalityName = optional\rorganizationName = optional\rorganizationalUnitName = optional\rcommonName = supplied\remailAddress = optional\r[ req ]\r# Options for the 'req' tool ('man req').\rdefault_bits = 4096\rdistinguished_name = req_distinguished_name\rstring_mask = utf8only\r# SHA-1 is deprecated, so use SHA-2 instead.\rdefault_md = sha512\r# Extension to add when the -x509 option is used.\rx509_extensions = v3_ca\r[ req_distinguished_name ]\r# See \u0026lt;https://en.wikipedia.org/wiki/Certificate_signing_request\u0026gt;.\rcountryName = Country Name (2 letter code)\rstateOrProvinceName = State or Province Name\rlocalityName = Locality Name\r0.organizationName = Organization Name\rorganizationalUnitName = Organizational Unit Name\rcommonName = Common Name\remailAddress = Email Address\r# Optionally, specify some defaults.\rcountryName_default = PT\rstateOrProvinceName_default = Lisboa\rlocalityName_default = Lisboa\r0.organizationName_default = TiagoJoaoSilva\rorganizationalUnitName_default = TJS\remailAddress_default = [email protected]\r[ v3_ca ]\r# Extensions for a typical CA ('man x509v3_config').\rsubjectKeyIdentifier = hash\rauthorityKeyIdentifier = keyid:always,issuer\rbasicConstraints = critical, CA:true\rkeyUsage = critical, digitalSignature, cRLSign, keyCertSign\r[ v3_intermediate_ca ]\r# Extensions for a typical intermediate CA ('man x509v3_config').\rsubjectKeyIdentifier = hash\rauthorityKeyIdentifier = keyid:always,issuer\rbasicConstraints = critical, CA:true, pathlen:0\rkeyUsage = critical, digitalSignature, cRLSign, keyCertSign\r[ usr_cert ]\r# Extensions for client certificates ('man x509v3_config').\rbasicConstraints = CA:FALSE\rnsCertType = client, email\rnsComment = \u0026quot;OpenSSL Generated Client Certificate\u0026quot;\rsubjectKeyIdentifier = hash\rauthorityKeyIdentifier = keyid,issuer\rkeyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment\rextendedKeyUsage = clientAuth, emailProtection\r[ server_cert ]\r# Extensions for server certificates ('man x509v3_config').\rbasicConstraints = CA:FALSE\rnsCertType = server\rnsComment = \u0026quot;OpenSSL Generated Server Certificate\u0026quot;\rsubjectKeyIdentifier = hash\rauthorityKeyIdentifier = keyid,issuer:always\rkeyUsage = critical, digitalSignature, keyEncipherment\rextendedKeyUsage = serverAuth\r[ crl_ext ]\r# Extension for CRLs ('man x509v3_config').\rauthorityKeyIdentifier=keyid:always\r[ ocsp ]\r# Extension for OCSP signing certificates ('man ocsp').\rbasicConstraints = CA:FALSE\rsubjectKeyIdentifier = hash\rauthorityKeyIdentifier = keyid,issuer\rkeyUsage = critical, digitalSignature\rextendedKeyUsage = critical, OCSPSigning\r\r\r\nCriamos uma palavra-passe complexa:\n1 2 3 openssl rand -base64 12 \u0026gt; /root/ca/private/ca.key.pass chmod 400 /root/ca/private/ca.key.pass cat /root/ca/private/ca.key.pass ayUiXnIjZFRh\r\nCriamos a chave indicando a palavra-passe complexa:\n1 2 openssl genrsa -aes256 -passout file:/root/ca/private/ca.key.pass \\ -out /root/ca/private/ca.key.pem 8192 Generating RSA private key, 8192 bit long modulus (2 primes)\r......................................................+++\r..+++\re is 65537 (0x010001)\r\nCriamos e auto-assinamos o certificado da RootCA:\n1 2 3 4 5 6 chmod 400 /root/ca/private/ca.key.pem openssl req -config /root/ca/openssl.cnf \\ -passin file:/root/ca/private/ca.key.pass \\ -key /root/ca/private/ca.key.pem \\ -new -x509 -days 7300 -sha512 -extensions v3_ca \\ -out /root/ca/certs/ca.cert.pem You are about to be asked to enter information that will be incorporated\rinto your certificate request.\rWhat you are about to enter is what is called a Distinguished Name or a DN.\rThere are quite a few fields but you can leave some blank\rFor some fields there will be a default value,\rIf you enter '.', the field will be left blank.\r-----\rCountry Name (2 letter code) [PT]:\rState or Province Name [Lisboa]:\rLocality Name [Lisboa]:\rOrganization Name [TiagoJoaoSilva]:\rOrganizational Unit Name [TJS]:\rCommon Name []:ca-tjs-1\rEmail Address [[email protected]]:\r 1 chmod 444 /root/ca/certs/ca.cert.pem Podemos examinar o conteúdo do certificado:\n1 openssl x509 -noout -text -in /root/ca/certs/ca.cert.pem Certificate:\rData:\rVersion: 3 (0x2)\rSerial Number:\r25:92:4d:14:da:6f:9f:8b:4b:49:55:fc:68:be:9e:c7:57:24:cd:70\rSignature Algorithm: sha512WithRSAEncryption\rIssuer: C = PT, ST = Lisboa, L = Lisboa, O = TiagoJoaoSilva, OU = TJS, CN = ca-tjs-1, emailAddress = [email protected]\rValidity\rNot Before: Aug 12 19:38:30 2021 GMT\rNot After : Aug 7 19:38:30 2041 GMT\rSubject: C = PT, ST = Lisboa, L = Lisboa, O = TiagoJoaoSilva, OU = TJS, CN = ca-tjs-1, emailAddress = [email protected]\rSubject Public Key Info:\rPublic Key Algorithm: rsaEncryption\rRSA Public-Key: (8192 bit)\rModulus: [...]\rExponent: 65537 (0x10001)\rX509v3 extensions:\rX509v3 Subject Key Identifier:\r01:F2:CC:54:E0:F2:58:AC:E2:14:8E:2B:DB:6D:B6:FF:5C:25:41:A0\rX509v3 Authority Key Identifier:\rkeyid:01:F2:CC:54:E0:F2:58:AC:E2:14:8E:2B:DB:6D:B6:FF:5C:25:41:A0\rX509v3 Basic Constraints: critical\rCA:TRUE\rX509v3 Key Usage: critical\rDigital Signature, Certificate Sign, CRL Sign\rSignature Algorithm: sha512WithRSAEncryption\r[...]\r Revogação de certificados Antes de irmos mais longe, acho que temos de falar já na revogação de certificados, ao contrário de todos os outros tutoriais da Internet que deixam esse assunto para o fim, se chegam sequer a falar nele. Se não o fizermos agora, será demasiado tarde para ser incluído em qualquer certificado criado pela RootCA.\nComo revogar um certificado 1 2 3 4 5 6 stamp=$(date +%F_%T) mv /root/ca/inter-ca/certs/example-ca.cert.pem{,-revoked_$stamp} openssl ca -config /root/ca/openssl.cnf \\ -passin file:/root/ca/private/ca.key.pass \\ -revoke /root/ca/inter-ca/certs/example-ca.cert.pem-revoked_$stamp \\ -crl_reason unspecified -crl_reason também pode ter os valores keyCompromise, CACompromise, affiliationChanged, superseded, cessationOfOperation, certificateHold, ou (só em Delta-CRLs) removeFromCRL\n-crl_hold coloca automaticamente a reason como certificateHold mas está fora do âmbito deste documento\n-crl_compromise AAAAMMDDHHMMSSZ coloca a reason como\nkeyCompromise na data assinalada.\n-crl_CA_compromise AAAAMMDDHHMMSSZ faz o mesmo, mas a reason é CACompromise\nPrecisamos de configurar um mecanismo para a RootCA disseminar a informação dos certificados revogados, e isso precisa de ser feito antes de se criar qualquer certificado subsequente, acrescentando informações ao openssl.cnf da RootCA antes de criar qualquer CA secundária.\nDistribuição de CRL O método clássico é a distribuição directa das listas CRL, que pode ser feita por vários meios, como um servidor HTTP, uma directoria LDAP ou AD, etc. Pode existir ainda uma complicação adicional, porque para evitar a transmissão constante de ficheiros grandes podem-se utilizar Delta-CRLs apenas com as alterações ao CRL; no entanto, apesar de esta ser uma possibilidade em Windows ou em outros pacotes de PKI, não está implementada no OpenSSL. Estas listas costumam ser actualizadas (porque expiram e todos os certificados dessa CA deixam de ser aceites) no máximo de 30 em 30 dias, mas a lista de CRLs da RootCA não deve expirar (ou expirar apenas anualmente quando for altura de actualizar o sistema que contém a RootCA).\n[CA_default]\rdefault_crl_days = 385\rNessa altura, refresca-se o CRL e (no caso de o sistema da RootCA ser airgapped), extrair o CRL (em papel, QR Code, CD-R ou outro meio seguro) e levá-lo para o sistema de onde vai ser distribuído.\nO formato de distribuição destas listas é DER (codificação binária), mas o ficheiro tem de ter a extensão .CRL (RFC 2585).\nO outro método, mais recomendado nos dias de hoje, é a utilização de um OCSP Responder para responder a consultas sobre a validade de um certificado, que é uma operação rápida que não necessita de muita largura de banda, permite que a disseminação da revogação seja assinada com uma chave da CA-mãe, e que a resposta fique em cache nos clientes (através de OCSP Stapling).\nComo o CRL da RootCA vai conter muito poucos certificados (a RootCA só vai emitir outras CAs, chamadas IntermediateCAs, SubordinateCAs ou SigningCAs, que serão poucas), vamos configurar uma emissão manual de CRLs para a RootCA.\nComeçamos por colocar a informação do local de onde será servido o CRL na secção [ v3_intermediate_ca ] do /root/ca/openssl.cnf, para ser incluída nos certificados das CAs emitidas pela RootCA. Vamos utilizar um servidor HTTP na porta 7788:\n[ v3_intermediate_ca ]\rcrlDistributionPoints = URI:http://server.tjs.lan:7788/root-ca.crl\rCriamos o CRL (https://blog.didierstevens.com/2013/05/08/howto-make-your-own-cert-and-revocation-list-with-openssl/)\n1 2 3 4 openssl ca -config /root/ca/openssl.cnf -gencrl \\ -passin file:/root/ca/private/ca.key.pass \\ -keyfile /root/ca/private/ca.key.pem -cert /root/ca/certs/ca.cert.pem \\ -out /root/ca/crl/ca.crl.pem Verificamos o conteúdo do CRL:\n1 openssl crl -in /root/ca/crl/ca.crl.pem -noout -text Certificate Revocation List (CRL):\rVersion 2 (0x1)\rSignature Algorithm: sha512WithRSAEncryption\rIssuer: C = PT, ST = Lisboa, L = Lisboa, O = TiagoJoaoSilva, OU = TJS, CN = ca-tjs-1, emailAddress = [email protected]\rLast Update: Aug 13 23:46:07 2021 GMT\rNext Update: Sep 2 23:46:07 2022 GMT\rCRL extensions:\rX509v3 Authority Key Identifier:\rkeyid:01:F2:CC:54:E0:F2:58:AC:E2:14:8E:2B:DB:6D:B6:FF:5C:25:41:A0\rX509v3 CRL Number:\r4097\rRevoked Certificates:\rSerial Number: 1001\rRevocation Date: Aug 13 22:11:25 2021 GMT\rCRL entry extensions:\rX509v3 CRL Reason Code:\rUnspecified\rSerial Number: 1002\rRevocation Date: Aug 13 23:41:51 2021 GMT\rCRL entry extensions:\rX509v3 CRL Reason Code:\rSuperseded\rSignature Algorithm: sha512WithRSAEncryption [...]\r\nE temos de converter o PEM (Base64) para formato DER:\n1 2 # openssl crl -inform PEM -in /root/ca/crl/ca.crl.pem \\ -outform DER -out /root/ca/crl/root-ca.crl Sistema ligado à rede Como a RootCA deve ser airgapped e offline, não é no sistema da RootCA que se deve configurar a distribuição de CRLs, porque esse sistema tem de estar acessível na rede.\nConfiguramos um novo sistema Debian 11 e recriamos a pasta que contém o CRL da RootCA:\n1 mkdir -p /root/ca/crl Fazemos lá chegar o ficheiro root-ca.crl de alguma maneira segura (gravar um CD-R, impressão e scanning com OCR, etc.) e colocámo-lo em /root/ca/crl\nInstalar e configurar o servidor web do CRL Vamos usar um servidor muito básico, o lighttpd\n1 apt install lighttpd -y De acordo com o wiki do Debian sobre o Lighttpd a instalação por defeito configura o serviço, agarra a porta 80/TCP, corre com o utilizador www-data, configura a webroot para ser /var/www/html, e os ficheiros default são index.php ou index.html, se bem que venha configurado para não correr ficheiros .php.\nVamos configurar outra porta (7788), a webroot será outra para não interferir com a default que é usada por outros servidores web, e desligar o desvio automático para index.html\nAlém disso, o que pode ser importante, a configuração de tipos MIME foi pré-feita com um script Perl, que se calhar vamos ter de editar ou refazer porque os ficheiros CRL têm de ser servidos por HTTP com um tipo MIME específico, application/pkix-crl\n(https://pki-tutorial.readthedocs.io/en/latest/mime.html)\n1 cp /etc/lighttpd/lighttpd.conf{,.orig} Mudar as linhas:\n 1 server.modules = (\r2 # \u0026quot;mod_indexfile\u0026quot;,\r3 # \u0026quot;mod_access\u0026quot;,\r4 # \u0026quot;mod_alias\u0026quot;,\r5 # \u0026quot;mod_redirect\u0026quot;,\r6 )\r8 server.document-root = \u0026quot;/var/www/crl\u0026quot;\r10 server.errorlog = \u0026quot;/var/log/lighttpd/crl-error.log\u0026quot;\r14 server.port = 7788\r41 #index-file.names = ( \u0026quot;index.php\u0026quot;, \u0026quot;index.html\u0026quot; )\rCriar a nova pasta webroot:\n1 mkdir /var/www/crl Mover para lá o index.html deixado pelo pacote lighttpd e desactivá-lo:\n1 2 mv /var/www/html/index.lighttpd.html /var/www/crl/index.lighttpd.html.disabled Colocar o CRL em formato DER dentro da webroot:\n1 2 3 cp /root/ca/crl/root-ca.crl /var/www/crl/root-ca.crl chown www-data:www-data /var/www/crl/root-ca.crl chmod 400 /var/www/crl/root-ca.crl Para configurar os tipos MIME, o lighttpd.conf chama um script que cria uma configuração MIME a partir dos tipos definidos em /etc/mime.types; será que este último já tem uma definição para o tipo MIME do CRL?\n1 grep pkix-crl /etc/mime.types application/pkix-crl crl\r\nPortanto, a linha 47 do lighttpd.conf vai criar uma lista de tipos MIME que inclui o nosso tipo CRL de cada vez que o serviço lighttpd for iniciado.\n47 include_shell \u0026quot;/usr/share/lighttpd/create-mime.conf.pl\u0026quot;\rConfirmamos a sintaxe do ficheiro lighttpd.conf:\n1 lighttpd -tt -f /etc/lighttpd/lighttpd.conf 2021-08-14 02:26:38: configfile.c.1142) WARNING: unknown config-key:\rurl.access-deny (ignored)\r\nEste erro não é importante, por isso:\n1 2 systemctl restart lighttpd systemctl status lighttpd ● lighttpd.service - Lighttpd Daemon\rLoaded: loaded (/lib/systemd/system/lighttpd.service; enabled; vendor preset: enabled)\rActive: active (running)\r 1 systemctl enable lighttpd Synchronizing state of lighttpd.service with SysV service script with /lib/systemd/systemd-sysv-install.\rExecuting: /lib/systemd/systemd-sysv-install enable lighttpd\r\nAbrimos a porta 7788 na firewall:\n1 ufw allow 7788 E testamos o acesso ao ficheiro:\n1 wget localhost:7788/root-ca.crl Resolving localhost (localhost)... ::1, 127.0.0.1\rConnecting to localhost (localhost)|::1|:7788... connected.\rHTTP request sent, awaiting response... 200 OK\rLength: 1359 (1.3K) [application/pkix-crl]\rSaving to: ‘root-ca.crl’\rroot-ca.crl 100%[=================================================] 1.33K --.-KB/s in 0s\r2021-08-14 02:33:18 (168 MB/s) - ‘root-ca.crl’ saved [1359/1359] \nFoi estabelecida ligação e o ficheiro é servido com o tipo MIME correcto.\nMas infelizmente, só se devem usar CRLs quando temos a certeza que os clientes suportam este formato (e nesse aspecto, quem se porta melhor é a Microsoft); por exemplo, é impossível revogar certificados de Webserver por distribuição de CRLs porque apenas o Internet Explorer tem código para descarregar e analisar um CRL (Firefox e Chrome não querem saber) https://news.netcraft.com/archives/2013/05/13/how-certificate-revocation-doesnt-work-in-practice.html . Por isso é mais seguro configurar o mecanismo alternativo, que é um OCSP Responder, também chamado AIA devido à directiva que o configura ( AuthorityInfoAccess).\nConfiguração do CNF com o endereço do OCSP Responder Começamos por colocar no openssl.cnf da RootCA a seguinte directiva, na secção [ intermediate_ca ]\nauthorityInfoAccess = OCSP;URI:http://ocsp.tjs.lan:7899\rA porta TCP do OCSP pode ser qualquer uma, sendo usual colocá-lo numa porta de tráfego HTTP pouco usada (como a 8008). Escolhi a porta 7899 porque depois de analisada a lista de portas da IANA, as portas 7888-7899/TCP não estão atribuídas, podendo ser usadas para este fim. Também se poderia desligar o lighttpd e reutilizar a porta 7788.\nO protocolo é HTTP e não HTTPS porque como se verificaria o certificado SSL do OCSP? (https://social.technet.microsoft.com/Forums/office/en-US/c65e1784-39be-4732-a135-bfba7446ad05/should-the-ocsp-responder-service-be-running-http-80-or-https-443-) A configuração de um OCSP Responder será documentada no segmento seguinte, que será a configuração da IntermediateCA; deixamos já a informação no .CNF da RootCA caso mais tarde se deseje implementar um OCSP Responder para ela também.\nNote-se: se estas informações não forem configuradas agora, só poderão ser introduzidas na PKI (e passadas a certificados emitidos pela RootCA) revogando e re-emitindo todos os certificados já emitidos; por isso a estrutura de uma PKI deve ser ponderada antes de ser implementada.\nPodemos passar à configuração da IntermediateCA.\n","description":"PKI em OpenSSL: parte 1 (RootCA)","id":2,"section":"sec","tags":null,"title":"PKI OpenSSL (pt 1)","uri":"https://tiagojsilva.github.io/pt/sec/pki/opensslpki_1/"},{"content":"Uma vez precisei de tentar simular uma rede heterogénea, com um router Cisco e um Huawei.\nNão foi fácil, porque o IOS não está disponível publicamente e o simulador da Huawei, o eNSP, está descontinuado e só funciona em VirtualBox 5.\nPara fazer esta simulação, é necessário um CPU que suporte VM nesting (Second-Level Address Translation - SLAT)\nVM de simulação Foi criada uma VM baseada em Windows 7, com 4GB de RAM, 2 vCPUs e 4 interfaces de rede. Pode ser possível baixar a RAM para 2GB, mas tal não foi testado; 1GB foi testado e é insuficiente.\n\r\rPara que o protocolo ARP dos routers simulados não se queixe que há IPs duplicados em MACs diferentes, é necessário fazer MAC Spoofing de propósito, colocando na configuração de MAC de cada interface do VirtualBox o MAC da porta do router simulado que vai comunicar com ela; primeiro deixa-se o MAC na configuração standard, e depois mal se levantem os routers simulados lê-se o MAC de cada porta, desliga-se a VM, e introduz-se esse MAC na configuração da interface correspondente do VirtualBox antes de ligar de novo a VM.\nO router simulado Cisco pode mudar os seus MACs para duplicar os MACs do VirtualBox, por isso este passo é facultativo para as interfaces do router Cisco; o mesmo deveria ser possível no router Huawei, mas apesar de isso estar descrito no manual, a simulação do AR2220 não pode mudar os seus MACs, por isso este passo é obrigatório para que o router simulado Huawei funcione.\nA configuração final será:\nInterface Virtual 1 Internal Network: WAN Se possível com MAC idêntico à interface externa do router simulado Cisco Promiscuous: Allow All Interface Virtual 2 Internal Network: LAN Se possível com MAC idêntico à interface interna do router simulado Cisco Promiscuous: Allow All Interface Virtual 3 Internal Network: WAN Sempre mesmo MAC da interface externa do router simulado Huawei Promiscuous: Allow All Interface Virtual 4 Internal Network: LAN Sempre mesmo MAC da interface interna do router simulado Huawei Promiscuous: Allow All\n\r\r Configuração de rede do guest Control Panel, Network Connections\nInterface da Interface Virtual 1 (confirmar, por exemplo, desligando o cabo de rede virtual)\nNome: C-Outside ou Cisco-EXT\nIP: 10.5.222.4\nNetmask: 255.255.0.0\nGateway: \u0026ndash;\nInterface da Interface Virtual 2 Nome: C-Inside ou Cisco-INT\nIP: 10.10.0.58\nNetmask: 255.255.255.248\nGateway: \u0026ndash;\nInterface da Interface Virtual 3 Nome: H-Outside ou Huawei-EXT\nIP: 10.5.222.6\nNetmask: 255.255.0.0\nGateway: \u0026ndash;\nInterface da Interface Virtual 2 Nome: H-Inside ou Huawei-INT\nIP: 10.10.0.59\nNetmask: 255.255.255.248\nGateway: \u0026ndash;\nSoftware a instalar VirtualBox 5.2.x e Extension Pack Winpcap 4.1.3 Wireshark-win64 3.2.5 eNSP V100R002C00B510 Setup GNS3 2.2.x ou superior (não instalar suporte para GNS3 VM) Finalizar a configuração da VM Salvar todos os projectos, desligar todos os programas, desligar a VM (Shutdown)\nNas propriedades Network da VM, mudar o MAC Address de cada interface virtual para o MAC da porta do router a que vai estar ligada (via clouds nos emuladores).\n\r\rArrancar com a VM de novo, abrir os projectos e configurar os routers\nConfiguração GNS3 para simulação de router Cisco 7200 Criar um template para o Cisco 7200 Clicar na primeira opçao da barra da esquerda, Browse Routers\n+ New template\n\r\rInstall appliance from server\nNext\nEscolher Routers \u0026gt; Cisco 7200 / Dynamips\nInstall\n\r\rInstall on this computer\nNext\nAllow custom files\nNo aviso Do you want to proceed? Yes\nEscolher o ficheiro .image (que está Missing) e clicar no botao Import que aparece em baixo\n\r\rEscolher o ficheiro c7200-adventerprisek9-mz.152-4.S3.bin com o checksum 79ffe4050b2cac60d51af8b953bb02b7. Não sei como encontrei este ficheiro, seguramente que me caiu do céu e de certeza que não tenho autorização para o usar. As imagens oficiais da Cisco para uso académico são incluídas na anualidade do VIRL - Cisco Modeling Labs\nOpen\nThis is not the correct file\nYes\n\r\rFica Ready to Install\nOpcionalmente, pode-se clicar em Create a new version e criar a versão 152-4.S3\nSeleccionar a versão original ou a nova versão criada, e\nNext\n\r\rDo you want to install?\nYes\nCriar uma nova topologia para o router Cisco Criar um novo projecto\nArrastar um router Cisco 7200 do template que criámos.\nClique-direito, Configure\n\r\rAdicionamos mais interfaces de rede ao router:\nSeparador Slots\nSlot 1: PA-GE\nSlot 2: PA-GE\nOK\n\r\rClicar no ecrã da barra à esquerda (Browse End Devices).\nArrastar duas Clouds para a topologia e dar-lhes nomes adequados\n\r\rClicar no cabo da barra à esquerda (Add links) - o cursor passa para um +\nClicar no router, escolher uma porta\n\r\rClicar numa das Clouds, escolher a interface de rede do Windows usada para essa porta\n\r\rFazer o mesmo com a outra Cloud.\nClique-direito no router, Start para o iniciar\nClique-direito no router, Console para aceder à consola série\n\r\rClicar em Enter (RETURN), e o router simulado arranca logo em modo privilegiado (#)\nAnotar o MAC das interfaces que se querem ligar ao exterior da topologia, porque precisamos de colocar esses MACs nas interfaces virtuais respectivas do Virtualbox 6\n1 show interface gig1/0 GigabitEthernet1/0 is administratively down, line protocol is down\rHardware is 82543, address is ca01.0438.001c (bia **ca01.0438.001c**)\r Configuração do Huawei simulado Configurar o eNSP para simular router Huawei AR2220 Ao contrário da simulação da Cisco, o uso das imagens do eNSP é livre (até porque se trata de um Linux que simula o software real e não uma cópia do software real em si mesmo como no caso da imagem IOS).\nCriar uma nova topologia para o router Huawei Clicar no botão New Topo\n\r\rArrastar um router (exemplo, AR2220)\n\r\rArrastar duas Clouds e dar-lhes nome\n\r\rClique-direito numa cloud, Settings\n\r\rNa cloud Outside, clique-direito, Settings\nPort Building\nBinding info: UDP\nPort type: Ethernet\nAdd\n\r\rBinding info: escolher a interface 3\nPort type: Ethernet\nAdd\n\r\rPort Map Setting\nPort type: Ethernet\nLocal Port: 1\nRemote Port: 2\nTwo-way Channel\nAdd\n\r\rFechar a janela\n\r\rNa Cloud Inside, clique-direito, Settings\nPort Building\nBinding info: UDP\nPort type: Ethernet\nAdd\nBinding info: escolher a interface 4\nPort type: Ethernet\nAdd\nPort Map Setting\nPort type: Ethernet\nLocal Port: 1\nRemote Port: 2\nTwo-way Channel\nAdd\nFechar a janela\nClicar nas ligações (relâmpago), seleccionar Auto ou Copper\nLigar o router a cada uma das clouds (como no Packet Tracer - clicar, escolher porta, clicar no destino, escolher porta)\n\r\r\r\rTecla Esc para sair do modo de ligação (cursor passa para ponteiro normal)\nClique direito no router, Start\nClique direito no router, CLI\n\r\rTirar o MAC das interfaces que foram ligadas às clouds\n\u0026lt;Huawei\u0026gt; display int g0/0/0\r[…]\rIP Sending Frames' Format is PKTFMT_ETHNT_2, Hardware address is\r**00e0-fc29-614c**\r[…]\r\n\r\rConfiguração inicial Huawei Abrir CLI do AR2220\nMay 16 2021 07:43:40-08:00 Huawei %%01IFPDT/4/IF_STATE(l)[0]:Interface GigabitEthernet0/0/0 has turned into UP state.\rMay 16 2021 07:43:40-08:00 Huawei %%01IFPDT/4/IF_STATE(l)[1]:Interface GigabitEthernet0/0/1 has turned into UP state.\r\nVemos a configuração-base:\n\u0026lt;Huawei\u0026gt; display current\r[V200R003C00]\r#\rsnmp-agent local-engineid 800007DB03000000000000\rsnmp-agent #\rclock timezone China-Standard-Time minus 08:00:00\r#\rportal local-server load portalpage.zip\r#\rdrop illegal-mac alarm\r#\rset cpu-usage threshold 80 restore 75\r#\raaa authentication-scheme default\rauthorization-scheme default\raccounting-scheme default\rdomain default domain default_admin local-user admin password cipher %$%$K8m.Nt84DZ}e#Configuramos o relógio para não estar em Pequim:\n\u0026lt;Huawei\u0026gt; clock timezone GMT add 0\r\u0026lt;Huawei\u0026gt; clock daylight-saving-time GMT repeating 01:00 last Sun Mar 01:00 last sun Oct 01:00\r\u0026lt;Huawei\u0026gt; display clock\r2021-05-16 01:21:21 DST\rSunday\rTime Zone(GMT) : UTC+00:00\rDaylight saving time :\rName : GMT\rRepeat mode : repeat\rStart year : 2000\rEnd year : 2099\rStart time : last Sunday March 01:00:00\rEnd time : last Sunday October 01:00:00\rSaving time : 01:00:00\r \u0026lt;Huawei\u0026gt; system-view\rEnter system view, return user view with Ctrl+Z.\r [Huawei] display version\rHuawei Versatile Routing Platform Software\rVRP (R) software, Version 5.130 (AR2200 V200R003C00)\rCopyright (C) 2011-2012 HUAWEI TECH CO., LTD\rHuawei AR2220 Router uptime is 0 week, 0 day, 1 hour, 55 minutes\rBKP 0 version information: 1. PCB Version : AR01BAK2A VER.NC\r2. If Supporting PoE : No\r3. Board Type : AR2220\r4. MPU Slot Quantity : 1\r5. LPU Slot Quantity : 6\rMPU 0(Master) : uptime is 0 week, 0 day, 1 hour, 55 minutes\rMPU version information : 1. PCB Version : AR01SRU2A VER.A\r2. MAB Version : 0\r3. Board Type : AR2220\r4. BootROM Version : 0\r [Huawei] sysname RSFE\r[RSFE]\rTeste da redundância dos routers simulados Colocaram-se três pings a correr num cliente na rede LAN (interna). Como é um sistema Linux, usou-se a opção -O (letra \u0026ldquo;o\u0026rdquo; maiúscula) para que mostre o equivalente à mensagem de timeout do Windows\n Um ping para 1.1.1.1 Um ping para o endereço interior do Cisco, (neste caso, 10.10.0.60) Um ping para o endereço interior do Huawei, (neste caso, 10.10.0.61)\nNa situação normal, com o Cisco como router designado, temos acesso ao exterior\n\r\r Fazendo shut na interface interior do Cisco, o ping para 10.10.0.60 pára, mas mantemos o acesso exterior.\nNão sei qual a origem das respostas duplicadas ICMP, mas:\n com o Huawei como Backup os pings para 10.10.0.61 voltam duplicados com o Huawei como Master os pings para 10.10.0.61 voltam normalmente mas os pings para 1.1.1.1 é que passam a ter respostas duplicadas.\n\r\r Boa sorte! Espero que este hack bem cabeludo ajude alguém que necessite de configurar um sistema misto mesmo que se veja impedido de ter acesso aos equipamentos físicos, ou que sirva de exemplo para outras topologias mais avançadas.\n","description":"Quem não tem cão...","id":3,"section":"networking","tags":null,"title":"Simulação de router Cisco e Huawei ","uri":"https://tiagojsilva.github.io/pt/networking/simul/gns3-ensp/"},{"content":"OpenSSL PKI (parte 2) - IntermediateCA Criar uma IntermediateCA Mais uma vez, a(s) IntermediateCA(s) devem estar alojadas num sistema separado (server) daquele que aloja a RootCA, e o sistema da RootCA (root) deve estar airgapped e desligado da corrente. No sistema online não me parece má ideia manter as CAs secundárias debaixo de /root/ca, o que permite colocar o certificado da RootCA no mesmo caminho (/root/ca/certs/ca.cert.pem). No entanto, esta é a única informação da RootCA que é necessário trazer para o host da(s) CA(s) secundária(s); é debatível se vale a pena trazer o CRL da RootCA em formato PEM e colocá-lo em /root/ca/crl/ca.crl.pem, a não ser que este sistema online seja o mesmo que esteja a ser usado para distribuir o CRL da RootCA (como visto anteriormente).\n1 2 3 4 5 mkdir -p /root/ca/certs cp ca.cert.pem /root/ca/certs/ mkdir /root/ca/crl cp ca.crl.pem /root/ca/crl/ mkdir /root/ca/csr Criamos a árvore de pastas completa para suportar a operação da IntermediateCA:\n1 2 3 4 5 6 inter=\u0026#34;/root/ca/inter-ca\u0026#34; mkdir $inter/{certs,crl,csr,newcerts,private} chmod 700 $inter/private touch $inter/index.txt echo 1000 \u0026gt; $inter/serial echo 1000 \u0026gt; $inter/crlnumber Criamos o ficheiro de configuração da Inter-CA:\n1 cat \u0026gt; $inter/openssl.cnf /root/ca/inter-ca/openssl.cnf\n\r\rExpandir\r\r# OpenSSL intermediate CA configuration file.\r# Copy to '/root/ca/inter-ca/openssl.cnf'.\r[ ca ]\r# 'man ca'\rdefault_ca = CA_default\r[ CA_default ]\r# Directory and file locations.\rdir = /root/ca/inter-ca\rcerts = $dir/certs\rcrl_dir = $dir/crl\rnew_certs_dir = $dir/newcerts\rdatabase = $dir/index.txt\rserial = $dir/serial\rRANDFILE = $dir/private/.rand\r# The root key and root certificate.\rprivate_key = $dir/private/inter-ca.key.pem\rcertificate = $dir/certs/inter-ca.cert.pem\r# For certificate revocation lists.\rcrlnumber = $dir/crlnumber\rcrl = $dir/crl/inter-ca.crl.pem\rcrl_extensions = crl_ext\rdefault_crl_days = 30\r# SHA-1 is deprecated, so use SHA-2 instead.\rdefault_md = sha512\rname_opt = ca_default\rcert_opt = ca_default\rdefault_days = 375\rpreserve = no\rpolicy = policy_loose\r# copy SAN, OCSP and other stuff to downstream certificates\rcopy_extensions = copy\r[ policy_strict ]\r# The root CA should only sign intermediate certificates that match.\r# See the POLICY FORMAT section of 'man ca'.\rcountryName = match\rstateOrProvinceName = match\rorganizationName = match\rorganizationalUnitName = optional\rcommonName = supplied\remailAddress = optional\r[ policy_loose ]\r# Allow the intermediate CA to sign a more diverse range of certificates.\r# See the POLICY FORMAT section of the 'ca' man page.\rcountryName = optional\rstateOrProvinceName = optional\rlocalityName = optional\rorganizationName = optional\rorganizationalUnitName = optional\rcommonName = supplied\remailAddress = optional\r[ req ]\r# Options for the 'req' tool ('man req').\rdefault_bits = 4096\rdistinguished_name = req_distinguished_name\rstring_mask = utf8only\r# SHA-1 is deprecated, so use SHA-2 instead.\rdefault_md = sha512\r# Extension to add when the -x509 option is used.\rx509_extensions = v3_ca\r[ req_distinguished_name ]\r# See \u0026lt;https://en.wikipedia.org/wiki/Certificate_signing_request\u0026gt;.\rcountryName = Country Name (2 letter code)\rstateOrProvinceName = State or Province Name\rlocalityName = Locality Name\r0.organizationName = Organization Name\rorganizationalUnitName = Organizational Unit Name\rcommonName = Common Name\remailAddress = Email Address\r# Optionally, specify some defaults.\rcountryName_default = PT\rstateOrProvinceName_default = Lisboa\rlocalityName_default = Lisboa\r0.organizationName_default = TiagoJoaoSilva\rorganizationalUnitName_default = TJS\remailAddress_default = [email protected]\r[ v3_ca ]\r# Extensions for a typical CA ('man x509v3_config').\rsubjectKeyIdentifier = hash\rauthorityKeyIdentifier = keyid:always,issuer\rbasicConstraints = critical, CA:true\rkeyUsage = critical, digitalSignature, cRLSign, keyCertSign\r[ v3_intermediate_ca ]\r# Extensions for a typical intermediate CA ('man x509v3_config').\rsubjectKeyIdentifier = hash\rauthorityKeyIdentifier = keyid:always,issuer\rbasicConstraints = critical, CA:true, pathlen:0\rkeyUsage = critical, digitalSignature, cRLSign, keyCertSign\r[ usr_cert ]\r# Extensions for client certificates ('man x509v3_config').\rbasicConstraints = CA:FALSE\rnsCertType = client, email\rnsComment = \u0026quot;OpenSSL Generated Client Certificate\u0026quot;\rsubjectKeyIdentifier = hash\rauthorityKeyIdentifier = keyid,issuer\rkeyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment\rextendedKeyUsage = clientAuth, emailProtection\r[ server_cert ]\r# Extensions for server certificates ('man x509v3_config').\rbasicConstraints = CA:FALSE\rnsCertType = server\rnsComment = \u0026quot;OpenSSL Generated Server Certificate\u0026quot;\rsubjectKeyIdentifier = hash\rauthorityKeyIdentifier = keyid,issuer:always\rkeyUsage = critical, digitalSignature, keyEncipherment\rextendedKeyUsage = serverAuth\r[ crl_ext ]\r# Extension for CRLs ('man x509v3_config').\rauthorityKeyIdentifier=keyid:always\r[ ocsp ]\r# Extension for OCSP signing certificates ('man ocsp').\rbasicConstraints = CA:FALSE\rsubjectKeyIdentifier = hash\rauthorityKeyIdentifier = keyid,issuer\rkeyUsage = critical, digitalSignature\rextendedKeyUsage = critical, OCSPSigning\r\r\r\nNum mundo ideal, haveria várias sub-CAs, nomeadas pelo uso a que se destinariam (geralmente com conjuntos de extensões diferentes para cada utilização):\n tls-ca: certificados para servidores e clientes vpn-ca: certificados para VPNs mime-ca: certificados para email code-ca: certificados para code signing net-ca: certificados para activos de rede\nA configuração dessas extensões está fora do âmbito deste documento. Mas cada uma delas teria a sua árvore de pastas e a sua cópia do openssl.cnf, ao qual eu daria um nome mais específico em cada caso.\nNa realidade, parece que quase ninguém se dá a este trabalho; geralmente existe uma CA separada para VPNs externas, se a empresa assinar software existe uma CA para code-signing, e depois uma única CA para todos os sistemas internos. Para que não seja preciso criar ficheiros de configuração separados para cada certificado re-especificando todas as funcionalidades que são comuns à InterCA, acrescentamos o seguinte a /root/ca/inter-ca/openssl.cnf:\n[ CA_default ]\r(…)\r# copy extensions missing from the CSR to the final certificate\rcopy_extensions = copy\rDe notar que como esta IntermediateCA é mais dinâmica que a RootCA, a vigência dos CRLs não deve ser maior do que 30 dias; aconselho que se configure uma tarefa periódica que refresque o CRL a cada 29 dias.\ndefault_crl_days = 30\rCriamos uma nova palavra-passe complexa para a InterCA:\n1 2 openssl rand -base64 12 \u0026gt; $inter/private/inter-ca.key.pass chmod 400 $inter/private/inter-ca.key.pass Criamos a chave da InterCA indicando a palavra-passe complexa:\n1 2 openssl genrsa -aes256 -passout file:$inter/private/inter-ca.key.pass \\ -out $inter/private/inter-ca.key.pem 8192 Generating RSA private key, 8192 bit long modulus (2 primes)\r......................................................................................................................................................................................................+++\r.....................................................................................................................................................................................................+++\re is 65537 (0x010001)\r 1 # chmod 400 $inter-ca/private/inter-ca.key.pem Criamos o Certificate Signing Request para assinarmos com a CA (note-se que fica nos CSRs da RootCA):\n1 2 3 4 openssl req -config $inter/openssl.cnf -new -sha512 \\ -passin file:$inter/private/inter-ca.key.pass \\ -key $inter/private/inter-ca.key.pem \\ -out /root/ca/csr/inter-ca.csr.pem You are about to be asked to enter information that will be incorporated\rinto your certificate request.\rWhat you are about to enter is what is called a Distinguished Name or a DN.\rThere are quite a few fields but you can leave some blank\rFor some fields there will be a default value,\rIf you enter '.', the field will be left blank.\r-----\rCountry Name (2 letter code) [PT]:\rState or Province Name [Lisboa]:\rLocality Name [Lisboa]:\rOrganization Name [TiagoJoaoSilva]:\rOrganizational Unit Name [TJS]:\rCommon Name []:**inter-ca-tjs-2**\rEmail Address [[email protected]]\r Assinar o CSR com a RootCA Voltamos ao sistema offline da RootCA e criamos a árvore de pastas necessária.\nComo apenas vai suportar a criação das InterCAs e não a sua operação, é muito mais simples:\n1 2 3 inter=\u0026#34;/root/ca/inter-ca\u0026#34; mkdir $inter/certs chmod 740 $inter/certs Trazemos do sistema online o CSR da IntermediateCA, que colocamos no mesmo local onde estava no sistema online (a pasta de CSRs da RootCA):\n1 cp inter-ca.csr.pem /root/ca/csr Para que a informação CDL e/ou AIA da RootCA seja passada à IntermediateCA, acrescentamos esta directiva à secção [ CA_default ] de /root/ca/openssl.cnf\n# copy extensions missing from the CSR to the final certificate\rcopy_extensions = copy\rAgora assinamos o CSR; note-se que vamos indicar que a extensão a usar do /root/ca/openssl.cnf é a [ v3_intermediate_ca ]!\n1 2 3 4 5 openssl ca -config /root/ca/openssl.cnf -extensions v3_intermediate_ca \\ -days 3650 -notext -md sha512 \\ -passin file:/root/ca/private/ca.key.pass \\ -in /root/ca/csr/inter-ca.csr.pem \\ -out $inter/certs/inter-ca.cert.pem Using configuration from /root/ca/openssl.cnf\rCheck that the request matches the signature\rSignature ok\rCertificate Details:\rSerial Number: 4099 (0x1003)\rValidity\rNot Before: Aug 13 23:44:07 2021 GMT\rNot After : Aug 11 23:44:07 2031 GMT\rSubject:\rcountryName = PT\rstateOrProvinceName = Lisboa\rorganizationName = TiagoJoaoSilva\rorganizationalUnitName = TJS\rcommonName = inter-ca-tjs-2\remailAddress = [email protected]\rX509v3 extensions:\rX509v3 Subject Key Identifier:\rE3:75:25:D7:74:08:0B:23:F0:AF:E4:EC:D0:D4:52:CB:5A:3A:10:2E\rX509v3 Authority Key Identifier:\rkeyid:01:F2:CC:54:E0:F2:58:AC:E2:14:8E:2B:DB:6D:B6:FF:5C:25:41:A0\rX509v3 Basic Constraints: critical\rCA:TRUE, pathlen:0\rX509v3 Key Usage: critical\rDigital Signature, Certificate Sign, CRL Sign\rX509v3 CRL Distribution Points:\rFull Name:\rURI:http://server.tjs.lan:7788/root-ca.crl\rCertificate is to be certified until Aug 11 23:44:07 2031 GMT (3650 days)\rSign the certificate? [y/n]:Y\r1 out of 1 certificate requests certified, commit? [y/n]Y\rWrite out database with 1 new entries\rData Base Updated\r\nVerificamos a emissão:\n1 openssl verify -CAfile /root/ca/certs/ca.cert.pem $inter/certs/inter-ca.cert.pem /root/ca/inter-ca/certs/inter-ca.cert.pem: OK\r\nCriamos um certificado para a cadeia de autoridade com um certificado Chain (também chamado Bundle), concatenando os certificados por ordem ascendente - o último será a RootCA ou o mais próximo.\n1 2 3 cat $inter/certs/inter-ca.cert.pem /root/ca/certs/ca.cert.pem \u0026gt; \\ $inter/certs/inter-ca_chain.cert.pem chmod 444 $inter/certs/inter-ca_chain.cert.pem Activar a IntermediateCA no sistema online Uma vez que deixamos no sistema online tudo aquilo que a IntermediateCA necessita para funcionar, só temos de trazer (de forma segura) os certificados assinados pela RootCA para o local adequado; não encontrei nenhuma fonte que indicasse que se deveria deixar os certificados da própria IntermediateCA em /root/ca/certs, por isso vamos deixá-los em /root/ca/inter-ca/certs\n1 cp inter-ca.cert.pem inter-ca_chain.cert.pem $inter/certs Revogação de certificados da IntermediateCA Como o número de certificados a emitir (ou a revogar) pela IntermediateCA será muito maior, é vantajoso que se utilize o método de verificação de revogação por OCSP Responder, também chamado AIA devido à directiva que o configura (AuthorityInfoAccess).\nConfiguração do CNF com o endereço do OCSP Responder Começamos por colocar no /root/ca/inter-ca/openssl.cnf a seguinte directiva nas secções [server_cert] e [usr_cert]\nauthorityInfoAccess = OCSP;URI:http://ocsp.tjs.lan:7888\rCriar o certificado Geramos uma chave:\n1 openssl genrsa -out /root/ca/inter-ca/private/ocsp.tjs.lan.key.pem 4096 Generating RSA private key, 4096 bit long modulus (2 primes)\r...............................++++\r................................................++++\re is 65537 (0x010001)\r\nPrecisamos de inserir no CSR Informação SAN (Subject Alternative Name) específica para o OCSP:\n1 cat \u0026gt; /root/ca/inter-ca/san/ocsp.tjs.lan-san.cnf [req]\rdistinguished_name = req_distinguished_name\rreq_extensions = req_ext\rprompt = no\r[req_distinguished_name]\rC = PT\rST = Lisboa\rL = Lisboa\rO = Tiago Joao Silva\rOU = TJS\rCN = ocsp.tjs.lan\r[req_ext]\rsubjectAltName = @alt_names\r[alt_names]\rIP.1 = 192.168.1.70\rDNS.1 = ocsp.tjs.lan Criamos o CSR:\n1 2 3 openssl req -config /root/ca/inter-ca/san/ocsp.tjs.lan-san.cnf -new -sha512 \\ -key /root/ca/inter-ca/private/ocsp.tjs.lan.key.pem \\ -out /root/ca/inter-ca/csr/ocsp.tjs.lan.csr.pem Confirmar que o CSR tem a informação SAN:\n1 2 openssl req -noout -text -in /root/ca/inter-ca/csr/ocsp.tjs.lan.csr.pem | \\ grep -A 1 \u0026#34;Subject Alternative Name\u0026#34; X509v3 Subject Alternative Name: IP Address:192.168.20.170, DNS:ocsp.tjs.lan\r\nAssinar o CSR com -extensions ocsp:\n1 2 3 4 5 openssl ca -config /root/ca/inter-ca/openssl.cnf \\ -extensions ocsp -days 823 -notext -md sha512 \\ -passin file:/root/ca/inter-ca/private/inter-ca.key.pass \\ -in /root/ca/inter-ca/csr/ocsp.tjs.lan.csr.pem \\ -out /root/ca/inter-ca/certs/ocsp.tjs.lan.cert.pem Using configuration from /root/ca/inter-ca/openssl.cnf\rCheck that the request matches the signature\rSignature ok\rCertificate Details:\rSerial Number: 4099 (0x1003)\rValidity\rNot Before: Aug 22 22:53:56 2021 GMT\rNot After : Nov 23 22:53:56 2023 GMT\rSubject:\rcountryName = PT\rstateOrProvinceName = Lisboa\rlocalityName = Lisboa\rorganizationName = Tiago Joao Silva\rorganizationalUnitName = TJS\rcommonName = ocsp.tjs.lan\rX509v3 extensions:\rX509v3 Basic Constraints:\rCA:FALSE\rX509v3 Subject Key Identifier:\rBD:A6:EE:6D:0F:73:0E:47:DC:26:9A:A8:B0:40:18:55:DB:35:6B:5A\rX509v3 Authority Key Identifier:\rkeyid:E3:75:25:D7:74:08:0B:23:F0:AF:E4:EC:D0:D4:52:CB:5A:3A:10:2E\rX509v3 Key Usage: critical\rDigital Signature\rX509v3 Extended Key Usage: critical\rOCSP Signing\rCertificate is to be certified until Nov 23 22:53:56 2023 GMT (823 days)\rSign the certificate? [y/n]:Y\r1 out of 1 certificate requests certified, commit? [y/n]Y\rWrite out database with 1 new entries\rData Base Updated\r\nConfirmar que o certificado tem a extensão OCSP:\n1 2 openssl x509 -noout -text -in /root/ca/inter-ca/certs/ocsp.tjs.lan.cert.pem | \\ grep -A1 X509v3 X509v3 extensions:\rX509v3 Basic Constraints:\rCA:FALSE\rX509v3 Subject Key Identifier:\rBD:A6:EE:6D:0F:73:0E:47:DC:26:9A:A8:B0:40:18:55:DB:35:6B:5A\rX509v3 Authority Key Identifier:\rkeyid:E3:75:25:D7:74:08:0B:23:F0:AF:E4:EC:D0:D4:52:CB:5A:3A:10:2E\r--\rX509v3 Key Usage: critical\rDigital Signature\rX509v3 Extended Key Usage: critical\rOCSP Signing\r 1 chmod 400 $inter/certs/ocsp.tjs.lan.cert.pem Criar um OCSP Responder no OpenSSL (não usar em produção) Para testar, vamos activar o Responder temporariamente:\n vamos usar a porta 7888, uma das que já vimos que está livre (ver a Parte 1 para detalhes) usando a opção -nrequest 1, vai fechar depois de receber um único pedido e vamos gravar um log. 1 2 3 4 5 6 openssl ocsp -index /root/ca/inter-ca/index.txt -port 7888 -text \\ -CA /root/ca/inter-ca/certs/inter-ca_chain.cert.pem \\ -rkey /root/ca/inter-ca/private/ocsp.tjs.lan.key.pem \\ -rsigner /root/ca/inter-ca/certs/ocsp.tjs.lan.cert.pem \\ -out /root/ca/inter-ca/ocsp-log.txt \\ -nrequest 1 \u0026amp; ocsp: waiting for OCSP client connections...\r\nAbrir a porta na firewall se esta estiver activa\n1 ufw allow 7888 Fazer uma pergunta ao Responder (usando o certificado emitido para o OCSP, ou outro):\n1 2 3 4 openssl ocsp -CAfile /root/ca/inter-ca/certs/ca-chain.cert.pem \\ -url http://127.0.0.1:7888 -resp_text \\ -issuer /root/ca/inter-ca/certs/inter-ca.cert.pem \\ -cert /root/ca/inter-ca/certs/ocsp.tjs.lan.cert.pem […]\rResponse verify OK\r/root/ca/inter-ca/certs/ocsp.tjs.lan.cert.pem: good\rThis Update: Aug 22 23:06:21 2021 GMT\r[1]+ Done openssl ocsp -index /root/ca/inter-ca/index.txt -port 7888 -text -CA /root/ca/inter-ca/certs/inter-ca_chain.cert.pem -rkey /root/ca/inter-ca/private/ocsp.tjs.lan.key.pem -rsigner /root/ca/inter-ca/certs/ocsp.tjs.lan.cert.pem -out /root/ca/inter-ca/ocsp-log.txt -crl_check_all -nrequest 1\r\nVerificamos o que aconteceu na comunicação com o OCSP:\n1 head -30 /root/ca/inter-ca/ocsp-log.txt OCSP Request Data:\rVersion: 1 (0x0)\rRequestor List:\rCertificate ID:\rHash Algorithm: sha1\rIssuer Name Hash: AE59C598DC56A005EA5239AE471093B7924F5018\rIssuer Key Hash: E37525D774080B23F0AFE4ECD0D452CB5A3A102E\rSerial Number: 1003\rRequest Extensions:\rOCSP Nonce:\r04104CA2F5C63FA8F6A8D89256935DB37177\rOCSP Response Data:\rOCSP Response Status: successful (0x0)\rResponse Type: Basic OCSP Response\rVersion: 1 (0x0)\rResponder Id: C = PT, ST = Lisboa, L = Lisboa, O = Tiago Joao Silva, OU = TJS, CN = ocsp.tjs.lan\rProduced At: Aug 22 23:06:21 2021 GMT\rResponses:\rCertificate ID:\rHash Algorithm: sha1\rIssuer Name Hash: AE59C598DC56A005EA5239AE471093B7924F5018\rIssuer Key Hash: E37525D774080B23F0AFE4ECD0D452CB5A3A102E\rSerial Number: 1003\rCert Status: good\rThis Update: Aug 22 23:06:21 2021 GMT\rResponse Extensions:\rOCSP Nonce:\r04104CA2F5C63FA8F6A8D89256935DB37177\rSignature Algorithm: sha256WithRSAEncryption\r Configurar o OCSP Responder como um serviço permanente Se o sistema usar o init systemd, criamos um Service Unit (outros inits usarão os seus mecanismos)\n1 cat \u0026gt; /etc/systemd/system/ocsp-responder_inter-ca.service [Unit]\rDescription = OCSP responder using OpenSSL (for CA inter-ca)\rAfter = network.target\r[Service]\rExecStart = /usr/bin/openssl ocsp \\\r-index /root/ca/inter-ca/index.txt \\\r-port 7888 \\\r-rkey /root/ca/inter-ca/private/ocsp.tjs.lan.key.pem \\\r-rsigner /root/ca/inter-ca/certs/ocsp.tjs.lan.cert.pem \\\r-CA /root/ca/inter-ca/certs/inter-ca_chain.cert.pem \\\r-text -crl_check_all\\\r-out /root/ca/inter-ca/ocsp-log.txt\r[Install]\rWantedBy = multi-user.target\r1 systemctl daemon-reload Testar o serviço:\n1 2 systemctl start ocsp-responder_inter-ca systemctl status ocsp-responder_inter-ca ● ocsp-responder_inter-ca.service - OCSP responder using OpenSSL (for CA inter-ca)\rLoaded: loaded (/etc/systemd/system/ocsp-responder_inter-ca.service; disabled; vendor preset: enabled)\rActive: active (running) since Mon 2021-08-23 00:21:27 WEST; 22s ago\r[…]\rAug 23 00:21:27 debian systemd[1]: Started OCSP responder using OpenSSL (for CA inter-ca).\rAug 23 00:21:27 debian openssl[2585]: ocsp: waiting for OCSP client connections...\r Fazer um pedido ao serviço:\n1 2 3 4 # openssl ocsp -CAfile /root/ca/inter-ca/certs/ca-chain.cert.pem \\ -url http://127.0.0.1:7888 -resp_text \\ -issuer /root/ca/inter-ca/certs/inter-ca.cert.pem \\ -cert /root/ca/inter-ca/certs/ocsp.tjs.lan.cert.pem Confirmar que a resposta é idêntica à que deu no teste feito anteriormente. Depois deixar o serviço como permanente:\n1 systemctl enable ocsp-responder_inter-ca Outras CAs Caso esta não seja a única IntermediateCA, outras se poderiam configurar seguindo exactamente o mesmo método, bastando mudar a porta de escuta (até à 7899/TCP há mais 10 portas disponíveis).\nNo entanto, não é recomendado usar o OpenSSL como um OCSP Responder, porque a implementação é mínima e pouco robusta.\n","description":"PKI em OpenSSL: parte 2 (IntermediateCA)","id":4,"section":"sec","tags":null,"title":"PKI OpenSSL (pt 2)","uri":"https://tiagojsilva.github.io/pt/sec/pki/opensslpki_2/"},{"content":"A 16 de Fevereiro de 2022, a Microsoft anunciou a primeira grande evolução de funcionalidades para o Windows 11, com o Dev Build 22557; a lista de mudanças era longa, e apelativa, mas o que fez toda a gente ter um calafrio na espinha foi isto:\n Similar to Windows 11 Home edition, Windows 11 Pro edition now requires internet connectivity during the initial device setup (OOBE) only. If you choose to setup device for personal use, MSA will be required for setup as well. You can expect Microsoft Account to be required in subsequent WIP flights.\n Tal como o Windows 11 Home Edition, a edição Windows 11 Pro agora requer uma ligação à Internet, mas apenas durante a configuração inicial do sistema (OOBE). Se escolher uma configuração para uso pessoal, será necessário também MSA. Pode partir do princípio de que uma conta Microsoft será obrigatória em futuros lançamentos WIP.\nPara dizer a verdade, uma conta Microsoft sempre foi obrigatória para ser um Insider; mas o que isto revela é que a Microsoft está a ponderar eliminar uma das principais razões pelas quais muitos utilizadores preferem utilizar uma edição Pro do Windows, apesar de ser mais cara.\nA partir desse momento, quem desejar as outras vantagens da edição Pro (BitLocker, acesso por Remote Desktop Connection a partir de outros computadores, Hyper-V e WSL2, suporte para mais do que um CPU) também precisa de ter uma conta Microsoft, ou uma conta de domínio.\nO truque que se costumava usar desde o WIndows 10 era desligar todas as ligações de rede e dizer que se queria usar uma conta de domínio sem nenhum Domain Controller presente na rede, o que resultava num timeout e na possibilidade de criar uma conta local.\nTalvez seja isto que a Microsoft vai bloquear, não apresentando a alternativa para criar uma conta local. De realçar que à data em que escrevo isto, a Dev Build 22557 não está disponível como ISO, por isso não pude testar o que fazer nas condições reais. Talvez volte a este assunto quando estiver disponível uma compilação para instalação directa que reflicta esta mudança de política e que me permita testar quaisquer mudanças no comportamento do Windows Setup.\r\nQue fazer? A alternativa será usar o ambiente de instalação e deployment do Windows para passar por cima de todo o processo OOBE (Out-Of-Box-Experience), onde está incluído o processo NetFlow que força o uso de uma conta Microsoft. Por enquanto o Windows Setup ainda não foi muito modificado no WIndows 11, apesar de a Microsoft estar a empurrar as PMEs que insistem em ter computadores locais para usarem Azure Active Directory + Intune/Endpoint Configuration Manager + Autopilot para em vez do clássico Windows Server + Windows Deployment Services (que de resto já não é suportado pelo Windows 11)\nColocar o boot.wim dum ISO do Windows 11 (ou do Server 2022) no WDS já não funciona por PXE; é necessário um boot.wim manipulado pelo ECM, pelo Deployment Toolkit (MDT) ou por outras ferramentas.\nTambém se pode modificar o boot.wim para se ligar a uma pasta de rede e lançar o Windows Setup\nOu fazer como um OEM e usar um script para fazer tudo à mão\n(fonte)\nClaro que tanto o ECM como o MDT dependem de Volume Licen$ing…\r\nUnattended Setup A automatização do Windows Setup depende de um Answer File em formato XML (genericamente chamado unattend.xml).\nEste ficheiro pode estar em vários locais, mas os mais vulgares são:\n %WINDIR%\\Panther\\unattend.xml Raiz da drive de onde foi lançado o Windows Setup Raiz de uma drive removível presente durante o Windows Setup Raiz da pasta de rede de onde foi lançado o Windows Setup Autounattend.xml e unattend.xml não são idênticos:\n Autounattend.xml contém as informações específicas para os passos iniciais do Windows Setup: linguagem do Windows Setup e do Windows a instalar, teclado, formatos, particionamento de discos e partição onde deve ser instalado o Windows, Upgrade ou Clean Install, chave de activação, e, presumo, slipstreaming de drivers e especialização durante o primeiro reinício. unattend.xml contém o resto e corre durante o segundo reinício (passos userAudit e oobeSystem) O ficheiro controla os vários passos do processo de instalação e pode ser criado de maneira point-and-click com a ferramenta Windows System Image Manager (SIM), que é parte do Assessment and Deployment Kit (ADK), ou no site Windows Answer File Generator\nUm bom tutorial de como construir um ficheiro para automatização de instalação com o SIM está aqui\r\nMas vamos tentar simplificar a coisa. Para passar por cima do OOBE e da obrigatoriedade de ter uma conta Microsoft, basta automatizar as seguintes operações:\n Responder automagicamente (ou não) às perguntas do OOBE, saltando o passo de criação de contas Criar uma (ou várias) contas locais na base de dados SAM E vou acrescentar duas conveniências, que são:\n Configurações de localização Configuração de Zona de Tempo Cabeçalho O ficheiro começa com o cabeçalho XML e a declaração do passo oobeSystem:\n1 2 3 4 5 6 \u0026lt;?xml version=\u0026#34;1.0\u0026#34; encoding=\u0026#34;utf-8\u0026#34;?\u0026gt; \u0026lt;unattend xmlns=\u0026#34;urn:schemas-microsoft-com:unattend\u0026#34;\u0026gt; \u0026lt;settings pass=\u0026#34;oobeSystem\u0026#34;\u0026gt; \u0026lt;/settings\u0026gt; \u0026lt;/unattend\u0026gt; Dentro das tags \u0026lt;settings\u0026gt;, colocamos as configurações.\nConfiguração de localização Normalmente descarrego ISOs English-International, mas quero o teclado e os formatos em pt-PT; para ver a lista de valores que deve consultar para outras opções de linguagem, teclado e formato, consultar esta página\nOs valores a configurar são:\n InputLocale: esquema de teclado SystemLocale: país ou região UILanguage: linguagem do Windows UserLocale: local do sistema UILanguageFallback: linguagem de recurso (normalmente en-US mas no caso das edições English-International é en-GB) 1 2 3 4 5 6 7 \u0026lt;component name=\u0026#34;Microsoft-Windows-International-Core\u0026#34; processorArchitecture=\u0026#34;amd64\u0026#34; publicKeyToken=\u0026#34;31bf3856ad364e35\u0026#34; language=\u0026#34;neutral\u0026#34; versionScope=\u0026#34;nonSxS\u0026#34; xmlns:wcm=\u0026#34;http://schemas.microsoft.com/WMIConfig/2002/State\u0026#34; xmlns:xsi=\u0026#34;http://www.w3.org/2001/XMLSchema-instance\u0026#34;\u0026gt; \u0026lt;InputLocale\u0026gt;0816:00000816\u0026lt;/InputLocale\u0026gt; \u0026lt;SystemLocale\u0026gt;en-GB\u0026lt;/SystemLocale\u0026gt; \u0026lt;UILanguage\u0026gt;en-GB\u0026lt;/UILanguage\u0026gt; \u0026lt;UILanguageFallback\u0026gt;en-GB\u0026lt;/UILanguageFallback\u0026gt; \u0026lt;UserLocale\u0026gt;en-GB\u0026lt;/UserLocale\u0026gt; \u0026lt;/component\u0026gt; Configuração de OOBE A seguir colocamos a configuração do OOBE:\n1 2 3 4 5 6 7 8 9 10 11 12 \u0026lt;component name=\u0026#34;Microsoft-Windows-Shell-Setup\u0026#34; processorArchitecture=\u0026#34;amd64\u0026#34; publicKeyToken=\u0026#34;31bf3856ad364e35\u0026#34; language=\u0026#34;neutral\u0026#34; versionScope=\u0026#34;nonSxS\u0026#34; xmlns:wcm=\u0026#34;http://schemas.microsoft.com/WMIConfig/2002/State\u0026#34; xmlns:xsi=\u0026#34;http://www.w3.org/2001/XMLSchema-instance\u0026#34;\u0026gt; \u0026lt;OOBE\u0026gt; \u0026lt;HideEULAPage\u0026gt;true\u0026lt;/HideEULAPage\u0026gt; \u0026lt;HideOEMRegistrationScreen\u0026gt;true\u0026lt;/HideOEMRegistrationScreen\u0026gt; \u0026lt;HideOnlineAccountScreens\u0026gt;true\u0026lt;/HideOnlineAccountScreens\u0026gt; \u0026lt;HideWirelessSetupInOOBE\u0026gt;true\u0026lt;/HideWirelessSetupInOOBE\u0026gt; \u0026lt;SkipUserOOBE\u0026gt;true\u0026lt;/SkipUserOOBE\u0026gt; \u0026lt;SkipMachineOOBE\u0026gt;true\u0026lt;/SkipMachineOOBE\u0026gt; \u0026lt;ProtectYourPC\u0026gt;3\u0026lt;/ProtectYourPC\u0026gt; \u0026lt;/OOBE\u0026gt; \u0026lt;/component\u0026gt; Os detalhes da configuração ProtectYourPC estão aqui; o valor 3 diz Não a tudo.\nConfiguração de utilizador(es) E finalmente chegamos ao finalmente, que é criar automaticamente uma, ou várias, contas locais que não sejam Microsoft Accounts.\nA seguir à tag \u0026lt;/OOBE\u0026gt; mas antes da tag \u0026lt;/component\u0026gt;, colocar o seguinte:\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 \u0026lt;UserAccounts\u0026gt; \u0026lt;LocalAccounts\u0026gt; \u0026lt;LocalAccount wcm:action=\u0026#34;add\u0026#34;\u0026gt; \u0026lt;Password\u0026gt; \u0026lt;Value\u0026gt;S0larFlares!\u0026lt;/Value\u0026gt; \u0026lt;PlainText\u0026gt;true\u0026lt;/PlainText\u0026gt; \u0026lt;/Password\u0026gt; \u0026lt;DisplayName\u0026gt;The Bastard\u0026lt;/DisplayName\u0026gt; \u0026lt;Group\u0026gt;Administrators\u0026lt;/Group\u0026gt; \u0026lt;Name\u0026gt;bofh\u0026lt;/Name\u0026gt; \u0026lt;/LocalAccount\u0026gt; \u0026lt;LocalAccount wcm:action=\u0026#34;add\u0026#34;\u0026gt; \u0026lt;Password\u0026gt; \u0026lt;Value\u0026gt;CattlePr0d!\u0026lt;/Value\u0026gt; \u0026lt;PlainText\u0026gt;true\u0026lt;/PlainText\u0026gt; \u0026lt;/Password\u0026gt; \u0026lt;DisplayName\u0026gt;Pimply-Faced Youth\u0026lt;/DisplayName\u0026gt; \u0026lt;Group\u0026gt;Users\u0026lt;/Group\u0026gt; \u0026lt;Name\u0026gt;pfy\u0026lt;/Name\u0026gt; \u0026lt;/LocalAccount\u0026gt; \u0026lt;/LocalAccounts\u0026gt; \u0026lt;/UserAccounts\u0026gt; Time Zone Para finalizar, costumo deixar a configuração de zona de tempo de Lisboa (outras zonas de tempo estão aqui), inserindo antes da tag \u0026lt;/component\u0026gt;\n \u0026lt;TimeZone\u0026gt;GMT Standard Time\u0026lt;/TimeZone\u0026gt;\rFicheiro final 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 \u0026lt;?xml version=\u0026#34;1.0\u0026#34; encoding=\u0026#34;utf-8\u0026#34;?\u0026gt; \u0026lt;unattend xmlns=\u0026#34;urn:schemas-microsoft-com:unattend\u0026#34;\u0026gt; \u0026lt;settings pass=\u0026#34;oobeSystem\u0026#34;\u0026gt; \u0026lt;component name=\u0026#34;Microsoft-Windows-International-Core\u0026#34; processorArchitecture=\u0026#34;amd64\u0026#34; publicKeyToken=\u0026#34;31bf3856ad364e35\u0026#34; language=\u0026#34;neutral\u0026#34; versionScope=\u0026#34;nonSxS\u0026#34; xmlns:wcm=\u0026#34;http://schemas.microsoft.com/WMIConfig/2002/State\u0026#34; xmlns:xsi=\u0026#34;http://www.w3.org/2001/XMLSchema-instance\u0026#34;\u0026gt; \u0026lt;InputLocale\u0026gt;0816:00000816\u0026lt;/InputLocale\u0026gt; \u0026lt;SystemLocale\u0026gt;en-GB\u0026lt;/SystemLocale\u0026gt; \u0026lt;UILanguage\u0026gt;en-GB\u0026lt;/UILanguage\u0026gt; \u0026lt;UILanguageFallback\u0026gt;en-GB\u0026lt;/UILanguageFallback\u0026gt; \u0026lt;UserLocale\u0026gt;en-GB\u0026lt;/UserLocale\u0026gt; \u0026lt;/component\u0026gt; \u0026lt;component name=\u0026#34;Microsoft-Windows-Shell-Setup\u0026#34; processorArchitecture=\u0026#34;amd64\u0026#34; publicKeyToken=\u0026#34;31bf3856ad364e35\u0026#34; language=\u0026#34;neutral\u0026#34; versionScope=\u0026#34;nonSxS\u0026#34; xmlns:wcm=\u0026#34;http://schemas.microsoft.com/WMIConfig/2002/State\u0026#34; xmlns:xsi=\u0026#34;http://www.w3.org/2001/XMLSchema-instance\u0026#34;\u0026gt; \u0026lt;OOBE\u0026gt; \u0026lt;HideEULAPage\u0026gt;true\u0026lt;/HideEULAPage\u0026gt; \u0026lt;HideOEMRegistrationScreen\u0026gt;true\u0026lt;/HideOEMRegistrationScreen\u0026gt; \u0026lt;HideOnlineAccountScreens\u0026gt;true\u0026lt;/HideOnlineAccountScreens\u0026gt; \u0026lt;HideWirelessSetupInOOBE\u0026gt;true\u0026lt;/HideWirelessSetupInOOBE\u0026gt; \u0026lt;SkipUserOOBE\u0026gt;true\u0026lt;/SkipUserOOBE\u0026gt; \u0026lt;SkipMachineOOBE\u0026gt;true\u0026lt;/SkipMachineOOBE\u0026gt; \u0026lt;ProtectYourPC\u0026gt;3\u0026lt;/ProtectYourPC\u0026gt; \u0026lt;/OOBE\u0026gt; \u0026lt;UserAccounts\u0026gt; \u0026lt;LocalAccounts\u0026gt; \u0026lt;LocalAccount wcm:action=\u0026#34;add\u0026#34;\u0026gt; \u0026lt;Password\u0026gt; \u0026lt;Value\u0026gt;S0larFlares!\u0026lt;/Value\u0026gt; \u0026lt;PlainText\u0026gt;true\u0026lt;/PlainText\u0026gt; \u0026lt;/Password\u0026gt; \u0026lt;DisplayName\u0026gt;The Bastard\u0026lt;/DisplayName\u0026gt; \u0026lt;Group\u0026gt;Administrators\u0026lt;/Group\u0026gt; \u0026lt;Name\u0026gt;bofh\u0026lt;/Name\u0026gt; \u0026lt;/LocalAccount\u0026gt; \u0026lt;LocalAccount wcm:action=\u0026#34;add\u0026#34;\u0026gt; \u0026lt;Password\u0026gt; \u0026lt;Value\u0026gt;CattlePr0d!\u0026lt;/Value\u0026gt; \u0026lt;PlainText\u0026gt;true\u0026lt;/PlainText\u0026gt; \u0026lt;/Password\u0026gt; \u0026lt;DisplayName\u0026gt;Pimply-Faced Youth\u0026lt;/DisplayName\u0026gt; \u0026lt;Group\u0026gt;Users\u0026lt;/Group\u0026gt; \u0026lt;Name\u0026gt;pfy\u0026lt;/Name\u0026gt; \u0026lt;/LocalAccount\u0026gt; \u0026lt;/LocalAccounts\u0026gt; \u0026lt;/UserAccounts\u0026gt; \u0026lt;TimeZone\u0026gt;GMT Standard Time\u0026lt;/TimeZone\u0026gt; \u0026lt;/component\u0026gt; \u0026lt;/settings\u0026gt; \u0026lt;/unattend\u0026gt; Gravar o ficheiro como unattend.xml assegurando que está codificado em ASCII ou UTF-8.\nFornecer o ficheiro ao Windows Setup Há várias maneiras de entregar o ficheiro, como visto acima.\nInstalação a partir de uma drive USB Se vai usar um programa como o Rufus (ou o Media Creation Toolkit da Microsoft) para criar uma drive USB de instalação, pode deixá-lo na raiz da drive. Em princípio, será copiado automaticamente para %WINDIR%\\Panther (mas não testei este mecanismo).\nInstalação a partir de ISO Caso se use o ficheiro ISO (como no caso de uma VM) ou um disco óptico, existem duas opções:\nEditar o ISO Montar o ISO, copiar os ficheiros para uma pasta (no exemplo será c:\\isos\\), usar o DISM para abrir e montar a imagem de instalação (install.wim), copiar o unattend.xml para Windows\\Panther, e fechar a imagem WIM.\ndism /Mount-Image /ImageFile:\u0026quot;c:\\isos\\install.wim\u0026quot; /Index:1 /MountDir:c:\\mount\rcopy unattend.xml c:\\mount\\windows\\panther\\unattend.xml\rdism /Unmount-Image /MountDir:c:\\mount /Commit\rPara verificar se o Index corresponde à edição do Windows que pretende instalar; usar o comando dism /Get-ImageInfo /imagefile:C:\\isos\\install.wim\r Depois usar a ferramenta que preferir para criar um novo ISO.\nNão testei este passo, mas deve funcionar, é um procedimento descrito na documentação da Microsoft.\nInstalar de ISO e colocar o XML numa drive USB Normalmente este é o processo mais simples e o mais fácil de implementar: grava-se o XML para uma drive USB que possa ser ligada ao computador a instalar (ou à VM) mas que não possa ser utilizada para arrancar o sistema\nChegado a um momento específico do processo de instalação (depois do 2º reinicio, ou seja, quando o sistema passa de \u0026ldquo;generalizado\u0026rdquo; para \u0026ldquo;especializado\u0026rdquo;), o unattend.xml será lido, analisado e copiado para a pasta C:\\Windows\\Panther\\\nEste processo é mais problemático quando se aplica a VMs porque quase nenhuma plataforma de virtualização permite a simulação de uma drive USB.\nAcaba por ser necessário possuir uma drive USB física e passá-la à VM (pelo processo específico de cada plataforma de virtualização) para que o unattend.xml seja aplicado desta maneira\r\nResultados Se o processo não der erro por algum problema com a sintaxe ou os valores do XML, as contas são criadas:\n\r\r\r\rO resultado de type c:\\windows\\panther\\unattend.xml mostra que o nosso ficheiro foi copiado mas as palavras-passe foram censuradas como medida de segurança.\n\r\rNa versão 21H01 do Windows 10 isto também acontece.\nMesmo assim, recomendo vivamente apagar o ficheiro a partir de uma sessão de linha de comandos com permissões de administrador.\nProblemas O link para o Windows Terminal no \u0026ldquo;Power Menu\u0026rdquo; (Win-X ou clique-direito no botão Windows) não funcionava até se abrir manualmente o Windows Terminal em All Apps\n\r\r\r\r\r\rFeito isso, o atalho começa a funcionar. Se é problema causado pela criação da conta em modo unattended sem passar pelo OOBE ou é específico desta compilação, não sei.\nOutro problema é a Pesquisa não funcionar (não é possível procurar a aplicação Windows Terminal, simplesmente não há resultados).\nComentário final Cada vez mais o Windows se torna disfuncional na ausência de uma ligação de rede durante a instalação; não me parece que a Microsoft esteja a caminhar na direcção certa, mas os consumidores decidiram premiar sistemas ainda mais fechados como o iOS e o Android, e a Microsoft deve achar que se não se quiser tornar na nova IBM precisa de ir pelo mesmo caminho e empurrar os seus utilizadores actuais para os seus serviços de cloud, por isso o resultado é o Windows 11.\nÀ medida que a Microsoft se fecha, mais e mais pessoas se sentem desconsideradas, mas se mal esperam por se verem livres da Microsoft, têm a absoluta anarquia que é o ecossistema Linux, a espionagem da Google e a prisão dourada da Apple como alternativas.\nEscolham bem. A Microsoft quer principalmente dinheiro pelos seus serviços, em vez de privacidade, liberdade ou previsibilidade.\n","description":"Sem mãos! Sem pés!","id":5,"section":"microsoft","tags":null,"title":"Windows Pro Wrestling","uri":"https://tiagojsilva.github.io/pt/microsoft/win11/2022-02-20_pro-wrestling/"},{"content":"Procura-se, Vivo ou Morto: editor CLI Este artigo baseia-se fortemente na página Wanted: Console Text Editor for Windows, que é muito completa e que recomendo fortemente que leiam (de caminho, ponham uma estrela no perfil GitHub do autor, Antoni Sawicki); no entanto, descobri tantas coisas que decidi que talvez possa dar a minha achega.\nO artigo original começa com as minhas razões para investigar este assunto:\n Since 2012 or so Microsoft is pushing concept of running Windows Server headless without GUI and administering everything through PowerShell. I remember sitting through countless TechEd / Ignite sessions year after year and all I could see were blue PowerShell command prompts everywhere. No more wizards and forms, MMC and GUI based administration is suddenly thing of a past. Just take a look at Server Core, WinPE, Nano, PS Remoting, Windows SSH server, Recovery Console and Emergency Management Services. Even System Center is a front end for PowerShell. Nowadays everything seems to be text mode.\nThis overall is good news and great improvement since previous generations of Windows, but what if you need to create or edit a PowerShell, CMD script or some config file?\n Desde 2012, mais coisa menos coisa, que a Microsoft está a promover a ideia de correr o Windows Server headless (sem GUI) e administrar tudo por PowerShell. Lembro-me de assistir a incontáveis sessões TechEd/Ignite ano após ano e eram sessões azuis PowerShell até perder de vista. Nada de wizards nem de formulários; MMC e administração por GUI passaram de repente a ser coisas do passado. Basta pensar em Server Core, WinPE, Nano, PS Remoting, Windows SSH, Recovery Console e Emergency Management Service. Até o System Center é uma fachada bonita em cima de PowerShell. Hoje em dia tudo parece ser em modo texto.\nEm geral, são boas notícias e uma grande evolução sobre versões anteriores do Windows, mas e se precisarmos de criar ou editar scripts PowerShell ou CMD, ou mesmo um ficheiro de configuração?\nExactamente!\nA primeira vez que me dei conta desta necessidade foi quando precisei de editar um ficheiro de configuração de um pacote portado do *NIX - o Notepad nem sequer suportava quebras de linha UNIX, por isso tive de instalar o Notepad++, e nada contra este último, excelente programa que só é pena que não seja multiplataforma - mas fiquei a pensar:\n E se só tivesse acesso remoto por CLI?\n E sim, nos Windows (cliente) mais modernos existe o Windows Subsystem for Linux (WSL), com acesso directo aos sistemas de ficheiros nativos do Windows, mas também toda a panóplia de shells e utilitários para *NIX. Mas não há WSL no Windows Server…\nParâmetros de avaliação Tenho alguns critérios que me ajudaram a eliminar uma quantidade substancial de candidatos:\n Uso livre e/ou gratuito, mesmo em utilização profissional Compatível com x64 Suportar terminações de linha *NIX e DOS Suportar UTF-8 Poder correr de um executável com um mínimo de instalação (sobretudo, nada de espalhar 400 ficheiros pelo disco de sistema) Sistema testado Os editores foram testados sumariamente em Windows 10, mas as instalações documentadas neste artigo são em Windows Server Core 2022 (se bem que para Server 2019 não deve haver grande diferença).\nEditor simples Este tipo de editores tem funcionalidades muito básicas, especialmente de busca e substituição, e raramente oferecem coisas como formatação de sintaxe; são para abrir um ficheiro de texto, mudar duas linhas e fechar. No mundo DOS/Windows, seguem o standard de interface CUA (Common User Access), desenvolvido para o OS/2 e utilizado em todas as aplicações da Microsoft, nomeadamente o EDIT.COM que foi lançado no MS-DOS 5.\nEDIT.EXE Este último é o mesmo EDIT.EXE que ainda está disponível em algumas versões do Windows. Só que como se trata de um programa de 16-bits, só corre em versões x86 de Windows. Testei com a versão 20H02, que ainda existe em x86, mas os Windows 10 OEM deixaram de ter versão x86 desde a 20H01, também conhecida como 2004.\nAntes de tentar correr o comando, é necessário ir às Properties da janela do CMD.EXE, separador Options e activar o Legacy Console; depois fechar o CMD.EXE e voltar a abrir.\n\r\rQuando se tenta correr o executável pela primeira vez, o Windows pede para instalar uma biblioteca, NTVDM, que é a NT Virtual DOS Machine.\n\r\rDepois de cumpridos estes requisitos, conseguimos abrir o velhinho MS-DOS Editor - claro que não funciona em x64, não sabe o que são terminações *NIX e nem imagina o que é UTF-8, por isso é apenas uma curiosidade…\n\r\rA última versão de Windows Server com suporte x86 é o Windows Server 2008, baseado no Vista.\nYEdit O YEdit faz parte do conjunto de utilitários de shell Yori\nÉ possível correr o YEdit sem o Yori, mas primeiro é preciso descarregar o Yori, como vou mostrar.\nO instalador do Yori é apenas um stub que descarrega a última versão directamente do repositório; ora, apesar de isso ser uma boa ideia (o instalador é sempre o mesmo e não é preciso reconstruí-lo a cada nova versão), esse modo de funcionamento, acrescentado ao facto de o instalador não estar assinado, faz com que todas as protecções anti-malware sejam activadas (avisos dentro do browser, SmartScreen, Windows Defender, etc.) se estivermos num Windows cliente; mas quando logados como Administrator num Windows Server, nada disto acontece.\nÉ compatível com x64 e UTF-8, que é o mais importante, mas é possível definir uma code page específica (lembram-se?) para abrir aqueles ficheiros que ficaram no século passado.\nPara mais informação sobre o Yedit, o mesmo autor do artigo original em que me estou a basear fez um artigo especificamente sobre o Yedit: Yedit – The missing edit.com replacement for modern Windows\nPela minha parte, depois de ultrapassada a questão da instalação, corre em Windows x64 e suporta UTF-8, por isso está aprovado…\n\r\rInstalação Para ficarem acessíveis, estes editores podem ser copiados para uma pasta do perfil local do utilizador como %LOCALAPPDATA%\\Microsoft\\WindowsApps\\; esta pasta é usada pela Microsoft para deixar atalhos para a localização real de vários executáveis como o winget, Windows Terminal (wt.exe), Edge, etc.\nNão existe Microsoft Store nos Windows Server mas a pasta existe na mesma e faz parte da variável PATH.\nDescarregamos o instalador:\n1 2 Invoke-WebRequest http://www.malsmith.net/download/?obj=yori/latest-stable/win32/ysetup.exe ` -O $ENV:UserProfile\\ysetup.exe E instalamos directamente:\n1 2 $yoripath = $ENV:LocalAppData + \u0026#39;\\Microsoft\\WindowsApps\\Yori\\\u0026#39; $ENV:UserProfile\\ysetup -typical -terminal -userpath $yoripath Obtaining package URLs...\rInstalling 1 of 4: http://www.malsmith.net/download/?obj=yori/latest-stable/yori-ypm-amd64.cab\rInstalling 2 of 4: http://www.malsmith.net/download/?obj=yori/latest-stable/yori-core-amd64.cab\rInstalling 3 of 4: http://www.malsmith.net/download/?obj=yori/latest-stable/yori-typical-amd64.cab\rInstalling 4 of 4: http://www.malsmith.net/download/?obj=yori/latest-stable/yori-completion-noarch.cab\rApplying installation options...\rInstallation complete.\rSuccess: Installation complete.\r Apesar de $ENV:LocalAppData\\Microsoft\\WindowsApps\\ fazer parte do PATH privado de cada utilizador desde o Windows 8, as suas subpastas não fazem (e teria sido feio largar o Yori na raiz da pasta); por isso, temos de acrescentar ao PATH o caminho onde instalamos o Yori:\n1 2 $yoripath += \u0026#39;;\u0026#39; $ENV:Path += $yoripath E finalmente yedit\n\r\rPor sua vez, o yedit.exe pode ser usado sozinho, sem o Yori, depois do mesmo ser instalado; nesse caso, convém não acrescentar a pasta do Yori ao PATH)\n1 2 3 4 $ENV:Path = $ENV:Path.Replace($yoripath,\u0026#34;\u0026#34;) $yoripath = $yoripath.TrimEnd(\u0026#39;;\u0026#39;) cp $yoripath\\yedit.exe $ENV:LocalAppData\\Microsoft\\WindowsApps\\ del $yoripath -Recurse -Force Para facilitar a vida ao leitor, vou disponibilizar aqui no site o executável do YEdit 1.70; usando este executável, basta largá-lo em $ENV:LocalAppData\\Microsoft\\WindowsApps\\ ou outra pasta que faça parte do PATH.\nyedit.exe v1.70 - (c) Malcolm Smith\n86F5437B1BE03C51625A251B7D9193AD\r\nMas uma vez mais, recomendo que experimentem e utilizem todo o pacote do Yori, porque vale a pena.\nSobre o Yori Um comentário quanto ao Yori: não sei onde é que o Yori esteve a minha vida toda, mas é fantástico. É o que o CMD.EXE devia ser há 20 anos, e é uma excelente opção se desejam uma shell mais poderosa sem ter de migrar para PowerShell ou instalar 1GB de WSL só para ter acesso às shells do mundo *NIX. Deixo uma pequena amostra dos comandos suportados:\n\r\rAplicam-se os avisos do costume quanto a correr código externo num servidor e habituarmo-nos a ferramentas de administração que não fazem parte do pacote-base de instalação.\r Wishlist: Tilde No mundo *NIX aconteceu o oposto, que foi alguém ter desenvolvido um editor simples com a interface CUA típica do Windows, que é mais natural para quem transita de uma GUI para a CLI. Esse editor chama-se Tilde e de momento não tem versão para Windows.\nSeria bom ter duas opções\u0026hellip;\nEditor avançado Estes editores são mais poderosos e têm uma curva de aprendizagem mais inclinada que os editores mais simples como o Notepad:\n\r\rMas costumam ter funções avançadas como macros, múltiplas janelas, coloração de sintaxe, plugins, etc.\nComeçando pelos editores clássicos do *NIX: Pico (Nano), VI (VIm), JOE e EMACS :\nPico/Nano: 404 A fonte mais próxima do Pico (o editor do programa de email Pine, daí o nome - PIne COmposer) deveria ser o site oficial, mas há muito tempo que é abandonware, desde que a universidade que o criou se esqueceu dele.\nNão só não é actualizado para MS-DOS desde 1997, como necessitava da instalação do middleware DJGPP. Outros tempos…\nJá o clone da FSF, GNU Nano, não oferece um ficheiro binário para Windows, e a compilação independente mais popular exige a instalação da biblioteca Cygwin para simular um ambiente POSIX no Windows; um pouco pesado de mais para o que estou à procura.\nMicro No entanto, um outro clone do Pico, chamado Micro, pode ser uma boa aposta:\n\r\rÉ o mais recente de todos, ainda está em desenvolvimento, é escrito em Go e tem versões para OSX, Free/Open/Net BSD, Linux (x86, x64 e ARM), e Windows (x86 e x64).\nFunciona bem, tem uma command bar (Ctrl-E) e os atalhos baseiam-se na tecla Ctrl seguindo a linha familiar do Pico, Nano, etc.\nTal como queremos para este desafio, o \u0026ldquo;instalador\u0026rdquo; é apenas um ZIP com um executável estaticamente linkado.\nInstalação 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 \u0026#39;Descobrimos o link para a última versão\u0026#39; $latest = \u0026#39;https://github.com\u0026#39; + ` ((Invoke-WebRequest http://github.com/zyedidia/micro/releases/latest/ -UseBasicParsing).Links | foreach {$_.href} | Select-String -Pattern \u0026#39;win64\u0026#39;) \u0026#39;Descarregamos o ZIP\u0026#39; Invoke-WebRequest $latest -UseBasicParsing -Out $ENV:UserProfile\\micro-latest.zip \u0026#39;apontamos para a pasta dos executáveis do utilizador\u0026#39; $micropath = $ENV:LocalAppData + \u0026#39;\\Microsoft\\WindowsApps\u0026#39; \u0026#39;extraimos o arquivo\u0026#39; Expand-Archive -Path $ENV:UserProfile\\micro-latest.zip -Destination $micropath \u0026#39;se nunca tivermos instalado o Micro antes, usar este comando para extrair o caminho para o executável\u0026#39; $micropath += ( (dir $micropath | where name -like micro-*).Name + \u0026#39;\\;\u0026#39;) \u0026#39;Acrescentamos esse caminho ao PATH\u0026#39; $ENV:Path += $micropath \u0026#39;Correr o editor\u0026#39; micro \r\r\rO ficheiro de configuração do Micro fica em $ENV:UserProfile\\.config\\micro\\settings.json\nVIM A versão para Microsoft do VIM (Vi, IMproved) vem em várias declinações (incluindo uma versão com interface gráfica chamada gvim), mas o que nos interessa é o executável para consola, que é compilado para x86 - mas não vamos abrir ficheiros com mais de 2GB, correcto?\nCaso precise mesmo de abrir ficheiros com mais de 2GB, o Neovim existe em versão x64 e instala-se mais ou menos da mesma maneira que se segue.\nInstalação O processo de descarregar e \u0026ldquo;instalar\u0026rdquo; é muito similar ao que foi usado para o Micro:\n1 2 3 4 5 6 Invoke-WebRequest https://ftp.nluug.nl/pub/vim/pc/vim82w32.zip -UseBasicParsing ` -Out $ENV:UserProfile\\vim82w32.zip Expand-Archive -Path $ENV:UserProfile\\vim82w32.zip ` -Destination $ENV:LocalAppData\\Microsoft\\WindowsApps $ENV:Path += ($ENV:LocalAppData + \u0026#39;\\Microsoft\\WindowsApps\\vim\\vim82\\;\u0026#39;) vim \r\r\rO perfil do Vim fica em $ENV:UserProfile\\.vimrc.\nPodem ver uma sugestão de .vimrc na página DotFiles\nJOE (Joe\u0026rsquo;s Own Editor) O JOE é bastante menos conhecido, mas tem os seus fãs.\nPara mais informações sobre o JOE para Windows, veja esta página.\nFelizmente, existe como executável independente, e até em várias versões consoante a interface preferida:\n joe para quem respeita o original https://sourceforge.net/projects/joe-editor/files/JOE%20for%20Windows/4.6/Standalone/joe.exe/download jmacs para quem gosta de EMACS https://sourceforge.net/projects/joe-editor/files/JOE%20for%20Windows/4.6/Standalone/jmacs.exe/download jstar para quem prefere Wordstar https://sourceforge.net/projects/joe-editor/files/JOE%20for%20Windows/4.6/Standalone/jstar.exe/download jpico para quem tem saudades do Pico/Nano e não gosta de mexer numa configuração em JSON como a que é usada pelo Micro https://sourceforge.net/projects/joe-editor/files/JOE%20for%20Windows/4.6/Standalone/jpico.exe/download Infelizmente, por estarem alojados no SourceForge, não encontrei nenhum link directo que permitisse descarregar os ficheiros numa instalação-base Windows Server Core; mas num WinServer com Desktop Experience, pode usar um browser para instalar e usar o JOE.\nNum Windows Server Core, é necessário instalar o programa WGET\nWGET para Windows O comando Invoke-WebRequest num Windows Server Core não pode recorrer ao motor de páginas HTML do sistema (Trident ou Blink) para pedidos HTTP complexos, como estes endereços do SourceForge que incluem redirects. Mas um utilitário de linha de comando que o pode fazer é o GNU WGET, que uma alma caridosa compila e distribui para Windows\nInstalamos o WGET com o mesmo método básico:\n1 2 Invoke-WebRequest https://eternallybored.org/misc/wget/1.21.2/64/wget.exe -UseBasicParsing ` -Out $ENV:LocalAppData\\Microsoft\\WindowsApps\\wget.exe wget, por defeito, é um Alias para Invoke-WebRequest, por isso é necessário chamar o executável WGET com wget.exe ou desactivar o Alias; em PowerShell 6+ é simples porque existe o comando Remove-Alias, mas em Windows PowerShell (a versão que vem por defeito nos sistemas Windows, que corresponde ao PowerShell 5.1), é um pouco mais complexo porque o comando não existe e os Alias têm vários Scopes em PowerShell. No entanto, while (Test-Path Alias:wget) {Remove-Item Alias:wget} resolve o problema.\r wget.exe -h, ou wget -h se tiver seguido a recomendação acima:\n\r\rExpandir\r\rGNU Wget 1.21.2, a non-interactive network retriever.\rUsage: wget [OPTION]... [URL]...\rMandatory arguments to long options are mandatory for short options too.\rStartup:\r-V, --version display the version of Wget and exit\r-h, --help print this help\r-b, --background go to background after startup\r-e, --execute=COMMAND execute a '.wgetrc'-style command\rLogging and input file:\r-o, --output-file=FILE log messages to FILE\r-a, --append-output=FILE append messages to FILE\r-d, --debug print lots of debugging information\r-q, --quiet quiet (no output)\r-v, --verbose be verbose (this is the default)\r-nv, --no-verbose turn off verboseness, without being quiet\r--report-speed=TYPE output bandwidth as TYPE. TYPE can be bits\r-i, --input-file=FILE download URLs found in local or external FILE\r--input-metalink=FILE download files covered in local Metalink FILE\r-F, --force-html treat input file as HTML\r-B, --base=URL resolves HTML input-file links (-i -F)\rrelative to URL\r--config=FILE specify config file to use\r--no-config do not read any config file\r--rejected-log=FILE log reasons for URL rejection to FILE\rDownload:\r-t, --tries=NUMBER set number of retries to NUMBER (0 unlimits)\r--retry-connrefused retry even if connection is refused\r--retry-on-http-error=ERRORS comma-separated list of HTTP errors to retry\r-O, --output-document=FILE write documents to FILE\r-nc, --no-clobber skip downloads that would download to\rexisting files (overwriting them)\r--no-netrc don't try to obtain credentials from .netrc\r-c, --continue resume getting a partially-downloaded file\r--start-pos=OFFSET start downloading from zero-based position OFFSET\r--progress=TYPE select progress gauge type\r--show-progress display the progress bar in any verbosity mode\r-N, --timestamping don't re-retrieve files unless newer than\rlocal\r--no-if-modified-since don't use conditional if-modified-since get\rrequests in timestamping mode\r--no-use-server-timestamps don't set the local file's timestamp by\rthe one on the server\r-S, --server-response print server response\r--spider don't download anything\r-T, --timeout=SECONDS set all timeout values to SECONDS\r--dns-servers=ADDRESSES list of DNS servers to query (comma separated)\r--bind-dns-address=ADDRESS bind DNS resolver to ADDRESS (hostname or IP) on local host\r--dns-timeout=SECS set the DNS lookup timeout to SECS\r--connect-timeout=SECS set the connect timeout to SECS\r--read-timeout=SECS set the read timeout to SECS\r-w, --wait=SECONDS wait SECONDS between retrievals\r(applies if more then 1 URL is to be retrieved)\r--waitretry=SECONDS wait 1..SECONDS between retries of a retrieval\r(applies if more then 1 URL is to be retrieved)\r--random-wait wait from 0.5*WAIT...1.5*WAIT secs between retrievals\r(applies if more then 1 URL is to be retrieved)\r--no-proxy explicitly turn off proxy\r-Q, --quota=NUMBER set retrieval quota to NUMBER\r--bind-address=ADDRESS bind to ADDRESS (hostname or IP) on local host\r--limit-rate=RATE limit download rate to RATE\r--no-dns-cache disable caching DNS lookups\r--restrict-file-names=OS restrict chars in file names to ones OS allows\r--ignore-case ignore case when matching files/directories\r-4, --inet4-only connect only to IPv4 addresses\r-6, --inet6-only connect only to IPv6 addresses\r--prefer-family=FAMILY connect first to addresses of specified family,\rone of IPv6, IPv4, or none\r--user=USER set both ftp and http user to USER\r--password=PASS set both ftp and http password to PASS\r--ask-password prompt for passwords\r--use-askpass=COMMAND specify credential handler for requesting\rusername and password. If no COMMAND is\rspecified the WGET_ASKPASS or the SSH_ASKPASS\renvironment variable is used.\r--no-iri turn off IRI support\r--local-encoding=ENC use ENC as the local encoding for IRIs\r--remote-encoding=ENC use ENC as the default remote encoding\r--unlink remove file before clobber\r--keep-badhash keep files with checksum mismatch (append .badhash)\r--metalink-index=NUMBER Metalink application/metalink4+xml metaurl ordinal NUMBER\r--metalink-over-http use Metalink metadata from HTTP response headers\r--preferred-location preferred location for Metalink resources\rDirectories:\r-nd, --no-directories don't create directories\r-x, --force-directories force creation of directories\r-nH, --no-host-directories don't create host directories\r--protocol-directories use protocol name in directories\r-P, --directory-prefix=PREFIX save files to PREFIX/..\r--cut-dirs=NUMBER ignore NUMBER remote directory components\rHTTP options:\r--http-user=USER set http user to USER\r--http-password=PASS set http password to PASS\r--no-cache disallow server-cached data\r--default-page=NAME change the default page name (normally\rthis is 'index.html'.)\r-E, --adjust-extension save HTML/CSS documents with proper extensions\r--ignore-length ignore 'Content-Length' header field\r--header=STRING insert STRING among the headers\r--compression=TYPE choose compression, one of auto, gzip and none. (default: none)\r--max-redirect maximum redirections allowed per page\r--proxy-user=USER set USER as proxy username\r--proxy-password=PASS set PASS as proxy password\r--referer=URL include 'Referer: URL' header in HTTP request\r--save-headers save the HTTP headers to file\r-U, --user-agent=AGENT identify as AGENT instead of Wget/VERSION\r--no-http-keep-alive disable HTTP keep-alive (persistent connections)\r--no-cookies don't use cookies\r--load-cookies=FILE load cookies from FILE before session\r--save-cookies=FILE save cookies to FILE after session\r--keep-session-cookies load and save session (non-permanent) cookies\r--post-data=STRING use the POST method; send STRING as the data\r--post-file=FILE use the POST method; send contents of FILE\r--method=HTTPMethod use method \"HTTPMethod\" in the request\r--body-data=STRING send STRING as data. --method MUST be set\r--body-file=FILE send contents of FILE. --method MUST be set\r--content-disposition honor the Content-Disposition header when\rchoosing local file names (EXPERIMENTAL)\r--content-on-error output the received content on server errors\r--auth-no-challenge send Basic HTTP authentication information\rwithout first waiting for the server's\rchallenge\rHTTPS (SSL/TLS) options:\r--secure-protocol=PR choose secure protocol, one of auto, SSLv2,\rSSLv3, TLSv1, TLSv1_1, TLSv1_2 and PFS\r--https-only only follow secure HTTPS links\r--no-check-certificate don't validate the server's certificate\r--certificate=FILE client certificate file\r--certificate-type=TYPE client certificate type, PEM or DER\r--private-key=FILE private key file\r--private-key-type=TYPE private key type, PEM or DER\r--ca-certificate=FILE file with the bundle of CAs\r--ca-directory=DIR directory where hash list of CAs is stored\r--crl-file=FILE file with bundle of CRLs\r--pinnedpubkey=FILE/HASHES Public key (PEM/DER) file, or any number\rof base64 encoded sha256 hashes preceded by\r'sha256//' and separated by ';', to verify\rpeer against\r--random-file=FILE file with random data for seeding the SSL PRNG\r--ciphers=STR Set the priority string (GnuTLS) or cipher list string (OpenSSL) directly.\rUse with care. This option overrides --secure-protocol.\rThe format and syntax of this string depend on the specific SSL/TLS engine.\rHSTS options:\r--no-hsts disable HSTS\r--hsts-file path of HSTS database (will override default)\rFTP options:\r--ftp-user=USER set ftp user to USER\r--ftp-password=PASS set ftp password to PASS\r--no-remove-listing don't remove '.listing' files\r--no-glob turn off FTP file name globbing\r--no-passive-ftp disable the \"passive\" transfer mode\r--preserve-permissions preserve remote file permissions\r--retr-symlinks when recursing, get linked-to files (not dir)\rFTPS options:\r--ftps-implicit use implicit FTPS (default port is 990)\r--ftps-resume-ssl resume the SSL/TLS session started in the control connection when\ropening a data connection\r--ftps-clear-data-connection cipher the control channel only; all the data will be in plaintext\r--ftps-fallback-to-ftp fall back to FTP if FTPS is not supported in the target server\rWARC options:\r--warc-file=FILENAME save request/response data to a .warc.gz file\r--warc-header=STRING insert STRING into the warcinfo record\r--warc-max-size=NUMBER set maximum size of WARC files to NUMBER\r--warc-cdx write CDX index files\r--warc-dedup=FILENAME do not store records listed in this CDX file\r--no-warc-compression do not compress WARC files with GZIP\r--no-warc-digests do not calculate SHA1 digests\r--no-warc-keep-log do not store the log file in a WARC record\r--warc-tempdir=DIRECTORY location for temporary files created by the\rWARC writer\rRecursive download:\r-r, --recursive specify recursive download\r-l, --level=NUMBER maximum recursion depth (inf or 0 for infinite)\r--delete-after delete files locally after downloading them\r-k, --convert-links make links in downloaded HTML or CSS point to\rlocal files\r--convert-file-only convert the file part of the URLs only (usually known as the basename)\r--backups=N before writing file X, rotate up to N backup files\r-K, --backup-converted before converting file X, back up as X.orig\r-m, --mirror shortcut for -N -r -l inf --no-remove-listing\r-p, --page-requisites get all images, etc. needed to display HTML page\r--strict-comments turn on strict (SGML) handling of HTML comments\rRecursive accept/reject:\r-A, --accept=LIST comma-separated list of accepted extensions\r-R, --reject=LIST comma-separated list of rejected extensions\r--accept-regex=REGEX regex matching accepted URLs\r--reject-regex=REGEX regex matching rejected URLs\r--regex-type=TYPE regex type (posix|pcre)\r-D, --domains=LIST comma-separated list of accepted domains\r--exclude-domains=LIST comma-separated list of rejected domains\r--follow-ftp follow FTP links from HTML documents\r--follow-tags=LIST comma-separated list of followed HTML tags\r--ignore-tags=LIST comma-separated list of ignored HTML tags\r-H, --span-hosts go to foreign hosts when recursive\r-L, --relative follow relative links only\r-I, --include-directories=LIST list of allowed directories\r--trust-server-names use the name specified by the redirection\rURL's last component\r-X, --exclude-directories=LIST list of excluded directories\r-np, --no-parent don't ascend to the parent directory\rEmail bug reports, questions, discussions to \rand/or open issues at https://savannah.gnu.org/bugs/?func=additem\u0026group=wget.\r\r\r\nDescarregar o JOE com o wget e instalar 1 2 wget -c https://sourceforge.net/projects/joe-editor/files/JOE%20for%20Windows/4.6/Standalone/joe.exe/download -O $ENV:LocalAppData\\Microsoft\\WindowsApps\\joe.exe joe \r\r\rComo se vê, o JOE abre uma nova janela em vez de utilizar a janela actual, por isso precisa de ser testado se funcionará numa shell remota pura como SSH ou PSRemoting e não numa sessão RDC.\nTestar com OpenSSH No Windows Server (2022 ou 2019), correr os comandos:\n1 Get-WindowsCapability -Online | where name -like \u0026#39;OpenSSH*\u0026#39; Name : OpenSSH.Client\\~\\~\\~\\~0.0.1.0\rState : Installed\rName : OpenSSH.Server\\~\\~\\~\\~0.0.1.0\rState : NotPresent\r O cliente SSH está instalado, por isso instalamos o OpenSSH.Server seguindo as instruções da Microsoft:\n1 2 3 4 5 6 7 8 9 10 11 12 Add-WindowsCapability -Online -Name OpenSSH.Server\\~\\~\\~\\~0.0.1.0 Start-Service sshd Set-Service -Name sshd -StartupType \u0026#39;Automatic\u0026#39; if (!(Get-NetFirewallRule -Name \u0026#34;OpenSSH-Server-In-TCP\u0026#34; -ErrorAction SilentlyContinue | Select-Object Name, Enabled)) ` { Write-Output \u0026#34;Firewall Rule \u0026#39;OpenSSH-Server-In-TCP\u0026#39; does not exist, creating it...\u0026#34; New-NetFirewallRule -Name \u0026#39;OpenSSH-Server-In-TCP\u0026#39; -DisplayName \u0026#39;OpenSSH Server (sshd)\u0026#39; ` -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22 ` } else { Write-Output \u0026#34;Firewall rule \u0026#39;OpenSSH-Server-In-TCP\u0026#39; has been created and exists.\u0026#34; } Como já temos o cliente SSH instalado, podemos abrir uma sessão SSH directamente no localhost:\n1 ssh Administrator@localhost The authenticity of host 'localhost (::1)' can't be established.\rECDSA key fingerprint is SHA256:[…].\rAre you sure you want to continue connecting (yes/no/[fingerprint])? yes\rWarning: Permanently added 'localhost' (ECDSA) to the list of known hosts.\rAdministrator@localhost's password:\rMicrosoft Windows [Version 10.0.20348.350]\r(c) Microsoft Corporation. All rights reserved.\radministrator@WIN-L32NQRNJ5GI C:\\Users\\Administrator\r E como suspeitava, tentando abrir o joe numa sessão CLI pura, não abre.\n\r\rPor isso, uma vez que para usar o JOE é necessário estar numa sessão Remote Desktop, na minha opinião mais vale usar o Notepad++\nO YEdit, o Micro e o Vim abrem correctamente dentro da sessão SSH.\nEMACS Se quiser mesmo usar o EMACS para editar uns ficheiros de texto, posso sugerir o JOE com interface EMACS (jmacs)? Não?\nEntão a melhor página que encontrei que o pode ajudar está aqui.\nCitando o artigo original,\n Emacs.exe binary is whopping 83 MB in size and the zip file contains two of them just in case. Whole unpacked folder is 400 MB.\n Eu mencionei que estava à procura de soluções pequenas e práticas, não de um sistema operativo e linguagem de programação que por acaso inclui um editor de texto ¯\\(ツ)/¯\nMenções honrosas O artigo original mencionava muito mais editores, mas experimentei a maior parte e acabei por abandonar quase todos porque eram impraticáveis ou incompatíveis.\nDos que me pareceram possíveis e que testei, apenas vou comentar as minhas impressões depois de os instalar; como não os acho úteis para os dias de hoje (por exemplo, por não suportarem UTF-8), não vou documentar a sua instalação.\nOpen Watcom VI https://github.com/open-watcom/open-watcom-v2\nhttps://github.com/tenox7/ntutils/tree/master/owvi\n\r\rO autor do artigo original deu-se ao trabalho de compilar apenas o editor do pacote OpenWatcom, que se instala a partir de https://github.com/tenox7/ntutils/blob/master/owvi/vi-x64.exe ou https://github.com/tenox7/ntutils/blob/master/owvi/vi-x86.exe; a documentação está em https://github.com/tenox7/ntutils/blob/master/owvi/vi.pdf\nNo entanto, apesar de parecer um bom compromisso entre o VI e um editor com menus (pode-se usar tal e qual como o VI, parece compatível com .vimrc, mas tem menus), não suporta UTF-8.\nKinesics Text Editor https://turtlewar.org/projects/editor/\nhttps://turtlewar.org/projects/editor/kit-153-win.exe\n\r\rFunciona em várias plataformas, mas o instalador Windows só funciona com permissões de Administrador, o que imediatamente nos avisa que é um programa de outros tempos\u0026hellip;\nÉ extremamente configurável, tem funcionalidades avançadas como selecção em modo de coluna (vi Visual Mode) mas também não suporta UTF-8\nE não é actualizado desde 2015\nFTE Editor http://fte.sourceforge.net/\nhttps://github.com/tenox7/ntutils/tree/master/fte\nNão corre porque precisa de bibliotecas MSVC muito antigas que não estão disponíveis num sistema Windows moderno\nThomson-Davis Editor - TDE http://adoxa.altervista.org/tde/\nhttps://github.com/tenox7/ntutils/tree/master/tde\n\r\rA profundidade dos menus e atalhos é enorme, é um editor extremamente poderoso, mas também não suporta UTF-8\u0026hellip;\nConclusão Depois de décadas a promover a gestão de sistemas por interfaces GUI, os editores CLI nativos das plataformas Microsoft definharam ao ponto de não terem salvação. O único que ainda é viável é o YEdit, talvez porque o programador ainda não desistiu (e parece um programador do caraças); além disso, o YEdit é muito simples.\nMas mesmo o fantástico Yori não teria sucesso onde o Cscript e o Kermit não tiveram (este Kermit era uma adaptação da Korn shell para Windows que a Microsoft pensou em desenvolver), porque o problema advinha de a CLI não ter interfaces consistentes com as quais interagir num sistema que depende completamente de interfaces como o Windows; isso só apareceu com o PowerShell e as ideias que lhe estão por trás.\nRecomendo o livro Shell of an Idea - The untold history of PowerShell escrito por Don Jones, que explica bastante bem o que passava na Microsoft nessa altura.\r\nAs melhores opções acabam por ser os editores vindos do *NIX que se mantiveram actualizados e que têm versões para Windows.\nCaso a falta de suporte a UTF-8 não seja um problema, gostei bastante do OpenWatcom VI e do TDE.\nMas as minhas escolhas são, claramente, o YEdit para coisas muito rápidas e o Vim para tarefas mais complicadas.\nBoa sorte!\n","description":"O que é velho torna-se novo outra vez","id":6,"section":"microsoft","tags":null,"title":"Editores na CLI Microsoft","uri":"https://tiagojsilva.github.io/pt/microsoft/tools/2022-01-15_cli-editors/"},{"content":"No meu workflow de criação de artigos vejo-me confrontado com o facto de precisar de converter tags em shortcodes Hugo, e de retirar os escapes a todos os caracteres que o Pandoc acha que tem de proteger.\nFazer isso operação a operação é o tipo de trabalho que me faz correr para algum tipo de automatização - e por isso é que eu digo que sou o maior preguiçoso do mundo.\nTentei arranjar algum tipo de plugin para Notepad++ ou VSCode que me ajudassem, mas no final, todos tinham algum problema; nomeadamente, como os meus alvos e as minhas substituições têm muitos caracteres especiais, queria evitar ferramentas que usassem expressões regulares.\nSim, o *NIX foi inventado para este tipo de trabalhos, e ferramentas como o sed seriam perfeitas para o que eu quero. Menos a parte das expressões regulares\u0026hellip;\r\nAcabei por perceber que não conseguia encontrar nada que não usasse expressões regulares. trombone.wav\nSolução com Notepad++ Eventualmente, depois de partir muita pedra, percebi que podia fazer isso com a busca normal do Notepad++, porque este aceita expressões regulares PCRE. E em PCRE, é possível construir uma única expressão feita de muitas cadeias de captura e substituição, com este formato:\n Busca Substituição (ta)|(te)|(ti) (?1pa)(?2pe)(?3pi) O problema da profusão de caracteres de escape acabou por ser resolvido com string literals, que estava habituado em .NET como @\u0026quot;foo\u0026quot;, mas que em regex normal não funcionam; no entanto, o PCRE tem string literals através da construção \\Qfoo\\E\nPara os outros, capturar \\_ implica escapar o \\(\\\\) e o _(\\_): o resultado é \\\\\\_\nDepois, ainda tive de resolver o problema de ter de escapar caracters na substituição; mas felizmente em PCRE só é necessário escapar $, \\, (, ), ?, e :\nPor exemplo:\n \u0026lt; e \u0026gt; saem da conversão Pandoc como \u0026amp;lt; e \u0026amp;gt;: retirar os escapes a \\,_,`,*,[, ], (.),| Busca:\n (\u0026amp;gt;)|(\u0026amp;lt;)|(\\\\\\\\)|(\\\\\\_)|(\\\\\\`)|(\\\\\\*)|(\\\\\\[)|(\\\\\\])|(\\\\\\()|(\\\\\\))|(\\\\\\|)\rSubstituição\n(?1\u0026gt;)(?2\u0026lt;)(?3\\\\)(?4_)(?5`)(?6*)(?7[)(?8])(?9\\()(?10\\))(?11|)\rÉ preciso muita, MUITA atenção porque nem tudo se escapa nas substituições\u0026hellip;\nCom esta funcionalidade, posso usar abreviaturas para os shortcodes e acelerei imenso a preparação destes artigos.\nSe o que demora mais é aprender e documentar, essa também é a parte divertida; converter a minha documentação num artigo para publicar é que devia ser o mais automático e imediato possível, para poder continuar a aprender e documentar\u0026hellip;\n","description":"Ctrl-H, Ctrl-H, Ctrl-H, Ctrl-H...","id":7,"section":"blog","tags":null,"title":"Busca e Substituição em massa com Notepad++","uri":"https://tiagojsilva.github.io/pt/blog/2022-01-27_multiple-search-and-replace/"},{"content":"\r\r\rComo chegámos aqui A distribuição CentOS sempre foi um animal estranho: como é que podia ser que a principal distribuição Linux de utilização exclusivamente paga (Red Hat Enterprise Linux, ou RHEL) tivesse um clone de utilização totalmente gratuita?\nPor isso, e por razões que indicarei abaixo, não me surpreendeu completamente que as condições de acesso à distribuição CentOS tenham mudado, se bem que o método, o tempo e a forma como tudo foi comunicado vão ser um caso de estudo de como-não-fazer\u0026hellip;\nFiquei curioso com as duas alternativas que se perfilaram, o Rocky Linux e o AlmaLinux, e decidi testar a migração de um sistema CentOS 8 para ambos, uma vez que tudo isto resultou no End-Of-Life do CentOS8 em Dezembro de 2021 em vez de 2029 como muita gente tinha planeado.\nFragmentação? Como sempre no mundo FOSS, nunca há apenas uma única resposta a um problema - é uma força, e uma fraqueza. Neste caso creio que ambos os projectos têm o seu público-alvo, que talvez lhes permita manterem-se os dois activos e vigorosos:\n RockyLinux AlmaLinux Base Territorial EUA Europa Público-alvo High-Performance Computing, hardware com drivers distribuídos em binário (estou-te a ver, HPE), ex-utilizadores do Scientific Linux cPanel, servidores Web Veremos se ambos sobreviverão…\nMais um concorrente pediu uma cadeira e sentou-se à mesa; dias depois da publicação original, a SuSE, que já tinha uma distribuição baseada em RPM (SuSE Linux Enterprise, ou SLE) e um kernel mais-ou-menos compatível com o RedHat em termos de kernel modules, anunciou o Liberty Linux, que oferece uma alternativa com suporte de nível empresarial e capaz de ser gerida pelas mesmas ferramentas que se usam para gerir uma infraestrutura baseada em SuSE bem, mas o RHEL também ja podia fazer isso\u0026hellip;). De acordo com o The Register, é de ressalvar que o kernel do Liberty Linux é o mesmo do SuSE Linux Enterprise (5.3.x), que é muito mais recente que o existente no RHEL 8 (4.18) - por isso o Liberty Linux parece ser uma proposta para convencer certos tipos de clientes mistos a abandonarem de vez a RedHat caso os seus sistemas sejam compatíveis com o SLE.\r\nO teste Para este teste, baseei-me num conjunto de VMs que simulava uma rede de serviços tipicamente Windows (AD-DC, SMB, impressão, Group Policies) com base num servidor CentOS8 e Samba (compilado da fonte).\n\r\rO objectivo é fazer o sidegrade a este último (TJGGS) para as alternativas ao CentOS8: Rocky Linux e AlmaLinux, e testar a funcionalidade básica.\nPreparativos Os computadores estão no domínio DASILVAT e utilizadores do domínio podem-se logar nos computadores:\n\r\rLOGONSERVER=\\\\TJGGS\rUSERDNSDOMAIN=DASILVAT.LOCAL\rUSERDOMAIN=DASILVAT\r Loguei-me em TJGGS com o PuTTY, a partir do computador RSAT\nFora da caixa, o sistema está tal e qual o deixei em Junho de 2020, quando terminei o trabalho para o CINEL.\nlogin as: formando\rAuthenticating with public key \"rsa-key-20200615\"\rPassphrase for key \"rsa-key-20200615\":\rLast login: Sat Jun 27 20:31:21 2020 from 10.12.140.99\r[formando@tjggs ~]$ uname -a\rLinux tjggs 4.18.0-147.8.1.el8_1.x86_64 #1 SMP Thu Apr 9 13:49:54 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux\r\nA primeira coisa que temos de fazer é uma actualização geral. E como há mais de um ano que os repositórios não são actualizados, é melhor usar --refresh\n1 sudo dnf upgrade -y --refresh [...]\rTransaction Summary\r====================================================================================================================================\rInstall 22 Packages\rUpgrade 518 Packages\r[...]\r Depois de um reinício, passámos do CentOS 8.1 para 8.4:\n1 uname -a Linux tjggs 4.18.0-305.19.1.el8_4.x86_64 #1 SMP Wed Sep 15 15:39:39 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux\r Nos clientes Windows surgiu o aviso de que as credenciais precisavam de ser reintroduzidas; logoff, mudança de palavra-passe, e ao tentar de novo o logon, surgiu o erro de que o computador não estava registado no domínio.\n\r\rMuito bem, loguei com o administrador local e tentei primeiro Remove-Computer -Credential DASILVAT\\Administrator e depois Add-Computer; sempre não autorizado (Access is denied).\nLoguei \u0026ldquo;localmente\u0026rdquo; em TJGGS e verifiquei os logs; /var/log/messages tinha uma indicação de que a sysvol estava com permissões erradas:\nchdir_current_service: vfs_ChDir(/usr/local/samba/var/locks/sysvol) failed: Permission denied. Current token: uid=3000025, gid=3000026, 7 groups: 3000025 3000026 3000035 3000036 3000037 3000006 3000011\r\nApesar de ser um bocado perigoso, usei o esfregão de palha de aço:\n1 2 samba-tool ntacl sysvolreset systemctl restart samba-ad-dc systemctl status samba-ad-dc já deu o serviço como activo e sem erros. E quando tentei de novo logar um utilizador no computador CLIENTE, funcionou, e os GPOs estavam activos.\nResolver o mesmo problema no cliente RSAT foi um pouco mais complicado; primeiro tive de tirar o cliente do domínio pela GUI (Computer Preferences como Administrator local), e depois já foi possível abrir uma PowerShell de Administrador e usar os comandos\n1 2 Add-Computer -Credential DASILVAT\\Administrator -Domain DASILVAT Restart-Computer No entanto, passei a ter outro problema no log do serviço samba-ad-dc; imagino que devido a ter reinicializado as ACLs da sysvol, agora são as permissões das shares que dão erro:\nchdir_current_service: vfs_ChDir(/mnt/dumdum/recursos) failed: Permission denied. Current token: uid=3000041, gid=3000026, 7 groups: 3000041 3000026 3000035 3000036 3000037 3000006 3000011\r\nEste token, claro, corresponde ao computador que acabei de reintroduzir no domínio:\n1 wbinfo --sid-to-name $(wbinfo --uid-to-sid 3000041) DASILVAT\\WIN7-RSAT$ 1\r A solução foi adicionar o grupo Domain Computers à share (bastaram permissões de leitura)\nAgora que temos o sistema mais ou menos estabilizado, podemos testar a migração de TJGGS de CentOS 8 para Rocky Linux e para AlmaLinux\nRocky Linux A página que documenta o processo de migração é https://docs.rockylinux.org/guides/migrate2rocky/ , e é aconselhado estarmos logados na conta root.\nPara evitar o método curl \u0026lt;url\u0026gt; -o \u0026lt;script\u0026gt;.sh, que pode ser inseguro se houver um ataque Man-In-The-Middle, começamos por instalar o git:\n1 dnf install git -y Last metadata expiration check: 2:05:12 ago on Sun 31 Oct 2021 09:14:58 PM WET.\rPackage git-2.27.0-1.el8.x86_64 is already installed.\rDependencies resolved.\rNothing to do.\rComplete!\r Descarregamos os scripts do repositório e corremos o script de migração:\n1 2 3 git clone https://github.com/rocky-linux/rocky-tools.git chmod u+x ./rocky-tools/migrate2rocky/migrate2rocky.sh ./rocky-tools/migrate2rocky/migrate2rocky.sh -r [...]\rDone, please reboot your system.\rA log of this installation can be found at /var/log/migrate2rocky.log\r Depois de reiniciar, o GRUB tem uma entrada \u0026ldquo;Rocky Linux\u0026rdquo;:\n\r\rO resultado de hostnamectl é:\n\r\rUm utilizador pré-existente ainda pode logar-se no domínio:\n\r\rUsando o RSAT, criei um novo utilizador com as mesmas características e o mesmo pacote de GPOs:\n\r\r\r\rO novo utilizador também se logou e as mesmas configurações foram aplicadas, excepto a impressora partilhada que é uma configuração muito sensível em Samba; no entanto, o fundo de ecrã correcto carregou (especificado por GPO a partir de uma pasta partilhada), por isso não foi impedido por qualquer problema de permissões nas shares do domínio.\n\r\rAlmaLinux Para uma avaliação equilibrada, usou-se um segundo clone de TJGGS ainda em CentOS mas já com os problemas do Samba resolvidos (pelo menos, aqueles que detectei)\nO processo de migração do AlmaLinux não está tão bem documentado como o Rocky; em vez de uma página de explicação, o botão Migrate em https://almalinux.org vai directamente para o repositório GitHub do script de migração, onde a documentação do processo fica a cargo do README. Não é a situação ideal.\nPor outro lado, também não é mencionada a hipótese de clonar localmente o repositório, e apenas é dada a sugestão de descarregar o script por curl. Ainda menos ideal, e claramente inseguro.\nPor isso, vamos repetir o processo mais seguro, como fizemos para o Rocky:\nAbrimos uma root shell e clonamos o repositório:\n1 2 3 git clone https://github.com/AlmaLinux/almalinux-deploy.git chmod u+x ./almalinux-deploy/almalinux-deploy.sh ./almalinux-deploy/almalinux-deploy.sh Check root privileges OK\rCheck centos-8.x86_64 is supported OK\rDownload RPM-GPG-KEY-AlmaLinux OK\rImport RPM-GPG-KEY-AlmaLinux to RPM DB OK\rDownload almalinux-release package OK\rVerify almalinux-release package OK\rYour OS is supported OK\rRemove OS specific rpm packages OK\r[...]\rAll Secure Boot related packages which were released by not AlmaLinux are reinstalledOK\rMigration to AlmaLinux is completed\r E reiniciei TJGGS\n\r\r\r\r\r\rNo RSAT criei um novo utilizador, agora na Active Directory baseada em AlmaLinux\n\r\rEste novo utilizador também se logou no domínio a partir do computador Cliente, com as GPOs aplicadas correctamente (menos a impressora):\n\r\rConclusão Como prometido, tanto o Rocky Linux como o AlmaLinux foram capazes de fazer a migração lateral de um servidor CentOS8 com alguns serviços (samba-ad-dc, chrony, RAIDs mdm, SSHd) sem grandes problemas.\nOs problemas iniciais de permissões de certeza que foram causados por mim durante a configuração inicial do servidor, porque me lembro que tinha problemas com as permissões da sysvol que impediam alguns GPOs de funcionar correctamente; basicamente o problema arrastou-se até agora.\nEditorial O mundo do Free and Open Source sempre viveu um problema causado por \u0026ldquo;Liberdade\u0026rdquo; e \u0026ldquo;Gratuitidade\u0026rdquo; se escreverem exactamente da mesma maneira em Inglês: Free. E se a Liberdade é um valor relativo para muita gente, a Gratuitidade é um atractivo muito maior e que se pode medir directamente, por isso o mundo FOSS, pelo menos nos primeiros anos, pouco fez para frisar que, das duas possibilidades, a Liberdade é que é o objectivo principal do FOSS.\nObviamente que nada é \u0026ldquo;de graça\u0026rdquo;, tudo tem um custo que se não somos nós a pagar sendo o produto, alguém está a pagar por nós, seja em esforço humano, ciclos de CPU, armazenamento, conectividade, energia, hardware… Por isso quando os projectos FOSS atingem alguma maturidade e posição no mercado, tentam que os utilizadores contribuam com alguma coisa (qualquer coisa!) que beneficie o projecto directamente, mais do que a mera divulgação e promoção.\nDeste modo, as companhias por trás de muitos projectos FOSS vendem serviços e suporte, mas cada vez mais também fecham certas conveniências por trás desses contratos, para incutir os utilizadores a pagarem dinheiro pelo produto FOSS. Essas conveniências extra (para além do simples suporte) costumam ser:\n Funcionalidade limitada: certas funcionalidades de uso mais empresarial são desenvolvidas com base numa licença não-FOSS e apenas são desbloqueadas contra o pagamento de uma licença ou compra de hardware em pacote OPNsense, e outros; notoriamente, quase todos os fornecedores de appliances de armazenamento baseadas em ZFS (como o TrueNAS) bloqueiam o acesso a funcionalidades de clustering e High-Availability à compra de hardware em pacote com o software. Acesso a actualizações: apenas são disponibilizados os binários da versão x.0.0, e quaisquer actualizações sob a forma de binários pré-compilados apenas estão disponíveis para utilizadores com contrato de suporte; no entanto, graças às licenças FOSS, quem quiser pode compilar o código-fonte (e assumir o suporte). Bareos, OPNsense Acesso a versões estáveis: em sentido contrário ao anterior, apenas são disponibilizadas em binário a compilação diária (nightly) do estado actual do processo de desenvolvimento, sem qualquer tipo de testes de funcionalidade (mas pelo menos a compilação terminou com sucesso); neste caso, para se obter uma versão estável é mais seguro ir buscar o código-fonte da nightly da versão principal (major version) anterior, que estará mais bem testada e cujas actualizações deverão corresponder a resoluções de erros - mesmo assim, sem nenhuma garantia de que não tenham sido introduzidos novos erros. VyOS A RedHat decidiu-se por uma variante desta última opção: em vez de apenas disponibilizar as nightlies do CentOS, teve noção que isso seria um passo maior que as pernas (além de já terem o Fedora Rawhide para isso) e decidiu que o CentOS passaria a estar acessível em binário no estado de desenvolvimento da minor version actual\n Em vez de a versão 8.4 do CentOS ser lançada depois do RHEL 8.4 ser lançado, o RHEL estará na versão 8.4 e o CentOS estará na versão seguinte 8.5, e apenas quando o CentOS Stream 8.5 for julgado estável é que será convertido em RHEL 8.5 e o CentOS passará imediatamente a testar as correcções previstas para versão 8.6. Ou mais ainda, quem quiser testar as funcionalidades da versão 9 do RHEL, já pode tentar instalar o CentOS Stream 9\u0026hellip; Deste modo, os utilizadores do CentOS contribuirão com testes (e relatórios de erros, ou assim espera a RedHat), pagando qualquer coisa pelo uso do código desenvolvido pela RedHat.\n","description":"De Herodes (CentOS) a Pilatos (Rocky e Alma)","id":8,"section":"unixlike","tags":null,"title":"Plano de Fuga","uri":"https://tiagojsilva.github.io/pt/unixlike/rpm/redhat/rocky_almalinux/2022-01-10_escape-from-centos/"},{"content":"Instalação do BIND9 O sistema onde este serviço BIND9 foi instalado é o mesmo que é descrito na página Instalação TinyCoreLinux.\nExiste um pacote BIND9 para o TinyCore, mas tal como noutras ocasiões, a instalação é muito faça-você-mesmo1. Não temos isqueiros, nem sequer fósforos, é mesmo esfregar os pauzinhos um no outro até sair fumo.\nInstalamos a extensão usando o browser tce-ab ou o directamente o instalador tce-load\n1 tce-load -wi bind bind.tcz.dep OK\rlibcap.tcz.dep OK\rDownloading: gcc_libs.tcz\rConnecting to repo.tinycorelinux.net (89.22.99.37:80)\rsaving to 'gcc_libs.tcz'\rgcc_libs.tcz 100% |************************************************************************************| 1020k 0:00:00 ETA\r'gcc_libs.tcz' saved\rgcc_libs.tcz: OK\rDownloading: attr.tcz\rConnecting to repo.tinycorelinux.net (89.22.99.37:80)\rsaving to 'attr.tcz'\rattr.tcz 100% |************************************************************************************| 24576 0:00:00 ETA\r'attr.tcz' saved\rattr.tcz: OK\rDownloading: libcap.tcz\rConnecting to repo.tinycorelinux.net (89.22.99.37:80)\rsaving to 'libcap.tcz'\rlibcap.tcz 100% |************************************************************************************| 24576 0:00:00 ETA\r'libcap.tcz' saved\rlibcap.tcz: OK\rDownloading: bind.tcz\rConnecting to repo.tinycorelinux.net (89.22.99.37:80)\rsaving to 'bind.tcz'\rbind.tcz 100% |************************************************************************************| 1864k 0:00:00 ETA\r'bind.tcz' saved\rbind.tcz: OK\r\nHá algumas dependências que por alguma razão não são instaladas automaticamente, e que temos de instalar:\n1 tce-load -wi libuv.tcz Downloading: libuv.tcz\rConnecting to repo.tinycorelinux.net (89.22.99.37:80)\rsaving to 'libuv.tcz'\rlibuv.tcz 100% |************************************************************************************| 65536 0:00:00 ETA\r'libuv.tcz' saved\rlibuv.tcz: OK\r Configuração inicial Para aproveitar o backup automático que temos configurado para a pasta /opt/, vamos colocar as configurações do bind em /opt/local/etc/bind em vez do usual /usr/local/etc/bind\n1 2 3 mkdir /opt/local/ mkdir /opt/local/etc/ mkdir /opt/local/etc/bind Temos de descarregar duas peças importantes de informação: a root zone e as bind keys\n1 2 wget -O /opt/local/etc/bind/root.zone \\ http://www.internic.net/domain/root.zone Connecting to www.internic.net (192.0.32.9:80)\rsaving to '/opt/local/etc/bind/root.zone'\rroot.zone 100% |************************************************************************************| 2113k 0:00:00 ETA\r'/opt/local/etc/bind/root.zone' saved\r 1 2 wget -O /opt/local/etc/bind/bind.keys \\ https://downloads.isc.org/isc/bind9/keys/9.11/bind.keys.v9_11 Connecting to downloads.isc.org (151.101.2.217:443)\rsaving to '/opt/local/etc/bind/bind.keys'\rbind.keys 100% |************************************************************************************| 3923 0:00:00 ETA\r'/opt/local/etc/bind/bind.keys' saved\r O ficheiro principal de configuração é o named.conf\nColocar o seguinte em /opt/local/etc/bind/named.conf:\nacl tjs {\rlocalnets; localhost;\r172.24.130.0/23; 10.48.130.0/24; };\roptions {\rdirectory \u0026quot;/opt/local/etc/bind\u0026quot;;\rforwarders { 1.1.1.1; 8.8.8.8; };\rallow-query { tjs; };\rdnssec-validation auto;\rbindkeys-file \u0026quot;/opt/local/etc/bind/bind.keys\u0026quot;;\rauth-nxdomain no;\rlisten-on-v6 { none; };\r};\r directory: pasta das configurações forwarders: aquilo que o BIND não souber, pergunta a estes allow-query: redes que podem pedir resolução de nomes, para as quais foi definida uma ACL Neste ficheiro também se declaram as zonas. Em primeiro lugar a zona root:\nzone \u0026quot;.\u0026quot; in {\rtype hint;\rfile \u0026quot;root.zone\u0026quot;;\r};\rExistem duas configurações para cada zona: a zona directa (forward zone), que converte nomes em IPs, e a zona reversa (reverse zone), que converte IPs em nomes)\nUma zona directa para o localhost2\nzone \u0026quot;localhost\u0026quot; in {\rtype master;\rfile \u0026quot;localhost.zone\u0026quot;;\r};\rUma zona reversa para o localhost\nzone \u0026quot;localhost\u0026quot; in {\rtype master;\rfile \u0026quot;localhost.zone\u0026quot;;\r};\rE por razões de segurança, descritas no RFC1912, também devem ser criadas duas zonas acessórias:\nzone \u0026quot;0.in-addr.arpa\u0026quot; in {\rtype master;\rfile \u0026quot;0.in-addr.arpa.zone\u0026quot;;\r};\rzone \u0026quot;255.in-addr.arpa\u0026quot; in {\rtype master;\rfile \u0026quot;255.in-addr.arpa.zone\u0026quot;;\r};\rCada zona declarada no named.conf necessita de um ficheiro de zona.\nO ficheiro da zona directa localhost é /opt/local/etc/bind/localhost.zone:\n; BIND data for LOCALHOST zone FWD\r;\r$ORIGIN localhost.\r$TTL 3D\r@ IN SOA @ root (\r2020090600 ; serial\r8H ; refresh\r2H ; retry\r7D ; expiry\r1D ; minimum\r)\r@ IN NS @\rIN A 127.0.0.1\rA zona reversa localhost é /opt/local/etc/bind/127.in-addr.arpa.zone:\n; BIND data for LOCALHOST zone REV\r;\r$ORIGIN 127.in-addr.arpa.\r$TTL 3D\r@ IN SOA localhost. admin.localhost. (\r2020090600 ; serial\r8H ; refresh\r2H ; retry\r7D ; expire\r1D ; negative caching TTL\r)\r;NS\r@ IN NS localhost.\r;localhost\r1 IN PTR localhost.\rNo campo Serial decidi3 usar a data de alteração da zona, seguida de um número com dois dígitos que indica se há várias mudanças no mesmo dia. Se o Serial de um ficheiro de zona alterado não for um número maior que o da versão anterior, o ficheiro de zona não será carregado pelos servidores.\nOs tempos SOA são próximos de 24h, 2h, 30d, 4d para servidores expostos à WAN, e 8h, 2h, 7d, 1d para servidores em LAN (fonte: RFC1912).\nAs zonas pedidas pelo RFC1912 só têm o bloco SOA e o NS:\n/opt/local/etc/bind/0.in-addr.arpa.zone\n; BIND RFC1912 data\r;\r$ORIGIN 0.in-addr.arpa.\r$TTL 3D\r@ IN SOA localhost. admin.localhost. (\r2020090600 ; serial\r8H ; refresh\r2H ; retry\r7D ; expire\r1D ; negative caching TTL\r)\r;NS\r@ IN NS localhost.\rA zona 255.in-addr.arpa é idêntica à anterior, basta copiar:\n1 sudo cp -a /opt/local/etc/bind/0.in-addr.arpa.zone /opt/local/etc/bind/255.in-addr.arpa.zone E neste último mudar $ORIGIN para 255.in-addr.arpa\nPode-se testar o funcionamento do bind com o comando:4\n1 sudo /usr/local/sbin/named -4g -c /opt/local/etc/bind/named.conf 05-Sep-2020 19:47:25.186 starting BIND 9.16.3 (Stable Release) \r05-Sep-2020 19:47:25.186 running on Linux i686 5.4.3-tinycore #2020 SMP Tue Dec 17 17:00:50 UTC 2019\r05-Sep-2020 19:47:25.186 built with '--prefix=/usr/local' '--sysconfdir=/usr/local/etc' '--libdir=/usr/local/lib' '--localstatedir=/var' '--enable-shared' '--disable-static' '--with-libtool' '--with-openssl=/usr/local' '--with-readline=-lreadline -lncursesw' '--enable-full-report' '--enable-linux-caps' 'CC=gcc -flto -fuse-linker-plugin -march=i486 -mtune=i686 -Os -pipe'\r05-Sep-2020 19:47:25.186 running as: named -4g -c /opt/local/etc/bind/named.conf\r05-Sep-2020 19:47:25.186 compiled by GCC 9.2.0\r05-Sep-2020 19:47:25.186 compiled with OpenSSL version: OpenSSL 1.1.1f 31 Mar 2020\r05-Sep-2020 19:47:25.186 linked to OpenSSL version: OpenSSL 1.1.1f 31 Mar 2020\r05-Sep-2020 19:47:25.186 compiled with zlib version: 1.2.11\r05-Sep-2020 19:47:25.186 linked to zlib version: 1.2.11\r05-Sep-2020 19:47:25.186 ----------------------------------------------------\r05-Sep-2020 19:47:25.186 BIND 9 is maintained by Internet Systems Consortium,\r05-Sep-2020 19:47:25.186 Inc. (ISC), a non-profit 501(c)(3) public-benefit\r05-Sep-2020 19:47:25.186 corporation. Support and training for BIND 9 are\r05-Sep-2020 19:47:25.186 available at https://www.isc.org/support\r05-Sep-2020 19:47:25.186 ----------------------------------------------------\r05-Sep-2020 19:47:25.186 adjusted limit on open files from 4096 to 1048576\r05-Sep-2020 19:47:25.186 found 1 CPU, using 1 worker thread\r05-Sep-2020 19:47:25.186 using 1 UDP listener per interface\r05-Sep-2020 19:47:25.186 using up to 21000 sockets\r05-Sep-2020 19:47:25.206 loading configuration from '/opt/local/etc/bind/named.conf'\r05-Sep-2020 19:47:25.209 reading built-in trust anchors from file '/opt/local/etc/bind/bind.keys'\r05-Sep-2020 19:47:25.209 /opt/local/etc/bind/bind.keys:22: option 'managed-keys' is deprecated\r05-Sep-2020 19:47:25.209 using default UDP/IPv4 port range: [32768, 60999]\r05-Sep-2020 19:47:25.216 listening on IPv4 interface lo, 127.0.0.1#53\r05-Sep-2020 19:47:25.219 listening on IPv4 interface eth0, 10.123.130.6#53\r05-Sep-2020 19:47:25.219 generating session key for dynamic DNS\r05-Sep-2020 19:47:25.219 sizing zone task pool based on 5 zones\r05-Sep-2020 19:47:26.176 extra data in root hints 'root.zone'\r05-Sep-2020 19:47:26.176 none:98: 'max-cache-size 90%' - setting to 162MB (out of 180MB)\r05-Sep-2020 19:47:26.183 obtaining root key for view _default from '/opt/local/etc/bind/bind.keys'\r05-Sep-2020 19:47:26.183 dnssec-validation auto: WARNING: root zone key not found\r05-Sep-2020 19:47:26.183 using built-in root key for view _default\r05-Sep-2020 19:47:26.183 set up managed keys zone for view _default, file 'managed-keys.bind'\r[...]\r05-Sep-2020 19:47:26.236 configuring command channel from '/usr/local/etc/rndc.key'\r05-Sep-2020 19:47:26.236 couldn't add command channel 127.0.0.1#953: file not found\r05-Sep-2020 19:47:26.239 not using config file logging statement for logging due to -g option\r05-Sep-2020 19:47:26.239 managed-keys-zone: loaded serial 3\r05-Sep-2020 19:47:26.243 zone 0.in-addr.arpa/IN: loaded serial 2020090600\r05-Sep-2020 19:47:26.269 zone 127.in-addr.arpa/IN: loaded serial 2020090600\r05-Sep-2020 19:47:26.273 zone 255.in-addr.arpa/IN: loaded serial 2020090600\r05-Sep-2020 19:47:26.279 zone localhost/IN: loaded serial 2020090600\r05-Sep-2020 19:47:26.279 all zones loaded\r05-Sep-2020 19:47:26.283 running\r Colocar o serviço a arrancar com o sistema:\n1 2 echo \u0026#34;/usr/local/sbin/named -4 -c /opt/local/etc/bind/named.conf \u0026amp;\u0026#34; \u0026gt;\u0026gt; \\ /opt/bootlocal.sh \u0026amp;\u0026amp; filetool.sh -b E é necessário mudar a configuração de rede para utilizar o serviço que foi instalado como servidor DNS do sistema. A alteração pode ser implementada imediatamente sem reiniciar, com o comando\n1 sudo echo \u0026#34;nameserver 127.0.0.1\u0026#34; \u0026gt; /etc/resolv.conf Mas caso se deseje que a configuração se mantenha depois de um reinício, há mais um passo a dar: edita-se o ficheiro /opt/eth0.sh, comentam-se as linhas echo existentes, e acrescenta-se a linha:\necho \u0026quot;nameserver 127.0.0.1\u0026quot; \u0026gt; /etc/resolv.conf\rComo o ficheiro está protegido contra alterações, é necessário forçar a alteração usando o comando :w! no vim. No final, claro,\n1 filetool.sh -b Gestão do serviço O TinyCore não tem nenhum processo de gestão de serviços pré-definido ou configurado, é tudo à unha. No limite, o BIND poderia ser desligado com sudo killall named e ligado de novo com o comando que temos usado até agora.\nMas podemos pôr uns pneus no carro, é mais confortável. O serviço BIND, tal como o OpenSSH que instalámos no artigo sobre a instalação do TinyCoreLinux (link no topo do artigo), tem um script de gestão (neste caso, bind) que é instalado automaticamente pela extensão em /usr/local/etc/init.d/\n1 /usr/local/etc/init.d/bind usage /usr/local/etc/init.d/bind start|stop|reload|restart|status\r Assim, não temos de escrever um script5 nem de adaptar o do OpenSSH.\nEste script, devido à maneira como as extensões são montadas no sistema, não pode ser alterado; para lhe fazermos alterações (que são necessárias), precisamos de copiar o script para um local permanente onde tenhamos permissões de escrita.\nO script está originalmente em /usr/local/etc/init.d/, por isso um local lógico será /opt/local/etc/init.d/\n1 mkdir /opt/local/etc/init.d E temos de copiar quebrando os symlinks dos ficheiros para o local onde o TinyCore os monta de facto, copiando o ficheiro real e não o symlink:\n1 sudo cp -aL /usr/local/etc/init.d/bind /opt/local/etc/init.d/ Acrescentamos essa pasta à variável de sistema PATH, para não termos de escrever o caminho para o(s) script(s) quando os quisermos usar:\n1 2 3 echo \u0026#39;export PATH=\u0026#34;$PATH:/opt/local/etc/init.d/\u0026#34; \u0026gt;\u0026gt; ~/.ashrc sudo echo \u0026#39;export PATH=\u0026#34;$PATH:/opt/local/etc/init.d/\u0026#34; \u0026gt;\u0026gt; /root/.ashrc filetool.sh -b Agora podemos fazer alterações ao script, nomeadamente a variável NAMED_OPTIONS. Mas ainda antes disso, temos de criar o utilizador e o grupo que vão gerir o serviço, porque uma extensão TCZ é uma mera lista de ficheiros e não toca nos ficheiros de sistema.\nUtilizador e grupo do serviço O script vem configurado para utilizar um utilizador criado especificamente para correr o serviço, named. Para o criar, precisamos dos comandos6:\n1 2 sudo addgroup named -g 2000 sudo adduser named -u 2000 -G named -DH -s /bin/false Fazer backup do /etc/passwd e do /etc/group:\n1 2 echo \u0026#34;etc/passwd\u0026#34; \u0026gt;\u0026gt; /opt/.filetool.lst echo \u0026#34;etc/group\u0026#34; \u0026gt;\u0026gt; /opt/.filetool.lst \u0026amp;\u0026amp; filetool.sh -b E mudar as permissões dos ficheiros de configuração:\n1 2 sudo chown -R named:named /opt/local/etc/bind sudo chmod -R 660 /opt/local/etc/bind Quando se utiliza o utilizador named, o bind vai tentar usar a pasta /var/run/named, que não existe. Temos de a criar e de a tornar persistente:\n1 2 3 mkdir /var/run/named sudo chown named:named /var/run/named echo \u0026#34;var/run/named\u0026#34; \u0026gt;\u0026gt; /opt/.filetool.lst \u0026amp;\u0026amp; filetool.sh -b Na nossa linha de comando actual de invocação do serviço, as nossas opções eram -4 (só IPv4) e -c /opt/local/etc/bin/named.conf (caminho para o ficheiro de configuração); são esses argumentos (especificando também o utilizador named) que temos de acrescentar na variável NAMED_OPTIONS do script /opt/local/etc/init.d/bind:\nNAMED_OPTIONS=\u0026quot;-u named -4 -c /opt/local/etc/bind/named.conf\u0026quot;\rGravar e sair.\nConfigurar o RNDC para gerir o BIND Mas o script de início do serviço também depende do utilitário de controlo rndc7, que não vem pronto a funcionar, ou não estaríamos no CoreLinux, estaríamos numa distribuição com água e saneamento básico:\nCriamos a chave que autoriza o rndc a comunicar com o bind e damos-lhe permanência:\n1 2 3 4 sudo rndc-confgen -a sudo chown root:staff /usr/local/etc/rndc.key sudo chmod 640 /usr/local/etc/rndc.key echo \u0026#34;usr/local/etc/rndc.key\u0026#34; \u0026gt;\u0026gt; /opt/.filetool.lst \u0026amp;\u0026amp; filetool.sh -b E pedimos um exemplo da configuração necessária:\n1 2 sudo rndc-confgen \u0026gt; /opt/local/etc/bind/rndc.out sudo cat /opt/local/etc/bind/rndc.out # Start of rndc.conf\rkey \"rndc-key\" {\ralgorithm hmac-sha256;\rsecret \"qXe5NgimFUmfztOZXJG4XXjkZJX0AdUEcTgci3+m38s=\";\r};\roptions {\rdefault-key \"rndc-key\";\rdefault-server 127.0.0.1;\rdefault-port 953;\r};\r# End of rndc.conf\r# Use with the following in named.conf, adjusting the allow list as needed:\r# key \"rndc-key\" {\r# algorithm hmac-sha256;\r# secret \"qXe5NgimFUmfztOZXJG4XXjkZJX0AdUEcTgci3+m38s=\";\r# };\r#\r# controls {\r# inet 127.0.0.1 port 953\r# allow { 127.0.0.1; } keys { \"rndc-key\"; };\r# };\r# End of named.conf\r No /opt/local/etc/bind/named.conf, acrescentam-se as instruções necessárias para usar o rndc, como indicado nos comentários acima.\nPrimeiro, o conteúdo da rndc.key\n1 sudo cat /usr/local/etc/rndc.key \u0026gt;\u0026gt; /opt/local/etc/bind/named.conf E acrescentar o seguinte ao /opt/local/etc/bind/named.conf\ncontrols {\rinet 127.0.0.1 port 953\rallow { 127.0.0.1; } keys { \u0026quot;rndc-key\u0026quot;; };\r};\rPara testar,\n1 2 3 sudo killall named /usr/local/sbin/named -u named -4 -c /opt/local/etc/bind/named.conf \u0026amp; rndc status version: BIND 9.16.3 (Stable Release) \rrunning on verynice: Linux i686 5.4.3-tinycore #2020 SMP Tue Dec 17 17:00:50 UTC 2019\rboot time: Sun, 06 Sep 2020 00:54:14 GMT\rlast configured: Sun, 06 Sep 2020 00:54:16 GMT\rconfiguration file: /opt/local/etc/bind/named.conf\rCPUs found: 1\rworker threads: 1\rUDP listeners per interface: 1\rnumber of zones: 106 (97 automatic)\rdebug level: 0\rxfers running: 0\rxfers deferred: 0\rsoa queries in progress: 0\rquery logging is OFF\rrecursive clients: 0/900/1000\rtcp clients: 0/150\rTCP high-water: 0\rserver is up and running\r Agora podemos ir ao /opt/bootlocal.sh e mudar a linha de activação de comando para usar o script. Comenta-se a linha de activação anterior (/usr/local/sbin/named -4 -c /opt/local/etc/bind/named.conf \u0026amp;) e acrescenta-se:\n/opt/local/etc/init.d/bind start\rGravar e sair.\nsudo reboot, para confirmar que as nossas configurações sobrevivem ao reinício do sistema.\nDepois de regressar, testar o serviço:\n1 rndc status [...]\rserver is up and running\r 1 nslookup www.google.com Server: 127.0.0.1\rAddress: 127.0.0.1#53\rNon-authoritative answer:\rName: www.google.com\rAddress: 216.58.211.228\rName: www.google.com\rAddress: 2a00:1450:4003:805::2004\r\n\r\rNum cliente que esteja numa das redes autorizadas a fazer perguntas, mudar a configuração de DNS para apontar ao IP de verynice (tenho utilizado 10.123.130.6), e ver se a resolução DNS é efectuada:\n\r\rConfiguração de zonas DNS As zonas são configuradas no ficheiro named.conf e a informação de cada zona reside em ficheiros de zona\nParece-me boa política separar os ficheiros de zona por \u0026ldquo;categoria\u0026rdquo;, na minha opinião, debaixo da pasta de configuração do BIND (neste caso, /opt/local/etc/bind/), dever-se-iam colocar os ficheiros de zona nas pastas:\n/opt/local/etc/bind/forward\r/opt/local/etc/bind/reverse\r/opt/local/etc/bind/slave\r/opt/local/etc/bind/stub\rNeste caso não o farei porque temos muito poucas zonas, mas mesmo assim vamos fazer uma pasta para os ficheiros de zona, para não ficarem misturados com as configurações do BIND propriamente dito:\n1 sudo mkdir /opt/local/etc/bind/zones Os ficheiros de zona podem ter nomes totalmente arbitrários, mas algumas convenções podem ser usadas; vou usar o termo definido entre aspas no named.conf terminado na extensão .zone; em Debian, os nomes costumam ser db.\u0026lt;nomedazona\u0026gt;, por exemplo.\nDeclaração das zonas no named.conf Editamos o /opt/local/etc/bind/named.conf e acrescentamos o seguinte:\nZona directa da rede do servidor DNS\nzone \u0026quot;dnstestes.wan\u0026quot; in {\rtype master;\rfile \u0026quot;zones/dnstestes.wan.zone\u0026quot;;\r# allow-update { };\r# allow-transfer { };\r# notify yes;\r};\rJá a zona reversa é:\nzone \u0026quot;130.123.10.in-addr.arpa\u0026quot; in {\rtype master;\rfile \u0026quot;zones/130.123.10.in-addr.arpa.zone\u0026quot;;\r# allow-update { };\r# allow-transfer { };\r# notify yes;\r};\rAs directivas allow-update, allow transfer e notify usam-se quando existem servidores DNS que são apenas seguidores para esta zona e devem ser actualizados por zone transfer quando há mudanças na zona.\r Configuramos uma zona normal no /opt/local/etc/bind/named.conf da seguinte maneira:\nzone \u0026quot;tjs.lan\u0026quot; in {\rtype master;\rfile \u0026quot;zones/tjs.lan.zone\u0026quot;;\r# allow-update { };\r# allow-transfer { };\r# notify yes;\r};\rEsta rede é um /23 e precisa de duas zonas reversas para ser coberta (por as zonas reversas DNS serem classful, ou seja, só /8, /16, ou /24), por isso vou colocar as duas que julgo serem necessárias:\nzone \u0026quot;130.24.172.in-addr.arpa\u0026quot; in {\rtype master;\rfile \u0026quot;zones/130.24.172.in-addr.arpa.zone\u0026quot;;\r# allow-update { };\r# allow-transfer { };\r# notify yes;\r};\rzone \u0026quot;131.24.172.in-addr.arpa\u0026quot; in {\rtype master;\rfile \u0026quot;zones/131.24.172.in-addr.arpa.zone\u0026quot;;\r# allow-update { };\r# allow-transfer { };\r# notify yes;\r};\rReinicia-se o serviço e verificar o seu estado:\n1 /opt/local/etc/init.d/bind restart Stopping BIND: /usr/local/sbin/rndc stop\rUsing killall named on additional BIND processes...\rStarting BIND: /usr/local/sbin/named -u named -4 -c /opt/local/etc/bind/named.conf\r 1 rndc status version: BIND 9.16.3 (Stable Release) \rrunning on verynice: Linux i686 5.4.3-tinycore #2020 SMP Tue Dec 17 17:00:50 UTC 2019\rboot time: Sat, 19 Sep 2020 11:12:11 GMT\rlast configured: Sat, 19 Sep 2020 11:12:12 GMT\rconfiguration file: /opt/local/etc/bind/named.conf\rCPUs found: 1\rworker threads: 1\rUDP listeners per interface: 1\rnumber of zones: 111 (97 automatic)\rdebug level: 0\rxfers running: 0\rxfers deferred: 0\rsoa queries in progress: 0\rquery logging is OFF\rrecursive clients: 0/900/1000\rtcp clients: 0/150\rTCP high-water: 0\rserver is up and running\r 1 tail -20 /var/log/messages | grep \u0026#34;named\u0026#34; | cut -d\u0026#34; \u0026#34; -f4- verynice daemon.info named[1612]: none:98: 'max-cache-size 90%' - setting to 162MB (out of 180MB)\rverynice daemon.notice named[1612]: command channel listening on 127.0.0.1#953\rverynice daemon.info named[1612]: managed-keys-zone: loaded serial 58\rverynice daemon.info named[1612]: zone 130.48.10.in-addr.arpa/IN: loaded serial 2020091600\rverynice daemon.info named[1612]: zone 0.in-addr.arpa/IN: loaded serial 2020090600\rverynice daemon.info named[1612]: zone 130.24.172.in-addr.arpa/IN: loaded serial 2020091710\rverynice daemon.info named[1612]: zone dnstestes.wan/IN: loaded serial 2020091600\rverynice daemon.info named[1612]: zone 127.in-addr.arpa/IN: loaded serial 2020090600\rverynice daemon.info named[1612]: zone 131.24.172.in-addr.arpa/IN: loaded serial 2020091710\rverynice daemon.info named[1612]: zone 255.in-addr.arpa/IN: loaded serial 2020090600\rverynice daemon.info named[1612]: zone tjs.lan/IN: loaded serial 2020091710\rverynice daemon.info named[1612]: zone localhost/IN: loaded serial 2020090600\rverynice daemon.notice named[1612]: all zones loaded\rverynice daemon.notice named[1612]: running\rverynice daemon.info named[1612]: managed-keys-zone: Key 20326 for zone . is now trusted (acceptance timer complete)\rverynice daemon.info named[1612]: resolver priming query complete\r Para testar, pode-se usar o nslookup integrado ou instalar o dig. O nslookup necessita, no entanto, de uma dependência que não está instalada:\n1 tce-load -wi readline.tcz readline.tcz.dep OK\rDownloading: readline.tcz\rConnecting to repo.tinycorelinux.net (89.22.99.37:80)\rsaving to 'readline.tcz'\rreadline.tcz 100% |************************************************************************************| 128k 0:00:00 ETA\r'readline.tcz' saved\rreadline.tcz: OK\r Testaram-se as seguintes resoluções, baseadas em ficheiros de zona que deixo como exercício preencherem com base nos resultados apresentados na captura de ecrã (um ficheiro de zona para cada uma das zonas declaradas no /opt/local/etc/bind/named.conf), a colocar em /opt/local/etc/bind/zones de acordo com o modelo demonstrado nas zonas pedidas pelo RFC1912 (acima):\n1 2 3 4 nslookup dasilvat.tjs.lan nslookup tjspc.tjs.lan nslookup gateway.dnstestes.wan nslookup verynice.dnstestes.wan \r\r\rComo na zona tjs.lan também se definiu um registo MX, testou-se a sua resolução (mude o ficheiro de zona com base no resultado apresentado na captura de ecrã abaixo):\n1 nslookup -type=MX tjs.lan \r\r\rConclusão Escolhi um TinyCore Linux para implementar este serviço porque o meu sistema host tinha muito pouca RAM para implementar o resto da topologia que ia usar; no entanto, o TinyCore Linux precisa de RAM para carregar a imagem de sistema e para as aplicações, por isso o mínimo de RAM que consegui usar foi 256MB, porque com 128MB o BIND9 não tinha memória suficiente para arrancar.\nNo entanto, um sistema Debian 10 (Minimal Install), que armazena o sistema em disco rígido e tem memória virtual, consegue configurar o serviço SSH, servidor NTP (este TinyCoreLinux era apenas um cliente) e BIND9 nos mesmos 256MB, por isso, a não ser que correr a partir de RAM e ser stateless (repor as configurações originais depois de um reboot) seja muito importante, recomendo que se use o Debian ou outro tipo de distro Linux mais mainstream\n (https://mivilisnet.wordpress.com/2019/06/11/microcore-linux-and-the-bind-server/#more-2666)\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n (https://wiki.samba.org/index.php/Setting_up_a_BIND_DNS_Server)\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n Porque é um dos métodos possíveis; existem outros.\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n -4 = só IPv4; -g = log no STDOUT em vez de STDERR ; -c \u0026lt;caminho_do_ficheiro_de_configuração\u0026gt;\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n (https://mivilisnet.wordpress.com/2020/05/05/how-i-wrote-my-shell-script-to-control-the-bind-daemon/)\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n -D não definir password; -H não criar home; -s shell (falsa para não poder fazer login)\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n https://www.ibm.com/support/pages/how-setup-rndc-bind-9\nhttps://tecadmin.net/configure-rndc-for-bind9\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n ","description":"Onde configuro o BIND9 no TinyCore Linux, uma distribuição em que quase nada está pronto a usar","id":9,"section":"networking","tags":null,"title":"BIND9: configuração de raiz","uri":"https://tiagojsilva.github.io/pt/networking/protocols/2021-10-30_dns-bind9-tinycorelinux/"},{"content":"\r\r\rEu só queria descarregar a demonstração do ESXi\u0026hellip;\nBom, a não ser que amanhã isto se resolva parece que vou começar a aprender hipervisores Tipo 1 com o XCP-ng\u0026hellip;\nPrimeiras impressões e isso.\n","description":"Tropeçar na primeira barreira","id":10,"section":"blog","tags":null,"title":"Ninguém atende","uri":"https://tiagojsilva.github.io/pt/blog/2021-11-17_computersaysno/"},{"content":"Na primeira vez em que tentei configurar um botão Copy para as caixas de código, deixei uma nota no GitHub do tema Zdoc.\nHá dias um outro utilizador do Zdoc publicou a solução que funcionou para ele, e com esse estímulo, tentei de novo.\nInfelizmente, já devo ter manipulado de mais o DOM da minha versão do tema (manter-me compatível com o upstream, infelizmente, não vai dar para já) para poder utilizar directamente o código dele, mas tentei mexer mais um pouco no código que tinha tentado utilizar anteriormente, que era baseado nesta solução proposta por Tom Spencer\nCom as minhas alterações, ficou assim:\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 // insert just before the \u0026lt;/script\u0026gt; tag // tomspencer, https://www.tomspencer.dev/blog/2018/09/14/adding-click-to-copy-buttons-to-a-hugo-powered-blog/ (function() { \u0026#39;use strict\u0026#39;; if(!document.queryCommandSupported(\u0026#39;copy\u0026#39;)) { return; } function flashCopyMessage(el, msg) { el.textContent = msg; setTimeout(function() { el.textContent = \u0026#34;COPY\u0026#34;; }, 1000); } function selectText(node) { var selection = window.getSelection(); var range = document.createRange(); range.selectNodeContents(node); selection.removeAllRanges(); selection.addRange(range); return selection; } function addCopyButton(containerEl) { var copyBtn = document.createElement(\u0026#34;button\u0026#34;); copyBtn.className = \u0026#34;highlight-copy-btn\u0026#34;; copyBtn.textContent = \u0026#34;COPY\u0026#34;; var codeEl = containerEl.firstElementChild; copyBtn.addEventListener(\u0026#39;click\u0026#39;, function() { try { var selection = selectText(codeEl); document.execCommand(\u0026#39;copy\u0026#39;); selection.removeAllRanges(); flashCopyMessage(copyBtn, \u0026#39;Copied!\u0026#39;) } catch(e) { console \u0026amp;\u0026amp; console.log(e); flashCopyMessage(copyBtn, \u0026#39;Failed :\\\u0026#39;(\u0026#39;) } }); containerEl.appendChild(copyBtn); } // Add copy button to code blocks var highlightBlocks = document.getElementsByClassName(\u0026#39;highlight\u0026#39;); for (var i = 0; i \u0026lt; highlightBlocks.length; i++) { addCopyButton(highlightBlocks[i]); } })(); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 .highlight-copy-btn { position: relative; bottom: 22px; right: 0px; border: 0; border-radius: 4px; padding: 1px; font-size: 0.6em; line-height: 1.0; opacity: 0.6; min-width: 65px; text-align: center; letter-spacing: 2px; @includethemify($codeblock) { color: themed(\u0026#39;content-pre-color\u0026#39;); background: themed(\u0026#39;content-pre-background-color\u0026#39;); border: 1.25px solid themed(\u0026#39;border-line-color\u0026#39;); } border-top-left-radius: 0; border-top-right-radius: 4px; border-bottom-right-radius: 0; border-bottom-left-radius: 4px; white-space: nowrap; padding: 4px 4px 5px 4px; margin: 0 0 0 1px; cursor: pointer; opacity: 0.6; } .highlight-copy-btn:hover { @includethemify($themes) { color: themed(\u0026#39;link\u0026#39;); background-color: themed(\u0026#39;body-background-color\u0026#39;); } } Funciona mais ou menos, mas só nos blocos de código para os quais foi detectada uma sintaxe (ou seja, em que o div class é highlight e o chroma foi activado). Para os outros, como os blocos de código nativos do MarkDown, não, e há ocasiões em que não posso ou não quero activar o chroma. Que fazer nesse caso?\nO código do Preston Rodriguez, que agradeço, não funciona com as alterações que já fiz ao tema e que não consigo desfazer nem perceber onde estão a falhar (já disse que não pesco quase nada de JavaScript?)\nTentei repetir, sem sucesso, o código do Tom Spencer em layouts/partials/head/scripts.html, mas usando como selector\nvar codeBlocks = document.querySelectorAll('pre \u0026gt; code');\rcodeBlocks.forEach(function(plainBlock) {\raddCopyButton(plainBlock);\r}\r(um perfeito exemplo da questão - neste momento o botão COPY não aparece aqui, mas se conseguir resolver isto, vai passar a aparecer)\n","description":"Recebi uma ajuda e tentei de novo","id":11,"section":"blog","tags":null,"title":"Botão copy, take 1","uri":"https://tiagojsilva.github.io/pt/blog/2021-11-08_copy-button-1/"},{"content":"Como disse num artigo anterior, estava a tentar actualizar-me quanto ao projecto VyOS, que parece ser uma forma económica de testar conceitos de rede, sem ter de pagar Cisco Modeling Labs (a única forma legal de usar sistemas virtuais da Cisco) ou similares.\nE bati de frente no problema do teclado português: não há teclado português. Sim, uma ligação SSH assume o layout do cliente - mas é preciso configurar a rede antes.\nAliás, todo o sistema de configuração de consola do Debian está desactivada ou inoperante. O que é chato porque o Debian usa uma maneira muito própria de configurar a consola.\nTentei testar para trás e para a frente para ver se descobria o ponto de regressão e percebi que:\n Em 1.2 ainda funciona Só que já não é recomendado usar dpkg-reconfigure a partir da shell, agora deve-se usar o comando set console keymap a partir do modo Monitor ($); que acaba por chamar dpkg-reconfigure keyboard-configuration e a seguir reinicia o serviço keyboard-setup.service(o VyOS passou a basear-se em systemd tal como o Debian que lhe serve de base) Em 1.3 e 1.4 não funciona foi adicionado um outro comando, agora em modo Configuration (#), set system option keyboard-layout XX, mas que apenas aceita XX=US, DE, FR, DK, NO, FI. Esse comando funciona, pelo menos para o layout NO (Norway, ou Nordic) que tem muitas teclas em comum com o PT-pt. Hmmm, pergunto-me de onde serão os principais contribuidores do projecto?\nDe caminho, também percebi que a melhor forma de compilar uma versão do VyOS é através da imagem Docker; tentei fazer reverse-engineering do dockerfile como recomendado pela própria página de documentação, mas apesar de ./configure me dizer que as dependências estavam todas correctas, a compilação era interrompida logo no início:\nE: The method driver /usr/lib/apt/methods/https could not be found.\rE: Failed to fetch https://repo.saltproject.io/py3/debian/10/amd64/3003/dists/buster/InRelease\rE: Some index files failed to download. They have been ignored, or old ones used instead.\rP: Begin unmounting filesystems...\rP: Saving caches...\rReading package lists...\rBuilding dependency tree...\rmake: *** [Makefile:32: iso] Error 1\r\nCompilar com a imagem Docker tem sido simples, por isso o acesso aos builds oficiais da versão 1.3 não deverá ser complicado.\nQuanto ao problema do teclado, a minha especulação ingénua leva-me a suspeitar de alguma coisa nos scripts que criam a instalação chroot que depois é colocada no ISO. Esqueceram-se do debconf console-setup? De algum pacote? Falta o ficheiro /bin/setupcon e sem ele o keyboard-setup.service não pode funcionar.\nUma das primeiras coisas que reparei é que a partir da versão 1.3 os caracteres da consola são os nativos, e não a fonte típica das distribuições baseadas em Debian; estará relacionado?\nAbri um thread no fórum (secção Bugs), e vou esperar algum tempo antes de abrir oficialmente um bug no Phabricator. Quanto tempo deverei dar? Duas semanas?\n","description":"Como andam as coisas","id":12,"section":"blog","tags":null,"title":"Actualização VyOS","uri":"https://tiagojsilva.github.io/pt/blog/2021-10-31_vyos2/"},{"content":"LiveCD 1.0-RC2, edição MATE O desenvolvimento da distro Adélie ficou muito tempo parado porque se dedicou a um programa de instalação simultaneamente gráfico e scriptável, chamado Horizon, que desviou muitos recursos do sistema-base. Muita coisa se passava nos bastidores mas exteriormente não havia novas releases.\nNo entanto, uma reorganização recente incutiu-lhes vento nas velas e o site está muito mais bonito, profissional e organizado, as mailing-lists fazem mais sentido, e o progresso parece estar a acelerar.\nNa versão que testei há bastante tempo (1.0-beta4) o Horizon estava completamente inoperacional e tive de usar o método de instalação manual; mesmo assim, esse método é interessante, porque é um bom exemplo de como fazer o bootstrap de um sistema Linux a partir de um repositório de binários, em vez de código-fonte como no Gentoo ou LinuxFromScratch, que demora muito mais.\nPara testar a instalação do sistema, descarreguei o LiveCD para x86_64 baseado em MATE, mas existem opções KDE e LXQt, em arquitecturas ARMv7, ARM64, PPC, PPC64 e x86.\nConfigurei no VirtualBox (6.1.22) uma VM Other Linux (64-bit) com 1GB de RAM, e o resto mantive nos defaults.\nO GRUB do LiveCD não escolhe automaticamente a opção para arrancar, por isso é sempre necessário alguma interação (nem que seja apenas carregar em Enter) para arrancar.\r\nProblemas iniciais Logo no ecrã inicial do MATE se vê a falta de polimento: clicar em Computer dá erro, e as \u0026ldquo;partições\u0026rdquo; proc e tmp deviam estar escondidas\n\r\rIsto é apenas cosmético, mas é um pequeno aperitivo para o que nos espera\u0026hellip;\nPara arrancar com o instalador HorizonUI, Applications \u0026gt; System Tools \u0026gt; System Installation\n\r\rSe não quiser acompanhar-me e quer começar já a instalar, dou-lhe a conclusão:\nFeche o instalador que abriu pelo menu gráfico\nAbra um terminal: Applications \u0026gt; System Tools \u0026gt; MATE Terminal\nMude para a conta root: $ su - ; a palavra-passe é live\n# horizon-ui\r\nTalvez por causa de termos uma aplicação root numa sessão sem permissões, se o monitor for desligado pelo PowerManagement a VM não recupera e pode inclusivamente crashar durante a instalação. Antes de iniciar o instalador colocar System \u0026gt; Preferences \u0026gt; Hardware \u0026gt; Power Management \u0026gt; Display Sleep = Never, e em System \u0026gt; Preferences \u0026gt; Look and Feel \u0026gt; Screensaver, desligar Activate when idle e Lock Screen; depois de a instalação iniciar esses painéis de configuração não podem ser abertos. Ambos são necessários.\nFoi testado em VirtualBox e VMware Workstation/Player\r\nAlém disso, não estão a brincar quando dizem que o acesso à WAN é obrigatório; nenhum dos pacotes é instalado a partir do LiveCD, e tudo é descarregado dos repositórios do Adélie.\r\nA estrutura do instalador é parecida com um wizard:\n\r\rContinue\n Keyboard Layout Load Firmware: o Adélie inclui firmware não-livre para placas gráficas e Wi-Fi Select Installation Disk Select partitioning Type: Erase and Use the Whole Disk ou Manual (escolhi Whole) Networking Setup: Automatic ou Manual - e aqui temos o primeiro showstopper, porque o acesso à rede é considerado obrigatório para a instalação e este passo tem muito por onde dar asneira.\n\r\rEscolhendo Manual, preenchemos os dados do costume para configurar o endereçamento IPv4 e IPv6 e seguimos, mas nada é feito para confirmar se os dados estão correctos; um endereço na gama multicast e uma gateway na classe E são aceites como válidos neste passo do instalador e o funcionamento da rede não é testado (com um ping para o endereço DNS indicado, por exemplo)\n\r\rAutomatic é DHCP, como seria de esperar, e não consegue obter um endereço, nem sequer inicia uma negociação DORA (Review DHCP Log). E isto acontece porque o HorizonUI não está a correr com privilégios de sistema…\n\r\rAbrindo um terminal, rapidamente percebemos que: O próprio LiveCD arranca sem acesso à rede, porque o DCHP tem de ser activado manualmente (# dhcpcd eth0) Pelo caminho, também deu para perceber que o sistema de ajuda man também não está configurado (\u0026ldquo;You\u0026rsquo;re on your own, kid!\u0026quot;) E finalmente, mesmo com o DHCP ligado no sistema, a porta eth0 levantada, com IP atribuído e acesso ao exterior, o HorizonUI continua a falhar no passo da configuração de rede porque não consegue fazer uma negociação DORA.\nA solução é invocar o instalador a partir da conta root (a palavra-passe é live), com # horizon-ui\n\r\rSeguimos com a instalação: Date and Time Settings (se não se tiver usado # horizon-ui, não é possível ajustar a data e hora, só a Timezone) Computer Name Software Selection Standard: instala um sistema KDE completo (mas eu escolhi um LiveCD MATE?) Mobile: KDE como acima, mas com drivers e ajustes mais adequados para portáteis Compact: LXQt muito básico Text-only Custom: a única maneira de instalar o MATE\n\r\r Startup Configuration: se queremos instalar um bootloader (neste caso, sim) Set Root Passphrase User Accounts (podem-se criar várias, mas é preciso configurar pelo menos um utilizador)\n\r\rE no final de tudo, caso não tenha seguido o meu conselho inicial, depara-se com outro problema de falta de permissões (neste caso, para gravar o script de instalação)\n\r\rCaso se tenha activado o instalador como root, a instalação inicia-se:\n\r\rE termina:\n\r\rNo entanto, Finish não reinicia o sistema como prometido. O que até não é mau porque permite fazer Shutdown, tirar o ISO da drive óptica e arrancar com calma. Standard Não só instala mesmo o KDE, como nem sequer honra o esquema de teclado que escolhemos no instalador; eu tinha escolhido pt:\n\r\rMobile É exactamente igual a Standard mas inclui drivers para periféricos mais vulgares em portáteis, como trackpads e gestores de bateria; não tenho como testar essas funcionalidades.\nCompact (LXQt e instalação mínima) Crasha durante a instalação e deixa o sistema incapaz de arrancar; note-se que depois de dar o erro, tentei usar o LiveCD LXQt em vez da versão MATE para ver se ajudava, mas alguma coisa parece estar errada nos repos ou no script da instalação do LXQt e dá erro na configuração das consolefonts (mais uma vez, a instalação no disco rígido depende apenas do script Horizon e dos repos do Adélie, e o LiveCD é apenas um ambiente gráfico para o instalador)\nOpções utilizadas pelo script Horizon:\n\r\rLog de erro:\n\r\rCustom Parece ser a única forma de instalar o MATE ou XFCE.\nA opção Custom tem mais páginas:\n Software Selection: conjuntos de pacotes as instalar; detalhado em baixo para cada caso Software Choices: permite escolher três opções muito particulares: Shell: Dash (compatível POSIX), ou Bash (compatível GNU) Init: S6-linux-init (+ OpenRC) (uma tentativa do mundo MUSL para ter algo similar ao Systemd, que apenas suporta GNU glibc) ou SysV Init Uevent: eudev (estável) vs mdevd (mais dinâmico e moderno mas instável) Foi sempre escolhido Bash, S6 e eudev \r\rO Software Selection foi definido como:\n☐ Desktop Environments\n ☑ KDE Plasma 5 ☑ Documentation\n☑ Internet Software\nA imagem abaixo é de outra tentativa de instalação, com o MATE:\n\r\rDepois de instalar, pendura no primeiro arranque; nenhum VTY responde e o processo de login não se inicia.\nNão tenho imagem porque os screenshots saíam vazios, o que me fez desconfiar de de uma incompatibiliade com a placa gráfica do VirtualBox (VMSVGA)\nDecidi testar a mesma configuração de instalação no VMware Workstation: o arranque chegava ao fim, mas o VTY 7 (onde costuma estar a consola gráfica) só tinha um cursor a piscar; e o comando startx dava not found\nComparando os relatórios das opções do script de instalação (installfile) nas opções \u0026ldquo;Standard\u0026rdquo; e \u0026ldquo;Custom\u0026rdquo;, acabei por perceber que na instalação \u0026ldquo;Custom\u0026rdquo; não eram instalados dois pacotes fundamentais para o ambiente gráfico, o sddm(que gere o login gráfico e a escolha de DE para essa sessão) e o próprio X11\n\r\rFigure 17. Instalação Standard\r\r\r\r\r\rFigure 18. Instalação Custom\r\r\r\rE note-se que o teclado configurado na consola continuava a ser US.\nTestei também a instalação \u0026ldquo;Custom\u0026rdquo; do MATE (como visto acima) e o LXQt, com o mesmo resultado\nConclusão Por muito que simpatize com a distribuição Adélie, usá-la é um exercício de frustração que me lembra os piores tempos do início do Linux (e o meu primeiro Linux foi um RedHat 4.5 - não RHEL, RedHat). Faltam-lhe vários anos de polimento e debugging, aquele trabalho chato que ninguém quer fazer, que as distribuições GNU/Linux que sobreviveram já fizeram (Debian, SuSE, RedHat, Arch), e de que as variantes (Ubuntu, Mint, Manjaro, etc.) se aproveitam.\nNeste momento, creio que o Adélie pode ser criticado por:\n oferecer LiveCDs que não são suficientemente funcionais para testar o sistema (quer dizer, sem acesso à rede sequer?) e que não contêm os pacotes necessários para instalar num sistema sem acesso online aos repos do Adélie; sim, o tamanho do LiveCD iria aumentar imenso, mas é o que um LiveCD é suposto ser. a instalação standard oferecida por cada LiveCD para instalar no disco de sistema não ser a mesma variante de DE do próprio LiveCD e ser sempre o KDE; mais uma vez, o LiveCD deve ser uma representação fidedigna do que vai ser instalado em disco, se bem que também deve oferecer o instalador completo. A instalação Custom que oferece os DEs alternativos ao KDE não terminar a instalação O LiveCD não ter o DHCP activado de raiz, que corresponderia a 90% (número tirado da cartola) das necessidades. não incluir manpages não incluir uma cópia da documentação online dentro do LiveCD o instalador não ser funcional a partir do utilizador da GUI e tudo isto poderia não ser tão grave, se o Adélie fosse uma distro GNU/Linux normal, mas não é. Em resumo, o Adélie é uma distribuição apenas para utilizadores muito avançados e se possível já com experiência em Alpine Linux, que usa o mesmo package manager (APK) e onde se baseia muito do userland do Adélie.\nSubmeti algumas destas informações como Issues no site de desenvolvimento do Adélie, e se descobrirem mais problemas sugiro que os submetam também; os programadores estão já perfeitamente adaptados ao sistema mas precisam que lhe relatem estas questões que aparecem a quem é um utilizador vulgar que experimenta o sistema pela primeira vez.\nO projecto Adélie é pequeno e por isso a comunicação é fácil e descomplicada, de tal forma que consegui entrar em contacto com a equipa que me explicou que esta versão RC2 foi produzida num momento muito complicado da vida do projecto por razões pessoais do programador principal (que compreendo perfeitamente, mas é preocupante que a distro esteja tão dependente de uma só pessoa) e que uma versão RC3 está garantida e a RC4 também é muito provável.\nNa minha opinião ainda nem chegou ao que se costuma chamar de Beta, mas a realidade é que a versão 1.0 é que vai ser a Public Beta, com uma versão 1.5 planeada para estabilização; o que deixa o Adélie Linux muito bem acompanhado, porque o OSX teve exactamente o mesmo padrão de desenvolvimento, mesmo com duas décadas de existência prévia como NextStep/OpenStep - só na versão OSX 10.2 Jaguar é que se tornou possível usá-lo como sistema do dia-a-dia sem praguejar como um carroceiro de 5 em 5 minutos.\n","description":"Onde tento instalar o Adélie e quase fico sem cabelo","id":13,"section":"unixlike","tags":null,"title":"Adelie Linux - Instalação LiveCD","uri":"https://tiagojsilva.github.io/pt/unixlike/musl/2021-09-13_adelie_livecd/"},{"content":"Informação nutricional Não esperem conteúdo vulgar neste site; raramente farei o equivalente ao enésimo artigo sobre como instalar o Postfix ou o Arch Linux, configurar uma NextCloud ou uma VPN: não me interessa, já está feito, não acrescento valor. Só o farei se der de caras com vários HOWTOs que me deixem insatisfeito ao ponto de acreditar que até eu serei capaz de fazer melhor.\nNeste momento estou interessado em explorar o mundo MUSL, as distribuições Linux de uso mais específico, e o init S6; não deveria estar chocado com o estado actual da documentação e desenvolvimento desses sistemas, comparado com os 50 mil artigos sobre como instalar o Ubuntu (contas por baixo), mas estou.\nVou investigar Guix/NixOS, se bem que acho que isso me vai levar ao mundo dos containers, nos quais não me sinto à vontade.\nVou continuar a fazer aquilo que posso fazer com um computador desktop sem acesso à cloud e um curso de Redes e Sistemas sem pinga de conteúdos de cloud, que são aquelas coisas obsoletas da virtualização e sistemas on-premises; quero mesmo aprender a criar sistemas resilientes (tanto storage como compute), mas o High-Availability costuma ser a opção que serve para abrir os cordões à bolsa de quem poderia usar a versão Community.\nPorquê? Sou seduzido pelos terceiros sistemas, que olham para as soluções existentes, vêm as falhas que quem está dentro deles não vê, e propõem uma alternativa; normalmente falha, porque quem está instalado só muito mais tarde se apercebe do mesmo e vários anos depois faz uma pálida imitação das potencialidades do terceiro sistema, e o efeito de rede na informática leva a que haja apenas um sistema dominante e uma alternativa, sem espaço para terceiros sistemas.\nPrefiro a organização ao caos, o passo seguro ao salto no vazio; não sou um empreendedor e nunca vou ficar rico.\nPelo contrário, tenho tido de engolir muitas desilusões\u0026hellip;\nLimitações Como disse já, tenho um outro trabalho fora da área do IT, por isso o meu tempo é limitado. Os meus meios também são limitados, por isso não posso pôr-me a tirar cursos e certificações, e vou recorrer o mais possível a aprendizagens gratuitas, por isso dificilmente terei exemplos da primeira linha da indústria. Mas espero que os princípios aprendidos com os pequenos iluminem o trabalho com os grandes\u0026hellip;\n","description":"Que fazer? Que fazer?","id":14,"section":"blog","tags":null,"title":"Manifesto","uri":"https://tiagojsilva.github.io/pt/blog/2021-10-08_wat-do/"},{"content":"Certificados de servidor e de cliente Agora que temos a nossa IntermediateCA configurada correctamente, podemos começar a utilizá-la para emitir certificados.\nNotas prévias:\n Deve-se usar metade dos bits usados na CA O CN do servidor deve ser o FQDN Um certificado servidor precisa de ter o mesmo FQDN repetido na informação SAN O CN dos clientes pode ser qualquer coisa, não é importante. Devem ser assinados com a IntermediateCA Normalmente têm a duração de um ano (365) e o máximo, desde Julho de 2019, é 824 dias (+1) Comando OpenSSL para certificado servidor: -extensions server_cert Comando OpenSSL para certificado cliente: -extensions usr_cert Só é possível copiar a informação SAN do CSR para o certificado se for colocada a opção copy_extensions = copy ou = all na secção [ca_default] do intermediate/openssl.conf; caso contrário, a informação SAN tem de ser reinserida quando se usa o comando x509 para assinar o CSR, de modo a que chegue ao certificado assinado. Vamos utilizar 4 servidores: offline: tem a RootCA server: tem o CRLDistribution da RootCA, a IntermediateCA e os seus certificados, e o OCSP Responder da IntermediateCA www: vai ter um servidor HTML certificado pela IntermediateCA cliente: vai aceder ao site que está em www Exemplo de certificado servidor: o servidor da PKI Começar por criar uma chave; neste caso deve-se omitir o -aes256 ou a opção -passout para não criar uma palavra-passe.\nSe existir uma palavra-passe, será necessário introduzi-la sempre que o processo do webserver seja iniciado…\n1 2 inter=\u0026#34;/root/ca/inter-ca\u0026#34; openssl genrsa -out $inter/private/server.tjs.lan.key.pem 4096 Generating RSA private key, 4096 bit long modulus (2 primes)\r...............................................................................................................++++\r........................................................++++\re is 65537 (0x010001)\r 1 chmod 400 $inter/private/server.tjs.lan.key.pem Criar informação SAN É especialmente útil quando o FQDN é fictício (por exemplo, não há DNS e precisamos de certificar o IP), mas tornou-se obrigatório porque agora os certificados de Web Server têm de ter o FQDN numa entrada SAN, e tê-lo só no CN já não é suficiente\u0026hellip;\nPara o fazer, temos de criar um ficheiro .CNF extra, contendo apenas essa informação (que será diferente para cada servidor)\n1 2 mkdir $inter/san cat \u0026gt; $inter/san/server.tjs.lan-san.cnf [req]\rdistinguished_name = req_distinguished_name\rreq_extensions = req_ext\rprompt = no\r[req_distinguished_name]\rC = PT\rST = Lisboa\rL = Lisboa\rO = Tiago Joao Silva\rOU = TJS\rCN = server.tjs.lan\r[req_ext]\rsubjectAltName = @alt_names\r[alt_names]\rIP.1 = 192.168.1.70\rDNS.1 = server.tjs.lan DNS.2 = dns.tjs.lan\rDNS.3 = chat.tjs.lan\rDNS.4 = mail.tjs.lan\rCriar o CSR 1 2 3 4 openssl req -config $inter/openssl.cnf \\ -key $inter/private/server.tjs.lan.key.pem \\ -config $inter/san/server.tjs.lan-san.cnf \\ -new -sha512 -out $inter/csr/server.tjs.lan.csr.pem Confirmar que o CSR tem a informação SAN:\n1 2 openssl req -noout -text -in $inter/csr/server.tjs.lan.csr.pem | \\ grep -A 1 \u0026#34;Subject Alternative Name\u0026#34; X509v3 Subject Alternative Name:\rIP Address:192.168.1.70, DNS:server.tjs.lan, DNS:dns.tjs.lan, DNS:chat.tjs.lan, DNS:mail.tjs.lan\r Assinar o CSR Atenção que desde Julho de 2019 o tempo máximo de um certificado Server é 824 dias (+hoje) e os browsers mais recentes rejeitam certificados com mais tempo\u0026hellip;\r Caso não exista copy\\_extensions = copy ou = all no inter-ca/openssl.cnf, será preciso reinserir a informação SAN com as opções -extensions req_ext e -extfile aaa-san.cnf\n1 2 3 4 5 6 7 openssl ca -config $inter/openssl.cnf \\ -extensions server_cert -days 823 -notext -md sha512 \\ -extensions req_ext \\ -extfile $inter/san/server.tjs.lan-san.cnf \\ -passin file:$inter/private/inter-ca.key.pass \\ -in $inter/csr/server.tjs.lan.csr.pem \\ -out $inter/certs/server.tjs.lan.cert.pem Caso exista copy\\_extensions = copy ou = all no inter-ca/openssl.cnf, é mais simples:\n1 2 3 4 5 openssl ca -config $inter/openssl.cnf \\ -extensions server_cert -days 823 -notext -md sha512 \\ -passin file:$inter/private/inter-ca.key.pass \\ -in $inter/csr/server.tjs.lan.csr.pem \\ -out $inter/certs/server.tjs.lan.cert.pem Using configuration from /root/ca/inter-ca/openssl.cnf\rCheck that the request matches the signature\rSignature ok\rCertificate Details:\rSerial Number: 4100 (0x1004)\rValidity\rNot Before: Aug 22 23:54:31 2021 GMT\rNot After : Nov 23 23:54:31 2023 GMT\rSubject:\rcountryName = PT\rstateOrProvinceName = Lisboa\rlocalityName = Lisboa\rorganizationName = Tiago Joao Silva\rorganizationalUnitName = TJS\rcommonName = server.tjs.lan\rX509v3 extensions:\rX509v3 Basic Constraints:\rCA:FALSE\rNetscape Cert Type:\rSSL Server\rNetscape Comment:\rOpenSSL Generated Server Certificate\rX509v3 Subject Key Identifier:\r94:00:E3:58:4F:BA:20:85:F7:9C:DC:47:3C:68:A1:46:8B:78:10:AF\rX509v3 Authority Key Identifier:\rkeyid:E3:75:25:D7:74:08:0B:23:F0:AF:E4:EC:D0:D4:52:CB:5A:3A:10:2E\rDirName:/C=PT/ST=Lisboa/L=Lisboa/O=TiagoJoaoSilva/OU=TJS/CN=ca-tjs-1/[email protected]\rserial:10:03\rX509v3 Key Usage: critical\rDigital Signature, Key Encipherment\rX509v3 Extended Key Usage:\rTLS Web Server Authentication\rAuthority Information Access:\rOCSP - URI:http://ocsp.tjs.lan:7888\rCertificate is to be certified until Nov 23 23:54:31 2023 GMT (823 days)\rSign the certificate? [y/n]:Y\r1 out of 1 certificate requests certified, commit? [y/n]Y\rWrite out database with 1 new entries\rData Base Updated\r 1 chmod 444 $inter/certs/server.tjs.lan.cert.pem Verificar a ChainOfTrust com o certificado CA-CHAIN 1 2 openssl verify -CAfile $inter/certs/inter-ca_chain.cert.pem \\ $inter/certs/server.tjs.lan.cert.pem /root/ca/inter-ca/certs/server.tjs.lan.cert.pem: OK\r Criar um certificado Chain/Bundle para o servidor Concatenamos o certificado do servidor com o certificado CA-CHAIN:\n1 2 cat $inter/certs/{server.tjs.lan.cert.pem,inter-ca_chain.cert.pem} \u0026gt; \\ $inter/certs/server.tjs.lan.cert_chain.pem Testes da CA Configurar um webserver Precisamos de criar um certificado novo para o webserver. O IP será 192.168.1.77 e o hostname será www\n1 2 3 4 inter=\u0026#34;/root/ca/inter-ca\u0026#34; openssl genrsa -out $inter/private/www.tjs.lan.key.pem 4096 chmod 400 $inter/private/www.tjs.lan.key.pem cat \u0026gt; $inter/san/www.tjs.lan-san.cnf [req]\rdistinguished_name = req_distinguished_name\rreq_extensions = req_ext\rprompt = no\r[req_distinguished_name]\rC = PT\rST = Lisboa\rL = Lisboa\rO = Tiago Joao Silva\rOU = TJS\rCN = www.tjs.lan\r[req_ext]\rsubjectAltName = @alt_names\r[alt_names]\rIP.1 = 192.168.1.77\rDNS.1 = www.tjs.lan 1 2 3 4 5 6 7 8 9 10 11 12 13 openssl req -config $inter/openssl.cnf \\ -key $inter/private/www.tjs.lan.key.pem \\ -config $inter/san/www.tjs.lan-san.cnf \\ -new -sha512 -out $inter/csr/www.tjs.lan.csr.pem openssl ca -config $inter/openssl.cnf \\ -extensions server_cert -days 823 -notext -md sha512 \\ -passin file:$inter/private/inter-ca.key.pass \\ -in $inter/csr/www.tjs.lan.csr.pem \\ -out $inter/certs/www.tjs.lan.cert.pem chmod 444 $inter/certs/www.tjs.lan.cert.pem cat $inter/certs/{www.tjs.lan.cert.pem,inter-ca_chain.cert.pem} \u0026gt; \\ $inter/certs/www.tjs.lan.cert_chain.pem chmod 444 $inter/certs/www.tjs.lan.cert_chain.pem Para testar, instalamos um novo sistema Debian 11 sem GUI.\nEditamos a configuração da interface desejada (enp0s3 é a interface primária no VirtualBox; no VMware é ens33)\n1 vim /etc/network/interfaces iface enp0s3 inet static\raddress 192.168.1.77/24\rgateway 192.168.1.1\r1 hostnamectl set-hostname www.tjs.lan Editar o ficheiro /etc/hosts; na segunda linha, mudar para:\n127.0.1.1\twww.tjs.lan\twww\rVerificar:\n1 for opt in {s,d,f}; do hostname -$opt ; done www\rtjs.lan\rwww.tjs.lan\r\nInstalamos o servidor Nginx\n1 apt install nginx -y Verificamos se serve a página definida por defeito\n1 wget localhost:80 -O- \u0026lt;!DOCTYPE html\u0026gt;\r\u0026lt;html\u0026gt;\r\u0026lt;head\u0026gt;\r\u0026lt;title\u0026gt;Welcome to nginx!\u0026lt;/title\u0026gt;\r\u0026lt;style\u0026gt;\rbody {\rwidth: 35em;\rmargin: 0 auto;\rfont-family: Tahoma, Verdana, Arial, sans-serif;\r}\r\u0026lt;/style\u0026gt;\r\u0026lt;/head\u0026gt;\r\u0026lt;body\u0026gt;\r\u0026lt;h1\u0026gt;Welcome to nginx!\u0026lt;/h1\u0026gt;\r\u0026lt;p\u0026gt;If you see this page, the nginx web server is successfully installed and\rworking. Further configuration is required.\u0026lt;/p\u0026gt;\r\u0026lt;p\u0026gt;For online documentation and support please refer to\r\u0026lt;a href=\u0026quot;http://nginx.org/\u0026quot;\u0026gt;nginx.org\u0026lt;/a\u0026gt;.\u0026lt;br\u0026gt;/\u0026gt;\rCommercial support is available at\r\u0026lt;a href=\u0026quot;http://nginx.com/\u0026quot;\u0026gt;nginx.com\u0026lt;/a\u0026gt;.\u0026lt;/p\u0026gt;\r\u0026lt;p\u0026gt;\u0026lt;em\u0026gt;Thank you for using nginx.\u0026lt;/em\u0026gt;\u0026lt;/p\u0026gt;\r\u0026lt;/body\u0026gt;\r\u0026lt;/html\u0026gt;\rTrazer o certificado CHAIN do servidor para o webserver e colocá-lo num caminho que não seja afectado por updates nos certificados, como uma pasta local-certs em /etc/ssl/\n1 2 3 mkdir /etc/ssl/local-certs cp www.tjs.lan.cert_chain.pem /etc/ssl/local-certs/ chmod 444 /etc/ssl/local-certs/www.tjs.lan.cert_chain.pem Trazer também a chave privada associada ao certificado do webserver e colocá-la em /etc/ssl/private/\n1 2 cp www.tjs.lan.key.pem /etc/ssl/private/ chmod 400 /etc/ssl/private/www.tjs.lan.key.pem Mudamos a configuração do Nginx para redirecionar automaticamente pedidos feitos à porta 80 (HTTP) para a porta 443 (HTTPS), e configuramos o certificado e a chave do webserver\n1 2 cp /etc/nginx/sites-available/default{,.orig} vim /etc/nginx/sites-available/default A partir da linha 21:\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 server { # redirect all HTTP to HTTPS listen 80; listen [::]:80; server_name\twww.tjs.lan; return 301 https://www.tjs.lan$request_uri; } server { listen 443 ssl; listen [::]:443 ssl; server_name www.tjs.lan; ssl_certificate /etc/ssl/local-certs/www.tjs.lan.cert_chain.pem; ssl_certificate_key /etc/ssl/private/www.tjs.lan.key.pem; Note-se que não se fechou a chaveta do site SSL, porque a configuração default continua por mais umas linhas e fecha mais abaixo.\n1 2 systemctl restart nginx wget localhost:80 -O- --2021-08-24 21:45:45-- http://localhost/\rResolving localhost (localhost)... ::1, 127.0.0.1\rConnecting to localhost (localhost)|::1|:80... connected.\rHTTP request sent, awaiting response... 301 Moved Permanently\rLocation: https://www.tjs.lan/ [following]\r--2021-08-24 21:45:45-- https://www.tjs.lan/\rResolving www.tjs.lan (www.tjs.lan)... 127.0.1.1\rConnecting to www.tjs.lan (www.tjs.lan)|127.0.1.1|:443... connected.\rERROR: The certificate of ‘www.tjs.lan’ is not trusted.\rERROR: The certificate of ‘www.tjs.lan’ doesn't have a known issuer.\r\nA redirecção está a acontecer, mas o wget local a www.tjs.lan não confia no certificado do servidor porque não conhece o certificado da RootCA.\r\nAbrimos as portas 80 e 443 da firewall\n1 2 ufw allow 80 ufw allow 443 Testar o webserver Configuramos um cliente gráfico (por exemplo, um Debian 11 com MATE).\nResolução de nomes Como não temos um servidor DNS com a zona tjs.lan nem com todos estes sistemas configurados, vamos adicionar o seguinte ao /etc/hosts dos três sistemas (server, www e cliente)\n# printf \u0026quot;\\\r#tjs.lan\\n\\\r192.168.1.70\tserver.tjs.lan server\\n\\\r192.168.1.70\tocsp.tjs.lan\tocsp\\n\\\r192.168.1.77\twww.tjs.lan www \\n\u0026quot; \\\r\u0026gt;\u0026gt; /etc/hosts\rInstalar o certificado Root no cliente final Importamos o certificado da RootCA para a home do utilizador actual do cliente.\nAbrimos o Firefox, Preferences, Privacy and Security, View Certificates…\nOu (about:preferences#privacy)\n\r\rImport…\n\r\rEscolhemos o certificado da RootCA, Open\n\r\r✓ Trust this CA to identify websites\n✓ Trust this CA to identify email users (opcional)\nOK\n\r\rClicando em View, podemos ver detalhes do certificado\n\r\rTemos a Authority importada, OK\n\r\rTestar o site Abrimos http://www.tjs.lan (pode ser necessário dizer ao Firefox que queremos mesmo ir para esse endereço), e temos uma ligação SSL protegida com o nosso certificado:\n\r\rConfigurar OCSP Stapling Fonte: https://www.digitalocean.com/community/tutorials/how-to-configure-ocsp-stapling-on-apache-and-nginx\nTrazemos para o webserver o certificado da RootCA\n1 cp ca.cert.pem /etc/ssl/local-certs/ Adicionamos as linhas seguintes ao site activo no Nginx (estávamos a usar /etc/nginx/sites-available/default), por baixo de ssl_certificate_key:\n1 2 3 ssl_stapling on; ssl_stapling_verify on; ssl_trusted_certificate /etc/ssl/local-certs/ca.cert.pem; Testar A partir do cliente, testar o processo de OCSP Stapling com o comando seguinte, não esquecendo de indicar o certificado da CA (que deixámos na homefolder do utilizador quando o importamos para dentro do Firefox); se o apagou, é necessário trazê-lo de novo para o cliente para que possa ser usado agora:\n1 echo QUIT | sudo openssl s_client -connect www.tjs.lan:443 -CAfile ~/ca.cert.pem -status \r\rExpandir\r\rCONNECTED(00000003)\rdepth=2 C = PT, ST = Lisboa, L = Lisboa, O = TiagoJoaoSilva, OU = TJS, CN = ca-tjs-1, emailAddress = [email protected]\rverify return:1\rdepth=1 C = PT, ST = Lisboa, O = TiagoJoaoSilva, OU = TJS, CN = inter-ca-tjs-2, emailAddress = [email protected]\rverify return:1\rdepth=0 C = PT, ST = Lisboa, L = Lisboa, O = Tiago Joao Silva, OU = TJS, CN = www.tjs.lan\rverify return:1\rOCSP response: ======================================\rOCSP Response Data:\rOCSP Response Status: successful (0x0)\rResponse Type: Basic OCSP Response\rVersion: 1 (0x0)\rResponder Id: C = PT, ST = Lisboa, L = Lisboa, O = Tiago Joao Silva, OU = TJS, CN = ocsp.tjs.lan\rProduced At: Aug 24 22:18:56 2021 GMT\rResponses:\rCertificate ID:\rHash Algorithm: sha1\rIssuer Name Hash: AE59C598DC56A005EA5239AE471093B7924F5018\rIssuer Key Hash: E37525D774080B23F0AFE4ECD0D452CB5A3A102E\rSerial Number: 1007\rCert Status: good\rThis Update: Aug 24 22:18:56 2021 GMT\r[…]\rCertificate:\rData:\rVersion: 3 (0x2)\rSerial Number: 4099 (0x1003)\rSignature Algorithm: sha512WithRSAEncryption\rIssuer: C=PT, ST=Lisboa, O=TiagoJoaoSilva, OU=TJS, CN=inter-ca-tjs-2/[email protected]\rValidity\rNot Before: Aug 22 22:53:56 2021 GMT\rNot After : Nov 23 22:53:56 2023 GMT\rSubject: C=PT, ST=Lisboa, L=Lisboa, O=Tiago Joao Silva, OU=TJS, CN=ocsp.tjs.lan\rSubject Public Key Info:\rPublic Key Algorithm: rsaEncryption\rRSA Public-Key: (4096 bit)\r[…]\r---\rCertificate chain\r0 s:C = PT, ST = Lisboa, L = Lisboa, O = Tiago Joao Silva, OU = TJS, CN = www.tjs.lan\ri:C = PT, ST = Lisboa, O = TiagoJoaoSilva, OU = TJS, CN = inter-ca-tjs-2, emailAddress = [email protected]\r1 s:C = PT, ST = Lisboa, O = TiagoJoaoSilva, OU = TJS, CN = inter-ca-tjs-2, emailAddress = [email protected]\ri:C = PT, ST = Lisboa, L = Lisboa, O = TiagoJoaoSilva, OU = TJS, CN = ca-tjs-1, emailAddress = [email protected]\r2 s:C = PT, ST = Lisboa, L = Lisboa, O = TiagoJoaoSilva, OU = TJS, CN = ca-tjs-1, emailAddress = [email protected]\ri:C = PT, ST = Lisboa, L = Lisboa, O = TiagoJoaoSilva, OU = TJS, CN = ca-tjs-1, emailAddress = [email protected]\r---\rServer certificate\r-----BEGIN CERTIFICATE-----\r[…]\rsubject=C = PT, ST = Lisboa, L = Lisboa, O = Tiago Joao Silva, OU = TJS, CN = www.tjs.lan\rissuer=C = PT, ST = Lisboa, O = TiagoJoaoSilva, OU = TJS, CN = inter-ca-tjs-2, emailAddress = [email protected]\r---\rNo client certificate CA names sent\rPeer signing digest: SHA256\rPeer signature type: RSA-PSS\rServer Temp Key: X25519, 253 bits\r---\rSSL handshake has read 11091 bytes and written 392 bytes\rVerification: OK\r---\rNew, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384\rServer public key is 4096 bit\rSecure Renegotiation IS NOT supported\rCompression: NONE\rExpansion: NONE\rNo ALPN negotiated\rEarly data was not sent\rVerify return code: 0 (ok)\r---\r---\rPost-Handshake New Session Ticket arrived:\rSSL-Session:\rProtocol : TLSv1.3\rCipher : TLS_AES_256_GCM_SHA384\rSession-ID: 18DD0A571D36D69EC35D46FBC8F28711DDEED91000F1F595897B061640DD86E9\rSession-ID-ctx: Resumption PSK: 2B54CFDFF0170EDC5F77AE462A18AAA4DC7CC3CED7B21E2F6B97454A0AB65725AE63DDA084379C793DADF63983606283\rPSK identity: None\rPSK identity hint: None\rSRP username: None\rTLS session ticket lifetime hint: 300 (seconds)\rTLS session ticket:\r0000 - 28 c6 3d 71 b3 5c 60 1f-a8 7d 5f f7 26 3c cd f5 (.=q.\\`..}_.\u0026\r Revogação com OSCP Responder O Stapling costuma ter uma validade de 7 dias, em que o server guarda a resposta e já não contacta de novo o OCSP para obter a confirmação da validade do certificado, enviando directamente a resposta anterior ao cliente.\nIsto significa que se revogarmos o certificado agora, só daqui a 7 dias é que o cliente recusará o certificado do webserver.\nA não ser, claro, que o webserver seja reiniciado para perder a memória da resposta OCSP\u0026hellip; Vamos revogar o certificado do webserver:\n1 2 3 4 5 6 stamp=$(date +%F_%T) mv /root/ca/inter-ca/certs/www.tjs.lan.cert.pem{,-revoked_$stamp} openssl ca -config /root/ca/inter-ca/openssl.cnf \\ -passin file:/root/ca/inter-ca/private/inter-ca.key.pass \\ -revoke /root/ca/inter-ca/certs/www.tjs.lan.cert.pem-revoked_$stamp \\ -crl_reason superseded Using configuration from /root/ca/inter-ca/openssl.cnf\rRevoking Certificate 1007.\rData Base Updated\r Reiniciamos o serviço do ocsp, para que este fique actualizado com o novo CRL\n1 systemctl restart ocsp-responder_inter-ca.service Reiniciamos o serviço do nginx em www, para perder a cache do OCSP Stapling\n1 systemctl restart nginx 1 echo QUIT | sudo openssl s_client -connect www.tjs.lan:443 -CAfile ~/ca.cert.pem -status CONNECTED(00000003)\rdepth=2 C = PT, ST = Lisboa, L = Lisboa, O = TiagoJoaoSilva, OU = TJS, CN = ca-tjs-1, emailAddress = [email protected]\rverify return:1\rdepth=1 C = PT, ST = Lisboa, O = TiagoJoaoSilva, OU = TJS, CN = inter-ca-tjs-2, emailAddress = [email protected]\rverify return:1\rdepth=0 C = PT, ST = Lisboa, L = Lisboa, O = Tiago Joao Silva, OU = TJS, CN = www.tjs.lan\rverify return:1\rOCSP response: no response sent\r Confirmar que os clientes vêem o certificado como revogado E quando tentamos aceder a www.tjs.lan pelo Firefox, somos informados que o certificado foi revogado:\n\r\rCriar um novo certificado para substituir o revogado Caso esteja a seguir o tutorial por ordem, é melhor emitir um certificado novo para www.tjs.lan antes de prosseguir. Não esquecer que uma vez que a chave não foi comprometida nem a informação do servidor www mudou, o seu CSR continua válido, e por isso só é necessário repetir os passos da assinatura do CSR em diante. Caso a chave privada tivesse sido comprometida, seria necessário emitir um novo certificado para www a partir do zero.\r\nDepois é preciso fazê-lo chegar ao local adequado em www.tjs.lan, reiniciar o nginx, e testar de novo o acesso ao webserver no cliente:\n\r\rRevogar a IntermediateCA Para revogarmos a IntermediateCA (vamos supor que alguém deixou a chave privada da IntermediateCA num repositório público do GitHub), temos de nos deslocar à RootCA, que está offline, e seguir os passos descritos na secção correspondente:\n1 2 3 4 5 6 stamp=$(date +%F_%T) mv /root/ca/inter-ca/certs/inter-ca.cert.pem{,-revoked_$stamp} openssl ca -config /root/ca/openssl.cnf \\ -passin file:/root/ca/private/ca.key.pass \\ -revoke /root/ca/inter-ca/certs/inter-ca.cert.pem-revoked_$stamp \\ -crl_reason keyCompromise Using configuration from /root/ca/openssl.cnf\rRevoking Certificate 1003.\rData Base Updated\r A seguir actualizamos o CRL e convertêmo-lo para DER, seguindo os passos da secção correspondente:\n1 2 3 4 5 6 openssl ca -config /root/ca/openssl.cnf -gencrl \\ -passin file:/root/ca/private/ca.key.pass \\ -keyfile /root/ca/private/ca.key.pem -cert /root/ca/certs/ca.cert.pem \\ -out /root/ca/crl/ca.crl.pem openssl crl -inform PEM -in /root/ca/crl/ca.crl.pem \\ -outform DER -out /root/ca/crl/root-ca.crl Podemos ver que o CRL alterado tem uma entrada nova:\n1 openssl crl -inform DER -text -noout -in /root/ca/crl/root-ca.crl Certificate Revocation List (CRL):\rVersion 2 (0x1)\rSignature Algorithm: sha512WithRSAEncryption\rIssuer: C = PT, ST = Lisboa, L = Lisboa, O = TiagoJoaoSilva, OU = TJS, CN = ca-tjs-1, emailAddress = [email protected]\rLast Update: Aug 25 20:50:52 2021 GMT\rNext Update: Sep 14 20:50:52 2022 GMT\rCRL extensions:\rX509v3 Authority Key Identifier:\rkeyid:01:F2:CC:54:E0:F2:58:AC:E2:14:8E:2B:DB:6D:B6:FF:5C:25:41:A0\rX509v3 CRL Number:\r4098\rRevoked Certificates:\rSerial Number: 1001\rRevocation Date: Aug 13 22:11:25 2021 GMT\rCRL entry extensions:\rX509v3 CRL Reason Code:\rUnspecified\rSerial Number: 1002\rRevocation Date: Aug 13 23:41:51 2021 GMT\rCRL entry extensions:\rX509v3 CRL Reason Code:\rSuperseded\rSerial Number: 1003\rRevocation Date: Aug 25 20:45:54 2021 GMT\rCRL entry extensions:\rX509v3 CRL Reason Code:\rKey Compromise\r Trazer o CRL actualizado do offline para online Usando um meio seguro que não quebre o airgapping do sistema da RootCA, levamos este ficheiro DER ao servidor que aloja a distribuição do CRL da RootCA:\n1 2 cp root-ca.crl /var/www/crl systemctl restart lighttpd.service Para eliminar a cache do OCSP Stapling, também é necessário reiniciar o webserver se queremos que a revogação seja imediatamente reconhecida em vez de esperarmos 7 dias:\n1 systemctl restart nginx.service Testar a revogação da IntermediateCA Em browsers modernos (falha) O site continua a ser reconhecido como seguro no Firefox, porque aparentemente os browsers não se dão ao trabalho de verificar a cadeia inteira de certificados (nem mesmo por OCSP), confiando apenas na lista interna de RootCAs e em CRLs internos distribuídos com as actualizações.\nA única excepção é o velhinho Internet Explorer, paz à sua alma, que vamos testar já a seguir.\nhttps://news.netcraft.com/archives/2013/05/13/how-certificate-revocation-doesnt-work-in-practice.html\nE não consigo encontrar um comando openssl verify que me consiga indicar que a cadeia do certificado www.tjs.lan.cert_chain.pem está quebrada pela revogação da IntermediateCA\n(https://stackoverflow.com/questions/25482199/verify-a-certificate-chain-using-openssl-verify)\nO uso de PKI em browsers parece que utiliza muitos atalhos\u0026hellip;\nEm Internet Explorer Para testar com Internet Explorer, precisamos de um cliente Windows, por isso provisionei uma VM Windows 7.\nImportar o certificado da RootCA Trazer o certificado da RootCA para o cliente Windows e salvar como ca.cert.cer)\n.CER é a extensão típica do Windows para ficheiros PEM (Base64)\r\nWin+R, certmgr.msc\nSeleccionar Trusted Root Certification Authorities/Certificates\nAll Tasks \u0026gt; Import\u0026hellip;\n\r\rEscolher o certificado (Browse\u0026hellip;)\n\r\rConfirmar que queremos instalar em Trusted Root\n\r\rYes\n\r\rE está instalado\n\r\rFicheiro hosts Agora precisamos de colocar a mesma informação no ficheiro hosts para resolver a falta de DNS.\nAbrir o Notepad com permissões de administrador (clique direito em cima do Notepad, Run as administrator)\n\r\rAbrir o ficheiro %SystemRoot%\\System32\\drivers\\etc\\hosts\nColar:\n#tjs.lan\r192.168.1.70\tserver.tjs.lan server\r192.168.1.70\tocsp.tjs.lan\tocsp\r192.168.1.77\twww.tjs.lan www\r\r\r\rSalvar o ficheiro e sair do Notepad.\nAbrir o site no IE Agora podemos testar se o IE reconhece que a Inter-CA que assinou o certificado do nosso site foi revogada:\nE o resultado é sim, o Internet Explorer consulta e respeita uma PKI interna a uma empresa, em vez de se limitar àquilo que já sabe sobre a PKI pública utilizada na Internet.\n\r\r","description":"PKI em OpenSSL: parte 3 (Servidores e Clientes)","id":15,"section":"sec","tags":null,"title":"PKI OpenSSL (pt 3)","uri":"https://tiagojsilva.github.io/pt/sec/pki/opensslpki_3/"},{"content":"Como muitos outros projectos de software livre e aberto, também o VyOS decidiu que ia continuar a ser livre, mas deixaria de ser grátis. Para convencer os utilizadores empresariais a abrirem os cordões à bolsa, decidiram que os binários compilados e distribuídos para instalação sob a forma de uma imagem ISO apenas estariam disponíveis ao público em versões instáveis, correspondentes, grosso modo, a um nightly build. A última versão estável pré-compilada é a 1.1-8, e a versão mais recente pode estar em vários tipos de estado, consoante esteja no início ou no fim do processo de release.\nÉ uma tendência cada vez mais forte, cujo exemplo mais polémico foi a passagem da distribuição CentOS de downstream do RHEL (estável) para upstream, servindo agora de teste beta (logo instável) do point-upgrade seguinte do RHEL.\nQueres à pála? Pelo menos paga reportando bugs\u0026hellip;\r\nNo entanto, nos próximos dias haverá uma oportunidade de ouro para obter uma versão do VyOS bastante estável, porque a versão 1.3 (equuleus) está em Release Preview (neste momento ainda a primeira, 1.3-epa1).\nPoderá haver mais Previews, mas as diferenças deverão ser mínimas.\nFelizmente, a licença original do VyOS obriga a manter o acesso livre ao código-fonte, e o projecto inclui instruções, que parecem bastante simples, para compilar a versão estável LTS directamente do repositório de código-fonte.\nMais novidades em breve\u0026hellip;\r\nHá pelo menos ano e meio que estragaram a configuração de esquema de teclado e é impossível configurar um teclado português.\nNada funciona: locale set-keymap, dpkg-reconfigure console-data, dpkg-reconfigure keyboard-configuration. Corre sem erros, mas é olímpicamente ignorado e o esquema mantém-se sempre como ANSI en-US.\nA \u0026ldquo;solução\u0026rdquo;, se é que se pode chamar, é configurar uma interface de rede, ligar o serviço SSH e aceder por SSH a partir de um cliente com o teclado bem configurado.\nOpen-source: sempre a falhar no mais básico.\r\n","description":"Não perca esta oportunidade!","id":16,"section":"blog","tags":null,"title":"Olh'ó VyOS fresquinhoo!!!","uri":"https://tiagojsilva.github.io/pt/blog/2021-10-07_getchorvyoshear/"},{"content":"O workflow que uso para produzir os artigos é uma jiga-joga que inventei p\u0026rsquo;raqui. Para variar\u0026hellip;\nComeço por escrever em Microsoft Word, porque estou habituado assim e tenho algum conteúdo em Word que quero converter para o site.\nDepois converto o DOCX para MarkDown com o Pandoc\npandoc -f docx -t gfm --wrap=none --extract-media images\\\u0026lt;secção\u0026gt;\\\u0026lt;artigo\u0026gt; -o artigo.md .\\artigo.docx\rAs vantagens de usar o Pandoc são muitas:\n Converte a formatação Negrito, Itálico e Negrito-Itálico nos equivalentes MarkDown Converte links nos equivalentes MarkDown sem \u0026ldquo;escapar\u0026rdquo; os caracteres dos links que o MarkDown não permite. Reproduz a estrutura de estilos (Título 1, Tìtulo 2) nos Headings do MarkDown e no índice (TOC) do artigo Extrai as imagens para uma pasta e coloca o link para a imagem inline, e inclui a informação alt text que seja colocada nas propriedades da imagem dentro do Word, mas não uso. Abro o .MD no Notepad++ para:\n Retirar os parágrafos duplicados que ficam entre cada linha Busca e substituição (shortcodes, caminhos com / em vez de \\, e outros) Crio o artigo dentro do Hugo:\nhugo new content\\pt\\\u0026lt;secção\u0026gt;\\\u0026lt;artigo\u0026gt;.md\rEdito o FrontMatter e copio o texto do Notepad++ para o novo .MD\nCopio as imagens para \u0026lt;site\u0026gt;/static/images/\u0026lt;secção\u0026gt;/\u0026lt;artigo\u0026gt;/\nLigo o site Hugo local:\nhugo server --buildFuture\rE faço os ajustes necessários no VSCode, onde tenho um workspace para o site.\nA tradução para Inglês é feita com uma extensão VSCode, funkyremi.VScode Google Translate, onde pus nas preferências que quero traduzir sempre de Português para Inglês. Copio o ficheiro \u0026lt;artigo\u0026gt;.MD para o local equivalente debaixo de \u0026lt;site\u0026gt;/content/en/, abro-o lado-a -lado com a versão em Português (de preferência no segundo monitor, porque é fácil fazer confusão entre os dois a meio da tradução), selecciono o texto que quero traduzir evitando termos técnicos, Alt-Shift-T e já está; não é perfeito e há muita afinação a fazer depois, mas poupa muito trabalho.\n","description":"Produzir conteúdo já não é fácil, mas reinventar a roda é que não...","id":17,"section":"blog","tags":null,"title":"Workflow dos artigos","uri":"https://tiagojsilva.github.io/pt/blog/2021-09-22_workflow/"},{"content":"De início não estava a pensar em permitir comentários, mas como o ser humano é um animal social, fui ver se podia configurar um sistema sem ter de inventar muito.\nDe início considerei o Disq.us, que vem do origem com o Hugo, mas tem muitas desvantagens.\nO Zdoc tem pré-configurado o Utteranc.es, que tem as vantagens de exigir um registo GitHub (gente que se porta bem, espero eu) e de ficar num repo.\nCriei um repo público só para os comentários e instalei a app Utteranc.es no repo.\nConfiguração Bastou ir ao config/params.toml, ligar o sistema de comentários e configurar as credenciais:\n1 2 3 4 5 enableComment = true [utterances] # https://utteranc.es/ owner = \u0026#34;\u0026lt;GitHub Username\u0026gt;\u0026#34; # Your GitHub ID repo = \u0026#34;\u0026lt;utteranc.es repo name\u0026gt;\u0026#34; # The repo to store comments E o Zdoc acrescenta automaticamente um campo de comentários no final dos artigos.\nBlog Mas nos posts do Blog, não. Para isso, é necessaário editar manualmente o partial, acrescentando {{ partial \u0026quot;comments/comments.html\u0026quot; . }} na secção correcta:\n1 2 3 4 5 6 7 8 9 \u0026lt;article id=\u0026#34;list-main\u0026#34; class=\u0026#34;{{ if $wideViewAsDefault }}lm{{ else }}m{{ end }}\u0026#34; data-dir=\u0026#34;{{ $.Param \u0026#34;languagedir\u0026#34; | default \u0026#34;ltr\u0026#34; }}\u0026#34;\u0026gt; {{ if $.Param \u0026#34;enableBlogBreadcrumb\u0026#34; }} {{ partial \u0026#34;main/component/breadcrumb.html\u0026#34; . }} {{ end }} {{ partial \u0026#34;main/sections/list-main.html\u0026#34; . }} {{ partial \u0026#34;main/component/pagination-single.html\u0026#34; . }} {{ partial \u0026#34;comments/comments.html\u0026#34; . }} \u0026lt;/article\u0026gt; E já está.\nInfelizmente, como se baseia em GitHub Issues e não em GitHub Discussions não há pré-moderação. Por isso portem-se bem.\n","description":"Vox populi","id":18,"section":"blog","tags":null,"title":"Comentários nos artigos","uri":"https://tiagojsilva.github.io/pt/blog/2021-09-15_site-comments/"},{"content":"O Zdoc tem uma secção \u0026ldquo;Updates\u0026rdquo; (que eu traduzi para \u0026ldquo;Histórico\u0026rdquo;), mas os artigos dentro dela eram criados à mão. Como sou preguiçoso (a pessoa mais preguiçosa do mundo) e não gosto de fazer coisas à mão quando podem ser automatizadas, tentei arranjar maneira de produzir um site index com menos esforço.\nNo Wordpress e outras plataformas dinâmicas é facílimo, mas num site estático como o Hugo, as soluções envolviam plugins, NPM, Node.js, tudo coisas com as quais não queria interagir (agora).\nMas felizmente, há uma possibilidade de fingir essa funcionalidade usando uma função interna do Hugo, que são as Taxonomies. Felizmente, não as uso para mais nada, mas não sei se fazer isto impede outros usos para as Taxonomies.\nAcrescenta-se o seguinte ao config.toml\n1 2 3 4 5 6 7 [taxonomies] year = \u0026#34;year\u0026#34; month = \u0026#34;month\u0026#34; [permalinks] year = \u0026#34;updates/:slug/\u0026#34; month = \u0026#34;updates/:slug/\u0026#34; Fazer isto acrescenta automaticamente páginas site/updates/ano e páginas site/updates/ano/mês, preenchidas com o :slug de todas as páginas que tenham esses valores nas variáveis year: e month: que agora podemos começar a pôr no Frontmatter de cada página, desta forma:\n1 2 3 4 5 6 7 ---title:\u0026#34;Secção Histórico\u0026#34;description:\u0026#34;Mais um hack...\u0026#34;[...]year:[\u0026#34;2021\u0026#34;]month:[\u0026#34;2021/09\u0026#34;]--- Para gerar estes campos automaticamente quando se cria um artigo ou post novos com hugo new, acrescentou-se o seguinte ao Frontmatter dos archetypes (archetypes/blog/post.md e archetypes/default.md):\nyear: [\u0026quot;{{ now.Format \u0026quot;2006\u0026quot; }}\u0026quot;]\rmonth: [\u0026quot;{{ now.Format \u0026quot;2006/01\u0026quot; }}\u0026quot;]\rE para que estas páginas não tenham o formato do blog (que é a configuração por defeito para Taxonomies), fez-se a seguinte mudança no layouts/_default/taxonomy.html\n1 2 3 4 5 6 7 \u0026lt;div class=\u0026#34;top\u0026#34;\u0026gt; \u0026lt;header class=\u0026#34;header__wrapper bgcolor__header\u0026#34;\u0026gt; {{ with .Site.GetPage \u0026#34;section\u0026#34; \u0026#34;blog\u0026#34; }} {{ if eq .Params.blogHeaderType \u0026#34;img\u0026#34; }} \u0026lt;!-- {{ partial \u0026#34;header/blog-header.html\u0026#34; . }} --\u0026gt; {{ partial \u0026#34;header/custom-header.html\u0026#34; . }} {{ else }} O layouts/partials/header/custom-header.html do Zdoc está vazio; se quiser alguma coisa no header pode editá-lo ou fazer um novo. No entanto, tal como está a configuração neste momento, o que escolher será aplicado a todas as Taxonomies\nDepois bastou fazer links estáticos no content/\u0026lt;lang\u0026gt;/updates/_index.md para as páginas automaticamente geradas:\n1 2 3 Actualizações [2021](/pt/updates/2021) - [Agosto](/pt/updates/2021/08) Sim, ainda tenho de criar estes links à mão, mas as páginas atras dos links são criadas sem que eu tenha de colocar cada post lá um a um.\nProgresso!\nFontes:\nhttps://discourse.gohugo.io/t/how-to-generate-chronological-blog-archives-in-hugo/13491/5\nhttps://discourse.gohugo.io/t/strugling-with-chronological-blog-archive/31963/2\nhttps://gohugo.io/templates/lists/\n","description":"Mais um hack...","id":19,"section":"blog","tags":null,"title":"Secção Histórico","uri":"https://tiagojsilva.github.io/pt/blog/2021-09-04_updates-page/"},{"content":"Uma coisa que me está a irritar no Zdoc é o espaço que se perde com as barras laterais, deixando pouco espaço ao centro para os artigos e tornando as imagens pequenas (sobretudo quando são screenshots widescreen).\nNão percebo o suficiente de HTML para tentar alargar a coluna central (aparte a seta pré-definida acima que alarga a coluna do artigo mas esconde o TOC), mas posso tentar que as imagens sejam mostradas em maior tamanho quando se clica nelas.\nJá agora, porque é que existe uma preferência wideViewAsDefault = true no config/params.toml mas não existe uma só para o Blog? O Blog não tem uma barra lateral à esquerda, por isso é para esse lado que a Wide View expande, deixando a TOC em paz no Blog. Wide View no Blog seria de graça\u0026hellip;\nPortanto fui a este link e configurei a biblioteca Lightbox.\nDescarreguei a última release e coloquei:\n lightbox.css em static/css/ lightbox.jsem static/js/\nAcrescentei no fim deste ficheiro: 1 2 3 // ========= lightbox \u0026lt;link rel=\u0026#34;stylesheet\u0026#34; href=\u0026#34;/css/lightbox.css\u0026#34;\u0026gt; // ================== Acrescentei antes do tag \u0026lt;/body\u0026gt; neste ficheiro:\n1 2 3 4 5 6 7 8 \u0026lt;!-- /lightbox --\u0026gt; \u0026lt;script src=\u0026#34;https://code.jquery.com/jquery-3.4.1.min.js\u0026#34; integrity=\u0026#34;sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=\u0026#34; crossorigin=\u0026#34;anonymous\u0026#34;\u0026gt; \u0026lt;/script\u0026gt; \u0026lt;script src=\u0026#34;/js/lightbox.js\u0026#34;\u0026gt;\u0026lt;/script\u0026gt; \u0026lt;link rel=\u0026#34;stylesheet\u0026#34; href=\u0026#34;/css/lightbox.css\u0026#34;\u0026gt; \u0026lt;!-- /lightbox --\u0026gt; Criei um shortcode lightbox, que aceita as mesmas opções do shortcode figure em que se baseia:\n\r\rExpandir\r\r1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 {{ if .Get \u0026#34;caption\u0026#34; }} {{ $.Scratch.Set \u0026#34;caption\u0026#34; (.Get \u0026#34;caption\u0026#34;) }} {{ else if .Get \u0026#34;alt\u0026#34; }} {{ $.Scratch.Set \u0026#34;caption\u0026#34; (.Get \u0026#34;alt\u0026#34;) }} {{ end }} \u0026lt;!-- resolve absolute image path --\u0026gt; {{ $permalink := $.Page.Permalink }} {{ $image := .Get \u0026#34;src\u0026#34; }} {{ $image_link_absolute := (findRE \u0026#34;^/\u0026#34; $image) }} \u0026lt;figure {{ with .Get \u0026#34;class\u0026#34; }}class=\u0026#34;{{.}}\u0026#34;{{ end }} {{ with .Get \u0026#34;width\u0026#34; }}style=\u0026#34;width: {{ . }};\u0026#34;{{ end }} {{ with .Get \u0026#34;height\u0026#34; }}style=\u0026#34;height: {{ . }};\u0026#34;{{ end }} \u0026gt; \u0026lt;a {{ if .Get \u0026#34;lightbox\u0026#34; }} data-lightbox=\u0026#34;{{ .Get \u0026#34;lightbox\u0026#34; | markdownify | plainify }}\u0026#34; {{ else }} data-lightbox=\u0026#34;image-{{ $image }}\u0026#34; {{ end }} {{ if $image_link_absolute }} href=\u0026#34;{{ $image | absURL }}\u0026#34; {{ else }} href=\u0026#34;{{ (printf \u0026#34;%s%s\u0026#34; $permalink $image) }}\u0026#34; {{ end }} {{ with .Get \u0026#34;target\u0026#34; }} target=\u0026#34;{{ . }}\u0026#34;{{ end }} {{ with .Get \u0026#34;rel\u0026#34; }} rel=\u0026#34;{{ . }}\u0026#34;{{ end }}\u0026gt; \u0026lt;img {{ if $image_link_absolute }} src=\u0026#34;{{ $image | absURL }}\u0026#34; {{ else }} src=\u0026#34;{{ (printf \u0026#34;%s%s\u0026#34; $permalink $image) }}\u0026#34; {{ end }} {{ if .Get \u0026#34;alt\u0026#34; }}alt=\u0026#34;{{ .Get \u0026#34;alt\u0026#34; | markdownify | plainify }}\u0026#34; {{ else if .Get \u0026#34;caption\u0026#34; }}alt=\u0026#34;{{ .Get \u0026#34;caption\u0026#34; | markdownify | plainify }}\u0026#34; {{ end }} {{ with .Get \u0026#34;align\u0026#34; }}align=\u0026#34;{{ . }}\u0026#34;{{ end }} /\u0026gt; \u0026lt;/a\u0026gt; \u0026lt;!-- caption and attr--\u0026gt; {{ if ($.Scratch.Get \u0026#34;caption\u0026#34;) }} \u0026lt;figcaption\u0026gt; \u0026lt;span class=\u0026#34;img--caption\u0026#34;\u0026gt; Figure {{ $.Page.Scratch.Get \u0026#34;fig\u0026#34; }}. {{ $.Scratch.Get \u0026#34;caption\u0026#34; | markdownify | plainify }} {{ if .Get \u0026#34;attr\u0026#34; }} [{{- with .Get \u0026#34;attrlink\u0026#34;}}\u0026lt;a href=\u0026#34;{{ . }}\u0026#34;\u0026gt;{{ end }}{{ .Get \u0026#34;attr\u0026#34; | markdownify }}{{ if .Get \u0026#34;attrlink\u0026#34;}}\u0026lt;/a\u0026gt;{{ end -}}] {{ end }} \u0026lt;/span\u0026gt; \u0026lt;/figcaption\u0026gt; {{ end }} \u0026lt;/figure\u0026gt; {{ .Page.Scratch.Add \u0026#34;fig\u0026#34; 1 }} {{ $.Scratch.Delete \u0026#34;caption\u0026#34;}} \r\r\nE está feito, tenho o efeito lightbox activado!\nClique na imagem em baixo para experimentar:\n\r\r","description":"Eu só atiro barro à parede...","id":20,"section":"blog","tags":null,"title":"Achievement unlocked: Lightbox","uri":"https://tiagojsilva.github.io/pt/blog/2021-09-02_lightbox/"},{"content":"Pois, tenho mexido aqui nalgumas coisas nos bastidores:\nAlterações no tema Eu queria usar um tema Hugo para documentação (documentos estruturados), se possível com um blog associado para conteúdo menos estruturado.\nQueria que tivesse (sem ordem de importância):\n Tema claro / escuro Multilíngua (i18n) Várias secções independentes Capacidade de incluir nas caixas de código tanto números de linha como prompts fora do texto, para que fossem ignorados ao copiar o conteúdo da caixa Ter caixas de saída de comandos com formatação distinta Só encontrei este tema, o Zdoc, que tinha uma grande parte das coisas que queria (o Docz parece estar a evoluir como uma alternativa), mas ainda lhe falta muita coisa:\n Não suporta caixas de saída de comandos Só inclui prompts $ e \u0026gt; (e eu precisava também de #, PS e PS#) não podia inserir ficheiros de configuração externos inline não tem um botão para copiar o conteúdo de uma caixa de código De ressalvar que nenhum tema Hugo tem isto tudo.\nCaixas de saída de comandos Resolvi com um shortcode e formatação CSS inline\n1 2 \u0026lt;pre style=\u0026#34;font-style: italic; font-size: 0.79rem\u0026#34;\u0026gt; {{.Inner}}\u0026lt;/pre\u0026gt; Output...\r Prompts para root, PowerShell e PowerShell admin Não foi nada de que me sinta especialmente orgulhoso, porque o código original era muito simples, bastou-me copiar e mudar alguns valores:\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 var hashCodeElem = document.querySelectorAll(\u0026#39;div.language-\\\\#\u0026#39;); hashCodeElem ? hashCodeElem.forEach(function(elem) { var lnts = elem.parentNode.parentNode ? elem.parentNode.parentNode.querySelectorAll(\u0026#39;.lnt\u0026#39;) : null; lnts ? lnts.forEach(function(lnt) { lnt.innerHTML = \u0026#39;#\u0026lt;br/\u0026gt;\u0026#39;; }) : null; }) : null; var psCodeElem = document.querySelectorAll(\u0026#39;div.language-\\\\ps\u0026#39;); psCodeElem ? psCodeElem.forEach(function(elem) { var lnts = elem.parentNode.parentNode ? elem.parentNode.parentNode.querySelectorAll(\u0026#39;.lnt\u0026#39;) : null; lnts ? lnts.forEach(function(lnt) { lnt.innerHTML = \u0026#39;PS\u0026gt;\u0026lt;br/\u0026gt;\u0026#39;; }) : null; }) : null; var psadmCodeElem = document.querySelectorAll(\u0026#39;div.language-\\\\psa\u0026#39;); psadmCodeElem ? psadmCodeElem.forEach(function(elem) { var lnts = elem.parentNode.parentNode ? elem.parentNode.parentNode.querySelectorAll(\u0026#39;.lnt\u0026#39;) : null; lnts ? lnts.forEach(function(lnt) { lnt.innerHTML = \u0026#39;PS#\u0026lt;br/\u0026gt;\u0026#39;; }) : null; }) : null; 1 rm -rf / 1 Stop-Computer 1 Stop-Computer -Computer DC01 Inserir ficheiros de texto externos Não consegui o que queria mas desenrasquei-me assim:\n Um shortcode para ler um ficheiro externo e colocá-lo dentro de um code fence: 1 2 3 4 \u0026lt;!--https://stackoverflow.com/a/45421343--\u0026gt; {{ $file := .Get \u0026#34;file\u0026#34; | readFile }} {{ $lang := .Get \u0026#34;language\u0026#34; }} {{ (print \u0026#34;```\u0026#34; $lang \u0026#34;\\n\u0026#34; $file \u0026#34;\\n```\u0026#34;) | markdownify }} Colocado dentro de um shortcode expand para criar um dropdown (incluído no Zdocs) E antecedido dum link para descarregar o ficheiro\nToda esta complicação é para minorar o problema que se segue. Copiar blocos de código Não consegui dar a volta; por causa do processamento que o tema faz aos code fences para inserir os prompts, o código que encontro para fazer isso falha, porque tenta copiar o texto do sítio errado ou coloca o botão no sítio errado.\nE como o CINEL, na sua imensa sabedoria, não me ensinou CSS nem estrutura DOM (o primeiro ano desse curso em que deixaram de ensinar isso), ainda estou um bocado perdido.\nMudança da fonte de título A fonte de título original do tema era a Montserrat, que era graficamente muito engraçada mas eu achei que no peso Black-900 que estava a ser usado desiquilibrava muito a página e a leitura era difícil.\nMudei-a para a fonte MPlus.\nConteúdo Desenvolver conteúdos para pôr aqui tem sido mais difícil do que estava à espera (além disso, agora tenho um trabalho que me paga as contas). A maior parte do que eu tenho pronto foi desenvolvido durante o curso CET-GRSI, e não posso exactamente chapar isso aqui e deixar os exercícios resolvidos aos próximos alunos!\nEstou a tentar extrair as partes mais avançadas que eram \u0026ldquo;bombons\u0026rdquo; no projecto e que só beneficiariam quem já tivesse feito o grosso dos trabalhos por si, mas não é fácil. Entretanto, estou a preparar uma série de artigos sobre Public Key Infrastructure\nMantenham-se atentos.\nCadência Vou alternar a publicação; cada artigo vai aparecer primeiro em Português, e na semana seguinte uma versão traduzida será publicada no site em Inglês (junto com uma versão portuguesa corrigida).\nEspero publicar novos artigos em semanas alternadas.\n","description":"Mexidas no tema, conteúdo, etc.","id":21,"section":"blog","tags":null,"title":"Actividade Agosto 2021","uri":"https://tiagojsilva.github.io/pt/blog/2021-08-28_site-update/"},{"content":"Dotfiles para Linux Tenho acumulando configurações que me facilitam a vida ou que me resolvem pequenos problemas irritantes.\nPublicar esses ficheiros aqui permite-me descarregá-los e instalá-los em qualquer nova conta que eu crie num sistema Linux.\nO URL para descarregar será https://tiagojsilva.github.io/unix/dotfiles/ficheiro\nExiste um arquivo TAR com todos os ficheiros; para os instalar a todos na sua pasta pessoal (~), usar o comando\n1 wget -O- https://tiagojsilva.github.io/unix/dotfiles/dotfiles.tar | tar -xvf- -C ~ .bashrc \r\rExpandir\r\r# ~/.bashrc: executed by bash(1) for non-login shells. # see /usr/share/doc/bash/examples/startup-files (in the package bash-doc) # for examples # If not running interactively, don't do anything case $- in *i*) ;; *) return;; esac # don't put duplicate lines or lines starting with space in the history. # See bash(1) for more options HISTCONTROL=ignoreboth # append to the history file, don't overwrite it shopt -s histappend # for setting history length see HISTSIZE and HISTFILESIZE in bash(1) HISTSIZE=1000 HISTFILESIZE=2000 # check the window size after each command and, if necessary, # update the values of LINES and COLUMNS. shopt -s checkwinsize # If set, the pattern \u0026quot;**\u0026quot; used in a pathname expansion context will # match all files and zero or more directories and subdirectories. shopt -s globstar # make less more friendly for non-text input files, see lesspipe(1) [ -x /usr/bin/lesspipe ] \u0026amp;\u0026amp; eval \u0026quot;$(SHELL=/bin/sh lesspipe)\u0026quot; # set variable identifying the chroot you work in (used in the prompt below) if [ -z \u0026quot;${debian_chroot:-}\u0026quot; ] \u0026amp;\u0026amp; [ -r /etc/debian_chroot ]; then debian_chroot=$(cat /etc/debian_chroot) fi # set a fancy prompt (non-color, unless we know we \u0026quot;want\u0026quot; color) case \u0026quot;$TERM\u0026quot; in xterm-color|*-256color) color_prompt=yes;; esac # uncomment for a colored prompt, if the terminal has the capability; turned # off by default to not distract the user: the focus in a terminal window # should be on the output of commands, not on the prompt #force_color_prompt=yes if [ -n \u0026quot;$force_color_prompt\u0026quot; ]; then if [ -x /usr/bin/tput ] \u0026amp;\u0026amp; tput setaf 1 \u0026gt;\u0026amp;/dev/null; then # We have color support; assume it's compliant with Ecma-48 # (ISO/IEC-6429). (Lack of such support is extremely rare, and such # a case would tend to support setf rather than setaf.) color_prompt=yes else color_prompt= fi fi if [ \u0026quot;$color_prompt\u0026quot; = yes ]; then PS1='${debian_chroot:+($debian_chroot)}\\[\\033[01;32m\\]\\u@\\h\\[\\033[00m\\]:\\[\\033[01;34m\\]\\w\\[\\033[00m\\]\\$ ' else PS1='${debian_chroot:+($debian_chroot)}\\u@\\h:\\w\\$ ' fi unset color_prompt force_color_prompt # If this is an xterm set the title to user@host:dir case \u0026quot;$TERM\u0026quot; in xterm*|rxvt*) PS1=\u0026quot;\\[\\e]0;${debian_chroot:+($debian_chroot)}\\u@\\h: \\w\\a\\]$PS1\u0026quot; ;; *) ;; esac # enable color support of ls and also add handy aliases if [ -x /usr/bin/dircolors ]; then #force my dircolors # test -r ~/.dircolors \u0026amp;\u0026amp; eval \u0026quot;$(dircolors -b ~/.dircolors)\u0026quot; || eval \u0026quot;$(dircolors -b)\u0026quot; source .dircolors alias ls='ls --color=auto' alias dir='dir --color=auto' #alias vdir='vdir --color=auto' alias grep='grep --color=auto' alias fgrep='fgrep --color=auto' alias egrep='egrep --color=auto' fi # colored GCC warnings and errors export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01' # some more ls aliases alias ll='ls -hlF' alias la='ls -hA' alias lla='ls -ahlF' alias l='ls -hCF' # Add an \u0026quot;alert\u0026quot; alias for long running commands. Use like so: # sleep 10; alert alias alert='notify-send --urgency=low -i \u0026quot;$([ $? = 0 ] \u0026amp;\u0026amp; echo terminal || echo error)\u0026quot; \u0026quot;$(history|tail -n1|sed -e '\\''s/^\\s*[0-9]\\+\\s*//;s/[;\u0026amp;|]\\s*alert$//'\\'')\u0026quot;' # Alias definitions. # You may want to put all your additions into a separate file like # ~/.bash_aliases, instead of adding them here directly. # See /usr/share/doc/bash-doc/examples in the bash-doc package. if [ -f ~/.bash_aliases ]; then . ~/.bash_aliases fi # enable programmable completion features (you don't need to enable # this, if it's already enabled in /etc/bash.bashrc and /etc/profile # sources /etc/bash.bashrc). if ! shopt -oq posix; then if [ -f /usr/share/bash-completion/bash_completion ]; then . /usr/share/bash-completion/bash_completion elif [ -f /etc/bash_completion ]; then . /etc/bash_completion fi fi \r\r .dircolors O padrão do Debian, mas troca o Azul Escuro das directorias por Amarelo.\n\r\rExpandir\r\r1 2 3 export LS_COLORS=\u0026#39;rs=0:di=01;93:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:\u0026#39;; \n \r\r\n.bash_aliases \r\rExpandir\r\r1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 alias ll=\u0026#39;ls -hlF\u0026#39; alias la=\u0026#39;ls -hA\u0026#39; alias lla=\u0026#39;ls -ahlF\u0026#39; alias cp=\u0026#39;cp -i\u0026#39; alias mv=\u0026#39;mv -i\u0026#39; alias rm=\u0026#39;rm -i --preserve-root\u0026#39; alias df=\u0026#39;df -H\u0026#39; alias du=\u0026#39;du -hs\u0026#39; alias wget=\u0026#39;wget -c\u0026#39; alias ports=\u0026#39;netstat -tulanp\u0026#39; alias cls=\u0026#39;clear\u0026#39; alias chown=\u0026#39;chown --preserve-root\u0026#39; alias chmod=\u0026#39;chmod --preserve-root\u0026#39; alias chgrp=\u0026#39;chgrp --preserve-root\u0026#39; alias srvno=\u0026#39;systemctl stop\u0026#39; alias sysno=\u0026#39;systemctl stop\u0026#39; alias srvgo=\u0026#39;systemctl start\u0026#39; alias sysgo=\u0026#39;systemctl start\u0026#39; alias srvsta=\u0026#39;systemctl start\u0026#39; alias syssta=\u0026#39;systemctl start\u0026#39; alias srvrst=\u0026#39;systemctl restart\u0026#39; alias sysrst=\u0026#39;systemctl restart\u0026#39; alias srvena=\u0026#39;systemctl enable\u0026#39; alias sysena=\u0026#39;systemctl enable\u0026#39; alias srvdis=\u0026#39;systemctl disable\u0026#39; alias sysdis=\u0026#39;systemctl disable\u0026#39; alias srvstat=\u0026#39;systemctl status\u0026#39; alias sysstat=\u0026#39;systemctl status\u0026#39; alias sudo=\u0026#39;sudo \u0026#39; \n \r\r .bash_functions \r\rExpandir\r\r1 2 3 4 function mcd () { mkdir -vp -- \u0026#34;$1\u0026#34; \u0026amp;\u0026amp; cd -P -- \u0026#34;$1\u0026#34; } \r\r .vimrc \r\rExpandir\r\r1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 \u0026#34; MIT Missing Semester 2020 Lecture 3 Youtube\u0026#34; https://missing.csail.mit.edu/2020/editors/\u0026#34; Comments in Vimscript start with a `\u0026#34;`.\u0026#34; tjs: load defaultssource $VIMRUNTIME/defaults.vim\u0026#34; If you open this file in Vim, it\u0026#39;ll be syntax highlighted for you.\u0026#34; Vim is based on Vi. Setting `nocompatible` switches from the default\u0026#34; Vi-compatibility mode and enables useful Vim functionality. This\u0026#34; configuration option turns out not to be necessary for the file named\u0026#34; \u0026#39;~/.vimrc\u0026#39;, because Vim automatically enters nocompatible mode if that file\u0026#34; is present. But we\u0026#39;re including it here just in case this config file is\u0026#34; loaded some other way (e.g. saved as `foo`, and then Vim started with\u0026#34; `vim -u foo`).set nocompatible\u0026#34; Cores/temas\u0026#34;set termguicolorsset background=darkcolo industryif has(\u0026#34;gui running\u0026#34;) set guioptions-=T set guioptions+=e set t_Co=256 set guitablabel=%M\\ %t let g:gruvbox_termcolors=256 let g:gruvbox_contrast_dark=\u0026#39;medium\u0026#39; colorscheme gruvboxendif\u0026#34; Turn on syntax highlighting.syntax on\u0026#34; Disable the default Vim startup message.set shortmess+=I\u0026#34; Show line numbers.set number\u0026#34; This enables relative line numbering mode. With both number and\u0026#34; relativenumber enabled, the current line shows the true line number, while\u0026#34; all other lines (above and below) are numbered relative to the current line.\u0026#34; This is useful because you can tell, at a glance, what count is needed to\u0026#34; jump up or down to a particular line, by {count}k to go up or {count}j to go\u0026#34; down.\u0026#34;set relativenumber\u0026#34; Always show the status line at the bottom, even if you only have one window open.set laststatus=2\u0026#34; The backspace key has slightly unintuitive behavior by default. For example,\u0026#34; by default, you can\u0026#39;t backspace before the insertion point set with \u0026#39;i\u0026#39;.\u0026#34; This configuration makes backspace behave more reasonably, in that you can\u0026#34; backspace over anything.set backspace=indent,eol,start\u0026#34; By default, Vim doesn\u0026#39;t let you hide a buffer (i.e. have a buffer that isn\u0026#39;t\u0026#34; shown in any window) that has unsaved changes. This is to prevent you from \u0026#34;\u0026#34; forgetting about unsaved changes and then quitting e.g. via `:qa!`. We find\u0026#34; hidden buffers helpful enough to disable this protection. See `:help hidden`\u0026#34; for more information on this.set hidden\u0026#34; This setting makes search case-insensitive when all characters in the string\u0026#34; being searched are lowercase. However, the search becomes case-sensitive if\u0026#34; it contains any capital letters. This makes searching more convenient.set ignorecaseset smartcase\u0026#34; Enable searching as you type, rather than waiting till you press enter.set incsearch\u0026#34; Unbind some useless/annoying default key bindings.nmap Q \u0026lt;Nop\u0026gt; \u0026#34; \u0026#39;Q\u0026#39; in normal mode enters Ex mode. You almost never want this.\u0026#34; Disable audible bell because it\u0026#39;s annoying.set noerrorbells visualbell t_vb=\u0026#34; Enable mouse support. You should avoid relying on this too much, but it can\u0026#34; sometimes be convenient.set mouse+=a\u0026#34; Try to prevent bad habits like using the arrow keys for movement. This is\u0026#34; not the only possible bad habit. For example, holding down the h/j/k/l keys\u0026#34; for movement, rather than using more efficient movement commands, is also a\u0026#34; bad habit. The former is enforceable through a .vimrc, while we don\u0026#39;t know\u0026#34; how to prevent the latter.\u0026#34; Do this in normal mode...\u0026#34;nnoremap \u0026lt;Left\u0026gt; :echoe \u0026#34;Use h\u0026#34;\u0026lt;CR\u0026gt;\u0026#34;nnoremap \u0026lt;Right\u0026gt; :echoe \u0026#34;Use l\u0026#34;\u0026lt;CR\u0026gt;\u0026#34;nnoremap \u0026lt;Up\u0026gt; :echoe \u0026#34;Use k\u0026#34;\u0026lt;CR\u0026gt;\u0026#34;nnoremap \u0026lt;Down\u0026gt; :echoe \u0026#34;Use j\u0026#34;\u0026lt;CR\u0026gt;\u0026#34; ...and in insert mode\u0026#34;inoremap \u0026lt;Left\u0026gt; \u0026lt;ESC\u0026gt;:echoe \u0026#34;Use h\u0026#34;\u0026lt;CR\u0026gt;\u0026#34;inoremap \u0026lt;Right\u0026gt; \u0026lt;ESC\u0026gt;:echoe \u0026#34;Use l\u0026#34;\u0026lt;CR\u0026gt;\u0026#34;inoremap \u0026lt;Up\u0026gt; \u0026lt;ESC\u0026gt;:echoe \u0026#34;Use k\u0026#34;\u0026lt;CR\u0026gt;\u0026#34;inoremap \u0026lt;Down\u0026gt; \u0026lt;ESC\u0026gt;:echoe \u0026#34;Use j\u0026#34;\u0026lt;CR\u0026gt;\u0026#34; escrever 4 espaços quando se usa TABset expandtabset tabstop=4set shiftwidth=4set softtabstop=4\u0026#34; open new split panes to right and bottom, which feels more naturalset splitbelowset splitrightset showmatch \u0026#34; show matching braces when text indicator is over themfiletype plugin indent on \u0026#34; enable file type detectionset autoindent\u0026#34; leader passa a ser ,let mapleader = \u0026#34;,\u0026#34;\u0026#34; Permanent undoset undodir=~/.vimdidset undofile\u0026#34; Ctrl+c and Ctrl+j as Esc\u0026#34; Ctrl-j is a little awkward unfortunately:\u0026#34; https://github.com/neovim/neovim/issues/5916\u0026#34; So we also map Ctrl+kinoremap \u0026lt;C-j\u0026gt; \u0026lt;Esc\u0026gt;nnoremap \u0026lt;C-k\u0026gt; \u0026lt;Esc\u0026gt;inoremap \u0026lt;C-k\u0026gt; \u0026lt;Esc\u0026gt;vnoremap \u0026lt;C-k\u0026gt; \u0026lt;Esc\u0026gt;snoremap \u0026lt;C-k\u0026gt; \u0026lt;Esc\u0026gt;xnoremap \u0026lt;C-k\u0026gt; \u0026lt;Esc\u0026gt;cnoremap \u0026lt;C-k\u0026gt; \u0026lt;Esc\u0026gt;onoremap \u0026lt;C-k\u0026gt; \u0026lt;Esc\u0026gt;lnoremap \u0026lt;C-k\u0026gt; \u0026lt;Esc\u0026gt;tnoremap \u0026lt;C-k\u0026gt; \u0026lt;Esc\u0026gt;nnoremap \u0026lt;C-c\u0026gt; \u0026lt;Esc\u0026gt;inoremap \u0026lt;C-c\u0026gt; \u0026lt;Esc\u0026gt;vnoremap \u0026lt;C-c\u0026gt; \u0026lt;Esc\u0026gt;snoremap \u0026lt;C-c\u0026gt; \u0026lt;Esc\u0026gt;xnoremap \u0026lt;C-c\u0026gt; \u0026lt;Esc\u0026gt;cnoremap \u0026lt;C-c\u0026gt; \u0026lt;Esc\u0026gt;onoremap \u0026lt;C-c\u0026gt; \u0026lt;Esc\u0026gt;lnoremap \u0026lt;C-c\u0026gt; \u0026lt;Esc\u0026gt;tnoremap \u0026lt;C-c\u0026gt; \u0026lt;Esc\u0026gt;\u0026#34; Neat X clipboard integration\u0026#34; \\p will paste clipboard into buffer\u0026#34; \\c will copy entire buffer into clipboardnoremap \u0026lt;leader\u0026gt;p :read !xsel --clipboard --output\u0026lt;cr\u0026gt;noremap \u0026lt;leader\u0026gt;c :w !xsel -ib\u0026lt;cr\u0026gt;\u0026lt;cr\u0026gt;\u0026#34; turn off search highlightvnoremap \u0026lt;C-h\u0026gt; :nohlsearch\u0026lt;cr\u0026gt;nnoremap \u0026lt;C-h\u0026gt; :nohlsearch\u0026lt;cr\u0026gt;\u0026#34; statusline\u0026#34;cores\u0026#34;terminal BG azulhi statusline ctermfg=4 \u0026#34;terminal letras cyanhi statusline ctermbg=6 set statusline= \u0026#34; clear the statusline for when vimrc is reloadedset statusline+=%-3.3n\\ \u0026#34; buffer numberset statusline+=%f\\ \u0026#34; file nameset statusline+=%h%m%r%w \u0026#34; flagsset statusline+=[%{strlen(\u0026amp;ft)?\u0026amp;ft:\u0026#39;none\u0026#39;}, \u0026#34; filetypeset statusline+=%{strlen(\u0026amp;fenc)?\u0026amp;fenc:\u0026amp;enc}, \u0026#34; encodingset statusline+=%{\u0026amp;fileformat}] \u0026#34; file formatset statusline+=%= \u0026#34; right alignset statusline+=%{synIDattr(synID(line(\u0026#39;.\u0026#39;),col(\u0026#39;.\u0026#39;),1),\u0026#39;name\u0026#39;)}\\ \u0026#34; highlightset statusline+=%b,0x%-8B\\ \u0026#34; current charset statusline+=%-14.(%l,%c%V%)\\ %\u0026lt;%P \u0026#34; offset\u0026#34; Folding\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;set foldenable \u0026#34; enable foldingset foldlevelstart=10 \u0026#34; open most folds by defaultset foldnestmax=10 \u0026#34; 10 nested fold max\u0026#34; space open/closes folds\u0026#34; nnoremap \u0026lt;space\u0026gt; zaset foldmethod=indent \u0026#34; fold based on indent level\u0026#34; This is especially useful for me since I spend my days in Python.\u0026#34; Other acceptable values are marker, manual, expr, syntax, diff.\u0026#34; Run :help foldmethod to find out what each of those do.\u0026#34; Custom Functions\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34; toggle between number and relativenumber (\\t)function! ToggleNumber() if(\u0026amp;relativenumber == 1) set norelativenumber set number else set relativenumber endifendfuncnnoremap \u0026lt;leader\u0026gt;t :call ToggleNumber()\u0026lt;CR\u0026gt;\u0026#34; Vim Markdown\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;\u0026#34;let g:markdown_fenced_languages = [ \\ \u0026#39;bash=sh\u0026#39;, \\ \u0026#39;c\u0026#39;, \\ \u0026#39;coffee\u0026#39;, \\ \u0026#39;erb=eruby\u0026#39;, \\ \u0026#39;javascript\u0026#39;, \\ \u0026#39;json\u0026#39;, \\ \u0026#39;perl\u0026#39;, \\ \u0026#39;python\u0026#39;, \\ \u0026#39;ruby\u0026#39;, \\ \u0026#39;yaml\u0026#39;, \\ \u0026#39;go\u0026#39;,\\]let g:vim_markdown_conceal = 2 \r\r .nanorc \r\rExpandir\r\r## .nanorc tjs 2020-06 ## https://www.if-not-true-then-false.com/2009/tuning-nano-text-editor-with-nanorc/ # scroll by line set smooth # indent set autoindent # easy backup (ficheiro~) set backup # one line more for content set morespace # hide shortcut help # set nohelp # tab 4 spaces set tabsize 4 # convert tabs to spaces on insertion set tabstospaces ########## #sintax ## Nanorc files include \u0026quot;/usr/share/nano/nanorc.nanorc\u0026quot; ## C/C++ include \u0026quot;/usr/share/nano/c.nanorc\u0026quot; ## HTML include \u0026quot;/usr/share/nano/html.nanorc\u0026quot; ## TeX include \u0026quot;/usr/share/nano/tex.nanorc\u0026quot; ## Quoted emails (under e.g. mutt) include \u0026quot;/usr/share/nano/mutt.nanorc\u0026quot; ## Patch files include \u0026quot;/usr/share/nano/patch.nanorc\u0026quot; ## Manpages include \u0026quot;/usr/share/nano/man.nanorc\u0026quot; ## Groff include \u0026quot;/usr/share/nano/groff.nanorc\u0026quot; ## Perl include \u0026quot;/usr/share/nano/perl.nanorc\u0026quot; ## Python include \u0026quot;/usr/share/nano/python.nanorc\u0026quot; ## Ruby include \u0026quot;/usr/share/nano/ruby.nanorc\u0026quot; ## Java include \u0026quot;/usr/share/nano/java.nanorc\u0026quot; ## Assembler include \u0026quot;/usr/share/nano/asm.nanorc\u0026quot; ## Bourne shell scripts include \u0026quot;/usr/share/nano/sh.nanorc\u0026quot; ## POV-Ray include \u0026quot;/usr/share/nano/pov.nanorc\u0026quot; \r\r .tmux.conf A tecla de atalho passa a ser Ctrl-A (que faz muito mais sentido, especialmente para quem trocar o CapsLock para Control), mas como interfere com a navegação na shell, é preciso segurar no Ctrl e teclar A duas vezes.\r\n\r\rExpandir\r\r#### #Keybindings #### # remap prefix from 'C-b' to 'C-a' # interfere com o \u0026quot;inicio de linha\u0026quot; na shell, passa a ser C-a+C-a unbind C-b set-option -g prefix C-a bind-key C-a send-prefix # split panes using | and - bind | split-window -h bind - split-window -v unbind '\u0026quot;' unbind % # reload config file (change file location to your the tmux.conf you want to use) bind r source-file ~/.tmux.conf # switch panes using Alt-arrow without prefix bind -n M-Left select-pane -L bind -n M-Right select-pane -R bind -n M-Up select-pane -U bind -n M-Down select-pane -D # Enable mouse mode (tmux 2.1 and above) set -g mouse on ###################### ### DESIGN CHANGES ### ###################### # loud or quiet? set -g visual-activity off set -g visual-bell off set -g visual-silence off setw -g monitor-activity off set -g bell-action none # modes setw -g clock-mode-colour colour5 setw -g mode-style 'fg=colour1 bg=colour18 bold' # panes set -g pane-border-style 'fg=colour19 bg=colour0' set -g pane-active-border-style 'bg=colour0 fg=colour9' # statusbar set -g status-position bottom set -g status-justify left #set -g status-style 'bg=colour18 fg=colour137 dim' set -g status-style 'bg=blue fg=colour240' set -g status-left '' set -g status-right '#[fg=colour253,bg=colour19] %d/%m #[fg=colour253,bg=colour8] %H:%M:%S ' set -g status-right-length 50 set -g status-left-length 20 #setw -g window-status-current-style 'fg=colour1 bg=colour19 bold' setw -g window-status-current-style 'fg=brightblue bg=cyan' #setw -g window-status-current-format ' #I#[fg=colour249]:#[fg=colour255]#W#[fg=colour249]#F ' setw -g window-status-current-format ' #I#[fg=white]:#[fg=colour255]#W#[fg=black]#F ' setw -g window-status-style 'fg=colour9 bg=colour18' #setw -g window-status-style 'fg=brightred bg=brightgreen' #setw -g window-status-format ' #I#[fg=colour237]:#[fg=colour250]#W#[fg=colour244]#F ' setw -g window-status-format ' #I#[fg=red]:#[fg=green]#W#[fg=blue]#F ' setw -g window-status-bell-style 'fg=colour255 bg=colour1 bold' #setw -g window-status-bell-style 'fg=red bg=white bold' # messages #set -g message-style 'fg=colour232 bg=colour16 bold' set -g message-style 'fg=white bg=red bold' \r\n","description":"Unix/Linux dotfiles","id":22,"section":"unixlike","tags":null,"title":"Dotfiles","uri":"https://tiagojsilva.github.io/pt/unixlike/dotfiles/"},{"content":"Sentem-se, e estejam à vontade.\nTenho tido a sorte de fazer dos meus gostos profissão; em novo, tive de escolher um deles (Som para Cinema), mas as voltas da vida levaram-me a abraçar um outro gosto, as TI, Mesmo que no final de contas tenha voltado à casa de partida, não dei o meu tempo como perdido; tive óptimos professores e colegas e aprendi imensas coisas que sempre quis saber\nPor isso, porque o bichinho acordou e para evitar que me esqueça de tudo, decidi fazer este site para registar e partilhar o que vou aprendendo.\nE se de caminho ajudar mais alguém, fico feliz por isso.\nQuando acabei o curso CET-GRSI (Gestão de Redes e de Sistemas de Informação) no CINEL, em 2020, e voltei para o Restauro de Som, dei de caras com este vídeo que me inspirou:\n\rQue de resto são coisas básicas: continuar a progredir, documentar extensivamente, e manter-me atento.\nUm dos conselhos já foi seguido: criar um site pessoal estático.\nÉ mesmo aqui. Bem-vindos.\n","description":"É preciso começar por qualquer lado!","id":23,"section":"blog","tags":null,"title":"Hello World","uri":"https://tiagojsilva.github.io/pt/blog/2021-08-09_hello-world/"}]