You are on page 1of 10

OpenSSH Guide for Dummies rev. 0.1 _ _ ___ _ _ ___ ___ ___ _ ___ _ _ _ . .

-_ _ _ ___ _ _ ___ ___ ___ ___ * truncode security development * http://truncode.org Nathan Wicked <nwicked@truncode.org> This paper is about using and better understanding the OpenSSH config files and how to use them in order to make your OpenSSH experience less painfull. Ofcourse all of these informations can be found in the the manual pages of ssh and sshd or at the OpenSSH homepage located http://www.openssh.org/. ] Section I: Introduction A short explanation of OpenSSH as one can find in the OpenSSH home page. OpenSSH is a FREE version of the SSH protocol suite of network connectivity tools that increasing numbers of people on the Internet are coming to rely on. Many users of telnet, rlogin, ftp, and other such programs might not realize that their password is transmitted across the Internet unencrypted, but it is. OpenSSH encrypts all traffic (including passwords) to effectively eliminate eavesdropping, connection hijacking, and other network-level attacks. Additionally, OpenSSH provides a myriad of secure tunneling capabilities, as well as a variety of authentication methods. The OpenSSH suite includes the ssh program which replaces rlogin and telnet, scp which replaces rcp, and sftp which replaces ftp. Also included is sshd which is the server side of the package, and the other basic utilities like ssh-add, ssh-agent, ssh-keysign, ssh-keyscan, ssh-keygen and sftp-server. OpenSSH supports SSH protocol versions 1.3, 1.5, and 2.0. ] Section II: SSH Server daemon config (sshd_config) At first we will see the most commonly used options that sshd_config supports and then we will suggest a nice small clean config file for you to see and use if you like. AllowGroups This keyword can be followed by a list of group name patterns, separated by spaces. If specified, login is allowed only for users whose primary group or supplementary group list matches one of the patterns. '*' and ''? can be used as wildcards in the patterns. Only group names are valid; a numerical group ID is not recognized. By default, login is allowed for all groups. AllowTcpForwarding Specifies whether TCP forwarding is permitted. The default is ``yes''. AllowUsers This keyword can be followed by a list of user name patterns, separated by spaces. If specified, login is allowed only for user names that match one of the patterns. '*' and ''? can be

used as wildcards in the patterns. Only user names are valid; a numerical user ID is not recognized. Banner In some jurisdictions, sending a warning message before authentication may be relevant for getting legal protection. The contents of the specified file are sent to the remote user before authentication is allowed. This option is only available for protocol version 2. By default, no banner is displayed. ClientAliveInterval Sets a timeout interval in seconds after which if no data has been received from the client, sshd will send a message through the encrypted channel to request a response from the client. The default is 0, indicating that these messages will not be sent to the client. This option applies to protocol version 2 only. Compression Specifies whether compression is allowed. The argument must be ``yes'' or ``no''. The default is ``yes''. DenyGroups Opposite of AllowGroups. DenyUsers Opposite of AllowUsers. KeepAlive Specifies whether the system should send TCP keepalive messages to the other side. The default is ``yes'' (to send keepalives). ListenAddress Specifies the local addresses sshd should listen on. The form is ListenAddress HOST:POST LoginGraceTime The server disconnects after this time if the user has not successfully logged in. The default is 120 seconds. LogLevel Gives the verbosity level that is used when logging messages from sshd. The possible values are: QUIET, FATAL, ERROR, INFO, VERBOSE, DEBUG, DEBUG1, DEBUG2 and DEBUG3. The default is INFO. PasswordAuthentication Specifies whether password authentication is allowed. The default is ``yes''. PermitEmptyPasswords When password authentication is allowed, it specifies whether the server allows login to accounts with empty password strings. The default is ``no''. PermitRootLogin Specifies whether root can login using ssh(1). The argument must be ``yes'', ``without-password'', ``forced-commands-only'' or ``no''. The default is ``yes''. If this option is set to ``without-password'' password authentication is disabled for root.

If this option is set to ``forced-commands-only'' root login with public key authentication will be allowed, but only if the command option has been specified (which may be useful for taking remote backups even if root login is normally not allowed). All other authentication methods are disabled for root. If this option is set to ``no'' root is not allowed to login. PidFile Specifies the file that contains the process ID of the sshd daemon. The default is /var/run/sshd.pid. PrintLastLog Specifies whether sshd should print the date and time when the user last logged in. The default is ``yes''. Protocol Specifies the protocol versions sshd supports. The possible values are ``1'' and ``2''. Default is 1,2. PubkeyAuthentication Specifies whether public key authentication is allowed. The default is ``yes''. StrictModes Specifies whether sshd should check file modes and ownership of the user's files and home directory before accepting login. The default is ``yes''. UsePrivilegeSeparation Specifies whether sshd separates privileges by creating an unprivileged child process to deal with incoming network traffic. After successful authentication, another process will be created that has the privilege of the authenticated user. The goal of privilege separation is to prevent privilege escalation by containing any corruption within the unprivileged processes. The default is ``yes''. And thats preaty much some of the most interesting options that one can use. Ofcourse there are more options than these. Depending on the situation, you might need options that we havent included. After finishing this Section you'll find your self in a good place and you'll be able to do it your self. Unless ofcourse you're a real dummie :P And here you'll see a sample config file with the options that we mention and why we wanna use them. ----sshd_config.sample-----# Sample sshd_config file # Sat Oct 4 20:40:49 BST 2003 # # if you use a system that creates a seperate Group with every user # you'll have to use theirs. # OpenBSD, RedHat and possibly others too are using same User / Group name # We use a group named admins for those that we need to administer the box. AllowGroups admins

# We dont want to allow tcp forwarding through ssh AllowTcpForwarding No # We are a bit paranoid so in case someone managed to add a user # in our group :P AllowUsers databus crap necrose modular nbarnes # we put this just for fun :P Banner /etc/truncode-sshd.banner # We dont want our users to stay on the server idle for more # than 3600 seconds. They might have gone away from their console # and forgot to log out. ClientAliveInterval 3600 # We want compression, make sure you compiled openssh --with-zlib Compression yes # We deny some groups that are overpowered again out of paranoia :-) # replace root with wheel if you're on BSD system :P # add your own groups too. DenyGroups root bin daemon sys adm tty disk lp mail news uucp kmem # We deny some users again out of paranoia just to make sure. DenyUsers bin backup daemon games mail mysql nobody # We want keep alive because it will help avoiding ghosts on our system. KeepAlive yes # We have multiple interfaces and we need sshd to listen only in one. # eth0: 192.168.1.1 # eth1: 62.1.0.1 ListenAddress 192.168.1.1:22 # We dont want our users to stay without authenticating their selfs from more # than 30 seconds # We dont want our users to stay without authenticating their selfs from more # than 30 seconds. You might want to increase this value if you're in slow # link. LoginGraceTime 30 # We want extra info on our sessions in case something bad will happend # like a new 0day sploit for example, we will be able to examine some logs # to see what happend. LogLevel VERBOSE # We dont want our users to use password in order to login. # Ofcourse the first user in the system will have to atleast be able to # su root or be able to login with password :P # passwords are bad either way mkey ?. PasswordAuthentication no # If we dont want passwords then we sure as hell dont wanna use # empty passwords. Those things are dangerus you know. PermitEmptyPasswords no # root is the damn bastard that can destroy your life in a matter of seconds # make sure you will not allow him to log. # this is why we used su root for a user :P

PermitRootLogin no # We use this file to manage our sshd, but basicaly if we need to reread # the sshd_config without droping everyones connection. # we use this file like this in order to restart our sshd. # This is also usefull if you have multiple sshd in your system # and you want to manage them seperately. # kill -HUP `cat /var/run/sshd.pid` PidFile /var/run/sshd-port22.pid # Yeah we want to see our last log info cause you never know what might # have happend while you were sleeping. Ofcourse an attacker could have # modified it but anyways we use it either way :P PrintLastLog yes # SSH v1 has great deal of bugs in its history so we dont want even to support # it on our servers. Protocol 2 # We gonna use our keys to access the server (read on the following Sections # for explanation about pub keys). PubkeyAuthentication yes # We want sshd to check for faulty permitions, if a user has world writable # authorized key someone might overwrite it and gain access with his account. StrictModes yes # Hell yeah, this is one of life savers of ssh, if this option wasnt in there # there would be at least 5 more exploits for openssh today :P UsePrivilegeSeparation yes # We dont wanna use FTP. One port one key a bit more secure feeling. Subsystem sftp /usr/lib/sftp-server ----sshd_config.sample-----] Section III: SSH Client (ssh_config or .ssh/config) Again we will describe the most commonly used options and again one sample ssh_config file. Host Restricts the following declarations (up to the next Host keyword) to be only for those hosts that match one of the patterns given after the keyword. '*' and ''? can be used as wildcards in the patterns. A single '*' as a pattern can be used to provide global defaults for all hosts. The host is the hostname argument given on the command line (i.e., the name is not converted to a canonicalized host name before matching). BindAddress Specify the interface to transmit from on machines with multiple interfaces or aliased addresses. Note that this option does not work if UsePrivilegedPort is set to ``yes''. CheckHostIP If this flag is set to ``yes'', ssh will additionally check the host IP address in the known_hosts file. This allows ssh to detect if a host key changed due to DNS spoofing. If the option

is set to ``no'', the check will not be executed. The default is ``yes''. Cipher Specifies the cipher to use for encrypting the session in protocol version 1. Currently, ``blowfish'', ``3des'', and ``des'' are supported. des is only supported in the ssh client for interoperability with legacy protocol 1 implementations that do not support the 3des cipher. Its use is strongly discouraged due to cryptographic weaknesses. The default is ``3des''. Compression Specifies whether to use compression. The argument must be ``yes'' or ``no''. The default is ``no''. ConnectionAttempts Specifies the number of tries (one per second) to make before exiting. The argument must be an integer. This may be useful in scripts if the connection sometimes fails. The default is 1. EscapeChar Sets the escape character (default: '~'). The escape character can also be set on the command line. The argument should be a single character, '^' followed by a letter, or ``none'' to disable the escape character entirely (making the connection transparent for binary data). HostName Specifies the real host name to log into. This can be used to specify nicknames or abbreviations for hosts. Default is the name given on the command line. Numeric IP addresses are also permitted (both on the command line and in HostName specifications). PasswordAuthentication Specifies whether to use password authentication. The argument to this keyword must be ``yes'' or ``no''. The default is ``yes''. Port Specifies the port number to connect on the remote host. Default is 22. Protocol Specifies the protocol versions ssh should support in order of preference. The possible values are ``1'' and ``2''. Multiple versions must be comma-separated. The default is ``2,1''. This means that ssh tries version 2 and falls back to version 1 if version 2 is not available. PubkeyAuthentication Specifies whether to try public key authentication. The argument to this keyword must be ``yes'' or ``no''. The default is ``yes''. This option applies to protocol version 2 only. User Specifies the user to log in as. This can be useful when a different user name is used on different machines. This saves the trouble of having to remember to give the user name on the command line.

And again here is a sample ssh_config file that will explain some things. Note that if you want to make the ssh_config file global you'll have to put it on /etc/ssh/ssh_config or if you wanna use it only for a single user you can put it on $HOME/.ssh/config . Either way its up to you. ----ssh_config.sample---# Sample ssh_config file # Sat Oct 4 20:40:49 BST 2003 # # The host we use in the command line is # pub for pub.truncode.org so we save a few keystrokes :P Host pub # Remember the two interfaces? Well we preffer this one :P # to be seen as our source address we dont want the ssh to # choose for as. BindAddress 192.168.1.1 # We want to make sure that everything is fine, we dont want to # continue on our authentication if something is wrong. CheckHostIP yes # 3des is good but we preffer a better algorithm Cipher blowfish # We want compression. Compression yes # some times this machine get crazy so we want to attempt 3 times # before we stop trying :P ConnectionAttempts 3 # This is the default but we used it either way EscapeChar ~ # The full hostname of the machine is HostName pub.truncode.org # Nop we said before we hate passwords. PasswordAuthentication no # This box uses a different port than the default so we have to tell # ssh what port that is in order to avoid -p port option. Port 6161 # We only trust SSH v2 Protocol 2 # Yeap we need pubkey only, we will explain about keys. PubkeyAuthentication yes # the username i use to connect on pub is different than my current # and i dont wana run ssh user@host anyways. User nwicked Now remember that the configurations for every host start from the Host until the next Host line. So if you wanted to add more systems add another Host blah at the end of file and write your options for ] Section IV: Keys simplified login line you could this host.

We will not explain in depth what and how the keys are used. We will just explain as simple as we can what they do and thats it :P What happens is this. You generate a pair of keys a public key and a private key. You send your public key to the server. When you're attempting to connect the server uses this public key to encrypt his own public key and sends it back. Now the authentication goes like this: Server encrypts data with your public key and only your private key can decrypt those informations. Same goes with client when you sending data you use the public key of the server to encrypt data and then the Server uses his own private key to decrypt what you just sent. As you can see the private keys MUST be secured. And this simplifies your login session a bit. You'll see in the next sections how to generate them and use them. ] Section V: Generate Keys The process of generating a key is really simple. Here is an example of SSH v2 keys generation. -------snip----nwicked@debian-pub:~ > ssh-keygen -t dsa Generating public/private dsa key pair. Enter file in which to save the key (/home/nwicked/.ssh/id_dsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Passphrases do not match. Try again. Enter passphrase (empty for no passphrase): my pass phrase Enter same passphrase again: my pass phrase Your identification has been saved in /home/nwicked/.ssh/id_dsa. Your public key has been saved in /home/nwicked/.ssh/id_dsa.pub. The key fingerprint is: 31:38:cc:ab:42:f0:35:21:61:50:5b:14:9a:f8:11:7f nwicked@aqua.truncode.org nwicked@debian-pub:~ > -------snip----Now we generated our keys and we are ready to use them. Read on... ] Section VI: Use the Key Luke Ok we manage to generate our keys now what? You have to give the public key to someone that can connect to the box you're planning to have access. In my case i have to mail my pub key to nbarnes (our admin) in order to place my public key to the correct place and allow me to connect. In your case nbarnes is not your admin :P so either its you or someone else, either way you have to place the keys in the Destination host in your $HOME/.ssh/ under the name of authorized_keys. If you have more than one key you simply cat key.pub >> authorized_keys and now you can connect using two diff keys. But still we are not over, because we have to write this damn passphrase again. And it was quite big :-/ So what are you gonna do? Read the next Section dummy. ] Section VII: Manage the Keys

Ok here is a litle tric i use in order to avoid giving my pass phrase every time. Note that the passphrase will only be required ONCE and it will never prompt you again until your next session to the source host. Our simple solution is ssh-agent and ssh-add tools. Consider ssh-agent as a tool that stores the pass phrase for a key and instead of you this tool gives the pass phrases to the ssh. ssh-add is the tool to add those pass phrases into ssh-agent. Since i use X in order to work multiple consoles in my system, i placed the appropriate commands into .xinitrc, but we will show you how to use it on your .profile in case you work only console. First we launch our ssh-agent from startx and we save the output into $HOME/.ssh/.ssh-agent this is because ssh-agent produces an output that we need to evaluate into our shell for all our sessions to use ssh-agent. ----.xinitrc---killall -9 ssh-agent ssh-agent>~/.ssh-agent exec fluxbox -----.xinitrc----Here is what the .ssh-agent file looks like You dont have to put these by your self. These will be added everytime you execute ssh-agent. ----~/.ssh-agent---SSH_AUTH_SOCK=/tmp/ssh-XXmrklhH/agent.2719; export SSH_AUTH_SOCK; SSH_AGENT_PID=2720; export SSH_AGENT_PID; echo Agent pid 2720; ----~/.ssh-agent---And here is our .bashrc that every console we open reads it. ----.bashrc----source ~/.ssh-agent alias exit="kill -9 $SSH_AGENT_PID;logout" ----.bashrc----Now everytime we open a new term we use the same SSH_AUTH_SOCK and thus we use the same ssh-agent for all our connections. If you want to use this for every seperate session you could simply put ----.bashrc---eval `ssh-agent` alias exit="kill -9 $SSH_AGENT_PID;logout" ----.bashrc---Now we have our files in place and our ssh-agent is working we need to add those keys in our ssh-agent. ----snip----nwicked@debian-pub:~ > ssh-add Enter passphrase for /home/nwicked/.ssh/id_dsa: Identity added: /home/nwicked/.ssh/id_dsa (/home/nwicked/.ssh/id_dsa) nwicked@debian-pub:~ > ----snip----

Now when i try to connect to a host (pub.truncode.org for example) i will get logged in automaticaly without giving password or passphrase. Now isnt that something? :P And still we maintain a level of security. Hope you enjoyed the text. You need to remember that everyone that uses SSH open to the world is a paranoid and just because its called Secure Shell it doesnt mean it is secure, it means it just uses a secure tunnel to send and receive data :P ----snip---

You might also like