RDSでMySQLを作ってみる
RDSというものを知りました。
パソコンから直接使えるRDSを作成します。
VPC内のEC2インスタンスではなく、VPC外部からインターネットを経由して接続できるようにします。
一番簡単そうな以下の方法にチャレンジします(今回はお勉強用なので選びましたがお仕事用にはセキュリティが緩いです)。
Publicly Accessible オプションを有効化して接続する
RDSをパブリックサブネットに配置し、Publicly Accessibleを有効にする方法です。 パブリックサブネットとは、インターネットゲートウェイへのルーティングが可能なサブネットです。 Publicly Accessibleを有効にすると、RDSのエンドポイントがパブリックIPアドレスに解決されます。 セキュリティグループでクライアントの拠点のIPアドレスだけ許可すれば、拠点からのみ接続できます。本番データを扱う場合などは、SSLを利用した暗号化を検討します。
手元の作業端末からAmazon RDSに接続する方法 | DevelopersIO
RDSでMySQLを作成してみます。
- AWS マネジメントコンソールで[RDS]を選択して、RDSの画面を表示します。
- [データベースの作成]ボタンで[データベースの作成]画面を表示します。
- 以下を設定して[データベースの作成]ボタン
- データベース作成方法を選択 : 標準作成
- エンジンのオプション
- テンプレート : 無料利用枠(お勉強用なので小さいサイズにしました)
- 設定
- 接続
- パブリックアクセス : あり
- この設定によりVPC外部から接続できるようになります。設定は自己責任でしてください。
- パブリックアクセス : あり
- データベース認証 : パスワードと IAM データベース認証
- 「パスワードと IAM データベース認証」を設定するとコマンドラインでIAM 認証を使用してDB インスタンスに接続できるようになります。
- 参考 : コマンドラインから IAM 認証を使用して、DB インスタンスに接続する: AWS CLI および mysql クライアント - Amazon Relational Database Service
- 追加設定
- 最初のデータベース名 : myDatabase(好きな名前でOK、指定なしにして作成しなくてもOK)
- ログのエクスポート : 全てにチェックON
- 削除保護の有効化 : ON
- 上記以外の設定値は規定値のまま
- 画面上部に表示される[認証情報の詳細を表示]ボタンでパスワードを確認してどっかに記録しておきます。
セキュリティグループに自分のパブリックIPアドレスを設定します。
- アクセス情報【使用中のIPアドレス確認】で自分のパブリックIPアドレスを確認します。
- データベースの一覧にある作成したRDSのDB識別子リンクで詳細画面を表示します。
- [接続とセキュリティ]にある[VPC セキュリティグループ]のリンクでセキュリティグループの画面を表示します。
- [インバウンド]タブの[編集]ボタンでダイアログを表示します。
- [ルールの追加]ボタンで行を追加して以下を設定します。
- [保存]ボタンで保存してダイアログを閉じます。
RDSへmysqlコマンドで接続してみます。
(停止していたら)RDSを起動します。
- データベースの一覧で作成したRDSを選択します。
- [アクション] > [開始]で起動します(少々時間がかかります)。
- 一覧の[ステータス]が「利用可能」になったら起動しています。
エンドポイントを確認します。
- データベース一覧から作成したDB 識別子のリンクから詳細画面を開きます。
- [接続とセキュリティ]タブ > [エンドポイント]に表示されている「{DB識別子}.xxxxx.{リージョン}.rds.amazonaws.com」がエンドポイントで接続情報となります。
MySQLにログインします。
mysqlのオプション | 意味 |
---|---|
-h | MySQL サーバーに接続するホスト |
-P | 接続に使用する TCP/IP ポート番号 |
-p | サーバーに接続する際に使用するパスワードを聞く |
-u | サーバーへの接続時に使用する MySQL ユーザー名 |
$ mysql -h mysql-80.xxx.{リージョン}.rds.amazonaws.com -P 3306 -u admin -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 21 Server version: 8.0.28 Source distribution Copyright (c) 2000, 2022, Oracle and/or its affiliates. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | myDatabase | | mysql | | performance_schema | | sys | +--------------------+ 5 rows in set (0.20 sec) mysql>
うまく接続できない場合は、RDSの[パブリックアクセシビリティ]またはセキュリティグループの設定が誤っています。
参考 : ERROR 2003 (HY000): Can't connect to MySQL server on - Qiita
自動停止するようにLambdaを設定します。
RDSは、停止していても7日で自動起動します。
そのまま使わずに放置しているとお金がかかります。
なので自動停止するようにします。
自動停止時間をAutoStopタグに設定します。
- データベース一覧から作成したDB 識別子のリンクから詳細画面を開きます。
- [タグ]タブ > [追加]ボタンで[タグの追加] ウィンドウを表示します。
- [タグキー]に「AutoStop」と[値]に「自動停止したい時間」を入力して[追加]ボタンでタグを追加します。
AWSのEC2インスタンスを祝日を除いた平日に自動起動するLambdaを作る記録
- EC2インスタンスを決まった時間に自動起動したいです。
- S3にバケットを作ります。
- 取得実リストを取得するLambda関数を作成します。
- EC2インスタンスを自動起動するLambda関数を作成します。
- 失敗したこと
EC2インスタンスを決まった時間に自動起動したいです。
起動しっぱなしでいいインスタンスですが、たまにうっかり誰かが停止しちゃったりします。
なので、始業時間になって停止していたら自動で起動してほしいです。
AutoStartタグに設定した時間になったら起動したいです。
起動したい時間は、時と共に変わるかもしれませんし、インスタンスによっても変わります。
なので、インスタンスに「AutoStart」というタグとその値に起動したい時間を設定します。
祝日は自動起動しないでほしいです。
平日(月~金曜日)にLambdaの実行を設定しても、祝日は意識してもらえません。
祝日は、使わないので節約のためにも起動しなくていいんです。
先人の知恵をパクッて使います。
S3にバケットを作ります。
祝日判定をするために使用するGoogleカレンダーの祝日リストを入れるためのバケットです。
祝日判定を行うにあたって、祝日のリストが必要になります。
今回はGoogleカレンダーで取得できる祝日リストを利用したいと思います。
下記URLから自由にダウンロードでき、現在から前後1年間を含む3年間分の祝日データが取得可能となっております。
https://www.google.com/calendar/ical/ja.japanese%23holiday%40group.v.calendar.google.com/public/basic.ics
Lambdaで祝日判定 | AWSやシステム・アプリ開発の最新情報|クロスパワーブログ
取得実リストを取得するLambda関数を作成します。
- AWSのコンソールにある[Lambda] > [関数の作成]ボタンで画面を開きます。
- 必要な項目を入力後に[関数の作成]ボタンで関数を作成します。
- オプション : [一から作成]
- 関数名 : get_google_holiday_list(任意の関数名でOK)
- ランタイム : Python3.8
- 実行ロール : 既存のロールを使用する
- 既存のロール : [lambda_basic_execution]を選択します。
- [関数の作成]ボタンで関数を作成します。
Lambda関数を実行するトリガーを作成します。
- [Designer]にある[トリガーを追加]ボタンでトリガーの設定画面を開きます。
- プルダウンから[CloudWatch Events]を選択します。
- 各入力欄を記載します。
- ルール : [新規ルールの作成]
- ルール名(必須) : get_google_holiday_list(任意の関数名でOK)
- ルールタイプ : [スケジュール式]
- スケジュール式 : cron(0 8 1 * ? *)(毎月1日の午前 8:00)
- [追加]ボタンでトリガーを追加する
関数を実装します。
import boto3 import urllib.request import re import os s3 = boto3.resource('s3') # Googleカレンダーの祝日リストを入れるためのバケット bucket = s3.Bucket('google-holiday-list') def write_holiday_list(list, file): for num in range(len(list)): pattern = r"DTSTART;VALUE=DATE:" # DTSTART;VALUE=DATE:yyyyMMddの行の正規表現 repattern = re.compile(pattern) target_line = list[num-1].decode('utf-8') match = repattern.search(target_line) if match is None: pass else: print('出力対象行:' + target_line) # 出力対象行(\r\n含む)の後ろから10文字目から8文字を出力する file.write(target_line[-10:-2] + '\n') return 0 def lambda_handler(event, context): # 祝日リストの取得元URL url = 'https://www.google.com/calendar/ical/ja.japanese%23holiday%40group.v.calendar.google.com/public/basic.ics' try: response = urllib.request.urlopen(url) list = response.readlines() except Exception as e: print('祝日リストの取得に失敗しました。') return 1 # 書き込みでファイルを開く f = open('/tmp/holiday.txt','w') write_holiday_list(list, f) f.close() data = open('/tmp/holiday.txt', 'rb') result = bucket.put_object(Key='holiday.txt', Body=data) data.close() os.remove('/tmp/holiday.txt')
使った関数の情報
- open : [Python入門]ファイル操作の基本 (1/3):Python入門 - @IT
- re : re --- 正規表現操作 — Python 3.8.2rc1 ドキュメント
- os : 【これでバッチリ!】Pythonのosモジュール使い方まとめ | 侍エンジニア塾ブログ(Samurai Blog) - プログラミング入門者向けサイト
- put_object() : S3 — Boto 3 Docs 1.12.0 documentation
- urllib.request : urllib.request --- URL を開くための拡張可能なライブラリ — Python 3.8.2rc1 ドキュメント
- スライスを使ってリストの指定した範囲の要素が含まれる新しいリストを取得する | Python入門
EC2インスタンスを自動起動するLambda関数を作成します。
- AWSのコンソールにある[Lambda] > [関数の作成]ボタンで画面を開きます。
- 必要な項目を入力後に[関数の作成]ボタンで関数を作成します。
- オプション : [一から作成]
- 関数名 : start_instances_by_tag_value(任意の関数名でOK)
- ランタイム : Python3.8
- 実行ロール : 既存のロールを使用する
- 既存のロール : [lambda_basic_execution]を選択します。
- [関数の作成]ボタンで関数を作成します。
Lambda関数を実行するトリガーを作成します。
- [Designer]にある[トリガーを追加]ボタンでトリガーの設定画面を開きます。
- プルダウンから[CloudWatch Events]を選択します。
- 各入力欄を記載します。
- ルール : [新規ルールの作成]
- ルール名(必須) : start_instances_by_tag_value(任意の関数名でOK)
- ルールタイプ : [スケジュール式]
- スケジュール式 : cron(0/10 8-11 ? * MON-FRI *) (平日AM8:00-11:00で10分毎)
- [追加]ボタンでトリガーを追加する
関数を実装します。
# -*- coding: utf-8 -*- from __future__ import print_function import sys import json from datetime import datetime, timedelta, timezone, date import boto3 import os DATETIME_FORMAT = '%Y-%m-%dT%H:%M:%SZ' JST = timezone(timedelta(hours=+9)) REGION_NAME = 'ap-northeast-1' TAG_NAME = 'AutoStart' TMP_HOLIDAY_FILE = '/tmp/holiday.txt' # CALENDAR_URL = "https://calendar.google.com/calendar/ical/ja.japanese%23holiday%40group.v.calendar.google.com/public/basic.ics" # NTP_URL = "http://ntp-b1.nict.go.jp/cgi-bin/json" print("Loading function") s3 = boto3.resource('s3') ec2 = boto3.client('ec2', REGION_NAME) def get_holiday_list(): """ S3バケットから祝日リストを取得する """ # Googleカレンダーの祝日リストを入れてあるバケット bucket = s3.Bucket('google-holiday-list') holiday_obj = bucket.Object('holiday.txt') with open(TMP_HOLIDAY_FILE, 'wb') as data: holiday_obj.download_fileobj(data) f = open(TMP_HOLIDAY_FILE) holiday_list = f.readlines() f.close() os.remove(TMP_HOLIDAY_FILE) return holiday_list def is_holiday(): """ 土日祝日判定処理 """ is_holiday = False day = date.today() today = day.strftime('%Y%m%d') week = day.weekday() holiday_list = get_holiday_list() check = today + '\n' in holiday_list if check == True: print('今日は祝日です。') is_holiday = True elif week == 5 or week == 6: print('今日は週末です。') is_holiday = True elif check == False: print('今日は平日です。') else: print('土日祝日判定に失敗しました') return is_holiday def get_tag(instance): """ TAG_NAMEのタグを配列で取得する. """ tag_list = instance['Tags'] tag = next(iter(filter(lambda tag: tag['Key'] == TAG_NAME and (tag['Value'] is not None and tag['Value'] != ''), tag_list)), None) return tag def get_tag_value_time(tag): """ タグに設定された時間を取得する. """ val = tag["Value"] if val == '': print('タグに時間が指定されていません。' + tag) return '' time = val.split(':') now = datetime.now(JST) tag_time = datetime(now.year, now.month, now.day, int(time[0]), int(time[1]), 0, 0, JST) return tag_time def is_start_instance(event, tag_time): utc_event_time = datetime.strptime(event["time"], DATETIME_FORMAT) print('実行時間(UTC)は、' + utc_event_time.strftime(DATETIME_FORMAT)) jst_event_time = utc_event_time.astimezone(JST) print('実行時間(JST)は、' + jst_event_time.strftime(DATETIME_FORMAT)) # AutoStopタグに指定された時刻の前後5分以内であればインスタンス起動する start_time_from = tag_time + timedelta(minutes=-5) start_time_to = tag_time + timedelta(minutes=5) print('実行時間(' + jst_event_time.strftime(DATETIME_FORMAT) + ')が、' + \ start_time_from.strftime(DATETIME_FORMAT) + 'から' + start_time_to.strftime(DATETIME_FORMAT) + 'だったら起動します。') return (start_time_from <= jst_event_time) and (jst_event_time <= start_time_to) def start_instance(event, instance): """ インスタンス起動処理 """ auto_start_tag = get_tag(instance) tag_time = get_tag_value_time(auto_start_tag) if tag_time == '': return print(instance['InstanceId'] + 'のタグに指定された時間(JST)は、' + tag_time.strftime(DATETIME_FORMAT)) if is_start_instance(event, tag_time): ec2.start_instances(InstanceIds=[instance['InstanceId']]) print(instance['InstanceId'] + 'を起動しました。') def lambda_handler(event, context): print("Received event: " + json.dumps(event, indent=2)) if is_holiday(): # 土日祝日なら処理終了 print('土日祝日は起動しません。') return # (停止している)かつ([AutoStart]タグのついている)インスタンス情報を取得する instances = ec2.describe_instances( Filters=[ {'Name': 'instance-state-name', 'Values': ['stopped']}, {'Name': 'tag-key', 'Values': [TAG_NAME]} ] )['Reservations'][0]['Instances'] if len(instances) > 0: # インスタンスを順番に処理していく for instance in instances: start_instance(event, instance)
使った関数の情報
- describe_instances : インスタンスの情報を辞書形式で取得する。
- download_fileobj() : Downloading Files — Boto 3 Docs 1.12.1 documentation
失敗したこと
'ec2.ServiceResource' object has no attribute 'describe_instances'
- 原因 : 使うオブジェクトを間違ってしまった。
- describe_instances()は、boto3.client('ec2')で取得したオブジェクトに含まれる関数なのに誤ってboto3.resource('ec2')で取得したオブジェクトで実行してしまった。
- 人のコードをコピペして使っているとこういうことが起こります。
ec2 = boto3.resource('ec2') #<<<< boto3.client('ec2')が正解 instances = ec2.describe_instances()
- 対応 : boto3.client('ec2')で取得したオブジェクトを使う
can't compare offset-naive and offset-aware datetimes
- 原因 : 異なるタイムゾーンのdatetimeオブジェクトを比較しているから
- 経緯 :
def get_tag_value_time(tag): ...省略... # 1. タイムゾーンを指定していなかった tag_time = datetime(now.year, now.month, now.day, int(time[0]), int(time[1])) print('タグに指定された時間(JST)は、' + tag_time.strftime(DATETIME_FORMAT)) return tag_time def is_start_instance(event, tag_time): ...省略... # 2. 実行時間はタイムゾーンをJSTにした jst_event_time = utc_event_time.astimezone(timezone(timedelta(hours=+9))) print('実行時間(JST)は、' + jst_event_time.strftime(DATETIME_FORMAT)) # AutoStopタグに指定された時刻の前後5分以内であればインスタンス起動する # 3. タイムゾーンはNoneになっていた start_time_from = tag_time + timedelta(minutes=-5) start_time_to = tag_time + timedelta(minutes=5) print('処理時間(' + jst_event_time.strftime(DATETIME_FORMAT) + ')が、' + \ start_time_from.strftime(DATETIME_FORMAT) + 'から' + start_time_to.strftime(DATETIME_FORMAT) + 'だったら起動します。') # 4. タイムゾーンがJSTとNoneのdatetimeオブジェクトを比較してエラーになった return (start_time_from <= jst_event_time) and (jst_event_time <= start_time_to) def start_instance(event, instance): ...省略... tag_time = get_tag_value_time(auto_start_tag) if is_start_instance(event, tag_time): ...省略...
- 調べた方法 : 各datetimeオブジェクトについてutcoffset()でタイムゾーンを確認した
print(tag_time.utcoffset()) # None print(jst_event_time.utcoffset()) # 9:00:00 print(start_time_from.utcoffset()) # None print(start_time_to.utcoffset()) # None
- 対応 : タグから取得した時間でdatetimeオブジェクトを作るときにタイムゾーンを指定する
JST = timezone(timedelta(hours=+9)) ...省略... def get_tag_value_time(tag): ...省略... tag_time = datetime(now.year, now.month, now.day, int(time[0]), int(time[1]), 0, 0, JST) print('タグに指定された時間(JST)は、' + tag_time.strftime(DATETIME_FORMAT)) return tag_time
Unable to import module 'lambda_function': No module named 'urllib2'
- 原因 : Python 3から urllib2 モジュールがなくなったから
import urllib2
...省略...
response = urllib2.urlopen(url)
注釈 urllib2 モジュールは、Python 3 で urllib.request, urllib.error に分割されました。 2to3 ツールが自動的にソースコードのimportを修正します。
20.6. urllib2 --- URL を開くための拡張可能なライブラリ — Python 2.7.17 ドキュメント
- 対応 : urllib.requestを使う
import urllib.request
...省略...
response = urllib.request.urlopen(url)
cannot use a string pattern on a bytes-like object
- 原因 : byte型とstr型を比較するから
- type関数で型を調べるとbyte型とstr型でした。
pattern = r"DTSTART;VALUE=DATE:" # DTSTART;VALUE=DATE:yyyyMMddの行の正規表現 repattern = re.compile(pattern) print(type(pattern)) # >>>>>>>>>>>>>>>>>>> <class 'str'> print(type(list[num-1])) #>>>>>>>>>>>>>>>>> <class 'bytes'> print(list[num-1]) #>>>>>>>>>>>>>>>>>>>>> b'END:VCALENDAR\r\n' match = repattern.search(list[num-1])
- 対応 : byte型をstr型に変換してから比較する
pattern = r"DTSTART;VALUE=DATE:" # DTSTART;VALUE=DATE:yyyyMMddの行の正規表現 repattern = re.compile(pattern) match = repattern.search(list[num-1].decode('utf-8')) #<<< 変換してから比較する
GMTとUTCとJSTとUNIX時間とPythonの狭間を泳ぐ
- 時間の種類が覚えられません。
- GMTは、ロンドン郊外にあるグリニッジ天文台での時間です。
- UTCは、GMTをちょっぴり調整した世界の標準時間です。
- JSTは、UTCより9時間進んでる日本での時間です。
- UNIX時間は、OSなどで使われるUTCでの1970-01-01 00:00:00からの経過秒数です。
- いろんな時間があるからPythonで変換もしてみました。
時間の種類が覚えられません。
GMTとUTCとJST・・・どれがなにか覚えられないので記録しておきます。
時間の種類 | 概要 | 現在時間 | UTCへ変換 | JSTへ変換 | UNIX時間 へ変換 |
---|---|---|---|---|---|
GMT | グリニッジ天文台 での時間 |
- | - | - | - |
UTC | GMTをちょっぴり 調整した時間 |
datetime. datetime.now (timezone.utc) |
- | utc_time. astimezone (timezone(timedelta (hours=+9))) |
utc_time. timestamp() |
JST | 日本の時間 | datetime. datetime.now() |
jst_time.astimezone (timezone.utc) |
- | jst_time. timestamp() |
UNIX 時間 |
コンピュータ用の時間 | int(time.time()) | datetime.fromtimestamp (unix_time, timezone.utc) |
datetime. fromtimestamp (unix_time) |
- |
UTCは、GMTをちょっぴり調整した世界の標準時間です。
- 日本語 : 協定世界時
- 英語 : Universal Time, Coordinated(調整された)
地球の自転速度の変動でちょっとずつ時間がずれるのでうるう秒で調整しています。
Pythonで現在時間のUTCを取得してみました。
>>> from datetime import datetime, timezone, timedelta # datetime.utcnow()よりdatetime.now(timezone.utc)を使うようにしたほうが良いそうです。 >>> utc_time = datetime.utcnow() >>> print(utc_time) 2020-02-13 13:01:52.177821 >>> utc_time = datetime.now(timezone.utc) >>> print(utc_time) 2020-02-13 13:02:08.306656+00:00
classmethod datetime.utcnow()
tzinfo が None である現在の UTC の日付および時刻を返します。このメソッドは now() と似ていますが、 naive な datetime オブジェクトとして現在の UTC 日付および時刻を返します。 aware な現在の UTC datetime は datetime.now(timezone.utc) を呼び出すことで取得できます。
警告 naive な datetime オブジェクトは多くの datetime メソッドでローカルな時間として扱われるため、 aware な datetime を使って UTC の時刻を表すのが好ましいです。 そのため、 UTC での現在の時刻を表すオブジェクトの作成では datetime.now(timezone.utc) を呼び出す方法が推奨されます。
datetime --- 基本的な日付型および時間型 — Python 3.8.2rc1 ドキュメント
JSTは、UTCより9時間進んでる日本での時間です。
- 日本語 : 日本標準時
- 英語 : Japan Standard Time
Pythonで現在時間のJSTを取得してみました。
>>> from datetime import datetime, timezone, timedelta >>> jst_time = datetime.now() >>> print(jst_time) 2020-02-13 22:01:39.673451
classmethod datetime.now(tz=None)
現在のローカルな日時を返します。オプションの引数 tz が None であるか指定されていない場合、このメソッドは today() と同様ですが、可能ならば time.time() タイムスタンプを通じて得ることができる、より高い精度で時刻を提供します (例えば、プラットフォームが C 関数 gettimeofday() をサポートする場合には可能なことがあります)。
tz が None でない場合、 tz は tzinfo のサブクラスのインスタンスでなければならず、現在の日付および時刻は tz のタイムゾーンに変換されます。
datetime --- 基本的な日付型および時間型 — Python 3.8.2rc1 ドキュメント
UNIX時間は、OSなどで使われるUTCでの1970-01-01 00:00:00からの経過秒数です。
Pythonで現在時間のUTCを取得してみました。
>>> import time from time >>> unix_time = int(time()) >>> print(unix_time) 1581601932
time.time() → float
エポック からの秒数を浮動小数点数で返します。 エポックの具体的な日付とうるう秒 (leap seconds) の扱いはプラットフォーム依存です。 Windows とほとんどの Unix システムでは、エポックは (UTC で) 1970 年 1 月 1 日 0 時 0 分 0 秒で、うるう秒はエポック秒の時間の勘定には入りません。 これは一般に Unix 時間 と呼ばれています。 与えられたプラットフォームでエポックが何なのかを知るには、 time.gmtime(0) の値を見てください。
time --- 時刻データへのアクセスと変換 — Python 3.8.2rc1 ドキュメント
いろんな時間があるからPythonで変換もしてみました。
UTCからJSTへ変換してみました。
>>> from datetime import datetime, timezone, timedelta >>> utc_time = datetime.now(timezone.utc) # UTCからJSTへ変換してみました。 >>> jst_time = utc_time.astimezone(timezone(timedelta(hours=+9))) >>> print(utc_time) 2020-02-13 14:05:37.511844+00:00 >>> print(jst_time) 2020-02-13 23:05:37.511844+09:00
timedelta オブジェクト
timedelta オブジェクトは経過時間、すなわち二つの日付や時刻間の差を表します。class datetime.timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0)
全ての引数がオプションで、デフォルト値は 0 です。 引数は整数、浮動小数点数でもよく、正でも負でもかまいません。
datetime --- 基本的な日付型および時間型 — Python 3.8.2rc1 ドキュメント
UTCからUNIX時間へ変換してみました。
>>> from datetime import datetime, timezone >>> utc_time = datetime.now(timezone.utc) # UTCからUNIX時間へ変換してみました。 >>> unix_time = utc_time.timestamp() >>> print(utc_time) 2020-02-13 22:10:53.173734+00:00 >>> print(unix_time) 1581631853.173734
datetime.timestamp()
datetime インスタンスに対応する POSIX タイムスタンプを返します。 返り値は time.time() で返される値に近い float です。このメソッドでは naive な datetime インスタンスはローカル時刻とし、プラットフォームの C 関数 mktime() に頼って変換を行います。 datetime は多くのプラットフォームの mktime() より広い範囲の値をサポートしているので、遥か過去の時刻や遥か未来の時刻に対し、このメソッドは OverflowError を送出するかもしれません。
datetime --- 基本的な日付型および時間型 — Python 3.8.2rc1 ドキュメント
JSTからUTCへ変換してみました。
>>> from datetime import datetime, timezone, timedelta >>> jst_time = datetime.now() # JSTからUTCへ変換してみました。 >>> utc_time = jst_time.astimezone(timezone.utc) >>> print(jst_time) 2020-02-13 22:59:58.017838 >>> print(utc_time) 2020-02-13 13:59:58.017838+00:00
datetime.astimezone(tz=None)
tz を新たに tzinfo 属性 として持つ datetime オブジェクトを返します。 日付および時刻データを調整して、返り値が self と同じ UTC 時刻を持ち、 tz におけるローカルな時刻を表すようにします。もし与えられた場合、 tz は tzinfo のサブクラスのインスタンスでなければならず、 インスタンスの utcoffset() および dst() メソッドは None を返してはなりません。もし self が naive ならば、おそらくシステムのタイムゾーンで時間を表現します。
datetime --- 基本的な日付型および時間型 — Python 3.8.2rc1 ドキュメント
JSTからUNIX時間へ変換してみました。
>>> from datetime import datetime, timezone >>> jst_time = datetime.now() # JSTからUNIX時間へ変換してみました。 >>> unix_time = jst_time.timestamp() >>> print(jst_time) 2020-02-14 07:15:27.515381 >>> print(unix_time) 1581632127.515381
UNIX時間からUTCへ変換してみました。
>>> from datetime import datetime, timezone >>> from time import time >>> unix_time = int(time()) # UNIX時間からUTCへ変換してみました。 >>> utc_time = datetime.fromtimestamp(unix_time, timezone.utc) >>> print(unix_time) 1581603619 >>> print(utc_time) 2020-02-13 14:20:19+00:00
class datetime.timezone(offset, name=None)
ローカル時刻と UTC の差分を表す timedelta オブジェクトを offset 引数に指定しなくてはいけません。これは -timedelta(hours=24) から timedelta(hours=24) までの両端を含まない範囲に収まっていなくてはなりません。そうでない場合 ValueError が送出されます。timezone.utc
UTC タイムゾーン timezone(timedelta(0)) です。
datetime --- 基本的な日付型および時間型 — Python 3.8.2rc1 ドキュメント
UNIX時間からJSTへ変換してみました。
>>> from datetime import datetime >>> from time import time >>> unix_time = int(time()) # UNIX時間からJSTへ変換してみました。 >>> jst_time = datetime.fromtimestamp(unix_time) >>> print(unix_time) 1581603238 >>> print(jst_time) 2020-02-13 23:13:58
classmethod datetime.fromtimestamp(timestamp, tz=None)
time.time() が返すような、 POSIX タイムスタンプに対応するローカルな日付と時刻を返します。オプションの引数 tz が None であるか、指定されていない場合、タイムスタンプはプラットフォームのローカルな日付および時刻に変換され、返される datetime オブジェクトは naive なものになります。
datetime --- 基本的な日付型および時間型 — Python 3.8.2rc1 ドキュメント
基本に立ち戻ってUMLのクラス図を学ぶ
- 前回の勉強内容
- 勉強のきっかけになった状況
- クラス図は、クラス同士の関係性を中心とした静的な構図を表します。
- クラスは、「操作」「属性」「ロール名」で構成されます。
- クラス同士の関係は、「汎化」「集約」「関連」などのクラスとクラスを結ぶ矢印的な線で表します。
- 次回の勉強内容
前回の勉強内容
勉強のきっかけになった状況
同僚と実装方針を話していてクラスの関係図をホワイトボードに書いたら、わかりにくくて正されました。
試験問題ができれば、理解できることになるわけではないですが基本を勉強します。
次のクラス図におけるクラス間の関係の説明のうち,適切なものはどれか。
- "バス","トラック"などのクラスが"自動車"クラスの定義を引き継ぐことを,インスタンスという。
- "バス","トラック"などのクラスの共通部分を抽出し"自動車"クラスとして定義することを,汎化という。
- "バス","トラック"などのクラスは,"自動車"クラスに対するオブジェクトという。
- "バス","トラック"などのそれぞれのクラスの違いを"自動車"クラスとして定義することを,特化という。
クラス図は、クラス同士の関係性を中心とした静的な構図を表します。
クラスとオブジェクトは、「わく組み」と 「その実体」の関係にあります。
全てのオブジェクトは、必ず何かのクラス定義のもとに生成され、クラスなしではオブジェクトは生成できません。UMLにおいて一般的に、オブジェクトはクラスのインスタンスであると言われるのは、クラスという一定の型に基づいて、実際のオブジェクトが生じるためです。
改訂新版 基礎UML UML 2対応 - インプレスブックス
問題領域やシステムの構造を見るために使われます。
クラスは、「操作」「属性」「ロール名」で構成されます。
ロール名は、関連におけるそれぞれのオブジェクトの役割(ロール)を示すものです。例えば、社員から見て、会社は雇用者という役割を持っています。一方、会社から見て、社員には従業員という役割があります。
クラス図の詳細化とその目的:初歩のUML(2) - @IT
クラス図は、クラスの仕様を決定する重要なモデルです。
クラス同士の関係は、「汎化」「集約」「関連」などのクラスとクラスを結ぶ矢印的な線で表します。
UMLのクラス図が表す内容はどれか。
- クラス間の動的な関係
- クラス同士が,必ず1対1に対応するような相互関係
- クラスを構成するクラス名,インスタンス,メッセージの3要素
- 汎化,集約,関連などのクラス間の関係
関連を持つクラス間のオブジェクトの数の対応関係は、多重度で表します。
一方のクラスのオブジェクトが、もう一方のクラスのいくつのオブジェクトと関係するかなど関連するクラス間の数量的な関係を示します。
関係性を表す図法があります。
図は"顧客が商品を注文する"を表現したUMLのクラス図である。"顧客が複数の商品をまとめて注文する"を表現したクラス図はどれか。ここで,"注文明細"は一つの注文に含まれる1種類の商品に対応し,"注文ヘッダ"は複数の"注文明細"を束ねた一つの注文に対応する。
答.
平成23年特別問45 UML クラス図|応用情報技術者試験.com
次回の勉強内容
勉強中・・・
AWSのEBSボリュームにタグをつけるLambdaを作った記録
EBSボリュームは管理しないと無駄にお金がかかります。
何気なくEC2を作るとEBSボリュームが作られます(既存のボリュームを使った場合を除く)。
EC2を削除(終了)してもEBSボリュームはデフォルトで削除されません。
結果、気が付いたら使ってないEBSボリュームが残っていることがあります。
aws.amazon.com
EC2インスタンスを削除するときはEBSボリュームも削除します。
それでもアタッチされていないEBSボリュームが残ることはあります。
複数人で長期間使っていればうっかりアタッチされていないEBSボリュームが残ることはあります。
とはいえ、本当にアタッチされていなければ削除していいのか?誰かが何かの目的で残しているのかも?
となった時に何に使われていたがわかる情報があると助かります。
やりたいこと
前提 : EC2にはNameタグをつけておきます。
EC2インスタンスには、Nameというタグをつけてインスタンスを使っているプロジェクトやサーバの情報をValueに入れておきます。
例えば、ponsukeプロジェクトのMySQLデータベースサーバにしているインスタンスなら「ponsuke-MySQL」をNameタグのValueに入れておく、みたいな。
Lambdaを作る記録
Lambdaの実行権限を作成します。
IAMのポリシーを作成します。
- AWSマネジメントコンソールにある[IAM] > サイドメニューの[ポリシー] > [ポリシーの作成]ボタンで作成画面を開きます。
- [JSON]タブを開いて下にある内容を入力します。
- [ポリシーの確認]ボタンで確認画面へ遷移して[名前(必須)]と[説明(任意)]を入力します。
- [ポリシーの作成]ボタンでポリシーを作成して一覧画面に戻ります。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ec2:DescribeInstances", "ec2:CreateTags", "logs:CreateLogStream", "logs:CreateLogGroup", "logs:PutLogEvents" ], "Resource": "*" } ] }
IAMのロールを作成します。
Lambda関数を作成します。
- AWSのコンソールにある[Lambda] > [関数の作成]ボタンで画面を開きます。
- 必要な項目を入力後に[関数の作成]ボタンで関数を作成します。
- オプション : [一から作成]
- 関数名 : attatch_name_tag_for_ebs_volume(任意の関数名でOK)
- ランタイム : Python3.8
- 実行ロール : 既存のロールを使用する
- 既存のロール : 作成したロールを選択します。
Lambda関数を実行するトリガーを作成します。
- [Designer]にある[トリガーを追加]ボタンでトリガーの設定画面を開きます。
- プルダウンから[CloudWatch Events]を選択します。
- 各入力欄を記載します
- ルール : [新規ルールの作成]
- ルール名(必須) : attatch_name_tag_for_ebs_volume(任意の関数名でOK)
- ルールタイプ : [スケジュール式]
- スケジュール式の書き方を参考にLambda関数を実行する予定を入力します。
- [追加]ボタンでトリガーを作成します。
関数の内容を実装します。
- EBSボリュームを取得するdescribe_volumes()の使い方
- EC2インスタンスを取得するdescribe_instances()の使い方
- EBSボリュームにタグをつけるcreate_tags()の使い方
import boto3 ec2 = boto3.client('ec2') print('Loading function') def get_name_tag_value(tags): """ タグリストからNameタグの値を取得する. Parameters ---------- tags 辞書形式のタグリスト """ name_tag_value = '' for tag in tags: if tag['Key'] == 'Name': name_tag_value = tag['Value'] break return name_tag_value def get_volumes_no_name_tag_and_attached(): """ [アタッチされていて][Nameタグが設定されていない]EBSボリュームを取得する. """ volumes = ec2.describe_volumes( Filters=[ { 'Name': 'attachment.status', 'Values': ['attached'] } ] )['Volumes'] volumes_no_name_tag = [] for volume in volumes: if 'Tags' not in volume: # タグが設定されていない場合:Nameタグのないボリュームとする volumes_no_name_tag.append(volume) else: # タグが設定されている場合 name_tag_value = get_name_tag_value(volume['Tags']) if name_tag_value == '': # Nameタグの値を取得できない場合:Nameタグのないボリュームとする volumes_no_name_tag.append(volume) return volumes_no_name_tag def get_ec2_instance_name_tag_value(volume): """ EBSボリュームにアタッチされているEC2インスタンスに設定されているNameタグの値を取得する. Parameters ---------- volume 対象となるEBSボリューム """ # アタッチされているEC2インスタンスのIDを取得する instance_id = volume['Attachments'][0]['InstanceId'] # EC2インスタンスのIDからインスタンスに設定されているタグ群を取得する tags = ec2.describe_instances( Filters=[ { 'Name': 'instance-id', 'Values': [instance_id] } ] )['Reservations'][0]['Instances'][0]['Tags'] # EC2インスタンスについているNameタグの値を取得する name_tag_value = get_name_tag_value(tags) return name_tag_value def set_name_tag_for_volume(volume_id, name_tag_value): """ EBSボリュームにNameタグを設定する. Parameters ---------- volume_id NameタグをつけるEBSボリュームID name_tag_value EC2インスタンスについているNameタグの値 """ response = ec2.create_tags( Resources=[volume_id], Tags=[{'Key': 'Name', 'Value': name_tag_value}] ) return 0 def lambda_handler(event, context): volumes = get_volumes_no_name_tag_and_attached() for volume in volumes: # EBSボリュームのIDを取得する. volume_id = volume['VolumeId'] print(str(volume_id) + 'にはNameタグが付いていません') name_tag_value = get_ec2_instance_name_tag_value(volume) # EC2インスタンスにNameタグが設定されている場合に処理を実行する. if name_tag_value != '': set_name_tag_for_volume(volume_id, name_tag_value) print(str(volume_id) + 'のNameタグに「' + name_tag_value + '」とつけました') return 0
失敗したこと
describe_volumes()の実行権限がIAMロールになかった
[ERROR] ClientError: An error occurred (UnauthorizedOperation) when calling the DescribeVolumes operation: You are not authorized to perform this operation.
- 事象 : describe_volumes()を実行したらエラーになった
- 原因 : describe_volumes()を実行する権限がないから
- エラーの時のIAMロールの権限設定 > 「ec2:DescribeInstances」しかない
...省略... "Effect": "Allow", "Action": [ "ec2:DescribeInstances", "ec2:CreateTags", "logs:CreateLogStream", "logs:CreateLogGroup", "logs:PutLogEvents" ], ...省略...
- 対応 : 「ec2:DescribeVolumes」を権限設定に追加する
...省略... "Effect": "Allow", "Action": [ "ec2:DescribeVolumes", <<< 追加 "ec2:DescribeInstances", "ec2:CreateTags", "logs:CreateLogStream", "logs:CreateLogGroup", "logs:PutLogEvents" ], ...省略...
describe_volumesの引数の型が不正だった
[ERROR] ParamValidationError: Parameter validation failed: Invalid type for parameter Filters[0].Values, value: Name, type: <class 'str'>, valid types: <class 'list'>, <class 'tuple'>
- 事象 : Filtersに指定したValuesに文字(str)を指定して実行したらエラーになった
# Nameタグが設定されていないEBSボリュームを取得する response = ec2.describe_volumes( Filters=[ { 'Name': 'tag:Name', 'Values': '' } ] )['Volumes']
- 原因 : Valuesにlistかtupleのシーケンス型を使っていないから
- [ドキュメントにもValues (list) と書いてあります。]
- 対応 : Valuesをlistで指定する
{ 'Name': 'tag:Name', 'Values': [''] <<<<<<<<<< 修正 }
Oracle Databaseにユーザー(スキーマ)を作った記録
- RDSでOracleを作成したのでユーザーを作成します。
- SQL*PlusでDBにログインします。
- ユーザーに設定する情報を確認します。
- ユーザーを作成します。
- 作成したユーザーでログインしてみます。
- 失敗したこと
- 環境
RDSでOracleを作成したのでユーザーを作成します。
SQL*PlusでDBにログインします。
管理者ユーザーでログインします。
$ sqlplus admin/hoge@oracle-12.fuga.us-east-2.rds.amazonaws.com:1521/PONDB SQL*Plus: Release 12.2.0.1.0 Production on 火 3月 10 13:57:46 2020 Copyright (c) 1982, 2016, Oracle. All rights reserved. 最終正常ログイン時間: 火 3月 10 2020 13:45:58 +00:00 Oracle Database 12c Standard Edition Release 12.2.0.1.0 - 64bit Production に接続されました。 SQL>
表示幅が狭いと見ずらいので広げます。
SQL> show linesize linesize 80 SQL> set linesize 120
ユーザーに設定する情報を確認します。
ユーザーを作成する構文
CREATE USER my_name
IDENTIFIED BY "my_password"
[DEFAULT TABLESPACE my_tablespace]
[TEMPORARY TABLESPACE my_temp_tablespace]
[PROFILE my_profile]
CREATE USER、ユーザーの作成 - オラクル・Oracleをマスターするための基本と仕組み
作りたいユーザー名が既にないことを確認します。
SQL> select distinct username from all_users where username like '%ponsuke%'; レコードが選択されませんでした。
注意 : キャメルケースでユーザー名を指定すると大文字小文字が区別されないのでダサいことになります。
キャメルケースで書くと大文字小文字が区別されず、全部大文字か全部小文字(表示するツールによるらしい)になります。
「_」などで区切るスネークケースがよいです。
ダサいのを誤って作ってしまったので削除しました。
/* 所有していたオブジェクトもろともユーザーを削除する */ SQL> drop user PONSUKETAROU cascade;
使用する表領域を選びます。
「DEFAULT TABLESPACE(ユーザー・オブジェクト を作成するときの使用するデフォルト表領域)」「TEMPORARY TABLESPACE(Oracle が使用する作業用の表領域)」で指定する値を選びます。
現在存在する表領域を検索して選びます。
SQL> select tablespace_name,block_size,initial_extent from dba_tablespaces; TABLESPACE_NAME BLOCK_SIZE INITIAL_EXTENT --------------- ---------- -------------- SYSTEM 8192 65536 SYSAUX 8192 65536 UNDO_T1 8192 65536 TEMP 8192 1048576 USERS 8192 65536 RDSADMIN 8192 65536 6行が選択されました。
ユーザーを作成します。
SQL> create user ponsuke identified by ponsuke default tablespace USERS temporary tablespace TEMP profile DEFAULT; ユーザーが作成されました。 -- 確認します。 SQL> select username from all_users where regexp_like(username, 'ponsuke', 'i'); USERNAME ------------------------------------------------------------------------------------------------------------------------ PONSUKE SQL>
権限を付与します。
権限を付与しないとデータベースに接続すらできません。
SQL> grant create session,create table,create view,create sequence,create trigger,create synonym,unlimited tablespace to ponsuke; 権限付与が成功しました。
作成したユーザーでログインしてみます。
$ sqlplus ponsuke/ponsuke@oracle-12.fuga.us-east-2.rds.amazonaws.com:1521/PONDB SQL*Plus: Release 12.2.0.1.0 Production on 火 3月 10 14:32:13 2020 Copyright (c) 1982, 2016, Oracle. All rights reserved. Oracle Database 12c Standard Edition Release 12.2.0.1.0 - 64bit Production に接続されました。 SQL>
AWSのRDSの証明書を更新した記録
5年ごとに証明書を更新する必要があります。
、RDS DB インスタンスと Aurora DB クラスターの SSL/TLS 証明書は有効期限が切れ、5 年ごとに置き換えられます。現在の証明書は、2020 年 3 月 5 日に期限切れになります。 クライアントとデータベースサーバーの両方で SSL/TLS 証明書を更新しない場合、証明書を検証して SSL/TLS により RDS DB インスタンスまたは Aurora クラスターに接続するデータベースクライアントとアプリケーションは、2020 年 3 月 5 日から接続できなくなります。
Amazon RDS のお客様: 2020 年 2 月 5 日までに SSL/TLS 証明書を更新してください | Amazon Web Services ブログ
実際にやった人の手順を参考に実施します。
今の証明書を確認します。
- コンソール > [RDS] > [データベース] > 対象のRDSのリンクから詳細画面を表示 > [接続とセキュリティ] > [認証機関]
- 認証機関 : rds-ca-2015
- 証明機関の日付 : Mar 6th, 2020
認証機関をrds-ca-2019へ更新します。
確認します。
- コンソール > [RDS] > [データベース] > 対象のRDSのリンクから詳細画面を表示 > [接続とセキュリティ] > [認証機関]
- 認証機関 : rds-ca-2019
- 証明機関の日付 : Aug 23rd, 2024
- DBクライアントツールから接続できることを確認します。
- 開発アプリケーションから接続できることを確認します。
- SQL*PLUSでも接続を確認します。
$ sqlplus {ユーザ名}/{パスワード}@hoge.fuge.ap-northeast-1.rds.amazonaws.com:1521/{サービス名} SQL*Plus: Release 12.2.0.1.0 Production on 木 1月 30 10:25:04 2020 Copyright (c) 1982, 2017, Oracle. All rights reserved. 最終正常ログイン時間: 火 1月 28 2020 10:19:05 +09:00 Oracle Database 12c Standard Edition Release 12.2.0.1.0 - 64bit Production に接続されました。 SQL>
医療情報倫理
- 医療業界に関わるエンジニアへの一歩目
- 個人情報とプライバシー
- 医療情報システムの利用者の責任
- 医療情報システムの担当者の責務
- 医療の情報化と患者の医療参画
- 医学・保健医療の研究倫理とポピュレーション・ヘルス
- 医療情報倫理
- 医療情報担当職の倫理網領
- 医療情報化の担い手として
医療業界に関わるエンジニアへの一歩目
医療業界に関わるお仕事をするエンジニアとして「医療情報技師」という資格の「医療情報システム」という分野を勉強してみます。
まずは、情報を取り扱うものとしての基本となる医療情報倫理です。
個人情報とプライバシー
医療の世界では、氏名や住所だけではなく生体情報という他人が容易には知り得ないような情報を取り扱います。
そんな医療の世界で働く人に向けて、厚生労働省からは医療・介護関係事業者における個人情報の適切な取扱いのためのガイダンスが出ています。
医療の世界に関わる人と言ってもお医者さんから介護士・研究者といろんな立場があるので、ガイダンスには以下のようなことが記載されています。
- 医療・介護関係事業者が行う措置の透明性の確保と対外的明確化
- 責任体制の明確化と患者・利用者窓口の設置等
- 遺族への診療情報の提供の取扱い
- 個人情報が研究に活用される場合の取扱い
- 遺伝情報を診療に活用する場合の取扱い
“医療情報システム向け「Amazon Web Services」利用リファレンス”の公開:APN パートナー各社 | Amazon Web Services ブログ
「個人情報」と「プライバシー」のびみょーーーな違い
「個人情報保護」と「プライバシー保護」は同じ意味に思えます。
しかし、医療情報技師の教科書では「個人情報」と「プライバシー」の違いを説明しています。
「プライバシーに関わる情報」とは、
個人の私生活上の事実に関する情報であり、「本人がその情報を開示しないで欲しいであろうと考えられる情報」である。
これに対し
「個人情報」は、
「特定の個人を識別できる情報」であり、私生活に関する情報か否か、開示しないで欲しいと考えられる情報か否かは問わない。
医療情報第5版医療情報システム編
医療情報システムの利用者の責任
医療に関わるシステムは、限られた人がエルタンできるようなものが多いように思います。
電子カルテや薬剤情報・検査機器を扱うシステムから研究や治験の情報を蓄積するシステムまで、誰でも彼でも閲覧できるものはではありません。
それは、先に紹介した「個人情報」「プライバシー」を取り扱うからです。
不適切な閲覧によるプライバシーの侵害をしないようにします。
システムを閲覧できる権限があるひとには「個人情報」「プライバシー」を守る義務が生じます。
そのために、利用者一人ひとりの意識が重要です。
故意及び重過失をもって、これらの要件に反する行為を行えば刑法上の秘密漏示罪で犯罪として処罰される場合があるが、診療情報等については過失による漏えいや目的外利用
も同様に大きな問題となり得る。
医療情報システムの安全管理に関するガイドライン
プライバシー権利を保証するための情報セキュリティ上の義務があります。
- 自身の認証番号やパスワードを管理し、これを他人に利用させない。
- 電子保存システムの情報の参照や入力に際して、認証番号やパスワードなどによってシステムに自身を認識させる。
- 電子保存システムへの入力に際して、確定操作(入力情報が正しいことを確認する操作)を行って、入力情報に対する責任を明示する。
- 代行入力の場合は、入力権限を持つ者が最終的に確定操作を行い、入力情報に対する責任を明示する。
- 作業終了あるいは離席する際は、必ずログアウト操作を行う。
ちょっとしたセキュリティ意識の弱さから漏洩事件が発生しています。
医療情報システムの担当者の責務
医療システムの責任者・担当者に対する指針として厚生労働省から医療情報システムの安全管理に関するガイドラインが出ています。
医療・介護関係事業者における個人情報の適切な取扱いのためのガイダンスでは、「医療情報システムの導入及びそれに伴う情報の外部保存を行う場合の取扱い」についてはこのガイダンスに従うことが記載されています。
医療の情報化と患者の医療参画
ここ数十年で医療へのコンピュータ導入の目的は、「業務の合理化」>「診療支援」>「患者中心の視点」へと視点の主役が変わってきているそうです。
電子カルテでは、
- 医療者 : 患者へ説明しやすく
- 患者 : カルテへの敷居が低くなる
と、「患者中心の医療」への取り組みにコンピュータ導入が寄与することとなる。
電子カルテを導入するメリット・デメリット | 導入するメリット・デメリット | 電子カルテサービス | SECOM セコム医療システム株式会社
医学・保健医療の研究倫理とポピュレーション・ヘルス
医療システムが導入されていくことで治療へつながる研究や症例の蓄積などへ医療情報の活用が活発になっていきます。
医療情報倫理
医療情報担当職の倫理網領
医療情報化の担い手として
AWSのRDSのバックアップをインスタンスに復元する記録
Amazon RDSはインスタンスの自動バックアップをしてくれます。
Amazon RDS は、DB インスタンスの自動バックアップを作成および保存します。Amazon RDS は、DB インスタンスのストレージボリュームのスナップショットを作成し、個々のデータベースだけではなく、その DB インスタンス全体をバックアップします。
バックアップの使用
自動化バックアップによってDB スナップショットができます。
サイドメニューに[スナップショット]と[Automated backups]の2つがあるので何が違うんだろう?と思いました。
[よくある質問]を読むと「自動化バックアップ機能によってスナップショットができる。」「スナップショットは自動化バックアップ機能を使わなくても作れる。」そうです。
バックアップを復元したければスナップショットを復元すればいいんですね。
Q: 自動化バックアップと DB スナップショットの違いは何ですか?
Amazon RDS は、DB インスタンスのバックアップと復元を行うための 2 つの方法を提供しています。自動バックアップとデータベーススナップショット (DB スナップショット) です。
よくある質問 - Amazon RDS | AWS
スナップショットを復元します。
失敗したこと
The option group hoge is associated with a different VPC than the request.
- 事象 : [DBインスタンスの復元]ボタンを押下したところ以下のメッセージが表示されて復元できない。
The option group hoge is associated with a different VPC than the request. (Service: AmazonRDS; Status Code: 400; Error Code: InvalidParameterCombination; Request ID: 74xxxxx)
- 原因 : [アベイラビリティーゾーン]を選択していないから
- スナップショットの元になったインスタンスの設定になっているのかと思い込んでみていませんでした。
- [オプション・グループ]を設定していると別のVPCに復元するのは大変なことです。
- 参考 : Amazon Web Services (AWS) ドキュメントのオプショングループに関する考慮事項
- スナップショットの元になったインスタンスの設定になっているのかと思い込んでみていませんでした。
- 対応 : [アベイラビリティーゾーン]を選択する
AWSのRDSを自動停止するLambdaを作る記録
- RDSは停止しても7日経つと自動で起動してしまいます。
- このサイトのやり方でRDSを自動停止するLambdaを作る
- 実行権限を作成する
- 自動停止の対象と停止時間を設定できるようにするためにRDSにAutoStopタグを追加します。
- Lambda関数を作成します。
- Lambda関数を実行するトリガーを作成します。
- 失敗したこと
RDSは停止しても7日経つと自動で起動してしまいます。
DB インスタンスは最大 7 日間停止できます。DB インスタンスを手動で起動しないで 7 日間が経過すると、DB インスタンスは自動的に起動します。
一時的に Amazon RDS DB インスタンスを停止する - Amazon Relational Database Service
なので、RDSを監視して自動で停止してほしいです。
案件が動いていない時は停止していてほしいです。ちょいちょい確認して停止するのは面倒くさいです。
そこで、世の中の知識を利用して自動停止できるようにします。
このサイトのやり方でRDSを自動停止するLambdaを作る
実行権限を作成する
Lambdaの実行権限を作成する - ponsuke_tarou’s blog
上記を参考にIAMのポリシーを作成し、ロールを作成します。
ポリシーに設定する内容は以下になります。
{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": [ "rds:StopDBInstance", "rds:ListTagsForResource" ], "Resource": "arn:aws:rds:*:*:db:*" }, { "Sid": "VisualEditor1", "Effect": "Allow", "Action": [ "logs:CreateLogStream", "rds:DescribeDBInstances", "logs:CreateLogGroup", "logs:PutLogEvents" ], "Resource": "*" } ] }
自動停止の対象と停止時間を設定できるようにするためにRDSにAutoStopタグを追加します。
- AWSマネジメントコンソールにある[RDS] > サイドメニューの[データベース] > 対象となるRDSを選択して詳細画面を開きます。
- [タグ]タブ > [追加]ボタンで[タグの追加] ウィンドウを表示します。
- [タグキー]に「AutoStop」と[値]に「自動停止したい時間」を入力します。
- [追加]を選択します。
Lambda関数を作成します。
- AWSのコンソールにある[Lambda] > [関数の作成]ボタンで画面を開きます。
- 必要な項目を入力後に[関数の作成]ボタンで関数を作成します。
- オプション : [一から作成]
- 関数名 : 任意の関数名
- ランタイム : Python3.8
- 実行ロール : 既存のロールを使用する
- 作成したロールを選択します。
関数を実装します。
[関数コード] > [lambda_function.py]に以下のコードを張り付けて[保存]ボタンで保存します。
# -*- coding: utf-8 -*- from __future__ import print_function import sys import json import boto3 import datetime REGION_NAME = "ap-northeast-1" print("Loading function") rds = boto3.client('rds') def get_auto_stop_tag(instance_arn): instance_tags = rds.list_tags_for_resource(ResourceName=instance_arn) tag_list = instance_tags['TagList'] tag = next(iter(filter(lambda tag: tag['Key'] == 'AutoStop' and (tag['Value'] is not None and tag['Value'] != ''), tag_list)), None) return tag def get_auto_stop_time(auto_stop_tag): today = datetime.datetime.now() param_day = today.day auto_stop_val = auto_stop_tag["Value"].split(":") # 設定時刻が8:59以前である場合、GMT変換時に前日にならないよう日付を1日進めておく if int(auto_stop_val[0]) < 9: param_day = param_day + 1 # タグに指定されたGMTでの時間 tag_time = datetime.datetime(today.year, today.month, param_day, int(auto_stop_val[0]), int(auto_stop_val[1])) gmt_time = tag_time + datetime.timedelta(hours=-9) return gmt_time def lambda_handler(event, context): print("Received event: " + json.dumps(event, indent=2)) # インスタンスを取得 instances = rds.describe_db_instances() if len(instances['DBInstances']) > 0: # インスタンスを順番に処理していく for instance in instances['DBInstances']: if instance['DBInstanceStatus'] == 'available': instance_arn = instance['DBInstanceArn'] print(instance_arn + 'は、稼働中です。') tag = get_auto_stop_tag(instance_arn) print('取得したAutoStopタグ:' + str(tag)) if tag: # AutoStopタグが指定されているインスタンスを処理する reference_time = get_auto_stop_time(tag) print('AutoStopタグに指定された時間(GMT)は、' + reference_time.strftime('%Y-%m-%dT%H:%M:%SZ') + 'です。') event_time = datetime.datetime.strptime(event["time"], '%Y-%m-%dT%H:%M:%SZ') reference_time_from = reference_time + datetime.timedelta(minutes=-5) reference_time_to = reference_time + datetime.timedelta(minutes=5) print('処理時間(' + event_time.strftime('%Y-%m-%dT%H:%M:%SZ') + ')が、' + \ reference_time_from.strftime('%Y-%m-%dT%H:%M:%SZ') + 'から' + reference_time_to.strftime('%Y-%m-%dT%H:%M:%SZ') + 'だったら停止します。') # AutoStopタグに指定された時刻の前後5分以内であればインスタンス停止する if reference_time_from <= event_time and event_time <= reference_time_to: rds.stop_db_instance(DBInstanceIdentifier=instance['DBInstanceIdentifier']) print(instance_arn + 'を停止しました。')
実装の参考サイト
AWS Lambda+Python3で複数のRDSを起動停止 | LINKBAL Blog
Lambdaの関数を利用してRDSを長期間停止する - Qiita
DescribeDBInstances - Amazon Relational Database Service
DB instance status - Amazon Relational Database Service
AWS Lambda Pythonをローカル環境で実行 | DevelopersIO
関数を動かしてみます。
- [テスト]ボタンで[テストイベントの設定]ダイアログを表示します。
- [新しいテストイベントの作成]を選択します。
- [イベントテンプレート]で「Hello World」を選択します。
- 引数の欄に「{"time": "2019-12-04T10:02:00Z"}」を入力します(時間はAutoStopタグに指定した時間の近い時間)。
- [イベント名]に任意の名前を設定して[作成]ボタンで保存します。
- [テスト]ボタンで関数を実行します。
- 実行結果とログを確認して、「成功」になるまでソースや設定の見直しをします。
Lambda関数を実行するトリガーを作成します。
CloudWatch EventsをトリガーとしてLambda関数を実行できるようにするためにイベントを登録します。
CloudWatch Eventsにイベントを登録します。
- AWSのコンソールにある[Lambda] > 作成したLambda関数を選択して詳細画面を開きます。
- [Designer]にある[トリガーを追加]ボタンでトリガーの設定画面を開きます。
- プルダウンからCloudWatch Eventsを選択します。
- [ルール]で「新規ルールの作成」を選択し、[ルール名(必須)][ルールの説明(任意)]を入力します。
- [ルールタイプ]で「スケジュール式」を選択し、[スケジュール式]に以下のサイトを参考にスケジュールを設定します。
失敗したこと
CloudWatch Eventsの[スケジュール式]の書き方を間違えた
Cron式で時間に「10-24」と指定したところエラーになりました。24時はだめなんですね。
Parameter ScheduleExpression is not valid. (Service: AmazonCloudWatchEvents; Status Code: 400; Error Code: ValidationException; Request ID: c.....)
Lambda関数でCloudWatch Logsに書き込むための権限がなかった。
Lambda関数を実行するCloudWatch Eventsを登録してからLambda関数の[モニタリング]タブを見てみるとメッセージが表示されていました。
メッセージにある[AWSLambdaBasicExecutionRole]の権限を追加します。
アクセス権限が見つかりません お使いの関数には、Amazon CloudWatch Logs に書き込むためのアクセス許可がありません。ログを閲覧するには、その実行ロールに AWSLambdaBasicExecutionRole の管理ポリシーを追加します。IAM コンソールを開きます。
- AWSマネジメントコンソールにある[IAM] > サイドメニューの[ポリシー] > [AWSLambdaBasicExecutionRole]を検索して詳細画面を表示します。
- [アクセス権] > [JSON]で権限の詳細を表示します。
- [Statement]に記載されている内容以下をコピーします。
- サイドメニューの[ポリシー] > Lambda関数に設定したポリシーを検索して詳細画面を表示します。
- [アクセス権] > [JSON] > [ポリシーの編集]ボタンで編集画面を表示します。
- コピーした内容を[Action]に追記します。
- [ポリシーの確認]ボタン > [変更の保存]ボタンで保存します。
describe_db_instancesを実行する権限がなかった。
Lambda関数を実行したらエラーになりました。ポリシーの[Action]に「rds:DescribeDBInstances」を追加しました。
{ "errorMessage": "An error occurred (AccessDenied) when calling the DescribeDBInstances operation: User: arn:aws:sts::8xxxxxxxxxxx:assumed-role/{ロール名}/{Lambda関数名} is not authorized to perform: rds:DescribeDBInstances", "errorType": "ClientError", "stackTrace": [ " File \"/var/task/lambda_function.py\", line 27, in lambda_handler\n instances = rds.describe_db_instances(Filters=[{\"Name\": \"DBInstanceStatus\", \"Values\": [\"available\"]}])\n", " File \"/var/runtime/botocore/client.py\", line 357, in _api_call\n return self._make_api_call(operation_name, kwargs)\n", " File \"/var/runtime/botocore/client.py\", line 661, in _make_api_call\n raise error_class(parsed_response, operation_name)\n" ] }
「rds:DescribeDBInstances」はリソースを限定できなかった。
以下のように単純に「rds:DescribeDBInstances」を追加したところ同じエラーになりました。
一部のRDSの情報の閲覧だけできるポリシーは作れなかった話 - Qiitaを読んでリソースを限定できないことを知りました。
...省略... "Action": [ "rds:StopDBInstance", "rds:DescribeDBInstances" ], "Resource": "arn:aws:rds:*:*:db:*" ...省略...
DMZは内部ネットワークを守るための領域です。
- 前回の勉強内容
- 勉強のきっかけになった問題
- DMZは、外部ネットワークと内部ネットワークの間にあるネットワーク上の領域です。
- DMZは、ファイアウォールやルータに隔離された領域です。
- DMZを設置していてもファイアウォールやDMZに設置した機器の正しい対策が行われていなければ、内部ネットワークは危険にさらされます。
- 次回の勉強内容
前回の勉強内容
勉強のきっかけになった問題
DMZ上に公開しているWebサーバで入力データを受け付け,内部ネットワークのDBサーバにそのデータを蓄積するシステムがある。インターネットからDMZを経由してなされるDBサーバへの不正侵入対策の一つとして,DMZと内部ネットワークとの間にファイアウォールを設置するとき,最も有効な設定はどれか。
DMZは、外部ネットワークと内部ネットワークの間にあるネットワーク上の領域です。
- 英語: DeMilitarized(離れる + 軍用化する) Zone
- 日本語: 非武装地帯
Webサーバなど外部に公開するサーバなどが設置されます。
ステートフル・インスペクションは、出入りするパケットの通信状態を把握して外部から送信されたパケットのアクセスを動的に制御するファイアウォールです。
DMZは、ファイアウォールやルータに隔離された領域です。
パケットフィルタリング型ファイアウォールを設置すると、パケットのヘッダ情報でアクセス制御を行うことができます。
内部ネットワークのDBサーバの受信ポート番号を固定し、WebサーバからDBサーバの受信ポート番号への通信だけをファイアウォールで通します。
「勉強のきっかけになった問題」にある設問の構成では、Webサーバから内部ネットワークへの通信はDBサーバに限れば良いので、DBサーバのポートを固定してファイアウォールへ設定します。これにより、不要な通信を通さずに済みます。
(参考)情報セキュリティスペシャリスト平成22年秋期 午前Ⅱ 問6
DMZを設置していてもファイアウォールやDMZに設置した機器の正しい対策が行われていなければ、内部ネットワークは危険にさらされます。
内部ネットワークのPCからインターネット上のWebサイトを参照するときにDMZ上に用意したVDI(Virtual Desktop Infrastructure)サーバ上のWebブラウザを利用すると,未知のマルウェアがPCにダウンロードされて,PCが感染することを防ぐというセキュリティ上の効果が期待できる。この効果を生み出すVDIサーバの動作の特徴はどれか。
答. Webサイトからの受信データを処理してVDIサーバで生成したデスクトップ画面の画像データだけをPCに送信する。
平成30年春期問41 VDIシステムの導入|応用情報技術者試験.com
公開サーバと同じマシンに公開する必要のないサーバを一緒に入れると公開する必要のないサーバは危険にさらされます。
企業のDMZ上で1台のDNSサーバを,インターネット公開用と,社内のPC及びサーバからの名前解決の問合せに対応する社内用とで共用している。このDNSサーバが,DNSキャッシュポイズニングの被害を受けた結果,直接引き起こされ得る現象はどれか。
答. 社内の利用者が,インターネット上の特定のWebサーバにアクセスしようとすると,本来とは異なるWebサーバに誘導される。
平成28年春期問36 DNSキャッシュポイズニング|応用情報技術者試験.com
ファイアウォールでは、「不正なアクセスによる攻撃」「Webアプリケーションの脆弱性を利用した攻撃」は防げません。
IDSとIPSを利用することで、ネットワークを監視して危険の連絡・遮断ができます。
WAFは、Webアプリケーションへの攻撃を監視し阻止します。
次回の勉強内容
WAFは、Webアプリケーションへの攻撃を監視し阻止します。
- 前回の勉強内容
- 勉強のきっかけになった問題
- パケットフィルタリング型ファイアウォールは、ネットワーク層の情報でアクセス制御を行うファイアウォールです。
- アプリケーションゲートウェイ型ファイアウォールは、アプリケーション層のチェックしてアクセス制御を行うファイアウォールです。
- IDSとIPSは、ネットワークを監視して危険をお知らせしてくれます。
- WAFは、Webアプリケーションへの攻撃を監視し阻止します。
- WAFを設置する場合、設置場所には「ネットワーク」と「ウェブサーバ」の 2 つがあります。
- 次回の勉強内容
前回の勉強内容
勉強のきっかけになった問題
図のような構成と通信サービスのシステムにおいて,Webアプリケーションの脆弱性対策としてネットワークのパケットをキャプチャしてWAFによる検査を行うとき,WAFの設置場所として最も適切な箇所はどこか。ここで,WAFには通信を暗号化したり復号したりする機能はないものとする。
情報セキュリティスペシャリスト平成25年春期 午前Ⅱ 問4
IDSとIPSは、ネットワークを監視して危険をお知らせしてくれます。
WAFは、Webアプリケーションへの攻撃を監視し阻止します。
- 正式名称 : Web Application Firewall
- 読み方 : わふ
通過するパケットのIPアドレスやポート番号だけでなくペイロード部(データ部分)をチェックすることで、Webアプリケーションに対する攻撃を検知し、遮断することが可能なファイアウォールです。
平成29年秋期問45 WAFの説明はどれか|応用情報技術者試験.com
Webサーバ及びアプリケーションに起因する脆(ぜい)弱性への攻撃を遮断します。
Webアプリケーションの防御に特化したファイアウォールで、パケットのヘッダ部に含まれるIPアドレスやポート番号だけでなくペイロード部(データ部分)をチェックし、攻撃の兆候の有無を検証します。
予想問題vol.5問29 WAFを利用する目的はどれか|情報セキュリティマネジメント試験.com
特徴的なパターンが含まれるかなどWebアプリケーションへの通信内容を検査して、不正な操作を遮断します。
検出パターンには、「ウェブアプリケーションの脆弱性を悪用する攻撃に含まれる可能性の高い文字列」や「ウェブアプリケーション仕様で定義されているパラメータの型、値」といったものを定義します。
安全なウェブサイトの作り方:IPA 独立行政法人 情報処理推進機構
Webサイトに対するアクセス内容を監視し、攻撃とみなされるパターンを検知したときに当該アクセスを遮断します。
チェックされる内容には「URLパラメタ」や「クッキーの内容」などのHTTPヘッダ情報や、「POSTデータの内容」などのメッセージボディ部などがあります。
基本情報技術者平成28年秋期 午前問42
クライアントとWebサーバの間においてクライアントからWebサーバに送信されたデータを検査して、SQLインジェクションなどの攻撃を遮断するためのものです。
パケットのヘッダ部に含まれるIPアドレスやポート番号だけでなくペイロード部(データ部分)をチェックし、攻撃の兆候の有無を検証します。これによりWebアプリケーションに対する攻撃を検知し、遮断することが可能です。
平成28年春期問43 Web Application Firewall|基本情報技術者試験.com
WAFを設置する場合、設置場所には「ネットワーク」と「ウェブサーバ」の 2 つがあります。
ネットワークに設置するWAFは、利用者とウェブサイト間の HTTP・HTTPS通信を通信経路上に介在することで検査します。
主な特徴は以下の通りです。
次回の勉強内容
勉強中・・・
ネットワークを監視して危険をお知らせしてくれるIDSとIPS
- 前回の勉強内容
- 勉強のきっかけになった問題
- IDSは、サーバやネットワークを監視しセキュリティポリシを侵害するような挙動を検知した場合に管理者へ通知します。
- IPSは、サーバやネットワークへの侵入を防ぐために不正な通信を検知して遮断する装置です。
- 次回の勉強内容
前回の勉強内容
勉強のきっかけになった問題
IDS(Intrusion Detection System)の特徴のうち,適切なものはどれか。
IDSは、サーバやネットワークを監視しセキュリティポリシを侵害するような挙動を検知した場合に管理者へ通知します。
- 英語: Intrusion(侵入) Detection(検出) System
- 日本語: 侵入検知システム
設置場所は「ネットワーク型」「ホスト型」の2種類あります。
ネットワーク型は、監視対象のネットワーク上に設置してネットワークの通信を監視します。
- 略称: NIDS
- 英語: Network-Based IDS
NIDSに通信内容を復号する機能がなければ、SSLを利用したアプリケーションを介して行われる攻撃を検知できません。
ホスト型は、監視対象サーバーに設置して通信の結果生成された受信データやログを監視します。
- 略称: HIDS
- 英語: Host-Based IDS
ホスト型IDSでは,シグネチャとのパターンマッチングを失敗させるためのパケットが挿入された攻撃でも検知できる。
平成18年春期問73 IDSの特徴のうち適切なもの|応用情報技術者試験.com
IPSは、サーバやネットワークへの侵入を防ぐために不正な通信を検知して遮断する装置です。
- 英語: Intrusion Prevention System
- 日本語: 侵入防御システム
IDSとの大きな違いは、不正なアクセスを管理者へ通知するだけではなく遮断してくれるところです。
次回の勉強内容
アプリケーションゲートウェイ型ファイアウォールは、アプリケーション層でパケットのデータまでをチェックしてアクセス制御を行うファイアウォールです。
- 前回の勉強内容
- 勉強のきっかけになった問題
- アプリケーションゲートウェイ型ファイアウォールは、アプリケーション層でパケットのデータまでをチェックしてアクセス制御を行うファイアウォールです。
- アプリケーションゲートウェイ型ファイアウォールは、インターネットと内部のネットワークを切り離します。
- 次回の勉強内容
前回の勉強内容
勉強のきっかけになった問題
ファイアウォールの方式に関する記述のうち,適切なものはどれか。
アプリケーションゲートウェイ型ファイアウォールは、アプリケーション層でパケットのデータまでをチェックしてアクセス制御を行うファイアウォールです。
ファイアウォール | セキュリティ | 通信 |
---|---|---|
パケットフィルタリング型 | バッファオーバーフロー攻撃*1やコンピュータウィルスが含まれる電子メールなどは防げない | 早い |
アプリケーションゲートウェイ型 | バッファオーバーフロー攻撃やコンピュータウィルスが含まれる電子メールなどは防げるが、なりすましは防げない | データまでチェックするので遅い |
アプリケーションゲートウェイ型ファイアウォールは、インターネットと内部のネットワークを切り離します。
インターネットからのパケットをアプリケーションゲートウェイが代理で受け取ります。
次回の勉強内容
パケットフィルタリング型ファイアウォールは、ネットワーク層でパケットのヘッダ情報でアクセス制御を行うファイアウォールです。
- 前回の勉強内容
- 勉強のきっかけになった問題
- パケットフィルタリング型ファイアウォールは、ネットワーク層でパケットのヘッダ情報でアクセス制御を行うファイアウォールです。
- パケットフィルタリング型ファイアウォールには、種類があります。
- 次回の勉強内容
前回の勉強内容
勉強のきっかけになった問題
ファイアウォールにおけるダイナミックパケットフィルタリングの特徴はどれか。
パケットフィルタリング型ファイアウォールは、ネットワーク層でパケットのヘッダ情報でアクセス制御を行うファイアウォールです。
パケットのヘッダ情報内のIPアドレス及びポート番号を基準にパケット通過の可否を決定します。
フィルタリングルールを用いて、本来必要なサービスに影響を及ぼすことなく外部に公開していないサービスへのアクセスを防げます。
社内ネットワークとインターネットの接続点にパケットフィルタリング型ファイアウォールを設置して,社内ネットワーク上のPCからインターネット上のWebサーバ(ポート番号80) にアクセスできるようにするとき,フィルタリングで許可するルールの適切な組合せはどれか。
平成23年特別問44 パケットフィルタリング|基本情報技術者試験.com
パケットフィルタリング型ファイアウォールには、種類があります。
Part2 フィルタリング---ファイアウォールの基本機能,フィルタリングの違いを理解する | 日経クロステック(xTECH)
スタティックパケットフィルタリングは、行きと戻りのヘッダ情報をフィルタリングテーブルに登録してアクセスを制御するファイアウォールです。
社内ネットワークとインターネットの接続点に,ステートフルインスペクション機能をもたない,静的なパケットフィルタリング型のファイアウォールを設置している。このネットワーク構成において,社内のPCからインターネット上のSMTPサーバに電子メールを送信できるようにするとき,ファイアウォールで通過を許可するTCPパケットのポート番号の組合せはどれか。ここで,SMTP通信には,デフォルトのポート番号を使うものとする。
(引用元)平成30年春期問44 パケットフィルタリングルール|基本情報技術者試験.com
ダイナミックパケットフィルタリングは、通信のやり取りを判断して動的にフィルタリングテーブルが更新するファイアウォールです。
- 英語: dynamic(動的な) packet filtering
戻りのパケットに関しては,過去に通過したリクエストパケットに対応したものだけを通過させることができます。
ステートフルパケットインスペクションは、出入りするパケットの通信状態を把握して外部から送信されたパケットのアクセスを動的に制御するファイアウォールです。
- 英語: Stateful(処理状態を把握す) Packet Inspection(検査)
- 略称: SPI
- 別名: ステートフルインスペクション、ステートファイアウォール
ダイナミックパケットフィルタリングの1つです。
パケットフィルタリングを拡張した方式であり,過去に通過したパケットから通信セッションを認識し,受け付けたパケットを通信セッションの状態に照らし合わせて通過させるか遮断させるかを判断します。
このファイアウォールはコンテキストの中でパケットを判断します。 コンテキストとは、文脈という意味で、この場合はプログラムが処理内容を置かれた状態や状況、 与えられた条件から判断するという意味です。
覚えておくべき4種のファイアウォール
個々のセッションごとに過去の通信を保持しているため「順序の矛盾した攻撃パケットを遮断することができる」ことや、常に最小限の許可ルールが追加されるため「アクセス制御リストの設定不備を突く攻撃を受けにくい」という優れた点があり、多くのファイアウォール製品に採用されています。
情報セキュリティスペシャリスト平成27年秋期 午前Ⅱ 問3