Skip to content

Latest commit

 

History

History
432 lines (316 loc) · 9.51 KB

File metadata and controls

432 lines (316 loc) · 9.51 KB

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