웹브라우저(구글 크롬, 익스플로러, 엣지 등)는 html, php, js 등의 확장자를 가진 파일을 웹서버로부터 읽어들여서 화면에 표시해주는 기능을 합니다. 


그런데 웹브라우저에서 읽어들일 수 있는 파일이 웹서버에 없다면?


nginx file share

▲ 웹브라우저는 웹서버에 있는 파일들의 목록을 띄웁니다(아파치 기본값).


웹서버 프로그램인 아파치(Apache)는 위 스크린 샷처럼 파일들의 목록을 띄웁니다. 상위/하위 디렉토리 이동도 당연히 가능하고요.

파일을 배포하기에 좋아보이죠?


▲ 또다른 웹서버 프로그램인 엔진엑스(Nginx)의 기본값은 파일목록을 볼 수 없도록 되어 있습니다.


기본값을 공개로 해놓고 필요에 따라 닫느냐, 기본값을 비공개로 해놓고 필요에 따라 여느냐는 편의성과 보안 중 어떤 가치를 중요하게 여기는지에 따른 선택인 것 같은데... 어쨌든 Nginx도 파일목록이 보이게끔 처리할 수 있다고 하니까 개방해 보겠습니다.

(파일 리스트를 노출하지 않고 파일 링크 주소만 전달하는 식으로 공유하는 것도 방법이 될 수 있겠습니다만... 파일 리스트를 노출하는 것이 좋을 때도 있죠.)


▲ 통상적으로 /var/www/html/ 경로를 웹루트로 쓰시고, 아파치 VirtualHost나 엔진엑스 server { } 블록으로 멀티사이트 구축하는 경우는 /var/www/html/ 하위에 디렉토리 여러개 만들어서 매칭시킨 다음 CMS 툴들을 넣고 쓰시잖아요?

저는 테스트를 위해 /var/www/html/jimnongtest2/ 라는 웹루트 하위에 folder, 1st, 2nd 디렉토리 트리를 만들었고, /home/계정명/ 하위에 3rd, 4th 디렉토리 트리를 만들었습니다.

(언급한 경로들을 눈에 익혀 주세요!!) => 설명하다보니 /home/aaa/ 경로는 아예 언급을 안하게 됐습니다. 이 경로는 눈에 익히지 마세요.


/etc/nginx/sites-enabled/ 경로에 있는 서버블록 설정 파일을 열어보면...


▲ 서버블록 구성이 이런 식으로 되어 있을 겁니다(설명용이라 최대한 간단하게 줄였어요.). 웹루트 경로가 초록색 밑줄이고요.

서버블록 안쪽 붉은 네모 부분에 location { } 블록을 추가해서 파일목록이 노출되는 곳을 만들 겁니다.


▲ 먼저, 이런 식으로 location 경로를 서버블록 하위의 특정 디렉토리까지로 적은 다음 autoindex on; 이라고 적고 Nginx 서비스를 재시작해보면...

(참고로 /folder/1st/ 이렇게 적지 마세요. /folder/1st 이렇게 마지막에 / 기호 빼고 적으세요.)


※ /etc/nginx/nginx.conf 파일의 http { } 블록 이나 /etc/nginx/sites-enabled/ 경로의 server { } 블록에 charset UTF-8; #한글깨짐방지 구문이 없다면 location { } 블록 안쪽에 charset UTF-8; 구문을 추가하는 것이 좋습니다. 그러면 한글로 된 파일명/디렉토리명이 깨지지 않아요.


▼ 웹브라우저로 해당 경로에 접근했을 때 파일 목록과 하위 디렉토리 목록이 보이는 것을 확인할 수 있습니다. 성공한 거죠!

▲ autoindex on; 설정은 하위 디렉토리(위 스샷에서 2nd)에까지 영향을 미칩니다. 상위 디렉토리(위 스샷에서 folder)에는 영향을 미치지 않아서 접근이 금지되는 것을 확인할 수 있고요.


▲ 만약 위 스샷처럼 하위 디렉토리 location 블록에 autoindex off; 설정을 하면 하위 디렉토리 접근이 차단되겠죠?




※ alias(별칭) 사용으로 긴 경로를 줄여보자(기존 경로를 대체)


도메인주소/folder/1st 경로를 웹브라우저에 직접 입력하기엔 좀 길게 느껴질 수 있습니다. 더 긴 경로도 있을 수 있고 말이지요.

이럴 때 경로에 alias를 적용하면 경로를 줄일 수 있습니다. 주소를 짧게 쓰면서 파일을 공유할 수 있다면 메리트가 있겠지요?


▲ 저는 location을 a로 할당하고 alias에는 /웹루트경로/folder/1st 를 할당해봤는데, 웹브라우저에 http://도메인주소/a 라고 쳐보니까 http://도메인주소/folder/1st 라고 친 것과 동일한 경로가 나오는 것을 확인할 수 있었습니다.

(스샷 참고 : alias 경로는 도메인 뒤에 붙는 경로를 적는 게 아니고, 리눅스 디렉토리 경로를 그대로 적는 겁니다.)


참고로 디렉토리 alias가 아니라 단일 파일을 alias하고 싶다면 이런 식으로 location 블럭을 구성하면 됩니다(크게 다를 게 없네요.).


location = /a.mp3 {

    alias /var/www/html/jimnongtest2/folder/1st/1st.mp3;

}


- 참고 문서 : NginX에서 location 패턴

Nginx HTTP Server - 4. HTTP 환경설정



※ location { } 블럭 내에서의 alias와 root 구문의 차이


location 블럭 내에서 alias 대신 root 명령어를 이용해서 경로를 구성하는 방법도 있다고 하는데요,

alias 명령어는 location 경로를 완전히 대체하는 개념이지만, root 명령어는 root경로 뒤에 location 경로를 붙이는 식으로 해석된다고 합니다.


▼ 예를 들어 /var/www/jimnongtest2/folder/1st 라는 디렉토리를 공유하고 싶은데 root 명령어를 쓰고자 한다면 root 경로는 /var/www/html/jimnongtest/folder 를 적고, location 경로에는 /1st 를 적어야 하는 것이죠.

▲ 웹브라우저 주소창에는 도메인 뒤에 location 경로만 적으면 이렇게 파일 목록이 보입니다.


▲ 하지만 이것을 alias 명령어로 구성하려면 location에는 /1st를, alias에는 전체 경로를 적어야 할 것입니다.


▲ 만약 location 경로에 /a 라고 적어주면 /var/www/html/jimnongtest/folder/a 디렉토리가 매칭될텐데, a라는 디렉토리가 실제로 존재하지 않는다면 (위 스샷처럼) 404 Not Found 에러가 뜨겠지요.


결국 alias든 root든 정답은 없는 것 같아요. 취향에 따라 alias나 root를 선택해서 location 블럭을 적당히 구성하시면 되겠습니다.




※ Nginx 경로에 비밀번호 걸기


Nginx에는 비밀번호를 걸 수 있는 기능이 내장되어 있다고 합니다. ngx_http_auth_basic_module 모듈이 해당 기능을 수행한다고 하는데요, 아래의 설명을 따라하시면 구축됩니다.


▲ 서버블록 설정파일 안쪽의 원하는 location 블록에 붉은 네모처럼 구성을 추가하고 저장+빠져나옵니다.


auth_basic 구문이 있어야 아래 스샷처럼 계정을 묻는 대화창이 나옵니다. 따옴표는 생략할 수 없고, 따옴표 안의 내용은 대화창에 표시되는 문구인데, 크롬에서는 표시되지 않는 것 같습니다(아래 스샷 참고).



auth_basic_user_file 구문은 계정 정보(ID와 비밀번호)가 저장된 파일의 경로입니다. 디렉토리와 파일명 모두 원하는 곳으로 정하면 됩니다. 다만 location 블록의 경로와 일치시키면 로그인했을 때 계정정보가 담긴 파일이 노출될 가능성이 올라가니까 안 좋겠죠? (실제로 해보면 노출이 안 되긴 하지만...)


다음으로 auth_basic_user_file 에서 설정한 경로에 계정(ID)과 비밀번호를 만드는 작업을 합니다.


▲ sudo sh -c "echo '계정명:$(openssl passwd)' >> /경로명/파일명"

(이 코드를 퍼가서 블로그에 게시하실 분은... 업그레이드 좀 해주세요. 잘 모르는 상태에서 짠거라 미흡합니다.)


터미널 창에서 이런 형식으로 입력하면 해당 경로에 파일이 생성되면서(파일이 존재하면 해당 파일에) 계정이 기록됩니다. (openssl 패키지가 구동되면서) 암호 입력을 2번 하라고 뜨는데, 암호를 넣으면 자동으로 암호화되고 salt 쳐져서 등록됩니다. 계정 정보를 담고 있는 파일을 에디터로 열어보면 "계정명:패스워드" 형태로 리스트화되어 저장된 것을 확인할 수 있고요.


터미널 창에서 명령어를 치는 것을 싫어하는 분들을 위해... 온라인 생성기를 준비해봤습니다.ㅋ

http://www.clockwatchers.com/htaccess_tool.html


▲ .htpasswd Tool 항목에 계정 정보를 입력하면 "계정명:암호화된 패스워드" 형식으로 나올 겁니다. auth_basic_user_file 경로에 복붙하면 됩니다.


참고로 .htpasswd는 아파치에서 쓰이는 형식인데, 엔진엑스에서도 적용할 수 있는 부분이 있네요. 다른 분들은 htpasswd 유틸리티를 우분투에 설치해서 패스워드를 생성하는 방법을 설명하셨는데, Nginx 쓰기로 한 마당에 굳이 아파치와의 연결고리를 만들 필요는 없지 않나... 생각합니다.


※ 참고 문서

https://dione6.blogspot.com/search?q=nginx

https://ohgyun.com/556

https://www.joinc.co.kr/w/man/12/Nginx/basicauth

https://www.digitalocean.com/community/tutorials/how-to-set-up-password-authentication-with-nginx-on-ubuntu-14-04



※ WebDAV 기능을 추가해보자(파일 쓰기, 디렉토리 생성 가능하도록)


Nginx 경로에 비밀번호 거는 작업까지 따라오셨다면 쓰기작업을 할 수 있는 WebDAV 기능 구축에도 욕심을 부려볼 수 있습니다.

저의 Nginx 설치 글을 따라하셨었다면 nginx-extras 패키지를 설치하셨을 텐데, nginx-full 패키지나 nginx-extras 패키지를 설치했다면 추가 구성요소(ngx_http_dav_module) 설치 없이 WebDAV를 구축할 수 있습니다.


▼ 경로 설정을 편하게 하려고 root 명령어 대신 alias 명령어를 썼습니다. 양해해주세요.

▲ 비밀번호 설정한 location 블록에 붉은 네모 표시한 구문들을 추가하고(경로는 원하는 곳으로 변경),

(temp 디렉토리 설정은 반드시 필요한 것 같습니다.)

(결국 위 스샷의 location { } 블럭 내용이 전부 들어가야 WebDAV 기능이 돌아가겠죠?)


▲ (옵션) 포트 바꾸고 싶으면 서버블록에서 listen 구문으로 바꾸면 됩니다. 저는 예를 들기 위해 포트를 추가하는 식으로 처리했는데, 보안을 생각한다면 서브도메인으로 서버블록을 다시 꾸리고 listen으로 포트를 연결한 다음 WebDAV location 블럭을 삽입하는 식으로 처리하는 것이 낫지 않을까요?


▲ Nginx 서비스를 재시작한 다음, 설정한 경로의 소유자명&그룹명을 www-data로 교체합니다. ll 명령어로 바뀐 것을 확인하면 좋겠죠.

(해당 디렉토리가 없으면 sudo mkdir 명령어로 만들고 진행해주세요.)


이것으로 WebDAV 설정 끝입니다. 간단하죠?


RaiDrive 같은 연결 프로그램을 쓰면 탐색기에서 파일을 읽고 쓸 수 있고, 안드로이드/IOS 파일탐색기에서도 WebDAV를 지원하면 마찬가지고, http 프로토콜을 지원하는 수많은 프로그램에서는 읽기 작업을 할 수 있으니까 편의성이 엄청 좋습니다.


※ 참고 문서

http://nginx.org/en/docs/http/ngx_http_dav_module.html

https://akal.co.kr/?p=1172


[우분투 18.04 데스크톱] LEMP : Let's Encrypt SSL 인증서 수동 발급과 엔진엑스(Nginx)에 적용하기



▲ 칼군무의 좋은 예.

반응형