Monday, November 9, 2015

Install Memcached (Caching Server) on RHEL/CentOS 6.3/5.8 and Fedora 17-12

What is Memcached?

Memcached is an open source distributed memory object caching program that allows us to improve and speeding up performance of dynamic web applications by caching data and objects in Memory. Memcached is also used to cache entire database tables and queries to improve performance of database. It is the only one caching system available freely and used by many big sites like YouTube, Facebook, Twitter, Reddit, Drupal, Zynga etc.

Enable EPEL repository under RHEL/CentOS 6.3/5.8

The fastest and easiest way to install and enable EPEL repository using YUM. First, select the RPM that matches your Linux OS architecture from the provided links and install it using method shown in below. The EPEL repo will install all the required dependency packages for memcached. (Note : Fedora doesn’t required EPEL repo, because it is part of fedora project).

For RHEL/CentOS 6 ( 32-Bit )

# wget http://mirrors.kernel.org/fedora-epel/6/i386/epel-release-6-7.noarch.rpm
# rpm -Uvh epel-release-6-7.noarch.rpm

For RHEL/CentOS 6 ( 64-Bit )

# wget http://mirrors.kernel.org/fedora-epel/6/x86_64/epel-release-6-7.noarch.rpm
# rpm -Uvh epel-release-6-7.noarch.rpm

For RHEL/CentOS 5 ( 32-Bit )

# wget http://mirrors.kernel.org/fedora-epel/5/i386/epel-release-5-4.noarch.rpm
# rpm -Uvh epel-release-5-4.noarch.rpm

For RHEL/CentOS 5 ( 64-Bit )

# wget http://mirrors.kernel.org/fedora-epel/5/x86_64/epel-release-5-4.noarch.rpm
# rpm -Uvh epel-release-5-4.noarch.rpm

Install Memcached

Install Memcached program by using following command with YUM tool.
# yum install memcached
Sample Output
Loaded plugins: fastestmirror
Determining fastest mirrors
epel: kartolo.sby.datautama.net.id
Dependencies Resolved

=====================================================================================================
 Package   Arch    Version     Repository     Size
=====================================================================================================
Installing:   
memcached   i386    1.4.5-1.el5    epel      71 k

Transaction Summary
=====================================================================================================
Install       1 Package(s)
Upgrade       0 Package(s)

Total download size: 71 k
Is this ok [y/N]: y
Downloading Packages:
memcached-1.4.5-1.el5.i386.rpm             |  71 kB     00:00
Running rpm_check_debug
Running Transaction Test
Finished Transaction Test
Transaction Test Succeeded
Running Transaction
  Installing     : memcached                        1/1

Installed:
  memcached.i386 0:1.4.5-1.el5

Complete!

Configure Memcached

Open the file called /etc/sysconfig/memcached with VI editor.
# vi /etc/sysconfig/memcached
Set or update parameters as follows, save the file and exit.
# Running on Port 11211
PORT="11211"

# Start as memcached daemon
USER="memcached"

# Set max simultaneous connections to 1024
MAXCONN="1024"

# Set Memory size to 2048 - 4GB(4096)
CACHESIZE="2048"

#Set server IP address
OPTIONS="-l 127.0.0.1"
Let’s discuss each of the above parameters in details.
  1. PORT : The port used by memcached to run.
  2. USER : The start-up daemon for memcached service.
  3. MAXCONN : The value used to set max simultaneous connections to 1024. For busy web servers you can increase to any number based on your requirements.
  4. CACHESIZE : Set cache size memory to 2048. For busy servers you can increase upto 4GB.
  5. OPTIONS : Set IP address of server, so that Apache or Nginx web servers can connect to it.

Start Memcached

Type the following commands to start and restart the Memcached daemon.
# chkconfig --levels 235 memcached on
# /etc/init.d/memcached start
# /etc/init.d/memcached restart
To stop and check status, use the following commands.
# /etc/init.d/memcached stop
# /etc/init.d/memcached status

Verify Memcached

Use netstat command to verify Memcached is running.
# netstat -tulpn | grep :11211

tcp        0      0 127.0.0.1:11211             0.0.0.0:*                   LISTEN      20775/memcached
udp        0      0 127.0.0.1:11211             0.0.0.0:*                               20775/memcached
Check the stats of the server using memcached-tool.
# memcached-tool 127.0.0.1 stats

Install Memcached PHP extension

Now, install PHP extension to work with Memcached daemon.
# yum install php-pecl-memcache

Install Memcached Perl Library

Install perl library for Memcached.
# yum install perl-Cache-Memcached

Install Memcached Python Library

Install python library for Memcached.
# yum install python-memcached

Restart Apache

Restart the Apache service to reflect changes.
# /etc/init.d/httpd restart
OR
# service httpd restart

Configure Firewall to Secure Memcached Server

Make sure you only have access to memcached server, to enable access to your own servers open file called /etc/sysconfig/iptables.
# vi /etc/sysconfig/iptables
Append the following iptables rules to allow access to your own servers.
## Enable access on IP ranges from 172.16.1.1 to 172.16.1.10 for Port 11211 ##
# iptables -A INPUT -p tcp --destination-port 11211 -m state --state NEW  -m iprange --src-range 172.16.1.1-172.16.1.10 -j ACCEPT
# iptables -A INPUT -p udp --destination-port 11211 -m state --state NEW  -m iprange --src-range 172.16.1.1-172.16.1.10 -j ACCEPT
Restart the iptables service to reflect changes.
# service iptables restart
OR
# /etc/init.d/iptables restart

Cache MySQL Queries with Memcached

It isn’t an easy task for all, you need to use API’s to modify your PHP codes to enable MySQL caching. You can find the examples codes at Memcache with MySQL and PHP.

Enable Memcached on WordPress Sites

For WordPress based sites, there is a plugin called Memcached Object Cache that you need to install it on your WordPress CMS.

Wednesday, April 15, 2015

How to permanently disable http_proxy

When I remove proxy from System/Network and apply it system wide it still remains when working in console. When I run:

env | grep proxy

it prints:

http_proxy=http://proxy.studnet.lan:8080
ftp_proxy=ftp://proxy.studnet.lan:8080
socks_proxy=socks://proxy.studnet.lan:8080
https_proxy=https://proxy.studnet.lan:8080
 
I could remove it with:

unset http_proxy
unset ftp_proxy
unset socks_proxy
unset https_proxy
 
but it's not permanent, when I reopen terminal these proxy variables are again setted.

How to remove them permanently?

Friday, February 27, 2015

The form dialog for input

Example

  • Create a shell script called useradd1.sh:
#!/bin/bash
# useradd1.sh - A simple shell script to display the form dialog on screen
# set field names i.e. shell variables
shell=""
groups=""
user=""
home=""
 
# open fd
exec 3>&1
 
# Store data to $VALUES variable
VALUES=$(dialog --ok-label "Submit" \
   --backtitle "Linux User Managment" \
   --title "Useradd" \
   --form "Create a new user" \
15 50 0 \
 "Username:" 1 1 "$user"  1 10 10 0 \
 "Shell:"    2 1 "$shell"   2 10 15 0 \
 "Group:"    3 1 "$groups"   3 10 8 0 \
 "HOME:"     4 1 "$home"  4 10 40 0 \
2>&1 1>&3)
 
# close fd
exec 3>&-
 
# display values just entered
echo "$VALUES"
Save and close the file. Run it as follows:
chmod +x useradd1.sh
./useradd1.sh
Sample outputs:

Sunday, February 8, 2015

Text To Speech and Translation Application For Ubuntu Linux - Gespeaker

eSpeak is a compact open source software speech synthesizer for English and other languages, for Linux and Windows. eSpeak uses a "formant synthesis" method. This allows many languages to be provided in a small size. The speech is clear, and can be used at high speeds, but is not as natural or smooth as larger synthesizers which are based on human speech recordings.

eSpeak is available as:
 * A command line program (Linux and Windows) to speak text from a file or from stdin.
 * A shared library version for use by other programs.

Gespeaker is a GTK+ front-end for espeak. It allows to play a text in many languages with settings for voice, pitch, volume, speed and word gap. The text played can also be recorded to WAV file.

Gespeaker supports multiple languages, currently English, Italian, French and Spanish. It works well with both Gnome, XFCE, LXDE environments.

Gespeaker Installation:
Open the terminal and type following command to install Gespeaker:

sudo apt-get install gespeaker
Currently Ubuntu packagers does not include mbrola in the official repositories, Ubuntu users will need to install mbrola and the voices from the Ubuntu Trucchi repository in this way from the terminal type following command:
sudo wget -O /etc/apt/sources.list.d/ubuntutrucchi.list http://www.ubuntutrucchi.it/repository/ubuntutrucchi.list
wget -O - http://www.ubuntutrucchi.it/repository/ubuntutrucchi.asc | sudo apt-key add -
sudo apt-get update 
After successful installation you can open the Gespeaker from the Unity 'Dash'


Using Gespeaker is easy, just enter text in the available text box, select a voice type (male or female), and a language from the drop down list. Click on Play button to hear the playback of the entered text in a selected language. You can also record the sound using the Record option.

Gespeaker also allows to play a text in many languages with settings  for voice, pitch, volume, speed and word gap.

Web File Explorer and Manager - eXtplorer

eXtplorer is a web-based File Manager. You can use it to

 * Copy & Move Files and Directories by Drag&Drop
 * Dynamic Directory Tree with on-demand loading of sub directories
 * Edit Files (with Syntax-Highlighting thanks to EditArea)
 * Rename, Delete or Create new Files and Directories
 * Access Files through FTP or directly (using PHP) to totally overcome permission and file ownership issues
 * Upload or Download files just as you like
 * Create and Extract Archives (ZIP, Tar, Tar/GZ, Tar/BZ)
 * User Management with different permission levels like "View only" or "Edit" and "Admin"
 * installs easily as a component for Joomla!.

All these features are packed into an intuitive Layout which makes working with files very easy. Thanks to the great ExtJS Javascript Library you can drag & drop folders and files, filter directories and sort the file list using various criteria.

You can even use eXtplorer to login to the FTP server (like net2ftp) and work as if you were using an FTP client.

eXtplorer is released under a dual-license: You can choose wether you want to use eXtplorer under the Mozilla Public License (MPL 1.1) or under the GNU General Public License (GNU/GPL). Note that if you decide to distribute/use eXtplorer under the MPL, you are not allowed to use the ExtJS Javascript library.

eXtplorer needs at least PHP 4.3 on the server and an up-to-date browser with Javascript enabled to run. 

Installing eXtplorer:
Open the terminal and type following command to install eXtplorer:

sudo apt-get install extplorer
NOTE: You also need to have Apache installed and configured.

Configure eXtplorer
Once the extplorer package is installed, you need to add an Alias directive to your web server configuration. Under Apache, it's done this way by adding following entry in file - /etc/apache2/mods-enabled/alias.conf
Alias /extplorer /usr/share/extplorer 
Once you have the extplorer package installed in your server, you need to initialise the password authentication system, this can be done using following command:
cat /usr/share/doc/extplorer/example.dot.htusers.php >/etc/extplorer/.htusers.php
Then login into eXtplorer's interface. For most it will be through an URL like this one:
http://<YOURSERVER>/extplorer

Then login as admin / admin. You will then be prompted to change this default password.

Using eXtplorer
On the left of the main screen you can see the directory tree. If you click on a directory in that tree, eXtplorer checks for subdirectories and loads them if existent.

In the Internet Explorer and Firefox you can right-click on a directory and access a context menu with actions you can perform on it. A double-click on a directory allows you to rename it.

The grid in the center of the main screen lists the first 50 files of the currently selected directory. You can display directories in the list by clicking Show Directories in the toolbar. If the directory contains more than 50 files and dirs, you can use the page navigation in the footer of the grid to go to the next page or jump to a page of your choice.

The grid allows you to perform right-clicks on certain files. A right-click opens the context menu - as well as a double-click. Actions which couldn't be executed are grayed out.
You can select multiple files at once using the Ctrl-Key while selecting items in the grid with the mouse or the up- and down- arrow keys.

Web Based Linux Command Line SSH Terminal - Ajaxterm

Ajaxterm is a web based terminal written in python and some AJAX JavaScript for client side.  It can use almost any web browser and even works through firewalls.. It was totally inspired and works almost exactly like http://anyterm.org/ except it's much easier to install.


Ajaxterm Installation:
Ubuntu users can use following command to install Ajaxterm:

sudo apt-get install ajaxterm
Other distribution:
Open the terminal and type following command to install  Ajaxterm:
wget http://antony.lesuisse.org/ajaxterm/files/Ajaxterm-0.10.tar.gz
tar zxvf Ajaxterm-0.10.tar.gz
cd Ajaxterm-0.10
./ajaxterm.py
After successful installation, open your browser and go to http://localhost:8022/ and you should see a SSH terminal screen ...


By default Ajaxterm only listen at 127.0.0.1:8022. For remote access, it is strongly recommended to use '''https SSL/TLS''', and that is simple to configure if you use the Apache web server with mod_proxy module enable.

Here is an configuration example:
Listen 443
NameVirtualHost *:443
    <VirtualHost *:443>
       ServerName localhost
       SSLEngine On
       SSLCertificateKeyFile ssl/apache.pem
       SSLCertificateFile ssl/apache.pem

       ProxyRequests Off
       <Proxy *>
               Order deny,allow
               Allow from all
       </Proxy>
       ProxyPass /ajaxterm/ http://localhost:8022/
       ProxyPassReverse /ajaxterm/ http://localhost:8022/
    </VirtualHost>

Perl Script: Reading the list of files from Directory

There are couple of ways to get the list of files from withing directory.

#1 - Using the built-in Perl glob function
#2 - Using opendir, readdir and closedir

Below Perl script demonstrate the usage of above methods to get the list of files, feel free to copy and use this code.


Source: read_dir.pl
#!/usr/bin/perl

# Method #1 - using the built-in Perl glob function
@filelist = <*>;
foreach $filename (@filelist) {
  print $filename;


# Method #2 - Using opendir, readdir and closedir

$dir = "/home/poison";
opendir(DIR, $dir) || die "Problem reading the dir. \n";

# Read the entire file names into a array
#@filelist = readdir(DIR);

while ($filename = readdir(DIR)) {
  print $filename , "\n";
}
closedir(DIR);

Read more: http://linuxpoison.blogspot.kr/2013/01/perl-script-reading-list-of-files-from.html#ixzz3R9E1JrWt

Perl Script: How to use system defined Error message

There are many Perl defined system variables that you can use in your script, one of them is "$!", When used in a numeric context, holds the current value of errno. If used in a string context, will hold the error string associated with errno.

Below is simple Perl script which prints all available system error message and their corresponding error codes.



Source: error_message.pl

#!/usr/bin/perl
for ($! = 1, $i = 1; $! <= 25; $!++, $i++) {
    $errormsg = $!;
    chomp($errormsg);
    print "$i : $! \n";
}
Output: perl error_message.pl
0001: Operation not permitted
0002: No such file or directory
0003: No such process
0004: Interrupted system call
0005: Input/output error
0006: No such device or address
0007: Argument list too long
0008: Exec format error
0009: Bad file descriptor
0010: No child processes
0011: Resource temporarily unavailable
0012: Cannot allocate memory
0013: Permission denied
0014: Bad address
0015: Block device required
0016: Device or resource busy
0017: File exists
0018: Invalid cross-device link
0019: No such device
0020: Not a directory
0021: Is a directory
0022: Invalid argument
0023: Too many open files in system
0024: Too many open files
0025: Inappropriate ioctl for device

There are many more system error messages, if you want to list all of them, just increase the above loop from 25 to 1000.

Read more: http://linuxpoison.blogspot.kr/2013/01/perl-script-how-to-use-system-defined.html#ixzz3R9DgCzGp

Howto check disk drive for errors and badblocks

badblocks is a Linux utility to check for bad sectors on a disk drive (A bad sector is a sector on a computer's disk drive or flash memory that cannot be used due to permanent damage or an OS inability to successfully access it.). It creates a list of these sectors that can be used with other programs, like mkfs, so that they are not used in the future and thus do not cause corruption of data. It is part of the e2fsprogs project.

It can be a good idea to periodically check for bad blocks. This is done with the badblocks command. It outputs a list of the numbers of all bad blocks it can find. This list can be fed to fsck to be recorded in the filesystem data structures so that the operating system won’t try to use the bad blocks for storing data. The following example will show how this could be done.

From the terminal, type following command:

$ sudo badblocks -v /dev/hda1 > bad-blocks
The above command will generate the file bad-blocks in the current directory from where you are running this command.

Now, you can pass this file to the fsck command to record these bad blocks
$ sudo fsck -t ext3 -l bad-blocks /dev/hda1
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Check reference counts.
Pass 5: Checking group summary information.

/dev/hda1: ***** FILE SYSTEM WAS MODIFIED *****

/dev/hda1: 11/360 files, 63/1440 blocks
If badblocks reports a block that was already used, e2fsck will try to move the block to another place. If the block was really bad, not just marginal, the contents of the file may be corrupted.

Looks at badblocks man pages for more command line options.

Opensource load balancing Software

Linux Virtual Server
The Linux Virtual Server Project is a project to cluster many real servers together into a highly available, high-performance virtual server. The LVS load balancer handles connections from clients and passes them on the the real servers (so-called Layer 4 switching) and can virtualize almost any TCP or UDP service, like HTTP, HTTPS, NNTP, FTP, DNS, ssh, POP3, IMAP4, SMTP, etc. It is fully transparent to the client accessing the virtual service.
Homepage: http://www.LinuxVirtualServer.org/

BalanceNG
BalanceNG is a modern software IP load balancing solution. It is small, fast, and easy to use and setup. It offers session persistence, different distribution methods (Round Robin, Random, Weighted Random, Least Session, Least Bandwidth, Hash, Agent, and Randomized Agent) and a customizable UDP health check agent in source code. It supports VRRP to set up high availability configurations on multiple nodes. It supports SNMP, integrating the BALANCENG-MIB with Net-SNMPD. It implements a very fast in-memory IP-to-location database, allowing powerful location-based server load-balancing.
Homepage:http://www.inlab.de/balanceng/

HAproxy 
HAproxy is a high-performance and highly-robust TCP and HTTP load balancer which provides cookie-based persistence, content-based switching, advanced traffic regulation with surge protection, automatic failover, run-time regex-based header control, Web-based reporting, advanced logging to help trouble-shooting buggy applications and/or networks, and a few other features. Its own event-driven state machine achieves 20,000 hits per second and surpasses GigaEthernet on modern hardware, even with tens of thousands of simultaneous connections.
Homepage:http://haproxy.1wt.eu/

Pen 
Pen is a load balancer for "simple" TCP-based protocols such as HTTP or SMTP. It allows several servers to appear as one to the outside. It automatically detects servers that are down and distributes clients among the available servers. This gives high availability and scalable performance.
Homepage:http://siag.nu/pen/

Crossroads Load Balancer
Crossroads is a daemon running in user space, and features extensive configurability, polling of back ends using wake up calls, status reporting, many algorithms to select the 'right' back end for a request (and user-defined algorithms for very special cases), and much more. Crossroads is service-independent: it is usable for any TCP service, such as HTTP(S), SSH, SMTP, and database connections. In the case of HTTP balancing, Crossroads can provide session stickiness for back end processes that need sessions, but aren't session-aware of other back ends. Crossroads can be run as a stand-alone daemon or via inetd.
Homepage:http://crossroads.e-tunity.com/

balance 
Balance is a simple but powerful generic TCP proxy with round-robin load balancing and failover mechanisms. Its behavior can be controlled at runtime using a simple command line syntax. Balance supports IPv6 on the listening side, which makes it a very useful tool for IPv6 migration of IPv4 only services and servers.
Homepage:http://www.inlab.de/balance.html

Distributor load balancer
Distributor is a software TCP load balancer. Like other load balancers, it accepts connections and distributes them to an array of back end servers. It is compatible with any standard TCP protocol (HTTP, LDAP, IMAP, etc.) and is also IPv6 compatible. It has many unique and advanced features and a high-performance architecture.
Homepage:http://distributor.sourceforge.net/

Pure Load Balancer
Pure Load Balancer is a high-performance software load balancer for the HTTP and SMTP protocols. It uses an asynchronous non-forking/non-blocking model, and provides fail-over abilities. When a backend server goes down, it automatically removes it from the server pool, and tries to bring it back to life later. Pure Load Balancer has full IPv6 support and works on OpenBSD, NetBSD, FreeBSD and Linux.
Homepage:http://plb.sunsite.dk/

Load Balancer Project
The Load Balancer Project is a tool that allows you to balance requests using clusters of servers. The goal is to achieve high availability load balancing with a simple configuration for the load balancer and the network topology. It leaves the servers untouched so the configuration only resides on the load balancer, and it allows you to manage any type of service via a plugin model design and a transparent proxy feature.
Homepage:http://www.jmcresearch.com/projects/loadbalancer/

mod_athena 
mod_athena is an Apache-based application load balancer for large systems. It allows the HTTP server to act as a load balancer either internally to Apache's own mod_proxy (for reverse proxying), or externally to machines querying it. Arbitrary statistics are sent to the engine via a simple GET plus query-string interface, from which it will then make decisions based on chosen algorithms.
Homepage:http://ath.sourceforge.net/

udpbalancer 
Udpbalancer is a reverse proxy that sorts UDP requests from your clients to your servers. It may operate in round-robin, volume balance, and load balance modes.
Homepage:http://dev.acts.hu/udpbalancer/

MultiLoad 
MultiLoad is a load balancer that redirects HTTP requests to pre-defined servers/locations. It gives the provider a way to balance the traffic and hides the real download location. It allows you to manage different version of each download. It is also a load balancing server extension. You can distribute files on some servers so that a downloaded file can be loaded form different servers. These servers can have different priorities to control the active traffic.

How to protect your server from DDos Attack

What is DDos attack:
On the Internet, a distributed denial-of-service (DDoS) attack is one in which a multitude of compromised systems attack a single target, thereby causing denial of service for users of the targeted system. The flood of incoming messages to the target system essentially forces it to shut down, thereby denying service to the system to legitimate users.

There is a perl script which prevent this:
First do the Installation of a simple perl script:

wget http://www.inetbase.com/scripts/ddos/install.sh
chmod 0700 install.sh
./install.sh

Uninstalling:
wget http://www.inetbase.com/scripts/ddos/uninstall.ddos
chmod 0700 uninstall.ddos
./uninstall.ddos

When you run this Perl script, it will then run an netstat command check how many times each IP is connected and if there are more then the number of connections you specified then it will automatically run a command in APF for the IP to be banned.

Monday, January 26, 2015

Building a load-balancing MySQL proxy with TrafficScript

When you need to scale out your MySQL database, replication is a good way to proceed. Database writes (UPDATEs) go to a 'master' server and are replicated across a set of 'slave' servers. Reads (SELECTs) are load-balanced across the slaves.

Overview


MySQL's replication documentation describes how to configure replication:

mysql1.png
MySQL Replication

A quick solution...


If you can modify your MySQL client application to direct 'Write' (i.e. 'UPDATE') connections to one IP address/port and 'Read' (i.e. 'SELECT') connections to another, then this problem is trivial to solve. This generally needs a code update (Using Replication for Scale-Out).

You will need to direct the 'Update' connections to the master database (or through a dedicated Stingray virtual server), and direct the 'Read' connections to a Stingray virtual server (in 'generic server first' mode) and load-balance the connections across the pool of MySQL slave servers using the 'least connections' load-balancing method:

mysql2.pngRouting connections from the application

However, in most cases, you probably don't have that degree of control over how your client application issues MySQL connections; all connections are directed to a single IP:port. A load balancer will need to discriminate between different connection types and route them accordingly.

Routing MySQL traffic


A MySQL database connection is authenticated by a username and password. In most database designs, multiple users with different access rights are used; less privileged user accounts can only read data (issuing 'SELECT' statements), and more privileged users can also perform updates (issuing 'UPDATE' statements).

A well architected application with sound security boundaries will take advantage of these multiple user accounts, using the account with least privilege to perform each operation. This reduces the opportunities for attacks like SQL injection to subvert database transactions and perform undesired updates.

This article describes how to use Stingray Traffic Manager to inspect and manage MySQL connections, routing connections authenticated with privileged users to the master database and load-balancing other connects to the slaves:

mysql3.png
Load-balancing MySQL connections

Designing a MySQL proxy


Stingray Traffic Manager functions as an application-level (layer-7) proxy. Most protocols are relatively easy for layer-7 proxies like Stingray to inspect and load-balance, and work 'out-of-the-box' or with relatively little configuration.

For more information, refer to the article Feature Brief: Server First, Client First and Generic Streaming Protocols.

Proxying MySQL connections


MySQL is much more complicated to proxy and load-balance.

When a MySQL client connects, the server immediately responds with a randomly generated challenge string (the 'salt'). The client then authenticates itself by responding with the username for the connection and a copy of the 'salt' encrypted using the corresponding password:

mysql4.png
Connect and Authenticate in MySQL

If the proxy is to route and load-balance based on the username in the connection, it needs to correctly authenticate the client connection first. When it finally connects to the chosen MySQL server, it will then have to re-authenticate the connection with the back-end server using a different salt.

Implementing a MySQL proxy in TrafficScript


In this example, we're going to proxy MySQL connections from two users - 'mysqlmaster' and 'mysqlslave', directing connections to the 'SQL Master' and 'SQL Slaves' pools as appropriate.

The proxy is implemented using two TrafficScript rules ('mysql-request' and 'mysql-response') on a 'server-first' Virtual Server listening on port 3306 for MySQL client connections. Together, the rules implement a simple state machine that mediates between the client and server:

mysql5.png
Implementing a MySQL proxy in TrafficScript

The state machine authenticates and inspects the client connection before deciding which pool to direct the connection to. The rule needs to know the encrypted password and desired pool for each user. The virtual server should be configured to send traffic to the built-in 'discard' pool by default.

The request rule:


Configure the following request rule on a 'server first' virtual server. Edit the values at the top to reflect the encrypted passwords (copied from the MySQL users table) and desired pools:

  1. sub encpassword( $user ) {  
  2.    # From the mysql users table - double-SHA1 of the password  
  3.    # Do not include the leading '*' in the long 40-byte encoded password  
  4.    if$user == "mysqlmaster" ) return "B17453F89631AE57EFC1B401AD1C7A59EFD547E5";  
  5.    if$user == "mysqlslave" )  return "14521EA7B4C66AE94E6CFF753453F89631AE57EF";  
  6. }  
  7.   
  8. sub pool( $user ) {  
  9.    if$user == "mysqlmaster" ) return "SQL Master";  
  10.    if$user == "mysqlslave" )  return "SQL Slaves";  
  11. }  
  12.   
  13. $state = connection.data.get( "state" );  
  14.   
  15. if( !$state ) {  
  16.    # First time in; we've just recieved a fresh connection  
  17.    $salt1 = randomBytes( 8 );  
  18.    $salt2 = randomBytes( 12 );    
  19.    connection.data.set( "salt"$salt1.$salt2 );  
  20.   
  21.   
  22.    $server_hs = "\0\0\0\0" .           # length - fill in below  
  23.        "\012" .                        # protocol version  
  24.        "Stingray Proxy v0.9\0" .           # server version  
  25.        "\01\0\0\0" .                   # thread 1  
  26.        $salt1."\0" .                   # salt(1)  
  27.        "\054\242" .                    # Capabilities  
  28.        "\010\02\0" .                   # Lang and status  
  29.        "\0\0\0\0\0\0\0\0\0\0\0\0\0" .  # Unused  
  30.        $salt2."\0";                    # salt(2)  
  31.   
  32.    $l = string.length( $server_hs )-4# Will be <= 255  
  33.    $server_hs = string.replaceBytes( $server_hs, string.intToBytes( $l1 ), 0 );  
  34.   
  35.    connection.data.set( "state""wait for clienths" );  
  36.    request.sendResponse( $server_hs );  
  37.   
  38.    break;  
  39. }  
  40.   
  41. if$state == "wait for clienths" ) {  
  42.    # We've recieved the client handshake.  
  43.    $chs = request.get( 1 );  
  44.    $chs_len = string.bytesToInt( $chs );  
  45.    $chs = request.get( $chs_len + 4 );  
  46.   
  47.    # user starts at byte 36; password follows after  
  48.    $i = string.find( $chs"\0"36 );  
  49.    $user = string.subString( $chs36$i-1 );  
  50.    $encpasswd = string.subString( $chs$i+2$i+21 );  
  51.   
  52.    $passwd2 = string.hexDecode( encpassword( $user ) );  
  53.     
  54.    $salt = connection.data.get( "salt" );  
  55.    $passwd1 = string_xor( $encpasswd, string.hashSHA1( $salt.$passwd2 ) );  
  56.   
  57.    if( string.hashSHA1( $passwd1 ) != $passwd2 ) {  
  58.       log.warn( "User '" . $user . "': authentication failure" );  
  59.       connection.data.set( "state""authentication failed" );  
  60.       connection.discard();  
  61.    }  
  62.   
  63.    connection.data.set( "user",     $user );  
  64.    connection.data.set( "passwd1",  $passwd1 );  
  65.    connection.data.set( "clienths"$chs );  
  66.   
  67.    connection.data.set( "state""wait for serverhs" );  
  68.    request.set( "" );  
  69.   
  70.    # Select pool based on user  
  71.    pool.select( pool( $user ) );  
  72.     
  73.    break;  
  74. }  
  75.   
  76. if$state == "wait for client data" ) {  
  77.    # Write the client handshake we remembered from earlier to the server,  
  78.    # and piggyback the request we've just recieved on the end  
  79.    $req = request.get();  
  80.   
  81.   
  82.    $chs     = connection.data.get( "clienths" );  
  83.    $passwd1 = connection.data.get( "passwd1" );    
  84.    $salt    = connection.data.get( "salt" );  
  85.   
  86.    $encpasswd = string_xor( $passwd1,  
  87.        string.hashSHA1( $salt . string.hashSHA1( $passwd1 ) ) );  
  88.   
  89.    $i = string.find( $chs"\0"36 );  
  90.    $chs = string.replaceBytes( $chs$encpasswd$i+2 );  
  91.   
  92.    connection.data.set( "state""do authentication" );  
  93.    request.set( $chs.$req );  
  94.   
  95.    break;  
  96. }  
  97.   
  98. # Helper function  
  99.   
  100. sub string_xor( $a$b ) {  
  101.    $r = "";  
  102.    while( string.length( $a ) ) {  
  103.       $a1 = string.left( $a1 ); $a = string.skip( $a1 );  
  104.       $b1 = string.left( $b1 ); $b = string.skip( $b1 );  
  105.   
  106.       $r = $r . chr( ord( $a1 ) ^ ord ( $b1 ) );  
  107.    }  
  108.    return $r;  
  109. }  

The response rule


Configure the following as a response rule, set to run every time, for the MySQL virtual server.

  1. $state = connection.data.get( "state" );  
  2.   
  3. $authok = "\07\0\0\2\0\0\0\02\0\0\0";  
  4.     
  5. if$state == "wait for serverhs" ) {  
  6.    # Read server handshake, remember the salt  
  7.    $shs = response.get( 1 );  
  8.    $shs_len = string.bytesToInt( $shs )+4;  
  9.    $shs = response.get( $shs_len );  
  10.   
  11.    $salt1 = string.substring( $shs$shs_len-40$shs_len-33 );  
  12.    $salt2 = string.substring( $shs$shs_len-13$shs_len-2 );  
  13.   
  14.    connection.data.set( "salt"$salt1.$salt2 );  
  15.   
  16.    # Write an authentication confirmation now to provoke the client  
  17.    # to send us more data (the first query).  This will prepare the  
  18.    # state machine to write the authentication to the server  
  19.    connection.data.set( "state""wait for client data" );  
  20.    response.set( $authok );  
  21.   
  22.    break;  
  23. }  
  24.   
  25. if$state == "do authentication" ) {  
  26.    # We're expecting two responses.  
  27.    # The first is the authentication confirmation which we discard.  
  28.    $res  = response.get();  
  29.    $res1 = string.left( $res11 );  
  30.    $res2 = string.skip( $res11 );  
  31.   
  32.    if$res1 != $authok ) {  
  33.       $user = connection.data.get( "user" );  
  34.       log.info( "Unexpected authentication failure for " . $user );  
  35.       connection.discard();  
  36.    }  
  37.   
  38.    connection.data.set( "state""complete" );  
  39.    response.set( $res2 );  
  40.   
  41.    break;  
  42. }  


Testing your configuration


If you have several MySQL databases to test against, testing this configuration is straightforward. Edit the request rule to add the correct passwords and pools, and use the mysql command-line client to make connections:

$ mysql -h zeus -u username -p
Enter password: *******

Check the 'current connections' list in the Stingray UI to see how Stingray has connected each session to a back-end database server.

If you encounter problems, try the following steps:

  • Ensure that trafficscript!variable_pool_use is set to 'Yes' in the Global Settings page on the UI. This setting allows you to use non-literal values in pool.use() and pool.select() TrafficScript functions.
  • Turn on the log!client_connection_failures and log!server_connection_failures settings in the Virtual Server > Connection Management configuration page; these settings will configure the traffic manager to write detailed debug messages to the Event Log whenever a connection fails.

Then review your Traffic Manager Event Log and your mysql logs in the event of an error.

Stingray's access logging can be used to record every connection. You can use the special *{name}d log macro to record information stored using connection.data.set(), such as the username used in each connection.

Conclusion


This article has demonstrated how to build a fairly sophisticated protocol parser where the Stingray-based proxy performs full authentication and inspection before making a load-balancing decision. The protocol parser then performs the authentication again against the chosen back-end server.

Once the client-side and server-side handshakes are complete, Stingray will simply forward data back and fro between the client and the server.

This example addresses the problem of scaling out your MySQL database, giving load-balancing and redundancy for database reads ('SELECTs'). It does not address the problem of scaling out your master 'write' server - you need to address that by investing in a sufficiently powerful server, architecting your database and application to minimise the number and impact of write operations, or by selecting a full clustering solution.


The solution leaves a single point of failure, in the form of the master database. This problem could be effectively dealt with by creating a monitor that tests the master database for correct operation. If it detects a failure, the monitor could promote one of the slave databases to master status and reconfigure the 'SQLMaster' pool to direct write (UPDATE) traffic to the new MySQL master server.

Acknowledgements


Ian Redfern's MySQL protocol description was invaluable in developing the proxy code.

Appendix - Password Problems?


This example assumes that you are using MySQL 4.1.x or later (it was tested with MySQL 5 clients and servers), and that your database has passwords in the 'long' 41-byte MySQL 4.1 (and later) format (see http://dev.mysql.com/doc/refman/5.0/en/password-hashing.html)

If you upgrade a pre-4.1 MySQL database to 4.1 or later, your passwords will remain in the pre-4.1 'short' format.

You can verify what password format your MySQL database is using as follows:

mysql> select password from mysql.user where user='username';
+------------------+
| password         |
+------------------+
| 6a4ba5f42d7d4f51 |
+------------------+
1 rows in set (0.00 sec)

mysql> update mysql.user set password=PASSWORD('password') where user='username';
Query OK, 1 rows affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select password from mysql.user where user='username';
+-------------------------------------------+
| password                                  |
+-------------------------------------------+
| *14521EA7B4C66AE94E6CFF753453F89631AE57EF |
+-------------------------------------------+
1 rows in set (0.00 sec)

If you can't create 'long' passwords, your database may be stuck in 'short' password mode. Run the following command to resize the password table if necessary:

$ mysql_fix_privilege_tables --password=admin password

Check that 'old_passwords' is not set to '1' (see here) in your my.cnf configuration file.

Check that the mysqld process isn't running with the --old-passwords option.

Finally, ensure that the privileges you have configured apply to connections from the Stingray proxy. You may need to GRANT... TO 'user'@'%' for example.

Thursday, January 8, 2015

How to create Ubuntu Live CD/DVD using Remastersys

This tutorial is for creating a Live CD/DVD based on Ubuntu 12.04. You can also try latest version of Ubuntu Live CD/DVD by using the following instructions.

Step 1
Install Ubuntu 12.04 in a PC or inside a Virtual Box application.
Upgrade the system by installing latest packages, apply the following commands,

sudo su
apt-get update
apt-get upgrade

Install the additional applications (e.g. Gimp) for your Live CD/DVD.

Step 2
You can remove following packages to reduce the size of final ISO file.
 apt-get remove libreoffice-help-en-us ubuntu-docs thunderbird smbclient rhythmbox totem deja-dup gnome-orca transmission-gtk 

Remove games, 

sudo apt-get purge aisleriot gnome-sudoku mahjongg ace-of-penguins gnomine gbrainy


Remove the unnecessary packages deposited in cache using Bleachbit. Otherwise the size of Live DVD will be heavy. Bleachbit can remove lot of junk files and save space. Install Bleachbit using the following command,

apt-get install bleachbit

Open Bleachbit from Applications > System Tools 



To use Bleachbit, see the documentation here.

Few more tips too make your Live DVD good,

Disable Apport to prevent unwanted system messages.

Open following file and fine the entry enabled=1 change to enabled=0.

sudo gedit /etc/default/apport 

You can change boot splash to text mode. Open following file

gedit /etc/default/grub
  
and find following line,

GRUB_CMDLINE_LINUX_DEFAULT="quiet splash" 

Remove the entry "quite splash", save file and close. 


Step 3
Installation of Remastersys in Ubuntu 12.04. Apply the following commands.

sudo su
wget -O - http://www.remastersys.com/ubuntu/remastersys.gpg.key | apt-key add -

gedit /etc/apt/sources.list


Add the following lines in the file, save and close.

#Remastersys Precise
deb http://www.remastersys.com/ubuntu precise main


Update the package repository and install Remastersys

apt-get update
apt-get install remastersys remastersys-gtk

Remastersys will appear in Applications > System Tools > Administration 
   
See the screen shots below,

Main screen of Remastersys.



You can assign a name for Live DVD.



You can export user settings to Live DVD. It means, you can assign an inbuilt user name and password for DVD.


You can click on appropriate buttons to build Live DVD. You need Internet connection to run Remastersys. Certain packages to be installed from Internet to build the Live DVD. The output will be in .iso format, you can locate it from /home/remastersys. Burn the .iso file in a DVD and boot from computer.