Лабораторная № 3, Firewall

May 08, 2010 19:48

Правила для файервола хранятся в виде текста.


firewall.py


  1. # -*- coding: cp1251 -*-

  2.  

  3. import re

  4.  

  5. ruleDict = {}

  6. ruleList = []

  7.  

  8. class IPError:

  9.    

  10.     """

  11.     Исключение возвращающее неправильное значение IP адреса или маски подсети.

  12.     """

  13.     def __init__(self,errValue):

  14.         self.errIP = errValue

  15.  

  16. regxIP = re.compile(r'''\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.

  17.                           (25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.

  18.                           (25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.

  19.                           (25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b''', re.VERBOSE)

  20.  

  21. def netmask(addr, mask):

  22.  

  23.     """

  24.     На основании введенного IP адреса и маски возвращает значения адреса подсети

  25.     и широковещательного адреса.

  26.     """

  27.    

  28.     ADDR = addr.strip().split('.')

  29.     MASK = mask.strip().split('.')

  30.     subnet = []

  31.     brdcst = []

  32.     shortMask = False

  33.     for i in range(len(ADDR)):

  34.         if int(MASK[i]) == 255 and shortMask == False:

  35.             subnet.append(str(int(ADDR[i]) & int(MASK[i])))

  36.             brdcst.append(str(int(ADDR[i]) | 255 - int(MASK[i])))

  37.         elif int(MASK[i]) == 0 and shortMask == True:

  38.             subnet.append(str(int(ADDR[i]) & int(MASK[i])))

  39.             brdcst.append(str(int(ADDR[i]) | 255 - int(MASK[i])))

  40.         elif int(MASK[i]) < 255 and shortMask == False:

  41.             shortMask = True

  42.             subnet.append(str(int(ADDR[i]) & int(MASK[i])))

  43.             brdcst.append(str(int(ADDR[i]) | 255 - int(MASK[i])))       

  44.         else:

  45.             raise IPError('Неправильно задана маска подсети: ' + mask)

  46.     return '.'.join(subnet), '.'.join(brdcst)

  47.  

  48. def add(ruleStr):

  49.  

  50.     """

  51.     Добавляет правило для файервола в словарь.

  52.     """

  53.    

  54.     try:

  55.         Rule, srcAddr, srcMask, dstAddr, dstMask = ruleStr.strip().split()

  56.     except ValueError:

  57.         raise IPError('Неправильное количество параметров.')

  58.    

  59.     for srcIP in [srcAddr, srcMask, dstAddr, dstMask]:

  60.         if not regxIP.search(srcIP):

  61.             raise IPError('Неправильно задан параметр: ' + srcIP)

  62.  

  63.     try:

  64.         subNetSrc, brdCstSrc = netmask(srcAddr, srcMask)

  65.         subNetDst, brdCstDst = netmask(dstAddr, dstMask)

  66.     except IPError, i:

  67.         raise IPError(i.errIP)

  68.  

  69.     if srcAddr == subNetSrc or srcAddr == brdCstSrc:

  70.         raise IPError('Адрес источника является адресом подсети или широковещательным адресом.')

  71.     elif dstAddr == subNetDst or dstAddr == brdCstDst:

  72.         raise IPError('Адрес источника является адресом подсети или широковещательным адресом.')

  73.        

  74.     if Rule.lower() == 'permit':

  75.         ruleDict[srcAddr + ' -> ' + dstAddr] = True

  76.         ruleList.append(ruleStr.strip())

  77.     elif Rule.lower() == 'deny':

  78.         ruleDict[srcAddr + ' -> ' + dstAddr] = False

  79.         ruleList.append(ruleStr.strip())

  80.     else:

  81.         raise IPError('\nНеправильно задано ключевое слово: ' + Rule.lower())

  82.  

  83. def list():

  84.  

  85.     """

  86.     Выводит на экран список правил для файервола.

  87.     """

  88.    

  89.     ruleNum = 1

  90.     print '\nПравила для файервола:'

  91.     if len(ruleList) == 0:

  92.         print '\nНи одного правила еще не задано.\n'

  93.     else:

  94.         for strRule in ruleList:

  95.             print '%2i %s' % (ruleNum, strRule)

  96.             ruleNum += 1

  97.             print '\n'

  98.  

  99. def filter (src, dst):

  100.  

  101.     """

  102.     Фильтрует пакет на основании адреса отправителя и адреса получателя.

  103.     Возвращает значение True | False | Строку с ошибкой.

  104.     """

  105.    

  106.     if regxIP.search(src) and regxIP.search(dst):

  107.         filterKey = src + ' -> ' + dst

  108.         if filterKey in ruleDict.keys():

  109.             return ruleDict[filterKey]

  110.         else:

  111.             return 'For this query rule not exist.'

  112.     else:

  113.         return 'Wrong data.'

  114.  

  115. def delete(delRule):

  116.    

  117.     """

  118.     По номеру удаляет правило из списка.

  119.     """

  120.    

  121.     if delRule.isdigit() and 0 < int(delRule) <= len(ruleList):

  122.         delKey = ruleList[int(delRule)-1].strip().split()

  123.         ruleList.remove(ruleList[int(delRule)-1])

  124.         ruleDict.pop(delKey[1] + ' -> ' + delKey[3])

  125.     else:

  126.         pass

  127.    

  128. def backup(fileDB,act):

  129.  

  130.     """

  131.     Очищает файл с правилами для файервола.

  132.     """

  133.    

  134.     if act == 'clear':

  135.         try:

  136.             DB = open(fileDB,'w')

  137.         except IOError:

  138.             print 'Файл невозможно стереть.'

  139.         finally:

  140.             DB.close()

  141.            

  142.     if act == 'save':

  143.         try:

  144.             rulesDB = open(fileDB,'w')

  145.             for i in ruleList:

  146.                 rulesDB.write(i+'\n')

  147.         except IOError:

  148.             print 'Правило не добавлено в файл для постоянного хранения.'

  149.         finally:

  150.             rulesDB.close()

  151.  

  152. def readDbFile(fileDB):

  153.  

  154.     """

  155.     Считывает правила из файла fileDB,

  156.     должен находится в том же каталоге что и модуль.

  157.     Возвращает словарь ruleDict.

  158.     """

  159.    

  160.     ruleDict = {}

  161.     ruleList = []

  162.    

  163.     for ruleLine in open(fileDB,'r'):

  164.         rule, srcaddr, srcmask, dstaddr, dstmask = ruleLine.strip().split()

  165.         ruleList.append(ruleLine.strip())

  166.         if rule.lower() == 'permit':

  167.             ruleDict[srcaddr + ' -> ' + dstaddr] = True

  168.         elif rule.lower() == 'deny':

  169.             ruleDict[srcaddr + ' -> ' + dstaddr] = False


start_firewall.py

# -*- coding: cp1251 -*-
import firewall

while True:
    print 'МЕНЮ'
    print '1 - Просмотреть список правил для файервола.'
    print '2 - Добавить правило.'
    print '3 - Удалить правило.'
    print '4 - Проверить IP пакет.'
    print '5 - Сохранить введенные правила в базу правил файервола.'
    print '6 - Очистить базу правил файервола.'
    print '7 - Восстановить базу правил из файла. Существующая база будет утеряна.'
    inputKey = raw_input('Выберите действие: ')
    if inputKey == 'q':
        break
    elif inputKey == '1':
        firewall.list()
    elif inputKey == '2':
        inputStr = raw_input('Введите правило: ')
        try:
            firewall.add(inputStr)
        except firewall.IPError, error:
            print '%s' % (error.errIP)

elif inputKey == '3':
        inputStr = raw_input('Введите номер строки для удаления: ')
        firewall.delete(inputStr)

elif inputKey == '4':
        inSrc, inDst = raw_input('Введите через пробле srcAddr и dstAddr: ').strip().split()
        print firewall.filter(inSrc, inDst)

elif inputKey == '5':
        firewall.backup('rules.db','save')

elif inputKey == '6':
        firewall.backup('rules.db','clear')

elif inputKey == '7':
        firewall.readDbFile('rules.db')



python, lab #03

Previous post Next post
Up