読者です 読者をやめる 読者になる 読者になる

Pandora Pocket

MS系の備忘録と日記。三日坊主。

さくらのVPSに移動したのでLAMP鯖構築シェルスクリプトを書き換えた

さくらのVPSがリニューアルして2GBプランが非常にお求めやすくなったのでこの機会に乗り換えました。

やっぱりシリアルコンソールがあると何かあったとき便利ですね。

標準はCentOSなのですがカスタムインストールでUbuntuに。SaaSesの頃は/bootが100MBしか切られて無くいろいろ大変でしたがさくらのVPSだと自分でパーティションを切れるので良い感じです。

VPSに環境構築するにあたって以前作ったシェルスクリプトを使ったところ一部うまく動かなかったので手直し。さくらのVPSでも動くようにしたのでまた公開してみます。

[shell]

#!/bin/sh

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

#Ubuntu 自動サーバー構築シェルスクリプト

#

#Version 1.0.5

#作者 Ovis http://pandora.thty.net/

##修正点

#1.05 phpMyAdmin復活、複数ユーザー登録追加

#1.04 phpmyadmin削除

#1.03 Webminのインストールを選択制に変更

#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

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

# ひな形

mkdir /etc/skel/public_html/

mkdir /etc/skel/log/

mkdir /etc/skel/.ssh/

chmod 700 /etc/skel/.ssh/

# ユーザー作成、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 deny group=nosu/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

cat <<EOT > /etc/iptables.up.rules

*filter

:INPUT ACCEPT [0:0]

:FORWARD ACCEPT [0:0]

:OUTPUT ACCEPT [0:0]

#外部からのSSHへの接続を許可

-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT

#ping許可

-A INPUT -p icmp --icmp-type any -j ACCEPT

# ループバックアドレスからのアクセスをすべて許可

-A INPUT -i lo -j ACCEPT

# 内部から行ったアクセスに対する外部からの応答アクセスを許可

-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

COMMIT

EOT

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 build-essential vim

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 php5-curl

apt-get install -y libapache2-mod-suphp

pecl install htscanner channel://pecl.php.net/htscanner-1.0.1

apt-get install -y php5-mysql php5-sqlite php-mdb2-driver-sqlite

apt-get install -y phpmyadmin

apt-get install -y libapache2-mod-speedycgi

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.580_all.deb -P /tmp

dpkg -i /tmp/webmin_1.580_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 php5

#ファイルの編集

#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

<VirtualHost *:80>

ServerAdmin webmaster@localhost

DocumentRoot /var/www

<Directory />

Options FollowSymLinks

AllowOverride None

</Directory>

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

</VirtualHost>

EOT

#deflate.conf

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

<IfModule mod_deflate.c>

# 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

</IfModule>

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

<Directory ~ ".svn">

Order allow,deny

Deny from all

</Directory>

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

#Sample Virtualhost

<virtualHost *:80>

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

</directory>

</virtualHost>

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 >> /etc/php5/cgi/php.ini

[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

chown -R www-data:www-data /usr/share/phpmyadmin

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

# アンチウイルス

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

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

tar xzvf /tmp/fp-Linux.x86.32-ws.tar.gz -C /

cd /f-prot/

./install-f-prot.pl

#定期的なウイルス探査

crontab -l > /tmp/fprot.cron

cat <<EOT >> /tmp/fprot.cron

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

EOT

crontab /tmp/fprot.cron

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

#シンボリックリンク

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 'ユーザー登録を行いますか?(Y/N)'

while [ 1 ]

do

echo -n "-->"

read time

case $time in

y|Y)

cat <<EOT > /tmp/userlist

ユーザー名を入力

EOT

cat <<EOT > /tmp/password

パスワードを入力

EOT

UserListFile=/tmp/userlist

password=/tmp/password

while read uname

do

while read pw

do

useradd -d /home/$uname -g users -s /bin/bash -m $uname

echo $uname:$pw | chpasswd

done < $password

done < $UserListFile

break

;;

n|N)

break

;;

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

esac

done

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

#時間設定

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

n|N)

crontab -l > /tmp/time.cron

cat <<EOT >> /tmp/time.cron

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

[/shell]

シェルスクリプトの内容はコメントに書いているとおりです。

一応説明すると、ロケールを日本に変更した上でrootに昇格できるアカウントを作成、SSH認証のセキュリティ面の対策をしてApache等必要なアプリケーションをインストール・設定、ユーザー一括登録を一気に行います。

ユーザー一括登録を行いたい場合は該当の場所を編集して下さい。複数ユーザーを登録するときは改行して下さい。

また、サーバーのメモリーに余裕がない場合317行目のコメントアウトを解除してskip-innodbさせるとMySQLのメモリー使用量が減ります。デメリットもありますが。

シェルスクリプトにしてはいますが、いくつかの行程でパスワードを入力したり選択する必要があるため一度実行したら何もしなくともLAMP環境ができるという訳ではないことに注意。

あまり他では見かけないのですが(もっと良い方法があるのかな)、suPHPを利用してPHPPerl等のプログラムをユーザー権限で動かすようにしています。これで一応悪さはできないはず。

本格的にLinuxを勉強したわけではないので穴がありそうですが、そこはご指摘いただければ。

オレオレ仕様なのでApacheの設定などは利用用途に合わせていじって下さい。もっと良い方法があるよ!という方はコメントいただけると嬉しいです。

あとこのスクリプトではSSHの鍵認証までは行っていないため実行が終わったら鍵認証をかけておくことをおすすめします。