Wednesday, October 7, 2009

Ubuntu MySQL 5.x Server

Spinning up new versions of servers at the office to host services. Last night I was tasked with migrating the MySQL server over to a new Ubuntu Server 8.04.3 LTS virtual machine. Lucky me, I have a template of that OS already, so I cloned one up and booted it.

Step 1:

After the cloning process, VMWare gives the virtual machine NIC a new MAC address. Why is this significant? Well, from what I understand, the MAC address is what Linux uses to associate eth0 with that NIC. So, since your NIC no longer has that old MAC address, you have to change /etc/network/interfaces to bring up eth1 instead of eth0. I am not sure how to get eth0 freed up, but it can probably be found with a carefully crafted Google query.

Step 2:

Next thing we want to do is update our Ubuntu Server. This is one of the main reasons why I like ubuntu, its really this simple:

sudo apt-get update
sudo apt-get dist-upgrade

Step 3:

Next order of business is authentication. We like to use integrated Active Directory authentication using Likewise. Its a very cool tool to make your Linux servers authenticate back to Active Directory so you do not have to maintain local /etc/passwd files, or a separate LDAP server.

As a matter of best practice, I always create a local /etc/passwd account. This is for two reasons, first, if AD cannot be found, you cannot logon (remember ubuntu does not give root a password), and second, its always industry best practice when authenticating against an LDAP server to leave a local admin account.

Once that account is added, I add likewise to the ubuntu server with the following command:
sudo apt-get install likewise-open
This is some pretty cool software. I ran a few commands next, the first puts likewise to automatically startup on a boot, so we do not have to do it manually. The second command is the command to join a domain (the 'administrator' can be replaced with any account with privileges to join a system to the domain).

sudo udate-rc.d likewise-open defaults
sudo domainjoin-cli join domain.local Administrator

Now, because I hate prepending my domain name to my username (IE domain\user) when logging in, I want it to just use the default domain name when I put in a username unless otherwise instructed. To do so, I added the following line to the /etc/samba/lwiauthd.conf file, then ran the command to restart likewise.
winbind use default domain = yes
sudo /etc/init.d/likewise-open restart
Then, the final order of business with likewise, I need my domain admins group to be able to sudo, similar to the way users in the admin group can in a default ubuntu installation. To do this, I editted the /etc/sudoers file and added the following line:
%domain^ admins ALL=(ALL) ALL
Step 4:

Next order of business is my nagios monitoring plugins. I use a monitoring tool call nagios to monitor my servers. Nagios has a plugin you can install called nrpe that runs as a local daemon or in xinetd so the monitoring server can send requests to run predefined scripts. This is helpful to obtain data you cannot get from remote, such as load average, disk utilization, etc. Note, I am only installing the client side plugins and remote pole daemon (nrpe), this is by no means a guide to setup a nagios server (maybe a future blog post though :P )

First thing I install is the nrpe-server package. This is the daemon (or xinetd process) that runs to accept remote connections to run predefined scripts and return the results.
sudo aptitude install nagios-nrpe-server
After this is installed, you will need to modify its configuration file located at /etc/nagios/nrpe.cfg. In this file you will setup two things, first there is a directive to specify which IP's are allowed to talk to your nrpe process (this will prevent bad people from monitoring your server without your permission). This is also where you setup your check commands. Nagios uses scripts called check commands to get perfdata from a server, such as disk space and load averages. You setup the scripts that run locally on command from the main nagios server in this file a well. Then, you simply tell your nagios server where this box is and what command to ask it to run.

I installed all the main check commands, then just chose which ones I wanted to use in the nrpe-server's configuration file. Here is how to install the plugins:

sudo apt-get install nagios-plugins nagios-plugins-basic
nagios-plugins-extra nagios-plugins-standard

Nagios should now be able to monitor your server.

Step 5:

Now its time to get our MySQL stuff installed. Once again, time for a shameless plug of "This is why I love Ubuntu":
sudo apt-get install mysql-server mysql-client
You have now installed MySQL server. It will probably ask you to set the mysql root password, try not to forget it.

Next, we'll install a really nifty MySQL admin tool called phpmyadmin. This usually requires you install a bunch of prerequisites, but in this case, its ubuntu-ized, so its just another one liner:
sudo apt-get install phpmyadmin
If you do not already have a web server installed, it will automatically install apache2 for you. After installation, it will launch an automatic configuration tool which will ask what web server to configure. Select apache2 if you did not have a web server installed prior. If you did, tell it which one.

The last couple of tasks are to enable some users for this SQL server and allow other hosts to connect to it.

We'll start with enabling some users. Here is the quick and dirty dev server way to do it. Please do not use this in real environments. I am not going to dive off into database security, just know this'll work for a nice little sandbox, not a production environment.
mysql -u root -p
CREATE USER 'user'@'%' IDENTIFIED BY
'password';
GRANT ALL PRIVILEGES ON *.* TO 'user'@'%';

Now that we have a user that can connect from any IP (thats what the % means) we need to tell the MySQL server to listen on an interface other than 127.0.0.1. By default, MySQL only listens on the localhost IP for security. In this instance, I need a database server to connect to it. There is a line that looks like this:
bind-address = 127.0.0.1

You are going to want this to be this server's (the MySQL server, not the web server) IP address. This is telling it what Ip addresses to listen on (do not mistake this with listen to). If you just comment this line out, MySQL will listen on all IP addresses of the host.

Step 6:

Now its migration time. What I do for migrations is do a mysqldump of the database, then import it on the other side from the dump file it produces. The mysqldump command will produce a file that goes one by one through your database tables, dumps them if they exist, creates the table, then inserts all the data into it. The output is really just one giant text file that can recreate your entire database.

If you are on a production system, its probably a good idea to stop any service leveraging the database, then bounce the database server to make sure all your writes are finished. Once this is done, we can use this command to dump a copy out:
mysqldump --add-locks --user=root --password=password --all -c dbname >
/path/to/dbname-backup.sql
Move this file over to the new MySQL server. We now add two lines to the top of the file:
create database dbname;
use dbname;
This will create our database and use it so we can create the tables and insert the data from the file. All we need to do is pipe the file into a mysql prompt:
mysql -u root -p < /path/to/dbname-backup.sql
Run some tests, everything should be happy. Our database is migrated over to our new server.

Step 7:

Finally, we need to ensure we are backing up our database. I created a little backup script that I use based off our migration command. Most people have solutions from their backup suites that work, I actually use both this and our suite. I think this is one of the easiest to restore backups (see Step 6 migration). Its adding 2 lines to a text file, then a 1 line command at a prompt to restore your database, can't beat that. I just run the script in cron. Please note, if you want to use the scp portion, the user running the script in cron needs a preshared RSA key with the remote backup server.
# set date format
date=`date '+%m%d%y'`
# dump database
mysqldump --add-locks --user=user --password=password --all -c dbname
> /path/to/dbname-backup-$date.sql
# compress backup file
gzip -9 /path/to/dbname-backup-$date.sql
# secure copy to backup server
scp /path/to/dbname-backup-$date.sql.gz user@backupserver.domain.local:/path/to/backup/dir
# if scp to fileserver failed, email me about it
if [ $? -gt 0 ]
then
mail -s "Development dbname
MySQL Backup Failed" emailalias@domain.local < /dev/null exit fi # remove local copy rm /path/to/dbname-backup-$date.sql.gz
Toss that into a script and put it in cron on an interval of choice. Its moving the backup off to another server and notifying you if the file does not move over correctly.

Thats all there is to it. We built a brand new server to host MySQL, have it authenticating against AD, monitored by our nagios server, backing itself up, and servicing our database needs. Funny part is, it took me longer to do the writeup than it did to do the actual work :)

Friday, October 2, 2009

Auto-start Virtual Machines on Linux

So here is my scenario. I have a redhat EL5 machine running vmware workstation 6.5. We had a power outage while I was out of town and these dev/test boxes are not on the UPS, DOH! Well, the developers at this point had to figure out how to start the virtual machines on this box by themselves. So, when I returned, my first task was to ensure that these virtual machines startup automatically within vmware workstation.

So, the first thing I did was figure out how to get the virtual machines to start with the vmrun command. The first thing I learned was that I needed a line added to the vmx file to ensure the question prompts will not hold up the virtual machine from starting without the GUI to see the question that Vmware wants answered. To do this, I added the following line to my vmx file so that vmware will automatically select the default answer to any questions it may have.

msg.autoAnswer = "TRUE"

So, now I was able to figure out using helpfiles and some carefully crafted google queries that you can start a virtual machine in vmware workstation with the following command in headless mode (IE, no DISPLAY variable set).

vmrun start nogui

After figuring this out, I need to create an init script to start this up. The first thing that popped in my mind is the fact that I do not want these VM's starting under the root user, so I adapted my vmrun command for the script to look like this:

su - rivey -c "vmrun start nogui"

This will use the switch user command to run the command in parenthesis as the user I specify. I then snatched up the sshd init script, stripped all the junk I didn't need out, and finished with the following:
#!/bin/bash
#
# Init file for start Virtual Machines
#
# will start the following VM's
# /vms/Solaris10/Solaris10.vmx
# /vms/DC01/DC01.vmx
# /backup/vms/oraresource/oraresource.vmx
# /backup/vms/WindowsMemberServer/WindowsMemberServer.vmx
#
# source function library.
/etc/rc.d/init.d/functions

RETVAL=0
prog="vmware-vms"

#Location of vmx files
VM1=/vms/Solaris10/Solaris10.vmx
VM2=/vms/DC01/DC01.vmx
VM3=/backup/vms/oraresource/oraresource.vmx
VM4=/backup/vms/WindowsMemberServer/WindowsMemberServer.vmx

VMRUN=/usr/bin/vmrun

runlevel=$(set -- $(runlevel); eval "echo \$$#" )

start()
{
echo -n $"Starting $prog: Solaris10 "
su - rivey -c "$VMRUN start $VM1 nogui"
RETVAL=$?
[ "$RETVAL" = 0 ]
echo

echo -n $"Starting $prog: DC01 "
su - rivey -c "$VMRUN start $VM2 nogui"
RETVAL=$?
[ "$RETVAL" = 0 ]
echo

echo -n $"Starting $prog: oraresource "
su - rivey -c "$VMRUN start $VM3 nogui"
RETVAL=$?
[ "$RETVAL" = 0 ]
echo

echo -n $"Starting $prog: WindowsMemberServer "
su - rivey -c "$VMRUN start $VM4 nogui"
RETVAL=$?
[ "$RETVAL" = 0 ]
echo
}

stop()
{

echo -n $"Stopping $prog: Solaris10 "
su - rivey -c "$VMRUN stop $VM1 nogui"
RETVAL=$?
[ "$RETVAL" = 0 ]
echo

echo -n $"Stopping $prog: DC01 "
su - rivey -c "$VMRUN stop $VM2 nogui"
RETVAL=$?
[ "$RETVAL" = 0 ]
echo

echo -n $"Stopping $prog: oraresource "
su - rivey -c "$VMRUN stop $VM3 nogui"
RETVAL=$?
[ "$RETVAL" = 0 ]
echo

echo -n $"Stopping $prog: WindowsMemberServer "
su - rivey -c "$VMRUN stop $VM4 nogui"
RETVAL=$?
[ "$RETVAL" = 0 ]
echo
}

case "$1" in

start)
start
;;

stop)
stop
;;

*)
echo $"Usage: $0
{startstop}"

RETVAL=1
esac
exit $RETVAL

Now, a few things to point out. The first is pretty obvious, this script is starting and stopping 4 different VM's. The second, this is by no means the cleanest way of doing this and probably not the best script in the world, but it was a pretty nice little thrown together script to get the job done. Quick and dirty. Initial tests show the script is working like a champ. I tossed the script in /etc/init.d, threw the executable bit on, then sym linked it into rc3.d and rc5.d.

Friday, July 24, 2009

Symantec NBU for Windows Class Build

Here at GCA we run classes for multiple vendors. I was tasked with creating the class build for the Symantec Netbackup 6.5 for Windows class. The hardware we are using, however, is all virtual. We are using a Netapp VTL and VMWare ESX Server in order to create the student systems. The hardware we are virtualizing on lives at our Tampa office while the class is going to be run from our Seattle office.

The build starts out pretty simple. I spun up some instances of Windows server 2003, patched them up, and made them ready to be cloned for student systems. On the netapp VTL, I created a bunch of Robots and Tape devices, which are emulating a StorageTek T9840C. I added 16 tapes, 8 on one serial format and 8 on another (as requested by Symantec). I then dropped a couple HBA's into the ESX Server and connected them to the VTL (we had plenty of HBA's laying around so the Multipathing and redundancy is nice to have seeing as how we are going to share the HBA's for all of the systems).

There were a few things that threw me. The first one was how to match up the Robot and Tape drives on each machine. When I connected the HBA's and added a new SCSI device to the VM, the pulldown list just had them by name, so I saw 8 Robots and 16 drives with no information regarding which was which. They were also not in any specific order.

To figure this out, I SSH'd over to the service console of the ESX Server and did an ls -al on the devices directory that contained all of the targets. This matched a sym link that had the LUN target directly to a ridculously long unique number identifier. This long number also shows after you add the SCSI device to vmware if you hover over it in the edit settings window.

The next thing I tripped over a bit was making it to where two virtual machines had access to the same SCSI device. The way this is done is by modifying the SCSI controller used to a different type. In edit virtual machine settings, if you click on the SCSI controller, you can change it so that the SCSI devices can be shared. The only problem is this change is globally on the SCSI controller, so to make this not problematic for the other SCSI devices, such as the windows C: drive, I moved the VTL SCSI devices over to a different SCSI id (1:0 instead of 0:3). This will make vmware automatically add a new SCSI controller to the box. This one I made the change and everything was happy.

The next thing I bumped into was our firewall. For whatever reason our checkpoint vpn tunnels are not setup correctly. I could not figure out how to allow the Seattle DMZ network to talk to the Tampa DMZ network over tcp/3389 (RDP). After spending some time trying to figure it out, I used a work around. I had 4 consecutive external IP's available, so I simply NAT'd these boxes out to the edge, allowed our Seattle office's external IP to RDP in on those external IP's and had it work that way instead of figuring out the VPN tunnel madness.

The last headache to figure out was the driver for the tape devices. The funny part is this is a chicken and egg problem. In order to get the driver for the tape drives installed, I need netbackup installed (it uses a symantec halfinch.sys driver). Well, during the install for the configuration portion, it wants the tape devices to be installed to configure them. In order to remedy this, Symantec added a pause mechanism to their setup scripts so the user can pause the install after the drivers are present on the system, install the tape devices from device manager, then continue the install.

On the day of the class everything ran smoothly. The only thing I forgot to do was to populate the host files of each system with the IP information on the other machines in the 'classroom'. This wasn't a big deal, the instructor was able to figure it out and work through it.

Class ran, students seemed to be happy from what I understand, and now I have a template for this build as well as the procedure (this is why I blog this stuff!) to build it back up again.

Thursday, July 23, 2009

Print to Fax

Our Toshiba eStudio series printer has the capability to print directly to fax. While the technology is cool, I think it is lacking a few features that I would like to see.

The user experience is pretty solid. When they are looking at something on their screen they want to fax, just act like you are printing it, select the Fax Printer from your printers list, enter the phone number, select a generic cover letter, enter the rest of the properties for the cover letter and fire away. Another neat little feature is the address book it has for faxing information. All of this is integrated into our AD domain, so I can shell out the driver from a windows print server and not have to worry about running around with a CD to everyones computer.

While its all fine and dandy, here are the shortcomings that I ran into. The AD integration works great, however, th little address book tool must be installed on each individual PC. The address book is also lacking the capability to integrate with my outlook/exchange account to pull my local contacts. It will integrate through MAPI to my Global Address List in AD, but that doesn't help since we do not store customer or vendor information in AD. This also eliminates the LDAP connector as well. I would like to have a centralized version of the address book for the 'private version' and/or have full integration with exchange/outlook local address books.

Another part that I found a bit annoying was the coversheets. I wish we could take an existing word document, insert special fields into the word document so that the printer can do a replace on those fields with the appropriate information field and give us the ability to do a custom coversheet.

If those features were available it would make faxing just that much smoother in my environment. People could either populate an existing shared address book in the domain and/or have the ability to use their local contacts in outlook/exchange to use for faxing. We would also be able to use our custom GCA coverletter for the faxing as well.

I can't really complain though, its an upgrade for sure. Just wish printing companies could keep up with network technologies a little better.

Version Control for Sharepoint / Project Server

We have a project server and I was asked to investigate the version control capabilities of the server. After doing some Googling on the subject, I was able to find an article that walked me through how to enable document version control on a sharepoint 2007 document library. It was actually very simple. All I had to do was on the root of the document library, click on settings. The link for the settings of the document library contained another link for version control settings. I clicked this link, turned on major and minor revisions and selected the option to force checkout when editting a document.

The neat part is, when a user opens a document for editting, it will automatically checkout that document (to prevent others from editting it). The other cool part is it saves a new minor revision every time a user saves it, also giving the user the ability to insert comments. It shows which user editted it, what time it was editted, and a slew of other information. The major revs are controlled by users simply selecting "Create new major revision" from a pulldown menu on the sharepoint site when looking at the document.

I think its very solid document management. Very intuitive to use. I have to admit, Microsoft actually did something right. If you know me, I typically am on the Microsoft hate bandwagon, but the project server product with sharepoint version control is pretty sweet.

Monday, July 13, 2009

CentOS NetInstall

The CentOS DVD finished downloading over the weekend. I went ahead and burned it to a DVD and popped it into the Dell PowerEdge 2600 Server and booted it. After it skipped the DVD an booted to the OS already on it, I checked BIOS to see the boot order is CD before HDD. I took a closer look at the drive, its CD only.. DOH!

So, instead of starting the download process all over, which will take another full day of downloading, I've decided that I will go a different route and install CentOS using an NFS mount point from a linux server that has the ISO file mounted on a loopback interface.

The idea behind this is to download a single 8 MB ISO file for the boot CD, then the boot CD can lookup the rest of the installation files from another box over the NFS protocol. First order of business, get NFS Server installed onto my Ubuntu Laptop that I will be using to host out the full distribution. On Ubuntu, this is a pretty simple task.
sudo apt-get install nfs-user-server

When I ran this command, I recieved an error saying "No installable candidate" with a bunch of information about my running kernel. This is just a guess, but I'm going to say that I need to update my Ubuntu laptop, which doesn't get much action, so I haven't updated it in months. So, I went ahead and started the update process which is going to take a while.
sudo apt-get update
sudo apt-get dist-upgrade

When this finishes, I'm going to run the nfs-server install command again, then it should just be a simple matter of setting up the NFS mount in /etc/exports file. While waiting I did a little research at the following site to get the syntax for setting up the export.
http://www.openfiler.com/products/system-requirements

I've done NFS a few times, so my eyes immediately found the kind of export I am looking to do, it is this line, which is added to /etc/exports. Then I run the command to make the NFS server re-read the config file and make my share available.
/usr/local 192.168.0.0/255.255.255.0(rw,sync,no_subtree_check)
sudo exportfs -ra

Now that I have my export, its time to boot from that netinstall CD and point it to my box to start the installation process. Because I am still waiting for my updates to finish, I did some Googling to find somebody who has done this before on CentOS. Here is what I found:
http://www.chrisgountanis.com/technical/34-technical/45-centos-netinstall.html

Seems pretty straight forward. The CD boots up, selected default options, DHCP, no IPv6 support (don't need it). Finally, it wants the NFS server name (IP) and the directory (nfs mountpoint with the media). I entered them both and sure enough, I was presented with a CentOS installation wizard. Rest of it is pretty straight forward, I go through the install as if I were using the DVD. Pretty cool stuff.

Friday, July 10, 2009

New Jumpstart Server Build

Yesterday I received a call that one of our remote offices was having serious network issues in the classrooms. We did some basic troubleshooting and determined the cause of the problem was the jumpstart server. The jumpstart server is used to 'jump' the classroom systems to a fresh build for the next class. It also acts as a DHCP server and a NAT router for all of the classrooms to route to the internet.

For a temporary fix, we grabbed an unused system from a classroom with solaris 10 on it and tossed it in place of the jumpstart server. We re-ip'd it to have the same IP as the old box that sat there (this prevents reconfiguration of the individual systems) and followed the steps in the following article to get it routing traffic.

http://gibbs.acu.edu/2007/02/24/using-solaris-10-as-a-firewallrouter/

Today, I am tasked with building a replacement for that box. The new paradigm that we are using here a GCA for the jumpstart servers is to make a linux host, then use VMware to virtualize the jumpstart server. All seven of our offices have a standard build for the classrooms. The classroom network is flat, then routes through a classserver (jumpstart server), which resides in the DMZ, and it will be forwarded out to the internet. Pretty simple setup.

The new server I am building is going to be using CentOS for the host OS, VMware server 2.0.1, and the Solaris 10 jumpstart server. The implementation we are using allows for us to be very flexible because every jumpstart server VM is exactly the same. The only modification we need to make for the host OS is to change the IP of the DMZ facing interface to the subnet of that office's DMZ.

The only difference we are doing on the new implementation is that we are not going to use the jumpstart server for routing, we are going to use CentOS. Instructors are allowed to login to the jumpstart servers to do bundles and move systems around, but that is not necessary on the CentOS stuff, because that should never change. I will use sudo and couple scripts to implement a way that the instructors can shutdown/reboot the CentOS box as well as start/shutdown/reboot the jumpstart server. These scripts are pretty cool and good to know about.

Stayed tuned for more info on iptables, vmware scripts, etc as I write and implement them. I probably will not get this done today as I am still waiting for CentOS to download.