sendmailで送るメールを迷惑メールとならないようにするための2つの施策

しっかりとドメインを取得して、サーバを立ててsendmailでメールを送信、自前のsmtpでメールを送信しても迷惑メールになる。メールが届かない(>人<;)

しっかりとしたサービスで迷惑がられていないサービスであれば下記対策をすることで迷惑メールになる可能性を減らすことができます。

1.逆引き設定

IPアドレスからホスト名を引けるようにしますが、逆引きは必ずしも設定しなくても良いことから設定していないこともありますがしっかりと設定しておきましょう。gmailはこの逆引きの設定で迷惑メールに入らなくなることが多いです。

http://support.google.com/mail/bin/answer.py?hl=ja&ctx=mail&answer=1311182&authuser=1

また、重要なことにSPFでIPを指定した際のIP逆引きが必要にもなります。

bindの逆引きの設定の仕方はここでは割愛します。
http://www.atmarkit.co.jp/flinux/rensai/bind904/bind904b.html
などを参照してください。

2.SPFの設定

SPFはメールの送信元が信頼出来るものなのかどうかをDNSサーバのTXTレコードのspf1を参照することでその信頼性を上げるというものです。YahooのメールはこのSPFを設定することで迷惑メールになる確率が下がりました。

SPFの設定は
http://www.openspf.org/SPF_Record_Syntax
に詳細があるのですがTXレコードに下記のフォーマットで記述します。
サンプルにお使いください。

"v=spf1 a:example.com ~all"
"v=spf1 include:example.com ~all"
"v=spf1 include:example.com ip4:0.0.0.0 ~all"
"v=spf1 ip4:0.0.0.0 ~all"
"v=spf1 ip4:0.0.0.0 ip4:1.1.1.1 ~all"
"v=spf1 include:_spf.google.com ~all"

google appsはinclude:_spf.google.comで通ります。gmail.comはredirect=_spf.google.comとなっていますが、sendmailでのSPFであればincludeのほうが効率が良いみたいです。


bindでゾーンファイルでの記述は下記のようになります。

example.com 90 IN TXT "v=spf1 include:example.com ip4:0.0.0.0 ~all"

~allと-allの違いが結構重要になってきます。

"+"	Pass
"-"	Fail
"~"	SoftFail
"?"	Neutral

http://www.openspf.org/SPF_Record_Syntax
に詳細があります。mxレコードの指定など色々と方法がありますので参考にしてみてください。

その他

SPFチェックはここで出来ます。sendmailなど動かすサーバののIPアドレスと、そこから発信するメールアドレスを入力します。

http://www.sendmail.co.jp/sa/spfcheck.html

digコマンドでTXTレコード調査
$ dig -t TXT 
;; ANSWER SECTION:
hostname.  81609 IN  TXT "v=spf1 include:xxxxx ~all"

使っているDebian5.0.10が徐々に古くなってきたのでaptも通らなくなってきた。

http://forums.debian.net/viewtopic.php?f=30&t=76253

そろそろ6.x squeezeにしないとなぁ。
という訳ですがとりあえず5.xでも使えるように色々と更新しました。
ただ、apt-get upgradeで多くのソフトを更新するとおそらくトラブルが出るので注意してください。
5.xから6.xで一度失敗している私なので(>人<;) 注意してください。

sources.list

deb http://ftp.fr.debian.org/debian/ squeeze main contrib non-free
deb-src http://ftp.fr.debian.org/debian/ squeeze main
deb http://security.debian.org/ squeeze/updates main
deb-src http://security.debian.org/ squeeze/updates main
deb http://www.debian-multimedia.org squeeze main non-free

下記のように怒られるので

W: GPG error: http://www.debian-multimedia.org squeeze Release: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY XXXXXXXXXXX
W: You may want to run apt-get update to correct these problems

keyring
http://stackoverflow.com/questions/1139127/debian-apt-get-update-error-public-key-is-not-available-no-pubkey-id

#apt-get install debian-keyring
#gpg --keyserver pgp.mit.edu --recv-keys 1F41B907
#gpg --armor --export 1F41B907 | apt-key add -

nginx + rapid-ssl導入 - わかりやすいよ



nginx + rapid-sslの導入方法を書きます。SSLって何かとめんどくさいイメージありますが、ファイルがどれがどれかわからなくなるから問題なのです。仕組みがわかっていてもファイルがどれがどれかわからなくなります。この時点でめんどくさいですね。でも簡単になるように説明します。
なんでめんどくさい書き方したブログしかないんだよ(・∀・) という不満があったので。

1.Rapid-SSLで暗号鍵を作成


http://www.rapid-ssl.jp/
SSLを取得します。年間で2,600円ですね。

https://www.rapid-ssl.jp/tools/makePkeyCsr2048.php
ダイレクトアクセスできない場合はトップページ> 新規お申し込み > お申込みフォーム > CSR作成ツールより
で2048ビットの秘密鍵の作成を行います。このツールを使ったほうが楽で確実です。

- 秘密鍵のパスワード
- コモンネーム(Common Name) [ 例) ssl.yourdomain.com ]
- 正式英語組織名 [ 例) Hentai, Inc. ]
- 部門名 [ 例) Design ]
- 市区町村名 [ 例) Kanazawa-shi ]
- 都道府県名 [ 例) Ishikawa ]

コモンネームはSSL接続の際のURL(FQDN)になります。ここ注意ね。

秘密鍵 (cert.key ※1)

-----BEGIN RSA PRIVATE KEY-----
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-----END RSA PRIVATE KEY-----

CSR (cert.csr)

-----BEGIN CERTIFICATE REQUEST-----
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
-----END CERTIFICATE REQUEST-----

の2つが表示されます。
cert.key, cert.csrとしてファイルに保存してください。
/etc/nginx/ssl に私は保存しました。


2.Rapid-SSLで登録支払い・メールの確認


https://www.rapid-ssl.jp/ssl/orderForm.php
のオーダーフォームより必要事項を入力。
CSRの貼り付けの項目では上記のcert.csrの内容を貼り付け。


ショッピングの感覚でクレジット決済まで進みます。
承認メールアドレスという項目は postmaster@yourhost.com などでメールを受け取る必要があります。こちらは怠らずおこなってください。


IDがメールで届き、メールが本当に届いているかの確認を行います。
https://www.rapid-ssl.jp/rapidssl-support/ssl-support.htm
でステータスの確認を行います。


メールに書かれているURLをクリックし
RapidSSLのサイトより認証作業を行います。



のような感じになります。


ステータス = 証明書発行完了
になるまでがんばってください。


3.メールの確認、暗号キーのメールの受取り

【通知】 SSL サーバ証明書発行完了のお知らせ

というメールが届くはずです。私はこのようなタイトルでした。

内容は

SSLサーバ証明書:

-----BEGIN CERTIFICATE-----
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
-----END CERTIFICATE-----

中間証明書:

-----BEGIN CERTIFICATE-----
DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
-----END CERTIFICATE-----

の2つです。確認できればOKです。


4.サーバ証明書+中間証明書を合体 (・∀・)

nginxではメールで届いた2つの証明書:SSLサーバ証明書、中間証明書をひとつにまとめたファイルにします。

合体証明書 ( cert.pem ※2 )

-----BEGIN CERTIFICATE-----
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
-----END CERTIFICATE-----

としてcert.pemを/etc/nginx/sslに保存。
ここすごく重要なので何度も読みなおすように。


5.ファイルの確認

cert.key ※1とcert.pem ※2がしっかりと手元にあるか確認してください。

cert.key ※1= Rapid-ssl登録時にWEBサイトで作成したものです(秘密鍵)。
cert.pem ※2= メールで送られてきた証明書を2つ合体させたものです(合体証明書)。

この2つがあればnginxのSSLサーバは動きます。

本記事では下記に保存したとして進めてあります。

/etc/nginx/ssl/cert.key
/etc/nginx/ssl/cert.pem

6.サーバ設定

nginxのconfファイルを書き換えます。

server {

    listen 443;
    server_name yourdomain.com;
    ssl on;

    # 秘密鍵 (cert.key ※1)
    ssl_certificate_key  /etc/nginx/ssl/cert.key;

    # 合体証明書 (cert.pem ※2)
    ssl_certificate      /etc/nginx/ssl/cert.pem;

    ssl_session_timeout  5m;
    ssl_protocols  SSLv2 SSLv3 TLSv1;
    ssl_ciphers  ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
    ssl_prefer_server_ciphers   on;

    access_log /var/log/nginx/ssl_yourdomain.com.log;
    error_log /var/log/nginx/ssl_yourdomain.com.error.log;
    root /var/www/yourdomain.com;
    index index.php;

}

nginx -tコマンドなどを入力すると

# nginx -t
Enter PEM pass phrase:
2012/03/19 00:00:00 [info] 00000#0: the configuration file /etc/nginx/nginx.conf syntax is ok
2012/03/19 00:00:00 [info] 00000#0: the configuration file /etc/nginx/nginx.conf was tested successfully

パスワード入力が求められます。Rapid-ssl登録時のものを入力しましょう。
エラーがなければあとは普通に再起動です。


その他:

symfony1.4をnginxでSSL化するときのnginx.confファイル例です
fastcgi_param HTTPS on は見落としがちですので注意してください。

server {

    listen 443;
    server_name yourdomain.com;
    ssl on;
    # 秘密鍵 (cert.key ※1)
    ssl_certificate_key  /etc/nginx/ssl/cert.key;
    # 合体証明書 (cert.pem ※2)
    ssl_certificate      /etc/nginx/ssl/cert.pem;

    ssl_session_timeout  5m;
    ssl_protocols  SSLv2 SSLv3 TLSv1;
    ssl_ciphers  ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
    ssl_prefer_server_ciphers   on;

    access_log /var/log/nginx/ssl_yourdomain.com.log;
    error_log /var/log/nginx/ssl_yourdomain.com.error.log;
    root /var/www/yourdomain.com;
    index index.php;

    location / {
        if (-f $request_filename) {
            expires max;
            break;
        }
        if ($request_filename !~ "\.(js|htc|ico|gif|jpg|png|css)$") {
            rewrite ^(.*) /index.php last;
        }
    }
    location /sf/ {
        root /usr/share/php/data/symfony/web;
    }
    location ~ \.php($|/) {
        set $script $uri;
        set $path_info "";
        if ($uri ~ "^(.+\.php)(/.+)") {
          set $script $1;
          set $path_info $2;
        }
        fastcgi_pass 127.0.0.1:9000;
        include /etc/nginx/fastcgi_params;
        fastcgi_param HTTPS on; # PHPで_SERVER[HTTPS]のため
        fastcgi_param SCRIPT_FILENAME /var/www/yourdmain.com/web$script;
        fastcgi_param PATH_INFO $path_info;
        fastcgi_param SCRIPT_NAME $script;
    }

}

nginx起動時に求められるパスワードを自動化するには?:

# cp cert.key cert.key.org
# openssl rsa -in cert.key.org -out cert.key

http://webmasters.stackexchange.com/questions/1247/can-i-skip-the-pem-pass-phrase-question-when-i-restart-the-webserver

参考になる:
http://dogmap.jp/2011/05/10/nginx-ssl/

オーストラリア旅行向け。インターネット環境確保について色々と調べてみた。Wifi modem simカードなど。


2003年にオーストラリアにいたのですがその時日本では殆どの家庭にADSL入っていたのですがオーストラリアの家庭ではあまり普及していなかったのを覚えています。しかも、オーストラリアのインターネットは未だにですが従量制なので日本の無制限の感覚に慣れていると自分がどのくらいの転送量を使っているのかわからないもので躊躇します。従量制?しかも一ヶ月500Gの転送量で10,000円程度。オーストラリアのインターネット環境は正直えっ?!ってなります。オーストラリアではEMobile, WiMaxなどのWiFi modemを使おうとなるとこの感覚を引きずってとなります。


Global dataのMiFiを借りたり海外ではSimフリーEmobileの端末に現地のSimカードを差し込んで利用しようとか色々と方法があります。何がベストな方法なのかというのをまとめたいと思います。

1.iPad(Softbank)は海外ではSimフリー

https://www.optus.com.au/shop/broadband/mobile/ipadplans
http://d.hatena.ne.jp/mekong23/20100529
とのことです。30Aドルで4Gの転送まで。ただし、Facebook, Twitter, LinkedIn, Myspace, eBay, Foursquareの転送量は無制限。Googleのサービスも無制限に入れて欲しいよね。Gmailとかも。

2.EMobile端末(国外ではSimフリー)で現地のSimカードを利用

・Telstra
GSM:900/1800MHz 3G:UMTS850/2100MHz, CDMA2000
・Optus
GSM:900/1800MHz 3G:UMTS2100/900MHz
vodafone AU (オーストラリア略のAUです日本のauではありません)
GSM:900/1800Mhz 3G:UMTS2100MHz
・3(three)
GSM:900/1800Mhz 3G:UMTS2100MHz


というキャリアがあります


Optus 3Gカバーエリア
http://www.optus.com.au/aboutoptus/About+Optus/Network+Coverage
http://www2.optus.com.au/


Telstraカバーエリア
http://www.telstra.com.au/mobile-phones/coverage-networks/our-coverage/mobile-broadband/



Telstraは大手でやはりカバー範囲は広いです。OptusはSimカードなど融通の聞くサービスが多いように私は思いました。Telstraは有線は相当強いという位置づけなのかもしれないですね。というわけでOptus Simを選ぶことに。


  • Optusプラン1.30日有効転送量3GBまで

https://www.optus.com.au/shop/Broadband/Mobile-Broadband/Prepaid-Mobile-Broadband/Optus-$30-SIM-PP-OMB


  • Optusプラン2.12ヶ月契約で19Aドル/Month(特定のサービスに対しては転送量無制限)

Facebook, Twitter, LinkedIn, Myspace, eBay and Foursquare.は無制限。Googleは?
https://www.optus.com.au/shop/mobilephones
でも12ヶ月も滞在しませんよね。



いずれもFacebook, Twitter, LinkedIn, Myspace, eBay, Foursquareの転送量は無制限。


転送量制限付き(3GBまで)でだいたい30ドル。結構高いですね。

3.旅行代理店H.I.S.WiFi modemレンタル



調べれば調べるほどわかります。H.I.S.WiFi modemがいかに企業努力しているかがわかります。
http://activities.his-vacation.com/jp/jp/TourList/Default.aspx?ARCD=O6&NTCD=AUS&KYWD=Wi-Fi
33Aドル/weekで転送量無制限で利用ができるとされています。実際使ってみてからレポします。


H.I.S.WiFi modemのモデルはこちら
http://www.cnet.com.au/optus-mini-wifi-modem-339308582.htm


ほとんどHuawei E583Cのようです
http://www.amazon.co.jp/dp/B004ED6CRY
ちなみに返却はどの都市のH.I.S.でも良いみたいです。本当に良いサービスです。


というわけで一週間程度の滞在の私は何を利用するかは決まりました。


長期滞在になるとまた事情が変わってきます。Optus回線よりもTelstra回線を引くのが良いのかもしれない。WiFi modemも持つのであればOptus simを使ったほうが良いみたいです。

Symfony2チュートリアル CRUDアプリを作る



Symfony2でひとまず動かすためのチュートリアルです。
crudコマンドを使って簡単なCRUDを実装します。

http://yourhost/app_dev.php/post/
チュートリアル用のアプリケーションを作ることを前提にします。

バンドル・エンティティを作成

TutorialHelloバンドルを作成し、Postというエンティティを追加します。

$ php app/console generate:bundle --namespace=Tutorial/HelloBundle
$ php app/console doctrine:generate:entity --entity=TutorialHelloBundle:Post --format=yml

Postエンティティの編集

doctrine:generate:entity --entity=TutorialHelloBundle:Post --format=yml
では2つのファイルが作成されます。

src/Tutorial/HelloBundle/Entity/Post.php
src/Tutorial/HelloBundle/Resources/config/doctrine/Post.orm.yml

一つはPostモデル、Post.orm.ymlはDoctrineORマッパー用(今回はアノテーションを利用しません)。
Post.orm.ymlを編集し、 app/console doctrine:generate:entitiesを実行
することでモデルを生成します。

Post.orm.ymlにnameとsubject, descriptionのカラムを準備します。

$ vim src/TutorialHelloBundle/Resources/config/doctrine/Post.orm.yml
Tutorial\HelloBundle\Entity\Post:
  type: entity
  table: null
  fields:
    id:
      type: integer
      id: true
      generator:
        strategy: AUTO
    name:
      type: string
      notnull: true
    subject:
      type: string
      notnull: true
    description:
      type: text
      notnull: true
    
  lifecycleCallbacks: {  }

ORM.YMLからモデル生成しテーブルをupdate

編集したPost.orm.ymlからPost.phpモデルを作成し、doctrine:schema:updateで
テーブルと同期させます。テーブルが存在しない場合は doctrine:schema:create
doctrine:generate:entitiesでバックアップを作成したくない場合は

    • no-backupオプションをつけます。バックアップを作成します。

Post.php~ というファイルが自動的に作成されます。

$ php app/console doctrine:generate:entities TutorialHelloBundle
$ php app/console doctrine:schema:update --force

PostクラスのCRUDを作成

doctrine:generate:crudCRUDを作成します。--entityオプションは必ず必要です。
また、--with-writeをつけないと表示のみ(show)となります。
CRUDには--with-writeが必要です。

$ php app/console doctrine:generate:crud --entity=TutorialHelloBundle:Post --with-write

routingの編集

CRUDのファイルが生成されたらroutingしてあげましょう。
app_dev.phpから/postからアクセスするように設定します。
app/config/routing_dev.yml を編集します。

$vim app/config/routing_dev.yml
# app/config/routing_dev.yml
_post:
    resource: "@TutorialHelloBundle/Controller/PostController.php"
    type:     annotation
    prefix:   /post

これで
http://yourhost/app_dev.php/post
にアクセスできるようになると思います。

Symfony2でも思った以上に簡単にCRUDアプリケーションが出来上がります。

Symfony2のapp/console エンティティ周り

// データベース作成・削除
php app/console doctrine:database:drop --force
php app/console doctrine:database:create

// バンドルの作成
php app/console generate:bundle --namespace="My/ProjectBundle" --format=yml

// エンティティの作成 --fieldsオプションも付けられます
php app/console doctrine:generate:entity --entity=MyProjectBundle:Post --format=yml

// yml Entityからモデルを作成 --no-backupでバックアップを作成しない
php app/console doctrine:generate:entities "MyProjectBundle" --no-backup

// エンティティからテーブルの作成・更新
php app/console doctrine:schema:create
php app/console doctrine:schema:update --force

ymlエンティティ作成に関してfieldsの詳細は
http://symfony.com/doc/2.0/reference/forms/types.html

relationsなどに関して
http://stackoverflow.com/questions/7546377/problem-with-symfony2-schema-yaml-unable-to-get-relationships-working

Symfony2の簡単チュートリアル(環境整備込み)



まだまだ現役のSymfony1.4.6ですがそろそろサポートも終わり、Symfony2が一般的になる日も近いような気がしてきているこのごろです。Symfony2はSymfony1.4.6と互換性がないといっていいでしょう。1.4.6で利用しているデータベースをSymfony2でモデルと生成して利用するというのが今後の流れになるでしょう。早めにSymfony2に触れておきましょう。

http://symfony.com/

色々とチュートリアルがあるけれども意外と動かなかったり。とりあえずここで書いてあるものは私の環境ではしっかりと動作させたもののみ掲載しています。Debian6.0.3 さくらVPSの上でVPN経由で動かしました。

Symfony2の環境整備

symfony2はPHP5.3.xで動作します。Debian6 SqueezeではPHP5.3が入ります。
Debian5 Lenny等の場合は
http://www.debian.org/releases/stable/i386/release-notes/ch-upgrading.ja.html
などを参考になりますが、Squeezeでのmysqlのバージョンアップで多くが何故かトラブります。
Squeezeではnginxのバージョンも上がりますのでSqueezeへのバージョンアップをお勧めします。
http://d.hatena.ne.jp/Kmusiclife/20120118/1326871846


nginxでsymfony2を動作させます。今のところ下記の設定で動作しています。
app.phpやapp_dev.phpのコントロールもこの辺でできます。

location / {
    root /path/symfony2/web;
    index index.html index.htm index.php;
}
location ~ \.php|\.html$ {
    include /etc/nginx/fastcgi_params;
    fastcgi_pass 127.0.0.1:9000;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME /path/symfony2/web$fastcgi_script_name;
}
location ~ \.cgi$ {
    include /etc/nginx/fastcgi_params;
    fastcgi_pass 127.0.0.1:8999;
    fastcgi_index index.cgi;
    fastcgi_param SCRIPT_FILENAME /path/symfony2/web$fastcgi_script_name;
}

なお、nginxなどの細かい設定は
http://d.hatena.ne.jp/Kmusiclife/searchdiary?word=%2A%5Bnginx%5D
を参考にしてください。

その他、gitなど必要となるソフトも幾つかありますのでその都度確認してください。

Symfony2の簡単チュートリアル

$ wget http://symfony.com/download?v=Symfony_Standard_Vendors_2.0.9.tgz -O Symfony_Standard_Vendors_2.0.9.tgz
$ tar zxvf Symfony_Standard_Vendors_2.0.9.tgz
$ mv Symfony symfony2
$ cd symfony2

download完了です

$ php app/check.php # 問題がなければ次へ
$ php bin/vendors install # vendorの場合は --reinstall を追加

localhost以外からアクセスする場合は

$ vim web/app_dev.php
/* コメントアウトします
if (!in_array(@$_SERVER['REMOTE_ADDR'], array(
    '127.0.0.1',
    '::1',
))) {
    header('HTTP/1.0 403 Forbidden');
    exit('You are not allowed to access this file. Check '.basename(__FILE__).' for more information.');
}
*/

ブラウザよりアクセスします。
http://hostname/app_dev.php
にアクセスします。

Whoops, looks like something went wrong.

などのエラーが出た場合はcacheのパーミッションに問題があることが多いです。

$ chmod -R 777 app/cache app/logs

でcacheのパーミッションを与えます。
welcomeのページが表示されればOKです。

http://hostname/app_dev.php/_configurator

よりデータベースなどの基本設定を行います。
おそらく書き込みエラーが出るので

$ chmod -R 777 app/config/parameters.ini

再度更新してリクエストを送り直せば更新されます。

Doctrine(model)を作成します。

$ php app/console doctrine:generate:entity --entity=AcmeDemoBundle:Product --fields="name:string(255) price:float description:text" --format=yml

を行うことによって

src/Acme/DemoBundle/Entity/Product.php
src/Acme/DemoBundle/Resources/config/doctrine/Product.orm.yml

の2つのファイルが作られます。 doctrine:generate:entityで--format=ymlを付けないとProduct.orm.ymlファイルが作成されませんので注意です。

$ php app/console doctrine:database:create
$ php app/console doctrine:schema:update --force

でデータベースにテーブルを作りモデルと同期させます。

// src/Acme/DemoBundle/Controller/DemoController.phpなどで
use Acme\DemoBundle\Entity\Product;

public function indexAction()
{

    $product = new Product();
    $product->setName('Foo bar');
    $product->setPrice(100.00);
    $product->setDescription('This is test description.');
    $em = $this->getDoctrine()->getEntityManager();
    $em->persist($product);
    $em->flush();
    
    echo $product->getId();
}

とテストコードが動けば問題ないでしょう。
http://hostname/app_dev.php/demo/
などでアクセスできると思います(環境によって異なります)。

この辺のはなしは
http://docs.symfony.gr.jp/symfony2/book/doctrine.html
にもあります。ただ、私はこのチュートリアルではしっかりと動作しませんでした。