pass. Хранение ключей ssh

2026-07-27 · 4 мин. для прочтения
blog computer-science

pass. Хранение ключей ssh.

Содержание

1 Общая информация

  • Хранение SSH-ключей с разной привязкой (к хостам, сервисам, проектам) в pass, gopass.

2 Иерархия хранения

  • Используем следующие пространства:

    • ssh/machines/<hostname>/ : ключи, созданные на конкретном хосте.
      • Эти ключи обычно используются для аутентификации этой машины на других серверах или сервисах.
    • ssh/hosts/ : ключи, привязанные к конкретным хостам.
    • ssh/services/ : ключи, относящиеся к конкретным сервисам (git, GitHub, GitLab), которые могут использоваться на разных хостах.
    • ssh/default : ключ по умолчанию (если используется).
  • Пример структуры:

ssh/
├── machines/
│   ├── laptop/
│   │   ├── id_ed25519
│   │   └── id_ed25519.pub
│   ├── server-01/
│   │   ├── id_rsa
│   │   └── id_rsa.pub
│   └── desktop/
│       ├── id_ecdsa
│       └── id_ecdsa.pub
├── hosts/
│   ├── prod-web-01/
│   │   ├── id_rsa
│   │   └── id_rsa.pub
│   └── bastion/
│       ├── id_ed25519
│       └── id_ed25519.pub
└── services/
    ├── github/
    │   ├── id_rsa
    │   └── id_rsa.pub
    ├── gitlab/
    │   ├── id_ecdsa
    │   └── id_ecdsa.pub
    └── aws/
        ├── id_rsa
        └── id_rsa.pub

3 Добавление ключей

  • Для каждого ключа можно выполнить добавление через редактор:

    # Создать запись для приватного ключа
    gopass insert ssh/machines/laptop/id_rsa
    # Вставить содержимое файла ~/.ssh/id_rsa (включая BEGIN/END)
    
    # Создать запись для публичного ключа
    gopass insert ssh/machines/laptop/id_rsa.pub
    # Вставить содержимое соответствующего .pub
    
  • Можно выполнить копированием из файла напрямую:

    gopass insert -f ssh/machines/laptop/id_ed25519 < ~/.ssh/id_ed25519
    gopass insert -f ssh/machines/laptop/id_ed25519.pub < ~/.ssh/id_ed25519.pub
    
    • Флаг -f заставит перезаписать запись, если она уже существует.
  • Аналогично для сервисов:

    gopass insert -f ssh/services/github/id_ed25519 < ~/.ssh/id_ed25519_github
    gopass insert -f ssh/services/github/id_ed25519.pub < ~/.ssh/id_ed25519_github.pub
    

4 Извлечение ключей

4.1 Сохранение в файл

  • Можно восстановить SSH-ключи из gopass в каталог ~/.ssh.

  • Посмотрите список сохранённых ключей:

    gopass list ssh/
    
  • Для каждого приватного ключа:

    gopass show ssh/machines/laptop/id_rsa > ~/.ssh/id_rsa
    chmod 600 ~/.ssh/id_rsa
    
  • Для каждого публичного ключа:

    gopass show ssh/machines/laptop/id_rsa.pub > ~/.ssh/id_rsa.pub
    chmod 644 ~/.ssh/id_rsa.pub
    
  • Восстановить сервисные ключи:

    # Восстановить ключ для GitHub
    gopass show ssh/services/github/id_ed25519 > ~/.ssh/id_ed25519_github
    chmod 600 ~/.ssh/id_ed25519_github
    gopass show ssh/services/github/id_ed25519.pub > ~/.ssh/id_ed25519_github.pub
    chmod 644 ~/.ssh/id_ed25519_github.pub
    
  • Чтобы восстановить все ключи сразу, можно использовать скрипт:

#!/bin/bash
# restore_all_ssh_keys.sh

SSH_DIR="$HOME/.ssh"
mkdir -p "$SSH_DIR"

# 1. Восстанавливаем ключ текущей машины
HOSTNAME=$(hostname -s)
MACHINE_PATH="ssh/machines/$HOSTNAME"
for key in $(gopass list "$MACHINE_PATH/" | grep -v '\.pub$'); do
    BASENAME=$(basename "$key")
    DEST="$SSH_DIR/$BASENAME"
    echo "Восстановление машины: $key -> $DEST"
    gopass show "$key" > "$DEST"
    chmod 600 "$DEST"
    # публичный
    pub="${key}.pub"
    if gopass show "$pub" &>/dev/null; then
        gopass show "$pub" > "$SSH_DIR/${BASENAME}.pub"
        chmod 644 "$SSH_DIR/${BASENAME}.pub"
    fi
done

# 2. Восстанавливаем все сервисные ключи
SERVICE_PATH="ssh/services"
for key in $(gopass list "$SERVICE_PATH/" | grep -v '\.pub$'); do
    BASENAME=$(basename "$key")
    # Добавляем суффикс сервиса, чтобы не конфликтовать с ключами машин
    SERVICE_NAME=$(echo "$key" | sed -E "s|^$SERVICE_PATH/([^/]+)/.*|\1|")
    DEST="$SSH_DIR/${BASENAME}_${SERVICE_NAME}"
    echo "Восстановление сервиса: $key -> $DEST"
    gopass show "$key" > "$DEST"
    chmod 600 "$DEST"
    # публичный
    pub="${key}.pub"
    if gopass show "$pub" &>/dev/null; then
        gopass show "$pub" > "$SSH_DIR/${BASENAME}_${SERVICE_NAME}.pub"
        chmod 644 "$SSH_DIR/${BASENAME}_${SERVICE_NAME}.pub"
    fi
done

echo "Готово. Ключи восстановлены в $SSH_DIR"

4.2 Вручную – для подключения по SSH

  • Если нужно подключиться к хосту, можно временно извлечь ключ в файл:

    gopass show ssh/hosts/prod-web-01/id_rsa > /tmp/prod_rsa
    chmod 600 /tmp/prod_rsa
    ssh -i /tmp/prod_rsa user@prod-web-01
    
  • Через ssh-agent (см. Агент для ключей ssh-agent):

    # Добавить ключ в агент, не сохраняя на диск
    gopass show ssh/hosts/prod-web-01/id_rsa | ssh-add -
    # Затем обычный ssh без -i
    ssh user@prod-web-01
    

4.3 Автоматический выбор ключа через ~/.ssh/config

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

  • Чтобы не хранить ключи на диске, можно использовать скрипт-обёртку, который извлекает ключ из gopass и передаёт его SSH.

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

  • Скрипт /usr/local/bin/ssh-with-gopass:

#!/bin/bash
# Использование: ssh-with-gopass user@host
HOST=$1
# Извлекаем ключ для этого хоста из gopass (если есть)
KEY=$(gopass show ssh/hosts/$HOST/id_rsa 2>/dev/null)
if [ $? -eq 0 ]; then
    # Передаём ключ через временный файл или напрямую в ssh -i
    echo "$KEY" > /tmp/ssh_key_$$ && chmod 600 /tmp/ssh_key_$$
    ssh -i /tmp/ssh_key_$$ "$@"
    rm -f /tmp/ssh_key_$$
else
    # Если нет ключа для хоста, пробуем ключ по умолчанию
    ssh "$@"
fi
  • Можно добавить ключи в агент при старте сессии:

    # Добавить все ключи из gopass (или выборочно) в агент
    for key in $(gopass list ssh/hosts/ | grep -v '.pub$'); do
        gopass show "$key" | ssh-add -
    done
    for key in $(gopass list ssh/services/ | grep -v '.pub$'); do
        gopass show "$key" | ssh-add -
    done
    
    • Эту команду можно поместить в .bashrc или .profile.
Дмитрий Сергеевич Кулябов
Authors
Профессор кафедры теории вероятностей и кибербезопасности
Работаю профессором на кафедре теории вероятностей и кибербезопасности Российского университета дружбы народов им. Патриса Лумумбы. Научные интересы относятся к области теоретической физики и математического моделирования.