Making Your WordPress Site Harder to Break Into

If you are using an infrastructure-as-a-service offering to host your WordPress site, you might find the following suggestions useful. If you have web access to site administration, e.g., via CPanel, there’s not much more you can do beyond:

  • Install WordFence.
  • Pick a very long password for your admin account. Have a look at secondary authentication options [described below].
  • Keep your software up to date.
  • Have a long hard look at all of those plugins you’re using, and try to cut them to the bone.

Here are a few Linux specific things to consider:

  • Install fail2ban.
  • Install the fail2ban WordPress plugin.
  • Change the default port you are running sshd on from 22 to something above 1024. You might want to check the IANA port listing to avoid colliding with other daemons you may be running on your box. This is pretty painless to do. You could do the same for all of your other network services [obviously excluding your web site and mail transfer agent, if you’re using one].
  • Consider running TCP wrappers on your ssh daemon access. Be careful not to lock yourself out if you don’t have a fixed IP address from your service provider. I use BT: a bit of googling suggested a couple of likely address ranges [81. and 86.], but my get out of jail card is a static IP I can use with a VPN service, which I’ve also configured.
  • Consider restricting access to mysqld to localhost. You may have already done this during install. I have to admit I was pretty careless when I was installing the database in terms of notetaking so I just added a TCP wrapper to be on the safe side.
  • Have an extremely long password for your admin account. Mine is basically half a mile long in 8 point text.
  • Have a look at some secondary authentication [or at least Captcha style robot identification] mechanism on the login form. I’ve experimented with Duo in the past. Make sure you understand the implications of changing your mobile phone if you are using one of the app based mechanisms.
  • Consider chrooting your website. I don’t but I may.
  • Have a look at some of the security scanners, like ZAP. Again, be careful not to lock yourself out with fail2ban.

The rest of these are host specific. A good starting point is to run

nmap -n localhost

to confirm what network services you are running. For instance, I found that my Linux distro had an FTP server running out of the box which I didn’t know about. In my case it was as simple as

pgrep ftp

to get the process id, then

ps -ef | grep <process_number>

[substituting appropriately] to find what the process was, and then finally

apt-get remove <package_name>

For any other servers you need to run, there’s a pretty good chance that there is fail2ban config that you can use off the shelf.

Why I felt I needed to pay more attention…

A few months ago, based on the daily activity reports I get from WordFence, I started blocking ranges of addresses using iptables. So if I got repeated brute force attempt on my admin password from say 192.187.111.146 [this is a real example], I’d block the the entire range by doing:

iptables -A INPUT -s 192.187.0.0/16 -j DROP

This was pretty tedious, but I only needed to do it around once a week. For some reason [presumably it’s some sort of off the shelf attack script], the attack counts from specific IPs always seemed to top out at exactly 1460 hits. Last week, I got my daily email which showed someone had hit the site 49k times that day. By the time I got home and did some digging in the logs, it was totalling more than 80k for the week. I suddenly realised that my manual blocking was way too blunt a tool, so last weekend I wrote a log scanning  script launched by cron every 30 minutes. It pattern matches on the login form in the Apache log file and sends me an email if an individual IP tops out at over a certain threshold. The longer term plan was that I’d call another script that would automatically insert the block rule in iptables. There would be a bit of messing around with state management [seek to a point in the log file based on the timestamp to not go over the same ground twice or something] and it would have to be run as root, but it would be better than nothing. I happened to mention this to someone at work who told me about fail2ban, which is doing the same thing [but better than I could have implemented it].

I also had a dig around at ssh logs, and discovered that some kind soul was trying to brute force the root password, and was up to 8k attempts for the week. Subsequent digging showed that the same thing was happening with my Imap server, but on a smaller scale.

While what I’ve suggested here isn’t necessarily bullet proof, it’s a reasonable start. Bear in mind that the types of attacks I’m seeing are commensurate with the value of my site, which in commercial terms is zero. And oh, the irony, when my server gets brought to its knees next week by someone with serious intent :).

Pin Your Pics…

My year and a bit dalliance with Android concluded as of yesterday, when I took delivery of an iPhone 8. I’m going to start developing again [although I’m going to have to divide my attention with C#, which I’m learning at work].

I’ll need to dust down a couple of projects: I have a password manager which I wrote as an experiment to learn about the Touch ID back in the day. I also really need to update my apps on the App Store…

…All of which leads me in a round about way to Pin Your Pics. It’s had very modest downloads since I released it: very low hundreds. That was up until July of this year, when it appears to have been ‘discovered’ in some way. I’ve no idea why or how. Anyway, this is what the downloads look like for this month which, by comparison to before, is pretty interesting:

Downloads for Pin Your Pics

I’m sure there’s every chance that it will sink without trace again.

Regardless, at some point in the next few weeks I’ll have a look at screen resolution – when I wrote it, it was fixed to the 5S screen dimensions, I think. Also, there’s a perennial bug with the controller for launching the camera, which I’ll have another bash at.

Madagascar: Walking Flowers. Who Knew?

I guess when The Beeb and Attenborough have made a series about a country, it’s a pretty safe bet that it’s going to be a humdinger of a place to visit. We got back from Madagascar on Friday afternoon, our tenth outing with the same company we’ve been using for all our long haul travel. I’ll cut to the chase: it was fabulous.

By the numbers:

  • Photos taken 1466 [me] and 683 [my wife]
  • Of which, keepers: lots. Seriously, if you can’t manage to get memorable pictures in Madagascar, it’s time to give up.
  • Kilometres covered by car: 1500.
  • Species of lemurs seen: 14.
  • Weight lost through illness: about 2kg.

I’ll start with that last point. Clearly, I upset some pagan poo gods by judging the phantom shitter on our Belize trip so harshly. I had the most sustained period of travel sickness that I’ve experienced to date. I only missed a day, but was under the weather from the third day and for about a week. My wife came down with it as well, but didn’t have it for quite as long as me. I jokingly put her stronger constitution down to her less literal enforcement of food best-before dates than me.

There were a couple of options for getting to Antananarivo [which, sympathetic to the world shortage in letter Ns, everyone calls Tana] but we ended up going via Paris. We had an overnight stay in a hotel about 10 minutes drive from the airport. The airport itself is pretty hectic: be prepared for enterprising ‘porters’ to descend on you and try to grab your luggage out of your hands – probably before you have any cash. While I think of it: there isn’t a great selection in duty free if you’re looking to get something last minute on the way back. It’s a similar sort of fare that you see in hotel shops. Oh, and if you’re transiting, be prepared to pay extra for a plastic bag that they staple shut for you – something I’d never come across before. As the 1 Euro represented 12% of the cost of the bottle of rum I was thinking about getting, I decided to skip.
Back to the itinerary. The next day we had two consecutive flights on the same plane – another first for us. First stop was Taolagnaro, and then we went straight on to Tulear, which is in the far south west corner of the country. We’d been warned by the travel company that there was a reasonable chance that our bags wouldn’t make the trip with us into Tana, and then that the internal flights might be rescheduled at short notice. Everything went really smoothly – in fact, the same could be said for the entire holiday. Every long haul trip we’ve had something has gone wrong. This was the first that the entire itinerary worked as planned.
We met our driver and guide for the rest of the holiday at Tulear [Yves and La La] who drove us to our next accommodation, called the Hotel Bakuba. It was a lovely place, something of an ongoing art project for the guy who runs it. That said, some of the features had practicality a little lower down the running order. Our room had a sunken seating area with a glass table in it, which I don’t think was really catering for the guest who might decide that a dozen postprandial Jager bombs are a good idea. It immediately made me think of this.

Mantrap

There was also a table with wildly splayed legs that we both stubbed our toes on every time we walked past it.

Fancy bed

It was undeniably top drawer accommodation but I couldn’t quite shake the sort of vibe you get in a bed and breakfast, because the couple who run it live there: you half-feel like you’re intruding when they are having dinner.
During our two night stay there we had a couple of outings, first to a spot called the Antsokay Arboretum, which was right next to the hotel, and then the Reniala forest. The Arboretum was an interesting enough hour but is really more for the gardening geek. Reniala gets you up close and personal to baobabs, which are fascinating.

baobab

From Tulear, we transferred to Isalo, and our next hotel, the Relais de la Reine, where we stayed for 3 nights. This, again, was pretty fancy: just the way the itinerary played out we had a gradual decrease in snazziness of accommodation.
It was in the Isalo national park that we had our first encounter with lemurs, specifically this little fella:

Hubbard’s  sportive lemur

Isalo is also one of your best chances to see sifakas doing their hoppity run along the ground – which brings me to another point. Travelling as we did at the start of July meant that we were right at the start of ‘shoulder season’ [which I’d never heard of before this trip]. It’s mid winter, so the animals are less active than pretty much any other time of the year. However, it also meant that the numbers of tourists around were very low. Probably the busiest of the parks that we went to was Ranomafana, where sightings are co-ordinated among the spotters and guides and so groups of people will coalesce when something interesting happens. I guess at one point we were up to about 15. Our guide said that during the high season, people are tripping over one another. We were told that the sifakas are most likely to hit the ground running in September to October but, given the propensity for the same ground to be covered with people, you’re extremely unlikely to see it.

Sifaka

The little bundle under this mum’s elbow is an infant:

Sifaka with infant

And another common brown lemur. I can’t help but anthropomorphise about this picture, that this guy is thinking ‘oh for God’s sake, get on with it, will you?’:

Grumpy common brown lemur

And so we get on to the title of this post: the ‘walking flowers’. I’d been ill for a couple of days by this stage and wasn’t feeling like the sharpest tool in the box. Our guide pointed a plant covered in white flowers and said, ‘have a look at these’. We’d never seen anything like them before and it took a while for me to notice that they were moving:

Flower bug

I’m not entirely sure which end is which. Needless to say, you don’t get them anywhere else except Madagascar.

Ring-tailed lemur

On our last full day we did a fairly long walk in the Namazaha Valley. It was supposed to be a 10km hike but my world was still being metered out in distances between toilets so we foreshortened it to about 6km in the end. Interesting spot, and a classic example of the arid environment in this part of the country.
The stones [centre left] in this picture are covering the entrance to a grave.

Isalo

On our last evening in Isalo, I was sitting outside the room when I noticed these weird shaped motes floating in the air. Given the recent experience with the flower bugs, I assumed that they were some sort of whacky insect, until one of them landed on me and I touched it with my finger:

Slash and burn

It’s hardly the most fascinating picture but it was quite a poignant one for me: it’s a piece of ash. ‘Slash and burn’ is a common agricultural technique in the country. We were told a fire got out of control a few years ago: it affected 60% of the Isalo park and killed all but two of the sifakas. You see a lot of fires as you are driving through the countryside.

We visited one other smaller reserve before we moved on, called Zombitse. It was ok: plenty of ring-tailed lemurs and chameleons in the mix but by this stage, unless the lemurs were species we hadn’t seen before or were doing handstands, it was time to move on. Despite the name, there were no zombies.

We had a long drive to our next venue, which was the Ranomafana national park and the Setam Lodge. We passed this along the way. I love this shot, which is pretty much straight out of the camera:

The sky from the start of the Simpsons

The change in the weather over the course of the day reflected our move out of the arid region and into rainforest. We had a very interesting night walk on the first evening with the highlight being a mouse lemur:

Mouse lemur

The guide got a banana and smeared it over the branch [which is the brown slimy stuff you can see in the shot]. You then hope that the smell attracts a lemur. It took a couple of goes as the first fishing expedition attracted a rat. Being Madagascar, you half expect the rats to have, I don’t know, wings and a handlebar moustache at the very least. Nope: they have plain old rats, just like everywhere else.

Anyway, the mouse lemurs are lightning fast: they run along the branch hoovering up the banana as they go. They are ridiculously cute. These and the bamboo lemurs look like the result of a conversation between a toddler and a cartoonist.

“Bigger eyes.”

“No problem.”

This is a baby long-nosed chameleon. It’s not a great shot but the conditions were pretty difficult: macro depth of field, at night, with the 2 inch long subject on a branch that was moving…

Baby long-nosed chameleon

The next day we had our physically toughest hike, which was about 8km over very hilly ground. Just on that point, in our experience I’d say it’s second only to Borneo, in terms of the physical demands of getting around in rainforest. That said, the temperature we had last week was low- to mid 20s. If you were covering the ground that we did in Ranomafana at the height of the summer, you’d have a real slog on your hands.

Ring-tailed mongoose

Golden bamboo lemur

Flat-tailed gecko

From Ranomafana we had another long drive to our final venue, which was the Eulophiella Lodge, next to the Andasibe national park. We broke the journey with an overnight stay in a guesthouse called the Maison Tanimanga in Antsirabe. That was notable for what I rated as the best meal of the holiday.

A quick aside about the grub before I get on to Andasibe. It’s French influenced, with every place we stayed in serving baguettes and croissants for breakfast.

  • Tulear had pretty decent food, but with the odd ‘miss’: like a zebu carpaccio starter which was frozen.
  • Relais de la Reine: very rich food, with lots of creamy sauces.
  • Setam Lodge: I’ve no idea. I was in full-on emergency mode and had boiled rice and vegetables for the entirety.
  • Maison Tanimanga: fabulous home-cooked French food.
  • Eulophiella: slightly simpler fare but still very nice.

Andasibe was the coldest of the places that we stayed, with the temperature down to 11C at night. I enjoyed this park the best, I think: it was slightly easier going and there was a fantastic variety of wildlife.

Velvet amity [I think]

Indri

Diademed sifaka

Nightjar [breeding pair – sleeping]

The last place we visited of note, which was on our way back to Tana was ‘Lemur Island’. It’s basically a mini-zoo built into the grounds of one of the fancier lodges in Antsirabe. Our guide was pretty diplomatic about it: it’s a for-profit affair, and the lemurs that are kept there don’t get rotated back into the wild. That said, where else in the world are you going to have a lemur jump on your head? They have 4 species: black and white ruffed, ring-tailed, common brown and bamboo. The ruffed and common brown like to get up close and personal, and the ruffed have particularly luxuriant fur. Once again, being out of season, we had the place to ourselves.

Golden bamboo lemur

Black and white ruffed lemur, and me. I’m on the right.

So that was our fortnight in Madagascar, and it really is an extraordinary place. You’ve got to hand it to that Attenborough fella: he really knows his onions.

Belize

We got back from a fortnight in Belize on Sunday afternoon. It was, by my reckoning, the 38th country we’ve visited, on a trip we worked on with a well known UK long haul travel specialist. I say ‘we’: my wife did all the organising. I had almost no idea where I was going – this was a matter of choice, I hasten to add.

By the numbers:
– Photos taken: 580.
– Of which, keepers: 4.
– Wildlife encounters of the “you’ve got to be kidding” variety: 1.
– Arrests: 1.

A warning in advance: we had a scene play out on the way to the famous ATM Cave which was rather unsavoury, and which I can neither window dress [for reasons that will become very clear] nor skip, by virtue of being a significant talking point for a day or two for us. You might want to come back to this if you are having your lunch.

The default offering from the travel company is to fly in via Miami, which an overnight stay. That felt like a waste of time, so we asked if we could fly in via Mexico instead, as we’d be able to stay ‘air-side’ when we were transiting. This isn’t actually right, and made for a pretty tense return leg [which I’ll come back to]. Our agent also screwed up the booking and couldn’t get us on to the Cancun flight to Belize City, so we ended up having to stay in a Marriot just outside the airport anyway. This meant we’d have a pretty long drive to the Belize border on the first full day. In short, travelling via Mexico gained us nothing: if you’re thinking of travelling from the UK, just take the simple option and come in via Miami. Cancun airport is massive, and we had a chaotic 90 minute wait to get our bags. The refried beans we had at breakfast were fantastic but hardly enough to swing it.

We were dropped at the border and walked across the timezone [a first] and through passport control into Belize, sharing the queue with people who seemed to be taking little apart from vast quantities of toilet roll into the country. A short drive and boat journey later and we were at our first destination and highlight of the holiday, the Lamanai Outpost Lodge. Great food, lots of interesting things to do, great wildlife guides, and a really nice atmosphere: we couldn’t rate it highly enough. We were there for 3 nights, and had a nice mix of activities: a couple of wildlife spotting walks, a ‘village life’ tour [which involved making corn tortillas by hand. It’s pretty tough] and a standout ‘flashlight boat trip’.

As well as spotting a pretty interesting array of wildlife [including 3 metre crocodiles which, honest gov, don’t attack humans so feel free to take a dip in the river. Yeah right!], the guide used a laser pointer to talk us through various constellations. I’ve only ever seen the Milky Way as prominently once before and it was stunning: the guys turned the engine off, and left us floating in the middle of the estuary, with absolutely no visible sources of light to spoil the effect.

This little fella worked his / her way into our room, early in the morning of the second night, an encounter which had us carefully knocking out the contents of our walking boots for the rest of the trip.

Early morning visitor

We had a really nice morning looking round the Mayan temples at Lamanai. The lodge had timed it that, apart from one other couple and their guide, we had the place to ourselves.

Lamanai Mayan Ruins

If I had one minor criticism, it would be of this:

Lamanai Mayan Ruins – Big Head

…which has been plastered over to protect the original stonework from the elements. My gripe is that it wasn’t done very sympathetically.

This is the best shot of howler monkeys that I managed to get. They are tricky – by virtue of both altitude and contrast. They also sound… odd. Think Jurassic Park. I took this at the long end of my 100-400mm L, with the 1.4x extender, which meant manual focus…

Howler monkeys

…something I gave up on later in the holiday.

We woke a few times to find that it had poured overnight. This leaf, just in the garden of the Lodge, was so succulent looking I was tempted to take a bite out of it:

Yum

From Lamanai, we had a long trip [via the airport for some reason] to Black Rock Lodge. While this place has stunning reviews, and we enjoyed our 6 nights there, it didn’t quite have the same atmosphere as Lamanai: it had more of a hotel vibe. Then there were the seating arrangements: enforced nightly rotation of the cabin occupants at mixed tables. We aren’t unfriendly, and we met some interesting people but the daily procession of the same questions started to get a bit wearing. By the end of our time there, I was itching to find another IT type to speculate on why no-one was able to send emails [untested hypothesis: blocks on both the TLS and non TLS SMTP ports due to people sending bandwidth unfriendly photo attachments].

Anything but the dreaded ‘…and what do you do…?’ Me, I like to judge people from a distance, without the whole palaver of having to find out what job they do first :).

It was in a fantastic location – again on a river. There was a bird feeder that you could spend hours at:

My goodness, my Guinness!

OK, I don’t want to get too technical, but this is a green bird…

A bird. With another bird.

…which I’ve completely failed to identify. We saw a few of these over the course of the stay:

Agouti

This fella also put in an appearance on our second day:

Arizona unicorn mantis

What a fantastic name for a beastie!

We’d pre-booked a couple of trips and had the option for more, but I fell into my standard long haul holiday pattern of starting to feel off colour at the end of the first week, and had a couple of lazy days, including one where my wife went to the market at San Ignacio, which she enjoyed [possibly because she was on her own :)]. Our first big trip based out of Black Rock was to the ATM caves. It was a physically challenging, but fantastic day out. Right up until I saw the camera shaped hole in the skull of one of skeletons, I was grumbling under my breath about not being able to take my little sports camera [a GoPro wannabe, which I’ve got a waterproof enclosure for].

We had an interesting trip to the cave. We were travelling with the guide in a group of 6: a father and daughter, two women and ourselves. I was talking to one of the women who I thought was possibly drunk. Given that she was about 60, it was about 10 in the morning and we were about to ford a river, I thought she was pretty keen, but who knew, a little bit of Dutch courage might have been what she needed. We’d been walking for about 20 minutes, maybe half an hour, and were somewhere between the second and third river crossing when we noticed quite a distinctive smell. I, in my naivety, immediately thought that we might be passing near by some pecaris: our guide at Lamanai a few days before had pointed out that they have a pretty distinctive musky sort of smell. Looking back at this, I can just imagine my wife rolling her eyes at me; at the time I thought my jungle tracker super-skills had just landed. Anyway, about a minute later, we realised that the woman I thought had been drunk had suffered a spectacular sphincteral failure, and had pooed herself. Wearing shorts. In a group of people. Passing another group that happened to be heading to cave at the same time. And we’re not talking a little whoops-a-daisy squeak: there was poo running down the back of both of her legs to her feet.

It’s funny the way these scenes play out. Rather than sympathy, the group immediately regressed to the rules of the school playground. The only goal, and the one thing that was trying to jostle the smell from my brain, was the thought that we needed to cross the next river in front of her. The rest of the group was coming independently to the same conclusion and there was a not-quite-running foot race developing. Cue the Benny Hill music.

The woman cleaned herself up – probably launching an epidemic of dysentery in the otherwise crystal clear water of the river – and subsequently made it about 2/3 of the way through the cave – with no-one standing behind her at any point in time, I hasten to add.

So, as you might have guessed, my sympathy levels were pretty low. Yes, rather than drunk, she was probably medicating. But, what was she thinking? ‘I don’t feel well, but damn it, I’ve come all this way so I’m going to have a bash at this physically demanding day out.’ Or later: ‘OK, the gates have opened. Oops. I’m just going to try and brazen this bad boy out. Maybe no-one noticed’.

Really?!? I’m sorry, but either you don’t go – to the cave! – or, if it’s a super emergency, sprint off the path, drop your trollies and drop the kids. Fair enough, eye contact might be as light on the ground as waterproof toilet roll but people will understand: everyone has close shaves with the holiday trots. I remember one particularly tricky moment on my one and only diving holiday, struggling like mad to get out of a wet suit with the clock ticking down. But, back to the cave woman: to just try and walk it off? Or, if you are that ill in the first place?

Stay indoors. You know, next to the toilet.

The cave itself was, despite thoughts of poo-gate lingering over us like a green cloud, fantastic: just an absolute sensory overload of sights, swimming, sauna-like humidity and climbing. It’s not for the faint of heart.

We had another full day out to visit the ruins at Caracol. It was really good fun: a walk around the forest with the remains of houses and temples looming out of the undergrowth. We stopped off at a cave, called the Rio Frio, which was actually the highlight of the day for me.

This is an HDR exposure comprising 3 shots, bracketed around an exposure of f8, and 0.6 seconds:

Rio Frio

That was followed by the weird moment of the day: the guide set up lunch and then just switched off: not even an attempt at I-work-in-the-people-busines-so-need-to-try conversation, he just stared glassy eyed into the middle distance. Fair enough, I guess: after a few years in the job there’s probably little to distinguish one set of sweaty Europeans from another…

 

At least he didn’t shit himself.

 

This was one of the last shots I took at Caracol. It’s a bit of a daft composition but I quite like it. The ceiba trees, central to Mayan culture, are everywhere, and they are fascinating:

Ceiba tree

From Black Rock, we had another long drive down to our last destination, Placencia. It’s a quirky little town which, for me, didn’t quite add up. While we ate well and enjoyed our few days there winding down, I couldn’t quite see the draw to the location itself – bearing in mind that there was a huge amount of development work going on and our hotel was pretty swanky [the Chabel Mar]. The beach was… well, to be kind, just ok. It was a little too steep to be kid friendly, and there was a strong breeze for almost the entire time we were there, so the water was very choppy. Hardly surprisingly, we saw all of 3 people swimming in the time we were there. Thinking about the location of the town more generally, while there were plenty of day trips to be had, but they were all a long way from Placencia itself.

Brown pelican

We had a couple of stand out meals in town: Dawn’s Grill did a shrimp curry, which was my best meal of the holiday. Also worth an honourable mention was Rhum Fish where we went for my wife’s birthday. That turned out to be memorable for the wrong reasons. She hadn’t been feeling great earlier in the day – a combination of a dodgy tummy, the weather and a bad reaction to a couple of sandfly bites – but felt well enough to go out. She ended up fainting in the loo, and not being able to open the door to get out of it because her hands were sweating so badly. I was just about to go into panic mode – bearing in mind that the starters were sitting on the table – and met her coming back from the loo looking grey. She almost fainted again. The staff were fantastic: a cold, sweet drink, cold towels, cab called, food boxed up. My wife was feeling fine, and ravenous, about 30 minutes later.

We had one last mini-adventure to unfurl on the trip home. We’d arranged a pickup with the ground agent to get us to the airport a couple of hours before they had suggested, which turned out to be a good job. Our driver was stopped at a police check-point and told that his insurance had expired, which was an arrestable offence. His car would have to be impounded, he’d have a night in jail and could arrange bail for a release the next day. We were sat in the back of the car, thinking, yeah, shame, but we need to get to the airport pretty soon. The driver called his son and, after a testing 45 minutes wondering how reliable this arrangement was going to be, he appeared in a very fancy 4 wheel drive and took us to the airport at breakneck speed.

The airport at Belize City appears a little chaotic to the uninitiated: e.g., a mismatch on flight departure times between the main board and the gate, and a very strange seat allocation mechanism that seemed to involve a lot of shouting. Our flight was duly called and, when I realised there were only going to be 3 passengers, my hopes of a nice 737 started to evaporate. We were in a single engined plane for the 90 minute flight. Contrary to popular belief, it wasn’t the air pressure differential on the wing combined with thrust that was keeping the plane in level – and admittedly fairly smooth – flight, but an act of intense willpower on my behalf. I was a nervous wreck by the time we landed. My wife loved it. We landed at a small, separate terminal and, because our pilot and co-pilot accounted for exactly 40% of the people going through the place, cleared customs and immigration control in about 5 minutes. At Belize City airport, we’d arranged for a private taxi to take us to the main terminal for international flights – vastly overpriced [$35] but worth it to make sure we were in plenty of time for final leg of the journey home.

So, all in all, a very enjoyable trip. It has to be said, it was a quite expensive one. While some of that is down to currency exchange rates, it was principally because the accommodation was pretty dear. Bottom line, it was still one of the best holidays we’ve had. The people were really friendly, and the country itself has a great mixture of history, wildlife and beaches to offer.

Thoroughly recommended.

Photography Footnotes

I took my tripod but not my 16-35mm lens, which was a mistake. There are plenty of opportunities for taking shots of the Milky Way [something I’d never tried before], and missing a wide shot of the Rio Frio cave was a bit of a shame.

It’s also worth taking a shutter remote. I had a half-pissed brainwave to improvise by putting the camera on the B setting, and using the off/on to trigger the shutter by holding the shutter release button down by using a Neurofen and about 10 Band Aids [cue my wife rolling her eyes again.] It nearly worked, but I got a bit of movement in the camera body when I turned it on and off – a combination of a beer-induced unsteady hand, and setting the tripod up on less than solid ground.

Best of a bad lot, this was a 111 second exposure [I had a Band Aid failure which closed the shutter] at f4 and ISO 800. I also bounced the flash around the foreground. Going to f2.8 and wide on the 16-35mm would have just made the difference:

Stars – don’t look too closely…

Creating an Alexa Custom Skill on a Web Service

The short version: there is no short version. Implementing server side functionality inevitably involves a fair amount of legwork. Also, an advance warning: I’m a novice at the programming language I chose to implement my web service in – Java. For this reason, I’m only going to post code snippets for problems you need to solve. There may be better ways of doing this. Finally, I’m leaving my Skill permanently in development mode: I don’t intend to publish. While it’s something I find useful, this was primarily a learning exercise for me. If you’ve ended up here via Google, hopefully you’ll find something you can re-purpose.

I’ll come to the Amazon side of things in a bit. First up, you will need a server to host your web service. You have a couple of options here [as an alternative to Lambda]: first, you can host on your home network. If you have DHCP, the typical process is to configure your broadband router for DDNS, and have a port forwarding rule on to your server. I decided to take another approach, simply because I wanted to try it out. I’ve paid for a vm with a hosting outfit called OVH. They have a really nice setup, so I’ve spent less than £10 for a server for 3 months. I’ll probably keep it on permanently as I like the flexibility.

I decided to implement my web service as a servlet. There are plenty of tutorials on how to set up the stub methods [and all the various libraries and files structures you will need when you come to export a War file]. I used Eclipse as my IDE. My testing cycle – which I imagine is pretty common – was to run tomcat on my laptop where I was doing the development. I could then build and deploy to that locally, and then test the interface by POSTing data to it with the Chrome plugin Postman. When I had something I wanted to deploy to my vm, I exported the WAR file, scp’ed it to the OVH server’s web apps directory, removed the old War [and expanded directory] and restarted.

A couple of foundational steps on the remote server. The OVH setup is a vanilla install of your operating system of choice – I went with Debian. As well as installing your server software [tomcat] and its requirements [Java], you’ll need to create a user for it. As Amazon requires the server to run on a privileged port, you’ll need to take this into account. As you really won’t want to run the server as root, I googled around for a snippet of C code which I could adapt and compile, which could use setuid to start my server as another user. This is something to take care over if you intend to run your service in anger, and you have no choice: you have got to run your service on port 443.

The next step on the server side, related to that privileged port, is TLS. Because I tried a ‘real’ CA, which I thought was on Amazon’s supported list [Let’s Encrypt], I also went to the trouble of registering a name for my vm’s IP. If you’re going to stay in developer mode, you may not need to do this. When I realised I was getting TLS handshake errors, I changed the config and went with an openssl self-signed certificate.

Turning to the configuration set up on the Amazon side, it’s generally pretty well documented, but there are a couple of exceptions to this. First, in the Skill Information, you have to provide an Invocation Name. I know of one other developer who made the same mistake as me because of the way the debugging pop-up information is worded: I assumed that the invocation string needed to start with ‘ask’, or equivalent. It doesn’t. If you just want your skill to be invoked with ‘widget counter’, you just have those two words, and then kick it off on your Echo with ‘Alexa, ask widget counter’, followed by one of your sample utterances.

This seems incredibly obvious, but there is a warning on the testing page which states, ‘Please complete the Interaction Model tab to start testing this skill’, I went off on a wild goose chase thinking I’d done something else wrong. That warning is arguably one of the misleading features of the whole orchestration interface that Amazon provides. It stays there permanently, no matter what you do.

There are some good examples of the Intent Schema, and other parts of the interaction model already out there but one more can’t hurt. Before I get into it, a quick explanation of what my skill does. My server side code ‘screen scrapes’ a train operator’s web site every 10 minutes. I then parse the rendered HTML looking for specific information about service conditions. That information forms the basis of the response.

Intent Schema:

{
   "intents":[
      {
         "intent":"TrainTimes",
         "slots":[
            {
               "name":"TrainServices",
               "type":"LIST_OF_SERVICES"
            }
         ]
      }
    ]
}

The custom slot looks like:

LIST_OF_SERVICES Peterborough | Luton | Cambridge | Brighton

and then some sample utterances:

TrainTimes how is {TrainServices}
TrainTimes how is the {TrainServices} service
TrainTimes how is the {TrainServices} line

[Brief aside: why ‘train times’, when it’s not timing related? This is a vestige of trying to navigate the mistake I made with the invocation name. I have a strong accent and so was trying all sorts, so at one point it was called ‘big dog’ :)].

The rest of the Amazon interface is pretty straightforward, such as the uploading of self signed certificate [if that’s the approach you choose to take]. One final step before moving away from the interface is the testing. The example question, ‘how is the peterborough service’ gets transformed into the following blob of JSON:

{
  "session": {
    "sessionId": "SessionId.[GUID here]",
    "application": {
      "applicationId": "amzn1.ask.skill.[another GUID here]"
    },
    "attributes": {},
    "user": {
      "userId": "amzn1.ask.account.[long account string here]"
    },
    "new": true
  },
  "request": {
    "type": "IntentRequest",
    "requestId": "EdwRequestId.[one more GUID here]",
    "locale": "en-GB",
    "timestamp": "2017-02-06T13:43:37Z",
    "intent": {
      "name": "TrainTimes",
      "slots": {
        "TrainServices": {
          "name": "TrainServices",
          "value": "Peterborough"
        }
      }
    }
  },
  "version": "1.0"
}

You will obviously need to check that your web service is able to parse this. As per my comments on  my testing cycle, I copied this into Postman as the raw content of a POST.

I’ll briefly go into some more detail about how my implementation works, because when you get into the business end of parsing the input JSON, you need to map it back to some data to respond with.

The parsing of the train company website as a skill isn’t my first bite at the implementation. I started by trying to write a widget for Android. It’s not as simple as just grabbing the HTML, though: the site uses Ajax to render the results. I ended up using HtmlUnit. Because it’s pretty slow, I implemented a class outside the servlet which uses a combination of a ServletContextListener, and then a ScheduledExectuorService. I got the example code from here to work from. The one gotcha is that your web.xml needs to refer to the class.

Next we get on to the hacky part of passing the information on to the servlet. What I did – having the listener write to a flat file which the servlet reads – is a reflection of my novice levels with Java.

So, returning to the list of general problems to solve: having received the POST data, your service then needs to get hold of the data, and then parse the JSON. For the first part, I tried  a few different options and then settled on the getBody implementation I found here.

The parsing of the JSON itself: it’s the first time I’ve ever done this and it feels way more complicated than it should be. I tried a couple of different parsing libraries, but ended up using JSON.simple.

Going back to the JSON data from the Amazon test interface, you have two consecutive objects, the session and the request. For an industrial strength implementation, there are things you need to do with the session data [I’ve also skipped over the TLS client certificate validation, which Amazon stipulates. While perfectly sensible for security purposes, it’s not necessary to get your development implementation up and running.

So the request itself contains a series of embedded objects that you need to unpack, in turn, until I finally get to the slots data. Your implementation will vary, but mine looks like this:

        JSONParser parser = new JSONParser();
        try {
            JSONObject obj = (JSONObject) parser.parse(postData);
            JSONObject jrequest = (JSONObject) obj.get("request");
            log.warning("request: " + jrequest.toString());
            JSONObject intent = (JSONObject) jrequest.get("intent");
            log.warning("intent: " + intent.toString());
            JSONObject slots = (JSONObject) intent.get("slots");
            log.warning("slots: " + slots.toString());
            JSONObject trainSvces = (JSONObject) slots.get("TrainServices");
            log.warning("trainSvces: " + trainSvces.toString());
            String trainSvceVal = (String) trainSvces.get("value");
            log.warning("trainSvceVal: " + trainSvceVal);
            resultString = trainSvceVal;
        } catch (ParseException e) {
            log.warning("ParseException error: ");
            ...
        } 

Again, for a ‘proper’ implementation, you are going to have to test each of the sub-objects. My code is taking a leap of faith :).

Having lost the will to live with the parsing, I have to admit that, having figured out which piece of the train-related data the web service needs to respond with, I then print the JSON straight out in the required format.

 

        response.setContentType("application/json;charset=UTF-8");
        PrintWriter out = response.getWriter();
        out.println("{");
        out.println("  \"response\": {");
        out.println("      \"outputSpeech\": {");
        out.println("         \"type\": \"PlainText\",");
        out.println("         \"text\": \"" + resultsString + "\"");
        out.println("    },");
        out.println("    \"shouldEndSession\": true");
        out.println("    }");
        out.println("}"); 

So, not exactly a thing of beauty, but it works.

If I have any better ideas for future skills to implement, I’ll start with the certificate that Amazon needs. There’s an outfit called StartSSL which it looks like they accept, but which requires email based validation on an address corresponding to the domain. I started looking at setting up PostFix for this – one for another day.

The Land of Fire, Ice and Very Expensive Soup

We’re just back from 4 nights in Reykjavik, which was an absolute blast. We did the usual suspects with trips to the Golden Circle and the Blue Lagoon. We weren’t so lucky with the Northern Lights, although we did get to see a murmuring on our second last night. The long exposure below [15 seconds, F4, ISO 800] picks out a lot more detail than was visible with the naked eye:

Northern Lights

Northern Lights

We knew from the weather forecast that there wasn’t really much point in booking an organised tour [and we really only had two nights to play with]. This was actually on a night when the tours had been cancelled. The composition is dire, but it was the darkest spot that we could find around the Old Harbour, and it was blowing a gale.

A few other obligatory waterfall / geyser type shots included below. Oh, and just to explain the title: on the Golden Circle, we called in for lunch at the facilities by Geysir, where you suffer the consequences of being a captive audience. The fish soup we had for lunch was delicious, but £28 for two bowls was almost as memorable as the scenery!

Gullfoss

Gullfoss

A Geyser; not the Geysir

A Geyser; not the Geysir

Where gloves go to die

Where gloves go to die

pfSense: Adding a Second LAN

While this is undoubtedly a beginner’s question, it’s one that I spent most of yesterday wrestling with. I also really struggled to find information on it: how to add a second LAN.

There are plenty of ways of achieving what I want on my network – to subdivide it between devices I trust, and ones I don’t [or at least trust less, such as my IP camera]. The new machine I got to run pfSense on has 4 network interfaces, so I decided to run two LANs straight off the adaptors [leaving one spare for a possible future experiment with IoT nonsense].

Adding the interface is well documented, as is the ‘default allow’ you’ll need to set in the firewall rules. What you also need to do is to configure a DHCP server, which is under the Services menu in the WebGUI. You’ll see there is an entry already configured for the first LAN, which you can use to figure out the settings. Obviously, this assumes that you configured the LAN for DHCP during the setup, which almost everyone is going to want to do.

I set an address range of .2 – .254, and then configured both the DNS server and the Gateway on .1. You’ll also have to set the ‘enable DHCP’ checkbox at the top, which is disabled by default.

While it’s obvious in retrospect, I went in completely the wrong direction, thinking it was something to do with routing rules. Routing is all well and good, but I was never going to get very far without an IP address :).

pfSense on a Celeron J1900

I spent the weekend setting up pfSense on a new piece of kit that I got last week. A reseller on Amazon is selling a bare bones box with 4 ethernet ports, a Celeron J1900 processor, 2Gb of RAM and a 64Gb SSD for £170, which I thought would be perfect for the task. It’s probably a little over-spec’ed if anything, but it’s a really lovely piece of kit.

I spent the entirety of the install process navigating various options in the Aptio BIOS interface. I had two issues. The first was pretty trivial, which was setting the boot order via ‘HD BBS Priorities’. The option above, ‘Boot Option’ seemed like the more likely but didn’t have any effect.

The second took me hours to figure out. I could see lots of Google hits for BSD installs and runtime issues, but nothing that fit the problem that I was having. During the install a command called bsdlabel hung, and then returned an error, ‘WRITE_EPDMA_QUEUED’, followed by ‘CAM status: command timeout’.

To cut a [very] long story short, I fixed it by setting SATA CONFIG -> SATA Mode -> IDE Mode.

It took me so long to get the install working I’ve not had a chance to play with pfSense itself yet, other than to prove it’s working. One immediate challenge I’ve yet to figure out is how to access the web interface if it’s ‘north’ of a wireless access point….