novnc_proxy 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. #!/usr/bin/env bash
  2. # Copyright (C) 2018 The noVNC Authors
  3. # Licensed under MPL 2.0 or any later version (see LICENSE.txt)
  4. usage() {
  5. if [ "$*" ]; then
  6. echo "$*"
  7. echo
  8. fi
  9. echo "Usage: ${NAME} [--listen PORT] [--vnc VNC_HOST:PORT] [--cert CERT] [--ssl-only]"
  10. echo
  11. echo "Starts the WebSockets proxy and a mini-webserver and "
  12. echo "provides a cut-and-paste URL to go to."
  13. echo
  14. echo " --listen PORT Port for proxy/webserver to listen on"
  15. echo " Default: 6080"
  16. echo " --vnc VNC_HOST:PORT VNC server host:port proxy target"
  17. echo " Default: localhost:5900"
  18. echo " --cert CERT Path to combined cert/key file, or just"
  19. echo " the cert file if used with --key"
  20. echo " Default: self.pem"
  21. echo " --key KEY Path to key file, when not combined with cert"
  22. echo " --web WEB Path to web files (e.g. vnc.html)"
  23. echo " Default: ./"
  24. echo " --ssl-only Disable non-https connections."
  25. echo " "
  26. echo " --record FILE Record traffic to FILE.session.js"
  27. echo " "
  28. echo " --syslog SERVER Can be local socket such as /dev/log, or a UDP host:port pair."
  29. echo " "
  30. echo " --heartbeat SEC send a ping to the client every SEC seconds"
  31. echo " --timeout SEC after SEC seconds exit when not connected"
  32. echo " --idle-timeout SEC server exits after SEC seconds if there are no"
  33. echo " active connections"
  34. echo " "
  35. exit 2
  36. }
  37. NAME="$(basename $0)"
  38. REAL_NAME="$(readlink -f $0)"
  39. HERE="$(cd "$(dirname "$REAL_NAME")" && pwd)"
  40. PORT="6080"
  41. VNC_DEST="localhost:5900"
  42. CERT=""
  43. KEY=""
  44. WEB=""
  45. proxy_pid=""
  46. SSLONLY=""
  47. RECORD_ARG=""
  48. SYSLOG_ARG=""
  49. HEARTBEAT_ARG=""
  50. IDLETIMEOUT_ARG=""
  51. TIMEOUT_ARG=""
  52. die() {
  53. echo "$*"
  54. exit 1
  55. }
  56. cleanup() {
  57. trap - TERM QUIT INT EXIT
  58. trap "true" CHLD # Ignore cleanup messages
  59. echo
  60. if [ -n "${proxy_pid}" ]; then
  61. echo "Terminating WebSockets proxy (${proxy_pid})"
  62. kill ${proxy_pid}
  63. fi
  64. }
  65. # Process Arguments
  66. # Arguments that only apply to chrooter itself
  67. while [ "$*" ]; do
  68. param=$1; shift; OPTARG=$1
  69. case $param in
  70. --listen) PORT="${OPTARG}"; shift ;;
  71. --vnc) VNC_DEST="${OPTARG}"; shift ;;
  72. --cert) CERT="${OPTARG}"; shift ;;
  73. --key) KEY="${OPTARG}"; shift ;;
  74. --web) WEB="${OPTARG}"; shift ;;
  75. --ssl-only) SSLONLY="--ssl-only" ;;
  76. --record) RECORD_ARG="--record ${OPTARG}"; shift ;;
  77. --syslog) SYSLOG_ARG="--syslog ${OPTARG}"; shift ;;
  78. --heartbeat) HEARTBEAT_ARG="--heartbeat ${OPTARG}"; shift ;;
  79. --idle-timeout) IDLETIMEOUT_ARG="--idle-timeout ${OPTARG}"; shift ;;
  80. --timeout) TIMEOUT_ARG="--timeout ${OPTARG}"; shift ;;
  81. -h|--help) usage ;;
  82. -*) usage "Unknown chrooter option: ${param}" ;;
  83. *) break ;;
  84. esac
  85. done
  86. # Sanity checks
  87. if bash -c "exec 7<>/dev/tcp/localhost/${PORT}" &> /dev/null; then
  88. exec 7<&-
  89. exec 7>&-
  90. die "Port ${PORT} in use. Try --listen PORT"
  91. else
  92. exec 7<&-
  93. exec 7>&-
  94. fi
  95. trap "cleanup" TERM QUIT INT EXIT
  96. # Find vnc.html
  97. if [ -n "${WEB}" ]; then
  98. if [ ! -e "${WEB}/vnc.html" ]; then
  99. die "Could not find ${WEB}/vnc.html"
  100. fi
  101. elif [ -e "$(pwd)/vnc.html" ]; then
  102. WEB=$(pwd)
  103. elif [ -e "${HERE}/../vnc.html" ]; then
  104. WEB=${HERE}/../
  105. elif [ -e "${HERE}/vnc.html" ]; then
  106. WEB=${HERE}
  107. elif [ -e "${HERE}/../share/novnc/vnc.html" ]; then
  108. WEB=${HERE}/../share/novnc/
  109. else
  110. die "Could not find vnc.html"
  111. fi
  112. # Find self.pem
  113. if [ -n "${CERT}" ]; then
  114. if [ ! -e "${CERT}" ]; then
  115. die "Could not find ${CERT}"
  116. fi
  117. elif [ -e "$(pwd)/self.pem" ]; then
  118. CERT="$(pwd)/self.pem"
  119. elif [ -e "${HERE}/../self.pem" ]; then
  120. CERT="${HERE}/../self.pem"
  121. elif [ -e "${HERE}/self.pem" ]; then
  122. CERT="${HERE}/self.pem"
  123. else
  124. echo "Warning: could not find self.pem"
  125. fi
  126. # Check key file
  127. if [ -n "${KEY}" ]; then
  128. if [ ! -e "${KEY}" ]; then
  129. die "Could not find ${KEY}"
  130. fi
  131. fi
  132. # try to find websockify (prefer local, try global, then download local)
  133. if [[ -d ${HERE}/websockify ]]; then
  134. WEBSOCKIFY=${HERE}/websockify/run
  135. if [[ ! -x $WEBSOCKIFY ]]; then
  136. echo "The path ${HERE}/websockify exists, but $WEBSOCKIFY either does not exist or is not executable."
  137. echo "If you intended to use an installed websockify package, please remove ${HERE}/websockify."
  138. exit 1
  139. fi
  140. echo "Using local websockify at $WEBSOCKIFY"
  141. else
  142. WEBSOCKIFY_FROMSYSTEM=$(which websockify 2>/dev/null)
  143. WEBSOCKIFY_FROMSNAP=${HERE}/../usr/bin/python2-websockify
  144. [ -f $WEBSOCKIFY_FROMSYSTEM ] && WEBSOCKIFY=$WEBSOCKIFY_FROMSYSTEM
  145. [ -f $WEBSOCKIFY_FROMSNAP ] && WEBSOCKIFY=$WEBSOCKIFY_FROMSNAP
  146. if [ ! -f "$WEBSOCKIFY" ]; then
  147. echo "No installed websockify, attempting to clone websockify..."
  148. WEBSOCKIFY=${HERE}/websockify/run
  149. git clone https://github.com/novnc/websockify ${HERE}/websockify
  150. if [[ ! -e $WEBSOCKIFY ]]; then
  151. echo "Unable to locate ${HERE}/websockify/run after downloading"
  152. exit 1
  153. fi
  154. echo "Using local websockify at $WEBSOCKIFY"
  155. else
  156. echo "Using installed websockify at $WEBSOCKIFY"
  157. fi
  158. fi
  159. echo "Starting webserver and WebSockets proxy on port ${PORT}"
  160. #${HERE}/websockify --web ${WEB} ${CERT:+--cert ${CERT}} ${PORT} ${VNC_DEST} &
  161. ${WEBSOCKIFY} ${SYSLOG_ARG} ${SSLONLY} --web ${WEB} ${CERT:+--cert ${CERT}} ${KEY:+--key ${KEY}} ${PORT} ${VNC_DEST} ${HEARTBEAT_ARG} ${IDLETIMEOUT_ARG} ${RECORD_ARG} ${TIMEOUT_ARG} &
  162. proxy_pid="$!"
  163. sleep 1
  164. if ! ps -p ${proxy_pid} >/dev/null; then
  165. proxy_pid=
  166. echo "Failed to start WebSockets proxy"
  167. exit 1
  168. fi
  169. echo -e "\n\nNavigate to this URL:\n"
  170. if [ "x$SSLONLY" == "x" ]; then
  171. echo -e " http://$(hostname):${PORT}/vnc.html?host=$(hostname)&port=${PORT}\n"
  172. else
  173. echo -e " https://$(hostname):${PORT}/vnc.html?host=$(hostname)&port=${PORT}\n"
  174. fi
  175. echo -e "Press Ctrl-C to exit\n\n"
  176. wait ${proxy_pid}