I have the following setup:
NTP 10.21.3.169 | | 10.21.3.160 (eth1) Linux 10.0.0.67 (eth0) | | 10.0.0.65 (pcn1) OpenBSD
The idea is to allow the NTPD client (not OpenNTP) on the OpenBSD box to get the time from the NTP server by using port forwarding on the OpenBSD box and iptables on the Linux box.
I am at the stage where the following is true:
- The OpenBSD box's pf.conf has been set up correctly such that running
tcpdump udpon the Linux box shows the correct traffic from the OpenBSD box when I run
ntpd -d -s
- The Linux box's iptables configuration has been set up correctly such that running
ntpd -d -son the OpenBSD box, the traffic shows up using
tcpdump udpon the NTP server
But nothing comes back - there is no traffic on either machine in the other direction.
The iptables rules I am using on the Linux machine are:
iptables -A PREROUTING -t nat -i eth0 -p udp --dport 123 -j DNAT --to-destination 10.21.3.169:123 iptables -A FORWARD -t filter -p udp -d 10.21.3.169 --dport 123 -j ACCEPT
Which seems correct to me. There is also an "accept state RELATED/ESTABLISHED" rule in the IPTables configuration that was there before I started this work.
What am I doing wrong? Is there something missing? Perhaps some extra rules for the reply?
I have followed the advice in @gromit's answer and @MadHatter's comments, and have the following information to add:
On the Linux box, running
cat /proc/sys/net/ipv4/ip_forward gives
ntpd -d -s on the OpenBSD box with
"eth1 on the Linux box (in different terminals, at the same time) gives the following output.
[root@OpenBSDBox ~]# ntpd -d -s ntp engine ready no reply received in time, skipping initial time setting no reply from 10.0.0.67 received in time, next query 3227s
tcpdump -n -n -i eth0 port 123
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes 10:05:26.448943 IP 10.0.0.65.63822 > 10.0.0.67.123: NTPv4, Client, length 48
tcpdump -n -n -i eth1 port 123
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on eth1, link-type EN10MB (Ethernet), capture size 96 bytes 10:05:26.449220 IP 10.21.3.160.63822 > 10.21.3.169.123: NTPv4, Client, length 48 10:05:26.449148 IP 10.21.3.169.123 > 10.21.3.160.63822: NTPv4, Server, length 48
So it looks like the routing is still not right on the Linux box - the reply is coming back from the NTP box but is not being sent to OpenBSD.
Just for clarity, the iptables routing that I have added now looks like this:
iptables -t nat -A PREROUTING -i eth0 -p udp --dport 123 -j DNAT --to-destination 10.21.3.169:123 iptables -t filter -A FORWARD -p udp -d 10.21.3.169 --dport 123 -j ACCEPT iptables -t nat -A POSTROUTING -o eth1 -p udp --dport 123 -j MASQUERADE //for the final line, I changed @gromit's suggestion slightly, as the --from option wasn't recognised iptables -t nat -A POSTROUTING -p udp --sport 123 -j SNAT --to-source 10.21.3.169
Leaving that final
iptables line out seems to make no difference to the
I have now got the following IPtables entries, and I am able to update the clock on the OpenBSD box:
iptables -t nat -A PREROUTING -i eth0 -p udp --dport 123 -j DNAT --to-destination 10.21.3.169:123 iptables -t nat -A PREROUTING -i eth1 -p udp --sport 123 -j DNAT --to-destination 10.0.0.65:123 iptables -t filter -A FORWARD -p udp -d 10.21.3.169 --dport 123 -j ACCEPT iptables -t filter -A FORWARD -p udp -d 10.0.0.65 --sport 123 -j ACCEPT iptables -t nat -A POSTROUTING -o eth1 -p udp --dport 123 -j MASQUERADE iptables -t nat -A POSTROUTING -p udp --sport 123 -j SNAT --to-source 10.21.3.169
However the second prerouting and second filter commands seem like overkill to me, as, as I understand it, they forward all UDP packets from port 123 on the NTP server. I have a feeling that this means that all NTP replies that go to the Linux box (ie including when the Linux box itself asks for the time) will get forwarded to the OpenBSD box.