Saturday, November 20, 2010

Frontend Engineering

With all the talk about Google PageSpeed in the past several months, I have developed an appreciation for learning how to improve user's experiences through better management of the conversations between web browser and server. These concepts pertain to an area of discipline that is being called Frontend Engineering.

Given tools like PageSpeed, it is a shame that many sites still fail to address the issues it reports. Easy gains are often had by following the advice it offers.

I hope to document some of the issues I encounter as I work through them in my day job, involving a large application that I'll call Big Enterprise App (BEA). I'll aim to compile from this a series of Frontend Engineering entries.

Update: Here is a good description of the topics Frontend Engineering deals with. The most succinct description I've heard for this kind of work so far is "responsibility for View Source."

New Toilet - Toto Drake II

We recently bought a Toto Drake II CST454CEFG to replace a poorly installed (and poorly performing) "builder grade" Mansfield Alto 160. The Toto uses only 1.28 gallons per flush, but it never clogs like the Mansfield did. It also is an elongated style, ADA height and overall just seems to have a higher quality fit and finish.



We ended up purchasing online through National Builder Supply, where we got $20 off for using Google Checkout. Shipping was free and the packing was impressively solid with no damage at all to the parts at all.

Installation was pretty straightforward, once I learned that a good way of coping with a broken PVC flange included overlaying it with a metal one expressly made for that purpose.

Obsoleting our plunger was reason enough to make the switch, but we really like that this minimizes our water usage and saves on the bill.

Our take:
  • Environment +1
  • Reduced rate of consumption for water service and softener salt +1
  • Improved aesthetics +1
  • No more plunger needed +1
  • Price was right, at $306 after $20 discount
We expect to place one of these in our other 2 bathrooms in the coming months.

Friday, October 2, 2009

Running JDK6 on FreeNAS 0.7rc1 rev4735

I had a good experience a few months ago when I re-purposed an old and inexpensive Dell PE400SC server as a network attached storage device running FreeNAS. That system has been a joy to work with, and has served to introduce me to my first experiences with iSCSI mounts from my Windows 7 box.

The underpinnings of FreeNAS are FreeBSD:

freenas:~# uname -a
FreeBSD freenas 7.2-RELEASE-p1 FreeBSD 7.2-RELEASE-p1

...as uname explains. Fortunately, FreeBSD is a system that I've gotten to appreciate and know for several years now. So it was just a matter of time before I started looking for what else this machine could do for me. Sure a few small utilities like screen, autossh, and gawk are nice to have, but my bigger interest lies in java applications, so I really wanted a JDK to support that.

So here are the steps I had to navigate to get the Diablo JDK into FreeNAS. I must say, the FreeNAS documentation site seemed kind of hit and miss for some of this information.


Fetch the java binary


I found this was easier done from Firefox from my Win7 box and saved back to the NAS, in part, because the URL redirects to a POST-only form. Grab the file from:


http://www.freebsdfoundation.org/cgi-bin/download?download=diablo-jdk-freebsd7.i386.1.6.0.07.02.tbz


Make pkg_add happy


There seems to be some confusion about what version of FreeBSD this was built with. Try this:


setenv PACKAGESITE ftp://ftp.freebsd.org/pub/FreeBSD/ports/i386/packages-6.4-release/


Attempt Diablo install


Try to install the java binary, but beware it may balk.

pkg_add -v diablo-jdk-freebsd7.i386.1.6.0.07.02.tbz


If it does complain, you may need to do a series of individual fetches with pkg_add:

pkg_add -r x11/xtrans-1.0.4

etc., for every complaint. Then retry the diablo install. In the end, I was rewarded with this:

freenas:~# java -version

java version "1.6.0_07"
Diablo Java(TM) SE Runtime Environment (build 1.6.0_07-b02)
Diablo Java HotSpot(TM) Client VM (build 10.0-b23, mixed mode)


...and a working javac!

Tuesday, September 29, 2009

Jetty 6.1.x hardening

By day, I am a web developer using Java. At work I'm forced to used RAD 6.0, Websphere and JDK 1.4. But on my own time, I favor Jetty for its light weight and ease of use.

Every time I update Jetty, I eventually get around to repeating the same configurations. This entry documents what I've found to be useful towards setting up a production-ready instance of jetty that has limited risk exposure.


Remove sample webapps

Delete all files under webapps\** - also, enable jetty-plus web apps at the same time (all my apps tend to use jndi and connection pools)

Disable default favico

Change etc/jetty.xml to stop serving the default favicon - find DefaultHandler add this serveIcon false setting:

<New id="DefaultHandler" class="org.mortbay.jetty.handler.DefaultHandler">
<Set name="serveIcon">false</Set>
</New>


Conceal server name/version header

Put this under server elements in both jetty.xml and jetty-plus.xml:

<Configure id="Server" class="org.mortbay.jetty.Server">
<Set name="sendServerVersion">false
...


Configure a default/ROOT webapp

Inside this webapp, use Jetty's error code range mappings to do something like this:

<get name="errorHandler">
<call name="addErrorPage">
<arg type="int">300</arg>
<arg type="int">599</arg>
<arg type="String">/WEB-INF/ERROR/generic.jsp</arg>
</call>
</get>

Change the default session cookie name

Normally, J2EE containers send a JSESSIONID cookie in the first request. But why even expose the fact that you're running a servlet container in the first place? Customize this cookie's name using the following in web.xml:

<context-param>
<param-name>org.mortbay.jetty.servlet.SessionCookie</param-name>
<param-value>XSESSIONID</param-value>
</context-param>
<context-param>
<param-name>org.mortbay.jetty.servlet.SessionURL</param-name>
<param-value>none</param-value>
</context-param>

That second setting disables URL session cookies.

The remainder of these notes addresses configuration items that have nothing to do with hardening - these are just convenient reminders to myself.

Add datasources

Under the Configure element for org.mortbay.jetty.Server, add resource definitions as needed.

Here is one example of a datasource with a pool defined using Apache DBCP (put all jars in etc/lib/ext):

<New id="TESTDB" class="org.mortbay.jetty.plus.naming.Resource">
<Arg></Arg>
<Arg>jdbc/TESTDB</Arg>
<Arg>
<New class="org.apache.commons.dbcp.BasicDataSource">
<Set name="driverClassName">com.ibm.db2.jcc.DB2Driver</Set>
<Set name="url">jdbc:db2://example.com:50000/TESTDB</Set>
<Set name="username">user</Set>
<Set name="password">pass</Set>
</New>
</Arg>
</New>


Add MIME mappings for required content types

Add the MIME mappings you'll need to etc/webdefault.xml - a few I have used are:

<mime-mapping>
<extension>jad</extension>
<mime-type>text/vnd.sun.j2me.app-descriptor</mime-type>
</mime-mapping>

<mime-mapping>
<extension>cod</extension>
<mime-type>application/vnd.rim.cod</mime-type>
</mime-mapping>

<!-- also add maps for ogg, others, etc. -->


Replace the DefaultHandler with a custom class


The default handler automatically lists all contexts configured for the webapp, which is not something you typically want in a production environment.



What other customizations would you recommend for locking Jetty down at initial setup?

Friday, January 9, 2009

Using recursion with grep on windows

I've hit this problem before, but never figured it out, so it has bugged me for a while now. But finally, here is the answer.

Having recently started on support for a new project at work, I wanted to get a sense of who had worked on this code base over the past decade or so of its existence. Being a fan of GNU tools for Windows my mind immediately goes to grep, but it didn't work the way I intuitively thought that it should. I wanted to do this from my project directory:


   grep --recursive @author *.java


...and then I figured a quick awk script could roll up counts by name for me. That last argument of *.java however needs be either a list of non-wildcarded filenames or a simple *


  grep --recursive --include="*.java" @author *


Thanks to the poster of this message for helping me find the answer.

Saturday, November 22, 2008

Internet filtering using Linksys routers, Tomato firmware, OpenDNS and FreeDNS

I recently had the opportunity to help out a friend who had some very specific requirements for a home LAN which they were in the process of connecting to the Internet via a cable modem. They wanted to have some restrictions and controls in place to block those nefarious and family-unfriendly web sites, as well as giving different degrees of access to different machines in the home based on things like time of day. After investigating several options for hardware and software, I was pretty happy with the results and thought I would share some of this information.

The Hardware




Linksys have made variations of their WRT54G line of internet routers since 2002. These amazing little devices have a wonderful reputation for their flexibility, stability and low cost. We're talking here about a $45-$65 consumer-level electronics item that is capable of running free software which bestows upon it many capabilities normally associated with systems costing at least 10 times the price. It is also nice to see that the specs on these quiet and power-sipping routers resemble those of circa 1998 PC (266Mhz, 16Mb Ram). Bonus points for being green!

Unfortunately, as with many things in life, Linksys decided to trim back their cost to build these little gems. So hardware revisions 5 and later of the mainstream WRT54G line do not have sufficient memory to support our main requirement: the loading of 3rd party firmware/software. The good news is that Linksys have gone on to provide enthusiasts with a router that does supply enough memory for this purpose, the WRT54GL. The current 1.1 revision of this router has a 200MHz CPU, 16Mb of ram and 4Mb of flash memory. I would, of course, like more memory (prior revisions of the 54G's had double that), but this is enough for most configurations that use alternative software. For those who are hardcore and want the very best, the well endowed 54G/GS models  can still be found out there on e-bay. Just be sure to check exact compatibility of your hardware version to the software you intend to run.

The Software




There are many choices for what software to run on these routers. Some of the more popular ones are DD-WRT, OpenWRT and Tomato. In this case, I chose Tomato for several reasons including:
  • a clean user interface: nicely done layout, vector-based graphs
  • many advanced options and functions are made accessible via the user interface
  • it has been stable and problem free for me for years. Current uptime as I write this: 120 days
  • its well maintained: I still get new releases every few months
By default, Tomato gives you not just one, but two configurable trigger actions that can be fired off whenever your service provider assigns you a different IP address. This came in very handy for the purposes of this specific installation, as you will see below.

The Services

The two services I set up to be notified when the IP address is changed are OpenDNS and FreeDNS. They each provide a different benefit.

FreeDNS provides a zero-cost dynamic DNS service. For those who may not recognize what that is, it lets you refer to your router by name (instead of by numeric IP address) from anywhere on the Internet. When leaving your home for vacation or work, you may be in the habit of making a note of the IP address of your router so it can be reached from the remote location. This is actually a bit of a gamble because what if the IP address is reassigned after you've left? Good luck finding your router now! FreeDNS will give you a fixed host name (something like myrouter.freedns.org) which automatically reflects the last IP address registered by your router. Updates are instant and the price is free, can't beat that. This is very convenient, and may save more than a few PostIT notes with out of date IP addresses scribbled on them. It also opens up possibility for hosting your own Internet services to the world from a server in your home. And if you happen to own your own domain, i.e. "mypersonaldomain.com" it is trivial to set up a CNAME record that then becomes a synonym to the assigned FreeDNS name (aka "myrouterathome.mypersonaldomain.com" is then a synonym for "myrouter.freedns.org"). This gives you another layer of flexibility, so that your selection of dynamic DNS providers can be changed in the future, but your personally assigned host name can remain constant. Think of it as a phone number you own, but that you forward to your actual number which can change at anytime for any reason.

OpenDNS on the other hand is a bit different. First, an analogy. When your cell phone company sells you service, it often includes some form of voice mail system. For most people, that default voice mail service is free and adequate. But what if you had the option to get a more feature rich voice mail system from a source other than your phone company (I actually do this using PhoneTag-highly recommended. Ask me for a referral code if you want to get a discount or to try them out)? Some people wouldn't bother with this since it would probably involve typing some codes into the phone and setting things up, but others might find that option very useful, whether it be for the enhanced features they would receive, or the flexibility it affords ("hey, now I could switch cell phone providers and still keep my same voice mail and its messages!"). This is called "unbundling" and it is not usually something that your incumbent service providers will promote or even tell you about, but often they are forced at some basic level to support it, usually due to regulatory demands.

DNS service is just like that voice mail service: it is a built in feature that every Internet service provider will include, but you have the liberty to use another provider if you want to, and often there is some other advantage to be gained in doing so. The primary function of DNS service is simply to translate a name like yahoo.com into a numeric address like 123.234.56.78. So you may ask what would be the point of having another company do this mundane thing for you? The answer is that OpenDNS manipulates the responses to these lookups in ways that reflect your personally selected preferences and add value.

One of these value-add features is their anti-phishing mechanism, which will send your users to a warning page instead of to the deceptive "phishing" forms posted by criminals seeking to collect your personal information. I am aware that some of the more recent web browsers also advertise that they include this kind of functionality, but as a matter of design, there are better ways to solve that problem. First, why should your PC (or "each of your PCs" if you have multiple) spend time and disk space tracking an ever changing list of phishing sites and vetting every page that you try to visit? I don't know about you, but my computers are already slow enough that I don't want to make them each do more work. If someone else like OpenDNS is offering to proactively do this for me instead, I'll gladly let them deal with that overhead. Offloading this task to them also benefits any web browsers or other Internet software running on your PC which do not yet have anti-phishing support built into them. When these programs look up the address for badguy.com, today they get no protection. But if that lookup is going through OpenDNS, they're automatically covered.

Another big plus for OpenDNS is categorical blocking of sites by content type. Call it parental controls or whatever you want, but many of us never want to see the seedy sides of the Internet. This service goes a very long way towards removing the likelihood of that happening. It also gives you an opportunity (in the OpenDNS account console they provide) to enter in a list of specific sites that you always want blocked. This is above and beyond the blocking they do based on your selection of broadly defined categories. Some of their broad categories include items like:
  • Adult Themes
  • Adware
  • Dating
  • File storage
  • Forums/Message boards
  • Gambling
  • Games
  • Hate/Discrimination
  • Lingerie/Bikini
  • Movies
  • Music
  • P2P/File sharing
  • Pornography
  • Proxy/Anonymizer
  • Sexuality
  • Tasteless
  • Television
  • Weapons
  • several others...
Getting the benefit out of this blocking feature is a bit more work, but its not complicated at all. You must sign up for a free account with OpenDNS, select your blocking categories and configure a method by which your network is identified to them (explanation below). You must also enter in any sites or URLs that you specifically want to have blocked, if that is desired. However, those screens are easy to use and follow. And since the administration of all this is centralized through the OpenDNS console, it is easy to maintain and monitor. Even attempts to access blocked sites and categories are logged and reported, so you can see a ticker that counts the number of times lil Johnny tried to visit www.bad-site-that-parents-said-not-to-visit.com!

The "configure a method by which your network is identified " step is where Tomato's second IP address updater comes into play. The router sees every IP address reassignment automatically, and so it can very efficiently inform OpenDNS of this change within seconds. I am aware that OpenDNS does provide a software "updater" for you that runs on your PC which sort of works, but for detailed reasons I won't go into here, let's just say that isn't really a great solution (depends on a running PC, updates lag after IP reassignment, wastes PC resources by running and polling blindly, etc. all of which leave you burdened with running MORE software on PCs and being un/under-protected for periods of time).

Future direction, final words

In my estimation, OpenDNS is the biggest news here. The nice thing is that you probably don't even have to run Tomato or have a special router to use it, although it is helpful if you do.

As nice as OpenDNS is (I may yet find that their controls alone are sufficient), I am still looking for a way to run a whitelisting proxy for certain PCs in the home. I know this is simple enough to do on a full PC running some form of unix and a proxy package like squid, but that seems like overkill. Ideally, I'd like a very simple, non-caching, whitelist proxy running ON the router and not on a separate PC. I'm looking into options like Privoxy, TinyProxy, Polipo and DansGuardian. Any success stories from router gurus out there would be appreciated.

I hope this is helpful to you if you've been looking for a good way to manage Internet connectivity in the home. There are always little ways that kids can find around measures we take, but this is a good general solution that works for a large set of the problems faced by concerned parents.

-mc