Автоматизація системного адміністрування за допомогою ssh і scp
Якщо Вам доводиться адмініструвати велику кількість Linux / Unix систем, Вам напевно потрібні скрипти для автоматизації деяких процесів. У процесі щоденної роботи Ви повинні були помітити, що Вам доводиться виконувати одні і ті ж, або схожі дії на кожній системі. Можливо Ви замислювалися про способи автоматизації цих процесів. Це особливо вірно при обслуговуванні великої кількості однаково сконфігурованих Linux / Unix систем. У цій статті я покажу, як це можна зробити за допомогою утиліт ssh.
Ідея в тому, щоб знайти спосіб скопіювати деякі файли з робочої станції, перед якою я сиджу зараз на кілька робочих станцій або серверів, а потім виконати на цих машинах деякі команди на зразок установки rpm пакетів або внесення певних настройок системи. Іноді нам треба спочатку виконати на цих машинах деякі команди, а потім отримати файли - результат виконання цих команд.
Щоб скористатися цією статтею необхідно розуміння основ програмування в оболонці. Інформацію про програмування в оболонці см. В статті Каті і Гвідо Сочер (Katja and Guido Socher) в LinuxFocus Shell Programming. Вам, також, буде потрібно знання утиліт ssh, таких як ssh-keygen, ssh-add, ssh, scp або sftp. Є вільна реалізація протоколу SSH під Linux: OpenSSH. що містить всі ці інструменти. Є і сторінки керівництва (man pages).
Чому ssh?
Питанням на питання: А чому ні? Можна використовувати rsh-rcp або telnet-ftp, але вони не підходять для небезпечної середовища, такий, як Інтернет, а, можливо, і інтранет. Ssh забезпечує захищену шифровану зв'язок двох комп'ютерів в незахищеній мережі. Я не збираюся обговорювати питання безпеки при використанні цих інструментів. Прочитайте статтю Джорджа Тарбуріча (Georges Tarbouriech) Through the tunnel (Крізь тунель).
Насправді я, в минулому, використовував скрипти на основі telnet / ftp.
Щоб скопіювати один файл з локального каталогу на віддалений комп'ютер можна скористатися командою:
scp / path / to / the / file / file1 user @ remote_host: / remotedir / newfile
У цьому прикладі файл file1 копіюється з локального каталогу на віддалений комп'ютер (remote_host може бути або IP або ім'я віддаленого комп'ютера) в каталог / remotedir під новим ім'ям newfile. Видається запрошення до аутентифікації під ім'ям 'user'. У разі вдалої аутентифікації і якщо користувач має відповідні права, файл буде скопійований. Можна не ставити нове ім'я файлу. У цьому випадку файл буде скопійований під старим іменем. Коротше, це означає, що при копіюванні файл можна перейменувати.
Зворотна операція теж можлива: можна скопіювати файл з віддаленого комп'ютера в локальний каталог:
scp user @ remote_host: / remotedir / file / path / to / local / folder / newfile
Є, також, дуже зручний варіант команди scp. Вказавши ключ '-r' Ви можете копіювати каталоги рекурсивно.
scp -r user @ remote_host: / remotedir.
Ця команда копіює каталог 'remotedir' і все його підкаталоги і файли з віддаленого комп'ютера в поточний робочий каталог під тим же ім'ям.
Примітка: Передбачається, що на віддаленому комп'ютері виконується демон sshd.
Дистанційна реєстрація за допомогою ssh
Замість rlogin або telnet можна скористатися більш безпечним способом - ssh:
Виконання команд з ssh
Є можливість за допомогою ssh виконувати на віддаленому комп'ютері команди:
ssh [email protected] df -H
Це дуже схоже на синтаксис віддаленої реєстрації. Відмінності починаються після імені комп'ютера. Видається команда (в цьому прикладі 'df -H') для виконання на віддаленому комп'ютері. Висновок команди буде відображений на Вашому терміналі.
Підключення до віддаленого комп'ютера без пароля
Замість використання аутентифікації по паролю можна використовувати пару ключів (публічний / приватний). Вам треба згенерувати пару ключів. Є утиліта ssh-keygen, яку можна використовувати для генерації ключів для ssh:
ssh-keygen -b 1 024 -t dsa
У Вас буде запитано ім'я приватного ключа. Ім'я публічного ключа зазвичай той же, що і приватного ключа з добавкою '.pub'. Тут '-b 1 024' це кількість біт створюваного ключа. Якщо це значення не вказано, буде використано значення за замовчуванням. '-t dsa' задає тип створюваного ключа. Можливі значення: 'rsa1' для протоколу версії 1 і 'rsa' або 'dsa' для протоколу версії 2. Я б рекомендував використання версії 2 протоколу SSH. Але якщо у Вас є старі сервери, що підтримують тільки протокол версії 1, Вам треба вказати '-t rsa1' для створення іншої пари ключів. Вказавши '-1' або '-2' Ви можете змусити ssh протокол версії 1 або 2 відповідно.
Щоб скористатися ключем, Вам треба встановити свій публічний ключ на віддалений комп'ютер. Вміст файлу публічного ключа має бути скопійовано або додано в файл
$ HOME / .ssh / authorized_keys або $ HOME / .ssh / authorized_keys2. Будьте уважні і не змішуйте ключі для різних версій протоколу. Для протоколу версії 1 використовується authorized_keys, а для протоколу версії 2 використовується authorized_keys2. Якщо Ви правильно встановили свій публічний ключ, в перший же раз, коли Ви підключіться до цього комп'ютера, буде запрошена Ваша парольний фраза (passphrase), а в разі відмови, буде запропоновано ввести відповідний пароль віддаленого користувача. Ви можете обмежити підключення до Вашої системі тільки використанням аутентифікації по публічному ключу, відредагувавши конфігураційний файл sshd. ім'я файлу
/ Etc / ssh / sshd_config а найменування параметра, який Вам треба змінити 'PasswordAuthentication'. Замініть цей параметр на no (PasswordAuthentication no) і перезапустіть sshd.
До цього моменту всі добре. У нас є безпечний спосіб копіювання і виконання команд на віддалених системах. Але автоматизуючи деякі завдання ми не повинні вводити ні паролів, ні пральних фраз. Інакше ми нічого не зможемо автоматизувати. Звичайно можна було б вписати в кожен скрипт необхідні паролі, але це не дуже гарна ідея. Краще доручити агенту ключів (key-agent) взяти на себе турботу про наших пральних фразах. ssh-agent - це програма, призначена для зберігання приватних ключів, використовуваних для аутентифікації по публічному ключу. Треба запустити агент ключів:
і додати Ваші приватні ключі, які слід використовувати
id_dsa - це файл приватного ключа DSA, а identity - файл приватного ключа RSA1. Це - імена файлів за замовчуванням, дані при генерації ключів за допомогою ssh-keygen. Звичайно, у Вас буде запрошена парольний фраза, перш ніж ssh-add додасть Ваш ключ до агента ключів. Список доданих ключів можна отримати за допомогою команди:
При використанні ssh-agent описаним вище способом, їм можна користуватися тільки з терміналу, в якому він був запущений. Щоб використовувати ssh-agent з будь-якого відкривається Вами терміналу доведеться потрудитися трохи більше. Я написав такий невеликий скрипт для запуску агента:
Якщо агент запущений і виконується Ви можете додавати до нього свої ключі. Але перед цим Ви повинні виконати файл agent_info, щоб утиліти ssh знали, де розташований Ваш агент:
І додати свої ключі за допомогою ssh-add. Можна додати в файл .bashrc кілька рядків так, щоб кожен раз при відкритті нового терміналу виконувався файл agent_info:
УВАГА: Ви повинні убезпечити комп'ютер, на якому використовуєте ssh-agent і скрипт автоматизації, який я тут опишу. Інакше, якщо хто-небудь отримає доступ до вашого облікового запису, він отримає доступ до всіх серверів, з якими Ви спілкуєтеся за допомогою ключів ssh. За все доводиться платити!
Тепер пора пояснити, як ми збираємося автоматизувати деякі із завдань системного адміністратора. Ідея полягає в тому, щоб виконати певну множину команд на певному безлічі хостів і скопіювати деякі файли на або з цих хостів. Це те, чим часто доводиться займатися системним адміністраторам. Ось цей скрипт:
Давайте запишемо скрипт ainstal.sh (automated installation - автоматизована установка) і спробуємо виконати його без параметрів. Ми отримаємо повідомлення:
Відповідно до цим повідомленням, якщо Ви не хочете виконувати команди, дайте аргументу commands.txt ім'я commands_empty.txt, а якщо не хочете пересилати ніяких файлів, дайте аргументу files_file ім'я files_empty.txt. Іноді, адже, потрібно тільки виконати кілька команд, а в інших випадках тільки переслати кілька файлів.
Перед тим, як дати порядкове пояснення скрипта, дамо приклад його використання: Припустимо, Ви додали в мережу вторинний DNS сервер і хотіли б додати його в файл /etc/resolv.conf. Для простоти припустимо, що на всіх Ваших комп'ютерах однаковий файл resolv.conf. У цьому випадку єдине, що Вам треба зробити, це скопіювати новий файл resolv.conf на всі комп'ютери.
Перше, що Вам потрібно - це список хостів. Запишемо їх все в файл hosts.txt. Формат цього файлу такий, що кожен рядок містить ім'я або IP тільки одного хоста. Ось приклад:
Як видно з прикладу, можна вказувати повністю кваліфіковані імена або тільки частина, що визначає ім'я комп'ютера. Крім того, Вам буде потрібно файл, в якому будуть записані імена файлів, які треба передати. Можливі два типи передачі:
- З локального хоста на хости, перераховані у файлі hosts.txt. Це той тип передачі, який нам потрібен.
- З кожного з хостів, перерахованих у файлі hosts.txt на локальний хост. Це в тому випадку, коли нам треба отримати деякі файли з кожного з хостів. Наприклад, при використанні простого скрипта резервного копіювання, який я опишу нижче в цій статті.
Файли, які треба передати, перераховані в іншому файлі. Давайте назвемо цей файл files_file.txt. Формат files_file.txt такий: Кожен рядок містить інформацію про копіювання тільки одного файлу. Можливі два напрямки копіювання: l2r (local to remote - з локального на віддалений) і r2l (remote to local - з віддаленого на локальний). l2r - це коли файл копіюється з локального хоста на віддалений. r2l - коли файл з віддаленого хоста копіюється на локальний. Після ключового слова напрямки слідують два імені файлу. Поля розділяються пробілами або табуляціями. Перший файл копіюється в другій відповідно до ключовим словом напрямки. Файл для віддаленого хоста повинно бути повністю кваліфікованим, інакше файл буде скопійований в домашній каталог користувача root. Ось наш files_file.txt:
Як бачите, я включив в файл опис його структури. Зазвичай я включаю це опис в кожен файл files_file.txt, який використовую. Це просте, але гарне рішення для документування. У цьому прикладі ми хочемо скопіювати файл resolv.conf на віддалений комп'ютер під ім'ям /etc/resolv.conf. У демонстраційних цілях після копіювання файлу на цільові комп'ютери я додав команди зміни власника і групи файлу і відображення вмісту /etc/resolv.conf. Команди, які треба виконати, поміщаються в окремий файл. Давайте назвемо його commands_file.txt. Ось наш файл commands_file.txt:
Файл команд містить команди, які повинні бути виконані на кожному комп'ютері, перерахованому у файлі hosts.txt. Команди виконуються послідовно, це означає, що спочатку виконується перша команда, потім друга і так далі.
Добре, тепер у нас є всі файли, необхідні для цього простого прикладу. Єдине, що залишилося, це вказати режим, який визначає, який з двох файлів: commands_file.txt або files_file.txt повинен оброблятися в першу чергу. Можна передати файли, перераховані у файлі files_file.txt file, а потім виконати всі команди на цільовому комп'ютері, це режим 1. Чи навпаки, виконати команди, а потім передати файли, це режим 2. Тепер можна виконати скрипт з необхідними аргументами, ось так :
/ainstall.sh 1 hosts.txt files_file.txt commands_file.txt
Невеликий рада: зазвичай ім'я файлу files.txt я починаю з files_ і додаю короткий описову назву, наприклад, files_resolvconf.txt. Подібним же чином я називаю hosts.txt і commands.txt.
/.ssh/agent_info ', він виконується. Цей файл містить інформацію про запущений у Вас агента ssh. Якщо Ви не користуєтеся агентом, Вам доведеться ввести пароль або парольний фразу вручну, що означає ніякої автоматики :). Потім кожен файл (hosts, files і commands) перевіряється на існування. Є, також, спеціальна перевірка на files_empty.txt і commands_empty.txt. Якщо Ви вказали таке ім'я, то перевірка на існування не потрібна. Я змінив цю частину скрипта при написанні цієї статті. Раніше було тільки:
Просте резервування конфігураційних файлів
Тут представлено більш складне використання цього скрипта. Ідея полягає в тому, щоб зробити резервні копії конфігураційних файлів всіх Ваших комп'ютерів або серверів. З цією метою я написав невеличкий скрипт, який використовує ainstall.sh:
У Вас повинен бути створений спеціальний каталог під ім'ям servers. У цьому каталозі повинні бути два файли: files_getbackup.txt і ll_servers.txt. Ось файл 'files_getbackup.txt':
r2l /root/backup.tgz backup.tgz
'Ll_servers.txt' містить імена або IP хостів, які необхідно резервувати. Кожному хосту, перерахованого в файлі 'll_servers.txt', повинен відповідати каталог з таким же ім'ям, в якому повинен бути файл commands_make_backups.txt, що містить команди для створення архіву /root/backup.tgz з конфігураційних файлів цього хоста. І каталог під ім'ям backup. Всі резервні файли цього хоста будуть зберігатися в цьому каталозі. Файл ll_servers.txt містить: