Skip to content

C Program To Work with IPTables as a SystemD service that will intercept NTP queries and forward them to a resolver of your choosing. Intented to allow blocking of NTP to all but 1 IP, limiting DDoS Reflection Surface.

License

Notifications You must be signed in to change notification settings

AVSISP/NTP-interception-Proxy

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 

Repository files navigation

NTP Proxy - Dual Stack IPv4/IPv6

High-performance asynchronous NTP proxy that intercepts NTP requests from specified clients (via ipset) and forwards them to a backend NTP server while maintaining the original destination IP as the source address in responses.

Features

  • 🚀 Asynchronous event-driven architecture (epoll)
  • 🌐 Full IPv4 and IPv6 client support
  • ⚡ High throughput with thread pool design
  • 🎯 Selective interception using ipset
  • 🔄 Automatic timeout handling
  • 📊 Query tracking and drop monitoring

Requirements

  • Linux kernel with netfilter support
  • libnetfilter-queue-dev
  • ipset
  • iptables and ip6tables
  • GCC compiler

Install Dependencies

# Debian/Ubuntu
apt-get update
apt-get install -y libnetfilter-queue-dev ipset iptables build-essential

# RHEL/CentOS
yum install -y libnetfilter_queue-devel ipset iptables gcc make

Configuration

1. Set Backend NTP Server

Edit ntp.c and change the NTP server IP address:

#define NTP_SERVER "pool.ntp.org"  // Change this to your NTP server
#define NTP_PORT 123

2. Compile

gcc -o ntp ntp.c -lnetfilter_queue -lpthread -O2

3. Install Binary

sudo install -m 755 ntp /usr/local/bin/ntp-proxy

IPSet Configuration

Create IPSets

# Create IPv4 ipset
ipset create myntp4 hash:ip family inet

# Create IPv6 ipset
ipset create myntp6 hash:ip family inet6

Add IPs to IPSets

# Add IPv4 addresses
ipset add myntp4 192.168.1.100
ipset add myntp4 10.0.0.0/24

# Add IPv6 addresses
ipset add myntp6 2001:db8::1
ipset add myntp6 fd00::/64

List IPSets

ipset list myntp4
ipset list myntp6

Save IPSets (persist across reboots)

# Save to file
ipset save > /etc/ipset.conf

# Restore on boot (add to /etc/rc.local or systemd)
ipset restore < /etc/ipset.conf

Firewall Rules

Apply iptables Rules

# IPv4 - Intercept NTP requests from myntp4 clients
iptables -t mangle -A PREROUTING -p udp --dport 123 -m set --match-set myntp4 src -j NFQUEUE --queue-num 123

# IPv6 - Intercept NTP requests from myntp6 clients
ip6tables -t mangle -A PREROUTING -p udp --dport 123 -m set --match-set myntp6 src -j NFQUEUE --queue-num 123

Make Rules Persistent

Option 1: Using iptables-persistent (Debian/Ubuntu)

apt-get install iptables-persistent
netfilter-persistent save

Option 2: Using systemd service

Create /etc/systemd/system/ntp-proxy-firewall.service:

[Unit]
Description=NTP Proxy Firewall Rules
Before=ntp-proxy.service
After=network.target

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/bash -c 'ipset restore < /etc/ipset.conf || true'
ExecStart=/sbin/iptables -t mangle -A PREROUTING -p udp --dport 123 -m set --match-set myntp4 src -j NFQUEUE --queue-num 123
ExecStart=/sbin/ip6tables -t mangle -A PREROUTING -p udp --dport 123 -m set --match-set myntp6 src -j NFQUEUE --queue-num 123
ExecStop=/sbin/iptables -t mangle -D PREROUTING -p udp --dport 123 -m set --match-set myntp4 src -j NFQUEUE --queue-num 123
ExecStop=/sbin/ip6tables -t mangle -D PREROUTING -p udp --dport 123 -m set --match-set myntp6 src -j NFQUEUE --queue-num 123

[Install]
WantedBy=multi-user.target

Enable it:

systemctl enable ntp-proxy-firewall.service
systemctl start ntp-proxy-firewall.service

Systemd Service

Create /etc/systemd/system/ntp-proxy.service:

[Unit]
Description=NTP Proxy - Dual Stack IPv4/IPv6
After=network.target ntp-proxy-firewall.service
Wants=ntp-proxy-firewall.service

[Service]
Type=simple
ExecStart=/usr/local/bin/ntp-proxy
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal

# Security hardening
NoNewPrivileges=false
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/log

# Resource limits
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

Enable and Start Service

# Reload systemd
systemctl daemon-reload

# Enable auto-start at boot
systemctl enable ntp-proxy.service

# Start the service
systemctl start ntp-proxy.service

# Check status
systemctl status ntp-proxy.service

# View logs
journalctl -u ntp-proxy.service -f

Service Management

# Restart service
systemctl restart ntp-proxy.service

# Stop service
systemctl stop ntp-proxy.service

# Disable auto-start
systemctl disable ntp-proxy.service

Complete Setup Example

# 1. Install dependencies
apt-get update && apt-get install -y libnetfilter-queue-dev ipset iptables build-essential

# 2. Compile
gcc -o ntp ntp.c -lnetfilter_queue -lpthread -O2

# 3. Install binary
sudo install -m 755 ntp /usr/local/bin/ntp-proxy

# 4. Create ipsets
ipset create myntp4 hash:ip family inet
ipset create myntp6 hash:ip family inet6

# 5. Add some IPs
ipset add myntp4 192.168.1.0/24
ipset add myntp6 2001:db8::/64

# 6. Save ipsets
ipset save > /etc/ipset.conf

# 7. Create firewall service
cat > /etc/systemd/system/ntp-proxy-firewall.service << 'EOF'
[Unit]
Description=NTP Proxy Firewall Rules
Before=ntp-proxy.service
After=network.target

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/bash -c 'ipset restore < /etc/ipset.conf || true'
ExecStart=/sbin/iptables -t mangle -A PREROUTING -p udp --dport 123 -m set --match-set myntp4 src -j NFQUEUE --queue-num 123
ExecStart=/sbin/ip6tables -t mangle -A PREROUTING -p udp --dport 123 -m set --match-set myntp6 src -j NFQUEUE --queue-num 123
ExecStop=/sbin/iptables -t mangle -D PREROUTING -p udp --dport 123 -m set --match-set myntp4 src -j NFQUEUE --queue-num 123
ExecStop=/sbin/ip6tables -t mangle -D PREROUTING -p udp --dport 123 -m set --match-set myntp6 src -j NFQUEUE --queue-num 123

[Install]
WantedBy=multi-user.target
EOF

# 8. Create ntp-proxy service
cat > /etc/systemd/system/ntp-proxy.service << 'EOF'
[Unit]
Description=NTP Proxy - Dual Stack IPv4/IPv6
After=network.target ntp-proxy-firewall.service
Wants=ntp-proxy-firewall.service

[Service]
Type=simple
ExecStart=/usr/local/bin/ntp-proxy
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal
NoNewPrivileges=false
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/log
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
EOF

# 9. Enable and start services
systemctl daemon-reload
systemctl enable ntp-proxy-firewall.service ntp-proxy.service
systemctl start ntp-proxy-firewall.service ntp-proxy.service

# 10. Verify
systemctl status ntp-proxy.service
journalctl -u ntp-proxy.service -f

Monitoring

Check Service Status

systemctl status ntp-proxy.service

View Real-time Logs

journalctl -u ntp-proxy.service -f

Check Queue Statistics

# Check NFQUEUE stats
cat /proc/net/netfilter/nfnetlink_queue

Verify IPSet Membership

# Check if an IP is in the set
ipset test myntp4 192.168.1.100
ipset test myntp6 2001:db8::1

Test NTP Synchronization

# Test NTP query from a client in the ipset
ntpdate -q pool.ntp.org

# Check system time sync status
timedatectl status

Troubleshooting

Service won't start

# Check for errors
journalctl -u ntp-proxy.service -n 50

# Verify binary exists
ls -l /usr/local/bin/ntp-proxy

# Check permissions
sudo /usr/local/bin/ntp-proxy

No NTP responses

# Verify iptables rules are active
iptables -t mangle -L PREROUTING -n -v
ip6tables -t mangle -L PREROUTING -n -v

# Check if packets are hitting the queue
cat /proc/net/netfilter/nfnetlink_queue

# Verify ipsets exist
ipset list

# Test NTP connectivity to backend server
ntpdate -q your.ntp.server

IPv6 not working

# Check IPv6 is enabled
sysctl net.ipv6.conf.all.disable_ipv6

# Verify IPv6 firewall rules
ip6tables -t mangle -L PREROUTING -n -v

# Test IPv6 connectivity
ping6 2001:4860:4860::8888

Time sync issues

# Check if NTP packets are being intercepted
tcpdump -i any udp port 123 -vv

# Verify backend NTP server is reachable
ntpdate -q <NTP_SERVER>

# Check for clock drift
ntpq -p

Performance Tuning

Adjust these values in ntp.c before compiling:

#define MAX_PENDING 1000        // Maximum concurrent queries
#define NTP_TIMEOUT_MS 300      // Query timeout in milliseconds
#define THREAD_POOL_SIZE 20     // Event loop thread count

Security Considerations

  • This proxy requires root privileges to use raw sockets and NFQUEUE
  • Only intercepts NTP requests from IPs in the ipset lists
  • Responses are spoofed to appear from the original destination IP
  • Enable NoNewPrivileges=true in systemd if not using raw sockets
  • Consider using authenticated NTP (NTPsec) for production environments

Use Cases

  • Centralized time source management for client networks
  • NTP traffic inspection and logging
  • Time synchronization in isolated network segments
  • Testing and development of NTP-dependent applications
  • Network time protocol monitoring and analysis

License

This project is provided as-is for educational and infrastructure purposes.

Architecture

Client (IPv4/IPv6) → iptables/ip6tables → NFQUEUE(123) → ntp-proxy
                                                            ↓
                                                    Backend NTP Server
                                                            ↓
                                                    ntp-proxy → Client
                                                    (spoofed source)

The proxy:

  1. Intercepts NTP requests via NFQUEUE
  2. Forwards them to the backend NTP server (IPv4)
  3. Receives responses
  4. Sends spoofed responses back to clients with original destination IP as source

About

C Program To Work with IPTables as a SystemD service that will intercept NTP queries and forward them to a resolver of your choosing. Intented to allow blocking of NTP to all but 1 IP, limiting DDoS Reflection Surface.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages