´ÙÀ½ ÀÌÀü Â÷·Ê

9. °¡»ó ¸ÞÀÏ/POP ¼­¹ö

9.1 ¹®Á¦

°¡»ó ¸ÞÀÏÀÇ Áö¿ø¿¡ ´ëÇÑ ¿äûÀº ³¯·Î Áõ°¡ÇÏ°í ÀÖ´Ù. ¼¾µå¸ÞÀÏÀº °¡»ó ¸ÞÀÏ ½Ã½ºÅÛÀ» Áö¿øÇÑ´Ù°í ¸»ÇÑ´Ù. ÇÏÁö¸¸ ±×°ÍÀÌ Áö¿øÇÏ´Â °ÍÀº ¿©·¯ µµ¸ÞÀο¡¼­ ¸ÞÀϵéÀ» °Ë»çÇÏ´Â ±â´ÉÀÌ´Ù. ±× ÈÄ ´ç½ÅÀº ƯÁ¤ ¸ÞÀÏÀ» ´Ù¸¥ °÷À¸·Î Æ÷¿öµù ÇÒ ¼ö ÀÖ´Ù. ÇÏÁö¸¸, ·ÎÄà ¸Ó½ÅÀ¸·Î Æ÷¿öµùµÈ ¸ÞÀÏÀ̳ª bob@domain1.com°ú bob@domain2.com¿¡ ¿Â ¸ÞÀÏÀº °°Àº ¸ÞÀÏ Æú´õ¿¡ µé¾î°¡ ÀÖ°Ô µÈ´Ù. À̵éÀÌ ¼­·Î ´Ù¸¥ ¸ÞÀÏÀÌ°í µÎ¸íÀÇ bobÀÌ ¼­·Î ´Ù¸¥ »ç¶÷ÀÏ ¶§¿¡´Â ¹®Á¦°¡ µÈ´Ù.

9.2 ÇØ°áÃ¥

´ç½ÅÀº °¢°¢ÀÇ »ç¿ëÀÚ À̸§¿¡ ¼ýÀÚ¸¦ ºÙ¿©¼­, ȤÀº Á¤ÇØÁø ¹®ÀÚ¸¦ ¾Õ¿¡ ºÙ¿©¼­ Áߺ¹µÇ´Â »ç¿ëÀÚ°¡ ¾Æ´ÔÀ» ±¸ºÐÇÒ ¼ö ÀÖ´Â ¹æ¹ýÀÌ ÀÖ´Ù.(¿¹: bob1, bob2 ȤÀº dom1bob, dom2bob) ´ç½ÅÀº ¶ÇÇÑ mailÀ̳ª pop¸¦ °íÃļ­ ÀÌ·± ÀüȯÀÌ º¸ÀÌÁö ¾Ê°Ô ÀÌ·ç¾îÁú ¼ö ÀÖ°Ô ¸¸µé¼öµµ ÀÖ´Ù. ¿ÜºÎ·Î ³ª°¡´Â ¸ÞÀÏ ¿ª½Ã ÀÌ·± ½ÄÀ¸·Î °¢°¢ÀÇ ¼­ºêµµ¸ÞÀο¡ ´ëÇؼ­ ±× À̸§À» »ç¿ëÇÏ°Ô ¸¸µé ¼ö ÀÖ´Ù.

³»°¡ °¡Áø ÇØ°áÃ¥Àº µÎ°¡ÁöÀÌ´Ù. Çϳª´Â sendmailÀ» ÀÌ¿ëÇÏ´Â °ÍÀÌ°í, ´Ù¸¥ Çϳª´Â QmailÀ» ÀÌ¿ëÇÏ´Â °ÍÀÌ´Ù. SendmailÀ» ÀÌ¿ëÇÑ ÇØ°áÃ¥Àº ÀÌ ±â´ÉÀ» Ãß°¡ÇÏ¿© sendmail À» ¼³Ä¡ÇÏ´Â °ÍÀÌ´Ù. ÇÏÁö¸¸, ÀÌ ¹æ¹ýÀº ¸ðµç Á¦¾àÀÌ sendmail¿¡ ¶È°°ÀÌ Àû¿ëµÈ´Ù. ÀÌ ¹æ¹ýÀº ¶ÇÇÑ °¢°¢ÀÇ µµ¸ÞÀο¡ ´ëÇؼ­ Çϳª¾¿ÀÇ sendmailÀÌ queue mode·Î ½ÇÇàµÇ¾î¾ß ÇÑ´Ù´Â ´ÜÁ¡À» °¡Áö°í ÀÖ´Ù. 50°³ ȤÀº ±× ÀÌ»óÀÇ senmail queue ÇÁ·Î¼¼½º´Â ¸Å½Ã°£ ½Ã½ºÅÛÀ» ¹Ù»Ú°Ô ¸¸µé °ÍÀÌ´Ù.

QmailÀ» ÀÌ¿ëÇÏ´Â ÇØ°áÃ¥Àº ¿©·¯°³ÀÇ QmailÀ» ÇÊ¿ä·ÎÇÏÁöµµ ¾Ê°í, ÇϳªÀÇ queue µð·ºÅ丮 ÀÌ¿Ü¿¡¼­µµ ½ÇÇà °¡´ÉÇÏ´Ù. ÀÌ ¹æ¹ýÀº QmailÀÌ virtuald¿Í ¸ÂÁö ¾Ê±â ¶§¹®¿¡ Ãß°¡ÀûÀÎ ÇÁ·Î±×·¥À» ÇÊ¿ä·Î ÇÑ´Ù. ³­ sendmailÀ» ÀÌ¿ëÇÑ ¹æ¹ý ¿ª½Ã ºñ½ÁÇÑ °úÁ¤À» ÇÊ¿ä·Î ÇÑ´Ù°í ¹Ï´Â´Ù. ÇÏÁö¸¸, QmailÀº ÀÌ °æ¿ì º¸´Ù ÇØ°áÃ¥À» À§ÇÑ Áغñ°¡ Àß µÇ¾îÀÖ´Â °Í °°´Ù.

³»°¡ ÇÑ ÇÁ·Î±×·¥ÀÌ ´Ù¸¥ ÇÁ·Î±×·¥º¸´Ù ³´´Ù´Â °ÍÀ» º¸ÁõÇÏ´Â °ÍÀº ¾Æ´Ï´Ù. Sendmail ¼³Ä¡´Â º¸´Ù Á÷Á¢ÀûÀÎ ÇØ°áÃ¥ÀÌÁö¸¸, QmailÀ» ÀÌ¿ëÇÏ´Â ¹æ¹ýÀÌ ¾Æ¸¶ ´õ °­·ÂÇÑ ÇØ°áÃ¥ÀÌ µÉ ¼ö ÀÖ´Ù.

9.3 SendmailÀ» ÀÌ¿ëÇÑ ÇØ°áÃ¥

¼Ò°³

°¢°¢ÀÇ °¡»ó ÆÄÀÏ ½Ã½ºÅÛÀº ÀÚ½ÅÀÇ /etc/passwd ¾È¿¡ µµ¸ÞÀÎÀ» ¼³Á¤ÇÑ´Ù. ÀÌ°ÍÀº bob@domain1.com°ú bob@domain2.comÀÌ ¼­·Î ´Ù¸¥ »ç¿ëÀÚ·Î /etc/passwd ¾È¿¡ µî·ÏµÇ¾î ÀÖ´Ù´Â °ÍÀ» ÀǹÌÇϸç, ¸ÞÀÏ ÇÁ·Î±×·¥¿¡¼­ µÎ »ç¿ëÀÚ¸¦ ±¸ºÐÇÏ´Â µ¥¿¡´Â ¾Æ¹« ¹®Á¦°¡ ¾ø´Ù. ¶ÇÇÑ ÀڽŸ¸ÀÇ ½ºÇ® µð·ºÅ丮 ¿ª½Ã °¡Áö°í ÀÖÀ¸¹Ç·Î ´Ù¸¥ °¡»ó ÆÄÀÏ ½Ã½ºÅÛ¿¡ ´ëÇؼ­ ¼­·Î ´Ù¸¥ ÆÄÀϷμ­ ¸ÞÀÏ Æú´õ°¡ Á¸ÀçÇÏ°Ô µÈ´Ù.

Sendmail ¼³Á¤ ÆÄÀÏ ¸¸µé±â

ÀϹÝÀûÀÎ /etc/sendmail.cf ¸¦ m4¸¦ ÅëÇØ ¸¸µç´Ù. ³»°¡ »ç¿ëÇÏ´Â °ÍÀº ´ÙÀ½°ú °°´Ù:

divert(0)
VERSIONID(`tcpproto.mc')
OSTYPE(linux)
FEATURE(redirect)
FEATURE(always_add_domain)
FEATURE(use_cw_file)
FEATURE(local_procmail)
MAILER(local)
MAILER(smtp)

Sendmail ¼³Á¤ÆÄÀÏ ÆíÁýÇϱâ

/virtual/domain1.com/etc/sendmail.cf ¸¦ °¡»ó µµ¸ÞÀο¡ ¹ÝÀÀÇÒ ¼ö ÀÖµµ·Ï ÆíÁýÇÑ´Ù:

vi /virtual/domain1.com/etc/sendmail.cf # Approximately Line 86 
It should say:

#Dj$w.Foo.COM

Replace it with:

Djdomain1.com

Sendmail Áö¿ª ¹è´Þ

/virtual/domain1.com/etc/sendmail.cw¸¦ Áö¿ª È£½ºÆ®À̸§À¸·Î ÆíÁýÇÑ´Ù.

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

°¡»ó µµ¸ÞÀÎ »çÀÌÀÇ Sendmail : The Hack (PRE8.8.6)

ÇÏÁö¸¸, 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¿¡¼­ Å×½ºÆ®Çغ» °á°ú ¾Æ¹« ¹®Á¦°¡ ¾ø¾ú´Ù.)

vi v8.8.5/src/main.c # Approximately Line 494
It should say:

load_if_names();

Replace it with:

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

¸¸¾à °¡»ó µµ¸ÞÀÎ »çÀÌ¿¡¼­ ¸ÞÀÏÀ» ÁÖ°í¹ÞÀ» ÇÊ¿ä°¡ ÀÖÀ» °æ¿ì¿¡¸¸ ÀÌ ¼³Á¤À» ÀÌ¿ëÇ϶ó. (¾Æ¸¶ ´ëºÎºÐÀÇ °æ¿ì ±×·¯ÇÏ°ÚÁö¸¸)

ÀÌ°ÍÀº ¹®Á¦Á¡À» ÇØ°áÇÒ °ÍÀÌ´Ù. ÇÏÁö¸¸, ÁÖµÈ ÀÌ´õ³Ý ÀåÄ¡ÀÎ eth0´Â ¾ø¾îÁöÁö ¾Ê´Â´Ù. µû¶ó¼­, ¸¸¾à ´ç½ÅÀÌ °¡»ó IP¿¡¼­ eth0·Î ¸ÞÀÏÀ» º¸³»°Ô µÇ¸é ÀÌ°ÍÀº ·ÎÄ÷Π¹è´ÞÀÌ µÉ °ÍÀÌ´Ù. µû¶ó¼­ ³ª´Â ÀÌ°ÍÀ» ´õ¹Ì(dummy) IPÀÎ virtual1.maindomain.com(10.10.10.157)·Î ÀÌ¿ëÇÑ´Ù. ³­ Àý´ë ÀÌ È£½ºÆ®·Î ¸ÞÀÏÀ» º¸³»Áö ¾ÊÀ¸¸ç, ¹°·Ð ±× °¡»ó µµ¸ÞÀÎÀ¸·Îµµ ¸ÞÀÏÀº °¡Áö ¾Ê´Â´Ù. ÀÌ ¹æ¹ýÀº ¶ÇÇÑ ³»°¡ ssh¸¦ »ç¿ëÇÏ´Â IP¸¦ °¡Áø ½Ã½ºÅÛÀÌ Á¤»óÀûÀÎÁö¸¦ È®ÀÎÇÏ´Â ¹æ¹ýÀ̱⵵ ÇÏ´Ù.

°¡»ó µµ¸ÞÀÎ »çÀÌÀÇ Sendmail : SendmailÀÇ »õ·Î¿î ±â´É (POST8.8.6)

Sendmail V8.8.6ºÎÅÍ´Â Ãß°¡ÀûÀÎ ³×Æ®¿öÅ© ÀÎÅÍÆäÀ̽ºÀÇ ºñ»ç¿ë žÀç(disable loading)¿¡ ´ëÇÑ »õ·Î¿î ¿É¼ÇÀÌ »ý°å´Ù. µû¶ó¼­ Äڵ带 ¹Ù²Ü ÇÊ¿ä´Â ¾ø°Ô µÇ¾ú´Âµ¥, ÀÌ°ÍÀ» DontProbeInterfaces¶ó ÇÑ´Ù.

/virtual/domain1.com/etc/sendmail.cf¸¦ ÆíÁýÇ϶ó.

vi /virtual/domain1.com/etc/sendmail.cf # Add the line
O DontProbeInterfaces=True

Sendmail.init

SendmailÀº µ¶¸³ÀûÀ¸·Î ½ÇÇàÀÌ ºÒ°¡´ÉÇÏ°í Ç×»ó inetd¸¦ ÅëÇؼ­ ½ÇÇàµÇ°Ô µÈ´Ù. ÀÌ ¹æ¹ýÀº ºñÈ¿À²ÀûÀÌ°í ½ÃÀÛÇÏ´Â µ¥ ½Ã°£ÀÌ °É¸®°ÚÁö¸¸, ¸¸¾à ´ç½ÅÀÌ ¿î¿µÇÏ´Â »çÀÌÆ®°¡ ÀÌ·± Á¡ÀÌ ¹®Á¦°¡ µÉ Á¤µµ·Î ³×Æ®¿öÅ©°¡ ºó¹øÇÏ´Ù¸é ÇϳªÀÇ ½Ã½ºÅÛ¿¡¼­ °¡»óÀÇ ¿©·¯ µµ¸ÞÀÎÀ» °°ÀÌ »ç¿ëÇÏ´Â °ÍÀº ÁÁÀº ¹æ¹ýÀÌ ¾Æ´Ï´Ù. -bd Ç÷¢(flag)°ú °°ÀÌ »ç¿ëÇÏÁö ¾Êµµ·Ï ÁÖÀÇÇ϶ó. ¶ÇÇÑ °¢°¢ÀÇ µµ¸ÞÀο¡ ´ëÇؼ­ sendmail -q À» ½ÇÇàÇÏ¿© ¹è´ÞµÇÁö ¾ÊÀº ¸ÞÀϵ鿡 ´ëÇÑ Å¥ ÀÛ¾÷À» °¡´ÉÇÏ°Ô ÇÏ´Â °Íµµ ÀØÁö ¸»¶ó. »õ·Î¿î sendmail.init ÆÄÀÏÀº ´ÙÀ½°ú °°´Ù:

#!/bin/sh

. /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

Inetd ¼³Á¤

Pop´Â ´Ù¸¥ ¿µÇâ¾øÀÌ Á¤»óÀûÀ¸·Î ¼³Ä¡µÉ °ÍÀÌ´Ù. ´ÜÁö inetdÀÇ ¿£Æ®¸®¿¡¼­ ÀÌ Ç×À» °¡»óÀÇ Æ÷Æ®¿Í ÇÔ²² °í·ÁÇÒ ÇÊ¿ä°¡ ÀÖ´Ù. inetd.conf ¿£Æ®¸®¿¡¼­ sendmail°ú pop¿¡ ´ëÇÑ °ÍÀº ´ÙÀ½°ú °°´Ù:

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

9.4 QmailÀ» ÀÌ¿ëÇÑ ¹æ¹ý

¼Ò°³

ÀÌ ¹æ¹ýÀº qmail-localÀÇ ¹è´Þ ½Ã½ºÅÛÀ» Â÷¿ëÇϱ⠶§¹®¿¡, °¡»óÀÇ È¨ µð·ºÅ丮 ¾ÈÀÇ .qmail ÆÄÀÏÀº ÀÛµ¿ÇÏÁö ¾Ê°Ô µÈ´Ù. ÇÏÁö¸¸, °¢°¢ÀÇ µµ¸ÞÀÎÀº µµ¸ÞÀÎ ÀüüÀÇ ¾Ù¸®¾î½Ì (aliasing)À» ÅëÁ¦ÇÏ´Â µµ¸ÞÀÎ ÁÖÀÎ »ç¿ëÀÚ(domain master user)¸¦ °®´Â´Ù. µÎ °³ÀÇ ¿ÜºÎ ÇÁ·Î±×·¥µéÀÌ µµ¸ÞÀÎ ÁÖÀÎÀÇ .qmail-default ÆÄÀÏÀ» »ç¿ëÇÒ ¼ö ÀÖ°Ô ÇØÁÙ °ÍÀÌ´Ù. °¢°¢ÀÇ µµ¸ÞÀο¡ ¸ÞÀÏÀÌ ¹è´ÞµÇ±â À§Çؼ­´Â ÀÌµé µÎ ÇÁ·Î±×·¥À» ÅëÇØ¾ß ÇÒ °ÍÀÌ´Ù.

µÎ °³ÀÇ ÇÁ·Î±×·¥ÀÌ ÇÊ¿äÇѵ¥, ±× °¡¿îµ¥ Çϳª´Â setuid root »óÅ·Π½ÇÇàµÈ´Ù. ÀÌ ÀÛÀº ÇÁ·Î±×·¥Àº ÀÏ´Ü ÇÁ·Î¼¼½ºÀÇ ¼ÒÀ¯±ÇÀ» root°¡ ¾Æ´Ñ »ç¿ëÀÚ·Î ¹Ù²Ù°í, ´Ù½Ã µÎ¹ø° ÇÁ·Î±×·¥À» ½ÇÇà½ÃŲ´Ù. °¡±î¿î º¸¾È °ü·Ã »çÀÌÆ®¿¡¼­ ¿Ö ÀÌ·± ¹æ½ÄÀÌ ÇÊ¿äÇÑÁö¸¦ Âü°íÇÒ ¼ö ÀÖÀ» °ÍÀÌ´Ù.

ÀÌ ¹æ¹ýÀº virtuald¸¦ »ç¿ëÇÒ Çʿ伺ÀÌ º°·Î ¾ø´Ù. QmailÀº ¸Å¿ì À¯µ¿ÀûÀÎ ÇÁ·Î±×·¥À̶ó ÀϹÝÀûÀÎ virtuald ¼³Á¤À» ÇÊ¿ä·ÎÇÏÁö ¾Ê´Â´Ù. QmailÀº ¸ÞÀÏÀÇ ¹è´ÞÀ» À§ÇØ ÇÁ·Î±×·¥µéÀÇ ¿¬°áÀ» ÀÌ¿ëÇϵµ·Ï ¼³°èµÇ¾ú´Ù. ÀÌ µðÀÚÀÎÀº °¡»ó ¼­ºñ½º ºÎºÐÀ» Qmail ¹è´Þ ÇÁ·Î¼¼½º Áß°£¿¡ ½±°Ô »ðÀÔÇÒ ¼ö ÀÖ°Ô ÇÑ´Ù.

´ç½ÅÀÌ QmailÀ» »ç¿ëÇÑ´Ù¸é ¸ÞÀÎ ¼­¹öÀÇ µµ¸ÞÀο¡¼­ ¹«Á¦ÇÑÀÇ µµ¸ÞÀÎ À̸§À» ¸¸µé¾î ³¾ ¼ö ÀÖ´Ù. ÀÌ°ÍÀº °¢°¢ÀÇ µµ¸ÞÀο¡ ´ëÇØ ºÐ¸®µÈ QmailÀ» °®´Â °ÍÀÌ ¾Æ´Ï±â ¶§¹®¿¡ °¡´ÉÇÏ´Ù. ¸ÞÀÏ Å¬¶óÀ̾ðÆ® ÇÁ·Î±×·¥(À¯µµ¶ó³ª elm, mutt µî)¿¡¼­ ´ç½ÅÀÌ ÀÓÀÇ·Î ¸¸µé¾î³½ µµ¸ÞÀÎ À̸§À» ÀνÄÇÏ´Â °ÍÀ» È®ÀÎÇØ º¸¶ó.

°¡»ó µµ¸ÞÀÎ ¼³Á¤

QmailÀº ´ç½ÅÀÌ Á¦°øÇÏ´Â °¢°¢ÀÇ °¡»ó µµ¸ÞÀÎÀ» ¹Þ¾ÆµéÀÏ ¼ö ÀÖµµ·Ï ¼³Á¤µÇ¾î¾ß ÇÑ´Ù. ¾Æ·¡ÀÇ ¸í·É¾îµéÀ» ¼öÇàÇ϶ó.

echo "domain1.com:domain1" >> /var/qmail/control/virtualdomains

µµ¸ÞÀÎÀÇ ÁÖÀÎ(Domain Master User) ¼³Á¤

¸ÞÀÎ /etc/passwd ÆÄÀÏ¿¡ domain1ÀÇ »ç¿ëÀÚµéÀ» Ãß°¡ÇÑ´Ù. ³ª´Â /bin/false ¼ÐÀ» ¸¸µé¾î µµ¸ÞÀÎ ÁÖÀÎ(the domain master)ÀÌ ·Î±×ÀÎÇÏÁö ¸øÇÏ°Ô ¸¸µé¾ú´Ù. µµ¸ÞÀÎ ÁÖÀÎÀº domain1ÀÇ .qmail ÆÄÀϵéÀ» Ãß°¡ÇÒ ¼ö ÀÖ°í, µµ¸ÞÀÎÀÇ ¸ðµç ¸ÞÀϵéÀº ÀÌ °èÁ¤À» ÅëÇÏ¿© ¹ß¼ÛµÈ´Ù. »ç¿ëÀÚ À̸§Àº ¿©´ü ÀÚ¸®±îÁö °¡´ÉÇÏ¸ç µµ¸ÞÀÎ À̸§Àº ´õ ±æ¾îÁö ¼ö ÀÖ´Ù´Â °ÍÀ» ÁÖÀÇÇϱ⠹ٶõ´Ù. ³ª¸ÓÁö ¹®ÀÚµéÀº ¹«½ÃµÈ´Ù. ÀÌ°ÍÀº domain12¶ó´Â »ç¿ëÀÚ¿Í domain123À̶ó´Â »ç¿ëÀÚ°¡ °°Àº »ç¿ëÀÚ·Î ÀνĵDZ⠶§¹®¿¡ QmailÀÌ È¥µ¿ÇÒ ¼ö ÀÖ´Ù´Â °ÍÀ» ÀǹÌÇÑ´Ù. µû¶ó¼­ µµ¸ÞÀÎ ÁÖÀÎ À̸§ °áÁ¤¿¡ ÁÖÀǸ¦ ±â¿ïÀ̱⠹ٶõ´Ù.

´ÙÀ½°ú °°Àº ÀýÂ÷¸¦ ÅëÇÏ¿© µµ¸ÞÀÎ ÁÖÀÎÀÇ .qmail ÆÄÀÏÀ» ¸¸µéÀÚ. ´Ù¸¥ ½Ã½ºÅÛ ¾Ù¸®¾î½º - ¿¹¸¦ µé¸é À¥¸¶½ºÅͳª È£½ºÆ®¸¶½ºÅÍ- °¡ ÀÌ ÁöÁ¡¿¡ Ãß°¡µÈ´Ù.

echo "user@domain1.com" > /home/d/domain1/.qmail-mailer-daemon
echo "user@domain1.com" > /home/d/domain1/.qmail-postmaster
echo "user@domain1.com" > /home/d/domain1/.qmail-root

µµ¸ÞÀÎ ÁÖÀÎÀÇ .qmail-default ÆÄÀÏÀ» ¸¸µéÀÚ. ÀÌ°ÍÀº ¸ðµç ¸ÞÀÏÀ» °¡»óÀÇ µµ¸ÞÀÎÀ¸·Î °É·¯ÁÖ°Ô µÉ °ÍÀÌ´Ù.

echo "| /usr/local/bin/virtmailfilter" > /home/d/domain1/.qmail-default

Tcpserver

QmailÀº Maildir Çü½ÄÀ» Áö¿øÇϴ Ưº°ÇÑ popÀ» ÇÊ¿ä·Î ÇÑ´Ù. ÀÌ pop ÇÁ·Î±×·¥ ¶ÇÇÑ °¡»ó ½Ã½ºÅÛ¿¡ ¸Â°Ô µÇ¾î¾ß ÇÑ´Ù. QmailÀÇ ÀúÀÚ´Â tcpserver(inetd ´ë¿ë)¸¦ Qmail°ú ÇÔ²² »ç¿ëÇÒ °ÍÀ» ±ÇÇϴµ¥, ³ªÀÇ ¿¹Á¦¿¡¼­µµ inetd ´ë½Å¿¡ tcpserver¸¦ »ç¿ëÇÏ¿´´Ù.

Tcpserver´Â ¼³Á¤ ÆÄÀÏÀ» ÇÊ¿ä·Î ÇÏÁö ¾Ê´Â´Ù. ¸ðµç Á¤º¸´Â ¸í·ÉÇà¿¡¼­ ÁÖ¾îÁö°Ô µÈ´Ù. ¿©±â ¸ÞÀÏ µ¥¸ó°ú popper¸¦ »ç¿ëÇϱâ À§ÇÑ tcpserver.initÀÌ ÀÖ´Ù.

#!/bin/sh

. /etc/rc.d/init.d/functions

QMAILDUSER=`grep qmaild /etc/passwd | cut -d: -f3`
QMAILDGROUP=`grep qmaild /etc/passwd | cut -d: -f4`

# See how we were called.
case "$1" in
  start)
        echo -n "Starting tcpserver: "
        tcpserver -u 0 -g 0 0 pop-3 /usr/local/bin/virtuald \
                /virtual/conf.pop qmail-popup virt.domain1.com \
                /bin/checkpassword /bin/qmail-pop3d Maildir &
        echo -n "pop "  
        tcpserver -u $QMAILDUSER -g $QMAILDGROUP 0 smtp \
                /var/qmail/bin/qmail-smtpd &
        echo -n "qmail "
        echo
        touch /var/lock/subsys/tcpserver
        ;;
  stop)
        echo -n "Stopping tcpserver: "
        killall -TERM tcpserver 
        echo -n "killing "
        echo 
        rm -f /var/lock/subsys/tcpserver
        ;;
  *)
        echo "Usage: tcpserver {start|stop}"
        exit 1
esac

exit 0

Qmail.init

´ç½ÅÀº Á¦°øµÇ´Â Ç¥ÁØ Qmail Ãʱ⠽ºÅ©¸³Æ®¸¦ ¹Ù·Î »ç¿ëÇÒ ¼ö ÀÖ´Ù. QmailÀº ÀÌ°ÍÀ» ¾î¶»°Ô ¼³Á¤ÇØ¾ß ÇÏ´ÂÁö¿¡ ´ëÇØ »ó´çÈ÷ ÁÁÀº ¹®¼­¿Í ÇÔ²² ¹èÆ÷µÈ´Ù.

¼Ò½º(Source)

Qmail·Î °¡»ó ¸ÞÀÏ ¼­ºñ½º¸¦ ±¸ÃàÇϱâ À§Çؼ­´Â µÎ°³ÀÇ ¼­·Î ´Ù¸¥ ÇÁ·Î±×·¥ÀÌ ÇÊ¿äÇÏ´Ù. Çϳª´Â virtmailfilterÀÌ°í, ´Ù¸¥ Çϳª´Â virtmaildeliveryÀÌ´Ù. ¿©±â virtmailfilter¿¡ ´ëÇÑ C ¼Ò½º Äڵ尡 ÀÖ´Ù. ÀÌ ÇÁ·Î±×·¥Àº /usr/local/bin¿¡ 4750ÀÇ ¼ÒÀ¯±ÇÀ» °¡Áö°í, root ¼ÒÀ¯, nofiles ±×·ìÀ¸·Î ¼³Ä¡µÇ¾î¾ß ÇÑ´Ù.

#include <sys/wait.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <pwd.h>

#define VIRTPRE                 "/virtual"

#define VIRTPWFILE              "etc/passwd"
#define VIRTDELIVERY            "/usr/local/bin/virtmaildelivery"
#define VIRTDELIVERY0           "virtmaildelivery"

#define PERM                    100
#define TEMP                    111
#define BUFSIZE                 8192

int main(int argc,char **argv)
{
        char *username,*usernameptr,*domain,*domainptr,*homedir;
        char virtpath[BUFSIZE];
        struct passwd *p;
        FILE *fppw;
        int status;
        gid_t gid;
        pid_t pid;

        if (!(username=getenv("EXT")))
        {
                fprintf(stdout,"environment variable EXT not set\n");
                exit(TEMP);
        }

        for(usernameptr=username;*usernameptr;usernameptr++)
        {
                *usernameptr=tolower(*usernameptr);
        }

        if (!(domain=getenv("HOST")))
        {
                fprintf(stdout,"environment variable HOST not set\n");
                exit(TEMP);
        }

        for(domainptr=domain;*domainptr;domainptr++)
        {
                if (*domainptr=='.' && *(domainptr+1)=='.')
                {
                        fprintf(stdout,"environment variable HOST has ..\n");
                        exit(TEMP);
                }
                if (*domainptr=='/')
                {
                        fprintf(stdout,"environment variable HOST has /\n");
                        exit(TEMP);
                }

                *domainptr=tolower(*domainptr);
        }

        for(domainptr=domain;;)
        {
                snprintf(virtpath,BUFSIZE,"%s/%s",VIRTPRE,domainptr);
                if (chdir(virtpath)>=0)
                        break;

                if (!(domainptr=strchr(domainptr,'.')))
                {
                        fprintf(stdout,"domain failed: %s\n",domain);
                        exit(TEMP);
                }

                domainptr++;
        }

        if (!(fppw=fopen(VIRTPWFILE,"r+")))
        {
                fprintf(stdout,"fopen failed: %s\n",VIRTPWFILE);
                exit(TEMP);
        }

        while((p=fgetpwent(fppw))!=NULL)
        {
                if (!strcmp(p->pw_name,username))
                        break;
        }

        if (!p)
        {
                fprintf(stdout,"user %s: not exist\n",username);
                exit(PERM);
        }

        if (fclose(fppw)==EOF)
        {
                fprintf(stdout,"fclose failed\n");
                exit(TEMP);
        }

        gid=p->pw_gid;
        homedir=p->pw_dir;

        if (setgid(gid)<0 || setuid(p->pw_uid)<0)
        {
                fprintf(stdout,"setuid/setgid failed\n");
                exit(TEMP);
        }

        switch(pid=fork())
        {
                case -1:
                        fprintf(stdout,"fork failed\n");
                        exit(TEMP);
                case 0:
                        if (execl(VIRTDELIVERY,VIRTDELIVERY0,username,homedir,NULL)<0)
                        {
                                fprintf(stdout,"execl failed\n");
                                exit(TEMP);
                        }
                default:
                        if (wait(&status)<0)
                        {
                                fprintf(stdout,"wait failed\n");
                                exit(TEMP);
                        }
                        if (!WIFEXITED(status))
                        {
                                fprintf(stdout,"child did not exit normally\n");
                                exit(TEMP);
                        }
                        break;
        }

        exit(WEXITSTATUS(status));
}

¼Ò½º(Source)

¿©±â¿¡´Â virtmaildelivery¿¡ ´ëÇÑ C ¼Ò½º Äڵ尡 ÀÖ´Ù. ÀÌ°ÍÀº /usr/local/bin¿¡ 0755ÀÇ ¼ÒÀ¯±ÇÀ¸·Î, ¼ÒÀ¯ÀÚ¿Í ±×·ì ¸ðµÎ root·Î ¼³Ä¡µÇ¾î¾ß ÇÑ´Ù.

#include <sys/stat.h>
#include <sys/file.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <time.h>

#define TEMP                    111
#define BUFSIZE                 8192
#define ATTEMPTS                10

int main(int argc,char **argv)
{
        char *user,*homedir,*dtline,*rpline,buffer[BUFSIZE],*p,mail[BUFSIZE];
        char maildir[BUFSIZE],newmaildir[BUFSIZE],host[BUFSIZE];
        int fd,n,nl,i,retval;
        struct stat statp;
        time_t thetime;
        pid_t pid;
        FILE *fp;

        retval=0;

        if (!argv[1])
        {
                fprintf(stdout,"invalid arguments: need username\n");
                exit(TEMP);
        }

        user=argv[1];

        if (!argv[2])
        {
                fprintf(stdout,"invalid arguments: need home directory\n");
                exit(TEMP);
        }

        homedir=argv[2];

        if (!(dtline=getenv("DTLINE")))
        {
                fprintf(stdout,"environment variable DTLINE not set\n");
                exit(TEMP);
        }

        if (!(rpline=getenv("RPLINE")))
        {
                fprintf(stdout,"environment variable RPLINE not set\n");
                exit(TEMP);
        }

        while (*homedir=='/')
                homedir++;
        snprintf(maildir,BUFSIZE,"%s/Maildir",homedir);
        if (chdir(maildir)<0)
        {
                fprintf(stdout,"chdir failed: %s\n",maildir);
                exit(TEMP);
        }

        time(&thetime);
        pid=getpid();
        if (gethostname(host,BUFSIZE)<0)
        {
                fprintf(stdout,"gethostname failed\n");
                exit(TEMP);
        }

        for(i=0;i<ATTEMPTS;i++)
        {
                snprintf(mail,BUFSIZE,"tmp/%u.%d.%s",thetime,pid,host);
                errno=0;
                stat(mail,&statp);
                if (errno==ENOENT)
                        break;

                sleep(2);
                time(&thetime);
        }
        if (i>=ATTEMPTS)
        {
                fprintf(stdout,"could not create %s\n",mail);
                exit(TEMP);
        }

        if (!(fp=fopen(mail,"w+")))
        {
                fprintf(stdout,"fopen failed: %s\n",mail);
                retval=TEMP; goto unlinkit;
        }

        fd=fileno(fp);

        if (fprintf(fp,"%s",rpline)<0)
        {
                fprintf(stdout,"fprintf failed\n");
                retval=TEMP; goto unlinkit;
        }

        if (fprintf(fp,"%s",dtline)<0)
        {
                fprintf(stdout,"fprintf failed\n");
                retval=TEMP; goto unlinkit;
        }

        while(fgets(buffer,BUFSIZE,stdin))
        {
                for(p=buffer;*p=='>';p++)
                        ;

                if (!strncmp(p,"From ",5))
                {
                        if (fputc('>',fp)<0)
                        {
                                fprintf(stdout,"fputc failed\n");
                                retval=TEMP; goto unlinkit;
                        }
                }

                if (fprintf(fp,"%s",buffer)<0)
                {
                        fprintf(stdout,"fprintf failed\n");
                        retval=TEMP; goto unlinkit;
                }
        }

        p=buffer+strlen(buffer);
        nl=2;
        if (*p=='\n')
                nl=1;

        for(n=0;n<nl;n++)
        {
                if (fputc('\n',fp)<0)
                {
                        fprintf(stdout,"fputc failed\n");
                        retval=TEMP; goto unlinkit;
                }
        }

        if (fsync(fd)<0)
        {
                fprintf(stdout,"fsync failed\n");
                retval=TEMP; goto unlinkit;
        }

        if (fclose(fp)==EOF)
        {
                fprintf(stdout,"fclose failed\n");
                retval=TEMP; goto unlinkit;
        }

        snprintf(newmaildir,BUFSIZE,"new/%u.%d.%s",thetime,pid,host);
        if (link(mail,newmaildir)<0)
        {
                fprintf(stdout,"link failed: %s %s\n",mail,newmaildir);
                retval=TEMP; goto unlinkit;
        }

unlinkit:
        if (unlink(mail)<0)
        {
                fprintf(stdout,"unlink failed: %s\n",mail);
                retval=TEMP;
        }

        exit(retval);
}

9.5 °¨»ç (Acknowledgement)

Qmail¿¡ ÀÇÇÑ ÇØ°áÃ¥À» °¡´ÉÇÏ°Ô µµ¿òÀ» ÁØ Vicente Gonzalez (vince@nycrc.net) ¿¡°Ô °¨»çÇÑ´Ù. ¾Æ¸¶ Vince¿¡°Ô °¨»çÀÇ ¸ÞÀÏ Á¤µµ´Â º¸³¾ ¼ö ÀÖ°ÚÁö¸¸, Qmail¿¡ ´ëÇÑ °ÍÀ» Æ÷ÇÔÇÏ¿© ÀÌ HOWTO¿¡ Æ÷ÇÔµÈ ³»¿ëÀÇ Áú¹®°ú ÀÇ°ßÀº ¸ðµÎ ³ª¿¡°Ô º¸³»µµ·Ï Ç϶ó.


´ÙÀ½ ÀÌÀü Â÷·Ê