nginx: jak deaktivovat https na default vhost?

nginx: jak deaktivovat https na default vhost?
« kdy: 17. 04. 2020, 22:21:43 »
Jak mam docilit aby nginx default na https nereagoval (jenom na vhosts ktere mam zadefinovane)? V /etc/nginx/sites-available/default mam:

Kód: [Vybrat]
server {
        listen 80 default_server;
        listen [::]:80 default_server;
        root /var/www/html;
        server_name _;
        location / { return 404; }
        #...
}

Kdyz se pripojim na defaultni vhost (treba pres http://IP), vse OK. Jenze kdyz skusim https://IP, bere to konfiguraci z prvniho vhostu kterej bezi na https.

Kód: [Vybrat]
server {
listen [::]:443 ssl http2 ipv6only=on;
listen 443 ssl http2;
        server_name something.somewhere.tld;
        #
}

Samozreme pak protestuje ze nesedi certifikat, atd...
« Poslední změna: 17. 04. 2020, 22:24:28 od Rhinox »


Re:nginx: jak deaktivovat https na default vhost?
« Odpověď #1 kdy: 17. 04. 2020, 22:44:44 »
By default, if the default_server parameter is not specified, then the default server will be the first one specified in the configuration. Asi kvuli tomu.

Re:nginx: jak deaktivovat https na default vhost?
« Odpověď #2 kdy: 18. 04. 2020, 00:06:48 »
No pochopil sem ze je to asi takhle, ale nejde tomu zabranit? Chci aby default naslouchal jen na 80, a ostatni vhosty na 80/443. Ale dobra, kdyz to nejde, skusil sem i default dat na 443 a dat mu nakou dummy-page. Do /etc/nginx/sites-available/default sem vlozil:

Kód: [Vybrat]
listen 443 default_server ssl http2;
listen [::]:443 default_server ssl http2 ipv6only=on;

Jenze ted nginx protestuje ze to mam nekde dva krat:

Kód: [Vybrat]
nginx -t
nginx: [emerg] duplicate listen options for [::]:443 in /etc/nginx/sites-enabled something.somewhere.tld:39
nginx: configuration file /etc/nginx/nginx.conf test failed

head -39 /etc/nginx/sites-enabled/something.somewhere.tld | tail -1
    listen [::]:443 ssl http2 ipv6only=on;

Proc? Vzdyt u toho druhyho vhostu mam definovano "server_name something.somewhere.tld", tak proc se plete s default?

Re:nginx: jak deaktivovat https na default vhost?
« Odpověď #3 kdy: 18. 04. 2020, 00:27:30 »
Skutečně tomu není možné zabránit, prohlížeč prostě očekává zcela validní odpověď, se správným certifikátem na správné doménové jméno. Což není splněno, tím pádem je vyvolána v prohlížeči chyba. Co by někdy potom ukázal nginx je irelevantní, tam se ani nedostaneme. Doporučuji tam nastavit nějakou stránku s chybovým HTTP kódem, aby při výpadku správného hosta monitoring zaječel, že přijíždí chybová stránka.

Pro ten druhý problém bychom museli vidět celý konfigurák, jak jej vypíše nginx -T, tedy včetně rozbalení všech include. Jsou to opravdu jediné volby listen v té sekci server? Mimochodem volba ipv6only=on je zbytečná, ve výchozím stavu se to i bez ní chová správně a pokud je tahle volba zopakovaná pro jedno rozhraní na více místech, ječí to taky chybu o duplicitě.

Re:nginx: jak deaktivovat https na default vhost?
« Odpověď #4 kdy: 18. 04. 2020, 00:53:51 »
/etc/nginx/sites-available/default:

Kód: [Vybrat]
server {
        listen 80 default_server;
        listen [::]:80 default_server;

        listen 443 default_server ssl http2;
        listen [::]:443 default_server ssl http2 ipv6only=on;
        include snippets/snakeoil.conf;

        root /var/www/html;
        server_name _;

        location / {
                return 404;
        }
}

/etc/nginx/sites-available/something.somewhere.tld

Kód: [Vybrat]
server {
        server_name something.somewhere.tld somewhere.tld;
        root /var/www/something.somewhere.tld;

        location / { try_files $uri $uri/ =404; }

    listen [::]:443 ssl http2 ipv6only=on; # managed by Certbot (<= TADY NGINX PROTESTUJE)
    listen 443 ssl http2; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/somewhere.tld/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/somewhere.tld/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

server {
    if ($host = something.somewhere.tld) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    if ($host = somewhere.tld) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

        listen 80;
        listen [::]:80;

        server_name something.somewhere.tld somewhere.tld;
        return 404; # managed by Certbot
}

Vyhodil sem jen nake nepodstatne veci (logy, location atd). BTW, tu ssl/https cas "psal" certbot (letsencrypt), taky ty redirecty...


Re:nginx: jak deaktivovat https na default vhost?
« Odpověď #5 kdy: 20. 04. 2020, 09:20:03 »
Vyzkoušel jsem to na čisté instalaci a je to skutečně tím ipv6only=on. Stačí to vyhodit a chyba s duplicitním listen zmizí.

Mimochodem ta přesměrování pomocí if jsou ošklivá a je to silně nedoporučovaný postup. Vím, že to psal Certbot. Doporučuji zvolit jiného ACME klienta a napsat si tu konfiguraci správně.

Re:nginx: jak deaktivovat https na default vhost?
« Odpověď #6 kdy: 20. 04. 2020, 15:07:03 »
Dekuji! Vyhodil sem to, a opravdu to ted funguje. BTW, takova zajimavost: potiz je jenom v default vhostu: kdyz tam mam:
listen [::]:443 default_server ssl http2 ipv6only=on
...nesmi byt ipv6only=on v zadnem jinem vhostu. Jinak nginx protestuje.

Kdyz ale
ipv6only=on
...vyhodim z default, vsechny ostatni vhosty to muzou mit! Tam uz nevadi ze je to uvedeno nekolikrat. Divne...

Re:nginx: jak deaktivovat https na default vhost?
« Odpověď #7 kdy: 20. 04. 2020, 15:40:13 »
Spousta direktiv u listen lze použít jen jedenkrát. Je to popsané zde, jsou nadepsané "These parameters can be specified in any listen directive, but only once for a given address:port pair.": http://nginx.org/en/docs/http/ngx_http_core_module.html#listen

Re:nginx: jak deaktivovat https na default vhost?
« Odpověď #8 kdy: 20. 04. 2020, 15:48:02 »
Mimochodem ta přesměrování pomocí if jsou ošklivá a je to silně nedoporučovaný postup. Vím, že to psal Certbot. Doporučuji zvolit jiného ACME klienta a napsat si tu konfiguraci správně.

If jsou zpracovávány poměrně složitě při každém požadavku, a pokud je v podmínce jen protokol (http/https) nebo hostname, je pro rychlost zpracování vhodnější použít zadefinovaného virtualhosta a v něm jediný return. Protohol / host se dohledává v tabulce mnohem rychleji, než se vyhodnocuje if a nehrozí ani chyby ze špatného pořadí ifů.

Na druhou stranu, pro velmi jednoduché weby s běžným počtem přístupů, je IF daleko menší výkonnostní zlo, než jakýkoliv PHP script. Takže bych asi IF neodsuzoval tak strašně moc příkře.

Certbot je nejvíc doporučovaný, ale považuji ho za pitomý. Snaží se o magickou automatizaci a díky tomu je omezený. Získat přes certbot dva certifikáty v páru (RSA+SECP) stejně znamená vzdát se všech jeho vymožeností. Docela příjemný mi přišel dehydrated.

Re:nginx: jak deaktivovat https na default vhost?
« Odpověď #9 kdy: 20. 04. 2020, 16:30:34 »
Je lepší se to učit rovnou pořádně a bez if. Je těžké se později takovou věc odnaučit. Proto to na školeních rovnou učím dobře od začátku.

Já v produkci všude používám klienta ACME.sh a jsem s ním velmi spokojený. Dehydrated je podle všeho ale také velmi dobře použitelný.

Rozhodně jsem v tomto ohledu přítelem jednoduchosti: aby to umělo všechny vlastnosti protokolu ACME a aby to nesahalo pokud možno nikam okolo. Já třeba ACME.sh pouštím v separátním uživatelském účtu, který nemá žádná práva a rozhodně mi nemůže nic překonfigurovávat.

Re:nginx: jak deaktivovat https na default vhost?
« Odpověď #10 kdy: 20. 04. 2020, 16:44:39 »
Já třeba ACME.sh pouštím v separátním uživatelském účtu, který nemá žádná práva a rozhodně mi nemůže nic překonfigurovávat.

To je další smutná kapitola. Měla by to být samozřejmost, ale co jsem tak viděl, není to ve výchozím stavu nikde nastavené. Vše se prasí, když už ne jako root, tak aspoň jako www-data, mod o+r je samozřejmost a ne zřídka člověk potká i o+rw. Nezkušení kolegové nenajdou nikde dobré články. Ty jsou buďto pro úplná jelita a nabádají ke špatným praktikám, nebo jsou naopak psaná pro znalé profesionály a ostatní jim nerozumí. Situaci ztěžuje i to, že pro každou distribuci musí existovat jiný postup, i to, že pro každou situaci se musí upravit. Já např. běžím v produkci weby oddělené v různých instancích nginx i php-fpm, každá pod svým userem. Tomu je poplatné i nastavení ACME klienta a jeho hooků.

Re:nginx: jak deaktivovat https na default vhost?
« Odpověď #11 kdy: 19. 05. 2020, 11:14:37 »
Řešil jsem teď něco podobného. Respektive nelíbilo se mi výchozí chování Nginxu, kdy pokud pro nějaký vhost, řekněme example.com, neposlouchá na portu 443, nabídne v odpovědi na https://example.com/ certifikát z nějakého jiného vhostu, který na 443 poslouchá. Nakonec jsem se rozhodl nechat výchozí na 443 poslouchat se self-signed certifikátem.
Kód: [Vybrat]
openssl req -x509 -newkey rsa:4096 -sha512 -days 3650
    -out /etc/nginx/ssl/cert.crt
    -keyout /etc/nginx/ssl/cert.key
    -nodes -batch
A pokud by to náhodou někdo v prohlížeči odsouhlasil, tak
Kód: [Vybrat]
    server {
        listen       443 ssl http2 default_server;
        listen       [::]:443 ssl http2 default_server;
        server_name  _;

        ssl_certificate            "/etc/nginx/ssl/cert.crt";
        ssl_certificate_key        "/etc/nginx/ssl/cert.key";

        return       444;
    }