一、nginx实现https
1、创建自签名证书
[root@centos7 ~]# cd /etc/pki/tls/certs/ ##必须进入到此目录下
[root@centos7 certs]# ls
ca-bundle.crt ca-bundle.trust.crt make-dummy-cert Makefile renew-dummy-cert
[root@centos7 certs]# cat Makefile
UTF8 := $(shell locale -c LC_CTYPE -k | grep -q charmap.*UTF-8 && echo -utf8)
DAYS=365
KEYLEN=2048
TYPE=rsa:$(KEYLEN)
EXTRA_FLAGS=
ifdef SERIAL
EXTRA_FLAGS+=-set_serial $(SERIAL)
endif
.PHONY: usage
.SUFFIXES: .key .csr .crt .pem
.PRECIOUS: %.key %.csr %.crt %.pem
usage:
@echo "This makefile allows you to create:"
@echo " o public/private key pairs"
@echo " o SSL certificate signing requests (CSRs)"
@echo " o self-signed SSL test certificates"
@echo
@echo "To create a key pair, run \"make SOMETHING.key\"."
@echo "To create a CSR, run \"make SOMETHING.csr\"."
@echo "To create a test certificate, run \"make SOMETHING.crt\"."
@echo "To create a key and a test certificate in one file, run \"make SOMETHING.pem\"."
@echo
@echo "To create a key for use with Apache, run \"make genkey\"."
@echo "To create a CSR for use with Apache, run \"make certreq\"."
@echo "To create a test certificate for use with Apache, run \"make testcert\"."
@echo
@echo "To create a test certificate with serial number other than random, add SERIAL=num"
@echo "You can also specify key length with KEYLEN=n and expiration in days with DAYS=n"
@echo "Any additional options can be passed to openssl req via EXTRA_FLAGS"
@echo
@echo Examples:
@echo " make server.key"
@echo " make server.csr"
@echo " make server.crt"
@echo " make stunnel.pem"
@echo " make genkey"
@echo " make certreq"
@echo " make testcert"
@echo " make server.crt SERIAL=1"
@echo " make stunnel.pem EXTRA_FLAGS=-sha384"
@echo " make testcert DAYS=600"
%.pem:
umask 77 ; \
PEM1=`/bin/mktemp /tmp/openssl.XXXXXX` ; \
PEM2=`/bin/mktemp /tmp/openssl.XXXXXX` ; \
/usr/bin/openssl req $(UTF8) -newkey $(TYPE) -keyout $$PEM1 -nodes -x509 -days $(DAYS) -out $$PEM2 $(EXTRA_FLAGS) ; \
cat $$PEM1 > $@ ; \
echo "" >> $@ ; \
cat $$PEM2 >> $@ ; \
$(RM) $$PEM1 $$PEM2
%.key:
umask 77 ; \
/usr/bin/openssl genrsa -aes128 $(KEYLEN) > $@
%.csr: %.key
umask 77 ; \
/usr/bin/openssl req $(UTF8) -new -key $^ -out $@
%.crt: %.key
umask 77 ; \
/usr/bin/openssl req $(UTF8) -new -key $^ -x509 -days $(DAYS) -out $@ $(EXTRA_FLAGS)
TLSROOT=/etc/pki/tls
KEY=$(TLSROOT)/private/localhost.key
CSR=$(TLSROOT)/certs/localhost.csr
CRT=$(TLSROOT)/certs/localhost.crt
genkey: $(KEY)
certreq: $(CSR)
testcert: $(CRT)
$(CSR): $(KEY)
umask 77 ; \
/usr/bin/openssl req $(UTF8) -new -key $(KEY) -out $(CSR)
$(CRT): $(KEY)
umask 77 ; \
/usr/bin/openssl req $(UTF8) -new -key $(KEY) -x509 -days $(DAYS) -out $(CRT) $(EXTRA_FLAGS)
根据/etc/pki/tls/certs/Makefile文件的定义,使用make命令可以生成证书及私钥等文件,但是默认生成的证书私钥文件是需要设置密码的,因此还要编辑一下Makefile文件,把-aes128去掉就可以在生成证书时不用输入口令。
[root@centos7 certs]# vim Makefile
%.key:
umask 77 ; \
/usr/bin/openssl genrsa $(KEYLEN) > $@ \
#usr/bin/openssl genrsa -aes128 $(KEYLEN) > $@
生成证书及私钥文件
[root@centos7 certs]# make nginxcrt.crt
umask 77 ; \
/usr/bin/openssl genrsa 2048 > nginxcrt.key \
#usr/bin/openssl genrsa -aes128 2048 > nginxcrt.key
Generating RSA private key, 2048 bit long modulus
........................................................................................+++
.........................................+++
e is 65537 (0x10001)
umask 77 ; \
/usr/bin/openssl req -utf8 -new -key nginxcrt.key -x509 -days 365 -out nginxcrt.crt
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:HN
Locality Name (eg, city) [Default City]:haikou
Organization Name (eg, company) [Default Company Ltd]:hailian
Organizational Unit Name (eg, section) []:30
Common Name (eg, your name or your server's hostname) []:www.a.com
Email Address []:
[root@centos7 certs]# ls
ca-bundle.crt ca-bundle.trust.crt make-dummy-cert Makefile Makefile.bak nginxcrt.crt nginxcrt.key renew-dummy-cert
查看证书的私钥文件发现没有加密信息
[root@centos7 certs]# cat nginxcrt.key
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA2v2XxxB4aWS3w3tEISwp7BYu0jx71uwgvGY2wWv2FudKyzi6
/ZuHgd1oWD5VYnW+CtGP4J1IB890qoFUcZpzvzPU/LINy3zuw+9ULLBB7SWtY8QM
zjQsrSllxnhUJ5xlCWNwcMZx/KNi+w3raOBCGCdYGmLbO8WDOReEfPjmpjKgsWtq
ts6zhwltIpYk++/YNM1WHY4+E2JSuzdvF6lGAEd869YDD3cNV/1qm6sKWgtDgJUi
gLzfQvSlJbAhI1FumwRZY4Y1AHvXNBJ8ZAXzNtLA+9dL4jMXaZzGR9Qpq1dddMp4
7IcBzhFtWzNK6/+ScCu0vztz6Qv7ckxuoyyMWQIDAQABAoIBAQCjaI3EHfcr9drm
BGovMqxJnbfsavOhyWsYClGbfTsRlh+Ki1eE/HReJF/DUSgXo3Je0kdBPTvNkDEn
NgBUEQODzmKE+Twv9paYIFM4UYGwOugqRNWlXOtlfzmRoqJxOFNwcQIrNPlDoouu
eJGMHaNUMK+eaNvcuyKTDIhxVK2Pn2A5emjQgxgFaClHQOyuPrNVjpKazUiYD/Yp
pSNjcFDpZ3WhGPGDiQHpmm9t1k21NEvqfaioAdKbXrRWsN1PfABSURG+xDCczb57
8rxCLKaA5aR1zxgN0Hx+n6rvT/VLp4uirWQIvKDy+UxTBFLQq64V819i8sPQmPcx
YwYVLFx9AoGBAPF8RI5/hF3A762tsaooF03gfP36tjYBg4kbvDKgGKNCTD6y3zoM
KeK4M8MTzGxK4DhNd7bZLZ0YrsPvIQJTCrsFwasr2NYoxB1Y7ZmvgQFQsGS74Lq5
DiNpGI7B1A+RsA9fj2zBXPFXWiiKmC4gpkZv9A+tOT3nCbP8ceMFLJVrAoGBAOgn
MpWym7fwviO9DyI7Y6X2eW/hIvdjxu+5ayOLz0jbHd2/Gqa2LclUy+/H30+Qsa77
zkIg0TWK+uGr9cVFBFnLDpfq+fxdWIy1AHXbekHNBvA16iE2wIwK4XEDQALWq1A6
Ydw40DcGltu344buVgK7BUtShazQ8ERhY7eNYdJLAoGAYxyPvrSTjS8sr+nEK4Q8
3FewtUT7F/tTEyjw+w4+TnNde7ZKbDal0kmr5PrxQdkRYcpZwhAs6ndA82Xn9F5E
3zGjpS9f1bXxl+Hx0sv3dKS7YPzDZZ+iL+Jok971vFYdHpIn+Yj7LoqdlFodz4DS
/cHhN7Xu8nsqvlZ0H6r1+3UCgYBMnBrSUbWXdseYTZx/5G9W5kZeyEHct71/gIW9
njaSSVTKx3TJDReA+A2wnBmyTQKFxyzin6fKbomqDTA2oDb2Vs8DDRTf1gIRtO1o
9zuaGUmv3Wrc+Q+DZ1fMDpGCHks8V3fRz6HOdsszyLQ5487YadUubRYV2IFhX24j
tXFRjwKBgQC1zqMpHdLJBD0r7mOvPqnx+662UpPHJPmk+yVvmVxEfrlqY37XvrWU
ktXHSWYvwuZc+HMa634LN5i4LahOxC4olIZMLwVIQYN8R5I6rgtKmrfJ0rwWeXIT
H8DXHGCy6gtYSPkXcj314cMV4ZmT5MwZTlw6gDb0ubxPqMVepM6aow==
-----END RSA PRIVATE KEY-----
2、创建证书存放目录并把证书文件放置此处
[root@centos7 conf.d]# mkdir ssl
[root@centos7 certs]# cp nginxcrt.crt nginxcrt.key /etc/nginx/conf.d/ssl/
[root@centos7 conf.d]# ls ssl/
nginxcrt.crt nginxcrt.key
3、配置https的虚拟主机
[root@centos7 conf.d]# vim a.com.conf
server {
listen 80 default_server;
listen 443 ssl default_server;
server_name www.a.com;
root /data/sitea/;
error_page 404 =200 /404.html;
ssl_certificate /etc/nginx/conf.d/ssl/nginxcrt.crt;
ssl_certificate_key /etc/nginx/conf.d/ssl/nginxcrt.key;
ssl_session_cache shared:sslcache:40m;
ssl_session_timeout 10m;
location /404.html {
root /data/sitea/error/;
}
location /status {
stub_status;
}
}
检查443端口
[root@centos7 conf.d]# ss -ntl | grep 443
LISTEN 0 128 *:443 *:*
访问测试
nginx还可以实现多虚拟主机的https,因为nginx支持SNI(服务器名称扩展)技术。实现多虚拟主机的步骤和上面的类型这里不再赘述。
二、实现地址重写
ngx_http_rewrite_module模块
将用户请求的URI基于PCRE regex所描述的模式进行检查,而后完成重定向替换。
rewrite regex replacement [flag]
将用户请求的URI基于regex所描述的模式进行检查,匹配到时将其替换为replacement指定的新的URI
注意:如果在同一级配置块中存在多个rewrite规则,那么会自下而下逐个检查;被某条件规则替换完成后,会重新一轮的替换检查,隐含有循环机制,但不超过10次;如果超过,提示500响应码。
[flag]所表示的标志位用于控制此循环机制,如果replacement是以http://或https://开头,则替换结果会直接以重定向返回给客户端。
[flag]:
last:重写完成后停止对当前URI在当前location中后续的其它重写操作,而后对新的URI启动新一轮重写检查;提前重启新一轮循环,不建议在location中使用
break:重写完成后停止对当前URI在当前location中后续的其它重写操作,而后直接跳转至重写规则配置块之后的其它配置;结束循环,建议在location中使用
redirect:临时重定向,重写完成后以临时重定向方式直接返回重写后生成的新URI给客户端,由客户端重新发起请求;使用相对路径,或者http://或https://开头,状态码:302
permanent:重写完成后以永久重定向方式直接返回重写后生成的新URI给客户端,由客户端重新发起请求,状态码:301
示例:
1、当客户端访问/bbs时就重写至/forum目录下的相应页面。
server {
listen 80 default_server;
listen 443 ssl default_server;
server_name www.a.com;
root /data/sitea/;
error_page 404 =200 /404.html;
ssl_certificate /etc/nginx/conf.d/ssl/nginxcrt.crt;
ssl_certificate_key /etc/nginx/conf.d/ssl/nginxcrt.key;
ssl_session_cache shared:sslcache:40m;
ssl_session_timeout 10m;
location /404.html {
root /data/sitea/error/;
}
location /bbs {
rewrite ^/bbs/(.*)$ /forum/$1 break;
}
2、当客户端访问http时就重写至https
server {
listen 80 default_server;
listen 443 ssl default_server;
server_name www.a.com;
root /data/sitea/;
error_page 404 =200 /404.html;
ssl_certificate /etc/nginx/conf.d/ssl/nginxcrt.crt;
ssl_certificate_key /etc/nginx/conf.d/ssl/nginxcrt.key;
ssl_session_cache shared:sslcache:40m;
ssl_session_timeout 10m;
location /404.html {
root /data/sitea/error/;
}
location / {
if ($scheme = http) {
rewrite / https://www.a.com/ redirect;
}
}
输入http://www.a.com就会自动跳转到https://www.a.com
3、访问.txt结尾的页面就跳转至.html,而访问.html结尾的页面就跳转至.txt。主要验证break的用法(重写完成后停止对当前URI在当前location中后续的其它重写操作,而后直接跳转至重写规则配置块之后的其它配置)。
[root@centos7 conf.d]# vim a.com.conf
server {
listen 80 default_server;
listen 443 ssl default_server;
server_name www.a.com;
root /data/sitea/;
error_page 404 =200 /404.html;
ssl_certificate /etc/nginx/conf.d/ssl/nginxcrt.crt;
ssl_certificate_key /etc/nginx/conf.d/ssl/nginxcrt.key;
ssl_session_cache shared:sslcache:40m;
ssl_session_timeout 10m;
location /404.html {
root /data/sitea/error/;
}
location ~* \.txt {
rewrite (.*)\.(txt)$ $1.html break ;
}
location ~* \.html {
rewrite (.*)\.(html)$ $1.txt ;
}
4、return 停止处理,并返回给客户端指定的响应码或URL
return code [text];
return code URL;
return URL;
location / {
if ( $uri ~* .*admin.* ) {
return 403 "DENY ACCESS";
}
}
ngx_http_referer_module模块:
用来阻止Referer首部无有效值的请求访问,可防止盗链
1、valid_referers none|blocked|server_names|string …;
定义referer首部的合法可用值,不能匹配的将是非法值
none:请求报文首部没有referer首部
blocked:请求报文有referer首部,但无有效值
server_names:参数,其可以有值作为主机名或主机名模式
arbitrary_string:任意字符串,但可使用* 作通配符
regular expression:被指定的正则表达式模式匹配到的字符串,要使用~开头,例如: ~.* \.cwj\.com
示例:
在a站点上编写一个盗链的页面,盗用b站点的图片
[root@centos7 siteb]# cat ../sitea/daolian.html
<img src=http://www.b.com/flower.jpg>
<h1>www.a.com</h1>
b站点的目录结构及配置文件
[root@centos7 siteb]# ls
error flower.jpg index.html
[root@centos7 siteb]# tree .
.
├── error
│ └── 404.html
├── flower.jpg
└── index.html
1 directory, 3 files
[root@centos7 conf.d]# cat b.com.conf
server {
listen 80 ;
server_name www.b.com;
root /data/siteb/;
error_page 404 =200 /404.html;
access_log /var/log/nginx/b_access.log main;
location /404.html {
root /data/siteb/error/;
}
}
发现成功盗链
查看b站点的日志,referers首部字段中记录着此次访问是从a站点的daolian.html站点过来的,也证明了被盗链。
示例:
[root@centos7 conf.d]# vim b.com.conf
server {
listen 80 ;
server_name www.b.com;
root /data/siteb/;
error_page 404 =200 /404.html;
access_log /var/log/nginx/b_access.log main;
valid_referers none block server_names *.baidu.com www.baidu.* ~\.google\.com ;
if ($invalid_referer) {
return 403 http://www.baidu.com;
}
location /404.html {
root /data/siteb/error/;
}
}
再次访问,发现盗链被阻止了
查看b站点的日志,发现从a站点过来的被阻止掉了。
从b站点访问还是可以的