ufwを可視化

最近のUbuntu Linuxはufw(User Fire Wall)でiptablesをサクッと管理できる。iptableはある一定の攻撃とかバーストしてきた物は遮断してログに出力する事ができる。ufwだと/var/log/ufw.logに出力されて…こんな感じで見れる。

Jan 15 06:54:07 xxxxxxxx kernel: [403471.687391] [UFW BLOCK] IN=eth0 OUT= MAC=02:AA:BB:CC:DD:EE:FF:GG:HH:II:JJ:KK:LL:00 SRC=94.179.145.26 DST=AAA.AAA.AAA.AAA LEN=40 TOS=0x00 PREC=0x00 TTL=239 ID=16411 PROTO=TCP SPT=9807 DPT=23231 WINDOW=8192 RES=0x00 SYN URGP=0 
Jan 15 06:54:18 xxxxxxxx kernel: [403483.004926] [UFW BLOCK] IN=eth0 OUT= MAC=02:AA:BB:CC:DD:EE:FF:GG:HH:II:JJ:KK:LL:00 SRC=203.189.152.165 DST=AAA.AAA.AAA.AAA LEN=44 TOS=0x00 PREC=0x00 TTL=240 ID=15727 PROTO=TCP SPT=62986 DPT=23 WINDOW=14600 RES=0x00 SYN URGP=0 
Jan 15 06:54:44 xxxxxxxx kernel: [403509.027416] [UFW BLOCK] IN=eth0 OUT= MAC=02:AA:BB:CC:DD:EE:FF:GG:HH:II:JJ:KK:LL:00 SRC=203.189.156.28 DST=AAA.AAA.AAA.AAA LEN=44 TOS=0x00 PREC=0x00 TTL=240 ID=4355 PROTO=TCP SPT=2541 DPT=23 WINDOW=14600 RES=0x00 SYN URGP=0 

一部割愛しているけど、まぁこんな感じ。折角、アタックしてきてくれているから、このlogginデータを使わないわけにはいけないよね…何か楽しいし(w)と思うのは自然な感じ。
というわけで、構成はこんな感じでkibanaで可視化することに。

[ufw.log]->[fluentd]->[elasticsearch]->[kibana]

まずは結果から…データは2017/01/14-17のとある1個のサーバに対して。こんな感じ。

1) attack logging count
12190(2.8/min)

2) TCP/UDP attack
TCP: 9144, UDP:3046

まぁ…TCPですよねー感はする。

2) port/tcp, udp attack top 20

イマドキtelnetかよ(w)的なツッコミをしたくなる。

3) attack country unique ip top 20

China                                   1076
Viet Nam                              367
United States                       334
Brazil                                     294
Korea, Republic of               274
Turkey                                  251
India                                      214
Taiwan, Province of China  210
Mexico                                  207
Russian Federation             196
Iran, Islamic Republic of     134
Argentina                             101
Romania                                 86
Italy                                        80
France                                    78
Ukraine                                   75
Thailand                                 74
Australia                                64
Poland                                    60
Colombia                                60

1位は断トツの中国。まぁこれはそうですね感はするけど、2位がUSを抜いてベトナムというのが何気にビリビリするものがある。あとはいっぱいIPアドレスのリストが取れて何か嬉しい(w)。

他にも攻撃してきたipをtracerouteして逆向きのIPアドレスの情報もロギングして取得している。例えばこんな感じに(超割愛しているw)

 
攻撃元
IP       101.204.212.118
Lon/Lat  30.6667, 104.067
国/街     China/Chengdu
+-----+-----------------+---------+---------+---------------+-------------------+
| ttl    | ip_addr           | lon       | lat        |country_name| city_name         |
+-----+-----------------+---------+---------+---------------+-------------------+
|   1  | 133.208.191.134 | 139.692 | 35.6895 | Japan         | Tokyo             |
|   2  | 62.115.63.101   | -87.65  | 41.85   | United States | Chicago           |
|   3  | 213.248.82.206  | 8.68417 | 50.1155 | Germany       | Frankfurt am Main |
|   4  | 219.158.25.29   | 116.397 | 39.9075 | China         | Beijing           |
|   5  | 219.158.103.97  | 116.397 | 39.9075 | China         | Beijing           |
|   6  | 219.158.110.222 | 116.397 | 39.9075 | China         | Beijing           |
+-----+-----------------+---------+---------+---------------+-------------------+

この場合は、中国->ドイツ->アメリカ->日本といった経路っすね。近いのに地球の反対側を通ってきているね。遠方よりはるばるお疲れさまです。このデータはDBに突っ込んでおいて使えるようにしていたりもする。

■ 設定
1) UFW
このufwはめっちゃ簡単にiptablesを管理できるからサラッと使っていたりする。例えば…

# ufw status 
状態: アクティブ
To                         Action      From
--                         ------      ----
443                        ALLOW       Anywhere
80                         ALLOW       Anywhere
80 (v6)                    ALLOW       Anywhere (v6)
443 (v6)                   ALLOW       Anywhere (v6)

こんな感じで一覧でサクッと分かる。iptablesだと…標準だとこんな感じね。

# iptables -L 
Chain INPUT (policy DROP)
target     prot opt source               destination         
ufw-before-logging-input  all  --  anywhere             anywhere            
ufw-before-input  all  --  anywhere             anywhere            
ufw-after-input  all  --  anywhere             anywhere            
ufw-after-logging-input  all  --  anywhere             anywhere            
ufw-reject-input  all  --  anywhere             anywhere            
ufw-track-input  all  --  anywhere             anywhere            

Chain FORWARD (policy DROP)
target     prot opt source               destination         
ufw-before-logging-forward  all  --  anywhere             anywhere            
ufw-before-forward  all  --  anywhere             anywhere            
ufw-after-forward  all  --  anywhere             anywhere            
ufw-after-logging-forward  all  --  anywhere             anywhere            
ufw-reject-forward  all  --  anywhere             anywhere            
ufw-track-forward  all  --  anywhere             anywhere            

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
ufw-before-logging-output  all  --  anywhere             anywhere            
ufw-before-output  all  --  anywhere             anywhere            
ufw-after-output  all  --  anywhere             anywhere            
ufw-after-logging-output  all  --  anywhere             anywhere            
ufw-reject-output  all  --  anywhere             anywhere            
ufw-track-output  all  --  anywhere             anywhere            

Chain ufw-after-forward (1 references)
target     prot opt source               destination         

Chain ufw-after-input (1 references)
target     prot opt source               destination         
ufw-skip-to-policy-input  udp  --  anywhere             anywhere             udp dpt:netbios-ns
ufw-skip-to-policy-input  udp  --  anywhere             anywhere             udp dpt:netbios-dgm
ufw-skip-to-policy-input  tcp  --  anywhere             anywhere             tcp dpt:netbios-ssn
ufw-skip-to-policy-input  tcp  --  anywhere             anywhere             tcp dpt:microsoft-ds
ufw-skip-to-policy-input  udp  --  anywhere             anywhere             udp dpt:bootps
ufw-skip-to-policy-input  udp  --  anywhere             anywhere             udp dpt:bootpc
ufw-skip-to-policy-input  all  --  anywhere             anywhere             ADDRTYPE match dst-type BROADCAST

Chain ufw-after-logging-forward (1 references)
target     prot opt source               destination         
LOG        all  --  anywhere             anywhere             limit: avg 3/min burst 10 LOG level warning prefix "[UFW BLOCK] "

Chain ufw-after-logging-input (1 references)
target     prot opt source               destination         
LOG        all  --  anywhere             anywhere             limit: avg 3/min burst 10 LOG level warning prefix "[UFW BLOCK] "

Chain ufw-after-logging-output (1 references)
target     prot opt source               destination         

Chain ufw-after-output (1 references)
target     prot opt source               destination         

Chain ufw-before-forward (1 references)
target     prot opt source               destination         
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
ACCEPT     icmp --  anywhere             anywhere             icmp destination-unreachable
ACCEPT     icmp --  anywhere             anywhere             icmp source-quench
ACCEPT     icmp --  anywhere             anywhere             icmp time-exceeded
ACCEPT     icmp --  anywhere             anywhere             icmp parameter-problem
ACCEPT     icmp --  anywhere             anywhere             icmp echo-request
ufw-user-forward  all  --  anywhere             anywhere            

Chain ufw-before-input (1 references)
target     prot opt source               destination         
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
ufw-logging-deny  all  --  anywhere             anywhere             ctstate INVALID
DROP       all  --  anywhere             anywhere             ctstate INVALID
ACCEPT     icmp --  anywhere             anywhere             icmp destination-unreachable
ACCEPT     icmp --  anywhere             anywhere             icmp source-quench
ACCEPT     icmp --  anywhere             anywhere             icmp time-exceeded
ACCEPT     icmp --  anywhere             anywhere             icmp parameter-problem
ACCEPT     icmp --  anywhere             anywhere             icmp echo-request
ACCEPT     udp  --  anywhere             anywhere             udp spt:bootps dpt:bootpc
ufw-not-local  all  --  anywhere             anywhere            
ACCEPT     udp  --  anywhere             224.0.0.251          udp dpt:mdns
ACCEPT     udp  --  anywhere             239.255.255.250      udp dpt:1900
ufw-user-input  all  --  anywhere             anywhere            

Chain ufw-before-logging-forward (1 references)
target     prot opt source               destination         

Chain ufw-before-logging-input (1 references)
target     prot opt source               destination         

Chain ufw-before-logging-output (1 references)
target     prot opt source               destination         

Chain ufw-before-output (1 references)
target     prot opt source               destination         
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
ufw-user-output  all  --  anywhere             anywhere            

Chain ufw-logging-allow (0 references)
target     prot opt source               destination         
LOG        all  --  anywhere             anywhere             limit: avg 3/min burst 10 LOG level warning prefix "[UFW ALLOW] "

Chain ufw-logging-deny (2 references)
target     prot opt source               destination         
RETURN     all  --  anywhere             anywhere             ctstate INVALID limit: avg 3/min burst 10
LOG        all  --  anywhere             anywhere             limit: avg 3/min burst 10 LOG level warning prefix "[UFW BLOCK] "

Chain ufw-not-local (1 references)
target     prot opt source               destination         
RETURN     all  --  anywhere             anywhere             ADDRTYPE match dst-type LOCAL
RETURN     all  --  anywhere             anywhere             ADDRTYPE match dst-type MULTICAST
RETURN     all  --  anywhere             anywhere             ADDRTYPE match dst-type BROADCAST
ufw-logging-deny  all  --  anywhere             anywhere             limit: avg 3/min burst 10
DROP       all  --  anywhere             anywhere            

Chain ufw-reject-forward (1 references)
target     prot opt source               destination         

Chain ufw-reject-input (1 references)
target     prot opt source               destination         

Chain ufw-reject-output (1 references)
target     prot opt source               destination         

Chain ufw-skip-to-policy-forward (0 references)
target     prot opt source               destination         
DROP       all  --  anywhere             anywhere            

Chain ufw-skip-to-policy-input (7 references)
target     prot opt source               destination         
DROP       all  --  anywhere             anywhere            

Chain ufw-skip-to-policy-output (0 references)
target     prot opt source               destination         
ACCEPT     all  --  anywhere             anywhere            

Chain ufw-track-forward (1 references)
target     prot opt source               destination         

Chain ufw-track-input (1 references)
target     prot opt source               destination         

Chain ufw-track-output (1 references)
target     prot opt source               destination         
ACCEPT     tcp  --  anywhere             anywhere             ctstate NEW
ACCEPT     udp  --  anywhere             anywhere             ctstate NEW

Chain ufw-user-forward (1 references)
target     prot opt source               destination         

Chain ufw-user-input (1 references)
target     prot opt source               destination         
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:https
ACCEPT     udp  --  anywhere             anywhere             udp dpt:https
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:http
ACCEPT     udp  --  anywhere             anywhere             udp dpt:http

Chain ufw-user-limit (2 references)
target     prot opt source               destination         
LOG        all  --  anywhere             anywhere             limit: avg 3/min burst 5 LOG level warning prefix "[UFW LIMIT BLOCK] "
REJECT     all  --  anywhere             anywhere             reject-with icmp-port-unreachable

Chain ufw-user-limit-accept (2 references)
target     prot opt source               destination         
ACCEPT     all  --  anywhere             anywhere            

Chain ufw-user-logging-forward (0 references)
target     prot opt source               destination         

Chain ufw-user-logging-input (0 references)
target     prot opt source               destination         

Chain ufw-user-logging-output (0 references)
target     prot opt source               destination         

Chain ufw-user-output (1 references)
target     prot opt source               destination      

まぁ..iptablesはパッと見で意味不明っすね。ってことで、ufwは適宜設定しておく。

2) fluentdの設定
ノリでこんな感じ。ufwからは他にも色々と取れたりするから適宜取得しておく。ぶっちゃけ、これ書いて設定とか終わりな感はする。

<source>
 type tail
 time_key time
 format /(?<time>[^\]]*).*SRC=(?<src>[^ ]*).*PROTO=(?<proto>[^ ]*).*DPT=(?<dpt>[^ ]*).*/ 
 time_format %b %d %H:%M:%S 
 path /var/log/ufw.log
 pos_file /var/log/td-agent/ufw.pos
 tag ufw.combined
</source>
<match ufw.*>
 type elasticsearch
 host hogehoge.host
 port 9200

 index_name ufw_log
 type_name ufw_log
 logstash_format true
 logstash_prefix ufw_access
 logstash_dateformat %Y%m
</match>

3) elasticsearch/kibanaの設定
これはググればOK。突っ込んで見るだけ。

■ おわりに…
こういうデータを持っておいて可視化しておくと、攻撃元IPのブラックリスト化、攻撃の傾向/トレンドの把握とかで、まぁちょろっとは使えるでしょう。まぁ、あとはpub/sub系のに流して、ブラウザで攻撃があったら情報がリアルタイムで見れるようにしておくとかね。これ系のは何となくそれなりっぽい規模の会社に1個くらい、可視化しれ見れるよーにしておくと、何となく後々幸せになれるような気がちょっぴりする。
あとtracerouteをかけて、経路のデータ/IPアドレスを取得してDBにまるごと突っ込んで簡単に使えるようにもしている。何となくDBにも入れておけば後々便利だし(esだけでも良いけどね)。