Remote

Revision 6 as of 2008-05-08 04:59:17

Clear message

Summary

There should be a simple, secure, robust way for a non-technical user to allow a more technical user to SSH to their computer and get root access, using only instructions that can be described simply, in layman's terms, over a poor quality phone line.

Rationale

For experienced Linux users, over-the-phone tech support for a non-technical friend is a common use case. It's normally an unpleasant experience, for the following reasons:

  • Telephones often have poor audio quality. For example, it's hard for the friend to tell whether you're saying "less" or "ls"
  • Describing what command lines to type can be socially awkward. For example, do you tell them where to put spaces and when to press enter? Making the wrong decisions will either insult your friend or make them feel even more helpless than they feel already
  • It's very difficult for a friend to accurately describe what they're seeing on their screen. For example, most people don't know how to pronounce "~" or what a backtick is

Other Projects

https://launchpad.net/locoremotesupport/

Design

There should be a pair of shell scripts, /bin/remote-recovery and /usr/bin/connect-to-remote-recovery. The former is run on the machine where support is needed (hereafter referred to as the "recovery machine"). The latter is run on the machine providing support (hereafter referred to as the "expert's machine").

In order to make it easier to access, the remote-recovery script should be available through GUI, command line, and GRUB.

Modern computers are often firewalled or placed behind NAT routers. Although non-technical users are at least as likely to have such things in place, they are more likely to know how to work around them. Therefore, the recovery machine first establishes an SSH connection with the expert's machine, then uses port-forwarding to make it possible to log in to the recovery machine's SSH server from the expert's machine.

Implementation

There should be three ways to run /bin/remote-recovery:

  • In the GRUB menu, there should be a "remote recovery" option
  • From the command-line
  • From the GUI, there should be System Tools->Remote Recovery option that runs the script in a terminal

Opening a terminal from the GUI is a better decision than creating a second (graphical) interface because:

  • It's more important that this system be bug-free than pretty. The extra complexity of a second interface introduces the chance to create more bugs
  • A second interface adds more opportunity for confusion between expert and friend: "okay, now press ente... er no, click on OK... or Continue, or Save, or whatever it is..."

There should be an init script that:

  • deletes the remote-recovery user if it exists
  • deletes /tmp/rr if it exists
  • runs /bin/remote-recovery if the remote recovery option is specified in GRUB

/bin/remote-recovery

Ideally, this script should work from first principles, assuming nothing about the system (e.g. that /usr is mounted, that ssh is installed). If you can think of implicit assumptions made in this implementation (and preferably workarounds for them), please add them.

  1. (note: this should be identical to step 1 on the expert's computer)BRIf the SSH server isn't running, enable it. If it won't enable, try various things:

    • If the package doesn't exist, ask if you can install it
    • If /usr or /usr/bin doesn't exist, check whether they're mentioned in /etc/fstab, and if so, whether they're mentioned in mount, then tell the user what's going on, and offer to print the contents of both.

  2. Remember the current iptables settings by doing:
    • iptables-save > /tmp/saved-iptables
      ip6tables-save > /tmp/saved-ip6tables
  3. To work around any firewalls the user has set up, and to avoid security issues if (for example) the user has set up an FTP server that an attacker could brute-force the remote-recovery password through, do:
    • iptables -I INPUT 1 -m state --state NEW -j DROP
      iptables -I INPUT 1 -i lo -m state --state NEW -j DROP
      iptables6 -I INPUT 1 -m state --state NEW -j DROP
      iptables6 -I INPUT 1 -i lo -m state --state NEW -j DROP
  4. Create a remote-recovery user
    • the home directory is /tmp/rr
    • they are in their own group, and have no useful permissions
    • their home directory is chmod 500
    • they have a randomly chosen password (the user is not asked about this)
    • Create a .bashrc that looks like this:
      touch ~/login
      cat <<EOF
      Welcome to the recovery mode
      
      This file should be populated with various information and warnings, including:
      
      * changes to iptables rules will be destroyed unless they're saved to /tmp/saved-ip*tables
      * You can sudo things using the password in ~/password
      * The recovery-mode script allows messages to be sent to you using the `write` command.  You can use `write` to send messages back
      EOF
  5. Print the following warning:
    • This program gives complete control of your computer to someone else on the Internet, so that they can help solve any problems you are having.
      
      While running this program, you will be asked for a passwords, and asked to confirm when the person fixing your computer has logged in.  You should get confirmation of these details over a phone line, so that you can be sure that you're talking to the person you think you're talking to.  In particular, you shouldn't send passwords over e-mail or instant messaging.
      
      *** Only run this program at the request of somebody you trust, when talking to them on the telephone ***
      
      There's no security risk if you quit the program now.  Type "continue" then press enter to continue, or anything else to quit
    • if they type "continue" (lower-case only), continue. b. otherwise, stop
  6. Prompt the user to enter the IP address of the computer you'll allow access to
  7. Prompt the user to enter the remote-recovery password of the person you'll allow access to
  8. ssh remote-recovery@$ip_address -L22:localhost:2222

    1. if that fails, do various diagnostics:
      • Does the computer have an IP address? Does it have a gateway?
      • Do a tracepath to $ip_address and print the results
    2. If it succeeds, read the line beginning "ssh-dsa " and append it to ~remote-recovery/.ssh/authorized_keys

  9. Tell the user whether SSH succeeded or failed.
    1. If it failed, explain why then stop.
  10. Inform the user that they can press ctrl-c to quit remote recovery.
  11. Wait until ~remote-recovery/login exists
  12. Check that w -h remote-recovery returns only one line of text, and ask the friend to confirm (over the phone) that the expert has logged in successfully

    1. If either condition is not met, throw all remote-recovery users out and warn the friend that they've been subject to foul play
  13. Read lines of text and write them to the remote-recovery user's tty

  14. Remove the remote-recovery user, remove them from sudoers, and delete their home directory
  15. Restore old iptables by doing:
    • iptables-restore < /tmp/saved-iptables
      iptables-restore < /tmp/saved-ip6tables

/usr/bin/connect-to-remote-recovery

  1. (note: this should be identical to step 1 on the recovery computer) If the SSH server isn't running, enable it. If it won't enable, try various things:
    • If the package doesn't exist, ask if you can install it
    • If /usr or /usr/bin doesn't exist, check whether they're mentioned in /etc/fstab, and if so, whether they're mentioned in mount, then tell the user what's going on, and offer to print the contents of both.

  2. Find the IP address(es) of the computer
    1. If any addresses are public (i.e. not one of the [wiki:WikiPedia/Private_network private addresses] 192.168.*, 10.*, 172.[16-31].*, or 169.254.*), the script stores them in memory
    2. Otherwise, tell the user to find their public address (e.g. through the settings page of their wireless router), and make sure that connections on port 22 are forwarded to <private IP address> port 22.

  3. Choose a password by showing the expert a prompt: "Remote recovery password [$PASS]: ", where $PASS is a previously-generated random password that is selected if the user presses <ENTER>

  4. Create a remote-recovery user
    • the home directory is /tmp/rr
    • they are in their own group, and have no useful permissions
    • their home directory is chmod 500
    • the password is as specified in step 3
    • Create a .bashrc that looks like this:
      touch ~/login
      cat ~/.ssh/id_dsa.pub
      pause
      exit
  5. Create a ~/.ssh/id_dsa with no passphrase
  6. Give the following information to the user:
    • The list of public IP addresses, printed in the form:
          12.34.56 (say: one two dot (pause) three four dot (pause) five six (pause) then press enter)
    • The remote-recovery user's password, printed in the form:
          abc123 (say: alpha bravo charlie one two three (pause) then press enter)
  7. (note: the next three steps should be identical to their equivalents on the recovery computer)BRWait until ~remote-recovery/login exists

  8. passwd -d remote-recovery - i.e. disable further logins from this account

  9. Check that w -h remote-recovery returns only one line of text, and ask the expert to confirm (over the phone) that the friend has logged in successfully

    1. If either condition is not met, throw all remote-recovery users out and warn the expert that they've been subject to foul play
  10. sudo -u remote-recovery ssh remote-recovery@127.0.0.1 -p 2222

  11. The expert now has a shell on the recovery computer, as user "remote-recovery". They can then read the password in ~/password, and sudo whatever they need to sudo.
  12. When ssh session exits, remove the remote-recovery user and delete its home directory

See also


CategoryNetworking CategoryRecovery