<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Bappoy&#039;s blog &#187; ssh</title>
	<atom:link href="http://bappoy.pp.ru/tag/ssh/feed" rel="self" type="application/rss+xml" />
	<link>http://bappoy.pp.ru</link>
	<description>Линуксоид на велосипеде с моторчиком</description>
	<lastBuildDate>Fri, 02 Dec 2011 11:44:47 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Угадывание мыслей и выполнение несуществующих команд средствами bash</title>
		<link>http://bappoy.pp.ru/2008/11/17/quick-call-ssh.html</link>
		<comments>http://bappoy.pp.ru/2008/11/17/quick-call-ssh.html#comments</comments>
		<pubDate>Mon, 17 Nov 2008 06:33:44 +0000</pubDate>
		<dc:creator>bappoy</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[debian]]></category>
		<category><![CDATA[ssh]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://bappoy.pp.ru/?p=336</guid>
		<description><![CDATA[<p>В Debian в bash был добавлен патч, благодаря которому пользователь может написать свою функцию, выполняемую в случае, если введённая пользователем команда отсутствует. В Ubuntu эту фичу использует подсказка command-not-found, заметно тормозящая работу, в то время как можно найти более интересные и полезные возможности применения этого механизма,  оставив поиск пакета специализированным программам. Поделюсь своим опытом.</p>
<p>У нашего подразделения есть специальная сеть для тестовых серверов и виртуальных машин: 192.168.20.0/24, и очень часто приходится набирать команды типа <code>ssh user@192.168.20.xx</code>, причем в командах различается только последняя цифра. У ограниченного числа серверов нужно указывать другой <code>username</code>. Реже приходится ходить на сервера в других подсетях (в пределах 192.168.0.0/16); также иногда клиенты открывают нам доступ к своим системам, чтобы мы смогли продиагностировать их проблему и решить ее на месте.</p>
<p>Как следует из предыдущего абзаца, очень часто набираются команды вида:</p>
<pre>ssh ordinary_user@192.168.20.xx
ssh special_user@192.168.xx.yy
ssh third_user@ww.xx.yy.zz</pre>
<p>Возникает естественное желание этот процесс сократить и оптимизировать. Когда серверов было немного, я насоздавал множество <a href="http://bappoy.pp.ru/2007/11/21/konsole-encodings.html">хитрых алиасов</a> вроде следующего:</p>
<pre>alias 123='ssh user@192.168.20.123'</pre>
<p>Однако вскоре я понял, что поддерживать список из полусотни alias&#8217;ов — не true unix way, и задумался об альтернативах. Вспомнил об опытах вебмастеров эпохи web 1.0 по использованию 404 ошибки для отображения страницы с нужным содержанием, задумался о том, каким образом bash перехватывает вызов неизвестной команды и подменяет её командой поиска нужного пакета&#8230; В результате беглого изучения состава пакета command-not-found было выяснено, что используется функция <code>command_not_found_handle</code>. Она принимает в качестве аргумента введённую пользователем команду, выполняет некие действия и возвращает 127, если ничего нельзя сделать (в таком случае bash выводит стандартное сообщение об ошибке), или любое другое число, если что-то получилось.</p>
<p>Остальное оказалось делом техники. В <code>~/.bashrc</code> была добавлена функция:</p>
<pre>command_not_found_handle () {
    if [[ ! "$1" ]] ; then
        return 127
    fi

    n="$1"

    if echo $n| perl -ne 'exit(/^([1-9]|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])$/ ? 0:1)' ; then
        ip=192.168.20.$n
    elif echo $n| perl -ne 'exit (/^([1-9]|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.([1-9]|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])$/ ? 0:1)' ; then
        ip=192.168.$n
    elif echo $n| perl -ne 'exit (/^([1-9]|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.([1-9]|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.([1-9]|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.([1-9]|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])$/ ? 0:1)' ; then
        ip=$n
    else
        return 127
    fi

    ssh $ip
}
</pre>
<p>Любое введённое число от 1 до 255 преобразуется в команду <code>ssh 192.168.20.число</code>; два числа — в <code>ssh 192.168.число.число</code>; любой введённый IP-адрес превращается в <code>ssh IP-адрес</code>. Во всех остальных случаях просто выводится сообщение <code>"command not found"</code>.</p>
<p>Поскольку используется довольно сложное регулярное выражение, то для его обработки пришлось использовать perl. Ещё был вариант с <code>grep -qP</code>, но эксперименальная опция <code>-P</code> (расширенная поддержка perl-овых регулярных выражений) включена в grep не во всех дистрибутивах (например, в Ubuntu 8.04 её нет, а в 8.10 уже есть).</p>
<p>Чтобы для всех хостов в 20 сети подставлялось общее имя пользователя ordinary_user, а для избранных хостов — специальные имена, в ~/.ssh/config я добавил строчки (общие параметры для всех хостов, предваряемые конструкцией <code>Host *</code>, должны находиться в конце списка):</p>
<pre>Host 192.168.20.251
User special_user1

Host 192.168.20.252
User special_user2

Host 192.168.20.254
User special_user3

Host *
User ordinary_user</pre>
<p>К сожалению, мне не удалось заставить эту функцию обрабатывать также и параметры командной строки: функции command_not_found_handle передаётся только первый позиционный параметр, остальные недоступны. Поэтому для каждого нестандартного хоста придётся либо писать полный вариант команды со всеми параметрами, либо указывать настройки сервера в ~/.ssh/config, подобно указанным выше. Имеются и прочие недостатки в реализации, обсуждаемые, в частности, на сайте <a href="http://smylers.hates-software.com/2008/01/04/090399e2.html">smylers hates software</a>.</p>
<p>Однако даже с такими ограничениями открываются новые потрясающие возможности.  Думаю, что предложенное мной применение не единственное, и этот пост — не последний на данную тему.</p>
<p>P.S. бонус для дочитавших до этого места: <a href="http://regexlib.com/">библиотека регулярных выражений perl</a>, где я нашел регэксп для проверки строки на соответствие IP-адресу.</p>
]]></description>
		<wfw:commentRss>http://bappoy.pp.ru/2008/11/17/quick-call-ssh.html/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>SOCKS proxy в SSH</title>
		<link>http://bappoy.pp.ru/2008/06/09/socks-in-ssh.html</link>
		<comments>http://bappoy.pp.ru/2008/06/09/socks-in-ssh.html#comments</comments>
		<pubDate>Mon, 09 Jun 2008 08:35:36 +0000</pubDate>
		<dc:creator>bappoy</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[ssh]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://bappoy.pp.ru/?p=281</guid>
		<description><![CDATA[<p><a href="http://alexey.sveshnikov.ru/">Алексей Свешников</a> в комментарии к заметке о <a href="http://bappoy.pp.ru/2008/02/27/ssh-tunneling-tips.html">пробросе туннелей через ssh</a> напомнил о возможности использования ssh в качестве SOCKS4/SOCKS5-сервера. </p>
<p>Допустим, у нас есть рабочая станция в локальной сети за firewall&#8217;ом; также имеется ssh-доступ на сервер в Интернете. Кроме ssh, никакой связи с внешним миром не имеется, а очень хочется, например, подключиться к какому-нибудь jabber-серверу.</p>
<p>На рабочей станции запускаем простую команду:</p>
<pre>ssh -D 5555 user@remotehost -f -N</pre>
<p>Теперь, указав в настройках XMPP-клиента (например, Pidgin&#8217;а) в качестве SOCKS5 прокси <code>localhost:5555</code>, получим желаемый результат: Pidgin соединяется с сервером через внешний сервер.  </p>
<p>Еще один неизвестный мне доселе ssh tip: в комплект поставки ssh входит программка ssh-copy-id, автоматически прописывающая ваш .ssh/.id_rsa.pub в .ssh/authorized_keys на целевом сервере и устанавливающая правильные права. Использовать это проще простого:</p>
<pre>ssh-copy-id user@remotehost</pre>
<p>(via <a href="http://habrahabr.ru/blog/linux/43416.html">10 трюков в командной строке, о которых вы не знали.</a>)</p>
]]></description>
		<wfw:commentRss>http://bappoy.pp.ru/2008/06/09/socks-in-ssh.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>2 способа проброса туннелей с использованием ssh</title>
		<link>http://bappoy.pp.ru/2008/02/27/ssh-tunneling-tips.html</link>
		<comments>http://bappoy.pp.ru/2008/02/27/ssh-tunneling-tips.html#comments</comments>
		<pubDate>Wed, 27 Feb 2008 12:42:41 +0000</pubDate>
		<dc:creator>bappoy</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[ssh]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://bappoy.pp.ru/2008/02/27/ssh-tunneling-tips/</guid>
		<description><![CDATA[<p><strong>1. туннель ssh</strong></p>
<p>Дано: сервер ourproxy.provider.ru, стоящий на страже локальной сети. Этот сервер доступен извне и на нём работает демон sshd.</p>
<p>Требуется: получить из дома доступ к ресурсам внутри локальной сети, например, к интранет-серверу 10.10.5.1:80</p>
<p>Решение: выполнить на домашней машине команду, пробрасывающую туннель к искомому IP-адресу через ourproxy.provider.ru:</p>
<blockquote><p><code>ssh -f -N user@ourproxy.provider.ru -L 8080:10.10.5.1:80</code></p></blockquote>
<p>Опция <code>-f</code> говорит ssh, что после соединения нужно уйти в background.<br />
Опция <code>-N</code> указывает, что никаких команд выполнять не нужно<br />
Ключ <code>-L</code> означает, что соединения к localhost на порт 8080 нужно перенаправлять на 80 порт IP-адреса 10.10.5.1</p>
<p>Таким образом, набирая в браузере адрес http://localhost:8080, попадаем на нужный сервер.</p>
<p><strong>2. обратный туннель ssh</strong></p>
<p>Дано: компьютер на работе, находящийся за firewall&#8217;ом и nat&#8217;ом; компьютер дома с доступом в интернет; сервер ourproxy.provider.ru с работающим sshd, доступный обоим компьютерам. Но в данном случае прямой доступ с ourproxy.provider.ru к рабочей машине отсутствует.</p>
<p>Требуется: получить из дома доступ к сервису sshd на рабочем компьютере.</p>
<p>Решение: на рабочей машине выполнить команду:</p>
<blockquote><p><code>ssh -f -N user@ourproxy.provider.ru -R 12345:localhost:22</code></p></blockquote>
<p>Опции -f и -N описаны несколькими строчками выше.<br />
Ключ -R означает, что подключения к порту 12345 на ourproxy.provider.ru будут перенаправляться на 22 порт рабочего компьютера.</p>
<p>После выполнения этой команды с рабочей машины можно будет попасть на эту машину с ourproxy.provider.ru, выполнив  команду:</p>
<blockquote><p><blockquode><code>ssh -p 12345 user@locahost</code></blockquode></p></blockquote>
<p>По этому же принципу можно получить доступ к прочим ресурсам локальной сети. Вот еще один пример.</p>
<p>На рабочей машине:</p>
<blockquote><p><code>ssh -f -N user@ourproxy.provider.ru -R 8080:10.10.5.1:80</code></p></blockquote>
<p>На домашней машине:</p>
<blockquote><p><code>ssh -f -N user@ourproxy.provider.ru -L localhost:8080:localhost:8080</code></p></blockquote>
<p>Теперь, набрав в адресной строке браузера на домашнем компьютере http://localhost:8080, получаем доступ к интранет-серверу за <s>семью замками</s> двумя firewall-ами.</p>
<p>Конечно же, это приводит к серьёзной бреши в корпоративной безопасности, поэтому крайне не рекомендуется злоупотреблять этим советом.</p>
<hr />Чтобы не писать команды вручную при каждой перезагрузке, можно внести их в конфигурационный файл ssh_config. Интересующихся отсылаю к соответствующему ману.</p>
]]></description>
		<wfw:commentRss>http://bappoy.pp.ru/2008/02/27/ssh-tunneling-tips.html/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Автоматическое изменение кодировки в konsole</title>
		<link>http://bappoy.pp.ru/2007/11/21/konsole-encodings.html</link>
		<comments>http://bappoy.pp.ru/2007/11/21/konsole-encodings.html#comments</comments>
		<pubDate>Tue, 20 Nov 2007 21:49:35 +0000</pubDate>
		<dc:creator>bappoy</dc:creator>
				<category><![CDATA[lifehack]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[Ссылки]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[konsole]]></category>
		<category><![CDATA[ssh]]></category>
		<category><![CDATA[советы]]></category>

		<guid isPermaLink="false">http://bappoy.pp.ru/2007/11/21/konsole-encodings/</guid>
		<description><![CDATA[<p>У нас в организации есть несколько серверов со старыми линуксами, которые используют кодировку KOI8-R. С того момента, как я поставил на свой рабочий компьютер Федору, меня очень раздражала необходимость вручную переключать кодировку для каждого сеанса в konsole. Сегодня под впечатлением от <a href="http://j-sheridan.livejournal.com/11522.html">заметки про установку away в ICQ в зависимости от достижимости телефона по bluetooth</a> наконец придумал, как это сделать.</p>
<p>Как и всякая программа KDE, konsole использует <a href="http://en.wikipedia.org/wiki/Dcop" title="Wikipedia: DCOP">DCOP</a> для внутрисистемных коммуникаций. Это означает, что запущенной программой можно управлять из командной строки командами типа &laquo;<code>dcop konsole-2115 konsole setFullScreen true</code>&laquo;. Здесь <code>konsole-2115</code> &#8212; название программы + её pid, все остальные аргументы &#8212; это, говоря языком ООП, объект, методы и параметры. Список программ, которыми можно рулить подобным образом, и их объектов с методами можно получить, выполняя последовательно команды dcop, dcop konsole-2115, dcop konsole-2115 konsole и т.д.</p>
<p>Вернёмся к нашим баранам. Konsole при запуске устанавливает две переменные окружения: KONSOLE_DCOP, в которой хранится ссылка на текущий экземпляр программы, и KONSOLE_DCOP_SESSION &#8212; ссылка на текущий сеанс. Для установки кодировки текущего сеанса нужно использовать такую команду:</p>
<blockquote><p><code>dcop $KONSOLE_DCOP_SESSION setEncoding KOI8-R</code></p></blockquote>
<p>Собственно, на этом задачу можно считать решённой, осталось правильно оформить ответ :)</p>
<p>В качестве быстрого решения подойдёт прописывание в .bashrc alias&#8217;ов для всех интересующих хостов:</p>
<blockquote><p><code>alias 01='dcop $KONSOLE_DCOP_SESSION setEncoding KOI8-R;ssh bpp@192.168.0.1 $*;dcop $KONSOLE_DCOP_SESSION setEncoding UTF8;'<br />
alias 02='dcop $KONSOLE_DCOP_SESSION setEncoding KOI8-R;ssh bpp@192.168.0.2 $*;dcop $KONSOLE_DCOP_SESSION setEncoding UTF8;'<br />
alias 03='dcop $KONSOLE_DCOP_SESSION setEncoding KOI8-R;ssh bpp@192.168.0.3 $*;dcop $KONSOLE_DCOP_SESSION setEncoding UTF8;'</code></p></blockquote>
<p>Более правильное решение &#8212; оформить это в виде небольшого скрипта ~/bin/ssh-launcher.sh, который умеет переименовывать сеанс и проверять, выполняется ли команда в konsole, а не, например, в xterme, который dcop не поддерживает. Кроме того, скрипт можно расширять, добавляя установку различных параметров konsole в зависимости от хоста назначения.</p>
<blockquote><p><code><br />
#!/bin/bash<br />
if !([[ "$1" ]] &amp;&amp; [[ "$2" ]]) ; then</code></p>
<blockquote><p>echo Usage: $0 username hostname \[ ssh parameters \]<br />
exit 1</p></blockquote>
<p>fi</p>
<p>ssh_params=( $* )<br />
ssh_user=${ssh_params[0]}<br />
ssh_host=${ssh_params[1]}<br />
unset ssh_params[0]<br />
unset ssh_params[1]<br />
ssh_parameters=${ssh_params[*]}</p>
<p>if [[ x"$KONSOLE_DCOP" != "x" ]] ; then # если мы в konsole</p>
<blockquote><p>dcop $KONSOLE_DCOP_SESSION setEncoding KOI8-R<br />
dcop $KONSOLE_DCOP_SESSION renameSession $ssh_user@$ssh_host<br />
ssh $ssh_user@$ssh_host $ssh_parameters<br />
dcop $KONSOLE_DCOP_SESSION renameSession `whoami`@`hostname`<br />
dcop $KONSOLE_DCOP_SESSION setEncoding UTF8</p></blockquote>
<p>else</p>
<blockquote><p>kdialog &#8211;text &laquo;run this from konsole&raquo;</p></blockquote>
<p>fi</p></blockquote>
<p>Теперь в ~/.bashrc можно прописать alias&#8217;ы длы вызова этого скрипта:</p>
<blockquote><p><code><br />
alias 01='ssh-launcher bpp 192.168.0.1 $*'<br />
alias 02='ssh-launcher bpp 192.168.0.1 $*'<br />
alias 03='ssh-launcher bpp 192.168.0.1 $*'<br />
...<br />
alias bpp='ssh-launcher bappoy bappoy.pp.ru $*'<br />
</code></p></blockquote>
<p>P.S. Обратите внимание на <code>$*</code> в конце alias&#8217;а &#8212; благодаря этой переменной можно очень быстро выполнять команды на указанном сервере:</p>
<blockquote><p><code>01 ps -ax\|grep httpd\|wc -l</code></p></blockquote>
<p><strong>Ссылки про DCOP</strong><br />
<a href="http://docs.kde.org/userguide/kde-diy.html">KDE DIY &#8211; Building Your Own Tools</a><br />
<a href="http://linuxgazette.mirrors.org.ua/issue97/oregan2.html">Using DCOP from the command line</a> (Linux Gazette #97)<br />
<a href="http://en.wikipedia.org/wiki/Dcop">DCOP @Wikipedia</a></p>
]]></description>
		<wfw:commentRss>http://bappoy.pp.ru/2007/11/21/konsole-encodings.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

