Proftp virtualhost configuration 설정 예제(proftpd.conf)

############################################                                                                      
#

#                       ProFTPD Korea User Groups                        
#                           http://proftpd.oops.org                

#                                                                    
############################################

# 번역 : 김정균 < admin@oops.org >
# 이 예제 설정 file은 두개의 가상 server와  anonymous login를 결합하는
# 것을 설명하고 있다.

ServerName                      “ProFTPD”
ServerType                      inetd

# Port 21 은 FTP 의 기본 port이다.
Port                            21

# Global은 main server와 모든 virtualhosts에 의해 공유되는 “global” 설정
# 을 생성한다.

<Global>
  # Umask 022는 group과 world writable로 부터 새로운 dir과 file들을 막기
  # 위한 훌륭한 기본 umask이다.
  Umask                         022
</Global>

# Server가 실행하는데 일반적인 user와 group을 설정한다.
User                            nobody
Group                           nobody

# DoS 공격을 막기 위해, 자식 process의 maximun number를 30으로 설정한다.
# 만약 30이상의 접속을 허락할 필요가 있다면 간단하게 이 치수를 증가시키도록
# 한다. 이것은 오직 standalone mode에서만 가능하다. inetd mode에서는
# service 당 maximun number를 제한 하는 것을 허락하는 inetd server에서
# 설정을 해야 한다.(xintd 역시 마찬가지 이다)
MaxInstances                    30

# 접속에 stall이 될때 끊어 지지 않는 최대 시간을 지정한다.
TimeoutIdle                     300

<VirtualHost ftp.virtual.com>

  ServerName                    “Virtual.com’s FTP Server”

  MaxClients                    10
  MaxLoginAttempts              1

  # DeferWelcome 는 client가 인증을 하기 전에 servername을 display하는
  # 것을 방지한다.
  DeferWelcome                  on

  # guest login만 허락하기를 위하여
  # nomal user login을 제한한다.
  <Limit LOGIN>
    DenyAll
  </Limit>

  # 다음, 자신들의 web site 등에 개인적으로 접근하기 위한 customer에
  # 의해 사용되어 지는 “guest” 계정을 만든다.
  <Anonymous ~cust1>
    User                        cust1
    Group                       cust1
    AnonRequirePassword         on

    <Limit LOGIN>
      AllowAll
    </Limit>

    HideUser                    root
    HideGroup                   root

    # 사용자가 접근하기를 원하지 않는 private directory
    <Directory logs>
      <Limit READ WRITE DIRS>
        DenyAll
      </Limit>
    </Directory>

  </Anonymous>

</VirtualHost>

# primary address에서 작동을 하지만 port는 4000번을 사용하는 또 다른
# virtual host 이다. access는 하나의 anonymous login만 된다.
<VirtualHost our.ip.address>

  ServerName                    “Our private FTP server”
  Port                          4000
  Umask                         027

  <Limit LOGIN>
    DenyAll
  </Limit>

  <Anonymous /usr/local/ftp/virtual/a_customer>

    User                        ftp
    Group                       ftp
    UserAlias                   anonymous ftp

    <Limit LOGIN>
      AllowAll
    </Limit>

    <Limit WRITE>
      DenyAll
    </Limit>

    <Directory incoming>
      <Limit WRITE>
        AllowAll
      </Limit>
    </Directory>

  </Anonymous>

</VirtualHost>

리눅스 압축풀기 명령어

1 tar아카이브(여러 파일을 한 파일로 묶은 것)을 생성하고 푼다.
아카이브의 확장자는 .tar 이다.

tar 는 실행시 반드시 옵션이 있어야 하기 때문에 옵션에 – 를 붙이지 않아도 된다(ps도 마찬가지 이유로 – 가 필요없다). 즉, tar xvf archive.tar 도 작동한다.

2 명령어 활용예
2.1 아카이브 풀기 tar -xvf archive.tar
archive.tar 라는 이름으로 묶인 파일과 디렉토리를 현재 디렉토리에 풀어준다. v 옵션은 파일을 푸는 과정을 화면에 출력해주라는 의미이다.

2.2 아카이브 만들기 tar -cvf archive.tar 묶을파일과디렉토리들
archive.tar 라는 이름으로 파일과 디렉토리를 묶어준다.

2.3 퍼미션을 유지하며 아카이브 만들기 tar -cvfp archive.tar 묶을파일과디렉토리들
archive.tar 라는 이름으로 퍼미션을 유지하며 파일과 디렉토리를 묶어준다.

2.4 tar+gzip 압축하기tar -czvf archive.tar.gz 묶을파일과디렉토리들
archive.tar.gz 라는 이름으로 파일과 디렉토리를 묶어준다. tar -czvfp archive.tar.gz 묶을파일과디렉토리들
archive.tar.gz 라는 이름으로 퍼미션을 유지하며 파일과 디렉토리를 묶어준다.

2.5 tar+bzip2 압축하기tar -cjvf archive.tar.bz 묶을파일과디렉토리들
archive.tar.bz 라는 이름으로 파일과 디렉토리를 묶어준다.

tar -cvjfp archive.tar.gz 묶을파일과디렉토리들
archive.tar.gz 라는 이름으로 퍼미션을 유지하며 파일과 디렉토리를 묶어준다.

2.6 gzip으로 압축된 tar 풀기 tar -xvzf archive.tar.gz
archive.tar.gz 라는 tar 로 묶인뒤 gzip 으로 압축된 파일을 먼저 압축을 푼뒤에 묶인 파일까지 풀어준다.

2.7 bzip2로 압축된 tar 풀기 tar -xvjf arhive.tar.bz
archive.tar.bz 라는 tar 로 묶인뒤 bzip2로 압축된 파일을 먼저 압축을 푼뒤에 묶인 파일까지 풀어준다.

2.8 허가권(Permission) 유지하며 풀기 tar -xpf archive.tar
파일을 묶을 당시의 각 파일의 허가권을 유지하며 풀어준다.

RCS (Revision Control System)

두 명 이상이 참여하는 프로젝트를 진행하고 있다면, 소스 파일의 변경 사항을 적절히 관리하여 변경 사항이 충돌하는 것을 방지하고 지금까지의 변경 사항을 추적하는 것이 중요하다. 소스 파일을 관리하는 데 널리 사용되는 세 가지 시스템은 RCS(Revision Control System), CVS(Current Version System), SCCS(Source Code Control System)이다.

여기에서는 RCS에 관해 간략하게 설명한다.

1.1.1. RCS

RCS는 소스 파일을 관리하는 여러 명령으로 구성되어 있다. 한 파일의 변경 사항을 하나의 파일로 관리하는 방식으로 소스 파일의 변경을 사항을 추적한다.

1.1.1.1. rcs 명령

rsc -i <filename>의 형식으로 명령을 내리면, 파일을 관리하기 위한 초기화 작업이 수행된다. 관리 파일이 생성되는데 원 파일 명 뒤에 ,v가 추가된 형태이다. RCS라는 하위 디렉터리를 만들어두면 관리 파일은 자동으로 이 디렉터리에 저장된다.

1.1.1.2. ci 명령

현재 버전을 저장하는 ci 명령을 사용해 파일을 Check In 할 수 있다. ci <filename>의 형식으로 명령을 내리면 원래 파일은 지워지고 모든 내용과 제어 정보가 RCS파일인 “filename,v” 파일에 들어가게 된다.

1.1.1.3. co 명령

파일을 변경하려면 파일을 Check Out 해야 한다. co -l <filename>을 호출하면 디렉터리에 filename파일이 생기며 CVS 파일은 잠기게 된다. 따라서 다른 사용자가 동시에 파일을 수정하는 것을 방지한다. 수정 후에는 ci를 이용해 다시 Check In 해야 한다. ci -l <filename>의 형식으로 호출하면, 파일을 CVS에 넣고 자동으로 체크아웃 되면서 CVS가 잠긴다. 즉, co -l <filename>을 호출하는 것과 같은 효과가 있다.

1.1.1.4. rolg 명령

rolg <filename> 명령으로 파일의 변경 내역을 볼 수 있다. 파일의 첫 번째 버전으로 돌아가고 싶다면 co -r.1.1 <filename>을 사용할 수 있다. 파일의 버전을 강제로 지정하려면 ci -r2 <filename>과 같은 방법을 사용할 수 있다.

1.1.1.5. rcsdiff 명령

rcsdiff -r1.1 -r1.2 <filename>과 같은 형식으로 두 버전의 차이점을 알아볼 수 있다.

1.1.1.6. 버전 식별

소스 파일에 특수한 매크로를 사용하여 Check In 하면 매크로가 확장되어 내용으로 대체된다. $RCSfile$ 매크로는 파일의 이름으로 확장되고, $Id$ 매크로는 버전을 식별하는 문자열로 확장된다.

1.1.1.7. ident 명령

ident 명령을 사용해 $Id$ 문자열을 포함하는 파일의 버전을 찾을 수 있다. ident <filename>을 입력하면 파일에서 $Id$에 해당하는 문자열 부분을 찾아 출력한다.

Implementing a New Manet Unicast Routing Protocol in NS2 Version 0.2 번역판-4

7 레이어-2 프로토콜들로부터 정보를 받기

몇 개의 라우팅 프로토콜들은 패킷이 레이어-2로부터 보내질 수 없을 때 반응에 흥미가 있을 것이다. 이것은 우리가 아래에 설명한 것처럼, 우리의 라우팅 에이전트에 의해서 쉽게 달성될 수 있다.

그것은 어떻게 작동하는가? 패킷의 공통의 헤더는 그 패킷이 그 레이어-2 에이전트에 의해서 보내질 수 없다면 호출될 것인 함수를 네가 명시할 수 있는 필드를 가진다. 그 함수를 protoname_mac_failed_callback()이라 부르자. 우리는 그런 레이어-2 실패에 대해 반응을 담당하는 역할을 하는 라우팅 에이전트 내에 또 다른 것을 호출하는 이런 함수를 사용할 것이다. 우리는 이런 두 번째 함수를 mac_failed()로 부를 것이다. 그래서 우리는 protoname/protoname.h의 줄 9만 단지 변경해야 한다

protoname/protoname.h

1: class Protoname : public Agent {

2: /* … */

3:

4: public:

5:

6: Protoname(nsaddr_t);

7: int command(int, const char*const*);

8: void recv(Packet*, Handler*);

9: void mac_failed(Packet*);

10: };

11: #endif

protoname/protoname.cc 파일은 더 많은 변화들을 요구한다. 무엇보다도 우리는 공통의 헤더 안쪽에 등록되는 그 함수를 구현해야 한다. 그 함수는 Protoname 클래스의 mac_failed() 함수로 단순히 호출할 것이다. 너는 아래에 구현을 볼 수 있다.

protoname/protoname.cc

1: static void

2: protoname_mac_failed_callback(Packet *p, void *arg) {

3: ((Protoname*)arg)->mac_failed(p);

4: }

mac_failed()에 의해서 구현된 기능성은 protoname 규격에 매우 의존한다. 예를 들어, 코드의 다음 조각은 디버그 메시지를 프린트하고 (줄 6-9) 패킷을 버린다. (줄 11)

protoname/protoname.cc

1: void

2: Protoname::mac_failed(Packet* p) {

3: struct hdr_ip* ih = HDR_IP(p);

4: struct hdr_cmn* ch = HDR_CMN(p);

5:

6: debug(“%f: Node %d MAC layer cannot send a packet to node %dn”,

7: CURRENT_TIME,

8: ra_addr(),

9: ch->next_hop());

10:

11: drop(p, DROP_RTR_MAC_CALLBACK);

12:

13: /* … do something … */

14: }

만약 우리가 라우팅 패킷이 레이어-2 프로토콜들에 의해서 보내지지 않을 때를 알기 원한다면 우리는 send_protoname_pkt()를 변경할 필요가 있다. 유사하게 만약 우리가 데이터 패킷들에 주의하기를 원한다면 forward_data()는 가볍게 마찬가지로 변경되어야 한다. 양쪽의 경우들에서 우리는 그 패킷의 공통의 헤더를 업데이트할 때 다음의 두 개의 줄들을 단지 더해야 한다.

protoname/protoname.cc

1: ch->xmit_failure_ = protoname_mac_failed_callback;

2: ch->xmit_failure_data_ = (void*)this;

protoname_mac_failed_callback()은 무슨 경우들에서 호출될 것인가? NS-2.27에서 우리는 두 개의 다른 상황들을 설립할 수 있다.

mac/arp.cc 노드가 목적지 주소를 (ARP를 통해서) 결정하기를 원하지만 재시도들의 최대 숫자가 초과될 때

mac/mac-802_11.cc 두 개의 가능성들이 있다. 첫 번째 것은 RTS가 보내졌지만 대응하는 CTS가 받아들여지지 않았고 재시도의 최대 숫자가 초과될 때 일어날 수 있다. 두 번째 것은 데이터 패킷이 전달되었지만 절대 ACK를 받지 못했고 (받아들여진 ACK가 없다) 재시도들의 최대 숫자가 초과될 때 발생한다.

8 유선이-붙은-무선 환경들을 위한 지원

이제까지 우리는 평평한 manet들, 즉, 무선-유일한 시나리오들에 대해서만 관련이 있었다. 이번 절에서 우리는 하이브리드 manet들 (NS2 용어를 따르면, 유선이-붙은-무선 시나리오들)을 다루기 위한 기본적인 개념들을 소개할 것이다. 유선이-붙은-무선 스크립트들은 계층적인 주소를 사용할 필요가 있고, 그래서 너는 주소의 이런 유형에서 필요한 지식을 얻기 위해서 15장과 29장 [2]을 읽어야 한다.

최소의 변화들과 함께 우리는 유선이-붙은-무선 시뮬레이션들에서 우리의 프로토콜을 사용할 수 있다. 이런 것들에서는 고정된 노드들, 무선 노드들 그리고 베이스 스테이션들이 있다. 베이스 스테이션은 유선과 무선 도메인들 사이에 게이트웨이이고, 모든 무선 노드는 자신이 어느 베이스 스테이션에 결합되는지를 알 필요가 있다. 우리가 유선이-붙은-무선 지원을 제공하기 위해서 실행할 필요가 있는 모든 것은 각각의 노드를 위해 일치하는 베이스 스테이션을 설정하는 것이다.

유선이-붙은-무선 시나리오들을 기술하는 시뮬레이션 스크립트들은 각각의 모바일 노드에서 시간적으로 앞선 동작을 수행하는데, 즉, 모든 모바일 노드는 베이스 스테이션 (노드 API베이스-스테이션 함수)에 부착된다. 그러나 우리는 여러 개의 베이스 스테이션들이 사용되는 시나리오들에 관심이 있고, 우리는 모바일 노드들이 그들의 결합된 베이스 스테이션들을 동적으로 바꾸기를 원한다는 것을 상상해라. 우리가 다수의 베이스 스테이션들이 허락되는 하이브리드 ad hoc 네트워크들을 지원하는 라우팅 프로토콜을 코드하기를 원한다면 이것은 유용하다. 만약 이것이 너의 경우라면, 그 절을 계속해서 읽어라.

다음의 코드에서 보여지는 것처럼 protoname/protoname.h를 다시 편집하자. 줄들 1과 11은 더해지고, 반면에 나머지는 변하지 않는다.

protoname/protoname.h

1: #include <mobilenode.h>

2:

3: /* … */

4:

5: class Protoname : public Agent {

6:

7: /* … */

8:

9: protected:

10:

11: MobileNode* node_;

12:

13: /* … */

14: };

우리는 라우팅 에이전트가 부착되는 노드를 의미하는 (common/mobilenode.h에서 정의된) 모바일노드 오브젝트에 대한 참조를 더했다. 이런 참조를 얻기 위해서 우리는 Protoname 건설자 안쪽에 다음의 줄 4를 더할 필요가 있다.

protoname/protoname.cc

1: Protoname::Protoname(nsaddr_t id) : Agent(PT_PROTONAME), pkt_timer_(this) {

2: bind_bool(“accessible_var_”, &accessible_var_);

3: ra_addr_ = id;

4: node_ = (MobileNode*)Node::get_node_by_address(id);

5: }

모바일노드 클래스는 우리가 관심이 있는 두 개의 함수들을 소유한다. 우선 첫째로 모바일 노드가 부착되는 베이스 스테이션의 식별자를 되돌려주는, base_stn()이다. 두 번째는 그 모바일 노드를 위한 적합한 베이스 스테이션을 설립할 수 있는 set_base_stn()이다. 그래서 우리는 유선이-붙은-무선 시뮬레이션들을 이런 두 개의 함수들을 사용함으로써 다룰 수 있다. 예를 들어, 다음의 코드는 그 모바일 노드 자체가 베이스 스테이션인지를 체크하고; 만약 아니라면 그때 그것은 베이스 스테이션을 할당 받는다.

protoname/protoname.cc

1: if (node_->base_stn() == ra_addr()) {

2: // I’m a base station

3: /* … */

4: }

5: else {

6: // I’m not a base station

7: node_->set_base_stn(base_stn_addr);

8: }

앞의 예제는 결합된 베이스 스테이션을 동적으로 바꾸는 법을 보여준다. 이런 바꿈들을 수행하기 위해서 사용되는 접근들은 프로토콜 자체에 의존한다.

참조

[1] Marc Greis. Tutorial for the Network Simulator ”ns”.

http://www.isi.edu/nsnam/ns/tutorial/index.html.

[2] The VINT Project. The ns Manual, December 2003.

http://www.isi.edu/nsnam/ns/ns-documentation.html.


[1] 이것은 manet 라우팅 프로토콜들에서 일반적인 특징이지만, 그러나 실제 목적은 랜덤 숫자들을 얻는 예제를 제공하는 것이다.

[2] 실제 이것은 사실이 아니다. 사실 데이터 패킷들은 자신들의 일치하는 에이전트에게 직접 배달되고, 그래서 포트 분류자는 우리의 라우팅 에이전트에서 필요하지 않다. 그러나 우리는 이런 설명을 유지하는데 왜냐하면 NS-2.27은 라우팅 에이전트가 자신의 API의 부분으로써 port-dmux 동작 (4.3.2절을 보라)을 받아들이는 것을 요구하기 때문이다.

[3] IP 헤더에 따라서 패킷의 Time To Live