Server Howtos
Part 2 of the Server Howto Guide explains how to put backup systems in place, how to secure ssh, keep an eye on logs, and manage dyndns.
Server backups
Backing up your server data is a basic protection against a dead hardrive, or your own misadventures as root (and hopefully you wont be getting hacked). At a minimum, use a second physical drive. Heres how:
Get some packages:
aptitude install cfdisk rsync curl hdparm
Assuming youve fitted the second drive on the second IDE as master, its blank, you want it as one big partition:
md /disk2
cfdisk /dev/hdb
Using the cfdisk gui delete any existing partitions, create one large partition, of type ext3, mounted on /disk2. Write changes, and close cfdisk. You might have to format the drive after, or it might already be done. If not:
mkfs /dev/hdb1 -V -t ext3
Then check your fstab to look something like this (depending on how you partitioned your drives):
nano /etc/fstab
/dev/hda1 / ext3 defaults 1 1
/dev/hda5 swap swap defaults 0 0
/dev/hda6 /home ext3 defaults 1 2
/dev/hdb1 /disk2 ext3 defaults 1 3
Typing:
mount /disk2
mount
df -h
Should confirm that your second drive is available at /disk2. If it doesnt show up in the last two commands above, then its not mounted and /disk2 wont be the contents of the second disk but just part of disk1. If good then:
md /disk2/backupdata
md /disk2/backuplog
Now for the daily backup, simply add a root cron entry (all on one line):
45 2 * * * mount /disk2;rsync -auqP /etc /home /lib /usr /var /root /disk2/backupdata --log-file=/disk2/backuplog/log.txt;umount /disk2
Which says to once a day in the wee hours, mount the drive, maintain an exact mirror of the first drive on the second drive, then unmount the drive.
You can even make the second drive spin down (after 5 mins idle) to save some power.
hdparm /dev/hdb -S 60
If you want to get really flash you can write some scripts to do revisoning incremental backups aswell, and email or ftp or webdav addtional backups off site.
LAN Client backups
While were onto backups lets backup your lan workstations while we are at it.
This basically involves creating a smb share.
aptitude install samba
md /home/lanbackups
chown cow:cow /home/lanbackups
The alter the samba config file to the effect of:
nano /etc/samba/smb.conf
security = share
workgroup = WORKGROUP
guest account = cow
[backup]
comment = Lan backups
path = /home/lanbackups
writable = yes
guest ok = yes
That should give your windows and mac clients access to the new share at //192.168.0.1/backup/ with no password required. You can read up on adding passwords and user shares and whatnot. Then just use your favorite backup program to do daily backups using the share as the destination. Or just add another share for NAS store for your laptops or whatever. There is an example backup script in the Webspaces CMS package.
Data migration and Mysql server dumps
After you fiddle around with these boxes a while you eventually need to move files from one server to another. Heres some pointers, by no means the only way.
You can use ftpcopy to create, from a second server 192.168.0.2, a duplicate of /var/www:
ftpcopy 192.168.0.1 -u cow -p moo /var/www /var/www
Or you can use rysnc to do the same.
For exporting mysql tables we could dump the entire database:
mysqldump -u root -p --quick --add-drop farm > /root/farmdump.txt
mysqldump -u root -p --no-data farm > /root/farmtables.txt
mysqldump -u root -p --no-create-info farm > /root/farmrecords.txt
To import the textfile dumps into the new machine, ftp the dumps over, then on the new machine:
cat farmdump.txt | mysql -u root -p farm
Now if you have a dead original box, then you will have to take the last /var/lib/mysql backup and copy it into place onthe new machine.
Mysql Apache Authentication
Generally youll be better off with session based logins. But this may be useful to keep everyone out of an internet connected webserver or other obscure uses. In essence this will make apache confer with a mysql table to do auth user logins, instead of a static .htaccess file.
Theres a problem with Debian Etch in this area, as the traditional
libapache2-mod-auth-mysql package does not exist anymore due to problems, and the newer mod_authn_dbd does not yet include a driver for MySQL. See: [http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=405773]
That leaves you with pam. Create your user table, then:
apt-get install libapache2-mod-auth-pam libpam-mysql
adduser www-data shadow
a2enmod auth_pam
/etc/init.d/apache2 force-reload
nano /etc/pam.d/apache2
auth sufficient pam_mysql.so verbose=1 user=cow passwd=moo host=localhost db=farm table=farm.users usercolumn=farm.users.username passwdcolumn=farm.users.password crypt=0
account sufficient pam_mysql.so verbose=1 user=farm passwd=moo host=localhost db=farm table=farm.users usercolumn=farm.users.username passwdcolumn=farm.users.password crypt=0
nano /var/www/html/.htaccess
AuthPAM_Enabled on
AuthPAM_FallThrough off
AuthType Basic
AuthName `The Fat Farm Intranet`
AuthUserFile /dev/null
AuthBasicAuthoritative Off
require valid-user
Like anything MYSQL it`ll add some overhead to the whole deal, but it has its uses.
Secure SSH External Access
While you can just port forward port 22 from your DSL router to the server, that would be an insecure setup. A tiny bit more secure would be to use a high WAN port like 9543, for example. So the port forward source port is 9543 and the dest port remains 22. That way you can change the port on putty to 9543 and you can get in at the same time reducing brute force attacks on port 22. But a much better method follows.
Here we do 3 things to make an ssh server tough enough to withstand the internet.
Generate a public /private key pair using windows puttygen.exe like so:
Download it and run it.
ssh2 rsa | generate | wiggle mouse
keep this window open for the remainder of the steps.
Save private key ( with or without passphrase)
with is more secure if you computer gets compromised. but requires a password to login ssh.
Choose somewhere quite safe, in your backup tree, like my documents | keys. Back it up!
Copy the public key from the `public key for pasting...` area
Paste it into the echo line just below.(needs the whole key on one line)
Do the below to the server (will work over a ssh connection, so long as you dont screw anything up.)
md -vp /home/cow/.ssh/
echo `ssh-rsa AAAAB3N...snip...sk18DafeYJVD== farm_rsa_apr_08` > /home/cow/.ssh/authorized_keys
nano /etc/ssh/sshd_config
PermitRootLogin no
ChallengeResponseAuthentication no
PasswordAuthentication no
/etc/init.d/ssh restart
If you still have your ssh connection, good. Close it.
Assuming you already have a putty session defined for the server on your own box,
Load, but not open your ssh client session.
Category | Connection | ssh | auth | privatekey file for auth | browse | my docs/keys/sshpriv.ppk
Save your session, then open it. Login as your user (cow) not root.
If you selected a passphrase before enter it otherwise youll log straight in. su root and thats it.
DYNDNS Updater
DDclient is not well documented, but does work if setup correctly. The main difficulties occur if if you havnet got the right IP discovery setup, it will keep trying to update and youll get into abuse status.
aptitude install ddclient
nano /etc/default/ddclient
run_ipup=`false`
run_daemon=`true`
daemon_interval=`600`
nano /etc/ddclient.conf
pid=/var/run/ddclient.pid
syslog=yes
use=web, web=checkip.dyndns.com/, web-skip=`IP Address`
protocol=dyndns2
server=members.dyndns.org
login=cow
password=`moo`
farm.homeip.net
/etc/init.d/ddclient restart
Or do what i did and write a script in perl. Its included in the CMS package. But briefly it hangs around the simple dyndns api to the effect:
if ($_ =`/usr/bin/curl -s -u $DD_AUTH `http://members.dyndns.org/nic/update?hostname=$DD_HOST&myip=$ipcurrent&wildcard=NOCHG&mx=NOCHG&backmx=NOCHG` `){
$dbo.= `$datenow DD UPDATE: reponse received/n`;
if (/good/) { $dbo.= `$datenow DD UPDATE: update success/n`; $gflag=1;}
elsif (/nochg/) { $dbo.= `$datenow DD UPDATE: responded NOCHG!/n`; $nflag=1; }
elsif (/notfqdn/) { $dbo.= `$datenow DD UPDATE: responded NOTFQDN!/n`; }
elsif (/abuse/) { $dbo.= `$datenow DD UPDATE: responded ABUSE!/n`; }
elsif (/nohost/) { $dbo.= `$datenow DD UPDATE: responded NOHOST!/n`; }
elsif (/badagent/) { $dbo.= `$datenow DD UPDATE: responded BADAGENT!/n`; }
elsif (/badsys/) { $dbo.= `$datenow DD UPDATE: responded BADSYS!/n`; }
else { $dbo.= `$datenow DD UPDATE: failed ($_)/n`; }
}
else { $dbo.= `DD UPDATE: response not recieved!/n`; }
And you can fish the WAN IP out of your router easliy enough by looking at the html and crafting a regular expression like for example:
if ($_= `/usr/bin/curl -s -u $ROUTERIPCHECKAUTH `http://$ROUTERIPCHECKADDRESS` `) {
if (/st_wan_ip/[0/] = `(/d{1,3}/./d{1,3}/./d{1,3}/./d{1,3})/) {
$ipcurrent=$1;
}
}
nb: the cms has altered the odd backslash to foreslashes, and quote to backticks. You need to fix those.
Logwatch
As a start to some better security logwatch is easy to do. Logwatch analyses the profuse and verbose server logs and emails you a summary once a day.
aptitude install logwatch