server-fist-steps
Trying to remember what to do first on a new linux server
Introduction
I host some stuff on a server, and I am trying to do a better job of it by using Ansible to maintain things; however, even before I can use Ansible on a new sever, there are a few first steps I need to do…
Unfortunately, I can never remember what they are, so I am documenting them for me and anyone else that happens to find this page.
Creating a user
Through my cloud provider, I created an Ubuntu server with a static IP address and root user.
Log in via ssh
using the command:
Once logged in, create a new user using the interactive adduser
command:
This should prompt you to add a password and optional information to your user.
Next we add the user (admin
in this case) to the
sudo
group, so the user has
administrative privileges:
Generating an SSH Key
If you do not already have an ssh
key,
generate one using:
It will ask for a file name; it will generate a public key file like this one:
Do not share the private key!
Add SSH key to your server
Now we need to copy the public key to the user we intend to log in as on the server.
Luckily, ssh-copy-id
can help us with this process. For example:
According to the manual, ssh-copy-id
will attempt to log into the server
with each provided key, and if it fails, will log in at the end and add each
public key that failed to the user's authorized_keys
file.
Keys in the authorized_keys
file can bypass password authentication. As
long as the private key stays private, this is more secure than password
authentication as only people in possession of the key can log in. This means
nobody can try to guess the password of your user and use it to log in.
-i identity_file
- The path to the SSH key we want to add to the host. By default, generated keys
get placed in
~/.ssh
, but if you gave a custom file-path when you invokedssh-keygen
, use that path instead. -n
- Don't actually install the keys, just list which keys would be installed. Add this argument if you just want to try out the command without changing anything.
admin@10.10.10.10
- Instead of
admin
, use the name of the user you created earlier, and instead of10.10.10.10
, use the IP of your server.
Log back into the server
Log into the server using your new ssh
key like so:
You should be able to log in with no password.
SSH Config
Finally, we can make some basic no-brainer SSH config changes.
First, disable password and root login now that our SSH keys are configured:
Change the port sshd
uses:
Verify the sshd_config
works using sshd -t
.
And restart the sshd
service.
Sidequest: Secure passwordless sudo
Using a PAM, one can
configure the server to use the SSH key authentication agent for sudo
permissions instead of a password.
PAM
— Pluggable Authentication Modules- Linux system that allows for custom password management, such as using hardware tokens or one-time-passwords for user login.
We can use the pam_ssh_agent_auth
module to allow using ssh as the auth
module for sudo
(or several other systems which use PAM).
However, I gather that setting this up requires compiling code and doing some
gnarly config. My server does not have a pam_ssh_agent_auth.so
(or similarly
named) file. I'd also need to edit some gnarly config files, so best left as a
future exercise.
Troubleshooting SSH Host Keys
As some troubleshooting, if the host is missing SSH host keys, ssh-keygen
can
do this easily like so:
- -A
- From the manual page:
Generate host keys of all default key types (
rsa
,ecdsa
, anded25519
) if they do not already exist. The host keys are generated with the default key file path, an empty passphrase, default bits for the key type, and default comment. If -f has also been specified, its argument is used as a prefix to the default path for the resulting host key files. This is used by system administration scripts to generate new host keys.
As far as I can tell, this should only be the case if something is going wrong.
If using the Ansible playbook provided in Jeff Geerling's book on Ansible, be
sure to add
. This is because the host keys require root
permissions to read! Also, run the playbook with become: yes
-K
if passwordless sudo
is
not set up.
1 ---
2 - hosts: hosts # replace with your host name
3 handlers:
4 - name: restart ssh
5 service: name=ssh state=restarted
6 tasks:
7 - name: Update SSH Configuration
8 become: yes
9 lineinfile:
10 dest: /etc/ssh/sshd_config
11 regexp: "{{ item.regexp }}"
12 line: "{{ item.line }}"
13 state: present
14 validate: 'sshd -t -f %s'
15 with_items:
16 - regexp: "^PasswordAuthentication"
17 line: "PasswordAuthentication no"
18 - regexp: "^PermitRootLogin"
19 line: "PermitRootLogin no"
20 - regexp: "^Port"
21 line: "Port 4761" # use a different port!!!
22 notify: restart ssh
Be sure to update the port to match in your hosts file.