ノート:
- このチュートリアルでは、Oracle Cloudへのアクセスが必要です。無料アカウントにサインアップするには、Oracle Cloud Infrastructure Free Tierの開始を参照してください。
- Oracle Cloud Infrastructureの資格証明、テナンシおよびコンパートメントの値の例を使用します。演習を完了するときに、これらの値をクラウド環境に固有の値に置き換えます。
Oracle Cloud Infrastructure Functionsを使用した電子メールによるOracle Cloud Guardの問題の送信
イントロダクション
今日、さまざまな業界のサイバーセキュリティ・チームは、クラウド環境の動的な性質に対処しながら、堅実なセキュリティ体制を維持するという複雑な課題に直面しています。数え切れないほどのリソース、構成、脅威の進化により、問題を迅速に追跡し対処することが重要です。Oracleでは、組織がセキュリティ管理を合理化し、これらの課題に真正面から取り組めるよう支援するツールを導入することの重要性を認識しています。Oracle Cloud Guardは、企業がクラウド・セキュリティ管理を簡素化するための堅牢な機能を提供し、単に脆弱性を特定することから、問題をチーム全体に自動的に配布してタイムリーに解決できるようにします。
このチュートリアルでは、セキュリティ・チームが詳細なOracle Cloud Guardセキュリティ・レポートを電子メールで直接受信および共有できるようにする、OCIのネイティブ・サービスを活用した自動ソリューションの概要を説明します。このアプローチにより、手作業が軽減され、継続的な監視が容易になり、クラウド・セキュリティに対する積極的な姿勢が保証されます。
目標
- Oracle Cloud Guardの未解決の問題をすべて電子メールで受け取り、適切なチームに配布して、解決への道を合理化できます。
前提条件
-
Oracle Cloud Infrastructure (OCI)テナンシへのアクセス。
-
Oracle Cloud Guard、OCI Functions、OCI Email Deliveryサービス、OCI VaultおよびOCI Resource Schedulerを管理する権限。
タスク1: 必要なポリシーおよびOracle Cloud Infrastructure Identity and Access Management (OCI IAM)権限の設定
このソリューションの各コンポーネントは、相互作用するOCIリソースにアクセスできる必要があります。
-
リソース・スケジューラ・ポリシー:スケジューラに、定義されたスケジュールでファンクションの実行を許可します。詳細は、ポリシーの例を参照してください。
-
ファンクション・ポリシー: OCI Vaultからシークレットを読み取り、Oracle Cloud Guardの問題を取得するファンクション権限を付与します。詳細については、Details for Functionsを参照してください。
タスク2: OCI Email Deliveryサービスの構成
-
レポートの送信に使用される承認済送信者電子メール・アドレスを作成して、OCI Email Deliveryサービスを設定します。詳細は、承認済送信者の作成を参照してください。
-
SMTPアクセス権限が制限された専用ユーザーを作成して、電子メール・アカウントのSimple Mail Transfer Protocol (SMTP)資格証明を生成します。
-
OCI IAMユーザーを作成すること。詳細は、ユーザーの作成を参照してください。
-
ユーザー機能を編集するには、「ユーザーの機能の編集」を参照してください。
-
SMTP資格証明を作成するには、SMTP資格証明の作成を参照してください。
-
タスク3: OCI VaultへのSMTP資格証明の格納
OCI Vaultを使用して、SMTP資格証明を安全に格納します。これにより、機密情報を機能外に保持することで、セキュリティを強化できます。
-
OCI Vaultを設定します。詳細は、Vaultの作成を参照してください。
-
マスター暗号化キーを作成するには、マスター暗号化キーの作成を参照してください。
-
シークレットを作成するには、Vaultでのシークレットの作成を参照してください。
タスク4: ファンクションの開発およびデプロイ
この関数は、過去1年に検出された未解決のセキュリティ姿勢の問題をフェッチします。リスク・レベルや検出時間などのパラメータに基づいてデータを構造化レポートにフォーマットし、電子メールでカンマ区切り値(CSV)添付として送信します。詳細は、「ファンクションのデプロイ」を参照してください。
次に、主な機能ステップの概要を示します。
- Oracle Cloud Guardから未解決の問題を取得します。
- 重大度に基づいて問題を編成し、書式設定します。
- CSVレポートを生成し、レポートを書式設定します。
- ボールトからSMTP資格証明を取得します。
- 添付ファイルとしてCSVを指定した受信者にEメールを送信します。
OCIのサーバーレス機能を使用すると、このレポートをカスタマイズして、サイバーセキュリティ・チームの重要なセキュリティ領域を最大限に明確化できます。
-
func.py
:import oci import io import smtplib import logging import base64 from oci.pagination import list_call_get_all_results from email.mime.multipart import MIMEMultipart from email.mime.base import MIMEBase from email import encoders from email.mime.text import MIMEText from openpyxl import Workbook from datetime import datetime, timedelta, timezone from openpyxl.styles import Font # Retrieve secrets from OCI Vault def get_secret_value(secret_ocid): print(f"Retrieving secret for OCID: {secret_ocid}") signer = oci.auth.signers.get_resource_principals_signer() secrets_client = oci.secrets.SecretsClient({}, signer=signer) try: secret_content = secrets_client.get_secret_bundle(secret_ocid) secret_data = secret_content.data.secret_bundle_content.content secret_value = base64.b64decode(secret_data).decode('utf-8') return secret_value except Exception as e: print(f"Failed to retrieve secret: {e}") raise # Format the CSV def get_font_style(risk_level, time_condition): color_map = { "CRITICAL": "8B0000", "HIGH": "FF8C00", "MEDIUM": "006400", "LOW": "00008B", "MINOR": "000000" } font_color = color_map.get(risk_level, "000000") is_bold = time_condition return Font(color=font_color, bold=is_bold) def get_clients_with_resource_principal(): signer = oci.auth.signers.get_resource_principals_signer() cloud_guard_client = oci.cloud_guard.CloudGuardClient({}, signer=signer) return cloud_guard_client def send_email_via_oci(subject, body, email, attachment, username_secret_ocid, password_secret_ocid, from_email, smtp_endpoint, smtp_port): msg = MIMEMultipart() msg['Subject'] = subject msg['From'] = from_email msg['To'] = email msg.attach(MIMEText(body, 'plain')) today_date = datetime.today().strftime('%Y-%m-%d') filename = f"CloudGuardReport_{today_date}.xlsx" part = MIMEBase('application', "octet-stream") part.set_payload(attachment) encoders.encode_base64(part) part.add_header('Content-Disposition', f"attachment; filename={filename}") msg.attach(part) try: username = get_secret_value(username_secret_ocid) password = get_secret_value(password_secret_ocid) server = smtplib.SMTP(smtp_endpoint, smtp_port) server.starttls() server.login(username, password) server.sendmail(msg['From'], [msg['To']], msg.as_string()) server.quit() print("Email sent successfully.") except Exception as e: print(f"Failed to send email: {e}") raise def handler(ctx, data: io.BytesIO=None): try: cfg = ctx.Config() compartment_id = cfg["compartment-id"] from_email = cfg["from-email"] email = cfg["to-email"] smtp_endpoint = cfg["smtp-endpoint"] smtp_port = cfg["smtp-port"] username_secret_ocid = cfg["smtp-username-secret-ocid"] password_secret_ocid = cfg["smtp-password-secret-ocid"] cg_access_level = cfg["cloudguard-access-level"] cloud_guard_client = get_clients_with_resource_principal() current_time = datetime.now(timezone.utc) time_last_7_days = current_time - timedelta(days=7) formatted_time_one_year_ago = (current_time - timedelta(days=365)).strftime("%Y-%m-%dT%H:%M:%S.%fZ") formatted_time_last_7_days = time_last_7_days.strftime("%Y-%m-%dT%H:%M:%S.%fZ") # List problems problem_response = list_call_get_all_results( cloud_guard_client.list_problems, compartment_id, compartment_id_in_subtree=True, access_level=cg_access_level, time_first_detected_greater_than_or_equal_to=formatted_time_one_year_ago, time_last_detected_greater_than_or_equal_to=formatted_time_last_7_days ).data if not problem_response: logging.info("No open problems found.") return {"statusCode": 200, "body": "No open problems found."} print(f"Found {len(problem_response)} problems") # Sort problems by Risk Level risk_level_order = {"CRITICAL": 1, "HIGH": 2, "MEDIUM": 3, "LOW": 4, "MINOR": 5} problem_response.sort(key=lambda x: risk_level_order.get(x.risk_level, 6)) # Create a workbook and select active worksheet wb = Workbook() ws = wb.active ws.title = "Cloud Guard Problems" ws.append([ "Region", "ID", "Resource Type", "Resource Name", "Risk Level", "Detector", "Rule Display Name", "Rule Description", "Rule Recommendation", "Resource ID", "Time First Detected", "Time Last Detected" ]) # Iterate through the problems for problem in problem_response: try: detector_rule_response = cloud_guard_client.get_detector_rule(problem.detector_id, problem.detector_rule_id).data rule_description = detector_rule_response.description detector = detector_rule_response.detector rule_display_name = detector_rule_response.display_name rule_recommendation = detector_rule_response.recommendation except Exception as e: logging.error(f"Error fetching detector rule details for problem {problem.id}: {str(e)}") rule_description, detector, rule_display_name, rule_recommendation = "N/A", "N/A", "N/A", "N/A" problem_details = [ problem.region, problem.id, problem.resource_type, problem.resource_name, problem.risk_level, detector, rule_display_name, rule_description, rule_recommendation, problem.resource_id, problem.time_first_detected.replace(tzinfo=None) if problem.time_first_detected else None, problem.time_last_detected.replace(tzinfo=None) if problem.time_last_detected else None ] # Add row to worksheet ws.append(problem_details) # Apply format time_condition = problem.time_last_detected > problem.time_first_detected if problem.time_last_detected and problem.time_first_detected else False font_style = get_font_style(problem.risk_level, time_condition) row_number = ws.max_row for cell in ws[row_number]: cell.font = font_style virtual_workbook = io.BytesIO() wb.save(virtual_workbook) virtual_workbook.seek(0) # Send email send_email_via_oci("OCI Cloud Guard Report", "Find attached the OCI Cloud Guard Report.", email, virtual_workbook.getvalue(), username_secret_ocid, password_secret_ocid, from_email, smtp_endpoint, smtp_port) return {"statusCode": 200, "body": "Email sent successfully."} except Exception as e: logging.error(f"Error: {str(e)}") return {"statusCode": 500, "body": f"Error: {str(e)}"}
-
func.yaml
:schema_version: 20180708 name: oci-cloud-guard-problems version: 0.0.1 runtime: python build_image: fnproject/python:3.9-dev run_image: fnproject/python:3.9 entrypoint: /python/bin/fdk /function/func.py handler memory: 256 config: compartment-id: Provide a compartment ID here to-email: Provide a valid email ID here from-email: Provide the Approved Sender Email ID created in the Email Delivery Service smtp-username-secret-ocid: Provide the SMTP Username Secret OCID smtp-password-secret-ocid: Provide the SMTP Password Secret OCID smtp-endpoint: Provide the SMTP endpoint from the Email Delivery Service smtp-port: 587 cloudguard-access-level: ACCESSIBLE or RESTRICTED
-
requirements.txt
:fdk oci openpyxl
タスク5: OCIリソース・スケジューラを使用したファンクションのスケジュール
最後のタスクは、OCIリソース・スケジューラを使用してファンクションの実行を自動化することです。この構成は毎週またはカスタマイズされた間隔で実行できるため、タイムリーで一貫性のあるセキュリティ・レポートを作成できます。詳細は、スケジュールの作成を参照してください。
-
関数を実行するには、次の必須情報を入力します。
ファンクションをデプロイする前に、次の構成の詳細を収集します。これらの入力は、デプロイメント方法に応じて、ファンクション構成ファイル(
func.yaml
)またはOCIコンソールで直接提供されます。- コンパートメントID:これは、Oracle Cloud Guardが有効になっているテナンシIDです。
- 差出人Eメール: OCI Email Deliveryサービスで作成した承認済送信者Eメール。
- 宛先Eメール:レポートが送信されるEメール・アドレス。
- SMTPエンドポイント:これを見つけるには、「電子メール配信」および「構成」に移動します。
- SMTPポート:通常、OCI Email Deliveryサービス構成で指定されている587または25。
- SMTPユーザー名シークレットOCID: OCI Vaultにセキュアに格納されているSMTPユーザー名のOCID。
- SMTPパスワード・シークレットOCID: OCI Vaultに安全に格納されるSMTPパスワードのOCID。
- クラウド・ガード・アクセス・レベル:リソースのアクセス・レベルを定義します(
ACCESSIBLE
またはRESTRICTED
)。デフォルトはACCESSIBLE
です。
-
実用的なOracle Cloud Guardレポートであるサンプル出力を取得します。
このOracle Cloud Guardレポートは、リスク・レベル別に分類された、OCI環境における未解決のセキュリティ問題の構造化された概要を提供します。リージョン、リソース・タイプ、重大度、検出タイムスタンプなどの重要な詳細により、サイバーセキュリティ・チームはアクションを評価し、優先順位を付けることができます。
次のステップ
Oracle Cloud Guardの自動レポート作成は、サイバーセキュリティ・チームがクラウド・セキュリティ・リスクを管理するための合理化されたプロアクティブなアプローチを提供します。組織は、重大度およびリスク・レベルで分類された1回かぎりの構成で、未解決のセキュリティ問題に関する週次レポートを受信できます。このソリューションは、クラウド・セキュリティ管理の複雑な手動タスクに対処するため、チームは問題を追跡するのではなく、タイムリーな問題解決に集中できます。Oracle Cloud GuardとそのCNAPP機能の使用方法の詳細は、Oracle担当者に連絡するか、クラウド・セキュリティ・サービスを参照してください。
承認
- 作成者 - Aneel Kanuri (Distinguished Cloud Architect)
その他の学習リソース
docs.oracle.com/learnの他のラボを確認するか、Oracle Learning YouTubeチャネルで無料のラーニング・コンテンツにアクセスしてください。また、education.oracle.com/learning-explorerにアクセスしてOracle Learning Explorerになります。
製品ドキュメントは、Oracle Help Centerを参照してください。
Send Oracle Cloud Guard Problems through Email using Oracle Cloud Infrastructure Functions
G23233-01
December 2024