Fix ntp time sync in virtual machines with kvm-clock

Posted in doh , Virtual

I know this problem is caused in different ways for each virtualization platform. And while my specific problem was using KVM, this should avoid the problem on all of them.

If all I wanted to do was fix the clock on a VM guest, I would have stopped running ntp on the guest and left it running on the underlying physical host. My requirement was to use the ip address of my VM guest as a time source.

If your host system uses Time Stamp Counter (TSC)…

# grep -m1 constant_tsc /proc/cpuinfo
flags  : fpu vme de pse tsc blah blah blah...
constant_tsc
# cat /sys/devices/system/clocksource/clocksource0/current_clocksource
tsc

and Virtual Machine guests use kvm-clock…

# cat /sys/devices/system/clocksource/clocksource0/current_clocksource
kvm-clock
# dmesg | grep clock
...
[    0.056001] kvm-clock: cpu 11, msr 0:11975701, secondary cpu clock
[    0.388036] Switching to clocksource kvm-clock
[    0.637349] rtc_cmos 00:01: setting system clock to 2012-01-21 19:18:21 UTC

Then you should not use ntp on the guest!

analog-clock

But what if you must use a guest as a time *source* ? If the physical host synchronizes to a good Internet time source and the VM guest uses itself (127.0.0.1), what would happen? Well it would still be fighting the clock. So that’s not going to work. I was just hoping to avoid spike messages showing up in client ntp logs, but the clock can skew drastically in either direction.

iptables MASQUERADE to the rescue!

Stop running ntpd on the guest and forward all ntp requests that come in to a physical host serving NTP. You need two rules minimum:

iptables -t nat -A PREROUTING -i eth0 -p udp -m udp --dport 123 -j DNAT --to-destination $HOST
iptables -t nat -A POSTROUTING -o eth0 -p udp -m udp --dport 123 -j MASQUERADE

If you have two interfaces, you can forward the traffic from one network to the other this way too. Just change the -i eth0 to match the other network interface and then allow forwarding:

sysctl net.ipv4.conf.eth0.forwarding=1
sysctl net.ipv4.conf.eth1.forwarding=1

Even if you only have one interface and the ntp server is on the same network, the masquerade should still work.

You should really limit forwarding to ntp for your source and destination too. Default policies of ACCEPT for iptables are bad if you don’t have an explicit rule to drop everything not handled by a higher rule.

# forwarding for ntp requests to your ntp server
iptables -A FORWARD -p udp -d 10.9.8.7/32 --dport 123 -j ACCEPT
# forwarding for responses from your ntp server
iptables -A FORWARD -p udp -d 192.168.1.0/24 --dport 123 -j ACCEPT
Posted by admica   @   23 January 2012
Tags : , , , , ,

Related Posts

0 Comments

No comments yet. Be the first to leave a comment !
Leave a Comment

Name

Email

Website

*

Previous Post
«
Next Post
»
Powered by Wordpress   |   Lunated designed by ZenVerse

Valid XHTML 1.0 Transitional