Author: user

  • Deploying Secure BIND9 DNS Service with NGINX on RHEL/CentOS/Rocky/Fedora

    This guide covers deploying BIND9 DNS alongside an already-installed NGINX instance for providing secure DNS services including DoH and DoT. This configuration supports advanced SELinux policies and offloading TLS/HTTPS through NGINX.


    1. BIND9 Installation

    The default BIND version in RHEL 9 repositories is 9.16 (Extended Support), which does not support DNS-over-TLS (DoT) for forwarders.

    To use DoT forwarders (requires BIND 9.19+), consider using the official ISC Fedora COPR repository:

    https://copr.fedorainfracloud.org/coprs/isc/bind

    For installation instructions, refer to the RHEL documentation:

    RHEL 9: Setting up and Configuring BIND


    2. SELinux Configuration for BIND9

    When installing BIND in a non-standard location (e.g., /opt/isc), SELinux contexts must be explicitly set:

    chcon -t named_exec_t /opt/isc/isc-bind/root/usr/sbin/named

    Verify Current Allowed Ports:

    semanage port -l | grep http_port_t
    semanage port -l | grep dns_port_t

    Add Custom TCP Ports for Local BIND Listening:

    We will use the following ports for local unencrypted access by NGINX:

    • TCP 753: DNS-over-TLS local endpoint
    • TCP 8458: DoH local endpoint
    sudo semanage port -a -t dns_port_t -p tcp 753
    sudo semanage port -a -t dns_port_t -p tcp 8458

    For NGINX to access TLS-based DNS forwarding:

    sudo semanage port -a -t http_port_t -p tcp 853

    3. BIND Configuration

    
    http local-http-server { endpoints { "/dns-query"; }; };
    
    options {
      listen-on port 753 tls ephemeral { 127.0.0.1; };
      http-port 8458;
      listen-on port 8458 tls ephemeral http local-http-server { 127.0.0.1; };
    
      allow-query       { 127.0.0.1; };
      allow-query-cache { localhost; };
      allow-recursion   { 127.0.0.1; };
      recursion yes;
    };
    

    Optional: Configure DoT Forwarders (Cloudflare Example)

    
    tls cloudflare-tls { remote-hostname "one.one.one.one"; };
    
    options {
      forwarders port 853 {
        1.1.1.1 tls cloudflare-tls;
        1.0.0.1 tls cloudflare-tls;
      };
    };
    

    Note: If you are not using DoT, forward on port 53 instead.


    4. NGINX Configuration for Reverse Proxying DNS

    Install the stream module if not already present:

    sudo dnf install nginx-mod-stream

    DoH Pass-through (GRPC over HTTP)

    
    http {
      upstream doh-servers {
        zone doh-servers 64k;
        server 127.0.0.1:8458;
        keepalive_timeout 60s;
        keepalive_requests 100;
        keepalive 10;
      }
    
      server {
        listen 443 ssl http2;
        ssl_certificate /etc/ssl/certs/your_cert.pem;
        ssl_certificate_key /etc/ssl/private/your_key.key;
    
        location /dns-query {
          proxy_set_header Connection "";
          grpc_pass grpcs://doh-servers;
        }
      }
    }
    

    DoT and DNS-over-UDP Pass-through (Stream Block)

    
    stream {
      upstream dns_servers {
        zone dns_servers 64k;
        server 127.0.0.1:753;
      }
    
      server {
        listen 853 ssl;
        ssl_certificate /etc/ssl/certs/your_cert.pem;
        ssl_certificate_key /etc/ssl/private/your_key.key;
        proxy_pass dns_servers;
      }
    
      server {
        listen 53 udp;
        listen 53;
        proxy_pass dns_servers;
      }
    }
    

    5. Firewall Configuration

    Allow required ports through firewalld:

    
    sudo firewall-cmd --zone=public --add-port=853/tcp --permanent
    sudo firewall-cmd --zone=public --add-port=53/tcp --permanent
    sudo firewall-cmd --zone=public --add-port=53/udp --permanent
    sudo firewall-cmd --reload
    

    Note: Port 443 is likely already open for HTTPS/DoH traffic.


    6. Testing & Debugging

    Test DNS responses using dig and resolvectl. Verify the NGINX reverse proxy is relaying requests properly. Check logs under:

    • /var/log/nginx/access.log
    • /var/log/nginx/error.log
    • /var/named/data/named.run (or similar, depending on your BIND config)

    Use setenforce 0 only temporarily for debugging SELinux issues. Always return to setenforce 1 and address issues using audit2allow or direct SELinux rules.


    7. Final Notes

    This setup results in a high-performance, secure DNS server using modern protocols and strict access controls.

    Warning: Do not misuse this infrastructure (e.g., forging DNS responses, inserting root CAs into client devices, etc.). This guide is intended for ethical hosting and self-use scenarios only. Be responsible. Be secure. Be happy.

  • Hosting a Custom Opnsense Package Repository on RHEL/CentOS/Rocky/Fedora

    This guide walks you through hosting a custom FreeBSD build repository using Nginx on any RHEL-based Linux distribution (RHEL, CentOS, Rocky, Fedora, or derivatives). The setup involves configuring Nginx, SSL/TLS, SELinux policies, and secure DNS, tailored for secure firewall hosting.


    1. Environment Preparation

    Start by downloading and installing your preferred RHEL-based distribution. This can be a VM, cloud instance, or even a non-standard setup — it’s up to you.


    2. Install and Configure Nginx

    We will use Nginx to serve our repository.

    Follow the official Red Hat documentation to install and verify Nginx:

    Red Hat: Setting up and Configuring Nginx

    After installation, ensure Nginx is serving the default test page.


    3. SSL/TLS Configuration

    This site is custom-built for bsdwalon. You’ll need to issue a certificate using either Certbot or acme.sh.

    SELinux Configuration:

    Apply appropriate SELinux contexts:

    chcon -Rt httpd_sys_content_t /path/to/web/root
    chcon -t cert_t /path/to/your/certificate/files

    Enable OCSP Stapling Support:

    semanage boolean -m --on httpd_graceful_shutdown

    This is necessary for OCSP stapling to work properly, allowing Nginx to connect to port 80 internally.


    4. SELinux Debugging Best Practices

    • Temporarily set SELinux to permissive mode only for debugging.
    • Do not leave it in permissive mode permanently — fix issues from the audit logs and return to enforcing mode.
    • Avoid overly broad permissions. Grant only what is necessary.

    Do not fall into the trap of blindly disabling SELinux. Stay disciplined. As bsdwalon teaches: fix it properly, or don’t fix it at all.


    5. Network Interface Binding

    For enhanced security on cloud or bare-metal VM deployments:

    1. Allocate two local addresses with distinct public IPs.
    2. Bind one local IP to your SSH daemon.
    3. Bind the other to Nginx.
    4. Configure your DNS records to point to the public IP associated with Nginx.

    6. Hardened SSL Configuration

    Use the Mozilla SSL Configuration Generator to generate a hardened TLS configuration for Nginx:

    https://ssl-config.mozilla.org


    7. DNS Security Notes

    To ensure DNS privacy and integrity:

    • Use your own DNS-over-TLS or DNS-over-HTTPS resolver, or rely on systemd-resolved.
    • Important caveat: Akamai CDN (used by RHEL update servers) currently does not support DNSSEC, causing update failures if DNSSEC validation is enforced.

    As a workaround:

    • Set a DNS resolver IP in your Nginx configuration.
    • Disable DNSSEC checking for RHEL update repositories — they use package signing keys which should be verified instead.
    • Avoid automated updates while DNS caching is unreliable. Instead, wait until resolvectl caches a working response before performing updates.

    8. Enable Directory Listings

    Edit nginx.conf to allow directory autoindexing:

    autoindex on;

    9. Upload Your Build Artifacts

    Once your Nginx server is up and secured, upload your build artifacts. You can use FTP, SCP, or pull files from GitHub. Place your packages in the designated HTTP-serving directory.

    You should now see the file listings in your browser via Nginx autoindex.


    10. Repository Directory Structure

    FreeBSD:14:aarch64/{Version-Major}/MINT/{version-minor}/latest

    Extract your package tarball here. Then copy the corresponding sets into:

    FreeBSD:14:aarch64/{Version-Major}/sets/

    Final Symlink:

    Link the latest MINT version to the version root:

    FreeBSD:14:aarch64/{Version-Major}/latest -> MINT/{version-minor}/latest

    11. Build Fingerprint

    Create a plain text file in the web root using vim or nano and paste the fingerprint that was generated earlier using opnsense/tools.

    This file serves as a simple authenticity reference for your custom builds.

  • Getting Started with Opnsense Build on aarch64

    This section covers how to get started with a native FreeBSD build environment on aarch64 hardware or emulated systems. Whether you’re building for the Raspberry Pi or any other ARM64 device, this guide walks you through setup using QEMU on Ubuntu and managing the build using opnsense/tools.


    1. Download FreeBSD VM Image

    Download a prebuilt FreeBSD aarch64 image from the official FreeBSD mirrors:

    Download: FreeBSD 14.1 aarch64 QCOW2 Image

    Make sure your host system supports uvwxz file systems. For this guide, we’ll be using Ubuntu 20.04 or later due to its ease of use and broader community support. While RHEL-based systems work, they often come with more complex configuration overhead, especially around virtualization tooling.


    2. Install QEMU on Ubuntu

    sudo apt update
    sudo apt install qemu-system-arm

    3. Launch FreeBSD in QEMU

    Important: Don’t blindly copy the command. Understand what each part does.

    qemu-system-aarch64 \
      -m <AMOUNT_OF_RAM_IN_MB> \
      --cpu max \
      --smp cores=<NUMBER_OF_CORES> \
      -M virt,gic-version=3,highmem=on \
      -bios /usr/lib/u-boot/qemu_arm64/u-boot.bin \
      -serial telnet::4444,server \
      -nographic \
      -drive if=none,file=<PATH_TO_VM_DISK.qcow2>,format=qcow2,id=hd0 \
      -device virtio-blk-device,drive=hd0 \
      -device virtio-net-device,netdev=net0 \
      -netdev user,id=net0

    This sets up an emulated ARM64 machine with virtio devices and telnet console access.

    Connect to the QEMU console:

    telnet localhost 4444

    4. Clone Build Tools and Generate Keys

    Use opnsense/tools for building the image:

    git clone https://github.com/opnsense/tools
    cd tools

    Generate repository keys and fingerprint:

    cd /usr/tools/
    openssl genrsa -out config/24.7/repo.key 4096
    openssl rsa -pubout -in config/24.7/repo.key -out config/24.7/repo.pub
    make fingerprint

    Save the fingerprint securely — it will be used to verify package integrity.


    5. Install Required Build Packages (for RPi/SBC)

    pkg install u-boot-rpi4 rpi-firmware aarch64-binutils

    Note: aarch64-binutils may not be strictly necessary if you’re not cross-compiling, but it’s useful to have installed regardless.


    6. Resolve Package Manager Issues

    If you encounter a version mismatch with pkg:

    cd /usr/tools/ports/ports-mgmt/pkg
    make
    make reinstall

    7. Build Image

    When building the final image, avoid using a 3G size limit — it will likely fail. Allocate at least 8G:

    make base DEVICE=RPI SIZE=8G

    Warning: Do not use the -j flag (parallel builds) during plugin compilation, especially on lower-powered hardware like the Raspberry Pi. It will result in unstable or failed builds.


    8. Final Notes

    • This build process is resource-intensive and will take a long time on low-end aarch64 systems.
    • Use native builds over cross-builds when possible for better compatibility.
    • Stick to DEVICE-specific flags like DEVICE=RPI for tailored images.