# Filtering out long (invalid) hostnames

**URL:** <https://www.ruby-forum.com/t/filtering-out-long-invalid-hostnames/237383>\
**Category:** NGINX\
**Created:** [November 9, 2013, 9:45pm UTC](https://www.ruby-forum.com/t/filtering-out-long-invalid-hostnames/237383 "2013-11-09T21:45:41Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Detlef\_R](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/58f4c7/32.png) [@Detlef\_R](https://www.ruby-forum.com/u/Detlef_R)\
**Post date:** [November 9, 2013, 9:45pm UTC](https://www.ruby-forum.com/t/filtering-out-long-invalid-hostnames/237383/1 "2013-11-09T21:45:41Z")

</div>

Recently we have seen some kind of hacker attempt on our hosting  
servers, passing very long hostnames in the HTTP Host: header. That  
means length(hostname) was higher than 2000, for few requests even more  
than 10000.

This was processed well by nginx, passed further to our upstreams, what  
caused only little trouble there: logs were filled with a lot of  
garbage.

After bit of investigation, I have found that according to RFC, the  
longest domain name should not be more than 253 characters. Also,  
splitting domain into labels (labels are strings between dots), each  
label should not exceed 63 characters.

For more info: [Domain Name System - Wikipedia](http://en.wikipedia.org/wiki/Domain_Name_System)  
(search for “Domain name syntax” part)

That raises question how nginx handles this kind of long hostnames, and  
why it still pasess those invalid hostnames to backends (upstreams).

However it still passes it, and we want to filter that out. Because the  
performance matters us much, we want to do that the best possible way.

CASE #1:

```
 if ($host ~* "^.{254,}$") {
     return 403;
 }

```

CASE #2: (this is probably more efficient)

```
 server {
     server_name "~^.{254,}$";
     listen 80;
     return 403;
 }

```

Case #2 is probably more efficient, but in both cases are regular  
expressions used. Would it matter if we put that server {} block at the  
end of our server list?

Also would it make any sense to check for a dot (.) in a server\_name or  
$host, and when not dot is present, return 403 as well?

Thanks for sharing your thoughts

Ondrej

–  
Ondrej JOMBIK  
Platon Technologies s.r.o., Hlavna 3, Sala SK-92701  
+421 903 PLATON - removed\_email\_address@domain.invalid - [http://platon.org](http://platon.org)

My current location: Phoenix, Arizona  
My current timezone: -0700 UTC (MST)  
(updated automatically)

---

<div class="post-metadata">

**Author:** ![Ondrej\_Jombik](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/a698b9/32.png) [@Ondrej\_Jombik](https://www.ruby-forum.com/u/Ondrej_Jombik)\
**Post date:** [November 11, 2013, 2:10pm UTC](https://www.ruby-forum.com/t/filtering-out-long-invalid-hostnames/237383/2 "2013-11-11T14:10:32Z")

</div>

Hello!

On Sat, Nov 09, 2013 at 09:44:52PM +0100, Ondrej Jombik wrote:

> longest domain name should not be more than 253 characters. Also,  
> splitting domain into labels (labels are strings between dots), each  
> label should not exceed 63 characters.
> 
> For more info: [Domain Name System - Wikipedia](http://en.wikipedia.org/wiki/Domain_Name_System)  
> (search for “Domain name syntax” part)
> 
> That raises question how nginx handles this kind of long hostnames, and  
> why it still pasess those invalid hostnames to backends (upstreams).

While DNS names are indeed limited to no more than 255 octets,  
it’s not a case for HTTP, which can be used with non-DNS names as  
well.

> ```
> server {
> server_name "~^.{254,}$";
> listen 80;
> return 403;
> }
> 
> ```
> 
> Case #2 is probably more efficient, but in both cases are regular  
> expressions used.

Recommended use is to list valid names in a server\_name  
directives, and filter out anything else by using a default server  
which returns an appropriate error.

Between the above two cases I would recommend case #2, mostly  
because it’s easier to support.

> Would it matter if we put that server {} block at the  
> end of our server list?

As long as there are no other regexp server names in your  
configuration - position doesn’t matter, see  
[Server names](http://nginx.org/en/docs/http/server_names.html).

> Also would it make any sense to check for a dot (.) in a server\_name or  
> $host, and when not dot is present, return 403 as well?

You may do so if your configuration assumes access via fully  
qualified domain names only, and you are not hosting TLDs.  
Otherwise it may cause problems. See here for details:

> **[Fully qualified domain name](https://en.wikipedia.org/wiki/Fully_qualified_domain_name)**
>
> A fully qualified domain name (FQDN), sometimes also referred to as an absolute domain name, is a domain name that specifies its exact location in the tree hierarchy of the Domain Name System (DNS). It specifies all domain levels, including the top-level domain and the root zone. A fully qualified domain name is distinguished by its lack of ambiguity in terms of DNS zone location in the hierarchy of DNS labels: it can be interpreted only in one way.
> A fully qualified domain name is conventionall...

–  
Maxim D.  
[http://nginx.org/en/donation.html](http://nginx.org/en/donation.html)
