2014年5月8日木曜日

FuelPHPでセキュアな設定をする

FuelPHPをお仕事で使う方も増えてきたと思います。
そんな中で気になるのはやはりセキュリティ。
ということで今日はFuelPHPでセキュアな状態にするための設定を書きます。
まず

@kenji_sさんの下記のブログが非常に分かりやすく書かれています。
今日はこれ以外の下記の項目について書きます。

  1. DBにセッションを保存
  2. 変更推奨のセッション情報
  3. https時にCookieにsecure属性を付与

1.DBにセッションを保存

defaultはセッションをクッキーに保存しています。
これをDBに変える情報は公式ドキュメントにあります。

FuelPHP公式ドキュメント 1.7

DB以外にも

  • File
  • Memcached
  • Redis

などが選べます。
DBを使う際にMySQLの方はいいのですがPostgreSQLを使う方は

#reate the sessions table
$ php oil r session:create

が動きません。
なのでCREATE文と設定方法をご紹介します。

まず

fuel/core/config/session.php



fuel/app/config/session.php

にコピーします。
次に fuel/app/config/session.php のdriverの項目でdbを指定します。

'driver'  => 'db',
次にdbにセッション専用のテーブルを作成します。
下記SQLで作成できます。

--PostgreSQL用
CREATE TABLE sessions
(
session_id character varying(40) NOT NULL,
previous_id character varying(40) NOT NULL,
user_agent text NOT NULL,
ip_hash character varying(32) NOT NULL DEFAULT ''::character varying,
created integer NOT NULL DEFAULT 0,
updated integer NOT NULL DEFAULT 0,
payload text NOT NULL,
CONSTRAINT sessions_pkey PRIMARY KEY (session_id),
CONSTRAINT sessions_payload_key UNIQUE (payload)
)
WITH (
OIDS=FALSE
);
ALTER TABLE sessions
OWNER TO ユーザ名;

これでセッションをDBに保存するようになります。

2.セッション時間の変更

セッション利用する際に変更推奨の項目です。
1.でcopyしてきた

fuel/app/config/session.php

の項目に

//セッションIDを保存するCookie名
cookie_name

があります。
こちらはdefaultの名前ではFuelPHPのどのdriverを使ってるかがわかります。
セキュアな環境を求められる際は変更した方が良いと思います。
似たような設定にCSRF対策時に利用するkey名があります。
こちらは

app/config/config.php

のSecurityの項目の

csrf_token_key

の項目で変更できます。

それ以外にもsession.phpには

  • expiration_time
  • rotation_time
  • match_ip
  • match_ua

などセキュアにセッションを扱うための設定があります。
defaultはゆるく設定されていますので要件に合わせて設定を変更すると良いと思います。

3.https時にCookieにsecure属性を付与

httpsの際にCookieにsecure属性をつけていないと盗聴される可能性があります。

PHP と Web アプリケーションのセキュリティについてのメモ

Cookie の secure 属性


セキュリテイについては安定の徳丸さんの記事を御覧ください。

徳丸浩の日記

HTTPSを使ってもCookieの改変は防げないことを実験で試してみた


FuelPHPはdefaultでは付与していません。
ですが設定一つで対応できます。
設定箇所は

fuel/app/config/config.php

'cookie' => array()

を有効にし

'secure' => false,



'secure' => true,

と変更します。
これでsecure属性を付与してくれます。
ただし、secure属性は

  • https通信時のみ Cookie の内容を送信
  • http通信時には Cookie の内容を送らない

というものですのでhttpでアクセスした際はCookieの内容を送信しません。
ですのでhttp通信時はセッションの保持もCSRFも正常に動作しません。
(本版環境はhttpsだけど開発環境はhttpの場合などでハマるポイントですね)

以上の3点が本番リリース時に気にする項目だと思います。
FuelPHPとは関係ないですがヘッダー情報でphpとapacheのバージョン情報が分かります。
こちらはapacheのhttpd.confやphp.iniを修正する必要があります。

■apacheの場合
・対象File
CentOS:/etc/httpd/httpd.conf
ubuntu:/etc/apache2/conf-enabled/security.conf

・変更箇所
ServerTokens Prod
ServerSignature Off

■PHPの場合
・対象File
php.ini

・変更箇所
expose_php = Off

となります。
上記と合わせて設定をご検討していただけたらと思います。


ということでFuelPHPのconfigは色々と設定出来るので一読すると面白いと思いますよ!!

Symfony2でDoctrine2使う時によく使うEntityのアノテーション一覧とDoctrine2のコマンド一覧

Symfony2シリーズ第二弾です。
Doctrine2はアノテーションでEntityの関係や属性を指定出来るので便利です。
ただドキュメントが英語だったので自分用によく使うヤツをまとめて置いときます。

公式ドキュメント(アノテーション一覧)

/**
 * UNIQUE制約のIndexを作るとき
 * nameを指定しない場合はIDX_6E72A8C13B66675Bのように種類_ランダムの名前が付けられる
 * @ORM\Table(name="テーブル名", uniqueConstraints={@UniqueConstraint(name="キー名", columns={"カラム名"})})
 * 複数指定もできる
 * @ORM\Table(name="テーブル名", uniqueConstraints={@UniqueConstraint(columns={"カラム名", "カラム名"})})
 *
 * Indexを指定したい時
 * @ORM\Table(name="テーブル名", indexes={@index(columns={"カラム名"})})
 * 複数指定もできる
 * @ORM\Table(name="テーブル名", indexes={@index(columns={"カラム名", "カラム名"})})
 *
 **/
class テーブル名
{
    /**
     * ID
     *
     * @var integer
     * 
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * オートインクリメントの指定
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * ほげ(外部キー貼る側)
     * 外部制約(リレーションを指定するときは名前空間を指定すると補完が効く
     * @var \project\MyBundle\Entity\Hoge\Hoge
     * リレーションの指定
     * @ManyToOne(targetEntity="\project\MyBundle\Entity\Hoge\Hoge", inversedBy="hoge")
     * @JoinColumn(name="hoge_id", referencedColumnName="id")
     * */
    private $hoge;

    /**
     * ほげ(外部キー貼られる側)
     * 外部キー貼られる側も指定がいる
     * @var \Doctrine\Common\Collections\ArrayCollection
     * カスケードの動作等は貼られる側で指定する
     * @OneToMany(targetEntity="\project\MyBundle\Entity\Hoge\Hoge", mappedBy="hoge", cascade={"persist","remove"})
     * */
    private $hoge;
 
     /**
     * 登録日時
     *
     * @var \DateTime
     *
     * @Gedmo\Timestampable(on="create")
     * @ORM\Column(name="created_at", type="datetime")
     */
    private $createdAt;

    /**
     * 更新日時
     *
     * @var \DateTime
     *
     * @Gedmo\Timestampable(on="update")
     * @ORM\Column(name="updated_at", type="datetime")
     */
    private $updatedAt;
}

注意が必要なのはリレーションを定義するときは両方のEntityにアノテーションを記載する必要があります。
そしてSQL的にはカスケードの条件は外部キーを貼る側に記載しますがアノテーションは外部キーを貼られる側に記載します。
というよりも実際にカスケードの条件はDDLとしては付与されてません。
アノテーションでのカスケード処理はDoctrineが処理する際に行うだけで実際のDBのDDLには関与しないので注意が必要です。
同じようにdefaultやon="create"も同様です。
DDLとしてdefaultやtimestamp型が使われるわけではないのです。
このへんはDBとコードが不一致なので動作については注意が必要ですね。

それとDoctrine2のよく使うCUIコマンドです。

//DBの作成
php app/console doctrine:database:create

//エンティティの作成
php app/console doctrine:generate:entity --entity="MyBundle:Entity名" --fields="name:string(255) price:float description:text"

//ゲッター・セッターの作成
php app/console doctrine:generate:entities project名/MyBundle/Entity/エンティティ名

//全部のエンティティの作成
php app/console doctrine:generate:entities projectMyBundle

//テーブルの作成
php app/console doctrine:schema:update --force

//データの投入
php app/console doctrine:fixtures:load --env=test


Doctrine2でDBマイグレーションを管理すると環境の複製やリリース等が簡単になります。
またFuelPHP2.0でもDoctrineを採用するようです。
PHPフレームワークのDBのスタンダードになりつつあるのでDoctrine2を覚えておいて損はないと思います。
(NetBeansはDoctrine2対応していますしね!)


ということで今日のところは以上です。

Symfony2のTwigExtentionをからContainerやEntityManagerを呼び出す

Symfony2は重厚で大規模開発には非常に優秀だと思います。
そんなSymfony2ですがちょっと手の込んだ事を調べると日本語情報が少ない印象です。
英語の公式ドキュメントとstackoverflow.comを行ったり来たりした結果をメモとして残しておきます。

やりたいこと


  1. Symfony2でTwigExtentionを作る
  2. 作ったTwigExtentionのgetGlobals()からDBの呼び出しやサービスの呼び出しをする
  3. base.html.twigの変数にDBから取り出した値を使う。

この2.をするのに情報がなかったです。
1.については公式ドキュメントがありますのでそちらを参考にしてください。

カスタムTwig拡張の書き方


さて本題ですがTwigExtentionをサービスコンテナに登録しましょう。
その際に

# src/Acme/DemoBundle/Resources/config/services.yml
services:
    acme.twig.acme_extension:
        class: Acme\DemoBundle\Twig\AcmeExtension
        tags:
            - { name: twig.extension }

    arguments:
            em: "@doctrine.orm.entity_manager"
            container: "@service_container"

とargumentsとしてEntityManagerとContainerを渡します。
次にTwigExtentionクラスのコンストラクタに
public function __construct($em, $container)
    {
        $this->em = $em;
        $this->container = $container;
    }
と記載します。
あとはControllerと同様に各メソッドからDoctrine2のmodelを呼び出すだけです。
実際にbase.html.twigの初期値にDBから取り出したデータを使いたいときはgetGlobals()をオーバーライドします。
public function getGlobals()
    {

        $var = $this->container
                ->get('my_domain.hoge_repository')
                ->getHoge();
        return [
            'hoge' => $hoge,
            'fuga' => 'fuga',
        ];
    }
と言った感じです。
base.html.twigの拡張すればかなりDRYにすることが出来るます。
ただしTwigExtentionでDBを呼び出すと毎回呼ばれます。
ですので出来るだけ回数を減らす必要があると思います。

Symfony2シリーズ続くかわかりませんが現場からは以上です。

2014年4月30日水曜日

第三回 中国地方DB勉強会を開いてきた

第二回から少し間が空きましたが第三回を開催しました。
今回もJPUG主催で行いましたがDBの種類関係なくハンズオンを行いました。
詳細は次のとおりです。

■中国地方DB勉強会のポータルサイト

GitHub上に作ってます。

中国地方DB勉強会

■第三回のコンテンツ内容

第三回中国地方DB勉強会申し込みサイト

■メーリングリスト

次回の告知についてはMLを使います。
興味がある方はチェックしてみてください。
講師の資料についてはポータルサイトのまとめに添付されています。

Googleグループ

dbstudychugoku@googlegroups.com

■動画とtwitterのまとめ

今回は諸事情によりありません。

■第三回のアンケート募集中

当日に参加やUst拝見された方は下記のアンケートに答えてくださると嬉しいです。
次回のコンテンツや今後の運営に活用させて頂きます。

アンケートはこちら
※匿名アンケートです


と以上のとおりです。

今回は久々に登壇しました。




資料としては非常にシンプルです。
実際の設定や詳細を知りたい人は

  「Linux HA PostgreSQL」

とかで検索すると幸せになれると思います。
Linux-HA Japan様が本当に詳しく情報提供してくれてます。
pgpool2については公式の日本語ドキュメントがあります。
また作者の石井さんには色々と助けていただきありがとうございました。

そして開催した感想ですが今回は初めてハンズオンに挑戦しました。
内容は会員向けファイルダウンローダーサイトのDB設計です。
すっごいざっくりとした仕様と僕が作ったWebのモックを元に皆さんに設計していただきました。
DB設計に慣れてる方が多く、結果は綺麗な正規化ばかりでした。
なのでマサカリの投げ合いになることはありませんでしたね(残念
その中でも印象に残ったのは

  • ファイルのバイナリをDBに保存するチームは居なかった
  • DBユーザをロールで複数作るチームも居なかった
  • ハンガリアン記法(m_userとか)も居なかった
ことですかね。
僕は例では3つともした(だってViewとか作る時にv_hogeとかしたいじゃん!)ので僕の実装例の時に集中マサカリを受けました(震え声。
そりゃ血塗れになったので覚えてるって話です(涙目
他にも

  • みんな外部制約キーを設定してた
  • DB固有の機能はほぼ使われてなかった
  • 極端な設計(IDリクワイアドとか)もなかった

といった感じでした。
これは参加者が純粋にレベルが高かったと言う印象です。
逆に言うとホントは来て欲しいDB初心者にはまだ参加のハードルが高いのかなとも思います。
初心者の参加については次の回の課題ですね。
またバリバリのRails使いが居たりすると結果は違ったかもしれません。

このハンズオンとは別に話題に上がったのは

  • column順番拘るか
  • updated_atやcreated_atは必要か
  • 削除の扱いについて
  • 外部制約かけるとER図をリバース・エンジニアリングする時に楽

というのがありました。
この変は実装の文化の違いなどもあるでしょうから他の人にも聞いてみたいところですね。

といった感じで非常に濃い内容の勉強会でした。
特にハンズオンをきっかけに色んな人の文化や考え方に触れられたのは勉強になりました。
意見交換自体は毎回やるようにしたいと思います。
個人的にはDDLの管理(DBマイグレーション?)はみんなどうしてるのか知りたいですね。


以上が第三回のことですが第四回は次のとおりに考えてます。

○第四回 中国地方DB勉強会 in 岡山

■開催概要
日時:2014年7月13日か21日(予定)
会場:岡山駅周辺を検討中
内容:PostgreSQLとMySQLの実行計画の使い方とチューニングについて

をやろうと思います。
講師については調整中なのでどこまで細かいところまでフォロー出来るかはわかりません。
ですが初心者の方こそ参加して欲しい内容になっております。
また勉強会の最後に意見交換の時間を用意します。
ここで日頃の疑問や困ってることをぶつけていただけたらと思います。

詳細が決まりましたら随時MLで告知していきます。
ご興味がある方はMLに参加をよろしくお願いします。
また申し込みサイトはDoorKeeperを利用予定です。
そちらのコミュニティも合わせてご活用ください。

といった感じで次は7月です。
久々の岡山ですが既に楽しみな内容にワクワクしてます!
また次回もどうぞよろしくお願いします。

2014年4月20日日曜日

ソニックガーデンのオフィスに突撃してみた

納品のない受託開発で有名なソニックガーデンに遊びに行ってきました。

ソニックガーデン


ソニックガーデンに行った目的はただ一つ、そう!倉貫さんに会うためです!!

倉貫さんのブログ


倉貫さんと言えばやっぱりアジャイル!!
そしてソニックガーデンと言えば冒頭でも触れた納品のない受託開発ですよね。
そこで聞いて感じたところをまとめてみました。

■納品のない受託開発についてそーだい的な考察

1. ターゲット

スタートアップみたいな変化の多いサービスを作りたい人に向いてます。
さらに言うとサービス作りたくて技術以外にフォーカスしてる人が合うと思います。
何故ならば技術の部分はソニックガーデンが全て請け負ってくれるからです。

だから「より良いサービス作り」に集中出来る←←←

これって非常に大切なことですよね。
逆に「業務系のような一回作ったら終わり」なシステムには向いてないと感じました。

2. 対象期間

これは「サービスが終わるまで」です。
最後まで付き合う=手抜きをせずちゃんと付き合うってことです。
なので対応するエンジニアのスキルは勿論のこと折衝力とかマーケティングとか技術以外の部分の負担も大きいですね。

3. 関わるエンジニアからみたメリット

これはホント色々あるのですが「自分の時間を作れる」ことが最大のメリットと思います。。
納期が無いので自分で作業時間をマネージメント出来ます。
なので上手くプロジェクトが回れば自分の時間が沢山作れます。
その時間で書籍を書くもよし、OSSに貢献するもよし、自分のサービスを作るもよし。
まるでGoogleの80%ルールみたいですよね。
でもこれってエンジニアのモチベーション維持には非常に大切です。
納品のない受託開発のビジネスモデルって長い目で見てるから社員の定着率も大事です。
そう考えるとモチベーション維持はとても大事なテーマだと思うのですがそれが綺麗に吸収されてると感じましたね。



ざっとですがこんな感じです。
話を聞けば聞くほど面白かったですね!
しかも自社サービスの話も伺いましたがこれがまた面白い!!
でもこれは企業秘密な所も多いと思うので興味がある方は直接聞いて見るのがいいと思います。
中国地方近隣ではオープンセミナー岡山に登壇されます。
セミナーや懇親会で是非アタックしてみてください!!

オープンセミナー岡山 申し込み

オープンセミナー岡山 懇親会申し込み


そしてエンジニアの人で納品のない受託開発に興味がある人はギルドと言う選択肢があります。
これは要はソニックガーデンのやり方を教えてもらいながら仕事を請け負う形です。
上記以外にもキャッシュ・フローが安定するなど色んなメリットがあります。
ただし一緒にやる仲間になる以上、ソニックガーデンの水準に達する必要があります。
その水準は低くなく、誰でも簡単になれるものではないなぁと感じました。
ただ今、その水準になっている必要はなく「将来的にそのレベルに達する見通しがある」ならチャンスだと思います。
興味がある方は下記のリンクを参考にしてみてください。

ソニックガーデンギルド


ということでソニックガーデン。
色々言われるIT業界のビジネスモデルにおいて非常に参考になる例の一つだと思いました。
また渋谷に行った際は是非ともお話を聞かせていただきたいですね!!

2014年4月19日土曜日

クレオフーガにお邪魔してきました

今、岡山のベンチャー企業でノリに乗ってるクレオフーガに遊びに行ってきました!

今、岡山のITベンチャーが熱い

クレオフーガは音楽コンテストコミュニティ クレオフーガを運営する会社です。
詳しくは最近リプレースしたコーポレートサイトを見てください。




クレオフーガは東京と岡山にオフィスがあるのですが今回は東京にお邪魔してきました。
その目的はこの人、西尾さんに会うためです!!
僕の個人的な友人であるハーレムさんや真央ちゃんがいる会社なので「非常に楽しそうな会社だなぁ」って印象だったのですが「じゃあトップはどう考えてるのよ?」ってのが今回お会いしようと思ったきっかけ。
で実際にあってどうだったかと言うと
  • 社員がベストパフォーマンスを出せるように色んな配慮をしてる
  • 自社サービスを育てることに対して非常に論理的
  • 音楽に対する想いがアツい

特に自社サービスの話は聞いててためになりましたね。
ドックフーディングも「自分が音楽大好き!」って視点なので本当にサービスに対する目線がユーザ目線なんですよね。
また楽曲を提供してるユーザとご飯を食べに行ったり、ボタンの配置一つも試行錯誤してて

売れるサービスには売れる理由がある


って当たり前のことを凄く感じましたね。
ただ今後の課題としてはマーケティングとデータアナリストが不足してるみたいです。
そういうのが得意で音楽が大好きな人はクレオフーガの門を叩いてみるといいかもしれません。


そしてそんなクレオフーガさんが協賛してるイベントが来月あります。

オープンセミナー岡山


去年は西尾さんが登壇してました。
今年はクレオフーガのメンバーである逸見さんが実行委員長です。
興味がある人はイベントや懇親会に顔を出してみるのもいいんじゃないでしょうか。

ということでクレオフーガ、勢いに納得の内容でした!!

2014年2月3日月曜日

オープンセミナー2014@広島に行ってきた

年に一回の広島のビックイベントに参加してきました。

■当日のTwitterのまとめ
#osh2014のまとめ

■オープンセミナー2014@広島の公式サイト
オープンセミナー広島のサイト

■テーマ
「TDD…そして Be Agile」

今年も参加してきました。
去年は実行委員長として開催側でしたが今年は副委員長として一歩後ろから応援してました。
また久々にオープンセミナーで登壇してお話させていただきました。
当日の発表資料はこちらです。




資料の中で紹介したリンク先

AWSのPostgreSQL(RDS)を使えるようになるまでの手順

Webアプリケーションを作るときに知ってると嬉しいPostgreSQLの使い方

1 発表者として

アジャイル、TDDをテーマにしてる中で自分だけ全く違う内容でした。
また事前アンケートでは自分のセッションが参加理由の人はいませんでした。
なので今回の内容としてはDBのことを知らない人向けです。
DB大好きな人からするとあんまり魅力を感じない内容かと思います。
ですが全くニーズが無い場所こそ、DB(データの大切さ)を伝える必要があると考えています。
何故ならばデスマの技術的なボトルネックはコードではなくDBが一番多いと思ってるからです。
「私はDB担当じゃないから」とか「DBってストレージの代わりでしょ?」って人にこそ RDS for PostgreSQL ですぐ始めれるのでチャレンジしてほしいなと思います。

とそんな考えで登壇させていただきました。
ただ聴衆の皆様にどれだけ内容が伝わったかわかりません。
また登壇のやり方も正しかったかわかりません。
というわけで聴衆の方はぜひぜひフィードバックをよろしくお願いします。
厳しいお言葉こそ次の課題だと思います。
小さなことでもご意見ご感想をいただけたらと思います。

オープンセミナー広島のアンケート


2 運営スタッフとして

今年は火村さんが実行委員長でした。
その火村さんから副実行委員長として指名されて補佐を務めさせていただきました。
結論からいうと火村さんが素晴らしい活躍を見せ、僕の仕事はほとんどなかったと思います。
また彼はこの一年、沢山のアウトプットと人柄で多くのエンジニアから愛される存在になりました。
これは僕が去年、彼を実行委員長に指名した際の

「ひむひむはもっと評価されるべき」

という狙いを予想を遥かに上回る結果で達成したかなと思っています。
イベントとしてもこれだけの人を集め、問題もなく終えたのは大切な実績になったと思います。
本当に良いイベントだったなぁと贔屓目無しで感じる一日でした。
もう総括すると #ひむひむマジひむひむ コレに集約されるかなと思います。


3 参加者として

本当に含蓄のあるセッションばかりで非常に充実したものでした。
どのセッションも面白く、珍しくセミナー中にコーディングする暇がないくらい聞き入ってました。
その中でも特に自分の心に響いたのは長沢さんのセッション。
大切だなっと感じたこと列挙すると













そして他の人のツイートを拝借すると






ざっくり自分なりにまとめます。


  1. 継続的に成長できる会社文化がないと売上は伸びない
  2. でもそれって会社の人材の能力と文化に依存する
  3. だからこそ高いモチベを維持できる環境と能力を発揮できる環境が必要
  4. そのために政治力を含めて自分になにができるか?

つまりは



ですよね。
と以上を踏まえた上で自分が会社で


  • 出来てること
  • 出来る事
  • やりたいこと


を振り返ってより良い環境つくりを提案・実践していかなきゃと感じました。



と言う感じで非常に有意義な一日でした。
また懇親会ではLTも盛り上がり、Shake Handsさんの魅力と相乗効果で楽しかったです。
やっぱり懇親会での交流は大切ですね。


ということで何度も言いますが最高の一日でした。
来年がどんなイベントになるか今から楽しみですし絶対参加します。
このblogを読まれてる皆様、来年も(は?)会場で会いましょう!!!


※和田さんがオススメしてる本でAmazonで手に入るオススメ本