Raspberry Pi security

Fonte: wirelesspt.net

Although focusing on the Raspberry Pi, this article is intended not just helping securing your Raspberry Pi but any other Linux operating system in general as well as any other Debian based distros.

Right out of the box your Raspberry Pi is not secure and thus vulnerable to potential well planed attacks and therefore you should harden it with security in mind. This tutorial requires superuser access either root or sudo permissions.

Re-generate SSH keys

If you have not hardened your raspberry pi yet you should always assume that the ssh keys are compromised. Therefore, you must re-generate them for your own usage by removing the old ones and create new ones.

rm -v /etc/ssh/ssh_host_* 
dpkg-reconfigure openssh-server

Password

After installation your Raspberry Pi login is an easy target to aim. It should be changed, locked or even removed.

Add a new user:

useradd --groups sudo -m copperfield

Change password to a passphrase such as: t0d@y!sth3b3std4yOf2020]

passwd copperfield

Next, reset the root password. Choose another long and hard passphrase to guess like previously shown

passwd root

Remove the pi user:

userdel -fr pi

Securing SSH

Edit sshd_config

nano -w /etc/ssh/sshd_config
# Make sure only the users you allow, are actually the only ones able to try to connect and adding their ip will be even more secure.
AllowUsers copperfield
# AllowUsers copperfield@ip # is more restrictive
# AllowUsers copperfield@ip root@ip # is even more restrictive

Port 22022 # Changing to a non default port is a good practice.

# Authentication:
LoginGraceTime 2m
PermitRootLogin no
# PermitRootLogin prohibit-password # to allow only with ssh key
StrictModes yes
MaxAuthTries 3

PubkeyAuthentication yes
AuthorizedKeysFile %h/.ssh/authorized_keys

# To enable empty passwords, change to yes (NOT RECOMMENDED)
PermitEmptyPasswords no

# Change to yes to enable challenge-response passwords (beware issues with
# some PAM modules and threads)
ChallengeResponseAuthentication no

# Change to no to disable tunneled clear text passwords
PasswordAuthentication no

UsePAM no

SSH keys

Next, and as regular user, (not root or sudo) generate an Ssh keypair and create a .ssh directory in your user’s (Copperfield) home directory and an authorized_keys file with the following commands. Be sure to set the permissions properly (otherwise the key based authentication will fail):

mkdir ~/.ssh
touch ~/.ssh/authorized_keys 
touch ~/.ssh/known_hosts
chmod 600 ~/.ssh/known_hosts
chmod 600 ~/.ssh/authorized_keys
cd ~/.ssh/
ssh-keygen -t ecdsa -b 521 -f <key_name_of_your_choice>

For added security you may want to add a password to this pub key when you are asked about it. This is recommended.

cat <key_name_of_your_choice.pub> >> ~/.ssh/authorized_keys

Make sure that <key_name_of_your_choice> does not stay on the raspberry pi. That is your private key.

systemctl enable ssh
systemctl restart ssh

Firewall

You should configure the firewall so that it logs a message whenever a firewall rule is activated and a connection is blocked.

Lets install what is needed:

apt-get install iptables iptables-persistent netstat-nat

Check for any previous rules:

iptables -L

Create a basic rule to ensure ssh on port 22020. If the port changes, also change the number here:

nano -w /etc/iptables/rules.v4
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]

# Allows all loopback (lo0) traffic and drop all traffic to 127/8 that doesn't use lo0
-A INPUT -i lo -j ACCEPT
-A INPUT ! -i lo -d 127.0.0.0/8 -j REJECT

# Accepts all established inbound connections
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Allows all outbound traffic
# You could modify this to only allow certain traffic
-A OUTPUT -j ACCEPT

# Allows SSH connections
# The --dport number is the same as in /etc/ssh/sshd_config
-A INPUT -p tcp -m state --state NEW --dport 22022 -j ACCEPT

# log iptables denied calls (access via 'dmesg' command)
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7

# Reject all other inbound - default deny unless explicitly allowed policy:
-A INPUT -j REJECT
-A FORWARD -j REJECT
COMMIT

Enable and start the service

systemctl enable netfilter-persistent.service
systemctl start netfilter-persistent.service

openvpn

If you are going to use openvpn, you will need to add a specific rule set at the begining of the iptables configuration file. OpenVPN may do this for you if you are using pivpn.

nano -w /etc/iptables/rules.v4

Add this at the top:

 *nat
:PREROUTING ACCEPT [319:21288]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [3:464]
:POSTROUTING ACCEPT [3:464]
-A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
COMMIT

Add this after the ssh rule:

# Allows openvpn connections
-A INPUT -p udp -m state --state NEW -m udp --dport 1195 -j ACCEPT
-A INPUT -i tun+ -j ACCEPT
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7
-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-port-unreachable
-A FORWARD -i tun+ -j ACCEPT
-A FORWARD -i tun+ -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i eth0 -o tun+ -m state --state RELATED,ESTABLISHED -j ACCEPT

Disable ICMP

Do not reply to external ping requests but allow doing them to others

nano -w /etc/iptables/rules.v4

Add this at the bottom and before COMMIT:

-A INPUT -p icmp --icmp-type echo-request -j DROP
-A OUTPUT -p icmp --icmp-type echo-request -j ALLOW

Apply rules

Next, ensure your iptables are working properly:

iptables-apply /etc/iptables/rules.v4
iptables-save

Check and confirm rules:

iptables -L

Log file

You can read the log in real time by doing:

tail -f /var/log/debug

and on Linux Mint:

tail -f /var/log/kern.log

Hide SSH with tor

The best you can do to secure ssh access to your Raspberry Pi is to access ssh using a tor hidden service. Doing so, not only hides the service on ipv4 and ipv6 as well as will bypass hardware firewalls and will not need configuration behind them.

Lets install what is needed:

apt-get install tor 

Backup default configuration file:

mv /etc/tor/torrc /etc/tor/torrc-default

Create new configuration file:

nano -w /etc/tor/torrc

Add the following inside:

# Defaults at /usr/share/tor/tor-service-defaults-torrc

User debian-tor
RunAsDaemon 1
PIDFile /var/run/tor/tor.pid
Log notice file /var/log/tor/tor.log
DataDirectory /var/lib/tor/services
DataDirectoryGroupReadable 0

## Hidden service configuration
# Version 3

HiddenServiceDir /var/lib/tor/services/ssh
HiddenServiceVersion 3
HiddenServicePort 22022 127.0.0.1:22

Edit tor-service-defaults-torrc and comment to close SocksPort 9050

nano -w /usr/share/tor/tor-service-defaults-torrc
#SocksPort 9050

Enable and start tor hidden service:

systemctl enable tor
systemctl start tor

Find your tor hidden service address for port 22022:

cat /var/lib/tor/services/ssh/hostname

And you will get something like this which will be your raspberry pi hidden address:

dkfljsdfsdlksdcvoiskdcvklscsdcsdmcsdmcklsdmlcmsdkciwejfowpef.onion 

Connect to hidden ssh

To connect to your hidden ssh raspberry pi service you need torsocks to be running on your client.

torsocks ssh -x -i <key_name_of_your_choice.key> user@6dkfljsdfsdlksdcvoiskdcvklscsdcsdmcsdmcklsdmlcmsdkciwejfowpef.onion -p 22022

ChrootDirectory jail

The term chroot refers to a process of creating a virtualized environment in a Linux or Unix operating system, separating it from the main operating system and directory structure. This process essentially generates a confined space, with its own root directory, to run software programs.

Edit sshd_config and add the following configuration at the very end of the configuration file. This can be done for any user or more than one user and or group of users.

nano -w /etc/ssh/sshd_config
Match User copperfield
   ChrootDirectory /home/copperfield
   AllowTCPForwarding no
   X11Forwarding no
   ForceCommand internal-sftp
   PermitTunnel no

Disable ipv6

Disabling IPv6 minimizes potential network attacks as it is as if you were uninstalling a second network adapter.

Edit:

nano -w /etc/sysctl.conf

and add this line, save and exit the editor:

net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
net.ipv6.conf.tun0.disable_ipv6 = 1

In your terminal type to commit changes:

sysctl -p

Unattended Upgrades

The purpose of unattended-upgrades is to keep the computer current with the latest security (and other) updates automatically.

Ensure Continuity

The Raspberry pi can crash when you are away, making all that depends on it to become offline but you can use it's broadcom hardware watchdog timer that can reboot the Raspberry pi in case it becomes unresponsive.

We need to use the bcm2708 module and make it persistent:

modprobe bcm2708_wdog
echo bcm2708_wdog >> /etc/modules

Packages needed:

apt-get install watchdog chkconfig

Enable and activate watchdog:

chkconfig watchdog on
systemctl enable watchdog
/etc/init.d/watchdog start

Configure the watchdog:

nano -w /etc/watchdog.conf

Uncomment the line #watchdog-device = /dev/watchdog so it reads:

watchdog-device = /dev/watchdog

The watchdog daemon will send /dev/watchdog a heartbeat every 10 seconds. If /dev/watchdog does not receive this signal it will restart your Raspberry Pi.

Receive reports

Install the package:

apt-get install logwatch exim4 exim4-config

Re-configure it:

dpkg-reconfigure exim4-config

Edit email setup:

nano -w /etc/exim4/passwd.client 

Add something to passwd.client like:

*.google.com:your_account_name@gmail.com:your_password

Restart exim4

systemctl restart exim4

Test the email setup on another shell by doing:

mail -s Test me@somemail.web
Test
.
Cc: 

And confirm reception.

Edit and adjust logwatch as needed:

nano -w /usr/share/logwatch/default.conf/logwatch.conf

Real mail logs in real time with:

tail -f /var/log/exim4/mainlog

See also

Links

Editor

Cmsv