# How to Set up a Fresh Ubuntu Server, Add Non-Root User, SSH Key, and UFW Firewall

When deploying a new Ubuntu server for the first time, default access is provided through the root account. While the root user has full privileges to manage the system, it is not recommended to use this account for daily operations due to security risks. The best practice is to immediately update the system and create a new user with sudo access, and grant it administrative privileges.
As a best practice to further enhance security, the user should enable login using SSH key authentication as a secure alternative to password-based access. 
Finally, configure a firewall to help control incoming and outgoing traffic based on predefined rules. This will limit exposure to unauthorized access. On Ubuntu systems, it is recommended to use Uncomplicated Firewall (UFW), which offers a simple, effective interface for managing iptables.
The following steps will guide you through the full process, including commands and visual examples.

## Instructions to Set up a Fresh Ubuntu Server
### Step 1: Update the System and Create a New Administrative User
1. Connect to your server using SSH.
   
   Begin by connecting to your server from your local machine using SSH. This will require the servers public IP address and the root user credentials provided in your Cherry Servers client portal. Use the following command to connect:
   ```bash command
   ssh root@your_server_ip
   ```
   Replace "your_server_ip" with the actual IP address of your Ubuntu server.    You will be prompted to accept the host key and enter the root password or use your private key if it has already been configured.
   ```bash output
   ➜ ssh root@93.115.25.160
   The authenticity of host '93.115.25.160 (93.115.25.160)' can't be established.
   ED25519 key fingerprint is    SHA256:qS+6coAg8JUBSvoh2NhFcW2Ydq3soWnZfVswNdNq6wOQ.
   This key is not known by any other names
   Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
   Warning: Permanently added '93.115.25.160' (ED25519) to the list of known hosts.
   ```
   
   If you are unfamiliar with SSH access or encounter problems such as authentication issues or timeouts, we recommend reviewing the following Cherry
   Servers documentation for detailed instructions:
   
   - [How to connect to a Linux server using SSH](https://www.cherryservers.com/knowledge/docs/compute/how-to/connect-with-ssh-linux)
   - [How to connect to your server and troubleshoot access issues](https://www.cherryservers.com/knowledge/docs/getting-started/connect-to-your-server)
   
2. Update and upgrade the system.
	
   Once connected to the server, the first thing you should do is update the package index and upgrade the system packages. This ensures that all installed software is up to date and includes the latest security patches. Run the following command:
   ```bash command
   sudo apt update && apt upgrade -y
   ```
   - *"apt update"* fetches the latest list of available packages and versions;
   - *"apt upgrade -y"* installs the updated versions for all currently installed packages without requiring manual confirmation (-y flag).
   
3. Create a new non-root user.

   Instead of continuing to operate as root, it is best to create a separate user account. This helps isolate critical system commands from daily use and enables better auditing and access control. To create a new user, run:
   ```bash command
   adduser cherry
   ```
   Replace "cherry" with the name you want for your administrative user. The system will prompt you to create a password and optionally provide additional user information such as full name or contact details. These can be left blank if desired. Note that this user does not have administrative privileges yet.
   ```bash output
   root@expert-lab:~# adduser cherry
   info: Adding user `cherry' ...
   info: Selecting UID/GID from range 1000 to 59999 ...
   info: Adding new group `cherry' (1001) ...
   info: Adding new user `cherry' (1001) with group `cherry (1001)' ...
   info: Creating home directory `/home/cherry' ...
   info: Copying files from `/etc/skel' ...
   New password:
   Retype new password:
   passwd: password updated successfully
   Changing the user information for cherry
   Enter the new value, or press ENTER for the default
        Full Name []:
        Room Number []:
        Work Phone []:
        Home Phone []:
        Other []:
   Is the information correct? [Y/n] Y
   info: Adding new user `cherry' to supplemental / extra groups `users' ...
   info: Adding user `cherry' to group `users' ...
   ```
   
4. Grant administrative privileges to the new user. 

   To give the newly created user permission to run administrative commands (such as *apt*, *reboot*, or system configuration tools), you must add them to the *sudo* group:
   ``` bash command
   usermod -aG sudo cherry
   ```
   - *usermod*  -  modifies user account settings.
   - *-aG*  -  appends the user to a group (without removing them from other groups).
   - *sudo*  -  the group that grants administrative privileges.

   This command ensures the user is added to the systems list of users allowed to elevate their privileges using the sudo command. These elevated commands will still require the user’s password to execute, providing a layer of accountability and control.
   
5. Verify the group membership. 

   To confirm that the user was successfully added to the *sudo* group, use the *groups* command:
   ```bash command
   groups cherry
   ```
   You should see output similar to:
   ```bash output
   root@expert-lab:~# groups cherry
   cherry : cherry sudo users
   ```
   New group membership will take effect upon the user's next login. If you are currently logged in as the new user in a separate session, log out and log back in to gain *sudo* privileges.

### Step 2: Set up SSH Key Based Authentication for the New User
After creating a new user with administrative privileges, the next step is to enable secure, password less login using SSH key authentication. This is a more secure alternative to password-based access and is considered a best practice for managing remote servers.

It is recommended to keep your current SSH session open until you confirm that your new user can log in and access the server. This prevents accidental lockout.

1. Copy your public SSH key to the new user. There are two ways to do this:

    **Option A**: use *rsync* (recommended when logged in as *root*):

   If your public key is already installed for the *root* user, you can simply copy it to the new user's home directory so that you can log in without entering a password every time. Run the following command as *root* to copy the SSH configuration from the root account to your new user (replace cherry with your actual username):
   ```bash command
   rsync --archive --chown=cherry:cherry ~/.ssh /home/cherry
   ```
   This command does the following: 
   - *rsync --archive* preserves file permissions and timestamps during the copy;
   - *--chown=cherry:cherry* changes the ownership of the *.ssh* directory and its contents to the new user.
   - *~/.ssh* is the source directory from the root account;
   - */home/cherry* is the target location for the new user.

   **Option B**: Use *ssh-copy-id* (simpler method from your local machine).

   If your public key is on your local system, you can directly copy it to the new user using this command (this method requires that password based login is temporarily allowed on the server.):
   ``` bash command
   ssh-copy-id cherry@your_server_ip
   ```
   This command will:
   - Connect to the server via SSH.
   - Append your local public key (usually *~/.ssh/id_rsa.pub*) to the remote user's *~/.ssh/authorized_keys* file.
   - Prompt for the password once and then enable key-based login going forward.

2. Once completed, the new user will be able to log in using the same SSH private key used for the root account. 

	If you have not done so yet, please view our dedicated guide to [generate and add an SSH key to the Cherry Servers client portal](https://www.cherryservers.com/knowledge/docs/compute/how-to/generate-and-add-ssh-keys).
3. Test the login with your new user.

   Now that the key has been copied, test logging in as the new user from your local machine:
   ```bash command
   ssh cherry@your_server_ip
   ```
  Replace "cherry" with your chosen username and *"your_server_ip"* with your server's actual public IP address. If everything was configured correctly, you should be able to log in without being prompted for a password.

### Step 3: Set up a Basic Firewall with UFW
Configuring a basic firewall with UFW helps restrict access to essential services, like SSH, and adds an extra layer of protection.  This firewall set up example is for Uncomplicated Firewall (UFW). UFW is not required for your server to function, but it is considered a best practice and essential for reducing the attack surface, especially on public facing servers.
1. Check if UFW is installed.
   
   Most modern Ubuntu installations come with UFW preinstalled. You can check if it is present by running:
   ```bash command
   sudo ufw status
   ```
   If the output is something like *"Status: inactive"*, UFW is installed but not yet enabled. If the command is not recognized, install it with:
   ```bash command
   sudo apt install ufw -y
   ```
   ```bash output
   root@expert-lab:~# sudo ufw status
   Status: inactive
   ```
2. Allow essential services.

   Before enabling the firewall, you need to explicitly allow any services that should n accessible. Since you are working via SSH, you must permit SSH traffic on the port you are using (default is port 22 unless you have configured a custom port):
    ```bash command
    sudo ufw allow OpenSSH
    ```
    Alternatively, if your SSH service is running on a non default port (e.g., 2222), you should allow that port directly:
   ```bash command
   sudo ufw allow 2222/tcp
   ```
  	Only after allowing SSH should you proceed to enable UFW, otherwise, you may lock yourself out.
   
3. Enable the firewall.
 
   To activate UFW and enforce the rules, run:
   ```bash command
   sudo ufw enable
   ```
   You will be prompted to confirm. Type *"y"* and press Enter. Once enabled, UFW will automatically apply on every reboot.
   ```bash output
   root@expert-lab:~# sudo ufw enable
   Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
   Firewall is active and enabled on system startup
   ```
4. Verify firewall status and rules.
  
   To confirm UFW is active and verify which rules are in place, use:
   ```bash command
   sudo ufw status verbose
   ```
   You should see output listing the allowed ports, such as:
   ```bash output
   root@expert-lab:~# sudo ufw status verbose
   Status: active
   Logging: on (low)
   Default: deny (incoming), allow (outgoing), disabled (routed)
   New profiles: skip
   
   To                         Action      From
   --                         ------      ----
   22/tcp (OpenSSH)           ALLOW IN    Anywhere
   22/tcp (OpenSSH (v6))      ALLOW IN    Anywhere (v6)
   ```
   This confirms that your firewall is active and permitting SSH access.
    
5. Additional recommendations.
- To allow other services in the future (e.g., HTTP, HTTPS), you can run:
```bash command
sudo ufw allow http
```
- If you want to disable UFW temporarily you can run:
```bash command
sudo ufw disable
```
- You can reset UFW to its default state with:
```bash command
sudo ufw reset
```
### OPTIONAL - Step 4: Disable Root Login via SSH
For enhanced security, it is highly recommended to disable direct SSH login as the root user once your new user has administrative privileges and SSH key access. This prevents attackers from targeting the default root account, which is a common target of brute force attempts.
1. Open the SSH daemon configuration file.

   Use a text editor like *nano* to open the SSH configuration:
   ```bash command
   sudo nano /etc/ssh/sshd_config
   ```
   Locate the following line. This is usually near the bottom):
   ```text
   PermitRootLogin yes
   ```
   Change its value to
   ```text
   PermitRootLogin no
   ```
   This change ensures that no one, not even with the correct password or SSH key, can log in as *root* over SSH. If you need to perform administrative tasks, you can do so using *sudo* from your non root account.

2. Restart the SSH service.

   For the changes to take effect, restart the SSH daemon:
   ```bash command
   sudo systemctl restart ssh
   ```
3. Confirm the configuration was applied.

   You can verify that the SSH daemon has the setting active using the following command:
   ```bash command
   sudo sshd -T | grep permitrootlogin
   ```
   The output should show:
   ```bash output
   permitrootlogin no
   ```
This confirms that the SSH server is enforcing the new restriction and will no longer accept root logins.

These initial setup steps are recommended for any production server and form a reliable baseline for deploying software stacks like LAMP, Docker, or Kubernetes. With this groundwork in place, your Ubuntu server is now secure, maintainable, and ready for future deployment tasks.