Перекрестное опыление: управляем Linux из-под Windows, и наоборот
В прошлой статье я обещал рассмотреть механизм удаленного подключения с Windows на серверы под управлением *nix, и наоборот при помощи PowerShell. Обещанного обычно ждут три года, но я успел чуть раньше. Что ж, если хочется с верного макбука управлять гетерогенной инфраструктурой, или наоборот ― с Surface Pro рулить Linux-серверами без всяких putty, ― прошу под кат.
Microsoft Loves Linux
Еще в 2015 году Microsoft торжественно объявила о запуске программы «Microsoft Linux». Сюда вошла как банальная поддержка гостевых *nix-like OS на Hyper-V, так и встроенная в Windows 10 Ubuntu и возможность запуска в Docker продуктов Microsoft, таких как SQL Server.
Компания также опубликовала исходный код PowerShell, что позволило запускать «Ракушку Мощи» не только на Windows. Из-под одноименного аккаунта на Github, помимо исходного кода, выложены и бинарники под большинство современных систем (лицензия MIT).
Это позволяет настроить удаленное управление с помощью единого инструмента ― PowerShell. Помимо подключения к консоли компьютера, можно запускать отдельные команды, в том числе и на нескольких серверах одновременно. Довольно удобно для автоматизации задач администрирования, таких как массовое изменение настроек, инвентаризация, сбор логов.
Порой удобно совмещать традиционные консольные команды со вставками PowerShell:
Для подключения к Windows-машинам при помощи PowerShell используется протокол WS-Man. Для GNU\Linux привычен SSH. Так как сегодня становятся универсальными оба протокола, разберем их подробнее.
PowerShell 6.0 под Windows и *nix, пока еще находится в бете. Поэтому не рекомендую без хорошего тестирования применять на боевых серверах описанное ниже.
Магомед не идет к горе
Когда технология удаленного доступа при помощи PowerShell только набирала обороты, единственным универсальным способом подключения к разным системам был протокол WS-Man. Для тестового стенда я взял Windows Server 2016 и Centos 7, для которых и буду настраивать возможность удаленного подключения и выполнения команд при помощи этого протокола.
Для начала установим на Centos свежий PowerShell:
После установки появилась возможность запускать привычные Windows-администратору командлеты. Например, посмотрим версию PS и получим список запущенных процессов командлетами $PSVersionTable и Get-Process:
Работаем в консоли PowerShell на CentOS.
Чтобы подключаться к Linux-машине с консоли Windows, нам понадобится установить и настроить:
- OMI (Open Management Infrastructure) ― адаптация WMI, которую также можно использовать для управления компьютерами с ОС, отличными от Windows;
- PSRP (PowerShell Remoting Protocol) ― библиотека, необходимая для удаленного подключения PowerShell.
Подробно с работой и эволюцией OMI и PSRP можно ознакомиться в отличном материале от Matt Wrock, я же просто установлю OMI командой:
Далее нужно настроить порты и аутентификацию в конфигурационном файле /etc/opt/omi/conf/omiserver.conf, после чего перезапустить сервер командой:
Для упрощения эксперимента я не буду настраивать ни NTLM-аутентификацию, ни Kerberos. Еще и шифрование отключу ― разумеется, в боевой среде делать этого не стоит. Для включения текстовой аутентификации и шифрования на стороне Windows в работе winrm достаточно выполнить следующие команды:
После настройки можно проверить работу OMI из консоли Windows:
Подключаемся к CentOS из cmd.
Теперь проверим работу обратным подключением ― из Linux к Windows:
… а затем с CentOS подключаемся к Windows.
После того, как WMI\OMI заработал, нужно установить и настроить PSRP. К сожалению и вопреки инструкции, бинарник отсутствует. Библиотеку пришлось компилировать, долго и нудно исправляя возникающие ошибки зависимостей:
Теперь мы сможем подключаться с Windows на Linux и наоборот при помощи PowerShell. Начнем с Windows на Linux:
С Windows на Linux.
Аналогичным образом можно провести и обратное подключение.
Invoke-Command можно «натравить» на список компьютеров, и с рабочей станции Windows создать пользователя на всех серверах Linux командой вида:
Надо сказать, что способ не самый удобный и эффективный. Минусов добавляет компиляция библиотек, разнообразные баги ― например, на момент написания статьи PSRP не позволял нормально подключиться из Linux в Windows.
Да и сами разработчики рекомендуют не плясать вокруг WS-Man, а обратиться к проверенному способу ― SSH. Что ж, попробуем и его.
Гора идет к Магомету
На этот раз машина с Windows получит чуть больше специфической подготовки ― нужно установить свежий PowerShell и OpenSSH.
После можно проверить синтаксис командлета New-PSSession. Если все произошло как надо, то командлет, помимо привычного параметра ComputerName, будет поддерживать и HostName.
PowerShell 6.0.0-beta.9 и обновленный синтаксис командлета.
Качаем последний релиз или используем пакет из репозитория Chocolatey. Все это разархивируем в \Program Files\OpenSSH.
В консоли с правами администратора переходим в папку с разархивированным содержимым и запускаем установку командой:
Теперь генерируем ключи:
В тестовой среде мы будем использовать парольную аутентификацию, поэтому стоит убедиться что она включена в файле sshd_config:
Если вы также хотите автоматически запускать PowerShell при подключении по SSH, то в параметре subsystem нужно прописать путь к желаемой версии PS:
Для работы клиента SSH нужно добавить директорию в %PATH% любым удобным способом. Например, таким:
Остается только настроить и запустить службы:
После установки уже можно наслаждаться подключением к серверу Windows по ssh.
C Windows через Putty на Linux, с Linux обратно на Windows по SSH.
На достигнутом останавливаться не будем и перейдем к настройке Linux. При настройке сервера SSH по умолчанию достаточно прописать PowerShell в Subsystem:
Теперь проверим подключение через командлет New-PSSession и Invoke-Command.
Работаем из PowerShell с Linux-сервером.
Теперь подключимся из Linux к Windows:
Работаем из PowerShell с Windows-сервером.
В отличие от WS-Man, SSH настраивается намного проще и работает стабильнее. Да и беспарольное подключение по ключам настраивать привычнее.
В хозяйстве пригодится
С однозначным «советом потребителю» все опять сложно: SSH проще в настройке и стабильнее, но WS-Man использует API и позволяет применять инструменты вроде JEA. На боевых серверах использовать WS-Man я бы не стал однозначно, а вот реализация OpenSSH в Windows как сервера, так и клиента мне понравилась. Для самопальной автоматизации вполне подойдет даже без PowerShell.
В любом случае, границы между Linux и Windows хоть и медленно, но начинают стираться, что безусловно радует.
Источник
Интегрируем команды Linux в Windows с помощью PowerShell и WSL
Типичный вопрос разработчиков под Windows: «Почему здесь до сих пор нет ?». Будь то мощное пролистывание less или привычные инструменты grep или sed , разработчики под Windows хотят получить лёгкий доступ к этим командам в повседневной работе.
Подсистема Windows для Linux (WSL) сделала огромный шаг вперёд в этом отношении. Она позволяет вызывать команды Linux из Windows, проксируя их через wsl.exe (например, wsl ls ). Хотя это значительное улучшение, но такой вариант страдает от ряда недостатков.
- Повсеместное добавление wsl утомительно и неестественно.
- Пути Windows в аргументах не всегда срабатывают, потому что обратные слэши интерпретируются как escape-символы, а не разделители каталогов.
- Пути Windows в аргументах не переводятся в соответствующую точку монтирования в WSL.
- Не учитываются параметры по умолчанию в профилях WSL с алиасами и переменными окружения.
- Не поддерживается завершение путей Linux.
- Не поддерживается завершение команд.
- Не поддерживается завершение аргументов.
В результате команды Linux воспринимаются под Windows как граждане второго сорта — и их сложнее использовать, чем родные команды. Чтобы уравнять их в правах, нужно решить перечисленные проблемы.
Оболочки функций PowerShell
C помощью оболочек функций PowerShell мы можем добавить автозавершение команд и устранить необходимость в префиксах wsl , транслируя пути Windows в пути WSL. Основные требования к оболочкам:
- Для каждой команды Linux должна быть одна оболочка функции с тем же именем.
- Оболочка должна распознавать пути Windows, переданные в качестве аргументов, и преобразовывать их в пути WSL.
- Оболочка должна вызывать wsl с соответствующей командой Linux на любой вход конвейера и передавая любые аргументы командной строки, переданные функции.
Поскольку этот шаблон может быть применён к любой команде, мы можем абстрагировать определение этих оболочек и динамически генерировать их из списка команд для импорта.
Список $command определяет команды для импорта. Затем мы динамически генерируем обёртку функции для каждой из них, используя команду Invoke-Expression (сначала удалив любые алиасы, которые будут конфликтовать с функцией).
Функция перебирает аргументы командной строки, определяет пути Windows с помощью команд Split-Path и Test-Path , а затем преобразует эти пути в пути WSL. Мы запускаем пути через вспомогательную функцию Format-WslArgument , которую определим позже. Она экранирует специальные символы, такие как пробелы и скобки, которые в противном случае были бы неверно истолкованы.
Наконец, передаём wsl входные данные конвейера и любые аргументы командной строки.
С помощью таких обёрток можно вызывать любимые команды Linux более естественным способом, не добавляя префикс wsl и не беспокоясь о том, как преобразуются пути:
- man bash
- less -i $profile.CurrentUserAllHosts
- ls -Al C:\Windows\ | less
- grep -Ein error *.log
- tail -f *.log
Здесь показан базовый набор команд, но вы можете создать оболочку для любой команды Linux, просто добавив её в список. Если вы добавите этот код в свой профиль PowerShell, эти команды будут доступны вам в каждом сеансе PowerShell, как и нативные команды!
Параметры по умолчанию
В Linux принято определять алиасы и/или переменные окружения в профилях (login profile), задавая параметры по умолчанию для часто используемых команд (например, alias ls=ls -AFh или export LESS=-i ). Один из недостатков проксирования через неинтерактивную оболочку wsl.exe — то, что профили не загружаются, поэтому эти параметры по умолчанию недоступны (т. е. ls в WSL и wsl ls будут вести себя по-разному с алиасом, определённым выше).
PowerShell предоставляет $PSDefaultParameterValues, стандартный механизм для определения параметров по умолчанию, но только для командлетов и расширенных функций. Конечно, можно из наших оболочек сделать расширенные функции, но это вносит лишние осложнения (так, PowerShell соотносит частичные имена параметров (например, -a соотносится с -ArgumentList ), которые будут конфликтовать с командами Linux, принимающими частичные имена в качестве аргументов), а синтаксис для определения значений по умолчанию будет не самым подходящим (для определения аргументов по умолчанию требуется имя параметра в ключе, а не только имя команды).
Однако с небольшим изменением наших оболочек мы можем внедрить модель, аналогичную $PSDefaultParameterValues , и включить параметры по умолчанию для команд Linux!
Передавая $WslDefaultParameterValues в командную строку, мы отправляем параметры через wsl.exe . Ниже показано, как добавить инструкции в профиль PowerShell для настройки параметров по умолчанию. Теперь мы можем это сделать!
Поскольку параметры моделируются после $PSDefaultParameterValues , вы можете легко их отключить на время, установив ключ «Disabled» в значение $true . Дополнительное преимущество отдельной хэш-таблицы в возможности отключить $WslDefaultParameterValues отдельно от $PSDefaultParameterValues .
Автозавершение аргументов
PowerShell позволяет регистрировать завершители аргументов с помощью команды Register-ArgumentCompleter . В Bash есть мощные программируемые средства для автозавершения. WSL позволяет вызывать bash из PowerShell. Если мы можем зарегистрировать завершители аргументов для наших оболочек функций PowerShell и вызвать bash для создания завершений, то получим полное автозавершение аргументов с той же точностью, что и в самом bash!
Код немного плотный без понимания некоторых внутренних функций bash, но в основном мы делаем следующее:
- Регистрируем завершатель аргументов для всех наших обёрток функций, передавая список $commands в параметр -CommandName для Register-ArgumentCompleter .
- Сопоставляем каждую команду с функцией оболочки, которую использует bash для автозавершения (для определения спецификаций автозавершения в bash используется $F , сокращение от complete -F ).
- Преобразуем аргументы PowerShell $wordToComplete , $commandAst и $cursorPosition в формат, ожидаемый функциями автозавершения bash в соответствии со спецификациями программируемого автозавершения bash.
- Составляем командную строку для передачи в wsl.exe , который обеспечивает правильную настройку среды, вызывает соответствующую функцию автозавершения и выводит результаты с разбиением по строкам.
- Затем вызываем wsl с командной строкой, разделяем выдачу разделителями строк и генерируем для каждой CompletionResults , сортируя их и экранируя символы, такие как пробелы и скобки, которые в противном случае были бы неверно истолкованы.
В итоге наши оболочки команд Linux будут использовать точно такое же автозавершение, как в bash! Например:
- ssh -c -J -m -O -o -Q -w -b
Каждое автозавершение подоставляет значения, специфичные для предыдущего аргумента, считывая данные конфигурации, такие как известные хосты, из WSL!
будет циклически перебирать параметры. покажет все доступные опции.
Кроме того, поскольку теперь у нас работает автозавершение bash, вы можете автозавершать пути Linux непосредственно в PowerShell!
/.bash
В тех случаях, когда автозавершение bash не даёт никаких результатов, PowerShell возвращается к системе по умолчанию с путями Windows. Таким образом, вы на практике можете одновременно использовать и те, и другие пути на своё усмотрение.
Заключение
С помощью PowerShell и WSL мы можем интегрировать команды Linux в Windows как нативные приложения. Нет необходимости искать билды Win32 или утилиты Linux или прерывать рабочий процесс, переходя в Linux-шелл. Просто установите WSL, настройте профиль PowerShell и перечислите команды, которые хотите импортировать! Богатое автозавершение для параметров команд и путей к файлам Linux и Windows — это функциональность, которой сегодня нет даже в нативных командах Windows.
Полный исходный код, описанный выше, а также дополнительные рекомендации по его включению в рабочий процесс доступны здесь.
Какие команды Linux вы считаете наиболее полезными? Каких ещё привычных вещей не хватает при работе в Windows? Пишите в комментариях или на GitHub!
Источник