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.


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


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.


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.


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 :)


# REF:

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!

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

Replace 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 or 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 host eq 1001 (hitcnt=0) 0xd0cd20cd 
  access-list inside line 8 extended permit udp host host eq 1001 (hitcnt=0) 0xf94e6d62 
  access-list inside line 8 extended permit udp host host eq 1001 (hitcnt=0) 0x0bced66c 
  access-list inside line 8 extended permit udp host host 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 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 is IMHO the best; the reason I’m not using 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

Chrome Screenshot of

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 and, 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:


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: If you have any suggestions or improvements, feel free to fork or create an issue on github.

No Comment 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


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.


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

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 in a text-editor and edit line 21 and replace http://replace*me/ with your website, e.g.:

origin = "" 

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… 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.:


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. & Wget

Ever since cisco updated their website (you know like, a year ago), I’ve struggled to find a way to wget software onto a box.

This week, I found a bodge using firefox. Sign into and go through the normal process, accepting agreements and begin the download.

Once the download starts, pause it… right click and copy the download link:

Copy link from downloads

Copy link from downloads

Then from your terminal/linux box, you can paste the url into wget:

wget -O ise- ""

- Quick gotcha alert, the link you paste must be in speachmarks/double quotes or the full url will not paste correctly.

OS X: anonymous ftp directory on Mountain Lion

Pretty much every google search I tried landed me on a mountain lion server page, given I’m using normal mountain lion on a macbook the results were not much use!

I use FTP to transfer images to various appliances, firewalls, proxies etc so for speed and simplicity I need anonymous ftp. The default home directory on 10.8 for anonymous FTP is /var/empty which is a special directory which I didn’t want to tamper with, once I found the right stuff in the man page changing the home of thr anonymous FTP user wasn’t actually that hard…

To get started, in case you need it, the command to start the FTP service is:

sudo launchctl load /System/Library/LaunchDaemons/ftp.plist

and to stop:

sudo launchctl unload /System/Library/LaunchDaemons/ftp.plist

The config file is /etc/ftpd.conf, mine looks like this:

# match umask from Mac OS X Server ftpd
umask all 022
chroot GUEST /Users/linickx/ftp
modify guest off
umask  guest 0707
upload guest on

As you can see, I have changed the home directory of my anonymous user to a folder called ftp inside my home directory.

Now, there’s some special security stuff you can do to that folder, see man ftpd for full details, but this should do you as a minimun

~ftp Make the home directory owned by “root” and unwritable by anyone.

~ftp/pub This directory and the subdirectories beneath it should be owned by the users and groups responsible for placing files in them, and be writable only by them (mode
755 or 775). They should not be owned or writable by ftp or its group.

~ftp/incoming This directory is where anonymous users place files they upload. The owners should be the user “ftp” and an appropriate group. Members of this group will be
the only users with access to these files after they have been uploaded; these should be people who know how to deal with them appropriately. If you wish anony-
mous FTP users to be able to see the names of the files in this directory the permissions should be 770, otherwise they should be 370.

The following ftpd.conf(5) directives should be used:
modify guest off
umask guest 0707
upload guest on

This will result in anonymous users being able to upload files to this directory, but they will not be able to download them, delete them, or overwrite them, due
to the umask and disabling of the commands mentioned above.

Happy FTP Everyone!

wireshark xquartz osx (mountain lion) – crash on start

If (like me) you have just installed wireshark and and xquartz at the same time you’ll notice that after completing both installations wireshark will crash and not start up properly.

The wireshark forum shows that if you run wireshark from the command line you get this error..

(process:1234): Gtk-WARNING **: Locale not supported by C library.
    Using the fallback 'C' locale.

(wireshark-bin:1234): Gtk-WARNING **: cannot open display:

… for which there are a couple of work arounds, such as setting your display variable or opening wireshark from within an xquartz terminal window.

The actual fix was found here, notice the log out after installing… by simply logging out and back in again my wireshark now loads without any nasty work arounds.

Hope that helps!

OS X: Mediatomb (luanchd) .plist file for automatic start up.

Inspired by this, but better ;)

So now I have got mediatomb working, I’ve started on my own StartupItem so that it loads at boot time. The reason it is better is because you can start and stop mediatomb via launchctl.

I saved the below (the more) as /Library/LaunchDaemons/com.linickx.mediatomb.plist.

To start:

sudo launchctl load /Library/LaunchDaemons/com.linickx.mediatomb.plist

To stop:

sudo launchctl unload /Library/LaunchDaemons/com.linickx.mediatomb.plist

Happy Days!

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "">
<plist version="1.0">
	<string>Run MediaTomb at boot</string>