My own config generator and autoloader part 2 – uploading the config


We finished part 1 where the config generator produced a test.txt file on the Window desktop. Now it’s time for another script to upload the config through a telnet connection. To do that, we need pexpect, and it’s not possible to install pexpect on windows. Fortunately, Windows 10 provides the windows subsystem for linux. I’ve installed Ubuntu using powershell.

Because the script doesn’t know the username, it needs to get the username folder from path.home. Once it has it, it reaches out to Windows, copies the test.txt config to its own c.txt file. Then it creates a telnet connection to the console server and uploads the config line by line.

import pexpect
import os
import sys
from pathlib import Path

def createall(ip,port,consoleserver):
#getting the username and copying the config
  myarraypath = str(Path.home()).split('/')
  table = { 39 : None }
  myfinaluser = myarraypath[2].translate(table)

#if c.txt exists, contents should be deleted
  clearcommand = "truncate -s 0 c.txt"
  command = "tail --lines=+1 /mnt/c/Users/" + myfinaluser + "/Desktop/test.txt >> /home/" + myfinaluser + "/c.txt"
#spawning a connection
  child = pexpect.spawn('telnet ' + ip + ' ' + port)
  child.logfile = sys.stdout.buffer
  child.timeout = 14
  child.delaybeforesend = 1.0
  myconsoleserver = consoleserver
  child.expect(consoleserver + ' login:')
#you just have to love my variable names
#you may see either of the prompts so 2 cases here
# if prompt is >, send an enable
  neverknow = child.expect(['#', '>'])
  if neverknow==1:
#if prompt is #, upload the c.txt file line by line
  elif neverknow==0:
     child.sendline('configure terminal')
     filename = 'c.txt' 
     with open(filename) as file_object:
       lines = file_object.readlines()
       for line in lines:
         line = line #+ "\015"

#this script can be run with the following command:
#python3 8002 myconsoleserver

if __name__ == "__main__":
  ip = sys.argv[1] 
  port = sys.argv[2]
  consoleserver = sys.argv[3]
  createall(ip, port, consoleserver)

My own config generator and autoloader part 1 – preparing the config

Hello again

It’s been a while since my last entry and i blame covid 🙂

Jokes aside, I used that 4 month break to do some thinking about where I want to be in a few years’ time. I kept learning python and watching how networks become more devops-oriented. The harsh reality is that most of network engineers will either lose their jobs or become programmers. There’s no denying that at this point.  Also, I personally feel that i’m a bit tired of good old network configuration (which is why i never did my ccie) and it’s time to make another step forward, just like 9 years ago when I joined the sonicwall support team. From now on my posts will concentrate more on how to automate operations rather than on operations per se.

Let’s start, then.

Part of what i do at work has to do with configuring new routers and sending them to client sites. I get a telnet connection through a console server to those routers, which isn’t ideal. Part 1 is coming up with the actual config, which is always a pain because you need to replace the config in a number of places. I’ve therefore come up with the following python script which:

  1. opens a GUI where you can put your config variables
  2. generates a config and saves the result to a test.txt file on the desktop
  3. archives the config as a <hostname>.txt file on the desktop
from networkconfgen import NetworkConfGen
import sys
import os

import PySimpleGUI as sg
import shutil
import socket
from tkinter import *
from tkinter import messagebox

#this creates the GUI layout 


layout = [[sg.Text('My config generator')], 
[sg.Text('LAN IP', size=(21, 2)),sg.InputText('x.y.z.a'),sg.Text('subnet mask', size=(18, 2)),sg.InputText('')], 
[sg.Text('WAN IP', size=(21, 2)),sg.InputText('a.s.d.f'),sg.Text('subnet mask', size=(12, 2)),sg.InputText('')],
[sg.Text('hostname', size=(21, 2)),sg.InputText('testrouter')],
[sg.Text('VRRP IP', size=(21, 2)),sg.InputText('x.y.z.b')],
[sg.Text('WAN next hop', size=(21, 2)),sg.InputText()],
[sg.Text('Serial Number', size=(21, 2)),sg.InputText('BIGBROWNFOX')],
[sg.Text('tunnel1 IP', size=(21, 2)),sg.InputText('172.16.0.x'),sg.Text('subnet mask', size=(12, 2)),sg.InputText('')],
[sg.Text('tunnel2 IP', size=(21, 2)),sg.InputText('172.16.1.x'),sg.Text('subnet mask', size=(12, 2)),sg.InputText('')],
[sg.Text('loopback', size=(21, 2)),sg.InputText('172.16.2.x'),sg.Text('subnet mask', size=(12, 2)),sg.InputText('')],
[sg.Text('network address of LAN', size=(21, 2)),sg.InputText('x.y.z.0'),sg.Text('subnet mask in slash format', size=(12, 2)),sg.InputText('/29')],

window = sg.Window('Window Title', layout) 
event, values =

#this reads the variables from the array generated by the GUI. 
lanip = values[0] 
lanipsubnetmask = values [1] 
wanip = values[2]
wanipsubnetmask = values [3]
hostname = values[4]
virtlanip = values[5]
nexthop = values[6]
serial = values[7]
tunnel1 = values[8]
tunnel1subnetmask = values[9]
tunnel2 = values[10]
tunnel2subnetmask = values[11]
loopback = values[12]
loopbacksubnetmask = values[13]
networklan = values[14]
networklansubnetmask = values[15]

#this checks if values in all fields are valid IP addresses

# legal
except socket.error:
messagebox.showerror(title="OH BLIMEY", message="ADDRESSING MISTAKE")


#this creates a confgen object

confgen = NetworkConfGen()

template = """

#here put any configuration you need with variables in the double brackets, example:
hostname {{hostname}}

interface Gi0/0
ip address {{WANIP}} {{WANIPSUNETMASK}}
parameters = {
"hostname": hostname, 
"WANIP": wanip,
"WANIPSUBNETMASK": wanipsubnetmask,
"REALLANIP": lanip,
"REALLANIPSUBNETMASK": lanipsubnetmask,
"VIRTLANIP": virtlanip,
"NEXTHOPWANIP": nexthop,
"SERIAL": serial,
"TUNNEL1IP": tunnel1,
"TUNNEL1IPSUBNETMASK": tunnel1subnetmask,
"TUNNEL2IP": tunnel2,
"TUNNEL2SUBNETMASK": tunnel2subnetmask,
"LOOPBACKIP": loopback,
"LOOPBACKIPSUBNETMASK": loopbacksubnetmask,
"NETWORKLAN": networklan,
"NETWORKLANSUBNETMASK": networklansubnetmask
result = confgen.render_from_string(
if not result.render_error:
sys.stdout = open("test.txt", "w")

print("Something went wrong: %s" % result.error_text)

oldname = 'test.txt'

SSH keys lost after reload on 16.9.2


I’m currently taking part in a project where we send out new routers to remote locations and on a number of occasions we had a problem where i couldn’t connect to my preconfigured router via ssh. I thought i was going crazy because this happened randomly and every time i had to console in to the router with the assistance of some onsite technician, which is always a hassle. And today i’ve found the confirmation in CSCvm54595: SSH keys can go missing if you write the config with do wr. Or you can upgrade to 16.9.3+.

I am not going mad after all. Cisco, this was not your finest (regression testing) hour.

What i did as a workaround…

event manager applet ssh_key_regenerate authorization bypass
event syslog occurs 1 pattern „SYS-5-RESTART” maxrun 90
action 1.0 cli command „enable”
action 1.1 cli command „conf t”
action 1.2 cli command „crypto key zeroize rsa MYSSHKEYS.server”
action 1.3 cli command „crypto key generate rsa general-keys label MYSSHKEYS modulus 4096”

Multi-sa support for VTIs


Tired of old crypto maps? ios-xe 16.12 has something for you, then.

This nifty little feature works just like crypto maps behind the scenes, but logically it’s a tunnel. All you need to do is create a tunnel with ip unnamed and add: tunnel protection policy ipv4 <crypto ACL name>:

interface Tunnel0
 ip unnumbered GigabitEthernet0/0/0
 tunnel source GigabitEthernet0/0/0
 tunnel mode ipsec ipv4
 tunnel destination
 tunnel protection ipsec policy ipv4 CACL
 tunnel protection ipsec profile PROF

Isn’t this just great?

I’ve tested this feature on 16.12.3 and it seems fine. So you can have a crypto map (your old VPN connections) on your outside interface and, slowly but surely, you can delete all your crypto map entries one by one, transforming them into new VTI tunnels.
One immediate benefit I can think of is the possibility to have QoS on your tunnels, plus you no longer have to deal with the fact that your tunnels are traffic-triggered. You don’t have to wait for your business partner to say: hey tunnel isn’t working, because you will see it in the status of your tunnels so you can monitor them with SNMP. How cool is that.

For now i’ve tested this on my CSR1000v in GNS3. Hopefully I’ll be able to convince someone at work to allow an upgrade on my ASRs so that I can see how this works in production.

I’ll try to see if this also works with DVTIs (virtual templates etc.).

Cool stuff i’ve found in the new core 300-401 coursebook


I’ve gone through 60% of the book so far (switching, routing, and most of wireless) and I must say it’s a bad book. There’s ton of theory, very little configuration. It may be good as a refresher book just before the exam but I think this approach will just produce paper tigers. But what do i know.

I’ve managed to find some new stuff, though. I’ll keep expanding this. I still have 12 chapters to go.

  1. BGP AIGP – cool stuff, if you have thousands of PEs, and if you’ve grouped them in private BGP AS but for some reason each BGP AS has a different IGP, AIGP lets BGP make routing decisions based on IGP metric.
  2. VRRP v3. This just adds ipv6 support and changes the config to address family config. Nothing fancy.

ISE binary certificate comparison mystery


I’m wondering if anyone has encountered the same problem with binary certicate comparison. The scenario is as follows:

  • the client hires a new employee
  • an AD account is created for that employee.
  • Meanwhile, a PC is prepared for that employee and an IT person logs to that PC for the first time. CA shares a copy of the certificate with AD.
  • The employee receives the PC but can’t log into the network
  • ISE says that no valid account has been found in AD for this certificate IF binary certificate comparison is used. If it is not used, ISE accepts the certificate as valid.

If the certificates are refreshed on the PC, all is well again.

My theory is that this is due to the fact that there are multiple domain controllers and I think that there might be problems if the domain controller receives the certificate from CA before the object is replicated on that branch domain controller and mapping of machine account to machine certificate fails on that controller. My theory is further corroborated by the following bug:

and the following forum entry:



What I do when i don’t do IP


You can totally skip this entry if you’re only interested in networks. It’s just that i’ve met a few new colleages recently who had the impression that I spent my whole life in the cisco world (and this is so not true! i spend the other half in junos 😀 ) so I’ve decided to show that there’s more to me than just the network guy.
So the other part of what I do is that I learn languages and read books in those languages. I’ve developed this system recently where I try to read 4 books in french, 1 in spanish and 1 in german to stop from getting all rusty. (I think i’d like to learn Arabic as well but it’s definitely not a goal for this decade. Maybe 2030-2040).

I don’t use my languages at work every day but I have been able to use my spanish to talk to clients from south america on a number of occasions and it really boosted my relationship with those clients. I use german occasionally and it’s been a massive help in my career because (unsurprisingly) few network people can speak german on a professional level. But overall I learn languages just to be able to read literature. I read really diverse stuff. Books by Graham Greene, Juli Zeh, Sapkowski, Stephen King, hell, i’ve even read 12 rules for life by Jordan Peterson lately. Although I don’t have the same drive to read for pleasure as in the past (which may be due to the fact that i read too much for work purposes and my brain is in overload most of the time), i can still manage one book a month. In the past i would have been mortified at sharing this poor(ish) result but times have changed and I’m as close to being proud of that as I can be. I have a full time job, i’m a dad and I still read one book a month. Do you get an ”average-at-all” badge if you’re the best dentist-driver? or the best baker among rock singers? or the most-overweight half-marathon participant ? Jack of many trades, master of none 🙂

CCNP and CCIE ENCOR 300-401 finally out


The book is finally out, at least on Safaribooks. I’ve read 1/3 so far and it’s a nice little refresher of things i read a long time ago and managed to forget, like what happens if you have MST between 2 switches with 2 links connecting them. Now you map vlan 10 instance 1 but leave vlan 20 in instance 0. Then you try to load balance the traffic by putting vlan 10 on upper link and vlan 20 on lower link only. Of course the vlan 20 traffic will be blocked because IST is a member of all interfaces 😀 so you end up with connectivity only on vlan 10 and hosts in vlan 20 lose connectivity. Of course, why would you not map all vlans to mst instances other than 0 ? laziness, i guess. I’ll try to read the whole book this week to see if it’s any good. I kind of expected more depth, but maybe this is the idea of the ”core” book? to keep it simple?

Anyways, i’ve been playing with very random things recently, like dmvpn with ikev2 and certificates between ASRs and new shiny c1116s. Something that is worth testing in gns3 is a weird situation where a branch router is reloaded and dmvpn gets stuck in NHRP state. What i’ve found is that the hub router mistakenly deletes both the old IKE and the new IKE, so it can never decrypt the data. It’s only when DPD on the branch router reinitializes IKE that NHRP starts working properly. So a quick and dirty fix of this bug is to lower DPD to 30 seconds but the bug is still there whenever a branch site loses power. oh well.
Another activity that i’ve been lucky to be assigned to was testing of 9336 nexus switches for a server block with an emphasis on vPC. It’s rare that you can get a free lab so I tried to test a lot of vPC features, like vPC autorecovery, layer3 peer router, peer switch etc. All in all the best assignment i’ve had in months.

Finally, i’d like to share a hilarious ”team work” situation i’ve seen recently; it’s quite recent so i hope nobody feels offended but i can’t help myself: the client reports (6 months ago) that a company laptop may have been stolen and asks the firewall team to block an internal IP from talking with the enterprise network. The brave fw team blocks this one IP and the matter is put to sleep. Now fast forward to October. A client PC can’t connect to certain IPs. The brave fw team receives the incident and logs a comment saying that everything is fine, because this deny action is as per client request 6 months earlier. The confused NOC team asks to remove the rule because it is no longer needed, the laptop was never stolen in the first place, and this is quite possibly a different laptop that happened to receive the same IP because this IP is in the dhcp scope. This request is rejected by the fw team who says that the IP address in question should simply be excluded from the DHCP scope instead because the rule was created based on customer request so it should stay. The ticket then detiorates into a senseless ping-pong (my opinion is so much better than yours etc.).
It is so sad that each team lives in their antinuke silo where everything is comfy and warm, with thick ITIL carpets and linen. And you do not leave your silo because your friends are inside and outside there could be wolves! and dragons! or worse – blood traitors! Giving in to your enemy request once is like inviting a vampire into your home. One never knows what will happen. It’s best to barricade the door and wait for the postnuclear winter. You can only leave your bunker according to ITIL rules. Does ITIL say to eat? No? then die of hunger we shall!

GNS 2.2 is coming…


Every now and then I have a look how the good old GNS is changing and I was kind of amused to see that the 2.2 update will bring the link awareness, that is: if you don’t connect a cable between two devices, the link will be down/down. Before, any link that you unshut would be automatically up.
Anyways, I’m kind of ”between jobs” at the moment as i’m moving to a different team so I feel like i’m in a limbo. Stll, if everything goes according to plan in the next 2 months, there are a few courses that i’d like to do in the future, depending on what i’ll be doing in my new team. It’s either CCIE wireless from networkdojo or CCIE enterprise from Micronics. Or maybe both.

On a slightly related note, i’ve been reading 12 rules for life by Jordan Peterson and I found this passage that I thought was very inspiring. If you have a choice between security and self-improvement, it’s a good idea to choose improvement.

“You are by no means only what you already know. You are also all that which you could know, if you only would. Thus, you should never sacrifice what you could be for what you are. You should never give up the better that resides within for the security you already have—and certainly not when you have already caught a glimpse, an undeniable glimpse, of something beyond.”

It’s important to have someone to look up to.


I was watching another video with Jordan Peterson today and I was reminded of how important it is to have an authority figure in your life, someone you can look up to, someone that you can listen to every day. Especially now where the world is changing at a pace never seen before, we are getting a bit lost, and there are many questions that nobody seems to have a good answer to. How to catch up with the changing technology and expectations at our workplace? What is my role in the family that is so unlike the family I was part of as a child? how to keep my life balanced and meaningful? Am I smart enough to get ahead in life or in my job?

A decade ago, back when I started learning about IP networks, I was lucky enough to stumble upon Jeremy Cioara, an amazing instructor from CBTnuggets. But he’s not only that: he can create an atmosphere where you can believe that you can achieve anything you want, that you are capable of achieving your goals, and that your goals are worth fighting for. Once in a while Jeremy will share with you his vision of the world, or he will tell a story about his wife and kids, how he deals with pressure etc., And even though it’s supposed to be strictly about IT, these extra bits and pieces about ”the world of Jeremy” are such a great addition to these courses because then Jeremy becomes a real person, a person that has the same challenges that you have, a person that also deals with the lack of time, with any mistakes he’s made at work etc. And he is able to maintain an unbelievable level of optimism and certain insouciance that makes you feel that this can be indeed the best job you can get because no problem is insurmountable.

For a few years Jeremy’s words were probably nearly 90% of all words that I heard every day as i spent up to 6 hours every day watching CBT. I’m fairly sure that if it hadn’t been for Jeremy, I wouldn’t have achieved that much in such a short period of time. And it would have been much more painful with any other trainer. So if you’re like me, try to browse through a few IT portals with video courses and see if any person in particular comes across as someone that you admire or at least someone you don’t mind watching for very extended periods of time.

So to all Jeremies, Brians and Jordans out there: cheers! You are the leaders of men in the age of technology and fast-paced change.