iptables 基礎

ufw 等に逃げてたのでそろそろ基礎的な部分を調べました。

基本的な構文

iptables スイッチ チェーン オプション -j アクション

大まかにですが、こんな感じかと思います。
※オプション、アクション等は私が勝手につけただけです。

チェーン

チェーンは、どこからの通信なのかを指定できます。受信するパケットに適用したり、送信するパケットに適用したりできます。
初めから定義されているチェーンは3つあります。

INPUT 受信するパケットに対して指定の指定です。
OUTPUT 送信するパケットに対して指定の指定です。
FORWARD これは転送を行うパケットに対しての指定です。これは設定するPCをルーターとして利用する場合に利用します。

アクション

アクションは、パケットを許可するのか、破棄するのかを指定します。
許可するには ACCEPT。破棄するには DROP を指定します。

スイッチ

チェーンの前にあるスイッチは、チェーンに追加したり、チェーンに指定がない場合のデフォルトの設定などができます。

-P : 初期設定

iptables -P チェーン アクション

パケットの指定がされていないパケットに対しての、デフォルトの設定を行います。

例えば受信するパケットをデフォルトで破棄するには次のようになります。

iptables -P INPUT DROP

-A : 追加

iptables -A チェーン オプション -j アクション

チェーンに対して新たなルールを追加します。
オプションに当てはまるチェーンのパケットを、アクションで処理する。
のような感じになります。

オプション
オプションは、プロトコル・ポート番号・モジュールを指定することができます。これはパケットの種類を細かく指定して許可するために使用します。

例えば ssh のパケットを受信するには tcp プロトコルの 22 番ポートを開放します

iptables -A INPUT -p tcp --dport 22 -j ACCEPT

-p がプロトコル。続く –dport がポート番号 になります。–dport は -p のオプション的な扱いのようなので –dport だけを指定することはできません。

IPアドレスで直接許可したり、制限をかけたりすることもできます。IPを指定するには -s (source) を使用します。IPアドレスにはマスクを使用することもできます。マスクを利用すると IP アドレスの範囲を一気に指定することができます。
192.168.0.0/16 や 192.168.0.0/255.255.255.0 のどちらの形でも記述可能です。


# 192.168.0.8 の ssh を許可する場合
iptables -A INPUT -s 192.168.0.8 -p tcp --dport 22 -j ACCEPT
# 192.168.0.0 ~ 192.168.0.255 からの ssh を許可する場合
iptables -A INPUT -s 192.168.0.0/255.255.255.0 -p tcp --dport 22 -j ACCEPT

モジュール

-m モジュール

これは個別に設定されている機能を有効化してより細かくパケットを制限できます。
例えばローカルネットワーク内限定だと思いますが、macアドレスによって許可することも可能です。
mac アドレスを判定するには mac モジュールを指定します。

-m mac --mac-source 00:50:8D:FD:E6:32

などのように指定できます。

ある程度わかった(かも)ので、いくつか例を作ってみます。

# 受信パケットをデフォルトで破棄
iptables -P INPUT DROP

# ssh のポート開放。
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# ローカルに対してのみ ssh 開放
iptables -A INPUT -s 192.168.0.0/24 -p tcp --dport 22 -j ACCEPT

# apache の 80 番開放
iptables -A INPUT -p tcp --dport 80 -j ACCEPT

# mysql の開放
iptables -A INPUT -p tcp --dport 3306 -j ACCEPT

# SSL の開放
iptables -A INPUT -p tcp --dport 443 -j ACCEPT

これで、基礎的な部分はできるようになりました…?

参考

http://wiki.centos.org/HowTos/Network/IPTables

GET/POST データの操作 – Python

GET・POST リクエストの判定

os モジュールのenviron[‘REQUEST_METHOD’] を使用します。POST でリクエストされると “POST”、GETでリクエストされると “GET” になります。通常は GET リクエストなので “GET” が入ります。

import os 
if os.environ['REQUEST_METHOD'] == 'POST':
print 'POST REQUEST'

GET・POST データの取得

cgi モジュール

リクエストされたデータを取得するには cgi モジュールの FieldStorage() を使用します。 これは、GET、POST の双方のデータを取得する事が出来ます。

data = cgi.FieldStorage()

値にアクセスするには、辞書の get のような動きの getvalue() メソッドがあります。

getvalue(取得したいキー, キーに値がなかった時のデフォルト値)

で使用することが出来ます。

data.getvalue('name', 'not found') 

POST か GET に値があれば name キーの値、なければnot found が返されます。

同じフィールドに複数の値がある場合

例えば、 GET パラメータに name=kingyo を指定、POST も同時に name=bachi とした場合、getvalue() の戻り値は それらを含んだリストに変わります。

getvalue() だと、単一の場合と複数の場合で、リストになったり文字列になったりするので、常にリストで取得したい場合は getlist(name) を使用します。

data.getlist('id')

getlist() は指定された name のフィールドや値がなければ空のリストを返します。

また、逆に常に文字列で取得したい場合は、getfirst(name, default=None) を使用します。

getfirst('id')

getfirst() は、複数の値があったとしても、一番最初の値だけを返します。なにが最初に来るかの順番は、ブラウザによって変わる可能性があるので、並び順は考慮しない作りにしないといけないようです。
name に指定されたフィールドや値がなければ、default に指定された値が返されます。(初期設定では None が返されます)

辞書風にアクセスする

getvalue() や getfirst(), getlist() 等を使わずに、辞書風でアクセスして値を取得する事も出来ます。

data['name'].value

辞書風アクセスは、.value だけでなく、in 演算子で包含検査、keys() や len() もサポートしているようです。

if 'name' in data:
	# True
else:
	# False

data.keys()  # ['name'] 等

len(data)  # 1

参考

http://www.python-izm.com/contents/cgi/request.shtml
http://docs.python.jp/2/library/cgi.html
http://bygzam.seesaa.net/s/article/110314834.html

WordPress 3.8 アップデート

ちょっと前からですが 3.8 へアップデート可能ですよっというのが出ていたのでアップデートしました。そして、まず違ったのが管理画面です!

デザインがフラットになっていました!でこれは見た目が変わっただけで、実用性はあまり変わらないと思ったのですが、手持ちのスマートフォンでアクセスしてみたら、な、なんとちゃんと専用の画面があるではないですか(゜ロ゜)!!
前々からモバイル端末の使い勝手が悪すぎて、どうしようかと悩んでいたのですが…もう解決です。不満はあるとは思いますが、今のところ許容範囲に収まっています!

新年明けてちょっと嬉しい出来事でした(´ω`)

Apache でメンテナンス画面を出力する

Apache で運営しているサイトを更新する時に、404 NotFound や 500 Internal Server Error が発生しているとアクセスしてきたユーザーには不親切だと思います。なので、Apache でメンテナンス画面を表示する方法をメモしておきます。(まあこのブログではなんの意味もありませんが……)

※Apache2.2.22 で動作確認しています。

全体的な処理として今回行うのは、

  1. アクセスしてきたユーザーをメンテナンス画面(単純なhtmlファイル)にリダイレクトする
  2. 自分自身のアクセスの場合のみ、通常のサイトを表示する(動作確認用)

以上のことを .htaccess により設定します。


自分のIPを調べる

まずは、メンテナンス画面が正常に動作するかどうかの確認用のIPアドレスをメモしておきます。以下のようなサイトで表示される IPアドレスをメモします。
http://www.cman.jp/network/support/go_access.cgi
このIPアドレスは自分自身のことを指していて、この IP アドレスのみに通常のサイトを表示したり、逆にこのIPのみにメンテナンス画面を表示することで、実際に切り替える前に動作確認を行います。


メンテナンス画面を作成

ドキュメントルートに、maintenance.html などとしてメンテナンス中とわかるような表示を行うページを作成します。ここでは単純に以下のような html ファイルを作成します。
※実際にメンテナンス表示ページは、 Apache 側で用意されてはいるのですが、文章が英語なので日本向けのサイトを扱っている場合、日本語で用意していた方が親切かと思います。

maintenance.html

<h1>メンテナンス中です。</h1>


振り分け用の .htaccess の設定

メンテナンス用の振り分け設定の確認

アクセスしてきたユーザーを maintenance.html にリダイレクトする設定を行います。
しかし、いきなり実行してもし、設定がうまく行っていなかった場合、 500 Internal Server Error 等が表示されてしまうので(.htaccess の中身の誤字の場合はどうしても 500 エラーになります)、振り分けがきちんと動作するかを 上記で控えておいた IPアドレスのみにメンテナンス画面を表示します。以下をドキュメントルートの .htaccess に記述します。.htaccess ファイルが存在しない場合は作成します。
追記する場合は稼働中の .htaccess をコピーしてバックアップをとって置いた方がいいです。
(mod_rewrite と .htaccess は許可されているものと仮定しておきます。)

# これはファイルの先頭に
ErrorDocument 503 /maintenance.html

# 以下は既に  があればその直下に記述

  RewriteEngine On
  RewriteCond %{REQUEST_URI} !=/maintenance.html
  RewriteCond %{REMOTE_ADDR} =IPアドレス
  RewriteRule ^.*$ - [R=503,L]

ErrorDocument 503 /maintenance.html
503 のリダイレクト先を /maintenance.html というファイルに設定するという設定です

RewriteCond %{REQUEST_URI} !=/maintenance.html
リクエストされた URI が maintenance.html でない場合に、この記述以降に、最初に出てくる RewriteRule を実行する という設定になります。

RewriteCond %{REMOTE_ADDR} =IPアドレス
リクエストしてきた IPアドレスが 指定した IPアドレスの場合に、この記述以降に、最初に出てくる RewriteRule を実行する という設定になります。

RewriteRule ^.*$ – [R=503,L]
この記述の場合、リクエストしてきた URL が ^.*$ という正規表現にマッチする場合、次の [R=503,L] を処理します。
^.*$ は全てのどの文字列もマッチするので全てのリクエストという指定になります。
R=503 はリダイレクトを 503 リダイレクトとして処理することを意味します。一時的に移動していますという意味になります。
最後のカンマで区切られた L はこの条件が実行されればそれ以降の RewriteRule の処理は行われなくなります。

上記の “IPアドレス” の部分を初めに控えた IPアドレスに変更します。こうすることで、このIPアドレスの場合のみに maintenance.html にリダイレクトするようになります。

この状態で、初めにIPアドレスを確認したデバイスでサイトを閲覧すると、メンテナンス中です。と表示されるかと思います。そして、他のデバイスから(WiFiに繋がっていないスマートフォン等)確認すると、通常のサイトが表示されていれば成功です。

メンテンス対象を逆にする

現状では指定したIPアドレスからのアクセス時のみメンテンス画面を表示しているのですが、この設定を逆にして、指定したIPアドレス以外からのアクセスを全て、 maintenance.html にリダイレクトすることになります。
先ほどの .htaccess の以下の部分を

RewriteCond %{REMOTE_ADDR} =IPアドレス

次の用に変更します。

RewriteCond %{REMOTE_ADDR} !=IPアドレス

!= は次の条件では無いという意味で、 “IPアドレス” では無い場合に RewriteRule が適用される用になります。指定したIPアドレス以外の場合に、メンテンス画面にリダイレクトさせることになります。

以上で、メンテナンス画面を表示することができます。


設定を元に戻す

動作確認を終え、メンテナンスが終了した時に元に戻すには、.htaccess を新規作成した場合.htaccess を削除、.htaccess に追記した場合は、上記で設定した Rewrite…の設定をまるまる削除すると、通常通りサイトが表示されるようになります。バックアップをとっていた場合は、それを上書きか置き換えをすれば元通りです。


参考サイト

http://web-tan.forum.impressrd.jp/e/2009/06/16/5880