実験日記

Python WEBアプリをCGIで使う(後編:Part1)

Pythonで作業を始める前にやっておきたいのが、デフォルトのエンコードセッティング。
かならずやっておきましょう。

プログラムからやるのではなく、環境設定として行うことで文字種別に関するエラーがコレで半減する。

インストールしているpython libraryのパスにある”site-packages”配下に作成する。
通常は/usr/lib/python2.6/site-packagesがCentOSのパスです。
# vi sitecustomize.py

import sys
sys.setdefaultencoding("utf-8")

プログラムから設定するdefaultencodingの設定もあるが、呼び出しモジュール側のことも考えるとエラーに成ってしまうことも度々。だからこの設定をしておくと全体でデフォルト文字コードを設定してくれる。

それでは、必要最低限のブラウザへ表示させる簡単なコードを書いてみましょう。WEBサーバの設定は前の記事を参考にしてください。
ブラウザへ出力するには、どの言語でも共通ですがこの2行を忘れずに

print "Content-Type: text/html;charset=utf-8"
print

以下のプログラムはIDとパスワードをブラウザ上へ出力する簡単なプログラムです。例えばワードプレスで会員サイトを作ろうと思った時にIDとパスワードを大量にまとめて発行したいときなど手作業でやったら大変です。ということでそのベースとなるサンプルプログラムです。
IDは何回やっても同じですが、ここはDBにあるシーケンシャルIDの最大値を求めて最終的に作り変えればよいでしょう。PDは毎回乱数で作成しMD5で暗号化していますのでWPのユーザテーブルに直接書き込んで使えば、もちろん問題なく使えます。

仕様:
クラス IdInf_gen にIDの長さとPDの長さを指定してIDとPDを得るプログラム。
コンソールで実行しても、ブラウザで実行しても動作するプログラムです。必ず最後はアクセス権を実行権限をつけましょう。

# vi disp.py

#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
import string
import random
import hashlib
import datetime

#ログイン名のダミー情報
base_code ="G"
b = 1

class  IdInf_gen(object):
    def  __init__(self,len=5,pw_len=10):
       self.__len  = len
       self.__pw_len = pw_len

    def  inst(self):
       fm = "%0" + str(self.__len) + "d"
       data = fm % b
       data = base_code + data
       pw = self.pw_gen()
       return {'id':data,'pw':pw[0],'pw_org':pw[1]}

    def  pw_gen(self):
       length = self.__pw_len
       src = string.digits + string.letters
       s=''
       for i in range(1, length):
          s += random.choice("suhvq4v87wrnqweq3b234tb2vNN")
       d = hashlib.md5(s).hexdigest()
       return [d,s]

def main():
    #第一引数がIDの長さ、第二引数がパスワードの長さ`
    p = IdInf_gen(10,15)
    print "Content-Type: text/html;charset=utf-8"
    print
    print "ID:" + p.inst()['id'] + "<br>"
    print "Crypt PD:" + p.inst()['pw'] + "<br>"
    print "ORIGIN PD:" + p.inst()['pw_org'] + "<br>"

if __name__  ==  '__main__':
    main()

# chmod 755 disp.py

コンソールで確認)
# ./disp.py

ブラウザで確認)
http://yourhost/yourpath/disp.py

Python WEBアプリをCGIで使う(前編)

「Python WEBアプリをCGIで使う」は一番手軽な作り方。既に作られているプログラムの継接ぎやちょっとした機能を作るならこれで十分。
確かに簡単ですから。WEBサーバへの設定が少なくて済む。

ApacheのWEBサーバ設定は基本気をつけるのは2箇所くらい。
CGIスクリプトのパス設定とExecCGIを追加すること。WEBサーバは言語に関係なくコンテンツプログラムを拡張子.cgiにしておけば
デフォルト設定でハンドラーのあたりはOKだ。 下記に仮想ホストのサンプルを貼り付ける。

<Virtualhost *:80>

ServerName  test.example.com
ServerAdmin test@example.com
CustomLog logs/test.access_log common
ErrorLog logs/test.error_log

DocumentRoot /home/www/html/httpdocs

ScriptAlias /cgi-bin/ /home/www/html/cgi-bin/
    <Directory "/home/www/html/cgi-bin">
        AddHandler cgi-script .py .cgi
        AllowOverride None
        Options ExecCGI SymLinksIfOwnerMatch
        Order allow,deny
        Allow from all
    </Directory>
   <Directory "/home/www/html/httpdocs">
        AllowOverride All
        Options ExecCGI SymLinksIfOwnerMatch
        Order allow,deny
        Allow from all

   </Directory>
</virtualHost>

WEBアプリをPythonで作るという事は!

PythonでWEBアプリを作るというのは、方法が幾つか用意されています。

  1. Apache等のWEBサーバの数ある言語の一つとしてCGIプログラムを作る。
  2. WSGIとしてpython単独でWEBサーバ兼コンテンツとして動作
  3. WSGI ScriptとしてApacheと連携
  4. WSGIとしてApacheでラップして動作

Pythonフレームワークの場合は、2番と4番をよく使います。
開発中は2番で作業をおこない、本番で4番というパターン。

開発中はサーバを再起動しないと行けない機会がおおくなるため、2番がいいんだよね。
本番は、1台のコンピュータで複数の仮想ホストを立てる事を考えるとApacheの機能を利用するのが一番手軽。だから4番。

ネットでPython関連のプログラムサンプルは検索すると沢山出てくるが、注意が必要な事は上記のどれで動作させているかということ。
これ、WEBのコンテンツを作る場合において非常にプログラムの書き方が変わってくるので要注意です。

例えば、WEBフォームの入力をGET,POSTで取り出す時に大きな差が出てきます。またブラウザーにエコーさせるということはスクリプト
ならprintで出力しますし、サーバ系ならreturnやレンダリングエンジンでエコーします。

Python インストールモジュールの確認

パイソンでモジュールのインストールを行うにはpipかeasy_installを使いますが、私は基本的にpipで導入します。

pip使うにしてもeasy_installが必要です。
これはsetuptoolsに入っているので。OSのパッケージ管理で導入します
CentOS,Fedora,REHEならyum installなどでsetuptoolsを入れましょう。

# yum install python-setuptools
後は自分の構築環境&ユーザで導入しましょう。
$ easy_install pip

現在インストール済みパッケージの表示

$ pip freeze

パッケージの検索

$ pip search

パッケージインストール

$ pip install

Pythonの仮想環境を作る

Pythonをやり始めると、まず最初に覚えたほうがよいなーと思うことは開発環境つくりです。

開発環境を作るという行為は、簡単に言ってしまうとLINUXのOSを入れて必要なソフトウェア・パッケージを入れる作業です。
沢山のお客様を抱えていると、単純に1台のコンピュータでは複数の」お客さまの事情にあった構成にできないケースがあります。
今なら、VSPサービスのような仮想マシンを立てるのが主流となっていますが、WEB系の世界に目を向けるとそこまでやらなくても
よいかなーと思います。

PHPにしろPythonにしろ、言語システムなるものを最初に導入しますが、オプションで導入するライブラリーパッケージが沢山
あり開発環境に合わせて取捨選択が必要となります。

Pythonを使い出してわかったことは、Pythonは有効バージョンがいくつか存在しており、微妙に仕様がちがうためこの点が
意外と問題になりやすい。PHPでもまあ、こんなことよくありますが。

で、Pythonはこの問題をクリアするのが簡単なです。
ようは、バージョンやパッケージに依存しない閉じた世界の開発環境を手軽に作るシステムが存在します。
それがvirtualenvという仕組みです。

virtualenvはpipコマンドからインストールします。
$pip install virtualenv

virtualenvを使って仮想環境を構築)

3パターン方法を案内します。

※ DEST_DIRは実際の自分の使っているパスに置き換えてください。
$ virtualenv DEST_DIR $ python virtualenv.py DEST_DIR <—-仕様付きで構築
$ virtualenv –no-site-packages DEST_DIR <—-余計なパッケージがはいらないまっさらで構築

仮想環境をイネーブルします。作業を開始する前にこの作業を実施しないとパスとか変数が通りません。
$ cd DEST_DIR
$ source bin/activate

sendmailAnalyzerでメールの送受信ログを解析。

なかなか、良いオープンソースを久しぶりに見つけた。
以前からメールの着信状況を調べたかったので、スパムメール対策のついでに解析できたらいいなーと思ってました。sendmailAnalyzerというオープンソースがあるんですね。知りませんでした。

さっそく導入してみましたがいい感じ。


あらかじめcpanで以下をインストールしましょう。
> install MIME::Base64;
> install MIME::QuotedPrint;
> install GD
> install GD::Graph
> install GD::Text
> install GD::Graph3d

あとは以下をコピぺですんなり入ります。
wget http://downloads.sourceforge.net/project/sa-report/sa-report/8.7/sendmailanalyzer8.7.tar.gz
tar xvfz sendmailanalyzer-8.7.tar.gz
cd sendmailanalyzer-8.7/
perl Makefile.PL
make && make install
/usr/local/sendmailanalyzer/sendmailanalyzer -f
/usr/local/sendmailanalyzer/sa_cache
cat << EOF >> /etc/httpd/conf/httpd.conf
Alias /sareport /usr/local/sendmailanalyzer/www

Options ExecCGI
AddHandler cgi-script .cgi
DirectoryIndex sa_report.cgi
Order deny,allow
Deny from all
Allow from all

EOF
service httpd restart
cd /tmp/sendmailanalyzer-8.7/start_scripts
chown root:root *
chmod 755 *
cp -p sendmailanalyzer /etc/init.d/sendmailanalyzer
chkconfig –add sendmailanalyzer
service sendmailanalyzer restart
echo << EOF >> /var/spool/cron/root
#
# SendmailAnalyzer log reporting daily cache
0 */1 * * * /usr/local/sendmailanalyzer/sa_cache > /dev/null 2>&1
#
EOF

LinuxでGoogle Driveを使う

LinuxでGoogleDriveは正式にんはサポートされていません。しかしInsyncというソフトがGoogleDriveに対応しています。
これを使って導入するとDropBoxのような感じでツールバーにアイコンが表示され利用ができます。

ダウンロードのURLはここ
https://www.insynchq.com/

Linuxは3種類用意されていますので、お使いのディストリが何系かわかったらそれに合わせたダウンロード
を行ってください。
https://www.insynchq.com/downloads/linux

CentOSならFedoraアイコンのInsync for GNOME Shellをご利用ください。
Ubuntu系ならUbuntuアイコンのInsync for Unityを利用ください。

ダウンロードしてインストーラ実行すると、WEB画面が開きGoogleDriveへの接続許可をとる画面がでてきますので
GoogleDriveへのアカウント登録を行うと接続が可能になります。

後は、自動で起動しないので自動起動するように起動スクリプトに入れましょう。

メールサーバ構築 | sendmail + Dovecot

10日でおぼえるLinuxサーバーでは、メールサーバの構築をわざと外して執筆をしました。これは理由があってなのですがメールサーバを構築する難しさが一昔前より困難になっているからです。要するに初心者には敷居がかなり高いためです。

現在のメールサーバはスパム対策を意識して作る必要がデフォルトで必須となります。これが難しさの一因となっています。
しかし、メールサーバ構築の方法について切望する方も多いため、今回はsendmail + dovecotで構成する構築方法を案内します。

通常CentOSでメールサーバを導入するというとPostfixがデフォルトで入っています。しかし、昔ながらのsendmailもなかなか負けていません。カスタマイズの柔軟差では歴史的な蓄積がありますので、ここで紹介するのはsendmailにしようと思います。

1.最初の準備(パッケージのインストール)

既にインストールされているPostfixを削除しsendmailをインストールします。
もちろんroot権限でインストールします。

# yum  remove   postfix
# yum  install  sendmail (sendmailメールパッケージ)
# yum install sendmail-cf (sendmialのCF作成ツール関連)

SPF(センダーポリシーフレームワーク)の導入。
# wget http://www.city-fan.org/ftp/contrib/yum-repo/city-fan.org-release-1-10.rhel6.noarch.rpm
# vi /etc/yu.repos.d/city-fan.org.repo

[city-fan.org]
name=city-fan.org repository for Red Hat Enterprise Linux (and clones) $releasever ($basearch)
#baseurl=http://mirror.city-fan.org/ftp/contrib/yum-repo/rhel$releasever/$basearch
mirrorlist=http://mirror.city-fan.org/ftp/contrib/yum-repo/mirrorlist-rhel$releasever
enabled=0
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-city-fan.org

smf-spfのパッケージをインストールします。
# yum –enablerepo=city-fan.org install smf-spf

メールドメインのDNSサーバへSPFの登録

正引きDNSレコードへ追加してください。
# vi xxxxxx.zone
@ IN TXT “v=spf1 mx ~all”

※ ‘-all’と’~all’の指定に注意。チルダの場合は除外メールの場合SPF:failを件名の先頭に追加され、実際には削除されない。
ある一定期間観測してからホワイトリスとを作って登録し、全除外を実行’-all’とするとよいだろう。
ホワイトリスとは/etc/mail/smfs/smf-spf.conf の編集により実現が可能です。

編集が終わったらDNSを再起動。
# service named restart

2.sendmail.mcの編集(sendmailサーバの設定中間ファイル)

sendmailの動作を決めるのはsendmail.cfファイルです。しかしこのファイルは設定が難しいため中間の設定ファイルとしてsendmail.mcを編集します。

# cd /etc/mail
# vi sendmail.mc

(修正する内容だけピックアップします。)
dnl # SMTP_AUTHの設定
TRUST_AUTH_MECH(`EXTERNAL DIGEST-MD5 CRAM-MD5 LOGIN PLAIN’)dnl
define(`confAUTH_MECHANISMS’, `EXTERNAL GSSAPI DIGEST-MD5 CRAM-MD5 LOGIN PLAIN’)dnl
dnl # procmailの設定
define(`PROCMAIL_MAILER_PATH’, `/usr/bin/procmail’)dnl
dnl # spamass-milterを動作させるためのマクロ
define(`confMILTER_MACROS_HELO’, confMILTER_MACROS_HELO`, {verify}’)dnl
dnl # smf-spfでSPFフィルターを実装
INPUT_MAIL_FILTER(`smf-spf’, `S=unix:/var/run/smfs/smf-spf.sock, T=S:30s;R:1m’)dnlFEATURE(`no_default_msa’, `dnl’)dnl
dnl # sendmailのセキュアシェル
FEATURE(`smrsh’, `/usr/sbin/smrsh’)dnl
dnl # 特定ホスト向けのメールを中継するサーバを指定する
FEATURE(`mailertable’, `hash -o /etc/mail/mailertable.db’)dnl
dnl # 仮想ホストの定義
FEATURE(`virtusertable’, `hash -o /etc/mail/virtusertable.db’)dnl
dnl # すでに削除されてしまったアカウント宛のメールに対して、 エラーメールの中に転送先アドレスの案内を含めます。
FEATURE(redirect)dnl
dnl # すべてのヘッダの送信者アドレスに、ホスト名が追加される
FEATURE(always_add_domain)dnl
dnl # 受信すべきドメインの定義を有効
FEATURE(use_cw_file)dnl
dnl # trusted-usersに記述する信頼ユーザ -fを指定してもワーニングを出されない
FEATURE(use_ct_file)dnl
dnl # procmailで配送
FEATURE(local_procmail, `’, `procmail -t -Y -a $h -d $u’)dnl
dnl # smtp接続(リレー)許可設定
FEATURE(`access_db’, `hash -T -o /etc/mail/access.db’)dnl
dnl # access_dbに受取らない設定をすることが出来ます。
FEATURE(`blacklist_recipients’)dnl
dnl # Submission Port(587)の設定
DAEMON_OPTIONS(`Port=submission, Name=MSA, M=Ea’)dnl
dnl # 25番ポートでの受信設定
DAEMON_OPTIONS(`Port=smtp, Name=MTA’)dnl
dnl # ローカルドメインでの受信有効
LOCAL_DOMAIN(`localhost.localdomain’)dnl
dnl # RBLで受信拒否
FEATURE(dnsbl,`all.rbl.jp’,`”554 Rejected ” $&{client_addr} ” found in all.rbl.jp”‘)dnl
dnl # 最大受信メッセージ容量(バイト)
define(`confMAX_MESSAGE_SIZE’,`10485760′)dnl
dnl # 1メール受信で最大50の受信者指定が可能
define(`confMAX_RCPTS_PER_MESSAGE’, `50′)dnl
dnl # バージョン情報をunknownに変更する
define(`confSMTP_LOGIN_MSG’,`unknown’)dnl
dnl # メールヘッダーに展開する際にバージョン情報をunknownに変更する
define(`confRECEIVED_HEADER’,`$?sfrom $s $.$?_($?s$|from $.$_)
$.$?{auth_type}(authenticated)
$.by $j (unknown)$?r with $r$. id $i$?u
for $u; $|;
$.$b’)dnl

sendmail.mcからsendmail.cfを作成

# make sendmail.cf
# make install-cf
以上でsendmail.cfとsubmit.cfがインストールされます。

submit.cf
sendmail 8.12では、25/TCPでメールを待ち受けるMTAと、MSA(Message submission agent)の機能が分離されました。
MSAとはローカルからのメールを587/TCPで待ち受ける特殊なMTAで、メール送信(投稿)のための構成要素です。
submit.cf はMSA のための設定ファイルで、メッセージの情報が不足していたり、形式が不完全であった場合にメッセージ形式を整形してからMSAは配送処理を行います。
標準では、/usr/bin/mailのようなMSP(ローカルホストからメールを送るプログラム)はsendmailのバイナリを実行しますが、 その際にMSAと通信してメールを送ります。
MSAはMSPから送信されたメールを受け取り、MTAに渡す機能を果たします。

受信ドメインの設定
複数のドメインを受信する場合もここ書きます。後はアカウント単位で設定をvirtusertableに書けば簡単にマルチドメイン
対応が可能です。

# vi local-host-names
xxxxxxx.com

強制受信つまりWhitelist
自分のサーバがチェックが厳しくて弾き返すなら、強制受信を以下のように行います。
# vi access
Connect:sakura.ne.jp OK
Connect:nifty.com OK
Connect:biglobe.ne.jp OK

sendmailの起動

# service sendmail start

アカウント作成はお好みで/etc/passwd,shadowでアカウントを作り、認証はsaslauthdデーモンで行います
巷のネットにあるサーバ構築情報には間違いが多くsaslauthdとauxpropをごちゃ混ぜにして説明しているサイトが多いですが
/etc/passwd使うならsaslauthdデーモンを利用します。

# /etc/sasl2/Sendmail.conf
pwcheck_method:saslauthd
mech_list: plain login cram-md5 digest-md5

# yum install cyrus-sasl # service saslauthd start
dovecotが入っている場合はdovecotも再起動してください。
# service dovecot restart

Imap – Dovecotの設定

まず最初にdovecotをインストール
# yum install dovecot
# service dovecot start

今回はシンプルな/etc/passwdで認証する方法をご紹介する。大勢のアカウントが無い、精々20人程度ならそんなもんでいいでしょう。

#cd /etc/dovecot

dovecot.confを編集します。
特にpopは必要ないでしょう。下記のようにします。
protocols = imap imaps

次に詳細を設定します。
# cd /etc/dovecot/conf.d

修正するファイルは以下の通り。
10-auth.conf
10-mail.conf
10-master.conf
10-ssl.conf
auth-system.conf.ext

1.
# vi 10-auth.conf
2カ所修正。

auth_mechanisms = plain login
include auth-system.conf.ext

2.
# vi 10-mail.confmbox_write_locks = fcntl

mail_location = maildir:~/Maildir
mbox_write_locks = fcntl

3.
# vi 10-master.conf

service imap-login {
inet_listener imap {
port = 143
}
inet_listener imaps {
port = 993
ssl = yes
}

}

4.
あらかじめ証明書は作っておいてくださいね。

# vi 10-ssl.conf
ssl = yes

ssl_cert =”xxxxxxxxx.crt”

ssl_key =”xxxxxxxxx.key”

ssl_key_password = “xxxxxxxxxx”

# vi auth-system.conf.ext

passdb {
driver = pam
# [session=yes] [setcred=yes] [failure_show_msg=yes] [max_requests=]
# [cache_key=] []
#args = dovecot
}

userdb {
# <doc/wiki/AuthDatabase.Passwd.txt>
driver = passwd
# [blocking=no]
#args =
}

# service dovecot restart

アカウント作成とパスワード設定
# useradd username
# passwd username

P218ページ phpMyAdminのパス修正 リスト4

訂正箇所:218ページ リスト4
誤:Alias    /phpMyAdmin       /usr/www/phpMyAdmin
正:Alias    /phpMyAdmin       /usr/share/phpMyAdmin

補足:
CentOSでphpmyadminを導入するとき、選択肢が2つあります。パッケージレポジトリ
rpmforgeとepelで提供されています。

導入した際の違いが若干ありフォルダーパス名に違いがあります。
/usr/share/phpmyadmin              (rpmforge)
/usr/share/phpMyAdmin             (epel)

セキュリテリティ上はAliasの後の文字(/phpsqltools)は変更した方が安全です。
多くのクラッカーがphpmyadminでアタックを繰り返すからです。
Alias     /phpsqltools      /usr/share/phpMyAdmin

もし、上記の設定をするときは以下のようにブラウザへ入力しアクセスします。
上記の場合はhttp://192/168.5.75/phpsqltools

Linux TIPS&実験室

ひさびさにリナックスサポートサイトをリニューアルしました。会社経営をしていることもあり中々時間をさけなくなっていましたが、また復活させて頑張ってサポート記事を書いていきたいと思います。

今回はサイト自体を、今はやりのレスポンシブ表示に対応させてみました。各種デバイスに合わせて最適な画面表示を行うようになっていますのでスマートフォンやタブレットでも見やすく表示させる事が可能です。

どうぞ今後ともよろしく御願いします。