Pandora Pocket

IT系と日常系の備忘録。三日坊主。

これまでUbuntuにLAMPサーバーを構築するための備忘録を書いていたのだけど、だんだん面倒になってきたので、勉強がてら一気にLAMPサーバーを構築することのできるシェルスクリプトを書いてみた。

例によってノークレームノーリターンで。

#!/bin/sh

######################################################################
#Ubuntu 自動サーバー構築シェルスクリプト
#Version 1.0.3
#作者 Ovis http://pandora.hitsujin.jp/

##修正点
#1.03 Webmiのインストールを選択制に変更
#1.02 SSHポートを変更してもiptablesの変更が行われてなかった問題の修正
#1.01 動かないバグの修正
#1.00 公開

######################################################################

#アップデート
apt-get update

######################################################################
# ロケールの変更
echo 'ロケールの変更を行いますか?(Y/N)'
while [ 1 ]
do
echo -n "-->"
read time
case $time in
y|Y)
apt-get install -y language-pack-ja
dpkg-reconfigure locales
update-locale LANG=ja_JP.UTF-8
sed -i -e 's/ja_JP ja_JP.eucJP/ja_JP ja_JP.UTF-8/' /etc/locale.alias
break

;;
n|N)
break
;;
*) echo "Error! YかNを入力して下さい。"
esac
done

######################################################################
# ユーザー作成、root昇格制限

sed -i -e 's/DIR_MODE=0755/DIR_MODE=0701/' /etc/adduser.conf
sed -i -e 's/#UMASK 022/#UMASK 072/' /etc/login.defs
echo 'adminアカウントの追加を行います。パスワードを設定してください。'
useradd -d /home/admin -g adm -s /bin/bash -m admin
passwd admin
sed -i -e 's/# auth required pam_wheel.so/auth required pam_wheel.so group=adm/' /etc/pam.d/su

#SSHセキュリティ対策

apt-get install -y denyhosts
sed -i -e 's/PURGE_DENY =/PURGE_DENY = 3h/' /etc/denyhosts.conf
sed -i -e 's/DENY_THRESHOLD_INVALID = 5/DENY_THRESHOLD_INVALID = 2/' /etc/denyhosts.conf
sed -i -e 's/DENY_THRESHOLD_VALID = 10/DENY_THRESHOLD_VALID = 5/' /etc/denyhosts.conf
sed -i -e 's/ADMIN_EMAIL = root@localhost/#ADMIN_EMAIL = root@localhost/' /etc/denyhosts.conf
echo 'SSHのポート番号を変更します。(デフォルトは22)'
echo -n "-->"
read sshport
sed -i -e "s/Port 22/Port ${sshport}/" /etc/ssh/sshd_config
sed -i -e 's/ADMIN_EMAIL = root@localhost/#ADMIN_EMAIL = root@localhost/' /etc/denyhosts.conf
sed -i -e "s/-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT/-A INPUT -p tcp -m tcp --dport ${sshport} -j ACCEPT/" /etc/iptables.up.rules

iptables-restore < /etc/iptables.up.rules

######################################################################

# Apache2、PHP等インストール

echo '途中入力画面が表示されます。'

apt-get install -y mysql-server sqlite3
apt-get install -y apache2 apache2-dev
apt-get install -y xinetd
apt-get install -y postfix
apt-get install -y php5 php-pear php5-gd php-apc php5-dev php5-cli php5-mcrypt php5-mhash php5-xsl php5-xmlrpc libssh2-php
apt-get install -y libapache2-mod-suphp
pecl install htscanner channel://pecl.php.net/htscanner-1.0.0
apt-get install -y php5-mysql php5-sqlite php-mdb2-driver-sqlite
apt-get install -y libapache2-mod-speedycgi
apt-get install -y phpmyadmin
apt-get install -y imagemagick libmagick9-dev

#Webminインストール

echo 'Webminのインストールを行いますか?(Y/N)'

while [ 1 ]
do
echo -n "-->"
read time
case $time in
y|Y)
wget http://nchc.dl.sourceforge.net/sourceforge/webadmin/webmin_1.550_all.deb -P /tmp
dpkg -i /tmp/webmin_1.550_all.deb
apt-get -f -y install
echo 'Webminのポート番号を変更します。(デフォルトは10000)'
echo -n "-->"
read webminport
sed -i -e "s/port=10000/port=${webminport}/" /etc/webmin/miniserv.conf
iptables -A INPUT -p tcp -m tcp --dport ${webminport} -j ACCEPT
break
;;
n|N)
break
;;
*) echo "Error! YかNを入力して下さい。"
esac
done

######################################################################

#iptables

iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT

iptables-save > /etc/iptables.up.rules

######################################################################

# Apacheの設定

#モジュール設定

a2enmod cache expires headers include rewrite speling speedycgi proxy

a2dismod autoindex

#ファイルの編集

#apache2.conf

sed -i -e 's/Timeout 300/Timeout 60/' /etc/apache2/apache2.conf
sed -i -e 's/ StartServers 5/ StartServers 3/' /etc/apache2/apache2.conf
sed -i '/ MinSpareServers 5/i ServerLimit 128' /etc/apache2/apache2.conf
sed -i -e 's/ MinSpareServers 5/ MinSpareServers 3/' /etc/apache2/apache2.conf
sed -i -e 's/ MaxSpareServers 10/ MaxSpareServers 5/' /etc/apache2/apache2.conf
sed -i -e 's/ MaxClients 150/ MaxClients 50/' /etc/apache2/apache2.conf
sed -i -e 's/ MaxRequestsPerChild 0/ MaxRequestsPerChild 10/' /etc/apache2/apache2.conf

#default

cat < 
<eot> /etc/apache2/sites-available/default</eot>
ServerAdmin webmaster@localhost
AddHandler application/x-httpd-php .php
DocumentRoot /var/www
Options FollowSymLinks
AllowOverride None
CustomLog /var/log/apache2/access.log combined env=!no_log
CustomLog /var/log/apache2/worm.log combined env=worm
ErrorLog /var/log/apache2/error.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
EOT

#deflate.conf

cat < 
<eot> /etc/apache2/mods-available/deflate.conf</eot>

# DEFLATEの有効化
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css
# 送信先ブラウザがNetscape 4.xの場合はtext/htmlのみ圧縮
BrowserMatch ^Mozilla/4 gzip-only-text/html
# 送信先ブラウザがNetscape 4.06-4.08の場合は圧縮しない
BrowserMatch ^Mozilla/4.0[678] no-gzip
# 送信先ブラウザがMSIEの場合は全て圧縮する
BrowserMatch bMSI[E] !no-gzip !gzip-only-text/html
# プロキシサーバーが圧縮未対応ブラウザへ圧縮ファイルを送信しないようにする
Header append Vary User-Agent env=!dont-vary
#画像ファイルは圧縮しない
SetEnvIfNoCase Request_URI .(?:gif|jpe?g|png|ico|pdf|mp3|ogg|wma|rm|wmv|mov|mpe?g)$ no-gzip dont-vary
SetEnvIfNoCase Request_URI .(?:z|taz|t?gz|t?bz2?|zip|lzh|sit|rar)$ no-gzip dont-vary
#コンテンツの圧縮転送
SetOutputFilter DEFLATE
EOT
#dir.conf
sed -i -e 's/index.html index.cgi index.pl index.php index.xhtml index.htm/index.html index.htm index.php index.cgi index.xhtml index.shtml index.pl/' /etc/apache2/mods-available/dir.conf
#httpd.conf
cat < 
<eot> /etc/apache2/httpd.conf</eot>
Order allow,deny
Deny from all
ServerName sample.com
ExpiresActive On
ExpiresByType image/gif "access plus 15 minutes"
ExpiresByType image/jpeg "access plus 15 minutes"
ExpiresByType image/png "access plus 15 minutes"
ExpiresByType application/x-shockwave-flash "access plus 15 minutes"
ExpiresByType text/html "access plus 5 minutes"
ExpiresByType text/css "access plus 15 minutes"

#Logs
LogFormat "%h %l %u %t "%r" %>s %b "%{Referer}i" "%{User-Agent}i"" combined
SetEnvIf Request_URI ".(ida|IDA|exe|printer|asp|dll)" worm no_log
SetEnvIf Request_URI "^/_mem_bin/" worm no_log
SetEnvIf Request_URI "^/_vti_bin/" worm no_log
SetEnvIf Request_URI "^/c/" worm no_log
SetEnvIf Request_URI "^/d/" worm no_log
SetEnvIf Request_URI "^/msadc/" worm no_log
SetEnvIf Request_URI "^/MSADC/" worm no_log
SetEnvIf Request_URI "^/scripts/" worm no_log
SetEnvIf Request_URI "^/default.ida" worm no_log
SetEnvIf Request_URI ".(gif|jpg|png|css|ico)$" no_log

EOT

#mime.conf
sed -i -e 's/#AddEncoding x-gzip .gz .tgz/AddEncoding x-gzip .gz .tgz/' /etc/apache2/mods-available/mime.conf
sed -i -e '/^AddLanguage ja .ja/d' /etc/apache2/mods-available/mime.conf
sed -i -e '1,/^AddLanguage/{/^AddLanguage/!b;i' -e 'AddLanguage ja .ja' -e '}' /etc/apache2/mods-available/mime.conf
sed -i '/#AddHandler cgi-script .cgi/iAddHandler x-suphp-cgi .cgi .pl' /etc/apache2/mods-available/mime.conf

#negotiation.conf
sed -i -e 's/en ca cs da de el eo es et fr he hr it ja/ja en ca cs da de el eo es et fr he hr it/' /etc/apache2/mods-available/negotiation.conf

#security
sed -i -e 's/ServerTokens OS/ServerTokens Prod/' /etc/apache2/conf.d/security
sed -i -e 's/#ServerSignature Off/ServerSignature Off/' /etc/apache2/conf.d/security
sed -i -e 's/ServerSignature On/#ServerSignature On/' /etc/apache2/conf.d/security

#vitrualhost.conf
cat < 
<eot> /etc/apache2/sites-available/virtualhost.conf</eot>

#Sample Virtualhost
ServerName www.sample.com
DocumentRoot /home/hogehoge/public_html/
CustomLog /home/hogehoge/log/access.log combined env=!no_log
CustomLog /home/hogehoge/log/worm.log combined env=worm
ErrorLog /home/hogehoge/log/error.log
Options ExecCGI FollowSymLinks MultiViews
LogLevel notice
KeepAlive Off
<directory "/home/hogehoge/">
AllowOverride All
Allow from All
Options +ExecCGI
EOT

a2ensite virtualhost.conf

#ログローテートの編集
sed -i -e 's#.log {#.log /home/*/log/*.log {#' /etc/logrotate.d/apache2
sed -i -e 's/ weekly/ daily/' /etc/logrotate.d/apache2
sed -i '/ missingok/i dateext' /etc/logrotate.d/apache2
sed -i -e 's/ rotate 52/ rotate 31/' /etc/logrotate.d/apache2

#PHPの設定
sed -i -e 's/output_buffering = 4096/output_buffering = Off/' /etc/php5/cgi/php.ini
sed -i -e 's/expose_php = On/expose_php = Off/' /etc/php5/cgi/php.ini
sed -i -e 's/memory_limit = 128M/memory_limit = 64M/' /etc/php5/cgi/php.ini
sed -i -e 's/log_errors_max_len = 1024/log_errors_max_len = 4096/' /etc/php5/cgi/php.ini
sed -i -e 's#;error_log = php_errors.log#error_log = /var/log/apache2/php_error.log#' /etc/php5/cgi/php.ini
sed -i -e 's/upload_max_filesize = 2M/upload_max_filesize = 10M/' /etc/php5/cgi/php.ini
sed -i -e 's#;session.save_path = "/tmp"#session.save_path = "/tmp"#' /etc/php5/cgi/php.ini
sed -i -e 's/session.hash_function = 0/session.hash_function = 1/' /etc/php5/cgi/php.ini
sed -i -e 's/;mbstring.language = Japanese/mbstring.language = Japanese/' /etc/php5/cgi/php.ini
sed -i -e 's#;date.timezone =#date.timezone = Asia/Tokyo#' /etc/php5/cgi/php.ini

cat < 
<eot>&gt; /etc/php5/cgi/php.ini</eot>

[htscanner]
extension="htscanner.so"
config_file=".htaccess"
; The fallback docroot when htscanner can't determine the current docroot default_docroot="/"
default_ttl=300
; Stop when an error occured in RINIT (no document root, cannot get path_translated,...)
stop_on_error = 0

EOT

#suPHPの設定
sed -i -e 's#docroot=/var/www:${HOME}/public_html#docroot=/#' /etc/suphp/suphp.conf
sed -i -e 's/allow_file_others_writeable=false/allow_file_others_writeable=true/' /etc/suphp/suphp.conf
sed -i -e 's/allow_directory_group_writeable=false/allow_directory_group_writeable=true/' /etc/suphp/suphp.conf
sed -i -e 's/allow_directory_others_writeable=false/allow_directory_others_writeable=true/' /etc/suphp/suphp.conf
sed -i -e 's/check_vhost_docroot=true/check_vhost_docroot=false/' /etc/suphp/suphp.conf
sed -i -e 's/umask=0077/umask=0022/' /etc/suphp/suphp.conf
sed -i -e 's/min_uid=100/min_uid=033/' /etc/suphp/suphp.conf
sed -i -e 's/min_gid=100/min_gid=033/' /etc/suphp/suphp.conf
sed -i '/suPHP_AddHandler/i suPHP_AddHandler x-suphp-cgi' /etc/apache2/mods-available/suphp.conf
sed -i '/ delaycompress/i rotate 10' /etc/logrotate.d/suphp-common

# MySQL詳細設定
mysql_secure_installation
sed -i '/[mysqld]/i skip-innodb' /etc/mysql/my.cnf

#phpMyAdmin
ln -s /usr/share/phpmyadmin /var/www/phpMyAdmin

######################################################################

# アンチウイルス

echo 'F-Prot Antivirusをインストールします。'

wget http://files.f-prot.com/files/unix-trial/fp-Linux-i686-ws.tar.gz -P /tmp

tar xzvf /tmp/fp-Linux-i686-ws.tar.gz -C /

cd /f-prot/

./install-f-prot.pl

#定期的なウイルス探査

crontab -l > /tmp/fprot.cron

cat < 
<eot>&gt; /tmp/fprot.cron</eot>

0 3 * * 3 fpscan /home --report -o /var/log/fprot_scan.log

EOT

crontab /tmp/fprot.cron

######################################################################

# 細々とした設定

#デフォルト

mkdir /etc/skel/public_html/

mkdir /etc/skel/log/

mkdir /etc/skel/.ssh/

chmod 700 /etc/skel/.ssh/

#シンボリックリンク

ln -s /usr/bin/speedy /usr/local/bin/speedy

# ちょっとしたセキュリティ向上

chmod 711 /etc/

chmod 711 /home/

chmod 711 /var/log/

chmod 700 /etc/apache2/

chmod 700 /etc/php5/cgi/php.ini

chmod 700 /etc/php5/apache2/php.ini

chmod 700 /etc/php5/cli/php.ini

######################################################################

#時間設定

echo '時間同期を行います。'

echo 'NTPdを利用する場合はy、ntpdateを利用する場合はnを入力して下さい。'

while [ 1 ]

do

echo -n "-->"

read time

case $time in

y|Y)

apt-get install -y ntp

sed -i '/server ntp.ubuntu.com/iserver ntp.jst.mfeed.ad.jp' /etc/ntp.conf

sed -i '/server ntp.ubuntu.com/iserver ntp.nict.jp' /etc/ntp.conf

sed -i '/server ntp.ubuntu.com/iserver ntp.ring.gr.jp' /etc/ntp.conf

sed -i -e '/^server ntp.ubuntu.com/d' /etc/ntp.conf

echo 'Xenを用いている仮想OSの場合はy、そうでないならnを入力して下さい。'

while [ 1 ]

do

echo -n "-->"

read time

case $time in

y|Y)

cat < 
<eot>&gt; /etc/sysctl.conf</eot>

# For ntpd on Xen

DomU.xen.independent_wallclock = 1

EOT

break

;;

n|N)

break

;;

*) echo "Error! YかNを入力して下さい。"

esac

done

break

;;

n|N)

crontab -l > /tmp/time.cron

cat < 
<eot>&gt; /tmp/time.cron</eot>

39 5,18 * * * /usr/sbin/ntpdate ntp.nict.jp

EOT

crontab /tmp/time.cron

break

;;

*) echo "Error! YかNを入力して下さい。"

esac

done

#念のためntpdateによる時間あわせ

ntpdate -u ntp.jst.mfeed.ad.jp

######################################################################

# 設定を反映する為リブートを行う

clear

echo '設定が終了しました。'

echo "SSHサーバーのポート番号は${sshport}となっています。"

echo 'ENTERキーを押すと再起動します。'

read dummy

echo '再起動します。'

reboot

このシェルスクリプトはUbuntu上にApache、MySQL、PHPを導入し楽してLAMP環境を構築するために作ったもの。

動作環境はSSHのみがインストールされたUbuntu10.10。テストはSaaSesのOsukini VPS LTプランで。

他の環境でもUbuntuなら動くでしょう。多分。

シェルスクリプト実行内容の流れ

1.パッケージ管理システムの更新 ↓ 2.英語版Ubuntuの場合ロケール変更→日本語へ(選択可) ↓ 3.ユーザー作成、SSHサーバーセキュリティ対策 ↓ 4.アプリケーションインストール ↓ 5.iptables設定 ↓ 6.Apache、PHPの設定変更 ↓ 7.ウイルス対策 ↓ 8.ユーザー作成時のひな形作成 ↓ 9.なんちゃってセキュリティ設定 ↓ 10.時間設定 ↓ 11.リブート

おそらく突っ込みどころ満載なので何かあったらコメント欄に。

追記(11/04/29)

やっぱり突っ込みどころ満載だったorz

というわけでいろいろ直しました。