nginx로 WebDAV 서버 구축하기

nginx로 WebDAV 서버 구축하기

홈 서버를 운영 할 때 WebDav 서버를 구축해두면 파일을 관리하기가 편해진다.

이번 포스트에서는 nginx로 WebDav 서버를 구축하는 법에 대해서 알아본다.
환경은 Ubuntu22.04 LTS를 사용하였다.


필요한 모듈 패키징

일반적으로 apt를 이용하여 nginx를 설치할텐데, nginx의 기본 패키지에는 WebDav 서버를 구축하는데 필요한 일부 기능이 탑재되어 있지 않다. 그렇기 때문에 WebDav 확장 모듈을 다운로드 하여 기존 소스와 합치는 컴파일링 작업이 필요하다.

사전 준비

우선은 필요한 파일들을 다운로드 할 디렉토리를 생성해주자.

$ cd ~
$ mkdir nginx
$ cd nginx

소스 리포지토리 리스트를 편집한다.

$ sudo nano /etc/apt/sources.list

맨 마지막 줄에 리포지토리 주소를 추가한다.

deb [signed-by=/etc/apt/keyrings/nginx.gpg] http://nginx.org/packages/ubuntu/ jammy nginx
deb-src [signed-by=/etc/apt/keyrings/nginx.gpg] http://nginx.org/packages/ubuntu/ jammy nginx

jammy는 Ubuntu22.04버전의 코드명. 다른 버전의 우분투를 사용 중이라면 해당 버전의 코드명으로 대체하면 된다.

다음은 nginx의 패키지 공개키를 다운로드

$ wget https://nginx.org/keys/nginx_signing.key

다운로드 한 공개키를 gpg 파일로 변환. 나중에 다운로드 받을 nginx의 소스 파일이 정말 공식 소스가 맞는지 확인 할 때 gpg 키가 사용된다.

$ gpg --no-default-keyring --keyring temp-keyring.gpg --import nginx_signing.key
$ gpg --no-default-keyring --keyring temp-keyring.gpg --export --output nginx.gpg

작성된 gpg 키를 apt-key에 추가.

$ cp -p nginx.gpg /etc/apt/keyrings/

패키징을 위한 준비

패키징을 하기 위해 필요한 앱을 설치.

$ apt install dpkg-dev

nginx의 소스 파일 다운로드. 가장 최신의 stable 버전이 다운로드 된다. 이 포스트를 작성하는 시점에서 가장 최신 버전은 1.22.1

$ apt source nginx

nginx의 dependency를 설치.

$ apt install debhelper dpkg-dev quilt lsb-release libssl-dev libpcre2-dev zlib1g-dev build-essential

빌드를 실행하는데 필요한 라이브러리 설치

$ apt install libxml2-dev libxslt-dev

nginx의 WebDav 확장 모듈 다운로드.

$ git clone https://github.com/arut/nginx-dav-ext-module.git

이것으로 nginx 소스에 WebDav 모듈을 추가해서 패키징하는데 필요한 준비가 끝난다.


컴파일

소스와 확장모듈을 합치기 위해서는 빌드 규칙을 수정해야한다.

우선 nginx-dav-ext-module의 절대 경로를 알아본다.

$ pwd

이 포스트의 위에서 부터 똑같이 따라했다면 아마 절대 경로는 아래와 같을 것이다.

/home/<유저명>/nginx/nginx-dav-ext-module

빌드 규칙이 쓰여있는 파일을 연다.

sudo nano nginx-1.22.1/debian/rules

스크롤을 내리다보면 config.status.nginxconfig.status.nginx_debug라는 항목이 있을 것이다. 두 항목 모두 CFLAGS라는 부분이 있는데 그 부분의 맨 마지막에 --add-module=<모듈의 절대경로>를 추가해주면 된다.

--add-module=/home/<유저명>/nginx/nginx-dav-ext-module

이제 컴파일하면 된다. 우선 소스 디렉토리로 이동

$ cd nginx-1.22.1

컴파일 실행.

$ dpkg-buildpackage -uc -b

빌드가 완성된 패키지 파일은 소스 디렉토리의 상위 디렉토리에 작성되기 때문에 상위 디렉토리로 이동.

$ cd ..

패키지를 인스톨 해주자. 이미 nginx가 설치되어 있는 경우는 apt uninstall nginx로 한번 언인스톨 한 후 인스톨 해주자.

dpkg -i nginx_1.22.1-1~jammy_amd64.deb

제대로 설치됐는지 확인 하고 마무리.

nginx -v

1.22.1이 뜨면 성공적으로 설치가 된 것이다.


서버블록 추가

nginx 서버 블록의 예제를 위해 사용 할 값.
자신에게 맞는 값을 사용하면 된다.

  • 사용 할 포트: 1234
  • 루트 디렉토리: /var/www/html/webdav
server {
    listen 1234;
    
    location / {
        root /var/www/html/webdav;
        
        # 보안설정 (인증된 사용자만 접속가능)
        auth_basic "Restricted";
        auth_basic_user_file /etc/nginx/.credentials.list;
        
        # 허용 할 오퍼레이션 설정. 
        # 왼쪽 부터 파일업로드 파일삭제 디렉토리생성 복사 이동
        dav_methods PUT DELETE MKCOL COPY MOVE;
        
        # PROPFIND: 리소스의 속성을 돌려줌 (디렉토리 구조 등)
        # OPTIONS: 어떤 오퍼레이션이 가능한지 알려줌
        # 이 기능이 필요해서 nginx-dav-ext-module을 패키징 한 것.
        dav_ext_methods PROPFIND OPTIONS;
        
        # WebDav의 액세스 권한
        dav_access user:rw group:rw all:r;
        
        # 캐릭터 코드
        charset utf-8;
        
        # 브라우저에서 접속 할 때 설정
        autoindex on; # WebDav의 목적은 파일 리스트를 보는 것이기 때문에 켜두는 것이 좋음
        autoindex_exact_size on; # 파일 사이즈 표시 여부
        autoindex_localtime on; # 파일이 마지막으로 수정 된 시각
        
        # 업로드 사이즈 제한
        client_max_body_size 0; # 0으로 하면 제한 없음
        
        # 기타 설정
        client_body_temp_path /tmp; # Request Body가 허용용량을 초과 했을 때 임시 적으로 request를 저장하는 디렉토리. 원하는 디렉토리로 변경 가능.
        create_full_put_path on; # 필요한 디렉토리를 작성 가능하게 설정.
        
        # 로그
        access_log /var/log/nginx/webdav.access.log;
        error_log /var/log/nginx/webdav.error.log;
    }
}

주석 외에 추가로 설명 한 부분들은 auth_basic & dav_access

auth_basic

클라이언트에서 서버에 접속 시, 유저명과 패스워드를 입력해야만 접속이 가능하도록 하는 기능.
브라우저에서 접속해보면 팝업이 뜨는데 그 때 입력 해야하는 인증 정보.

예제 코드에서는 인증 정보를 /etc/nginx/.credentials.list에 저장하도록 했다.
이 파일 안에 기술 해야 할 정보는 다음과 같다.

<username>:<password>

username이 john, password가 1234라고 하면

john:1234

이런식으로 기술하면 된다.
하지만 비밀번호는 Plain 방식으로 저장하면 안되니 암호화를 한 비밀번호를 기술 해 준다.
암호화 된 비밀번호는 다음 커맨드로 만들 수 있다.

openssl passwd -apr1

그러면 설정 할 비밀번호를 물어보니 입력해주면 되고, 비밀번호 확인을 위해 다시 입력해주면 암호화 된 비밀번호가 나온다.

# 비밀 번호가 1234인 경우
Password: 
Verifying - Password: 
$apr1$PwfyDUro$D5FeSx2zu4uV3tg1N4WEq.

마지막 .까지가 비밀번호다.
그럼 최종적으로 .credentials.list에 적어야 하는 내용은 다음과 같다.

john:$apr1$PwfyDUro$D5FeSx2zu4uV3tg1N4WEq.

.credentials.list를 열어서 내용을 적어주고 저장.

$ sudo nano /etc/nginx/.credentials.list

john:$apr1$PwfyDUro$D5FeSx2zu4uV3tg1N4WEq.

브라우저로 접속 시 유저명에 john, 비밀번호 1234를 입력하면 WebDav에 접속 할 수 있다.
다른 WebDav 클라이언트를 사용 할 때도 마찬가지.

dav_access

auth_basic의 인증과 dav_access에서 설정하는 WebDav의 액세스 권한은 어떻게 다를까.

dav_access user:rw group:rw all:r;

여기서 설정하는 usergroup은 리눅스의 유저와 그룹을 얘기한다. auth_basic에 설정하는 유저명과는 전혀 상관이 없는 부분.

WebDav에서 접속 가능하게 해 둔 디렉토리의 권한이 제대로 되어있지 않다면, WebDav로 접속시 파일을 읽을 수는 있어도 이름을 변경, 파일 삭제와 같은 건 실행이 되지 않는다.
파일을 읽을 수 있는건 all:r에서 WebDav에 접속만 하면 누구든 파일을 읽을 수 있게 설정을 해뒀기 때문이다.

그럼 여기서 말하는 usergroup은 무엇을 뜻하는 걸까.
nginx의 환경설정에서 설정해 둔 usergroup을 뜻한다.

nginx의 환경설정 파일을 열어서 확인해보자.

nano /etc/nginx/nginx.conf

딱히 이 파일을 편집한 적이 없다면 맨 윗 부분에 user nginx;라고 적혀 있을 것이다.
여기에 적혀 있는 user가 앞서 말한 dav_access에서 사용하는 user이다.
설정하는 방법은

user <user>:<group>;

인데 <user>만 설정하고 <group>을 설정하지 않으면 group도 자동으로 user와 같은 이름으로 설정이 된다. nginx의 기본값의 경우 user도 nginx, group도 nginx가 된다.

이 부분이 중요한 이유는 WebDav에서 접속 가능하게 설정해둔 디렉토리에 usernginx가 권한이 없다면 파일을 편집 할 수 없다. (dav_access all:rw라고 설정하면 가능은 하지만 보안상 좋지 않다)

예를 들어 루트 디렉토리가 /var/www/html/webdav/인데 nginx가 이 디렉토리에 대한 권한이 없으면, 파일을 편집하려고 할 때 Permission Denied 에러가 뜨게 된다.

리눅스 시스템의 퍼미션과 유저권한은 이번 포스트의 주제에서 벗어 나기 때문에 자세한 설명은 생략한다.
잘 모르는 경우 ls -l <path> & chmod & chown에 대해서 알아보면 된다.


nginx에서 WebDav를 구축 할 때 알아두면 좋은 기초적인 지식 정리 끝.