C# Reflection DataTableをListに代入

DataGridViewのDataSourceにList<Model>を渡すとき、DataTableからList<Model>に代入をReflectionで作ってみる。普段はそのまま名前を書いてしまうことも多い。

 

SSL/TLS メモ

SSL/TLSは分かりづらいのでメモ

●SSLとTLS
Secure Sockets Layer
Transport Layer Security

SSLは既に廃止、プロトコルとしてはTLSのみ。呼称としてのみSSL。

●公開鍵暗号
公開鍵は暗号化
秘密鍵は復号化、公開鍵の生成。
※秘密鍵で暗号化というのは考えない。

●バージョン

Chromeデベロッパーツール>セキュリティ

●SSL/TLS

・サーバーは認証局に証明書を発行してもらう
CSRを認証局でハッシュ化し、それを署名生成鍵(秘密鍵)で暗号化。
CSR+暗号化されたハッシュ=署名済証明書

・サーバーに署名済証明書をインストール

※以下ハンドシェイク(TLSのバージョンによって違う)

・共通鍵生成
お互い、非公開パラメータと公開パラメータを生成し、公開パラメータを相手に送る。

・サーバーはクライアントに署名済証明書(中間CA証明書なども)を送付

・クライアントは署名済証明書に改ざんがないか検証
署名済証明書を検証鍵(公開鍵)で復号化し、CSRから計算したハッシュと、
復号化したハッシュを比較する。
※検証鍵はOS/ブラウザにインストールされている

GCP Cloud SQL(MySQL) 使い方

先日VPS(Indigo)のSQLite→MySQLの実験を行ってみたが、GCPでもやってみることにした。

初期設定

Cloud SQL 無料トライアルを実行する。
(既にクレジット等の情報は登録済みなのでそのまま完了)

コンソールにログイン>左側メニューのSQLを選択。
プロジェクト(すでにMyFirstProjectが存在している)をクリック。
インスタンスを作成をクリック。
MySQLをクリック。

インスタンスID、rootパスワードを入力する。
無料トライアルだが、実際運用を始めれば安く利用したいので、
asia-northeast1(東京)/db-f1-micro
SSD/10GB
自動バックアップしない
を選択する。インスタンス生成には少し時間がかかる。

・インスタンス作成後

コンソールにログイン>左側メニューのSQLを選択。
作成したインスタンスを選択。

左側メニューの接続を選択。
SSL接続のみ許可をクリック。
クライアント証明書を作成をクリックし、一意のIDを追加し作成。

・サーバー証明書:server-ca.pem
・クライアントの公開鍵証明書:client-cert.pem
・クライアント秘密鍵:client-key.pem
という3つのファイルをダウンロードする。

同じく左側メニューの接続から、ネットワークを追加をクリック。
ネットワークの項目:0.0.0.0/0
を追加し完了>保存を実行。

左側メニューの概要を選択、パブリックIPアドレスを確認。

MySQL Wokbenchから接続

Standard TCP/IPを選択。

・Parametersタブ
Hostname:パブリックIPアドレス
Port:3306
Username:DBユーザー名(root、app_user等)
パスワード:DBパスワード

・SSLタブ
Use SSL:Require and Verify CA
SSL Key File, SSL CERT File, SSL CA File
それぞれ、ダウンロードしたファイルを選択。
※登録後ファイルのパス変更(移動)できないので注意。

とりあえずこれでつながる。

C#(MySqlConnection)から接続

.Netではpemが使えないため、
(https://dev.mysql.com/doc/connector-net/en/connector-net-tutorials-ssl-pfx.html)
opensslのある環境上で(今回はVPSで)実行

openssl pkcs12 -export -inkey client-key.pem -in client-cert.pem -out client.pfx
pfxファイルを作成する。(client部は任意の名前)

pfxパスワードを聞かれるが、空白も可能で空白の場合、接続文字列のCertificatePasswordは不要となる。

・ワンライナーで設定する場合
pass=$(head /dev/urandom | tr -dc a-km-np-z1-9 | head -c 13);openssl pkcs12 -export -inkey client-key.pem -in client-cert.pem -out client.pfx -passout pass:${pass};echo $pass;

・接続文字列

MySQLのConnectorはNuGetでもインストーラーでもいける。インストーラなら参照設定から登録。

VBAからの接続

MySQLのODBCドライバをインストールする。32/64bitはOSではなくOfficeに合わせる ‘(ファイル>アカウント>Excelバージョン情報)

https://dev.mysql.com/downloads/connector/odbc/
mysql-connector-odbc-xxx-winx64(32).msi

MySQLにインポート

・データベース作成

コンソール>SQL>インスタンス選択>データベース>データベースの作成をクリック。

文字セット:utf8
照合:デフォルトの照合

・ファイルアップロード(Storage)

コンソール>Storage>ブラウザ>バケットを作成をクリック。

バケットに一意の名前をつける。

ロケーションタイプ:Region
ロケーション:asia-northeast1(東京)
ストレージクラス:Standard
アクセス制御:均一

コンソール>Storage>ブラウザ>バケットを選択>ファイルをアップロードをクリック。

・インポート

コンソール>SQL>インスタンス選択>概要>インポートをクリック。

ソースにファイルを指定:アップロードしたファイル選択
ファイル形式:SQL
インポート先:作成したデータベース名

VPSのMySQLへはSQLiteで作成したファイルを直接インポートできたが、GCPではできなかったため、とりあえず今回はSQLite>MySQL(VPS)>MySQL(GCP)という流れになった。

Python 組み込みサーバー

 

・組み込みサーバーでCGIを処理

Win10設定>アプリ>アプリと実行エイリアス
python.exeをオフにする

sysdm.cpl>詳細設定>環境変数
からパスを通す
C:\Users\mail\AppData\Local\Programs\Python

バッチファイルを作成

バッチと同じ階層にpython.pyを作成

バッチと同じ階層にindex.htmlを作成

binファルダ以下にtest.pyを作成

 

Python XML・Json

 

Python データベース基本

 

Python ファイル関連

 

Python 基本文法

新しい言語を少し触ってみようかなということでPythonをはじめた。

VBA 並び替え(Sort)

いつも忘れてしまうので。

ダイアログを表示させ、実行は手動にする場合。

 

Ubuntu(Indigo) 初期設定

IndigoにUbuntuを設定+ローカルにあるSQLiteをIndigo上のMySQLにエクスポートする実験。

インスタンス生成

ダッシュボード>インスタンス管理>インスタンス
からインスタンス生成し、起動する。

表示されているIPアドレスにTeraTermから接続

TeraTerm 起動マクロ

SSH接続

公開鍵方式でのSSH接続、OSでUbuntuを選択すると、自然とユーザー名はubuntuとなる。

公開鍵で、TeraTermとWinSCPで接続できるように設定する。

Ubuntu セキュリティ関連設定

MySQL

・インストール
sudo apt install mysql-server

(インストール後、起動+自動起動するようになっている)

・バージョン確認
sudo mysql –version

・起動、他
sudo systemctl (start|stop|restart|status)  mysql

・my.cnfを探す
sudo mysql –help | grep my.cnf
今回は
sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf

・(外部から接続する場合)bind-addressをコメントアウト。
ここで指定したIPアドレスのみ接続を受け付ける。接続元のIPアドレスがわかる場合は指定しても大丈夫だが、複数のIPアドレスは指定できない。

(my.cnfを変更した場合、再起動)

MySQLのrootアカウントは標準でauth_socket認証しており、パスワード設定しても、パスワード無しでログインできる。ここで少しつまづいた。
(sudo mysql -u rootとすれば入れる)

・文字コード確認
sudo mysql -u root
show variables like ‘char%’;

・文字コード変更

今は最初からutf8mb4になっている。
もしなっていない場合、mysqld.cnfに下記を追加する。

これで、utf8に変わる。

・DB作成
sudo mysql -u root
create database check_sheet character set utf8mb4;

・ユーザー作成

(外部から接続する場合ホストは%としておく)
create user ‘app_user’@’%’;

※同時にパスワードを設定する場合、
create user ‘app_user’@’%’ identified by ‘1234’;
auth_socket認証とする場合、
create user user@host identified with auth_socket;

・ユーザー削除
drop user ‘app_user’@’%’;

・ユーザー一覧
select user, host, authentication_string, plugin from mysql.user;

・権限設定
grant create,drop,alter,select,insert,update,delete on check_sheet.* to ‘app_user’@’%’;

これを実行しないと作成したユーザーでDBが操作できない。

・権限確認
show grants for ‘app_user’@’%’;

・権限削除
revoke all, grant option from ‘app_user’@’%’;

・パスワード設定

シェルからワンライナーの場合
pass=$(head /dev/urandom | tr -dc a-km-np-z1-9 | head -c 13); sudo mysql -u root -e “alter user ‘app_user’@’%’ identified by ‘${pass}'”; echo $pass;

あるいは、
alter user ‘app_user’@’%’ identified by ‘2345’;
set password for ‘app_user’@’%’ = ‘2345’;

MySQL SSL接続

・状態確認
show variables like ‘%ssl%’;

初回起動時に、mysql_ssl_rsa_setup()が実行され、このようにSSLが有効になっていた。MySQLのデータディレクトリ以下に生成される。

ca.pem:自己署名CA証明書
ca-key.pem:CA秘密鍵
server-cert.pem:サーバ用公開鍵
server-key.pem:サーバ用秘密鍵
client-cert.pem:クライアント用公開鍵
client-key.pem:クライアント用秘密鍵
private_key.pem:caching_sha2_password, sha256_password用秘密鍵
public_key.pem:caching_sha2_password, sha256_password用公開鍵

・データディレクトリ確認
show variables like ‘%datadir%’;

(後のコピーでも必要なので、ここで実行)
permission deniedとなるので、
sudo su
を実行する。

・データディレクトリに移動
cd /var/lib/mysql

・コピー+パーミッション変更

データディレクトリから、
client-cert.pem
client-key.pem
ca.pem (必要なら)
をダウンロードするため、先ずホームディレクトリにコピーする。
(これらのファイルはWorkbechで利用するけど、もしC#だけなら、そのまま変換するのでダウンロード不要)

今回は/var/lib/mysql/にあったので、コピーする。
cp /var/lib/mysql/client-cert.pem /home/ubuntu/client-cert.pem;
cp /var/lib/mysql/client-key.pem /home/ubuntu/client-key.pem;
cp /var/lib/mysql/ca.pem /home/ubuntu/ca.pem

・パーミッション変更

ダウンロードするのにパーミッション変更が必要なので、ホームディレクトリ(コピー先)に移動し、
chmod go+r ca.pem;
chmod go+r client-key.pem;
chmod go+r client-cert.pem

のようにする。

これでWinSCPなどでダウンロードできる。

・ユーザー戻す
su ubuntu

・SSLのユーザー状態確認
select user,host,ssl_type from mysql.user;

ssl_typeの部分を確認する。

・権限追加
alter user ‘app_user’@’%’ require X509;

・全ての権限を削除
revoke all, grant option from ‘app_user’@’%’;

requireで指定するオプションについて

・SSL
暗号化接続はサーバーのcert,keyのみなので、クライアントのcert,keyは指定しなくても大丈夫。

・X509
クライアントを証明する必要があるためクライアントにcert,keyを指定する必要がある。

ここの指定とは別にクライアント側からもオプションがある。

・DISABLED
・PREFERRED (default)
サーバが暗号化接続をサポートしている場合は暗号化接続。接続できない場合は通常の接続。
・REQUIRED
サーバー認証を行なって接続する。
・VERIFY_CA
サーバー認証とクライアント認証を行って接続する。

MySQL 外部からの接続

IPアドレスの指定がない、またはIPアドレスの指定をしたいが固定ではない場合、MySQLのbind-addressは複数指定できず、ユーザーのホスト部を頻繁に変更するのも手間なのでufwで弾くのが簡単。

sudo ufw allow 3306/tcp
sudo ufw reload

もしIPアドレスを指定したい場合

sudo ufw allow from IPアドレス to any port 3306 proto tcp
これで、特定のIPのみMySQLに接続できる。

IPアドレスが変更になったら、
sudo ufw status numbered
でNoを確認し、
sudo ufw delete 番号
(複数不可)
で該当ルールを削除し、再度、
sudo ufw allow from IPアドレス to any port 3306 proto tcp
で変更後のIPアドレスを指定する。

Apache+PHP

今回は利用しない。

Ubuntu Apache(PHP+MySQL) 設定

クライアント設定

GCP Cloud SQL(MySQL) 使い方

SQLiteをMySQLへエクスポート

とりあえず動かすためだけの設定で実際は細かく調整する必要がある

DB Browser for SQLiteにて、
ファイル>エクスポート>データベースをSQLファイルへ

・insert into にカラム名を保持
・insert文に複数行(VALUES)
にチェック。

・すべてをエクスポート
・古いスキーマを上書き(DROP TABLE した後に CREATE TABLE)
を選択して保存。(DROPしないと何度か実行するときに作成済みのテーブルが残ったりする)

それぞれデータの内容によって違うが今回は書き出したSQLファイルを下記の通り修正。

・先頭のBIGIN TRANSACTIONをSTART TRANSACTIONに変更。

・全てのダブルクォーテーションの削除。
テーブル名やカラム名がダブルクォーテーションで囲われているため。

・CREATE TABLEで型が抜けている部分にtextを追加。

・全ての型をtextに変更。
insertの部分でint等も空の部分がシングルクォーテーションになっているため

・PRIMARY KEY()を削除。
上の行末のカンマも削除

ファイルサイズが大きいので、WinSCPでアップロードし、
mysql -u root -p db名 < SQLファイル.sql
として実行。
※ちなみに、エクスポートは、
mysqldump –single-transaction -u ユーザ名 DB名 > 出力先ファイル名

Workbenchの場合、
Server>Data Import>Import from Self-Contained File
Default Target Schemaからデータベース名を選択しStart Importを実行。

ERROR 2006 (HY000) at line 1820: MySQL server has gone away
Operation failed with exitcode 1

というエラーがでた場合、
set global max_allowed_packet = 16777216;
(一時的)

インポート後にカラム1つずつデータ型を変更する。
alter table table_name modify column_name int not null primary key auto_increment;
のように処理し、
intに関しては、SQLiteで空文字が入ってしまっているとエラーがでるので、
update table_name set column_name = null where column_name = “”;
このようにした。