オープンソースこねこね

Webプログラミングなどについてあれこれ。

CentOS6でサーバを構築する際におこなっている基本設定

2016年にもなって今さらという感じですが、CentOS6でサーバを構築する際の自分がやっている初期の基本設定、確認事項をまとめておこうと思います。

CentOS6のサポート期限が2020年までで、自分が今後メインに使っていく環境もCentOS7などに移行しようと思っています。遅まきながらローカルのVirtualBoxにCentOS7をいれていろいろ試していますが、CentOSは6と7で大幅な変更がなされ、今まで普通に出来ていたことを一から学び直す必要があったりしてツライ日々ではあります。

このように徐々にCentOS6から離れていくことになるので、そのあたりの記憶が急速に失われていく前に、今まで書いたメモなどを元に情報を整理しておこうかと思い立ったのがきっかけです。

※ここではサーバのロールにかかわらず行う基本的な作業をまとめています。通常この環境の上にWebサーバ(httpd, nginxなど)やDB(MySQLなど)をインストールすることになります。

※本文中のコマンドは基本的にrootユーザで行っているものとします。一般ユーザを使い必要に応じて都度root権限を使うようにしている方はsudoをつけるなど、コマンドを読み替えてください。

ランレベルの確認

OSのランレベルを確認します。ここではサーバ用途なので3が設定されていればいいでしょう

# cat /etc/inittab 
# inittab is only used by upstart for the default runlevel.
#
# ADDING OTHER CONFIGURATION HERE WILL HAVE NO EFFECT ON YOUR SYSTEM.
#
# System initialization is started by /etc/init/rcS.conf
#
# Individual runlevels are started by /etc/init/rc.conf
#
# Ctrl-Alt-Delete is handled by /etc/init/control-alt-delete.conf
#
# Terminal gettys are handled by /etc/init/tty.conf and /etc/init/serial.conf,
# with configuration in /etc/sysconfig/init.
#
# For information on how to write upstart event handlers, or how
# upstart works, see init(5), init(8), and initctl(8).
#
# Default runlevel. The runlevels used are:
#   0 - halt (Do NOT set initdefault to this)
#   1 - Single user mode
#   2 - Multiuser, without NFS (The same as 3, if you do not have networking)
#   3 - Full multiuser mode
#   4 - unused
#   5 - X11
#   6 - reboot (Do NOT set initdefault to this)
# 
id:3:initdefault:

id:3:initdefault:となっていることを確認します。

サービス起動設定の確認

chkconfigで起動設定になっているサービス(デーモン)を確認します。

# chkconfig --list
auditd          0:off   1:off   2:on    3:on    4:on    5:on    6:off
blk-availability    0:off   1:on    2:on    3:on    4:on    5:on    6:off
cgconfig        0:off   1:off   2:off   3:off   4:off   5:off   6:off
cgred           0:off   1:off   2:off   3:off   4:off   5:off   6:off
crond           0:off   1:off   2:on    3:on    4:on    5:on    6:off
...

不要と思われるサービスはサーバリソースの無駄使いになるので、以下のコマンドで停止設定にしておきます。

# chkconfig <サービス名> off

これはOS起動時のサービスの自動起動設定なので、合わせて

# /etc/init.d/<サービス名> stop

として現在の実行状態も停止します。

さて、サーバ 用途でランレベルは3になっているので3:onとなっているサービスを上から順に調べて、offにしていくのですが、自分の知識範囲でよくわからないものもあったします。その場合はとりあえずonにしておいています。もちろんすべて把握できるのが良いのですが。。。

逆にOSの起動時に実行させたいサービスは

# chkconfig <サービス名> on

とします。

ディクスサイズの確認

# df -h

-hをつけるとサイズにM(メガ)とかG(ギガ)とかがついてわかりやすく表示されます。 サーバスペックにあったディクスサイズになっていることや、パーティションを確認します。

ロケールの設定

システムが使うロケール/etc/sysconfig/i18nで設定します

日本語なら

LANG="ja_JP.UTF-8"

英語なら

LANG="en_US.UTF-8"

としておきます。また

# yum install man-pages-ja

をインストールして、ロケールを日本語にしておくとmanページが日本語表示されるようになります。

タイムゾーンとNTPの設定

タイムゾーンを日本にする

# cp -f /usr/share/zoneinfo/Japan /etc/localtime

/etc/sysconfig/clockを以下のように編集する

ZONE="Asia/Tokyo"

サーバの時刻をあわせるntpdについての設定/etc/ntp.confを確認します。

server 0.centos.pool.ntp.org iburst
server 1.centos.pool.ntp.org iburst
server 2.centos.pool.ntp.org iburst
server 3.centos.pool.ntp.org iburst

のようにntpサーバが指定されていること。

dateコマンドで表示される時刻が正しいことを確認する。

# date

ネットワーク関連の設定

幾つかあるので、順番に見ていきます。

ネットワークの設定

/etc/sysconfig/network

NETWORKINGyesになっているのとHOSTNAMEを確認する

NETWORKING=yes
HOSTNAME=your-hostname

ネットワーク・インターフェースの確認

ネットワーク・インターフェースは/etc/sysconfig/network-scripts配下にインターフェースごとにifcfg-xxxというファイルに設定されている。

例えばifcfg-eth0イーサネットの0番目のインターフェース

DEVICE="eth0"
BOOTPROTO="none"
IPADDR=192.168.56.14
NETMASK=255.255.255.0
ONBOOT="yes"
TYPE="Ethernet"
UUID="c67412a6-19cf-427a-9f4d-96ca89217519"

静的はIPを割り当てている場合はIPADDRNETMASKなどの設定を確認、編集する。またネットワークの設定を変更したら

# /etc/init.d/network restart

で反映させる。

IPアドレスの確認

# ifconfig

IPアドレスの設定が、設定通りか確認します。

ネットワークの疎通確認

# ping yahoo.co.jp

pingが外に向けて通るかを確認します。0% packet lossとなればOK。

# traceroute yahoo.co.jp

外につなぎに行く際にどのようなIPを経由するかを確認。ネットワーク管理者ではないので、ざっと結果を眺めるだけです。

yumリポジトリ

yumCentOSの標準パッケージ管理システムです。システムワイドにパッケージをインストールする場合、基本的にyumを使う方針にしています。ソースからのインストールに代表されるその他のインストール方法はファイルシステムのどこに何が配置されるか把握、管理するのが難しく、これはアンインストールなどの作業を困難にします。

ただCentOSでは標準のyumリポジトリでインストールできるパッケージは数が少なかったり、バージョンが古かったりする(特にPHPのバージョンが古いのがLAMP環境では致命的です)ので、以下のサードパーティリポジトリを追加して使っています。俗に「野良リポジトリ」と呼ばれるものです。

  • epel
  • remi

追加は以下のコマンドを実行します。

# rpm -ivh http://ftp.riken.jp/Linux/fedora/epel/6/x86_64/epel-release-6-8.noarch.rpm
# rpm -ivh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm

追加したサードパーティリポジトリは標準では想定されていない環境をインストールするので、予期せぬ不具合を発生させる可能性があると思われます。デフォルトでは使わないように設定し、インストールやアップデート時、必要に応じて有効化して使うのが広く知られている手法のようです(※といいつつ、私はデフォルトで有効化してしまっています。後述します)。その場合は以下のように設定ファイルを修正、確認しましょう。

/etc/yum.repos.d/epel.repo

[epel]
# 中略...
enabled=0

/etc/yum.repos.d/epel.repo

[remi]
# 中略...
enabled=0

これでデフォルトは無効化されます。利用する場合は以下のようにします。

# yum install php --enablerepo=remi,epel

コマンドメモ

インストール(phpをインストールの例)

# yum install php

アップデート

# yum update php

アンインストール

# yum remove php

インストール済みパッケージの情報

# rpm -qi php

インストール済みパッケージのファイル一覧

# rpm -ql php

補足(個人的なデフォルトの設定)

前述したように、サードパーティリポジトリ利用のデフォルト設定を無効にはしていません。というのも実際にパッケージをインストールする作業はchefなどのプロビジョニングツールを使っているので、デフォルトで有効になっていないと、これらのツールから正しくインストールできないという理由があるからです。

bash-completion

素のbashのままだとzshになれた補完脳にはツライので、bash-completionを入れます。

# yum install bash-completion

インストールするだけで、ある程度補完が効くようになります。カスタマイズは特にしていません。

ファイアウォール (iptables)

iptablesファイアウォールです。iptablesコマンドから設定できるのですが、よく覚えてないし全体の設定を眺めて設定できるので、設定ファイルを直接編集しています。(設定ファイルの先頭にManual customization of this file is not recommended.って書かれているので本来は非推奨なのですが。。。)

iptablesの設定の詳細は覚えていないのですが(よくググります)、基本的に以下のようにINPUTチェインに外部接続を許可する設定を書いていきます。 最後にそれ以外はすべて拒否するように設定しておきます。

/etc/sysconfig/iptables

# Firewall configuration written by system-config-firewall
# Manual customization of this file is not recommended.

*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT

# httpd
-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT

# ssh
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT

# ...中略

# 最後に拒否
-A INPUT -j REJECT --reject-with icmp-host-prohibited

これで必要のない外部アクセスを遮断でき、不正アクセス対策になります。最後にrestartして設定を反映します。

# /etc/init.d/iptables restart

なお、iptablesの設定をミスってsshでリモートサーバに繋げなくなって詰む、という状況を避けたいので今のターミナルのセッションが生きているうちに、restartしたらまず別のターミナルを立ち上げてssh接続を試します。

sshd

ssh接続はセキュリティを強くするため、ポート番号を変えて、鍵認証オンリーにします。以下、編集および確認箇所のみを記載します。

/etc/ssh/sshd_config

# 22以外に変えます
Port 2222
# rootログインは禁止
PermitRootLogin no
# パスワード認証は禁止
PasswordAuthentication no

再起動して設定を反映します。

/etc/init.d/sshd restart

logrotate

ログのローテート設定。ログが無尽蔵に大きくなってディクスサイズを圧迫しないように設定、確認します。 初期設定時の他にhttpdなどのデーモンやログを出力するアプリケーションを追加した時にも目を通します。

/etc/logrotate.d/以下にログの対象ごとに設定ファイルがあるのでそれを確認します。例えばnginxは以下のようになっていたりします。

/etc/logrotate.d/nginx

/var/log/nginx/*.log {
        daily
        missingok
        rotate 52
        compress
        delaycompress
        notifempty
        create 640 nginx adm
        sharedscripts
        postrotate
                [ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
        endscript
}

実際の設定はログのサイズや保存期間の要件などによって異なるので、それを考慮し設定します。

sysctl

カーネルパラメータの設定です。/etc/sysctl.confを編集します。以下のパラメータを追加、変更。

net.nf_conntrack_max = 1000000
net.netfilter.nf_conntrack_max = 1000000
net.core.somaxconn = 1024
vm.overcommit_memory = 1

net.nf_conntrack_maxnet.netfilter.nf_conntrack_maxネットワークアクセスが高負荷になったときパケットのトラッキングがデフォルトの上限値を上回ることがあるのでそれに対応するため、実際の数値はメモリの量と相談です。

参考:

https://www.e-agency.co.jp/column/20121225.html

net.core.somaxconnはソケットをListenするキューの最大数。memcacnedとかredisはこれがカーネルのデフォルト値(128)より大きく設定されているので、増やす

参考:

net.core.somaxconnについて調べてみた - tetsuyai’s blog

vm.overcommit_memoryはメモリが足りなくなったときのmallocの動作についての制御のよう。デフォルトだと高負荷時にredis起動時にバックグランドセーブが失敗する可能性がある、という警告がでる。

参考:

passingloop • Linux のオーバーコミットについて調べてみた

設定値を反映するために以下のコマンドを打つ。

sysctl -p

確認。

sysctl -a

環境変数

環境変数はサーバにデプロイするアプリケーションの振る舞いを制御するためなどに使います。 サーバのロールやdevelopmentproductionのような環境情報を設定しておきます。 アプリケーションは実行時にこの環境変数を読むことでデバッグモードに変えたり、本番用の設定に切り替えたりできるように実装します。

ただ環境変数はsudo時、sshでログイン時、sshで直接コマンド実行時、実行中のhttpdプロセス内、などプロセスの実行のコンテキストによって変わるので、 常に一貫した設定を読めるようにしておくのがなかなか難しく、悩みどころになっています。現状は同じ環境変数を反映させる設定を複数の箇所に行っています。

/etc/envrionment

SERVER_ENVIRONMENT=production
SERVER_ROLE=web

/etc/profile.d/environment.sh

export SERVER_ENVIRONMENT=production
export SERVER_ROLE=web

以上2つが基本。あとはhttpdアプリケーションサーバに使うときは/etc/httpd/conf/httpd.confにも設定します

SetEnv SERVER_ENVIRONMENT "production"
SetEnv SERVER_ROLE "web"

設定の記述が重複してしまうのでコピペにならないように、chefやitamaeのようなプロビジョニングツールで変数にしてカバーしています。。。