重新从应用层面考量ssl,思考在四层转发和七层转发中,实现ssl会有何问题。

SSL/TLS

  • TLS是SSL的升级版,TLS 1.0是目前应用最广泛的。
  • TLS介于TCP和HTTP之间,但其实TLS已经和上层应用无关了。

stream ssl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
stream {
upstream horizon {
server 10.1.0.254:80;
}
server {
listen 5000 ssl;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers AES128-SHA:AES256-SHA:RC4-SHA:DES-CBC3-SHA:RC4-MD5;
ssl_certificate /root/horizon-ssl/ssl.crt;
ssl_certificate_key /root/horizon-ssl/ssl.key;
ssl_session_cache shared:iSSL:10m;
ssl_session_timeout 10m;

proxy_pass horizon;
}
}
  • 在stream上开启ssl,就是直接加了一层TLS,转发不影响后端应用。
  • 但坑爹是后端的redirect不能正常运行。
  • 如果后端是一个http服务器,那么redirection就会是http://server
  • 并且此时不能应用proxy_redirect。

http ssl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';

access_log /var/log/nginx/access.log main;

sendfile on;
#tcp_nopush on;

keepalive_timeout 65;

#gzip on;
server {
listen 8080 ssl;
server_name 202.120.40.8:1180
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers AES128-SHA:AES256-SHA:RC4-SHA:DES-CBC3-SHA:RC4-MD5;
ssl_certificate /root/horizon-ssl/ssl.crt;
ssl_certificate_key /root/horizon-ssl/ssl.key;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;

location / {
proxy_pass http://10.1.0.254:80;
proxy_redirect http:// https://;
proxy_set_header Host $host:1180;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
error_page 497 https://$server_name$request_uri;
}
}
  • http转发就复杂了,nginx会重新拟http请求报文,后端接收到的http和用户原本的就不太一样了。
  • 所以这里设置了一些参数,让几个header和用户的相同。
  • 这里服务端返回的redirect会是http,所以需要重写成https。