シャドーITの調査と利用サービスの管理
サービスの分類結果だけで承認済みと判断せず、主体と利用先を含めて調べます。
説明
CASBはクラウドサービスの利用を把握し、組織の規則に応じて可視化や制御を行います。サービス名が分かること、組織が承認した利用であること、適切なテナントへの操作であることは別の確認です。
固定のURL・通信量・端末情報を、ホスト名に基づくアプリ台帳と照合します。同じサービスの個人領域と、似た名前の別ホストも調べます。
サービスの分類結果だけで承認済みと判断せず、主体と利用先を含めて調べます。
1通信と承認台帳を読む
approvedは組織の承認状態を表す固定資料です。
from sp15 import *
from sp02 import show通信と承認台帳を読む
db=connect()
show(db,"SELECT * FROM app ORDER BY host")
show(db,"SELECT id,user,url,bytes,device FROM traffic ORDER BY t")FileShareは承認済み、Notesは未承認です。ただし台帳はホスト単位で、個々の利用領域までは表していません。
2URLからホストを正確に取り出す
文字列の部分一致ではなくURL解析を使います。
db.create_function('hostname',1,lambda u:urlsplitURLからホストを正確に取り出す(u).hostname)
show(db,"SELECT id,hostname(url) AS host FROM traffic ORDER BY t")r4のホストはfiles.example.test.other.example.testです。files.example.testを含むだけでは同じホストになりません。
3分類できない通信も残して結合する
LEFT JOINで未登録ホストを残します。
show(db,"SELECT t.id,a.name,a.approved FROM traffic t LEFT JOIN分類できない通信も残して結合する app a ON hostname(t.url)=a.host ORDER BY t.t")r3は未承認のNotes、r4は分類不明です。未登録を未承認と一つにまとめず、台帳の不足も点検します。
4同じサービス内の利用領域を確認する
パスの先頭部分を固定資料の領域名として取得します。
for ident,url in db.execute("SELECT id,url FROM traffic WHERE hostname(url)='files.example.test' ORDER BY t"):
print(ident,urlsplit同じサービス内の利用領域を確認する(url).path.split('/')[1])acmeとpersonalです。この試料では領域をパスで表していますが、実サービスではテナントIDや監査記録から所属を確認します。
5利用者別の量を集計する
バイト数は固定記録の送信量です。
show(db,"SELECT user,SUM利用者別の量を集計する(bytes) AS bytes FROM traffic GROUP BY user ORDER BY user")aliceは1020、bobは500です。量だけでは機密情報の持出しかどうかは分かりません。内容や宛先、業務との対応を追加します。
6管理外端末の利用を抽出する
端末属性とアプリ分類を一緒に読みます。
show管理外端末の利用を抽出する(db,"SELECT t.id,t.user,a.name,a.approved FROM traffic t LEFT JOIN app a ON hostname(t.url)=a.host WHERE device='unmanaged'")bobのNotes利用が該当します。利用を発見したことと、その経路を制御できていることは別です。
7承認の変更後に結果を再評価する
Notesを審査後に承認した場合の台帳変更です。
db.execute("UPDATE app SET approved=1 WHERE name='Notes'")
show承認の変更後に結果を再評価する(db,"SELECT t.id,a.name,a.approved,t.device FROM traffic t JOIN app a ON hostname(t.url)=a.host WHERE t.id='r3'")承認状態は1ですが端末はunmanagedのままです。台帳上の承認変更が端末管理や過去の配送結果を変えるわけではありません。
まとめ
URLはホストとして解析して照合します。
サービス承認と利用テナントを分けて確認します。
発見、評価、経路上の制御を分けます。
操作履歴と解説を振り返れます。
Python 3.15 / SQLite / 固定の主体・権限・操作記録
from sp15 import *
from sp02 import show
db=connect()
show(db,"SELECT * FROM app ORDER BY host")
show(db,"SELECT id,user,url,bytes,device FROM traffic ORDER BY t")host | name | approved files.example.test | FileShare | 1 notes.example.test | Notes | 0 id | user | url | bytes | device r1 | alice | https://files.example.test/acme/doc7 | 100 | managed r2 | alice | https://files.example.test/personal/doc8 | 900 | managed r3 | bob | https://notes.example.test/n1 | 500 | unmanaged r4 | alice | https://files.example.test.other.example.test/x | 20 | managed
db.create_function('hostname',1,lambda u:urlsplit(u).hostname)
show(db,"SELECT id,hostname(url) AS host FROM traffic ORDER BY t")id | host r1 | files.example.test r2 | files.example.test r3 | notes.example.test r4 | files.example.test.other.example.test
show(db,"SELECT t.id,a.name,a.approved FROM traffic t LEFT JOIN app a ON hostname(t.url)=a.host ORDER BY t.t")id | name | approved r1 | FileShare | 1 r2 | FileShare | 1 r3 | Notes | 0 r4 | NULL | NULL
for ident,url in db.execute("SELECT id,url FROM traffic WHERE hostname(url)='files.example.test' ORDER BY t"):
print(ident,urlsplit(url).path.split('/')[1])r1 acme r2 personal
show(db,"SELECT user,SUM(bytes) AS bytes FROM traffic GROUP BY user ORDER BY user")user | bytes alice | 1020 bob | 500
show(db,"SELECT t.id,t.user,a.name,a.approved FROM traffic t LEFT JOIN app a ON hostname(t.url)=a.host WHERE device='unmanaged'")id | user | name | approved r3 | bob | Notes | 0
db.execute("UPDATE app SET approved=1 WHERE name='Notes'")
show(db,"SELECT t.id,a.name,a.approved,t.device FROM traffic t JOIN app a ON hostname(t.url)=a.host WHERE t.id='r3'")id | name | approved | device r3 | Notes | 1 | unmanaged
演習完了