Как Ваш компьютер может дать доступ к себе через туннель средствами ssh, autossh, autosshd: различия между версиями

Материал из ALT Linux Wiki
(Автоматический туннель)
м (источник неправильного написания названия дистрибутива, в т.ч. и в википедии)
 
(не показано 47 промежуточных версий 3 участников)
Строка 1: Строка 1:
[[category:HOWTO]]
Здесь будет подробно рассказано, как дать ''кому-то'' доступ на ваш (мобильный) компьютер через туннель.
 
Туннель нужен, если у вашего компьютера нет постоянного адреса в Интернете. Это будет удобно, если вы ездите с ним и подключаетесь к Интернету по-разному.
 
(Иногда в подобных ситуациях люди используют проприетарный [[TeamViewer]]. Можно обойтись без него и иметь всё под своим контролем.)
 
Туннель (на самом деле, проброс одного порта) будет создаваться средствами {{prg|ssh}} ({{pkg|openssh-client}}), {{pkg|autossh}}, {{pkg|autosshd}}. Это основная задача, описанию решения которой посвящён этот рассказ.
 
* ''кому-то'' в этом руководстве будет названо ''я'' для простоты.
 
* {{prg|ssh}} в этом рассказе появится ещё и в другой роли: как средство входа для меня на ваш компьютер (с вашей стороны это обеспечивает {{pkg|openssh-server}}). Но эти две роли независимы друг от друга.
 
* Считается, что я имею больше опыта администрирования, поэтому указания для вас подробные, а для меня -- краткие, схематичные.
 
* Я должен буду вам сообщить, а вы подставить конкретные значения для моих данных: '''<nowiki>{{{MY_HOST}}}, {{{MY_HOST_SSHPORT}}}, {{{MY_PUBLIC_KEY}}}, {{{ME}}}</nowiki>'''.<noinclude> (Пример этого руководства с ''чьими-то'' конкретными данными: [[Участник:IvanZakharyaschev/Как дать мне доступ по ssh на Ваш (мобильный) компьютер]].)</noinclude>
 
==Туннель==
==Туннель==
===Конфигурация туннеля===
===Конфигурация туннеля===
====вы и я: ваше имя====
====вы и я: ваше имя====
* Договоримся об имени для вашего компьютера (по которому я буду вести у себя учёт). Обозначим его NAME; дальше вместо NAME будем подставлять это выбранное ваше имя.
* Договоримся об имени для вашего компьютера (по которому я буду вести у себя учёт). Обозначим его '''NAME'''; дальше вместо '''NAME''' будем подставлять это выбранное ваше имя.


====вы: ваш ключ, которому я позволю делать туннель у меня====
====вы: ваш ключ, которому я позволю делать туннель у меня====
'''(делает обычный пользователь, не root)'''
'''(делает обычный пользователь, не root)'''
* ssh-keygen -f ~/.ssh/id_for_tunnel -C 'tunnel wanted by NAME'
* {{cmd|ssh-keygen -f ~/.ssh/id_for_tun_'''NAME''' -C 'tunnel wanted by '''NAME''''}}
* Сообщите мне его открытую (т.н. "публичную") часть: cat ~/.ssh/id_for_tunnel.pub
* Сообщите мне его открытую (т.н. "публичную") часть: {{cmd|cat ~/.ssh/id_for_tun_'''NAME'''.pub}}


====с моей стороны: пользователь и порт для туннеля====
====с моей стороны: пользователь и выбор порта для туннеля====
'''(делает администратор)'''
'''(делает администратор)'''
* useradd -m tun_NAME
* {{cmd|useradd -m tun_'''NAME'''}}
* Позволяю входить по вашему ключу: cat >> ~tun_NAME/.ssh/authorized_keys
* Позволяю входить по вашему ключу: {{cmd|cat >> ~tun_'''NAME'''/.ssh/authorized_keys}} (Заготовка файла {{path|~tun_'''NAME'''/.ssh/authorized_keys}} уже будет после {{cmd|useradd}}.)
* Выбираю у себя номер порта и сообщаю его вам. (Пусть он обозначается PORT_NAME.) Возможна конфигурация, когда порт выбирается автоматически (как в конфигурации ниже); тогда заранее договариваться о номере порта не надо.
* '''TODO:''' Хорошо бы ещё запретить этому специальному пользователю (для обслуживания туннеля с моей стороны) выполнять любые команды из-под {{prg|ssh}}, запускать командную оболочку, входить для иных целей, помимо туннеля.
* Выбираю у себя номер порта и сообщаю его вам. (Пусть он обозначается '''PORT_NAME'''.) Возможна конфигурация, когда порт выбирается автоматически (как в конфигурации ниже); тогда заранее договариваться о номере порта не надо.


====вы: сохраняете конфигурацию====
====вы: сохраняете конфигурацию====
'''(делает тот же обычный пользователь, не root)'''
'''(делает тот же обычный пользователь, не root)'''


* Впишите в ~/.ssh/config конфигурацию (например, cat >> ~/.ssh/config -- дописывает в конец файла; потом Ctrl-D), о которой мы договорились:
* Впишите в {{path|~/.ssh/config}} конфигурацию (например, {{cmd|cat >> ~/.ssh/config}} -- дописывает в конец файла; потом Ctrl-D), о которой мы договорились:


   Host imz_tunnel
   Host '''{{{MY_NAME}}}'''_tunnel
       Hostname 79.165.57.121
       Hostname '''{{{MY_HOST}}}'''
       Port 2202
       Port '''{{{MY_HOST_SSHPORT}}}'''
       User tun_NAME
       User tun_'''NAME'''
       IdentityFile ~/.ssh/id_for_tunnel
       IdentityFile ~/.ssh/id_for_tun_'''NAME'''
       ForwardX11 no
       ForwardX11 no
       Compression yes
       Compression yes
Строка 33: Строка 49:
0 в качестве номера порта значит, что порт будет подобран автоматически (и напечатается ssh-клиентом -- см. команду ниже). В таком случае о номере порта можно заранее не договариваться.
0 в качестве номера порта значит, что порт будет подобран автоматически (и напечатается ssh-клиентом -- см. команду ниже). В таком случае о номере порта можно заранее не договариваться.


(NAME нужно заменить на имя, выделенное для вас.)
('''NAME''' нужно заменить на имя, выделенное для вас.)


Отредактировать ~/.ssh/config можно каким-нибудь текстовым редактором<ref>Какой-нибудь текстовый редактор: например, medit в [[Simply Linux]]: medit ~/.ssh/config; или, например, emacs -- [[Управление пакетами|пакет с ним можно поставить]], если он не стоит.</ref>.
(Вместо '''{{{MY_NAME}}}'''_tunnel можете придумать любое другое удобное для вас обозначение того, к кому вы пробрасываете туннель, и использовать его в командах ниже.)
 
Отредактировать {{path|~/.ssh/config}} можно каким-нибудь текстовым редактором<ref>Какой-нибудь текстовый редактор: например, {{prg|medit}} в [[Simply Linux]]: {{cmd|medit ~/.ssh/config}}; или, например, {{prg|emacs}} -- [[Управление пакетами|пакет с ним можно поставить]], если он не стоит.</ref>.
 
====мы: виден ли выделенный для вас порт снаружи====
Напомню себе и вам о ещё одном варианте строчки из этой конфигурации:
 
      RemoteForward *:0 localhost:22
 
или (при ручном выборе номера порта)
 
      RemoteForward *:'''PORT_NAME''' localhost:22
 
-- этот вариант нужен, если мы с вами договоримся, что назначенный для вас порт на моей стороне должен слушать на всех сетевых интерфейсах моего компьютера (и виден из моих локальных сетей). Тогда я смогу его легко пробросить и совсем наружу в интернет.
 
Я должен, чтобы слушание на всех интерфейсах работало, включить следующую опцию в {{path|/etc/openssh/sshd_config}}<ref>man ssh_config:<blockquote>If the bind_address is not specified, the default is to only bind to loopback addresses.  If the bind_address is ‘<code>*</code>’ or an empty string, then the forwarding is requested to listen on all interfaces.  Specifying a remote bind_address will only succeed if the server's <code>GatewayPorts</code> option is enabled (see {{path|sshd_config}}(5)).</blockquote></ref>:
 
    GatewayPorts yes


===Запуск туннеля===
===Запуск туннеля===
Строка 41: Строка 74:
'''(делает тот же обычный пользователь, не root)'''
'''(делает тот же обычный пользователь, не root)'''


* ssh imz_tunnel
* {{cmd|ssh '''{{{MY_NAME}}}'''_tunnel}}
 
(там будет написан номер выделенного порта у меня, если мы решили конфигурировать туннель с автоматическим выделением порта на моей стороне. Можете мне его сообщить -- будет обозначаться '''PORT_NAME'''.)


(там будет написан номер выделенного порта у меня, если мы решили конфигурировать туннель с автоматическим выделением порта на моей стороне. Можете мне его сообщить -- будет обозначаться PORT_NAME.)
На самом деле, в нашем деле "правильнее" было бы дать команду с опцией:
 
* {{cmd|ssh -N '''{{{MY_NAME}}}'''_tunnel}}
 
-- опция {{cmd|-N}} указывает ssh-клиенту, чтобы он только перенаправлял порты (т.е. создавал "туннель"), но не давал вам командную оболочку другого компьютера (моего, к которому вы подключаетесь). Я мог бы как раз и запретить специальному пользователю, под которым с моей стороны обслуживается туннель, работать с командной оболочкой (потому что исполнять команды на моём компьютере -- не наша цель).


==С вашей стороны: вход для меня==
==С вашей стороны: вход для меня==
'''([[Su|делается root]])'''
'''([[Su|делается root]])'''
(Ниже описаны самые обыкновенные действия для заведения пользователя для кого-то.)


====пользователь для меня и ключ====
====пользователь для меня и ключ====
* useradd -G wheel -m imz (группа wheel нужна, если я должен быть администратором)
(Вы можете узнать, какое имя пользователя я предпочитаю; здесь: '''{{{ME}}}'''.)
* Сообщайте мне пароль root, когда мне нужно администрировать, или добавьте меня в /etc/sudoers.<ref>На самом деле, например, в ALTLinux [[p7]] пользователи из группы wheel и так уже могут пользоваться sudo. Но чтобы пользоваться sudo, нужно иметь свой пароль. Его можете установить вы: passwd imz; или дать это сделать мне, когда я войду и стану администратором через [[su|su -]], узнав от вас ваш пароль root-а.</ref>
 
* cat >> ~imz/.ssh/authorized_keys
* {{cmd|useradd -G wheel -m '''{{{ME}}}'''}} (группа wheel нужна, если я должен быть администратором)
* Сообщайте мне пароль root, когда мне нужно администрировать, или добавьте меня в {{path|/etc/sudoers}}.<ref>На самом деле, например, в ALT Linux [[p7]] пользователи из группы wheel и так уже могут пользоваться {{prg|sudo}}. Но чтобы пользоваться {{prg|sudo}}, нужно иметь свой пароль. Его можете установить вы: {{cmd|passwd '''{{{ME}}}'''}}; или дать это сделать мне, когда я войду и стану администратором через [[su|{{cmd|su -}}]], узнав от вас ваш пароль root-а.</ref>
* {{cmd|cat >> ~'''{{{ME}}}'''/.ssh/authorized_keys}}


     ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAyUMWCDcoo3xlTilUObv06CKzCO+sj0fLHzIf9aBSa0jheHeknPP850S+65CU1Hds8gm4bLC1DWtDQ2ciIkEfDeKHBKpVpUKKbhs2b263Nw8ZEA1nR+C20lrvNM4XSft9DWpC3Z2pRsOYqs0e1rpUM0OotL15f/OUvhoeIP1fHpKrZPzWZ8tir5VTstL4d2jUZ1w0FJMwnPSK2uQ6hTMLXMfiBj5ZLLgXh+gd23x07i3X9I0AM3Jf6hMsrmpY6NrdhcSLQ12Zap3q7kO3tpR2Q10SobOEFRzKwjxwnrwVk29YWDaCm1L8m3bSbn1nmeMVok5Qquq/qRuTMzIuzsYLdw== imz@vaio
     '''{{{MY_PUBLIC_KEY}}}'''


====ssh-сервер у вас работает?====
====ssh-сервер у вас работает?====
* service sshd status
* {{cmd|service sshd status}}
* Если нет, включите: service sshd start
* Если нет, включите: {{cmd|service sshd start}}
* Если не стоит этот пакет, поставьте: apt-get install openssh-server
* Если не стоит этот пакет, поставьте: {{cmd|apt-get install openssh-server}}
* Включите навсегда: chkconfig sshd on
* Включите навсегда: {{cmd|chkconfig sshd on}}
* Посмотрите, будет ли он запускаться теперь всегда: chkconfig --list sshd<ref>похоже, что для systemd (например, в ALTLinux [[p7]]) эта команда никакой информации не даст... Какая же будет аналогичная команда? -- Подскажите кто-нибудь!</ref>
* Посмотрите, будет ли он запускаться теперь всегда: {{cmd|chkconfig sshd}}<ref>Для систем со старым-добрым SysV init можно использовать и команду {{cmd|chkconfig --list sshd}}; а для новомодного {{prg|systemd}} (например, в ALT Linux [[p7]]) эта команда даст информацию так:<pre>
# chkconfig sshd
Внимание: Отправляется запрос 'systemctl is-enabled sshd.service'.
disabled
#
</pre>
</ref>
 
====Замечание: ssh-сервер у вас безопасен?====
Вообще-то, если мы договоримся, что на порт, выделенный для Вас с моей стороны, надо пускать всех с Интернета, то стоит обеспокоиться тем, чтобы нельзя было Вас атаковать подбором паролей к Вашим пользователям, т.е. в настройках ssh-сервера запретить вход по паролю (останется вход по ключу). ('''TODO:''' написать конкретно!)


==Сессия удалённой работы/администрирования==
==Сессия удалённой работы/администрирования==
===я: иду===
===я: иду===
'''(обычный пользователь)'''
'''(обычный пользователь)'''
* ssh 0 -l imz -p PORT_NAME -v
* {{cmd|ssh 0 -l '''{{{ME}}}''' -p '''PORT_NAME''' -v}}
* su - или sudo su - (использую, соответственно, ваш пароль root-а или пароль пользователя imz, который вы установили -- их вы мн должны сообщить)
* {{cmd|su -}} или {{cmd|sudo su -}} (использую, соответственно, ваш пароль root-а или пароль пользователя '''{{{ME}}}''', который вы установили -- их вы мне должны сообщить)


==Автоматический туннель==
==Автоматический туннель==
Для большего удобства давайте позаботимся об автоматическом поддержании туннеля (средствами [http://packages.altlinux.org/en/Sisyphus/srpms/autossh autossh] и "обёрктой" вокруг него -- [http://packages.altlinux.org/en/Sisyphus/srpms/autosshd autosshd]).
Для большего удобства давайте позаботимся об автоматическом поддержании туннеля (средствами [http://packages.altlinux.org/en/Sisyphus/srpms/autossh autossh] и "обёрктой" вокруг него -- [http://packages.altlinux.org/en/Sisyphus/srpms/autosshd autosshd]).


Преимущество {{cmd|autossh}} перед {{cmd|ssh}} в том, что такая команда будет перезапускать ssh с туннелем в случае всяких проблем. (Вам не нужно будет вручную заново давать эту команду.)
Преимущество команды {{cmd|autossh}} перед {{cmd|ssh}} в том, что такая команда будет перезапускать {{prg|ssh}} с туннелем в случае всяких проблем. (Вам не нужно будет вручную заново давать эту команду.)


Преимущество же {{cmd|auosshd}} в том, что туннель будет запускаться сисмтемным сервисом, т.е. каждый раз при загрузке вашей системы, и вам не нужно будет об этом заботиться и давать самим команду. Это может также быть удобно, если я удалённо буду экспериментировать с перезагрузкой вашей системы. (Системный сервис, конечно, можно будет при желании отключить потом.)
Преимущество же {{prg|autosshd}} в том, что туннель будет запускаться системным сервисом, т.е. каждый раз при загрузке вашей системы, и вам не нужно будет об этом заботиться и давать самим команду. Это может также быть удобно, если я удалённо буду экспериментировать с перезагрузкой вашей системы. (Системный сервис, конечно, можно будет при желании отключить потом.)


Вот несколько всё более сложных усовершенствований:
Вот несколько всё более сложных усовершенствований:
Строка 79: Строка 131:
===вы: делайте autossh вместо ssh===
===вы: делайте autossh вместо ssh===
'''(делает ваш обычный пользователь)'''
'''(делает ваш обычный пользователь)'''
(Пакет {{pkg|autossh}} должен быть у вас установлен администратором, например, так: {{cmd|apt-get install autossh}}.)


Для [[#Запуск туннеля|запуска туннеля]] вместо
Для [[#Запуск туннеля|запуска туннеля]] вместо


    ssh -N imz_tunnel
* {{cmd|ssh -N '''{{{MY_NAME}}}'''_tunnel}}


попробуйте:
попробуйте:


     autossh -N imz_tunnel
* {{cmd|autossh -M 0 -N '''{{{MY_NAME}}}'''_tunnel}}
 
У {{prg|autossh}} обязательна опция {{cmd|-M}}, которая даёт порт для мониторинга соединения, но [http://git.altlinux.org/people/ldv/packages/?p=autossh.git;a=blob;f=autossh/README;h=3dc697db893ebcb1f26dfbc15e83337208a20517;hb=HEAD#l69 документация {{path|/usr/share/doc/autossh-1.4c/README}} говорит, что] современные {{prg|ssh}} могут сами это делать (см. опции <code>ServerAliveInterval</code>, <code>ServerAliveInterval</code>). {{cmd|-M 0}} как раз отключает этот мониторинг.
 
===вы: пусть специальный пользователь _autossh занимается туннелем===
'''([[Su|делается root]])'''
 
* предварительно поставьте {{prg|autosshd}} (версия пакета в репозитории пакетов Sisyphus могла уже измениться, конечно -- см.&nbsp;[http://packages.altlinux.org/en/Sisyphus/srpms/autosshd/get ссылки для скачивания]):
{{cmd|apt-get install ftp://ftp.altlinux.org/pub/distributions/ALTLinux/Sisyphus/files/noarch/RPMS/autosshd-0.0.2-alt8.noarch.rpm}}
 
(Лучше поставьте из архива именно ту версию, которую я "одобрил", т.е. с которой я проверял эту инструкцию: {{cmd|apt-get install ftp://ftp.altlinux.org/pub/distributions/archive/sisyphus/date/2014/01/31/noarch/RPMS.classic/autosshd-0.0.2-alt8.noarch.rpm}}! Чтобы не перезаписать конкретную версию при обновлении, можно добавить строчку <code>RPM::Hold { "^autosshd"; };</code> в конфигурацию APT, например, в отдельный новый файл {{path|/etc/apt/apt.conf.d/autosshd-tested.conf}}.)
 
Будет создан специальный пользователь _autossh с домашней директорией {{path|/var/lib/autosshd/}}.<ref>После установки autosshd-0.0.2-alt3 видим:<pre>
# fgrep ssh /etc/passwd
sshd:x:484:465::/var/empty:/dev/null
_autossh:x:480:458:Autossh daemon:/var/lib/autosshd:/dev/null
# rpm -qf /var/lib/autosshd --scripts
preinstall scriptlet (through /bin/sh):
# Add the "_autossh" user
/usr/sbin/groupadd -r -f _autossh 2>/dev/null ||:
/usr/sbin/useradd  -r -g _autossh -c 'Autossh daemon' \
-s /dev/null -d /var/lib/autosshd _autossh 2>/dev/null ||:
/usr/sbin/usermod -p `pwgen -s 24 1` _autossh
postinstall scriptlet (through /bin/sh):
if [ ! -f /var/lib/autosshd/.ssh/id_dsa ]; then
    mkdir -p /var/lib/autosshd/.ssh
    /usr/bin/ssh-keygen -t dsa -b 1024 -C "AutoSSH daemon" -N "" -q -f /var/lib/autosshd/.ssh/id_dsa
    echo "StrictHostKeyChecking no" > /var/lib/autosshd/.ssh/config
    cp /var/lib/autosshd/.ssh/id_dsa.pub /var/lib/autosshd/.ssh/authorized_keys
fi
chown -R _autossh:_autossh /var/lib/autosshd/
chown _autossh:_autossh /var/run/autossh.d/
 
/usr/sbin/post_service autosshd
preuninstall scriptlet (through /bin/sh):
/usr/sbin/preun_service autosshd
postuninstall scriptlet (through /bin/sh):
/usr/sbin/userdel -r _autossh 2>/dev/null ||:
/usr/sbin/groupdel -r _autossh 2>/dev/null ||:
#
</pre></ref>
 
* перенесите настройки ssh-туннеля к этому специальному пользователю ('''YOU''' -- имя вашего обычного пользователя):
** {{cmd|cp -v ~'''YOU'''/.ssh/id_for_tun_'''NAME'''* ~_autossh/.ssh/}}
** {{cmd|cat ~'''YOU'''/.ssh/config >> ~_autossh/.ssh/config}}
** {{cmd|chown _autossh:_autossh -R ~_autossh/.ssh}}
 
Теперь вашу обычную команду инициации туннеля ({{cmd|ssh -N '''{{{MY_NAME}}}'''_tunnel}}) можно исполнять от имени нового специального пользователя; так вы будете в большей безопасности от атак из сети и от ошибок в {{prg|ssh}} (ваши личные данные, с которыми вы работаете от имени своего обычного пользователя, а также вся система в случае, если вы можете переключаться в администратора -- если вы в группе wheel). Однако специальный пользователь _autossh настроен так, что под ним "зайти" в систему нельзя, поэтому просто самому проверить и запустить {{cmd|ssh -N '''{{{MY_NAME}}}'''_tunnel}}, сделав, скажем, {{cmd|su - _autossh}}, не получится. Можно рассматривать сделанные нами настройки ssh для пользователя _autossh как задел для работы {{prg|autosshd}} (или как пример того, что эти настройки можно сделать под каким-то другим пользователем и от этого может быть польза).
 
===вы: настройка autosshd===
* настройки в файле {{path|/etc/autossh.d/'''{{{MY_NAME}}}'''_tunnel.conf}} (нужен какой-нибудь ненулевой AUTOSSH_PORT!<ref>Хоть сам {{prg|autossh}} может работать с современным {{prg|ssh}} с {{cmd|-M 0}}, но {{prg|autosshd}} устроен [http://git.altlinux.org/people/lav/packages/?p=autosshd.git;a=blob;f=autosshd/etc/rc.d/init.d/autosshd;h=d9924e0238a84c56928cd3e1af9eb61f3b414c48;hb=HEAD#l84 так, что он по номеру этого заданного порта выслеживает процесс {{prg|autossh}}] (и потом управляет им).</ref> и в опциях {{prg|(auto)ssh}} должна быть {{cmd|-N}}!):
 
    #usage: autossh [-V] [-M monitor_port[:echo_port]] [-f] [SSH_OPTIONS]
    #
    #    -M specifies monitor port. May be overridden by environment
    #      variable AUTOSSH_PORT. 0 turns monitoring loop off.
    #      Alternatively, a port for an echo service on the remote
    #      machine may be specified. (Normally port 7.)
    #    -f run in background (autossh handles this, and does not  pass it to ssh.)
     #    -V print autossh version and exit.
    #
    #Environment variables are:
    #    AUTOSSH_LOGLEVEL    - level of log verbosity
    AUTOSSH_LOGLEVEL=4
   
    #    AUTOSSH_MESSAGE    - message to append to echo string (max 64 bytes)
    #    AUTOSSH_PIDFILE    - write pid to this file
    #    AUTOSSH_FIRST_POLL  - time before first connection check (seconds)
    #
   
    #    AUTOSSH_POLL        - how often to check the connection (seconds)
    #AUTOSSH_POLL=600
    #    AUTOSSH_PORT        - port to use for monitor connection
    #AUTOSSH_PORT=20000
    #    AUTOSSH_GATETIME    - how long must an ssh session be established
    #                          before we decide it really was established
    #                          (in seconds). Default is 30 seconds; use of -f
    #                          flag sets this to 0.
    #AUTOSSH_GATETIME=30
    #    AUTOSSH_LOGFILE    - file to log to (default is to use the syslog facility)
    #AUTOSSH_LOGFILE=$HOST.log
   
    #    AUTOSSH_DEBUG      - turn logging to maximum verbosity and log to stderr
    AUTOSSH_DEBUG=yes
   
    #    AUTOSSH_PATH        - path to ssh if not default
    #AUTOSSH_PATH=/usr/local/bin/ssh
   
    #    AUTOSSH_MAXSTART    - max times to restart (default is no limit)
    #AUTOSSH_MAXSTART=100
   
    #    AUTOSSH_MAXLIFETIME - set the maximum time to live (seconds)
   
    AUTOSSH_PIDFILE=/var/run/autosshd/'''{{{MY_NAME}}}'''_tunnel.pid
    AUTOSSH_LOCKFILE='''{{{MY_NAME}}}'''_tunnel.lck
    AUTOSSH_LOGFILE=/var/lib/autosshd/'''{{{MY_NAME}}}'''_tunnel.log
   
    HOST='''{{{MY_NAME}}}'''_tunnel
    USER=_autossh
   
    #AUTOSSH_PORT parameter must be unique for each connection and can not be 0
    AUTOSSH_PORT=6666
   
    MANUAL=no
   
    AUTOSSH_OPTIONS=" -M ${AUTOSSH_PORT} -f -N ${HOST}"
 
 
* для удобства в {{path|/var/lib/autosshd/.ssh/config}} предлагается назначить фиксированный порт на моей стороне -- '''PORT_NAME''', о котором мы договорились (т.е. который я вам выделил и сообщил); вместо
 
      RemoteForward 0 localhost:22
 
сделайте:
 
      RemoteForward '''PORT_NAME''' localhost:22
 
например, что-нибудь вроде (Предупреждение: это совсем не тот порт, что AUTOSSH_PORT, который появлялся просто как часть внутренней кухни, несовершенной):
 
      RemoteForward '''6060''' localhost:22
 
* проверка, запускается ли настроенный сервис -- как обычно:
** вы запускаете: {{cmd|service autosshd start}}
** вы смотрите о его состоянии: {{cmd|service autosshd status}}
** я проверяю: {{cmd|ssh 0 -p '''PORT_NAME''' -l '''{{{ME}}}'''}} (могу также вписать эти параметры в раздел вроде "Host '''NAME'''" в свой {{path|~/.ssh/config}})


(Пакет autossh должен быть у вас установлен администратором, например, так: {{cmd|apt-get install autossh}}.)
* включаем сервис на каждый запуск системы -- как обычно:
** включен ли уже: {{cmd|chkconfig --list autosshd}}
** пусть будет включён: {{cmd|chkconfig autosshd on}}
** включен ли теперь: {{cmd|chkconfig --list autosshd}}


==Примечания (о частных особенностях систем)==
==Примечания (о частных особенностях систем)==
<references />
<references />
{{Category navigation|title=HOWTO|category=HOWTO|sortkey={{SUBPAGENAME}}}}

Текущая версия от 08:02, 31 мая 2019

Здесь будет подробно рассказано, как дать кому-то доступ на ваш (мобильный) компьютер через туннель.

Туннель нужен, если у вашего компьютера нет постоянного адреса в Интернете. Это будет удобно, если вы ездите с ним и подключаетесь к Интернету по-разному.

(Иногда в подобных ситуациях люди используют проприетарный TeamViewer. Можно обойтись без него и иметь всё под своим контролем.)

Туннель (на самом деле, проброс одного порта) будет создаваться средствами ssh (openssh-client), autossh, autosshd. Это основная задача, описанию решения которой посвящён этот рассказ.

  • кому-то в этом руководстве будет названо я для простоты.
  • ssh в этом рассказе появится ещё и в другой роли: как средство входа для меня на ваш компьютер (с вашей стороны это обеспечивает openssh-server). Но эти две роли независимы друг от друга.
  • Считается, что я имею больше опыта администрирования, поэтому указания для вас подробные, а для меня -- краткие, схематичные.

Туннель

Конфигурация туннеля

вы и я: ваше имя

  • Договоримся об имени для вашего компьютера (по которому я буду вести у себя учёт). Обозначим его NAME; дальше вместо NAME будем подставлять это выбранное ваше имя.

вы: ваш ключ, которому я позволю делать туннель у меня

(делает обычный пользователь, не root)

  • ssh-keygen -f ~/.ssh/id_for_tun_NAME -C 'tunnel wanted by NAME'
  • Сообщите мне его открытую (т.н. "публичную") часть: cat ~/.ssh/id_for_tun_NAME.pub

с моей стороны: пользователь и выбор порта для туннеля

(делает администратор)

  • useradd -m tun_NAME
  • Позволяю входить по вашему ключу: cat >> ~tun_NAME/.ssh/authorized_keys (Заготовка файла ~tun_NAME/.ssh/authorized_keys уже будет после useradd.)
  • TODO: Хорошо бы ещё запретить этому специальному пользователю (для обслуживания туннеля с моей стороны) выполнять любые команды из-под ssh, запускать командную оболочку, входить для иных целей, помимо туннеля.
  • Выбираю у себя номер порта и сообщаю его вам. (Пусть он обозначается PORT_NAME.) Возможна конфигурация, когда порт выбирается автоматически (как в конфигурации ниже); тогда заранее договариваться о номере порта не надо.

вы: сохраняете конфигурацию

(делает тот же обычный пользователь, не root)

  • Впишите в ~/.ssh/config конфигурацию (например, cat >> ~/.ssh/config -- дописывает в конец файла; потом Ctrl-D), о которой мы договорились:
 Host {{{MY_NAME}}}_tunnel
      Hostname {{{MY_HOST}}}
      Port {{{MY_HOST_SSHPORT}}}
      User tun_NAME
      IdentityFile ~/.ssh/id_for_tun_NAME
      ForwardX11 no
      Compression yes
      CompressionLevel 9
      RemoteForward 0 localhost:22

0 в качестве номера порта значит, что порт будет подобран автоматически (и напечатается ssh-клиентом -- см. команду ниже). В таком случае о номере порта можно заранее не договариваться.

(NAME нужно заменить на имя, выделенное для вас.)

(Вместо {{{MY_NAME}}}_tunnel можете придумать любое другое удобное для вас обозначение того, к кому вы пробрасываете туннель, и использовать его в командах ниже.)

Отредактировать ~/.ssh/config можно каким-нибудь текстовым редактором[1].

мы: виден ли выделенный для вас порт снаружи

Напомню себе и вам о ещё одном варианте строчки из этой конфигурации:

      RemoteForward *:0 localhost:22

или (при ручном выборе номера порта)

      RemoteForward *:PORT_NAME localhost:22

-- этот вариант нужен, если мы с вами договоримся, что назначенный для вас порт на моей стороне должен слушать на всех сетевых интерфейсах моего компьютера (и виден из моих локальных сетей). Тогда я смогу его легко пробросить и совсем наружу в интернет.

Я должен, чтобы слушание на всех интерфейсах работало, включить следующую опцию в /etc/openssh/sshd_config[2]:

   GatewayPorts yes

Запуск туннеля

вы: инициируете туннель (каждый раз, когда нужно)

(делает тот же обычный пользователь, не root)

  • ssh {{{MY_NAME}}}_tunnel

(там будет написан номер выделенного порта у меня, если мы решили конфигурировать туннель с автоматическим выделением порта на моей стороне. Можете мне его сообщить -- будет обозначаться PORT_NAME.)

На самом деле, в нашем деле "правильнее" было бы дать команду с опцией:

  • ssh -N {{{MY_NAME}}}_tunnel

-- опция -N указывает ssh-клиенту, чтобы он только перенаправлял порты (т.е. создавал "туннель"), но не давал вам командную оболочку другого компьютера (моего, к которому вы подключаетесь). Я мог бы как раз и запретить специальному пользователю, под которым с моей стороны обслуживается туннель, работать с командной оболочкой (потому что исполнять команды на моём компьютере -- не наша цель).

С вашей стороны: вход для меня

(делается root)

(Ниже описаны самые обыкновенные действия для заведения пользователя для кого-то.)

пользователь для меня и ключ

(Вы можете узнать, какое имя пользователя я предпочитаю; здесь: {{{ME}}}.)

  • useradd -G wheel -m {{{ME}}} (группа wheel нужна, если я должен быть администратором)
  • Сообщайте мне пароль root, когда мне нужно администрировать, или добавьте меня в /etc/sudoers.[3]
  • cat >> ~{{{ME}}}/.ssh/authorized_keys
   {{{MY_PUBLIC_KEY}}}

ssh-сервер у вас работает?

  • service sshd status
  • Если нет, включите: service sshd start
  • Если не стоит этот пакет, поставьте: apt-get install openssh-server
  • Включите навсегда: chkconfig sshd on
  • Посмотрите, будет ли он запускаться теперь всегда: chkconfig sshd[4]

Замечание: ssh-сервер у вас безопасен?

Вообще-то, если мы договоримся, что на порт, выделенный для Вас с моей стороны, надо пускать всех с Интернета, то стоит обеспокоиться тем, чтобы нельзя было Вас атаковать подбором паролей к Вашим пользователям, т.е. в настройках ssh-сервера запретить вход по паролю (останется вход по ключу). (TODO: написать конкретно!)

Сессия удалённой работы/администрирования

я: иду

(обычный пользователь)

  • ssh 0 -l {{{ME}}} -p PORT_NAME -v
  • su - или sudo su - (использую, соответственно, ваш пароль root-а или пароль пользователя {{{ME}}}, который вы установили -- их вы мне должны сообщить)

Автоматический туннель

Для большего удобства давайте позаботимся об автоматическом поддержании туннеля (средствами autossh и "обёрктой" вокруг него -- autosshd).

Преимущество команды autossh перед ssh в том, что такая команда будет перезапускать ssh с туннелем в случае всяких проблем. (Вам не нужно будет вручную заново давать эту команду.)

Преимущество же autosshd в том, что туннель будет запускаться системным сервисом, т.е. каждый раз при загрузке вашей системы, и вам не нужно будет об этом заботиться и давать самим команду. Это может также быть удобно, если я удалённо буду экспериментировать с перезагрузкой вашей системы. (Системный сервис, конечно, можно будет при желании отключить потом.)

Вот несколько всё более сложных усовершенствований:

вы: делайте autossh вместо ssh

(делает ваш обычный пользователь)

(Пакет autossh должен быть у вас установлен администратором, например, так: apt-get install autossh.)

Для запуска туннеля вместо

  • ssh -N {{{MY_NAME}}}_tunnel

попробуйте:

  • autossh -M 0 -N {{{MY_NAME}}}_tunnel

У autossh обязательна опция -M, которая даёт порт для мониторинга соединения, но документация /usr/share/doc/autossh-1.4c/README говорит, что современные ssh могут сами это делать (см. опции ServerAliveInterval, ServerAliveInterval). -M 0 как раз отключает этот мониторинг.

вы: пусть специальный пользователь _autossh занимается туннелем

(делается root)

  • предварительно поставьте autosshd (версия пакета в репозитории пакетов Sisyphus могла уже измениться, конечно -- см. ссылки для скачивания):

apt-get install ftp://ftp.altlinux.org/pub/distributions/ALTLinux/Sisyphus/files/noarch/RPMS/autosshd-0.0.2-alt8.noarch.rpm

(Лучше поставьте из архива именно ту версию, которую я "одобрил", т.е. с которой я проверял эту инструкцию: apt-get install ftp://ftp.altlinux.org/pub/distributions/archive/sisyphus/date/2014/01/31/noarch/RPMS.classic/autosshd-0.0.2-alt8.noarch.rpm! Чтобы не перезаписать конкретную версию при обновлении, можно добавить строчку RPM::Hold { "^autosshd"; }; в конфигурацию APT, например, в отдельный новый файл /etc/apt/apt.conf.d/autosshd-tested.conf.)

Будет создан специальный пользователь _autossh с домашней директорией /var/lib/autosshd/.[5]

  • перенесите настройки ssh-туннеля к этому специальному пользователю (YOU -- имя вашего обычного пользователя):
    • cp -v ~YOU/.ssh/id_for_tun_NAME* ~_autossh/.ssh/
    • cat ~YOU/.ssh/config >> ~_autossh/.ssh/config
    • chown _autossh:_autossh -R ~_autossh/.ssh

Теперь вашу обычную команду инициации туннеля (ssh -N {{{MY_NAME}}}_tunnel) можно исполнять от имени нового специального пользователя; так вы будете в большей безопасности от атак из сети и от ошибок в ssh (ваши личные данные, с которыми вы работаете от имени своего обычного пользователя, а также вся система в случае, если вы можете переключаться в администратора -- если вы в группе wheel). Однако специальный пользователь _autossh настроен так, что под ним "зайти" в систему нельзя, поэтому просто самому проверить и запустить ssh -N {{{MY_NAME}}}_tunnel, сделав, скажем, su - _autossh, не получится. Можно рассматривать сделанные нами настройки ssh для пользователя _autossh как задел для работы autosshd (или как пример того, что эти настройки можно сделать под каким-то другим пользователем и от этого может быть польза).

вы: настройка autosshd

  • настройки в файле /etc/autossh.d/{{{MY_NAME}}}_tunnel.conf (нужен какой-нибудь ненулевой AUTOSSH_PORT![6] и в опциях (auto)ssh должна быть -N!):
   #usage: autossh [-V] [-M monitor_port[:echo_port]] [-f] [SSH_OPTIONS]
   #
   #    -M specifies monitor port. May be overridden by environment
   #       variable AUTOSSH_PORT. 0 turns monitoring loop off.
   #       Alternatively, a port for an echo service on the remote
   #       machine may be specified. (Normally port 7.)
   #    -f run in background (autossh handles this, and does not  pass it to ssh.)
   #    -V print autossh version and exit.
   #
   #Environment variables are:
   #    AUTOSSH_LOGLEVEL    - level of log verbosity
   AUTOSSH_LOGLEVEL=4
   
   #    AUTOSSH_MESSAGE     - message to append to echo string (max 64 bytes)
   #    AUTOSSH_PIDFILE     - write pid to this file
   #    AUTOSSH_FIRST_POLL  - time before first connection check (seconds)
   #
   
   #    AUTOSSH_POLL        - how often to check the connection (seconds)
   #AUTOSSH_POLL=600
   #    AUTOSSH_PORT        - port to use for monitor connection
   #AUTOSSH_PORT=20000
   #    AUTOSSH_GATETIME    - how long must an ssh session be established
   #                          before we decide it really was established
   #                          (in seconds). Default is 30 seconds; use of -f
   #                          flag sets this to 0.
   #AUTOSSH_GATETIME=30
   #    AUTOSSH_LOGFILE     - file to log to (default is to use the syslog facility)
   #AUTOSSH_LOGFILE=$HOST.log
   
   #    AUTOSSH_DEBUG       - turn logging to maximum verbosity and log to stderr
   AUTOSSH_DEBUG=yes 
   
   #    AUTOSSH_PATH        - path to ssh if not default
   #AUTOSSH_PATH=/usr/local/bin/ssh
   
   #    AUTOSSH_MAXSTART    - max times to restart (default is no limit)
   #AUTOSSH_MAXSTART=100
   
   #    AUTOSSH_MAXLIFETIME - set the maximum time to live (seconds)
   
   AUTOSSH_PIDFILE=/var/run/autosshd/{{{MY_NAME}}}_tunnel.pid
   AUTOSSH_LOCKFILE={{{MY_NAME}}}_tunnel.lck
   AUTOSSH_LOGFILE=/var/lib/autosshd/{{{MY_NAME}}}_tunnel.log
   
   HOST={{{MY_NAME}}}_tunnel
   USER=_autossh
   
   #AUTOSSH_PORT parameter must be unique for each connection and can not be 0
   AUTOSSH_PORT=6666
   
   MANUAL=no
   
   AUTOSSH_OPTIONS=" -M ${AUTOSSH_PORT} -f -N ${HOST}"


  • для удобства в /var/lib/autosshd/.ssh/config предлагается назначить фиксированный порт на моей стороне -- PORT_NAME, о котором мы договорились (т.е. который я вам выделил и сообщил); вместо
     RemoteForward 0 localhost:22

сделайте:

     RemoteForward PORT_NAME localhost:22

например, что-нибудь вроде (Предупреждение: это совсем не тот порт, что AUTOSSH_PORT, который появлялся просто как часть внутренней кухни, несовершенной):

     RemoteForward 6060 localhost:22
  • проверка, запускается ли настроенный сервис -- как обычно:
    • вы запускаете: service autosshd start
    • вы смотрите о его состоянии: service autosshd status
    • я проверяю: ssh 0 -p PORT_NAME -l {{{ME}}} (могу также вписать эти параметры в раздел вроде "Host NAME" в свой ~/.ssh/config)
  • включаем сервис на каждый запуск системы -- как обычно:
    • включен ли уже: chkconfig --list autosshd
    • пусть будет включён: chkconfig autosshd on
    • включен ли теперь: chkconfig --list autosshd

Примечания (о частных особенностях систем)

  1. Какой-нибудь текстовый редактор: например, medit в Simply Linux: medit ~/.ssh/config; или, например, emacs -- пакет с ним можно поставить, если он не стоит.
  2. man ssh_config:

    If the bind_address is not specified, the default is to only bind to loopback addresses. If the bind_address is ‘*’ or an empty string, then the forwarding is requested to listen on all interfaces. Specifying a remote bind_address will only succeed if the server's GatewayPorts option is enabled (see sshd_config(5)).

  3. На самом деле, например, в ALT Linux p7 пользователи из группы wheel и так уже могут пользоваться sudo. Но чтобы пользоваться sudo, нужно иметь свой пароль. Его можете установить вы: passwd {{{ME}}}; или дать это сделать мне, когда я войду и стану администратором через su -, узнав от вас ваш пароль root-а.
  4. Для систем со старым-добрым SysV init можно использовать и команду chkconfig --list sshd; а для новомодного systemd (например, в ALT Linux p7) эта команда даст информацию так:
    # chkconfig sshd
    Внимание: Отправляется запрос 'systemctl is-enabled sshd.service'.
    disabled
    # 
    
  5. После установки autosshd-0.0.2-alt3 видим:
    # fgrep ssh /etc/passwd
    sshd:x:484:465::/var/empty:/dev/null
    _autossh:x:480:458:Autossh daemon:/var/lib/autosshd:/dev/null
    # rpm -qf /var/lib/autosshd --scripts 
    preinstall scriptlet (through /bin/sh):
    # Add the "_autossh" user
    /usr/sbin/groupadd -r -f _autossh 2>/dev/null ||:
    /usr/sbin/useradd  -r -g _autossh -c 'Autossh daemon' \
    	-s /dev/null -d /var/lib/autosshd _autossh 2>/dev/null ||:
    /usr/sbin/usermod -p `pwgen -s 24 1` _autossh
    postinstall scriptlet (through /bin/sh):
    if [ ! -f /var/lib/autosshd/.ssh/id_dsa ]; then
        mkdir -p /var/lib/autosshd/.ssh
        /usr/bin/ssh-keygen -t dsa -b 1024 -C "AutoSSH daemon" -N "" -q -f /var/lib/autosshd/.ssh/id_dsa
        echo "StrictHostKeyChecking no" > /var/lib/autosshd/.ssh/config
        cp /var/lib/autosshd/.ssh/id_dsa.pub /var/lib/autosshd/.ssh/authorized_keys
    fi
    chown -R _autossh:_autossh /var/lib/autosshd/
    chown _autossh:_autossh /var/run/autossh.d/
    
    /usr/sbin/post_service autosshd
    preuninstall scriptlet (through /bin/sh):
    /usr/sbin/preun_service autosshd
    postuninstall scriptlet (through /bin/sh):
    /usr/sbin/userdel -r _autossh 2>/dev/null ||:
    /usr/sbin/groupdel -r _autossh 2>/dev/null ||:
    # 
    
  6. Хоть сам autossh может работать с современным ssh с -M 0, но autosshd устроен так, что он по номеру этого заданного порта выслеживает процесс autossh (и потом управляет им).