Feb. 19, 2017, 2:54 p.m.
Posted by soar

KeeAgent + Windows Subsystem for Linux

Долгое время я не могу отказаться от использования Windows дома. И если на работе у меня уже давно Ubuntu, работать в которой очень комфортно, то вот для домашнего ПК пока вариантов не много. И на мой взгляд Windows Subsystem for Linux одно из величайших нововведений в истории из всех, что я помню. Это действительно работает, работает круто и так, как должно работать.

Однако жить полностью в WSL не получается и возникает множество вопросов о том, как помирить привычные Windows-утилиты с ПО в Linux. Так например я давно пользуюсь RSA-ключами в KeePass/KeeAgent и мне хотелось бы использовать bash c git/openssh.

Спасибо David Lechner, который подсказал мне правильный путь решения этой проблемы. Об этом написано здесь, но я еще раз остановлюсь на подробностях.

Первое, что нужно сделать - включить в KeeAgent "сокеты" для MSysGit/CygWin. Однако, как написал мне David Lechner:

WSL uses actual Unix sockets, which are not available in Cygwin/MSYS because Windows does not support Unix socket natively (or at least not until recently). Instead, Cygwin/MSYS use TCP/IP sockets.


Проблема в том, что эти файлы не являются полноценными сокетами Linux и представляют из себя просто указатель на порт:

$ cat /mnt/c/ProgramData/keeagent-cygwin.sock
!<socket >49935 s 665DDD9C-41701475-05F7459B-35A6C427

Нам же необходимо создать полноценный сокет в WSL и сделать это можно с помощью утилиты socat, про которую многие не знают. А именно она занимается тем, что соединяет два канала, каждый из которых может быть файлом, устройством, каналом, сетевым сокетом и т.д.

Всё что нам нужно - добавить в .bashrc строки, которые будут получать порт, который слушает KeeAgent, и создавать для него файловый сокет во временной директории.

SSH_AUTH_KEEAGENT_SOCK=/mnt/c/ProgramData/keeagent-msysgit.sock
SSH_AUTH_KEEAGENT_PORT=`sed -r 's/!<socket >([0-9]*\b).*/\1/' ${SSH_AUTH_KEEAGENT_SOCK}`
SSH_AUTH_TMPDIR=`mktemp --tmpdir --directory keeagent-ssh.XXXXXXXXXX`

export SSH_AUTH_SOCK="${SSH_AUTH_TMPDIR}/agent.$$"
setsid socat UNIX-LISTEN:${SSH_AUTH_SOCK},mode=0600,fork,shut-down TCP:127.0.0.1:${SSH_AUTH_KEEAGENT_PORT},connect-timeout=2 >/dev/null 2>&1 &

echo "SSH_AUTH_SOCK: ${SSH_AUTH_SOCK}"

UPD: я добавил setsid, чтобы нажатие Ctrl+C не убивало процесс socat.

Comments