En aquestes que estava Xina pensant com idiotitzar als occidentals i guanyar-lis la cursa tecnològica... I puf! Va inventar TikTok. Els nostres joves perden un munt d'hores en aquesta app d'scroll infinit, sense fer res mínimament útil amb la seva vida. Quan jo era jove tampoc és que fes res útil, però almenys trastejar amb ordinadors hem va fer el que sóc ara.
El curiós és que TikTok dins de Xina no existeix com a tal, és una app que només permet 40 minuts d'ús al dia i enlloc de valls hi ha força continguts educatius. Mmmmm... Ves quina cosa!
Almeys ho comento amb els adolescents que tinc al voltant, i clar, amb el sistema educatiu super motivador que tenim i això, doncs a vegades hem pregunto si les coses surten bé per casualitat.
#13/12/2022 18:45 Software Politikon Autor: Alex Canalda
Fa ja molts, molts, molts anys que tinc aquest domini de Canalda.net. Al principi el tenia a l'empresa Register. Però es van tornar avariciosos, pujant preus i spammejant en compra i compra més dominis. I el vaig migrar a uns amics. I que té a veure això amb l'email? Més endevant.
Fa un temps que he reinstal·lat el servidor de casa, que té aquest blog i un servidor de correu, entre altres coses. I clar, que poso per fer de servidor de correu? Doncs he trobat el MailEnable. Que té una part gratuïta i una de pagament. De moment amb la gratuïta funciono bastant bé.
Peeeeerò, hem vaig trobar amb problemes:
Clar, no mola que el Gmail et digui que la teva adreça de correu es dolenta. I és perque falla el DKIM i el SPF.
El DKIM es una signatura que afegeix el servidor de correu que envia i que després el servidor de correu que rep pot validar. I aquesta validació la fa mitjançant un certificat públic. I es posa en el domini. En el MailEnable es configura així:
El "selector" es un petit text que es posarà al domini (jo he posat "dkm", però es pot posar el que es vulgui), de la següent forma selector._domainkeys.domini.com. En el meu cas és "dkm._domainkeys.canalda.net". Va ser configurar això i el Google es va deixar de queixar.
Peeeeeerò encara no passava la validació SPF. El SPF diu quines són les adreces dels servidors de correu vàlids per enviar un email. Estava configurat per domini, es a dir, que el SPF tenia una pinta com aquesta "mail.canalda.net", però es veu que això al Google no li mola. Calia posar-ho per IP, algo com: TXT canalda.net "v=spf1 ip4:91.126.242.214 include:mail.canalda.net -all". Va ser posar-ho i alehop! Solucionat. Ja va passar el SPF també.
El Gmail té l'opció, quan estas mirant un correu, en els tres punts verticals de la dreta de "Ver el Original" on es pot consultar si el missatge ha passat les validacions.
Quan per Nadal graven uns vídeos dels nens fent els pastorets i tens que compartir 3.5GB amb persones que tenen pocs coneixements d'informàtica a.k.a usuaris, i el tema pendrive no mola. No mola pel tema pandèmia i per que els usuaris són despistats i els pendrives no tornen.
Donat que tinc un servidor de SFTP a casa i que explicar com instal·lar i configurar un client de SFTP a segons qui doncs li pot donar un yuyu cerebral, o simplement no té temps ni ganes d'aprendre, cal fer algo fàcil de fer servir.
Doncs dit i fet, un programet dummy on hi ha un client de SFTP amb la configuració posada i el que ha de descarregar també. Ah! I com a bonus track donat que els usuaris van per Wifi, ara falla ara no, ara tenen una estona per descarregar, ara paren a descansar... Doncs té la funció "resume" o que continua allà on ho ha deixat.
El codi a continuació, és una aplicació Winforms de tota la vida, el formulari té dos botons, una barra de progrés i un quadre de text.
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Renci.SshNet;
using Renci.SshNet.Common;
using Renci.SshNet.Sftp;
namespace Downloader
{
public partial class frmDownloader : Form
{
bool EnMarxa = false;
public frmDownloader()
{
InitializeComponent();
}
privatedelegatevoid SetLogDelegate(string propertyValue);
publicvoid SetLog(string propertyValue)
{
if (this.InvokeRequired)
{
this.Invoke(new SetLogDelegate(SetLog), propertyValue);
}
else
{
if (txtLog.Text.Length > 10000) txtLog.Text = "";
txtLog.Text += Environment.NewLine + DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToLongTimeString() + " - " + propertyValue;
}
}
publicstring ObtenirIP(string host)
{
IPHostEntry hostEntry;
string adreca = "";
hostEntry = Dns.GetHostEntry(host);
if (hostEntry.AddressList.Length > 0)
{
IPAddress ip = hostEntry.AddressList[0];
adreca = ip.ToString();
}
return adreca;
}
privatevoid btnDownload_Click(object sender, EventArgs e)
{
btnDownload.Enabled = false;
string host = @"sftp.elteudomini.aqui";
string username = "posaixo";
string password = @"aixoaltra";
string carpetaLocal;
List<clsCarpeta> CarpetesABaixar = newList<clsCarpeta>();
ConfiguracioABaixar(CarpetesABaixar);
string localDirectoryBase = AppDomain.CurrentDomain.BaseDirectory;
EnMarxa = true;
try
{
SetLog("Intentant conectar: " + host + " - " + ObtenirIP(host));
using (SftpClient client = new SftpClient(host, username, password))
{
try
{
client.Connect();
}
catch (Exception Ex)
{
SetLog("Error conectant: " + Ex.Message);
}
if (!client.IsConnected)
{
SetLog("Client no ha conectat");
return;
}
else
{
SetLog("Conectat OK");
}
foreach (clsCarpeta Carpeta in CarpetesABaixar)
{
carpetaLocal = localDirectoryBase + Carpeta.NomLocal;
if (!Directory.Exists(carpetaLocal))
{
Directory.CreateDirectory(carpetaLocal);
}
foreach (clsFitxer Fitxer in Carpeta.Fitxers)
{
DescarregaFitxer(Fitxer, Carpeta, client);
}
}
}
}
catch(Exception Err)
{
SetLog("ERROR: " + Err.Message);
}
SetLog("Acabat");
btnDownload.Enabled = true;
}
privatevoid DescarregaFitxer(clsFitxer fitxer, clsCarpeta carpeta, SftpClient client)
{
int numIntents = 0;
int maxIntents = 10;
bool retry = false;
float percentatgeFet = 0;
string localDirectory = AppDomain.CurrentDomain.BaseDirectory + carpeta.NomLocal;
string NomSencerFitxerRemot = carpeta.NomRemot + fitxer.Nom;
do
{
bool retrying = retry;
retry = false;
if (!client.Exists(NomSencerFitxerRemot))
{
SetLog("Fitxer remot no trobat: " + NomSencerFitxerRemot);
return;
}
SetLog("Obtenint atributs del fitxer: " + NomSencerFitxerRemot);
SftpFileAttributes atributs = client.GetAttributes(NomSencerFitxerRemot);
long MidaTotal = atributs.Size;
fitxer.Mida = MidaTotal;
SetLog("Mida del fitxer a descarregar: " + MidaTotal);
string destinationFile = Path.Combine(localDirectory, fitxer.Nom);
SetLog("Grabant fitxer a: " + destinationFile);
if (File.Exists(destinationFile))
{
FileInfo infoFitxerLocal = new FileInfo(destinationFile);
if (infoFitxerLocal.Length == fitxer.Mida)
{
SetLog("Fitxer " + fitxer.Nom + " ja descarregat, saltant al següent");
return;
}
else
{
retrying = true;
}
}
try
{
Stream destinationStream;
try
{
if (retrying)
{
SetLog("Continuant descarrega");
destinationStream = new FileStream(destinationFile, FileMode.Append);
}
else
{
SetLog("Descarrega nova de cero");
destinationStream = new FileStream(destinationFile, FileMode.Create);
}
}
catch (Exception Err)
{
SetLog("No s'ha pogut crear el fitxer local: " + destinationFile);
SetLog(Err.Message);
return;
}
using (destinationStream)
using (SftpFileStream sourceStream = client.Open(NomSencerFitxerRemot, FileMode.Open))
{
sourceStream.Seek(destinationStream.Length, SeekOrigin.Begin);
// You can simply use sourceStream.CopyTo(destinationStream) here.// But if you need to monitor download progress,// you have to loop yourself.byte[] buffer = newbyte[81920];
int read;
long total = destinationStream.Length;
while ((read = sourceStream.Read(buffer, 0, buffer.Length)) != 0)
{
destinationStream.Write(buffer, 0, read);
total = total + (long)read;
percentatgeFet = ((float)total / (float)MidaTotal) * 100;
prgBarDescarregat.Value = (int)Math.Truncate(percentatgeFet);
lblProgress.Text = Math.Round(percentatgeFet, 2) + "%";
Application.DoEvents();
if (!EnMarxa)
{
client.Disconnect();
return;
}
}
}
}
catch (SshException ex)
{
SetLog("Error: " + ex.Message);
retry = true;
numIntents++;
SetLog("Reintents: " + numIntents);
if (numIntents > maxIntents)
{
SetLog("Sortint per mases reintents: " + numIntents);
break;
}
}
}
while (retry);
}
privatevoid ConfiguracioABaixar(List<clsCarpeta> carpetesABaixar)
{
clsCarpeta Carpeta;
clsFitxer Fitxer;
Carpeta = new clsCarpeta();
Carpeta.NomLocal = "Harry Potter";
Carpeta.NomRemot = "/Incoming2/Pelis infantils/Harry Potter/";
Fitxer = new clsFitxer();
Fitxer.Nom = "bla bla bla 1.mkv";
Carpeta.Fitxers.Add(Fitxer);
Fitxer = new clsFitxer();
Fitxer.Nom = "Bla bla bla 2.mkv";
Carpeta.Fitxers.Add(Fitxer);
carpetesABaixar.Add(Carpeta);
}
privatevoid btnTancar_Click(object sender, EventArgs e)
{
EnMarxa = false;
Application.Exit();
}
}
}
Porto més d'un any tele-treballant. Amb el portàtil de la feina. Clar, un portàtil que no es mou del lloc no té gaire sentit. A més un portàtil és incòmode per treballar. Per varies raons, per ergonomia (pantalla petita, teclat pse pse, ratolí que no té...) i per falta de potència.
Com usuari el primer que adreces és l'ergonomia, quan veus que la cosa va per llarg enxufes ràpidament un teclat i un ratolí. I si pots també una pantalla. Aleshores, si tens dos ordinadors, un d'escriptori i el portàtil vas enxufant les coses a un o l'altra segons quin vas a fer servir, fins que et canses. Es el moment de fer escriptori remot.
Obres el portàtil per engegar-lo i has configurat el Windows perque no faci cas de que la tapa està tancada. El portàtil té un cable de xarxa (ja cansat de la wifi) i el d'alimentació. I des de l'ordinador gran fas escriptori remot al portàtil, que està com un trepitja papers gegant sobre una taula. Bé, almenys ja no fas el tema d'enxufar i desenxufar monitor, teclat i ratolí. Treballes amb una bona ergonomia, amb bona postura corporal i perifèrics de qualitat. Però segueix el run-run de perque tinc que tenir engegats 2 ordinadors i que tinc un tros de taula, de la meva taula, "okupat". Calia buscar una solució. I és quan vaig decidir virtualitzar el portàtil. Sobretot quan l'ordinador d'escriptori és una mica bèstia.
Primer de tot hem de ser administradors del portàtil, és un punt important.
Es pot fer amb VMWare, però jo he triat Microsoft, el HyperV, i he fet servir el Disk2VHD per convertir el disc físic del portàtil en un fitxer. El VHD és l'extensió de "Virtual Hard Disk" que són els fitxers que fan de disc dur de les màquines virtuals de Microsoft. Cal tenir prou espai al disc del portàtil, o es pot fer servir un disc extern USB, igualment caldrà copiar el fitxer resultant al disc del PC d'escriptori d'alguna manera.
Dit i fet, en el portàtil de la feina va trigar uns 40 minuts i va deixar un fitxer d'uns 100GB. El programa diu que no suporta discs de més de 127GB, igualment penso que si es fa neteja és una mida correcte.
Vaig copiar el fitxer al PC d'escriptori i li vaig crear una màquina virtual. 8 nuclis i 16GB de RAM, la meitat del PC d'escriptori, i el doble que el portàtil. El canvi de velocitat va ser instantani. Ara cal configurar les eines. La VPN va funcionar a la primera, però el Microsoft Teams no. Els PCs tenen un xip de seguretat, el TPM (Trusted Platform Module) on guarden coses, i el Teams guarda coses allí. Cal configurar la màquina virtual amb un TPM virtual i dir-li al Teams que s'oblidi del TPM anterior. Que quedi així, més o menys.
Ara cal fer lo del TPM, escrivim "Credential Manager" al menú inici de Windows...
Ara esborrem les credencials del Teams si hi ha alguna. Cal reiniciar la màquina virtual, i intentar entrar al Teams a veure si li agrada.
Si encara dóna problemes, cal fer un últim pas, que es posar una clau al registre de Windows.
Un cop el Teams i demès família, Office inclòs ja estan domesticats a la nova VM, cal configurar el tema multimèdia. Amb els auriculars amb micròfon per fer les "calls", o trucades, no he tingut problema. Amb la webcam, cal fer algunes cosetes, primer cal tenir una webcam, perquè el portàtil tenia una, però al PC d'escriptori li he tingut que posar. Cal teclejar al menú inici del PC d'escriptori (no el virtual) "Group" i sortirà l'administrador de polítiques de grup. Cal anar a la següent clau i habilitar-la.
Cal reiniciar el PC, altra cop. Si les opcions de configuració no apareixen quan conectem a la VM es poden tornar a fer aparèixer amb la instrucció: vmconnect localhost "nom_màquina_virtual" /edit . En un Powershell executat com administrador. Aleshores surt l'opció de vincular coses USB (USB remote FX) de la màquina host a la VM.
Ha costat de configurar tot plegat, però ara que ja està i tot funciona és un goig poder gaudir d'un bon hardware a la feina, que tot vagi ràpid, i no tenir trastos per sobre la taula que molesten. Yummi yummi!
#14/04/2021 19:38 Hardware Software Autor: Alex Canalda
Seguint amb el post del certificat autosignat, també es pot fer que un certificat siqui CA (Certificate Authority). Perque és interessant que un certificat sigui CA Root? Perque es pot posar aquest al magatzem de certificats CA del Firefox i a partir d'aquest moment els certificats signats amb aquest CA estaran reconeguts com a "bons" pel Firefox.
Cal seguir els mateixos passos que quan es fa un certificat SSL autosignat, però fins a un punt. Concretament cal seguir fins al punt 7, a partir d'aquest punt ja comencen els canvis.
Cal dir-li al certificat quins seran els seus usos, "Key Usage". Es marquen les opcions de "Firma d'altres certificats" i "Firma CRL" (Els CRL és la llista de certificats rebutxats (Certificate revoked list)).
A més a més cal dir-li que és una CA
Finalment s'exporta fent botó dret i escollir exportar del menú i es posa al Firefox, al grup de CAs
A partir d'aleshores amb el P12 podem signar CSRs que generem per fer temes de HTTPS, i al tenir la CA importada al navegador quedaran reconeguts. I ja muntem una empresa i cobrem per fer-ho... o no.
Des de que treballo amb certificats sempre m'ha sorprès la complexitat que li donen a una cosa que hauria de simple. Sempre des de línia de comandes, fent servir paràmetres exòtics... per mi que ho fan expressament per mantenir-los allunyats dels usuaris i que els informàtics tinguin feina.
Els passos a seguir són:
Descarregar el KeyStore Explorer, que es una eina FreeWare que permet gestionar certificats amb una... interficies grafica! Tremendu!
Crear un nou repositori de certificats, a mi m'agrada el P12, però hi ha d'altres tipus. El P12 es pot obrir des de C#.
Li donem al botó del guardar i ens preguntarà de crear una password pel fitxer. Li posem una que ens agradi, 1234 o així que és d'alta seguretat.
Generem un parell de clau pública-clau privada RSA. Li donem al OK, però encara no haurem acabat. Aquest és el primer pas.
Ara cal afegir les propietats, amb aquest botó encerclat. També augmentar la data de caducitat, al gust, jo li poso un munt d'anys per no ternir que amoinar-me:
La propietat IMPORTANT es la CN o "Common Name". A de coincidir amb el domini del servidor d'Internet, que si es localhost, serà "localhost" però si és un altra cal posar-lo. És el que els guiris diuen fully qualified name (FQDN) del servidor. La resta són etiquetes que es poden posar coses... es recomana posar dades acurades, per allò de les "best practices".
Li donem al "OK" un cop omplertes les dades però encara no hem acabat. Encara estem a la pantalla de "Generate Key Pair". Ara cal donar-li al botó "Add Extensions".
A la pantalla de les extensions, cal afegir amb el botó "+".
Ara cal afegir les extensions i les seves opcions, tot molt fàcil... Comencem per "Key usage", on cal marcar "Digital Signature" i "Key Encipherment".
Encara no hem acabat amb les extensions... Falta la "Extended Key Usage" on cal marcar la "TLS Web Server Authentication"
Amb això hi ha prou, encara que si es vol ser "purista" també es pot afegir el SANs (Subject Alternative Names). On es posa altra cop el FQDN del servidor (igual que al CN).
Amb això ja podem anar donant al botó, posant un nom a la clau, i si volem una pwd extra a la clau.
Ara cal generar un CSR (Certificate Signin Request) perque en teoria la signi una CA (Certificate Authority) i la posi sota el seu paraigües, però ja veure'm com es fa això... De moment generem el CSR fent botó dret sobre les claus acabades de crear i escollim l'opció "Generate CSR". Amb això tindrem creat un fitxer amb extensió CSR que es pot enviar per mail al responsable de la CA.
I ara ens imaginem que som la CA i rebem aquest CSR. Signem nosaltres mateixos el certificat. És l'opció "Sign".
Amb el fitxer firmat ara fem una importació de resposta de CA cap dins del P12.
Ara cal fer dos passos, posar el certificat al Firefox per tal que el reconegui (clar, Firefox no es fia de la CA "fake" que hem fet. Però es pot convencer.
I l'últim pas es fer servir el P12 que tenim des de C#, com si fos un servidor web.
if (UseSSL)
{
SSLStream = new SslStream(socket.GetStream(), false);
// Authenticate the server but don't require the client to authenticate.try
{
SSLStream.AuthenticateAsServer(serverCertificate, false, SslProtocols.Tls12, false);
inputStream = new BufferedStream(SSLStream);
// Display the properties and settings for the authenticated stream.
DisplaySecurityLevel(SSLStream);
DisplaySecurityServices(SSLStream);
DisplayCertificateInformation(SSLStream);
DisplayStreamProperties(SSLStream);
}
catch (AuthenticationException e)
{
server.IFace.SetResultsValue(string.Format("AuthenticationException: {0}", e.Message));
if (e.InnerException != null)
{
server.IFace.SetResultsValue(string.Format("Inner exception: {0}", e.InnerException.Message));
}
server.IFace.SetResultsValue("Authentication failed - closing the connection.");
}
catch (Exception e)
{
server.IFace.SetResultsValue(string.Format("Exception: {0}", e.Message));
if (e.InnerException != null)
{
server.IFace.SetResultsValue(string.Format("Inner exception: {0}", e.InnerException.Message));
}
}
}
else
{
inputStream = new BufferedStream(socket.GetStream());
}
Amb aquest codi, i el Firefox configurat amb el nostre certificat es poden fer "webservers" en C# amb connexions SSL la mar de cuques. Si volem tenir més d'un webserver d'aquests, llavors caldria muntar nosaltres mateixos la nostra propia CA, però això serà en un altra post.
El blog fa temps que funciona amb SSL, però com aconseguir un certificat reconegut gratis i que es vagi renovant solet? Aaaaaah...
Doncs faig servir els certificats de LetsEncrypt que són gratuïts. El que passa és que no hi ha cap lloc on descarregar el certificat, ni cap cosa "intuitiva" on fer la petició del certificat. T'envien a una pàgina amb un CertBot que mmm... diguem que es per Apaches o NGINX, coses que per la gent de Windows sonen rares i estranyes. Per sort, el que en realitat fa LetEncrypt és exposar un interface on fer peticions seguint el protocol ACME (com la marca de "coses" del Correcaminos, humor informàtic) i aleshores cal buscar un client que gestioni el protocol ACME, un client (LetEncrypt serà el servidor).
El client que he trobat senzill i fàcil de fer servir, que s'integra correctament amb el IIS (ja fa les modificacions en la configuració ell solet i tot) és el win-acme. Descarregues, executes el client, segueixes la configuració de pantalla i ja tens el IIS configurat, un certificat i una tasca programada que verifica la caducitat del certificat i el renova automàticament. Job done!
Ara que estem de confinament, pandèmia, etc... La administració hauria de ser més electrònica que mai. Però no se per que l'administració pública va decidir fer servir certificats, per identificar-te o per firmar etc... I no. Aquesta tecnologia és molt bona en teoria, però no és usable. I la usabilitat mata en informàtica.
No pot ser que cap BANC faci servir certificats, i no hi ha res més seriós que els calers. Per que nasos la administració pública fa servir aquestes merdes que si no tens una combinació de navegador, java o X (on X potser una alineació astral complexe) no funcionen. I el navegador pot ser obsolet, o el java estar lligat a una versió que no existeix de fa molts anys. Com a bonus a més a més els certificats caduquen (WTF?!!!?).
La gent gran no poden fer-los servir. De fet un usuari normal tampoc i jo just just.
Que costaria que la FNMT expedís unes targetes de coordenades amb un PIN rollo bancari, amb números grossos i que la gent gran les pugui llegir, o que facin servir un PIN personal rollo targeta de credit. Sobretot posar webs adaptables a diferents resolucions. No m'imagino a cap línia aèria dissenyant la seva web com ho fa l'administració, i amb la millonada que costa. De Renfe i la seva web ni parlem, però bé, que marxo del tema, que certificats no gracies. Hi ha mètodes alternatius més usables i ja. L'administració pública hauria d'aprendre dels bancs, i els bancs tenen marge de millora però van fent.
#29/10/2020 18:26 Software Politikon Autor: Alex Canalda
La meva organització ha tingut a bé tocar-me els bemolls amb el Windows Update, no se per que es fiquen pel mig en algo que funciona prou bé. He decidit treure aquesta política de grup del PC que l'empresa ha tingut a bé que faci servir. Per fer-ho cal obrir l'editor del registre de Windows i liquidar les següents claus:
A SQL Server es pot fer un UPDATE d'un camp de tipus text, char, nchar, nvarchar, nchar etc... amb la funció REPLACE. Té els típics 3 paràmetres: On buscar, que buscar i el nou text a posar. Però... sembla que REPLACE no funciona amb camps text, ntext (WTF! Si són texts!). Almenys en el SQL Server 2016. He mirat i no sembla que ho hagin millorat en versions superiors. Molt "Bussiness inteligence" però rascar coses bàsiques costa. En finssss. Però hi ha un forma de fer aquests UPDATES, fent servir el CAST, es a dir convertint el tipus de dada a un que sí li agradi al REPLACE.
UPDATE [tblPaginas]
SET [Contenido] = CAST(REPLACE(CAST([Contenido] asNVarchar(MAX)),'TEXT QUE BUSQUES I VOLS MODIFICAR','NOU TEXT') ASNText)
WHERE [Contenido] LIKE'%ALGUNA CONDICIO%'
Es a dir cal fer un CAST d'anada per posar el text a nvarchar(MAX) i un altra de tornada. I arreglat!
#20/02/2020 13:19 SQLServer Software Autor: Alex Canalda