Автоматизация начальной настройки веб-сервера

от автора

Наверняка, у многих есть собственные веб серверы. Настройка нового сервера с нуля — достаточно нудное и времяубивающее трудоемкое занятие не только для новичка, но и для бывалых.

А если к тому же по долгу службы вам приходится настраивать по несколько серверов в неделю/месяц, то невольно начинаешь задумываться об автоматизации этого процесса. Хочу поделиться bash скриптом, который я использую для начальной настройки RedHat / CentOS серверов.

Идею этого скрипта я подсмотрел давным давно у ныне заброшенного проекта Centmin. Скрипт рассчитан на настройку RedHat Enterprise Linux (CentOS) версий 5 и 6, но может быть легко адаптирован для других систем.

Итак, ввиду большого количества комментариев в коде, приведу только краткое описание.

  • Подключение репозиториев epel, ius, nginx. Обновление пакетов
  • Устанавка минимального набора утилит, необходимых для нормальной работы системы, а также зависимостей для новых программ
  • Настройка SSHD
  • Установка NTPD, выбор временной зоны, синхронизация даты
  • Монтирование /tmp и /dev/shm c атрибутами noexec и nosuid
  • Установка и настройка Virtualmin, CSF Firewall, MySQL 5.5, PHP 5.4, Nginx, Postfix, SaslAuth, phpMyAdmin
  • Установка и обновление CPANminus как замены CPAN
  • Отключение ненужных сервисов из автозагрузки

Большинство операций скрипт выполнит самостоятельно, но некоторые действия со стороны пользователя все же необходимы. Например, ввод данных для создания SSL сертификата и подтверждение установки Virtualmin.

Приветствуются любые предложения и замечания, я далеко не специалист по написанию скриптов на BASH.

p.s. прошу извинить за английский, я не привык писать комментарии в коде на русском.

И так, сам скрипт…

#!/bin/sh # Author: sam2kb  ROOT_ALIAS='vasya@pupkin.ru'  # Set your email here CENTOS_VERSION='6'  # Major RedHat version e.g. 5 or 6  ZONEINFO='America/New_York' SET_TIMEZONE=y UPDATE_PACKAGES=y ADD_REPOS=y ALTER_KERNEL_PARAMS=y SECURE_TMP=y SECURE_SHM=y SECURE_SSHD=y SSHD_PORT=11022 SSHD_USERS='root'  # Allowed IPs CSF_IGNORE=' 188.72.80.205 # Sape.ru 188.72.80.201 # Sape.ru';  # Allowed IPs WEBMIN_ALLOW='' # Separate with space WEBMIN_PORT=11033  INSTALL_WEBMIN=y INSTALL_CPANMIN=y INSTALL_CSF=y INSTALL_NTP=y	# Install Network time protocol daemon INSTALL_PMNV=y	# PHP, MYSQL, NGINX, VIRTUALMIN INSTALL_PMA=y	# Install phpMyAdmin PMA_VERSION='3.5.3'  # YOU SHOULD NOT NEED TO MODIFY ANYTHING BELOW THIS LINE  +++++++++++++++++++ # JUST RUN "sh /server-init.sh" # ############################################################### SCRIPT_NAME='Initial server setup script' DIR_TMP="/server-init"			# Working directory to be created by installer KEYPRESS_PARAM='-s -n1 -p'		# Read a keypress without hitting ENTER 								# -s means do not echo input 								# -n means accept only N characters of input 								# -p means echo the following prompt before reading input ASKCMD="read $KEYPRESS_PARAM " CUR_DIR=`pwd`					# Get current directory MACHINE_TYPE=`uname -m`			# Used to detect if OS is 64bit or not if [ "${MACHINE_TYPE}" == 'i686' ]; then 	MACHINE_TYPE='i386' fi ############################################################### # FUNCTIONS  ASK () { 	keystroke='' 	while [[ "$keystroke" != [yYnNaA] ]]; do 		$ASKCMD "$1" keystroke 		echo "$keystroke"; 	done 	key=$(echo $keystroke) }  # Setup colors black='\E[30;40m' red='\E[31;40m' green='\E[32;40m' yellow='\E[33;40m' blue='\E[34;40m' magenta='\E[35;40m' cyan='\E[36;40m' white='\E[37;40m'  boldblack='\E[1;30;40m' boldred='\E[1;31;40m' green='\E[1;32;40m' boldyellow='\E[1;33;40m' boldblue='\E[1;34;40m' boldmagenta='\E[1;35;40m' boldcyan='\E[1;36;40m' boldwhite='\E[1;37;40m'  reset="tput sgr0"      #  Reset text attributes to normal without clearing screen  cecho ()	# Colored-echo. 			# $1 = message 			# $2 = color 			# if $3 not set, print stars { 	message=$1 	color=$2  	if [[ $3 == '' ]]; then 		echo " "; 		echo -e "$color********************************************************"; $reset; 	fi 	echo -e "$color* $message" ; $reset  	if [[ $3 == '' ]]; then 		echo -e "$color********************************************************"; $reset; 		echo " "; 	fi 	sleep 0.3 # sleep for two seconds 	return }  run_the_script () { 	# If OpenVZ user add user/group 500 - else various folders and devices 	# will end up with an odd user/group name for some reason 	if [ -f /proc/user_beancounters ]; then 		groupadd 500 		useradd -g 500 -s /sbin/nologin -M 500 	fi  	if [ "${ROOT_ALIAS}" != '' ]; then 		cecho "Adding root alias" $green 		sed -i 's/#root:\s*marc/root:\t\t'"${ROOT_ALIAS}"'/g' /etc/aliases 		newaliases 	fi  	if [[ "$UPDATE_PACKAGES" = [yY] ]]; then 		cecho "Updating packages" $green 		yum clean all 		yum -y update glibc\* 		yum -y update yum\* rpm\* python\* 		yum clean all 		yum -y update 	fi  	if [[ "$ADD_REPOS" = [yY] ]]; then 		cecho "* Adding repositories" $green 		yum install -y wget rpm  		if [ "${CENTOS_VERSION}" == '5' ]; then 			wget -c http://dl.iuscommunity.org/pub/ius/stable/Redhat/5/${MACHINE_TYPE}/ius-release-1.0-10.ius.el5.noarch.rpm --tries=3 			wget -c http://dl.iuscommunity.org/pub/ius/stable/Redhat/5/${MACHINE_TYPE}/epel-release-5-4.noarch.rpm --tries=3 			wget -c http://nginx.org/packages/centos/5/noarch/RPMS/nginx-release-centos-5-0.el5.ngx.noarch.rpm --tries=3 		else 			wget -c http://dl.iuscommunity.org/pub/ius/stable/Redhat/6/${MACHINE_TYPE}/ius-release-1.0-10.ius.el6.noarch.rpm --tries=3 			wget -c http://dl.iuscommunity.org/pub/ius/stable/Redhat/6/${MACHINE_TYPE}/epel-release-6-5.noarch.rpm --tries=3 			wget -c http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm --tries=3 		fi  		rpm -ivh epel-release-* 		rpm -ivh ius-release-* 		rpm -ivh nginx-release-centos-*  		yum -y update epel-release ius-release nginx-release-centos 	fi  	if [[ "$UPDATE_PACKAGES" = [yY] ]]; then 		cecho "Updating packages (new repos)..." $green 		yum clean all 		yum -y update 	fi  	cecho "Installing Development Tools" $green 	yum -y install wget perl perl-CPAN perl-devel perl-YAML perl-Time-HiRes perl-DBD-MySQL perl-libwww-perl perl-Net-SSLeay python gcc make automake autoconf patch mlocate libtool nano rsync sysstat lsof curl xterm dbus-x11 libXt-devel unzip zip zlib bzip2 openssh* file e2fsprogs iptables* libjpeg libpng freetype pam-devel  	if [[ "$ALTER_KERNEL_PARAMS" = [yY] ]]; then 		cecho "Altering kernel params" $green 		echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout; 		echo 3000 > /proc/sys/net/core/netdev_max_backlog; 		echo 3000 > /proc/sys/net/core/somaxconn; 		echo 10 > /proc/sys/net/ipv4/tcp_keepalive_intvl; 		echo 2 > /proc/sys/net/ipv4/tcp_keepalive_probes; 		echo 300000 > /proc/sys/fs/file-max;  		cat >> /etc/security/limits.conf <<EOF  *               soft    nofile          20000 *               hard    nofile          150000 EOF 	fi  	if [[ "$SECURE_SSHD" = [yY] ]]; then 		cecho "Securing SSHD" $green 		cat >> /etc/ssh/sshd_config <<EOF  UseDNS no Port $SSHD_PORT Protocol 2 AllowUsers $SSHD_USERS EOF 	fi  	if [[ "$SECURE_TMP" = [yY] ]]; then 		cecho "Secured /tmp and /var/tmp" $green 		rm -rf /tmp; mkdir /tmp; 		mount -t tmpfs -o rw,noexec,nosuid tmpfs /tmp 		chmod 1777 /tmp 		echo "tmpfs                   /tmp                    tmpfs   rw,noexec,nosuid     0 0" >> /etc/fstab 		rm -rf /var/tmp; ln -s /tmp /var/tmp 	fi  	if [[ "$SECURE_SHM" = [yY] ]]; then 		cecho "Secured /dev/shm" $green 		umount /dev/shm; rm -rf /dev/shm; mkdir /dev/shm 		mount -t tmpfs -o rw,noexec,nosuid tmpfs /dev/shm 		chmod 1777 /dev/shm; 		echo "tmpfs                   /dev/shm                tmpfs   rw,noexec,nosuid     0 0" >> /etc/fstab 	fi  	if [[ "$SET_TIMEZONE" = [yY] ]]; then 		cecho "Setting preferred timezone" $green 		rm -f /etc/localtime 		ln -s /usr/share/zoneinfo/$ZONEINFO /etc/localtime 		cecho "Current date & time for the zone you selected is: " $green "-" 		date 	fi  	if [[ "$INSTALL_PMNV" = [yY] ]]; then 		cecho "Removing old mysql package" $green 		service mysqld stop 		rpm -e --nodeps mysql-libs  		cecho "Installing MYSQL" $green 		yum -y install mysql55-server mysql55-devel mysql55-libs mysqlclient16  		cecho "Installing PHP" $green 		yum -y install php54 php54-bcmath php54-cli php54-common php54-devel php54-fpm php54-gd php54-imap php54-ioncube-loader php54-mbstring php54-mcrypt php54-mysql php54-pear php54-pecl-geoip php54-pecl-apc php54-process php54-xml php54-xmlrpc  		cecho "Installing NGINX" $green 		yum -y install nginx 	fi   	if [[ "$INSTALL_CPANMIN" = [yY] ]]; then 		# Install and upgrade cpanmin 		curl -L http://cpanmin.us | perl - --self-upgrade  		# Install system modules 		cpanm Authen::Libwrap Authen::PAM Time:HiRes IO::Pty Getopt::Long Digest::SHA1 Net::SSLeay 	fi   	if [[ "$INSTALL_WEBMIN" = [yY] ]]; then 		cecho "Installing Webmin" $green 			wget -c http://www.webmin.com/download/rpm/webmin-current.rpm --tries=3 			rpm -ivh webmin-*  			sed -i "s/port=10000/port=$WEBMIN_PORT/g" /etc/webmin/miniserv.conf 			sed -i "s/listen=10000/listen=$WEBMIN_PORT/g" /etc/webmin/miniserv.conf 			sed -i "s/ssl=0/ssl=1/g" /etc/webmin/miniserv.conf  			if [ "${WEBMIN_ALLOW}" != '' ]; then 				cat >> /etc/webmin/miniserv.conf<<EOF allow=$WEBMIN_ALLOW EOF 			fi 			service webmin restart 	fi   	if [[ "$INSTALL_PMNV" = [yY] ]]; then 		cecho "Installing Virtualmin" $green 		cd /usr/local/src 		wget -c http://software.virtualmin.com/gpl/scripts/install.sh --tries=3  		# Skip obsolete packages (we already installed latest versions of PHP and MySQL) 		sed -i 's/mysql mysql-server mysql-devel //g' /usr/local/src/install.sh 		sed -i 's/php php-xml php-gd php-imap php-mysql php-odbc php-pear php-pgsql php-snmp php-xmlrpc php-mbstring //g' /usr/local/src/install.sh  		# Virtualmin requires insecure /tmp 		mount -o remount,exec /tmp 		sh install.sh 		mount -o remount /tmp  		# Stop useless services 		service mailman stop; chkconfig mailman off 		service usermin stop; chkconfig usermin off  		cecho "Setting up Postfix" $green 		mkdir /etc/postfix/ssl 		POSTFIX_SSL='/etc/postfix/ssl'  		# Generate SSL certificate for Postfix 		openssl genrsa -des3 -rand /etc/hosts -out $POSTFIX_SSL/smtpd.key 1024 		chmod 600 $POSTFIX_SSL/smtpd.key 		openssl req -new -key $POSTFIX_SSL/smtpd.key -out $POSTFIX_SSL/smtpd.csr 		openssl x509 -req -days 3650 -in $POSTFIX_SSL/smtpd.csr -signkey $POSTFIX_SSL/smtpd.key -out $POSTFIX_SSL/smtpd.crt 		openssl rsa -in $POSTFIX_SSL/smtpd.key -out $POSTFIX_SSL/smtpd.key.unencrypted 		mv -f $POSTFIX_SSL/smtpd.key.unencrypted $POSTFIX_SSL/smtpd.key 		openssl req -new -x509 -extensions v3_ca -keyout $POSTFIX_SSL/cakey.pem -out $POSTFIX_SSL/cacert.pem -days 3650  		# TODO: postfix config, dovecot config  		# Fix saslauthd path 		mkdir -p /var/spool/postfix/var/run/saslauthd 		chown postfix.root -R /var/spool/postfix/var/ 		sed -i 's~SOCKETDIR=.*$~SOCKETDIR=/var/spool/postfix/var/run/saslauthd~g' /etc/sysconfig/saslauthd 		service saslauthd restart  		# Copy postfix certificate over to nginx 		cecho "Setting up nginx" $green 		mkdir -p /var/nginx/temp; mkdir /etc/nginx/ssl 		cp /etc/postfix/ssl/smtpd.crt /etc/nginx/ssl/server.crt 		cp /etc/postfix/ssl/smtpd.key /etc/nginx/ssl/server.key   		if [[ "$INSTALL_PMA" = [yY] ]]; then 			cecho "Installing phpMyAdmin" $green 			mkdir /home/www; 			wget -c http://downloads.sourceforge.net/project/phpmyadmin/phpMyAdmin/${PMA_VERSION}/phpMyAdmin-${PMA_VERSION}-english.zip --tries=3 			unzip phpMyAdmin-${PMA_VERSION}-english.zip; 			mv phpMyAdmin-${PMA_VERSION}-english /home/www/pma 			rm -rf /home/www/pma/setup  			# Random blowfish secret 			BLOWFISH=`tr -dc A-Za-z0-9_ < /dev/urandom | head -c 30` 			cat >/home/www/pma/config.inc.php<<EOF <?php  \$cfg['blowfish_secret'] = '$BLOWFISH';  ?> EOF 			chown apache.apache -R /home/www/pma; 		fi  		cecho "Setting up installed services" $green 		service proftpd stop; chkconfig proftpd off 		service httpd stop; chkconfig httpd off  		service nginx start; chkconfig nginx on 		service mysqld start; chkconfig mysqld on 		service php-fpm start; chkconfig php-fpm on 	fi   	if [[ "$INSTALL_CSF" = [yY] ]]; then 		cecho "Installing CSF firewall" $green 		wget -c http://www.configserver.com/free/csf.tgz --tries=3  		tar zxf csf.tgz -C $DIR_TMP/; cd $DIR_TMP/csf 		sh install.sh 		cd $DIR_TMP  		# Make sure log file exists 		touch /var/log/lfd.log  		cecho "Testing IP Tables Modules" $green 		perl /etc/csf/csftest.pl  		CCONF='/etc/csf/csf.conf'  		cecho "Configuring CSF, step 1" $green 		sed -i 's/TESTING_INTERVAL = "[^"]*"/TESTING_INTERVAL = "10"/g' $CCONF 		sed -i 's/AUTO_UPDATES = "0"/AUTO_UPDATES = "1"/g' $CCONF 		sed -i 's/ICMP_OUT_RATE = "[^"]*"/ICMP_OUT_RATE = "2\/s"/g' $CCONF 		sed -i 's/DENY_IP_LIMIT = "[^"]*"/DENY_IP_LIMIT = "200"/g' $CCONF 		sed -i 's/PS_EMAIL_ALERT = "1"/PS_EMAIL_ALERT = "0"/g' $CCONF 		sed -i 's/DROP_NOLOG = "[^"]*"/DROP_NOLOG = "21,22,67,68,82,111,113,135:139,445,513,520,1433,3306"/g' $CCONF 		sed -i 's/SAFECHAINUPDATE = "0"/SAFECHAINUPDATE = "1"/g' $CCONF  		cecho "Configuring CSF, step 2" $green 		if [ ! -f /proc/user_beancounters ]; then 			# Flood protection. Not available in OpenVZ 			sed -i 's/SYNFLOOD = "0"/SYNFLOOD = "1"/g' $CCONF 			sed -i 's/SYNFLOOD_RATE = "[^"]*\/s"/SYNFLOOD_RATE = "100\/s"/g' $CCONF 			sed -i 's/SYNFLOOD_BURST = "[^"]*"/SYNFLOOD_BURST = "150"/g' $CCONF 		fi  		sed -i 's/TCP_IN = "[^"]*"/TCP_IN = "25,53,80,143,443,465,587,993,995,'"${WEBMIN_PORT}"','"${SSHD_PORT}"'"/g' $CCONF 		sed -i 's/LF_DSHIELD = "0"/LF_DSHIELD = "86400"/g' $CCONF 		sed -i 's/LF_SPAMHAUS = "0"/LF_SPAMHAUS = "86400"/g' $CCONF 		sed -i 's/LF_DIRWATCH = "[^"]*"/LF_DIRWATCH = "0"/g' $CCONF 		sed -i 's/LF_INTEGRITY = "[^"]*"/LF_INTEGRITY = "0"/g' $CCONF 		sed -i 's/LF_DISTATTACK = "0"/LF_DISTATTACK = "1"/g' $CCONF 		sed -i 's/LF_DISTATTACK_UNIQ = "[^"]*"/LF_DISTATTACK_UNIQ = "3"/g' $CCONF  		cecho "Configuring CSF, step 3" $green 		sed -i 's/LF_NETBLOCK = "0"/LF_NETBLOCK = "1"/g' $CCONF 		sed -i 's/LF_NETBLOCK_COUNT = "[^"]*"/LF_NETBLOCK_COUNT = "6"/g' $CCONF 		sed -i 's/LF_SSHD = "[^"]*"/LF_SSHD = "2"/g' $CCONF 		sed -i 's/LF_FTPD = "[^"]*"/LF_FTPD = "3"/g' $CCONF 		sed -i 's/LF_SMTPAUTH = "[^"]*"/LF_SMTPAUTH = "3"/g' $CCONF 		sed -i 's/LF_POP3D = "[^"]*"/LF_POP3D = "3"/g' $CCONF 		sed -i 's/LF_IMAPD = "[^"]*"/LF_IMAPD = "3"/g' $CCONF  		cd $DIR_TMP  		cecho "Adding Applications/Users to CSF ignore list" $green  		cat >>/etc/csf/csf.pignore<<EOF  exe:/usr/libexec/mysqld exe:/usr/sbin/php-fpm exe:/usr/sbin/nginx user:postfix user:dovecot user:dovenull user:haldaemon EOF  		cat >>/etc/csf/csf.ignore<<EOF  74.125.0.0/16 # Google 77.88.0.0/18 # Yandex $CSF_IGNORE EOF  		cat >>/etc/csf/csf.rignore<<EOF  .googlebot.com .google.com .1e100.net .yahoo.net .msn.com .mail.ru .yandex.ru EOF  		chkconfig --levels 235 csf on 		service csf restart  		if [[ "$INSTALL_WEBMIN" = [yY] ]]; then 			cecho "Installing Webmin CSF module" $green 			perl /usr/libexec/webmin/install-module.pl /etc/csf/csfwebmin.tgz 		fi 	fi   	if [ -f /proc/user_beancounters ]; then 		cecho "OpenVZ system detected, NTP not installed" $green 	else 		if [[ "$INSTALL_NTP" = [yY] ]]; then 			cecho "Installing NTP (and syncing time)" $green 			yum -y install ntp 			chkconfig --levels 235 ntpd on 			ntpdate pool.ntp.org 			cecho "The date/time is now:" $green 			date 			cecho "If this is correct, then everything is working properly" $green  			service ntpd restart 		fi 	fi  	# Final yum update 	yum -y update  }  ################################################################ # SCRIPT START # clear  cecho "********************************************************" $boldyellow "-" cecho "$SCRIPT_NAME" $green "-" cecho "********************************************************" $boldyellow "-" echo " " ASK "Would you like to continue? [y/n] " if [[ "$key" = [nN] ]]; then     exit 0 fi  if [ -d "$DIR_TMP" ]; then 	ASK "It seems that you have run this script before. Do you want to exit? [y/n]" 	if [[ "$key" = [yY] ]]; then 		cecho "Installation aborted " $green 		exit 	fi else 	mkdir $DIR_TMP; cd $DIR_TMP 	run_the_script fi  cd $DIR_TMP   cecho "**********************************************************************" $green "-" cecho "* Installation complete, congratulations!" $green "-" cecho "* Enjoy CentOS!" $green "-" cecho "**********************************************************************" $green "-"  cecho "Temporary files/folders removed" $green 	cd; rm -rf $DIR_TMP  cecho "Running updatedb command. Please wait..." $green 	updatedb  cecho "Deleting $SCRIPT_NAME" $green 	rm -f $0  cecho "Disabling services" $green 	if [ "${CENTOS_VERSION}" == '5' ]; then 		# Add services you want to disable 		chkconfig xfs off; service xfs stop 		chkconfig atd off; service atd stop 		chkconfig nfslock off; service nfslock stop 		chkconfig rpcidmapd off; service rpcidmapd stop 		chkconfig anacron off; service anacron stop 		chkconfig avahi-daemon off; service avahi-daemon stop 		chkconfig hidd off; service hidd stop 		chkconfig pcscd off; service pcscd stop 	else 		# Add services you want to disable 		chkconfig avahi-daemon off; service avahi-daemon stop 	fi  if [[ "$SECURE_SSHD" = [yY] ]]; then 	service sshd restart fi  cecho "All done! It's recommended to reboot the server now." $green exit; 

ссылка на оригинал статьи http://habrahabr.ru/post/158523/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *