Updated guide to ed25519, Debian 11 and nftables

This commit is contained in:
Sun Knudsen 2022-01-08 07:42:53 -05:00
parent 9db6a0ffbf
commit 81e2853f89
No known key found for this signature in database
GPG Key ID: 02C43AD072D57783

View File

@ -36,33 +36,33 @@ $ mkdir ~/.ssh
$ cd ~/.ssh $ cd ~/.ssh
$ ssh-keygen -t rsa -C "pi" $ ssh-keygen -t ed25519 -C "pi"
Generating public/private rsa key pair. Generating public/private ed25519 key pair.
Enter file in which to save the key (/Users/sunknudsen/.ssh/id_rsa): pi Enter file in which to save the key (/Users/sunknudsen/.ssh/id_ed25519): pi
Enter passphrase (empty for no passphrase): Enter passphrase (empty for no passphrase):
Enter same passphrase again: Enter same passphrase again:
Your identification has been saved in pi. Your identification has been saved in pi.
Your public key has been saved in pi.pub. Your public key has been saved in pi.pub.
The key fingerprint is: The key fingerprint is:
SHA256:NZkr0Bmu6tpQfDp2GHTIPyBz253uZk/gOmoqzEszGM0 pi SHA256:U3hEUQC0GAyCOPaks1Xv04ouoN9ezwtfK4CnUxKqAms pi
The key's randomart image is: The key's randomart image is:
+---[RSA 3072]----+ +--[ED25519 256]--+
| . | |... .o..oo=+. |
| . . o o o | |+. o ..o + |
| o * o + = | |..+ . o o o |
| o * * + o o | | o o. . o |
|. E = * S . | | +. o. S |
|.. . * + o | |.o. o +o o |
|++. * . o . | |oo. =+.o . |
|ooo=.o.oo. | |=E ooo *.. . |
| o+++..+... | |o...=o =o. |
+----[SHA256]-----+ +----[SHA256]-----+
$ cat pi.pub $ cat pi.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDCzQpX9uqDP8L2gSZNJxYEi04Y1pZWz28v4zANY5dU6M35OFzXZcRcBqi2ZxiQofgxRrX9QlAcmcPFz8/CkpPw2WgQTflm+46ZrVEZcwwGwJsJwm7QVLQLd44/xtejEvMjzsuYDjJ1q4WhEvMSleTfOrix4yP0mjn83Zk1l6AMxR5J8DDumiHsGSYfcp+1XS9x4r4HP0mS2RpIy3rcoxLoJaYEKvVTj9qdvPMK7SDymZcvuBsgObEARVr77q4qhUfTP+xR91hHNEYD9FnCHF3qQBzlTlmTwpwhH6vOdWE3uUXCug9Ugw42Zj3PW0zd5rQ7EEpD9SDLbUqajpn2M5AlhkS9OrLpnIptocetRKNI9HzyAV1KqdNiQeL7/59d4y+HuZ9y032SaNzR1fw0nYMoHzTN9d+zPvziDZ183/pwtEXZNVVGzYO1r56n3S4vLx8YCpYqiHYVQVDF8aweoHYs3dAGAfPxmQ85+45UKpFR18XSGCqCO2fwbyTGDhkxCzU= pi ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHLwQ2fk5VvoKJ6PNdJfmtum6fTAIn7xG5vbFm0YjEGY pi
``` ```
### Step 2: generate heredoc (the output of following command will be used at [step 10](#step-10-configure-pi-ssh-authorized-keys)) ### Step 2: generate heredoc (the output of following command will be used at [step 11](#step-11-configure-pi-ssh-authorized-keys))
```shell ```shell
cat << EOF cat << EOF
@ -78,47 +78,48 @@ EOF
> WARNING: DO NOT RUN THE FOLLOWING COMMANDS AS-IS. > WARNING: DO NOT RUN THE FOLLOWING COMMANDS AS-IS.
Run `diskutil list` to find disk ID of SD card to overwrite with “Raspberry Pi OS Lite” (`disk2` in the following example). Run `diskutil list` to find disk ID of SD card to overwrite with “Raspberry Pi OS Lite” (`disk4` in the following example).
Replace `diskn` and `rdiskn` with disk ID of SD card (`disk2` and `rdisk2` in the following example) and `2021-03-04-raspios-buster-armhf-lite.img` with current image. Replace `diskn` and `rdiskn` with disk ID of SD card (`disk4` and `rdisk4` in the following example) and `2021-10-30-raspios-bullseye-armhf-lite.img` with current image.
```console ```console
$ diskutil list $ diskutil list
/dev/disk0 (internal, physical): /dev/disk0 (internal):
#: TYPE NAME SIZE IDENTIFIER #: TYPE NAME SIZE IDENTIFIER
0: GUID_partition_scheme *500.3 GB disk0 0: GUID_partition_scheme 500.3 GB disk0
1: EFI EFI 209.7 MB disk0s1 1: Apple_APFS_ISC 524.3 MB disk0s1
2: Apple_APFS Container disk1 500.1 GB disk0s2 2: Apple_APFS Container disk3 494.4 GB disk0s2
3: Apple_APFS_Recovery 5.4 GB disk0s3
/dev/disk1 (synthesized): /dev/disk3 (synthesized):
#: TYPE NAME SIZE IDENTIFIER #: TYPE NAME SIZE IDENTIFIER
0: APFS Container Scheme - +500.1 GB disk1 0: APFS Container Scheme - +494.4 GB disk3
Physical Store disk0s2 Physical Store disk0s2
1: APFS Volume Macintosh HD - Data 340.9 GB disk1s1 1: APFS Volume Macintosh HD 15.3 GB disk3s1
2: APFS Volume Preboot 85.9 MB disk1s2 2: APFS Snapshot com.apple.os.update-... 15.3 GB disk3s1s1
3: APFS Volume Recovery 529.0 MB disk1s3 3: APFS Volume Preboot 328.4 MB disk3s2
4: APFS Volume VM 3.2 GB disk1s4 4: APFS Volume Recovery 815.1 MB disk3s3
5: APFS Volume Macintosh HD 11.3 GB disk1s5 5: APFS Volume Data 458.6 GB disk3s5
6: APFS Volume VM 2.1 GB disk3s6
/dev/disk2 (internal, physical): /dev/disk4 (external, physical):
#: TYPE NAME SIZE IDENTIFIER #: TYPE NAME SIZE IDENTIFIER
0: FDisk_partition_scheme *15.9 GB disk2 0: FDisk_partition_scheme *15.9 GB disk4
1: Windows_FAT_32 boot 268.4 MB disk2s1 1: Windows_NTFS Untitled 15.9 GB disk4s1
2: Linux 15.7 GB disk2s2
$ sudo diskutil unmount /dev/diskn $ sudo diskutil unmount /dev/diskn
disk2 was already unmounted or it has a partitioning scheme so use "diskutil unmountDisk" instead disk4 was already unmounted or it has a partitioning scheme so use "diskutil unmountDisk" instead
$ sudo diskutil unmountDisk /dev/diskn (if previous step fails) $ sudo diskutil unmountDisk /dev/diskn (if previous step fails)
Unmount of all volumes on disk2 was successful Unmount of all volumes on disk4 was successful
$ sudo dd bs=1m if=$HOME/Downloads/2021-03-04-raspios-buster-armhf-lite.img of=/dev/rdiskn $ sudo dd bs=1m if=$HOME/Downloads/2021-10-30-raspios-bullseye-armhf-lite.img of=/dev/rdiskn
1772+0 records in 1864+0 records in
1772+0 records out 1864+0 records out
1858076672 bytes transferred in 40.449002 secs (45936280 bytes/sec) 1954545664 bytes transferred in 37.454965 secs (52183887 bytes/sec)
$ sudo diskutil unmountDisk /dev/diskn $ sudo diskutil unmountDisk /dev/diskn
Unmount of all volumes on disk2 was successful Unmount of all volumes on disk4 was successful
``` ```
### Step 5: log in as pi (using keyboard) and change password using `passwd` ### Step 5: log in as pi (using keyboard) and change password using `passwd`
@ -160,47 +161,15 @@ ip a
### Step 9: log in to Raspberry Pi over SSH ### Step 9: log in to Raspberry Pi over SSH
Replace `10.0.1.248` with IP of Raspberry Pi. Replace `10.0.1.181` with IP of Raspberry Pi.
When asked for passphrase, enter passphrase from [step 5](#step-5-log-in-as-pi-using-keyboard-and-change-password-using-passwd). When asked for passphrase, enter passphrase from [step 5](#step-5-log-in-as-pi-using-keyboard-and-change-password-using-passwd).
```shell ```shell
ssh pi@10.0.1.248 ssh pi@10.0.1.181
``` ```
### Step 10: configure pi SSH authorized keys ### Step 10: disable pi Bash history
#### Create `.ssh` directory
```shell
mkdir ~/.ssh
```
#### Create `~/.ssh/authorized_keys` using heredoc generated at [step 2](#step-2-generate-heredoc-the-output-of-following-command-will-be-used-at-step-10)
```shell
cat << "_EOF" > ~/.ssh/authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDCzQpX9uqDP8L2gSZNJxYEi04Y1pZWz28v4zANY5dU6M35OFzXZcRcBqi2ZxiQofgxRrX9QlAcmcPFz8/CkpPw2WgQTflm+46ZrVEZcwwGwJsJwm7QVLQLd44/xtejEvMjzsuYDjJ1q4WhEvMSleTfOrix4yP0mjn83Zk1l6AMxR5J8DDumiHsGSYfcp+1XS9x4r4HP0mS2RpIy3rcoxLoJaYEKvVTj9qdvPMK7SDymZcvuBsgObEARVr77q4qhUfTP+xR91hHNEYD9FnCHF3qQBzlTlmTwpwhH6vOdWE3uUXCug9Ugw42Zj3PW0zd5rQ7EEpD9SDLbUqajpn2M5AlhkS9OrLpnIptocetRKNI9HzyAV1KqdNiQeL7/59d4y+HuZ9y032SaNzR1fw0nYMoHzTN9d+zPvziDZ183/pwtEXZNVVGzYO1r56n3S4vLx8YCpYqiHYVQVDF8aweoHYs3dAGAfPxmQ85+45UKpFR18XSGCqCO2fwbyTGDhkxCzU= pi
_EOF
```
### Step 11: log out
```shell
exit
```
### Step 12: log in
Replace `10.0.1.248` with IP of Raspberry Pi.
When asked for passphrase, enter passphrase from [step 1](#step-1-create-ssh-key-pair-on-macos).
```shell
ssh pi@10.0.1.248 -i ~/.ssh/pi
```
### Step 13: disable pi Bash history
```shell ```shell
sed -i -E 's/^HISTSIZE=/#HISTSIZE=/' ~/.bashrc sed -i -E 's/^HISTSIZE=/#HISTSIZE=/' ~/.bashrc
@ -210,46 +179,59 @@ history -c; history -w
source ~/.bashrc source ~/.bashrc
``` ```
### Step 14: configure pi `.vimrc` ### Step 11: configure pi SSH authorized keys
#### Create `.ssh` directory
```shell ```shell
cat << "EOF" > ~/.vimrc mkdir ~/.ssh
set encoding=UTF-8
set termencoding=UTF-8
set nocompatible
set backspace=indent,eol,start
set autoindent
set tabstop=2
set shiftwidth=2
set expandtab
set smarttab
set ruler
set paste
syntax on
EOF
``` ```
### Step 15: switch to root #### Create `~/.ssh/authorized_keys` using heredoc generated at [step 2](#step-2-generate-heredoc-the-output-of-following-command-will-be-used-at-step-11)
```shell
cat << "_EOF" > ~/.ssh/authorized_keys
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHLwQ2fk5VvoKJ6PNdJfmtum6fTAIn7xG5vbFm0YjEGY pi
_EOF
```
### Step 12: log out
```shell
exit
```
### Step 13: log in
Replace `10.0.1.181` with IP of Raspberry Pi.
When asked for passphrase, enter passphrase from [step 1](#step-1-create-ssh-key-pair-on-macos).
```shell
ssh pi@10.0.1.181 -i ~/.ssh/pi
```
### Step 14: switch to root
```shell ```shell
sudo su - sudo su -
``` ```
### Step 15: disable root Bash history
```shell
echo "HISTFILESIZE=0" >> ~/.bashrc
history -c; history -w
source ~/.bashrc
```
### Step 16: disable pi sudo `nopassword` “feature” ### Step 16: disable pi sudo `nopassword` “feature”
```shell ```shell
rm /etc/sudoers.d/010_* rm /etc/sudoers.d/010_*
``` ```
### Step 17: disable root Bash history ### Step 17: set root password
```shell
echo "HISTFILESIZE=0" >> ~/.bashrc
history -c; history -w
source ~/.bashrc
```
### Step 18: set root password
When asked for password, use output from `openssl rand -base64 24` (and store password in password manager). When asked for password, use output from `openssl rand -base64 24` (and store password in password manager).
@ -260,26 +242,7 @@ Retype new password:
passwd: password updated successfully passwd: password updated successfully
``` ```
### Step 19: configure root `.vimrc` ### Step 18: disable root login and password authentication
```shell
cat << "EOF" > ~/.vimrc
set encoding=UTF-8
set termencoding=UTF-8
set nocompatible
set backspace=indent,eol,start
set autoindent
set tabstop=2
set shiftwidth=2
set expandtab
set smarttab
set ruler
set paste
syntax on
EOF
```
### Step 20: disable root login and password authentication
```shell ```shell
sed -i -E 's/^(#)?PermitRootLogin (prohibit-password|yes)/PermitRootLogin no/' /etc/ssh/sshd_config sed -i -E 's/^(#)?PermitRootLogin (prohibit-password|yes)/PermitRootLogin no/' /etc/ssh/sshd_config
@ -287,9 +250,9 @@ sed -i -E 's/^(#)?PasswordAuthentication yes/PasswordAuthentication no/' /etc/ss
systemctl restart ssh systemctl restart ssh
``` ```
### Step 21: disable Bluetooth and Wi-Fi ### Step 19: disable Bluetooth and Wi-Fi
> Heads-up: will take effect after reboot. > Heads-up: step will take effect after reboot.
#### Disable Bluetooth #### Disable Bluetooth
@ -303,63 +266,9 @@ echo "dtoverlay=disable-bt" >> /boot/config.txt
echo "dtoverlay=disable-wifi" >> /boot/config.txt echo "dtoverlay=disable-wifi" >> /boot/config.txt
``` ```
### Step 22: update APT index, install `iptables-persistent` and Vim and upgrade system ### Step 20: configure sysctl (if network is IPv4-only)
#### Update APT index > Heads-up: only run following if network is IPv4-only.
```shell
apt update
```
#### Install `iptables-persistent` and Vim
When asked to save current IPv4 or IPv6 rules, answer “Yes”.
```shell
apt install -y iptables-persistent vim
```
#### Upgrade packages
> Heads-up: if asked which version of `/etc/ssh/sshd_config` to keep, select “keep the local version currently installed”.
```shell
apt upgrade -y
```
### Step 23: reboot
```shell
systemctl reboot
```
### Step 24: log in
Replace `10.0.1.248` with IP of Raspberry Pi.
When asked for passphrase, enter passphrase from [step 1](#step-1-create-ssh-key-pair-on-macos).
```shell
ssh pi@10.0.1.248 -i ~/.ssh/pi
```
### Step 25: switch to root
```shell
sudo su -
```
### Step 26: set timezone (the following is for Montreal time)
See https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
```shell
timedatectl set-timezone America/Montreal
```
### Step 27: configure sysctl (if network is IPv4-only)
> Heads-up: only run the following if network is IPv4-only.
```shell ```shell
cp /etc/sysctl.conf /etc/sysctl.conf.backup cp /etc/sysctl.conf /etc/sysctl.conf.backup
@ -371,70 +280,64 @@ EOF
sysctl -p sysctl -p
``` ```
### Step 28: configure firewall ### Step 21: enable nftables and configure firewall rules
#### Enable nftables
```shell ```shell
iptables -N SSH_BRUTE_FORCE_MITIGATION systemctl enable nftables
iptables -A SSH_BRUTE_FORCE_MITIGATION -m recent --name SSH --set systemctl start nftables
iptables -A SSH_BRUTE_FORCE_MITIGATION -m recent --name SSH --update --seconds 300 --hitcount 10 -m limit --limit 1/second --limit-burst 100 -j LOG --log-prefix "iptables[ssh-brute-force]: " ```
iptables -A SSH_BRUTE_FORCE_MITIGATION -m recent --name SSH --update --seconds 300 --hitcount 10 -j DROP
iptables -A SSH_BRUTE_FORCE_MITIGATION -j ACCEPT #### Configure firewall rules
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -p tcp --dport 22 --syn -m conntrack --ctstate NEW -j SSH_BRUTE_FORCE_MITIGATION ```shell
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT nft flush ruleset
iptables -A OUTPUT -o lo -j ACCEPT nft add table ip firewall
iptables -A OUTPUT -p tcp --dport 53 -m state --state NEW -j ACCEPT nft add chain ip firewall input { type filter hook input priority 0 \; policy drop \; }
iptables -A OUTPUT -p udp --dport 53 -m state --state NEW -j ACCEPT nft add rule ip firewall input iif lo accept
iptables -A OUTPUT -p tcp --dport 80 -m state --state NEW -j ACCEPT nft add rule ip firewall input iif != lo ip daddr 127.0.0.0/8 drop
iptables -A OUTPUT -p udp --dport 123 -m state --state NEW -j ACCEPT nft add rule ip firewall input tcp dport ssh accept
iptables -A OUTPUT -p tcp --dport 443 -m state --state NEW -j ACCEPT nft add rule ip firewall input ct state established,related accept
iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT nft add chain ip firewall forward { type filter hook forward priority 0 \; policy drop \; }
iptables -P FORWARD DROP nft add chain ip firewall output { type filter hook output priority 0 \; policy drop \; }
iptables -P INPUT DROP nft add rule ip firewall output oif lo accept
iptables -P OUTPUT DROP nft add rule ip firewall output tcp dport { http, https } accept
nft add rule ip firewall output udp dport { domain, ntp } accept
nft add rule ip firewall output ct state established,related accept
``` ```
If network is IPv4-only, run: If network is IPv4-only, run:
```shell ```shell
ip6tables -P FORWARD DROP nft add table ip6 firewall
ip6tables -P INPUT DROP nft add chain ip6 firewall input { type filter hook input priority 0 \; policy drop \; }
ip6tables -P OUTPUT DROP nft add chain ip6 firewall forward { type filter hook forward priority 0 \; policy drop \; }
nft add chain ip6 firewall output { type filter hook output priority 0 \; policy drop \; }
``` ```
If network is dual stack (IPv4 + IPv6) run: If network is dual stack (IPv4 + IPv6) run:
```shell ```shell
ip6tables -A INPUT -i lo -j ACCEPT nft add table ip6 firewall
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type destination-unreachable -j ACCEPT nft add chain ip6 firewall input { type filter hook input priority 0\; policy drop\; }
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type packet-too-big -j ACCEPT nft add rule ip6 firewall input iif lo accept
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type time-exceeded -j ACCEPT nft add rule ip6 firewall input iif != lo ip6 daddr ::1 drop
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type parameter-problem -j ACCEPT nft add rule ip6 firewall input meta l4proto ipv6-icmp icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem } accept
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type router-advertisement -m hl --hl-eq 255 -j ACCEPT nft add rule ip6 firewall input meta l4proto ipv6-icmp icmpv6 type { nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert, nd-redirect } ip6 hoplimit 255 accept
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type neighbor-solicitation -m hl --hl-eq 255 -j ACCEPT nft add rule ip6 firewall input tcp dport ssh accept
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type neighbor-advertisement -m hl --hl-eq 255 -j ACCEPT nft add rule ip6 firewall input ct state established,related accept
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type redirect -m hl --hl-eq 255 -j ACCEPT nft add chain ip6 firewall forward { type filter hook forward priority 0\; policy drop\; }
ip6tables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT nft add chain ip6 firewall output { type filter hook output priority 0\; policy drop\; }
ip6tables -A OUTPUT -o lo -j ACCEPT nft add rule ip6 firewall output oif lo accept
ip6tables -A OUTPUT -p ipv6-icmp --icmpv6-type destination-unreachable -j ACCEPT nft add rule ip6 firewall output meta l4proto ipv6-icmp icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem } accept
ip6tables -A OUTPUT -p ipv6-icmp --icmpv6-type packet-too-big -j ACCEPT nft add rule ip6 firewall output meta l4proto ipv6-icmp icmpv6 type { nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert } ip6 hoplimit 255 accept
ip6tables -A OUTPUT -p ipv6-icmp --icmpv6-type time-exceeded -j ACCEPT nft add rule ip6 firewall output tcp dport { http, https } accept
ip6tables -A OUTPUT -p ipv6-icmp --icmpv6-type parameter-problem -j ACCEPT nft add rule ip6 firewall output udp dport { domain, ntp } accept
ip6tables -A OUTPUT -p ipv6-icmp --icmpv6-type router-solicitation -m hl --hl-eq 255 -j ACCEPT nft add rule ip6 firewall output ct state related,established accept
ip6tables -A OUTPUT -p ipv6-icmp --icmpv6-type neighbour-solicitation -m hl --hl-eq 255 -j ACCEPT
ip6tables -A OUTPUT -p ipv6-icmp --icmpv6-type neighbour-advertisement -m hl --hl-eq 255 -j ACCEPT
ip6tables -A OUTPUT -p tcp --dport 53 -m state --state NEW -j ACCEPT
ip6tables -A OUTPUT -p udp --dport 53 -m state --state NEW -j ACCEPT
ip6tables -A OUTPUT -p tcp --dport 80 -m state --state NEW -j ACCEPT
ip6tables -A OUTPUT -p udp --dport 123 -m state --state NEW -j ACCEPT
ip6tables -A OUTPUT -p tcp --dport 443 -m state --state NEW -j ACCEPT
ip6tables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
ip6tables -P FORWARD DROP
ip6tables -P INPUT DROP
ip6tables -P OUTPUT DROP
``` ```
### Step 29: log out and log in to confirm firewall didnt block SSH ### Step 22: log out and log in to confirm firewall is not blocking SSH
#### Log out #### Log out
@ -445,23 +348,59 @@ exit
#### Log in #### Log in
Replace `10.0.1.248` with IP of Raspberry Pi. Replace `10.0.1.181` with IP of Raspberry Pi.
```shell ```shell
ssh pi@10.0.1.248 -i ~/.ssh/pi ssh pi@10.0.1.181 -i ~/.ssh/pi
``` ```
### Step 30: switch to root ### Step 23: switch to root
```shell ```shell
sudo su - sudo su -
``` ```
### Step 31: make firewall rules persistent ### Step 24: make firewall rules persistent
```shell ```shell
iptables-save > /etc/iptables/rules.v4 cat << "EOF" > /etc/nftables.conf
ip6tables-save > /etc/iptables/rules.v6 #!/usr/sbin/nft -f
flush ruleset
EOF
```
```shell
nft list ruleset >> /etc/nftables.conf
```
### Step 25: set timezone
See https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
```shell
timedatectl set-timezone America/Montreal
```
### Step 26: disable swap
```shell
systemctl disable dphys-swapfile
```
### Step 27: update APT index and upgrade system
#### Update APT index
```shell
apt update
```
#### Upgrade packages
```shell
apt upgrade -y
``` ```
👍 👍