내 블로그 // 디지털 아카이브

생각, 프로젝트 및 기술 노트

원래 제 블로그 설정은 홈 서버에서 운영되기 때문에 WireGuard를 통한 순수 IPv6 프로젝트로 계획되었습니다 (참고로 route64.org에서 무료 IPv6 주소를 받을 수 있습니다). 접근성을 높이기 위해 이제 외부 IPv4 프록시를 추가했습니다 (@Larvitz님 감사합니다).

하지만 즉시 SSL 문제가 발생했습니다. 원래 A 레코드와 AAAA 레코드가 모두 프록시를 통해 전달되었기 때문에, 제 서버에서 Let's Encrypt 인증이 실패했습니다.

해결책: "IPv6 해킹"

해결책은 AAAA 레코드를 프록시로 보내는 대신 제 서버의 WireGuard IP로 직접 명시하는 것이었습니다.

  • 도메인: blog.burningboard.org
  • A 레코드 (프록시): 194.28.98.217
  • AAAA 레코드 (서버): 2a11:6c7:f05:a8::2 (WireGuard)

WireGuard IP를 가리키는 이 직접적인 AAAA 레코드를 통해 Let's Encrypt는 (AAAA 레코드가 기본적으로 우선순위를 갖기 때문에) 여전히 IPv6를 통해 제 서버에 직접 도달하여 SSL 인증서를 발급합니다. IPv4 트래픽은 프록시에 의해 암호화되어 저에게 전달됩니다.

최종 구성

통신이 원활하게 이루어지도록 Caddy 서버를 수정해야 했습니다.

1. 제 서버에서 (NixOS, blog.nix)

실제 방문자 IP가 프록시 IP로 덮어씌워지지 않고 올바르게 도달하도록 하려면, 해당 프록시를 신뢰할 수 있는 것으로 표시해야 합니다.

services.caddy.globalConfig = ''
  servers {
      trusted_proxies static 2a06:9801:1c:1000::10
  }
'';

2. 외부 프록시에서 (Caddy)

프록시가 HTTPS를 통해 제 서버에 올바르게 접속하려면 호스트 이름(SNI)을 함께 보내야 합니다.

reverse_proxy [https://[2a11:6c7:f05:a8::2]:443](https://[2a11:6c7:f05:a8::2]:443) {
    header_up Host {host}
    transport http {
        tls_server_name blog.burningboard.org
    }
}

이제 블로그는 IPv4와 IPv6를 통해 접속 가능하며, 안전하게 암호화되었고 제 집 IP는 여전히 비공개로 유지됩니다! 🚀

가장 중요한 점부터 말씀드리면, 익숙한 Markdown 파일이 계속해서 기반이 됩니다. 저는 이 간단한 솔루션을 정말 좋아하거든요. 하지만 내부적으로는 많은 변화가 있었습니다.

설정을 꽤 많이 손봤습니다:

📂 MD 파일: 블로그 구조는 마크다운 기반으로 단순하게 유지됩니다.

🌍 그 어느 때보다 글로벌하게: 이제 제 블로그는 43개 언어 번역을 지원합니다. 네, 클링온어도 포함되어 있습니다! 🖖 (Qapla'!)

원래 계획은 브라우저 언어 감지를 기반으로 한 완전 자동 실시간 번역이었습니다. 스포일러를 하자면, 부분적으로만 성공했습니다. AI가 인상적이긴 하지만, 우리가 원하는 수준에 완전히 도달하지는 못했다는 것을 알 수 있었습니다.

해결책은 이렇습니다. 이제 모든 게시물을 지정된 모든 언어로 미리 번역해 둡니다. 이는 검색 엔진 최적화(SEO)에도 훨씬 유리합니다. 자동 감지가 작동하지 않을 경우, 지구본 아이콘을 통해 선호하는 언어를 수동으로 설정할 수 있으며, 이 설정은 쿠키를 통해 간편하게 저장됩니다.

번역은 이제 Gemini 3 Flash를 사용하여 수행되며, 놀라울 정도로 좋은 결과를 보여줍니다. 하지만 AI를 주의 깊게 살펴봐야 합니다. 첫 번째 일괄 작업에서는 태그까지 잘못 번역되었는데, 이는 당연히 의도한 바가 아니었습니다.

코드는 계속해서 제공됩니다(관심 있으신 분은 메시지 주세요) 👍 다만, 이제 시스템에 별도의 Gemini API 키 🔑가 필요하다는 점에 유의해 주세요.

저는 최근 블로그를 WriteFreely에서 직접 개발한 MD-Blog로 전환했습니다 (여기서 MD는 당연히 Markdown을 의미합니다). 이전 시스템의 업데이트 실패가 계기가 되었지만, 결과적으로는 모든 것을 획기적으로 단순화하고 디자인에 대한 완전한 제어권을 확보할 수 있었던 완벽한 기회가 되었습니다.

핵심은 data/ 폴더에 있는 간단한 마크다운 파일들로, 런타임 시 현대적인 HTML로 변환됩니다. 그 결과 매우 빠르고 데이터베이스가 필요 없으며, 자체 디자인 시스템(다크 모드 포함) 덕분에 제가 상상했던 모습 그대로 구현되었습니다. 이제 현대적인 Mastodon 공유 버튼도 기본으로 탑재되어 있습니다.

코드나 가벼운 설정 방식에 관심이 있으시다면 Mastodon을 통해 언제든지 연락해 주세요!

사실 #Winboat의 아이디어는 훌륭하지만, 현재 구현 상태는 다소 불안정해 보입니다. 올해 초 설치한 이후 시스템이 잘 작동해 왔으나, 오늘 소프트웨어가 완전히 작동을 멈췄습니다.

이미지가 갑자기 메모리(RAM) 부족 오류를 보고했습니다. 수동으로 문제를 해결하려 시도했지만, 안타깝게도 시스템을 완전히 사용할 수 없는 상태로 만들고 말았습니다. 더 이상 문제 해결에 시간을 낭비하는 대신, 곧바로 Dockurr Windows 이미지로 전환했습니다. 어차피 이 이미지가 Winboat의 기술적 기반이기도 합니다.

Fehlermeldung

1. 준비 과정

저는 Podman을 사용하고 있기 때문에, 먼저 호스트 시스템에 필요한 디렉토리를 생성했습니다. 이렇게 하면 컨테이너를 다시 생성해야 할 경우에도 데이터 무결성을 유지할 수 있습니다.

mkdir -p $HOME/Windows/System
mkdir -p $HOME/Windows/Shared

2. 실행 명령

중요 참고 사항: -e USERNAME-e PASSWORD 변수의 자리 표시자를 본인의 개인 로그인 정보로 바꾸세요.

podman run -d \
  --name windows \
  -p 8006:8006 \
  --device=/dev/kvm \
  --cap-add NET_ADMIN \
  -e RAM_SIZE="8G" \
  -e USERNAME="Carsten" \
  -e PASSWORD="1234" \
  -e LANGUAGE="German" \
  -v $HOME/Windows/System:/storage:Z \
  -v $HOME/Windows/Shared:/shared:Z \
  --stop-timeout 120 \
  dockurr/windows

컨테이너가 활성화되면 브라우저를 통해 직접 Windows 인스턴스에 접속할 수 있습니다.

http://127.0.0.1:8006

Laufender Container

3. 요약

위에서 언급한 명령은 한 번만 실행하면 되었습니다. 이제 일상적인 작업에서 다음 단축 명령어를 통해 Windows 환경을 매우 편리하게 제어할 수 있습니다.

  • 시작: podman start windows
  • 중지: podman stop windows (또는 Windows 내부에서 직접 종료)
  • 상태 확인: podman ps -a

관련 링크:

NixOS를 더 잘 알아가기 위해 나만의 블로그를 설치했습니다. 놀랍게도 모든 과정이 꽤 간단했습니다.

WriteFreely는 미니멀하고 설정이 빠르며 불필요한 요소가 없어 이 목적에 아주 잘 맞습니다. 가볍게 시작하면서 동시에 무언가를 배우기에 완벽하죠. 설정도 기분 좋을 만큼 깔끔합니다. 몇 가지 옵션을 설정하고, 디렉토리를 준비하고, 리버스 프록시를 앞에 두면 끝입니다.

현재 제 NixOS 설정은 다음과 같습니다:

{ config, pkgs, ... }:

{
  services.writefreely = {
    enable = true;
    host = "blog.burningboard.org"; 
    settings = {
      server = {
        port = 8080;
        min_log_level = "debug";
      };
      app = {
        host = "https://blog.burningboard.org";
        single_user = true;
        landing = "/read";
        wf_modesty = true;
        federation = true;
        public_stats = true;
        theme = "write";
      };
    };
    stateDir = "/opt/writefreely";
  };

  # ActivityPub 키 생성 수정: 페더레이션에는 openssl이 필요함
  systemd.services.writefreely.path = [ pkgs.openssl ];

  # 올바른 권한으로 데이터 디렉토리 자동 생성
  systemd.tmpfiles.rules = [
    "d /opt/writefreely 0700 writefreely writefreely -"
  ];

  services.caddy.virtualHosts."blog.burningboard.org".extraConfig = ''
    reverse_proxy 127.0.0.1:8080 {
      header_up Host {host}
      header_up X-Real-IP {remote_host}
      header_up X-Forwarded-For {remote_host}
      header_up X-Forwarded-Proto {scheme}
    }
  '';
}

기본적으로 이게 전부입니다. NixOS는 이러한 서비스를 깔끔하게 설정하고 재현 가능하게 유지하는 것을 정말 쉽게 만들어 줍니다.