SSH public key authentication: Difference between revisions

From NixOS Wiki
imported>Milahu
remove unnecessary server config
m typo
 
(9 intermediate revisions by 6 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>


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.
Now the public key is stored on the <code>another-machine</code> in <code>/home/user/.ssh/authorized_keys</code>


Now we must tell the SSH client to send the public key:
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">
<syntaxhighlight lang="console">
[user@clientmachine] $ ssh -i ~/.ssh/servermachine servermachine
[user@clientmachine] $ ssh -i ~/.ssh/another-machine another-machine-host-or-ip
</syntaxhighlight>
</syntaxhighlight>


The connection should work without password.
The connection should work without password.


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


<syntaxhighlight>
<syntaxhighlight>
Host servermachine
Host another-machine
   HostName 192.168.1.105
   HostName 192.168.1.105 # another-machine-host-or-ip
   #Port 22
   #Port 22
   #User user
   #User user
Line 28: Line 31:
   # Prevent using ssh-agent or another keyfile, useful for testing
   # Prevent using ssh-agent or another keyfile, useful for testing
   IdentitiesOnly yes
   IdentitiesOnly yes
   IdentityFile ~/.ssh/servermachine
   IdentityFile ~/.ssh/another-machine
</syntaxhighlight>
</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">
programs.ssh.startAgent = true;
</syntaxhighlight>
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>.
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">
[user@your-machine] $ ssh-add .ssh/id_rsa
Enter passphrase for .ssh/id_rsa:
Identity added: .ssh/id_rsa (myaccounts@mymachine)
</syntaxhighlight>
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 ==
== SSH server config ==


Optionally, on the <code>servermachine</code>, we can set <code>passwordAuthentication = false;</code> to require public key authentication, usually for better security.
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">
<syntaxhighlight lang="nix">
services.openssh = {
services.openssh = {
   enable = true;
   enable = true;
# passwordAuthentication = false; # default true
  # require public key authentication for better security
# permitRootLogin = "yes";
  settings.PasswordAuthentication = false;
#  challengeResponseAuthentication = false;
  settings.KbdInteractiveAuthentication = false;
  #settings.PermitRootLogin = "yes";
};
};
</syntaxhighlight>
</syntaxhighlight>
Line 49: 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>

Latest revision as of 21:26, 25 July 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
];

See also