SSH bei Fehlversuchen blocken o. ä.?

Status
Für weitere Antworten geschlossen.

jahlives

Benutzer
Mitglied seit
19. Aug 2008
Beiträge
18.275
Punkte für Reaktionen
4
Punkte
0
Ja es sieht so aus, als würden sie iptables einbauen ...

Itari
Echt? Vollgenial, endlich kann man die Dienste auch auf der DS absichern. Bin schon ganz voller Vorfreude auf den neuen DSM
hm... stimmt eigentlich; am besten wäre blocken im Router. Der weiß aber nichts von dem Unfug, den der Angreifer auf der DS verzapft.
Ein Crack Versuch auf ein Login PW wird auch einem vorgelagerten Router auffallen. Der Cracker wird zuviele Verbindungen aufmachen müssen. Ein guter Router würde ab einem bestimmten Schwellenwert die IP temporär blocken oder zwischen zwei Verbindungen Zwangspausen einbauen.

Das Tüpfelchen auf dem i wäre natürlich wenn die DS Firewall die Router Regeln einstellen könnte: Also eine Meldung an den Router "Hei block mir diese IP für alle Services". ;)

Sonst halte ich es wie itari. Je früher du blockst desto besser. Wobei ich die Provider eher nicht in die Pflicht nehmen würde. Weil über meine Firewalls will ich die Kontrolle. Sonst musst du erstmal den Provider erreichen und ihn darum bitten eine zu scharfe Regel wieder zu entfernen (wenn die Provider aber ein Interface pro Zugang bieten würden, sähe die Sache schon wieder anders aus)
 

itari

Benutzer
Mitglied seit
15. Mai 2008
Beiträge
21.900
Punkte für Reaktionen
14
Punkte
0
Also mein Router hat ne Mini-Firewall und man könnte Dienste und Adresse gezielt filtern ... es wäre also nur ein wenig guter Wille und Statistikkenntnisse seitens des Herstellers nötig, dann würde das schon gehen ...

Fernsteuerungssoftware für Router gibt es auch, kenne allerdings nur grad was für Windows http://www.routercontrol.de/. Ansonsten läuft das ja auch unter dem Thema: "wie hacke ich einen Router?" :D

Itari
 

jahlives

Benutzer
Mitglied seit
19. Aug 2008
Beiträge
18.275
Punkte für Reaktionen
4
Punkte
0
Ich habe schon (leider sehr viel teurere) Router gesehen, die IP Blacklists im XML Format führen. Bei gewissen Modellen kann man diese Listen an der LAN Schnittstelle via ftp hochladen oder direkt auf dem Router mittels telnet/ssh darauf zugreifen.
Damit ist es ein "leichtes", dass alle Systeme (z.B. IDS oder die Dienste auf den Servern selber) Zugriffe an einer zentralen Stelle blockieren können
 

itari

Benutzer
Mitglied seit
15. Mai 2008
Beiträge
21.900
Punkte für Reaktionen
14
Punkte
0
Wenn die kleinen DS Multi-IP-fahig wären, dann könnte man auf sie auch ne Router-Software portieren, die das alles könnte ...

Itari
 

jahlives

Benutzer
Mitglied seit
19. Aug 2008
Beiträge
18.275
Punkte für Reaktionen
4
Punkte
0

itari

Benutzer
Mitglied seit
15. Mai 2008
Beiträge
21.900
Punkte für Reaktionen
14
Punkte
0
Wir könnten auch ein STOP-Schild einbauen ... ist ja gerade 'in' sowas ;)

Itari
 
Zuletzt bearbeitet:

PeterG

Benutzer
Mitglied seit
12. Sep 2008
Beiträge
472
Punkte für Reaktionen
0
Punkte
0
Also mein Router hat ne Mini-Firewall und man könnte Dienste und Adresse gezielt filtern ...

Das haben wohl die meisten Router, im Heimbereich allerdings in der Regel nicht - mit Standard Firmware - für den Anwender zugänglich und im Detail einstellbar. Ausserdem müsste es ja regelbasiert sein, also in der Art: Wenn auf Port xxxx mehr als yyy Verbindungen in ttt.s Sekunden geöffnet werden --> IP blocken dauerhaft/zeitweise. Und natürlich: Wenn Nachricht von DS über pösen Purschen, sofort zumachen ;)...

Gruß
Peter
 

jahlives

Benutzer
Mitglied seit
19. Aug 2008
Beiträge
18.275
Punkte für Reaktionen
4
Punkte
0
PHP Script für Log Files nach falschen SSH Logins absuchen und blocken

@PeterG
Dein "Problem" hat mir keine Ruhe gelassen und ich habe mir ein PHP Script gebastelt, das die Log Files nach "falschen" Logins durchsucht.
Voraussetzungen/Einschränkungen sind z.Z.

* ssh muss unter xinetd laufen
* läuft nur für ssh
* im xinetd conf file für ssh MUSS eine Zeile no_access = enthalten sein (kann auch leer sein hinter dem =)
* muss als root laufen
* kann erst reagieren wenn es aufgerufen wurde (wget oder php Shell-Interpreter)
* das Logfile sollte keine zu alten Einträge enthalten. Ich verwende dazu syslog-ng und logrotate (beide via ipkg). ** mit dem aktuellsten Code kann man festlegen wie alt die zu beachtenden Einträge maximal sein dürfen **

TODO:

* Erweiterung auf beliebige Protokolle
* Überwachung aller Services unter xinetd
* Gesperrte IPs nach bestimmter Zeit wieder löschen

WICHTIG:
Den Code habe ich mehrfach bei mir zu Hause getestet (DS408). Es wird aber an Systemfiles rumgeschrieben. Schlimmstenfalls startet der xinetd nicht mehr. Ich konnte in allen Test keine Fehler feststellen, trotzdem geht der Einsatz komplett auf die eigene Kappe ;)
PHP:
<?php
//Array of Protocols to search in the log files
$protocolsToWatch = array('sshd');
//Path of config directory for xinetd services
$xinetdServiceConf = '/opt/etc/xinetd.d';
//Array of filenames for xinetd services config files
$xinetdConfFiles = array('ssh');
//Path of log file
$logPath = '/opt/var/log/auth.log';
//Maximum allowed failed logins tries
$maxLogonTries = 2;
//Minimum time between last and second last failed login
$minTimeBetweenLogins = 10;
//Login Failures older than this will be ignored
$maxAgeLastLogin = 600;


/**
 * Initialo function to read full content of syslog file
 *
 * @param string path Path of the log file
 * @return array Content of Log File
 */
function getRawLog($path){
  return file($path);
}

/**
 * Function to filter the raw data from syslog for failed logins with defined protocols
 *
 * @param array $content Array of syslog lines
 * @return array A array of filtered log lines
 */
function filterRecords($content){
  $cont = array();
  foreach($content as $wert){
    if(stripos($wert,'failed') !== false){
      preg_match('/.*'.$protocolsToWatch[0].'.*/',$wert,$temp);
    }else{
      continue;
    }
    //$content[] = $temp[0];
    if(count($temp) > 0) $cont[] = $temp[0];
  }
  return $cont;
}

/**
 * Function to get IP adresses and access times from filtered log lines
 *
 * @param array $content Array of filtered log lines
 * @return array Array of IPs and Access Times => array[IP_ADDR] = array(TIME_OF_TRY,TIME_OF_TRY...)
 */
function processRecords($content){
  $cont = array();
  //var_dump($content);
  foreach($content as $wert){
    preg_match('/^([a-zA-z]*)\s(\d{1,2})\s(\d{1,2}:\d{1,2}:\d{1,2}).*?(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/',$wert,$temp);
    $cont[$temp[4]][] = strtotime($temp[1].' '.$temp[2].' '.$temp[3]);
  }
  return $cont;
}

/**
 * Function for check the log records (return of proccessRecords()) for violations of Login Rules
 *
 * This functions checks the log records and adds ip-addresss to be blocked if:
 * * more than $maxLogonTries failed attempts to login are detected AND
 * * the time difference between the last failed login and the second last is less than $minTimeBetweenLogins seconds
 * 
 * @param array $content Array of ips and access times from syslog array[IP_ADDR] = array(TIME_OF_TRY,TIME_OF_TRY...)
 * @return array Array of ips to be blocked
 */
function determineViolations($content){
  $cont = array();
  //var_dump($content);
  //exit;
  foreach($content as $key=>$wert){
    if(count($wert) >= $GLOBALS['maxLogonTries']){
      sort($wert);
      //var_dump($wert);
      //exit;
      if(($wert[count($wert)-1]-$wert[count($wert)-2] < $GLOBALS['minTimeBetweenLogins']) && (time() - $wert[count($wert)-1] <= $GLOBALS['maxAgeLastLogin'])){
        $cont[] = $key;
      }else{
        continue;
      }
    }
  }
  //var_dump($cont);
  //exit;
  return $cont;
}

/**
 * Function to block a certain IP Adress in xinet Service Conf
 *
 * This function expects a array with IP addresses to block
 * @param array $ip
 * @return boolean true for block action and false for no block action
 */
function blockIP($ip){
  //var_dump($ip);
  //exit;
  $block = false;
  $str = '';

  $content = file($GLOBALS['xinetdServiceConf'].'/'.$GLOBALS['xinetdConfFiles'][0]);
  $t = array();
  $schl = null;
  foreach($content as $key=>$wert){
    if(strpos($wert,'no_access') !== false){
      preg_match_all('/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/',$wert,$t);
      //var_dump($t);
      //exit;
      break;
    }
  }
  //var_dump($t);
  //exit;
  foreach($ip as $ipp){
    if(in_array($ipp,$t[0]) === false){
      $block = true;
      $str .= $ipp.' ';
    }
  }
  $content[$key] = 'no_access = '.implode(' ',$t[0]).' '.$str."\n";
  if($block === true){
    $t = implode('',$content);
    /*echo '<pre>';
    echo $t;
    echo '</pre>';
    exit;*/
    $fp = fopen($GLOBALS['xinetdServiceConf'].'/'.$GLOBALS['xinetdConfFiles'][0],'w');
    fwrite($fp,$t);
    fclose($fp);
    exec('kill -HUP `pidof xinetd`');
    return true;
  }else{
    return false;
  }
}
var_dump(blockIP((determineViolations((processRecords(filterRecords(getRawLog($logPath))))))));
?>
Noch ein Tipp:
Gegen Ende des Codes findest du einen auskommentierten Block. Diesen würde ich aktivieren damit du schauen kannst, dass der String für die Datei fehlerfrei ausschaut
PHP:
/*echo '<pre>';
  echo $t;
  echo '</pre>';
  exit;*/
Einfach die Kommentarzeichen entfernen. Wenn es gut ausschaut und alle Pfade korrekt sind, dann kannst du es wieder auskommentieren und das Script in die Datei schreiben lassen.

Gruss

tobi

p.s. Code auch als Attachment. Einfach txt in php umbenennen. Obigen Code habe ich eingefügt, damit sich jeder überzeugen kann, dass ich keine "Schweinereien" auf der DS veranstalte ;)
 

Anhänge

  • logScan.txt
    4,2 KB · Aufrufe: 3
Zuletzt bearbeitet:
Status
Für weitere Antworten geschlossen.
 

Kaffeautomat

Wenn du das Forum hilfreich findest oder uns unterstützen möchtest, dann gib uns doch einfach einen Kaffee aus.

Als Dankeschön schalten wir deinen Account werbefrei.

:coffee:

Hier gehts zum Kaffeeautomat