Обучающая программа «Протокол IPv6»

от автора

Этот материал создан коллективными усилиями преподавателя и студента. Первый и четвертый этапы были разработаны студентом, второй и третий — преподавателем, а пятый этап — результат совместной работы.

Этап первый – событие или инцидент

Попав на второй курс, я начал полноценное обучение по своей специальности техника связи. И одним из важнейших направлений была IP адресация. Но к моему огромному сожалению, 95% времени мы обучались работе с протоколом IPv4, создавая сети, разбивая их на подсети и изучая специфику этого протокола. Меня это беспокоило, ибо такой фокус на устаревающей технологии пагубно влияет на будущих специалистов.

На 3 курсе я ушёл заниматься кибербезопасностью в Skills Battles, где ещё больше узнал про IP адресацию и наконец то полноценно поработал с IPv6. После этого я загорелся идеей сделать что-то по протоколу IPv6, чтобы обычные обучающиеся узнавали про IPv6 и становились более подкованными в нём.

Этап второй — зачем это надо?

Я, как преподаватель дисциплины Компьютерные сети, понимала необходимость изучения протокола IPv6. Протокол IPv6 больше соответствует современным реалиям. Формат IPv6-адреса составляет 128 бит, которые представлены восемью шестнадцатибитными шестнадцатеричными блоками и разделены двоеточиями.

Если сравнивать с IPv4, то IPv6 имеет следующие достоинства:

  • маршрутизация становится более эффективной, поскольку пакеты передаются без необходимости фрагментации;

  • встроена технология QoS, для обеспечения эффективной передачи данных в условиях ограниченных возможностей сети;

  • устранён механизм преобразования сетевых адресов NAT;

  • упрощается администрирование сети благодаря автоконфигурации адресов;

  • уменьшаются затраты на обработку за счёт улучшенной структуры заголовков.

Всем понятно, что будущее за протоколом 6 версии. Но в учебных программах, большее количество часов отведено для изучения 4 версии.

Студентам скучно читать просто теоретический материал, да и скорость усвоения материала у всех разная. Поэтому было решено в рамках дипломного проектирования создать программу по изучению протокола IPv6.

Этап третий — постановка задачи

Мною, как руководителем дипломного проектирования, было разработано и выдано задание разработать приложение, в котором содержится лекционный материал, тесты и практические задания по теме «Протокол IPv6».

Приложение должно иметь функционал регистрации и авторизации пользователей, возможность сохранения результатов и прогресса учащихся, а также страницу для администратора. Администратор должен иметь возможность управлять учетными записями пользователей, просматривать их результаты и удалять пользователей при необходимости.

Этап четвертый — реализация

Так как я имел достаточно опыта в работе с фреймворком для разработки веб приложений – Django, я выбрал его для реализации своей задачи.

В качестве базы данных я выбрал PostgreSQL. Django позволяет легко и быстро создавать приложения и мне отдельно нравится в нём его система маршрутизации и реализация шаблона MVP (Model-View-Presenter). Изначально у меня не было предпочтений в выборе базы данных, но после изучения рынка я пришёл к PostgreSQL. Она была выбрана для получения опыта с релевантной на данный момент базой данных.

Итоговая база данных выглядит так

База данных

База данных

Было разработано 5 тем, каждая из которых затрагивает ключевые аспекты протокола IPv6.

Темы, затрагивающие протокол IPv6

Темы, затрагивающие протокол IPv6

Для усложнения жизни учащихся и повышения безопасности мной была создана защищённая маршрутизация. Доступ к лекциям, тестам и заданиям возможен только по POST запросам и система адресации Django и csrf токены позволяют так сделать.

Например система генерации и вывода заданий выглядит вот так.

def exercise(request):     if request.POST.get('number') is None:        return redirect('/')     if request.session.get('auth') and request.method == 'POST':         form = dict(request.POST)         num = int(form.get('number')[0])        if num == 3:            addresses = RecordingAddresses.objects.order_by('?')[:12]      id_addresses = []             f_addresses = []             a_addresses = []          i = 0            for address in addresses:               id_addresses.append(address.id)          if i < len(addresses) / 2:                 f_addresses.append(address.full_record)       else:                  a_addresses.append(address.abbreviation)            i += 1          request.session["id_addresses"] = id_addresses      return render(request, 'tasks/task3.html',              {'auth': request.session.get('auth'), "f_addresses": f_addresses,  "a_addresses": a_addresses})      if num == 4:           task_4_data = []            task_texts = []             for i in range(3):                type_task = random.choice([True, False])  # True - 4 бита False - 5 битов     if type_task:               type_task_text = "подсети "                else:                     type_task_text = "интерфейса "              addresses_names =  ['a136', 'b062', '7f8c', '974c', 'ff0d', 'cb8b', '8e51', 'afbc',    '11ae', '153f', 'a39f', 'fc97', '0445', '1d4c', '6209', 'ab7a',    '5dc3', '9692', 'd4f1', 'af91', '3c97', '4a0f', '5b60', 'b72b',   'ed0c', '149c', '15dc', '1e69', '687d', 'ba80', '99b9', 'cc8a',    '6358', 'f32e', 'aa29', '4c49', 'b88d', '970e', '3a78', 'f88c',    'b89c', 'da45', '73b6', '180a', '9df3', '85e6', '7f34', '1608',   'd8dd', '719c', '5138', '3f2c', 'a6e8', '22a9', '4eed', '2993',  'f3f8', '5710', '4acc', '2a75', '50a6', '7d28', '8a33', 'fe9a',   'e424', '7d97', '252b', '89f7', '5bd6', '1e4a', '734d', '6bd3',    '1870', 'a633', 'b6b4', '15bf', '7494', '0c7d', '8d98', '2def',    '0ee5', '378b', '8f7d', '6835', 'b0c1', 'f451', 'cc42', '2f39',   '8d51', 'b269', '9729', 'eedc', 'ee80', 'bc4b', 'ce67', 'af69',   '0054', '2329', '7361', '4cbb', 'c368', '7f27', 'a042', 'c5d0',   '3057', 'ee51', 'f62c', '6b13', '1fd0', 'ca8a', '1d23', '3e33',   '1030', '7d04', '61de', '3ae1', '960b', '229f', 'caab', '0000',    'ca32', 'f177', '09f1', '5242', '2883', 'ca35', '2df6', 'bd86']      random.shuffle(addresses_names)              address_name = addresses_names[0] + ':' + addresses_names[1] + ':' + addresses_names[1]                 number_of_subnets = random.randint(17, 4080)      task_text = "Произведите разбиение сети " + address_name + ":: на подсети с использованием идентификатора " + type_task_text + "и укажите " + str(             number_of_subnets) + " подсеть."          task_texts.append(task_text)               task_4_data.append([type_task, address_name, number_of_subnets])  request.session["task_4_data"] = task_4_data         return render(request, 'tasks/task4.html',             {'auth': request.session.get('auth'), "tasks": task_texts})   return render(request, 'tasks/task' + str(num) + '.html', {'auth': request.session.get('auth')})     else:         return redirect('/login')

Теперь перейдём к заданиям. Они присутствуют только в 2, 3 и 4 темах.

В задании 2 темы нужно заполнить поля заголовка и указать размеры.

Вот так проходит обработка формы

task = Task.objects.filter(task_number=str(num)).first()     answers = json.loads(task.task_answer)   for i in range(8):        if str(form.get('formChoice' + str(i + 1))[0]) == str(answers['naming'][i]):   result_task += 1      if str(form.get('size' + str(i + 1))[0]) == str(answers['len'][i]):  result_task += 1     grade = calculation_result(16, result_task)if num == 3:    for i in range(12):  address = RecordingAddresses.objects.filter(id=request.session["id_addresses"][i]).first()    if i < 6 and str.strip(form['address'][i].lower()) == str.strip(address.abbreviation):        result_task += 1    if i >= 6 and str.strip(form['address'][i].lower()) == str.strip(address.full_record):          result_task += 1   grade = calculation_result(12, result_task) task_answer = TaskAnswer(task_result=grade, task_id_id=Task.objects.filter(task_number=num).first().id,      user_id_id=request.session['id'])task_answer.save()if grade > "2":   user = User.objects.get(id=request.session['id'])    user.theme_status = user.theme_status[:num - 1] + '1' + user.theme_status[num:]    user.save(update_fields=["theme_status"])return render(request, 'result_task_page.html',          {'result': grade, 'number': num}) 

В задании 3 темы необходимо сократить и восстановить по 6 адресов.

Для генерации адресов используется вот этот код

addresses = RecordingAddresses.objects.order_by('?')[:12] id_addresses = [] f_addresses = [] a_addresses = [] i = 0for address in addresses:    id_addresses.append(address.id)     if i < len(addresses) / 2:      f_addresses.append(address.full_record)  else:        a_addresses.append(address.abbreviation)   i += 1request.session["id_addresses"] = id_addressesreturn render(request, 'tasks/task3.html',      {'auth': request.session.get('auth'), "f_addresses": f_addresses, "a_addresses": a_addresses}) 

А для проверки корректности используется этот код

for i in range(12):    address = RecordingAddresses.objects.filter(id=request.session["id_addresses"][i]).first()    if i < 6 and str.strip(form['address'][i].lower()) == str.strip(address.abbreviation):     result_task += 1  if i >= 6 and str.strip(form['address'][i].lower()) == str.strip(address.full_record):    result_task += 1grade = calculation_result(12, result_task) 

Задание 4 темы требует разбиение сети на подсети и указание последней

Данный код генерирует сети и необходимое количество подсетей

task_4_data = []task_texts = []for i in range(3):     type_task = random.choice([True, False])  # True - 4 бита False - 5 битов  if type_task:         type_task_text = "подсети "   else:      type_task_text = "интерфейса "     addresses_names = ['a136', 'b062'] # Их больше     random.shuffle(addresses_names)  address_name = addresses_names[0] + ':' + addresses_names[1] + ':' + addresses_names[1]   number_of_subnets = random.randint(17, 4080)   task_text = "Произведите разбиение сети " + address_name + ":: на подсети с использованием идентификатора " + type_task_text + "и укажите " + str(        number_of_subnets) + " подсеть."    task_texts.append(task_text)  task_4_data.append([type_task, address_name, number_of_subnets])request.session["task_4_data"] = task_4_datareturn render(request, 'tasks/task4.html',      {'auth': request.session.get('auth'), "tasks": task_texts}) 

А данный код проверяет выполненную работу

i = 0for task_data in request.session["task_4_data"]:   number_of_subnets_hex = hex(int(task_data[2]))[2:]  # True - 4 бита False - 5 битов subnet = ":0000:0"    len_num_sub = len(number_of_subnets_hex)    if task_data[0]:       subnet = subnet[:len(subnet) - len_num_sub - 2] + str(number_of_subnets_hex) + ":0"   else:       subnet = (subnet[:len(subnet) - len_num_sub - 1] +    str(number_of_subnets_hex[:len_num_sub - 1]) +          ":" + number_of_subnets_hex[len_num_sub - 1:len_num_sub])    ans_address = task_data[1] + subnet + "000:0000:0000:0000"     try:         if ipaddress.IPv6Address(ans_address) == ipaddress.IPv6Address(form.get('address')[i]):    result_task += 1   except:     print("Nop")  i += 1grade = 2 + result_task 

Этап пятый — тестирование

Когда Веб приложение было готово, мы протестировали его с помощью студентов-добровольцев. Студенты критичных проблем не выявили. По их отзывам программа интересная, материал дан в доступной форме, а также есть возможность проверить свои знания и умения с помощью тестов и практических заданий.

Веб приложение доступно в открытом репозитории Github https://github.com/GoshArt/DiplomIPv6/


ссылка на оригинал статьи https://habr.com/ru/articles/813119/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *