Определить включен ли компьютер через сеть

Сегодня напишем простой скрипт на языке shell, который будет определять включен ли компьютер, находящийся в сети. Например, нужно, чтобы туннель на роутере поднимался только, когда клиентская машина включена и разрушался, при ее выключении.


Вот такая у нас будет схемка, в качестве VPN сервера может выступать маршрутизатор филиала фирмы. Или, может быть, вы захотите, чтобы туннель пробрасывался к вашему VPS серверу для доступа к закрытым извне инструментам администрирования, некоторым портам (PMA, MySQL)

Как пробрасывать сам туннель, посредством OpenSSH, я уже рассказывал в ранее опубликованной статье. Поэтому, остановимся на вопросе определения, включен ли компьютер.

У стандартной консольной команды ping, есть параметры количества посылаемых запросов и таймаут ответа. Создадим shell скрипт detectPC.sh, следующего содержания:

  1. #!/bin/bash
  2. host=‘192.168.12.1’
  3. ping $host -c 1 -W 1 > /dev/null
  4. if [ $? —eq 0 ]
  5. then
  6. echo ‘Host is up’
  7. else
  8. echo ‘Host is down’
  9. fi

Как несложно догадаться, в переменной host указывается ip адрес машины, которую нужно проверить на предмет включения. Будем исходить из того, что на ней не закрыт ping (icmp 0, 8), что, кстати, в противном случае является дурным тоном. Никогда не закрывайте данные типы icmp сообщений, по крайней мере полностью.

У команды ping есть интересующие нас ключи:
-c – количество отправляемых запросов,
-W – таймаут ожидания ответа.

Устанавливаем один пакет и время ожидания одну секунду. Дальше самое интересное, после выполнения можно определить статус только что выполненной команды, через специальную переменную – “$?”. Обычно в Linux, если все прошло без ошибок, возвращается цифра 0. Иначе — ненулевое значение.

Едем дальше, теперь мы определили, включен ли PC, как пробросить туннель? Создадим другой скрипт, для обработки команд, toggleVPN.sh:

  1. #!/bin/bash
  2. controlFile=‘/var/run/ssh-myvpn-tunnel-control’
  3. remoteHost=‘111.222.33.44’
  4. function up()
  5. {
  6. if [ ! -S $controlFile ]
  7. then
  8. /usr/bin/ssh -S $controlFile -M -f -w 0:0 $remoteHost ifconfig tun0 10.10.10.1/30 pointopoint 10.10.10.2
  9. exit 0
  10. else
  11. echo ‘Tunnel already up!’
  12. exit 1
  13. fi
  14. }
  15. function down()
  16. {
  17. if [ -S $controlFile ]
  18. then
  19. /usr/bin/ssh -S $controlFile -O exit $remoteHost
  20. exit 0
  21. else
  22. echo ‘Tunnel already down!’
  23. exit 1
  24. fi
  25. }
  26. case $1 in
  27. ‘up’)
  28. up
  29. ;;
  30. ‘down’ )
  31. down
  32. ;;
  33. *)
  34. echo ‘Usage: up|down’
  35. ;;
  36. esac
  37. exit 1

Теперь наш detectPC.sh примет следующий вид:

  1. #!/bin/bash
  2. cd /22 #папка, где лежит скрипт toggletunnel.sh
  3. host=‘192.168.12.1’
  4. ping $host -c 1 -W 1 > /dev/null
  5. if [ $? —eq 0 ]
  6. then
  7. ./toggletunnel.sh up
  8. else
  9. ./toggletunnel.sh down
  10. fi

Обнаруживается недостаток: хардкод абсолютного пути. Запускать через cron будет неудобно. Чтобы повысить удобство использования, можно объединить эти два скрипта в один, следующим образом:

  1. #!/bin/bash
  2. controlFile=‘/var/run/ssh-myvpn-tunnel-control’
  3. remoteHost=‘111.222.33.44’ #OpenSSH сервер
  4. checkHost=‘192.168.12.1’ #Мониторим включена ли.
  5. function up()
  6. {
  7. if [ ! -S $controlFile ]
  8. then
  9. /usr/bin/ssh -S $controlFile -M -f -w 0:0 $remoteHost ifconfig tun0 10.10.10.1/30 pointopoint 10.10.10.2
  10. exit 0
  11. else
  12. echo ‘Tunnel already up!’
  13. exit 1
  14. fi
  15. }
  16. function down()
  17. {
  18. if [ -S $controlFile ]
  19. then
  20. /usr/bin/ssh -S $controlFile -O exit $remoteHost
  21. exit 0
  22. else
  23. echo ‘Tunnel already down!’
  24. exit 1
  25. fi
  26. }
  27. function auto()
  28. {
  29. ping $checkHost -c 1 -W 1 > /dev/null
  30. if [ $? —eq 0 ]
  31. then
  32. up
  33. else
  34. down
  35. fi
  36. }
  37. case $1 in
  38. ‘up’)
  39. up
  40. ;;
  41. ‘down’ )
  42. down
  43. ;;
  44. ‘auto’ )
  45. auto
  46. ;;
  47. *)
  48. echo ‘Usage: up|down|auto’
  49. ;;
  50. esac
  51. exit 1