Aug 13 2008

Wordpress: Using a Cron job to keep things safe

NOTE:
This is maybe not suitable for WPMU

DOWNLOAD:
WordPress Backup with Cron.pdf

Original Links

Using a Cron job to keep things safe

What it does:

At midnight every night, the core WordPress tables are backed up, compressed and emailed to you. The backed up file is then deleted from the server.

For the script to work, you must have MUTT installed on your server. Ask your host about this.
Known hosts on which this works: A Small Orange, EMax hosting and Site5. If you know of any others, please let me know ?

Why it does this:

The only backup script I could find that did what I wanted was automysql. Problem was that this backed up the entire database and I wanted to exclude tables involved with stats and spam. There may well be a way to modify automysql but I could not find it. So I put this together.

License:

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
(See the download).

Disclaimer:

I am not responsible if this does anything wrong. Before you install code you should be either familiar with what it does and how, or you should ask someone you trust – with a cron job asking your host is a “Good Thing”.

Cron Job ?

http://en.wikipedia.org/wiki/Cron explains. If you are unsure about Cron, or you need to know if you can run Cron jobs, talk to your host – only they can answer.

NOTE

This ONLY backs up those tables which were created when you installed WP. If keeping all your stats, all your anti-spam settings, your user-online tables, your mostaccessed tables etc etc etc is important, just go use automysql – it is more fully featured. I’m working on the principle that if something catastrophic did happen then all you really want is your posts, comments and links.

The script

In a nutshell it says this: “Get this database, save a copy, compress it, mail it, delete the copy.”

#Set the 4 variables
#Replace what is AFTER the = with the information from your wp-config.php file
#That’s your information on the right okay ?

DBNAME=DB_NAME

DBPASS=DB_PASSWORD

DBUSER=DB_USER

#Keep the ” around your address
EMAIL=”you@your_email.com”

mysqldump –opt -u $DBUSER -p$DBPASS $DBNAME > backup.sql
gzip backup.sql
DATE=`date +%Y%m%d` ; mv backup.sql.gz $DBNAME-backup-$DATE.sql.gz
echo ‘Blog Name:Your mySQL Backup is attached’ | mutt -a $DBNAME-backup-$DATE.sql.gz $EMAIL -s “MySQL Backup”
rm $DBNAME-backup-$DATE.sql.gz

All you need to do is tell it which database and where to send it. Easy :)

See the ‘Blog Name:’ bit ? Put something there to identify it for you. Useful if you have multiple cron running.

You can download the 2.0 script here: http://www.tamba2.org.uk/wordpress/cron/cronjob2.sh

Setting up the script

Complete the details

The script is configured for the default ‘table_prefix’ of wp_
If you changed that prefix at the time of installation, you will need to change it in the script.

Then complete your email details. Remember that you could be getting emails that are over 1MB in size and increasing, and that these will arrive frequently. Be sure that your email account can accommodate these. (Finally ! A use for GMail !)

Uploading the file

You could put this cronjob file in any directory on your website BUT DO NOT.
If you put this in your main directory or a sub-directory (which could be www / htdocs / public_html / mainwebsite_html) it is readable in a browser. Which means I can download it and find out how to access your database. So unless you want to take that risk, DO NOT UPLOAD THIS INTO YOUR MAIN DIRECTORY.

You need to upload the file above your main directory. That way it is not accessible from a browser.

The ‘etc’ directory is one place for this to go. I’ll use my site as an example:
When I login by ftp, I see these:

Click the indicated directory and upload your cron file into it.

Change the file permissions to 711

Now you need to get the PATH for your file.
Login to your blog, click Options, then Miscellaneous. Look at what is in the box for this Destination directory:. It should look something like this

/home/name/public_html/blog/wp-images/

The information you need is everything before the public_html.
Remember – on your host it might be www or htdocs or mainwebsite_html or something very similar.

Your path will therefore be /home/name/etc/cronjob.sh
If you unsure at all, ask your host for the PATH to the directory where you uploaded the file.

Setting the cron job

Your host should offer a way of accessing and setting cron jobs. The screenshots here are for CPanel.

That line of information you just copied ? Paste that where shown.

Now check the other boxes – I get a backup every night at midnight so if you want the same, make the same options highlighted. (If you are considering running the cron job more frequently than once every 24 hours, you must read the Q & A section at the bottom of this page).

Click the button beneath that says “Save Crontab”

That’s it – all done !

Q & A

* I’m still not sure about cron jobs. Will you do it for me ?
o No. Talk to your host, post in their support forums.
* How often can I run this ?
o Ask your host. I can’t see why you would want to run it more than once a day…..
* I’ve stayed up til midnight and nothing has happened !!
o Heh, I did this too. The script kicks in when it gets to midnight on the server. Look in your WordPress options for the Times in the weblog should differ by: and work out when it should arrive
* Can I test it sooner ?
o Yes – just alter it to work “Every 15 minutes” and “Every hour”. It will then send one fairly quickly. Remember to change it back !
* Can I leave the copy on the server too ?
o Yes. Remove the line rm backup-$DATE.sql.gz
Be sure to delete old ones regularly – this is a very fast way to fill server space !
* How do I backup more than one database ?
o You would need to run one cron job per database BUT the script would also need to take account of this and name the saved files appropriately. If you need this, I suggest you look at automysql for your needs.
* It does not work.
o The script tries 2 methods to send the email. If you do not get a backup file, and instead you get an error message, ask your host for advice. I am unable to advise on error messages. I have tested this script many times on my database and have had no untoward effects. Before looking for any help anywhere, check that you have done everything here.
* My backups are massive!
o The script backs up everything – including any stats / spam tables that have the same table prefix.
To reduce the size of the backup so it only gets what is essential then change this

mysqldump –opt -u $DBUSER -p$DBPASS $DBNAME > backup.sql

to

mysqldump –opt -u $DBUSER -p$DBPASS $DBNAME wp_users wp_posts [and all the other table names] > backup.sql

These pages are independent of http://wordpress.org
All design, content & images © Mark 2004/2005/2006/2007. All rights reserved.

subnoto

Aug 13 2008

Wordpress: Upgrading (Not MU Version)

Original Page

DOWNLOAD:
Upgrading WordPress.pdf

Before you get started, make sure you meet the minimum requirements.

Three Step Upgrade

These are the short instructions, if you want more check out the extended upgrade instructions. If you experience problems with the Three Step Upgrade, you may want to review the more detailed upgrade instructions.

For these instructions, it is assumed that your blog’s URL is http://example.com/wordpress/. Note that during the upgrade process access to your blog may not work for your visitors. You may consider a plugin like Maintenance Mode.

Step 0: Before You Get Started

* Just in case something goes wrong, make sure you have a backup. WordPress_Backups is a comprehensive guide.

* Deactivate your plugins. A plugin might not be compatible with the new version, so it’s nice to check for new versions of them and deactivate any that may cause problems. You can reactivate plugins one-by-one after the upgrade.

Step 1: Replace WordPress files

1. Get the latest WordPress. Either download and extract it to your computer or download it directly to the server.

2. Copy the new files to your server, overwriting old files. You may use FTP or shell commands to do so.

NOTE
The wp-content folder requires special handling, as do the plugins and themes folders. You must copy over the contents of these folders, not the entire folder. Copying the entire folder overwrites all your customizations and added content.

Also take care to preserve the wp-config.php file in the root directory, as it contains your database sign-in information. Do note though that usually this will not be a problem since in a new installation the config file will be named wp-config-sample.php.

Step 2: Upgrade your installation

1. Visit the upgrade page. It will be at a URL like http://example.com/wordpress/wp-admin/upgrade.php. This updates your database to be compatible with the latest code, and before you do this your blog might look funny.

Step 3: Do something nice for yourself

If you have caching enabled, your changes will appear to users more immediately if you clear the cache at this point (and if you don’t, you may get confused when you see the old version number in page footers when you check to see if the upgrade worked).

Your WordPress installation is successfully upgraded. That’s as simple as we can make it without Updating WordPress Using Subversion.

Consider rewarding yourself with a blog post about the upgrade, reading that book or article you’ve been putting off, or simply sitting back for a few moments and let the world pass you by.
Troubleshooting

If anything has gone wrong the first thing to do is go through all the steps in our extended upgrade instructions. That page also has information about some of the most common problems we see.

Aug 13 2008

PHP: Create ZIP file with PASSWORD

function zipme ($SOURCE, $PWD) {
$software = “/usr/bin/zip”;
$parameter = “-P”;
$blank = ” “;
$dozip = $software . $blank . $parameter . $blank . $PWD . $blank . $SOURCE . “.zip” . $blank . $SOURCE;
$output = `$dozip`;
return $output;
}

Aug 13 2008

How to create a self-signed SSL Certificate …


… which can be used for testing purposes or internal usage
Source : http://www.akadia.com/services/ssh_test_certificate.html



Overview




The following is an extremely simplified view of how SSL is
implemented and what part the certificate plays in the entire process.


Normal web traffic is sent unencrypted over the Internet. That is,
anyone with access to the right tools can snoop all of that traffic. Obviously, this
can lead to problems, especially where security and privacy is necessary, such as in
credit card data and bank transactions. The Secure Socket Layer is used to encrypt
the data stream between the web server and the web client (the browser).



SSL makes use of what is known as asymmetric cryptography,
commonly referred to as public key cryptography (PKI). With public key
cryptography, two keys are created, one public, one private. Anything encrypted with
either key can only be decrypted with its corresponding key. Thus if a message or
data stream were encrypted with the server’s private key, it can be decrypted only
using its corresponding public key, ensuring that the data only could have come from
the server.


If SSL utilizes public key cryptography to encrypt the data stream
traveling over the Internet, why is a certificate necessary? The technical answer to
that question is that a certificate is not really necessary – the data is secure and cannot easily be decrypted by a third party. However,
certificates do serve a crucial role in the communication process. The certificate,
signed by a trusted Certificate Authority (CA), ensures that the certificate holder
is really who he claims to be. Without a trusted signed certificate, your data may be
encrypted, however, the party you are communicating with may not be whom you think.
Without certificates, impersonation attacks would be much more common.




Step 1: Generate a Private Key




The openssl toolkit is used to generate an RSA Private
Key
and CSR (Certificate Signing Request). It can also be used to generate
self-signed certificates which can be used for testing purposes or internal
usage.



The first step is to create your RSA Private Key. This key is a
1024 bit RSA key which is encrypted using Triple-DES and stored in a PEM format so
that it is readable as ASCII text.



openssl genrsa -des3 -out server.key 1024



Generating RSA private key, 1024 bit long modulus

…………………………………………………++++++

……..++++++

e is 65537 (0×10001)

Enter PEM pass phrase:

Verifying password – Enter PEM pass phrase:



Step 2: Generate a CSR (Certificate Signing Request)




Once the private key is generated a Certificate Signing Request can be generated. The
CSR is then used in one of two ways. Ideally, the CSR will be sent to a Certificate
Authority, such as Thawte or Verisign who will verify the identity of the requestor
and issue a signed certificate. The second option is to self-sign the CSR, which
will be demonstrated in the next section
.


During the generation of the CSR, you will be prompted for several pieces of
information. These are the X.509 attributes of the certificate. One of the prompts
will be for “Common Name (e.g., YOUR name)”. It is important that this field be
filled in with the fully qualified domain name of the server to be protected by SSL.
If the website to be protected will be https://public.akadia.com, then enter
public.akadia.com at this prompt. The command to generate the CSR is as follows:



openssl req -new -key server.key -out server.csr



Country Name (2 letter code) [GB]:CH

State or Province Name (full name)
[Berkshire]
:Bern

Locality Name (eg, city)
[Newbury]
:Oberdiessbach

Organization Name (eg, company) [My Company
Ltd]
:Akadia AG

Organizational Unit Name (eg, section)
[]
:Information Technology

Common Name (eg, your name or your server’s hostname)
[]
:public.akadia.com

Email Address []:martin.zahn@akadia.com

Please enter the following ‘extra’ attributes

to be sent with your certificate request

A challenge password []:

An optional company name []:




Step 3: Remove Passphrase from Key




One unfortunate side-effect of the pass-phrased private key is that Apache will
ask for the pass-phrase each time the web server is started
. Obviously this is
not necessarily convenient as someone will not always be around to type in the
pass-phrase, such as after a reboot or crash. mod_ssl includes the ability to use an
external program in place of the built-in pass-phrase dialog, however, this is not
necessarily the most secure option either. It is possible to remove the Triple-DES
encryption from the key
, thereby no longer needing to type in a pass-phrase. If
the private key is no longer encrypted, it is critical that this file only be
readable by the root user! If your system is ever compromised and a third party
obtains your unencrypted private key, the corresponding certificate will need to be
revoked. With that being said, use the following command to remove the pass-phrase
from the key:


cp server.key server.key.org

openssl rsa -in server.key.org -out server.key



The newly created server.key file has no more passphrase in it.


-rw-r–r– 1 root root 745 Jun 29 12:19 server.csr

-rw-r–r– 1 root root 891 Jun 29 13:22 server.key

-rw-r–r– 1 root root 963 Jun 29 13:22 server.key.org




Step 4: Generating a Self-Signed Certificate



At this point you will need to generate a self-signed certificate because you either
don’t plan on having your certificate signed by a CA, or you wish to test your new
SSL implementation while the CA is signing your certificate. This temporary
certificate will generate an error in the client browser to the effect that the
signing certificate authority is unknown and not trusted.



To generate a temporary certificate which is good for 365 days, issue the following
command:



openssl x509 -req -days 365 -in server.csr -signkey server.key -out
server.crt

Signature ok

subject=/C=CH/ST=Bern/L=Oberdiessbach/O=Akadia AG/OU=Information

Technology/CN=public.akadia.com/Email=martin.zahn@akadia.com

Getting Private key



Step 5: Installing the Private Key and Certificate




When Apache with mod_ssl is installed, it creates several directories in the Apache
config directory. The location of this directory will differ depending on how Apache
was compiled.



cp server.crt /usr/local/apache/conf/ssl.crt

cp server.key /usr/local/apache/conf/ssl.key




Step 6: Configuring SSL Enabled Virtual Hosts




SSLEngine on

SSLCertificateFile /usr/local/apache/conf/ssl.crt/server.crt

SSLCertificateKeyFile /usr/local/apache/conf/ssl.key/server.key

SetEnvIf User-Agent “.*MSIE.*” nokeepalive ssl-unclean-shutdown

CustomLog logs/ssl_request_log

“%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \”%r\” %b”



Step 7: Restart Apache and Test




/etc/init.d/httpd stop

/etc/init.d/httpd stop



https://public.akadia.com


Aug 13 2008

Creating ZIP Files on the Spot

This interesting article found on Zend.com will explain to you how to create ZIP files on the fly using PHP.

Terms of Agreement:
By using this article, you agree to the following terms…
1) You may use this article in your own programs (and may compile it into a program and distribute it in compiled format for languages that allow it) freely and with no charge.
2) You MAY NOT redistribute this article (for example to a web site) without written permission from the original author. Failure to do so is a violation of copyright laws.
3) You may link to this article from another website, but ONLY if it is not wrapped in a frame.
4) You will abide by any additional copyright restrictions which the author may have placed in the article or article’s description.
Ever wondered how you could create ZIP files on the fly? In this article, which I found on Zend.com, you’ll be able to. The original version can be found here: http://www.zend.com/zend/spotlight/creating-zip-files2.php

? php

/*

Zip file creation class
makes zip files on the fly…

use the functions add_dir() and add_file() to build the zip file;
see example code below

by Eric Mueller
http://www.themepark.com

v1.1 9-20-01
– added comments to example

v1.0 2-5-01

initial version with:
– class appearance
– add_file() and file() methods
– gzcompress() output hacking
by Denis O.Philippov, webmaster@atlant.ru, http://www.atlant.ru

*/

// official ZIP file format: http://www. // pkware.com/appnote.txt

class zipfile
{

var $datasec = array(); // array to store compressed data
var $ctrl_dir = array(); // central directory
var $eof_ctrl_dir = “\x50\x4b\x05\x06\x00\x00\x00\x00″; //end of Central directory record
var $old_offset = 0;

function add_dir($name)

// adds “directory” to archive – do this before putting any files in directory!
// $name – name of directory… like this: “path/”
// …then you can add files using add_file with names like “path/file.txt”
{
$name = str_replace(”\\”, “/”, $name);

$fr = “\x50\x4b\x03\x04″;
$fr .= “\x0a\x00″; // ver needed to extract
$fr .= “\x00\x00″; // gen purpose bit flag
$fr .= “\x00\x00″; // compression method
$fr .= “\x00\x00\x00\x00″; // last mod time and date

$fr .= pack(”V”,0); // crc32
$fr .= pack(”V”,0); //compressed filesize
$fr .= pack(”V”,0); //uncompressed filesize
$fr .= pack(”v”, strlen($name) ); //length of pathname
$fr .= pack(”v”, 0 ); //extra field length
$fr .= $name;
// end of “local file header” segment

// no “file data” segment for path

// “data descriptor” segment (optional but necessary if archive is not served as file)
$fr .= pack(”V”,$crc); //crc32
$fr .= pack(”V”,$c_len); //compressed filesize
$fr .= pack(”V”,$unc_len); //uncompressed filesize

// add this entry to array
$this -> datasec[] = $fr;

$new_offset = strlen(implode(”", $this->datasec));

// ext. file attributes mirrors MS-DOS directory attr byte, detailed
// at http://support.microsoft.com/support/kb/articles/Q125/0/19.asp

// now add to central record
$cdrec = “\x50\x4b\x01\x02″;
$cdrec .=”\x00\x00″; // version made by
$cdrec .=”\x0a\x00″; // version needed to extract
$cdrec .=”\x00\x00″; // gen purpose bit flag
$cdrec .=”\x00\x00″; // compression method
$cdrec .=”\x00\x00\x00\x00″; // last mod time & date
$cdrec .= pack(”V”,0); // crc32
$cdrec .= pack(”V”,0); //compressed filesize
$cdrec .= pack(”V”,0); //uncompressed filesize
$cdrec .= pack(”v”, strlen($name) ); //length of filename
$cdrec .= pack(”v”, 0 ); //extra field length
$cdrec .= pack(”v”, 0 ); //file comment length
$cdrec .= pack(”v”, 0 ); //disk number start
$cdrec .= pack(”v”, 0 ); //internal file attributes
$ext = “\x00\x00\x10\x00″;
$ext = “\xff\xff\xff\xff”;
$cdrec .= pack(”V”, 16 ); //external file attributes – ‘directory’ bit set

$cdrec .= pack(”V”, $this -> old_offset ); //relative offset of local header
$this -> old_offset = $new_offset;

$cdrec .= $name;
// optional extra field, file comment goes here
// save to array
$this -> ctrl_dir[] = $cdrec;

}

function add_file($data, $name)

// adds “file” to archive
// $data – file contents
// $name – name of file in archive. Add path if your want

{
$name = str_replace(”\\”, “/”, $name);
//$name = str_replace(”\\”, “\\\\”, $name);

$fr = “\x50\x4b\x03\x04″;
$fr .= “\x14\x00″; // ver needed to extract
$fr .= “\x00\x00″; // gen purpose bit flag
$fr .= “\x08\x00″; // compression method
$fr .= “\x00\x00\x00\x00″; // last mod time and date

$unc_len = strlen($data);
$crc = crc32($data);
$zdata = gzcompress($data);
$zdata = substr( substr($zdata, 0, strlen($zdata) – 4), 2); // fix crc bug
$c_len = strlen($zdata);
$fr .= pack(”V”,$crc); // crc32
$fr .= pack(”V”,$c_len); //compressed filesize
$fr .= pack(”V”,$unc_len); //uncompressed filesize
$fr .= pack(”v”, strlen($name) ); //length of filename
$fr .= pack(”v”, 0 ); //extra field length
$fr .= $name;
// end of “local file header” segment

// “file data” segment
$fr .= $zdata;

// “data descriptor” segment (optional but necessary if archive is not served as file)
$fr .= pack(”V”,$crc); //crc32
$fr .= pack(”V”,$c_len); //compressed filesize
$fr .= pack(”V”,$unc_len); //uncompressed filesize

// add this entry to array
$this -> datasec[] = $fr;

$new_offset = strlen(implode(”", $this->datasec));

// now add to central directory record
$cdrec = “\x50\x4b\x01\x02″;
$cdrec .=”\x00\x00″; // version made by
$cdrec .=”\x14\x00″; // version needed to extract
$cdrec .=”\x00\x00″; // gen purpose bit flag
$cdrec .=”\x08\x00″; // compression method
$cdrec .=”\x00\x00\x00\x00″; // last mod time & date
$cdrec .= pack(”V”,$crc); // crc32
$cdrec .= pack(”V”,$c_len); //compressed filesize
$cdrec .= pack(”V”,$unc_len); //uncompressed filesize
$cdrec .= pack(”v”, strlen($name) ); //length of filename
$cdrec .= pack(”v”, 0 ); //extra field length
$cdrec .= pack(”v”, 0 ); //file comment length
$cdrec .= pack(”v”, 0 ); //disk number start
$cdrec .= pack(”v”, 0 ); //internal file attributes
$cdrec .= pack(”V”, 32 ); //external file attributes – ‘archive’ bit set

$cdrec .= pack(”V”, $this -> old_offset ); //relative offset of local header
// &n // bsp; echo “old offset is “.$this->old_offset.”, new offset is $new_offset
“;
$this -> old_offset = $new_offset;

$cdrec .= $name;
// optional extra field, file comment goes here
// save to central directory
$this -> ctrl_dir[] = $cdrec;
}

function file() { // dump out file
$data = implode(”", $this -> datasec);
$ctrldir = implode(”", $this -> ctrl_dir);

return
$data.
$ctrldir.
$this -> eof_ctrl_dir.
pack(”v”, sizeof($this -> ctrl_dir)). // total # of entries “on this disk”
pack(”v”, sizeof($this -> ctrl_dir)). // total # of entries overall
pack(”V”, strlen($ctrldir)). // size of central dir
pack(”V”, strlen($data)). // offset to start of central dir
“\x00\x00″; // .zip file comment length
}
}

?

Example Usage of the Class

? php

$zipfile = new zipfile();

// add the subdirectory … important!
$zipfile -> add_dir(”dir/”);

// add the binary data stored in the string ‘filedata’
$filedata = “(read your file into $filedata)”;
$zipfile -> add_file($filedata, “dir/file.txt”);

// the next three lines force an immediate download of the zip file:
header(”Content-type: application/octet-stream”);
header(”Content-disposition: attachment; filename=test.zip”);
echo $zipfile -> file();

// OR instead of doing that, you can write out the file to the loca disk like this:
$filename = “output.zip”;
$fd = fopen ($filename, “wb”);
$out = fwrite ($fd, $zipfile -> file());
fclose ($fd);

// then offer it to the user to download:
Click here to download the new zip file.

?