企业nginx应用实例(功能拆分记录)附安全加固配置
一.默认访问协议强制跳转(http--->https)
server { listen 80; server_name dannylinux.top www.dannylinux.top; # rewrite ^/(.*) https://$server_name/$1 permanent; return 301 https://$server_name/$request_uri; } server { listen 443; server_name dannylinux.top www.dannylinux.top; ssl on; ssl_certificate /usr/local/nginx/conf/ssl/server.pem; ssl_certificate_key /usr/local/nginx/conf/ssl/server.key; ssl_session_timeout 5m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #启用TLS1.1、TLS1.2要求OpenSSL1.0.1及以上版本,若您的OpenSSL版本低于要求,请使用 ssl_protocols TLSv1; ssl_ciphers HIGH:!RC4:!MD5:!aNULL:!eNULL:!NULL:!DH:!EDH:!EXP:+MEDIUM; ssl_prefer_server_ciphers on; location / { root /opt/source/dannyweb; index index.html; } }
二.获取用户真实源IP
proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Cookie $http_cookie; client_max_body_size 30m; client_body_buffer_size 128k; proxy_connect_timeout 600; proxy_read_timeout 600; proxy_send_timeout 600; proxy_buffer_size 64k; proxy_buffers 32 32k; proxy_busy_buffers_size 128k; proxy_http_version 1.1;
三.反向代理功能实现
#danny-test1 upstream danny-test1 { ip_hash; server 12.1.1.1:8091; server 12.1.1.2:8091; check interval=3000 rise=2 fall=5 timeout=1000 default_down=true type=http; //开启nginx状态检查 } #danny-test2 upstream danny-test2 { ip_hash; server 12.1.1.1:8090; server 12.1.1.2:8090; check interval=3000 rise=2 fall=5 timeout=1000 default_down=true type=tcp; } #danny-web upstream danny-web { ip_hash; server 12.1.1.1:7083; server 12.1.1.1:7083; check interval=3000 rise=2 fall=5 timeout=1000 default_down=true type=http; } #danny-fs upstream danny-fs { ip_hash; server 12.1.1.1:6070; server 12.1.1.2:6070; check interval=3000 rise=2 fall=5 timeout=1000 default_down=true type=tcp; } #danny-order-web upstream danny-order-web { ip_hash; server 12.1.1.1:7788; server 12.1.1.1:7788; check interval=3000 rise=2 fall=5 timeout=1000 default_down=true type=http; } ####################################### server { listen 80 default; listen 443 ssl; server_name blog.dannylinux.top; #ssl on; ssl_certificate /usr/local/nginx/conf/ssl/server.pem; ssl_certificate_key /usr/local/nginx/conf/ssl/server.key; ssl_client_certificate /usr/local/nginx/conf/ssl/client.pem; ssl_session_timeout 5m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers HIGH:!RC4:!MD5:!aNULL:!eNULL:!NULL:!DH:!EDH:!EXP:+MEDIUM; ssl_prefer_server_ciphers on; #ssl_verify_client on; #####################################屏蔽爬虫 if ($http_user_agent ~* "qihoobot|Baiduspider|Googlebot|Googlebot-Mobile|Googlebot-Image|Mediapartners-Google|Adsbot-Google|Feedfetcher-Google|Yahoo! Slurp|Yahoo! Slurp China|YoudaoBot|Sosospider|Sogou spider|Sogou web spider|MSNBot|ia_archiver|Tomato Bot") { return 403; } location ^~ /WEB-INF { deny all; } ##upstream status location /upstream_status { allow 12.1.1.3; allow 13.1.0.0/16; allow 14.1.1.2; allow 15.1.1.1; # deny all; check_status; access_log off; } ##nginx status location /nginx_status { allow 12.1.1.3; allow 13.1.0.0/16; allow 14.1.1.2; # deny all; stub_status on; access_log off; } #danny-new-static location ~ ^/(teststatic)/ { root /opt/source/danny-static/; } ##########3.0 proxy########## location / { proxy_pass http://danny-web; include /usr/local/nginx/conf/proxy.conf; } #版本匹配 location ~ ^/(v(\d+)/danny-test1)/ { proxy_pass http://danny-test1; include /usr/local/nginx/conf/proxy.conf; #普通匹配 location ~ ^/(danny-test2) { proxy_pass http://danny-test2; include /usr/local/nginx/conf/proxy.conf; } #条件匹配 #danny-fs location ~ ^/(resource|upload)/ { root /opt/proxy_temp; if (!-e $request_filename){ proxy_pass http://danny-fs; } proxy_cache imgcache; proxy_cache_valid 200 304 301 302 30d; proxy_cache_valid any 1d; proxy_cache_key $host$uri$is_args$args; include /usr/local/nginx/conf/proxy.conf; } #多条件匹配 #danny-order-web location ~ ^/(v(\d+)/hehe|v(\d+)/haha|v(\d+)/yoyo|v(\d+)/wuwu|v(\d+)/xixi)/ { proxy_pass http://danny-order-web; include /usr/local/nginx/conf/proxy.conf; }
以上都可单独为写为conf文件
附:安全加固配置
http中
#隐藏主机信息-异常信息泄露处理 proxy_hide_header X-Powered-By; proxy_hide_header Server; #禁用server_tokens指令,不暴露版本号-异常信息泄露处理 server_tokens off; #禁止目录浏览 autoindex off; #只允许加载同源的 fram、iframe、object,解决X-Frame-Options报头缺失 add_header X-Frame-Options SAMEORIGIN; #CSP防护,定义所有资源文件的默认加载规则为self,表示允许相同来源的内容(相同的协议、域名和端口) add_header Content-Security-Policy "default-src 'self' "; #开启XSS防护,开启 XSS 过滤,并且若检查到 XSS 攻击,停止渲染页面 add_header X-XSS-Protection: "1; mode=block"; #当响应类型未指定或错误指定时,不允许任何猜测 add_header X-Content-Type-Options nosniff;
server中
listen 83; #listen 443 ssl; server_name 192.168.3.173 127.0.0.1 www.xxx.com; #ssl on; #ssl_certificate F:\ssl\server.pem; #ssl_certificate_key F:\ssl\server.key; ssl_session_timeout 5m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #ssl_ciphers HIGH:!RC4:!MD5:!aNULL:!eNULL:!NULL:!DH:!EDH:!EXP:+MEDIUM; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!3DES:!ADH:!RC4:!DH:!DHE; ssl_prefer_server_ciphers on; #防止host头攻击 if ($http_Host !~* ^192.168.3.173|127.0.0.1|www.xxx.com|localhost$) { return 403; } #屏蔽爬虫 if ($http_user_agent ~* "qihoobot|Baiduspider|Googlebot|Googlebot-Mobile|Googlebot-Image|Mediapartners-Google|Adsbot-Google|Feedfetcher-Google|Yahoo! Slurp|Yahoo! Slurp China|YoudaoBot|Sosospider|Sogou spider|Sogou web spider|MSNBot|ia_archiver|Tomato Bot") { return 403; } #charset koi8-r; #access_log logs\host.access.log main; location / { root C:\inetpub\wwwroot; index index.html; add_header Cache-Control no-cache; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-IP $remote_addr; proxy_pass http://192.168.3.173:82; #IIS地址 proxy_connect_timeout 30s; } #限制某些格式文件运行 location ~* \.(config|ini|docx|txt|doc)$ { # deny all; return 404; } #禁止访问某些后缀文件 location ~* \.(php|zip|jsp|asp|aspx)$ { deny all; } #禁止访问某个目录下的某些后缀文件 location ~ /(xx|xx|xx|xx)/.*\.php$ { deny all; } #禁止访问某些目录及其下的所有文件 location ^*/xxx/ { deny all; } # 限制HTTP请求,只允许GET、POST和HEAD请求并禁用其他,http 444 代表无响应 if ($request_method !~ ^(GET|HEAD|POST)$) { return 444; } #设置只能域名访问 # set $flag 0; # if ($host ~* xxxx){ # set $flag 1; # } # if ($flag = 0){ # return 500 /50x.html; # } #拦截非法referer valid_referers none blocked 192.168.3.177; if ($invalid_referer) { return 403; }
上诉加固配置解释
1、X-Frame-Options 同源策略
资料:
X-Frame-Options HTTP 响应头是用来给浏览器指示允许一个页面可否在 <frame>, <iframe> 或者 <object> 中展现的标记。网站可以使用此功能,来确保自己网站的内容没有被嵌到别人的网站中去,也从而避免了点击劫持 (clickjacking) 的攻击。
该响应头用于是否允许浏览器加载 frame、 iframe、 object 等属性。可以使用该功能来避免点击劫持,就是防止网站被别人用iframe嵌入使用
add_header X-Frame-Options SAMEORIGIN;
该指令用三个可用的配置:
X-Frame-Options: DENY
X-Frame-Options: SAMEORIGIN
X-Frame-Options: ALLOW-FROM https://example.com/
当设置为 DENY 时,站点禁止任何页面被嵌入。
当设置为 SAMEORIGIN 时,只允许加载同源的 fram/iframe/object。
当设置为 ALLOW-FROM 时,只允许加载指定的源。
------------------------------------------------------------------
2、Content-Security-Policy CSP防护
该响应头主要用于规定页面可以加载那些资源(css/js/img 等)
定义所有资源文件的默认加载规则为self,表示允许相同来源的内容(相同的协议、域名和端口)
add_header Content-Security-Policy "default-src 'self' ";
或
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline';font-src 'self' data:; img-src 'self' data: 'unsafe-inline' https:; style-src 'self' 'unsafe-inline';frame-ancestors 'self'; frame-src 'self';connect-src https:";
------------------------------------------------------------------
3、X-XSS-Protection 开启XSS防护
该响应头是用于防范及过滤 XSS的
add_header X-XSS-Protection "1; mode=block";
可选参数:
X-XSS-Protection: 0
X-XSS-Protection: 1
X-XSS-Protection: 1; mode=block
X-XSS-Protection: 1; report=<reporting-uri>
说明:
0,禁用 XSS 过滤
1,开启 XSS 过滤
1; mode=block,开启 XSS 过滤,并且若检查到 XSS 攻击,停止渲染页面(例如IE8中,检查到攻击时,整个页面会被一个#替换);
X-XSS-Protection: 1; report=<reporting-uri>,开启 XSS 过滤,并且若检查到 XSS 攻击,将使用指定的 url 来发送报告。
HTTP X-XSS-Protection 响应头是 Internet Explorer,Chrome 和 Safari 的一个特性,
当检测到跨站脚本攻击 (XSS)时,浏览器将停止加载页面。
X-XSS-Protection响应头的缺失使得目标URL更易遭受跨站脚本攻击。
浏览器提供的XSS保护机制并不完美,但是开启后仍然可以提升攻击难度。
------------------------------------------------------------------
4、X-Content-Type-Options资源解析
解释:
互联网上的资源有各种类型,通常浏览器会根据响应头的Content-Type字段来分辨它们的类型。例如:text/html代表html文档,image/png是PNG图片,text/css是CSS样式文档。然而,有些资源的Content-Type是错的或者未定义。这时,某些浏览器会启用MIME-sniffing来猜测该资源的类型,解析内容并执行。
例如,我们即使给一个html文档指定Content-Type为text/plain,在IE8-中这个文档依然会被当做html来解析。利用浏览器的这个特性,攻击者甚至可以让原本应该解析为图片的请求被解析为JavaScript。在Nginx里通过下面这个响应头可以禁用浏览器的类型猜测行为。
X-Content-Type-Options HTTP 消息头相当于一个提示标志,被服务器用来提示客户端一定要遵循在 Content-Type 首部中对 MIME 类型 的设定,而不能对其进行修改。
这就禁用了客户端的 MIME 类型嗅探行为,换句话说,也就是意味着网站管理员确定自己的设置没有问题。
X-Content-Type-Options响应头的缺失使得目标URL更易遭受跨站脚本攻击。
add_header X-Content-Type-Options nosniff;
用来指定浏览器对未指定或错误指定 Content-Type 资源真正类型的猜测行为,nosniff 表示不允许任何猜测
如:通过精心制作一个图像文件,并在其中嵌入可以被浏览器所展示和执行的 HTML 和 JavaScript 代码。由于未关闭资源的类型猜测,浏览器将直接执行嵌入的 JavaScript 代码,而不是显示图片。
这个响应头的值只能是 nosniff,可用于 IE8+ 和 Chrome,
IE的行为受X-Content-Type-Options的影响,如果Web应用没有返回Content-Type,那么IE9、IE11将拒绝加载相关资源。
如果服务器发送响应头 “X-Content-Type-Options: nosniff”,则 script 和 styleSheet,元素会拒绝包含错误的 MIME 类型的响应。这是一种安全功能,有助于防止基于 MIME 类型混淆的攻击。
------------------------------------------------------------------
5、 Strict-Transport-Security HSTS防护
Strict-Transport-Security,简称 HSTS。该响应头用于标识浏览器用 HTTPS 替代 HTTP 的方式去访问目标站点。
有的网站开启了https,但为了照顾用户的使用体验(因为用户总是很赖的,一般不会主动键入https,而是直接输入域名, 直接输入域名访问,默认就是http访问)同时也支持http访问,当用户http访问的时候,就会返回给用户一个302重定向,重定向到https的地址,然后后续的访问都使用https传输,这种通信模式看起来貌似没有问题,但细致分析,就会发现种通信模式也存在一个风险,那就是这个302重定向可能会被劫持篡改,如果被改成一个恶意的或者钓鱼的https站点,一旦落入钓鱼站点,数据还有安全可言吗?
对于篡改302的攻击,建议服务器开启HTTP Strict Transport Security功能,这个功能的含义是:
当用户已经安全的登录开启过htst功能的网站 (支持hsts功能的站点会在响应头中插入:Strict-Transport-Security) 之后,支持htst的浏览器(比如chrome. firefox)会自动将这个域名加入到HSTS列表,下次即使用户使用http访问这个网站,支持htst功能的浏览器就会自动发送https请求(前提是用户没有清空缓存,如果清空了缓存第一次访问还是明文,后续浏览器接收到服务器响应头中的Strict-Transport-Security,就会把域名加入到hsts缓存中,然后才会在发送请求前将http内部转换成https),而不是先发送http,然后重定向到https,这样就能避免中途的302重定向URL被篡改。进一步提高通信的安全性。
HSTS的作用是强制客户端(如浏览器)使用HTTPS与服务器创建连接。服务器开启HSTS的方法是,当客户端通过HTTPS发出请求时,在服务器返回的超文本传输协议响应头中包含Strict-Transport-Security字段。非加密传输时设置的HSTS字段无效。
开启方式如下:
add_header strict-transport-security "max-age=16070400; includeSubDomains;";
当用户第一次访问后,将返回一个包含了 strict-transport-security 响应头的字段。他将告诉浏览器,在接下来的 16070400 秒内,当前网站的所有请求都强制使用 HTTPS 的方式访问。即使用户手动输入 http://,浏览器也会强制使用 HTTPS 方式访问。
参数 includeSubDomains 是可选的,当指定了该参数,所有子域名将采用同样的 HSTS 规则。
可以看到 HSTS 可以很好的解决 HTTPS 降级攻击,但是对于 HSTS 生效前的首次 HTTP 请求,依然无法避免被劫持。浏览器厂商们为了解决这个问题,提出了 HSTS Preload List 方案:内置一份可以定期更新的列表,对于列表中的域名,即使用户之前没有访问过,也会使用 HTTPS 协议
------------------------------------------------------------------
6、CSRF跨站伪请求防护
CSRF的一般防护策略:
1. 限制referer请求来源
location /iot/ {
valid_referers none blocked 192.168.1.1; #现在referer源
if ($invalid_referer) {
return 403;
}
proxy_set_header Host $http_host;
proxy_pass http://127.0.0.1:3399/xxx/;
}
2. 增加字段token验证
3. 在程序中增加filter,获取referer之后,进行判断
String verifyRefererStr=“http://localhost:8889/,http://localhost:8090/,http://localhost:80/”; HttpServletRequest req = (HttpServletRequest) servletRequest; String referer=req.getHeader(“referer”); System.out.println(“referer:”+referer); String[] verifyReferer = verifyRefererStr.split(","); boolean csrfFlag=false; for (String vReferer : verifyReferer) { if (referer == null || referer.trim().startsWith(vReferer)) { csrfFlag = true; break; } } if (!csrfFlag) { System.out.println("疑似CSRF攻击,referer:" + referer); return; } filterChain.doFilter(servletRequest, servletResponse);
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了