I've done this in my last few significant development servers.
I use dbdns to setup a DNS server under my control on the server, with the 'tinydns' and 'dnscache' programs running.
In tinydns, I setup a custom/local top-level DNS space (/service/dnscache/root/data):
# Nameservers for the local TLDs
.virtual::ns.virtual
# an address for the machine
=virtual:192.168.1.100
=ns.virtual::192.168.1.100
# TLD and a second level DNS wildcard
+virtual:192.168.1.95:
+*.virtual:192.168.1.95:
# some have specific addresses
+fred.virtual:192.168.1.97
Then, I tell dnscache where to look for *.virtual domain names car of the file: /service/dnscache/root/servers/virtual
# which IP address tinyDNS runs on
127.0.0.1
Now, going to bill.virtual (or anything else not specifically give) will return 192.168.1.95.
Set the address of the dnscache server as the local name servers and you too should be able to ping the address of bill.virtual - and then you can have those names picked up with Apache to serve websites.