2011.12.22 14:07

NHN Ajax UI4팀 심상민 

웹 페이지의 한계에서 벗어나 실시간으로 상호작용하는 웹 서비스를 만드는 표준 기술인 WebSocket. 그리고 다양한 방식의 실시간 웹 기술을 손쉽게 사용할 수 있는 Socket.io. 이 두 기술이 무엇인지 설명하고 어떻게 사용하는지 간단한 예제로 알아보겠습니다.

  • 웹 소켓(Web Socket)이 있기까지

    1989년 CERN(http://public.web.cern.ch)에서 웹의 역사가 시작되었을 때에는 사용자와의 상호작용은 웹 개발에서 큰 부분을 차지하지 않았다. 그러나 초창기에 연구기관에서 사용하던 웹은 점점 더 일상생활에 파고들었고, PC용 응용 프로그램(Native Application)을 대체할 수 있는 정도까지 되었다. 지금까지의 PC 환경이 이렇게 변화한 것처럼 모바일 환경에서도 앞으로 마찬가지로 변화할 것으로 보인다.

    전형적인 브라우저 렌더링 방식은 HTTP 요청(HTTP Request)에 대한 HTTP 응답(HTTP Response)을 받아서 브라우저의 화면을 깨끗하게 지우고 받은 내용을 새로 표시하는 방식이다. 내용을 지우고 다시 그리면 브라우저의 깜빡임이 생기게 된다. 이러한 깜빡임 없이 원하는 부분만 다시 그리며 실시간으로 사용자와 상호작용하는 방식이 나타나고 사용자와 상호작용하는 웹 서비스를 선호하는 사용자가 증가하면서 RIA(Rich Internet Application) 기술의 발달이 촉진되었다.

    상호작용하는 웹 서비스를 위해 숨겨진 프레임(Hidden Frame)을 이용한 방법이나 Long Polling, Stream 등 다양한 방법을 사용했다. 그러나 이러한 방식은 브라우저가 HTTP 요청를 보내고 웹 서버가 이 요청에 대한 HTTP 응답를 보내는 단방향 메세지 교환 '규칙'을 변경하지 않고 구현한 방식이다. 그렇기 때문에 상호작용하는 웹 페이지를 복잡하고 어려운 코드로 구현해야 했다.

    보다 쉽게 상호작용하는 웹 페이지를 만들려면 브라우저와 웹 서버 사이에 더 자유로운 양방향 메시지 송수신(bi-directional full-duplex communication)이 필요하다. 그래서 HTML5 표준안의 일부로 WebSocket API(이후 WebSocket)가 등장했다.

    122111_0950_WebSocketSo1.png

    그림 1 WebSocket과 일반적인 Ajax Long Polling 방식 비교(이미지 출처: http://java.sys-con.com/node/1315473)

    WebSocket은 그 이름에서 알 수 있듯이 소켓을 이용하여 자유롭게 데이터를 주고 받을 수 있다. 즉 기존의 요청-응답 관계 방식보다 더 쉽게 데이터를 교환할 수 있다.

  • WebSocket 프로토콜

    표준 WebSocket의 API는 W3C에서 관장하고, 프로토콜은 IETF(Internet Engineering Task Force)에서 관장한다. 그리고 WebSocket은 다른 HTTP 요청과 마찬가지로 80번 포트를 통해 웹 서버에 연결한다. HTTP 프로토콜의 버전은 1.1이지만 다음 헤더의 예에서 볼 수 있듯이, Upgrade 헤더를 사용하여 웹 서버에 요청한다. 당연한 이야기겠지만 클라이언트인 브라우저와 마찬가지로 웹 서버도 WebSocket 기능을 지원해야한다.

    1
    2
    3
    GET /... HTTP/1.1
    Upgrade: WebSocket
    Connection: Upgrade

    브라우저는 "Upgrade: WebSocket" 헤더 등과 함께 랜덤하게 생성한 키를 서버에 보낸다. 웹 서버는 이 키를 바탕으로 토큰을 생성한 후 브라우저에 돌려준다. 이런 과정으로 WebSocket 핸드쉐이킹이 이루어진다.

    그 뒤 Protocol Overhead 방식으로 웹 서버와 브라우저가 데이터를 주고 받는다. Protocol Overhead 방식은 여러 TCP 커넥션을 생성하지 않고 하나의 80번 포트 TCP 커넥션을 이용하고, 별도의 헤더 등으로 논리적인 데이터 흐름 단위를 이용하여 여러 개의 커넥션을 맺는 효과를 내는 방식이다.

    이런 방식을 사용하기 때문에 방화벽이 있는 환경에서도 무리 없이 WebSocket을 사용할 수 있다.

  • WebSocket을 지원하는 브라우저와 웹 서버

    클라이언트인 브라우저 중에서는 Chrome, Safari, Firefox, Opera에서 WebSocket을 사용할 수 있으며, 각종 모바일 브라우저에서도 WebSocket을 사용할 수 있다.

    122111_0950_WebSocketSo2.png

    그림 2 WebSocket 지원 여부(이미지 출처: http://caniuse.com)

    Mozilla 계열 브라우저와 Opera에서는 프록시와 관련된 보안 이슈 때문에 WebSocket의 기본 설정을 'disable'로 설정했다. about:config 페이지에서 설정을 변경할 수 있지만 많은 사용자들이 이 조치에 불만을 제기했다. 프록시와 관련된 문제는 Flash나 Java에서도 동일하게 발생하는데 WebSocket만 기본 설정에서 제외했다는 것에 대한 불만이었다. 이러한 의견을 반영한 것인지 Mozilla 재단에서는 Firefox 6.0부터 네임 스페이스를 붙여 MozWebSocket으로 다시 WebSocket을 지원하기 시작했다. 이 사례는 사용자들이 WebSocket에 거는 기대감이 굉장히 크다는 것을 엿볼 수 있는 사례다.

    그러나 WebSocket 프로토콜은 아직 확정된 상태가 아니다. 현재 Draft75, Draft76 등의 이름으로 계속 드래프트 버전이 나오고 있다. 그렇기 때문에 브라우저별로 지원하는 WebSocket 버전도 다르다.

    122111_0950_WebSocketSo3.png

    그림 3 브라우저 별 Web Socket 버전 지원 상황(이미지 출처: http://en.wikipedia.org/wiki/WebSocket)

    웹 서버 중에서는 Apache에서 별도의 모듈을 설치하여 WebSocket을 사용할 수 있다. JEE 환경의 WAS에서는 Jetty, GlassFish에서 WebSocket을 사용할 수 있다. 또한 Node.js에서도 WebSocket을 사용할 수 있다. 그러나 아직 Tomcat은 공식적인 지원 계획을 발표하고 있지 않다.

  • WebSocket API를 사용해 보자

    백문이 불여일견이듯이 백문이 불여일행, 몸으로 익히는 공부가 제일 좋다. 다음의 간단한 예제로 WebSocket API를 구현해 보고 어떻게 활용할 수 있는지 알아보자.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    if ('WebSocket' in window) {
        var oSocket = new WebSocket(“ws://localhost:80”);
     
        oSocket.onmessage = function (e) {
            console.log(e.data);
        };
     
        oSocket.onopen = function (e) {
            console.log(“open”);
        };
     
        oSocket.onclose = function (e) {
            console.log(“close”);
        };
     
        oSocket.send(“message”);
        oSocket.close();
    }

    이 몇줄의 코드만 알고 있어도 WebSocket API를 사용할 수 있다. ws://가 눈에 띌 수도 있을 것 같다. WebSocket 프로토콜을 나타내는 ws://는 URI 스키마(Scheme)를 사용한다. 암호화 소켓은 https://처럼 wss://를 사용한다.

    위의 코드를 실행하면 먼저 new WebSocket() 메서드로 웹서버와 연결한다. 그리고 생성된 WebSocket 인스턴스를 이용하여 소켓에 연결할 때(onopen), 소켓 연결을 종료할 때(onclose), 메시지를 받았을 때(onmessage) 등의 이벤트를 각각 정의할 수 있다. 서버에 메시지를 보내고 싶을 때에는 send() 메서드를 이용한다. 그 외에 WebSocket API에 대한 더 자세한 내용은 http://dev.w3.org/html5/websockets/#the-websocket-interface를 참조한다.

  • 그렇다면 Socket.io는 무엇인가?

    WebSocket은 다가올 미래의 기술이지 아직 인터넷 기업에서 시범적으로라도 써 볼 수 있는 기술이 아니다. WebSocket이 미래의 기술이라면 Socket.io는 현재 바로 사용할 수 있는 기술이다. Socket.io는 JavaScript를 이용하여 브라우저 종류에 상관없이 실시간 웹을 구현할 수 있도록 한 기술이다.

    Guillermo Rauch가 만든 Socket.io는 WebSocket, FlashSocket, AJAX Long Polling, AJAX Multi part Streaming, IFrame, JSONP Polling을 하나의 API로 추상화한 것이다. 즉 브라우저와 웹 서버의 종류와 버전을 파악하여 가장 적합한 기술을 선택하여 사용하는 방식이다. 가령 브라우저에 Flash Plugin v10.0.0 이상(FlashSocket 지원 버전)이 설치되어 있으면 FlashSocket을 사용하고, Flash Plugin이 없으면 AJAX Long Polling 방식을 사용한다.

    개발자가 각 기술을 깊이 이해하지 못하거나 구현 방법을 잘 알지 못해도 사용할 수 있다. Web Socket과 달리 Socket.io는 표준 기술이 아니고 Node.js 모듈로서 Guillermo Rauch가 CTO로 있는 LearnBoost(https://www.learnboost.com)라는 회사의 저작물이며 MIT 라이센스를 가진 오픈소스이다. 현재 Node.js가 아닌 다른 프레임워크에서 Socket.io를 사용할 수 있도록 하는 시도가 있다.

  • Socket.io를 사용해 보자

    Socket.io는 WebSocket과 마찬가지로 브라우저에서는 JavaScript를 사용한다. WebSocket 프로토콜은 IETF에서 관장하는 표준 프로토콜이라서 WebSocket을 지원하는 여러 서버 구현체(Jetty, GlassFish, Node.js, Netty, Grizzly 등)가 있지만 Socket.io는 Node.js 하나 밖에 없다.

    Socket.io를 사용하려면 다음과 같이 NPM(Node Package Management)을 이용하여 Socket.io를 웹 서버에 설치한다.

    1
    npm install socket.io

    설치 후 아래와 같이 서버 스크립트를 작성한다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // 80 포트로 소켓을 연다
    var io = require('socket.io').listen(80);
     
    // connection이 발생할 때 핸들러를 실행한다.
    io.sockets.on('connection', function (socket) {
    // 클라이언트로 news 이벤트를 보낸다.
        socket.emit('news', { hello: 'world' });
     
    // 클라이언트에서 my other event가 발생하면 데이터를 받는다.
    socket.on('my other event', function (data) {
            console.log(data);
        });
    });

    작성한 스크립트를 nohup 등을 이용하여 백그라운드로 실행한다. nohup을 사용하면 hang-up signal이 발생해도 스크립트의 동작이 멈추지 않는다.

    1
    nohup node ./server.js &

    클라이언트는 Socket.io 패키지에 있는 클라이언트 스크립트를 이용하여 아래와 같이 작성한다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    <script src="/socket.io/socket.io.js"></script>
    <script>
    // localhost로 연결한다.
    var socket =
      io.connect('http://localhost');
     
    // 서버에서 news 이벤트가 일어날 때 데이터를 받는다.
    socket.on('news',
      function (data) {
        console.log(data);
      //서버에 my other event 이벤트를 보낸다.
        socket.emit('my other event',
          { my: 'data' });
    });
    </script>

    이로써 Socket.io를 사용할 준비는 모두 끝났다. 브라우저에서 클라이언트 페이지를 열면 클라이언트 콘솔에는 "{ hello : 'world' }"가, 서버 콘솔에는 "{ my : 'data' }"가 출력되는 것을 확인할 수 있을 것이다.

    io.Socket() 메서드를 호출하면 웹 서버(Node.js를 이용하는 웹 서버)와 연결한다. 이때 서버로부터 sessionid 정보와 timeout 정보를 받고, 브라우저의 WebSocket 지원 여부, FlashSocket 지원 여부를 보내고 크로스 도메인 설정 정보 등을 주고 받은 후 적합한 실시간 웹 방식을 선택한다.

    Socket.io를 활용하는 다양한 예제는 http://socket.io/#how-to-use에서 확인할 수 있다.

  • 마치며

    실시간으로 상호작용하는 웹 서비스를 짧은 시간 안에 쉽게 구현할 수 있는 기술은 빠르게 발전하고 있다. 지금보다 훨씬 더 다양하게 상호작용하는 UX가 선보일 것이라는 게 막연한 공상은 아닐 것이다. 웹 소켓이나 Socket.io 모두 현재 발전 중인 기술이다. 이 기술이 발전하는 과정을 지켜보는 것은 큰 즐거움이 될 것이라고 생각한다.


  • 출처 - http://helloworld.naver.com/helloworld/1336


    ===================================================================================


    node.js 유용한 모듈 (8) – socket.io

    본 게시물은 원저자의 허락을 얻어 번역된 것입니다.

    원문 링크 - http://www.catonmat.net/blog/nodejs-modules-socketio/

    1회 연재 – dnode (RPC 라이브러리) 
    2회 연재 – optimist (옵션 파서) 
    3회 연재 – lazy (lazy 리스트 처리) 
    4회 연재 – request (HTTP 스트림 처리) 
    5회 연재 – hashish (해시 처리)
    6회 연재 – read(쉬운 표준 입력 처리)
    7회 연재 – ntwitter(트위터 API)

    이번에 소개할 모듈은 socket.io다. 여러분들 대부분이 socket.io 모듈에 대해서 알고 있을 거라 생각하지만, 몇몇분들이 나에게 socket.io에 대한 기사를 다뤄줄 것을 요청했기 때문에 연재에서 포함시키기로 했다.

    socket.io는 웹소켓 만들고 이를 통해 모든 브라우저에서 실시간 처리가 가능하게끔 해준다. 그것은 또한 빌트인 멀티플렉싱, 수평적 확장, 그리고 자동 JSON  인코딩/디코딩을 제공함으로써 웹소켓의 기능을 향상시켜준다. Socket.io는 LearnBoost의 공동 창업자인 Guillermo Rauch에 의해 작성됐다.

    socket.io는 현재 환경에서 가능한 최상의 실시간 커뮤니케이션 방법을 선택한다. 여기 socket.io가 지원하는 모든 커뮤니케이션 방법 리스트가 있다.

    • WebSocket
    • Adobe® Flash® Socket
    • AJAX long polling
    • AJAX multipart streaming
    • Forever Iframe
    • JSONP Polling

    예를 들어, 만약 여러분이 크롬 브라우저를 사용한다면 socket.io는 웹소켓을 사용할 것이다. 만약 웹 소켓을 지원하지 않는 브라우저를 사용한다면, 플래시 소켓, 롱 폴링 순으로 커뮤니케니션 방법을 설정할 것이다.

    가장 기본적인 socket.io 예제를 살펴보자.

    var io = require('socket.io');
    var express = require('express');
    
    var app = express.createServer()
    var io = io.listen(app);
    
    app.listen(80);
    
    io.sockets.on('connection', function (socket) {
      socket.emit('news', { hello: 'world' });
      socket.on('my other event', function (data) {
        console.log(data);
      });
      socket.on('disconnect', function () {
        console.log('user disconnected');
      });
    });

    이 예제는 아주 훌륭한 express라는 node 웹 프레임워크(express 모듈은 곧 연재에서 다룰 것이다)를 사용하는데, 웹 서버의 포트를 80번으로 설정하고 socket.io를 추가했다.

    socket.io는 새로운 커넥션 연결을 대기하다가 브라우저가 새 커넥션을 생성할 때, 브라우저로 다시 { hello: 'world' }객체를 보내는 news 이벤트를 발생시킨다.

    그것은 또한 my other event와 disconnect의 이벤트 핸들러를 설정한다. 웹 애플리케이션이 이런 이벤트들을 발생시키면, socket.io는  function (data) { console.log(data); } 콜백을 호출하는데 이는 단지 data를 콘솔에 출력하는 역할을 한다.

    아래 코드는 클라이언트 측 코드이다. (브라우저에서 동작)

    <script src="/socket.io/socket.io.js"></script>
    <script>
      var socket = io.connect('http://localhost');
      socket.on('news', function (data) {
        console.log(data);
        socket.emit('my other event', { my: 'data' });
      });
    </script>

    우선 socket.io.js 스크립트를 로드하고, http://localhost 으로 socket.io 커넥션을 생성한다. 이때 socket.io는 브라우저가 지원하는 가장 최선의 커뮤니케이션 방법을 선택한다. 만약 브라우저가 크롬이라면 웹소켓을 사용할 것이다. 그렇지 않다면 위에서 소개한 커뮤니케이션 방법 중에서 플래시 소켓, 롱 폴링 등의 순서로 순차적으로 조사하여 가장 최상의 방법을 선택할 것이다. 그런 다음엔 news 이벤트를 수신 대기하다가, 해당 이벤트가 발생하면 my other event 이벤트를 발생시킨다.

    이런 식으로 여러분은 모든 종류의 실시간 애플리케이션 (가령,  웹 채팅 서버 와 웹 IRC 클라인트)을 개발할 수 있다.

    socket.io는 네임스페이스, volatile 메시지 , 메시지 수신 확인 그리고 메시지 브로드캐스팅 같은 기능도 지원한다. 좀더 자세한 내용은 socket.io 도움말을 살펴보기 바란다.

    npm을 통해 socket.io를 설치할 수 있다.

    npm install socket.io

    Socket.io의 GitHub 사이트: https://github.com/LearnBoost/socket.io.

    아울러 socket.io 기반으로 RPC 함수를 호출했던 dnode (1회 연재)를 살펴보기 바란다.

    If you love these articles, subscribe to my blog for more, follow me on Twitter to find about my adventures, and watch me produce code on GitHub!

    관련 글:

    1. Node.js를 활용하여 웹페이지 긁어오기.
    2. node.js 유용한 모듈 (7) – ntwitter
    3. node.js 유용한 모듈 (6) – read
    4. node.js 유용한 모듈 (5) – hashish
    5. node.js 유용한 모듈 (4) – request
    6. node.js 유용한 모듈 (3) – lazy
    7. node.js 유용한 모듈 (2) – optimist
    8. node.js 유용한 모듈 (1) – dnode
    9. cloud9을 활용한 node.js 프로그래밍
    10. npm 1.0 간단정리


    출처 - http://nodejs-kr.org/insidejs/archives/704


    ===================================================================================



    'Framework & Platform > Node.js' 카테고리의 다른 글

    node.js - 이클립스에서 디버깅  (0) 2012.07.16
    node.js - npm 1.0 사용하기  (0) 2012.07.16
    node.js - CentOS에서 설치(install in linux)  (0) 2012.07.03
    node.js - 소개 3  (0) 2012.06.07
    node.js - 소개 2  (0) 2012.06.07
    Posted by linuxism
    ,

    php - mail 함수

    Development/PHP 2012. 7. 11. 15:03


    이번시간에는 메일을 보내는 명령어 mail() 에 대해 배워보도록 하겠습니다.

    mail() 함수는 이메일을 보내는 함수로 기본적인 사용방법은 다음과 같습니다.

    mail(받는이메일주소, 제목, 내용)

    위 형식으로 사용을 하면 메일이 보내집니다.

    그런데 보내는 사람 같은것은 어디에 적어줘야할까요?

    mail 함수의 인자에서 내용 다음에 메일의 header 를 넣어줍니다.

    mail(받는이메일주소, 제목, 내용, header)

    이 header 에 메일의 언어셋이나 보내는 사람 참조등의 여러 정보를 넣을수 있습니다.

    아래 예문을 보면서 설명드리겠습니다.(PHP 함수 검색에 나오는 예제입니다.)
    <?php
    // 받는 사람이 여럿일 경우 , 로 늘려준다.
    $to  = 'aidan@example.com' . ', '; // note the comma
    $to .= 'wez@example.com';

    // 제목
    $subject = 'Birthday Reminders for August';

    // 내용
    $message = '
    <html>
    <head>
      <title>Birthday Reminders for August</title>
    </head>
    <body>
      <p>Here are the birthdays upcoming in August!</p>
      <table>
        <tr>
          <th>Person</th><th>Day</th><th>Month</th><th>Year</th>
        </tr>
        <tr>
          <td>Joe</td><td>3rd</td><td>August</td><td>1970</td>
        </tr>
        <tr>
          <td>Sally</td><td>17th</td><td>August</td><td>1973</td>
        </tr>
      </table>
    </body>
    </html>
    ';

    // HTML 내용을 메일로 보낼때는 Content-type을 설정해야한다
    $headers  = 'MIME-Version: 1.0' . "\r\n";
    $headers .= 'Content-type: text/html; charset=euc-kr' . "\r\n";

    // 추가 header

    // 받는사람 표시
    $headers .= 'To: Mary <mary@example.com>, Kelly <kelly@example.com>' . "\r\n";


    // 보내는사람
    $headers .= 'From: Birthday Reminder <birthday@example.com>' . "\r\n";

    // 참조
    $headers .= 'Cc: birthdayarchive@example.com' . "\r\n";

    // 숨은참조
    $headers .= 'Bcc: birthdaycheck@example.com' . "\r\n";

    // 메일 보내기
    mail($to, $subject, $message, $headers);
    ?>

    주석을 보시면 알겠지만 위와 같은 방식으로 메일을 보낼 내용과 header 등을 설정해서 보낼수가 있습니다.

    그러면 다음시간부터 예약 프로그램에 대해 배워보도록 하겠습니다.


    출처 - http://handsome.pe.kr/105








    메일 함수 
    <?php 
    mail('recipient@toodtood.nettoodtoodone@toodtood.netmetoo@toodtood.net', 
    '제목', 
    '내용이다.',  
    "To: The Receiver <recipient@toodtood.net>\\n" . 
    "From: The Sender <sender@toodtood.net>\\n" .  
    "cc: Interested <toodtoodone@toodtood.net>\\n" .    
    "Bcc: Me Too <metoo@toodtood.net>\\n" .    
    "X-Mailer: PHP 4.x"); 
    ?> 


    출처 - http://www.nuno21.net/bbs/board.php?bo_table=php&wr_id=16&sfl=&stx=&sst=wr_good&sod=desc&sop=and&page=5








    메일 함수를 보시면 
    mail('받는사람','제목','내용','기타추가헤더'); 

    이렇게 4개의 인자를 전달해 주잖아요.. 
    $to = 'mail@mail.com'; 
    $add = 'one@mail.com,two@mail.com,three@mail.com,four@mail.com'; 

    $to 는 받는 사람 그리고, $add 는 같이 받을 사람들메일 주소.. 

    mail($to,"메일 제목","참조메일연습","Cc:$addn"); 
    혹은 
    mail($to,"메일 제목","참조메일연습","Bcc:$addn"); 
    이렇게 메일헤더에 Cc 혹은 Bcc 를 추가해 주면 여러명이 같은메일을 
    받아볼수 있습니다.. 

    Cc 와 Bcc 의 차이점은 

    Cc 로 전송할 경우 아웃룩 익스프레스에서 보면 받는사람 주소란에 
    모든 이메일주소가 표시됩니다..더불어 회신을 하게 되면 
    그 메일 주소에 있는 모든 이에게 전달 되겠죠.. 

    때문에 가급적이면 Bcc (아웃룩에선 숨은참조라 불립니다) 의 형태로 
    전송해 주는게 좋습니다... 

    [출처] 마루아라










    'Development > PHP' 카테고리의 다른 글

    php - include vs require  (0) 2013.01.08
    php - date() 오류  (0) 2012.07.21
    PHP Framework - CodeIgniter  (0) 2012.05.07
    PHP framework 종류  (0) 2012.05.07
    php 오류해석기  (0) 2012.02.03
    Posted by linuxism
    ,


    초보자를 위한 Exim4 설치하기

    작성자 coolseed@hotmail.com, http://koov.net 이 문서는 http://debianusers.org/DebianWiki/wiki.php/exim4 의 문서가 원본입니다.

    1 초보자를 위한 Exim4 설치하기

    1.1 목적

    데비안 설치시 기본적으로 설치되는 Exim4 MTA를 초보자도 완벽하게 설치 할수 있도록 하는것이 이 문서의 목적이다. 이 문서는 아래와 같은 조건을 기본으로 한다.

    • 해당 서버가 메일서버로 동작한다.
    • 계정은 시스템 계정을 기본으로 한다.(가상유저 지원안함)
    • ?POP3서비스를 제공한다.
    • 기본적으로 모든 릴레이는 막혀 있으며 SMTP인증을 통하여 메일을 발송한다.

    가정조건

    • 문서에 나와있는 호스트의 이름은 mail.foobar.com 이다.
    • 이 호스트는 domain.net의 메일도 수신하고 있다.

    1.2 준비사항 #

    우선 아래의 패키지들을 설치하도록 한다.

    • exim4
    • qpopper
    • sasl2-bin
    ''$ apt-get install exim4 qpopper sasl2-bin''

    1.3 기본설정 #

    • /etc/exim4 디렉토리에 들어가면 아래의 파일이 들어있다.
    ''$ ls
      exim4.conf.template  passwd.client  update-exim4.conf.conf''
    • 우선 update-exim4.conf.conf 파일을 수정한다.
    " # /etc/exim4/update-exim4.conf.conf
    #
    # Edit this file and /etc/mailname by hand and execute update-exim4.conf
    # yourself or use 'dpkg-reconfigure exim4-config'
    #
    # Please note that this is _not_ a dpkg-conffile and that automatic changes
    # to this file might happen. The code handling this will honor your local
    # changes, so this is usually fine, but will break local schemes that mess
    # around with multiple versions of the file.
    #
    # update-exim4.conf uses this file to determine variable values to replace
    # the DEBCONFsomethingDEBCONF strings in the configuration template files.
    #
    # Most settings found in here do have corresponding questions in the
    # Debconf configuration, but not all of them.
    #
    # This is a Debian specific file
    dc_eximconfig_configtype='internet'
    dc_other_hostnames='foobar.com:domain.net' # FQDN 이부분에 메일도메인을 적어준다. 여러개의 도메인을 운영중이라면 : 로 구분한다.
    dc_local_interfaces='' # 이부분은 접속허용가능호스트를 적어준다. 기본적으로 모든 메일을 받아야 하므로 비워둔다.
    dc_readhost=''
    dc_relay_domains='' # 다른곳으로 릴레이 시킬 도메인을 적는부분이다. 비워둔다.
    dc_minimaldns='false'
    dc_relay_nets=''
    dc_smarthost=''
    CFILEMODE='644'
    dc_use_split_config='false'
    dc_hide_mailname=''
    dc_mailname_in_oh='true' ''
    • 자 위와같이 수정한후 아래의 명령을 실행하면 exim config파일이 자동으로 생성된다.
    ''$ update-exim4.conf -d /etc/exim4 -o /etc/exim4/exim4.conf''
    ''$ ls /etc/exim4
    ./  ../  conf.d/  exim4.conf  exim4.conf.template  passwd.client  update-exim4.conf.conf''

    여기까지가 기본적인 Exim4의 설정단계이다. 이렇게 하면 기본적으로 메일을 받는것은 문제 없이 될것이다. 아울러 ?POP3또한 qpopper패키지를 설치하게 되면 별다른 설정없이 ?POP3서비스를 이용할수 있다.

    1.4 SMTP인증

    이제 메일을 보내는 작업을 하게 될것이다. 일반적으로 모든 메일서버는 릴레이를 제한하여야 하는데 그 이유는 무분별한 스팸메일을 막기 위해서 이다. 그러나 가끔 개념이 없는 관리자는 이런것을 무시하고 메일서버를 대충 설치하는 경우 해당 서버가 스패머들에의해 엄청난양의 스팸메일을 뿌리거나 네트워크 대역폭을 낭비하는 경우가 생긴다. 따라서 서버의 릴레이를 제한하고 인증된 사용자만이 메일을 보낼수 있도록 셋팅하도록 한다.

    맨처음에 설치한 패키지중 sasl2-bin 패키지가 이러한 SMTP인증을 해주는 데몬 패키지 이다.

    그 첫번째 단계로 우선 Exim4의 설정을 SMTP인증으로 변경하는 작업을 해보도록 하자

    • /etc/exim4/exim4.conf.template 파일을 연다.
    ''$ vi /etc/exim4/exim4.conf.template''

    위의 화일을 열어 아래와같이 주석처리된 부분을 제거한다.

    ''.......상단생략.......
    # Authenticate against local passwords using sasl2-bin
    # Requires exim_uid to be a member of sasl group, see README.SMTP-AUTH
    plain_saslauthd_server:
    driver = plaintext
    public_name = PLAIN
    server_condition = ${if saslauthd{{$2}{$3}}{1}{0}}
    server_set_id = $2
    server_prompts = :
    #   .ifndef AUTH_SERVER_ALLOW_NOTLS_PASSWORDS
    #   server_advertise_condition = ${if eq{$tls_cipher}{}{}{*}}
    #   .endif
    #
    login_saslauthd_server:
    driver = plaintext
    public_name = LOGIN
    server_prompts = "Username:: : Password::"
    # don't send system passwords over unencrypted connections
    #   server_advertise_condition = ${if eq{$tls_cipher}{}{0}{1}}
    server_condition = ${if saslauthd{{$1}{$2}}{1}{0}}
    server_set_id = $1
    #   .ifndef AUTH_SERVER_ALLOW_NOTLS_PASSWORDS
    #   server_advertise_condition = ${if eq{$tls_cipher}{}{}{*}}
    #   .endif
    #
    ## 이하 모든 아래내용은 주석처리 하도록 한다. ##''
    • 위와같이 exim4.conf.template화일을 수정한후
    ''$ update-exim4.conf -d /etc/exim4 -o /etc/exim4/exim4.conf''

    명령을 다시 해주어 exim4.conf화일을 재생성한다.

    • 그리고 /etc/group 파일을 열어 Debian-exim유저를 sasl그룹에 포함시켜준다.
    ''root:x:0:
    daemon:x:1:
    bin:x:2:
    sys:x:3:
    adm:x:4:
    tty:x:5:
    disk:x:6:
    lp:x:7:
    mail:x:8:
    news:x:9:
    uucp:x:10:
    man:x:12:
    proxy:x:13:
    kmem:x:15:
    dialout:x:20:
    fax:x:21:
    voice:x:22:
    cdrom:x:24:hal
    floppy:x:25:hal
    tape:x:26:
    sudo:x:27:
    audio:x:29:
    dip:x:30:
    www-data:x:33:
    backup:x:34:
    operator:x:37:
    list:x:38:
    irc:x:39:
    src:x:40:
    gnats:x:41:
    shadow:x:42:
    utmp:x:43:
    video:x:44:
    sasl:x:45:Debian-exim           # 여기에 추가시켜준다.
    plugdev:x:46:
    staff:x:50:
    games:x:60:
    users:x:100:
    nogroup:x:65534:
    crontab:x:101:
    Debian-exim:x:102:
    ssh:x:103:
    messagebus:x:104:
    dirmngr:x:105:
    hal:x:106:
    camera:x:107:
    scanner:x:108:
    saned:x:109:
    gdm:x:110: ''
    • sasl 데몬을 기동하기 위해 아래의 파일을 수정한다.
    ''$ vi /etc/default/saslauthd''
    ''# This needs to be uncommented before saslauthd will be run automatically
    # START=yes
    # You must specify the authentication mechanisms you wish to use.
    # This defaults to "pam" for PAM support, but may also include
    # "shadow" or "sasldb", like this:
    # MECHANISMS="pam shadow"
    START="yes"  # 데몬을 가동하기 위해 추가한다.
    MECHANISMS="pam shadow" # 기본적인 password방식은 shadow이므로 shadow만 있어도 상관 없다.''
    • 이제 exim4와 sasl데몬을 재시작 하도록 한다.
     ''$ /etc/init.d/saslauthd restart ''
    ''Stopping SASL Authentication Daemon: saslauthd.
     Starting SASL Authentication Daemon: saslauthd.''
    ''$ /etc/init.d/exim4 restart
     Restarting MTA: exim4.''
    • 마지막으로 모든 설정이 제대로 되었는지 확인하기 위해 메일이 잘 오가는지 테스트 해보도록 한다.
    • 아울러 릴레이가 제대로 막혀 있는지 확인또한 철저히 하여 불필요한 스팸메일을 발송하지 못하도록 한다.

    1.4.1 릴레이 테스트 #

    릴레이 테스트는 아래의 페이지에서 간단하게 할 수 있다. http://people.kldp.org/~eunjea/relay-test.php

    1.5 마무리 #

    이상으로 Exim4의 가장 기본적인 설정을 마무리하도록 한다. 기타 문서에 대한 교정이나 내용의 문의사항은 아래로 연락바랍니다. Email & MSN : coolseed@hotmail.com


    Eunjea's Home Page

    relay test

    자신의 메일 서버가 오픈 릴레이인지 확인하는 방법은 다음과 같이 아주 간단합니다 (웹에서 테스트 해볼 수 있습니다).

    일단 릴레이가 허용되지 말아야할 ip를 가진 컴퓨터에서 메일 서버의 25번 smtp포트로 접근합니다. 굵게 표시된 곳이 제가 입력한 것입니다. rcpt to에는 메일 수신자를 입력하는데 릴레이를 허용하거나, 메일 서버가 받아들일 도메인이 아닌데도 그대로 ok 가 떨어지면 릴레이가 열려있는 상태입니다. 다음과 비슷한 메세지가 나오면서 거부되어야 정상입니다.

    $ telnet foobar.com 25
    Trying 192.168.1.1...
    Connected to foobar.com.
    Escape character is '^]'.
    220 foobar.com ESMTP
    helo foobar.com
    250 foobar.com
    mail from: test@test.com
    250 ok
    rcpt to: test@test.com
    553 sorry, that domain isn't allowed relay (#5.7.1)
    제발 다시 한번 당부하지만, 메일서버의 릴레이를 오픈해 놓지 말아주십시요. 아무 생각없이 릴레이를 열어놓은 메일 서버는 스패머에게 이용되어 자신뿐만 아니라 다른 사람에게도 피해를 주며 결국에는 국가적 망신입니다.

    "뭐 잠깐 열어 놓는데 별일 있겠어?" 하는 생각을 하시나요? 제 칵테일 패치에 릴레이 시도하면 로그를 남기도록 한 부분이 있는데 패치를 적용한 뒤에 qmail 로그를 확인해보면 얼마나 많은 스패머들이 오픈 릴레이를 노리고 있는지 알 수 있습니다.

    [ xxx@silver ]grep "Attempted relay" /var/log/qmail/smtp/current | wc -l
         54


    출처 - http://ubuntu.or.kr/wiki/doku.php?id=%EC%B4%88%EB%B3%B4%EC%9E%90%EB%A5%BC_%EC%9C%84%ED%95%9C_exim4

    'System > Common' 카테고리의 다른 글

    명령어 옵션(option) 플래그(flag) 클러스터(cluster)  (0) 2012.07.24
    ssh 일반 계정 접속 제한  (0) 2012.07.16
    libpcap  (0) 2012.07.09
    DNS - named 설정 점검  (0) 2012.05.14
    Cloud Computing  (0) 2012.04.27
    Posted by linuxism
    ,