Моят блог // Дигитален архив

Мисли, проекти и технически бележки

Първоначално конфигурацията на моя блог беше планирана като чисто IPv6 проект чрез WireGuard, тъй като всичко се хоства на домашен сървър (между другото, безплатни IPv6 адреси можете да получите от route64.org). За да подобря достъпността, добавих външно 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)

Чрез този директен AAAA запис към моя WireGuard IP адрес, Let’s Encrypt продължава да достига до сървъра ми директно чрез IPv6 (тъй като AAAA записът се приоритизира по подразбиране) и издава 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 файлове: Структурата на блога остава проста, базирана на Markdown.

🌍 По-глобален от всякога: Моят блог вече поддържа преводи на 43 езика. Да, включително клингонски! 🖖 (Qapla'!)

Планът беше за напълно автоматичен превод в реално време, базиран на разпознаването на езика на браузъра. Спойлер: Проработи само частично. Човек забелязва: Изкуственият интелект е впечатляващ, но все още не е точно „там“, където бихме искали да бъде.

Решението: Сега просто превеждам всяка публикация предварително на всички зададени езици, което е и значително по-добре за търсачките (SEO). Ако автоматичното разпознаване не проработи, можете ръчно да зададете предпочитания от вас език чрез иконата на земното кълбо, който след това се запазва съвсем лесно чрез бисквитка (cookie).

Преводите вече се извършват с Gemini 3 Flash, което дава изненадващо добри резултати. Въпреки това, човек трябва да следи внимателно работата на AI: При първото масово изпълнение погрешно бяха преведени и таговете, което, разбира се, не беше планирано така.

Кодът все още е наличен (просто ми пишете, ако проявявате интерес) 👍 Имайте предвид обаче, че системата вече изисква собствен Gemini API ключ 🔑.

Набързо прехвърлих блога си от WriteFreely към собствена разработка: MD-Blog (MD, разбира се, означава Markdown). Поводът беше неуспешна актуализация на старата система – но в крайна сметка това се оказа перфектният тласък да опростя всичко радикално и да получа пълен контрол върху дизайна.

В основата са обикновени Markdown файлове в папка data/, които се преобразуват в модерен HTML в реално време. Резултатът е светкавично бърз, работи без база данни и благодарение на собствената дизайн система (включително тъмен режим) сега изглежда точно така, както си го представях. Дори модерен бутон за споделяне в Mastodon вече е интегриран директно.

Ако проявявате интерес към кода или олекотената конфигурация, не се колебайте да се свържете с мен в Mastodon!

Всъщност идеята зад #Winboat е отлична, но реализацията в момента изглежда все още малко нестабилна. От инсталацията в началото на годината системата работеше, но днес софтуерът напълно отказа да функционира.

Образът (image) внезапно съобщи за недостатъчна оперативна памет (RAM). Опитах се да отстраня проблема ръчно, което за съжаление направи системата окончателно неизползваема. Вместо да инвестирам повече време в търсене на грешки, преминах директно към Dockurr Windows-Image – той и без това е техническата основа на 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 е много подходящ за целта: минималистичен, бърз за настройка и без излишен баласт. Идеален за лесен старт и учене в процеса. Конфигурацията е приятно прегледна. Няколко зададени опции, подготвена директория, обратен прокси сървър (reverse proxy) отпред — и готово.

Ето как изглежда текущата ми 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 наистина улеснява чистото конфигуриране и поддържането на такива услуги по възпроизводим начин.