{
    "version": "https:\/\/jsonfeed.org\/version\/1",
    "title": "M9K blog: заметки с тегом системное администрирование",
    "_rss_description": "Заметки обо всём: devops, lifestyle, культура.",
    "_rss_language": "ru",
    "_itunes_email": "",
    "_itunes_categories_xml": "",
    "_itunes_image": "",
    "_itunes_explicit": "",
    "home_page_url": "https:\/\/blog.m9k.space\/tags\/sistemnoe-administrirovanie\/",
    "feed_url": "https:\/\/blog.m9k.space\/tags\/sistemnoe-administrirovanie\/json\/",
    "icon": "https:\/\/blog.m9k.space\/user\/userpic@2x.jpg?1769095194",
    "author": {
        "name": "M",
        "url": "https:\/\/blog.m9k.space\/",
        "avatar": "https:\/\/blog.m9k.space\/user\/userpic@2x.jpg?1769095194"
    },
    "items": [
        {
            "id": "210",
            "url": "https:\/\/blog.m9k.space\/all\/proxmox-7-debian-12-13-lxc-template\/",
            "title": "Proxmox 7 + Debian 12|13 LXC Template",
            "content_html": "<p>У Proxmox есть неплохая обратная совместимость с более свежими версиями LXC-контейнеров по сравнению с той версией Debian, на которой основан текущий релиз. В нашем случае используется Proxmox 7 (на базе Debian 11).<\/p>\n<p>При попытке создать контейнер получаем ошибку вида:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">TASK ERROR: unable to create CT 100 - unsupported debian version '1X'<\/code><\/pre><p>Для обхода проблемы правим файл<br \/>\n\/usr\/share\/perl5\/PVE\/LXC\/Setup\/Debian.pm в двух местах.<\/p>\n<p>Обновляем карту версий:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">my $version_map = { 'stretch\/sid' =&gt; 9.1, 'buster\/sid' =&gt; 10, 'bullseye\/sid'=&gt; 11, 'bookworm\/sid'=&gt; 12, 'trixie\/sid' =&gt; 13, 'kali-rolling'=&gt; 11, };<\/code><\/pre><p>Расширяем допустимый диапазон версий:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">if !($version &gt;= 4 &amp;&amp; $version &lt;= 14);<\/code><\/pre><p>После этого перезапускаем связанные демоны:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">systemctl restart pvedaemon \r\nsystemctl restart pveproxy<\/code><\/pre><p>Готово, контейнер успешно создаётся.<\/p>\n<p>Разумеется, это грязный хак: при обновлениях Proxmox изменения будут перезаписаны, так что решение подходит только как временное.<\/p>\n",
            "date_published": "2026-02-07T03:27:43+00:00",
            "date_modified": "2026-02-07T03:27:32+00:00",
            "_date_published_rfc2822": "Sat, 07 Feb 2026 03:27:43 +0000",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "210",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css"
                ],
                "og_images": []
            }
        },
        {
            "id": "203",
            "url": "https:\/\/blog.m9k.space\/all\/windows-peremeschenie-faylov-v-direktorii-po-sovpadeniyu-chasti\/",
            "title": "Windows перемещение файлов в директории по совпадению части имени",
            "content_html": "<p>В указанной директории ищем файлы с «_45» или «_16», перемещаем во внутреннюю создаваемую директорию.<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">$dir = &quot;C:\\work\\pics&quot;\r\n$target = Join-Path $dir 'substrateInstagram'\r\nNew-Item -ItemType Directory -Path $target -Force | Out-Null\r\nGet-ChildItem -Path $dir -Filter *.jpg -File |\r\n  Where-Object { $_.BaseName -match '(_45|_16)' } |\r\n  Move-Item -Destination $target<\/code><\/pre>",
            "date_published": "2025-10-10T02:38:06+00:00",
            "date_modified": "2025-10-10T02:38:04+00:00",
            "_date_published_rfc2822": "Fri, 10 Oct 2025 02:38:06 +0000",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "203",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css"
                ],
                "og_images": []
            }
        },
        {
            "id": "202",
            "url": "https:\/\/blog.m9k.space\/all\/linux-passwordless-oneliner\/",
            "title": "Linux Passwordless oneliner",
            "content_html": "<pre class=\"e2-text-code\"><code class=\"\">TARGET=user@host; PORT=22; [[ -r ~\/.ssh\/id_ed25519.pub ]] || ssh-keygen -t ed25519 -N &quot;&quot; -f ~\/.ssh\/id_ed25519; ssh -p &quot;$PORT&quot; &quot;$TARGET&quot; 'umask 077; mkdir -p ~\/.ssh &amp;&amp; cat &gt; ~\/.ssh\/authorized_keys' &lt; ~\/.ssh\/id_ed25519.pub &amp;&amp; ssh -p &quot;$PORT&quot; &quot;$TARGET&quot; 'echo &quot;&gt;&gt;&gt; Root доступ подтверждён&quot;'<\/code><\/pre>",
            "date_published": "2025-08-25T10:44:17+00:00",
            "date_modified": "2025-08-25T10:44:14+00:00",
            "_date_published_rfc2822": "Mon, 25 Aug 2025 10:44:17 +0000",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "202",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css"
                ],
                "og_images": []
            }
        },
        {
            "id": "201",
            "url": "https:\/\/blog.m9k.space\/all\/skreschivaem-uzha-i-ezha\/",
            "title": "CouchDB, Debian, AstraLinux, Docker и все-все-все",
            "content_html": "<p>Возникла необходимость запустить Couchdb в контейнере, где базовая ось (и базовые же пакеты) должны быть очень-очень свежими, в противной случай контейнер не проходит встроенную проверку на безопасность.<br \/>\nСтандартный официальный образ собран на базе Debian 12.<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">FROM debian:bookworm-slim<\/code><\/pre><p>Простая замена базового образа на<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">FROM debian:trixie-slim<\/code><\/pre><p>приводит к тому, что контейнер не собирается по зависимостям.<br \/>\nСмотрим официальную репу в части зависимостей и видим прекрасное — libmozjs-78-0 (>= 78.15.0). Пробуем ставить свежую версию, которая есть в репах — не помогает, пакет couchdb принципиально требует libmozjs-78-0.<\/p>\n<p>Ок, скрещиваем ежа и ужа.<\/p>\n<p>У debian есть механизм apt-pinning. Это механизм, позволяющий задать приоритеты для версий пакетов из разных источников (репозиториев, release-веток, PPA), чтобы фиксировать версию, запрещать обновление или предпочитать конкретный источник.<\/p>\n<p>Коротко приоритеты делятся на:<\/p>\n<ul>\n<li>< 0 — никогда не устанавливать.<\/li>\n<li>1..99 — ставить только при явном указании версии.<\/li>\n<li>100 — приоритет уже установленной версии.<\/li>\n<li>500 — дефолт для неприоритетных источников.<\/li>\n<li>990 — приоритет для целевого релиза (-t), либо если явно указан release.<\/li>\n<li>>1000 — разрешает понижение версии (downgrade) к закреплённой.<\/li>\n<\/ul>\n<p>Добавляет в наш Dockerfile:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">RUN echo &quot;deb http:\/\/deb.debian.org\/debian bookworm main&quot; &gt; \/etc\/apt\/sources.list.d\/bookworm.list &amp;&amp; \\\r\n    echo &quot;Package: *\\nPin: release n=bookworm\\nPin-Priority: 500&quot; &gt; \/etc\/apt\/preferences.d\/bookworm &amp;&amp; \\\r\n    echo &quot;Package: *\\nPin: release n=trixie\\nPin-Priority: 600&quot; &gt; \/etc\/apt\/preferences.d\/trixie &amp;&amp; \\\r\n    echo &quot;deb [signed-by=\/usr\/share\/keyrings\/couchdb-archive-keyring.gpg] https:\/\/apache.jfrog.io\/artifactory\/couchdb-deb\/ bookworm main&quot; \\\r\n            &gt; \/etc\/apt\/sources.list.d\/couchdb.list &amp;&amp; \\\r\n    apt-get update<\/code><\/pre><p>Основная часть пакетов ставится из свежей репы, часть, которых в ней нет — из старых.<\/p>\n",
            "date_published": "2025-08-14T10:40:09+00:00",
            "date_modified": "2025-08-14T10:40:08+00:00",
            "_date_published_rfc2822": "Thu, 14 Aug 2025 10:40:09 +0000",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "201",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css"
                ],
                "og_images": []
            }
        },
        {
            "id": "200",
            "url": "https:\/\/blog.m9k.space\/all\/curl-over-ssh-tunnel\/",
            "title": "Curl over ssh-tls-tunnel",
            "content_html": "<p>Есть ресурс resource.name, на который нужно ходить curl-ом с засылкой данных через JSON. Специфика ресурса такова, что он принимает соединения через TLS 1.3.<br \/>\nЕсть сервер A server.name, на котором нет выхода на нужный ресурс, но есть Nginx, и есть ssh-доступ до сервера B<br \/>\nЕсть сервер B, на котором есть выход на нужный ресурс, но сам сервер очень старый, и TLS на нём не проходит по требования resource.name.<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">printf '' | openssl s_client -connect 127.0.0.1:8443 -servername resource.name -tls1_3 -brief<\/code><\/pre><p>Костылим:<br \/>\nНа сервере A поднимаем туннель на внутренний порт:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">ssh -fN -o ExitOnForwardFailure=yes -o ServerAliveInterval=60 -o ServerAliveCountMax=3 -L 8443:resource.name:443 user@serverB<\/code><\/pre><p>На Nginx рисуем конфиг:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">server {\r\n        listen 9090;\r\n        server_name         server.name;\r\n\r\n        access_log  \/site\/logs\/nginx\/port_9090.log  main;\r\n        error_log   \/site\/logs\/nginx\/port_9090.error.log;\r\n\r\nlocation \/ {\r\n        proxy_pass https:\/\/127.0.0.1:8443;\r\n\r\n        proxy_set_header Host resource.name;\r\n        proxy_ssl_server_name on;\r\n        proxy_ssl_name resource.name;\r\n        proxy_ssl_protocols TLSv1.3;\r\n        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\r\n        proxy_set_header X-Forwarded-Proto https;\r\n        proxy_connect_timeout 10s;\r\n        proxy_read_timeout 60s;\r\n        proxy_ssl_verify off;\r\n}\r\n}<\/code><\/pre><p>Кидаемся тестовым запросом:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">curl -v -X POST 'http:\/\/server.name:9090\/resource' -H 'Content-Type: application\/json' --data '{&quot;login&quot;:&quot;$LOGIN&quot;,&quot;password&quot;:&quot;$PASSWORD&quot;}'<\/code><\/pre>",
            "date_published": "2025-08-14T10:21:23+00:00",
            "date_modified": "2025-08-14T10:43:11+00:00",
            "_date_published_rfc2822": "Thu, 14 Aug 2025 10:21:23 +0000",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "200",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css"
                ],
                "og_images": []
            }
        },
        {
            "id": "199",
            "url": "https:\/\/blog.m9k.space\/all\/unzip-bez-unzip\/",
            "title": "Unzip без unzip",
            "content_html": "<p>Есть сервер без выхода в сеть с древней ОС и мёртвыми репами. Нужно распаковать zip-архив — но утилиты нет.<br \/>\nРешаем вопрос python-ом:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">python - &lt;&lt;'EOF'\r\nimport zipfile, os\r\narchive = 'archive.zip'\r\ntarget_dir = 'archive.zip'\r\n\r\nif not os.path.exists(target_dir):\r\n    os.makedirs(target_dir)\r\n\r\nwith zipfile.ZipFile(archive, 'r') as z:\r\n    for name in z.namelist():\r\n        z.extract(name, target_dir)\r\nEOF<\/code><\/pre>",
            "date_published": "2025-08-14T10:07:44+00:00",
            "date_modified": "2025-08-14T10:07:31+00:00",
            "_date_published_rfc2822": "Thu, 14 Aug 2025 10:07:44 +0000",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "199",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css"
                ],
                "og_images": []
            }
        },
        {
            "id": "197",
            "url": "https:\/\/blog.m9k.space\/all\/multistage-docker-kak-peresobirat-bez-kesha-ne-ves-dockefile\/",
            "title": "Multistage Docker — как пересобирать без кэша не весь Dockefile",
            "content_html": "<p>Возникла необходимость пересобрать отдельный stage-контейнер из Dockerfile. Первый собранный контейнер — это контейнер сборки OpenSSL, который выполняется очень, очень долго. Для того, чтоб сэкономить время, во вторую часть добавляем:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\"># Stage 1: OpenSSL-сборка (пусть останется закешированной)\r\nFROM debian:bookworm AS openssl-build\r\n# ... \r\n# Stage 2: основная\r\nFROM debian:bookworm-slim\r\n# Аргумент, чтобы инвалидировать кэш\r\nARG CACHE_BREAKER=default\r\n# Используем его в ENV, чтобы Docker счёл слой новым\r\nENV CACHE_BREAKER=${CACHE_BREAKER}<\/code><\/pre>",
            "date_published": "2025-08-05T08:47:54+00:00",
            "date_modified": "2025-08-05T08:47:44+00:00",
            "_date_published_rfc2822": "Tue, 05 Aug 2025 08:47:54 +0000",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "197",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css"
                ],
                "og_images": []
            }
        },
        {
            "id": "184",
            "url": "https:\/\/blog.m9k.space\/all\/perechityvanie-topologii-diska-v-vm-posle-rasshireniya-ego-v-gip\/",
            "title": "Перечитывание топологии диска в ВМ после расширения его в гипервизоре",
            "content_html": "<pre class=\"e2-text-code\"><code class=\"\">echo 1 &gt; \/sys\/class\/scsi_device\/0:0:0:0\/device\/rescan<\/code><\/pre>",
            "date_published": "2025-04-08T08:04:53+00:00",
            "date_modified": "2025-04-08T08:04:49+00:00",
            "_date_published_rfc2822": "Tue, 08 Apr 2025 08:04:53 +0000",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "184",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css"
                ],
                "og_images": []
            }
        },
        {
            "id": "182",
            "url": "https:\/\/blog.m9k.space\/all\/chain-iz-cepochki-sertifikatov\/",
            "title": "Chain из цепочки сертификатов",
            "content_html": "<pre class=\"e2-text-code\"><code class=\"\">cat domain.crt intermediate.crt root.crt &gt; chain.crt<\/code><\/pre><pre class=\"e2-text-code\"><code class=\"\">-----BEGIN CERTIFICATE-----\r\n...\r\n-----END CERTIFICATE-----\r\n-----BEGIN CERTIFICATE-----\r\n...\r\n-----END CERTIFICATE-----\r\n-----BEGIN CERTIFICATE-----\r\n...\r\n-----END CERTIFICATE-----<\/code><\/pre>",
            "date_published": "2025-03-19T03:47:53+00:00",
            "date_modified": "2025-03-19T03:47:49+00:00",
            "_date_published_rfc2822": "Wed, 19 Mar 2025 03:47:53 +0000",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "182",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css"
                ],
                "og_images": []
            }
        },
        {
            "id": "181",
            "url": "https:\/\/blog.m9k.space\/all\/zfs-na-oracle-linux-8-10\/",
            "title": "ZFS на Oracle Linux 8.10",
            "content_html": "<p>При установке ZFS на Oracle Linux 8.10 по официальной <a href=\"https:\/\/openzfs.github.io\/openzfs-docs\/Getting%20Started\/RHEL-based%20distro\/index.html\">доке<\/a> столкнулся с неочевидной ошибкой:<\/p>\n<blockquote>\n<p>checking for kernel config option compatibility... done<br \/>\nchecking whether CONFIG_MODULES is defined... no<br \/>\nconfigure: error:<br \/>\n\t\t*** This kernel does not include the required loadable module<br \/>\n\t\t*** support!<br \/>\n\t\t***<br \/>\n\t\t*** To build OpenZFS as a loadable Linux kernel module<br \/>\n\t\t*** enable loadable module support by setting<br \/>\n\t\t*** `CONFIG_MODULES=y` in the kernel configuration and run<br \/>\n\t\t*** `make modules_prepare` in the Linux source tree.<br \/>\n\t\t***<br \/>\n\t\t*** If you don’t intend to enable loadable kernel module<br \/>\n\t\t*** support, please compile OpenZFS as a Linux kernel built-in.<br \/>\n\t\t***<br \/>\n\t\t*** Prepare the Linux source tree by running `make prepare`,<br \/>\n\t\t*** use the OpenZFS `—enable-linux-builtin` configure option,<br \/>\n\t\t*** copy the OpenZFS sources into the Linux source tree using<br \/>\n\t\t*** `.\/copy-builtin <linux source directory>`,<br \/>\n\t\t*** set `CONFIG_ZFS=y` in the kernel configuration and compile<br \/>\n\t\t*** kernel as usual.<\/p>\n<\/blockquote>\n<p>Объяснение и решение проблемы нашёл <a href=\"https:\/\/run.tournament.org.il\/build-zfs-on-oel-with-uek7\/\">тут<\/a><\/p>\n<blockquote>\n<p>The root of the problem is with the GCC toolset used to build UEK7 kernel, which is different from the one used to build Redhat compatible version. RH kernel is built (using the default) GCC.<\/p>\n<\/blockquote>\n<p>Решение:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">dnf install -y gcc-toolset-11-annobin-plugin-gcc\r\n. \/opt\/rh\/gcc-toolset-11\/enable\r\ndkms install zfs\/$VERSION<\/code><\/pre>",
            "date_published": "2025-03-06T10:29:29+00:00",
            "date_modified": "2025-03-06T10:29:48+00:00",
            "_date_published_rfc2822": "Thu, 06 Mar 2025 10:29:29 +0000",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "181",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css"
                ],
                "og_images": []
            }
        },
        {
            "id": "180",
            "url": "https:\/\/blog.m9k.space\/all\/python2-7-na-debian-12\/",
            "title": "Python 2.7 на Debian 12",
            "content_html": "<p>Потребовалось старым Ansible выполнить скрипты на свежайщем Debian 12. Столкнулся с тем, что в дистрибутиве окончательно выпилили поддержку Python 2.7. Пришлось сотворить Франкенштейна:<\/p>\n<ol start=\"1\">\n<li>Добавляем в \/etc\/apt\/sources.list:<\/li>\n<\/ol>\n<pre class=\"e2-text-code\"><code class=\"\">deb http:\/\/archive.debian.org\/debian\/ stretch contrib main non-free<\/code><\/pre><ol start=\"2\">\n<li>Обновляемся<\/li>\n<\/ol>\n<pre class=\"e2-text-code\"><code class=\"\">sudo apt-get update<\/code><\/pre><ol start=\"3\">\n<li>Делаем установку<\/li>\n<\/ol>\n<pre class=\"e2-text-code\"><code class=\"\">sudo apt-get install python2.7<\/code><\/pre><ol start=\"4\">\n<li>Делаем симлинк на бинарь<\/li>\n<\/ol>\n<pre class=\"e2-text-code\"><code class=\"\">cd \/usr\/bin &amp;&amp;  ln -s python2.7 python<\/code><\/pre><ol start=\"5\">\n<li>Удаляем добавленное в п.1 и повторно делаем пункт 2.<\/li>\n<\/ol>\n",
            "date_published": "2025-03-06T10:22:59+00:00",
            "date_modified": "2025-03-06T10:22:58+00:00",
            "_date_published_rfc2822": "Thu, 06 Mar 2025 10:22:59 +0000",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "180",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css"
                ],
                "og_images": []
            }
        },
        {
            "id": "179",
            "url": "https:\/\/blog.m9k.space\/all\/osnovnoy-potrebitel-swap-na-linux-serverah\/",
            "title": "Основной потребитель swap на Linux-серверах",
            "content_html": "<pre class=\"e2-text-code\"><code class=\"\">for file in \/proc\/*\/status ; do awk '\/VmSwap|Name\/{printf $2 &quot; &quot; $3}END{ print &quot;&quot;}' $file; done | sort -k 2 -n -r | less<\/code><\/pre><p>Взято <a href=\"https:\/\/blog.programs74.ru\/linux-which-process-is-using-swap\/\">отсюда<\/a><\/p>\n",
            "date_published": "2025-03-04T02:45:41+00:00",
            "date_modified": "2025-03-04T02:45:36+00:00",
            "_date_published_rfc2822": "Tue, 04 Mar 2025 02:45:41 +0000",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "179",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css"
                ],
                "og_images": []
            }
        },
        {
            "id": "178",
            "url": "https:\/\/blog.m9k.space\/all\/sed-udalit-kommentarii-iz-xml\/",
            "title": "SED удалить комментарии из XML",
            "content_html": "<p>Возникла задача сравнить два XML-файла конфигурации Clickhouse для выяснения, что же в ней не так. Беда конфигурации в том, что она содержит прям какое-то совершенное безумное количество закомментированных параметров, и сравнение «в лоб» превращается в муку. Почистим файлы SED-ом:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">cat config.xml | sed '\/&lt;!--.*--&gt;\/d' | sed '\/&lt;!--\/,\/--&gt;\/d' | sed '\/^[[:space:]]*$\/d' &gt; config_without_comments.xml<\/code><\/pre>",
            "date_published": "2025-02-24T04:28:21+00:00",
            "date_modified": "2025-02-24T04:28:18+00:00",
            "_date_published_rfc2822": "Mon, 24 Feb 2025 04:28:21 +0000",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "178",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css"
                ],
                "og_images": []
            }
        },
        {
            "id": "177",
            "url": "https:\/\/blog.m9k.space\/all\/apache-kafka-chtenie-iz-topikov\/",
            "title": "Apache Kafka Чтение из топиков",
            "content_html": "<p>Простое чтение топика с нулевой позиции:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">.\/kafka-console-consumer.sh --bootstrap-server $HOST:$PORT --topic $TOPIC_NAME --from-beginning<\/code><\/pre><p>Для чтения с определённой позиции нужно знать максимальный оффсет:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">.\/kafka-run-class.sh kafka.tools.GetOffsetShell --broker-list $HOST:$PORT --topic $TOPIC_NAME<\/code><\/pre><p>Цифра, которую выдаст команда, это максимальное смещение.<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">.\/kafka-console-consumer.sh --bootstrap-server $HOST:$PORT --topic $TOPIC_NAME --offset $OFFSET_START --partition $PARTITION_NUMBER<\/code><\/pre><p>$OFFSET_START — это максимальное смещение минус некая величина до позиции, с которой мы хотим вычитать топик.<\/p>\n",
            "date_published": "2025-02-14T09:19:41+00:00",
            "date_modified": "2025-02-14T09:19:36+00:00",
            "_date_published_rfc2822": "Fri, 14 Feb 2025 09:19:41 +0000",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "177",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css"
                ],
                "og_images": []
            }
        },
        {
            "id": "176",
            "url": "https:\/\/blog.m9k.space\/all\/hairpin-nat-mikrotik\/",
            "title": "Hairpin NAT Mikrotik",
            "content_html": "<p>Потребовалось настроить хождение на сайты в локальной сети не через интернет, и тут неожиданно выяснилось, что инструкция на официальной Вики не очень рабочая. Беглый гуглинг привёл вот <a href=\"сюда\"><a href=\"https:\/\/blog.mark99.ru\/pravilnyj-nat-loopback-hairpin-nat-v-mikrotik\/\">https:\/\/blog.mark99.ru\/pravilnyj-nat-loopback-hairpin-nat-v-mikrotik\/<\/a><\/a>. Копипаст самого основного:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">\/ip firewall mangle\r\nadd chain=prerouting comment=&quot;NAT Loopback detect&quot; dst-address=%EXTERNAL_IP% in-interface=LAN connection-state=new action=mark-packet new-packet-mark=nat-loopback passthrough=yes\r\n\/ip firewall nat\r\nadd chain=srcnat packet-mark=nat-loopback action=masquerade comment=&quot;NAT Loopback replace address&quot; \r\n\/ip firewall nat\r\nadd chain=dstnat dst-address=%EXTERNAL_IP% protocol=tcp dst-port=80,443 action=dst-nat to-addresses=%SITE_IP_INTERNAL%<\/code><\/pre>",
            "date_published": "2025-02-08T08:26:00+00:00",
            "date_modified": "2025-02-08T08:25:56+00:00",
            "_date_published_rfc2822": "Sat, 08 Feb 2025 08:26:00 +0000",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "176",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css"
                ],
                "og_images": []
            }
        },
        {
            "id": "175",
            "url": "https:\/\/blog.m9k.space\/all\/gallery-dl-2\/",
            "title": "gallery-dl",
            "content_html": "<p>Минималистичная консольная утилита, которая позволяет в автоматическом режиме тягать контент с нескольких десятков сайтов. Мне потребовалось, чтоб в автоматическом режиме вытянуть контент со страницы, на которую я был подписан в Boosty.<br \/>\n<a href=\"https:\/\/github.com\/mikf\/gallery-dl\">GitHub<\/a><\/p>\n<pre class=\"e2-text-code\"><code class=\"\">gallery-dl --cookies-from-browser firefox &quot;URL&quot;<\/code><\/pre>",
            "date_published": "2025-01-30T13:41:39+00:00",
            "date_modified": "2025-04-02T13:03:17+00:00",
            "_date_published_rfc2822": "Thu, 30 Jan 2025 13:41:39 +0000",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "175",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css"
                ],
                "og_images": []
            }
        },
        {
            "id": "174",
            "url": "https:\/\/blog.m9k.space\/all\/bombardier-2\/",
            "title": "Bombardier",
            "content_html": "<p>Максимальная простая и удобная тулза для тестирования нагрузки веб-приложений.<br \/>\n<a href=\"https:\/\/github.com\/codesenberg\/bombardier\">GitHub<\/a><br \/>\nПример:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">bombardier -c 125 -n 10000000 http:\/\/localhost:8080<\/code><\/pre>",
            "date_published": "2025-01-24T15:03:29+00:00",
            "date_modified": "2025-02-24T04:36:50+00:00",
            "_date_published_rfc2822": "Fri, 24 Jan 2025 15:03:29 +0000",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "174",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css"
                ],
                "og_images": []
            }
        },
        {
            "id": "164",
            "url": "https:\/\/blog.m9k.space\/all\/oracle-cloning-scheme-in-entire-db\/",
            "title": "Oracle: Cloning scheme in entire DB",
            "content_html": "<pre class=\"e2-text-code\"><code class=\"\">&gt;CREATE USER &lt;SCHEME_DEST&gt; IDENTIFIED BY &quot;&lt;SCHEME_DEST_PASSWORD&gt;&quot;;\r\n&gt;GRANT CONNECT TO &lt;SCHEME_DEST&gt;;\r\n&gt;GRANT CREATE SESSION TO &lt;SCHEME_DEST&gt;;\r\n&gt;ALTER USER &lt;SCHEME_DEST&gt; quota unlimited on &lt;DEFAULT_USER_TABLESPACE&gt;;\r\n&gt;expdp system\/&lt;SYSTEM PASSWORD&gt;@&lt;DB_SID&gt; schemas=&lt;SCHEME_SRC&gt; directory=&lt;DIRECTORY NAME&gt; dumpfile=&lt;DUMP NAME&gt;.dmp logfile=explog.txt\r\n&gt;impdp system\/&lt;SYSTEM PASSWORD&gt;@&lt;DB_SID&gt; directory=&lt;DIRECTORY NAME&gt; dumpfile=&lt;DUMP NAME&gt;.dmp logfile=implog.txt remap_schema=&lt;SCHEME_SRC&gt;:&lt;SCHEME_DEST&gt; transform=OID:N<\/code><\/pre>",
            "date_published": "2024-08-06T07:27:14+00:00",
            "date_modified": "2024-08-06T07:34:11+00:00",
            "_date_published_rfc2822": "Tue, 06 Aug 2024 07:27:14 +0000",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "164",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css"
                ],
                "og_images": []
            }
        },
        {
            "id": "162",
            "url": "https:\/\/blog.m9k.space\/all\/add-nonpassword-sudo-to-sudoers\/",
            "title": "Add NonPassword Sudo to sudoers",
            "content_html": "<pre class=\"e2-text-code\"><code class=\"\">echo &quot;$USER ALL=(ALL:ALL) NOPASSWD: ALL&quot; | sudo tee \/etc\/sudoers.d\/$USER<\/code><\/pre>",
            "date_published": "2024-07-15T03:14:19+00:00",
            "date_modified": "2024-07-15T03:14:17+00:00",
            "_date_published_rfc2822": "Mon, 15 Jul 2024 03:14:19 +0000",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "162",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css"
                ],
                "og_images": []
            }
        },
        {
            "id": "161",
            "url": "https:\/\/blog.m9k.space\/all\/proverka-raboty-ftp\/",
            "title": "Проверка работы FTPs с использованием сертификатов",
            "content_html": "<pre class=\"e2-text-code\"><code class=\"\">curl -3 -k -v --ftp-ssl --tlsv1.2 --ftp-ssl-reqd --ftp-pasv --key client.key --cacert ca.crt --cert client.crt --user $USERNAME ftp:\/\/$IP:$PORT<\/code><\/pre>",
            "date_published": "2024-07-12T05:47:00+00:00",
            "date_modified": "2024-07-12T05:46:58+00:00",
            "_date_published_rfc2822": "Fri, 12 Jul 2024 05:47:00 +0000",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "161",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css"
                ],
                "og_images": []
            }
        }
    ],
    "_e2_version": 3877,
    "_e2_ua_string": "E2 (v3877; Aegea)"
}