Security News
Weekly Downloads Now Available in npm Package Search Results
Socket's package search now displays weekly downloads for npm packages, helping developers quickly assess popularity and make more informed decisions.
junedns-server
Advanced tools
Dataclick Olimpo ☀️JuNeDNS Server Safe, Lightweight and Full DNS Server ideal for single or hosting servers
JuNeDNS Server is a lightweight DNS authoritative and recursive server created in Node.js with a fully functionality and easy installation and use.
✔ All DNS server features that a DNS server requires.
✔ Safe, lightweight, and easy installation.
✔ Detailed information about JuNeDNS functionallity.
✔ All about domains DNS service/protocol knowledge you need are here in this documentation.
✔ Support for IDN (internationalized domain name) for non-ASCII characters (coding in Punycode).
✔ You don´t need anything else in a DNS server system (protocols/records that really unused, bloatware).
✔ So, perfect for advanced or beginners SysAdmins.
✔ Just insert domains and records into database without restart DNS service.
✔ Forget about complicated text config files for DNS zones.
✔ Control Your DNS directly in Your server.
✔ Do not depend on external DNS like Cloudflare that can be attacked and disabled, or with security issues like Authenticated Origin Pulls, causing your domains not to resolve for a while - Downdetector.
Eduardo Ruiz <eruiz@dataclick.es>
Have a look to JuNe BackServer in Backend.
CREATE DATABASE IF NOT EXISTS junedns;
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP ON junedns.* TO 'junednsusr'@'localhost' IDENTIFIED BY 'YOUR_PASSWORD_HERE';
FLUSH PRIVILEGES;
USE junedns;
👉 And create tables using mysql.sql
File junedns.conf
// Protocols
protocol_ipv4=true
protocol_ipv6=true
protocol_dot=false
protocol_doh=false
// Database
mysql_host=127.0.0.1
mysql_port=3306
mysql_name=junedns
mysql_user=junednsusr
mysql_pass=
// Verbose logs in JuNeDNS_PATH/junedns.log
// 0=None, 1=Errors, 2=All (3=debug)
log=0
// Main domain for PTR, and DNSSEC (PRO version)
main_domain=mydomain.tld
// Server public IP address for PTR and backend
ipv4=1.2.3.4
ipv6=
// DNS-over-TLS (DoT)
dot_cert=
dot_key=
// DNS-over-HTTPS (DoH)
doh_port=8085
doh_cert=
doh_key=
// Forward resolve requests if domain is not hosted
forward=false
forward_pri_ipv4=8.8.8.8
forward_sec_ipv4=8.8.4.4
forward_pri_ipv6=
forward_sec_ipv6=
// -- Only PRO version --
license_key=
license_name=
dnssec=true
dkim_path=
dkim_genkey=
dkim_selector=
// For backend
backend_url=http://localhost:9053
backend_cert=
backend_key=
backend_api=false
Changes requires restart JuNeDNS Server / You need root privileges for installation.
chmod 600 junedns.conf
Important variables to be setted are mysql_ and ipv4 / ipv6
BEWARE! Setting forward=true your server maybe attacked using open DNS resolver vulnerability.
forward_pri_ipv4 / forward_sec_ipv4 public primary and secondary DNS server addresses to resolve external domains, in Linux you can use same as /etc/resolv.conf, (not very necessary to use forward IPv6):
DNS server: | Primary IPv4 | Secondary IPv4 | Primary IPv6 | Secondary IPv6 |
---|---|---|---|---|
8.8.8.8 | 8.8.4.4 | 2001:4860:4860::8888 | 2001:4860:4860::8844 | |
Quad9 | 9.9.9.9 | 149.112.112.112 | 2620:fe::fe | 2620:fe::9 |
OpenDNS | 208.67.222.222 | 208.67.220.220 | 2620:0:ccc::2 | 2620:0:ccd::2 |
Cloudflare | 1.1.1.1 | 1.0.0.1 | 2606:4700:4700::1111 | 2606:4700:4700::1001 |
Alternate DNS | 76.76.19.19 | 8.20.247.20 | 2602:fcbc::ad | 2602:fcbc:2::ad |
Or have a look to https://public-dns.info
Run JuNeDNS Server using Node.js with source code or from binary:
Download or clone this repository.
Install dependencies npm install
(JuNe 1 dependence: MySQL).
Requirements node.js and Node Package Manager (NPM).
Running from command line (for example to debug)
-node server.js
or npm start
Running as service
🐧Linux:
junedns.service
in folder /etc/systemd/system
or /usr/lib/systemd/system
use ExecStart Source code execution line and adjust path if necessary.systemctl enable junedns.service && systemctl start junedns.service
check if running systemctl status junedns.service
🪟 Windows:
sc create "JuNeDNS Server" binPath="NodeJS_PATH\node JuNeDNS_PATH\server.js"
start with net start "JuNeDNS Server"
Download and decompress your version: 🐧Linux (20 Mb), 🪟 Windows (17 Mb) or 🍎MacOS (20 Mb).
Create junedns.conf
Running from command line (for example to debug with log=3)
-./junedns
or junedns
Running as service
🐧Linux:
mkdir /etc/junedns
and copy file in it.chmod +x /etc/junedns/junedns
/etc/junedns/junedns.conf
and chmod 600.junedns.service
in folder /etc/systemd/system
or /usr/lib/systemd/system
use ExecStart Binary execution line and adjust path if necessary.systemctl enable junedns.service && systemctl start junedns.service
check if running systemctl status junedns.service
🪟 Windows:
C:\Users\[USER]\AppData\Roaming\JuNeDNS
and copy file in it.C:\Users\[USER]\AppData\Roaming\JuNeDNS\junedns.conf
sc create "JuNeDNS Server" binPath="C:\Users\[USER]\AppData\Roaming\JuNeDNS\junedns.exe"
start with net start "JuNeDNS Server"
🐧Linux: Uncomment the ExecStart line you need for junedns.service
[Unit]
Description=JuNeDNS Server
After=network.target
[Service]
Type=simple
# Select only 1 ExecStart
#ExecStart=/etc/junedns/junedns #Binary execution
#ExecStart=/usr/bin/node /etc/junedns/server.js #Source code execution
Restart=always
TimeoutStartSec=0
[Install]
WantedBy=default.target
INSERT INTO domains SET id=1, name='mydomain.tld';
INSERT INTO records SET domain_id=1, name='mydomain.tld', type='SOA', content='ns1.nsdomain.tld info.nsdomain.tld 3 10380 3600 604800 3600';
INSERT INTO records SET domain_id=1, name='mydomain.tld', type='A', content='1.2.3.4';
INSERT INTO records SET domain_id=1, name='mydomain.tld', type='AAAA', content='i:want:an:ipv6:address:so:change:me';
INSERT INTO records SET domain_id=1, name='mydomain.tld', type='NS', content='ns1.nsdomain.tld';
INSERT INTO records SET domain_id=1, name='mydomain.tld', type='NS', content='ns2.nsdomain.tld';
INSERT INTO records SET domain_id=1, name='www.mydomain.tld', type='CNAME', content='mydomain.tld';
INSERT INTO records SET domain_id=1, name='mydomain.tld', type='MX', content='mail.mydomain.tld 10';
INSERT INTO records SET domain_id=1, name='mail.mydomain.tld', type='A', content='1.2.3.4';
INSERT INTO records SET domain_id=1, name='mail.mydomain.tld', type='AAAA', content='i:want:an:ipv6:address:so:change:me';
INSERT INTO records SET domain_id=1, name='mydomain.tld', type='TXT', content='v=spf1 mx -all';
You should add a PTR record for the server main_domain reverse lookup specified in junedns.conf and containing hostname of the machine with the main domain.
INSERT INTO records SET domain_id=1, name='maindomain.tld', type='PTR', content='hostname.maindomain.tld';
Standard record that lists all authorized servers to send Emails in the domain to avoid spoofing attacks:
INSERT INTO records SET domain_id=1, name='mydomain.tld', type='TXT', content='v=spf1 mx -all';
-all | Fails authentication |
---|---|
~all | Softfails authentication |
+all | Passes authentication |
?all | Neutral |
Service | SPF record |
---|---|
Google Workspace | v=spf1 a mx include:_spf.google.com ~all |
Microsoft Exchange | v=spf1 include:spf.protection.outlook.com -all |
Mailchimp | v=spf1 include:spf.mandrillapp.com ?all |
INSERT INTO records SET domain_id=1, name='mydomain.tld', type='MX', content='aspmx.l.google.com 1';
INSERT INTO records SET domain_id=1, name='mydomain.tld', type='MX', content='alt1.aspmx.l.google.com 5';
INSERT INTO records SET domain_id=1, name='mydomain.tld', type='MX', content='alt2.aspmx.l.google.com 5';
INSERT INTO records SET domain_id=1, name='mydomain.tld', type='MX', content='alt3.aspmx.l.google.com 10';
INSERT INTO records SET domain_id=1, name='mydomain.tld', type='MX', content='alt4.aspmx.l.google.com 10';
Automatically added.
INSERT INTO records SET domain_id=1, name='auth._domainkey.mydomain.tld', type='TXT', content='v=DKIM1; h=rsa-sha256; k=rsa; p=DKIM_KEY_HERE';
INSERT INTO records SET domain_id=1, name='_dmarc.mydomain.tld', type='TXT', content='v=DMARC1; p=reject; pct=100';
p=Policy: reject, none (no action) or quarantine (move to junk/spam Email folder).
nslookup command | Function |
---|---|
nslookup mydomain.tld 127.0.0.1 | General domain test A/AAAA |
nslookup -type=soa mydomain.tld 127.0.0.1 | For SOA record |
nslookup -debug -type=a mydomain.tld 127.0.0.1 | For A record and show detailed debug |
dig command | Function |
---|---|
dig @127.0.0.1 A mydomain.tld | For A record |
dig @127.0.0.1 A +dnssec mydomain.tld | Requesting A with DNSSEC |
Implementation of new Internet protocols is a hard way, because all systems have the original protocols first, and new ones are not usually adapted, and unable to replace them. We can see many examples such as IPv6, HTTP/2, HTTP/3 Quic, DNSSEC (neither Google or Microsoft use it), DoT or DoH...
The new protocols: DoT (DNS-over-TLS) and DoH (DNS-over-HTTPS) proposed at Internet Engineering Task Force (IETF) to encrypt DNS traffic, to prevent eavesdropping and manipulation of DNS data via man-in-the-middle attacks. But since UDP is the main DNS protocol, it´s not recommended to disable it and enable only the new ones protocols for backwards reasons and to avoid to be unreachable, you must combine them. Therefore, using it is more exotic than functional.
Encrypts DNS traffic queries through the Transport Layer Security (TLS) protocol on port 853.
Set protocol_dot=true
, dot_key
and dot_cert
(Let´s Encrypt) certificates paths in junedns.conf
Encrypts DNS traffic queries through a Hypertext Transfer Protocol Secure encrypted session (HTTPS) on port 443 and endpoint: /dns-query
Set protocol_doh=true
, doh_key
and doh_cert
(Let´s Encrypt) certificates paths in junedns.conf
Example:
doh_port=443
doh_cert=ACME_PATH/mydomain.tld/fullchain.cer
doh_key=ACME_PATH/mydomain.tld/mydomain.tld.key
If you have conflicts with port 443 (HTTPS) due to a Web server service running in the same machine like Nginx, then you can proxy DoH port from an available free doh_port=8085 to 443, and empty values for doh_cert / doh_key to force JuNeDNS Server to run DoH in HTTP mode (so SSL certificate through Nginx):
doh_port=8085
doh_cert=
doh_key=
Nginx config:
server {
listen 443 ssl;
listen [::]:443 ssl; #http3?
server_name mydomain.tld;
ssl_certificate ACME_PATH/mydomain.tld/fullchain.cer;
ssl_certificate_key ACME_PATH/mydomain.tld/mydomain.tld.key;
ssl_protocols TLSv1.2 TLSv1.3;
location / {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://127.0.0.1:8085;
}
}
With this technique you could combine your Website and DoH in the same server with location /dns-query
Test it (to output file): curl -H "accept: application/dns-json" "http://127.0.0.1:8085/dns-query?name=mydomain.tld&type=A" --output file.bin
dnssec=true in junedns.conf
Domain Name System Security Extensions, provides cryptographic authentication of DNS records, according to RFC 4035, with Authenticated Data (AD) and Checking Disabled (CD) flags on header.
ZSK (Zone Signing Keys) and KSK (Key Signing Keys) private and public DNSSEC keys will be created and inserted into database automatically on the first resolve request.
DS, DNSKEY and RRSIGs records are dynamically generated by JuNeDNS Server, so they don´t appear in records database table.
dig @127.0.0.1 A +dnssec mydomain.tld
mydomain.tld. 3600 IN A 1.2.3.4
mydomain.tld. 3600 IN RRSIG A 8 2 3600 20230715080515 20230615080515 50238 mydomain.tld. DAtckAl17....
dig @127.0.0.1 DNSKEY +multi mydomain.tld
dig @127.0.0.1 DS mydomain.tld
Domain Keys Identified Mail, for Email authentication with digital signature to prevent spoofing, phishing and spam. Install from OpenDKIM and configure it. DKIM signature and setup will be created and inserted into database automatically on the first resolve request, so it´s mandatory to config OpenDKIM path for domains, binary to GenKey, and DKIM selector (same as Selector in opendkim.conf):
dkim_path=/etc/opendkim
dkim_genkey=/usr/sbin/opendkim-genkey
dkim_selector=auth
Domain-based Message Authentication, Reporting and Conformance, protect Email from unauthorized use for Email spoofing, indicating that Emails are protected by SPF and/or DKIM.
For security, maximum log size per file will be 50 Mb or truncate.
Line formats in junedns.log
when log=2
(or 3) in junedns.conf
yyyy-mm-dd hh:mm:ss [REQ|RES|FWD|ERR] IP: <ip> protocol info
protocol: UDP, TCP, DoT or DoH.
Sample of mydomain.tld SOA resolve Request from IP 1.2.3.4 UDP (info = DNS request in JSON):
2023-06-15 09:45:05 [REQ] IP: <1.2.3.4> UDP {"header":{"id":2,"qr":1,"opcode":0,"aa":0,"tc":0,"rd":1,"ra":0,"z":0,"ad":0,"cd":0,"rcode":0,"qdcount":1,"nscount":0,"arcount":0,"ancount":0},"questions":[{"name":"mydomain.tld","type":6,"class":1}],"answers":[],"authorities":[],"additionals":[]}
2023-06-15 09:45:05 [RES] IP: <1.2.3.4> UDP SOA mydomain.tld -> {"name":"mydomain.tld","type":6,"class":1,"ttl":259200,"primary":"ns1.nsdomain.tld","admin":"info.mydomain.tld","serial":"3","refresh":"10380","retry":"3600","expiration":"604800","minimum":"3600"}
junedns.conf
2023-06-15 09:45:05 [ERR] IP: <1.2.3.4> UDP ER_BAD_DB_ERROR: Unknown database 'junedns'
2023-06-15 09:45:05 [NXDOMAIN] IP: <1.2.3.4> UDP nonexistentdomain.tld
This is useful if you need to prevent NXDOMAIN Flood DDoS attacks, see Fail2ban.🐧Linux: Add rotate log functionality and keep in mind that log file will be increase over time.
/var/log/junedns.log
and changing const flog value in server.js/etc/logrotate.d/junedns
and set correctly JuNeDNS_PATHJuNeDNS_PATH/junedns.log {
daily
missingok
rotate 4
compress
copytruncate
create 600 root root
}
Get executable compiled in folder dist/ (x64 bits) for: 🐧Linux, 🪟 Windows and 🍎MacOS.
npm run build
or by platform npm run build-linux
(or build-win, build-macos)Using acme.sh to create/renew SSL certificates for HTTPS, and create TXT domain challenge.
ACME_PATH/dnsapi
sudo apt install mariadb-client
ACME_PATH/account.conf
JUNEDNS_DBName='junedns'
JUNEDNS_DBUser='junednsusr'
JUNEDNS_DBPass=''
Then to create a new certificate:
ACME_PATH/acme.sh --issue --dns dns_junedns -d "mydomain.tld" --server letsencrypt
Let´s Encrypt is free but only 3 months validity.
Add cron task to automatically renew SSL certificates:
ACME_PATH/acme.sh --home "ACME_PATH" --renew-all --stopRenewOnError --server letsencrypt --cron
Use --server letsencrypt to allow * wildcard domains (default ZeroSSL not supported).
✔️JuNeDNS detects if certificates are renewed (different datetime) and restarts DoT or DoH automatically.
SSL certificates are always needed from a Certification Authority entity (CA), because software like browsers require a trusted signer (we don´t know why / what exactly these entities certifies about us❓), unless you want to see the scary browser warning about ´Potential Security Risk´. If you want to generate a self-signed certificate key pair, only for testing/development purposes (not for production environments) private-key.pem and public-cert.pem:
openssl genrsa -out private-key.pem 2048
openssl req -new -key private-key.pem -out csr.pem
openssl x509 -req -in csr.pem -signkey private-key.pem -out public-cert.pem
🛡️Just in case you want to know how apply Fail2ban and Iptables. Although no real way to protect yourself against these attacks.
If you want to prevent DDoS / brute force attacks you can use Fail2ban. Don´t forget that you may receive several resolve requests from the same IP (others DNS servers), although of different users. Set maxretry to a high value. Example for UDP:
log=2
in junedns.conf
/etc/fail2ban/jail.d/junedns.conf
[junedns-iptables]
enabled = true
port = dns
filter = junednsfilter
action = iptables[name=junedns, port=53, protocol=udp]
logpath = /etc/junedns/junedns.log
maxretry = 10
/etc/fail2ban/filter.d/junednsfilter.conf
[Definition]
failregex = ^.+IP: <HOST>.+$
ignoreregex =
[Definition]
failregex = ^.+NXDOMAIN.+IP: <HOST>.+$
ignoreregex =
fail2ban-client set junedns-iptables unbanip 1.2.3.4
To protect against DDoS (Distributed Denial of Service) attacks or DNS amplification DDoS attacks, you could limit rate to accept queries.
iptables -A INPUT -p udp –dport 53 -m hashlimit
–hashlimit-name DNS –hashlimit-above 20/second –hashlimit-mode srcip
–hashlimit-burst 100 –hashlimit-srcmask 28 -j DROP
https://github.com/EduardoRuizM/junedns-backend
https://github.com/EduardoRuizM/junedns-frontend
https://github.com/EduardoRuizM/junedns-noip
Dataclick Olimpo JuNeDNS
Using SQL sentences to export domains / records, and with access to both databases (adjust names). Truncate JuNeDNS tables to start from scratch:
DELETE FROM junedns.domains;
INSERT INTO junedns.domains (id, name, nopunycode, created)
SELECT id, name, name, CURRENT_DATE FROM powerdns.domains;
DELETE FROM junedns.records;
INSERT INTO junedns.records (domain_id, name, type, content, ttl, disabled)
SELECT domain_id, name, type, TRIM(CONCAT_WS('', content, ' ', prio)), ttl, disabled FROM powerdns.records;
File | Description |
---|---|
lib/ | Dependences classes and constants |
dns_junedns.sh | Let´s Encrypt API for acme.sh to create/renew SSL certificates |
junedns.conf | Configuration file for database, etc... |
junedns.service | Systemctl service for binary or source code execution |
logo.png | JuNeDNS Logo free to use |
mysql.sql | MySQL/MariaDB database tables |
package.compile.json | package.json file to compile binaries in folder dist/ |
package.json | Original package.json |
README.md | Full guide about JuNeDNS and DNS service/protocol in markdown |
server.js | Lightweighted JuNeDNS Server main file, just 10 Kb (JuNe Philosophy) |
JuNeDNS | PowerDNS | Diff % | |
---|---|---|---|
Source Code | 63 Kb | 7.503 Kb | 0,8 % |
Files / Folders | 5 / 1 | 663 / 35 | 0,7 % / 2,8 % |
Compiled | 50 Mb | 394 Mb | 13 % |
FAQs
Dataclick Olimpo - JuNeDNS Server
The npm package junedns-server receives a total of 8 weekly downloads. As such, junedns-server popularity was classified as not popular.
We found that junedns-server demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Socket's package search now displays weekly downloads for npm packages, helping developers quickly assess popularity and make more informed decisions.
Security News
A Stanford study reveals 9.5% of engineers contribute almost nothing, costing tech $90B annually, with remote work fueling the rise of "ghost engineers."
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.