ElastiCache(Redis)へRuby on RailsでTLS接続方法のメモ
ElastiCache(Redis)で認証(Redis auth)設定を構成する場合、Redisへの通信暗号化が前提となります。
1. redis-cli での接続確認
redis-cliは、通信暗号化機能が実装されていないため、stunnelを使用した疎通・接続確認が可能です。
Amazon ElastiCache の転送時の暗号化が有効化された Redis ノードへの接続に redis-cli を使用するにはどうすればよいですか? redis-cli を使用して送信中の暗号化を有効にした Redis 用 Amazon ElastiCache ノードへの接続
2. Rails consoleを使用した接続確認
[前提環境] Rails ClientがLinuxへ導入済みであること
$ ruby -v ruby 2.6.6p146 (2020-03-31 revision 67876) [x86_64-linux] $ gem -v 3.0.3 $ rails -v Rails 5.2.4.3 $ gem list redis *** LOCAL GEMS *** redis (4.2.1) redis-actionpack (5.2.0) redis-activesupport (5.2.0) redis-rack (2.1.3) redis-rails (5.0.2) redis-store (1.9.0) redis-store-testing (0.0.2)
[通常時との差異]
Redisオブジェクト作成時のurlを"rediss://"にします。
(url: 'rediss://<パスワード>@
$ rails c Loading development environment (Rails 5.2.4.3) irb(main):001:0> redis = Redis.new(url: 'rediss://:This-is-a-sample-token@master.xxxxxxxxx.xxxxx.apne1.cache.amazonaws.com:6379/0') => #<Redis client v4.2.1 for redis://master.xxxxxx.xxxxxx.apne1.cache.amazonaws.com:6379/0> irb(main):002:0> redis.set "mykeyid0002", "123456789abcdefg" => "OK" irb(main):003:0> redis.keys => ["mykeyid0002", "keyid1111", "mykeyid0001", "hoge"]
参考情報 Support of encryption when using Redis from Amazon ElastiCache
3. Rails session_store使用時の設定、接続/検証コマンド
Ruby on Railsサンプル簡易アプリをrails newで作成して、session_storeを用いたセッション管理をElastiCacheに格納するため以下session_store.rbを作成。
config/initializers/session_store.rb
<ApplicationName>::Application.config.session_store :redis_store, { servers: [ { host: "master.xxxxxx.xxxxxx.apne1.cache.amazonaws.com", xxx# EndPoint FQDN port: 6379, # Port db: 0, password: "this-is-a-test-token", # Radis auth token (password) ssl: true, # ssl enable namespace: "session" }, ], expire_after: 90.minutes }
rails s -b でアプリケーションを起動し、ブラウザからアクセスする。
$ rails s -b 10.0.X.XXX => Booting Puma => Rails 5.2.4.4 application starting in development => Run `rails server -h` for more startup options Puma starting in single mode... * Version 3.12.6 (ruby 2.6.6-p146), codename: Llamas in Pajamas * Min threads: 5, max threads: 5 * Environment: development * Listening on tcp://10.0.X.XXX:3000 Use Ctrl-C to stop
Rails ConsoleでElastiChacheにセッション情報が格納されているか確認する。
$ rails c Running via Spring preloader in process 16498 Loading development environment (Rails 5.2.4.4) irb(main):001:0> redis = Redis.new(url: 'rediss://:This-is-a-sample-token@master.XXXXXX.XXXXX.apne1.cache.amazonaws.com:6379/0') => #<Redis client v4.2.1 for redis://master.rXXXXX.XXXXXX.apne1.cache.amazonaws.com:6379/0> irb(main):002:0> redis.keys => ["session:2::11bd96f4315c95ef2b216bcf4e2807a056efdb2143735d41bb3f2c2ae689c247"] ← Session情報Key irb(main):003:0> redis.get "session:2::11bd96f4315c95ef2b216bcf4e2807a056efdb2143735d41bb3f2c2ae689c247" => "\u0004\b{\u0006I\"\u0010_csrf_token\u0006:\u0006EFI\"1fRkIT2faQQxor1sqNiRaDCp6l3G2eEsKR2XA8ImG2ZI=\u0006;\u0000F" ↑ Session情報 # 他クライアントからRailsアプリケーションへアクセス irb(main):004:0> redis.keys => ["session:2::19177af23f6ec49087bf08ca78deda97d7dd7f884d8b77f367df6d7599b4350a", "session:2::11bd96f4315c95ef2b216bcf4e2807a056efdb2143735d41bb3f2c2ae689c247"] ↑ Session情報Keyが追加された irb(main):005:0>
以上
ElastiCache(Redisクラスターモード無効/有効)への接続確認手順メモ
AWSからクライアントライブラリ提供はしておりません。大変申し訳ございません。 (以下資料のP.20参照) [AWS Black Belt Online Seminar 2017 Amazon ElastiCache] (https://d1.awsstatic.com/webinars/jp/pdf/services/20171214_AWS-Blackbelt-ElastiCache.pdf)
ただし、 "Redis 用 Amazon ElastiCache は、オープンソース Redis のデータ形式および Redis API との互換性を備えており、Redis クライアントとの連携が可能です。コードを変更することなく、自己管理型の Redis ワークロードを Redis 用 ElastiCache に移行できます。" Redis 互換 上記記載からオープンソースRedisに準拠したライブラリであれば使用可能かと思います。
Github: redis-rails Usage with Redis Cluster
ElastiCache(Redisサーバ)
ElastiCacheクラスタ名 | モード | シャード数 | ノード数 |
---|---|---|---|
rediscluster | Clustered Redis | 3 | 7 |
redisnoncluster | Redis ReadReplica | 1 | 2 |
Rails Client (AmazonLinux 2)
$ ruby -v ruby 2.6.6p146 (2020-03-31 revision 67876) [x86_64-linux] $ gem -v 3.0.3 $ rails -v Rails 5.2.4.3 $ gem list redis *** LOCAL GEMS *** redis (4.2.1) redis-actionpack (5.2.0) redis-activesupport (5.2.0) redis-rack (2.1.3) redis-rails (5.0.2) redis-store (1.9.0) redis-store-testing (0.0.2)
Redisクラスターモード無効
$ rails c Loading development environment (Rails 5.2.4.3) irb(main):001:0> redis = Redis.new(url: 'redis://xxxxxxxxxx.xxxxx.ng.0001.apne1.cache.amazonaws.com:6379/0') => #<Redis client v4.2.1 for redis://xxxxxxxxxx.xxxxx.ng.0001.apne1.cache.amazonaws.com:6379/0> irb(main):002:0> redis.flushdb <--- データ削除 => "OK" irb(main):003:0> redis.keys <--- データ削除確認 => [] irb(main):004:0> redis.set "mykeyid0001", "123456789abcdefg" <--- データSET => "OK" irb(main):005:0> redis.keys <--- Key一覧確認 => ["mykeyid0001"] irb(main):006:0> redis.get "mykeyid0001" <--- データGET => "123456789abcdefg"
Redisクラスターモード有効
$ rails c Loading development environment (Rails 5.2.4.3) irb(main):001:0> redis = Redis.new(cluster: %w[ **redis://xxxxxxxxxx.xxxxx.apne1.cache.amazonaws.com** :6379]) => #<Redis client v4.2.1 for **redis://10.0.XXX.XXX:6379/0 redis://10.0.XXX.XXX:6379/0 redis://10.0.XXX.XXX:6379/0** > irb(main):002:0> redis.flushdb <--- データ削除 => "OK" irb(main):003:0> redis.keys <--- データ削除確認 => [] irb(main):004:0> redis.set "mykeyid0001", "123456789abcdefg" <--- データSET => "OK" irb(main):005:0> redis.keys <--- Key一覧確認 => ["mykeyid0001"] irb(main):006:0> redis.get "mykeyid0001" <--- データGET => "123456789abcdefg" irb(main):007:0> redis.set "mykeyid0002", "123456789abcdefg" <--- 異なるKeyでデータSET => "OK" irb(main):008:0> redis.set "mykeyid0003", "aaaaaaaaaaaaa" <--- 異なるKeyでデータSET => "OK" irb(main):009:0> redis.set "mykeyid0004", "bbbbbbbbbbbb" <--- 異なるKeyでデータSET => "OK" irb(main):010:0> redis.get "mykeyid0003" => "aaaaaaaaaaaaa" irb(main):011:0> redis.keys => ["mykeyid0001", "mykeyid0002", "mykeyid0003", "mykeyid0004"] <--- Key一覧確認 (略) # 各ノード別接続してデータ分散されているか確認 $ rails c Loading development environment (Rails 5.2.4.3) # Cluster へ接続してKeyリスト取得 irb(main):001:0> redis = Redis.new(cluster: %w[redis://xxxxxxxxxxxx.xxxxxxx.apne1.cache.amazonaws.com:6379]) => #<Redis client v4.2.1 for redis://10.0.XXX.XXX:6379/0 redis://10.0.XXX.XXX:6379/0 redis://10.0.XXX.XXX:6379/0> irb(main):002:0> redis.keys => ["keyid0001", "keyid1001", "keyid1002", "keyid1003", "keyid1332", "keyid1333", "mykeyid0001", "mykeyid0002", "mykeyid0003", "mykeyid0004", "sessionid0001", "sessionid0002", "sessionid0003", "sessionid0004", "sessionid1111", "sessionid1112"] # Keyのハッシュ値をもとにシャード毎にデータ格納されているか確認 # node0001-001(シャード1) irb(main):001:0> redis = Redis.new(url: 'redis://xxxxxxxxxx.xxxxxxxxxxx.apne1.cache.amazonaws.com:6379/0') => #<Redis client v4.2.1 for redis://xxxxxxxxxxxxx-0001-001.eyz6sy.0001.apne1.cache.amazonaws.com:6379/0> irb(main):002:0> redis.keys => ["sessionid1112", "sessionid0001", "mykeyid0002", "mykeyid0003", "keyid0001", "keyid1333", "keyid1332", "keyid1002"] # node0002-001(シャード2) irb(main):001:0> redis = Redis.new(url: 'redis://xxxxxxxxxxxxx-0002-001.eyz6sy.0001.apne1.cache.amazonaws.com:6379/0') => #<Redis client v4.2.1 for redis://rxxxxxxxxxxxxx-0002-001.eyz6sy.0001.apne1.cache.amazonaws.com:6379/0> irb(main):002:0> redis.keys => ["sessionid0003", "sessionid1111", "sessionid0002", "keyid1001", "mykeyid0004"] # node0003-001(シャード3) irb(main):001:0> redis = Redis.new(url: 'redis://xxxxxxxxxxxxxr-0003-001.eyz6sy.0001.apne1.cache.amazonaws.com:6379/0') => #<Redis client v4.2.1 for redis://xxxxxxxxxxxxx-0003-001.eyz6sy.0001.apne1.cache.amazonaws.com:6379/0> irb(main):002:0> redis.keys => ["sessionid0004", "keyid1003", "mykeyid0001"]
PCからAWS Systems Manager 経由で SSH トンネルを使用してプライベート VPCのEC2へログイン
参考URL AWS Systems Manager 経由で SSH トンネルを使用してプライベート VPC リソースにアクセスしたいと考えています。どうすればよいですか?
前提条件
- ローカルマシンの Session Manager プラグイン v1.1.23 以降が導入済み。
- ローカルマシンの AWS コマンドラインインターフェイス (CLI) v1.16.12 以降が導入済み。
- (オプション)jqコマンドが使えると便利です。
Windowsでjqコマンドをインストールしてコマンドプロンプトで使う方法。その他OSへのインストール方法まとめ。
事前準備 AWS SSOログインのURL (ex) https://d-XXXXXXXX.awsapps.com/start
AWS CLI 導入ガイド macOS での AWS CLI バージョン 2 のインストール、更新、アンインストール Windows での AWS CLI バージョン 2 のインストール、更新、アンインストール
Session Managerプラグイン導入ガイド (オプション) AWS CLI 用の Session Manager plugin をインストールする
SSO ユーザで ローカルPC AWS CLI 実行手順 (任意のTerminalSoftを使用ください。WindowsはPowerShellまたは、Windows Terminalで使用可能です)
以下手順はWindows Treminal(PowerShell)の例となります。基本的にはMac、WSLのTerminalも同様です。
1. AWS シングルサインオン を使用するための AWS CLI の設定
# AWS SSO を使用するための名前付きプロファイルの設定 PS C:> aws --version aws-cli/2.0.61 Python/3.7.7 Windows/10 exe/AMD64 PS C:> aws configure sso SSO start URL [None]: https://d-95671852ef.awsapps.com/start SSO Region [None]: ap-northeast-1 Attempting to automatically open the SSO authorization page in your default browser. If the browser does not open or you wish to use a different device to authorize this request, open the following URL: https://device.sso.ap-northeast-1.amazonaws.com/ Then enter the code: XXXX-WWWW There are 6 AWS accounts available to you. : :
SSO画面に登録されているAWSアカウントがリストされます。ログインしたいAWSアカウントを選択します。
ブラウザが起動し、「Sing into AWS CLI」ボタンをクリックします。
SSOログイン画面が表示されます。ログインします。
Treminalに戻ります。
## Profileを設定します。profile name は任意です。 Using the account ID 682167675618 The only role available to you is: AdministratorAccess Using the role name "AdministratorAccess" CLI default client Region [None]: ap-northeast-1 CLI default output format [None]: json CLI profile name [AdministratorAccess-682167675618]: poc To use this profile, specify the profile name using --profile, as shown: aws s3 ls --profile poc PS C:> ## AWS CLI 確認 (S3 backet 一覧表示) PS C:> aws s3 ls --profile poc 2020-10-30 15:44:29 XXXXXX1 2020-09-10 11:22:23 XXXXXX2 2020-10-28 21:34:29 XXXXXX3 2020-11-02 21:52:42 XXXXXX4 2020-10-30 15:53:02 imageXXXXXXXX 2020-10-23 23:40:06 imageXXXXYYYY 2020-10-23 09:53:50 imageYYYYYYYY 2020-10-24 13:11:18 imageXXXXXXXX 2020-10-27 15:28:30 imageZZZZZZZZ PS C:> ## ローカルPCでIAM権限に応じたAWS CLI(--profile 付与)を実行することが可能です。
2. SSMセッションマネージャー経由でのEC2ログイン手順
参考 ステップ 8: (オプション) Session Manager を通して SSH 接続を有効にする
「.ssh/config」 の設定例
# SSH over Session Manager host i-* mi-* ProxyCommand sh -c "aws ssm start-session --profile ${profile} --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'"
AWS CLIでEC2インスタンスのinstance-id取得
## Instance-ID 取得 $ aws ec2 describe-instances --profile poc | jq '.Reservations[].Instances[] | {InstanceId, InstanceName: (.Tags[] | select(.K ey=="Name").Value)}' : { "InstanceId": "i-015XXXXXXXXXXXX", "InstanceName": "CentOS" } : ## インスタンス起動確認 $ aws ec2 describe-instance-status --instance-ids i-015XXXXXXXXXXXX --profile poc| jq '.InstanceStatuses[] | {InstanceId, In stanceState: .InstanceState.Name, SystemStatus: .SystemStatus.Status, InstanceStatus: .InstanceStatus.Status}' { "InstanceId": "i-015XXXXXXXXXXXX", "InstanceState": "running", "SystemStatus": "ok", "InstanceStatus": "ok" }
EC2(CentOS7)へssh接続
$ export profile="poc" ssh <user>@<instance-id> -i <秘密鍵> $ ssh centos@i-015XXXXXXXXXXXX -i .ssh/aEC2.pem Last login: Wed Nov 4 07:51:36 2020 from localhost [centos@ip- ~]$ [centos@ip- ~]$ who centos pts/0 Nov 5 04:57 (localhost)
一般サイト SCP でファイル転送 ポートフォワードしてプライベートサブネットのRDS接続
(参考情報) AWS CLI でインスタンス停止
## インスタンス停止 $ aws ec2 stop-instances --profile poc --instance-ids i-015b2XXXXXXXXXX { "StoppingInstances": [ { "CurrentState": { "Code": 64, "Name": "stopping" }, "InstanceId": "i-015b2XXXXXXXXXXX", "PreviousState": { "Code": 16, "Name": "running" } } ] } ## 停止確認 $ aws ec2 describe-instances --profile poc --instance-ids i-015b2XXXXXXXXXX | jq '.Reservations[].Instances[] | {InstanceId, InstanceState: .State.Name}' { "InstanceId": "i-015b2XXXXXXXXXXXXX", "InstanceState": "stopped" }
AWS Systems ManagerのRunCommand機能でChef実行メモ
前提確認
- 対象EC2のOSにSSM Agentが導入済みでssm-userがsudo可能な構成
- 対象EC2のIAMロールに"AmazonS3ReadOnlyAccess"などS3読取権限が付与されアクセス可能
Chef Cookbook配置用のS3 Bucketを東京リージョンへ作成
(例) cookbook20200923 など
S3 BucketのBucket Policyの設定
SystemsManagerでS3のCookbookを指定する際、オブジェクトURLでの指定となるためBucket Policyを指定します。 以下VPCからアクセス可能なBucket Policyの設定例です。 [S3] -> [cookbook20200923] -> [アクセス権限タブ] -> [バケットポリシー]
{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowGetObjectFromVPC", "Effect": "Allow", "Principal": "*", "Action": "s3:*", "Resource": [ "arn:aws:s3:::cookbook20200923/*", ← 作成したBucket名 "arn:aws:s3:::cookbook20200923" ], "Condition": { "StringLike": { "aws:SourceVpc": "vpc-XXXXXXXXXXXX" ← アクセスするVPC名 } } } ] }
Chef Cookbookの配置
適用したいCookbookをtar+gzコマンドでアーカイブし、1で作成したS3 Bucketへ配置する。
# ls -l cookbooks/ total 0 drwxr-xr-x 6 root root 168 Sep 16 03:36 httpd_centos drwxr-xr-x 6 root root 168 Sep 16 03:36 httpd_install # tar zcvf cookbooks20200923.tar.gz ./cookbooks (略) # ls -l cookbooks20200923.tar.gz -rw-r--r-- 1 root root 14044 Sep 23 05:04 cookbooks20200923.tar.gz ←このファイルを1で作成したS3 BucketへUPLOADしてください。
AWS Systems ManagerでのChef実行例
S3 Bucketに配置したCookbookファイルのオブジェクトURL確認
AWS Systems Managerのrun command実行
AWS Systems Managerのrun command実行(AWS-ApplyChefRecipes)
AWS Systems Managerのrun command実行結果
ElastiCache(Redis)でAUTH構成時のRails TLS接続確認方法について
ElastiCache(Redis)で認証(Redis auth)設定を構成する場合、Redisへの通信暗号化が前提となります。
Redis-Authと通信暗号化 構成時の接続確認方法について記載させて頂きます。
1. redis-cli での接続確認
redis-cliは、通信暗号化機能が実装されていないため、stunnelを使用した疎通・接続確認が可能です。
Amazon ElastiCache の転送時の暗号化が有効化された Redis ノードへの接続に redis-cli を使用するにはどうすればよいですか?
redis-cli を使用して送信中の暗号化を有効にした Redis 用 Amazon ElastiCache ノードへの接続
2. [参考情報] rails consoleを使用した接続確認
環境
Rails Client (AmazonLinux 2)
$ ruby -v ruby 2.6.6p146 (2020-03-31 revision 67876) [x86_64-linux] $ gem -v 3.0.3 $ rails -v Rails 5.2.4.3 $ gem list redis *** LOCAL GEMS *** redis (4.2.1) redis-actionpack (5.2.0) redis-activesupport (5.2.0) redis-rack (2.1.3) redis-rails (5.0.2) redis-store (1.9.0) redis-store-testing (0.0.2)
rails consoleでの接続/検証コマンド
Redisオブジェクト作成時のurlを"rediss://"にします。
(url: 'rediss://<パスワード>>@
$ rails c Loading development environment (Rails 5.2.4.3) irb(main):001:0> redis = Redis.new(url: 'rediss://:This-is-a-sample-token@master.xxxxxxxx.yyyyy.apne1.cache.amazonaws.com:6379/0') => #<Redis client v4.2.1 for redis://master.xxxxxxxxx.yyyyy.apne1.cache.amazonaws.com:6379/0> irb(main):002:0> redis.set "mykeyid0002", "123456789abcdefg" => "OK" irb(main):003:0> redis.keys => ["mykeyid0002", "keyid1111", "mykeyid0001", "hoge"]
参考情報 Support of encryption when using Redis from Amazon ElastiCache
3. [参考情報] Rails session_store使用時の設定、接続/検証コマンド
Ruby on Railsサンプル簡易アプリをrails newで作成。 session_storeを用いたセッション管理をElastiCacheに格納するため以下session_store.rbを作成。
config/initializers/session_store.rb
<ApplicationName>::Application.config.session_store :redis_store, { servers: [ { host: "master.xxxxxx.yyyyyy.apne1.cache.amazonaws.com", # EndPoint FQDN port: 6379, # Port db: 0, password: "this-is-a-test-token", # auth token (password) ssl: true, # ssl enable namespace: "session" }, ], expire_after: 90.minutes }
rails s -b
$ rails s -b 10.0.X.X => Booting Puma => Rails 5.2.4.4 application starting in development => Run `rails server -h` for more startup options Puma starting in single mode... * Version 3.12.6 (ruby 2.6.6-p146), codename: Llamas in Pajamas * Min threads: 5, max threads: 5 * Environment: development * Listening on tcp://10.0.X.X:3000 Use Ctrl-C to stop
ElastiChacheにセッション情報が格納されているか確認。
$ rails c Running via Spring preloader in process 16498 Loading development environment (Rails 5.2.4.4) irb(main):001:0> redis = Redis.new(url: 'rediss://:This-is-a-sample-token@master.xxxxxx.yyyyyy.apne1.cache.amazonaws.com:6379/0') => #<Redis client v4.2.1 for redis://master.xxxxx.yyyyy.apne1.cache.amazonaws.com:6379/0> irb(main):002:0> redis.keys => ["session:2::11bd96f4315c95ef2b216bcf4e2807a056efdb2143735d41bb3f2c2ae689c247"] # Session情報Key irb(main):003:0> redis.get "session:2::11bd96f4315c95ef2b216bcf4e2807a056efdb2143735d41bb3f2c2ae689c247" => "\u0004\b{\u0006I\"\u0010_csrf_token\u0006:\u0006EFI\"1fRkIT2faQQxor1sqNiRaDCp6l3G2eEsKR2XA8ImG2ZI=\u0006;\u0000F" # Session情報 ### 他クライアントからRailsアプリケーションへアクセス irb(main):004:0> redis.keys => ["session:2::19177af23f6ec49087bf08ca78deda97d7dd7f884d8b77f367df6d7599b4350a", "session:2::11bd96f4315c95ef2b216bcf4e2807a056efdb2143735d41bb3f2c2ae689c247"] # Session情報Keyが追加された irb(main):005:0>
参考情報 Support of encryption when using Redis from Amazon ElastiCache
NLB経由でPrivateSubnetへvsFTPdを構成メモ
NLB経由でFTPサーバをPrivateSubnetに配置構成メモ
参考:
[AWS] NLB経由でFTP接続する際の注意点 - Qiita
How to run an FTPS server behind the AWS Network Load Balancer | by Michael Kirk | Medium
構成したアーキテクチャ図
1. /etc/vsftpd/vsftpd.conf の設定
/etc/vsftpd/vsftpd.conf
anonymous_enable=NO
local_enable=YES
write_enable=YES
local_umask=022
dirmessage_enable=NO
xferlog_enable=YES
connect_from_port_20=NO
xferlog_std_format=NO
ascii_upload_enable=YES
ascii_download_enable=YES
listen=YES
listen_ipv6=NO
pasv_enable=YES
pasv_addr_resolve=YES
pasv_address=[ NLBのFQDN .amazonaws.com]
pasv_promiscuous=NO
pasv_min_port=60001 ←データ転送用ポート範囲指定(同時接続可能数)
pasv_max_port=60002 ←データ転送用ポート範囲指定
use_localtime=YES
userlist_deny=NO
pam_service_name=vsftpd
userlist_enable=YES
tcp_wrappers=NO
force_dot_files=YES
2. NLB用ターゲットグループ設定
NLB用ターゲットグループは、制御ポート用、データ転送ポート用(pasv_min_port~pasv_max_port) を作成する。
データ転送ポート用(pasv_min_port~pasv_max_port) ターゲットグループ作成時は、HealthCheck項目のportをOverride選択して21にすることを忘れないようにします。
3. NLB作成
NLB作成は、以下のように制御用ポート、データ転送用ポート(2.で作成したターゲットグループを指定)を作成する