SSH public key authentication: Difference between revisions

From NixOS Wiki
imported>Milahu
Created page with "Let's assume a <code>servermachine</code> is running NixOS. To setup a public key based SSH connection from <code>clientmachine</code> to <code>servermachine</code>: <syntaxh..."
 
 
(12 intermediate revisions by 8 users not shown)
Line 1: Line 1:
Let's assume a <code>servermachine</code> is running NixOS. To setup a public key based SSH connection from <code>clientmachine</code> to <code>servermachine</code>:
To setup a public key based SSH connection from <code>your-machine</code> (client) to <code>another-machine</code> (server):


<syntaxhighlight lang="console">
<syntaxhighlight lang="console">
[user@clientmachine] $ ssh-keygen -f ~/.ssh/servermachine
[user@your-machine] $ ssh-keygen -f ~/.ssh/another-machine
[user@clientmachine] $ ssh-copy-id -i ~/.ssh/servermachine servermachine
[user@your-machine] $ ssh-copy-id -i ~/.ssh/another-machine another-machine-host-or-ip
</syntaxhighlight>
</syntaxhighlight>


Now the public key is stored on the <code>servermachine</code> in <code>/home/user/.ssh/authorized_keys</code>
In case <code>another-machine</code> uses another port for SSH connections use this command instead:
<syntaxhighlight lang="console">
[user@your-machine] $ ssh-copy-id -i ~/.ssh/another-machine -p1234 another-machine-host-or-ip
</syntaxhighlight>
 
Now the public key is stored on the <code>another-machine</code> in <code>/home/user/.ssh/authorized_keys</code>
 
On <code>your-machine</code>, we stored the key file in the non-standard path <code>~/.ssh/another-machine</code>, so we must tell the SSH client to use the key file:
 
<syntaxhighlight lang="console">
[user@clientmachine] $ ssh -i ~/.ssh/another-machine another-machine-host-or-ip
</syntaxhighlight>


Note: On the <code>clientmachine</code>, we created the public key file in the non-standard path <code>~/.ssh/servermachine</code>, so later we must use <code>ssh -i ~/.ssh/servermachine servermachine</code> to send our public key.
The connection should work without password.


Now, on the <code>servermachine</code>, we must tell the SSH server, where to find the <code>authorized_keys</code> file. To <code>/etc/nixos/configuration.nix</code> we add:
To make the SSH client automatically use the key file, we add this to <code>/home/user/.ssh/config</code>:


<syntaxhighlight>
Host another-machine
  HostName 192.168.1.105 # another-machine-host-or-ip
  #Port 22
  #User user
  # Prevent using ssh-agent or another keyfile, useful for testing
  IdentitiesOnly yes
  IdentityFile ~/.ssh/another-machine
</syntaxhighlight>
== SSH agent ==
A ssh private key, for which a phrase is defined, can be clumsy if you use it multiple times. It is possible to store the private key identity in a ssh-agent. The ssh-agent uses the ssh private key identity when you issue a ssh command, for instance when using ssh to connect.
To define NixOS to setup a ssh-agent, add this to your configuration:
<syntaxhighlight lang="nix">
<syntaxhighlight lang="nix">
services.openssh = {
programs.ssh.startAgent = true;
  enable = true;
  authorizedKeysFiles = [ ".ssh/authorized_keys" ];
#  passwordAuthentication = false;
#  permitRootLogin = "yes";
#  challengeResponseAuthentication = false;
};
</syntaxhighlight>
</syntaxhighlight>


Optionally, we can set <code>passwordAuthentication = false;</code> to require public key authentication, usually for better security.
NixOS will start a user systemd service with the ssh-agent at login. You can see the service with the command <code>systemctl --user status ssh-agent</code>.


Now we must tell the SSH client to send the public key:
It provides also the environment variable $SSH_AUTH_SOCK which refers to <code>/run/user/1000/ssh-agent</code> , in this case for user id 1000.
 
If you want to use a ssh key pair for authenticating, you can add this to the ssh-agent using the command ssh-add entering the phrase only once.


<syntaxhighlight lang="console">
<syntaxhighlight lang="console">
[user@clientmachine] $ ssh -i ~/.ssh/servermachine servermachine
[user@your-machine] $ ssh-add .ssh/id_rsa
Enter passphrase for .ssh/id_rsa:
Identity added: .ssh/id_rsa (myaccounts@mymachine)
</syntaxhighlight>
</syntaxhighlight>


The connection should work without password.
If you store the ssh public key with the command ssh-copy-id on <code>another-machine</code> as shown above, you can logon without giving a password or phrase.
 
== SSH server config ==


== Alternative config ==
Optionally, on the NixOS-based <code>another-machine</code>, we can set <code>passwordAuthentication = false;</code> to require public key authentication for better security.
 
<syntaxhighlight lang="nix">
services.openssh = {
  enable = true;
  # require public key authentication for better security
  settings.PasswordAuthentication = false;
  settings.KbdInteractiveAuthentication = false;
  #settings.PermitRootLogin = "yes";
};
</syntaxhighlight>


We can also store the public keys in <code>/etc/nixos/configuration.nix</code>:
We can also store the public keys in <code>/etc/nixos/configuration.nix</code>:
Line 39: Line 75:
users.users."user".openssh.authorizedKeys.keys = [
users.users."user".openssh.authorizedKeys.keys = [
   "ssh-rsa AAAAB3Nz....6OWM= user" # content of authorized_keys file
   "ssh-rsa AAAAB3Nz....6OWM= user" # content of authorized_keys file
   # note: ssh-copy-id will add user@clientmachine after the public key
   # note: ssh-copy-id will add user@your-machine after the public key
   # but we can remove the "@clientmachine" part
   # but we can remove the "@your-machine" part
];
];
</syntaxhighlight>
</syntaxhighlight>
Line 51: Line 87:
];
];
</syntaxhighlight>
</syntaxhighlight>
== KDE ==
By default, KDE prompts you to enter the passwords for your SSH keys to unlock them across session starts. To avoid being asked to unlock your SSH keys every time a session is restarted (e.g., after logging out or rebooting), you can use <code>ksshaskpass</code> to store the passwords. To enable this, make the following changes to your configuration:
<syntaxhighlight lang="nix">
programs.ssh = {
  startAgent = true;
  enableAskPassword = true;
  askPassword = pkgs.lib.mkForce "${pkgs.ksshaskpass.out}/bin/ksshaskpass";
};
environment.variables = {
  SSH_ASKPASS_REQUIRE = "prefer";
};
</syntaxhighlight>
{{Note | It is also possible to add {{ic|SSH_ASKPASS}} to your environment variables, but you will likely encounter complaints when running {{ic|nixos-rebuild}}. You can add {{ic|lib.mkForce}} to {{ic|SSH_ASKPASS}} to circumvent the error, like this:<br />{{ic|1=SSH_ASKPASS = lib.mkForce "${pkgs.ksshaskpass.out}/bin/ksshaskpass";}}.
}}
After applying these changes, either log out (if you used <code>switch</code>) or reboot (if you used <code>boot</code> for the variables to take effect.
When you use an SSH key for the first time, you will be prompted to enter its passphrase. <strong><em>Be sure to select the "Remember password" checkbox</strong></em> and the passphrase will be securely stored in the KDE Wallet and automatically retrieved across session restarts.
== See also ==
* [[Distributed build]]

Latest revision as of 11:44, 15 November 2024

To setup a public key based SSH connection from your-machine (client) to another-machine (server):

[user@your-machine] $ ssh-keygen -f ~/.ssh/another-machine
[user@your-machine] $ ssh-copy-id -i ~/.ssh/another-machine another-machine-host-or-ip

In case another-machine uses another port for SSH connections use this command instead:

[user@your-machine] $ ssh-copy-id -i ~/.ssh/another-machine -p1234 another-machine-host-or-ip

Now the public key is stored on the another-machine in /home/user/.ssh/authorized_keys

On your-machine, we stored the key file in the non-standard path ~/.ssh/another-machine, so we must tell the SSH client to use the key file:

[user@clientmachine] $ ssh -i ~/.ssh/another-machine another-machine-host-or-ip

The connection should work without password.

To make the SSH client automatically use the key file, we add this to /home/user/.ssh/config:

Host another-machine
  HostName 192.168.1.105 # another-machine-host-or-ip
  #Port 22
  #User user

  # Prevent using ssh-agent or another keyfile, useful for testing
  IdentitiesOnly yes
  IdentityFile ~/.ssh/another-machine

SSH agent

A ssh private key, for which a phrase is defined, can be clumsy if you use it multiple times. It is possible to store the private key identity in a ssh-agent. The ssh-agent uses the ssh private key identity when you issue a ssh command, for instance when using ssh to connect.

To define NixOS to setup a ssh-agent, add this to your configuration:

programs.ssh.startAgent = true;

NixOS will start a user systemd service with the ssh-agent at login. You can see the service with the command systemctl --user status ssh-agent.

It provides also the environment variable $SSH_AUTH_SOCK which refers to /run/user/1000/ssh-agent , in this case for user id 1000.

If you want to use a ssh key pair for authenticating, you can add this to the ssh-agent using the command ssh-add entering the phrase only once.

[user@your-machine] $ ssh-add .ssh/id_rsa
Enter passphrase for .ssh/id_rsa: 
Identity added: .ssh/id_rsa (myaccounts@mymachine)

If you store the ssh public key with the command ssh-copy-id on another-machine as shown above, you can logon without giving a password or phrase.

SSH server config

Optionally, on the NixOS-based another-machine, we can set passwordAuthentication = false; to require public key authentication for better security.

services.openssh = {
  enable = true;
  # require public key authentication for better security
  settings.PasswordAuthentication = false;
  settings.KbdInteractiveAuthentication = false;
  #settings.PermitRootLogin = "yes";
};

We can also store the public keys in /etc/nixos/configuration.nix:

users.users."user".openssh.authorizedKeys.keys = [
  "ssh-rsa AAAAB3Nz....6OWM= user" # content of authorized_keys file
  # note: ssh-copy-id will add user@your-machine after the public key
  # but we can remove the "@your-machine" part
];

... or use a custom path for the authorized_keys file:

users.users."user".openssh.authorizedKeys.keyFiles = [
  /etc/nixos/ssh/authorized_keys
];

KDE

By default, KDE prompts you to enter the passwords for your SSH keys to unlock them across session starts. To avoid being asked to unlock your SSH keys every time a session is restarted (e.g., after logging out or rebooting), you can use ksshaskpass to store the passwords. To enable this, make the following changes to your configuration:

programs.ssh = {
  startAgent = true;
  enableAskPassword = true;
  askPassword = pkgs.lib.mkForce "${pkgs.ksshaskpass.out}/bin/ksshaskpass";
};

environment.variables = {
  SSH_ASKPASS_REQUIRE = "prefer";
};
Note: It is also possible to add SSH_ASKPASS to your environment variables, but you will likely encounter complaints when running nixos-rebuild. You can add lib.mkForce to SSH_ASKPASS to circumvent the error, like this:
SSH_ASKPASS = lib.mkForce "${pkgs.ksshaskpass.out}/bin/ksshaskpass";.

After applying these changes, either log out (if you used switch) or reboot (if you used boot for the variables to take effect.

When you use an SSH key for the first time, you will be prompted to enter its passphrase. Be sure to select the "Remember password" checkbox and the passphrase will be securely stored in the KDE Wallet and automatically retrieved across session restarts.

See also