<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>SW 개발이 좋은 사람</title>
    <link>https://forest71.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Tue, 19 May 2026 03:03:32 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>forest71</managingEditor>
    <item>
      <title>&amp;gt;&amp;gt;&amp;gt; 블로그 주요 내용 &amp;lt;&amp;lt;&amp;lt;</title>
      <link>https://forest71.tistory.com/notice/223</link>
      <description>&lt;p&gt;&lt;b&gt;&lt;span&gt;챗봇&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;- &lt;a href=&quot;https://forest71.tistory.com/205&quot;&gt;5분만에 둘러보는 챗봇 만들기 - Dialogflow&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span&gt;메일 서버&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://forest71.tistory.com/216&quot;&gt;- Apache James 메일 서버 구축&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;- &lt;a href=&quot;https://forest71.tistory.com/220&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;스팸&amp;nbsp;메일&amp;nbsp;서버&amp;nbsp;구축&amp;nbsp;-&amp;nbsp;SpamAssassin&amp;nbsp;&amp;amp;&amp;nbsp;Postfix&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span&gt;검색 엔진&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;- &lt;a href=&quot;http://forest71.tistory.com/151&quot;&gt;Spring + SolrJ + Solr (Lucene) 기반 게시판: 초급&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;- &lt;a href=&quot;https://forest71.tistory.com/200&quot;&gt;Solr 예제 분석: 초급&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;- &lt;a href=&quot;https://forest71.tistory.com/208&quot;&gt;Solr 실전 예제 구축: 중급&lt;br /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;- &lt;a href=&quot;https://forest71.tistory.com/207&quot;&gt;Elastcsearch &lt;/a&gt;&lt;a href=&quot;https://forest71.tistory.com/207&quot;&gt;실전 예제 구축: 중급&lt;br /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;a href=&quot;http://forest71.tistory.com/category/Java/%EA%B2%8C%EC%8B%9C%ED%8C%90%EA%B8%B0%EB%B3%B8&quot;&gt;&lt;span&gt;게시판 (Java)&lt;/span&gt;&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;- Spring 4 + MyBatis 3 + MariaDB&lt;/p&gt;
&lt;p&gt;- &lt;a href=&quot;http://forest71.tistory.com/category/Java/%EA%B2%8C%EC%8B%9C%ED%8C%90%201&quot;&gt;게시판 1단계 ~ 4단계: 초급&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span&gt;&lt;a href=&quot;http://forest71.tistory.com/category/Java/%EA%B2%8C%EC%8B%9C%ED%8C%90%205:%20%EB%8C%93%EA%B8%80&quot;&gt;- 게시판 4단계 이상: 중급 이상&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;- &lt;a href=&quot;http://forest71.tistory.com/category/Java/%EA%B2%8C%EC%8B%9C%ED%8C%90%20%EA%B8%B0%ED%83%80:%20%ED%92%88%EC%A7%88%20%EB%93%B1&quot;&gt;품질 관리 예제&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;a href=&quot;http://forest71.tistory.com/category/Java/JPetStore&quot;&gt;&lt;span&gt;JPetStore(Java)&lt;/span&gt;&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;- Spring 4 + MyBatis 3+ HSQLDB + ETC&lt;/p&gt;
&lt;p&gt;- 다양한 Java 관련 기술을 적용한 쇼핑몰 예제&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;a href=&quot;http://forest71.tistory.com/78&quot;&gt;&lt;span&gt;프로젝트 9&lt;/span&gt;&lt;/a&gt;&lt;/b&gt;&lt;b&gt;&lt;a href=&quot;http://forest71.tistory.com/78&quot;&gt;&lt;span&gt; (Java)&lt;/span&gt;&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;- Spring 4 + MyBatis 3 + MariaDB&lt;/p&gt;
&lt;p&gt;- 실제 프로젝트 템플릿, 중급 이상&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;a href=&quot;http://forest71.tistory.com/93&quot;&gt;&lt;span&gt;과제 관리 시스템(PMS 9)&lt;/span&gt;&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;- Spring 4 + MyBatis 3 + MariaDB&lt;/p&gt;
&lt;p&gt;- Project 9을 응용한 예제, 중급 이상&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span&gt;&lt;a href=&quot;http://forest71.tistory.com/category/Java/PMS9&quot;&gt;&lt;span&gt;★&lt;/span&gt;&lt;/a&gt;&lt;a href=&quot;http://forest71.tistory.com/category/Java/PMS9&quot;&gt;&lt;span&gt; 개발 과정: 쉽게 개발하는 방법 정리&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;a href=&quot;http://forest71.tistory.com/163&quot;&gt;&lt;span&gt;그룹웨어 (Groupware 9)&lt;/span&gt;&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;- Spring 4 + MyBatis 3 + MariaDB&lt;/p&gt;
&lt;p&gt;- Project 9을 응용한 예제, 초중급 연습용&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;a href=&quot;http://forest71.tistory.com/category/Database/SQL%20%EC%97%B0%EC%8A%B5&quot;&gt;&lt;span&gt;데이터 베이스(MariaDB)&lt;/span&gt;&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;- SQL 실습 4(SubQuery): 초급&lt;/p&gt;
&lt;p&gt;- SQL 연습 이후: 중급 이상&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span&gt;Node.JS&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;- 기초: &lt;a href=&quot;http://forest71.tistory.com/142&quot;&gt;게시판 만들기&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;- &lt;a href=&quot;http://forest71.tistory.com/147&quot;&gt;nineBatis (9batis)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;- &lt;a href=&quot;http://forest71.tistory.com/category/Node.js/Angular%20JS&quot;&gt;기초: Angular 간단 게시판 &lt;/a&gt;&lt;/p&gt;
&lt;p&gt;- &lt;a href=&quot;http://forest71.tistory.com/165&quot;&gt;기초: Firebase 기반 간단 게시판&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;- &lt;a href=&quot;http://forest71.tistory.com/186&quot;&gt;응용: Firebase 기반 메신저 앱 - DirectTalk9 (Web과 PC 버전)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;- &lt;a href=&quot;https://forest71.tistory.com/195&quot;&gt;응용: 우리동네, 아이랑 놀곳. Node(Express) + MariaDB&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;- &lt;a href=&quot;https://forest71.tistory.com/211&quot;&gt;화상 채팅 예제로 익히는 WebRTC&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span&gt;React&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;- &lt;a href=&quot;http://forest71.tistory.com/183&quot;&gt;기초: React 게시판(CRUD) 만들기&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;- &lt;a href=&quot;http://forest71.tistory.com/184&quot;&gt;기초: React + Redux 게시판(CRUD) 만들기&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;- &lt;a href=&quot;http://forest71.tistory.com/189&quot;&gt;기초: React(Redux) + Firebase 게시판(CRUD) 만들기&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span&gt;자바스크립트&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;- &lt;a href=&quot;http://forest71.tistory.com/129&quot;&gt;기초: 테이블 정렬(table sorting)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;- &lt;a href=&quot;http://forest71.tistory.com/132&quot;&gt;기초: 테이블 컬럼 이동(Drag and Drop Table Columns)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;- &lt;a href=&quot;http://forest71.tistory.com/70&quot;&gt;guupload&lt;/a&gt;: 파일 업로드 라이브러리&lt;/p&gt;
&lt;p&gt;- &lt;a href=&quot;http://forest71.tistory.com/category/JavaScript/NicEdit&quot;&gt;웹에디터(NicEdit)로 배우는 자바스크립트 객체지향 프로그래밍&lt;/a&gt;: 중급 이상&lt;/p&gt;
&lt;p&gt;- &lt;a href=&quot;http://forest71.tistory.com/category/JavaScript/TreeGrid&quot;&gt;TreeGrid&lt;/a&gt;: 초급 이상&lt;/p&gt;
&lt;p&gt;- &lt;a href=&quot;http://forest71.tistory.com/category/JavaScript/%EC%95%84%EB%82%A0%EB%A1%9C%EA%B7%B8%20%EC%8B%9C%EA%B3%84&quot;&gt;아날로그 시계&lt;/a&gt;(Canvas, SVG, D3): 초급 이상&lt;/p&gt;
&lt;p&gt;- &lt;a href=&quot;http://forest71.tistory.com/113&quot;&gt;CD9: Chart Design Tool for C3 (D3)&lt;br /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;- &lt;a href=&quot;http://forest71.tistory.com/110&quot;&gt;D3&lt;/a&gt;&lt;a href=&quot;http://forest71.tistory.com/110&quot;&gt; 기반 차트 제작&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;- &lt;a href=&quot;http://forest71.tistory.com/133&quot;&gt;두개의 테트리스 (Tetris)&lt;/a&gt;: 초급 이상&lt;/p&gt;
&lt;p&gt;- &lt;a href=&quot;http://forest71.tistory.com/156&quot;&gt;이미지 편집기(PaintWeb) 사용법&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://forest71.tistory.com/214&quot;&gt;-&amp;nbsp;모바일 전용 자바스크립트 이미지 편집기 - ImageEditor9&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span&gt;Android&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;- 기초: &lt;a href=&quot;http://forest71.tistory.com/159&quot;&gt;Android로 계산기 만들기&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;- &lt;a href=&quot;http://forest71.tistory.com/172&quot;&gt;Firebase 기반 메신저&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;- &lt;a href=&quot;http://forest71.tistory.com/175&quot;&gt;예제 분석 1: Firebase realtime database&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;- &lt;a href=&quot;https://forest71.tistory.com/185?category=686350&quot;&gt;Android Immortal Service (죽지않는 서비스) 구현&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <author>forest71</author>
      <guid isPermaLink="true">https://forest71.tistory.com/notice/223</guid>
      <pubDate>Sun, 17 Jan 2021 12:37:10 +0900</pubDate>
    </item>
    <item>
      <title>5. Apache James 메일 서버 - 스팸 필터</title>
      <link>https://forest71.tistory.com/221</link>
      <description>&lt;p&gt;메일 서버를 운영하면, 어떻게 아는지 몰라도 매일 매일 많은 스팸 메일들을 수신하게 된다.&lt;br /&gt;&lt;br /&gt;이 스팸 메일들을 차단하기 위해 &lt;a href=&quot;https://forest71.tistory.com/220&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;스팸 서버를 별도로 구축하기도&lt;/a&gt; 하지만, 메일 서버에 스팸 필터를 설치하여 구현할 수도 있다.&lt;/p&gt;
&lt;p&gt;앞서서 &lt;a href=&quot;https://forest71.tistory.com/220&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;SpamAssassin을 이용하여 스팸 서버를 구축&lt;/a&gt;하는 것을 정리하였고&lt;/p&gt;
&lt;p&gt;여기에서는 SpamAssassin을 Apache James 메일 서버의 스팸 필터로 사용하는 2 가지 방법을 정리한다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;
&lt;p style=&quot;text-align: center;&quot;&gt;메일 관련 내용들&lt;/p&gt;
&lt;p&gt;1. &lt;a href=&quot;https://forest71.tistory.com/216&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;메일 서버 구축: Apache James&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;2. &lt;a href=&quot;https://forest71.tistory.com/220&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;스팸 메일 서버 구축: Postfix &amp;amp; Apache SpamAssassin &lt;/a&gt;&lt;/p&gt;
&lt;p&gt;3. 메일 서버와 스팸 필터: Apache James &amp;amp; SpamAssassin&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;먼저, SpamAssassin을 다음 명령어로 설치한다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;사용하는 리눅스에 따라서 설치하는 명령어만 다를 뿐 나머지는 동일하다 (CentOS를 기준).&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; CentOS &amp;gt; sudo yum install spamassassin&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Ubuntu &amp;gt; sudo apt-get install spamassassin&lt;/p&gt;
&lt;p&gt;좀 더 상세한 설치는 &lt;a href=&quot;https://forest71.tistory.com/220&quot;&gt;스팸 서버 구축&lt;/a&gt;에 정리한 인터넷 자료를(url) 참고 하면 된다.&lt;/p&gt;
&lt;p&gt;SpamAssassin을 설치하고, SpamAssassin 설정(local.cf) 파일을 다음과 같이 수정한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CentOS &amp;gt; vi /etc/mail/spamassassin/local.cf&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Ubuntu &amp;gt; vi &lt;span&gt;/etc/spamassassin/local.cf&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;required_hits&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;2&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;report_safe&amp;nbsp;0&lt;br /&gt;rewrite_header&amp;nbsp;Subject&amp;nbsp;[SPAM]&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;SpamAssassin은 지정되거나 학습된 규칙에 의해서 메일을 평가해서 점수로 환산하고, 지정된 값(required_hits) 이상이면 스팸으로 표시한다.&lt;/p&gt;
&lt;p&gt;위 설정외에도 다양한 설정을 할 수 있는데, 설정에 대한 상세한 내용은 &lt;a href=&quot;https://www.auctionpro.co.kr/?product=146&amp;amp;paged=77&quot;&gt;이 사이트에&lt;/a&gt; 정리된 내용을 참고하면 된다.&lt;/p&gt;
&lt;p&gt;&lt;u&gt;기본 값은 5인데, 이렇게 지정되면 테스트하기 어렵기 때문에 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;2&lt;/b&gt;&lt;/span&gt;으로 수정한다.&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;수정내용을 반영하기 위해서 SpamAssassin을 재가동 한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;gt; sudo service spamassassin restart&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이상으로 SpamAssassin에서 처리할 것은 완료 되었다.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;이제부터는 Apache James 에서 Spam 설정을 하고, 메일 테스트를 진행한다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;먼저, James를 설치한 폴더 하위의 conf 파일 중&amp;nbsp; smtpserver.xml파일을 열어서&lt;/p&gt;
&lt;p&gt;SpamAssassinHandler를 사용할 수 있도록 주석으로 처리된(&amp;lt;!--&amp;nbsp; --&amp;gt;) 부분을 삭제한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;gt; vi conf/smtpserver.xml&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;&amp;lt;!--&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;lt;handler class=&quot;org.apache.james.smtpserver.fastfail.SpamAssassinHandler&quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;spamdHost&amp;gt;127.0.0.1&amp;lt;/spamdHost&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;spamdPort&amp;gt;783&amp;lt;/spamdPort&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;spamdRejectionHits&amp;gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;2&lt;/span&gt;&lt;/b&gt;&amp;lt;/spamdRejectionHits&amp;gt;&lt;br /&gt;&amp;lt;/handler&amp;gt;&lt;br /&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&amp;nbsp;--&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;SpamAssassin은 지정되거나 학습된 규칙에 의해서 메일을 평가해서 점수로 환산한다.&lt;/p&gt;
&lt;p&gt;Apache James가 수신한 메일을 SpamAssassin에 넘기고, SpamAssassin이 평가한 점수를 반환 받아서 spamdRejectionHits 값으로 지정한 값 이상이면 메일을 수신하지 않고 돌려 보낸다.&lt;/p&gt;
&lt;p&gt;spamdRejectionHits의 &lt;span style=&quot;color: #ee2323;&quot;&gt;기본 값은 10&lt;/span&gt;으로 되어 있는데, 값이 너무 높으면 테스트를 할 수 없기 때문에 &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;2&lt;/span&gt;&lt;/b&gt;로 수정해서 테스트 한다.&lt;/p&gt;
&lt;p&gt;수정한 내용을 반영하기 위해서 Apache James를 제가동 한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;gt; sudo bin/james restart&lt;/p&gt;
&lt;p&gt;로그를 확인해서 제임스 재가동 완료 여부를 확인한다 (10여초 이상이 걸린다).&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;gt; tail -f log/wrapper.log&lt;/p&gt;
&lt;p&gt;메일을 주고 받기 위해 앞서 생성한 생성한 계정(gujc1)외에 하나 더 생성(gujc2)하거나&lt;/p&gt;
&lt;p&gt;생성한 하나의 계정으로 메일을 주고 받도록한다.&lt;/p&gt;
&lt;p&gt;여기서는 썬더버드(Thunderbird)를 사용할 예정인데,&lt;/p&gt;
&lt;p&gt;아웃룩등의 &lt;a href=&quot;https://forest71.tistory.com/218&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;MUA을 실행해서 생성한 메일 계정을 등록&lt;/a&gt;하고 다음과 같이 메일을 발송한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bJrUlf/btqS1V0nPzh/nUanwODLQIGkEC3dnysM20/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bJrUlf/btqS1V0nPzh/nUanwODLQIGkEC3dnysM20/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bJrUlf/btqS1V0nPzh/nUanwODLQIGkEC3dnysM20/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbJrUlf%2FbtqS1V0nPzh%2FnUanwODLQIGkEC3dnysM20%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;메일 본문에 dear winner를 입력하고 메일을 발송한다.&lt;/p&gt;
&lt;p&gt;다음과 같이 오류가 발생하는 것을 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FREf7/btqSXi3agpC/YT9Ly8LQBsnymgt4oWp7Vk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FREf7/btqSXi3agpC/YT9Ly8LQBsnymgt4oWp7Vk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FREf7/btqSXi3agpC/YT9Ly8LQBsnymgt4oWp7Vk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFREf7%2FbtqSXi3agpC%2FYT9Ly8LQBsnymgt4oWp7Vk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;지금 보내려는 메시지는 스팸인 것 같으니, 스팸이 아니라면 관리자에게 연락하라는 메시지가 나타난다.&lt;/p&gt;
&lt;p&gt;dear winner는 스팸 발송자들이 많이 사용하는 단어로&lt;/p&gt;
&lt;p&gt;이 단어가 메일 본문에 있으면 SpamAssassin가 스팸으로 판단해서 Apache James에게 알려주고&lt;/p&gt;
&lt;p&gt;Apache James가 위와 같이 수신 거부를 하게 된다.&lt;/p&gt;
&lt;p&gt;dear winner 같은 스팸 단어와 관련된 자세한 내용은 &lt;a href=&quot;https://forest71.tistory.com/220&quot;&gt;스팸 서버 구축&lt;/a&gt;에 정리된 내용을 참고하면 된다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;앞서서 smtpserver.xml파일에서 수정했던 SpamAssassin 설정 부분을 다시 주석처리하고&lt;/p&gt;
&lt;p&gt;Apache James를 재가동하고 메일을 보내면 다음과 같이 메일이 잘 송신되고 수신되는 것을 볼 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/enMh2a/btqS6YBLN18/n1Q0Hd5Bv7fdgKs4YkX9b0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/enMh2a/btqS6YBLN18/n1Q0Hd5Bv7fdgKs4YkX9b0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/enMh2a/btqS6YBLN18/n1Q0Hd5Bv7fdgKs4YkX9b0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FenMh2a%2FbtqS6YBLN18%2Fn1Q0Hd5Bv7fdgKs4YkX9b0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;이 방식은 수신된 메일이 확실하게 스팸 메일(spamdRejectionHits 이 10 이상- 테스트는 2)이면 되돌려 보내는 것이다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;하지만 수신한 메일이 스팸인지 애매한 경우도 있다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;spamdRejectionHits에 지정된 값 보다 작지만 (즉, 수신되었지만)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;앞서 SpamAssassin에서 지정한 required_hits&amp;nbsp;값보다 큰 메일은 메일 수신자의 스팸 폴더에 넣어주는게 좋다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;(required_hits의 기본값은 5이지만, 앞서서 테스트를 위해 2로 지정했다.)&lt;/p&gt;
&lt;p&gt;&lt;b&gt;대부부의 상용 메일 서버들은 스팸으로 의심되는 메일들은 각 개인의 스팸 폴더에 넣어주고,&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt; 개인이 판단하도록 하기 때문에 여기에서도 이 방식을 구현한다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;앞서서 smtpserver.xml파일에서 수정했던 SpamAssassin 설정 부분을 다시 주석처리하거나&lt;/p&gt;
&lt;p&gt;spamdRejectionHits 값을 10 이상으로 수정해서 스팸 메일을 반환하지 않도록 한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;스팸 폴더에 메일을 저장하기 위해, conf 폴더에 있는 mailetcontainer.xml 파일에 다음 설정을 추가한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;gt; vi conf/mailetcontainer.xml&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;생략 ~~&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;lt;processor state=&quot;root&quot; enableJmx=&quot;true&quot;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;생략&amp;nbsp;~~&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;mailet&amp;nbsp;match=&quot;SMTPAuthSuccessful&quot;&amp;nbsp;class=&quot;ToProcessor&quot;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;processor&amp;gt;transport&amp;lt;/processor&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/mailet&amp;gt;&lt;/span&gt; &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;mailet match=&quot;All&quot; class=&quot;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;SpamAssassin&lt;/span&gt;&lt;/b&gt;&quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;spamdHost&amp;gt;localhost&amp;lt;/spamdHost&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;spamdPort&amp;gt;783&amp;lt;/spamdPort&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/mailet&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;mailet match=&quot;HasHeader=org.apache.james.spamassassin.flag=YES&quot; class=&quot;ToProcessor&quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;processor&amp;gt;spam&amp;lt;/processor&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/mailet&amp;gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;mailetcontainer.xml는 메일을 처리하는 주요 과정을 설정하는 파일로,&lt;/p&gt;
&lt;p&gt;메일을 수신하면 &lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;SpamAssassin&lt;/span&gt;&lt;/b&gt;클래스를 실행해서 스팸 확인을 하도록 추가하였다.&lt;/p&gt;
&lt;p&gt;match 문은(&lt;a href=&quot;https://james.apache.org/server/3/dev-provided-matchers.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Macher&lt;/a&gt;) 일종의 if문을 의미하는데,&lt;/p&gt;
&lt;p&gt;위 코드에서는 모든 메일(All)은 SpamAssassin에 접속해서 스팸 여부를 확인하는 &lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;SpamAssassin&lt;/span&gt;&lt;/b&gt;클래스를 거치도록 하였다.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;SpamAssassin&lt;/span&gt;&lt;/b&gt;클래스에서는 스팸 여부를 확인후 org.apache.james.spamassassin.flag헤더를 추가하고 YES / NO 값을 지정한다.&lt;/p&gt;
&lt;p&gt;다음 match에서는 검사후 org.apache.james.spamassassin.flag헤더의 값이 YES이면&lt;/p&gt;
&lt;p&gt;spam처리를 하는 spam프로세스(&amp;lt;processor&amp;gt;spam&amp;lt;/processor&amp;gt;)로 이동한다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;주의: 인터넷 검색 자료(공식자료?)에서는 &lt;span style=&quot;color: #ee2323;&quot;&gt;HasMailAttributeWithValue&lt;/span&gt;=org.apache.james.spamassassin.flag,YES를 사용하도록 되어 있다.&lt;br /&gt;HasMailAttributeWithValue는 속성값을 확인하는 것인데, 이유는 모르지만 제대로 작동하지 않는다.&lt;br /&gt;여기에서는 헤더 값을 확인하는 &lt;span style=&quot;color: #ee2323;&quot;&gt;HasHeader&lt;/span&gt;를 사용했다.&lt;br /&gt;상세한 설명은 &lt;a href=&quot;https://james.apache.org/server/3/dev-provided-matchers.html&quot;&gt;Apache James Macher 문서&lt;/a&gt;에 정리되어 있다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;mailetcontainer.xml 하단에 다음과 같이 spam프로세스를 처리하는 부분이 있다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&amp;lt;processor&amp;nbsp;state=&quot;&lt;span style=&quot;color: #006dd7;&quot;&gt;spam&lt;/span&gt;&quot;&amp;nbsp;enableJmx=&quot;true&quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;!--&amp;nbsp;To&amp;nbsp;place&amp;nbsp;the&amp;nbsp;spam&amp;nbsp;messages&amp;nbsp;in&amp;nbsp;the&amp;nbsp;user&amp;nbsp;junk&amp;nbsp;folder,&amp;nbsp;uncomment&amp;nbsp;this&amp;nbsp;matcher/mailet&amp;nbsp;configuration&amp;nbsp;--&amp;gt;&lt;br /&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;!--&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;mailet&amp;nbsp;match=&quot;RecipientIsLocal&quot;&amp;nbsp;class=&quot;ToRecipientFolder&quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;folder&amp;gt;Junk&amp;lt;/folder&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;consume&amp;gt;false&amp;lt;/consume&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/mailet&amp;gt;&lt;br /&gt;&amp;nbsp;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&amp;nbsp; --&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;mailet&amp;nbsp;match=&quot;All&quot;&amp;nbsp;class=&quot;ToRepository&quot;&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;repositoryPath&amp;gt;file://var/mail/spam/&amp;lt;/repositoryPath&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/mailet&amp;gt;&lt;br /&gt;&amp;lt;/processor&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;스팸으로 확인된 메일은 지정된 경로(repositoryPath)에 저장하도록 되어 있다.&lt;/p&gt;
&lt;p&gt;이 Matcher를 삭제하고, 그 위에 주석으로(&amp;lt;!--&amp;nbsp; --&amp;gt;) 작성된 코드에서 주석을 제거한다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&amp;lt;processor&amp;nbsp;state=&quot;spam&quot;&amp;nbsp;enableJmx=&quot;true&quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;!--&amp;nbsp;To&amp;nbsp;place&amp;nbsp;the&amp;nbsp;spam&amp;nbsp;messages&amp;nbsp;in&amp;nbsp;the&amp;nbsp;user&amp;nbsp;junk&amp;nbsp;folder,&amp;nbsp;uncomment&amp;nbsp;this&amp;nbsp;matcher/mailet&amp;nbsp;configuration&amp;nbsp;--&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;lt;mailet&amp;nbsp;match=&quot;RecipientIsLocal&quot;&amp;nbsp;class=&quot;ToRecipientFolder&quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;folder&amp;gt;Junk&amp;lt;/folder&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;consume&amp;gt;false&amp;lt;/consume&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/mailet&amp;gt;&lt;br /&gt;&amp;lt;/processor&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;수신자(Recipient)가 Apache James에 등록된(local) 사용자면 (RecipientIsLocal)&lt;/p&gt;
&lt;p&gt;수신자 저장 클래스를(ToRecipientFolder) 실행해서 스팸(Junk) 폴더에 저장하도록 한다.&lt;/p&gt;
&lt;p&gt;스팸으로 지정되면, 한 폴더에 모으는 것이 아니고 각 개인의 스팸 폴더에 저장해서 개인이 볼 수 있도록 설정했다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;마지막 설정으로 수신한 스팸을 저장할 개인별 Junk 폴더를(메일함) 생성한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; james-cli.sh CreateMailbox private 이메일주소 Junk&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bPxBn1/btqTDJZJRFj/vJDCErHpHGEekwyoitk6i0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bPxBn1/btqTDJZJRFj/vJDCErHpHGEekwyoitk6i0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bPxBn1/btqTDJZJRFj/vJDCErHpHGEekwyoitk6i0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbPxBn1%2FbtqTDJZJRFj%2FvJDCErHpHGEekwyoitk6i0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Apache James를 재가동하고,&lt;/p&gt;
&lt;p&gt;선더버드와 같은 MUA에서 다음과 같이 스팸 메일을 발송한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bGhVO6/btqS9YIhXGe/gCJ2N0aUqdLxzInGoySsf0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bGhVO6/btqS9YIhXGe/gCJ2N0aUqdLxzInGoySsf0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bGhVO6/btqS9YIhXGe/gCJ2N0aUqdLxzInGoySsf0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbGhVO6%2FbtqS9YIhXGe%2FgCJ2N0aUqdLxzInGoySsf0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;그림과 같이 [스팸 편지함]에 메일이 제대로 저장 되는 것을 볼 수 있다.&lt;/p&gt;
&lt;p&gt;수신한 메일을 선택하고 그림 우측 중앙에 있는 [기타]를 선택해서, [소스보기]를 실행한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bsGuvu/btqTF25Cm1m/Grn5T9fQ0aeQhPGYkXayC0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bsGuvu/btqTF25Cm1m/Grn5T9fQ0aeQhPGYkXayC0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bsGuvu/btqTF25Cm1m/Grn5T9fQ0aeQhPGYkXayC0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbsGuvu%2FbtqTF25Cm1m%2FGrn5T9fQ0aeQhPGYkXayC0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;다음과 같이 수신한 메일의 EML 원문 내용을 볼 수 있는데, 메일 헤더에 스팸 메일로 표시되어 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bajOr9/btqTF3XI58n/7Uf2jjMywBpgX7XkxuKKk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bajOr9/btqTF3XI58n/7Uf2jjMywBpgX7XkxuKKk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bajOr9/btqTF3XI58n/7Uf2jjMywBpgX7XkxuKKk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbajOr9%2FbtqTF3XI58n%2F7Uf2jjMywBpgX7XkxuKKk0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;org.apache.james.spamassassin.flag가 YES이고, 스팸 점수가 2.9점으로 표시되었다.&lt;/p&gt;
&lt;p&gt;위 그림과 같이 [스팸 편지함]이 보이지 않는 경우,&lt;/p&gt;
&lt;p&gt;썬더보드의 경우 해당 메일 계정을 선택하고 마우스 오른쪽 버튼을 눌러서 [설정] 메뉴를 실행한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/byZuDs/btqTNAzJNkQ/tMFVAz0iffUhJOio8TPxR0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/byZuDs/btqTNAzJNkQ/tMFVAz0iffUhJOio8TPxR0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/byZuDs/btqTNAzJNkQ/tMFVAz0iffUhJOio8TPxR0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbyZuDs%2FbtqTNAzJNkQ%2FtMFVAz0iffUhJOio8TPxR0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;계정 설정 화면 하단에 있는 [새 스팸 메시지 이동]을 선택하고, 편지함 탭을 선택하면 [스팸 편지함]을 볼 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MdYb7/btqTJSVrjLq/VFMB7kXxIm0bFBujQ1ba0K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MdYb7/btqTJSVrjLq/VFMB7kXxIm0bFBujQ1ba0K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MdYb7/btqTJSVrjLq/VFMB7kXxIm0bFBujQ1ba0K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMdYb7%2FbtqTJSVrjLq%2FVFMB7kXxIm0bFBujQ1ba0K%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;이상으로 SpamAssassin을 Apache James 의 스팸 필터로 사용하는 방법을 정리하였다.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://forest71.tistory.com/220&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;SpamAssassin을 스팸 서버&lt;/a&gt;로 사용하는 방법도 정리하였는데,&lt;/p&gt;
&lt;p&gt;SpamAssassin을 스팸 서버로 사용하는 경우,&lt;/p&gt;
&lt;p&gt;스팸 메일이면 메일헤더에 X-Spam-Flag가 추가되고 YES값이 추가된다(&lt;a href=&quot;https://forest71.tistory.com/220&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;참고&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;앞서 mailetcontainer.xml 에서 설정한 스팸 필터 연동 부분을 삭제하고 (&amp;lt;mailet match=&quot;All&quot; class=&quot;SpamAssassin&quot;&amp;gt;)&lt;/p&gt;
&lt;p&gt;스팸 여부를 확인하는 HasHeader=org.apache.james.spamassassin.flag=YES 대신에&lt;/p&gt;
&lt;p&gt;HasHeader=X-Spam-Flag=YES을 지정하면 &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;스팸서버에서 판단한 스팸 메일을 각 개인의 스팸 메일함(Junk)에 저장할 수 있다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;덧붙이는 글&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;한글 스팸 메일들을 SpamAssassin으로 학습시켜서 스팸 메일을 테스트하는 내용에 대해서 공유할 계획입니다.&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;자신의 메일 함에 있는, 또는 회사 스팸 서버에 있는 스팸 메일들을 공유해주시면 감사하겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;net_forest@hanmail.net 으로 보내주세요.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>서버/메일</category>
      <author>forest71</author>
      <guid isPermaLink="true">https://forest71.tistory.com/221</guid>
      <comments>https://forest71.tistory.com/221#entry221comment</comments>
      <pubDate>Sun, 10 Jan 2021 12:10:23 +0900</pubDate>
    </item>
    <item>
      <title>스팸 메일 서버 구축 - SpamAssassin &amp;amp; Postfix</title>
      <link>https://forest71.tistory.com/220</link>
      <description>&lt;p&gt;앞서서 &lt;a href=&quot;https://forest71.tistory.com/216&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Apache James를 이용하여 메일 서버를 운영하는 방법&lt;/a&gt;에 대해서 정리하였다.&lt;/p&gt;
&lt;p&gt;이렇게 메일 서버를 운영하면, 어떻게 아는지 몰라도 매일 매일 많은 스팸 메일들을 수신하게 된다.&lt;/p&gt;
&lt;p&gt;이 스팸 메일들을 차단하기 위해 스팸 서버를 이용하거나 메일 서버내에 &lt;a href=&quot;https://forest71.tistory.com/221&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;스팸 필터&lt;/a&gt;를 적용해서 이용하는데, 여기에서는 오픈 소스인 Apache SpamAssassin를 이용하여 스팸 서버를 구축하는 방법에 대해서 정리한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;
&lt;p style=&quot;text-align: center;&quot;&gt;메일 관련 내용들&lt;/p&gt;
&lt;p&gt;1. &lt;a href=&quot;https://forest71.tistory.com/216&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;메일 서버 구축 : Apache James&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;2. 스팸 메일 서버 구축: Postfix &amp;amp; Apache SpamAssassin&lt;/p&gt;
&lt;p&gt;3. &lt;a href=&quot;https://forest71.tistory.com/221&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;메일 서버와 스팸 필터 : Apache James &amp;amp; SpamAssassin&lt;/a&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;구축 방법은 다음과 같이 인터넷 검색으로 쉽게 찾을 수 있기 때문에 여기에서는 정리하지 않고, 스팸 메일 서버를 이용해서 실제로 &lt;u&gt;테스트하는 방법만 정리&lt;/u&gt;한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;스팸 서버 구축에 필요한 SpamAssassin은 리눅스에서 운영되며 여기에서는 Centos 7에 설치하고 정리하였다.&lt;/p&gt;
&lt;p&gt;Ubuntu도 설치법은 유사하다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Centos 설치&lt;/b&gt;&lt;br /&gt;&lt;a href=&quot;https://tweenpath.net/configuring-spamassassin-postfix-centos/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://tweenpath.net/configuring-spamassassin-postfix-centos/&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;https://devopspoints.com/centos-7-installing-and-configuring-spamassassin.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://devopspoints.com/centos-7-installing-and-configuring-spamassassin.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Ubuntu 설치&lt;/b&gt;&lt;br /&gt;&lt;a href=&quot;https://hostadvice.com/how-to/how-to-secure-postfix-with-spamassassin-on-an-ubuntu-18-04-vps-or-dedicated-server/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://hostadvice.com/how-to/how-to-secure-postfix-with-spamassassin-on-an-ubuntu-18-04-vps-or-dedicated-server/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;스팸 서버도 메일을 주고 받는 서버이기 때문에 메일 서버랑 기본적으로 동일하다.&lt;/p&gt;
&lt;p&gt;따라서 인터넷 자료는 Postfix, Dovecot등으로 메일 서버를 구축하고,&lt;/p&gt;
&lt;p&gt;SpamAssassin으로 스팸 메일을 체크를 하는 식으로 구현하는 자료가 많은데, 이러한 내용들은 설치만 해도 제법 복잡하다 (이런 구축은 스팸 서버라기 보다 스팸 필터라고 생각한다).&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;u&gt;스팸 서버는 메일을 주고 받는 SMTP와 스팸 여부를 확인하는 기능만으도 충분하다.&lt;/u&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;(각종 메일 처리나 IMAP, POP3등을 구현하지 않는다.)&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt; 메일 송수신에 사용되는 SMTP는 Postfix를 이용하고, &lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;송수신하는 메일에 대한 스팸 여부는 SpamAssassin으로 확인하도록 구축한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Postfix는 운영체제와 같이 설치되어 있고, SpamAssassin만 위 인터넷 자료를 따라서 설치한다 (Ubuntu에서 spamc는 굳이 설치하지 않아도 되는 것 같다).&lt;/p&gt;
&lt;p&gt;&lt;u&gt;설치 문서의 핵심은 메일을 발송하는 Postfix와 SpamAssassin을 연결하는 것&lt;/u&gt;으로, Postfix에서 메일을 송수신 하면 SpamAssassin으로 검사 하기 위한 것이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;다만, 이 문서에서 SpamAssassin 설정(/etc/mail/spamassassin/local.cf)을 다음과 같이 수정한다 (CentOS).&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;gt; vi /etc/mail/spamassassin/local.cf&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;required_hits&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt; 2&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;report_safe 0&lt;br /&gt;rewrite_header Subject [SPAM]&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;SpamAssassin은 지정되거나 학습된 규칙에 의해서 메일을 평가해서 점수로 환산하고, 지정된 값(required_hits) 이상이면 스팸으로 표시한다.&lt;/p&gt;
&lt;p&gt;위 설정외에도 다양한 설정을 할 수 있는데, 설정에 대한 상세한 내용은 &lt;a href=&quot;https://www.auctionpro.co.kr/?product=146&amp;amp;paged=77&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;이 사이트에&lt;/a&gt; 정리된 내용을 참고하면 된다.&lt;/p&gt;
&lt;p&gt;&lt;u&gt;기본 값은 5인데, 이렇게 지정되면 테스트하기 어렵기 때문에 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;2&lt;/b&gt;&lt;/span&gt;으로 수정해서 진행한다.&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;수정내용을 반영하기 위해서 SpamAssassin을 재가동 한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;gt; sudo service spamassassin restart&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;스팸 메일을 테스트하려면 스팸 메일을 만들어야 한다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;스팸 메일을 만들려면 SpamAssassin의 규칙을 알아야 하는데, 다음 그림과 같이 &lt;a href=&quot;https://www.futurequest.net/docs/SA/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Futurequest 사이트에&lt;/a&gt; 잘 정리되어 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TTruK/btqSZxyquzY/ayxpMF1jjivdHyDfKxqPlk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TTruK/btqSZxyquzY/ayxpMF1jjivdHyDfKxqPlk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TTruK/btqSZxyquzY/ayxpMF1jjivdHyDfKxqPlk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTTruK%2FbtqSZxyquzY%2FayxpMF1jjivdHyDfKxqPlk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;위 내용들은 메일이 어떤 내용을 가지고 있는 냐에 따라 점수를 부여하는지를 나타낸 것으로&lt;/p&gt;
&lt;p&gt;특정 메일이 위 사항을 위반했는지 확인해서 점수들을 부여하고, 이 점수들을 합산하여 스팸으로 평가한다.&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;위 리스트 중에 메일 본문에 &quot;&lt;b&gt;dear winner&lt;/b&gt;&quot;란 글자가 있으면 3.099의 점수를 부여 받는다는 것을 알 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;앞서 SpamAssassin 설정에서 기준 점수를 &lt;b&gt;2&lt;/b&gt;점으로 지정했으니 &quot;dear winner&quot;를 입력하면 스팸 메일로 처리할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;이 문장을 포함한 메일을 메일서버나 스팸 서버에서 수신하도록 하면 되는데, &lt;/span&gt;&lt;u&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;도메인을 등록하고 MX 레코드등을 지정하지 않으면 메일을 수신할 수 없다.&lt;/span&gt;&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;이 문제 때문에 스팸 서버 설치만 있고 테스트가 없는 것 같은데,&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;여기에서는 &lt;u&gt;스팸 서버로 수신하는 것이 아니고, 송신하는 방식으로 테스트 한다.&lt;/u&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;스팸 서버는 송신을 하던 수신을 하던, 스팸 여부를 확인하기 때문이다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그리고, &lt;a href=&quot;https://forest71.tistory.com/216&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Apache James에서 정리한 것&lt;/a&gt;과 같이 메일을&amp;nbsp; 송신하는 것은 별도의 도메인이나 MX 레코드등을 지정하지 않아도 가능하기 때문이다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Postfix와 SpamAssassin이 잘 실행되었으면 (스팸 서버가 구축되었으면), 실제로 메일을 보내기 위해 텔넷으로 이 스팸(?)서버에 접속한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;gt; telnet localhost 25&lt;/p&gt;
&lt;p&gt;Postfix등 메일 서버는 기본적으로 25번 포트를 사용한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;텔넷 접속후 다음 내용을 순서데로 입력한다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;ehlo aaa&lt;br /&gt;mail from:&amp;lt;gujc1@forest71.com&amp;gt;&lt;br /&gt;rcpt to:&amp;lt;gujc~~~@gmail.com&amp;gt;&lt;br /&gt;data&lt;br /&gt;subject:dear winner&lt;br /&gt;&lt;br /&gt;dear winner&lt;br /&gt;&lt;br /&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;ehlo는 메일을 보내겠다고 Postfix에 알리는 것으로 아무 값(aaa)이나 지정하면 된다.&lt;/p&gt;
&lt;p&gt;메일을 보내는 사람(from)과 받는 사람(to)을 입력한다.&lt;/p&gt;
&lt;p&gt;보내는 사람은(from) 아무 값이나 입력해도 되다.&lt;/p&gt;
&lt;p&gt;아무 값이나 입력해도 되기 때문에 스팸 발송자들이 다양하게(?) 활용한다.&lt;/p&gt;
&lt;p&gt;받는 사람은(to) 메일을 받아야 하기 때문에 실제 사용하는 계정을 지정한다.&lt;/p&gt;
&lt;p&gt;data를 지정하고 엔터키를 치면 메일 제목(subject)과 본문을 입력할 수 있다.&lt;/p&gt;
&lt;p&gt;제목(subject)을 입력한 뒤에는 빈 라인 하나를 입력해야 제목(subject)으로 인식된다.&lt;/p&gt;
&lt;p&gt;그렇지 않으면 본문으로 처리되어 제목없는 메일이 발송된다.&lt;/p&gt;
&lt;p&gt;본문까지 입력한 뒤에는 점(.)을 입력하고 엔터키를 쳐서 다음과 같이 메일을 발송한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b6cWnu/btqSZxrGjgR/Lf3M5B1TZtgjTg9PmRy6kK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b6cWnu/btqSZxrGjgR/Lf3M5B1TZtgjTg9PmRy6kK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b6cWnu/btqSZxrGjgR/Lf3M5B1TZtgjTg9PmRy6kK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb6cWnu%2FbtqSZxrGjgR%2FLf3M5B1TZtgjTg9PmRy6kK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;여기에서는 gmail로 메일을 보냈으니 gmail에 접속해서 보낸 메일을 확인한다.&lt;/p&gt;
&lt;p&gt;대부분 스팸 메일함에 있을 텐데, SpamAssassin 때문이 아니고, 구글의 스팸 서버가 그렇게 처리한 것이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cyR3TN/btqS9YH0zyV/ee417anJczKbxropBThoo0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cyR3TN/btqS9YH0zyV/ee417anJczKbxropBThoo0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cyR3TN/btqS9YH0zyV/ee417anJczKbxropBThoo0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcyR3TN%2FbtqS9YH0zyV%2Fee417anJczKbxropBThoo0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;위 그림과 같이 메일 제목에 [SPAM]이 붙은 것을 볼 수 있다.&lt;/p&gt;
&lt;p&gt;일반적인 문장으로 보내면 [SPAM]이라는 문자열이 없다.&lt;/p&gt;
&lt;p&gt;위 메일은 메일을 보낼때 SpamAssassin이 스팸으로 판단해서 메일 제목에 붙인 것으로, 앞서 설정한 SpamAssassin&amp;nbsp; 설정에서 지정한 문자열이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;그림 우측의 메뉴(점 3개)를 클릭해서 [원본보기]를 선택한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bNi1bT/btqS4LWLdYp/0m3USEqjPGEkzTAUGnnOd1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bNi1bT/btqS4LWLdYp/0m3USEqjPGEkzTAUGnnOd1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bNi1bT/btqS4LWLdYp/0m3USEqjPGEkzTAUGnnOd1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbNi1bT%2FbtqS4LWLdYp%2F0m3USEqjPGEkzTAUGnnOd1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;메일 보기 화면은 필요한 사항만 추출하여 잘 정리하여 보여주는 것이고, 실제 수신해서 저장한 EML 메일 내용은 다음과 같이 다양한 정보들을 포함하고 있다.&lt;/p&gt;
&lt;p&gt;실행된 별창에서 스크롤을 내리면 다음과 같이&amp;nbsp; X-Spam~~으로 시작하는 메일 헤더들을 볼 수 있다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;생략 ~~~&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;Received: by localhost.localdomain (Postfix, from userid 1001) id 30AEC811148; Sat,&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp; 9 Jan 2021 15:44:19 +0900 (KST)&lt;/span&gt;&lt;br /&gt;X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on localhost.localdomain&lt;br /&gt;X-Spam-Flag: YES&lt;br /&gt;X-Spam-Level: ****&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;X-Spam-Status: Yes, score=4.5 required=2.0&lt;/b&gt;&lt;/span&gt; tests=ALL_TRUSTED,DEAR_WINNER, DKIM_ADSP_NXDOMAIN,MISSING_HEADERS,NO_DNS_FOR_FROM,TVD_SPACE_RATIO autolearn=no autolearn_force=no version=3.4.0&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;X-Spam-Report&lt;/b&gt;&lt;/span&gt;: * -1.0 ALL_TRUSTED Passed through trusted hosts only via SMTP *&lt;br /&gt;&amp;nbsp; 0.8 DKIM_ADSP_NXDOMAIN No valid author signature and domain not in DNS *&lt;br /&gt;&amp;nbsp; 1.2 MISSING_HEADERS Missing To: header *&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&amp;nbsp; 3.1 DEAR_WINNER BODY: Spam with generic salutation of &quot;dear winner&quot; *&lt;/span&gt;&lt;br /&gt;&amp;nbsp; 0.4 NO_DNS_FOR_FROM DNS: Envelope sender has no MX or A DNS records *&lt;br /&gt;&amp;nbsp; 0.0 TVD_SPACE_RATIO No description available.&lt;br /&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;Received: from aaa (localhost [IPv6:::1]) by localhost.localdomain (Postfix) with ESMTP id 3DA12811149 for &amp;lt;gujc71@gmail.com&amp;gt;; Sat,&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp; 9 Jan 2021 15:43:30 +0900 (KST)&lt;/span&gt;&lt;br /&gt;subject: [SPAM] dear winner&lt;br /&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;Message-Id: &amp;lt;20210109064341.3DA12811149@localhost.localdomain&amp;gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;메일을 발송하기 전에 SpamAssassin이&amp;nbsp; 처리한 결과를 메일 헤더에 저장한 것으로&lt;/p&gt;
&lt;p&gt;X-Spam-Status에 기준값이(required) 2인데, 이 메일은 4.5 (score)이기 때문에 스팸(yes)이라고 저장되어 있다.&lt;/p&gt;
&lt;p&gt;X-Spam-Report에는 어떻게 4.5점이 되었는지 이유가 정리되어 있다.&lt;/p&gt;
&lt;p&gt;다른 이유도 있지만 &quot;dear winner&quot;가 3.1점으로 가장 큰 이유가 되었다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이상으로 스팸 서버를 구축해서 테스트 하는 방법을 정리하였다.&lt;/p&gt;
&lt;p&gt;&lt;u&gt;메일을 수신하지 못하기 때문에 발신으로 테스트 하였지만, 실제 스팸 서버를 구축하고 수신으로 처리하여도 동일한 결과를 얻을 수 있다.&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;실제로 스팸 서버로 사용하기 위해 빠진 내용은 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;스팸 서버가 메일을 받아서 스팸 여부를 확인하고 나면 확인한 메일을 실제 메일서버로 전달(relay)한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;또, 실제 메일 서버에서는 메일의 헤더를 확인하고 스팸이면 삭제하거나 해당 수신자의 스팸 메일함에 넣게 된다.&lt;/p&gt;
&lt;p&gt;도메인 관련 설정도 필요하고 메일 서버도 정리해야 하기 때문에 메일서버로 전달(relay)하는 기능은 여기서 정리하지 않았고,&lt;/p&gt;
&lt;p&gt;스팸 메일함에 저장하는 방법은 SpamAssassin을 &lt;a href=&quot;https://forest71.tistory.com/221&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;스팸 필터로 사용하는 방법&lt;/a&gt;을 정리하는 부분에서 조금 정리하였다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;추가적으로 정리하지 못한 내용은 [한글] 메일에 대한 스팸 처리이다.&lt;/p&gt;
&lt;p&gt;SpamAssassin은 베이지안(Bayesian) 알고리즘으로 스팸 메일을 학습해서 성능을 향상시킬 수 있다.&lt;/p&gt;
&lt;p&gt;영어 메일은 학습해서 기본적인 규칙을 만들어 가지고 있지만, 한글에 대한 규칙은 제공되는 것이 없다 (못 찾은 것일 수도 있다).&lt;/p&gt;
&lt;p&gt;한글 스팸 규칙을 만들기 위해서는 한글 스팸 메일들을 학습시켜야 하는데, 제법 많은 메일이 필요해서 테스트를 하지 못했다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;덧붙이는 글&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;한글 스팸 메일들을 SpamAssassin으로 학습시켜서 스팸 메일을 테스트하는 내용에 대해서 공유할 계획입니다.&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;자신의 메일 함에 있는, 또는 회사 스팸 서버에 있는 스팸 메일들을 공유해주시면 감사하겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;net_forest@hanmail.net 으로 보내주세요.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>서버/메일</category>
      <author>forest71</author>
      <guid isPermaLink="true">https://forest71.tistory.com/220</guid>
      <comments>https://forest71.tistory.com/220#entry220comment</comments>
      <pubDate>Sat, 9 Jan 2021 15:53:29 +0900</pubDate>
    </item>
    <item>
      <title>1. Apache James 메일 서버 - 설치</title>
      <link>https://forest71.tistory.com/216</link>
      <description>&lt;p&gt;Apache James 메일 서버는 Java로 만든 메일 서버로&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.ubuntupit.com/best-linux-mail-server-software-and-solutions/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;다양한 오픈 소스 메일 서버&lt;/a&gt; 중에서 최고의 메일 서버인지는 확인되지 않지만, 안정적인 기능과 Apache의 지원을 받는 메일 서버이다.&lt;/p&gt;
&lt;p&gt;다만 문서나 자료가 많지 않아서, 알게 되는 것들을 기록차원에서 다음과 같이 나누어 정리한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;Apache James 메일 서버 - 설치&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://forest71.tistory.com/217&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Apache James 메일 서버 - 설정&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://forest71.tistory.com/218&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Apache James 메일 서버 - 메일 클라이언트&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://forest71.tistory.com/219&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Apache James 메일 서버 - Text와 JPA(MariaDB등)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://forest71.tistory.com/221&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Apache James 메일 서버 - 스팸 필터 (SpamAssassin)&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Apache James 메일 서버(이하 James)를 사용해 보기 전에&lt;/p&gt;
&lt;p&gt;SMTP(Simple Mail Transfer Protocol), IMAP(Internet Message Access Protocol) 등의 개념에 대해서는 검색해 보거나 다음 자료들을 읽어보는 것이 좋다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;a href=&quot;https://wodonggun.github.io/wodonggun.github.io/study/SMTP,-POP3,-IMAP-%EC%9D%B4%EB%9E%80.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://wodonggun.github.io/wodonggun.github.io/study/SMTP,-POP3,-IMAP-%EC%9D%B4%EB%9E%80.html&lt;/a&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;a href=&quot;https://m.post.naver.com/viewer/postView.nhn?volumeNo=26957131&amp;amp;memberNo=2521903&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://m.post.naver.com/viewer/postView.nhn?volumeNo=26957131&amp;amp;memberNo=2521903&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;https://james.apache.org/index.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;James의 공식 사이트&lt;/a&gt;는 다음과 같이 그럴 듯 해 보이는데, 메뉴를 클릭하면 심플한 구조에 간단한 설명들만 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cw2936/btqOqT0sJjI/yhJOx247VtJY695cgqH1yK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cw2936/btqOqT0sJjI/yhJOx247VtJY695cgqH1yK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cw2936/btqOqT0sJjI/yhJOx247VtJY695cgqH1yK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcw2936%2FbtqOqT0sJjI%2FyhJOx247VtJY695cgqH1yK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;상세한 자료는 &lt;a href=&quot;https://gitter.im/apache/james-project&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;커뮤니티 사이트&lt;/a&gt;의 내용을 참조해야 한다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;James 설치 방법은 다음 URL에 정리되어 있지만, 상세하게 설명되어 있지 않다.&lt;/p&gt;
&lt;p&gt;(아는 사람에게는 간단 명료한 설치 문서가 될 것 같다.)&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;a href=&quot;https://james.apache.org/server/quick-start.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://james.apache.org/server/quick-start.html&lt;/a&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;a href=&quot;https://james.apache.org/server/install.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://james.apache.org/server/install.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KtTNM/btqOoNsTKMa/05GieZ6YgtY5v4FMcG3Hx1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KtTNM/btqOoNsTKMa/05GieZ6YgtY5v4FMcG3Hx1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KtTNM/btqOoNsTKMa/05GieZ6YgtY5v4FMcG3Hx1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKtTNM%2FbtqOoNsTKMa%2F05GieZ6YgtY5v4FMcG3Hx1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;여기에서는 이 내용을 토대로 윈도우(10)에서 설치하는 방법을 중심으로 정리한다.&lt;/p&gt;
&lt;p&gt;리눅스에 설치하는 방법은 위 URL 내용대로 하면 되지만, 윈도우는 조금 더 설치가 어렵기(?) 때문이다.&lt;/p&gt;
&lt;p&gt;Java 설치 방법은 여기에서 정리하지 않는다.&lt;/p&gt;
&lt;p&gt;&lt;u&gt;JDK 1.8 이상을 설치해야 하고, JAVA_HOME과 bin 폴더에 대한 Path는 지정되어 있어야 한다.&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;먼저, &lt;a href=&quot;https://james.apache.org/download.cgi#Apache_James_Server&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;다운로드 사이트&lt;/a&gt;에서 &lt;a href=&quot;https://james.apache.org/download.cgi#Apache_James_Server&quot;&gt;apache-james-3.5.0-app.zip&lt;/a&gt; 파일을 다운받는다.&lt;/p&gt;
&lt;p&gt;오픈 소스이기 때문에 &lt;a href=&quot;https://james.apache.org/server/dev-build.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;소스를 받아서&lt;/a&gt; (할 수 있다면) 수정해서 사용할 수도 있다.&lt;/p&gt;
&lt;p&gt;(도전 중인데, 설치가 쉽지 않다. 실력향상을 위해 도전해 보는 것도 좋을 것 같다.)&lt;/p&gt;
&lt;p&gt;여기에서는 Binary 파일인 &lt;a href=&quot;https://james.apache.org/download.cgi#Apache_James_Server&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;apache-james-3.5.0-app.zip&lt;/a&gt;을 받아서 실행한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/90de0/btqOqULPT4d/z0eHEtR121T7OuFBKAV2k1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/90de0/btqOqULPT4d/z0eHEtR121T7OuFBKAV2k1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/90de0/btqOqULPT4d/z0eHEtR121T7OuFBKAV2k1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F90de0%2FbtqOqULPT4d%2Fz0eHEtR121T7OuFBKAV2k1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;적당한 폴더에 압축을 풀면, 다음과 같은 폴더 구조를 볼 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2tQuz/btqOvfgVZEj/lm5YKt1FhGQl71p9LQkyQK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2tQuz/btqOvfgVZEj/lm5YKt1FhGQl71p9LQkyQK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2tQuz/btqOvfgVZEj/lm5YKt1FhGQl71p9LQkyQK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2tQuz%2FbtqOvfgVZEj%2Flm5YKt1FhGQl71p9LQkyQK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;bin 폴더에는 James를 실행하는 파일이 있고,&lt;/p&gt;
&lt;p&gt;conf 폴더에는 James 설정 파일들이 있다.&lt;/p&gt;
&lt;p&gt;lib 폴더는 James 실행에 필요한 Java 라이브러리들이 있고,&lt;/p&gt;
&lt;p&gt;log 폴더는 실행 결과에 대한 다양한 정보를 제공하는 로그 파일들이 있다.&lt;/p&gt;
&lt;p&gt;var 폴더에는 activemq, 메일 오류 파일 등이 저장되어 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;conf 폴더에는 20 여개의 설정 파일들이 있다.&lt;/p&gt;
&lt;p&gt;James는 다양한 기능을 제공하는데, 이 설정 파일들을 이용하여 조절할 수 있다.&lt;/p&gt;
&lt;p&gt;설정에 대한 &lt;a href=&quot;https://james.apache.org/server/config.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;간략한 웹 페이지가 있지만&lt;/a&gt; 설명이 많지 않고, 각 설정 파일 안에 간단한 설명이 주석으로 포함되어 있다.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://forest71.tistory.com/217&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;설정과 관련된 주요한 몇 가지 내용은 별도로 정리한다&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;여기에서는 James를 실행하기 위한 설명 몇 가지만 지정한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;domainlist.xml 파일에서 사용할 도메인(forest71.com)을 지정한다.&lt;/p&gt;
&lt;p&gt;이 도메인은 실제 등록된 도메인을 지정해도 되고, 테스트를 위해서 여기서는 forest71.com을 사용한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/44U6d/btqOuGMB4MB/V01qq4gf00QpmWe9RgNnTk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/44U6d/btqOuGMB4MB/V01qq4gf00QpmWe9RgNnTk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/44U6d/btqOuGMB4MB/V01qq4gf00QpmWe9RgNnTk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F44U6d%2FbtqOuGMB4MB%2FV01qq4gf00QpmWe9RgNnTk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;사용할 도메인을 지정하고 James를 실행하면 되지만,&lt;/p&gt;
&lt;p&gt;mailetcontainer.xml에서 우편 관리자 계정에 대한 도메인도 위와 같이 동일하게 지정한다.&lt;/p&gt;
&lt;p&gt;우편 관리자 계정은 반송 메일 등에 사용된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JclVr/btqOthmxqYt/ZAaQ9nBppMdam8Q4Jszk4k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JclVr/btqOthmxqYt/ZAaQ9nBppMdam8Q4Jszk4k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JclVr/btqOthmxqYt/ZAaQ9nBppMdam8Q4Jszk4k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJclVr%2FbtqOthmxqYt%2FZAaQ9nBppMdam8Q4Jszk4k%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;James는 Java로 제작되었기 때문에 다운로드 받은 zip 파일 하나로 윈도우와 리눅스에서 실행할 수 있다.&lt;/p&gt;
&lt;p&gt;다만, James가 여러 가지 이유로 갑자기 종료 되었거나 멈춰진 상태로 있을 경우, 자동으로 감지하여 재시작하기 위해 &lt;a href=&quot;https://www.tanukisoftware.com/en/wrapper.php&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Wrapper를&lt;/a&gt; 사용하여 제작되었다.&lt;/p&gt;
&lt;p&gt;(기업에서 메일 서버는 중지되면 안 된다.)&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;이 Wrapper가 윈도우에서는 윈도우 서비스로 등록해서 사용하고, 리눅스에서는 쉘(Shell)로 백그라운드에서 실행한다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;윈도우 시작 메뉴를 눌러 cmd 를 입력해서 콘솔(cmd) 창을 관리자 권한으로 실행한다.&lt;/p&gt;
&lt;p&gt;리눅스도 root 권한으로 실행해야 한다.&lt;/p&gt;
&lt;p&gt;(메일 서버는 25와 143포트(port)를 사용하는데 1024보다 작은 포트는 관리자 권한으로만 실행 할 수 있다.)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;콘솔 창에서 James 압축을 해제한 폴더 중 bin 폴더로 이동하여 james.bat install 를 실행한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bB4Bwg/btqOvfnF8S6/fuCxqPnrkZZ1ugTFZ6Xxw1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bB4Bwg/btqOvfnF8S6/fuCxqPnrkZZ1ugTFZ6Xxw1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bB4Bwg/btqOvfnF8S6/fuCxqPnrkZZ1ugTFZ6Xxw1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbB4Bwg%2FbtqOvfnF8S6%2FfuCxqPnrkZZ1ugTFZ6Xxw1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;이것은 James를 윈도우 서비스로 등록하는 명령어로, 다음과 같이 서비스가 등록된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/U5Nv2/btqOtgA53Ny/A5qSteXjaFrdvbeWIPsOI1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/U5Nv2/btqOtgA53Ny/A5qSteXjaFrdvbeWIPsOI1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/U5Nv2/btqOtgA53Ny/A5qSteXjaFrdvbeWIPsOI1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FU5Nv2%2FbtqOtgA53Ny%2FA5qSteXjaFrdvbeWIPsOI1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;james.bat remove로 제거 할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;윈도우 서비스 창에서 실행 버튼을 눌러 실행해도 되고, 콘솔 창에서 james.bat start로 실행해도 된다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;start외에 stop이나 restart 로 James를 중지하거나 재시작할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ba4M7F/btqOqTMZmf0/axbX0xgkdLryDpMGMyCw50/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ba4M7F/btqOqTMZmf0/axbX0xgkdLryDpMGMyCw50/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ba4M7F/btqOqTMZmf0/axbX0xgkdLryDpMGMyCw50/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fba4M7F%2FbtqOqTMZmf0%2FaxbX0xgkdLryDpMGMyCw50%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;리눅스에서는 james.bat 대신에 &lt;b&gt;./james.sh&lt;/b&gt;를 실행하면 되고, 위와 같이 서비스에 등록하는 과정없이 실행하면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;윈도우는 관리자 권한으로 콘솔(cmd) 창을 실행했지만,&lt;/p&gt;
&lt;p&gt;리눅스는 root 계정으로 로그인해서 실행하거나 다음과 같이 sudo를 이용해서 실행해야 한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sudo ./james.sh start&lt;/p&gt;
&lt;p&gt;James를 실행하는 윈도우와 리눅스의 차이는 이 정도가 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;log폴더에 다양한 로그 파일들이 생성되는데, wrapper.log 파일에 각 로그의 내용이 포함되어 생성된다.&lt;/p&gt;
&lt;p&gt;wrapper.log파일을 적절한 편집기로 열어서 다음과 같이 잘 시작되었는지 확인한다.&lt;/p&gt;
&lt;p&gt;리눅스는 less log/wrapper.log 나 tail -f log/wrapper.log로 확인한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cenDj4/btqOvQ2gWGv/aLj5KdOnjHeodnv8Yde9R0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cenDj4/btqOvQ2gWGv/aLj5KdOnjHeodnv8Yde9R0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cenDj4/btqOvQ2gWGv/aLj5KdOnjHeodnv8Yde9R0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcenDj4%2FbtqOvQ2gWGv%2FaLj5KdOnjHeodnv8Yde9R0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;주의&lt;/b&gt;&lt;/span&gt;: wrapper.log에 위와 같은 실행 결과가 아닌, 다음과 같은 오류를 볼 수 있다.&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Unable to start JVM: No such file or directory (2)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; JVM exited while loading the application.&lt;br /&gt;&lt;br /&gt;이것은 JAVA_HOME 이나 PATH 설정이 제대로 지정되지 않아서 생기는 오류로 JAVA_HOME 이나 PATH 설정을 확인한다.&lt;br /&gt;콘솔 창에서 java를 실행하면 사용법이 출력되어야 제대로 설치된 것이다.&lt;br /&gt;&lt;br /&gt;계속 이렇게 오류가 발생할 경우 conf폴더의 wrapper.conf 파일에서 다음과 같이 java가 설치된 경로(bin폴더 포함)를 지정하면 된다.&lt;br /&gt;
&lt;p&gt;# Java Application&lt;br /&gt;wrapper.java.command=&lt;span style=&quot;color: #ee2323;&quot;&gt;(자바경로지정)&lt;/span&gt;java&lt;br /&gt;wrapper.working.dir=.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;또는 콘솔 창에서 다음 명령어로 SMTP (25), POP3 (110), IMAP (143) 포트가 보이면 잘 실행된 것이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 윈도우 : netstat -an&lt;span style=&quot;color: #ee2323;&quot;&gt;q&lt;/span&gt; | &lt;span style=&quot;color: #006dd7;&quot;&gt;findstr&lt;/span&gt; LISTEN&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 리눅스 : netstat -an&lt;span style=&quot;color: #ee2323;&quot;&gt;p&lt;/span&gt; | &lt;span style=&quot;color: #006dd7;&quot;&gt;grep&lt;/span&gt; LISTEN&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dD361h/btqOtZTfPA9/HwNNNkoo5uPwRt5KOrkWJK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dD361h/btqOtZTfPA9/HwNNNkoo5uPwRt5KOrkWJK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dD361h/btqOtZTfPA9/HwNNNkoo5uPwRt5KOrkWJK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdD361h%2FbtqOtZTfPA9%2FHwNNNkoo5uPwRt5KOrkWJK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;James가 제대로 실행되었으면,&lt;/p&gt;
&lt;p&gt;다음 명령어로 앞서 지정한 도메인을 제임스에 등록하고, ListDomains으로 확인한다 (다음 주의사항 확인).&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 윈도우: james-cli.bat adddomain forest71.com&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 리눅스: ./james-cli.sh AddDomain forest71.com&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;주의&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;James 설치 문서에서는 위와 같이 실행하라고 하는데,&lt;br /&gt;domainlist.xml 파일에서 사용할 도메인(forest71.com)을 지정했기 때문에 추가하지 않아도 된다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;다음 명령어로(adduser) 메일 사용자(계정@도메인)을 생성하고 ListUsers로 확인한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; james-cli AddUser gujc1@forest71.com gujc1234&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/butVtO/btqOpqRNuY3/zvtlpTSPK4IBa7nc30LeQ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/butVtO/btqOpqRNuY3/zvtlpTSPK4IBa7nc30LeQ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/butVtO/btqOpqRNuY3/zvtlpTSPK4IBa7nc30LeQ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbutVtO%2FbtqOpqRNuY3%2FzvtlpTSPK4IBa7nc30LeQ1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;이상으로 James 설치 방법을 윈도우 중심으로 정리하였다.&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;윈도우나 리눅스나 기본적인 설치 / 사용 방법은 동일하다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;윈도우는 윈도우 서비스에 등록해서(james install) 사용하는 차이만 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;(굳이 추가하면 bat를 사용하느냐? sh을 사용하느냐의 차이도 있다.)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;
&lt;p&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;주의&lt;/b&gt;&lt;/span&gt;: 리눅스(Linux)에는 기본적으로 Postfix나 Sendmail이 설치된 경우가 있다.&lt;/p&gt;
&lt;p&gt;설치전에 netstat 로 25번 포트를 사용하는 프로그램이 있는지 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;설치된 경우에는 James를 실행할때, wrapper.log에 포트 중복 오류가 발생한다.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;James 설치 방법을 한마디로 정리하면, James 메일 도메인과 메일 사용자를 등록해서 실행하는 것이다.&lt;/p&gt;
&lt;p&gt;기본적인 설정만으로도 내부 메일은 문제없이 사용할 수 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이제 메일을 보내고 받으면 되는데, &lt;a href=&quot;https://forest71.tistory.com/218&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;메일을 송수신&lt;/a&gt;하는 방법과 좀더 &lt;a href=&quot;https://forest71.tistory.com/217&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;상세한 설정&lt;/a&gt;은 다른 페이지에 정리하였다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>서버/메일</category>
      <author>forest71</author>
      <guid isPermaLink="true">https://forest71.tistory.com/216</guid>
      <comments>https://forest71.tistory.com/216#entry216comment</comments>
      <pubDate>Sun, 6 Dec 2020 19:33:27 +0900</pubDate>
    </item>
    <item>
      <title>2. Apache James 메일 서버 - 설정</title>
      <link>https://forest71.tistory.com/217</link>
      <description>&lt;p&gt;앞서서 James의 conf 폴더에 있는 여러 설정 파일 중에서 domainlist.xml, mailetcontainer.xml에서 도메인을(forest71.com) 수정해서 실행하였다.&lt;/p&gt;
&lt;p&gt;여기에서는 몇 가지(알고 있는 or 중요한) 설정에 대해서 정리한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://forest71.tistory.com/216&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Apache James 메일 서버 - 설치&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Apache James 메일 서버 - 설정&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://forest71.tistory.com/218&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Apache James 메일 서버 - 메일 클라이언트&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://forest71.tistory.com/219&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Apache James 메일 서버 - Text와 JPA(MariaDB등)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://forest71.tistory.com/221&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Apache James 메일 서버 - 스팸 필터 (SpamAssassin)&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;먼저 확인할 설정 파일은&lt;/p&gt;
&lt;p&gt;&lt;b&gt;메일을 보낼 때 사용하는 프로토콜인 SMTP (smtpserver.xml),&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;수신한 메일을 확인하기 위해 사용하는 프로토콜인 IMAP (imapserver.xml) 이다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;POP3 (pop3server.xml) 프로토콜도 있지만 과거에 많이 사용하던 것으로, IMAP 사용이 권장되고 설정 방법도 비슷해서 여기에서는 정리하지 않는다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;SMTP와 관련해서 설정하는 smtpserver.xml의 내용은(주석 제거) 다음과 같다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&amp;lt;smtpservers&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;span style=&quot;color: #ee2323;&quot;&gt;smtpserver&lt;/span&gt; enabled=&quot;true&quot;&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;span style=&quot;color: #006dd7;&quot;&gt;jmxName&lt;/span&gt;&amp;gt;smtpserver&amp;lt;/jmxName&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;span style=&quot;color: #ee2323;&quot;&gt;bind&lt;/span&gt;&amp;gt;0.0.0.0:&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;25&lt;/b&gt;&lt;/span&gt;&amp;lt;/bind&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;connectionBacklog&amp;gt;200&amp;lt;/connectionBacklog&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;span style=&quot;color: #ee2323;&quot;&gt;tls&lt;/span&gt; socketTLS=&quot;false&quot; startTLS=&quot;false&quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;span style=&quot;color: #006dd7;&quot;&gt;keystore&lt;/span&gt;&amp;gt;file://conf/keystore&amp;lt;/keystore&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;span style=&quot;color: #006dd7;&quot;&gt;secret&lt;/span&gt;&amp;gt;yoursecret&amp;lt;/secret&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;provider&amp;gt;org.bouncycastle.jce.provider.BouncyCastleProvider&amp;lt;/provider&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;algorithm&amp;gt;SunX509&amp;lt;/algorithm&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/tls&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;connectiontimeout&amp;gt;360&amp;lt;/connectiontimeout&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;connectionLimit&amp;gt;0&amp;lt;/connectionLimit&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;connectionLimitPerIP&amp;gt;0&amp;lt;/connectionLimitPerIP&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;span style=&quot;color: #ee2323;&quot;&gt;authorizedAddresses&lt;/span&gt;&amp;gt;127.0.0.0/8&amp;lt;/authorizedAddresses&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;maxmessagesize&amp;gt;0&amp;lt;/maxmessagesize&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;addressBracketsEnforcement&amp;gt;true&amp;lt;/addressBracketsEnforcement&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;handlerchain&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;handler class=&quot;org.apache.james.smtpserver.fastfail.ValidRcptHandler&quot;/&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;handler class=&quot;org.apache.james.smtpserver.CoreCmdHandlerLoader&quot;/&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/handlerchain&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;lt;/smtpserver&amp;gt;&lt;br /&gt;&amp;lt;/smtpservers&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;text-align: right;&quot;&gt;smtpserver.xml&lt;/p&gt;
&lt;p&gt;&amp;lt;smtpserver&amp;gt;속성 enabled값이 true면 SMTP를 사용하는 것이고, false이면 사용하지 않는다 (메일을 보내고 받을&amp;nbsp; 수 없다).&lt;/p&gt;
&lt;p&gt;&amp;lt;bind&amp;gt;의 25는 사용할 포트를 지정하는 것으로, SMTP는 25번 외에 465, 587번 포트를 사용할 수 있다.&lt;/p&gt;
&lt;p&gt;이 포트는 &amp;lt;tls&amp;gt;에서 어떤 인증 방식을 사용하는지에 따라 결정한다.&lt;/p&gt;
&lt;p&gt;25번은 일반적인 통신에(socketTLS=&quot;false&quot; startTLS=&quot;false&quot;) 많이 사용하고,&lt;/p&gt;
&lt;p&gt;465, 587번은 SSL(Secure Sockets Layer)이나 TLS(Transport Layer Security)를 사용할 때 지정한다.&lt;/p&gt;
&lt;p&gt;위의 포트 번호를 바꿔도 돼고, smtpserver 속성(smtpserver&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;s&lt;/span&gt;&lt;/b&gt;내에 있는) 전체를 복사해서 하나 더 만들어도 된다.&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;2개이상을 사용할 경우에는 &amp;lt;jmxName&amp;gt;의 이름을 다르게 부여해야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;25번 포트의 &amp;lt;jmxName&amp;gt;는 smtpserver이니, 다른 포트는 smtpserver_ssl 등의 이름으로 지정한다.&lt;/p&gt;
&lt;p&gt;이외에 &amp;lt;keystore&amp;gt; 속성에 인증서 파일이나 JKS 파일을 지정하고, &amp;lt;secret&amp;gt; 속성에 비밀번호를 지정해서 인증서(SSL, TLS)를 사용한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;마지막으로 &amp;lt;authorizedAddresses&amp;gt; 속성은 인증 주소를 의미한다.&lt;/p&gt;
&lt;p&gt;SMTP, IMAP등은 원격에서 메일 서버에 접속하는 것으로 아이디와 비번을 이용하여 로그인을 해야한다.&lt;/p&gt;
&lt;p&gt;&amp;lt;authorizedAddresses&amp;gt;는 이러한 로그인을 하지 않아도 되는 IP주소를 의미한다.&lt;/p&gt;
&lt;p&gt;주로, 그룹웨어나 ERP등의 시스템에서 알림 메일등을 발송할때 해당 시스템 서버의 IP를 지정해서 로그인없이 메일을 발송할때 유용하다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이외에도 다양한 설정이 있고, 주석으로 작성되어 있지만 스팸 차단 프로그램과 연동하는 SpamAssassinHandler나 스팸 발송 업체들(IP)를 차단하는 URIRBLHandler등의 기능도 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;IMAP을 설정하는 &lt;a href=&quot;http://imapserver.xml&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;imapserver.xml&lt;/a&gt;에서는 다음과 같이 사용할 포트를 지정하고, 인증서(SSL, TLS)를 사용할지 결정한다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&amp;lt;imapservers&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;imapserver enabled=&quot;true&quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;span style=&quot;color: #006dd7;&quot;&gt;jmxName&lt;/span&gt;&amp;gt;imapserver&amp;lt;/jmxName&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;span style=&quot;color: #ee2323;&quot;&gt;bind&lt;/span&gt;&amp;gt;0.0.0.0:&lt;span style=&quot;color: #006dd7;&quot;&gt;143&lt;/span&gt;&amp;lt;/bind&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;connectionBacklog&amp;gt;200&amp;lt;/connectionBacklog&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;span style=&quot;color: #ee2323;&quot;&gt;tls&lt;/span&gt; socketTLS=&quot;false&quot; startTLS=&quot;false&quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;keystore&amp;gt;file://conf/keystore&amp;lt;/keystore&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;secret&amp;gt;yoursecret&amp;lt;/secret&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;provider&amp;gt;org.bouncycastle.jce.provider.BouncyCastleProvider&amp;lt;/provider&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/tls&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;connectionLimit&amp;gt;0&amp;lt;/connectionLimit&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;connectionLimitPerIP&amp;gt;0&amp;lt;/connectionLimitPerIP&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/imapserver&amp;gt;&lt;br /&gt;&amp;lt;/imapservers&amp;gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;text-align: right;&quot;&gt;imapserver.xml&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;SMTP와 사용법은 동일하고 사용하는 포트만 143으로 차이가 있다.&lt;/p&gt;
&lt;p&gt;인증서(SSL, TLS)를 사용할 경우에는 993 포트를 사용하고,&amp;nbsp; SMTP와 같이 2개의 포트를 지정할 수 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 120px;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 120px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 120px;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;SMTP, IMAP과 SSL(TLS)에 대한 정리&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;아웃룩, 썬더버드등의 메일 클라이언트 프로그램을 MUA(Mail User Agent)이라고 한다.&lt;br /&gt;이런 프로그램을 이용하여 메일 작성하면 SMTP를 이용하여 메일 서버로 보내고,&lt;br /&gt;해당 메일서버는 다른 메일 서버로 SMTP를 이용하여 메일을 발송한다&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Mail Transfer Agent - MTA)&lt;/span&gt;. &lt;br /&gt;메일 전송은 모두 SMTP 프로토콜이다 (많은 사람이 혼동했다).&lt;br /&gt;메일 서버에서 수신한 메일을 가지고 오는 것은 IMAP/POP3 프로토콜이다.&lt;br /&gt;&lt;br /&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cYERwT/btqOt05UQN7/1gkG3wQNi5BRmhNEj8o0xk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cYERwT/btqOt05UQN7/1gkG3wQNi5BRmhNEj8o0xk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cYERwT/btqOt05UQN7/1gkG3wQNi5BRmhNEj8o0xk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcYERwT%2FbtqOt05UQN7%2F1gkG3wQNi5BRmhNEj8o0xk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br /&gt;&lt;br /&gt;여기에 별도로 정리하는 것은 인증서 사용에 대해서 혼동하는 경우가 많기 때문으로,&lt;br /&gt;&lt;br /&gt;당연이 IMAP/POP3 에서 인증서를 지정하면, 서버에서 메일을 가지고 올때 지정된 인증서로 암호화 해서 가지고 온다.&lt;br /&gt;그리고, SMTP에 인증서를 지정하면, 지정된 인증서로 메일을 암호화해서 메일 서버로 전송한다.&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;하지만, 이 메일을 다른 메일 서버로 보낼 때에는 상대 서버에 지정된 인증서를 사용한다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;당연한 개념인데, 자신의 메일 서버에 지정된 인증서로 암호화해서 보내는 것이 아니고&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;상대 서버의 인증서로 암호화해서 상대 서버로 보내게 된다.&lt;/span&gt;&lt;br /&gt;자신의 서버에 인증서를 지정하지 않아도 보안 메일을 보낼 수 있는데, &lt;br /&gt;자신의 서버에 인증서를 설치하지 않아서 보안 메일을 사용하지 않는 경우가 있다 (누군가의 경험).&lt;br /&gt;&lt;br /&gt;이 내용은 다음의 mailetcontainer.xml 정리에서 gmail을 대상으로한 예제에서 확인할 수 있다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;다음은 James에서 가장 중요하고(?) 복잡한 mailetcontainer.xml파일이다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;James가 메일을 처리하는 과정을 통제하는 부분으로 플러그인을 개발해서 부족한 기능을 구현할 수 있다.&lt;/p&gt;
&lt;p&gt;기업에서 많이 사용하는 자동 포워딩이나 자동 분류 등의 다양한 부가 기능을 구현할 수 있는데,&lt;/p&gt;
&lt;p&gt;여기에서 정리할 수 없고 아직 분석(?) 중에 있다.&lt;/p&gt;
&lt;p&gt;간단하게 정리하면 processor와 match가 중심인데, processor는 여러가지 처리 단계를 의미하고, match는 일종의 if문을 의미한다.&lt;/p&gt;
&lt;p&gt;즉, 메일이 어떤 조건에 맞으면 (match) 특정한 일을(class) 하거나 특정한 processor로 이동하도록 한다(ToProcessor).&lt;/p&gt;
&lt;p&gt;class에는 실제 Java 클래스를 지정해서 원하는 일을 하도록 한다.&lt;/p&gt;
&lt;p&gt;여러가지 조건들은 &lt;a href=&quot;https://james.apache.org/server/3/dev-provided-matchers.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Apach James 문서를&lt;/a&gt; 참고하면 된다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;다만, 여기서는 몇 가지 사항만 정리한다.&lt;/p&gt;
&lt;p&gt;먼저, 다음 match를 제거해야 외부로 메일을 보낼 수 있다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&amp;lt;mailet match=&quot;RemoteAddrNotInNetwork=127.0.0.1&quot; class=&quot;ToProcessor&quot;&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;processor&amp;gt;relay-denied&amp;lt;/processor&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;notice&amp;gt;550 - Requested action not taken: relaying denied&amp;lt;/notice&amp;gt;&lt;br /&gt;&amp;lt;/mailet&amp;gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;text-align: right;&quot;&gt;mailetcontainer.xml&lt;/p&gt;
&lt;p&gt;내부(LocalDelivery)는 현재 James 메일 서버에 등록된 도메인의 계정끼리 메일을 주고 받는 것을 의미하고,&lt;/p&gt;
&lt;p&gt;외부(RemoteDelivery)는 Gmail등의 다른 메일서버로 메일을 보내는 것을 의미한다.&lt;/p&gt;
&lt;p&gt;외부주소가 127.0.0.1이 아니면 relay-denied라는 processor로 보내서 메일을 발송하지 않고 종료한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이 match를 제거하고, 구글 gmail로 메일을 발송하면 다음과 같이 잘 발송되는 것을 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ANMu1/btqPe2aynxR/m4G3Bb9AKEbVgVukve6J81/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ANMu1/btqPe2aynxR/m4G3Bb9AKEbVgVukve6J81/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ANMu1/btqPe2aynxR/m4G3Bb9AKEbVgVukve6J81/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FANMu1%2FbtqPe2aynxR%2Fm4G3Bb9AKEbVgVukve6J81%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;[받은 편지함]에 메일이 없다면 [스팸 메일함]에 있을 것이다 (이유는 다양).&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;수신한 메일에서 [나에게] 옆에 빨간색 아이콘을 클릭하면 다음과 같은 그림을 볼 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/caglyL/btqPfSlcZ6a/xKy6fXNhY4pQEihOTxAKWK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/caglyL/btqPfSlcZ6a/xKy6fXNhY4pQEihOTxAKWK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/caglyL/btqPfSlcZ6a/xKy6fXNhY4pQEihOTxAKWK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcaglyL%2FbtqPfSlcZ6a%2FxKy6fXNhY4pQEihOTxAKWK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;[암호화 기능 사용하지 않음]이라고 표시되는데, 메일을 암호화하지 않고 평문 메일로 받았다는 것이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;다음과 같이 RemoteDelivery에 startTLS 속성을 추가하고, James를 재가동한 후에 메일을 보낸다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&amp;nbsp;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;lt;mailet&amp;nbsp;match=&quot;All&quot;&amp;nbsp;class=&quot;RemoteDelivery&quot;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;outgoing&amp;gt;outgoing&amp;lt;/outgoing&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;startTLS&amp;gt;true&amp;lt;/startTLS&amp;gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;text-align: right;&quot;&gt;mailetcontainer.xml&lt;/p&gt;
&lt;p&gt;다음과 같이 안전한 메일로 표시되는 것을 볼 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bg5Pxd/btqPaUK9okT/ArYioESjw0HCcXboduykL0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bg5Pxd/btqPaUK9okT/ArYioESjw0HCcXboduykL0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bg5Pxd/btqPaUK9okT/ArYioESjw0HCcXboduykL0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbg5Pxd%2FbtqPaUK9okT%2FArYioESjw0HCcXboduykL0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;이렇게 암호화된 메일을 주고 받는 경우, 수신 서버가 개발자 SSL등 개발 인증서를 사용하여 설치한 경우에는(상용 인증서) 메일을 수신할 수 없다.&lt;/p&gt;
&lt;p&gt;다음과 같이 RemoteDelivery 클래스의 설정에 mail.smtp.ssl.trust를 추가해서 사용한다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&amp;nbsp;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;lt;mailet&amp;nbsp;match=&quot;All&quot;&amp;nbsp;class=&quot;RemoteDelivery&quot;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;outgoing&amp;gt;outgoing&amp;lt;/outgoing&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;startTLS&amp;gt;true&amp;lt;/startTLS&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color: #ee2323;&quot;&gt;&amp;lt;mail.smtp.ssl.trust&amp;gt;*&amp;lt;/mail.smtp.ssl.trust&amp;gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;text-align: right;&quot;&gt;mailetcontainer.xml&lt;/p&gt;
&lt;p&gt;RemoteDelivery에는 다양한 속성이 있으니, &lt;a href=&quot;https://james.apache.org/server/3/apidocs/org/apache/james/transport/mailets/RemoteDelivery.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;James 문서를&lt;/a&gt; 참고해서 익혀 두는 것이 좋다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이 외에도 mailetcontainer.xml 파일에는 메일과 관련된 다양한 처리를 설정할 수 있다.&lt;/p&gt;
&lt;p&gt;다양한 기능들이 주석으로 처리되어 사용자가 선택해서 사용할 수 있다.&lt;/p&gt;
&lt;p&gt;예로, 다음 설정은 첨부 파일의 확장자를 확인해서 제한하는 기능으로 주석을(&amp;lt;!-- --&amp;gt;) 해제하면 사용할 수 있다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&amp;lt;!-- Check attachment extensions for possible viruses --&amp;gt;&lt;br /&gt;&amp;lt;!-- The &quot;-z&quot; option requests the check to be non-recursively applied --&amp;gt;&lt;br /&gt;&amp;lt;!-- to the contents of any attached '*.zip' file. --&amp;gt;&lt;br /&gt;&amp;lt;!-- &lt;br /&gt;&amp;lt;mailet match=&quot;AttachmentFileNameIs=-d -z *.exe *.com *.bat *.cmd *.pif *.scr *.vbs *.avi *.mp3 *.mpeg *.shs&quot; class=&quot;Bounce&quot; onMatchException=&quot;error&quot;&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;inline&amp;gt;heads&amp;lt;/inline&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;attachment&amp;gt;none&amp;lt;/attachment&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;passThrough&amp;gt;false&amp;lt;/passThrough&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;prefix&amp;gt;[REJECTED]&amp;lt;/prefix&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;notice&amp;gt;&lt;br /&gt;The Security Policy of XXX does not allow to forward messages containing attachments having any of the extensions .exe, .com, .bat, .cmd, .pif, .scr, .vbs, .avi, .mp3, .mpeg, .shs, therefore your message has been rejected.&lt;br /&gt;&lt;br /&gt;Please don't reply to this e-mail as it has been automatically sent by the antivirus system.&lt;br /&gt;&lt;br /&gt;Regards, Postmaster XXX.YYY&lt;br /&gt;.....................................&lt;br /&gt;&amp;nbsp; &amp;lt;/notice&amp;gt;&lt;br /&gt;&amp;lt;/mailet&amp;gt;&lt;br /&gt;&amp;nbsp;--&amp;gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;다음 설정은 내부 사용자가 메일을 보내면(SenderIsLocal),&amp;nbsp; 발신자의 보낸 편지함(Sent)에 메일을 저장하도록하는 설정이다.&lt;/p&gt;
&lt;p&gt;이 설정은 기본 사용으로 되어 있는데, MUA로 메일을 발송하는 경우 MUA에서 보낸 편지함에 저장하고 James에서도 보낸 편지함에 저장하면서 MUA의 보낸 편지함에 2개의 동일한 메일이 저장된다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;!-- Place a copy in the user Sent folder --&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;mailet&amp;nbsp;match=&quot;SenderIsLocal&quot;&amp;nbsp;class=&quot;ToSenderFolder&quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;folder&amp;gt;Sent&amp;lt;/folder&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;consume&amp;gt;false&amp;lt;/consume&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/mailet&amp;gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Apache James에서 이 기능을 중지하고 사용해면 해결되는데,&lt;/p&gt;
&lt;p&gt;Apache James를 기반으로 웹 메일을 구축한 경우 서버에 보낸 메일이 남지않는 문제가 생긴다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;mailbox.xml는 주고 받은 메일을 저장하는 형태를 지정하는 파일이다.&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&amp;lt;mailbox&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;lt;!-- supported providers are: --&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;lt;!--&lt;span style=&quot;color: #006dd7;&quot;&gt; jpa, maildir, memory&lt;/span&gt; --&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;lt;!-- Be aware that maildir will only work on unix like operation systems! --&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;lt;provider&amp;gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;jpa&lt;/span&gt;&lt;/b&gt;&amp;lt;/provider&amp;gt;&lt;br /&gt;&amp;lt;/mailbox&amp;gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;text-align: right;&quot;&gt;mailbox.xml&lt;/p&gt;
&lt;p&gt;jpa, maildir, memory의 세가지 방식이 제공되는데,&lt;/p&gt;
&lt;p&gt;jpa는 OpenJPA를 이용하여 메일 정보를 각종 데이터 베이스 (MariaDB, Oracle 등)에 저장하여 관리하는 것으로 기본 설정으로 지정되어 있다.&lt;/p&gt;
&lt;p&gt;maildir는 하나의 메일을 EML 파일로 저장하고, 전체 리스트등을 Text 파일로 관리하는 방식을 의미한다.&lt;/p&gt;
&lt;p&gt;메일 사용자, 도메인 등은 jpa와 동일하게 OpenJPA를 이용하여 데이터베이스에 저장된다.&lt;/p&gt;
&lt;p&gt;memory는 일종의 테스트 용으로 maildir와 유사하지만 메일 정보를 파일이 아닌 메모리에 저장한다.&lt;/p&gt;
&lt;p&gt;James를 재가동하면 메일 송수신 내역이 사라진다.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://forest71.tistory.com/219&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;이 3가지 방법에 대한 자세한 사용 방법은 따로 정리하였다.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;이외에도 cassandra등이 지원된다고 한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;개인적으로 메일의 첨부 파일을 데이터 베이스에 저장하는 것을(jpa방식) 좋게 생각하지 않는데,&lt;/p&gt;
&lt;p&gt;maildir는 개인별 메일 리스트를 Text 파일로 관리하면서, 메일 양이 많은 경우 속도가 떨어지는 문제가 있다.&lt;/p&gt;
&lt;p&gt;(왜 속도가 떨어지는지 해당 코드를 분석해서 알고 있지만 수정해서 기여할 여력(?)이...)&lt;/p&gt;
&lt;p&gt;따라서, 메일의 헤더(보낸사람, 받는사람, 제목등)는 데이터베이스에&lt;/p&gt;
&lt;p&gt;양이 많은 본문과 첨부 파일은 파일로 저장하는 방식이 좋을 것 같아서 방법을 찾고 있다.&lt;/p&gt;
&lt;p&gt;특히, 웹 메일을 구현하려면 JPA 방식으로 구현되어야 하는데, 첨부 파일을 데이터베이스에 저장하는 것이...&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://forest71.tistory.com/219&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;자세한 사용 방법은 따로 정리하였다&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;다음 파일은 JPA 사용시 접속할 데이터베이스 접속 정보를 지정하는 james-database.properties 파일이다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;사용할 데이터베이스(database=DERBY)를 지정하고,&lt;/p&gt;
&lt;p&gt;JAVA에서 JDBC를 이용해서 데이터베이스에 접속하는 4가지 기본 정보를 지정하면 된다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;database.driverClassName=org.apache.derby.jdbc.EmbeddedDriver&lt;br /&gt;database.url=jdbc:derby:../var/store/derby;create=true&lt;br /&gt;database.username=app&lt;br /&gt;database.password=app&lt;br /&gt;&lt;br /&gt;# Supported adapters are:&lt;br /&gt;# &lt;span style=&quot;color: #006dd7;&quot;&gt;DB2, DERBY, H2, HSQL, INFORMIX, MYSQL, ORACLE, POSTGRESQL, SQL_SERVER, SYBASE&lt;/span&gt; &lt;br /&gt;vendorAdapter.database=DERBY&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;openjpa.streaming=false&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;text-align: right;&quot;&gt;james-database.properties&lt;/p&gt;
&lt;p&gt;&lt;b&gt;다음 파일은 usersrepository.xml로 사용자 계정의 암호화 방식을 지정한다.&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;
&lt;p&gt;&amp;lt;!-- JPA based backend. Support password algorithm are:&lt;br /&gt;&amp;nbsp; &lt;span style=&quot;color: #006dd7;&quot;&gt;MD5, SHA-256, SHA-512, NONE&lt;/span&gt;&lt;br /&gt;--&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;usersrepository name=&quot;LocalUsers&quot; class=&quot;org.apache.james.user.jpa.JPAUsersRepository&quot;&amp;gt;&lt;/p&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;algorithm&amp;gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;MD5&lt;/span&gt;&amp;lt;/algorithm&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;enableVirtualHosting&amp;gt;true&amp;lt;/enableVirtualHosting&amp;gt;&lt;br /&gt;&amp;lt;/usersrepository&amp;gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;text-align: right;&quot;&gt;usersrepository.xml&lt;/p&gt;
&lt;p&gt;기본은 MD5인데 SHA-256을 지정해서 사용하는 것이 좋다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;마지막으로 정리할 파일은 wrapper.conf로 사용할 메모리를 지정 등 Java 실행 환경을 지정할 수 있다.&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;# Initial Java Heap Size (in MB)&lt;br /&gt;#wrapper.java.initmemory=3&lt;br /&gt;wrapper.java.initmemory=128&lt;br /&gt;&lt;br /&gt;# Maximum Java Heap Size (in MB)&lt;br /&gt;#wrapper.java.maxmemory=64&lt;br /&gt;wrapper.java.maxmemory=512&lt;br /&gt;&lt;br /&gt;# Log Level for console output.&amp;nbsp; (See docs for log levels)&lt;br /&gt;wrapper.console.loglevel=INFO&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;text-align: right;&quot;&gt;wrapper.conf&lt;/p&gt;
&lt;p&gt;기본적으로 메모리를 MB 단위로 지정했는데, 처리 양이 많은 경우 GB 단위로 하는 것이 좋고,&lt;/p&gt;
&lt;p&gt;James의 각종 처리를 확인하기 위해서는 로그 단위를 INFO보다 DEBUG등으로 하는 것이 좋다.&lt;/p&gt;
&lt;p&gt;James 로그는 Log4J를 사용하나 Log4J를 찾아보고, log4j2.xml에서 설정한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>서버/메일</category>
      <author>forest71</author>
      <guid isPermaLink="true">https://forest71.tistory.com/217</guid>
      <comments>https://forest71.tistory.com/217#entry217comment</comments>
      <pubDate>Sun, 6 Dec 2020 19:33:05 +0900</pubDate>
    </item>
    <item>
      <title>3. Apache James 메일 서버 - 메일 클라이언트</title>
      <link>https://forest71.tistory.com/218</link>
      <description>&lt;p&gt;&amp;nbsp;&lt;br /&gt;앞서 설치한 Apache James 메일 서버에 접속해서 메일을 보내고 받는 방법을 정리한다.&lt;/p&gt;
&lt;p&gt;메일을 보내고 받는 방법은 간단하게는 텔넷(telnet)을 이용할 수 있고, 전용 프로그램(Mail Transfer Agent - MTA)을 설치해서 이용할 수도 있다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://forest71.tistory.com/216&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Apache James 메일 서버 - 설치&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://forest71.tistory.com/217&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Apache James 메일 서버 - 설정&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Apache James 메일 서버 - 메일 클라이언트&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://forest71.tistory.com/219&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Apache James 메일 서버 - Text와 JPA(MariaDB등)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://forest71.tistory.com/221&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Apache James 메일 서버 - 스팸 필터 (SpamAssassin)&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;사전 작업&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;메일 접속을 하기 전에, 앞서 James를 실행하면서 지정한 forest71.com 도메인을 등록한다.&lt;/p&gt;
&lt;p&gt;실제 도메인을 사용한 경우에는 신경 쓰지 않아도 되지만, 개발자가 임의로 지정한 도메인인 경우에는 운영체제에 임의로 등록해서 사용해야 한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;먼저 James를 설치한 PC가 윈도우일 경우에는 윈도우 시작 메뉴에서 관리자 권한으로 메모장을 실행하고,&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sEp2l/btqOvSe75NM/5aBVnnkKZsvAKqKbzjzZvK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sEp2l/btqOvSe75NM/5aBVnnkKZsvAKqKbzjzZvK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sEp2l/btqOvSe75NM/5aBVnnkKZsvAKqKbzjzZvK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsEp2l%2FbtqOvSe75NM%2F5aBVnnkKZsvAKqKbzjzZvK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;C:\Windows\System32\drivers\etc 폴더에 있는 hosts 파일을 열어서 다음과 같이 수정한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c9hkjO/btqOuGTL2kc/y6MuJwka7M4VpOI5SmTFxK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c9hkjO/btqOuGTL2kc/y6MuJwka7M4VpOI5SmTFxK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c9hkjO/btqOuGTL2kc/y6MuJwka7M4VpOI5SmTFxK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc9hkjO%2FbtqOuGTL2kc%2Fy6MuJwka7M4VpOI5SmTFxK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;127.0.0.1은 현재 사용 중인 PC를 의미하고,&lt;/p&gt;
&lt;p&gt;임의로 지정한 forest71.com 도메인은 127.0.0.1를 가르키도록 지정했다.&lt;/p&gt;
&lt;p&gt;다른 PC에 제임스를 실행한 경우에는 해당 PC의 IP를 지정하면 된다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;리눅스일 경우에는 etc/hosts를 관리자 권한으로 수정한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sudo vi /etc/hosts&lt;/p&gt;
&lt;p&gt;윈도우와 동일하게 127.0.0.1을 임의의 도메인 forest71.com로 지정한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZdMfE/btqOt0dS1pV/XDwaek2c8CVFvP4xXEAVm0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZdMfE/btqOt0dS1pV/XDwaek2c8CVFvP4xXEAVm0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZdMfE/btqOt0dS1pV/XDwaek2c8CVFvP4xXEAVm0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZdMfE%2FbtqOt0dS1pV%2FXDwaek2c8CVFvP4xXEAVm0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;네트워크 상태를 점검하는 명령어인 ping으로 forest71.com의 IP를 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ping forest71.com&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/caKv76/btqOtZMSc6e/Fn6hymqviNvqCrNgPopZSk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/caKv76/btqOtZMSc6e/Fn6hymqviNvqCrNgPopZSk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/caKv76/btqOtZMSc6e/Fn6hymqviNvqCrNgPopZSk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcaKv76%2FbtqOtZMSc6e%2FFn6hymqviNvqCrNgPopZSk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;1. 텔넷(Telnet)&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;텔넷은 간단하게 메일 서버가 제대로 작동하는지 확인하기 위해 많이 사용하는 방법으로, 각종 명령어를 직접 입력해야 하는 불편함이 있다.&lt;/p&gt;
&lt;p&gt;하지만, 폐쇄망일 경우에 별도의 MUA를 설치할 수 없는 경우가 많아, 많은 사람들이 이용하는 방법이다.&lt;/p&gt;
&lt;p&gt;리눅스일 경우에는 기본 설치되어 있고, 윈도우는 추가 설치를 해야 한다.&lt;/p&gt;
&lt;p&gt;설치 방법은&lt;a href=&quot;https://www.google.com/search?client=firefox-b-d&amp;amp;q=%EC%9C%88%EB%8F%84%EC%9A%B0+%ED%85%94%EB%84%B7&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt; [윈도우 텔넷]으로 검색하면&lt;/a&gt; 쉽게 찾을 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;텔넷을 설치한 후에, 운영체제에 관계없이 콘솔에서 다음 명령어 중 하나로 텔넷을 실행한다.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;메일 발송(SMTP-25)을 먼저 테스트한다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; telnet localhost 25 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; telnet 1270.0.01 25 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; telnet forest71.com 25&lt;/p&gt;
&lt;p&gt;localhost는 현재 텔넷을 실행한 컴퓨터의 도메인을 의미하는 것으로 127.0.0.1과 같은 의미이다.&lt;/p&gt;
&lt;p&gt;메일 서버가 텔넷을 실행하는 서버에 있는 경우 위와 같이 IP를 지정하고, 다른 서버에 있는 경우에는 해당 메일 서버의 도메인이나 IP를 지정한다.&lt;/p&gt;
&lt;p&gt;메일을 발송할 것이라 SMTP 포트인 25번으로 접속한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;당연하겠지만 메일을 가져올 때는 IMAP 포트인 143으로 접속한다.&lt;/p&gt;
&lt;p&gt;모든 설정이 제대로 된 경우 다음과 같은 SMTP 메시지가 입력되고 커서가 깜박인다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dR51tl/btqOqTUeLGS/3RpJz4o7xVv97gmKbhJkk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dR51tl/btqOqTUeLGS/3RpJz4o7xVv97gmKbhJkk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dR51tl/btqOqTUeLGS/3RpJz4o7xVv97gmKbhJkk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdR51tl%2FbtqOqTUeLGS%2F3RpJz4o7xVv97gmKbhJkk0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;ehlo 명령어로 메일 전송을 시작한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ehlo test&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bZuXpD/btqOtFnzRdb/8G07TNu7KuDm0PlGQ3fLp1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bZuXpD/btqOtFnzRdb/8G07TNu7KuDm0PlGQ3fLp1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bZuXpD/btqOtFnzRdb/8G07TNu7KuDm0PlGQ3fLp1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbZuXpD%2FbtqOtFnzRdb%2F8G07TNu7KuDm0PlGQ3fLp1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;ehlo 다음에는 아무 값이나 입력하면 된다.&lt;/p&gt;
&lt;p&gt;위와 같은 메시지가 출력되면,&lt;/p&gt;
&lt;p&gt;메일을 보내는 사람 mail from:&amp;lt;gujc1@forest71.com&amp;gt;&lt;/p&gt;
&lt;p&gt;메일을 받는 사람 rcpt to:&amp;lt;gujc1@forest71.com&amp;gt;&lt;/p&gt;
&lt;p&gt;을 입력하고 메일 내용을 작성하기 위해 data를 입력하고 &amp;lt;enter&amp;gt;키를 누른다.&lt;/p&gt;
&lt;p&gt;메일 제목을 입력하고 Subject:&amp;nbsp;test&amp;nbsp;mail&lt;/p&gt;
&lt;p&gt;본문을 입력한 뒤에 this&amp;nbsp;is&amp;nbsp;a&amp;nbsp;test&amp;nbsp;mail&lt;/p&gt;
&lt;p&gt;점(.)을 입력하고 &amp;lt;enter&amp;gt;키를 누르면 메일이 발송된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bZV0Kn/btqOtZTHSgh/0kfFjgJoGlq0btQRnnkHw0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bZV0Kn/btqOtZTHSgh/0kfFjgJoGlq0btQRnnkHw0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bZV0Kn/btqOtZTHSgh/0kfFjgJoGlq0btQRnnkHw0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbZV0Kn%2FbtqOtZTHSgh%2F0kfFjgJoGlq0btQRnnkHw0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;메일 제목을(Subject) 입력한 뒤에 &amp;lt;enter&amp;gt;키를 눌러 &amp;lt;CRLF&amp;gt;를 추가하고 메시지를 입력해야&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;메일 제목과 본문이 구분된다.&lt;/p&gt;
&lt;p&gt;그렇지 않으면 제목이 없는 메일이 발송된다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;이번에는 받은 메일을 가져오는 IMAP을 연습해 보기 위해 콘솔에서 다음 명령어 중 하나로 텔넷을 실행한다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; telnet localhost 143 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; telnet 1270.0.01 143 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; telnet forest71.com 143&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cWtrwa/btqOzBxepMK/15ksSQQ1lO5oxpV5Tna4qk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cWtrwa/btqOzBxepMK/15ksSQQ1lO5oxpV5Tna4qk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cWtrwa/btqOzBxepMK/15ksSQQ1lO5oxpV5Tna4qk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcWtrwa%2FbtqOzBxepMK%2F15ksSQQ1lO5oxpV5Tna4qk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;IMAP 환영 메시지가 나오면,&lt;/p&gt;
&lt;p&gt;메시지를 확인할 계정과 비밀번호를 지정해서 다음과 같이 login을 한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; a login&amp;nbsp; gujc1@forest71.com gujc1234&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Gn2uU/btqOveW7tt7/7UOSI7DwmYpOmZECD7ocy1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Gn2uU/btqOveW7tt7/7UOSI7DwmYpOmZECD7ocy1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Gn2uU/btqOveW7tt7/7UOSI7DwmYpOmZECD7ocy1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGn2uU%2FbtqOveW7tt7%2F7UOSI7DwmYpOmZECD7ocy1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;list 명령어로 로그인한 계정의 메일함 종류를 확인한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; a list &quot;&quot; &quot;*&quot;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bIkgSS/btqOzBqtcKk/uFs90MqO28PIPGkpXJyui1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bIkgSS/btqOzBqtcKk/uFs90MqO28PIPGkpXJyui1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bIkgSS/btqOzBqtcKk/uFs90MqO28PIPGkpXJyui1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbIkgSS%2FbtqOzBqtcKk%2FuFs90MqO28PIPGkpXJyui1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;별도의 메일함을 생성하지 않았기 때문에&lt;/p&gt;
&lt;p&gt;기본 메일함인 받은 편지함(INBOX), 보낸 편지함(Sent), 삭제함(Trash)등이 출력된다.&lt;/p&gt;
&lt;p&gt;받은 메일을 읽기 위해 받은 편지함(INBOX)을 선택한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; a select inbox&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BJWhj/btqOtD4qQNb/wEU3HK2LSCPkQbK9fqDCH0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BJWhj/btqOtD4qQNb/wEU3HK2LSCPkQbK9fqDCH0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BJWhj/btqOtD4qQNb/wEU3HK2LSCPkQbK9fqDCH0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBJWhj%2FbtqOtD4qQNb%2FwEU3HK2LSCPkQbK9fqDCH0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;하나의 메일(1 EXISTS)이 있다고 표시된다.&lt;/p&gt;
&lt;p&gt;이미 한번 읽었기 때문에 0 RECENT로 표시 되는데, 안 읽은 메시지가 있으면 안 읽은 메시지 개수가 표시된다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;fetch 명령어로 하나의 메일에 대한 내용을 확인 할 수 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; a fetch 1 body[]&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cxK3D0/btqOxs8pKoJ/qSjRpHZ9kzsVgqsmKF6Ek0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cxK3D0/btqOxs8pKoJ/qSjRpHZ9kzsVgqsmKF6Ek0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cxK3D0/btqOxs8pKoJ/qSjRpHZ9kzsVgqsmKF6Ek0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcxK3D0%2FbtqOxs8pKoJ%2FqSjRpHZ9kzsVgqsmKF6Ek0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;1 은 메일 서버에서 메일함 별로 부여하는 메일 고유 번호로 (uid라고 한다),&lt;/p&gt;
&lt;p&gt;메일 개수를 번호로 생각하고 지정하면 된다.&lt;/p&gt;
&lt;p&gt;여기서는 위 그림과 같이 하나의 메일, 첫번째 메일의 내용을 보여 준다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이외에도 imap은 다양한 명령어가 있으니, [&lt;a href=&quot;https://www.google.com/search?newwindow=1&amp;amp;client=firefox-b-d&amp;amp;ei=HBfCX9droJSvvA_vtKW4Ag&amp;amp;q=imap+%EB%AA%85%EB%A0%B9%EC%96%B4&amp;amp;oq=IMAP+%EB%AA%85&amp;amp;gs_lcp=CgZwc3ktYWIQAxgAMgIIADIECAAQHjoECAAQRzoICAAQsQMQgwE6BQgAELEDOgQIABBDUOCJlgdY35aWB2CfpZYHaABwA3gAgAGAA4gBywmSAQcwLjcuMC4xmAEAoAEBqgEHZ3dzLXdpesgBAcABAQ&amp;amp;sclient=psy-ab&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;imap 명령어&lt;/a&gt;]로 관련 내용들을 찾아서 익혀두는 것이 좋다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;주의: IMAP에서는 특정 계정으로 로그인을 했지만, SMTP에서는 로그인을 하지 않았다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;SMTP에서 로그인을 하지 않고 메일을 발송할 수 있었던 이유는 James SMTP 설정 파일인 smtpserver.xml의 속성 중에서 &amp;lt;authorizedAddresses&amp;gt;에서 로컬 IP(127.0.0.1)를 지정했기 때문이다.&lt;/p&gt;
&lt;p&gt;&lt;u&gt;&amp;lt;authorizedAddresses&amp;gt;속성으로 지정된 IP에서 보내는 메일은 로그인을 하지 않고 메일을 발송한다.&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;SMTP 로그인은 계정 정보를 Base64로 변환해서 입력해야 하는데, 상세한 내용은 [&lt;a href=&quot;https://www.google.com/search?newwindow=1&amp;amp;client=firefox-b-d&amp;amp;ei=4lHCX5iJHo_1wAPUvLeoCA&amp;amp;q=SMTP+%EB%AA%85%EB%A0%B9%EC%96%B4&amp;amp;oq=SMTP+%EB%AA%85%EB%A0%B9%EC%96%B4&amp;amp;gs_lcp=CgZwc3ktYWIQAzICCAAyBggAEAcQHjIGCAAQBxAeOgQIABAeUKKZE1jYoBNg_KITaABwAHgAgAGLAogB3weSAQUwLjYuMZgBAKABAaoBB2d3cy13aXrAAQE&amp;amp;sclient=psy-ab&amp;amp;ved=0ahUKEwiYgtmvraXtAhWPOnAKHVTeDYUQ4dUDCAw&amp;amp;uact=5&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;SMTP 명령어&lt;/a&gt;]로 검색해서 익혀두는 것이 좋다.&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;로그인을 해서 메일을 발송하는 경우에는 다음과 같이 MUA(Mail User Agent) 사용하는 것이 편리하다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;br /&gt;&lt;b&gt;2.&amp;nbsp; Mail User Agent&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;이메일을 읽고 보내는 이메일 클라이언트 프로그램들은(Mail User Agent) 인터넷으로 쉽게 구할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.techradar.com/best/best-email-clients&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;무료와 유료가 다양하게 제공&lt;/a&gt;되는데, 기업에서는 제법 오래전 부터 아웃룩(Outlook)이 독보적이다.&lt;/p&gt;
&lt;p&gt;다만, &lt;span style=&quot;color: #ee2323;&quot;&gt;아웃룩은 메일 서버에 인증서 설정이 되어 있지 않으면 쉽게 계정을 등록할 수 없다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;개인적으로 &lt;b&gt;PC에서는&lt;/b&gt; 오픈 소스인 썬더 버드를 선호한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bhDhKj/btqOuHd9nOJ/0isrLY2iasOROHh8wJS9W0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bhDhKj/btqOuHd9nOJ/0isrLY2iasOROHh8wJS9W0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bhDhKj/btqOuHd9nOJ/0isrLY2iasOROHh8wJS9W0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbhDhKj%2FbtqOuHd9nOJ%2F0isrLY2iasOROHh8wJS9W0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;썬더버드와 같은 MUA를 사용하면 메일을 쉽게 주고 받을 수 있는데, 현재 로컬에 개발로 설정하였기 때문에 썬더버드에서 메일을 발송하면 메일은 잘 발송되지만, 발송된 메일을 보낸 편지함(sent)에 저장하면서 오류가 발생한다.&lt;/p&gt;
&lt;p&gt;그냥 무시하고 사용해도 된다 (?).&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;자세한 설치는 [&lt;a href=&quot;https://www.google.com/search?newwindow=1&amp;amp;client=firefox-b-d&amp;amp;ei=H1PCX-qqCMipoATh_pzIDw&amp;amp;q=%EC%8D%AC%EB%8D%94%EB%B2%84%EB%93%9C+%EC%84%A4%EC%B9%98&amp;amp;oq=%EC%8D%AC%EB%8D%94%EB%B2%84%EB%93%9C+%EC%84%A4%EC%B9%98&amp;amp;gs_lcp=CgZwc3ktYWIQAzICCAAyBggAEAgQHjIGCAAQBRAeMgYIABAFEB4yBggAEAUQHjoECAAQRzoGCAAQChAeULi9CVjUxglg0cgJaABwAngAgAGYAYgB6gaSAQMwLjeYAQCgAQKgAQGqAQdnd3Mtd2l6yAEBwAEB&amp;amp;sclient=psy-ab&amp;amp;ved=0ahUKEwiqttfGrqXtAhXIFIgKHWE_B_kQ4dUDCAw&amp;amp;uact=5&quot;&gt;썬더버드 설치&lt;/a&gt;]로 검색해서 익혀두고, 여기에서는 계정 등록시 주의해야 할 사항을 정리한다.&lt;/p&gt;
&lt;p&gt;다음 그림과 같이 이메일 계정 등록 화면에서 하단에 있는 [수동으로 구성]을 선택한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/blYGUU/btqOCdQrh3h/MDkpKAahTH3cy5psz2apcK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/blYGUU/btqOCdQrh3h/MDkpKAahTH3cy5psz2apcK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/blYGUU/btqOCdQrh3h/MDkpKAahTH3cy5psz2apcK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FblYGUU%2FbtqOCdQrh3h%2FMDkpKAahTH3cy5psz2apcK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;[수동으로 구성]을 선택하면, 다음 그림과 같이 SMTP와 IMAP 서버 주소를 입력하는 창에 자동으로 도메인 앞에 점(.)이 붙어 생성된다.&lt;/p&gt;
&lt;p&gt;SMTP와 IMAP 프로토콜 별로 서버 도메인을 등록하기 때문에 점이 붙는데,&lt;/p&gt;
&lt;p&gt;&lt;b&gt;smtp.&lt;/b&gt;forest71.com, &lt;b&gt;imap.&lt;/b&gt;forest71.com 같이 하위 도메인을 프로토콜별 서버 주소로 입력해야 한다.&lt;/p&gt;
&lt;p&gt;또는 합쳐서 &lt;b&gt;mail.&lt;/b&gt;forest71.com과 같은 도메인을 등록해서 사용한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/R6rH9/btqOzBxhzVz/DqP2P25vlNJqJhiqC8smkk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/R6rH9/btqOzBxhzVz/DqP2P25vlNJqJhiqC8smkk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/R6rH9/btqOzBxhzVz/DqP2P25vlNJqJhiqC8smkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FR6rH9%2FbtqOzBxhzVz%2FDqP2P25vlNJqJhiqC8smkk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;여기에서는 임의의 도메인을 만들어서 사용하는 것이기 때문에 하위 도메인 없이 구현하였다.&lt;/p&gt;
&lt;p&gt;따라서 점(.)을 제거하고 forest.com만 서버 주소로 입력한다.&lt;/p&gt;
&lt;p&gt;단, 썬더버드를 설치한 PC의 hosts 파일에 forest.com을 등록해야 한다.&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;아니면 James를 설치한 서버 주소 IP를 직접 입력해서 사용해도 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;모바일에서는 아웃룩을 사용하지 않는 것이 좋을 것 같다.&lt;/p&gt;
&lt;p&gt;자주 (약 2주 간격) 업데이트하기도 하는데, 모바일의 특성상 메일 서버에 인증서가 설치되어 있어야 이메일 계정을 등록할 수 있다.&lt;/p&gt;
&lt;p&gt;그나마 많이 사용하는 것이 스파크 인것 같고, 개인적으로는 gmail 앱을(gmail 메일 서버가 아니다.) 선호한다.&lt;/p&gt;
&lt;p&gt;Android 폰에는 기본적으로 설치되어 있다.&lt;/p&gt;
&lt;p&gt;모바일 MUA에 계정을 등록하려면 James에 인증서를 등록해서 실행해야 하기 때문에&lt;/p&gt;
&lt;p&gt;모바일 MUA에 계정을 등록하는 방법은 정리하지 않는다.&lt;/p&gt;</description>
      <category>서버/메일</category>
      <author>forest71</author>
      <guid isPermaLink="true">https://forest71.tistory.com/218</guid>
      <comments>https://forest71.tistory.com/218#entry218comment</comments>
      <pubDate>Sun, 6 Dec 2020 19:32:44 +0900</pubDate>
    </item>
    <item>
      <title>4. Apache James 메일 서버 - Text와 JPA(MariaDB등)</title>
      <link>https://forest71.tistory.com/219</link>
      <description>&lt;p&gt;Apache James를 설치하고 접속해서 메일을 주고 받는 것까지 정리하였고, 여기에서는 주고 받은 메일을 저장하는 방식에 대해서 정리한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://forest71.tistory.com/216&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Apache James 메일 서버 - 설치&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://forest71.tistory.com/217&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Apache James 메일 서버 - 설정&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://forest71.tistory.com/218&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Apache James 메일 서버 - 메일 클라이언트&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Apache James 메일 서버 - Text와 JPA(MariaDB등)&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://forest71.tistory.com/221&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Apache James 메일 서버 - 스팸 필터 (SpamAssassin)&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://forest71.tistory.com/217&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;앞서 정리한 conf 폴더의 설정 파일&lt;/a&gt; 중에서 mailbox.xml는 주고 받은 메일을 저장하는 형태를 지정하는 파일로,&lt;/p&gt;
&lt;p&gt;James에서는 jpa, maildir, memory 등의 방식이 제공된다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&amp;lt;mailbox&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;lt;!-- supported providers are: --&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;lt;!--&lt;span style=&quot;color: #006dd7;&quot;&gt; jpa, maildir, memory&lt;/span&gt; --&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;lt;!-- Be aware that maildir will only work on unix like operation systems! --&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;lt;provider&amp;gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;jpa&lt;/span&gt;&lt;/b&gt;&amp;lt;/provider&amp;gt;&lt;br /&gt;&amp;lt;/mailbox&amp;gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;text-align: right;&quot;&gt;mailbox.xml&lt;/p&gt;
&lt;p&gt;jpa, maildir, memory의 세가지 방식이 제공되는데,&lt;/p&gt;
&lt;p&gt;jpa는 OpenJPA를 이용하여 메일 정보를 각종 데이터베이스 (MariaDB, Oracle 등)에 저장하여 관리하는 것으로 기본 설정으로 지정되어 있다.&lt;/p&gt;
&lt;p&gt;maildir은 하나의 메일을 EML 파일로 저장하고, 전체 메일 리스트 등을 Text 파일로 관리하는 방식을 의미한다.&lt;/p&gt;
&lt;p&gt;메일 사용자, 도메인 등은 jpa와 동일하게 OpenJPA를 이용하여 데이터베이스에 저장한다.&lt;/p&gt;
&lt;p&gt;memory는 일종의 테스트 용으로 maildir와 유사하지만 메일 정보를 파일이 아닌 메모리에 저장하기 때문에 James를 재가동하면 메일 송수신 내역이 사라진다.&lt;/p&gt;
&lt;p&gt;여기에서는 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;maildir과 jpa 설정 방식에 대한 자세한 내용을 정리한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;먼저, mailbox.xml에서 위와 같이 &amp;lt;provider&amp;gt;가 jpa로 지정되었는지 확인하고 (기본 설정),&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;conf 폴드의 james-database.properties 파일을 다음과 같이 수정한다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;database.driverClassName=&lt;span style=&quot;color: #ee2323;&quot;&gt;org.mariadb.jdbc.Driver&lt;/span&gt;&lt;br /&gt;database.url=&lt;span style=&quot;color: #ee2323;&quot;&gt;jdbc:mariadb://127.0.0.1:3306/james_mail&lt;/span&gt;&lt;br /&gt;database.username=&lt;span style=&quot;color: #ee2323;&quot;&gt;root&lt;/span&gt;&lt;br /&gt;database.password=&lt;span style=&quot;color: #ee2323;&quot;&gt;gujc1004&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;# Supported adapters are:&lt;br /&gt;# DB2, DERBY, H2, HSQL, INFORMIX, MYSQL, ORACLE, POSTGRESQL, SQL_SERVER, SYBASE &lt;br /&gt;vendorAdapter.database=&lt;span style=&quot;color: #ee2323;&quot;&gt;MYSQL&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;text-align: right;&quot;&gt;james-database.properties&lt;/p&gt;
&lt;p&gt;james-database.properties 파일은 데이터베이스 방식을 사용하기 위해 데이터베이스 접속 정보를 입력하는 파일로 Java의 JDBC 설정 내용과 동일한 값을 입력한다.&lt;/p&gt;
&lt;p&gt;기본 데이터베이스는 DERBY로 지정되어 있고, 앞서서 설정한 도메인(forest71.com), 사용자(gujc1@forest71.com), 메일 송수신 정보 등이 DERBY에 저장되어 있다.&lt;/p&gt;
&lt;p&gt;DERBY는 많은 데이터를 처리하기 어렵고 관련 자료를 구하기도 어렵다.&lt;/p&gt;
&lt;p&gt;여기에서는 James가 OpenJPA로 지원하는 여러가지 데이터베이스 중 보편적인 &lt;b&gt;MariaDB&lt;/b&gt;를 사용한다.&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;u&gt;MariaDB를 설치하는 방법은 여기서 정리하지 않으니 인터넷 자료를 찾아서 설치하고&lt;/u&gt;, &lt;/span&gt;&lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;b&gt;james_mail&lt;/b&gt;이라는 데이터베이스를 생성하면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #ef5369;&quot;&gt;다른 데이터베이스를 생성한 경우에는 위 코드에서 database.url에 해당 데이터베이스 이름을 지정하면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;i&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;주의&lt;/b&gt;&lt;/span&gt;: MariaDB를 사용하지만 드라이버 클래스 이름만 mariadb를 지정하고, vendorAdapter.database 변수에는 MYSQL을 지정해서 사용한다.&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;&lt;i&gt;&lt;i&gt;MariaDB&lt;/i&gt;대신에 MYSQL을 설치해서 사용해도 된다.&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;MariaDB와 Apache James를 연결하기 위한 JDBC 드라이버를 &lt;a href=&quot;https://mariadb.com/kb/en/about-mariadb-connector-j/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;MariaDB 드라이버(Connector/J)&lt;/a&gt; 공식 사이트에서 다운로드 받는다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HsCLK/btqOCcEcR1Z/mu8E315KY6Q8gOfTPYOc4K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HsCLK/btqOCcEcR1Z/mu8E315KY6Q8gOfTPYOc4K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HsCLK/btqOCcEcR1Z/mu8E315KY6Q8gOfTPYOc4K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHsCLK%2FbtqOCcEcR1Z%2Fmu8E315KY6Q8gOfTPYOc4K%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;Java용 라이브러리를 선택하고, download 버튼을 클릭한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bpNnXW/btqOCc5hTss/9SCrenqWG5gjNaiFPu4dlk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bpNnXW/btqOCc5hTss/9SCrenqWG5gjNaiFPu4dlk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bpNnXW/btqOCc5hTss/9SCrenqWG5gjNaiFPu4dlk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbpNnXW%2FbtqOCc5hTss%2F9SCrenqWG5gjNaiFPu4dlk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;다운로드 받을 때, 다음 그림의 왼쪽과 같이 이메일 등의 개인 정보를 입력하라고 하는데,&lt;/p&gt;
&lt;p&gt;입력하지 않고 가만이 있으면 다운로드가 진행된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lZZAA/btqOxraRdyY/u4ZSZzz7IDmmtTDx55i1g0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lZZAA/btqOxraRdyY/u4ZSZzz7IDmmtTDx55i1g0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lZZAA/btqOxraRdyY/u4ZSZzz7IDmmtTDx55i1g0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlZZAA%2FbtqOxraRdyY%2Fu4ZSZzz7IDmmtTDx55i1g0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;다운로드 받은 jar파일을(현재는 mariadb-java-client-2.7.1.jar) 복사해서&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;James의 conf폴더 하위에 있는 lib(james-server-app-3.5.0\conf\lib) 폴더에 넣어준다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;그리고, 제임스를 재가동(james restart)한다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;제임스를 재가동하면 데이터베이스를 MariaDB로 변경하였기 때문에&lt;/p&gt;
&lt;p&gt;앞서서 설정한 도메인(forest71.com), 사용자(gujc1@forest71.com), 메일 송수신 정보가 없다.&lt;/p&gt;
&lt;p&gt;콘솔창에서 사용자를 다시 생성한다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; james-cli.bat adduser gujc1@forest71.com gujc1234&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;도메인은 따로 설정 파일에서 (domainlist.xml) 등록했기 때문에 다시 생성하지 않아도 된다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;데이터베이스 관리도구로 MariaDB에 접속하면 지정한 데이터베이스(james_mail)에 자동으로 테이블들이 생성되어 있고&lt;/p&gt;
&lt;p&gt;도메인 테이블(james_domain)에 임의로 사용하는 도메인(forest71.com)이 등록되어 있는 것을 볼 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6QIT5/btqOFiqCQHD/3xsOa6q1bKKhYz9eqw8mh0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6QIT5/btqOFiqCQHD/3xsOa6q1bKKhYz9eqw8mh0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6QIT5/btqOFiqCQHD/3xsOa6q1bKKhYz9eqw8mh0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6QIT5%2FbtqOFiqCQHD%2F3xsOa6q1bKKhYz9eqw8mh0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;james_user 테이블에 새로 생성한 사용자가&lt;/p&gt;
&lt;p&gt;james_mailbox에는 사용자별 메일함이&lt;/p&gt;
&lt;p&gt;james_mail에는 송수신한 메일들이 저장되어 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;대량의 메일을 관리하기에는 MariaDB나 Oracle등의 DBMS를 사용하는 것이 좋은데&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;첨부파일도 데이터베이스에 저장하는 것이 좋은지에 대해서는 의문이 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;지나치게 데이터 베이스 용량이 커지면서 백업과 복구에 소요되는 시간등의 문제가 있을 것 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;이번에는 JPA외에 전통적인 text 방식으로 관리하는 maildir 방식으로 구현한다.&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;다만, text 방식은 윈도우에서 제대로 작동하지 않는다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;이유는 아래에 정리하였으며, 여기에서는 리눅스로 정리한다.&lt;/p&gt;
&lt;p&gt;mailbox.xml에서 다음과 같이 &amp;lt;provider&amp;gt;를 maildir로 변경한다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&amp;lt;mailbox&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;lt;!-- supported providers are: --&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;lt;!--&lt;span style=&quot;color: #006dd7;&quot;&gt; jpa, maildir, memory&lt;/span&gt; --&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;lt;!-- Be aware that maildir will only work on unix like operation systems! --&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;lt;provider&amp;gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;maildir&lt;/span&gt;&lt;/b&gt;&amp;lt;/provider&amp;gt;&lt;br /&gt;&amp;lt;/mailbox&amp;gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;text-align: right;&quot;&gt;mailbox.xml&lt;/p&gt;
&lt;p&gt;그리고, 제임스를 재가동(james restart)한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;conf 폴더에 있는 mailbox-maildir.properties 파일에는 다음과 같은 내용이 있다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;maildir.folder=../var/store/maildir/&lt;span style=&quot;color: #ee2323;&quot;&gt;%domain&lt;/span&gt;/&lt;span style=&quot;color: #ee2323;&quot;&gt;%user&lt;/span&gt;&lt;br /&gt;maildir.messageNameParser.strictMode=false&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;text-align: right;&quot;&gt;mailbox-maildir.properties&lt;/p&gt;
&lt;p&gt;James를 설치한 폴더의 하위에 var 폴더 하위로 이어지는 위와 같은 경로가 있다.&lt;/p&gt;
&lt;p&gt;이중 도메인(%domain)은 forest.com이고, 사용자(%user)는 gujc1이다.&lt;/p&gt;
&lt;p&gt;즉, james-server-app-3.5.0\var\store\maildir\forest71.com\ 폴더에 사용자별로 폴더가 생긴다.&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;메일을 하나 발송한 뒤에&lt;/span&gt; 해당 폴더를 확인하면 다음과 같은 폴더들이 생성된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/K3zQp/btqO73hxSnD/oBoeFTvYlTWgye0RUp8NV1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/K3zQp/btqO73hxSnD/oBoeFTvYlTWgye0RUp8NV1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/K3zQp/btqO73hxSnD/oBoeFTvYlTWgye0RUp8NV1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FK3zQp%2FbtqO73hxSnD%2FoBoeFTvYlTWgye0RUp8NV1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;각 계정의 기본 폴더(gujc1)가 받은 메일함(inbox)이고&lt;/p&gt;
&lt;p&gt;보낸 메일함은 .Sent이고, 각 폴더 안에 new와 cur 폴더가 있다.&lt;/p&gt;
&lt;p&gt;새로 받은 메일은 new 폴더에, imap 접속하고 나면 cur폴더에 EML 파일이 생성된다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;다음 그림과 같이 메일의 EML 파일명에 콜론(:)이 포함되어 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;이 콜론이 윈도우에서는 파일명으로 사용할 수 없는 특수 문자라서 maildir 방식은 리눅스에만 사용할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cx53jL/btqPe2aAs4J/oJvYM18jHnykTXouP1LZw1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cx53jL/btqPe2aAs4J/oJvYM18jHnykTXouP1LZw1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cx53jL/btqPe2aAs4J/oJvYM18jHnykTXouP1LZw1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcx53jL%2FbtqPe2aAs4J%2FoJvYM18jHnykTXouP1LZw1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;maildir로 지정하면 메일 내용은 EML 파일로 생성해서 관리하고, 계정별 메일 리스트는 james-uidlist라는 텍스트 파일로 관리한다.&lt;/p&gt;
&lt;p&gt;james-uidlist는 메일함 별로 생성되어 관리하는데,&lt;/p&gt;
&lt;p&gt;한 사용자가 하나의 메일함에 메일을 많이 가지고 있는 경우 처리 속도가 느린 단점이 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;송수신된 메일들을 파일로 처리하기 때문에,&lt;/p&gt;
&lt;p&gt;앞서서 메일 정보를 저장하는 james_mail 테이블을 확인하면 메일이 추가 되지 않는 것을 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>서버/메일</category>
      <author>forest71</author>
      <guid isPermaLink="true">https://forest71.tistory.com/219</guid>
      <comments>https://forest71.tistory.com/219#entry219comment</comments>
      <pubDate>Sun, 6 Dec 2020 19:32:18 +0900</pubDate>
    </item>
    <item>
      <title>WebRTC 외부에서 사용하기 &amp;ndash; coturn</title>
      <link>https://forest71.tistory.com/215</link>
      <description>&lt;p&gt;WebRTC는&amp;nbsp;개인간&amp;nbsp;연결(Peer&amp;nbsp;to&amp;nbsp;Peer)을&amp;nbsp;기본으로&amp;nbsp;하기&amp;nbsp;때문에&lt;/p&gt;
&lt;p&gt;실행되는 단말기(PC, 휴대폰등)가 공인 IP를 가지거나 같은 네트워크(공유기) 안에서 서로 인식 할 수 있어야 한다.&lt;/p&gt;
&lt;p&gt;하나는 공유기 안에 있고, 다른 하나는 공유기 밖에 있다면 통신을 할 수 없다.&lt;/p&gt;
&lt;p&gt;즉, 앞서서 정리한 화상채팅용 &lt;a href=&quot;https://forest71.tistory.com/211&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;WebRTC 예제는&lt;/a&gt; 같은 공유기 내에서만 실행된다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이 경우 각 단말기는 공인 IP를 가진 서버(Server)를 경유해서 통신해야 하고,&lt;/p&gt;
&lt;p&gt;coturn서버는 WebRTC가 이렇게 통신할 수 있도록 중계 서버 역할을 해주는 오픈 소스 프로그램이다.&lt;/p&gt;
&lt;p&gt;(이런 서버를 Turn 서버라고 한다. Turn / Stun의 개념은 인터넷으로 쉽게 찾을 수 있다.)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;coturn 서버의 설치 절차는 간단하고 쉽지만 (설치 자료를 쉽게 찾을 수 있다),&lt;/p&gt;
&lt;p&gt;&lt;u&gt;리눅스에서만 사용할 수 있고,&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;&lt;u&gt;외부에서 접근하기 위해 공인 IP를 가진 서버에 설치해야 하기 때문에 공유기를 사용하는 환경(집)에서는 한계가 있&lt;/u&gt;다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;따라서, 여기에서는 &lt;u&gt;coturn 설치 절차나 사용 방법을 정리하지 않고,&lt;/u&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;다음과 같이 공유기(집)를 사용하는 환경에서 coturn 서버를 설치해서 운영하기 위해 필요한 것들을(링크자료) 간단하게 정리한다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;WSL 설치: Linux 설치를 위해&lt;/li&gt;
&lt;li&gt;공유기 사용시 포트포워딩: 공인 IP 사용&lt;/li&gt;
&lt;li&gt;coturn 설치 후 테스트&lt;/li&gt;
&lt;li&gt;예제와&amp;nbsp;연동&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;공인 IP를 가진 리눅스 서버가 있는 경우 1번과 2번은 넘어가도 무방하다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. WSL 설치&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;coturn을 사용하기 위해서는 리눅스가 필요한데,&lt;/p&gt;
&lt;p&gt;Windows 10 에서는 WSL(Windows Subsystem for Linux)로 쉽게 설치해서 사용할 수 있다.&lt;/p&gt;
&lt;p&gt;도커(Docker), VirtualBox 같은 가상화 소프트웨어를 사용해도 좋지만,&lt;/p&gt;
&lt;p&gt;개인적인 호기심과 저사양 노트북을 쓰는 관계로 WSL을 사용해서 coturn 서버를 구축했다.&lt;/p&gt;
&lt;p&gt;WSL의 설치는 &lt;a href=&quot;https://www.44bits.io/ko/post/wsl2-install-and-basic-usage&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;여기에서&lt;/a&gt; 제공하는 내용을 따라서 진행하면 된다.&lt;/p&gt;
&lt;p&gt;Ubuntu 설치시 로그인을 요청하는데, 계정이 없다면 로그인 창을 그냥 닫아도 설치된다.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.44bits.io/ko/post/wsl2-install-and-basic-usage&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;이 내용의&lt;/a&gt; 하단에 있는 도커는 설치 하지 않아도 되고, WSL로 우분투(UBUNTU)를 설치한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;WSL의 단점은 WSL로 설치한 운영체제의 IP가 재부팅 할 때 마다 변경된다는 것이다.&lt;/p&gt;
&lt;p&gt;이 문제는 &lt;a href=&quot;https://blog.dalso.org/linux/wsl2/11430&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;이 글에서&lt;/a&gt; 정리한 스크립트를 실행해서 해결한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;WSL로 우분투를 설치한 경우 텔넷(telnet)이 기본으로 설치되어 있지 않다.&lt;/p&gt;
&lt;p&gt;개인적으로 윈도우즈 콘솔(cmd, Terminal) 화면을 좋아하지 않아서, WSL등으로 리눅스를 실행하고 텔넷으로 접속해서 사용하는 것을 선호한다.&lt;/p&gt;
&lt;p&gt;이경우 &lt;a href=&quot;https://parksb.github.io/article/21.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;SSH등을 지원하게 설치&lt;/a&gt;해서(apt install openssh-server) 사용하는 것이 좋다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;br /&gt;&lt;b&gt;2. 공유기 사용시 포트포워딩&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/h2&gt;
&lt;p&gt;다음으로, 외부에서 WSL로 설치한 리눅스에 접속할 수 있도록 지정해야 한다.&lt;/p&gt;
&lt;p&gt;[공유기 포트포워딩] 인터넷을 검색해보면 쉽게 자료를 구할 수 있다.&lt;/p&gt;
&lt;p&gt;사용하는 공유기에 따라 설정이 다르기 때문에 제조사를 포함해서 검색하면 변경 방법을 찾을 수 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Coturn 서버외에 &lt;u&gt;화상 채팅을 사용하려는 사용자들이 접속해서 채팅을 시작할 수 있도록 도와주는 웹 서버도 외부에서 접속해야 한다.&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;이 웹 서버(&lt;a href=&quot;https://forest71.tistory.com/211&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;WerbRTC 예제 참조&lt;/a&gt;)도 같이 리눅스 서버에서 실행시키고 외부에서 접근할 수 있게 한다.&lt;/p&gt;
&lt;p&gt;그리고 다음과 같이 웹 서버에서 사용하는 3000과 443 포트를 지정하고,&lt;/p&gt;
&lt;p&gt;Coturn 서버에서 사용하는 3478과 5349 포트를 지정해 준다.&lt;/p&gt;
&lt;p&gt;다음 리스트에서 포트 외에 지정된 [내부 IP 주소]는 WSL이 실행된 노트북(PC)의 내부 IP이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bF7c7Q/btqMPhIaP28/LGhdFJR8UG6HuELMOBckh0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bF7c7Q/btqMPhIaP28/LGhdFJR8UG6HuELMOBckh0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bF7c7Q/btqMPhIaP28/LGhdFJR8UG6HuELMOBckh0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbF7c7Q%2FbtqMPhIaP28%2FLGhdFJR8UG6HuELMOBckh0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;포트 포워딩이 잘 되었는지 확인하려면, &lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;NodeJS로 만든 &lt;a href=&quot;https://forest71.tistory.com/211&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;WebRTC 예제를&lt;/span&gt;&lt;/a&gt; 다운 받아서 리눅스에 설치한다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;NodeJS&lt;/span&gt;를 설치하고 &lt;a href=&quot;https://forest71.tistory.com/211&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;WebRTC &lt;/span&gt;예제를&lt;/a&gt; 복사해서 실행하면 된다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;u&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;이 예제를 내부 IP가 아닌 공인 IP로 접속할 수 있으면 포트 포워딩이 잘 이루어진 것이다.&lt;/span&gt;&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;coturn 서버를 설치하고 잘 실행되는지 확인하려면 WebRTC 예제가 있어야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;자신의 외부(공인) IP는 다음과 같이 포털에서 ip로 검색하면 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7kkmv/btqMRjMtndM/N6EjC4jZWMYgUKQTBDvFn1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7kkmv/btqMRjMtndM/N6EjC4jZWMYgUKQTBDvFn1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7kkmv/btqMRjMtndM/N6EjC4jZWMYgUKQTBDvFn1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7kkmv%2FbtqMRjMtndM%2FN6EjC4jZWMYgUKQTBDvFn1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. coturn 설치 후 테스트&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Coturn&amp;nbsp;설치는&amp;nbsp;인터넷&amp;nbsp;자료가&amp;nbsp;많으니&amp;nbsp;검색해&amp;nbsp;보거나,&amp;nbsp;다음&amp;nbsp;자료를&amp;nbsp;참고하면&amp;nbsp;된다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;a href=&quot;https://buttercoconut.xyz/247/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;buttercoconut.xyz/247/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;a href=&quot;https://meetrix.io/blog/webrtc/coturn/installation.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;meetrix.io/blog/webrtc/coturn/installation.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;a href=&quot;http://www.omegaduck.com/2019/08/12/sturn-turn-%EC%84%9C%EB%B2%84-%EA%B5%AC%EC%84%B1/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;www.omegaduck.com/2019/08/12/sturn-turn-%EC%84%9C%EB%B2%84-%EA%B5%AC%EC%84%B1/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;설치시 완성된 서비스를 제공하는 것이 아니기 때문에 SSL(TLS)을 설치하지 않아도 되고, &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;도메인도 사용할 필요 없이&lt;/span&gt; 공인 IP만 지정해서 사용한다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;Coturn 설치 후 설치가 잘 되었는지, turnutils_uclient 를 이용하여 다음과 같이 확인한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; turnutils_uclient -t -u 계정 -w 비밀번호 공인IP&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tc2vX/btqMN4o0K4X/CkgRFMjdjCdRZYA2pTYpkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tc2vX/btqMN4o0K4X/CkgRFMjdjCdRZYA2pTYpkK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tc2vX/btqMN4o0K4X/CkgRFMjdjCdRZYA2pTYpkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Ftc2vX%2FbtqMN4o0K4X%2FCkgRFMjdjCdRZYA2pTYpkK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;공인 IP 대신에 내부 IP를 지정해서, coturn 서버는 잘 설치되었는데, 포트 포워딩이나 방화벽 문제로 외부에서 접속이 안되는지 확인하는 하는 용도로도 사용할 수 있다.&lt;/p&gt;
&lt;p&gt;또는 &lt;a href=&quot;https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;ICE 사이트에서&lt;/a&gt; 다음 그림과 같이 확인 할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bXigEr/btqNnv7CUjx/PRrl3bnKcXNLx6FKVh3kp0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bXigEr/btqNnv7CUjx/PRrl3bnKcXNLx6FKVh3kp0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bXigEr/btqNnv7CUjx/PRrl3bnKcXNLx6FKVh3kp0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbXigEr%2FbtqNnv7CUjx%2FPRrl3bnKcXNLx6FKVh3kp0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;설치한 coturn 서버 정보를 입력한 후에 [Gather candidates]를 누르면, 설치가 제대로 된 경우 그림과 비슷한 결과를 얻을 수 있다.&lt;/p&gt;
&lt;p&gt;위 그림과 다른 결과가 나온다면 coturn 설정이나 방화벽 설정 등을 다시 확인해야 한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4. 예제와&amp;nbsp;연동&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;앞서 정리한 &lt;a href=&quot;https://forest71.tistory.com/211&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;WebRTC 예제를&lt;/a&gt; 설치하고&lt;/p&gt;
&lt;p&gt;설치한 Turn 서버 정보를 입력기 위해, main.js 파일에서 다음과 같이 수정한다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&lt;br /&gt;var&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;pcConfig&amp;nbsp;&lt;/span&gt;=&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;'iceServers':&amp;nbsp;[&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&quot;urls&quot;:[&quot;turn:공인IP:3478?transport=tcp&quot;],&quot;username&quot;:&quot;계정&quot;,&quot;credential&quot;:&quot;비밀번호&quot;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;]&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;function&amp;nbsp;createPeerConnection()&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;try&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pc&amp;nbsp;=&amp;nbsp;new&amp;nbsp;RTCPeerConnection(&lt;span style=&quot;color: #ee2323;&quot;&gt;pcConfig&lt;/span&gt;);&lt;br /&gt;~&amp;nbsp;생략&amp;nbsp;~~&lt;br /&gt;}&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;설치한 coturn 서버의 정보를 pcConfig 변수에 지정하고, 이 pcConfig를 WebRTC를 실행할때(new RTCPeerConnection) 지정한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이 WebRTC 예제는 구글 예제를 기반으로 작성한 것으로, 구글의 WebRTC 설명용으로 작성된 코드로 짐작되지만 사용하지 않는 코드가 있다.&lt;/p&gt;
&lt;p&gt;예로 main.js 파일에서 requestTurn로 검색되는 코드는 사용하지 않는 코드로 Turn 서버 접속에 문제를 만들 수 있다.&lt;/p&gt;
&lt;p&gt;코드를 확인해서 삭제하는 것이 좋다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이제 하나는 공유기 안에서 WebRTC 서버에 접속하고, 하나는 휴대폰으로(둘다 휴대폰) 접속해서 화상 통화가 잘 실행되는지 확인한다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkIMeb%2FbtqE7PMXOH7%2FOK3vf7RJOIDrbh8BZCzLA1%2Fimg.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Node.js/WebRTC</category>
      <author>forest71</author>
      <guid isPermaLink="true">https://forest71.tistory.com/215</guid>
      <comments>https://forest71.tistory.com/215#entry215comment</comments>
      <pubDate>Sun, 15 Nov 2020 10:25:40 +0900</pubDate>
    </item>
    <item>
      <title>모바일 전용 자바스크립트 이미지 편집기 - ImageEditor9</title>
      <link>https://forest71.tistory.com/214</link>
      <description>&lt;p&gt;ImageEditor9은 모바일 전용 자바스크립트 이미지 편집기로,&lt;/p&gt;
&lt;p&gt;모바일의 특징을 고려하여 모바일에서 손쉽게 이미지를 편집할 수 있도록 제작하였다.&lt;/p&gt;
&lt;p&gt;소스는 &lt;a href=&quot;https://github.com/gujc71/imageEditor9&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;github에서&lt;/a&gt; 받을 수 있고, &lt;a href=&quot;https://gujc71.github.io/imageEditor9/example.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;데모도&lt;/a&gt; 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;여기에서는 ImageEditor9의 주요 이미지 편집 기능과 자바 스크립트로 실행하는 방법을 정리한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;screenshot.png&quot; data-origin-width=&quot;533&quot; data-origin-height=&quot;468&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kY10V/btqKAAjl7AJ/EMqLiNuwXBEuabOtOSg840/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kY10V/btqKAAjl7AJ/EMqLiNuwXBEuabOtOSg840/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kY10V/btqKAAjl7AJ/EMqLiNuwXBEuabOtOSg840/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkY10V%2FbtqKAAjl7AJ%2FEMqLiNuwXBEuabOtOSg840%2Fimg.png&quot; data-filename=&quot;screenshot.png&quot; data-origin-width=&quot;533&quot; data-origin-height=&quot;468&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 이미지 편집 기능&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;모바일용&amp;nbsp;이미지&amp;nbsp;편집기이기&amp;nbsp;때문에&amp;nbsp;기본적인&amp;nbsp;편집&amp;nbsp;기능은&amp;nbsp;손가락&amp;nbsp;터치를&amp;nbsp;활용한&amp;nbsp;편집&amp;nbsp;기능이다.&lt;/p&gt;
&lt;p&gt;이미지를&amp;nbsp;한&amp;nbsp;손가락으로&amp;nbsp;누른&amp;nbsp;체&amp;nbsp;이동하면&amp;nbsp;이미지의&amp;nbsp;위치를&amp;nbsp;옮길&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p&gt;손가락&amp;nbsp;두&amp;nbsp;개를&amp;nbsp;터치한&amp;nbsp;경우에는&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;상황에&amp;nbsp;따라&amp;nbsp;확대/축소를&amp;nbsp;하거나&amp;nbsp;회전하도록&amp;nbsp;구현하였다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;두 손가락을 대고 좁히거나 넓히면 확대 / 축소를,&lt;/p&gt;
&lt;p&gt;두&amp;nbsp;손가락을&amp;nbsp;옆으로&amp;nbsp;움직이면&amp;nbsp;이미지를&amp;nbsp;회전&amp;nbsp;시킬&amp;nbsp;수&amp;nbsp;있다&lt;/p&gt;
&lt;p&gt;(구현&amp;nbsp;알고리즘은&amp;nbsp;기울기를&amp;nbsp;계산하여&amp;nbsp;수직&amp;nbsp;이동에&amp;nbsp;가까우면&amp;nbsp;확대&amp;nbsp;축소를,&amp;nbsp;수평이면&amp;nbsp;회전시키는&amp;nbsp;방식이다.)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;메뉴를 이용한 편집 기능은 메인 메뉴를 클릭하면 위 그림처럼 세로로 메뉴가 나타난다.&lt;/p&gt;
&lt;p&gt;제공되는 메뉴는 다음과 같고, 순서데로 가로/세로 크기변경, 좌우 회전, 확대/축소의 편집기능과 나가기, 저장 기능이 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bfMJYi/btqKSgjvzln/HHqDzj5jzTbkeskozkk400/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bfMJYi/btqKSgjvzln/HHqDzj5jzTbkeskozkk400/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bfMJYi/btqKSgjvzln/HHqDzj5jzTbkeskozkk400/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbfMJYi%2FbtqKSgjvzln%2FHHqDzj5jzTbkeskozkk400%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;손가락을 이용해서 사용하는 회전과 크기 조정 기능을 메뉴를 이용하여 사용할 수도 있다.&lt;/p&gt;
&lt;p&gt;회전 기능은 왼쪽과 오른쪽으로 10도씩 이동할 수 있다.&lt;/p&gt;
&lt;p&gt;크기 조정은 10% 단위로 크기로 확대하거나 축소할 수 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;비슷한 회전 기능으로 이미지의 크기를 변경하면서 90도로 회전하는 가로/세로 크기변경 기능이 있다.&lt;/p&gt;
&lt;p&gt;즉, 앞서의 첫 그림과 같이 가로와 세로의 크기가 바뀌는 기능을 (오른쪽 그림) 제공한다.&lt;/p&gt;
&lt;p&gt;모바일은 기기를 회전 시켜서 사진을 찍는 경우가 많아서 구현한 기능이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;편집한 이미지는 저장하거나, 저장없이 프로그램을 종료할 수 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. 사용방법&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;이러한 모바일 전용 이미지 편집기 ImageEditor9은 자바스크립트(JavaScript) 라이브러로, 다음과 같이 자바스크립트로 간단하게 실행 할 수 있다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;먼저, 사용하고자 하는 HTML 파일에서 ImageEditor9 라이브러리(ImageEditor9.js)와 디자인(ImageEditor9.css) 파일을 포함한다.&lt;/p&gt;
&lt;pre id=&quot;code_1602466634594&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;link rel=&quot;stylesheet&quot; href=&quot;imageEditor9.css&quot;&amp;gt;
&amp;lt;script src=&quot;imageEditor9.js&quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;ImageEditor9은 이미지 편집을 하려고 할 때 생성해도 되고,&lt;/p&gt;
&lt;p&gt;다음과 같이 HTML 문서가 로딩되고(onload) 나면 미리 생성해도(&lt;span style=&quot;color: #8a3db6;&quot;&gt;new&lt;/span&gt;) 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1602466680145&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;  window.onload = function() { 
    img = document.getElementById('img1');
    imageEditor = new ImageEditor9 (document.getElementById(&quot;imageEditor9&quot;));
    imageEditor.onSave = function() {
      img.src = imageEditor.toDataURL();
    }
  }&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ImageEditor9을 생성할 때(&lt;span style=&quot;color: #8a3db6;&quot;&gt;new&lt;/span&gt;) 이미지 편집기능을 구현한 div 태그(다음 코드)를 매개 변수로 지정한다.&lt;br /&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;( document.getElementById(&quot;imageEditor9&quot;) )&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;이 div 태그 안에 ImageEditor9에 필요한 내용들을 생성해서 편집 기능을 사용한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;ImageEditor9을 생성하고 나면,&lt;/p&gt;
&lt;p&gt;ImageEditor9에서 편집한 이미지를 받아서 처리할 저장(onSave) 이벤트를 지정해야 한다.&lt;/p&gt;
&lt;p&gt;여기에서는 편집한 이미지를 Base64로 받아서(toDataURL), 원본 이미지(img) 태그의 이미지를(src) 교체한다.&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;실제 사용할 경우에는 편집한 이미지 정보를 서버로 전송해서 저장하는 형태로 사용할 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1602466717039&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;body&amp;gt;
  &amp;lt;div id=&quot;imageEditor9&quot;&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;이렇게 생성한 ImageEditor9은 showFullscreen() 함수로 화면에 보이도록 실행한다.&lt;/p&gt;
&lt;p&gt;그리고, 편집할 이미지 원본을 지정하면(setImageSource), ImageEditor9에서 해당 이미지를 편집 할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1602466773822&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;  function ev_fullEditor(){
    imageEditor.showFullscreen();
    imageEditor.setImageSource(img);
  }
  &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;showFull&lt;span style=&quot;color: #ee2323;&quot;&gt;screen&lt;/span&gt;() 함수외에도 showFull&lt;span style=&quot;color: #ee2323;&quot;&gt;document&lt;/span&gt;()함수가 제공된다.&lt;/p&gt;
&lt;p&gt;showFull&lt;span style=&quot;color: #ee2323;&quot;&gt;screen&lt;/span&gt;() 함수는 모바일의 작은 화면을 최대한 활용하기 위해,&lt;/p&gt;
&lt;p&gt;스크린 전체를 편집화면으로(requestFullscreen()) 사용하는 기능으로&lt;/p&gt;
&lt;p&gt;웹브라우저에서 F11을 눌렀을때, 전체 화면으로 표시되는 기능을 이용한 것이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;u&gt;이 기능은 애플의 사파리(Safari)에서 동작하지 않기 때문에 showFull&lt;span style=&quot;color: #ee2323;&quot;&gt;document&lt;/span&gt;() 함수를 제작하였다.&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;showFull&lt;span style=&quot;color: #ee2323;&quot;&gt;screen&lt;/span&gt;() 함수로 실행해도 애플의 사파리(Safari)에서는 showFull&lt;span style=&quot;color: #ee2323;&quot;&gt;document&lt;/span&gt;()로 실행된다.&lt;/p&gt;
&lt;p&gt;showFull&lt;span style=&quot;color: #ee2323;&quot;&gt;document&lt;/span&gt;()는 스크린이 아닌 문서에 꽉찬 실행으로 팝업 다이얼로그와 같은 방식으로 구현했다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;이상으로 ImageEditor9은 모바일 전용 자바스크립트 이미지 편집기의 편집 기능과 사용방법에 대해서 정리하였다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;b&gt;ImageEditor9은 &lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;모바일의&amp;nbsp;특징인&amp;nbsp;손가락을&amp;nbsp;이용한&amp;nbsp;편집&amp;nbsp;기능과&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;모바일의 작은 화면을 극복하기 위해 전체 화면으로 이미지를 편집할 수 있는 기능에 맞추어 제작하였다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>JavaScript/기타</category>
      <author>forest71</author>
      <guid isPermaLink="true">https://forest71.tistory.com/214</guid>
      <comments>https://forest71.tistory.com/214#entry214comment</comments>
      <pubDate>Sun, 18 Oct 2020 20:54:03 +0900</pubDate>
    </item>
    <item>
      <title>1. 화상 채팅 예제로 익히는 WebRTC  - 기본 예제</title>
      <link>https://forest71.tistory.com/211</link>
      <description>&lt;p&gt;WebRTC는 구글에서 공유한 웹 기반 커뮤니케이션 라이브러리로, 별도의 설치 없이 웹 브라우저에서 화상채팅을 할 수 있는 기능을 제공한다.&lt;/p&gt;
&lt;p&gt;WebRTC는 화상채팅, 음성채팅 등을 쉽게 제작할 수 있도록 도와주며,몇 번의 검색만으로 다음과 같이 다양한 설명과 예제 소스를 구할 수 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;a href=&quot;https://www.html5rocks.com/ko/tutorials/webrtc/basics/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;WebRTC 개념 및 각종 개념 설명&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;a href=&quot;https://codelabs.developers.google.com/codelabs/webrtc-web/#0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;화상채팅&amp;nbsp;예제&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;a href=&quot;https://webrtc.github.io/samples/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;WebRTC&amp;nbsp;각종&amp;nbsp;예제&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;video-conference-5231324_640.png&quot; data-origin-width=&quot;384&quot; data-origin-height=&quot;253&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dVPC5U/btqE4CMvGfl/rfb8EYEPsJbda6RVnwGxNk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dVPC5U/btqE4CMvGfl/rfb8EYEPsJbda6RVnwGxNk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dVPC5U/btqE4CMvGfl/rfb8EYEPsJbda6RVnwGxNk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdVPC5U%2FbtqE4CMvGfl%2Frfb8EYEPsJbda6RVnwGxNk%2Fimg.png&quot; data-filename=&quot;video-conference-5231324_640.png&quot; data-origin-width=&quot;384&quot; data-origin-height=&quot;253&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;대부분이 개념 설명과 코드 사용법을 중심으로 설명했는데,&lt;/p&gt;
&lt;p&gt;여기에서는&amp;nbsp;개념&amp;nbsp;설명&amp;nbsp;없이&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;구글에서 제공하는 예제에 여러 가지 기능을 추가하는 방식으로 정리한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;WebRTC&lt;/span&gt;는 제법 어려운&lt;span&gt;(&lt;/span&gt;낯선&lt;span&gt;) &lt;/span&gt;내용들이 많고,&lt;/p&gt;
&lt;p&gt;NodeJS, SSL, Soeket.IO, HTML, CSS 등의 부가적인 것에 대해서도 알아야 한다.&lt;/p&gt;
&lt;p&gt;여기에서 간단하게 예제를 구현해 보면서&lt;span&gt; WebRTC &lt;/span&gt;개발에 대한 재미를 느낀 뒤에,&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;본격적으로 관련된 깊이 있는 내용들을 찾아보면 좋을 것이다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;하지만, 최소한의 기본 개념은 있어야 하니,&lt;/p&gt;
&lt;p&gt;WebRTC 개념 및 각종 개념에 대한 설명은 한번 쯤 읽어보고 다음 내용을 따라 하는 것이 좋다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;화상 채팅 예제로 익히는 WebRTC - 기본 예제&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://forest71.tistory.com/213&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;화상 채팅 예제로 익히는 WebRTC - 기능 추가&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://forest71.tistory.com/215&quot;&gt;WebRTC 외부에서 사용하기 &amp;ndash; coturn&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;구글의&amp;nbsp;&lt;a href=&quot;https://codelabs.developers.google.com/codelabs/webrtc-web/#0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;WebRTC 예제는&lt;/a&gt; 다음과 같이 기초부터 하나씩 기능을 추가하여 6가지 단계로 구성되어 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;1단계는 카메라에서 비디오를 추출하는 예제,&lt;/li&gt;
&lt;li&gt;2단계는 RTCPeerConnection을 이용하여 대화상대에게 비디오를 제공하는 예제 (네트워크없이)&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;3단계는 RTCDataChannel을 이용하여 데이터를 주고 받는 예제&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;4단계는 서버를 이용하여 메시지를 주고 받는 예제 (signaling)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;5단계는 네트워크 상에서 비디오를 주고 받는 예제&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;6단계는 이미지(데이터)를 공유(제공)하는 예제 이다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;1~3 단계는 네트워크로 상대와 연결하는 것 없이 혼자 실행하는 것으로&lt;/p&gt;
&lt;p&gt;다운로드 받은 파일을 탐색기에서 실행해서(웹 브라우저로) 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;해당 &lt;a href=&quot;https://codelabs.developers.google.com/codelabs/webrtc-web/#2&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;예제의 설명서&lt;/a&gt;에는 크롬(Chrome)의 플러그인인 Web Server를 설치해서 사용하는 방법을 설명하는데,&lt;/p&gt;
&lt;p&gt;1~3 단계는 그냥 파일로 실행하며 관련 코드를 확인하고 인터넷으로 해당 설명을 찾아보는 것으로 충분할&amp;nbsp; 것 같다.&lt;/p&gt;
&lt;p&gt;4~6단계는 네트워크를 기반으로 하는 예제이기 때문에 NodeJS를 설치해서 웹으로 실행해야 한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;3단계와 6단계는 데이터를 주고 받는 RTCDataChannel에 대한 것으로,&amp;nbsp;&lt;/p&gt;
&lt;p&gt;처음 시작하는 사람에게는 RTCPeerConnection 만으로도 충분이 어렵기 때문에 여기서는 정리하지 않는다.&lt;/p&gt;
&lt;p&gt;2단계에서 사용된 RTC&lt;b&gt;Peer&lt;/b&gt;Connection은 Peer라는 단어에서 알 수 있겠지만&lt;/p&gt;
&lt;p&gt;대화 상대 둘이서 직접 연결해서 대화에 필요한 이미지를 주고 받도록 하는 클래스로&lt;/p&gt;
&lt;p&gt;WebRTC로 화상채팅을 구현하기 위해서 꼭 알아야 하는 클래스이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;정리하면,&lt;/p&gt;
&lt;p&gt;카메라에서&amp;nbsp;비디오를&amp;nbsp;추출하고(getUserMedia&amp;nbsp;-&amp;nbsp;1단계),&amp;nbsp;&lt;/p&gt;
&lt;p&gt;대화&amp;nbsp;상대를&amp;nbsp;찾아서&amp;nbsp;(signaling&amp;nbsp;-&amp;nbsp;4단계)&lt;/p&gt;
&lt;p&gt;네트워크로 연결하여 (RTCPeerConnection - 2단계)&lt;/p&gt;
&lt;p&gt;비디오를&amp;nbsp;주고&amp;nbsp;받는&amp;nbsp;예제로&amp;nbsp;위&amp;nbsp;단계를&amp;nbsp;종합한&amp;nbsp;예제가&amp;nbsp;5단계의&amp;nbsp;예제이다.&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;즉, 5단계의 예제를 실행하면,&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;두 대의 장치에서 이미지를 주고 받으며 화상채팅이 되는 것을 볼 수 있다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;따라서, 여기에서는 이 5단계의 예제에 기능을 추가하는 방식을 정리한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;주의&lt;/span&gt;: 예제는 크롬 브라우저에서만 작동한다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;IE, Edge(이전 버전, 최신 edge는 크롬기반으로 작동한다)를 제외하고는 WebRTC를 지원하지만,&amp;nbsp;&lt;/p&gt;
&lt;p&gt;예제는&amp;nbsp;크롬에서만&amp;nbsp;작동한다.&amp;nbsp;다른&amp;nbsp;웹&amp;nbsp;브라우저에서&amp;nbsp;실행하려면&amp;nbsp;별도의&amp;nbsp;처리가&amp;nbsp;필요하다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이 외에도 구글의 예제는 &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;몇 가지 부족한 것 들이 있다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;먼저 WebRTC는 기본적으로 네트워크 연결시 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;SSL이 있어야 한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;localhost로 간단하게 비디오 화면을 가져오는 것 외에,&lt;/p&gt;
&lt;p&gt;네트워크로 연결해서 데이터를 주고 받으며 화상 채팅을 하려면 SSL이 있어야 한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;두 번째, 대화 상대를 찾기 위해 사용하는 서버가 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;한번만&lt;/b&gt;&lt;/span&gt; 연결 하도록 작성되어서,&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;한번 채팅을 하고 나면 계속 서버를 재가동해야 한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;프로그램을 조금이라도 수정하고 확인하려면 계속 서버를 재가동해야 한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;마지막으로, 해당 예제는 이미지만 주고 받는 화상채팅으로 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;오디오는&amp;nbsp;제공되지&amp;nbsp;않는다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이상의 3가지 기능을 보강하는 방법은 코드 몇 줄만 추가하면 되는 것으로&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;u&gt;&lt;b&gt;이렇게 기능을 보강하다 보면 WebRTC 예제(코드)와 친해지고 개발 능력을 향상 시킬 수 있을 것이다.&lt;/b&gt;&lt;/u&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;본격적으로 이상의 부족한 부분을 보강을 하기 전에&lt;span&gt;, &lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;구글 예제 중 &lt;span&gt;5&lt;/span&gt;단계 예제부터 실행 한다&lt;span&gt;.&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;먼저 &lt;a href=&quot;https://github.com/googlecodelabs/webrtc-web&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Github&lt;/a&gt;&lt;/span&gt;&lt;a href=&quot;https://github.com/googlecodelabs/webrtc-web&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;에서 소스를&lt;/a&gt; 다운 받아서 적절한 디렉토리에 설치한다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;git 명령어로 설치하거나 [Download ZIP]을 선택해서 압축 파일을 받아서 설치한다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;image9.png&quot; data-origin-width=&quot;1161&quot; data-origin-height=&quot;871&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MAaF3/btqFaMWkGBq/kDcsMcyxLDIWrWMOYa6eK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MAaF3/btqFaMWkGBq/kDcsMcyxLDIWrWMOYa6eK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MAaF3/btqFaMWkGBq/kDcsMcyxLDIWrWMOYa6eK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMAaF3%2FbtqFaMWkGBq%2FkDcsMcyxLDIWrWMOYa6eK0%2Fimg.png&quot; data-filename=&quot;image9.png&quot; data-origin-width=&quot;1161&quot; data-origin-height=&quot;871&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;주의&lt;/b&gt;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;서버가 &lt;span&gt;NodeJS&lt;/span&gt;로 구축되어 있기 때문에&lt;span&gt; NodeJS&lt;/span&gt;를 설치한다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt; &lt;a href=&quot;https://nodejs.org/ko/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;NodeJS&lt;/a&gt;&lt;/span&gt;&lt;a href=&quot;https://nodejs.org/ko/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;는 홈페이지에서&lt;/a&gt; 자신의 운영체제에 맞추어 다운로드 받아서 실행하면 된다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;콘솔창&lt;span&gt;(CMD)&lt;/span&gt;에서 예제&lt;span&gt; 5(step-05)&lt;/span&gt;가 있는 디렉토리로 이동해서 파일을 확인하고&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;image1.png&quot; data-origin-width=&quot;679&quot; data-origin-height=&quot;313&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yAvud/btqE14Rda9r/yi1hHvrEwht3keLt6Ngkt1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yAvud/btqE14Rda9r/yi1hHvrEwht3keLt6Ngkt1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yAvud/btqE14Rda9r/yi1hHvrEwht3keLt6Ngkt1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyAvud%2FbtqE14Rda9r%2Fyi1hHvrEwht3keLt6Ngkt1%2Fimg.png&quot; data-filename=&quot;image1.png&quot; data-origin-width=&quot;679&quot; data-origin-height=&quot;313&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;span&gt;npm i (install) &lt;/span&gt;명령어로 예제 실행에 필요한 라이브러리들을 설치한다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;실행이 끝나면 탐색기에서 &lt;span&gt;node_modules &lt;/span&gt;폴더에 라이브러리들이 설치된 것을 확인할 수 있다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;콘솔창에서 &lt;b&gt;node index.js &lt;/b&gt;&lt;/span&gt;을 실행해서 웹 서버를 실행한다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;아무런 메시지도 없이 다음과 같이 커서가 깜박이면 제대로 실행된 것이다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;image2.png&quot; data-origin-width=&quot;679&quot; data-origin-height=&quot;313&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bswfJx/btqE14DFWV7/iyQFNhbLBR1I4SMR1Ynui1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bswfJx/btqE14DFWV7/iyQFNhbLBR1I4SMR1Ynui1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bswfJx/btqE14DFWV7/iyQFNhbLBR1I4SMR1Ynui1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbswfJx%2FbtqE14DFWV7%2FiyQFNhbLBR1I4SMR1Ynui1%2Fimg.png&quot; data-filename=&quot;image2.png&quot; data-origin-width=&quot;679&quot; data-origin-height=&quot;313&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;크롬을 실행해서 주소창에 http://localhost:8080을 입력한다.&lt;/p&gt;
&lt;p&gt;다음 그림과 같이 카메라 사용 권한 요청화면에서 [허용]을 선택한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;image3.png&quot; data-origin-width=&quot;687&quot; data-origin-height=&quot;355&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/V6y0S/btqE2uWgl9z/pvi91hItIchmyIhkHYNQD0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/V6y0S/btqE2uWgl9z/pvi91hItIchmyIhkHYNQD0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/V6y0S/btqE2uWgl9z/pvi91hItIchmyIhkHYNQD0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FV6y0S%2FbtqE2uWgl9z%2Fpvi91hItIchmyIhkHYNQD0%2Fimg.png&quot; data-filename=&quot;image3.png&quot; data-origin-width=&quot;687&quot; data-origin-height=&quot;355&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;그림과 같이 자신의 모습이&lt;span&gt;(?) &lt;/span&gt;웹 브라우저에 나타나는 것을 볼 수 있다&lt;span&gt;.&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;image4.png&quot; data-origin-width=&quot;687&quot; data-origin-height=&quot;433&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PKBu5/btqE33cKBm8/Fc3kYcjvoiRWhjAXrvIzA0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PKBu5/btqE33cKBm8/Fc3kYcjvoiRWhjAXrvIzA0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PKBu5/btqE33cKBm8/Fc3kYcjvoiRWhjAXrvIzA0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPKBu5%2FbtqE33cKBm8%2FFc3kYcjvoiRWhjAXrvIzA0%2Fimg.png&quot; data-filename=&quot;image4.png&quot; data-origin-width=&quot;687&quot; data-origin-height=&quot;433&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;하지만 다음과 같이 다른 컴퓨터나 휴대폰으로 접속하면&lt;span&gt;, 화면이 나타나지&lt;/span&gt; 않는다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;http://&lt;span&gt;&lt;span&gt;서버 &lt;/span&gt;&lt;/span&gt;IP:8080&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;참고&lt;span&gt;: 서버&lt;/span&gt;&lt;span&gt; IP&lt;/span&gt;는 NodeJS를 실행한 컴퓨터의 콘솔창에서&lt;span&gt; ipconfig or ifconfig&lt;/span&gt;를 입력하면 확인할 수 있다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;localhost가 아닌 IP를 사용하는 경우에는 자신의 컴퓨터에서도 화면이 나타나지 않는다.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;카메라에서 이미지를 못&lt;span&gt;가지고 &lt;/span&gt;오는 것으로, SSL을 통하지 않으면 카메라(WebRTC)를 이용할 수 없다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;이제, 이러한 문제들을 해결하고, &lt;a href=&quot;https://forest71.tistory.com/213&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;기능을 추가하는 방법에 대해서 정리한다 (다음 페이지).&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;참고사항&lt;/b&gt;&lt;/span&gt;: step-05 폴더에 있는 5 단계 예제의 주요 파일은 다음과 같다.&lt;/p&gt;
&lt;p&gt;다음 파일들을 모두 수정하니, 어떤 파일인지, 어떤 코드가 있는지 알고 있어야 한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;index.js - NodeJS로 실행한 웹 서버 및 Signaling&lt;/li&gt;
&lt;li&gt;index.html - 사용자가 웹으로 접근했을때, 보여주는 웹페이지. 화상채팅 화면.
&lt;ul style=&quot;list-style-type: square;&quot; data-ke-list-type=&quot;square&quot;&gt;
&lt;li&gt;js/main.js - index.html 파일에는 간단한 html 태그만 있고, RTCPeerConnection과 같은 실제 화상채팅을 하는 클라이언트 코드가 모두 여기 있다.&lt;/li&gt;
&lt;li&gt;css/main.css - index.html 에서 사용할 디자인 내용이 작성되어 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Node.js/WebRTC</category>
      <author>forest71</author>
      <guid isPermaLink="true">https://forest71.tistory.com/211</guid>
      <comments>https://forest71.tistory.com/211#entry211comment</comments>
      <pubDate>Sun, 28 Jun 2020 14:57:03 +0900</pubDate>
    </item>
  </channel>
</rss>