mirror of
https://github.com/sunknudsen/privacy-guides.git
synced 2025-02-23 09:13:56 +00:00
Updated guide to ed25519, Debian 11 and nftables
This commit is contained in:
parent
9db6a0ffbf
commit
81e2853f89
@ -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 didn’t 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
|
||||||
```
|
```
|
||||||
|
|
||||||
👍
|
👍
|
||||||
|
Loading…
x
Reference in New Issue
Block a user