Ubuntu 20.04 GUI版JMeterをDockerで起動する
使用するファイル
C:\ │ docker-compose.yml │ ├─home\ └─ubuntu\ Dockerfile
docker-compose.yml
version: '3' services: app: build: context: ./ubuntu/ dockerfile: ./Dockerfile ports: - '2222:22' - '13389:3389' tty: true container_name: ubuntu20.04 volumes: - ./home:/home
Dockerfile
FROM ubuntu:20.04 RUN apt update RUN apt install -y openssh-server RUN mkdir /var/run/sshd RUN echo 'root:password' | chpasswd RUN sed -ri 's/^#?PermitRootLogin\s+.*/PermitRootLogin yes/' /etc/ssh/sshd_config # SSH login fix. Otherwise user is kicked off after login RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd ENV NOTVISIBLE "in users profile" RUN echo "export VISIBLE=now" >> /etc/profile EXPOSE 22 ENTRYPOINT [ "/usr/sbin/sshd", "-D" ] RUN apt-get update RUN echo y | apt-get upgrade # JMeter RUN echo y | apt-get install openjdk-8-jdk RUN cd /opt RUN wget http://ftp.meisei-u.ac.jp/mirror/apache/dist//jmeter/binaries/apache-jmeter-5.2.1.tgz RUN tar xvzf apache-jmeter-5.2.1.tgz RUN echo "export PATH=$PATH:/opt/apache-jmeter-5.2.1/bin" >> ~/.bashrc EXPOSE 3389
RDP サーバ xrdp インストール
$apt-get install xrdp
デスクトップ環境 lxde インストール
$apt-get install lxde
Windows からリモートデスクトップ接続
Ubuntuにリモートデスクトップ接続します。
localhost:13389
root でログインします。
username: root password: password
Ubuntuにリモートデスクトップ接続できる事が確認できます。
Ubuntu 20.04 SSHサーバをDockerで起動する
使用するファイル
C:\ │ docker-compose.yml │ ├─home\ └─ubuntu\ Dockerfile
docker-compose.yml
version: '3' services: app: build: context: ./ubuntu/ dockerfile: ./Dockerfile ports: - '2222:22' tty: true container_name: ubuntu20.04 volumes: - ./home:/home
Dockerfile
FROM ubuntu:20.04 RUN apt update RUN apt install -y openssh-server RUN mkdir /var/run/sshd RUN echo 'root:password' | chpasswd RUN sed -ri 's/^#?PermitRootLogin\s+.*/PermitRootLogin yes/' /etc/ssh/sshd_config # SSH login fix. Otherwise user is kicked off after login RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd ENV NOTVISIBLE "in users profile" RUN echo "export VISIBLE=now" >> /etc/profile EXPOSE 22 ENTRYPOINT [ "/usr/sbin/sshd", "-D" ]
ssh接続の確認
ssh接続はUbuntuの22番ポートにポートフォワーディングしている2222番ポートを指定します。今回ssh接続のパスワードはpasswordとしています。
ssh -p 2222 root@localhost
コンテナを作り直してssh接続する場合
コンテナを作り直すとssh接続が失敗します。
PS C:\docker\ubuntu20_04> ssh -p 2222 root@localhost @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY! Someone could be eavesdropping on you right now (man-in-the-middle attack)! It is also possible that a host key has just been changed. The fingerprint for the ECDSA key sent by the remote host is SHA256:*********************************************************. Please contact your system administrator. Add correct host key in C:\\Users\\<User name>/.ssh/known_hosts to get rid of this message. Offending ECDSA key in C:\\Users\\<User name>/.ssh/known_hosts:2 ECDSA host key for [localhost]:2222 has changed and you have requested strict checking. Host key verification failed.
SSHでは初回接続時に接続先ホストの公開鍵を保存しておき、次回接続時にホスト鍵を比較して前回と同じホストに接続したかを確認するような仕組みになっています。
「SSHホスト鍵が変わってるよ!」と怒られたときの対処 - Qiita
known_hostsファイルからssh鍵を削除する事でssh接続が行えました。
$ ssh-keygen -R '[localhost]:2222'
DockerでFTPサーバを起動してC#でファイル転送を行う
はじめに
前回はDockerでSQL Serverを起動して開発に利用しました。
knkomko.hatenablog.com
今回はFTPサーバを使うため、前回と同様にDockerを利用していきます。
DockerでPure-FTPdを起動してC#によりファイル転送を行います。
yml形式のファイルとC#のソースコードはこちらです。
github.com
開発環境
・Widnows10 Pro
・Docker Engine Community Version 20.10.5
使用するファイル
C:\DOCKER\PURE-FTP\ │ docker-compose.yml │ ├─ etc\ │ └─ home\
docker-compose.yml
FTPでファイルをアップロードすると ./home ディレクトリに保存されます。
version: '3' services: ftp-server: image: stilliard/pure-ftpd:hardened container_name: ftp-server ports: - "21:21" - "30000-30009:30000-30009" volumes: - ./home:/home/ftpusers - ./etc:/etc/ssl/private environment: - PUBLICHOST=localhost - FTP_USER_NAME=xuser - FTP_USER_PASS=xpass - FTP_USER_HOME=/home/ftpusers - ADDED_FLAGS="--tls=2"
FTPサーバの起動
yml形式のファイルと同じディレクトリで compose upを実行します。
$docker compose up -d --build
container ls で起動しているコンテナにFTPサーバが表示されることを確認します。
$docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES d31b413c7a11 stilliard/pure-ftpd:hardened "/bin/sh -c '/run.sh…" 54 seconds ago Up 46 seconds 0.0.0.0:21->21/tcp, 0.0.0.0:30000-30009->30000-30009/tcp ftp-server
stop <コンテナ名> で起動しているコンテナを停止できます。
$docker stop ftp-server
start <コンテナ名> で停止しているコンテナを起動できます。
$docker start ftp-server
FTPサーバの確認
Windows10の場合になります。
エクスプローラーからFTPサーバに接続ができる事を確認します。
ftp://localhost/
サインオンの画面ではアカウント情報を入力します。
[Log On]ボタンを押下するとFTPサーバに接続できます。
ユーザー名:xuser パスワード:xpass
C#でファイル転送
FTPサーバーにファイル転送を行うサンプルになります。
サンプルの作成にあたって参考にした公式ドキュメントです。
docs.microsoft.com
ファイルの転送の方法は2ステップです。
ステップ1でFTPサーバにログオンします。
ログオンに成功するとファイル転送を行うStreamが取得できます。
// Get the object used to communicate with the server. FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://" + TextHost.Text + "/" + ListBoxDirectory.SelectedItem.ToString()); request.Method = WebRequestMethods.Ftp.DownloadFile; // FTP user logon. request.Credentials = new NetworkCredential(TextUserName.Text, TextPassword.Text);
ステップ2でファイルの転送を行います。
ダウンロードになりますが、FileStreamを使用してFTPサーバにあるファイルのバイナリを1024バイトごと読み込んで、ローカルのファイルに書き込んでいます。
using (FileStream fs = new FileStream(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + @"\Downloads\" + ListBoxDirectory.SelectedItem.ToString(), FileMode.CreateNew, FileAccess.Write)) using (Stream responseStream = response.GetResponseStream()) { byte[] buffer = new byte[1024]; while (true) { int readSize = responseStream.Read(buffer, 0, buffer.Length); if (readSize == 0) { break; } fs.Write(buffer, 0, readSize); } }
Ubuntu 18.04 自己署名証明書でSSLに対応する
はじめに
SSLに対応したテスト環境が必要になったので自己署名証明書を利用しました。
今回は証明書を発行して Google Chrome でSSLに対応する方法をまとめます。
内容は example.com にアクセスして Nginx のトップページを表示します。
自己認証局の準備
証明書の保存場所を指定します。
$sudo vim /etc/ssl/openssl.cnf [ CA_default ] dir = /etc/ssl/example-ca # Where everything is kept
証明書の保存場所を作成します。
$mkdir /etc/ssl/example-ca $cd /etc/ssl/example-ca $ sudo mkdir certs $ sudo mkdir private $ sudo mkdir crl $ sudo mkdir newcerts $sudo sh -c "echo '01' > /etc/ssl/example-ca/serial" $sudo touch /etc/ssl/example-ca/index.txt
CA証明書の作成
$cd /etc/ssl/example-ca #有効期限が10年の自己署名証明書を作成 sudo openssl req -new -x509 -newkey rsa:2048 -out cacert.pem -keyout private/cakey.pem -days 36500 #認証局のパスワードを入力 Enter PEM pass phrase: #パスワードの再入力 Verifying - Enter PEM pass phrase: #証明書の情報を入力 Country Name (2 letter code) [AU]:JP State or Province Name (full name) [Some-State]:Tokyo Locality Name (eg, city) []:Ota Organization Name (eg, company) [Internet Widgits Pty Ltd]:Example CA Organizational Unit Name (eg, section) []: Common Name (e.g. server FQDN or YOUR name) []:Example CA Email Address []:email@example.com
2つのファイルが作成されている事を確認します。
#CA証明書 /etc/ssl/example-ca/cacert.pem #CA証明書の秘密鍵 /etc/ssl/example-ca/private/cakey.pem
作成したCA証明書をブラウザにインポート
以下のコマンドで作成した example-ca.der をクライアント側で実行します。
$sudo openssl x509 -inform PEM -outform DER -in /etc/ssl/example-ca/cacert.pem -out /etc/ssl/example-ca/example-ca.der
Windows10 の場合になります。
exemple-ca.der をダブルクリックして起動して、[証明書のインストール]ボタンを左クリック。
"ローカルコンピュータ"を選択して[次へ]ボタンを左クリック。
"証明書をすべて次のストアに配置する"を選択して[参照]ボタンを左クリック。
"信頼されたルート証明機関"を選択して[OK]ボタンを左クリック。
[次へ]ボタンを左クリック。
[完了]ボタンを左クリック。
メッセージが表示されたらインストールは完了です。
自己署名証明書の作成
$sudo mkdir /etc/ssl/example.com/ $sudo openssl req -new -keyout /etc/ssl/example.com/example-key.pem -out /etc/ssl/example.com/example-csr.pem #秘密鍵のパスワードを入力 Enter PEM pass phrase: #パスワードの再入力 Verifying - Enter PEM pass phrase: #証明書の情報を入力 Country Name (2 letter code) [AU]:JP State or Province Name (full name) [Some-State]:Tokyo Locality Name (eg, city) []:Ota Organization Name (eg, company) [Internet Widgits Pty Ltd]:Example CA Organizational Unit Name (eg, section) []: #ドメイン名を入力 Common Name (e.g. server FQDN or YOUR name) []:example.com Email Address []:email@example.com #パスワードを入力 A challenge password []: An optional company name []:
2つのファイルが作成されている事を確認します。
#サーバ証明書要求ファイル /etc/ssl/example.com/example-csr.pem #サーバ秘密鍵 /etc/ssl/example.com/example-key.pem
SAN を含んだ自己署名証明書の作成
Google Chrome 58 から Common Name ではなく SubjectAltName でドメイン名を確認するため、SubjectAltName を含んだ自己署名証明書を作成します。
$cd /etc/ssl/example.com $sudo sh -c "echo subjectAltName=DNS:example.com > san.ext"
ファイルが作成されている事を確認します。
#SubjectAltName ファイル
/etc/ssl/example.com/san.ext
root権限を使用して署名を行います。
#rootにログインする $sudo su #自己承認局で署名 $openssl ca -days 36500 -cert /etc/ssl/example-ca/cacert.pem -keyfile /etc/ssl/example-ca/private/cakey.pem -in /etc/ssl/example.com/example-csr.pem > /etc/ssl/example.com/example.crt -extfile /etc/ssl/example.com/san.ext #自己認証局のパスワードを入力 Enter pass phrase for /etc/ssl/Hoge-Private-CA/private/cakey.pem: Sign the certificate? [y/n]:y 1 out of 1 certificate requests certified, commit? [y/n] y #rootからログアウトする $exit
ファイルが作成されている事を確認します。
#SubjectAltName を含んだ自己署名証明書ファイル
/etc/ssl/example.com/example.crt
Nginx のインストール
$sudo apt update $sudo apt-get install -y wget $sudo apt-get install -y gnupg2 $wget https://nginx.org/keys/nginx_signing.key $sudo apt-key add nginx_signing.key $sudo vi /etc/apt/sources.list # sources.list に追加する deb http://nginx.org/packages/ubuntu/ bionic nginx deb-src http://nginx.org/packages/ubuntu/ bionic nginx $sudo apt update $sudo apt install nginx # Nginx のバージョンが表示される事を確認する $nginx -v
Nginx の設定
Nginxのサービス起動時に証明書のパスワード入力を求められるため
パスワードを入力したファイルを作成して参照するようにします。
$sudo vim /etc/ssl/example.com/pwf #パスワードを入力 example
証明書を利用してSSL通信ができるように設定します。
$sudo vim /etc/nginx/conf.d/default.conf #default.conf を変更 server { listen 80; listen 443 ssl; ssl on; server_name example.com; ssl_certificate /etc/ssl/example.com/example.crt; ssl_password_file /etc/ssl/example.com/pwf ssl_certificate_key /etc/ssl/example.com/example-key.pem
Nginx のサービスを開始します。
証明書のアクセス権が無いとエラーになるのでroot権限で実行しています。
#rootにログインする $sudo su #設定ファイルのテスト $nginx -t #サービスの開始 $systemctl start nginx #rootからログアウトする $exit
DockerでSQL Serverのデータベースをリストアして起動する
はじめに
これまでSQL Serverを利用した開発は、EC2インスタンスを使用していました。
Dockerを使うと手元の環境で SQL Server を起動して開発を行う事が出来るので
今回はDockerの利点である環境の自動構築を行い、接続までの手順をまとめます。
開発環境
・Widnows10 Pro
・Docker Engine Community Version 20.10.5
使用するファイル
C:\DOCKER\SAMPLE-MSSQL │ docker-compose.yml │ ├─ mssql │ db-init.sh │ ddl.sql │ Dockerfile │ entrypoint.sh │ ├─ mssql-backup │ sampledb.bak │ └─ mssql-data
docker-compose.yml
version: '3' services: db: build: context: ./mssql/ dockerfile: ./Dockerfile container_name: sample-mssql-2017 ports: - "1433:1433" environment: - ACCEPT_EULA=Y - SA_PASSWORD=Sa@mple@dm1n - MSSQL_PID=Express - MSSQL_LCID=1041 - MSSQL_COLLATION=Japanese_CI_AS - PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" volumes: - ./mssql-data:/var/opt/mssql - ./mssql-backup:/var/opt/mssql/data/backup
Dockerfile
FROM mcr.microsoft.com/mssql/server:2017-latest COPY ./entrypoint.sh /usr/src/entrypoint.sh COPY ./db-init.sh /usr/src/db-init.sh COPY ./ddl.sql /usr/src/ddl.sql WORKDIR /usr/src/ RUN chmod +x /usr/src/db-init.sh CMD /bin/bash ./entrypoint.sh
entrypoint.sh
デバッグし易いように db-init.sh の実行ログを log.txt として残しています。
./db-init.sh >> /var/opt/mssql/data/backup/log.txt 2>&1 & /opt/mssql/bin/sqlservr
db-init.sh
25s の待ち時間はリストアを行う為にSQL Serverが起動するまで待ちます。
10s の待ち時間はデータベースユーザを追加する為にリストアの終了を待ちます。
/bin/sleep 25s touch /var/opt/mssql/data/sampledb.mdf touch /var/opt/mssql/data/sampledb_Log.ldf /opt/mssql-tools/bin/sqlcmd -H localhost -U sa -P S@mple@dm1n -Q "RESTORE DATABASE sampledb FROM DISK = '/var/opt/mssql/data/backup/sampledb.bak' WITH FILE = 1, STATS = 5, REPLACE, MOVE 'sampledb' TO '/var/opt/mssql/data/sampledb.mdf', MOVE 'sampledb_Log' TO '/var/opt/mssql/data/sampledb_Log.ldf'" /bin/sleep 10s /opt/mssql-tools/bin/sqlcmd -H localhost -U sa -P S@mple@dm1n -i /usr/src/ddl.sql
ddl.sql
EXECUTE AS LOGIN = 'sa' USE sampletable GO DROP USER SampleUser CREATE USER SampleUser for login SampleUser ALTER USER SampleUser WITH DEFAULT_SCHEMA = dbo GO GRANT CONNECT TO SampleUser GO exec sp_addrolemember 'db_owner', SampleUser GO
SQL Server の起動
docker compose up --build
SQL Server の接続
SQL Server Management Studio を使用して接続ができることを確認しました。
参考資料
macでSQL Server on Linuxコンテナに自動でサンプルDBを取り込む手順 – お役立ち情報サイト・アレアレ
Docker + MySQLで開発環境用DBの作成 - もぐもぐプログラミング
Dockerfileを書き換えても反映されないときはbuild忘れ | へっぽこ開発室
[Windows] Dockerを使用してホスト環境を汚さずにmssql-server-linuxを使う | LaptrinhX
sleep: command not found - Query Admin
SQL Server on Linux for Docker でのエラー対策 - 蒼の王座・裏口
sql server - Restore database in docker container - Stack Overflow
Create Login, User, assign Permission: SQL Server Tutorial
sql server - TSQL to Map User to Database - Stack Overflow
C#から踏み台サーバを経由してSQL Serverに接続する
はじめに
複数人による開発でSQL Serverに接続できないかと考えました。
単純にEC2のポートを開けると不正にログインを試みるbotに耐えられずSQL Server が停止しまうため、踏み台サーバを経由した接続を行うことにしました。
全体像
A : 踏み台サーバ
B : データベースサーバ
A : 踏み台サーバ
SSH接続をする22番ポートを開けています。
またSSH接続用アカウントを新規作成しています。
今回はSSH.NETを使用してポートフォワーディングを行うため、踏み台サーバではポートフォワーディングの設定は行っていません。
B : データベースサーバ
SQL Serverの規定インスタンスに接続する1433番ポートを開けています。
ソースコード
C#からSSH接続が行えるSSH.NETを使用しました。
github.com
ソースコードはこちらです。
github.com
// 踏み台サーバのホスト名 string bastionServer = "XXXXXXXXXX"; // 踏み台サーバのアカウント名 string userName = "XXXXXXXXXX"; // 踏み台サーバのパスワード string password = "XXXXXXXXXX"; ConnectionInfo info = new ConnectionInfo(bastionServer, 22, userName, new AuthenticationMethod[] { new PasswordAuthenticationMethod(userName, password) } );
ForwardedPortLocal からポートフォワーディングを行っています。
// SQL Server 接続文字列 string connectionString = @"Data Source=127.0.0.1;Integrated Security=False;User ID=XXXXXXXXXX;Password=XXXXXXXXXX"; // データベースサーバのホスト名 string dbServer = "XXXXXXXXXX"; using (var client = new SshClient(info)) { client.Connect(); var forward = new ForwardedPortLocal("127.0.0.1", 1433, dbServer, 1433); client.AddForwardedPort(forward); forward.Start(); using (var connection = new SqlConnection(connectionString)) { using (var command = connection.CreateCommand()) { try { connection.Open(); connection.Open(); command.CommandText = @"SELECT count(*) AS count FROM employee";
結果
踏み台サーバを経由してSQL Server に接続する事ができました。
参考資料
C# で踏み台サーバー経由で RDS for MySQLに接続する方法 - 蒼の王座・裏口
Azure SQLDBにlinux踏み台サーバ経由で接続するには - Qiita
【SSH接続】Windows端末からパスワードなしでSSHログインする方法 | mathkuro
https://note.affi-sapo-sv.com/ssh-unprotected-key.php
Windows Server 2019 EC2インスタンスでSSHサーバーを有効にする | DevelopersIO
Windows/Linuxでポートフォワーディングする方法 - 備忘録
技術メモメモ: Windows Server 2019で標準サポートされた「OpenSSH」がすごく便利そうだった話
スマホにある子供の写真を親のLINEへ定期的に送ってみた
はじめに
コロナの影響で実家に帰れない為、子供の写真を親のLINEへ送っています。
しかし段々とLINEから送る事を手間に感じてしまい、送り忘れも増えました。
画像共有アプリの利用も考えましたが、アプリのインストール方法から親に説明する必要があるため、新しいアプリの利用は現実的な方法ではありません。
そこで写真を撮るだけで親のLINEに送れないかと考え、取り組むことにしました。
また無料で使えるサービスを組み合わせて実現することを目標にしました。
使ったサービス
- Google フォト
写真や動画をバックアップする - iPhone と iPad - Google フォト ヘルプ
ファイルを一般公開で共有する - Google Workspace ラーニング センター
Google Cloud Computing, Hosting Services & APIs
- Google Apps Script
【サンプルコード】GASでGoogleフォトの写真をドライブに日付ソート
- LINE Messaging API
料金
LINEに1日1枚の画像を送る程度であれば無料の範囲で実現できました。
- Google フォト
- Google ドライブ
容量15GBまで無料で使えます。
Google のストレージを追加購入する - パソコン - Google ドライブ ヘルプ
- Google クラウド
- Google Apps Script
APIも無料で使えます。
Google Drive Apis の利用に関して
- LINE Messaging API
フリープランを使用していて無料です。
料金プラン|LINE for Business
サービス間の連携
①画像を読み込む
子供の写真を撮影するスマホにGoogleフォトのアプリをインストールしています。
同期の設定によりスマホ内の写真はGoogleフォトのクラウドストレージに自動でバックアップされるので、Google Apps Scriptでその画像を毎朝9時に読み込みます。
②画像をコピー
Googleアカウントを持たない人にも共有する一般公開のフォルダにGoogleフォトの画像をコピーします。
一般公開とすることでLINEに画像の表示を可能にしています。
③メッセージの送信
Googleフォトにコピーした画像のURLをLINEに送信します。
画像のURLは外部から閲覧できるよう部分的に変更をしています。
④画像の表示
LINEを開くとGoogleドライブに保存していた画像が表示されます。
学び
①Googleドライブ
LINEに画像を表示するにはドライブのURLを変更する必要がありました。
ドライブのURLから画像にアクセスできるURLに変更しています。
var downloadURL = buff.getUrl().replace("/file/d/", "/uc?id=").replace("/view?usp=drivesdk", "")
【変更前】
https://drive.google.com/file/d/<ファイルID>/view?usp
【変更後】
https://drive.google.com/uc?id=<ファイルID>
②ダウンロードリンク
画像のURLに "=d" を付加すると画像のダウンロードリンクになります。
LINEで送った画像のダウンロードを可能にする為に必要でした。
③LINE Messaging API
画像を送るには imageThumbnail と imageFullSize を使用します。
変数downloadURLにGoogleドライブの画像のURLを格納しています。
var token = ["XXXXXXXXXXXXXXXX"]; //LINEで自動通知をする宛先のトークン。 var options = { "method" : "post", "payload" : {"message": "Today's photo.", "imageThumbnail" : downloadURL, "imageFullsize" : downloadURL, }, "headers" : {"Authorization" : "Bearer "+ token} }; UrlFetchApp.fetch("https://notify-api.line.me/api/notify", options);
結果
僕自身はLINEを使う事が無くなり写真を撮るだけで良くなりました。
なにより我が子の成長を母と兄に見てもらえて嬉しく思っています。