こんにちは。技術部の石垣です。
今回はスイッチ・FW等で通信制御を行うACL(Access Contorl List)を自動で生成しネットワーク環境をセキュアに且つプログラマブルに管理する方法について説明したいと思います。
想定読者
社内外のネットワーク管理者、セキュリティ担当者
背景と課題
一般的な企業システム・ネットワークではネットワーク通信を前提とした様々なシステム(ログ管理サーバー、認証サーバー、DBサーバー、アプリケーションサーバー、メールサーバー、プロキシサーバー、ネームサーバ、NTPサーバー等)が稼働しているとおもいます。
昨今仮想環境を利用してサーバーをカジュアルに構築できるようになり大変便利ですが、反面インスタンスが増えるに従い管理コストも増えることになります。
例えば部署ごとにシステムが別々に構築されて統一感(ガバナンスが効いていない)の無い混沌とした状態、テスト環境、開発環境向けに構築したインスタンス等が放置されているなど攻撃者にとって、情報の窃取、アカウントの取得、踏み台等に活用可能な状態であり攻撃を受けるリスクや被害の影響が広がります。
APTなどの攻撃は基本ネットワークを介しての攻撃であるため、ネットワークを適切に制御することによって攻撃に晒されるリスクが低減可能である!
と頭では理解できますが、どのようにして漏れなくネットワークを確実に制御するか、正確にACLを管理し運用管理するにはどうすればよいのか?等、インフラ担当者にとって悩しい課題であるかとおもいます。
例えば*nixサーバーへ個別にIptableを設定する場合、ホスト毎に設定、管理が別々となるため、統一的に通信ルールを適応するのが難しくメンテナンスも大変となります。またネットワーク機器にACLを適応しネットワーク全体を管理することも方法も考えられますが、複雑なネットワーク構成である場合、様々なメーカー機器(Cisco, Juniper..)がある場合、ネットワーク構成図を見ながら、異なるACLフォーマットを理解しマニュアルで設定することは、間違いも起きやすく現実的ではありません。
Capircaを使ってACLを自動生成
そこでオープンソースプロジェクトとして公開されているcapricaを利用して様々なプラットフォームに対応したACLを自動で生成することを試してみます。
前提条件
ネットワーク構成
- オフィスセグメント(社員の執務室ネットワーク): 192.168.1.0/24
- サーバーセグメント(社内システムのネットワーク):10.0.0.0/24
- ネットワークオペレーションセグメント(インフラチームのネットワーク):192.168.254.0/24
ACLポリシー
- サーバーセグメント内はTCP・UDPともに通信可能
- ネットワークオペレーションセグメントからサーバーセグメントへssh portへの接続が可能である。
- オフィスセグメントからサーバーセグメントへのssh portは通信不可とする。
- オフィスセグメントからサーバーセグメントへはhttps portの通信が可能とする。
- その他プライベートセグメントからの通信は破棄しログに記録する。
ACLの自動生成
今回上記条件でACLを生成する為に以下の設定ファイルを作成しました。
ディレクトリ構成
├── ACL
│ ├── README.md
│ ├── def
│ │ ├── CUSTOM.net
│ │ ├── NETWORK.net
│ │ └── SERVICES.svc
│ └── policies
│ ├── includes-extended
│ │ ├── int-intra-server-segment.inc
│ │ └── rfc1918-networks-blocking.inc
│ └── pol
│ └── sample.pol
上記でメインとなるのはCUSTOM.net、int-intra-server-segment.incおよびsample.polになります。
以下に各ファイルの説明を行います。
ネットワーク設定(CUSTOM.net)はACLで設定を行いたいネットワークセグメントやIP等にネットワーク名を割り当てるファイルです。ここでは上記ネットワーク構成を定義しています。
# Server
INTRA_SERVER = 10.0.0.0/24
# Operation
NOC_SEGMENT = 192.168.254.0/24
# Office Segment
INTRA_OFFICE = 192.168.1.0/24
INTRA = INTRA_SEGMENT
NOC_SEGMENT
INTRA_OFFICE
ACLポリシー設定(int-intra-server-segment.inc)はネットワーク設定に記載されているネットワーク名を組み合わせて、ネットワークの送信元、送信先、プロトコル種別、動作を定義します。また他のACLポリシー設定を参照することも可能なDSLとなっています。
今回の例ではcisco server extended
を利用しCISCO機器向けの設定を出力します。
header {
comment:: "'Firewall ACL for intra server segment ACL'"
target:: cisco server extended
}
term accept-same-segment {
comment:: "'Allow tcp/udp from INTRA_SERVER'"
source-address:: INTRA_SERVER
destination-address:: INTRA_SERVER
action:: accept
}
term accept-ssh-replies {
comment:: "'Allow ssh tcp replies to NOC_SEGMENT.'"
destination-address:: NOC_SEGMENT
source-address:: INTRA_SERVER
source-port:: SSH
protocol:: tcp
option:: tcp-established
action:: accept
}
term deny-ssh-request {
comment:: "'Deny ssh tcp replies to INTRA_OFFICE.'"
destination-address:: INTRA_OFFICE
source-port:: SSH
protocol:: tcp
action:: deny
}
term accept-tcp-replies {
comment:: "'Allow tcp replies to INTRA_OFFICE.'"
destination-address:: INTRA_OFFICE
source-address:: INTRA_SERVER
source-port:: HTTPS
protocol:: tcp
option:: tcp-established
action:: accept
}
#include './includes-extended/rfc1918-networks-blocking.inc'
ACLを生成する設定ファイル(sample.pol)のターゲットを変更することでJuniperであったりnetfilterなど様々なフォーマットを生成可能です。
#include 'includes-extended/int-intra-server-segment.inc'
上記設定等を含んだdockerイメージをgithubに公開しているのでgit cloneしACLを生成します。
https://github.com/CyberDefenseInstitute/docker-capirca
$make acl
Sending build context to Docker daemon 121.9kB
Step 1/6 : FROM python:2
2: Pulling from library/python
4176fe04cefe: Pull complete
851356ecf618: Pull complete
6115379c7b49: Pull complete
aaf7d781d601: Pull complete
40cf661a3cc4: Pull complete
c582f0b73e63: Pull complete
6c1ea8f72a0d: Pull complete
7051a41ae6b7: Pull complete
〜〜〜〜
略
〜〜〜〜
Step 6/6 : ENTRYPOINT ["python","-m"]
---> Running in 2f92416749f3
Removing intermediate container 2f92416749f3
---> 4d05c35d9723
Successfully built 4d05c35d9723
Successfully tagged cyberdefense.jp/docker-capirca:latest
I0228 09:35:04.882195 140325479311104 aclgen.py:486] finding policies...
W0228 09:35:04.883672 140325479311104 aclgen.py:417] --> ./policies/includes-extended
W0228 09:35:04.883840 140325479311104 aclgen.py:422] --> ./policies/includes-extended (0 pol files found)
I0228 09:35:05.004882 140325479311104 aclgen.py:437] no files changed, not writing to disk
I0228 09:35:05.005214 140325479311104 aclgen.py:517] done.
暫くしてACLフォルダの直下に、sample.acl というファイルが生成されます。 このファイルが今回自動で生成されたACL設定となります。
! $Id:$
! $Date:$
! $Revision:$
no ip access-list extended server
ip access-list extended server
remark $Id:$
remark 'Firewall ACL for intra server segment ACL'
remark accept-same-segment
remark 'Allow tcp/udp from INTRA_SERVER'
permit ip 10.0.0.0 0.0.0.255 10.0.0.0 0.0.0.255
remark accept-ssh-replies
remark 'Allow ssh tcp replies to NOC_SEGMENT.'
permit tcp 10.0.0.0 0.0.0.255 eq 22 192.168.254.0 0.0.0.255 established
remark deny-ssh-request
remark 'Deny ssh tcp replies to INTRA_OFFICE.'
deny tcp any eq 22 192.168.1.0 0.0.0.255
remark accept-tcp-replies
remark 'Allow tcp replies to INTRA_OFFICE.'
permit tcp 10.0.0.0 0.0.0.255 eq 443 192.168.1.0 0.0.0.255 established
remark discard-spoofs
deny ip any 10.0.0.0 0.255.255.255 log
deny ip any 172.16.0.0 0.15.255.255 log
deny ip any 192.168.0.0 0.0.255.255 log
exit
あとはFWやスイッチ等に上記設定を流し込み適応することで完了です。
上記のルールを複数組み合わせ、基幹系のスイッチやFWを管理するセグメント毎、VLAN毎に適応することで個別に、もしくは全体を管理することが可能となります。
弊社内では上記の方法で複雑なネットワーク構成のACL(数千行)をセグメント毎、VLAN毎に生成し実運用環境に適応しています。
ネットワーク変更の度に、各種ファイルを更新しレポジトリに記録しているので、変更管理記録も可能となっています。
最近はAnsibleのスイッチ向けのモジュール多数公開されているのでネットワーク機器へ設定を自動で流し込んだりできるのでネットワーク管理が捗ります。
ネットワーク通信を確実に制御する為には、まず通信ルール・ポリシーの確立を行い、ルール・ポリシーをDSLで記載するといった感じです。
システムに影響を与えないで運用管理するためには、既存のネットワーク環境はどうなっているかを把握し、通信ルール・ポリシー確立した上で、プログラマブルにACLを生成する等が必要作業となります。
またACLが本当に正しく生成されているか確認する方法として形式的手法や証明支援でACLをチェックする方法がいくつかあります。が実装するにはかなり難易度が高いのです。
この機会に一度ネットワークの設定状況を見直し、ノーガードなネットワークシステムの保護、ルールが多すぎて事実上管理不能なACL、何の為か分からない多数のACL、エクセルによるACL管理等の排除を強く推奨します。
それではHappy Networking!