Archivi per la categoria ‘Script’

Cerberus: crack archives rar, zip, 7z with bash

giovedì, 31 maggio 2012




  • Google Plus
  • Twitter
  • Facebook
  • Reddit
  • RSS

Lo script seguente cerca la password di un archivio 7z, rar o zip, attraverso metodi di forza bruta e attacchi con dizionario. Per la serie “che cosa possiamo fare con Bash“.

#!/bin/bash
#=====================================================================================
#
#          Title: cerberus
#         Author: Giacomo Trudu aka `Wicker25` - wicker25 [at] gmail [dot] com
#           Site: http://www.hackyourmind.org/
#        License: GNU Lesser General Public License v3 (LGPL3)
#        Version: 0.6.3
#
#  = Version 0.6.3 =
#   + improved analysis resuming
#
#  = Version 0.6.2 =
#   + changed speed unit to pwds/s
#
#  = Version 0.6.1 =
#   + fixed spinner animation
#
#  = Version 0.6 =
#   + improved statistics output
#
#  = Version 0.5.4 =
#   + improved performance with large dictionary files
#
#=====================================================================================

# Versione
name='cerberus';
version='0.6.3';

# Informazioni sull'attacco
mode='incremental';
mode_opt='';
mode_format='';
mode_resume=false;
mode_length=6;
mode_jobs=( 1 1 );
decrypt='';

# Decrittatore
decrypt_7z='7z t -y -p%s %s';
decrypt_rar='unrar t -y -p%s %s';
decrypt_zip='7z t -y -p%s %s';

# Risposta affermativa del decrittatore
password_found="Everything is Ok|All Ok";

# Alfabeto
spinner_chars=( '\' '|' '/' '-' );
spinner=0;

# Unità del tempo
time_factors=( 31536000 2628000 604800 86400 3600 60 1 );
time_names=( 'years' 'months' 'weeks' 'days' 'hours' 'minutes' 'seconds' );

# Stato dell'analisi (none, found or interrupted)
status='none';

# Contatore delle password analizzate
count=0;

# Parametri usati per le statistiche
stats_speed='-';
stats_eta='-';
last_count=0;
last_time=`date +%s`;


# Aggiorna le statistiche dell'analisi
function update_stats {

   # Calcolo la velocità di analisi
   speed=`echo "scale = 3; ( $count - $last_count ) / ( $time - $last_time )" | bc`;

   # Converto la velocità in passwords/minuto
   stats_speed="${speed/.*} pwds/s";

   # Calcolo il tempo rimanente alla fine dell'analisi
   eta=`echo "scale = 3; ( $combinations - $count ) / $speed" | bc`;
   stats_eta='';

   # Costruisco la stringa del tempo trascorso
   elapsed="${eta/.*}";

   let 'precision = 2';

   for k in `seq 0 6`;
   do
      let 'value = elapsed / time_factors[k]';

      if [ $value -ne 0 ];
      then
         if [ $value -gt 1 ]; 
         then
            stats_eta="$stats_eta$value ${time_names[$k]} ";
         else
            stats_eta="$stats_eta$value ${time_names[$k]%?} ";
         fi;

         if [ $precision -gt 1 ];
         then
            let 'precision--';
         else
            break;
         fi;
      fi;

      let 'elapsed %= time_factors[k]';
   done;

   if [ -n "$stats_eta" ];
   then
      stats_eta="${stats_eta%?}";
   else
      stats_eta='-';
   fi;

   let 'last_count = count';
}


# Prova la password sull'obiettivo
function test_password {

   # Incremento il contatore delle password testate
   let 'count++';

   # Formatto la password
   if [ -n "$mode_format" ];
   then
      password=`echo "$password" | sed -e "$mode_format"`;
   fi;

   # Controllo che siano passati almeno 3 secondi
   time=`date +%s`;

   if [ `expr $time - $last_time` -ge 1 ];
   then
      # Aggiorna le statistiche dell'analisi
      update_stats;

      # Controllo se un altro processo ha già trovato la password
      if [ -s "$meta_password" ];
      then
         password=`cat "$meta_password"`;
         status='found';
      fi;

      # Memorizzo i progressi dell'analisi
      echo -e "$mode\n$mode_opt\n$mode_length\n$mode_format\n$i $to" > "$meta";

      # Memorizzo l'istante corrente per il prossimo controllo
      let 'last_time = time';

      # Scelgo il carattere dello spinner
      spinner_current="${spinner_chars[`expr $spinner % 4`]}";

      # Stampo i progressi dell'analisi
      printf "\r\033[K%s Checking '%s'... (%d checked, speed %s, eta %s)" "$spinner_current" "$password" $count "$stats_speed" "$stats_eta";

      # Modifico il carattere dello spinner
      let 'spinner++';
   fi;

   # Provo a decrittare l'archivio usando la password corrente
   printf -v password "%q" $password;

   if `printf "$decrypt" "$password" "$target"` 2> /dev/null | grep -Eiq "$password_found";
   then
      echo "$password" > "$meta_password";
      status='found';
   fi;
}


# Cattura il segnale di uscita
function control_attack {

   read -s -n1 -t0.001 key;

   if [ "$key" == $'\x1b' ];
   then
      status='interrupted';
   fi;
}


# Attacco forza bruta
function bruteforce_attack {

   # Costruisco l'alfabeto per l'attacco
   if [ -z $mode_opt ];
   then
      mode_opt='alnum';
   fi;

   case $mode_opt in
      num)      symbols=( {0..9} );;
      alpha)    symbols=( {a..z} );;
      alcase)   symbols=( {a..z} {A..Z} );;
      alpun)    symbols=( {a..z} ' ' '(' ')' '.' ';' ':' '!' '?' '/' '\' );;
      alcpun)   symbols=( {a..z} {A..Z} ' ' '(' ')' '.' ';' ':' '!' '?' '/' '\' );;
      alnum)    symbols=( {a..z} {0..9} );;
      alcnum)   symbols=( {a..z} {A..Z} {0..9} );;
      pun)      symbols=( ' ' '(' ')' '.' ';' ':' '!' '?' '/' '\' );;
      all)      symbols=( {a..z} {A..Z} {0..9} ' ' '(' ')' '.' ';' ':' '!' '?' '/' '\'  );;
   esac;

   symbols_l=${#symbols[*]};

   # Calcolo il numero delle combinazioni da provare
   if [ $mode == 'incremental' ];
   then
      let 'combinations = 0';

      for i in `seq 1 $mode_length`;
      do
         let 'combinations += symbols_l ** i';
      done;
   else
      let 'combinations = symbols_l ** mode_length';
   fi;

   # Carico eventuali configurazioni preesistenti
   if [ $mode_resume == false ];
   then
      total=`echo "scale = 2; $combinations / ${mode_jobs[1]} + 1" | bc`;
      total=${total/.*};

      let 'from += ( mode_jobs[0] - 1 ) * total';
      let 'to = from + total';
   fi;

   # Aggiusto i valori in modo da non uscire dalle combinazioni previste
   if [ $from -lt 0 ];
   then
      let 'from = 0';
   fi;

   if [ $to -gt $combinations ];
   then
      let 'to = combinations';
   fi;

   # Calcolo le combinazioni restanti
   let 'combinations = to - from';

   # Informazioni sull'attacco
   echo "Combinations: $combinations (from `expr $from + 1` to $to)";

   # Ciclo principale
   let 'i = from';

   while [ $i -lt $to ];
   do
      # Catturo il segnale di uscita
      control_attack;

      # Controllo se la ricerca è terminata
      if [ $status != 'none' ];
      then
         break;
      fi;

      # Se è stata richiesta, applico la ricerca incrementale
      let 'current = i';

      if [ $mode == 'incremental' ];
      then
         for j in `seq 1 $mode_length`;
         do
            let 'val = symbols_l ** j';

            if [ $current -ge $val ];
            then
               let 'current -= val';
            else
               break;
            fi;
         done;

         let 'password_l = j - 1';
      else
         let 'password_l = mode_length - 1';
      fi;

      # Costruisco la nuova password
      password='';

      for j in `seq 0 $password_l`;
      do
         let 'val = current % symbols_l';

         if [ $val -ge 0 ];
         then
            printf -v password "%s%s" "${symbols[$val]}" "$password";
         fi;

         let 'current /= symbols_l';

         if [ $current -lt 0 ];
         then
            break
         fi;
      done;

      # Provo la nuova password sull'obiettivo
      test_password;

      # Passo alla prossima password
      let 'i++';
   done;
}


# Attacco con dizionario
function dictionary_attack {

   # Leggo il numero delle parole presenti nel dizionario
   combinations=`wc -l "$mode_opt" | awk '{ print $1 }'`;

   # Carico eventuali configurazioni preesistenti
   if [ $mode_resume == false ];
   then
      total=`echo "scale = 2; $combinations / ${mode_jobs[1]} + 1" | bc`;
      total=${total/.*};

      let 'from = ( mode_jobs[0] - 1 ) * total';
      let 'to = from + total';
   fi;

   # Aggiusto i valori in modo da non uscire dal dizionario
   if [ $from -lt 0 ];
   then
      let 'from = 0';
   fi;

   if [ $to -gt $combinations ];
   then
      let 'to = combinations';
   fi;

   # Calcolo le combinazioni restanti
   let 'combinations = to - from';

   # Informazioni sull'attacco
   echo "Combinations: $combinations (from `expr $from + 1` to $to)";

   # Provo le parole contenute nel dizionario
   exec 3< "$mode_opt";

   let 'i = 0';

   while read -u 3 line;
   do
      # Catturo il segnale di uscita
      control_attack;

      # Controllo se la ricerca è terminata
      if [ $status != 'none' ];
      then
         break;
      fi;

      # Ignoro le password già testate
      if [ $i -ge $from ];
      then
         # Provo la nuova password sull'obiettivo
         password="`echo $line | sed 's/[\n\r]//g'`";

         test_password;
      fi;

      let 'i++';
   done;
}


# Processo i parametri
usage="Usage: `basename $0` [-b <num|...|all>|-i <num|...|all>|-d <file>] [-l <length>] [-j <current,total>] [-p <format>] [-f <type>] [-r] [-h] -t <target>";

if [ $# -eq 0 ];
then
   echo $usage;
   exit 1;
fi;

while getopts 'b:i:d:f:l:j:p:t:rvh' opt;
do
   case $opt in

      b) mode='bruteforce';

         if [[ ! "$OPTARG" =~ ^(num|alpha|alcase|alpun|alcpun|alnum|alcnum|pun|all)$ ]];
         then
            echo "Invalid brute force attack!";
            echo $usage;
            exit 1;
         fi;

         mode_opt="$OPTARG";;

      i) mode='incremental';

         if [[ ! "$OPTARG" =~ ^(num|alpha|alcase|alpun|alcpun|alnum|alcnum|pun|all)$ ]];
         then
            echo "Invalid incremental brute force attack!";
            echo $usage;
            exit 1;
         fi;

         mode_opt="$OPTARG";;

      d) mode='dictionary';

         if [ ! -r "$OPTARG" ];
         then
            echo "Invalid dictionary file!";
            echo $usage;
            exit 1;
         fi;

         directory=`dirname $OPTARG`;
         name=`basename $OPTARG`;
         mode_opt="`cd "$PWD"; cd "$directory"; pwd`/$name";;

      f) case $OPTARG in
            7z)    decrypt=$decrypt_7z;;
            rar)   decrypt=$decrypt_rar;;
            zip)   decrypt=$decrypt_zip;;
         esac;;

      r) mode_resume=true;;

      l) if [[ ! "$OPTARG" =~ ^[0-9]*$ ]];
         then
            echo "Invalid length!";
            echo $usage;
            exit 1;
         fi;

         mode_length="$OPTARG";;

      p) mode_format="$OPTARG";;

      j) if [[ ! "$OPTARG" =~ ^([1-9]+),([1-9]+)$ ]] || [ ${BASH_REMATCH[1]} -gt ${BASH_REMATCH[2]} ];
         then
            echo "Invalid process splitting!";
            echo $usage;
            exit 1;
         fi;

         mode_jobs=( "${BASH_REMATCH[1]}" "${BASH_REMATCH[2]}" );;

      t) target="$OPTARG";;

      v) echo "$name v$version";
         exit 0;;

      h|?)  echo -e "$usage\n";
            echo '  -b <num|alpha|alcase|alpun|alcpun|alnum|alcnum|pun|all>     Brute force attack';
            echo '  -i <num|alpha|alcase|alpun|alcpun|alnum|alcnum|pun|all>     Incremental brute force attack';
            echo '  -d <file>                                                   Dictionary attack';
            echo '  -f <7z|rar|zip>                                             Target format';
            echo '  -l                                                          Length of passwords';
            echo '  -p <format>                                                 Format passwords';
            echo '  -j <current,total>                                          Split process';
            echo '  -r                                                          Resume previous attack';
            echo '  -v                                                          Print version';
            echo '  -h                                                          Print this message';
            echo;
            exit 0;;
   esac;
done;

# Controllo la validità dell'obiettivo
if [ -r "$target" ];
then
   # Costruisco i percorsi ai file d'appoggio
   meta="$target.meta${mode_jobs[0]}";
   meta_password="$target.password";

   # Controllo se la password è già stata trovata
   if [ -s "$meta_password" ];
   then
      password=`cat "$meta_password"`;
      echo "Password already found: $password";
      exit 1;
   fi;

   # Se non è stato scelto il decrittatore imposto quello più adatto al file
   if [ -z "$decrypt" ];
   then
      format=`file -ib "$target"`;

      if [[ "$format" =~ ^application/.*7z ]];
      then
         decrypt=$decrypt_7z;

      elif [[ "$format" =~ ^application/.*rar ]]
      then
         decrypt=$decrypt_rar;

      elif [[ "$format" =~ ^application/.*zip ]]
      then
         decrypt=$decrypt_zip;
      else
         echo "Unknown target format!";
         exit 1;
      fi;
   fi;

   # Continuo l'attacco iniziato in precedenza
   if [ $mode_resume == true ];
   then
      echo "Resuming...";

      if [ -r "$meta" ];
      then
         mode=`head -1 "$meta"`;
         mode_opt=`sed -n "2p" "$meta"`;
         mode_length=`sed -n "3p" "$meta"`;
         mode_format=`sed -n "4p" "$meta"`;
         from=`tail -1 "$meta" | awk '{ print $1 }'`;
         to=`tail -1 "$meta" | awk '{ print $2 }'`;
      else
         echo "Invalid meta file!";
         exit 1;
      fi;
   fi;

   # Inizio l'attacco sull'obiettivo
   case $mode in
      bruteforce|incremental)   bruteforce_attack;;
      dictionary)               dictionary_attack;;
   esac;

   # Memorizzo i progressi dell'analisi
   echo -e "$mode\n$mode_opt\n$mode_length\n$mode_format\n$i $to" > "$meta";

   # Mostro all'utente i risultati dell'elaborazione
   case $status in
      none)          echo -e "\nPassword not found! ($count checked)";;
      found)         echo -e "\nPassword found: '$password' ($count checked)";;
      interrupted)   echo -e "\nInterrupted. ($count checked)";;
   esac;
else
   echo "Invalid target!";
fi;

(continua…)

Javascript: a flexible module pattern

venerdì, 4 maggio 2012




  • Google Plus
  • Twitter
  • Facebook
  • Reddit
  • RSS

La programmazione modulare è un paradigma di programmazione che permette di definire un programma come l’insieme di più unità indipendenti tra di loro, chiamate appunto “moduli“.
In questo contesto è possibile sviluppare un software lavorando singolarmente sulle sue componenti, isolando funzioni e strutture tra loro affini e favorendo la riusabilità del codice stesso.
Inoltre diventa estremamente semplice estendere le funzionalità del programma con la creazione di nuovi moduli o la modifica di quelli già esistenti.

Javascript non ha un supporto nativo alla programmazione modulare, ma grazie alla sua estrema flessibilità è possibile attuare questo paradigma seguendo il cosidetto “module pattern“. Quest’ultimo prevede la creazione di una classe singleton, con una propria visibilità (o scope) che garantisce il principio dell’information hiding.

Il seguente codice è una mia personale implementazione del module pattern.

/** Modulo per la gestione di un veicolo **/
( function ( BASE, NAME ) {

BASE[ NAME ] = ( function () {

   /** PRIVATO **/
   var fuel = 0;

   /** PUBBLICO **/
   var setFuel = function ( value ) { fuel = value; };
   var getFuel = function () { return fuel; };
   var move = function () { fuel -= 1; };

   // Restituisco i membri e i metodi pubblici
   return {

      setFuel: setFuel,
      getFuel: getFuel,
      move: move
   };

}() );

}( window, 'Vehicle' ) );

(continua…)

Javascript: formatting date like PHP

giovedì, 19 aprile 2012




  • Google Plus
  • Twitter
  • Facebook
  • Reddit
  • RSS

Un’implementazione Javascript della funzione date di PHP.

/*
    Title --- formatdate.js

    Copyright (C) 2012 Giacomo Trudu - wicker25[at]gmail[dot]com

    This script is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation version 3 of the License.

    This script is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with this script. If not, see <http://www.gnu.org/licenses/>.

	= Version 1.1 =
	 + improved performance
*/

/** Formatta un timestamp o un'oggetto Date  **/
var formatDate = function ( format, time, r ) {

   // Preparo i parametri
   r = ( typeof( r ) != 'undefined' && r );
   var date = ( typeof( time ) != 'undefined' ) ? ( time instanceof Date ? time : new Date( time * 1000 ) ) : new Date;

   // Calcolo il numero dei secondi dall'inizio dell'anno
   var yearSecs = ( date - new Date( date.getFullYear(), 0, 1 ) ) / 1000;

   // Estraggo alcune informazioni dalla formattazione standard
   var meta = String( date ).match( /^.*?([A-Z]{1,4})([\-+]\d{4}) \(([A-Z]+)\).*$/ );

   // Estraggo le informazioni
   date = {

      d : date.getDate(),
      D : date.getDay(),
      m : date.getMonth(),
      y : date.getFullYear(),
      l : ( new Date( date.getFullYear(), 1, 29 ).getMonth() === 1 | 0 ),
      h : date.getHours(),
      M : date.getMinutes(),
      s : date.getSeconds(),
      u : date.getMilliseconds(),
      t : date.getTime(),
      z : date.getTimezoneOffset()
   };

   // Stringa della data formattata
   var str = '';

   // Riempie di zeri le cifre alla sinistra di un numero
   var pad = function ( value, len ) {

      return ( '000000000' + String( value ) ).slice( -len );
   };

   // Parametri della formattazione
   var fmt_values = {

      d : function () { return pad( date.d, 2 ); },
      D : function () { return [ 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat' ][ date.D ]; },
      j : function () { return date.d; },
      l : function () { return [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' ][ date.D ]; },
      N : function () { return date.D + 1; },
      S : function () { return [ 'th', 'st', 'nd', 'rd' ][ date.d % 10 > 3 ? 0 : ( date.d < 10 || date.d > 20 ) * date.d % 10 ]; },
      w : function () { return date.D; },
      z : function () { return Math.ceil( yearSecs / 86400 ); },
      W : function () { return Math.ceil( yearSecs / 604800 ); },
      F : function () { return [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ][ date.m ]; },
      m : function () { return pad( date.m + 1, 2 ); },
      M : function () { return [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ][ date.m ]; },
      n : function () { return date.m + 1; },
      t : function () { return [31, (date.l ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][ date.m ]; },
      L : function () { return date.l; },
      Y : function () { return date.y; },
      y : function () { return String( date.y ).slice( -2 ); },
      a : function () { return ( date.h < 12 ? 'am' : 'pm' ); },
      A : function () { return ( date.h < 12 ? 'AM' : 'PM' ); },
      g : function () { return date.h % 12 || 12; },
      G : function () { return date.h; },
      h : function () { return pad( date.h % 12 || 12, 2 ); },
      H : function () { return pad( date.h, 2 ); },
      i : function () { return pad( date.M, 2 ); },
      s : function () { return pad( date.s, 2 ); },
      u : function () { return date.u * 1000; },
      I : function () { return ( date.m > 2 && date.m < 10 || ( date.m == 2 && date.D - date.d >= 8 - 1 ) ); },
      O : function () { return meta[2]; },
      P : function () { return meta[2].slice( 0, -2 ) + ':' + meta[2].slice( -2 ); },
      T : function () { return meta[3]; },
      Z : function () { return -date.z * 60; },
      c : function () { return ( !r ? formatDate( 'Y-m-d\\TH:i:sP', time, true ) : null ); },
      r : function () { return ( !r ? formatDate( 'D, d M Y H:i:s O', time, true ) : null ); },
      U : function () { return Math.floor( date.t / 1000 ); }
   };

   // Divido la stringa di formattazione in token tenendo conto dei caratteri di escape
   var tokens = format.match( /(\\.|.)/gi );

   // Costruisco la stringa del tempo
   for ( var i = 0; i < tokens.length; i++ )
      str += ( tokens[i] in fmt_values ? fmt_values[ tokens[i] ]() : ( tokens[i].length == 1 ? tokens[i] : tokens[i][1] ) );

   return str;
};

Esempio di utilizzo:

formatDate( 'j, n, Y' ); // => '10, 3, 2001'
formatDate( 'F j, Y, g:i a' ); // => 'March 10, 2001, 5:16 pm'
formatDate( 'd/m/Y', 1230000000 ); // => '23/12/2008'
formatDate( 'H:i', new Date() ); // => '19:52'
formatDate( 'c' ); // => '2012-04-20T19:12:35+02:00'
formatDate( '\\i\\t \\i\\s \\t\\h\\e jS \\d\\a\\y.' ); // => 'it is the 20th day.'

Oppure si può integrare direttamente al tipo Date:

Date.prototype.format = function ( format ) { return formatDate( format, this ); };

// Esempio:
var timestr = new Date().format( 'd/m/Y' );

Load dynamically MathJax with JQuery.getScript()

sabato, 10 marzo 2012




  • Google Plus
  • Twitter
  • Facebook
  • Reddit
  • RSS

Un problema che mi ha dato del filo da torcere… Maledetti percorsi assoluti.

<html>
<head>
    <script type="text/javascript" src="lib/jquery.js"></script>
    <title>Titolo della pagina</title>
</head>
<body>

<div>\[ \left [ - \frac{\hbar^2}{2 m} \frac{\partial^2}{\partial x^2} + V \right ] \Psi
= i \hbar \frac{\partial}{\partial t} \Psi \]</div>

<a id="loadMathJax" href="#">Carica MathJax</a>

<script type="text/javascript">
<!--

    // Percorso alla libreria
    var MathJax_path = 'lib/mathjax/';

    // Carico MathJax alla pressione del link
    $('#loadMathJax').click( function () {

        // Creo la configurazione di MathJax
        var config =

            "MathJax.Ajax.config.root = '" + MathJax_path + "';" + // <- Importante
            "MathJax.Hub.Config( { " +
            "    extensions: [ 'tex2jax.js' ], " +
            "    jax: [ 'input/TeX', 'output/HTML-CSS' ], " +
            "    tex2jax: { " +
            "      inlineMath: [ ['\[', '\]'] ], " +
            "      processEscapes: true " +
            "    }, " +
            "});";

        $('head').append( $('<script></script>').attr( 'type', 'text/x-mathjax-config' ).text( config ) );

        // Carico la libreria
        $.getScript( MathJax_path + 'MathJax.js?config=TeX-AMS-MML_HTMLorMML', function () {

            // Modifico il pulsante
            $('#loadMathJax').unbind( 'click' ).css( 'text-decoration', 'line-through' );
        } );
    } );

-->
</script>

</body>
</html>

Meteosat sul desktop: bash + wget + imagemagick

sabato, 13 novembre 2010




  • Google Plus
  • Twitter
  • Facebook
  • Reddit
  • RSS

Meteosat Europa


Questo semplice script scarica ad intervalli regolari un’immagine presa dal web e la copia sul nostro sfondo. Vi chiedete a quale scopo? Stavo curiosando tra le immagini della terra fornite da Meteosat, che si aggiornano ogni 15 minuti, quando ho pensato di aggiungerle direttamente al mio desktop.

(continua…)

Creiamo il nostro Muletto: Debian + OpenSSH + Deluge-web

martedì, 28 settembre 2010




  • Google Plus
  • Twitter
  • Facebook
  • Reddit
  • RSS

Avete un vecchio PC che da anni utilizzate solo come fermaporte? Beh.. Riciclatelo!
In questa breve guida vi spiegherò come configurare un semplice Muletto per il download attraverso BitTorrent, gestito in remoto tramite protocollo SSH.

Ecco di cosa abbiamo bisogno:

  1. L’unità centrale del PC menzionato sopra, munito di scheda di rete (costo approssimativo: 10€).
  2. Una linea ADSL decente con annesso Router (un’uscita ethernet servirà al nuovo server).
  3. Una copia su CD/DVD del sistema operativo Debian (o Ubuntu Server, o quello che volete).

(continua…)



Powered by Linux   Powered by Apache   Powered by MYSQL   Powered by PHP   Viewable With Any Browser   Hacker Culture   Creative Commons Licensed