セキュリティー設定

FreeBSDの基本的なセキュリティーを設定する

前回までの設定で、WordPress サーバーの構築が出来ましたが、あくまでも自分や目の届く範囲のユーザーがWordPressをアクセスするための設定でした。

ここから、WordPressを動かしている FreeBSD OSをパブリックネットワークに公開しても大丈夫なようにいくつかの設定を行いたいと思います。
そのためには、以下の通り、最低限のセキュリティー強化を図ります。

  1. ロギングを強化する
    1. syslog.conf
    2. ログのローテーション
  2. アクセスコントロールを設定
  3. ファイヤーウォールを設置する

考え方は、1. サーバーへのアクセスが発生した場合、そのアクセスを十分に記録するということです。FreeBSD インストール直後から有効になっていますが、私から見ると若干物足りない設定になっていますので、ロギングを強化します。
次に、2. サーバーへリモートアクセス可能な利用者とポートの関係を限定します。サーバーへのアクセスを許可するネットワークと、許可しないネットワークを設定します。
最後に、3. ファイヤーウォールを使って不要なサービスポートを塞ぎます。使っていない、使う予定がないポートは塞ぎ、また、到着したパケットをがどんな目的でサーバーにアクセスしてきているのか目印となるよう記録するようにします。

以上の設定を行えば、サーバーの無防備サービス状態を発見して侵入を試みる不特定IPアドレスへの攻撃からサーバーを防御できます。

サービスポートからサーバーへの侵入を試みる場合、いきなり侵入されることは希です。まず、サーバーの開かれているポートをポートスキャンにより調査したり、Webページをアクセスして動作しているOSとバージョンを確認したり、ハッキングできる穴を探します。可能な限りの記録を残す事により、ハッキングの予兆を察知します。万が一侵入されたとしても、あとから記録をたどり、どこからどんな風に侵入が発生したのかを推測するのに役立ちます。

ロギングを強化

FreeBSD の場合、 /etc/syslog.conf を編集することによってロギング条件を設定できます。

# cat syslog.conf
# $FreeBSD: release/9.2.0/etc/syslog.conf 238473 2012-07-15 10:55:43Z brueffer $
#
#       Spaces ARE valid field separators in this file. However,
#       other *nix-like systems still insist on using tabs as field
#       separators. If you are sharing this file between systems, you
#       may want to use only tabs as field separators here.
#       Consult the syslog.conf(5) manpage.
*.err;kern.warning;auth.notice;mail.crit                /dev/console
*.notice;authpriv.none;kern.debug;lpr.info;mail.crit;news.err   /var/log/messages
security.*                                      /var/log/security
auth.info;authpriv.info                         /var/log/auth.log
mail.info                                       /var/log/maillog
lpr.info                                        /var/log/lpd-errs
ftp.info                                        /var/log/xferlog
cron.*                                          /var/log/cron
*.=debug                                        /var/log/debug.log
*.emerg                                         *
# uncomment this to log all writes to /dev/console to /var/log/console.log
# touch /var/log/console.log and chmod it to mode 600 before it will work
#console.info                                   /var/log/console.log
# uncomment this to enable logging of all log messages to /var/log/all.log
# touch /var/log/all.log and chmod it to mode 600 before it will work
#*.*                                            /var/log/all.log
# uncomment this to enable logging to a remote loghost named loghost
#*.*                                            @loghost
# uncomment these if you're running inn
# news.crit                                     /var/log/news/news.crit
# news.err                                      /var/log/news/news.err
# news.notice                                   /var/log/news/news.notice
!ppp
*.*                                             /var/log/ppp.log
!*

これを次のように編集して、あとから追加する機会が多いサーバーアプリケーションの記録を出来るようにします。

*.err;kern.warning;auth.notice;mail.crit                /dev/console
*.notice;authpriv.none;kern.debug;lpr.info;mail.crit;news.err   /var/log/messages
security.*                                      /var/log/security
auth.info;authpriv.info                         /var/log/auth.log
mail.info                                       /var/log/maillog
lpr.info                                        /var/log/lpd-errs
ftp.info                                        /var/log/xferlog
cron.*                                          /var/log/cron
user.*                                          /var/log/userlog
*.=debug                                        /var/log/debug.log
*.emerg                                         *
# uncomment this to log all writes to /dev/console to /var/log/console.log
console.info                                    /var/log/console.log
local7.notice                                   /var/log/local7.log

そして、新たに追加したログファイルが記録できるよう、空のファイルを作っておきます。

# cd /var/log
# touch console.log local7.log

syslog.conf を編集しただけでは、大した量のログを残せませんので約1年分の記録を残せるように、ログをローテーションさせるための設定を /etc/newsyslog.conf を編集することによって行います。

下記がデフォルトの newsyslog.conf です。

# cat /etc/newsyslog.conf
省略
# logfilename          [owner:group]    mode count size when  flags [/pid_file] [sig_num]
/var/log/all.log                        600  7     *    @T00  J
/var/log/amd.log                        644  7     100  *     J
/var/log/auth.log                       600  7     100  @0101T JC
/var/log/console.log                    600  5     100  *     J
/var/log/cron                           600  3     100  *     JC
/var/log/daily.log                      640  7     *    @T00  JN
/var/log/debug.log                      600  7     100  *     JC
/var/log/kerberos.log                   600  7     100  *     J
/var/log/lpd-errs                       644  7     100  *     JC
/var/log/maillog                        640  7     *    @T00  JC
/var/log/messages                       644  5     100  @0101T JC
/var/log/monthly.log                    640  12    *    $M1D0 JN
/var/log/pflog                          600  3     100  *     JB    /var/run/pflogd.pid
/var/log/ppp.log        root:network    640  3     100  *     JC
/var/log/security                       600  10    100  *     JC
/var/log/sendmail.st                    640  10    *    168   BN
/var/log/utx.log                        644  3     *    @01T05 B
/var/log/weekly.log                     640  5     *    $W6D0 JN
/var/log/xferlog                        600  7     100  *     JC

Webサーバーとして公開するサーバーの場合、赤文字のログファイルは巨大化する傾向にあります。
デフォルトでは100kB毎にログをローテーションし、5~7世代を保持する設定になっていますが、これでは1週間分程度しか記録できない場合がありますので、必要性に応じて半年から1年程度の記録を残せるように編集することにします。

以下は、私が使用しているログローテションの一例です。保存ログサイズを大きくしたり、ローテートするタイミングを月が更新するタイミングにしたりしています。下から2行分はHTTPサーバーのApacheログを月の初めにローテートするための記述です。毎月1日の0時にログを更新する設定にしています。

# logfilename          [owner:group]    mode count size when  flags [/pid_file] [sig_num]
/var/log/all.log                        600  7     *    @T00  J
/var/log/amd.log                        644  7     100  *     J
/var/log/auth.log                       600  9     500  *     JC
/var/log/console.log                    600  5     500  *     J
/var/log/cron                           600  3     100  *     JC
/var/log/daily.log                      640  7     *    @T00  JN
/var/log/debug.log                      600  7     100  *     JC
/var/log/kerberos.log                   600  7     100  *     J
/var/log/lpd-errs                       644  7     100  *     JC
/var/log/maillog                        640  12    *    $M1D00  JC
/var/log/messages                       644  12     999 *       JC
/var/log/monthly.log                    640  12    *    $M1D0 JN
/var/log/pflog                          600  3     100  *     JB    /var/run/pflogd.pid
/var/log/ppp.log        root:network    640  3     500  *     JC
/var/log/security                       600  12    999  *     JC
/var/log/sendmail.st                    640  10    *    168   BN
/var/log/utx.log                        644  3     *    @01T05 B
/var/log/weekly.log                     640  5     *    $W6D0 JN
/var/log/xferlog                        600  10    999  *     JC
/home/wordpress/log/httpd-access.log www:www   644  12    999  $M1D0  Z   /var/run/httpd.pid
/home/wordpress/log/httpd-error.log  www:www   644  12    999  $M1D0  Z   /var/run/httpd.pid

auth.log はログインを試みた記録、 xferlog は ftpファイル転送を試みた記録です。security にはファイヤーウォールのログが記録されます。
運営開始後は、時々 /var/log のファイルを観察して、ログファイルがあまりに大きくなってディスクを圧迫していないかチェックする必要があります。あまりにも大きくなるファイルがあれば、原因を突き止めて newsyslog.conf を編集する必要があります。

アクセスコントロール

FreeBSD にはリモート接続パケットのアクセス元のIPアドレスをチェックして、その接続を受け付けるか拒否するかを決める機能があります。
/etc/hosts.allow を適切に編集することにより、接続を許可しないホストからのアクセスをリモートアクセス用プログラムに渡す前の段階で拒否することができ、仮にサービスにセキュリティーホールがあったとしても、制御がプログラムに渡る前の段階で通信を切断できます。

/etc/hosts.allow の編集

さて、今回のサーバーでは、ssh, telnet, ftp を使って外部からの接続を受け付けるようにしていますので、/etc/hosts.allow の sshd, telnetd, ftpd のセクションを編集することになります。例えば以下のように記述します。

#ALL : ALL : allow

まず、全許可になっている上記の行をコメントアウトします。

sshd : 192.168.0.0/255.255.0.0 : allow #1
sshd : 116.58.172.107 192.168.1.10: allow  #2
sshd : .ppp.prin.ne.jp : allow  #3

一行目は、プライベートネットワーク 192.168.0.* のipアドレスを持つホストからのssh 接続をネットワーク単位で許可しています。
二行目は、ホスト毎に許可する場合の例です。ホスト名かIPアドレスで定義します。複数ホストを記述する場合はスペースで区切ります。
三行目は、ドメイン単位で許可する場合の例です。上の例は出先からリモートメンテナンスを行う必要がある場合の例で、その時々でどんなIPアドレスが割り振られるかわからないときは、このようにドメイン単位を使うしかありません。対象となるIPアドレスが多い場合はちょっと気持ち悪いですが仕方ありません。国内プロバイダーの場合は、万が一被害にあってしまった時、刑事事件として処理して警察権限でプロバイダーの協力を得るしかないでしょう。その覚悟がないのならVPNやダイヤルアップをセットアップするしかないでしょう。

同様に telnet と ftp ポートも設定します。ftpに関しては、デフォルトでは全て許可になっていますので、コメントアウトして塞ぎます。

telnetd : 192.168.0.0/255.255.0.0 : allow
telnetd : 116.58.172.107 192.168.1.10: allow
telnetd : .ppp.prin.ne.jp : allow
#
ftpd : 192.168.0.0/255.255.0.0 : allow
ftpd : 116.58.172.107 192.168.1.10: allow
ftpd : .ppp.prin.ne.jp : allow
#ftpd : ALL : allow

定義しなかったアクセスに関しては、hosts.allow ファイル最後の記述により、全部拒否されることになります。

# The rest of the daemons are protected.
ALL : ALL \
        : severity auth.info \
        : twist /bin/echo "You are not welcome to use %d from %h."

次に、サービスポートに対して大量の接続を行いサービス妨害を行う攻撃を防ぐために、1分間に一定数以上のアクセスが発生した場合、接続を停止するように inetd 起動時のオプションを /etc/rc.conf に記述します。
私のサーバーに対しても海外アドレスから1分間に100以上のログインパケットを送りつけられることがありますが、次の設定で1分間に同じIPアドレスから6回以上アクセスが発生すると、そのIPアドレスを拒絶し、サーバー全体でも毎分12本以上の接続を受け付けないようにします。

inetd_flags="-wWl -C 6 -R 12"

もし、運用上この数では少ないということであれば、数字を1,2個大きめにして inetd を再起動します。

以上がアクセスコントロールによるセキュリティー強化です。

ファイヤーウォール

FreeBSD のファイヤーウォール機能はパケットフィルタリングだけではなく、ポートフォワーディング、帯域制御など非常に高機能で複雑なコントロールが可能ですが、全てコマンドで制御するため高度な設定を行うのは結構大変です。またデフォルトではファイヤウォールがオフの状態になっています。
しかし、ワークステーションモードを選択すれば設定が非常にシンプルになります。以下がファイヤウォールをワークステーションモードにするための /etc/rc.conf の記述例です。

# /etc/rc.conf に追加する
firewall_enable="YES"
firewall_type="workstation"
firewall_logging="YES"
firewall_myservices="20,21,22,23,25,53,80,110,113,123,143,443,993,995"
firewall_allowservices="any"
firewall_trusted="192.168.1.10"
firewall_logdeny="YES"
firewall_nologports="135-139,445,1433,1434,17500"

firewall_myservices にサービスポートをカンマで区切って記述します。(この例では公開しているサービスポート以外に、将来開くことになりそうなポート番号をあらかじめオープンしています。 25,53,110,113,123,143,443,993,995 は現時点では削除しても構いません)
firewall_trusted に無条件にアクセスを許可するホストIPアドレスを記述します。
firewall_nologports に、許可せず、記録も取らないポート番号を記述します。
その他の設定は、上記のままにします。

/etc/rc.firewall を編集

log="log logamount 0" # The default of 100 is too low.

ファイヤーウォールのロギングカウンターは、デフォルトでは500になっており、ログが膨らむと自動停止してしまいます。この記述を編集し、上限を解除します。

このあとで、FreeBSDを再起動すれば、ファイヤウォールが有効になります。

 

関連項目