728x90

-- 분석 함수

    -- RANK OVER()

    -- ROW_NUMBER() OVER() ** 중요  제일 많은 씀 **

      -- 순위를 구함. 

      -- RANK() OVER()는 동일 순위인 경우 1,1,3, 형식으로 출력하지만

      -- ROW_NUMBER() OVER()는 동일 순위인 경우 1,2,3, 형식으로 출력

      -- DENSE_RANK() OVER()는 동일 순위인 경우 1,1,2 형식으로 출력

      -- ROW_NUMBER() OVER()는 매우매우매우 중요한 함수이므로 반드시 알아 둘것 !!!!!!!!!!!!!!!!!!!!!!!

      

      --기본급 내림차순으로 순위를 구하기

      SELECT name, basicpay, RANK() OVER(ORDER BY basicpay DESC) 순위 FROM insa; -- 비교데이타가 똑같으면 순위를 건너뜀

      

      SELECT name, basicpay, ROW_NUMBER() OVER(ORDER BY basicpay DESC) 순위 FROM insa; -- 비교데이타가 똑같아도 순위를 차례대로 매김

      

      -- 기본급 내림차순으로 순위. 단, 기본급이 같으면 수당 내림차순.

      SELECT name, basicpay, sudang, RANK() OVER(ORDER BY basicpay DESC, sudang DESC) 순위 FROM insa;

      

       SELECT name, basicpay, sudang, ROW_NUMBER() OVER(ORDER BY basicpay DESC, sudang DESC) 순위 FROM insa;

      

      -- 부서별 기본급의 내림차순 순위 구하기

      SELECT name, basicpay, buseo, 

        RANK() OVER(PARTITION BY buseo ORDER BY basicpay DESC, sudang DESC) 순위 

        FROM insa;

      

      SELECT name, basicpay, buseo, 

        ROW_NUMBER() OVER(PARTITION BY buseo ORDER BY basicpay DESC, sudang DESC) 순위 

        FROM insa;

      

      -- 출신도별 부서별 순위(학년의 반별)

      SELECT name, basicpay, city, buseo, 

        RANK() OVER(PARTITION BY city ORDER BY basicpay DESC, sudang DESC) 순위 

        FROM insa;

        

      -- 여자 인원수가 가장 많은 부서는?

      SELECT buseo, COUNT(*) FROM insa

        WHERE SUBSTR(ssn,8,1) IN (2,4,6)

        GROUP BY buseo;

        

      SELECT buseo FROM(

      SELECT buseo, COUNT(*) cnt, RANK() OVER(ORDER BY COUNT(*) DESC) 순위

        FROM insa WHERE SUBSTR(ssn,8,1) IN (2,4,6) GROUP BY buseo

        ) WHERE 순위 =1;

        

      -- 기본급여 많이 받는 1~10등 까지 출력(name, basicpay)

      SELECT name, basicpay,RANK() OVER(ORDER BY basicpay DESC) 순위 FROM(

      SELECT name, basicpay, RANK() OVER(ORDER BY basicpay DESC) 순위 FROM insa 

      ) WHERE 순위 <=10;

      

      -- 기본급 상위 10% 출력(name, basicpay)

       SELECT name, basicpay FROM(

        SELECT name, basicpay, RANK() OVER(ORDER BY basicpay DESC) 순위 FROM insa 

        )WHERE 순위<=TRUNC((SELECT COUNT(*) FROM insa) *0.1);

      

      -- 기본급 하위 10% 출력(

      SELECT name, basicpay FROM(

        SELECT name, basicpay, RANK() OVER(ORDER BY basicpay) 순위 FROM insa 

        )WHERE 순위<=TRUNC((SELECT COUNT(*) FROM insa) *0.1);

      

      -- 부서별 기본급여 가장 높은 사람들 출력( name, buseo, jikwi)

      SELECT name, buseo,basicpay, RANK() OVER(PARTITION BY buseo ORDER BY basicpay DESC) 순위

      FROM insa; -- 일단 부서별 순위를 매기는 쿼리

      

      SELECT name, buseo,basicpay FROM(

        SELECT name, buseo,basicpay,

        RANK() OVER(PARTITION BY buseo ORDER BY basicpay DESC) 순위 

        FROM insa

        ) WHERE 순위=1;

        

    -- ***** 나중에 게시판 작성 할 때 사용하는 쿼리 형식이므로 반드 암기 해야함. *****

    -- ROW_NUMBER()를 이용한 쿼리가 아래 ROWNUM을 사용한 쿼리보다 우수

      SELECT num,name,basicpay FROM(

        SELECT num, name, basicpay, ROW_NUMBER() OVER(ORDER BY num DESC) rnum FROM insa

        ) WHERE rnum>= 10 AND rnum <=15 ORDER BY num DESC;

        

     SELECT num,name,basicpay FROM(

      SELECT ROWNUM rnum, num, name, basicpay FROM(

        SELECT num, name, basicpay FROM insa ORDER BY num DESC

      )

    )WHERE rnum>=10 AND rnum<=15;



출처: http://tibang.tistory.com/entry/오라클-분석-함수-RANK-OVER-ROWNUMBER-OVER [T없이맑은날]

반응형
728x90

출처 - http://kalipso.tistory.com/80 

출처 - http://mentor75.tistory.com/entry/ORACLE-TABLE-SPACE-%EC%82%AC%EC%9A%A9%EB%9F%89-%ED%99%95%EC%9D%B8%EC%BF%BC%EB%A6%AC

출처 - https://kldp.org/node/34801

출처 - http://stackoverflow.com/questions/264914/how-do-i-calculate-tables-size-in-oracle

 

1. 테이블스페이스 정보 조회

SELECT * FROM DBA_TABLESPACES;

 

 

2. 테이블스페이스별 용량 확인 쿼리문(MB 단위)

select   substr(a.tablespace_name,1,30) tablespace,
         round(sum(a.total1)/1024/1024,1) "TotalMB",
         round(sum(a.total1)/1024/1024,1)-round(sum(a.sum1)/1024/1024,1) "UsedMB",
         round(sum(a.sum1)/1024/1024,1) "FreeMB",
         round((round(sum(a.total1)/1024/1024,1)-round(sum(a.sum1)/1024/1024,1))/round(sum(a.total1)/1024/1024,1)*100,2) "Used%"
from
         (select   tablespace_name,0 total1,sum(bytes) sum1,max(bytes) MAXB,count(bytes) cnt
          from     dba_free_space
          group by tablespace_name
          union
          select   tablespace_name,sum(bytes) total1,0,0,0
          from     dba_data_files
          group by tablespace_name) a
group by a.tablespace_name
order by tablespace;

 

조회결과를 다음과 같이 살펴볼 수 있다.

TABLESPACE명총용량(TotalMB)사용용량(UsedMB)여유용량(FreeMB)사용율(Used%)
SYSAUX1024514.4509.650.23
SYSTEM102439063438.09
TS_SEND_DATA7096059890.611069.484.4
TS_SEND_TEMP10240.11023.90.01
UNDOTBS1451855.74462.31.23
USERS1000.199.90.1

 

 

3. 테이블스페이스별 현황 확인 쿼리문(MB 단위)

SELECT TABLESPACE_NAME, FILE_NAME, BYTES/1024 AS MBytes, RESULT/1024 AS USE_MBytes FROM
  (
  SELECT E.TABLESPACE_NAME,E.FILE_NAME,E.BYTES, (E.BYTES-SUM(F.BYTES)) RESULT
  FROM DBA_DATA_FILES E, DBA_FREE_SPACE F
  WHERE E.FILE_ID = F.FILE_ID
  GROUP BY E.TABLESPACE_NAME, E.FILE_NAME, E.BYTES
  ) A;

 

TABLESPACE_NAMEFILE_NAMEMBYTESUSE_MBYTES
SYSTEMC:\ORACLE\PRODUCT\10.2.0\ORADATA\TEST\SYSTEM01.DBF14643201458816
SYSAUXC:\ORACLE\PRODUCT\10.2.0\ORADATA\TEST\SYSAUX01.DBF471040450048
USERSC:\ORACLE\PRODUCT\10.2.0\ORADATA\TEST\USERS01.DBF51203328
TESTC:\ORACLE\PRODUCT\10.2.0\ORADATA\TEST\TEST2073395218843264
EXAMPLEC:\ORACLE\PRODUCT\10.2.0\ORADATA\TEST\EXAMPLE01.DBF10240079552
UNDOTBS1C:\ORACLE\PRODUCT\10.2.0\ORADATA\TEST\UNDOTBS01.DBF691712017856
ORCLC:\ORACLE\PRODUCT\10.2.0\ORADATA\TEST\ORCL10485761600

 

 

4.  테이블스페이스별, 파일별 현황 확인 쿼리문(바이트 단위)

SELECT    A.TABLESPACE_NAME "테이블스페이스명",
          A.FILE_NAME "파일경로",
           (A.BYTES - B.FREE)    "사용공간",
            B.FREE                 "여유 공간",
            A.BYTES                "총크기",
            TO_CHAR( (B.FREE / A.BYTES * 100) , '999.99')||'%' "여유공간"
      FROM
       (
         SELECT FILE_ID,
                TABLESPACE_NAME,
                FILE_NAME,
                SUBSTR(FILE_NAME,1,200) FILE_NM,
                SUM(BYTES) BYTES
           FROM DBA_DATA_FILES
         GROUP BY FILE_ID,TABLESPACE_NAME,FILE_NAME,SUBSTR(FILE_NAME,1,200)
       ) A,
       (
         SELECT TABLESPACE_NAME,
                FILE_ID,
                SUM(NVL(BYTES,0)) FREE
           FROM DBA_FREE_SPACE
        GROUP BY TABLESPACE_NAME,FILE_ID
       ) B
      WHERE A.TABLESPACE_NAME=B.TABLESPACE_NAME
         AND A.FILE_ID = B.FILE_ID;

 

테이블스페이스명파일경로사용공간여유공간총크기여유공간
TS_TEST_DATA/oradata/TEST/ts_test_data02.dbf16148332544532650393621474836480  24.80%
TS_TEST_DATA/oradata/TEST/ts_test_data03.dbf16073621504540121497621474836480  25.15%
TS_TEST_DATA/oradata/TEST/ts_test_data.dbf3057785241687942758431457280000   2.80%
SYSAUX/oradata/TEST/sysaux01.dbf5393612805343805441073741824  49.77%
USERS/oradata/TEST/users01.dbf65536104792064104857600  99.94%
SYSTEM/oradata/TEST/system01.dbf4089446406647971841073741824  61.91%
UNDOTBS1/oradata/TEST/undotbs01.dbf5314969646843166724737466368  98.88%
TS_TEST_TEMP/oradata/TEST/ts_test_temp.dbf6553610736762881073741824  99.99%

 

 

5. 테이블 용량 조회

SELECT
   owner, table_name, TRUNC(sum(bytes)/1024/1024/1024) GB
FROM
(SELECT segment_name table_name, owner, bytes
FROM dba_segments
WHERE segment_type in  ('TABLE','TABLE PARTITION')
UNION ALL
SELECT i.table_name, i.owner, s.bytes
FROM dba_indexes i, dba_segments s
WHERE s.segment_name = i.index_name
AND   s.owner = i.owner
AND   s.segment_type in ('INDEX','INDEX PARTITION')
UNION ALL
SELECT l.table_name, l.owner, s.bytes
FROM dba_lobs l, dba_segments s
WHERE s.segment_name = l.segment_name
AND   s.owner = l.owner
AND   s.segment_type IN ('LOBSEGMENT','LOB PARTITION')
UNION ALL
SELECT l.table_name, l.owner, s.bytes
FROM dba_lobs l, dba_segments s
WHERE s.segment_name = l.index_name
AND   s.owner = l.owner
AND   s.segment_type = 'LOBINDEX')
---WHERE owner in UPPER('&owner')
GROUP BY table_name, owner
HAVING SUM(bytes)/1024/1024 > 10  /* Ignore really small tables */
ORDER BY SUM(bytes) desc


반응형
728x90

Too many open files 해결하기

출처 : http://blog.leekyoungil.com/?p=219

IO 관련해서 개발을 하다보면 자주 마주치는 부분중 하나가 이 오류일 것이다. 

java.io.IOException: Too many open files

일단 해당 메시지로 구글 검색을 하면 대부분 해결책이 

“시스템의 open files 를 올려라 리눅스의 경우 ulimit -n 65535” 이정도 및 limit.conf 파일 수정 하는 것이
나오는 것이 대부분 일것이다. 

하지만 그전에 프로그램에서 뭔가 파일을 열고 닫는 부분에서 버그가 있어야 하지 않을까? 라는 것으로 접근하는 것이
가장 우선시 되어야 할 사항 이라고 생각한다. 

일단 이렇게 접근 하기 위해서는 프로그램이 실행이 될때 (어떠한 액션이 발생할때) 지금 열린 파일의 갯수를 알아야 할것이 아닌가? 

os 가 linux 라고 가정 할때 대상 프로세스에서 열린 파일의 수를 실시간으로 확인이 가능한 간단한 스크립트를 소개하겠다.

가령 대상 프로세스가 java 프로세스라고 가정하면 

shell # ps aux | grep java

해당 프로세스 리스트를 확인하면 

아래와 같이 593228 라는 프로세스 아이디가 나온다.

그러면 아래처럼 linux shell 상에서 명령어를 실행하면…

라고 실행하면 2초 단위로 해당 프로세스에서 열린 파일의 갯수가 출력되니 디버깅에 참고하기 바란다.


반응형
728x90

국내 망분리 관련 현황

최근 대규모 개인정보 유출사고가 잇따라 발생함에 따라 유출된 개인 정보로 인해 보이스피싱,스팸메일 등 2차 피해의 발생 우려가 커지고있다. 이에따라 정부는 개인정보 유출사고를 근절하기 위해 보다 높은 수준의 보안대책을 마련하였다.그 일환으로 2012년 8월 17일에 공포된 개정 「정보통신망 이용촉진 및 정보보호 등에 관한 법률 시행령」에 개인정보처리시스템에 접근하는 컴퓨터 등의 외부 인터넷망 차단(망분리)조항이 신설되었다(2013년 2월 18일부터 시행).

하지만 망분리는 국내 기관/기업에서 구축을 좋아하지 않는다.
이유는 망분리 자체가 업무에 시너지를 주기보다는 제약사항이 많기 때문이다.

 

1, 망분리 관련법

1) 관련법

망분리 관련 법은 , ‘정보통신망법’ 및 ‘개인정보보호법’, 금융위원회의 ‘금융전산 망분리 가이드라인’에 따름

  • 정보통신망 이용촉진 및 정보보호 등에 관한 법률 시행령 제 15조 2항 3호(2013년 2월 18일 시행)
  • 개인정보 보호법 시행령 제 30조 1항 2호

[정보통신망 이용촉진 및 정보보호 등에 관련 법률 시행령]

제15조(개인정보의 보호조치)② 법 제28조제1항제2호에 따라 정보통신서비스 제공자등은 개인정보에 대한 불법적인 접근을 차단하기 위하여 다음 각 호의 조치를 하여야 한다. 다만, 제3호의 조치는 전년도 말 기준 직전 3개월간 그 개인정보가 저장·관리되고 있는 이용자 수가 일일평균 100만명 이상이거나 정보통신서비스 부문 전년도(법인인 경우에는 전 사업연도를 말한다) 매출액이 100억원 이상인 정보통신서비스 제공자등만 해당한다.
<개정 2012.8.17.>1. 개인정보를 처리할 수 있도록 체계적으로 구성한 데이터베이스시스템(이하 “개인정보처리시스템”이라 한다)에 대한 접근권한의 부여·변경·말소 등에 관한 기준의 수립·시행
2. 개인정보처리시스템에 대한 침입차단시스템 및 침입탐지시스템의 설치·운영
3. 개인정보처리시스템에 접속하는 개인정보취급자 컴퓨터 등에 대한 외부 인터넷망 차단
4. 비밀번호의 생성 방법 및 변경 주기 등의 기준 설정과 운영
5. 그 밖에 개인정보에 대한 접근통제를 위하여 필요한 조치

 

[개인정보 보호법 시행령 제 30조 1항 2호]

제30조(개인정보의 안전성 확보 조치)

① 개인정보처리자는 법 제29조에 따라 다음 각 호의 안전성 확보 조치를 하여야 한다.

1. 개인정보의 안전한 처리를 위한 내부 관리계획의 수립·시행
2. 개인정보에 대한 접근 통제 및 접근 권한의 제한 조치
3. 개인정보를 안전하게 저장·전송할 수 있는 암호화 기술의 적용 또는 이에 상응하는 조치
4. 개인정보 침해사고 발생에 대응하기 위한 접속기록의 보관 및 위조·변조 방지를 위한 조치
5. 개인정보에 대한 보안프로그램의 설치 및 갱신
6. 개인정보의 안전한 보관을 위한 보관시설의 마련 또는 잠금장치의 설치 등 물리적 조치

② 안전행정부장관은 개인정보처리자가 제1항에 따른 안전성 확보 조치를 하도록 시스템을 구축하는 등 필요한 지원을 할 수 있다.  <개정 2013.3.23.>
③ 제1항에 따른 안전성 확보 조치에 관한 세부 기준은 안전행정부장관이 정하여 고시한다.  <개정 2013.3.23.>

2) 망분리 대상

정보통신망법 시행령에 따르면,전년도말 직전 3개월간 일일평균 100만명 이상의 이용자 개인정보를 보유하거나 전년도 정보통신분야매출액이 100억원 이상인 정보통신서비스 제공자는 개인정보처리시스템에 접속하는 컴퓨터 등을 외부 인터넷망과 차단해야 함

[망분리 대상]

구분대상기준
사업자
– 전년도말 기준 직전 3개월간 개인정보가 저장․관리되고 있는 이용자수가 일일평균 100만명 이상
– 정보통신서비스 부문 전년도(전 사업년도) 매출액이 100억원 이상
개인정보
취급자
– 개인정보 다운로드 가능자
– 개인 정보 파기 가능자
– 개인정보 접근권한 설정 가능자

개인정보의 단순 열람, 수정 권한만을 가진 개인정보취급자는 의무 대상은 아니지만, 개인정보의 유노출에 대해 엄격히 제한해야함

3) 금융권 망분리 가이드라인


금융위원회에서 망분리 도입 내용을 담은 ‘금융전산 망분리 가이드라인’ 배포
 전산센터 망분리는 ‘14년말까지 완료하고, 본점․영업점은 단계적으로 추진(은행 ’15년말, 그외 ‘16년말까지*) 

2. 망분리 관련 솔루션 현황

1) 망분리 구축 방식(3가지)

물리적 망분리, 서버가상화기반 망분리, 클라이언트기반 망분리 등 3가지 방식으로 구축할 수 있음

[방식별 비교]

구분물리적망분리서버가상화 기반 망분리
(SBC)
클라이언트 기반 망분리
(CBC)
운영방법업무용 pc와
인터넷용 pc로 물리적 분리
(pc2대 사용)
인터넷 망은 서버를 통해 업무망은 pc로 분리
(반대로 구축 가능)
pc 부분 가상화를 통해 인터넷 영역과 업무 영역 분리
도입
비용
높음
(추가 pc, 이중망 구축)
보통
(서버 팜 구축)
낮음
(추가 장비 최소화)
추가
장비
추가 pc 1대
라이선스(OS, Office)
네트워크(스위치, 방화벽)
서버팜(서버, 스토리지 등)
네트워크(스위치)
가상화 소프트웨어
네트워크(게이트웨이)
PC기반 솔루션
보안매우 높음
(근본적 분리)
높음
(서버에서 인터넷 사용)
높음
(PC에서 인터넷 사용)
장점해커의 직접적인 접근 차단문서 보안 등 높은 보안성
PC대비 업무환경TCO우수
BYOD/스마트오피스 최적
도입비용 최소화
쉽고 간편한 설치
단점비효율성
(비용, 유지/관리 등)
스마트 오피스 불가
최초 도입비용 높음
WAN 구간 작업이나 다수 접속 시 성능저하
고장발생 시 복구 어려움
대표
제품
네트워크 및 PC업체WMware VM view
Citrix의 XenDesktop 등
안랩의 트러스존
미라지웍스의 아이데스크

2) 망분리 솔루션 현황

망분리 솔루션은 서버가상화기반(SBC)과 클라이언트기반(CBC) 솔루션으로 구분하며 SBC는 외산제품, CBC는 국내 제품을 중심으로 구축되고 있음 

[방식별 비교]

구분
서버가상화(SBC)클라이언트 기반(CBC)
해외국내해외국내
솔루션VM view(VMware)
XenDesktop(Citrix)
Hyper-V(Microsoft)
VERDE(Virtual Brides)
Dstation(틸론)
ETRIDaaS(ETRI)
MED-V(Microsoft)트러스트존(안랩)
iDesk(미라지웍스)
VMcraft(브이엠솔루션)

 

[솔루션별 주요 업체]

제조사솔루션주요 구축 업체
SBC해외(미국)VM view(VMware)굿모닝아이텍, 청담정보기술, 다우기술,
SBC해외(미국)XenDesktop(Citrix)다우기술(총판), 나무기술, 타임게이트, 글로벌텔레콤
SBC해외(미국)Hyper-V(Microsoft)MS 파트너
SBC해외(미국)VERDE(Virtual Brides)(주)데이터뱅크코리아
SBC국내+해외Dstation(틸론)틸론, 가온아이(총판), 디지털오션
SBC국내ETRIDaaS(ETRI)이트론, 한위드정보기술, 이나루
CBC해외(미국)MED-V(Microsoft)MS 파트너
CBC국내트러스트존(안랩)안랩
CBC국내iDesk(미라지웍스)시큐아이, 나무기술, 에스큐브아이
CBC국내VMcraft(브이엠솔루션)브이렘솔루션

3. 망분리 도입 현황

‘09년~’14년까지 신문기사를 통해 망분리 구축 보도자료를 게재한 곳은 총 21건으로 CBC방식 48%(10건), SBC 38%(8건), 물리적 및 기타 방식 14%(3건)으로 구축

  •  총 21건 중 국내솔루션 62%(13건), 해외솔루션 29%(6건)로 망분리 사업은 국내 솔루션이 우위를 점하고 있음

[구축사례]

시기기관내용방식솔루션비고
12009.12기업은행금융권최초 520개 지점영업망과 53개 본부 부서 12,000명SBCDstation(틸론)국내솔루션
22012.08한국수자원공사1차 180대SBCDstation(틸론)국내솔루션
32012.1교통안전공단용역직원용 50명CBCiDesk(미라지웍스)국국내솔루션
42012.11주택금융공사IT직원 70명CBCiDesk(미라지웍스)국내솔루션
52013.06신한은행전국영업점 15,000대CBCMED-V(Microsoft)해외솔루션
62013.06국민은행국내 금융권 최대
30,000대
CBC트러스트존(안랩)국내솔루션
72013.07KDB산업은행최초 200대,
차후 3,000대
CBC트러스트존(안랩)국내솔루션
82013.07한국가스공사3,200대CBCiDesk(미라지웍스)국내솔루션
92013.07근로복지공단7,000명SBCDstation(틸론)국내솔루션
102013.08KTDS500대CBCiDesk(미라지웍스)국내솔루션
112013.1대법원1차 3,500명
2차 7,500명
SBCDstation(틸론)국내솔루션
122014.01인천교육청문서중앙화기반에망분리기능탑재ECM클라우드독(넷아이디)국내솔루션
132014.02삼성전자 시안공장2,000대CBCiDesk(미라지웍스)국내솔루션
142014.02알리안츠생명3,000대(지점사용)SBCVM view(VMware)해외솔루션
152014.02한국지역난방공사1,500명SBCXenDesktop(Citrix)해외솔루션
162014.03국민연금공단전국 140여 콜센터물리적LGU+
172014.03경기도1,000대CBCVMcraft(브이엠솔루션)국내솔루션
182014.03국민연금공단800명SBCXenDesktop(Citrix)해외솔루션
19진행중기업은행(확대)영업점까지물리적진행중
20진행중농협은행6,000대CBC진행중
21진행중부산은행3,500명SBCVERDE(Virtual Brides)해외솔루션

4. 시사점

1)  CBC 방식을 선호하는 이유 

  • 망분리 도입은 기관의 업무 효율 및 매출에 기여하는 것이 아니고 법제도 아래 의무사항이기 때문에 쉽고, 저렴하고, 빨리 구축할 수 있는 방식을 선호
  • 망분리시 서버가상화기반(SBC)를 선호하는 기관은 BYOD/스마트워크 구축 및 문서 중앙화(보안)를 동시에 실현할 수 있기 때문
  • 언론에 공개되어 있지 않은 많은 망분리 도입 기관은 대부분 물리적 망분리 방식으로 구현(업무용PC + 인터넷용 테블릿 PC)

 

2) 해외솔루션을 선호하는 이유(망분리는 국내솔루션이 선전하고 있지만 큰 규모는 여전히 해외 솔루션)

  • 분리 구현 방식의 솔루션은 기능보다 안정된 운영이 중요한 요소기 때문에 레퍼런스와 운영 경험이 많은 해외 솔루션을 선호
  • 국내 기술 지원체계가 해외 솔루션 업체보다 열악하여 추후 발생될 장애 상황에 대한 심리적 불안감 때문에 해외 솔루션을 선호
  • 해외 솔루션의 경우 하드웨어 유통을 기반으로 한 중견업체들이 영업을 진행하는 것에 반해 국내는 중소기업을 중심으로 영업을 진행하기 때문에 영업력의 파워에서 불리함 (* 영업력이 앞서면 실제 BMT 및 RFP 작성이 해외 솔루션 편향적으로 진행될 가능성이 높기 때문에 동등한 평가가 불가능)

 

정현석(클라우드 컨설턴트_비즈니스 & 도입설계)


반응형
728x90

$ tar cvf - * | ssh root@[Target IPAddress] tar xf - -C [Target Directory]

반응형
728x90

출처 : http://zero-gravity.tistory.com/221

OTP 기능을 구현하라는 미션이 떨어졌고, 힌트로는 구글OTP라는 것이 있다라는 것만 받았다.


   찾아보니 거의 다 "Google Authenticator"라는 앱을 다운받아서 구글 로그인을 할 때에 이용하는 내용이었다.


   뭔가 구글에서 제공하는 API가 있어야 구글앱을 이용해서 개발을 할 수 있을 텐데, 눈을 씻고 찾아봐도 API는 없었다.


   찾다찾다 구글앱의 공식 홈페이지에서 파일들을 다운로드 할 수 있는 곳을 찾았는데, C언어로 되어있고 내가 원하는 것은 아니었다. 아마도 SSH로 접속해서 이걸 설치하고 로그인을 할 때에 사용하는 그런 종류인 듯 싶다.(이곳 참고)


   알고리즘을 중심으로 찾아본 결과, 아마도 IETF에 있는 RFC6238이라는 문서를 기반으로 구글앱이 이와 같은 알고리즘으로 구현을 해놓은 것 같다.


   따져보니 이것과 똑같은 알고리즘으로 Key/바코드를 만들어내고 그것을 검증하는 코드를 짜면 완벽하게 구글앱을 사용하는 OTP 기능을 만들어낼 수 있을 것 같았다.


   다른 사람들이 만들어놓은 자바 코드를 찾지 못했을 경우, 최악의 경우엔 정말 그렇게 해보려고 했다.


   국내에선 파이썬 코드를 쉽게 찾을 수 있었지만 자바가 아니어서 아무 쓸모가 없었다.


   지푸라기라도 잡는 심정으로 온갖 검색어 조합을 동원하여 외국 사이트를 이 잡듯이 뒤진 결과,


   다행히 누군가 자바스크립트로 구현해놓은 코드를 발견했다.


   미칠듯이 기뻤다. 속으로 감동의 눈물을 흘릴 정도였다. 그러나 의존하는 라이브러리 파일들을 제대로 다 링크해주고, 코드도 이대로 했음에도 불구하고 어떤 연유에서인지 내가 테스트하는 프로젝트에서는 작동하지 않았다. 


   이내 포기하고 다른 코드를 찾아 헤맸는데, 정말 다행스럽게도 자바로 구현한 코드를 찾았냈다!!!


   그런데 이것도 코드에서 sercretSize, numOfScratchCodes, scratchCodeSize를 몇으로 설정해줘야 하는지 별 말도 없고 그닥 친절하지 않아서 적용에 실패했다.


   더 찾아보니 이 코드를 기반으로 복잡하게 만들어놓은 코드를 발견했는데, 이건 더 머리가 터질 것 같았다. 하루 반 동안 붙잡고 하다가 GG.


   결국 다시 간단한 자바 코드로 돌아가서 붙잡고 요리조리 해본 결과, 성공!!!!


   서론이 길었다.;;


   아무튼 총 4일 동안 끙끙대서 성공한 결과물을 아래에 설명하고자 한다. 비록 내가 처음부터 날코딩한 것은 아니지만, OTP를 구현하려 나처럼 인터넷 망망대해를 떠돌고 있을 불쌍한 중생들을 위해 올려놓는다.




   먼저 OTP란 무엇이고 어떻게 돌아가는지부터 알고 들어가야 하니 간단하게 짚고 넘어가겠다.



   1. OTP란?


   One Time Password의 약자로, 우리말로 하면 일회용 비밀번호라 할 수 있다. 일회성이라는 특징 때문에 일반 비밀번호 입력이나 공인인증서 이용보다도 더 안전한 방법으로 알려져있다. 주로 금융권이나 일반 웹사이트 2차 로그인 인증으로 많이 활용되고 있다. OTP의 종류에는 원리에 따라 S/KEY방식, 시간 동기화 방식, 챌린지 응답 방식, 이벤트 동기화 방식 등이 있다. (좀더 자세한 내용을 알고 싶다면, 위키백과 참조) 여기서는 이중 시간 동기화 방식을 사용한 Google Authenticator라는 앱으로 TOTP 인증을 구현해보도록 하겠다.




   2. TOTP((Time-based One Time Password)의 원리


   많은 사람들이 오해하는 게 있는데(나 또한 그랬다), OTP 기기와 서버가 통신하는 줄 착각한다. 실상은 그렇지 않다. OTP 기기와 서버는 모두 같은 알고리즘을 바탕으로 하기 때문에 통신이 필요치 않다. 원리는 간단하다. 서버쪽에서 해당 알고리즘으로 Key나 바코드 주소를 생성해주면 그걸 OTP 기기에 입력해준다. 그러면 기기에서는 그 Key나 바코드를 기준으로 하여 30~60초 마다 계속하여 새로운 일회용 비밀번호를 생성해낸다. 그 일회용 비밀번호를 입력하여 서버로 전송하면 서버에서 그 비밀번호가 맞는지 알고리즘으로 확인하는 방식이다. 여기서 구글앱을 이용한다는 것은 OTP 기기 대신에 스마트폰에 있는 Google Authenticator라는 앱으로 대체한다는 것이다.


   뭔가 복잡해보이지만, 이해하고나면 쉽다.




   3. Java로 구현해보기.


   자 그럼 Java로 직접해보자. 아래는 JSP를 이용해서 웹사이트에 구현하다는 가정 하에 진행하였다.


   먼저 commons-codec.jar 파일을 라이브러리에 추가해준다.



 commons-codec-1.9.jar



   또 만약 자바 버전이 1.6 이하일 경우에는 아래의 파일을 다운받아서 라이브러리 추가해준다.



 security.jar



   그리고 자신의 스마트폰에 Google Authenticator 앱을 다운받아 설치해놓는다.

   


   다음은 실제 코드다.


   2차 인증 로그인 리퀘스트가 들어올 시, 사용자명과 계정명을 받아서 키를 생성할 부분.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import java.io.IOException;
import java.util.Arrays;
import java.util.Random;
 
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import org.apache.commons.codec.binary.Base32;
 
public class OtpServlet extends HttpServlet {
 
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse res)
            throws ServletException, IOException {
         
        // Allocating the buffer
//      byte[] buffer = new byte[secretSize + numOfScratchCodes * scratchCodeSize];
        byte[] buffer = new byte[5 5 5];
         
        // Filling the buffer with random numbers.
        // Notice: you want to reuse the same random generator
        // while generating larger random number sequences.
        new Random().nextBytes(buffer);
 
        // Getting the key and converting it to Base32
        Base32 codec = new Base32();
//      byte[] secretKey = Arrays.copyOf(buffer, secretSize);
        byte[] secretKey = Arrays.copyOf(buffer, 5);
        byte[] bEncodedKey = codec.encode(secretKey);
         
        // 생성된 Key!
        String encodedKey = new String(bEncodedKey);
         
        System.out.println("encodedKey : " + encodedKey);
         
//      String url = getQRBarcodeURL(userName, hostName, secretKeyStr);
        // userName과 hostName은 변수로 받아서 넣어야 하지만, 여기선 테스트를 위해 하드코딩 해줬다.
        String url = getQRBarcodeURL("hj""company.com", encodedKey); // 생성된 바코드 주소!
        System.out.println("URL : " + url);
         
        String view = "/WEB-INF/view/otpTest.jsp";
         
        req.setAttribute("encodedKey", encodedKey);
        req.setAttribute("url", url);
         
        req.getRequestDispatcher(view).forward(req, res);
         
    }
     
    public static String getQRBarcodeURL(String user, String host, String secret) {
         
        return String.format(format, user, host, secret);
    }
     
}




   otpTest.jsp

1
2
3
4
5
6
7
8
9
10
당신의 키는 → ${encodedKey } 입니다. <br>
당신의 바코드 주소는 → ${url } 입니다. <br><br>
 
<form action="<%=request.getContextPath() %>/otpTestResult.ok" method="get">
    code : <input type="text" name="user_code"><br><br>
     
    <input type="hidden" name="encodedKey" value="${encodedKey }" readonly="readonly"><br><br>
    <input type="submit" value="전송!">
     
</form>


   키나 바코드를 이용해 구글앱에서 항목을 추가한 뒤, 거기서 생성되는 일회용 비밀번호를 code 부분에 써주고 전송을 클릭한다.



   code 부분에 저 숫자를 넣어주면 된다.




   전송 리퀘스트를 받는 부분에서 해당 코드가 맞는지 여부를 검사한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
 
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import org.apache.commons.codec.binary.Base32;
 
public class OtpResultServlet extends HttpServlet {
 
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse res)
            throws ServletException, IOException {
         
        String user_codeStr = req.getParameter("user_code");
        long user_code = Integer.parseInt(user_codeStr);
        String encodedKey = req.getParameter("encodedKey");
        long l = new Date().getTime();
        long ll =  l / 30000;
         
        boolean check_code = false;
        try {
            // 키, 코드, 시간으로 일회용 비밀번호가 맞는지 일치 여부 확인.
            check_code = check_code(encodedKey, user_code, ll);
        catch (InvalidKeyException e) {
            e.printStackTrace();
        catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
         
        // 일치한다면 true.
        System.out.println("check_code : " + check_code);
         
    }
 
    private static boolean check_code(String secret, long code, long t) throwsNoSuchAlgorithmException, InvalidKeyException {
        Base32 codec = new Base32();
        byte[] decodedKey = codec.decode(secret);
 
        // Window is used to check codes generated in the near past.
        // You can use this value to tune how far you're willing to go.
        int window = 3;
        for (int i = -window; i <= window; ++i) {
            long hash = verify_code(decodedKey, t + i);
 
            if (hash == code) {
                return true;
            }
        }
 
        // The validation code is invalid.
        return false;
    }
     
    private static int verify_code(byte[] key, long t)
            throws NoSuchAlgorithmException, InvalidKeyException {
        byte[] data = new byte[8];
        long value = t;
        for (int i = 8; i-- > 0; value >>>= 8) {
            data[i] = (byte) value;
        }
 
        SecretKeySpec signKey = new SecretKeySpec(key, "HmacSHA1");
        Mac mac = Mac.getInstance("HmacSHA1");
        mac.init(signKey);
        byte[] hash = mac.doFinal(data);
 
        int offset = hash[20 1] & 0xF;
 
        // We're using a long because Java hasn't got unsigned int.
        long truncatedHash = 0;
        for (int i = 0; i < 4; ++i) {
            truncatedHash <<= 8;
            // We are dealing with signed bytes:
            // we just keep the first byte.
            truncatedHash |= (hash[offset + i] & 0xFF);
        }
 
        truncatedHash &= 0x7FFFFFFF;
        truncatedHash %= 1000000;
 
        return (int) truncatedHash;
    }
     
}


   시간이 흘러서 일회용 비밀번호가 계속 바뀌어도 바뀐 일회용 비밀번호를 입력하면 완벽하게 true를 뱉어냄을 확인할 수 있다.


   지금까지 구글앱을 이용한 OTP 기능을 어떻게 구현하는지 알아봤다.


   사실 구글앱을 이용하는 방법 말고도 오픈소스를 이용한다든지, 돈으로 떼우는 방법 등등..  방법은 많다.


   아무쪼록 구글앱을 이용한 OTP 기능 개발을 찾아헤매는 사람들에게 도움이 되었길 바란다.

반응형
728x90

INFORMATIONAL
Errata Exist

Internet Engineering Task Force (IETF)                        D. M'Raihi
Request for Comments: 6238                                Verisign, Inc.
Category: Informational                                       S. Machani
ISSN: 2070-1721                                         Diversinet Corp.
                                                                  M. Pei
                                                                Symantec
                                                               J. Rydell
                                                          Portwise, Inc.
                                                                May 2011


              

TOTP: Time-Based One-Time Password Algorithm

Abstract This document describes an extension of the One-Time Password (OTP) algorithm, namely the HMAC-based One-Time Password (HOTP) algorithm, as defined in RFC 4226, to support the time-based moving factor. The HOTP algorithm specifies an event-based OTP algorithm, where the moving factor is an event counter. The present work bases the moving factor on a time value. A time-based variant of the OTP algorithm provides short-lived OTP values, which are desirable for enhanced security. The proposed algorithm can be used across a wide range of network applications, from remote Virtual Private Network (VPN) access and Wi-Fi network logon to transaction-oriented Web applications. The authors believe that a common and shared algorithm will facilitate adoption of two-factor authentication on the Internet by enabling interoperability across commercial and open-source implementations. Status of This Memo This document is not an Internet Standards Track specification; it is published for informational purposes. This document is a product of the Internet Engineering Task Force (IETF). It represents the consensus of the IETF community. It has received public review and has been approved for publication by the Internet Engineering Steering Group (IESG). Not all documents approved by the IESG are a candidate for any level of Internet Standard; see Section 2 of RFC 5741. Information about the current status of this document, any errata, and how to provide feedback on it may be obtained at http://www.rfc-editor.org/info/rfc6238. M'Raihi, et al. Informational [Page 1]


RFC 6238                      HOTPTimeBased                     May 2011


Copyright Notice

   Copyright (c) 2011 IETF Trust and the persons identified as the
   document authors.  All rights reserved.

   This document is subject to BCP 78 and the IETF Trust's Legal
   Provisions Relating to IETF Documents
   (http://trustee.ietf.org/license-info) in effect on the date of
   publication of this document.  Please review these documents
   carefully, as they describe your rights and restrictions with respect
   to this document.  Code Components extracted from this document must
   include Simplified BSD License text as described in Section 4.e of
   the Trust Legal Provisions and are provided without warranty as
   described in the Simplified BSD License.

Table of Contents

   1. Introduction ....................................................2
      1.1. Scope ......................................................2
      1.2. Background .................................................3
   2. Notation and Terminology ........................................3
   3. Algorithm Requirements ..........................................3
   4. TOTP Algorithm ..................................................4
      4.1. Notations ..................................................4
      4.2. Description ................................................4
   5. Security Considerations .........................................5
      5.1. General ....................................................5
      5.2. Validation and Time-Step Size ..............................6
   6. Resynchronization ...............................................7
   7. Acknowledgements ................................................7
   8. References ......................................................8
      8.1. Normative References .......................................8
      8.2. Informative References .....................................8
   Appendix A. TOTP Algorithm: Reference Implementation ...............9
   Appendix B. Test Vectors ..........................................14

1. Introduction

1.1. Scope

This document describes an extension of the One-Time Password (OTP) algorithm, namely the HMAC-based One-Time Password (HOTP) algorithm, as defined in [RFC4226], to support the time-based moving factor. M'Raihi, et al. Informational [Page 2]


RFC 6238                      HOTPTimeBased                     May 2011


1.2. Background

As defined in [RFC4226], the HOTP algorithm is based on the HMAC-SHA-1 algorithm (as specified in [RFC2104]) and applied to an increasing counter value representing the message in the HMAC computation. Basically, the output of the HMAC-SHA-1 calculation is truncated to obtain user-friendly values: HOTP(K,C) = Truncate(HMAC-SHA-1(K,C)) where Truncate represents the function that can convert an HMAC-SHA-1 value into an HOTP value. K and C represent the shared secret and counter value; see [RFC4226] for detailed definitions. TOTP is the time-based variant of this algorithm, where a value T, derived from a time reference and a time step, replaces the counter C in the HOTP computation. TOTP implementations MAY use HMAC-SHA-256 or HMAC-SHA-512 functions, based on SHA-256 or SHA-512 [SHA2] hash functions, instead of the HMAC-SHA-1 function that has been specified for the HOTP computation in [RFC4226].

2. Notation and Terminology

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119].

3. Algorithm Requirements

This section summarizes the requirements taken into account for designing the TOTP algorithm. R1: The prover (e.g., token, soft token) and verifier (authentication or validation server) MUST know or be able to derive the current Unix time (i.e., the number of seconds elapsed since midnight UTC of January 1, 1970) for OTP generation. See [UT] for a more detailed definition of the commonly known "Unix time". The precision of the time used by the prover affects how often the clock synchronization should be done; see Section 6. R2: The prover and verifier MUST either share the same secret or the knowledge of a secret transformation to generate a shared secret. R3: The algorithm MUST use HOTP [RFC4226] as a key building block. M'Raihi, et al. Informational [Page 3]


RFC 6238                      HOTPTimeBased                     May 2011


   R4: The prover and verifier MUST use the same time-step value X.

   R5: There MUST be a unique secret (key) for each prover.

   R6: The keys SHOULD be randomly generated or derived using key
       derivation algorithms.

   R7: The keys MAY be stored in a tamper-resistant device and SHOULD be
       protected against unauthorized access and usage.

4. TOTP Algorithm

This variant of the HOTP algorithm specifies the calculation of a one-time password value, based on a representation of the counter as a time factor.

4.1. Notations

o X represents the time step in seconds (default value X = 30 seconds) and is a system parameter. o T0 is the Unix time to start counting time steps (default value is 0, i.e., the Unix epoch) and is also a system parameter.

4.2. Description

Basically, we define TOTP as TOTP = HOTP(K, T), where T is an integer and represents the number of time steps between the initial counter time T0 and the current Unix time. More specifically, T = (Current Unix time - T0) / X, where the default floor function is used in the computation. For example, with T0 = 0 and Time Step X = 30, T = 1 if the current Unix time is 59 seconds, and T = 2 if the current Unix time is 60 seconds. The implementation of this algorithm MUST support a time value T larger than a 32-bit integer when it is beyond the year 2038. The value of the system parameters X and T0 are pre-established during the provisioning process and communicated between a prover and verifier as part of the provisioning step. The provisioning flow is out of scope of this document; refer to [RFC6030] for such provisioning container specifications. M'Raihi, et al. Informational [Page 4]


RFC 6238                      HOTPTimeBased                     May 2011


5. Security Considerations

5.1. General

The security and strength of this algorithm depend on the properties of the underlying building block HOTP, which is a construction based on HMAC [RFC2104] using SHA-1 as the hash function. The conclusion of the security analysis detailed in [RFC4226] is that, for all practical purposes, the outputs of the dynamic truncation on distinct inputs are uniformly and independently distributed strings. The analysis demonstrates that the best possible attack against the HOTP function is the brute force attack. As indicated in the algorithm requirement section, keys SHOULD be chosen at random or using a cryptographically strong pseudorandom generator properly seeded with a random value. Keys SHOULD be of the length of the HMAC output to facilitate interoperability. We RECOMMEND following the recommendations in [RFC4086] for all pseudorandom and random number generations. The pseudorandom numbers used for generating the keys SHOULD successfully pass the randomness test specified in [CN], or a similar well-recognized test. All the communications SHOULD take place over a secure channel, e.g., Secure Socket Layer/Transport Layer Security (SSL/TLS) [RFC5246] or IPsec connections [RFC4301]. We also RECOMMEND storing the keys securely in the validation system, and, more specifically, encrypting them using tamper-resistant hardware encryption and exposing them only when required: for example, the key is decrypted when needed to verify an OTP value, and re-encrypted immediately to limit exposure in the RAM to a short period of time. The key store MUST be in a secure area, to avoid, as much as possible, direct attack on the validation system and secrets database. Particularly, access to the key material should be limited to programs and processes required by the validation system only. M'Raihi, et al. Informational [Page 5]


RFC 6238                      HOTPTimeBased                     May 2011


5.2. Validation and Time-Step Size

An OTP generated within the same time step will be the same. When an OTP is received at a validation system, it doesn't know a client's exact timestamp when an OTP was generated. The validation system may typically use the timestamp when an OTP is received for OTP comparison. Due to network latency, the gap (as measured by T, that is, the number of time steps since T0) between the time that the OTP was generated and the time that the OTP arrives at the receiving system may be large. The receiving time at the validation system and the actual OTP generation may not fall within the same time-step window that produced the same OTP. When an OTP is generated at the end of a time-step window, the receiving time most likely falls into the next time-step window. A validation system SHOULD typically set a policy for an acceptable OTP transmission delay window for validation. The validation system should compare OTPs not only with the receiving timestamp but also the past timestamps that are within the transmission delay. A larger acceptable delay window would expose a larger window for attacks. We RECOMMEND that at most one time step is allowed as the network delay. The time-step size has an impact on both security and usability. A larger time-step size means a larger validity window for an OTP to be accepted by a validation system. There are implications for using a larger time-step size, as follows: First, a larger time-step size exposes a larger window to attack. When an OTP is generated and exposed to a third party before it is consumed, the third party can consume the OTP within the time-step window. We RECOMMEND a default time-step size of 30 seconds. This default value of 30 seconds is selected as a balance between security and usability. Second, the next different OTP must be generated in the next time- step window. A user must wait until the clock moves to the next time-step window from the last submission. The waiting time may not be exactly the length of the time step, depending on when the last OTP was generated. For example, if the last OTP was generated at the halfway point in a time-step window, the waiting time for the next OTP is half the length of the time step. In general, a larger time- step window means a longer waiting time for a user to get the next valid OTP after the last successful OTP validation. A too-large window (for example, 10 minutes) most probably won't be suitable for typical Internet login use cases; a user may not be able to get the next OTP within 10 minutes and therefore will have to re-login to the same site in 10 minutes. M'Raihi, et al. Informational [Page 6]


RFC 6238                      HOTPTimeBased                     May 2011


   Note that a prover may send the same OTP inside a given time-step
   window multiple times to a verifier.  The verifier MUST NOT accept
   the second attempt of the OTP after the successful validation has
   been issued for the first OTP, which ensures one-time only use of an
   OTP.

6. Resynchronization

Because of possible clock drifts between a client and a validation server, we RECOMMEND that the validator be set with a specific limit to the number of time steps a prover can be "out of synch" before being rejected. This limit can be set both forward and backward from the calculated time step on receipt of the OTP value. If the time step is 30 seconds as recommended, and the validator is set to only accept two time steps backward, then the maximum elapsed time drift would be around 89 seconds, i.e., 29 seconds in the calculated time step and 60 seconds for two backward time steps. This would mean the validator could perform a validation against the current time and then two further validations for each backward step (for a total of 3 validations). Upon successful validation, the validation server can record the detected clock drift for the token in terms of the number of time steps. When a new OTP is received after this step, the validator can validate the OTP with the current timestamp adjusted with the recorded number of time-step clock drifts for the token. Also, it is important to note that the longer a prover has not sent an OTP to a validation system, the longer (potentially) the accumulated clock drift between the prover and the verifier. In such cases, the automatic resynchronization described above may not work if the drift exceeds the allowed threshold. Additional authentication measures should be used to safely authenticate the prover and explicitly resynchronize the clock drift between the prover and the validator.

7. Acknowledgements

The authors of this document would like to thank the following people for their contributions and support to make this a better specification: Hannes Tschofenig, Jonathan Tuliani, David Dix, Siddharth Bajaj, Stu Veath, Shuh Chang, Oanh Hoang, John Huang, and Siddhartha Mohapatra. M'Raihi, et al. Informational [Page 7]


RFC 6238                      HOTPTimeBased                     May 2011


8. References

8.1. Normative References

[RFC2104] Krawczyk, H., Bellare, M., and R. Canetti, "HMAC: Keyed- Hashing for Message Authentication", RFC 2104, February 1997. [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997. [RFC4086] Eastlake 3rd, D., Schiller, J., and S. Crocker, "Randomness Recommendations for Security", BCP 106, RFC 4086, June 2005. [RFC4226] M'Raihi, D., Bellare, M., Hoornaert, F., Naccache, D., and O. Ranen, "HOTP: An HMAC-Based One-Time Password Algorithm", RFC 4226, December 2005. [SHA2] NIST, "FIPS PUB 180-3: Secure Hash Standard (SHS)", October 2008, <http://csrc.nist.gov/publications/fips/ fips180-3/fips180-3_final.pdf>.

8.2. Informative References

[CN] Coron, J. and D. Naccache, "An Accurate Evaluation of Maurer's Universal Test", LNCS 1556, February 1999, <http://www.gemplus.com/smart/rd/publications/pdf/ CN99maur.pdf>. [RFC4301] Kent, S. and K. Seo, "Security Architecture for the Internet Protocol", RFC 4301, December 2005. [RFC5246] Dierks, T. and E. Rescorla, "The Transport Layer Security (TLS) Protocol Version 1.2", RFC 5246, August 2008. [RFC6030] Hoyer, P., Pei, M., and S. Machani, "Portable Symmetric Key Container (PSKC)", RFC 6030, October 2010. [UT] Wikipedia, "Unix time", February 2011, <http://en.wikipedia.org/wiki/Unix_time>. M'Raihi, et al. Informational [Page 8]


RFC 6238                      HOTPTimeBased                     May 2011


Appendix A. TOTP Algorithm: Reference Implementation

<CODE BEGINS> /** Copyright (c) 2011 IETF Trust and the persons identified as authors of the code. All rights reserved. Redistribution and use in source and binary forms, with or without modification, is permitted pursuant to, and subject to the license terms contained in, the Simplified BSD License set forth in Section 4.c of the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info). */ import java.lang.reflect.UndeclaredThrowableException; import java.security.GeneralSecurityException; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import java.math.BigInteger; import java.util.TimeZone; /** * This is an example implementation of the OATH * TOTP algorithm. * Visit www.openauthentication.org for more information. * * @author Johan Rydell, PortWise, Inc. */ public class TOTP { private TOTP() {} /** * This method uses the JCE to provide the crypto algorithm. * HMAC computes a Hashed Message Authentication Code with the * crypto hash algorithm as a parameter. * * @param crypto: the crypto algorithm (HmacSHA1, HmacSHA256, * HmacSHA512) * @param keyBytes: the bytes to use for the HMAC key * @param text: the message or text to be authenticated */ M'Raihi, et al. Informational [Page 9]


RFC 6238                      HOTPTimeBased                     May 2011


     private static byte[] hmac_sha(String crypto, byte[] keyBytes,
             byte[] text){
         try {
             Mac hmac;
             hmac = Mac.getInstance(crypto);
             SecretKeySpec macKey =
                 new SecretKeySpec(keyBytes, "RAW");
             hmac.init(macKey);
             return hmac.doFinal(text);
         } catch (GeneralSecurityException gse) {
             throw new UndeclaredThrowableException(gse);
         }
     }


     /**
      * This method converts a HEX string to Byte[]
      *
      * @param hex: the HEX string
      *
      * @return: a byte array
      */

     private static byte[] hexStr2Bytes(String hex){
         // Adding one byte to get the right conversion
         // Values starting with "0" can be converted
         byte[] bArray = new BigInteger("10" + hex,16).toByteArray();

         // Copy all the REAL bytes, not the "first"
         byte[] ret = new byte[bArray.length - 1];
         for (int i = 0; i < ret.length; i++)
             ret[i] = bArray[i+1];
         return ret;
     }

     private static final int[] DIGITS_POWER
     // 0 1  2   3    4     5      6       7        8
     = {1,10,100,1000,10000,100000,1000000,10000000,100000000 };













M'Raihi, et al.               Informational                    [Page 10]


RFC 6238                      HOTPTimeBased                     May 2011


     /**
      * This method generates a TOTP value for the given
      * set of parameters.
      *
      * @param key: the shared secret, HEX encoded
      * @param time: a value that reflects a time
      * @param returnDigits: number of digits to return
      *
      * @return: a numeric String in base 10 that includes
      *              {@link truncationDigits} digits
      */

     public static String generateTOTP(String key,
             String time,
             String returnDigits){
         return generateTOTP(key, time, returnDigits, "HmacSHA1");
     }


     /**
      * This method generates a TOTP value for the given
      * set of parameters.
      *
      * @param key: the shared secret, HEX encoded
      * @param time: a value that reflects a time
      * @param returnDigits: number of digits to return
      *
      * @return: a numeric String in base 10 that includes
      *              {@link truncationDigits} digits
      */

     public static String generateTOTP256(String key,
             String time,
             String returnDigits){
         return generateTOTP(key, time, returnDigits, "HmacSHA256");
     }















M'Raihi, et al.               Informational                    [Page 11]


RFC 6238                      HOTPTimeBased                     May 2011


     /**
      * This method generates a TOTP value for the given
      * set of parameters.
      *
      * @param key: the shared secret, HEX encoded
      * @param time: a value that reflects a time
      * @param returnDigits: number of digits to return
      *
      * @return: a numeric String in base 10 that includes
      *              {@link truncationDigits} digits
      */

     public static String generateTOTP512(String key,
             String time,
             String returnDigits){
         return generateTOTP(key, time, returnDigits, "HmacSHA512");
     }


     /**
      * This method generates a TOTP value for the given
      * set of parameters.
      *
      * @param key: the shared secret, HEX encoded
      * @param time: a value that reflects a time
      * @param returnDigits: number of digits to return
      * @param crypto: the crypto function to use
      *
      * @return: a numeric String in base 10 that includes
      *              {@link truncationDigits} digits
      */

     public static String generateTOTP(String key,
             String time,
             String returnDigits,
             String crypto){
         int codeDigits = Integer.decode(returnDigits).intValue();
         String result = null;

         // Using the counter
         // First 8 bytes are for the movingFactor
         // Compliant with base RFC 4226 (HOTP)
         while (time.length() < 16 )
             time = "0" + time;

         // Get the HEX in a Byte[]
         byte[] msg = hexStr2Bytes(time);
         byte[] k = hexStr2Bytes(key);



M'Raihi, et al.               Informational                    [Page 12]


RFC 6238                      HOTPTimeBased                     May 2011


         byte[] hash = hmac_sha(crypto, k, msg);

         // put selected bytes into result int
         int offset = hash[hash.length - 1] & 0xf;

         int binary =
             ((hash[offset] & 0x7f) << 24) |
             ((hash[offset + 1] & 0xff) << 16) |
             ((hash[offset + 2] & 0xff) << 8) |
             (hash[offset + 3] & 0xff);

         int otp = binary % DIGITS_POWER[codeDigits];

         result = Integer.toString(otp);
         while (result.length() < codeDigits) {
             result = "0" + result;
         }
         return result;
     }

     public static void main(String[] args) {
         // Seed for HMAC-SHA1 - 20 bytes
         String seed = "3132333435363738393031323334353637383930";
         // Seed for HMAC-SHA256 - 32 bytes
         String seed32 = "3132333435363738393031323334353637383930" +
         "313233343536373839303132";
         // Seed for HMAC-SHA512 - 64 bytes
         String seed64 = "3132333435363738393031323334353637383930" +
         "3132333435363738393031323334353637383930" +
         "3132333435363738393031323334353637383930" +
         "31323334";
         long T0 = 0;
         long X = 30;
         long testTime[] = {59L, 1111111109L, 1111111111L,
                 1234567890L, 2000000000L, 20000000000L};

         String steps = "0";
         DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
         df.setTimeZone(TimeZone.getTimeZone("UTC"));












M'Raihi, et al.               Informational                    [Page 13]


RFC 6238                      HOTPTimeBased                     May 2011


         try {
             System.out.println(
                     "+---------------+-----------------------+" +
             "------------------+--------+--------+");
             System.out.println(
                     "|  Time(sec)    |   Time (UTC format)   " +
             "| Value of T(Hex)  |  TOTP  | Mode   |");
             System.out.println(
                     "+---------------+-----------------------+" +
             "------------------+--------+--------+");

             for (int i=0; i<testTime.length; i++) {
                 long T = (testTime[i] - T0)/X;
                 steps = Long.toHexString(T).toUpperCase();
                 while (steps.length() < 16) steps = "0" + steps;
                 String fmtTime = String.format("%1$-11s", testTime[i]);
                 String utcTime = df.format(new Date(testTime[i]*1000));
                 System.out.print("|  " + fmtTime + "  |  " + utcTime +
                         "  | " + steps + " |");
                 System.out.println(generateTOTP(seed, steps, "8",
                 "HmacSHA1") + "| SHA1   |");
                 System.out.print("|  " + fmtTime + "  |  " + utcTime +
                         "  | " + steps + " |");
                 System.out.println(generateTOTP(seed32, steps, "8",
                 "HmacSHA256") + "| SHA256 |");
                 System.out.print("|  " + fmtTime + "  |  " + utcTime +
                         "  | " + steps + " |");
                 System.out.println(generateTOTP(seed64, steps, "8",
                 "HmacSHA512") + "| SHA512 |");

                 System.out.println(
                         "+---------------+-----------------------+" +
                 "------------------+--------+--------+");
             }
         }catch (final Exception e){
             System.out.println("Error : " + e);
         }
     }
 }

 <CODE ENDS>

Appendix B. Test Vectors

This section provides test values that can be used for the HOTP time- based variant algorithm interoperability test. M'Raihi, et al. Informational [Page 14]


RFC 6238                      HOTPTimeBased                     May 2011


   The test token shared secret uses the ASCII string value
   "12345678901234567890".  With Time Step X = 30, and the Unix epoch as
   the initial value to count time steps, where T0 = 0, the TOTP
   algorithm will display the following values for specified modes and
   timestamps.

  +-------------+--------------+------------------+----------+--------+
  |  Time (sec) |   UTC Time   | Value of T (hex) |   TOTP   |  Mode  |
  +-------------+--------------+------------------+----------+--------+
  |      59     |  1970-01-01  | 0000000000000001 | 94287082 |  SHA1  |
  |             |   00:00:59   |                  |          |        |
  |      59     |  1970-01-01  | 0000000000000001 | 46119246 | SHA256 |
  |             |   00:00:59   |                  |          |        |
  |      59     |  1970-01-01  | 0000000000000001 | 90693936 | SHA512 |
  |             |   00:00:59   |                  |          |        |
  |  1111111109 |  2005-03-18  | 00000000023523EC | 07081804 |  SHA1  |
  |             |   01:58:29   |                  |          |        |
  |  1111111109 |  2005-03-18  | 00000000023523EC | 68084774 | SHA256 |
  |             |   01:58:29   |                  |          |        |
  |  1111111109 |  2005-03-18  | 00000000023523EC | 25091201 | SHA512 |
  |             |   01:58:29   |                  |          |        |
  |  1111111111 |  2005-03-18  | 00000000023523ED | 14050471 |  SHA1  |
  |             |   01:58:31   |                  |          |        |
  |  1111111111 |  2005-03-18  | 00000000023523ED | 67062674 | SHA256 |
  |             |   01:58:31   |                  |          |        |
  |  1111111111 |  2005-03-18  | 00000000023523ED | 99943326 | SHA512 |
  |             |   01:58:31   |                  |          |        |
  |  1234567890 |  2009-02-13  | 000000000273EF07 | 89005924 |  SHA1  |
  |             |   23:31:30   |                  |          |        |
  |  1234567890 |  2009-02-13  | 000000000273EF07 | 91819424 | SHA256 |
  |             |   23:31:30   |                  |          |        |
  |  1234567890 |  2009-02-13  | 000000000273EF07 | 93441116 | SHA512 |
  |             |   23:31:30   |                  |          |        |
  |  2000000000 |  2033-05-18  | 0000000003F940AA | 69279037 |  SHA1  |
  |             |   03:33:20   |                  |          |        |
  |  2000000000 |  2033-05-18  | 0000000003F940AA | 90698825 | SHA256 |
  |             |   03:33:20   |                  |          |        |
  |  2000000000 |  2033-05-18  | 0000000003F940AA | 38618901 | SHA512 |
  |             |   03:33:20   |                  |          |        |
  | 20000000000 |  2603-10-11  | 0000000027BC86AA | 65353130 |  SHA1  |
  |             |   11:33:20   |                  |          |        |
  | 20000000000 |  2603-10-11  | 0000000027BC86AA | 77737706 | SHA256 |
  |             |   11:33:20   |                  |          |        |
  | 20000000000 |  2603-10-11  | 0000000027BC86AA | 47863826 | SHA512 |
  |             |   11:33:20   |                  |          |        |
  +-------------+--------------+------------------+----------+--------+

                            Table 1: TOTP Table



M'Raihi, et al.               Informational                    [Page 15]


RFC 6238                      HOTPTimeBased                     May 2011


Authors' Addresses

   David M'Raihi
   Verisign, Inc.
   685 E. Middlefield Road
   Mountain View, CA  94043
   USA

   EMail: davidietf@gmail.com


   Salah Machani
   Diversinet Corp.
   2225 Sheppard Avenue East, Suite 1801
   Toronto, Ontario  M2J 5C2
   Canada

   EMail: smachani@diversinet.com


   Mingliang Pei
   Symantec
   510 E. Middlefield Road
   Mountain View, CA  94043
   USA

   EMail: Mingliang_Pei@symantec.com


   Johan Rydell
   Portwise, Inc.
   275 Hawthorne Ave., Suite 119
   Palo Alto, CA  94301
   USA

   EMail: johanietf@gmail.com


반응형
728x90

# vsftpd 주요 서비스

/etc/rc.d/init.d/vsftpd start          //FTP서비스 시작
/etc/rc.d/init.d/vsftpd stop          //FTP서비스 종료
/etc/rc.d/init.d/vsftpd restart       //FTP서비스 재시작
/etc/vsftpd/vsftpd.conf               //설정 파일

/sbin/chkconfig vsftpd on           //부팅 시 자동실행

/yum update vsftpd                    //이미 설치가 되어 있으면, vsftpd 업데이트하기

 


# vsftpd 관련 파일

/etc/vsftpd/vsftpd.conf          //vsftpd의 주된 설정파일
/usr/sbin/vsftpd                   //vsftpd의 데몬파일
/etc/initd./vsftpd                  //vsftpd 시작/종료/재시작 스크립트
/etc/pam.d/vsftpd                //vsftpd의 PAM설정
/var/log/vsftpd.log               //vsftpd의 로그파일
/etc/vsftpd.user_list             //FTP 접속을 제한할 사용자 리스트
/etc/vsftpd.ftpusers              //PAM에서 사용하는 FTP 접속제한자 리트스파일


 


# 계정별 vsftpd 접속제한 파일

1. /etc/vsftpd.user_list (or /etc/vsftpd/user_list)
vsftpd에서 기본으로 사용하는 계정별 접속제어 파일이다. 이 파일에 등록된 사용자들은 ftp접속을 거부하게 된다.  
이 파일에 등록할 때에는 다음 3가지 룰을 지켜주면 된다.

  - 가능한 시스템 계정들은 모두 등록한다.
  - 한 행에 한 계정씩만 등록한다.
  - /etc/vfstpd/vsftpd.conf파일(or /etc/vsftpd.conf)에서 
     "userlist_deny=NO"으로 설정되었을 경우에 여기에 등록한 사용자들은 접속을 허용하는 사용자들이며
     "userlist_deny=YES"로 설정하였을 경우에는 접속을 거부하는 사용자리스트가 된다.
     YES가 기본이므로 기본설정을 변경하지 않는다면 이 파일은 접속거부자리스트파일이 된다.


2. /etc/vsftpd.ftpusers (or /etc/vsftpd/ftpusers)
다음은 PAM의 VSFTPD 설정파일로서 /etc/vsftpd/ftpusers 파일에 등록된 사용자들은 접속을 거부하겠다는 의미의 
설정 파일이다. 즉, /etc/vsftpd.ftpusers 파일은 PAM에서 설정하여 사용하고 있는 ftp 접속거부자 리스트 파일이다.

#cat /etc/pam.d/vsftpd
#%PAM-1.0
auth       required     pam_listfile.so item=user sense=deny file=/etc/vsftpd/ftpusers onerr=succeed
auth       required     pam_stack.so service=system-auth
auth       required     pam_shells.so
account    required     pam_stack.so service=system-auth
session    required     pam_stack.so service=system-auth


 


# /etc/vsftpd/vsftpd.conf 설정옵션

- anonymous_enable=YES (default YES)
  익명(anonymous)접속을 허용할 것인(YES) 허용하지 않을 것인가(NO)를 결정한다.

- anon_root=/var/ftp
  익명(anonymous)접속시 루트디렉토리를 지정한다.

- local_enable=YES (default YES)
  로컬 계정 사용자들의 접속을 허용할 것인가의 여부를 결정한다.
  YES로 설정하면 로컬계정사용자의 접속을 허용하는 것이며 NO로 설정하면 허용하지 않는 것이다.

- write_enable=YES (default YES)
  이 설정은 ftp전용명령어 중에 write명령어를 허용할 것인가를 결정하는 것이다.
  허용하려면 YES, 허용하지 않으려면 NO를 설정한다.

- local_umas=022 (default 022)
  로컬계정 사용자들의 umask값을 설정한다.

- anon_upload_enable=YES (default NO)
  익명(anonymous)계정 사용자에게 파일 어로드를 허용할 것인가(YES) 허용하지 않을 것인가(NO)의 여부를 설정한다.
  가능한 익명계정으로 접속한 사용자에게는 업로드 권한을 허용하지 않는 것이 보안에 좋다.

- anon_mkdir_write_enable=YES (default NO)
  익명(anonymous)계정 사용자에게 디렉토리 생성권한을 허용할 것인가(YES) 허용하지 않을 것인가(NO)의 여부를 설정하는 지시자이다.
  가능한 익명계정으로 접속한 사용자에게는 디렉토리 생성권한을 허용하지 않는 것이 보안에 좋다.

- ftpd_banner=Welcome to blah FTP service.
  ftp서버로 접속할 때에 안내메시지등을 출력하려면 여기서 설정하면 된다.

- dirmessage_enable=YES
  ftp접속한 사용자가 특정 디렉토리로 이동하였을 때 개별 디렉토리의 메시지를 보여주도록 허용할 것인가(YES) 허용하지 안을 것인가(NO)를 설정하다.

- message_file=.message
  ftp접속후에 특정 디렉토리로 이동할 때에 디렉토리 안내메시지 파일로 사용할 파일명을 지정한다.

- xferlog_enable=YES
  ftp접속후에 파일 업로드와 다운로드에 대한 로그를 남길것인가(YES) 남기지 않을 것인가(NO)를 설정한다.

- xferlog_file=/var/log/vsftpd.log
  ftp로그파일의 위치를 결정한다.

- xferlog_std_format=YES
  로그파일에 남길 로그파일의 포맷을 기본포맷으로 남길 것인가(YES) 아닌가(NO)를 설정한다.

- connect_from_port_20=YES
  ftp서비스는 기본적으로 21번 포트와 20번 포트를 사용한다.
  ftp 접속돠 명령어에 사용되는 포트는 21번이며 실제 데이터전송에 사용되는 기본포트는 20번이다.
  이 때 20번 포트의 데이터전송 연결을 허용할 것인가(YES) 허용하지 않을 것인가(NO)를 설정한다.

- session_support=YES
  이 설정이 YES로 설정되어 유효하게 되었을 때에는 바이너리파일인 wtmp에 ftp접속관련기록을 남기게 된다.
  last라는 명령어는 각 사용자들의 접속기록을 wtmp파일에서 가져와 확인하는 명령어이므로 이 설정이 적용되면 last명령어로 ftp접속기록을 확인할 수 있다.

- idle_session_timeout=600
  ftp연결에서 idle타임에 대한 타임아웃값을 설정한다.

- data_connection_timeout=120
  데이터 전송시 적용되는 타임아웃값을 설정한다.

- anon_max_rate=0
  local_max_rate=0
  trans_chunk_size=0
  ftp서비스의 전송속도를 제한하는 설정이다.
  초당 byte수를 지정할 수 있으며 제한없이 허용하려면 0으로 설정한다.
  이 설정은 vsftpd가 독립뎀ㄴ(standalone)모드로 서비스될 때에만 적용되는 것이다.

- max_clients=30
  max_per_ip=3
  이 설정은 동시 ftp접속자수를 제한하는 설정이다.
  max_clients는 ftp접속을 최대 30명까지만 허용하는 설정이다.
  max_per_ip는 한 IP(호스트)에서 동시에 3번까지만 접속이 가능하다는 설정이다.

- ascii_upload_enable=YES
  ascii_download_enable=YES
  기본적으로 ASCII모드로 업로드/다운로드하는 것은 제한되어 있다.
  이 설정으로 ASCII모드로의 업로드/다운로드를 허용하도록 설정할 수 있다.

- deny_email_enable=YES
  banned_email_file=/etc/vsftpd/banned_emails
  익명접속시에 기본적으로 사용되는 계정명을 anonymous이며 패스워드는 email형식으로 입력하면 된다.
  이 때 패스워드로 인정하지 않을 즉, 패스워드로 사용하지 못하도록 할 email 주소를 사용하도록 하는 지시자이다.
  즉, "deny_email_enable=YES"로 설정하시고 "banned_email_file=/etc/vsftpd/banned_emails"로 설정되어 있다면
  패스워드로 허용하지 않을 email 주소를 /etc/vsftpd/banned_emails 파일에 넣어두면 된다.
  그러면 이 파일에 등록된 email주소는 패스워드로 인정하지 않는다.

- chroot_list_enable=YES
  chroot_list_file=/etc/vsftpd/chroot_list
  전체 사용자가 아닌 특정 사용자들에 대하여 자신의 홈디렉토리를 루트디렉토리로 인식하도록 하는 기능으로서 이 기능은 사용자의 홈디렉토리의 상위디렉토리로 벗어나지 못하도록 하는 설정이다.
  먼저 "chroot_list_enable=YES"로 설정하고 /etc/vsftpd/chroot_list 파일에는 이 기능을 적용할 사용자계정명을 등록하면 된다.
  즉, /etc/vsftpd/chroot_list 파일에 등록된 사용자들에 한하여 chroot기능이 적용되어 자기 자신의 홈디렉토리 상위 디렉토리의 이동이 제한된다.

- chroot_local_user=YES
  특정 사용자가 아닌 전체 사용자를 대상으로 chroot()기능을 적용하여 자기 자신의 홈디렉토리 상위 디렉토리로 이동하지 못하도록 하려면 이 설정을 YES로 설정한다.
  만약 "chroot_list_enable=YES" 이고 "chroot_local_user=YES"이면 /etc/vsftpd/chroot_list파일에 등록된 사용자들만 chroot()적용을 받지 않게 된다.
  즉, 이 두 설정이 모두 YES로 되어있다면 /etc/vsftpd/chroot_list에 등록된 사용자들을 제외한 나머지 사용자들만 chroot()가 적용된다.

- ls_recurse_enable=YES
  ftp접속에서는 ls 사용시 -R옵션을 허용하지 않는 것이 기본 설정이다.
  -R옵션이란 서브디렉토리내의 파일들의 리스팅(목록)까지 모두 확인할 수 있도록 하는 것이다.
  이 지시자의 값이 YES로 되어 있다면 ftp접속후에 디렉토리 목록 확인시에 서브디렉토리들의 목록들까지 하넌에 볼 수 있는 -R옵션을 허용하게 된다.

- pam_service_name=vsftpd
  vsftp에서 PAM설정파일명으로 사용할 파일명을 지정한다.

- listen=YES
  listen_port=21
  만약 vsftpd를 xinetd모드가 아닌 독립데몬(standalone)으로 서비스하려면 위의 listen지시자를 YES로 설정하고 listen_port에 서비스할 포트번호(기본 21번)를 지정하면 된다.


출처 : http://oracle.tistory.com/129 (안나푸르나)

반응형
728x90

SFTP는 기본적으로 로그를 남지 않습니다, 때문에 파일의 변경/삭제가 어떻게 된 것인 찾기가 곤란할 수 있습니다.

이번에 소개해 드릴 openssh 및 syslog의 간단한 설정으로 SFTP 작업 로그 남기는 방법에 대해 소개 드립니다.

 

 

1. /etc/ssh/sshd_config 의 편집


아래의 라인을 수정이나 추가해 줍니다.
보통 ‘Subsystem’이 주석 처리되어 있을 것이니 주석을 해제하고 아래와 같이 수정/추가해 주시면 됩니다.

추가할 내용 : Subsystem       sftp    /usr/libexec/openssh/sftp-server -f local2 -l INFO

명령: # echo “Subsystem       sftp    /usr/libexec/openssh/sftp-server -f local2 -l INFO” >> /etc/ssh/sshd_config
          # tail /etc/ssh/sshd_config

sftp88

sftp-server에 대한 자세한 설정 사항은 “man sftp-server” 로 옵션 사항을 참고하세요.

2. syslog.conf 나 rsyslog.con 파일 수정


저는 경우 rsyslog를 사용하여 /etc/rsyslog.conf 에 내용을 추가 했습니다.

추가 내용  : local2.*                                        /var/log/sftp.log

 

명령: # echo “local2.*                                        /var/log/sftp.log” >> /etc/rsyslog.conf
         # tail /etc/rsyslog.conf
sftp77

 

3. 로그 파일 생성 : sftp.log


sftp.log 파일은 syslog나 rsyslog 서비스를 재시작 해주면 자동으로 생성이 된다, 만약 생성이 되지 않았을 경우 다음 명령으로 생성해 줍니다.

 

명령:  # touch /var/log/sftp.log

4. rsyslog, sshd,서비스 재시작


명령 : # /etc/init.d/rsyslog restart 또는 /etc/init.d/syslog restart
          # /etc/init.d/sshd restart

 

 

5. 로그 남김 확인
sftp 테스트 접속 후 로그를 보자

명령 : # tail -f /var/log/sftp.log
sftp99

 

6. 로그로테이트 추가
로그가 기록되는 것이 확인되었다면, 마지막으로 로그로테이트에 sftp.log를 추가하여, 일정 용량 이상일 경우 로그를 백업하도록 하자.
/etc/logrotate.d/syslog 에 “/var/log/sftp.log” 를 추가하자.

sftp66

반응형
728x90

sftp 로그를 남겨보자.

sftp 로그는 남지 않습니다. 그 방식이 inet 방식이 되었든 standalone가 되었든 안남습니다.
왜 남지 않을까요?
생각해보았지만, ftp로그에도 별도로 남지는 않더라구요.

ftp 로그는 저는 xferlog로 남기지만, 암튼 남지 않는건 확실합니다. 

 

 

vi /etc/ssh/sshd_config 
루트로 로그인 하여 다음의 설정 상황을 살펴봅시다.
119 # override default of no subsystems
120 Subsystem       sftp    /usr/libexec/openssh/sftp-server -f local2 -l INFO

편의상 set nu로 줄표시를 하였습니다. 

이것과 상관이 있지는 않습니다. 

일단 멘페이지에서 관련된 메뉴얼을 확인해보았습니다. 
번역을 할까 말까 했는데, 우리가 관심있게 봐야 할 것은 로그레벨 설정하는 것과 로그 패실리티 설정하는 것 두개만 존재한다고 보면
될것 같습니다. 


man sftp-server
SFTP-SERVER(8)            BSD System Manager’s Manual           SFTP-SERVER(8)

NAME
     sftp-server - SFTP server subsystem

SYNOPSIS
     sftp-server [-f log_facility] [-l log_level]

DESCRIPTION
     sftp-server is a program that speaks the server side of SFTP protocol to stdout and expects client requests from
     stdin.  sftp-server is not intended to be called directly, but from sshd(8) using the Subsystem option.

     Command-line flags to sftp-server should be specified in the Subsystem declaration.  See sshd_config(5) for more
     information.

     Valid options are:

     -f log_facility
             Specifies the facility code that is used when logging messages from sftp-server.  The possible values
             are: DAEMON, USER, AUTH, LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7.  The default is
             AUTH.

     -l log_level
             Specifies which messages will be logged by sftp-server.  The possible values are: QUIET, FATAL, ERROR,
             INFO, VERBOSE, DEBUG, DEBUG1, DEBUG2, and DEBUG3.  INFO and VERBOSE log transactions that sftp-server
             performs on behalf of the client.  DEBUG and DEBUG1 are equivalent.  DEBUG2 and DEBUG3 each specify
             higher levels of debugging output.  The default is ERROR.

     For logging to work, sftp-server must be able to access /dev/log.  Use of sftp-server in a chroot configuation
     therefore requires that syslogd(8) establish a logging socket inside the chroot directory.

SEE ALSO
     sftp(1), ssh(1), sshd_config(5), sshd(8)

     T. Ylonen and S. Lehtinen, SSH File Transfer Protocol, draft-ietf-secsh-filexfer-00.txt, January 2001, work in
     progress material.

AUTHORS
     Markus Friedl 〈markus@openbsd.org

HISTORY
     sftp-server first appeared in OpenBSD 2.8 .

BSD                             August 30, 2000                            BSD
(END) 

 

그 다음은 로그를 관리해야 할 부분을 세팅해야 합니다. 

 

 

vi /etc/syslog.conf 
35 local2.*                                        /var/log/sftp.log
가장 바닥에 셋팅하면 됩니다.

여기가 좀 중요한것 같은데,
syslog 재시작 해주고, sshd 재시작해주면 됩니다. 
순서가 중요하다고 이런 저런 사이트에서 보면 있네요.

 

되는지 안되는지 확인해보면 됩니다. 


tail -f /var/log/sftp.log 
Apr 16 17:59:02 www sftp-server[2985]: debug1: request 291: sent names count 1
Apr 16 17:59:02 www sftp-server[2985]: debug1: read eof
Apr 16 17:59:02 www sftp-server[2985]: session closed for local user 

 

되는 것을 확인합니다.


반응형

+ Recent posts