####################### Openssh tips and tricks ####################### :Author: Dimitry Dukhovny .. contents:: Openssh is the way standards-compliant nodes communicate securely. Alternatives exist, but no one cares. This workhorse is well maintained and implements good crypto out of the box. .. .. note:: .. To help support this site and learn more, check out .. `Step by Step Secure Shell Configuration (SSH) for Linux Server, Router and Switch `_. .. note:: To donate to the maintenance of these pages, do send BTC to bc1qkw0pp78kv67zrgp8xds7qrqen7mhlz0rs5p8p5 .. .. image:: images/qrcode-gnomon-static.png Using keys to pivot around your environment =========================================== Using keys is safer, smarter, and easier on your life than using passwords. That is only true if you do not mismanage your keys. Use keys in the name of both security and sloth. Create an RSA key pair if you do not already have one. .. code-block:: bash :linenos: :caption: create your personal keys # This will prompt you for a passphrase. Do pick one! [ ! -f ~/.ssh/id_rsa ] && ssh-keygen Fetch the host key from every remote host you are likely to encounter. I raid the */etc/hosts* file and the */etc/ansible/hosts.ini* files for this. .. code-block:: bash :linenos: :caption: keyscan as much as we can to avoid key acceptance prompts egrep -hv '^\s*(#|\[.*\]|$)' /etc/hosts /etc/ansible/hosts | \ awk '{print $1}' | sort | uniq | \ xargs ssh-keyscan >> ~/.ssh/known_hosts Load your new key into memory so you never get prompted for an SSH password until you log out. This will prompt you for a passphrase. Once. Then you can log into as many hosts as you want without a prompt. .. code-block:: bash :linenos: :caption: load the key into memory # This will prompt you for your passphrase eval `ssh-agent`; ssh-add ~/.ssh/id_rsa Disseminate SSH keys ==================== .. code-block:: bash :linenos: :caption: create an authorized keys file on every host remotehostlist=`egrep -hv '^\s*(#|\[.*\]|$)' \ /etc/hosts /etc/ansible/hosts | \ awk '{print $1}' | sort | uniq` for rh in ${remotehostlist} do ssh -o preferredauthentications=password user1@${rh} \ "echo `cat ~/.ssh/id_rsa.pub` >> \ .ssh/authorized_keys; \ chmod 600 ~/.ssh/authorized_keys" done .. Fetch keys from AWS Secrets =========================== * Create an *RSA key secret* called **svc.ssh.key** from your *id_rsa* file * Create an *RSA key passphrase* secret called **svc.ssh.key.p** .. code-block:: bash :linenos: :caption: save your secrets read -p "Enter passphrase:" -s aws secretsmanager create-secret \ --name svc.ssh.key.p \ --description "encrypted service account SSH key passphrase" \ --secret-string "${REPLY}" unset REPLY aws secretsmanager create-secret \ --name svc.ssh.key \ --description "encrypted service account SSH key" \ --secret-string "`cat ${HOME}/.ssh/id_rsa`" .. * For each scripted execution, you can use... .. code-block:: bash :linenos: :caption: use your secrets in scripted actions without prompting datestamp=`date +%s` [ ! -d ${HOME}/.ssh ] && mkdir -p ${HOME}/.ssh aws secretsmanager \ get-secret-value \ --secret-id "svc.ssh.key.p" \ --query SecretString \ > ${HOME}/.ssh/service.key echo 'aws secretsmanager \ get-secret-value \ --secret-id "svc.ssh.key.p" \ --query SecretString' \ > ${HOME}/.ssh/.k.sh chmod 700 ${HOME}/.ssh ${HOME}/.ssh/.k.sh chmod 400 ${HOME}/.ssh/service.key export DISPLAY=1 export SSH_ASKPASS=${HOME}/.ssh/.k.sh eval `ssh-agent` ssh-add ${HOME}/.ssh/service.key <<< ${HOME}/.ssh/.k.sh # Perform your SSH actions after this, such as Ansible runs # unset your key with... # ssh-agent -k .. Trouble: failed login with no password prompt ============================================== You probably have an RSA key in ~/.ssh, but your receiving host only allows one login attempt and has no *authorized_keys* file with your public key in it. You need to tell it to use a password because SSH prefers key logins. For these examples, you are **user1** and you want to log into **serverB**. .. code-block:: bash :linenos: :caption: log into a host, forcing a password prompt ssh -o preferredauthentications=password user1@serverB Let us say you want to just fix the problem once and for all by copying your public key to the remote host. Do this. .. code-block:: bash :linenos: :caption: create an authorized keys file on a single remote host ssh -o preferredauthentications=password user1@serverB \ "echo `cat ~/.ssh/id_rsa.pub` >> .ssh/authorized_keys; \ chmod 600 ~/.ssh/authorized_keys" Use the trick from the keyscan example to do this on every remote host. See `Disseminate SSH keys`_. Trouble: logins are painfully slow =================================== The most common two culprits are DNS troubles on the receiving host and GSSAPI login attempts when you are not using the GSS API. I will address the latter here. See `Troubleshooting DNS `_ for the former. Trouble: key file is too open or has wrong permissions ======================================================= * SSH wants the private key to be protected from unauthorized users. * Assuming a key called *mykey* in the *.ssh* directory ... .. code-block:: bash :linenos: chmod 700 ${HOME}/.ssh chmod 600 ${HOME}/.ssh/mykey ..