Skip to content
4Quarks edited this page Aug 22, 2024 · 36 revisions

pDNSSOC is a minimalistic component allowing DNS data to be centrally collected, and correlated with malicious domains / IPs from a MISP instance.

Installation overview

A complete pDNSSOC deployment requires:

  • Access to a MISP instance (URL + API key are needed)
  • A source of DNS data, for example:
    • dnstap files (typically rsync'ed of SSH)
    • a DNS server with a go-dnscollector sender
  • A pDNSSOC server: a go-dnscollector receiver + pDNSSOC

pDNSSOC server

go-dnscollector receiver

  1. Create the user that will run the service:

    sudo useradd --system --no-create-home --shell /usr/sbin/nologin dnscollector
  2. Define the version of the go-dnscollector that you want to install:

     GO_DNSCOLLECTOR_VERSION=$(curl -s https://api.github.com/repos/dmachard/go-dnscollector/releases/latest | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/' | sed 's/^v//')
  3. Install go-dnscollector

    curl -LO  "https://github.com/dmachard/go-dnscollector/releases/download/v${GO_DNSCOLLECTOR_VERSION}/go-dnscollector_${GO_DNSCOLLECTOR_VERSION}_linux_amd64.tar.gz" && \
    tar xvf "go-dnscollector_${GO_DNSCOLLECTOR_VERSION}_linux_amd64.tar.gz" && \
    mv go-dnscollector /usr/bin/
  4. Adjust the permissions for the user and create the directories needed to be able to run go-dnscollector:

    chmod +x /usr/bin/go-dnscollector
    chcon -t bin_t /usr/bin/go-dnscollector
    setcap cap_net_raw+ep /usr/bin/go-dnscollector
    chown dnscollector:dnscollector /usr/bin/go-dnscollector
    
    mkdir -p /var/dnscollector /var/dnscollector/alerts /var/dnscollector/queries /var/dnscollector/matches
    touch /var/dnscollector/alerts/matches.json /var/dnscollector/misp_ips.txt /var/dnscollector/misp_domains.txt /var/dnscollector/queries/queries.json /var/dnscollector/alerts_db.txt /var/dnscollector/matches/matches_domains.json /var/dnscollector/matches/matches_ips.json
    chown -R dnscollector:dnscollector /var/dnscollector/
    chmod -R u+rw /var/dnscollector/
  5. Adjust the configuration file, which is automatically generated as config.yml using the following templates:

    mkdir -p /etc/dnscollector 
    curl -o /etc/dnscollector/config.yml https://raw.githubusercontent.com/CERN-CERT/pDNSSOC/main/files/configuration/dnscollector/server.yml
    chown -R dnscollector:dnscollector /etc/dnscollector/
    chmod -R u+rw /etc/dnscollector/ 
    vi /etc/dnscollector/config.yml
  6. Test the configuration file to make sure it doesn't have typos:

    go-dnscollector -config /etc/dnscollector/config.yml -test-config
  7. Execute the collector:

Configure the collector as a service:

 curl -o /etc/systemd/system/dnscollector.service https://raw.githubusercontent.com/CERN-CERT/pDNSSOC/main/files/configuration/dnscollector/dnscollector.service
 systemctl daemon-reload
 systemctl start dnscollector
 systemctl enable dnscollector

For debugging purposes, it is possible to start go-dnscollector manually

 go-dnscollector -config /etc/dnscollector/config.yml
  1. Ensure that the collecting port set in the configuration file is accessible and the port open. For example:
    sudo firewall-cmd --zone=public --add-port=7001/tcp --permanent
    sudo firewall-cmd --zone=public --add-port=7001/udp --permanent
    sudo firewall-cmd --reload

pDNSSOC

  1. Create the pdnssoc directory.

    mkdir /etc/pdnssoccli
  2. Install pdnssoc-cli

    pip3 install git+https://github.com/safer-trust/pdnssoc-cli.git@topic/packaging
  3. Create the pdnssoccli configuration file (pdnssoccli.yml) under /etc/pdnssoccli and modify it based on the pdnssoccli template. For details, see the configuration documentation.

    curl -o /etc/pdnssoccli/pdnssoccli.yml https://raw.githubusercontent.com/CERN-CERT/pDNSSOC/main/files/configuration/pdnssoccli/pdnssoccli.yml
    chown -R dnscollector:dnscollector /etc/pdnssoccli
    vi /etc/pdnssoccli/pdnssoccli.yml
  1. Create the cronjob to automate correlation and alerting:
    curl -o /etc/cron.d/pdnssoccli https://raw.githubusercontent.com/CERN-CERT/pDNSSOC/main/files/configuration/pdnssoccli/pdnssoccli.cron
    service cron reload

go-dnscollector sender (DNS server side)

  1. Create the user that will run the service:

    sudo useradd --system --no-create-home --shell /usr/sbin/nologin dnscollector
  2. Define the version of the go-dnscollector that you want to install:

     GO_DNSCOLLECTOR_VERSION=$(curl -s https://api.github.com/repos/dmachard/go-dnscollector/releases/latest | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/' | sed 's/^v//')
  3. Install go-dnscollector

    curl -LO  "https://github.com/dmachard/go-dnscollector/releases/download/v${GO_DNSCOLLECTOR_VERSION}/go-dnscollector_${GO_DNSCOLLECTOR_VERSION}_linux_amd64.tar.gz" && \
    tar xvf "go-dnscollector_${GO_DNSCOLLECTOR_VERSION}_linux_amd64.tar.gz" && \
    mv go-dnscollector /usr/bin/
  4. Adjust the permissions for the user and create the directories needed to be able to run go-dnscollector:

    chmod +x /usr/bin/go-dnscollector
    chcon -t bin_t /usr/bin/go-dnscollector
    setcap cap_net_raw+ep /usr/bin/go-dnscollector
    chown dnscollector:dnscollector /usr/bin/go-dnscollector
    
    mkdir -p /var/dnscollector
    chown -R dnscollector:dnscollector /var/dnscollector/
    chmod -R u+rw /var/dnscollector/
  5. Adjust the configuration file, which is automatically generated as config.yml using the following templates:

    mkdir -p /etc/dnscollector 
    curl -o /etc/dnscollector/config.yml https://raw.githubusercontent.com/CERN-CERT/pDNSSOC/main/files/configuration/dnscollector/client.yml
    chown -R dnscollector:dnscollector /etc/dnscollector/
    chmod -R u+rw /etc/dnscollector/ 
    vi /etc/dnscollector/config.yml
  6. Test the configuration file to make sure it doesn't have typos:

    go-dnscollector -config /etc/dnscollector/config.yml -test-config
  7. Execute the collector:

Configure the collector as a service:

 curl -o /etc/systemd/system/dnscollector.service https://raw.githubusercontent.com/CERN-CERT/pDNSSOC/main/files/configuration/dnscollector/dnscollector.service
 systemctl daemon-reload
 systemctl start dnscollector
 systemctl enable dnscollector

For debugging purposes, it is possible to start go-dnscollector manually

 go-dnscollector -config /etc/dnscollector/config.yml

Testing and debugging pDNSSOC

  • Check if the service is running and its logs:
# systemctl status dnscollector
# journalctl -u dnscollector -f
  • Check if the process is running:
# ps -aux | grep dnscollector
dnscoll+   37571  0.0  1.1 1395372 40108 ?       Ssl  May23   2:03 /usr/bin/go-dnscollector -c /etc/dnscollector/config.yml
  • Check if the connection has been established. We will use the port 7001 as example:

    A. From the DNS sensor:

    # netstat -putan | grep 7001
    tcp        0      0 IP_DNS:59450            IP_PDNSSOC:7001         ESTABLISHED 37571/go-dnscollect 

    B. From pDNSSOC:

    # netstat -putan | grep 7001
    tcp6       0      0 :::7001                 :::*                    LISTEN      19378/go-dnscollect 
    tcp6       0      0 IP_PDNSSOC:7001         IP_DNS:59450            ESTABLISHED 19378/go-dnscollect
  • Check if the pDNSSOC collector is receiving logs:

# tail /var/dnscollector/queries.json
# tcpdump -i eth0 -A port 7001
  • Check the location where pDNSSOC was installed:
# pip show pdnssoc-cli
  • Verify that the pDNSSOC command line tool works
# pdnssoc-cli fetch-iocs
# pdnssoc-cli correlate
# pdnssoc-cli alert
  • Verify that pdnssoccli.yml has a right format
# pip install yamllint
# yamllint /etc/pdnssoccli/pdnssoccli.yml
  • Check if the IOCs could be fetched from MISP
# tail /var/dnscollector/misp_domains.txt 
# tail /var/dnscollector/misp_ips.txt 
  • Test a malicious domain resolution to check that the alerts are created. You can use any domain from the misp_domains.txt,
# dig @IP_DNS maliciousdomain.com
# cat /var/dnscollector/queries.json | grep maliciousdomain.com

DNS Server (for testing)

To set up a test environment, you can easily deploy a Bind9 DNS server by following the steps outlined below. Please note that the provided template and installation instructions are intended for testing purposes only and are NOT suitable for a production environment. For best practices and production setups, please refer to the Official Documentation.

  1. Install Bind9
    dnf copr enable isc/bind
    yum install isc-bind
  2. Create log directory and edit the name.conf file using the template
    mkdir -p /var/log/named 
    chown named:named /var/log/named 
    curl -o /etc/opt/isc/scls/isc-bind/named.conf https://raw.githubusercontent.com/CERN-CERT/pDNSSOC/main/files/configuration/test_lab/named.conf
    vim /etc/opt/isc/scls/isc-bind/named.conf
    chown named:named /etc/opt/isc/scls/isc-bind/named.conf
    sudo -u named /opt/isc/isc-bind/root/usr/bin/named-checkconf /etc/opt/isc/scls/isc-bind/named.conf
  3. Start and enable the DNS service
    systemctl start isc-bind-named
    systemctl enable isc-bind-named
    systemctl status isc-bind-named
  4. Open the internal firewall if you want to resolve domains from other instances
    systemctl start firewalld
    systemctl enable firewalld
    firewall-cmd --permanent --add-service=dns
    firewall-cmd --reload
    firewall-cmd --list-all

Test installation

  • Check that the DNS can resolve domains.
host1# dig @IP_DNS maliciousdomain.com
dns# /opt/isc/isc-bind/root/usr/bin/dnstap-read /var/log/named/dnstap.log 
27-May-2024 17:57:01.255 CQ IP_HOST1:47263 -> IP_DNS:53 UDP 49b maliciousdomain.com/IN/A
Clone this wiki locally