ひとこと

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

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月26日土曜日

Java ServletとAWS-SESでメール送信 No.3

フォームから送信された内容をチェックし、前回作ったプログラムを実行するサーブレットプログラムを作る。


チェックするのは2つ。
・本文の有無
何度か試してみたところ、本文が空だとメール送信できない様子(要検証)
なので本文が入力されているかどうかを調べる。
(このコードでは0か1かの簡単なチェックしかしていない)

・宛先アドレス
今回は個人的な事情で、宛先メールアドレスを指定できる機能が必要だった。
フォームの「宛先メールアドレス」にアドレスが入力されていればそのアドレスへ、
未入力なら本来の宛先である自分のGmailアドレスへメールを送信する。
(ここでも単純なチェックしかしていないが)


[プログラム]
package send;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class SendMail extends HttpServlet{
 
 public void doPost(HttpServletRequest request,HttpServletResponse response)
  throws ServletException,IOException{
  
  // 文字コード指定
  request.setCharacterEncoding("UTF-8");
  response.setContentType("text/html; charset=UTF-8");
  PrintWriter out = response.getWriter();
  
  // メール内容設定
  String subject = request.getParameter("subject"); // 件名取得
  String body = request.getParameter("body");   // 本文取得
  String address = "";
   // 本文入力チェック
  if (body.equals("")) {
   out.print("本文が入力されていません。");
  }else {
   // 宛先アドレス設定
   address = request.getParameter("address");
    // 宛先アドレス入力チェック
   if (address.equals("")) {
    address = "xxxxxxx@gmail.com";
   }

   // メール発射用意!!
   SES ses = new SES();
   // 実行して結果メッセージ出力
   out.print(ses.send(subject,body,address));
  }
 }
}



またコード眺めてて思ったんだけど、メールの文字コードってISO-2022-JPじゃなかったっけ・・・
何も考えずUTF-8にしたが・・・まぁSESが直接メール送信するわけじゃないし、いいのかな(?)

いいか。メールの内容はちゃんと送れてるし。



プログラムをweb.xmlでマッピングする。





    
    
        SendMail
        send.SendMail
      
    
        SendMail
        /SendMail
     
    



Syntax Highlighter使うとDOCTYPEが表示されないのかしら
このページのソースの1143行目を見ればわかると思うがこのxmlコードにはDOCTYPEの指定があります。



とりあえず、ここまで出来たらEclipseでTomcatプラグインを使って動作テストをしてみましょう。

正常にメールが送信されているのを確認したら、
Amazon Web Serviceで仮想サーバ構築 No.5にメモした方法でFTP通信をして、
TomcatのWebappsフォルダ直下(/opt/tomcat7/webapps/)にプロジェクトを配置する。

その後Amazon Web Serviceで仮想サーバ構築 No.4にメモした方法でTomcatを再起動
またはブラウザでTomcatのManagerにアクセスしてプロジェクトを起動する。


これで問い合わせフォーム完成!
ちなみにフォームのURLは「http://xxx.xxx.xxx.xxx:8080/SendMail/html/form.html」である。

Tomcatをポート番号デフォルトで使用している場合、アクセスするポートは8080番となる。
AWS-EC2インスタンスにアクセスする場合はSecurity Groupで8080を許可する必要があるので注意。





そういえばこないだHackMeのLv3をクリアしたので
その攻略法も今度メモしておこうかな。

2013年1月25日金曜日

Java ServletとAWS-SESでメール送信 No.2 -サーバプログラム作成-

前回作ったHTMLフォームに入力された内容をメール通知するプログラムを作る。


まずはとりあえずプログラムのサンプルを動かしてみよう。

1.Eclipseを起動し、AWS Java Projectを新規作成



2.プロジェクト名を入力し、AWS SDK for Java SamplesからSES JavaMail Sampleを選択し「完了」をクリック



3.生成されたプロジェクトにサンプルコードが入ってることを確認



4.サンプルコード中、メールアドレスを指定する部分を自分のアドレスに書き換える。

これを


こうする

この場合は自身のGmailアドレスから同じGmailアドレスにメールを送信することになる。


5.コードの変更を保存し、プログラムを実行する。

6.送信元に指定したメールアドレス宛に、Amazonからメールが届く。
その本文中のリンクをクリックするとアドレスが認証され、以降からメールが送信できるようになる。

7.もう一度プログラムを実行すると、指定した宛先アドレスにメールが届く。




このサンプルコードを基に、問い合わせフォームのサーバプログラム SES.java を作成した。

[事前準備]
○AWSアカウントのキーの値を確認する
AWSにサインアップし、「Security Credentials」をクリックする

セキュリティ証明書ページ中ほどの「アクセス証明書」>「アクセスキー」にある英数字がキーの値。

○必要なjarファイルを用意する
下記のファイルをプロジェクトの「WEB-INF」>「lib」フォルダにコピペする。
・aws-java-sdk-1.3.28.jar
・commons-codec-1.3.jar
・commons-logging-1.1.1.jar
・httpclient-4.1.1.jar
・httpcore-4.1.jar
・mail-1.4.3.jar
ちなみに全てaws-java-sdkのフォルダ内にあります。
それぞれのバージョンは多少違ってもいいんじゃないかな確認してないけど
コピペしたらEcliplseでプロジェクトのビルドパスに追加しましょう。

[プログラム]
package send;

import java.io.IOException;
import java.util.Properties;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.simpleemail.AWSJavaMailTransport;
import com.amazonaws.services.simpleemail.AmazonSimpleEmailService;
import com.amazonaws.services.simpleemail.AmazonSimpleEmailServiceClient;
import com.amazonaws.services.simpleemail.model.ListVerifiedEmailAddressesResult;
import com.amazonaws.services.simpleemail.model.VerifyEmailAddressRequest;

public class SES {

  // subject(件名),body(本文),to(宛先メールアドレス)を引数とするメール送信実行メソッド
    public static String send(String subject,String body,String to) {
     
     final String access_key= "AWSアカウントのACCESS_KEYの値";
     final String secret_key= "AWSアカウントのSECRET_KEYの値";
     
        final String SUBJECT = subject;      // 件名
        final String BODY = body;       // 本文
        final String TO = to;        // 宛先
        final String FROM = "xxxxxxx@gmail.com";     // 送信元

    // 実行結果メッセージ用の変数
     String message = "";
     
     AWSCredentials credentials = new BasicAWSCredentials(access_key,secret_key);
  AmazonSimpleEmailService ses = new AmazonSimpleEmailServiceClient(credentials);

        verifyEmailAddress(ses, FROM);  // 送信元認証
        //verifyEmailAddress(ses, TO);  // 宛先認証?

  Properties props = new Properties();
  props.setProperty("mail.transport.protocol", "aws");
        props.setProperty("mail.aws.user", access_key);
        props.setProperty("mail.aws.password", secret_key);

        Session session = Session.getInstance(props);
        try {
            Message msg = new MimeMessage(session);
             // 送信元設定
             msg.setFrom(new InternetAddress(FROM));
             // 宛先設定
             msg.addRecipient(Message.RecipientType.TO, new InternetAddress(TO));
             // メールタイトル設定
             msg.setSubject(SUBJECT);
             // メール本文設定
             msg.setText(BODY);
            msg.saveChanges();

            Transport t = new AWSJavaMailTransport(session, null);
            t.connect();
            t.sendMessage(msg, null);
            t.close();
            
            message = "送信が完了しました。";
            return message;
            
        }catch (AddressException ae) {
         message = "入力されたメールアドレスが正しくありません。";
         return message;
        }
         catch (Exception e) {
         message = "送信に失敗しました。";
         return message;
        }
    }

  // 以下は変更なし
    private static void verifyEmailAddress(AmazonSimpleEmailService ses, String address) {
        ListVerifiedEmailAddressesResult verifiedEmails = ses.listVerifiedEmailAddresses();
        if (verifiedEmails.getVerifiedEmailAddresses().contains(address)) return;

        ses.verifyEmailAddress(new VerifyEmailAddressRequest().withEmailAddress(address));
        System.out.println("Please check the email address " + address + " to verify it");
        System.exit(0);
    }
}



今コード眺めてて思ったけどmessageのあたりもっとスマートにできるよな・・・精進しよう

新しい送信元を設定する度にAmazonから認証用メールくるのが嫌!!って場合は、
AWSでプロダクションアクセス権を申請すると認証ステップをスキップできて良いそうです。
僕は面倒だから申請してないけど。今回の場合、送信元は固定だしね


長くなったので最後のプログラムは次回。




2013年1月24日木曜日

Java ServletとAWS-SESでメール送信 No.1 -準備とフォーム作成-

今回メモするのは、問い合わせフォームみたいなWebアプリケーションプログラム。
っていうか問い合わせフォーム。前回までに作った仮想サーバで動かす。


全体的な処理の流れはこんな感じ↓
1.HTMLフォームに内容を入力し、Java Servletプログラムに送信
2.Java Servletプログラムは内容を確認し、SESにリクエストを送信
3.SESでメール送信


使うもの
Eclipse
Eclipse用Tomcatプラグイン
AWS Toolkit for Eclipse
※Tomcatプラグインを使うには、PCにTomcatをインストールする必要があるよ。


プロジェクトの最終的な構造は↓の通り。


form.html   → 普通のHTMLフォーム
SendMail.java → 入力内容を簡単にチェックし、問題なければメールを送信するプログラム
SES.java   → SESでメールを送るためのメソッドを定義したクラスファイル



form.html を作成する。

テスト用に宛先メールアドレスの入力欄を作っているが別に無くても問題ない。コードは以下



testForm


件名と本文を入力してください。
管理者のメールアドレス以外の宛先にメールを送信する場合は、 その宛先メールアドレスも入力してください。
件名:

本文:

宛先メールアドレス:





ほんとは今日の内に全部書いてしまうつもりだったんだけど、コードや画像を載せると記事が激しく長くなり
可読性が著しく低下する事になるから2回か3回に分けて書くことにする。

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月12日土曜日

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

仮想サーバはJava Servletが動作するAPサーバとして使用するので、
Apache Tomcatを仮想サーバにインストールする。

LinuxやCUIに不慣れだと小難しくて面倒に思えるが、やってみると案外簡単だった。



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

2.インスタンスにTomcatをダウンロードする。
sudo wget http://ftp.riken.jp/net/apache/tomcat/tomcat-7/v7.0.34/bin/apache-tomcat-7.0.34.tar.gz

ちなみに、ここでは現在の最新版であるver7.0.34をダウンロードしている。
最新のバージョン情報を確かめるにはここを確認する。

3.ダウンロードしたファイルをtar形式のアーカイブに解凍する。
sudo tar -xzf apache-tomcat-7.0.34.tar.gz

4.Tomcatを/opt直下へ移動する
sudo mv apache-tomcat-7.0.34 /opt/tomcat7

5.Tomcat操作用のユーザを設定しておく。maroと命名
sudo useradd -d /opt/tomcat7 -s /bin/false maro

6./opt/tomcat7以下の所有者を、5で設定したユーザに設定
sudo chown -R maro. /opt/tomcat7

7.Tomcatを起動
sudo /opt/tomcat7/bin/startup.sh

8.ブラウザで「http://xxx.xxx.xxx.xxx:8080/」にアクセス。xxx...の部分は仮想サーバのIPアドレスに置き換える

9.こんな画面が表示されたらインストール成功!

※インスタンスのTomcatのWebページにアクセスできない場合はAWSのSecurity Groupを確認


よし!これで終わり!と思うかも知れないがまだやる事がある。
7でTomcatを起動した時に表示された内容に、おかしな点があるはずだ。


JRE_HOMEの位置が違うよね。
No.1から書いてきた通りにやってきたなら、jreは「/usr/lib/jvm/java-7-oracle」の直下にあるはず。

というわけで、この機会にJREの位置をTomにしっかり教えてあげよう。


10.catalina.shを編集し、JAVA_HOMEとJRE_HOMEを設定する。
sudo nano /opt/tomcat7/bin/catalina.sh
  JAVA_HOME="/usr/lib/jvm/java-7-oracle"
  JRE_HOME="/usr/lib/jvm/java-7-oracle/jre"

11.Tomcatを終了→起動し、JRE_HOMEが設定した通りに変更されているのを確認する。
sudo /opt/tomcat7/bin/shutdown.sh
sudo /opt/tomcat7/bin/startup.sh



ここまでやればAPサーバとして最低限の動作はするんだけど
せっかくなのでmanagerを使えるようにする。


12.tomcat-users.xmlを編集し、managerのアカウントを設定する。
sudo nano /opt/tomcat7/conf/tomcat-users.xml

tomcat-usersタグ内に以下の2行を追加(xxx..の部分は任意の文字列)
  <role rolename="manager-gui" />
  <user username="xxxxx" password="xxxxxxxxxx" roles="manager-gui" />



13.Tomcatを再び再起動し、ブラウザで「http://xxx.xxx.xxx.xxx:8080/manager」にアクセスし、
IDとパスワードの欄に12で設定したusernameとpasswordをそれぞれ入力する。

14.この画面が表示されたらok




今回使ったコマンドの意味は↓のサイトに詳しく載っている。
Unix入門 - Linuxコマンド一覧
Unix入門 - Linuxコマンド一覧 - tar
Unix入門 - Linuxコマンド一覧 - useradd
Unix入門 - Linuxコマンド一覧 - chown