ACLをどうにかしたい話
ちょっとやっては飽きたり挫折したり面倒くさくなって放り投げたりしていた企画を今月になってまたやっていました。
- Perl で Cisco ACL Parser を作れないかな?
- Road to Cisco ACL Parser
- Road to Cisco ACL Parser(2)
- Road to Cisco ACL Parser(3)
……あらためて並べてみると古いねえ。年単位で放置してるし。それをなんでここに来てまたやり始めたかというと、Trema 関係で Ruby でいろいろ書くようになって、Perl で面倒だなあと思っていたところって実は Ruby でやるとわりと障壁下がるんじゃないかなあ…と思ったからでした。あと ACL 何とかしたい(某お仕事的に)というのは変わらないので。やってないから解決したかってそんなことなくて、数年延命しながら崖っぷちにちょっとずつ近づいているだけなのだ。…というACLどうにかしたい話は別なところでまとめたい。とりあえずツールについて今回は書く。
Perl で作ってたとき は基本的な ACL の syntax まではできてたのでコレは流用したらいいよねー。というところで、Racc への移植とアクションを作るって事をやってみたのでした。
とりあえず使ってみる
今のところの機能
ここに置いてある
今のところこの辺の機能が実装できています。
名前付き拡張ACLとかで 2×2になるので、主要な4種類の ACL を parse することができます。というより目論見は parse することと言うよりは、読んだ上でアレコレ処理させることなので、ACL Interpreter (ACL Intp) という名前にしてみました。
インストール
bundler で生成しているけど rubygems への登録とかはしてません。というのもまだ大幅に内容を書き換える可能性があると思っているので。そもそもですね。テストとかまだちゃんと網羅的にかけてないのですよ。そこそこ動くよな…というところまでは見えているけど。入れるのはそんなに面倒じゃないはず。git clone
して bundle install
してください。
Syntax Checker として
とりあえず動かしてみましょうかね。tool/check-acl.rb
は ACL Intp の応用として書いてみたツールです。複数のACLを読み込んで解釈し、同じ物を出力するだけです…ってだけだとあまり実用性がないので、エラーがあればそれを教えてくれます。手書きで書いたACLが正しいかどうかチェックするような使い方を想定した物ですね。term-ansicolor を使って、要素別にカラーリングをしています。
stereocat@vnwt10ctrl-of13:~/cisco_acl_intp$ ruby tool/check-acl.rb -h ruby tool/check-acl.rb [options] [args] -c, --color enable coloring -d, --debug enable debug print --yydebug enable yydebug -f, --file FILE acl file stereocat@vnwt10ctrl-of13:~/cisco_acl_intp$
samples
ディレクトリにいくつかACLのサンプルがあります。それを読ませてみましょう。-f
オプションでファイルをわたしてもいいし、ファイルオプションがなければ標準入力から読むようになっています。
stereocat@vnwt10ctrl-of13:~/cisco_acl_intp$ cat samples/err-acl.txt access-list 1 permit 192.168.0.0 0.0.255.255 access-list 1 deny any log access-list 100 remark General Internet Access access-list 100 permit icmp any any access-list 100 permit ip 192.168.0.0 0.0.255.255 any access-list 100 permit tcp any host 210.197.74.200 access-list 100 remark !wrong acl number! access-list 10 permit udp any eq ntp any eq ntp access-list 100 remark !------cleared------! access-list 100 remark !wrong header! caccess-list caccess-list 100 remark 6to4 access-list 100 remark !------cleared------! access-list 100 permit 41 any host 192.88.99.1 access-list 100 remark !wrong ip proto number! access-list 100 permit 256 any host 192.88.99.1 access-list 100 remark !------cleared------! access-list 100 remark !wrong ip proto! access-list 100 permit hoge any host 192.88.99.1 access-list 100 remark !------cleared------! access-list 100 permit ip any host 192.88.99.1 access-list 100 remark others access-list 100 permit tcp any eq 0 any eq 0 access-list 100 permit udp any eq 0 any eq 0 access-list 100 deny ip any any log access-list 110 remark SPLIT_VPN access-list 110 permit ip 192.168.0.0 0.0.255.255 any ip access-list extended FA8-OUT deny udp any any eq bootpc deny udp any any eq bootps remark !argment error! 65536 permit tcp host 192.168.3.4 173.30.240.0 0.0.0.255 range 32768 65536 remark !------cleared------! remark !argment error! 255 => 256 deny udp 192.168.3.0 0.0.240.256 lt 1024 any eq 80 remark !------cleared------! remark network access-list remark!! permit tcp any any established deny tcp any any syn rst remark !syntax error! tcp -> tp (typo) deny up any any log-input hoge remark !------cleared------! permit ip any any log ! ip access-list standard remote-ipv4 permit 192.168.0.0 0.0.255.255 remark standard access-list last deny!? deny any log ! stereocat@vnwt10ctrl-of13:~/cisco_acl_intp$
実行してみるとこんな感じ。
いま、Parser 上のエラー処理(エラーリカバリ)は行単位なので、
- エラーがあればその行は捨てる
- 1行に複数のエラーがある場合は、エラー判定できるのは最初に見つかった物だけ
です。ということで、元ファイルのエラー行が消えて、前後の remark
行だけが出てくれてれば正解、ということ。見つかったエラーは上の方にわらわらっと出てます。
機能と制限
もともとやりたいことってなんだって、別に ACL syntax check だけじゃないわけですね。ACL を読んで object 化された上で各種処理を加えられるようになりたい。コード観てもらえればわかりますが、読み込み終わった時点で ACL class object が帰ってくるようになってるので、後はそのオブジェクトに対して検索処理とかいろいろ実装したいわけです。まあそれも今後のネタということで。
で、そういった構造上の都合なども含めてまだいくつか機能制約があったりします。
- Named ACL のヘッダ部分(1行目の
ip access-list
の行でのエラー処理
そもそもまだ実装していない機能
- syntax としては object-group とかかなりマニアックな機能についても実装してありますが、その辺はやってません。というか自分が普段使っている(使ったことがある)物だけ今は実装しています。このあたりは時間があれば拡張していく…かな……
eq 80 443 8000 8080
みたいに eq/neq が複数(10個まで)のポート番号リストを取るみたいな機能も新しい IOS だとあるみたいだけど、これはまだ syntax そのものの実装ができていません。…こういう機能っていつついたんだろう? 手元でチェックするように使っていたのが IOS 12.2(52) くらいなので、基準はこの辺です。- ACL の feature の全貌がよくわからん…。全 feature に対してどのくらい実装してるかみたいなの調べたいんですが、まあ面倒でね…
- IPv6 ACL には対応していません。
- PIX/ASA 系の ACL には対応していません。
まとめ
なんかとりとめのない話ですが。まあ最近こういうのを作ってて、それっぽく動くところまでできたので軽く紹介だけしてみようかなあってだけです。テストもうちょっと真面目に作らないと…と思いつつ、コレを使った応用ってところで今ちょっと考えているのでいったんコレの実装はペンディング。まあまたどっかで手をつけるでしょう。