All opinions expressed are those of the authors and not necessarily those of OSNews.com, our sponsors, or our affiliates.
  Add to My Yahoo!  Subscribe with Bloglines  Subscribe in NewsGator Online

published on 2009-11-20 15:28:00 in the "code" category
Kroc Camen
  1. What?
  2. Why?
  3. The Code
    1. Encoding the Videos
  4. Drawbacks
  5. Frequently Asked Questions
  6. Please Contribute
    1. Related Projects

Update: Version 0.3.
What?s new?

  1. Simpler Syntax

  2. Download links outside of fallback
    (makes no sense otherwise)

  3. Working reliably on iPhone OS 3.0+ now

Hosting for the video generously provided by Chris Double of TinyVid.tv

Download Video: High Quality ?MP4? ? Low Quality ?OGG?

What?

Video for Everybody is very simply a chunk of HTML code that embeds a video into a website using the HTML5 <video> element which offers native playback in Firefox 3.5, Safari 3 & 4, Google Chrome and an increasing number of other browsers:

Screenshot of Firefox 3.5 playing video using HTML5

This is native OGG video playback in Firefox 3.5 (you get H.264 playback in Safari). No plugins to install. The video is played by the browser itself. It loads quickly and doesn?t threaten to crash your browser.

In other browsers that do not support <video>, it falls back to QuickTime.

Screenshot of Internet Explorer 8 playing video using Apple QuickTime

(which allows playback on the iPhone)

Two screenshots of an iPhone (OS v2) playing video

If QuickTime is not installed, Adobe Flash is used:
You can host locally or embed any Flash file, such as a YouTube video.

Screenshot of Internet Explorer 8 playing video using Adobe Flash

Finally, if all else fails, the placeholder image is shown and the user can download the video using the links provided.

Screenshot of Firefox 3 without QuickTime or Flash installed, displaying a fall back message about the video

This is all done without JavaScript and requires only two video encodes, one OGG file for Firefox 3.5, and one MP4 file for everything else (Flash / Safari / iPhone). Instructions on how to convert your videos to these formats with the correct settings are provided further down this article.

It?s compatible with HTML 4, HTML5 (valid markup), XHTML 1 and additionally also works when served as application/xhtml+xml.

For a full browser compatibility list, see the Video for Everybody Test Page.

Why?

Assumptions:

The market is made up of more OSes, browsers and processor architectures than it was five years ago. More people (especially geeks) are browsing with AdBlock / NoScript / FlashBlock than ever before. We can no longer just assume people are going to have Flash and are allowing you to use it.

The same rules apply to video. If my platform / device / browser of choice cannot see your video, or you do not offer me the means to download the video to view offline, then I don?t see whatever it is you?ve got to show me.

I therefore want to help all web developers get to grips with <video>, to make it easy for them to show video content without having to sacrifice legacy browsers, nor ask you to install anything just to do so.

Starting Off on the Wrong Foot:

I see a problem with how people are beginning to offer HTML5 video. Whilst it is fantastic that DailyMotion and YouTube are experimenting with HTML5 there are a number of primary things content providers must satisfy for HTML5 video to adhere to the openness it is purposed for.

Not treated like a special case
No special page you have to visit. No extra effort should be required on your part to get video your browser already supports perfectly.
No browser sniffing
Implementations could turn up anywhere, in any form. OGG is open-source open-specification. Serving to only mainstream browsers like Firefox 3.5 goes against the whole point of open-video removing the requirement to be tied to one particular vendor.
Don?t require JavaScript
Developers generally don?t know how to include the video tag whilst falling back to alternatives. Trying to detect browsers using JavaScript and writing the <video> element into the page is just going about it the wrong way.

Video for Everybody specifically solves these problems.
It:

Allows content producers to provide HTML5 video as an equal citizen
The same code is used for browsers that support <video>, as well as QuickTime and Flash. No special copy of your website has to be setup, no options have to be ticked. Video for Everybody plays the right file for the right level of support the user?s browser provides.
Degrades extremely gracefully, providing multiple levels of fallback
Using Flash only provides you support for platforms where Flash is installed. No Flash: No Video. Video for Everybody will most of the time still play the video even if Flash is not installed. Flash is not supported on the iPhone, the ?1 platform for users accessing the web on a mobile.
Is just plain copy & paste HTML
Of course, you can write a server side script to insert it over and over again according to however many videos you have, but the HTML itself does not use JavaScript to insert the video or detect browsers or even provide the fallbacks. You can enhance Video for Everybody with JavaScript (it?s just the template to get you started), but the core selection of which video format plays is completely down to the browser, no JavaScript involved.

The Code

There?s nothing particularly new about this, people have been doing object-fallback for ages now, however this is an attempt at including HTML5 video into the mix, as well as trying to degrade as gracefully as possible with many levels and have very broad browser / device support (including the iPhone). See the test page for a full list.

Here follows the full source code. It?s very large because it?s fully commented.
You can easily compact this down (one such example follows afterwards).

<!-- ?Video For Everybody? v0.3
     =================================================================================================================== -->
<!-- first try HTML5 playback. if serving as XML, expand `controls` to `controls="controls"` and autoplay likewise -->
<video width="640" height="360" poster="__POSTER__.JPG" controls>
	<source src="__VIDEO__.OGV" type="video/ogg" /><!-- Firefox 3.5 native OGG video -->
	<source src="__VIDEO__.MP4" type="video/mp4" /><!-- Safari / iPhone video -->
	<!-- IE only QuickTime embed: IE6 is ignored as it does not support `<object>` in `<object>` so we skip QuickTime
	     and go straight to Flash further down. the line break after the `classid` is required due to a bug in IE -->
	<!--[if gt IE 6]>
	<object width="640" height="375" classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B"><!
	[endif]-->
	<!-- non-IE QuickTime embed (hidden from IE): the self-closing comment tag allows non-IE browsers to
	     see the HTML whilst being compatible with serving as XML -->
	<!--[if !IE]><!-->
	<object width="640" height="375" type="video/quicktime" data="__VIDEO__.MP4">
	<!--<![endif]-->
	<param name="src" value="__VIDEO__.MP4" />
	<param name="showlogo" value="false" />
	<!-- fallback to Flash -->
	<object width="640" height="380" type="application/x-shockwave-flash"
		data="__FLASH__.SWF?image=__POSTER__.JPG&amp;file=__VIDEO__.MP4">
		<!-- Firefox uses the `data` attribute above, IE/Safari uses the param below -->
		<param name="movie" value="__FLASH__.SWF?image=__POSTER__.JPG&amp;file=__VIDEO__.MP4" />
		<!-- fallback image. download links are below the video. warning: putting anything more than
		     the fallback image in the fallback may trigger an iPhone OS3.0+ bug -->
		<img src="__POSTER__.JPG" width="640" height="360" alt="Title of video"
		     title="No video playback capabilities, please download the video below"
		/>
	</object><!--[if gt IE 6]><!-->
	</object><!--<![endif]-->
</video>
<!-- you *must* offer a download link as they may be able to play the file locally -->
<p>Download Video: <a href="__VIDEO__.MP4">High Quality ?MP4?</a> | <a href="__VIDEO__.OGV">Low Quality ?OGG?</a></p>

(If you would like your video to automatically start playing, check out the sample code on the Test Page.)

Here?s a compacted version as an example:
(Technically, only one line break is required, to deal with an IE bug, on line 4)

<video width="640" height="360" poster="__POSTER__.JPG" controls>
	<source src="__VIDEO__.OGV" type="video/ogg" />
	<source src="__VIDEO__.MP4" type="video/mp4" /><!--[if gt IE 6]>
	<object width="640" height="375" classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B"><!
	[endif]--><!--[if !IE]><!-->
	<object width="640" height="375" type="video/quicktime" data="__VIDEO__.MP4">
	<!--<![endif]-->
	<param name="src" value="__VIDEO__.MP4" />
	<param name="showlogo" value="false" />
	<object width="640" height="380" type="application/x-shockwave-flash"
		data="__FLASH__.SWF?image=__POSTER__.JPG&amp;file=__VIDEO__.MP4">
		<param name="movie" value="__FLASH__.SWF?image=__POSTER__.JPG&amp;file=__VIDEO__.MP4" />
		<img src="__POSTER__.JPG" width="640" height="360" alt="Title of video"
		     title="No video playback capabilities, please download the video below" />
	</object><!--[if gt IE 6]><!--></object><!--<![endif]-->
</video>
<p>Download Video: <a href="__VIDEO__.MP4">High Quality ?MP4?</a> | <a href="__VIDEO__.OGV">Low Quality ?OGG?</a></p>

You need to do a number of things to use the code:

  • Ensure your server is using the correct mime-types. Firefox 3.5 will not play the OGG video if the mime-type is wrong. Place these lines in your .htaccess file to send the correct mime-types to browsers

    AddType video/ogg .ogv
    AddType video/mp4 .mp4
  • Replace __VIDEO__.MP4 with the path to your video encoded to MP4-H.264

  • Replace __VIDEO__.OGV with the path to your video encoded to OGG

  • Replace __POSTER__.JPG with the path to an image you want to act as a title screen to the video, it will be shown before the video plays in Flash, and as a representative image when the video is unable to play

  • Replace __FLASH__.SWF with the path to the Flash video player you are using. I use JW Player as it can play the same MP4 that is used for everything else, but this could be any Flash resource including YouTube. Sample code for using YouTube can be seen on the Video for Everybody YouTube Test Page

It is absolutely essential that you provide download links outside of the video for two reasons:

  1. You want people to view your video, right? So why would you wrap the video up in Flash, and then don?t bother providing a means to download the video? There seems to be this phobia of allowing people to actually view the video file you want to show them, like they?re going to immediately pirate it on their street corner. Unless you?ve been living in a hole, it is impossible for you to prevent people from downloading your video files, even if you lock them up in Flash and don?t provide the key. There are hundreds of apps and websites to circumvent that. Give people your video files?you want them to see the video anyway and you are fooling yourself if you think that they shouldn?t be allowed to download the video.

  2. There are some instances where people will simply not be able to view the video inside the web page. Providing users the means to download the video will ensure your message gets through. This is the only way to support the Palm Pr?, for example.

Encoding the Videos

Video for Everybody uses an MP4 video file to play in Safari, in Flash and on the iPhone. Therefore the MP4 file must conform to the requirements for these three platforms. Technically Safari can play anything QuickTime can play. Flash can play H.264 and the iPhone is a little more restrictive in that it tops out at 640x480, does not support streaming, and does not support the Main H.264 profile. See Apple?s own instructions for the specifics.

The OGG file is solely for Firefox 3.5 at the moment for Firefox 3.5 and Chrome, but more browsers may use it in the future as OGG is an open standard and can be implemented by any vendor if they choose so. It is not patent-encumbered and therefore a cheaper choice than MP4 which requires licensing.

For best results, I recommend including the poster image as the first frame when you encode the video. In QuickTime and HTML5 <video>, the first frame of the video is shown until the user clicks play, giving the users an idea of the content beforehand. You can see I?ve done this with my video examples.

I am no expert in video encoding and explaining the entire process is beyond the scope of this article, however this article explains the background technical information and extensive instructions on how to encode compatible OGG files.

Drawbacks

Limited <video> Controls

You can roll your own controls using any HTML and a bit of JavaScript. HTML5 also has the benefit that it is far more efficient than Flash, HD video in the browser is possible?without requiring a supercomputer.

A native video implementation improves as the browser improves. Upgrades are free. If a browser vendor adds fullscreen playback to their <video> implementation, then you get it for free. Firefox 3.6 has built in fullscreen support, but until then there?s a Firefox extension for it already. It?s early days yet and if people don?t start using <video> then the improvements won?t come as fast. Video for Everybody hopes to spur on the improvement of <video> implementations.

Lastly, a current bug in Firefox 3.5 means that when JavaScript is disabled (NoScript for example) the video controls do not display. The developer of NoScript is aware of this issue and will try to come up with a solution. For now, right-click on the video for the controls, or use autoplay on your videos, or rely on users allowing your site in NoScript (the same as they have to do with Flash).

If It Doesn?t Work, It Doesn?t Work

As a raw bit of HTML, you have the issue that some browsers just don?t do things right no matter what. I?ve worked around as many bugs as possible in the most common browsers, however there are some issues that cannot be solved with HTML alone. For example, on Linux systems without Firefox 3.5, Flash or MPEG-4 codecs, the browser may attempt to play the video using the M-Player plugin which will display a blank, broken video interface (due to not having an MPEG4 decoder) instead of the fallback. Personally, I suspect the adoption of Firefox 3.5 on Linux will be rapid, and many users will already have installed either Flash or the extra codecs. Regardless, this is why it is important to always provide download links below the video.

Without JavaScript Video for Everybody can?t deal with those kinds of situations. This affects only a small number of users, however if you need to target these users you can always add JavaScript to Video for Everybody to detect the problematic browser scenarios and make adjustments accordingly. That?s perfectly fine to do as long the Video for Everybody HTML is included in the source and JavaScript enhancements are done on page-load; that way your JavaScript won?t prevent Video for Everybody working for the other 99% of scenarios.

Frequently Asked Questions

Because new ideas are confusing.

Isn?t this 4× as much effort than just using Flash?

Video for Everybody doesn?t require 4 different video encodes! It uses only two, which supports 4× as many platforms and browsers than Flash alone does as well as reaching almost anybody who doesn?t have Flash installed or can?t install it (iPhone / Some 64-Bit operating systems).

In fact, it ends up being more effort in the long-run using a Flash only method because when a device like the iPhone comes along and it doesn?t have Flash and it becomes very popular, you now have to re-encode FLV files and add browser detection and new code to deal with it. New hand-held devices that are coming out generally don?t support Flash, or only support a tiny sub-set, however they are using ports of Webkit and Gecko that may support HTML5 <video>, and as the mobile smart-phone market increases, HTML5 video will keep up far quicker than Adobe and who they choose to support.

The code is too large / ugly

In an ideal world, all the browser vendors would agree upon one standard and one way of doing things and update their old browsers to match too. Then you could just use just <video src="my_video.ogg" /> and it?d play in any browser.

That?s not the case though. Video for Everybody is a hack, a kludge, a workaround. It is to deal with the fact we still have millstones like IE tied around our necks that just won?t get with the times. Video for Everybody deals with all of these broken browsers so that you don?t have to.

I doubt you hand-type every object tag you use. You just copy and paste a template, or use a server-side function to spit out the code each time. The size of the code is moot therefore and can be compacted to a decent size.

Going forward, in the future as HTML5 becomes standard and common, then the layers in Video for Everybody can be dropped and we can all (hopefully) move to just the video element and be done. That won?t happen unless we start making use of HTML5 now to help drive adoption. Maybe one day even Microsoft will add <video> to IE and it should (unless they manage to do even that wrong) ?just work? with Video for Everybody, shedding the Flash layer and automatically moving up to native video.

Are you saying that JavaScript is bad?

No. Video for Everybody is not aimed at bringing down JavaScript or demanding you go back to the stone age. It is a base template that can easily be enhanced using JavaScript, but does not use it itself to provide the fallback mechanisms.

Other HTML5 video embedding methods use JavaScript to detect the browser?s capabilities and insert the appropriate <video> / Flash content, however this has the drawback that JavaScript must be enabled or even supported?Most RSS readers do not execute JavaScript as a security measure. With Video for Everybody, even in environments without JavaScript the user will still either see the video or be able to download it. The more people who see your video, the better for you.

Can I modify it?

Yes! However, just bear this in mind: Video for Everybody is designed to provide video for all browsers within reason; there are a lot of hacks in the code to make the same HTML work across many, many browsers, each tested with and without Flash and QuickTime. That?s a big matrix of testing. If you modify Video for Everybody you might?quite unknowingly?break support for some particular combinations. Please either do what testing you can, or ask me to get involved in helping to test your modifications.

Why don?t you include Cortado, a Java applet that can play OGG video?

The user-experience is more important than the underlying technology. The problem with Java is the user-experience compared to Flash and HTML5 video. The loading of a Java applet causes a noticeable pause whilst the Java Runtime Environment loads. Even on my powerful Mac, the page loading freezes and the hard disk thrashes for a few seconds, on low powered machines I?ve seen the entire computer lock up for 10 seconds. On Windows you get a tray-icon appear an a bubble pop-up from said tray icon distracting you. This is simply unacceptable for playing a video.

Amazon did an experiment whereby they added 100 milliseconds to the load time of their page. Sales dropped 1% immediately. Google did a similar test, adding just half a second to the load time. Traffic dropped 20% immediately.

By including Cortado in Video for Everybody I would be effectively putting some customers off from visiting your website, even damaging people?s opinion of your site because it ?slows their computer down?. Video is used to communicate a message and that needs to be done with the minimal amount of fuss and as much speed as possible. Until Sun Oracle improve Java to the point where it is no longer a visual nuisance and a speed-bump then I would consider it.

You are of course free to modify Video for Everybody to include Cortado! If it serves your demographic or needs better, by all means do so.

Please Contribute

Video for Everybody is not a complete solution. It is the template for you to get started. Please help test Video for Everybody on a wide range of browsers, plugins and devices.

HTML5 video is here now, available on a very wide range of platforms and devices that stretch well beyond what Flash can support. We need to start building the tools and the patterns to support everybody seamlessly. Video for Everybody is my contribution to this larger movement across the web as a helping hand to bridge the gap for developers so that they do not have to be in the position of choosing one (Flash) or the other (<video>), but being able to choose both.

Please send anything Video for Everybody related to me at kroccamen@gmail.com and consider subscribing to the RSS for updates.

If you?ve modified Video for Everybody to do something else, or have created an HTML5 video related project, please let me know and if it upholds the same principles as VfE, I?ll list it here.

(I will not list projects that cannot play the video in an RSS reader. Using JavaScript to insert <video> defeats the entire purpose.)

Univers Video Plugin
A WordPress plugin that provides you a simple interface for inserting video. It uses Video for Everybody for the base template but steps up to a custom interface if JavaScript is available. The plugin even does server-side encoding. The Flash interface is designed to closely mimic the look of Firefox 3.5?s native <video> controls to provide consistency, regardless of technology used. Absolutely stunning work.

Comments

published on 2009-11-20 10:50:00
Kroc Camen

Dasein is an interactive art installation which uses a constructed space, cctv recordings, custom glass and live projections to create a unique and one time viewer experience.

Very interesting use of Video for Everybody, but what really tops the cake is this: Video for Everybody button
Isn?t that just cute!

Update: The web developer of the site has kindly made available the original source file used to make this button. The zip file is enclosed in this article.


Comments

published on 2009-11-19 21:13:00 in the "quote" category
Kroc Camen

If the status quo is good enough for you, you are not working hard enough. Do better. The world needs it.

Kroc Camen

Comments

published on 2009-11-19 10:38:00 in the "quote" category
Kroc Camen

Clutter is when you can hide the entire side column of a website, and not lose anything of value.

Kroc Camen

Comments

published by Eugenia on 2009-11-19 07:14:07 in the "Entertainment" category
Eugenia Loli-Queru

This is a 38-second preview of a music video I shot 1.5 months ago, and it should be completed in December, after we do some necessary re-shoots. The Bay Area artist is Andy Kong, the song is called “Accidental Love Song”, and it’s part of his newly released album “This Beautiful World“.

It was shot with a naked Canon HV20 (just an ND filter was used). The specific “band” scenes you see here were shot in PF24 (at 1/48), but the rest of the video actually has cut-scenes of a little background story we put together. The cut-scenes were shot in 60i, interpolated to 60p, and then slowed-down to 24p (2.5 times).

Edited with Sony Vegas Pro 9, Cineform removed pulldown to 24p, and the following plugins were used: AAV ColorLab, Color Corrector, and a custom Magic Bullet template.


Comments

published by noreply@blogger.com (Ron Phipps) on 2009-11-18 22:19:00 in the "community" category
We've been dealing with an issue on a client's site where customers were reporting that they could not login and when they added items to their cart the cart would come up empty. This information pointed towards a problem with the customer's session being dropped, but we were unable to determine the common line across these customer's environments and came up empty handed. This was a case of being unable to reproduce a problem which made it nearly impossible to fix.

This morning on the Interchange users list there was a post from Racke discussing a similiar issue. His customer had the Ask.com toolbar installed and Interchange's robot matching code was mistakenly matching the Ask.com toolbar as a search spider. The user agent of the browser with Ask.com installed appeared as so:

"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; msn OptimizedIE8;ENUS; AskTB5.6)"

A quick look at the current robots.cfg that Steven Graham linked showed that 'AskTB' had been added to the NotRobotUA directive which instructs Interchange to not consider AskTB a search spider, thus allowing proper use of sessions on the site.

Updating the robots.cfg on our client's site allowed users with Ask.com to browse, login and checkout as expected. Those with Interchange sites who see reports of similiar issues should consider a false positive spider match a possibility and update their robots.cfg.


Comments

published by Eugenia on 2009-11-18 11:48:52 in the "Entertainment" category
Eugenia Loli-Queru

Finished watching The Prisoner’s 2009 remake last night. A total of six episodes, starring Ian McKellen (as 2) and Jim Caviezel (as 6). Spoilers below.

The cinematography and pacing was good throughout the six episodes. It starts with 6 finding himself in the desert and getting back to this seemingly idealistic “Village”. The people there have accepted that there’s nothing beyond the village, that there’s no other world beyond it. During the six episodes, No 2 is trying to break No 6, to make him believe that there’s nothing beyond the Village. However, unlike most of the others who only have dreams relating to other places, No 6 has clear as day memories of his New York life that happens in parallel to his Village life. Naturally, he tries to break free of it, but he can’t. No 2 is the authority in the Village, and he’s got a son and a comatose wife. The Village is not a nice place in reality: everyone’s spying on everyone else, people are getting abducted or getting killed if they are reported. The idealistic nature of the Village is only skin deep.

At the end, is revealed that the Village is not a real place, but a subconscious (or other state of consciousness) level, ran by the brain of No2’s real-life wife in New York, who’s a scientist and creator of psychotropic drugs. The other inhabitants of the village are random NY people, most of them employees of Summakor, the corporation that real-life No2 leads (and that No6 recently resigned from). Summakor runs this project supposedly to help these people, who are all chosen to occupy the village since they lead a troubled real life. So basically, the Village acts as a restrain of the subconscious mind in order to control unwanted behavior of the real life person.

Some people were not happy with this resolution, that the Village is not a real place, but I like it just fine. I think it’s sci-fi enough, and pretty interesting too. Others were unhappy because the series was not like the original ’60s series. Personally, I don’t care about this at all, I review this series on its own merits, as an individual work of art. My problem with the series is elsewhere.

My problem is with the ending. No2 is blowing himself into pieces in order to free himself from the Village’s plane of existence, just as 313 (6’s romantic interest in the series) takes a special pill that makes her real life NY counterpart the new “brain server”, rather than No2’s wife. Now, No2’s wife is not comatose anymore (she was comatose in both lives, because her brain was needed at 100% operation in order to run the Village), and 313/Sarah is. At the very end, 6 is trying to make the Village a better place (in the Village life), and he’s accepted back a higher ranking job at Summakor (in his NY life). The last thing we see in the series is 313 crying, and we don’t know if it’s because of happiness because 6 will indeed try to make the Village a better place, or because 6 has turned, without realizing it, into the new 2: a tyrant.

See, this is a very unsatisfactory ending. We spent 5.5 episodes seeing 6 fighting the status quo and rebel against the tyranny. Even just 20 minutes before the ending the NY counterpart of 6 was questioning the ethics of running such a project. Are we to believe that just like that 6 accepted the Village for what it is and decided to stay in it? Why? Just because of a woman? And was No2’s plan all along to get 6 to accept the Village and be part of it, even if 6 had full knowledge of the other world? In other words, was the whole thing a trap, to find a new boss for the Village? A new boss who while he knew of the truth he would choose to stay?

I just find it stupid knowing the truth and not killing yourself to get out of it. Regardless if there’s a woman involved or not. Made no sense to me. Or is this an allegory for “yeah, you’re young, you’re rebellious, and then you get married, and your life is over“. Because honestly, that’s the only “deeper message” I got out of the series. Or are we, the viewers, to believe that such an experiment with people’s minds “is a good thing” and that’s why 6 accepted it? I personally don’t see anything good with it, it’s evil. Especially since none of these people volunteered for it!

What should have been done instead was the NY 6 destroying all computers and maybe even No2’s wife in order to end the Village. That’s what any sane person would have done. Instead, (a pretty confused throughout the series) No 6 becomes a conformist himself, in both lives. Or was 6 brought into the Village in order to tame/conform him, a subconscious development that subsequently controlled his NY counterpart to accept the job as the new high ranking exec of Summacor? Is this how that corporation hires people, by manipulating their employees’ morality in their subconscious level first? Most people do conform later in their lives, so I guess the ending does mirror real life.

Regardless, the ending just felt unsatisfactory as it left a negative, hopeless mental let-down to the viewer. And the writing was particularly confusing at the end. This is a series that could have been done a bit better if the story and subplots were spelled out a bit clearer with less over-done “artsy” cuts like the ones at the end of each episode. Less surrealism please in the last 5 minutes. Thank you.


Comments

published by steph@endpoint.com (Steph Powell) on 2009-11-17 22:49:00 in the "seo" category

A couple of months ago, I integrated Omniture SiteCatalyst into an Interchange site for one of End Point's clients, CityPass. Shortly after, the client added a blog to their site, which is a standalone WordPress instance that runs separately from the Interchange ecommerce application. I was asked to add SiteCatalyst tracking to the blog.

I've had some experience with WordPress plugin development, and I thought this was a great opportunity to develop a plugin to abstract the SiteCatalyst code from the WordPress theme. I was surprised that there were limited Omniture WordPress plugins available, so I'd like to share my experiences through a brief tutorial for building a WordPress plugin to integrate Omniture SiteCatalyst.

First, I created the base wordpress file to append the code near the footer of the wordpress theme. This file must live in the ~/wp-content/plugins/ directory. I named the file omniture.php.

  <?php /*
    Plugin Name: SiteCatalyst for WordPress
    Plugin URI: http:www.endpoint.com/
    Version: 1.0
    Author: Steph Powell
    */
    function omniture_tag() {
    }
    add_action('wp_footer', 'omniture_tag');
  ?>

In the code above, the wp_footer is a specific WordPress hook that runs just before the </body> tag. Next, I added the base Omniture code inside the omniture_tag function:

...

function omniture_tag() {
?>
<script type="text/javascript">
<!-- var s_account = 'omniture_account_id'; -->
</script>
<script type="text/javascript" src="/path/to/s_code.js"></script>
<script type="text/javascript"><!--
s.pageName='' //page name
s.channel='' //channel
s.pageType='' //page type
s.prop1='' //traffic variable 1
s.prop2='' //traffic variable 2
s.prop3='' //traffic variable 3
s.prop4= '' //traffic variable 4
s.prop5= '' //traffic variable 5
s.campaign= '' //campaign variable
s.state= '' //user state
s.zip= '' //user zip
s.events= '' //user events
s.products= '' //user products
s.purchaseID= '' //purchase ID
s.eVar1= '' //conversion variable 1
s.eVar2= '' //conversion variable 2
s.eVar3= '' //conversion variable 3
s.eVar4= '' //conversion variable 4
s.eVar5= '' //conversion variable 5
/************* DO NOT ALTER ANYTHING BELOW THIS LINE ! **************/
var s_code=s.t();if(s_code)document.write(s_code)
--></script>
<?php
}

...

To test the footer hook, I activated the plugin in the WordPress admin. A blog refresh should yield the Omniture code (with no variables defined) near the </body> tag of the source code.

After verifying that the code was correctly appended near the footer in the source code, I determined how to track the WordPress traffic in SiteCatalyst. For our client, the traffic was to be divided into the home page, static page, articles, tag pages, category pages and archive pages. The Omniture variables pageName, channel, pageType, prop1, prop2, and prop3 were modified to track these pages. Existing WordPress functions is_home, is_page, is_single, is_category, is_tag, is_month, the_title, get_the_category, the_title, single_cat_title, single_tag_title, the_date were used.

...

<script type="text/javascript"><!--
<?php
if(is_home()) {    //WordPress functionality to check if page is home page
        $pageName = $channel = $pageType = $prop1 = 'Blog Home';
} elseif (is_page()) {    //WordPress functionality to check if page is static page
        $pageName = $channel = the_title('', '', false);
        $pageType = $prop1 = 'Static Page';
} elseif (is_single()) { //WordPress functionality to check if page is article
        $categories = get_the_category();
        $pageName = $prop2 = the_title('', '', false);
        $channel = $categories[0]->name;
        $pageType = $prop1 = 'Article';
} elseif (is_category()) {    //WordPress functionality to check if page is category page
        $pageName = $channel = single_cat_title('', false);
        $pageName = 'Category: ' . $pageName;
        $pageType = $prop1 = 'Category';
} elseif (is_tag()) {     //WordPress functionality to check if page is tag page
        $pageName = $channel = single_tag_title('', false);
        $pageType = $prop1 = 'Tag';
} elseif (is_month()) {     //WordPress functionality to check if page is month page
        list($month, $year) = split(' ', the_date('F Y', '', '', false));
        $pageName = 'Month Archive: ' . $month . ' ' . $year;
        $channel = $pageType = $prop1 = 'Month Archive';
        $prop2 = $year;
        $prop3 = $month;
}
echo "s.pageName = '$pageName' //page namen";
echo "s.channel = '$channel' //channeln";
echo "s.pageType = '$pageType'  //page typen";
echo "s.prop1 = '$prop1' //traffic variable 1n";
echo "s.prop2 = '$prop2' //traffic variable 2n";
echo "s.prop3 = '$prop3' //traffic variable 3n";
?>
s.prop4 = '' //traffic variable 4

...

The plugin allows you to freely switch between WordPress themes without having to manage the SiteCatalyst code and to track the basic WordPress page hierarchy. Here are example outputs of the SiteCatalyst variables broken down by page type:

Homepage

s.pageName = 'Blog Home' //page name
s.channel = 'Blog Home' //channel
s.pageType = 'Blog Home'  //page type
s.prop1 = 'Blog Home' //traffic variable 1
s.prop2 = '' //traffic variable 2
s.prop3 = '' //traffic variable 3

Tag Page

s.pageName = 'chocolate' //page name
s.channel = 'chocolate' //channel
s.pageType = 'Tag'  //page type
s.prop1 = 'Tag' //traffic variable 1
s.prop2 = '' //traffic variable 2
s.prop3 = '' //traffic variable 3

Category Page

s.pageName = 'Category: Food' //page name
s.channel = 'Food' //channel
s.pageType = 'Category'  //page type
s.prop1 = 'Category' //traffic variable 1
s.prop2 = '' //traffic variable 2
s.prop3 = '' //traffic variable 3

Static Page

s.pageName = 'About' //page name
s.channel = 'About' //channel
s.pageType = 'Static Page'  //page type
s.prop1 = 'Static Page' //traffic variable 1
s.prop2 = '' //traffic variable 2
s.prop3 = '' //traffic variable 3

Archive

s.pageName = 'Month Archive: November 2009' //page name
s.channel = 'Month Archive' //channel
s.pageType = 'Month Archive'  //page type
s.prop1 = 'Month Archive' //traffic variable 1
s.prop2 = '2009' //traffic variable 2
s.prop3 = 'November' //traffic variable 3

Article

s.pageName = 'Hello world!' //page name
s.channel = 'Test Category' //channel
s.pageType = 'Article'  //page type
s.prop1 = 'Article' //traffic variable 1
s.prop2 = 'Hello world!' //traffic variable 2
s.prop3 = '' //traffic variable 3

A followup step to this plugin would be to use the wp_options table in WordPress to manage the Omniture account id, which would allow admin to set the Omniture account id through the WordPress admin without editing the plugin code. I've uploaded the plugin to a github repository here.


Comments

published by Adam S (firsttubedotcom) on 2009-11-17 18:48:56 in the "Technology" category
Adam S

Thank you, John Resig. Because of you, I’m learning about Javascript the way Andy Gadiel taught me HTML. In the days before server-side scripting, I learned my first bits of HTML largely by viewing the source of Andy Gadiel’s Phish page (which, for some reason, remains largely unchanged since ~1997).  By reading Gadiel’s HTML, I slowly pieced together my own understanding of HTML.  It was Joe Burns’ fantastic Javascript Goodies that first had me dipping my n00b fingers into client side active scripting.  I picked up CSS all over the web.

Resig’s jQuery is so powerful and so easy that even with basic knowledge of CSS and Javascript, anyone can be a virtual scripting master.  It’s so easy, that I’ve slacked on learning about javascript objects, inheritance, closures, anonymous functions, prototypes, and scores of  other Javascript staples that I should’ve long since mastered.   I just discovered John’s new web app, cleverly titled “Learning Advanced Javascript“, and so far, so good!

I wrote this myself and understand why it works, which is much more than I could say yesterday.

var ninja = {
	walk: function(steps,turn) {
		toDo = 'Walking '+steps+' steps forward, then turning '+turn;
		return this;
	  },
	star: function(action,distance) {
		toDo = toDo+' '+action+'ing star '+distance+' feet'; return this;
	  },
	then: function() {
		toDo = toDo+', then '; return this;
	},
	doIt: function() {
		log(toDo);
	}
}
ninja.walk('7','south').then().star('throw','50').doIt();

Output:

> Walking 7 steps forward, then turning south, then throwing star 50 feet

It’s clear to me – and has been for some time – that the future of the web, for better or for worse, rests heavily on the mighty shoulders of client side scripting.   Building on powerful, extensible frameworks like jQuery and MooTools, the next generation of web apps is sure to compete with the desktop.  The ability to understand how to utilize the frameworks when necessary and hack together powerful scriptlets for other purposes seems essential to success in the future web. I know I’ll be investing in “Secrets of a Javascript Ninja” just as a result of this tutorial.


Comments

published by noreply@blogger.com (Ethan Rowe) on 2009-11-17 06:31:00 in the "open-source" category

CakePHP, a popular MVC framework in/for PHP, offers a pretty easy-to-use object-relational mapper, as well as fairly straightforward fixture class for test data. Consequently, it's fairly easy to get into test-driven development with CakePHP, though this can take some acclimation if you're coming from Rails or Django or some such; the need to go through a web interface to navigate to and execute your test cases feels, to me, a little unnatural. Nevertheless, you can get writing tests pretty quickly, and the openness of the testing framework means that it won't get in your way. Indeed, compared to the overwhelming plethora of testing options one gets in the Ruby space -- and the accompanying sense that the choice of testing framework is akin to one's choice of religion, political party, or top 10 desert island album list -- CakePHP's straightforward testing feels a little liberating.

Which is why it was a little surprising to me that getting a test fixture going for the join table on a has-and-belongs-to-many (HABTM) association is -- at least in my experience -- not the clearest thing in the world.

One can presumably configure the fixture to merely use the table option in the fixture's $import attribute. However, as I was following the table and model naming conventions, I felt that I must be doing something wrong in my attempts to get a fixture going for a HABTM relationship, and consequently I eschewed the (potentially) easy way out to try to find a solution that ought to work.

So, let's say my relations were:

  • Product model: some stuff to sell
  • Sale model: individual "sale" events when particular products are promoted
  • A products_sales join table establishes a many-to-many relationship (can we all acknowledge that "many-to-many" is much more convenient for meatspace communication than the horrendously awkward "has-and-belongs-to-many"?) between these two fabulous structures

You can go with the usual Cake-ish model definitions:


# in app/models/product.php
class Product extends AppModel {
    $name = 'Product';
    $hasAndBelongsToMany = array(
        'Sale' => array('className' => 'Sale')
    );
}

# in app/models/sale.php
class Sale extends AppModel {
    $name = 'Sale';
    $hasAndBelongsToMany = array(
        'Product' => array('className' => 'Product')
    );
}
 
Since we're following the naming conventions here (singular model name fronts pluralized table name, the join table for the HABTM relationship uses pluralized names for each relation joined, in alphabetical order), then the above code should be all you need for the relationship to work.

Indeed, as explained in this helpful article on the HABTM-in-CakePHP subject, you should find that queries using these models will automatically include 'ProductsSale' model entries in their result sets, with that model being dynamically generated by the HABTM association.

So, that means you should be able to create a test fixture for the ProductsSale model, right?


# in app/tests/fixtures/products_sale.php
class ProductsSale extends CakeTestFixture {
    $name = 'ProductsSale';
    $import = 'ProductsSale';
    $records = array(
       a buncha awesome stuff...
    );
}
 

Unfortunately, at least with my experience on CakePHP 1.2.5, that doesn't work. When your test case attempts to load the fixture, you'll get SQL errors indicating that the test-prefixed version of your "products_sales" table doesn't exist.

I haven't done a sufficiently exhaustive analysis of the Cake innards to sort out why this is, and may yet do so. My guess based on nothing other than observation and intuition is that the auto-generated model is related only to the models involved in the HABTM relationship, through the bindModel method, and does not get generated in any global capacity such that it exists as a model in its own right. Consequently, while the testing code can guess the correct table name for the join table based on the naming conventions used for the fixture, since it doesn't relate to an extant model, it fails to go through the model-wrapping procedures that typically take place per test-case (setting up the test-space table per model, populating it from the fixture, etc.)

Fortunately, as illustrated by the aforementioned helpful article, we can front the join table with a full-fledged model class, and use that model class within the association definitions. This solves the problem of the broken fixture, as the fixture will now refer to a standard model and successfully set up the test table, data, etc.

That means the code becomes:


# in app/models/products_sale.php
class ProductsSale extends AppModel {
    /* the naming convention assumes singularized model name
       based on the entire table name; it does not make inner
       names singular.  This feels a little unclean.  If it
       really bothers you, recall the language you're using
       and I suspect you'll get over it. */
    $name = 'ProductsSale';
    /* The join table belongs to both relations */
    $belongsTo = array('Product', 'Sale');
}

# in app/models/product.php
class Product extends AppModel {
    $name = 'Product';
    /* Use the 'with' option to join through the new model class */
    $hasAndBelongsToMany = array(
        'Sale' => array('with' => 'ProductsSale')
    );
}

# in app/models/sale.php
class Sale extends AppModel {
    $name = 'Sale';
    /* And again, the 'with' option */
    $hasAndBelongsToMany = array(
        'Product' => array('with' => 'ProductsSale')
    );
}
  

No changes are necessary to the fixture for ProductsSale; once that join model is in place, it'll be good.

It is not uncommon for ORMs to provide magical intelligence for establishing HABTM relationships, and as a matter of convenience it's pretty handy. It is similarly common to allow for HABTM association through an explicitly-defined model class. While this ups the ceremony for setting up your ORM, there are benefits that come with it; a reduced reliance on magic can be distinctly advantageous if you ever get into hairy situations with ORM query wrangling, and it is reasonably common for a HABTM association to have annotations on the relationship itself. In each case, you'll be happy to have your join table fronted by a model class.

Hopefully this will save somebody else some trouble.


Comments

published by steph@endpoint.com (Steph Powell) on 2009-11-16 17:57:00 in the "seo" category

I'm back at work after last week's PubCon Vegas. I published several articles about specific sessions, but I wanted to provide some nuggets on recurring themes of the conference.

Google Caffeine Update

This year Google rolled out some changes referred to as the Google Caffeine update. This change increases the speed and size of the index, moves Google search to real-time, and improves search results relevancy and accuracy. It was a popular topic at the conference, however, not much light was shed on how algorithm changes would affect your search results, if at all. I'll have to keep an eye on this to see if there are any significant changes in End Point's search performance.

Bing

Bing is gaining traction. They want to get [at least] 51% of the search market share.

Social media

Social media was a hot topic at the conference. An entire track was allocated to Twitter topics on the first day of the conference. However, it still pales in comparison to search. Of all referrals on the web, search still accounts for 98% and social media referrals only account for less than 1% (view referral data here). Dr. Pete from SEOMoz nicely summarized the elephant in the room at PubCon regarding social media that it's important to measure social media response to determine if it provides business value.

Ecommerce Advice

I asked Rob Snell, author of Starting a Yahoo Business for Dummies, for the most important advice for ecommerce SEO he could provide. He explained the importance of content development and link building to target keywords based on keyword conversion. Basically, SEO efforts shouldn't be wasted on keywords that don't convert well. I typically don't have access to client keyword conversion data, but this is great advice.

Internal SEO Processes

Another recurring topic I observed at PubCon was that often internal SEO processes are a much bigger obstacle than the actual SEO work. It's important to get the entire team on your side. Alex Bennert of Wall Street Journal discussed understanding your audience when presenting SEO. Here are some examples of appropriate topics for a given audience:

  • IT Folks: sitemaps, duplicate content (parameter issues, pagination, sorting, crawl allocation, dev servers), canonical link elements, 301 redirects, intuitive link structure
  • Biz Dev & Marketing Folks: syndication of content, evaluation of vendor products & integration, assessing SEO value and link equity of partner sites, microsites, leveraging multiple assets
  • Content Developers: on page elements best practices, linking, anchor text best practices, keyword research, keyword trends, analytics
  • Management: progress, timelines, roadmaps

On the topic of internal processes, I was entertained by the various comments expressing the developer-marketer relationship, for example:

  • "Don't ever let a developer control your URL structure."
  • "Don't ever let a developer control your site architecture."
  • "This site looks like it was designed by a developer."

Apparently developers are the most obvious scapegoat. Back to the point, though: It often requires more effort to get SEO understanding and support than actually explaining what needs to be done.

Search Engine Spam

Search engine spam detection is cool. During a couple of sessions with Matt Cutts, I became interested in writing code to detect search spam. For example:

  • Crawling the web to detect links where the anchor text is '.'.
  • Crawling the web to identify sites where robots.txt blocks ia_archiver.
  • Crawling the web to detect pages with keyword stuffing.

I've typically been involved in the technical side of SEO (duplicate content, indexation, crawlability), and haven't been involved in link building or content development, but these discussions provoked me to start looking at search spam from an engineer's perspective.

Google Parameter Masking

Apparently I missed the announcement of parameter masking in Google Webmaster Tools. I've helped battle duplicate content for several clients, and at PubCon I heard about parameter masking provided in Google Webmaster Tools. This functionality was announced in October of 2009 and allows you to provide suggestions to the crawler to ignore specific query parameters.

Parameter masking is yet another solution to managing duplicate content in addition to the rel="canonical" tag, creative uses of robots.txt, and the nofollow tag. The ideal solution for SEO would be to build a site architecture that doesn't require the use of any of these solutions. However, as developers we have all experienced how legacy code persists and sometimes a low effort-high return solution is the best short term option.


Comments

published by noreply@blogger.com (Greg Sabino Mullane) on 2009-11-16 17:12:00 in the "security" category

One of the best ways to secure your box against SSH attacks is the use of port knocking. Basically, port knocking seals off your SSH port, usually with firewall rules, such that nobody can even tell if you are running SSH until the proper "knock" is given, at which time the SSH port appears again to a specific IP address. In most cases, a "knock" simply means accessing specific ports in a specific order within a given time frame.

Let's step back a moment and see why this solution is needed. Before SSH there was telnet, which was a great idea way back at the start of the Internet when hosts trusted each other. However, it was (and is) extremely insecure, as it entails sending usernames and passwords "in the clear" over the internet. SSH, or Secure Shell, is like telnet on steroids. With a mean bodyguard. There are two common ways to log in to a system using SSH. The first way is with a password. You enter the username, then the password. Nice and simple, and similar to telnet, except that the information is not sent in the clear. The second common way to connect with SSH is by using public key authentication. This is what I use 99% of the time. It's very secure, and very convenient. You put the public copy of your PGP key on the server, and then use your local private SSH key to authenticate. Since you can cache your private key, this means only having to type in your SSH password once, and then you can ssh to many different systems with no password needed.

So, back to port knocking. It turns out that any system connected to the internet is basically going to come under attack. One common target is SSH - specifically, people connecting to the SSH port, then trying combinations of usernames and passwords in the hopes that one of them is right. The best prevention against these attacks is to have a good password. Because public key authentication is so easy, and makes typing in the actual account password such a rare event, you can make the password something very secure, such as:

gtsmef#3ZdbVdAebAS@9e[AS4fed';8fS14S0A8d!!9~d1aAQ5.81sa0'ed

However, this won't stop others from trying usernames and passwords anyway, which fills up your logs with their attempts and is generally annoying. Thus, the need to "hide" the SSH port, which by default is 22. One thing some people do is move SSH to a "non-standard" port, where non-standard means anything but 22. Typically, some random number that won't conflict with anything else. This will reduce and/or stop all the break-in attempts, but at a high cost: all clients connecting have to know to use that port. With the ssh client, it's adding a -p argument, or setting a "Port" line in the relevant section of your .ssh/config file.

All of which brings us to port knocking. What if we could run SSH on port 22, but not answer to just anyone, but only to people who knew the secret code? That's what port knocking allows us to do. There are many variants on port knocking and many programs that implement it. My favorite is "knockd", mostly because it's simple to learn and use, and is available in some distros' packaging systems. My port knocking discussion and examples will focus on knockd, unless stated otherwise.

knockd is a daemon that listens for incoming requests to your box, and reacts when a certain combination is reached. Once knockd is installed and running, you modify your firewall rules (e.g. iptables) to drop all incoming traffic to port 22. To the outside world, it's exactly as if you are not running SSH at all. No break-in attempts are possible, and your security logs stay nice and boring. When you want to connect to the box via SSH, you first send a series of knocks to the box. If the proper combination is received, knockd will open a hole in the firewall for your IP on port 22. From this point forward, you can SSH in as normal. The new firewall entry can get removed right away, cleared out at some time period later, or you can define another knock sequence to remove the firewall listing and close the hole again.

What exactly is the knock? It's a series of connections to TCP or UDP ports. I prefer choosing a few random TCP ports, so that I can simply use telnet calls to connect to the ports. Keep in mind that when you do connect, it will appear as if nothing happened - you cannot tell that knockd is logging your attempt, and possibly acting on it.

Here's a sample knockd configuration file:

[options]
  logfile = /var/log/knockd.log

[openSSH]
  sequence    = 32144,21312,21120
  seq_timeout = 15
  command     = /sbin/iptables -I INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
  tcpflags    = syn

[closeSSH]
  sequence    = 32144,21312,21121
  seq_timeout = 15
  command     = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
  tcpflags    = syn

In the above file, we've stated that any host that sends a TCP syn flag to ports 32144, 21312, and 21120, in that order, within 15 seconds, will cause the iptables command to be run. Note that the use of iptables is completely not hard-coded to knockd at all. Any command at all can be run when the port sequence is triggered, which allows for all sorts of fancy tricks.To close it up, we do the same sequence, except the final port is 21221.

Once knockd is installed, and the configuration file is put in place, start it up and begin testing. Leave a separate SSH connection open to the box while you are testing! If you are really paranoid, you might want to open a second SSH daemon on a second port as well. First, check that the port knocking works by triggering the port combinations. knockd comes with a command-line utility for doing so, but I usually just use telnet like so:

[greg@home ~] telnet example.com 32144
Trying 123.456.789.000...
telnet: connect to address 123.456.789.000: Connection refused
[greg@home ~] telnet example.com 21312
Trying 123.456.789.000...
telnet: connect to address 123.456.789.000: Connection refused
[greg@home ~] telnet example.com 21120
Trying 123.456.789.000...
telnet: connect to address 123.456.789.000: Connection refused

Note that we reveived a bunch of "Connection refused" - the same message as if we tried any other random port. Also the same message that people trying to connect to a port knock protected SSH will see. If you look in the logs for knockd (set as /var/log/knockd.log in the example file above), you'll see some lines like this if all went well:

[2009-11-09 14:01] 100.200.300.400: openSSH: Stage 1
[2009-11-09 14:01] 100.200.300.400: openSSH: Stage 2
[2009-11-09 14:01] 100.200.300.400: openSSH: Stage 3
[2009-11-09 14:01] 100.200.300.400: openSSH: OPEN SESAME
[2009-11-09 14:01] openSSH: running command: /sbin/iptables -I INPUT -s 100.200.300.400 -p tcp --dport 22 -j ACCEPT

Voila! Your iptables should now contain a new line:

$ iptables -L -n | grep 100.200
ACCEPT     tcp  --  100.200.300.400  anywhere            tcp dpt:ssh

The next step is to lock everyone else out from the SSH port. Add a new rule to the firewall, but make sure it goes to the bottom:

$ iptables -A INPUT -p tcp --dport ssh -j DROP
$ iptables -L | grep DROP
DROP       tcp  --  anywhere             anywhere            tcp dpt:ssh

You'll note that we used "A" to append the DROP to the bottom of the INPUT chain, and "I" to insert the exceptions to the top of the INPUT chain. At this point, you should try a new SSH connection and make sure you can still connect.If all is working, the final step is to make sure the knockd daemon starts up on boot, and that the DROP rule is added on boot as well. You can also add some hard-coded exceptions for boxes you know are secure, if you don't want to have to port knock from them every time.

One flaw in the above scheme the sharp reader may have spotted is that although the SSH port cannot be reached without a knock, the sequence of knocks used can easily be intercepted and played back. While this doesn't gain the potential bad guy too much, there is a way to overcome it. The knockd program allows the port knocking combinations to be stored inside of a file, and read from, one line at a time. Each successful knock will move the required knocks to the next line, so that even knowing someone else's knock sequence will not help, as it changes each time. To implement this, just replace the 'sequence' line as seen in the above configuration file with a line like this:

one_time_sequences = /etc/knockd.sequences.txt

In this case, the sequences will be read from the file named "/etc/knockd.sequences.txt". See the manpage for knockd for more details on one_time_sequences as well as other features not discussed here. For more on port knocking in general, visit portknocking.org.

While the one_time_sequences is a great idea, I'd like to see something a little different implemented someday. Specifically, having to pre-populate a fixed list of sequences is a drag. Not only do you have to make sure they are random, and that you have enough, but you have to keep the list with you locally. Lose that list, and you cannot get in! A better way would be to have your port knocking program generate the new port sequences on the fly. It would also encrypt the new port sequences to one or more public keys, and then put the file somewhere web accessible. Thus, one could simply grab the file from the server, decrypt it, and perform the port knocking based on the list of ports inside of it. Is all of that overkill for SSH? Almost certainly. :) However, there are many other uses for port knocking that simple SSH blocking and unblocking. Remember that many pieces of information can be used against your server, including what services are running on which ports, and which versions are in use.


Comments

published on 2009-11-16 13:23:00 in the "quote" category
Kroc Camen

I find it somewhat ironic that twenty years later a C64 game on the iPhone costs the same as when it was new in the shops.

Kroc Camen

Comments

published on 2009-11-15 22:09:00
Kroc Camen

ezBoard. Wow, a blast from the past. It?s like your childhood teddy knocking on your door, all dirty and sodden. You had forgotten about it.


Comments

published by Eugenia on 2009-11-15 10:33:35 in the "Filmmaking" category
Eugenia Loli-Queru

Having nothing more to do tonight I browsed the archives of the HV20.com forum to search for good HV footage (and I already check out properly tagged videos on Youtube and Vimeo daily). Found some interesting stuff. Two full-length HV movies for one. “Hollow” is a drama, and “Envelop” is a horror movie (login to the site to be able to view the screen-caps). Both movies are in post-production right now.

Secondly, I found this beautiful music video shot with an HV20 (w/ 35mm adapter). I believe VH1 and MTVU was going to show it, not sure if it actually reached the TV sets. It did reach their web sites though. The song is currently offered for free for promotional reasons. Get it here.

And one more music video, with the same director and band. I believe this was also shot with his HV20, but I will have to confirm with the director. UPDATE: Confirmed, it’s also with the HV20 and a Letus Mini adapter. Here’s a picture of the director’s rig, and a yet another music video by the same director and band, with the HV20.


Comments