FreeBSD 12.1で ファイアウォール ( ipfw )の設定

カテゴリー
FreeBSD セキュリティ

VPSで借りたサーバに FreeBSD 12.1 をセットアップする一環で、ファイアウォールの設定を解説していきます。

FreeBSD には Linux での「 iptables 」に相当するファイアウォール「 ipfw 」が組み込まれています。

引用:Wikipedia – iptables
https://ja.wikipedia.org/wiki/Iptables

iptablesは、Linuxに実装されたパケットフィルタリングおよびネットワークアドレス変換 (NAT) 機能であるNetfilter(複数のNetfilterモジュールとして実装されている)の設定を操作するコマンドのこと。Netfilterは、いわゆるファイアウォールやルータとしての役割を果たす。IPv4 用の実装が iptables で、IPv6 用の実装が ip6tables である。

だいぶ前は入っていない場合があり、その際はカーネルごとビルドしなおして追加が必要だったりしましたが、
最近はVPSなどで導入すると最初から入っているようです。

公式の英語ドキュメントなどは次の通りです。

システム設定

手始めにシステムに対して、ipfwを使用するための設定を etc/rc.conf に追記しましょう。
これらを追加した時点で、サーバーを再起動したら自動でファイアウォールが起動するようになります。

sudo sysrc firewall_enable="YES" && sudo sysrc firewall_logdeny="YES" && sudo sysrc firewall_type="workstation"

設定が成功したら下記のように出力されるはずです。

firewall_enable: NO -> YES
firewall_logdeny: NO -> YES
firewall_type: UNKNOWN -> workstation

これらの設定は上から順に

  • サーバー起動時に有効化
  • 拒否時に  / var / log / security にログ出力
  • ワークステーションのルールで動作

となります。

最後にコネクションあたりの最大ログの設定をしておきます。

echo "net.inet.ip.fw.verbose_limit=5" >> /etc/sysctl.conf

追加設定

さらに、sshやWEBサーバなどを許可する追加設定スクリプトを指定するには、次のようにします。

sudo sysrc firewall_script="/etc/ipfw.rules"

設定追加スクリプトの記述

公式のドキュメントを参考に、設定を記述していきます。

sudo vi /etc/ipfw.rules

公式ドキュメントの例をベースにWEBサーバーとsshdを中心に設定をする例を用意しました。

  • ファイアウォールの設定は個人のクセがあります。
    他方ではこのportを閉じるべき扱いをされていたり、
    このサービスのやり取りはport変えるべきなど様々な意見があります。
    このため、下記の設定例は参考程度ということでよろしくお願いします。

さて、次の設定を行った上で使用します。

  • NICの指定。
  • DNSサーバの指定。
  • sshdの受けportが22222に変更してあります。
    デフォルトは22、変更する場合は任意のport番号に。
#!/bin/sh
# この先頭のコメントはシェルスクリプトの実行パスなので消さないでください
# ファイル名、これは置き場所のメモです
# /etc/ipfw.rules
# ipfwのルールを初期化します
ipfw -q -f flush
# 何度も使うのでルール追加コマンドを変数に入れます
cmd="ipfw -q add"
# ネットワークカード(LANボード)の指定です。
# XXXを ifconfig a で表示される適切なNICカードで指定してください。
# VPSの場合はサーバーのIPアドレスが表示されているものを選びましょう。
pif="XXX"     # interface name of NIC attached to Internet
############################################################################
# stateful connections internal systems can create to hosts on the Internet
############################################################################
# DNS
# /etc/resolv.conf に記載のあるDNSサーバのIPアドレスでx.x.x.xを置き換えてください
$cmd 00110 allow tcp from any to x.x.x.x 53 out via $pif setup keep-state
$cmd 00111 allow udp from any to x.x.x.x 53 out via $pif keep-state
# LOCALHOST
$cmd 00120 allow all from any to any via lo0
$cmd 00121 deny  all from any to 127.0.0.0/8
$cmd 00122 deny  all from 127.0.0.0/8 to any
# 80 (WWW)
$cmd 00210 allow all from any to any  80 out via $pif setup keep-state
# 443 (https)
$cmd 00220 allow all from any to any 443 out via $pif setup keep-state
# Allow outbound email connections
$cmd 00230 allow tcp from any to any 25 out via $pif setup keep-state
$cmd 00231 allow tcp from any to any 110 out via $pif setup keep-state
# Allow outbound ping
$cmd 00250 allow icmp from any to any out via $pif keep-state
# Allow outbound NTP
$cmd 00260 allow udp from any to any 123 out via $pif keep-state
# Allow outbound SSH
$cmd 00280 allow tcp from any to any 22 out via $pif setup keep-state
# DENY
$cmd 00299 deny log all from any to any out via $pif
############################################################################
# Deny all inbound traffic from non-routable reserved address spaces
############################################################################
$cmd 00300 deny all from 192.168.0.0/16 to any in via $pif     #RFC 1918 private IP
$cmd 00301 deny all from 172.16.0.0/12 to any in via $pif      #RFC 1918 private IP
$cmd 00302 deny all from 10.0.0.0/8 to any in via $pif         #RFC 1918 private IP
$cmd 00303 deny all from 127.0.0.0/8 to any in via $pif        #loopback
$cmd 00304 deny all from 0.0.0.0/8 to any in via $pif          #loopback
$cmd 00305 deny all from 169.254.0.0/16 to any in via $pif     #DHCP auto-config
$cmd 00306 deny all from 192.0.2.0/24 to any in via $pif       #reserved for docs
$cmd 00307 deny all from 204.152.64.0/23 to any in via $pif    #Sun cluster interconnect
$cmd 00308 deny all from 224.0.0.0/3 to any in via $pif        #Class D & E multicast
# Deny public pings
$cmd 00310 deny icmp from any to any in via $pif
# Deny ident
$cmd 00315 deny tcp from any to any 113 in via $pif
# Deny all Netbios services.
$cmd 00320 deny tcp from any to any 137 in via $pif
$cmd 00321 deny tcp from any to any 138 in via $pif
$cmd 00322 deny tcp from any to any 139 in via $pif
$cmd 00323 deny tcp from any to any 81 in via $pif
# Deny fragments
$cmd 00330 deny all from any to any frag in via $pif
# Deny ACK packets that did not match the dynamic rule table
$cmd 00332 deny tcp from any to any established in via $pif
# Allow traffic from ISP's DHCP server.
# Replace x.x.x.x with the same IP address used in rule 00120.
#$cmd 00360 allow udp from any to x.x.x.x 67 in via $pif keep-state
# Allow HTTP connections to internal web server
$cmd 00400 allow all from any to me  80 in via $pif setup limit src-addr 2
$cmd 00401 allow all from any to me 443 in via $pif setup limit src-addr 2
# Allow inbound SSH connections
$cmd 00410 allow tcp from any to me 22222 in via $pif setup limit src-addr 2
# Reject and log all other incoming connections
$cmd 00499 deny log all from any to any in via $pif

ファイアウォールの起動

設定をしたら、ファイアウォールを起動しましょう。

  • 設定を間違えているとssh接続出来なくなったりします。
  • シリアルコンソールやシングルユーザーが無いなど、
    絶対に失敗できない場合はrootでcrontab -eして30分ごとに service ipfw stop し、
    上手くいったらあとで解除するなどで自衛しましょう。

それでは、下記のコマンドでファイアウォールを起動します。

sudo service ipfw start

起動後、有効なルールは次のコマンドで確認できます。

sudo ipfw -a list

再起動してのテスト

sshdへ正常につながり、WEBサーバも正常に見えるようなら
最後に一度サーバーマシン自体を再起動し、それでも正常かどうか見ておきましょう。

最近のVPSではメンテや物理サーバーの移動などで知らないうちにサーバーが再起動したりすることもあります。
その際にsshdが通じないと涙目になりますので。。。