Nginx ters vekil ile şifrele sağlar


45

Giriş

Farklı bağlantı noktalarında çeşitli geliştirme araçlarını barındırmak için bir süredir kullandığım bir geliştiriciden (şu anda Ubuntu 14.04 LTS çalıştıran) kullanıyorum. Bağlantı noktalarının hatırlanması zor olabileceğinden, tüm hizmetlerim için 80 numaralı bağlantı noktasını kullanmaya ve ana makine adına dayalı olarak bağlantı noktası dahili olarak iletmeye karar verdim.

Domain.com:5432 yazmak yerine, sub.domain.com adresinden kolayca erişebilirim

Örneğin, 7547 numaralı bağlantı noktasını kullanan ve sub.domain.com adresinde çalışan X uygulaması aşağıdaki nginx yapılandırmasına sahiptir:

upstream sub {
    server 127.0.0.1:7547;
}

server {
    listen 80;
    server_name sub.domain.com www.sub.domain.com;
    access_log /var/log/nginx/sub.log combined;
    location / {
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_pass http://127.0.0.1:7547;
            proxy_set_header Authorization "";
    }
}

Soru

Seçtiğim mevcut konfigürasyon yapısı göz önüne alındığında farklı şifreleri https altında çalıştırmak ve letsencrypt kullanmak mümkün müdür?


3
Bu konuyla ilgili bir blog yazısı yazdım: tom.busby.ninja/letsecnrypt-nginx-reverse-proxy-no-downtime
Tom Busby

Yanıtlar:


81

Evet, HTTP sunucularına nginx proxy istekleri verebilir ve ardından HTTPS üzerinden istemcilere yanıt verebilirsiniz. Bunu yaparken, nginx <-> proxy connect'ın beklenen saldırganınız kim tarafından koklanmasının muhtemel olmadığından emin olmak isteyeceksiniz. Güvenli yeterince yaklaşımlar olabilir şunlardır:

  • aynı ana bilgisayara proxy oluşturma (yaptığınız gibi)
  • güvenlik duvarınızın arkasındaki diğer ana bilgisayarlara proxy sunucusu

İnternette başka bir ev sahibine proxy sunucusunun yeterince güvenli olması pek mümkün değildir.

Proxy olarak kullandığınız web sunucusunu kullanarak bir Let's Encrypt sertifikası almanız için talimatlar.

İlk şifrenizi Let's Encrypt'tan istemek

Maddeyi serveralt .well-knowndizinin yerel bir dizinden sunulmasına izin verecek şekilde değiştirin , örneğin:

server {
    listen 80;
    server_name sub.domain.com www.sub.domain.com;
    […]
    location /.well-known {
            alias /var/www/sub.domain.com/.well-known;
    }

    location / {
        # proxy commands go here
        […]
    }
}

http://sub.domain.com/.well-known Let's Encrypt sunucularının, karşılaştığı zorlukların cevaplarını arayacağı yerdir.

Daha sonra, certbot istemcisini webroot eklentisini (root olarak) kullanarak Let's Encrypt'tan bir sertifika istemek için kullanabilirsiniz :

certbot certonly --webroot -w /var/www/sub.domain.com/ -d sub.domain.com -d www.sub.domain.com

Anahtarınız, sertifikanız ve sertifika zinciriniz şimdi /etc/letsencrypt/live/sub.domain.com/

Sertifikanızı kullanmak için nginx'i yapılandırma

İlk önce şunun gibi yeni bir sunucu maddesi oluşturun:

server {
    listen 443 ssl;

    # if you wish, you can use the below line for listen instead
    # which enables HTTP/2
    # requires nginx version >= 1.9.5
    # listen 443 ssl http2;

    server_name sub.domain.com www.sub.domain.com;

    ssl_certificate /etc/letsencrypt/live/sub.domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/sub.domain.com/privkey.pem;

    # Turn on OCSP stapling as recommended at 
    # https://community.letsencrypt.org/t/integration-guide/13123 
    # requires nginx version >= 1.3.7
    ssl_stapling on;
    ssl_stapling_verify on;

    # Uncomment this line only after testing in browsers,
    # as it commits you to continuing to serve your site over HTTPS
    # in future
    # add_header Strict-Transport-Security "max-age=31536000";

    access_log /var/log/nginx/sub.log combined;

    # maintain the .well-known directory alias for renewals
    location /.well-known {
        alias /var/www/sub.domain.com/.well-known;
    }

    location / {
        # proxy commands go here as in your port 80 configuration
        […]
    }
}

Nginx'i yeniden yükle:

service nginx reload

HTTPS'nin şu anda çalıştığını https://sub.domain.comve https://www.sub.domain.comtarayıcınızda (ve özellikle desteklemek istediğiniz diğer tarayıcılarda) ziyaret ederek ve sertifika hataları bildirmediklerini kontrol ederek çalıştığını doğrulayın.

Önerilen: ayrıca raymii.org sitesini da gözden geçirin: nginx'te Güçlü SSL Güvenliği ve SSL Laboratuarlarında yapılandırmanızı test edin .

(Önerilen) HTTP isteklerini HTTPS'ye yönlendir

Sitenizin https://, URL’nin sürümüyle çalıştığını onayladıktan sonra , bazı kullanıcıların gittikleri için güvensiz içerik http://sub.domain.comsunmalarına izin vermek yerine , onları sitenin HTTPS sürümüne yönlendirin.

Port 80 serveryan tümcesini tümüyle değiştirin :

server {
    listen 80;
    server_name sub.domain.com www.sub.domain.com;
    rewrite     ^   https://$host$request_uri? permanent;
}

Ayrıca, bu satırı bağlantı noktası 443 yapılandırmasında da açmanız gerekir, böylece tarayıcılar sitenin HTTP sürümünü bile denemediğini hatırlar:

add_header Strict-Transport-Security "max-age=31536000";

Sertifikanızı otomatik olarak yenileyin

Bu komutu (root olarak), yeni sertifika kullanarak (mevcut sertifikanızla aynı yola sahip olacak) certbot ve nginx'i yeniden yüklediği bilinen tüm sertifikaları yenilemek için kullanabilirsiniz:

certbot renew --renew-hook "service nginx reload"

certbot yalnızca 60 günden daha eski sertifikaları yenilemeye çalışacaktır, bu nedenle bu komutu çok düzenli olarak ve mümkünse otomatik olarak çalıştırmak güvenlidir (ve önerilir!) . Örneğin, aşağıdaki komutu koyabilirsiniz /etc/crontab:

# at 4:47am/pm, renew all Let's Encrypt certificates over 60 days old
47 4,16   * * *   root   certbot renew --quiet --renew-hook "service nginx reload"

Yenilikleri, bir kuru çalıştırmayla test edebilirsiniz; bu, etki alanınızla bağlantı kurmak için gerçek bir test yapmak üzere Let's Encrypt aşamalandırma sunucularıyla iletişim kuracak , ancak elde edilen sertifikaları saklamayacaktır:

certbot --dry-run renew

Veya aşağıdakilerle erken yenilemeye zorlayabilirsiniz:

certbot renew --force-renew --renew-hook "service nginx reload"

Not: Koşuyu istediğiniz kadar kurutabilirsiniz, ancak gerçek yenilemeler Let's Encrypt hız sınırlarına tabidir .


Çözümün benim için işe yaramıyor. Temelde aynı konfigürasyona sahibim. Goopen.tk için çalışıyor, ancak www.goopen.tk için değil
Alko

3
@Alko, cevabın talimatları doğru ve bu konuyu kapsıyor. Kullanırken certbotveya başka bir aracı, iş için hem www ve www olmayan biçimde etki alanını belirlemek için unutamam.
Paulo Coghi

Altında yoldan location /.well-knownayrılman gerekiyor .well-known. Kullanın alias /var/www/sub.domain.com, değilalias /var/www/sub.domain.com/.well-known
gldraphael

1
Birisi neden "yeniden yazmak ^ https: // $ host $ request_uri? Perman;" kullanmak istediğinizi açıklayabilir mi? burada "return 301 https: // $ server_name $ request_uri;"
ZaxLofful

Konumdaki yolun etrafında tırnaklara ihtiyacım olduğunu buldum. location '/.well-known' {. Bu bir sürüm şey veya sadece benim kurulum olup olmadığından emin değilim ama başka birinin sıkışmış olması durumunda.
Frank V

2

Evet, nginxhttps'nin bitiş noktası olarak kullanabilir ve http üzerinden arka uçlarla işbirliği yapabilirsiniz. Örneğin benim config:

server {
        server_name host;
        listen 443 ssl;
...
 location /svn/ {
            auth_ldap off;

            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;

            proxy_pass http://localhost:1080/svn/;
            proxy_redirect http://localhost:1080/ https://host/;
        }
...
}

Fakat bildiğim gibi, şifrelemeyle sertifika aldığınızda tüm alt alanları işaret etmeniz gerekecek ve eğer bu bir problemse, o zaman URL https://host/serviceyerine URL'yi seçmelisiniz .https://service.host

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.