2718.us blog » ssh tunnel http://2718.us/blog Miscellaneous Technological Geekery Tue, 18 May 2010 02:42:55 +0000 en hourly 1 http://wordpress.org/?v=3.0.4 OS X, Wake-on-LAN, and Passworded Screensavers http://2718.us/blog/2008/08/13/os-x-wake-on-lan-and-passworded-screensavers/ http://2718.us/blog/2008/08/13/os-x-wake-on-lan-and-passworded-screensavers/#comments Wed, 13 Aug 2008 20:35:04 +0000 2718.us http://2718.us/blog/?p=91 The other day, I realized while I was at work that I needed some files from my Mac desktop at home.  Normally, no problem, ssh into my firewall and open a tunnel to my desktop (this is better done with authpf, but that’s a post for another time), use sftp, and done.  The problem is that because of unexplained kernel panics (probably a bad RAM module), my desktop would crash hard if left on all day, so I’ve been putting it to sleep when I go to work.  Now, with my Mac set to wake for remote admin access, I ought to be able to run a wake-on-LAN utility to wake it up and be fine, except that I use a passworded screensaver.  With a passworded screensaver, waking the machine locally or remotely will give 30-60-second window during which the computer is awake and expecting a password to be entered at the physical machine; there doesn’t seem to be a way to do this remotely and unlike earlier versions of OS X, since 10.3 or 10.4 or so, you can’t just kill the screensaver process from the command line (i.e. by logging in with ssh).

On the other hand, ssh is a very robust protocol and somehow ssh sessions seem to readily survive disconnect/reconnect cycles. Making use of this, it is possible to get a workable, if slow, connection to a passworded-and-sleeping Mac.  On one connection to the firewall machine, run a loop of the wake-on-LAN command so that the magic packets that make the Mac wake are being sent every second or so.  Use another connection to ssh into the Mac and do whatever you need to do.  It helps to plan out what you need to do so that you can get the commands in fast, but even during the cycle where the Mac goes back to sleep and gets reawakened by the wake-on-LAN loop, you can type commands; they just won’t appear (not even echoed) until ssh recovers the connection.

While this is an annoying way to use a machine and it’s probably not good for the hardware to cycle in and out of sleep repeatedly in such a short time span, it does give a way to get at a passworded and sleeping Mac remotely.

]]>
http://2718.us/blog/2008/08/13/os-x-wake-on-lan-and-passworded-screensavers/feed/ 0
SSH Tunneling on a Mac http://2718.us/blog/2008/06/13/ssh-tunneling-on-a-mac/ http://2718.us/blog/2008/06/13/ssh-tunneling-on-a-mac/#comments Fri, 13 Jun 2008 22:55:27 +0000 2718.us http://2718.us/blog/?p=45 Since my employer’s wireless network is unencrypted and since I use other open WiFi networks with some frequency, I’ve gotten in the habbit of tunneling everything through SSH, using the SOCKS5 proxy mechanism built in to SSH.  In WinXP, there’s a nice little program called Tunnelier that makes the setup of the tunnel simple and it reconnects automatically, so the tunneling part is virtually automatic (even though proxy setup is still tricky and/or annoying).

On the Mac, however, I have tried several programs and never really been happy.  So I wrote a little AppleScript that not only sets up the SSH tunnel, but also deals with switching my location to set the system’s network settings to use the proxy (the code is after the cut).  Combine this with System Proxy for Firefox and all my application traffic goes through the SSH tunnel.  Note also that if you’re using a SOCKS5 proxy with Firefox, you probably want to set it to do DNS lookups through the proxy.

This script also stores the info for creating the tunnel (server, login, pw) in the keychain.

Here’s the “library” script where I put the functions to do the underlying work (since I have various different tunnels I use):

  1. on startTunnel(targetServer) –returns PID of ssh for killing later
  2.  tell application "Keychain Scripting"
  3.  
  4.   set sshTunnelKeys to every Internet key of current keychain whose (name is "autoSSHTunnel") and (server is targetServer)
  5.  
  6.   if sshTunnelKeys is {} then
  7.    set sshKey to my makeSSHKeyWithServer(targetServer)
  8.   else
  9.    set sshKey to item 1 of sshTunnelKeys
  10.   end if
  11.   set user to account of sshKey
  12.   set passwd to password of sshKey as string
  13.   set sshHost to server of sshKey as string
  14.  end tell
  15.  
  16.  set sshCommand to "ssh -fND 9999 " & user & "@" & sshHost
  17.  
  18.  set expectScript to "spawn " & sshCommand & "
  19. expect assword
  20. send \"" & passwd & "\\n\"
  21. sleep 1"
  22.  
  23.  do shell script "/usr/bin/expect -c '" & expectScript & "' &>/dev/null &"
  24.  
  25.  set tries to 0
  26.  repeat
  27.   set tries to tries + 1
  28.   try
  29.    set sshPIDstring to (do shell script "sleep 1;bash -c 'ps ax -o pid,tt,command | grep \"??\" | grep \"" & sshCommand & "\" | grep -v grep | grep -v expect'")
  30.    set sshPID to first word of sshPIDstring
  31.    set gotPID to true
  32.   on error
  33.    set gotPID to false
  34.   end try
  35.   if gotPID then
  36.    exit repeat
  37.   end if
  38.   if tries > 10 then
  39.    exit repeat
  40.   end if
  41.  end repeat
  42.  if gotPID then
  43.   return sshPID
  44.  else
  45.   return false
  46.  end if
  47. end startTunnel
  48.  
  49. on setUseTunnel()
  50.  do shell script "scselect 'Use SOCKS5 Proxy on localhost:9999'"
  51. end setUseTunnel
  52.  
  53. on clearUseTunnel()
  54.  do shell script "scselect 'Automatic'"
  55. end clearUseTunnel
  56.  
  57. on stopTunnel(pid)
  58.  do shell script "kill " & pid
  59. end stopTunnel
  60.  
  61. on makeSSHKeyWithServer(targetServer)
  62.  tell application "Keychain Scripting"
  63.   repeat
  64.    set acctBox to display dialog "Enter your SSH login for host " & targetServer & ":" default answer "" buttons {"Cancel", "OK"} default button 2
  65.    set myAcct to the text returned of acctBox
  66.    set myButton to the button returned of acctBox
  67.    if myButton is "Cancel" then
  68.     –quit
  69.    else
  70.     if myAcct is not "" then
  71.      exit repeat
  72.     else
  73.      display dialog "bad login"
  74.     end if
  75.    end if
  76.   end repeat
  77.   repeat
  78.    set passBox to display dialog "Enter your password:" default answer "" buttons {"Cancel", "OK"} default button 2 with hidden answer
  79.    set myPass to the text returned of passBox
  80.    set myButton to the button returned of passBox
  81.    if myButton is "Cancel" then
  82.     –quit
  83.    else
  84.     if myPass is not "" then
  85.      exit repeat
  86.     else
  87.      display dialog "can't use blank passwd"
  88.     end if
  89.    end if
  90.   end repeat
  91.   set newSSHKey to make new Internet key with properties {name:"autoSSHTunnel", account:myAcct, password:myPass, server:targetServer, authentication:default, protocol:SSH}
  92.  end tell
  93.  return newSSHKey
  94. end makeSSHKeyWithServer

And here’s the actual script I run.

  1. property Lib : (path to scripts folder from user domain as text) & "Script Library:"
  2. property sshTunnelLib : load script Lib & "ssh_tunnel.scpt" as alias
  3.  
  4. sshTunnelLib's setUseTunnel()
  5.  
  6. set sshPID to sshTunnelLib's startTunnel("fqdn.of.your.server")
  7. if sshPID is not false then
  8.  set noPIDtxt to ""
  9.  set buttonTxt to "Kill SSH and Exit"
  10. else
  11.  set noPIDtxt to " (but couldn't get PID)"
  12.  set buttonTxt to "Exit"
  13. end if
  14.  
  15. display dialog "SSH-tunneled SOCKS5 proxy running on localhost:9999" & noPIDtxt buttons {buttonTxt}
  16.  
  17. if sshPID is not false then
  18.  sshTunnelLib's stopTunnel(sshPID)
  19. end if
  20.  
  21. sshTunnelLib's clearUseTunnel()
]]>
http://2718.us/blog/2008/06/13/ssh-tunneling-on-a-mac/feed/ 0