NetflowをElastiflowで取り込む

Elasticsearchで取り込んだデータをKibanaでインデックス化まではいけたのだけれど, ダッシュボードにNetflowがないのでフォーラムに問い合わせしてみたら, 「ElastiFlowをおすすめする」と言われたのでそちらでやってみた。

手順はここにある。
https://github.com/robcowart/elastiflow

しかし必要リソースが多い・・・。

flows/sec (v)CPUs Memory Disk (30-days) ES JVM Heap LS JVM Heap
250 4 24 GB 305 GB 8 GB 4 GB
1000 8 32 GB 1.22 TB 12 GB 4 GB
2500 12 64 GB 3.05 TB 24 GB 6 GB

手順

  1. 確認
  2. Javaのヒープサイズ確認
  3. Logstash Pluginインストール
  4. Git Hubから関連ファイル取得・配置
  5. 設定ファイル編集
  6. プロセス再起動
  7. Kibanaでインデックス作成・ダッシュボードjsonを読み込む

アップデート

もろもろアップデートしておく。なお, Elasticsearchのバージョンは6.2.4。

yum update -y

Javaのヒープサイズ変更

It is recommended that Logstash be given at least 2GB of JVM heap. If all options, incl. DNS lookups (requires version 3.0.10 or later of the DNS filter), are enabled increase this to 4GB. 

とあったので初期値1G, MAX値を4Gへ変更。

vi /etc/logstash/jvm.options
# Xms represents the initial size of total heap space
# Xmx represents the maximum size of total heap space

#-Xms256m
#-Xmx1g
-Xms1g
-Xmx4g

Logstash Pluginインストール

# ./logstash-plugin install logstash-codec-sflow
Validating logstash-codec-sflow
Installing logstash-codec-sflow
Installation successful
# ./logstash-plugin update logstash-codec-netflow
Updating logstash-codec-netflow
Updated logstash-codec-netflow 3.13.2 to 3.14.0
# ./logstash-plugin update logstash-input-udp
Updating logstash-input-udp
Updated logstash-input-udp 3.3.2 to 3.3.3
# ./logstash-plugin update logstash-filter-dns
Updating logstash-filter-dns
Updated logstash-filter-dns 3.0.9 to 3.0.10

Git Hubから関連ファイル取得・配置・編集

% git clone https://github.com/robcowart/elastiflow.git
% ls -l elastiflow
total 32
drwxrwxr-x. 2 centos centos 75 May 24 20:02 kibana
-rw-rw-r--. 1 centos centos 1026 May 24 20:02 LICENSE.md
drwxrwxr-x. 3 centos centos 23 May 24 20:02 logstash
drwxrwxr-x. 2 centos centos 54 May 24 22:49 logstash.service.d
drwxrwxr-x. 2 centos centos 26 May 24 20:02 profile.d
-rw-rw-r--. 1 centos centos 28091 May 24 20:02 README.md

設定ファイル配置

# cp -r ./elastiflow/logstash/elastiflow/ /etc/logstash/

設定ファイル編集。
netflow以外使わないので, それ以外のファイルはdisableにした。

10_input_ipfix_ipv4.logstash.conf.disabled
10_input_ipfix_ipv6.logstash.conf.disabled
10_input_netflow_ipv4.logstash.conf
10_input_netflow_ipv6.logstash.conf.disabled
10_input_sflow_ipv4.logstash.conf.disabled
10_input_sflow_ipv6.logstash.conf.disabled
20_filter_10_begin.logstash.conf
20_filter_20_netflow.logstash.conf
20_filter_30_ipfix.logstash.conf.disabled
20_filter_40_sflow.logstash.conf.disabled
20_filter_90_post_process.logstash.conf
30_output.logstash.conf

インプットファイル編集

# vi 10_input_netflow_ipv4.logstash.conf

変更点。

host => "${ELASTIFLOW_NETFLOW_IPV4_HOST:172.16.10.50}"
port => "${ELASTIFLOW_NETFLOW_IPV4_PORT:9995}"

アウトプットファイル編集

# vi 30_output.logstash.conf

変更点。

hosts => [ "${ELASTIFLOW_ES_HOST:172.16.10.50:9200}" ]
user => "${ELASTIFLOW_ES_USER:elastic}"
password => "${ELASTIFLOW_ES_PASSWD:elastic}"

起動スクリプト配置

# cp -r ./elastiflow/logstash.service.d/ /etc/systemd/system/

起動スクリプト編集

# vi /etc/systemd/system/logstash.service.d/elastiflow.conf

変えたところは以下。

Environment="ELASTIFLOW_NAMESERVER=1.1.1.1"
Environment="ELASTIFLOW_ES_HOST=172.16.10.50"
Environment="ELASTIFLOW_ES_PASSWD=changeme"
Environment="ELASTIFLOW_NETFLOW_IPV4_HOST=172.16.10.50"
Environment="ELASTIFLOW_NETFLOW_IPV4_PORT=9995"

アプリケーションID登録。

# vi /etc/logstash/elastiflow/dictionaries/app_id.srctype.yml

Cisco841を登録。

"192.168.1.2": "c841m"

pipeline.ymlに以下追加。合わせてnetflowの行はコメントアウト。

# For ElastiFlow
- pipeline.id: elastiflow
path.config: "/etc/logstash/elastiflow/conf.d/*.conf"

プロセス再起動

#systemctl restart logstash
#systemctl daemon-reload

Kibanaにjson取り込み

「Management -> Save Objects -> Import」でGitから取得したelastiflow.dashboards.jsonをインポート。

できた!

ただ, うちの仮想マシンのスペック不足で結構な頻度でエラーが出る。
この辺は今の状況ではどうしようもないなー。

【メモ】MTUの種類

Catalystでジャンボフレームに対応させる設定を調べていて, MTU周りについてのメモ。

参考)
インターフェイスおよびハードウェア コンポーネント コンフィギュレーション ガイド、Cisco IOS XE Release 3SE(Catalyst 3650 スイッチ)
Interface and Hardware Component Configuration Guide, Cisco IOS XE Release 3SE (Catalyst 3650 Switches)
微妙に日本語と英語のサイトが違う。

System MTU Values

The following MTU values can be configured:
  • System MTU–This value applies to switched packets on the Gigabit Ethernet and 10-Gigabit Ethernet ports of the switch. Use the system mtu bytes global configuration command to specify the system jumbo MTU value.
  • System Jumbo MTU–This value applies to switched packets on the Gigabit Ethernet and 10-Gigabit Ethernet ports of the switch. Use the system mtu jumbo bytesglobal configuration command to specify the system jumbo MTU value.
  • Protocol-specific MTU–This value applies only to routed packets on all routed ports of the switch or switch stack. Use the ip mtu bytes or ipv6 mtu bytes interface configuration command to specify the protocol-specific MTU value.

・system mtu コマンド
1Gと10Gのスイッチングポートに適用。設定後再起動が必要。
・system mtu jumbo コマンド
1Gと10Gのスイッチングポートに適用。設定後再起動が必要。
上と何が違うんだ???
・ip mtu コマンド
Routed-portに適用される設定。インタフェースに設定。再起動不要。
system mtu の値より大きいものは設定不可。

うーん。「system mtu」と「system mtu jumbo」違いが分からない。
と, ここでCat3650が1Gbps以上のインタフェースしか持っていないからこういうマニュアルになっているのか?と思って別の機種も含めて調べてみると・・・。

 Catalyst スイッチでのジャンボ/ジャイアント フレーム サポートの設定例

すべての 10/100 インターフェイスで MTU を変更するには、system mtu コマンドを使用します。 このコマンドは、10/100 インターフェイスについてのみ効力があります。
3750(config)# system mtu 15463750(config)# exit3750# reload
すべてのギガビット イーサネット インターフェイスで MTU を変更するには、system mtu jumbo コマンドを使用します。 このコマンドは、ギガビット イーサネット インターフェイスについてのみ効力があります。
3750(config)# system mtu jumbo 90003750(config)# exit3750# reload
: system mtu コマンドはギガビット イーサネット ポートには影響せず、 system mtu jumbo コマンドは 10/100 ポートには影響しません。 system mtu jumbo コマンドを設定していない場合は、system mtu コマンドの設定がすべてのギガビット イーサネット インターフェイスに適用されます。

とあった。1G以上のインタフェースしかないスイッチでは「system mtu」でも「system mtu jumbo」でもどちらでもすればよさそう。

【メモ】elasticsearchアップグレードしたらエラーで起動しない件

Just a note。

こんなメッセージが出て起動しなかった。

java.lang.IllegalArgumentException: plugin [ingest-geoip] is incompatible with version [6.2.4]; was designed for version [6.1.2]
at org.elasticsearch.plugins.PluginInfo.readFromProperties(PluginInfo.java:237) ~[elasticsearch-6.2.4.jar:6.2.4]
at org.elasticsearch.plugins.PluginInfo.readFromProperties(PluginInfo.java:184) ~[elasticsearch-6.2.4.jar:6.2.4]
at org.elasticsearch.bootstrap.Spawner.spawnNativePluginControllers(Spawner.java:75) ~[elasticsearch-6.2.4.jar:6.2.4]
at org.elasticsearch.bootstrap.Bootstrap.setup(Bootstrap.java:167) ~[elasticsearch-6.2.4.jar:6.2.4]
at org.elasticsearch.bootstrap.Bootstrap.init(Bootstrap.java:323) [elasticsearch-6.2.4.jar:6.2.4]
at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:121) [elasticsearch-6.2.4.jar:6.2.4]
at org.elasticsearch.bootstrap.Elasticsearch.execute(Elasticsearch.java:112) [elasticsearch-6.2.4.jar:6.2.4]
at org.elasticsearch.cli.EnvironmentAwareCommand.execute(EnvironmentAwareCommand.java:86) [elasticsearch-6.2.4.jar:6.2.4]
at org.elasticsearch.cli.Command.mainWithoutErrorHandling(Command.java:124) [elasticsearch-cli-6.2.4.jar:6.2.4]
at org.elasticsearch.cli.Command.main(Command.java:90) [elasticsearch-cli-6.2.4.jar:6.2.4]
at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:92) [elasticsearch-6.2.4.jar:6.2.4]
at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:85) [elasticsearch-6.2.4.jar:6.2.4]

一度6.1.3へダウングレードして, ingest-geoipを削除。 その後またアップグレードで復旧。

NAT on a stick

例えばNATに対応していない機器(L3SW等)があったとして, それでもNATしなくてはならない場合。
図のようにワンアームでルータをつないでNATボックスとする構成が取れる。

図ではルータのアイコンになっているけれど, R1がNATに対応していないとき

ヘアピンNATやNAT on a Stick と呼ぶらしい。
Ciscoサイトを参照して検証する。
参照URL:スティック上のネットワーク アドレス変換

構成概要

    • 172.16.10.0/24 を172.20.10.0/24 へネットワークNATする。
    • NATポイントはR2。
    • VPC2は172.20.10.0/24のアドレスでアクセスする。

      そのため, R1では必然的にPBRを利用してVPC1の通信をR2へ転送する。

      Config

      ※ 抜粋
      R1 Config

      !
      interface Ethernet0/0
      description to R3
      ip address 192.168.2.1 255.255.255.0
      !
      interface Ethernet0/1
      description to R2
      ip address 10.10.10.1 255.255.255.0
      !
      interface Ethernet0/2
      description to R4
      ip address 192.168.1.1 255.255.255.0
      ip policy route-map PBR
      !
      ip route 172.16.10.0 255.255.255.0 192.168.1.2
      ip route 172.16.20.0 255.255.255.0 192.168.2.2
      ip route 172.20.10.0 255.255.255.0 10.10.10.2
      !
      ip access-list extended PBR
      permit ip 172.16.10.0 0.0.0.255 any
      !
      !
      route-map PBR permit 10
      match ip address PBR
      set ip next-hop 10.10.10.2
      !
      !

      R2 Config

      !
      interface Loopback0
      ip address 1.1.1.1 255.255.255.255
      ip nat outside
      ip virtual-reassembly in
      !
      interface Ethernet0/0
      description to R1
      ip address 10.10.10.2 255.255.255.0
      ip nat inside
      ip virtual-reassembly in
      ip policy route-map NAT
      !
      !
      ip nat inside source static network 172.16.10.0 172.20.10.0 /24 no-alias
      ip route 0.0.0.0 0.0.0.0 10.10.10.1
      ip route 172.20.10.0 255.255.255.0 Ethernet0/0
      !
      ip access-list extended PBR
      permit ip 172.16.10.0 0.0.0.255 any
      permit ip any 172.20.10.0 0.0.0.255
      !
      !
      route-map NAT permit 10
      match ip address PBR
      set interface Loopback0
      !

      パケットフロー
      CiscoルータにおけるNATの処理は公式ページにあるとおり。
      参考:NATの処理順序
      今回関係する箇所を太文字で。

      1. IPSec ACL チェック
      2. 復号化
      3. 入力ACLチェック
      4. 入力レート制限をチェック
      5. 入力アカウンティング
      6. Web キャッシュにリダイレクト
      7. ポリシー ルーティング
      8. ルーティング
      9. Inside から Outside への NAT
      10. クリプト(暗号化用のマップのチェックとマーク)
      11. 出力アクセス リストをチェック
      12. CBAC検査
      13. TCP インターセプト
      14. 暗号化
      15. キューイング
      1. IPSec ACL チェック
      2. 復号化
      3. 入力ACLチェック
      4. 入力レート制限をチェック
      5. 入力アカウンティング
      6. Web キャッシュにリダイレクト
      7. OutsideからInsideへの NAT
      8. ポリシー ルーティング
      9. ルーティング
      10. クリプト(暗号化用のマップのチェックとマーク)
      11. 出力アクセス リストをチェック
      12. CBAC 検査
      13. TCP インターセプト
      14. 暗号化
      15. キューイング

      プチ解説

      @R1
      NAT変換後のアドレスをR2へ向けます。

      ip route 172.16.20.0 255.255.255.0 192.168.2.2

      VPC1からのトラフィックをR2(NATボックス)へ捻じ曲げます。

      interface Ethernet0/2
      description to R4
      ip address 192.168.1.1 255.255.255.0
      ip policy route-map PBR
      !
      !
      ip access-list extended PBR
      permit ip 172.16.10.0 0.0.0.255 any
      !
      !
      route-map PBR permit 10
      match ip address PBR
      set ip next-hop 10.10.10.2

      @R2
      物理IFをinsideに指定します。

      interface Ethernet0/0
      description to R1
      ip address 10.10.10.2 255.255.255.0
      ip nat inside
      ip virtual-reassembly in

      Loopbackをoutsideに指定します。

      interface Loopback0
      ip address 1.1.1.1 255.255.255.255
      ip nat outside
      ip virtual-reassembly in

      NAT設定。IOS15以降はno-aliasが必要です。

      ip nat inside source static network 172.16.10.0 172.20.10.0 /24 no-alias

      global insideのアドレスを自身に持たせるためStatic Routeを物理IFへ指定します。
      が, この構成ではなくてもいけました。(NATの処理フロー見ると不要な気がするんですが未だ理解できず。)

      ip route 172.20.10.0 255.255.255.0 Ethernet0/0

      NAT対象となる通信をPBRでLoopbackインタフェース(outside IF)へ送り込みます。これでinside-outsideに偽装します。

      interface Ethernet0/0
      description to R1
      ip address 10.10.10.2 255.255.255.0
      ip nat inside
      no ip virtual-reassembly in
      ip policy route-map NAT
      !
      !
      ip access-list extended PBR
      permit ip 172.16.10.0 0.0.0.255 any
      permit ip any 172.20.10.0 0.0.0.255
      !
      !
      route-map NAT permit 10
      match ip address PBR
      set interface Loopback0
      !

      通信確認。

      VPCS> ping 172.16.20.1

      84 bytes from 172.16.20.1 icmp_seq=1 ttl=251 time=1.802 ms
      84 bytes from 172.16.20.1 icmp_seq=2 ttl=251 time=3.606 ms
      84 bytes from 172.16.20.1 icmp_seq=3 ttl=251 time=4.168 ms
      84 bytes from 172.16.20.1 icmp_seq=4 ttl=251 time=3.517 ms
      84 bytes from 172.16.20.1 icmp_seq=5 ttl=251 time=3.150 ms


      R2#sh ip nat translations
      Pro Inside global Inside local Outside local Outside global
      icmp 172.20.10.10:28052 172.16.10.10:28052 172.16.20.1:28052 172.16.20.1:28052
      icmp 172.20.10.10:28308 172.16.10.10:28308 172.16.20.1:28308 172.16.20.1:28308
      icmp 172.20.10.10:28564 172.16.10.10:28564 172.16.20.1:28564 172.16.20.1:28564
      icmp 172.20.10.10:28820 172.16.10.10:28820 172.16.20.1:28820 172.16.20.1:28820
      icmp 172.20.10.10:29076 172.16.10.10:29076 172.16.20.1:29076 172.16.20.1:29076
      --- 172.20.10.10 172.16.10.10 --- ---
      --- 172.20.10.0 172.16.10.0 --- ---
      R2#

      VPCS> ping 172.20.10.10

      84 bytes from 172.20.10.10 icmp_seq=1 ttl=59 time=2.539 ms
      84 bytes from 172.20.10.10 icmp_seq=2 ttl=59 time=4.796 ms
      84 bytes from 172.20.10.10 icmp_seq=3 ttl=59 time=5.276 ms
      84 bytes from 172.20.10.10 icmp_seq=4 ttl=59 time=4.397 ms
      84 bytes from 172.20.10.10 icmp_seq=5 ttl=59 time=6.855 ms

      VPCS>

      注意点

      Loopback IFへトラフィックを投げるのでCPU処理に落ちます。
      スループットが気になる場合は物理的に(もしくはトランク等して)2本インタフェースを用意したほうがベター。
      IOS12台と15台でコマンドが若干違うので古いバージョンを使うときは確認しましょう。