<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Безопасность on DevOps Way - Практические гайды</title>
    <link>https://devopsway.ru/categories/%D0%B1%D0%B5%D0%B7%D0%BE%D0%BF%D0%B0%D1%81%D0%BD%D0%BE%D1%81%D1%82%D1%8C/</link>
    <description>Recent content in Безопасность on DevOps Way - Практические гайды</description>
    <image>
      <title>DevOps Way - Практические гайды</title>
      <url>https://devopsway.ru/images/devopsway-og.png</url>
      <link>https://devopsway.ru/images/devopsway-og.png</link>
    </image>
    <generator>Hugo -- 0.161.1</generator>
    <language>ru</language>
    <lastBuildDate>Mon, 11 May 2026 13:31:05 -0400</lastBuildDate>
    <atom:link href="https://devopsway.ru/categories/%D0%B1%D0%B5%D0%B7%D0%BE%D0%BF%D0%B0%D1%81%D0%BD%D0%BE%D1%81%D1%82%D1%8C/feed.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>FreeIPA: руководство по установке централизованной системы управления идентификацией</title>
      <link>https://devopsway.ru/posts/freeipa-setup/</link>
      <pubDate>Sun, 01 Jun 2025 10:00:00 +0300</pubDate>
      <guid>https://devopsway.ru/posts/freeipa-setup/</guid>
      <description>Production-ready руководство по FreeIPA: установка сервера, DNS, Certificate Authority, Kerberos, управление пользователями и группами. Проверено на AlmaLinux 9.</description>
      <content:encoded><![CDATA[<p><strong>Категория:</strong> Системное администрирование
<strong>Цель:</strong> Развернуть production FreeIPA с учётом всех подводных камней</p>
<p><strong>Чему научитесь:</strong></p>
<ul>
<li>Правильная установка FreeIPA</li>
<li>Настройка LDAP, Kerberos, DNS, CA</li>
<li>Управление пользователями</li>
<li>Мониторинг и решение проблем</li>
<li>Резервное копирование</li>
</ul>
<p><strong>Требования:</strong></p>
<ul>
<li>RHEL/CentOS Stream/AlmaLinux/Rocky 8-9</li>
<li>Минимум 4GB RAM</li>
<li>Статический IP и FQDN</li>
<li>Доступ root</li>
</ul>
<p><strong>Серия статей:</strong> <a href="/series/freeipa/">все части</a></p>
<ol>
<li><strong>Установка FreeIPA</strong> (эта статья)</li>
<li><a href="/posts/freeipa-nfs-autofs/">NFS + Autofs интеграция</a></li>
<li><a href="/posts/freeipa-vault-integration/">Hashicorp Vault интеграция</a></li>
</ol>
<hr>
<h2 id="архитектура-freeipa">Архитектура FreeIPA</h2>


<div class="mermaid">
graph TB
  A[FreeIPA Сервер]
  A --> B[LDAP<br/>389 Directory]
  A --> C[Kerberos<br/>MIT KDC]
  A --> D[DNS<br/>BIND]
  A --> E[CA<br/>Dogtag]

    </div>
<p><strong>Компоненты:</strong></p>
<ul>
<li><strong>389 Directory Server</strong> - LDAP пользователей/групп</li>
<li><strong>MIT Kerberos</strong> - SSO аутентификация</li>
<li><strong>Dogtag CA</strong> - центр сертификации</li>
<li><strong>BIND DNS</strong> - DNS с динамическими обновлениями</li>
<li><strong>SSSD</strong> - интеграция клиентов</li>
<li><strong>Web UI</strong> - веб-интерфейс</li>
</ul>
<p><strong>Возможности:</strong></p>
<ul>
<li>Централизованная аутентификация</li>
<li>Kerberos SSO</li>
<li>Встроенный CA</li>
<li>Интегрированный DNS</li>
<li>Управление пользователями</li>
<li>SSH ключи</li>
<li>Правила sudo</li>
</ul>
<hr>
<h2 id="системные-требования">Системные требования</h2>
<p><strong>Поддерживаемые ОС:</strong></p>
<table>
  <thead>
      <tr>
          <th>ОС</th>
          <th>Рекомендация</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>RHEL 8, 9</td>
          <td>Production</td>
      </tr>
      <tr>
          <td>CentOS Stream 8, 9</td>
          <td>Production</td>
      </tr>
      <tr>
          <td>AlmaLinux 8, 9</td>
          <td>Production</td>
      </tr>
      <tr>
          <td>Rocky Linux 8, 9</td>
          <td>Production</td>
      </tr>
      <tr>
          <td>Fedora 38+</td>
          <td>Только тесты</td>
      </tr>
  </tbody>
</table>
<p><strong>Ресурсы:</strong></p>
<table>
  <thead>
      <tr>
          <th>Параметр</th>
          <th>Лаборатория</th>
          <th>Production</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>RAM</td>
          <td>2 GB</td>
          <td>4-8 GB</td>
      </tr>
      <tr>
          <td>CPU</td>
          <td>2 ядра</td>
          <td>4 ядра</td>
      </tr>
      <tr>
          <td>Диск</td>
          <td>10 GB</td>
          <td>20+ GB</td>
      </tr>
  </tbody>
</table>
<p><strong>О RAM:</strong> 2GB только для тестов, 4GB минимум для production</p>
<hr>
<h2 id="1-подготовка-системы">1. Подготовка системы</h2>
<h3 id="настройка-hostname">Настройка hostname</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">hostnamectl set-hostname ipa-master.example.com
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Проверка</span>
</span></span><span class="line"><span class="cl">hostnamectl status
</span></span><span class="line"><span class="cl">getent hosts ipa-master.example.com
</span></span></code></pre></div><h3 id="файл-etchosts">Файл /etc/hosts</h3>
<p>Только для начальной установки!</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">grep -q ipa-master.example.com /etc/hosts <span class="o">||</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">cat &gt;&gt; /etc/hosts <span class="s">&lt;&lt; EOF
</span></span></span><span class="line"><span class="cl"><span class="s">192.168.1.10 ipa-master.example.com ipa-master
</span></span></span><span class="line"><span class="cl"><span class="s">EOF</span>
</span></span></code></pre></div><h3 id="синхронизация-времени">Синхронизация времени</h3>
<p><strong>КРИТИЧНО для Kerberos!</strong> Разница &gt;5 минут = отказ</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">dnf install -y chrony
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">cat &gt;&gt; /etc/chrony.conf <span class="s">&lt;&lt; &#39;EOF&#39;
</span></span></span><span class="line"><span class="cl"><span class="s">
</span></span></span><span class="line"><span class="cl"><span class="s"># NTP серверы
</span></span></span><span class="line"><span class="cl"><span class="s">pool 2.pool.ntp.org iburst
</span></span></span><span class="line"><span class="cl"><span class="s">server 0.pool.ntp.org iburst
</span></span></span><span class="line"><span class="cl"><span class="s">makestep 1.0 3
</span></span></span><span class="line"><span class="cl"><span class="s">EOF</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">systemctl <span class="nb">enable</span> chronyd --now
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Проверка (команда chronyc с буквой &#39;c&#39;!)</span>
</span></span><span class="line"><span class="cl">chronyc sources
</span></span><span class="line"><span class="cl">chronyc tracking
</span></span></code></pre></div><h3 id="настройка-firewall">Настройка Firewall</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">dnf install -y firewalld
</span></span><span class="line"><span class="cl">systemctl <span class="nb">enable</span> firewalld --now
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Если есть готовые сервисы</span>
</span></span><span class="line"><span class="cl">firewall-cmd --permanent --add-service<span class="o">=</span>freeipa-ldap
</span></span><span class="line"><span class="cl">firewall-cmd --permanent --add-service<span class="o">=</span>freeipa-ldaps
</span></span><span class="line"><span class="cl">firewall-cmd --permanent --add-service<span class="o">=</span>dns
</span></span><span class="line"><span class="cl">firewall-cmd --permanent --add-service<span class="o">=</span>http
</span></span><span class="line"><span class="cl">firewall-cmd --permanent --add-service<span class="o">=</span>https
</span></span><span class="line"><span class="cl">firewall-cmd --permanent --add-service<span class="o">=</span>kerberos
</span></span><span class="line"><span class="cl">firewall-cmd --permanent --add-service<span class="o">=</span>kpasswd
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Если нет - используйте порты</span>
</span></span><span class="line"><span class="cl">firewall-cmd --permanent --add-port<span class="o">=</span>80/tcp
</span></span><span class="line"><span class="cl">firewall-cmd --permanent --add-port<span class="o">=</span>443/tcp
</span></span><span class="line"><span class="cl">firewall-cmd --permanent --add-port<span class="o">=</span>389/tcp
</span></span><span class="line"><span class="cl">firewall-cmd --permanent --add-port<span class="o">=</span>636/tcp
</span></span><span class="line"><span class="cl">firewall-cmd --permanent --add-port<span class="o">=</span>88/tcp
</span></span><span class="line"><span class="cl">firewall-cmd --permanent --add-port<span class="o">=</span>88/udp
</span></span><span class="line"><span class="cl">firewall-cmd --permanent --add-port<span class="o">=</span>464/tcp
</span></span><span class="line"><span class="cl">firewall-cmd --permanent --add-port<span class="o">=</span>464/udp
</span></span><span class="line"><span class="cl">firewall-cmd --permanent --add-port<span class="o">=</span>53/tcp
</span></span><span class="line"><span class="cl">firewall-cmd --permanent --add-port<span class="o">=</span>53/udp
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">firewall-cmd --reload
</span></span></code></pre></div><h3 id="selinux">SELinux</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Должно быть Enforcing</span>
</span></span><span class="line"><span class="cl">getenforce
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Если отключён</span>
</span></span><span class="line"><span class="cl">sed -i <span class="s1">&#39;s/^SELINUX=.*/SELINUX=enforcing/&#39;</span> /etc/selinux/config
</span></span><span class="line"><span class="cl">reboot
</span></span></code></pre></div><hr>
<h2 id="2-установка-freeipa">2. Установка FreeIPA</h2>
<h3 id="установка-пакетов">Установка пакетов</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">dnf update -y
</span></span><span class="line"><span class="cl">dnf install -y ipa-server ipa-server-dns ipa-admintools
</span></span></code></pre></div><h3 id="интерактивная-установка">Интерактивная установка</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">ipa-server-install --setup-dns
</span></span></code></pre></div><h3 id="автоматическая-установка">Автоматическая установка</h3>
<p><strong>Production:</strong> Используйте пароли из файлов!</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nb">export</span> <span class="nv">IPA_DS_PASSWORD</span><span class="o">=</span><span class="k">$(</span>cat /root/.ipa_ds_pass<span class="k">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">export</span> <span class="nv">IPA_ADMIN_PASSWORD</span><span class="o">=</span><span class="k">$(</span>cat /root/.ipa_admin_pass<span class="k">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">ipa-server-install <span class="se">\
</span></span></span><span class="line"><span class="cl"> --hostname<span class="o">=</span><span class="s2">&#34;ipa-master.example.com&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl"> --domain<span class="o">=</span><span class="s2">&#34;example.com&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl"> --realm<span class="o">=</span><span class="s2">&#34;EXAMPLE.COM&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl"> --ds-password<span class="o">=</span><span class="s2">&#34;</span><span class="nv">$IPA_DS_PASSWORD</span><span class="s2">&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl"> --admin-password<span class="o">=</span><span class="s2">&#34;</span><span class="nv">$IPA_ADMIN_PASSWORD</span><span class="s2">&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl"> --setup-dns <span class="se">\
</span></span></span><span class="line"><span class="cl"> --forwarder<span class="o">=</span><span class="s2">&#34;8.8.8.8&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl"> --forwarder<span class="o">=</span><span class="s2">&#34;1.1.1.1&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl"> --no-ntp <span class="se">\
</span></span></span><span class="line"><span class="cl"> --unattended
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">unset</span> IPA_DS_PASSWORD IPA_ADMIN_PASSWORD
</span></span></code></pre></div><p><strong>Флаг &ndash;no-ntp:</strong> Только если время УЖЕ синхронизировано!</p>
<h3 id="проверка-установки">Проверка установки</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Kerberos ticket</span>
</span></span><span class="line"><span class="cl">kinit admin
</span></span><span class="line"><span class="cl">klist
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Статус сервисов</span>
</span></span><span class="line"><span class="cl">ipactl status
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Healthcheck (если доступен)</span>
</span></span><span class="line"><span class="cl">dnf install -y ipa-healthcheck
</span></span><span class="line"><span class="cl">ipa-healthcheck --failures-only
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># DNS</span>
</span></span><span class="line"><span class="cl">dig ipa-master.example.com @localhost
</span></span><span class="line"><span class="cl">dig _ldap._tcp.example.com SRV @localhost
</span></span><span class="line"><span class="cl">dig _kerberos._tcp.example.com SRV @localhost
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># LDAP (через Kerberos, НЕ anonymous!)</span>
</span></span><span class="line"><span class="cl">ldapsearch -Y GSSAPI -b <span class="s2">&#34;dc=example,dc=com&#34;</span> -LLL <span class="s2">&#34;(objectClass=*)&#34;</span> dn <span class="p">|</span> head -20
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Web UI</span>
</span></span><span class="line"><span class="cl">curl -s -o /dev/null -w <span class="s2">&#34;%{http_code}\n&#34;</span> https://ipa-master.example.com/ipa/ui
</span></span></code></pre></div><p>Браузер: <code>https://ipa-master.example.com/ipa/ui</code></p>
<hr>
<h2 id="3-управление-пользователями">3. Управление пользователями</h2>
<h3 id="создание-пользователя">Создание пользователя</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">ipa user-add jdoe <span class="se">\
</span></span></span><span class="line"><span class="cl">    --first<span class="o">=</span><span class="s2">&#34;John&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">    --last<span class="o">=</span><span class="s2">&#34;Doe&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">    --email<span class="o">=</span><span class="s2">&#34;jdoe@example.com&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">    --password
</span></span></code></pre></div><h3 id="просмотр">Просмотр</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">ipa user-show jdoe
</span></span><span class="line"><span class="cl">ipa user-find
</span></span></code></pre></div><h3 id="изменение">Изменение</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">ipa user-mod jdoe --title<span class="o">=</span><span class="s2">&#34;Senior DevOps&#34;</span>
</span></span><span class="line"><span class="cl">ipa passwd jdoe
</span></span></code></pre></div><h3 id="управление-статусом">Управление статусом</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">ipa user-disable jdoe
</span></span><span class="line"><span class="cl">ipa user-enable jdoe
</span></span><span class="line"><span class="cl">ipa user-del jdoe
</span></span></code></pre></div><p><strong>Важно:</strong> После удаления tickets живут до истечения (24ч по умолчанию)</p>
<h3 id="ssh-ключи">SSH ключи</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">ipa user-mod jdoe --sshpubkey<span class="o">=</span><span class="s2">&#34;ssh-rsa AAAAB3...&#34;</span>
</span></span></code></pre></div><h3 id="группы">Группы</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">ipa group-add developers --desc<span class="o">=</span><span class="s2">&#34;Разработчики&#34;</span>
</span></span><span class="line"><span class="cl">ipa group-add-member developers --users<span class="o">=</span>jdoe,alice
</span></span><span class="line"><span class="cl">ipa group-show developers
</span></span></code></pre></div><hr>
<h2 id="4-подключение-клиентов">4. Подключение клиентов</h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># На клиенте</span>
</span></span><span class="line"><span class="cl">dnf install -y ipa-client
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Временная запись</span>
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;192.168.1.10 ipa-master.example.com&#34;</span> &gt;&gt; /etc/hosts
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Подключение</span>
</span></span><span class="line"><span class="cl">ipa-client-install --enable-dns-updates --mkhomedir
</span></span></code></pre></div><p><strong>Проверка:</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">kinit admin
</span></span><span class="line"><span class="cl">id jdoe
</span></span><span class="line"><span class="cl">su - jdoe
</span></span></code></pre></div><hr>
<h2 id="5-правила-sudo">5. Правила Sudo</h2>
<h3 id="создание-команд">Создание команд</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Проверяем путь!</span>
</span></span><span class="line"><span class="cl">which systemctl
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">ipa sudocmd-add /usr/bin/systemctl
</span></span><span class="line"><span class="cl">ipa sudocmd-add /usr/bin/journalctl
</span></span></code></pre></div><h3 id="группы-команд">Группы команд</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">ipa sudocmdgroup-add system-commands
</span></span><span class="line"><span class="cl">ipa sudocmdgroup-add-member system-commands <span class="se">\
</span></span></span><span class="line"><span class="cl">    --sudocmds<span class="o">=</span>/usr/bin/systemctl,/usr/bin/journalctl
</span></span></code></pre></div><h3 id="правила">Правила</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">ipa sudorule-add sysadmins_full <span class="se">\
</span></span></span><span class="line"><span class="cl">    --desc<span class="o">=</span><span class="s2">&#34;Полный доступ&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">    --hostcat<span class="o">=</span>all
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">ipa sudorule-add-user sysadmins_full --groups<span class="o">=</span>sysadmins
</span></span><span class="line"><span class="cl">ipa sudorule-add-allow-command sysadmins_full <span class="se">\
</span></span></span><span class="line"><span class="cl">    --sudocmdgroups<span class="o">=</span>system-commands
</span></span></code></pre></div><p><strong>Production:</strong> Используйте hostgroups вместо <code>--hostcat=all</code></p>
<h3 id="тестирование">Тестирование</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">su - alice
</span></span><span class="line"><span class="cl">sudo -l
</span></span><span class="line"><span class="cl">sudo systemctl status httpd
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Если не применяется - очистить cache</span>
</span></span><span class="line"><span class="cl">sss_cache -E
</span></span></code></pre></div><hr>
<h2 id="6-управление-dns">6. Управление DNS</h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># A запись</span>
</span></span><span class="line"><span class="cl">ipa dnsrecord-add example.com web --a-rec<span class="o">=</span>192.168.1.30
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># CNAME</span>
</span></span><span class="line"><span class="cl">ipa dnsrecord-add example.com www --cname-rec<span class="o">=</span>web.example.com.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Reverse зона</span>
</span></span><span class="line"><span class="cl">ipa dnszone-add 1.168.192.in-addr.arpa
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># PTR запись</span>
</span></span><span class="line"><span class="cl">ipa dnsrecord-add 1.168.192.in-addr.arpa <span class="m">30</span> --ptr-rec<span class="o">=</span>web.example.com.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Удаление</span>
</span></span><span class="line"><span class="cl">ipa dnsrecord-del example.com web --a-rec<span class="o">=</span>192.168.1.30
</span></span></code></pre></div><hr>
<h2 id="7-мониторинг">7. Мониторинг</h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="cp">#!/bin/bash
</span></span></span><span class="line"><span class="cl"><span class="c1"># freeipa-monitor.sh</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nv">REALM</span><span class="o">=</span><span class="k">$(</span>hostname -d <span class="p">|</span> tr <span class="s1">&#39;[:lower:]&#39;</span> <span class="s1">&#39;[:upper:]&#39;</span><span class="k">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34; Проверка FreeIPA&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Сервисы</span>
</span></span><span class="line"><span class="cl">ipactl status
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Healthcheck</span>
</span></span><span class="line"><span class="cl">ipa-healthcheck --failures-only 2&gt;/dev/null
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Web UI</span>
</span></span><span class="line"><span class="cl"><span class="nv">HTTP_STATUS</span><span class="o">=</span><span class="k">$(</span>curl -s -o /dev/null -w <span class="s2">&#34;%{http_code}&#34;</span> https://<span class="k">$(</span>hostname -f<span class="k">)</span>/ipa/ui<span class="k">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;Web UI: </span><span class="nv">$HTTP_STATUS</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># LDAP</span>
</span></span><span class="line"><span class="cl">kinit -k
</span></span><span class="line"><span class="cl"><span class="nv">DOMAIN</span><span class="o">=</span><span class="k">$(</span>hostname -d<span class="k">)</span>
</span></span><span class="line"><span class="cl"><span class="nv">BASE_DN</span><span class="o">=</span><span class="k">$(</span><span class="nb">echo</span> <span class="s2">&#34;</span><span class="nv">$DOMAIN</span><span class="s2">&#34;</span> <span class="p">|</span> sed <span class="s1">&#39;s/\./,dc=/g; s/^/dc=/&#39;</span><span class="k">)</span>
</span></span><span class="line"><span class="cl">ldapsearch -Y GSSAPI -b <span class="s2">&#34;</span><span class="nv">$BASE_DN</span><span class="s2">&#34;</span> -LLL dn <span class="p">&amp;</span>&gt;/dev/null <span class="o">&amp;&amp;</span> <span class="nb">echo</span> <span class="s2">&#34;LDAP: OK&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Сертификат</span>
</span></span><span class="line"><span class="cl">openssl x509 -in /var/lib/ipa/certs/httpd.crt -noout -enddate
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Время</span>
</span></span><span class="line"><span class="cl">chronyc tracking
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Directory Server</span>
</span></span><span class="line"><span class="cl"><span class="nv">DS_INSTANCE</span><span class="o">=</span><span class="s2">&#34;dirsrv@</span><span class="k">$(</span><span class="nb">echo</span> <span class="nv">$REALM</span> <span class="p">|</span> tr <span class="s1">&#39;.&#39;</span> <span class="s1">&#39;-&#39;</span><span class="k">)</span><span class="s2">.service&#34;</span>
</span></span><span class="line"><span class="cl">systemctl is-active <span class="s2">&#34;</span><span class="nv">$DS_INSTANCE</span><span class="s2">&#34;</span>
</span></span></code></pre></div><hr>
<h2 id="8-резервное-копирование">8. Резервное копирование</h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="cp">#!/bin/bash
</span></span></span><span class="line"><span class="cl"><span class="c1"># freeipa-backup.sh</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nv">BACKUP_DIR</span><span class="o">=</span><span class="s2">&#34;/backup/freeipa&#34;</span>
</span></span><span class="line"><span class="cl">mkdir -p <span class="s2">&#34;</span><span class="nv">$BACKUP_DIR</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Резервное копирование</span>
</span></span><span class="line"><span class="cl">ipa-backup --data --online
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Архивация</span>
</span></span><span class="line"><span class="cl"><span class="nv">LATEST</span><span class="o">=</span><span class="k">$(</span>ls -t /var/lib/ipa/backup/ipa-data-* 2&gt;/dev/null <span class="p">|</span> head -1<span class="k">)</span>
</span></span><span class="line"><span class="cl">tar czf <span class="s2">&#34;</span><span class="si">${</span><span class="nv">BACKUP_DIR</span><span class="si">}</span><span class="s2">/backup-</span><span class="k">$(</span>date +%Y%m%d<span class="k">)</span><span class="s2">.tar.gz&#34;</span> -C <span class="s2">&#34;</span><span class="k">$(</span>dirname <span class="nv">$LATEST</span><span class="k">)</span><span class="s2">&#34;</span> <span class="s2">&#34;</span><span class="k">$(</span>basename <span class="nv">$LATEST</span><span class="k">)</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Очистка старых (&gt;30 дней)</span>
</span></span><span class="line"><span class="cl">find <span class="s2">&#34;</span><span class="nv">$BACKUP_DIR</span><span class="s2">&#34;</span> -name <span class="s2">&#34;*.tar.gz&#34;</span> -mtime +30 -delete
</span></span></code></pre></div><p><strong>Multi-master:</strong> Backup делается на ОДНОЙ реплике</p>
<p><strong>Автоматизация:</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">cat &gt; /etc/cron.d/freeipa-backup <span class="s">&lt;&lt; &#39;EOF&#39;
</span></span></span><span class="line"><span class="cl"><span class="s">PATH=/usr/sbin:/usr/bin:/sbin:/bin
</span></span></span><span class="line"><span class="cl"><span class="s">0 2 * * * root /root/freeipa-backup.sh
</span></span></span><span class="line"><span class="cl"><span class="s">EOF</span>
</span></span></code></pre></div><p><strong>Восстановление:</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">tar xzf backup-YYYYMMDD.tar.gz -C /var/lib/ipa/backup/
</span></span><span class="line"><span class="cl">ipa-restore /var/lib/ipa/backup/ipa-data-YYYY-MM-DD-HH-MM-SS
</span></span></code></pre></div><hr>
<h2 id="решение-проблем">Решение проблем</h2>
<details>
<summary><b> Проблема 1: Истёк сертификат</b></summary>
<p><strong>Проверка:</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">ipa cert-find --all --pkey-only
</span></span><span class="line"><span class="cl">getcert list
</span></span></code></pre></div><p><strong>Для HTTP/LDAP:</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">ipa-certupdate
</span></span><span class="line"><span class="cl">ipactl restart
</span></span></code></pre></div><p><strong>Для self-signed CA:</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">ipa-cacert-manage renew --self-signed
</span></span><span class="line"><span class="cl">ipactl restart
</span></span></code></pre></div></details>
<details>
<summary><b> Проблема 2: Kerberos не работает</b></summary>
<p><strong>Проверка времени:</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">chronyc tracking
</span></span><span class="line"><span class="cl">chronyc sources
</span></span></code></pre></div><p><strong>Kerberos:</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">klist
</span></span><span class="line"><span class="cl">kinit admin
</span></span><span class="line"><span class="cl">klist -k /etc/krb5.keytab
</span></span><span class="line"><span class="cl">systemctl status krb5kdc
</span></span><span class="line"><span class="cl">journalctl -u krb5kdc -n <span class="m">50</span>
</span></span></code></pre></div></details>
<details>
<summary><b> Проблема 3: LDAP не отвечает</b></summary>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nv">REALM</span><span class="o">=</span><span class="k">$(</span>hostname -d <span class="p">|</span> tr <span class="s1">&#39;[:lower:]&#39;</span> <span class="s1">&#39;[:upper:]&#39;</span><span class="k">)</span>
</span></span><span class="line"><span class="cl"><span class="nv">DS_INSTANCE</span><span class="o">=</span><span class="s2">&#34;dirsrv@</span><span class="k">$(</span><span class="nb">echo</span> <span class="nv">$REALM</span> <span class="p">|</span> tr <span class="s1">&#39;.&#39;</span> <span class="s1">&#39;-&#39;</span><span class="k">)</span><span class="s2">.service&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">systemctl status <span class="s2">&#34;</span><span class="nv">$DS_INSTANCE</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">systemctl restart <span class="s2">&#34;</span><span class="nv">$DS_INSTANCE</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">tail -n <span class="m">100</span> /var/log/dirsrv/slapd-*/errors
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Тест</span>
</span></span><span class="line"><span class="cl">kinit admin
</span></span><span class="line"><span class="cl">ldapsearch -Y GSSAPI -b <span class="s2">&#34;dc=example,dc=com&#34;</span> -LLL
</span></span></code></pre></div></details>
<details>
<summary><b> Проблема 4: Web UI недоступен</b></summary>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">systemctl status httpd
</span></span><span class="line"><span class="cl">tail -n <span class="m">50</span> /var/log/httpd/error_log
</span></span><span class="line"><span class="cl">ipactl status
</span></span></code></pre></div></details>
<details>
<summary><b> Проблема 5: Клиент не подключается</b></summary>
<p><strong>Правильный порядок диагностики:</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># 1. Проверка подключения</span>
</span></span><span class="line"><span class="cl">ipa ping
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 2. Kerberos</span>
</span></span><span class="line"><span class="cl">kinit admin
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 3. LDAP</span>
</span></span><span class="line"><span class="cl">id testuser
</span></span><span class="line"><span class="cl">getent passwd testuser
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 4. SSSD</span>
</span></span><span class="line"><span class="cl">systemctl status sssd
</span></span><span class="line"><span class="cl">sssctl domain-status example.com
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 5. DNS</span>
</span></span><span class="line"><span class="cl">dig _ldap._tcp.example.com SRV
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 6. Cache</span>
</span></span><span class="line"><span class="cl">sss_cache -E
</span></span><span class="line"><span class="cl">systemctl restart sssd
</span></span></code></pre></div><p><strong>Переустановка (последний вариант!):</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">ipa-client-install --uninstall
</span></span><span class="line"><span class="cl">ipa-client-install --enable-dns-updates --mkhomedir
</span></span></code></pre></div></details>
<hr>
<h2 id="полезные-команды">Полезные команды</h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Управление</span>
</span></span><span class="line"><span class="cl">ipactl restart/stop/start/status
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Конфигурация</span>
</span></span><span class="line"><span class="cl">ipa config-show
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Справка</span>
</span></span><span class="line"><span class="cl">ipa <span class="nb">help</span> commands
</span></span><span class="line"><span class="cl">ipa <span class="nb">help</span> topics
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Пользователи</span>
</span></span><span class="line"><span class="cl">ipa user-add/show/mod/del username
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Группы</span>
</span></span><span class="line"><span class="cl">ipa group-add/show/del groupname
</span></span></code></pre></div><hr>
<h2 id="заключение">Заключение</h2>
<p>Развёрнут production-ready FreeIPA:</p>
<ul>
<li>Все типичные ошибки исправлены</li>
<li>Безопасная конфигурация</li>
<li>Готовые скрипты мониторинга</li>
<li>Резервное копирование</li>
</ul>
<p><strong>Ключевые принципы:</strong></p>
<ol>
<li>Синхронизация времени критична</li>
<li>DNS правильный</li>
<li>LDAP через Kerberos</li>
<li>Регулярный мониторинг</li>
<li>Автоматический backup</li>
</ol>
<hr>
<h2 id="что-дальше">Что дальше</h2>
<ul>
<li><strong><a href="/posts/freeipa-nfs-autofs/">Часть 2: NFS + Autofs</a></strong> — централизованное хранилище: NFS с root_squash, автомонтирование домашних каталогов через Autofs + FreeIPA LDAP, Kerberos-шифрование</li>
<li><strong><a href="/posts/freeipa-vault-integration/">Часть 3: Hashicorp Vault</a></strong> — управление секретами: LDAP-аутентификация через FreeIPA, политики на основе групп, KV engine</li>
<li><strong><a href="/series/freeipa/">Вся серия FreeIPA</a></strong> — карта всех гайдов серии</li>
</ul>
<hr>
<h2 id="контактная-информация">КОНТАКТНАЯ ИНФОРМАЦИЯ</h2>
<p><strong>Telegram:</strong> <a href="https://t.me/DevITWay">@DevITWay</a></p>
<p><strong>Сайт:</strong> <a href="https://devopsway.ru/">devopsway.ru</a></p>
]]></content:encoded>
    </item>
    <item>
      <title>FreeIPA &#43; NFS &#43; Autofs: Production-Grade централизованное хранилище</title>
      <link>https://devopsway.ru/posts/freeipa-nfs-autofs/</link>
      <pubDate>Mon, 15 Dec 2025 10:00:00 +0300</pubDate>
      <guid>https://devopsway.ru/posts/freeipa-nfs-autofs/</guid>
      <description>Production-ready NFS &#43; Autofs с FreeIPA: безопасная конфигурация, Kerberos, правильные mount options. Проверено в enterprise</description>
      <content:encoded><![CDATA[<p><strong>Категория:</strong> Системное администрирование
<strong>Цель:</strong> Настроить безопасное NFS хранилище с автомонтированием</p>
<p><strong>Чему научитесь:</strong></p>
<ul>
<li>Безопасная настройка NFS (без no_root_squash!)</li>
<li>Правильные параметры монтирования (hard vs soft)</li>
<li>Autofs с FreeIPA LDAP</li>
<li>Kerberos для NFS</li>
<li>Решение проблем</li>
</ul>
<p><strong>Требования:</strong></p>
<ul>
<li>FreeIPA настроен (<a href="/posts/freeipa-setup/">часть 1</a>)</li>
<li>RHEL/CentOS Stream/AlmaLinux/Rocky 8-9</li>
<li>Статический IP</li>
<li>Root доступ</li>
</ul>
<p><strong>Серия статей:</strong> <a href="/series/freeipa/">все части</a></p>
<ol>
<li><a href="/posts/freeipa-setup/">Установка FreeIPA</a></li>
<li><strong>NFS + Autofs</strong> (эта статья)</li>
<li><a href="/posts/freeipa-vault-integration/">Hashicorp Vault интеграция</a></li>
</ol>
<hr>
<h2 id="production-vs-лаборатория">Production vs Лаборатория</h2>
<table>
  <thead>
      <tr>
          <th>Параметр</th>
          <th>Лаборатория</th>
          <th>Production</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>NFS exports</strong></td>
          <td>no_root_squash</td>
          <td>root_squash</td>
      </tr>
      <tr>
          <td><strong>Монтирование /home</strong></td>
          <td>soft</td>
          <td>hard</td>
      </tr>
      <tr>
          <td><strong>DNS</strong></td>
          <td>chattr +i</td>
          <td>NetworkManager</td>
      </tr>
      <tr>
          <td><strong>Kerberos</strong></td>
          <td>Опционально</td>
          <td>Обязательно</td>
      </tr>
      <tr>
          <td><strong>SELinux</strong></td>
          <td>Permissive</td>
          <td>Enforcing</td>
      </tr>
  </tbody>
</table>
<p><strong>Важно:</strong> <code>no_root_squash</code> в production = нарушение безопасности!</p>
<hr>
<h2 id="архитектура">Архитектура</h2>


<div class="mermaid">
graph LR
 A[FreeIPA]
 B[NFS Сервер]
 C[Клиенты]
 
 A -->|Autofs maps| C
 B -->|NFS shares| C
 A -->|Kerberos| B
 A -->|Kerberos| C

    </div>
<p><strong>Процесс монтирования:</strong></p>
<ol>
<li>Пользователь заходит: <code>cd /home/username</code></li>
<li>Autofs запрашивает LDAP через SSSD</li>
<li>FreeIPA возвращает путь к NFS</li>
<li>Autofs монтирует с Kerberos</li>
<li>Доступ предоставлен</li>
</ol>
<hr>
<h2 id="требования">Требования</h2>
<table>
  <thead>
      <tr>
          <th>Компонент</th>
          <th>Требования</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>FreeIPA</td>
          <td>Настроен</td>
      </tr>
      <tr>
          <td>NFS Server</td>
          <td>RHEL 8-9</td>
      </tr>
      <tr>
          <td>RAM</td>
          <td>1-2 GB</td>
      </tr>
      <tr>
          <td>Диск</td>
          <td>По потребностям</td>
      </tr>
  </tbody>
</table>
<hr>
<h2 id="часть-1-nfs-сервер">Часть 1: NFS Сервер</h2>
<h3 id="настройка-hostname-и-dns">Настройка hostname и DNS</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">hostnamectl set-hostname nfs-server.example.com
</span></span></code></pre></div><p><strong>На FreeIPA:</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">kinit admin
</span></span><span class="line"><span class="cl">ipa dnsrecord-add example.com nfs-server --a-rec<span class="o">=</span>192.168.1.20
</span></span></code></pre></div><p><strong>На NFS сервере (NetworkManager!):</strong></p>
<p><strong>НЕ используйте <code>chattr +i</code>!</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Определяем подключение</span>
</span></span><span class="line"><span class="cl"><span class="nv">CONN_NAME</span><span class="o">=</span><span class="k">$(</span>nmcli -t -f NAME,DEVICE con show --active <span class="p">|</span> grep -v <span class="s1">&#39;^lo&#39;</span> <span class="p">|</span> head -1 <span class="p">|</span> cut -d: -f1<span class="k">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Настройка DNS</span>
</span></span><span class="line"><span class="cl">nmcli con mod <span class="s2">&#34;</span><span class="nv">$CONN_NAME</span><span class="s2">&#34;</span> ipv4.dns <span class="s2">&#34;192.168.1.10 8.8.8.8&#34;</span>
</span></span><span class="line"><span class="cl">nmcli con mod <span class="s2">&#34;</span><span class="nv">$CONN_NAME</span><span class="s2">&#34;</span> ipv4.dns-search <span class="s2">&#34;example.com&#34;</span>
</span></span><span class="line"><span class="cl">nmcli con mod <span class="s2">&#34;</span><span class="nv">$CONN_NAME</span><span class="s2">&#34;</span> ipv4.ignore-auto-dns yes
</span></span><span class="line"><span class="cl">nmcli con up <span class="s2">&#34;</span><span class="nv">$CONN_NAME</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Проверка</span>
</span></span><span class="line"><span class="cl">nslookup nfs-server.example.com
</span></span></code></pre></div><p><strong>Почему не chattr +i:</strong></p>
<ul>
<li>Ломает NetworkManager</li>
<li>Ломает systemd-resolved</li>
<li>Проблемы при диагностике</li>
</ul>
<h3 id="установка-nfs">Установка NFS</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">dnf install -y nfs-utils rpcbind
</span></span><span class="line"><span class="cl">systemctl <span class="nb">enable</span> --now rpcbind nfs-server
</span></span></code></pre></div><p><strong>rpcbind:</strong> Для NFSv4-only не обязателен, но рекомендуется для совместимости</p>
<h3 id="firewall">Firewall</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">firewall-cmd --permanent --add-service<span class="o">=</span>nfs
</span></span><span class="line"><span class="cl">firewall-cmd --permanent --add-service<span class="o">=</span>mountd
</span></span><span class="line"><span class="cl">firewall-cmd --permanent --add-service<span class="o">=</span>rpc-bind
</span></span><span class="line"><span class="cl">firewall-cmd --reload
</span></span></code></pre></div><h3 id="структура-директорий">Структура директорий</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">mkdir -p /export/home
</span></span><span class="line"><span class="cl">mkdir -p /export/shared/<span class="o">{</span>docs,projects,scripts<span class="o">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">chmod <span class="m">755</span> /export/home
</span></span><span class="line"><span class="cl">chmod <span class="m">755</span> /export/shared
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">cat &gt; /export/shared/README.txt <span class="s">&lt;&lt; EOF
</span></span></span><span class="line"><span class="cl"><span class="s">FreeIPA NFS Storage
</span></span></span><span class="line"><span class="cl"><span class="s">Server: $(hostname -f)
</span></span></span><span class="line"><span class="cl"><span class="s">EOF</span>
</span></span></code></pre></div><h3 id="nfs-exports-production">NFS Exports (PRODUCTION!)</h3>
<p><strong>КРИТИЧНО:</strong> <code>no_root_squash</code> = SECURITY РИСК!</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">cat &gt; /etc/exports <span class="s">&lt;&lt; &#39;EOF&#39;
</span></span></span><span class="line"><span class="cl"><span class="s"># Production конфигурация - root_squash ОБЯЗАТЕЛЕН!
</span></span></span><span class="line"><span class="cl"><span class="s">
</span></span></span><span class="line"><span class="cl"><span class="s">/export/home 192.168.1.0/24(rw,sync,root_squash,no_subtree_check)
</span></span></span><span class="line"><span class="cl"><span class="s">/export/shared 192.168.1.0/24(rw,sync,root_squash,no_subtree_check)
</span></span></span><span class="line"><span class="cl"><span class="s">EOF</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">exportfs -ra
</span></span><span class="line"><span class="cl">exportfs -v
</span></span><span class="line"><span class="cl">showmount -e localhost
</span></span></code></pre></div><p><strong>О sec=sys:</strong> На начальном этапе используется <code>sec=sys</code>. Далее переключаемся на Kerberos. В production Kerberos <strong>обязателен</strong>!</p>
<p><strong>Таблица параметров монтирования:</strong></p>
<table>
  <thead>
      <tr>
          <th>Сценарий</th>
          <th>Параметры</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>/home</td>
          <td>rw,hard,intr,sec=krb5p</td>
      </tr>
      <tr>
          <td>/shared/docs</td>
          <td>ro,soft,sec=krb5i</td>
      </tr>
      <tr>
          <td>/shared/projects</td>
          <td>rw,hard,intr,sec=krb5i</td>
      </tr>
  </tbody>
</table>
<p><strong>О no_root_squash:</strong></p>
<ul>
<li>Допустим ТОЛЬКО для backup серверов</li>
<li>НИКОГДА для /home или /shared!</li>
<li>Любой root на клиенте = root на NFS</li>
</ul>
<h3 id="регистрация-в-freeipa">Регистрация в FreeIPA</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Установка клиента</span>
</span></span><span class="line"><span class="cl">dnf install -y ipa-client
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Подключение</span>
</span></span><span class="line"><span class="cl">ipa-client-install <span class="se">\
</span></span></span><span class="line"><span class="cl"> --server<span class="o">=</span>ipa-master.example.com <span class="se">\
</span></span></span><span class="line"><span class="cl"> --domain<span class="o">=</span>example.com <span class="se">\
</span></span></span><span class="line"><span class="cl"> --realm<span class="o">=</span>EXAMPLE.COM <span class="se">\
</span></span></span><span class="line"><span class="cl"> --principal<span class="o">=</span>admin <span class="se">\
</span></span></span><span class="line"><span class="cl"> --mkhomedir <span class="se">\
</span></span></span><span class="line"><span class="cl"> --enable-dns-updates <span class="se">\
</span></span></span><span class="line"><span class="cl"> --unattended
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">kinit admin
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Host и service</span>
</span></span><span class="line"><span class="cl">ipa host-add nfs-server.example.com --ip-address<span class="o">=</span>192.168.1.20
</span></span><span class="line"><span class="cl">ipa service-add nfs/nfs-server.example.com
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Keytab</span>
</span></span><span class="line"><span class="cl">ipa-getkeytab -s ipa-master.example.com <span class="se">\
</span></span></span><span class="line"><span class="cl"> -p nfs/nfs-server.example.com <span class="se">\
</span></span></span><span class="line"><span class="cl"> -k /etc/krb5.keytab
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Проверка</span>
</span></span><span class="line"><span class="cl">klist -k /etc/krb5.keytab
</span></span></code></pre></div><h3 id="создание-домашних-директорий">Создание домашних директорий</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Получаем через getent (надёжнее чем id!)</span>
</span></span><span class="line"><span class="cl"><span class="nv">USERINFO</span><span class="o">=</span><span class="k">$(</span>getent passwd testuser<span class="k">)</span>
</span></span><span class="line"><span class="cl"><span class="nv">USERNAME</span><span class="o">=</span><span class="k">$(</span><span class="nb">echo</span> <span class="s2">&#34;</span><span class="nv">$USERINFO</span><span class="s2">&#34;</span> <span class="p">|</span> cut -d: -f1<span class="k">)</span>
</span></span><span class="line"><span class="cl"><span class="nv">UID</span><span class="o">=</span><span class="k">$(</span><span class="nb">echo</span> <span class="s2">&#34;</span><span class="nv">$USERINFO</span><span class="s2">&#34;</span> <span class="p">|</span> cut -d: -f3<span class="k">)</span>
</span></span><span class="line"><span class="cl"><span class="nv">GID</span><span class="o">=</span><span class="k">$(</span><span class="nb">echo</span> <span class="s2">&#34;</span><span class="nv">$USERINFO</span><span class="s2">&#34;</span> <span class="p">|</span> cut -d: -f4<span class="k">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">mkdir -p <span class="s2">&#34;/export/home/</span><span class="nv">$USERNAME</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">chown <span class="s2">&#34;</span><span class="nv">$UID</span><span class="s2">:</span><span class="nv">$GID</span><span class="s2">&#34;</span> <span class="s2">&#34;/export/home/</span><span class="nv">$USERNAME</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">chmod <span class="m">700</span> <span class="s2">&#34;/export/home/</span><span class="nv">$USERNAME</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">mkdir -p <span class="s2">&#34;/export/home/</span><span class="nv">$USERNAME</span><span class="s2">&#34;</span>/<span class="o">{</span>Documents,Downloads,Projects<span class="o">}</span>
</span></span><span class="line"><span class="cl">chown -R <span class="s2">&#34;</span><span class="nv">$UID</span><span class="s2">:</span><span class="nv">$GID</span><span class="s2">&#34;</span> <span class="s2">&#34;/export/home/</span><span class="nv">$USERNAME</span><span class="s2">&#34;</span>
</span></span></code></pre></div><hr>
<h2 id="часть-2-autofs-в-freeipa">Часть 2: Autofs в FreeIPA</h2>
<h3 id="создание-location">Создание Location</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">kinit admin
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Idempotent создание</span>
</span></span><span class="line"><span class="cl">ipa automountlocation-show default 2&gt;/dev/null <span class="o">||</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">ipa automountlocation-add default
</span></span></code></pre></div><h3 id="map-для-home">Map для /home</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">ipa automountmap-add default auto.home
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">ipa automountkey-add default auto.master <span class="se">\
</span></span></span><span class="line"><span class="cl">    --key<span class="o">=</span>/home <span class="se">\
</span></span></span><span class="line"><span class="cl">    --info<span class="o">=</span>auto.home
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># ВАЖНО: hard mounts для /home!</span>
</span></span><span class="line"><span class="cl">ipa automountkey-add default auto.home <span class="se">\
</span></span></span><span class="line"><span class="cl">    --key<span class="o">=</span><span class="s1">&#39;*&#39;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">    --info<span class="o">=</span><span class="s1">&#39;-rw,hard,sec=krb5p nfs-server.example.com:/export/home/&amp;&#39;</span>
</span></span></code></pre></div><p><strong>О параметрах /home:</strong></p>
<table>
  <thead>
      <tr>
          <th>Параметр</th>
          <th>Почему</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>hard</td>
          <td>Без потери данных! soft → битые .ssh, .bashrc</td>
      </tr>
      <tr>
          <td>krb5p</td>
          <td>Kerberos + шифрование</td>
      </tr>
  </tbody>
</table>
<blockquote>
<p><strong>Примечание:</strong> опция <code>intr</code> deprecated с ядра 2.6.25 и игнорируется в NFSv4. Не используйте.</p>
</blockquote>
<p>** НИКОГДА soft для /home!**</p>
<h3 id="map-для-shared">Map для /shared</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">ipa automountmap-add default auto.shared
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">ipa automountkey-add default auto.master <span class="se">\
</span></span></span><span class="line"><span class="cl">    --key<span class="o">=</span>/shared <span class="se">\
</span></span></span><span class="line"><span class="cl">    --info<span class="o">=</span>auto.shared
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Read-only docs (soft OK)</span>
</span></span><span class="line"><span class="cl">ipa automountkey-add default auto.shared <span class="se">\
</span></span></span><span class="line"><span class="cl">    --key<span class="o">=</span>docs <span class="se">\
</span></span></span><span class="line"><span class="cl">    --info<span class="o">=</span><span class="s1">&#39;-ro,soft,sec=krb5i nfs-server.example.com:/export/shared/docs&#39;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Projects (hard!)</span>
</span></span><span class="line"><span class="cl">ipa automountkey-add default auto.shared <span class="se">\
</span></span></span><span class="line"><span class="cl">    --key<span class="o">=</span>projects <span class="se">\
</span></span></span><span class="line"><span class="cl">    --info<span class="o">=</span><span class="s1">&#39;-rw,hard,intr,sec=krb5i nfs-server.example.com:/export/shared/projects&#39;</span>
</span></span></code></pre></div><p><strong>Уровни безопасности Kerberos:</strong></p>
<table>
  <thead>
      <tr>
          <th>Уровень</th>
          <th>Описание</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>krb5</td>
          <td>Аутентификация</td>
      </tr>
      <tr>
          <td>krb5i</td>
          <td>+ Проверка целостности</td>
      </tr>
      <tr>
          <td>krb5p</td>
          <td>+ Шифрование</td>
      </tr>
  </tbody>
</table>
<hr>
<h2 id="часть-3-клиенты">Часть 3: Клиенты</h2>
<h3 id="подготовка">Подготовка</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">dnf install -y autofs nfs-utils
</span></span></code></pre></div><h3 id="dns-networkmanager">DNS (NetworkManager!)</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nv">CONN_NAME</span><span class="o">=</span><span class="k">$(</span>nmcli -t -f NAME,DEVICE con show --active <span class="p">|</span> grep -v <span class="s1">&#39;^lo&#39;</span> <span class="p">|</span> head -1 <span class="p">|</span> cut -d: -f1<span class="k">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">nmcli con mod <span class="s2">&#34;</span><span class="nv">$CONN_NAME</span><span class="s2">&#34;</span> ipv4.dns <span class="s2">&#34;192.168.1.10 8.8.8.8&#34;</span>
</span></span><span class="line"><span class="cl">nmcli con mod <span class="s2">&#34;</span><span class="nv">$CONN_NAME</span><span class="s2">&#34;</span> ipv4.ignore-auto-dns yes
</span></span><span class="line"><span class="cl">nmcli con up <span class="s2">&#34;</span><span class="nv">$CONN_NAME</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">dig nfs-server.example.com
</span></span></code></pre></div><h3 id="настройка-autofs">Настройка Autofs</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">ipa-client-automount --location<span class="o">=</span>default --unattended
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Проверка</span>
</span></span><span class="line"><span class="cl">automount -m
</span></span></code></pre></div><h3 id="запуск">Запуск</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">systemctl restart sssd
</span></span><span class="line"><span class="cl">systemctl <span class="nb">enable</span> autofs --now
</span></span><span class="line"><span class="cl">systemctl status autofs
</span></span></code></pre></div><hr>
<h2 id="часть-4-kerberos-для-nfs">Часть 4: Kerberos для NFS</h2>
<h3 id="nfs-сервер">NFS сервер</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Уже получили keytab ранее</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">cat &gt;&gt; /etc/nfs.conf <span class="s">&lt;&lt; &#39;EOF&#39;
</span></span></span><span class="line"><span class="cl"><span class="s">
</span></span></span><span class="line"><span class="cl"><span class="s">[nfsd]
</span></span></span><span class="line"><span class="cl"><span class="s">vers4=y
</span></span></span><span class="line"><span class="cl"><span class="s">vers4.0=y
</span></span></span><span class="line"><span class="cl"><span class="s">vers4.1=y
</span></span></span><span class="line"><span class="cl"><span class="s">vers4.2=y
</span></span></span><span class="line"><span class="cl"><span class="s">EOF</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Обновление exports</span>
</span></span><span class="line"><span class="cl">cat &gt; /etc/exports <span class="s">&lt;&lt; &#39;EOF&#39;
</span></span></span><span class="line"><span class="cl"><span class="s"># Kerberos-secured
</span></span></span><span class="line"><span class="cl"><span class="s">
</span></span></span><span class="line"><span class="cl"><span class="s">/export/home 192.168.1.0/24(rw,sync,sec=krb5p,root_squash,no_subtree_check)
</span></span></span><span class="line"><span class="cl"><span class="s">/export/shared 192.168.1.0/24(rw,sync,sec=krb5i,root_squash,no_subtree_check)
</span></span></span><span class="line"><span class="cl"><span class="s">EOF</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">exportfs -ra
</span></span><span class="line"><span class="cl">systemctl restart nfs-server
</span></span></code></pre></div><h3 id="клиент-проверка">Клиент (проверка!)</h3>
<p><strong>КРИТИЧНО:</strong> Проверить, что Kerberos работает!</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">su - testuser
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Проверка ticket</span>
</span></span><span class="line"><span class="cl">klist
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Переход в home (триггер монтирования)</span>
</span></span><span class="line"><span class="cl"><span class="nb">cd</span> /home/testuser
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Проверка параметров монтирования</span>
</span></span><span class="line"><span class="cl">mount <span class="p">|</span> grep <span class="s2">&#34;/home/testuser&#34;</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Должно содержать: sec=krb5p</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">exit</span>
</span></span></code></pre></div><hr>
<h2 id="тестирование">Тестирование</h2>
<h3 id="тест-1-автомонтирование">Тест 1: Автомонтирование</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">su - testuser
</span></span><span class="line"><span class="cl"><span class="nb">pwd</span>
</span></span><span class="line"><span class="cl">df -h /home/testuser
</span></span><span class="line"><span class="cl">mount <span class="p">|</span> grep testuser
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;Test from </span><span class="k">$(</span>hostname<span class="k">)</span><span class="s2">&#34;</span> &gt; test.txt
</span></span><span class="line"><span class="cl">cat test.txt
</span></span><span class="line"><span class="cl"><span class="nb">exit</span>
</span></span></code></pre></div><h3 id="тест-2-shared">Тест 2: Shared</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Read-only</span>
</span></span><span class="line"><span class="cl">ls /shared/docs
</span></span><span class="line"><span class="cl">touch /shared/docs/test.txt <span class="c1"># Должна ошибка!</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Read-write</span>
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;Notes&#34;</span> &gt; /shared/projects/notes.txt
</span></span><span class="line"><span class="cl">cat /shared/projects/notes.txt
</span></span></code></pre></div><h3 id="тест-3-kerberos">Тест 3: Kerberos</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">kdestroy
</span></span><span class="line"><span class="cl">ls /home/testuser <span class="c1"># Должна ошибка!</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">kinit testuser
</span></span><span class="line"><span class="cl">ls /home/testuser <span class="c1"># Работает!</span>
</span></span></code></pre></div><h3 id="тест-4-hard-vs-soft">Тест 4: Hard vs Soft</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># На сервере</span>
</span></span><span class="line"><span class="cl">systemctl stop nfs-server
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># На клиенте</span>
</span></span><span class="line"><span class="cl">ls /home/testuser <span class="c1"># Зависает (правильно!)</span>
</span></span><span class="line"><span class="cl">ls /shared/docs <span class="c1"># Ошибка через timeout</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Восстановление</span>
</span></span><span class="line"><span class="cl">systemctl start nfs-server
</span></span></code></pre></div><hr>
<h2 id="production-конфигурация">Production конфигурация</h2>
<h3 id="скрипт-создания-домашних-директорий">Скрипт создания домашних директорий</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="cp">#!/bin/bash
</span></span></span><span class="line"><span class="cl"><span class="c1"># create-homes.sh - Production версия</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nv">NFS_HOME_BASE</span><span class="o">=</span><span class="s2">&#34;/export/home&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nv">MIN_UID</span><span class="o">=</span><span class="m">1000</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nv">USERS</span><span class="o">=</span><span class="k">$(</span>ipa user-find --all --raw <span class="p">|</span> grep <span class="s1">&#39;uid:&#39;</span> <span class="p">|</span> awk <span class="s1">&#39;{print $2}&#39;</span><span class="k">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">for</span> user in <span class="nv">$USERS</span><span class="p">;</span> <span class="k">do</span>
</span></span><span class="line"><span class="cl">    <span class="nv">USERINFO</span><span class="o">=</span><span class="k">$(</span>getent passwd <span class="s2">&#34;</span><span class="nv">$user</span><span class="s2">&#34;</span> 2&gt;/dev/null<span class="k">)</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="o">[</span> -z <span class="s2">&#34;</span><span class="nv">$USERINFO</span><span class="s2">&#34;</span> <span class="o">]</span> <span class="o">&amp;&amp;</span> <span class="k">continue</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="nv">UID</span><span class="o">=</span><span class="k">$(</span><span class="nb">echo</span> <span class="s2">&#34;</span><span class="nv">$USERINFO</span><span class="s2">&#34;</span> <span class="p">|</span> cut -d: -f3<span class="k">)</span>
</span></span><span class="line"><span class="cl">    <span class="nv">GID</span><span class="o">=</span><span class="k">$(</span><span class="nb">echo</span> <span class="s2">&#34;</span><span class="nv">$USERINFO</span><span class="s2">&#34;</span> <span class="p">|</span> cut -d: -f4<span class="k">)</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="c1"># Фильтр системных пользователей</span>
</span></span><span class="line"><span class="cl">    <span class="o">[</span> <span class="s2">&#34;</span><span class="nv">$UID</span><span class="s2">&#34;</span> -lt <span class="s2">&#34;</span><span class="nv">$MIN_UID</span><span class="s2">&#34;</span> <span class="o">]</span> <span class="o">&amp;&amp;</span> <span class="k">continue</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="nv">USER_HOME</span><span class="o">=</span><span class="s2">&#34;</span><span class="si">${</span><span class="nv">NFS_HOME_BASE</span><span class="si">}</span><span class="s2">/</span><span class="si">${</span><span class="nv">user</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="o">[</span> ! -d <span class="s2">&#34;</span><span class="nv">$USER_HOME</span><span class="s2">&#34;</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">        mkdir -p <span class="s2">&#34;</span><span class="nv">$USER_HOME</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">        chown <span class="s2">&#34;</span><span class="nv">$UID</span><span class="s2">:</span><span class="nv">$GID</span><span class="s2">&#34;</span> <span class="s2">&#34;</span><span class="nv">$USER_HOME</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">        chmod <span class="m">700</span> <span class="s2">&#34;</span><span class="nv">$USER_HOME</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">        mkdir -p <span class="s2">&#34;</span><span class="nv">$USER_HOME</span><span class="s2">&#34;</span>/<span class="o">{</span>Documents,Downloads,Projects<span class="o">}</span>
</span></span><span class="line"><span class="cl">        chown -R <span class="s2">&#34;</span><span class="nv">$UID</span><span class="s2">:</span><span class="nv">$GID</span><span class="s2">&#34;</span> <span class="s2">&#34;</span><span class="nv">$USER_HOME</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="nb">echo</span> <span class="s2">&#34; Создано: </span><span class="nv">$USER_HOME</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">fi</span>
</span></span><span class="line"><span class="cl"><span class="k">done</span>
</span></span></code></pre></div><h3 id="квоты">Квоты</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># В /etc/fstab (для сохранения после reboot!)</span>
</span></span><span class="line"><span class="cl">cat &gt;&gt; /etc/fstab <span class="s">&lt;&lt; &#39;EOF&#39;
</span></span></span><span class="line"><span class="cl"><span class="s">/dev/mapper/vg-export /export xfs defaults,usrquota,grpquota 0 0
</span></span></span><span class="line"><span class="cl"><span class="s">EOF</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">mount -o remount /export
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># XFS (RHEL 8/9) — используйте xfs_quota, НЕ quotacheck/quotaon</span>
</span></span><span class="line"><span class="cl">xfs_quota -x -c <span class="s1">&#39;limit bsoft=10g bhard=11g testuser&#39;</span> /export
</span></span><span class="line"><span class="cl">xfs_quota -x -c <span class="s1">&#39;report -h&#39;</span> /export
</span></span></code></pre></div><blockquote>
<p><strong>Важно:</strong> <code>quotacheck</code> и <code>quotaon</code> — утилиты для ext4. На XFS (стандарт RHEL 8/9)
квоты управляются через <code>xfs_quota</code> и включаются mount-опциями <code>usrquota,grpquota</code>.</p>
</blockquote>
<h3 id="selinux">SELinux</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># НЕ public_content_rw_t (это для Apache!)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Используем nfs_t</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">semanage fcontext -a -t nfs_t <span class="s2">&#34;/export/home(/.*)?&#34;</span>
</span></span><span class="line"><span class="cl">restorecon -R /export/home
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">semanage fcontext -a -t nfs_t <span class="s2">&#34;/export/shared(/.*)?&#34;</span>
</span></span><span class="line"><span class="cl">restorecon -R /export/shared
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">setsebool -P use_nfs_home_dirs on
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># На клиентах</span>
</span></span><span class="line"><span class="cl">setsebool -P use_nfs_home_dirs on
</span></span></code></pre></div><hr>
<h2 id="мониторинг">Мониторинг</h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="cp">#!/bin/bash
</span></span></span><span class="line"><span class="cl"><span class="c1"># nfs-monitor.sh</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34; NFS Server Monitoring&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">nfsstat -s <span class="p">|</span> head -20
</span></span><span class="line"><span class="cl">exportfs -v
</span></span><span class="line"><span class="cl">showmount -a <span class="c1"># Legacy, но для быстрой диагностики</span>
</span></span><span class="line"><span class="cl">klist -k /etc/krb5.keytab <span class="p">|</span> grep nfs
</span></span><span class="line"><span class="cl">df -h /export
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;Top 10 файлов:&#34;</span>
</span></span><span class="line"><span class="cl">find /export/home -type f -exec du -h <span class="o">{}</span> + 2&gt;/dev/null <span class="p">|</span> sort -rh <span class="p">|</span> head -10
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34; Завершено: </span><span class="k">$(</span>date<span class="k">)</span><span class="s2">&#34;</span>
</span></span></code></pre></div><hr>
<h2 id="решение-проблем">Решение проблем</h2>
<details>
<summary><b> Проблема 1: Autofs не монтирует</b></summary>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">automount -m
</span></span><span class="line"><span class="cl">systemctl status sssd
</span></span><span class="line"><span class="cl">sssctl domain-status example.com
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">sss_cache -E
</span></span><span class="line"><span class="cl">systemctl restart sssd
</span></span><span class="line"><span class="cl">systemctl restart autofs
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Debug</span>
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;logging = debug&#34;</span> &gt;&gt; /etc/autofs.conf
</span></span><span class="line"><span class="cl">systemctl restart autofs
</span></span><span class="line"><span class="cl">journalctl -u autofs -f
</span></span></code></pre></div></details>
<details>
<summary><b> Проблема 2: Permission denied</b></summary>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Проверка Kerberos</span>
</span></span><span class="line"><span class="cl">klist
</span></span><span class="line"><span class="cl">kinit testuser
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Проверка параметров монтирования</span>
</span></span><span class="line"><span class="cl">mount <span class="p">|</span> grep nfs4 <span class="p">|</span> grep krb5
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># На NFS сервере</span>
</span></span><span class="line"><span class="cl">exportfs -v <span class="p">|</span> grep sec
</span></span></code></pre></div></details>
<details>
<summary><b> Проблема 3: Stale file handle</b></summary>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Клиент</span>
</span></span><span class="line"><span class="cl">umount -f /home/testuser
</span></span><span class="line"><span class="cl">fuser -km /home/testuser
</span></span><span class="line"><span class="cl">systemctl restart autofs
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Сервер</span>
</span></span><span class="line"><span class="cl">exportfs -ra
</span></span><span class="line"><span class="cl">systemctl restart nfs-server
</span></span></code></pre></div></details>
<hr>
<h2 id="production-checklist">Production Checklist</h2>
<p>Перед запуском:</p>
<ul>
<li><input disabled="" type="checkbox"> DNS через FreeIPA (NetworkManager!)</li>
<li><input disabled="" type="checkbox"> UID/GID синхронизированы (getent passwd)</li>
<li><input disabled="" type="checkbox"> <strong>root_squash</strong> в exports (НЕ no_root_squash!)</li>
<li><input disabled="" type="checkbox"> <strong>hard mounts</strong> для /home (НЕ soft!)</li>
<li><input disabled="" type="checkbox"> Kerberos работает (klist, mount | grep krb5)</li>
<li><input disabled="" type="checkbox"> SELinux Enforcing + nfs_t</li>
<li><input disabled="" type="checkbox"> Firewall настроен</li>
<li><input disabled="" type="checkbox"> Backup /export</li>
<li><input disabled="" type="checkbox"> Квоты (/etc/fstab)</li>
<li><input disabled="" type="checkbox"> Мониторинг</li>
<li><input disabled="" type="checkbox"> Все тесты пройдены</li>
</ul>
<hr>
<h2 id="заключение">Заключение</h2>
<p>Настроили production-grade NFS + Autofs:</p>
<p><strong>Безопасность:</strong></p>
<ul>
<li>root_squash вместо no_root_squash</li>
<li>Kerberos шифрование (krb5p для /home)</li>
<li>SELinux Enforcing</li>
</ul>
<p><strong>Надёжность:</strong></p>
<ul>
<li>hard mounts для критичных данных</li>
<li>Правильная DNS конфигурация</li>
<li>Управление квотами</li>
</ul>
<p><strong>Принципы:</strong></p>
<ol>
<li>Security first: root_squash, Kerberos, SELinux</li>
<li>Целостность данных: hard для /home</li>
<li>DNS правильно: NetworkManager</li>
<li>Регулярный мониторинг</li>
</ol>
<hr>
<h2 id="что-дальше">Что дальше</h2>
<ul>
<li><strong><a href="/posts/freeipa-vault-integration/">Часть 3: Hashicorp Vault</a></strong> — управление секретами: LDAP-аутентификация через FreeIPA, политики на основе групп, KV engine</li>
<li><strong><a href="/posts/freeipa-setup/">Часть 1: Установка FreeIPA</a></strong> — если пропустили: полная установка FreeIPA с DNS, CA, Kerberos</li>
<li><strong><a href="/series/freeipa/">Вся серия FreeIPA</a></strong> — карта всех гайдов серии</li>
</ul>
<hr>
<h2 id="контактная-информация">КОНТАКТНАЯ ИНФОРМАЦИЯ</h2>
<p><strong>Telegram:</strong> <a href="https://t.me/DevITWay">@DevITWay</a></p>
<p><strong>Сайт:</strong> <a href="https://devopsway.ru/">devopsway.ru</a></p>
]]></content:encoded>
    </item>
    <item>
      <title>Интеграция Hashicorp Vault с FreeIPA: Управление секретами в DevOps</title>
      <link>https://devopsway.ru/posts/freeipa-vault-integration/</link>
      <pubDate>Mon, 15 Dec 2025 10:00:00 +0300</pubDate>
      <guid>https://devopsway.ru/posts/freeipa-vault-integration/</guid>
      <description>Полное руководство по интеграции Hashicorp Vault с FreeIPA для централизованного управления секретами. LDAP аутентификация, динамические учетные данные, PKI интеграция.</description>
      <content:encoded><![CDATA[<h2 id="архитектура-интеграции">Архитектура интеграции</h2>


<div class="mermaid">
graph TB
 A[Пользователь]
 B[Vault Server]
 C[FreeIPA LDAP]
 
 A -->|1. Логин| B
 B -->|2. Проверка| C
 C -->|3. OK| B
 B -->|4. Token| A
 A -->|5. Секреты| B

    </div>
<p><strong>Процесс аутентификации:</strong></p>
<ol>
<li>Пользователь вводит LDAP учётные данные</li>
<li>Vault запрашивает FreeIPA LDAP</li>
<li>FreeIPA проверяет учётные данные</li>
<li>Vault выдаёт токен доступа</li>
<li>Пользователь работает с секретами</li>
</ol>
<p><strong>Серия статей:</strong> <a href="/series/freeipa/">все части</a></p>
<ol>
<li><a href="/posts/freeipa-setup/">Установка FreeIPA</a></li>
<li><a href="/posts/freeipa-nfs-autofs/">NFS + Autofs интеграция</a></li>
<li><strong>Hashicorp Vault интеграция</strong> (эта статья)</li>
</ol>
<hr>
<h2 id="требования">Требования</h2>
<table>
  <thead>
      <tr>
          <th>Компонент</th>
          <th>Требования</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>FreeIPA</td>
          <td>Настроен и работает (<a href="/posts/freeipa-setup/">часть 1</a>)</td>
      </tr>
      <tr>
          <td>Vault Server</td>
          <td>Linux, 2GB RAM</td>
      </tr>
      <tr>
          <td>Клиенты</td>
          <td>Vault CLI</td>
      </tr>
      <tr>
          <td>Сеть</td>
          <td>Доступ к FreeIPA:389</td>
      </tr>
  </tbody>
</table>
<hr>
<h2 id="часть-1-установка-vault">Часть 1: Установка Vault</h2>
<h3 id="установка-на-rhelcentos">Установка на RHEL/CentOS</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Репозиторий HashiCorp</span>
</span></span><span class="line"><span class="cl">dnf config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Установка</span>
</span></span><span class="line"><span class="cl">dnf install -y vault
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Проверка</span>
</span></span><span class="line"><span class="cl">vault --version
</span></span></code></pre></div><h3 id="конфигурация-vault">Конфигурация Vault</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">mkdir -p /etc/vault.d
</span></span><span class="line"><span class="cl">mkdir -p /opt/vault/data
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">cat &gt; /etc/vault.d/vault.hcl <span class="s">&lt;&lt; &#39;EOF&#39;
</span></span></span><span class="line"><span class="cl"><span class="s"># Vault конфигурация для интеграции с FreeIPA
</span></span></span><span class="line"><span class="cl"><span class="s">
</span></span></span><span class="line"><span class="cl"><span class="s">storage &#34;file&#34; {
</span></span></span><span class="line"><span class="cl"><span class="s"> path = &#34;/opt/vault/data&#34;
</span></span></span><span class="line"><span class="cl"><span class="s">}
</span></span></span><span class="line"><span class="cl"><span class="s">
</span></span></span><span class="line"><span class="cl"><span class="s">listener &#34;tcp&#34; {
</span></span></span><span class="line"><span class="cl"><span class="s"> address = &#34;0.0.0.0:8200&#34;
</span></span></span><span class="line"><span class="cl"><span class="s"> tls_disable = 1
</span></span></span><span class="line"><span class="cl"><span class="s">}
</span></span></span><span class="line"><span class="cl"><span class="s">
</span></span></span><span class="line"><span class="cl"><span class="s">api_addr = &#34;http://192.168.1.30:8200&#34;
</span></span></span><span class="line"><span class="cl"><span class="s">ui = true
</span></span></span><span class="line"><span class="cl"><span class="s">EOF</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">chown -R vault:vault /opt/vault /etc/vault.d
</span></span><span class="line"><span class="cl">chmod <span class="m">640</span> /etc/vault.d/vault.hcl
</span></span></code></pre></div><p><strong>Важно:</strong> <code>tls_disable = 1</code> только для лаборатории! В production используйте TLS!</p>
<h3 id="запуск-vault">Запуск Vault</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Systemd service</span>
</span></span><span class="line"><span class="cl">systemctl <span class="nb">enable</span> vault
</span></span><span class="line"><span class="cl">systemctl start vault
</span></span><span class="line"><span class="cl">systemctl status vault
</span></span></code></pre></div><h3 id="firewall">Firewall</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">firewall-cmd --permanent --add-port<span class="o">=</span>8200/tcp
</span></span><span class="line"><span class="cl">firewall-cmd --reload
</span></span></code></pre></div><h3 id="инициализация">Инициализация</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Экспорт адреса</span>
</span></span><span class="line"><span class="cl"><span class="nb">export</span> <span class="nv">VAULT_ADDR</span><span class="o">=</span><span class="s1">&#39;http://127.0.0.1:8200&#39;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Инициализация</span>
</span></span><span class="line"><span class="cl">vault operator init -key-shares<span class="o">=</span><span class="m">5</span> -key-threshold<span class="o">=</span><span class="m">3</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># СОХРАНИТЕ ВСЕ КЛЮЧИ И ROOT TOKEN!</span>
</span></span></code></pre></div><p><strong>Вывод будет примерно такой:</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">Unseal Key 1: xxx...
</span></span><span class="line"><span class="cl">Unseal Key 2: yyy...
</span></span><span class="line"><span class="cl">Unseal Key 3: zzz...
</span></span><span class="line"><span class="cl">Unseal Key 4: aaa...
</span></span><span class="line"><span class="cl">Unseal Key 5: bbb...
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Initial Root Token: hvs.xxx...
</span></span></code></pre></div><p><strong>КРИТИЧНО:</strong> Сохраните ключи в безопасном месте!</p>
<h3 id="распечатывание-unseal">Распечатывание (Unseal)</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Используем 3 любых ключа из 5</span>
</span></span><span class="line"><span class="cl">vault operator unseal &lt;key1&gt;
</span></span><span class="line"><span class="cl">vault operator unseal &lt;key2&gt;
</span></span><span class="line"><span class="cl">vault operator unseal &lt;key3&gt;
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Проверка статуса</span>
</span></span><span class="line"><span class="cl">vault status
</span></span></code></pre></div><h3 id="вход">Вход</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">vault login &lt;root-token&gt;
</span></span></code></pre></div><hr>
<h2 id="часть-2-интеграция-с-freeipa-ldap">Часть 2: Интеграция с FreeIPA LDAP</h2>
<h3 id="создание-учётной-записи-для-vault">Создание учётной записи для Vault</h3>
<p><strong>На FreeIPA сервере:</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">kinit admin
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Создаём service account для Vault</span>
</span></span><span class="line"><span class="cl">ipa user-add vault-service <span class="se">\
</span></span></span><span class="line"><span class="cl">    --first<span class="o">=</span><span class="s2">&#34;Vault&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">    --last<span class="o">=</span><span class="s2">&#34;Service&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">    --password
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Задаём постоянный пароль</span>
</span></span><span class="line"><span class="cl">ipa passwd vault-service
</span></span></code></pre></div><p><strong>Важно:</strong> Сохраните пароль в безопасном месте!</p>
<h3 id="проверка-ldap-подключения">Проверка LDAP подключения</h3>
<p><strong>С Vault сервера:</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Тест LDAP подключения</span>
</span></span><span class="line"><span class="cl">ldapsearch -x -H ldap://ipa-master.example.com <span class="se">\
</span></span></span><span class="line"><span class="cl">    -D <span class="s2">&#34;uid=vault-service,cn=users,cn=accounts,dc=example,dc=com&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">    -W <span class="se">\
</span></span></span><span class="line"><span class="cl">    -b <span class="s2">&#34;cn=users,cn=accounts,dc=example,dc=com&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">    <span class="s2">&#34;(uid=testuser)&#34;</span>
</span></span></code></pre></div><p>Должен вернуть информацию о пользователе</p>
<h3 id="включение-ldap-аутентификации-в-vault">Включение LDAP аутентификации в Vault</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Включаем auth метод</span>
</span></span><span class="line"><span class="cl">vault auth <span class="nb">enable</span> ldap
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Настройка LDAP</span>
</span></span><span class="line"><span class="cl">vault write auth/ldap/config <span class="se">\
</span></span></span><span class="line"><span class="cl">    <span class="nv">url</span><span class="o">=</span><span class="s2">&#34;ldap://ipa-master.example.com&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">    <span class="nv">binddn</span><span class="o">=</span><span class="s2">&#34;uid=vault-service,cn=users,cn=accounts,dc=example,dc=com&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">    <span class="nv">bindpass</span><span class="o">=</span><span class="s2">&#34;&lt;пароль-vault-service&gt;&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">    <span class="nv">userdn</span><span class="o">=</span><span class="s2">&#34;cn=users,cn=accounts,dc=example,dc=com&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">    <span class="nv">userattr</span><span class="o">=</span><span class="s2">&#34;uid&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">    <span class="nv">groupdn</span><span class="o">=</span><span class="s2">&#34;cn=groups,cn=accounts,dc=example,dc=com&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">    <span class="nv">groupattr</span><span class="o">=</span><span class="s2">&#34;cn&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">    <span class="nv">groupfilter</span><span class="o">=</span><span class="s2">&#34;(&amp;(objectClass=posixGroup)(member={{.UserDN}}))&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Проверка конфигурации</span>
</span></span><span class="line"><span class="cl">vault <span class="nb">read</span> auth/ldap/config
</span></span></code></pre></div><h3 id="тест-ldap-аутентификации">Тест LDAP аутентификации</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Вход под FreeIPA пользователем</span>
</span></span><span class="line"><span class="cl">vault login -method<span class="o">=</span>ldap <span class="nv">username</span><span class="o">=</span>testuser
</span></span><span class="line"><span class="cl"><span class="c1"># Введите пароль</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Проверка токена</span>
</span></span><span class="line"><span class="cl">vault token lookup
</span></span></code></pre></div><p>Успешный вход = интеграция работает!</p>
<hr>
<h2 id="часть-3-политики-доступа">Часть 3: Политики доступа</h2>
<h3 id="создание-политик">Создание политик</h3>
<p><strong>Политика для разработчиков:</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">cat &gt; /tmp/dev-policy.hcl <span class="s">&lt;&lt; &#39;EOF&#39;
</span></span></span><span class="line"><span class="cl"><span class="s"># Политика для разработчиков
</span></span></span><span class="line"><span class="cl"><span class="s">
</span></span></span><span class="line"><span class="cl"><span class="s"># Чтение/запись в secret/dev/*
</span></span></span><span class="line"><span class="cl"><span class="s">path &#34;secret/data/dev/*&#34; {
</span></span></span><span class="line"><span class="cl"><span class="s"> capabilities = [&#34;create&#34;, &#34;read&#34;, &#34;update&#34;, &#34;delete&#34;, &#34;list&#34;]
</span></span></span><span class="line"><span class="cl"><span class="s">}
</span></span></span><span class="line"><span class="cl"><span class="s">
</span></span></span><span class="line"><span class="cl"><span class="s"># Чтение secret/shared/*
</span></span></span><span class="line"><span class="cl"><span class="s">path &#34;secret/data/shared/*&#34; {
</span></span></span><span class="line"><span class="cl"><span class="s"> capabilities = [&#34;read&#34;, &#34;list&#34;]
</span></span></span><span class="line"><span class="cl"><span class="s">}
</span></span></span><span class="line"><span class="cl"><span class="s">
</span></span></span><span class="line"><span class="cl"><span class="s"># Metadata
</span></span></span><span class="line"><span class="cl"><span class="s">path &#34;secret/metadata/*&#34; {
</span></span></span><span class="line"><span class="cl"><span class="s"> capabilities = [&#34;list&#34;]
</span></span></span><span class="line"><span class="cl"><span class="s">}
</span></span></span><span class="line"><span class="cl"><span class="s">EOF</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">vault policy write dev-policy /tmp/dev-policy.hcl
</span></span></code></pre></div><p><strong>Политика для администраторов:</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">cat &gt; /tmp/admin-policy.hcl <span class="s">&lt;&lt; &#39;EOF&#39;
</span></span></span><span class="line"><span class="cl"><span class="s"># Политика для администраторов
</span></span></span><span class="line"><span class="cl"><span class="s">
</span></span></span><span class="line"><span class="cl"><span class="s"># Полный доступ к secret/*
</span></span></span><span class="line"><span class="cl"><span class="s">path &#34;secret/*&#34; {
</span></span></span><span class="line"><span class="cl"><span class="s"> capabilities = [&#34;create&#34;, &#34;read&#34;, &#34;update&#34;, &#34;delete&#34;, &#34;list&#34;]
</span></span></span><span class="line"><span class="cl"><span class="s">}
</span></span></span><span class="line"><span class="cl"><span class="s">
</span></span></span><span class="line"><span class="cl"><span class="s"># Управление политиками
</span></span></span><span class="line"><span class="cl"><span class="s">path &#34;sys/policies/acl/*&#34; {
</span></span></span><span class="line"><span class="cl"><span class="s"> capabilities = [&#34;create&#34;, &#34;read&#34;, &#34;update&#34;, &#34;delete&#34;, &#34;list&#34;]
</span></span></span><span class="line"><span class="cl"><span class="s">}
</span></span></span><span class="line"><span class="cl"><span class="s">
</span></span></span><span class="line"><span class="cl"><span class="s"># Просмотр auth методов
</span></span></span><span class="line"><span class="cl"><span class="s">path &#34;sys/auth&#34; {
</span></span></span><span class="line"><span class="cl"><span class="s"> capabilities = [&#34;read&#34;, &#34;list&#34;]
</span></span></span><span class="line"><span class="cl"><span class="s">}
</span></span></span><span class="line"><span class="cl"><span class="s">EOF</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">vault policy write admin-policy /tmp/admin-policy.hcl
</span></span></code></pre></div><h3 id="привязка-политик-к-группам-ldap">Привязка политик к группам LDAP</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Группа developers → dev-policy</span>
</span></span><span class="line"><span class="cl">vault write auth/ldap/groups/developers <span class="nv">policies</span><span class="o">=</span>dev-policy
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Группа sysadmins → admin-policy</span>
</span></span><span class="line"><span class="cl">vault write auth/ldap/groups/sysadmins <span class="nv">policies</span><span class="o">=</span>admin-policy
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Проверка</span>
</span></span><span class="line"><span class="cl">vault <span class="nb">read</span> auth/ldap/groups/developers
</span></span><span class="line"><span class="cl">vault <span class="nb">read</span> auth/ldap/groups/sysadmins
</span></span></code></pre></div><h3 id="проверка-прав-доступа">Проверка прав доступа</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Вход как разработчик</span>
</span></span><span class="line"><span class="cl">vault login -method<span class="o">=</span>ldap <span class="nv">username</span><span class="o">=</span>alice
</span></span><span class="line"><span class="cl"><span class="c1"># alice в группе developers</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Проверка политик</span>
</span></span><span class="line"><span class="cl">vault token lookup <span class="p">|</span> grep policies
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Тест доступа</span>
</span></span><span class="line"><span class="cl">vault kv put secret/dev/myapp <span class="nv">password</span><span class="o">=</span>secret123 <span class="c1"># OK</span>
</span></span><span class="line"><span class="cl">vault kv get secret/dev/myapp <span class="c1"># OK</span>
</span></span><span class="line"><span class="cl">vault kv put secret/prod/myapp <span class="nv">password</span><span class="o">=</span><span class="nb">test</span> <span class="c1"># Denied!</span>
</span></span></code></pre></div><hr>
<h2 id="часть-4-управление-секретами">Часть 4: Управление секретами</h2>
<blockquote>
<p><strong>Примечание:</strong> KV engine должен быть включён <strong>до</strong> использования <code>vault kv put</code>.
Если вы выполняли примеры из Части 3 — включите engine сейчас.</p>
</blockquote>
<h3 id="включение-kv-секретов">Включение KV секретов</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># KV version 2</span>
</span></span><span class="line"><span class="cl">vault secrets <span class="nb">enable</span> -path<span class="o">=</span>secret kv-v2
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Проверка</span>
</span></span><span class="line"><span class="cl">vault secrets list
</span></span></code></pre></div><h3 id="создание-секретов">Создание секретов</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Простой секрет</span>
</span></span><span class="line"><span class="cl">vault kv put secret/dev/database <span class="se">\
</span></span></span><span class="line"><span class="cl">    <span class="nv">username</span><span class="o">=</span>dbuser <span class="se">\
</span></span></span><span class="line"><span class="cl">    <span class="nv">password</span><span class="o">=</span>SuperSecret123
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># С метаданными</span>
</span></span><span class="line"><span class="cl">vault kv put secret/dev/api <span class="se">\
</span></span></span><span class="line"><span class="cl">    <span class="nv">api_key</span><span class="o">=</span>abc123xyz <span class="se">\
</span></span></span><span class="line"><span class="cl">    <span class="nv">endpoint</span><span class="o">=</span>https://api.example.com <span class="se">\
</span></span></span><span class="line"><span class="cl">    <span class="nv">created_by</span><span class="o">=</span>admin
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Файл как секрет</span>
</span></span><span class="line"><span class="cl">vault kv put secret/dev/ssh-key <span class="nv">value</span><span class="o">=</span>@~/.ssh/id_rsa
</span></span></code></pre></div><h3 id="чтение-секретов">Чтение секретов</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Полный вывод</span>
</span></span><span class="line"><span class="cl">vault kv get secret/dev/database
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Только значения</span>
</span></span><span class="line"><span class="cl">vault kv get -field<span class="o">=</span>password secret/dev/database
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># JSON формат</span>
</span></span><span class="line"><span class="cl">vault kv get -format<span class="o">=</span>json secret/dev/database
</span></span></code></pre></div><h3 id="версии-секретов">Версии секретов</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Обновление (создаёт версию 2)</span>
</span></span><span class="line"><span class="cl">vault kv put secret/dev/database <span class="se">\
</span></span></span><span class="line"><span class="cl">    <span class="nv">username</span><span class="o">=</span>dbuser <span class="se">\
</span></span></span><span class="line"><span class="cl">    <span class="nv">password</span><span class="o">=</span>NewPassword456
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Просмотр версии 1</span>
</span></span><span class="line"><span class="cl">vault kv get -version<span class="o">=</span><span class="m">1</span> secret/dev/database
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Просмотр истории</span>
</span></span><span class="line"><span class="cl">vault kv metadata get secret/dev/database
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Откат к версии 1</span>
</span></span><span class="line"><span class="cl">vault kv rollback -version<span class="o">=</span><span class="m">1</span> secret/dev/database
</span></span></code></pre></div><h3 id="удаление-секретов">Удаление секретов</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Мягкое удаление (можно восстановить)</span>
</span></span><span class="line"><span class="cl">vault kv delete secret/dev/database
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Восстановление</span>
</span></span><span class="line"><span class="cl">vault kv undelete -versions<span class="o">=</span><span class="m">2</span> secret/dev/database
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Полное удаление</span>
</span></span><span class="line"><span class="cl">vault kv destroy -versions<span class="o">=</span>1,2 secret/dev/database
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Удаление всех версий</span>
</span></span><span class="line"><span class="cl">vault kv metadata delete secret/dev/database
</span></span></code></pre></div><hr>
<h2 id="часть-5-динамические-секреты">Часть 5: Динамические секреты</h2>
<h3 id="подключение-к-postgresql-пример">Подключение к PostgreSQL (пример)</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Включаем database engine</span>
</span></span><span class="line"><span class="cl">vault secrets <span class="nb">enable</span> database
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Настройка подключения</span>
</span></span><span class="line"><span class="cl">vault write database/config/postgresql <span class="se">\
</span></span></span><span class="line"><span class="cl"> <span class="nv">plugin_name</span><span class="o">=</span>postgresql-database-plugin <span class="se">\
</span></span></span><span class="line"><span class="cl"> <span class="nv">allowed_roles</span><span class="o">=</span><span class="s2">&#34;dev-role&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl"> <span class="nv">connection_url</span><span class="o">=</span><span class="s2">&#34;postgresql://{{username}}:{{password}}@postgres:5432/mydb&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl"> <span class="nv">username</span><span class="o">=</span><span class="s2">&#34;vaultadmin&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl"> <span class="nv">password</span><span class="o">=</span><span class="s2">&#34;vaultpass&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Создание роли</span>
</span></span><span class="line"><span class="cl">vault write database/roles/dev-role <span class="se">\
</span></span></span><span class="line"><span class="cl"> <span class="nv">db_name</span><span class="o">=</span>postgresql <span class="se">\
</span></span></span><span class="line"><span class="cl"> <span class="nv">creation_statements</span><span class="o">=</span><span class="s2">&#34;CREATE ROLE \&#34;{{name}}\&#34; WITH LOGIN PASSWORD &#39;{{password}}&#39; VALID UNTIL &#39;{{expiration}}&#39;; \
</span></span></span><span class="line"><span class="cl"><span class="s2"> GRANT SELECT ON ALL TABLES IN SCHEMA public TO \&#34;{{name}}\&#34;;&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl"> <span class="nv">default_ttl</span><span class="o">=</span><span class="s2">&#34;1h&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl"> <span class="nv">max_ttl</span><span class="o">=</span><span class="s2">&#34;24h&#34;</span>
</span></span></code></pre></div><h3 id="генерация-динамических-учётных-данных">Генерация динамических учётных данных</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Получение временных credentials</span>
</span></span><span class="line"><span class="cl">vault <span class="nb">read</span> database/creds/dev-role
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Вывод:</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Key Value</span>
</span></span><span class="line"><span class="cl"><span class="c1"># lease_id database/creds/dev-role/xxx</span>
</span></span><span class="line"><span class="cl"><span class="c1"># lease_duration 1h</span>
</span></span><span class="line"><span class="cl"><span class="c1"># username v-token-dev-role-yyy</span>
</span></span><span class="line"><span class="cl"><span class="c1"># password A1B2C3D4E5F6</span>
</span></span></code></pre></div><p>Учётные данные действуют 1 час, затем автоматически удаляются!</p>
<hr>
<h2 id="часть-6-мониторинг">Часть 6: Мониторинг</h2>
<h3 id="проверка-здоровья-vault">Проверка здоровья Vault</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="cp">#!/bin/bash
</span></span></span><span class="line"><span class="cl"><span class="c1"># vault-health.sh</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">export</span> <span class="nv">VAULT_ADDR</span><span class="o">=</span><span class="s1">&#39;http://127.0.0.1:8200&#39;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34; Проверка Vault&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Статус</span>
</span></span><span class="line"><span class="cl">vault status
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Health endpoint</span>
</span></span><span class="line"><span class="cl">curl -s http://127.0.0.1:8200/v1/sys/health <span class="p">|</span> jq
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Проверка LDAP</span>
</span></span><span class="line"><span class="cl">vault auth list <span class="p">|</span> grep ldap
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Проверка секретов</span>
</span></span><span class="line"><span class="cl">vault secrets list
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Политики</span>
</span></span><span class="line"><span class="cl">vault policy list
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34; Завершено&#34;</span>
</span></span></code></pre></div><h3 id="аудит-логи">Аудит логи</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Включение файлового аудита</span>
</span></span><span class="line"><span class="cl">vault audit <span class="nb">enable</span> file <span class="nv">file_path</span><span class="o">=</span>/var/log/vault-audit.log
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Проверка</span>
</span></span><span class="line"><span class="cl">vault audit list
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Просмотр логов</span>
</span></span><span class="line"><span class="cl">tail -f /var/log/vault-audit.log <span class="p">|</span> jq
</span></span></code></pre></div><hr>
<h2 id="часть-7-использование-vault-cli">Часть 7: Использование Vault CLI</h2>
<h3 id="настройка-окружения">Настройка окружения</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># В ~/.bashrc или ~/.zshrc</span>
</span></span><span class="line"><span class="cl"><span class="nb">export</span> <span class="nv">VAULT_ADDR</span><span class="o">=</span><span class="s1">&#39;http://vault-server:8200&#39;</span>
</span></span><span class="line"><span class="cl"><span class="nb">export</span> <span class="nv">VAULT_TOKEN</span><span class="o">=</span><span class="s1">&#39;hvs.xxx...&#39;</span> <span class="c1"># Или используйте vault login</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Или создайте файл</span>
</span></span><span class="line"><span class="cl">cat &gt; ~/.vault-env <span class="s">&lt;&lt; &#39;EOF&#39;
</span></span></span><span class="line"><span class="cl"><span class="s">export VAULT_ADDR=&#39;http://192.168.1.30:8200&#39;
</span></span></span><span class="line"><span class="cl"><span class="s">EOF</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">source</span> ~/.vault-env
</span></span></code></pre></div><h3 id="часто-используемые-команды">Часто используемые команды</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Статус</span>
</span></span><span class="line"><span class="cl">vault status
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Вход</span>
</span></span><span class="line"><span class="cl">vault login -method<span class="o">=</span>ldap <span class="nv">username</span><span class="o">=</span>alice
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Чтение секрета</span>
</span></span><span class="line"><span class="cl">vault kv get secret/dev/myapp
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Запись секрета</span>
</span></span><span class="line"><span class="cl">vault kv put secret/dev/myapp <span class="nv">key</span><span class="o">=</span>value
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Список секретов</span>
</span></span><span class="line"><span class="cl">vault kv list secret/dev/
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Политики</span>
</span></span><span class="line"><span class="cl">vault policy list
</span></span><span class="line"><span class="cl">vault policy <span class="nb">read</span> dev-policy
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Токены</span>
</span></span><span class="line"><span class="cl">vault token lookup
</span></span><span class="line"><span class="cl">vault token renew
</span></span><span class="line"><span class="cl">vault token revoke &lt;token&gt;
</span></span></code></pre></div><h3 id="автоматизация-с-vault-cli">Автоматизация с vault CLI</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="cp">#!/bin/bash
</span></span></span><span class="line"><span class="cl"><span class="c1"># deploy-with-secrets.sh</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Вход (пароль запрашивается интерактивно — не передавайте в аргументах!)</span>
</span></span><span class="line"><span class="cl">vault login -method<span class="o">=</span>ldap <span class="nv">username</span><span class="o">=</span>deploy-user
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Получение секретов</span>
</span></span><span class="line"><span class="cl"><span class="nv">DB_PASS</span><span class="o">=</span><span class="k">$(</span>vault kv get -field<span class="o">=</span>password secret/prod/database<span class="k">)</span>
</span></span><span class="line"><span class="cl"><span class="nv">API_KEY</span><span class="o">=</span><span class="k">$(</span>vault kv get -field<span class="o">=</span>api_key secret/prod/api<span class="k">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Использование в deployment</span>
</span></span><span class="line"><span class="cl">docker run -e <span class="nv">DB_PASSWORD</span><span class="o">=</span><span class="s2">&#34;</span><span class="nv">$DB_PASS</span><span class="s2">&#34;</span> -e <span class="nv">API_KEY</span><span class="o">=</span><span class="s2">&#34;</span><span class="nv">$API_KEY</span><span class="s2">&#34;</span> myapp
</span></span></code></pre></div><hr>
<h2 id="часть-8-best-practices">Часть 8: Best Practices</h2>
<h3 id="безопасность">Безопасность</h3>
<ol>
<li><strong>TLS обязателен в production:</strong></li>
</ol>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># В vault.hcl</span>
</span></span><span class="line"><span class="cl">listener <span class="s2">&#34;tcp&#34;</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">  <span class="nv">address</span> <span class="o">=</span> <span class="s2">&#34;0.0.0.0:8200&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="nv">tls_cert_file</span> <span class="o">=</span> <span class="s2">&#34;/etc/vault.d/vault.crt&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="nv">tls_key_file</span> <span class="o">=</span> <span class="s2">&#34;/etc/vault.d/vault.key&#34;</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span></code></pre></div><ol start="2">
<li><strong>Ротация root token:</strong></li>
</ol>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">vault token revoke &lt;old-root-token&gt;
</span></span><span class="line"><span class="cl">vault operator generate-root
</span></span></code></pre></div><ol start="3">
<li>
<p><strong>Минимальные привилегии:</strong></p>
<ul>
<li>Используйте специфичные политики</li>
<li>Не давайте root доступ всем</li>
<li>Регулярно проверяйте права</li>
</ul>
</li>
<li>
<p><strong>Аудит:</strong></p>
<ul>
<li>Включите аудит логи</li>
<li>Мониторьте доступ</li>
<li>Настройте алерты</li>
</ul>
</li>
</ol>
<h3 id="резервное-копирование">Резервное копирование</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="cp">#!/bin/bash
</span></span></span><span class="line"><span class="cl"><span class="c1"># vault-backup.sh</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nv">BACKUP_DIR</span><span class="o">=</span><span class="s2">&#34;/backup/vault&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nv">DATE</span><span class="o">=</span><span class="k">$(</span>date +%Y%m%d_%H%M%S<span class="k">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">mkdir -p <span class="s2">&#34;</span><span class="nv">$BACKUP_DIR</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Остановка Vault</span>
</span></span><span class="line"><span class="cl">systemctl stop vault
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Backup данных</span>
</span></span><span class="line"><span class="cl">tar czf <span class="s2">&#34;</span><span class="si">${</span><span class="nv">BACKUP_DIR</span><span class="si">}</span><span class="s2">/vault-data-</span><span class="si">${</span><span class="nv">DATE</span><span class="si">}</span><span class="s2">.tar.gz&#34;</span> /opt/vault/data
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Backup конфигурации</span>
</span></span><span class="line"><span class="cl">tar czf <span class="s2">&#34;</span><span class="si">${</span><span class="nv">BACKUP_DIR</span><span class="si">}</span><span class="s2">/vault-config-</span><span class="si">${</span><span class="nv">DATE</span><span class="si">}</span><span class="s2">.tar.gz&#34;</span> /etc/vault.d
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Запуск</span>
</span></span><span class="line"><span class="cl">systemctl start vault
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Очистка старых (&gt;30 дней)</span>
</span></span><span class="line"><span class="cl">find <span class="s2">&#34;</span><span class="nv">$BACKUP_DIR</span><span class="s2">&#34;</span> -name <span class="s2">&#34;*.tar.gz&#34;</span> -mtime +30 -delete
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34; Backup завершён: </span><span class="si">${</span><span class="nv">DATE</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span></code></pre></div><h3 id="high-availability">High Availability</h3>
<p>Для production рекомендуется:</p>
<ul>
<li>3+ серверов Vault</li>
<li>Integrated Storage (Raft) — встроенный backend с Vault 1.4+</li>
<li>Load balancer перед Vault</li>
<li>Auto-unseal через облачные KMS</li>
</ul>
<hr>
<h2 id="решение-проблем">Решение проблем</h2>
<details>
<summary><b> Проблема 1: Vault sealed</b></summary>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Проверка</span>
</span></span><span class="line"><span class="cl">vault status
</span></span><span class="line"><span class="cl"><span class="c1"># Вывод: Sealed: true</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Unseal (нужны 3 ключа)</span>
</span></span><span class="line"><span class="cl">vault operator unseal &lt;key1&gt;
</span></span><span class="line"><span class="cl">vault operator unseal &lt;key2&gt;
</span></span><span class="line"><span class="cl">vault operator unseal &lt;key3&gt;
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Проверка</span>
</span></span><span class="line"><span class="cl">vault status
</span></span></code></pre></div></details>
<details>
<summary><b> Проблема 2: LDAP аутентификация не работает</b></summary>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Проверка конфигурации</span>
</span></span><span class="line"><span class="cl">vault <span class="nb">read</span> auth/ldap/config
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Тест LDAP напрямую</span>
</span></span><span class="line"><span class="cl">ldapsearch -x -H ldap://ipa-master.example.com <span class="se">\
</span></span></span><span class="line"><span class="cl"> -D <span class="s2">&#34;uid=vault-service,cn=users,cn=accounts,dc=example,dc=com&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl"> -W -b <span class="s2">&#34;cn=users,cn=accounts,dc=example,dc=com&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Проверка групп</span>
</span></span><span class="line"><span class="cl">vault <span class="nb">read</span> auth/ldap/groups/developers
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Логи</span>
</span></span><span class="line"><span class="cl">journalctl -u vault -n <span class="m">100</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Debug mode</span>
</span></span><span class="line"><span class="cl"><span class="nb">export</span> <span class="nv">VAULT_LOG_LEVEL</span><span class="o">=</span>debug
</span></span><span class="line"><span class="cl">vault login -method<span class="o">=</span>ldap <span class="nv">username</span><span class="o">=</span>testuser
</span></span></code></pre></div></details>
<details>
<summary><b> Проблема 3: Permission denied при чтении секрета</b></summary>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Проверка текущих политик</span>
</span></span><span class="line"><span class="cl">vault token lookup <span class="p">|</span> grep policies
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Проверка политики</span>
</span></span><span class="line"><span class="cl">vault policy <span class="nb">read</span> dev-policy
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Проверка пути</span>
</span></span><span class="line"><span class="cl">vault kv list secret/
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Тест с root token</span>
</span></span><span class="line"><span class="cl">vault login &lt;root-token&gt;
</span></span><span class="line"><span class="cl">vault kv get secret/dev/myapp
</span></span></code></pre></div></details>
<details>
<summary><b> Проблема 4: Token expired</b></summary>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Проверка TTL</span>
</span></span><span class="line"><span class="cl">vault token lookup
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Renewal (если возможно)</span>
</span></span><span class="line"><span class="cl">vault token renew
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Повторный вход</span>
</span></span><span class="line"><span class="cl">vault login -method<span class="o">=</span>ldap <span class="nv">username</span><span class="o">=</span>alice
</span></span></code></pre></div></details>
<hr>
<h2 id="полезные-команды">Полезные команды</h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Статус и здоровье</span>
</span></span><span class="line"><span class="cl">vault status
</span></span><span class="line"><span class="cl">vault operator members
</span></span><span class="line"><span class="cl">curl http://vault:8200/v1/sys/health
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Auth методы</span>
</span></span><span class="line"><span class="cl">vault auth list
</span></span><span class="line"><span class="cl">vault auth enable/disable &lt;method&gt;
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Secrets engines</span>
</span></span><span class="line"><span class="cl">vault secrets list
</span></span><span class="line"><span class="cl">vault secrets enable/disable &lt;engine&gt;
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Политики</span>
</span></span><span class="line"><span class="cl">vault policy list
</span></span><span class="line"><span class="cl">vault policy <span class="nb">read</span> &lt;name&gt;
</span></span><span class="line"><span class="cl">vault policy write &lt;name&gt; &lt;file&gt;
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Токены</span>
</span></span><span class="line"><span class="cl">vault token lookup
</span></span><span class="line"><span class="cl">vault token renew
</span></span><span class="line"><span class="cl">vault token revoke
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># KV операции</span>
</span></span><span class="line"><span class="cl">vault kv put/get/delete/list
</span></span><span class="line"><span class="cl">vault kv metadata get
</span></span><span class="line"><span class="cl">vault kv rollback
</span></span></code></pre></div><hr>
<h2 id="заключение">Заключение</h2>
<p>Настроена полная интеграция Vault + FreeIPA:</p>
<p><strong>Результаты:</strong></p>
<ul>
<li>Централизованная аутентификация через FreeIPA LDAP</li>
<li>Политики доступа на основе групп</li>
<li>Безопасное хранение секретов</li>
<li>Динамические учётные данные</li>
<li>Аудит всех операций</li>
</ul>
<p><strong>Ключевые принципы:</strong></p>
<ol>
<li>LDAP интеграция упрощает управление доступом</li>
<li>Политики определяют права на основе групп FreeIPA</li>
<li>Секреты версионируются и могут быть восстановлены</li>
<li>Динамические credentials повышают безопасность</li>
<li>TLS обязателен в production</li>
</ol>
<p><strong>Use cases:</strong></p>
<ul>
<li>Хранение паролей для приложений</li>
<li>API ключи и токены</li>
<li>Сертификаты и ключи</li>
<li>Динамические database credentials</li>
<li>Secrets для CI/CD</li>
<li>Конфигурационные данные</li>
</ul>
<hr>
<h2 id="что-дальше">Что дальше</h2>
<p>Это финальная часть серии FreeIPA. Полная экосистема настроена: FreeIPA для аутентификации, NFS для хранилища, Vault для секретов.</p>
<p><strong>Предыдущие части:</strong></p>
<ul>
<li><strong><a href="/posts/freeipa-setup/">Часть 1: Установка FreeIPA</a></strong> — установка сервера, DNS, CA, Kerberos, управление пользователями</li>
<li><strong><a href="/posts/freeipa-nfs-autofs/">Часть 2: NFS + Autofs</a></strong> — централизованное хранилище с автомонтированием и Kerberos</li>
<li><strong><a href="/series/freeipa/">Вся серия FreeIPA</a></strong> — карта всех гайдов серии</li>
</ul>
<p><strong>Внешние ресурсы:</strong></p>
<ul>
<li><a href="https://www.vaultproject.io/docs">Vault Documentation</a></li>
<li><a href="https://www.vaultproject.io/docs/auth/ldap">LDAP Auth Method</a></li>
<li><a href="https://www.vaultproject.io/docs/internals/security">Vault Best Practices</a></li>
</ul>
<hr>
<h2 id="контактная-информация">КОНТАКТНАЯ ИНФОРМАЦИЯ</h2>
<p><strong>Telegram:</strong> <a href="https://t.me/DevITWay">@DevITWay</a></p>
<p><strong>Сайт:</strong> <a href="https://devopsway.ru/">devopsway.ru</a></p>
]]></content:encoded>
    </item>
  </channel>
</rss>
