May the brute-force be with you, Botnet!

Das Internet ist voller böser Jungs und Mädchen. Ich arbeite für eine Firma, die mit ihren Produkten Firmen und Menschen hilft, sich gegen diese Bösewichte zu wehren. Doch auch privat betreibe ich eigene Server und Dienste. Da ich ein wenig zu paranoid bin, nutze ich meinen eigenen Mailserver und keine gmail oder andere „free“-mail adresse.

Nicht jeder kann einen eigenen Server betreiben. Denn wenn man nichts davon versteht, kann man es auch gleich einem Dritten überlassen, der weiß, was er tut. Falls nicht, ist man mit gmail doch besser aufgehoben.

Auf meinem Server befinden sich daher noch andere Benutzer, die gerne freemail-frei emailen wollen. Sie kennen mich alle persönlich und vertrauen mir, dass ich keinen Schindluder mit ihren Daten treibe.

Auf meinem Server läuft das IDS/IPSfail2ban„. Das ist ein System, das brute-force Angriffe auf Passworte erkennt und die Übeltäter automatisch blockiert. Das ist schön und dient als erste Verteidigungslinie. Aber so richtig Sicherheit bringt es nicht.

Ich sehe in den Logs, dass versucht wird, Passworte herauszufinden. Hier ein paar echte Logs aus dem Server, in der ich nur die Domain des potentiellen Opfers geändert habe:

2019-02-03 10:11:26 plain authenticator failed for (127.0.0.1) [191.102.28.34]: 535 Incorrect authentication data (set_id=info@victim.tld)
2019-02-03 10:11:28 login authenticator failed for (127.0.0.1) [191.102.28.34]: 535 Incorrect authentication data (set_id=info@victim.tld)
2019-02-03 10:31:16 plain authenticator failed for isp-31-222-13-236.saowifi.net (127.0.0.1) [31.222.13.236]: 535 Incorrect authentication data (set_id=info@victim.tld)
2019-02-03 10:31:16 login authenticator failed for isp-31-222-13-236.saowifi.net (127.0.0.1) [31.222.13.236]: 535 Incorrect authentication data (set_id=info@victim.tld)
2019-02-03 11:18:28 plain authenticator failed for (127.0.0.1) [88.81.93.221]: 535 Incorrect authentication data (set_id=info@victim.tld)
2019-02-03 11:18:29 login authenticator failed for (127.0.0.1) [88.81.93.221]: 535 Incorrect authentication data (set_id=info@victim.tld)
2019-02-03 11:55:13 plain authenticator failed for (127.0.0.1) [186.148.80.202]: 535 Incorrect authentication data (set_id=info@victim.tld)
2019-02-03 11:55:15 login authenticator failed for (127.0.0.1) [186.148.80.202]: 535 Incorrect authentication data (set_id=info@victim.tld)
2019-02-03 12:15:34 plain authenticator failed for (127.0.0.1) [178.219.123.243]: 535 Incorrect authentication data (set_id=info@victim.tld)
2019-02-03 12:15:35 login authenticator failed for (127.0.0.1) [178.219.123.243]: 535 Incorrect authentication data (set_id=info@victim.tld)

Wie man sieht, wird pro IP genau zwei Mal probiert und dann aufgegeben. Das liegt daran, dass man ab da Gefahr läuft, von einem IDS/IPS entdeckt zu werden. Wer aber genügend IPs zur Verfügung hat, wechselt eben von einer IP zur anderen.

Diese IPs bekommt man über Botnetze oder Anonymisierungsdienste. Gegen die kann man sich kaum zur Wehr setzen, ohne echte Benutzer auszusperren.

Es hilft also nur, gute Passworte zu nutzen und für jeden Dienst ein eigenes. Und wann immer es möglich ist, auf eine Zwei-Faktor-Authentifizierung zu setzen.

Werbeanzeigen
May the brute-force be with you, Botnet!

Bandbreite anzeigen

Die aktuell genutzte Bandbreite eines Linux Systems wird ermittelt als übertragene Bytes pro Zeitabstand. Einen „aktuellen“ Wert zum Auslesen gibt es nicht, man muss also die Bandbreite aus zwei Deltawerten übertragener Bytes berechnen. Ich habe ein Script gefunden und etwas erweitert. Es zeigt die Bandbreite für alle Interfaces in Kbits und Mbits an. Das Script ist simpel gehalten und ohne Parameter, die irgend etwas steuern. Aber das kann man ja nachträglich einbauen. Wenn man will.

#!/bin/bash                                                                          

intervalo=2
info="/sys/class/net/"
cd $info
while true; do
for interface in eth*
do
  eval rx1$interface=`cat $info$interface/statistics/rx_bytes`
  eval tx1$interface=`cat $info$interface/statistics/tx_bytes`
done
  sleep $intervalo
for interface in eth*
do
  eval rx2$interface=`cat $info$interface/statistics/rx_bytes`
  eval tx2$interface=`cat $info$interface/statistics/tx_bytes`
done
clear
date
for interface in eth*             
do
  echo $interface
  echo ---- 
  rx1=$(eval echo \${rx1$interface})
  rx2=$(eval echo \${rx2$interface})
  tx1=$(eval echo \${tx1$interface})
  tx2=$(eval echo \${tx2$interface})
  echo RX: $((($rx2-$rx1)/($intervalo*1024))) Kbps
  echo RX: $((($rx2-$rx1)/($intervalo*1048576))) Mbps
  echo TX: $((($tx2-$tx1)/($intervalo*1024))) Kbps
  echo TX: $((($tx2-$tx1)/($intervalo*1048576))) Mbps
done
done
Bandbreite anzeigen

HTML emails mit mail.mailutils

Das Programm mail.mailutils (meist einfach mail) ist auf vielen Linux-Distributionen installiert. Man kann damit über die Shell Emails verschicken, was sehr praktisch ist für scripte und cron-jobs, die den Admin per Mail informieren sollen.

Manchmal will man auch mal ein wenig mit HTML spielen und sei es auch nur, um um den Text ein <pre> zu setzen, damit er mit einer Monospace-Schrift angezeigt wird und ASCII-Art und Tabellen ordentlich dargestellt werden.

So schickt man HTML:

# generiere random boundary
BOUNDARY=$(date | md5sum | head -c8)
echo "
--_$BOUNDARY_
Content-Type: text/html; charset=\"us-ascii\"
Content-Transfer-Encoding: quoted-printable

<html><pre>
Meine Tabelle

+-------+----------+
| id    | analysis |
+-------+----------+
| 36190 |      219 |
| 36192 |      219 |
| 36273 |      219 |
| 36275 |       -1 |
| 36276 |       -1 |
| 36289 |      219 |
| 36293 |      122 |
| 36371 |      219 |
| 36388 |      219 |
| 36393 |      219 |
| 36394 |       -1 |
| 36395 |       -1 |
| 36708 |      122 |
+-------+----------+
</pre></html>
--_$BOUNDARY_--

" | mail.mailutils -s "Mein Subject" \
-a Content-Type:"multipart/alternative; boundary="\"_$BOUNDARY_\"" \
-a From:mein@absender.tld mein@empfaenger.tld

Diese Tabelle sieht jetzt sauber aus, wenn sie den Empfänger erreicht. Die Leerzeilen vor und nach dem Boundary und/oder Headern sind wichtig!

Wenn ich ein Bild in das HTML einbetten will, wird es komplizierter. Das mail-Tool kann zwar mit -A Anhänge verschicken, aber die kann ich dann nicht im HTML nutzen, da ich die dazugehörige ID nicht kenne.
Also muss ich das händisch machen, damit ich alle Parameter kontrollieren kann. Da Email ein 7-Bit Medium ist, muss ich aus dem Binär-Bild ASCII machen und dann noch dem Mailprogramm erklären, wie es das ASCII wieder in eine Binär-Bilddatei zurückverwandelt. Ich benutze hier base64 dafür, da das standardmässig installiert ist und so ziemlich jedes Mailprogramm das versteht. Ausserdem muss ich dem Bild einen Namen geben, denn der Dateiname geht verloren beim encoden in base64, und dazu eine ID, mit der ich darauf verweisen kann im HTML-Code der Mail. So gehts:

# generiere random boundary und Image ID
BOUNDARY=$(date | md5sum | head -c8)
IMAGEID=$(date | md5sum | head -c10 | rev)
# meine Bilddatei
IMAGEFILE=graph.png
( echo "
--_$BOUNDARY_
Content-Type: text/html; charset=\"us-ascii\"
Content-Transfer-Encoding: quoted-printable

<html>
Mein Graph als Bild:<br>
<img contenttype=3D\"image/png\" src=3D\"cid:$IMAGEID\"><br>
Sieht gut aus!

</pre></html>

--_$BOUNDARY_
Content-Type: image/png;name=\"$IMAGEFILE\"
Content-Disposition: attachment;filename=\"$IMAGEFILE\"
Content-ID: <$IMAGEID>
Content-Transfer-Encoding: base64 
"
base64 $IMAGEFILE 
echo "
--_$BOUNDARY_--" ) |  mail.mailutils -s "Mein Subject" \
-a Content-Type:"multipart/related; boundary="\"_$BOUNDARY_\""; type="\"multipart/alternative\""" \
-a MIME-Version:"1.0" \
-a From:mein@absender.tld mein@empfaenger.tld

Es gibt ausser mail.mailutils noch viele andere Commandline-Mailer wie etwa mutt oder mailx. Mit Hilfe der Beispiele oben kann man auch diese Mailer dazu bringen, HTML zu verschicken. Einfach mal gucken, welche Tools auf dem System installiert sind. Auch OS X kann das.

HTML emails mit mail.mailutils

bye bye, netstat

Mit netstat kann man sehen, welche Verbindungen gerade aktiv sind und auf welchen Ports ein Prozess horcht.

Aber netstat ist langsam. Ich habe einen Server, auf dem einige 10k TCP Verbindungen offen sind und der trotz fantastischer CPU und RAM Ausstattung geschlagene 2 Minuten braucht, um netstat auszuführen (mit -n, also ohne Namensauflösung!).

Deutlich schneller, nämlich unter einer Sekunde, schafft das der Nachfolger ss, was wohl eine Abkürzung von socket stat oder so ähnlich sein soll. Die manpage sagt nur „another utility to investigate sockets“.

Das Gute ist, es versteht alle Optionen von netstat. Wer also historisch bedingte Schwierigkeiten hat, ss zu tippen oder bloss ein Gewohnheitstier ist, macht sich einfach ein alias in der .bashrc:

alias netstat=ss
bye bye, netstat

Sekunden umrechnen und anzeigen

Ich habe ein Script mit einer Schleife geschrieben, das ziemlich lange läuft und auch vorher weiss, wie lange es ungefähr laufen wird. Ich will dem Anwender sagen, wie viel Geduld er noch aufbringen muss.

Erst schreibe ich eine Funktion, die die Umrechnung in Tage, Stunden und Minuten macht:

function DisplayTime {
  local T=$1
  local D=$((T/60/60/24))
  local H=$((T/60/60%24))
  local M=$((T/60%60))
  local S=$((T%60))
  [[ $D > 0 ]] && printf '%d days ' $D
  [[ $H > 0 ]] && printf '%d hours ' $H
  [[ $M > 0 ]] && printf '%d minutes ' $M
  [[ $D > 0 || $H > 0 || $M > 0 ]] && printf 'and '
  printf '%d seconds\n' $S
}

Ich nutze in der Benamsung von Funktionen immer eine Kombination aus Groß- und Kleinbuchstaben, damit ich sie als Funktion erkenne und sie nicht mit einem Systembefehl oder einer Variable verwechsle.

Dann schreibe ich einen Echo-Befehl in die Schleife, der seinen Output selbst ersetzt und benutze dafür die obige Funktion. Voraussetzung ist natürlich, dass ich die Variable $SEKUNDEN vorher im Skript irgendwie errechnet habe.

echo -ne "time remaining: $(DisplayTime $SEKUNDEN)                        \r"

Das „\r“ mit dem -e zusammen sorgt dafür, dass die Zeile überschrieben wird. Die Leerzeichen sind nötig, da der Output von der Funktion mit der Zeit kürzer wird und die Zeile sonst nicht  komplett überschrieben wird. Wenn jemand eine bessere Lösung als die Leerzeichen hat, dann her damit!

Sekunden umrechnen und anzeigen

snmp unter Ubuntu precise

Wie nervig. Nach einem (überfälligen) Update von Ubuntu lucid auf Ubuntu precise ging SNMP nicht mehr. Warum? Die Antwort steht in /etc/snmp/snmp.conf:

#
# As the snmp packages come without MIB files due to license reasons, loading
# of MIBs is disabled by default. If you added the MIBs you can reenable
# loaging them by commenting out the following line.
mibs :

Um die MIBs wieder zu bekommen, installiert man das Packet snmp-mibs-downloader und kommentiert die Zeile mibs : in oben genannter Datei aus. Danach geht alles wieder, wie es soll.

snmp unter Ubuntu precise