让我们用nginx反向代理encryption

介绍

我有一个开发服务器(目前运行Ubuntu 14.04 LTS),我已经使用了一段时间来在不同的端口上托pipe各种开发工具。 因为这些端口很难记住,所以我决定使用端口80作为我的所有服务,并在内部根据主机名进行端口转发。

而不是写入domain.com:5432,只需访问它通过sub.domain.com

例如,使用端口7547并在sub.domain.com上运行的应用程序X具有以下nginxconfiguration:

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 ""; } } 

问题

考虑到我select的当前configuration结构,是否可以使用letsencrypt并在https下运行不同的服务?

是的,您可以向HTTP服务器发送nginx代理请求,然后自己通过HTTPS响应客户端。 当你这样做的时候,你需要确保nginx < – >代理连接不太可能被你预期的攻击者嗅探到。 足够安全的方法可能包括:

  • 代理到相同的主机(和你一样)
  • 代理到防火墙后面的其他主机

在公共互联网上代理另一个主机不太可能是安全的。

以下是使用您用作代理服务器的相同Web服务器获取Let's Encrypt证书的说明。

从Let's Encrypt请求初始证书

修改您的server子句以允许从本地目录中提供.well-known的子目录,例如:

 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是让我们encryption服务器将寻找它所面临的挑战的答案。

然后,您可以使用certbot客户端使用webroot插件(以root身份)从Let's Encrypt请求证书:

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

您的密钥,证书和证书链现在将安装在/etc/letsencrypt/live/sub.domain.com/

configurationnginx使用你的证书

首先创build一个像这样的新的服务器子句:

 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:

 service nginx reload 

通过在浏览器(以及您特别希望支持的任何其他浏览器)中访问https://sub.domain.comhttps://www.sub.domain.com并检查他们是否不报告,validationHTTPS是否正常工作证书错误。

build议:还请查看nginx上的raymii.org:强大的SSL安全性,并在SSL实验室testing您的configuration。

(推荐)将HTTP请求redirect到HTTPS

一旦确认您的网站使用的是https://版本的url,而不是让某些用户提供不安全的内容,因为他们访问了http://sub.domain.com ,将其redirect到网站的HTTPS版本。

将您的整个端口80 server子句replace为:

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

您现在也应该在端口443configuration中取消注释此行,以便浏览器记得甚至不尝试网站的HTTP版本:

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

自动更新您的证书

您可以使用此命令(以root用户身份)更新certbot已知的所有证书,并使用新证书(与现有证书具有相同的path)重新加载nginx:

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

certbot只会尝试更新超过60天的证书,所以它是安全的(并build议!) 非常有规律地运行此命令,并且如果可能的话会自动运行。 例如,您可以在/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" 

您可以使用干运行来testing续订,这将与Let's Encrypt登台服务器进行联系,对联系您的域进行真正的testing,但不会存储结果证书:

 certbot --dry-run renew 

或者你可以强制更新:

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

请注意:您可以随意多次运行,但实际续约将受到“ 让我们encryption”的限制 。

是的,您可以使用nginx作为https的终点,并通过http与后端合作。 例如我的configuration:

 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/; } ... } 

但据我所知,让我们encryption,你必须指出所有的子域,当你拿到证书,如果这是一个问题,那么你selecturlhttps://host/service而不是https://service.host