A New Paradigm in an Old Dog's World

Networking and Other General Geekery

IRSSI + Mac OSX + Growl Notifications

OK, this may be a little off topic, but I thought it was kind of neat. I recently started using bitlbee again (I stopped due to missing features/support when I last looked at it, but it has come a long way it seems, plus there are public IPv6 servers now!)  So, the primary thing I found missing from this, if I was to stop using ichat, was good notification of new messages.  So… after a little searching, I found this post at Matt Hutchinson’s blog.  He’s doing this on a remote server, which is fine, but I run irssi locally, and don’t really care to leave it idling when I’m not on the computer, since I’m never going to go through backlog, so…  I did a few things differently:

1.Installed fnotify irssi script:

cd ~/.irssi/scripts

wget --no-check-certificate -O- "https://gist.github.com/gists/542141/download" | tar -zxvf -

mv */fnotify.pl .

ln -s ~/.irssi/scripts/fnotify.pl autorun

2. Installed Growl and growlnotifiy.

3. Update ~/.irssi/config with bitlbee server info:

servers = (

{ address = "2001:470:dc2e:5::1"; chatnet = "bitlbee"; port = "6667"; }

{ address = "godzilla.everdot.org"; chatnet = "bitlbee"; port = "6667"; }

}

chatnets = {

bitlbee = {

type = "IRC";

### the next line acts as an autoconnect function to the IM gateway bitlbee

autosendcmd = "/^msg -bitlbee &bitlbee identify PASSWORD; wait -bitlbee 2000";

};

}

3. Grab a nice irssi png

wget -O ~/.irssi/irssi-icon.png "http://blog.ufsoft.org/_uploads/irssi.png"

4. Update ~/.bash_alias file with a new function called ‘chat’ which will watch the ~/.irssi/fnotify file and push new messages to growl:

 function chat { if [[ $( ps aux | grep -v grep | grep "tail -f .*fnotify" ) ]]; then echo Growl running; else echo > ~/.irssi/fnotify; tail -f ~/.irssi/fnotify |  while read; do growlnotify --image ~/.irssi/irssi-icon.png -m "$REPLY"; echo $REPLY | cut -f1-10 -d" " | say; done & fi; irssi -c godzilla.everdot.org;  }

The ‘cut -f1-10′ portion limits the amount sent to ‘say’ to the first 10 words. Adjust to your personal preference.

5. Open a new terminal (to source the ~/.bash_aliases file) and run the function to launch the watch process and irssi and connect to bitlbee.

I typically run two instances of irssi. One for irc, and the second for bitlbee. Neat thing about this, is once that watcher process is running, it will alert you to any hilights or private messages. Very cool.

Traceroute

OK, I know this is a little rudimentary, but… it seems to come up a lot.  Simply put, traceroutes that result in the last hop showing low latency and no packet loss, have no latency or packet loss along the way, regardless of what the traceroute shows.  I’ve seen a lot of escalations trying to troubleshoot why the 3rd router in a 10 hop traceroute is not responding, or has a high ping, but the end to end is low and consistent.  Below is a little powerpoint I put together, to help illustrate how traceroute works, in the interest of getting people to stop chasing wild geese.  I hope it helps you explain this relatively straight forward concept:

traceroute.pptx

JUNOScript – First attempt

So, there are many things that make Junos very robust and flexible.  One of the more rarely used, and more powerful is the built in scripting capabilities.  We’ve found a couple of situations where a script would come in very handy.

  1. By default, Juniper routers have all interfaces in an admin up state.  This is great, except for the fact that our NMS alarms on any interface that is admin up, but down, so this kicks off all kinds of alarms
  2. Every GigE port in our network has a single vlan that is used for management, and must be ‘bridged’ together.  Its really common to forget to add a newly configured interface to the bridge-group.

Interface-disable.slax

We’ve got this great script we’ve been using that transitively disables any unconfigured interface.  While I think its excellent to admin up interfaces by default, most NMS’s assume there is a problem with an interface in up/down status, so in order to avoid alarms, we’ve been using this script:

/*
 * This script transiently disables all unconfigured ge interfaces.
 */

version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match configuration {

    /* Get the current interface list  */
    var $interfaces = jcs:invoke( "get-interface-information" );

    /* Only ge and xe interfaces */
    var $ge-interfaces = $interfaces/physical-interface[starts-with(name, "ge-") or starts-with(name, "xe-")];

    var $interface-hierarchy = interfaces;

    /* Go through each ge interface, if it isn't within the configuration than transiently disable it */
    for-each( $ge-interfaces ) {

        if( jcs:empty( $interface-hierarchy/interface[name == current()/name ] ) ) {
            <transient-change> {
                <interfaces> {
                    <interface> {
                        <name> name;
                        <disable>;
                    }
                }
            }
        }
    }
}

This works really well, with one exception.  After a power failure, the transient change is lost, and all unconfigured interfaces are in up/down status until someone logs in and does a commit.  While I enjoy the clean looking config the transitive solution offers, we’ve had a need to ensure this initial alarming doesn’t happen, which means we need to change the config non-transitively.

Below is the config I will apply (I use the group so during configuration later, all child units are also disabled, which has more to do with our internal processes than anything technical) to each interface.

interfaces {
    <*> {
        disable;
        unit <*> {
            disable;
        }
    }
}

interfaces {

    ge-0/0/0 {

        apply-groups DISABLEIF;

    }

}

Here is the non-transitive script to use that will apply the DISABLEIF group to each interface:

/*
 * This script disables all unconfigured ge interfaces.
 */

version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match configuration {

    /* Get the current interface list  */
    var $interfaces = jcs:invoke( "get-interface-information" );

    /* Only ge and xe interfaces */
    var $ge-interfaces = $interfaces/physical-interface[starts-with(name, "ge-") or starts-with(name, "xe-")];

    var $interface-hierarchy = interfaces;

    /* Go through each ge interface, if it isn't within the configuration than apply-group DISABLEIF */
    for-each( $ge-interfaces ) {

        if( jcs:empty( $interface-hierarchy/interface[name == current()/name ] ) ) {
	     <xnm:warning> {
		<message> "Disabling unconfigured interface: " _ name;
	     }
	     <change> {
                <interfaces> {
                    <interface> {
                        <name> name;
                        <apply-groups> "DISABLEIF";
                    }
                }
	     }
        }
    }

}

You'll have to store this file on the router's hard drive in /var/db/scripts/commit/

Of course, you must tell your router to run this script on each commit:

set system script commit file "interface-disable.slax"

I'll cover the bridge-domain update in another post!

SSH Errors when connecting to a Juniper Netscreen SSG5-GT

Recently, I started working with Netscreens, which I haven’t done for 10 years or so. Things have changed a bit. As I’m learning ScreenOS, and trying to get around and configure these things, I’m getting really aggravated because while I’m RTFM’ing, the ssh session keeps disconnecting with this error:

buffer_get_ret: trying to get more bytes 4 than in buffer 0
buffer_get_int: buffer error

It only seems to happen after a very short period of inactivity though. Highly reproducible, and seems to happen from all my OSX clients I’ve tried. So, I try from a ubuntu box, and it doesn’t happen, which leads me to evaluate what is different between the two. Both are running the same OpenSSH version, but a different OpenSSL version. Oh, and the Ubuntu config is a stock vanilla config, while the OSX boxes all have a custom ~/.ssh/config that is used to set usernames and a few ssh options to make my life easier.

So, I renamed ~/.ssh/ on a OSX box, and the problem vanishes! This tells me it has to do with my ssh config. After a bit of troubleshooting, I isolated the problem in this portion of my ~/.ssh/config file:

Host *
ServerAliveInterval 30

I use this command to keep from timing out on SSH servers that boot you for inactivity. It works fine for all the servers I’ve used, until now. Apparently when the SSH client detects 30 seconds of inactivity, it sends some sort of stay alive message, which the Netscreen fails to handle and decides to immediately disconnect.

To work around this, set this value to 0 (to disable) on your Netscreen hosts in the ~/.ssh/config file:

Host vpn*
ServerAliveInterval 0

All my Netscreens are in my hostfile and begin with vpn-

You need to put the hostname, IP address with or without the asterisk wildcard for your situation.

Hope you found this helpful. I was unable to find ANYTHING on the net that explains this.

EDIT: Michael Newton has had success in adding the following options as well to the Host entry in the ssh config:

Host ns5gt
TCPKeepAlive no
ServerAliveInterval 0
HostKeyAlgorithms ssh-dss

EVPL vs E-TREE

Just finished watching a MEF webcast on ethernet backhaul for mobile wireless.

While this is interesting, MEF (as always) doesn’t give you any technical details about how it can be done.  Its refreshing to see that what I’ve been working on is 100% in line with MEF’s vague standards.  ;)

On another note, I noticed that they are starting to more predominantly use the term ETREE instead of EVPL.  They should pick one and stick to it.  Also, the diagram for EVPL/ETREE uses a ‘Ethernet LAN’ symbol with dotted lines showing the ‘ROOT’ and ‘LEAF’ relationships.  Seems to me they expect EVPL to be a LAN with some mechanism to prevent LEAVES from seeing one another.

This deviates from what I’ve seen most folks do.  The problem I’ve seen with the EVPL/ETREE service, is most folks approach the problem by stacking multiple EVC’s on the same trunk handoff to a customer.  This breaks transparency and requires tag coordination w/the customer, and breaks L2protocol tunneling, and just causes general headaches for everyone involved.

I thought of an illustration of how to accomplish this at L2 that would help the engineers with more L2 experience.

Its essentially the same notion as Private VLAN’s (the community port is the root, and pvlan ports are leaves)

Roots and Leaves

Roots and Leaves

So, the idea is if the root sends a unknown unicast frame, the switch will tag it with 20 (incoming/outgoing in the diagram is from the switch port’s perspective).  20 can be accepted at the other root, and each of the leafs, so this frame will be flooded at all ports.

If a leaf sends an unknown unicast frame, the switch will tag it with 10.  The switch is configured to send VLAN 10 ONLY to the root ports, so this frame will be flooded at the two ROOT ports, and NOT the leaf ports.

The same principle applies to how we do this using VPLS on the Junipers.  The difference is we’re using the VRF-target to control what traffic is being sent to.  Using the same ID’s for the diagram above, for VPLS with a single root we’d do:

routing-instances Acme {
// Root
export target:11427:10;
// Leaf
import target:11427:20;
}

With multiple roots, it gets a little more complex if you want roots to speak to one another:

policy-options {
//first we define a policy that will bgp tag traffic leaving the root
policy-statement CUST-Acme_EXPORT {
term 1 {
from protocol bgp;
then {
community add CUST-Acme_Roots;
}
}
term 2 {
then reject;
}
then accept;
}
//next a policy that matches traffic from the other root and leaves (for a leaf site, we’d remove the ‘Leafs’ community here)
policy-statement CUST-Acme_IMPORT {
term 1 {
from {
protocol bgp;
community [ CUST-Acme_Leafs CUST-Acme_Roots ];
}
}

}
community CUST_Acme_Roots members 123:10;
community CUST_Acme_Leafs members 123:20;
}
routing-instances Acme {
instance-type vpls;
interface ge-0/0/0.200
no-local-switching;
vrf-import CUST-Acme_IMPORT;
vrf-export CUST-Acme_EXPORT;
protocols {
vpls {
vpls-id 1234;
}
}
}

All, very fun stuff and very flexible.

Philosophy

Well, this notion of ‘blogging’ isn’t unfamiliar to me, but I’m certainly not experienced with it, so hang in there.  It’ll get better with time.  I intend to focus this primarily on Network Engineering, which is a topic I really love.  Coincidentally, I get paid to think about this stuff, so technically I’m a professional.  In reality though, I know that I understand a fraction of what is out there.  I hope to share my fraction in an effort to strengthen my own understanding, and I encourage you to reciprocate with ideas and knowledge you have that may compliment.

Read the rest of this entry »

Follow

Get every new post delivered to your Inbox.