Ubuntuでufwを設定する

ufw (Uncomplicated Firewall) は主にUbuntuで採用されているiptablesのラッパーで,pythonで実装されている.

iptablesをより平易な構文で使えるようになるのが利点だ.

ネットワークにあまり詳しくないサーバエンジニアにとっては,iptablesはそれなりに難解なものらしい.

筆者はインフラ系のSEとして,Reflexive ACLやLock and Key ACLに始まり,Time Based ACLやEEMとTCLを駆使したEvent Driven ACLなど,変態的なアクセス制御をCisco謹製ルータで実装してきた身としては,iptablesは構文も平易で機能も充実しておりなかなか便利なやつである.最初はBSDのipfwより設定書きにくいなーなどと思ったものだが.

閑話休題

今回は Ubuntu Server 12.10 quantal quetzal を使用し,以下の示す要件を満たす設定を実施する.

要件

今回設定対象のサーバはVPSでホストされたUbuntuで,ウェブアプリケーションサーバとして利用する. アクセス制御は以下の要件を満たすものとする.

  1. IPv6サポートをOFFにする
  2. 特定の Source IP address(自宅,オフィス等)に対し,SSH(TCP/22)を制限無しで許可する
  3. 明示的に許可されていない通信は全て遮断する
  4. SSH(TCP/22)を開放し,総当たり攻撃対策として,接続要求に閾値を設ける
  5. HTTP(TCP/80)を開放する
  6. HTTPS(TCP/443)を開放する

さて,実装にかかるまえの注意事項だが,当然ufwやiptablesが初期状態かつ無効化されていることを前提にしている.

ufwが動いている状態で設定を行うと,当然ながら既存の設定や接続に影響を及ぼす可能性があるので十分に注意が必要だ.

Set up the firewall using ufw on ubuntu

1. IPv6サポートのOFF

/etc/default/ufw に以下の設定を追加する.

-IPV6=yes
+IPV6=no

2. 特定の Source IP addressに対し,SSH(TCP/22)を制限無しで許可する

/etc/ufw/before.rules に設定を追加する.

参考までに筆者の設定を以下に記載した.

0.0.0.0の部分は,適宜必要なホストあるいはネットワークアドレスに変更してほしい.

# allow SSH remote access
## home
-A ufw-before-input -m state --state NEW -m tcp -p tcp --dport 22 -s 0.0.0.0 -j ACCEPT
## office
-A ufw-before-input -m state --state NEW -m tcp -p tcp --dport 22 -s 0.0.0.0 -j ACCEPT

3 . 明示的に許可されていない通信は全て遮断する

ここからがufwコマンドを使った設定だ.

以下のコマンドを特権にて発行する.

# ufw default DENY

4. SSH(TCP/22)を開放し,ブルートフォース攻撃対策として,接続要求に閾値を設ける

以下のコマンドを特権にて発行する.

# ufw limit 22

ここまでで,簡単なブルートフォース攻撃対策を設けたSSHの許可設定と,それ以外を遮断するルールの準備ができた.

ufwを起動し,ステータスの確認をしてみよう.

ここまでで失敗をしていると,最悪リモートアクセスできなくなる恐れがあるので,念の為コンソールに入れるように準備をしておく.

まずは有効化だ.以下のコマンドを特権にて発行する.

# ufw enable

続いて,設定の確認をしてみよう.以下のコマンドを特権にて発行する.

# ufw status

Status: active

To                         Action      From
--                         ------      ----
22                         LIMIT       Anywhere

上記のように見えていれば問題ない.

5. HTTP(TCP/80)を開放する

以下のコマンドを特権にて発行する.

# ufw allow 80

6. HTTPS(TCP/443)を開放する

以下のコマンドを特権にて発行する.

# ufw allow 443

7. 確認

要件通りの設定が入っていることを確認する.

# ufw status
Status: active

To                         Action      From
--                         ------      ----
22                         LIMIT       Anywhere
80                         ALLOW       Anywhere
443                        ALLOW       Anywhere

2.の要件はiptablesコマンドで確認する必要がある.

# iptables -L ufw-before-input -v -n

Chain ufw-before-input (1 references)
 pkts bytes target     prot opt in     out     source               destination         
 5552  375K ACCEPT     all  --  lo     *       0.0.0.0/0            0.0.0.0/0           
 380K  152M ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
 3688  180K ufw-logging-deny  all  --  *      *       0.0.0.0/0            0.0.0.0/0            state INVALID
 3688  180K DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            state INVALID
    0     0 ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0            icmptype 3
    0     0 ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0            icmptype 4
    0     0 ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0            icmptype 11
    0     0 ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0            icmptype 12
  373 13392 ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0            icmptype 8
    0     0 ACCEPT     udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp spt:67 dpt:68
2322K  326M ufw-not-local  all  --  *      *       0.0.0.0/0            0.0.0.0/0           
    0     0 ACCEPT     udp  --  *      *       0.0.0.0/0            224.0.0.251          udp dpt:5353
    0     0 ACCEPT     udp  --  *      *       0.0.0.0/0            239.255.255.250      udp dpt:1900
    5   276 ACCEPT     tcp  --  *      *       XXX.XXX.XXX.XXX        0.0.0.0/0            state NEW tcp dpt:22
    3   180 ACCEPT     tcp  --  *      *       YYY.YYY.YYY.YYY        0.0.0.0/0            state NEW tcp dpt:22
2322K  326M ufw-user-input  all  --  *      *       0.0.0.0/0            0.0.0.0/0 

上記出力においてXXXやYYYでマスクされている箇所が,自分で設定した任意のIPアドレスになっていれば問題ない.