# Default server with custom 404

**URL:** <https://www.ruby-forum.com/t/default-server-with-custom-404/244414>\
**Category:** NGINX\
**Created:** [April 6, 2016, 3:26pm UTC](https://www.ruby-forum.com/t/default-server-with-custom-404/244414 "2016-04-06T15:26:37Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Rafa\_F](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/958977/32.png) [@Rafa\_F](https://www.ruby-forum.com/u/Rafa_F)\
**Post date:** [April 6, 2016, 3:26pm UTC](https://www.ruby-forum.com/t/default-server-with-custom-404/244414/1 "2016-04-06T15:26:37Z")

</div>

I see this question has been asked and answered many times, but I am  
unable to  
make it work.

On a server with multiple virtual hosts I wish to make a catchall which  
responds  
to everything with a 404 that reveals no information.

I am running nginx version: nginx/1.8.1 on ubuntu 14.04.

My catchall looks like this

server {  
listen 80 default\_server;  
listen 443 ssl default\_server;  
allow all;  
charset utf-8;  
error\_page 404 /404.html;  
root /mypath/html/;  
location = /404.html {  
root /mypath/html/;  
}  
location / {  
return 404;  
}  
}

if I make a fake /etc/hosts dns say [dongo.bilbo.com](http://dongo.bilbo.com) and point at my  
server then

[http://dongo.bilbo.com/404.html](http://dongo.bilbo.com/404.html) shows me the correct 404 page with no  
Nginx  
info, however, any other path eg [http://dongo.bilbo.com](http://dongo.bilbo.com) always shows me  
the  
standard Nginx 404 page.

Is there a way to customize my error page for this case?

I would add that the following works well for my real sites

> ```
> charset utf-8;
> error_page 404 /404.html;
> location /404.html {
> root /mypath/html;
> }
> 
> ```

and there I do see the 404.html from /mypath/html when I visit missing  
pages.

## Alternatively is there a way to override nginx’s 404 page so it doesn’t reveal the server.

Robin Becker

---

<div class="post-metadata">

**Author:** ![Robin\_Becker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/e79b87/32.png) [@Robin\_Becker](https://www.ruby-forum.com/u/Robin_Becker)\
**Post date:** [April 7, 2016, 12:15am UTC](https://www.ruby-forum.com/t/default-server-with-custom-404/244414/2 "2016-04-07T00:15:19Z")

</div>

On Wed, Apr 06, 2016 at 02:26:25PM +0100, Robin Becker wrote:

Hi there,

> I see this question has been asked and answered many times, but I am  
> unable to make it work.

It seems to work for me.

Are you certain that no caching in front of nginx is interfering with  
your tests?

What do you see if you do something like

curl -v -H Host:anything [http://your-server/should-give-404](http://your-server/should-give-404)

?

> On a server with multiple virtual hosts I wish to make a catchall  
> which responds to everything with a 404 that reveals no information.

What information does the default nginx internal 404 response reveal,  
that your own file does not? See the “curl -v” response above for the  
http headers.

> I am running nginx version: nginx/1.8.1 on ubuntu 14.04.
> 
> My catchall looks like this
> 
> server {  
> listen 80 default\_server;

This will be the default server over any others that have “listen \*:80”  
(in its various guises). If you have anything like “listen ip” anywhere,  
then any connection to that IP will not use this server{}.

You most likely do not have “listen ip” anywhere. But just in case –  
this is not necessarily a catch-_all_.

> if I make a fake /etc/hosts dns say [dongo.bilbo.com](http://dongo.bilbo.com) and point at my server then
> 
> [http://dongo.bilbo.com/404.html](http://dongo.bilbo.com/404.html) shows me the correct 404 page with  
> no Nginx info, however, any other path eg [http://dongo.bilbo.com](http://dongo.bilbo.com)  
> always shows me the standard Nginx 404 page.

That’s not what I get.

If you still have the problem, perhaps the debug log will show more  
about what is going on.

> Is there a way to customize my error page for this case?

What you have done should work. Depending on the rest of your config,  
of course.

> Alternatively is there a way to override nginx’s 404 page so it  
> doesn’t reveal the server.

Patch the code and recompile.

You probably don’t want to do that.

## f

Francis D. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![Robin\_Becker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/e79b87/32.png) [@Robin\_Becker](https://www.ruby-forum.com/u/Robin_Becker)\
**Post date:** [April 7, 2016, 11:31am UTC](https://www.ruby-forum.com/t/default-server-with-custom-404/244414/3 "2016-04-07T11:31:46Z")

</div>

On 06/04/2016 23:14, Francis D. wrote:  
…

> > Alternatively is there a way to override nginx’s 404 page so it  
> > doesn’t reveal the server.
> 
> Patch the code and recompile.
> 
> You probably don’t want to do that.
> 
> f

I suspect my issue has more to do with me not understanding the way  
server names  
are matched. I look in vain for some equivalent to apache2ctl -S, but  
can’t find it.

I have only one vhost with the default\_server present and thought that

listen 80 default\_server;

would fire for servers without an explicit match. Some simple testing  
reveals  
another is matching, but I don’t know which one yet.

As this is a live server I won’t try the debug route there, just bad  
luck we got  
an IP address that had previous connections to some kind of music  
distribution.

Compiling nginx would be a last resort.

## Sorry for the noise.

Robin Becker

---

<div class="post-metadata">

**Author:** ![Robin\_Becker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/e79b87/32.png) [@Robin\_Becker](https://www.ruby-forum.com/u/Robin_Becker)\
**Post date:** [April 7, 2016, 2:17pm UTC](https://www.ruby-forum.com/t/default-server-with-custom-404/244414/4 "2016-04-07T14:17:41Z")

</div>

On Thu, Apr 07, 2016 at 10:31:31AM +0100, Robin Becker wrote:

> On 06/04/2016 23:14, Francis D. wrote:

Hi there,

> > > Is there a way to customize my error page for this case?
> > 
> > What you have done should work. Depending on the rest of your config,  
> > of course.

> I suspect my issue has more to do with me not understanding the way  
> server names are matched. I look in vain for some equivalent to  
> apache2ctl -S, but can’t find it.

[nginx documentation](http://nginx.org/en/docs/) links to  
[How nginx processes a request](http://nginx.org/en/docs/http/request_processing.html) for the first,  
and [Command-line parameters](http://nginx.org/en/docs/switches.html) for the second.

Very approximately,

nginx -T | grep ‘listen|server’

will indicate your server{} blocks, their contained listen directives,  
and their contained server\_name directives.

(Except: “nginx -T” isn’t in v1.8.1. So grep in your config file, and  
in any files that you “include” in it.)

When you know the IP:port the connection arrives on, plus the hostname  
that is requested, you can probably work out which server{} block nginx  
will choose to handle the request.

> I have only one vhost with the default\_server present and thought that
> 
> listen 80 default\_server;
> 
> would fire for servers without an explicit match. Some simple  
> testing reveals another is matching, but I don’t know which one yet.

For every unique “listen IP” or “listen IP:80” directive that you  
have anywhere in your config, add the same line to this server{} with  
default\_server set.

(Which means: if you have somewhere “listen 127.0.0.1:80;”, then you  
add a line “listen 127.0.0.1:80 default\_server;” to your catch-all  
server block.)

> As this is a live server I won’t try the debug route there, just bad  
> luck we got an IP address that had previous connections to some kind  
> of music distribution.

Install nginx on your test machine. Configure it there until you are  
happy that it does what you want. Then transfer the config to your  
production machine.

Good luck with it,

## f

Francis D. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![Robin\_Becker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/e79b87/32.png) [@Robin\_Becker](https://www.ruby-forum.com/u/Robin_Becker)\
**Post date:** [April 7, 2016, 3:05pm UTC](https://www.ruby-forum.com/t/default-server-with-custom-404/244414/5 "2016-04-07T15:05:00Z")

</div>

On 07/04/2016 13:17, Francis D. wrote:  
…

> For every unique “listen IP” or “listen IP:80” directive that you  
> have anywhere in your config, add the same line to this server{} with  
> default\_server set.
> 
> (Which means: if you have somewhere “listen 127.0.0.1:80;”, then you  
> add a line “listen 127.0.0.1:80 default\_server;” to your catch-all  
> server block.)

…  
Ah I begin to see the light, I had thought the default\_server attribute  
would  
force this irrespective of the listen now I see I have to allow  
listening with  
all the patterns eg IP1:80 IP1:443 IP2:80… that makes things much  
clearer. Thank you very much.

> Good luck with it,
> 
> f

–  
Robin Becker
