install mercurial with nginx

개발을 할때면 간단히 형상관리를 할수 있는 개인만의 repository를 가지고 싶어지는데, AWS 상에서 nginx서버를 이용해서 간단한 mercurial web repository 를 구성해보았다.

soruce url : http://geeksharp.com/2010/01/20/mercurial-web-with-fastcgi-nginx/ http://mercurial.selenic.com/wiki/HgWebDirStepByStep

case : ubuntu(on aws)

apt-get install nginx mercurial python-flup spawn-fcgi
mkdir /var/www/hg
chown ubuntu:www-data /var/www/hg

case : amazon linux ami(on aws)

sudo yum install nginx spawn-fcgi mercurial
sudo easy_install flup
mkdir /var/www/hg
chown ec2-user:nginx /var/www/hg

nginx를 ubuntu, yum 기본패키지를 깔수도 있고, 최신 stable 버젼으로 깔수도(http://wiki.nginx.org/Install) 있다.

vi /var/www/hg/hgwebdir.fcgi

#!/usr/bin/env python
#
# An example CGI script to export multiple hgweb repos, edit as necessary

# adjust python path if not a system-wide install:
#import sys
#sys.path.insert(0, "/path/to/python/lib")

# enable demandloading to reduce startup time
from mercurial import demandimport; demandimport.enable()

# Uncomment to send python tracebacks to the browser if an error occurs:
#import cgitb
#cgitb.enable()

# If you'd like to serve pages with UTF-8 instead of your default
# locale charset, you can do so by uncommenting the following lines.
# Note that this will cause your .hgrc files to be interpreted in
# UTF-8 and all your repo files to be displayed using UTF-8.
#
import os
os.environ["HGENCODING"] = "UTF-8"

from mercurial.hgweb.hgwebdir_mod import hgwebdir
from flup.server.fcgi import WSGIServer

# The config file looks like this. You can have paths to individual
# repos, collections of repos in a directory tree, or both.
#
# [paths]
# virtual/path1 = /real/path1
# virtual/path2 = /real/path2
# virtual/root = /real/root/*
# / = /real/root2/*
#
# [collections]
# /prefix/to/strip/off = /root/of/tree/full/of/repos
#
# paths example:
#
# * First two lines mount one repository into one virtual path, like
# '/real/path1' into 'virtual/path1'.
#
# * The third entry tells every mercurial repository found in
# '/real/root', recursively, should be mounted in 'virtual/root'. This
# format is preferred over the [collections] one, using absolute paths
# as configuration keys is not supported on every platform (including
# Windows).
#
# * The last entry is a special case mounting all repositories in
# '/real/root2' in the root of the virtual directory.
#
# collections example: say directory tree /foo contains repos /foo/bar,
# /foo/quux/baz. Give this config section:
# [collections]
# /foo = /foo
# Then repos will list as bar and quux/baz.
#
# Alternatively you can pass a list of ('virtual/path', '/real/path') tuples
# or use a dictionary with entries like 'virtual/path': '/real/path'

WSGIServer(hgwebdir('/var/www/hg/hgweb.config')).run()
sudo chmod ug+x /var/www/hg/hgwebdir.fcgi

WSGI 서버를 만들수 있도록 한다.

vi /var/www/hg/hgweb.config

[web]
baseurl = /
allow_push = *
push_ssl = false

[paths]
/ = /var/www/hg/*

WSGI 서버에서 레포지토리 연결할수 있도록 설정 파일을 설정해준다.

perl -le 'print crypt("[your-password]", "salt-hash")'
vi /var/www/hg/hgusers.config

username:encrypted-password:comment

접근 암호도 설정해준다.

vi /etc/init.d/fcgi-hg

#! /bin/sh
#
# fcgi-hg Startup script for the nginx HTTP Server
#
# chkconfig: - 84 15
# description: Loading php-cgi using spawn-cgi
# HTML files and CGI.
#
# Author: Ryan Norbauer
# Modified: Geoffrey Grosenbach http://topfunky.com
# Modified: David Krmpotic http://davidhq.com
# Modified: Kun Xi http://kunxi.org
PATH=/opt/python/bin:$PATH
DAEMON=/usr/bin/spawn-fcgi
FCGIHOST=127.0.0.1
FCGIPORT=9003
FCGIUSER=nginx # ubuntu www-data
FCGIGROUP=nginx
FCGIAPP=/var/www/hg/hgwebdir.fcgi
PIDFILE=/var/run/fcgi-hg.pid
DESC="HG in FastCGI mode"

# Gracefully exit if the package has been removed.
test -x $DAEMON || exit 0
test -x $FCGIAPP || exit 0

start() {
$DAEMON -a $FCGIHOST -p $FCGIPORT -u $FCGIUSER -g $FCGIGROUP -f $FCGIAPP -P $PIDFILE 2> /dev/null || echo -en "\n already running"
}

stop() {
kill -QUIT `cat $PIDFILE` || echo -en "\n not running"
}

restart() {
kill -HUP `cat $PIDFILE` || echo -en "\n can't reload"
}

case "$1" in
start)
echo -n "Starting $DESC: "
start
;;
stop)
echo -n "Stopping $DESC: "
stop
;;
restart|reload)
echo -n "Restarting $DESC: "
stop
# One second might not be time enough for a daemon to stop,
# if this happens, d_start will fail (and dpkg will break if
# the package is being upgraded). Change the timeout if needed
# be, or change d_stop to have start-stop-daemon use --retry.
# Notice that using --retry slows down the shutdown process somewhat.
sleep 1
start
;;
*)
echo "Usage: $SCRIPTNAME {start|stop|restart|reload}" >&2
exit 3
;;
esac

exit $?

서버 실행시 서비스 등록을 해준다.

sudo chkconfig fcgi-hg on		# case amazon linux ami or centos
sudo update-rc.d fcgi-hg defaults		# case ubuntu

fcgi-hg 에 대한 init script를 만들어주고 등록한다.

vi /etc/nginx/host.d/xxxxx

server {
	listen 80;
	server_name test.abc.com;
	root /var/www/hg/;
	gzip on;

	location / {
		include fastcgi_params;
		fastcgi_pass 127.0.0.1:9003;
		fastcgi_split_path_info ^(/)(.*)$;
		fastcgi_param  SCRIPT_NAME      $fastcgi_script_name;
		fastcgi_param  PATH_INFO        $fastcgi_path_info;
		fastcgi_param  AUTH_USER        $remote_user;
		fastcgi_param  REMOTE_USER      $remote_user;
		fastcgi_intercept_errors        off;
		limit_except GET HEAD {
			auth_basic  'Geek\'s Repositories';
			auth_basic_user_file /var/www/hg/hgusers.config;
		}
	}
	location /static/ {
		rewrite /static/(.*) /$1 break;
		root /usr/lib/python2.6/site-packages/mercurial/templates/static;
		expires 30d;
	}
}

nginx 웹설정 파일을 수정해주고 nginx를 restart 를 하면 해당 도메인으로 mercurial web repository가 뜨는 것을 볼 수 있다.

hg init /var/www/hg/[project_name]
sudo chgrp -R nginx /var/www/hg/[project_name]	# case centos
sudo chgrp -R www-data /var/www/hg/[project_name]	# case ubuntu

[project_name]의 이름의 프로젝트를 위와 같이 추가하면 각각의 프로젝트에 대해 repository 가 생기는 것을 볼수 있다.

iptables simple setting

linux 서버를 셋팅할때 각각 배포본마다 설정되어있는 iptables 설정은 배포본의 경계를 넘나들때나, 변경할때 귀찮기 마련이다. 그래서 마련한 간단히 셋팅을 바꿀수 있는 스크립트.

referance : http://wiki.centos.org/HowTos/Network/IPTables

case : centos

vi gen_iptable.sh

#!/bin/bash
/sbin/iptables -F
# Allow SSH connections on tcp port 22
/sbin/iptables -A INPUT -i eth0 -p tcp --dport 22 -j ACCEPT
# Set default policies for INPUT, FORWARD and OUTPUT chains
/sbin/iptables -P INPUT DROP
/sbin/iptables -P FORWARD DROP
/sbin/iptables -P OUTPUT ACCEPT
# Set access for localhost
/sbin/iptables -A INPUT -i lo -j ACCEPT
# Accept packets belonging to established and related connections
/sbin/iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# My Firewall
/sbin/iptables -A INPUT -i eth0 -p tcp --dport 80 -j ACCEPT
/sbin/iptables -A INPUT -i eth0 -p tcp --dport 22 -s xxx.xxx.xxx.xxx -j ACCEPT
# Save settings
/sbin/service iptables save
# List rules
/sbin/iptables -L -v

case : ubuntu

vi gen_iptable.sh

#!/bin/bash
/sbin/iptables -F
# Allow SSH connections on tcp port 22
/sbin/iptables -A INPUT -i eth0 -p tcp --dport 22 -j ACCEPT
# Set default policies for INPUT, FORWARD and OUTPUT chains
/sbin/iptables -P INPUT DROP
/sbin/iptables -P FORWARD DROP
/sbin/iptables -P OUTPUT ACCEPT
# Set access for localhost
/sbin/iptables -A INPUT -i lo -j ACCEPT
# Accept packets belonging to established and related connections
/sbin/iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# My Firewall
/sbin/iptables -A INPUT -i eth0 -p tcp --dport 80 -j ACCEPT
/sbin/iptables -A INPUT -i eth0 -p tcp --dport 22 -s xxx.xxx.xxx.xxx -j ACCEPT
# Save settings
/sbin/iptables-save > /etc/iptables.rule
# List rules
/sbin/iptables -L -v

using clamav & php-clamv

clamv는 오픈소스로 제공되는 백신프로그램이다. 또한 php-clamv를 이용하면 업로드 되는 파일이 바이러스나 웹쉘, rootkit일 경우 잡아줄수 있는 php 라이브러리이다.

hompage : http://www.clamav.net/

case centos :

wget http://download.fedora.redhat.com/pub/epel/5/i386/clamav-db-0.97-12.el5.i386.rpm
wget http://download.fedora.redhat.com/pub/epel/5/i386/clamav-0.97-12.el5.i386.rpm
wget http://download.fedora.redhat.com/pub/epel/5/i386/clamav-devel-0.97-12.el5.i386.rpm
wget http://download.fedora.redhat.com/pub/epel/5/i386/clamd-0.97-12.el5.i386.rpm
rpm -Uvh clamav-db-0.97-12.el5.i386.rpm clamav-0.97-12.el5.i386.rpm clamav-devel-0.97-12.el5.i386.rpm clamd-0.97-12.el5.i386.rpm

referance : http://code.google.com/p/clamav-cron/

clamav-cron를 이용하면 쉽게 cron등록을 할 수 있다. (단 실제 실행해보니 몇가지 권한 문제가 있어서 몇가지 수정했다. 알맞게 이메일등과 메일 제목들을 수정해준다.)

wget http://clamav-cron.googlecode.com/files/clamav-cron-0.6 -O /usr/local/bin/clamav-cron
chmod 755 /usr/local/bin/clamav-cron
vi /usr/local/bin/clamav-cron 

#!/bin/bash
#
# clamav-cron v. 0.6.1 - Copyright © 2009, Stefano Stagnaro & Yupmin
# This is Free Software released under the GNU GPL license version 3

#============================================#
#        User configuration section          #
#============================================#

# Log file name and its path:
CV_LOGFILE="/var/log/clamav-cron.log"

# Notification e-mail sender (could be fake):
CV_MAILFROM="abc@test.com"

# Notification e-mail recipient:
CV_MAILTO="abc@test.com"

# Notification e-mail secondary recipients:
#CV_MAILTO_CC="stefano@abc.com; danilo@abc.com"

# Notification e-mail subject:
CV_SUBJECT="Test.com - ClamAV scan report"

#============================================#

CV_TARGET="$1"
CV_VERSION="0.6"

if [ -e $CV_LOGFILE ]
then
        /bin/rm $CV_LOGFILE
fi
/bin/touch $CV_LOGFILE
/bin/chmod 666 $CV_LOGFILE
/bin/chmod o+w /var/lib/clamav

if [ -z "$1" ]
then
        CV_TARGET="$HOME"
fi

#To be read on stdout (and root mail):
echo -e `basename $0` v. $CV_VERSION - Copyright 2009, Stefano Stagnaro '\n'

#To be read on logfile (sent via sendmail):
echo -e $CV_SUBJECT - $(date) '\n' >> $CV_LOGFILE
echo -e Script: `basename $0` v. $CV_VERSION - Copyright 2009, Stefano Stagnaro  >> $CV_LOGFILE
echo -e Scanned: $CV_TARGET on $HOSTNAME'\n' >> $CV_LOGFILE

/usr/bin/freshclam --log=$CV_LOGFILE --user $USER --verbose

#To be read on stdout (and root mail):
echo -e '------------------------------------\n'

/usr/bin/clamscan --infected --log=$CV_LOGFILE --recursive $CV_TARGET
CLAMSCAN=$?

if [ "$CLAMSCAN" -eq "1" ]
then
        CV_SUBJECT="[VIRUS!] "$CV_SUBJECT
elif [ "$CLAMSCAN" -gt "1" ]
then
        CV_SUBJECT="[ERR] "$CV_SUBJECT
fi

#/bin/mail -s "$CV_SUBJECT" -c $CV_MAILTO_CC $CV_MAILTO -- -f $CV_MAILFROM < $CV_LOGFILE
/bin/mail -s "$CV_SUBJECT" $CV_MAILTO -- -f $CV_MAILFROM < $CV_LOGFILE

cron으로 매일 돌리지 말고, 중요한 부위등을 알맞게 나눠서 돌리면 될듯 하다.

vi /etc/crontab
45 23 * * 6 /usr/local/bin/clamav-cron /home

clamav-php 라이브러리는 다음과 같이 설치한다. 기본 clamav가 깔려있는 clamav database path등에 유의한다.

php-clamav의 경우 centos 5 에 컴파일해서 사용할 경우 아파치 프로세스크가가 5~7배 커지는 것으로 보임. 사용주의 요망.

source : http://php-clamav.sourceforge.net/

wget http://sourceforge.net/projects/php-clamav/files/0.15/php-clamav_0.15.3.tar.gz/download
tar xvfz php-clamav-0.15.3
cd php-clamav-0.15.3
phpize
./configure --with-clamav
make; make install;
vi /etc/clamav.ini

extension=clamav.so
[clamav]
clamav.dbpath="/var/clamav"
clamav.maxreclevel=16
clamav.maxfiles=10000
clamav.maxfilesize=26214400
clamav.maxscansize=104857600
clamav.keeptmp=0
clamav.tmpdir="/var/tmp"