Как Ваш компьютер может дать доступ к себе через туннель средствами ssh, autossh, autosshd
Материал из ALT Linux Wiki
м (→вы: ваш ключ, которому я позволю делать туннель у меня: более простое слово) |
м (Иногда в подобных ситуациях люди используют проприетарный TeamViewer) |
||
(72 промежуточные версии не показаны) | |||
Строка 1: | Строка 1: | ||
- | [[ | + | Здесь будет подробно рассказано, как дать ''кому-то'' доступ на ваш (мобильный) компьютер через туннель. |
+ | |||
+ | Туннель нужен, если у вашего компьютера нет постоянного адреса в Интернете. Это будет удобно, если вы ездите с ним и подключаетесь к Интернету по-разному. | ||
+ | |||
+ | (Иногда в подобных ситуациях люди используют проприетарный 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''' будем подставлять это выбранное ваше имя. |
====вы: ваш ключ, которому я позволю делать туннель у меня==== | ====вы: ваш ключ, которому я позволю делать туннель у меня==== | ||
- | * ssh-keygen -f ~/.ssh/ | + | '''(делает обычный пользователь, не root)''' |
- | * Сообщите мне его открытую (т. | + | * {{cmd|ssh-keygen -f ~/.ssh/id_for_tun_'''NAME''' -C 'tunnel wanted by '''NAME''''}} |
+ | * Сообщите мне его открытую (т.н. "публичную") часть: {{cmd|cat ~/.ssh/id_for_tun_'''NAME'''.pub}} | ||
- | ====с моей стороны: пользователь и | + | ====с моей стороны: пользователь и выбор порта для туннеля==== |
- | * useradd -m | + | '''(делает администратор)''' |
- | * Позволяю входить по вашему ключу: cat > ~/.ssh/authorized_keys | + | * {{cmd|useradd -m tun_'''NAME'''}} |
- | * Выбираю у себя номер порта и сообщаю его вам. (Пусть он обозначается PORT_NAME.) | + | * Позволяю входить по вашему ключу: {{cmd|cat >> ~tun_'''NAME'''/.ssh/authorized_keys}} (Заготовка файла {{path|~tun_'''NAME'''/.ssh/authorized_keys}} уже будет после {{cmd|useradd}}.) |
+ | * '''TODO:''' Хорошо бы ещё запретить этому специальному пользователю (для обслуживания туннеля с моей стороны) выполнять любые команды из-под {{prg|ssh}}, запускать командную оболочку, входить для иных целей, помимо туннеля. | ||
+ | * Выбираю у себя номер порта и сообщаю его вам. (Пусть он обозначается '''PORT_NAME'''.) Возможна конфигурация, когда порт выбирается автоматически (как в конфигурации ниже); тогда заранее договариваться о номере порта не надо. | ||
====вы: сохраняете конфигурацию==== | ====вы: сохраняете конфигурацию==== | ||
- | + | '''(делает тот же обычный пользователь, не root)''' | |
- | Host | + | * Впишите в {{path|~/.ssh/config}} конфигурацию (например, {{cmd|cat >> ~/.ssh/config}} -- дописывает в конец файла; потом Ctrl-D), о которой мы договорились: |
- | Hostname | + | |
- | Port | + | Host '''{{{MY_NAME}}}'''_tunnel |
- | User | + | Hostname '''{{{MY_HOST}}}''' |
- | IdentityFile ~/.ssh/ | + | Port '''{{{MY_HOST_SSHPORT}}}''' |
+ | User tun_'''NAME''' | ||
+ | IdentityFile ~/.ssh/id_for_tun_'''NAME''' | ||
ForwardX11 no | ForwardX11 no | ||
Compression yes | Compression yes | ||
CompressionLevel 9 | CompressionLevel 9 | ||
RemoteForward 0 localhost:22 | RemoteForward 0 localhost:22 | ||
+ | |||
+ | 0 в качестве номера порта значит, что порт будет подобран автоматически (и напечатается ssh-клиентом -- см. команду ниже). В таком случае о номере порта можно заранее не договариваться. | ||
+ | |||
+ | ('''NAME''' нужно заменить на имя, выделенное для вас.) | ||
+ | |||
+ | (Вместо '''{{{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 | ||
===Запуск туннеля=== | ===Запуск туннеля=== | ||
==== вы: инициируете туннель (каждый раз, когда нужно)==== | ==== вы: инициируете туннель (каждый раз, когда нужно)==== | ||
- | * ssh | + | '''(делает тот же обычный пользователь, не root)''' |
+ | |||
+ | * {{cmd|ssh '''{{{MY_NAME}}}'''_tunnel}} | ||
+ | |||
+ | (там будет написан номер выделенного порта у меня, если мы решили конфигурировать туннель с автоматическим выделением порта на моей стороне. Можете мне его сообщить -- будет обозначаться '''PORT_NAME'''.) | ||
+ | |||
+ | На самом деле, в нашем деле "правильнее" было бы дать команду с опцией: | ||
+ | |||
+ | * {{cmd|ssh -N '''{{{MY_NAME}}}'''_tunnel}} | ||
+ | |||
+ | -- опция {{cmd|-N}} указывает ssh-клиенту, чтобы он только перенаправлял порты (т.е. создавал "туннель"), но не давал вам командную оболочку другого компьютера (моего, к которому вы подключаетесь). Я мог бы как раз и запретить специальному пользователю, под которым с моей стороны обслуживается туннель, работать с командной оболочкой (потому что исполнять команды на моём компьютере -- не наша цель). | ||
==С вашей стороны: вход для меня== | ==С вашей стороны: вход для меня== | ||
+ | '''([[Su|делается root]])''' | ||
+ | |||
+ | (Ниже описаны самые обыкновенные действия для заведения пользователя для кого-то.) | ||
+ | |||
====пользователь для меня и ключ==== | ====пользователь для меня и ключ==== | ||
- | + | (Вы можете узнать, какое имя пользователя я предпочитаю; здесь: '''{{{ME}}}'''.) | |
- | + | ||
- | + | ||
- | + | * {{cmd|useradd -G wheel -m '''{{{ME}}}'''}} (группа wheel нужна, если я должен быть администратором) | |
+ | * Сообщайте мне пароль root, когда мне нужно администрировать, или добавьте меня в {{path|/etc/sudoers}}.<ref>На самом деле, например, в ALTLinux [[p7]] пользователи из группы wheel и так уже могут пользоваться {{prg|sudo}}. Но чтобы пользоваться {{prg|sudo}}, нужно иметь свой пароль. Его можете установить вы: {{cmd|passwd '''{{{ME}}}'''}}; или дать это сделать мне, когда я войду и стану администратором через [[su|{{cmd|su -}}]], узнав от вас ваш пароль root-а.</ref> | ||
+ | * {{cmd|cat >> ~'''{{{ME}}}'''/.ssh/authorized_keys}} | ||
+ | |||
+ | '''{{{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}} |
+ | * Посмотрите, будет ли он запускаться теперь всегда: {{cmd|chkconfig sshd}}<ref>Для систем со старым-добрым SysV init можно использовать и команду {{cmd|chkconfig --list sshd}}; а для новомодного {{prg|systemd}} (например, в ALTLinux [[p7]]) эта команда даст информацию так:<pre> | ||
+ | # chkconfig sshd | ||
+ | Внимание: Отправляется запрос 'systemctl is-enabled sshd.service'. | ||
+ | disabled | ||
+ | # | ||
+ | </pre> | ||
+ | </ref> | ||
+ | |||
+ | ====Замечание: ssh-сервер у вас безопасен?==== | ||
+ | Вообще-то, если мы договоримся, что на порт, выделенный для Вас с моей стороны, надо пускать всех с Интернета, то стоит обеспокоиться тем, чтобы нельзя было Вас атаковать подбором паролей к Вашим пользователям, т.е. в настройках ssh-сервера запретить вход по паролю (останется вход по ключу). ('''TODO:''' написать конкретно!) | ||
+ | |||
+ | ==Сессия удалённой работы/администрирования== | ||
+ | ===я: иду=== | ||
+ | '''(обычный пользователь)''' | ||
+ | * {{cmd|ssh 0 -l '''{{{ME}}}''' -p '''PORT_NAME''' -v}} | ||
+ | * {{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]). | ||
+ | |||
+ | Преимущество команды {{cmd|autossh}} перед {{cmd|ssh}} в том, что такая команда будет перезапускать {{prg|ssh}} с туннелем в случае всяких проблем. (Вам не нужно будет вручную заново давать эту команду.) | ||
+ | |||
+ | Преимущество же {{prg|autosshd}} в том, что туннель будет запускаться системным сервисом, т.е. каждый раз при загрузке вашей системы, и вам не нужно будет об этом заботиться и давать самим команду. Это может также быть удобно, если я удалённо буду экспериментировать с перезагрузкой вашей системы. (Системный сервис, конечно, можно будет при желании отключить потом.) | ||
+ | |||
+ | Вот несколько всё более сложных усовершенствований: | ||
+ | |||
+ | ===вы: делайте autossh вместо ssh=== | ||
+ | '''(делает ваш обычный пользователь)''' | ||
+ | |||
+ | (Пакет {{pkg|autossh}} должен быть у вас установлен администратором, например, так: {{cmd|apt-get install autossh}}.) | ||
+ | |||
+ | Для [[#Запуск туннеля|запуска туннеля]] вместо | ||
+ | |||
+ | * {{cmd|ssh -N '''{{{MY_NAME}}}'''_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 могла уже измениться, конечно -- см. [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}}) | ||
+ | |||
+ | * включаем сервис на каждый запуск системы -- как обычно: | ||
+ | ** включен ли уже: {{cmd|chkconfig --list autosshd}} | ||
+ | ** пусть будет включён: {{cmd|chkconfig autosshd on}} | ||
+ | ** включен ли теперь: {{cmd|chkconfig --list autosshd}} | ||
+ | |||
+ | ==Примечания (о частных особенностях систем)== | ||
+ | <references /> | ||
+ | {{Category navigation|title=HOWTO|category=HOWTO|sortkey={{SUBPAGENAME}}}} |
Текущая версия на 09:24, 23 ноября 2015
Здесь будет подробно рассказано, как дать кому-то доступ на ваш (мобильный) компьютер через туннель.
Туннель нужен, если у вашего компьютера нет постоянного адреса в Интернете. Это будет удобно, если вы ездите с ним и подключаетесь к Интернету по-разному.
(Иногда в подобных ситуациях люди используют проприетарный TeamViewer. Можно обойтись без него и иметь всё под своим контролем.)
Туннель (на самом деле, проброс одного порта) будет создаваться средствами ssh (openssh-client), autossh, autosshd. Это основная задача, описанию решения которой посвящён этот рассказ.
- кому-то в этом руководстве будет названо я для простоты.
- ssh в этом рассказе появится ещё и в другой роли: как средство входа для меня на ваш компьютер (с вашей стороны это обеспечивает openssh-server). Но эти две роли независимы друг от друга.
- Считается, что я имею больше опыта администрирования, поэтому указания для вас подробные, а для меня -- краткие, схематичные.
- Я должен буду вам сообщить, а вы подставить конкретные значения для моих данных: {{{MY_HOST}}}, {{{MY_HOST_SSHPORT}}}, {{{MY_PUBLIC_KEY}}}, {{{ME}}}. (Пример этого руководства с чьими-то конкретными данными: Участник:IvanZakharyaschev/Как дать мне доступ по ssh на Ваш (мобильный) компьютер.)
Содержание |
Туннель
Конфигурация туннеля
вы и я: ваше имя
- Договоримся об имени для вашего компьютера (по которому я буду вести у себя учёт). Обозначим его 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-клиенту, чтобы он только перенаправлял порты (т.е. создавал "туннель"), но не давал вам командную оболочку другого компьютера (моего, к которому вы подключаетесь). Я мог бы как раз и запретить специальному пользователю, под которым с моей стороны обслуживается туннель, работать с командной оболочкой (потому что исполнять команды на моём компьютере -- не наша цель).
С вашей стороны: вход для меня
(Ниже описаны самые обыкновенные действия для заведения пользователя для кого-то.)
пользователь для меня и ключ
(Вы можете узнать, какое имя пользователя я предпочитаю; здесь: {{{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 занимается туннелем
- предварительно поставьте 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
Примечания (о частных особенностях систем)
- ↑ Какой-нибудь текстовый редактор: например, medit в Simply Linux: medit ~/.ssh/config; или, например, emacs -- пакет с ним можно поставить, если он не стоит.
- ↑ 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'sGatewayPorts
option is enabled (see sshd_config(5)). - ↑ На самом деле, например, в ALTLinux p7 пользователи из группы wheel и так уже могут пользоваться sudo. Но чтобы пользоваться sudo, нужно иметь свой пароль. Его можете установить вы: passwd {{{ME}}}; или дать это сделать мне, когда я войду и стану администратором через su -, узнав от вас ваш пароль root-а.
- ↑ Для систем со старым-добрым SysV init можно использовать и команду chkconfig --list sshd; а для новомодного systemd (например, в ALTLinux p7) эта команда даст информацию так:
# chkconfig sshd Внимание: Отправляется запрос 'systemctl is-enabled sshd.service'. disabled #
- ↑ После установки 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 ||: #
- ↑ Хоть сам autossh может работать с современным ssh с -M 0, но autosshd устроен так, что он по номеру этого заданного порта выслеживает процесс autossh (и потом управляет им).