Self-signing with Nginx to reject HTTP/HTTPS traffic to raw IP addresses at the L7 application layer

5 min

language: ja bn en es hi pt ru zh-cn zh-tw

Hello, I'm incompetent.
While it's generally not necessary to consciously manage DNS servers for some domains using tools like unbound amidst the spread of edge computing services, it is still essential for some people.
For example, for someone like me who self-hosts a mail server capable of sending and receiving, dependencies like OpenDKIM might bring in unbound.
Furthermore, there's a non-zero chance that a publicly exposed raw IP address could become a vulnerability for DDoS attacks, and accessing it directly via raw IP is detrimental to mental health, so I've decided to block it.

While Fail2ban can block DDoS attacks, it seems to manage blocked IPs by inserting them into a database based on logs, which can be resource-intensive. If using Fail2ban, it's better to do it on a domain-by-domain basis. For raw IPs that aren't typically used, I'll use a different method this time: protecting HTTP/HTTPS communication on the Nginx side.

Simply blocking HTTP communication

In my case, my global public IP address is as follows, so it looks like this.

# http通信
server {
    listen 80;
    listen [::]:80;

    server_name 167.179.75.206;

    return 444;
}

However, for SSL communication, Nginx becomes an HTTPS listener by explicitly indicating it's SSL communication, like listen 443 ssl;.

Then, if you put this in the http section and run nginx -t...

# https通信
server {
    listen 443 ssl;
    listen [::]:443 ssl;

    server_name 167.179.75.206;

    # IPアドレスへのアクセスを拒否
    return 444;
}

What happens?

# nginx -t
nginx: [emerg] no "ssl_certificate" is defined for the "listen ... ssl" directive in /usr/local/etc/nginx/nginx.conf:90
nginx: configuration file /usr/local/etc/nginx/nginx.conf test failed

That's right, because it's SSL communication, it complains that there's no key.
In such cases, self-signing is necessary... "It's me! It's me!" you have to say, "This is my certificate, lol." I will prove myself, right here, right now...

So, OpenSSL, can you do something about this?

Let's use the power of OpenSSL to perform this "it's me" scam... I mean, "it's me" certificate.
While there's an undeniable feeling of entrusting the next era to LibreSSL, which forked from OpenBSD, it seems it will take some time for it to become widespread.
For now, since only I will be using it, I'll set it for 3 years.

openssl req -x509 -nodes -days 1095 -newkey rsa:2048 -keyout /usr/local/etc/nginx/selfsigned.key -out /usr/local/etc/nginx/selfsigned.crt

Then, if you proceed without entering anything at the prompt, the key will be generated at the specified export destination.

Nginx, I'm back!

Let's specify this key in Nginx.

# https通信
server {
    listen 443 ssl;
    listen [::]:443 ssl;

    server_name 167.179.75.206;

    # 自己署名証明書と秘密鍵の指定
    ssl_certificate /usr/local/etc/nginx/selfsigned.crt;
    ssl_certificate_key /usr/local/etc/nginx/selfsigned.key;

    return 444;
}

And with this, it worked.
The end.

Related Posts