2018/11/16

postfix メールキューのエラー 大量のメールを誤送信してしまい、遅延がひどい場合の措置

サーバ内のメール転送プログラム実行中にエラーが生じた際に、
エラー警告メールを送信し、エスケープする処理を盛り込んだのだが、
エスケープの記述をしくじり、エンドレス送信が生じてしまった。

2時間程経過した際に以上に気づき、即座にプログラムは停止させ、/var/spool/mail/配下の指定アドレスの中身は処理したのだが、
postfixのキューに大量の残骸が残ってしまった。
遅延の遅延の遅延を繰り返し、頑張って送ってきてはいるが、
1万数千単位のメールが何時までも送られてくるため、当該ユーザの
通常のメールにも遅延が生じてしまっている状態。

そこで、postfixのキューを何とかして、通常の状態に戻してみた。

幸い、該当のメールのサイズが2kBと非常に小さいもので、他の遅延が殆どなかったので、
さらっと内容を確認して、該当のメールだけを削除する。

qmgr キューマネージャーにてメッセージはキューを通過する。

格納されている先

/var/spool/postfix/incoming リモート受信した最新のメッセージ格納
/var/spool/postfix/active 処理中メッセージ
/var/spool/postfix/bounce  配信できなかったメールID毎のログ 
/var/spool/postfix/corrupt  postfixの形式に則ってないメッセージ格納 
/var/spool/postfix/deferred 配信不能だがリトライする。
/var/spool/postfix/hold     無期限保存する際利用
/var/spool/postfix/defer 一時的に配送不能なメッセージリトライする。


既に、 /var/spool/mail/配下の指定アドレスの中身は処理済みの場合、
問題は、
deferredとdeferに残骸が有ると、何度もリトライを繰り返してしまう点にある。
 
そこで、 defer配下をfindしてファイルサイズ2kのものをxargsで渡して削除 
# find /var/spool/postfix/defer/ -size 2k | xargs rm -rf
 
マジで全部消えるので、ほんとにそのサイズで大丈夫か?を確認すること 
※ -execだとファイルの数だけコマンドを投げる仕様のようで、時間がかかってしまう。
  今回1万数千回の実行は xargs の方が向いている。
 
同様に、deferredでも行う。
# find /var/spool/postfix/deferred/ -size 2k | xargs rm -rf
 
その後、 残った問題の無いものを強制送信。
# postfix flush
 
最後にキューをきれいにする
# postsuper -d ALL 

キューがきれいになったか確認
# postqueue -p
Mail queue is empty

これで、正常な状態に戻っている(はず)
小生の環境では、これで正常に配信されるようになった。

この方の解説が非常にわかりやすかった。ありがとうございます。
kazupon.com様

2018/11/06

SUBARU XV DBA-GT7 CADデータ

現行のSUBARU(スバル)XVのCADデータが見つからず・・・。
平面図が欲しかったが、SUBARUさんも3面図のみの掲載・・・。
平面図を作成するために、結局全部書いてしまった・・・。

誰トク?なCADデータだが、約2,500台/月の販売実績だし、
ちょっとリコール出てるけど、車に問題はないし、
オーナー様にご利用頂ければと思い、公開。


FC2に「SUBARU_XV_DBA_GT7.zip」でアップロードしてます。(JW_CAD)

SUBARU(スバル)XV 2017年5月~ DBA-GT7型 2.0i-Sアイサイト


PHP 日本語メールの環境依存文字 文字化け対策

先般、SPF問題の解決の為、PHPMAILERにてメール送信を行うように仕様変更したが、
まだ、JIS-2022-JPの7bit問題が解決していない。

問題点としては、さまざまな環境のメールサーバやOSがアンドロイドでないフィーチャーフォン
(所謂ガラケー)では、8bitを許容していないようだが、ほとんどの動作環境下でUTF-8が
利用できるようになってきている。
と思われる。

そこで、今までは、JIS-2022-JP(7bit)の制約を受け、環境依存文字や半角カナ
が文字化けを起こす環境で運用を行っていたが、さすがに、ガラケーのみで
運用をするユーザが現役社会人である可能性は、万が一くらいでいいだろうと判断した。

前段が長くなってしまったが、
UTF-8でPHPMAILERのインスタンスを生成する際の記載をオボエガキ
前回との変更箇所をオレンジ表記



smtp送信テストPHP(UTF-8送信)
<?
require_once("/置いた所/vendor/autoload.php" ); //これを忘れると動かない!!
require_once("/置いた所/vendor/phpmailer/phpmailer/class.phpmailer.php"); //これを忘れると動かない!!
mb_language("japanese"); 
mb_internal_encoding("UTF-8");   
 
$to = "XXXX@gmail.com";
$subject = "SMTP587テスト";
$body = "smtpサーバ経由のメールテスト";
$from = "hoge@hogehoge.com";
$fromname = "送信テスト君";

$mail = new PHPMailer();//インスタンス生成
$mail->CharSet = "UTF-8";//UTF-8の宣言をすること
$mail->Encoding = "base64";//記述しないと正しく認識しないサーバが存在するらしい。

$mail->IsSMTP(); //smtp利用宣言
$mail->SMTPAuth = TRUE;//smtp認証宣言
$mail->Host = 'mail.xxxx.jp:587';    // ホストアドレス:ポート25or587
$mail->Username = 'hoge'; //smtp認証ユーザ
$mail->Password = 'hogehoge';  //smtp認証パス

$mail->AddAddress($to);
$mail->From = $from;
$mail->FromName = $fromname;
$mail->Subject = $subject;
$mail->Body  = $body;
$mail->AddAttachment('./hogefile.pdf');日本語は極力使わない!!
 
 //メールを送信
if (!$mail->Send()){
    echo("Failed to send mail. Error:".$mail->ErrorInfo);
}else{
    echo("Send mail OK.");
}
?>

大分後になって
$mail->CharSet = "UTF-8";
$mail->Encoding = "base64";
と宣言をするよりも、
$mail->CharSet = "iso-2022-jp";
$mail->Encoding = "7bit";
として、愚直に
mb_encode_mimeheader(mb_convert_encoding($fromname,"JIS","UTF-8"))
としたほうが、エンコード率が高いことが分かった。

2018/10/24

composerで配置したPHPMailerの アクセス権限について

昨日、home直下のユーザディレクトリで作業を行ない、
/home/user/vendorという状況でテストを行ったが

例えば、/ver/www/htmlの配下から
/home/user/vendorにリクエストをする際に、パーミッションエラーが起こり
phpのプログラムが止まってしまった。

autoload.phpが正しくrequireされているかを確認するのが、厄介だった。
また、home以下のディレクトリのパーミッションを流石にすべて777にしたくないので、
/ver/www/html側に
composerから再度PHPMailerを配置し、お茶を濁した。

2018/10/23

メールの到達率を高める。 SPF逆引き対策

受付完了のメールなどを、社内のサーバから送信しているのだが、
セキュアな対策を行っているメールサーバを利用している方に、メールが届かない
というケースが生じてきた。

SPF(Sender Policy Framework) という技術だそうで、
FORMのIPアドレスがDNSの逆引きで実在するかをチェックするという動きのようだ。

わざわざレンタルサーバ上でメールを作成して送信も手間なので、
今までは、特段気にしていなかったが、基幹システム化しつつあるため、そうも言ってられなくなった。
要は、実在するSMTPサーバを経由してメールを送ればいいので、少し調べた所
いくつか方法があった。

1.postfixのmain.cf にリレーさせる
2.Qdsmtpというhal456さんが作成したライブラリを利用させて頂き、smtpサーバ経由にする。
3.PHPMailerという老舗のライブラリを利用させて頂きsmtpサーバを経由にする。


1.は設定変更等が生じた際に面倒な気がしてならないので、保留。
2.は魅力的だが、php7.0以降でサポートしていないようなので、後ろ髪惹かれつ第2候補に
というわけで、PHPMailerをインストールしてみる。

依存関係を考慮しつつライブラリを使えるようにしてくれる
composerという PHPのパッケージ管理システムを使って
PHPMailerを導入してみる。


# mkdir comp 適当な作業ディレクトリを作成。
# cd comp

# php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
# php composer-setup.php
 All settings correct for using Composer
 Downloading...

 Composer (version 1.7.2) successfully installed to: /root/composer.phar
 Use it: php composer.phar
# rm -f composer-setup.php もう要らないので、消す
# mv composer.phar /usr/local/bin/composer システム全般で使えるように移動
セキュリティホールになるからルートで使うなと言われるらしいので、 一般ユーザで確認
$ composer
でロゴとか出れば、OK
 
続けて、ライブラリ phpmailerを入れる。
 
任意のユーザの任意のディレクトリで行うこと
 
$ composer require phpmailer/phpmailer
Using version ^5.2 for phpmailer/phpmailer
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
  - Installing phpmailer/phpmailer (v5.2.26): Downloading (100%)
phpmailer/phpmailer suggests installing league/oauth2-google (Needed for Google XOAUTH2 authentication)
Writing lock file
Generating autoload files
  
何処に置いたか忘れたら、これで探すようかな? 
$ find -name vendor -type d
 
 
 


smtp送信テストPHP


<?

require_once("/置いた所/vendor/autoload.php" ); //これを忘れると動かない!!
require_once("/置いた所/vendor/phpmailer/phpmailer/class.phpmailer.php"); //これを忘れると動かない!!
mb_language("japanese"); 
mb_internal_encoding("UTF-8");   
 
$to = "XXXX@gmail.com";
$subject = "SMTP587テスト";
$body = "smtpサーバ経由のメールテスト";
$from = "hoge@hogehoge.com";
$fromname = "送信テスト君";

$mail = new PHPMailer();//インスタンス生成
$mail->CharSet = "iso-2022-jp";
$mail->Encoding = "7bit";

$mail->IsSMTP(); //smtp利用宣言
$mail->SMTPAuth = TRUE;//smtp認証宣言
$mail->Host = 'mail.xxxx.jp:587';    // ホストアドレス:ポート25or587
$mail->Username = 'hoge'; //smtp認証ユーザ
$mail->Password = 'hogehoge';  //smtp認証パス

$mail->AddAddress($to);
$mail->From = $from;
$mail->FromName = mb_encode_mimeheader(mb_convert_encoding($fromname,"JIS","UTF-8"));
$mail->Subject = mb_encode_mimeheader(mb_convert_encoding($subject,"JIS","UTF-8"));
$mail->Body  = mb_convert_encoding($body,"JIS","UTF-8");

//メールを送信
if (!$mail->Send()){
    echo("Failed to send mail. Error:".$mail->ErrorInfo);
}else{
    echo("Send mail OK.");
}
?>
 
テスト送信が届いたら、
念のため、SMTPサーバの/var/log/maillog も確認し、上手くいってるようだ。
稼働中のプログラムの置き換えをして完了。
 
明日できれば置き換えよう 
うん、がんばろう・・・。
 
 

2018/10/10

tesseractの数字と一部の記号のみ識字させる方法

https://code-examples.net/ja/q/4b73be
此処に記載があった。

outputbase digits のオプションでは、何故か上手く行かなかったので、
少し調べてみたところ
標準出力にオプションでキャラクタの設定が出来るとあった。
stdout -c tessedit_char_whitelist=指定したい内容
これは上手くいったので、一旦標準出力させたものを無理やりファイル出力させた。
正規の方法は、学習させることだと思うが、
数字とハイフンのみ識別させればよかったので、この方法を採った。
数字の認識のみさせるであれば余程特殊なフォントでなければ、かなりの精度で認識した。

ファイル出力する場合
$ tesseract test.png stdout -c tessedit_char_whitelist=0123456789- >test.txt

このようにすると良い。

デフォルトのライブラリを通すと、~や#に誤認識することが有り、
上手くなかったので、探してみたところ有益な情報が見つかったので、オボエガキ

2018/09/12

MSSQLへPHPで接続(PDO接続)

表題の、PHPでMSSQLへの接続時のオボエガキ

もともとは、mssql_connectにてMS SQLServerに接続していたが、
サーバの仕様変更と、php7から利用できなくなることもありPDOPHP Data Objects の略)
接続へ切り替えた。

設定は、/etc/odbc.iniにてODBCのIDとfreetdsドライバーを関連付
/etc/odbcinst.iniに freetdsドライバーを追加
[freetds]
Description = MS SQL database access with Free TDS
Driver      = /usr/local/lib/libtdsodbc.so
UsageCount  = 1
Trace = Yes

freetdsをリポジトリからインストールするとSSLサポートされないので、
手動でインストールが必要だった。
https://stackoverflow.com/questions/39395548/how-to-configure-pymssql-with-ssl-support-on-ubuntu-16-04-lts/39395549
先駆者様ありがとうございます。
python-pip と libssl-dev をインストール後、
freeTDSは0.95のtar.gzを展開し、ディレクトリ内でmakeインストールする。

# ./configure --with-openssl=/usr/include/openssl --with-tdsver=7.3 
# make 
# make install


$ tsql -C
Compile-time settings (established with the "configure" script)
                            Version: freetds v0.95
             freetds.conf directory: /usr/local/etc
     MS db-lib source compatibility: no
        Sybase binary compatibility: no
                      Thread safety: yes
                      iconv library: yes
                        TDS version: 7.3
                              iODBC: no
                           unixodbc: yes
              SSPI "trusted" logins: no
                           Kerberos: no
                            OpenSSL: yes ←ここが重要
                             GnuTLS: no


freetdsで接続する際に参照される接続先の定義は、/home/ユーザ名/.freetds.confに記載する。
##.freetds.confの中身##

#   $Id: freetds.conf,v 1.12 2007-12-25 06:02:36 jklowden Exp $
#
# This file is installed by FreeTDS if no file by the same
# name is found in the installation directory.
#
# For information about the layout of this file and its settings,
# see the freetds.conf manpage "man freetds.conf".

# Global settings are overridden by those in a database
# server specific section
[global]
        # TDS protocol version
;       tds version = 4.2
        # Whether to write a TDSDUMP file for diagnostic purposes
        # (setting this to /tmp is insecure on a multi-user system)
;       dump file = /tmp/freetds.log
;       debug flags = 0xffff
        # Command and connection timeouts
;       timeout = 10
;       connect timeout = 10
        # If you get out-of-memory errors, it may mean that your client
        # is trying to allocate a huge buffer for a TEXT field.
        # Try setting 'text size' to a more reasonable limit
        text size = 64512
# A typical Sybase server
[hoge] ←この変数を 'odbc:hoge' で読み込む。
        host = hoge-sql.database.windows.net 
        port = 1433
        tds version = 7.3
        database = DEMODB
        encryption = require


【PHPの中身】

//MSSQLにPDO接続
//基本:$pdo = new PDO($dsn, $username, $password, $driver_options);
try {
    $pdo = new PDO('odbc:hoge','ログインユーザ名@hoge-sql.database.winwdows.net','パスワード');
    $pdo->exec('SET CHARACTER SET utf8');
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
}catch(PDOException $Exception){
    die('接続エラー:' .$Exception->getMessage());

}

//クエリ取得
try{
    $sql= "select * from [テーブル名] where 条件";
    $stmh = $pdo->prepare($sql);
    $stmh->execute();
}catch(PDOException $Exception){
    die('接続エラー:' .$Exception->getMessage());
}

while($col = $stmh->fetch(PDO::FETCH_ASSOC)){
print($col['カラム名']);
//変数等を定義する場合も普通に行える。
}
}//クエリの取得終了

//sqlServerの接続を解除

 $pdo = null;


2018/08/09

postfixのTLS設定 

gmailで暗号化されていないと赤い鍵が表示されて何か気になるので対策してみる。

ファイアーウォールは適宜解放のこと
25、587、465

ローカルのSSL/TLSの設定は行っているが、
postfixのサーバ間の接続については、細かく設定していなかった。(MTA間通信)
これをTLSやS/MIMEに対応させていないと、gmailで赤い鍵が表示されてしまう仕様のようだ。

postfixの設定見直しはSMTP関連は次のようにしておく

# nano /etc/postfix/master.cf  頭の方に記載がある
【中身】
smtp      inet  n       -       n       -       -       smtpd
↑必須
submission inet n       -       n       -       -       smtpd
↑587ポートを使う場合 
 -o smtpd_tls_security_level=may
↑587の時これをencriptにすると、STARTTLSをしてから送れ、と言われてしまうので、どっちも許容のmayがよい
 -o smtpd_sasl_auth_enable=yes
SMTP認証を使う場合はyesにする
 -o smtpd_client_restrictions=permit_sasl_authenticated,reject
↑SMTP-AUTHを通ったものを許可する。rejectは細かく指定するとそこは蹴れる。


# nano /etc/postfix/main.cf   TLSは末尾に記載されているので、そこを編集
【中身】
## TLS
#  Transport Layer Security
#
smtpd_use_tls = yes
smtp_use_tls = yes
#smtpd_tls_auth_only = yes
↑これを有効にするとTLSでないと蹴るので、コメントアウトのままにしておく
smtpd_tls_key_file = /usr/local/ssl/private/キーファイル.key
smtpd_tls_CAfile = /usr/local/ssl/crt/SSL証明書ファイル.crt
smtpd_tls_loglevel = 3
↑これを1にすると、ログにTLSの事が記載されるらしい。
smtpd_tls_received_header = yes
tls_random_source = dev:/dev/urandom 
smtpd_tls_security_level=may
↑25ポートからのSTARTTLSを使う場合は、master.cfでなく、main.cfに記載するとの事。


postfixを再起動して内容反映
 
# systemctl restart postfix

オレンジ色の部分を記載すると、
相手がTLSを受け付けてくれる場合は、MTA間通信をSSL/TLSにて行える

赤い鍵が消えた。よかった。

2018/06/27

指定ディレクト配下のPDFのファイル名を変更する。

はじめに、OCRをさせる為、Tesseract-OCRをmake installする

その事前準備のライブラリをインストールする

# yum install autoconf automake libtool
# yum install libpng-devel libjpeg-devel libtiff-devel zlib-devel
# yum install libicu-devel
# yum install pango-devel

途中のmakeでmakeでICU(文字コード変換ライブラリ)が必要になるらしいが、
パッケージが無いので、

icu4c をmakeからインストールする
 
# cd /usr/local/src/
# sudo wget http://download.icu-project.org/files/icu4c/56rc/icu4c-56_rc-src.tgz
# tar zxf icu4c-56_rc-src.tgz
# cd icu/source/
# ./configure
# make
# make install

Leptonica という画像解析ライブラリも必要なので、
こちらも、makeからインストール 1.76が最新

# cd /usr/local/src/ 
# wget http://www.leptonica.com/source/leptonica-1.76.0.tar.gz
# tar -xzvf leptonica-1.76.0.tar.gz
# cd leptonica-1.76.0
# ./configure
# make
# make install



tesseract-ocrと辞書のインストール
# cd /usr/local/src/ 
# wget https://github.com/tesseract-ocr/tesseract/archive/3.04.01.tar.gz
# mv 3.04.01.tar.gz tesseract3.01.01.tar.gz
# tar -zxvf tesseract3.01.01.tar.gz
# cd tesseract-3.04.01/
#./autogen.sh
# LDFLAGS="-L/usr/local/lib" CFLAGS="-I/usr/local/include" ./configure --with-training-tools
# make
# make install
# ldconfig


更に、設定ファイルを定義
取敢えず英語の場合、 
tesseract-ocr-3.02.eng.tar.gzをどこからか探してくる。
/usr/local/share/tessdate/配下に 中身をコピーする。


これで、ようやくocrが使える。

 

# pdftoppm 0000.pdf 0000out これで、0000ont.ppmが生成されるので、
これをocrに掛ける。
画像が大きい場合は、optionでトリミングしたりする。

$ pdftoppm /storage1/scanedPdf/20180613133511305.pdf -f 1 -l 1 -mono -x 110 -y 45 -W 140 -H 35 -png  /storage1/scanedPdf/mono

こんな感じで使う。

mono-1.pngをocrに掛ける。
$ tesseract /storage1/scanedPdf/mono-1.png  /storage1/scanedPdf/mono

mono.txtが生成されるので、
これをトリミングして、
欲しい部分だけにする。

$ cat ./mono.txt|tr -d '\n''' > ./mono0.txt
$ cat ./mono0.txt|tr -d ' ' > ./mono1.txt
これで、mono1.txtには
10xx-1XXXXXX が記載されている。

これを使って元のPDFのリネームを行いたい。

ハイフンの全角「ー」と「-」半角を認識する様で、
全角で読み込んでしまうことが有ったので、
nkf コマンドですべて半角にしてしまう事にする。
# yum install nkf
コマンドの際は、
cat $filename-0.txt|nkf -Z4 > $filename.txt
-Zで 全角⇒半角だが、 helpによると-Z4は
JISX0208 Katakana to JISX0201 Katakanaとなっており、
どうもこの方が精度が良いようなので、-Z4でやってみる。


シェルスクリプトの例


#!/bin/bash
#tesseractのパスを通す
export PATH="/usr/local/bin:$PATH"
#ディレクトリ移動
echo "ディレクトリを移動"
cd /storage1/scanedPdf/
#while用にディレクトリ内のファイル数をカウント
count=$(ls | wc -w)
echo "ディレクトリ内のファイル数:"$count
#カウントが0以上なら、ループ処理を行う。
#-ne not equal
while [ $count -ne 0 ]
do
#一行づつ処理するために念のため仕掛ける。いきなり変数でも問題ない。
for file in `\find . -maxdepth 1 -name '*.pdf'| head -n1`; do
basename $file .pdf
done
#変数定義
filename=$(basename $file .pdf)
#pdftoppmでpdfデータの左上(0,0)基準の座標(100,45)から座標(290,80)までを切り出しモノクロのpngを生成する。
pdftoppm $filename.pdf -f 1 -l 1 -mono -x 100 -y 45 -W 190 -H 35 -png  /storage1/scanedPdf/$filename
#上記のpngをOCRで読み取り、テキストファイルを生成する。
#-1は「ファイル名-1.png」が生成されてしまうため、この-1が必要となる。
tesseract $filename-1.png -psm 6  $filename-1
#テキストデータ内の半角スペースを削除する
cat $filename-1.txt|tr -d ' ' > $filename-2.txt
#テキストデータ内の全角―を半角-に書き換える
cat $filename-2.txt|nkf -Z4 > $filename.txt
#変数定義
pdfname=$(head -n 1 $filename.txt)
echo $pdfname
#pdfの名称を1xxx-1xxxxxの形に変更して、/storage1/pdf/に移動
mv ./$filename.pdf /storage1/pdf/$pdfname.pdf
#作業ファイルを削除
rm $filename*
#カウントのデクリメント
count=$(( count -1))
done

上手く動いた。
当初、パスを通していなかったため、上手く動かなかったが、cronでも問題なく動いた。
複合機で一つ一つのファイルを開いて中身を確認して名称を付けるのは非常に面倒くさいし、もの凄い時間を浪費する。
これは、かなり便利だと思う。

2018/06/19

リモートデスクトップ接続が出来ない(windowsアップデートによる)


WindowsServer2012へリモートデスクトップ接続を行なおうとすると、

認証エラー
要求された関数はサポートされません

サーバ:192.168.0.xxx

のダイアログが表示されて接続できない。


環境
サーバ
Windows 2012R2
クライアント
windows7 Home(セキュリティパッチのみ)


2018 年 5 月の更新プログラム適用によるリモート デスクトップ接続への影響
https://blogs.technet.microsoft.com/askcorejp/2018/05/02/2018-05-rollup-credssp-rdp/

4-2. リモート デスクトップ接続元 (クライアント) での回避策
リモートデスクトップ接続元にて以下レジストリを手動もしくは REG ADD コマンドで追加いただくことでも回避策 1 と同様の効果が得られます。

レジストリ パス : HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System\CredSSP\Parameters
値 : AllowEncryptionOracle
データの種類 : DWORD
値 : 2

REG ADD コマンドで追加いただく場合には以下のコマンド ラインとなります。
REG ADD HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System\CredSSP\Parameters /v AllowEncryptionOracle /t REG_DWORD /d 2

とのこと。


コマンドプロンプトを監理者権限で起動し、

REG ADD HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System\CredSSP\Parameters /v AllowEncryptionOracle /t REG_DWORD /d 2

を叩くと接続できた。

根本的な解決は、サーバ側に更新プログラムを適用させろ
との事なので、早めにやろう。

2018/06/04

postgresql 初期化と接続 外部からのdump

postgresqlがインストールされているか確認。
pgsql --version
psql (PostgreSQL) 9.2.18

起動テストをしてみる。
# systemctl start postgresql.service
Job for postgresql.service failed because the control process exited with error code. See "systemctl status postgresql.service" and "journalctl -xe" for details.

初期化が必要だった。
# service postgresql initdb
Hint: the preferred way to do this is now "postgresql-setup initdb"
Initializing database ... OK

動かしてみる。
# systemctl start postgresql.service
[root@localhost ~]# systemctl status postgresql.service
● postgresql.service - PostgreSQL database server
   Loaded: loaded (/usr/lib/systemd/system/postgresql.service; disabled; vendor preset: disabled)
   Active: active (running) since 月 2018-06-04 18:54:47 JST; 12s ago
  Process: 1627 ExecStart=/usr/bin/pg_ctl start -D ${PGDATA} -s -o -p ${PGPORT} -w -t 300 (code=exited, status=0/SUCCESS)
  Process: 1619 ExecStartPre=/usr/bin/postgresql-check-db-dir ${PGDATA} (code=exited, status=0/SUCCESS)
 Main PID: 1630 (postgres)
   CGroup: /system.slice/postgresql.service
           tq1630 /usr/bin/postgres -D /var/lib/pgsql/data -p 5432
           tq1631 postgres: logger process
           tq1633 postgres: checkpointer process
           tq1634 postgres: writer process
           tq1635 postgres: wal writer process
           tq1636 postgres: autovacuum launcher process
           mq1637 postgres: stats collector process

 6月 04 18:54:46 localhost.localdomain systemd[1]: Starting PostgreSQL database server...
 6月 04 18:54:47 localhost.localdomain systemd[1]: Started PostgreSQL database server.

動いた。


一旦停止して、外部からのアクセスが出来るようにする。
# nano /var/lib/pgsql/data/postgresql.conf
L60位のlisten_addressを許容
listen_addresses = '*'                  # what IP address(es) to listen on;

# nano /var/lib/pgsql/data/pg_hba.conf
末尾にIPアドレスの設定

# TYPE  DATABASE        USER            ADDRESS                 METHOD
# "local" is for Unix domain socket connections only
local   all             all                                     trust
# IPv4 local connections:
host    all             all             127.0.0.1/32            trust
# IPv6 local connections:
host    all             all             ::1/128                 trust
# Allow replication connections from localhost, by a user with the
# replication privilege.
#local   replication     postgres                                trust
#host    replication     postgres        127.0.0.1/32            trust
#host    replication     postgres        ::1/128                 trust
# for server
host    all         all         192.168.xxx.0/24        password
host    all         all         192.168.xxx.0/24       password
host    all         all         192.168.xxx.0/24       password
# for vendor
host    all         all         xxx.xxx.xxx.xxx/28     password


firewallを開放
# firewall-cmd --add-service=postgresql --permanent
success
# systemctl restart firewalld.service

再度起動

恐らく問題なく接続できている。

pg_dumpで外部サーバに接続する場合は、同じユーザを作成し、ルートに .pgpass を作成
書き方は
192.168.0.XXX:5432:DB名:ユーザ名:パスワード

複数のDBがある時は、
192.168.0.xxx:5432:*:user:password でOK

$ chmod 600 .pgpass パーミッションは600指定
パーミッション600にしないと、エラーになった。

$ pg_dump -Ft -h 192.168.0.xxx -p 5432 -U user -w dbName > /home/user/dbName_`date '+%y%m%d%H%M'`

-wがパスワード請求無しのオプション
こんな感じでdump出来るので、これをシェルスクリプトにして、crontabに書いて終了。

2018/05/29

JDK8(171)とtomcatとgroupsessionのインストール CentOS7

1.Java SE Development Kit 8u171のインストール


http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
JDK10はgroupsessionが未対応なので、8の最新をダウンロード
rpmパッケージをダウンロードして、ローカルインストールする。

# yum install jdk-8u171-linux-x64.rpm
既にパッケージがインストールされているときは、最新を認識させる必要がある。
# alternatives --config java
3 プログラムがあり 'java' を提供します。
選択 コマンド
-----------------------------------------------
1 java-1.7.0-openjdk.x86_64 (/usr/lib/jvm/java-1.7.0-openjdk-1.7.0.131-2.6.9.0.el7_3.x86_64/jre/bin/java)
*+ 2 java-1.8.0-openjdk.x86_64 (/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-2.b11.el7_3.x86_64/jre/bin/java)
3 /usr/java/jdk1.8.0_171-amd64/jre/bin/java
Enter を押して現在の選択 [+] を保持するか、選択番号を入力します:

最新になっているので、問題ない。
# echo $JAVA_HOME でパスが通っているか確認。
何も出なければ、とおっていないので、在処を探す。
# readlink $(readlink $(which java))
/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-2.b11.el7_3.x86_64/jre/bin/java

設定し、反映させる
# echo "export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-2.b11.el7_3.x86_64/jre" >> /root/.bashrc
# source /root/.bashrc
# echo $JAVA_HOME
/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-2.b11.el7_3.x86_64/jre

2.tomcatユーザを作成、パスワード

# useradd tomcat
# passwd tomcat

3.tomcatをインストール

http://tomcat.apache.org/
gsessionはJ2EEコンテナは6,7,8が対象なので、apache-tomcat-8.5.31.tar.gzをダウンロードし、
展開 ⇒ /usr/localへ移動 ⇒ 所有者をtomcatに ⇒ シンボリックリンクを作成
# tar xvfz apache-tomcat-8.5.31.tar.gz
# mv apache-tomcat-8.5.31 /usr/local
# cd /usr/local
# chown -R tomcat:tomcat apache-tomcat-8.5.31
# ln -s apache-tomcat-8.5.31 tomcat

4.環境変数の定義

JAVA_HOMEとCATALINA_HOMEを定義する。
CentOSの場合、/etc/profileが既にあるので、この後ろに書く。
# nano /etc/profile
末尾に
JAVA_HOME=/usr/java/default
CATALINA_HOME=/usr/local/tomcat
export JAVA_HOME CATALINA_HOME
を加える。

5.systemdの起動用にtomcat.serviceを作成。


# nano /usr/lib/systemd/system/tomcat.service
[Unit]
Description=Apache Tomcat Web Application Container
After=network.target
[Service]
Type=forking
Environment=JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-2.b11.el7_3.x86_64/jre/
Environment=CATALINA_OPTS=-Xmx3072M -2048XmsM
ExecStart=/usr/local/apache-tomcat-8.5.31/bin/startup.sh
ExecStop=/usr/local/apache-tomcat-8.5.31/bin/shutdown.sh
ExecReStart=/usr/local/apache-tomcat-8.5.31/bin/shutdown.sh;/usr/local/apache-tomcat-8.5.31/bin/startup.sh
[Install]
WantedBy=multi-user.target

実行権限を付与
# chmod 755 /usr/lib/systemd/system/tomcat.service

ヒープメモリを
Environment=CATALINA_OPTS=-Xmx3072M -2048XmsM
で設定しないで、~/tomcat/bin/startup.shから直接起動時に反映させたい場合は、
~/tomcat/bin 配下に setenv.sh を作成して、その中に書けば良い

#!/bin/sh
JAVA_OPTS="-server -Xms2048M -Xmx3072M"
export JAVA_OPTS

これで々ように起動時にヒープメモリが設定される。

6.firewall 8080ポートの開放


# firewall-cmd --add-port=8080/tcp --permanent
success
# firewall-cmd --reload
# firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: em1
sources:
services: dhcpv6-client ssh
ports: 8080/tcp
protocols:
masquerade: no
forward-ports:
sourceports:
icmp-blocks:
rich rules:
8080が開いた。

7.起動、停止テスト

# systemctl start tomcat
停止は、
# systemctl stop tomcat
自動起動は
# systemctl enable tomcat



稼働確認


groupsessionのインストール


最新版をダウンロード
https://groupsession.jp/dl/gsession_war_4_8_1-dl1.html

から、gsession.warをダウンロード
# systemctl stop tomcat でtomcatを停止してから、
/usr/local/apache-tomcat-8.5.31/webappsにgsession.warを置く。
# systemctl start tomcat で起動。

2018/05/21

centOS7にntfsのhddをマウントさせる

ntfsドライブをマウントするためのパッケージは

fuse
fuse-ntfs-3g
dkms
dkms-fuse

# yum -y --enablerepo=epel install dkms fuse-ntfs-3g
yumでインストールするが、
epelリポジトリのパッケージをインストールする時は --enablerepo=epel と文句言われるので-y
のパラメータを追加すること。

内部の構成を確認する、パーティションを変更したりする場合で2TBを超える場合は、
fdiskではなく parted -l とかで、処理をすること

マウント先を、適宜指定する
# mkdir /mnt/usbhdd
マウント
# mount -t ntfs-3g /dev/sdb1 /mnt/usbhdd
アンマウント
# umount /mnt/usbhdd

以上

2018/05/19

Linux find 今日作業したファイルを検索

作業したファイのバックアップを取る際に、広域に跨ってると意外に探すのが面倒だったりする。
いつ頃作業したかがわかれば、findで割と容易に見つけられる。

オプション
-type f :ファイルのみを対象に検索
-type d :ディレクトリを対象に検索
-mmin -60 :60分以内に更新
-amin -60 :60分以内にアクセス
-mtime -2 :2日以内に更新
-atime -2 :2日以内にアクセス
-anewer :後述のファイルの日付より後に更新されたものを抽出

今日アクセスしたファイルやディレクトを検索
$ find /home/aaa/bbb/ -atime 0

60分以内に更新したファイルを検索
$ find /home/aaa/bbb/ -type f -mmin -60

元.vmファイルより新しいファイルを検索
$ find /home/aaa/bbb/ -anewer ./work/元.vm

2018/05/17

SQL JOIN時に絞り込み条件付加

join on を指定する際に、条件を付けてjoinできるのを知った。

select <テーブルA>.<カラム1>,<テーブルA>.<カラム2>・・・・,<テーブルB>.<カラム5>,<テーブルC>.<カラム2> from <テーブルA> inner join <テーブルB> on <テーブルB>.<カラム1>=<テーブルA>.<カラム1> and <テーブルB>.<カラム1>=true and <テーブルB>.<カラム2>=0
left join <テーブルC> on <テーブルC>.<カラム1>=<テーブルA>.<カラム1> where 更に条件;¥

このような感じで、join on の際に、複数の条件を付与して連結できる。



LeftJoinの場合は、従の条件を絞ってから連結 というような動きにはならないようだ。
あくまで、 主の条件が絞られていれば、絞ってから連結とする模様。

where以下に条件を書かなくても絞り込めるので、where以下がスッキリする、整理しやすい
というメリットがある。




grepを使った絞り込み ファイル単位で複数の行に条件を設けて抽出する場合


grepを使った絞り込み

条件

ディレクトリA
   aaa.xml
   bbb.xml
   ccc.xml
   ・
   ・
   ・
   zzz.xml

aaa.xml
<type>0</type>
   ・
   ・
<name>0463</name>

bbb.xml
<type>1</type>
   ・
   ・
<name>0463</name>

ccc.xml

<type>2</type>
   ・
   ・
<name>1234</name>

ccc.xml
<type>0</type>
   ・
   ・
<name>0463</name>


ディレクトリAの中にあるxmlで、typeが0、nameが0463のファイルを抽出したい場合
一回のgrepで抽出しようとしたが、行が異なると判定されてしまうので、上手くいかず。
-P '検索箇所頭[\s\S]*?検索箇所末尾' の Pオプションを使った場合、
ファイルサイズが大きく、ファイス数が多いとかなりの負荷がかかる。
また、改行の\nを削除したファイルに置換するものコピーの手間がかかる。
今回の対象ファイル数が、25,000ファイル位あった。
こんなの一つづつはご免蒙る。


そこで、次の手順を取った。
1.取得したい条件を一旦ファイルにする。
 $ grep -r -l "0" /ディレクトリA >type.txt
 $ grep -r -l "0463" /ディレクトリA >name.txt

-rで回帰
-l でファイル名のみ抽出させる。(行数やパターンが出ると、2でgrepした際に重ならない)

2.grepで重なる部分を取得する。
 $ grep -f {type,name}.txt
 結果
 aaa.xml
 ccc.xml
  ・
  ・
 のように抽出したいファイルが絞り込める。
 実際は、
 /home/ディレクトリA/ディレクトリB_1000/1/20180301_134814.xm ディレクトリBのレベルで判別したいので、一旦マージ用のファイルを生成し、
 $ grep -f {type,name}.txt >merge.txt

この段で、P オプションとoオプション(only-matching)を使って絞り込む
  $ grep -oP 'ディレクトリB[\s\S]*?/' merge.txt | uniq -d
ディレクトリB/ ←この部分を取得したい。
 uniq -d  ユニークで重複を表示させない。
  結果
 ディレクトリB_1000
 ディレクトリB_1010
 ディレクトリB_1012
    ・
    ・
    ・
 ディレクトリ
期待値が取れた。 

2018/05/11

TeraTerm(ssh)でGUI(X11転送、X-Window)を使う。

WINDOWSマシンで、X-Window(X11転送、X11フォワーディング)を利用するために

接続先のサーバのsshdでX-wiondwsが許容されている。
TeraTermはインストールされている。
として、

https://ja.osdn.net/projects/sfnet_xming/releases/
ここから、
Xming
Xming-fonts

を其々インストーラーからインストールする。

Xmingをデフォルトでインストールする。

途中でポート(ファイアーフォール)の許可を求めてくるので、許可しておく。
続いてXming-fontsもデフォルトでインストールする。

TeraTermを立ち上げて、
設定⇒ssh設定⇒SSHポート転送を開き、

リモートの(X)アプリケーションをローカルのXサーバに表示するにチェック。

設定の保存をして、再度立ち上げれば、X11転送の設定が完了。(TeraTermの再起動が必要)

端末から、sshでログインして、GUIのコマンド(nautilusなど)を実行すると
X-Windowsが立ち上がる。

sshを更に経由する際は
(直接外部からでなく、一旦固定IPのサーバを経由して、そこからローカルアドレスのサーバにアクセスする様な場合
sshに -Yのパラメータを付けて、
ssh -Y ユーザ名@IPアドレス としておかないと、
X11転送を実行する際に。エラーが帰ってきます。

OpenSSH-7.3p1 日本語マニュアルより、
-Y
信頼された X11 転送を許可します。信頼された X11 転送は、X11 SECURITY 拡張機能の制約をうけることはありません。
との事である。

最初これが見つからずに、認証で躓いたので、オボエガキ。

2018/04/05

PHP URLのgetパラメータ で利用できる文字列と対策

メールで飛んできた内容にurlを張り付けて、DBに書き込むという
少々危険な匂いを漂わせるプログラムを書いたところ、

urlのgetパラメータにコード変換しないと利用できない文字列があった。

具体には以下の一覧を参照

文字 ! " # $ % & ' ( ) * + , - . /
コード %20 %21 %22 %23 %24 %25 %26 %27 %28 %29 %2A %2B %2C %2D %2E %2F
文字 : ; < = > ? @ [ \ ] ^ _ ` { | } ~
コード %3A %3B %3C %3D %3E %3F %40 %5B %5C %5D %5E %5F %60 %7B %7C %7D %7E

今回は、メールアドレスをgetパラメータで遣り取りしたかったので、
@を%40に変換してあげる必要がある。

$mailadd= "hoge@hoge.com";
$mailadd = str_replace("@", "%40", $mailadd);


$msg .= "http://192.168.0.xxx/insert.php?password=$password&username=$username&mailadd=$mailadd"."\n";

こんな感じで
メールの本文の中にinsert.php で使う変数をgetパラメータで予め投げておきたいときに
役に立ちそう。
地味に%20の半角や%2fのスラッシュあたりが便利。


postgrers シーケンス nextvalの記述と確認と変更

シーケンス(シーケンシャル、連番)作成
create sequence seq_id start with 1;

現在のシーケンス確認 
SELECT last_value from seq_id;

nextvalの値を確認
select nextval('seq_id');

値を修正
SELECT SETVAL('seq_id',999);




2018/02/20

SQL CASE文 複数記述 三つの内最大の物を取得する 

次のようなテーブル名 Scoreで4行の其々最大のレコードを取得したいとき。 


Score
x y z
1 2 3
1 2 2
3 3 3
5 4 2

単純な比較の場合は、簡単な記述で済む


SELECT CASE WHEN x < y THEN y
            ELSE x END AS maxmum
  FROM Score;





しかしながら、複数で比較が発生する場合は些か記載が面倒になる




SELECT CASE WHEN CASE WHEN x < y THEN y
                      ELSE x END < z THEN z
            ELSE CASE WHEN x < y THEN y
                      ELSE x END END AS maxmum

  FROM Score;

4つでの比較になると、更に2回記述が増えるので、非常に見難い。
三つ巴までが使用限界と思う。


テーブル内に処理番号、日付、店舗ごとの管理連番、を格納している社内DBで、
年度ごとの店舗ごとの処理件数の合計をカウントでなく、管理連番の最大値の合計を
取得したかった。
受付時、受付受理時、一次納品、二次納品、三次納品、納品完了
このようなステージごとに管理しているが、
一次~三次納品は一括りで数値が欲しかったため、
複数のcaseが必要になった。

力技で一行づつ比較となるので、
レコード数が重いと結構負荷がかかるようだ。