Python3 : Kleiner Portscanner

Ist jetzt zwar kein Hexenwerk aber hier ein kleiner Portscanner in Python3

#!/usr/bin/env python3
import argparse , socket , sys , logging
from datetime import datetime

SOCKET_STATES = {
    0: "open",
    11: "firewalled",
    111: "closed",
}

def parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument("hostname", metavar="HOSTNAME",
                        help="define the hostname to be checked")
    parser.add_argument("start_port", type=int, metavar="START_PORT",
                        help="define the start port")
    parser.add_argument("end_port", type=int, metavar="END_PORT",
                        help="define the end port")
    parser.add_argument("-a", "--all-ports", action="store_true",
                        help="shows all (default is show only open ports)")
    parser.add_argument("-l", "--logfile", type=str, 
    					help="if set i will write an logfile (you have to set an logfile incl path)")
    parser.add_argument("-t", "--timeout", type=int, default=3, 
    					help=("set the TIMEOUT for socket operations (default is 3 seconds)"))
    parser.add_argument("-v", "--verbose", action="store_true",
                        help="set debug mode (set --all-ports)")
    args = parser.parse_args()
    
    if args.end_port < args.start_port:
    	sys.exit("END_PORT must be higher then START_PORT")

    if 0 < args.start_port <= 65535 and 0 < args.end_port <= 65535:
        return args
    else:
        sys.exit("The Portrange must between 1-65535")

def get_ip_address(hostname):
    try:
        return socket.gethostbyname(hostname)
    except socket.error as err:
        # print (str(err))
        print ('Hostname could not be resolved. Exiting')
        sys.exit(4)

def check_port(ip, port):
    try:
        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
            result = s.connect_ex((ip, port))
            return SOCKET_STATES.get(result, result)
    except KeyboardInterrupt:
    	sys.exit(1)
    except socket.gaierror:
        print ('Hostname could not be resolved. Exiting')
        sys.exit(3)
    except socket.error:
        print ("Couldn't connect to server")
        sys.exit(2)

def write_log(entry,state):
	if state in ['info', 'warning', 'critical','error']:
		log_method = getattr(logging,state)
		log_method(str(entry))

def scan_ports(remote_host, start_port, end_port, logfile , debug=False, show_all=False):
    ip = get_ip_address(remote_host)
    # Print Banner
    print ("-" * 90)
    print ("please wait, scanning remote host {0} , takes some time !".format(ip))
    print ("-" * 90)
    print ("\n")

    t_start = datetime.now()
    for port in range(start_port, end_port + 1):
        if debug:
            print ("\n--> check port {0} on ip {1}\n".format(port, ip))
        port_state = check_port(ip, port)
        if logfile:
        	write_log ("--> check port {0} on ip {1} its {2}".format(port, ip, port_state),"info")
        if port_state == "open" or show_all or debug:
            print ("Port {0: >5}: {1: >10}".format(port, port_state))
    duration = datetime.now() - t_start

    print ("\n")
    print ("-" * 90)
    print ("scanning completed in : {0}".format(duration))

if __name__ == '__main__':
    args = parse_args()
    socket.setdefaulttimeout(int(args.timeout))
    logging.basicConfig(format='%(asctime)s | %(levelname)s | %(message)s',filename=args.logfile,filemode='w',level=logging.DEBUG)
    scan_ports(remote_host=args.hostname,
               start_port=args.start_port, end_port=args.end_port,
               debug=args.verbose, show_all=args.all_ports,logfile=args.logfile)

Bash : SSH Skript mit eigener known_hosts

Problem : Wir arbeiten hier auf einem Server mit mehreren Usern, es kommt immer wieder vor das jemand die known_hosts überschreibt. Den Schuldigen haben wir noch nicht gefunden ;-) Also verwenden wir jetzt in unseren Skripts eigene known_hosts files.

Lösung :
Ich habe mir angewöhnt im Skript Ordner einen Ordner ssh anzulegen in dem dann die known_hosts liegt.
Somit bin ich unabhängig von anderen.
Setzen einer Variable im Skript
SSH_KNOWN_HOST="-o ConnectTimeout=30 -o UserKnownHostsFile=$(dirname $(readlink -f ${0}))/ssh/known_hosts"
Im Skript selbst kann man das so verwenden.
ssh ${SSH_KNOWN_HOST} USER@HOSTNAME
Da sftp und ssh die selben Parameter kennen kann man diese Variable beim Aufruf von ssh und sftp verwenden.

ntop : Eigene Anwendung zu Port zuordnen

Erstmal was ist ntop eigentlich.
ntop (network top) ist eine quelloffene und freie Software, mit der Netzwerkverkehr mitgeschnitten und analysiert werden kann.
Quelle : https://de.wikipedia.org/wiki/Ntop

Diese Software kann schön genutzt werden um z.B. auf einem Gateway oder einer Firewall zu monitoren wo der Traffic so hin läuft. Es werden schon ein ganzer Pack Plugins mitgeliefert aber eigene Anwendungen werden nicht erkannt. Ich habe hier eine kleine Anwendung geschrieben die über udp Port 5404 Daten versendet. Jetzt möchte ich natürlich das auch in meinem Gateway angezeigt bekommen um zu beurteilen wieviel Traffic darüber läuft. Das kann man relativ einfach realisieren jedoch hat es mir auch etwas Arbeit gekostet diesen einfachen Weg zu finden ;-)

Erstellt eine Datei in der später die Protokolle hinzugefügt werden.
touch /usr/share/ntopng/httpdocs/protocol-app.txt
Jetzt füge ich meine Anwendung hinzu, das diese auch im Webfrontend nicht mehr unter UNKNOWN läuft.
echo "udp:5404 @MyApp" > /usr/share/ntopng/httpdocs/protocol-app.txt 
dann müssen wir noch dafür sorgen das diese Datei auch beim Start von ntopng gelesen wird dazu editieren wir das configfile unter /etc/ntopng mit dem Befehl.
echo "-p /usr/share/ntopng/httpdocs/protocol-app.txt" >> /etc/ntopng/ntopng.conf
Dann starten wir den Server neu mit dem Befehl
service ntopng restart
Wenn dann bei den Protokollen MyApp steht wurde alles richtig gemacht ;-) ntop beispiel

Mehr Infos :
http://www.ntop.org/ndpi/configuring-ndpi-for-custom-protocol-detection/

AWS : Mount eines S3 Buckets unter Debian

Installation des benötigten Packetes auf der Debian Kiste.
apt install s3fs
Erstellen einer Passwort Datei im Home Directory
touch ~/.passwd-s3fs
echo "accessKeyId:secretAccessKey" > ~/.passwd-s3fs
Wenn mehrere Amazon S3 Buckets verwendet werden müssen kann auch der Name des Buckets vor den Zugangsdaten hinzugefügt werden.
echo "bucketName:accessKeyId:secretAccessKey" > ~/.passwd-s3fs
Da hier sensible Zugangsdaten in der Datei stehen müssen die Rechte auf 600 geändert werden !
chmod 600 ~/.passwd-s3fs
Wenn alles richtig ist kann das Amazon S3 Buckets gemountet werden
s3fs [BUCKET-NAME] [MOUNT-POINT]
Der Eintrag für /etc/fstab sieht dann so aus, hier ist debug noch aktiv. Das sollte für einen Betrieb in der Produktion deaktiviert werden.
# MOUNT S3 MIT DEBUG
[BUCKET-NAME] [MOUNTPOINT] fuse.s3fs _netdev,allow_other,dbglevel=dbg,curldbg 0 0
# MOUNT S3 OHNE DEBUG
[BUCKET-NAME] [MOUNTPOINT] fuse.s3fs _netdev,allow_other 0 0

Quellen :
https://cloud.netapp.com/blog/amazon-s3-as-a-file-system
https://github.com/s3fs-fuse/s3fs-fuse/wiki/Fuse-Over-Amazon

Debian 9 : hohe CPU Last durch systemd-journald

Problem : Ein Server mit Debian 9 hat eine durchgehend hohe Systemlast. Beim prüfen der Last fällt auf das "systemd-journald" der Grund ist. Nachdem ich mit journalctl -xe nachgeschaut habe woran das liegen könnte sind mir die folgenden Zeilen aufgefallen die sich immer wieder wiederholen.
Sep 08 14:33:27 HOSTNAME sh[293]: /sbin/dhclient-script: 28: .: Can't open /usr/share/sendmail/dynamic
Sep 08 14:33:27 HOSTNAME dhclient[302]: DHCPDECLINE on eth0 to 255.255.255.255 port 67
Sep 08 14:33:27 HOSTNAME sh[293]: DHCPDECLINE on eth0 to 255.255.255.255 port 67
Sep 08 14:33:27 HOSTNAME sh[293]: DHCPDISCOVER on eth0 to 255.255.255.255 port 67 interval 5
Sep 08 14:33:27 HOSTNAME dhclient[302]: DHCPDISCOVER on eth0 to 255.255.255.255 port 67 interval 5
Sep 08 14:33:27 HOSTNAME dhclient[302]: DHCPREQUEST of XXX.XXX.XXX.XXX on eth0 to 255.255.255.255 port 67
Sep 08 14:33:27 HOSTNAME sh[293]: DHCPREQUEST of XXX.XXX.XXX.XXX on eth0 to 255.255.255.255 port 67
Sep 08 14:33:27 HOSTNAME sh[293]: DHCPOFFER of XXX.XXX.XXX.XXX from XXX.XXX.XXX.XXX
Sep 08 14:33:27 HOSTNAME dhclient[302]: DHCPOFFER of XXX.XXX.XXX.XXX from XXX.XXX.XXX.XXX
Sep 08 14:33:27 HOSTNAME sh[293]: DHCPACK of XXX.XXX.XXX.XXX from XXX.XXX.XXX.XXX
Sep 08 14:33:27 HOSTNAME dhclient[302]: DHCPACK of XXX.XXX.XXX.XXX from XXX.XXX.XXX.XXX
Sep 08 14:33:27 HOSTNAME sh[293]: RTNETLINK answers: File exists

Der Grund für den andauernden Neustart Wahn des dhclient war diese Zeile
Sep 08 14:33:27 HOSTNAME sh[293]: /sbin/dhclient-script: 28: .: Can't open /usr/share/sendmail/dynamic
Lösung : In meinem Fall lief ein Skript Amok.
/etc/dhcp/dhclient-exit-hooks.d/sendmail
Da ich hier sowieso auf eine andere Art der Überwachung setzte hab ich das Skript einfach mit folgenden Befehl gelöscht
rm /etc/dhcp/dhclient-exit-hooks.d/sendmail
seitdem ist die Systemlast wieder auf dem gewohnten Stand unterwegs. Wenn man das allerdings benötigt kann man auch diesen Befehl in den Terminal hämmern.
mkdir -p /usr/share/sendmail && touch /usr/share/sendmail/dynamic
“Das einzig sichere System müsste ausgeschaltet, in einem versiegelten und von Stahlbeton ummantelten Raum und von bewaffneten Schutztruppen umstellt sein.”
Gene Spafford (Sicherheitsexperte)