同一个端口实现http跳转https
默认的,http和https需要使用不同的端口,做http到https的跳转,也需要从http的端口(默认为80)跳转到https的端口(443),那么,如何实现在一个端口的情况下,使用http访问转向到https呢?一个简单的方法是利用nginx的497错误码
原理:http和https是tcp的上层协议,当nginx服务器建立tcp连接后,根据收到的第一份数据来确定客户端是希望建立tls还是http。nginx会判断tcp请求的首写节内容以进行区分,如果是0x80或者0x16就可能是ssl或者tls,然后尝试https握手。如果端口开启了https,但请求过来的并不是,会抛出一个http级别的错误,这个错误的状态码是NGX_HTTP_TO_HTTPS,错误代码497,然后在返回response中会抛出一个400错误(因为497不是标准状态码,丢给浏览器也没有用),这时浏览器会显示"400 Bad Request,The plain HTTP request wes sent to HTTPS port"
这样,可以对497进行路由处理,做302重定向,核心代码如下:
error_page 497 https://$host:8080$request_uri;
示例配置如下:
server {
charset utf-8;
client_max_body_size 128M;
listen 8080 ssl;
ssl_certificate cert/test.com.pem;
ssl_certificate_key cert/test.com.pem;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
server_name test;
root /var/www;
index index.php;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location /check.html {
return 200;
access_log off;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass 127.0.0.1:9000;
#fastcgi_pass unix:/var/run/php5-fpm.sock;
try_files $uri =404;
}
location ~* /\. {
deny all;
}
error_page 497 https://$host:8080$request_uri;
}
在线配置文件生成
在线生成nginx配置文件
https://nginxconfig.io
图片防盗链
通过检测header字段里的referer字段判断,若referer来自规定的域名或空时,认为是正常的访问,否则为盗链
#https访问http的图片,因为安全性规定,所带referer为空
location ~* .(gif|jpg|png|bmp)$ {
valid_referers none blocked *.xxx.com server_names ~.google. ~.baidu.;
if ($invalid_referer) {
return 403;
}
}