Крутые лайфхаки для работы с WSL (Подсистема Windows для Linux )
Я глубоко погружен в WSL (Windows Subsystem для Linux), и теперь, когда WSL2 доступен в Windows Insiders, это отличное время, чтобы по-настоящему изучить доступные опции. Очень интересная фича, которую я нашел в WSL, — возможность «чисто» перемещать данные между мирами. Это не тот опыт, который вы легко можете получить с полноценными виртуальными машинами, и он говорит о тесной интеграции Linux и Windows.
Под катом подробнее о некоторых интересных вещах, которые вы можете делать, смешивая арахисовое масло и шоколад!
Запустите Windows Explorer из Linux и получите доступ к файлам вашего дистрибутива
Используйте настоящие команды Linux (не CGYWIN) из Windows
Я уже писал об этом раньше, но теперь есть алиасы для функций PowerShell, которые позволяют вам использовать настоящие команды Linux изнутри Windows.
Вы можете вызвать любую команду Linux напрямую из DOS/Windows/чего угодно, просто поместив ее после WSL.exe, вот так.
Запустите Visual Studio Code и получите доступ к вашим приложениям Linux нативно на Windows
Вы можете запустить «code.», находясь в папке в WSL, и вам будет предложено установить расширения VS Remote.. Это эффективно разделяет Visual Studio Code пополам и запускает «headless» VS Code Server в Linux с клиентом VS Code в мире Windows.
Вам также необходимо установить Visual Studio Code и расширение Remote — WSL. При желании, установите бета-версию Windows Terminal для лучшего опыта работы с терминалом в Windows.
Вот отличная подборка статей из блога Windows Command Line.
Запуск нескольких Linux в считанные секунды
Я могу легко запустить их, а также назначить профили, чтобы они появлялись в моем Windows Terminal.
Запустите X Windows Server под Windows с Pengwin
Простое перемещение дистрибутивов WSL между системами Windows.
Ana Betts отмечает эту замечательную технику, с помощью которой вы можете легко перенести свой идеальный дистрибутив WSL2 с одной машины на n машин.
Вот и все. Получите идеальную настройку Linux, синхронизированную на всех ваших системах.
Используйте провайдер учетных данных Windows Git внутри WSL
Все перечисленные фичи переткают в кульминацию в этом крутом посте от Ana Betts, где она интегрирует Windows Git Credential Provider в WSL, превращая /usr/bin/git-credential-manager в сценарий оболочки, который вызывает диспетчер git creds Windows. Гениально. Это было бы возможно только при условии чистой и тесной интеграции.
Настройка окружения в CLI. WSL / Windows Terminal
Есть люди, которые большинство рабочего времени проводят в консоли, есть те, кто пользуются терминалом при необходимости, запуская что-то по инструкциям. Но я думаю, что каждый айтишник, будь он разработчиком, сисадмином, сетевым инженером, или даже senior yaml developer`ом, пользуется command line interface. Далеко не все задумываются об улучшении рабочего окружения в CLI и повышении продуктивности работы в терминале. Мне хотелось бы поделиться своим опытом настройки окружения для работы с Linux из Windows.
Из статьи вы узнаете, какими средствами и каким терминалом актуально пользоваться в настоящее время для запуска Linux приложений в Windows 10. Речь пойдёт о WSL 2 и Windows Terminal, набирающим всё большую популярность у пользователей, которым для работы нужен Linux. Так как большинство use-case`ов у меня связаны с удалённым подключением через SSH, большая часть информации будет релевантно для случаев удалённых подключений, со всеми особенностями, связанными с этим (пробросом ssh ключей через ssh agent, пробросом X-сервера, управлением подключениями etс).
Внимание! Под катом много картинок и ужатого, но местами объёмного, gif`а, рекомендуется открывать статью при наличии соответствующего доступа к интернету. Заходите под кат, если вам актуален запуск Linux утилит под Windows, оптимизация работы в окружении CLI, или вы просто любите технические тексты и цветные терминалы. Текст я постарался скрасить скринкастами и скриншотами терминала, чтобы было не скучно.
Введение
Как на домашнем, так и на рабочем ноутбуке, единственная ОС сейчас у меня Windows 10, и в этом году я окончательно перешёл на использование только WSL вместо VM / dualboot / Cygwin / MinGW. Теперь мой терминал по умолчанию — это локальный шелл WSL, где я могу запускать практически любые задачи, как в нативном Linux. Кроме этого, в домашней сети работает мини-сервер Intel NUC, на котором развёрнут Proxmox с LXC контейнерами и KVM, в котором крутится Docker. На все VM хожу по SSH, с ключами из директории Windows. Очень много времени в профессиональной деятельности проходит в CLI, с домашним сервером и сетью тоже самое. Поэтому всегда возникает желание разобраться с инструментами для более комфортной работы в терминале, а в Windows всегда с этим были проблемы. Но сейчас всё меняется.
Эта и последующие статьи больше ориентированы на энтузиастов, которые ищут свежие решения и желают прокачать свой шелл. Но и новичкам должно быть что-то интересно, хотя статья получилась с достаточно глубоким погружением в тему и предполагает, что у читателя есть какие-то фундаментальные знания в Linux. Вся информация собрана на основе личного опыта использования WSL, терминала, а так же бесконечного листания Stack Overflow и Github issues в процессе постоянного усовершенствования конфигов и поиска удобных тулов для работы.
Windows Subsystem for Linux (WSL) 2
В интернете и на Хабре есть несколько нормальных статей про WSL (раз статья про установку/настройку WSL с X-сервером, два заметка про WSL 2, три статья про Python разработку в VSCode с WSL), описывающих установку и настройку системы. Однако не все действия по установке уже актуальны, так же как и ограничений с подводными камнями становится меньше. Я не буду подробно останавливаться на установке, инструкция по установке актуальной (второй) версии WSL есть на сайте Microsoft, также в интернете можно найти краткие туториалы.
Сейчас WSL ещё находится в стадии активной разработки и недавно (июнь 2019) вышла новая версия WSL 2, которая на данный момент доступна только для свежих версий Windows участникам Windows Insiders. При возможности советую сразу проапгрейдить WSL до версии 2, так как в ней улучшили работу системных вызовов, работу с сетью, ФС, и в целом она построена на другой архитектуре и по некоторым данным даёт 20-кратный прирост скорости по сравнению с первой версией.
Установка WSL 2
Для работы WSL требуется включить Hyper-V, потому что дистрибутивы Linux запускаются в легковесных VM с помощью виртуализации Hyper-V.
Далее я приведу краткую инструкция установки из CLI PowerShell дистрибутива WSL на примере Kali Linux). При предпочтении Ubuntu или другого дистрибутива Linux из доступных, заменить ссылку и названия на соответствующие.
Проверить версию билда Windows:
Активировать компоненты VirtualMachinePlatform и Microsoft-Windows-Subsystem-Linux:
Перезагрузка.
Дальше либо установить дистрибутив из Microsoft Store (https://aka.ms/wslstore), либо дальше выполнить в PowerShell:
Запустить консоль WSL (дистрибутив должен был появиться в меню Start, поиск по названию дистра), дождаться приглашения установить нового пользователя, закрыть консоль.
Теперь дистрибутив должен появится в списке, если выполнить в PowerShell:
При необходимости преобразовать дистрибутив в формат WSL версии 2:
Сделать root пользователем по умолчанию (опционально):
Если вы получили ошибку «A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.», значит у вас стоит билд, в котором проявляется очередной (уже исправленный в последних релизах) баг. Как обычно, есть воркэраунд, либо использовать дистрибутив Ubuntu, с ним у меня не было проблем на той же не последней версии билда.
При необходимости, переместить виртуальный диск WSL на другой раздел (отличный от C:) можно по инструкции. Делать это лучше сразу, так как не всё может пройти гладко.
Disclaimer про безопасность. В WSL и на других Linux-серверах в домашней сети я не запускаю никаких критически важных систем, и других пользователей (кроме меня), в сети нет, поэтому я почти везде хожу под root, с ssh аутентификацией через ключи. Я знаю, что это не лучшая практика, однако речь про личное dev-окружение и я не вижу смысла создавать не-root пользователя. Вопросы безопасности в этой статье рассматриваться не будут, об этом я собираюсь когда-нибудь написать отдельно (про то, как в домашней сети без боли организовать взаимодействие сервисов через TLS с централизованным обновлением сертификатов; о синхронизации
/.ssh/config между серверами, пробросе портов и ключей и т.д.).
Конфигурация WSL
Начиная с билда 17093, основной файл конфигурации WSL находится на ФС дистрибутива по адресу /etc/wsl.conf, в нём описываются настройки, которые будут применять при каждой загрузке дистрибутива:
[automount]
enabled = true
root = /mnt
options = «metadata,umask=22,fmask=11»
mountFsTab = true
[network]
generateHosts = true
generateResolvConf = true
[interop]
enabled = true
appendWindowsPath = true
Сделать ребут дистрибутива можно из PowerShell командой:
После этого можно обновить пакеты и заняться настройкой ОС под себя. Я пока не буду касаться настроек шелла и окружения в Linux, оставлю это для следующей статьи.
Файловая система WSL 2 и производительность
Файлы внутри WSL версии 2 хранятся на виртуальном диске VHDX, в качестве файловой системы используется ext4. Получить доступ к rootfs WSL можно через путь такого формата:
В WSL версии 1 не использовался VHDX и был простой доступ к директории, в которой находились файлы Linux, и Microsoft строго не рекомендовали изменять Linux файлы из Windows. В новой версии WSL доступ к ФС на виртуальном диске обеспечивается с помощью файлового сервера Plan 9 Filesystem Protocol.
В предыдущих версиях WSL были проблемы с производительностью файловой системой, потому что системные вызовы эмулировались через API Windows, доступ к файлам был медленный и нестабильный. В концу 2019 года в WSL 2 архитектура поменялась и используется нативное ядро Linux. Судя по слайду из youtube-презентации The new Windows subsystem for Linux architecture: a deep dive, производительность дисковых операций выросла в 2-5 раз.
Максимальный объём диска ограничен 256GB, при превышении этого объёма необходимо будет делать ресайз, инструкция есть в документации.
Изначально, у WSL были проблемы с тем, чтобы высвобождать ресурсы после использования RAM. В билде 19013 эту проблему решили. Если запускать ресурсоёмкие задачи (например, сборка rust приложения) можно заметить, что процесс Vmmem будет в топе Диспетчера задач, однако потребление памяти значительно снизилось в последних версиях WSL.
Имя хоста (hostname) в Linux берётся из имени PC в Windows, независимо от того, что прописать в /etc/hostname или командой hostnamectl set-hostname.
В отличии от первой версии, в WSL 2 сеть работает через виртуальный Hyper-V свитч:
В данном случае сеть 172.27.144.0/20 используется под WSL, её первый адрес (172.27.144.1) — это хостовая система Windows.
Из Linux обращаться по сети к хостовым сервисам (запущенным в Windows) можно, например, так:
IP-адрес Windows тут берётся из /etc/resolv.conf, где он генерируется автоматически согласно настройкам wsl.conf.
Наоборот, если нужен коннект к Linux сокету из приложения Windows, необходимо обращаться к IP-адресу WSL. При этом есть нюанс — в Linux сервис необходимо запускать не на localhost (127.0.0.1), а на адресе 0.0.0.0. Например, чтобы быстро поднять SOCKS5 proxy до своего VPS, нужно запустить SSH с параметром dynamic port forwarding:
После этого в приложении Windows, например Chrome, в качестве адреса SOCKS5 прописать не localhost, а адрес WSL, в данном случае 172.27.150.196. Кстати, таким нехитрым способом туннелирования трафика через VPS в Хроме появляется возможность использовать доступ к сайтам через IPv6.
IP-адрес в Linux после перезагрузки будет каждый раз меняться, так что в сценариях, когда нужно иметь постоянно работающий и автоматически запускающийся port forwarding, нужно искать воркэраунд. Есть много способов решения этой проблемы, разной степени костыльности, почитать подробнее можно в этом issue на github. Я воспользовался утилитой go-wsl2-host, которая реализует Windows Service, добавляющий автоматически IP-адрес WSL в файл hosts Windows, таким образом на хостовой системе можно прописать хостнейм типа ubuntu.wsl и по нему обращаться к Linux. Однако всё это костыли и работает не очень хорошо, остаётся ждать, когда Microsoft пофиксят эти проблемы.
UPD. Пока я писал эту статью, обнаружил, что вышли обновления (билд 18945), в которых появилась возможность достучаться через localhost до сервисов, запущенных в WSL. Правда, оказалось, что есть баг, из-за которого всё равно это не работало у всех, фикс в августовском билде 18970. Так как не всем прилетают обновления, даже если быть участником программы Windows Insiders, я не стал корректировать информацию, может кому-то это поможет настроить сетевое взаимодействие.
OpenSSH в Windows и автозапуск сервисов
Windows 10, как и Windows Server 2019, комплектуется форком OpenSSH, включающем все знакомые утилиты ssh-keygen, ssh-add, scp и другие, а том числе ssh-agent и сам сервер sshd. И клиент, и сервер поставить можно через Apps > Apps and Features > Manage Optional Features, но версия клиента ssh будет не последняя. Я столкнулся с багом, не позволяющим коннектиться к хосту через jump-хост с опцией ProxyJump и оказалось, что эту проблему пофиксили, но нужно вручную обновить SSH клиента. Установить актуальную версию Win32 OpenSSH можно, скачав zip из раздела Releases на гитхабе, и распаковав, к примеру, в C:\Program Files\OpenSSH. Сторонним софтом ssh.exe (например, при использовании Remote Development режима в VSCode) вызывается из $PATH (%SYSTEMROOT%\System32\OpenSSH\), нужно изменить переменную среды. Environment variables изменяются через GUI в Start > Edit the system environment variables (Пуск > Изменение системных переменных среды), там необходимо новый путь поставить выше старой версии.
Я использую SSH-сервер на ноутбуке внутри WSL для того, чтобы удалённо можно было ходить с машины на машину. И, благодаря тому, что я использую техники ssh port forwarding и продуманно настроенный централизованный конфиг SSH клиентов, я могу прозрачно ходить по всем своим серверам, вводя хостнейм вместо адресов. То есть, если даже подключить какой-то из ноутбуков к мобильной сети, autossh демон подключится к jump-хосту и я всё равно смогу зайти на компьютер, никакой NAT не будет помехой. Поэтому мне важно, чтобы sshd всё время был в состоянии up.
Единственный рабочий способ попасть по SSH в WSL — это пробросить порт SSH. Это можно сделать с самого WSL с помощью RemoteForward, либо с другого сервера в домашней сети. Мало лишь кому это надо, да и это уже advanced level, так что просто приведу рабочую команду:
Теперь при коннекте на адрес mt.example.com:2263 можно попасть прямо в WSL.
Если планируется поднимать SSH-сервер в WSL, нужно не забыть сконфигурировать необходимые параметры запуска сервера в /etc/ssh/sshd_config. Чтобы не было конфликта при бинде сервиса на порт 22, OpenSSH сервер в Windows следует отключить или вовсе удалить, если он установлен (Apps > Apps and Features > Manage Optional Features).
X forwarding
Приятным моментом оказалось, что в Windows 10 есть утилита clip.exe, позволяющая перенаправлять stdout напрямую в буфер обмена Windows. Это удобно использовать в таких программах как tmux, а благодаря пробросу X-сервера текст можно копировать и с удалённых хостов. Чтобы всё работало, необходимо иметь всегда запущенный X-сервер в Windows и правильно прописанную переменную $DISPLAY.
Немного скучной теории. На *nix системах с запущенным X имеются разные типы буферов обмена (primary, secondary, clipboard), в контексте этой статьи это не так важно, но важно для общего понимания механизма работы. Для работы с буферами обмена на Linux есть две утилиты (xclip и xsel). Обе утилиты имеют схожий функционал, в xsel его немного больше, но базовый функционал, необходимый для проброса содержимого буфера, одинаков. В X приложениях выделенный текст попадает в primary selection, вставляется при этом средней кнопкой мышки, в xclip и xsel используется по умолчанию primary selection.
Например, чтобы скопировать в буфер по умолчанию содержимое переменной, нужно передать stdout на stdin утилиты xclip, без дополнительных параметров:
А чтобы вывести содержимое буфера по умолчанию, запустить xclip с ключом -o:
Чтобы буфер обмена перенаправлялся через X-сервер и графические приложения запускались на локальном сервере X, необходимо в переменную $DISPLAY прописать IP-адрес, являющийся default gateway для WSL. Пока что ничего лучше того, чтобы брать его из resolv.conf (который генерируется автоматически Windows), не придумали. Поэтому, самый простой способ — прописать экспорт переменной $DISPLAY в профайле шелла (например,
В качестве X-сервера я выбрал бесплатный VcXsrv, он умеет работать с буфером, имеет разные режимы отображения окон и запускается из командной строки с прописанными опциями. По ссылке на gist можно посмотреть все опции.
Создать задачу автозапуска X-сервера можно в Task Scheduler примерно таким образом:
SSH ключи
Чтобы программы из Windows могли использовать SSH ключи (например, редактор при работе с удалённым репозиторием GitHub), и в то же время не было второй копии ключей в WSL, лучше всего сгенерировать ключи в Windows %HOMEPATH%/.ssh и создать симлинки в домашней директории WSL.
/.ssh/config можно прописать параметр IdentityFile, указав путь к ключам на диске Windows:
Host *
IdentityFile /mnt/c/Users/$
Если ключи были скопированы откуда-то и права на файлы не выставлены правильно, поправить permissions:
chmod 600 /mnt/c/Users/$
chmod 644 /mnt/c/Users/$
chmod 700 /mnt/c/Users/$
Таким образом, при дальнейшей настройке доступа по ключам SSH пользователь идентифицируется однозначно одним набором ключей в одном месте, как при использовании приложений Windows, так и Linux. Теперь можно добавить публичный ключ на сервера/сервисы, куда необходимо будет ходить с этого компьютера. Если в домашней сети есть другие устройства, на которые требуется доступ по SSH, то правильно будет скопировать свой публичный ключ на эти сервера (ssh-copy-id), но не надо копировать ключи одного сервера на другой. Так как при работе через SSH можно (и нужно) использовать ssh-agent, то при коннекте с одного сервера на другой, агент заботится, чтобы авторизация происходила по проброшенному ключу. Чтобы всё работало правильно и ожидаемо, нужно позаботиться о файле
/.ssh/config, в котором надо прописать все необходимые опции.
Host *
TCPKeepAlive yes
ServerAliveInterval 30
ServerAliveCountMax 3
ForwardAgent yes
AddKeysToAgent yes
ForwardX11 yes
ForwardX11Trusted yes
Какой терминал выбрать для работы в Linux на Windows
Сначала хочется сделать небольшое ревью существующих терминальных оболочек под Windows, умеющих запускать WSL. Среди пользователей популярен функциональный комбайн MobaXterm, который умеет создавать различные сессии, в том числе графические (WSL, bash/zsh, Mosh, RDP, VNC и т.п.), позволяет делать макросы и запускать скрипты, имеет много настроек и функциональных возможностей, ssh agent, автозапускаемый ssh port forwarding, и даже имеет встроенный сервер ftp/tftp/http, но продукт closed source и, к тому же, платный. Hyper — другой, более современный эмулятор терминала, позволяющий запускать WSL shell, терминал построен на HTML/JS/CSS и расширяется с помощью плагинов в виде node.js модулей (awesome list). Есть и другие терминалы, позволяющие запускать WSL с разной степенью костыльности (ConEmu, его форк Cmder, WSLtty и др.), но их я оставлю без внимания.
Дальше в этой статье речь пойдёт про Windows Terminal, на который я перешёл с недавних пор, и пока что испытываю только положительные эмоции. Terminal пока что ещё в статусе бета, но работает достаточно стабильно. Из фич на данный момент реализован мультитаб, разделение панелей (splitting), настраиваемые профили терминальных подключений, цветовые схемы, ну и больше нечего перечислить. Но этого функционала вполне хватает, мне даже нравится, что софт не перегружен лишним — как будто бы разработчики придерживаются принципа KISS.
Установка и настройка Windows Terminal
Установить Windows Terminal можно из Windows Store, либо скачав бинарник из раздела Releases на гитхабе проекта, там же и вся актуальная информация, инструкции и FAQ. Терминал требует, как минимум, версию Windows 1903 и билд 18362. Предпочтительнее устанавливать через Windows Store, так как обновлять в этом случае проще, прямо из стора. Обновления выходят регулярно, на гитхабе выложен план развития (roadmap) первой версии терминала. На данный момент все фичи версии 1 уже реализованы (по плану до конца 2019 года реализовать все улучшения), дальше несколько месяцев работы над устранениями багов и в апреле 2020 планируется официальный релиз Terminal v1.0. Приятно, что MS теперь есть на гитхабе, их софт научился показывать логи, внятные ошибки и любые проблемы легко гуглятся.
Настроек в терминале пока не много, но их хватает для комфортной работы, продукт активно развивается, есть на github, где пользователи могут создать feature request или bug report. Разработчики принимают участие в обсуждении проблем с пользователями, зачастую предлагая воркэраунды, когда обнаруживается баг.
Конфиг хранится в json формате, после сохранения применяется сразу же. Это удобно хотя бы потому, что можно применять хорошие практики управлением конфигурациями рабочего окружения — все линуксовые конфиги я храню в git репозитории, на Windows из рабочего инструмента использую только VSCode, который умеет синхронизировать конфиг через github gist, а локальный конфиг воркспейса сохранять отдельно в dotfiles. Вот и Terminal движется в ту же сторону, используя те же хоткеи и формат конфига, как VSCode. Править конфиг, кстати, удобно через VSCode, особенно если уже пользуетесь этим отличным редактором от MS. Файл конфигурации терминала уже содержит многие дефолтные настройки, а правильный редактор позволяет посмотреть все опции с описанием key и вариантами value из schema (особенно это удобно, когда у проекта ещё нет полноценной документации). Плюсом доступны все фишечки IDE в виде автодополнения, intellisense, проверкой синтаксиса, форматированием и т.д.
Документация для разработчиков доступна тут, а здесь пока что небольшая страничка документации для пользователей. Отдельная страница посвящена настройкам, которые прописываются в json файле конфигурации. Оттуда можно узнать, что структурно настройки делятся на:
Шрифты
Чтобы терминал по-настоящему радовал пользователя, обязательно надо инсталлировать шрифты с поддержкой спец символов и лигатур. Выбрать можно из:
Устанавливается шрифт в Windows с помощью установщика шрифтов ОС. Для этого надо скачать последнюю версию понравившегося шрифта с github releases архивом и вручную установить шрифт в системе.
Заключение
Получилась очень объёмная статья, в одном месте собрана вся актуальная информация по установке, настройке и использованию Windows Terminal совместно с WSL. В дальнейшем я хочу так же оформить статьёй заметки о ZSH и tmux, и расписать свой опыт деплоя конфигураций на VM и синхронизации dotfiles между хостами. Всё в рамках автоматизации домашней сети, но это будет полезно и для разработчиков / девопсов / системных инженеров. Ещё из нераскрытых тем остался запуск Docker в WSL 2, но у меня нет необходимости запускать докер на персональном компьютере, так как для этого есть выделенный сервер.
Я надеюсь, что никто не пожалел, что дочитал статью и вынес для себя какие-то новые знания. Если кому-то есть, что добавить, давайте делиться мыслями в комментариях. Если есть какие-то замечания по тексту, пишите в ЛС, хочется поддерживать этот гайд в актуальности.