Official release date for the most basic installation instructions will be official here. Scripts and automation will come at a later date, when its more mature.
Raspberry Pi 4 is a very capable little creditcard sized computer with a 4 Core ARM CPU. It comes with different boards, sizing 1GB, 2GB, 4GB and 8GB RAM. I have, for the most basic things in my test and online systems, always chosen the 4GB model and a 32GB SD card. Do not underestimate, these applications require both memory and CPU. Running it on Raspberry Pi 2, 3, 3B+, yes, it can be installed but will most likely fail or not perform well. Trust me, I've tried it already, I've been working on this for years.
It should also be said, most of these chapters will come with extensive explanations, why and why not to do things. You might be able to follow if you are an intermediate to advanced user familiar with linux bash and configuration.
NOTE: Most of these components already exist and comes via the very well version managed Debian Buster repository. It should be somewhat safe to use, however I have had experiences of opensource software suddenly stopped working due to version handling and kernel differences. This may happen, and in such cases it might take time to get the problems fixed. If possible then dont update the firmware versions on your raspberry on your own, let them come with the repository updates.
1) Myth People have a tendency to misunderstand the use-case of wifi accesspoint signal range. The raspberry cannot produce long range wifi, and the businesscase is actually to stay within your house, and securely access the wifi. If you want a long range, you can buy a an external USB wifi adapter and use that as an accesspoint card. However, all wificards are not capable of being used as a Accesspoint. In some cases, your might even have to re-compile the sourcecode from the hostapd. I will, in my efforts try to produce or point to a compatible list of wifi adapters.
2) Myth People have a tendency to misunderstand the use-case of data throughput. Yes, you will ofcourse be able to watch 2 different netflix movies on two different mobilephones or update your mobilephones with updates. The Raspberry will make it possible, but there are ofcourse limitations. For example, I have made this work with 20/20Mhz band, and unfortunately been unsuccessful trying 40/40Mhz bands with the built-in wificard.
Read carefully: I also publish this information because I care about your safety, I expect you to use this extensive knowledge wisely and not maliciously. If you find problems or detect security issues, don't hesitate to inform me. I expect you to do that.
Read carefully: I strongly urge you to not put this device directly on the Internet, unless you know exactly what you are doing. I suggest atleast put it behind a NAT router, a firewall or atleast some kind of transit network.
in progress, and subject to change
Warning! This device will be warm. This device is going to be online most of the day, and carrying a heavy load, so a proper aluminium armor without fan is probably a good idea. Just make sure the heated components are properly attached and leading away the heat from the components. I have had success with the GeekWorm Raspberry Pi 4 Armor Gray, thus leading the cpu at +53C.
in progress, and the instruction is subject to change
Instruction here on installing image from a Windows system
in progress, and the instruction is subject to change
Instruction here on installing image from a Raspberry system
I'm currently working on a Raspberry Pi with a Desktop, this is why the SD card instruction looks like this at the moment. Instructions for Windows will come in a while. But for now, I'm on a raspberry desktop.
I have based my Raspberry Pi wifi router image on the Raspbian Buster Lite version, but I'm pretty sure Raspberry Pi OS Buster version will work the same way as the previous versions. This will be tested extensively before the official release date 2020-07-01. At the time of this writing, this OS has not been tested.
Download the Raspberry Pi OS (32-bit) Lite from The Rasberry Pi foundation, here.
Open a console and prepare your image file to be written to the SD card.
$ sudo apt-get update
$ sudo apt-get install dcfldd gunzip dnsutils tcpdump nmap -y
Note: you can use the dd command, I just like the progress indicator of dcfldd.
Go to the Downloads folder
$ cd Downloads
$ ls -l
total 16469060
...
-rw-r--r-- 1 pi pi 452715448 jun 14 10:08 2020-05-27-raspios-buster-lite-armhf.zip
...
Verify the sha256 hash, like so, and verify the red text output in the console.
$ sha256sum 2020-05-27-raspios-buster-lite-armhf.zip | grep f5786604be4b41e292c5b3c711e2efa64b25a5b51869ea8313d58da0b46afc64
...
f5786604be4b41e292c5b3c711e2efa64b25a5b51869ea8313d58da0b46afc64 2020-05-27-raspios-buster-lite-armhf.zip
...
Extract the image with the gunzip command.
$ gunzip 2020-05-27-raspios-buster-lite-armhf.zip
Insert your USB 3.0 SD card reader, and run the following command.
$ dmesg
...
[18217.822017] usb 2-1: new SuperSpeed Gen 1 USB device number 2 using xhci_hcd
[18217.881582] usb 2-1: New USB device found, idVendor=0bda, idProduct=0326, bcdDevice=11.24
[18217.881598] usb 2-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[18217.881611] usb 2-1: Product: USB3.0 Card Reader
[18217.881623] usb 2-1: Manufacturer: Realtek
[18217.881635] usb 2-1: SerialNumber: 201404081410
[18217.899942] usb-storage 2-1:1.0: USB Mass Storage device detected
[18217.901303] scsi host0: usb-storage 2-1:1.0
[18218.991413] scsi 0:0:0:0: Direct-Access Generic- USB3.0 CRW -SD 1.00 PQ: 0 ANSI: 6
[18219.003925] scsi 0:0:0:1: Direct-Access Generic- USB3.0 CRW -SD 1.00 PQ: 0 ANSI: 6
[18219.006767] sd 0:0:0:0: [sda] Attached SCSI removable disk
[18219.014432] sd 0:0:0:1: [sdb] Attached SCSI removable disk
[18219.022467] sd 0:0:0:0: Attached scsi generic sg0 type 0
[18219.022666] sd 0:0:0:1: Attached scsi generic sg1 type 0
...
[18380.662439] sd 0:0:0:1: [sdb] 62333952 512-byte logical blocks: (31.9 GB/29.7 GiB)
[18380.672670] sdb: sdb1 sdb2
...
The last 2 lines contain a SD card and its partitions detected, in this case sdb (disk), sdb1 (partition1) and sdb2 (partition2), because this is a raspberry card. Your output might be different, it might be sda or sdb.
To overwrite the SD card sdb with your new raspberry image. Please do note the warning, This will indeed delete all previous contents of your SD card, make sure its the correct card in your reader.
$ sudo dcfldd if=2020-05-27-raspios-buster-lite-armhf.img of=/dev/sdb bs=4M
in progress
in prgress, also subject to change
In this section we will assign static IPv4 addresses on your raspbian. If you have other networks you should assign them to the configuration below, and use the correct network and subnetmask for your network. I will however be consistent here, most people with a little knowledge do understand that if you work with this system remotely, you will be disconnected and will need to reconnect to the device, while restarting the service.
$ sudo nano /etc/dhcpcd.conf
And add/modify the the eth0 static section:
interface eth0
static ip_address=192.168.220.30/24
static routers=192.168.220.254
static domain_name_servers=1.1.1.1 8.8.8.8
And add/modify the wlan0 static section:
interface wlan0
static ip_address=192.168.230.254/24
# no routers
# no domain_name_servers
Note: I will add IPv6 configuration later, and when I do, it will work perfectly with the raspbian networking.
in progress, also subject to change
Since your raspberry doesnt have a physical clock, its important to have it synchronize its clock with the configured network time servers available. Like anyone working with Cyber security, correct timestamps is of the essence in any evidence or logs. This to determine the correct timestamp something happened. Failing to do so, will render logs and evidence unusable.
Ok, you don't really have to change the timesynccd service, because it comes preinstalled on Debian Buster, however it is a good idea to have knowledge about this service existance, and that you don't need to install the ntp service. The NTP service which in turn will open port UDP/123, opening a footprint for traffic towards your Raspberry. The ntp service is complicated to secure, so unless you know how, don't use it.
Example: The location of your NTP (Network Time Protocol) server configuration
$ sudo nano /etc/systemd/timesyncd.conf
Example: I've made an example if you want to choose your own NTP servers.
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
#
# Entries in this file show the compile time defaults.
# You can change settings by editing this file.
# Defaults can be restored by simply deleting this file.
#
# See timesyncd.conf(5) for details.
[Time]
NTP=ntp3.sptime.se ntp4.sptime.se
#FallbackNTP=0.debian.pool.ntp.org 1.debian.pool.ntp.org 2.debian.pool.ntp.org 3.debian.pool.ntp.org
#RootDistanceMaxSec=5
PollIntervalMinSec=64
PollIntervalMaxSec=2048
Advice: You can uncomment the FallbackNTP and RootDistanceMaxSec if you want to have a NTP fallback and make sure your NTP servers answer within 5 seconds. This is recommended.
Advice: The PollIntervalMinSec and PollIntervalMaxSec is the interval frame between sending ntp requests to the destinations. A value below 64 seconds is not recommended, unless you wish to be blacklisted on the ntp providers. So, don't go below 64 seconds.
Example: Check if the time is synchronized.
$ timedatectl status
Local time: sön 2020-06-14 10:44:44 UTC
Universal time: sön 2020-06-14 10:44:44 UTC
RTC time: n/a
Time zone: Etc/UTC (UTC, +0000)
System clock synchronized: yes
NTP service: active
RTC in local TZ: no
Example: Turning NTP on or off. Please do turn it on with true.
$ sudo timedatectl set-ntp false
$ sudo timedatectl set-ntp true
Example: List available timezones. Grep if you want a shorter list.
$ timedatectl list-timezones
$ timedatectl list-timezones | grep America
$ timedatectl list-timezones | grep Europe
$ timedatectl list-timezones | grep Australia/Sydney
Example: Set timezone.
$ sudo timedatectl set-timezone Europe/Paris
$ sudo timedatectl set-timezone Europe/Stockholm
$ sudo timedatectl set-timezone Australia/Sydney
Example: Check the status the systemd-timesyncd service.
$ sudo systemctl status systemd-timesyncd
Example: Restart the systemd-timesyncd service.
$ sudo systemctl restart systemd-timesyncd
Thankyou for reading this section, this will help you in our later sections during logging, evidence and negotiating ipsec and prevent you from getting errors later when we use transport layer security with certificates. They will depend on you completing this section.
in progress
In this chapter we are going to install the hostapd, an essential component for making your Raspberry Pi 4 a wifi access point. This will enable the wlan0 adapter on the raspberry to act like a accesspoint.
If you are using your Raspberry Pi 4, wifi to connect to another accesspoint, this will stop it from doing that. From now on your eth0 interface will be the outside/transit interface.
Lets get started
Step 1: Update and upgrade your OS, then install the Wifi AccessPoint daemon.
$ sudo apt-get update
$ sudo apt-get upgrade -y
$ sudo apt-get install -y hostapd
Step 2: Make sure the hostapd.service is stopped.
$ sudo systemctl stop hostapd
Step 3: Start by disabling and masking the wpa_supplicant.service, which makes your raspberry a client to an external access point. This will stop the wifi client on your Raspberry Pi.
$ sudo systemclt stop wpa_supplicant.service
$ sudo systemctl disable wpa_supplicant.service
$ sudo systemctl mask wpa_supplicant.service
Step 4: And if you really want to be sure its not used, then..
$ sudo mv /etc/wpa_supplicant/wpa_supplicant.conf /etc/wpa_supplicant/wpa_supplicant.conf.old
Step 5: Make sure your hostapd.conf is pointed out inside the file /etc/default/hostapd.
$ sudo nano /etc/default/hostapd
# Defaults for hostapd initscript
#
# WARNING: The DAEMON_CONF setting has been deprecated and will be removed
# in future package releases.
#
# See /usr/share/doc/hostapd/README.Debian for information about alternative
# methods of managing hostapd.
#
# Uncomment and set DAEMON_CONF to the absolute path of a hostapd configuration
# file and hostapd will be started during system boot. An example configuration
# file can be found at /usr/share/doc/hostapd/examples/hostapd.conf.gz
#
# ** yes, enter it here.. even its deprecated **
DAEMON_CONF="/etc/hostapd/hostapd.conf"
# Additional daemon options to be appended to hostapd command:-
# -d show more debug messages (-dd for even more)
# -K include key data in debug messages
# -t include timestamps in some debug messages
#
# Note that -B (daemon mode) and -P (pidfile) options are automatically
# configured by the init.d script and must not be added to DAEMON_OPTS.
#
#DAEMON_OPTS=""
I have made a couple of hostapd configuration examples for you to select from.
$ sudo nano /etc/hostapd/hostapd.conf
Example configuration 1: Wireless 802.11ac on 5Ghz, on channel 48, bandwidth 20/20Mhz. Recommended for iPhone 6 and upwards.
########################################
## This configuration will work with ##
## newer iPhone models, 6s and newer ##
## Android phones. ##
## ##
## However Smart TV's might not work ##
## with this as some of them still ##
## use 802.11b/g/n on the 2.4Ghz ##
## band. ##
## ##
## Check your documentation. ##
## ##
## This configuration is recommended ##
## for devices that have VPN ##
## capability. ##
## ##
## Check your documentation. ##
########################################
# attach this hostapd to wlan0 (builtin wireless card)
interface=wlan0
# always use the nl80211 driver, unless otherwise specified.
driver=nl80211
# enable the 5Ghz band.
hw_mode=a
# Channel 36 or 48 is probably your best option for 20/20Mhz band.
# Important, if you run multiple Raspberries as accesspoints next to eachother, I urge you to use different channels.
channel=48
# Country Wireless compliance code. (enter your country code: Example GB, US or SE)
country_code=SE
# Wireless compliance 802.11d (1=enable, 0=disable)
ieee80211d=1
# Wireless compliance 802.11n (1=enable, 0=disable)
ieee80211n=1
# Wireless compliance 802.11ac (1=enable, 0=disable)
ieee80211ac=1
# new variable, untested.
#wme_enabled=1
# bandwith controller.
wmm_enabled=1
# bandwith controller. 40/40Ghz example. Does not work.
# ht_capab=[HT40+][SHORT-GI-80][DSSS_CCK-40]
# macaddress acl (1=enabled, 0=disabled)
macaddr_acl=0
# hide ssid broadcasts (1=enabled, 0=disabled)
ignore_broadcast_ssid=0
########################################
## Wifi settings here ##
########################################
# enter ssid name here, make sure it does not conflict with another accesspoint.
ssid=wifi-03.firestorm.org
# enable authentication (1=enable, 0=disable)
auth_algs=1
# enforce wpa2 algorithms. 1=wpa1, 2=wpa2, 3=combined wpa1 and wpa2 (not recommended)
wpa=2
# enforce use of pre-shared key.
wpa_key_mgmt=WPA-PSK
# enforce the CCMP encryption algorithm
rsn_pairwise=CCMP
# enforce hostapd with your preshared key.
wpa_passphrase=<enter your password here. 20-32 characters recommended.>
The hostapd is masked, which means you cannot enable it per default. Unmask it and then enable it.
$ sudo systemctl unmask hostapd
$ sudo systemctl enable hostapd
Example: Stop the hostapd.service
$ sudo systemctl stop hostapd.service
Example: Start the hostapd.service
$ sudo systemctl start hostapd.service
Example: Check status of the hostapd.service
$ sudo systemctl status hostapd.service
Step 1: Run iwconfig to see if your hostapd mode is now set to Master.
$ sudo iwconfig
...
wlan0 IEEE 802.11 Mode:Master Tx-Power=31 dBm
Retry short limit:7 RTS thr:off Fragment thr:off
Power Management:on
...
NOTE; The output should indicate that mode is master and that there is transmission power around 31dBm with your built in wifi card, wlan0.
Step 2: Verify that wlan0 is acting as access point, AP, and that the channel you selected is active and working.
$ iw wlan0 info
Interface wlan0
ifindex 3
wdev 0x1
addr xx:xx:xx:xx:xx:xx
ssid wifi-03.firestorm.org
type AP
wiphy 0
channel 48 (5240 MHz), width: 20 MHz, center1: 5240 MHz
txpower 31.00 dBm
This chapter has set the foundation for your accesspoint configuration and for enabling the wifi 802.11 broadcasting. It should be broadcasting its ssid now, but lets finish the next chapter before connecting to the ssid.
In this chapter we are going to enable dhcp and dns which will enable your accesspoint to configure any wifi attached devices with the ip addresses they will be using to navigate the wifi network. I'll be using dnsmasq since this probably is the most qualified software for this task.
Dnsmasq is widely used in routers and other network appliances for both dhcp and dns services. If you shoud select something, then select dnsmasq, its easy and uncomplicated. Keep things simple.
I'm repeating the installation of dnsutils, tcpdump, because you will need them later in this chapter.
update, upgrade and install dnsmasq
$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo apt-get install dnsmasq dnsutils tcpdump -y
$ sudo systemctl stop dnsmasq
$ sudo systemctl stop hostapd
Rename the dnsmasq.conf to old and start a new dnsmasq.conf file.
$ sudo mv /etc/dnsmasq.conf /etc/dnsmasq.conf.orig
$ sudo nano /etc/dnsmasq.conf
Add the following entries.
local=/localnet/
# exmple on howto re-route ntp dns requests to another network time protocol server.
#address=/ntp.org/193.11.166.2
#address=/time-ios.apple.com/193.11.166.2
addn-hosts=/etc/dnsmasq/hostile_hosts
# exmpand-hosts adds the appropriate domain specified below to your devices
# when retreiving dhcp addresses from dnsmasq.
expand-hosts
domain=internal.firestorm.org
domain=wifi.firestorm.org,192.168.230.0/24
domain=ipsec.firestorm.org,192.168.231.0/24
# we havent added docker yet, but this entry would be correct.
#domain=docker.firestorm.org,172.17.0.0/16
# we havent added the ipsec pool yet, but a synthetic domain
# for non-dnsmasq ipsec pool would do the trick.
#synth-domain=ipsec.firestorm.org,192.168.231.0/24,ipsec-
# listen for DNS request on these addresses.
listen-address=192.168.230.254
listen-address=192.168.220.30
# we havent added docker yet, but this entry would be correct.
#listen-address=172.17.0.1
listen-address=127.0.0.1
# no dhcp responses on eth0
no-dhcp-interface=eth0
# we havent added docker yet, but this entry would be correct.
#no-dhcp-interface=docker0
# dhcp wifi network
dhcp-range=192.168.230.10,192.168.230.30,255.255.255.0,6h
dhcp-option=option:ntp-server,193.11.166.2,193.11.166.18
dhcp-option=option:dns-server,192.168.230.254
dhcp-option=option:domain-search,wifi.firestorm.org
# make wpad behave on wifi.
dhcp-option=252,"\n"
# authorative dhcp on wifi network.
dhcp-authoritative
# example, you can add your own command to run when a client requests a dhcp entry.
dhcp-script=/bin/echo
srv-host=_ipp._tcp,printer.internal.firestorm.org,631
srv-host=_raw._tcp,printer.internal.firestorm.org,9100
txt-record=_http._tcp.printer.internal.firestorm.org,name=value,paper=A4
log-queries
log-dhcp
conf-dir=/etc/dnsmasq.d/,*.conf
$ sudo mkdir /etc/dnsmasq/
$ sudo nano /etc/dnsmasq/hostile_hosts
########################################
## HOSTILE ##
########################################
# redirector examples
# redirect url of choice to ip of choice
127.0.0.1 *.hostile-web-server.com
Add static dns records for your dnsmasq installation.
$ sudo nano /etc/hosts
# leave this section unchanged.
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
# example: 127.0.1.1 should refer to your specific raspberry pi hostname.
# in my case, my raspberry name is firestorm-cataclystic-0003.
127.0.1.1 firestorm-cataclystic-0003
# ip address, see /etc/dhcpcd.conf for wifi network card configuration.
192.168.230.254 firestorm-cataclystic-0003.wifi.firestorm.org
# ip address, see /etc/dhcpcd.conf for physical network card configuration.
192.168.220.30 firestorm-cataclystic-0003.internal.firestorm.org
# we havent added docker yet, but this entry would be correct.
#172.17.0.1 gate.docker.firestorm.org
Enable traffic forwarding from your wlan0 card to eth0 physical network card.
$ sudo nano /etc/sysctl.conf
Example: Find net.ipv4.ip_forward inside your sysctl.conf and set it to 1 to enable IPv4 forwarding.
net.ipv4.ip_forward=1
Disable traffic forwarding from your wlan0 card to eth0 physical network card.
$ sudo nano /etc/sysctl.conf
Example: Find net.ipv6.conf.all.forwarding inside your sysctl.conf and set it to 0 to disable IPV6 forwarding.
net.ipv6.conf.all.forwarding=0
Disable IPv6 on all network cards.
$ sudo nano /etc/sysctl.conf
Add the following lines
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
net.ipv6.conf.eth0.disable_ipv6 = 1
net.ipv6.conf.wlan0.disable_ipv6 = 1
To separate the wifi-network (192.168.230.0/24) from the transit-network (192.168.220.0/24), we need to add a network address translation (NAT). Thankfully we have iptables, who will do that for free.
A postrouting masquerade, NAT, on the eth0 interface will translate one network to another by changing the source ip of a packet on its way out through the eth0 device. It will help route wifi traffic out towards the Internet, and infact keep state and translate traffic going back in. Again, for free.
Add the following statement on your raspberry to start network address translation
$ sudo iptables -A POSTROUTING -o eth0 -j MASQUERADE
IMPORTANT; Although this is the correct way to do this, do note that the above statement is in no way permanent. If you turn the raspberry off or restart it, you will need to add this statement again.
Networking and iptables on Linux is difficult subject for people who are not familiar with network configurations. In other words this section could work for you, or it could bring you a lot of headache. I'll try to keep this as simple and easy as possible and in each chapter from here, add more detail.
Step 1: Add a iptables configuration file on disk
Step 1.1: Create the configuration file
$ sudo touch /etc/iptables.ipv4.nat
Step 1.2: Add ownership to user root and group root
$ sudo chown root:root /etc/iptables.ipv4.nat
Step 1.3: Set the access rights for root read/write, group read and everyone read
$ sudo chmod 644 /etc/iptables.ipv4.nat
Step 2: Add the permanent statements to the configuration file
$ sudo nano /etc/iptables.ipv4.nat
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
# Add a NAT to outbound traffic on the eth0 interface.
# This statement is typically what we would write in our 'iptables -A POSTROUTING -o eth0 -j MASQUERADE' statement.
-A POSTROUTING -o eth0 -j MASQUERADE
# Add a NAT to outbound traffic on the wlan0 interface.
# We will talk more about this in the IPSec chapter, but for now comment it out.
# This statement is typically what we would write in our 'iptables -A POSTROUTING -o wlan0 -j MASQUERADE' statement.
#-A POSTROUTING -o wlan0 -j MASQUERADE
# Below command commits the nat statements
COMMIT
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:LOG_ACCEPT - [0:0]
:LOG_DROP - [0:0]
# I have added these statements for future debugging and logging, leave them as is.
-A LOG_ACCEPT -j LOG --log-prefix "INPUT:ACCEPT " --log-level 6
-A LOG_ACCEPT -j ACCEPT
-A LOG_DROP -j LOG --log-prefix "INPUT:DROP " --log-level 6
-A LOG_DROP -j DROP
# Below command commits the filter and access list statements
COMMIT
WARNING; This iptables configuration is permissive to just get you started, please do not connect any of the physical interfaces with this configuration to any unsecured network, such as Internet. This would be a very bad idea. We will touch this subject further, and secure the iptables rules in the upcomming chapters.
Step 3: Add the raspberry load the iptables configuration at startup
$ sudo nano /etc/rc.local
# Add the iptables-restore statement here to load the
# iptables.ipv4.nat configuration, just before the
# exit 0 statement.
iptables-restore < /etc/iptables.ipv4.nat
exit 0
Step 4: Load the iptables configuration
$ sudo iptables-restore < /etc/iptables.ipv4.nat
Step 5: Verify the ip tables configuration
$ sudo iptables-save
$ sudo iptables -L -v -n
The chapters until here has taken you all the way to get your Raspberry Pi up and running as a simple wifi accesspoint. We have added the dnsmasq configuration, with both dns-, dhcp-, hostnames- and some basic iptables configuration. As I wrote, iptables are somewhat complex for beginners, I promise we will be touching the iptables configuration in further chapters. From this point we will be securing the configurations.
Wireless technology, is wireless. Unfortunately wifi access 802.11a/b/g/n/ac with WPA1 and WPA2 is not too difficult to gain access to, even with long passwords its still easy to overtake, overcome, get in to and also inject data into. To prevent this from happening we have the IPsec protocol (50), which will establish, exchange keys and negotiate security associations, making encrypted tunnels which is really difficult to inject data into from a 3rd party on the network.
There is also the aspect of rouge devices, evil doers, injecting data into your wifi data streams or just risk of someone using your network to download porn. Thats right. Having a wifi is not just about you, but also potentially about someone else using your Internet. The arguments to use tunnels encrypted with IPsec is strong.
I've tested IPsec tunnels with certificates from a home made 4096bit certificate authority and issued 2048bit certificates, however that is just too complex to write in this guide. I am instead going to set a long passphrase for you, to get you going and to prevent evil doers from injecting stuff between you and your raspberry.
If you want to secure your wifi network, you can also enable NAT on the wlan0 card to prevent any other wifi traffic from passing your raspberry without first negotiating an IPsec tunnel into the Raspberry. I will give some examples on how to do that. Just remember that some devices don't have IPSec builtin, and they cannot use IPSec .. Some examples are; TVs, IoTs, Arduinos, older mobilephones, and such. You will have to decide whats good enough for you, I'll just give you the tools to secure your network. Al dente style.
Update, upgrade and install the StrongSwan IPSec packages.
$ sudo apt-get update
$ sudo apt-get upgrade -y
$ sudo apt-get install strongswan -y
Example 1: Configure the default IPSec settings with preshared-key
$ sudo nano /etc/ipsec.conf
# ipsec.conf - strongSwan IPsec configuration file
# basic configuration
config setup
# strictcrlpolicy=yes
# uniqueids = no
conn %default
# lifetime
lifetime=12h
dpddelay=30s
dpdtimeout=120s
dpdaction=restart
ikelifetime=60m
keylife=20m
rekeymargin=3m
keyingtries=1
keyexchange=ikev2
mobike=yes
authby=secret
reauth=no
conn vpnserver-dhcpclients
# self config
left=192.168.230.254
leftid=wifi-03@wifi.firestorm.org
leftsubnet=0.0.0.0/0
leftfirewall=yes
# clients config
# any client can start negotiating.
right=%any
# all clients need to present themselfs as something@wifi.firestorm.org
rightid=*@wifi.firestorm.org
# when ipsec connected, use this ipv4 pool inside the raspberry.
rightsourceip=192.168.231.0/24
# when ipsec connected, use this dns server
rightdns=192.168.230.254
#rightdns=172.17.0.1
rightupdown=/bin/echo
auto=add
include /var/lib/strongswan/ipsec.conf.inc
Example 1: Add your IPSec device for preshared-key tunnel on the wifi-network.
$ sudo nano /etc/ipsec.secrets
# This file holds shared secrets or RSA private keys for authentication.
# RSA private key for this host, authenticating it to any other host
# which knows the public part.
# EXAMPLE: yourdevice
yourdevice@wifi.firestorm.org : PSK YourSuperLongPasswordHere
Go ahead and uncomment the ipsec.firestorm.org section in your dnsmasq.conf
$ sudo nano /etc/dnsmasq.conf
# we havent added the ipsec pool yet, but a synthetic domain
# for non-dnsmasq ipsec pool would do the trick.
synth-domain=ipsec.firestorm.org,192.168.231.0/24,ipsec-
To prevent future problems with implicit deny iptables, which we will enable later, here are some things to prepare in your IPSec configuration.
IMPORTANT; The above configured ipsec configuration will work flawlessly with iptables when installing strongswan on a vanilla raspberry-kernel; however it will definately stop working when updating the raspberry kernel to newer versions. Obviously there are some compiled or hardwired relation between the strongswan version and the iptables netlink kernel driver.
To make this work anyway, also with an updated kernel, you will need to enable the charon kernel-netlink, socket-default and libipsec traffic selectors.
Lets get started
Step 1: Enable the charon socket-default fwmark and load the socket selector.
$ sudo nano /etc/strongswan.d/charon/socket-default.conf
socket-default {
# Firewall mark to set on outbound packets.
fwmark = 0x4
# Whether to load the plugin. Can also be an integer to increase the
# priority of this plugin.
load = yes
# Set source address on outbound packets, if possible.
# set_source = yes
# Force sending interface on outbound packets, if possible.
# set_sourceif = no
# Listen on IPv4, if possible.
# use_ipv4 = yes
# Listen on IPv6, if possible.
# use_ipv6 = yes
}
Step 2: Enable the charon kernel-netlink negated fwmark and load the netlink selector.
$ sudo nano /etc/strongswan.d/charon/kernel-netlink.conf
kernel-netlink {
# Buffer size for received Netlink messages.
# buflen = <min(PAGE_SIZE, 8192)>
# Force maximum Netlink receive buffer on Netlink socket.
# force_receive_buffer_size = no
# Firewall mark to set on the routing rule that directs traffic to our
# routing table.
fwmark = !0x4
# Whether to ignore errors potentially resulting from a retransmission.
# ignore_retransmit_errors = no
# Whether to load the plugin. Can also be an integer to increase the
# priority of this plugin.
load = yes
# MSS to set on installed routes, 0 to disable.
# mss = 0
# MTU to set on installed routes, 0 to disable.
# mtu = 0
# Whether to perform concurrent Netlink ROUTE queries on a single socket.
# parallel_route = no
# Whether to perform concurrent Netlink XFRM queries on a single socket.
# parallel_xfrm = no
# Whether to always use XFRM_MSG_UPDPOLICY to install policies.
# policy_update = no
# Whether to use port or socket based IKE XFRM bypass policies.
# port_bypass = no
# Whether to process changes in routing rules to trigger roam events.
# process_rules = no
# Maximum Netlink socket receive buffer in bytes.
# receive_buffer_size = 0
# Number of Netlink message retransmissions to send on timeout.
# retries = 0
# Whether to trigger roam events when interfaces, addresses or routes
# change.
# roam_events = yes
# Whether to set protocol and ports in the selector installed on transport
# mode IPsec SAs in the kernel.
# set_proto_port_transport_sa = no
# Netlink message retransmission timeout, 0 to disable retransmissions.
# timeout = 0
# Lifetime of XFRM acquire state and allocated SPIs in kernel.
# xfrm_acq_expires = 165
# XFRM policy hashing threshold configuration for IPv4 and IPv6.
spdh_thresh {
ipv4 {
# Local subnet XFRM policy hashing threshold for IPv4.
# lbits = 32
# Remote subnet XFRM policy hashing threshold for IPv4.
# rbits = 32
}
ipv6 {
# Local subnet XFRM policy hashing threshold for IPv6.
# lbits = 128
# Remote subnet XFRM policy hashing threshold for IPv6.
# rbits = 128
}
}
}
Step 3: Enable the charon ipsec peer traffic selector for iptables selector rules to be created when negotiating ipsec.
$ sudo nano /etc/strongswan.d/charon/kernel-libipsec.conf
kernel-libipsec {
# allow peer traffic selector
allow_peer_ts = yes
}
Here are some commands to disable, enable, start, stop the ipsec.service
Disable the ipsec.service
$ sudo systemctl disable ipsec.service
Enable the ipsec.service
$ sudo systemctl enable ipsec.service
Stop the ipsec.service
$ sudo systemctl stop ipsec.service
Start the ipsec.service
$ sudo systemctl start ipsec.service
Get the status of the ipsec.service
$ sudo systemctl status ipsec.service
To add VPN on iPhone start the Settings app.
In the Settings app, go to General > VPN > Add VPN-configuration.
In the field Type, select IKEv2.
In the field Description, add wifi-03.firestorm.org
In the field Server, add firestorm-cataclystic-0003.wifi.firestorm.org
In the field Serveraddress, add 192.168.230.254
In the field Remote-ID, add wifi-03@wifi.firestorm.org
In the field Local-ID, add yourdevice@wifi.firestorm.org
In the field Userauthentication, select None - this will prevent you from being prompted time and time again for username/password.
In the field Use Certificate, select off
In the field Secret, enter the pre-shared key that you selected in the ipsec.secret file.
Select OK and start the IPsec connection.
Verify the automated ipsec policy match rules was created when IPSec connection was negotiated.
$ sudo iptables -L -v -n
Chain INPUT (policy ACCEPT 1M packets, 1M bytes)
pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 1492K packets, 96M bytes)
pkts bytes target prot opt in out source destination
52 460 ACCEPT all -- wlan0 * 192.168.231.1 0.0.0.0/0 policy match dir in pol ipsec reqid 2 proto 50
8675 2K ACCEPT all -- * wlan0 0.0.0.0/0 192.168.231.1 policy match dir out pol ipsec reqid 2 proto 50
Chain INPUT (policy ACCEPT 1M packets, 1M bytes)
pkts bytes target prot opt in out source destination
...
$ sudo ipsec statusall
Status of IKE charon daemon (strongSwan x.x.x, Linux 5.x.x-v7l+, armv7l):
uptime: 13 days, since Mar 19 19:05:06 2021
malloc: sbrk 2760704, mmap 0, used 907056, free 1853648
worker threads: 11 of 16 idle, 5/0/0/0 working, job queue: 0/0/0/0, scheduled: 3
loaded plugins: charon aes rc2 sha2 sha1 md5 mgf1 random nonce x509 revocation constraints pubkey pkcs1 pkcs7 pkcs8 pkcs12 pgp dnskey sshkey pem openssl fips-prf gmp agent xcbc hmac gcm attr kernel-netlink resolve socket-default connmark stroke updown counters
Virtual IP pools (size/online/offline):
192.168.231.0/24: 254/1/1
Listening IP addresses:
192.168.220.30
192.168.230.254
Connections:
vpnserver-dhcpclients: 192.168.230.254...%any IKEv2, dpddelay=30s
vpnserver-dhcpclients: local: [wifi-03@wifi.firestorm.org] uses pre-shared key authentication
vpnserver-dhcpclients: remote: [*@wifi.firestorm.org] uses pre-shared key authentication
vpnserver-dhcpclients: child: 0.0.0.0/0 === dynamic TUNNEL, dpdaction=restart
Security Associations (1 up, 0 connecting):
vpnserver-dhcpclients[2]: ESTABLISHED 24 minutes ago, 192.168.230.254[wifi-03@wifi.firestorm.org]...192.168.230.15[yourdevice@wifi.firestorm.org]
vpnserver-dhcpclients[2]: IKEv2 SPIs: e37ebeff3870b2c6_i f76ce6da4ebbcdf9_r*, rekeying in 30 minutes
vpnserver-dhcpclients[2]: IKE proposal: AES_CBC_256/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_2048
vpnserver-dhcpclients{2}: INSTALLED, TUNNEL, reqid 2, ESP SPIs: c693110e_i 08f45c7a_o
vpnserver-dhcpclients{2}: AES_CBC_256/HMAC_SHA2_256_128, 12652 bytes_i (81 pkts, 52s ago), 26505 bytes_o (69 pkts, 52s ago), rekeying in 11 hours
vpnserver-dhcpclients{2}: 0.0.0.0/0 === 192.168.231.1/32
This concludes the IPSec configuration, and I hope you will take the opportunity to use this.
Now that we have functional accesspoints and are hopefully using them for our devices, such as iphones, etc. I will take the opportunity to get you started on automated network scanning. This to find the simplest form of vulnerabilities on your networks. This section is for somewhat advanced users, but I will try to keep it simple.
NMAP is in first case an enumeration tool, to map networks. The plugins used by NMAP are small scripts to attempt to identify the simplest and probably the worst kind of vulnerabilities. NMAP is not full scale a vulnerability scanner, but a network mapper. Its primary usage is to detect whatever it is you have connected on your network.
In this section we will prepare a USB 3.0 storage for the upcomming chapters, add scheduled plugin downloads and network scans.
Lets get started
Step 1: Logon with SSH or console, on your Raspberry Pi wifi accesspoint.
Step 2: Remove any unused USB disks to prevent data deletion.
Step 3: Start by inserting the Kingston 64GB in the blue usb 3.0 ports and run the following command.
dmesg
...
...
[16758.236924] usb 2-1: new SuperSpeed Gen 1 USB device number 2 using xhci_hcd
[16758.258823] usb 2-1: New USB device found, idVendor=0951, idProduct=1666, bcdDevice= 1.10
[16758.258840] usb 2-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[16758.258851] usb 2-1: Product: DataTraveler 3.0
[16758.258860] usb 2-1: Manufacturer: Kingston
[16758.258869] usb 2-1: SerialNumber: 408D5C165308E3C1A9442E39
[16758.263555] usb-storage 2-1:1.0: USB Mass Storage device detected
[16758.265674] scsi host0: usb-storage 2-1:1.0
[16759.293326] scsi 0:0:0:0: Direct-Access Kingston DataTraveler 3.0 PMAP PQ: 0 ANSI: 6
[16759.295989] sd 0:0:0:0: [sda] 121110528 512-byte logical blocks: (62.0 GB/57.8 GiB)
[16759.296328] sd 0:0:0:0: [sda] Write Protect is off
[16759.296335] sd 0:0:0:0: [sda] Mode Sense: 45 00 00 00
[16759.299824] sd 0:0:0:0: [sda] Write cache: disabled, read cache: enabled, doesn't support DPO or FUA
[16759.305521] sd 0:0:0:0: Attached scsi generic sg0 type 0
[16760.589334] sda: sda1
[16760.591770] sd 0:0:0:0: [sda] Attached SCSI removable disk
...
NOTE; In my case it is a /dev/sda device that is detected with a sdb1 partition on it. In your case it could be something else.
Step 4: Clear the Kingston 64GB /dev/sda disk, WARNING this will delete whatever is on it.
$ sudo dcfldd if=/dev/zero of=/dev/sda bs=4M
Step 4.1: Run sync to have the previous operations written and finalized to disk.
$ sudo sync
Step 4.2: List the memory devices attached to the Raspberry.
$ sudo fdisk -l
Step 4.3: Add a primary partition of type 0x83 on the kingston /dev/sda disk.
$ sudo fdisk /dev/sda
Step 4.4: Add the EXT4 filesystem on the kingston memory partition that you just created.
$ sudo mkfs.ext4 /dev/sda1
Step 4.5: Show the UUID added with the EXT4 /dev/sda1 partition.
$ sudo lsblk -f /dev/sda
...
NAME FSTYPE LABEL UUID FSAVAIL FSUSE% MOUNTPOINT
sda
└─sda1 ext4 e4ef75de-acfd-459a-8f1e-d9becc517e55 53G 1%
...
Step 4.6: Edit the filesystem tab, and add the UUID from the previous step, to have the new volume mounted at system start.
$ sudo nano /etc/fstab
# add the following line, with the UUID from the step above.
UUID=e4ef75de-acfd-459a-8f1e-d9becc517e55 /mnt/volume ext4 defaults,noatime 0 1
Step 4.7: Create the mount directory under the /mnt folder.
$ sudo mkdir -p /mnt/volume
Step 4.8: Mount all defined volumes from the fstab.
$ sudo mount -a
Step 4.9: Set the mount directory with the correct ownership.
$ sudo chown -Rv pi:pi /mnt/volume
Step 5: Verify that /dev/sda1 was mounted to /mnt/volume.
$ df -h
Filesystem Size Used Free Use% Mount
/dev/root 29G 3,2G 25G 12% /
devtmpfs 1,8G 0 1,8G 0% /dev
tmpfs 1,8G 0 1,8G 0% /dev/shm
tmpfs 1,8G 177M 1,7G 10% /run
tmpfs 5,0M 4,0K 5,0M 1% /run/lock
tmpfs 1,8G 0 1,8G 0% /sys/fs/cgroup
/dev/mmcblk0p1 253M 48M 205M 19% /boot
/dev/sda1 57G 0G 56G 0% /mnt/volume
tmpfs 365M 0 365M 0% /run/user/1000
DISCLAIMER: Before performing this step, make sure you are authorized with a written permission from whoever owns the transit/outside network.
Step 1: Update and install NMAP on your Raspberry Pi.
$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo apt-get install nmap -y
Step 2: Schedule NMAP tasks to download and scan networks.
$ crontab -e
NOTE: First time: Select option 1 to use nano, if it asks which editor to use.
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h dom mon dow command
# at 18:00 - download updated plugin scripts from nmap.
00 18 * * * /usr/bin/nmap --script-updatedb > /dev/null 2>&1
########################################
## DISCLAIMER ##
## Make sure you have written ##
## permission to scan the network ##
########################################
# every 30 minutes scan subnet 192.168.220.0/24 and write the outputfiles to /mnt/volume with datetime.
*/30 * * * * /usr/bin/nmap 192.168.220.0/24 -Pn -oA /mnt/volume/firestorm-192.168.220.0-$(date +\%Y\%m\%d_\%H\%M\%S) > /dev/null 2>&1
# every 30 minutes scan subnet 192.168.230.0/24 and write the outputfiles to /mnt/volume with datetime.
*/30 * * * * /usr/bin/nmap 192.168.230.0/24 -Pn -oA /mnt/volume/firestorm-192.168.230.0-$(date +\%Y\%m\%d_\%H\%M\%S) > /dev/null 2>&1
in progress
in progress
in progress
in progress
in progress
in progress
in progress