読者です 読者をやめる 読者になる 読者になる

cronの使いどころと注意点について

指定日時にジョブの自動実行を行うジョブスケジューラことcron
バッチ処理などの定期実行で主に用いているがベストプラクティスがわからずおそるおそる使っていたためまとめる。

使いどころ
・アプリケーションのジョブの実行
・システムに関わるジョブの実行
・監視用途

crontabの設定

cronの設定にはcrontab形式と呼ばれるテキストファイルが用いられ、その編集にcrontabコマンドを使います。
crontabはユーザごとに設定されcrontabコマンドで編集したcronコマンドは/var/spool/cron/[user name]に保存されます。

一般的な設定方法

crontab -eを討つと編集画面が立ち上がりますがcrontab -rをミスタイプしてしまうと全消去してしまう恐れがあります。
そのため、crontab とファイル指定を行うことができるのでその方法で編集するのが望ましいでしょう。
なお実行結果は/var/log/cronに記録されていきます。

crontabの注意点

実行ディレクトリの問題

各cronのジョブが実行される際のカレントディレクトリは、ユーザのホームディレクトリになります。
そのため、実行コマンドの指定は絶対パスを使ったり、事前に実行ディレクトリにcdする必要があります。

環境変数

cronの各ジョブ実行時には、環境変数は最低限しかセットされていません。
特に$PATHに/usr/bin:/binしか指定されていないため、セットしたはずのコマンドにパスが通っておらず、コマンドが実行できないというミスがありがちです。

毎分指定

毎朝5時ちょうどにバックアップをしたい場合を例にあげると
うっかりこういった設定ミスをしてしまう。(過去に自分もした)

意図した正しい設定

  0 5 - * * /path/to/backup.sh

間違えた設定

 * 5 * * * //path/to/backup.sh
%のエスケープ

crontabの指定において%は改行を意味するメタ文字です。
もし%を記述したい場合はエスケープ文字を入れる必要があります
例:%→\%

0分ちょうど指定を避ける

1時間毎に行う定期処理については毎時0分に設定してしまいたくなるが
ちょうどの時間は他のジョブが設定されがちなので0分になると急にサーバの負荷が上がる危険性があるため避けるべきです。
特にクローラを動かしたり、外部APIへの問い合わせを行うような処理を行う場合は
先方の負荷を考え0分指定にしないようにしたほうがいいようです。

参考文献
新しいLinuxの教科書

asset pipelineについて

railsチュートリアル1周目ではまずチュートリアル通りに手を動かすことを
意識してやったけどハマったり理解できていなかったところがあるため
再度意味を理解しながら2周目を始めた。
スキマ時間とはいえ1周目よりは早く終わらせたい(前回3ヶ月かかった)

今回はasset pipelineについて
以下の順で実行しているようなのでまとめた。

まずは各単語の意味からおさらい

Asset
有用なもの・貴重なものの意
ここではRailsではJavaScriptCSS、画像ファイル、ERBなど
Webアプリケーションを構成する部品を指す。

Pipeline
ルート、補給線の意
Railsでは、効率的な方法を提供するための一連の作業

参考記事から引用

アセットパイプラインとは、JavaScriptCSSのアセットを最小化 (minify: スペースや改行を詰めるなど) または圧縮して連結するためのフレームワーク

1コンパイル

従来のCSSJavaScriptでは記述が難しく、効率が悪いことから
Sass、CofeeScriptなどの高級言語を使用。
これら高級言語はネイティブ言語への変換が必要

変更前→変更後
common.css.sass→common.css
foovar.js.erb.coffee → foobar.js.erb → foobar.js

2統合

1つのファイルにまとめて、通信回数を減らす。
<link>タグの通信コストが大きいため記述回数を減らす

統合前

    link href="common.css" rel="stylesheet" type="texxt/css"
    link href="foobar.css" rel="stylesheet" type="texxt/css"

統合後

    link href="application.css" rel="stylesheet" type="texxt/css"
3圧縮

改行、空行、コメントを取り除いてサイズを縮小する
書くほどでもないですが、いわゆるファイルサイズの縮小です。

4ダイジェスト付与

1度レンダリングされたCSSJavaScriptはブラウザでキャッシュされる。
Asset修正後は表示を反映させるためにファイル名にダイジェストを付与している(おそらく一意な配列)
業務でも以前即時性が求められるページにてPHPでもランダムな文字列を
GETパラメータに付けてリロードするといった処理を実装したりしたのでそれと似たようなものなのかなという印象

参考記事
https://railsguides.jp/asset_pipeline.html


次回は多分cronをやる予定

ディレクトリトラバーサル対策について

PHPでファイル操作周りを扱う際に
忘れがちだったので徳丸先生の本をもとに思い出すついでのメモ

概要

外部からパラメータでサーバ上のファイル名を指定できるWebアプリケーションでは、
ファイル名に対するチェックが不十分であるとアプリケーションの意図しないファイルに対して閲覧や改ざん、削除ができる場合がある。
これをディレクトリ・トラバーサル脆弱性と呼ぶ。

脆弱性が生まれる原因と対策

外部からファイル名を指定できる仕様を避ける

ファイル名を固定にする、もしくはファイル名を間接的に番号で指定する

ファイル名にディレクトリを含まれないようにする

ファイル名にディレクトリ名が含まれないようにすれば、アプリケーションの想定したディレクトリのみにアクセスすることになりディレクトリ・トラバーサル脆弱性が解消する。
ディレクトリを示す記号文字は「/」、「\」、「:」などOSで異なる。
そのため、OSによる違いを吸収できるライブラリを使用するべきである。PHPの場合はbasename()を使用する。
サンプルコード

<?php
 define('TMPLDIR','/var/www/tmpl/');
 $tmpl = $_GET['template'];
 if(!pregmatch('/\A[a-z0-9]+\z/ui',$tmpl)){
 die('template')
 }
?>
<body>
<?php readfile(TMPLDIR.$tmpl.'.html'); ?>
</body>
ファイル名を英数字に限定する(記号を許可しない)

ファイル名を英数字のみを通す正規表現に限定することが効果的な対策と言える

まとめ

ファイル名を外部から指定しない

Nokogiri使ってスクレイピング

Railsチュートリアルが終わったので
Rubyの基本文法をcode academyとかで写経しながら以前スクレイピングしてみたが、open-uriのcharsetの取得の仕方で躓いた。

対象ページの文字コードUTF-8で期待値が”UTF-8”にもかかわらず、
open(uri).charsetで取得できる文字コード
"iso-889-1"になるため文字化けして出力されてしまう場合があるということが判明した。

YahooのTOPページなどは問題な”UTF-8”で取得できるのだが
一部ページではiso-8859-1といった具合。

ソースコードは以下(scrape_title.rb)

#URLにアクセスするためのライブラリの読み込み
require 'open-uri'
#Nokogiriライブラリの読み込み
require 'nokogiri'
#スクレイピング先のURL
uri = 'http://tenjin.keizai.biz/headline/archives/'
charset = nil

html = open(uri) do |f|
         charset = f.charset #文字種別を取得
                if charset == "iso-8859-1"
                        charset = "UTF-8"
                end
        html =  f.read #htmlを読み込んで変数htmlに渡す
end
#htmlをパースしてオブジェクトを生成
parse_doc = Nokogiri::HTML.parse(html,nil,charset)

parse_doc.xpath('//div[@class="item"]').each do |node|
#記事タイトルを表示
p node.css('span').inner_text

end

open-uriライブラリのマニュアルに以下のように書いてあった。

URI のスキームが HTTP であり、自身のタイプが text である場合は、 [RFC2616] 3.7.1 で定められているとおり、文字列 "iso-8859-1" を返します。

https://docs.ruby-lang.org/ja/latest/class/OpenURI=3a=3aMeta.html

実行すると取得はできた
f:id:sunecosuri_san:20170130125500p:plain


一旦、”iso-8859-1”だったらUTF-8に指定というような記述をしているが絶対にスマートではない
もう少しスマートな方法があるはず、、

参考ブログ
inobo52.hatenablog.com

情けないことにApacheのhttpdでドハマりした

CGIの実行設定が必要なのにhttpd .confばかりを眺めて実行なんでできないんだとうんうん唸って数時間無駄にした日だったのでメモ。

端的にいうと/usr/local/apache2/conf.d/配下のファイルを編集する際は注意って話です。

httpd.confにデフォルトで以下の記述がある。

Include conf.d/*.conf


そのため、conf.d配下にあるxxxxx.confというファイルはすべて読み込まれてしまう。 
Optionsやディレクティブを指定するときなどはconf.dの内容も確認した上で編集しないと
同じ内容のファイルを二重に読み込んだりするとエラーになってしまう。

そのような事態の解決方法は以下の2つ 
1.Include conf.dのアスタリスク指定をやめて必要なファイル名のみ直書きで指定

2.conf.dディレクトリ配下のファイル名には気をつける。
バックアップファイルなら専用のディレクトリを作成したほうが吉。

1番のやりかたのが確実で心理的に安心感はある気がする。
しかし、自分ではない誰かが触るとき抵抗が生まれるかもしれない。
そういった場合は2番しかない。
Apacheの設定関連のドキュメント読み漁ってたらLDAP関連はもちろん
認証まわりとか全然把握できてないものばかり見受けられたので空いた時間に
どういうことができるのか目を通しておきたい。

ローカルでサクッとphpmyadmin込のLAMP環境

phpmyadmin込のLAMP環境を気軽に作りたいなと思ったので勉強のためdocker-composeで作ってみた。

【前提条件】

docker-composeとdockerが使えることが前提になるので
各コマンドがconsoleから使えない場合はDocker for macもしくはDocker for WindowsをインストールすればOK。
■公式が提供しているインストール方法はこちら

【手順】

1.リポジトリをclone

$ git clone https://github.com/sunecosuri/lamp-docker.git

2.ディレクトリを移動

$ cd lamp-docker

3.PHPのバージョン設定
以下のURLに記載されているタグを基に使用したいphpのバージョンを指定する。
(リポジトリのソースの初期設定は7.1.0)

docker-hubで提供しているコンテナ一覧
※公式のリポジトリ以外で提供しているコンテナ以外は検証できていないため動作の保障ができかねます。

例)7.1.0→5.6に変更したい場合
「FROM php:7.1.0-apache」→「FROM php:5-apache

4.phpの設定
/php/php.iniを適宜編集する。
今回はこのまま実行するので割愛します。

5.mysqlの設定
/mysql/my.cnfを適宜編集する。
今回はこのまま実行するので割愛します。

6.ポートフォワーディングの設定
docker-compose.override.ymlを編集する
ホスト:コンテナとなっているので適宜編集する。

mysql:
  ports:
    - "3300:3306"
php:
  ports:
    - "80:80"
phpmyadmin:
  ports:
    - "8080:80"

7.ビルドして立ち上げる

$ docker-compose up -d

8.Webサーバの接続確認
『http://{ホストのIPアドレス}』にアクセスして
phpinfoが表示されればOK。
f:id:sunecosuri_san:20170123133808p:plain

9.phpmyadminの接続確認
『http://{ホストのIPアドレス}:8080』にアクセスして
phpmyadminが表示されればOK。
f:id:sunecosuri_san:20170123133827p:plain
補足
コンテナを停止させたいとき

$ docker-compose stop

まとめ

以下の3つのコマンドで環境が作れます。
1.$ git clone https://github.com/sunecosuri/lamp-docker.git
2.$ cd lamp-docker
3.$ docker-compose up -d

終了したいときは以下のコマンドで終了できます。

$ cd lamp-docker
$ docker-compose stop

上記のDocker環境はGitHubにも公開してみた。
https://github.com/sunecosuri/lamp-docker

各設定ファイルについてはdockerイメージを削除してリビルドかけると反映します。
今後はバージョン切り替えも込みでXAMPPとかMAMPよりカジュアルに使えるようにしていければなという気持ちです。

2016年の振り返りと2017年の抱負

2016年の振り返り

・教育していただいた先輩の退職

2016年の1/3は教育してもらった先輩が4月で退職するため
業務の引き継ぎで精神的にいっぱいいっぱいな期間だった。

先輩が退職後、コードを書くのはほぼ自分一人だけになりこのままではまずいとかなり焦りだし、
4月を過ぎた頃には「コードを書く」という意味でのソフトウェアエンジニアリングに業務で携わる時間があまりなくて悶々としていた。
現在のライブラリを流用、改修していく作業の繰り返しを行うにつれて
「コードを書きたい!」という欲求が非常に強かった。

とはいっても、まったくコードを書く仕事をしていないわけではなくて、
仕事では会社で秘伝のタレ化しているオレオレライブラリやFWなど各案件に潜む、
いわゆるイケてないと感じた技術的負債の返済(リファクタ)、業務フローの効率化の提案などをした。
業務フローの効率化の提案については長くなりそうなので割愛。。

・技術について話せる相手もいないため勉強会に顔を出すようになる

同僚も先輩のエンジニアもいないため、外部の人の技術動向と刺激を受けたくて勉強会に足を運び始めるようになる。
PHPカンファレンス福岡とfukuoka.phpあとはペパボ・はてなインフラ技術基盤技術大会、OSC福岡などに参加して
Docker、RoRとCentOS7を触り始める。RoRチュートリアルをざっくり1周しただけだがうまくいかないところはざっとそのままに一旦飛ばしてしまっていた。
Docker、CentOS7については勉強用にVPS借りてWebサーバを0から構築したり
docker-composeを用いて3コマンドでLAMP環境を構築するリポジトリなどを公開し、そのネタでQiitaのDockerアドカレに投稿などもできた。
10月からは休日にWEB+DBPressのweb開発新人研修やRailsTutorialをやるなどをした。

2017年の抱負

PHP the right wayの振り返りをしながらPHP7でのコード力を上げる
 →PHPのFWで一つアプリケーションを作成する
   LaravelかLumenにしようかと思います。

***いつかやりたいやつ

退職した先輩がGentooSlackwareを勧められたけどわからないなりにやってみたい。

・他の言語の習得

 →RoRチュートリアルを通してRoRの基本を理解
   簡単なWEBアプリでもいいから作る

・愚痴っぽくなりかけたら「その課題を解決するには、」と一度深呼吸する

 →これについては言葉通りなのだが誰かのブログに書いてあった

本当にそれがやりたいのであれば、自分でそれができる環境をつくるためのアクションを積極的に起こしてほしい。

を意識して行動していきたい。

・手を動かしていきたい

 →言わずもがなですが圧倒的にコード力も知識も足りないと感じているので気になっているのはまず手を動かしてから考えていきたいと思います。
引き続き学習は続けていくし、エンジニアとしてもっと成長したいので
インプットとアウトプットのサイクルをどんどん回して習慣づけていきたいと思います。