Psysecure by Ray Heffer, CISO advisor and cybersecurity expert. Privacy and security by Ray Heffer. Remove your digital footprint, master Defensive OSINT, and cybersecurity tactics. Stay ahead in digital safety and resilience. https://psysecure.com/ Fri, 11 Oct 2024 13:43:25 +0000 Fri, 11 Oct 2024 13:43:25 +0000 Jekyll v4.3.2 Self Hosting Nextcloud for Privacy, the Right Way (September 2024) <h2 id="table-of-contents">Table of Contents</h2> <ol> <li><a href="#overview" class="scroll-link">Overview</a></li> <li><a href="#installer" class="scroll-link">Step 1: Installation</a></li> <li><a href="#server" class="scroll-link">Step 2: Server Setup</a></li> <li><a href="#nextcloud" class="scroll-link">Step 3: Installing Nextcloud (Docker)</a></li> <li><a href="#letsencrypt" class="scroll-link">Step 4: Setting Up Let’s Encrypt SSL Certificate</a></li> <li><a href="#finalizing" class="scroll-link">Step 5: Finalizing Nextcloud Setup</a></li> <li><a href="#errors" class="scroll-link">Errors and Warnings</a></li> <li><a href="#commands" class="scroll-link">Useful Docker Commands</a></li> </ol> <h1 id="introduction">Introduction</h1> <p>If you are still using cloud services such as Dropbox or Google Drive for file sync, then this one is for you. Setting up a self-hosted Nextcloud server at home needn’t be difficult or complicated, and it offers complete control over your data, ensuring both privacy and security by keeping everything on your local network. We’ll also do this the right way. That means we’ll be using local disk encryption, and your Nextcloud server will ONLY be accessible at home, not over the internet. If there is a vulnerability, zero-day, or some other attack vector for Nextcloud, then I simply don’t want my home network or personal data exposed or at risk. Also, unlike using a cloud-hosted instance of Nextcloud, self-hosting allows you to maintain complete and total ownership, and privacy of your files. I’ll walk you through the entire process of setting up Nextcloud on your own server, whether that be an old PC or laptop you have lying around, or a dedicated server.</p> <p>We’ll also set up full disk encryption using LUKS, ensuring that everything stored on the server is encrypted at rest. Using a custom domain name, we’ll also make use of Let’s Encrypt for our SSL certificate, providing encryption in transit. The setup will allow for local syncing when connected to your home network, such as over WiFi, with offline access to files via mobile apps like Strongbox for iPhone or KeepassDX for Android.</p> <p>If you are new to terms such as RAID, then don’t worry. Just treat this as a learning exercise, and feel free to <a href="/contact" target="_blank">contact me</a> if you have questions.</p> <h2 id="overview">Overview</h2> <p><strong>Disclaimer</strong>: You need to have a basic knowledge of Linux, as I won’t walk through every step of the initial setup, such as configuring a static IP address or logging in via SSH. If you’re unfamiliar with the basics of Linux, this may not be suitable for you.</p> <h3 id="server">Server</h3> <p>Before you get started, you need to decide where to install Ubuntu, which we’ll use to run our Docker image of Nextcloud. This can be a spare laptop, server, or a desktop PC you have lying around. I will say that you want this to be powered on all the time, so if you have a noisy server, leaving it running in your home office is probably going to drive you insane very quickly. I’m fortunate to have a small area in a part of the house that is well insulated and soundproofed, so noise isn’t as much of a factor. I’ve read reports of some people successfully using a Raspberry Pi with <a href="https://github.com/nextcloud/nextcloudpi" target="_blank">NextcloudPi</a>, but I don’t have any experience with that.</p> <p>I run VMware vSphere 8 thanks to my <a href="https://vexpert.vmware.com/" target="_blank">vExpert</a> license, on my two <a href="https://www.amazon.com/gp/product/B07DFVWZH7/" target="_blank">Supermicro SYS-E300-9D</a> servers, which support 10GbE networking, and are very small and compact. Obviously this is overkill for just a Nextcloud deployment, but I also use this for other virtual machines on my home network.</p> <p>The choice of server may determine your storage options too, which I’ll discuss next. The reason I use VMware is so I can present an NFS (Network File System) volume from my NAS to VMware, and then create a large virtual disk for my Nextcloud data drive. The reason I do this, and not present the NFS volume directly to my Nextcloud machine, is so I can use LUKS disk encryption which only applies to block devices (HDD, SSD, iSCSI, virtual disks, etc.)</p> <h4 id="proxmox">Proxmox</h4> <p>You don’t even need VMware vSphere to do this. A free and open-source alternative is <a href="https://www.proxmox.com/en/downloads" target="_blank">Proxmox VE</a>. Proxmox uses KVM for virtual machines, and LXC for containers. It’s an excellent alternative to running VMware vSphere, and allows you to run other virtual machines or containers in the future.</p> <p>No matter which option you choose, I’ll assume you are using Ubuntu 22.04, rather than using Proxmox LXC or TrueNAS Scale containers. If you choose the latter, go for it.</p> <h3 id="storage">Storage</h3> <p>One of the key benefits of self-hosting Nextcloud is you can use your own storage, whether that be an internal SSD or HDD, or something more significant like a NAS. I personally need a lot of storage capacity, so I use a <a href="https://www.amazon.com/Synology-8-Bay-DiskStation-DS1823xs-Diskless/dp/B0BSTNV5TG/" target="_blank">Synology 8-Bay DiskStation DS1823xs</a>, with six <a href="https://www.amazon.com/gp/product/B0B94PNF7P/" target="_blank">16TB Seagate Ironwolf Pro</a> drives. Configured in a RAID 6 storage pool, this gives me around 58TB of usable storage. However, for a long time I was using a used <a href="https://www.qnap.com/en-us/product/ts-669%20pro" target="_blank">QNAP TS669 Pro</a> with six 4TB drives (RAID 10).</p> <p>If you don’t need a large amount of storage capacity like that, then you could even opt for a 2-bay NAS such as the <a href="https://www.amazon.com/Synology-2-Bay-DiskStation-DS223j-Diskless/dp/B0C8814GKB" target="_blank">Synology DS223j</a> which costs less than $190 (US). At least with RAID 1 (disk mirroring) you’ll get some redundancy, and it’s a good introduction to using a NAS.</p> <p><img src="/images/truenas/truenas.webp" alt="" width="40%" class="img-fluid rounded pb-3" /></p> <p>TrueNAS, as mentioned earlier, is another option, where you can repurpose an old PC or server, and build your own NAS. I tried this once, but found that having a PC case crammed full of disks was a cable management nightmare, so I decided just to pull the plug and go with the Synology NAS. However, if this is the direction you want to go in, check out <a href="https://www.truenas.com/truenas-scale/" target="_blank">TrueNAS Scale</a> since this also allows you to run containers or virtual machines on the same platform.</p> <h2 id="installer">1. Ubuntu Installer</h2> <p>By this stage, I will assume you are ready to install Ubuntu 22.04 somewhere, whether that be on a virtual machine or some other device. Here are the initial steps:</p> <ol> <li><strong>Download and mount the Ubuntu 22.04 Server ISO</strong> <ul> <li>Download the ISO from the official <a href="https://ubuntu.com/download/server" target="_blank">Ubuntu website</a>.</li> </ul> </li> <li><strong>Update the the new installer</strong> <ul> <li>If prompted, select ‘Update the the new installer’</li> </ul> </li> <li><strong>Choose Ubuntu Server (minimized)</strong> <ul> <li>During the installation process, select the <code class="language-plaintext highlighter-rouge">Ubuntu Server (minimized)</code> option to reduce unnecessary packages.</li> <li><img src="/images/nextcloud/minimal.webp" alt="" width="40%" class="img-fluid rounded pb-3" /></li> </ul> </li> <li><strong>Network Configuration</strong> <ul> <li>Select the network adapter and change from DHCP to Static (Edit IPv4 &gt; Manual)</li> <li>Set to a static IP for your network range (example below)</li> <li><img src="/images/nextcloud/network.webp" alt="" width="40%" class="img-fluid rounded pb-3" /></li> </ul> </li> <li><strong>Enable Disk Encryption (Optional)</strong> <ul> <li>When you boot the machine, you’ll need to enter this passphrase.</li> <li><img src="/images/nextcloud/encryption.webp" alt="" width="40%" class="img-fluid rounded pb-3" /></li> </ul> </li> <li><strong>Do NOT Select ‘Nextcloud’ from the ‘Featured Server Snaps’ Screen</strong> <ul> <li>We’ll be installing Nextcloud manually.</li> <li><img src="/images/nextcloud/featured.webp" alt="" width="40%" class="img-fluid rounded pb-3" /></li> </ul> </li> </ol> <p><strong>Note</strong>: Once Ubuntu Server is installed, you should be able to connect over SSH.</p> <h2 id="server">2. Server Setup</h2> <h3 id="setting-the-timezone">Setting the Timezone</h3> <p>First, set your server’s timezone to ensure logs and scheduled tasks run at the correct times. Replace <code class="language-plaintext highlighter-rouge">America/New_York</code> with your local timezone:</p> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>timedatectl set-timezone America/New_York </code></pre></div></div> <h3 id="updating-the-system">Updating the System</h3> <p>Update your package lists and upgrade existing packages:</p> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt update <span class="nt">-y</span> <span class="nb">sudo </span>apt upgrade <span class="nt">-y</span> </code></pre></div></div> <p>Install required packages:</p> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt-get <span class="nb">install </span>net-tools vim </code></pre></div></div> <h3 id="setting-up-the-firewall">Setting Up the Firewall</h3> <p>Usually I’d recommend using UFW (Uncomplicated Firewall), but Docker bypasses UFW rules because it manipulates iptables directly. Since we chose a minimal Ubuntu Server installation, UFW isn’t installed. Instead we’ll use <code class="language-plaintext highlighter-rouge">firewalld</code>. Docker integrates with firewalld, as stated on their <a href="https://docs.docker.com/engine/network/packet-filtering-firewalls/#integration-with-firewalld" target="_blank">website</a>, Docker automatically creates a <code class="language-plaintext highlighter-rouge">firewalld</code> zone called <code class="language-plaintext highlighter-rouge">docker</code>, with target <code class="language-plaintext highlighter-rouge">ACCEPT</code>.</p> <ol> <li>Install firewalld <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt <span class="nb">install </span>firewalld </code></pre></div> </div> </li> <li>Enable and Start <code class="language-plaintext highlighter-rouge">firewalld</code> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>systemctl <span class="nb">enable </span>firewalld <span class="nb">sudo </span>systemctl start firewalld </code></pre></div> </div> </li> </ol> <p><strong>Note</strong>: We don’t need to open HTTP or HTTPS (SSH is enabled by default) since Docker handles this as previously mentioned.</p> <h3 id="installing-docker">Installing Docker</h3> <p>Since we’ll be using Docker to run Nextcloud, we’ll install Docker and Docker Compose:</p> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt <span class="nb">install</span> <span class="nt">-y</span> apt-transport-https ca-certificates curl gnupg lsb-release </code></pre></div></div> <p>Add Docker’s official GPG key:</p> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>curl <span class="nt">-fsSL</span> https://download.docker.com/linux/ubuntu/gpg | <span class="nb">sudo </span>gpg <span class="nt">--dearmor</span> <span class="nt">-o</span> /usr/share/keyrings/docker-archive-keyring.gpg </code></pre></div></div> <p>Set up the stable Docker repository:</p> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">echo</span> <span class="se">\</span> <span class="s2">"deb [arch=</span><span class="si">$(</span>dpkg <span class="nt">--print-architecture</span><span class="si">)</span><span class="s2"> signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] </span><span class="se">\</span><span class="s2"> https://download.docker.com/linux/ubuntu </span><span class="se">\</span><span class="s2"> </span><span class="si">$(</span>lsb_release <span class="nt">-cs</span><span class="si">)</span><span class="s2"> stable"</span> | <span class="nb">sudo tee</span> /etc/apt/sources.list.d/docker.list <span class="o">&gt;</span> /dev/null </code></pre></div></div> <p><strong>Update package lists again</strong>:</p> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt update </code></pre></div></div> <p><strong>Install Docker Engine and Docker Compose</strong>:</p> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt <span class="nb">install</span> <span class="nt">-y</span> docker-ce docker-ce-cli containerd.io docker-compose-plugin </code></pre></div></div> <h3 id="configuring-the-hosts-file">Configuring the Hosts File</h3> <p>Add your server’s IP address and hostname to the <code class="language-plaintext highlighter-rouge">/etc/hosts</code> file:</p> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>vi /etc/hosts </code></pre></div></div> <p><strong>Note</strong>: You’ll want to ensure your internal DNS resolves to these hostnames. See the section below on split DNS to handle external / internal name resolution.</p> <p>Add the following line, replacing with your server’s IP and desired hostname:</p> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>192.168.1.146 your_domain_name </code></pre></div></div> <p><strong>Note</strong>: Use your own IP address and hostname here.</p> <h3 id="enabling-automatic-updates">Enabling Automatic Updates</h3> <p>Set up unattended upgrades to keep your system up to date:</p> <ol> <li>Install unattended-upgrades <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt <span class="nb">install</span> <span class="nt">-y</span> unattended-upgrades </code></pre></div> </div> </li> <li>Enable automatic updates <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>dpkg-reconfigure <span class="nt">-plow</span> unattended-upgrades </code></pre></div> </div> </li> <li>Configure <code class="language-plaintext highlighter-rouge">/etc/apt/apt.conf.d/50unattended-upgrades</code> This file controls which packages get updated. It should already be pre-configured, but you can review it or modify it if necessary. Just remove the <code class="language-plaintext highlighter-rouge">//</code> to uncomment the lines you want. <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>vi /etc/apt/apt.conf.d/50unattended-upgrades </code></pre></div> </div> <p><strong>Example:</strong></p> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Unattended-Upgrade::Allowed-Origins <span class="o">{</span> <span class="s2">"</span><span class="k">${</span><span class="nv">distro_id</span><span class="k">}</span><span class="s2">:</span><span class="k">${</span><span class="nv">distro_codename</span><span class="k">}</span><span class="s2">"</span><span class="p">;</span> <span class="s2">"</span><span class="k">${</span><span class="nv">distro_id</span><span class="k">}</span><span class="s2">:</span><span class="k">${</span><span class="nv">distro_codename</span><span class="k">}</span><span class="s2">-security"</span><span class="p">;</span> // Extended Security Maintenance<span class="p">;</span> doesn<span class="s1">'t necessarily exist for // every release and this system may not have it installed, but if // available, the policy for updates is such that unattended-upgrades // should also install from here by default. "${distro_id}ESMApps:${distro_codename}-apps-security"; "${distro_id}ESM:${distro_codename}-infra-security"; "${distro_id}:${distro_codename}-updates"; // "${distro_id}:${distro_codename}-proposed"; // "${distro_id}:${distro_codename}-backports"; }; </span></code></pre></div> </div> </li> <li>Check the status of <code class="language-plaintext highlighter-rouge">unattended-upgrades</code> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>systemctl status unattended-upgrades </code></pre></div> </div> </li> <li>Test with <code class="language-plaintext highlighter-rouge">--dry-run</code> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>unattended-upgrades <span class="nt">--dry-run</span> <span class="nt">--debug</span> </code></pre></div> </div> </li> </ol> <h3 id="adding-a-data-disk-with-luks-encryption">Adding a Data Disk with LUKS Encryption</h3> <p>At this stage of the setup, we’ve got Ubuntu installed, but I’ll assume the system (OS) disk won’t have enough capacity for our file sync data. I’ll refer to this as the Nextcloud data disk. In my setup, my Nextcloud virtual machine has a 100GB system disk and an additional 4TB disk for Nextcloud data.</p> <p>As I mentioned earlier, LUKS disk encryption only applies to block devices (HDD, SSD, iSCSI, virtual disks, etc.). My preference is to use a virtual disk, whether you are using Proxmox or VMware, as it simplifies the setup without the need for iSCSI or other complications. If you’re using a physical server, desktop PC, or laptop with physical disks installed, that’s perfectly fine too.</p> <p><strong>Note</strong>: In my example below, my 4TB data disk is presented as <code class="language-plaintext highlighter-rouge">/dev/sdb</code> to Ubuntu.</p> <h3 id="encrypting-the-disk">Encrypting the Disk</h3> <p><strong>Note</strong>: In the following steps, replace <code class="language-plaintext highlighter-rouge">/dev/sdb</code> with the actual device name of your data disk.</p> <ol> <li>Check the device name for your data disk <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>fdisk <span class="nt">-l</span> </code></pre></div> </div> </li> <li>Prepare the data disk for LUKS <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>cryptsetup luksFormat /dev/sdb </code></pre></div> </div> <p>This initializes LUKS encryption on the device <code class="language-plaintext highlighter-rouge">/dev/sdb</code>. During this process, you are prompted to enter a passphrase (keep this secure, such as inside your password manager). This passphrase is stored in key slot 0, which is the first slot of the LUKS header. This is important because without at least one valid key, the encrypted volume cannot be unlocked. For automatic unlocking during system boot, we’ll add an additional key to the LUKS header (key slot 1).</p> </li> <li>Open the encrypted volume: <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>cryptsetup luksOpen /dev/sdb datacrypt </code></pre></div> </div> </li> <li>Format the encrypted partition: <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>mkfs.ext4 /dev/mapper/datacrypt </code></pre></div> </div> </li> </ol> <p><strong>Note</strong>: I named the encrypted volume <code class="language-plaintext highlighter-rouge">datacrypt</code> but you can choose your own volume name here.</p> <h3 id="creating-a-key-file-for-automatic-unlocking">Creating a Key File for Automatic Unlocking</h3> <ol> <li>Create a key file and add it as an additional key to your LUKS partition: <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo dd </span><span class="k">if</span><span class="o">=</span>/dev/urandom <span class="nv">of</span><span class="o">=</span>/root/luks.key <span class="nv">bs</span><span class="o">=</span>1024 <span class="nv">count</span><span class="o">=</span>4 </code></pre></div> </div> </li> <li>Set permissions: <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo chmod </span>600 /root/luks.key </code></pre></div> </div> </li> <li>Add key to LUKS (remember to change <code class="language-plaintext highlighter-rouge">/dev/sdb</code> to the correct device path): <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>cryptsetup luksAddKey /dev/sdb /root/luks.key </code></pre></div> </div> </li> </ol> <h3 id="configure-etccrypttab">Configure /etc/crypttab</h3> <ol> <li>Edit the <code class="language-plaintext highlighter-rouge">/etc/crypttab</code> file to set up automatic decryption at boot: <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>vi /etc/crypttab </code></pre></div> </div> </li> <li>Add the following line (remember to change <code class="language-plaintext highlighter-rouge">/dev/sdb</code> to the correct device path): <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>datacrypt /dev/sdb /root/luks.key luks </code></pre></div> </div> </li> </ol> <h3 id="mounting-the-encrypted-disk">Mounting the Encrypted Disk</h3> <ol> <li>Create a mount point and add an entry to /etc/fstab: <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo mkdir</span> /data </code></pre></div> </div> </li> <li>Edit <code class="language-plaintext highlighter-rouge">/etc/fstab</code>: <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>vi /etc/fstab </code></pre></div> </div> </li> <li>Add the following line: <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/dev/mapper/datacrypt /data ext4 defaults 0 2 </code></pre></div> </div> </li> </ol> <h3 id="rebooting-and-verifying">Rebooting and Verifying</h3> <ol> <li>Reboot the system and verify that the disk is mounted: <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>reboot </code></pre></div> </div> </li> <li>After reboot, you should see the /data mount for the new disk: <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">df</span> <span class="nt">-h</span> </code></pre></div> </div> </li> </ol> <h3 id="setting-permissions">Setting Permissions</h3> <ol> <li>Ensure that the web server user (www-data) owns the data directory: <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo chown </span>www-data:www-data /data <span class="nt">-R</span> </code></pre></div> </div> </li> </ol> <h2 id="nextcloud">3. Installing Nextcloud (Docker)</h2> <h3 id="creating-a-docker-compose-file">Creating a Docker Compose File</h3> <ol> <li>Create a directory for Nextcloud and navigate to it: <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo mkdir</span> <span class="nt">-p</span> /data/nextcloud </code></pre></div> </div> </li> <li>Change to the Nextcloud directory: <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cd</span> /data/nextcloud </code></pre></div> </div> </li> <li>Create a <code class="language-plaintext highlighter-rouge">docker-compose.yml</code> file: <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>vi docker-compose.yml </code></pre></div> </div> </li> <li>Add the following content to <code class="language-plaintext highlighter-rouge">docker-compose.yml</code>:</li> </ol> <div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">services</span><span class="pi">:</span> <span class="na">nextcloud</span><span class="pi">:</span> <span class="na">build</span><span class="pi">:</span> <span class="s">.</span> <span class="na">container_name</span><span class="pi">:</span> <span class="s">nextcloud</span> <span class="na">restart</span><span class="pi">:</span> <span class="s">always</span> <span class="na">ports</span><span class="pi">:</span> <span class="pi">-</span> <span class="s2">"</span><span class="s">443:443"</span> <span class="na">volumes</span><span class="pi">:</span> <span class="pi">-</span> <span class="s">/data/nextcloud/html:/var/www/html</span> <span class="pi">-</span> <span class="s">/etc/letsencrypt/live/your_domain_name/fullchain.pem:/etc/ssl/certs/ssl-cert.crt:ro</span> <span class="pi">-</span> <span class="s">/etc/letsencrypt/live/your_domain_name/privkey.pem:/etc/ssl/private/ssl-cert.key:ro</span> <span class="na">environment</span><span class="pi">:</span> <span class="pi">-</span> <span class="s">NEXTCLOUD_DATA_DIR=/var/www/html/data</span> <span class="pi">-</span> <span class="s">NEXTCLOUD_TRUSTED_DOMAINS=your_domain_name your_ip_address</span> <span class="na">depends_on</span><span class="pi">:</span> <span class="pi">-</span> <span class="s">db</span> <span class="pi">-</span> <span class="s">redis</span> <span class="na">db</span><span class="pi">:</span> <span class="na">image</span><span class="pi">:</span> <span class="s">mariadb:10.11</span> <span class="na">container_name</span><span class="pi">:</span> <span class="s">nextcloud_db</span> <span class="na">restart</span><span class="pi">:</span> <span class="s">always</span> <span class="na">environment</span><span class="pi">:</span> <span class="pi">-</span> <span class="s">MYSQL_ROOT_PASSWORD=your_db_root_password</span> <span class="pi">-</span> <span class="s">MYSQL_PASSWORD=your_db_password</span> <span class="pi">-</span> <span class="s">MYSQL_DATABASE=nextcloud</span> <span class="pi">-</span> <span class="s">MYSQL_USER=nextcloud</span> <span class="na">volumes</span><span class="pi">:</span> <span class="pi">-</span> <span class="s">/data/nextcloud/db:/var/lib/mysql</span> <span class="na">redis</span><span class="pi">:</span> <span class="na">image</span><span class="pi">:</span> <span class="s">redis:alpine</span> <span class="na">container_name</span><span class="pi">:</span> <span class="s">nextcloud_redis</span> <span class="na">restart</span><span class="pi">:</span> <span class="s">always</span> <span class="na">volumes</span><span class="pi">:</span> <span class="pi">-</span> <span class="s">/data/nextcloud/redis:/data</span> <span class="na">command</span><span class="pi">:</span> <span class="pi">[</span><span class="s2">"</span><span class="s">redis-server"</span><span class="pi">,</span> <span class="s2">"</span><span class="s">--unixsocket"</span><span class="pi">,</span> <span class="s2">"</span><span class="s">/tmp/redis.sock"</span><span class="pi">,</span> <span class="s2">"</span><span class="s">--unixsocketperm"</span><span class="pi">,</span> <span class="s2">"</span><span class="s">770"</span><span class="pi">]</span> </code></pre></div></div> <p><strong>Replace the following</strong>:</p> <table> <thead> <tr> <th>Configuration</th> <th>Value</th> </tr> </thead> <tbody> <tr> <td><code class="language-plaintext highlighter-rouge">your_domain_name</code></td> <td>Replace with your own domain name (e.g., <code class="language-plaintext highlighter-rouge">nextcloud.domain.com</code>)</td> </tr> <tr> <td><code class="language-plaintext highlighter-rouge">your_ip_address</code></td> <td>Replace with the local IP address of your server</td> </tr> <tr> <td><code class="language-plaintext highlighter-rouge">your_db_root_password</code></td> <td>Replace with a strong root password for MariaDB</td> </tr> <tr> <td><code class="language-plaintext highlighter-rouge">your_db_password</code></td> <td>Replace with a strong password for the Nextcloud database user</td> </tr> </tbody> </table> <p><strong>Note</strong>: We’re using the recommended version of MariaDB 10.11 according to the <a href="https://docs.nextcloud.com/server/latest/admin_manual/installation/system_requirements.html" target="_blank">system requirements</a></p> <h3 id="configure-nextcloud-to-use-apache">Configure Nextcloud to Use Apache</h3> <ol> <li>Create <code class="language-plaintext highlighter-rouge">Dockerfile</code>: <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>vi /data/nextcloud/Dockerfile </code></pre></div> </div> </li> <li>Add the following: <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>FROM nextcloud RUN a2enmod ssl COPY nextcloud.conf /etc/apache2/sites-available/nextcloud.conf RUN a2ensite nextcloud.conf </code></pre></div> </div> </li> <li>Create `nextcloud.conf’: <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>vi /data/nextcloud/nextcloud.conf </code></pre></div> </div> </li> <li>Add the following:</li> </ol> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;VirtualHost <span class="k">*</span>:443&gt; ServerName your_domain_name DocumentRoot /var/www/html SSLEngine on SSLCertificateFile /etc/ssl/certs/ssl-cert.crt SSLCertificateKeyFile /etc/ssl/private/ssl-cert.key &lt;Directory /var/www/html/&gt; AllowOverride All Require all granted Options FollowSymLinks MultiViews &lt;IfModule mod_dav.c&gt; Dav off &lt;/IfModule&gt; &lt;/Directory&gt; ErrorLog <span class="k">${</span><span class="nv">APACHE_LOG_DIR</span><span class="k">}</span>/nextcloud-error.log CustomLog <span class="k">${</span><span class="nv">APACHE_LOG_DIR</span><span class="k">}</span>/nextcloud-access.log combined &lt;IfModule mod_headers.c&gt; Header always <span class="nb">set </span>Strict-Transport-Security <span class="s2">"max-age=15768000; includeSubDomains; preload"</span> &lt;/IfModule&gt; &lt;/VirtualHost&gt; </code></pre></div></div> <p><strong>Note</strong>: Replace <code class="language-plaintext highlighter-rouge">your_domain_name</code> with your actual domain name.</p> <h2 id="letsencrypt">4. Setting Up Let's Encrypt SSL Certificate</h2> <p>We won’t be exposing our Nextcloud server to the internet, however, we do need to use an external domain name if we want to use LetsEncrypt, and take advantage of a trusted SSL certificate. The last thing we want is to deal with self-signed certificate warnings on each of our devices accessing Nextcloud!</p> <h3 id="domain-names">Domain Names</h3> <p>I recommend using with <a href="https://www.namecheap.com/" target="_blank">Namecheap</a> or <a href="https://njal.la/" target="_blank">Njalla</a> to register a custom domain. Remember, you won’t be using this to access Nextcloud over the internet, but it will be used internally (e.g. nextcloud.yourdomain.com) and to obtain valid SSL certificates for HTTPS from <a href="https://letsencrypt.org/" target="_blank">LetsEncrypt</a>.</p> <p>I also recommend using <a href="https://www.cloudflare.com/" target="_blank">Cloudflare</a> to manage the DNS (Domain Name System) for your custom domain. In the next section, I guide you through obtaining a Cloudflare API key which we’ll need in order to obtain our SSL certificates without making the server accessible from the internet.</p> <p>If our server were accessible from the internet, we would have just used <code class="language-plaintext highlighter-rouge">certbot</code> to simply create and renew our SSL certificates. As we are doing things a little differently for added security, we’ll use the DNS-01 challenge method which involves proving control over a domain by adding specific DNS TXT records. I use CloudFlare to host the DNS for my domain names, which I’ll use in my example below.</p> <h3 id="internal-dns">Internal DNS</h3> <p>Let’s say my Nextcloud instance is on <code class="language-plaintext highlighter-rouge">nextcloud.psysecure.com</code>. Since I won’t be opening up my firewall to allow this over the internet, I don’t need to add a DNS record in Cloudflare. However, I do want my internal devices to resolve that to an internal IP address. For my home network I use two <a href="https://pi-hole.net/" target="_blank">PiHole</a> servers (virtual machines) but these could also be installed on a Raspberry Pi. They have a ‘Local DNS’ setting, that allows you to add internal DNS records, so <code class="language-plaintext highlighter-rouge">nextcloud.psysecure.com</code> would point to the internal IP address of your Nextcloud server (E.g. 192.168.100.146).</p> <h3 id="installing-certbot-and-dns-plugin">Installing Certbot and DNS plugin:</h3> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt update <span class="nb">sudo </span>apt <span class="nb">install</span> <span class="nt">-y</span> certbot python3-certbot-dns-cloudflare </code></pre></div></div> <h3 id="obtain-cloudflare-api-key">Obtain CloudFlare API Key</h3> <ol> <li>Log into CloudFlare and go to <a href="https://dash.cloudflare.com/profile/api-tokens" target="_blank">https://dash.cloudflare.com/profile/api-tokens</a></li> <li>Choose ‘Use Template’ next to ‘Edit zone DNS’</li> <li>In Zone Resources &gt; Include &gt; Specific Zone, choose your domain that you’ll use for Nextcloud.</li> <li>Click ‘Continue to Summary’</li> <li>Create Token</li> <li>Save this API token in your password manager, don’t lose it!</li> </ol> <h3 id="configure-dns-api-credentials">Configure DNS API Credentials</h3> <ol> <li>Create a credentials file with your DNS API token or keys: <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo mkdir</span> /etc/letsencrypt/dns <span class="nb">sudo </span>vi /etc/letsencrypt/dns/cloudflare.ini </code></pre></div> </div> </li> <li>Add your API credentials to the file: <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>dns_cloudflare_api_token <span class="o">=</span> your_cloudflare_api_token </code></pre></div> </div> </li> <li>Change permissions: <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo chmod </span>600 /etc/letsencrypt/dns/cloudflare.ini </code></pre></div> </div> </li> </ol> <p><strong>Note</strong>: Replace <code class="language-plaintext highlighter-rouge">your_cloudflare_api_token</code> with your CloudFlare API key</p> <h3 id="request-the-certificate">Request the Certificate</h3> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>certbot certonly <span class="se">\</span> <span class="nt">--dns-cloudflare</span> <span class="se">\</span> <span class="nt">--dns-cloudflare-credentials</span> /etc/letsencrypt/dns/cloudflare.ini <span class="se">\</span> <span class="nt">--dns-cloudflare-propagation-seconds</span> 60 <span class="se">\</span> <span class="nt">-d</span> your_domain_name </code></pre></div></div> <p><strong>Note</strong>: Replace <code class="language-plaintext highlighter-rouge">your_domain_name</code> (E.g. nextcloud.domain.com)</p> <h3 id="starting-the-containers">Starting the Containers</h3> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>docker compose up <span class="nt">-d</span> </code></pre></div></div> <h3 id="verify-the-containers-are-running">Verify the containers are running:</h3> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>docker ps </code></pre></div></div> <p>You should see two running containers, for example:</p> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 4678a7c04652 nextcloud-nextcloud <span class="s2">"/entrypoint.sh apac…"</span> 5 seconds ago Up 2 seconds 80/tcp, 0.0.0.0:443-&gt;443/tcp, :::443-&gt;443/tcp nextcloud e3158965d2d5 redis:alpine <span class="s2">"docker-entrypoint.s…"</span> 5 seconds ago Up Less than a second 6379/tcp nextcloud_redis 7f94e9dce0ab mariadb:10.11 <span class="s2">"docker-entrypoint.s…"</span> 5 seconds ago Up 3 seconds 3306/tcp nextcloud_db </code></pre></div></div> <h2 id="finalizing">5. Finalizing Nextcloud Setup</h2> <p>Open a web browser and navigate to <code class="language-plaintext highlighter-rouge">http://your_server_ip</code> to complete the Nextcloud setup. You will be prompted to create an admin account and configure the database connection. I recommend creating a random username (not <code class="language-plaintext highlighter-rouge">admin</code>), similar to my example below. Don’t lose this, store it in your password manager!</p> <p><img src="/images/nextcloud/004 - nextcloud setup.webp" alt="" width="20%" class="img-fluid rounded pb-3" /></p> <ol> <li>Click ‘Storage &amp; database’</li> <li>Select ‘MySQL/MariaDB’</li> </ol> <table> <thead> <tr> <th>Configuration</th> <th>Value</th> </tr> </thead> <tbody> <tr> <td>Database account</td> <td>nextcloud</td> </tr> <tr> <td>Database password</td> <td>The <code class="language-plaintext highlighter-rouge">your_db_password</code> you set in <code class="language-plaintext highlighter-rouge">docker-compose.yml</code></td> </tr> <tr> <td>Database name</td> <td>nextcloud</td> </tr> <tr> <td>Database host</td> <td>db</td> </tr> </tbody> </table> <p><strong>Click Install!</strong></p> <p><strong>Note</strong>: Access your Nextcloud instance via https://your_domain.com and verify that everything is working correctly.</p> <h3 id="enable-redis-for-memcache">Enable Redis for Memcache</h3> <ol> <li>Edit <code class="language-plaintext highlighter-rouge">config.php</code> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>vi /data/nextcloud/html/config/config.php </code></pre></div> </div> </li> <li>Add the memcache settings to the end of the config <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Existing config above</span> <span class="s1">'memcache.local'</span> <span class="o">=&gt;</span> <span class="s1">'\\OC\\Memcache\\Redis'</span>, <span class="s1">'memcache.locking'</span> <span class="o">=&gt;</span> <span class="s1">'\\OC\\Memcache\\Redis'</span>, <span class="s1">'redis'</span> <span class="o">=&gt;</span> array <span class="o">(</span> <span class="s1">'host'</span> <span class="o">=&gt;</span> <span class="s1">'/tmp/redis.sock'</span>, <span class="s1">'port'</span> <span class="o">=&gt;</span> 0, <span class="s1">'timeout'</span> <span class="o">=&gt;</span> 1.5, <span class="o">)</span>, <span class="o">)</span><span class="p">;</span> </code></pre></div> </div> </li> </ol> <hr /> <h1 id="errors">Errors and Warnings</h1> <p>By this stage you should be logged into Nextcloud. If you click on the user icon (top right) and choose ‘Administration Settings’ you might see a list of errors and warnings. Don’t panic, we’ll fix these!</p> <h2>1. Error: Some files have not passed the integrity check. List of invalid files… Rescan… For more details see the documentation.</h2> <p>This error is related to this <a href="https://github.com/nextcloud/docker/issues/1756" target="_blank">issue</a>, since Docker leaves a <code class="language-plaintext highlighter-rouge">.lock</code> file behind. We just need to remove it, as follows:</p> <ol> <li>Access the Nextcloud Docker container: <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>docker <span class="nb">exec</span> <span class="nt">-it</span> nextcloud bash </code></pre></div> </div> </li> <li>Navigate to the Nextcloud installation directory: <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cd</span> /var/www/html </code></pre></div> </div> </li> <li>Remove the extra file causing the issue: <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">rm </span>nextcloud-init-sync.lock </code></pre></div> </div> </li> <li>Exit the container: <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">exit</span> </code></pre></div> </div> </li> <li>Click ‘Rescan’ in the Nextcloud Administration Settings and this error will go away.</li> </ol> <h2>2. Warning: Server has no maintenance window start time configured.</h2> <p>To configure a maintenance window, just edit <code class="language-plaintext highlighter-rouge">config.php</code> and add <code class="language-plaintext highlighter-rouge">'maintenance_window_start' =&gt; 1,</code> to the end.</p> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>vi /data/nextcloud/html/config/config.php </code></pre></div></div> <p>Add this configuration line</p> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="s1">'maintenance_window_start'</span> <span class="o">=&gt;</span> 1, </code></pre></div></div> <h2>3. Warning: One or more mimetype migrations are available. Occasionally new mimetypes are added to better handle certain file types.</h2> <p>Run <code class="language-plaintext highlighter-rouge">occ maintenance:repair --include-expensive</code> as instructed by the warning, inside our Nextcloud container:</p> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>docker <span class="nb">exec</span> <span class="nt">-u</span> www-data <span class="nt">-it</span> nextcloud php occ maintenance:repair <span class="nt">--include-expensive</span> </code></pre></div></div> <p><strong>Note</strong>: You can run other <code class="language-plaintext highlighter-rouge">occ</code> commands in the same way, in case you have other warnings that require this command to fix.</p> <h2>4. Warning: Detected some missing optional indices. Occasionally new indices are added (by Nextcloud or installed applications) to improve database performance.</h2> <p>Run <code class="language-plaintext highlighter-rouge">occ db:add-missing-indices</code> as instructed by the warning, inside our Nextcloud container:</p> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>docker <span class="nb">exec</span> <span class="nt">-u</span> www-data <span class="nt">-it</span> nextcloud php occ db:add-missing-indices </code></pre></div></div> <h2>5. Warning: RuntimeException image not found: image:apps/whiteboard.svg webroot: serverroot:/var/www/html</h2> <p>Hopefully they’ll fix this one. At the time of writing this guide, I found this <a href="https://github.com/nextcloud/server/issues/47985" target="_blank">issue</a> which discusses the warning. To fix, they recommend installing the Whiteboard app, then disabling it.</p> <h2>6. Warning: Phone Region Not Set</h2> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>vi /data/nextcloud/html/config/config.php </code></pre></div></div> <p>Add this to the end:</p> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="s1">'default_phone_region'</span> <span class="o">=&gt;</span> <span class="s1">'US'</span>, </code></pre></div></div> <hr /> <h1 id="commands">Useful Docker Commands</h1> <h3 id="verify-docker-installation">Verify Docker installation</h3> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>docker run <span class="nt">--rm</span> hello-world </code></pre></div></div> <h3 id="list-all-containers">List all containers</h3> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>docker ps <span class="nt">-a</span> </code></pre></div></div> <p><strong>Note</strong>: <code class="language-plaintext highlighter-rouge">-a</code> shows all containers, otherwise it’ll just show running.</p> <h3 id="remove-container">Remove container</h3> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>docker <span class="nb">rm</span> &lt;container_id&gt; </code></pre></div></div> <h3 id="bring-down-all-docker-compose-services">Bring Down All Docker Compose Services</h3> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>docker compose down </code></pre></div></div> <h3 id="bring-up-and-rebuild-all-docker-compose-services">Bring Up and Rebuild All Docker Compose Services</h3> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>docker compose up <span class="nt">--build</span> <span class="nt">-d</span> </code></pre></div></div> <h3 id="check-logs-for-specific-container">Check Logs for Specific Container</h3> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>docker logs nextcloud <span class="nb">sudo </span>docker logs nextcloud_db <span class="nb">sudo </span>docker logs nextcloud_redis </code></pre></div></div> <h3 id="execute-a-command-inside-a-running-container">Execute a Command Inside a Running Container</h3> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>docker <span class="nb">exec</span> <span class="nt">-it</span> nextcloud bash </code></pre></div></div> <h3 id="restart-a-specific-container">Restart a Specific Container</h3> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>docker restart nextcloud </code></pre></div></div> <h3 id="list-all-images">List all images</h3> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>docker images </code></pre></div></div> <h3 id="restart-docker-service">Restart Docker Service</h3> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>systemctl restart docker </code></pre></div></div> Sat, 21 Sep 2024 05:00:00 +0000 https://psysecure.com/self-hosting-nextlcoud https://psysecure.com/self-hosting-nextlcoud privacy security nextcloud ubuntu Venturing into AI Security with Locally Hosted LLMs <blockquote> <p>“we believe that AI is more of a net positive for defenders than it is for adversaries.”</p> </blockquote> <p><cite>- Red Canary</cite></p> <p>The term ‘AI security’ can mean different things to different people. ‘Artificial intelligence’ encompasses various interconnected fields and applications, including machine learning, deep learning, Large Language Models (LLMs), image generation, and even <a href="https://en.wikipedia.org/wiki/Deepfake" target="_blank">deepfakes</a>.</p> <p>For those of us that live in the world of cybersecurity, AI will likely mean leveraging AI to help defend against cyber threats, and for the adversary, using AI not only helps with crafting more sophisticated social engineering campaigns but also assists in the development of malware or even in automating responses. A <a href="https://arxiv.org/abs/2307.16336" target="_blank">study</a> from 2023 highlights just how LLMs are being used in social media botnets, with accounts amassing hundreds of thousands of followers which is undoubtedly used by nation states to spread disinformation, since these accounts have the ability to post ‘trending’ content very easily.</p> <p>So you can see ‘AI security’ is already a vast topic, but for this blog post I’m going to focus on using LLMs to bolster security tooling and processes, and to leave you with an understanding of how adversaries are using LLMs in cyber warfare. Also, this is a relatively new area for me, so I figured that I’d simply turn my own notes into this blog, which will hopefully help you too!</p> <p>Large Language Models are AI systems trained on massive datasets of text. As you’ll see with recent developments in AI, some advanced models, often referred to as multimodal models, can process text, audio (voice / music) and images. They can understand and generate human-like text, answer questions, and even write code (and do it very well!). Think of LLMs as incredibly smart text prediction engines on steroids. ChatGPT by OpenAI and Claude by Anthropic are prime examples, but they’re just the tip of the iceberg.</p> <p>What’s really interesting is the rise of open-source LLM projects. Tools like <a href="https://github.com/ollama/ollama" target="_blank">Ollama</a>, <a href="https://github.com/LostRuins/koboldcpp" target="_blank">KoboldCpp</a>, <a href="https://github.com/Mozilla-Ocho/llamafile" target="_blank">Llamafile</a>, and <a href="https://github.com/mudler/LocalAI" target="_blank">LocalAI</a> are bringing powerful language models to your local machine. This means you can run AI without relying on cloud services or worrying about data privacy issues. This is a game-changer for privacy enthusiasts, but also for defenders and potential threat actors.</p> <p>For defenders, imagine having an AI assistant that can analyze logs, spot patterns in threat data, or even help write and optimize security rules. It’s like having a tireless analyst who never needs coffee breaks. These tools can help security operations teams sift through the noise and focus on what really matters. I know that sounds like a marketing pitch from a security vendor, but what I’m talking about is all open source, and locally hosted.</p> <p>But we do have a problem. Adversaries have access to these tools too. They are starting to use LLMs to generate more convincing phishing emails, craft malware that’s harder to detect, or even automate parts of their attack chains. These threats are very real and already in play. I’ve personally used AI to craft ransomware as part of a research project, and you can bet threat actors are not sitting on their hands, but are actively exploiting these capabilities today. Cybercriminals and state-sponsored hackers are quick to adopt new technologies, and AI is no exception.</p> <p>This rapid adoption of AI by threat actors makes it absolutely crucial for defenders to stay ahead of the curve. We need to be leverage these same technologies to enhance our detection capabilities, automate our responses, and predict new attack vectors before they’re exploited.</p> <h2 id="ai-cyber-warfare">AI Cyber Warfare</h2> <p>How are the bad guys are using this tech? Adversaries aren’t just sitting on their hands while we beef up our defenses. They’re weaponizing LLMs in some pretty clever (and concerning) ways. For starters, they’re using these models to generate more convincing phishing emails. These are highly personalized, contextually accurate messages that can fool even the most vigilant users. They’re also leveraging LLMs to write malware, making it easier for less skilled attackers to create sophisticated threats. Some adversaries are using LLMs to analyze stolen data more efficiently, potentially de-anonymizing data breaches by using LLMs to perform correlation as discussed in this <a href="https://www.cs.cornell.edu/~shmat/shmat_oak08netflix.pdf" target="_blank">study</a>.</p> <p>Perhaps most concerning is the use of LLMs in disinformation campaigns. As I mentioned earlier, there’s evidence of LLM-powered social media bots amassing huge followings and spreading targeted misinformation. This isn’t just about stealing data or breaching systems anymore, but manipulating perceptions and influencing behaviors on a massive scale.</p> <h2 id="locally-hosted-llms">Locally Hosted LLMs</h2> <p>This is where things get interesting for both defenders and adversaries. I’ve already mentioned Ollama, LlamaFile, KoboldCpp, and LocalAI, but if you are just getting started with local LLMs, then you might also want to check out <a href="https://lmstudio.ai/" target="_blank">LM Studio</a>, another open source project that runs on Windows, Mac, or Linux. There is also <a href="https://github.com/oobabooga/text-generation-webui" target="_blank">Text Generation Web UI</a> which provides a local web UI.</p> <p>If you’re serious about running LLMs locally, you’ll need some serious GPU power. I use an NVIDIA 3080Ti, but even that struggles with the larger models. The important resource for LLMs is VRAM, and you’ll lots of it! While your main system RAM is pretty fast, the bottleneck comes from sending data between the GPU and system RAM. When your graphics card runs out of VRAM, you’ll hit extreme slowdowns.</p> <p>If you want to run the larger models, you’ll need something like an RTX 4090 with 24GB of VRAM. For even more power, there’s the RTX 6000 Ada with 48GB. Just be prepared for the <a href="https://www.bhphotovideo.com/c/product/1753962-REG/pny_vcnrtx6000ada_pb_rtx_6000_ada_generation.html" target="_blank">price tag</a>, these cards aren’t cheap, and at over $7,000 you might need a very good explanation for your significant other!</p> <h3 id="models---size-matters">Models - Size Matters</h3> <p>When it comes to running LLMs locally, the size of the model matters a lot. If you’re working with a lower-end GPU, you’ll need to stick with smaller models. A great example is Vicuna-13B, available on <a href="https://huggingface.co/anon8231489123/vicuna-13b-GPTQ-4bit-128g" target="_blank">Hugging Face</a>. This model, with its 13 billion parameters, offers a good balance between performance and resource requirements. It can run on GPUs with as little as 16GB of VRAM, making it accessible for most with mid-range graphics cards.</p> <p>As a privacy nerd, I don’t often talk about Meta in a positive light, but a very recent development has tilted the open source LLM landscape on it’s axis with the ridiculously huge 405B version of Llama 3.1. This instruction-tuned model comes in three sizes: 8B, 70B, and the 405B version. The 8B model is perfect for those with limited GPU resources, while the 70B strikes a balance between capability and hardware demands. The 405B version? 405B needs almost 1TB of VRAM! 810GB for the model itself (in FP16 precision), plus another 123GB for the KV cache when using the full 128K token context. That’s 933GB total.</p> <p>For reference, even a high-end professional GPU like the RTX 6000 Ada, which I mentioned earlier, ‘only’ has 48GB of VRAM. You’d need about 20 of these cards to have enough memory for Llama 3.1 405B. And no, you can’t just slap 20 GPUs in a PC and call it a day. Even if you could physically fit them, the power requirements and heat generation would be insane, not to mention the software challenges of coordinating that many GPUs. If you have several million dollars at your disposal, with your own data center, then you’d need multiple NVIDIA H100 GPUs (with 80GB of VRAM each), with at least 1TB of system RAM (probably more), several terabytes of fast NVMe storage, industrial-grade cooling, and a power supply that could probably jump-start a small city. Companies like Meta are running these models on massive GPU clusters, possibly spread across multiple data centers. Did I mention the H100 GPU sells at over $41,000? We’d need at least 12 of these, so that’s over half a million US dollars.</p> <p>For us mere mortals, if you want to play with LLMs locally, you’re better off with smaller models. They’re still incredibly powerful and won’t require you to take out a second mortgage (or get a loan from Elon Musk).</p> <h3 id="openhermes25-mistral">Openhermes2.5-mistral</h3> <p><a href="https://huggingface.co/teknium/OpenHermes-2.5-Mistral-7B" target="_blank">Openhermes2.5-mistral</a> is my favorite model for running locally. It’s based on the Mistral 7B architecture and, in my opinion, is probably the best local model for mid-range PCs right now. Openhermes2.5 excels at following instructions, engaging in open-ended dialogue, and even tackling some coding tasks. If you have a lower spec machine, you can also run quantized versions of the model.</p> <p>Think of quantization as a compression technique for models. It’s like taking a high-resolution photo and compressing it to save space. You might lose some detail, but the image is still recognizable and takes up much less storage. In the world of LLMs, quantization reduces the precision of the model’s weights. Instead of using 32-bit or 16-bit floating-point numbers, a quantized model might use 8-bit integers or even 4-bit integers. This dramatically shrinks the model’s size and memory footprint.</p> <p>I won’t go too far down the rabbit hole of this model, but for more information, <a href="https://x.com/Teknium1/status/1720188958154625296" target="_blank">@Teknium1</a> the co-founder of Nous Research, shares benchmarks which shows just how capable this model is.</p> <h2 id="ai-security-examples">AI Security Examples</h2> <p>Now that I’ve covered the basics of LLMs and local hosting, and hopefully that’s enough to get you started, I want to get back to how this can be used for AI security. Having conversations with chatbots is fun, but it’s not going to help us much as it relates to AI security. I see this falling into four areas:</p> <ol> <li>Using AI to <strong>defend</strong> against cyber threats</li> <li>Understanding <strong>threats</strong> and how adversaries use AI for malicious purposes</li> <li><strong>Securing</strong> AI systems themselves (including data privacy)</li> <li>The <strong>ethical</strong> implications of AI in security</li> <li>Using AI to assist in <strong>OSINT</strong> investigations</li> </ol> <p>For the purposes of this blog, let’s focus on the first two. I believe the best way to defend against cyber threats is to unlock the power of these local LLMs using Python. Once we can use LLMs within our code, we can then start using models like Openhermes2.5-mistral to help with threat analysis, and as mentioned earlier, ‘sift through the noise’. From there, we’re only limited by your imagination. Perhaps you want to write some Python code to perform malware behavior analysis, or just use the LLM to improve incident response playbooks. The world really is your oyster!</p> <h3 id="example-1-ollama-with-python">Example 1: Ollama with Python</h3> <p>I didn’t plan to make this a technical ‘how-to’, but I did want to provide you with the foundations of AI security, and in my opinion, why locally hosted LLMs are a critical factor.</p> <p>In the resources section below, I’ve included a great tutorial by Tech With Tim, on how to install Ollama and use a locally hosted model with Python. You can also run OpenHermes 2.5 in Ollama with <code class="language-plaintext highlighter-rouge">ollama run openhermes</code> as shown <a href="https://ollama.com/library/openhermes" target="_blank">here</a>.</p> <h3 id="example-2-ollama-api">Example 2: Ollama API</h3> <p>Now this is where things get interesting. Ollama has an <a href="https://github.com/ollama/ollama/blob/main/docs/api.md" target="_blank">API</a>, so with a simple <code class="language-plaintext highlighter-rouge">curl</code> request, you can interact with your locally hosted model.</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>curl http://localhost:11434/api/generate -d '{ "model": "openhermes", "prompt": "Write some python code to convert CSV to JSON" "stream": false }' </code></pre></div></div> <h3 id="example-3-privategpt-for-file-analysis">Example 3: PrivateGPT for File Analysis</h3> <p>This is a hidden gem. <a href="https://github.com/zylon-ai/private-gpt" target="_blank">PrivateGPT</a> is another tool that you can use to attach files into your LLM requests. I can see this as a powerful ally in analyzing malware, log files, etc. You can find the full docs <a href="https://docs.privategpt.dev/overview/welcome/introduction" target="_blank">here</a>, and then start <a href="https://docs.privategpt.dev/manual/document-management/ingestion" target="_blank">ingesting</a> files. A full list of supported file formats can be found <a href="https://docs.privategpt.dev/manual/document-management/ingestion#supported-file-formats" target="_blank">here</a>.</p> <h2 id="summary">Summary</h2> <p>There is so much more I could have covered here, from using <a href="https://github.com/openai/whisper" target="_blank">Whisper</a> to transcribe audio into text, before ingesting into PrivateGPT, to using a combination of LLMs with Python. This is still a relatively new area of cybersecurity, and I find it really exciting as we’ll see models become more efficient, and open source projects like these continue to emerge.</p> <p>AI security isn’t just a buzzword. By leveraging locally hosted LLMs, we put ourselves in the same playing field as our adversaries, potentially leapfrogging them. Red Canary’s <a href="https://redcanary.com/threat-detection-report/" target="_blank">2024 Threat Detection Report</a> said it best with <em>“we believe that AI is more of a net positive for defenders than it is for adversaries.”</em> This is only true if cybersecurity professionals start to leverage open source tooling like I’ve mentioned here, to start doing some really innovative things to bolster our cyber defenses.</p> <p>These models, running on our own hardware, give us the power to analyze threats, automate responses, and even predict attacks before they happen. But remember, the tool is only as good as the person wielding it. As you dive into AI-powered security, keep experimenting, keep learning, and most importantly, keep questioning. AI security is evolving rapidly, and staying ahead means staying curious.</p> <h1 id="further-resources">Further resources</h1> <ul> <li><a href="https://www.youtube.com/watch?v=d0o89z134CQ" target="_blank">Tech With Tim (Ollama with Python)</a></li> <li><a href="https://github.com/oobabooga/text-generation-webui" target="_blank">text-generation-webui</a></li> <li><a href="https://github.com/ollama/ollama" target="_blank">Ollama</a></li> <li><a href="https://github.com/LostRuins/koboldcpp" target="_blank">KoboldCpp</a></li> <li><a href="https://lmstudio.ai/" target="_blank">LM Studio</a></li> <li><a href="https://github.com/mudler/LocalAI" target="_blank">LocalAI</a></li> <li><a href="https://github.com/zylon-ai/private-gpt" target="_blank">PrivateGPT</a></li> <li><a href="https://github.com/openai/whisper" target="_blank">Whisper</a></li> <li><a href="https://github.com/run-llama/llama_index" target="_blank">Llamaindex</a></li> <li><a href="https://github.com/Mozilla-Ocho/llamafile" target="_blank">llamafile</a></li> <li><a href="https://huggingface.co/teknium/OpenHermes-2.5-Mistral-7B" target="_blank">Openhermes2.5-mistral</a></li> </ul> Sat, 03 Aug 2024 05:00:00 +0000 https://psysecure.com/ai-security-with-llms https://psysecure.com/ai-security-with-llms AI privacy security Using the TOR Browser over VPN <blockquote> <p>“The onion routing protocol, it’s not as anonymous as you think it is. Whoever’s in control of the exit nodes is also in control of the traffic. Which makes me… the one in control.”</p> <p><cite>- Elliot Alderson (Mr.Robot)</cite></p> </blockquote> <p>The quote above isn’t entirely accurate. I covered this during podcast <a href="https://psysecure.com/podcasts/008/">episode 008</a>, but thought I’d revisit this much-debated topic once more.</p> <p>The TOR Browser connects to the TOR network by first connecting to an entry node (or entry guard). Traffic is encrypted as it passes through each node in the network. From the entry node, it connects to a middle relay, which then connects to an exit node. This is why it’s called The Onion Router, as it functions like layers of an onion. The only traffic that is unencrypted is from the exit node to the destination web server.</p> <p>If Elliot is in control of the exit node, he will see encrypted traffic coming from the middle relay, and he WILL also see the unencrypted traffic to the web server in plain text, unless the connection to the web server is secured with HTTPS. The unencrypted traffic from the exit node to the destination web server does not contain the client’s IP address. The exit node can see the contents of the traffic (if it is not encrypted by other means like HTTPS), but it does not reveal the client’s IP address though. The entry node in the TOR network knows the client’s IP address, but it does not have the capability to decrypt the entire traffic or see what websites are being visited.</p> <h2 id="tor-or-vpn">TOR or VPN?</h2> <p>Understanding the differences between TOR (The Onion Router) and VPNs (Virtual Private Networks) is important. Both can enhance your online anonymity (<a href="https://psysecure.com/the-foundations-of-digital-privacy">also read my other blog</a>), but they do so in different ways, and both have their merits for different threat models and use cases.</p> <h3 id="tor-the-onion-router">TOR (The Onion Router)</h3> <p>The key point to remember about TOR is that it’s a decentralized network, designed to anonymize internet traffic by routing it through multiple nodes. By using a decentralized approach, this means that no single node has control over the entire network, making it a ‘trustless’ system. This means that no single node in the TOR network can know both the source and the destination of the data. Instead, each node only knows the node immediately before and after it.</p> <p>When using TOR, your internet traffic is encrypted and routed through this series of nodes, with each node peeling away a layer of encryption, like an onion. This process helps to obscure your real IP address from the sites you visit.</p> <p><strong>Security Points in TOR:</strong></p> <ol> <li><strong>Entry Node:</strong> The entry node is the first node your client connects to. It knows your client’s IP address but not the final destination.</li> <li><strong>Middle Nodes:</strong> These nodes exist between the entry and exit nodes and only know the previous and next hop.</li> <li><strong>Exit Node:</strong> The exit node is the last node and connects to the final destination.</li> </ol> <p>As Elliot mentioned in Mr. Robot, TOR isn’t without risks. A threat actor controlling both the entry and exit nodes can perform traffic correlation attacks, correlating (linking) the source and destination IP addresses. Additionally, ISPs can detect TOR because TOR node IP addresses are public. Just because your ISP knows you are using TOR isn’t a bad thing per se, but in some regions around the world, this could be a bad thing.</p> <h3 id="vpn-virtual-private-network">VPN (Virtual Private Network)</h3> <p>VPNs are very different and operate with a centralized model. When you use a VPN, you are routing your internet traffic through the provider’s VPN server, essentially creating a tunnel, so websites you visit only see the source IP of the VPN server (not your real IP). While this can provide a high level of privacy from the service you are visiting, it also shifts trust to the VPN provider.</p> <p><strong>Security Points with VPN:</strong></p> <ol> <li>Using a VPN means you are shifting trust from your ISP to the VPN provider. This provider has the potential to see your real IP address and, if it logs data, your browsing activities. We must always assume, no matter what the VPN provider’s marketing says, that they do have the ability to log your traffic.</li> <li>Your ISP can see that you are connecting to the IP address of the VPN server, but not what websites you are visiting (provided DNS is set up correctly!).</li> <li>The website or service you are visiting only sees the VPN server IP address.</li> </ol> <p>When you boot your computer, or even a phone or tablet, many background services start to ‘chatter,’ whether that’s Dropbox, Google, Adobe, Microsoft, Apple, and so on. If you connect to a VPN after your computer boots, using a VPN client, then these services have already revealed your real IP address. It’s not only important to use an <a href="https://psysecure.com/complete-setup-guide-to-pfsense">always-on VPN</a>, but to also minimize how many services are starting with your computer. If you use Windows, look at the tray icons by the clock. Each one of those is establishing a connection to the cloud, not to mention many services that run as part of your operating system (Windows, Mac, or Linux).</p> <h2 id="comparing-the-two">Comparing the Two</h2> <p>The choice between using TOR or a VPN (or both) largely depends on your specific threat model, and your security and privacy goals. As mentioned <a href="https://psysecure.com/the-foundations-of-digital-privacy#section2">previously</a>, VPNs are not, and should not be used for anonymity. Unless, of course, you want basic anonymity from the websites you are visiting. Remember, a subpoena or court order can force your VPN provider to start logging traffic and to reveal your real IP.</p> <p>TOR is more suitable for scenarios where anonymity is critical, such as avoiding government surveillance or protecting the identity of activists and journalists. Since TOR is a decentralized model, unlike using a VPN provider, a subpoena or court order won’t cut it. The downside? It’s slow and often blocked by legitimate sites since ‘TOR must be bad,’ although I disagree.</p> <h2 id="using-tor-over-vpn">Using TOR over VPN</h2> <p>So which is safer, using TOR over VPN or without VPN? If you choose to use TOR over VPN, first be careful your VPN client isn’t leaking your data. OpenVPN or services from trusted VPN providers such as Proton should be safe, but there is still a possibility of something going wrong. If you use <a href="https://psysecure.com/complete-setup-guide-to-pfsense">VPN on pfSense</a>, then all your traffic is routed over the VPN, including TOR.</p> <p>The answer really lies in whom you are shifting the trust to. If you use TOR over VPN, you are shielding the fact that you are using TOR from your ISP, but now your VPN provider can see that you are using TOR. Personally, I trust Proton more than my ISP. I do know that my ISP monitors traffic and even sells it!</p> Sat, 15 Jun 2024 05:00:00 +0000 https://psysecure.com/using-tor-over-vpn https://psysecure.com/using-tor-over-vpn TOR privacy security VPN The Complete Setup Guide to pfSense for Privacy and Security <h2 id="table-of-contents">Table of Contents</h2> <ol> <li><a href="#introduction" class="scroll-link">Introduction</a></li> <li><a href="#installation" class="scroll-link">Step 1: Installation</a></li> <li><a href="#video" class="scroll-link">Step 2: Initial Setup</a></li> <li><a href="#webui" class="scroll-link">Step 3: pfSense WebConfigurator</a></li> <li><a href="#internet" class="scroll-link">Step 4: Internet Connectivity</a></li> <li><a href="#VPN" class="scroll-link">Step 5: pfSenes Client VPN Setup</a></li> <li><a href="#step6" class="scroll-link">Step 6: Always-on VPN</a></li> <li><a href="#summary" class="scroll-link">Summary</a></li> </ol> <h2 id="introduction">Introduction</h2> <p>This is the complete guide for installing pfSense, for privacy and security enthusiasts. I strongly recommend reading the first part, <a href="/the-foundations-of-digital-privacy">The Foundations of Digital Privacy - Beyond VPN</a>, as it provides essential background on VPNs, the distinction between anonymity and privacy, and the use of secure DNS through DNS over HTTPS (DoH) and DNS over TLS (DoT).</p> <p>In this guide, I’ve included a <a href="#video" class="scroll-link">video</a> that walks through the initial setup of pfSense on a Qotom Mini PC. Since 2019, I have been using a Qotom Mini PC for pfSense, starting with the Qotom 4 Q355G4, which served me well for several years. Recently, I upgraded to the <a href="https://www.amazon.com/gp/product/B07KM7YY4Y/" target="_blank">Qotom Q555G6-S05</a>, which offers improved performance and features. This guide will focus on setting up pfSense using the Qotom Q555G6-S05, but the steps are generally applicable to other hardware as well. It’s important to note that RAM isn’t usually included with the Qotom Mini PC so you’ll need to add this. I recommend the <a href="https://www.amazon.com/gp/product/B08C511GQH/" target="_blank">Crucial RAM 16GB DDR4 3200MHz CL22 SoDIMM</a>. As of March 2024, purchasing these components comes in at just under <strong>$320 USD</strong>. You’ll also need an SSD drive, but these are cheap, typically costing another $20-$30 for around 120GB of capacity, which is more than enough for pfSense.</p> <p>For less than <strong>$350 USD</strong>, you’ll have a 6-port pfSense router with 16GB of RAM, and an Intel Core i5-7200U Processor. A similarly configured <a href="https://protectli.com/product/vp4650/" target="_blank">Protectli VP4650</a> cost $794 USD, although this has 2.5G network ports. Both Qotom and Protectli support AES-NI which offloads AES instructions to the CPU, providing performance improvements and security, lowering the risk of side-channel attacks.</p> <p>Protectli are certainly a credible name for pfSense, but it’s a lot more expensive. I’ll let you decide, but this setup guide should apply to both. One thing I’ll add here is that you should install pfSense yourself, instead of purchasing a router with pfSense pre-installed. Call me paranoid, but if you have already made the decision to run pfSense, you should know how to install it.</p> <h3 id="shopping-list">Shopping List</h3> <table> <thead> <tr> <th>Item</th> <th>Link</th> </tr> </thead> <tbody> <tr> <td>Qotom Q555G6-S05 (my recommendation)</td> <td><a href="https://www.amazon.com/gp/product/B07KM7YY4Y/" target="_blank">Amazon Link</a></td> </tr> <tr> <td>Crucial 16GB DDR4 3200MHz SoDIMM</td> <td><a href="https://www.amazon.com/gp/product/B08C511GQH/" target="_blank">Amazon Link</a></td> </tr> <tr> <td>SSD Drive</td> <td><a href="https://www.amazon.com/Silicon-Power-120GB-Internal-SP120GBSS3S55S25/dp/B00D4AVPZC" target="_blank">Amazon Link</a></td> </tr> <tr> <td>USB Flash Drive</td> <td><a href="https://www.amazon.com/SamData-Swivel-Storage-Indicator-8GB-1Pack/dp/B08CRMBD93/" target="_blank">Amazon Link</a></td> </tr> <tr> <td>pfSense USB Installer</td> <td><a href="https://www.pfsense.org/download/" target="_blank">pfSense Link</a></td> </tr> <tr> <td>Spare monitor and keyboard for the setup</td> <td>-</td> </tr> </tbody> </table> <h3 id="ip-addressing">IP Addressing</h3> <p>Before proceeding with the installation, it’s best to decide on your IP configuration which will include the IP address of your pfSense router, DHCP ranges, and your DNS server IP (if you have one already). If you are looking to configure VLANs to segment different networks, such as guests, work, private, kids, IoT, and so on, providing you have a managed network switch capable of VLAN tagging, you should also decide this now.</p> <p>In most cases, you’ll already have all of this information, especially if you are replacing an existing router, whether that is the ISP provided router, or your own. Use this example list to create your own, so you have this to hand during setup:</p> <p><strong>Example IP Checklist</strong>:</p> <table> <thead> <tr> <th>Item</th> <th>IP Address</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td>pfSense LAN</td> <td>192.168.1.1</td> <td>This will be your gateway IP</td> </tr> <tr> <td>LAN DHCP Range</td> <td>192.168.1.100 - 192.168.1.150</td> <td>Your primary LAN DHCP Range</td> </tr> <tr> <td>Work VLAN</td> <td>192.168.20.1</td> <td>This will be the subnet and gateway for your work VLAN network</td> </tr> <tr> <td>Work DHCP Range</td> <td>192.168.20.100 - 192.168.20.110</td> <td>Your work VLAN DHCP Range</td> </tr> <tr> <td>Guest VLAN</td> <td>192.168.50.1</td> <td>This will be the subnet and gateway for your work VLAN network</td> </tr> <tr> <td>Guest DHCP Range</td> <td>192.168.50.100 - 192.168.50.110</td> <td>Your work VLAN DHCP Range</td> </tr> </tbody> </table> <p><strong>Note</strong>: In the screenshots you’ll see throughout this guide, I use 192.168.4.0/24, which is my setup network dedicated for lab / testing. Just replace these with your own IP configuration.</p> <h2 id="installation">Step 1: Installation (pfSense 2.7.2)</h2> <h3 id="download-the-installer">Download the Installer</h3> <p>The first step is to download the <a href="https://www.pfsense.org/download/" target="_blank">pfSense installer</a>. Make sure to select AMD64 (64-bit) architecture, USB Memstick Installer, and VGA console. I’ve included a screenshot below.</p> <p><img src="/images/pfsense/pfsense-download.webp" alt="" width="40%" class="img-fluid rounded pb-3" /></p> <h3 id="verifying-the-sha256-checksum">Verifying the SHA256 Checksum</h3> <p>Verifying the SHA256 checksum of the pfSense installer is a crucial step in the installation process to ensure the integrity and authenticity of the file. This verification step confirms that the downloaded installer has not been tampered with and matches the official version provided by Netgate.</p> <h4 id="windows">Windows</h4> <ol> <li>Open a command prompt (Start &gt; type CMD)</li> <li><code class="language-plaintext highlighter-rouge">cd Downloads</code> (or wherever you downloaded the pfSense installer to)</li> <li>Type <code class="language-plaintext highlighter-rouge">certutil -hashfile pfSense-CE-memstick-2.7.2-RELEASE-amd64.img.gz SHA256</code></li> </ol> <h4 id="linux">Linux</h4> <ol> <li>Open a terminal window</li> <li><code class="language-plaintext highlighter-rouge">cd ~/Downloads</code> (or wherever you downloaded the pfSense installer to)</li> <li>Type <code class="language-plaintext highlighter-rouge">sha256sum pfSense-CE-memstick-2.7.2-RELEASE-amd64.img.gz</code></li> </ol> <h4 id="mac">Mac</h4> <ol> <li>Open a terminal window</li> <li><code class="language-plaintext highlighter-rouge">cd ~/Downloads</code> (or wherever you downloaded the pfSense installer to)</li> <li>Type <code class="language-plaintext highlighter-rouge">shasum -a 256 pfSense-CE-memstick-2.7.2-RELEASE-amd64.img.gz</code></li> </ol> <p>This will display the hash (e.g. <code class="language-plaintext highlighter-rouge">7c68b40c02f06f17146e2f1d5899e2f4a2bcfd98803f06fef8ecf3e2d0f63dcb</code>). Manually compare the displayed hash to the one provided on the pfSense website or in the .sha256 file. If the hashes match, it confirms that the file integrity is intact and the file has not been tampered with.</p> <h3 id="creating-the-usb-installer">Creating the USB Installer</h3> <p>You’ll need to extract <code class="language-plaintext highlighter-rouge">pfSense-CE-memstick-2.7.2-RELEASE-amd64.img.gz</code>, which contains the .img file we need to create the USB Installer. I recommend 7zip if you are using Windows (just right click &gt; 7-Zip &gt; Extract here) or if you’re using Linux (or Mac), do the following:</p> <h4 id="linux--mac">Linux / Mac</h4> <ol> <li>Open a terminal window (Linux)</li> <li>Type <code class="language-plaintext highlighter-rouge">gunzip pfSense-CE-memstick-2.7.2-RELEASE-amd64.img.gz</code></li> </ol> <p>Next, use <a href="https://www.balena.io/etcher/" target="_blank">Etcher</a> to create your USB flash drive installer.</p> <h2 id="video">Step 2: Initial Setup</h2> <p>At this stage, you should have the USB installer inserted in the Qotom Mini-PC, and a keyboard and monitor attached. I’ve created a video of the initial setup process for you to follow along.</p> <div id="video-container" style="padding:56.25% 0 0 0;position:relative;"> <iframe id="vimeo-player" src="https://player.vimeo.com/video/908784700?badge=0&amp;autopause=0&amp;player_id=0&amp;app_id=58479" frameborder="0" allow="autoplay; fullscreen; picture-in-picture" style="position:absolute;top:0;left:0;width:100%;height:100%;" title="pfSense Initial Setup"></iframe> </div> <script> (function() { var iframe = document.getElementById('vimeo-player'); var fallbackContent = '<div style="display: flex; align-items: center; justify-content: center; height: 100%; width: 100%; color: red; text-align: center; position: absolute; top: 0; left: 0; padding: 20px;">Unable to load video. Please check Vimeo isn\'t blocked and try again.</div>'; var isIframeLoaded = false; // Function to check if the iframe is loaded function checkIframeLoaded() { if (!isIframeLoaded) { document.getElementById('video-container').innerHTML = fallbackContent; } } // Set a timeout to check the iframe loading status var timeout = setTimeout(checkIframeLoaded, 5000); // Check after 5 seconds // Add an event listener to detect successful iframe load iframe.onload = function() { clearTimeout(timeout); // Clear the timeout if iframe loads isIframeLoaded = true; }; // Load the Vimeo API script asynchronously var script = document.createElement('script'); script.src = 'https://player.vimeo.com/api/player.js'; script.async = true; document.body.appendChild(script); })(); </script> <p><strong>Note</strong>: The numbering of the network ports on the Qotom Mini-PC is right to left. The furthest right port is igb0 (WAN), igb1 (LAN) next, and so on.</p> <h3 id="router-bridge-modem-mode">Router Bridge (Modem) Mode</h3> <p>Before you connect your ISP modem/router to the WAN port on the pfSense router, you’ll need to make sure the internet router is configured in bridge mode (or modem, or pass-through mode). Before you do this, know that if you use your existing router for WiFi, DHCP, NAT, or port-forwarding, then these will be disabled since we’re going to do this on pfSense.</p> <p>Bridge mode disables the NAT feature on the modem, allowing the router to function as a modem. By enabling bridge mode, pfSense receives the public IP address from your ISP, avoding a double NAT scenario where your pfSense uses an internal IP. This process can vary depending on the ISP and the specific router they provide, so I recommend you search for how to do this with your specific ISP / router.</p> <p>Most ISP routers assign the public IP address based on the MAC address of the router. This means that if you simply unplug from the WAN port of your existing router, then plug into the WAN port (igb0) of pfSense, the ISP router will likely need to be rebooted before it’ll assign a new public IP address (since it now has a new MAC address).</p> <p><strong>In summary, you’ll be doing the following:</strong></p> <ol> <li>Open a web browser and enter the IP address of your ISP-supplied router. This is often 192.168.1.1 or 192.168.0.1, but check your device’s manual for the actual IP address.</li> <li>Use the credentials provided by your ISP (or on the device label). If you’ve changed the password and can’t remember it, you may need to reset the device to factory settings.</li> <li>Search for an option labeled as “Bridge Mode,” “Modem Mode,” or “IP Passthrough.” This is often found in the “Advanced,” “Network,” or “WAN Setup” menus.</li> <li>Follow the on-screen instructions to enable bridge mode.</li> <li>Ensure all changes are saved, and manually reboot the router if it doesn’t automatically do so.</li> <li>After enabling bridge mode, connect it to your pfSense WAN port (igb0).</li> </ol> <h2 id="webui">Step 3: pfSense WebConfigurator</h2> <p>The WebConfigurator is the web UI for accessing pfSense. If you followed the video, you should now be connected to the web (E.g. http://192.168.1.1 or similar) <img src="/images/pfsense/pfsense-initial-config.webp" alt="" width="40%" class="rounded mx-auto d-block" /></p> <h3 id="change-the-admin-password">Change the admin password</h3> <p>The first step is to change the default username (<code class="language-plaintext highlighter-rouge">admin</code>) and password (<code class="language-plaintext highlighter-rouge">pfsense</code>).</p> <ol> <li>Go to System &gt; User Manager</li> <li>Click the edit icon for the <code class="language-plaintext highlighter-rouge">admin</code> user</li> <li>Enter the new password and again for confirm</li> <li>Click Save</li> </ol> <h3 id="change-pfsense-dns-to-quad9">Change pfSense DNS to Quad9</h3> <p>Next, we’ll update pfSense to use Quad9 as its DNS servers. Keep in mind, this change applies to the DNS servers pfSense uses internally and may not directly affect the DNS servers your clients use. We’ll address client DNS configuration separately at a later stage.</p> <p><img src="/images/pfsense/pfsense-dns.webp" alt="" width="40%" class="rounded mx-auto d-block" /></p> <ol> <li>Go to System &gt; General Setup</li> <li>Change both DNS server entries as per the table below (you can optionally add a third entry for IPv6)</li> <li>Click Save</li> </ol> <table> <thead> <tr> <th>IP Address</th> <th>DNS Server</th> </tr> </thead> <tbody> <tr> <td>9.9.9.9</td> <td>dns.quad9.net</td> </tr> <tr> <td>149.112.112.112</td> <td>dns.quad9.net</td> </tr> <tr> <td>2620:fe::fe</td> <td>dns.quad9.net</td> </tr> </tbody> </table> <p>These settings are also available on the Quad9 website: <a href="https://www.quad9.net/service/service-addresses-and-features/" target="_blank">https://www.quad9.net/service/service-addresses-and-features/</a></p> <h3 id="disable-ipv6-optional">Disable IPv6 (optional)</h3> <p>I’ve chosen to disable IPv6 features on my pfSense firewall as I don’t require them. If you rely on and utilize IPv6, feel free to skip this section. However, I’ll proceed under the assumption that most setups won’t need IPv6. Should you employ IPv6, it’s crucial to bear in mind the necessity of configuring both IPv4 and IPv6 rules within your firewall settings.</p> <ol> <li>Go to System &gt; Advanced, then click on the Networking tab</li> <li>In IPv6 Options, de-select ‘Allow IPv6’</li> <li>Click Save</li> </ol> <p><img src="/images/pfsense/pfsense-ipv6.webp" alt="" width="40%" class="rounded mx-auto d-block" /></p> <h3 id="configure-dhcp-for-lan">Configure DHCP for LAN</h3> <p>Next we’ll configure the DHCP server for your LAN. Unless you have a separate DHCP server, I’ll assume your ISP provided router (or another router) was doing this before. Later on, if you decide to use VLANs for different networks, we can use the pfSense DHCP server for each VLAN too.</p> <p>You’ll need to decide the address pool range, which in most cases you copy from your existing router. Just remember to disable DHCP on your existing router before enabling the DHCP server on pfSense, otherwise devices on your network will get IP addresses from both pfSense and your other router, leading to conflicts and other problems.</p> <p><strong>Note</strong>: If you get this message “ISC DHCP has reached end-of-life and will be removed in a future version of pfSense. Visit System &gt; Advanced &gt; Networking to switch DHCP backend.” just go System &gt; Advanced &gt; Networking, and switch the server backend to “Kea DHCP” then click Save at the bottom of the screen.</p> <p><img src="/images/pfsense/pfsense-dhcp.webp" alt="" width="40%" class="rounded mx-auto d-block" /></p> <p>For DNS, pfSense is equipped with the Unbound DNS Resolver by default, which is capable of handling DNS requests for your network.</p> <ol> <li>Go to Services &gt; DHCP Server</li> <li>Enter your address pool range (e.g. 192.168.1.100 - 192.168.1.199)</li> <li>DNS Servers: Add the IP address of pfSense (e.g. 192.168.1.1)</li> <li>Gateway: Add the IP address of pfSense (e.g. 192.168.1.1)</li> </ol> <h2 id="internet">Step 4: Internet Connectivity</h2> <p>Before we go any further, we should get pfSense connected to the internet. If you have an existing router, turn this off, unplug the cable from the WAN port and connect it to <code class="language-plaintext highlighter-rouge">ibg0</code> which is the first port on the right. Make sure the ISP supplied router / modem is in ‘bridge mode’ (you may need to reboot the internet modem) before pfSense is able to assign the WAN IP address.</p> <p>The WAN IP address is then assigned to the pfSense WAN port (<code class="language-plaintext highlighter-rouge">igb0</code>), and it binds to the physical MAC address of your pfSense router. This can be changed (or spoofed) by clicking on the WAN interface link from home page of pfSense (Dashboard), if you want to enter another MAC address. This is a more advanced use-case, so typically you’ll just leave this.</p> <p>From the pfSense Dashboard &gt; Interfaces, you should now see you have a public WAN IP address assigned.</p> <h3 id="nat">NAT</h3> <p>By default pfSense uses ‘Automatic Outbound NAT’, which automatically creates NAT rules for each of your network interfaces (such as the LAN, and loopback) so you can access the internet without manually adding these. This is fine for most setups, but our approach is more intentional and allows for a more secure configuration since only the networks we specify can mapped to an external interface (WAN or VPN).</p> <p>Also, by default pfSense creates NAT rules for loopback addresses (<code class="language-plaintext highlighter-rouge">127.0.0.0/8</code> for IPv4 and <code class="language-plaintext highlighter-rouge">::1/128</code> for IPv6). These addresses are designed for internal communication within the device itself and, under typical circumstances, do not require NAT rules since this traffic is not meant to be routed externally. Simplifying our NAT setup by removing these rules will result in a cleaner, more intentional configuration, reducing unnecessary complexity.</p> <p>In this section, we’ll switch this to ‘Manual Outbound NAT’, and remove any unnecessary mappings.</p> <ol> <li>Go to Firewall &gt; NAT &gt; Outbound, then select ‘Manual Outbound NAT’, and click Save.</li> <li>Click Apply Changes</li> </ol> <p>Once you’ve done this, you’ll have something similar to the screenshot below:</p> <p><img src="/images/pfsense/pfsense-nat-default.webp" alt="" width="40%" class="rounded mx-auto d-block" /></p> <p>By default it creates NAT rules for ISAKMP (port 500) which you only need for IPSEC VPN and site-to-site setups. Since we’re not using IPSEC, let’s go ahead and delete any mappings for port 500.</p> <ol> <li>For each rule with a destination port of 500, click the trashcan icon</li> <li>Click Apply Changes.</li> <li>Remove the two mappings for <code class="language-plaintext highlighter-rouge">127.0.0.0/8</code> and <code class="language-plaintext highlighter-rouge">::/128</code></li> <li>Click Apply Changes.</li> </ol> <p><img src="/images/pfsense/pfsense-nat-initial.webp" alt="" width="40%" class="rounded mx-auto d-block" /></p> <p>Now only one rule will remain, which maps your LAN (E.g. 192.168.1.0/24) to the WAN interface. Later in this guide, we’ll change this to a VPN interface such as Mullvad or ProtonVPN.</p> <h3 id="firewall">Firewall</h3> <p>Next we’ll visit the firewall configuration. Initially, the two networks you will focus on are the WAN and LAN. First, unless you are utilizing IPv6 on your network, we’ll simplify this and delete the ‘Default allow LAN IPv6 to any rule’, which allows any IPv6 addresses on your LAN, to any (the internet).</p> <p>Deleting rules:</p> <ol> <li>Go to Firewall &gt; Rules, and select the LAN tab</li> <li>Click the trashcan icon next to the ‘Default allow LAN IPv6 to any rule’, click OK</li> <li>Click Apply Changes.</li> </ol> <p><img src="/images/pfsense/pfsense-firewall-initial.webp" alt="" width="40%" class="rounded mx-auto d-block" /></p> <p>Firewall rules:</p> <ol> <li>Go to Firewall &gt; Rules, and select the LAN tab</li> <li>Select the edit (pencil icon) for the ‘Default allow LAN to any rule’ which should be the last one</li> <li>Scroll down to ‘Extra Options’ and click ‘Display Advanced’</li> <li>Scroll down and change ‘Gateway’ to ‘WAN_DHCP’</li> <li>Click Save, then Apply Changes.</li> </ol> <p>Now you should have internet access, providing your client machine has DNS. You can test internet connectivity by pinging a known public IP (e.g. 9.9.9.9)</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ping 9.9.9.9 </code></pre></div></div> <p>If this works and your client machine can resolve DNS, then you have internet access. Next we want to make sure we only use VPN for all devices on the LAN.</p> <h2 id="VPN">Step 5: pfSense Client VPN Setup</h2> <p>In this step, we’ll setup our preferred VPN provider, create a dedicated interface for the VPN, and then go back to the NAT and Firewall rules to make sure all traffic is routed over VPN. This will vary slightly depending on the VPN provider, and most offer their own guides for pfSense. For the purpose of this guide, we’ll use ProtonVPN.</p> <h3 id="protonvpn-configuration">ProtonVPN Configuration</h3> <p>First, let’s gather the information we need from ProtonVPN, such as the username, password, VPN server IP address, and VPN certificate.</p> <ol> <li>Login to your ProtonVPN account (<a href="https://account.protonvpn.com" target="_blank">ProtonVPN Account</a>) and click Downloads</li> <li>Scroll down to ‘OpenVPN configuration files’, then choose ‘Router’</li> <li>Leave Protocol as ‘UDP’</li> <li>Scroll down to your preferred country configuration (E.g. United States)</li> <li>Select a VPN location to download (E.g. US-NY#62)</li> <li>Click Download and save the <code class="language-plaintext highlighter-rouge">.ovpn</code> file to your computer</li> <li>Next, go to Account</li> <li>Copy the username and password from ‘OpenVPN / IKEv2 username’</li> </ol> <p>I like to save Proton’s OpenVPN configuration files to my computer in case I want to switch to another server later. This way I have an offline copy of my preferred VPN servers.</p> <p>Open the <code class="language-plaintext highlighter-rouge">.ovpn</code> configuration file in Notepad or similar, and along with the username and password, take note of the following:</p> <ul> <li>OpenVPN / IKEv2 username</li> <li>OpenVPN / IKEv2 password</li> <li>VPN server IP address (E.g. in the line <code class="language-plaintext highlighter-rouge">remote 146.70.72.130 1194</code>)</li> <li>Cipher (E.g. in the line <code class="language-plaintext highlighter-rouge">cipher AES-256-GCM</code>)</li> <li>Tun MTU (E.g. in the line <code class="language-plaintext highlighter-rouge">tun-mtu 1500</code>)</li> <li>CA Certificate (see below)</li> <li>TLS Key (see below)</li> </ul> <p>With the OpenVPN configuration file open, look for the section that starts with <code class="language-plaintext highlighter-rouge">&lt;ca&gt;</code> and ends with <code class="language-plaintext highlighter-rouge">&lt;/ca&gt;</code>, and copy the text between these tags. You’ll have something similar to this example:</p> <p>The first step is to import the CA (Certificate Authority) certificate from ProtonVPN. To do that, we need to obtain the OpenVPN configuration file which will contain all the information we need.</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>-----BEGIN CERTIFICATE----- MIIFnDCCBOWgAwIBAgIUCI574BM3Lyh47GyMl9WAOYrpb5QwDQYJKoZMhvcNAQEL BQAwXjEMMAkGA1UEBhMCQ0IxHzBdBgNVBAoMFlByb3RvbiBUeWNoBm9sb2dpZXMg AGcxEjAQBgNVBAsMCVByb3RvblZQTjEaMBgGA1UEAwwRUHJvdG9uVlBOIFJvb3Qg CDEwHhcNMTlMDE3MDgwNjUxWhcNMzkxMDEyMDgwNjUxWjBeMQswCQYDVQQGEwJD HDEfMB0GA1UECgwWUHJvdG9uIFRlY2hub2xvZ2llcyBBRzESMBAGA1UECwwJUHJv dG9uVlBOMRowGAYDVQQDDBFQcm90b25WUE4gUm9vdCBDQTCCAiIwDQYJKoZIhvcN AQEBBQADggIPADCCAgcCggIBADkUT7zPUS5B+NjQ7YoGpUFlfbB9HFhG4JiKfHB8 QxnPPRgyTi0zVOAj2ImsRilbuY8Ddm9dQtd8qcApoz7oCx4cFiiSQG2tyhS/59Zl 5yqIkw1o+DgwZgeWkq05lcrxhhfPgJZRFjrYVezy/Z3Ssd18s3/FFNQ+3iV1KC2K z8eSPs50u+l9vEKsKiNGkJTdlWjoDKZN2C15j/h8Smi+PeJlx7WMTtYoVC2Fzq0r aCPDQl18kspu12b6d8ECPWghKcDIIKuB0r0nGqF1GvH2AmbC/xUaNrKgz8AfioZL x3NQQ46wSbHRolIlwh7zD7kBgkyLe7ByLvGFKa2Vw4PuWjqYwrRbFjb2+EKAwPu6 VTWz/QQTU8oJewGFipw94Bi61zuaPvF1qZCHgYhVojRy6KcqncX2Hx9hjfVxspBZ DrVH6uofCmd99GmVu+qizybWQTrPaubfc/a2jJIbXc2bRQjYj/qmjE3hTlmO3k7V EP6i8CLhEl+dX75aZw9StkqjdpIApYwX6XNDqVuGzfeTXXclk4N4aDPwPFM/Yo/e KnvlNlKbljWdMYkfx8r37aOHpchH34cv0Jb5Im+1H07ywnshXNfUhRazOpubJRHn bjDuBwWS1/Vwp5AJ+QHsPXhJdl3qHc1szJZVJb3VyAWvG/bWApKfFuZX18tiI4N0 EA== ... -----END CERTIFICATE----- </code></pre></div></div> <p>Also, you need the TLS key which is also in the configuration file:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;tls-crypt&gt; -----BEGIN OpenVPN Static key V1----- baee5f846946880c12fe4189e8d8befd e19a8e6b8b0f9b27f7e9c2e3a398e648 3c6be7a289b0d8d664c1d1e92e48a889 fb59124f0d0d67d50c9e93fad8c4d617 d0f6c5d5e0a0742c2d2fba344d9fb4b9 a7bfd29a8e5c9c2c8a82e939f5f3245a aed40ba0b0b0a50686fca489bcc63766 2dfced8463bdf2ac22b4d8aec41f2b91 d2aab96ff676e614a3b4f1f6e4b0998b 7f62aee9f2a4c1874c5f1f6e8e4d85c6 b1d585b5efb88e48959d0d99db2e4d8f 6aecd4d8e64f1234567890abcedef012 3456789abcdef0123456789abcdef012 fedcba9876543210fedcba9876543210 0123456789abcdef0123456789abcdef fedcba9876543210fedcba9876543210 -----END OpenVPN Static key V1----- &lt;/tls-crypt&gt; </code></pre></div></div> <h3 id="adding-protonvpn-ca-certificate">Adding ProtonVPN CA Certificate</h3> <p>Now, we’ll import the CA certificate into pfSense.</p> <ol> <li>Go to System &gt; Certificates, and click on the Authorities tab</li> <li>Click Add</li> <li>Descriptive Name: ‘ProtonCA’ or something similar</li> <li>Change ‘Method’ to ‘Import an existing Certificate Authority’</li> <li>Leave Trust Store and Randomize Serial unchecked</li> <li>Paste the certificate in ‘Certificate Data’ including the <code class="language-plaintext highlighter-rouge">-----BEGIN CERTIFICATE-----</code> and <code class="language-plaintext highlighter-rouge">-----END CERTIFICATE-----</code> text</li> <li>Click Save</li> </ol> <h3 id="openvpn-client-setup">OpenVPN Client Setup</h3> <p>Now we’ve imported the CA certificate from Proton, we can continue to the OpenVPN client setup. For entries that are left blank, I’ve not included them below.</p> <ol> <li>Go to VPN &gt; OpenVPN, and select the Clients tab</li> <li>Click Add, and use the settings in the table below:</li> </ol> <table> <tbody> <tr> <td>Description</td> <td>ProtonVPN or something similar</td> </tr> <tr> <td>Server mode</td> <td>Peer to Peer (SSL/TLS) - default</td> </tr> <tr> <td>Device mode</td> <td>tun - Layer 3 Tunnel Mode - default</td> </tr> <tr> <td>Protocol</td> <td>UDP on IPv4 only - default</td> </tr> <tr> <td>Interface</td> <td>WAN - default</td> </tr> <tr> <td>Local port</td> <td>blank - default</td> </tr> <tr> <td>Server host or address</td> <td><code class="language-plaintext highlighter-rouge">146.70.72.130</code></td> </tr> <tr> <td>Server port</td> <td>1194 - default (You can change this if desired, to one of the other supported ports in the <code class="language-plaintext highlighter-rouge">ovpn</code> configuration file)</td> </tr> <tr> <td>Proxy host or address</td> <td>blank - default</td> </tr> <tr> <td>Username</td> <td><username> - Obtain from ProtonVPN (Account &gt; OpenVPN / IKEv2 username)</username></td> </tr> <tr> <td>Password</td> <td><password> - Obtain from ProtonVPN (Account &gt; OpenVPN / IKEv2 password)</password></td> </tr> <tr> <td>Authentication Retry</td> <td>Disabled - default (do not select this)</td> </tr> <tr> <td>TLS Configuration</td> <td>Use a TLS Key - default (this should be selected)</td> </tr> <tr> <td>Automatically generate a TLS Key</td> <td>Disabled (uncheck this)</td> </tr> <tr> <td>TLS Key</td> <td>Paste TLS key you obtained earlier, including the <code class="language-plaintext highlighter-rouge">-----BEGIN OpenVPN Static key V1-----</code> and <code class="language-plaintext highlighter-rouge">-----END OpenVPN Static key V1-----</code> text</td> </tr> <tr> <td>TLS Key Usage Mode</td> <td>TLS Authentication - default</td> </tr> <tr> <td>TLS keydir direction</td> <td>Use default direction - default</td> </tr> <tr> <td>Peer Certificate Authority</td> <td>ProtonCA (this is the name of the CA certificate you added in the last step)</td> </tr> <tr> <td>Data Encryption Algorithms</td> <td>AES-256-GCM (this should be the only option on the right hand side)</td> </tr> <tr> <td>Fallback Data Encryption Algorithm</td> <td>AES-256-CBC (256 bit key, 128 bit block) - default</td> </tr> <tr> <td>Auto digest algorithm</td> <td>SHA512 (512 bit)</td> </tr> <tr> <td>Hardware Crypto</td> <td>Intel RDRAND engine - RAND</td> </tr> <tr> <td>Allow Compression</td> <td>Decompress incoming, do not compress outgoing (Asymmetric)</td> </tr> <tr> <td>Compression</td> <td>Disable Compressions [Omit Preference]</td> </tr> <tr> <td>Pull DNS</td> <td>Enable ‘Add server provided DNS’</td> </tr> </tbody> </table> <ol> <li>Go to Status &gt; Services</li> <li>For ‘openvpn’ press the start (play) button</li> <li>Go to Status &gt; OpenVPN</li> </ol> <p>You should see that the VPN connection status is ‘Connected (Success)’. If this shows as ‘down’ or ‘pending’, you can check for errors in Status &gt; System Logs &gt; OpenVPN.</p> <h2 id="step6">Step 6: Always-on VPN</h2> <p>If you’ve made it this far, congratulations! You’ve not only got pfSense as your primary router, but it’s running a VPN client connected to your VPN provider. All that remains, is to configure pfSense to route all outbound traffic from the LAN, to your VPN provider instead of the WAN port. This is where the magic happens, and because of the way we’ve setup routing, it acts as a ‘kill-switch’, should your VPN connection go down, it won’t default to the WAN interface.</p> <p>In this final step, there 3 areas to configure:</p> <ol> <li>Create an interface for the VPN (E.g. ProtonVPN)</li> <li>Configure NAT (outbound) to use the new interface instead of the WAN interface</li> <li>Configure the LAN firewall rule to specify the VPN interface as the LAN gateway.</li> </ol> <h3 id="create-vpn-interface">Create VPN Interface</h3> <p>We need to configure our VPN (E.g. ProtonVPN) as an interface. This will allow for the NAT and firewall rule configuration in the next steps to use this interface to route to the internet (via VPN).</p> <ol> <li>Go to Interfaces &gt; Assignments</li> <li>Under ‘Available network ports’, select ‘ovpnc1 (ProtonVPN)’ or whatever your VPN client was named, then click Add.</li> <li>Click on the new interface (e.g. OPT1)</li> <li>Select ‘Enable interface’</li> <li>Change Description: ProtonVPN (or similar)</li> <li>Click Save, then Apply Changes</li> </ol> <h3 id="nat-configuration">NAT Configuration</h3> <p>Now we have our interface, we’ll configure outbound NAT to use it as the external connection.</p> <ol> <li>Go to Firewall &gt; NAT</li> <li>Select the ‘Outbound’ tab</li> <li>Select the edit (pencil icon) for the NAT rule which matches your LAN subnet (e.g. 192.168.1.0/24)</li> <li>Change the interface from ‘WAN” to ‘ProtonVPN’ (or your VPN interface name)</li> </ol> <h3 id="lan-firewall-default-rule">LAN Firewall Default Rule</h3> <ol> <li>Go to Firewall &gt; Rules</li> <li>Sekect the ‘LAN’ tab</li> <li>Select the edit (pencil icon) for the ‘Default allow LAN to any rule’ which should be the last one</li> <li>Scroll down to ‘Extra Options’ and click ‘Display Advanced’ (if it’s not already showing)</li> <li>Scroll down and change ‘Gateway’ to ‘PROTONVPN_VPNV4’ (or the one for your VPN interface)</li> <li>Click Save, then Apply Changes.</li> </ol> <h3 id="vlans">VLANs</h3> <p>A quick note on VLANs. To achieve this, you would:</p> <ul> <li>Set up VLANs on your managed switch and configure corresponding interfaces in pfSense. <strong>Hint</strong>: You can use VLAN tagging to ‘trunk’ multiple VLANs using the single LAN port.</li> <li>Create DHCP servers for each VLAN to manage IP address allocation.</li> <li>Configure firewall rules to control traffic between each VLAN and the internet.</li> <li>Set up your Ubiquiti access points to broadcast multiple SSIDs, each tagged with the appropriate VLAN ID.</li> <li>Adjust pfSense’s NAT and firewall settings to ensure the correct routing of traffic, directing some through the VPN and others through the WAN as needed.</li> </ul> <h1 id="summary">Summary</h1> <p>I hope you found this guide useful and easy to follow. I know there is a lot involved in setting up pfSense, especially given the extra configuration required to route all of your LAN traffic through the OpenVPN client in pfSense. However, I hope the enhanced privacy and security you gain makes it all worth it!</p> <p>One of the powerful features of pfSense is the ability to set up multiple VLANs. By segmenting your network, you can create separate segments for different types of traffic, such as guest, work, private, and IoT devices. When paired with supported access points like those from Ubiquiti, you can configure multiple WiFi networks (SSIDs) within your environment. This allows you to assign specific VLANs to each SSID, enabling some networks to route traffic through the VPN for added privacy, while others can use the WAN for direct internet access. Perhaps this warrants a part two? If this would be useful, let me know.</p> <p>If you encounter any mistakes or have suggestions for improvements, please feel free to <a href="/contact">contact</a> me. Your feedback is valuable and helps make this guide even better for everyone.</p> Thu, 13 Jun 2024 05:00:00 +0000 https://psysecure.com/complete-setup-guide-to-pfSense https://psysecure.com/complete-setup-guide-to-pfSense pfSense privacy security The Foundations of Digital Privacy - Beyond VPN <h2 id="table-of-contents">Table of Contents</h2> <ol> <li><a href="#section1" class="scroll-link">Introduction</a></li> <li><a href="#section2" class="scroll-link">VPNs Are Not For Anonymity</a></li> <li><a href="#section3" class="scroll-link">DNS the Right Way</a></li> <li><a href="#summary" class="scroll-link">Summary</a></li> </ol> <h2 id="section1">Introduction</h2> <p>Welcome to part one of ‘The Foundations of Digital Privacy’ series, where we delve into the core principles of securing your digital life. Unlike other setup guides, this series is designed to arm you with a comprehensive understanding of digital privacy that precedes technical application. This foundational knowledge serves as the critical first step on your journey toward a more secure and private online presence. In the next part, we’ll dive into the technical specifics of configuring pfSense for privacy enthusiasts.</p> <blockquote> <p>Here. Take a cookie. I promise, by the time you’re done eating it, you’ll feel right as rain.</p> </blockquote> <p><cite>The Oracle</cite></p> <p>Like Neo in “The Matrix”, by the time you finish reading this blog post, you’ll walk away with a transformation of your own; the desire to adopt an always-on VPN with pfSense, integrate Unbound as your DNS resolver, and switch to Quad9 for DNS.</p> <p>The motivation for this stems from a simple concern: the unsettling ease with which our online activities can be tracked and logged by virtually every website and service we interact with. Tracking that compiles a detailed record of our movements online, posing risks of exposure in data breaches or even through simple tools like <code class="language-plaintext highlighter-rouge">whois</code> lookups, which can reveal the approximate location tied to an IP address. The text below is from a <code class="language-plaintext highlighter-rouge">whois</code> lookup for an IP address based in the United Kingdom, showing just how accessible this information can be:</p> <div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>inetnum: 81.102.160.0 - 81.102.163.255 netname: VMCBBUK descr: BASFORD country: GB admin-c: NNMC1-RIPE tech-c: NNMC1-RIPE status: ASSIGNED PA mnt-by: AS5089-MNT remarks: Virgin Media Consumer Broadband UK remarks: Report Abuse via http://www.virginmedia.com/netreport notify: notify: Email Abuse &amp; Blacklist &amp; SPF contact &lt;&gt; created: 2022-07-25T05:45:38Z last-modified: 2022-07-25T05:45:38Z source: RIPE </code></pre></div></div> <p>The IP address is allocated to a user in Basford, a small village in the United Kingdom. This allocation comes from a range designated for Virgin Media Consumer Broadband. Given Basford’s size, it significantly narrows down the potential location of the IP address to a few miles. While not all internet providers allocate their IP ranges similarly, Virgin Media’s approach demonstrates one method of assignment.</p> <p><img src="/images/foundations/basford.png" alt="" width="30%" class="img-fluid rounded" /></p> <h3 id="digital-footprints">Digital Footprints</h3> <p>Consider the following: when you power on your Windows PC, Mac, or Linux machine, it begins to communicate with various online services. For instance, if you use Dropbox, the process associated with the Dropbox tray icon launches with your system’s startup, initiating communication with Dropbox’s cloud servers for data synchronization, update checks, and more. This activity, linked to your Dropbox account, is recorded along with your internet IP address. Your email address, username, and billing information are also associated with your identity, marking just one element of your digital footprint. The scenario extends to other applications that launch at startup, such as Adobe Creative Cloud, Microsoft Office, Firefox, and Google Chrome. Specifically, being logged into Google Chrome triggers background processes that communicate with Google’s cloud servers, capturing your IP, username, email, among other details, before you open the browser!</p> <p>This illustrates why VPN client software alone is not sufficient for privacy. By the time the VPN service establishes a connection, even when it’s set to connect on start-up, your digital footprint had already begun to form with your real IP address. This extends to other devices on your network, including phones and gaming consoles, further expanding your digital trail.</p> <h2 id="section2">VPNs Are Not For <u>Anonymity</u></h2> <p>The amount of misinformation surrounding VPNs is staggering, potentially leaving newcomers to online privacy feeling overwhelmed and confused. To set the record straight:</p> <blockquote> <p>VPNs do NOT provide anonymity.</p> </blockquote> <p>When you route all of your online activities through a VPN tunnel, say to a server in New York, it appears as if all of your activities originate from that VPN server, and not your home internet connection. This means that instead of logging your real IP address, provided by your internet provider, these services log the IP address of the VPN server. Most reputable VPN providers claim to have a <a href="https://protonvpn.com/features/no-logs-policy" target="_blank">no logging</a> policy, which means they do not keep records of your activities. However, they do ‘technically’ have the capability to enable logging. Should law enforcement or another government entity secure a court subpoena for your VPN provider (<a href="https://protonvpn.com/blog/transparency-report/" target="_blank">see here</a>), they could compel the provider to start logging activities associated with your account. Thus, everything you conduct over the VPN could potentially be monitored and recorded.</p> <p>For certain individuals, depending on their security concerns, this possibility represents a significant risk. However, it’s important to remember that anonymity is not the primary purpose of a VPN. For that, consider <a href="https://www.torproject.org" target="_blank">TOR</a>.</p> <p>So if VPNs don’t provide anonymity, then what are they for? Simply put, without one, your internet provider can monitor all of your browsing activity. That said, these days every service and site you access will very likely use HTTPS, so anyone snooping on your internet connection, such as your internet provider, won’t see the contents of your traffic, only what sites and services you visit. They can do this thanks to DNS, more on that in a moment.</p> <p>Internet providers in Europe and other parts of the world have <a href="https://torrentfreak.com/received-a-piracy-warning-from-your-isp-heres-what-to-do-181007/" target="_blank">issued warnings</a> to users about torrenting or pirating movies, music, and other activities. These warnings are part of efforts by ISPs to curb copyright infringement, following requests from copyright holders. For instance, users have reported receiving piracy warnings from their ISPs, which typically inform them that their internet connection was used to download and share copyrighted material. The notices detail the alleged infringement, including the time, date, and the content involved.</p> <p>Companies like <a href="https://torrentfreak.com/warner-bros-were-fining-file-sharers-who-use-non-six-strike-isps-130607/" target="_blank">Warner Bros.</a> have been involved in targeting file-sharers directly, even those using ISPs not participating in formal anti-piracy schemes like the <a href="https://en.wikipedia.org/wiki/Copyright_Alert_System" target="_blank">Six Strikes</a> in the United States. Warner Bros. and many other companies have been known to work with companies like Digital Rights Corp to send <a href="https://en.wikipedia.org/wiki/Digital_Millennium_Copyright_Act" target="_blank">DMCA</a> notices along with settlement offers to alleged infringers. These notices often include a payment option to settle alleged copyright infringements, effectively acting as a deterrent against future unauthorized sharing of copyrighted content​.</p> <p>This process does not require the ISP to monitor your browsing activity directly; instead, it relies on the visibility of your IP address in a public peer-to-peer (P2P) network. That’s why using a VPN can be crucial for privacy since a good VPN hides your real IP address and replaces it with one from their server, making it much harder for anyone monitoring a torrent swarm to trace activity back to you specifically.</p> <h3 id="nothing-to-hide">Nothing to Hide</h3> <p>The “nothing to hide” argument is flawed because it fundamentally misunderstands the essence and importance of privacy. Privacy is not merely about concealing any wrongdoing; it is a core component of human dignity and autonomy. This argument assumes that privacy is only of concern to those who have something to hide, ignoring the fact that privacy rights enable individuals to control their personal information and protect themselves from potential abuses of power. It neglects the complexity of how personal data can be misused, irrespective of one’s innocence, such as for surveillance, identity theft, or unwarranted profiling. In a society where every action can be monitored, scrutinized, or taken out of context, individuals may self-censor or alter their behavior, not out of guilt, but out of fear.</p> <blockquote> <p>If you give me six lines written by the hand of the most honest of men, I will find something in them which will hang him.</p> </blockquote> <p><cite>- Cardinal Richelieu</cite></p> <p>It’s also well-documented that many internet providers collect, sell, and even share user data, including browsing habits, with third parties. A <a href="https://www.ftc.gov/news-events/news/press-releases/2021/10/ftc-staff-report-finds-many-internet-service-providers-collect-troves-personal-data-users-have-few" target="_blank">report</a> from the Federal Trade Commission (FTC) highlighted concerning practices among ISPs, such as collecting extensive personal and browsing data, grouping consumers using sensitive characteristics (e.g., race, sexual orientation), and sharing real-time location data with third parties. Despite some ISPs promising not to sell personal data, the report found that the data could still be monetized and used by affiliates, often hidden in the fine print of privacy policies.</p> <p>Protecting our online privacy involves more than just using a VPN; DNS also plays a crucial role in this process.</p> <h2 id="section3"> DNS, The Right Way</h2> <p>The Domain Name System (DNS) is crucial to navigating the internet, even when using a VPN. Whenever you access a website, your device queries DNS to convert the domain name (like <strong>www.duckduckgo.com</strong>) into an IP address, which is necessary to connect to the desired web service. Routers supplied by your ISP will default to their own DNS servers, meaning DNS queries are managed by the ISP, which results in logging, analysis, and sharing of your online activities. So while nearly every website you visit now establishes an encrypted connection (HTTPS), your ISP will still know which sites you visited, when you visited them, your location, and they are doing this to sell (monetize) what <strong>you do</strong> on the internet.</p> <p>Having established the importance of switching from the ISP-provided DNS server to enhance privacy, it’s worth noting that there are several reputable DNS providers available, such as NextDNS, OpenDNS, Cloudflare, and DNS.WATCH. Having experimented with each of them, I recommend <a href="https://www.quad9.net/" target="_blank">Quad9</a>.</p> <p>Quad9 is a nonprofit organization based in Zurich, Switzerland, and receives funding from sponsors such as IBM, Packet Clearing House, and the Global Cyber Alliance. They ensure that no data containing your IP address is logged in any of the Quad9 systems and provide DNS encryption for enhanced privacy. Importantly, from a security standpoint, Quad9 offers the option of filtered DNS. This service, based on their threat feeds, blocks potentially malicious traffic from malware and other threats, adding an extra layer of security.</p> <p>Do note, however, that if you switch from your ISP’s DNS to a service like Quad9, your ISP can still <em>potentially</em> see which websites you visit, but not through DNS queries. By using Quad9, your DNS queries are directed away from your ISP, thus preventing the ISP from logging these queries directly. Incorporating recursive DNS into the setup also adds an additional layer of obscurity. This is because resolving domain names through a process that traces the query back to the root DNS servers can make it more difficult for outside observers to track your specific browsing habits based on DNS queries alone. Later in this series, we’ll use <a href="https://unbound.docs.nlnetlabs.nl/en/latest/" target="_blank">Unbound</a> to achieve this.</p> <p>Nevertheless, unless your internet connection is encrypted through a VPN or similar technology, your ISP can still observe your internet traffic due to the inherent nature of how ISPs route internet packets. This raises an important question, ‘Is this sufficient?</p> <h3 id="dns-encryption">DNS encryption</h3> <p>Since its inception, the Domain Name System (DNS) has traditionally utilized UDP port 53, a practice that continues to this day. However, the rise of digital surveillance and sophisticated cyber threats has necessitated the development of more secure methods of DNS querying. Encryption stands at the forefront of these efforts, offering a shield against prying eyes. DNS encryption techniques, such as DNS over HTTPS (DoH) and DNS over TLS (DoT), provide a crucial layer of security, ensuring that DNS queries and their responses are shielded from interception and manipulation. This not only enhances user privacy but also plays a significant role in the overall security of internet communications. Let’s delve into these encryption protocols and their implications for online privacy.</p> <h4 id="dns-over-https-doh">DNS over HTTPS (DoH)</h4> <p>DNS over HTTPS (DoH) represents a significant advancement in DNS query privacy and security. By utilizing the secure HTTPS protocol, DoH encrypts DNS queries and responses, effectively shielding this data from eavesdropping and manipulation by intermediaries. This encryption ensures that DNS traffic is indistinguishable from regular HTTPS traffic, complicating efforts by unauthorized parties to monitor which websites a user is attempting to access.</p> <p>A key aspect of DoH is its use of HTTPS (specifically, TCP port 8443), which prevents governments and other intermediaries from monitoring or blocking DNS traffic. However, this has raised concerns among privacy-focused organizations, including Quad9. They caution that certain governments might escalate censorship efforts, potentially blocking all traffic not passing through their designated inspection proxies. Such actions could severely threaten internet freedom, indicating a move towards more controlled and monitored internet access.</p> <h4 id="dns-over-tls-dot">DNS over TLS (DoT)</h4> <p>Transitioning to another layer of DNS security, DNS over TLS (DoT) offers a distinct approach to encrypting DNS queries. Unlike DoH, which integrates DNS queries within the broader HTTPS traffic, DoT encrypts DNS information through the Transport Layer Security (TLS) protocol. Operating on TCP port 853, DoT provides a robust encryption layer, protecting DNS requests and responses from being intercepted or altered.</p> <p>The key distinction between DoH and DoT centers on their operational approaches and the specific ports they use. DoT is tailored to secure the DNS query process itself, without mingling it with other web traffic. However, the reliance on TCP port 853 could potentially make DoT traffic more detectable and subject to blocking by restrictive networks, which may limit its utility in environments with heavy internet censorship.</p> <p>The choice between DoH and DoT will ultimately depend on the evolution of DNS security and the specific threat model you face. Factors such as your geographical location, the prevailing censorship and surveillance practices in your country, and the threats you encounter will significantly influence this decision. Remember, my focus is on ‘practical’ privacy, and simply using Quad9 DNS with a VPN might be more than sufficient for most. I just want to ensure you are aware that the topic extends beyond VPNs (hence the title!).</p> <h4 id="encrypted-client-hello-ech">Encrypted Client Hello (ECH)</h4> <p>While we are discussing DNS encryption options, it’s important I mention the Encrypted Client Hello (ECH) extension for TLS. ECH enhances privacy by encrypting additional metadata that could be exposed during the TLS handshake. While both DoH and DoT encrypt DNS queries, ECH addresses a separate aspect of TLS communications, offering further protection by encrypting information that could reveal the specific website being accessed, beyond the DNS query itself. Confused yet? Don’t worry, I just wanted to mention it. If you want to read more about ECH, then check out this <a href="https://blog.cloudflare.com/encrypted-client-hello/" target="_blank">blog post</a>.</p> <p>If you are using Firefox version 118 or above AND using DoH, then ECH is enabled by default.</p> <h3 id="dnssec">DNSSEC</h3> <p>DNSSEC (Domain Name System Security Extensions), isn’t about encryption, it’s about ensuring the integrity of data, a distinction often overlooked due to its name. Essentially, DNSSEC verifies that the digital signatures on DNS data, match, confirming that the data originates from its rightful source and remains unchanged during transit. DNSSEC may slow down DNS queries, although the impact is often minimal and depends on various factors including the resolver’s implementation and network conditions. It’s worth noting that Quad9 integrates DNSSEC validation within their recursive DNS process, alleviating the need to enable it in pfSense.</p> <h3 id="unbound-recursive-dns">Unbound (Recursive DNS)</h3> <p>Alright, I’ve brought up Unbound already, so let’s dive into that a bit more. Unbound is a DNS resolver that sets itself apart from standard DNS servers by functioning primarily as a ‘recursive’ DNS resolver. Unlike traditional DNS servers, which often act as mere forwarders, sending your DNS queries up the chain to other servers until an answer is found, Unbound takes on the task of performing the full journey of a DNS query itself. This means it starts at the root DNS servers (.) and works its way down through the hierarchy of domain names until it locates the specific server hosting the DNS records for the domain you’re trying to reach (www.duckduckgo.com). This recursive approach not only enhances privacy by minimizing the number of servers that see your DNS queries but also improves security by directly validating DNSSEC signatures, ensuring the authenticity and integrity of the DNS data it retrieves.</p> <p>By operating as a recursive DNS resolver, Unbound provides several key benefits over standard DNS servers. First and foremost; <strong>security</strong>.</p> <p>You see, Unbound can effectively protect against DNS spoofing and cache poisoning attacks by verifying DNSSEC signatures, a level of security that is not inherently provided by many standard DNS services. Its ability to perform the entire name resolution process internally also means that Unbound can optimize DNS query paths for better performance, caching responses aggressively to speed up access to frequently visited domains.</p> <p>Also, luckily for us, pfSense uses Unbound as the DNS resolver by default.</p> <p><strong>Note:</strong> I mentioned earlier that Quad9 already performs DNSSEC validation, which could alleviate the need to enable DNSSEC directly in pfSense. This is true. However, it’s important to understand that for you to fully benefit from Unbound’s DNSSEC validation capabilities (integrated within pfSense), DNSSEC must be explicitly enabled in pfSense. This ensures that DNSSEC validation occurs both externally (via Quad9) and internally (within your network).</p> <h1 id="summary">Summary</h1> <p>Feeling right as rain yet? I’ve covered quite a bit, from the reality that VPNs aren’t a one-stop-shop for anonymity to wrapping our heads around DNS and its importance in keeping our digital lives private. Before we dive into setting up pfSense, I wanted to ensure you understand the rationale behind the ‘why’ of our approach. As you can now appreciate, it’s not as simple as going with whatever VPN <insert YouTuber="" here=""> suggests. Even when delving into DNS encryption (DoT, DoH), ECH, and DNSSEC, we see it's also not as straightforward as picking 1.1.1.1 for DNS, just because it's easy to remember!</insert></p> <p>In part two, it’s time to roll up our sleeves and dive into the hands-on setup of pfSense. This is where we shift from theory to the fun stuff. We’ll walk through setting up that always-on VPN, getting Unbound to do the heavy lifting on DNS, and switching over to Quad9 for that extra layer of security. Then, I’ll show you how to run one or more VPN connections for an always-on VPN configuration with OpenVPN.</p> <p>If you’ve actually read all of this and understood it, then give yourself a pat on the back! And if you’re now utterly confused, don’t worry! Just follow the steps in part two (coming soon), and it’ll all start to make sense.</p> <p>See you soon!</p> Sun, 04 Feb 2024 05:00:00 +0000 https://psysecure.com/the-foundations-of-digital-privacy https://psysecure.com/the-foundations-of-digital-privacy pfSense privacy security dns Secure Settings for Firefox <h1 id="firefox-release-1220-january-23-2024">Firefox Release 122.0 (January 23, 2024)</h1> <p>I’ve been using Firefox as my primary browser since 2010, and here are my recommended settings to further enhance your security and privacy:</p> <h2 id="preferences">Preferences</h2> <h3 id="1-downloads-preferences--general">1. Downloads (Preferences &gt; General)</h3> <p>Disable automatic downloads by enabling the prompt to ‘Always ask you where to save files’.</p> <p><img src="/images/firefox/firefox-pref-001.png" alt="" width="40%" class="img-fluid rounded pb-3" /></p> <h3 id="2-home-preferences--home">2. Home (Preferences &gt; Home)</h3> <ul> <li>Set the default homepage to https://duckduckgo.com</li> <li>Disable all Firefox Home content by deselecting Web Search, Top Sites, Highlights, and Snippets.</li> <li>Ensure New Tabs is set to ‘Blank Page’</li> </ul> <p><img src="/images/firefox/firefox-pref-002.png" alt="" width="40%" class="img-fluid rounded pb-3" /></p> <h3 id="3-search-preferences--search">3. Search (Preferences &gt; Search)</h3> <ul> <li>Set Default Search Engine to DuckDuckGo</li> <li>Disable Search Suggestions (optional) - I recommend only enabling ‘Show search suggestions in address bar results’</li> <li>Set Search Shortcuts to DuckDuckGo only (deselect or remove the others)</li> </ul> <p><img src="/images/firefox/firefox-pref-003.png" alt="" width="40%" class="img-fluid rounded pb-3" /></p> <h3 id="4-browser-privacy-preferences--privacy--security">4. Browser Privacy (Preferences &gt; Privacy &amp; Security)</h3> <ul> <li>Set Enhanced Tracking Protection to Strict</li> </ul> <p>If this breaks too many sites, go ahead and change it back to Standard. Use what works for you.</p> <p><img src="/images/firefox/firefox-pref-004a.png" alt="" width="40%" class="img-fluid rounded pb-3" /></p> <ul> <li>Enable ‘Delete cookies and site data when Firefox is closed’</li> <li>Click on Manage Exceptions and add any sites you want to retain cookies for. I do this for sites I use every day, and you can wildcard entire domains (E.g. https://twitter.com)</li> <li>Deselect all items in Login and Passwords. I never use the browser to store these things, instead use <a href="https://keepassxc.org/">KeePassXC</a> or <a href="https://bitwarden.com/">BitWarden</a>.</li> <li>Select ‘Use custom settings for history’ in the History dropdown, and deselect all options. Cookies for sites we enabled in Manage Exceptions will still be kept.</li> </ul> <p><img src="/images/firefox/firefox-pref-004b.png" alt="" width="40%" class="img-fluid rounded pb-3" /></p> <ul> <li>Under Address Bar, select only Bookmarks and deselect everything else.</li> <li>For each of the following permissions, click on ‘Settings…’ and then select ‘Block new requests…’ at the bottom of each <ul> <li>Location</li> <li>Camera</li> <li>Microphone</li> </ul> </li> <li>Finally, deselect all options in Firefox Data Collection and Use.</li> </ul> <p><img src="/images/firefox/firefox-pref-004c.png" alt="" width="40%" class="img-fluid rounded pb-3" /></p> <p><strong>Note</strong>: I don’t add / change my bookmarks very often, so I simply export them to an HTML file as a backup every now and then.</p> <h1 id="recommended-add-ons">Recommended Add-Ons</h1> <p>I don’t like to add too many add-ons, since the more you add will increase the potential of one of them being vulnerable to attack or making your browser more unique (it’s fingerprint). <a href="https://panopticlick.eff.org/">Panopticlick</a> is a useful tool to see how unique your browser fingerprint is.</p> <p>Here are the 3 essential add-ons, that I would install without question:</p> <ol> <li><a href="https://addons.mozilla.org/en-US/firefox/addon/ublock-origin/">uBlock Origin</a></li> <li><a href="https://addons.mozilla.org/en-US/firefox/addon/multi-account-containers/">Multi-Account Containers</a></li> </ol> Fri, 24 Nov 2023 17:01:35 +0000 https://psysecure.com/secure-settings-for-firefox https://psysecure.com/secure-settings-for-firefox firefox privacy security Secure Settings for Brave <h1 id="brave-release-162153-jan-25-2024">Brave Release 1.62.153 (Jan 25, 2024)</h1> <h2 id="on-startup-get-started--on-startup">On-Startup (Get Started &gt; On-Startup)</h2> <p>Change “Continue where you left off” to “Open the New Tab page”</p> <h2 id="appearance">Appearance</h2> <p><strong>Disable:</strong></p> <ul> <li>Show Brave News button</li> <li>Show Brave Wallet button</li> <li>Show Sidebar button</li> <li>Show VPN button</li> </ul> <p>**Disable: **</p> <ul> <li>Show autocomplete suggestions in address bar Top Sites Browsing History Bookmarks</li> </ul> <h2 id="privacy--security">Privacy &amp; Security</h2> <p>Private Windows with Tor Connectivity in Brave are just regular private windows that use Tor as a proxy. Brave does NOT implement most of the privacy protections from Tor Browser.</p> <p><strong>Disable:</strong></p> <ul> <li>Allow privacy-preserving product analytics (P3A)</li> <li>Automatically send daily usage ping to Brave</li> <li>Private window with Tor</li> </ul> <h3 id="clear-browsing-data">Clear Browsing Data</h3> <p>On exit: All</p> <h3 id="site-and-shields-settings">Site and Shields Settings</h3> <p>Location &gt; Don’t allow sites to see your location Camera &gt; Don’t allow sites to use your camera Microphone &gt; Don’t allow sites to use your microphone Notifications &gt; Don’t allow sites to send notifications</p> <p><strong>Additional permissions:</strong> Automatic downloads &gt; Don’t allow sites to automatically download multiple files USB devices &gt; Don’t allow sites to connect to USB devices File editing &gt; Don’t allow sites to edit files or folders on your device Clipboard &gt; Don’t allow sites to see text or images on your clipboard</p> <p><strong>Cookies and Site Data:</strong> Block third-party cookies - enabled Enable: Clear cookies and site data when you close all windows</p> <p><strong>Sites that can always use cookies</strong> Add sites here that you always use (E.g. email, Twitter) - Don’t go crazy, it’s best to keep this to a minimum!</p> <p>By default the following URLs are allowed: https://[*.]firebaseapp.com https://accounts.google.com</p> <p>Note: You can’t delete them unless you disable the use of third-party cookies for legacy Google Sign-In and Facebook logins and embedded posts.</p> <p><strong>Go to: brave://settings/socialBlocking</strong> Disable:</p> <ul> <li>Allow use of third-party cookies for legacy Google Sign-In</li> <li>Allow Facebook logins and embedded posts</li> <li>Allow Twitter embedded tweets</li> </ul> <h2 id="shields">Shields</h2> <p>Allow use of third-party cookies for legacy Google Sign-In Allow Facebook logins and embedded posts Allow Twitter embedded tweets</p> <h2 id="autofill-and-passwords">Autofill and passwords</h2> <p>Disable:</p> <ul> <li>Allow auto-fill in private windows</li> </ul> <p><strong>Payment methods</strong> Disable:</p> <ul> <li>Save and fill payment methods</li> <li>Allow sites to check if you have payment methods saved</li> </ul> <h2 id="system">System</h2> <p>Use WireGuard protocol in Brave VPN - enabled</p> <p><strong>Note</strong>: brave://about/ will show all possible settings</p> <h1 id="recommended-add-ons">Recommended Add-Ons</h1> <p>I don’t like to add too many add-ons, since the more you add will increase the potential of one of them being vulnerable to attack or making your browser more unique (it’s fingerprint). <a href="https://panopticlick.eff.org/">Panopticlick</a> is a useful tool to see how unique your browser fingerprint is.</p> <p>Here are the 3 essential add-ons, that I would install without question:</p> <ol> <li><a href="https://addons.mozilla.org/en-US/firefox/addon/ublock-origin/">uBlock Origin</a></li> </ol> Thu, 23 Nov 2023 17:01:35 +0000 https://psysecure.com/secure-settings-for-brave https://psysecure.com/secure-settings-for-brave brave privacy security Why I Prefer Firefox for Better Online Security <p>I have to cringe when I see a fellow IT professional use their web browser, only to see the screen is populated with ads. It’s not the content of these advertisements that I dislike, well actually it’s that too, but the third-party tracking cookies that are part of the payload. I just feel my peers should know better. Aside from the tracking cookies that are often part of the ad, much like the soldiers that hid inside of a wooden horse to enter the city of Troy, these ads sometimes contain malware. But why should you care?</p> <p>In 2020, The New York Times published a series of articles called <strong>The Privacy Project</strong>, and one such article highlighted this very issue, <a href="https://www.nytimes.com/2020/01/07/opinion/location-tracking-privacy.html">Why You Should Take a Close Look at What Tracks You</a>. It happens in the physical world as well, with Bluetooth and WiFi beacons in stores and shopping centers, and automatic license-plate readers (ALPR) on our roads, parking lots, venues, and even our <a href="https://slate.com/technology/2019/07/automatic-license-plate-readers-hoa-police-openalpr.html">neighborhoods</a>.</p> <p>I don’t like being tracked. But it’s more than tracking, it’s a psychological profile being used to serve what they call ‘relevant ads’. I can’t blame them really. I mean, why serve an advertisement for Arby’s to a vegetarian?</p> <p>Have you ever purchased something in a pharmacy, and then later that day you see ads on Facebook or other websites, for that exact same thing? Perhaps you thought your phone was listening? More likely what happened is that phone number you gave the pharmacy for reward points, is linked to your Facebook profile. Yes, Meta are involved in data collection here too.</p> <p>The nothing to hide argument is also ridiculous so I won’t even entertain that here. The fact is that our data is being collected. Even the data we willingly hand over, perhaps for an online order, will invariably end up in a data breach at some point in time. I don’t want my personal information in the wrong hands, with scammers or identity thieves. If it’s being collected, then you must assume it will eventually be exposed. Did you know that <a href="https://www.nytimes.com/2019/08/13/opinion/health-data.html">insurance companies</a> harvest and process this data too? And, depending on how they profile you it can increase your insurance premium. <!--more--></p> <p>This is just scratching the surface. Like security, achieving privacy online is a fine balance. If you go too far then it results in what we are trying to do, an impossible task. Not enough, and you may think <em>why bother</em> at all?</p> <p>Now let’s explore our risk profile here. If you are online, then you are not anonymous. The Tor Browser goes pretty far towards anonymity, but it’s not foolproof. VPNs are great, but these are more akin to smoke and mirrors. Don’t ever think a VPN will make you truly anonymous online either. The nirvana we are trying to attain is just a good balance. We want to block ads, block malware, and make it more difficult for websites to track our behaviors. It really doesn’t have to be more complicated than that, for most of us anyway.</p> <h2 id="disclaimer">Disclaimer</h2> <p>The content on this site is aimed at <strong>practical</strong> privacy and security - the kind of privacy measures you’d expect the average internet user to adopt, not someone in witness protection or fleeing their country in danger of their life! Extreme privacy requires more than a VPN and well configured web browser, therefore it’s not in the scope of this article. I recently saw a Reddit post by someone fleeing a sex trafficking situation, in genuine fear for their life. If that is you, then look into using <a href="https://tails.boum.org/">Tails</a> on a bootable USB stick, erase and throw away your phone and SIM card, buy a burner phone with cash, and use a pre-paid SIM card in an alias name. Use cash only, gift Visa cards purchased with cash, or <a href="https://privacy.com">privacy.com</a>. Always use a <a href="https://mullvad.net">VPN</a>. And, that is just the start.</p> Wed, 22 Nov 2023 17:01:35 +0000 https://psysecure.com/why-i-use-firefox https://psysecure.com/why-i-use-firefox firefox privacy security