end0tknr's kipple - web写経開発

太宰府天満宮の狛犬って、妙にカワイイ

最尤推定 (さいゆうすいてい) - もっともらしい母比率を求める

サイコロの偶数が6回中、2回出るときの母比率(1回当たりの偶数が出る確立)?

例として、母比率=0.5の場合、6回中、2回、偶数が出る確立を求めます。

 \Large {}_6 C_2 0.5^2 (1-0.5)^4
= \Large \frac {6!}{2!(6-2)!} 0.5^6
= \Large 15 0.5^6
 \Large ≒ 15 0.015625 ≒ 0.2343

同様に母比率=0.2, 0.3 , 0.4 , 0.8 の場合を求めます。

 \Large {}_6 C_2 0.2^2 (1-0.2)^4
= \Large 15  0.3^2 0.7^4 = 15  0.04 0.4096 = 0.24576
 \Large {}_6 C_2 0.3^2 (1-0.3)^4
= \Large 15  0.3^2 0.7^4 = 15  0.09 0.2401 = 0.324135
 \Large {}_6 C_2 0.4^2 (1-0.4)^4
= \Large 15  0.4^2 0.6^4 = 15 0.16 0.1296 = 0.31104
 \Large {}_6 C_2 0.8^2 (1-0.8)^4
= \Large 15  0.8^2 0.2^4 = 15  0.64 0.0016 = 0.01536

以上より、「0.324135」が最も大きいことから、サイコロの偶数が6回中、2回出るときの母比率は、「0.3」程度と推定できます。

最尤関数による最尤推定

http://mathtrain.jp/mle ←こちらの写経です。

次は、最尤関数を用いて、先程の最尤推定を行います。

母比率=Pとおいたとき、6回中、2回出る最尤関数は次の通り


L(P) = {}_6 C_2 P^2 (1-P)^4

L(P)を最大にするPと、log L(P)を最大にするPは同じである為、 ここで計算を楽にする為、対数をとります。(対数尤度関数)


log L(P) = log\{ {}_6 C_2 P^2 (1-P)^4 \}
= log {}_6 C_2 + 2 log P + 4 log (1-P)

Pが最大値をとるとき、log L(P)の傾き? = 0 となる為、Pで微分します。


\Large \frac {d}{dP} log L(P) = 2 \frac {1}{P} + 4 \frac {1}{(1-P)} (1-P)'

\Large 0 = 2 \frac {1}{P} - 4 \frac {1}{(1-P)}

\Large P = \frac {1}{3}

log(1-P)の微分で、合成関数の微分を利用することをすっかり忘れていました。

二項分布と、多項分布

多項分布...すっかり忘れてた

二値変数

「合格or不合格」「表or裏」のように2つの値を取り得る変数

二項分布

二値変数において、成功率=P、試行回数=n、成功回数=kとなる確率は以下の通り

 _nC_k P^{k} (1 - P)^{n-k} = \Large{\frac{n!}{k!(n-k)!}} P^{k} (1 - P)^{n-k}

多値変数

「二値変数」と異なり、3つ以上の値を取り得る変数

多項分布

変数の種類=kの多値変数において、各値の発生確立=P1, P2,..., Pk、発生回数=x1, x2,..., xk となる確立は以下の通り

\Large{\frac{n!}{x_1! x_2! ... x_k!}} P_1^{x_1} P_2^{x_2} ... P_k^{x_k}

さくらレンタルサーバでのsmtpメール送信は、Net::SMTPS for perlのauth()で、LOGIN を指定

end0tknr.hateblo.jp

以前、書いたgmail.comのstmp送信をそのまま利用できなかったので、いろいろ試してみたら、以下のように auth() で AUTHMETHOD='LOGIN' を指定したら動きました。

http://search.cpan.org/perldoc?Net%3A%3ASMTPS

#!/usr/local/bin/perl
use strict;
use utf8;
use Encode;
use Net::SMTPS;
use Data::Dumper;

my $SMTP_CONF =
    {host     => 'ないしょ.sakura.ne.jp',
     port     => '587',
     from     => 'ないしょ',
     auth_uid => 'ないしょ',
     auth_pw  => 'ないしょ',
     ssl=>        'starttls', # ssl / starttls / undef
     auth_method=>'LOGIN'     # CRAM-MD5 (default) / LOGIN / PLAIN / DIGEST-MD5
    };


    
main( @ARGV );

sub main {
    my ($mailto) = @_;
    
    my $smtp = Net::SMTPS->new(
        $SMTP_CONF->{host},
        Port  => $SMTP_CONF->{port},
        doSSL => $SMTP_CONF->{ssl},
        Debug => 1
    );

    $smtp->auth( $SMTP_CONF->{auth_uid},
                 $SMTP_CONF->{auth_pw},
                 $SMTP_CONF->{auth_method} )
        or die "can't login smtp server";

    my $mailto = [ $mailto ];
    my $mailto_str = join( ',', @$mailto );

    my $subject_org = 'これはテストです';
    my $subject = Encode::encode( 'MIME-Header-ISO_2022_JP', $subject_org );

    my $message = <<EOF;
このメールはテストです
EOF

    #メールのヘッダーを構築
    my $header = << "MAILHEADER_1";
From: $SMTP_CONF->{from}
Return-path: $SMTP_CONF->{from}
Reply-To: $SMTP_CONF->{from}
To: $mailto_str
MAILHEADER_1

    $header .= <<"MAILHEADER_2";
Subject: $subject
Mime-Version: 1.0
Content-Type: text/plain; charset = "ISO-2022-JP"
Content-Transfer-Encoding: 7bit
MAILHEADER_2

    $message = Encode::encode( 'iso-2022-jp', $message );

    $smtp->mail( $SMTP_CONF->{from} );
    $smtp->to(@$mailto);
    $smtp->data();
    $smtp->datasend("$header\n");
    $smtp->datasend("$message\n");
    $smtp->dataend();
    $smtp->quit;
}

DockerToolbox-1.12.0.exe を win7 に installしたら、Docker Quickstart Terminal の実行でerror

https://www.docker.com/products/docker-toolbox

https://github.com/docker/toolbox/releases/download/v1.12.0/DockerToolbox-1.12.0.exe

をinstall後、Docker Quickstart Terminal でerror...

Error creating machine: Error in driver during machine creation: Unable to start the VM: C:\Program Files\Oracle\VirtualBox\VBoxManage.exe startvm default --type headless failed:
VBoxManage.exe: error: The virtual machine 'default' has terminated unexpectedly
 during startup with exit code 1 (0x1).  More details may be available in 'C:\Us
ers\endo\.docker\machine\machines\default\default\Logs\VBoxHardening.log'
VBoxManage.exe: error: Details: code E_FAIL (0x80004005), component MachineWrap,
 interface IMachine

Looks like something went wrong in step ´Checking if machine default exists´..
. Press any key to continue...

↑このように表示されたので、 VBoxHardening.log を覗いてみると、以下の通り。 「Try 'sc.exe query vboxdrv'」らしいので実行してみましたが、原因は特定できず。

23c0.1744: supR3HardenedWinInitAppBin(0x0): '\Device\HarddiskVolume2\Program Files\Oracle\VirtualBox'
23c0.1744: System32:  \Device\HarddiskVolume2\Windows\System32
23c0.1744: WinSxS:    \Device\HarddiskVolume2\Windows\winsxs
23c0.1744: KnownDllPath: C:\Windows\system32
23c0.1744: supR3HardenedVmProcessInit: Opening vboxdrv stub...
23c0.1744: Error opening VBoxDrvStub:  STATUS_OBJECT_NAME_NOT_FOUND
23c0.1744: supR3HardenedWinReadErrorInfoDevice: NtCreateFile -> 0xc0000034
23c0.1744: Error -101 in supR3HardenedWinReSpawn! (enmWhat=3)
23c0.1744: NtCreateFile(\Device\VBoxDrvStub) failed: 0xc0000034 STATUS_OBJECT_NAME_NOT_FOUND (0 retries)

Driver is probably stuck stopping/starting. Try 'sc.exe query vboxdrv' to get more information about its state. Rebooting may actually help.
2438.2818: supR3HardenedWinCheckChild: enmRequest=2 rc=-101 enmWhat=3 supR3HardenedWinReSpawn: NtCreateFile(\Device\VBoxDrvStub) failed: 0xc0000034 STATUS_OBJECT_NAME_NOT_FOUND (0 retries)

Driver is probably stuck stopping/starting. Try 'sc.exe query vboxdrv' to get more information about its state. Rebooting may actually help.
2438.2818: Error -101 in supR3HardenedWinReSpawn! (enmWhat=3)
2438.2818: NtCreateFile(\Device\VBoxDrvStub) failed: 0xc0000034 STATUS_OBJECT_NAME_NOT_FOUND (0 retries)

Driver is probably stuck stopping/starting. Try 'sc.exe query vboxdrv' to get more information about its state. Rebooting may actually help.

DockerToolbox-1.12.0.exe の前に既にinstallしていたvirtual box 5.0.24 のcentosも起動しなくなったので、コントロールパネルから「修復」を実行したら、dockerもvirtualboxも問題なく起動するようになりました。 何だったんでしょうね? f:id:end0tknr:20161004072153p:plain

download streaming file by rtmpdump and , convert to mp4 by ffmpeg

#!/usr/local/bin/perl
use strict;
use warnings;
use utf8;
use Encode;
use FindBin;
use LWP::UserAgent;
use XML::Simple;
use Data::Dumper;

## NHKゴガク https://www2.nhk.or.jp/gogaku/english/

my $MUSIC_OUT_DIR = $FindBin::Bin;

my $MUSIC_LIST_ROOT = 'https://www2.nhk.or.jp/gogaku/st/xml';
my $MUSIC_LIST_CHANNELS =
    {english=>[
               'enjoy',         #エンジョイ・シンプル・イングリッシュ
               'basic1',        #基礎英語1
               'basic2',        #基礎英語2
               'basic3',        #基礎英語3
               'kaiwa',         #ラジオ英会話
               'timetrial',     #英会話タイムトライアル
               'kouryaku',      #攻略!英語リスニング
               'business1',     #入門ビジネス英語
               'business2',     #実践ビジネス英語
              ],
    };

# There are some paramaters
# in https://www2.nhk.or.jp/gogaku/st/flash/sound/ggk_str_pc3.swf , below.
# You can extract from swf file
#  by Flare ( http://www.nowrap.de/flare.html ).
my $MUSIC_FILE_ROOT = 'rtmpe://flvs.nhk.or.jp:1935/ondemand';
my $MUSCI_FILE_SUB_PATH = 'mp4:flv/gogaku-stream/mp4';

my $RTMPDUMP_CMD = '/usr/local/bin/rtmpdump';
my $FFMPEG_CMD = '/usr/bin/ffmpeg';

main(@ARGV);

sub main {
    my (@cmd_args) = @_;

    for my $lang (sort keys %$MUSIC_LIST_CHANNELS ){
        for my $channel (@{$MUSIC_LIST_CHANNELS->{$lang}}){
            ## DOWNLOAD CHANNEL INFOS
            my $channel_infos = get_music_list($lang,$channel);
            
            next if(ref($channel_infos) ne 'ARRAY' or
                    scalar(@$channel_infos) ==0 );

            my $out_dir = get_output_dir($lang,$channel);

            for my $channel_info ( @$channel_infos ){
                ## DOWNLOAD MUSIC FILE by rtmpdump
                my $music_file = get_music_file($channel_info, $out_dir);
                next unless $music_file;

                sleep(2);
                
                ## CORRECT by ffmpeg
                my $mp4_file = conv_to_mp4($music_file);
                print Encode::encode('utf8',"DONE $mp4_file"),"\n";
                
                unlink $music_file or die "$music_file$!";
            }
        }
    }
}

sub conv_to_mp4 {
    my($org_file) = @_;

    my $new_file = "$org_file.mp4";
    my $cmd =
        "$FFMPEG_CMD -loglevel error -y -i $org_file -acodec copy $new_file";
    
    my $fh;
    unless( open $fh, '-|', $cmd ){
        print STDERR Encode::encode('utf8',"fail open $cmd"),"\n";
        return;
    }
    unless( close($fh) ){
        print STDERR Encode::encode('utf8',"fail close $cmd"),"\n";
        return;
    }

    return $new_file;
}

sub get_output_dir {
    my($lang,$channel) = @_;

    my $out_dir_0 = join('/',$MUSIC_OUT_DIR,$lang);
    if(not -d $out_dir_0){
        mkdir $out_dir_0 or die "fail mkdir $out_dir_0 $!";
    }
    return $out_dir_0;

    # my $out_dir = join('/',$MUSIC_OUT_DIR,$lang,$channel);
    # if(not -d $out_dir ){
    #     mkdir $out_dir or die "fail mkdir $out_dir $!";
    # }
    # return $out_dir;
}

sub get_music_file {
    my ($channel_info, $out_dir) = @_;

    my $url = join('/',
                   $MUSIC_FILE_ROOT,
                   $MUSCI_FILE_SUB_PATH,
                   $channel_info->{file});
    my $out_file = join('/',
                        $out_dir,
                        "$channel_info->{title}_$channel_info->{hdate}");
    my $cmd = "$RTMPDUMP_CMD --quiet -r $url -o $out_file";
    my $fh;
    unless( open $fh, '-|', $cmd ){
        print STDERR Encode::encode('utf8',"fail open $cmd"),"\n";
        return;
    }
    unless( close($fh) ){
        print STDERR Encode::encode('utf8',"fail close $cmd"),"\n";
        return;
    }

    return $out_file;
}

sub get_music_list {
    my ($lang, $channel) = @_;

    my $url = join('/',$MUSIC_LIST_ROOT,$lang, $channel,'listdataflv.xml');
    my $ua = LWP::UserAgent->new;
    my $res = $ua->get($url);
    if(not $res->is_success ) {
        print STDERR $res->status_line , " $url\n";
        return [];
    }

    my $xml_content = $res->content;
    $xml_content = Encode::decode('utf8',$xml_content);
    my $ret = XML::Simple::XMLin($xml_content);

    return $ret->{music};
}

open amを「 〜.jp」のようなccTLDの場合は3つ以上の「.」が必要

https://github.com/k-tamura/openam-book-jp/blob/master/preparing-for-installation.md に、

テスト目的のためであっても、localhostドメインを使用しないで下さい。 OpenAMの動作は、ドメイン名に基づいて返されるブラウザのクッキーに依存しています。基本的には、少なくとも2つの「.」(ドット)を含むドメイン名を使用していることを確認して下さい。 例) openam.example.com ※正確には、OpenAMインストール時の「Cookie ドメイン」に含める「.」の数は、「〜.com 」のようなgTLDの場合は2つでも構いませんが、「 〜.jp」のようなccTLDの場合は3つ以上が必要です。

しっかり記載されていた。勉強になります。

特に

したがって「.example.com」や「.example.co.jp」は適切であっても、「.example.jp」は不適切ということになります。

には驚いた。

pythonで、任意のdirにライブラリのpathを通す

#!/usr/local/bin/perl
use strict;
use warnings;
use utf8;
use FindBin;
use File::Spec;
use lib File::Spec->catdir($FindBin::Bin, '../lib');
   :

perlでは上記のように「use lib , FindBin」を使用していましたが pythonでは、以下のように「import sys,os」や「sys.path.append()」を使うみたい。

init.py」の配備もポイントみたい

$ cat script/foo.py 
#!/usr/local/bin/python
# coding: utf-8
import sys,os
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../lib')

from TestClass import TestClass

def main():
    test_obj = TestClass(3)
    print test_obj.width


if __name__ == '__main__':
    main()
$ cat lib/TestClass.py
# coding: utf-8

class TestClass(object):
    def __init__(self, width): #constractor
        self.width = width
$ tree
.
├── lib
│   ├── __init__.py
│   └── TestClass.py
└── script
     └── foo.py

App::cpanminus と OrePAN で、localにcpan mirrorを作成し、そこからinstall

internetに接続されていない環境に 対象のperl moduleをinstallする必要があったので、OrePANを使ってみみた。

前準備

事前に本番機には、App::cpanminus (cpanmコマンド)、 開発機?には、OrePAN + App::cpanminus (cpanmコマンド)をinstallしておいて下さい。

開発機にcpan-mirror を作成し、本番機へscp

$ cpanm -L local-tmp --save-dists=cpan-mirror Plack::Middleware::ReverseProxy 
$ cpanm -L local-tmp --save-dists=cpan-mirror Amon2
$ cpanm -L local-tmp --save-dists=cpan-mirror DBI
$ cpanm -L local-tmp --save-dists=cpan-mirror DBD::SQLite
$ cpanm -L local-tmp --save-dists=cpan-mirror DBD::mysql
$ cpanm -L local-tmp --save-dists=cpan-mirror DBIx::Class
  :

↑こちらのようなコマンドで、search.cpan.org からmodule ダウンロードのみ行います。

その後、↓こちらのコマンドでmodule一覧(index file)を作成し、 cpan-mirrorを本番機へscpします。

$ orepan_index.pl -r ./cpan-mirror
$ tar -zcvf cpan-mirror.tar.gz cpan-mirror/
$ scp -i ~/.ssh/id_rsa cpan-mirror.tar.gz ???.???.???.???:tmp/

本番ではscpされたcpan-mirrorからinstall

後は簡単。

# cd /home/endo
# cpanm --mirror=file:///home/endo/cpan-mirror --mirror-only  Amon2
# cpanm --mirror=file:///home/endo/cpan-mirror --mirror-only  DBI
   :

mysql5.7 をsrcからinstall

end0tknr.hateblo.jp

以前、↑こちらで mysql5.5をinstallしましたが、5.7では少々異なりましたので

install mysql 5.7

$ wget http://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.14.tar.gz
$ tar -xvf mysql-5.7.14.tar.gz
$ cd mysql-5.7.14
$ cmake . \
   -DCMAKE_INSTALL_PREFIX=/usr/local/mysql \
   -DDEFAULT_CHARSET=utf8 \
   -DDEFAULT_COLLATION=utf8_general_ci \
   -DENABLED_LOCAL_INFILE=true \
   -DWITH_INNOBASE_STORAGE_ENGINE=1 \
   -DWITH_EXTRA_CHARSETS=all \
   -DWITH_READLINE=ON
  :
CMake Error at cmake/boost.cmake:81 (MESSAGE):
  You can download it with -DDOWNLOAD_BOOST=1 -DWITH_BOOST=<directory>

  This CMake script will look for boost in <directory>.  If it is not there,
  it will download and unpack it (in that directory) for you.

  If you are inside a firewall, you may need to use an http proxy:

  export http_proxy=http://example.com:80

Call Stack (most recent call first):
  cmake/boost.cmake:238 (COULD_NOT_FIND_BOOST)
  CMakeLists.txt:455 (INCLUDE)
-- Configuring incomplete, errors occurred!

mysql5.7よりboostが必要になったようです。

そこで、cmakeのoptionに 「-DDOWNLOAD_BOOST=1 -DWITH_BOOST=/home/endo/tmp/」を追加すると boostを勝手にdownloadしてくれます。

cmake . \
   -DCMAKE_INSTALL_PREFIX=/usr/local/mysql \
   -DDEFAULT_CHARSET=utf8 \
   -DDEFAULT_COLLATION=utf8_general_ci \
   -DENABLED_LOCAL_INFILE=true \
   -DWITH_INNOBASE_STORAGE_ENGINE=1 \
   -DWITH_EXTRA_CHARSETS=all \
   -DWITH_READLINE=ON \
   -DDOWNLOAD_BOOST=1 \
   -DWITH_BOOST=/home/endo/tmp/

$ make
$ make test
# make install

edit /etc/my.conf

ポイントは - skip-grant-tables がないと、id/pw=root/null でログインできません - sql-mode="ONLY_FULL_GROUP_BY" となっていると、selectする全colをgroup by で指定する必要があります

# For advice on how to change settings please see
# http://dev.mysql.com/doc/refman/5.7/en/server-configuration-defaults.html
# *** DO NOT EDIT THIS FILE. It's a template which will be copied to the
# *** default location during install, and will be replaced if you
# *** upgrade to a newer version of MySQL.

[mysqld]

# Remove leading # and set to the amount of RAM for the most important data
# cache in MySQL. Start at 70% of total RAM for dedicated server, else 10%.
# innodb_buffer_pool_size = 128M

# Remove leading # to turn on a very important data integrity option: logging
# changes to the binary log between backups.
# log_bin

# These are commonly set, remove the # and set as required.
# basedir = .....
# datadir = .....
# port = .....
# server_id = .....
# socket = .....
default-storage-engine = INNODB
basedir = /usr/local/mysql
datadir = /home/mysql/data
port            = 3306
socket          = /tmp/mysql.sock

skip-grant-tables
#sql-mode="ONLY_FULL_GROUP_BY"
sql-mode=""

# Remove leading # to set options mainly useful for reporting servers.
# The server defaults are faster for transactions and fast SELECTs.
# Adjust sizes as needed, experiment to find the optimal values.
# join_buffer_size = 128M
# sort_buffer_size = 2M
# read_rnd_buffer_size = 2M 

# sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES 


# max connections
max_connections = 64
# table_open_cache = (max_connections * tables used in one transaction) + alpha
table_open_cache = 800
# table_definition_cache = (all tables in mysql + max_connections) + alpha
table_definition_cache = 400
# open_files_limit = table_open_cache * 1.4
open_files_limit = 1120
 
# global buffer
key_buffer_size = 16M
query_cache_type = 0
# innodb_buffer_pool_size = RAM for Mysql * 0.7
innodb_buffer_pool_size = 256M
 
# thread buffer
read_buffer_size = 256K
read_rnd_buffer_size = 512K
join_buffer_size = 256K
sort_buffer_size = 512K
 
# InnoDB
innodb_file_per_table
innodb_autoextend_increment = 64
innodb_log_files_in_group = 2
innodb_log_file_size = 64M
innodb_log_buffer_size = 16M
innodb_flush_log_at_trx_commit = 1
innodb_flush_neighbors=0
#innodb_flush_method=O_DIRECT
innodb_thread_concurrency = 4
innodb_commit_concurrency = 4
 
# log
general_log = 0
general_log_file = /usr/local/var/mysql/general.log
slow_query_log = 0
 
[mysqldump]
#max_allowed_packet = 16M
quick
set-charset
single-transaction

install apache2.2 + perl5.18 + mod_perl2.0.9

install perl 5.18

$ wget http://www.cpan.org/src/5.0/perl-5.18.4.tar.gz
$ tar -xvf perl-5.18.4.tar.gz
$ cd perl-5.18.4
$ ./Configure -Dusethreads -Accflags="-fPIC" -de
$ make
$ make test
$ su
# make install

※「-Dusethreads -Accflags="-fPIC"」option are needed by mod_perl.

install apache2.2

$ wget http://ftp.riken.jp/net/apache//httpd/httpd-2.2.31.tar.gz
$ tar -xvf httpd-2.2.31.tar.gz
$ cd httpd-2.2.31
$ ./configure --prefix=/home/endo/local/apache22 \
              --with-mpm=prefork \
              --enable-proxy \
              --enable-modules=all \
              --enable-so
$ make
$ make install

install mod_perl

$ wget http://www.apache.org/dyn/closer.cgi/perl/mod_perl-2.0.9.tar.gz
$ tar -xvf mod_perl-2.0.9.tar.gz
$ cd mod_perl-2.0.9
$ /usr/local/bin/perl Makefile.PL \
          USE_APXS=1 \
          WITH_APXS=/home/endo/local/apache22/bin/apxs \
          EVERYTHING=1
$ make
$ make test
$ su
# make install

edit httpd.conf & startup.pl

$ vi /home/endo/local/apache22/conf/httpd.conf
  :
LoadModule perl_module modules/mod_perl.so
PerlRequire /home/endo/local/apache22/conf/startup.pl

PerlSetEnv XING_CONF     /home/endo/dev/xing/etc/config.yaml

<Directory "/home/endo/dev/xing/app">
    AllowOverride All
    Order allow,deny
    Allow from all

    AuthType BASIC
    AuthUserFile /home/endo/dev/htpasswd
    AuthName "COLINUX MEMBERS"
    require valid-user

    <Files "*.pl">
       Options ExecCGI
       AddHandler cgi-script .pl
       SetHandler perl-script
       PerlHandler ModPerl::Registry
       PerlSendHeader On
    </Files>
</Directory>
Alias /Xing /home/endo/dev/xing/app
$ vi /home/endo/local/apache22/conf/startup.pl
  :
#/usr/local/bin/perl

BEGIN {
    use lib qw(.
               /home/endo/dev/xing/lib
             );
}

use NMW::Template;
$NMW::Template::ENCODING = 'utf8';
@NMW::Template::template_path=('/home/endo/dev/xing/tmpl');

use CGI;
$CGI::LIST_CONTEXT_WARN = 0;

#use Devel::Cover;
#$DEVEL_COVER_OPTIONS='-dir,/home/endo/tmp';

1;

nginx + nginx-auth-ldap module

step1/3 - install

$ cd /home/endo/tmp

$ wget http://nginx.org/download/nginx-1.9.3.tar.gz
$ tar -xvf nginx-1.9.3.tar.gz

$ wget https://www.openssl.org/source/openssl-1.0.2d.tar.gz
$ tar -xvf openssl-1.0.2d.tar.gz

$ git clone https://github.com/kvspb/nginx-auth-ldap.git

$ cd nginx-1.9.3
$ ./configure --prefix=/home/endo/local/nginx \
              --with-http_ssl_module \
              --with-openssl=../openssl-1.0.2d \
              --add-module=../nginx-auth-ldap
$ make
$ make install

step2/3 - edit nginx.conf

$ vi /home/endo/local/nginx/conf/nginx_auth_ldap.conf

worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  65;

    ldap_server ldap_sexy {
        url ldap://ldap.sexy.co.jp/ou=people,o=sexy-group?uid?sub?(objectClass=*)
        group_attribute uniqueMember;
        group_attribute_is_dn on;
        require valid_user;
    }

    server {
        listen       8080;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            auth_ldap "AUTH_LDAP";
            auth_ldap_servers ldap_sexy;
            root   html;
            index  index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

step 3/3 - start nginx

$ cd /home/endo/local/nginx
$ ./sbin/nginx -c conf/nginx_auth_ldap.conf