Статьи → Сервера → Создание и зеркалирование репозитория в Astra Linux
Сервера Актуальная

Создание и зеркалирование репозитория в Astra Linux

Andrew ⚡ Администратор
(обновлено 13.10.2026)
134 v1.0

В данной статье, мы поделим на две части процесс. В первой части мы создадим структуру для репозитория, отзеркалируем действующий репозиторий Astra Linux 1.8.6. Во второй части мы создадим свой, локальный репозиторий, в который загрузим пакеты, не входящие в основной репозиторий Astra Linux и применим установку этих пакетов на втором сервере используя наш репозиторий.

Для чего создавать свой репозиторий (вместе с зеркалом)? Во-первых, вы перестанете зависеть от интернета, от багов в Latest версиях обновлений, от удаления старых версий репозиториев. Во-вторых, вы сами будете решать, обновлять ваш парк машин на новую версию или нет. В-третьих, вы сами можете добавлять и обновлять пакеты, которые отсутствуют в интернет-репозитории. Предположим у Вас есть парк из 30 машин, вам нужно обновить каждую до новой версии. Все 30 машин пойдут загружать в интернет пакеты для обновления, особенно если вы запустите массовое обновление скриптом/ansible/puppet, это сразу удар поддых вашему каналу связи. Да, можно настроить cron на обновление рандомной датой и временем или же в часы наименьшей нагрузки или постепенное (партиями) обновления. Локальный репозиторий все равно не панацея и он не сделает безболезненным обновлением сразу 30 машин за раз, но уже с локального репозитория. Тут так же нужно планировать порционную подачу. В случае с интернетом, вы дадите хорошую нагрузку на интернет канал, а в случае с локальным, вы скорее всего упретесь в характеристики вашего железа (опять же, если у вас есть гигабитная сетка). Но грамотный подход в лице: гигабитная сеть, apt-cacher, cron и вы с легкостью обновите все 30 машин. Можно настроить свой сервер не как зеркало интернет-репозитория, а как кэширующий прокси-сервер, а уже с него производить обновления. Это так же существенно снизит нагрузку на интернет канал, но не решит проблему, когда интернет отсутствует.

Второй пример все с этими же 30 машинами. Захотели вы установить пакет, которого нет в репозитории. Вы его скачиваете с просторов интернета, загружаете на свою репу и с помощью скриптов/ansible или же puppet - осуществляете его установку на все 30 машин и в дальнейшем можете обновлять и подкидывать новые версии пакетов программ. Это лишь пару примеров из большинства плюсов своего сервера репозитория.

Приступим. Для своего репозитория, я рекомендую при установке Astra Linux создать отдельный раздел и назвать его - /repo. Как размечать диски есть тут.

  • Стенд:
    • Сервер 1 (astraops-repo) - 192.168.31.81
    • Сервер 2 (astraops-grafana) - 192.168.31.214

Часть 1. Сервер с зеркалом

0. Обновим индексы пакетов

sudo apt update

1. Установим пакеты для зеркала и локального репозитория

sudo apt install -y nginx gnupg reprepro dpkg-dev ca-certificates apt-mirror2

2. Создадим структуру для зеркалирования и локального репозитория

sudo mkdir -p /repo/{mirror,repo,preload}

создание директории

Приватный GPG-ключ - вне /repo!

sudo mkdir -p /root/.gnupg

sudo chmod 700 /root/.gnupg

sudo chown -R root:root /repo

sudo chmod -R 755 /repo

нарезаем права

/repo/mirror/       -- зеркало официальных репозиториев Astra Linux
/repo/repo           -- локальный репозиторий, база reprepro
/repo/preload      -- входящие .deb-файлы перед добавлением в репозиторий
/root/.gnupg        -- отдельный GNUPGHOME для ключа локального репозитория

3. Настройка /etc/apt/mirror.list

sudo vim /etc/apt/mirror.list

Нужно изменить два блока: параметры (config) и список репозиториев.

Изменяем base_path на свой, это корневой каталог, внутри которого создастся структура (mirror/, skel/, var/) с помощью apt-mirror2.

Важно: apt-mirror2 создаст внутри base_path подкаталог mirror. То есть фактические файлы репозитория окажутся в /repo/mirror/mirror/. Именно этот вложенный каталог впоследствии нужно будет раздавать через nginx как DocumentRoot.

отредактируйте две вещи:

Находим строку:

set base_path         /var/spool/apt-mirror

Приводим ее в такой вид:

set base_path         /repo/mirror

конфиг mirror.listменяем на свой путь

Остальные пути (mirror_path, skel_path, var_path) уже используют $base_path , трогать их не нужно.

Находим в самом низу файла, репозитории, они будут у нас в качестве источника, откуда будем зеркалировать.

старые источники зеркалирования

Удалим эти строчки, так как они не актуальны, а возьмем актуальные из sources.list или же из интернета. Я взял и адаптировал их под apt-mirror2 из sources.list.

берем источник репозиторияКопируем эти строчки и вставляем в /etc/apt/mirror.list

Получилось вот так:

вставили новые источники зеркалирования

http2-disable https://dl.astralinux.ru/astra/stable/1.8_x86-64/main-repository
deb https://dl.astralinux.ru/astra/stable/1.8_x86-64/main-repository 1.8_x86-64 main contrib non-free non-free-firmware

http2-disable https://dl.astralinux.ru/astra/stable/1.8_x86-64/extended-repository
deb https://dl.astralinux.ru/astra/stable/1.8_x86-64/extended-repository 1.8_x86-64 main contrib non-free non-free-firmware

clean https://dl.astralinux.ru/astra/stable/1.8_x86-64/main-repository
clean https://dl.astralinux.ru/astra/stable/1.8_x86-64/extended-repository

Для удобства, я добавил комментарий «Источники зеркалирования».

  • http2-disable <URL>
    • Эта директива отключает использование HTTP/2 при обращении к указанному репозиторию. apt-mirror2 в этом случае будет работать с ним по HTTP/1.1 (или HTTPS с HTTP/1.1).
  • clean <URL>
    • Эта директива разрешает автоматическую очистку устаревших файлов в зеркале указанного репозитория.
    • При каждом запуске apt-mirror2 скачивает новые версии пакетов и метаданных.Старые версии .deb-файлов, которые уже удалены из внешнего репозитория, остаются в зеркале и занимают место. По умолчанию (без clean) apt-mirror2 не удаляет такие файлы, а только создает скрипт $var_path/clean.sh, который можно запустить вручную.
    • Если указать clean <URL>, apt-mirror2 сам выполнит очистку для этого репозитория в конце синхронизации и не нужно запускать скрипт вручную.

Чтобы зеркало не «обнулилось» из-за сбоя на стороне внешнего сервера, есть два предохранителя (закомментированы в дефолтном конфиге):

# set wipe_size_ratio 0.4 - не чистить, если удаляется > 40% объема;

# set wipe_count_ratio 0.4 - не чистить, если удаляется > 40% файлов.

Если суммарный объем или количество удаляемых файлов превышает эти параметры от общего размера/количества, очистка не выполняется. Это защита от ситуации, когда внешний сервер временно отдал пустой или неполный репозиторий.

Накидываем права для учетной записи apt-mirror - запуск будем осуществлять от ее имени.

sudo chown -R apt-mirror:apt-mirror /repo/mirror

4. Запускаем зеркалирование интернет-репозиториев к себе в хранилище

sudo -u apt-mirror apt-mirror

запуск зеркалирования

Внимание! Запустил я с двумя ветками: main и extended, но из-за ограниченного количества памяти на SSD где крутятся виртуалки, я отменил зеркалирование и закоментировал ветку extended, так как суммарный объем может достигать 30-50 гб, которыми я не располагаю. По этому дальше в статье, на скриншотах он будет закомментирован, но я покажу, как его задействовать тоже.

Объем зеркала main - 2.9 GiB

Это размер только main-repository без extended. Полное зеркало Astra Linux 1.8 с обоими репозиториями занимает значительно больше. 

зеркалирование завершено

После зеркалирования, можно посмотреть, что 1.8.6 я загрузил к себе на сервер.

конфиг release

Видно, что конфиг Release лежит как раз в том месте, куда мы зеркалировали.

5. Настройка Nginx.

Ну вот и все, репозиторий мы отзеркалировали, теперь у нас локально имеется своя репа 1.8.6, но нужно сделать ее доступной для других машин. На помощь нам придет любой веб-сервер (Apache2, Nginx). Всю свою практику я видел репозитории на apache2, но вот на nginx не видел ни разу (я не говорю что их нет, просто я не видел вживую, а так же в статьях никто не использовал nginx). Я привык работать с nginx, да и он более современней, чем apache2, а так же написал его наш соотечественник, по этому будем использовать его в качестве веб-сервера.

Так как мы установили nginx на шаге 1, то сразу перейдем к его настройке.

Создадим отдельную директорию для отображения в браузере

sudo mkdir -p /repo/html

Сделаем симлинк зеркала в эту директорию

sudo ln -s /repo/mirror/mirror/download.astralinux.ru/astra/stable/1.8_x86-64 /repo/html/astra_1.8.6

Накинем права www-data (чтобы nginx имел туда доступ) на директорию

sudo chown -R www-data:www-data /repo/html

Альтернатива, можно создать симлинк через MC (Midnight Commander).

sudo mc

Если ошибка и ее нет, то установите (sudo apt install mc)

открыли MC

Слева директория /repo/html где будут лежать симлинки, а справа директория с репозиторием которые мы отзеркалировали на 4-ом шаге. Сейчас я покажу, как можно создать симлинки. 

Выбираем справа директорию на которую хотите сделать симлинк, потом «Файл» и «Символическая ссылка»

создание симлинка

Изменяем «Имя символической ссылки» на astra_1.8.6

изменяем имя симлинка

поменяли имя симлинка на astra_1.8.6

Получилось так

создали симлинк

Забегая немного вперед (еще не настроили nginx, по этому у вас так отображаться не будет)

будет выглядеть так

файл релиза

Внимание! Мы сделали симлинк на main ветку, а лучше делать на обе сразу, тобишь на директорию 1.8_x86-64 где лежат repository-main и repository-extended. Покажу на примере.

создаем симлинк 1.8_x86-64

То есть мы создаем симлинк директории 1.8_x86-64! Так как astra_1.8.6 уже есть в моем случае, то я создам astra_1.8.6_stable

создаем симлинк astra_1.8.6_stable

Получилось так:

получился результат

Если перейти в astra_1.8.6_stable то увидим ветки main и extended

ветки main и extended

Возвращаемся к Nginx.

Создадим новый конфиг для nginx

sudo vim /etc/nginx/sites-available/astraops-repo

и содержимое:

server {
    listen 80;
    server_name _;

    root /repo/html;
    autoindex on;

    disable_symlinks off;

    autoindex_exact_size off;
    autoindex_localtime on;

    location / {
        try_files $uri $uri/ =404;
    }
}

содержимое nginx

Что тут у нас есть:

  • listen 80 - работает по 80 порту
  • server_name - можно указать ip/имя машины или оставить _.
  •  root /repo/html; - Корневая директория для поиска файлов
  • autoindex on; - Включает вывод списка файлов
  •  disable_symlinks off; - ВАЖНО: Разрешаем nginx следовать по символическим ссылкам
  • autoindex_exact_size off; autoindex_localtime on; -- улучшаем вид листинга
  • location / { - Пытаемся отдать файл, если его нет - показываем листинг

Создаем симлинк конфига в действующие конфиги nginx.

sudo ln -s /etc/nginx/sites-available/astraops-repo /etc/nginx/sites-enabled/

создаем симлинк

Перезапускаем службу nginx

sudo systemctl restart nginx

Теперь можно идти в браузер и проверять что показывает сервер. Я уже показал на примере создания симлинка через MC. Но вставлю еще раз.

результат

Как видим, в браузере при заходе по ip адресу сервера 192.168.31.81 сразу открывается репозиторий, в котором мы создали симлинк на 1.8.6 (в данном примере я сначала создал astra_1.8.6, так как я не качал extended-repository).

6. Настройка клиента (сервер 2 (astraops-grafana))

Идем на второй сервер (клиент) (astraops-grafana) и прописываем sources.list. 

sudo vim /etc/apt/sources.list

Здесь прописан интернет-репозиторий

интернет-репозиторий

Заменяем на

локальный репозиторий

Запись получается такого рода

deb http://192.168.31.81/astra_1.8.6/main-repository     1.8_x86-64 main contrib non-free non-free-firmware
deb http://192.168.31.81/astra_1.8.6/extended-repository 1.8_x86-64 main contrib non-free non-free-firmware

Если вы делали симлинк с помощью команды или не делали название симлинка astra_1.8.6_stable.

Что мы видим, ip адрес сервера 1 (astraops-repo), далее директория astra_1.8.6 в которую если зайти, есть две поддиректории: main-repository и extended-repository

Далее запускаем обновление индексов

sudo apt update

ошибка apt update

Это нормальное поведение, так как у меня extended-repository пустой, говорил об этом ранее. То я просто закомментирую его в /etc/apt/sources.list и прогоню apt update еще раз.

ошибка ушла

Отлично, ошибка ушла и новых нет. Теперь я могу загружать пакеты со своего локального сервера и даже если пропадет интернет, то доступ к репозиторию у меня всегда будет. Так как у меня 1.8.6 сервер 2, то обновлять соответственно нечего.

Можно так же переписать под astra_1.8.6 который я создал для чисто main-repository.

переписываем /etc/apt/sources.list под main-repositoryрезультат apt update

Как видим, я вообще не указывал main-repository, а лишь astra_1.8.6 (это симлинк, который ведет на зеркало в main-repository).

Внимание! Но я рекомендую создавать структуру такую: astra_1.8.6 в которой лежат main-repository и extended-repository. Если в дальнейшем у вас будут еще версии, которые вы не хотите или не можете обновить до новой, то можно будет разбить на версии: astra_1.8.6, astra_1.8.4, astra_1.8.1 и так далее. В каждой директории у вас будут (main-repository и extended-repository).
Важное замечание про зеркало с оригинальными подписями. Если вы просто зеркалируете репозиторий, включая:
Release
Release.gpg
InRelease
Packages
Packages.gz
Sources
pool/

то клиентские машины будут проверять подпись оригинальным ключом Astra Linux, а не вашим ключом. Не нужно переподписывать официальное зеркало своим ключом, если только вы не собираете полностью собственный репозиторий-сборку

На этом часть 1 завершена. Мы с Вами создали создали на чистом сервере, локальный репозиторий, в который отзеркалировали интернет-репозиторий версии Astra Linux 1.8.6.39 и теперь можем быть суверенными от интернет репозитория и от свежих версий. Во второй части, мы создадим свой репозиторий, со своим набором пакетов.


Часть 2. Создаем локальный репозиторий

0. Создание ключей

Начнем мы с создания ключей.

Репозиторий должен быть подписан, чтобы apt на клиентских машинах мог проверить его подлинность. Создадим GPG-ключ от имени пользователя, который будет управлять репозиторием (в нашем случае - root).

sudo gpg --gen-key

Вводим имя, почту.

создание ключей gpg

Создаем «фраза-пароль»

Внимание! Запомните ее, так как вводит ее будем регулярно.

создаем фраза-пароль

Повторяем ввод:

повторяем фразу-пароль

После генерации получила основной ключ и подключ.

сгенерировали ключи

Теперь нужно узнать ID (отпечаток) ключа, он понадобится для конфигурации в дальнейшем:

sudo gpg --list-secret-keys --keyid-format LONG

Вывод будет примерно таким:

/root/.gnupg/pubring.kbx
------------------------
sec   rsa3072/BB6221A5A24B3EAD 2026-10-09 [SC] [   годен до: 2028-10-08]
      AE84190B326A5EB17B8E4946BB6221A5A24B3EAD
uid               [  абсолютно ] Andrew <astraops@local.ru>
ssb   rsa3072/FDDCAC6CEB813028 2026-10-09 [E] [   годен до: 2028-10-08]

sec - основной ключ. Он используется для подписи (флаг [SC] = Sign + Certify). Именно его нужно указывать в reprepro.

ssb - подключ. Он используется для шифрования (флаг [E]). Для подписи репозитория он не подходит.

В данном примере ID ключа - BB6221A5A24B3EAD (или полный отпечаток AE84190B326A5EB17B8E4946BB6221A5A24B3EAD).

В conf/distributions в директиве SignWith указывайте полный отпечаток основного ключа:

SignWith: AE84190B326A5EB17B8E4946BB6221A5A24B3EAD

В редких случаях, короткий может совпасть с другим ключом.

1. Настройка reprepro

Создадим директорию для настроек

sudo mkdir -p /repo/repo/conf/

Создадим конфиг distributions

sudo vim /repo/repo/conf/distributions

Скопируйте содержимое, заменив <ваш-отпечаток> на ID ключа из предыдущего пункта:

Origin: Astra Local Repository
Label: Astra Local
Codename: 1.8_x86-64
Suite: stable
Version: 1.8
Architectures: amd64
Components: main contrib non-free non-free-firmware
UDebComponents: main
Contents:
SignWith: <ваш-отпечаток>

конфиг distributions

Сохраняем и выходим.

  • Codename: 1.8_x86-64 - это кодовая строка, которая будет использоваться в sources.list на клиентах. Можно задать любое, удобное имя (например, astra-custom).
  • Components: здесь можно перечислить компоненты, которые планируете использовать. main - для ваших собственных пакетов.
  • SignWith: указываем ID GPG-ключа.

2. Инициализация репозитория

Вводим команду ниже, чтобы reprepro создал базовую структуру (dists, pool и т.д.):

sudo reprepro --ask-passphrase -b /repo/repo export

инициализация репозитория

Нас просят ввести пароль от GPG-ключа.

ввод пароль от gpg ключа

инициализация репозитория

3. Экспорт публичного ключа для клиентов

Клиентам нужен наш публичный ключ, чтобы доверять репозиторию. Экспортируем его в файл:

создадим директорию для публичного ключа

sudo mkdir -p /repo/repo/keys

экспортируем публичный ключ

sudo gpg --armor --output /repo/repo/keys/repo.gpg --export <ваш-отпечаток>

Этот файл (repo.gpg) нужно будет скопировать на каждую клиентскую машину.

экспорт публичного ключа

Скопируем ключ в /tmp и перенес на сервер 2 (astraops-grafana).

переносим клюв /tmp

перебрасываем ключ на сервер 2

Вернемся к ключу на клиенте чуть позже.

4. Настройка Nginx

Назовем свою ветку репозитория /repo.

Чтобы репозиторий был доступен по адресу http://192.168.31.81/repo/, нужно либо создать симлинк, либо настроить alias в nginx. Рекомендую симлинк - это проще и надежнее.

Создаем симлинк в корне html-директории

sudo ln -s /repo/repo /repo/html/repo

создаем симлинк repo

Проверяем, что симлинк ведет куда надо

ls -la /repo/html/repo

Перезапускаем nginx (на всякий случай).

sudo systemctl reload nginx

Проверяем в браузере

проверяем /repo в браузере

5. Настройка клиента

На клиентской машине нужно сделать две вещи:

  1. Скопировать и импортировать публичный ключ репозитория;
  2. Добавить /repo в sources.list

Возвращаемся к ключу, который мы уже закинули на сервер 2. Импортируем ключ на сервере 2 (astraops-grafana).

Внимание! Есть два метода добавления ключа. Я покажу оба, но рекомендую использовать второй, по этому просто посмотрите первый и применяйте второй.

Первый метод:

импортируем публичный ключ

Теперь необходимо прописать в sources.list новый репозиторий.

Открываем sources.list

sudo vim /etc/apt/sources.list

Вставляем

deb [signed-by=/usr/share/keyrings/astra-local.gpg] http://192.168.31.81/repo 1.8_x86-64 main contrib non-free non-free-firmware

Важные замечания:

В sources.list на клиентах вы указываете Codename (1.8_x86-64), который задали в conf/distributions. Он не обязан совпадать с версией Astra Linux.

указываем путь до ключа gpg

[signed-by=/usr/share/keyrings/astra-local.gpg]

Часть Значение
deb Бинарный репозиторий
[signed-by=...] Указывает, каким ключом проверять подпись
http://192.168.31.81/repo URL вашего репозитория (через симлинк в nginx)
1.8_x86-64 Codename из conf/distributions
main contrib non-free non-free-firmware Компоненты

Если не указать [signed-by=...], то получим следующее.

ошибка apt update

Если укажем

указываем ключ

То теперь при sudo apt update, ошибок нет.

ошибок нет

Второй метод:

Если у вас ключ лежит локально уже на машине, то можно добавить его одной командой, но запускаем рядом с ключом.

sudo gpg --no-default-keyring --keyring gnupg-ring:/etc/apt/trusted.gpg.d/repo.gpg --import repo.gpg

Накидываем права

sudo chmod 644 /etc/apt/trusted.gpg.d/repo.gpg

добавляем ключ вторым методом

Теперь необходимо прописать в sources.list новый репозиторий.

Открываем sources.list

sudo vim /etc/apt/sources.list

Вставляем

deb http://192.168.31.81/repo 1.8_x86-64 main contrib non-free non-free-firmware

Теперь убираем [signed-by=/usr/share/keyrings/astra-local.gpg]

если вы делали на первом методе.

убираем путь до ключаполучился такой путь

Проверяем, что все работает.

sudo apt update

проверяем apt update

Рассмотрим вариант, если ключ у вас на репе лежит в html. Это все еще ко второму методу относится.

Сделаем симлинк ключа на веб-сервере.

делаем симлинкпоявился ключсВидим, что ключ теперь доступен для загрузки всем.

Теперь можно загрузить и установить одной командой на любой машине:

sudo curl -s http://192.168.31.81/repo.gpg | sudo gpg --no-default-keyring --keyring gnupg-ring:/etc/apt/trusted.gpg.d/repo.gpg --import && sudo chmod 644 /etc/apt/trusted.gpg.d/repo.gpg

Данная команда загрузит с репы ключ, сразу передаст его на импорт в хранилище ключей и накинет нужные права.

Далее запускаем sudo apt update

проверка курла

Я думаю такой метод проще и лучше, чем прописывать в sources.list путь до ключа.

Теперь у нас два локальных репозитория подключено: 1 - main-repository (зеркало интернет-репозитория Astra Linux 1.8.6.39); 2 - repo (локальный наш main репозиторий с нашими пакетами).

6. Добавление deb пакетов в свой репозиторий

Давайте добавим в наш созданный репозиторий, хотя бы один пакет, для теста. Пробежавшись по загрузкам, я нашел недавно загруженный LM-Studio.deb

нашли deb пакет lm-studio

Супер, его точно нету в репозиториях астры))

Закидываем его на сервер 1 (astraops-repo).

закидываем пакет на сервер

Теперь копируем его в директорию /repo/preload

Данную директорию мы создали специально, чтобы из нее загружать новые пакеты в наш репозиторий.

копируем пакет в /preload

Теперь загрузим все пакеты из /repo/preload в наш репозиторий.

sudo reprepro --ask-passphrase -b /repo/repo includedeb 1.8_x86-64 /repo/preload/*.deb

  • 1.8_x86-64 - это Codename из файла distributions.
  • includedeb - команда для добавления бинарного пакета.

После добавления reprepro автоматически обновит индексы.

добавление пакетов deb в репозиторий

Если зайти в браузер и перейти в /repo/pool/main/l/lm-studio, то увидим наш добавленный пакет

добавленный пакет lm-studio

Идем на машину сервер 2 (astraopfs-grafana), обновляем индексы пакетов и проверяем, доступен ли lm-studio для загрузки из репозитория repo.

обновляем индексы пакетов

нам доступен lm-studio для загрузки

Отлично! Нам доступен для установки lm-studio с нашего локального репозитория. Теперь мы можем загружать любые пакеты, а так же свои сборки deb пакетов. Осталось распространить свой локальный репозиторий с ключом на условные 30 машин. Можно сделать вручную, можно написать скрипт, можно через Ansible, Puppet, Kaspersky. Как фантазия сработает! Я надеюсь, что данная статья была для Вас полезна! Увидимся в следующих статьях, удачи!

0
Andrew

DevOps Engineer

1 50 статей
Комментарии (0)
Войдите, чтобы оставить комментарий

Пока нет комментариев. Будьте первым!