2012/04/17

Ubuntu Server 10.04 に iptables の設定を行う

さくら VPS の Ubuntu Server 10.04 では、iptables の初期設定はオールスルーになっている。
$ sudo iptables -L
Chain INPUT (policy ACCEPT) target prot opt source destination Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination
これはさすがにアレなので、設定しましょう。
# 設定の永続化に使用する iptables-persistent をインストール
$ sudo aptitude install iptables-persistent

# iptables 用ディレクトリの作成
$ sudo mkdir /etc/iptables

# 設定スクリプトを作成(内容は後述)
$ sudo vi /etc/iptables/iptables.sh

# 設定スクリプトの実行
$ sudo sh /etc/iptables/iptables.sh

# 正しく設定されているかを確認
$ sudo iptables -L
Chain INPUT (policy DROP) target prot opt source destination ACCEPT all -- anywhere anywhere DROP all -- 10.0.0.0/8 anywhere DROP all -- 172.16.0.0/12 anywhere DROP all -- 192.168.0.0/16 anywhere ACCEPT icmp -- anywhere anywhere icmp echo-request ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED ACCEPT tcp -- anywhere anywhere tcp dpt:www ACCEPT tcp -- anywhere anywhere tcp dpt:https ACCEPT tcp -- anywhere anywhere tcp dpt:ssh LOG all -- anywhere anywhere limit: avg 1/sec burst 5 LOG level warning prefix '[IPTABLES INPUT] : ' DROP all -- anywhere anywhere Chain FORWARD (policy DROP) target prot opt source destination LOG all -- anywhere anywhere limit: avg 1/sec burst 5 LOG level warning prefix '[IPTABLES FORWARD] : ' DROP all -- anywhere anywhere Chain OUTPUT (policy ACCEPT) target prot opt source destination ACCEPT all -- anywhere anywhere
# iptables.rule が作成されているかを確認 $ ls /etc/iptables
iptables.rule iptables.sh
# 現在の設定を永続化する $ sudo service iptables-persistent start
iptables.sh の中身はこんな感じ
#!/bin/sh

# テーブル初期化
/sbin/iptables -F
# 定義チェインを削除
/sbin/iptables -X

# デフォルトルールの設定(受信:破棄, 送信:許可, 通過:破棄)
/sbin/iptables -P INPUT DROP
/sbin/iptables -P OUTPUT ACCEPT
/sbin/iptables -P FORWARD DROP

# 自ホストからのアクセスを許可
/sbin/iptables -A INPUT -i lo -j ACCEPT
/sbin/iptables -A OUTPUT -o lo -j ACCEPT

# プライベートIPアドレスからのアクセスを破棄
/sbin/iptables -A INPUT -s 10.0.0.0/8 -j DROP
/sbin/iptables -A INPUT -s 172.16.0.0/12 -j DROP
/sbin/iptables -A INPUT -s 192.168.0.0/16 -j DROP

# ping を許可
/sbin/iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT

# 内部から行ったアクセスに対する外部からの返答アクセスを許可
/sbin/iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# 拒否IPからのアクセスを破棄
# 拒否IPは /etc/iptables/drop_ip に1行ごとに記述する
if [ -s /etc/iptables/drop_ip ]; then
    for ip in `cat /etc/iptables/drop_ip`
    do 
        /sbin/iptables -I INPUT -s $ip -j DROP
    done
fi

# 各サービスで使用するポートを許可
# HTTP
/sbin/iptables -A INPUT -p tcp --dport 80 -j ACCEPT
# HTTPS
/sbin/iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# ssh
/sbin/iptables -A INPUT -p tcp --dport 12345 -j ACCEPT

# 上記のルールにマッチしなかったアクセスはログを記録して破棄
/sbin/iptables -A INPUT -m limit --limit 1/s -j LOG --log-prefix '[IPTABLES INPUT] : '
/sbin/iptables -A INPUT -j DROP
/sbin/iptables -A FORWARD -m limit --limit 1/s -j LOG --log-prefix '[IPTABLES FORWARD] : '
/sbin/iptables -A FORWARD -j DROP

# 保存
/sbin/iptables-save > /etc/iptables/iptables.rule

さくら VPS (Ubuntu Server 10.04)設定エントリ一覧

2012/04/16

お名前.comの独自ドメインをさくらVPSに割り当てる

せっかく VPS を契約したのだから独自ドメインで運用したい。
というわけで、お名前.comで取得した独自ドメインにさくらVPSを割り当てましょう。
  • お名前.comにログイン
  • ドメイン設定 → ネームサーバーの設定 → レンタル DNS レコード設定
  • 設定するドメインを選択
  • サブドメイン無しで、TYPE: A、VALUE: さくら VPS の IP アドレスを登録
  • サブドメイン www に対して、TYPE: A、VALUE: さくら VPS の IP アドレスを登録
  • ポチポチ進めれば完了
  • しばらくして、登録されていることを確認する
ここまでで、ドメイン側の設定は終わり。
次は、サーバ側を変更する。
まずは、さくらのVPSホームでホスト名を変更する。
ssh でログインし、 /etc/hostname と /etc/hosts の該当箇所を変更する。
サーバを再起動すれば設定完了。お疲れ様でした。

Ubuntu Server 10.04 の ssh ポートを変更する

前回 ssh を鍵形式ログインに変更したけど、念の為ポートも変更しましょう。
# クライアントから ssh でログイン
% ssh user@[server]

# サーバーの sshd_config を編集
$ sudo vi /etc/ssh/sshd_config
- Port 22 + Port 12345
# /etc/services も変更しておく $ sudo vi /etc/services
- ssh 22/tcp # SSH Remote Login Protocol - ssh 22/udp + ssh 12345/tcp # SSH Remote Login Protocol + ssh 12345/udp
# サービス再起動 $ sudo service ssh restart
ssh start/running, process 6331
# 一旦接続を閉じる $ exit
logout Connection to [server] closed.
# 再度ログイン % ssh user@[server]
ssh: connect to host [server] port 22: Connection refused
ポート 22 でログインできなくなりました。
ログインするにはポートを指定すればOK。
% ssh user@[server] -p 12345

2012/04/13

Ubuntu Server 10.04 に SSH を設定する

まずは、パスワードで SSH ログイン。
最初から ssh は入っているようなので、設定ファイルを書き換える。
# vim 入ってなかった
$ sudo vi /etc/ssh/sshd_config
# root でのログインを不可 - PermitRootLogin yes + PermitRootLogin no
まだカギを生成指定なので、とりあえず root でのログインだけ封じておく。
サービスを再起動
$ sudo service ssh restart
ssh start/running, process 1043
パスワードでログインだと不安なので、鍵を使ったログインにしましょう。
クライアントの Ubuntu で鍵を生成。
% ssh-keygen -t rsa
Generating public/private rsa key pair. Enter file in which to save the key (/home/user/.ssh/id_rsa): # 何も入力せず Enter Enter passphrase (empty for no passphrase): # SSH用パスワードの入力 Enter same passphrase again: # パスワード確認のためもう一度入力 Your identification has been saved in /home/user/.ssh/id_rsa. Your public key has been saved in /home/user/.ssh/id_rsa.pub. The key fingerprint is: XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX user@host
これで $HOME/.ssh/ 以下に id_rsa, id_rsa.pub が作成された。
% ls -al ~/.ssh
合計 20 drwx------ 2 user user 4096 2012-04-13 07:14 . drwxr-xr-x 57 user user 4096 2012-04-13 07:19 .. -rw------- 1 user user 1743 2012-04-13 07:14 id_rsa -rw-r--r-- 1 user user 398 2012-04-13 07:14 id_rsa.pub -rw-r--r-- 1 user user 442 2012-04-13 06:46 known_hosts
id_rsa が秘密鍵で、id_rsa.pub が公開鍵なので id_rsa.pub を接続したい先のサーバに登録してやる。
% scp .ssh/id_rsa.pub サーバのIPアドレス:~/
id_rsa.pub 100% 398 0.4KB/s 00:00
次はサーバ側でこの鍵を登録する。
# なかったので作成
$ mkdir .ssh
# 登録。最初だから > でもいいけど、今後のことを考えて >> でやるようにしとく
$ cat id_rsa.pub >> .ssh/authorized_keys
これで今後、このクライアントからのアクセスは鍵方式での認証になる。

2012/04/12

さくらのVPS 2G に Ubuntu Server 10.04 をインストール

先日さくらのVPS 2G を契約した。
契約時点で Cent OS が自動的にインストールされているので、これを Ubuntu Server に変更しましょう。
コントロールパネルでOS再インストールを選択。
カスタムOSインストールへ。
OSを選択
実行をクリックすると QEMU が立ち上がる。
Java が実行できる必要があるので、インストールされていて、ブラウザで実行できる必要がある。
キーボードを選択。
OSの言語選択は出て来なかった。
キーボードのレイアウトを選択。
ブラウザ上に表示されているIPアドレスを入力。
ネットマスクを入力。
デフォルトとは違うこともあるので注意。
ゲートウェイを登録
パーティションの種類を選択。
ディスクを選択。
パーティションを確認される。
インストール開始。
管理者ユーザーの名前を入力。
めんどくさかったら、後で登録する管理ユーザーと同じでいい。
管理者ユーザーを登録。
管理者ユーザーのパスワードを登録。
確認のためパスワードをもっかい入力。
ホームディレクトリを暗号化するかどうか選択。
残りのインストールが行われる。
インストール完了。お疲れ様でした。
各選択肢でどれを選ぶかは用途にあわせてご自由に。
言われるままに進めるだけなので非常に簡単です。
さて、これから少しづつ環境を作っていこう。

2012/02/07

PostgreSQL の interval (と reltime)

PostgreSQL にて n ヶ月後の初日や最終日を文字列で返す関数を登録しようとした。
イメージとしてはこんな感じ。
create or replace function first_date_string_on_month(integer)
returns varchar
as 
$BODY$select to_char(date_trunc('month', current_date + interval '$1 months'), 'YYYY/MM/DD')$BODY$
language 'sql';
だがこれだとうまくいかなくて、引数に何を与えても 2012/03/01 が返ってくる。
'$1 months' が '1 months' とみなされている気がする。

で、次にやってみたのがこんな感じ。
create or replace function first_date_string_on_month(integer)
returns varchar
as 
$BODY$select to_char(date_trunc('month', current_date + interval ($1 || ' months')), 'YYYY/MM/DD')$BODY$
language 'sql';
構文エラーで登録すらできない。

interval だとだめなのかなと思って、interval のいらない current_timestamp で挑戦してみる。
create or replace function first_date_string_on_month(integer)
returns varchar
as 
$BODY$select to_char(date_trunc('month', current_timestamp + ($1 || ' months')), 'YYYY/MM/DD')$BODY$
language 'sql';
「ERROR: 演算子が存在しません: date + text」と言われる。

なるほど text だからキャストが必要なのかと言うことで varchar にキャストしてみる。
create or replace function first_date_string_on_month(integer)
returns varchar
as 
$BODY$select to_char(date_trunc('month', current_timestamp + cast($1 || ' months' as varchar)), 'YYYY/MM/DD')$BODY$
language 'sql';
これまた演算子が存在しないと言われる。

そういや、そもそも interval ってなんなんだ
と思って調べてみるとどうやらデータ型らしい。
interval '1 months' みたいに書くから識別子とかかと思ってたらデータ型でキャストというか型変換を意味していたのか!
というわけでこうしてみた。
create or replace function first_date_string_on_month(integer)
returns varchar
as 
$BODY$select to_char(date_trunc('month', current_timestamp + cast($1 || ' months' as interval)), 'YYYY/MM/DD')$BODY$
language 'sql';
登録できたよ。
select first_date_string_on_month(3)
--  → 2012/05/01
select first_date_string_on_month(-2)
--  → 2011/12/01
select first_date_string_on_month(0)
--  → 2012/02/01
ちゃんと動いてるよ。

ちなみに reltime というデータ型もあるみたい。
create or replace function first_date_string_on_month(integer)
returns varchar
as 
$BODY$select to_char(date_trunc('month', current_timestamp + cast($1 || ' months' as reltime)), 'YYYY/MM/DD')$BODY$
language 'sql';
とすると登録できて同じ結果が取得できた。
reltime型 を引数に取る interval 関数というのがあるので、それが関係していると思われるがよくわからない。
Google 先生で調べても PostgreSQL と realtime の検索結果が表示されるし。
とりあえず interval を使うのが正当だと思うのでそれでいいや。

2011/12/24

Nokogiri 使ったので軽くメモ

Nokogiri を使って HTML のソース解析を簡単にやってみたのでメモ。 まずはインストール。
# これがないと Nokogiri インストール時にエラーになる
$ sudo aptitude install libxml2-dev libxslt1-dev
# Nokogiri をインストール
$ sudo gem install nokogiri
そして、使い方。
require 'rubygems'
require 'open-uri'
require 'nokogiri'

# この open メソッドのために open-uri を require する
html = Nokogiri::HTML(open(url))
# XPath で指定する(css セレクタよりも個人的には XPath の方が好み。)
options = html.search("//div[@id='summary']/select[@class='prefectures']/option")
# 対応する要素がない場合、空が帰ってくる
if options.length.zero?
  puts "データがありません"
else
  options.each do |option|
    # 属性値の取得とテキストの取得
    puts "#{option.attribute('value')} : #{option.text}"
  end
end
DOM がわかってれば簡単だ。 Nokogiri の使い方についてはコチラが簡潔わかりやすいと思う。

2011/08/04

Object#try マジ便利

Rails 2.3 から導入された Object#try これ便利ですね。
とあるオブジェクト obj があって attr という属性を持っている場合、obj.try(:attr) とすると、obj が nil でもエラーがでないと。
# これが
value = obj ? obj.attr : nil

# こんな風にかける
value = obj.try(:attr)

# ほかにもこんなのが
if obj && obj.attr_1 && obj.attr_1.attr_2
  value = obj.attr_1.attr_2.attr3
end

# こうかける
if obj.try(:attr_1).try(:attr_2)
  value = obj.attr_1.attr_2.attr_3
end
nil かどうかを意識しなくてすむというのは非常に大きい。

2011/07/25

Android にモバイル Suica がやってきたよ

7/23 に Android 対応モバイル Suica サービスが開始されたと言うことでさっそくインストールした。
普通にマーケットからするするっとインストール。
寝かせておいた W53CA に SIM を移して、久々に立ち上げて機種変更の手続き。
また IS03 に SIM を入れ替えて移行の手続き。
ちょっとめんどくさかったけど、トラブルなく移行できた。
残ってた 1500 ほどのポイントも生き返った。
後は今使用中のカードタイプの定期券をモバイル Suica に移せるといいんだけど、できるんだっけ?

[2011-07-28_追記]
コールセンターに問い合わせてみたら、機種変更にて引き継いだ場合、別カードの定期情報は取り込めないらしい。
がっかり

2011/06/16

すべての submit に disable_with を

submit ボタンをダブルクリックとかされて、二重登録されてしまうことありますね。
その対策として、クライアント側でお手軽なのが、submit ボタンを押された瞬間に disabled にしてやるというのがあります。
サーバ側でのチェックをするには token を組み込むだのありますが、今回はクライアント側 JavaScript のお話のみということで。

Rails だと非常に簡単にこの機能を提供していて、f.submit :disable_with => '処理中' みたいな感じでできます。
submit_tag でも同様です。(f.submit は submit_tag を呼び出してるし)
ところが、全てのフォームにおいてこれを仕込んでいくのは非常にめんどくさい。
どうせなら一度の設定でアプリケーション全体に適応させましょう。
やってみると意外と簡単で、$RAILS_ROOT/config/initializers の下にこんなコードのファイルを配置するだけ。
module ActionView
  module Helpers
    module FormTagHelper
      alias_method :original_submit_tag, :submit_tag
      def submit_tag(value=nil, options={})
        options[:disable_with] = '処理中...' unless options[:disable_with]
        original_submit_tag(value, options)
      end
    end
  end
end

これで全ての submit は二度押し禁止になりました。
しかし、submit でダウンロードさせた場合、レスポンスがファイルにいってしまうので disabled のまま画面は止まってしまいます。
そんなときは、f.submit :disabl_with => '' のように空文字を渡すだけで大丈夫。