lunedì 18 febbraio 2019

SmartMatic A4-210: le famigerate Voting Machine

Dopo litri e litri di mesi di assenza, ritorno a scrivere sul blog di un progetto che sto portando avanti per una scuola delle mie zone.
Ricordate le voting machine del referendum lombardo? Quelle per le quali si sono spesi un sacco di soldi, date poi in comodato gratuito alle scuole una volta "riconvertite" in normali tablet? Ecco quelle.
Rimosso il software e tutti i device per il voto, i signori della Smartmatic hanno installato Ubuntu 16.04 LTS, facendo qualche setup custom, visto le scarse dotazioni dell'oggetto, per renderlo usabile.
A parte gli ovvi problemi di aggiornamento (Ubuntu 16 anche se LTS non è proprio così recente), il problema fondamentale è che un sistema operativo così configuarato non è adatto a un uso scolastico: la tastiera on screen, le applicazioni sviluppate per desktop rendono l'uso macchinoso e quindi molto difficoltoso se si pensa a studenti con qualche disabilità.

L'alternativa Tablet-Friendly

Se si pensa a un device senza tastiera fisica con un touchscreen, l'alternativa a Ubuntu come sistema operativo è abbastanza scontata: Android. Nello specifico, essendo un sistema a 64bit, ho optato per Android-x86, uno dei porting del robottino su x86.

 Preparare USB

Prima di procedere con l'installazione è necessario preparare un supporto USB con l'immagine di installazione. Al momento in cui scrivo è presente nella sezione Download la versione 8.1 RC2 (oreo). Scaricata la .iso, da Windows è possibile utilizzare rufus per scrivere l'immagine su USB. Da Linux invece possiamo tranquillamente utilizzare dd.

Accesso al BIOS

Il device è equipaggiato con efi, per cui si deve predisporre il boot da lì.
Armiamoci di una tastiera usb da collegare, che ci servirà per premere CANC all'avvio e accedere al bios. La password è smart?ecp. Una volta entrati nell'ultima schermata si deve selezionare il boot da EFI.
Una volta lanciata la shell efi, col comando map si dovrebbe vedere, tra le varie voci, quella dell'usb (di solito fs1). Per lanciare il boot:
fs1:
cd \efi\boot\

BOOTx86.EFI
Partirà il bootmanager android che consente l'avvio come Live o l'installazione.

Ecco un video che spiega come fare:


Setup del wifi

La scheda wifi del device (una broadcom) necessita di un file di configurazione aggiuntivo che va copiato in /system/lib/firmware/brcm/
Il file si deve chiamare brcmfmac43430-sdio.txt (come il nome del modulo). Ecco quello originale recupato dall'installazione linux:

#AP6212_NVRAM_V1.0_20140814_WIN8.1
# 2.4 GHz, 20 MHz BW mode

# The following parameter values are just placeholders, need to be updated.
manfid=0x2d0
prodid=0x0726
vendid=0x14e4
devid=0x43e2
boardtype=0x0726
boardrev=0x1101
boardnum=22
macaddr=00:90:4c:c5:12:38
sromrev=11
boardflags=0x00404201
xtalfreq=26000
nocrc=1
ag0=255
aa2g=1
ccode=CN

pa0itssit=0x20
extpagain2g=0

#PA parameters for 2.4GHz, measured at CHIP OUTPUT
pa2ga0=-168,7161,-820
AvVmid_c0=0x0,0xc8
cckpwroffset0=5

# PPR params
maxp2ga0=90
txpwrbckof=6
cckbw202gpo=0x5555
legofdmbw202gpo=0x77777777
mcsbw202gpo=0xaaaaaaaa

# OFDM IIR :
ofdmdigfilttype=7
# PAPD mode:
papdmode=2

il0macaddr=00:90:4c:c5:12:38
wl0id=0x431b

#OOB parameters
hostwake=0x40
hostrdy=0x41
usbrdy=0x03
usbrdydelay=100
deadman_to=0xffffffff
# muxenab: 0x1 for UART enable, 0x10 for Host awake
#muxenab=0x10
# CLDO PWM voltage settings - 0x4 - 1.1 volt
#cldo_pwm=0x4
glitch_based_crsmin=1

#sd_oobonly=1
sd_gpout=0
sd_gpval=1
sd_gpdc=0
Dopo aver creato sulla USB il file di testo con la configurazione della scheda wifi (brcmfmac43430-sdio.txt), ad esempio nella directory /wifi, procediamo a installarlo sul sistema.
Si va in console con Ctrl+Alt+F1.
cd /storage/
dovrebbe esserci una directory con un numero di serie (es F654-DAB8) o un nome che identifica la chiavetta USB (questo dipende dalla chiavetta).
cd F654-DAB8/wifi/
cp brcmfmac43430-sdio.txt /system/lib/firmware/brcm/
reboot
Il Tablet a questo punto si riavvia e tutto dovrebbe funzionare a dovere!

venerdì 12 agosto 2016

Qnap Recovery - DOM Replace




I fatti

Era un luminoso pomeriggio d'aprile ed ero alla ricerca di un posto ove salvare i backup delle VM vmware di sviluppo. Ad un certo punto, scavando nei rifiuti, emerge un qnap (TS-469U-RP),  l'ideale per i miei scopi: 4 dischi, due schede di rete, alimentazione ridondata e, cosa da non sottovalutare in un uffiico, abbastanza silenzioso. Purtroppo la bestia si trovava nel paradiso dell'hardware, non a caso.

L'analisi

Primo test: collego tensione. Nessuna esplosione e niente puzza di bruciato. Accendo, collegando un monitor e una tastiera usb. Compare il logo qnap ma poi tutto sembra congelato. Spengo brutalmente e riaccendo e qualcosa sembra partire: uncompressing linux... ok booting kernel . Pochi secondi dopo, schermata nera e cursore fisso.

L'azione 

Probabilmente il firmware è andato, penso. La procedura di recovery sul sito qnap prevede il boot da usb con una distro minimale per poi copiare su DOM (disk on module) l'immagine del firmware base.
Grazie a DriveDroid ho sempre a portata di mano, sullo smartphone, una iso di sysrescuecd. Collego, quindi il telefono via usb e faccio il boot.
L'entusiasmo si spegne presto: per qualche motivo, non ben definito, il video sparisce dopo pochi secondi dal boot. La cosa più semplice che mi viene in mente è di collegarmi via ssh.
In sysrescuecd per attivare l'ssh devo passare due parametri al boot
  • password di root, con rootpass=xxx;
  • indirizzo ip fisso, con  ethx=x.x.x.x/yy.
A quel punto da un altro pc della rete mi connetto col putty e zac! Funziona! Posso finalmente procedere al rispristino del firmware.
Al successivo reboot, il nas parte correttamente. Procedo con l'upgrade del firmware come da manuale.
Ennesimo reboot (e che è, windows?) e stavolta mi si presenta il prompt dell'efi. Qualcosa non quadra: il sistema non trova niente da cui bootare. Vuoi vedere che il famoso DOM non funziona ? Spengo tutto e apro il case.
Il DOM di cui si parla tanto non è altro che una memoria SSD da 512MB collegata ad una porta usb a pettine interna.

La DOM da 512MB

Ennesimo boot con sysrescuecd per copiare (con dd) dalla DOM a una chiavetta USB. Finita l'operazione collego una porta usb con la chiavetta al connettore interno. Questo perché bootando direttamente da usb esterno, il sistema (forse perchè si aspetta di lavorare da /dev/sda) non funziona.
In giallo il connettore USB

Accendo, attendo la fine del boot e, finalmente, il qnap è di nuovo operativo!





martedì 28 aprile 2015

SSH Pam Fun

Come già raccontavo nel post "Raspberry pi: two factor authentication", l'utilizzo dei Pluggable Authentication Module consente di affinare la fase di autenticazione.
Ben presto mi sono accorto che il dover inserire sempre un doppio codice (password e codice d'accesso), sebbene renda la connessione ssh più resistente al brute force, si può dire superfluo (e anche un po' fastidioso) quando si accede da postazione "sicura" (es: macchina locale).

Pam_access.so

Questo modulo consente di regolare l'accesso basandosi su login, indirizzo ip di provenienza, dominio ecc. Di norma le regole vengono prese dal file /etc/security/access.conf ma è possibile indicare un percorso differente tramite il parametro accessfile.
Nel file si definiscono, quindi, le regole per l'accesso. Se per ipotesi volessimo l'accesso consentito solo alla rete locale, la regola sarebbe:

debe@raspberrypi /etc/pam.d $ cat /etc/security/access-local.conf
# only allow from local IP range
+ : ALL : 192.168.1.0/24
+ : ALL : LOCAL
- : ALL : ALL
A questo punto se configurassi pam_access.so in /etc/pam.d/ssh come required mi troverei con ssh accessibile solo da rete locale. Ma quello che voglio io è bypassare il modulo di google nel caso pam_access.so abbia successo (cioè ci sia un match con le regole).
Ecco quindi la riga completa:
auth    [success=1 default=ignore] pam_access.so accessfile=/etc/security/access-local.conf
auth       required     pam_google_authenticator.so
Fra parentesi quadre si vede che in caso di successo, si indica al sistema di "saltare" il successivo passo (quello del Google authenticator). In tutti gli altri casi, il modulo e' ignorato.

venerdì 24 maggio 2013

Scherzi da ufficio: apertura del lettore cd.

La vita da ufficio, si sa, è noiosa. Per risollevare il morale, non c'è niente di meglio di un simpatico scherzetto.
Il prerequisito per la fattibilità della carognata, è la possibilità di accedere da remoto al pc del malcapitato di turno. Quindi munitevi di un account di dominio, un tool tipo psexec e questo simpatico script in vbscript da salvare come ejectCD.vbs

Const CDROM = 4
For Each d in CreateObject("Scripting.FileSystemObject").Drives
  If d.DriveType = CDROM Then
    Eject d.DriveLetter & ":\"  
  End If
Next

Sub Eject(CDROM)
  Dim ssfDrives
  ssfDrives = 17
  CreateObject("Shell.Application")_
    .Namespace(ssfDrives).ParseName(CDROM).InvokeVerb("Eject")
End Sub
Facciamo partire lo scherzone: si va in console nella directory dove avremo messo lo script e il psexec e si lanciano in sequenza i comandi:
C:\> psexec \\NomePcCollega -u utente -p password "cscript //H:CScript" 
C:\> psexec \\NomePcCollega -u utente -p password -c ejectCD.vbs
Il primo imposta di default l'esecutore dei vbs in console, il secondo fa partire lo script vero e proprio, dopo averlo copiato sul pc del malcapitato
Lo script va alla ricerca dei drive di tipo cdrom e per ognuno di essi lancia il comando Eject utilizzando la lettera che lo identifica (es F:\)

Schedulare l'apertura

Per rendere ancora più subdola la cosa, si può schedulare un task sul pc del collega per aprire il cdrom a intervalli regolari. Innanzitutto bisogna copiare lo script in una directory sul pc della povera vittima. Fatto? bene! Sempre con il psexec ci colleghiamo in console da remoto sul pc
C:\> psexec \\NomePcCollega -i -s -u utente -p password cmd.exe
oppure utilizzando il telnet se sul pc è attivo. Una volta ottenuta la console si schedula  un processo tramite il tool schtasks
C:\> schtask /Create /SC HOURLY /TN scherzone /TR ejectCD.vbs
In questo modo, se tutto va bene, abbiamo impostato l'apertura del cd del povero collega ogni ora.

Non nascondo che io l'ho messo in pratica con successo. Il malcapitato ha messo lo scotch sul lettore...

venerdì 10 maggio 2013

Clonare una VM con ESXi v5

Sono diventato il fortunato possessore di un server ESXi v5 sul quale far girare un po' di VM per i vari test. Una delle sfortune del suddetto server è che non ha tutte le fantastiche (e costose) features delle varie versioni superiori, in primis la clonazione. Fortunatamente grazie all'accesso ssh e un po' di console, si può tranquillamente portare a compimento l'operazione.

Attivare connessione SSH dal vSphere Client

Apriamo il client e ci connettiamo al server con un utente amministrativo. Nella tag configuration, si seleziona Security Profile e poi Properties.. nella sezione Services. Selezionando SSH e Options... si ha la possibilità di fare un bel Start. Fatto ciò ci si connette con utente root via ssh.

Clonare Disco

Giunti in console ci vengono in aiuto un sacco di tool. Il primo è vmkfstools che consente di fare la copia del disco virtuale. Requisito necessario è che la VM origine sia spenta, altrimenti non è possibile ottenere il lock esclusivo. Ci spostiamo quindi sul datastorage e lanciamo la copia del disco.
~ # cd /vmfs/volumes/4f466873-289b519c-2689-d067e5e5780e/vm1
/vmfs/volumes/4f466873-289b519c-2689-d067e5e5780e/vm1 # mkdir ../vm2
/vmfs/volumes/4f466873-289b519c-2689-d067e5e5780e/vm1 # vmkfstools -i vm1.vmdk ../vm2-vm2.vmkd
Destination disk format: VMFS zeroedthick
Cloning disk 'vm1.vmdk'...
Clone: 100% done.

Ecco fatto. A questo punto sarebbe sufficiente creare una nuova vm con il disco appena copiato. ma io sono pigro e quindi mi copio pure la configurazione.

Clonare Configurazione

Il file .vmx è un semplice file di testo. Si può quindi copiare tranquillamente e poi editare a mano.
/vmfs/volumes/4f466873-289b519c-2689-d067e5e5780e/vm1 # cp vm1.vmx ../vm2/vm2.vmx
si edita quindi il file vm2.vmx e si sostituiscono le occorrenze di nome, file del disco, file della memoria virtuale e file di swap, adattandoli a quelli appena creati, come ad esempio:
nvram = "vm2.nvram"
displayName = "vm2"
extendedConfigFile = "vm2.vmxf"
ide0:0.fileName = "vm2.vmdk"
sched.swap.derivedName = "/vmfs/volumes/4f466873-289b519c-2689-d067e5e5780e/XPPlcTestDebe/vm2-ab51994b.vswp"
 

Aggiungere la VM all'inventario

Abbiamo tutto quello che serve alla nuova VM. Registriamola, quindi, con il comando
~ # vim-cmd solo/registervm  /vmfs/volumes/4f466873-289b519c-2689-d067e5e5780e/vm2/vm2.vmx
che restituisce l'id della vm appena creata.
Attenzione che nel caso di windows bisogna poi cambiare l'hostname e il SID tramite il tool della sysinternals

Ciao
Debe

venerdì 3 maggio 2013

Cambiare IP al volo con Netsh + HTA

Quando scendo nei vari impianti dove lavoro mi capita di dover collegare il mio portatile su reti diverse (senza DHCP). Cambiare ogni volta l'indirizzo ip cliccando in giro per le varie voci di windows 7 non è abbastanza geek per me, per cui ho deciso di trovare un sistema più diretto.

Netsh

Questo tool, presente di serie sui sistemi windows dai tempi di xp, permette di configurare diversi aspetti della rete via shell (netsh -> net shell), tra cui ovviamente anche l'indirizzo ip.
Il netsh lavora per contesti, quindi prima di dare il comando vero e proprio si deve dichiarare in quale si lavora, nel nostro caso  interface ip. Per impostare l'indirizzo vero e proprio si utilizza set address con questa sintassi:
set address "nome interfaccia" static x.x.x.x y.y.y.y z.z.z.z
completando con il nome dell'interfaccia (di solito Local Area Network) e la famosa terna indirizzo ip, netmask e gateway.
Il comando completo quindi è:
netsh interface ip set address "Local Area Network" 192.168.1.10 255.255.255.0 192.168.1.1

HTA

Dato che comunque sono pigro e non ho voglia di scrivere un intero comando nella shell, ho pensato bene di accorciare il lavoro facendo una applicazione HTA (html application) che richiede le informazioni e lancia il comando di conseguenza.
L'HTA non è altro che una pagina web con un po' di VBScript dentro un file con estensione .hta.


<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>

 <meta content="text/html; charset=ISO-8859-1" http-equiv="content-type">
 <title>Change IP Address</title>
 <HTA:APPLICATION ID="ChengeIP"
 APPLICATIONNAME="ChangeIP"
 CAPTION="yes"
 BORDER="thick"
 SCROLL="no"
 SHOWINTASKBAR="yes"
 SINGLEINSTANCE="yes"
 SYSMENU="yes"
 MINIMIZEBUTTON="yes"
 MAXIMIZEBUTTON="no"
 >
 <script language="VBscript">
 Sub Window_onLoad
 window.resizeto 380,300
 end Sub
 function ChangeIP(lsNetworkName, lsIp, lsNM, lsGateway)
 DIM objShell
 if lsIp <> "" then
 set objShell = CreateObject("wscript.shell")
 iReturn = objShell.Run("CMD /S netsh interface ipv4 set address """ & lsNetworkName & """ static " & lsIp & " " & lsNM & " " + lsGateway , , True)
 set objShell = Nothing
 end if
 end function
 </script>
</head>
<body bgcolor="#008040">
<p style="text-align:center">
Cambio IP
</p>


<table style="text-align: left; margin-left: auto; margin-right: auto; height: 100px; width: auto;" border="0" cellpadding="2" cellspacing="2">

  <tbody>

 <tr>

      <td style="width: 100px; height: 30px;">Network Name:</td>

      <td style="text-align: center; height: 30px; width: 212px;"><input style="width:200" name="NetworkName" value="Local Area Connection"><br></td>

    </tr>

    <tr>

      <td style="width: 100px; height: 30px;">IP:</td>

      <td style="text-align: center; height: 30px; width: 212px;"><input style="width:200" name="IP"><br></td>

    </tr>

    <tr>

      <td style="width: 100px; height: 30px;">Netmask:</td>

      <td style="text-align: center; height: 30px; width: 212px;"><input style="width:200" value="255.255.255.0" name="Netmask"></td>

    </tr>

    <tr>

      <td style="width: 100px; height: 30px;">Gateway:</td>

      <td style="text-align: center; height: 30px; width: 212px;"><input style="width:200" value="" name="Gateway" ></td>

    </tr>

  </tbody>

</table>

<br>

<div style="text-align: center;"><button onclick="call ChangeIP(NetworkName.value, IP.value, Netmask.value, Gateway.value)" name="Cambia IP" type="button" style="CURSOR: hand">Cambia IP</button><br>

</div>
</body>
</html>

venerdì 19 aprile 2013

Raspberry PI: Two Factor Authentication via Google

Ebbene sì: sono uno dei fortunati possessori di una RaspberryPI. In realtà ne posseggo due, una utilizzata per i test e l'altra che se ne sta allegramente collegata al modem di casa per "fare cose". Quest'ultima è direttamente accessibile dalla Grande Rete attraverso la più classica delle connessioni SSH.
La raspberryPI e la maglietta. Stiloso!
Un bel giorno mi sovvenne l'idea di rendere il login un pochino più sicuro, introducendo la Two Factor Authentication:
un metodo di autenticazione che si basa sull'utilizzo congiunto di due metodi di autenticazione individuale.
Nello specifico i due metodi sarebbero:
  1. qualcosa che si conosce (la coppia user/password);
  2. qualcosa che si possiede (un generatore di codici);
Nulla di nuovo, insomma. Diversi istituti bancari da tempo utilizzano questa modalità per l'accesso all'e-banking. Anche Google consente di attivare il meccanismo sui suoi account utilizzando, come generatore di password temporanee, una applicazione per smartphone. Il tutto è generosamente rilasciato sotto forma di modulo PAM.
Ma veniamo alla pratica e cerchiamo di farla valere più della grammatica.
Prendiamo la raspberry sulla quale sta girando la raspbian e installiamo il modulo che serve.
debe@raspberrypi ~ $ sudo apt-get install libpam-google-authenticator
Fatto? Bene! Passiamo alla configurazione.
Lanciando il tool google-authenticator viene chiesto se si vuole utilizzare un token time-based (TOTP) cioè che cambia a intervalli regolari, oppure no.
Do you want authentication tokens to be time-based (y/n) n
https://www.google.com/chart?chs=200x200&chld=M|0&cht=qr&chl=otpauth://hotp/utente@host%3Fsecret%3DCHIAVESEGRETISSIMA
Your new secret key is: CHIAVESEGRETISSIMA
Your verification code is 123456
Your emergency scratch codes are:
  xxxxxxxx
  yyyyyyyy
  zzzzzzzz
  qqqqqqqq
  hhhhhhhh
 Do you want me to update your "/home/debe/.google_authenticator" file (y/n)
Se decidiamo per la prima strada, bisogna tener presente che il clock della macchina deve essere corretto e quindi, probabilmente, serve installare anche un client ntp.
Scelto il tipo, ci viene fornito il materiale per sincronizzare l'applicazione che genera i codici. Si può scansionare il QR Code direttamente in console (generato tramite la libreria libqrencode3), seguendo il link fornito, oppure inserendo manualmente la chiave di partenza. Al termine salviamo il file di configurazione.
Ora indichiamo a sshd di utilizzare il modulo appena installato. Aggiungiamo al file /etc/pam.d/sshd (dopo tutte le autenticazioni di default) la riga.
auth required pam_google_authenticator.so nullok
nullok serve per consentire l'accesso anche a chi non ha un file di configurazione (quindi solo con user-pass).
I codici di emergenza servono, con somma fantasia, in caso in cui non abbiamo a disposizione qualcosa per generare il codice.
Prima di far ripartire sshd manca ancora un passo: nel file /etc/ssh/sshd_config il parametro ChallengeResponseAuthentication deve essere yes.
Facciamo ripartire il servizio sshd e tentiamo il login:

debe@host1:~> ssh <indirizzoIP>
Password:
Verification code:
Linux raspberrypi 3.6.11+ #371 PREEMPT Thu Feb 7 16:31:35 GMT 2013 armv6l
debe@raspberrypi ~ $
Il verification code è quello generato dalla applicazione.

That's all folks!
Ciao
Debe