Remove SSH host keys from known_hosts file

As a nwetwork admin you have to replace hardware because it’s faulty or of old age. After replacing the hardware , you will be warned of a man-in-the-middle attack while gaining access using SSH.

Warning looks like:

$ ssh some-host
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ECDSA key sent by the remote host is
SHA256:<super long, ECDSA finger print here>.
Please contact your system administrator.

When you are sure that the man-in-the-middle warning is caused by hardware replacement proceed by removing the old ssh key. If you are NOT sure DO NOT proceed and find the root-cause of this warning.

Proceed by removing the old key using the following command;

ssh-keygen -R <hostname>

Now you can get access using SSH. But first you will be prompted to add a new ssh-key to your known-hosts file.

Comments Off on Remove SSH host keys from known_hosts file

Multiple patterns with expect. Handling a SSH login dialog.

When automating network tasks, you a can hit a node which you have not logged on earlier. Using SSH you will end up in a dialog where the ssh client wants to add ssh-key to the known key list. You will hit a wall when using expect in a rather unsophisticated way, e.g.:

expect "this"
send "that\r"

Expect provides a way to conditionally send answers;

expect {
      "pattern_a" { send "answer_a\r"}
      "pattern_b" { send "answer_b\r"}
}

This resembles a construction like switch/case known in other programming/scripting languages. Like any other proper switch/case statement there is a default to act like a catch all. Like most programming/scripting languages it is possible to nest statements. Take a look at the next code ;

expect {
  "outer pattern_a" { 
    send "answer_a\r"}
  "outer pattern_b" {
    send "answer_b\r"
    #nesting starts------------------------
    expect {
      "inner pattern" {
        send "answer inner pattern\r" }
      default {
        send_user "Inner pattern not found\r"
        exit }
    }
    #nesting ends--------------------------
  } 
  #default behavior defined below.
  default {
    send_user "Pattern not found, bugging out\n"
    exit
  }
}

Nesting easily confuses the code, keep your code clearly readable. Provide comments in your code, to enable you to troubleshoot your own code in the future.

For a ssh login dialog you need to program the following steps;

#!/usr/bin/expect

set user uberuser
set passwd SuPeRseCriT
# grab the first argument and use it as var $host
set host [lindex $argv 0]

#set the timeout to a pleasantly low number, but not too low. 
set timeout 2

spawn ssh $user@$host

#--login shizzle starts here -------------------------------------------------
expect {
  "yes/no" {
    send "yes\r"
    #-- nesting start -- yes/no -> passwd dialog -----------------------------
    expect { 
      "assword:" {
        send "$passwd\r"
        #catch all undefined patterns
        default {
          send_user "Login failure\n"
          exit
        }
      }
      #-- nesting ends -- yes/no -> passwd dialog ----------------------------
      # catch all undefined patterns
       default {
         send_user "Login failure\n"
         exit                 
       }
     } 
   } 
   "assword:" {  
     send "$passwd\r"
     expect {
       ">" { exp_continue }  
       default { 
         send_user "Login failure\n"
         exit
       } 
    }     
  }
  default {
    send_user "Login failed\n"
    exit
  }
}
#--login shizzle ends here----------------------------------------------------

# Your magic goes here.. or
interact
# and type the commands your self :D

This code will effectively handle the ssh yes/no dialog. I tend to keep my code as tidy as possible in regards of comment, tabs and braces. This helps read the code afterwards.

It may seem redundant to this many “default” sections, but you want to handle wrong usernames as well. Which is handled implicit.

Hopefully this will help you understanding expect somewhat more.

Posted in TCL/Expect | Comments Off on Multiple patterns with expect. Handling a SSH login dialog.

Custom logfile on Juniper

Recently I placed a switch for a project. And now I want to see how often the switch is used by wired users. Lets for argument sake asume interface bounce is not handled by the standard log files.

Juniper provides a a way to create a logfile for your specific needs. Only thing you need to do is create a regular expression to catch the event. Interface bounce events are recognized by the keyword “ifOperStatus”

set system syslog file interface-logs any any
set system syslog file interface-logs match ifOperStatus
set system syslog file interface-logs archive size 500k
set system syslog file interface-logs archive files 20
  • File name is defined by file interface-logs
  • Filter is defined by match ifOperStatus
  • Archive size is defined by archive size 500k
  • and archive history is defined by archive files 20

This does the trick,. But an interface up event results is two log entries. One for the interface and one for the attached vlan subinterface.

ninja@juniper-ex3400> show log interface-logs | trim 25
juniper-ex3400 mib2d[15326]: SNMP_TRAP_LINK_DOWN: ifIndex 665, ifAdminStatus up(1), ifOperStatus down(2), ifName xe-0/2/0
juniper-ex3400 mib2d[15326]: SNMP_TRAP_LINK_UP: ifIndex 665, ifAdminStatus up(1), ifOperStatus up(1), ifName xe-0/2/0
juniper-ex3400 mib2d[15326]: SNMP_TRAP_LINK_UP: ifIndex 666, ifAdminStatus up(1), ifOperStatus up(1), ifName xe-0/2/0.0

A nice to have would be to filter out the vlan subinterfaces. The solution I came up with is replace the match statement with;

set system syslog file interface-logs match "ifOperStatus[ 0-9a-zA-Z(),-/]{1,}\/[0-9]{1,}$"

Now you only have one down notification and one up notification.Configuration looks like ;

set system syslog file interface-logs any any
set system syslog file interface-logs match "ifOperStatus[ 0-9a-zA-Z(),-/]{1,}\/[0-9]{1,}$"
set system syslog file interface-logs archive size 500k
set system syslog file interface-logs archive files 20

Et voila… you have created a logfile for your own specific purpose. The only problem I experience is creating a propper regexp to catch the log message. Luckily there are some tools available on the internet such as www.regexp101.com which you can use to test run your rexexp skills.

Posted in Commands, Juniper | 2 Comments

Pre-shared key on Cisco ASA55x0

Cisco devices store password crypted when “service password-encryption” is turned on. You should enable this on your network equipment.
You want to give imposters a hard time, so this is behavior you want.

Last week I found out a astonishing thing…

I configured a vpn on a Cisco ASA55x0. And misplaced the password.

I had two options;

  1. give the vpn a new pre-shared key,
  2. start a little search to find a loop hole. I decided the latter.

Show run or show start gives me, albeit in a decent way, the “finger“. The output is pre-shared key *, just an asterik nothing more nothing less. It gave the a gut feeling that pre-shared key a somewhere parsed and replaced by “*”. I know there is another way to read the config file.

more system:running-config

This did the trick. The proper pre-shared key was found after a little tinkering with pipe subcommands.

In hind sight; “show” parses the config file and replaces the password information. Whereas “more” does not parse the config file, it shows the content.

I do not know which software versions are affected. But I do know that you must keep access to the nodes restricted to the people and systems that  must have access. In other words: keep your config files and access to the config files safe.

Posted in security | Comments Off on Pre-shared key on Cisco ASA55x0

Cisco TCL – ping script.

70px-Tcl-powered.svgIn an earlier blog I wrote about a tiny hello world script.  Now I want to raise the bar a little bit, by creating a ping script. After a quick search on the internet I found a several kinds of scripts.  Each having their own maturity an complexity level. A script like this is convenient addition when setting up a lab. In case you need to check connectivity time and time again.

In this script we ping a number predefined host. If three consecutive pings get a reply than pinging this host is successful.

Lets start coding;

Create a script on the flash drive

puts [ open "flash:pingbulk.tcl" w+ ] {

Define the IP addresses we want to ping. Pay attention: this is static list.

 foreach ip {
 1.1.1.1
 2.2.2.2
 } {

Now the three consecutive ping logic will go here…
If a regexp find “!!!” than the ping is successful.

 if { [regexp "(!!!)" [exec "ping $ip timeout 1" ]] } {
 puts "$ip"
 } else { puts "$ip **** failed ***" }
 }
}

As some habits die hard, we create an alias called pingbulk.
Once the alias is executed we see the following result;

R1#pingbulk
1.1.1.1
2.2.2.2 **** failed ***
R1#

Entirely as expected; ip address 1.1.1.1 is assigned to the loopback0 interface.
Ip address 2.2.2.2 is assigned anywhere nor is the router connected to any network.nowhere to be found.

The complete script looks like;

puts [ open "flash:pingbulk.tcl" w+ ] {
foreach ip {
   1.1.1.1
   2.2.2.2
   } {
   if { [regexp "(!!!)" [exec "ping $ip timeout 1" ]] } {
     puts "$ip"
     } else { puts "$ip **** failed ***" }
   }
}

Additional notes: Please take note of the accolade placement. TCL interprets on a per rule basis. If you type “puts [open “flash:file.tcl” w+ ]” than only a file is opened and closed with the name nvram:file.tcl. Nothing is read or written to and from this file.

Same applies to other constructs like “foreach” “if/else” etc…. Another nice addition would be to use the “ip host” statements present in the config. Making the scripts more dynamic.

 

 

Posted in cisco | Tagged , , , , | Comments Off on Cisco TCL – ping script.

Cisco TCL – first steps… Hello world

70px-Tcl-powered.svgFor some time Cisco offers TCL shell on their equipment. This is awesome, because sometimes you need a single command to retrieve information whereas IOS demands you to enter one or more commands.

But before we get lots in possibilities and impossibilities. Lets create a tiny script to say “Hello world”.   First we will write the script afterwards I explain the tricky parts.

R1#tclsh
R1(tcl)#puts [ open "flash:hworld.tcl" w+ ] {
+>(tcl)#puts "Hello world..."
+>(tcl)#}
R1(tcl)#exit

First I run trough the commands;

Puts is short for PUT String. Output is ‘echoed’ on screen (stdout) unless defined otherwise. Definition is done in brackets. In the first instance a file is opened to which the output is written.

Open opens a file, w+ describes that a file is opened for write AND if no file of that name is found one must be created.

Script can executed by;

R1#tclsh flash:hworld.tcl
Hello world...

R1#

If you want to call TCL script more like a IOS command you can create an alias.

R1#conf t
Enter configuration commands, one per line. End with CNTL/Z.
R1(config)#alias exec hello tclsh flash:hworld.tcl
R1(config)#exit
R1#

An alias name “hello” is created. Once executed you will get the following result.

R1#hello
Hello world...

R1#

Okay, writing a tiny tclshell “hello world” script is not rocket-science.
Once you explore more and more you’ll get the hang of it and can do really fun stuff.

Posted in cisco | Tagged , | Comments Off on Cisco TCL – first steps… Hello world

Anki – Spaced Repetition

While studying, I am seeking for ways to study more efficient. In the beginning I stumbled upon a method called ‘spaced repetition’. This method is wildly popular in the U.S. Unfortunately when I attended high school my home country this method was not used. I guess when if I knew about this method earlier in life my career would have looked much different.

Since I am network professional, a computer is never far away. The computer hardware uses Windows, Ubuntu and Android as an OS.  I want the study progress to be available on all hardware. First I used different software, unfortunately the variety of  OS’s proved difficult.

Recently I found a tool automate spaced repetition and which enabled syncing between the computers and tablets. The tool is called Anki. ( https://apps.ankiweb.net/ ). At this point I have only checked syncing between Ubuntu and Android.

It works like a charm.

Posted in Lifehacking | Comments Off on Anki – Spaced Repetition

First Hop Redundancy Protocol – HSRP

Cisco proprietary HSRP protocol is a protocol for enabling a first hop fault tolerant router. Enabling your default gateway ip address to ‘live’ on more than one router. Back in the old days you had one router to exit a lan.
Once the router died or was out of service due to maintenance hosts in the LAN were not able to communicate out of the lan.

Cisco created a protocol which enabled two (or more) routers to listen to one ip address (layer 3) and one mac-address (layer 2).
Both layer 2 and 3 addresses have used in the redundancy setup otherwise you have to wait for arp entries to time-out.

While configuring you need to set the standby priority. Priority can be set between 0 and 255. Default value is 100.
When the HSRP Active interface has become unavailable, priority is decremented by 10. Choose you HSRP priorities smart.

In the topologies I have seen, the priorities chosen were 100 and 105 or 95 and 100. In all cases that were two router set-ups.
Of course you can be creative and create a three router set-up.

Communication between participating router is done through multicast ip’s HSRP v1 224.0.0.2:1985(UDP) and HSRP v2 224.0.0.102:1985(UDP).

Important use “preemt” : to get the router with the highest priority to recover to Active after an outage.

 R1#sh run int e1/1
 !
 interface Ethernet1/1
 description lan-1
 ip address 172.16.10.2 255.255.255.0
 ip helper-address 172.16.99.254
 standby 1 ip 172.16.10.1
 standby 1 priority 105
 standby 1 preempt
 R2#sh run int e1/1
 !
 interface Ethernet1/1
 description lan-1
 ip address 172.16.10.3 255.255.255.0
 ip helper-address 172.16.99.254
 standby 2 ip 172.16.10.1
 standby 2 priority 100
 standby 2 preempt

The configuration of the DHCP server is not very complicated.

 ip dhcp excluded-address 172.16.10.1 172.16.10.10
 ip dhcp excluded-address 172.16.10.254
 !
 ip dhcp pool lan-1
  network 172.16.10.0 255.255.255.0
  default-router 172.16.10.1 
 !

Be sure to set the default gateway to the HSRP address, otherwise you have a very neat solution which does not give you the fail save you need.

Posted in CCNP | Comments Off on First Hop Redundancy Protocol – HSRP

Access-list mask or wildcard

G’day all, today I was messing around with access-list.  And after getting my head around the weird subnets of rfc1918. Weird as in an A-class (/8) is reserved in A-space, B-class (/16) in reserved in C-space, and for the B-space has a /12 is reserved. Nothing is standard in the world of standards.

But that on a side-note. The whole rfc1918 got me distracted. So when I started creating the access-list, I mistakenly used the subnet mask instead of the wildcard.

First I made the access-list using subnet masks.

ISP1-R1(config)#ip access-list extended rfc1918-wrong
ISP1-R1(config-ext-nacl)#permit ip 10.0.0.0 255.0.0.0 any
ISP1-R1(config-ext-nacl)#permit ip 172.16.0.0 255.240.0.0 any
ISP1-R1(config-ext-nacl)#permit ip 192.168.0.0 255.255.255.0 any
ISP1-R1(config-ext-nacl)#deny ip any any
ISP1-R1(config-ext-nacl)#exit

Next I made the access-list using wild cards.

ISP1-R1(config)#ip access-list ex rfc1918-right
ISP1-R1(config-ext-nacl)#permit ip 10.0.0.0 0.255.255.255 any
ISP1-R1(config-ext-nacl)#permit ip 172.16.0.0 0.15.255.255 any
ISP1-R1(config-ext-nacl)#permit ip 192.168.0.0 0.0.255.255 any
ISP1-R1(config-ext-nacl)#deny ip any any

I check the things that I do in a network. I think its a good habit and somebodies health might depend on it.

ISP1-R1#sh access-lists
Extended IP access list rfc1918-wrong
10 permit ip 0.0.0.0 255.0.0.0 any
20 permit ip 0.0.0.0 255.240.0.0 any
30 permit ip 0.0.0.0 255.255.255.0 any
40 deny ip any any
Extended IP access list rfc1918-right
10 permit ip 10.0.0.0 0.255.255.255 any
20 permit ip 172.16.0.0 0.15.255.255 any
30 permit ip 192.168.0.0 0.0.255.255 any
40 deny ip any any

You see that the access-list made using subnet mask are completely borked.

The moral of the story is as follows;

  • always check what you have configured.
  • Use subnet mask to assign ip addresses to interfaces ans wildcards for accesslists.

 

Posted in CCNP | Tagged , , , , | Comments Off on Access-list mask or wildcard

Juniper filters

In the networking world a multitude of vendors are present. And each of them have their magnificent features  but also their quirks. And one of the quirks, for the network vendors in general, is that terminology is not uniform.

Where Cisco likes to talk about Access-Control List or ACL for short Juniper likes to talk about filters. Juniper filters are awesome. Juniper likes to arrange information a tree-like structure. This enables Juniper for future changes in software approach.

Cisco has standard access-list, the down-side; modification can not be done. Deletion of one ACE is not possible.  The entire ACL has to be removed.

A slight improvement are extended access-lists. Every ACE has a number associated with it. And using some ip access-list resequence magic you can make some room to insert ACE’s.

This hassle is not known to Juniper engineers.

Simply create a access-list ehm …. filter

set firewall family inet filter generic-filter term discard then discard

This filter simply, forwards every packet to the great bit-bucket in the sky.

If you want to allow traffic from you lan towards webservers you add the following;

set firewall family inet filter generic-filter term web_lan from source-address 10.0.0.0/8
set firewall family inet filter generic-filter term web_lan from protocol tcp
set firewall family inet filter generic-filter term web_lan from destination-port 80
set firewall family inet filter generic-filter term web_lan then accept

Now you have two terms within the “generic-filter”

show configuration firewall
family inet {
    filter generic-filter {    
        term discard {
            then {
                discard;
            }
        }
        term web_lan {
            from {
                source-address {
                    10.0.0.0/8;   
                }
                protocol tcp;
                destination-port 80;
            }
            then accept;
        }
    }

If you leave it this way traffic to the webservers are discarded instead of allowed. This is where Juniper added some pretty awesome magic;just shuffle the term to a place where is fits best.

insert firewall family inet filter generic-filter term web_lan before term discard

Of course you need to address some more issues like established traffic etc.

But this is how Juniper addresses filters. And there are a whole lot more things you can manage with filters. You can create a variables , and when a condition is met the counter is raised by the value you like.  Variable is readable in the context of show firewall.

Today my first steps in Juniper filtering. An awesome experience.

Posted in Juniper | Comments Off on Juniper filters