  Virtual Services Howto
  Brian Ackerman, brian@nycrc.net
  v1.2, 4 November 1997
  伊佐治 哲, isaji@mxu.meshnet.or.jp
  23 Dec 1997

  このドキュメントはサービスの仮想化の方法についてますます増えてきた要求
  に応じて書かれました。 (訳者：訳文に関する質問は必ず伊佐治までお願いい
  たします。またこのHOWTO本体(英語)の最新版は ftp://sun-
  site.unc.edu/pub/Linux/docs/HOWTO/ から入手できます)。
  ______________________________________________________________________

  目次

  1. イントロダクション
     1.1 必要な知識
     1.2 目的
     1.3 フィードバック
     1.4 改訂履歴
     1.5 著作権、配布条件(Copyright/Distribution)

  2. IPエイリアス
  3. バーチャルデーモン(virtuald)
     3.1 どのような動作をするか
     3.2 inetd
     3.3 virtual.conf
     3.4 virtualdのソース

  4. 仮想スクリプト(Virt scripts)
     4.1 virtfs
     4.2 virtexec
     4.3 virtfsとvirtexecに関する注意

  5. DNS
  6. Syslog
     6.1 問題点
     6.2 解決方法

  7. 仮想FTP
  8. 仮想Web
  9. 仮想的なMail/Pop
     9.1 Qmail の注意点
     9.2 問題
     9.3 悪い解決方法
     9.4 良い解決方法

  10. その他仮想的にできること
  11. まとめ
  12. FAQ
  13. 作業メモ
     13.1 virtfsについて
     13.2 その他のエラー
        13.2.1 /var/log/syslog:
        13.2.2 FTP
        13.2.3 Mail
        13.2.4 Web

  ______________________________________________________________________

  1.  イントロダクション

  1.1.  必要な知識

  仮想サービスの設定はそんなに難しいものではありません。しかし基礎的な事
  柄に加えてそれ以上の知識も必要とされます。このドキュメントではLinuxマ
  シンの設定の仕方については取り扱いません。

  このドキュメントを理解するには以下述べるドキュメントの内容にちゃんと慣
  れ親しんでいるものと仮定します。

  o  LinuxカーネルのコンパイルとIP aliasingサポートの追加 IP alias mini-
     HOWTO

  o  ネットワークデバイスのセットアップと設定 NET-3 HOWTO

  o  inetdの設定 NET-3 HOWTO

  o  ネットワークパッケージのコンパイルとインストール Sendmail Site
     Apache Site Wu-Ftpd FAQ

  o  DNSの設定 DNS HOWTO

     もし上に述べた事柄についてまだ理解していなければ、これらのパッケー
     ジに慣れるように上に指示されたリンクを使いそのドキュメント等を読ま
     れることを強くお奨めます。これらのドキュメント内容についてメールを
     送っていただいても返事は出しません。HOWTOの該当する著者に直接聞いて
     下さい。

  1.2.  目的

  仮想サービスの目的は複数のネットワークカードを使わないで複数のIPアドレ
  スを単体マシンに認識させるというものです。IPエイリアスはカーネルオプ
  ションで、このオプションは各ネットワークデバイスに一つ以上のIPアドレス
  を割り当てるようにするためのです。カーネルはバックグランドで各IPアドレ
  スを高速にスワップすることにより多重送信 (multiplexes)を行います。ユー
  ザーにとってはひとつ以上のネットワークカードがあるかのように見えるわけ
  です。

  この多重送信(multiplexing)によってwww.domain1.com, www.domain2.comなど
  といった複数のドメインをひとつのドメイン程度のコストで運営できます。残
  念なことに多くのサービス(ftp, web, mail)はそのままではこの複数のドメイ
  ンで使えません。それらを適切に動作させるためには、設定ファイルとソース
  コードを修正しなくてはなりません。このドキュメントは仮想マシンのセッ
  ティングにおいてその修正をどのように行うか解説しています。

  デーモンも同様に仮想サービスの機能を提供するために必要です。今回使うデ
  ーモン(virtuald)のソースは、この後ドキュメント中に出てきます。

  1.3.  フィードバック

  パッケージがアップデートされたり設定の変更があった時に、このドキュメン
  トを拡張します。このドキュメントで、はっきりしないなどの不具合がありま
  したらその提案や質問などをメールに書いて送って下さい。またコメントはで
  きるだけはっきりと、どこの章がわかりにくいかを明記して下さい。その結果
  著者がHOWTO全文に目を通さずにすみます。サブジェクトにはVIRTSERVICES
  HOWTOと書いて送っていただくことも大切です。その他のメールは個人用とな
  ります。個人用メールを読まずせっかく送ったメールも処分してしまうかもし
  れないので十分注意して下さい。

  このドキュメントで著者が提示した例はほんの一例にすぎないので、そのまま
  コピーして使わないで下さい。読者各自が自分の環境にあうように書き換えて
  おいて下さい。もし何か問題がありましたら著者までメールを送って下さい。
  その際メールにはちゃんと設定ファイル、エラーメッセージを書いてくだされ
  ば、ちゃんと目を通してその解決などの提案をメールで返事します。
  1.4.  改訂履歴

  V1.0 初期バージョン

  V1.1 Virtual Web Sectionのエラー更新

  V1.2 日付の更新

  1.5.  著作権、配布条件(Copyright/Distribution)

  This document is Copyright (c) 1997 by The Computer Resource Center
  Inc.

  A verbatim copy may be reproduced or distributed in any medium
  physical or electronic without permission of the author.  Translations
  are similiarly permitted without express permission if it includes a
  notice on who translated it.  Commercial redistribution is allowed and
  encouraged; however please notify Computer Resource Center of any such
  distributions.

  Excerpts from the document may be used without prior consent provided
  that the derivative work contains the verbatim copy or a pointer to a
  verbatim copy.

  Permission is granted to make and distribute verbatim copies of this
  document provided the copyright notice and this permission notice are
  preserved on all copies.

  In short, we wish to promote dissemination of this information through
  as many channels as possible. However, I do wish to retain copyright
  on this HOWTO document, and would like to be notified of any plans to
  redistribute this HOWTO.

  (和訳文を付けておきますが、正式な著作権は英語の原文に従います)

  著者の承認をとらずに原文のコピーをして物理的/電子的媒体で改変/配布して
  もかまいません。翻訳も同様に特別な許可はいりませんが、その場合は誰が翻
  訳したのか必ず明記して下さい。商用的な再配布は認めます。また推奨しま
  す。しかしそのような配布をする時も Computer Resource Centerにまで届け
  出て下さい。

  本文からの引用は事前の同意(原文引用や原文へのポインタを含んだ内容を提
  供する際の同意)なしで使っていただいてかまいません。

  ドキュメントの原文コピーを改変/配布する際は、著作権の表示やこの許可条
  項が文書に含まれている限り可能です。

  できるだけ多くの分野でこの情報が普及すること希望します。しかしドキュメ
  ントの著作権は保護されますし再配布する場合は届け出て下さい。

  2.  IPエイリアス

  IPエイリアス(IP aliasing)は仮想ホストマシンを稼働するために設定するカ
  ーネルオプションのことです。mini-HOWTOがすでにあるのでこちらを参照して
  ください (IP aliasing)。設定方法の質問などが扱われています。 (訳注：具
  体的なエイリアスの設定。カーネルオプションでエイリアスオプションを選択
  してカーネルの再構築をします。その後rootで

    ifconfig eth0:0 (追加するIP)
    route add -host (追加するIP) dev eth0:0

  とします。詳しくは「NET-2/3-HOWTO」の13.11.2.1を参照して下さい)。

  3.  バーチャルデーモン(virtuald)

  3.1.  どのような動作をするか

  ネットワーク接続は"IPアドレス"と"ポート番号"のペアからなっています。
  ネットワークプログラミングのAPI(Applications Program
  Interface)はsockets apiと呼ばれます。ソケットは開いたファイルのように
  振舞い、これに対する読み書きをすることでネットワーク経由でデータをやり
  とりができます。

  ローカルソケットのIPアドレスを返すファンクションコールgetsockname があ
  ります。

  virtualdはgetsockname(訳注：/lib/libc.so)を、どのローカルマシンのIPが
  アクセスされているかを決めるのに用います。 Virtualdは設定ファイルを読
  み込み、そのIPに対応するディレクトリを取得します。そのディレクトリに
  chrootした後、実際に行われるサービスに接続を引き渡します。

   chroot  はルートディレクトリ'/' を別のディレクトリにセットし直し、そ
  のディレクトリ(新しいルートディレクトリ)よりも上にある全てのものは実行
  されているプログラムからは見えません(切り離されます)。こうして各IPアド
  レスはそれぞれの仮想ファイルシステムを取得します。これはネットワークプ
  ログラムからは透過的なので(上に書いたような操作は隠してあるので)、プロ
  グラムは何事もなかったかのように動作します。

  このようにして、inetdといったプログラムと連結されたVirtuald はいろいろ
  なサービスを仮想化して使うことができるのです。

  3.2.  inetd

  Inetdは複数のポートを監視し、接続があった場合に(例えばpop要求があった
  ときなどに)ネットワークネゴシエーション行って指定されたプログラムに接
  続を引き渡すスーパーサーバです。これにより、必要がなくて何もしていない
  サーバがないようにします。

  標準的な /etc/inetd.confファイルは

  ftp stream tcp nowait root /usr/sbin/tcpd wu.ftpd -l -a
  pop-3 stream tcp nowait root /usr/sbin/tcpd in.qpop -s

  となります。(訳注：pop-3はpop3の場合はpop3にして下さい)。

  また仮想的な/etc/inetd.confファイルは

  ftp stream tcp nowait root /usr/bin/virtuald virtuald /virtual/conf.ftp wu.ftpd -l -a
  pop-3 stream tcp nowait root /usr/bin/virtuald virtuald /virtual/conf.pop in.qpop -s

  となります。

  3.3.  virtual.conf

  それぞれのサービスに対応するIPとディレクトリをコントロールする
  confファイルを取得します。一つのマスターconfファイルがあり、またドメイ
  ンの異なるリストのサービスが必要なときはそれに応じたconfファイルを用意
  することができます。virtual.confは以下のような内容です。

  # This is a comment and so are blank lines

  # Format IP <SPACE> dir <NOSPACES>
  10.10.10.129 /virtual/foo.bar.com
  10.10.10.130 /virtual/bar.foo.com
  10.10.10.157 /virtual/boo.la.com

  (訳注：実際の中身は各設定環境に合わせて書き換えて下さい。そしてこの
  ファイルは(上のinitd.confの設定に合わせた)該当ディレクトリおよびファイ
  ル名にコピーします)。

  3.4.  virtualdのソース

  (訳注：このVirtualdのソースは gcc -o viturald virtuald.cとしてコンパイ
  ルできます。また後の文章と合わせるために/usr/binにコピーします)

  ______________________________________________________________________
  #include <netinet/in.h>
  #include <sys/socket.h>
  #include <arpa/inet.h>
  #include <stdarg.h>
  #include <string.h>
  #include <syslog.h>
  #include <stdio.h>

  #define BUFSIZE 8192

  main(int argc,char **argv)
  {
          char buffer[BUFSIZE];
          char *ipaddr,*dir;

          logit("Virtuald Starting: $Revision: 1.2 $");
          if (!argv[1])
          {
                  logit("invalid arguments: no conf file");
                  quitting_virtuald(0);
          }
          if (!argv[2])
          {
                  logit("invalid arguments: no program to run");
                  quitting_virtuald(0);
          }
          if (getipaddr(&ipaddr))
          {
                  logit("getipaddr failed");
                  quitting_virtuald(0);
          }
          sprintf(buffer,"Incoming ip: %s",ipaddr);
          logit(buffer);
          if (iptodir(&dir,ipaddr,argv[1]))
          {
                  logit("iptodir failed");
                  quitting_virtuald(0);
          }
          if (chroot(dir)<0)
          {
                  logit("chroot failed: %m");
                  quitting_virtuald(0);
          }
          sprintf(buffer,"Chroot dir: %s",dir);
          logit(buffer);
          if (chdir("/")<0)
          {
                  logit("chdir failed: %m");
                  quitting_virtuald(0);
          }
          if (execvp(argv[2],argv+2)<0)
          {
                  logit("execvp failed: %m");
                  quitting_virtuald(0);
          }
  }

  int logit(char *buf)
  {
          openlog("virtuald",LOG_PID,LOG_DAEMON);
          syslog(LOG_ERR,buf);
          closelog();
          return 0;
  }

  int quitting_virtuald(int retval)
  {
          exit(retval);
          return 0;
  }

  int getipaddr(char **ipaddr)
  {
          struct sockaddr_in virtual_addr;
          static char ipaddrbuf[BUFSIZE];
          int virtual_len;
          char *ipptr;

          virtual_len=sizeof(virtual_addr);
          if (getsockname(0,(struct sockaddr *)&virtual_addr,&virtual_len)<0)
          {
                  logit("getipaddr: getsockname failed: %m");
                  return -1;
          }
          if (!(ipptr=inet_ntoa(virtual_addr.sin_addr)))
          {
                  logit("getipaddr: inet_ntoa failed: %m");
                  return -1;
          }
          strncpy(ipaddrbuf,ipptr,sizeof(ipaddrbuf)-1);
          *ipaddr=ipaddrbuf;
          return 0;
  }

  int iptodir(char **dir,char *ipaddr,char *filename)
  {
          char buffer[BUFSIZE],*bufptr;
          static char dirbuf[BUFSIZE];
          FILE *fp;

          if (!(fp=fopen(filename,"r")))
          {
                  logit("iptodir: fopen failed: %m");
                  return -1;
          }
          *dir=NULL;
          while(fgets(buffer,BUFSIZE,fp))
          {
                  buffer[strlen(buffer)-1]=0;
                  if (*buffer=='#' || *buffer==0)
                          continue;
                  if (!(bufptr=strchr(buffer,' ')))
                  {
                          logit("iptodir: strchr failed");
                          return -1;
                  }
                  *bufptr++=0;
                  if (!strcmp(buffer,ipaddr))
                  {
                          strncpy(dirbuf,bufptr,sizeof(dirbuf)-1);
                          *dir=dirbuf;
                          break;
                  }
          }
          if (fclose(fp)==EOF)
          {
                  logit("iptodir: fclose failed: %m");
                  return -1;
          }
          if (!*dir)
          {
                  logit("iptodir: ip not found in conf file");
                  return -1;
          }
          return 0;
  }
  ______________________________________________________________________

  4.  仮想スクリプト(Virt scripts)

  4.1.  virtfs

  各ドメインはそれぞれのディレクトリ構造を持っています。 chroot を使って
  いるのでシェアライブラリ(shared libraries), バイナリ, conf ファイル等
  の 重複したコピーが必要になります。著者は各ドメイン用の
  /virtual/domain.comを作り、それぞれにコピーして使っています。そのため
  多くのディスクスペースを使いますが新しいマシンやネットワークカードを購
  入するよりは安価でしょう。もしディスクスペースを節約したいのならそれぞ
  れのファイルをリンクすれば間に合います (訳注：このリンクはシンボリック
  リンクではありません)。

  ここでvirtfsスクリプトの例をあげます。

  ______________________________________________________________________
  #!/bin/bash

  echo '$Revision: 1.2 $'

  echo -n "Enter the domain name: "
  read domain

  if [ "$domain" = "" ]
  then
          echo Nothing entered: aborting
          exit 0
  fi

  leadingdir=/virtual

  echo -n "Enter leading dir: (Enter for default: $leadingdir): "
  read ans

  if [ "$ans" != "" ]
  then
          leadingdir=$ans
  fi

  newdir=$leadingdir/$domain

  if [ -d "$newdir" ]
  then
          echo New directory: $newdir: ALREADY exists
          exit 0
  else
          echo New directory: $newdir
  fi

  echo Create $newdir
  mkdir -p $newdir

  echo Create bin
  cp -pdR /bin $newdir

  echo Create dev
  cp -pdR /dev $newdir

  echo Create dev/log
  ln -f /virtual/log $newdir/dev/log

  echo Create etc
  mkdir -p $newdir/etc
  for i in /etc/*
  do
          if [ -d "$i" ]
          then
                  continue
          fi
          cp -pd $i $newdir/etc
  done

  echo Create etc/skel
  mkdir -p $newdir/etc/skel

  echo Create home
  for i in a b c d e f g h i j k l m n o p q r s t u v w x y z
  #   (訳注：ここの[a-z]はそれぞれ設定するユーザー名に変更します)
  do
          mkdir -p $newdir/home/$i
  done
  echo Create home/c/crc
  mkdir -p $newdir/home/c/crc
  chown crc.users $newdir/home/c/crc
  #  (訳注：ここも設定したユーザーに合わせて変更して下さい)

  echo Create lib
  mkdir -p $newdir/lib
  for i in /lib/*
  do
          if [ -d "$i" ]
          then
                  continue
          fi
          cp -pd $i $newdir/lib
  done

  echo Create proc
  mkdir -p $newdir/proc

  echo Create sbin
  cp -pdR /sbin $newdir

  echo Create tmp
  mkdir -p -m 0777 $newdir/tmp
  chmod +t $newdir/tmp

  echo Create usr
  mkdir -p $newdir/usr

  echo Create usr/bin
  cp -pdR /usr/bin $newdir/usr

  echo Create usr/lib
  mkdir -p $newdir/usr/lib

  echo Create usr/lib/locale
  cp -pdR /usr/lib/locale $newdir/usr/lib
  #       (訳注：ここのディレクトリ適当に変更します)

  echo Create usr/lib/terminfo
  cp -pdR /usr/lib/terminfo $newdir/usr/lib

  echo Create usr/lib/zoneinfo
  cp -pdR /usr/lib/zoneinfo $newdir/usr/lib

  echo Create usr/lib/\*.so\*
  cp -pdR /usr/lib/*.so* $newdir/usr/lib

  echo Create usr/sbin
  cp -pdR /usr/sbin $newdir/usr

  echo Linking usr/tmp
  ln -s /tmp $newdir/usr/tmp

  echo Create var
  mkdir -p $newdir/var

  echo Create var/lock
  cp -pdR /var/lock $newdir/var

  echo Create var/log
  mkdir -p $newdir/var/log

  echo Create var/log/wtmp
  cp /dev/null $newdir/var/log/wtmp

  echo Create var/run
  cp -pdR /var/run $newdir/var

  echo Create var/run/utmp
  cp /dev/null $newdir/var/run/utmp

  echo Create var/spool
  cp -pdR /var/spool $newdir/var

  echo Linking var/tmp
  ln -s /tmp $newdir/var/tmp

  echo Create var/www/html
  mkdir -p $newdir/var/www/html
  chown webmast.www $newdir/var/www/html
  #  (訳注：ここのchownも適当に変更しておいて下さい。以下同様)
  chmod g+s $newdir/var/www/html

  echo Create var/www/master
  mkdir -p $newdir/var/www/master
  chown webmast.www $newdir/var/www/master

  echo Create var/www/server
  mkdir -p $newdir/var/www/server
  chown webmast.www $newdir/var/www/server

  exit 0
  ______________________________________________________________________

  4.2.  virtexec

  仮想環境でコマンドを実行するにはそのディレクトリへ chroot してから実行
  します。ここでコマンドを操作するvirtexecを呼び出すシェルスクリプトを書
  きました。 (訳注：以下のコードを切り取って/usr/binディレクトリにコピー
  します。属性の変更(chmod +x)をしておいて下さい)。

  ______________________________________________________________________
  #!/bin/sh

  echo '$Revision: 1.2 $'

  BNAME=`basename $0`
  FIRST4CHAR=`echo $BNAME | cut -c1-4`
  REALBNAME=`echo $BNAME | cut -c5-`

  if [ "$BNAME" = "virtexec" ]
  then
          echo Cannot run virtexec directly: NEED a symlink
          exit 0
  fi

  if [ "$FIRST4CHAR" != "virt" ]
  then
          echo Symlink not a virt function
          exit 0
  fi

  list=""
  num=1
  for i in /virtual/*
  do
          if [ ! -d "$i" ]
          then
                  continue
          fi
          if [ "$i" = "/virtual/lost+found" ]
          then
                  continue
          fi
          list="$list $i $num"
          num=`expr $num + 1`
  done

  if [ "$list" = "" ]
  then
          echo No virtual environments exist
          exit 0
  fi

  dialog --clear --title 'Virtexec' --menu Pick 20 70 12 $list 2> /tmp/menu.$$
  if [ "$?" = "0" ]
  then
          newdir=`cat /tmp/menu.$$`
  else
          newdir=""
  fi
  tput clear
  rm -f /tmp/menu.$$

  echo '$Revision: 1.2 $'

  if [ ! -d "$newdir" ]
  then
          echo New directory: $newdir: NOT EXIST
          exit 0
  else
          echo New directory: $newdir
  fi

  echo bname: $BNAME

  echo realbname: $REALBNAME
  if [ "$*" = "" ]
  then
          echo args: none
  else
          echo args: $*
  fi

  echo Changing to $newdir
  cd $newdir

  echo Running program $REALBNAME

  chroot $newdir $REALBNAME $*

  exit 0
  ______________________________________________________________________

  これを実行するには各自のシステムに dialog プログラムがインストールされ
  ている必要があります。注意してください。 (訳注：dialog = シェルスクリ
  プトからダイアログボックスを開くコマンドです。ほとんどのシステムではイ
  ンストールされています)。 virtexecを使うためにシンボリックリンクをはり
  ます。例えば、

  ln -s /usr/bin/virtexec /usr/bin/virtpasswd
  ln -s /usr/bin/virtexec /usr/bin/virtvi
  ln -s /usr/bin/virtexec /usr/bin/virtpico
  ln -s /usr/bin/virtexec /usr/bin/virtemacs
  ln -s /usr/bin/virtexec /usr/bin/virtmailq

  ここでvirtvi、virtpasswd、virtmailq等と入力すればそれぞれviが起動した
  り、ユーザーのパスワードが変更できたり、仮想システム上のメールキューを
  チェックできたりします。必要に応じてもっと多くリンクをはることもできま
  す。しかしプログラムがシェアライブラリ(shared library)を必要とするとき
  は仮想ファイルシステム上になければなりません。バイナリファイルも同様に
  仮想ファイルシステム上になければなりません。

  4.3.  virtfsとvirtexecに関する注意

  著者は全てのスクリプトを/usr/binにインストールしています。仮想ファイル
  システム上に置きたくないものは/usr/localに置いています。スクリプトはコ
  ピーに関してなにもタッチしないようにします。仮想ファイルシステム間でま
  たがらないことが重要な全てのファイルは削除しなくてはいけません。例え
  ば、著者のシステムにはsshがインストールされていますが、プライベートキ
  ー (private key)はどの仮想ファイルシステムからも見えるようにはしたくあ
  りません。そこでvirtfsを実行した後にそれぞれの仮想ファイルシステムから
  プライベートキーを削除しています。 (訳注：sshはSecure Shellのことで
  す。secure authentication, encryption, encrypted X11 connections,
  encrypted TCP/IP forwarding をもったリモートログインプログラムで,適当
  なアーカイブサーバの archives/net/ssh/ディレクトリなどから入手できま
  す)

  またresolv.conf(訳注： DNS情報など /etc/resolv.conf) も変更し他のドメ
  イン名があるファイルは全て移動しています。例えば /etc/hosts や
  /etc/HOSTNAMEなどです。

  virtexecにシンボリックリンクをはっているプログラムは

  o  virtpasswd -- パスワード変更

  o  virtadduser -- ユーザー追加

  o  virtdeluser -- ユーザー削除

  o  virtsmbstatus -- samba status

  o  virtvi -- ファイルの編集

  o  virtmailq -- mailqのチェック

  o  virtnewaliases -- エイリアステーブル再構築

     です。

  5.  DNS

  DNSは普通に設定できます。このシステムの良い点は、全てのサービスにおい
  てマシンが(実は一台にもかかわらず)わかれているかのように振舞うというこ
  とです。 DNSに関するHOWTOは DNS を参照してください。

  6.  Syslog

  6.1.  問題点

  syslogはUNIXシステムで共通して使われるシステムログユーティリティです。
  (訳注：syslog=カーネル(kernel)のメッセージ・リング・バッファーを読んだ
  り消去(clear)したりする)。 syslogはFIFO(First In First Out)と呼ばれる
  スペシャルファイルを開くデーモンです。FIFOはパイプ(pipe)に似たスペシャ
  ルファイルです。 syslogデーモンはリードサイドからのデータを待ち、ライ
  トサイドに書き込むための C関数があります。もしこれらのC関数でプログラ
  ムを書けば出力はsyslogに入ります。

   chroot 環境を使っていて、FIFO /dev/logは仮想環境には存在しないことに
  注意して下さい。これは全ての仮想環境がsyslogへの記録ができないというこ
  とを意味しています。プログラムは新しく作ったものの代わりとして/dev/log
  を使えないので、ファイルを単にコピーすることもできません。

  syslogの特定のバージョンにはudpソケットをFIFOの代わりに使っているもの
  もありますが、これは一般的なことではありません。

  6.2.  解決方法

  syslogは、コマンドラインで指定すれば、異なるFIFOを探します。例えば以下
  のようにします。

  syslog -p /virtual/log

  そして/dev/logを/virtual/logにリンクをはります(シンボリックリンク)。

  ln -sf /virtual/log /dev/log

  つぎに以下のようにしてこのファイルに全ての/dev/logをリンクします (これ
  はハードリンクでシンボリックリンクではないことに注意)。

  ln /virtual/log /virtual/domain.com/dev/log

  上記のvirtfsスクリプトではすでにこれを行っています。/virtualは一つの連
  続したディスクにあり、/dev/logはリンクされているので同じinode 番号かつ
  同じデータを指すことになります。chrootはこれをストップできないので全て
  の仮想/dev/logは機能します。全環境からのメッセージは一つの場所に記録さ
  れます。しかしもしプログラムを書きたくなく、それぞれlog ファイルを分け
  たいという場合は以下のようにして別々にsyslogを使うこともできます。

  syslog -p /virtual/domain1.com/dev/log
  syslog -p /virtual/domain2.com/dev/log

  もっともこうすることはプロセスIDの浪費なのでお奨めしません。このバー
  ジョンのsyslog.initは、不適切な設定がされている場合には起動する度に毎
  回 /dev/log に再リンクしてしまいます。以下、修正したsyslog.initファイ
  ルを挙げておきます。

  ______________________________________________________________________
  #!/bin/sh

  # Source function library.
  . /etc/rc.d/init.d/functions

  case "$1" in
    start)
          echo -n "Starting dev log: "
          ln -sf /virtual/log /dev/log
          echo done
          echo -n "Starting system loggers: "
          daemon syslogd -p /virtual/log
          daemon klogd
          echo
          echo -n "Starting virtual dev log: "
          for i in /virtual/*
          do
                  if [ ! -d "$i" ]
                  then
                          continue
                  fi
                  if [ "$i" = "/virtual/lost+found" ]
                  then
                          continue
                  fi
                  ln -f /virtual/log $i/dev/log
                  echo -n "."
          done
          echo " done"
          touch /var/lock/subsys/syslog
          ;;
    stop)
          echo -n "Shutting down system loggers: "
          killproc syslogd
          killproc klogd
          echo
          rm -f /var/lock/subsys/syslog
          ;;
    *)
          echo "Usage: syslog {start|stop}"
          exit 1
  esac

  exit 0
  ______________________________________________________________________

  一台のディスクに全ての仮想ファイルシステムを置かなくてもよいことに注意
  して下さい。もっともディスク上に仮想ファイルシステムを持つ各パーティ
  ション用のsyslogを実行しなければならないでしょう。

  7.  仮想FTP

  Wu-ftpdも仮想化して使うように設定できます(訳注：「Virtual-wu-ftpd」
  (吉峯 幸郎さん訳)も出ているのでそちらも参照して下さい)。しかし各ドメイ
  ンでパスワードファイルをわけた状態にはできません。例えばもし
   bob@domain1.com と bob@domain2.com の両方がアカウントを必要とした場
  合、どちらか一方をbob2としたりします。つまり違う名前にする必要がありま
  す。各ドメインの仮想ファイルシステムがある状態なのでパスワードファイル
  をわけてしまえばこの問題は解消します。virtnewuserスクリプトと
  virtpasswdスクリプトを上に書いたような方法で作って設定してください。仮
  想ファイルシステムによって各仮想環境上で影響を受けることなくanonymous
  ftp を行うことができます。

  inetd.confにwu-ftpをエントリします。

  ftp stream tcp nowait root /usr/bin/virtuald virtuald /virtual/conf.ftp wu.ftpd -l -a

  8.  仮想Web

  Apacheはそれ自身で仮想ドメインをサポートしています。内部仮想ドメインメ
  カニズムを使うことを著者が推奨しているプログラムです。inetdを通して何
  か実行する時はコストがかかります。この場合、プログラムは実行する毎にス
  タートせねばなりません。つまりwebサービスには不向きな遅い応答であると
  いうことを意味しています。 Apacheは多くのアクセスが生じた時の接続を止
  めるメカニズムも持っています。

  もしinetdを通さずApacheを使い場合はinetd.confファイルに以下の行を追加
  してください。

  www stream tcp nowait www /usr/bin/virtuald \
          virtuald /virtual/conf.www httpd -f /var/www/conf/httpd.conf

  そして /var/www/conf/httpd.confファイル(訳注：環境によって
  httpd.confがある場所は違います)に以下のように明記します。

  ServerType inetd

  デフォルトでは"standalone"を設定しています。あとはシングルドメインで
  使っていた時と同じようにApacheサーバの設定をします。

  これを書いている時点では仮想web HOWTOはありません (訳注：
  「Virtual-Web-HOWTO」が現在は出ています)。しかしこれが出てくるだろうと
  思います。やがてはそのHOWTOを参照してここに書こうと思います。もしまだ
  出てこず、要求が出て来たらApache仮想ホストの設定方法についての章を書く
  つもりです。

  9.  仮想的なMail/Pop

  9.1.  Qmail の注意点

  この章はsendmailのみに関する内容です。qmailの章はHOWTOの次のバージョン
  で追加します(訳注：Qmailに関するマニュアルは「Qmail+MH」などが出ていま
  す)。

  9.2.  問題

  現在、仮想メールのサポートに関する要求はますます増えていま
  す。Sendmailは仮想メールをサポートすると言っていますが、その内容は異な
  るドメインからのメール取り込みのことのようです。メールをどこかにフォワ
  ードさせるということができます。しかしもしローカルマシンにフォワードし
  たりbob@domain1.com、bob@domain2.comにメールが来る場合などでは同じメー
  ルフォルダにたまってしまうでしょう。これは bob宛のメールが実際は違う人
  宛で中身も違うのだから問題です。

  9.3.  悪い解決方法

  ユーザー名に番号を追加(例えばbob1, bob2など)したり、頭に文字を入れて
  dom1bob, dom2bobにしたりすることによってユーザーの一意性(unique)を保証
  することはできます。これを裏で変換するように mailやpop をハック(hack)
  することもできますが汚い(messy)方法です。出ていく方のメールもまたバー
  ナー(ヘッダ)にmaindomain.comがついていて各サブドメインのメールバーナー
  も違ったものにしたいのです。

  9.4.  良い解決方法

  各仮想ファイルシステムに各ドメイン用の/etc/passwdを用意しています。こ
  れはbob@domain1.comとbob@domain2.comが、別々の /etc/passwd上の違うユー
  ザーであり、メールのトラブルはないということになります。このユーザー達
  には自分用のspoolディレクトリが用意されていて、各仮想ファイルシステム
  上のメールフォルダは互いに違うものであることになります。

  しかし、sendmailはちょっとしたソースコードの修正が必要です。
  sendmailは/etc/sendmail.cwと呼ばれるファイルを持っています。これ
  はsendmailが他のホストに転送しないでローカルに配送する全てのホスト名を
  含んでいるファイルです。

  sendmailはマシン上の全デバイスの内部チェックを、ローカルIPでこのリスト
  を初期化するために行います。もし同じマシン上の仮想ドメイン間でメールを
  送る場合、問題が出てきてしまいます。sendmailには他の仮想ドメインがロー
  カルアドレスであり、メールもローカルにスプールするという考えはないので
  す。

  例えばbob@domain1.comさんがfred@domain2.comにメールを送ったとしま
  す。domain1.comのsendmailはdomain2.comがローカルであると判断するの
  でdomain1.comにメールをスプールしてしまい、結果として domain2.comにメ
  ールが届くことはありません。そこでsendmailを修正してやります(著者
  はv8.8.5のsendmailでこれを行い、特に問題はありませ
  ん)。src/main.cの494行辺りを編集します。 sendmailのソースは適当なサイ
  トやディストリビューションCDROMから入手できます。

  vi v8.8.5/src/main.c # Approximately Line 493

  として、

  load_if_names();

  という箇所を

  /* load_if_names(); Commented out since hurts virtual */

  とコメントアウトしてしまいます(訳注：この関数はインターフェースの走査
  と追加名の場所をしめす関数でconf.c line 4399にこの関数自体がありま
  す。IPリストのスキャンなどを行っています)。もし仮想ドメイン間のメール
  送信が必要ならこれを行うだけでよいことに注意して下さい。

  問題は解決されたのですが、メインのイーサネットデバイスeth0は削除されて
  いません。そこで、もし同一マシンの仮想IPからeth0上のIPにメールを送る場
  合はローカルに送られます。著者はダミーIPvirtual1.domain.com
  (10.10.10.157)として使っています。このホストにはメールを送らないのでど
  の仮想ドメインもいりません。これはシステムが大丈夫かどうかチェックする
  ために sshでログインする時に使うIPでもあります。

  /etc/sendmail.cwの編集

  vi /etc/sendmail.cw
  mail.domain1.com
  domain1.com
  domain1
  localhost

  m4を使って/etc/sendmail.cfを好きなように作ります。著者は以下のようなも
  のを使いました。

  divert(0)dnl
  VERSIONID(`@(#)tcpproto.mc      8.5 (Berkeley) 3/23/96')
  OSTYPE(linux)
  FEATURE(redirect)
  FEATURE(always_add_domain)
  FEATURE(use_cw_file)
  FEATURE(local_procmail)
  MAILER(local)
  MAILER(smtp)

  (訳注：m4はUNIXマクロプロセッサで、たいていのシステムに入っています。
  最新バージョンはftp://prep.ai.mit.edu/pub/gnu/から入手できます。m4
  linux.mc > /etc/sendmail.cfなどとして使います。 m4の例
  が/usr/lib/m4-exampleにあります。オプションはm4 --help で調べて下さい)

  /etc/sendmail.cfを仮想ドメイン応答するように編集。

  vi /etc/sendmail.cf # 86行辺りを編集

  #  my official SMTP hostname (defined automatically)
  #Dj$w.Foo.COM
  という箇所があるので、これを

  #  my official SMTP hostname (defined automatically)
  Djdomain1.com
  としておきます。

  sendmailはそれ自身ではそのサービスを始めることができず、inetdを通して
  起動する必要があります。これは役に立つことでもなく起動時間を遅くしてい
  るだけでしょう。読者が高速なサイトを管理しているなら仮想マシン上に他の
  ドメインを占有させるべきではないかもしれません。

   -bd フラグを付けて起動することは決してしないで下さい。 (訳注：このフ
  ラグはsendmailをデーモンとして起動するオプションです。くわしいこと
  はman sendmailして下さい)。また各ドメインで配送していないメールを送り
  出す(queue up)するために sendmail -qと実行する必要があることに注意して
  ください。

  #!/bin/sh

  # Source function library.
  . /etc/rc.d/init.d/functions

  case "$1" in
    start)
          echo -n "Starting sendmail: "
          daemon sendmail -q1h
          echo
          echo -n "Starting virtual sendmail: "
          for i in /virtual/*
          do
                  if [ ! -d "$i" ]
                  then
                          continue
                  fi
                  if [ "$i" = "/virtual/lost+found" ]
                  then
                          continue
                  fi
                  chroot $i sendmail -q1h
                  echo -n "."
          done
          echo " done"
          touch /var/lock/subsys/sendmail
          ;;
    stop)
          echo -n "Stopping sendmail: "
          killproc sendmail
          echo
          rm -f /var/lock/subsys/sendmail
          ;;
    *)
          echo "Usage: sendmail {start|stop}"
          exit 1
  esac

  exit 0

  popは特に何もせずにインストールしてしまいます。virtualdのパートを追加
  した上で inetdのエントリーをすることが必要です。sendmailとpopに関す
  るinetd.confのエントリは、

  pop-3 stream tcp nowait root /usr/bin/virtuald virtuald /virtual/conf.pop in.qpop -s
  smtp stream tcp nowait root /usr/bin/virtuald virtuald /virtual/conf.mail sendmail -bs

  となります。

  10.  その他仮想的にできること

  他のサービスも同じような手順です。

  o  仮想ファイルシステムにバイナリ、ライブラリファイルを追加

  o  /etc/inetd.confの追加

  o  /virtual/conf.serviceを作る

  o  必要に応じて仮想スクリプトを編集する

     sambaパッケージとEudoraを使っての仮想poppassdを試してみました。どち
     らも問題なく動作しています。もしもっと興味があれば仮想sambaのインス
     トール方法についての章も設けたいと考えています。

  11.  まとめ

  以上が必要な作業です。この文書によって人びとの前向きな反応に出会えるこ
  とを期待しています。連絡は Computer Resource Center までお願いいたしま
  す。もし疑問な点やドキュメントのアップデートなどありましたら教えて下さ
  い。今後のHOWTOに追加したいと思います。

  12.  FAQ

  Q1.    どうしてこのFAQについて質問がないのですか？

  A1.    まだだれも質問してないからです。

  (訳注：以上ここまでが原文)

  13.  作業メモ

  13.1.  virtfsについて

  実行すると

  Enter the domain name: domain.com
  Enter leading dir: (Enter for default: /virtual):

  と聞かれます。それぞれ入力して下さい。上の例では以下のようなディレクト
  リが作られ、適当なファイルがそれぞれのディレクトリにコピーされます。

  /virtual/domain.com/
              |- bin
              |- dev
              |- etc
              |- home
              |- lib
              |- proc
              |- sbin
              |- tmp
              |- usr
              |- var
              \-log

  13.2.  その他のエラー

  13.2.1.  /var/log/syslog:

  Dec 22 23:28:46 kaien virtuald[298]: Virtuald Starting: $Revision: 1.2 $
  Dec 22 23:28:46 kaien virtuald[298]: getipaddr: getsockname failed:
                                       Socket opera
  Dec 22 23:28:46 kaien virtuald[298]: getipaddr failed

  ======> ip-aliasが設定されていません。

  Dec 23 00:30:26 kaien virtuald[1132]: Virtuald Starting: $Revision: 1.2 $
  Dec 23 00:30:26 kaien virtuald[1132]: Incoming ip: 192.168.1.1
  Dec 23 00:30:26 kaien virtuald[1132]: iptodir: fopen failed: No such
  file or dir
  Dec 23 00:30:26 kaien virtuald[1132]: iptodir failed

  ======>  /etc/initd.confに設定したconfファイルがありません。

  13.2.2.  FTP

  ftp は /virtual/etc/passwdで設定したユーザーでloginできます。

  例：

  Connected to 192.168.1.4. <=== IP-alias address
  220 kaien FTP server (Version wu-2.4(1) Tue Dec 5 20:51:15 CST 1995) ready.
  Name (192.168.1.4:apple): 331 Password required for hogehoge
  230-No directory! Logging in with home=/
             ===>これはまだ /virtual/home/hogehogeを作っていないから。
  230 User hogehoge logged in.
  Remote system type is UNIX.
  Using binary mode to transfer files.
  ftp> 221 Goodbye.

  13.2.3.  Mail

  13.2.4.  Web

  [訳者 ：    伊佐治  哲 (isaji@mxu.meshnet.or.jp)

  校正 ：    藤原 輝嘉さん  (fujiwara@cim.pe.u-tokyo.ac.jp) ]

