NOTE: Many of the commands used here are redundant or unnecessary. They are included to further illustrate what is happening behind the scenes.
Contents
Prerequisites
- CyanogenMod 10.1 on your remote device (build after May 12, 2013)
- An SSH client on your local machine (such as OpenSSH or PuTTY)
- A private SSH key. (If you don’t already have one, see this helpful article for information on how to make one.)
- A means of running commands on your phone as root. This guide uses an
adb
connection to your device (see ADB intro for more information)
Setting up sshd
All command are executed from the adb
root shell (su
to root from adb
shell), unless otherwise specified. Properly setting the file and directory permissions is critical for sshd
to function as expected.
Setting up the directory structure
mkdir -p /data/ssh/empty chmod 700 /data/ssh chmod 700 /data/ssh/empty
/data/ssh
holds the server’s host keys and configuration file. /data/ssh/empty
is used for privsep.
NOTE: Both /data/ssh
and /data/ssh/empty
should have already existed. They are created here in case of previous accidental deletion.
Helpful Tip
Commands can be pasted into PuTTY by right-clicking or pressing Shift-Ins.
Creating the server configuration file
cat /system/etc/ssh/sshd_config | \ sed 's/#PermitRootLogin yes$/PermitRootLogin no/' | \ sed 's/#PubkeyAuthentication yes/PubkeyAuthentication yes/' | \ sed 's/#PasswordAuthentication yes/PasswordAuthentication no/' | \ sed 's/#PermitEmptyPasswords no/PermitEmptyPasswords no/' | \ sed 's/#ChallengeResponseAuthentication yes/ChallengeResponseAuthentication no/' | \ sed 's;/usr/libexec/sftp-server;internal-sftp;' > \ /data/ssh/sshd_config chmod 600 /data/ssh/sshd_config
PermitRootLogin no
forbids root login (We’ll be logging in asshell
.)PubkeyAuthentication yes
allows the public key authentication methodPasswordAuthentication no
prevents the password authentication methodPermitEmptyPasswords no
prevents submitting empty passwords (probably redundant, since we disabled password authentication *shrug*)ChallengeResponseAuthentication no
prevents the challenge response authentication methodSubsystem sftp internal-sftp
allowssftp
without the need for thesftp-server
binary
NOTE: You could probably set a password for shell
with passwd
and use the password authentication method, but I am unsure of what, if any, effects this might have.
Helpful Tip
Lines that end in a \
continue the same command on the following line. This was done above improve readability of a long command.
Setting the Authorised Public Key
Upload your public key to your phone to /data/.ssh/authorized_keys
in a text file on a single line. This file is a list of all the public keys that sshd will allow with one key per line. Since only your public key will be allowed, there will only be one line in it. First, make the directory where the public key will be stored, and grant it the correct permissions.
mkdir -p /data/.ssh chmod 700 /data/.ssh chown shell:shell /data/.ssh
Then upload your public key to your phone. (This one command is done on your computer.)
adb push your_public_key /data/.ssh/authorized_keys
Now, fix the permissions.
chmod 600 /data/.ssh/authorized_keys chown shell:shell /data/.ssh/authorized_keys
NOTE: /data/.ssh
should have already existed. As with, /data/ssh
and /data/ssh/empty
, it is created here in case of previous accidental deletion.
Helpful Tip
Some sftp
clients may require the use of an SSH key agent to manage the key.
Starting sshd
There is a script already on the phone called start-ssh that will start sshd, but it requires modification:
mkdir -p /data/local/userinit.d cat /system/bin/start-ssh | \ sed 's;/system/etc/ssh/sshd_config;/data/ssh/sshd_config;' > \ /data/local/userinit.d/99sshd chmod 755 /data/local/userinit.d/99sshd
/system/etc/ssh/sshd_config
is changed to/data/ssh/sshd_config
so configuration changes are not lost after a /system flash
To start sshd, run /data/local/userinit.d/99sshd
, the new version of start-ssh. It must be run as root. It will also get run automatically by /system/etc/init.d/90userinit
on startup, along with any other scripts you put in /data/local/userinit.d
.
Connecting and Usage
Once sshd has been started on the phone, you can connect to it with your favourite SSH client and the username shell
. This is the same username adb shell
gives you, so your permissions are the same until you choose to elevate them using su
. You can connect as root
(you’ll have to edit sshd_config to allow it), but that is highly inadviseable. Only using root when you have to puts you at a much smaller risk of accidentally wrecking things.
The shell
user is pretty weak, so you might like to carve out a home folder, where shell
has write access. There you can also keep settings for all your favourite shelly programs, like emacs, vim, and bash. The following is an example of just that.
Make the folder (as root
, using su):
mkdir /data/home chmod 755 /data/home chown shell:shell /data/home
Everything else from here on in can be done as shell
over SSH or with scp. Copy over some key config files (run on the computer):
scp .inputrc .bash_profile .bashrc .vimrc .screenrc shell@hostname:/data/home
Now, we’d like a fast way of configuring the home directory, since it gets ignored when we first log in. Put the following in /data/home/login:
#!/system/xbin/bash HOME='/data/home' cd exec bash --login
Then set its permissions to allow execution:
chmod 755 /data/home/login
Now, to switch to the new home directory when you log in, just type exec /data/home/login
.
Android has made it so that the files and directories shell
creates can only be accessed by itself by default. If you want to access the files you make with shell
from your other apps, like file browsers, without root access, you’ll need to change the default file and directory creation permissions. Add the following to your .bash_profile on a line by itself to allow read-only access from all apps: umask 0022
. To allow all apps read/write access, use umask 0000
instead.
To emulate sudo behaviour, you might like to put the following alias in your .bashrc: alias sudo='su root'
.
Troubleshooting
- Change
# DEBUG=1
toDEBUG=1
in/data/local/userinit.d/99sshd
to enable debug logging tologcat
- Reboot remote device (or
kill
thesshd
process and run99sshd
) - Run
logcat | grep sshd
to show the debug log - When in debug mode,
sshd
will quit after the first ssh session exits. Recomment theDEBUG=1
line and restart99sshd
for normal behavior.
NOTE: Most issues will be related to permissions.
Helpful Tip
Some devices may be sluggish with the screen locked. Try unlocking the screen to see if performance improves.
Todo
- Find specific versions of CM where supported
- Identify effects of setting password for
shell
user - Add more troubleshooting information
- Add a section for client (PuTTY) setup; specifically, private key conversion (
puttygen
) and/or ssh-agent (pageant
) usage (this may be more useful has a it’s own document)
Problem with SELinux
My solution for problem:
W/sshd type=1400 audit(0.0:16): avc: denied { open } for name="sshd_config"
- Install SuperSu ([1])
- create directory /system/su.d
- modify file 99sshd and add/change
supolicy --live "allow sysinit self:capability setgid;allow sysinit system_data_file:file open;"
/system/bin/logwrapper /system/bin/sshd -f /data/ssh/sshd_config
Notice I removed the -D param. Because with it the sshd was killed.
And added the logwrapper, because sshd can generate an output when error.
- put the file 99sshd into /system/su.d/ (remount rw)
I choosed this directory because the userinit.sh had problems (selinux) with running another scripts.
Allowing root login
Modify file /data/ssh/sshd_config
AuthorizedKeysFile /data/.ssh/authorized_keys.%u PermitRootLogin yes
and rename file /data/.ssh/authorized_keys to authorized_keys.root and authorized_keys.shell
Content of this page is based on informations from wiki.cyanogenmod.org, under CC BY-SA 3.0 licence.