さくらのVPSがリニューアルして2GBプランが非常にお求めやすくなったのでこの機会に乗り換えました。
やっぱりシリアルコンソールがあると何かあったとき便利ですね。
標準はCentOSなのですがカスタムインストールでUbuntuに。SaaSesの頃は/bootが100MBしか切られて無くいろいろ大変でしたがさくらのVPSだと自分でパーティションを切れるので良い感じです。
VPSに環境構築するにあたって以前作ったシェルスクリプトを使ったところ一部うまく動かなかったので手直し。さくらのVPSでも動くようにしたのでまた公開してみます。
#!/bin/sh
######################################################################
#Ubuntu 自動サーバー構築シェルスクリプト
#
#Version 1.0.5
#作者 Ovis https://blog.hitsujin.jp/
##修正点
#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
シェルスクリプトの内容はコメントに書いているとおりです。
一応説明すると、ロケールを日本に変更した上でrootに昇格できるアカウントを作成、SSH認証のセキュリティ面の対策をしてApache等必要なアプリケーションをインストール・設定、ユーザー一括登録を一気に行います。
ユーザー一括登録を行いたい場合は該当の場所を編集して下さい。複数ユーザーを登録するときは改行して下さい。
また、サーバーのメモリーに余裕がない場合317行目のコメントアウトを解除してskip-innodbさせるとMySQLのメモリー使用量が減ります。デメリットもありますが。
シェルスクリプトにしてはいますが、いくつかの行程でパスワードを入力したり選択する必要があるため一度実行したら何もしなくともLAMP環境ができるという訳ではないことに注意。
あまり他では見かけないのですが(もっと良い方法があるのかな)、suPHPを利用してPHPやPerl等のプログラムをユーザー権限で動かすようにしています。これで一応悪さはできないはず。
本格的にLinuxを勉強したわけではないので穴がありそうですが、そこはご指摘いただければ。
オレオレ仕様なのでApacheの設定などは利用用途に合わせていじって下さい。もっと良い方法があるよ!という方はコメントいただけると嬉しいです。
あとこのスクリプトではSSHの鍵認証までは行っていないため実行が終わったら鍵認証をかけておくことをおすすめします。