The solution:
sudo ln -s /usr/local/git/bin/git /usr/local/bin/
Saturday, July 23, 2011
Saturday, July 16, 2011
php mongo 1.2.1 on Amazon Linux
The src rpm is here: http://www.kuliyev.com/php-pecl-mongo-1.2.1-4.amzn1.src.rpm
The i686 (no x64 yet, sorry) rpm is here: http://www.kuliyev.com/php-pecl-mongo-1.2.1-4.amzn1.i686.rpm
Have fun.
The i686 (no x64 yet, sorry) rpm is here: http://www.kuliyev.com/php-pecl-mongo-1.2.1-4.amzn1.i686.rpm
Have fun.
php-fpm for EC2 Amazon Linux
How to get the latest php-fpm on Amazon Linux without hassle.
I needed the latest php-fpm (5.3.6) run on Amazon linux, so I got the Amazon's php source rpm and patched it to include the php-fpm. Here are the steps:
1. Install necessary build packages:
yum install -yy rpm-build gcc make redhat-rpm-config
2.Get the source rpm (will be downloaded to /usr/src/srpm/debug/)
get_reference_source -p php
3. Unpack it
rpm -i /usr/src/srpm/debug/php-5.3.6-1.13.amzn1.src.rpm
4. Install packages required to the build:
yum install -yy bzip2-devel curl-devel db4-devel gmp-devel httpd-devel pam-devel libstdc++-devel openssl-devel sqlite-devel pcre-devel libedit-devel libtool gcc-c++ libevent-devel libtool-ltdl-devel libc-client-devel mysql-devel postgresql-devel unixODBC-devel libxml2-devel net-snmp-devel libxslt-devel libxml2-devel libjpeg-devel libpng-devel freetype-devel libXpm-devel t1lib-devel libmcrypt-devel libtidy-devel freetds-devel aspell-devel libicu-devel
5. Edit the /usr/src/rpm/SPECS/php.spec file and add php-fpm or get mine: http://www.kuliyev.com/php.spec
5. Build the RPM (rpmbuild will ask to install
rpmbuild -bs --clean /usr/src/rpm/SPECS/php.spec
You can download the ready-to-build source rpm from here: http://www.kuliyev.com/php-5.3.6-1.13.amzn1.src.rpm
Or, even better, ready to install rpm (i686 version for now, sorry): http://www.kuliyev.com/php-fpm-5.3.6-1.13.amzn1.i686.rpm
Have fun.
I needed the latest php-fpm (5.3.6) run on Amazon linux, so I got the Amazon's php source rpm and patched it to include the php-fpm. Here are the steps:
1. Install necessary build packages:
yum install -yy rpm-build gcc make redhat-rpm-config
2.Get the source rpm (will be downloaded to /usr/src/srpm/debug/)
get_reference_source -p php
3. Unpack it
rpm -i /usr/src/srpm/debug/php-5.3.6-1.13.amzn1.src.rpm
4. Install packages required to the build:
yum install -yy bzip2-devel curl-devel db4-devel gmp-devel httpd-devel pam-devel libstdc++-devel openssl-devel sqlite-devel pcre-devel libedit-devel libtool gcc-c++ libevent-devel libtool-ltdl-devel libc-client-devel mysql-devel postgresql-devel unixODBC-devel libxml2-devel net-snmp-devel libxslt-devel libxml2-devel libjpeg-devel libpng-devel freetype-devel libXpm-devel t1lib-devel libmcrypt-devel libtidy-devel freetds-devel aspell-devel libicu-devel
5. Edit the /usr/src/rpm/SPECS/php.spec file and add php-fpm or get mine: http://www.kuliyev.com/php.spec
5. Build the RPM (rpmbuild will ask to install
rpmbuild -bs --clean /usr/src/rpm/SPECS/php.spec
You can download the ready-to-build source rpm from here: http://www.kuliyev.com/php-5.3.6-1.13.amzn1.src.rpm
Or, even better, ready to install rpm (i686 version for now, sorry): http://www.kuliyev.com/php-fpm-5.3.6-1.13.amzn1.i686.rpm
Have fun.
tmux on Amazon Linux
I need tmux for my daily job and Amazon Linux lacks it, so I compiled mine from the tmux-1.4-3.el5.1.src.rpm. It was required the libevent-1.4.13-1 and not the amazon's one, however. So, I compiled libevent too.
i686:
x64:
src:
Have fun.
Thursday, January 6, 2011
Haproxy PostgreSQL health check patch
I have written a small patch to enable a correct PostgreSQL health check
It works similar to mysql-check with the very same parameters.
E.g.:
listen pgsql 127.0.0.1:5432
mode tcp
option pgsql-check user pgsql
server masterdb pgsql.server.com:5432 check inter 10000
The patch has been commited to 1.5 tree.
You can use it against 1.4 tree without any problems.
Moreover, I have submitted the FreeBSD PR to 1.4 port in ports tree as well.
Audit ports in jail on FreeBSD
The modified metaportaudit.sh script to perform a ports security audit in jails on FreeBSD from here .
This script audit only base jails not the cloned ones. You can grab it here.
Do not forget to edit /usr/local/etc/periodic/security/*.portaudit on about line 55
you'll want to change:
echo
echo /usr/local/sbin/portaudit -a |
su -fm "${daily_status_security_portaudit_user:-nobody}" || rc=$?
to
echo
echo /root/bin/metaportaudit.sh -a |
su -fm "${daily_status_security_portaudit_user:-nobody}" || rc=$?
Tuesday, December 28, 2010
Notes about creating FreeBSD jails
Something like that:
/bin/sh
mkdir /var/jails && cd /var/jails
for D in `ls`; do
mkdir -p $D/root $D/bin $D/dev $D/etc $D/lib $D/libexec $D/tmp $D/usr $D/var $D/home/$D
chmod o+rwxt $D/tmp
mtree -deU -f /etc/mtree/BSD.var.dist -p $D/var
done
cd /usr/src
for D in `ls /var/jails/`; do
make distribution DESTDIR=/var/jails/$D
done
cat >> /etc/rc.conf
# Jails
jail_enable="YES"
jail_mount_enable="YES"
jail_sysvipc_allow="YES"
jail_list="jail1 jail2 jail3"
## jail1
jail_jail1_name="jail1"
jail_jail1_hostname="jail1.com"
jail_jail1_ip="127.0.0.10/8"
jail_jail1_interface="lo0"
jail_jail1_rootdir="/var/jails/jail1"
jail_jail1_devfs_enable="YES"
jail_jail1_devfs_ruleset="devfsrules_jail"
## jail2
jail_jail2_name="jail2"
jail_jail2_hostname="jail2.com"
jail_jail2_ip="127.0.0.20/8"
jail_jail2_interface="lo0"
jail_jail2_rootdir="/var/jails/jail2"
jail_jail2_devfs_enable="YES"
jail_jail2_devfs_ruleset="devfsrules_jail"
## jail3
jail_jail3_name="jail3"
jail_jail3_hostname="jail3.com"
jail_jail3_ip="127.0.0.30/8"
jail_jail3_interface="lo0"
jail_jail3_rootdir="/var/jails/jail3"
jail_jail3_devfs_enable="YES"
jail_jail3_devfs_ruleset="devfsrules_jail"
^D
cat /etc/fstab.jail1
/var/jails/ruby/bin /var/jails/jail1/bin nullfs ro 0 0
/var/jails/ruby/lib /var/jails/jail1/lib nullfs ro 0 0
/var/jails/ruby/libexec /var/jails/jail1/libexec nullfs ro 0 0
/var/jails/ruby/usr /var/jails/jail1/usr nullfs ro 0 0
tmpfs /var/jails/jail1/tmp tmpfs rw,size=1G 0 0
/bin/sh
mkdir /var/jails && cd /var/jails
for D in `ls`; do
mkdir -p $D/root $D/bin $D/dev $D/etc $D/lib $D/libexec $D/tmp $D/usr $D/var $D/home/$D
chmod o+rwxt $D/tmp
mtree -deU -f /etc/mtree/BSD.var.dist -p $D/var
done
cd /usr/src
for D in `ls /var/jails/`; do
make distribution DESTDIR=/var/jails/$D
done
cat >> /etc/rc.conf
# Jails
jail_enable="YES"
jail_mount_enable="YES"
jail_sysvipc_allow="YES"
jail_list="jail1 jail2 jail3"
## jail1
jail_jail1_name="jail1"
jail_jail1_hostname="jail1.com"
jail_jail1_ip="127.0.0.10/8"
jail_jail1_interface="lo0"
jail_jail1_rootdir="/var/jails/jail1"
jail_jail1_devfs_enable="YES"
jail_jail1_devfs_ruleset="devfsrules_jail"
## jail2
jail_jail2_name="jail2"
jail_jail2_hostname="jail2.com"
jail_jail2_ip="127.0.0.20/8"
jail_jail2_interface="lo0"
jail_jail2_rootdir="/var/jails/jail2"
jail_jail2_devfs_enable="YES"
jail_jail2_devfs_ruleset="devfsrules_jail"
## jail3
jail_jail3_name="jail3"
jail_jail3_hostname="jail3.com"
jail_jail3_ip="127.0.0.30/8"
jail_jail3_interface="lo0"
jail_jail3_rootdir="/var/jails/jail3"
jail_jail3_devfs_enable="YES"
jail_jail3_devfs_ruleset="devfsrules_jail"
^D
cat /etc/fstab.jail1
/var/jails/ruby/bin /var/jails/jail1/bin nullfs ro 0 0
/var/jails/ruby/lib /var/jails/jail1/lib nullfs ro 0 0
/var/jails/ruby/libexec /var/jails/jail1/libexec nullfs ro 0 0
/var/jails/ruby/usr /var/jails/jail1/usr nullfs ro 0 0
tmpfs /var/jails/jail1/tmp tmpfs rw,size=1G 0 0
Sunday, November 7, 2010
Simple script to monitor replication in PostgreSQL 9
Here is the simple script to monitor PostgreSQL replication on FreeBSD:
========= Cut here =========
#!/bin/sh
# Timeout in seconds
readonly timeout=600
last_chkp=`pg_controldata /var/db/pgsql/ | grep "Time of latest checkpoint" | sed "s/.*checkpoint: *//"`
last_chkp=`date -j -f "%a %b %d %T %Z %Y" "$last_chkp" "+%s"`
now=`date`
now=`date -j -f "%a %b %d %T %Z %Y" "$now" "+%s"`
if [ `expr $now - $last_chkp` -gt $timeout ]; then
echo Replication kaput!
fi
========= Cut here =========
#!/bin/sh
# Timeout in seconds
readonly timeout=600
last_chkp=`pg_controldata /var/db/pgsql/ | grep "Time of latest checkpoint" | sed "s/.*checkpoint: *//"`
last_chkp=`date -j -f "%a %b %d %T %Z %Y" "$last_chkp" "+%s"`
now=`date`
now=`date -j -f "%a %b %d %T %Z %Y" "$now" "+%s"`
if [ `expr $now - $last_chkp` -gt $timeout ]; then
echo Replication kaput!
fi
Monday, October 4, 2010
Tarsnap cleanup on FreeBSD
The simple script to preform tarsnap cleanup on FreeBSD:
#!/bin/sh
keyfile="/path/to/rw_keyfile"
# man(1) date will help (keep files for last 7 days in this example)
# we prefer to keep files in this format 2009-10-18+06:15-database as mentioned in earlier post
rd=`date -v-7d -v0H -v0M -v0S`
pd=`date -j -f "%a %b %d %T %Z %Y" "$rd" "+%s"`
for file in `tarsnap --keyfile $keyfile --list-archives | sort`; do
fd=`echo -n $file | cut -d'+' -f 1`
fd=`date -j -f "%Y-%m-%d %T" "$fd 00:00:00" "+%s"`
if [ $fd -lt $pd ]; then
echo Deleting the $file archive
tarsnap --keyfile $keyfile -d -f $file
fi
done
#!/bin/sh
keyfile="/path/to/rw_keyfile"
# man(1) date will help (keep files for last 7 days in this example)
# we prefer to keep files in this format 2009-10-18+06:15-database as mentioned in earlier post
rd=`date -v-7d -v0H -v0M -v0S`
pd=`date -j -f "%a %b %d %T %Z %Y" "$rd" "+%s"`
for file in `tarsnap --keyfile $keyfile --list-archives | sort`; do
fd=`echo -n $file | cut -d'+' -f 1`
fd=`date -j -f "%Y-%m-%d %T" "$fd 00:00:00" "+%s"`
if [ $fd -lt $pd ]; then
echo Deleting the $file archive
tarsnap --keyfile $keyfile -d -f $file
fi
done
Script to perform tarsnapping of data on FreeBSD
Here is the script to perform tarsnapping on FreeBSD:
#!/bin/sh
# Directories to backup
DIRS=/usr/local/etc/tarsnap-backup.conf
#EXTRA_FLAGS=--dry-run
BACKUP=`date "+%Y-%m-%d+%H:%M"`
TARSNAP="/usr/local/bin/tarsnap"
# Do backups
IFS='
'
for dirs in `grep -v -e '^#.' $DIRS`; do
# Needs to set IFS to space to allow passing arguments to tarsnap
IFS=' '
echo ${dirs}
$TARSNAP $EXTRA_FLAGS -c -f $BACKUP-${dirs}
done
The conf file should look like:
archive_name1 /list /of /directories1
archive_name2 /list /of /directories2
misc /root /etc /boot/loader.conf /usr/local/etc /usr/local/opt /var/cron/tabs /var/services /var/mail /var/qmail/control /var/qmail/alias
#!/bin/sh
# Directories to backup
DIRS=/usr/local/etc/tarsnap-backup.conf
#EXTRA_FLAGS=--dry-run
BACKUP=`date "+%Y-%m-%d+%H:%M"`
TARSNAP="/usr/local/bin/tarsnap"
# Do backups
IFS='
'
for dirs in `grep -v -e '^#.' $DIRS`; do
# Needs to set IFS to space to allow passing arguments to tarsnap
IFS=' '
echo ${dirs}
$TARSNAP $EXTRA_FLAGS -c -f $BACKUP-${dirs}
done
The conf file should look like:
archive_name1 /list /of /directories1
archive_name2 /list /of /directories2
misc /root /etc /boot/loader.conf /usr/local/etc /usr/local/opt /var/cron/tabs /var/services /var/mail /var/qmail/control /var/qmail/alias
Thursday, November 26, 2009
Get NetFlow entries from a flowd via logsock to put to PostgreSQL in Perl
Here is a small piece of code in Perl to get NetFlow entries from a flowd via logging socket (logsock) and put to a PostgreSQL database.
Beware, no sanity checking at all!!!
=== cut here ===
#!/usr/bin/perl
use IO::Socket;
use Socket;
use Flowd;
use DBI;
# Database settings
my $DBI_DRIVER = "Pg"; # or one of "Pg" "mysql" "mysqlPP"
my $DB = "netflow";
my $HOST = "localhost";
my $TABLE = "flow";
my $USER = "netflow";
my $PASS = "password";
$sock_addr="/var/run/flowd/flowd.sock";
unlink($sock_addr);
$sock = IO::Socket::UNIX->new( Local => $sock_addr, Type => SOCK_DGRAM)
or die "Can't bind to Unix Socket: $!\n";
$sock->setsockopt(SOL_SOCKET, SO_RCVBUF, 65440);
my $db = DBI->connect("dbi:$DBI_DRIVER:host=$HOST;database=$DB", $USER, $PASS)
or die "DBI->connect error: " . $DBI::errstr;
print "Started.\n";
while ($bytes = $sock->recv($input,1024)) {
$flowfields = Flowd::deserialise($input);
$recv_time = sprintf "%s.%03d",$flowfields->{recv_sec}, $flowfields->{recv_usec};
$flow_start = $recv_time + ($flowfields->{flow_start} - $flowfields->{sys_uptime_ms})/1000;
$flow_finish = $recv_time + ($flowfields->{flow_finish} - $flowfields->{sys_uptime_ms})/1000;
$sql = sprintf("INSERT INTO flows (recv_time, agent_addr, protocol_id, src_addr, src_port, dst_addr, dst_port, packets, octets, flow_start, flow_finish) VALUES (to_timestamp('%s'), '%s', '%u', '%s', '%u', '%s', '%u', '%s', '%s', to_timestamp('%s'), to_timestamp('%s'))",
$recv_time,
$flowfields->{agent_addr},
$flowfields->{protocol},
$flowfields->{src_addr},
$flowfields->{src_port},
$flowfields->{dst_addr},
$flowfields->{dst_port},
$flowfields->{flow_packets},
$flowfields->{flow_octets},
$flow_start,
$flow_finish
);
$db->do($sql) or die "db->do failed: " . $DBI::errstr;
}
1;
=== cut here ===
The SQL schema:
CREATE TABLE flows (
id serial NOT NULL,
recv_time timestamp with time zone DEFAULT now() NOT NULL,
agent_addr inet NOT NULL,
protocol_id integer NOT NULL,
src_addr inet NOT NULL,
src_port integer NOT NULL,
dst_addr inet NOT NULL,
dst_port integer NOT NULL,
packets bigint DEFAULT 0 NOT NULL,
octets bigint DEFAULT 0 NOT NULL,
flow_start timestamp with time zone NOT NULL,
flow_finish timestamp with time zone NOT NULL
);
Beware, no sanity checking at all!!!
=== cut here ===
#!/usr/bin/perl
use IO::Socket;
use Socket;
use Flowd;
use DBI;
# Database settings
my $DBI_DRIVER = "Pg"; # or one of "Pg" "mysql" "mysqlPP"
my $DB = "netflow";
my $HOST = "localhost";
my $TABLE = "flow";
my $USER = "netflow";
my $PASS = "password";
$sock_addr="/var/run/flowd/flowd.sock";
unlink($sock_addr);
$sock = IO::Socket::UNIX->new( Local => $sock_addr, Type => SOCK_DGRAM)
or die "Can't bind to Unix Socket: $!\n";
$sock->setsockopt(SOL_SOCKET, SO_RCVBUF, 65440);
my $db = DBI->connect("dbi:$DBI_DRIVER:host=$HOST;database=$DB", $USER, $PASS)
or die "DBI->connect error: " . $DBI::errstr;
print "Started.\n";
while ($bytes = $sock->recv($input,1024)) {
$flowfields = Flowd::deserialise($input);
$recv_time = sprintf "%s.%03d",$flowfields->{recv_sec}, $flowfields->{recv_usec};
$flow_start = $recv_time + ($flowfields->{flow_start} - $flowfields->{sys_uptime_ms})/1000;
$flow_finish = $recv_time + ($flowfields->{flow_finish} - $flowfields->{sys_uptime_ms})/1000;
$sql = sprintf("INSERT INTO flows (recv_time, agent_addr, protocol_id, src_addr, src_port, dst_addr, dst_port, packets, octets, flow_start, flow_finish) VALUES (to_timestamp('%s'), '%s', '%u', '%s', '%u', '%s', '%u', '%s', '%s', to_timestamp('%s'), to_timestamp('%s'))",
$recv_time,
$flowfields->{agent_addr},
$flowfields->{protocol},
$flowfields->{src_addr},
$flowfields->{src_port},
$flowfields->{dst_addr},
$flowfields->{dst_port},
$flowfields->{flow_packets},
$flowfields->{flow_octets},
$flow_start,
$flow_finish
);
$db->do($sql) or die "db->do failed: " . $DBI::errstr;
}
1;
=== cut here ===
The SQL schema:
CREATE TABLE flows (
id serial NOT NULL,
recv_time timestamp with time zone DEFAULT now() NOT NULL,
agent_addr inet NOT NULL,
protocol_id integer NOT NULL,
src_addr inet NOT NULL,
src_port integer NOT NULL,
dst_addr inet NOT NULL,
dst_port integer NOT NULL,
packets bigint DEFAULT 0 NOT NULL,
octets bigint DEFAULT 0 NOT NULL,
flow_start timestamp with time zone NOT NULL,
flow_finish timestamp with time zone NOT NULL
);
Saturday, March 8, 2008
Patching Squid to support gzip/deflate encoding
Squid is a caching proxy for the Web supporting HTTP, HTTPS, FTP, and more. It reduces bandwidth and improves response times by caching and reusing frequently-requested web pages. Squid has extensive access controls and makes a great server accelerator.
Unfortunately, Squid is HTTP/1.0 due to the lack of certain features and the main disadvantage, from my point of view, is a lack of gzip/deflate content encoding.
There is a patch created by Swell Technology and committed to the HEAD. But it was not tested and little bit outdated.
So I've spent around six late night/early morning hours to merge the patch to Squid 3.0-Stable1. Right now patched squid it running on the old AMD Athlon64 3000+ machine serving around 500 simultaneously connected clients through the dial-up lines. The main concern was the CPU utilization, but FreeBSD team made an excellent work in regards of the performance in FreeBSD 7.
So here is the snapshot from top:
56897 squid 1 4 0 1085M 1044M kqread 9:28 5.18% squid
and uptime is:
1:51PM up 7 days, 10:45, 2 users, load averages: 0.01, 0.06, 0.15
The FreeBSD port patch is here.
Enjoy.
UPDATE:
Link to FreeBSD PR
UPDATE 1:
FreeBSD maintainer refused to integrate patch to ports tree:
Unfortunately, Squid is HTTP/1.0 due to the lack of certain features and the main disadvantage, from my point of view, is a lack of gzip/deflate content encoding.
There is a patch created by Swell Technology and committed to the HEAD. But it was not tested and little bit outdated.
So I've spent around six late night/early morning hours to merge the patch to Squid 3.0-Stable1. Right now patched squid it running on the old AMD Athlon64 3000+ machine serving around 500 simultaneously connected clients through the dial-up lines. The main concern was the CPU utilization, but FreeBSD team made an excellent work in regards of the performance in FreeBSD 7.
So here is the snapshot from top:
56897 squid 1 4 0 1085M 1044M kqread 9:28 5.18% squid
and uptime is:
1:51PM up 7 days, 10:45, 2 users, load averages: 0.01, 0.06, 0.15
The FreeBSD port patch is here.
Enjoy.
UPDATE:
Link to FreeBSD PR
UPDATE 1:
FreeBSD maintainer refused to integrate patch to ports tree:
| From: | Thomas-Martin Seck |
| Date: | Sat, 8 Mar 2008 15:59:46 +0100 |
| I am sorry, but I am not going to integrate third-party patches into the Squid ports any more (this includes patchsets that are available from devel.squid-cache.org). Please work with the Squid developers on integrating this feature into mainline Squid. Short rationale: Third party patches are a headache to maintain, especially when they are no longer maintained (cf ICAP for Squid-2) and they can be a major source of trouble when they contain bugs that are then wrongly attributed to bugs in Squid itself. I would therefore like to keep the port as close to the mainline source as possible to make it easy for users to get support for it from the Squid developers in case of problems. | |
Monday, September 24, 2007
Small script to check MySQL replication
Small script to check MySQL replication on FreeBSD. Path to mysql.sock as a parameter:
cat /usr/local/opt/check_relication.sh
#!/bin/sh
treshold=1200
### Do not edit below
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin
if [ -z $1 ] ; then
echo "Usage: $0 /path/to/mysql.sock"
exit 255
fi
seconds=`mysql -S $1 -N -e "show slave status\G" | grep Seconds_Behind_Master | cut -d: -f 2`
if [ -z $seconds ] ; then
exit 255
fi
if [ $seconds = "NULL" ]; then
echo Replication kaput!!!
exit 255
fi
if [ $seconds -gt $treshold ]; then
echo Slave behind the master more than $treshold seconds!
fi
Just put to crontab something like this:
*/30 * * * * /usr/local/opt/check_relication.sh /tmp/mysql.sock
cat /usr/local/opt/check_relication.sh
#!/bin/sh
treshold=1200
### Do not edit below
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin
if [ -z $1 ] ; then
echo "Usage: $0 /path/to/mysql.sock"
exit 255
fi
seconds=`mysql -S $1 -N -e "show slave status\G" | grep Seconds_Behind_Master | cut -d: -f 2`
if [ -z $seconds ] ; then
exit 255
fi
if [ $seconds = "NULL" ]; then
echo Replication kaput!!!
exit 255
fi
if [ $seconds -gt $treshold ]; then
echo Slave behind the master more than $treshold seconds!
fi
Just put to crontab something like this:
*/30 * * * * /usr/local/opt/check_relication.sh /tmp/mysql.sock
Friday, August 3, 2007
Move from apache 2.2 to Nginx as a PHP or Ruby web server
Recently we started to move moderately loaded news web site from apache 2.2 to Nginx due to it's incredible performance and security.
So, here the short instruction set to start Nginx with PHP and RubyOnRails under daemontools monitoring on FreeBSD:
PHP:
cat /var/services/backend-phpfcgi/run
#!/bin/sh
exec 2>&1
exec setuidgid backend spawn-fcgi -n -a 127.0.0.1 -p 9000 -f /usr/local/bin/php-cgi
I'm using spawn-fcgi from lighttpd package, however the php-cgi can be ran directly.
RubyOnRail:
cat /var/services/backend-rubyfcgi/run
#!/bin/sh
umask 22
export RAILS_ENV=production
exec setuidgid rubysite spawn-fcgi -n -a 127.0.0.1 -p 9001 -f /home/rubysite/www/public/dispatch.fcgi
Nginx configuration files:
cat /usr/local/etc/nginx/nginx.conf
user www;
worker_processes 30;
timer_resolution 1000ms;
error_log /var/log/nginx-error.log error;
pid /var/run/nginx.pid;
events {
worker_connections 2048;
use kqueue;
}
http {
include mime.types;
default_type application/octet-stream;
access_log off;
gzip on;
gzip_comp_level 6;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
include vhosts/conf-*;
server {
listen ip.add.re.ss:80 default accept_filter=httpready;
error_page 404 /404.html;
location / {
root /home/default/www;
index index.html;
}
}
}
cat /usr/local/etc/nginx/vhosts/conf-site.com
server {
listen ip.add.re.ss;
server_name site.com www.site.com
location / {
root /home/site/www;
index index.php;
}
location ~* ^.+\.(php)$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /home/site/www/$fastcgi_script_name;
include fastcgi_params;
}
}
cat /usr/local/etc/nginx/fastcgi_params
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param REDIRECT_STATUS 200;
Nginx runs under www privileges and the back-end as a backend user so security is much improved.
P.S.
Interesting link shows nginx as third popular web server.
So, here the short instruction set to start Nginx with PHP and RubyOnRails under daemontools monitoring on FreeBSD:
PHP:
cat /var/services/backend-phpfcgi/run
#!/bin/sh
exec 2>&1
exec setuidgid backend spawn-fcgi -n -a 127.0.0.1 -p 9000 -f /usr/local/bin/php-cgi
I'm using spawn-fcgi from lighttpd package, however the php-cgi can be ran directly.
RubyOnRail:
cat /var/services/backend-rubyfcgi/run
#!/bin/sh
umask 22
export RAILS_ENV=production
exec setuidgid rubysite spawn-fcgi -n -a 127.0.0.1 -p 9001 -f /home/rubysite/www/public/dispatch.fcgi
Nginx configuration files:
cat /usr/local/etc/nginx/nginx.conf
user www;
worker_processes 30;
timer_resolution 1000ms;
error_log /var/log/nginx-error.log error;
pid /var/run/nginx.pid;
events {
worker_connections 2048;
use kqueue;
}
http {
include mime.types;
default_type application/octet-stream;
access_log off;
gzip on;
gzip_comp_level 6;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
include vhosts/conf-*;
server {
listen ip.add.re.ss:80 default accept_filter=httpready;
error_page 404 /404.html;
location / {
root /home/default/www;
index index.html;
}
}
}
cat /usr/local/etc/nginx/vhosts/conf-site.com
server {
listen ip.add.re.ss;
server_name site.com www.site.com
location / {
root /home/site/www;
index index.php;
}
location ~* ^.+\.(php)$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /home/site/www/$fastcgi_script_name;
include fastcgi_params;
}
}
cat /usr/local/etc/nginx/fastcgi_params
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param REDIRECT_STATUS 200;
Nginx runs under www privileges and the back-end as a backend user so security is much improved.
P.S.
Interesting link shows nginx as third popular web server.
Sunday, June 17, 2007
new natd patch for FreeBSD using kqueue
UPDATE, this patch is not going to work properly, so forget the cricket!!!
Yesterday I've rewrote patch to natd using kqueue. Since I do not have FreeBSD with nat around, patch is not tested yet. Probably tomorrow will be chance to test. Long story- short. Testers are welcome. No warranty!!!
How to apply this patch:
(become root)
(at this point you should already have the system sources)
cd /usr/src/sbin/natd &&amp; patch -p2 < /path/to/natd.patch && make && make install clean
Yesterday I've rewrote patch to natd using kqueue. Since I do not have FreeBSD with nat around, patch is not tested yet. Probably tomorrow will be chance to test. Long story- short. Testers are welcome. No warranty!!!
How to apply this patch:
(become root)
(at this point you should already have the system sources)
cd /usr/src/sbin/natd &&amp; patch -p2 < /path/to/natd.patch && make && make install clean
Saturday, May 26, 2007
FreeBSD network settings for highly utilized squid proxy server by dial-up users
Port config knobs:
cat /var/db/ports/squid26/options
# This file is auto-generated by 'make config'.
# No user-servicable parts inside!
# Options for squid-2.6.9
_OPTIONS_READ=squid-2.6.9
WITHOUT_SQUID_LDAP_AUTH=true
WITHOUT_SQUID_SASL_AUTH=true
WITHOUT_SQUID_DELAY_POOLS=true
WITH_SQUID_SNMP=true
WITHOUT_SQUID_CARP=true
WITHOUT_SQUID_SSL=true
WITHOUT_SQUID_PINGER=true
WITHOUT_SQUID_DNS_HELPER=true
WITH_SQUID_HTCP=true
WITHOUT_SQUID_VIA_DB=true
WITH_SQUID_CACHE_DIGESTS=true
WITH_SQUID_WCCP=true
WITHOUT_SQUID_WCCPV2=true
WITH_SQUID_STRICT_HTTP=true
WITHOUT_SQUID_IDENT=true
WITHOUT_SQUID_REFERER_LOG=true
WITHOUT_SQUID_USERAGENT_LOG=true
WITHOUT_SQUID_ARP_ACL=true
WITH_SQUID_PF=true
WITHOUT_SQUID_IPFILTER=true
WITH_SQUID_FOLLOW_XFF=true
WITHOUT_SQUID_ICAP=true
WITH_SQUID_AUFS=true
WITH_SQUID_COSS=true
WITH_SQUID_KQUEUE=true
WITH_SQUID_LARGEFILE=true
WITH_SQUID_STACKTRACES=true
Boot network settings:
cat /boot/loader.conf
accf_http_load="YES"
accf_data_load="YES"
#kern.hz=1000
kern.maxproc=6164
kern.maxdsiz="1536M"
kern.dfldsiz="1536M"
kern.maxssiz="512M"
kern.ipc.msgseg=768
kern.ipc.msgssz=128
kern.ipc.msgtql=3072
kern.ipc.msgmnb=12288
kern.ipc.msgmni=60
kern.ipc.shmall=6144
kern.ipc.shmseg=24
kern.ipc.shmmni=48
kern.ipc.shmmax=51457280
kern.ipc.shm_use_phys=1
kern.ipc.nmbclusters=131072
kern.ipc.maxsockbuf=524288
net.inet.tcp.tcbhashsize=16384
Run-time settings:
cat /etc/sysctl.conf
security.bsd.see_other_uids=0
kern.maxfiles=40960
kern.maxfilesperproc=22190
kern.timecounter.hardware=TSC
kern.ipc.somaxconn=4096
cat /var/db/ports/squid26/options
# This file is auto-generated by 'make config'.
# No user-servicable parts inside!
# Options for squid-2.6.9
_OPTIONS_READ=squid-2.6.9
WITHOUT_SQUID_LDAP_AUTH=true
WITHOUT_SQUID_SASL_AUTH=true
WITHOUT_SQUID_DELAY_POOLS=true
WITH_SQUID_SNMP=true
WITHOUT_SQUID_CARP=true
WITHOUT_SQUID_SSL=true
WITHOUT_SQUID_PINGER=true
WITHOUT_SQUID_DNS_HELPER=true
WITH_SQUID_HTCP=true
WITHOUT_SQUID_VIA_DB=true
WITH_SQUID_CACHE_DIGESTS=true
WITH_SQUID_WCCP=true
WITHOUT_SQUID_WCCPV2=true
WITH_SQUID_STRICT_HTTP=true
WITHOUT_SQUID_IDENT=true
WITHOUT_SQUID_REFERER_LOG=true
WITHOUT_SQUID_USERAGENT_LOG=true
WITHOUT_SQUID_ARP_ACL=true
WITH_SQUID_PF=true
WITHOUT_SQUID_IPFILTER=true
WITH_SQUID_FOLLOW_XFF=true
WITHOUT_SQUID_ICAP=true
WITH_SQUID_AUFS=true
WITH_SQUID_COSS=true
WITH_SQUID_KQUEUE=true
WITH_SQUID_LARGEFILE=true
WITH_SQUID_STACKTRACES=true
Boot network settings:
cat /boot/loader.conf
accf_http_load="YES"
accf_data_load="YES"
#kern.hz=1000
kern.maxproc=6164
kern.maxdsiz="1536M"
kern.dfldsiz="1536M"
kern.maxssiz="512M"
kern.ipc.msgseg=768
kern.ipc.msgssz=128
kern.ipc.msgtql=3072
kern.ipc.msgmnb=12288
kern.ipc.msgmni=60
kern.ipc.shmall=6144
kern.ipc.shmseg=24
kern.ipc.shmmni=48
kern.ipc.shmmax=51457280
kern.ipc.shm_use_phys=1
kern.ipc.nmbclusters=131072
kern.ipc.maxsockbuf=524288
net.inet.tcp.tcbhashsize=16384
Run-time settings:
cat /etc/sysctl.conf
security.bsd.see_other_uids=0
kern.maxfiles=40960
kern.maxfilesperproc=22190
kern.timecounter.hardware=TSC
kern.ipc.somaxconn=4096
To repartition disk drive /duplicate file system in FreeBSD :
1. create new slice using bsdlabel
2. newfs newly created slice
3. mount it to /mnt (or wherever)
4. cd /mnt (or wherever)
5. try to minimize amount of the open files on source filesystem by killing all unnecessary daemons
6. dump -0ab 128 -C 32 -f - /dev/slicename | restore -rb 128 -f -
7. ensure backup is adequate
8. modify /etc/fstab and point new filesystem to desired mount point
9. check is everything ok throughly.
10 umount old mount point && mount new one or reboot if the live fs like e.g. /usr
1. create new slice using bsdlabel
2. newfs newly created slice
3. mount it to /mnt (or wherever)
4. cd /mnt (or wherever)
5. try to minimize amount of the open files on source filesystem by killing all unnecessary daemons
6. dump -0ab 128 -C 32 -f - /dev/slicename | restore -rb 128 -f -
7. ensure backup is adequate
8. modify /etc/fstab and point new filesystem to desired mount point
9. check is everything ok throughly.
10 umount old mount point && mount new one or reboot if the live fs like e.g. /usr
Monday, April 9, 2007
Organize files backup and upload them to ftp server
This script performs a daily files backup. The goal is to get possibility to restore any file within seven days. To economically waste disk space, the full backup is performed only once within a week on Sunday morning. On all other days only differential backup is performed (backup files changes from last FULL backup only). This technique allows to significantly speedup the restore. Scheme is simple, one full backup followed by six differential ones.
The /usr/local/etc/backup.conf file stores directories to include/exclude to/from backup, syntax is simple: the first "+" means to backup, and the "-" means to exclude from the backup.
cat /usr/local/etc/backup.conf
+/etc
+/usr/local/etc
+/usr/local/opt
+/home
-/home/www/logs
+/var/mail
+/var/qmail/control
+/var/qmail/alias
+/var/cron/tabs
-/var/mail/spam
So, here we go:
cat /usr/local/opt/files_backup.sh
#!/bin/sh
to_backup=/usr/local/etc/backup.conf
backupdir=/path/to/store/backups
ftp_to=ftp://host.name.to.put.backups.to/`hostname -s`/files
# Days to make diffs
diff_days=6
# Days to keep backup
restore_days=7
### Do not edit below
umask 037
PATH=/bin:/usr/bin
date=`date "+%Y-%m-%d"`
# Find last full backup in ${diff_days} days if exists
last_full=`find ${backupdir} -name "*-full.tbz2" -type f -mtime -${diff_days} | sort -r | head -1`
# Enumerate directories to include in backup
for dir in `cat ${to_backup}` ; do
case `expr -- "${dir}" : '\(^.\)'` in
+) include="${include} `expr -- "${dir}" : '+\(.*\)'`" ;;
-) exclude="${exclude} --exclude `expr -- "${dir}" : '-\(.*\)'`" ;;
esac
done
if [ ${last_full} ]; then
if [ "`find ${to_backup} -newer ${last_full}`" ]; then
filesuff="full.tbz2"
else
filesuff="diff.tbz2"
newer="-W newer-mtime-than=${last_full}"
fi
else
filesuff="full.tbz2"
fi
filename=${date}-${filesuff}
# Backup files and put to ftp server
tar jPpcf ${backupdir}/${filename} ${newer} ${exclude} ${include} && \
ftp -Vu ${ftp_to}/${filename} ${backupdir}/${filename}
# Find Last Full Backup to Keep ( LFB2K ) in ${restore_days} days
full2keep=`find ${backupdir} -name '*-full.tbz2' -type f -mtime +${restore_days} | sort -r | head -1`
if [ ${full2keep} ]; then
full2keep_name=`expr "//${full2keep}" : '.*/\(.*\)'`
# Delete files older than LFB2K
find ${backupdir} -type f ! -newer ${full2keep} ! -name ${full2keep_name} -name '*.tbz2' -delete
# Delete unnecessary diff files belongs to LFB2K
find ${backupdir} -type f -newerBm ${full2keep} -Btime +${restore_days} -name '*.tbz2' -delete
fi
This script can be downloaded from here.
There were some fixes and modifications.
The /usr/local/etc/backup.conf file stores directories to include/exclude to/from backup, syntax is simple: the first "+" means to backup, and the "-" means to exclude from the backup.
cat /usr/local/etc/backup.conf
+/etc
+/usr/local/etc
+/usr/local/opt
+/home
-/home/www/logs
+/var/mail
+/var/qmail/control
+/var/qmail/alias
+/var/cron/tabs
-/var/mail/spam
So, here we go:
cat /usr/local/opt/files_backup.sh
#!/bin/sh
to_backup=/usr/local/etc/backup.conf
backupdir=/path/to/store/backups
ftp_to=ftp://host.name.to.put.backups.to/`hostname -s`/files
# Days to make diffs
diff_days=6
# Days to keep backup
restore_days=7
### Do not edit below
umask 037
PATH=/bin:/usr/bin
date=`date "+%Y-%m-%d"`
# Find last full backup in ${diff_days} days if exists
last_full=`find ${backupdir} -name "*-full.tbz2" -type f -mtime -${diff_days} | sort -r | head -1`
# Enumerate directories to include in backup
for dir in `cat ${to_backup}` ; do
case `expr -- "${dir}" : '\(^.\)'` in
+) include="${include} `expr -- "${dir}" : '+\(.*\)'`" ;;
-) exclude="${exclude} --exclude `expr -- "${dir}" : '-\(.*\)'`" ;;
esac
done
if [ ${last_full} ]; then
if [ "`find ${to_backup} -newer ${last_full}`" ]; then
filesuff="full.tbz2"
else
filesuff="diff.tbz2"
newer="-W newer-mtime-than=${last_full}"
fi
else
filesuff="full.tbz2"
fi
filename=${date}-${filesuff}
# Backup files and put to ftp server
tar jPpcf ${backupdir}/${filename} ${newer} ${exclude} ${include} && \
ftp -Vu ${ftp_to}/${filename} ${backupdir}/${filename}
# Find Last Full Backup to Keep ( LFB2K ) in ${restore_days} days
full2keep=`find ${backupdir} -name '*-full.tbz2' -type f -mtime +${restore_days} | sort -r | head -1`
if [ ${full2keep} ]; then
full2keep_name=`expr "//${full2keep}" : '.*/\(.*\)'`
# Delete files older than LFB2K
find ${backupdir} -type f ! -newer ${full2keep} ! -name ${full2keep_name} -name '*.tbz2' -delete
# Delete unnecessary diff files belongs to LFB2K
find ${backupdir} -type f -newerBm ${full2keep} -Btime +${restore_days} -name '*.tbz2' -delete
fi
This script can be downloaded from here.
There were some fixes and modifications.
Monday, March 19, 2007
Organize MySQL backups and put to ftp server
So we have very important MySQL databases hosted on FreeBSD OS we do not want to lose.
First step is to create backup procedures to make backups to local disk.
But this will not help us much if server will crash.
As the second step we will put local backups to remote ftp server configured to allow only upload with unique filenames. The download and even delete or overwrite is prohibited.
FTP server configuration is the subject of another post.
I prefer to put my scripts in /usr/local/opt/. Let's name the script "mysql_backup.sh"
# cat > /usr/local/opt/mysql_backup.sh
#!/bin/sh
username=USERNAME
password=PASSWORD
backupdir=/path/to/backup
ftp_to=ftp://host.name.to.put.backups.to/`hostname -s`/db
days=7
### Do not edit below
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin
umask 077
now=`date "+%Y-%m-%dT%H:%M:%S"`
databases=`mysql -u ${username} -p${password} -N -e "show databases"`
for db in ${databases} ; do
mysqldump -u ${username} -p${password} --opt -F -l ${db} > ${backupdir}/${db}-${now} && \
bzip2 -9 ${backupdir}/${db}-${now} && \
ftp -Vu ${ftp_to}/${db}-${now}.bz2 ${backupdir}/${db}-${now}.bz2
done
find ${backupdir} -name '*-*.bz2' -a -type f -mtime +${days} -delete
^D
Script enumerates all databases and then dumps each in backup folder using DBNAME-YEAR-MONTH-DAY_HOUR:MINUTE scheme as the name. After, script archives the dump using bzip2 and upload archive to the ftp server. Last part of the script removes files in backup folder older than, in my case, 7 days.
So, everything is ready, and let's modify /etc/crontab to run script every night at 05:30
# echo "30 5 * * * root /usr/local/opt/mysql_backup.sh" >> /etc/crontab
That's it.
P.S.
Will be wise to run script manually before putting to crontab.
First step is to create backup procedures to make backups to local disk.
But this will not help us much if server will crash.
As the second step we will put local backups to remote ftp server configured to allow only upload with unique filenames. The download and even delete or overwrite is prohibited.
FTP server configuration is the subject of another post.
I prefer to put my scripts in /usr/local/opt/. Let's name the script "mysql_backup.sh"
# cat > /usr/local/opt/mysql_backup.sh
#!/bin/sh
username=USERNAME
password=PASSWORD
backupdir=/path/to/backup
ftp_to=ftp://host.name.to.put.backups.to/`hostname -s`/db
days=7
### Do not edit below
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin
umask 077
now=`date "+%Y-%m-%dT%H:%M:%S"`
databases=`mysql -u ${username} -p${password} -N -e "show databases"`
for db in ${databases} ; do
mysqldump -u ${username} -p${password} --opt -F -l ${db} > ${backupdir}/${db}-${now} && \
bzip2 -9 ${backupdir}/${db}-${now} && \
ftp -Vu ${ftp_to}/${db}-${now}.bz2 ${backupdir}/${db}-${now}.bz2
done
find ${backupdir} -name '*-*.bz2' -a -type f -mtime +${days} -delete
^D
Script enumerates all databases and then dumps each in backup folder using DBNAME-YEAR-MONTH-DAY_HOUR:MINUTE scheme as the name. After, script archives the dump using bzip2 and upload archive to the ftp server. Last part of the script removes files in backup folder older than, in my case, 7 days.
So, everything is ready, and let's modify /etc/crontab to run script every night at 05:30
# echo "30 5 * * * root /usr/local/opt/mysql_backup.sh" >> /etc/crontab
That's it.
P.S.
Will be wise to run script manually before putting to crontab.
Script to flush logs from replicant host to master
#!/bin/sh
# Format host:username:password
hosts="host1:username1:password1 host2:username2:password2"
###
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin
for system in $hosts ; do
host=`echo $system | cut -d : -f 1`
user=`echo $system | cut -d : -f 2`
password=`echo $system | cut -d : -f 3`
log=`mysql -S /tmp/$host-mysql.sock -B --skip-column-names mysql -e "show slave status" | cut -f 6`
if [ ${log} ]; then
mysql -h $host -u $user -p$password -e "PURGE MASTER LOGS TO '$log';"
fi
pid="/home/$host/`hostname`.pid"
kill -HUP `cat $pid`
done
# Format host:username:password
hosts="host1:username1:password1 host2:username2:password2"
###
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin
for system in $hosts ; do
host=`echo $system | cut -d : -f 1`
user=`echo $system | cut -d : -f 2`
password=`echo $system | cut -d : -f 3`
log=`mysql -S /tmp/$host-mysql.sock -B --skip-column-names mysql -e "show slave status" | cut -f 6`
if [ ${log} ]; then
mysql -h $host -u $user -p$password -e "PURGE MASTER LOGS TO '$log';"
fi
pid="/home/$host/`hostname`.pid"
kill -HUP `cat $pid`
done
Subscribe to:
Posts (Atom)