当社はIT技術のオンライン教育を得意としたセミナー専門会社です。 | 一戸英男

ITエンジニアの技術力UPをお約束します。

Python MySQLデータベース操作その1(基本編) mysqlclientモジュール

Python MySQLデータベース操作その1(基本編) mysqlclientモジュール


pythonでMySQLの操作をする場合現在ではmysqlclientモジュールを利用するユーザ数が多いようだ。フレームワークではbottleに限らず使えます。MySQL操作ライブラリーはPyMySQLが多いけど、今回はmysqlclientモジュールを使った場合の基本操作をまとめて行こうと思います。どのライブラリーでも考え方は同じですから改造は簡単だと思います。本テストではカーソルは意図的にcloseしていません。規模が多くなりメモリの再利用が必要な場合は必要かと思いますが通常の小規模では不要なケースのほうが多いと思います。予め「pip install MySQL-python」or「pip install pymysql」をインストールしてください。mysql driverはpip側のアップデートで名前が変わったりすることもあります。また互換性のあるdriverであれば何でも良いと思いますのでpip searchで調べてみてください。

とりあえず、データベースを実験用に2つ用意します。

user_dbデータベース usersテーブル

local_areaデータベース districtテーブル

db_sampleのSQLダウンロード(ZIP形式)

下記の手順で一気にDB作成、テーブル作成、データ挿入までやります。

DB接続情報をyamlファイルで保存

viかnanoエディターでdb.yamlと開いて接続情報を次のような感じで記述保存してください。プログラムに記述しないでDB接続を書いておくとやはり便利です。とくに沢山のDBやテーブルを操作するのであればそうした方が合理的になると思います。ご自分のMySQL環境に合わせてユーザ名やパスワードを書き換えてください。

もし、yamlがインストールされていなかったら「apt-get install libyaml-dev」「yum install python-yaml」「pip3 install pyyaml」とかでインストールできると思います。

fetchoneで一つづつレコードを取り出すやり方で表示する場合

この方式は、データ量が多いときに有利です。1回毎に1レコードを取り出すためバッファの枯渇になることがありません。大規模ならこの方式を使うのが基本です。工夫次第で取得レコードを複数ライン取り出すことも可能でしょう。

実行結果

fetchallで全てバッファに読み込んで表示する場合

メモリ空間が大きい場合は一度にバッファに詰め込んで取り出せるのでパフォーマンス的に有利です。しかしメモリの枯渇が生じる可能性があるので本格的に大規模系で使う場合はレコード数をチェックしてからメモリ容量を予測して不足かどうか判断の上、実行するか判断しないと行けない場合もあります。

実行結果

DB2つを使ってjoinでinner結合して表示する。

実行結果

他のデータベースを使用する場合

21行目の「cons = db_connect(config_db(),’DB1′)」の部分のDB1をDB2にすればDB2から情報を取り出すことが出来ます。あとは全て同じです。

タグ: , , ,

備忘録:pythonマルチスレッド pasteサーバ redirectでエラー発生の場合の対処


python bottleフレームワークでは内部のマルチスレッドhttpサーバでpasteサーバが使われるケースが多い。しかし、redirect処理を行った際にエラーが吐かれてしまうという問題に遭遇しました。処理自体は問題なく動作するのですがやはり気になります。この問題を解決するためにpasteサーバ関連で呼び出されるライブラリーのコードをトレースして原因がわかりました。この記事はその備忘録として残します。

実際に起きてるエラーはこんな感じ。

そもそも20行目の「TypeError: a bytes-like object is required, not ‘str’」これが勘違いのもとだった。よくある関数returnでHTMLテンプレートに返す際にencodeやdecode処理でutf-8に変換しないと駄目な場合があります。これが抜けているのかな!?と思いきや全く違うところに問題があった。

pasteサーバでredirect処理した場合に発生するエラー出力結果

python3になってからstringsは文字コードの扱いがUnicodeに変わりました。しかしネットワーク上での通信はbyte stringになる必要があり、よく使われるライブラリーではこのUnicodeへの対応がきっちり済んでいるため問題が生じるケースが少ないのですが稀にpython2.x時代からpython3ソースコード対応が中途半端なものがあります。つまり移行が完全にできていないケースだったようです。幸いにも原因は15行目のこれ「self.wsgi_write_chunk(”)」が原因であることにすぐに気がつけた。つまりhttpプロトコルのメッセージヘッダ項目やメッセージボディが空っぽの場合にきちんと処理ができなくて20行目のエラーになってしまうというものです。


まとめると、redirectの処理はメッセージヘッダの一部項目が空であるため、ライブラリーが誤って20行目のエラーを吐き出してしまう。これを回避するためにredirectへ具体的なレスポンスコードを指定してあげることでメッセージヘッダ項目が空になることを防ぐ。

リダイレクト レスポンスコード

  • 301 Moved Permanently
  • 302 Found(Moved Temporary
  • 303 See Other
  • 307 Temporary Redirect

redirectの際にレスポンスコード301を入れて空になるのを防いだところエラーが消えた

タグ: , , ,

DoS攻撃激減。 python3.5でiptablesの国内IPのみの接続ルールを生成&適用。


pythonでiptables向けにAPNICが管理しているIP割当ブロック情報から国内IPアドレスの最新情報を集め、自動で追加するプログラムを昨年の夏頃作ったのですが、pythonの環境やライブラリーバージョンが現状と合わなくなってきたので再度作りなおししました。python3.5で動作しました。追加したルールが保存されるように「service iptables save」を実行してください。(Redhat6.x,CentOS6.x系 CentOS7でもiptablesに切り替えで使えます)

2018/6/2 SCRIPTコードを改定しました。

実行する。

非常にデータが大きいため処理に時間がかかります。実行後はiptablesのルールを保存しましょう。

再度ルールを実行したい場合は全ルールを破棄します。iptablesを-Fオプションで実行すると全クリアになります。

タグ: , , , ,

Python3 Bottleフレームワーク入門(その10)- WSGI via uwsgi Server on SSL


今回は、Pythonでお馴染みのWSGI(外部サーバ)の技術を使ったSSL接続を試してみます。

WSGIとはシンプルすぎて非常にわかりにくいものですが、簡単に言うと通常コマンドラインで標準出力しているものを内部及び外部のhttpサーバで使われているネットワークの土管にバイパスしてブラウザへの表示を拝借してしまおうという発想です。

bottleフレームワークはもとからWSGIの内部WEBサーバを走らせる機能が標準装備しているため外部WEBサーバ使う理由に何が必要なのか?という疑問を持つ人もいると思います。それはbottleの標準WEBサーバはシングルスレッドなので多くの接続を処理したり、SSL接続をしたい場合はこのようにWSGIの外部サーバ連携する技術を駆使しないと現実的なWEBサーバとして利用できないのです。ではまず最初にbottleで簡単なWEBサーバを起動してみましょう。

index.pyを実行するとシンプルなWEBサーバ(正確に言うとシングルスレッド内部WSGIサーバです。)が起動します。

ここまでは誰でも普段からやっていると思います。

今度はこれを外部接続WSGI仕様に変えてソースを改良します。
特にWSGI関連ライブラリーを呼び出す必要はありません。ポイントはapplicationというクラスです。uWSGIから呼び出すため、mainは生成されずelseへ分岐します。ここへbottleのインスタンスを渡してあげます。このケースではdefault_app()ですが、もしご自分でbottleのインスタンスを他の変数やクラスへ継承させているならそれを代入しましょう。これがWSGI仕様にする要になります。

最下行にたった2行が追加されました。たったこれだけです。大変シンプルですね。

次はuwsgiというシンプルな外部WSGI接続が可能なWEBサーバーをpipでインストールします。

これでブラウザへ接続をすれば「Hello World! Bottle and uWSGI!」と表示されます。

次にwsgiでSSL接続を行ってみましょう。pythonのプログラムは特に修正する必要はありません。uwsgiのネットワークトンネルを拝借していますから、SSLの処理はuwsgiの機能で行います。


テスト環境でSSLサーバの設置を行う場合のやり方

よくオレオレ証明書を使う方がいますが、今は安いSSL証明書なら年間ライセンス1000円程度で購入できます。私はテスト用に1000円のSSLライセンスを購入して実験利用しています。
テスト環境で実験する場合はWindows側では”c:\Windows\System32\Drivers\etc\hosts”を管理者権限モードでテキストエディタで開いてDNSの照合よりも先にhostsファイルに登録したドメインとIPアドレスを参照するように予めテスト用のドメインを登録しておきます。ドメイン認証だけのSSLならこれでうまくいきます。それ以外の認証が入っている高価なSSLだと「安全ではない」がでるかもしれません。


こうすることで、SSL証明書のドメインとテスト用のサーバのドメインを一致させブラウザを騙します。そうしないとhttps接続時に赤色でバツや三角がブラウザ上のURLそばのアイコンが表示されます。


証明書の準備と取得証明書のマージ処理からサーバ起動まで

証明書が購入できたら次に作業するフォルダーに証明書用のフォルダーを作成します。今はとりあえずauthという名前のフォルダーを作成します。そこに購入した証明書ファイルを配置します。以下のような最低でも3種類のファイルが必要となります。

  • サーバー証明書(server.crt)
  • サーバ秘密鍵(server.key)
  • 中間証明書(ca-bundle.ca)

これらのファイルで中間証明書はuwsgiコマンドのパラメータで指定する事ができないため、中間証明書とサーバ証明書は1つのファイルにマージします。

マージされた証明書は必ず一度エディターで中を開けてチェックして下さい。順番は関係あります。サーバ証明書が一番上に来るようにして下さい。また中間証明書はサーバ証明書のend区切りコメントに連続にならないように改行を必ず入れてください。そうしないとエラーになります。

下記は証明書を結合した場合の証明書同士のボーダーを示しています。予め結合する前にサーバ証明書に改行を入れておくと安全です。必ず結合後はチェックしましょう。

次のようにuwsgiを起動する際に鍵ファイルや証明書を指定します。

実際の実行時のターミナル画面は次のようになります。

実際に本番稼働させる場合は実行用のユーザとグループを用意してchrootさせて実行すると以下の警告はなくなります。

その他uwsgiの実行オプションはここ

パラメータでスレッド数、プロセス数やパフォーマンスに関するその他の項目、ログの場所など細かくチューニングが可能です

スレッド数やプロセス数を増やせば必ずしもマルチスレッドに対応したコンテンツになるとは限りません。例えばコンテンツがREAD主体の静的コンテンツはスレッド数やプロセス数を増やせばマルチスレッドになると思いますが、動的に変化するコンテンツは内部側でもマルチスレッド対応(thread_safeは必須)にしないと駄目なケースが多いと思います。というか、多くのケースはPythonコンテンツ側もマルチスレッド動作に対応する必然性があるかもしれません。マルチスレッド対応とは2種類の意味があります。DBなどファイル書き込みが複数のスレッドで競合が起きないようにするという意味と複数のコネクションを1プロセスで捌くという意味です。今回の場合はスクリプト起動なので必要最低限で前者が必須のケースです。マルチスレッド通信はProxyタイプ通信で連携する場合では必須なので他の章を参考にしてください。

ブラウザから以下のようにアクセスができたら成功です。中間証明書がきちんと登録ができていないと今のブラウザは厳しいので「このサイトは安全でない」と表示されるので要注意です。必ず中間証明書とサーバー証明書をマージして区切り線が前後に改行されていることを確認しましょう。



Python Bottle Framework入門 全13回
1.基礎編サーバ起動
2.リクエストメソッド
3.ORM Peewee (MySQL)
4.ORM Peewee CRUD
5.Cookie And Session
6.Abort and Redirect
7.マルチスレッドWEBサーバ
8.デーモン化
9.Json
10.WSGI on SSL
11.Apache連携起動(外部WSGI) SSL接続
12.Apache連携起動(ReverseProxy)SSL接続
13.hprox連携起動(ReverseProxy)SSL接続&HTTP2対応

合わせて読みたいPython MySQL操作関連

タグ: , , , , ,

Apacheログからセキュリティアタックの解析をする。


ApacheのWEBログから攻撃の手法を読み取るツールをご紹介したいと思います。ツールの言語はPython2.x系で記述されていますが、少し手を入れてpyhon3.xで動作するパッチを作ってみました。2.x系と動作比較した感じは動作良好のようです。

コードGoogleで登録されているapacheログのセキュリティ解析ツール(scalp)

https://code.google.com/archive/p/apache-scalp/

それではダウンロードして準備しましょう。

python3.x系で動作させる場合はこのパッチを適用

実行にはApacheのログが必要です。まずは例えばフォルダー「input」を作ります。そこへアパッチのログを一旦コピーしましょう。次に解析結果を「out」フォルダー入れるために作成します。出力結果はHTML形式にします。尚コマンドラインが長いためシェルで実行する事をお勧めします

scanする攻撃パターン検索用のスキーマ(default_filter.xml)

ブラウザにてhttp://xxx.xxx.xxx.xxx:8000/out/xxxxx.access_log_scalp_Thu-07-Sep-2017.htmlのような感じでアクセスしてみてください。下記のような表示が出てくるはずです。

まとめとして、ログが巨大な場合はsplitコマンドで予め分割して編集してから解析ツールに通すほうが良さそうです。また新たな攻撃パターン手口はdefault_filter.xmlを編集して登録すると拡張できる点は良いですね。

タグ: , , ,

1 2 3 4