215

I need to test sub-domains on my localhost. How can I effectively have this result of adding *.localhost.com to my /etc/hosts/ file?

If it's not possible, how do I work around this problem? I need to test wildcard sub-domains on my localserver. It is a Django devserver, can the Django dev server handle the sub-domains? Can some other piece of software/routing give me the end result I want?

Greenonline
  • 215
  • 2
  • 5
  • 13
MikeN
  • 8,252
  • 5
  • 22
  • 18
  • 1
    Belongs on superuser ? – Paul R Mar 02 '10 at 16:48
  • I know people say it's not possible! But how do I do it anyway! What is something outside of /etc/hosts/ I can use to get the effect. I'm testing a development server. – MikeN Mar 02 '10 at 20:17
  • on superuser: http://unix.stackexchange.com/questions/3352/wildcard-in-etc-hosts-file – Ciro Santilli OurBigBook.com Aug 06 '14 at 09:31
  • As most answers are focusing on your first question (localhost subdomain wildcards), I'll answer your secondary question as a comment: yes, the Django dev server is perfectly capable of handling localhost subdomains, you just have to convince your browser and your OS to send the traffic its way (using one of the various solutions below)! – hheimbuerger Mar 09 '18 at 21:22

15 Answers15

179

Install dnsmasq (I do this on all my Linux desktops as a DNS cache anyways). In dnsmasq.conf add the line:

address=/localhost.com/127.0.0.1
Cristian Ciupitu
  • 6,226
  • 2
  • 41
  • 55
tomchuk
  • 1,941
  • 2
  • 10
  • 3
  • Thank you! I've been wanting this for years. It works wonderfully. Now I don't have to edit /etc/hosts every time I make a new website to test locally. – JasonWoof Oct 09 '10 at 22:30
  • dnsmasq.conf didn't exist by default. I created the file /etc/dnsmasq.conf and added just that line and started $sudo dnsmasq. The browsers picked up the changes without restart. – so_mv Sep 13 '11 at 07:58
  • 7
    Brilliant! Note for Mac users, it really is this simple: 1. `sudo port install dnsmasq` 2. edit `/opt/local/etc/dnsmasq.conf` 3. `sudo port load dnsmasq` – tomc Nov 16 '11 at 11:57
  • 23
    OSX with brew: same as above but brew install dnsmasq – Matt Humphrey Mar 07 '13 at 21:41
  • 2
    fyi brew > port (re @MattHumphrey suggestion) – electblake Mar 22 '13 at 02:57
  • 1
    This example doesn't work for me, possibly because I'm using http://vagrantup.com for local serving. Don't worry, I already changed the IP to the correct one `192.168.50.11` but DNS is not resolving. Any ideas, is this example correct for "non-127.0.0.1" IP's? – Brian Oct 27 '13 at 19:55
  • I like how it comes with the rule `/double-click.net/127.0.0.1` commented out... which is exactly why I looked up this question. – Gary Apr 11 '15 at 16:18
  • 6
    Great tip. For an Ubuntu 14.04 desktop (which runs dnsmasq by default), create a file called `/etc/NetworkManager/dnsmasq.d/dnsmasq-localhost.conf` and put the line `address=/localhost.com/127.0.0.1` in it, then restart. – user38397 May 21 '15 at 18:48
  • For OSX, here is a detail setup http://passingcuriosity.com/2013/dnsmasq-dev-osx/ – Js Lim Nov 30 '15 at 03:33
  • Any ideas how to do this or if this still works in Ubuntu 15.10? The instructions above for 14.04 didn't work for me. – Ibrahim Mar 07 '16 at 08:08
  • If it doesn't work for OS X check out this http://stackoverflow.com/a/19651350/1903743 – Taylan Mar 22 '16 at 10:01
  • See https://www.leaseweb.com/labs/2013/08/wildcard-dns-ubuntu-hosts-file-using-dnsmasq/ for more info. Worked on a Debian 8. – Ricalsin Sep 06 '16 at 19:43
  • 2
    How can I do this for multiple domains? And how do I refresh after editing the file? I want `*.localhost` and `*.loc`. I added two lines: `address=/localhost/127.0.0.1` and `address=/loc/127.0.0.1`. For some reason only the first one works. And after commenting out both, and calling `sudo service dnsmasq restart` and `sudo service network-manager restart` I still have the *.localhost version working. – donquixote Sep 11 '17 at 22:33
  • This solution works perfectly. Don't be fooled on Ubuntu 18. There is a dnsmasq.d directory. This doesn't mean dnsmasq is installed! You need to install dnsmasq. Some great instructions can be found here: https://computingforgeeks.com/install-and-configure-dnsmasq-on-ubuntu-18-04-lts/ – mcmacerson May 04 '20 at 13:28
80

It is not possible to specify wildcards in the /etc/hosts file. Either specify the required hostnames explicitly or alternatively set up a local name server with the appropriate rules.

ar.
  • 1,084
  • 6
  • 3
51

I have written a dns proxy in Python. It will read wildcard entries in /etc/hosts. See here: https://github.com/hubdotcom/marlon-tools/blob/master/tools/dnsproxy/dnsproxy.py

marlonyao
  • 626
  • 6
  • 3
  • This is perfect! I have been looking for a simple solution like this for a long time (Working on OSX Mavericks BTW) – Billy Moon Nov 05 '13 at 22:07
  • 2
    now, if we could only just `pip install` it :) – metakermit Mar 25 '14 at 11:39
  • 1
    I installed this, did everything and ran it, but it does not block sites. – DisplayName Dec 13 '15 at 18:47
  • Can not upvote this enough. I've needed this forever, stumbled upon this gem of a question and answer, and I'm a bit of a Python hacker, and this is a neat tidbit. Thanks for sharing! – Farley Sep 08 '16 at 15:41
16

You need to set up a DNS server and have each client use it for resolution. The server itself can be something as "light" as dnsmasq or as heavy as BIND.

Gerald Combs
  • 6,331
  • 23
  • 35
15

Simple Workflow (no need to install anything)

I personally like to create a PAC file for that and make my browser just use it.

Step 1: create a file e.g.: *.proxy.pac* somewhere (I use my $home folder)

Step 2: paste this code (example is with port 8000):

function FindProxyForURL(url, host) {
  if (shExpMatch(host, "*localhost")) {
    return "PROXY localhost:8000";
  }
  return "DIRECT";
}

Step 3: Make your Browser use this PAC file.

Youtube Video for PAC & Firefox

Step 4: Now you can test your app by accessing: http://mysubdomain.localhost/

Step 5: Enjoy :)

techraf
  • 4,163
  • 8
  • 27
  • 44
Bijan
  • 101
  • 1
  • 4
  • 7
    Perhaps it is worth mentioning that this will only affect your browser. Other programs (like `wget`, will not get affected by this). That is not per se a problem, but perhaps it is better to mention this. – Willem Van Onsem Apr 24 '18 at 21:02
  • If you go the .pac route and you're implementing a node.js server, you will be surprised to see that `req.url` is now an absolute URL. This is done because the assumption is that you want to write an actual proxy server, but it is surprising if you came to this technique just as a way to stop adding /etc/hosts entries for debugging. FYI to those who might go the same road I did. – Tom Boutell Jan 02 '19 at 20:26
  • How I can apply this to Google Chrome/mium & Brave browser as well? – Dimitrios Desyllas Sep 16 '21 at 11:27
6

I've tidied up an old project of mine:

https://github.com/airtonix/avahi-aliases

requirements:

  • linux where avahi and python-avahi are installable
  • you're ok with .local domains (avahi doesn't support any other kind)

Advantages over using dnsmasq or the python dns proxy:

  • other avahi/bonjour users on your local network can resolve the aliases you create and announce to the network ( providing you're allowing access to port 5353 )
airtonix
  • 171
  • 1
  • 3
4

You cannot use a wildcard in /etc/hosts.

Have a look here for a good walkthrough on how to accomplish on OS X using BIND, the built-in but inactive DNS server, and Apache.

pauska
  • 19,532
  • 4
  • 55
  • 75
Trevor
  • 199
  • 2
4

This DNS based solution worked perfectly in my case, without need to install anything : https://gist.github.com/fedir/04e60d679d5657d1f9f9aa10b3168282 (Mac OSX 10.9)

Fedir RYKHTIK
  • 577
  • 8
  • 18
3

Copying from this blog here is how to do it on mac:

https://hedichaibi.com/how-to-setup-wildcard-dev-domains-with-dnsmasq-on-a-mac/

~ brew install dnsmasq

~ vim /usr/local/etc/dnsmasq.conf

# This file will be added to the configuration
conf-file=/Users/your_user_name/.dnsmasq/dnsmasq.conf

~ vim /Users/your_user_name/.dnsmasq/dnsmasq.conf

# example.localhost will be resolved as 127.0.0.1, including subdomains
address=/example.localhost/127.0.0.1
listen-address=127.0.0.1

~ sudo brew services stop dnsmasq

~ sudo brew services start dnsmasq

We need to tell macOS to use 127.0.0.1 as the first DNS resolver.

enter image description here

Lance
  • 233
  • 2
  • 8
3

If you want to use dnsmasq with NetworkManager you can (or even must?) start dnsmasq from NetworkManager by adding

dns=dnsmasq

to /etc/NetworkManager/NetworkManager.conf. Then the dnsmasq config goes to /etc/NetworkManager/dnsmasq.conf or /etc/NetworkManager/dnsmasq.d/ resp.

TNT
  • 131
  • 2
2

Short answer:

Your /etc/hosts/ file won't let you use wildcards or port numbers. You will need to create one entry for each of your subdomain

2

The short answer is you don't. The longer answer is you need to be clearer on what you desire to actually achieve, because there is perhaps either a better way, and a different way to achieve it.

For web-hosting (I've never seen it used otherwise) is done in DNS in combination with a virtual hosting aware web server. For more information on wildcard DNS records (Wikipedia), and an article Wildcard hosting with Apache and Bind for Linux using bind and Apache.

At worst, you could use a local DNS server I suppose.

mctylr
  • 865
  • 4
  • 9
2

dnsmasq worked for me, except I had to make some additional steps.

Here is the full procedure:

  1. Prepend /etc/resolv.conf with the following line

     nameserver 127.0.0.1
    
  2. Add the following lines to /etc/dnsmasq.conf

     listen-address=127.0.0.1
     address=/localhost.localdomain/127.0.0.1
     address=/localhost/127.0.0.1
    
  3. Restart dnsmasq (do not simply tell dnsmasq to reload the config files)

Jayen
  • 1,827
  • 3
  • 16
  • 27
jbangerter
  • 121
  • 2
2

A common task for this subject is to map directories to subdomains. A very straightforward way for that is to append the directory-based entries automatically to the hosts file:

#!/usr/bin/python

import os

hostsFile = open("/etc/hosts", "a+");

lines = hostsFile.readlines()

for fileName in os.listdir('/opt/subdomainDirs'):

    entryExists = False
    for line in lines:
        if fileName in line:
            entryExists = True  

    if not entryExists:
        hostsFile.write("127.0.0.1 " + fileName + ".localhost\n");
2

Thank you tschundeee for what I consider to be the ultimate answer to this issue, wish I could just comment but here is the total configuration for those trying to accomplish the original goal (wildcards all pointing to same codebase -- install nothing, dev environment ie, XAMPP)

hosts file (add an entry)

file: /etc/hosts (non-windows)

127.0.0.1   example.local

httpd.conf configuration (enable vhosts)

file: /XAMPP/etc/httpd.conf

# Virtual hosts
Include etc/extra/httpd-vhosts.conf

httpd-vhosts.conf configuration

file: XAMPP/etc/extra/httpd-vhosts.conf

<VirtualHost *:80>
    ServerAdmin admin@example.local
    DocumentRoot "/path_to_XAMPP/htdocs"
    ServerName example.local
    ServerAlias *.example.local
#    SetEnv APP_ENVIRONMENT development
#    ErrorLog "logs/example.local-error_log"
#    CustomLog "logs/example.local-access_log" common
</VirtualHost>

restart apache

create pac file:

save as whatever.pac wherever you want to and then load the file in the browser's network>proxy>auto_configuration settings (reload if you alter this)

function FindProxyForURL(url, host) {
  if (shExpMatch(host, "*example.local")) {
    return "PROXY example.local";
  }
  return "DIRECT";
}