ひとこと

― 今日のひとこと ―
年に1回くらい、EVE Onlineやりたくなるのよね。
(2025.12.24)
ラベル network の投稿を表示しています。 すべての投稿を表示
ラベル network の投稿を表示しています。 すべての投稿を表示

2016年10月28日金曜日

SMTPでレスポンス分割...?

うちの製品に、メールで情報を送信する機能がある。
つまりSMTP通信を行う機能だ。

その機能について、某大企業の担当者から問い合わせがあった。
「メールが送信できません。」

うちのユーザサポート部署のFさんが詳しくヒアリングしてくれて、
開発部にいる僕に相談しにきた。

話を聞くと、どうやらお客さんの環境はかなり特殊なようだ。
それというのも、EHLOのレスポンスをUTMが分割しているというのだ。
送ってもらったパケットキャプチャを確認してみた。

普通ならレスポンスは1度にまとめて送られてくる。
しかしそのUTMは、SMTPサーバから受け取った複数行リプライを数行ずつ
計2つのパケットに分割して送ってきていたのだ。
SMTPのレスポンスを分割するなんて、僕は聞いたことがなかった。

SMTPのレスポンスは分割され得るものなのか?
インターネットで調べてもそんな例は見当たらない。
ネットワーク系にかなり詳しい同僚も、そんなの見たことないよと言う。
(ちなみにこの同僚、某世界的大手企業から『アジアNo.1セールスエンジニア』と認定されており、同業他社からスカウトされまくる凄い人である。)
これはどうしたものだろう。



そのUTM、実は問い合わせてきたお客さんの会社の製品である。
なので訊いてみた。分割の根拠と理由。
するとこんな回答があった。

「RFCに分割手法が書いてある。」
「ウィルスチェックのためにリプライを解析しており、タイムアウトを防ぐべく分割して送っている。」



SMTPについて記述されたRFC5321なら僕は読んだことがある。
しかしレスポンス分割に関係しそうなことなんて書かれてないはずだ。
念のために改めて読んでみたが、やはりそんなことは書かれていない。
お客さんが言っているのは別のRFCなのだろうか。
だとしたらSMTP以外の規約が絡んでくるということであり、すごく面倒だな。

Fさん経由で、根拠としているRFCの番号を訊いてみた。
結果は・・・

Fさん「RFC5321だそうです。4.2章のこの部分。」

5321かよ。
そして示された部分はEHLOの複数行リプライの文法に関する記述。
要約するとこんな内容である。
「最終行以外は2XX-xxxxxxxx、最終行はハイフンをスペースに変えて2XX xxxxxxxxとせよ」
「最終行にスペースが使われてなくても対応できるようにクライアントは準備しておけ」

はい。
これは1度のリプライが複数行に及ぶ場合の文法を定義してるわけで、
どう読んでもパケット分割に対応すべしと受け取ることはできないよね。
そもそもEHLOでパケット分割を許容するならDATAコマンド風な仕様になるはずだよね。
つまり五月雨送信の終了を明示的に表す情報が必ず送られてくるべきっていう仕様。

と思ったままをFさん経由で回答すると、
お客さんは案外あっさりと納得してくれた。
なんだそりゃ。

ちなみに、分割の理由についても思うところはある。
分割されたパケットの送信間隔は1秒にも満たない。
ならば分割などという致命的なRFC違反なんかしなくても、
レスポンスはひとまずそのまま送っておいて、もし問題ありと判定したなら
以降の通信を拒否すればいいのだ。ただそれだけ。

でもこの部分、Fさんはお客さんに伝えてない。
まぁ言えないよな。言う必要ないし。



うちのその製品では、EHLOのレスポンス内容に関わらず
ユーザが指定した設定に従ってSMTPコマンドを実行する。
これもRFCに則った動作とはいえないが、色々と事情があったのだ。
その分、通常はこの動作がネックにならないように作り込んでおり、
このお客さん以外のすべてのユーザ環境で正常稼働している。

今回お客さんはStartTLSとSMTP認証を使っていた。
なので具体的には、
「EHLOの分割レスポンス2つ目をUTMが送信する前にSTARTTLSコマンドが実行されてるぞ!だからメール送信できないぞ!」
という問い合わせだったわけだ。

これについては上述の通り、お客さんは「UTMが悪いんじゃん!」と納得してくれた。
しかし・・・

「EHLOの分割レスポンス2つ目をUTMが送信する前にAUTHコマンドが実行されてるぞ!だからメール送信できないぞ!あとAUTHコマンドってなんだ!」
という問い合わせが翌日あった。もちろん同じお客さんである。

なぜだか知らないがこのお客さん、どうやら「じゃあStartTLS使わなければいいんじゃん!」と思ったらしい。

だからそもそも分割してんのが駄目なんだって!!!

それと少しは自分で調べてみてよ・・・。
「SMTP Auth」で調べたら、AUTHコマンドがSMTP認証のコマンドだってすぐわかるよ。。
コマンドレベルの細かい問い合わせしてくる割に知識がないんだよな。
ひょっとして新人なのかな・・・先輩にいわれて問い合わせてるだけの


そんなお話

2013年2月2日土曜日

Amazon Web Serviceで仮想サーバ構築 No.8 -TomcatでBASIC認証-

Tomcatサーバのサーブレットプログラムに対するアクセスにBASIC認証を適応する方法。

プログラムの利用者を限定したい場合、No.7で利用可能になったHTTPS通信と併用する事でより安全に通信を行えるようになる。
っていうかBASIC認証で使用する秘密情報は素でネットワークを流れるから暗号通信と併用しないと危険

今回はデフォルトで用意されている「UserDatabaseRealm」を利用する。




1.No.2にメモした方法でインスタンスに接続する。


2.tomcatのtomcat-users.xmlを編集する。
roleに関する部分のコメントを解除し、必要に応じてロールやユーザを追加する。

ここを


こうする


今回はTomcatにアクセスを許可するユーザには「tomcat」というroleを割り当てる。


3.サーブレットのweb.xmlを編集する。

web-appタグにsecurity-constraintタグとlogin-configタグとsecurity-roleタグを追加する。
↓はJava ServletとAWS-SESでメール送信 No.3 で作成したプログラムにBASIC認証を導入した場合の例





    
    
        SendMail
        send.SendMail
      
    
        SendMail
        /SendMail
     

    

    
     
      html
      /*
     
     
      tomcat
     
    
    
    
     BASIC
     UserDatabaseRealm
    
    
  tomcat
    
    



4.Tomcatを再起動する。



これで設定はおしまい。BASIC認証を設定したプログラムにアクセスしてみると・・・


このように認証ウィンドウが開く。



ただ、いまいちよくわかんないんだけど
web-resource-nameタグで指定したhtmlフォルダ以外のプログラムにアクセスしても認証ウィンドウが出てくるんだよね。
まぁ自分の場合はメール送信プログラムの実行前に認証できてればよかったから別にいいけど。
この辺はきっと未来の自分がなんとかしてくれるだろう。。


追記(2013/02/03_17:22):web-resource-collectionタグ内の記述について
web-resource-nameタグに記述するのは「リソース名」ではなく、
「アクセス制限ルールを適用するリソースに対する任意の名称」です。つまり何でもいいようです。
また、url-patternタグに記述するのは「web-resource-nameで指定したリソースからのパス」ではなく、
単純に「アクセスを制限するリソースのURL」でした。servlet-mappingタグでのurl-patternの指定と同じ記法です。

たとえば、「http://xxx.xxx.xxx.xxx/SendMail/html/」以下のプログラムに対するアクセスに認証を設ける場合は、
     
      まろ最高
      /html/*
     
 
とするのが正解です。


貴重なアドバイスを下さった越冬老師様に、大変感謝いたします。


2013年2月1日金曜日

Amazon Web Serviceで仮想サーバ構築 No.7 -TomcatでHTTPS通信-

TomcatサーバとHTTPS通信できるようにする方法をメモする。

今回もこれまでにAWS-EC2で作成した仮想サーバを使用している(Ubuntu12/Tomcat7)




1.No.2にメモした方法でインスタンスに接続する。

2.No.4で設定したTomcatの所有ユーザ(自分の場合はmaro)のホームディレクトリへ移動する
cd /home/maro

3.SSL/TLS通信で必要となるキーストアを作成する。
keytool -genkey -alias tomcat -keyalg RSA

#以下の質問に答えていく(全てアルファベット)

Enter keystore password: キーストアのパスワードを入力

What is your first and last name?
  [Unknown]:  ①TomcatサーバのFQDNを入力

What is the name of your organizational unit?
  [Unknown]: ②組織単位名を入力

What is the name of your organization?
  [Unknown]:  ③組織名を入力

What is the name of your City or Locality?
  [Unknown]:  ④都市名または地域名を入力

What is the name of your State or Province?
  [Unknown]:  ⑤都道府県を入力

What is the two-letter country code for this unit?
  [Unknown]:  ⑥国番号を入力(日本ならJP)

  ちなみに、僕の場合は⑥以外は全てmaroだかmaro.comだか、とにかくてきとーに入力した。
  Elastic IPのサービスを受けていないからドメイン名など持ってない!とにかく暗号化できればいい。


4.server.xmlを編集する。

  No.6でポート番号の設定を変更したConnecterタグの少し下に、コメント化されたSSL/TLSに関するConnecterタグがある。
  そのコメントを解除して、以下の2行を追加する。
keystoreFile="キーストアの指定"
keystorePass="キーストアのパスワード"
  ついでにHTTPSのポート番号(Tomcatデフォルト値8443)をウェルノウンポートに合わせる場合は、
  「port="8443"」を「port="443"」に変更する。



5.Tomcatを再起動して変更を反映させる。




これでおわり。
実際にアクセスしてみると・・・

警告が表示される。まぁてきとーにドメイン指定された自前の証明書を使ってるわけだから当然よね。

例外として承認すれば接続できるわけだけど

散々な言われ様だな・・・


結果

URIスキームに注目。「https://」になってるのが確認できる。





次回はBASIC認証の導入。

Amazon Web Serviceで仮想サーバ構築 No.6 -Tomcatポート変更-

Tomcatのポート番号は8080がデフォルトだから、そのままだとサーバにアクセスする度にいちいち指定しないといけないから面倒。

というわけで、ポート番号をウェルノウンポートに合わせる方法をメモする。


1.tomcatの conf/server.xml を開く。

2.Connecterタグのportの値を変更する。

  これを


  こう


  redirectPortは別に変えなくてもいい。

2013年1月14日月曜日

Amazon Web Serviceで仮想サーバ構築 No.5 -vsFTPdインストール-

前回、仮想サーバがAPサーバとして動かせる状態になった。
しかし動くだけではだめ。開発したプログラムを配置できるようにしなければならない。

というわけで今回は、FTP通信でデータを仮想サーバと送受信できるようにする方法をメモする。
まぁインスタンスにvsFTPdをインストールして設定するだけなんだけど。

vsFTPd(very secure FTP daemon)というのは、その名の通りFTPサーバである。
設定内容は以下の通り。




1.No.2にメモした方法で、インスタンスに接続する。

2.インスタンスにvsftpdをインストールする。
sudo apt-get update
sudo apt-get install vsftpd
vsftpdが自動で起動してしまう↓ので、停止させる。

sudo /etc/init.d/vsftpd stop

3.vsftpd.confの内容を変更する。
sudo nano /etc/vsftpd.conf
anonymous_enable=NO
local_enable=YES
write_enable=YES
chroot_local_user=YES
chroot_list_enable=YES
chroot_list_file=/etc/vsftpd.chroot_list
ls_recurse_enable=YES
use_localtime=YES
userlist_enable=YES
userlist_deny=NO
userlist_file=/etc/vsftpd.user_list
local_root=

4.vsftpd.chroot_listに、chrootを許可するユーザのユーザ名を記述する。(この記事の最後を要確認)
sudo nano /etc/vsftpd.chroot_list

5.vsftpd.user_listに、アクセスを許可するユーザのユーザ名を記述する。
sudo nano /etc/vsftpd.user_list

6.vsftpdを起動する。
sudo service vsftpd start


これで、開発のための仮想サーバ側の基本的な準備はおしまい。たぶん。
では、ここからは仮想サーバと実際にデータをやり取りする方法。


7.FFFTPをPCにダウンロード&インストールする。

8.FFFTP.exeを実行してFFFTPを起動する。


9.メニューの「接続(F)」>「接続(C)」をクリック


10.「ホスト一覧」ウィンドウの「新規ホスト」をクリック


11.「基本」タブを編集する。
接続先ホストの名前(任意)とIPアドレス、
chroot_listとuser_listに記述したユーザ名とそのユーザのパスワードを書き込む。

12.「拡張」タブを↓のように編集する。


13.「文字コード」タブを編集する。ホスト・ファイル名共にUTF-8を指定。

14.「高度」タブを↓のように編集し、「OK」をクリックして設定完了。


15.「ホスト一覧」ウィンドウに、設定した接続先が表示される。


16.「接続」をクリックし、↓の画面のようになれば成功。




これで、自宅PCで書いたコードを仮想サーバに送って実行させる事ができるようになった。
うん。万々歳!!


・・・ただ、ひとつ訂正しなければならない点があったんだ。
ここまで普通に流してきた風に書いたけど、これを読んでる未来の自分はもう気づいてるはずだ。

「前回Tomcat用に作ったユーザにはパスワードなんか設定してなかった。いつの間に設定したんだ?」
そう訝しんでる事だろう未来の自分。むしろ訝しめ。

実は、前回のやり方で作成したユーザmaroはそのままではvsFTPdで使えないんだ。
だから同名ユーザを作り直して、そのついでにパスワードを設定していたんだ。すまない。

そこらへんの手順は次の通りだ。

1./opt/tomcat7以下の所有者をubuntuに変更
sudo chown -R ubuntu /opt/tomcat7

2.maroを削除
sudo userdel -r maro

3.maroを作成しパスワードを設定
sudo adduser maro

4.maroをsudoersに追加
sudo visudo
# User privilege specification
root    ALL=(ALL) ALL
maro    ALL=(ALL) ALL

5./opt/tomcat7以下の所有者をmaroに変更
sudo chown -R maro /opt/tomcat7

もしこの時点で/home直下にmaroディレクトリが無ければ、以下の手順も追加する。
6./home直下にmaroディレクトリを作成
sudo mkdir /home/maro

7./home/maro以下の所有者をmaroに設定
sudo chown -R maro /home/maro


以上の5つないし7つの手順を、vsFTPdを起動する前にやっておけばいい。
そんなん面倒くせぇよと思うならもうubuntuアカウントのpasswd設定してvsFTPdに使う事をお勧めします

2013年1月7日月曜日

Amazon Web Serviceで仮想サーバ構築 No.2 -インスタンスへの接続-

七草粥がおいしい。さつま揚げとたくあんも最高。
というわけで今回は、前回作成したインスタンスに自宅PCから接続する方法をメモしておく。

AWSで作った仮想サーバは当然Amazonのデータセンタに存在する。
前回はインスタンスを東京から15000km離れたウェストバージニア州に設置したので、
自宅から直接操作するなんてことはできない。なのでSSH通信を使って遠隔操作する。そのために使用するのがputtyだ。

puttyフリーのtelnet/SSHクライアントソフトであり、仮想サーバを構築する上で(僕にとっては)必要不可欠な存在である。


まず、puttyを使う準備をしよう。

1.puttyのダウンロードページで「putty.zip」をクリックし、zipファイルをダウンロードする。


2.ダウンロードしたファイルを解凍すると、↓のような内容である事が確認できる。


3.アプリケーションがいくつか入っているが、利用するのは「putty.exe」「puttygen.exe」だけだ。


4.安全なSSH通信を行うには鍵が必要だ。ここで前回ダウンロードした鍵ファイルを使用する。
前回ダウンロードした鍵ファイルをputtyで使えるように加工する。「puttygen.exe」を起動。


5.「Load」をクリックし、前回ダウンロードした鍵ファイル(~.pem)を選択


6.読み込み成功メッセージが表示される。「OK」をクリック


7.何も入力せず「Save private key」をクリック。
パスワード設定しなくていいの?と訊かれるが「はい」をクリックする


8.新たに作成したputty用鍵ファイル(~.ppk)を保存。ファイル名は何でもok


以上でSSH通信の準備は整った。早速インスタンスに接続してみる。


1.AWS EC2のページへ行き、前回作成したインスタンスを起動する。

2.インスタンスをクリックして選択すると、画面下部にインスタンスの情報が表示される。
↓の画像の下線部を見てほしい。


一部ぼかしてある↑の画像では「107-xxx-19-1x1」となっている部分。
これがインスタンスのIPアドレスの値を表している。

3.先ほどダウンロードしたフォルダ内の「putty.exe」をクリックして起動

4.画面左側の「Category」から「Session」を選択し、
「Host Name (or IP address)」に先ほど確認したインスタンスのIPアドレスを入力する。
(今回の自分の場合、 107.xxx.19.1x1 がIPアドレスとなる)


5.次に、「Category」から「Window」>「Translaiton」を選択し、
「Remote character set」を「UTF-8」にする。


6.「Category」から「SSH」>「Auth」を選択し、
「Browse」をクリックして先ほど作成したputty用鍵ファイルを選択


7.画面右下の「Open」をクリック

8.この画面が表示されたら接続成功。


9.ユーザ名を入力してログイン!


初回ログイン時に使用するユーザ名はデフォルトで決められている。
インスタンス作成時に指定したOSがLinuxなら「ec2-user」、Ubuntuなら「ubuntu」など。

※もし「server refused our key」と表示されてログインできないようなら、
インスタンスを作り直してみる事をお勧めする。その際はKey Pairも新たに作成すること。



これでインスタンスをいじる準備は全て整った。
次回からはこの仮想サーバをカスタマイズして、アプリケーションサーバを構築していく。