主にプログラミングに関して。Python, .NET Framework(C#), JavaScript, その他いくらか。
記事にあるサンプルやコードは要検証。使用に際しては責任を負いかねます

ブログ移転計画

                
 しばらく更新できてなかったが、自分でブログエンジンを書いて移行しようかと考えている。以前にそういうものはPython+GAEで作ったが、もうGAEからはおさらばしたい。新しい環境はASP.NET MVC + MongoDB on Linux。Dockerも利用を考えている。

 とりあえずDockerでNginX、ASP.NET MVC、MongoDBをsupervisordで管理するものを用意した。あとはコードを書いていくだけだ。

1604090026063.jpg

Dockerfile
FROM matoba/aspmvc

RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv EA312927 && \
echo "deb http://repo.mongodb.org/apt/debian wheezy/mongodb-org/3.2 main" | tee /etc/apt/sources.list.d/mongodb-org-3.2.list && \
apt-get update && \
apt-get install -y mongodb-org && \
apt-get -y install nginx && \
apt-get install -y supervisor

RUN echo "daemon off;" >> /etc/nginx/nginx.conf
RUN rm /etc/nginx/sites-enabled/default
ADD nginx.conf /etc/nginx/conf.d/
RUN /etc/init.d/nginx reload
RUN mkdir -p /data/db

COPY . /app
WORKDIR /app
COPY mongod.conf /etc/mongod.conf

EXPOSE 80
ENTRYPOINT /usr/bin/supervisord -c supervisord.conf


nginx.conf
server {
listen 80 default;
server_name example.org;
access_log /var/log/nginx/example.log;

location / {
proxy_pass http://127.0.0.1:5004;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}


mongod.conf
processManagement:
fork: false
net:
bindIp: 127.0.0.1
port: 27017
storage:
dbPath: /data/db
systemLog:
destination: file
path: "/var/log/mongodb/mongod.log"
logAppend: true
storage:
journal:
enabled: true


supervisord.conf
[supervisord]
nodaemon = true

[program:nginx]
command = nginx

[program:mongodb]
command = mongod --config /etc/mongod.conf
user = root
autostart = true
autorestart = true

[program:aspmvc]
command = dnx -p project.json web

スポンサーサイト



DockerでSQLインジェクションを試せるイメージを用意する

                
 今となってはいろいろ対策の手が打たれているが、それでも知識もなくWebアプリを作るとうっかりできてしまうことがあるSQLインジェクション。どんな立場からどんな攻撃ができうるかを示すために、脆弱性を持ったWebアプリを作ってみようと考えた。
 それを使って脆弱性をつついてもらうデモにしたい。つついてもらったらデータベースに変更が入る。そうしたら別の人に試してもらうにはリセットが必要となる。もろもろの環境リセットが簡単にできるとデモとして最高。そういうわけでDockerイメージとして脆弱性を持ったWebアプリをすぐ実行できるものを用意する。


 Webアプリ部分はどんなものにするか。とりあえずすごく簡単なものにしておく。アクセスしてきたクライアントにフォームを返す。フォームに名前を入力してPostする。フォームに入力された名前がデータベースにあれば、実行されたクエリ文とその名前が表示される。入力された名前がデータベースになければエラー文が表示される。以上のものをPythonで書いた。
1601241839287.jpg
1601241839493.jpg
1601241840245.jpg
 「John」とポストするだけなら問題ない。「John"; SELECT * FROM employees;DROP TABLE employees;"」などとポストされるとJohnの登録されていたテーブルが落ち、以降はJohnと入力してもデータベースにそもそもテーブルがないためエラーとなる。


Dockerfileは以下。
FROM ubuntu

RUN apt-get update && apt-get -y install nginx && \
apt-get install -y supervisor && \
apt-get install -y python3-pip && \
pip3 install gunicorn && \
pip3 install tornado

RUN apt-get install -y mysql-server

RUN echo "daemon off;" >> /etc/nginx/nginx.conf
RUN rm /etc/nginx/sites-enabled/default
ADD hello.conf /etc/nginx/conf.d/
RUN /etc/init.d/nginx reload

ADD * /usr/
WORKDIR /usr/
RUN dpkg -i mysql-connector-python-py3_2.1.3-1ubuntu14.04_all.deb
RUN /etc/init.d/mysql start && \
mysql < init.sql

EXPOSE 80
CMD /usr/bin/supervisord -c supervisord.conf

 Python製Webアプリ、MySQL、NginXはsupervisordでコントロールにした。PythonのMySQLConnectorはpipインストール設定が手間だったのでdebパッケージを落としてきてdpkgコマンドインストールにした。

 その他ファイルの設定はGithubにて公開中。
https://github.com/hMatoba/SQLInjection-DockerSample

 上記のDockerfileがあるディレクトリでビルドを実行する。
> docker build -t matoba/sql_injection ./
 
 ついでにどこからでもダウンロードできるようにプッシュしておく。
> docker push matoba/sql_injection

 イメージをダウンロードし、そこからコンテナを立ち上げて試してみる。
> docker pull matoba/sql_injection
> docker run -d -p 80:80 --name sql_inj matoba/sql_injection
1601241927297.jpg


 動いているので問題なし。あとはデータベースを含めたWebアプリ部分をもうちょっとまともにする。今のままでも試すことはできるが、かなり最低限に絞っているので試した人のインパクトは小さいだろう。
 Dockerのおかげで、いつでも使い捨てができる手軽なSQLインジェクションの脆弱性を持ったWebアプリデモが簡単に用意できるようになった。
 

JavaScript: クライアントサイドでもサーバサイドでも使えるライブラリのテスト(Docker, TravisCI)

                
 ブラウザでもNodejs環境でも動作するJavaScriptライブラリをGithubにのっけてある。
https://github.com/hMatoba/piexifjs
 必要になったら使ってくださいというスタンスにしてある。信頼性確保のためにテストを書いてTravisCIで実行されるようにしていたが、テストはPhantomjsを使ってクライアントサイドのみを行っていた。クライアントサイド、サーバサイドの両対応がウリのライブラリなので両方のテストをTravisCIでやっておいて、ライブラリを見つけた人が信頼できるようにしたいので、サーバサイドのテストを行うようにちょっとファイルを追加したり。

 クライアントサイドのテストはヘッドレスでブラウザが使えるPhantomjsに自作のテストフレームワークphestum.jsを使用し、
>phantomjs phestum.js mylib.js
上記コマンドで動くようになっていた。クライアントサイドはこのままで問題ないのでサーバサイドテストを追加する。
 とりあえず簡単なテストを書き、nodetest.jsという名前で保存した。テストとして問題なく終了すればエラーコードなしで終了、問題があればエラーコード1で終了するようにしてある。これはNodejsで動かすのでコマンドとしては下記。
>node nodetest.js
上記のnodeコマンドは環境によってはnodejsでないと動かない。後で出てくるがDockerにてubuntu内ではnodejs、TravisCI環境ではnodeでコマンドが通る。

 テストは用意した。あとはテストするだけ。TravisCIですぐに行ってもいいが、自分でDockerを使ってテスト環境を用意し、それにパスしたらTravisCIで行うようにしたほうが問題があったときに手っ取り早い。よってまずDockerを使ったテストの準備。下記が実際に使ったDockerfile。NodejsとPhantomjsのインストール、テストするライブラリやテストコードのコピーを行う。
FROM ubuntu

RUN apt-get update && \
apt-get install -y nodejs && \
apt-get install -y phantomjs

RUN mkdir /test/
ADD . /test/
WORKDIR /test/

ENTRYPOINT phantomjs phestum.js piexif.js && nodejs nodetest.js

 準備ができたらイメージのビルドから実行までを行い、テストを通ることを確認する。テストに通らなかったら修正を加え、またビルドから実行まで。
docker build mylib_test .
docker run mylib_test
1508302207353.jpg
1508302207439.jpg



 Dockerで用意した環境でテストが通ったのでTravisCIでも行う。.travis.ymlが下記。
sudo: false

language: node_js
node_js:
- "0.12"

script: phantomjs phestum.js piexif.js && node nodetest.js

 これでTravisCIでもテストが行われる。テストはコマンドにあるとおり、Phantomjsを使ったクライアントサイド、Nodejsを使ったサーバサイドのテストが行われる。二つのコマンドが&&でつながれているので、問題なければ二つが順番に実行される。これでクライアントサイド、サーバサイド両対応のJavaScriptライブラリとして堂々と公開しておけるだろう。
1508302210434.jpg
https://travis-ci.org/hMatoba/piexifjs

Windows 10: Boot2Docker on Hyper-V

                
tags: Docker
 Windowsには8以降でHyper-Vが導入されている。アプリ開発でWindowsOSのエミュレータが動くときはこのHyper-Vにお世話になる。そういうわけで欠かせない機能になっているが、このHyper-VをOnにするとCPU仮想化機能の都合で他の仮想化ソフトが使えなくなる。VirtualBoxとか。VirtualBoxが使えなくなるとBoot2Dockerが起動しなくなる。そんなわけでBoot2DockerをHyper-Vで動かすことにする。

参考
http://www.henning.ms/2015/05/11/running-docker-on-hyper-v/
http://blog.thestateofme.com/2014/02/18/boot2docker-on-hyper-v/

 やることはわりと単純。Boot2DockerはISOが提供されているのでそれを入手し、それをHyper-Vで動かす。Boot2Dockerの永続ストレージを用意する。ホストOSがネットワークでシェアしているディレクトリをVirtualBox上で動かしたBoot2Dockerと同様にマウントして、ホストで用意したファイルをBoot2Docker内で使えるようにする。


・Boot2DockerのISOの入手
 下記から。
https://github.com/boot2docker/boot2docker/releases

・Hyper-VでBoot2Dockerの立ち上げ
 落としたISOをHyper-Vで立ち上げる。新しいVirtual Machineを作成し、DVDドライブにISOイメージを登録。とりあえず立ち上げを確認したいのでハードディスクはまだ付けておかなくてもいい。もちろんネットワークはLAN内ファイルシェアやもろもろのダウンロードができるようにつないでおく。External設定で。
 準備ができたらその仮想マシンを起動し、Boot2Dockerが入力を受け付ける画面にまで進むことを確認する。気が済んだら仮想ハードディスクを取り付けるので落とす。

・ストレージの用意
 Boot2Dockerに仮想ハードディスクを取り付ける。Boot2Docker仮想マシンのSettingsを開いて、IDE Controller0のところにHDDを追加する。新規の仮想ハードディスクを取り付ける。
 仮想ハードディスクを取り付けたらBoot2Docker仮想マシンを立ち上げる。そしてまずフォーマットを下記のようにかける。

sudo fdisk /dev/sda
n
e
ターミナルに従ってデフォルトとされてる値を入力
同様にデフォルト値を入力
n
l
同様にデフォルト値を入力
同様にデフォルト値を入力
w
sudo mkfs.ext4 -L boot2docker-data /dev/sda5

 パーティションの1から4でどれにするか聞かれたら1を選ぶ。
 上記のコマンドが済んだら準備ができたので再起動。

・ホストマシンのシェアディレクトリをBoot2Dockerにマウント
 せっかくだからホストマシンのPowerShellからSSH接続をまず試し、接続が成功したら続いてマウントをする。Boot2Dockerが立ち上がるとき、あるいは起動後にifconfigでIPアドレスを調べる。そしてそこにuser:docker pass:tcuserでPowerShellからログインする。PowerShellで下記を入力。
SSH docker@[Boot2Docker IP]
 パスワードを入れればBoot2Dockerに入れる。このままVirtualBoxのBoot2Dockerと同様に/c/Usersにホストのユーザーディレクトリをマウントする。
 まずディレクトリの作成。
sudo mkdir -p /c/Users
 続いてマウント。
sudo mount //[host's ip]/Users /c/Users -o username=[host user],password=[password]
 マウントコマンドにはパスワードまでつける。LinuxMintで同様のマウントをパスワード抜きでやったら、コマンド入力後にパスワードを聞き返された。しかしBoot2Dockerではパスワード抜きでは即刻access deniedではじかれた。
 VirtualBoxのBoot2Dockerと同様に/c/Users以下にディレクトリがマウントされていることを確認する。


 ついでに以前Boot2Dockerのために作成していた設定ファイルをそのまま使い、コンテナ上で立ち上げたWebアプリにホストマシンからアクセスする。成功すればHello from sv.という文字列がブラウザに表示される。
http://elicon.blog57.fc2.com/blog-entry-465.html
 SSH接続してあるPowerShellからこれまでの追加で以下を入力した。用意済みのシェルスクリプトを実行するコマンドである。
cd /Users/john/docker/b3
sh hello.sh
 接続成功。
1508071502470.jpg



 Hyper-Vの使用によってVirtualBoxが立ち上げられなくなるので、Boot2DockerをHyper-Vで使うことを試みた。Boot2Dockerを立ち上げて永続ストレージを用意できてしまえば、あとは立ち上げ時にホストのネットワークシェアディレクトリをマウントするだけでVirtualBoxのBoot2Dockerと同様に使えた。同様ということでこれまでのBoot2Dockerで使っていた設定ファイルそのままでコンテナを動かせている。これならVirtualBoxなしでもうまくいけそうである。
 参考にした記事では仮想ハードディスクを作成した後、それをベースとしてコピーを作って再び取り付けて使用している。それで新しいBoot2Docker仮想マシンの作成時にフォーマットの手間などが省けるということらしい。ぼくはBoot2Docker仮想マシンは一台で十分だったし、もしのちのちそれを作り直すことになってもその手間が5分(もしかしたら3分程度かも)で済むものだったのでベースのみで使用している。


 さらにVirtualBoxのBoot2Dockerに近づけるには・・・
 Hyper-V管理ツールではなくPowerShellからゲストを立ち上げるには下記。
Start-VM -Name "boot2docker"

 いちいち実行するたびにマウントコマンドを実行するのは面倒。マウントコマンドを起動時に実行されるシェルスクリプトに書いておく。
http://stackoverflow.com/questions/26639968/boot2docker-startup-script-to-mount-local-shared-folder-with-host
 Boot2Dockerでは/var/lib/boot2docker/bootlocal.shが起動時に実行されるので、ここにマウントコマンドを書いておけば立ち上げるたびに自分で書く必要がなくなる。

Docker: Docker + supervisor + NginX

                
tags: Docker python
 前回はDocker + NginxでPythonのWebアプリを走らせた。
http://elicon.blog57.fc2.com/blog-entry-460.html
 前回作ったものはコンテナを走らせてからNginXを追加コマンドで走らせていた。どうせならコンテナを走らせればNginxとPythonスクリプトが起動して、Webアプリとしても動作してくれるとありがたかったのだが、NginXが基本的にデーモンプロセスで実行なことなどでそうなっていた。今回はそれをsupervisorを使って解消し、コンテナを走らせれば追加コマンドなしでWebアプリとして動作するようにコンテナを作る。

 前回からWebアプリのPythonスクリプトhello.pyと、NginXの設定ファイルhello.confをそのまま持ってくる。あとsupervisor設定ファイルsupervisord.confを用意する。
 
 Dockerfileとsupervisor.confは以下。
FROM ubuntu

RUN apt-get update && apt-get -y install nginx && \
apt-get install -y supervisor && \
apt-get install -y python3-pip && \
pip3 install gunicorn && \
pip3 install tornado

RUN echo "daemon off;" >> /etc/nginx/nginx.conf
RUN rm /etc/nginx/sites-enabled/default
ADD hello.conf /etc/nginx/conf.d/
RUN /etc/init.d/nginx reload

ADD . /usr/
WORKDIR /usr/

EXPOSE 80
CMD /usr/bin/supervisord -c supervisord.conf


[supervisord]
nodaemon = true

[program:nginx]
command = nginx

[program:hello_app]
command = gunicorn hello:wsgi_app


 上記のファイルを用意した状態で下記二行を実行すればsupervisorによってNginXとPythonWebアプリの両方が起動している。http://192.168.59.103/へアクセス。
docker build -t b3_tmp ./
docker run -d -p 80:80 --name b3 b3_tmp

1507290936497.jpg
プロフィール

h

Author:h

最新記事
リンク
作ったものなど
月別アーカイブ
カテゴリ
タグリスト

検索フォーム
Amazon