Как запустить туннель в фоновом режиме как часть сценария оболочки
Я постоянно запускаю эти две команды, чтобы подключиться к моему экземпляру rds в aws, защищенном брандмауэром (поэтому я туннелирую через экземпляр ec2), вот так:
Команда 1: открыть туннель (запустить в фоновом режиме)
ssh -N -L port:host:5432 user@$ip -i ~/.ssh/key.pub &
Команда 2: подключиться к БД через туннельный порт:
PGPASSWORD=password psql dbname -U user -h ip_address -p port;
это потрясающе, но я бы хотел объединить их в одну функцию. Но у меня ничего не получалось
попытка 1: запустить без второстепенных вещей:
function db()
{
ssh -N -L port:host:5432 user@$ip -i ~/.ssh/key.pub &
PGPASSWORD=password psql dbname -U user -h ip_address -p port;
}
просто говорит мне это:
$proddb
[1] 62924
psql: could not connect to server: Connection refused
Is the server running on host "127.0.0.1" and accepting
TCP/IP connections on port 6666?
хотя начальная команда выполняется в фоновом режиме:
ps aux | grep host
(standard input):435:abdullah 62924 0.0 0.0 4315660 5828 s006 S 3:06PM 0:00.03 ssh -N -L port:host:5432 user@$ip -i ~/.ssh/key.pub
и если я сразу же запускаю следующую команду после нее.. я подключаюсь к БД просто отлично!
PGPASSWORD=password psql dbname -U user -h ip_address -p port;
user=>
как мне сделать эту работу?
2 ответа
Первая команда не успела установить туннель при запуске второй команды, что дало "Отказ в соединении".
Просто не используйте &
но используйте вместо этого вариант -f
:
-f
Запрашивает ssh перейти в фоновый режим непосредственно перед выполнением команды. Это полезно, если ssh собирается запрашивать пароли или парольные фразы, но пользователь хочет сделать это в фоновом режиме. Это подразумевает -n. Рекомендуемый способ запуска программ X11 на удаленном сайте - это что-то вроде ssh -f host xterm.
Если для параметра конфигурации ExitOnForwardFailure установлено значение "да", то клиент, запущенный с параметром -f, будет ожидать успешной установки переадресации всех удаленных портов, прежде чем перейти в фоновый режим.
Собрав все это вместе, замените строку ssh в функции:
ssh -o ExitOnForwardFailure=yes -f -N -L port:host:5432 user@$ip -i ~/.ssh/key.pub
таким образом, запуск функции несколько раз, не оставит (несколько-1) бесполезный запуск SSH.
Также возможно заменить -N
с короткой удаленной командой сна. Таким образом, не будет долгоживущей бездействующей команды ssh, которую нужно искать, чтобы ее убить. Ssh все еще будет ждать окончания использования туннеля, прежде чем закончится, поэтому небольшая задержка не является проблемой:
ssh -o ExitOnForwardFailure=yes -f -L port:host:5432 user@$ip -i ~/.ssh/key.pub sleep 15
Это решение @AB также можно использовать для создания «сервера перехода» между dmz (интернет-конечные точки или пограничные конечные точки) и mz (бэкэнд) с прямым туннелем порта ssh к внутренним хостам, например:
(все соответствующие порты должны быть открыты с помощью firewall-cmd)
desthost_ip — это целевой IP-адрес для службы, к которой осуществляется доступ, к нему должен быть привязан отвечающий процесс, т. е. tomcat, webapp и т. д.
На краю ДМЗ:
ssh -o ExitOnForwardFailure=yes -f -L localhost_ip:port:desthost_ip:port user@dest_ip -i xyz.key sleep 15
Итак, если у localhost также есть общедоступный IP-адрес; если предположить, что на desthost работает служба https, то может работать что-то вроде этого:
https://public_ip_of_localhost:port
Это должно открыть веб-страницу службы desthost_ip:port.
ssh -o ExitOnForwardFailure=yes -f -L 192.168.1.199:8001:192.168.2.10:8081 user@192.168.2.10 -i xyz.key sleep 15
И
https://192.168.1.199:8001
или
https://public_ip_for_192.168.1.199:8001
откроется страница услуги на192.168.2.10:8081
.