RSAのEncrypt/Decrypt で例外が出るときの対処
要約
RSACryptoServiceProvider
を使って Encrypt を呼び出した場合、文字列が長いと WindowsCryptographicException
が出る。(Decryptの場合は CryptographicException
) その場合は KeySize
と パディングから最大長を割り出してそのサイズ以下でブロック化し暗号化・復号化を行う必要がある。また、暗号化したブロックのサイズは復号化するときにわかるように情報を付与しておかないと復号化は難しそうだ。
基本的には非対称暗号で大きなデータを扱うのではなく、共通鍵暗号をデータの暗号化に使用し、共通鍵の暗号化にのみ非対称暗号を使用するのが良いようだ。
参考資料
RSACryptoServiceProvider.Encrypt メソッド (System.Security.Cryptography) | Microsoft Docs
【C#】文字列を指定した文字数で分割する拡張メソッド - コガネブログ
Convert.ToBase64String メソッド (System) | Microsoft Docs
PHPのmcrypt関数で使用する初期化ベクトル(IV)とは公開されて… - 人力検索はてな
コード(非対称暗号での暗号化)
MSTest を使用して暗号化・復号化のサンプルを作成した。 TestEncryptAndDecrypt3
が今回のキモの部分。今回はパディングを PKCS # 1 v 1.5
で行うため、rsa.KeySize
bit / 8 bit - 11 バイト = 117 バイトがブロック最大長となる。今回は暗号化したデータブロックを復号化サイドで判断できるようにするため、BASE64でエンコードし改行で区切ることでブロックを分割した。
using System; using System.Text; using System.Collections.Generic; using System.Security.Cryptography; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace EncryptTest { [TestClass] public class UnitTest1 { private string publicKey, privateKey; [TestInitialize] public void TestInit() { using (var rsa = new RSACryptoServiceProvider()) { publicKey = rsa.ToXmlString(false); privateKey = rsa.ToXmlString(true); } } [DataTestMethod] [DataRow("Hello World!!")] [DataRow("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")] public void TestEncryptAndDecrypt1(string rawString) { var rawBytes = Encoding.ASCII.GetBytes(rawString); byte[] encryptedBytes; using (var rsa = new RSACryptoServiceProvider()) { rsa.FromXmlString(publicKey); encryptedBytes = rsa.Encrypt(rawBytes, false); } string decryptedString; using (var rsa = new RSACryptoServiceProvider()) { byte[] decryptedBytes; rsa.FromXmlString(privateKey); decryptedBytes = rsa.Decrypt(encryptedBytes, false); decryptedString = Encoding.ASCII.GetString(decryptedBytes); } Assert.AreEqual(rawString, decryptedString); } [TestMethod] public void TestEncryptAndDecrypt2() { // 128 - 11 バイト (117 バイト) を超えると rsa.Encrypt() で例外が発生する。 var rawString = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; var rawBytes = Encoding.ASCII.GetBytes(rawString); using (var rsa = new RSACryptoServiceProvider()) { rsa.FromXmlString(publicKey); try { rsa.Encrypt(rawBytes, false); } catch (Exception e) { Assert.AreEqual("WindowsCryptographicException", e.GetType().Name); return; } Assert.Fail("This Test should be thrown exception."); } } [DataTestMethod] [DataRow("Hello World!!")] [DataRow("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")] [DataRow("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")] public void TestEncryptAndDecrypt3(string rawString) { string encryptedBase64String; using (var rsa = new RSACryptoServiceProvider()) { rsa.FromXmlString(publicKey); var count = (rsa.KeySize / 8) - 11; var splitStrings = new List<string>(); var length = (int)Math.Ceiling((double)rawString.Length / count); for (int i = 0; i < length; i++) { int start = count * i; if (rawString.Length <= start) { break; } if (rawString.Length < start + count) { splitStrings.Add(rawString.Substring(start)); } else { splitStrings.Add(rawString.Substring(start, count)); } } var sb = new StringBuilder(); foreach (var line in splitStrings) { var tempBytes = Encoding.ASCII.GetBytes(line); var tempEncBytes = rsa.Encrypt(tempBytes, false); sb.AppendLine(Convert.ToBase64String(tempEncBytes, 0, tempEncBytes.Length)); } encryptedBase64String = sb.ToString(); } var decryptedString = ""; using (var rsa = new RSACryptoServiceProvider()) { byte[] decryptedBytes; rsa.FromXmlString(privateKey); foreach(var line in encryptedBase64String.Split('\n')) { if (string.IsNullOrEmpty(line)) continue; var base64Bytes = Convert.FromBase64String(line); decryptedBytes = rsa.Decrypt(base64Bytes, false); decryptedString += Encoding.ASCII.GetString(decryptedBytes); } } Assert.AreEqual(rawString, decryptedString); } } }
コード(共通鍵暗号での暗号化)
さっきの例ではデータの暗号化に非対称暗号(RSA)を用いた。ただ、データが大きくなるにつれパフォーマンスの問題が出てくるらしい、なので、データの暗号化は共通鍵暗号を用い、共通鍵の暗号に非対称暗号を用いることで安全性・パフォーマンスの両面からカバーする。という方法が今の主流らしい。簡単に手順を示すと以下のようになる。
共通鍵受け渡しフロー
暗号化データ受け渡しフロー
- (B)は共通鍵でデータを暗号化
- (B)は暗号化されたデータをもう一方に受け渡す
- (A)は共通鍵で暗号化されたデータを復号化する
上記では便宜上データの暗号化を(B)で行っているが、共通鍵の受け渡しが終われば、データの暗号化はどちらが行っても問題なく行える。
以下、上記を実装したコードサンプルとなる。コード中の共通鍵のIVを平文で受け渡ししているが、暗号化・復号化が一回限りでIVを受け渡してすぐに行われるのであれば平文でもさほど問題ないようだ。(PHPのmcrypt関数で使用する初期化ベクトル(IV)とは公開されて… - 人力検索はてな)
using System; using System.IO; using System.Text; using System.Collections.Generic; using System.Security.Cryptography; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace AESTest { [TestClass] public class UnitTest1 { [DataTestMethod] [DataRow("Hello World!!")] [DataRow("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")] [DataRow("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")] public void TestEncryptAndDecrypt1(string rawString) { var decryptor = new Decryptor(); var encryptor = new Encryptor(); TransferCommonKey(encryptor, decryptor); byte[] iv, encryptedText; (iv, encryptedText) = encryptor.Encrypt(rawString); string decString; decString = decryptor.Decrypt(iv, encryptedText); Assert.AreEqual(rawString, decString); } private void TransferCommonKey(Encryptor encryptor, Decryptor decryptor) { string publicKey = decryptor.GetPublicKey(); byte[] encryptedCommonKey = encryptor.GenerateEncryptedCommonKey(publicKey); decryptor.TransferCommonKey(encryptedCommonKey); } } class Encryptor { byte[] commonKey; public byte[] GenerateEncryptedCommonKey(string publicKey) { var aes = Aes.Create(); commonKey = aes.Key; using var rsa = new RSACryptoServiceProvider(); rsa.FromXmlString(publicKey); return rsa.Encrypt(aes.Key, false); } public (byte[], byte[]) Encrypt(string text) { byte[] encrypted; var aes = Aes.Create(); using (var ms = new MemoryStream()) using (var cryptStream = new CryptoStream(ms, aes.CreateEncryptor(commonKey, aes.IV), CryptoStreamMode.Write)) { using (var sWriter = new StreamWriter(cryptStream)) { sWriter.Write(text); } encrypted = ms.ToArray(); } return (aes.IV, encrypted); } } class Decryptor { string publicKey, privateKey; byte[] commonKey; public Decryptor() { using var rsa = new RSACryptoServiceProvider(); publicKey = rsa.ToXmlString(false); privateKey = rsa.ToXmlString(true); } public string GetPublicKey() { return publicKey; } public void TransferCommonKey(byte[] encryptedCommonKey) { using var rsa = new RSACryptoServiceProvider(); rsa.FromXmlString(privateKey); commonKey = rsa.Decrypt(encryptedCommonKey, false); } public string Decrypt(byte[] iv, byte[] data) { var aes = Aes.Create(); using var ms = new MemoryStream(data); using var cryptStream = new CryptoStream(ms, aes.CreateDecryptor(commonKey, iv), CryptoStreamMode.Read); using var sReader = new StreamReader(cryptStream); return sReader.ReadLine(); } } }
プライベート認証局によるCA署名証明書の作成
参考資料
OpenSSL で認証局 (CA) を構築する手順 (Windows) - OpenSSL - Node.js 環境構築 - Node.js 入門
OpenSSL で構築した認証局 (CA) でサーバ証明書を発行する方法 - OpenSSL - Node.js 環境構築 - Node.js 入門
OpenSSL で構築した認証局 (CA) で発行したサーバ証明書を利用して HTTPS 通信する方法 - OpenSSL - Node.js 環境構築 - Node.js 入門
CAの証明書を作成
openssl の 設定ファイル
[ca] default_ca = ca_default [ca_default] dir = . certs = $dir/certs crl_dir = $dir/crl new_certs_dir = $dir/newcerts database = $dir/index.txt certificate = $dir/certs/cacert.crt serial = $dir/serial crlnumber = $dir/crlnumber crl = $dir/crl.pem private_key = $dir/private/caprivkey.key x509_extensions = usr_cert name_opt = ca_default cert_opt = ca_default default_days = 365 default_crl_days = 30 default_md = default preserve = no policy = policy_anything [ policy_anything ] countryName = optional stateOrProvinceName = optional localityName = optional organizationName = optional organizationalUnitName = optional commonName = supplied emailAddress = optional domainComponent = optional [req] prompt = no distinguished_name = dn [dn] CN = Root CA O = Root CA OU = Root CA L = localization ST = state C = JP [usr_cert] basicConstraints = CA:true,pathlen:0 nsComment = "OpenSSL Generated Certificate" extendedKeyUsage = serverAuth,clientAuth subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer subjectAltName = @alt_names [alt_names] URI=http://ca.example.com DNS.1=example.com
CAのプライベートキー作成
openssl genrsa -out caprivkey.key 2048
CAの証明書署名要求作成
openssl req -new -config ca.cnf -out cacert.csr -key caprivkey.key
証明書作成の前準備
mkdir newcerts touch index.txt echo 00 > serial
CAの証明書を自己署名証明書を作成
openssl ca -config ca.cnf -batch -extensions usr_cert -out cacert.crt -in cacert.csr -selfsign -keyfile caprivkey.key
CA署名証明書の作成
openssl の設定ファイル
CAの時とほぼ同じだが、basicConstraints
が違う。CAではないので、falseにする。
[ca] default_ca = ca_default [ca_default] dir = . certs = $dir/certs crl_dir = $dir/crl new_certs_dir = $dir/newcerts database = $dir/index.txt certificate = $dir/certs/cacert.crt serial = $dir/serial crlnumber = $dir/crlnumber crl = $dir/crl.pem private_key = $dir/private/caprivkey.key x509_extensions = usr_cert name_opt = ca_default cert_opt = ca_default default_days = 365 default_crl_days = 30 default_md = default preserve = no policy = policy_anything [ policy_anything ] countryName = optional stateOrProvinceName = optional localityName = optional organizationName = optional organizationalUnitName = optional commonName = supplied emailAddress = optional domainComponent = optional [req] prompt = no distinguished_name = dn [dn] CN = My Certificate ST = Japan C = JP [usr_cert] basicConstraints = CA:false nsComment = "OpenSSL Generated Certificate" extendedKeyUsage = serverAuth,clientAuth subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer subjectAltName = @alt_names [alt_names] URI=http://cert.example.com DNS.1=example.com
CA署名証明書を作成する前準備
mkdir private mv caprivkey.key private/caprivkey.key mkdir certs mv cacert.crt certs/cacert.crt
CA署名対象の秘密鍵の作成
openssl genrsa -out server.key 2048
証明書署名要求作成
openssl req -new -config cert.cnf -out server.csr -key server.key
CA署名証明書の作成
openssl ca -config cert.cnf -batch -extensions usr_cert -out server.crt -in server.csr
おまけ
証明書を PEM から DER に変換
openssl x509 -in server.crt -inform pem -out server.der -outform der
CRLを発行(空)
echo 00 > crlnumber openssl ca -gencrl -config ca.cnf -out crl.pem
CRLをPEMからDERに変換
openssl crl -in crl.pem -inform pem -out crl.crl -outform der
(C#) 並行処理キー入力まちプログラム
参考サイト
ポイント
CancellationTokenSource() でトークン作成して、トークンからキャンセル用トークンを生成して、それをすべての非同期タスクで共有して、キャンセルが起きた時の処理をタスクに書くってとこ。
今回は WaitKeyTask でしかキャンセルしてないけど、すべてのタスクで共有して、WaitKeyTaskともども Task.WaitAll() で待っておけば、どこからでもキャンセルできるようになると思う。
コード
using System; using System.Threading; using System.Threading.Tasks; using System.Collections.Generic; namespace ExampleOfWaitKey { class Program { static void Task1(CancellationToken token, string c, int duration) { while (true) { Console.Write(c); Task.Delay(duration).Wait(); if(token.IsCancellationRequested) { // WaitKeyTask() でキャンセルが発行されると // Task.Delay().Wait() 明けにこちらに落ちる // 終了に時間がかかるような処理の代わり var t = new Random().Next(1,10); Task.Delay(t * 100).Wait(); Console.WriteLine(); Console.WriteLine("{0}: was canceled", c); return; } } } static void WaitKeyTask(CancellationTokenSource tokenSource) { Console.ReadLine(); // キー入力まち tokenSource.Cancel(); // キャンセル通知 } static void Main(string[] args) { // キャンセル伝播用トークンの作成 var tokenSource = new CancellationTokenSource(); var cancelToken = tokenSource.Token; // キー入力待ち非同期タスクの実行 var waitKeyTask = Task.Run(() =>WaitKeyTask(tokenSource)); // 非同期処理タスクの実行 // var tasks = new List<Task>(); tasks.Add(Task.Run(() => Task1(cancelToken, "a", 100))); tasks.Add(Task.Run(() => Task1(cancelToken, "b", 200))); // キー入力待ち waitKeyTask.Wait(); Console.WriteLine(); Console.WriteLine("キーが押されました。"); Console.WriteLine("すべてのタスクが終了するのを待ちます..."); // 全タスクのキャンセル処理待ち Task.WaitAll(tasks.ToArray()); } } }
Vue.js 練習
これはなに?
私が Vue.js を練習した時の忘備録的記録です。詳しい内容が知りたいならオフィシャルのリファレンスを見たほうがよいです。日本語ですし。
経緯
最近 PHP でもやってみるかな、と思って始めたけど、テンプレートエンジンでいいのがなさそうだったので(というか、Smarty しかつかってないけど)、それなら Vue.js をフロントにしてみては? と思って使い始めてる。気に入らなかったらやめると思う。
ちなみにVue.js をPHPのフロントにする方法は以下のサイトに載ってます。
レガシー管理ページをちょっと動的にするためだけのVue.jsとPHP - Qiita
初めの一歩。Hello World
以下の html を サーバーに置くと Hello Vue!! と表示される。
<html> <head> <title></title> <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> </head> <body> <div id="app"> {{ message }} </div> <script type="text/javascript"> var v = new Vue({ el: "#app", data: { message: "Hello Vue!!" } }); </script> </body> </html>
<div id="app">
下の要素で {{ }}
でくくった部分を置き換える。というのが基本的な動作のようだ。
属性の動的生成
属性にデータを割り当てたいからと言って <a href="{{ link }}">test</a>
という書き方はできないらしい。その代わりに <a v-bind:href="link">test</a>
という書き方をする。 v-bind:
というプレフィックスを属性名につけることで値にデータ名が使えるようになる。下記の例では link
の部分が #app
に置き換わる。
<html> <head> <title></title> <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> </head> <body> <div id="app"> <a v-bind:href="link">test</a> </div> <script type="text/javascript"> var v1 = new Vue({ el: "#app", data: { link: "#app", } }); </script> </body> </html>
属性に式を指定して動的生成
さっきの例では バインドしている値はデータ名のみだが、値は式でもよい。以下の例では href="/sub_dir/"
となる。
<html> <head> <title></title> <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> </head> <body> <div id="app"> <a v-bind:href="link + '/'">test</a> </div> <script type="text/javascript"> var v1 = new Vue({ el: "#app", data: { link: "/sub_dir", } }); </script> </body> </html>
属性にメソッドを指定して動的生成
式だけではなくてメソッドも可能。オリジナルのメソッドだけではなく、組み込み関数も指定できる。例えば、<a v-bind:href="Math.abs(-100)">test</a>
とすると <a href="100">test</a>
が生成される。意味はない。
<html> <head> <title></title> <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> </head> <body> <div id="app"> <a v-bind:href="goto('/')">test</a> </div> <script type="text/javascript"> var v1 = new Vue({ el: "#app", methods: { goto: function(path) { return "/sub_dir" + path; } } }); </script> </body> </html>
コンポーネント
でもやっぱり、属性に式とか関数とか書きたくない。一回だけならまだいいけど、何回も書くとなるともうちょっと違う感じで書きたい。
コンポーネントは独自のノードを作成するための手法。
<html> <head> <title></title> <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> </head> <body> <div id="app"> <link_to uri="/"></link_to> </div> <script type="text/javascript"> Vue.component('link_to', { props: ['uri'], template: ` <a :href="uri">test</a> ` }) var v1 = new Vue({ el: "#app", }); </script> </body> </html>
こんな感じでかける。ただ、これだど直接書くのと変わらないのでコンポーネント側で関数や式を使って入力値(ここでは uri
) を修飾してあげるとよいかも。ただ、オリジナルのメソッドやデータをコンポーネント内で使いたい場合には以下の例のように this.$root.goto(uri)
のようにし、少し工夫する必要がある。何回も同じような記述をする場合はコンポーネントにまとめておくのがよさそうだ。
<html> <head> <title></title> <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> </head> <body> <div id="app"> <link_to uri="/"></link_to> </div> <script type="text/javascript"> Vue.component('link_to', { props: ['uri'], template: ` <a :href="this.$root.goto(uri)">test</a> ` }) var v1 = new Vue({ el: "#app", methods: { goto: function(uri) { return "/sub_dir" + uri; } } }); </script> </body> </html>
コンポーネントのネスト
先の例では、<a>
要素のテキストが test
固定になってしまって不便。props に足してもいいけど、HTMLっぽく書きたい場合もある。そういう場合は <slot>
を使う。
<html> <head> <title></title> <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> </head> <body> <div id="app"> <link_to uri="/">test</link_to> </div> <script type="text/javascript"> Vue.component('link_to', { props: ['uri'], template: ` <a :href="this.$root.goto(uri)"><slot></slot></a> ` }) var v1 = new Vue({ el: "#app", methods: { goto: function(uri) { return "/sub_dir" + uri; } } }); </script> </body> </html>
おわり
おわり。
ディスクのパーティションを変更後、Linuxの起動が遅った問題
あらすじ
Virtual Box で初回 10GBで仮想ディスクを組んでしまい、途中で空き容量不足でLinuxが固まる問題が発生したので、仮想ディスク容量を拡張したが、パーティション設定が以前のままで、拡張部分が使えず結局空き容量不足という状態だった。KNOPPIXを入れて、gpartedにてパーティション設定を変更し、再度起動すると空き容量の問題は解決したが、起動時にジャーナルの再チェックが必ず入るようになり、1分30秒待たされることになった。
参考サイト
起動で1分半待たされる問題の解決法! | ウィンドウズにおさらばした文系中高年
原因
パーティション設定を変更したことで、スワップのUUIDが更新されてしまい、/etc/fstab のUUIDと違うことでLinuxが異常を検知してしまい、起動時にディスクチェックが走ってしまうのが問題のようです。
復旧方法
- blkid コマンドでUUIDをチェック
$ sudo blkid
- 表示されたUUIDを /etc/fstab に反映
$ sudo vim /etc/fstab
- 起動時に「gave up waiting for suspend/resume device」が出る場合は /etc/initramfs-tools/conf.d/resumeも更新する
$ sudo vim /etc/initramfs-tools/conf.d/resume $ sudo update-initramfs -u
以上!!
オレオレ証明書(自己著名証明書) DER ファイル作成 (サブジェクト代替名付き)
参考サイト
オレオレSSL証明書(自己署名証明書)を作るワンライナー
https://www.karakaram.com/creating-self-signed-certificate/SAN(Subject Alternative Name) のオレオレ証明書
https://qiita.com/nis_nagaid_1984/items/b8f87d41ea108d47af61OpenSSLコマンドの備忘録
https://qiita.com/takech9203/items/5206f8e2572e95209bbc
作成手順
秘密鍵を作成
$ openssl genrsa 2048 > server.key
証明書署名要求を作成
$ openssl req -new -key server.key > server.csr
自己署名証明書を作成
san.txt
という名前でSubject Alternative Name(サブジェクト代替名)の設定を記載
subjectAltName = URI:hoge.com, DNS:fuga.com
-extfile
オプションを使って SANを指定しつつ自己著名証明書を作成
$ openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt -extfile san.txt
DERファイルの作成
$ openssl x509 -inform pem -outform der -in server.crt -out cacert.der
DERファイルの中身を見たい場合
$ openssl x509 -inform der -text < cacert.der
AWS EC2 nginx + php + postgresql
参考サイト
EC2(Amazon-Linux-2)にNginxを入れてブラウザで確認するまで2018冬 [画像で解説] インスタンス編
https://qiita.com/ymzk-jp/items/ef9203a9b9f8ce5d34afEC2(Amazon-Linux-2)にNginxを入れてブラウザで確認するまで2018冬 [画像で解説] Nginx編
https://qiita.com/ymzk-jp/items/49daf14495ba090b3187Windows10 の ssh を使った AWS EC2 への接続
https://qiita.com/uttne/items/7bfa4e820834f7f54be8AWSのEC2で行うAmazon Linux2(nginx・php-fpm)環境構築
https://qiita.com/2no553/items/968068b1752ea6154beb
↑ phpinfo.php を作成した後、sudo systemctl restart nginx
すること。
- PostgreSQL データベースを作成、接続する(Amazon RDSを使用します)
https://aws.amazon.com/jp/getting-started/hands-on/create-connect-postgresql-db/
【詰まったこと】EC2側からRDS側にアクセスできなくて困った
RDS側のセキュリティグループのインバウンドルールにルールを追加するといけた。追加するのは、ソースにEC2側のセキュリティグループを足せばいい。
【プチ詰まり】psql の指定の方法がわからなかった
- PostgreSQL DB インスタンスを作成して PostgreSQL DB インスタンスのデータベースに接続する
https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/CHAP_GettingStarted.CreatingConnecting.PostgreSQL.html
$ psql --host=DB_instance_endpoint --port=port --username=master_user_name --password --dbname=database_name
こんな感じでいけるっぽい。
【プチ詰まり】pdo_pgsql がない
- Amazon Linux 2にPHP7.3とPostgreSQL12をインストールする
https://qiita.com/atmitani/items/152f1d083146afe1e60b
上の記事にあるように yum
でインストールしてあげる必要がある。
yum install -y php-devel yum install -y php-gd yum install -y php-intl yum install -y php-json yum install -y php-mbstring yum install -y php-mcrypt yum install -y php-pdo yum install -y php-pgsql
【プチ詰まり】php の PDO でエラーが出る
Error :SQLSTATE[08006] [7] could not translate host name "***.rds.amazonaws.com" to address: Name or service not known
こんなエラーがでる。
→ 【解決】単純にURL間違ってた。。。
- AWS EC2 AmazonLinux2 Gitをインストールする
https://qiita.com/miriwo/items/8d5b35950232c1126d36
【プチ詰まり】composer のパス
/usr/local/bin/composer がパスなので、root だと実行パスにない状態となる。 root では /usr/local/bin/composer を指定すること。
【プチ詰まり】.env を導入したい
- PHP dotenvの読み込み方が変わってた
https://qiita.com/sngazm/items/d27639f54e0abe723da9
【小ネタ】
- Linuxでターミナルのカーソルが消えた場合の対処法
https://applingo.tokyo/article/7268
【プチ詰まり】sessionが機能しない
色々みてると、ファイルに権限がないことが原因だった。
- (小ネタ)session.save_pathの調べ方
https://qiita.com/cranpun/items/02eaa615c523aac8f375
Amazon Linux 2 の場合は /var/lib/php/session
になってた。ただ、グループが apache になってたので、 nginx に変更したら動いた。