SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

特集記事

TCPWrapperに対応したサービスの「POP Before」化を実現する

サービスを「POP Before」化する方法

  • X ポスト
  • このエントリーをはてなブックマークに追加

自分が使いたいから作ったものなのですが、外出先で適当に自宅サーバにログインしたくなったときに思いつきで作ったええ加減なLinux用シェルスクリプトです。TCPWrapperに対応する全てのソフトをPOPbefore化してしまいます。

  • X ポスト
  • このエントリーをはてなブックマークに追加

はじめに

 さて、外出先で自宅のサーバにログインしたくなったとき皆様はどうしていますか? モバイル環境から自宅に対してVPNを貼ったり、SoftEtherを使ったり、SSHを使用して暗号化を施してログインしたり、と様々な方法があると思います。

 VPNやSoftEtherを利用する場合、導入段階で面倒な作業を行う必要があるため、私はSSHを使っています。しかし、動的IPから自宅にSSHで入る場合、SSHのポートを外部に開かなければいけません。

 昨今、個人・企業問わずSSHのポートに対して総当り攻撃が増えています。きちんとSSHを設定して秘密鍵交換方式にしていれば総当り攻撃も回避できるのですが、それに伴うログの量やサーバ負荷などを考えると、閉じていた方が無難という判断もできます。しかし、どうしてもSSHポートから入りたい場面というのは出てきます。

 そんなわけで、シェル初心者ですが以下のスクリプトを作成してみました。

 このスクリプトを使用すると、TCPWrapperに対応するサービスを「POP Before」(POP認証後、接続IPに対し許可を与える)化することが可能になります。

対象読者

 本稿では、ある程度シェルスクリプトを使うことができる、初心者から中級者を読者として想定しています。

必要な環境

 最近のUNIX互換OSで動作するはずですが、私の環境ではRedhat Linux 8で動作確認を行っています。

 動作するには以下のパッケージがインストールされている必要があります。

 特にバージョン差異による誤動作などは無いとは思いますが、念のためご自身の環境でデバッグモードによるテスト動作をお勧めします。

/bin/sh -x ./access-allow.sh

初期設定

 ソース上部にある「Default setting. 」の部分を、お使いの環境に合わせてカスタマイズしてください。

「Default setting. 」の部分
# Default setting.
# DBPATH=<drac db file path>
DBPATH=/etc/mail/dracd.db

# FILEPATH=<hosts.allow file path>
FILEPATH=/etc/hosts.allow

# FILEPATH=<hosts.allow backup file path>
FILEPATH2=/etc/hosts.allow.bak

# Temporary file path
TMP=/tmp/access-allow
TMP2=/tmp/access-allow.bak
SCR=/tmp/access-allow.scr

# LOGFILE=<log file path>
LOGFILE=/var/log/access-allow.log

# TIME=<Sleep sec time>
TIME=20

# SERVICE=<service or daemon name>
# Please input service corresponding to TCP Wrapper. 
SERVICE=in.sshd

# Default setting end.

 上記以外では以下のことが必要です。

  • 既存の「hosts.allow」に以下の行を追加
  • # access-allow
    
  • できれば、既存「hosts.allow」ファイルのバックアップ

初期設定時の注意

 一時ファイルのファイル名は、なるべく推測しにくい名前にすることをお勧めします。

一時ファイルの名前(パス)の指定
# Temporary file path
TMP=/tmp/access-allow
TMP2=/tmp/access-allow.bak
SCR=/tmp/access-allow.scr

使用方法

 root権限で、バックグラウンドで実行してください。

バックグラウンドでのシェルスクリプトの実行
# ./access-allow.sh &

基本動作

 シェルスクリプトを作成した経験がある方ならば、ソースを見ればわかるとは思いますが、以下のようになっています。

  1. DBから抽出
  2. 前回の記録との照合
  3. 差異があった場合は前回「hosts.allow」に追加した分を削除して、今回の内容を追加
  4. ログの書き出し
  5. 20秒間のスリープ(デフォルトでは20秒)
  6. 「1.」に戻る

ソースコード

「access-allow.sh」
#!/bin/sh
# POPbeforeETCSERVICE Script.
# Version 1.2
# Copyright (c) 2005 Mappi <info@mappi-daily.net> 
# All rights reserved.

# This script is the one to give the access permit in cooperation
# with dracd as for service corresponding to TCP Wrapper. 

PATH=/bin:/usr/bin:/sbin:/usr/sbin;export PATH

# Default setting.
# DBPATH=<drac db file path>
DBPATH=/etc/mail/dracd.db

# FILEPATH=<hosts.allow file path>
FILEPATH=/etc/hosts.allow

# FILEPATH=<hosts.allow backup file path>
FILEPATH2=/etc/hosts.allow.bak

# Temporary file path
TMP=/tmp/access-allow
TMP2=/tmp/access-allow.bak
SCR=/tmp/access-allow.scr

# LOGFILE=<log file path>
LOGFILE=/var/log/access-allow.log

# TIME=<Sleep sec time>
TIME=20

# SERVICE=<service or daemon name>
# Please input service corresponding to TCP Wrapper. 
SERVICE=in.sshd

# Default setting end.

# Environmental investigation
if [ ! "(" -s ${DBPATH} ")" ];then
    echo "${0}:${DBPATH}: No such file or directory"
    echo "${0}:${DBPATH}: No such file or directory" >> ${LOGFILE}
    exit 1
fi
if [ ! "(" -s ${FILEPATH} ")" ];then
    echo "${0}:${FILEPATH}: No such file or directory"
    echo "${0}:${FILEPATH}: No such file or directory" >> ${LOGFILE}
    exit 1
fi

# Start log output
echo "`date` access-allow.sh start..." >> ${LOGFILE}
# Delete temporary files.
if [ ${TMP} ];then
    rm -f ${TMP}
fi

# Main processing.
while [ "TRUE" ]
do
COUNT=`db33_dump -p ${DBPATH} |
 egrep "[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*" | wc -l |
 sed s/^[[:space:]]*//g`
CT=1
until [ "${CT}" -gt "${COUNT}" ]
    do
    echo -n "`db33_dump -p ${DBPATH} |
 egrep '[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*' | sed -n ${CT}p` " >> ${TMP}
    CT=`expr ${CT} + 1`
    done
    if [ "`cat ${TMP}`" != "`cat ${TMP2}`" ];then
        echo "/access-allow/a\\" > ${SCR}
        echo -n "${SERVICE} : " >> ${SCR}
        cat ${TMP} >> ${SCR}
        cp ${FILEPATH} ${FILEPATH2}
        sed /${SERVICE}/d ${FILEPATH2} > ${FILEPATH}
        cp ${FILEPATH} ${FILEPATH2}
        sed -f ${SCR} ${FILEPATH2} > ${FILEPATH}
        echo "`date` add `cat ${TMP}`" >> ${LOGFILE}
    fi
mv ${TMP} ${TMP2}
sleep ${TIME}
done

最後に

 今回、CodeZineに投稿したわけは勉強としての意味合いが強く、はっきり言って自分のソースコードはスマートではありません。もっとスマートなやり方を思いつく読者の方がたくさんいると思います。

 拙い記事ですが、ここに投稿したことによって自分自身がさらに精進できればいいなと思っています。皆様の暖かい意見をお待ちしております。

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
特集記事連載記事一覧

もっと読む

この記事の著者

名無し草(ナサナシグサ)

よろしくお願いいたします。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/155 2008/09/01 18:51

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング