[proxmox] Nginx로 webdav 서버 돌려보기

JSHyeon·2024년 7월 24일
post-thumbnail

0. 들어가기

지난 포스팅에서 proxmox 환경에서 리버스 프록시 서버와 webdav 서버를 설치했다.

apache로 구성된 webdav 서버는 안정적이긴 했지만 리버스 프록시 적용 시 특정 명령에 502 에러가 뜨고(아마 프록시 쪽 문제였겠지만), 설정이 복잡한 등 불편함을 많이 느꼈다.

내친 김에 점유율도 높고 설정도 비교적 편리한 Nginx로 webdav 서버를 구축해보고자 했다.

이 글을 따라가면 이런 구조로 구축된다. proxmox 쪽은 리버스 프록시 서버 컨테이너, webdav 서버 컨테이너로 구성되며 그 중 리버스 프록시 서버 컨테이너만 외부로 노출된다.

1. Nginx로 webdav 서버 구축하기

proxmox에서 리눅스 컨테이너를 하나 생성하고, 거기에 webdav 서버를 구축한다.
먼저 컨테이너를 하나 생성한다. 나는 이 사양 정도로 진행을 해봤다.

이 컨테이너의 쉘에 접속하자. 서버 구축을 위해 먼저 nginx와 libnginx-mod-http-dav 라이브러리를 설치해야 한다.

$ sudo apt update
$ sudo apt install nginx nginx-full

그 다음 webdav로 공유할 폴더의 소유권을 변경해야 한다. 기본적으로 www-data다.

$ sudo chown www-data:www-data /path/to/share

그 다음 인증 정보를 담은 파일을 생성해주어야 한다. 나는 /etc/nginx/.htpasswd 위치에 생성해 주었다.

$ sudo apt install apache2-utils
$ htpasswd -c /etc/nginx/.htpasswd <webdav-username>

android용 webdav 클라이언트 앱이 basic 인증만 지원하기 때문에... HTTP basic 인증으로 처리하려 한다.

이때 basic 인증은 계정 정보를 평문으로 전송하기 때문에 반드시 암호화된 프로토콜과 함께 사용해야 한다! 나는 리버스 프록시 서버를 통해 HTTPS를 적용시켜보기로 했다.

그 다음 /etc/nginx/sited-enabled/ 경로에 설정 파일을 하나 만들자. 나는 /etc/nginx/sited-enabled/webdav 파일을 만들어서 진행했다.

dav_ext_lock_zone zone=foo:10m;

server {
        listen 80;
        listen [::]:80;

        server_name <inner-address>;

        charset utf-8;

        client_max_body_size 0;
        client_body_buffer_size 0;

        location / {
                root /path/to/share;

                charset utf-8;

                set $x $uri$request_method;

                if ($x ~ [^/]MKCOL$) {
                        rewrite ^(.*)$ $1/;
                }

                autoindex on;
                auth_basic "Restricted Access";
                auth_basic_user_file /etc/nginx/.htpasswd;
                client_body_temp_path /tmp;
                dav_methods PUT DELETE MKCOL COPY MOVE;
                dav_ext_methods PROPFIND OPTIONS LOCK UNLOCK;
                dav_ext_lock zone=foo;
                dav_access user:rw group:rw all:r;
        }
}

<inner-address>/path/to/share은 본인 상황에 맞춰 바꿔주자.

그다음 nginx -t로 설정 유효성 검사를 진행한 다음 systemctl restart nginx로 변경 사항을 적용해주자.

정상적으로 진행되었다면 웹 브라우저로 http://<inner-address>로 접속했을 때 이런 화면이 뜰 것이다.

htpasswd 명령어에서 입력했던 계정으로 접속하면 /path/to/share 경로의 내용이 표시될 것이다.
이제 webdav 서버 구축은 완료되었고, 이제 외부로 노출할 리버스 프록시 서버를 만들어보자.

2. 리버스 프록시 서버 구축하기

리버스 프록시 서버는 클라이언트의 요청을 받아 각각의 서버로 연결해주는 서버다. 클라이언트의 업무?를 대리하는 일반적인 프록시 서버와 반대로, 서버 쪽에서의 처리를 담당하기 때문에 리버스가 붙었다.

리버스 프록시 서버를 구축하면, 리버스 프록시 서버만 HTTPS CA 인증서를 발급하면 되기 때문에 유지 및 관리가 용이하다. 또 로드 밸런싱을 지원하고, 외부에 노출되는 서버가 리버스 프록시 서버 하나로 줄어들기 때문에 보안 측면에서도 좋다.

이 단락에서는 nginx를 이용해서 리버스 프록시 서버를 구축하고, CA 인증서도 발급하여 HTTPS 적용까지 진행해 보도록 한다.

먼저 컨테이너를 하나 생성하고, 그리고 위 단락를 참고해서 nginx 설치까지 진행해주자.

그 다음 nginx 설정을 변경해야 한다. proxy_pass 옵션으로 nginx로 온 요청을 넘겨줄 수 있다.

다음의 설정을 /etc/nginx/sites-enabled/default에 넣어주자.

map $http_destination $fixed_destination {
    default $http_destination;
    "~^https://(.*)$" http://$1;
}

server {
        server_name <domain>;

        listen 443 ssl;

        client_max_body_size 0;
        client_body_buffer_size 0;

        charset utf-8;

        location / {
                proxy_pass <webdav-inner-address>;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_set_header Destination $fixed_destination;
        }
}

현재 구성에서는 webdav 서버는 HTTP를, 리버스 프록시 서버는 HTTPS를 사용하므로 이를 변환시키는 로직이 필요하다. proxy_pass에서 요청 URL 변환은 대응할 수 있으나 HTTP 헤더에 있는 주소는 자동으로 변환되지 않으므로, 이를 변환시켜야 한다. 위 설정에서 이 부분이 해당 변환을 수행한다.

map $http_destination $fixed_destination {
    default $http_destination;
    "~^https://(.*)$" http://$1;
}

server {
		...
        location / {
        		...
                proxy_set_header Destination $fixed_destination;
        }
}

두 번째로 HTTPS 적용을 위해 도메인 등록이 필요하다. 나는 gabia에서 도메인을 하나 샀다...
그 다음, 도메인 사이트 설정에서 도메인을 서버의 IP 주소와 연동시켜야 한다. 유동 IP의 경우 DDNS를 설정한 다음, DDNS의 주소를 도메인 설정에서 넣으면 되는 것 같다. 나는 고정 IP 환경에서 서버를 세팅했으므로 도메인 설정에서 IP 주소를 바로 입력했다.

이제 certbot을 설치하고 CA 인증서를 발급받아 nginx 설정에 넣어줘야 한다.

$ sudo apt update
$ sudo apt install certbot python3-certbot-nginx

그 다음 다음 명령을 실행해서 CA 인증서 발급 및 등록을 진행하자.

$ sudo certbot --nginx -d <domain>

이제 $ sudo systemctl restart nginx를 입력하여 nginx 서버를 재시작하고, 웹 브라우저로 도메인 주소로 접속하면 HTTPS가 적용된 webdav 서버로 접속될 것이다.

이런 방식으로 proxmox web ui, 공유기 관리자 페이지도 HTTPS 및 인증 방식을 적용시켜 외부로 공개할 수 있다. 물론 가급적 관리자 페이지는 외부 접속을 허용하지 않는 것이 보안 상 이롭기 때문에, 복잡한 비밀번호를 설정하고 fail2ban 같은 추가 대응책을 마련하는 것이 좋다.

모든 서브도메인에 대한 CA 인증서 발급 받기(작성중)

certbot으로 모든 서브도메인에 대한 인증서를 발급받을 수 있다.

$ sudo certbot certonly --manual -d *.your.domain -d your.domain --preferred-challenges dns

413 client intended to send too large body 오류 해결하기

request body가 너무 커서 발생하는 오류다. client_max_body_size를 0(무제한)으로 두면 해결된다.

MOVE 명령 시 400 오류 해결하기

HTTP Header에 있는 Destination URL가 https://...로 되어 있고, 이것이 수정되지 않아 잘못된 요청을 보내고 있었다..(이거 잡는데 2시간 걸렸음)

참고자료

https://yusang.tistory.com/80

https://leeleelee3264.github.io/post/2023-03-25-subdomain-with-nginx/

https://www.lesstif.com/system-admin/nginx-http-413-client-intended-to-send-too-large-body-86311189.html

https://devblog.lazyig.com/76/

profile
네트워크와 인프라를 좋아하는 학부생

0개의 댓글