NAT テーブルが溢れた...

 某所の F/W がおかしいということで救援要請が... 症状として

  • F/W 内部の Web、FTPSSHSMTP サーバへの接続が数回に一回しか成功しない
  • WAN 側 I/F まではパケットがキチンと来ている
  • LAN 側 I/F からはチョロチョロしかパケットが出て行かない
  • CPU 負荷、メモリ使用量などは大したことが無い

とのこと。日記のタイトルのごとく既に引退した身なのでサーバにログインすることもできず、それだけではさっぱり分からない... と言って臨時でアカウントを戻してもらうことに。

 で、見てみたらどうも /var/log/pf.log がドンドン増えていく。Firefox でアクセスした自分のパケットも記録されているので、確かにこれはおかしい。

  1. 昔、keep state ルールの flags に "S" を指定していたので、"S/SA" に修正
  2. (状況が変わらないので)pass all でフィルタリングを無効化
  3. ipnat -F で NAT テーブルを強制フラッシュ

の順で作業し、結局 ipnat -F で一時的に状況が改善しました。ということでどうも NAT テーブルが溢れていたようです。NAT テーブル溢れを改善するには... と Google で調べてみたら以下の URL が参考になったのでメモ。

方法としては

  1. ip_nat.h の "#undef LARGE_NAT" を "#define LARGE_NAT" に変えてカーネル再構築
  2. kernel MIB の幾つかの値を変更し、NAT テーブルの保持期間(?)を短くする

でしょうか。1 がベストでしょうけれども、流石に勝手に作り直すわけにもいかず。とりあえずは 2 の

# sysctl -w net.inet.ipf.fr_tcpidletimeout=7200
# sysctl -w net.inet.ipf.fr_tcpclosewait=120
# sysctl -w net.inet.ipf.fr_tcplastack=120
# sysctl -w net.inet.ipf.fr_tcptimeout=240
# sysctl -w net.inet.ipf.fr_tcpclosed=60
# sysctl -w net.inet.ipf.fr_tcphalfclosed=300
# sysctl -w net.inet.ipf.fr_udptimeout=90
# sysctl -w net.inet.ipf.fr_icmptimeout=35

で急場を凌ぎました。