что такое ssh доступ на хостинге
Памятка пользователям ssh
Предупреждение: пост очень объёмный, но для удобства использования я решил не резать его на части.
Управление ключами
Теория в нескольких словах: ssh может авторизоваться не по паролю, а по ключу. Ключ состоит из открытой и закрытой части. Открытая кладётся в домашний каталог пользователя, «которым» заходят на сервер, закрытая — в домашний каталог пользователя, который идёт на удалённый сервер. Половинки сравниваются (я утрирую) и если всё ок — пускают. Важно: авторизуется не только клиент на сервере, но и сервер по отношению к клиенту (то есть у сервера есть свой собственный ключ). Главной особенностью ключа по сравнению с паролем является то, что его нельзя «украсть», взломав сервер — ключ не передаётся с клиента на сервер, а во время авторизации клиент доказывает серверу, что владеет ключом (та самая криптографическая магия).
Генерация ключа
Свой ключ можно сгенерировать с помощью команды ssh-keygen. Если не задать параметры, то он сохранит всё так, как надо.
Ключ можно закрыть паролем. Этот пароль (в обычных графических интерфейсах) спрашивается один раз и сохраняется некоторое время. Если пароль указать пустым, он спрашиваться при использовании не будет. Восстановить забытый пароль невозможно.
Структура ключа
/.ssh/id_rsa.pub — открытый ключ. Его копируют на сервера, куда нужно получить доступ.
/.ssh/id_rsa — закрытый ключ. Его нельзя никому показывать. Если вы в письмо/чат скопипастите его вместо pub, то нужно генерировать новый ключ. (Я не шучу, примерно 10% людей, которых просишь дать ssh-ключ постят id_rsa, причём из этих десяти процентов мужского пола 100%).
Копирование ключа на сервер
/.ssh/authorized_keys и положить туда открытый ключ, то можно будет заходить без пароля. Обратите внимание, права на файл не должны давать возможность писать в этот файл посторонним пользователям, иначе ssh его не примет. В ключе последнее поле — user@machine. Оно не имеет никакого отношения к авторизации и служит только для удобства определения где чей ключ. Заметим, это поле может быть поменяно (или даже удалено) без нарушения структуры ключа.
Если вы знаете пароль пользователя, то процесс можно упростить. Команда ssh-copy-id user@server позволяет скопировать ключ не редактируя файлы вручную.
Замечание: Старые руководства по ssh упоминают про authorized_keys2. Причина: была первая версия ssh, потом стала вторая (текущая), для неё сделали свой набор конфигов, всех это очень утомило, и вторая версия уже давным давно переключилась на версии без всяких «2». То есть всегда authorized_keys и не думать о разных версиях.
Если у вас ssh на нестандартном порту, то ssh-copy-id требует особого ухищрения при работе: ssh-copy-id ‘-p 443 user@server’ (внимание на кавычки).
Ключ сервера
/.ssh/known_hosts. Узнать, где какой ключ нельзя (ибо несекьюрно).
Если ключ сервера поменялся (например, сервер переустановили), ssh вопит от подделке ключа. Обратите внимание, если сервер не трогали, а ssh вопит, значит вы не на тот сервер ломитесь (например, в сети появился ещё один компьютер с тем же IP, особо этим страдают всякие локальные сети с 192.168.1.1, которых в мире несколько миллионов). Сценарий «злобной man in the middle атаки» маловероятен, чаще просто ошибка с IP, хотя если «всё хорошо», а ключ поменялся — это повод поднять уровень паранойи на пару уровней (а если у вас авторизация по ключу, а сервер вдруг запросил пароль — то паранойю можно включать на 100% и пароль не вводить).
Ключ сервера хранится в /etc/ssh/ssh_host_rsa_key и /etc/ssh/ssh_host_rsa_key.pub. Их можно:
а) скопировать со старого сервера на новый.
б) сгенерировать с помощью ssh-keygen. Пароля при этом задавать не надо (т.е. пустой). Ключ с паролем ssh-сервер использовать не сможет.
Заметим, если вы сервера клонируете (например, в виртуалках), то ssh-ключи сервера нужно обязательно перегенерировать.
Старые ключи из know_hosts при этом лучше убрать, иначе ssh будет ругаться на duplicate key.
Копирование файлов
Передача файлов на сервер иногда может утомлять. Помимо возни с sftp и прочими странными вещами, ssh предоставляет нам команду scp, которая осуществляет копирование файла через ssh-сессию.
scp path/myfile user@8.8.8.8:/full/path/to/new/location/
Обратно тоже можно:
scp user@8.8.8.8:/full/path/to/file /path/to/put/here
Fish warning: Не смотря на то, что mc умеет делать соединение по ssh, копировать большие файлы будет очень мучительно, т.к. fish (модуль mc для работы с ssh как с виртуальной fs) работает очень медленно. 100-200кб — предел, дальше начинается испытание терпения. (Я вспомнил свою очень раннюю молодость, когда не зная про scp, я копировал
5Гб через fish в mc, заняло это чуть больше 12 часов на FastEthernet).
Возможность копировать здорово. Но хочется так, чтобы «сохранить как» — и сразу на сервер. И чтобы в графическом режиме копировать не из специальной программы, а из любой, привычной.
sshfs
Теория: модуль fuse позволяет «экспортировать» запросы к файловой системе из ядра обратно в userspace к соответствующей программе. Это позволяет легко реализовывать «псевдофайловые системы». Например, мы можем предоставить доступ к удалённой файловой системе через ssh так, что все локальные приложения (за малым исключением) не будут ничего подозревать.
Собственно, исключение: O_DIRECT не поддерживается, увы (это проблема не sshfs, это проблема fuse вообще).
Использование: установить пакет sshfs (сам притащит за собой fuse).
Собственно, пример моего скрипта, который монтирует desunote.ru (размещающийся у меня на домашнем комьютере — с него в этой статье показываются картинки) на мой ноут:
Делаем файл +x, вызываем, идём в любое приложение, говорим сохранить и видим:
Если вы много работаете с данными от рута, то можно (нужно) сделать idmap:
-o idmap=user. Работает она следующим образом: если мы коннектимся как пользователь pupkin@server, а локально работаем как пользователь vasiliy, то мы говорим «считать, что файлы pupkin, это файлы vasiliy». ну или «root», если мы коннектимся как root.
В моём случае idmap не нужен, так как имена пользователей (локальное и удалённое) совпадают.
Заметим, комфортно работать получается только если у нас есть ssh-ключик (см. начало статьи), если нет — авторизация по паролю выбешивает на 2-3 подключение.
Удалённое исполнение кода
ssh может выполнить команду на удалённом сервере и тут же закрыть соединение. Простейший пример:
ssh user@server ls /etc/
Выведет нам содержимое /etc/ на server, при этом у нас будет локальная командная строка.
Это нас приводит следующей фиче:
Проброс stdin/out
Допустим, мы хотим сделать запрос к программе удалённо, а потом её вывод поместить в локальный файл
ssh user@8.8.8.8 command >my_file
Допустим, мы хотим локальный вывод положить удалённо
mycommand |scp — user@8.8.8.8:/path/remote_file
Усложним пример — мы можем прокидывать файлы с сервера на сервер: Делаем цепочку, чтобы положить stdin на 10.1.1.2, который нам не доступен снаружи:
mycommand | ssh user@8.8.8.8 «scp — user@10.1.1.2:/path/to/file»
Есть и вот такой головоломный приём использования pipe’а (любезно подсказали в комментариях в жж):
Tar запаковывает файлы по маске локально, пишет их в stdout, откуда их читает ssh, передаёт в stdin на удалённом сервере, где их cd игнорирует (не читает stdin), а tar — читает и распаковывает. Так сказать, scp для бедных.
Алиасы
Скажу честно, до последнего времени не знал и не использовал. Оказались очень удобными.
Можно прописать общесистемные alias’ы на IP (/etc/hosts), но это кривоватый выход (и пользователя и опции всё равно печатать). Есть путь короче.
/.ssh/config позволяет задать параметры подключения, в том числе специальные для серверов, что самое важное, для каждого сервера своё. Вот пример конфига:
Все доступные для использования опции можно увидеть в man ssh_config (не путать с sshd_config).
Опции по умолчанию
По подсказке UUSER: вы можете указать настройки соединения по умолчанию с помощью конструкции Host *, т.е., например:
То же самое можно сделать и в /etc/ssh/ssh_config (не путать с /etc/ssh/sshd_config), но это требует прав рута и распространяется на всех пользователей.
Проброс X-сервера
Собственно, немножко я проспойлерил эту часть в примере конфига выше. ForwardX11 — это как раз оно.
и чудо, окошко логина в windows на нашем рабочем столе. Заметим, тщательно зашифрованное и неотличимое от обычного ssh-трафика.
Socks-proxy
Когда я оказываюсь в очередной гостинице (кафе, конференции), то местный wifi чаще всего оказывается ужасным — закрытые порты, неизвестно какой уровень безопасности. Да и доверия к чужим точкам доступа не особо много (это не паранойя, я вполне наблюдал как уводят пароли и куки с помощью банального ноутбука, раздающего 3G всем желающим с названием близлежащей кафешки (и пишущего интересное в процессе)).
Особые проблемы доставляют закрытые порты. То джаббер прикроют, то IMAP, то ещё что-нибудь.
Обычный VPN (pptp, l2tp, openvpn) в таких ситуациях не работает — его просто не пропускают. Экспериментально известно, что 443ий порт чаще всего оставляют, причём в режиме CONNECT, то есть пропускают «как есть» (обычный http могут ещё прозрачно на сквид завернуть).
Решением служит socks-proxy режим работы ssh. Его принцип: ssh-клиент подключается к серверу и слушает локально. Получив запрос, он отправляет его (через открытое соединение) на сервер, сервер устанавливает соединение согласно запросу и все данные передаёт обратно ssh-клиенту. А тот отвечает обратившемуся. Для работы нужно сказать приложениям «использовать socks-proxy». И указать IP-адрес прокси. В случае с ssh это чаще всего localhost (так вы не отдадите свой канал чужим людям).
Подключение в режиме sock-proxy выглядит так:
Вот так выглядит мой конфиг:
/etc/ssh/sshd_config:
(фрагмент)
Port 22
Port 443
/.ssh/config с ноутбука, который описывает vpn
(обратите внимание на «ленивую» форму записи localhost — 127.1, это вполне себе законный метод написать 127.0.0.1)
Проброс портов
Мы переходим к крайне сложной для понимания части функционала SSH, позволяющей осуществлять головоломные операции по туннелированию TCP «из сервера» и «на сервер».
Для понимания ситуации все примеры ниже будут ссылаться на вот эту схему:
Комментарии: Две серые сети. Первая сеть напоминает типичную офисную сеть (NAT), вторая — «гейтвей», то есть сервер с белым интерфейсом и серым, смотрящим в свою собственную приватную сеть. В дальнейших рассуждениях мы полагаем, что «наш» ноутбук — А, а «сервер» — Б.
Задача: у нас локально запущено приложение, нам нужно дать возможность другому пользователю (за пределами нашей сети) посмотреть на него.
Решение: проброс локального порта (127.0.0.1:80) на публично доступный адрес. Допустим, наш «публично доступный» Б занял 80ый порт чем-то полезным, так что пробрасывать мы будем на нестандартный порт (8080).
Итоговая конфигурация: запросы на 8.8.8.8:8080 будут попадать на localhost ноутбука А.
Опция -R позволяет перенаправлять с удалённого (Remote) сервера порт на свой (локальный).
Важно: если мы хотим использовать адрес 8.8.8.8, то нам нужно разрешить GatewayPorts в настройках сервера Б.
Задача. На сервере «Б» слушает некий демон (допустим, sql-сервер). Наше приложение не совместимо с сервером (другая битность, ОС, злой админ, запрещающий и накладывающий лимиты и т.д.). Мы хотим локально получить доступ к удалённому localhost’у.
Итоговая конфигурация: запросы на localhost:3333 на ‘A’ должны обслуживаться демоном на localhost:3128 ‘Б’.
Опция -L позволяет локальные обращения (Local) направлять на удалённый сервер.
Задача: На сервере «Б» на сером интерфейсе слушает некий сервис и мы хотим дать возможность коллеге (192.168.0.3) посмотреть на это приложение.
Итоговая конфигурация: запросы на наш серый IP-адрес (192.168.0.2) попадают на серый интерфейс сервера Б.
Вложенные туннели
Разумеется, туннели можно перенаправлять.
Усложним задачу: теперь нам хочется показать коллеге приложение, запущенное на localhost на сервере с адресом 10.1.1.2 (на 80ом порту).
Что происходит? Мы говорим ssh перенаправлять локальные запросы с нашего адреса на localhost сервера Б и сразу после подключения запустить ssh (то есть клиента ssh) на сервере Б с опцией слушать на localhost и передавать запросы на сервер 10.1.1.2 (куда клиент и должен подключиться). Порт 9999 выбран произвольно, главное, чтобы совпадал в первом вызове и во втором.
Реверс-сокс-прокси
Туннелирование
Если к этому моменту попа отдела безопасности не сияет лысиной, а ssh всё ещё не внесён в список врагов безопасности номер один, вот вам окончательный убийца всего и вся: туннелирование IP или даже ethernet. В самых радикальных случаях это позволяет туннелировать dhcp, заниматься удалённым arp-спуфингом, делать wake up on lan и прочие безобразия второго уровня.
(сам я увы, таким не пользовался).
Легко понять, что в таких условиях невозможно никаким DPI (deep packet inspection) отловить подобные туннели — либо ssh разрешён (читай — делай что хочешь), либо ssh запрещён (и можно смело из такой компании идиотов увольняться не ощущая ни малейшего сожаления).
Проброс авторизации
Если вы думаете, что на этом всё, то…… впрочем, в отличие от автора, у которого «снизу» ещё не написано, читатель заранее видит, что там снизу много букв и интриги не получается.
OpenSSH позволяет использовать сервера в качестве плацдарма для подключения к другим серверам, даже если эти сервера недоверенные и могут злоупотреблять чем хотят.
Для начала о простом пробросе авторизации.
Допустим, мы хотим подключиться к серверу 10.1.1.2, который готов принять наш ключ. Но копировать его на 8.8.8.8 мы не хотим, ибо там проходной двор и половина людей имеет sudo и может шариться по чужим каталогам. Компромиссным вариантом было бы иметь «другой» ssh-ключ, который бы авторизовывал user@8.8.8.8 на 10.1.1.2, но если мы не хотим пускать кого попало с 8.8.8.8 на 10.1.1.2, то это не вариант (тем паче, что ключ могут не только поюзать, но и скопировать себе «на чёрный день»).
Вызов выглядит так:
Удалённый ssh-клиент (на 8.8.8.8) может доказать 10.1.1.2, что мы это мы только если мы к этому серверу подключены и дали ssh-клиенту доступ к своему агенту авторизации (но не ключу!).
В большинстве случаев это прокатывает.
Однако, если сервер совсем дурной, то root сервера может использовать сокет для имперсонализации, когда мы подключены.
Есть ещё более могучий метод — он превращает ssh в простой pipe (в смысле, «трубу») через которую насквозь мы осуществляем работу с удалённым сервером.
Главным достоинством этого метода является полная независимость от доверенности промежуточного сервера. Он может использовать поддельный ssh-сервер, логгировать все байты и все действия, перехватывать любые данные и подделывать их как хочет — взаимодействие идёт между «итоговым» сервером и клиентом. Если данные оконечного сервера подделаны, то подпись не сойдётся. Если данные не подделаны, то сессия устанавливается в защищённом режиме, так что перехватывать нечего.
Эту клёвую настройку я не знал, и раскопал её redrampage.
Выглядит это так (циферки для картинки выше):
Повторю важную мысль: сервер 8.8.8.8 не может перехватить или подделать трафик, воспользоваться агентом авторизации пользователя или иным образом изменить трафик. Запретить — да, может. Но если разрешил — пропустит через себя без расшифровки или модификации. Для работы конфигурации нужно иметь свой открытый ключ в authorized_keys как для user@8.8.8.8, так и в user2@10.1.1.2
Разумеется, подключение можно оснащать всеми прочими фенечками — прокидыванием портов, копированием файлов, сокс-прокси, L2-туннелями, туннелированием X-сервера и т.д.
Магия SSH
С SSH многие знакомы давно, но, как и я, не все подозревают о том, какие возможности таятся за этими магическими тремя буквами. Хотел бы поделиться своим небольшим опытом использования SSH для решения различных административных задач.
1) Local TCP forwarding
Начнем с простого — local TCP forwarding:
Имеем удаленный сервер «host2» с неким приложением, допустим, PostgreSQL server, которое принимает TCP-соединения на порту 5432. При этом вполне логично, что на этом сервере стоит файрвол, который прямых соединений извне на порт 5432 не разрешает, но при этом есть доступ по SSH (по-умолчанию порт 22, рекомендую его изменить). Требуется подключиться с нашего рабочего места «host1» клиентским приложением к серверу PostgreSQL на «host2».
Для этого на «host1» в консоли набираем:
Теперь на «host1» мы можем соединяться с PostgreSQL сервером через локальный порт 9999:
Мы также можем соединяться с приложением не на самом «host2», а на любой доступной ему машине:
Для этого при пробросе портов вместо «localhost» указываем имя хоста, например «host3»:
Тут важно заметить, что «host3» должен быть известен (если это имя, а не IP-адрес) и доступен для машины «host2».
Также можно через «host1» предоставить доступ любому другому узлу (назовем его «host1A») к сервису на «host3»:
Для этого нужно вставить в команду соединения ssh IP-адрес интерфейса, на котором будет поднят локальный порт 9999:
В данном примере порт 9999 будет открыт на всех доступных на «host1» IPv4 интерфейсах.
2) Remote TCP forwarding
Но что делать, если, например, «host2» не имеет белого IP-адреса, находится за NAT или вообще все входящие соединения к нему закрыты? Или, например, на «host2» стоит Windows и нет возможности поставить SSH-сервер?
Для этого случая есть Remote TCP forwarding:
Теперь нужно устанавливать ssh-соединение в обратном направлении — от «host2» к «host1». Т.е. наша административная рабочая станция будет SSH-сервером и будет доступна по SSH с «host2», а на «host2» нужно будет выполнить подключение SSH-клиентом:
Например, в PuTTy это делается так:
Идем по дереву настроек: Connection → SSH → Tunnels.
Далее в поле «Source port» вбиваем 9999, в «Destination» — localhost:5432, а ниже выбираем «Remote», и нажимаем Add.
Не забываем после этого сохранить настройки сессии, если требуется.
Также у вас возникнут дополнительные сложности с обеспечением безопасности на «host1», если вы не доверяете узлу «host2». Однако это выходит за рамки данной статьи.
И, конечно, вы каким-то образом (сами или с посторонней помощью) должны инициировать ssh-соединение со стороны «host2» вводом приведенной выше команды, а «host1» должен иметь белый IP-адрес и открытый порт SSH.
После установки ssh-соединения все работает аналогично предыдущей главе.
3) TCP forwarding chain через несколько узлов
В закрытых сетях часто бывает, что нужный нам узел напрямую недоступен. Т.е. мы можем зайти на нужный хост только по цепочке, например host1 → host2 → host3 → host4:
host1# ssh host2
host2# ssh host3
host3# ssh host4
host4# echo hello host4
Это может происходить например если эти узлы являются шлюзами, либо если на них доступны шлюзы только в соседние подсети.
В таком случае мы также можем делать TCP forwarding по цепочке:
Здесь порты 9991, 9992, 9993 выбраны для наглядности, на практике можно использовать один и тот же порт (например, 9999), если он свободен на всех узлах.
Итого нужно выполнить следующую цепочку команд:
После успешного выполнения перечисленных выше команд, на узлах выполняется следующее:
ВАЖНО! Все указанные на схемах стрелками соединения являются отдельными TCP-соединениями (сессиями).
4) TCP forwarding ssh-соединения
Иногда бывает нужно соединиться по ssh с сервером, который напрямую недоступен, а доступ возможен только по цепочке ssh-серверов (см. предыдущую главу). Теперь мы обладаем нужными знаниями чтобы сделать следующее:
Таким образом, на порту 2222 на «host1» у нас теперь есть форвардинг на порт SSH (22) на «host4». Можем соединиться:
Казалось бы, зачем это нужно? Например, вот зачем:
Ну и вообще, здорово что теперь «host4» так близко 🙂
Вывод: можно делать TCP forwarding большого уровня вложенности.
Если пользуетесь одним и тем же портом (2222) для доступа к разным удаленным серверам, то будут ошибки RSA fingerprint, который остался от предыдущего сервера. Его нужно будет удалить из
5) SSH VPN Tunnel
TCP port forwarding — это отличная возможность. Но что если нам нужно больше? Доступ по UDP, доступ к множеству портов и хостов, доступ к динамическим портам? Ответ очевиден — VPN. И всемогущий SSH начиная с версии 4.3 и здесь придет нам на помощь.
Забегая вперед скажу: этот функционал SSH хорошо работает если вам нужно временное решение для каких-то административных задач. Для построения постоянных VPN этот вариант далеко не самый подходящий, т. к. он предполагает TCP-over-TCP, что плохо скажется на скорости соединения.
Настройка SSH-сервера:
PermitTunnel в настройках sshd по-умолчанию выключен, его нужно включить в /etc/ssh/sshd_config:
PermitTunnel yes
или
PermitTunnel point-to-point
ВАЖНО: для поднятия нового сетевого интерфейса туннеля и на ssh-клиенте, и на ssh-сервере необходимы права суперпользователя. Можно долго спорить о том, насколько это небезопасно, но в большинстве случаев на ssh-сервере достаточно настройки:
Таким образом вы запрещаете вход root по паролю, а разрешаете только другими средствами, например, по ключу RSA, что гораздо безопаснее.
Перезапускаем sshd:
sudo service sshd restart # centos
или
/etc/init.d/ssh restart # (debian/ubuntu)
host1# ifconfig tun5
tun5 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
POINTOPOINT NOARP MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:500
RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)
Назначаем интерфейсам IP-адреса и поднимаем их:
host1# sudo ifconfig tun5 192.168.150.101/24 pointopoint 192.168.150.102
host2# sudo ifconfig tun5 192.168.150.102/24 pointopoint 192.168.150.101
Если есть файрвол, не забываем разрешить соединения с интерфейса tun5:
На host1 это делать необязательно, здесь это сделано лишь для того чтобы ping работал в обе стороны.
host1# ping 192.168.150.102
host2# ping 192.168.150.101
Если рассмотреть более ранний пример с PostgreSQL, то теперь схема будет такая:
А команда для подключения к серверу PostgreSQL будет выглядеть так:
Ну а далее можно делать какой-либо из этих узлов шлюзом, если нужно обеспечить доступ не к одному узлу, а к сети. Например:
host1# # Предположим, у host2 есть доступ к сети 192.168.2.x, куда нам нужно попасть с host1
host1# # Прописываем host2 как шлюз в сеть 192.168.2.x
host1# sudo ip route add 192.168.2.0/24 via 192.168.150.2
host1# # Наслаждаемся доступом в сеть с host1
host1# ping 192.168.2.1
После окончания работы не забываем вернуть net.ipv4.ip_forward и файрвол в исходное состояние.
host1# sudo iptables-restore
Допустим, нужно настроить сервер в закрытой сети, где доступ в Интернет запрещен, но тем не менее у вас туда есть лазейка — доступ через один ssh-сервер или цепочку ssh-серверов. Предположим, для настройки сервера вам нужен на нем доступ в Интернет. Тогда проще самостоятельно настроить временный доступ в Интернет на требующем настройки сервере, чем просить это сделать обслуживающий персонал.
Допустим, есть доступ по ssh с вашей рабочей машины host1 на сервер host2, с него — на host3, а уже оттуда — на нужный вам host4. Тогда делаем TCP forwarding для ssh (если с host1 вы сразу можете соединиться с host4, пропустите этот шаг):
Далее, соединяемся с host4 и поднимаем интерфейс tun5:
Смотрим таблицу маршрутизации на host4, допустим видим следующее:
ВАЖНО! Далее нам скорее всего захочется сделать маршрутом по-умолчанию интерфейс tun5 со шлюзом 192.168.150.101, через который будет доступен Интернет. Поэтому на данном этапе важно точно знать, какие маршруты нужно дописать, чтобы заменить маршрут по-умолчанию. Это важно, поскольку довольно часто маршруты на отдельные сети не прописывают отдельно, а просто задают маршрут по-умолчанию (0.0.0.0/0) со шлюзом, через который и идет весь межсетевой трафик. Более того, вполне вероятно что ваше ssh-соединение с сервером также использует исходный шлюз по-умолчанию.
Для простоты в данном примере предположим, что никаких маршрутов кроме 192.168.56.0/24 серверу для нормального функционирования не нужно и что предыдущий ssh-хост host3 имеет IP-адрес из этой же сети.
Настраиваем наш host1 для работы в качестве шлюза в Интернет для host4:
Изменяем маршрут по-умолчанию на host4 (ОСТОРОЖНО, см. предупреждение выше!):
Если весь Интернет нам не нужен, а только конкретные IP-адреса/маски, то можно маршрут по-умолчанию не менять, а дописать только нужные нам адреса через шлюз на tun5.
Проверяем, что есть Интернет:
Отлично. Осталось настроить DNS. Есть множество способов это сделать, проще всего отредактировать файл /etc/resolv.conf и добавить туда строчки:
nameserver 8.8.8.8
nameserver 8.8.4.4
После этого Интернет должен быть полностью доступен:
После окончания работы не забываем вернуть все в исходное состояние:
host1# # восстанавливаем правила файрвола на host1
host1# sudo iptables-restore
host2# # восстановите маршрут по-умолчанию на host4:
host2# sudo ip route replace default via 192.168.56.254
host2# # и уберите добавленные ранее DNS-сервера из /etc/resolv.conf
6) Коротко о беспарольном доступе
Думаю, все уже знают что авторизация по паролю это не про нас. Но на всякий случай впихну сюда краткую инструкцию по настройке аутентификации по ключу RSA:
1. На клиентских машинах генерируем пользователю свой ключ RSA:
По-умолчанию приватный ключ сохраняется в
/.ssh/id_rsa, а открытый — в
/.ssh/id_rsa.pub. Приватный ключ храните как зеницу ока и никому не давайте, никуда не копируйте.
При создании ключа можно задать пароль (passphrase), которым ключ будет зашифрован.
2. Клиентские открытые ключи нужно сохранить на ssh-сервере в файле
это домашняя директория того пользователя, которым будете логиниться), каждый на отдельной строке. Для того чтобы это не делать вручную, на каждом клиенте можно воспользоваться командой:
Где user — имя пользователя на сервере, sshserver — имя или IP-адрес ssh-сервера.
/.ssh/authorized_keys на ssh-сервере необходимо задать следующие права:
chmod 0700
3. Проверьте, что можете зайти на сервер по ключу, без ввода пароля (не путать с passphrase):
ssh user@sshserver
Рекомендую не закрывать хотя бы одну активную ssh-сессию с сервером до тех пор, пока окончательно не закончите настройку и не убедитесь что все работает.
4. Отключите на SSH-сервере возможность входа по паролю в файле /etc/ssh/sshd_config:
Возможность входа по открытому ключу обычно уже включена по-умолчанию:
Я обычно также отключаю две следующие опции:
GSSAPIAuthentication no
UseDNS no
В некоторых случаях это позволяет ускорить процесс соединения (например, когда на сервере нет доступа в Интернет).
5. Перезапустите sshd:
service sshd restart
или
/etc/init.d/ssh restart