Web鯖で特定の人間だけに見せたい領域がある場合パスワード認証をかけるわけだが、昔ならBasic認証を使ってパスワードをかけるようだが、安全ではないので変わりにDigest認証を使うらしい。
以下、その方法。
まず、対象のディレクトリに対する設定。
やり方は二種類あって、「設定ファイルに直接書き込む方法」と「.htaccessを使う方法」があります。
公開されているディレクトリが絶対パスが「/www」で、認証をかけたいディレクトリが「/www/test」だった場合を想定。
以下、設定ファイルを使う場合。
<Directory "/www/test"> AuthType Digest AuthName "private zone" AuthDigestDomain /test/ AuthUserFile /etc/apache2/.htdigest Require valid-user </Directory>
以下、.htaccessを使う場合。
対象のディレクトリに.htaccessを作って書き込む。
AuthType Digest AuthName "private zone" AuthDigestDomain /test/ AuthUserFile /etc/apache2/.htdigest Require valid-user
AuthNameは領域を示す文字列で、認証を求めたユーザのダイアログに表示されたり、保護する範囲(後述)を決めたりする。
AuthUserFileは認証するユーザが書かれたファイルで、コマンドで作成する。
このファイルは何処にでも置けるので、外部から見えない位置に置いておくのが良い。
Requireはアクセスできるユーザを指定する事が出来ます。
「user hoge」を指定した場合は、ユーザhogeのみがアクセス出来るようになり、「valid-user」の場合はAuthUserFileに書かれているユーザ全てがアクセス出来るようになる(「group hoge」という指定もあるが、説明が増えるのでここでは省く)。
AuthDigestDomainは対象ディレクトリを指定する所だと思うが、省略しても動く謎の設定。
説明を読んだ感じでは、保護するディレクトリのルートは最低でも指定した方が良いらしい(指定しないと、無駄なヘッダーのやり取りが発生したりする)。
他のホストと認証を共有したりする時も使用するそうだが、使う事も無いと思うので保護するルートディレクトリのみを書いておけばよいだろう。
認証するユーザを作成します。
htdigestというコマンドを使用して作成します。
ファイルの作成する場所は「/etc/apache2/.htdigest」で、領域は「private zone」、ユーザ名は「hoge」を例とします。
# htdigest -c /etc/apache2/.htdigest "private zone" hoge
新規作成時のみオプション「-c」を付けてください。
ここで領域が出てきましたが、このユーザ(hoge)が認証に成功した場合、ここで指定された領域(private zone)と設定ファイルのAuthNameで書かれた領域が一致したディレクトリは、認証の有効期限(ブラウザ終了とか)が続く限り認証作業を省略してアクセスする事が出来ます。
これを使えば細かく制御が出来そうです。
1000投稿をしようとしたら、新しいパーマリンクが生成されずに過去の記事のパーマリンクが生成されてしまい、新しい記事が投稿されない状態になってしまった。
最初は、ついにデータベースが吹き飛んだか? と、思って色々チェックしても問題が見当たらずに、Apacheの再起動もしてみたが改善されない。
で、色々調べてみたらブラウザのキャッシュが悪戯している可能性が・・・というのを発見したので、キャッシュを消してみた所、無事に解決した。
しかし、ブラウザのキャッシュでのトラブルってまだあったんだねぇ。
私が現役でWebなプログラマをやってた時は、結構問題が起こって困ってたんだけど、まさか8年近く経った今でもそんな事が起こるとは。
技術が進んでいるようで、そんなに進んでいないんじゃないかと思ってしまったのであった。
固定IPを止めて外部に鯖を借りてしまった為、自宅のIPを使う時に色々と面倒な作業が発生し始めた。
この作業を簡略化する為に、Dynamic DNSを作る事にした。
一応、今使っているルータの販売元がDynamic DNSのサービスをタダでやってるんだけど、次回もこのメーカーを買わなきゃいけなくなるので、それは避けたいのと、他にも無料でやっている所はあるが、面白そうと言う理由だけでやってしまう☆
この記事を参考にして作業する人は、以下の条件に適合する人のみ。
- 自分でグローバルな所に置いてあるDNSを持っている
無い人には意味の無い記事です。
無料か有料なDynamic DNSサービスを探して使ってください。
うちみたいな運用を個人でやってるのは、少ないと思います(笑) - Debian LinuxでBIND9が動いていて、既にマスターゾーンサーバになっている
うちの環境です。 - SSHで接続できる
色々とセキュリティ関係で手を抜く為に使ってます。
まず始めに、/etc/bindの書き込み権限を変更します。
多分、初期状態では所有者rootでグループbindになってますが、bindに対しての書き込み権限がありません。
コマンドを使用しての書き換えにbindに権限が必要なので変更。
# chmod g+w /etc/bind
後、実行するとゾーンファイルも書き換えられるので、対象の正引きゾーンファイルもbindユーザが書き込み出来る様に権限を変えてください。
設定ファイルのゾーン定義の部分で、書き換えが起こる部分に以下の設定を追加する。
allow-update { localhost; };
これを追記する事で、ローカルホストからのみコマンドによってゾーンファイルを書き換える事が可能になります。
書き換える方法はnsupdateコマンドを使用します。
このコマンドを使用すると、対話式のプロンプトに移行します。
> update add hoge.maocat.net. 3600 in a 192.168.255.1 > send
上記のコマンドでhoge.maocat.netを192.168.255.1として、TTL3600、Aレコードの形で登録する事が出来ます。
削除する場合は以下の通り。
> update delete hoge.maocat.net. > send
更新を確認する場合は、hostコマンドかdigコマンド(windowsではnslookup)を使用する。
実際にゾーンファイルに書き込まれるのには少し時間がかかる。
で、これをシェルスクリプトで書き換えを行う。
ルータに割り振られたIPを通知するには、sshを使った時に環境変数に接続元の情報が書き込まれるので、それを加工する。
このスクリプトを使う専門のユーザを作って実行させた方がいいかも。
以下、登録用のシェルスクリプト。
#!/bin/sh CONNECTION_IP=`echo $SSH_CONNECTION | cut -f1 -d " "` COMMAND_FILE="$HOME/dns_update_command" HOST_NAME="hoge.maocat.net" if expr "$CONNECTION_IP" : "^[0-9]\{1,3\}[.][0-9]\{1,3\}[.][0-9]\{1,3\}[.][0-9]\{1,3\}$" > /dev/null ; then DNS_RESULT=`host $HOST_NAME` if expr "$DNS_RESULT" : "^Host $HOST_NAME not found" > /dev/null ; then echo "update add $HOST_NAME. 3600 in a $CONNECTION_IP" > $COMMAND_FILE echo "" >> $COMMAND_FILE nsupdate $COMMAND_FILE elif expr "$DNS_RESULT" : "^$HOST_NAME has address" > /dev/null ; then echo "update delete $HOST_NAME." > $COMMAND_FILE echo "update add $HOST_NAME. 3600 in a $CONNECTION_IP" >> $COMMAND_FILE echo "" >> $COMMAND_FILE nsupdate $COMMAND_FILE fi fi
sshから接続して、このスクリプトを実行すれば接続したIPが登録されます。
ここを参考にして、暗号鍵での接続やコマンド制限を駆使すれば、cronでの自動化やセキュリティの向上が出来ると思います。
DebianLinuxのデフォルトでは、digコマンドやらnslookupコマンドが入っていない。
毎回、鯖を再構築する時に忘れてググル先生に頼っているのでメモっとく。
以下のコマンドを叩くだけで、必要な物はインストールされる。
apt-get install dnsutils
画像をデータベースに保存する為にbyte型に変換する必要があったので、調べてみた。
ソースコードはtry-catchを省略しているので、適宜入れるように。
//Bitmap to Bytes ByteArrayOutputStream baos = new ByteArrayOutputStream(); bitmap.compress(CompressFormat.PNG, 100, baos); byte[] bytes = baos.toByteArray();
byteに変換すれば、データベースにも保存できる。
//Bytes to Bitmap Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
戻すのは簡単。
大きい画像を取り出す場合は、optionを使って色々弄る必要があるかも。
//Bitmap to File FileOutputStream fos = openFileOutput("test.png", Context.MODE_PRIVATE); bitmap.compress(CompressFormat.PNG, 100, baos); fos.flush(); fos.close();
ファイルに保存する場合はFileOutputStreamを使う。
読み込みに関してはBitmapFactory.decodeFileを使えば読み出せる。
書き込み時にファイルのパスを省略しているが、読み出す時はフルパスが必要っぽい。