<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Brett's Blog</title><link>/</link><description>Recent content on Brett's Blog</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><copyright>© 2015-2026 Brett Lykins</copyright><lastBuildDate>Sun, 22 Feb 2026 10:59:00 -0500</lastBuildDate><atom:link href="/feed.xml" rel="self" type="application/rss+xml"/><item><title>Testing ISAKMP Part 4: Using Scapy</title><link>/posts/2026/netcat-isakmp-4/</link><pubDate>Sun, 22 Feb 2026 10:59:00 -0500</pubDate><guid>/posts/2026/netcat-isakmp-4/</guid><description>&lt;p&gt;In &lt;a href="./posts/2026/netcat-isakmp-2/"&gt;Part 2&lt;/a&gt;, I showed how to test ISAKMP with a pre-built hex string and netcat. In &lt;a href="./posts/2026/netcat-isakmp-3/"&gt;Part 3&lt;/a&gt;, we dove deep into the byte-by-byte construction of ISAKMP packets. Now let&amp;rsquo;s use Scapy to automate this with Python.&lt;/p&gt;
&lt;h2 id="why-scapy"&gt;Why Scapy?&lt;/h2&gt;
&lt;p&gt;Netcat with hex strings works for one-off tests, but Scapy lets you build packets programmatically, parse responses automatically, and script tests across multiple targets. It understands ISAKMP structure and handles length fields and checksums for you.&lt;/p&gt;
&lt;h2 id="prerequisites"&gt;Prerequisites&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Python 3.8+ installed&lt;/li&gt;
&lt;li&gt;Basic Python knowledge&lt;/li&gt;
&lt;li&gt;Understanding of ISAKMP concepts (see &lt;a href="./posts/2016/netcat-isakmp/"&gt;Part 1&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Target ISAKMP/IKE peer to test&lt;/li&gt;
&lt;li&gt;Root/sudo access (required for raw socket operations)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="installation"&gt;Installation&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Install Poetry (if not already installed)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl -sSL https://install.python-poetry.org &lt;span class="p"&gt;|&lt;/span&gt; python3 -
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Install Scapy via Poetry&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /path/to/your/project
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;poetry init
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;poetry add scapy
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Or install globally&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pip install scapy
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Verify installation&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;python3 -c &lt;span class="s2"&gt;&amp;#34;from scapy.all import *; print(conf.version)&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; Scapy requires raw socket access, which needs root/sudo privileges. When using Poetry with sudo, you must install dependencies as root: &lt;code&gt;sudo poetry install&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="basic-isakmp-packet-with-scapy"&gt;Basic ISAKMP Packet with Scapy&lt;/h2&gt;
&lt;h3 id="the-simple-approach"&gt;The Simple Approach&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;span class="lnt"&gt;32
&lt;/span&gt;&lt;span class="lnt"&gt;33
&lt;/span&gt;&lt;span class="lnt"&gt;34
&lt;/span&gt;&lt;span class="lnt"&gt;35
&lt;/span&gt;&lt;span class="lnt"&gt;36
&lt;/span&gt;&lt;span class="lnt"&gt;37
&lt;/span&gt;&lt;span class="lnt"&gt;38
&lt;/span&gt;&lt;span class="lnt"&gt;39
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="ch"&gt;#!/usr/bin/env python3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;scapy.all&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Target configuration&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;target_ip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;192.168.1.1&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;target_port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Build basic ISAKMP packet&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Create IP and UDP layers&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;ip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;IP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dst&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;target_ip&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;udp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;UDP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sport&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dport&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;target_port&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Create ISAKMP header (Identity Protection, Main Mode)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;isakmp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ISAKMP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;init_cookie&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;RandString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="c1"&gt;# Random 8-byte initiator cookie&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;resp_cookie&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="se"&gt;\x00&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# Responder cookie (zeros for initial packet)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;exch_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# Identity Protection (Main Mode)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Create SA payload with a simple transform&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;sa&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ISAKMP_payload_SA&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;prop&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ISAKMP_payload_Proposal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;proto&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# ISAKMP&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;trans&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ISAKMP_payload_Transform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;transform_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="c1"&gt;# KEY_IKE&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Assemble the complete packet&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;packet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ip&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;udp&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;isakmp&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Send and receive&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sr1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;packet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;verbose&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;show&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;No response received&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="building-a-complete-phase-1-packet"&gt;Building a Complete Phase 1 Packet&lt;/h2&gt;
&lt;h3 id="transform-set-configuration"&gt;Transform Set Configuration&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;span class="lnt"&gt;32
&lt;/span&gt;&lt;span class="lnt"&gt;33
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Define transform set parameters&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Using modern cryptographic standards&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Encryption algorithms (RFC 3602, RFC 2409)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;ENCR_AES_CBC&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;ENCR_3DES_CBC&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Hash algorithms (RFC 2409)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;HASH_SHA256&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;HASH_SHA1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Diffie-Hellman groups (RFC 2409, RFC 3526)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;DH_GROUP_14&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt; &lt;span class="c1"&gt;# 2048-bit MODP&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;DH_GROUP_5&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="c1"&gt;# 1536-bit MODP&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;DH_GROUP_2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="c1"&gt;# 1024-bit MODP&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Authentication methods (RFC 2409)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;AUTH_PSK&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="c1"&gt;# Pre-Shared Key&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;AUTH_RSA_SIG&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="c1"&gt;# RSA Signatures&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Life duration type (RFC 2409)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;LIFE_TYPE_SECONDS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;LIFE_TYPE_KILOBYTES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Define a modern transform set&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;transform_set&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;encryption&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ENCR_AES_CBC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;key_length&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;256&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# AES-256&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;hash&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;HASH_SHA256&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;dh_group&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;DH_GROUP_14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;auth_method&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;AUTH_PSK&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;lifetime&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;86400&lt;/span&gt; &lt;span class="c1"&gt;# 24 hours in seconds&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="constructing-the-packet"&gt;Constructing the Packet&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;span class="lnt"&gt;32
&lt;/span&gt;&lt;span class="lnt"&gt;33
&lt;/span&gt;&lt;span class="lnt"&gt;34
&lt;/span&gt;&lt;span class="lnt"&gt;35
&lt;/span&gt;&lt;span class="lnt"&gt;36
&lt;/span&gt;&lt;span class="lnt"&gt;37
&lt;/span&gt;&lt;span class="lnt"&gt;38
&lt;/span&gt;&lt;span class="lnt"&gt;39
&lt;/span&gt;&lt;span class="lnt"&gt;40
&lt;/span&gt;&lt;span class="lnt"&gt;41
&lt;/span&gt;&lt;span class="lnt"&gt;42
&lt;/span&gt;&lt;span class="lnt"&gt;43
&lt;/span&gt;&lt;span class="lnt"&gt;44
&lt;/span&gt;&lt;span class="lnt"&gt;45
&lt;/span&gt;&lt;span class="lnt"&gt;46
&lt;/span&gt;&lt;span class="lnt"&gt;47
&lt;/span&gt;&lt;span class="lnt"&gt;48
&lt;/span&gt;&lt;span class="lnt"&gt;49
&lt;/span&gt;&lt;span class="lnt"&gt;50
&lt;/span&gt;&lt;span class="lnt"&gt;51
&lt;/span&gt;&lt;span class="lnt"&gt;52
&lt;/span&gt;&lt;span class="lnt"&gt;53
&lt;/span&gt;&lt;span class="lnt"&gt;54
&lt;/span&gt;&lt;span class="lnt"&gt;55
&lt;/span&gt;&lt;span class="lnt"&gt;56
&lt;/span&gt;&lt;span class="lnt"&gt;57
&lt;/span&gt;&lt;span class="lnt"&gt;58
&lt;/span&gt;&lt;span class="lnt"&gt;59
&lt;/span&gt;&lt;span class="lnt"&gt;60
&lt;/span&gt;&lt;span class="lnt"&gt;61
&lt;/span&gt;&lt;span class="lnt"&gt;62
&lt;/span&gt;&lt;span class="lnt"&gt;63
&lt;/span&gt;&lt;span class="lnt"&gt;64
&lt;/span&gt;&lt;span class="lnt"&gt;65
&lt;/span&gt;&lt;span class="lnt"&gt;66
&lt;/span&gt;&lt;span class="lnt"&gt;67
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;scapy.all&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;build_isakmp_packet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;target_ip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;transform_set&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; Build a complete ISAKMP Phase 1 Main Mode packet with specified transform set.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; Args:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; target_ip: Target IP address
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; transform_set: Dictionary with encryption, hash, dh_group, auth_method, lifetime
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; Returns:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; Complete Scapy packet ready to send
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# IP and UDP layers&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;IP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dst&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;target_ip&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;udp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;UDP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sport&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dport&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# ISAKMP header&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;isakmp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ISAKMP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;init_cookie&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;RandString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;resp_cookie&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="se"&gt;\x00&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;exch_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# Identity Protection (Main Mode)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# Build transform attributes as list of (type, value) tuples&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# Type numbers: 1=Encryption, 2=Hash, 3=Auth, 4=Group, 11=LifeType, 12=LifeDuration, 14=KeyLength&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;transforms&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;transform_set&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;encryption&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt; &lt;span class="c1"&gt;# Encryption algorithm&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;transform_set&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;hash&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt; &lt;span class="c1"&gt;# Hash algorithm&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;transform_set&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;dh_group&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt; &lt;span class="c1"&gt;# DH Group&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;transform_set&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;auth_method&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt; &lt;span class="c1"&gt;# Authentication method&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="c1"&gt;# Life Type: seconds&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;transform_set&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;lifetime&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="c1"&gt;# Life Duration&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# Add key length if specified&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;transform_set&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;key_length&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;transforms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;transform_set&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;key_length&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# Build Transform payload&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;transform&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ISAKMP_payload_Transform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;transform_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# KEY_IKE&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;transforms&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;transforms&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# Build Proposal payload&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;proposal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ISAKMP_payload_Proposal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;proposal&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;proto&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# ISAKMP&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;trans&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;transform&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# Build SA payload&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;sa&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ISAKMP_payload_SA&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;doi&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# IPsec DOI (lowercase field name)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;situation&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# Identity Only&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;prop&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;proposal&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# Assemble complete packet&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;packet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ip&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;udp&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;isakmp&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;packet&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Example usage&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;192.168.1.1&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;packet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;build_isakmp_packet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;transform_set&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Scapy&amp;rsquo;s ISAKMP implementation uses a list of &lt;code&gt;(type, value)&lt;/code&gt; tuples for transform attributes, not individual attribute objects. This is simpler and matches how the protocol actually works.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="sending-and-analyzing-responses"&gt;Sending and Analyzing Responses&lt;/h2&gt;
&lt;h3 id="send-the-packet"&gt;Send the Packet&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;span class="lnt"&gt;32
&lt;/span&gt;&lt;span class="lnt"&gt;33
&lt;/span&gt;&lt;span class="lnt"&gt;34
&lt;/span&gt;&lt;span class="lnt"&gt;35
&lt;/span&gt;&lt;span class="lnt"&gt;36
&lt;/span&gt;&lt;span class="lnt"&gt;37
&lt;/span&gt;&lt;span class="lnt"&gt;38
&lt;/span&gt;&lt;span class="lnt"&gt;39
&lt;/span&gt;&lt;span class="lnt"&gt;40
&lt;/span&gt;&lt;span class="lnt"&gt;41
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;send_isakmp_packet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;packet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; Send ISAKMP packet and capture response.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; Args:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; packet: Scapy packet to send
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; timeout: Response timeout in seconds
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; Returns:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; Response packet or None
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;[*] Sending ISAKMP packet to &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;packet&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;IP&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dst&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:500&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;[*] Initiator Cookie: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;packet&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ISAKMP&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;init_cookie&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hex&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# Send packet and wait for response&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sr1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;packet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;verbose&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;[+] Response received from &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;IP&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;[-] No response received (timeout)&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Send the packet&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;send_isakmp_packet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;packet&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;haslayer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ISAKMP&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# Extract basic info&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;[*] Response Details:&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34; Responder Cookie: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ISAKMP&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;resp_cookie&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hex&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34; Exchange Type: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ISAKMP&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exch_type&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34; Next Payload: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ISAKMP&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;next_payload&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# Check if SA payload is present&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;haslayer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ISAKMP_payload_SA&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;[+] SA payload received - transform set accepted!&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;[-] No SA payload - transform set rejected&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# Note: Some devices send NOTIFY payloads on rejection&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# Check for ISAKMP_payload_Notification for detailed error info&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="understanding-the-response"&gt;Understanding the Response&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;span class="lnt"&gt;32
&lt;/span&gt;&lt;span class="lnt"&gt;33
&lt;/span&gt;&lt;span class="lnt"&gt;34
&lt;/span&gt;&lt;span class="lnt"&gt;35
&lt;/span&gt;&lt;span class="lnt"&gt;36
&lt;/span&gt;&lt;span class="lnt"&gt;37
&lt;/span&gt;&lt;span class="lnt"&gt;38
&lt;/span&gt;&lt;span class="lnt"&gt;39
&lt;/span&gt;&lt;span class="lnt"&gt;40
&lt;/span&gt;&lt;span class="lnt"&gt;41
&lt;/span&gt;&lt;span class="lnt"&gt;42
&lt;/span&gt;&lt;span class="lnt"&gt;43
&lt;/span&gt;&lt;span class="lnt"&gt;44
&lt;/span&gt;&lt;span class="lnt"&gt;45
&lt;/span&gt;&lt;span class="lnt"&gt;46
&lt;/span&gt;&lt;span class="lnt"&gt;47
&lt;/span&gt;&lt;span class="lnt"&gt;48
&lt;/span&gt;&lt;span class="lnt"&gt;49
&lt;/span&gt;&lt;span class="lnt"&gt;50
&lt;/span&gt;&lt;span class="lnt"&gt;51
&lt;/span&gt;&lt;span class="lnt"&gt;52
&lt;/span&gt;&lt;span class="lnt"&gt;53
&lt;/span&gt;&lt;span class="lnt"&gt;54
&lt;/span&gt;&lt;span class="lnt"&gt;55
&lt;/span&gt;&lt;span class="lnt"&gt;56
&lt;/span&gt;&lt;span class="lnt"&gt;57
&lt;/span&gt;&lt;span class="lnt"&gt;58
&lt;/span&gt;&lt;span class="lnt"&gt;59
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;parse_isakmp_response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; Parse ISAKMP response and extract transform set details.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; Args:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; response: Scapy packet containing ISAKMP response
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; Returns:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; Dictionary with parsed response details
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;haslayer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ISAKMP&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;responder_cookie&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ISAKMP&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;resp_cookie&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hex&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;exchange_type&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ISAKMP&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exch_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;accepted&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;transform_set&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# Check for SA payload (indicates acceptance)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;haslayer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ISAKMP_payload_SA&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;accepted&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# Extract transform attributes if present&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;haslayer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ISAKMP_payload_Transform&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;transform&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ISAKMP_payload_Transform&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# Parse attributes&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;hasattr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;attributes&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;attr&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;transform&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;attributes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;attr_type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;attribute_type&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;attr_val&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;attribute_value&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# Map attribute types to names&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;attr_type&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mh"&gt;0x8001&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x0001&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;transform_set&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;encryption&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;attr_val&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;attr_type&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mh"&gt;0x800e&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x000e&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;transform_set&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;key_length&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;attr_val&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;attr_type&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mh"&gt;0x8002&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x0002&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;transform_set&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;hash&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;attr_val&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;attr_type&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mh"&gt;0x8004&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x0004&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;transform_set&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;dh_group&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;attr_val&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;attr_type&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mh"&gt;0x8003&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x0003&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;transform_set&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;auth_method&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;attr_val&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Example usage&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;parsed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;parse_isakmp_response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;parsed&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;parsed&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;accepted&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;[+] Transform set ACCEPTED by peer&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34; Encryption: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;parsed&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;transform_set&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;encryption&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;N/A&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34; Hash: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;parsed&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;transform_set&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;hash&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;N/A&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34; DH Group: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;parsed&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;transform_set&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;dh_group&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;N/A&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;[-] Transform set REJECTED or no response&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="advanced-usage"&gt;Advanced Usage&lt;/h2&gt;
&lt;h3 id="testing-multiple-transform-sets"&gt;Testing Multiple Transform Sets&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;span class="lnt"&gt;32
&lt;/span&gt;&lt;span class="lnt"&gt;33
&lt;/span&gt;&lt;span class="lnt"&gt;34
&lt;/span&gt;&lt;span class="lnt"&gt;35
&lt;/span&gt;&lt;span class="lnt"&gt;36
&lt;/span&gt;&lt;span class="lnt"&gt;37
&lt;/span&gt;&lt;span class="lnt"&gt;38
&lt;/span&gt;&lt;span class="lnt"&gt;39
&lt;/span&gt;&lt;span class="lnt"&gt;40
&lt;/span&gt;&lt;span class="lnt"&gt;41
&lt;/span&gt;&lt;span class="lnt"&gt;42
&lt;/span&gt;&lt;span class="lnt"&gt;43
&lt;/span&gt;&lt;span class="lnt"&gt;44
&lt;/span&gt;&lt;span class="lnt"&gt;45
&lt;/span&gt;&lt;span class="lnt"&gt;46
&lt;/span&gt;&lt;span class="lnt"&gt;47
&lt;/span&gt;&lt;span class="lnt"&gt;48
&lt;/span&gt;&lt;span class="lnt"&gt;49
&lt;/span&gt;&lt;span class="lnt"&gt;50
&lt;/span&gt;&lt;span class="lnt"&gt;51
&lt;/span&gt;&lt;span class="lnt"&gt;52
&lt;/span&gt;&lt;span class="lnt"&gt;53
&lt;/span&gt;&lt;span class="lnt"&gt;54
&lt;/span&gt;&lt;span class="lnt"&gt;55
&lt;/span&gt;&lt;span class="lnt"&gt;56
&lt;/span&gt;&lt;span class="lnt"&gt;57
&lt;/span&gt;&lt;span class="lnt"&gt;58
&lt;/span&gt;&lt;span class="lnt"&gt;59
&lt;/span&gt;&lt;span class="lnt"&gt;60
&lt;/span&gt;&lt;span class="lnt"&gt;61
&lt;/span&gt;&lt;span class="lnt"&gt;62
&lt;/span&gt;&lt;span class="lnt"&gt;63
&lt;/span&gt;&lt;span class="lnt"&gt;64
&lt;/span&gt;&lt;span class="lnt"&gt;65
&lt;/span&gt;&lt;span class="lnt"&gt;66
&lt;/span&gt;&lt;span class="lnt"&gt;67
&lt;/span&gt;&lt;span class="lnt"&gt;68
&lt;/span&gt;&lt;span class="lnt"&gt;69
&lt;/span&gt;&lt;span class="lnt"&gt;70
&lt;/span&gt;&lt;span class="lnt"&gt;71
&lt;/span&gt;&lt;span class="lnt"&gt;72
&lt;/span&gt;&lt;span class="lnt"&gt;73
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_transform_sets&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;target_ip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;transform_sets&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; Test multiple transform sets against a target.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; Args:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; target_ip: Target IP address
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; transform_sets: List of transform set dictionaries
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; timeout: Response timeout in seconds
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; Returns:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; List of results with acceptance status
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ts&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;transform_sets&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;[*] Testing transform set &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;transform_sets&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34; Encryption: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ts&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;encryption&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, Hash: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ts&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;hash&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, DH: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ts&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;dh_group&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# Build and send packet&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;packet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;build_isakmp_packet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;target_ip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sr1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;packet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;verbose&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# Parse response&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;parsed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;parse_isakmp_response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;transform_set&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;accepted&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;parsed&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;accepted&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;parsed&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;response&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;parsed&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;accepted&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34; [+] ACCEPTED&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34; [-] REJECTED or no response&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# Small delay between tests&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Define multiple transform sets to test&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;test_sets&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# Modern strong crypto&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;encryption&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# AES-CBC&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;key_length&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;256&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;hash&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# SHA-256&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;dh_group&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# 2048-bit&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;auth_method&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;lifetime&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;86400&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# Moderate crypto&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;encryption&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# AES-CBC&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;key_length&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;128&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;hash&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# SHA-256&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;dh_group&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# 2048-bit&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;auth_method&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;lifetime&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;86400&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Run tests&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;test_transform_sets&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;192.168.1.1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;test_sets&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Summary&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;=&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;SUMMARY&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;=&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;accepted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;accepted&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Accepted: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;accepted&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; transform sets&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="aggressive-mode-vs-main-mode"&gt;Aggressive Mode vs Main Mode&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;span class="lnt"&gt;32
&lt;/span&gt;&lt;span class="lnt"&gt;33
&lt;/span&gt;&lt;span class="lnt"&gt;34
&lt;/span&gt;&lt;span class="lnt"&gt;35
&lt;/span&gt;&lt;span class="lnt"&gt;36
&lt;/span&gt;&lt;span class="lnt"&gt;37
&lt;/span&gt;&lt;span class="lnt"&gt;38
&lt;/span&gt;&lt;span class="lnt"&gt;39
&lt;/span&gt;&lt;span class="lnt"&gt;40
&lt;/span&gt;&lt;span class="lnt"&gt;41
&lt;/span&gt;&lt;span class="lnt"&gt;42
&lt;/span&gt;&lt;span class="lnt"&gt;43
&lt;/span&gt;&lt;span class="lnt"&gt;44
&lt;/span&gt;&lt;span class="lnt"&gt;45
&lt;/span&gt;&lt;span class="lnt"&gt;46
&lt;/span&gt;&lt;span class="lnt"&gt;47
&lt;/span&gt;&lt;span class="lnt"&gt;48
&lt;/span&gt;&lt;span class="lnt"&gt;49
&lt;/span&gt;&lt;span class="lnt"&gt;50
&lt;/span&gt;&lt;span class="lnt"&gt;51
&lt;/span&gt;&lt;span class="lnt"&gt;52
&lt;/span&gt;&lt;span class="lnt"&gt;53
&lt;/span&gt;&lt;span class="lnt"&gt;54
&lt;/span&gt;&lt;span class="lnt"&gt;55
&lt;/span&gt;&lt;span class="lnt"&gt;56
&lt;/span&gt;&lt;span class="lnt"&gt;57
&lt;/span&gt;&lt;span class="lnt"&gt;58
&lt;/span&gt;&lt;span class="lnt"&gt;59
&lt;/span&gt;&lt;span class="lnt"&gt;60
&lt;/span&gt;&lt;span class="lnt"&gt;61
&lt;/span&gt;&lt;span class="lnt"&gt;62
&lt;/span&gt;&lt;span class="lnt"&gt;63
&lt;/span&gt;&lt;span class="lnt"&gt;64
&lt;/span&gt;&lt;span class="lnt"&gt;65
&lt;/span&gt;&lt;span class="lnt"&gt;66
&lt;/span&gt;&lt;span class="lnt"&gt;67
&lt;/span&gt;&lt;span class="lnt"&gt;68
&lt;/span&gt;&lt;span class="lnt"&gt;69
&lt;/span&gt;&lt;span class="lnt"&gt;70
&lt;/span&gt;&lt;span class="lnt"&gt;71
&lt;/span&gt;&lt;span class="lnt"&gt;72
&lt;/span&gt;&lt;span class="lnt"&gt;73
&lt;/span&gt;&lt;span class="lnt"&gt;74
&lt;/span&gt;&lt;span class="lnt"&gt;75
&lt;/span&gt;&lt;span class="lnt"&gt;76
&lt;/span&gt;&lt;span class="lnt"&gt;77
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;build_aggressive_mode_packet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;target_ip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;transform_set&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;identity&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;test@example.com&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; Build ISAKMP Aggressive Mode packet.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; Aggressive Mode sends more information in the first packet (including identity)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; but completes the exchange faster (3 packets vs 6 in Main Mode).
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; Args:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; target_ip: Target IP address
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; transform_set: Transform set dictionary
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; identity: Identity string for ID payload
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; Returns:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; Complete Scapy packet
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# IP and UDP layers&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;IP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dst&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;target_ip&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;udp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;UDP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sport&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dport&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# ISAKMP header for Aggressive Mode&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;isakmp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ISAKMP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;init_cookie&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;RandString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;resp_cookie&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="se"&gt;\x00&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;next_payload&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# SA payload&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;exch_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# Aggressive Mode (vs 2 for Main Mode)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;flags&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# Build SA payload (same as Main Mode)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# ... (use build_isakmp_packet logic for SA/Proposal/Transform)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# Add Key Exchange payload (sent in first packet in Aggressive Mode)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ke&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ISAKMP_payload_KE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;next_payload&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# ID payload follows&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ke&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;RandString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;128&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# DH public value (size depends on DH group)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# Add Identification payload (sent in first packet in Aggressive Mode)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;id_payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ISAKMP_payload_ID&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;next_payload&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;IDtype&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# ID_USER_FQDN&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;IdentData&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;identity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# Assemble: ISAKMP / SA / KE / ID&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# Note: In Main Mode, KE and ID come in later packets&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;packet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ip&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;udp&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;isakmp&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;ke&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;id_payload&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;packet&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Compare the two modes:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Main Mode (6 packets total, more secure)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Packet 1: HDR, SA&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Packet 2: HDR, SA&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Packet 3: HDR, KE, Nonce&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Packet 4: HDR, KE, Nonce&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Packet 5: HDR*, ID, HASH&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Packet 6: HDR*, ID, HASH&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;main_mode_packet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;build_isakmp_packet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;192.168.1.1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;transform_set&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Main Mode packet size: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main_mode_packet&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; bytes&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Main Mode exchange type: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;main_mode_packet&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ISAKMP&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exch_type&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Aggressive Mode (3 packets total, faster but exposes identity)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Packet 1: HDR, SA, KE, Nonce, ID&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Packet 2: HDR, SA, KE, Nonce, ID, HASH&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Packet 3: HDR*, HASH&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;aggressive_packet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;build_aggressive_mode_packet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;192.168.1.1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;transform_set&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Aggressive Mode packet size: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;aggressive_packet&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; bytes&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Aggressive Mode exchange type: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;aggressive_packet&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ISAKMP&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exch_type&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Security consideration:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Main Mode encrypts identity, Aggressive Mode sends it in CLEARTEXT&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# This is a critical security vulnerability - attackers can harvest identities&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Use Main Mode unless you have a specific requirement for Aggressive Mode&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="nat-t-detection"&gt;NAT-T Detection&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# TODO: Add NAT-T vendor ID&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# TODO: Test for NAT-T support&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="creating-a-reusable-script"&gt;Creating a Reusable Script&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve created a complete script that combines all these techniques. The full code is in the &lt;a href="https://github.com/lykinsbd/nn_examples/tree/master/isakmp_testing"&gt;nn_examples repository&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The repository includes additional transform sets (including legacy crypto) for real-world compatibility testing.&lt;/p&gt;
&lt;h3 id="quick-start"&gt;Quick Start&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Clone the repository&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git clone https://github.com/lykinsbd/nn_examples.git
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; nn_examples/isakmp_testing
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Install dependencies with Poetry (both user and root)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;poetry install
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo poetry install
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Test a single target&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo poetry run python isakmp_tester.py 192.168.1.1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Test multiple transform sets&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo poetry run python isakmp_tester.py 192.168.1.1 --test-multiple
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Use Aggressive Mode&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo poetry run python isakmp_tester.py 192.168.1.1 --aggressive
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Why &lt;code&gt;sudo poetry install&lt;/code&gt;?&lt;/strong&gt; Scapy requires raw socket access (root privileges). Since &lt;code&gt;sudo&lt;/code&gt; runs in a separate environment, dependencies must be installed both as your user and as root.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="example-output"&gt;Example Output&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[*] Testing 192.168.1.1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Mode: Main Mode
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Encryption: 7
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Hash: 4
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; DH Group: 14
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[+] ACCEPTED - Transform set accepted by peer
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Responder Cookie: a1b2c3d4e5f67890
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="self-contained-testing"&gt;Self-Contained Testing&lt;/h3&gt;
&lt;p&gt;The repository also includes &lt;code&gt;isakmp_listener.py&lt;/code&gt; - a test responder for testing without a real VPN device:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Terminal 1: Start the test listener&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo poetry run python isakmp_listener.py
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Terminal 2: Test against localhost&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo poetry run python isakmp_tester.py 127.0.0.1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo poetry run python isakmp_tester.py 127.0.0.1 --test-multiple
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;The listener accepts all proposed transform sets and logs packet details. Good for testing the tester script, learning packet structure, and debugging without VPN hardware.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; When testing against localhost (127.0.0.1), you may receive ISAKMP responses even without the listener running. This is the kernel&amp;rsquo;s UDP socket handling, not actual ISAKMP protocol responses. For realistic testing, use a real ISAKMP/VPN device or test between different machines.&lt;/p&gt;
&lt;h2 id="comparison-scapy-vs-netcat-vs-ike-scan"&gt;Comparison: Scapy vs Netcat vs ike-scan&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Scapy&lt;/th&gt;
&lt;th&gt;Netcat&lt;/th&gt;
&lt;th&gt;ike-scan&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Dynamic construction&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Response parsing&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scripting&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;⚠️&lt;/td&gt;
&lt;td&gt;⚠️&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Learning tool&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Production ready&lt;/td&gt;
&lt;td&gt;⚠️&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Installation&lt;/td&gt;
&lt;td&gt;pip&lt;/td&gt;
&lt;td&gt;Built-in&lt;/td&gt;
&lt;td&gt;Package manager&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="security-considerations"&gt;Security Considerations&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Authorization Required:&lt;/strong&gt; Only test systems you own or have explicit permission to test. ISAKMP probes are logged by VPN concentrators, firewalls, and IDS/IPS systems. Repeated probes trigger security alerts.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Phase 1 Only:&lt;/strong&gt; This covers IKE Phase 1 (ISAKMP) only. Establishing a full VPN tunnel requires Phase 2 (IPsec Quick Mode) and proper authentication credentials.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cryptographic Parameters:&lt;/strong&gt; Use SHA-256 (not SHA-1), AES-256, and DH Group 14+ (2048-bit minimum).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting&lt;/h2&gt;
&lt;h3 id="permission-denied"&gt;Permission Denied&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Scapy requires root for raw sockets&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo poetry run python script.py
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Make sure dependencies are installed for root too&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo poetry install
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="no-response-received"&gt;No Response Received&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Check firewall rules (UDP/500)&lt;/li&gt;
&lt;li&gt;Verify target IP is correct&lt;/li&gt;
&lt;li&gt;Confirm ISAKMP service is running&lt;/li&gt;
&lt;li&gt;Check for NAT between you and target&lt;/li&gt;
&lt;li&gt;VPN concentrators rate-limit ISAKMP attempts - wait 30-60 seconds between tests&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="import-errors"&gt;Import Errors&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Install missing dependencies&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pip install scapy cryptography
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="next-steps"&gt;Next Steps&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Explore IKEv2 with Scapy&lt;/li&gt;
&lt;li&gt;Build Phase 2 (Quick Mode) packets&lt;/li&gt;
&lt;li&gt;Implement full IKE exchange&lt;/li&gt;
&lt;li&gt;Add support for certificates (RSA signatures)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Scapy bridges the gap between manual packet construction and specialized tools like ike-scan. While netcat teaches you the raw protocol (&lt;a href="./posts/2026/netcat-isakmp-2/"&gt;Part 2&lt;/a&gt;) and manual construction reveals the internals (&lt;a href="./posts/2026/netcat-isakmp-3/"&gt;Part 3&lt;/a&gt;), Scapy gives you the power to automate and scale your testing.&lt;/p&gt;
&lt;p&gt;For production VPN scanning, use dedicated tools like &lt;code&gt;ike-scan&lt;/code&gt; or &lt;code&gt;nmap --script ike-version&lt;/code&gt;. For learning and custom testing, Scapy is unmatched.&lt;/p&gt;
&lt;h2 id="references"&gt;References&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://scapy.readthedocs.io/"&gt;Scapy Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://tools.ietf.org/html/rfc2408"&gt;RFC 2408 - ISAKMP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://tools.ietf.org/html/rfc2409"&gt;RFC 2409 - IKE&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://scapy.readthedocs.io/en/latest/api/scapy.layers.isakmp.html"&gt;Scapy ISAKMP Layer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Testing ISAKMP Part 3: Building Packets from Scratch</title><link>/posts/2026/netcat-isakmp-3/</link><pubDate>Sat, 14 Feb 2026 17:16:00 -0500</pubDate><guid>/posts/2026/netcat-isakmp-3/</guid><description>&lt;p&gt;In &lt;a href="./posts/2026/netcat-isakmp-2/"&gt;Part 2&lt;/a&gt;, I provided a ready-to-use ISAKMP packet for testing VPN connectivity. But where did that hex string come from? This post breaks down ISAKMP packet construction byte-by-byte.&lt;/p&gt;
&lt;p&gt;Understanding packet structure at the byte level helps you debug protocol issues, customize packets for specific testing scenarios, and understand what tools like &lt;code&gt;ike-scan&lt;/code&gt; are doing under the hood.&lt;/p&gt;
&lt;h2 id="the-approach"&gt;The Approach&lt;/h2&gt;
&lt;p&gt;After spending time reading &lt;a href="https://tools.ietf.org/html/rfc2408"&gt;RFC2408&lt;/a&gt; for the basic header in Part 1, I decided to base this complete packet on an actual captured ISAKMP conversation. If you don&amp;rsquo;t have an ISAKMP capture handy, you can find protocol details and examples at the &lt;a href="https://wiki.wireshark.org/Protocols/isakmp"&gt;Wireshark ISAKMP Protocol page&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I still recommend reading RFC2408 to understand ISAKMP message structure, otherwise this sea of hexadecimal will be confusing.&lt;/p&gt;
&lt;h2 id="hand-crafted-datagram"&gt;Hand-Crafted Datagram&lt;/h2&gt;
&lt;p&gt;The primary ingredient needed to make a complete ISAKMP datagram is an attempt to set up the SA (Security Association) including nested inner payloads and an offer of a Transform set.&lt;/p&gt;
&lt;h3 id="header"&gt;Header&lt;/h3&gt;
&lt;p&gt;As discussed previously, the header format for ISAKMP (IKE v1) is defined in &lt;a href="https://tools.ietf.org/html/rfc2408#section-3.1"&gt;RFC2408 Section 3.1&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Initiator and Responder Cookies&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;8 bytes per Cookie&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Initiator Cookie&lt;/em&gt;
&lt;ul&gt;
&lt;li&gt;AKA the SPI or Security Parameter Index&lt;/li&gt;
&lt;li&gt;We&amp;rsquo;ll make this a value of 1 since it has to be something and we don&amp;rsquo;t care what it is.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Production note:&lt;/strong&gt; RFC 2408 recommends pseudo-random generation to prevent DoS attacks&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\x00\x00\x00\x00\x00\x00\x00\x01&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Responder Cookie&lt;/em&gt;
&lt;ul&gt;
&lt;li&gt;All zeros because this is an initial communication, and as the Initiator, we don&amp;rsquo;t know what the responder will send yet.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\x00\x00\x00\x00\x00\x00\x00\x00&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Next Payload&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;1 byte&lt;/li&gt;
&lt;li&gt;The Next Payload will be of a Security Association type, so per RFC2408 Section 3.1 this is a value of 1.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\x01&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Major Version and Minor Version&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;4 bits each&lt;/li&gt;
&lt;li&gt;Mandatory values of 1 and 0, because we&amp;rsquo;re using ISAKMP version 1.0&lt;/li&gt;
&lt;li&gt;That would be 0001 and 0000 in binary.&lt;/li&gt;
&lt;li&gt;Together, that would look like 00010000, which equals 10 in Hex.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\x10&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Exchange Type&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;1 byte&lt;/li&gt;
&lt;li&gt;The Exchange Types are laid out in &lt;a href="https://www.rfc-editor.org/rfc/rfc2408.html#section-4.4"&gt;RFC2408 Section 4.4&lt;/a&gt; to &lt;a href="https://www.rfc-editor.org/rfc/rfc2408.html#section-4.8"&gt;Section 4.8&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;From our sample packet capture, I see we want an Identity Protection type (02).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\x02&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Flags&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;1 byte&lt;/li&gt;
&lt;li&gt;We still need no flags, so leaving this at 0.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\x00&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Message ID&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;4 bytes&lt;/li&gt;
&lt;li&gt;Must be zeros per RFC2408 for an initial Phase 1 datagram like we&amp;rsquo;re simulating.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\x00\x00\x00\x00&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Length&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;4 bytes&lt;/li&gt;
&lt;li&gt;I have doubled back from the bottom to fill in this value, as you are unable to calculate it until you have built all the inner payloads.&lt;/li&gt;
&lt;li&gt;This totals up to 88 bytes or 58 in hex.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\x00\x00\x00\x58&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="generic-payload-header"&gt;Generic Payload Header&lt;/h3&gt;
&lt;p&gt;There is a simple header on each ISAKMP payload as shown below, it is defined in &lt;a href="https://www.rfc-editor.org/rfc/rfc2408.html#section-3.2"&gt;RFC2408 Section 3.2&lt;/a&gt;.
We&amp;rsquo;ll need one on our outer SA Payload, and one will be present on any interior/nested payloads as well (such as additional Proposals or Vendor Specific Attributes).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Next Payload&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;1 byte&lt;/li&gt;
&lt;li&gt;This is the last outer payload, so 0.&lt;/li&gt;
&lt;li&gt;We&amp;rsquo;re not simulating Vendor Specific Attributes or anything like that, just trying to make a minimum viable datagram.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\x00&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RESERVED&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;1 byte&lt;/li&gt;
&lt;li&gt;Unused, set to Zero.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\x00&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Payload Length&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;2 bytes&lt;/li&gt;
&lt;li&gt;I am cheating somewhat, and know this value as I have gone forward to finish the payload, and then calculated backward to get this value.&lt;/li&gt;
&lt;li&gt;It includes the Generic Payload header elements (including the length field we&amp;rsquo;re calculating now) and the length of the inner SA Payload from below.&lt;/li&gt;
&lt;li&gt;That totals 60 bytes or 3c in hex.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\x00\x3c&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="security-association-payload"&gt;Security Association Payload&lt;/h3&gt;
&lt;p&gt;SA Payload is defined in &lt;a href="https://tools.ietf.org/html/rfc2408#section-3.4"&gt;RFC2408 Section 3.4&lt;/a&gt; and laid out as shown below.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Domain of Interpretation (DOI)&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;4 bytes&lt;/li&gt;
&lt;li&gt;See &lt;a href="https://www.rfc-editor.org/rfc/rfc2408.html#section-2.1"&gt;RFC2408 Section 2.1&lt;/a&gt; for more information on what the DOI is.
For our purposes, this is a value of 1, for an IPSEC DOI (&lt;a href="https://www.rfc-editor.org/rfc/rfc2407.html"&gt;RFC2407&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\x00\x00\x00\x01&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Situation&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Variable length (4 bytes in this case)&lt;/li&gt;
&lt;li&gt;based on the DOI For IPSEC DOI, per &lt;a href="https://www.rfc-editor.org/rfc/rfc2407.html#section-4.2"&gt;RFC2407 section 4.2&lt;/a&gt;, this will be 4 bytes.&lt;/li&gt;
&lt;li&gt;Our sample capture indicates to say that this is Identity Only (value of 00000001).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\x00\x00\x00\x01&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="proposal-payload"&gt;Proposal Payload&lt;/h3&gt;
&lt;p&gt;Inside the SA Payload, there is the payload containing the ISAKMP Proposal on how to go about setting up the Security Association.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Next Payload&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;1 byte&lt;/li&gt;
&lt;li&gt;This will be zero as there is no other Proposal being sent.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\x00&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RESERVED&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;1 byte&lt;/li&gt;
&lt;li&gt;Unused, set to zero.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\x00&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Payload length&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;2 bytes&lt;/li&gt;
&lt;li&gt;Again, I only know this value as I am working backward, and have calculated it out knowing the length of this payload.&lt;/li&gt;
&lt;li&gt;It is 48 bytes long (including the two bytes above, these two bytes, and everything in the payload below), which is 30 in hex.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\x00\x30&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Proposal Number&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;1 byte&lt;/li&gt;
&lt;li&gt;If there is more than one Proposal in the payload, which Proposal is this?&lt;/li&gt;
&lt;li&gt;In our case, this is the first and only Proposal, so set this to 00000001.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\x01&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Protocol ID&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;1 byte&lt;/li&gt;
&lt;li&gt;This took some tracking down, but as defined in &lt;a href="https://tools.ietf.org/html/rfc2408#section-3.6"&gt;RFC2408 Section 3.6&lt;/a&gt;, the specific values for these are defined by the DOI in use (IPSec DOI in our case).&lt;/li&gt;
&lt;li&gt;The IDs are defined in &lt;a href="https://www.rfc-editor.org/rfc/rfc2407.html"&gt;RFC2407 Section 4.4.1&lt;/a&gt;, and we&amp;rsquo;re using ISAKMP (value of 1).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\x01&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SPI Size&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;1 byte&lt;/li&gt;
&lt;li&gt;Set to zero for ISAKMP (as the Initiator and Responder cookies will be used for the SPIs).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\x00&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Number of Transforms&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;1 byte&lt;/li&gt;
&lt;li&gt;We&amp;rsquo;re just sending one Transform, so set it to a value of 1.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\x01&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="transform-payload"&gt;Transform Payload&lt;/h3&gt;
&lt;p&gt;And finally, inside of THAT payload are one or more Transforms.
(I told you this would get confusing…)
For our purposes, I&amp;rsquo;m just going to offer a single, simple, and fairly common transform set consisting of:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Encryption: AES-128&lt;/li&gt;
&lt;li&gt;Hash: SHA&lt;/li&gt;
&lt;li&gt;Diffie-Hellman: Group 5&lt;/li&gt;
&lt;li&gt;Authentication: Pre-Shared Key&lt;/li&gt;
&lt;li&gt;Lifetime 86400 seconds&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Security Notice:&lt;/strong&gt; This packet uses legacy cryptographic parameters for maximum compatibility with older devices. For production VPNs, use:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Hash: SHA-256 or SHA-384&lt;/li&gt;
&lt;li&gt;Encryption: AES-256-CBC or AES-256-GCM&lt;/li&gt;
&lt;li&gt;DH Group: Group 14 (2048-bit) or higher&lt;/li&gt;
&lt;li&gt;Consider IKEv2 instead of IKEv1 for modern deployments&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;It is worth noting that the Transform Attributes are expressed as TLV (Type-Length-Value) or TV (Type-Value).
If you&amp;rsquo;re not familiar with what a TLV is, &lt;a href="https://en.wikipedia.org/wiki/Type-length-value"&gt;I recommend becoming familiar&lt;/a&gt; with it as it crops up again and again in network protocols.
TLVs allow a protocol to be extended in ways beyond the original scope, for example, TLVs are what make a routing protocol like ISIS able to be extended to support Shortest Path Bridging.&lt;/p&gt;
&lt;p&gt;The TLV/TV information for our purposes is laid out across all three original IPSEC/ISAKMP/IKE RFCs (&lt;a href="https://tools.ietf.org/html/rfc2407"&gt;RFC2407&lt;/a&gt;, &lt;a href="https://tools.ietf.org/html/rfc2408"&gt;RFC2408&lt;/a&gt;, and &lt;a href="https://tools.ietf.org/html/rfc2409"&gt;RFC2409&lt;/a&gt; respectively.)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;For getting the bulk of actual Types, Values, and whether they are fixed or variable length, you need &lt;a href="https://tools.ietf.org/html/rfc2409#appendix-A"&gt;RFC2409 Appendix A&lt;/a&gt; which lists the IKE Attribute Assigned Numbers.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://tools.ietf.org/html/rfc2408#section-3.3"&gt;RFC2408 Section 3.3&lt;/a&gt; however, specifies the underlying Data Attribute format.&lt;/li&gt;
&lt;li&gt;But to figure out what Domain of Interpretation (DOI) to use we have to consult &lt;a href="https://tools.ietf.org/html/rfc2407#section-4.4.2"&gt;RFC2407 Section 4.4.2&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It is also important to call out that &lt;a href="https://tools.ietf.org/html/rfc2408#section-3.3"&gt;RFC2408 Section 3.3&lt;/a&gt; indicates that the most significant (leftmost) bit of the Attribute field, will determine if these bits represent a TLV (0) or TV (1).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If it is a TLV (0), then there is a length field sent.&lt;/li&gt;
&lt;li&gt;If it is a TV (1), then it is assumed to be two bytes, and no length field is sent.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For example, this means that a TV (1) for an Encryption Algorithm (1) of AES-CBC (7) in Binary would be:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;1000 0000 0000 0001 0000 0000 0000 0111&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Translated to Hexadecimal, that would come out as:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;\x80\x01\x00\x07&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;We will similarly construct each value below (and we&amp;rsquo;ll use this value as well).&lt;/p&gt;
&lt;h4 id="transform-set"&gt;Transform Set&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Next Payload&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;1 byte&lt;/li&gt;
&lt;li&gt;This will be zero as no other Transforms are being sent.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\x00&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RESERVED&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;1 byte&lt;/li&gt;
&lt;li&gt;Unused, set to zero.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\x00&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Payload length&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;2 bytes&lt;/li&gt;
&lt;li&gt;This is a value of 40 bytes that I only know because I finished building the payload and came back to calculate this value.&lt;/li&gt;
&lt;li&gt;40 in hex is 28.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\x00\x28&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Transform Number&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;1 byte&lt;/li&gt;
&lt;li&gt;This is the only transform we&amp;rsquo;re sending, and it&amp;rsquo;s the first, so 1.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\x01&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Transform ID&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;1 byte&lt;/li&gt;
&lt;li&gt;This value is specified by the DOI, so &lt;a href="https://tools.ietf.org/html/rfc2407#section-4.4.2"&gt;RFC2407 Section 4.4.2&lt;/a&gt; says to simply use 1 for IKE.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\x01&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RESERVED2&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;2 bytes&lt;/li&gt;
&lt;li&gt;Two more bytes of mandatory zeros.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\x00\x00&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="transform-ike-attributes"&gt;Transform IKE Attributes&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Encryption Algorithm&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;4 bytes&lt;/li&gt;
&lt;li&gt;As we worked out above, this should be four bytes for a TV (starting with 80).&lt;/li&gt;
&lt;li&gt;Next, comes the encryption algorithm attribute class of 1.&lt;/li&gt;
&lt;li&gt;The attribute class value portion of this TV was a little tricky because AES came out well after &lt;a href="https://tools.ietf.org/html/rfc2409"&gt;RFC2409&lt;/a&gt; was published.&lt;/li&gt;
&lt;li&gt;That information is laid out in &lt;a href="https://www.rfc-editor.org/rfc/rfc3602#section-5.1"&gt;RFC3602 (The AES-CBC Cipher Algorithm and Its Use with IPsec) Section 5.1&lt;/a&gt;, and indicates that the AES ID is &amp;ldquo;7&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\x80\x01\x00\x07&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Key Length&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;4 bytes&lt;/li&gt;
&lt;li&gt;We&amp;rsquo;re using a Key Length (class attribute of 14, or 0e in hex) of 128 bits (80 in hex), and this is a TV as well, so we get:&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\x80\x0e\x00\x80&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hash Algorithm&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;4 bytes&lt;/li&gt;
&lt;li&gt;We&amp;rsquo;re using a hash algorithm (class attribute of 2) of SHA (which is also a value of 2), and again we&amp;rsquo;re getting these values from &lt;a href="https://tools.ietf.org/html/rfc2409#appendix-A"&gt;RFC2409 Appendix A&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Also, this field is a TV, which means it again starts with \x80 and is 4 bytes, so we have:&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\x80\x02\x00\x02&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Diffie-Hellman Group&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;4 bytes&lt;/li&gt;
&lt;li&gt;For the Group Description (class attribute of 4) we&amp;rsquo;re going to use DH Group 5, which scouring &lt;a href="https://tools.ietf.org/html/rfc2409#appendix-A"&gt;RFC2409 Appendix A&lt;/a&gt; again tells us is a value of 5.&lt;/li&gt;
&lt;li&gt;This is again a TV (starts with \x80) and is 4 bytes:&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\x80\x04\x00\x05&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Authentication Method&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;4 bytes&lt;/li&gt;
&lt;li&gt;For the Authentication Method (class attribute of 3) we are using a pre-shared key (value of 1):&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\x80\x03\x00\x01&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Lifetime&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;4 + variable bytes (8 in this case)&lt;/li&gt;
&lt;li&gt;We&amp;rsquo;re going to set a lifetime of one day (or 86400 seconds).&lt;/li&gt;
&lt;li&gt;This breaks into two fields.
&lt;ul&gt;
&lt;li&gt;First a TV of Life Type (what are we measuring, seconds or kilobytes) with:
&lt;ul&gt;
&lt;li&gt;A class attribute of 11 (0b in hex) and a value of 1 for seconds.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Next is a TLV (which starts with 00 instead of 80) of Life Duration (how many of that unit) with:
&lt;ul&gt;
&lt;li&gt;A class attribute of 12 (0c in hex), a two-byte length field with a value of 4 bytes, and a value of 86400 decimal = 0x15180 hex (written as &lt;code&gt;\x00\x01\x51\x80&lt;/code&gt; in big-endian).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\x80\x0b\x00\x01\x00\x0c\x00\x04\x00\x01\x51\x80&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="the-complete-hex-string"&gt;The Complete Hex String&lt;/h2&gt;
&lt;p&gt;Now to add all of this into one giant string of hexadecimal:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x01\x10\x02\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x3c\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x30\x01\x01\x00\x01\x00\x00\x00\x28\x01\x01\x00\x00\x80\x01\x00\x07\x80\x0e\x00\x80\x80\x02\x00\x02\x80\x04\x00\x05\x80\x03\x00\x01\x80\x0b\x00\x01\x00\x0c\x00\x04\x00\x01\x51\x80
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;This 88-byte packet represents a complete ISAKMP Phase 1 Identity Protection exchange initiation with the transform set we defined above.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Building ISAKMP packets byte-by-byte is tedious but educational. It gives you deep insight into how VPN protocols work at the wire level. For practical testing, use the ready-made packet from &lt;a href="./posts/2026/netcat-isakmp-2/"&gt;Part 2&lt;/a&gt; or tools like &lt;code&gt;ike-scan&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Key Takeaways:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ISAKMP packets have nested payload structures (SA → Proposal → Transform)&lt;/li&gt;
&lt;li&gt;Each payload has its own header with length fields&lt;/li&gt;
&lt;li&gt;Transform attributes use TLV/TV encoding&lt;/li&gt;
&lt;li&gt;Length fields must be calculated backward from inner payloads&lt;/li&gt;
&lt;li&gt;Understanding this structure helps debug VPN issues&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For those interested in automating this process, consider exploring Python with the Scapy library for dynamic packet construction.&lt;/p&gt;</description></item><item><title>Testing ISAKMP Part 2: Pre-Built Packets</title><link>/posts/2026/netcat-isakmp-2/</link><pubDate>Sat, 07 Feb 2026 10:00:00 -0500</pubDate><guid>/posts/2026/netcat-isakmp-2/</guid><description>&lt;p&gt;In &lt;a href="./posts/2016/netcat-isakmp/"&gt;my previous post&lt;/a&gt; about using &lt;code&gt;netcat&lt;/code&gt; to test ISAKMP, I validated that UDP/500 was open &lt;strong&gt;to&lt;/strong&gt; the destination, and that semi-valid ISAKMP headers were being received by the peer (a Cisco ASAv in this case). However, this validation required me to be knowledgeable in troubleshooting the Cisco ASA platform so that I could easily determine if my pseudo-ISAKMP packets arrived (and also required that I control or have access to the ASA). What if the peer is outside of your control or is a platform you are not at all familiar with? In that case, what I want to do now is send a complete ISAKMP initial communication and receive a reply from the peer. This test serves the dual purpose of removing the need for debugs or logging on the peer and validates the return path (and any stateful/L7 inspection) as well.&lt;/p&gt;
&lt;p&gt;Rather than hand-crafting every byte again, I based this packet on an actual captured ISAKMP conversation. If you don&amp;rsquo;t have a capture handy, you can find ISAKMP protocol details and examples at the &lt;a href="https://wiki.wireshark.org/Protocols/isakmp"&gt;Wireshark ISAKMP Protocol page&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Want to understand how this packet was built?&lt;/strong&gt; Check out &lt;a href="./posts/2026/netcat-isakmp-3/"&gt;Part 3&lt;/a&gt; for a detailed byte-by-byte breakdown of ISAKMP packet construction.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="the-test-packet"&gt;The Test Packet&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve constructed a complete 88-byte ISAKMP Phase 1 packet with the following transform set:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Encryption:&lt;/strong&gt; AES-128-CBC&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hash:&lt;/strong&gt; SHA-1&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DH Group:&lt;/strong&gt; Group 5 (1536-bit MODP)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Authentication:&lt;/strong&gt; Pre-Shared Key&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Lifetime:&lt;/strong&gt; 86400 seconds (24 hours)&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Security Notice:&lt;/strong&gt; This packet uses legacy cryptographic parameters for maximum compatibility with older devices. For production VPNs, use:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Hash: SHA-256 or SHA-384&lt;/li&gt;
&lt;li&gt;Encryption: AES-256-CBC or AES-256-GCM&lt;/li&gt;
&lt;li&gt;DH Group: Group 14 (2048-bit) or higher&lt;/li&gt;
&lt;li&gt;Consider IKEv2 instead of IKEv1 for modern deployments&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference&lt;/h2&gt;
&lt;p&gt;For those who want to skip the detailed explanation and just test connectivity, here&amp;rsquo;s everything you need:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Complete ISAKMP Test Packet:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;ISAKMP_PACKET&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x01\x10\x02\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x3c\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x30\x01\x01\x00\x01\x00\x00\x00\x28\x01\x01\x00\x00\x80\x01\x00\x07\x80\x0e\x00\x80\x80\x02\x00\x02\x80\x04\x00\x05\x80\x03\x00\x01\x80\x0b\x00\x01\x00\x0c\x00\x04\x00\x01\x51\x80&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Basic Test:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; -ne &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$ISAKMP_PACKET&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; nc -u TARGET_IP &lt;span class="m"&gt;500&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;With Timeout and Response Capture:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; -ne &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$ISAKMP_PACKET&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; timeout &lt;span class="m"&gt;5&lt;/span&gt; nc -u TARGET_IP &lt;span class="m"&gt;500&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; hexdump -C
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;What This Packet Offers:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Encryption: AES-128-CBC&lt;/li&gt;
&lt;li&gt;Hash: SHA-1&lt;/li&gt;
&lt;li&gt;DH Group: Group 5 (1536-bit MODP)&lt;/li&gt;
&lt;li&gt;Authentication: Pre-Shared Key&lt;/li&gt;
&lt;li&gt;Lifetime: 86400 seconds (24 hours)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="testing-the-complete-datagram"&gt;Testing the Complete Datagram&lt;/h2&gt;
&lt;p&gt;Now that we have our complete ISAKMP packet, let&amp;rsquo;s test it with netcat. The beauty of this approach is that we&amp;rsquo;ll get a proper ISAKMP response back if the peer is functioning correctly, eliminating the need for debug access.&lt;/p&gt;
&lt;h3 id="basic-test"&gt;Basic Test&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; -ne &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$ISAKMP_PACKET&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; nc -u 192.168.1.1 &lt;span class="m"&gt;500&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="enhanced-test-with-timeout"&gt;Enhanced Test with Timeout&lt;/h3&gt;
&lt;p&gt;For better control and to avoid hanging connections, use netcat with a timeout:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; -ne &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$ISAKMP_PACKET&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; timeout &lt;span class="m"&gt;5&lt;/span&gt; nc -u 192.168.1.1 &lt;span class="m"&gt;500&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="capturing-the-response"&gt;Capturing the Response&lt;/h3&gt;
&lt;p&gt;To see the hex response for analysis:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; -ne &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$ISAKMP_PACKET&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; timeout &lt;span class="m"&gt;5&lt;/span&gt; nc -u 192.168.1.1 &lt;span class="m"&gt;500&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; hexdump -C
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="expected-results"&gt;Expected Results&lt;/h2&gt;
&lt;h3 id="analyzing-the-response"&gt;Analyzing the Response&lt;/h3&gt;
&lt;p&gt;When you receive a response, here&amp;rsquo;s how to decode it:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Bytes 0-7 (Initiator Cookie):&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;00 00 00 00 00 00 00 01
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Should match YOUR initiator cookie - confirms this is a reply to your packet.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Bytes 8-15 (Responder Cookie):&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;a1 b2 c3 d4 e5 f6 07 08
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Non-zero random value - the peer&amp;rsquo;s SPI. Save this for multi-packet exchanges.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Byte 16 (Next Payload):&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;01&lt;/code&gt; = SA payload (peer accepted and is proposing parameters)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0d&lt;/code&gt; = Notification payload (usually an error)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Byte 18 (Exchange Type):&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;02&lt;/code&gt; = Identity Protection (Main Mode) - normal&lt;/li&gt;
&lt;li&gt;&lt;code&gt;05&lt;/code&gt; = Informational - usually error notification&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Bytes 24-27 (Length):&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;00 00 00 84
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Total packet length (132 bytes). Longer responses typically mean successful negotiation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Common Notification Payloads:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0e 00&lt;/code&gt; (14) = NO-PROPOSAL-CHOSEN - transform set mismatch&lt;/li&gt;
&lt;li&gt;&lt;code&gt;18 00&lt;/code&gt; (24) = AUTHENTICATION-FAILED - PSK/cert issue&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0d 00&lt;/code&gt; (13) = INVALID-PAYLOAD-TYPE - malformed packet&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="successful-response"&gt;Successful Response&lt;/h3&gt;
&lt;p&gt;If the ISAKMP peer is functioning correctly, you should receive a response that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Has the same initiator cookie&lt;/strong&gt; (&lt;code&gt;00 00 00 00 00 00 00 01&lt;/code&gt;) in the first 8 bytes&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Contains a responder cookie&lt;/strong&gt; (non-zero values in bytes 9-16)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Shows exchange type 02&lt;/strong&gt; (Identity Protection) in byte 18&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Has a reasonable length&lt;/strong&gt; (typically 100+ bytes for a full SA response)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Example successful response header:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;00000000 00 00 00 00 00 00 00 01 a1 b2 c3 d4 e5 f6 07 08 |................|
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;00000010 01 10 02 00 00 00 00 00 00 00 00 84 |............|
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="error-responses"&gt;Error Responses&lt;/h3&gt;
&lt;p&gt;Different error conditions will produce different responses:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;No Matching Transform Sets:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You&amp;rsquo;ll get a response with a Notification payload&lt;/li&gt;
&lt;li&gt;The notification will indicate &amp;ldquo;NO-PROPOSAL-CHOSEN&amp;rdquo; (error 14)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Authentication Issues:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;May receive &amp;ldquo;AUTHENTICATION-FAILED&amp;rdquo; notification&lt;/li&gt;
&lt;li&gt;Or connection may be silently dropped&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Firewall/NAT Issues:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;No response at all (timeout)&lt;/li&gt;
&lt;li&gt;Or ICMP unreachable messages&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="troubleshooting-tips"&gt;Troubleshooting Tips&lt;/h2&gt;
&lt;h3 id="no-response"&gt;No Response&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Check basic connectivity&lt;/strong&gt; first with a simple UDP test&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Verify the target IP&lt;/strong&gt; is actually running ISAKMP/IKE&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Check for NAT/firewall&lt;/strong&gt; blocking UDP/500&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Try different source ports&lt;/strong&gt; - some firewalls are picky&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Wait between attempts&lt;/strong&gt; - rate limiting may block rapid tests (30-60 seconds)&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="malformed-packet-errors"&gt;Malformed Packet Errors&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Double-check the hex string&lt;/strong&gt; - any typos will break the packet&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Verify packet length&lt;/strong&gt; matches the length field in the header&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Test with Wireshark&lt;/strong&gt; to validate packet structure&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="transform-set-mismatches"&gt;Transform Set Mismatches&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Try different encryption algorithms&lt;/strong&gt; (3DES, AES-256)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Adjust DH groups&lt;/strong&gt; (Group 2, Group 14)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Change hash algorithms&lt;/strong&gt; (MD5, SHA-256)&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="nat-considerations"&gt;NAT Considerations&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;NAT Detection:&lt;/strong&gt;
If testing through NAT, be aware:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Source port randomization may break return traffic&lt;/li&gt;
&lt;li&gt;Some firewalls require NAT-T (UDP 4500) for NATed ISAKMP&lt;/li&gt;
&lt;li&gt;ESP (protocol 50) will be blocked by NAT without NAT-T&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Testing through NAT:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Bind to specific source port&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; -ne &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$ISAKMP_PACKET&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; nc -u -p &lt;span class="m"&gt;500&lt;/span&gt; TARGET_IP &lt;span class="m"&gt;500&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;NAT-T Detection:&lt;/strong&gt;
Modern VPN gateways may respond on UDP 4500 instead of 500 if NAT is detected.&lt;/p&gt;
&lt;h3 id="aggressive-mode-vs-main-mode"&gt;Aggressive Mode vs Main Mode&lt;/h3&gt;
&lt;p&gt;This packet uses Main Mode (Identity Protection). If you get no response, the peer might only support Aggressive Mode:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Change Exchange Type from &lt;code&gt;\x02&lt;/code&gt; to &lt;code&gt;\x04&lt;/code&gt; (byte 18)&lt;/li&gt;
&lt;li&gt;Note: Aggressive Mode is deprecated due to security weaknesses&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="ikev2-confusion"&gt;IKEv2 Confusion&lt;/h3&gt;
&lt;p&gt;If you get INVALID_MAJOR_VERSION notification:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Target only supports IKEv2 (RFC 7296)&lt;/li&gt;
&lt;li&gt;This technique only works for IKEv1&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;ike-scan&lt;/code&gt; tool for IKEv2 testing&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="validating-your-packet"&gt;Validating Your Packet&lt;/h3&gt;
&lt;p&gt;Before testing against production systems, validate your packet structure:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Capture your test packet&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; -ne &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$ISAKMP_PACKET&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; nc -u 127.0.0.1 &lt;span class="m"&gt;500&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo tcpdump -i lo -w test.pcap udp port &lt;span class="m"&gt;500&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Open in Wireshark and verify:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ISAKMP protocol is correctly decoded (not &amp;ldquo;Malformed Packet&amp;rdquo;)&lt;/li&gt;
&lt;li&gt;All payload lengths match actual payload sizes&lt;/li&gt;
&lt;li&gt;Transform attributes are properly formatted&lt;/li&gt;
&lt;li&gt;No &amp;ldquo;Expert Info&amp;rdquo; warnings about malformed fields&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="alternative-tools"&gt;Alternative Tools&lt;/h2&gt;
&lt;p&gt;While this manual method teaches protocol internals, consider these tools for production use:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ike-scan:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ike-scan -M TARGET_IP
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;Supports IKEv1 and IKEv2&lt;/li&gt;
&lt;li&gt;Tests multiple transform sets automatically&lt;/li&gt;
&lt;li&gt;Better for production troubleshooting&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;nmap:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nmap -sU -p &lt;span class="m"&gt;500&lt;/span&gt; --script ike-version TARGET_IP
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;Detects IKE version support&lt;/li&gt;
&lt;li&gt;Identifies vendor implementations&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;When to use manual method:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Learning protocol internals&lt;/li&gt;
&lt;li&gt;Highly restricted environments (no tools available)&lt;/li&gt;
&lt;li&gt;Testing specific edge cases&lt;/li&gt;
&lt;li&gt;Forensic analysis of VPN behavior&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;By using a pre-crafted complete ISAKMP datagram, we&amp;rsquo;ve eliminated the dependency on having debug access to the peer device. This approach validates outbound connectivity (UDP/500 reachability), peer responsiveness, and return path functionality - all without needing access to the remote device.&lt;/p&gt;
&lt;p&gt;For a detailed breakdown of how this packet was constructed, see &lt;a href="./posts/2026/netcat-isakmp-3/"&gt;Part 3&lt;/a&gt;. For automated testing with Python and Scapy, check out &lt;a href="./posts/2026/netcat-isakmp-4/"&gt;Part 4&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="references"&gt;References&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Next Steps:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Want to understand how this packet was built? Read &lt;a href="./posts/2026/netcat-isakmp-3/"&gt;Part 3&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Explore automating this with Python and the Scapy library&lt;/li&gt;
&lt;li&gt;Check out &lt;code&gt;ike-scan&lt;/code&gt; for more advanced VPN testing scenarios&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Parsing Network Device Output Part 3: CiscoConfParse</title><link>/posts/2026/parsing-netdevice-output-3/</link><pubDate>Mon, 19 Jan 2026 10:55:00 -0500</pubDate><guid>/posts/2026/parsing-netdevice-output-3/</guid><description>&lt;p&gt;In the first post in this series, I talked briefly about &lt;a href="./posts/2020/parsing-netdevice-output-1/"&gt;utilizing Regular Expressions (Regex)&lt;/a&gt; to parse network device output. Next, I delved into &lt;a href="./posts/2020/parsing-netdevice-output-2/"&gt;the difference between status and configuration&lt;/a&gt; when it comes to network device output, and why you might use one tool vs another depending on which type of output you are working with.&lt;/p&gt;
&lt;p&gt;As a brief refresher, network device output (from a traditional CLI session) can generally come in two forms:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Status
&lt;ul&gt;
&lt;li&gt;An output that presents some attribute or information about the current state of the device or its performance.&lt;/li&gt;
&lt;li&gt;Example commands for gathering status include:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;show version&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;show interfaces&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Example commands for modifying status include:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;clear counters&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;reload&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Configuration
&lt;ul&gt;
&lt;li&gt;An output that presents the desired/requested operating condition of the device.&lt;/li&gt;
&lt;li&gt;Example commands for gathering configuration include:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;show running-config&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;show startup-config&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In this post, we&amp;rsquo;ll look at one of the open-source parsing libraries that exist for network device configuration: &lt;a href="http://www.pennington.net/py/ciscoconfparse/"&gt;CiscoConfParse&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="why-not-just-use-regex"&gt;Why Not Just Use Regex?&lt;/h2&gt;
&lt;p&gt;CiscoConfParse, as well as &lt;a href="https://github.com/netdevops/hier_config"&gt;Hierarchical Configuration (heir_config)&lt;/a&gt; which we&amp;rsquo;ll cover in the next post, provide much more power than simply using Regex to match and extract a pattern from a line of status or configuration. These parsing libraries provide a framework to understand and manipulate &amp;ldquo;Cisco style&amp;rdquo; configuration (with indented blocks representing related items), or even &amp;ldquo;Juniper style&amp;rdquo; curly brace (&lt;code&gt;{}&lt;/code&gt;) delineated configuration.&lt;/p&gt;
&lt;p&gt;If you think about the previous Regex example, how would we utilize Regex to easily parse the following configuration output, specifically looking to answer this question:&lt;/p&gt;
&lt;p&gt;What interfaces have &lt;code&gt;security-level 0&lt;/code&gt; configured on them?&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-cisco" data-lang="cisco"&gt;!
interface GigabitEthernet0/0
description OUTSIDE-VLAN300-10.10.10.0/24
nameif OUTSIDE
security-level 0
ip address 10.10.10.50 255.255.255.0
!
interface GigabitEthernet0/1
no nameif
no security-level
no ip address
!
interface GigabitEthernet0/1.400
description INSIDE-VLAN400-10.10.40.0/24
vlan 400
nameif INSIDE
security-level 100
ip address 10.10.40.1 255.255.255.0
!
interface Management0/0
management-only
nameif MGMT
security-level 0
ip address 10.10.60.2 255.255.255.0
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;For example, you can certainly search for the string &amp;ldquo;&lt;code&gt;security-level 0&lt;/code&gt;&amp;rdquo;, however how do you then tie it back to the interface above it? Remember that when we&amp;rsquo;re evaluating a string with Regex, we can work on a multi-line string.
We would have to set up capturing groups for the &lt;code&gt;interface&lt;/code&gt; and &lt;code&gt;nameif&lt;/code&gt;, and then only match if there was also our target string.
And while, of course, this is doable, it quickly becomes cumbersome to do for every item you wish to match.
Also consider, what if you want to output the entire interface configuration for any interface that matches &amp;ldquo;&lt;code&gt;security-level 0&lt;/code&gt;&amp;rdquo;?
There is a better and simpler way to handle this.&lt;/p&gt;
&lt;h2 id="enter-ciscoconfparse"&gt;Enter CiscoConfParse&lt;/h2&gt;
&lt;p&gt;CiscoConfParse solves this problem, and more, by breaking the configuration into parent/child chunks and allowing you to search and find based on the contents of either.
For an in-depth walk-through and examples I highly recommend the &lt;a href="http://www.pennington.net/py/ciscoconfparse/installation.html#using-ciscoconfparse"&gt;CiscoConfParse documentation&lt;/a&gt;; below we&amp;rsquo;ll simply demonstrate a quick use case.&lt;/p&gt;
&lt;p&gt;For our test environment, we&amp;rsquo;re utilizing the same firewall pair and management station &lt;a href="./posts/2020/parsing-netdevice-output-1/"&gt;from the previous post&lt;/a&gt;:&lt;/p&gt;
&lt;img src="./img/2020/nn_example_parse_net_device_config-2.png" alt="Image of a Person sitting at a computer connecting to two firewall devices." class="center" style="border-radius: 8px;" /&gt;
&lt;p&gt;In this series of posts, we&amp;rsquo;ll just use the simple network shown here. There is a Management Station with Python 3.8 installed, and two Cisco ASAv firewalls (ASAv1 and ASAv2) in a tiered setup.&lt;/p&gt;
&lt;p&gt;Code samples and &lt;code&gt;requirements.txt&lt;/code&gt; for this post can be found &lt;a href="https://github.com/lykinsbd/nn_examples/tree/master/parsing_net_devices"&gt;on my Github&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Below is an example script, based on the previous examples in this series, where we log into these ASAs, gather the output of &lt;code&gt;show run interface&lt;/code&gt;, and print out the interface(s) with &lt;code&gt;security-level 0&lt;/code&gt; configured.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;span class="lnt"&gt;32
&lt;/span&gt;&lt;span class="lnt"&gt;33
&lt;/span&gt;&lt;span class="lnt"&gt;34
&lt;/span&gt;&lt;span class="lnt"&gt;35
&lt;/span&gt;&lt;span class="lnt"&gt;36
&lt;/span&gt;&lt;span class="lnt"&gt;37
&lt;/span&gt;&lt;span class="lnt"&gt;38
&lt;/span&gt;&lt;span class="lnt"&gt;39
&lt;/span&gt;&lt;span class="lnt"&gt;40
&lt;/span&gt;&lt;span class="lnt"&gt;41
&lt;/span&gt;&lt;span class="lnt"&gt;42
&lt;/span&gt;&lt;span class="lnt"&gt;43
&lt;/span&gt;&lt;span class="lnt"&gt;44
&lt;/span&gt;&lt;span class="lnt"&gt;45
&lt;/span&gt;&lt;span class="lnt"&gt;46
&lt;/span&gt;&lt;span class="lnt"&gt;47
&lt;/span&gt;&lt;span class="lnt"&gt;48
&lt;/span&gt;&lt;span class="lnt"&gt;49
&lt;/span&gt;&lt;span class="lnt"&gt;50
&lt;/span&gt;&lt;span class="lnt"&gt;51
&lt;/span&gt;&lt;span class="lnt"&gt;52
&lt;/span&gt;&lt;span class="lnt"&gt;53
&lt;/span&gt;&lt;span class="lnt"&gt;54
&lt;/span&gt;&lt;span class="lnt"&gt;55
&lt;/span&gt;&lt;span class="lnt"&gt;56
&lt;/span&gt;&lt;span class="lnt"&gt;57
&lt;/span&gt;&lt;span class="lnt"&gt;58
&lt;/span&gt;&lt;span class="lnt"&gt;59
&lt;/span&gt;&lt;span class="lnt"&gt;60
&lt;/span&gt;&lt;span class="lnt"&gt;61
&lt;/span&gt;&lt;span class="lnt"&gt;62
&lt;/span&gt;&lt;span class="lnt"&gt;63
&lt;/span&gt;&lt;span class="lnt"&gt;64
&lt;/span&gt;&lt;span class="lnt"&gt;65
&lt;/span&gt;&lt;span class="lnt"&gt;66
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="ch"&gt;#!/usr/bin/env python3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;Example code for Network-Notes.com entry on Parsing Network Device Output
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;getpass&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;sys&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;ciscoconfparse&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;CiscoConfParse&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;netmiko&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ConnectHandler&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;Test parsing network device configuration
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Gather the needed credentials&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;net_device_username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Username: &amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;net_device_password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;getpass&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getpass&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Set enable/secret = password for now&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;net_device_secret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;net_device_password&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Setup a dict with our ASAvs in it, in real world this could be read&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# from a CSV or the CLI or any other source&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;firewalls&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;ASAv1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;ip&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;10.10.10.50&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;platform&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;cisco_asa&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;ASAv2&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;ip&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;10.10.60.2&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;platform&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;cisco_asa&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Setup an empty dict for our results:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Instantiate netmiko connection objects and gather the output of&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# `show run interface` on these two firewalls&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;fw_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fw_data&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;firewalls&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Connecting to &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;fw_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;...&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;fw_connection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ConnectHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;fw_data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;ip&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;device_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;fw_data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;platform&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;net_device_username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;net_device_password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;net_device_secret&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;fw_name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fw_connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;send_command&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;command_string&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;show run interface&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Parse our results:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Parsing Results...&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;outside_interfaces&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;fw_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;interface_config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CiscoConfParse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;splitlines&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;outside_interfaces&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;fw_name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;interface_config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;find_objects_w_child&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;parentspec&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;^interface&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;childspec&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;security-level 0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Print our results&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;fw_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;interface_list&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;outside_interfaces&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;==== ==== [ &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;fw_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&amp;#34;&lt;/span&gt;&lt;span class="s2"&gt;Outside&lt;/span&gt;&lt;span class="se"&gt;\&amp;#34;&lt;/span&gt;&lt;span class="s2"&gt; interfaces ] ==== ====&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;interface&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;interface_list&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34; ==== [ &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;interface&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; ] ==== &lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;interface&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ioscfg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;It will produce the following output when executed:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-cisco" data-lang="cisco"&gt;Username: cisco
Password:
Connecting to ASAv1â€¦
Connecting to ASAv2â€¦
Parsing Resultsâ€¦
==== ==== [ ASAv1 &amp;#34;Outside&amp;#34; interfaces ] ==== ====
==== [ interface GigabitEthernet0/0 ] ====
interface GigabitEthernet0/0
description OUTSIDE-VLAN300-10.10.10.0/24
nameif OUTSIDE
security-level 0
ip address 10.10.10.50 255.255.255.0
ospf authentication-key
ospf message-digest-key 1 md5
ospf authentication message-digest
==== ==== [ ASAv2 &amp;#34;Outside&amp;#34; interfaces ] ==== ====
==== [ interface Management0/0 ] ====
interface Management0/0
management-only
nameif MGMT
security-level 0
ip address 10.10.60.2 255.255.255.0
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As you can see, we easily found the interfaces we needed, and have the entire configuration. Now let&amp;rsquo;s break apart what happened a little bit more.&lt;/p&gt;
&lt;h2 id="parentchild-relationships"&gt;Parent/Child Relationships&lt;/h2&gt;
&lt;p&gt;CiscoConfParse understands the hierarchical nature of Cisco-style configuration. In our example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Parent&lt;/strong&gt;: &lt;code&gt;interface GigabitEthernet0/0&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Children&lt;/strong&gt;: All indented lines under that interface (description, nameif, security-level, etc.)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The key method in our script is:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;interface_config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;find_objects_w_child&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;parentspec&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;^interface&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;childspec&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;security-level 0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;This searches for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;parentspec&lt;/strong&gt;: Lines matching regex &lt;code&gt;^interface&lt;/code&gt; (lines starting with &amp;ldquo;interface&amp;rdquo;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;childspec&lt;/strong&gt;: That have a child line containing &amp;ldquo;security-level 0&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The result is a list of &lt;code&gt;IOSCfgLine&lt;/code&gt; objects representing matching parent interfaces.&lt;/p&gt;
&lt;h2 id="key-ciscoconfparse-methods"&gt;Key CiscoConfParse Methods&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;find_objects()&lt;/code&gt; - Find lines matching a regex pattern&lt;/li&gt;
&lt;li&gt;&lt;code&gt;find_objects_w_child()&lt;/code&gt; - Find parents with specific children&lt;/li&gt;
&lt;li&gt;&lt;code&gt;find_objects_wo_child()&lt;/code&gt; - Find parents without specific children&lt;/li&gt;
&lt;li&gt;&lt;code&gt;find_children()&lt;/code&gt; - Find all children of a parent&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Each object provides:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;.text&lt;/code&gt; - The configuration line text&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.ioscfg&lt;/code&gt; - Complete configuration block (parent + children)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.children&lt;/code&gt; - List of child objects&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="why-this-matters"&gt;Why This Matters&lt;/h2&gt;
&lt;p&gt;Compare this to the regex approach from Part 1. To find interfaces with &lt;code&gt;security-level 0&lt;/code&gt; using regex, you&amp;rsquo;d need complex multi-line patterns and capturing groups. CiscoConfParse makes it intuitive by understanding configuration structure.&lt;/p&gt;
&lt;p&gt;This is particularly powerful for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Security audits (find interfaces with specific settings)&lt;/li&gt;
&lt;li&gt;Configuration validation (ensure required settings exist)&lt;/li&gt;
&lt;li&gt;Bulk changes (identify what needs updating)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="whats-next"&gt;What&amp;rsquo;s Next&lt;/h2&gt;
&lt;p&gt;In the next post, we&amp;rsquo;ll explore Hierarchical Configuration (hier_config), which builds on these concepts to provide configuration comparison and remediation capabilities.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;CiscoConfParse transforms configuration parsing from complex regex gymnastics into readable, maintainable code. By understanding parent/child relationships in network configurations, it makes complex parsing tasks simple and intuitive.&lt;/p&gt;</description></item><item><title>Migrating from WordPress to Hugo on Cloudflare Pages</title><link>/posts/2023/migrating-to-hugo/</link><pubDate>Tue, 11 Jul 2023 13:42:23 -0400</pubDate><guid>/posts/2023/migrating-to-hugo/</guid><description>&lt;p&gt;After years of running WordPress on a self-hosted DigitalOcean droplet, I decided it was time for a change. The site was slow, required constant maintenance, and felt like overkill for a simple blog. Here&amp;rsquo;s how I migrated to Hugo and Cloudflare Pages.&lt;/p&gt;
&lt;h2 id="the-old-setup"&gt;The Old Setup&lt;/h2&gt;
&lt;p&gt;My previous infrastructure:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Hosting&lt;/strong&gt;: DigitalOcean droplet ($12/month)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CMS&lt;/strong&gt;: Self-hosted WordPress with MySQL&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CDN&lt;/strong&gt;: Cloudflare (free tier) in front&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Maintenance&lt;/strong&gt;: Regular updates, security patches, backups&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Performance&lt;/strong&gt;: Decent, but database queries added latency&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The droplet ran Ubuntu with Apache, PHP, MySQL, and all the typical WordPress stack. It worked, but it felt heavy for what was essentially a collection of markdown-style posts.&lt;/p&gt;
&lt;h2 id="why-hugo"&gt;Why Hugo?&lt;/h2&gt;
&lt;p&gt;I wanted something:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Fast&lt;/strong&gt;: Static sites are blazing fast&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Simple&lt;/strong&gt;: No database, no PHP, just HTML/CSS/JS&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Portable&lt;/strong&gt;: Content in markdown, easy to version control&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Free&lt;/strong&gt;: Cloudflare Pages offers free hosting&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Secure&lt;/strong&gt;: No CMS to hack, no database to compromise&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Hugo checked all these boxes. It&amp;rsquo;s a static site generator written in Go that&amp;rsquo;s incredibly fast and has a great ecosystem of themes.&lt;/p&gt;
&lt;h2 id="the-migration-process"&gt;The Migration Process&lt;/h2&gt;
&lt;h3 id="1-export-wordpress-content"&gt;1. Export WordPress Content&lt;/h3&gt;
&lt;p&gt;I used the built-in WordPress export tool to generate an XML file with all posts, then converted them to markdown format. Several tools exist for this conversion, including wordpress-to-hugo-exporter and various online converters. Manual cleanup was necessary afterward to fix formatting inconsistencies.&lt;/p&gt;
&lt;h3 id="2-choose-a-theme"&gt;2. Choose a Theme&lt;/h3&gt;
&lt;p&gt;I selected the &lt;a href="https://themes.gohugo.io/themes/hugo-theme-terminal/"&gt;Terminal theme&lt;/a&gt; for its clean, minimal design. The retro terminal aesthetic fits well with technical content and provides excellent readability.&lt;/p&gt;
&lt;h3 id="3-set-up-hugo-locally"&gt;3. Set Up Hugo Locally&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Install Hugo&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;brew install hugo
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Create new site&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;hugo new site network-notes.com
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; network-notes.com
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Add theme&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git submodule add https://github.com/panr/hugo-theme-terminal.git themes/terminal
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Configure&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cp themes/terminal/exampleSite/config.toml .
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Edit config.toml with my settings&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="4-migrate-content"&gt;4. Migrate Content&lt;/h3&gt;
&lt;p&gt;I moved all the converted markdown files into &lt;code&gt;content/posts/&lt;/code&gt; organized by year:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;content/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└── posts/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ├── 2015/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ├── 2016/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └── 2020/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Each post needed some cleanup - fixing image paths, updating internal links, and adjusting frontmatter.&lt;/p&gt;
&lt;h3 id="5-set-up-cloudflare-pages"&gt;5. Set Up Cloudflare Pages&lt;/h3&gt;
&lt;p&gt;Cloudflare Pages is incredibly simple:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Push Hugo site to GitHub&lt;/li&gt;
&lt;li&gt;Connect GitHub repo to Cloudflare Pages&lt;/li&gt;
&lt;li&gt;Configure build settings:
&lt;ul&gt;
&lt;li&gt;Build command: &lt;code&gt;hugo&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Build output directory: &lt;code&gt;public&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Environment variable: &lt;code&gt;HUGO_VERSION=0.120.0&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;That&amp;rsquo;s it. Every push to &lt;code&gt;main&lt;/code&gt; triggers a new build and deployment.&lt;/p&gt;
&lt;h3 id="6-configure-dns"&gt;6. Configure DNS&lt;/h3&gt;
&lt;p&gt;Updated my Cloudflare DNS to point to Pages:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;network-notes.com → CNAME → network-notes-com.pages.dev (proxied)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;I also set up a preview branch:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;blog2.network-notes.com → CNAME → preview.network-notes-com.pages.dev (proxied)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;This lets me review posts before publishing to production.&lt;/p&gt;
&lt;h3 id="7-decommission-digitalocean"&gt;7. Decommission DigitalOcean&lt;/h3&gt;
&lt;p&gt;Once everything was working, I:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Backed up the WordPress database (just in case)&lt;/li&gt;
&lt;li&gt;Took a final snapshot of the droplet&lt;/li&gt;
&lt;li&gt;Destroyed the droplet&lt;/li&gt;
&lt;li&gt;Saved $12/month&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="the-results"&gt;The Results&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Performance&lt;/strong&gt;: Page load times dropped from ~800ms to ~200ms. Static HTML is fast.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Maintenance&lt;/strong&gt;: Zero. No more WordPress updates, no more security patches, no more database backups.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cost&lt;/strong&gt;: $0/month for hosting (Cloudflare Pages free tier is generous)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Workflow&lt;/strong&gt;: Write in markdown, commit to git, automatic deployment. Much better than the WordPress editor.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Reliability&lt;/strong&gt;: Cloudflare&amp;rsquo;s global CDN means the site is fast everywhere and has excellent uptime.&lt;/p&gt;
&lt;h2 id="infrastructure-as-code"&gt;Infrastructure as Code&lt;/h2&gt;
&lt;p&gt;I manage all my DNS and Cloudflare configuration with Terraform. The network-notes.com configuration includes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;DNS records&lt;/li&gt;
&lt;li&gt;Page rules for caching&lt;/li&gt;
&lt;li&gt;SSL/TLS settings&lt;/li&gt;
&lt;li&gt;Preview branch setup&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Everything is version controlled and reproducible, making it easy to recreate or modify the infrastructure.&lt;/p&gt;
&lt;h2 id="lessons-learned"&gt;Lessons Learned&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Markdown is powerful&lt;/strong&gt;: Once you get used to writing in markdown, it&amp;rsquo;s hard to go back to WYSIWYG editors.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Static sites aren&amp;rsquo;t limiting&lt;/strong&gt;: For a blog, you don&amp;rsquo;t need dynamic content. Comments can be handled by external services if needed.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Git-based workflows are great&lt;/strong&gt;: Having your entire site in version control is liberating. Rollbacks are trivial, history is preserved, and collaboration is easy.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cloudflare Pages is excellent&lt;/strong&gt;: The free tier is generous, builds are fast, and the preview deployments are incredibly useful.&lt;/p&gt;
&lt;h2 id="would-i-recommend-it"&gt;Would I Recommend It?&lt;/h2&gt;
&lt;p&gt;Absolutely, if you&amp;rsquo;re running a simple blog or documentation site. The migration took a weekend, but the ongoing benefits are worth it:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;No more server maintenance&lt;/li&gt;
&lt;li&gt;Faster site&lt;/li&gt;
&lt;li&gt;Better workflow&lt;/li&gt;
&lt;li&gt;Lower costs&lt;/li&gt;
&lt;li&gt;More secure&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you need dynamic features (user accounts, complex forms, e-commerce), WordPress or another CMS might still make sense. But for content-focused sites, static site generators like Hugo are hard to beat.&lt;/p&gt;
&lt;h2 id="resources"&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://gohugo.io/documentation/"&gt;Hugo Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developers.cloudflare.com/pages/"&gt;Cloudflare Pages Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://themes.gohugo.io/themes/hugo-theme-terminal/"&gt;Terminal Theme&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The blog is now faster, cheaper, and easier to maintain. Sometimes simpler really is better.&lt;/p&gt;</description></item><item><title>Parsing Network Device Output Part 2: Status or Configuration?</title><link>/posts/2020/parsing-netdevice-output-2/</link><pubDate>Sat, 21 Mar 2020 20:01:00 -0500</pubDate><guid>/posts/2020/parsing-netdevice-output-2/</guid><description>&lt;h2 id="a-brief-interlude"&gt;A Brief Interlude&lt;/h2&gt;
&lt;p&gt;In my first post in this series, I dove into &lt;a href="./posts/2020/parsing-netdevice-output-1/"&gt;utilizing Regular Expressions (Regex) to parse network device output&lt;/a&gt;. Before I continue with some of the other parsing options, I thought it would be worthwhile to post a short blog laying out some definitions that I’ll be relying on. Specifically, I&amp;rsquo;ll be using them for delineation among the different parsing options and their use cases.&lt;/p&gt;
&lt;p&gt;At the heart of this problem, is that when interacting with traditional network devices there aren’t many programmatic options, such as a REST API, to return structured data. Sure, you could use SNMP for &lt;em&gt;some things&lt;/em&gt;, but not for everything. In addition, working with SNMP can be its type of nightmare, believe me, I’ve fought that fight many times in the past. This is changing as the industry matures, Cisco even has an entire certification track around utilizing their APIs now, however even today most Network Engineers&amp;rsquo; first foray into automation uses SSH to query a device for information. This brings us to output.&lt;/p&gt;
&lt;h2 id="what-is-output"&gt;What is Output?&lt;/h2&gt;
&lt;p&gt;For our purposes, &amp;ldquo;Output&amp;rdquo; will be defined as any response that a network device returns when given a command via its Command Line Interface (CLI). This could be accomplished by many means; depending on the network device in question the CLI could be reached via Telnet, SSH, or even HTTPS. No matter the access method, the network device is still returning the same data, our output.&lt;/p&gt;
&lt;p&gt;Execute &lt;code&gt;show version&lt;/code&gt; on a Cisco-like device, and it will return some form of the status of the version as that device understands it. It will be structured, loosely, for human consumption with perhaps headings/titles or indentation/punctuation for legibility. It will &lt;strong&gt;not&lt;/strong&gt; generally be structured in a way that would easily allow a computer program to understand and interact with it.&lt;/p&gt;
&lt;p&gt;Just as you can issue &lt;code&gt;show version&lt;/code&gt; and get output, you can similarly on most network devices execute a command akin to &lt;code&gt;show running-config&lt;/code&gt; and get output. This would return some form of data about the configuration that was currently in use on that network device. Again, it will have some form of structure, usually either delineated by indentation or curly braces (&lt;code&gt;{}&lt;/code&gt;), but mostly it will be in a form that is not easily understood or manipulated by a computer program that you are writing.&lt;/p&gt;
&lt;p&gt;I make the specific call out that it may not easily be understood by a program that &lt;em&gt;you are writing&lt;/em&gt; because of course the network device itself can take that configuration and turn it into actionable information. However, that does us no good, as most vendors aren’t open sourcing their internal operating systems&amp;rsquo; parsing logic.&lt;/p&gt;
&lt;h2 id="status-vs-configuration"&gt;Status vs. Configuration&lt;/h2&gt;
&lt;p&gt;In the two examples above, we received output from a network device after we issued a command via the CLI. One gave us some sort of status about the device, and the other gave us information about its configuration. Broadly speaking, all CLI commands on a network device fall into these two categories. You are either gathering or changing the status of the device with commands such as &lt;code&gt;show version&lt;/code&gt;, &lt;code&gt;show flash&lt;/code&gt;, or &lt;code&gt;clear counters&lt;/code&gt;. Or you are gathering or changing the configuration of the device with commands such as &lt;code&gt;show running-config&lt;/code&gt;, or &lt;code&gt;config t;interface e1/0;no shutdown&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;It is vital to keep in mind which type of information you’re looking for or what changes you are trying to make, and whether it involves the device’s status or configuration. This will heavily influence how you parse/interact with the output that the device has given you. Some parsing methods or libraries are made specifically for turning configuration into something easy to manipulate/change in Python (CiscoConfParse, Heir Config), and some are more generic and can parse both status and configuration (Regex, TextFSM, Genie).&lt;/p&gt;
&lt;p&gt;In the next post, I’ll dive into &lt;strong&gt;CiscoConfParse&lt;/strong&gt; first, and we’ll see how it can make the act of understanding and manipulating traditional unstructured network device configuration much simpler.&lt;/p&gt;</description></item><item><title>Parsing Network Device Output Part 1: Regex</title><link>/posts/2020/parsing-netdevice-output-1/</link><pubDate>Wed, 04 Mar 2020 20:17:00 -0500</pubDate><guid>/posts/2020/parsing-netdevice-output-1/</guid><description>&lt;h2 id="in-the-beginning"&gt;In the Beginning&lt;/h2&gt;
&lt;p&gt;Often when making their first steps into Network Automation, people may have an idea of what they want to do, but not exactly how to get there. For example, an engineer may want to simplify a single time-intensive task “Gather the SW version, serial numbers, and uptime from all of my Cisco ASAs.” However, upon getting the information, they’re unsure what to do with it or how to parse it and use it for something else. I’ve seen this question come up a few different times, and thought a series of blog posts was in order. Each of the posts (including this one) outline some sample parsing options. However, it is worth noting that Regex is not better or worse than using a parsing library, for example, they may just have different use cases.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;First, in this post, I will outline the basics of gathering our information and parsing it directly with our own Regular Expressions (Regex).&lt;/li&gt;
&lt;li&gt;Next, I will demonstrate parsing this information with the popular &lt;a href="https://github.com/mpenning/ciscoconfparse"&gt;CiscoConfParse&lt;/a&gt; and &lt;a href="https://github.com/netdevops/hier_config"&gt;HeirConfig&lt;/a&gt; libraries.&lt;/li&gt;
&lt;li&gt;Third, I will demonstrate simple parsing with Google’s &lt;a href="https://github.com/google/textfsm"&gt;TextFSM&lt;/a&gt; and the awesome library of templates provided by &lt;a href="https://www.networktocode.com/"&gt;Network To Code&lt;/a&gt;, &lt;a href="https://github.com/networktocode/ntc-templates"&gt;ntc-templates&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Finally, I will demonstrate simple parsing with Cisco’s &lt;a href="https://developer.cisco.com/docs/pyats/"&gt;Genie/PyATS&lt;/a&gt; libraries.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note that I am going to skip over a lot of the minutia of &lt;a href="https://pynet.twb-tech.com/blog/automation/netmiko.html"&gt;what Netmiko is&lt;/a&gt;, and &lt;a href="https://pynet.twb-tech.com/blog/automation/netmiko.html"&gt;how to use it&lt;/a&gt; to gather network device information, as there are &lt;a href="https://codingpackets.com/blog/netmiko-getting-started"&gt;many&lt;/a&gt; &lt;a href="https://www.charleslabri.com/python-lesson-5-netmiko/"&gt;wonderful&lt;/a&gt; &lt;a href="https://medium.com/@jrecchia0/intro-to-network-automation-with-python-and-netmiko-a80f08a0c2c2"&gt;resources&lt;/a&gt; out there already on this. We’re going to focus primarily on what to do with the output once you have it.&lt;/p&gt;
&lt;figure&gt;&lt;img src="./img/2020/nn_example_parse_net_device_config-2.png"
alt="Image of a Person sitting at a computer connecting to two firewall devices."&gt;&lt;figcaption&gt;
&lt;p&gt;Example Network&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;In this series of posts, we’ll just use the simple network shown here. There is a Management Station with Python 3.8 installed, and two Cisco ASAv firewalls (ASAv1 and ASAv2) in a tiered setup.&lt;/p&gt;
&lt;p&gt;Code samples and “requirements.txt” for this post can be found &lt;a href="https://github.com/lykinsbd/nn_examples/tree/master/parsing_net_devices"&gt;on my Github&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="environment-preparation"&gt;Environment Preparation&lt;/h2&gt;
&lt;p&gt;For this entire series of posts, I will be working the examples in a python virtual environment setup with the following dependencies installed. Note that we’re installing iPython, which is a much better alternative to the built in Python interactive shell. I highly recommend &lt;a href="https://ipython.readthedocs.io/en/stable/"&gt;checking it out&lt;/a&gt; by executing &lt;code&gt;ipython&lt;/code&gt; in this virtual environment. iPython allows us to do some more interactive introspection on objects and method/object doc_strings in real time, which we’ll use in later posts.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;iPython&lt;/li&gt;
&lt;li&gt;Netmiko&lt;/li&gt;
&lt;li&gt;CiscoConfParse&lt;/li&gt;
&lt;li&gt;HeirConfig&lt;/li&gt;
&lt;li&gt;NTC Templates&lt;/li&gt;
&lt;li&gt;Genie/PyATS&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;First, I create a virtual environment with whatever name you wish, and then activate that environment:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;python3.8 -m venv nn_examples
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; nn_examples&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="nb"&gt;source&lt;/span&gt; bin/activate
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Next, I install the dependencies as discussed above:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pip install ciscoconfparse genie hier-config ipython netmiko ntc_templates pyats
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="gathering-our-output"&gt;Gathering our Output&lt;/h2&gt;
&lt;p&gt;We need to instantiate a connection to our ASAs, and then execute the command “show version | inc So|Serial| up” against them to gather the needed output. Simple enough with Netmiko as shown below (&lt;a href="https://github.com/lykinsbd/nn_examples/blob/master/parsing_net_devices/raw_gather.py"&gt;or on Github&lt;/a&gt;):&lt;/p&gt;
&lt;details class="collapsable-code" &gt;
&lt;summary title="Click to interact"&gt;&lt;span class="collapsable-code__title"&gt;raw_gather.py&lt;/span&gt;&lt;/summary&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;span class="lnt"&gt;32
&lt;/span&gt;&lt;span class="lnt"&gt;33
&lt;/span&gt;&lt;span class="lnt"&gt;34
&lt;/span&gt;&lt;span class="lnt"&gt;35
&lt;/span&gt;&lt;span class="lnt"&gt;36
&lt;/span&gt;&lt;span class="lnt"&gt;37
&lt;/span&gt;&lt;span class="lnt"&gt;38
&lt;/span&gt;&lt;span class="lnt"&gt;39
&lt;/span&gt;&lt;span class="lnt"&gt;40
&lt;/span&gt;&lt;span class="lnt"&gt;41
&lt;/span&gt;&lt;span class="lnt"&gt;42
&lt;/span&gt;&lt;span class="lnt"&gt;43
&lt;/span&gt;&lt;span class="lnt"&gt;44
&lt;/span&gt;&lt;span class="lnt"&gt;45
&lt;/span&gt;&lt;span class="lnt"&gt;46
&lt;/span&gt;&lt;span class="lnt"&gt;47
&lt;/span&gt;&lt;span class="lnt"&gt;48
&lt;/span&gt;&lt;span class="lnt"&gt;49
&lt;/span&gt;&lt;span class="lnt"&gt;50
&lt;/span&gt;&lt;span class="lnt"&gt;51
&lt;/span&gt;&lt;span class="lnt"&gt;52
&lt;/span&gt;&lt;span class="lnt"&gt;53
&lt;/span&gt;&lt;span class="lnt"&gt;54
&lt;/span&gt;&lt;span class="lnt"&gt;55
&lt;/span&gt;&lt;span class="lnt"&gt;56
&lt;/span&gt;&lt;span class="lnt"&gt;57
&lt;/span&gt;&lt;span class="lnt"&gt;58
&lt;/span&gt;&lt;span class="lnt"&gt;59
&lt;/span&gt;&lt;span class="lnt"&gt;60
&lt;/span&gt;&lt;span class="lnt"&gt;61
&lt;/span&gt;&lt;span class="lnt"&gt;62
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# !/usr/bin/env python3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;Example code for Network-Notes.com entry on Parsing Network Device Output
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;getpass&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;re&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;sys&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;netmiko&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ConnectHandler&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;Test parsing network device configuration
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Gather the needed credentials&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;net_device_username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Username: &amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;net_device_password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;getpass&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getpass&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Set enable/secret = password for now&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;net_device_secret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;net_device_password&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Setup a dict with our ASAvs in it, in real world this could be read&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# from a CSV or the CLI or any other source&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;firewalls&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;ASAv1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;ip&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;10.10.10.50&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;platform&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;cisco_asa&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;ASAv2&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;ip&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;10.10.60.2&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;platform&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;cisco_asa&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Setup an empty dict for our results&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Instantiate netmiko connection objects and gather the output of&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# `show version | inc So|Serial| up` on these two firewalls&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;fw_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fw_data&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;firewalls&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Connecting to &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;fw_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;...&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;fw_connection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ConnectHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;fw_data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;ip&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;device_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;fw_data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;platform&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;net_device_username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;net_device_password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;net_device_secret&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;fw_name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fw_connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;send_command&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;command_string&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;show version | inc So|Serial| up&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Print our results&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;fw_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;fw_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; information:&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/details&gt;
&lt;p&gt;Successfully executed with “python3.8 raw_gather.py”, this will output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Username: cisco
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Password:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Connecting to ASAv1â€¦
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Connecting to ASAv2â€¦
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ASAv1 information:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Cisco Adaptive Security Appliance Software Version 9.12(1)2
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ASAv1 up 23 mins 50 secs
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Serial Number: 123456789AB
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ASAv2 information:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Cisco Adaptive Security Appliance Software Version 9.13(1)2
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ASAv2 up 24 mins 5 secs
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Serial Number: 123456789AC
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Now that we have an example of gathering the information, let’s parse it to python variables via Regex.&lt;/p&gt;
&lt;h2 id="parsing-with-regex"&gt;Parsing with Regex&lt;/h2&gt;
&lt;p&gt;Much like above, I will not exhaustively cover what Regex (Regular Expressions) are, as there are boundless resources on the internet (&lt;a href="https://www.amazon.com/Mastering-Regular-Expressions-Jeffrey-Friedl/dp/0596528124"&gt;and good old O’Reilly books&lt;/a&gt;) that do this. Suffice to say for our purposes, that it is a way to match patterns in a string of text and gather output based on that, and that I strongly recommend finding a good test bed like &lt;a href="https://regex101.com/"&gt;Regex101&lt;/a&gt; to help you along the way. You can get extremely complicated with Regex, and it can also bite you in the behind, &lt;a href="https://blog.cloudflare.com/details-of-the-cloudflare-outage-on-july-2-2019/"&gt;just ask Cloudflare&lt;/a&gt;… Here is the three Regular Expressions I am using to match relevant output from the ASA with links to Regex101 examples demonstrating them.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://regex101.com/r/UhumV2/4"&gt;Software Version&lt;/a&gt;:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Software Version (\d.\d{1,2}(?:(?\d{1,2}?)?\d{1,2}?)?)\W*$&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://regex101.com/r/aIwznp/2/"&gt;Uptime&lt;/a&gt;:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;up (.*)$&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://regex101.com/r/8hVK8j/2"&gt;Serial Number&lt;/a&gt;:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Serial Number: (\S*)$&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now here is what the program looks like utilizing the python re Regex module. The only difference is the addition of a section for parsing the output we’ve received, so that is all I’ll list below. The complete file is on Github as &lt;a href="https://github.com/lykinsbd/nn_examples/blob/master/parsing_net_devices/parse_with_regex.py"&gt;parse_with_regex.py&lt;/a&gt;:&lt;/p&gt;
&lt;details class="collapsable-code" &gt;
&lt;summary title="Click to interact"&gt;&lt;span class="collapsable-code__title"&gt;raw_gather.py&lt;/span&gt;&lt;/summary&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Parse our results&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Parsing Results...&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;parsed_results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;fw_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;parsed_results&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;fw_name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;parsed_results&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;fw_name&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;version&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Software Version (\d.\d{1,2}(?:\(?\d{1,2}?\)?\d{1,2}?)?)\W*$&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MULTILINE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;parsed_results&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;fw_name&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;uptime&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;up (.*)$&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MULTILINE&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;parsed_results&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;fw_name&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;serial&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Serial Number: (\S*)$&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MULTILINE&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Print our results&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;fw_name&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;fw_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; information:&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s2"&gt;Version: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;parsed_results&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;fw_name&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;version&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s2"&gt;Uptime: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;parsed_results&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;fw_name&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;uptime&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s2"&gt;Serial Number: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;parsed_results&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;fw_name&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;serial&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/details&gt;
&lt;p&gt;This will give us the results of:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Username: cisco
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Password:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Connecting to ASAv1â€¦
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Connecting to ASAv2â€¦
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Parsing Resultsâ€¦
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ASAv1 information:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Version: 9.12(1)2
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Uptime: 1 hour 25 mins
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Serial Number: 123456789AB
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ASAv2 information:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Version: 9.13(1)2
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Uptime: 1 hour 25 mins
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Serial Number: 123456789AC
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;As you can see, this is a much more structured and useful output. We could also similarly output this to a CSV or other data source, now that we have parsed the data into something of more value than a raw string of all the data.&lt;/p&gt;
&lt;h2 id="next-up-parsing-libraries"&gt;Next Up, Parsing Libraries&lt;/h2&gt;
&lt;p&gt;In the next post I publish, I will utilize this same environment, but make use of some common configuration parsing libraries (CiscoConfParse and HeirConfig) to show how they could be useful for certain use cases.&lt;/p&gt;</description></item><item><title>Cisco Certification Program Refresh</title><link>/posts/2019/cisco-cert-refresh/</link><pubDate>Mon, 10 Jun 2019 12:30:00 -0500</pubDate><guid>/posts/2019/cisco-cert-refresh/</guid><description>&lt;p&gt;One of the primary reasons I originally started this blog, was to use it for personal accountability with my Cisco certification progress. As I studied and understood a particular topic, I could write a blog article on that topic to cement it in my mind and share that knowledge with others.&lt;/p&gt;
&lt;p&gt;The complete lack of blog posts reflects how well that plan went… I did complete my CCNP Security and was in pursuit of my CCIE Security when my career trajectory shifted. No longer was I solely a Network or Security Architect, an increasing portion of my role was focused on Network Automation and solving problems at a massive scale. I stopped chasing traditional networking certifications and spent many thousands of hours learning Python and Golang to best solve the problems I was faced with at my job.&lt;/p&gt;
&lt;p&gt;While that work has been fulfilling and challenging, it doesn’t present itself well to the traditional Networking world mindset of “certification chasing”. Since I stopped actively pursuing Cisco certifications I have had more than one conversation where people have asked things like: “So where’s your CCIE at?” or “Are you going into management now?” As I looked at the Cisco certifications available, there wasn’t one that presented value to me and the work I was doing every day, beyond the basic knowledge acquired in getting my CCNA and CCNP Voice, Security, and Route/Switch in the past. I couldn’t justify the expense (in both money and time away from my family) to chase a CCIE if it didn’t apply to my career.&lt;/p&gt;
&lt;p&gt;Well as of today, Cisco is announcing something that changes all of that, and I’m super excited. They are doing a complete, top to bottom, refresh and realignment of the certifications that are offered, and the process to get/keep them.&lt;/p&gt;
&lt;h2 id="new-and-improved-cisco-certifications"&gt;New and Improved Cisco Certifications&lt;/h2&gt;
&lt;p&gt;All the discussed changes below go into effect on February 24th, 2020. So you’ve got time to finish your existing studies or gear up for a new certification/track.&lt;/p&gt;
&lt;p&gt;First and foremost, and the most personally exciting to me, is that there is a completely new certification track:&lt;/p&gt;
&lt;figure&gt;&lt;img src="./img/2019/new_cert_tracks-1.png"
alt="New Cisco Certification Tracks"&gt;&lt;figcaption&gt;
&lt;p&gt;The New Certification Tracks from Cisco!&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Now Network Automation/Netdevops is to be recognized via DevNet certifications in their track! Including up to a forthcoming DevNet Expert certification targeted at the same level of expertise expected out of CCIE-level folks.&lt;/p&gt;
&lt;p&gt;According to &lt;a href="https://developer.cisco.com/certification/"&gt;DevNet&lt;/a&gt; the DevNet Professional level exam/certification is targeted at:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;… developers who have at least three to five years of experience designing and implementing applications built on Cisco platforms. Two exams cover designing and developing resilient, robust and secure applications using Cisco APIs and platforms, and managing and deploying applications on Cisco infrastructure.&lt;/p&gt;
&lt;p&gt;Cisco DevNet&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is exactly where I find myself sitting today, and I’m super excited to see that Cisco and the folks at DevNet are listening to the community and responding to this need! I will be one of the first people in line next February when these exams go live. And I can 100% see the value in pursuing the DevNet Expert examination in my career path.&lt;/p&gt;
&lt;h2 id="additional-changes"&gt;Additional Changes&lt;/h2&gt;
&lt;p&gt;There are some significant changes to the certification paths, even inside the existing network-focused paths.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;No more prerequisites for any Cisco certification, if you’re at the Professional or Expert level in your field, go sit that exam.&lt;/li&gt;
&lt;li&gt;All certifications are good for 3 years from the last pass date (including Expert level).&lt;/li&gt;
&lt;li&gt;There are now additional options, including Continuing Education, for renewing your certifications at all levels.&lt;/li&gt;
&lt;li&gt;Associate level (CCNA or DevNet Associate) is one exam.&lt;/li&gt;
&lt;li&gt;Professional level (CCNP or DevNet Professional) is two exams:
&lt;ul&gt;
&lt;li&gt;A Core skills exam in your track.&lt;/li&gt;
&lt;li&gt;A Concentration exam in a more specific area of focus to your specialization.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Taking additional specialization exams will grant you Cisco Specialist badges/awards.&lt;/li&gt;
&lt;li&gt;The tracks available to the Networking path narrow down to Enterprise, Security, Service Provider, Collaboration, and Data Center.
&lt;ul&gt;
&lt;li&gt;For example, Route/Switch and Wireless are being collapsed into the Enterprise track.&lt;/li&gt;
&lt;li&gt;Each of these topics now exists as a concentration or specialization exam inside the Enterprise track at the Professional level.&lt;/li&gt;
&lt;li&gt;If you’re mid-CCNP and want to know what the path forward for you looks like:
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.cisco.com/c/en/us/training-events/training-certifications/certifications/professional/ccnp-security-migration-tool.html"&gt;CCNP Security Migration Tool&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.cisco.com/c/en/us/training-events/training-certifications/certifications/professional/ccnp-routing-switching-migration-tool.html"&gt;CCNP RS Migration Tool&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.cisco.com/c/en/us/training-events/training-certifications/certifications/professional/ccnp-wireless-migration-tool.html"&gt;CCNP Wireless Migration Tool&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As discussed above, these changes will go into place on February 24th, 2020. However, exam topics and other information are now live via the links below. And expect MANY blog posts and other information from Cisco in the coming days, weeks, and months.&lt;/p&gt;
&lt;p&gt;Happy Certing!&lt;/p&gt;
&lt;h2 id="links"&gt;Links&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.cisco.com/c/dam/en_us/training-events/training-certification-faqs.pdf"&gt;Frequently Asked Questions (PDF)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.cisco.com/c/en/us/training-events/training-certifications/take-learning-to-next-level.html"&gt;General information on the new certification changes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.cisco.com/c/en/us/training-events/training-certifications/certifications/devnet.html"&gt;Information on the DevNet certifications&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.cisco.com/certification/"&gt;More information from DevNet on these certs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.cisco.com/c/en/us/training-events/training-certifications/next-level-certifications.html"&gt;Information on the certification tracks&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>#CiscoChampion 2019</title><link>/posts/2019/cisco-champion-2019/</link><pubDate>Fri, 04 Jan 2019 08:18:00 -0500</pubDate><guid>/posts/2019/cisco-champion-2019/</guid><description>&lt;p&gt;Happy 2019 everyone! Since I was lucky enough to be selected as a &lt;a href="https://community.cisco.com/t5/cisco-champions-public-documents/cisco-champion-program-faq-updated-october-2018/ta-p/3732770"&gt;Cisco Champion for 2019&lt;/a&gt;, I thought it was time to revive my zombie blog!&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve got quite a few posts in the hopper and will focus on not being such a perfectionist to posts that I don&amp;rsquo;t just hit that &amp;ldquo;Publish&amp;rdquo; button. Posts will be coming about:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Network Security&lt;/li&gt;
&lt;li&gt;Network Programmability&lt;/li&gt;
&lt;li&gt;Python&lt;/li&gt;
&lt;li&gt;Systems Architecture&lt;/li&gt;
&lt;li&gt;And more!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here&amp;rsquo;s to an exciting and educational 2019!&lt;/p&gt;</description></item><item><title>Testing ISAKMP Part 1: Basic Connectivity</title><link>/posts/2016/netcat-isakmp/</link><pubDate>Fri, 20 May 2016 22:44:00 -0500</pubDate><guid>/posts/2016/netcat-isakmp/</guid><description>&lt;h2 id="the-scenario"&gt;The Scenario&lt;/h2&gt;
&lt;p&gt;In the course of my day-to-day job, I interact with VPNs on many devices (primarily IPSec VPNs on the Cisco ASA). Oftentimes the simplest way to test an IPSec VPN is to fire up &lt;a href="http://linux.die.net/man/8/vpnc"&gt;&lt;code&gt;vpnc&lt;/code&gt;&lt;/a&gt; in a VM, change the config file as needed, and validate the connection.&lt;/p&gt;
&lt;p&gt;Sometimes though, you need to be more granular with your testing. Perhaps the person controlling the other endpoint/peer is not in charge of the intermediate network, and you need to validate that ISAKMP traffic is allowed through to the peer. Perhaps you want to validate an ACL that should be blocking ISAKMP. Or perhaps you&amp;rsquo;re just curious to gain a deeper understanding of what is happening at the protocol level. Either way, there&amp;rsquo;s no easy way to validate that ISAKMP is permitted end to end.&lt;/p&gt;
&lt;p&gt;Because ISAKMP utilizes UDP port 500 for transport, you can&amp;rsquo;t simply Telnet to the port and validate that it is permitted. We&amp;rsquo;re talking about UDP, not TCP, which means there is no Layer 4 validation of an open socket (the Three-Way-Handshake of TCP). This means that you can&amp;rsquo;t do something like &lt;code&gt;nc -uvv $host 500&lt;/code&gt; because while &lt;a href="http://linux.die.net/man/1/nc"&gt;&lt;code&gt;netcat&lt;/code&gt;&lt;/a&gt; can certainly open and utilize UDP sockets, netcat alone can&amp;rsquo;t tell you if a UDP port is open and listening. To test this below, I attempt to use netcat to check whether my local box is listening on UDP port 500 (which I know it is not):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ nc -uvv 127.0.0.1 &lt;span class="m"&gt;500&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; found &lt;span class="m"&gt;0&lt;/span&gt; associations
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; found &lt;span class="m"&gt;1&lt;/span&gt; connections:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 1: &lt;span class="nv"&gt;flags&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;82&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; outif &lt;span class="o"&gt;(&lt;/span&gt;null&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; src 127.0.0.1 port &lt;span class="m"&gt;59894&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; dst 127.0.0.1 port &lt;span class="m"&gt;500&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; rank info not available
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Connection to 127.0.0.1 port &lt;span class="m"&gt;500&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;udp/isakmp&lt;span class="o"&gt;]&lt;/span&gt; succeeded!
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Succeeded indeed… Although we need to do something more to validate whether UDP/500 is open and listening for ISAKMP datagrams, as mentioned above we can still actually utilize netcat We can use it to open the UDP socket and then pipe in semi-valid ISAKMP data for netcat to pass to our destination. This way, we can at least get some sort of response or validation via either an ISAKMP reply message or debugs/counters on the far side peer.&lt;/p&gt;
&lt;h2 id="rfc2048--internet-security-association-and-key-management-protocol"&gt;RFC2048 – Internet Security Association and Key Management Protocol&lt;/h2&gt;
&lt;p&gt;ISAKMP is defined in &lt;a href="https://datatracker.ietf.org/doc/html/rfc2408"&gt;RFC2048&lt;/a&gt;, which describes in great detail the underlying structure of an ISAKMP UDP datagram. In section 3.1, it lays out the header format which is all we need for testing:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 1 2 3
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ! Initiator !
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ! Cookie !
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ! Responder !
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ! Cookie !
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ! Next Payload ! MjVer ! MnVer ! Exchange Type ! Flags !
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ! Message ID !
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ! Length !
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Essentially, if you haven’t seen this style of packet diagram, each number across the top represents a bit, and each row represents 32 bits or 4 octets/bytes whichever you prefer. In this case, the ISAKMP header is 7 rows tall, which means that the ISAKMP header is 224 bits (7*32), or more commonly, 28 bytes long.&lt;/p&gt;
&lt;p&gt;Now we know how long the data has to be, but what are we going to put into it? The header breaks down into the following chunks:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Initiator and Responder Cookies&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;8 bytes per Cookie&lt;/li&gt;
&lt;li&gt;These are tokens that enable each endpoint to identify Security Associations (&lt;a href="https://datatracker.ietf.org/doc/html/rfc2408#section-2.4"&gt;RFC2048, Sec 2.4&lt;/a&gt;), and to act as a method to assist in securing the communication (&lt;a href="https://datatracker.ietf.org/doc/html/rfc2408#section-2.5.3"&gt;RFC2048, Sec 2.5.3&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;Also known as the Security Parameter Index (SPI).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Next Payload&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;1 byte&lt;/li&gt;
&lt;li&gt;Indicates what type of message is following this header.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Major Version and Minor Version&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;4 bits each&lt;/li&gt;
&lt;li&gt;Set to 1 and 0 respectively in RFC2048.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Exchange Type&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;1 byte&lt;/li&gt;
&lt;li&gt;Tells the other system what type of messages and payloads to expect.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Flags&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;1 byte&lt;/li&gt;
&lt;li&gt;Set specific ISAKMP options; only the first three bits are specified in RFC2048 rest are to be zeros.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Message ID&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;4 bytes&lt;/li&gt;
&lt;li&gt;A unique ID is used in Phase 2 negotiations; as we’re simulating a Phase 1 datagram these are set to all zeros.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Length&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;4 bytes&lt;/li&gt;
&lt;li&gt;The combined length of the header and payloads is represented in bytes/octets.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Taking this information, we are now able to determine what fields we need to fill out and with what values to create our testing datagram. Once we are complete, we can simply feed the appropriate arrangement of binary into netcat, and it should be able to simulate the beginning of a valid ISAKMP exchange with the peer.&lt;/p&gt;
&lt;p&gt;The only hitch with this plan is the need for binary. For mere humans, visually tracking long strings of binary is not easy; at a glance can you tell if this is 7 or 8 digits &lt;code&gt;00000001&lt;/code&gt;? In addition, writing out each byte would get tedious and increase the likelihood of human error.&lt;/p&gt;
&lt;h2 id="hexadecimal-to-the-rescue"&gt;Hexadecimal to the Rescue&lt;/h2&gt;
&lt;p&gt;Luckily we can shortcut this process by representing the binary values with &lt;a href="https://en.wikipedia.org/wiki/Hexadecimal#Using_0.E2.80.939_and_A.E2.80.93F"&gt;Hexadecimal in &lt;code&gt;\x&lt;/code&gt; notation&lt;/a&gt;. This allows us to simply represent each byte or octet as a four-character string. For example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Binary: &lt;span class="m"&gt;000000000000000100000010000000011&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Hexadecimal: &lt;span class="se"&gt;\x&lt;/span&gt;00&lt;span class="se"&gt;\x&lt;/span&gt;01&lt;span class="se"&gt;\x&lt;/span&gt;02&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="m"&gt;03&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Validation using xxd:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;\x01\x02\x03\x04&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; xxd -b 0000000: &lt;span class="m"&gt;00000001&lt;/span&gt; &lt;span class="m"&gt;00000010&lt;/span&gt; &lt;span class="m"&gt;00000011&lt;/span&gt; &lt;span class="m"&gt;00000100&lt;/span&gt; ....
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Working with that format, and referencing the above breakdown of the header format gives us the following Hexadecimal:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Initiator and Responder Cookies&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;8 bytes per Cookie&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Initiator Cookie&lt;/em&gt;
&lt;ul&gt;
&lt;li&gt;We’ll make this a value of 1 since it has to be something and we don’t care what it is.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\x00\x00\x00\x00\x00\x00\x00\x01&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Responder Cookie&lt;/em&gt;
&lt;ul&gt;
&lt;li&gt;All zeros because this is an initial communication.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\x00\x00\x00\x00\x00\x00\x00\x00&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Next Payload&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;1 byte&lt;/li&gt;
&lt;li&gt;No Next Payload, so a value of 0.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\x00&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Major Version and Minor Version&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;4 bits each&lt;/li&gt;
&lt;li&gt;Mandatory values of 1 and 0, because we’re using ISAKMP version 1.0&lt;/li&gt;
&lt;li&gt;That would be 0001 and 0000 in binary.&lt;/li&gt;
&lt;li&gt;Together, that would look like 00010000, which equals 10 in Hex.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\x10&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Exchange Type&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;1 byte&lt;/li&gt;
&lt;li&gt;We’re making a fake datagram with no payload, so we’ll try none (0) which appears to be permitted by RFC2048.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\x00&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Flags&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;1 byte&lt;/li&gt;
&lt;li&gt;No specific flags are needed, so we’re also setting this to 0.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\x00&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Message ID&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;4 bytes&lt;/li&gt;
&lt;li&gt;Must be zeros per RFC2048 for an initial Phase 1 datagram like we’re simulating.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\x00\x00\x00\x00&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Length&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;4 bytes&lt;/li&gt;
&lt;li&gt;This will be equal to 28 since we have a header with no payload.&lt;/li&gt;
&lt;li&gt;28 in Hex is 1C.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\x1C&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Finally, our complete string of Hex for the simulated initial ISAKMP datagram would be:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x1C
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="sending-our-data"&gt;Sending Our Data&lt;/h2&gt;
&lt;p&gt;Now that we have the complete Hex string for our test datagram, how do we go about sending it? Well as described earlier, we’re going to simply pass it into netcat by printing the string and piping it into netcat. But first, we need to get a destination setup that is listening for ISAKMP traffic. In my case, I’ve spun up a virtual Cisco ASA in my lab to act as our peer, and have it listening for ISAKMP traffic on the &lt;code&gt;INSIDE&lt;/code&gt; interface (172.16.16.1).&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;span class="lnt"&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ASAv-1A/pri/act# show run int G0/4
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;!
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; interface GigabitEthernet0/4
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; nameif INSIDE
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; security-level 100
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ip address 172.16.16.1 255.255.255.0
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; standby 172.16.16.2
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ASAv-1A/pri/act# show run crypto ikev1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; crypto ikev1 enable INSIDE
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Taking the above Hex string and using &lt;code&gt;printf&lt;/code&gt; to send it into netcat gives us the following output (all of the Hex should be on one line, however for readability I have broken it up here):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ &lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="se"&gt;\x&lt;/span&gt;00&lt;span class="se"&gt;\x&lt;/span&gt;00&lt;span class="se"&gt;\x&lt;/span&gt;00&lt;span class="se"&gt;\x&lt;/span&gt;00&lt;span class="se"&gt;\x&lt;/span&gt;00&lt;span class="se"&gt;\x&lt;/span&gt;00&lt;span class="se"&gt;\x&lt;/span&gt;00&lt;span class="se"&gt;\x&lt;/span&gt;01&lt;span class="se"&gt;\x&lt;/span&gt;00&lt;span class="se"&gt;\x&lt;/span&gt;00&lt;span class="se"&gt;\x&lt;/span&gt;00&lt;span class="se"&gt;\x&lt;/span&gt;00&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="m"&gt;00&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="se"&gt;\x&lt;/span&gt;00&lt;span class="se"&gt;\x&lt;/span&gt;00&lt;span class="se"&gt;\x&lt;/span&gt;00&lt;span class="se"&gt;\x&lt;/span&gt;00&lt;span class="se"&gt;\x&lt;/span&gt;10&lt;span class="se"&gt;\x&lt;/span&gt;00&lt;span class="se"&gt;\x&lt;/span&gt;00&lt;span class="se"&gt;\x&lt;/span&gt;00&lt;span class="se"&gt;\x&lt;/span&gt;00&lt;span class="se"&gt;\x&lt;/span&gt;00&lt;span class="se"&gt;\x&lt;/span&gt;00&lt;span class="se"&gt;\x&lt;/span&gt;1C &lt;span class="p"&gt;|&lt;/span&gt; nc -uvv 172.16.16.1 &lt;span class="m"&gt;500&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Connection to 172.16.16.1 &lt;span class="m"&gt;500&lt;/span&gt; port &lt;span class="o"&gt;[&lt;/span&gt;udp/isakmp&lt;span class="o"&gt;]&lt;/span&gt; succeeded!
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;^C
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;As you can see, netcat says “Connection succeeded” again, and the output on our end is not so different from when we tested to a non-ISAKMP speaking endpoint. However, on the ASA IKEv1 statistics, we can see something very interesting:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ASAv-1A/pri/act# show crypto ikev1 stats | inc Drop
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;In Drop Packets: 6 Out Drop Packets: 0
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;So the ASA saw the packet and marked it as invalid in some way then dropped it (which makes sense because we didn’t send any payload at all).&lt;/p&gt;
&lt;p&gt;This validates that the path for UDP/500 is open from my test box to the peer!&lt;/p&gt;
&lt;h2 id="bonus-validations"&gt;Bonus Validations&lt;/h2&gt;
&lt;p&gt;I’m a curious soul though, so I wanted to dig deeper still. For more detail we can turn on the IKEv1 debugs on the ASA and see as it is receiving and discarding each of the packets:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ASAv-1A/pri/act# debug crypto ikev1 255
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ASAv-1A/pri/act#
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;May 21 03:25:04 [IKEv1]IKE Receiver: Packet received on 172.16.16.1:500 from 172.16.16.16:39994
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;May 21 03:25:04 [IKEv1]IKE Receiver: Runt ISAKMP packet discarded on Port 500 from 172.16.16.16:39994
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;May 21 03:25:04 [IKEv1]IKE Receiver: Packet received on 172.16.16.1:500 from 172.16.16.16:39994
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;May 21 03:25:04 [IKEv1]IKE Receiver: Runt ISAKMP packet discarded on Port 500 from 172.16.16.16:39994
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;May 21 03:25:05 [IKEv1]IKE Receiver: Packet received on 172.16.16.1:500 from 172.16.16.16:39994
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;May 21 03:25:05 [IKEv1]IKE Receiver: Runt ISAKMP packet discarded on Port 500 from 172.16.16.16:39994
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;May 21 03:25:06 [IKEv1]IKE Receiver: Packet received on 172.16.16.1:500 from 172.16.16.16:39994
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;May 21 03:25:06 [IKEv1]IKE Receiver: Runt ISAKMP packet discarded on Port 500 from 172.16.16.16:39994
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;May 21 03:25:07 [IKEv1]IKE Receiver: Packet received on 172.16.16.1:500 from 172.16.16.16:39994
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;May 21 03:25:07 [IKEv1]IKE Receiver: Runt ISAKMP packet discarded on Port 500 from 172.16.16.16:39994
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;May 21 03:25:07 [IKEv1]IKE Receiver: Packet received on 172.16.16.1:500 from 172.16.16.16:39994
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;May 21 03:25:07 [IKEv1]IKE Receiver: Discarding packet, invalid IKE version
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;And for the coup, I did a packet capture on the ASA for all UDP/500 traffic and decoded it to see if the protocol decoder could interpret the frames as ISAKMP:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ASAv-1A/pri/act# cap cap1 int INSIDE match udp any any eq 500
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ASAv-1A/pri/act# show cap cap1 decode 6 packets captured
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 1: 03:34:01.443916 172.16.16.16.35457 &amp;gt; 172.16.16.1.500: udp 1 [ISAKMP header incomplete]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 2: 03:34:01.444007 172.16.16.16.35457 &amp;gt; 172.16.16.1.500: udp 1 [ISAKMP header incomplete]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 3: 03:34:02.444892 172.16.16.16.35457 &amp;gt; 172.16.16.1.500: udp 1 [ISAKMP header incomplete]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 4: 03:34:03.445609 172.16.16.16.35457 &amp;gt; 172.16.16.1.500: udp 1 [ISAKMP header incomplete]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 5: 03:34:04.447059 172.16.16.16.35457 &amp;gt; 172.16.16.1.500: udp 1 [ISAKMP header incomplete]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 6: 03:34:04.450126 172.16.16.16.35457 &amp;gt; 172.16.16.1.500: udp 75 ISAKMP Header Initiator COOKIE: 78 30 30 78 30 30 78 30 Responder COOKIE: 30 78 30 30 78 30 30 78 Next Payload: IKEV2 LEAP PAYLOAD Version: 3.0 Exchange Type: DOI Specific Use Flags: MessageID: 30783031 Length: 2016424056 [ISAKMP payload corrupted or truncated]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;And there you have it, a means to quickly and easily validate a UDP/500 path!&lt;/p&gt;
&lt;h2 id="series-update-2026"&gt;Series Update (2026)&lt;/h2&gt;
&lt;p&gt;This post has been expanded into a comprehensive series:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Part 1&lt;/strong&gt; (this post): Basic connectivity testing with minimal ISAKMP headers&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="./posts/2026/netcat-isakmp-2/"&gt;Part 2&lt;/a&gt;&lt;/strong&gt;: Testing with pre-built complete packets&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="./posts/2026/netcat-isakmp-3/"&gt;Part 3&lt;/a&gt;&lt;/strong&gt;: Building ISAKMP packets from scratch&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="./posts/2026/netcat-isakmp-4/"&gt;Part 4&lt;/a&gt;&lt;/strong&gt;: Automating tests with Scapy (coming soon)&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>300-208 SISAS - What Is Cisco ISE?</title><link>/posts/2015/300-208-sisas-2/</link><pubDate>Sat, 12 Dec 2015 21:20:00 -0500</pubDate><guid>/posts/2015/300-208-sisas-2/</guid><description>&lt;p&gt;In my &lt;a href="./posts/2015/300-208-sisas/"&gt;earlier post about the Cisco 300-208 SISAS&lt;/a&gt; (Implementing Cisco Secure Access Solutions) exam, I gave a brief overview of the exam and listed the exam topics as &lt;a href="https://learningnetwork.cisco.com/community/certifications/ccnpsecurity/sisas/exam-topics"&gt;laid out by the Cisco Learning Community&lt;/a&gt;. However, I felt that these largely boil down to a few key concepts related to &lt;a href="http://www.cisco.com/c/en/us/products/collateral/security/identity-services-engine/data_sheet_c78-656174.html"&gt;Cisco ISE (Identity Services Engine)&lt;/a&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Understand what ISE is.&lt;/li&gt;
&lt;li&gt;Understand why you might use ISE in a wired or wireless network.&lt;/li&gt;
&lt;li&gt;Understand what ISE does at a protocol level.&lt;/li&gt;
&lt;li&gt;Understand how ISE interacts with Network Access Devices and other systems.&lt;/li&gt;
&lt;li&gt;Understand how to configure ISE and the Network Access Devices.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This post will deal with Concept 1, Understand what Cisco ISE is.&lt;/p&gt;
&lt;h2 id="a-little-history"&gt;A Little History&lt;/h2&gt;
&lt;p&gt;Before you can understand what ISE is, I feel that you need to know where it came from. Cisco&amp;rsquo;s NAC (Network Access Control) offerings have been fairly scattershot over the years. They even tried unsuccessfully to market a contrary meaning of NAC for several years, attempting to sell their services as Network Admission Control. Thankfully, they&amp;rsquo;ve given in and joined the rest of us in Network Access Control land.&lt;/p&gt;
&lt;p&gt;Cisco ACS (Access Control Server) was the direct predecessor to ISE and still exists today. It provides RADIUS and TACACS services and can integrate with central Identity Stores such as Active Directory or another LDAP-speaking software. This means that you would often find ACS in an enterprise network serving to authenticate VPN and wireless users or control access to network devices. Over time ACS evolved, as most Cisco applications have, from something you installed on top of Windows, to a full-blown Linux-based appliance (&lt;a href="http://www.cisco.com/c/en/us/td/docs/net_mgmt/cisco_secure_access_control_system/5-0/release/notes/ACS-50-releasenotes.html"&gt;as of ACS 5.0 in 2009&lt;/a&gt;). The common &amp;ldquo;appliance&amp;rdquo; model in use today, means that without a little (non-Cisco approved) tinkering you don&amp;rsquo;t have access to the Linux guts of Cisco ACS, or ISE for that matter, you&amp;rsquo;ve simply presented an application.&lt;/p&gt;
&lt;p&gt;At the same time that ACS was growing and advancing in capabilities, there was also the burst of BYOD onto the market and a growing market in servers/services to manage and administer user Identity on the network. Cisco saw an opportunity to forklift the capabilities of ACS into a new product that was targeted directly at the &amp;ldquo;new&amp;rdquo; Identity Management market, not just traditional &amp;ldquo;access control&amp;rdquo;. They took the underlying operating system from ACS, a RHEL/CentOS-based distribution that they call ADE-OS (Application Deployment Engine), and added a few new capabilities and features to the application. This creation is what we know today as Cisco ISE. Essentially, you can think of ISE as ACS version 6.0.&lt;/p&gt;
&lt;p&gt;The only thing left out of ISE (&lt;a href="http://www.cisco.com/c/en/us/td/docs/security/ise/2-0/release_notes/ise20_rn.html"&gt;until the recent release of Cisco ISE v2.0&lt;/a&gt;) was TACACS, as it was intended that you still purchase ACS to control network device administrative access. For the 300-208 SISAS exam today, you can consider TACACS to be out-of-scope for ISE, and to be the sole purview of ACS, although you still have to understand TACACS for the exam.&lt;/p&gt;
&lt;p&gt;What Is Identity Management?&lt;/p&gt;
&lt;p&gt;A full discussion of what Identity and Identity Management is, could take up many pages and posts (&lt;a href="https://en.wikipedia.org/wiki/Identity_management"&gt;see Wikipedia&lt;/a&gt;), however for the 300-208 SISAS exam it can be summed up as this from the Official Cert Guide:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;An identity is a representation of who a user or device is. Cisco ISE uses an endpoint&amp;rsquo;s MAC address to uniquely identify that endpoint. A username is one method of uniquely identifying an end user. Although SSIDs and IP addresses can be used as conditions or attributes in ISE policies, they are not identities.&lt;/p&gt;
&lt;p&gt;Woland, Aaron; Redmon, Kevin (2015-04-27). CCNP Security SISAS 300-208 Official Cert Guide (Certification Guide) (Kindle Locations 13023-13026). Cisco Press. Kindle Edition.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;An Identity Management system can then be defined as a way to keep track of Identity information for many users or devices, as well as the associated Authorization and Authentication information for those entities. This is precisely what Cisco ISE is and does. It provides all manner of services related to managing who users and devices are, and what network resources they may access. Cisco ISE does not directly stop an entity from accessing a portion of the network (there are sometimes Inline Policy Nodes, but they are not common). The Network Access Devices themselves handle the heavy lifting of granting/denying access by utilizing IEEE 802.1x which I will discuss in a subsequent post. ISE simply provides a centralized location to set policy, gather reporting, and then interact with the NAD via Radius.&lt;/p&gt;
&lt;p&gt;In the next post, I will delve into Concept 2, the Whys surrounding Cisco ISE, as well as give a few example use cases.&lt;/p&gt;</description></item><item><title>The Elusive A+ Rating on SSL Labs</title><link>/posts/2015/ssl-labs-aplus/</link><pubDate>Mon, 24 Aug 2015 22:58:00 -0500</pubDate><guid>/posts/2015/ssl-labs-aplus/</guid><description>&lt;p&gt;I often have to talk people off a cliff because of their website&amp;rsquo;s (sometimes perceived) vulnerabilities on &lt;a href="https://www.ssllabs.com/ssltest"&gt;Qualys&amp;rsquo; SSL Labs&lt;/a&gt; testing site. They have received an A- score for their site after running the tests, and see a few things in yellow. Suddenly, they begin to believe that every villain on the web is now running amok with their data. The truth of the matter is that if your SSL configuration is rating at an A-, that configuration is usually just fine. Out of curiosity, I recently spent a few hours tweaking and managed to upgrade from an A- to an A+ for this domain. I wanted to share that process so that anyone else can know what it might take to get an A+.&lt;/p&gt;
&lt;figure&gt;&lt;img src="./img/2015/SSL-Labs-APlus.jpg"
alt="SSL Labs A&amp;#43; Rating"&gt;&lt;figcaption&gt;
&lt;p&gt;A+ Rating for network-notes.com on Qualys SSL Labs Testing&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="caveats-and-advice"&gt;Caveats and Advice&lt;/h2&gt;
&lt;p&gt;The things that get you to an A+, are mostly semantic and not always the most obvious and open vulnerabilities. The SSL Labs scoring process, while open and based on common sense/best practices, is simply one entity&amp;rsquo;s opinion of your SSL configuration. In addition to the somewhat arbitrary nature of any benchmarking site, such as SSL Labs, remember that a configuration that gets an A+ today is one new vulnerability away from an F. Your security posture on any system must be continuously evolving, along with the threats you&amp;rsquo;re defending against.&lt;/p&gt;
&lt;p&gt;These caveats also hold for any configurations listed here. These are not guarantees that your site will be secure, or even recommendations. They merely reflect the Apache and mod_ssl configurations that suited my needs, in my circumstances, at the time of this writing. Please use common sense when establishing an SSL policy for your website.&lt;/p&gt;
&lt;p&gt;The tweaks boiled down to either explicitly defining things in my Apache VirtualHost configuration that I assumed didn&amp;rsquo;t matter, or bending my strict configuration a little bit to meet the requirements of older browsers. For example, I was initially only going to enable TLSv1.2. If you can&amp;rsquo;t support TLSv1.2, I wasn&amp;rsquo;t really worried if the site was unavailable to you. However, as I thought about it, I realized that it was a pointless stance to take. Why isolate this site from an unfortunately large, albeit less secure, portion of the web when I don&amp;rsquo;t have to? I&amp;rsquo;m not hosting any sensitive information on these servers; I am not asking users to make credit card transactions or give me their Social Security numbers. I eventually walked my SSL configuration backward and enabled TLSv1.0, TLSv1.1, and TLSv1.2 as part of my remediation efforts to get the elusive A+ from SSL Labs.&lt;/p&gt;
&lt;h2 id="how-to-get-an-a--without-really-trying"&gt;How to Get an A- Without Really Trying&lt;/h2&gt;
&lt;p&gt;Below is an example of the Apache VirtualHost configuration I had in place before beginning this process. It was graded at an A- by SSL Labs and is pretty standard. Most of it was pulled directly from the &lt;code&gt;default-ssl.conf&lt;/code&gt; file in Apache 2.4.&lt;/p&gt;
&lt;details class="collapsable-code" &gt;
&lt;summary title="Click to interact"&gt;&lt;span class="collapsable-code__title"&gt;Starter Apache Config&lt;/span&gt;&lt;/summary&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-apacheconf" data-lang="apacheconf"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;IfModule&lt;/span&gt; &lt;span class="s"&gt;mod_ssl.c&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;VirtualHost&lt;/span&gt; &lt;span class="s"&gt;*:443&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;ServerName&lt;/span&gt; network-notes.com
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c"&gt;# SSL Configuration&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;SSLEngine&lt;/span&gt; &lt;span class="k"&gt;on&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;SSLProtocol&lt;/span&gt; +TLSv1.1 +TLSv1.2
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;SSLCipherSuite&lt;/span&gt; HIGH:!aNULL:!MD5
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;SSLCertificateFile&lt;/span&gt; network-notes.com.pem
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;SSLCertificateKeyFile&lt;/span&gt; network-notes.com.key
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;SSLCertificateChainFile&lt;/span&gt; network-notes.com-cabundle
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c"&gt;# Fixes for IE being, well, IE...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;BrowserMatch&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;MSIE [2-6]&amp;#34;&lt;/span&gt; nokeepalive ssl-unclean-shutdown
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;\downgrade-1&lt;/span&gt;.&lt;span class="err"&gt;0&lt;/span&gt; &lt;span class="err"&gt;force-response-1&lt;/span&gt;.&lt;span class="err"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;BrowserMatch&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;MSIE [17-9]&amp;#34;&lt;/span&gt; ssl-unclean-shutdown
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c"&gt;# Browser caching for static content&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;filesMatch&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;.(js|css|png|jpeg|jpg|gif|ico|swf|flv|pdf|zip)$&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;Header&lt;/span&gt; set Cache-Control &lt;span class="s2"&gt;&amp;#34;max-age=1209600, public&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/filesMatch&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c"&gt;# Redirect &amp;#34;/&amp;#34; to &amp;#34;/blog/&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;If&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;%{REQUEST_URI} == &amp;#39;/&amp;#39;&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;Redirect&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;/&amp;#34;&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;/blog/&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/If&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/VirtualHost&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;/IfModule&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/details&gt;
&lt;p&gt;Now, here&amp;rsquo;s what the good folks at Qualys SSL Labs had to say about that configuration:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&amp;ldquo;The server does not support Forward Secrecy with the reference browsers. Grade reduced to A-. &lt;a href="https://en.wikipedia.org/wiki/Forward_secrecy"&gt;MORE INFO»&lt;/a&gt;&amp;rdquo;
&lt;ol&gt;
&lt;li&gt;&amp;ldquo;Forward Secrecy - With some browsers (&lt;a href="https://community.qualys.com/blogs/securitylabs/2013/06/25/ssl-labs-deploying-forward-secrecy"&gt;more info&lt;/a&gt;)&amp;rdquo;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&amp;ldquo;Incorrect SNI Alerts - &amp;lt;www.network-notes.com&amp;gt;&amp;rdquo;&lt;/li&gt;
&lt;li&gt;In addition, unless a browser was one of the newest versions available, there was also a slew of &amp;ldquo;Protocol or cipher suite mismatch&amp;rdquo;.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="working-towards-an-a"&gt;Working Towards an A&lt;/h2&gt;
&lt;p&gt;The easiest fix was enabling TLSv1.o as I described earlier. By simply adding &lt;code&gt;+TLSv1&lt;/code&gt; to the &lt;code&gt;SSLProtocol&lt;/code&gt; directive, I opened up a much larger range of possible Protocol/Cipher Suite combinations:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-apacheconf" data-lang="apacheconf"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;SSLProtocol&lt;/span&gt; +TLSv1 +TLSv1.1 +TLSv1.2
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Unfortunately, this change resulted in no movement whatsoever of my A- rating. At the very least, issue #3 was resolved; the wide majority of browsers could negotiate a connection. The question remains, however, why would Forward Secrecy only work with some browsers? I have configured all of the DHE and ECDHE ciphers needed and was able to confirm this fact because many browser simulations can connect with an ECDHE cipher. Upon further investigation of the output from SSL Labs, I found the following, &amp;ldquo;Cipher Suites (sorted by strength as the server has no preference)&amp;rdquo;. The Forward Secrecy enabled ciphers are available to all browsers, but I wondered if SSL Labs was indicating that some might not pick them because they weren&amp;rsquo;t offered first.&lt;/p&gt;
&lt;p&gt;I always assumed cipher suite order was generally arbitrary, but to appease SSL Labs I sorted them by strength. I added &lt;code&gt;@strength&lt;/code&gt; to the end of my &lt;code&gt;SSLCipherSuite&lt;/code&gt; directive, and also added the SSLHonorCipherOrder directive. The &lt;a href="http://httpd.apache.org/docs/2.4/mod/mod_ssl.html#sslhonorcipherorder"&gt;&lt;code&gt;SSLHonorCipherOrder&lt;/code&gt;&lt;/a&gt; directive was because, if I&amp;rsquo;m going to sort my cipher suite, your browser better obey.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-apacheconf" data-lang="apacheconf"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;SSLCipherSuite&lt;/span&gt; HIGH:!aNULL:!MD5:@STRENGTH
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;SSLHonorCipherOrder&lt;/span&gt; &lt;span class="k"&gt;on&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Upon testing again I had&amp;hellip; Success! I was upgraded to an A!&lt;/p&gt;
&lt;p&gt;From SSL Labs: &amp;ldquo;Forward Secrecy - Yes (with most browsers) ROBUST (&lt;a href="https://community.qualys.com/blogs/securitylabs/2013/06/25/ssl-labs-deploying-forward-secrecy"&gt;more info&lt;/a&gt;)&amp;rdquo; There is now only one more issue in yellow, so I assumed that fixing the SNI mixup should get me to an A+.&lt;/p&gt;
&lt;h2 id="sni-ed-remarks"&gt;SNI-ed Remarks&lt;/h2&gt;
&lt;p&gt;The SNI error given was not exactly verbose: &amp;ldquo;Incorrect SNI Alerts - &amp;lt;www.network-notes.com&amp;gt;&amp;rdquo;. This was a little puzzling, as I&amp;rsquo;m not using SNI for this site; there&amp;rsquo;s only one domain hosted on the server. After Googling for a few minutes, I found myself at a &lt;a href="https://community.qualys.com/thread/13532"&gt;Qualys Community post&lt;/a&gt; from August 2014 detailing this issue. Most helpful it gave a quick and dirty test to validate the issue yourself using OpenSSL (&lt;code&gt;openssl&lt;/code&gt;), which I tweaked as shown below to look for unrecognized name SSL alerts. You can see in the first example using network-notes.com, that there was no issue. However, when using &amp;lt;www.network-notes.com&amp;gt;, the server was indeed giving back an unrecognized name error:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ &lt;span class="nv"&gt;SERVER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;network-notes.com&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; -e &lt;span class="s2"&gt;&amp;#34;HEAD / HTTP/1.0\r\nHost: &lt;/span&gt;&lt;span class="nv"&gt;$SERVER&lt;/span&gt;&lt;span class="s2"&gt;\r\n\r\n&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; openssl s_client -servername &lt;span class="nv"&gt;$SERVER&lt;/span&gt; -connect &lt;span class="nv"&gt;$SERVER&lt;/span&gt;:443 -state 2&amp;gt;&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; grep unrecognized
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ &lt;span class="nv"&gt;SERVER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;www.network-notes.com&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; -e &lt;span class="s2"&gt;&amp;#34;HEAD / HTTP/1.0\r\nHost: &lt;/span&gt;&lt;span class="nv"&gt;$SERVER&lt;/span&gt;&lt;span class="s2"&gt;\r\n\r\n&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; openssl s_client -servername &lt;span class="nv"&gt;$SERVER&lt;/span&gt; -connect &lt;span class="nv"&gt;$SERVER&lt;/span&gt;:443 -state 2&amp;gt;&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; grep unrecognized
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;SSL3 alert read:warning:unrecognized name
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;This is a perfect example of the minutia you have to wade through in search of an A+. My DNS for this domain is configured with &amp;lt;www.network-notes.com&amp;gt; as a CNAME for network-notes.com, so no one should ever wind up at &amp;lt;www.network-notes.com&amp;gt;. However, since it is a SAN in my SSL certificate, according to Qualys I need to specify it as a ServerAlias in my Apache VirtualHost configuration:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-apacheconf" data-lang="apacheconf"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;ServerAlias&lt;/span&gt; www.network-notes.com
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;This change cleared up the SNI error on SSL Labs, and in my testing, however, my grade is still (only?) an A. Now it&amp;rsquo;s time to think this through and re-read the output from SSL Labs.&lt;/p&gt;
&lt;h2 id="headed-for-an-a"&gt;Headed for an A+&lt;/h2&gt;
&lt;p&gt;One of the lines indicated that I did not have the HSTS (HTTP Strict Transport Security) enabled. There&amp;rsquo;s a great &lt;a href="https://raymii.org/s/tutorials/HTTP_Strict_Transport_Security_for_Apache_NGINX_and_Lighttpd.html"&gt;summary of HSTS, including sample configurations&lt;/a&gt; at Raymii.org, but essentially it is an HTTP header that is returned to your browser on the first visit. This header tells your browser to always use HTTPS for any subsequent visits to your domain. Since I have all traffic redirecting to HTTPS already, I figured this would be a simple addition. After all, at this point, I was grasping at straws and I added the following configuration:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-apacheconf" data-lang="apacheconf"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;Header&lt;/span&gt; always set Strict-Transport-Security &lt;span class="s2"&gt;&amp;#34;max-age=63072000; includeSubdomains; preload&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;And finally, lo and behold, the elusive A+!&lt;/p&gt;
&lt;p&gt;Quote from the test: &amp;ldquo;This server supports HTTP Strict Transport Security with long duration. Grade set to A+.&amp;rdquo;&lt;/p&gt;
&lt;h2 id="final-results"&gt;Final Results&lt;/h2&gt;
&lt;p&gt;Now that we have the A+, I figured I should go ahead and complete the other task that I was considering as a possibility, configuring &lt;a href="https://en.wikipedia.org/wiki/OCSP_stapling"&gt;OSCP Stapling&lt;/a&gt;. This was a simple enough configuration consisting of two additional lines, one defining where the OSCP Stapling cache would be and another turning the feature on. While this change didn&amp;rsquo;t upgrade my SSL Labs score any further (A++ anyone?), it did green up another field. After all this time working on the configuration was still fairly satisfying.&lt;/p&gt;
&lt;p&gt;Below is an example of what my SSL VirtualHosts file looked like after all of these contortions. I hope you all find it useful, and please let me know if you all have any recommendations, corrections, or your own stories of optimizing SSL.&lt;/p&gt;
&lt;details class="collapsable-code" &gt;
&lt;summary title="Click to interact"&gt;&lt;span class="collapsable-code__title"&gt;Final Apache Config&lt;/span&gt;&lt;/summary&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;span class="lnt"&gt;32
&lt;/span&gt;&lt;span class="lnt"&gt;33
&lt;/span&gt;&lt;span class="lnt"&gt;34
&lt;/span&gt;&lt;span class="lnt"&gt;35
&lt;/span&gt;&lt;span class="lnt"&gt;36
&lt;/span&gt;&lt;span class="lnt"&gt;37
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-apacheconf" data-lang="apacheconf"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;IfModule&lt;/span&gt; &lt;span class="s"&gt;mod_ssl.c&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;SSLStaplingCache&lt;/span&gt; shmcb:/tmp/stapling_cache(128000)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;VirtualHost&lt;/span&gt; &lt;span class="s"&gt;*:443&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;ServerName&lt;/span&gt; network-notes.com
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;ServerAlias&lt;/span&gt; www.network-notes.com
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c"&gt;# SSL Configuration&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;SSLEngine&lt;/span&gt; &lt;span class="k"&gt;on&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;SSLProtocol&lt;/span&gt; +TLSv1 +TLSv1.1 +TLSv1.2
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;SSLCipherSuite&lt;/span&gt; HIGH:!aNULL:!MD5:@STRENGTH
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;SSLHonorCipherOrder&lt;/span&gt; &lt;span class="k"&gt;on&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;SSLCertificateFile&lt;/span&gt; network-notes.com.pem
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;SSLCertificateKeyFile&lt;/span&gt; network-notes.com.key
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;SSLCertificateChainFile&lt;/span&gt; network-notes.com-cabundle
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;SSLUseStapling&lt;/span&gt; &lt;span class="k"&gt;on&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c"&gt;# HSTS Configuration&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;Header&lt;/span&gt; always set Strict-Transport-Security &lt;span class="s2"&gt;&amp;#34;max-age=63072000; includeSubdomains; preload&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c"&gt;# Fixes for IE being, well, IE...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;BrowserMatch&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;MSIE [2-6]&amp;#34;&lt;/span&gt; nokeepalive ssl-unclean-shutdown
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;\downgrade-1&lt;/span&gt;.&lt;span class="err"&gt;0&lt;/span&gt; &lt;span class="err"&gt;force-response-1&lt;/span&gt;.&lt;span class="err"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;BrowserMatch&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;MSIE [17-9]&amp;#34;&lt;/span&gt; ssl-unclean-shutdown
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c"&gt;# Browser caching for static content&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;filesMatch&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;.(js|css|png|jpeg|jpg|gif|ico|swf|flv|pdf|zip)$&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;Header&lt;/span&gt; set Cache-Control &lt;span class="s2"&gt;&amp;#34;max-age=1209600, public&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/filesMatch&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c"&gt;# Redirect &amp;#34;/&amp;#34; to &amp;#34;/blog/&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;If&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;%{REQUEST_URI} == &amp;#39;/&amp;#39;&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;Redirect&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;/&amp;#34;&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;/blog/&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/If&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/VirtualHost&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;/IfModule&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/details&gt;</description></item><item><title>300-208 SISAS - How to Tackle the Beast</title><link>/posts/2015/300-208-sisas/</link><pubDate>Wed, 19 Aug 2015 23:09:00 -0500</pubDate><guid>/posts/2015/300-208-sisas/</guid><description>&lt;p&gt;The best way to finish something is to begin it. So I decided I would begin my prep for the 300-208 SISAS (Implementing Cisco Secure Access Solutions) exam, by laying out my personal study plan against the exam topics, found &lt;a href="https://learningnetwork.cisco.com/community/certifications/ccnpsecurity/sisas/exam-topics"&gt;here on the Cisco Learning Community&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The exam topics are broken into five broad categories, and Cisco also gives a general indication of what percentage of the exam is on each topic:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1.0 Identity Management/Secure Access - 33%
2.0 Threat Defense - 10%
3.0 Troubleshooting, Monitoring, and Reporting Tools - 7%
4.0 Threat Defense Architectures - 17%
5.0 Identity Management Architectures - 33%
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Each of those broad topics has several sub-categories; 1.0 Identity Management/Secure Access, for example, is broken down into over 60 sub-sections. This depth of expected knowledge can seem quite daunting at first, especially given the vague nature of some of the topics. However, I&amp;rsquo;ve found that the exam breaks down into 5 key areas, and are all focused primarily on &lt;a href="http://www.cisco.com/c/en/us/products/collateral/security/identity-services-engine/data_sheet_c78-656174.html"&gt;Cisco ISE (Identity Services Engine)&lt;/a&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Understand what ISE is.&lt;/li&gt;
&lt;li&gt;Understand why you might use ISE in a wired or wireless network.&lt;/li&gt;
&lt;li&gt;Understand what ISE does at a protocol level.&lt;/li&gt;
&lt;li&gt;Understand how ISE interacts with Network Access Devices and other systems.&lt;/li&gt;
&lt;li&gt;Understand how to configure ISE and the Network Access Devices.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This is why my primary focus in these exam preparations is getting hands-on with Cisco ISE. I have been spending at least 10 minutes per night, getting familiar with both the GUI itself and the operations that ISE can do. 10 minutes may not seem like much, but getting any hands-on time with a complex system matters. You have to keep yourself sharp and fresh when preparing for an exam. Especially if, like in my current job, you do not interact with ISE at all on a day-to-day basis.&lt;/p&gt;
&lt;p&gt;In the next few posts, I&amp;rsquo;ll dig further into each of these 5 key areas, as well as discuss how to set up an ISE test lab for yourself and talk through some of the scenarios I&amp;rsquo;m using for my lab.&lt;/p&gt;</description></item><item><title>CCNP Security - Halfway There</title><link>/posts/2015/ccnp-sec-halfway/</link><pubDate>Sat, 15 Aug 2015 21:52:00 -0500</pubDate><guid>/posts/2015/ccnp-sec-halfway/</guid><description>&lt;p&gt;I am halfway towards my CCNP Security and am finally gearing up to finish it. When I completed the 642-618 FIREWALL and 642-648 VPN exams at the beginning of 2014, I was promptly sidetracked by the little things in life. (Such as moving across the country, starting a new job, and finishing my BSIT at WGU.) Knowing that the old CCNP Security exams had cycled out in April of 2014, I used &lt;a href="http://www.cisco.com/web/learning/tools/ccnp_security/index.html"&gt;Cisco&amp;rsquo;s CCNP Security Migration Path&lt;/a&gt; tool to validate that I was left with these two exams:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;300-207 SITCS (Implementing Cisco Threat Control Solutions)&lt;/li&gt;
&lt;li&gt;300-208 SISAS (Implementing Cisco Secure Access Solutions)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I am starting first with the 300-208 SISAS exam as it covers a range of topics, such as 802.1x, Cisco ISE, and Radius, that I am very familiar with. However, from everything I&amp;rsquo;ve read, it goes into great depth on the minutia of the ISE interface. As I haven&amp;rsquo;t touched ISE in a production environment in over a year now, I&amp;rsquo;ve been spending time most evenings in my lab spinning up and down many different scenarios.&lt;/p&gt;
&lt;p&gt;My lab for this study is entirely virtual and is a dry run for building my CCIE Security lab. It currently consists of the following, largely coordinated and controlled via GNS3:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ISE 1.2 - VMWare Fusion on my MacBook&lt;/li&gt;
&lt;li&gt;ACS 5.6 - VMWare Fusion on my MacBook&lt;/li&gt;
&lt;li&gt;CentOS test boxes (x2) - VMWare Fusion on my MacBook&lt;/li&gt;
&lt;li&gt;IOU L2 Image (x2) - Rackspace Cloud Server&lt;/li&gt;
&lt;li&gt;IOU L3 Image (x6) - Rackspace Cloud Server&lt;/li&gt;
&lt;li&gt;ASA 8.4 (x2) - QEMU on a Rackspace Cloud Server&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the weeks to come I&amp;rsquo;ll be posting more about my exam preparations, including lab scenarios and links.  This is mostly for me, but if anyone else gets some use out of it too, even better.&lt;/p&gt;</description></item><item><title/><link>/about-source/readme/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>/about-source/readme/</guid><description>&lt;h1 id="hello-there-"&gt;Hello there 👋&lt;/h1&gt;
&lt;!-- vale Microsoft.FirstPerson = NO --&gt;
&lt;!-- vale Microsoft.Vocab = NO --&gt;
&lt;p&gt;My name is Brett Lykins, and my pronouns are &lt;a href="https://pronoun.is/he"&gt;He/Him&lt;/a&gt;.&lt;/p&gt;
&lt;!-- vale Microsoft.Vocab = YES --&gt;
&lt;p&gt;I live in Fairfax, Virginia, USA.&lt;/p&gt;
&lt;p&gt;
&lt;img align="center" width="450" alt="Image of Brett in front of some trees" src="./images/IMG_5617_smol_cropped.jpg"&gt;
&lt;/p&gt;
&lt;h2 id="quick-facts-about-me"&gt;Quick facts about me&lt;/h2&gt;
&lt;p&gt;One of these is a lie, and you should try to guess which one.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;🤓 I am a new nerd who loves knowing how things work and how they&amp;rsquo;re put together&lt;/li&gt;
&lt;li&gt;👨🏻‍💻 🎸 I am passionate about technology and music, but after an unsuccessful year at music school I realized I should probably keep technology as a career and music as a hobby&lt;/li&gt;
&lt;li&gt;💼 I spent 15 years working in Networking and Security before I began to use Python and Go to make my life easier&lt;/li&gt;
&lt;li&gt;✍🏻 🎙 I write and speak about the intersection of these things to help organizations solve IT infrastructure problems&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="current-projects"&gt;Current projects&lt;/h2&gt;
&lt;p&gt;These are projects that I am (somewhat) actively working on.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/lykinsbd/naas"&gt;NAAS&lt;/a&gt;: Netmiko as A Service is a REST API wrapper for the popular &lt;a href="https://github.com/ktbyers/netmiko"&gt;Netmiko&lt;/a&gt; Python library for interacting with network devices. Currently modernizing and preparing for v1.0 release.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/tbotnz/cisshgo"&gt;cisshgo&lt;/a&gt;: A small, fast, concurrent SSH server to emulate network equipment (for example, Cisco IOS) for testing purposes.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/lykinsbd/leanpub-multi-action"&gt;Leanpub Multi Action&lt;/a&gt;: A Github Action I built for interacting with the API of &lt;a href="https://leanpub.com/"&gt;Leanpub&lt;/a&gt; in your authoring workflows.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="past-projects"&gt;Past projects&lt;/h2&gt;
&lt;p&gt;These are projects I was actively working on in the past, but I&amp;rsquo;ve not touched much in recent months (or years 😅).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/lykinsbd/stockpiler"&gt;Stockpiler&lt;/a&gt;: A &lt;a href="https://github.com/nornir-automation/nornir"&gt;Nornir&lt;/a&gt;-based tool for backing up network device configurations.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="tech-stack"&gt;Tech stack&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Languages&lt;/strong&gt;: Python, Go, Shell/Bash, Groovy&lt;br&gt;
&lt;strong&gt;Infrastructure&lt;/strong&gt;: Docker, Kubernetes, Terraform, AWS, Linux&lt;br&gt;
&lt;strong&gt;Network Automation&lt;/strong&gt;: Infrahub, Nautobot, NetBox, Ansible, Netmiko, Nornir, NAPALM&lt;br&gt;
&lt;strong&gt;Protocols&lt;/strong&gt;: GNMI, Netconf/RESTconf, SNMP&lt;br&gt;
&lt;strong&gt;Tools&lt;/strong&gt;: Git, GitHub Actions, Flask, Redis&lt;/p&gt;
&lt;h2 id="lets-connect"&gt;Let&amp;rsquo;s connect&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;📝 Blog: &lt;a href="https://network-notes.com"&gt;network-notes.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;💼 LinkedIn: &lt;a href="https://www.linkedin.com/in/brettlykins/"&gt;brettlykins&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;📧 Email: &lt;a href="mailto:lykinsbd@gmail.com"&gt;lykinsbd@gmail.com&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="drumroll-please"&gt;Drumroll please&lt;/h2&gt;
&lt;p&gt;The lie was the first one, if you guessed right here is a cookie: 🍪&lt;/p&gt;
&lt;p&gt;I am not a new nerd, but a lifelong nerd.&lt;/p&gt;
&lt;p&gt;And here are the receipts.&lt;/p&gt;
&lt;p&gt;My first computer:&lt;/p&gt;
&lt;p&gt;
&lt;img align="center" width="450" alt="A picture of Brett as a diapered-toddler typing on an Apple IIe" src="./images/IMG_2377.jpg"&gt;
&lt;/p&gt;
&lt;p&gt;Teaching my son that This is the Way:&lt;/p&gt;
&lt;p&gt;
&lt;img align="center" width="450" alt="A picture of Brett and his son in Star Wars costumes" src="./images/IMG_6025.jpg"&gt;
&lt;/p&gt;
&lt;!--
**lykinsbd/lykinsbd** is a ✨ _special_ ✨ repository because its `README.md` (this file) appears on your GitHub profile.
Here are some ideas to get you started:
- 🔭 I’m currently working on ...
- 🌱 I’m currently learning ...
- 👯 I’m looking to collaborate on ...
- 🤔 I’m looking for help with ...
- 💬 Ask me about ...
- 📫 How to reach me: ...
- 😄 Pronouns: ...
- ⚡ Fun fact: ...
--&gt;
&lt;!-- vale Microsoft.FirstPerson = YES --&gt;</description></item><item><title>About</title><link>/about/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>/about/</guid><description>&lt;blockquote&gt;
&lt;p&gt;This page is sourced from my &lt;a href="https://github.com/lykinsbd"&gt;GitHub profile README&lt;/a&gt;. View the original on GitHub for the latest updates.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id="hello-there-"&gt;Hello there 👋&lt;/h1&gt;
&lt;!-- vale Microsoft.FirstPerson = NO --&gt;
&lt;!-- vale Microsoft.Vocab = NO --&gt;
&lt;p&gt;My name is Brett Lykins, and my pronouns are &lt;a href="https://pronoun.is/he"&gt;He/Him&lt;/a&gt;.&lt;/p&gt;
&lt;!-- vale Microsoft.Vocab = YES --&gt;
&lt;p&gt;I live in Fairfax, Virginia, USA.&lt;/p&gt;
&lt;p&gt;
&lt;img align="center" width="450" alt="Image of Brett in front of some trees" src="https://raw.githubusercontent.com/lykinsbd/lykinsbd/main/images/IMG_5617_smol_cropped.jpg"&gt;
&lt;/p&gt;
&lt;h2 id="quick-facts-about-me"&gt;Quick facts about me&lt;/h2&gt;
&lt;p&gt;One of these is a lie, and you should try to guess which one.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;🤓 I am a new nerd who loves knowing how things work and how they&amp;rsquo;re put together&lt;/li&gt;
&lt;li&gt;👨🏻‍💻 🎸 I am passionate about technology and music, but after an unsuccessful year at music school I realized I should probably keep technology as a career and music as a hobby&lt;/li&gt;
&lt;li&gt;💼 I spent 15 years working in Networking and Security before I began to use Python and Go to make my life easier&lt;/li&gt;
&lt;li&gt;✍🏻 🎙 I write and speak about the intersection of these things to help organizations solve IT infrastructure problems&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="current-projects"&gt;Current projects&lt;/h2&gt;
&lt;p&gt;These are projects that I am (somewhat) actively working on.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/lykinsbd/naas"&gt;NAAS&lt;/a&gt;: Netmiko as A Service is a REST API wrapper for the popular &lt;a href="https://github.com/ktbyers/netmiko"&gt;Netmiko&lt;/a&gt; Python library for interacting with network devices. Currently modernizing and preparing for v1.0 release.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/tbotnz/cisshgo"&gt;cisshgo&lt;/a&gt;: A small, fast, concurrent SSH server to emulate network equipment (for example, Cisco IOS) for testing purposes.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/lykinsbd/leanpub-multi-action"&gt;Leanpub Multi Action&lt;/a&gt;: A Github Action I built for interacting with the API of &lt;a href="https://leanpub.com/"&gt;Leanpub&lt;/a&gt; in your authoring workflows.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="past-projects"&gt;Past projects&lt;/h2&gt;
&lt;p&gt;These are projects I was actively working on in the past, but I&amp;rsquo;ve not touched much in recent months (or years 😅).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/lykinsbd/stockpiler"&gt;Stockpiler&lt;/a&gt;: A &lt;a href="https://github.com/nornir-automation/nornir"&gt;Nornir&lt;/a&gt;-based tool for backing up network device configurations.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="tech-stack"&gt;Tech stack&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Languages&lt;/strong&gt;: Python, Go, Shell/Bash, Groovy&lt;br&gt;
&lt;strong&gt;Infrastructure&lt;/strong&gt;: Docker, Kubernetes, Terraform, AWS, Linux&lt;br&gt;
&lt;strong&gt;Network Automation&lt;/strong&gt;: Infrahub, Nautobot, NetBox, Ansible, Netmiko, Nornir, NAPALM&lt;br&gt;
&lt;strong&gt;Protocols&lt;/strong&gt;: GNMI, Netconf/RESTconf, SNMP&lt;br&gt;
&lt;strong&gt;Tools&lt;/strong&gt;: Git, GitHub Actions, Flask, Redis&lt;/p&gt;
&lt;h2 id="lets-connect"&gt;Let&amp;rsquo;s connect&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;📝 Blog: &lt;a href="https://network-notes.com"&gt;network-notes.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;💼 LinkedIn: &lt;a href="https://www.linkedin.com/in/brettlykins/"&gt;brettlykins&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;📧 Email: &lt;a href="mailto:lykinsbd@gmail.com"&gt;lykinsbd@gmail.com&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="drumroll-please"&gt;Drumroll please&lt;/h2&gt;
&lt;p&gt;The lie was the first one, if you guessed right here is a cookie: 🍪&lt;/p&gt;
&lt;p&gt;I am not a new nerd, but a lifelong nerd.&lt;/p&gt;
&lt;p&gt;And here are the receipts.&lt;/p&gt;
&lt;p&gt;My first computer:&lt;/p&gt;
&lt;p&gt;
&lt;img align="center" width="450" alt="A picture of Brett as a diapered-toddler typing on an Apple IIe" src="https://raw.githubusercontent.com/lykinsbd/lykinsbd/main/images/IMG_2377.jpg"&gt;
&lt;/p&gt;
&lt;p&gt;Teaching my son that This is the Way:&lt;/p&gt;
&lt;p&gt;
&lt;img align="center" width="450" alt="A picture of Brett and his son in Star Wars costumes" src="https://raw.githubusercontent.com/lykinsbd/lykinsbd/main/images/IMG_6025.jpg"&gt;
&lt;/p&gt;
&lt;!--
**lykinsbd/lykinsbd** is a ✨ _special_ ✨ repository because its `README.md` (this file) appears on your GitHub profile.
Here are some ideas to get you started:
- 🔭 I’m currently working on ...
- 🌱 I’m currently learning ...
- 👯 I’m looking to collaborate on ...
- 🤔 I’m looking for help with ...
- 💬 Ask me about ...
- 📫 How to reach me: ...
- 😄 Pronouns: ...
- ⚡ Fun fact: ...
--&gt;
&lt;!-- vale Microsoft.FirstPerson = YES --&gt;</description></item><item><title>Archive</title><link>/archive/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>/archive/</guid><description/></item></channel></rss>