Benutzer-Werkzeuge

Webseiten-Werkzeuge


programme:dhcpdnsadmin:netmanager

Python Implementierung vom netmanager

Check DNS

OS Programm Aufruf in Python

Hier als Beispiel als Aufruf vom Programm host mit einer beliebigen URL:

import os
 
def get_ip_address(url):
    command = "host " + url
    process = os.popen(command)

Im dda miteinbauen? import sys Aufruf der unten angegebenen DNS-Tools.

You can also use the named-checkzone utility that is part of the bind9 package:

named-checkzone example.com /etc/bind/db.example.com

and

named-checkzone 1.168.192.in-addr.arpa. /etc/bind/db.192

This is a great way to make sure you haven't made any mistakes before restarting bind9. You can use the dig utility to test the reverse zone as well as the new domain name:

dig 1.168.192.in-addr.arpa. AXFR

You should see output resolving 1.168.192.in-addr.arpa. to your nameserver.

it.example.de/MX 'mail.it.example.de' has no address records (A or AAAA)

Um die Fehlermeldung zu beheben, muss in der MX-Zeile des Header-Files, der Hostname des Mail-Servers eingetragen werden. Ausserdem muss ein gültiger DNS-Eintag vorhanden sein.

NS      dhcp1              ; Master DNS
NS      dhcp2              ; Slave DNS
MX      10      postfix1   ; Mail Server

postfix1   A    192.168.178.20

Evtl. muss dieser Eintag auch in anderen Zonen gesetzt werden, mit anderen Domain Namen.

SUSE

Die Software befindet sich bei SUSE in folgenden Paketen:

named-checkzone

rpm -qf /usr/sbin/named-checkzone
bind-9.9.9P1-63.7.1.x86_64

dhcpd

rpm -qf /usr/sbin/dhcpd
dhcp-server-4.3.3-10.14.1.x86_64

Debian / Raspbian

sudo apt install bind9utils
which named-checkzone
/usr/sbin/named-checkzone

Check DHCP

The syntax you are looking for is

dhcpd -t -cf /path/to/dhcpd.conf

The -t option will do a config check:

If the -t flag is specified, the server will simply test the configuration file for correct syntax, but will not attempt to perform any network operations. This can be used to test the new configuration file automatically before installing it.

You do not need to use -cf if you are using the default config file path.

/usr/sbin/dhcpd -t

The one you tried with -tf /path/to/… is quite different and relates to tracing.

Packages

Mehrere Module können auch in einem Paket (package) zusammengefasst werden. Ein Paket ist im Prinzip ein Verzeichnis, welches Python-Module enthält. Zusätzlich dazu muss es noch eine Datei mit dem Namen init.py enthalten. Diese Datei kann leer sein oder Python-Code enthalten der bei Import des Paketes ausgeführt werden soll. Pakete werden wie normale Module importiert.

Mengen

Mit Mengen arbeiten um doppelte Elemente wie IP, Hostnamen und MAC Adr. zu beseitigen. Mengen im PDF Seite 39

Eingabe

Split

String in Liste umwandeln, zur Speicherung von Rechnername, MAC und VLAN

eingabe.py
EINGABE = input("Bitte Werte eingeben: ")
 
LISTEA = EINGABE.split()
 
print (type(LISTEA))
print(LISTEA[1])

IP-Adressen generieren

IP-Adressen für VLAN erstellen mit for-Anweisung und der Funktion range(). Mit Seperator sep=„.“ wird vor der Variablen i das Leerzeichen, welches Standardmäßig von print eingefügt wird, durch einem Punkt ersetzt.

for i in range(1, 11):
    print("192.168.178",i,sep=".")
 
...
192.168.178.1
192.168.178.2
192.168.178.3
192.168.178.4
192.168.178.5
192.168.178.6
192.168.178.7
192.168.178.8
192.168.178.9
192.168.178.10

Reverse IP

Hier ohne ipaddress Modul. Ein Beispiel welches sich auf IP übertragen lässt:

>>> ip
'172.16.1.20'
>>> 
>>>
>>> ip = ip.replace("."," ")
>>> ip
'172 16 1 20'
>>> revword = ip.split()
>>> 
>>> revword
['172', '16', '1', '20']
>>> revword.reverse()
>>> revword
['20', '1', '16', '172']
>>> revword='.'.join(revword)
>>> revword
'20.1.16.172'

Strings bearbeiten

None Datentypen zusammensetzten, diese als Sting umwandeln und als nächstes mit Leerzeichen trennen.

  summemacs +=  "{} ".format(str(macvondeldev))

Listen bearbeiten

>>> IPADR
['192', '168', '178', '2']
>>> 
>>> 
>>> IPADR[3]
'2'
>>> IPADR[3]="48"
>>> IPADR
['192', '168', '178', '48']

Spalten aus zwei Listen zusammenführen. Hier zum Beispiel eine Liste mit Geräten und eine Liste mit MAC-Adr. welche zusammen geführt werden sollen. Als Ergebnis soll in der ersten Spalte die Geräte untereinander und in der zweiten die MAC-Adr. untereinander stehen.

print ([x + y for x, y in zip(l_filter_devices,l_filter_mac)])

Prüfung, ob Element in Sequenz enthalten

Zur Prüfung ob IP-Adr. schon vergeben im VLAN. Hier ist i.d.R. nur die letzte Nr. der IP-Adr. von Interesse. Es lässt sich ohne Probleme nur auf die letzte Nr. prüfen ohne das die vorderen Bereiche berücksichtigt werden. Bei Sequenzen kann man auch prüfen, ob (oder ob nicht) ein Element in einer Sequenz vorhanden ist. Dafür gibt es die Operatoren „in“ und „not in“. Die Arbeitsweise erkennt man im folgenden Protokoll einer interaktiven Sitzung:

>>> IPADR
['192', '168', '178', '48']
>>> "178" in IPADR
True
>>> "178" in IPADR[3]
False
>>> "48" in IPADR[3]
True

Dictionaries Zuordnungen

Die Hauptoperationen, die an einem Dictionary durchgeführt werden, sind die Ablage eines Wertes unter einem Schlüssel und der Abruf eines Wertes mit dem gegebenen Schlüssel. Es ist auch möglich ein Schlüssel-Wert-Paar per del zu löschen. Legt man einen Wert unter einem Schlüssel ab, der schon benutzt wird, Überschreibt man den alten Wert, der vorher mit diesem Schlüssel verknüpft war. Einen Wert mit einem nicht-existenten Schlüssel abrufen zu wollen, erzeugt eine Fehlermeldung. Der Aufruf list(d.keys()) auf ein Dictionary gibt eine Liste aller Schlüssel in zufälliger Reihenfolge zurück (will man sie sortiert haben, verwendet man einfach die Funktion sorted(d.keys()) stattdessen).2 Um zu über- prüfen ob ein einzelner Schlüssel im Dictionary ist, lässt sich das Schlüsselwort in benutzen.

Ein Beispiel im Python Tut war eine typische Übersetzung von englisch/deutsch und deutsch/französisch. Durch Verknüpfung beider Dictionaries konnte man nun auch von Französisch nach Englisch übersetzen. Mit dem Wissen kann man das gleich nun auch auf Netzwerk ebene anwenden. Eine Übersetzung von IP/DEVICE und DEVICE/MAC ermöglich eine Zuordnung der abgefragten IP-Adr zu einem Geräte-Namen und einer MAC-Adr.

>>> list(dda.keys())
['e9999', 'e1234']
>>> list(dda.keys())[1]
'e1234'
>>> list(dda.keys())[0]
'e9999'
 
>>> list(dda.values())
['66:55:44:33:22', '00:11:22:33:44']
>>> list(dda.values())[0]
'66:55:44:33:22'
  1. Konfig Dateien als Dict. einlesen
  2. DHCP Konfig Dateien als ein Dict. erstellen
  3. DNS Konfig Dateien als ein Dict. erstellen
  4. Dict. verknüpfen
dict.py
## Dictionaries Zuordnungen ##
 
IP_DEVICE = {"172.16.1.1" : "e5101", "172.16.1.2" : "e5102", "172.16.1.3" : "e5103"}
DEVICE_MAC = {"e5101" : "00:00:00:00:00:01", "e5102" : "00:00:00:00:00:02", "e5103" : "00:00:00:00:00:03"}
 
print(IP_DEVICE["172.16.1.1"])
print(MAC_DEVICE["e5101"])
 
print(MAC_DEVICE[IP_DEVICE["172.16.1.1"]])

Erzeuge Dict. aus zwei Eingabe Listen

#
# Erzeuge Dict. aus zwei Eingabe Listen
#
l_devices = devices.split()
l_macadr = macadr.split()
d_eingabe = {}
 
for dev, mac in zip(l_devices, l_macadr):
    d_eingabe[dev] = [ mac,  None ]    # ip = None
 
print (d_eingabe)

weitere Beispiele:

>>> d_xxx = {}
>>> for dev, mac, ips in zip(l_dev, m_dev, l_ips):
...     d_xxx[dev, mac] = [ ips ]
... 
>>> d_xxx
{('e111', '11:11:11'): ['172.16.6.14'], ('e222', '22:22:22'): ['172.16.6.11'], ('e333', '33:33:33'): ['172.16.6.12']}
>>> for dev, mac, ips in zip(l_dev, m_dev, l_ips):
...     d_xxx[dev, mac] = [ ips ]
... 
>>> d_xxx
{('e111', '11:11:11'): ['172.16.6.14'], ('e222', '22:22:22'): ['172.16.6.11'], ('e333', '33:33:33'): ['172.16.6.12']}
>>> l_ips
['172.16.6.14', '172.16.6.11', '172.16.6.12', '172.16.6.13', '172.16.6.16', '172.16.6.17']
>>> l_ips = ['192.168.1.1', '192.168.1.2', '192.168.1.3', '192.168.1.4', '192.168.1.5']
>>> 
>>> 
>>> for dev, mac, ips in zip(l_dev, m_dev, l_ips):
...     d_xxx[dev, mac] = [ ips ]
... 
>>> 
>>> d_xxx
{('e111', '11:11:11'): ['192.168.1.1'], ('e222', '22:22:22'): ['192.168.1.2'], ('e333', '33:33:33'): ['192.168.1.3']}
>>> 

Dictionarys zusammenfügen

Mit der Methode update() kann man ein zweites Dictionary in ein Dictionary einhängen. Enthält das zweite Dictionary Schlüssel, die auch im ersten vorkommen, so werden diese mit den Werten des zweiten überschrieben.

>>> w={"house":"Haus","cat":"Katze","red":"rot"}
>>> w1 = {"red":"rouge","blau":"bleu"}
>>> w.update(w1)
>>> print(w)
{'house': 'Haus', 'blau': 'bleu', 'red': 'rouge', 'cat': 'Katze'}

Dateien

startswith/endswith

Einlesen

Datei als Liste einlesen:

VLANDATEI = open("0600/vlan0600.in").readlines()
print(VLANDATEI[2:8])

Unterschiede beim Einlesen

>>> lines = []
>>> with open ('dda_dict/vlans/vlan0100.in') as file:
...     lines = file.read().splitlines()
... 
>>> print(lines)
['e1001 01:22:33:44:55:16 172.16.1.1', 'e1002 02:22:33:44:55:16 172.16.1.2', 'e1003 03:22:33:44:55:16 172.16.1.3', 'e1004 04:22:33:44:55:16 172.16.1.4', 'e1005 05:22:33:44:55:16 172.16.1.5', 'e1006 06:22:33:44:55:16 172.16.1.6', 'e1007 07:22:33:44:55:16 172.16.1.7', 'e1008 08:22:33:44:55:16 172.16.1.8', 'e1009 09:22:33:44:55:16 172.16.1.9', 'e1010 10:22:33:44:55:16 172.16.1.10', 'e1011 11:22:33:44:55:16 172.16.1.11', 'e1012 12:22:33:44:55:16 172.16.1.12', 'e1013 13:22:33:44:55:16 172.16.1.13', 'e1014 14:22:33:44:55:16 172.16.1.14', 'e1015 15:22:33:44:55:16 172.16.1.15', 'e1016 16:22:33:44:55:16 172.16.1.16', 'e1017 17:22:33:44:55:16 172.16.1.17', 'e1018 18:22:33:44:55:16 172.16.1.18', 'e1019 19:22:33:44:55:16 172.16.1.19', 'e1020 20:22:33:44:55:16 172.16.1.20', 'e1021 21:22:33:44:55:16 172.16.1.21', 'e1022 22:22:33:44:55:16 172.16.1.22', 'e1023 23:22:33:44:55:16 172.16.1.23', 'e1024 24:22:33:44:55:16 172.16.1.24', 'e1025 25:22:33:44:55:16 172.16.1.25', 'e1026 26:22:33:44:55:16 172.16.1.26', 'e1027 27:22:33:44:55:16 172.16.1.27', 'e1028 28:22:33:44:55:16 172.16.1.28', 'e1029 29:22:33:44:55:16 172.16.1.29', 'e1030 30:22:33:44:55:16 172.16.1.30', 'e1031 31:22:33:44:55:16 172.16.1.31', 'e1032 32:22:33:44:55:16 172.16.1.32', 'e1033 33:22:33:44:55:16 172.16.1.33', 'e1034 34:22:33:44:55:16 172.16.1.34', 'e1035 35:22:33:44:55:16 172.16.1.35', 'e1036 36:22:33:44:55:16 172.16.1.36', 'e1037 37:22:33:44:55:16 172.16.1.37', 'e1038 38:22:33:44:55:16 172.16.1.38', 'e1039 39:22:33:44:55:16 172.16.1.39', 'e1040 40:22:33:44:55:16 172.16.1.40', 'e1041 41:22:33:44:55:16 172.16.1.41', 'e1042 42:22:33:44:55:16 172.16.1.42', 'e1043 43:22:33:44:55:16 172.16.1.43', 'e1044 44:22:33:44:55:16 172.16.1.44', 'e1045 45:22:33:44:55:16 172.16.1.45', 'e1046 46:22:33:44:55:16 172.16.1.46', 'e1047 47:22:33:44:55:16 172.16.1.47', 'e1048 48:22:33:44:55:16 172.16.1.48', 'e1049 49:22:33:44:55:16 172.16.1.49']
>>> 
>>> lines = []
>>> with open ('dda_dict/vlans/vlan0100.in') as file:
...     lines = file.readlines()
... 
>>> print(lines)
['e1001 01:22:33:44:55:16 172.16.1.1\n', 'e1002 02:22:33:44:55:16 172.16.1.2\n', 'e1003 03:22:33:44:55:16 172.16.1.3\n', 'e1004 04:22:33:44:55:16 172.16.1.4\n', 'e1005 05:22:33:44:55:16 172.16.1.5\n', 'e1006 06:22:33:44:55:16 172.16.1.6\n', 'e1007 07:22:33:44:55:16 172.16.1.7\n', 'e1008 08:22:33:44:55:16 172.16.1.8\n', 'e1009 09:22:33:44:55:16 172.16.1.9\n', 'e1010 10:22:33:44:55:16 172.16.1.10\n', 'e1011 11:22:33:44:55:16 172.16.1.11\n', 'e1012 12:22:33:44:55:16 172.16.1.12\n', 'e1013 13:22:33:44:55:16 172.16.1.13\n', 'e1014 14:22:33:44:55:16 172.16.1.14\n', 'e1015 15:22:33:44:55:16 172.16.1.15\n', 'e1016 16:22:33:44:55:16 172.16.1.16\n', 'e1017 17:22:33:44:55:16 172.16.1.17\n', 'e1018 18:22:33:44:55:16 172.16.1.18\n', 'e1019 19:22:33:44:55:16 172.16.1.19\n', 'e1020 20:22:33:44:55:16 172.16.1.20\n', 'e1021 21:22:33:44:55:16 172.16.1.21\n', 'e1022 22:22:33:44:55:16 172.16.1.22\n', 'e1023 23:22:33:44:55:16 172.16.1.23\n', 'e1024 24:22:33:44:55:16 172.16.1.24\n', 'e1025 25:22:33:44:55:16 172.16.1.25\n', 'e1026 26:22:33:44:55:16 172.16.1.26\n', 'e1027 27:22:33:44:55:16 172.16.1.27\n', 'e1028 28:22:33:44:55:16 172.16.1.28\n', 'e1029 29:22:33:44:55:16 172.16.1.29\n', 'e1030 30:22:33:44:55:16 172.16.1.30\n', 'e1031 31:22:33:44:55:16 172.16.1.31\n', 'e1032 32:22:33:44:55:16 172.16.1.32\n', 'e1033 33:22:33:44:55:16 172.16.1.33\n', 'e1034 34:22:33:44:55:16 172.16.1.34\n', 'e1035 35:22:33:44:55:16 172.16.1.35\n', 'e1036 36:22:33:44:55:16 172.16.1.36\n', 'e1037 37:22:33:44:55:16 172.16.1.37\n', 'e1038 38:22:33:44:55:16 172.16.1.38\n', 'e1039 39:22:33:44:55:16 172.16.1.39\n', 'e1040 40:22:33:44:55:16 172.16.1.40\n', 'e1041 41:22:33:44:55:16 172.16.1.41\n', 'e1042 42:22:33:44:55:16 172.16.1.42\n', 'e1043 43:22:33:44:55:16 172.16.1.43\n', 'e1044 44:22:33:44:55:16 172.16.1.44\n', 'e1045 45:22:33:44:55:16 172.16.1.45\n', 'e1046 46:22:33:44:55:16 172.16.1.46\n', 'e1047 47:22:33:44:55:16 172.16.1.47\n', 'e1048 48:22:33:44:55:16 172.16.1.48\n', 'e1049 49:22:33:44:55:16 172.16.1.49\n']
>>>

Dateien schreiben

Eine Datei schreiben, Pfad angeben und Dateiendung vergeben:

    def write(self):
        ''' Schreiben der DNS-Zonefiles. Diese Dateien enthalten die Inhalte der modifizierten DNS-Header und VLAN-Dateien '''
        output_path = '../output/'
        completehfileName = path.join(output_path, self.name+".de")
        # Aufruf der Fkt. zonefileformat()
        l_zfformatlines = self._zonefileformat()
        print ("update Datei: {}".format(completehfileName))
        with open(completehfileName, 'w') as zonefile:
            zonefile.write(self._header)
            zonefile.writelines(l_zfformatlines)
 

Mehrere Lines aus Datei entfernen

Zum Beispiel aus einer Übergabe an das Python Programm sollen mehrere PC-Nr. aus einer Datei-Liste entfernt werden. Hier wird startswith verwendet. Eine for-Schleife mit enumerate und dessen Index hatte hier zu Problemen geführt, da beim löschen mit del lines[i] der Index verrutscht und nur jede zweite Zeile entfernt wird.

An startswith kann man keine Eingabe Listen übergeben aber dafür eine Tupel. Die am Python Programm übergebenen PC-Nummern wurden in einer Liste gespeichert welche in eine Tupel gewandelt wurden.

 
def remove_line_with_device(self):        
        vlandatei = open(self._full_fn,"w")
        for line in self._lines:
            if not line.startswith(self.t_devices):
                vlandatei.write(line)
                print(line)
        vlandatei.close()

shelve-Modul verwenden um Konfig-Dateien einzulesen und zu bearbeiten.

Man kann ein shelve-Objekt auch einfach mit dem dict-Casting-Operator in ein Dictionary wandeln:

>>> s
≤shelve.DbfilenameShelf object at 0xb7133dcc>
>>> dict(s)
{'city': 'London', 'street': 'Fleet Str'}
>>> 

Im folgenden Beispiel demonstrieren wir, dass wir in einem Shelf-Eintrag auch komplexe Objekte, wie beispielsweise Dictionaries abspeichern können:

>>> import shelve
>>> tele = shelve.open("MyPhoneBook")
>>> tele["Mike"] = {"first":"Mike", "last":"Miller", "phone":"4689"}
>>> tele["Steve"] = {"first":"Stephan", "last":"Burns", "phone":"8745"}
>>> tele["Eve"] = {"first":"Eve", "last":"Naomi", "phone":"9069"}
>>> tele["Eve"]["phone"]
'9069'

Die Daten sind auch in diesem Fall persistent gespeichert, d.h. man kann Sie auch wieder in einem späteren Programmlauf benutzen. Alles was man tun muss, ist die Datei MyPhoneBook zu öffnen:

$ python3
Python 3.2.3 (default, Feb 28 2014, 00:22:33) 
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import shelve
>>> tele = shelve.open("MyPhoneBook")
>>> tele["Steve"]["phone"]
'8745'
>>> 

Ablauf Optimierung mit cProfile

http://www.linux-magazin.de/ausgaben/2006/12/gut-gezielt/2/

import cProfile
import sys
sys.argv.append("-update")
f = open("dda.py")
ef = f.read()
f.close()
cProfile.run(ef, "dda.stats")

import pstats
s = pstats.Stats("dda.stats")
s.sort_stats('time')
s.print_stats(10)

Fri Jul 27 16:03:10 2018    dda.stats

         9945 function calls (9898 primitive calls) in 0.235 seconds

   Ordered by: internal time
   List reduced from 274 to 10 due to restriction <10>

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
       87    0.088    0.001    0.088    0.001 {built-in method builtins.print}
       19    0.030    0.002    0.031    0.002 {built-in method io.open}
     10/1    0.013    0.001    0.235    0.235 {built-in method builtins.exec}
        9    0.010    0.001    0.010    0.001 {method 'read' of '_io.FileIO' objects}
        9    0.007    0.001    0.007    0.001 {built-in method marshal.loads}
        1    0.005    0.005    0.031    0.031 /home/ronni/Dokumente/Projekte/eric/dda/DnsZonefile.py:83(_reversefileformat)
       26    0.005    0.000    0.024    0.001 {built-in method builtins.__build_class__}
     1339    0.005    0.000    0.005    0.000 {method 'format' of 'str' objects}
     1342    0.004    0.000    0.004    0.000 {method 'split' of 'str' objects}
      721    0.002    0.000    0.002    0.000 {method 'join' of 'str' objects}


<pstats.Stats object at 0x7686f770>
>>> 
>>> 

https://stackoverflow.com/questions/7165465/optimizing-python-code

Man kann eine Funktion in cProfile testen lassen wie folgt:

import cProfile
cProfile.run('myFunction()', 'myFunction.profile')
Then to view the results:

import pstats
stats = pstats.Stats('myFunction.profile')
stats.strip_dirs().sort_stats('time').print_stats()
This will show you in which functions most of the time is spent.
programme/dhcpdnsadmin/netmanager.txt · Zuletzt geändert: 2020/11/13 13:54 von pulsar