HRConvert2 직접 호스팅 방법 및 설치 가이드
HRConvert2를 사용해 외부 서버를 거치지 않고 안전하게 파일을 변환하십시오. Apache 및 Docker 설치법과 bubblewrap 샌드박스 설정, 그리고 FFmpeg와 ImageMagick을 활용한 로컬 변환 환경 구축 방법을 상세히 안내합니다.
파일 변환기를 직접 호스팅하는 이유
파일 변환기를 직접 호스팅하면 파일이 자신의 디스크 내부에만 머무릅니다. 이것이 바로 직접 호스팅을 운영하는 유일한 이유입니다. 무료 변환 사이트는 파일을 업로드받은 뒤 그 파일이 어떻게 처리되는지 알 수 있는 방법을 제공하지 않습니다. 서명된 고객 계약서나 스캔한 의료 기록과 같은 파일을 다룰 때, 업로드 행위 자체가 보안 사고가 될 수 있습니다. HRConvert2는 PHP로 작성되었으며 GPLv3 라이선스를 따르는 드래그 앤 드롭 방식의 파일 변환 서버입니다. 2026년 8월 18일에 3.7.4 버전이 릴리스되었으며, 프로젝트 측은 488개의 형식을 지원한다고 밝히고 있습니다.
이 서비스는 데이터베이스, 계정, 쿠키를 사용하지 않습니다. 사용자는 임시 디렉터리로 간주됩니다. 모든 변환 작업은 로컬 명령줄 도구가 수행합니다. 문서에는 LibreOffice, 오디오와 비디오에는 FFmpeg, 이미지에는 ImageMagick, 광학 문자 인식(OCR)에는 Tesseract를 사용하며, 그 외 나머지 형식은 다양한 소형 도구들이 처리합니다. HRConvert2는 업로드 페이지, 파이프라인, 그리고 그 주변의 정리 작업을 담당합니다.
이 도구는 파일을 한 형식에서 다른 형식으로 변환합니다. 브라우저 기반의 오피스 제품군이 아니므로, 사용자가 브라우저 탭에서 문서를 편집하기를 원한다면 직접 호스팅하는 OnlyOffice 및 Collabora와 비교해 보십시오. 또한 이 도구는 저장소 역할도 하지 않습니다. 변환된 결과물은 삭제되도록 설계되었으므로, 파일을 장기적으로 보관해야 한다면 해당 작업은 직접 호스팅하는 파일 관리자의 몫입니다.
필요한 환경
Debian 또는 Ubuntu, Apache 2.4, PHP 8 이상, 그리고 bubblewrap이 필요합니다. Bubblewrap(bwrap)은 샌드박스 역할을 하며, 선택 사항이 아닙니다. 샌드박스를 구축할 수 없는 서버는 샌드박스 없이 실행하는 대신 변환 작업을 거부합니다. 업스트림 README에 따르면 Raspberry Pi Model B+로도 충분하며, 이는 PHP 부분에 한해서는 사실입니다. 변환기 바이너리가 실제 하드웨어 사양을 결정하며, 이에 대해서는 아래에서 자세히 다룹니다.
두 가지 설치 방법이 있습니다. Docker 이미지는 즉시 사용할 수 있습니다. Apache와 PHP를 직접 설치하는 방식은 저녁 시간 정도가 소요되며, 서버에 정확히 무엇이 설치되어 있는지 파악할 수 있게 해줍니다.
오늘 밤 Docker로 실행하기
이 이미지는 모든 변환기 바이너리를 포함하고 있어 크기가 큽니다. 2026년 8월 기준으로 약 3 GB입니다. 이미지를 내려받기 전에 디스크 여유 공간을 확인하십시오.
태그 관리가 중요합니다. 2026년 8월 17일 기준으로 Docker Hub에 게시된 최신 태그는 v3.7.2이며, 최신 GitHub 릴리스는 v3.7.4입니다. latest 태그는 가리키는 버전이 수시로 변경될 수 있고, 이 애플리케이션은 파서 영역이 넓으므로 특정 버전을 고정하고 의도적으로 업그레이드하십시오.
docker pull zelon88/hrconvert2:v3.7.2
docker run -d --name hrconvert2 \
-p 127.0.0.1:8080:80 \
--security-opt seccomp=unconfined \
zelon88/hrconvert2:v3.7.2docker ps
curl -I http://127.0.0.1:8080/정상적인 컨테이너는 Up 상태를 유지하며 curl 명령은 HTTP/1.1 200 OK을 반환합니다. 계속 재시작되는 컨테이너는 시작 과정에 문제가 있는 것이므로, 설정을 변경하기 전에 docker logs hrconvert2을 먼저 읽어보십시오.
두 가지 플래그가 중요합니다. -p 127.0.0.1:8080:80는 루프백 인터페이스에만 포트를 노출하므로, 의도적으로 앞에 프록시를 두기 전까지는 외부에서 변환기에 접근할 수 없습니다. 프로젝트 예제는 -p 8080:80 -p 8443:443을 매핑하는데, 이는 공용 인터페이스를 포함한 모든 인터페이스에서 수신 대기합니다. --security-opt seccomp=unconfined 플래그가 필요한 이유는 bubblewrap이 사용자 네임스페이스와 마운트 시스템 호출을 사용하여 샌드박스를 구축하는데, Docker의 기본 seccomp 프로필이 이를 차단하기 때문입니다. 이 플래그가 없으면 변환 작업이 실패하며 애플리케이션은 그 이유를 A sandbox blocks the required syscalls unless it was started with the correct options.와 같이 알립니다.
이 플래그는 일종의 트레이드오프입니다. 컨테이너의 시스템 호출 필터를 완화하여 애플리케이션이 내부에서 더 엄격한 자체 샌드박스를 구축할 수 있게 합니다. 이 동작을 결정하는 두 가지 설정은 Resources/config.php 내의 $RequireSandbox와 $RequireSandboxOnDocker이며, 기본값은 각각 TRUE와 FALSE입니다. Docker 요구 사항이 기본적으로 꺼져 있기 때문에, seccomp 플래그가 없는 컨테이너는 샌드박스 없이 변환을 수행합니다. 플래그를 적용한 후 $RequireSandboxOnDocker = TRUE;을 설정하면 컨테이너 내부에서 다시 거부 동작을 수행하게 할 수 있습니다.
이 장비에 Docker를 처음 설치한다면 데몬부터 설정하십시오. VPS에서 Docker 실행하기 문서에서 설치 방법, 스토리지 드라이버, Docker가 자체 방화벽 규칙을 작성하는 방식을 다룹니다.
Apache 및 PHP에 설치하기
저장소에 있는 Documentation/INSTALLATION_INSTRUCTIONS.txt 파일이 기준이며, 총 9단계로 진행됩니다. 전체적인 구성은 다음과 같습니다. 웹 서버, 언어, 샌드박스부터 시작하십시오.
sudo apt update
sudo apt install -y apache2 php libapache2-mod-php php-all-dev php8.3-zip php8.3-gd bubblewrapphp8.3-* 이름은 Ubuntu 24.04 기준입니다. php -v를 실행하여 본인의 버전에 맞는 접두사를 사용하십시오. PHP 릴리스마다 패키지 이름이 변경되므로 잘못된 이름을 사용하면 Unable to locate package 오류가 발생합니다.
다음은 변환기입니다. 문서, 이미지, 오디오, 비디오 및 OCR을 다루며, 이는 사용자가 실제로 수행하는 대부분의 변환 작업을 포함합니다.
sudo apt install -y imagemagick ffmpeg libreoffice-common libreoffice-java-common \
default-jre ghostscript poppler-utils libgxps-utils tesseract-ocr inkscape \
xvfb clamav curl tar libxcb-cursor0아카이브 형식, 3D 모델, 전자책 및 부팅 가능한 ISO 이미지는 더 많은 패키지가 필요하며, 일부는 Ubuntu의 multiverse 구성 요소에 포함되어 있습니다. 공식 지침의 3단계와 5단계에 전체 목록이 순서대로 나와 있습니다. 두 가지 의존성 패키지는 apt 패키지가 아닙니다. 저장소는 인코더가 필요하거나 Ubuntu에서 패키징하지 않는 ImageMagick 7이 필요한 사용자를 위해 Documentation/Build/ffmpeg-build.sh 및 Documentation/Build/build-imagemagick-v7.sh를 제공합니다. 전자책 지원은 calibre 자체 설치 프로그램을 통해 이루어지며, 지침에는 한 줄로 명시되어 있습니다.
sudo -v && wget -nv -O- https://download.calibre-ebook.com/linux-installer.sh | sudo sh /dev/stdin이는 root 권한으로 셸에 파이프라인을 통해 전달되는 벤더 스크립트입니다. 이것이 업스트림 방식이며 선택 사항입니다. 이 단계를 건너뛰면 전자책 변환 기능만 사용할 수 없습니다.
다음은 PHP 제한 설정입니다. 변환 작업은 느리고 파일 크기가 크기 때문에 기본값은 너무 작습니다. 프로젝트는 php.ini에서 다음 값을 설정합니다.
max_execution_time = 1200
max_input_time = 90
memory_limit = 512M
post_max_size = 5000M
upload_max_filesize = 5000M
max_file_uploads = 100
display_errors = Off
zlib.output_compression = On이 수치들은 여유 자원이 있는 시스템을 가정합니다. 소규모 VPS에서 작업할 경우 값을 낮추십시오. upload_max_filesize = 5000M와 max_file_uploads = 100를 사용하면 단일 요청으로 40 GB 디스크 용량을 훨씬 초과하는 데이터를 기록할 수 있기 때문입니다. Apache를 재시작하고 PHP가 실제로 로드한 설정을 확인하십시오.
sudo service apache2 restart
php -i | grep -E "upload_max_filesize|post_max_size|memory_limit"이제 작업 디렉터리를 설정합니다. Resources/config.php의 $ConvertLoc에서 이름을 지정하며, 기본값은 /DATA/HRConvert2입니다. 웹 서버 사용자가 해당 디렉터리의 소유권을 가져야 합니다.
sudo mkdir -p /DATA/HRConvert2
sudo chmod -R 0755 /DATA/HRConvert2
sudo chown -R www-data:www-data /DATA/HRConvert2Apache 문서 루트 아래에 릴리스 파일의 압축을 풉니다. 기본 레이아웃은 HRProprietary/HRConvert2 폴더에 배치하며, Resources/config.php의 $InstLoc에는 실제 설치 경로를 지정해야 합니다. 그런 다음 내장 진단 도구를 실행하십시오. 이는 사용자가 문제를 겪기 전에 누락된 의존성을 찾는 가장 빠른 방법입니다.
sudo php /path/to/HRConvert2/convertCore.php -v-v는 핵심 버전, 의존성 검사, 샌드박스 상태, 언어 팩 등 전체 설치 상태를 점검합니다. 파일 변환은 명령줄에서 지원되지 않으므로, 이 인수 세트는 관리 목적으로만 사용됩니다.
Ubuntu 24.04를 새로 설치하면 왜 모든 변환 작업이 실패합니까?
샌드박스 때문이며, 이는 첫날 가장 흔하게 발생하는 문제입니다. Ubuntu 24.04와 Debian 12는 기본적으로 권한이 없는 사용자의 네임스페이스(user namespace)를 제한합니다. Bubblewrap은 샌드박스를 구축하기 위해 사용자 네임스페이스가 필요한데, 이로 인해 bwrap이 시작되지 못합니다. 애플리케이션은 샌드박스 없이는 변환을 거부하므로 모든 작업이 실패하게 됩니다.
직접 확인하는 방법은 다음과 같습니다.
bwrap --ro-bind / / --dev /dev /bin/true && echo sandbox okPermission denied 오류가 발생한다면 네임스페이스가 차단된 것입니다. 해결 방법은 bwrap 바이너리에 AppArmor 프로필을 적용하는 것입니다. 먼저 ABI 파일을 나열하고 가장 높은 숫자를 확인하십시오.
ls /etc/apparmor.d/abi/그런 다음 /etc/apparmor.d/bwrap를 작성하고, 4.0 부분을 확인한 가장 높은 숫자로 교체하십시오.
abi <abi/4.0>,
include <tunables/global>
profile bwrap /usr/bin/bwrap flags=(unconfined) {
userns,
include if exists <local/bwrap>
}프로필을 로드하십시오.
sudo apparmor_parser -r /etc/apparmor.d/bwrap출력이 없으면 프로필이 정상적으로 로드된 것입니다. bwrap 확인 명령을 다시 실행하면 sandbox ok이 출력될 것입니다. 이제부터 변환 작업이 정상적으로 작동합니다.
공개 변환기는 외부인에게 노출된 파서입니다
이 섹션은 이 게시물의 핵심 목적입니다. 인터넷에서 접근 가능한 파일 변환기는 익명의 사용자로부터 임의의 파일을 받아 LibreOffice, ImageMagick, FFmpeg 또는 Ghostscript로 전달합니다. 이들은 파서 버그의 긴 역사를 가진 거대한 C 및 C++ 코드베이스입니다. 파일을 업로드하는 사용자가 형식을 선택한다는 것은, 곧 어떤 파서가 실행될지 그리고 그 내부의 어떤 코드 경로가 동작할지를 사용자가 결정한다는 의미입니다.
HRConvert2는 모든 의존성 소프트웨어를 bubblewrap 네임스페이스 안에서 실행하는 방식으로 이에 대응합니다. 각 변환 작업은 두 개의 디렉터리만 볼 수 있습니다. 하나는 읽기 전용으로 마운트된 입력 파일이 있는 디렉터리이고, 다른 하나는 출력 파일을 받는 디렉터리입니다. 네트워크는 공유되지 않으며, 프로젝트의 표현을 빌리자면 closes every URL handler in every dependency at once입니다. 이는 생각보다 훨씬 중요합니다. ImageMagick과 Ghostscript는 모두 URL을 가져오는 참조를 허용하는데, 변환기가 이를 악용하면 내부 네트워크에서 클라우드 메타데이터 엔드포인트에 접근하는 서버 측 요청 위조(SSRF) 도구로 변질될 수 있기 때문입니다. 네임스페이스 내에 네트워크가 없으면 이러한 데이터 가져오기(fetch)는 불가능합니다.
거부(refusal)는 나머지 절반의 핵심입니다. A server that cannot build a sandbox refuses the conversion rather than quietly running without one. 아무도 읽지 않는 로그에 경고만 남기는 도구보다, 실패 시 즉시 차단되는 도구가 훨씬 가치가 있습니다. 이것이 바로 앞서 언급한 AppArmor 설정이 선택 사항이 아니며, 컨테이너를 외부에 노출하기 전에 $RequireSandboxOnDocker을 검토해야 하는 이유입니다.
policy.xml을 이용한 ImageMagick 보안 강화
ImageMagick의 자체 정책 파일은 샌드박스 하위의 두 번째 보안 계층이며, 이를 설정하는 것이 좋습니다. Ubuntu 24.04의 ImageMagick 6에서 해당 파일은 /etc/ImageMagick-6/policy.xml에 위치합니다. 현재 활성화된 설정을 출력하려면 다음을 실행합니다.
identify -list policy프로젝트는 Documentation/Build/policy.xml에 정책 파일을 제공하며, 이는 좋은 참고 모델이 됩니다. 이 정책은 PS, PS2, PS3, EPS, XPS 및 MVG 코더(coder)를 거부하고, URL, HTTPS, HTTP 및 gs 델리게이트(delegate)를 거부하는 동시에 PDF는 허용합니다.
<policy domain="coder" rights="none" pattern="PS" />
<policy domain="coder" rights="none" pattern="MVG" />
<policy domain="delegate" rights="none" pattern="URL" />
<policy domain="delegate" rights="none" pattern="gs" />
<policy domain="coder" rights="read|write" pattern="PDF" />gs 행이 가장 중요합니다. ImageMagick은 PostScript를 직접 파싱하지 않습니다. 대신 Ghostscript를 호출하며, 잘 알려진 ImageMagick 원격 코드 실행 취약점은 바로 이 델리게이트에서 발생합니다. 해당 델리게이트를 거부하면 파일의 형식 선언과 관계없이 ImageMagick은 업로드된 파일을 gs에 전달하지 않습니다.
동일한 정책 파일에서 리소스 제한을 설정할 수 있으며, 이를 통해 조작된 이미지가 서버 자원을 고갈시키는 것을 방지합니다.
<policy domain="resource" name="memory" value="256MiB"/>
<policy domain="resource" name="map" value="512MiB"/>
<policy domain="resource" name="disk" value="1GiB"/>
<policy domain="resource" name="width" value="16KP"/>
<policy domain="resource" name="height" value="16KP"/>
<policy domain="resource" name="area" value="128MP"/>압축 폭탄(decompression bomb)은 실제 크기는 작지만 선언된 차원은 매우 큰 파일입니다. width, height 및 area 제한은 메모리 할당이 발생하기 전에 이를 거부하므로, 커널이 프로세스를 강제 종료하기 전에 프로세스가 스스로 종료됩니다.
반대 방향의 함정도 존재합니다. Ubuntu의 기본 정책은 PDF 코더를 완전히 거부하므로, 수정하지 않은 시스템에서는 PDF 작업 시 attempt to perform an operation not allowed by the security policy 'PDF' 오류가 발생합니다. 이 메시지는 정책이 정상적으로 작동하고 있음을 의미합니다. 코더를 다시 허용할지는 신중하게 결정해야 하며, 허용하더라도 gs 델리게이트는 계속 거부 상태로 유지해야 합니다.
소규모 VPS에서 의존성 체인이 초래하는 비용
유휴 상태일 때는 이 중 어느 것도 비용이 많이 들지 않습니다. Apache와 PHP는 수십 메가바이트 정도를 점유하며, 변환기 바이너리는 전혀 실행되지 않습니다. 전체 비용은 파일이 도착하는 순간 한꺼번에 발생합니다.
문서 변환이 시작되면 LibreOffice가 실행되고, 이는 다시 Java 런타임을 시작합니다. 이미지 변환은 위 정책에 따라 ImageMagick에 256 MiB의 메모리와 512 MiB의 메모리 맵을 할당합니다. 비디오 변환은 FFmpeg이 비디오 처리를 위해 수행하는 방식대로 사용 가능한 모든 코어를 점유합니다. 프로젝트 설정에서 PHP 자체의 memory_limit은 512M으로 지정되어 있습니다. 이러한 수치들은 단일 작업 중에 운영 체제 및 웹 서버의 자원 사용량 위에 누적됩니다.
따라서 1 GB RAM을 가진 VPS는 첫 번째 실제 문서 변환 시 스왑을 사용하게 되며, 이후 스래싱(thrashing) 현상이 발생합니다. 메모리가 고갈되면 커널의 out of memory killer가 상주 크기가 가장 큰 프로세스를 종료합니다. 보통은 soffice.bin가 종료되며, 사용자는 유용한 메시지 없이 변환이 실패하는 상황을 겪게 됩니다. 때로는 apache2가 종료되어 사이트 전체가 다운되기도 합니다. 이 경우 dmesg -T | grep -i "killed process"을 통해 사후에 확인할 수 있습니다.
이는 벤치마크라기보다는 사이징 가이드입니다. 4 GB RAM과 2개의 코어는 소규모 팀이 사용하기에 적합하며, 문서와 이미지 위주의 작업이고 대기 시간을 감수한다면 스왑 파일을 포함한 2 GB RAM으로도 운영이 가능합니다. 스왑 파일이 변환 속도를 높여주지는 않습니다. 스왑 파일은 급격한 부하를 치명적인 오류가 아닌 느린 처리로 전환해주며, 이는 페이지가 멈추는 것과 서비스가 중단되는 것의 차이를 만듭니다. 디스크 공간은 필요하다고 느끼는 것보다 더 넉넉하게 할당하십시오. 3 GB 크기의 이미지, 큰 업로드 제한, 그리고 변환된 출력물은 다른 자원이 고갈되기 훨씬 전에 디스크를 가득 채우기 때문입니다.
변환 작업은 본질적으로 버스트(bursty)한 특성을 가집니다. 두 사람이 동시에 비디오를 업로드하면 모든 코어를 사용하게 되며, 다음 요청은 그 뒤에서 대기하게 됩니다. 이 앞단에는 작업 큐가 없으므로, 사용자가 제어할 수 있는 유일한 수단은 제한 설정뿐입니다.
단일 업로드가 디스크를 가득 채우지 않도록 제한 설정하기
먼저 PHP 값을 조정합니다. 4 GB 메모리를 사용하는 공유 서버라면 upload_max_filesize = 512M, post_max_size = 512M, max_file_uploads = 20 정도가 적절한 시작점입니다. max_execution_time = 1200은 하나의 PHP 요청이 20분 동안 실행되도록 허용하는데, 이는 긴 영상 변환 작업에 꼭 필요하지만 동시에 느린 업로드 하나가 20분 동안 워커를 점유하게 됨을 의미합니다.
그다음, 요청이 PHP에 도달하기 전에 프록시 단계에서 크기와 속도를 제한합니다.
limit_req_zone $binary_remote_addr zone=convert:10m rate=6r/m;
server {
listen 443 ssl;
server_name convert.example.com;
client_max_body_size 512M;
client_body_timeout 300s;
location / {
limit_req zone=convert burst=4 nodelay;
proxy_pass http://127.0.0.1:8080;
proxy_read_timeout 1200s;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}client_max_body_size은 변환하려는 가장 큰 파일보다 커야 합니다. 그렇지 않으면 Nginx가 413 Request Entity Too Large를 반환하며 PHP는 업로드 파일을 전달받지 못합니다. proxy_read_timeout은 가장 긴 변환 시간보다 길어야 합니다. 그렇지 않으면 프록시 뒤에서 정상적으로 실행 중인 작업이 브라우저에 504 Gateway Time-out를 반환하게 됩니다. TLS(전송 계층 보안) 종료를 포함한 해당 서버 블록의 나머지 설정은 Nginx 리버스 프록시 설정 줄 단위 상세 설명에서 다룹니다.
변환된 파일 삭제
모든 변환 작업은 웹 서버가 읽을 수 있는 디렉터리에 민감한 파일의 복사본을 남깁니다. 정리 작업은 단순한 변환 도구와 그동안 변환된 모든 파일이 저장된 아카이브를 구분 짓는 기준입니다.
$DeleteThreshold는 Resources/config.php 내에서 세션이 만료되는 시간을 분 단위로 설정하며, 기본값은 60입니다. 콘텐츠가 민감한 경우 이 값을 15로 낮추십시오. 정리 작업 자체는 코어의 명령줄 인수로 수행합니다.
sudo -u www-data php /path/to/HRConvert2/convertCore.php -c
sudo -u www-data php /path/to/HRConvert2/convertCore.php -c=15-c은 설정된 임계값을 사용하여 두 데이터 위치에서 만료된 세션을 삭제합니다. -c=15은 해당 실행 시에만 15분을 사용합니다. -c=now는 사용자가 현재 변환 중인 세션을 포함하여 나이와 관계없이 모든 세션을 삭제하므로, 유지보수 시에만 사용하십시오. 동일한 인수를 docker exec을 통해 컨테이너 내부에서도 사용할 수 있습니다.
정리 작업이 페이지 로드에 의존하지 않도록 타이머를 설정하십시오. /etc/cron.d/hrconvert2에 다음 한 줄을 추가하는 것으로 충분합니다.
*/10 * * * * www-data php /path/to/HRConvert2/convertCore.php -c몇 분 후 ls /DATA/HRConvert2로 확인하면 오래된 세션 디렉터리가 사라지는 것을 볼 수 있습니다. 웹 서버 사용자가 해당 디렉터리의 소유자이므로, 파서가 공격당할 경우 공격자는 정확히 그 계정의 권한을 획득하게 됩니다. 따라서 해당 계정은 가치 있는 다른 어떤 파일도 소유해서는 안 됩니다. VPS에서의 최소 권한 사용자 계정은 일반적인 패턴이며, 이 경우 특히 더 중요하게 적용됩니다.
공개 목적이 아니라면 인증 뒤에 배치하십시오
기본 설치 상태에서는 설계상 계정이 존재하지 않습니다. 페이지에 접근할 수 있는 사람은 누구나 파일을 업로드하고 변환기 바이너리를 실행할 수 있으며, 속도 제한(rate limit)은 이를 지연시킬 뿐입니다. 따라서 어떤 상황인지 결정해야 합니다.
본인과 소수의 동료를 위한 것이라면, 외부로 전혀 노출하지 마십시오. 위에서 설명한 대로 컨테이너를 루프백(loopback)에 바인딩하고 사설 네트워크나 SSH 터널을 통해 접근하십시오. 이렇게 하면 공용 인터넷의 그 누구도 파일을 보낼 수 없으며, 공격을 필터링하는 대신 공격 표면 전체를 제거하게 됩니다.
브라우저에서 접근해야 한다면, 프록시 앞에 인증을 추가하십시오. Basic auth는 두 개의 명령어로 설정할 수 있으며, 외부인이 업로드 폼에 접근하지 못하도록 차단합니다:
sudo apt install -y apache2-utils
sudo htpasswd -c /etc/nginx/.htpasswd alicelocation / {
auth_basic "Converter";
auth_basic_user_file /etc/nginx/.htpasswd;
proxy_pass http://127.0.0.1:8080;
}Nginx를 다시 로드하고 페이지를 불러오십시오. 인증 창이 나타나면 정상적으로 작동하는 것이며, 나타나지 않는다면 편집한 location 블록이 해당 요청을 처리하고 있지 않은 것입니다. 공유 비밀번호가 아닌 실제 계정을 사용하려면, 단일 사인온(SSO) 제공자에서 TLS를 종료하십시오. 직접 호스팅하는 Authentik SSO 서버를 사용하면 자체 로그인 기능이 없는 애플리케이션 앞단에서 포워드 인증(forward authentication)을 수행할 수 있습니다.
진정으로 공개적인 변환기를 운영하는 것이 목적이라면, 그에 따른 위험을 수용하고 대비책을 세우십시오. 샌드박스가 공격받을 것임을 가정해야 합니다. 이미지 태그를 고정하고, ImageMagick 정책을 엄격하게 유지하며, 업로드 제한을 작게 설정하고, 중요한 데이터가 없는 VPS에서 실행하십시오.
실패 유형 및 확인되는 메시지
모든 변환이 즉시 실패합니다. 샌드박스를 빌드할 수 없습니다. 일반적인 설치 환경에서는 AppArmor 프로필이 원인입니다. Docker 환경에서는 --security-opt seccomp=unconfined가 누락된 경우입니다. 애플리케이션은 이를 A sandbox blocks the required syscalls unless it was started with the correct options.라고 명시하며 See --Require Sandbox-- & --Require Sandbox On Docker-- in config.php.을 가리킵니다.
이미지 변환만 실패합니다. Bubblewrap is missing or non functional, so this image conversion cannot be isolated!은 웹 서버 사용자의 경로에 bwrap이 없거나 접근할 수 없음을 의미합니다.
특정 형식만 변환에 실패합니다. 바이너리가 누락된 경우이며, ImageMagick may not be installed, or may not be reachable on the system path used by the web server user.와 같이 명확하게 보고됩니다. 이 메시지는 FFmpeg와 LibreOffice 모두에서 동일하게 나타납니다. convertCore.php -v을 실행하여 설치된 항목을 확인하십시오. Apache 워커의 PATH는 사용자의 로그인 셸 PATH와 다를 수 있음을 유의해야 합니다.
PDF 작업이 정책 오류로 실패합니다. attempt to perform an operation not allowed by the security policy 'PDF'은 HRConvert2가 아닌 ImageMagick의 policy.xml에서 발생하는 오류입니다.
대용량 업로드 시 413 오류가 반환됩니다. nginx의 client_max_body_size 설정값이 파일 크기보다 작기 때문입니다. 처리 과정에는 nginx에 하나, PHP에 두 개, 총 세 개의 제한이 있으며 이 중 가장 작은 값이 적용됩니다.
변환이 중단되고 명확한 변경 사항이 없습니다. The device where data is stored has an insufficient amount of storage space available.가 발생합니다. 여유 공간을 확인하고 정리 작업(cleanup sweep)이 실제로 실행 중인지 확인하십시오.
로그에 정리 작업 관련 불만이 기록됩니다. Could not clean the temporary location! 및 Could not clean the convert location!은 소유권 문제입니다. 웹 서버 사용자가 $ConvertLoc에 지정된 디렉터리의 소유권을 가지고 있어야 합니다.
FAQ
자가 호스팅 파일 변환기를 인터넷에 공개해도 안전합니까?
외부인에게 파서(parser)를 노출하는 것으로 간주한다면 충분히 안전합니다. 모든 업로드는 LibreOffice, ImageMagick, FFmpeg 또는 Ghostscript로 전달되며, 업로드하는 사용자가 이를 선택합니다. HRConvert2는 이러한 도구들을 네트워크 접근이 차단되고 입력 디렉터리가 읽기 전용으로 설정된 bubblewrap 네임스페이스 내부에서 실행합니다. 또한 샌드박스 처리가 불가능한 변환은 거부하며, 이는 매우 강력한 기본 보안 설정입니다. 그럼에도 인증을 요구하고, 업로드 제한을 작게 설정하며, 다른 중요한 데이터가 없는 VPS에서 실행하는 것이 좋습니다.
Ubuntu 24.04를 새로 설치했는데 왜 모든 변환이 실패합니까?
Ubuntu 24.04와 Debian 12는 비권한 사용자 네임스페이스(unprivileged user namespaces)를 제한하며, bubblewrap은 샌드박스를 구축하기 위해 이를 필요로 합니다. 이 애플리케이션은 샌드박스 없이는 변환을 수행하지 않으므로, 일부 작업이 아닌 모든 작업이 실패하게 됩니다. /usr/bin/bwrap에 대한 AppArmor 프로필을 flags=(unconfined)로 작성하고, sudo apparmor_parser -r /etc/apparmor.d/bwrap으로 로드한 뒤, bwrap --ro-bind / / --dev /dev /bin/true로 확인하십시오.
Docker에서는 변환이 실패하는데 일반 설치 환경에서는 왜 작동합니까?
Docker의 기본 seccomp 프로필은 bubblewrap이 사용하는 시스템 호출을 차단하므로 컨테이너 내부에서 샌드박스를 생성할 수 없습니다. 이 프로젝트의 실행 명령어가 사용하는 --security-opt seccomp=unconfined 플래그를 추가하여 시작하십시오. $RequireSandboxOnDocker은 기본값이 FALSE이므로, 플래그를 설정하지 않은 컨테이너는 샌드박스 없이 변환을 시도할 수 있다는 점에 유의하십시오. seccomp 플래그가 적용된 후에는 이를 TRUE로 설정하십시오.
파일 변환 서버에는 어느 정도의 RAM이 필요합니까?
유휴 상태일 때는 메모리 점유가 적지만, 실제 변환 작업 시에는 그렇지 않습니다. LibreOffice는 Java 런타임을 시작하며, ImageMagick은 기본 정책 하에서 256 MiB의 메모리와 512 MiB의 맵을 사용하고, PHP 자체 제한은 512M입니다. 1 GB VPS에서는 이러한 조합으로 인해 스왑이 발생하며, OOM(Out of Memory) 킬러가 soffice.bin 또는 apache2를 종료시킵니다. 소규모 팀의 경우 4 GB RAM과 2개의 코어를 계획하고, 변환 작업이 메시지 없이 종료될 때마다 dmesg -T | grep -i "killed process"을 확인하십시오.
변환된 파일은 어디에 저장되며 언제 삭제됩니까?
파일은 Resources/config.php 내의 $ConvertLoc로 지정된 작업 디렉터리로 이동하며, 기본값은 /DATA/HRConvert2입니다. $DeleteThreshold은 세션이 만료되는 시간을 분 단위로 설정하며, 기본값은 60입니다. 삭제 작업은 명령줄에서 수행합니다. php convertCore.php -c은 만료된 세션을 삭제하고, -c=now는 활성 세션을 포함한 모든 세션을 즉시 삭제합니다. 사이트 방문 여부와 관계없이 삭제가 이루어지도록 -c을 cron 항목이나 systemd 타이머에 등록하십시오.