SPAM from China

I just wanted to let you know that I am aware that some botnet is attempting to use my domain name for SPAM.

humble_pie

LINICKX.com (& .co.uk) are both configured with SPF, DKIM and have valid DMARC records.

As you can see from my dmarcian report, I am requesting that all SMTP/Mail servers reject any message which has not authenticated itself, if you are receiving mail, please update your server to respect this.

I have attempted to contact the owners of the addresses sending the SPAM, according to dmarcian they are all in china… I even used google translate to translate the mail ;)

spam_from_china

Unfortunately the mailboxes for the abuse email addresses are bouncing (probably full) and are rejecting mail.

If you think I’ve missed something, and you have any advise feel free to use my contact page.

OSX Automator and Python – for mac address conversion

Recently I wrote a python script for converting mac addresses (which you can download from github) and the reason I wrote it is because I receive emails like this…

email_with_mac

The background is, I’m working on an 802.1x project, I need to find the printer, the quickest solution in this case is to look in the ARP cache of the router/switch on site.

The irritant is that in the email the MAC is in EUI format, but routers/switches are in Cisco’s. To Further irritate, Cisco ISE and ACS use EUI format so if someone sends you a MAC address from a switch or their windows machine then you need to convert it, I’ve spent a lot of time replacing dots and dashes :D

Today, I realised that I could use Apple’s Automator to grab text from somewhere… I could then parse it through my python scripts and have the results in my clip board… ready for pasting!

Below is my automator workflow

Automator_-_Convert_to_EUI_MAC

In the python field you can’t see the full text… paste in this…

import sys

addr=str(sys.argv[1])

if "." in addr:
	delimiter = "."
elif ":" in addr:
	delimiter = ":"
elif "-" in addr:
	delimiter = "-"

# Eliminate the delimiter
m = addr.replace(delimiter, "")

# Normalise Case
m = m.lower()
u = m.upper()

eui= ":".join(["%s%s" % (m[i], m[i+1]) for i in range(0,12,2)])

print eui

If you’ve having issues creating a new automator service from the screenshot I have uploaded my Convert to EUI MAC.workflow save it to ~/Library/Services

Once you’re all setup, you’ll be able to right click any mac address and convert it. I’ve also created a Convert to Cisco MAC.workflow if you need it in router/switch format.

Installing Paramiko (Python and PIP) on Windows

Following the release of crassh; the 1st FAQ was, great how do I make this work on windows?

Steps as follows:

  1. Download and install Visual Studio C++ 2008 Express Edition
    (do not install SQL)
  2. Install Python 2.7.8 – Select the correct MSI for your architecture
  3. Download get-pip.py (Don’t use Internet Explorer it will mangle the file; use Firefox to download.)
  4. Open an Administrator command prompt and run “c:\Python27\python.exe get-pip.py
  5. From the same admin prompt, run “C:\Program Files\Microsoft Visual Studio 9.0\Common7\Tools\vsvars32.bat” (for 32bit machines… or for 64bit machines, run “C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\Tools\vsvars64.bat
  6. )

  7. From the same admin prompt, run “c:\Python27\Scripts\pip install paramiko

And you’re done!

#REF: http://stackoverflow.com/questions/2817869/error-unable-to-find-vcvarsall-bat

Automating Cisco commands with C.R.A.SSH

This is my first python project; the goal was simple replace manual labour with ones and zeros… in this case write a tool which can run multiple commands on multiple switches/routers.

I’ve called the tool Cisco Remote Automation via SSH, or C.R.A.SSH for short. The name is in homage to S.H.I.E.L.D because I really wanted the name to sound like “crash” as a way of reminding users that if you are not careful this script is a car-crash-waiting-to-happen!

The script on github: https://github.com/linickx/crassh. To use it, you’ll need python with paramiko installed.

Usage can be simple, ./crassh.py (not forgetting to chmod 755 first!) and this prompt you to execute one command on a switch.

nick@linickx:~$ ./crassh.py -p
Enter the switch to connect to: 192.168.1.72
The switch command you want to run: show ver
Enter your username: nb
Enter your password:
Connecting to 192.168.1.72 ... 
192.168.1.72: Running show ver
show ver
Cisco IOS Software, C2960S Software (C2960S-UNIVERSALK9-M), Version 12.2(55)SE7, RELEASE SOFTWARE (fc1)

<CUT by Nick for breivity>

Configuration register is 0xF

SW01#
Switch 192.168.1.72 done


 ********************************** 
   Output files:
     - SW01-140808-010101.txt
 Script FINISHED ! 
 ********************************** 
nick@linickx:~$

The real power of the script is with the -s and -c options which allow you to work on multiple switches running multiple commands respectively.

A simple example is to automate configuring an interface description… create a text file called testconfig.txt with the following contents

show run int g1/9
conf t
interface GigabitEthernet1/9
description *** UNUSED ***
exit
exit
show run int g1/9

Then, run the command with the -c option (the -p option prints the file instead of writing to a file). e.g.

./crassh.py -c testconfig.txt -p

Here is the output.

[nick@linickx temp]$ ./crassh.py -c testconfig.txt -p
Enter the switch to connect to: Switch
Enter your username: nb
Enter your password:
Connecting to Switch ... 
Switch: Running show run int g1/9
show run int g1/9
Building configuration...

Current configuration : 174 bytes
!
interface GigabitEthernet1/9
 description ***** UNUSED *****
 switchport
 switchport access vlan 999
 no logging event link-status
 shutdown
 spanning-tree guard root
end

Switch#
Switch: Running conf t
conf t
Enter configuration commands, one per line.  End with CNTL/Z.
Switch(config)#
Switch: Running interface GigabitEthernet1/9
interface GigabitEthernet1/9
Switch(config-if)#
Switch: Running description *** UNUSED ***
description *** UNUSED ***
Switch(config-if)#
Switch: Running exit
exit
Switch(config)#
Switch: Running exit
exit
Switch#
Switch: Running show run int g1/9
show run int g1/9
Building configuration...

Current configuration : 170 bytes
!
interface GigabitEthernet1/9
 description *** UNUSED ***
 switchport
 switchport access vlan 999
 no logging event link-status
 shutdown
 spanning-tree guard root
end

Switch#
Switch Switch done


 ********************************** 
 Script FINISHED ! 
 ********************************** 
[nick@linickx temp]$ 

Now, if you create a text file with a list of switches in it, called myswitches.txt like:

192.168.1.72
coreswitch.domain.local
accessswitch1.domain.local

And run:

./crassh.py -c testconfig.txt -s myswitches.txt -p

The you’ll configure the description of G1/9 the same on all three switches!

I think now you’re probably getting the idea, crassh can be used to deploy a standard config to switches, or run the same show command to gather information, show authentication sessions | inc VOICE to find dot1x authenticated ip-phones anyone?

Cisco ISE is a Web Server!

When deploying BYOD instructions and error messages to end users are key to user satisfaction. The the overhead and additional complexity of a dedicated web server might not be appropriate for your team/security/design.

If you happen to be running Cisco’s ISE as your authentication server then you can use that to host your pages!

The implementation is quite simple, to get started create a new custom portal.. but take care on the name you choose as you’ll need it later; in the picture below mine is called CustomErrorPage.

General

Next upload your files, notice how my screenshot has a bootstrap CSS file. You need to upload all the HTML/CSS/JS/images/etc.

upload

The final step is to configure the file mappings. You want them all to point to your index.html, that way no matter what the user tries they always get the same response.

filemappings

Save your work (hit submit!) and you’re done.

Now your page can be found at http://ise.ip.addrdess/guestportal/portals/CustomErrorPage/index.html

(Change CustomErrorPage if you called yours something different)

Below is what mine looks like.

Ooops__Something_Went_Wrong_

You can then use AuthZ results to redirect people to the page in question :)

Python and MAC addresses

In the last few days I’ve started to learn python and gone a bit python mad with it, as a result I have a bunch of test scripts where I have been learning to do stuff. This is one of my first ones, basically I’ve taken this guy craig‘s normalisation technique and used to to create outputs.

The basic premise is you can input a MAC address in any of the three formats (EUI, Microsoft, Cisco) and it will spit out the mac address in all three… simplifying copy/paste if you have given MACs in one format and need another :)

#!/usr/bin/python

# My Post: http://www.linickx.com/3970/python-and-mac-addresses

# REF: http://craigbalfour.blogspot.co.uk/2008/10/normalizing-mac-address-string.html
# REF http://www.cyberciti.biz/faq/python-command-line-arguments-argv-example/

# Lib
import sys, getopt

# Function

def printhelp():
  print("Usage: %s -m MAC " % sys.argv[0])
  print("\n MAC can be in any of the following formats: ")
  print(" - 00:00:00:00:00:00")
  print(" - 00-00-00-00-00-00")
  print(" - 0000.0000.0000")
  print("\n Version %s" % version)

# Defaults

addr=""
version="1.01"

# CLI input
try:
    myopts, args = getopt.getopt(sys.argv[1:],"m:h")
except getopt.GetoptError as e:
    print (str(e))
    printhelp()
    sys.exit(2)

# o == option
# a == argument passed to the o

for o, a in myopts:
    if o == '-m':
        addr=a
    if o == '-h':
        printhelp()
        sys.exit()

if addr == "":
  addr = raw_input("Enter the MAC address: ")

# Determine which delimiter style out input is using
if "." in addr:
  delimiter = "."
elif ":" in addr:
  delimiter = ":"
elif "-" in addr:
  delimiter = "-"

# Eliminate the delimiter
m = addr.replace(delimiter, "")

m = m.lower()
u = m.upper()

# convert!
cisco= ".".join(["%s%s%s%s" % (m[i], m[i+1], m[i+2], m[i+3]) for i in range(0,12,4)])
eui= ":".join(["%s%s" % (m[i], m[i+1]) for i in range(0,12,2)])
ms= "-".join(["%s%s" % (u[i], u[i+1]) for i in range(0,12,2)])

print "Cisco: " + cisco
print "EUI: " + eui
print "Microsoft: " + ms

… I’m sure there will be more of these to come!

UPDATE: I’ve created a gist for convertmac.py. The code above has been modified to support a command line argument… like so…

linickx:~ nick$ ./convertmac.py -m 11:22:33:11:33:11
Cisco: 1122.3311.3311
EUI: 11:22:33:11:33:11
Microsoft: 11-22-33-11-33-11
linickx:~ nick$ 

Cisco ASA SYSLOG config for Tufin SecureTrack

I’m sure there’s a very good reason that the Tufin Secure Track User Guide (R14-1) has 8 pages of screenshots instead of including these 10 lines of config; I just don’t yet know what the reason is :)

logging enable
logging timestamp
logging facility 23
logging message 111008 level  notifications
logging device-id  hostname 
logging list securetrack message 111008
logging list securetrack message 106100
logging list securetrack message 106023
logging trap securetrack
logging host inside 1.2.3.4

Replace 1.2.3.4 with the IP address of your ST server.

Cisco ASA – inc – regex examples

I use stuff like show run | inc abc all the time but I’ve never really dabbled with plumbing regex through it, I played a little today. Here’s a couple of examples you might find useful:

Look for either https or www in an access-list

FW01/pri/act# show run access-list inside | inc (https|www) 
access-list inside extended permit tcp object inside any4 eq www 
access-list inside extended permit tcp object inside any4 eq https 

Look for either 10.10.1.91 or 10.10.1.92 in an access-list

FW01/pri/act# show access-list inside | inc 10.10.1.(91|92)
  access-list inside line 8 extended permit udp host 10.10.1.91 host 10.1.2.199 eq 1001 (hitcnt=0) 0xd0cd20cd 
  access-list inside line 8 extended permit udp host 10.10.1.91 host 10.1.2.200 eq 1001 (hitcnt=0) 0xf94e6d62 
  access-list inside line 8 extended permit udp host 10.10.1.92 host 10.1.2.199 eq 1001 (hitcnt=0) 0x0bced66c 
  access-list inside line 8 extended permit udp host 10.10.1.92 host 10.1.2.200 eq 1001 (hitcnt=0) 0x9ceae405 

There’s loads that can be done, google is your friend.

The LINICKX clock – power by jquery, css3 and Google App Engine

It’s been a long time since my last weekend project, over on git hub I have just published the code for my LINICKX Clock.

n800 linickx clock

Photo of my n800 running clock.linickx.co.uk in full screen

I have an old Nokia n800 which I wanted to put to some use. If you want a good time service then time.is is IMHO the best; the reason I’m not using time.is/just on my n800 is that it’s very boring! I wanted to create something that would change, add a little bit of variety – regardless on your opinion on if LCD screen-burn exists or not.

LINICKX Clock is powered by Google’s App Engine (GAE), which means that occasionally it will sleep, however I’ve been running the clock for a few days now an it’s updating fine.

The background, font, text-area and clock delimiters change every 15mins so if you want to see something unique to you then you’ll have to be patient!

Chrome Screenshot of clock.linickx.co.uk

Chrome Screenshot of clock.linickx.co.uk

The clock uses from very simply jquery to download a JSON file from the server, the JSON response updates the style sheet for the page. Some of the clock features are CSS3, such as the blinking delimiter and scaling background so browser milage may vary. The background images are powered by Subtlepatterns.com and SimpleDesktops.com, I’m caching the images on the GAE to reduce the impact to the upstream provider (hopefully they don’t mind!).

You can easily run your own if you want, the simplest method would be to deploy your own app into google, i.e. create a new app, change the application “name” in app.yaml and deploy. If you want to run this locally then you’ll need php (and memcached for caching), you’ll also need to rewrite the permalinks, for example on line 96 of index.php:

$.getJSON('/rd').success(function(data){ 

The random data is a http request to /rd unless you use something like mod_rewrite then you will need to change this to /rd.php

The source code can be found here: github.com/linickx/clock. If you have any suggestions or improvements, feel free to fork or create an issue on github.

No Comment

Linickx.com has been using comments on WordPress for over 5 years now and over that time the quality and quantity of comments has varied. In the last six+ months comments have become mostly spam. To reduce the amount of outages caused by spam, scrapers and other internet-rubbish the comment forms and previous comments have been removed.

Intelligent humans are still able to use twitter or the contact form to get in touch :)

Using bootstrap on Cisco ISE

ISE 1.1 had horrible web portals which didn’t render well on mobile devices at all (which was odd for a BYOD solution), anyway, Cisco have fixed that now in 1.2 with the ability to enable a mobile version… but what if you want something totally custom that works well both on desktops and mobile?

Enter bootstrap!

The trick to getting this working is know the correct paths for the stylesheets so to make things easy I have created a gitgub project called ise-bootstrap. To get started create a custom portal with the name myportal and upload the files. Change your authz result to point an the new file and enjoy the responsive goodness!

Here are some 1.1 screenshots of me creating the portal, the process is pretty similar in 1.2 – I will upload some newer screenshots at some point!

The only gotcha to be aware of are the Glyphicons, if you want to use those then you need to customise the bootstrap download so that it matches the name of your portal.

This is the end result…

ISE 1.1 07 example login page

If you get stuck, there is a README which compliments this blog post.

Using Google as a FREE origin pull CDN

There are bucket load of posts on how to use google application engine (GAE) as a CDN but many of them direct you to hosting static content on a google server. For me that approach isn’t practical, every time I did a WordPress update or plugin upgrade I would have to push an update to GAE… annoying!

Origin-Pull is the future then, basically the server acting as a CDN pulls a copy of the original, caches it and serves that to clients. Updates on the main site are easy, just wait for the CDN to age out it’s cache or if you are impatient manually purge.

Over the weekend I stumpbled upon SymPullCDN a GAE app, it’s a bit out of date so I’ve pushed a newer version to github. I’ve made two changes, firstly updated to python2.7 (as per google’s recommendation) and secondly I’ve added a cron job to keep your GAE app snappy :)

Setting up your own copy is simple, start by signing up for GAE and create a new “application”, mine’s called mygaecdn

create_gae

Next get a copy of the Google App Engine SDK for Python also known as GoogleAppEngineLauncher… Install it :)

Once it’s running, create a new application… give it the same name as the app you created on google.

new_gae_app

Take a note of the directory in which the application is being created, mine is Users/nick/Documents/GoogleAppEngine/mygaecdn

Next download this zip file which has the updated SymPullCDN files.

Delete everything from your Users/nick/Documents/GoogleAppEngine/mygaecdn and place in there the contents of SymPullCDN-master.zip

Open app.yaml in a text-editor and edit line 1 to replace *replace*me* with your application name, e.g.:

application: mygaecdn

Next open main.py in a text-editor and edit line 21 and replace http://replace*me/ with your website, e.g.:

origin = "http://www.linickx.com/" 

Make sure you save both files and you are done!

Now, test locally in the GoogleAppEngineLauncher app before deploying to google. Click the green “play” and a GAE application will run on your local machine; from the screenshot above you can see mine is listening on “port 10080″, so I can open a web browser to http://localhost:10080 – all things being equal you will see a copy of your website :)

If that works you’re ready to deploy…. hit the blue “deploy” button to push you app up to google. When that’s finished you should be able to visit mygaecdn.appspot.com… obviously yours isn’t called mygaecdn!

Once the deploy is finished you have a GAE ready and willing to serve cached copies of your site.

What you do next will depend on your website. Me, I use WordPress and wp-super-cache, so I can simply enable the CDN feature in that, e.g.:

wp_wp-s-c_cdn

You might have to install something, or change some URLs, whatever you do, just remember to only change links to static content such as CSS, JS or IMG – anything dynamic is likely to end in a world of pain.

FOOTNOTE: The term CDN is used loosely in this blog post, GAE is more of a content off-load, IMHO a CDN should server you geographically-local content but in all my tests on webpagetest showed all my content coming from Google-USA, not that is really a problem as their servers are still rocket-quick :cool:

OS X: Sync’ing keychains in the iCloud

Keychains hold passwords, certificates and general secret stuff – only do this if you understand the Apple will have access to this…. well assuming they can crack your keychain password (which they probably can).

Synchronising a keychain across macs could be useful, for example, having a dedicated keychain for WiFi credentials.

I stumbled across this link (dated Nov 2011) and found that this still works!

The ~Library/Mobile Documents/ folder is pushed to all iCloud enabled computers, so I have created a new folder, and copied my WiFi keychain into it:

$ mkdir ~/Library/Mobile\ Documents/com~linickx~icloud
$ cp ~/Library/Keychains/wifi.keychain ~/Library/Mobile\ Documents/com~linickx~icloud/

If you only have one keychain login.keychain, consider splitting out the really secret stuff and only sync’ing the stuff you want to share with apple.

Now open “Keychain Access”, delete the original keychain and add/open the iCloud copy. On any other Mac, add/open the iCloud keychain. Once complete, any change to the keychain will be pushed to all Macs, simplifying password changes :)

I’m also using this to sync dotfiles!

You could use dropbox for this, one reason to use dropbox is that iCloud sync seems to be a bit hit n miss; however Dropbox already have enough of my secrets, I’m not suggesting that iCloud is more secure, it’s just better to have many baskets.

FOOTNOTE: If your mobile documents folder isn’t sync’ing, see this post by SteveX.