dehio3’s diary

仕事、生活、趣味のメモ

ELB経由のアクセスでapacheのアクセスログの最初に表示されるIPを元のIPに変える

環境

$ sudo /usr/sbin/httpd -V
Server version: Apache/2.4.6 (CentOS)
Server built:   Nov 19 2015 21:43:13
Server's Module Magic Number: 20120211:24
Server loaded:  APR 1.4.8, APR-UTIL 1.5.2
Compiled using: APR 1.4.8, APR-UTIL 1.5.2

やりたいこと

  • apacheアクセスログの先頭のIPからアクセス元IPを判断してる。
  • ELB経由のアクセスにすると先頭のIPがELBのIPになるため判断できなくなるのを解消したい。

対応

  • mod_remoteipモジュールで、リモートIPアドレスをX-Forwarded-Forに書き換える
$ cat /etc/httpd/conf.d/remote_ip.conf
<IfModule remoteip_module>
    RemoteIPHeader X-Forwarded-For
</IfModule>
$ cat /etc/httpd/conf/httpd.conf
#LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%a %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined

先頭を%hから%aに変更する。

ちなみにLogFormatで直接%{X-Forwarded-For}iを指定するやり方もあるけど、アクセス元がX-Forwarded-Forヘッダが付いている状態だとカンマ区切りでアクセス元と、ELB両方のIPが表示されるので注意。

cloudpack.media

EUC環境でpyenvでpythonインストールしたらエラーでた

環境

$ cat /etc/redhat-release
CentOS release 5.11 (Final)
$ pyenv -v
pyenv 1.1.2-2-g5ab088c

事象

-bash-3.2$ pyenv install 3.4.3
Downloading Python-3.4.3.tgz...
-> https://www.python.org/ftp/python/3.4.3/Python-3.4.3.tgz
Installing Python-3.4.3...

BUILD FAILED (CentOS 5.11 using python-build 1.1.2-2-g5ab088c)

Inspect or clean up the working tree at /tmp/python-build.20170713102222.4904
Results logged to /tmp/python-build.20170713102222.4904.log

Last 10 log lines:
        if test $? -ne 0 ; then \
                echo "generate-posix-vars failed" ; \
                rm -f ./pybuilddir.txt ; \
                exit 1 ; \
        fi
Fatal Python error: Py_Initialize: Unable to get the locale encoding
LookupError: unknown encoding: EUC-JP
/bin/sh: line 5: 13142 アボートしました        ./python -E -S -m sysconfig --generate-posix-vars
generate-posix-vars failed
make: *** [pybuilddir.txt] エラー 1
-bash-3.2$

調査

LookupError: unknown encoding: EUC-JP

WindowsでPythonがLookupError: unknown encoding: cp65001 - Qiita

上記が書いてるけど、そもそも PYTHONIOENCODING で何がかわる?

PYTHONIOENCODING

Python 3の各種エンコーディングについて - Qiita

標準入出力のエンコーディングに影響する環境変数らしい。

対処

awscliを使いたいだけだったので、とりあえずpythonのバージョンを下げたらいけた…

-bash-3.2$ pyenv install 2.7.13
Downloading Python-2.7.13.tgz...
-> https://www.python.org/ftp/python/2.7.13/Python-2.7.13.tgz
Installing Python-2.7.13...
Installed Python-2.7.13 to /home/fan/.pyenv/versions/2.7.13

-bash-3.2$

根本解決になってないけど、要件はみたせるからとりあえずこれで進める。

pyenv + virtualenv で 複数パターンのansible環境を作る

要件

  • 社員が共有で使うansible 環境を作る
  • pythonとansibleのバージョンアップに柔軟に対応できる環境を作る

参考

qiita.com

環境

$ cat /etc/redhat-release
CentOS release 6.9 (Final)
$ python --version
Python 2.6.9

pyenv install

# cd /usr/local/src/
# git clone https://github.com/yyuu/pyenv.git pyenv
Initialized empty Git repository in /usr/local/src/pyenv/.git/
remote: Counting objects: 15154, done.
remote: Compressing objects: 100% (7/7), done.
remote: Total 15154 (delta 0), reused 3 (delta 0), pack-reused 15147
Receiving objects: 100% (15154/15154), 2.70 MiB | 1.33 MiB/s, done.
Resolving deltas: 100% (10369/10369), done.

各ユーザーにて利用できるように権限を変更する (変えないと個別で環境作る時に作れない)

# ls -ld /usr/local/src/pyenv/
drwxr-xr-x. 10 root root 4096  7月  7 19:04 2017 /usr/local/src/pyenv/
# chmod 777 /usr/local/src/pyenv
# ls -ld /usr/local/src/pyenv/
drwxrwxrwx. 10 root root 4096  7月  7 19:04 2017 /usr/local/src/pyenv/

pyenv-virtualenv install

# cd /usr/local/src/pyenv/plugins/
# git clone https://github.com/yyuu/pyenv-virtualenv.git
Initialized empty Git repository in /usr/local/src/pyenv/plugins/pyenv-virtualenv/.git/
remote: Counting objects: 1892, done.
remote: Compressing objects: 100% (5/5), done.
remote: Total 1892 (delta 0), reused 1 (delta 0), pack-reused 1887
Receiving objects: 100% (1892/1892), 543.54 KiB | 693 KiB/s, done.
Resolving deltas: 100% (1294/1294), done.

ユーザー初期設定

$ echo 'export PYENV_ROOT=$HOME/.pyenv' >> ~/.bash_profile
$ echo 'export PYENV_ROOT=/usr/local/src/pyenv' >> ~/.bash_profile
$ echo 'export PATH=$PYENV_ROOT/bin:$PATH' >> ~/.bash_profile
$ echo 'eval "$(pyenv init -)"' >> ~/.bash_profile
$ tail -3  ~/.bash_profile
export PYENV_ROOT=/usr/local/src/pyenv
export PATH=$PYENV_ROOT/bin:$PATH
eval "$(pyenv init -)"
$ source ~/.bash_profile
$ which pyenv
/usr/local/pyenv/bin/pyenv

python install

$ pyenv install --list
Available versions:
  2.1.3
  2.2.3
  2.3.7
(省略)

上記でインストールできるバージョンを確認する

$ pyenv install 2.7.5
Downloading Python-2.7.5.tgz...
-> https://www.python.org/ftp/python/2.7.5/Python-2.7.5.tgz
Installing Python-2.7.5...
patching file ./Modules/readline.c
Hunk #1 succeeded at 204 (offset -2 lines).
Hunk #2 succeeded at 747 (offset -2 lines).
Hunk #3 succeeded at 857 (offset -2 lines).
Hunk #4 succeeded at 905 (offset -13 lines).
patching file ./Lib/site.py
patching file ./Lib/ssl.py
Hunk #2 succeeded at 430 (offset -5 lines).
patching file ./Modules/_ssl.c
Hunk #1 succeeded at 65 (offset -2 lines).
Hunk #2 succeeded at 304 (offset -4 lines).
Hunk #3 succeeded at 1729 (offset -83 lines).
Installing pip from https://bootstrap.pypa.io/get-pip.py...
Installed Python-2.7.5 to /usr/local/src/pyenv/versions/2.7.5
$ pyenv versions
* system (set by /usr/local/src/pyenv/version)
  2.7.5

virtualenv 環境作成

$ pyenv virtualenv 2.7.5 py-2.7.5-ansible-2.3.1.0
Collecting virtualenv
/usr/local/src/pyenv/versions/2.7.5/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/util/ssl_.py:318: SNIMissingWarning: An HTTPS request has been made, but the SNI (Subject Name Indication) extension to TLS is not available on this platform. This may cause the server to present an incorrect TLS certificate, which can cause validation failures. You can upgrade to a newer version of Python to solve this. For more information, see https://urllib3.readthedocs.io/en/latest/security.html#snimissingwarning.
  SNIMissingWarning
/usr/local/src/pyenv/versions/2.7.5/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/util/ssl_.py:122: InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. You can upgrade to a newer version of Python to solve this. For more information, see https://urllib3.readthedocs.io/en/latest/security.html#insecureplatformwarning.
  InsecurePlatformWarning
  Downloading virtualenv-15.1.0-py2.py3-none-any.whl (1.8MB)
    100%  | 1.8MB 565kB/s
Installing collected packages: virtualenv
Successfully installed virtualenv-15.1.0
New python executable in /usr/local/src/pyenv/versions/2.7.5/envs/py-2.7.5-ansible-2.3.1.0/bin/python2.7
Also creating executable in /usr/local/src/pyenv/versions/2.7.5/envs/py-2.7.5-ansible-2.3.1.0/bin/python
Installing setuptools, pip, wheel...done.
Installing pip from https://bootstrap.pypa.io/get-pip.py...
Requirement already up-to-date: pip in /usr/local/src/pyenv/versions/2.7.5/envs/py-2.7.5-ansible-2.3.1.0/lib/python2.7/site-packages
$ pyenv versions
* system (set by /usr/local/src/pyenv/version)
  2.7.5
  2.7.5/envs/py-2.7.5-ansible-2.3.1.0
  py-2.7.5-ansible-2.3.1.0

ansible install

ローカル環境を選択

$ pyenv local py-2.7.5-ansible-2.3.1.0
$ pyenv versions
  system
  2.7.5
  2.7.5/envs/py-2.7.5-ansible-2.3.1.0
* py-2.7.5-ansible-2.3.1.0 (set by /home/tom_tanaka/.python-version)
$ pip list
DEPRECATION: The default format will switch to columns in the future. You can use --format=(legacy|columns) (or define a format=(legacy|columns) in your pip.conf under the [list] section) to disable this warning.
pip (9.0.1)
setuptools (36.0.1)
wheel (0.29.0)
$ pip install ansible
$ ansible --version
ansible 2.3.1.0
  config file = /etc/ansible/ansible.cfg
  configured module search path = Default w/o overrides
  python version = 2.7.5 (default, Jul  7 2017, 19:36:14) [GCC 4.4.7 20120313 (Red Hat 4.4.7-18)]

メール送信時の文字コードについて

目的

メール送信処理してるperlスクリプトについて、perlのバージョンアップ&OSの文字コード変更に伴い改修する。

環境

変更前

$ cat /etc/sysconfig/i18n
LANG="ja_JP.eucJP"
SUPPORTED="ja_JP.eucJP:ja_JP:ja"
SYSFONT="latarcyrheb-sun16"
$ perl -version

This is perl, v5.8.5 built for x86_64-linux-thread-multi

Copyright 1987-2004, Larry Wall

Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using `man perl' or `perldoc perl'.  If you have access to the
Internet, point your browser at http://www.perl.com/, the Perl Home Page.

変更後

# cat /etc/sysconfig/i18n
LANG=ja_JP.UTF-8
# perl -version

This is perl 5, version 16, subversion 3 (v5.16.3) built for x86_64-linux-thread-multi
(with 29 registered patches, see perl -V for more detail)

Copyright 1987-2012, Larry Wall

Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl".  If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.

処理

修正が必要な処理だけ抜粋

use Jcode;
require './mimew.pl';


(中略)

### サブジェクトを jis にして、MIME エンコード
$subject = mimeencode(Jcode'jis($subject));

### 本文を jis に
$body = Jcode'jis($body);

### 添付するデータを、base64 でエンコード
$attach = &bodyencode($attach_tmp, "b64");
$attach .= &benflush("b64");

### ファイル名を sjis にして MIME エンコード。(推奨 ascii )
$filename = mimeencode(Jcode'sjis($filename));


### 全体のヘッダ
print MAIL "MIME-Version: 1.0\n";
print MAIL "Content-Type: Multipart/Mixed; boundary=\"$boundary\"\n";
print MAIL "Content-Transfer-Encoding:Base64\n";
print MAIL "From: $from\n";
print MAIL "To: $to\n";
#print MAIL "cc: $cc\n";
print MAIL "Subject: $subject\n";

### メール本文のパート
print MAIL "--$boundary\n";
print MAIL "Content-Type: text/plain; charset=\"ISO-2022-JP\"\n";
print MAIL "\n";
print MAIL "$body\n";

### 添付ファイルのパート
print MAIL "--$boundary\n";
print MAIL "Content-Type: application/octet-stream; name=\"$filename\"\n";
print MAIL "Content-Transfer-Encoding: base64\n";
print MAIL "Content-Disposition: attachment; filename=\"$filename\"\n";
print MAIL "\n";
print MAIL "$attach\n";
print MAIL "\n";

### マルチパートのおわり。
print MAIL "--$boundary" . "--\n";

調査

そもそものメール送信作法

参考 MIME の基礎

MIMEへの変換

 ### サブジェクトを jis にして、MIME エンコード
-$subject = mimeencode(Jcode'jis($subject));
+$subject = encode('MIME-Header', $subject);
 ### ファイル名を sjis にして MIME エンコード。(推奨 ascii )
-$filename = mimeencode(Jcode'sjis($filename));
+$filename = encode('MIME-Header', encode('sjis', $filename));

JISへの変換

 ### 本文を jis に
-$body = Jcode'jis($body);
+$body = encode('jis', $body);

base64への変換

 ### 添付するデータを、base64 でエンコード
-$attach = &bodyencode($attach_tmp, "b64");
-$attach .= &benflush("b64");
+$attach = encode_base64($attach_tmp);

ibwww-perl レスポンス(response)オブジェクトの復帰コードがバージョンによって違った

事象

URLの存在チェックする処理にて、バージョンが変わるとHTTPステータスコード200から403に変わってしまった。

チェックスクリプト

#!/usr/bin/perl

use strict;
use warnings;
use LWP::UserAgent;

my $ua = LWP::UserAgent->new;
$ua->agent('Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1)');
$ua->timeout(5);

my $url = '<チェックしたいURL>';

my $req = HTTP::Request->new(GET => $url);
my $res = $ua->request($req);

#print $res->as_string();

print $res->status_line . "\n";
print $res->code . "\n";

$ perl http_status.pl
200 OK
200

$ perl http_status.pl
403 Forbidden
403

環境

perl

$ perl -version

This is perl, v5.8.5 built for x86_64-linux-thread-multi

Copyright 1987-2004, Larry Wall

Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using `man perl' or `perldoc perl'.  If you have access to the
Internet, point your browser at http://www.perl.com/, the Perl Home Page.
$ rpm -qa | grep libwww-perl
perl-libwww-perl-5.79-5

$ perl -version

This is perl 5, version 16, subversion 3 (v5.16.3) built for x86_64-linux-thread-multi
(with 29 registered patches, see perl -V for more detail)

Copyright 1987-2012, Larry Wall

Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl".  If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.
$ rpm -qa | grep libwww-perl
perl-libwww-perl-6.05-2.17.amzn1.noarch

対処

agentの指定を無効化した

#$ua->agent('Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1)');

agentの指定しない場合のagentは?

libwww-perlのバージョンが設定される

 [06/Jun/2017:14:47:32 +0000] "GET /index.html HTTP/1.1" 200 - "-" "libwww-perl/6.05"
[06/Jun/2017:14:51:13 +0000] "GET /index.html HTTP/1.1" 200 - "-" "libwww-perl/5.805"

実際のブラウザからのアクセスを想定した動作にしたいのでagentは設定する。

無効化するとスパム扱いされる可能性あるから設定したい。

ブラウザからアクセスした場合のヘッダー情報と、スクリプトからのアクセスした場合のヘッダー情報を比較して

色々試した結果以下を追加したら成功した。

$ua->default_header('accept-encoding' => 'gzip,deflate');

あとSSLのサイトで、ブラウザはOKだけどスクリプトNGだった奴は以下を追加して対応

$ua->ssl_opts(verify_hostname => 0);

にひりずむ::しんぷる - LWP での SSL 接続で certificate verify failed しちゃう件の解決方法

詳細はまた後日。。。

公開ファイルが文字化ける

事象

  • ブラウザ上にて公開しているファイルの文字が文字化けして表示される。
  • ファイルのOS上の文字コードShift_JIS

環境

OS

# cat /etc/system-release
Amazon Linux AMI release 2017.03

apache

# /usr/sbin/httpd -V
Server version: Apache/2.2.31 (Unix)
Server built:   Jul 19 2016 00:11:31
Server's Module Magic Number: 20051115:40
Server loaded:  APR 1.5.1, APR-Util 1.4.1
Compiled using: APR 1.5.1, APR-Util 1.4.1

ファイルの文字コード

# nkf -guess hoge.txt
Shift_JIS (LF)

OSの文字コード

# cat /etc/sysconfig/i18n
LANG=ja_JP.UTF-8

Response Header の確認

Accept-Ranges:bytes
Content-Length:169
Content-Type:text/plain; charset=UTF-8
Date:Mon, 05 Jun 2017 02:52:32 GMT
ETag:"138-a9-550f427692dc0"
Last-Modified:Fri, 02 Jun 2017 06:20:47 GMT
Server:Apache/2.2.31 (Amazon)

Content-TypecharsetUTF-8に指定されている。

対処

httpd.conf の AddDefaultCharset を無効化

# grep AddDefaultCharset /etc/httpd/conf/httpd.conf
#AddDefaultCharset UTF-8

変更後のResponse Header

Accept-Ranges:bytes
Connection:close
Content-Length:169
Content-Type:text/plain
Date:Mon, 05 Jun 2017 03:00:02 GMT
ETag:"138-a9-550f427692dc0"
Last-Modified:Fri, 02 Jun 2017 06:20:47 GMT
Server:Apache/2.2.31 (Amazon)

charsetの指定が解除され、ブラウザが自動で判定した文字コードで表示された。

AddDefaultCharset とは?

  • レスポンスのコンテントタイプが text/plain あるいは text/html の場合に追加するデフォルトの charset パラメータ

core - Apache HTTP サーバ バージョン 2.2

ansible dynamic inventory ec2

目的

  • aws上に作成したec2に対して、全台に一括でコマンド操作を行う。
  • 動的インベントリを利用する事で、ec2の情報を常に最新の情報取得する。

Dynamic Inventory — Ansible Documentation

インベントリ用ディレクト作成

mkdir ec2_command ; cd ec2_command
mkdir hosts ; cd hosts

動的インベントリ用ファイル取得

wget https://raw.githubusercontent.com/ansible/ansible/devel/contrib/inventory/ec2.py
wget https://raw.githubusercontent.com/ansible/ansible/devel/contrib/inventory/ec2.ini

ec2.ini 修正

  • 利用しているリージョンに書き換える
regions = all
regions_exclude = ap-northeast-1

ec2リスト取得

$ ./ec2.py --list
ERROR: "Authentication error retrieving ec2 inventory.
 - No AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY environment vars found
 - Boto configs found at '~/.aws/credentials', but the credentials contained may not be correct", while: getting EC2 instances

credentialsファイルは存在し正しく設定してるのにこける。

どうやら時刻のずれが原因のよう。

blog.ozacc.com

確かに時間ずれてる&ntpd動いてない。

$ /etc/init.d/ntpd status
ntpd は停止しています
$ chkconfig | grep ntp
ntpd            0:off   1:off   2:off   3:off   4:off   5:off   6:off
ntpdate         0:off   1:off   2:off   3:off   4:off   5:off   6:off

時刻を合わせる

$ sudo /etc/init.d/ntpd start
ntpd を起動中:                                             [  OK  ]

再度実行

$ ./ec2.py --list