Med fokus på din virksomheds forretningsgange watermark with eaktion circles

Connecting Access to MySQL through a SSH tunnel using Putty and port forwarding

December 25th, 2011

I’m publishing today this article that is some years old and was just collecting dust in my drawer. I believe it can still be useful to many. In particular the problem I’m going to solve is about the MySql error:

Connection failed: [08S1][MySQL][ODBC 5.1] Lost connection to MySQL server at ’reading initial communication packet’

Just paste the title of the post in a Google search box and you’ll get plenty of tutorials for how to set up Putty to do this.

The reason why I add something to the argument, is that after having used tunneling to connect to a MySQL RDBMS for some years, the day came when my settings didn’t work any longer. I used a fair amount of hours to find a solution to the problem and Google was only helpful to exclude other solutions. There’s no reason why you should do the same.

The error I got when testing the connection from the Connector configuration window was:

Connection failed: [08S1][MySQL][ODBC 5.1] Lost connection to MySQL server at ’reading initial communication packet’, system error: 2

If you google the Internet to find a solution to this error, you will probably come to the conclusion that something is wrong with your firewall settings or your network connectivity. Many times the solution given to solve problems that lead to the same error message, is to correct the server connect_timeout from the once default 5 (seconds) to a higher time span.

However this was definitely not the culprit in my case.

My setup

Now, before we go on to read about the mistake I made and the solution, I’d better add some details about the setup I’m working with. In a different setup you might have to use somewhat different settings.

I’m connecting to a MySQL server on a Linux box (Debian etch), from Windows XP / Vista.
The tunnel (port forwarding over SSH) is done using Putty.

What is important to notice for this text to be valid is the fact that MySQL runs on Linux and not on Windows.

The wrong tunnel configuration

The mistake is shown in this picture showing Putty tunnel configuration.

I had set the tunnel in such a way, to forward my local port to remote Linux box, port 3306 – writing the domain name, it could also have been the remote IP address. Now, this is not wrong in general and among the tutorials you’ll find on the Internet many recommend this setting. On the other hand the tunnel had been working fine for some years, and it would have gone on for more years if I hadn’t switched to a different server.

DSN configuration

Before we come to why this setting in fact is a mistake we’ll also have a look at another of the settings needed for the Access-MySQL connection to work, the DSN settings.

As you might know, here we set the data source as being the

local port (2306 in my case, different from MySQL default port 3306 to avoid conflicts with a possible MySQL for Windows installed on my PC) that we want to forward to the remote MySQL server. The setting under “Server” must be 127.0.0.1 in most of the cases. The reason is that your /etc/mysql/my.cnf file will have a line:

bind-address            = 127.0.0.1

This tells the server to only allow connection from the localhost, that is from users of the same Linux box, not connecting from outside. This line is default in a Debian distribution, and I believe it’s default in many other distros too. It avoids to expose the server to all possible connection attempts from black hat guys on the Internet. This is actually one of the reasons why we do SSH tunneling in the first place.

When you have logged into your server through Putty, your server is no longer remote, and that’s why 127.0.0.1 here doesn’t prevent the connection, and at the same time you comply with what is written in the option file (bind-address   = 127.0.0.1).  What happens is that all what you send to your local port will be transferred by Putty to the corresponding port on what “was” the remote server. MS Access or any other application using that port will never know.

This setting is shown correctly in all the tutorials, I have seen on the Internet.

Why the Tunnel configuration was wrong

However one could ask, whether or not we need to write the remote address or the localhost address in the tunnel configuration, not all the tutorials agree on this point. And in fact the answer is that we don’t need to write the remote address, or rather that we should avoid this: When Putty is establishing the port forwarding, it is already connected to your remote server, the connection happens between the two ports on the local and the remote server no matter if we write the local or the remote address in the tunnel settings, as long as it is a valid way of specifying it.

Putty doesn’t care, SSH doesn’t care, but MySQL does apparently care: as we have seen,

it will toss a: Connection failed: [08S1][MySQL][ODBC 5.1] Lost connection to MySQL server at ’reading initial communication packet’, system error: 2

To sum up

Summing up:

write the loopback address in the tunnel settings,

write the loopback address in the DSN setting

One last detail

Yes, one last thing remains to be explained and this is why on earth the “wrong” settings did work on my first server, and did no longer work when I used them on a new server?

Now, my explanation here is a fair amount more than plain guesswork, but still guesswork, however it makes sense to me and it is enough to let me sleep at night. It might satisfy you as well: I believe the reason is that on the first box (where the remote address didn’t hinder the connection) I had only one IP address on one network card. The OS was probably making its own translation of the remote address into the loopback address before MySQL received it. On the second box (where this setting stopped working) I had several IP addresses, and probably for this reason the remote address was no longer just translated by the OS into the loopback address for MySQL, and this triggered the connection error.

At least this will give you one more chance to find a solution to the problem, before blaming your firewall settings or network connectivity.

WordPress Plugin Shortcode Generator Not Saving Shortcodes

November 28th, 2011

Recently I needed the WordPress plugin “Shortcode Generator” for one of my customers. Unfortunately I experienced the same as others: the plugin seems to work but when you go back and see your newly created shortcode, all you get is: “There are no generated shortcodes defined”.

With this post I publish a fix for the problem. I’ll do the same on some of the posts that report the problem on the WordPress website.

Why the plugin does not save codes

The reason is that the shortcode table in the database is not created when the plugin is activated. The table is not created because the table schema triggers an error due to one of the indexes being too large. You don’t see the error as WordPress suppresses it, however the table is not there.

To solve the problem you have to repeat the following steps, briefly put:

  • add code to properly deactivate the plugin
  • fix the database schema
  • deactivate the plugin
  • reactivate the plugin
I assume here that you have already tried and activated the plugin.

Detailed step-by-step description

These four steps are easy to accomplish even for non programmers, just follow the  description below:

Open the plugin main file in a text editor. The file is located inside the folder wp-content/plugins/shortcode-generator/ and the name is shortcode-generator.php.

Inside your WordPress admin section, you can edit it from

plugins>editor>Select plugin to edit >Shortcode Generator >shortcode-generator/shortcode-generator.php

Find the “uninstall” function at around line 65

function uninstall(){

}

And change it into this:

function uninstall(){

    delete_option('scg_version');

}

Find the “install” function at line 43:

function install(){
    global $wpdb;
    require(ABSPATH.'/wp-admin/includes/upgrade.php');
    $installed_version = get_option('scg_version');
    if($installed_version == '' || $installed_version < SCG_VERSION){
        $create_table = "
        CREATE TABLE {$wpdb->shortcodes} (
        `ID` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
        `shortcode` VARCHAR( 255 ) NOT NULL ,
        `value` LONGTEXT NOT NULL ,
        `type` VARCHAR( 255 ) NOT NULL ,
        UNIQUE (`shortcode`, `type`) ,
        FULLTEXT (
        `value`
        )
        )
        ";
        dbDelta($create_table);
    }
    add_option('scg_version',SCG_VERSION,'','no');
}

and change the definition of the “type” column to be 8 instead of 255. In this way Mysql will also have a better performance and since the types are only “wysiwyg” and “html”, both shorter than 8 chars, 8 is all you need.
The new “install” function looks like below:

function install(){
    global $wpdb;
    require(ABSPATH.'/wp-admin/includes/upgrade.php');
    $installed_version = get_option('scg_version');
    if($installed_version == '' || $installed_version < SCG_VERSION){
        $create_table = "
        CREATE TABLE {$wpdb->shortcodes} (
        `ID` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
        `shortcode` VARCHAR( 255 ) NOT NULL ,
        `value` LONGTEXT NOT NULL ,
        `type` VARCHAR( 8 ) NOT NULL ,
        UNIQUE (`shortcode`, `type`) ,
        FULLTEXT (
        `value`
        )
        )
        ";
        dbDelta($create_table);
    }
    add_option('scg_version',SCG_VERSION,'','no');
}

Then deactivate the plugin:

From your WordPress admin section

>plugins>installed plugins > Active

Click on “Deactivate”

Then reactivate

>plugins>installed plugins > Inactive

That’s it! The table should have been created and with it the ability to save your shortcodes.

Templating with Smarty for Ajax Enabled Applications

August 18th, 2011

JavaScript is the future

The future is pretty clear to me, JavaScript will be the one and only on the web.
And I mean both on the client side and the server side. Am I going crazy?
Just wait for node.js to be ready for prime time and let the YUI Library be finished with the application framework, then we start talking.

However, while we wait for the day of the grand merging of technologies, we still have to do some work and keep the code nicely organized. Smarty helps me to do that. I use Smarty templates to separate code from presentation and (among other things) Smarty plugins to organize my code.

In the meanwhile, get YUI and AJAX to work nicely with Smarty and PHP

When I started using Ajax it was with the help of Xajax. What I like of Xajax is that it allows me to target a single function right from the client code, and to control the JavaScript code from inside the PHP code. A pretty fine grained 2-way communication.

Now that I use YUI more and more, I wanted to get rid of the duplication of JavaScript code that is caused by having to load both the Xajax and the YUI JavaScript libraries. Anyone serious about JavaScript would have no doubt, I had to say goodbye to Xajax.

However, YUI is naturally slanted to the JavaScript side. With YUI you produce modules and stuff that encapsulate XHR transactions, and you pass a url to the transaction. On the server side you’re on your own for how to organize your code in a manageable way.

Manageable to me means among other things that:

  • I can include my php files from wherever I want, especially from outside my server root
  • I can have a one-to-one relationship between the page I’m showing to the user and the code that supports it
  • I don’t need to create extra urls just to pull in responses to my JavaScript code
  • I don’t have to reinvent a new set of conventions each time I write some JavaScript code

These are the things I felt YUI was making difficult to me.

To make up for this I’ve developed a set of two modules: inlineXHR(php), a lightweight PHP module, that works together with inlineXHR, a lightweight JavaScript module for YUI 3. With the two inlineXHR modules, I have re-established a fine grained 2-way communication between my PHP code on the server side and my JavaScript code on the client.

Now I can again target directly from JavaScript, PHP functions, class methods and Smarty plugins. All AJAX / JSON stuff is taken care of once and for all, the cursor is spinning when it has to, errors are logged to console or popped up in alerts, and I can write PHP code without even thinking about the fact that the output has to be sent through the wire, as JSON.

If you use YUI and PHP, and you too think that life is too nice to use time reinventing the wheel each time a JS code need to talk to your server, you might want to give it a try. It’s free, open source and BSD licensed.

Click to see usage instructions and working examples

Upgrading from Debian Lenny to Squeeze (version 6)

June 6th, 2011

You want to update to Debian Squeeze from Lenny. You don’t want to scour the whole Debian documentation just to be sure not to have overlooked details that apply to your situation. Here is a complete step-by-step tutorial for upgrading to Squeeze from Debian Lenny.

In 4 steps is listed here the procedure we’ll follow. There are quicker, more risky, procedures, however the time saved doing otherwise is count in seconds, who bothers.

  1. minimal system upgrade, followed by
  2. a kernel upgrade, udev upgrade and reboot, and then
  3. (optionally) upgrade the packages associated with your critical services.
  4. full upgrade

I spell out here all the preconditions that apply for this condensed but complete step-by-step tutorial for upgrading from Debian Lenny to Squeeze. You can easily find out if this is for you or not. For web developers that use Debian as a testing/production machine this will apply in 95% of all cases.

If you don’t meet all preconditions you’ll have to go read the full documentation.

Our Goal

The goal is to be able to update from a remote terminal with as little disruption and as few risks as possible, by risks meaning the need to resort to a local console to fix problems. However no guarantees are given. None at all. The only guarantee I can give, is that I have tried the upgrade myself on 3 different Debian boxes. On one it failed because I followed a different, shorter, recipe. Two were successful following this one.

Preconditions for the Upgrade

Your Debian Lenny is a pure command line installation (no GUI, that is, x-server and more). You are running some servers and other stuff, but you don’t have external users logging in their own /home directory to care of.

You have a Debian Lenny (version 5) that is up to date to the last update point. Otherwise

aptitude update

aptitude full-upgrade

should resolve any issues. Verify with

dpkg -l | pager

no packages should have a combination of h and fh as the first 2 flags in the output.

it might be bad if you have any other combination of letters. Here is an excerpt of mine.

ii  apt-utils    0.7.20.2+lenny2    APT utility programs
ii  aptitude   0.4.11.11-1~lenny1  terminal-based package ...
rc  aspell-en     6.0-0-5.1                  English dictionary for G...

ii is OK, rc is OK

From here on we’ll use Apt instead of Aptitude (it is officially recommended for a Lenny to Squeeze upgrade)

Other preconditions to “qualify” for blindly following this step-by-step recipe:

You don’t have third party packages (from repositories other than the official Debian Lenny repositories), if you do, remove them prior the upgrade and treat their upgrade independently.

“If you are using some VPN services (such as tinc) they might not be available throughout the upgrade process”

“You should not upgrade using telnet, rlogin, rsh”, you might loose connection, use ssh instead.”

“If you have configured APT to install certain packages from a distribution other than stable (e.g. from testing), you may have to change your APT pinning configuration. In this case you want to read the whole document on Debian org.

Let’s start

1 Minimal System Upgrade

Take a backup of

  • all /etc
  • the file ./curr-pkgs.txt after having done: dpkg --get-selections "*" > ./curr-pkgs.txt
  • /var/lib/dpkg
  • /var/lib/apt/extended_states
  • /var/lib/aptitude/pkgstates
  • Any other files you care of (DB, web files, /home files etc.)

Do evaluate ”what if” in case you should be forced to reboot from the console terminal and the off/on button on your box.

If things go wrong this is the link you need.

Start doing your upgrade.

Change the sources to squeeze:

less /etc/apt/sources.list

Substitute any occurrence of lenny with squeeze. Don’t use stable, to avoid getting into troubles at the next version upgrade, write squeeze. Codenames are unique, category names are not.

Also remove sources for debian-volatile that are no longer used. Be sure to have all of main, contrib and non-free (for network cards firmware)

Here are my sources :

deb http://ftp.de.debian.org/debian/ squeeze main contrib non-free
deb-src http://ftp.de.debian.org/debian/ squeeze main contrib non-free

deb http://security.debian.org/ squeeze/updates main contrib non-free
deb-src http://security.debian.org/ squeeze/updates main contrib non-free

deb http://ftp.de.debian.org/debian squeeze-updates main contrib non-free
deb-src http://ftp.de.debian.org/debian squeeze-updates main contrib non-free
Ctrl-c
Y

Record your upgrade session with

script -t 2>~/upgrade-squeeze1.time -a ~/upgrade-squeeze1.script

When finishd you’ll stop recording typing: ”exit” Timing info is in the .time file, you can see all what happened and console messages reading the .script file.

Now enter:

apt-get update
apt-get upgrade

(we’re only doing a minimal upgrade now)

You might need to open an extra terminal during the upgrade to examine some situations as to be able to reply to questions posed to you by the upgrade process. To do so type

Alt-right arrow.

2. Upgrade Kernel and Udev

Upgrade the kernel
Start by finding a suitable linux kernel image

apt-cache search linux-image-2.6.

And choose one that suits your architecture and is equal or older to linux-image-2.6.26-2

apt-get install linux-image-2.6-<your flavor>

Although you had non-free among your sources you might end up into the following situation, due to bad handling of firmwares by the installer:

W: Possible missing firmware /lib/firmware/tigon/tg3_tso5.bin for module tg3
W: Possible missing firmware /lib/firmware/tigon/tg3_tso.bin for module tg3
W: Possible missing firmware /lib/firmware/tigon/tg3.bin for module tg3

In this case install manually the nonfree firmware package:

apt-get install firmware-linux-nonfree

And you google about it to be reassured that you’ll have the correct driver installed anyway.

In another case I got the corresponding message for another driver:

This system is currently running Linux 2.6.26-2-686 and you are installing Linux 2.6.32-5-686.
In the new version some of the drivers used on this system may require additional firmware files:
r8169: rtl_nic/rtl8168d-2.fw, rtl_nic/rtl8168d-1.fw

choose not to do anything, however I ended up anyway with a well functioning Debian, go figure it!

Install the new version of udev

apt-get install udev

stop the script recording by entering ”exit”
Reboot the system.

Restart recording in a different filename with

script -t 2>~/upgrade-squeeze2.time -a ~/upgrade-squeeze2.script

3. Optionally Upgrade Your Critical Packages

For extra control, on a production machine, upgrade some individual packages by their own.

apt-get dist-upgrade <package-name>

Go on doing the full upgrade

4. Complete the Upgrade

apt-get dist-upgrade

Do the various configuration as asked during the process, if you choose to upgrade to the configuration  (which is recommended) you can always retrieve the old configuration in the .dpkg-old version of your config files.

Enjoy your new Debian.

The Risk Of “Don’t Make Me Think”

April 22nd, 2011

Or, when the knowledge should be in the box, that you call your company

We have (almost) all heard about the Amazon cloud outage at the North Virginia data center, and for sure we have been hearing many bloggers’ thoughts about it. Here is my take at it.

Disclaimer: all what I write doesn’t aspire to a general validity, it only tries to have a very special validity for my own approach to producing web applications and IT services, and at being an entrepreneur in general. The current hyperspace event is a very good opportunity to double check the concept of ”Don’t make me think”.

As Leon Katsnelson writes, this outage has shown how many companies use cloud computing. The question to me is not whether this is a good or a bad thing, or whether they should have bought a different sevice from Amazon, the question to me is more whether they are at all aware of it.

Cloud computing as a business model has taken some knowledge out of the companies and has collected it inside the service itself. Cloud computing has taken on because of the “don’t make me think” drive.  Together with  the knowledge, what has been thrown out of the companies, are also a lot worries and that is what  companies pay for, they pay to be able to think about something else than computing.

This is all right and well, in the end “Don’t make me think” is what all businesses sell in a way or the other. However some business should rather re-think what their core business is.

I by pure chance know of at least one company that has been down due to this outage, and whose very business is selling backup services. And they not only sell to final customers, they sell to resellers. This means that many, and many companies, whose business, among other things, is selling continual availability of data, have been down for over 24 hours, and without having any chance to do anything about it, for themselves or for their customers.

The lesson: when you sell “Don’t make me think” it should be based on your own knowledge of what’s in the box. If you sell a box that you bought from someone else that bought it from someone else that … you got it, then you not only take the thinking out of the equation, but also the responsibility, and that’s overselling.

Differently from Leon Katsnelson, I think that there are other options than buying cloud computing from Amazon, whether it is with a silver lining or not: one is to build your own cloud, the technology is readily available and if your business is backup services, the knowledge too should be in your own box.