Remote

Differences between revisions 7 and 22 (spanning 15 versions)
Revision 7 as of 2008-05-09 06:40:52
Size: 10216
Editor: 193
Comment:
Revision 22 as of 2008-08-06 16:18:23
Size: 11279
Editor: localhost
Comment: converted to 1.6 markup
Deletions are marked like this. Additions are marked like this.
Line 3: Line 3:
There should be a simple, secure, robust way for a non-technical user to allow a more technical user to [https://help.ubuntu.com/community/SSHHowto 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. There should be a simple, secure, robust way for a non-technical user to allow a more technical user to connect 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. The facility to allow the technical user access should be available, and easily visible, in the default install. Current solutions are secure, robust or simple, but never more than two out of three.

In this document, the technical user is referred to as the "helper", and the non-technical user as the "friend".

[[https://launchpad.net/remote-help-assistant|Remote help assistant]] is a program being developed based on this specification.
Line 11: Line 15:
 * 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  * 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 that sub-areas within a window are referred to as tabs.
Line 15: Line 19:
https://launchpad.net/locoremotesupport/ Several projects aim to provide complete application suites that handle tasks such as remote support. Included among them are:

 * [[https://launchpad.net/locoremotesupport/|LoCo Remote]]
 * [[https://launchpad.net/telepathy|Telepathy]]

This project would not provide a complete suite, just a tool to enable remote connections to be made. Complete solutions aren't appropriate to a support request made over the phone.

GNOME's [[http://www.gnomejournal.org/article/29/remote-desktop-administration-using-vino|vino]] and KDE's [[http://docs.kde.org/kde3/en/kdenetwork/krfb/index.html|krfb]] provide VNC access to a computer. These provide an excellent basis for allowing the helper to connect to a computer with a functioning X server, although this tool needs to add a command-line mode, the ability to route around NAT and firewalls, and an effective mechanism for communicating security information over the telephone. To reinforce the last point, both vino and krfb expect users to send invitations by e-mail, but non-technical users can't be expected to have PGP-encrypted e-mail already set up, and it would be impractical to set it up for them over the phone.

[[http://www.gnu.org/software/screen/|GNU Screen]] provides shell access to multiple users, but isn't designed for use across multiple computers. To adapt it for this purpose, we would have to find some way of exporting a pseudo-terminal over a network.

== Overview of the problem ==

Both helper and friend might be behind a NAT router or a firewall beyond their control. It's more likely that the helper would be able to configure their network to allow incoming connections on specified ports, but this can't be assumed in the general case.

The friend's computer can't be assumed to have a particularly large set of packages installed and functioning, as they might have removed important packages (or broken them in a more imaginative way). In this blueprint, it will be assumed that the friend has installed packages that are installed in at least 99% of cases reported to [[http://popcon.ubuntu.com/|the Ubuntu popularity contest]], not necessarily with functioning configuration files. Systems more broken than this would be better served by (semi-)automated recovery scripts that can solve specific problems, or by booting to a live CD with a remote recovery script on it.

The helper's computer can be assumed to have a much more complete system, because people with sufficient expertise and patience to help out can reasonably be asked to install packages outside of main, and can be assumed to maintain those packages properly.

If the friend has an X session running, the helper should be given access to it over a VNC connection. Otherwise, the friend should be given a login shell on the user's machine.

Man-in-the-middle attacks are a serious security issue here. If helper and friend haven't already exchanged security information (such as SSH keys), a tamper-proof connection is needed in order to confirm the connection they're using. A telephone conversation is sufficiently tamper-proof for purposes of this project - albeit a channel with severely limited bandwidth. Other systems (such as instant messaging or e-mail) are not sufficiently tamper-proof, and should not be recommended. Since users will use insecure channels no matter what recommendations we make, the following rules should apply, as a second line of defence:

 * The helper should never be able to do anything behind the friend's back. Anything the helper does should be visible to the friend
 * passwords and other important security information should never be transferred over the connection
 * The friend should have an easy way of terminating the session, and should be aware of that method

The first of these conditions have two important side-effects, one positive, one negative. The positive side-effect is that the friend has the opportunity to learn a little by watching the helper. The negative side-effect is that there's no easy way to transfer files between the computers. It's possible to transfer files by pasting base64-encoded text, which accomplishes the same goal and leaves the friend with the ability to check the process.

The second condition can be met by ensuring that, as well as reading anything the helper can read, the friend can write anywhere that the helper can write. Therefore, if the helper needs a password, the friend can type it in without telling the helper.

Over a VNC connection, these conditions are trivially met - both users share a session, and the friend can terminate the session by pressing ctrl-alt-backspace. Over a login shell, these conditions can be met by ensuring that both users have read and write access to the shell, and that the session is terminated when the friend types ctrl-alt-c, or some other special sequence.
Line 19: Line 54:
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"). This program will be written as a single file in a scripting language, so that it can simply be downloaded and run in an emergency, no matter the architecture the user uses. Python is a good choice for the scripting language because in a default Ubuntu installation, Python supports creating pseudo-ttys (necessary for creating a fully functional shell session) and IPv6 (necessary to talk to Vino), which are only available in Perl if you install extra packages. Although [[http://popcon.ubuntu.com/|the Ubuntu popularity contest]] ranks Python lower than Perl, both packages are installed and regularly used in well over 99% of popcon results.
Line 21: Line 56:
In order to make it easier to access, the remote-recovery script should be available through GUI, command line, and GRUB. In order to make it easier to access, the script on the friend's computer should be available through the recovery menu in single user mode, and through System Tools->Share my Desktop from the GUI.
Line 23: Line 58:
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. Connecting the helper and friend will be a seven step process:
Line 25: Line 60:
== Implementation ==  1. '''Information:''' Welcome, explanation of what the program does, warnings about security
 1. '''Question:''' Run in helper of friend mode?
 1. '''Question:'''
  a. If in helper mode, information about what the friend needs to know in order to contact the helper
  a. If in friend mode, IP address of the helper, and an option to automatically run a VNC server (if one isn't running already)
 Both users also get the option to automatically manage their firewall, and to use a reverse connection (explained below)
 1. '''Wait:''' both users are asked to wait while the computers connect to one another and exchange information
 1. '''Question:''' both users are asked to verify the SSH keys that will be used to secure the connection
 1. '''Wait:''' the friend's computer tries to start a VNC server, the helper's computer waits to hear what type of session to run
 1. '''Information:''' Your connection has been set up, how to close the connection, etc.
Line 27: Line 71:
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
In friend mode, the answers to questions should default to the values used by the last successful connection. This is because friends normally only have one helper, but helpers normally have several friends.
Line 32: Line 73:
Opening a terminal from the GUI is a better decision than creating a second (graphical) interface because: To work properly, the program needs connections made over the local loopback interface never to be firewalled in IPv4 or IPv6, and to be able to communicate freely to and from IPv4 TCP port 2222. Inexperienced users might have put firewall rules in place that break this program, while experienced users would be upset if the program modified their firewall behind their backs. Therefore the user is offered the option to have the program poke the relevant holes in the firewall, but the option is disabled by default.
Line 34: Line 75:
 * 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..."
Because helpers are more likely to be able to work around NAT, the program connects from friend to helper by default. Using a reverse connection forces the helper's computer to connect to the friend's instead.
Line 37: Line 77:
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
Once an (insecure) connection has been established, the computers swap SSH keys, usernames, and whether they have an SSH server installed. One user will need to have an SSH server installed (but not necessarily running) in later stages, although it doesn't matter who.
Line 42: Line 79:
=== /bin/remote-recovery === When verifying one another's SSH keys, users will be shown the key both as plain text and in the [[WikiPedia:NATO_phonetic_alphabet|NATO phonetic alphabet]], so that they can unambiguously speak it over a phone line. The computers have already exchanged keys over an insecure connection, so the purpose of this stage is just to verify the keys (in case of a man-in-the-middle attack).
Line 44: Line 81:
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. Ideally, Python's SSL sockets would be used to secure the connection, but their poor documentation and lack of obvious way to extract SSH key information from a session make them an unwise choice. Beyond the programming obstacles, these issues suggest that Python's SSL implementation has too few eyeballs on it to be trustworthy in a security context. Instead, an SSH client and server will be used as a poor man's cryptography library. Because a connection has already been established, communication with the SSH client and server will be done over the local loopback interface, and the encrypted data transferred over the already-established connection. This saves users the need to open up a second public port for the SSH server to listen on, or to wait while the connection on port 2222 is torn down.
Line 46: Line 83:
 1. (note: this should be identical to step 1 on the expert's computer)[[BR]]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.
 1. Remember the current iptables settings by doing:
    {{{
iptables-save > /tmp/saved-iptables
ip6tables-save > /tmp/saved-ip6tables
}}}
 1. 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
}}}
 1. 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
}}}
 1. 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
}}}
    a. if they type "continue" (lower-case only), continue.
    b. otherwise, stop
 1. Prompt the user to enter the IP address of the computer you'll allow access to
 1. Prompt the user to enter the remote-recovery password of the person you'll allow access to
 1. `ssh remote-recovery@$ip_address -L22:localhost:2222`
   a. 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
   a. If it succeeds, read the line beginning "ssh-dsa " and append it to `~remote-recovery/.ssh/authorized_keys`
 1. Tell the user whether SSH succeeded or failed.
    a. If it failed, explain why then stop.
 1. Inform the user that they can press ctrl-c to quit remote recovery.
 1. Wait until ~remote-recovery/login exists
 1. 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
    a. If either condition is not met, throw all remote-recovery users out and warn the friend that they've been subject to foul play
 1. Read lines of text and `write` them to the remote-recovery user's tty
 1. Remove the remote-recovery user, remove them from sudoers, and delete their home directory
 1. 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.
 1. Find the IP address(es) of the computer
   a. 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
   a. 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.
 1. 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>
 1. 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
}}}
 1. Create a ~/.ssh/id_dsa with no passphrase
 1. 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)
}}}
 1. (note: the next three steps should be identical to their equivalents on the recovery computer)[[BR]]Wait until ~remote-recovery/login exists
 1. `passwd -d remote-recovery` - i.e. disable further logins from this account
 1. 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
    a. If either condition is not met, throw all remote-recovery users out and warn the expert that they've been subject to foul play
 1. `sudo -u remote-recovery ssh remote-recovery@127.0.0.1 -p 2222`
 1. 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.
 1. When ssh session exits, remove the remote-recovery user and delete its home directory
Once the SSH connection has been established, the friend's computer will try to connect to a local VNC server, and will advertise a VNC session if it finds one. Otherwise, it will advertise a shell session.
Line 154: Line 87:
 * [https://lists.ubuntu.com/archives/ubuntu-devel-discuss/2008-May/004078.html Discussion on the ubuntu-devel-discuss mailing list]  * [[https://lists.ubuntu.com/archives/ubuntu-devel-discuss/2008-May/004078.html|Discussion on the ubuntu-devel-discuss mailing list]]
 * [[https://launchpad.net/remote-help-assistant|Remote help assistant]]

Summary

There should be a simple, secure, robust way for a non-technical user to allow a more technical user to connect 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. The facility to allow the technical user access should be available, and easily visible, in the default install. Current solutions are secure, robust or simple, but never more than two out of three.

In this document, the technical user is referred to as the "helper", and the non-technical user as the "friend".

Remote help assistant is a program being developed based on this specification.

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 that sub-areas within a window are referred to as tabs.

Other Projects

Several projects aim to provide complete application suites that handle tasks such as remote support. Included among them are:

This project would not provide a complete suite, just a tool to enable remote connections to be made. Complete solutions aren't appropriate to a support request made over the phone.

GNOME's vino and KDE's krfb provide VNC access to a computer. These provide an excellent basis for allowing the helper to connect to a computer with a functioning X server, although this tool needs to add a command-line mode, the ability to route around NAT and firewalls, and an effective mechanism for communicating security information over the telephone. To reinforce the last point, both vino and krfb expect users to send invitations by e-mail, but non-technical users can't be expected to have PGP-encrypted e-mail already set up, and it would be impractical to set it up for them over the phone.

GNU Screen provides shell access to multiple users, but isn't designed for use across multiple computers. To adapt it for this purpose, we would have to find some way of exporting a pseudo-terminal over a network.

Overview of the problem

Both helper and friend might be behind a NAT router or a firewall beyond their control. It's more likely that the helper would be able to configure their network to allow incoming connections on specified ports, but this can't be assumed in the general case.

The friend's computer can't be assumed to have a particularly large set of packages installed and functioning, as they might have removed important packages (or broken them in a more imaginative way). In this blueprint, it will be assumed that the friend has installed packages that are installed in at least 99% of cases reported to the Ubuntu popularity contest, not necessarily with functioning configuration files. Systems more broken than this would be better served by (semi-)automated recovery scripts that can solve specific problems, or by booting to a live CD with a remote recovery script on it.

The helper's computer can be assumed to have a much more complete system, because people with sufficient expertise and patience to help out can reasonably be asked to install packages outside of main, and can be assumed to maintain those packages properly.

If the friend has an X session running, the helper should be given access to it over a VNC connection. Otherwise, the friend should be given a login shell on the user's machine.

Man-in-the-middle attacks are a serious security issue here. If helper and friend haven't already exchanged security information (such as SSH keys), a tamper-proof connection is needed in order to confirm the connection they're using. A telephone conversation is sufficiently tamper-proof for purposes of this project - albeit a channel with severely limited bandwidth. Other systems (such as instant messaging or e-mail) are not sufficiently tamper-proof, and should not be recommended. Since users will use insecure channels no matter what recommendations we make, the following rules should apply, as a second line of defence:

  • The helper should never be able to do anything behind the friend's back. Anything the helper does should be visible to the friend
  • passwords and other important security information should never be transferred over the connection
  • The friend should have an easy way of terminating the session, and should be aware of that method

The first of these conditions have two important side-effects, one positive, one negative. The positive side-effect is that the friend has the opportunity to learn a little by watching the helper. The negative side-effect is that there's no easy way to transfer files between the computers. It's possible to transfer files by pasting base64-encoded text, which accomplishes the same goal and leaves the friend with the ability to check the process.

The second condition can be met by ensuring that, as well as reading anything the helper can read, the friend can write anywhere that the helper can write. Therefore, if the helper needs a password, the friend can type it in without telling the helper.

Over a VNC connection, these conditions are trivially met - both users share a session, and the friend can terminate the session by pressing ctrl-alt-backspace. Over a login shell, these conditions can be met by ensuring that both users have read and write access to the shell, and that the session is terminated when the friend types ctrl-alt-c, or some other special sequence.

Design

This program will be written as a single file in a scripting language, so that it can simply be downloaded and run in an emergency, no matter the architecture the user uses. Python is a good choice for the scripting language because in a default Ubuntu installation, Python supports creating pseudo-ttys (necessary for creating a fully functional shell session) and IPv6 (necessary to talk to Vino), which are only available in Perl if you install extra packages. Although the Ubuntu popularity contest ranks Python lower than Perl, both packages are installed and regularly used in well over 99% of popcon results.

In order to make it easier to access, the script on the friend's computer should be available through the recovery menu in single user mode, and through System Tools->Share my Desktop from the GUI.

Connecting the helper and friend will be a seven step process:

  1. Information: Welcome, explanation of what the program does, warnings about security

  2. Question: Run in helper of friend mode?

  3. Question:

    1. If in helper mode, information about what the friend needs to know in order to contact the helper
    2. If in friend mode, IP address of the helper, and an option to automatically run a VNC server (if one isn't running already)
    Both users also get the option to automatically manage their firewall, and to use a reverse connection (explained below)
  4. Wait: both users are asked to wait while the computers connect to one another and exchange information

  5. Question: both users are asked to verify the SSH keys that will be used to secure the connection

  6. Wait: the friend's computer tries to start a VNC server, the helper's computer waits to hear what type of session to run

  7. Information: Your connection has been set up, how to close the connection, etc.

In friend mode, the answers to questions should default to the values used by the last successful connection. This is because friends normally only have one helper, but helpers normally have several friends.

To work properly, the program needs connections made over the local loopback interface never to be firewalled in IPv4 or IPv6, and to be able to communicate freely to and from IPv4 TCP port 2222. Inexperienced users might have put firewall rules in place that break this program, while experienced users would be upset if the program modified their firewall behind their backs. Therefore the user is offered the option to have the program poke the relevant holes in the firewall, but the option is disabled by default.

Because helpers are more likely to be able to work around NAT, the program connects from friend to helper by default. Using a reverse connection forces the helper's computer to connect to the friend's instead.

Once an (insecure) connection has been established, the computers swap SSH keys, usernames, and whether they have an SSH server installed. One user will need to have an SSH server installed (but not necessarily running) in later stages, although it doesn't matter who.

When verifying one another's SSH keys, users will be shown the key both as plain text and in the NATO phonetic alphabet, so that they can unambiguously speak it over a phone line. The computers have already exchanged keys over an insecure connection, so the purpose of this stage is just to verify the keys (in case of a man-in-the-middle attack).

Ideally, Python's SSL sockets would be used to secure the connection, but their poor documentation and lack of obvious way to extract SSH key information from a session make them an unwise choice. Beyond the programming obstacles, these issues suggest that Python's SSL implementation has too few eyeballs on it to be trustworthy in a security context. Instead, an SSH client and server will be used as a poor man's cryptography library. Because a connection has already been established, communication with the SSH client and server will be done over the local loopback interface, and the encrypted data transferred over the already-established connection. This saves users the need to open up a second public port for the SSH server to listen on, or to wait while the connection on port 2222 is torn down.

Once the SSH connection has been established, the friend's computer will try to connect to a local VNC server, and will advertise a VNC session if it finds one. Otherwise, it will advertise a shell session.

See also


CategoryNetworking CategoryRecovery

Recovery/Remote (last edited 2008-08-06 16:18:23 by localhost)