Soo

[카테고리:] 컴퓨터

  • 비밀번호 관리가 이렇게 귀찮을 줄이야 – Vaultwarden

    비밀번호가 너무 많다.

    비밀번호 만큼 브라우저니 앱이니 많다. 다들 자기 시스템에 비밀번호를 저장하라고 난리다. 내가 보니 비밀번호를 저장해둔 시스템이 400여개 생각보다 많지 않네? 그래도 모두 외울순 없으니 난감한차에 비밀번호를 안전하게 보호해준다는 크롬, 삼성브라우저, 파이어폭스, 알패스(망했죠?)까지.. 처음엔 고마웠다.

    요즘엔 브라우저 호환때문에 이것 저것 쓰진 않지만 얼마전까지만 해도 그런 불편이 심했다. 모바일은 그나마 양반인게  A사이트는 B브라우저에서만 잘 작동하고,  C사이트는 D브라우저에서 딱 맞춰 보이는 증상이 덜하다. 하지만 모바일에서만 쓰느냐?  패드나 구형PC등도  시스템에 맞춰서 브라우저를 설치해서 사용한다.  HWP를 많이 쓰면 웨일을 쓰기도 하고, 우수한 플러그인의 압도적인 양을 생각하면 크롬을, 크롬의 램 먹는 하마가 꼴보기 싫으면 엣지를 모바일과 데스크탑 패드등의 핸드오프의 편리함을 위해서는 사파리를 선택하는 식이지 모두 친절하게도 한번 로그인한 사이트의 아이디와 비밀번호를 안전하게 보관했다가 다음 접속에는 자동으로 입력 해 준다.

    그런데 이게 각 회사들에게는 사용자사 해당 시스템에 귀속되어버리는 락인(LOCK-IN)이 되어 너무 불편해져버리는 단점이 되버렸다.

    엣지나 크롬, 사파리나 삼성브라우저등등 PC와 모바일등에서이름만 같고 사용처가 다르다보니 모바일에서는 지문으로 입력되는 비밀번호가 PC에서는 크롬아니면 비밀번호가 저장이 되어있지 않고, 삼성브라우저에는 기억되어있는 패스워드가 사파리엔 없고 그렇다고 브라우저를 하나만 쓰자니 되는것도 있고 아닌것도 있고 어느날엔가 너무 화딱지가 나서 이런생각까지 들게됬다.

    패스워드를 내가 다 기억하고있으면 패스워드가 저장된 브라우저 골라쓰느라 똑같은 사이트를 몇번씩 들락 거리지 않아도 되잖아!

    물론 내 머리는 저걸 다 기억할리 없으니 패스워드 저장과 자동입력하는것을 내가 관리한다면 그래서 브라우저가 달라도 플랫폼이 달라도 아무문제가 없겠다 생각이 들었다.(깨닫는게 이렇게 오래 걸릴일도 아닌데 말이지..) 심지어 나는 패스워드를 메모앱에 아무런 보안대책없이 적어뒀으니 이걸 이제 생각해낸 내가 여러모로 답답했다.

    일단 내가 가진 패스워드들은 저 세가지다

    • 크롬
    • 삼성패스
    • 메모에 적어둔 것들

    모두 vaultwarden으로 하나씩 옮겨야했다.

    먼저 가장 자주 사용하는 모바일에서는 삼성패스에 거의 모든 비밀번호가 생성되어있는데 이것부터 옮기기로 했다. 이녀석은 캡쳐도 안돼네

    삼성월렛 -> 설정(점세개) -> 삼성 패스 데이터 가져오기 및 내보내기

    데이터가져오기

    폰에 데이터 내보내기

    ID 및 비밀번호

    비밀번호를 체크하면 내 폰안에 .spass 파일로 저장이 되는데 꼭 비밀번호를 설정해야한다.

    이제 이 파일의 비밀번호를 없애고 Vaultwarden에 불러오기로 옮겨야하는데 비밀번호를 바꾸는데는 두가지 방법이 있다.

    • 폰내에서 파이썬 스크립트로 하기
    • 클라이언트 사이드 변환기를 사용 – 브라우저에 파일을 올려서 github등의 오픈소스 해독사이트를쓰는건데 불안해서 안했다.

    폰으로 받은 삼성패스 .spass파일을 폰에서 해독하는것도 뭐 결국 온라인에서 프로그램을 받아야하지만 이 방법으로 하기로했고 마침(?) 핸드폰에 Termux가 설치 되어있어서 아래의 순서로 따라하면 비밀번호를 해제한 파일을 얻을 수 있었다.

    Termux-setup-storage  # Termux프로그램이 파일에 접근할 권한 부여

    # 파이썬 및 변환기 프로그램 다운로드
    pkg install python python-cryptography git -y
    git clone https://github.com/NHClaessens/samsung_pass_converter.git

    #프로그램 폴더로 이동 및 파일가져오기
    cd samsung_pass_converter
    cp ~/storage/download/내보내기한 파일명.spass ./

    # 암호 해독 “내비밀번호” 부분은 필히 본인이 정한 비밀번호 넣기
    python convert.py ./2026_07_29_13_41_51_spass_export_data.spass “내비밀번호”

    #Download폴더로 CSV파일 이동
    cp ./*.csv ~/storage/downloads/

    이제 Vaultwarden에서 삼성패스의 비밀번호를 불러오기할 모든 준비가 끝났다.

    파일 선택을 누르고 핸드폰의 Download의 csv파일을 첨부하면 끝이다. 생각보다 너무 쉽다.

    핸드폰과 PC에 클라이언트인 Bitwaden을 설치하고 자체호스팅된 Vaultwarden의 주소를 적어주면 해당시스템에서 구글에 저장된 비밀번호나 삼성월렛에 저장된 비밀번호대신 Vaultwarden에 옮겨진 내 관리하의 패스워드로 로그인이 된다.

    크롬에서라면 확장프로그램 Bitwarden을 설치하고 툴바에 고정을 선택해주면 편하다.

    크롬의 비밀번호 관리자는 저장을 해제하고 비밀번호 내보내기로 Vaultwarden에서 읽어들일 패스워드 목록을 받을수 있다.
    자체호스팅으로 변경
    내 Vaultwarden의 주소와 패스워드를 적으면 끝

    끝으로 메모장에 적어두던 파일은 Bitwarden의 보안 메모에 옮겨뒀다. 과정에서 생성한 CSV파일들을 꼭 지우는걸 잊지말자.

  • Proxmox NPM LXC에서 Tailscale가 죽었을 때 (실제 장애 복구 기록)

    환경 요약

    • Proxmox VE 8.x (Kernel 6.8.x)
    • Nginx Proxy Manager LXC 컨테이너 (Debian 12)
    • Tailscale 사용 (외부 접근/관리)

    1. 장애 발생 상황

    📸 첨부 이미지 1: Proxmox Summary 화면 (CPU/RAM 정상인데 체감 속도 저하)

    어느 날 NPM VM(LXC)을 재부팅한 이후부터 이상 증상이 시작됐다.

    • NPM 웹 페이지 로딩이 극단적으로 느림
      • Proxmox 에서 해당 컨테이너로의 콘솔 접속 자체가 늦거나 끊김
      • Tailnet에서 NPM 노드가 보이지 않음
    • 하지만 Proxmox Summary에서는 CPU / RAM 사용률 정상

    처음엔 디스크 I/O 문제를 의심했지만, sync 명령이 즉시 반환되어 스토리지 병목은 아닌 것으로 판단했다.


    2. Tailscale 상태 확인

    📸 첨부 이미지 2: tailscale status 실행 시 오류 화면

    NPM LXC 안에서 확인한 결과:systemctl status tailscaled

    결과는 명확했다.Active: failed (Result: exit-code)

    즉, tailscaled 데몬 자체가 기동 실패 상태였다.


    3. 결정적 로그 (원인 확정)

    journalctl -u tailscaled 로그
    root@nginxproxymanager:~# journalctl -u tailscaled -b –no-pager | tail -n 120
    Dec 29 16:23:22 nginxproxymanager systemd[1]: tailscaled.service: Main process exited, code=exited, status=1/FAILURE
    Dec 29 16:23:22 nginxproxymanager tailscaled[415]: TPM: error opening: stat /dev/tpmrm0: no such file or directory
    Dec 29 16:23:22 nginxproxymanager tailscaled[415]: logtail started
    Dec 29 16:23:22 nginxproxymanager tailscaled[415]: Program starting: v1.92.3-ta17f36b9b-ga4dc88aac, Go 1.25.5: []string{“/usr/sbin/tailscaled”, “–cleanup”}
    Dec 29 16:23:22 nginxproxymanager tailscaled[415]: LogID: e6162d241fd04f3372e9cde1bb50d0f5f0e122c5e3f85ebd6d01c6033a2cb41c
    Dec 29 16:23:22 nginxproxymanager tailscaled[415]: logpolicy: using $STATE_DIRECTORY, “/var/lib/tailscale”
    Dec 29 16:23:22 nginxproxymanager tailscaled[415]: dns: [rc=unknown ret=direct]
    Dec 29 16:23:22 nginxproxymanager tailscaled[415]: dns: using “direct” mode
    Dec 29 16:23:22 nginxproxymanager tailscaled[415]: dns: using *dns.directManager
    Dec 29 16:23:22 nginxproxymanager tailscaled[415]: dns: inotify: NewDirWatcher: context canceled
    Dec 29 16:23:22 nginxproxymanager tailscaled[415]: flushing log.
    Dec 29 16:23:22 nginxproxymanager tailscaled[415]: logger closing down
    Dec 29 16:23:23 nginxproxymanager systemd[1]: tailscaled.service: Failed with result ‘exit-code’.
    Dec 29 16:23:23 nginxproxymanager systemd[1]: tailscaled.service: Scheduled restart job, restart counter is at 2.
    Dec 29 16:23:23 nginxproxymanager systemd[1]: Stopped tailscaled.service – Tailscale node agent.
    Dec 29 16:23:23 nginxproxymanager systemd[1]: Starting tailscaled.service – Tailscale node agent…
    Dec 29 16:23:23 nginxproxymanager tailscaled[634]: TPM: error opening: stat /dev/tpmrm0: no such file or directory
    Dec 29 16:23:23 nginxproxymanager tailscaled[634]: logtail started
    Dec 29 16:23:23 nginxproxymanager tailscaled[634]: Program starting: v1.92.3-ta17f36b9b-ga4dc88aac, Go 1.25.5: []string{“/usr/sbin/tailscaled”, “–state=/var/lib/tailscale/tailscaled.state”, “–socket=/run/tailscale/tailscaled.sock”, “–port=41641”}
    Dec 29 16:23:23 nginxproxymanager tailscaled[634]: LogID: e6162d241fd04f3372e9cde1bb50d0f5f0e122c5e3f85ebd6d01c6033a2cb41c
    Dec 29 16:23:23 nginxproxymanager tailscaled[634]: logpolicy: using $STATE_DIRECTORY, “/var/lib/tailscale”
    Dec 29 16:23:23 nginxproxymanager tailscaled[634]: dns: [rc=unknown ret=direct]
    Dec 29 16:23:23 nginxproxymanager tailscaled[634]: dns: using “direct” mode
    Dec 29 16:23:23 nginxproxymanager tailscaled[634]: dns: using *dns.directManager
    Dec 29 16:23:23 nginxproxymanager tailscaled[634]: dns: inotify: NewDirWatcher: context canceled
    Dec 29 16:23:23 nginxproxymanager tailscaled[634]: wgengine.NewUserspaceEngine(tun “tailscale0”) …
    Dec 29 16:23:23 nginxproxymanager systemd[1]: Started tailscaled.service – Tailscale node agent.
    Dec 29 16:23:23 nginxproxymanager tailscaled[634]: Linux kernel version: 6.8.12-5-pve
    Dec 29 16:23:23 nginxproxymanager tailscaled[634]: is CONFIG_TUN enabled in your kernel? modprobe tun failed with: modprobe: FATAL: Module tun not found in directory /lib/modules/6.8.12-5-pve
    Dec 29 16:23:23 nginxproxymanager tailscaled[634]: tun module not loaded nor found on disk
    Dec 29 16:23:23 nginxproxymanager tailscaled[634]: wgengine.NewUserspaceEngine(tun “tailscale0”) error: tstun.New(“tailscale0”): CreateTUN(“tailscale0”) failed; /dev/net/tun does not exist
    Dec 29 16:23:23 nginxproxymanager tailscaled[634]: flushing log.
    Dec 29 16:23:23 nginxproxymanager tailscaled[634]: logger closing down
    Dec 29 16:23:24 nginxproxymanager tailscaled[634]: getLocalBackend error: createEngine: tstun.New(“tailscale0”): CreateTUN(“tailscale0”) failed; /dev/net/tun does not exist
    Dec 29 16:23:24 nginxproxymanager systemd[1]: tailscaled.service: Main process exited, code=exited, status=1/FAILURE
    Dec 29 16:23:24 nginxproxymanager tailscaled[665]: TPM: error opening: stat /dev/tpmrm0: no such file or directory
    Dec 29 16:23:24 nginxproxymanager tailscaled[665]: logtail started
    Dec 29 16:23:24 nginxproxymanager tailscaled[665]: Program starting: v1.92.3-ta17f36b9b-ga4dc88aac, Go 1.25.5: []string{“/usr/sbin/tailscaled”, “–cleanup”}
    Dec 29 16:23:24 nginxproxymanager tailscaled[665]: LogID: e6162d241fd04f3372e9cde1bb50d0f5f0e122c5e3f85ebd6d01c6033a2cb41c
    Dec 29 16:23:24 nginxproxymanager tailscaled[665]: logpolicy: using $STATE_DIRECTORY, “/var/lib/tailscale”
    Dec 29 16:23:24 nginxproxymanager tailscaled[665]: dns: [rc=unknown ret=direct]
    Dec 29 16:23:24 nginxproxymanager tailscaled[665]: dns: using “direct” mode
    Dec 29 16:23:24 nginxproxymanager tailscaled[665]: dns: using *dns.directManager
    Dec 29 16:23:24 nginxproxymanager tailscaled[665]: dns: inotify: NewDirWatcher: context canceled
    Dec 29 16:23:24 nginxproxymanager tailscaled[665]: flushing log.
    Dec 29 16:23:24 nginxproxymanager tailscaled[665]: logger closing down
    Dec 29 16:23:24 nginxproxymanager systemd[1]: tailscaled.service: Failed with result ‘exit-code’.
    Dec 29 16:23:24 nginxproxymanager systemd[1]: tailscaled.service: Scheduled restart job, restart counter is at 3.
    Dec 29 16:23:24 nginxproxymanager systemd[1]: Stopped tailscaled.service – Tailscale node agent.
    Dec 29 16:23:24 nginxproxymanager systemd[1]: Starting tailscaled.service – Tailscale node agent…
    Dec 29 16:23:24 nginxproxymanager tailscaled[691]: TPM: error opening: stat /dev/tpmrm0: no such file or directory
    Dec 29 16:23:24 nginxproxymanager tailscaled[691]: logtail started
    Dec 29 16:23:24 nginxproxymanager tailscaled[691]: Program starting: v1.92.3-ta17f36b9b-ga4dc88aac, Go 1.25.5: []string{“/usr/sbin/tailscaled”, “–state=/var/lib/tailscale/tailscaled.state”, “–socket=/run/tailscale/tailscaled.sock”, “–port=41641”}
    Dec 29 16:23:24 nginxproxymanager tailscaled[691]: LogID: e6162d241fd04f3372e9cde1bb50d0f5f0e122c5e3f85ebd6d01c6033a2cb41c
    Dec 29 16:23:24 nginxproxymanager tailscaled[691]: logpolicy: using $STATE_DIRECTORY, “/var/lib/tailscale”
    Dec 29 16:23:24 nginxproxymanager tailscaled[691]: dns: [rc=unknown ret=direct]
    Dec 29 16:23:24 nginxproxymanager tailscaled[691]: dns: using “direct” mode
    Dec 29 16:23:24 nginxproxymanager tailscaled[691]: dns: using *dns.directManager
    Dec 29 16:23:24 nginxproxymanager tailscaled[691]: dns: inotify: NewDirWatcher: context canceled
    Dec 29 16:23:25 nginxproxymanager tailscaled[691]: wgengine.NewUserspaceEngine(tun “tailscale0”) …
    Dec 29 16:23:25 nginxproxymanager systemd[1]: Started tailscaled.service – Tailscale node agent.
    Dec 29 16:23:25 nginxproxymanager tailscaled[691]: Linux kernel version: 6.8.12-5-pve
    Dec 29 16:23:25 nginxproxymanager tailscaled[691]: is CONFIG_TUN enabled in your kernel? modprobe tun failed with: modprobe: FATAL: Module tun not found in directory /lib/modules/6.8.12-5-pve
    Dec 29 16:23:25 nginxproxymanager tailscaled[691]: tun module not loaded nor found on disk
    Dec 29 16:23:25 nginxproxymanager tailscaled[691]: wgengine.NewUserspaceEngine(tun “tailscale0”) error: tstun.New(“tailscale0”): CreateTUN(“tailscale0”) failed; /dev/net/tun does not exist
    Dec 29 16:23:25 nginxproxymanager tailscaled[691]: flushing log.
    Dec 29 16:23:25 nginxproxymanager tailscaled[691]: logger closing down
    Dec 29 16:23:25 nginxproxymanager tailscaled[691]: getLocalBackend error: createEngine: tstun.New(“tailscale0”): CreateTUN(“tailscale0”) failed; /dev/net/tun does not exist
    Dec 29 16:23:25 nginxproxymanager systemd[1]: tailscaled.service: Main process exited, code=exited, status=1/FAILURE
    Dec 29 16:23:25 nginxproxymanager tailscaled[722]: TPM: error opening: stat /dev/tpmrm0: no such file or directory
    Dec 29 16:23:25 nginxproxymanager tailscaled[722]: logtail started
    Dec 29 16:23:25 nginxproxymanager tailscaled[722]: Program starting: v1.92.3-ta17f36b9b-ga4dc88aac, Go 1.25.5: []string{“/usr/sbin/tailscaled”, “–cleanup”}
    Dec 29 16:23:25 nginxproxymanager tailscaled[722]: LogID: e6162d241fd04f3372e9cde1bb50d0f5f0e122c5e3f85ebd6d01c6033a2cb41c
    Dec 29 16:23:25 nginxproxymanager tailscaled[722]: logpolicy: using $STATE_DIRECTORY, “/var/lib/tailscale”
    Dec 29 16:23:25 nginxproxymanager tailscaled[722]: dns: [rc=unknown ret=direct]
    Dec 29 16:23:25 nginxproxymanager tailscaled[722]: dns: using “direct” mode
    Dec 29 16:23:25 nginxproxymanager tailscaled[722]: dns: using *dns.directManager
    Dec 29 16:23:25 nginxproxymanager tailscaled[722]: dns: inotify: NewDirWatcher: context canceled
    Dec 29 16:23:25 nginxproxymanager tailscaled[722]: flushing log.
    Dec 29 16:23:25 nginxproxymanager tailscaled[722]: logger closing down
    Dec 29 16:23:26 nginxproxymanager systemd[1]: tailscaled.service: Failed with result ‘exit-code’.
    Dec 29 16:23:26 nginxproxymanager systemd[1]: tailscaled.service: Scheduled restart job, restart counter is at 4.
    Dec 29 16:23:26 nginxproxymanager systemd[1]: Stopped tailscaled.service – Tailscale node agent.
    Dec 29 16:23:26 nginxproxymanager systemd[1]: Starting tailscaled.service – Tailscale node agent…
    Dec 29 16:23:26 nginxproxymanager tailscaled[748]: TPM: error opening: stat /dev/tpmrm0: no such file or directory
    Dec 29 16:23:26 nginxproxymanager tailscaled[748]: logtail started
    Dec 29 16:23:26 nginxproxymanager tailscaled[748]: Program starting: v1.92.3-ta17f36b9b-ga4dc88aac, Go 1.25.5: []string{“/usr/sbin/tailscaled”, “–state=/var/lib/tailscale/tailscaled.state”, “–socket=/run/tailscale/tailscaled.sock”, “–port=41641”}
    Dec 29 16:23:26 nginxproxymanager tailscaled[748]: LogID: e6162d241fd04f3372e9cde1bb50d0f5f0e122c5e3f85ebd6d01c6033a2cb41c
    Dec 29 16:23:26 nginxproxymanager tailscaled[748]: logpolicy: using $STATE_DIRECTORY, “/var/lib/tailscale”
    Dec 29 16:23:26 nginxproxymanager tailscaled[748]: dns: [rc=unknown ret=direct]
    Dec 29 16:23:26 nginxproxymanager tailscaled[748]: dns: using “direct” mode
    Dec 29 16:23:26 nginxproxymanager tailscaled[748]: dns: using *dns.directManager
    Dec 29 16:23:26 nginxproxymanager tailscaled[748]: dns: inotify: NewDirWatcher: context canceled
    Dec 29 16:23:26 nginxproxymanager tailscaled[748]: wgengine.NewUserspaceEngine(tun “tailscale0”) …
    Dec 29 16:23:26 nginxproxymanager systemd[1]: Started tailscaled.service – Tailscale node agent.
    Dec 29 16:23:26 nginxproxymanager tailscaled[748]: Linux kernel version: 6.8.12-5-pve
    Dec 29 16:23:26 nginxproxymanager tailscaled[748]: is CONFIG_TUN enabled in your kernel? modprobe tun failed with: modprobe: FATAL: Module tun not found in directory /lib/modules/6.8.12-5-pve
    Dec 29 16:23:26 nginxproxymanager tailscaled[748]: tun module not loaded nor found on disk
    Dec 29 16:23:26 nginxproxymanager tailscaled[748]: wgengine.NewUserspaceEngine(tun “tailscale0”) error: tstun.New(“tailscale0”): CreateTUN(“tailscale0”) failed; /dev/net/tun does not exist
    Dec 29 16:23:26 nginxproxymanager tailscaled[748]: flushing log.
    Dec 29 16:23:26 nginxproxymanager tailscaled[748]: logger closing down
    Dec 29 16:23:27 nginxproxymanager tailscaled[748]: getLocalBackend error: createEngine: tstun.New(“tailscale0”): CreateTUN(“tailscale0”) failed; /dev/net/tun does not exist
    Dec 29 16:23:27 nginxproxymanager systemd[1]: tailscaled.service: Main process exited, code=exited, status=1/FAILURE
    Dec 29 16:23:27 nginxproxymanager tailscaled[779]: TPM: error opening: stat /dev/tpmrm0: no such file or directory
    Dec 29 16:23:27 nginxproxymanager tailscaled[779]: logtail started
    Dec 29 16:23:27 nginxproxymanager tailscaled[779]: Program starting: v1.92.3-ta17f36b9b-ga4dc88aac, Go 1.25.5: []string{“/usr/sbin/tailscaled”, “–cleanup”}
    Dec 29 16:23:27 nginxproxymanager tailscaled[779]: LogID: e6162d241fd04f3372e9cde1bb50d0f5f0e122c5e3f85ebd6d01c6033a2cb41c
    Dec 29 16:23:27 nginxproxymanager tailscaled[779]: logpolicy: using $STATE_DIRECTORY, “/var/lib/tailscale”
    Dec 29 16:23:27 nginxproxymanager tailscaled[779]: dns: [rc=unknown ret=direct]
    Dec 29 16:23:27 nginxproxymanager tailscaled[779]: dns: using “direct” mode
    Dec 29 16:23:27 nginxproxymanager tailscaled[779]: dns: using *dns.directManager
    Dec 29 16:23:27 nginxproxymanager tailscaled[779]: dns: inotify: NewDirWatcher: context canceled
    Dec 29 16:23:27 nginxproxymanager tailscaled[779]: flushing log.
    Dec 29 16:23:27 nginxproxymanager tailscaled[779]: logger closing down
    Dec 29 16:23:27 nginxproxymanager systemd[1]: tailscaled.service: Failed with result ‘exit-code’.
    Dec 29 16:23:28 nginxproxymanager systemd[1]: tailscaled.service: Scheduled restart job, restart counter is at 5.
    Dec 29 16:23:28 nginxproxymanager systemd[1]: Stopped tailscaled.service – Tailscale node agent.
    Dec 29 16:23:28 nginxproxymanager systemd[1]: tailscaled.service: Start request repeated too quickly.
    Dec 29 16:23:28 nginxproxymanager systemd[1]: tailscaled.service: Failed with result ‘exit-code’.
    Dec 29 16:23:28 nginxproxymanager systemd[1]: Failed to start tailscaled.service – Tailscale node agent.

    journalctl -u tailscaled -b --no-pager

    핵심 로그:CreateTUN("tailscale0") failed; /dev/net/tun does not exist modprobe: FATAL: Module tun not found

    여기서 원인을 찾을 수 있었다.

    이 NPM은 LXC 컨테이너이고, /dev/net/tun 이 패스스루되지 않은 상태

    컨테이너 안에서 modprobe tun 이 실패하는 건 정상이다.
    LXC에서는 Host가 가진 TUN 디바이스를 직접 마운트해줘야 한다.


    4. Proxmox Host에서 해결 조치

    (1) LXC 설정 파일 수정

    nano /etc/pve/lxc/<CTID>.conf

    아래 항목 추가:lxc.cgroup2.devices.allow: c 10:200 rwm lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file 0 0 features: keyctl=1,nesting=1

    (2) 컨테이너 재시작

    pct restart <CTID>


    5. 컨테이너 내부에서 최종 확인

    ls -l /dev/net/tun systemctl reset-failed tailscaled systemctl start tailscaled tailscale status

    정상 출력 예시:100.97.x.x nginxproxymanager linux 100.115.x.x proxmox linux ...

    Tailnet 정상 복구 완료


    6. 왜 NPM만 유독 느렸을까?

    Nginx Proxy Manager는:

    • HTTPS 인증서 갱신
    • 외부 API 통신
    • Reverse Proxy 트래픽

    모두 외부 네트워크 의존도가 높다.

    Tailscale이 죽은 상태에서:

    • 외부 접근 경로가 지연
    • DNS/네트워크 타임아웃 누적

    → 체감 성능이 급격히 나빠진 것처럼 보인 것뿐이었다.


    7. 정리

    • Proxmox 자원 그래프는 항상 진실을 말하지 않는다
    • LXC에서 Tailscale을 쓸 경우
      • /dev/net/tun 패스스루는 필수
    • 재부팅 후 발생한 서비스 장애는
      • 로그 한 줄로 확정 원인까지 갈 수 있다

    다음에 같은 증상이 나오면

    1. systemctl status tailscaled
    2. journalctl -u tailscaled -b
    3. /dev/net/tun 존재 여부 확인
  • I2. 설치 후 웹 UI 접속 안 되던 날

    설치는 분명히 끝났다.
    오히려 너무 깔끔하게 끝나서 의심조차 하지 않았다.

    문제는 재부팅 이후였다.


    설치 완료 메시지, 그리고 처음 본 주소

    Proxmox 다운로드 페이지

    설치가 끝나자 이런 문구가 나왔다.

    You can now connect to the Proxmox VE web interface:
    https://xxx.xxx.xxx.xxx:8006

    이 문장을 보는 순간,
    **“이제 끝났다”**고 생각했다.

    IP도 나와 있고
    웹 UI 주소까지 친절하게 알려준다.
    딱히 의심할 이유가 없었다.


    주소를 쳤는데… 아무것도 안 열린다

    Tailscale로 접속시도
    Image

    다른 PC에서 브라우저를 열고
    안내된 주소를 그대로 입력했다.

    • 페이지가 열리지 않는다
    • 연결할 수 없다는 메시지만 반복된다
    • 로딩조차 없다

    이때까지만 해도
    설치 실패라고는 생각하지 않았다.

    “뭔가 하나를 더 해야 하나?”
    그 정도의 막연한 불안이었다.


    IP는 있는데, 왜 접속이 안 될까

    여기서 가장 헷갈렸던 지점이 이거다.

    • IP 주소는 설치 화면에 분명히 표시됨
    • 네트워크 케이블도 연결됨
    • 그런데 웹 UI는 열리지 않음

    이 상황은
    네트워크가 안 된 건지,
    웹 서비스가 안 뜬 건지조차 구분이 안 됐다.


    포트라는 개념을 그제야 인식했다

    문제는 단순했다.
    하지만 그때는 단순하지 않았다.

    Proxmox 웹 UI는

    • HTTP 80
    • HTTPS 443

    이 아니라
    👉 HTTPS 8006 포트를 쓴다.

    IP만 치면 안 되고,
    :8006까지 정확히 입력해야 했다.

    이걸 알기 전까지
    나는 계속 “IP는 맞는데 왜 안 되지?”만 반복했다.


    방화벽도, 장애도 아니었다

    이 문제에서 더 헷갈렸던 이유는 이거다.

    • 서버가 꺼진 것도 아니고
    • 네트워크 케이블이 빠진 것도 아니고
    • 오류 메시지도 친절하지 않다

    단지 접속 포트를 몰랐을 뿐인데,
    상황은 완전한 먹통처럼 보였다.


    이 날의 결론

    • Proxmox 설치는 끝났었다
    • 서버도 정상적으로 켜져 있었다
    • 문제는 웹 UI 접근 방식이었다

    그리고 이 경험 덕분에
    처음으로 명확히 인식하게 됐다.

    “서버는 켜졌다고 끝이 아니다.
    어디로, 어떻게 접근하는지를 알아야 한다.


    이 삽질이 남긴 흔적

    이 사건 이후로는

    • IP 주소를 보면 포트부터 확인하게 됐고
    • “접속 안 됨”이라는 말 앞에
      네트워크 / 포트 / 서비스 상태를 나눠서 생각하게 됐다

    기술적으로 대단한 문제는 아니었다. 초보가 너무 몰랐던게 문제였지.

    하지만
    홈서버를 처음 다루는 입장에서는 충분히 하루를 날릴 수 있는 문제였다.

    현재는 Proxmox 9.1이 다운로드 되지만, 작년에 설치한버젼은 8.4였다. 오랫만에 설치페이지에 다시 들어오니 Mail Gateway, Backup Sever, Datacenter Manager 등이 보이는데 신기하고 호기심도 생기고, 머리아프다.

  • I1. Proxmox 첫 설치 – 시작부터 삐끗했던 이유

    홈서버를 처음 꾸리기로 했을 때,
    머릿속에 떠오른 그림은 단순했다.

    하나의 물리 서버

    그 위에 여러 서비스

    웹으로 관리하는 구조

    그래서 자연스럽게 하이퍼바이저부터 찾기 시작했다.

    처음엔 ESXi였다

    사실 Proxmox가 첫 선택은 아니었다.
    VMware ESXi가 먼저 떠올랐다.

    자료가 많고

    기업 환경에서 검증됐고

    “서버 가상화”라고 하면 가장 먼저 나오는 이름

    개인 홈서버라도,
    검증된 선택을 하고 싶었다.

    Broadcom 이후, 상황이 달라졌다

    문제는 그 다음이었다.

    VMware가 Broadcom에 인수된 이후,
    ESXi를 둘러싼 환경이 완전히 바뀌었다.

    무료 ESXi 배포 중단

    기존 다운로드 링크 다수 폐쇄

    개인 사용자 기준으로 지금 당장 합법적으로 쓸 수 있는 경로가 사라짐

    블로그 글은 많았다.
    하지만 대부분 이런 식이었다.

    “예전에 이렇게 설치했다”

    “이 링크에서 받으면 된다” → 이미 막힘

    “계정 만들면 된다” → 더 이상 무료 아님

    그때 깨달았다.

    > 과거에 가능했던 것과, 지금 가능한 건 다르다.

    지금 시점에서 실제로 내려받을 수 있고,
    문제 없이 쓸 수 있는 것이어야 했다.

    그래서 Proxmox였다

    Proxmox는 완벽해서 선택한 게 아니었다.

    공식 사이트에서 바로 내려받을 수 있고

    라이선스 꼬임 없이

    개인 환경에서도

    실제 운영이 가능한 하이퍼바이저

    “지금 가용한 선택지”라는 점이 가장 컸다.

    그래서 Proxmox를 설치하기로 했다.

    설치 자체는 생각보다 간단했다

    USB를 만들어 부팅하고,
    설치 화면을 따라가니 큰 문제는 없었다.

    디스크 선택

    지역 / 키보드

    관리자 비밀번호

    네트워크 설정

    여기까지는 정말 순조로웠다.

    문제는, 이 다음을 아무도 알려주지 않았다는 것이다.

    네트워크 설정, 경고가 없던 선택

    설치 중 네트워크 설정 화면이 나온다.

    DHCP (자동)

    수동 설정

    DHCP가 뭔지는 알고 있었다.
    공유기 환경에서 IP를 자동으로 받아오는 방식이라는 것도 알고 있었다.

    그래서 DHCP를 선택했다.

    IP Address : 자동
    Gateway : 자동
    DNS : 자동

    이 선택이 위험하다는 경고는 없었다.
    이 설정이 설치 이후 웹 UI 접근 방식과 직결된다는 설명도 없었다.

    문제는 몰라서가 아니라, 어디서 조심해야 하는지 몰랐다는 것이다.

    설치 완료, 그리고 착각

    설치가 끝나고 재부팅되자 콘솔에 문구 하나가 찍혔다.

    You can now connect to the Proxmox VE web interface:
    https://xxx.xxx.xxx.xxx:8006/

    그 순간엔 정말 끝난 줄 알았다.

    “이제 웹으로 접속하면 되겠네.”

    IP도 보이고, https 주소도 있다.
    문제 없어 보였다.

    웹 UI는 열리지 않았다

    브라우저에 주소를 입력했다.

    https://xxx.xxx.xxx.xxx

    결과는 단순했다.

    접속 불가

    타임아웃

    아무 반응 없음

    주소를 다시 확인했다.
    다른 기기에서도 시도했다.

    그래도 안 됐다.

    문제는 네트워크가 아니라, 포트였다

    지금 와서 보면 원인은 명확하다.

    Proxmox 웹 UI는 기본 포트가 8006이다.
    443도 아니고, 80도 아니다.
    포트를 명시하지 않으면 접속 자체가 안 된다.

    하지만 설치 과정에서는:

    “웹 UI는 8006 포트만 사용한다”는 경고도

    “이 포트를 놓치면 접속 안 된다”는 안내도

    일반 https와 다르다는 설명도

    아무것도 없었다.

    콘솔에 출력된 문구는
    중요한 힌트라기보다, 그냥 안내 문장처럼 보였다.

    그래서 문제를 잘못 짚었다

    포트를 빼먹은 상태에서 접속을 시도하니,
    자연스럽게 문제를 이렇게 오해했다.

    DHCP 설정이 잘못된 걸까?

    IP가 이상한 걸까?

    네트워크가 아예 안 붙은 걸까?

    이때부터
    “설치는 끝났는데 웹 UI가 안 열린다”는 문제가 시작됐다.

    이 첫 설치에서 얻은 교훈

    이 글은 성공담이 아니다.
    출발선에서의 기록이다.

    서버 OS는 “설치된다”와 “쓸 수 있다”가 전혀 다르다

    아는 개념과, 실제로 조심해야 할 지점은 다르다

    무엇보다도 지금 가용한 기술인지 확인하지 않으면 시작부터 틀어진다

    그래서 Proxmox를 선택했다.

    ESXi가 나빠서가 아니라,
    지금 이 시점에 선택할 수 없었기 때문이다.

    다음 이야기

    다음 글에서는
    이 설치 과정에서 가장 시간을 잡아먹었던 문제,

    UEFI / Secure Boot 삽질을 정리한다.

    왜 설치를 여러 번 다시 해야 했는지,
    그 이유를 기록으로 남긴다.

  • H4. 미니PC에 서버를 올릴 때, 내가 조심하게 된 이유들


    미니PC로 서버를 꾸리고 나서 한동안은 정말 별문제 없었다.
    설치도 잘 끝났고, 서비스도 정상적으로 돌아갔다.
    CPU 사용률도 낮았고, 메모리도 여유 있었고, 로그에도 이상은 없었다.

    그런데 이상하게 마음이 편하지 않았다.
    문제가 터진 건 아닌데,
    언제 한 번은 이유 없이 멈출 것 같은 느낌이 계속 들었다.

    이 글은 “문제가 생겼다”의 기록이 아니라,
    왜 그런 불안이 생겼고, 그걸 어떻게 이해하게 됐는지에 대한 정리다.


    1) CPU는 멀쩡한데, 왜 전체가 멍해질까

    처음엔 당연히 CPU를 의심했다.
    N100 미니PC에 Proxmox, VM 여러 개, DSM까지 올려놨으니
    “이건 분명 과부하겠지”라는 생각이 먼저 들었다.

    그래서 가장 먼저 본 게 CPU 사용률이었다.
    그런데 이상하게도, 늘 여유 있었다.

    서비스가 느릴 때도
    웹이 굼뜰 때도
    DSM 반응이 늦을 때도
    CPU는 태평했다.

    그때 처음으로 이런 생각이 들었다.

    “이건 힘이 부족해서가 아니라,
    어딘가를 기다리느라 멈춰 있는 상태 아닐까?

    그 이후부터 시스템을 볼 때
    CPU보다 디스크 반응과 체감 지연을 더 보게 됐다.
    그리고 미니PC 환경에서는
    성능 부족보다 ‘대기’가 먼저 문제로 나타난다는 걸 체감하게 됐다.


    2) 스토리지를 늘렸는데, 왜 마음은 더 바빠졌을까

    저장 공간을 늘리면 당연히 안정될 줄 알았다.
    공간 여유는 곧 마음의 여유라고 믿었다.

    하지만 외장 스토리지를 붙인 뒤부터
    오히려 서버 상태를 더 자주 확인하게 됐다.

    • 지금도 잘 붙어 있나
    • 재부팅하면 바로 인식될까
    • 이 상태가 정상인 게 맞나

    문제는 대부분 항상 발생하지 않았다는 점이다.
    아주 가끔, 한 번씩만 이상했다.
    그래서 더 신경이 쓰였다.

    그때 깨달았다.

    외장 스토리지는
    단순히 용량을 늘려주는 장치가 아니라,
    운영자가 관리해야 할 조건을 하나 더 추가하는 선택이라는 걸.


    3) 문제는 발열이 아니라, ‘전원이 들어오는 방식’이었다

    한동안 시스템이 애매하게 불안정하다고 느낀 적이 있었다.
    완전히 꺼지지는 않는데,
    가끔 설명하기 어려운 멈춤이나 반응 지연이 나타났다.

    처음엔 발열을 의심했다.
    미니PC는 작고 조용하다 보니,
    열이 쌓이고 있는 걸 내가 과소평가한 게 아닐까 싶었다.

    그런데 온도가 특별히 높지 않은 상황에서도
    비슷한 증상이 반복됐다.
    그제서야 방향이 조금씩 어긋나고 있다는 걸 느꼈다.

    나중에 알고 보니 문제는 발열이 아니었다.
    이 미니PC는 PD 전원 입력과 어댑터 전원 입력을 모두 지원하는 구조였고,
    중고로 들인 기기라 PD 전원부가 이미 정상적으로 동작하지 않는 상태였다.

    전원이 아예 안 들어오는 게 아니라,
    “들어오긴 하는데 안정적이지 않은 상태”였다.

    그걸 처음엔 몰랐다.
    그래서 성능 문제나 I/O 문제로 착각했고,
    한참을 돌아가고 나서야 원인을 이해하게 됐다.

    이 경험을 통해 분명히 알게 된 게 있다.

    미니PC에서는
    전원이 들어온다는 사실보다
    어떤 경로로, 얼마나 안정적으로 들어오는지가 더 중요하다

    작은 시스템일수록
    전원부 하나의 이상이
    전체 불안정으로 확대될 수 있다는 걸 몸으로 알게 됐다.


    4) 서버는 멀쩡한데, 서비스가 죽어 있었다

    한동안 가장 헷갈렸던 경험이 있다.
    서비스가 안 된다는 이야기를 들었는데,
    정작 서버에 들어가 보면 멀쩡한 상태였다.

    CPU도 정상, 디스크도 정상, VM도 살아 있었다.

    나중에 알고 보니 문제는 서버가 아니었다.
    당시 사용하던 ipTIME 공유기가
    전원 어댑터 불량으로 혼자서 죽는 경우가 있었다.
    (알고 보니 꽤 유명한 고질병이었다.)

    문제는 이게 아주 조용히 일어났다는 점이다.

    • 서버는 계속 돌아가고 있었고
    • 나는 아무것도 모르고 있었고
    • 아이들이 “와이파이 안 돼”라고 말해줄 때마다
      공유기를 껐다 켰다

    그 과정에서
    DDNS도 잠시 iptime.org에서 tplinkdns.com으로 바뀌었다.

    이 경험을 통해 확실히 인식하게 됐다.

    “서버가 살아 있다는 것과
    서비스가 정상이라는 건 전혀 다른 문제구나

    미니PC 서버에서 가장 무서운 장애는
    크게 터지는 문제가 아니라,
    조용히 죽어 있는데 아무도 모르는 상태였다.

    (지금 생각해보면,
    그때 아이들이 최고의 모니터링 시스템이었다.)


    5) 네트워크는 ‘되면 끝’이 아니었다

    처음엔 네트워크가 되기만 하면 충분하다고 생각했다.
    실제로 잘 됐고, 그동안은 큰 문제도 없었다.

    하지만 한 번 꼬이고 나니
    “왜 안 되는지”보다
    “어디부터 봐야 하는지”를 모르는 상태가 훨씬 무서웠다.

    그 이후로 네트워크는
    자동 설정에 맡기는 영역이 아니라,
    내가 이해한 만큼만 단순하게 유지해야 하는 영역이 됐다.


    6) 그래서 내린 결론

    이 모든 경험을 거치고 나서 얻은 결론은 단순하다.

    미니PC에 서버를 올릴 때
    조심해야 할 건 사양이 아니라 변수였다.

    • CPU보다 먼저 체감되는 I/O
    • 확장이 곧 안정은 아닌 스토리지 구성
    • 발열이 아니라 전원 경로에서 시작된 불안정
    • 서버보다 먼저 죽을 수 있는 네트워크 장비
    • 그리고 “죽은 줄 모르는 상태”가 가장 위험한 운영 방식

    미니PC 서버는
    성능 싸움이 아니라 운영 감각 싸움이었다.

    솔직히 말하면,
    이 정도까지 고민하게 될 줄은 몰랐다.
    그냥 파일 좀 올려두려던 시작이었으니까.

    하지만 한 가지는 분명하다.
    이 과정을 거치고 나니,
    미니PC는 더 이상 불안한 장난감이 아니라
    내가 이해하고 통제할 수 있는 서버가 됐다.


    reboot system boot 6.8.12-5-pve Thu Feb 20 21:10 – 19:12 (98+22:02) reboot system boot 6.8.12-5-pve Thu Feb 6 14:28 – 19:12 (113+04:44) reboot system boot 6.8.12-5-pve Tue Jan 21 00:07 – 19:12 (129+19:05)

    위 로그는 last reboot으로 본 서버의 연속 가동일이다. 빈약한 하드웨어가 무리될까 멈춰둔거긴 한데 사실 판단의 근거가 없다. 앞으로의 공부와 경험이 후에 시스템 중단의 판단 기준이 되거나, 보조될 시스템을 구축해야겠지

  • H3. SSD / HDD 구성과 DSM을 고려한 스토리지 판단


    스토리지 구성은 처음부터 가장 신중하게 접근한 영역이었다.
    CPU나 RAM은 부족하면 체감으로 드러나지만, 스토리지는 한 번 구조를 잘못 잡으면 나중에 되돌리기 어렵다. 특히 Proxmox 위에 DSM을 올리는 구조에서는 더 그랬다.

    내부 SSD는 ‘시스템 디스크’로만 쓰기로 했다

    미니PC 내부에는 NVMe SSD 하나만 사용했다.
    용량을 크게 가져가지도 않았다. 처음부터 내부 디스크에 데이터를 쌓을 생각이 없었기 때문이다.

    내부 SSD의 역할은 명확했다.

    • Proxmox OS
    • VM / LXC 디스크
    • 로그와 임시 파일

    이 이상은 맡기지 않았다.
    OS와 데이터가 섞이면, 장애가 날 때 항상 둘 다 위험해진다. 성능 문제가 아니라 구조의 문제였다.

    DSM 이전, Nextcloud를 먼저 써봤다

    DSM을 올리기 전, 잠시 Nextcloud를 직접 구축해서 사용해봤다.
    지금 생각하면 네트워크 초보가 할 선택이었는지는 애매하지만, 당시에는 “직접 서비스 하나쯤은 굴려봐야겠다”는 생각이 더 컸다.

    Nextcloud는 생각보다 많은 걸 요구했다.

    • 웹 서버 설정
    • 인증서 처리
    • 스토리지 경로와 권한
    • 내부망 / 외부망 구분
    • 문제 발생 시 책임 범위

    기능 자체보다 더 어려웠던 건,
    어디까지를 내가 관리해야 하는지 알 수 없다는 점이었다.

    이 경험을 통해 질문이 하나 생겼다.

    NAS란 서버일까,
    아니면 관리 범위가 정해진 가전일까?

    DSM VM은 ‘상용 NAS 체험’에 가까웠다

    그래서 DSM을 Proxmox 위에 VM으로 올렸다.
    목적은 명확했다.

    • 상용 NAS는 어떤 철학으로 운영되는지
    • 사용자가 만져야 할 영역과
    • 만지지 않아야 할 영역이 어디까지인지

    DSM은 틀이 분명했다.
    할 수 있는 건 많지만, 정해진 방식 안에서만 허용된다. Nextcloud에서 느꼈던 불안함과는 다른 종류의 안정감이었다.

    이 시점의 계획은 꽤 정석적이었다.

    • DSM VM으로 충분히 사용해본다
    • 익숙해지면
    • 소형 시놀로지를 하나 추가한다
    • 그 장비를 백업 전용 NAS로 쓴다

    교과서적인 NAS 확장 시나리오였다.

    TerraMaster 외장 스토리지를 선택한 이유

    하지만 1년 가까이 Proxmox와 DSM을 운영하면서 판단이 조금씩 바뀌었다.
    장애를 몇 번 겪고, 복구 과정을 직접 지나오면서 깨달은 건 이것이었다.

    백업의 핵심은
    장비가 아니라 경로와 책임의 분리다.

    그래서 내부 디스크를 늘리는 대신,
    TerraMaster 외장 스토리지를 추가했다.

    이 외장 스토리지는 NAS처럼 모든 걸 떠맡는 장비가 아니다.
    의도적으로 디스크 박스(DAS) 역할에 충실한 제품을 골랐다.

    • Proxmox에서는 직접 접근하지 않고
    • DSM에서만 볼륨으로 사용
    • 데이터 영역을 물리적으로 분리

    확장을 고려하긴 했지만, 목적은 서비스 확장이 아니라 백업 구조 확장이었다.

    백업 경로를 바꾼 결정의 배경

    원래 생각했던 “소형 시놀로지 추가” 계획을 완전히 버린 건 아니다.
    다만 지금 시점에서는 보류했다.

    • 지금 구조를 최소 1년 이상 더 운영해보고
    • 업데이트, 장애, 복구를 충분히 겪은 뒤
    • 그때도 필요하다고 느껴지면 결정해도 늦지 않다고 판단했다

    경험이 쌓이면서,
    지금의 나에게 가장 중요한 건 장비 추가가 아니라
    내가 이해하고 통제할 수 있는 범위 안에서의 안정성이었다.

    이 시점의 결론

    지금의 스토리지 구성은 화려하지 않다.
    성능도, 확장성도 최신 NAS 구성에 비하면 평범하다.

    하지만 1년 동안 실제로 운영해보니 이 구조는 분명했다.

    • 문제가 생기면 원인을 추적할 수 있고
    • 복구 경로가 머릿속에 그려지며
    • “이게 날아가면 끝”이라는 불안에서 벗어날 수 있다

    이 판단은 이론이 아니라 운영 경험에서 나온 결과다.

    다음 글에서는
    이 모든 스토리지와 서비스 구성을 바탕으로
    미니PC에 서버를 올릴 때 반드시 조심해야 할 점들을 정리해보려고 한다.
    (H.4로 이어진다)

  • H2. RAM 16GB 선택 이유와 실제 체감

    미니PC를 주문하기 직전까지 가장 오래 고민했던 부품이 RAM이었다.
    CPU는 이미 N100으로 정해져 있었고, 스토리지는 나중에라도 교체가 가능했지만, RAM만큼은 처음 선택이 거의 끝까지 간다고 봐도 됐다.

    왜 16GB였나

    처음엔 8GB도 후보였다.
    N100이라는 CPU 자체가 고성능은 아니고, “가벼운 홈서버”를 목표로 한다면 8GB면 충분하다는 글도 많았다.
    하지만 나는 Proxmox 위에 여러 VM을 동시에 올릴 계획이었고, 그 구조에서 RAM은 단순한 여유가 아니라 안정성 그 자체에 가깝다.

    • Proxmox 자체가 기본으로 잡아먹는 메모리
    • DSM VM (생각보다 메모리 욕심이 큼)
    • Nginx Proxy Manager
    • 테스트용 리눅스 VM
    • 가끔 켜두는 Windows VM

    이걸 전부 동시에 띄워두는 순간, 8GB는 “돌아가긴 함” 수준일 가능성이 높았다.
    나는 돌아가다 멈추는 서버보다, 항상 여유 있는 서버를 원했다.

    그래서 처음부터 16GB로 갔다.

    실제 사용하면서 느낀 점

    결론부터 말하면, 16GB는 과하지 않았다. 딱 적절했다.

    Proxmox 대시보드를 보면, 평상시 메모리 사용량은 대략 이렇다.

    • Proxmox 호스트: 1~1.5GB
    • DSM VM: 4~6GB (캐시 포함)
    • NPM + 기타 경량 서비스: 1GB 내외
    • 여유 메모리: 항상 4~6GB 이상 남음

    중요한 건 이 남는 메모리 덕분에 아무 일도 안 일어난다는 점이다.
    스왑이 도는 소리도 없고, 갑자기 느려지는 순간도 없다.
    서비스 하나를 더 띄워도 “괜찮을까?”를 먼저 고민하지 않게 된다.

    RAM이 체감에 영향을 주는 순간들

    흥미로운 건, CPU 사용률이 낮은데도 체감이 불안해질 때가 있다는 점이다.
    이럴 때 원인을 보면 대부분 메모리 압박이었다.

    • DSM에서 대용량 파일 복사
    • 동시에 여러 클라이언트가 접속
    • 백그라운드에서 인덱싱이나 썸네일 작업

    이런 작업들은 CPU보다 RAM을 먼저 잡아먹는다.
    16GB에서는 “조용히 지나가는 작업”이었지만,
    만약 8GB였다면 분명히 체감 지연이나 스왑이 발생했을 거라고 느꼈다.

    만약 다시 선택한다면?

    지금 시점에서 다시 선택해도 16GB를 고른다.
    N100이라는 CPU 한계는 명확하지만, RAM은 그 한계를 최대한 늦춰준다.

    다만 한 가지는 분명하다.

    • 16GB는 여유
    • 32GB는 이 급의 미니PC에선 과함

    CPU가 먼저 병목이 되는 구조에서 RAM만 늘리는 건 체감 향상이 거의 없다.
    16GB는 “이 시스템이 할 수 있는 만큼을 안정적으로 하게 해주는 선”이었다.


    정리하자면,
    N100 미니PC + Proxmox 환경에서 RAM 16GB는 사치가 아니라 보험에 가깝다.
    서버를 ‘가끔 만지는 장난감’이 아니라, ‘항상 켜두는 기반’으로 쓰고 싶다면, 이 선택은 충분히 납득 가능한 선택이었다.

  • H1. N100 미니PC로 홈서버가 가능한 이유

    (스펙보다 중요한 것)

    홈서버를 꾸린다고 했을 때, 가장 먼저 떠오르는 질문은 늘 같다.
    “그 사양으로 뭐가 되겠어?”

    내가 선택한 건 인텔 N100 CPU가 들어간 미니PC였다.
    데스크탑 기준으로 보면 저전력, 저성능 축에 속하고, 서버라는 단어와는 거리가 멀어 보이는 물건이다.
    하지만 1년을 굴려본 지금, 결론부터 말하면 이렇다.

    N100은 ‘서버용 CPU’가 아니라 ‘홈서버에 최적화된 CPU’였다.


    서버는 늘 최대 성능을 쓰지 않는다

    홈서버를 실제로 돌려보면, CPU가 풀로드로 달리는 순간은 거의 없다.
    파일 서버, 사진 백업, 간단한 웹 서비스, 리버스 프록시, 노트 서버, 가벼운 미디어 스트리밍.
    이런 작업들은 대부분 짧고 간헐적이다.

    N100의 특징은 바로 여기서 드러난다.

    • 아이들 상태에서는 소비전력이 극히 낮고
    • 요청이 들어올 때만 짧게 클럭을 끌어올리며
    • 다시 조용히 내려간다

    24시간 켜두는 장비에 이보다 더 중요한 특성은 없었다.
    “빠르냐”보다 **“쓸데없이 낭비하지 않느냐”**가 훨씬 중요했다.


    코어 수보다 중요한 건 ‘용도 분리’

    N100은 4코어 4스레드다.
    이 숫자만 놓고 보면 VM 여러 개를 돌리기엔 부족해 보인다.

    하지만 Proxmox 위에서 직접 써보니 체감은 달랐다.

    • 무거운 작업은 애초에 올리지 않고
    • 서비스별로 역할을 명확히 나누고
    • LXC와 VM을 섞어 쓰는 구조로 가져가니

    CPU가 병목이 되는 상황은 거의 나오지 않았다.

    중요한 건 **“얼마나 많은 걸 얹느냐”가 아니라
    “무엇을 얹지 않느냐”**였다.


    소음, 발열, 공간 — 집 안 서버의 현실

    집 안에 두는 서버는 데이터센터 기준으로 판단하면 안 된다.

    • 팬 소음이 크면 실패
    • 발열이 높으면 실패
    • 공간을 많이 차지하면 실패

    N100 미니PC는 이 세 가지를 모두 피했다.

    책장 한 칸, 공유기 옆, 콘센트 하나.
    이 정도 존재감으로 1년을 버텼다는 점은 꽤 결정적이었다.

    서버가 생활 공간을 침범하지 않는 것,
    이게 홈서버에서는 스펙만큼이나 중요한 조건이었다.


    결국 남는 질문 하나

    1년을 쓰고 나니, 처음의 질문은 이렇게 바뀌었다.

    “이 정도면 충분하지 않나?”

    N100으로 대규모 서비스를 돌릴 생각이었다면 당연히 틀린 선택이었을 것이다.
    하지만 내가 원했던 건

    • 내 데이터
    • 내 서비스
    • 내가 관리 가능한 범위

    그 이상도, 이하도 아니었다.

    N100은 그 경계를 정확히 지켜주는 CPU였다.

    다음 글에서는
    왜 RAM을 16GB로 선택했는지,
    그리고 실제로 얼마나 남고 모자랐는지를 정리해보려 한다

  • P1. 홈서버를 시작하기 전 내가 기대했던 것들 (그리고 착각)


    홈서버를 떠올리면 머릿속에 먼저 그려진 건 꽤 그럴듯한 그림이었다.
    한 번 세팅해두면 조용히 돌아가고, 파일은 자동으로 정리되며, 사진과 음악은 언제 어디서든 꺼내 쓸 수 있는 ‘집 안의 작은 데이터센터’.
    클라우드 서비스처럼 매달 비용이 빠져나가지도 않고, 내 데이터는 전부 내가 관리하는 구조.
    기술적으로도, 감정적으로도 꽤 만족스러운 선택처럼 보였다.

    특히 기대했던 건 편의성이었다.
    핸드폰 사진은 자동으로 백업되고, 음악과 영상은 스트리밍 서비스처럼 바로 재생되고,
    가족들도 별다른 설명 없이 “그냥 들어가서 쓰면 되는” 환경.
    ‘서버’라는 단어가 주는 복잡함은 설치 과정에서만 잠깐 감수하면 되는 비용이라고 생각했다.

    하지만 그 기대에는 몇 가지 분명한 착각이 섞여 있었다.

    첫 번째 착각은 **“한 번만 세팅하면 끝”**이라는 믿음이었다.
    현실에서는 그게 시작이었다.
    IP는 바뀌고, 인증서는 만료되고, 업데이트 하나에 서비스가 멈췄다.
    어제까지 잘 되던 것이 오늘 갑자기 안 되는 일도 생각보다 자주 벌어졌다.
    홈서버는 가전이 아니라, 계속 관리해야 하는 운영 대상이었다.

    두 번째 착각은 **“가족도 자연스럽게 쓸 것”**이라는 기대였다.
    구조를 알고 있는 나에게는 불편함이 보이지 않았지만,
    가족에게는 로그인 하나, 경로 하나가 그대로 진입장벽이 되었다.
    결국 ‘내가 편한 서버’와 ‘가족이 쓰는 서비스’는 전혀 다른 문제라는 걸 알게 됐다.

    세 번째 착각은 **“성능은 크게 중요하지 않다”**는 생각이었다.
    미니PC에 NAS 하나, 서비스 몇 개쯤은 충분히 여유롭다고 여겼다.
    하지만 서비스가 늘어날수록 병목은 CPU가 아니라 I/O와 네트워크,
    그리고 무엇보다 내 판단에서 먼저 나타났다.
    수치는 멀쩡해 보여도 마음은 계속 불안해졌다.

    돌이켜보면 홈서버를 시작하기 전의 나는
    ‘내 자료는 클라우드에도, 누군가의 서버를 거치지도 않게 하고 싶다’는 로망에
    기대를 너무 많이 얹어두고 있었다.
    사진을 찍어 공유하면 카카오톡으로 전송되고,
    어디선가 누군가는 그걸 볼 수도 있겠다는 생각에
    퀵쉐어나 에어드롭을 더 선호하게 된 것도 같은 맥락이었다.

    그럼에도 불구하고, 이 선택을 후회하느냐고 묻는다면 답은 아니다.
    착각이 깨진 자리에 현실적인 기준과 경험이 남았고,
    그게 이후의 모든 선택—Proxmox, DSM, 그리고 서비스 분리—의 출발점이 되었기 때문이다.

    이제부터의 이야기는
    그 기대가 하나씩 무너지고, 대신 무엇을 얻게 되었는지에 대한 기록이다.


  • P0. 왜 Proxmox였나 – 미니PC로 서버를 하게 된 이유

    핸드폰 속에는 생각보다 많은 것들이 들어 있다.
    사진, 영상, 음악.
    찍고, 저장하고, 다시는 정리하지 않은 채 쌓여 간다.

    물론 마음에 드는 사진만 골라 분류해 두면 좋겠지만, 현실은 그렇지 않다.
    대부분은 날짜순으로만 정리되고,
    핸드폰이 바뀌는 순간 정렬 방식은 또 달라진다.
    오래전 사진을 새 폰으로 옮겨 보관하다 보면 결국 남는 건 하나다.

    공간의 압박.
    그리고 그 압박은 곧 기기 가격의 압박으로 이어진다.

    음악도 다르지 않았다.
    멜론, 애플뮤직, 삼성뮤직, 벅스 같은 스트리밍 서비스를 이용하면서
    늘 비슷한 최신 가요만 반복해서 듣게 된다.
    귀에 익을 즈음이면 추천 목록은 또 다른 낯선 노래로 바뀌고,
    예전에 자주 듣던 음악을 다시 찾는 일은 생각보다 귀찮은 일이 된다.

    사진과 음악, 영상까지.
    이 모든 걸 오래도록 한 곳에 모아두고,
    필요할 때 언제든 꺼내 볼 수 있으면 좋겠다는 생각이 들었다.
    그리고 이 고민이 나만의 것이 아니라는 것도 곧 알게 됐다.
    가족들 역시 비슷한 불편함을 느끼고 있었다.

    그래서 자연스럽게 NAS를 떠올렸다.
    이미 오래전부터 존재를 알고 있던 장비였다.
    하지만 막상 알아보기 시작하니 생각보다 복잡했다.
    하드웨어 선택부터 모델 구분, 용도에 맞는 구성까지.
    DSM을 기준으로 고민하다 보니 선택지는 더 늘어났다.
    제조사도 많았고, 모델은 끝이 없었다.

    문득 이런 생각이 들었다.
    NAS도 결국은 작은 컴퓨터일 뿐 아닌가.

    그렇다면 굳이 전용 장비일 필요가 있을까?
    데스크탑을 쓰기엔 현실적인 문제가 많았다.
    누군가는 업무를 보다가 끌 수도 있고,
    실수로 설정을 바꾸거나 데이터를 건드릴 수도 있다.
    24시간 안정적으로 돌아가야 하는 용도로는 어울리지 않았다.

    그때 눈에 들어온 것이 미니PC였다.
    TV 뒤에 숨겨둘 수 있을 정도로 작고,
    항상 켜 두어도 부담 없는 저전력 제품.
    모든 제어는 온라인으로 하고,
    조용히 24시간 돌아가기만 하면 되는 구조.

    미니PC는 그 조건에 정확히 맞아떨어졌다.

    남은 선택지는 하나였다.
    이 작은 컴퓨터 위에 무엇을 올릴 것인가.

    처음부터 답은 분명하지 않았다.
    다만 한 가지 기준은 명확했다.

    한 번 올리면 끝나는 구조가 아니라,
    바꿀 수 있고, 나눌 수 있고, 다시 살릴 수 있는 구조여야 한다.

    그 기준에서 선택한 것이 Proxmox였다.
    이 선택이 1년 동안 어떤 시행착오로 이어질지는
    그때는 알지 못했다.

    이 기록은
    그렇게 시작된 작은 홈서버가
    어디까지 가게 되었는지에 대한 이야기다.