define( 'DISALLOW_FILE_EDIT', true );
The post Centralized Backup Script appeared first on Managed Wordpress Hosting | Managed VPS Hosting | Stack Star.
]]>I thought I’d share a backup script that was written to consolidate backups onto one server instead of spreading the backup process across several servers. The advantages are somewhat obvious to consolidating the script onto one server, namely being that editing or making changes is much easier as you only have one script to edit.
The environment where this may be ideal would be for environments with 15-20 servers or less. I’d recommend a complete end-to-end backup solution for servers that exceed that number such as Bacula perhaps.
The bash shell script that I pasted below is very straightforward and takes two arguments. The first is the hostname or ip address of the destination server you are backing up. The next (and potentially unlimited) arguments will be single quote encased folders which you would want backed up.
This script is dependent on the server the script is running on having ssh key based authentication enabled and implemented for the root user. Security considerations can be made with IP based restrictions either in the ssh configuration, firewall configuration or other considerations.
#!/bin/sh
# Offsite Backup script
# Written by www.stardothosting.com
# Dynamic backup script
currentmonth=`date "+%Y-%m-%d %H:%M:%S"`
currentdate=`date "+%Y-%m-%d%H_%M_%S"`
backup_email="backups@youremail.com"
backupserver="origin-backup-server.hostname.com"
# Check User Input
if [ "$#" -lt 2 ]
then
echo -e "nnUsage Syntax :"
echo -e "./backup.sh [hostname] [folder1] [folder2] [folder3]"
echo -e "Example : ./backup.sh your-server.com '/etc' '/usr/local/www' '/var/lib/mysql'nn"
exit 1
fi
# get the server's hostname
host_name=`ssh -l root $1 "hostname"`
echo "Host name : $host_name"
if [ "$host_name" == "" ]
then
host_name="unknown_$currentdate"
fi
echo "$host_name Offsite Backup Report: " $currentmonth > /var/log/backup.log
echo -e "----------------------------------------------------------" >> /var/log/backup.log
echo -e "" >> /var/log/backup.log
# Ensure permissions are correct
chown -R backups:backups /home/fileserver/backups/
ls -d /home/fileserver/backups/* | grep -v ".ssh|.bash" | xargs -d "n" chmod -R 775
# iterate over user arguments & set error level to 0
errors=0
for arg in "${@:2}"
do
# check if receiving directory exists
if [ ! -d "/home/fileserver/backups/$host_name" ]
then
mkdir /home/fileserver/backups/$host_name
fi
sanitize=`echo $arg | sed 's/[^/]/+$ //'`
sanitize_dir=`echo $arg | awk -F '/' '{printf "%s", $2}'`
/usr/bin/ssh -o ServerAliveInterval=1 -o TCPKeepAlive=yes -l root $1 "/usr/bin/rsync -ravzp --progress --exclude 'clam_quarantinedir' $sanitize/ backups@$backupserver:/home/fileserver/backups/$host_name/$sanitize_dir; echo $? > /tmp/bu_rlevel.txt" >> /var/log/backup.log 2>&1
echo "/usr/bin/ssh -o ServerAliveInterval=1 -o TCPKeepAlive=yes -l root $1 "/usr/bin/rsync -ravzp --progress --exclude 'clam_quarantinedir' $sanitize/ backups@$backupserver:/home/fileserver/backups/$host_name/$sanitize_dir""
runlevel=`ssh -l root $1 "cat /tmp/bu_rlevel.txt"`
echo "Runlevel : $runlevel"
if [ "$runlevel" -ge 1 ]
then
errors=$((counter+1))
else
echo -e "Script Backup for $arg Completed Successfully!" >> /var/log/backup.log 2>&1
fi
done
# Check error level
if [ $errors -ge 1 ]
then
echo -e "There were some errors in the backup job for $host_name, please investigate" >> /var/log/backup.log 2>&1
cat /var/log/backup.log | mail -s "$host_name Backup Job failed" $backup_email
else
cat /var/log/backup.log | mail -s "$host_name Backup Job Completed" $backup_email
fi
It should be explained further that this script actually connects to the destination server as the root user, using ssh key authentication. It then initiates a remote rsync command on the destination server back to the backup server as a user called “backupuser”. So that means that not only does the ssh key need to be installed for root on the destination servers, but a user called “backupuser” needs to be added on the backup server itself, with the ssh keys of all the destination servers installed for the remote rsync.
Hopefully I did not over complicate this, because it really is quite simple :
Backup Server –> root –> destination server to backup — > backupuser rsync –> Backup Server
Once you implement the script and do a few dry run tests then it might be ready to implement a scheduled task for each destination server. Here is an example of one cron entry for a server to be backed up :
01 1 * * * /bin/sh /usr/local/bin/backups.sh destination-server-hostname '/etc' '/usr/local/www' '/home/automysql-backups'
The post Centralized Backup Script appeared first on Managed Wordpress Hosting | Managed VPS Hosting | Stack Star.
]]>The post ProFTPD with MySQL Authentication appeared first on Managed Wordpress Hosting | Managed VPS Hosting | Stack Star.
]]>1. install proftpd-mysql from the ports with WITH_QUOTA set:
cd /usr/ports/ftp/proftpd-mysql/ env WITH_QUOTA=yes make env WITH_QUOTA=yes make install
2. Add the global proftpd user & Proftpd group to your system.
I used uid & gid 5500 simply because that’s what was used at one of the sites I was referencing (listed below).
pw groupadd -n Proftpd -g 5500 pw useradd proftpd -u 5500 -g Proftpd -s /sbin/nologin -d /dev/null -c "Proftpd User"
3. Create the mySQL database
create database proftpd; grant all on proftpd.* to 'proftpd'@'localhost' identified by 'password'
( change ‘password’ to something secret! )
4. Create the mySQL tables for the users & quota
create table proftpdUsers (
sqlUID int unsigned auto_increment not null,
userName varchar(30) not null unique,
passwd varchar(80) not null,
uid int unsigned not null unique,
gid int unsigned not null,
homedir tinytext,
shell tinytext,
primary key(sqlUID)
) ;
create table proftpdGroups (
sqlGID int unsigned auto_increment not null,
groupName varchar(30) not null unique,
gid int unsigned not null unique,
members tinytext,
primary key(sqlGID)
);
CREATE TABLE proftpdQuotaLimits (
name VARCHAR(30),
quota_type ENUM("user", "group", "class", "all") NOT NULL,
per_session ENUM("false", "true") NOT NULL,
limit_type ENUM("soft", "hard") NOT NULL,
bytes_in_avail FLOAT NOT NULL,
bytes_out_avail FLOAT NOT NULL,
bytes_xfer_avail FLOAT NOT NULL,
files_in_avail INT UNSIGNED NOT NULL,
files_out_avail INT UNSIGNED NOT NULL,
files_xfer_avail INT UNSIGNED NOT NULL
);
CREATE TABLE proftpdQuotaTallies (
name VARCHAR(30) NOT NULL,
quota_type ENUM("user", "group", "class", "all") NOT NULL,
bytes_in_used FLOAT NOT NULL,
bytes_out_used FLOAT NOT NULL,
bytes_xfer_used FLOAT NOT NULL,
files_in_used INT UNSIGNED NOT NULL,
files_out_used INT UNSIGNED NOT NULL,
files_xfer_used INT UNSIGNED NOT NULL
);
5. Add a test user to the proftpd database
(assumes /home/ftp is where you keep your ftp users. Otherwise, change the homedir location). This is certainly not a necessary step, but you should probably check to see if your configuration is working. You can delete this user later.
insert into proftpdUsers values ( 0, 'test', 'test', 5500, 5500, '/home/ftp/test', '/sbin/nologin' );
6. Set your proftpd configuration to use the mySQL authentication and quotas:
(NOTE: this is not a complete configuration file, it’s basically just the default config file with mySQL auth & quotas added, but note that the User and Group directives are the user & group we added in step 2. )
MaxInstances 30 # Set the user and group under which the server will run. User proftpd Group Proftpd # To cause every FTP user to be "jailed" (chrooted) into their home # directory, uncomment this line. DefaultRoot ~ # Normally, we want files to be overwriteable. AllowOverwrite on # Bar use of SITE CHMOD by defaultDenyAll # Log format and location LogFormat default "%t %h %a %s %m %f %b %T "%r"" ExtendedLog /var/log/proftpd.log ALL default SystemLog /var/log/proftpd.log ALL default TransferLog /var/log/proftpd.log ALL default # Uncomment this if you have "invalid shell" errors in your proftpd.log #RequireValidShell off # The passwords in MySQL are encrypted using CRYPT SQLAuthTypes Plaintext Crypt SQLAuthenticate users* groups* # used to connect to the database # databasename@host database_user user_password SQLConnectInfo proftpd@localhost proftpd yourdatabasepassword # Here we tell ProFTPd the names of the database columns in the "usertable" # we want it to interact with. Match the names with those in the db SQLUserInfo proftpdUsers userName passwd uid gid homedir shell # Here we tell ProFTPd the names of the database columns in the "grouptable" # we want it to interact with. Again the names match with those in the db SQLGroupInfo proftpdGroups groupName gid members # set min UID and GID - otherwise these are 999 each SQLMinID 5000 #============ # User quotas # =========== QuotaEngine on QuotaDirectoryTally on QuotaDisplayUnits Mb QuotaShowQuotas on # create a user's home directory on demand if it doesn't exist SQLHomedirOnDemand on SQLNamedQuery get-quota-limit SELECT "name, quota_type, per_session, limit_type, bytes_in_avail, bytes_out_avail, bytes_xfer_avail, files_in_avail, files_out_avail, files_xfer_avail FROM proftpdQuotaLimits WHERE name = '%{0}' AND quota_type = '%{1}'" SQLNamedQuery get-quota-tally SELECT "name, quota_type, bytes_in_used, bytes_out_used, bytes_xfer_used, files_in_used, files_out_used, files_xfer_used FROM proftpdQuotaTallies WHERE name = '%{0}' AND quota_type = '%{1}'" SQLNamedQuery update-quota-tally UPDATE "bytes_in_used = bytes_in_used + %{0}, bytes_out_used = bytes_out_used + %{1}, bytes_xfer_used = bytes_xfer_used + %{2}, files_in_used = files_in_used + %{3}, files_out_used = files_out_used + %{4}, files_xfer_used = files_xfer_used + %{5} WHERE name = '%{6}' AND quota_type = '%{7}'" proftpdQuotaTallies SQLNamedQuery insert-quota-tally INSERT "%{0}, %{1}, %{2}, %{3}, %{4}, %{5}, %{6}, %{7}" proftpdQuotaTallies QuotaLimitTable sql:/get-quota-limit QuotaTallyTable sql:/get-quota-tally/update-quota-tally/insert-quota-tally
The post ProFTPD with MySQL Authentication appeared first on Managed Wordpress Hosting | Managed VPS Hosting | Stack Star.
]]>The post SSH Key based authentication appeared first on Managed Wordpress Hosting | Managed VPS Hosting | Stack Star.
]]>What makes this process seamless and efficient is to implement ssh key authentication to replace password based authentication.
When implemented, commands can be executed via scripts in order to execute and gather all the information that’s required in order to complete your task.
Sound easy? It is!
Public Key Setup
First, confirm that OpenSSH is the SSH software installed on the client system. Key generation may vary under different implementations of SSH. The ssh -V command should print a line beginning with OpenSSH, followed by other details.
$ ssh -V OpenSSH_3.6.1p1+CAN-2003-0693, SSH protocols 1.5/2.0, OpenSSL 0x0090702f
Key Generation
A RSA key pair must be generated on the client system. The public portion of this key pair will reside on the servers being connected to, while the private portion needs to remain on a secure local area of the client system, by default in ~/.ssh/id_rsa. The key generation can be done with the ssh-keygen(1) utility.
client$ mkdir ~/.ssh client$ chmod 700 ~/.ssh client$ ssh-keygen -q -f ~/.ssh/id_rsa -t rsa Enter passphrase (empty for no passphrase): … Enter same passphrase again: …
Depending on your work environment and the security policies and procedures, you may want to enter a passphrase. This effectively defeats the purpose of this, however. Entering an empty passphrase will allow you to complete a seamless connection.
The file permissions should be locked down to prevent other users from being able to read the key pair data. OpenSSH may also refuse to support public key authentication if the file permissions are too open. These fixes should be done on all systems involved.
$ chmod go-w ~/ $ chmod 700 ~/.ssh $ chmod go-rwx ~/.ssh/*
Key Distribution
The public portion of the RSA key pair must be copied to any servers that will be accessed by the client. The public key information to be copied should be located in the ~/.ssh/id_rsa.pub file on the client. Assuming that all of the servers use OpenSSH instead of a different SSH implementation, the public key data must be appended into the ~/.ssh/authorized_keys file on the servers.
first, upload public key from client to server:
client$ scp ~/.ssh/id_rsa.pub server.example.org:
next, setup the public key on server:
server$ mkdir ~/.ssh server$ chmod 700 ~/.ssh server$ cat ~/id_rsa.pub >> ~/.ssh/authorized_keys server$ chmod 600 ~/.ssh/authorized_keys server$ rm ~/id_rsa.pub
Be sure to append new public key data to the authorized_keys file, as multiple public keys may be in use. Each public key entry must be on a different line.
Many different things can prevent public key authentication from working, so be sure to confirm that public key connections to the server work properly. If the following test fails, consult the debugging notes.
client$ ssh -o PreferredAuthentications=publickey server.example.org Enter passphrase for key '/…/.ssh/id_rsa': … … server$
Key distribution can be automated with module:authkey and CFEngine. This script maps public keys stored in a filesystem repository to specific accounts on various classes of systems, allowing a user key to be replicated to all systems the user has access to.
If exporting the public key to a different group or company, consider removing or changing the optional public key comment field to avoid exposing the default username and hostname.
Easy!
The post SSH Key based authentication appeared first on Managed Wordpress Hosting | Managed VPS Hosting | Stack Star.
]]>