tohokuaikiのチラシの裏

技術的ネタとか。

PHPでアクセスしてきたIPアドレスがプライベートアドレスかをチェックする

プライベートIPは以下の範囲で

10.0.0.0~10.255.255.255
172.16.0.0~172.31.255.255
192.168.0.0~192.168.255.255

PHPip2longをかませると

167772160~184549375
2886729728~2887778303
3232235520~3232301055

なので、こんな感じで。

<?php
function isPrivateAddress($ip = null)
{
    is_null($ip) and $ip = $_SERVER['REMOTE_ADDR'];
    
    $iplong = ip2long($ip);
    $iplong = sprintf('%u', $iplong); // for 32bit architecture
    
    return ($iplong >= 167772160 && $iplong <=184549375) ||
           ($iplong >= 2886729728 && $iplong <=2887778303) ||
           ($iplong >= 3232235520 && $iplong <=3232301055) ;
}

テスト

<?php
$testips=<<<EOF
10.0.0.0
10.0.0.1
10.0.1.1
10.255.255.254
10.255.255.255
11.0.0.1
172.15.234.1
172.16.0.0
172.16.0.1
172.31.255.254
172.31.255.255
172.32.0.1
191.255.255.255
192.168.0.0
192.168.0.1
192.168.255.254
192.168.255.255
193.0.0.1
EOF;

foreach (explode("\n", $testips) as $ip){
    $ip = trim($ip);
    $long = ip2long($ip);
    printf("%s\t(%u)\t=>\t%s\n",
           $ip, $long,
           isPrivateAddress($ip) ? 'private' : 'global');
}

10.0.0.0        (167772160)     =>      private
10.0.0.1        (167772161)     =>      private
10.0.1.1        (167772417)     =>      private
10.255.255.254  (184549374)     =>      private
10.255.255.255  (184549375)     =>      private
11.0.0.1        (184549377)     =>      global
172.15.234.1    (2886724097)    =>      global
172.16.0.0      (2886729728)    =>      private
172.16.0.1      (2886729729)    =>      private
172.31.255.254  (2887778302)    =>      private
172.31.255.255  (2887778303)    =>      private
172.32.0.1      (2887778305)    =>      global
191.255.255.255 (3221225471)    =>      global
192.168.0.0     (3232235520)    =>      private
192.168.0.1     (3232235521)    =>      private
192.168.255.254 (3232301054)    =>      private
192.168.255.255 (3232301055)    =>      private
193.0.0.1       (3238002689)    =>      global

VirtualBoxに共有フォルダを作成する方法のメモ

普通だったらこんな事せずに、Sambaで終わらせるんだけどこのパソコンは後で別の所に持っていくのでIPアドレスとかなんだりかんだりが変わる可能性があるのでVirtualBoxの共有フォルダ機能を使用した。

ホストOSはWindows10Home、ゲストOSはDebian8(jessie)

仮想マシンにGuest Additionsをインストール

この記事を参考にした。 qiita.com

マシンに仮想ディスクを挿入

自分の場合、起動させたゲストOSのコンソールからデバイス光学ドライブ>ディスクイメージを選択で、C:\Program Files\Oracle\VirtualBox\VBoxGuestAdditions.iso を選択した。

f:id:tohokuaiki:20181112122236p:plain

ゲストOSでインストールスクリプトを実行

…の前にこのインストールスクリプトはmake, gcc, kernel-packageが必要なので

apt-get install -y gcc make kernel-package

をしてから

mkdir -p /mnt/cdrom
mount -r /dev/cdrom /mnt/cdrom
sh /mnt/cdrom/VBoxLinuxAdditions.run

としても、なんかエラーで引っかかる…

# sh /mnt/cdrom/VBoxLinuxAdditions.run
Verifying archive integrity... All good.
Uncompressing VirtualBox 5.2.20 Guest Additions for Linux........
VirtualBox Guest Additions installer
Removing installed version 5.2.20 of VirtualBox Guest Additions...
Copying additional installer modules ...
Installing additional modules ...
VirtualBox Guest Additions: Building the VirtualBox Guest Additions kernel modules.  This may take a while.

This system is currently not set up to build kernel modules.
Please install the Linux kernel "header" files matching the current kernel
for adding new hardware support to the system.
The distribution packages containing the headers are probably:
    linux-headers-686-pae linux-headers-3.16.0-6-686-pae
update-initramfs: Generating /boot/initrd.img-3.16.0-6-686-pae
VirtualBox Guest Additions: Starting.
VirtualBox Guest Additions: Building the VirtualBox Guest Additions kernel modules.  This may take a while.

This system is currently not set up to build kernel modules.
Please install the Linux kernel "header" files matching the current kernel
for adding new hardware support to the system.
The distribution packages containing the headers are probably:
    linux-headers-686-pae linux-headers-3.16.0-6-686-pae
update-initramfs: Generating /boot/initrd.img-3.16.0-6-686-pae

linux-headersが必要な様子。apt-cache search linux-headersをするとlinux-headers-686-paeとlinux-headers-3.16.0-6-686-paeってのがあったので、これを入れておけばいいのかな?

apt-get install -y linux-headers-686-pae linux-headers-3.16.0-6-686-pae

としてから sh /mnt/cdrom/VBoxLinuxAdditions.run をするとどうやらうまく進行してくれた。

共有フォルダをVirtualBoxで作成

ゲストOSをシャットダウンしてからVirtualBoxで共有フォルダを設定

f:id:tohokuaiki:20181112122829p:plain

ゲスト側での共有設定

mount -t vboxsf share_folder_name /home/user/sample

で、毎回起動時にマウントするように /etc/rc.local に記載しておく。

これをやらなくても、VirtualBoxで設定しただけで自動的にマウントするようになった。

→ 以下の問題を解決するためにはVirtualBoxから自動起動ではなく、ゲストOSからの自動起動が必要になってしまう。

が、作成されるファイル・フォルダに問題が…

ホストからでもゲストからでもファイル・フォルダを作成すると、オーナーがrootでグループがvboxsfになり、パーミッションが770になってしまう。 あまりうれしくない。

gpasswd -a XXXXXX vboxsf

してやると、ゲストOS側で使用するユーザーXXXXXXもこの共有ファイルを触れるけど、ん~~~。イマイチ。だいたいApacheでこのファイルを覗けないというのはどうなんだろうという気もするし、いや、apacheユーザーをvboxsfに入れればいいじゃんって思うけど、さすがにapacheの作成するファイルがrootオーナーってどうなんだろうという。

しかも、フォルダの位置がゲストOSから見ると、/media/sf_{VirtualBoxで設定した共有フォルダ名} となる。うーん、sambaみたいにできないものだろうか…

ということで、この記事を見ながら編集。 giraffydev.hatenablog.com

-oオプションで、マウントするオーナーとグループの設定

自分のuid,gidを知る。

id xXXXXX
uid=1000(XXXXXX) gid=1000(XXXXXX)

とあるので、両方とも1000なので、

-o uid=1000,gid=1000 

とする。

-oオプションで、マウントする時のファイルとディレクトリのデフォルトモードを設定

-o fmode=0664,dmode=0755

で結局のマウントコマンドは

mount -t vboxsf share_folder_name /home/user/sample -o uid=1000,gid=1000,fmode=0664,dmode=0755

となる。

地味にアンマウントができなくて汗る。

-t オプションと -i オプションが必要らしい。 qiita.com

sudo umount -t vboxsf -i /home/user/sample

とする。

自動設定

VirtualBoxで設定した自動起動だとこういうところは上手くやってくれない。

/etc/rc.localにさっきのマウントコマンドを記載してもいいけど、なんとなく/etc/fstabに記載したくなった。

デバイス名(share_folder_name)        マウントポイント(/home/users/sample)       vboxsf  uid=1000,gid=1000,fmode=0664,dmode=0755    0    0

/etc/modulesにvboxsfを食わないと起動時にミスするっていう記載があったけど、なんか問題なくいった。新しいOSで対応されたのかもしれない。 VirtualBoxの共有フォルダの自動マウント化 - どうでもいい日記帳

PHPのoutput bufferingの罠

別のサーバーだとheaderの前にエラーが出て「Message: Cannot modify header information - headers already sent by」になって終わっちゃうのに、自分のサーバーだとこれが引っかからなくて不思議だなーって思ってたら

f:id:tohokuaiki:20181107164605p:plain
output.bufferingの値が設定されていた。なんぞこれ。

PHP: 実行時設定 - Manual

output_buffering boolean/integer このディレクティブを 'On' と設定することにより、全てのファイルに 関して出力バッファリングを有効にすることができます。 特定の大きさにバッファの大きさを制限したい場合、このディレクティブの 値として 'On' の代わりに最大バイト数(例:output_buffering=4096) を使用することができます。 PHP-CLI ではこのディレクティブが常に Off となります。

ということ。試しに、var_dump(ob_get_status());exit; してみたら

array(7) {
  ["name"]=>
  string(22) "default output handler"
  ["type"]=>
  int(0)
  ["flags"]=>
  int(20592)
  ["level"]=>
  int(0)
  ["chunk_size"]=>
  int(4096)
  ["buffer_size"]=>
  int(69632)
  ["buffer_used"]=>
  int(0)
}

って出てきた。なー。デフォルトでob_start()してたってことなのね。

.htaccess

php_value output_buffering 0

として対策完了。

10年くらいぶりにPerlのCPANモジュールをインストールしようとしたら全然覚えてなくて焦った。

MT6を使おうとして

Perlすっかり忘れてる。mt-check.cgiにアクセスしたらいっぱいオプションで必要なのが出てきた。

CPANをインストール

# yum install perl-CPAN

CPANプロンプトを起動する

# perl -MCPAN -e shell

最初はなんか言われるけど、のきなみエンターキーをたたく。

CPANモジュールのインストール

cpan[1]> install Net::SSLeay

スペース区切りで複数を一度にインストールいけるかと思いきやダメだった。

複数行くときは、

# perl -MCPAN -e 'CPAN::Shell->install("XML::LibXML::SAX")'
# perl -MCPAN -e 'CPAN::Shell->install("Authen::SASL")'

みたいにやる。

モジュールのインストールの有無を確認

一覧で出てきてほしいなーと思いつつ、インストール済みのCPANモジュールを調べる | bacchi.me そういうのは無いみたいなので。

# perl -Mモジュール名 -e \'\'

で何も出てこなければインストールされている。エラーメッセージがでたらインストールされてない。という方法。

Archive::Zipとかインストールでコケル。メンテナンスされてないんだろうか。

とりあえず、MT6で出てきたのを

perl -MCPAN -e 'CPAN::Shell->install("CGI::Cookie")'
perl -MCPAN -e 'CPAN::Shell->install("Scalar::Util")'
perl -MCPAN -e 'CPAN::Shell->install("LWP::UserAgent")'
perl -MCPAN -e 'CPAN::Shell->install("File::Spec")'
perl -MCPAN -e 'CPAN::Shell->install("Image::Size")'
perl -MCPAN -e 'CPAN::Shell->install("CGI")'
perl -MCPAN -e 'CPAN::Shell->install("DBI")'
perl -MCPAN -e 'CPAN::Shell->install("DBD::mysql")'
perl -MCPAN -e 'CPAN::Shell->install("DBD::SQLite")'
perl -MCPAN -e 'CPAN::Shell->install("DBD::Pg")'
perl -MCPAN -e 'CPAN::Shell->install("DBD::SQLite2")'
perl -MCPAN -e 'CPAN::Shell->install("Net::SSLeay")'
perl -MCPAN -e 'CPAN::Shell->install("IPC::Run")'
perl -MCPAN -e 'CPAN::Shell->install("Archive::Zip")'
perl -MCPAN -e 'CPAN::Shell->install("Net::SMTP::TLS")'
perl -MCPAN -e 'CPAN::Shell->install("XML::LibXML::SAX")'
perl -MCPAN -e 'CPAN::Shell->install("Authen::SASL")'
perl -MCPAN -e 'CPAN::Shell->install("Storable")'
perl -MCPAN -e 'CPAN::Shell->install("List::Util")'
perl -MCPAN -e 'CPAN::Shell->install("CGI::PSGI")'
perl -MCPAN -e 'CPAN::Shell->install("Cache::Memcached")'
perl -MCPAN -e 'CPAN::Shell->install("Digest::SHA")'
perl -MCPAN -e 'CPAN::Shell->install("Cache::File")'
perl -MCPAN -e 'CPAN::Shell->install("Crypt::SSLeay")'
perl -MCPAN -e 'CPAN::Shell->install("GD")'
perl -MCPAN -e 'CPAN::Shell->install("Archive::Tar")'
perl -MCPAN -e 'CPAN::Shell->install("Safe")'
perl -MCPAN -e 'CPAN::Shell->install("XML::SAX::Expat")'
perl -MCPAN -e 'CPAN::Shell->install("CGI::Parse::PSGI")'
perl -MCPAN -e 'CPAN::Shell->install("Image::Magick")'
perl -MCPAN -e 'CPAN::Shell->install("File::Temp")'
perl -MCPAN -e 'CPAN::Shell->install("HTML::Parser")'
perl -MCPAN -e 'CPAN::Shell->install("Crypt::DSA")'
perl -MCPAN -e 'CPAN::Shell->install("XML::SAX")'
perl -MCPAN -e 'CPAN::Shell->install("SOAP::Lite")'
perl -MCPAN -e 'CPAN::Shell->install("Text::Balanced")'
perl -MCPAN -e 'CPAN::Shell->install("Digest::MD5")'
perl -MCPAN -e 'CPAN::Shell->install("HTML::Entities")'
perl -MCPAN -e 'CPAN::Shell->install("XML::Parser")'
perl -MCPAN -e 'CPAN::Shell->install("IO::Socket::SSL")'
perl -MCPAN -e 'CPAN::Shell->install("IO::Uncompress::Gunzip")'
perl -MCPAN -e 'CPAN::Shell->install("Digest::SHA1")'
perl -MCPAN -e 'CPAN::Shell->install("Plack")'
perl -MCPAN -e 'CPAN::Shell->install("IO::Compress::Gzip")'
perl -MCPAN -e 'CPAN::Shell->install("Imager")'
perl -MCPAN -e 'CPAN::Shell->install("XML::Atom")'
perl -MCPAN -e 'CPAN::Shell->install("Time::HiRes")'
perl -MCPAN -e 'CPAN::Shell->install("YAML::Syck")'
perl -MCPAN -e 'CPAN::Shell->install("Net::SMTP")'
perl -MCPAN -e 'CPAN::Shell->install("Mozilla::CA")'
perl -MCPAN -e 'CPAN::Shell->install("MIME::Base64")'
perl -MCPAN -e 'CPAN::Shell->install("XMLRPC::Transport::HTTP::Plack")'
perl -MCPAN -e 'CPAN::Shell->install("Net::SMTP::SSL")'
perl -MCPAN -e 'CPAN::Shell->install("XML::SAX::ExpatXS")'

この中でいくつかインストール失敗するのがあって、もうオプショナルだしあきらめようかなと思ったんだけど、以下にあるのは普通にyumで転がってたので

# yum install -y perl-Archive-Zip perl-XML-SAX perl-Crypt-SSLeay perl-GD perl-XML-Parser 

で行けた。いくつかモジュールがO.Kになってた。うーん歴史を感じる。

VagrantとChefで開発環境を作る

もらったアプリケーションが、VagrantとChefを使ってるぽかったのでWindows10でChefからVagrantを通して開発環境を作ってみるメモ。

とりあえず参考資料 Vagrant と Chef による仮想環境構築の自動化(VirtualBox編) | オブジェクトの広場

Vagrantはインストールして使ってるので、Chefのインストールから。

Chefのインストールとセットアップ

https://downloads.chef.io/chef-dk/ から最新版のChef Development Kitをダウンロードしてインストール。

セットアップ

さきほどのブログ記事には

Chef-DK にバンドルされた Ruby の利用が推奨されています。以下のコマンドで Chef-DK の Ruby を使うように指定して下さい。
% eval "$(chef shell-init SHELL_NAME)"
(注意)SHELL_NAME の箇所は自分が使っているシェル名に置き換えてください。

ってあるけど、よくわからない。こういう時は本家ドキュメントを読む。インストール手順からのhttps://docs.chef.io/dk_windows.html:title=Windowsでのセットアップ]

WindowsのスタートメニューからインストールされたChef DKを起動。PowerShellの管理者モードで起動する。
f:id:tohokuaiki:20180919142715p:plain

Chef実行時の環境設定を行う。rubyコマンドで C:/opscode/chefdk/embedded/bin にあるruby.exeが使われるようになる。

現在のセッションだけなら

chef shell-init powershell | Invoke-Expression

を実行。
パーマネントに設定したい場合は、下記のようにする。

"chef shell-init powershell | Invoke-Expression" >> $PROFILE

この時、$PROFILEファイルは、

PS C:\WINDOWS\system32> $PROFILE
C:\Users\t-ito\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1

なのだけど、これが無い場合は

if(Test-Path $PROFILE){ chef shell-init powershell | Add-Content $PROFILE } else { New-Item -Force -ItemType File $PROFILE; chef shell-init powershell | Add-Content $PROFILE }

とする。

PowerShellスクリプト実行は、セキュリティ上実行されない場合があるので 

Set-ExecutionPolicy RemoteSigned

で「Y」を選択実行しておく。

chefコマンド-vでチェックしておく。cygwinだとうまくいかなかった。

Vagrant のインストール

本体はインストール済みなので、プラグインを。

$ vagrant plugin install vagrant-vbguest
$ vagrant plugin install vagrant-chef-zero
$ vagrant plugin install vagrant-omnibus

と3つインストールする。最初のvagrant-vbguestはおそらく既にインストール済みである。

次のvagrant-chef-zeroをインストールする所で引っかかる。

2> vagrant plugin install vagrant-chef-zero
Installing the 'vagrant-chef-zero' plugin. This can take a few minutes...
Building native extensions.  This could take a while...
Bundler, the underlying system Vagrant uses to install plugins,
reported an error. The error is shown below. These errors are usually
caused by misconfigured plugin installations or transient network
issues. The error from Bundler is:

ERROR: Failed to build gem native extension.

    current directory: C:/Users/t-ito/.vagrant.d/gems/2.4.4/gems/ffi-yajl-1.4.0/ext/ffi_yajl/ext/encoder
C:/HashiCorp/Vagrant/embedded/mingw64/bin/ruby.exe -r ./siteconf20180919-1164-1h53pll.rb extconf.rb
 -IC:/Users/t-ito/.vagrant.d/gems/2.4.4/gems/libyajl2-1.2.0/lib/libyajl2/vendored-libyajl2/include -march=x86-64 -mtune=generic -O2 -pipe
 -LC:/Users/t-ito/.vagrant.d/gems/2.4.4/gems/libyajl2-1.2.0/lib/libyajl2/vendored-libyajl2/lib -L. -pipe
creating Makefile

current directory: C:/Users/t-ito/.vagrant.d/gems/2.4.4/gems/ffi-yajl-1.4.0/ext/ffi_yajl/ext/encoder
make "DESTDIR=" clean

current directory: C:/Users/t-ito/.vagrant.d/gems/2.4.4/gems/ffi-yajl-1.4.0/ext/ffi_yajl/ext/encoder
make "DESTDIR="
generating encoder-x64-mingw32.def
compiling encoder.c
encoder.c: In function 'Init_encoder':
encoder.c:382:20: error: 'rb_cFixnum' undeclared (first use in this function); did you mean 'rb_isalnum'?
   rb_define_method(rb_cFixnum, "ffi_yajl", rb_cFixnum_ffi_yajl, 2);
                    ^~~~~~~~~~
                    rb_isalnum
encoder.c:382:20: note: each undeclared identifier is reported only once for each function it appears in
encoder.c:383:20: error: 'rb_cBignum' undeclared (first use in this function); did you mean 'rb_cFixnum'?
   rb_define_method(rb_cBignum, "ffi_yajl", rb_cBignum_ffi_yajl, 2);
                    ^~~~~~~~~~
                    rb_cFixnum
make: *** [Makefile:242: encoder.o] Error 1

make failed, exit code 2

Gem files will remain installed in C:/Users/t-ito/.vagrant.d/gems/2.4.4/gems/ffi-yajl-1.4.0 for inspection.
Results logged to C:/Users/t-ito/.vagrant.d/gems/2.4.4/extensions/x64-mingw32/2.4.0/ffi-yajl-1.4.0/gem_make.out

よくわからない…無視して進める。

貰ったVagrantfileにberkshelfが使ってあるっぽいんでインストール、

>vagrant plugin install vagrant-berkshelf
Installing the 'vagrant-berkshelf' plugin. This can take a few minutes...
Fetching: vagrant-berkshelf-5.1.2.gem (100%)
The Vagrant Berkshelf plugin requires Berkshelf from the Chef Development Kit.
You can download the latest version of the Chef Development Kit from:

    https://downloads.chef.io/chefdk

Installing Berkshelf via other methods is not officially supported.
Successfully uninstalled hashie-2.1.2
Successfully uninstalled libyajl2-1.2.0
Successfully uninstalled mixlib-log-1.7.1
Installed the plugin 'vagrant-berkshelf (5.1.2)'!
Post install message from the 'vagrant-berkshelf' plugin:

The Vagrant Berkshelf plugin requires Berkshelf from the Chef Development Kit.
You can download the latest version of the Chef Development Kit from:

    https://downloads.chef.io/chefdk

Installing Berkshelf via other methods is not officially supported.

そして、vagrant upすると

vm:
* The host path of the shared folder is missing: ../projects

と出る。

Vagrantfileがある階層の1個上にprojectsというフォルダを作成し、再度vagrant upするとなにやら進みだした。Windowsから管理者権限チェックが入るがとりあえず「はい」を選択して進める。Windows Defenderからもなんか聞かれるが通す。

なんか、vagrant upすると同時にyumで色々とインストールが始まった。たぶん、chef-zeroはいらなかったっぽい。

で、進んでくと、

    default: SSH auth method: private key
==> default: Mounting shared folders...
    default: /vagrant => C:/Users/t-ito/VagrantBox/xxxxxxx/projects
Vagrant was unable to mount VirtualBox shared folders. This is usually
because the filesystem "vboxsf" is not available. This filesystem is
made available via the VirtualBox Guest Additions and kernel module.
Please verify that these guest additions are properly installed in the
guest. This is not a bug in Vagrant and is usually caused by a faulty
Vagrant box. For context, the command attempted was:

mount -t vboxsf -o dmode=777,fmode=666,uid=500,gid=500 vagrant /vagrant

The error output from the command was:

/sbin/mount.vboxsf: mounting failed with the error: No such device

となった。mountで引っかかったのだけど、とりあえずVMは起動しててvagrant sshで接続は可能。

Vagrantfileのマウントの設定がMacOSのパス設定だったのでWindowsのものに変更。

  config.vm.synced_folder "C:\\hogehoge\\projects", project_path

という感じで書き換えた。(バックスラッシュ二重)

ネットワークアダプタの日本語が邪魔してる?

しかし、どうもローカルからVagrantへのマウントができない。

Vagrant was unable to mount VirtualBox shared folders. This is usually because the filesystem "vboxsf" is not available.

とか

C:/HashiCorp/Vagrant/embedded/gems/2.1.5/gems/vagrant-2.1.5/lib/vagrant/util/io.rb:32:in `encode': "\x80" on Windows-31J (Encoding::InvalidByteSequenceError)

とか言われる。日本語なんて使ってないのに…。

全うに取り組むのをあきらめて、VagrantコマンドでEncoding::InvalidByteSequenceErrorであったように直接 C:/HashiCorp/Vagrant/embedded/gems/2.1.5/gems/vagrant-2.1.5/lib/vagrant/util/io.rb を書き換えてやった。そしたら、マウントしてshefが動くところまで行った。

しかし、

$ vagrant vbguest

でヴァージョン合わすといいよとあったのでやってみるとむしろ悪化。再びマウントができなくなってしまい…。

NoMethodError: undefined method `tz=' for #<Chef

Chef v13でtimezone-iiを使う(なるべく使わない方が良い)