Linux マシンで ADSL 接続をし、サーバを運用する方法

初版 2001年 6月13日
第2版 2001年 6月14日
第3版 2001年 6月21日
第4版 2003年10月21日

無保証

この文書は完全に無保証です。この文書へのリンクは自由です。


概要

Linux マシンで ADSL 接続により、サーバを運用する方法を紹介します。

ADSL 接続では、接続が不意に切断されたり、不意に復旧したりすることもあります。サーバを運用するためには、不意の復旧を待つのではなく、こちらから復旧させることも必要になります。

具体的なサーバは示しませんが、ウェブ・サーバにしてもメール・サーバにしても、このような機能は必要となります。

ADSL 接続するまでの手順と、DHCP による非固定グローバル IP アドレス割り当てで、Dynamic Name Service を利用して、なるべく安定してサーバを運用できる方法を示します。


方法

1. ADSL 接続まで

1.1 ifupdown、PPP、RP-PPPoE のインストール

PPPRP-PPPoE をインストールします。Debian GNU/Linux 2.2(Potato)の場合で、インターネットにつながっている場合は Fig. 1 のように実行すると自動的にインストールできます。Woody の場合は ifupdown パッケージもインストールします。

他の Linux ディストリビューションを使っている場合は、ifupdown の orig.tar.gz をダウンロードしてインストールするとうまくいくと思います(未確認です)。

Fig. 1
# apt-get update
# apt-get install ppp pppoe

ADSL MODEM につながっているイーサネット・カードのインターフェース名が eth1 とすると、/etc/network/interfaces の eth1 のところは Fig. 2 のように記述します。

Fig. 2
auto eth1
iface eth1 inet static
  address 1.1.1.1
  network 1.1.1.1
  netmask 255.255.255.255
  broadcast 1.1.1.1

PPP を初めて使う場合、ppp0 が ADSL で通信をするときのインターフェース名になります(eth1 ではない)。ですから、ppp0 について、/etc/network/interfaces ファイルに Fig. 3 のように記述しておくといいでしょう。

Fig. 3
auto ppp0
iface ppp0 inet ppp
  provider dsl-provider
  up /usr/local/sbin/firewall.sh on
  down /usr/local/sbin/firewall.sh off

ここで、パラメータ provider に dsl-provider を指定していますが、これは PPP で設定するファイル名で、/etc/ppp/peers/dsl-provider を指定したことになります。これは後で設定します。パラメータ up と down は、それぞれ、インターフェース ppp0 が接続状態になったとき、切断状態になったときに実行するプログラム(スクリプト等)を指定します。ここでは、/usr/local/sbin/firewall.sh on と /usr/local/sbin/firewall.sh off を指定しています。このスクリプト・ファイルはファイアウォールを設定したり解除したりするために、あなたが書くものです。Linux にはじめから付属しているものではありません。

PPP 付属の pon dsl-provider、poff で ppp0 を有効にしたり無効にしたりすると、Fig. 3 の up や down で指定したスクリプトが実行されません。ですから、ifup ppp0、ifdown ppp0 を使って ppp0 を有効にしたり無効にしたりします。ifup、ifdown コマンドは、Debian GNU/Linux 2.2(Potato)なら netbase パッケージに、その後の版では ifupdown パッケージに含まれています。

/etc/ppp/pap-secrets ファイルの最後の行に、次を追記します。

Fig. 4
account@provider.ne.jp        provider.ne.jp         Password

ここで、account はプロバイダから与えられたアカウント名、provider.ne.jp はプロバイダのドメイン名です。Password はプロバイダにアクセスするためのパスワードです。

RP-PPPoE をインストールすると、/etc/ppp/peers/dsl-provider というファイルが作られます。/etc/ppp/peers/dsl-provider の最初の行は Fig. 5 のようになっていますが、 Fig. 6 のように修正します。

Fig. 5
pty "pppoe -I eth0 -T 80"
Fig. 6
pty "pppoe -I eth1 -T 80 -m 1412"
〜中略〜
user account@provider.ne.jp

ここで修正する必要があるのは -I オプションのインターフェース名を ADSL MODEM が接続されたイーサネット・カードのインターフェース名に変更することと、-m オプションで 1412 を指定するようにすることです。また、user パラメータでユーザ名を追加します。

ADSL の MTU については、ここのページに詳しいことが書かれています。これによると、MTU は 1454 に設定すればよいことがわかります。たた、Fig. 6 で設定している 1412 という値は、RP-PPPoE の man ページで、マシンをゲートウェイとして使い内側に LAN がある場合に強く推奨されている値です。

ADSL では、MTU を適切に設定しないと通信できないホストがあります。「お気に入りのウェブ・サイトが、いままでアナログ MODEM で接続していたときには見えたのに、ADSL にしたら見えなくなってしまった」ということが起こりえますので、MTU の設定には注意が必要です。

1.2 ADSL 接続の確認

では、ADSL 接続ができたか試してみましょう。Fig. 7 にそのようすを示します。

Fig. 7
# ifup eth1      # ADSL MODEM がつながっているインターフェースを有効にする。
# ifconfig       # 有効になったか調べてみる。
eth0      〜省略〜

eth1      リンク方法:イーサーネット  ハードウェアアドレス 00:00:E8:35:EB:DE
          inetアドレス:1.1.1.1 ブロードキャスト:1.1.1.1 マスク:255.255.255.255
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
      衝突(Collisions):625 TXキュー長:100
          RX bytes:0 (0.0 Mb)  TX bytes:0 (0.0 Mb)
          割り込み:11 ベースアドレス:0xe400

lo        リンク方法:ローカルループバック
          inetアドレス:127.0.0.1マスク:255.0.0.0
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:46301 errors:0 dropped:0 overruns:0 frame:0
          TX packets:46301 errors:0 dropped:0 overruns:0 carrier:0
      衝突(Collisions):0 TXキュー長:0
          RX bytes:2147389 (2.0 Mb)  TX bytes:2147389 (2.0 Mb)

# ifup ppp0       # ADSL 通信をするためのインターフェース ppp0 を有効にする。
# ifconfig        # 有効になったか調べてみる。有効になるまで数分かかることもある。
eth1      リンク方法:イーサーネット  ハードウェアアドレス 00:00:E8:35:EB:DE
          inetアドレス:1.1.1.1 ブロードキャスト:1.1.1.1 マスク:255.255.255.255
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
      衝突(Collisions):625 TXキュー長:100
          RX bytes:0 (0.0 Mb)  TX bytes:0 (0.0 Mb)
          割り込み:11 ベースアドレス:0xe400

lo        リンク方法:ローカルループバック
          inetアドレス:127.0.0.1マスク:255.0.0.0
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:46301 errors:0 dropped:0 overruns:0 frame:0
          TX packets:46301 errors:0 dropped:0 overruns:0 carrier:0
      衝突(Collisions):0 TXキュー長:0
          RX bytes:2147389 (2.0 Mb)  TX bytes:2147389 (2.0 Mb)

ppp0      リンク方法:Point-to-Pointプロトコル
          inetアドレス:aaa.bbb.ccc.ddd P-t-P:eee.fff.ggg.hhh マスク:255.255.255.255
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1454  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
      衝突(Collisions):0 TXキュー長:3
          RX bytes:0 (0.0 Mb)  TX bytes:0 (0.0 Mb)

#

このように、ifconfig コマンドは、有効になっているインターフェースについての情報を表示します。ifup ppp0 してから ppp0 が実際に有効になるまで(ifconfig で表示されるまで)少し時間がかかることもあるので、数分待ってみましょう。

上記のように ppp0 が表示されれば、ADSL 接続は成功しています。ブラウザやMUA(メーラ)がインストールされていて適切に設定されていれば、ブラウザを立ち上げたり、メールをやりとりしたりできる状態になっています。

2. ADSL 接続の維持

クライアントとして Linux を動かすのであれば、第 1 章の設定で OK ですが、サーバを動かす場合はいくつか問題があります。

ひとつは、ADSL 接続は時々不意に接続が切れてしまうことがあることです。Linux 側では、常に接続されているかを監視しておき、切断されていたら再接続をする必要があります。固定のグローバル IP アドレスが割り当てられる場合でもこれは必要です。

もうひとつは、DHCP でグローバル IP アドレスを割り当てられる場合に問題となるのですが、ADSL では特に何もしなくても不意に接続が回復する場合があります。また、前記のように接続を監視していてこちらから再接続をして接続を回復する場合もあります。いずれにしても、接続が回復した場合、割り当てられる IP アドレスが前回とは異なるかもしれません。Dynamic Name Service でグローバルなドメイン名を登録している場合は、新しい IP アドレスで登録しなおす必要があります。そうしないと、ユーザは、誰か別のマシンをあなたのマシンだと思ってアクセスしてしまうでしょう。

ここでは、任意のインターフェースに割り当てられている IP アドレスを返すシェル・スクリプト getipaddress.sh(これは pppcontinue.sh から呼び出される)と、接続を維持するためのシェル・スクリプト pppcontinue.sh とを用意し、cron で定期的に実行するようにします。

2.1 接続を維持するためのスクリプトの用意

getipaddress.sh を書きます。これは、pppcontinue.sh 以外にも汎用的に使えますので、使い方も示しておきます。

Fig. 8 /usr/local/sbin/getipaddress.sh
書式 getipaddress.sh [interface]
説明

getipaddress.sh は、インターフェースを指定しないで実行した場合は使い方を表示し、戻り値 0 で終了します。interface が指定された場合は、指定されたインターフェースの IP アドレスを標準出力に出力し、戻り値 0 で終了します。指定されたインターフェースが動作していない場合や、存在しないインターフェースが指定された場合は、標準エラー出力にエラー・メッセージを出力して戻り値 1 で終了します。

#!/bin/sh

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

if [ -z $1 ]; then
  echo "Usage: $0 interface" 1>&2
  exit 0;
fi

IFACE=$1

# IFACE の IP アドレスを調べる

if TMP=`LC_ALL=C ifconfig | egrep '\<'$IFACE'\>' -A 1` ; then
  echo "$TMP" | tail -1 | sed -e 's/ *//' -e 's/inet addr://' -e 's/ .*$//'
  exit 0;
else
  echo "$IFACE is down or there is no such interface." 1>&2
  exit 1;
fi

getipaddress.sh を実行属性にして(コマンドは chmod +x getipaddress.sh)、/usr/local/sbin ディレクトリ(なければ作ります)にコピーします。

次に、接続を維持するためのシェル・スクリプト pppcontinue.sh を書きます。このスクリプトは /var/local/log にログ・ファイルを出力するので、/var/local/log というディレクトリあらかじめを作成しておく必要があります。また、/var/local/run に、前回接続時の IP アドレスを格納するので /var/local/run ディレクトリもあらかじめ作成しておく必要があります。

Fig. 9 /usr/local/sbin/pppcontinue.sh
#! /bin/bash

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

# ログ・ファイルを設定。
LOG=/var/local/log/pppcontinue.log
# ログに記述する日付のフォーマット。
DATE_FMT="+%Y-%m-%d %a %T (%Z)"
# ADSL のインターフェースを設定。
ETH_PPP=eth1
PPP=ppp0
# タイムアウト対策用の ping 宛先アドレス。自分のプロバイダにしておく。
PING_ADDR=www.din.or.jp
# IP アドレスを格納しておくためのファイル。
IPFILE=/var/local/run/$PPP.ip

# PPP の IP アドレスを調べる。
CURRENT_IP=`/usr/local/sbin/getipaddress.sh $PPP 2> /dev/null`
RESULT=$?


# 接続状態にある場合は、接続タイムアウト対策のため ping でも打っておく。
if [ $RESULT -eq 0]; then
  ping -q -c 1 $PING_ADDR > /dev/null 2>> $LOG
fi

if [ $RESULT -ne 0 ]; then
  # 切断状態にある
  echo -n "[`LC_ALL=C date "$DATE_FMT"`]: " >> $LOG
  echo "Disconnected. Trying to reconnect." >> $LOG
  sleep 1
  echo "" >> $LOG
  echo "Down $PPP." >> $LOG
  ifdown $PPP >> $LOG 2>&1
  echo "Done." >> $LOG
  echo "Down $ETH_PPP." >> $LOG
  ifdown $ETH_PPP >> $LOG 2>&1
  echo "Done." >> $LOG
  sleep 1
  echo "Up $ETH_PPP." >> $LOG
  ifup   $ETH_PPP >> $LOG 2>&1
  echo "Done." >> $LOG
  echo "Up $PPP." >> $LOG
  ifup   $PPP >> $LOG 2>&1
  echo "Done." >> $LOG

  # 上記で再接続ができた場合
  sleep 10
  CURRENT_IP=`/usr/local/sbin/getipaddress.sh $PPP`
  RESULT=$?
  if [ $RESULT -eq 0 ]; then
    echo "Succeeded to reconnect." >> $LOG
  fi

  echo "----------------------------" >> $LOG
fi

if [ $RESULT -eq 0 ]; then
  # 接続状態にある
  if [ -f $IPFILE ]; then
    OLD_IP=`cat $IPFILE`
    if [ $CURRENT_IP != $OLD_IP ]; then
      echo -n "[`LC_ALL=C date "$DATE_FMT"`]: " >> $LOG
      echo "Different IP address has been given." >> $LOG
      echo "Try to update the DNS." >> $LOG
      /usr/local/sbin/dyndyn.sh delete >> $LOG 2>&1
      /usr/local/sbin/dyndyn.sh update >> $LOG 2>&1
      if [ $? -eq 0 ]; then
        echo $CURRENT_IP > $IPFILE
        echo "Old IP address was [$OLD_IP]." >> $LOG
        echo "Wrote new IP address [$CURRENT_IP] into $IPFILE." >> $LOG
      fi
      echo "----------------------------" >> $LOG
    fi
  else
    echo -n "[`LC_ALL=C date "$DATE_FMT"`]: " >> $LOG
    echo "$IPFILE does not exist." >> $LOG
    echo "Try to update the DNS." >> $LOG
    /usr/local/sbin/dyndyn.sh delete >> $LOG 2>&1
    /usr/local/sbin/dyndyn.sh update >> $LOG 2>&1
    if [ $? -eq 0 ]; then
      echo $CURRENT_IP > $IPFILE
      echo "Wrote new IP address [$CURRENT_IP] into $IPFILE." >> $LOG
    fi
  echo "----------------------------" >> $LOG
  fi
fi

この pppcontinue.sh も実行属性をつけて /usr/local/sbin にコピーします。

pppcontinue.sh の中で /usr/local/sbin/dyndyn.sh を呼び出しています。この dyndyn.sh は、Dynamic Name Service を提供している dyn.to の DNS を更新するためのスクリプトです。引数 delete は DNS から独自ドメインを削除し、update は DNS に独自ドメインと現在割り当てられている IP アドレスとの組を登録します。この部分は、あなたが使っている Dynamic Name Service の方法で同等の処理をするように書き換えてください。

2.2 接続維持用のスクリプトを自動実行する

これは簡単です。/etc/crontab に、Fig. 10 の 1 行を追記するだけです。こうすると、偶数分に pppcontinue.sh が実行されます。

Fig. 10
# Flet's ADSL
0-59/2 *        * * *   root    /usr/local/sbin/pppcontinue.sh

3. サーバを運用しよう

このように設定してうまく動けば、DHCP のグローバル IP 接続環境でも、極力安定してサーバを運用することができます。Apache でも qmail でも ProFTPD でも、外部からアクセスするようなサーバを運用してみましょう。

4. 参考文献の検索

参考文献の検索はこちらが便利です。

5. 謝辞

次の方々に感謝します。

Debian-JP メーリング・リストでアドバイスをくださった皆さん。

Debian Project、Debian-JP Project、その他のプロジェクトのみなさん。

RP-PPPoE の作者 Roaring Penguin's PPPoE Software のみなさん。

PPP の作者さん。

Linux の作者 Linus Torvalds さん。


島田博幸 shimaden@din.or.jp

[このコーナーの目次へ] [Tip - 便利ノート(ちょっと便利なコーナーへ)] [トップ・ページへ]

$Id: tip0009.html,v 1.11 2004/06/06 14:10:20 shimaden Exp $