labunix's blog

labunixのラボUnix

Fortigate-60Cの性能情報ログを自前のスクリプトで取得する。

■Fortigate-60Cの性能情報ログを自前のスクリプトで取得する。
 Fortigate-60CのCPU(1core)、メモリ(512MB)、npuのすべてにおいて、
 ngfwライセンスを適用した場合でもすべての機能を有効にするほどのリソースは無い。
 また、ログディスクが無いモデルのため、特にメモリがボトルネックになりやすい。

# get system status | grep ^Version
Version: FortiGate-60C v5.2.3,build0670,150318 (GA)

# get hardware status 
Model name: FortiGate-60C
ASIC version: CP0
ASIC SRAM: 64M
CPU: FortiSOC
Number of CPUs: 1
RAM: 439 MB
MTD Flash: 128 MB /dev/mtd
Hard disk: not available
USB Flash: not available

■Fortigate-60Cに搭載しているのはnpu4のみで、
 主な目的はVPNの高速処理

# get system npu 
enc-offload-antireplay: disable 
dec-offload-antireplay: enable 
offload-ipsec-host  : disable 

# get hardware cpu | grep MIPS
BogoMIPS	: 524.28
Command fail. Return code -27

# show full-configuration system global | grep offload
    set ipsec-hmac-offload enable

# show full-configuration system npu 
config system npu
    set enc-offload-antireplay disable
    set dec-offload-antireplay enable
    set offload-ipsec-host disable
end

# show full-configuration firewall policy | grep "auto-asic\|edit"
    edit 1
        set auto-asic-offload enable
    edit 3
        set auto-asic-offload enable
    edit 4
        set auto-asic-offload enable5分間隔で取得するはずの性能情報も実際には常に正確に5分置きに取得しているわけでは無い。
 ※CPUの使用率が0%なのは、まだテスト環境なので、
  firewall policyにマッチする通信がほとんど無いため。
  この状況でメモリ不足は厳しい。

$ sudo awk '/perf-stats/{OFS=",";print $5,$6,$18,$19}' \
    /var/log/Fortigate-80C.log | \
    sed -e 's/date=//g' -e 's/time=//g' \
        -e 's/cpu=//g' -e 's/mem=//g' -e 's%-%/%g' | \
    grep `date -d "Yesterday" '+%Y/%m/%d'` | head -5
2015/08/15,02:19:00,0,76
2015/08/15,03:28:59,0,76
2015/08/15,03:30:07,0,82
2015/08/15,03:33:59,0,76
2015/08/15,03:35:07,0,82

■もう少し調べてみると性能情報を取得していない時間帯もある。

$ sudo awk '/perf-stats/{OFS=",";print $5,$6,$18,$19}' \
    /var/log/Fortigate-80C.log | \
    sed -e 's/date=//g' -e 's/time=//g' \
        -e 's/cpu=//g' -e 's/mem=//g' -e 's%-%/%g' | \
    grep "2015/08/16" | awk -F\, '{print $2}' | cut -c -2 | uniq -c
      1 01
     15 03
     24 04
     24 05
     24 06
     24 07
     24 08
     24 09
     24 10
     24 11
     24 12
     24 13
     24 14
     24 15
     24 16
     13 17

■最も頻度の高いメモリの使用率は以下の77%と83%。

$ sudo awk '/perf-stats/{OFS=",";print $5,$6,$18,$19}' \
    /var/log/Fortigate-80C.log | \
    sed -e 's/date=//g' -e 's/time=//g' \
        -e 's/cpu=//g' -e 's/mem=//g' -e 's%-%/%g' | \
    grep "2015/08/16" | \
    awk -F\, '{print $4}' | sort | uniq -c | awk '($1>10){print}'
    160 77
    170 8380%のしきい値を超えるとを新規セッションを受け付けない
 「conserve mode」になるが、今月については以下のようなログは見当たらない。

$ sudo grep "conserve mode" /var/log/Fortigate-60C.log  | \
    tail -1 | sed s/"[a-z0-9]*=[a-z0-9]*"/"\n  &"/g | tail -10
  type=event 
  subtype=system 
  level=notice 
  vd="root" 
  logdesc="Kernel leaves conserve mode" 
  service=kernel 
  conserve=exit 
  free="40532 pages" 
  green="39321 pages" 
  msg="Kernel leaves conserve mode"

■対処方法については以下にナレッジがある。

 "The system has entered conserve mode" FortiGate log message explanation
 http://kb.fortinet.com/kb/viewContent.do?externalId=11076

■TTL等の調整はせずに、DHCPサーバを無効にしたり、SNMPを止めるなどの対処を行い、
 機能は減らさずにメモリ使用率は68%まで低減できた。

# get system performance status | grep "CPU\|Mem"
CPU states: 0% user 0% system 0% nice 100% idle
CPU0 states: 0% user 0% system 0% nice 100% idle
Memory states: 68% used

■後は自分で性能情報を取得する。
 例えば、アカウントがデフォルトで、
 172.31.31.252からtelnetが有効なinterfaceに接続した端末から
 性能情報を採取するスクリプトを書く。

$ cat fortigate-perf.sh 
#!/bin/bash

USERNAME=admin
PASSWORD=
TARGETIP=172.31.31.252
COMMAND="get system performance status"

(sleep 1;echo "$USERNAME"; \
 sleep 1;echo "$PASSWORD"; \
 sleep 1;echo "$COMMAND"; \
 sleep 3;echo "exit"; \
) | telnet $TARGETIP 2>&1 | \
  awk 'BEGIN{"date +%Y/%m/%d,%H:%M:%S" | getline;printf $0}; \
            {if ($1=="CPU")    {printf ",%d",100-$(NF-1)} \
        else{if ($1=="Memory") {printf ",%d",$(NF-1)-0} \
            }}; \
       END  {printf "\n"}'

■実行結果は以下。

$ ./fortigate-perf.sh 
2015/08/16,20:21:17,12,68

■cronに登録

$ ls -l /var/local/fortigate-perf.sh 
-rwxr-xr-x 1 labunix labunix 468  816 20:19 /var/local/fortigate-perf.sh

$ cat /etc/cron.d/fgtperf 
#
SHELL=/bin/sh
PATH=/bin:/usr/bin
FGTPERF=/var/local/fortigate-perf.sh
FGTPERFLOG=/var/log/fortigate-perf.csv

*/5 * * * *   root	test -x $FGTPERF && /bin/bash $FGTPERF >> $FGTPERFLOG

$ sudo /etc/init.d/cron reload
[ ok ] Reloading configuration files for periodic command scheduler: cron.

■ところで、1%とはどの位かと言うと、約4MB。

$ cat fortigate-mem1per.sh 
#!/bin/bash

USERNAME=admin
PASSWORD=
TARGETIP=172.31.31.252
COMMAND="get hardware memory"

(sleep 1;echo "$USERNAME"; \
 sleep 1;echo "$PASSWORD"; \
 sleep 1;echo "$COMMAND"; \
 sleep 3;echo "exit"; \
) | telnet $TARGETIP 2>&1 | \
  awk '/MemTotal/ {print $2/100"kB"}' 

$ ./fortigate-mem1per.sh 
4503.84kB

■68%とは「68.0~68.9%」と考えた場合、
 使用率からしきい値の80%まで約49MB使用出来る。

$ ./fortigate-mem1per.sh | awk '{print $1*(80-(68+1))"kB"}'
49542.2kB

■最後にcronが順調に性能情報ログを出力し続けていることを確認。

$ sudo tail -f /var/log/fortigate-perf.csv 
2015/08/16,20:35:01,4,68
2015/08/16,20:40:01,4,68
2015/08/16,20:45:01,2,68
2015/08/16,20:50:01,2,68
2015/08/16,20:55:01,2,68

■余談。
 telnetのユーザ、パスワードを保存する方法よりも、
 sshの公開鍵をFortigateに登録する方法に置き換える方が良い。

 Fortigate-80Cのバックアップをscpとcronで自動化する。
 http://labunix.hateblo.jp/entry/20150301/1425137577

$ echo 'config system admin
edit labunix
set accprofile prof_admin
set ssh-public-key1 "'`cat .ssh/id_rsa.pub | awk '{print $1,$2}'`'"
end' | ssh -T admin@172.31.31.252

$ ssh admin@172.31.31.252 "get system performance status" 2>&1 | \
  awk 'BEGIN{"date +%Y/%m/%d,%H:%M:%S" | getline;printf $0}; \                                                       
            {if ($1=="CPU")    {printf ",%d",100-$(NF-1)} \
        else{if ($1=="Memory") {printf ",%d",$(NF-1)-0} \                                        
            }}; \
       END  {printf "\n"}'
2015/08/16,21:03:27,68